Bläddra i källkod

feat(course):优化课程奖励发放逻辑并增强微信登录校验

- 添加 Redis 分布式锁防止奖励重复发放
- 微信登录增加 UnionId 校验,确保用户唯一性
-重构奖励发放方法,提取核心业务逻辑至独立函数
- 移除冗余代码和未使用的导入包
-优化红包发放流程,完善异常处理与日志记录
- 调整公司余额校验逻辑,提升安全性
- 注释掉部分旧的余额回滚逻辑,待后续完善
- 增加对 APP 来源用户的积分奖励特殊处理
- 删除重复的时间工具类导入
- 补充锁竞争时的提示信息,改善用户体验
xw 18 timmar sedan
förälder
incheckning
db5909b108

+ 189 - 121
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.BeanCopyUtils;
-import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.constant.FsConstants;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
@@ -71,7 +70,6 @@ import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
 import com.google.common.collect.Sets;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.jetbrains.annotations.NotNull;
 import org.redisson.api.RLock;
@@ -93,9 +91,6 @@ import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
-import java.text.SimpleDateFormat;
-import java.time.*;
-import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
@@ -247,15 +242,17 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     @Autowired
     private IFsUserCompanyBindService fsUserCompanyBindService;
 
-    @Autowired
-    private IFsUserCoursePeriodService fsUserCoursePeriodService;
     @Autowired
     private BalanceRollbackErrorMapper balanceRollbackErrorMapper;
-
+    @Autowired
+    private IFsUserCoursePeriodService fsUserCoursePeriodService;
 
     @Autowired
     private IFsUserCoursePeriodDaysService fsUserCoursePeriodDaysService;
 
+
+
+
     /**
      * 查询课堂视频
      *
@@ -1085,72 +1082,99 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 //        if (isWithin10Minutes){
 //            return R.error("非有效期内,不允许领取!");
 //        }
-        // 获取用户信息
-        FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
+        // 生成锁的key,基于用户ID和视频ID确保同一用户同一视频的请求被锁定
+        String lockKey = "reward_lock:user:" + param.getUserId() + ":video:" + param.getVideoId();
+        RLock lock = redissonClient.getLock(lockKey);
+
+        try {
+            // 尝试获取锁,等待时间5秒,锁过期时间30秒
+            boolean isLocked = lock.tryLock(5, 60, TimeUnit.SECONDS);
+            if (!isLocked) {
+                logger.warn("获取锁失败,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
+                return R.error("操作频繁,请稍后再试!");
+            }
+
+            logger.info("成功获取锁,开始处理奖励发放,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
+            // 获取用户信息
+            FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
 //        if (StringUtils.isEmpty(user.getMpOpenId())){
 //            return R.error("未识别到领取信息");
 //        }
-        log.info("查询会员信息:{}", user);
-        if (user.getStatus()==0){
-            return R.error("会员被停用,无权限,请联系客服!");
-        }
-        FsCourseWatchLog watchLog = new FsCourseWatchLog();
+            log.info("查询会员信息:{}", user);
+            if (user.getStatus()==0){
+                return R.error("会员被停用,无权限,请联系客服!");
+            }
+            FsCourseWatchLog watchLog = new FsCourseWatchLog();
 
-        // 根据链接类型判断是否已发放奖励
-        watchLog = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
-        log.info("看课记录:{}", watchLog);
-        if (watchLog == null) {
-            return R.error("无记录");
-        }
-        if (watchLog.getLogType() != 2) {
-            return R.error("未完课");
-        }
-        if (watchLog.getRewardType() != null) {
-            FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
-            log.info("课程红包:{}", packetLog);
-            if(packetLog != null && packetLog.getStatus() == 1) {
-                return R.error("已领取该课程奖励,不可重复领取!");
+            // 根据链接类型判断是否已发放奖励
+            watchLog = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
+            log.info("看课记录:{}", watchLog);
+            if (watchLog == null) {
+                return R.error("无记录");
             }
-            if(packetLog != null && packetLog.getStatus() == 0) {
-                log.info("判断领取记录");
-                if(StringUtils.isNotEmpty(packetLog.getResult())){
-                    log.info("是否有结果");
-                    R r = JSON.parseObject(packetLog.getResult(), R.class);
-                    return r;
-                } else {
-                    return R.error("操作频繁,请稍后再试!");
+            if (watchLog.getLogType() != 2) {
+                return R.error("未完课");
+            }
+            if (watchLog.getRewardType() != null) {
+                FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
+                log.info("课程红包:{}", packetLog);
+                if(packetLog != null && packetLog.getStatus() == 1) {
+                    return R.error("已领取该课程奖励,不可重复领取!");
+                }
+                if(packetLog != null && packetLog.getStatus() == 0) {
+                    log.info("判断领取记录");
+                    if(StringUtils.isNotEmpty(packetLog.getResult())){
+                        log.info("是否有结果");
+                        R r = JSON.parseObject(packetLog.getResult(), R.class);
+                        return r;
+                    } else {
+                        return R.error("操作频繁,请稍后再试!");
+                    }
+                }
+                if(packetLog != null && packetLog.getStatus() == 2) {
+                    return R.error("请联系客服补发");
                 }
+                return R.error("奖励已发放");
+            }
+            // 获取视频信息
+            FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
+
+            // 获取配置信息
+            String json = configService.selectConfigByKey("course.config");
+            CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+            log.info("奖励类型:{}", config.getRewardType());
+            // 根据奖励类型发放不同奖励
+            switch (config.getRewardType()) {
+                // 红包奖励
+                case 1:
+                    return sendRedPacketReward(param, user, watchLog, video, config);
+                // 积分奖励
+                case 2:
+                    return sendIntegralReward(param,user, watchLog, config);
+                // 红包+积分
+                case 3:
+                    R sendRed = sendRedPacketReward(param, user, watchLog, video, config);
+                    if (!Objects.equals(sendRed.get("code"), 200)) {
+                        return sendRed;
+                    }
+                    return sendIntegralReward(param,user, watchLog, config);
+                default:
+                    return R.error("参数错误!");
             }
-            if(packetLog != null && packetLog.getStatus() == 2) {
-                return R.error("请联系客服补发");
+//            return executeSendRewardBusiness(param);
+
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            logger.error("获取锁被中断,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId(), e);
+            return R.error("系统繁忙,请重试!");
+        } finally {
+            // 释放锁
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+                logger.info("释放锁成功,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
             }
-            return R.error("奖励已发放");
         }
-        // 获取视频信息
-        FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
 
-        // 获取配置信息
-        String json = configService.selectConfigByKey("course.config");
-        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        log.info("奖励类型:{}", config.getRewardType());
-        // 根据奖励类型发放不同奖励
-        switch (config.getRewardType()) {
-            // 红包奖励
-            case 1:
-                return sendRedPacketReward(param, user, watchLog, video, config);
-            // 积分奖励
-            case 2:
-                return sendIntegralReward(param,user, watchLog, config);
-            // 红包+积分
-            case 3:
-                R sendRed = sendRedPacketReward(param, user, watchLog, video, config);
-                if (!Objects.equals(sendRed.get("code"), 200)) {
-                    return sendRed;
-                }
-                return sendIntegralReward(param,user, watchLog, config);
-            default:
-                return R.error("参数错误!");
-        }
     }
 
 
@@ -1178,22 +1202,60 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     @Override
     public R sendRewardByFsUser(FsCourseSendRewardUParam param) {
+        // 生成锁的key,基于用户ID和视频ID确保同一用户同一视频的请求被锁定
+        String lockKey = "reward_lock:user:" + param.getUserId() + ":video:" + param.getVideoId();
+        RLock lock = redissonClient.getLock(lockKey);
+
+        try {
+            // 尝试获取锁,等待时间5秒,锁过期时间30秒
+            boolean isLocked = lock.tryLock(5, 60, TimeUnit.SECONDS);
+            if (!isLocked) {
+                logger.warn("获取锁失败,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
+                return R.error("操作频繁,请稍后再试!");
+            }
+
+            logger.info("成功获取锁,开始处理奖励发放,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
+            return executeSendRewardBusiness(param);
+
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            logger.error("获取锁被中断,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId(), e);
+            return R.error("系统繁忙,请重试!");
+        } finally {
+            // 释放锁
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+                logger.info("释放锁成功,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
+            }
+        }
+    }
+
+
+    /**
+     * 实际的奖励发放业务逻辑
+     */
+    private R executeSendRewardBusiness(FsCourseSendRewardUParam param) {
         log.info("进入用户判断");
         FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
-        if (user == null){
+        if (user == null || user.getStatus()==0){
             return R.error("未识别到用户信息");
         }
+
         FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByFsUser(param.getUserId(), param.getVideoId(), param.getCompanyUserId());
         if (log == null) {
             return R.error("无记录");
         }
 
-        FsCourseAnswerLogs rightLog = courseAnswerLogsMapper.selectRightLogByCourseVideo(param.getVideoId(), param.getUserId(), param.getQwUserId());
+        if (log.getLogType() != 2){
+            return R.error("未完课");
+        }
 
+        FsCourseAnswerLogs rightLog = courseAnswerLogsMapper.selectRightLogByCourseVideo(param.getVideoId(), param.getUserId(), param.getQwUserId());
         if (rightLog == null) {
             logger.error("未答题:{}",param.getUserId());
             return R.error("未答题");
         }
+
         if (log.getRewardType() != null ) {
             if (log.getRewardType() == 1){
                 FsCourseRedPacketLog fsCourseRedPacketLog = redPacketLogMapper.selectUserFsCourseRedPacketLog(param.getVideoId(), param.getUserId(),param.getPeriodId());
@@ -1211,11 +1273,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             }else if (log.getRewardType() == 2){
                 return R.error("已领取该课程奖励,不可重复领取!");
             }
-
         }
 
-
-
         // 获取视频信息
         FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
 
@@ -1223,6 +1282,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
 
+        // 判断来源是否是app,如是app,则发放积分奖励
+        int sourceApp = 3;
+        if(sourceApp == param.getSource()){
+            return sendIntegralReward(param, user, log, config);
+        }
+
         // 根据奖励类型发放不同奖励
         switch (config.getRewardType()) {
             // 红包奖励
@@ -1321,11 +1386,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         logger.info("红包金额 {},红包商户号 {}",amount,packetParam);
         //2025.6.19 红包金额为0的时候
         if (amount.compareTo(BigDecimal.ZERO)>0){
-            Company company = companyMapper.selectCompanyById(param.getCompanyId());
-            BigDecimal money = company.getMoney();
-            if (money.compareTo(BigDecimal.ZERO)<0) {
-                return R.error("服务商余额不足,请联系群主服务器充值!");
-            }
             // 发送红包
             return sendRedPacketRewardToUser(param, log, config, packetParam, amount);
         } else {
@@ -1355,32 +1415,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     private R sendRedPacketRewardToUser(FsCourseSendRewardUParam param, FsCourseWatchLog log, CourseConfig config, WxSendRedPacketParam packetParam, BigDecimal amount) {
 
-        //  添加分布式锁,防止同一秒内重复点击
-        String lockKey = String.format("redPacket:user:%s:video:%s:period:%s", 
-            param.getUserId(), param.getVideoId(), param.getPeriodId());
-        RLock lock = redissonClient.getLock(lockKey);
-        
-        try {
-            // 尝试获取锁(等待3秒,持有10秒)
-            boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
-            if (!locked) {
-                logger.warn("【红包领取】获取锁失败,userId:{}, videoId:{}, periodId:{}", 
-                    param.getUserId(), param.getVideoId(), param.getPeriodId());
-                return R.error("系统繁忙,请稍后重试!");
-            }
-            
-            //  双重检查:再次查询是否已经领取过
-            FsCourseRedPacketLog existQuery = new FsCourseRedPacketLog();
-            existQuery.setUserId(param.getUserId());
-            existQuery.setVideoId(param.getVideoId());
-            existQuery.setPeriodId(param.getPeriodId());
-            List<FsCourseRedPacketLog> existLogs = redPacketLogMapper.selectFsCourseRedPacketLogList(existQuery);
-            
-            if (existLogs != null && !existLogs.isEmpty()) {
-                logger.warn("【红包领取】用户已领取过红包,userId:{}, videoId:{}, periodId:{}, 已存在{}条记录",
-                    param.getUserId(), param.getVideoId(), param.getPeriodId(), existLogs.size());
-                return R.error("已领取该课程奖励,不可重复领取!");
-            }
 
         // 发送红包
         R sendRedPacket = paymentService.sendRedPacket(packetParam);
@@ -1418,26 +1452,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         } else {
             return R.error("奖励发送失败,请联系客服");
         }
-        
-        } catch (InterruptedException e) {
-            logger.error("【红包领取】获取锁被中断", e);
-            Thread.currentThread().interrupt();
-            return R.error("系统繁忙,请稍后重试!");
-        } catch (Exception e) {
-            logger.error("【红包领取】发放红包异常,userId:{}, videoId:{}", 
-                param.getUserId(), param.getVideoId(), e);
-            return R.error("红包发放失败,请联系客服");
-        } finally {
-            // 释放锁
-            if (lock != null && lock.isHeldByCurrentThread()) {
-                lock.unlock();
-                logger.info("【红包领取】释放锁成功,userId:{}, videoId:{}", 
-                    param.getUserId(), param.getVideoId());
-            }
-        }
     }
 
 
+
+
     private void handleFsUserWx(FsUser user, String appId) {
         FsUserWx fsUserWx = new FsUserWx();
         fsUserWx.setType(1);
@@ -1535,17 +1554,61 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         //2025.6.19 红包金额为0的时候
         if (amount.compareTo(BigDecimal.ZERO)>0){
+
             Company company = companyMapper.selectCompanyById(param.getCompanyId());
             BigDecimal money = company.getMoney();
             if (money.compareTo(BigDecimal.ZERO)<=0) {
                 return R.error("服务商余额不足,请联系群主服务器充值!");
             }
+
+            // 发送红包
+            R sendRedPacket = paymentService.sendRedPacket(packetParam);
+            if (sendRedPacket.get("code").equals(200)) {
+                FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
+                TransferBillsResult transferBillsResult;
+                if (sendRedPacket.get("isNew").equals(1)){
+                    transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
+                    redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
+                    redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
+                    redPacketLog.setBatchId(transferBillsResult.getTransferBillNo());
+                }else {
+                    redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+                    redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());
+                }
+                // 添加红包记录
+                redPacketLog.setCourseId(param.getCourseId());
+                redPacketLog.setCompanyId(param.getCompanyId());
+                redPacketLog.setUserId(param.getUserId());
+                redPacketLog.setVideoId(param.getVideoId());
+                redPacketLog.setStatus(0);
+                redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null);
+                redPacketLog.setCompanyUserId(param.getCompanyUserId());
+                redPacketLog.setCreateTime(new Date());
+                redPacketLog.setAmount(amount);
+                redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
+                redPacketLog.setPeriodId(param.getPeriodId());
+                redPacketLog.setAppId(param.getAppId());
+
+                redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+
+                // 更新观看记录的奖励类型
+                log.setRewardType(config.getRewardType());
+                courseWatchLogMapper.updateFsCourseWatchLog(log);
+
+                return sendRedPacket;
+            } else {
+                return R.error("奖励发送失败,请联系客服");
+            }
+
+            // 先注释 20251024 redis 余额 充值没有考虑 其余扣减没有考虑
             // ===================== 20251022 xgb 修改 本次修改目的为了实时扣减公司余额=====================
             // 1 使用redis缓存加锁 预扣减余额 红包发送失败 恢复redis缓存余额,如果回滚失败登记异常记录表 定时任务重新回滚余额
             // 2 另起定时任务 同步缓存余额到redis中
             // 3 启动系统时查询公司账户余额(这个时候要保证余额正确)保存到redis缓存中
 
+
             // 预设值异常对象
+            /*
             BalanceRollbackError balanceRollbackError = new BalanceRollbackError();
             balanceRollbackError.setCompanyId(packetParam.getCompanyId());
             balanceRollbackError.setUserId(user.getUserId());
@@ -1603,6 +1666,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 }
             }
 
+
+
             // 调用第三方接口(锁外操作)
             R sendRedPacket;
             try {
@@ -1611,7 +1676,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 logger.error("红包发送异常: 异常请求参数{}",packetParam, e);
                 // 异常时回滚余额
 
-                rollbackBalance(balanceRollbackError);
+//                rollbackBalance(balanceRollbackError);
                 return R.error("奖励发送失败,请联系客服");
             }
 
@@ -1649,12 +1714,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 courseWatchLogMapper.updateFsCourseWatchLog(log);
                 // 发送成功,记录日志等操作
                 return sendRedPacket;
+
+
             } else {
                 // 发送失败,回滚余额
-                rollbackBalance(balanceRollbackError);
+//                rollbackBalance(balanceRollbackError);
                 return R.error("奖励发送失败,请联系客服");
             }
-
+             */
             // ===================== 本次修改目的为了实时扣减公司余额=====================
         } else {
             FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
@@ -1871,7 +1938,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         redPacketLog.setWatchLogId(log.getLogId() !=null ? log.getLogId() : null);
         redPacketLog.setPeriodId(param.getPeriodId());
         redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
-        return R.ok("奖励发放成功").put("rewardType",config.getRewardType());
+        return R.ok("积分奖励发放成功").put("rewardType",config.getRewardType());
     }
 
     @Override
@@ -2479,6 +2546,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             });
         }
     }
+
     @Override
     public void batchUpdateRed(List<BatchRedUpdate> list) {
         list.forEach(e -> {

+ 3 - 0
fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java

@@ -153,6 +153,9 @@ public class WxH5MpController {
             // 获取微信用户信息
             WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
             WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
+            if (StringUtils.isEmpty(wxMpUser.getUnionId())){
+                return R.error("未绑定开放平台");
+            }
 
             // 处理用户信息
             FsUser user = processUserInfoByCourseLoginByMp(wxMpUser);

+ 3 - 0
fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

@@ -318,6 +318,9 @@ public class WxUserController extends AppBaseController{
         try{
             WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
             WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
+            if (StringUtils.isEmpty(wxMpUser.getUnionId())){
+                return R.error("未绑定开放平台");
+            }
             FsUser user=userService.selectFsUserByUnionid(wxMpUser.getUnionId());
             if(user!=null){
                 FsUser userMap=new FsUser();

+ 3 - 5
fs-user-app/src/main/java/com/fs/app/controller/course/CourseMpLoginController.java

@@ -80,11 +80,9 @@ public class CourseMpLoginController {
     try{
       WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
       WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
-      WxMpUserService wxMpUserService = wxMpService.getUserService();
-//      WxMpUser userInfo = wxMpUserService.userInfo(wxMpUser.getOpenid());
-//      if (!userInfo.getSubscribe()){
-//        return R.error("请关注公众号进行登录");
-//      }
+      if(StringUtils.isBlank(wxMpUser.getUnionId())){
+        return R.error("请使用微信扫码登录");
+      }
       FsUser user=userService.selectFsUserByUnionid(wxMpUser.getUnionId());
       if(user!=null){
         FsUser userMap=new FsUser();