查询用户信息

This commit is contained in:
LittleBoy 2022-11-21 14:13:45 +08:00
parent 5129b79a3f
commit 7eba424661
22 changed files with 372 additions and 42 deletions

View File

@ -82,6 +82,18 @@
<artifactId>bcprov-jdk15on</artifactId>
<version>1.57</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.33.0</version>
</dependency>
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
<version>1.33.0</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,22 @@
package me.xiaoyan.point.api.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
// 跨域 目前小程序不需要暂时不用考虑
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**").allowedOrigins("*");
// }
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
}

View File

@ -10,6 +10,7 @@ public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}

View File

@ -0,0 +1,104 @@
package me.xiaoyan.point.api.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
//redis配置类
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值默认使用JDK的序列化方式
Jackson2JsonRedisSerializer jackson = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域field,get和set,以及修饰符范围ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型类必须是非final修饰的final修饰的类比如String,Integer等会跑出异常
//om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson.setObjectMapper(om);
// 值采用json序列化
template.setValueSerializer(jackson);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jackson);
template.afterPropertiesSet();
return template;
}
/**
* 对hash类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
/**
* 对redis字符串类型数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
/**
* 对链表类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
/**
* 对无序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
/**
* 对有序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}

View File

@ -27,7 +27,7 @@ public class SwaggerConfiguration {
// 创建api文档信息
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("me.xiaoyan.point.api.controller"))

View File

@ -0,0 +1,23 @@
package me.xiaoyan.point.api.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import me.xiaoyan.point.api.pojo.PointRecord;
import me.xiaoyan.point.api.pojo.vo.PageParam;
import me.xiaoyan.point.api.service.PointRecordService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("point")
public class PointController {
@Resource
private PointRecordService pointRecordService;
public IPage<PointRecord> list(@RequestBody PageParam param){
return pointRecordService.histories(StpUtil.getLoginIdAsInt(),param);
}
}

View File

@ -0,0 +1,18 @@
package me.xiaoyan.point.api.controller;
import io.swagger.annotations.ApiOperation;
import me.xiaoyan.point.api.pojo.vo.SignResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("sign")
public class SignController {
@ApiOperation("今日签到")
@RequestMapping("today")
public SignResult signToday() {
return null;
}
}

View File

@ -0,0 +1,45 @@
package me.xiaoyan.point.api.controller;
import cn.dev33.satoken.stp.StpUtil;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import me.xiaoyan.point.api.pojo.UserInfo;
import me.xiaoyan.point.api.pojo.vo.SignResult;
import me.xiaoyan.point.api.pojo.vo.UserLoginData;
import me.xiaoyan.point.api.service.UserInfoService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("user")
public class UserinfoController {
@Resource
private UserInfoService userInfoService;
// code => openid等信息
// 使用wx.login获取到的code进行登录完成登录后下发用户登录凭证
@ApiOperation("登录")
@PostMapping("login")
@SneakyThrows
public String login(@Validated @RequestBody UserLoginData data) {
//@NotNull(message = "登录code不能为空")
UserInfo info = userInfoService.login(data);
// 完成登录
StpUtil.login(info.getId());
// 可以考虑将用户信息保存到sa-token
// StpUtil.getSession().set("userinfo",info);
return StpUtil.getTokenInfo().getTokenValue();
}
@ApiOperation("获取登录用户的基本信息")
@RequestMapping("info")
public UserInfo getInfo() {
int uid = StpUtil.getLoginIdAsInt();
return userInfoService.getInfoById(uid);
}
}

View File

@ -1,29 +0,0 @@
package me.xiaoyan.point.api.controller;
import lombok.SneakyThrows;
import me.xiaoyan.point.api.pojo.UserInfo;
import me.xiaoyan.point.api.pojo.vo.UserLoginData;
import me.xiaoyan.point.api.service.UserInfoService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
@RestController
public class WechatController {
@Resource
private UserInfoService userInfoService;
// code => openid等信息
// 使用wx.login获取到的code进行登录完成登录后下发用户登录凭证
@RequestMapping("/wechat/login")
@SneakyThrows
public UserInfo login(@Validated @RequestBody UserLoginData data) {
//@NotNull(message = "登录code不能为空")
return userInfoService.login(data);
}
}

View File

@ -2,21 +2,26 @@ package me.xiaoyan.point.api.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Point implements Serializable {
@TableId(type = IdType.NONE)
private Integer uid;
private Integer totalPoint;
private Integer validPoint;
private Integer expirePoint;
private Integer expireTime;
private Integer updateTime;
private Date expireTime;
private Date updateTime;
}

View File

@ -3,8 +3,10 @@ package me.xiaoyan.point.api.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@ -13,6 +15,8 @@ import java.util.Date;
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("point_record")
public class PointRecord implements Serializable {
@TableId(type = IdType.AUTO)

View File

@ -2,8 +2,10 @@ package me.xiaoyan.point.api.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@ -12,6 +14,8 @@ import java.util.Date;
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SignRecord implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;

View File

@ -1,10 +1,13 @@
package me.xiaoyan.point.api.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@ -13,6 +16,8 @@ import java.util.Date;
@Data
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("userinfo")
public class UserInfo implements Serializable {
/**
@ -57,4 +62,6 @@ public class UserInfo implements Serializable {
* 状态
*/
private Integer status;
@TableField(exist = false)
private Point pointInfo;
}

View File

@ -0,0 +1,22 @@
package me.xiaoyan.point.api.pojo.vo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Builder
public class PageParam {
private Integer page;
private Integer pageSize = 20;
public Page getPage(){
return new Page().setCurrent(page).setSize(pageSize);
}
}

View File

@ -0,0 +1,11 @@
package me.xiaoyan.point.api.pojo.vo;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Builder
@Accessors(chain = true)
public class SignResult {
}

View File

@ -3,6 +3,7 @@ package me.xiaoyan.point.api.pojo.vo;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Data
@ -13,4 +14,8 @@ public class UserLoginData implements Serializable {
private String iv;
@NotEmpty(message = "code参数不能为空")
private String code;
/**
* 推荐用户id
*/
private int recommend;
}

View File

@ -1,8 +1,12 @@
package me.xiaoyan.point.api.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import me.xiaoyan.point.api.pojo.PointRecord;
import me.xiaoyan.point.api.pojo.UserInfo;
import me.xiaoyan.point.api.pojo.vo.PageParam;
import java.util.List;
public interface PointRecordService extends IService<PointRecord> {
/**
@ -13,4 +17,8 @@ public interface PointRecordService extends IService<PointRecord> {
* @return
*/
public PointRecord record(Integer uid,Integer point,String reason);
IPage<PointRecord> histories(Integer uid, PageParam param);
IPage<PointRecord> exchangeHistories(Integer uid, PageParam param);
}

View File

@ -12,4 +12,6 @@ public interface UserInfoService extends IService<UserInfo> {
* @return
*/
public UserInfo login(UserLoginData data);
UserInfo getInfoById(Integer uid);
}

View File

@ -1,16 +1,20 @@
package me.xiaoyan.point.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import me.xiaoyan.point.api.error.BizException;
import me.xiaoyan.point.api.mapper.PointRecordMapper;
import me.xiaoyan.point.api.pojo.Point;
import me.xiaoyan.point.api.pojo.PointRecord;
import me.xiaoyan.point.api.pojo.vo.PageParam;
import me.xiaoyan.point.api.service.PointRecordService;
import me.xiaoyan.point.api.service.PointService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
@Service
public class PointRecordServiceImpl extends ServiceImpl<PointRecordMapper, PointRecord>
@ -43,4 +47,20 @@ public class PointRecordServiceImpl extends ServiceImpl<PointRecordMapper, Point
this.save(record);
return record;
}
@Override
public IPage<PointRecord> histories(Integer uid, PageParam param) {
QueryWrapper<PointRecord> q = new QueryWrapper();
q.eq("uid",uid);
this.getBaseMapper().selectPage(param.getPage(), q);
return null;
}
public IPage<PointRecord> exchangeHistories(Integer uid, PageParam param) {
QueryWrapper<PointRecord> q = new QueryWrapper();
q.eq("uid",uid);
q.lt("point",0);
this.getBaseMapper().selectPage(param.getPage(), q);
return null;
}
}

View File

@ -27,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.io.Serializable;
@Service
@Slf4j
@ -53,7 +54,20 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
@Resource
private PointRecordService pointRecordService;
public void firstLogin(UserInfo info) {
public void firstLogin(UserInfo info, int recommendUid) {
if (recommendUid > 0) {
// 判断推荐者是否存在
if (this.getById(recommendUid) != null) {
// 存在则设置后续操作
info.setParentId(recommendUid);
// 增加推荐积分
pointRecordService.record(
recommendUid,
recommendPoint,
"推荐新用户"
);
}
}
// 先新增用户基本信息
save(info);
// 新增积分信息
@ -90,7 +104,7 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
userInfo = wechatUserInfo.getUserinfo().setOpenId(sessionData.getOpenid());
//
// 不存在走 第一次登录流程
firstLogin(userInfo);
firstLogin(userInfo, data.getRecommend());
}
// 首先
return userInfo;
@ -126,4 +140,12 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo>
return data;
}
}
public UserInfo getInfoById(Integer id) {
final UserInfo userinfo = getById(id);
if (userinfo != null) {
userinfo.setPointInfo(pointService.getById(userinfo.getId()));
}
return userinfo;
}
}

View File

@ -8,6 +8,8 @@ application:
first_login: 200
recommend: 100
spring:
profiles:
active: dev
application:
name: point_api
datasource:
@ -51,4 +53,21 @@ mybatis-plus:
configuration:
# 日志接口
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
cache-enabled: true
cache-enabled: true
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
sa-token:
# token名称 (同时也是cookie名称)
token-name: token
# token有效期单位s 默认30天, -1代表永不过期
timeout: -1
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: true

View File

@ -11,16 +11,21 @@ public class WechatTests {
@DisplayName("解密用户信息")
@Test
void testDecode(){
String encryptedData = "Ezl1S3BHjBeg/HP0Nim/c9eLLYP5L1kgvqSpR+RQYFG6c3Qx0K5U6btEY5IByCw1OsnZ0hKDccNJn3VA/ZgpkxjDODt+XLcph3KqEL6LDU9BLDRFxCI7u+eHBorz5HWYzGITXiuyPb9NWmGAPXwwp0abFqqaycb5u4oii7I/tnh7NIRIcMxAft1YfbVdzQDjraRHFH5hg6Eh4RGSjy6rg1bG/sMecw4+XWM1psTjKBYNwtsG5oxBWja6DniPhmWU6ZwjVMfgJX5Z7wcw2vtmuDPOMCEE1SEcwmTcQ5YKLlPsPBAJhrF3Lxg9oTD1/IlZ";
String iv = "ckSRPBLA61WONzUDINIWMg==";
// String encryptedData = "Ezl1S3BHjBeg/HP0Nim/c9eLLYP5L1kgvqSpR+RQYFG6c3Qx0K5U6btEY5IByCw1OsnZ0hKDccNJn3VA/ZgpkxjDODt+XLcph3KqEL6LDU9BLDRFxCI7u+eHBorz5HWYzGITXiuyPb9NWmGAPXwwp0abFqqaycb5u4oii7I/tnh7NIRIcMxAft1YfbVdzQDjraRHFH5hg6Eh4RGSjy6rg1bG/sMecw4+XWM1psTjKBYNwtsG5oxBWja6DniPhmWU6ZwjVMfgJX5Z7wcw2vtmuDPOMCEE1SEcwmTcQ5YKLlPsPBAJhrF3Lxg9oTD1/IlZ";
// String iv = "ckSRPBLA61WONzUDINIWMg==";
String sessionKey= "091WPNkl23zoha4xbpnl2cev9l4WPNk7";
String encryptedData = "3mmRZjsqy3Tpgw78jm7HNB3n6/pb8nX9jS1GgngV4tHGSe+yhKIXy7u7kxXz7nKS5lwNqt+UQCXF3EHHd1PQJowtpYWNhLBjNZcGjEdIi6a5pxntmwmFsjTX+SjPNmq5Th4iKSwSyMjLIByZqJt7N3hB5OyT5YAo54lsJrln8DJoPE1m6kddHcLqnJy+g12QQTP1u3tFvCEostrCpb109Bhe889wAxm55ekPHTQ+JWYCsPy0TsjmyvqZCQZyB+RNtlW/ohCpLe4oCOF0Nz9Id6N+Kj6bXvgDcEMBf3vwMXSnbWHuqJAuLUWwbsspB/2T";
String iv = "qfrpHwHjjqPQVlzzxE9D1A==";
// sessionKey= "PKX9EeH6y+pzz8qYrga2jQ==";
// encryptedData = "SCK0Ik7THl+USkwTRqTQ9BYGe6rWlXosQ8fWA3I3AsFHTCuPnjbsjFooIEZVcS6mq911XeP5BJJBpPU6A1O3aNuC9L7ebXqTMQX83bVBtaDQySvCIlyyq26xhm8AbWWexl5994NJDpKkNml9ilbYia99bF8bXzXvLCksQQkz82EpZTqztzmCrTdFBZOIrJ+lDnl7rSBWJvVVtoagzgSq2Ux59LcJtxCukIUoZ8fz54//Hm4GhrLucO4zPKTi087f77Pd9K9Rz3LLJ79NMQHHQLtZ38Ws79IKoHBZ7xHXbl3O8xPeTBrrWeHbNfNs1CbOyoe0RwXVjs/fMR9451PeLVM5jg4fj3IDyTFjpx5aUzQRaIrSY/BjVFJoxU/viwQC6LsCBOyXl5uV5h+qIPC5suFbmhl5Q56eU07wbOjNxktEIJsIgbrT+GWRZVPba3dUo+6RoZySxCMA16TRKfuTwjXceV3oNueFdTNyw05s9N43OkrLeKcz1dFeNnpA9DHEVngB1J7MY4RkazdKaWzrld1DjxW6+rk01GgtAr3+H88=";
// iv = "Ql/m+Ksll5ziCCZj+07J6g==";
WechatUserInfo wechatUserInfo = WechatDecryptDataUtil.decryptData(
"SCK0Ik7THl+USkwTRqTQ9BYGe6rWlXosQ8fWA3I3AsFHTCuPnjbsjFooIEZVcS6mq911XeP5BJJBpPU6A1O3aNuC9L7ebXqTMQX83bVBtaDQySvCIlyyq26xhm8AbWWexl5994NJDpKkNml9ilbYia99bF8bXzXvLCksQQkz82EpZTqztzmCrTdFBZOIrJ+lDnl7rSBWJvVVtoagzgSq2Ux59LcJtxCukIUoZ8fz54//Hm4GhrLucO4zPKTi087f77Pd9K9Rz3LLJ79NMQHHQLtZ38Ws79IKoHBZ7xHXbl3O8xPeTBrrWeHbNfNs1CbOyoe0RwXVjs/fMR9451PeLVM5jg4fj3IDyTFjpx5aUzQRaIrSY/BjVFJoxU/viwQC6LsCBOyXl5uV5h+qIPC5suFbmhl5Q56eU07wbOjNxktEIJsIgbrT+GWRZVPba3dUo+6RoZySxCMA16TRKfuTwjXceV3oNueFdTNyw05s9N43OkrLeKcz1dFeNnpA9DHEVngB1J7MY4RkazdKaWzrld1DjxW6+rk01GgtAr3+H88=",
"PKX9EeH6y+pzz8qYrga2jQ==",
"Ql/m+Ksll5ziCCZj+07J6g=="
encryptedData,
sessionKey,
iv
);
System.out.println(wechatUserInfo);
// System.out.println(wechatUserInfo);
}
}