Kaynağa Gözat

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_java

caoliqin 4 gün önce
ebeveyn
işleme
de33d403cc

+ 2 - 1
fs-common/src/main/java/com/fs/common/enums/DataSourceType.java

@@ -18,5 +18,6 @@ public enum DataSourceType
     /**
      * 从库
      */
-    SLAVE
+    SLAVE,
+    SopREAD
 }

+ 5 - 0
fs-company-app/src/main/java/com/fs/app/controller/UserController.java

@@ -156,6 +156,7 @@ public class UserController extends AppBaseController {
         }
 
         try {
+
             //判断用户基本规则
             CompanyUser companyUser = userService.selectUserByUserName(param.getAccount());
             if (companyUser == null) {
@@ -176,6 +177,10 @@ public class UserController extends AppBaseController {
                 throw new BaseException("此用户所属公司不存在或已停用");
             }
 
+            if (StringUtils.isNotEmpty(company.getCourseMiniAppId()) && !company.getCourseMiniAppId().equals(param.getAppId())){
+                return R.error("登录用户不属于该小程序");
+            }
+
             // 公司名称
             companyUser.setCompanyName(company.getCompanyName());
             // 岗位

+ 2 - 0
fs-company-app/src/main/java/com/fs/app/param/LoginParam.java

@@ -14,4 +14,6 @@ public class LoginParam {
     private String password;
 
     private String jpushId;
+
+    private String appId;
 }

+ 7 - 0
fs-service/src/main/java/com/fs/common/param/LoginMaWxParam.java

@@ -46,4 +46,11 @@ public class LoginMaWxParam implements Serializable {
 //    @ApiModelProperty(value = "用户密码")
 //    private String password;
 
+    /**
+     * 0:静默授权  1:手机号授权
+     */
+    @NotNull(message = "授权类型缺失")
+    @ApiModelProperty(value = "小程序授权类型")
+    private Integer authType;
+
 }

+ 2 - 0
fs-service/src/main/java/com/fs/course/domain/FsCourseRealLink.java

@@ -43,4 +43,6 @@ public class FsCourseRealLink implements Serializable
     private Long id;
 
     private String chatId;
+
+    private Long projectId;//项目ID
 }

+ 159 - 1
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -914,7 +914,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         switch (config.getRewardType()) {
             // 红包奖励
             case 1:
-                return sendRedPacketReward(param, user, log, video, config);
+                return sendRedPacketRewardFsUser(param, user, log, video, config);
             // 积分奖励
             case 2:
                 return sendIntegralReward(param,user, log, config);
@@ -1073,6 +1073,164 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     }
 
+    /**
+     * 发放红包奖励
+     *
+     * @param param 请求参数
+     * @param user 用户信息
+     * @param log 观看日志
+     * @param video 视频信息
+     * @param config 配置信息
+     * @return 处理结果
+     */
+    private R sendRedPacketRewardFsUser(FsCourseSendRewardUParam param, FsUser user, FsCourseWatchLog log, FsUserCourseVideo video, CourseConfig config) {
+        // 判断是否属于领取红包时间(会员看课发放红包)
+        if (param.getPeriodId()!=null && param.getPeriodId()>0) {
+            FsUserCoursePeriodDays periodDays = new FsUserCoursePeriodDays();
+            periodDays.setVideoId(param.getVideoId());
+            periodDays.setPeriodId(param.getPeriodId());
+            //正常情况是只能查询到一条,之前可能存在重复的脏数据,暂使用查询list的方式
+            List<FsUserCoursePeriodDays> fsUserCoursePeriodDays = fsUserCoursePeriodDaysMapper.selectFsUserCoursePeriodDaysList(periodDays);
+            if(fsUserCoursePeriodDays != null && !fsUserCoursePeriodDays.isEmpty()){
+                periodDays = fsUserCoursePeriodDays.get(0);
+            }
+            if(periodDays != null && periodDays.getLastJoinTime() !=null && LocalDateTime.now().isAfter(periodDays.getLastJoinTime())) {
+                return R.error(403,"已超过领取红包时间");
+            }
+        }
+
+        // 确定红包金额
+        BigDecimal amount = BigDecimal.ZERO;
+        FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(param.getVideoId(), param.getCompanyId(), param.getPeriodId());
+
+        if (redPackage != null) {
+            amount = redPackage.getRedPacketMoney();
+        } else if (video != null) {
+            amount = video.getRedPacketMoney();
+        }
+
+        // 准备发送红包参数
+        WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
+//        packetParam.setOpenId(getOpenId(user.getUserId(), param.getCompanyId(), param.getSource()));
+        packetParam.setOpenId(user.getMpOpenId());
+        // 来源是小程序切换openId
+        if (param.getSource() == 2) {
+            //处理多小程序问题
+            Company company = companyMapper.selectCompanyById(param.getCompanyId());
+            if (company.getCourseMiniAppId()==null){
+                return R.error("销售公司参数错误,未绑定小程序");
+            }
+            FsUserWx fsUserWx = fsUserWxService.selectByAppIdAndUserId(company.getCourseMiniAppId(),user.getUserId(),1);
+            if (fsUserWx ==null || fsUserWx.getOpenId()==null){
+                return R.error("小程序openId参数缺失");
+            }
+
+            System.out.println("小程序id"+user.getCourseMaOpenId());
+            //查出公司绑定openid并赋值
+            packetParam.setOpenId(fsUserWx.getOpenId());
+        }
+        packetParam.setAmount(amount);
+        packetParam.setSource(param.getSource());
+        packetParam.setRedPacketMode(config.getRedPacketMode());
+        packetParam.setCompanyId(param.getCompanyId());
+
+        System.out.println("红包金额"+amount);
+        System.out.println("红包商户号"+packetParam);
+        //2025.6.19 红包金额为0的时候
+        if (amount.compareTo(BigDecimal.ZERO)>0){
+
+            Company company = companyMapper.selectCompanyByIdForUpdate(param.getCompanyId());
+            BigDecimal money = company.getMoney();
+            BigDecimal subtract = money.subtract(amount);
+            if (subtract.compareTo(BigDecimal.ZERO)<0){
+                FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
+                redPacketLog.setCourseId(param.getCourseId());
+                redPacketLog.setCompanyId(param.getCompanyId());
+                redPacketLog.setUserId(param.getUserId());
+                redPacketLog.setVideoId(param.getVideoId());
+                redPacketLog.setStatus(2);
+                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());
+                redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+                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());
+                }else {
+                    redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+                }
+                // 添加红包记录
+                redPacketLog.setCourseId(param.getCourseId());
+//            redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+                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());
+                redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+
+                // 更新观看记录的奖励类型
+                log.setRewardType(config.getRewardType());
+                courseWatchLogMapper.updateFsCourseWatchLog(log);
+                company.setMoney(subtract);
+                companyMapper.updateCompany(company);
+
+                CompanyMoneyLogs logs=new CompanyMoneyLogs();
+                logs.setCompanyId(company.getCompanyId());
+                logs.setRemark("扣除红包金额");
+                logs.setMoney(amount.multiply(new BigDecimal(-1)));
+                logs.setLogsType(15);
+                logs.setBalance(company.getMoney());
+                logs.setCreateTime(new Date());
+                moneyLogsMapper.insertCompanyMoneyLogs(logs);
+
+                return sendRedPacket;
+            } else {
+                return R.error("奖励发送失败,请联系客服");
+            }
+        } else {
+            FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
+            // 添加红包记录
+            redPacketLog.setCourseId(param.getCourseId());
+//            redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+            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(BigDecimal.ZERO);
+            redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
+            redPacketLog.setPeriodId(param.getPeriodId());
+            redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+
+            // 更新观看记录的奖励类型
+//            if (param.getLinkType() == null || param.getLinkType() == 0) {
+            log.setRewardType(config.getRewardType());
+            courseWatchLogMapper.updateFsCourseWatchLog(log);
+//            }
+            return R.ok("红包发送成功");
+        }
+
+    }
+
     /**
      * 获取用户openId
      *

+ 13 - 2
fs-service/src/main/java/com/fs/his/domain/FsUserWx.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.Date;
 
 @Data
 @TableName("fs_user_wx")
@@ -17,6 +18,11 @@ public class FsUserWx {
      * 用户ID
      */
     private Long fsUserId;
+
+    /**
+     * 公司ID
+     */
+    private Long companyId;
     /**
      * 小程序/公众号appId
      */
@@ -29,12 +35,17 @@ public class FsUserWx {
      * 微信openId
      */
     private String openId;
+
+    /**
+     * 1:小程序 2:服务号
+     */
+    private Integer type;
     /**
      * 创建时间
      */
-    private LocalDateTime createTime;
+    private Date createTime;
     /**
      * 修改时间
      */
-    private LocalDateTime updateTime;
+    private Date updateTime;
 }

+ 2 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserWxService.java

@@ -10,4 +10,6 @@ public interface IFsUserWxService extends IService<FsUserWx> {
      * @param wx    配置信息
      */
     void saveOrUpdateByUniqueKey(FsUserWx wx);
+
+    FsUserWx selectByAppIdAndUserId(String appId, Long userId,Integer type);
 }

+ 11 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserWxServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.his.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.his.domain.FsUserWx;
 import com.fs.his.mapper.FsUserWxMapper;
@@ -19,4 +20,14 @@ public class FsUserWxServiceImpl extends ServiceImpl<FsUserWxMapper, FsUserWx> i
     public void saveOrUpdateByUniqueKey(FsUserWx wx) {
         baseMapper.insertOrUpdateByUniqueKey(wx);
     }
+
+    @Override
+    public FsUserWx selectByAppIdAndUserId(String appId, Long userId,Integer type) {
+        return this.baseMapper.selectOne(
+                new QueryWrapper<FsUserWx>()
+                        .eq("app_id", appId)
+                        .eq("fs_user_id", userId)
+                        .eq("type", type)
+        );
+    }
 }

+ 6 - 2
fs-user-course/src/main/java/com/fs/course/controller/CourseWxH5Controller.java

@@ -1,10 +1,11 @@
 package com.fs.course.controller;
 
 
-import com.fs.course.annotation.Login;
+
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
+import com.fs.course.annotation.Login;
 import com.fs.course.param.FsCourseQuestionAnswerUParam;
 import com.fs.course.param.FsCourseSendRewardUParam;
 import com.fs.course.param.FsUserCourseVideoFinishUParam;
@@ -36,6 +37,9 @@ public class CourseWxH5Controller extends AppBaseController {
     @Autowired
     private IFsUserCourseVideoService courseVideoService;
 
+    @Autowired
+    private ISysConfigService configService;
+
     @Autowired
     private IFsCourseLinkService courseLinkService;
 
@@ -106,7 +110,7 @@ public class CourseWxH5Controller extends AppBaseController {
         if (param.getDuration()==null){
             logger.info("zyp \n【未识别到时长】:{}",param.getUserId());
         }
-        return questionBankService.courseAnswer(param, true);
+        return questionBankService.courseAnswerByFsUser(param);
     }
 
     @ApiOperation("发放奖励")

+ 172 - 74
fs-user-course/src/main/java/com/fs/course/controller/WxCompanyUserController.java

@@ -5,7 +5,7 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
 import cn.hutool.core.date.DateTime;
 import com.alibaba.fastjson.JSON;
-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.LoginMaWxParam;
@@ -18,9 +18,12 @@ import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.course.config.CourseMaConfig;
+import com.fs.course.utils.JwtUtils;
 import com.fs.his.domain.FsUser;
+import com.fs.his.enums.FsUserOperationEnum;
 import com.fs.his.service.IFsUserService;
 
+import com.fs.his.service.IFsUserWxService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.wx.miniapp.config.WxMaProperties;
@@ -39,7 +42,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import com.fs.his.domain.FsUserWx;
 
 @Api("微信小程序相关接口")
 @RestController
@@ -72,105 +78,197 @@ public class WxCompanyUserController extends AppBaseController {
     @Autowired
     private SysConfigMapper sysConfigMapper;
 
+    @Autowired
+    private IFsUserWxService fsUserWxService;
+
     @ApiOperation("小程序-授权登录")
     @PostMapping("/loginByMa")
+//    @UserOperationLog(operationType = FsUserOperationEnum.MINLOGIN)
     public R login(@RequestBody LoginMaWxParam param) {
         log.info("=====================进入小程序授权登录, 入参: {}", param);
         if (StringUtils.isBlank(param.getCode())) {
             return R.error("code不存在");
         }
-        SysConfig sysConfig3 = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
-        List<CourseMaConfig> courseMaConfigs = JSON.parseArray(sysConfig3.getConfigValue(), CourseMaConfig.class);
-        if (courseMaConfigs.isEmpty()){
-            return R.error("小程序配置为空");
+
+        Company company = companyService.selectCompanyById(param.getCompanyId());
+        if (company.getCourseMiniAppId() == null) {
+            return R.error("小程序参数错误!");
         }
-        CourseMaConfig courseMaConfig = courseMaConfigs.get(0);
-        //获取第二个小程序配置,序号从0开始
-        final WxMaService wxService = WxMaConfiguration.getMaService(courseMaConfig.getAppid());
+
+        final WxMaService wxService = WxMaConfiguration.getMaService(company.getCourseMiniAppId());
         try {
             WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
             this.logger.info(session.getSessionKey());
             this.logger.info(session.getOpenid());
             this.logger.info(session.getUnionid());
-            // 解密
-            WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
-            FsUser user = userService.selectFsUserByPhone(phoneNoInfo.getPhoneNumber());
-
-            // 特殊(需求设计:需要根据公司是否开启黑名单来设置会员初始化的状态)
-            Company company = null;
-            if(param.getCompanyId() != null){
-                company = companyService.selectCompanyById(param.getCompanyId());
-            }
 
-            // 根据销售后台设置的  是否需要单独注册会员 来判断是否需要设置销售的值
-            CompanyUser companyUser = null;
-            if(param.getCompanyUserId() != null){
-                companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
+            // 手机号信息
+            WxMaPhoneNumberInfo phoneNoInfo = null;
+            if (param.getAuthType()==1){
+                phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
             }
 
+            FsUser user = getUserByAuthType(param, wxService, session, phoneNoInfo);
+
+
+            // 2. 获取销售信息
+            CompanyUser companyUser = getCompanyUser(param);
+
+            // 3. 处理用户注册或更新
             String ip = IpUtil.getRequestIp();
-            if (user == null) {
-                if(StringUtils.isNotEmpty(session.getUnionid())){
-                    user = userService.selectFsUserByUnionId(session.getUnionid());
-                } else {
-                    user = userService.selectFsUserByCourseMaOpenId(session.getOpenid());
-                }
-                if (user != null) {
-                    //修改
-                    FsUser userMap = new FsUser();
-                    userMap.setUserId(user.getUserId());
-                    userMap.setCourseMaOpenId(session.getOpenid());
-                    userMap.setUnionId(session.getUnionid());
-                    userMap.setUpdateTime(new DateTime());
-                    userMap.setNickName(param.getNickname() != null ? param.getNickname() : "微信用户");
-                    userMap.setAvatar(param.getAvatar() != null ? param.getAvatar() : null);
-                    userMap.setPhone(phoneNoInfo.getPhoneNumber());
-                    // 逻辑调整:如果会员已经绑定了销售,直接提示,不让注册-2025年6月16日14点53分
-                    if (user.getCompanyUserId() != null && !param.getCompanyUserId().equals(user.getCompanyUserId())){
-                        return R.error(406, "该用户已成为其他销售会员");
-                    }
-                    if(companyUser != null && companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1){
-                        user.setCompanyId(param.getCompanyId());
-                        user.setCompanyUserId(param.getCompanyUserId());
-                    }
-                    userService.updateFsUser(userMap);
-                } else {
-                    //新增
-                    user = new FsUser();
-                    user.setNickName(param.getNickname() != null ? param.getNickname() : "微信用户");
-                    user.setAvatar(param.getAvatar() != null ? param.getAvatar() : null);
-                    user.setStatus((company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1);
-                    user.setCourseMaOpenId(session.getOpenid());
-                    user.setUnionId(session.getUnionid());
-                    user.setCreateTime(new Date());
-                    user.setPhone(phoneNoInfo.getPhoneNumber());
-                    if(companyUser != null && companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1){
-                        user.setCompanyId(param.getCompanyId());
-                        user.setCompanyUserId(param.getCompanyUserId());
-                    }
-                    userService.insertFsUser(user);
-                }
-            } else {
-                FsUser userMap = new FsUser();
-                userMap.setUserId(user.getUserId());
-                userMap.setUpdateTime(new DateTime());
-                userMap.setPhone(phoneNoInfo.getPhoneNumber());
-                userMap.setLastIp(ip);
-                if (StringUtils.isNotEmpty(session.getUnionid())) {
-                    userMap.setUnionId(session.getUnionid());
-                }
-                userService.updateFsUser(userMap);
-            }
+            user = handleUserRegisterOrUpdate(user, param, session, phoneNoInfo, company, companyUser, ip);
+
+            // 4. 处理用户与小程序的绑定
+            handleFsUserWx(user, param, company, session);
+
             log.info("保存成功的用户信息user: {}, 用户id: {}", user, user.getUserId());
             String token = jwtUtils.generateToken(user.getUserId());
             // 返回一个写死的数据到前端
-            return R.ok("登录成功").put("token", token).put("phoneNumber", phoneNoInfo.getPhoneNumber()).put("nickName", "微信用户").put("user", user);
+            return R.ok("登录成功").put("token", token).put("user", user);
         } catch (WxErrorException e) {
             this.logger.error(e.getMessage(), e);
             return R.error("授权失败," + e.getMessage());
         }
     }
 
+    /**
+     * 根据authType获取用户信息
+     */
+    private FsUser getUserByAuthType(LoginMaWxParam param, WxMaService wxService, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo) throws WxErrorException {
+        FsUser user = null;
+        if (param.getAuthType() == 1) {
+            user = userService.selectFsUserByPhone(phoneNoInfo.getPhoneNumber());
+        } else {
+            // unionid判定唯一
+            if (StringUtils.isNotEmpty(session.getUnionid())) {
+                user = userService.selectFsUserByUnionId(session.getUnionid());
+            }
+        }
+        return user;
+    }
+
+    /**
+     * 获取销售信息
+     */
+    private CompanyUser getCompanyUser(LoginMaWxParam param) {
+        if (param.getCompanyUserId() != null) {
+            return companyUserService.selectCompanyUserById(param.getCompanyUserId());
+        }
+        return null;
+    }
+
+    /**
+     * 处理用户注册或更新
+     */
+    private FsUser handleUserRegisterOrUpdate(FsUser user, LoginMaWxParam param, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo, Company company, CompanyUser companyUser, String ip) {
+        if (user == null) {
+            user = userService.selectFsUserByCourseMaOpenId(session.getOpenid());
+            if (user != null) {
+                // 修改
+                return updateUser(user, param, session, phoneNoInfo, company, companyUser);
+            } else {
+                // 新增
+                return createUser(param, session, phoneNoInfo, company, companyUser);
+            }
+        } else {
+            // 已存在用户,更新信息
+            updateUserInfo(user, param, session, phoneNoInfo, ip);
+            return user;
+        }
+    }
+
+    /**
+     * 新增用户
+     */
+    private FsUser createUser(LoginMaWxParam param, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo, Company company, CompanyUser companyUser) {
+        FsUser user = new FsUser();
+        user.setNickName(param.getNickname() != null ? param.getNickname() : "微信用户");
+        user.setAvatar(param.getAvatar() != null ? param.getAvatar() : null);
+        user.setStatus((company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1);
+        // user.setCourseMaOpenId(session.getOpenid());
+        user.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
+        user.setCreateTime(new Date());
+        if (param.getAuthType() == 1 && phoneNoInfo != null) {
+            user.setPhone(phoneNoInfo.getPhoneNumber());
+        }
+        if (companyUser != null && companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1) {
+            user.setCompanyId(param.getCompanyId());
+            user.setCompanyUserId(param.getCompanyUserId());
+        }
+        userService.insertFsUser(user);
+        return user;
+    }
+
+    /**
+     * 修改用户
+     */
+    private FsUser updateUser(FsUser user, LoginMaWxParam param, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo, Company company, CompanyUser companyUser) {
+        FsUser userMap = new FsUser();
+        userMap.setUserId(user.getUserId());
+        // userMap.setCourseMaOpenId(session.getOpenid());
+        userMap.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
+        userMap.setUpdateTime(new DateTime());
+        userMap.setNickName(param.getNickname() != null ? param.getNickname() : user.getNickName());
+        userMap.setAvatar(param.getAvatar() != null ? param.getAvatar() : user.getAvatar());
+        if (param.getAuthType() == 1 && phoneNoInfo != null) {
+            userMap.setPhone(phoneNoInfo.getPhoneNumber());
+        }
+        // 逻辑调整:如果会员已经绑定了销售,直接提示,不让注册-2025年6月16日14点53分
+        if (user.getCompanyUserId() != null && !param.getCompanyUserId().equals(user.getCompanyUserId())) {
+            throw new RuntimeException("该用户已成为其他销售会员");
+        }
+        if (companyUser != null && companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1) {
+            userMap.setCompanyId(param.getCompanyId());
+            userMap.setCompanyUserId(param.getCompanyUserId());
+        }
+        userService.updateFsUser(userMap);
+        return userMap;
+    }
+
+    /**
+     * 更新已存在用户信息
+     */
+    private void updateUserInfo(FsUser user, LoginMaWxParam param, WxMaJscode2SessionResult session, WxMaPhoneNumberInfo phoneNoInfo, String ip) {
+        FsUser userMap = new FsUser();
+        userMap.setUserId(user.getUserId());
+        userMap.setUpdateTime(new DateTime());
+        if (param.getAuthType() == 1 && phoneNoInfo != null) {
+            user.setPhone(phoneNoInfo.getPhoneNumber());
+        }
+        userMap.setLastIp(ip);
+        if (StringUtils.isNotEmpty(session.getUnionid())) {
+            userMap.setUnionId(session.getUnionid());
+        }
+        userService.updateFsUser(userMap);
+    }
+
+    /**
+     * 处理用户与小程序的绑定
+     */
+    private void handleFsUserWx(FsUser user, LoginMaWxParam param, Company company, WxMaJscode2SessionResult session) {
+        if (user == null) return;
+        FsUserWx fsUserWx = fsUserWxService.selectByAppIdAndUserId(company.getCourseMiniAppId(), user.getUserId(), 1);
+        if (fsUserWx == null) {
+            fsUserWx = new FsUserWx();
+            fsUserWx.setType(1);
+            fsUserWx.setFsUserId(user.getUserId());
+            fsUserWx.setCompanyId(param.getCompanyId());
+            fsUserWx.setAppId(company.getCourseMiniAppId());
+            fsUserWx.setOpenId(session.getOpenid());
+            fsUserWx.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
+            fsUserWx.setCreateTime(new Date());
+            fsUserWxService.save(fsUserWx);
+        } else {
+            fsUserWx.setFsUserId(user.getUserId());
+            fsUserWx.setCompanyId(param.getCompanyId());
+            fsUserWx.setAppId(company.getCourseMiniAppId());
+            fsUserWx.setOpenId(session.getOpenid());
+            fsUserWx.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
+            fsUserWx.setUpdateTime(new Date());
+            fsUserWxService.updateById(fsUserWx);
+        }
+    }
+
 //    @Login(isMiniLogin = true)
 //    @ApiOperation("获取销售通过小程序登录后的用户信息")
 //    @GetMapping("/getMaUser")

+ 133 - 0
fs-user-course/src/main/java/com/fs/course/controller/WxH5MpController.java

@@ -0,0 +1,133 @@
+package com.fs.course.controller;
+
+import cn.hutool.core.date.DateTime;
+
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.service.ICompanyService;
+import com.fs.company.service.ICompanyUserService;
+import com.fs.course.mapper.FsCourseWatchLogMapper;
+import com.fs.course.param.FsUserLoginByMpParam;
+import com.fs.course.utils.JwtUtils;
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
+import com.fs.qw.mapper.QwExternalContactMapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+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.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.validation.Valid;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@Api("会员-h5-微信相关接口(后面不需要这个接口了,再删除))")
+@RestController
+@RequestMapping("/app/wx/h5/mp")
+@Slf4j
+public class WxH5MpController {
+    Logger logger = LoggerFactory.getLogger(getClass());
+    @Autowired
+    private WxMpService wxMpService;
+
+    @Autowired
+    private IFsUserService userService;
+
+    @Autowired
+    JwtUtils jwtUtils;
+    @Autowired
+    RedisCache redisCache;
+
+    @Autowired
+    FsCourseWatchLogMapper fsCourseWatchLogMapper;
+    @Autowired
+    QwExternalContactMapper qwExternalContactMapper;
+    @Autowired
+    ICompanyService companyService;
+    @Autowired
+    ICompanyUserService companyUserService;
+
+
+    @ApiOperation("课程分享链接公众号登录")
+    @PostMapping("/loginByMp")
+    public R loginByMp(@Valid @RequestBody FsUserLoginByMpParam param) throws WxErrorException {
+//        try {
+            //获取微信用户信息
+            WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
+            WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
+            //1、特殊(需求设计:需要根据公司是否开启黑名单来设置会员初始化的状态)
+            Company company = null;
+            if(param.getCompanyId() != null){
+                company = companyService.selectCompanyById(param.getCompanyId());
+            }
+            // 根据销售后台设置的  是否需要单独注册会员 来判断是否需要设置销售的值
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
+
+            FsUser user;
+        logger.info("当前微信信息---------------------------》{}",wxMpUser);
+            if(StringUtils.isNotEmpty(wxMpUser.getUnionId())) {
+                user = userService.selectFsUserByUnionId(wxMpUser.getUnionId());
+            } else {
+                logger.info("当前查询参数-----------》{}",wxMpUser.getOpenid());
+                user = userService.selectFsUserByOpenId(wxMpUser.getOpenid());
+            }
+        logger.info("当前用户信息-----------》{}",user);
+            if (user != null) {
+                //修改
+                FsUser userMap = new FsUser();
+                userMap.setUserId(user.getUserId());
+                userMap.setMpOpenId(wxMpUser.getOpenid());
+                userMap.setUnionId(wxMpUser.getUnionId());
+                userMap.setUpdateTime(new DateTime());
+                userMap.setAvatar(wxMpUser.getHeadImgUrl());
+                userMap.setNickName(wxMpUser.getNickname());
+                userService.updateFsUser(userMap);
+            } else {
+                //新增
+                user = new FsUser();
+                user.setNickName(wxMpUser.getNickname());
+                user.setAvatar(wxMpUser.getHeadImgUrl());
+                user.setStatus((company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1);
+                user.setMpOpenId(wxMpUser.getOpenid());
+                user.setUnionId(wxMpUser.getUnionId());
+                user.setCreateTime(new Date());
+                if(companyUser.getIsNeedRegisterMember() != 1){
+                    user.setCompanyId(param.getCompanyId());
+                    user.setCompanyUserId(param.getCompanyUserId());
+                }
+                userService.insertFsUser(user);
+            }
+            log.error("用户信息user: {}, 用户id: {}", user, user.getUserId());
+            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);
+            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());
+//            }
+//        }
+
+    }
+
+
+}

+ 1 - 9
fs-user-course/src/main/java/com/fs/course/controller/WxMpController.java

@@ -161,18 +161,10 @@ public class WxMpController {
   @PostMapping("/loginByMp")
   @Transactional
   public R loginByMp( @RequestBody FsUserLoginByMpParam 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);
-      WxMpUserService wxMpUserService = wxMpService.getUserService();
-      WxMpUser userInfo = wxMpUserService.userInfo(wxMpUser.getOpenid());
-//      if (!userInfo.getSubscribe()){
-//        return R.error("请关注公众号进行登录");
-//      }
+
       FsUser user=userService.selectFsUserByUnionid(wxMpUser.getUnionId());
       if(user!=null){
         FsUser userMap=new FsUser();

+ 13 - 0
fs-user-course/src/main/java/com/fs/course/param/FsUserLoginByMpParam.java

@@ -1,8 +1,10 @@
 package com.fs.course.param;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
 @Data
@@ -10,4 +12,15 @@ public class FsUserLoginByMpParam implements Serializable {
     @NotBlank(message = "code参数缺失")
     private String code;
     private Long videoId;
+
+    @NotNull(message = "公司id不能为空")
+    @ApiModelProperty(value = "公司id")
+    private Long companyId;
+
+    @NotNull(message = "销售id不能为空")
+    @ApiModelProperty(value = "销售id")
+    private Long companyUserId;
+
+    @NotBlank(message = "服务号参数缺失")
+    private String appId;//服务号APPID
 }

BIN
fs-user-course/src/main/resources/apiclient_cert.p12


+ 2 - 0
fs-user-course/src/main/resources/banner.txt

@@ -0,0 +1,2 @@
+Application Version: ${fs.version}
+Spring Boot Version: ${spring-boot.version}

+ 1 - 0
pom.xml

@@ -267,6 +267,7 @@
         <module>fs-qwhook-msg</module>
         <module>fs-repeat-api</module>
         <module>fs-ipad-task</module>
+        <module>fs-user-course</module>
     </modules>
 
     <packaging>pom</packaging>