|
@@ -0,0 +1,371 @@
|
|
|
+package com.fs.course.controller;
|
|
|
+
|
|
|
+import cn.binarywang.wx.miniapp.api.WxMaService;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.fs.course.annotation.Login;
|
|
|
+import com.fs.course.utils.JwtUtils;
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
+import com.fs.common.core.redis.RedisCache;
|
|
|
+import com.fs.common.param.LoginParam;
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
+import com.fs.core.config.WxMaConfiguration;
|
|
|
+import com.fs.course.config.CourseMaConfig;
|
|
|
+import com.fs.his.config.FsSysConfig;
|
|
|
+import com.fs.his.domain.FsUser;
|
|
|
+import com.fs.his.domain.FsUserLoginLog;
|
|
|
+import com.fs.his.mapper.FsUserLoginLogMapper;
|
|
|
+import com.fs.his.service.IFsUserService;
|
|
|
+import com.fs.his.utils.ConfigUtil;
|
|
|
+import com.fs.system.domain.SysConfig;
|
|
|
+import com.fs.system.mapper.SysConfigMapper;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.Synchronized;
|
|
|
+import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
|
|
|
+import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
|
|
|
+import me.chanjar.weixin.common.error.WxErrorException;
|
|
|
+import me.chanjar.weixin.mp.api.WxMpService;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.function.Supplier;
|
|
|
+
|
|
|
+import static com.fs.his.utils.PhoneUtil.encryptPhone;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 微信小程序用户接口
|
|
|
+ *
|
|
|
+ */
|
|
|
+@Api("微信接口")
|
|
|
+@RestController
|
|
|
+@RequestMapping(value="/app/wx")
|
|
|
+public class WxUserController extends AppBaseController{
|
|
|
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
|
+ @Autowired
|
|
|
+ private ConfigUtil configUtil;
|
|
|
+ @Autowired
|
|
|
+ private IFsUserService userService;
|
|
|
+ @Autowired
|
|
|
+ FsUserLoginLogMapper fsUserLoginLogMapper;
|
|
|
+ @Autowired
|
|
|
+ private SysConfigMapper sysConfigMapper;
|
|
|
+ @Autowired
|
|
|
+ JwtUtils jwtUtils;
|
|
|
+ @Autowired
|
|
|
+ RedisCache redisCache;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WxMpService wxMpService;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登陆接口
|
|
|
+ */
|
|
|
+ /**
|
|
|
+ * 登陆接口
|
|
|
+ */
|
|
|
+ @ApiOperation("登录")
|
|
|
+ @PostMapping("/login")
|
|
|
+ @Transactional
|
|
|
+ public R login( @RequestBody LoginParam param) {
|
|
|
+ if (StringUtils.isBlank(param.getCode())) {
|
|
|
+ return R.error("code不存在");
|
|
|
+ }
|
|
|
+ FsSysConfig con = configUtil.getSysConfig();
|
|
|
+ final WxMaService wxService = WxMaConfiguration.getMaService(con.getAppid());
|
|
|
+ try {
|
|
|
+ WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
|
|
|
+ this.logger.info(session.getSessionKey());
|
|
|
+ this.logger.info(session.getOpenid());
|
|
|
+ // 解密
|
|
|
+ WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
|
|
|
+ //三端用户同步,先用unionid查询
|
|
|
+ FsUser user = new FsUser();
|
|
|
+ if (session.getUnionid()!=null){
|
|
|
+ user = userService.selectFsUserByUnionid(session.getUnionid());
|
|
|
+ if (user==null){
|
|
|
+ user = userService.selectFsUserByOpenId(session.getOpenid());
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ user = userService.selectFsUserByOpenId(session.getOpenid());
|
|
|
+ }
|
|
|
+
|
|
|
+ if(user==null){
|
|
|
+ //新用户
|
|
|
+ String phoneNumber = phoneNoInfo.getPhoneNumber();
|
|
|
+
|
|
|
+
|
|
|
+ //查询手机号是否存在,如果存在,更新
|
|
|
+ FsUser checkPhone=userService.selectFsUserByPhone(encryptPhone(phoneNumber));
|
|
|
+ if (checkPhone==null){
|
|
|
+ checkPhone=userService.selectFsUserByPhone(phoneNumber);
|
|
|
+ }
|
|
|
+ if(checkPhone!=null){
|
|
|
+ user=checkPhone;
|
|
|
+ FsUser userMap=new FsUser();
|
|
|
+ userMap.setMaOpenId(session.getOpenid());
|
|
|
+ userMap.setUserId(checkPhone.getUserId());
|
|
|
+ userMap.setUpdateTime(new DateTime());
|
|
|
+ if(session.getUnionid()!=null){
|
|
|
+ userMap.setUnionId(session.getUnionid());
|
|
|
+ }
|
|
|
+ userService.updateFsUser(userMap);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ //写入
|
|
|
+ user=new FsUser();
|
|
|
+ user.setPhone(phoneNoInfo.getPhoneNumber());
|
|
|
+ user.setNickName("微信用户"+phoneNoInfo.getPhoneNumber().substring(phoneNoInfo.getPhoneNumber().length()-4));
|
|
|
+ user.setAvatar("https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230725/a848605591384ec29d49773dd58d9345.jpg");
|
|
|
+ user.setStatus(1);
|
|
|
+ user.setMaOpenId(session.getOpenid());
|
|
|
+ user.setCreateTime(new Date());
|
|
|
+ if(session.getUnionid()!=null){
|
|
|
+ user.setUnionId(session.getUnionid());
|
|
|
+ }
|
|
|
+ userService.insertFsUser(user);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ if(user.getStatus().equals(0)){
|
|
|
+
|
|
|
+ return R.error("此会员已禁用");
|
|
|
+ }
|
|
|
+ FsUser userMap=new FsUser();
|
|
|
+ userMap.setUserId(user.getUserId());
|
|
|
+ if(session.getUnionid()!=null){
|
|
|
+ userMap.setUnionId(session.getUnionid());
|
|
|
+ }
|
|
|
+ userMap.setMaOpenId(session.getOpenid());
|
|
|
+ userMap.setPhone(phoneNoInfo.getPhoneNumber());
|
|
|
+ userMap.setUpdateTime(new DateTime());
|
|
|
+ userService.updateFsUser(userMap);
|
|
|
+ }
|
|
|
+ String token = jwtUtils.generateToken(user.getUserId());
|
|
|
+// redisCache.setCacheObject("token:"+user.getUserId(),token,365, TimeUnit.DAYS);
|
|
|
+ Map<String,Object> map=new HashMap<>();
|
|
|
+ map.put("token",token);
|
|
|
+ user.setPhone(encryptPhone(phoneNoInfo.getPhoneNumber()));
|
|
|
+ map.put("user",user);
|
|
|
+ FsUserLoginLog log = new FsUserLoginLog();
|
|
|
+ log.setCode(param.getCode());
|
|
|
+ log.setLoginJson(JSON.toJSONString(param));
|
|
|
+// log.setUserRegisterJson(JSON.toJSONString(jsonMap));
|
|
|
+ log.setStatus(1);
|
|
|
+ log.setUserId(user.getUserId());
|
|
|
+ log.setPhone(user.getPhone());
|
|
|
+ log.setMaOpenId(user.getMaOpenId());
|
|
|
+ log.setCreateTime(DateUtils.getNowDate());
|
|
|
+ fsUserLoginLogMapper.insertFsUserLoginLog(log);
|
|
|
+ return R.ok(map);
|
|
|
+ } catch (WxErrorException e) {
|
|
|
+ //this.logger.error(e.getMessage(), e);
|
|
|
+ return R.error("授权失败,"+e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("小程序看课登录")
|
|
|
+ @PostMapping("/courseLogin")
|
|
|
+ @Transactional
|
|
|
+ public R courseLogin(@RequestBody LoginParam param) {
|
|
|
+ SysConfig sysConfig3 = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
|
|
|
+ List<CourseMaConfig> courseMaConfigs = JSON.parseArray(sysConfig3.getConfigValue(), CourseMaConfig.class);
|
|
|
+ if (courseMaConfigs.isEmpty()){
|
|
|
+ return R.error("小程序配置为空");
|
|
|
+ }
|
|
|
+ CourseMaConfig courseMaConfig = courseMaConfigs.get(0);
|
|
|
+ return handleCourseLogin(param,
|
|
|
+ () -> WxMaConfiguration.getMaService(courseMaConfig.getAppid()),
|
|
|
+ courseMaConfig.getName());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 公共登录处理方法
|
|
|
+ * @param param 登录参数
|
|
|
+ * @param wxServiceSupplier 微信服务提供函数(差异化点1:不同方式获取WxMaService)
|
|
|
+ * @param logName 日志名称(差异化点2:不同场景标识)
|
|
|
+ */
|
|
|
+ private R handleCourseLogin(LoginParam param, Supplier<WxMaService> wxServiceSupplier, String logName) {
|
|
|
+ if (StringUtils.isBlank(param.getCode())) {
|
|
|
+ return R.error("code不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 通过函数式接口获取不同的微信服务实例
|
|
|
+ final WxMaService wxService = wxServiceSupplier.get();
|
|
|
+ WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
|
|
|
+ this.logger.info("获取{} Session:{}", logName, session);
|
|
|
+
|
|
|
+ FsUser user = userService.selectFsUserByUnionid(session.getUnionid());
|
|
|
+ boolean isNewUser = false;
|
|
|
+
|
|
|
+ // 用户存在时的更新逻辑
|
|
|
+ if(user != null){
|
|
|
+ FsUser userMap = new FsUser();
|
|
|
+ userMap.setUserId(user.getUserId());
|
|
|
+ userMap.setCourseMaOpenId(session.getOpenid());
|
|
|
+ userMap.setUpdateTime(new DateTime());
|
|
|
+ userService.updateFsUser(userMap);
|
|
|
+ }
|
|
|
+ // 用户不存在时的创建逻辑
|
|
|
+ else {
|
|
|
+ user = new FsUser();
|
|
|
+ user.setNickName("微信用户");
|
|
|
+ user.setAvatar("https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230725/a848605591384ec29d49773dd58d9345.jpg");
|
|
|
+ user.setStatus(1);
|
|
|
+ user.setCourseMaOpenId(session.getOpenid());
|
|
|
+ user.setUnionId(session.getUnionid());
|
|
|
+ user.setCreateTime(new Date());
|
|
|
+ userService.insertFsUser(user);
|
|
|
+ isNewUser = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成Token
|
|
|
+ String token = jwtUtils.generateToken(user.getUserId());
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ map.put("token", token);
|
|
|
+ map.put("user", user);
|
|
|
+ map.put("isNew", isNewUser);
|
|
|
+
|
|
|
+ logger.info("zyp \n 【点播{}登录】:{}", logName, user.getUserId());
|
|
|
+ return R.ok(map);
|
|
|
+ } catch (WxErrorException e){
|
|
|
+ logger.error("{}授权失败:{}", logName, e.getMessage(), e);
|
|
|
+ return R.error("授权失败," + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static String genCode() {
|
|
|
+ String year = new SimpleDateFormat("yy").format(new Date());
|
|
|
+ String day = String.format("%tj", new Date());
|
|
|
+ double random = Math.random() * 10000000;
|
|
|
+ while (random < 1000000) {
|
|
|
+ random = Math.random() * 10000000;
|
|
|
+ }
|
|
|
+ int intRandom = Double.valueOf(random).intValue();
|
|
|
+ String verifyCode = year + day + intRandom;
|
|
|
+ return verifyCode;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("公众号登录")
|
|
|
+ @PostMapping("/loginByMp")
|
|
|
+ public R loginByMp( @RequestBody LoginParam param) {
|
|
|
+ if (StringUtils.isBlank(param.getCode())) {
|
|
|
+ return R.error("code不存在");
|
|
|
+ }
|
|
|
+ try{
|
|
|
+ WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
|
|
|
+ WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
|
|
|
+ FsUser user=userService.selectFsUserByUnionid(wxMpUser.getUnionId());
|
|
|
+ if(user!=null){
|
|
|
+ FsUser userMap=new FsUser();
|
|
|
+ userMap.setUserId(user.getUserId());
|
|
|
+ userMap.setNickName(wxMpUser.getNickname());
|
|
|
+ userMap.setAvatar(wxMpUser.getHeadImgUrl());
|
|
|
+ userMap.setMpOpenId(wxMpUser.getOpenid());
|
|
|
+ userMap.setUpdateTime(new DateTime());
|
|
|
+ userService.updateFsUser(userMap);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ //写入
|
|
|
+ String code=genCode();
|
|
|
+ user=new FsUser();
|
|
|
+ user.setNickName(wxMpUser.getNickname());
|
|
|
+ user.setAvatar(wxMpUser.getHeadImgUrl());
|
|
|
+ user.setStatus(1);
|
|
|
+ user.setSex(wxMpUser.getSex());
|
|
|
+ user.setMpOpenId(wxMpUser.getOpenid());
|
|
|
+ user.setUnionId(wxMpUser.getUnionId());
|
|
|
+ user.setCreateTime(new Date());
|
|
|
+ userService.insertFsUser(user);
|
|
|
+ }
|
|
|
+ String token = jwtUtils.generateToken(user.getUserId());
|
|
|
+ redisCache.setCacheObject("token:"+user.getUserId(),token,604800, TimeUnit.SECONDS);
|
|
|
+ Map<String,Object> map=new HashMap<>();
|
|
|
+ map.put("token",token);
|
|
|
+ map.put("user",user);
|
|
|
+
|
|
|
+ FsUserLoginLog log = new FsUserLoginLog();
|
|
|
+ log.setCode(param.getCode());
|
|
|
+ log.setLoginJson(JSON.toJSONString(param));
|
|
|
+// log.setUserRegisterJson(JSON.toJSONString(jsonMap));
|
|
|
+ log.setStatus(1);
|
|
|
+ log.setUserId(user.getUserId());
|
|
|
+ log.setPhone(user.getPhone());
|
|
|
+ log.setMaOpenId(user.getMaOpenId());
|
|
|
+ log.setCreateTime(DateUtils.getNowDate());
|
|
|
+ fsUserLoginLogMapper.insertFsUserLoginLog(log);
|
|
|
+ return R.ok(map);
|
|
|
+ }
|
|
|
+ catch (WxErrorException e){
|
|
|
+ if(e.getError().getErrorCode()==40163){
|
|
|
+ return R.error(40163,e.getError().getErrorMsg());
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ return R.error("授权失败,"+e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * <pre>
|
|
|
+ * 获取微信用户信息
|
|
|
+ * </pre>
|
|
|
+ */
|
|
|
+ @Login
|
|
|
+ @ApiOperation("获取微信小程序用户信息")
|
|
|
+ @PostMapping("/getWeixinInfo")
|
|
|
+ public R getWeixinInfo(@RequestBody LoginParam param) {
|
|
|
+ FsSysConfig con = configUtil.getSysConfig();
|
|
|
+ final WxMaService wxService = WxMaConfiguration.getMaService(con.getAppid());
|
|
|
+ try {
|
|
|
+ WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
|
|
|
+ // 用户信息校验
|
|
|
+ if (!wxService.getUserService().checkUserInfo(session.getSessionKey(), param.getRawData(), param.getSignature())) {
|
|
|
+ return R.error("user check failed");
|
|
|
+ }
|
|
|
+ // 解密用户信息
|
|
|
+ WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
|
|
|
+ FsUser user=userService.selectFsUserByUserId(Long.parseLong(getUserId()));
|
|
|
+ user.setNickName(userInfo.getNickName());
|
|
|
+ user.setAvatar(userInfo.getAvatarUrl());
|
|
|
+ user.setIsWeixinAuth(1);
|
|
|
+ userService.updateFsUser(user);
|
|
|
+ return R.ok();
|
|
|
+ } catch (WxErrorException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return R.ok("授权成功");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @GetMapping("/loginTest")
|
|
|
+ @Synchronized
|
|
|
+ public R loginByMp(String phone) {
|
|
|
+ //如果开启了UnionId
|
|
|
+ FsUser user=userService.selectFsUserByMpOpenId(phone);
|
|
|
+ String token = jwtUtils.generateToken(user.getUserId());
|
|
|
+ return R.ok("登录成功").put("token",token).put("user", user);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|