Преглед изворни кода

Merge remote-tracking branch 'origin/ScrmStores' into ScrmStores

yjwang пре 3 дана
родитељ
комит
a900f8127c
20 измењених фајлова са 352 додато и 63 уклоњено
  1. 22 0
      fs-company/src/main/java/com/fs/company/controller/company/CompanyConfigController.java
  2. 4 0
      fs-company/src/main/java/com/fs/company/controller/qw/SopUserLogsController.java
  3. 1 1
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  4. 14 10
      fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java
  5. 5 12
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  6. 12 0
      fs-service/src/main/java/com/fs/company/mapper/CompanyConfigMapper.java
  7. 30 0
      fs-service/src/main/java/com/fs/company/param/SaveCompanyMiniAppParam.java
  8. 6 0
      fs-service/src/main/java/com/fs/company/service/ICompanyConfigService.java
  9. 60 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyConfigServiceImpl.java
  10. 32 0
      fs-service/src/main/java/com/fs/company/vo/CompanyMiniAppVO.java
  11. 42 19
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  12. 20 5
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/WellnessFoodCheck.java
  13. 2 0
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  14. 2 0
      fs-service/src/main/java/com/fs/sop/service/IQwSopTempRulesService.java
  15. 2 0
      fs-service/src/main/java/com/fs/sop/service/ISopUserLogsService.java
  16. 6 0
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java
  17. 6 6
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  18. 75 7
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsServiceImpl.java
  19. 3 3
      fs-service/src/main/resources/application-dev-yjb.yml
  20. 8 0
      fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

+ 22 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyConfigController.java

@@ -5,7 +5,9 @@ import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.ServletUtils;
 import com.fs.company.domain.CompanyConfig;
+import com.fs.company.param.SaveCompanyMiniAppParam;
 import com.fs.company.service.ICompanyConfigService;
+import com.fs.company.vo.CompanyMiniAppVO;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
 import com.fs.system.domain.SysConfig;
@@ -15,6 +17,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * 系统配置
  *
@@ -78,6 +82,24 @@ public class CompanyConfigController extends BaseController
 
     }
 
+    /**
+     * 获取公司可配置小程序列表
+     * @return
+     */
+    @PreAuthorize("@ss.hasPermi('company:miniConfig:list')")
+    @GetMapping(value = "/getCompanyMiniAppList")
+    public R getCompanyMiniAppList()
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        if(null == loginUser) {
+            return R.error("用户信息错误");
+        }
+        Long companyId = loginUser.getCompany().getCompanyId();
+        List<CompanyMiniAppVO> companyMiniAppList = companyConfigService.getCompanyMiniAppList(companyId);
+        SaveCompanyMiniAppParam param = companyConfigService.getCurrentCompanyMiniApp(companyId);
+        return R.ok().put("data",companyMiniAppList).put("current",param);
+
+    }
 
 
 

+ 4 - 0
fs-company/src/main/java/com/fs/company/controller/qw/SopUserLogsController.java

@@ -195,4 +195,8 @@ public class SopUserLogsController extends BaseController
         sopUserLogsService.replaceUser(vo);
         return R.ok();
     }
+    @GetMapping("/getShortLink")
+    public R getShortLink(String id, String sopId, String appId){
+        return sopUserLogsService.getShortLink(id, sopId, appId);
+    }
 }

+ 1 - 1
fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java

@@ -60,7 +60,7 @@ public class IpadSendServer {
     private final ICompanyMiniappService companyMiniappService;
     private final IFsCoursePlaySourceConfigService playSourceConfigService;
     private final FsUserMapper fsUserMapper;
-    private static final List<String> PROJECT_NAMES = Arrays.asList("济南联志健康", "北京存在文化");
+    private static final List<String> PROJECT_NAMES = Arrays.asList("济南联志健康", "北京存在文化","宽益堂");
     private void sendMiniProgram(BaseVo vo, QwSopCourseFinishTempSetting.Setting content, Map<String, FsCoursePlaySourceConfig> miniMap, Long companyId) {
         // 发送参数原本的appid
         String appid = content.getMiniprogramAppid();

+ 14 - 10
fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java

@@ -90,12 +90,14 @@ public class SendMsg {
         if (qwUserList.isEmpty()) {
             List<QwIpadServer> serverList = qwIpadServerMapper.selectList(new QueryWrapper<QwIpadServer>().eq("group_no", groupNo));
             if (serverList.isEmpty()) {
+                log.info("没找到可用的服务器 {} ",serverList);
                 return new ArrayList<>();
             }
             List<Long> serverIds = PubFun.listToNewList(serverList, QwIpadServer::getId);
             List<QwUser> qwUsers = qwUserMapper.selectList(new QueryWrapper<QwUser>().eq("send_msg_type", 1).eq("server_status", 1).eq("ipad_status", 1).in("server_id", serverIds));
             qwUserList.addAll(qwUsers);
         }
+        log.info("getQwUserList {}",JSON.toJSONString(qwUserList));
         return qwUserList;
     }
 
@@ -169,6 +171,7 @@ public class SendMsg {
         // 获取当前企微待发送记录
         List<QwSopLogs> qwSopLogList = qwSopLogsMapper.selectByQwUserId(qwUser.getId());
         if (qwSopLogList.isEmpty()) {
+            log.info("获取当前企微待发送记录为空");
             return;
         }
         // 获取企微用户
@@ -178,6 +181,7 @@ public class SendMsg {
         long end1 = System.currentTimeMillis();
         // 判断这个企微是否需要发送
         if (!sendServer.isSend(user, parentVo)) {
+            log.info("当前这个企微不需要发送 数据{}",user);
             return;
         }
         log.info("销售:{}, 消息:{}, 耗时: {}, 时间:{}", user.getQwUserName(), qwSopLogList.size(), end1 - start1, qwMap.get(qwUser.getId()));
@@ -264,16 +268,16 @@ public class SendMsg {
                 }
             }
             // 推送 APP
-//            if (!setting.getSetting().isEmpty()) {
-//                new Thread(() -> {
-//                    try {
-//                        List<QwSopTempSetting.Content.Setting> settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "9".equals(e.getContentType())).collect(Collectors.toList());
-//                        asyncSopTestService.asyncSendMsgBySopAppLinkNormalIM(settings, qwSopLogs.getCorpId(), user.getCompanyUserId(), qwSopLogs.getFsUserId());
-//                    } catch (Exception e) {
-//                        log.error("推送APP失败", e);
-//                    }
-//                }).start();
-//            }
+            if (!setting.getSetting().isEmpty()) {
+                new Thread(() -> {
+                    try {
+                        List<QwSopTempSetting.Content.Setting> settings = JSON.parseArray(JSON.toJSONString(setting.getSetting()), QwSopTempSetting.Content.Setting.class).stream().filter(e -> "9".equals(e.getContentType())).collect(Collectors.toList());
+                        asyncSopTestService.asyncSendMsgBySopAppLinkNormalIM(settings, qwSopLogs.getCorpId(), user.getCompanyUserId(), qwSopLogs.getFsUserId());
+                    } catch (Exception e) {
+                        log.error("推送APP失败", e);
+                    }
+                }).start();
+            }
             qwSopLogs.setSend(true);
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             QwSopLogs updateQwSop = new QwSopLogs();

+ 5 - 12
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -1006,14 +1006,13 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
                     String sortLink = createLinkByMiniApp(setting, logVo, sendTime, courseId, videoId,
                             qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId(), isGroupChat ? groupChat.getChatId() : null);
-                    QwExternalContact qwExternalContact = qwExternalContactMapper.selectById(externalId);
-                    LocalDateTime createTime = qwExternalContact.getCreateTime() == null ? LocalDateTime.now() : DateUtil.dateToLocalDateTime(qwExternalContact.getCreateTime());
+
                     if(sopLogs.getSendType()==1){
                         setting.setMiniprogramAppid(miniAppId);
                     }else {
                         int miniType = getLevel(grade);
                         //算主备小程序
-                        String finalAppId = getAppIdFromMiniMap(miniMap, companyId, sendMsgType, grade, createTime);
+                        String finalAppId = getAppIdFromMiniMap(miniMap, companyId, sendMsgType, grade);
 
                         if (StringUtil.strIsNullOrEmpty(finalAppId)) {
                             finalAppId = miniAppId;
@@ -1088,7 +1087,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private String getAppIdFromMiniMap(Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
                                        String companyId,
                                        int sendMsgType,
-                                       Integer grade, LocalDateTime createTime) {
+                                       Integer grade) {
         if (miniMap.isEmpty() || sendMsgType != 1) {
             return null;
         }
@@ -1097,14 +1096,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         if (gradeMap == null) {
             return null;
         }
-        LocalDateTime lastTime = LocalDateTime.of(2025, 11, 6, 23, 59, 59);
-//        if (createTime.isAfter(lastTime)) {
-//            System.out.println("创建时间大于目标时间");
-//        } else {
-//            System.out.println("创建时间不大于目标时间");
-//        }
-//        int listIndex = getLevel(grade);
-        int listIndex = createTime.isAfter(lastTime) ? 1 : 0 ;
+
+        int listIndex = getLevel(grade);
         List<CompanyMiniapp> miniapps = gradeMap.get(listIndex);
 
         if (miniapps == null || miniapps.isEmpty()) {

+ 12 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyConfigMapper.java

@@ -1,6 +1,7 @@
 package com.fs.company.mapper;
 
 import com.fs.company.domain.CompanyConfig;
+import com.fs.company.vo.CompanyMiniAppVO;
 import com.fs.system.domain.SysConfig;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
@@ -74,4 +75,15 @@ public interface CompanyConfigMapper
 
     @Select("select config_value from company_config where company_id=#{companyId} and config_key='redPacket:config' ")
     String selectRedPacketConfigByKey(Long companyId);
+
+    @Select("select \n" +
+            "id,\n" +
+            "name,\n" +
+            "appid\n" +
+            "from\n" +
+            "fs_course_play_source_config\n" +
+            "where \n" +
+            "is_del = 0\n" +
+            "and FIND_IN_SET(#{companyId},set_company_ids)")
+    List<CompanyMiniAppVO> getCompanyMiniAppList(@Param("companyId") Long companyId);
 }

+ 30 - 0
fs-service/src/main/java/com/fs/company/param/SaveCompanyMiniAppParam.java

@@ -0,0 +1,30 @@
+package com.fs.company.param;
+
+import lombok.Data;
+
+/**
+ * @author MixLiu
+ * @date 2025/11/22 下午1:59)
+ */
+
+@Data
+public class SaveCompanyMiniAppParam {
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 主要小程序
+     */
+    private String mainMiniAppId;
+
+    /**
+     * 备用小程序
+     */
+    private String backupMiniAppId;
+
+    private Long updateBy;
+
+}

+ 6 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyConfigService.java

@@ -1,6 +1,8 @@
 package com.fs.company.service;
 
 import com.fs.company.domain.CompanyConfig;
+import com.fs.company.param.SaveCompanyMiniAppParam;
+import com.fs.company.vo.CompanyMiniAppVO;
 
 import java.util.List;
 
@@ -69,4 +71,8 @@ public interface ICompanyConfigService
     CompanyConfig selectCompanyConfigByServerKey(String key);
 
     String selectRedPacketConfigByKey(Long companyId);
+
+    List<CompanyMiniAppVO> getCompanyMiniAppList(Long companyId);
+
+    SaveCompanyMiniAppParam getCurrentCompanyMiniApp(Long companyId);
 }

+ 60 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyConfigServiceImpl.java

@@ -1,12 +1,21 @@
 package com.fs.company.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.core.text.Convert;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyConfig;
+import com.fs.company.domain.CompanyMiniapp;
 import com.fs.company.mapper.CompanyConfigMapper;
+import com.fs.company.mapper.CompanyMiniappMapper;
+import com.fs.company.param.SaveCompanyMiniAppParam;
 import com.fs.company.service.ICompanyConfigService;
+import com.fs.company.vo.CompanyMiniAppVO;
+import com.fs.course.config.CourseMaConfig;
+import com.fs.course.domain.FsCoursePlaySourceConfig;
+import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
 import com.fs.system.domain.SysConfig;
 import org.apache.http.util.Asserts;
 import org.redisson.api.RedissonClient;
@@ -14,9 +23,11 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 import static com.fs.common.utils.DictUtils.getCacheKey;
 
@@ -35,6 +46,10 @@ public class CompanyConfigServiceImpl implements ICompanyConfigService
     private CompanyConfigMapper companyConfigMapper;
     @Autowired
     private RedisTemplate<String, String> redisTemplate; // 注入RedisTemplate
+    @Autowired
+    private CompanyMiniappMapper companyMiniappMapper;
+    @Autowired
+    private FsCoursePlaySourceConfigMapper fsCoursePlaySourceConfigMapper;
     private static final String REDIS_KEY_PREFIX = "red_packet_config:";
     private static final long CACHE_TIMEOUT = 24 * 60 * 60;
 
@@ -167,6 +182,51 @@ public class CompanyConfigServiceImpl implements ICompanyConfigService
         }
     }
 
+    /**
+     * 获取公司可配置小程序列表
+     * @param companyId
+     * @return
+     */
+    @Override
+    public List<CompanyMiniAppVO> getCompanyMiniAppList(Long companyId) {
+        List<CompanyMiniapp> miniList = companyMiniappMapper.selectList(new QueryWrapper<CompanyMiniapp>().eq("company_id", companyId));
+        List<String> collect = miniList.stream().map(CompanyMiniapp::getAppId).distinct().collect(Collectors.toList());
+        List<FsCoursePlaySourceConfig> configList = fsCoursePlaySourceConfigMapper.selectList(new QueryWrapper<>());
+        return configList.stream().filter(e -> collect.contains(e.getAppid())).map(e -> {
+            CompanyMiniAppVO vo = new CompanyMiniAppVO();
+            vo.setAppid(e.getAppid());
+            vo.setName(e.getName());
+            return vo;
+        }).collect(Collectors.toList());
+    }
+
+    //主要小程序
+    Integer type_main = 0;
+    //备用小程序
+    Integer type_backup = 1;
+    @Override
+    public SaveCompanyMiniAppParam getCurrentCompanyMiniApp(Long companyId){
+        SaveCompanyMiniAppParam result = new SaveCompanyMiniAppParam();
+        CompanyMiniapp companyMiniapp = new CompanyMiniapp();
+        companyMiniapp.setCompanyId(companyId);
+        List<CompanyMiniapp> companyMiniapps = companyMiniappMapper.selectCompanyMiniappList(companyMiniapp);
+        if(null != companyMiniapps && companyMiniapps.size() == 2){
+            for (CompanyMiniapp miniapp : companyMiniapps) {
+                //主要小程序更新
+                if(type_main.equals(miniapp.getType())){
+                    result.setMainMiniAppId(miniapp.getAppId());
+                }
+                //备用小程序更新
+                if(type_backup.equals(miniapp.getType())){
+                    result.setBackupMiniAppId(miniapp.getAppId());
+                }
+            }
+        }
+
+        return result;
+    }
+
+
     private static final ConcurrentHashMap<Long, Object> LOCKS = new ConcurrentHashMap<>();
     private static Object getSynchronizationObject(Long companyId) {
         return LOCKS.computeIfAbsent(companyId, k -> new Object());

+ 32 - 0
fs-service/src/main/java/com/fs/company/vo/CompanyMiniAppVO.java

@@ -0,0 +1,32 @@
+package com.fs.company.vo;
+
+import lombok.Data;
+
+/**
+ * @author MixLiu
+ * @date 2025/11/22 下午1:42)
+ */
+
+@Data
+public class CompanyMiniAppVO {
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 小程序/公众号名称
+     */
+    private String name;
+
+    /**
+     * 小程序/公众号appid
+     */
+    private String appid;
+
+    /**
+     * 小程序所属公司id
+     */
+    private Long companyId;
+
+}

+ 42 - 19
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -567,66 +567,89 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     }
     private R handleQwRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
+        //未注册提示
+        String noRegisterMsg = "由于您还未完成注册,请联系伴学助手完成注册即可观看!";
         FsCourseLink courseLink = courseLinkMapper.selectFsCourseLinkByLink(param.getLink());
-        String msg = "<div style=\"color: red;margin-bottom: 15px;font-weight: bold;\">本课程为群会员独享<br>请长按二维码</div>\n" +
-                "\t\t\t\t\t<div style=\"color: #999;font-size: 14px;font-weight: bold;\">添加伴学助手免费领取会员权限</div>";
         QwGroupChat qwGroupChat = qwGroupChatMapper.selectQwGroupChatByChatId(courseLink.getChatId());
-        if(qwGroupChat == null){
+        if (qwGroupChat == null) {
             return R.error("群参数异常");
         }
-        SopUserLogsInfo sopUserLogsInfo =  new SopUserLogsInfo();
+        SopUserLogsInfo sopUserLogsInfo = new SopUserLogsInfo();
         sopUserLogsInfo.setChatId(courseLink.getChatId());
         List<QwGroupChatUser> qwGroupChatUsers = qwGroupChatUserMapper.selectByChatId(sopUserLogsInfo);
-        if(qwGroupChatUsers == null || qwGroupChatUsers.isEmpty()){
+        if (qwGroupChatUsers == null || qwGroupChatUsers.isEmpty()) {
             return R.error("群参数异常");
         }
-        QwExternalContact qwExternalContact =
-                qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+        //群聊寻找用户新逻辑
+        QwExternalContact qwExternalContact = null;
+        if (null != param.getUserId()) {
+            try {
+                qwExternalContact = qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
                         .eq("user_id", qwGroupChat.getOwner())
                         .eq("fs_user_id", param.getUserId())
                         .eq("corp_id", param.getCorpId())
-                        .eq("status",0));
+                        .eq("status", 0));
+            } catch (Exception e) {
+                log.error("群聊用户id匹配异常,参数user_id:{},fs_user_id:{},corp_id:{}", qwGroupChat.getOwner(), param.getUserId(), param.getCorpId(), e);
+            }
+        }
+        //找当前群中的用户匹配
+        if (StringUtils.isNotBlank(param.getChatId()) && null == qwExternalContact) {
+            List<QwExternalContact> groupChatUserByChatIdAndUserName = qwExternalContactMapper.getGroupChatUserByChatIdAndUserName(qwGroupChat.getOwner(), user.getNickName(), param.getCorpId(), param.getChatId());
+            log.info("群聊用户查询结果,参数user_id:{},name:{},corp_id:{},chatId:{},groupChatUserByChatIdAndUserName:{}", qwGroupChat.getOwner(), user.getNickName(), param.getCorpId(), param.getChatId(), groupChatUserByChatIdAndUserName);
+            //没找到用户 || 找到的用户数量大于1 使用userid查询匹配
+            if (null == groupChatUserByChatIdAndUserName || groupChatUserByChatIdAndUserName.size() != 1) {
+                log.error("群聊用户昵称匹配异常,参数user_id:{},name:{},corp_id:{},chatId:{}", qwGroupChat.getOwner(), user.getNickName(), param.getCorpId(), param.getChatId());
+            } else {
+                qwExternalContact = groupChatUserByChatIdAndUserName.get(0);
+            }
+        }
         if(qwExternalContact==null){
-            return addCustomerService(param.getQwUserId(),msg);
+            return R.error(noRegisterMsg);
         }
-        if(qwGroupChatUsers.stream().noneMatch(e -> e.getUserId().equals(qwExternalContact.getExternalUserId()))){
+        QwExternalContact finalQwExternalContact = qwExternalContact;
+        if (qwGroupChatUsers.stream().noneMatch(e -> e.getUserId().equals(finalQwExternalContact.getExternalUserId()))) {
             log.error("客户不在群:{},里面:{}", qwGroupChat.getChatId(), qwExternalContact.getExternalUserId());
-            return addCustomerService(param.getQwUserId(),msg);
+            return R.error(noRegisterMsg);
         }
         Long qwExternalId = qwExternalContact.getId();
 //        addCompanyCompanyFsUser(param);
         FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(qwExternalId, param.getVideoId(),param.getQwUserId());
         if (log==null ){
-            return addCustomerService(param.getQwUserId(),msg);
+            return R.error(noRegisterMsg);
         }
         //判断外部联系人有没有绑定userId
-        if (qwExternalContact.getFsUserId()!=null){
+        if (qwExternalContact.getFsUserId() != null) {
             //有客户有小程序id  但 登录的小程序id和根据外部联系人id查出来的小程序id不一致
             if (!qwExternalContact.getFsUserId().equals(param.getUserId())) {
-                return addCustomerService(param.getQwUserId(),msg);
+                return R.error(noRegisterMsg);
             }
             List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByMiniUserId(param.getUserId());
             //匹配客户公司id
             if (qwExternalContacts.stream().noneMatch(contact -> contact.getCorpId().equals(param.getCorpId()))){
-                return addCustomerService(param.getQwUserId(),msg);
+                return R.error(noRegisterMsg);
             }
 
             //看课记录中userId为0绑定userId
-            if (log.getUserId()==null||log.getUserId().equals(0L) || !log.getUserId().equals(param.getUserId())){
+            if (log.getUserId() == null || log.getUserId().equals(0L) || !log.getUserId().equals(param.getUserId())) {
                 log.setUserId(param.getUserId());
             }
 
             log.setUpdateTime(new Date());
             //重粉逻辑
-            fsUserCompanyBindService.bindFsUser(param.getUserId(), qwExternalId, log.getLogId());
+            //
             courseWatchLogMapper.updateFsCourseWatchLog(log);
+            iSopUserLogsInfoService.updateSopUserInfoByExternalId(qwExternalId, param.getUserId());
 
-        }else {
+
+        } else {
             //没绑定fsUser直接绑定fsUser
             QwExternalContact contact = new QwExternalContact();
             contact.setId(qwExternalId);
             contact.setFsUserId(param.getUserId());
             qwExternalContactMapper.updateQwExternalContact(contact);
+            iSopUserLogsInfoService.updateSopUserInfoByExternalId(qwExternalId, param.getUserId());
+
             FsUser fsUser = new FsUser();
             fsUser.setUserId(user.getUserId());
             fsUser.setIsAddQw(1);
@@ -639,7 +662,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         }
         //重粉逻辑
         fsUserCompanyBindService.bindFsUser(param.getUserId(), qwExternalId, log.getLogId());
-        return R.error(567,"群聊通用链接").put("qwExternalId", qwExternalContact.getId());
+        return R.error(567, "群聊通用链接").put("qwExternalId", qwExternalContact.getId());
     }
     private R handleRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
         //查询客户列表

+ 20 - 5
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/WellnessFoodCheck.java

@@ -3,6 +3,7 @@ package com.fs.hisStore.service.categoryVal;
 import com.fs.common.utils.txocr.ContainsResult;
 import com.fs.hisStore.domain.FsStoreScrm;
 import com.fs.hisStore.service.impl.FsStoreScrmServiceImpl;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
@@ -35,11 +36,25 @@ public class WellnessFoodCheck extends AbstractHandler{
     public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType){
         FsStoreScrm fsStoreScrm = fsStoreScrmService.selectFsStoreByStoreId(storeId);
         ContainsResult result = new ContainsResult();
-        boolean flag = StringUtils.isNotEmpty(fsStoreScrm.getFoodLicense());
-        result.setFlag(flag);
-        result.setMessage(flag ? "已上传健康食品经营许可证" : "未上传健康食品经营许可证");
-        //目前没有办法通过文档抽取保健食品中前面的打勾,只能判断是否上传,当然可以重写TxOcrClient.ExtractDocBasic方法。
-        return result;
+        if(ObjectUtils.isEmpty(fsStoreScrm.getFoodLicenseBusinessScope())){
+            result.setFlag(false);
+            result.setMessage("未填写传健康食品经营许可证");
+            return result;
+        }else{
+            String foodLicenseBusinessScope = fsStoreScrm.getFoodLicenseBusinessScope();
+
+            boolean ybz_flag = foodLicenseBusinessScope.contains("预包装食品");
+            boolean bj_flag = foodLicenseBusinessScope.contains("保健食品");
+            if(ybz_flag || bj_flag){
+                result.setFlag(true);
+                result.setMessage("通过");
+            }else {
+                result.setFlag(false);
+                result.setMessage("不符合!");
+            }
+            return result;
+        }
+
     }
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -533,4 +533,6 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
      * 根据qw_user_id+crop_id+external_user_id查询外部联系人信息
      * */
     QwExternalContact selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(ExternalContactParam externalContactParam);
+
+    List<QwExternalContact> getGroupChatUserByChatIdAndUserName(@Param("userId")String userId,@Param("userName")String userName,@Param("corpId") String corpId,@Param("chatId") String chatId);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/sop/service/IQwSopTempRulesService.java

@@ -88,4 +88,6 @@ public interface IQwSopTempRulesService extends IService<QwSopTempRules>{
     List<QwSopTempRules> listById(List<Long> rulesIds);
 
     void updateSiFenTemp();
+
+    List<QwSopTempRules> selectListByDayId(Long id);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/sop/service/ISopUserLogsService.java

@@ -66,4 +66,6 @@ public interface ISopUserLogsService {
     public List<SopUserLogs> meetsTherestoreByIsDaysNotStudy(int offset,int pageSize,Integer notStudyDays);
 
     void replaceUser(ReplaceUserDto vo);
+
+    R getShortLink(String id, String sopId, String appId);
 }

+ 6 - 0
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java

@@ -245,4 +245,10 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
             contentMapper.updateQwSopTempContent(content1);
         }
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public List<QwSopTempRules> selectListByDayId(Long id) {
+        return list(new QueryWrapper<QwSopTempRules>().eq("day_id", id));
+    }
 }

+ 6 - 6
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -1495,9 +1495,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     }
 
     //插入观看记录
-    private void addWatchLogIfNeeded(String sopId, Integer videoId, Integer courseId,
-                                     Long fsUserId, String qwUserId, String companyUserId,
-                                     String companyId, Long externalId, String startTime,Date createTime) {
+    void addWatchLogIfNeeded(String sopId, Integer videoId, Integer courseId,
+                             Long fsUserId, String qwUserId, String companyUserId,
+                             String companyId, Long externalId, String startTime, Date createTime) {
 
         try {
             FsCourseWatchLog watchLog = new FsCourseWatchLog();
@@ -1551,9 +1551,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         return sortLink.replaceAll("^[\\s\\u2005]+", "");
     }
 
-    private String createLinkByMiniApp(QwSopCourseFinishTempSetting.Setting setting, String corpId, Date sendTime,
-                                     Integer courseId, Integer videoId, Long qwUserId,
-                                     String companyUserId, String companyId, Long externalId,CourseConfig config, String chatId) {
+    String createLinkByMiniApp(QwSopCourseFinishTempSetting.Setting setting, String corpId, Date sendTime,
+                               Integer courseId, Integer videoId, Long qwUserId,
+                               String companyUserId, String companyId, Long externalId, CourseConfig config, String chatId) {
 
         FsCourseLink link = createFsCourseLink(corpId, sendTime, courseId, videoId, qwUserId,
                                                 companyUserId, companyId, externalId,3,chatId);

+ 75 - 7
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsServiceImpl.java

@@ -8,6 +8,7 @@ import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.date.DateUtil;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.param.FsCourseLinkCreateParam;
@@ -16,18 +17,18 @@ import com.fs.crm.domain.CrmMsg;
 import com.fs.crm.mapper.CrmMsgMapper;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwGroupChat;
+import com.fs.qw.domain.QwGroupChatUser;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
+import com.fs.qw.mapper.QwGroupChatMapper;
+import com.fs.qw.mapper.QwGroupChatUserMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.param.SopUserLogsVO;
 import com.fs.qw.service.IQwGroupChatService;
 import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.*;
 import com.fs.qwApi.service.QwApiService;
-import com.fs.sop.domain.QwSop;
-import com.fs.sop.domain.QwSopLogs;
-import com.fs.sop.domain.SopUserLogs;
-import com.fs.sop.domain.SopUserLogsInfo;
+import com.fs.sop.domain.*;
 import com.fs.sop.mapper.QwSopMapper;
 import com.fs.sop.mapper.SopUserLogsInfoMapper;
 import com.fs.sop.mapper.SopUserLogsMapper;
@@ -35,9 +36,7 @@ import com.fs.sop.params.QwRatingConfig;
 import com.fs.sop.params.SopUserLogsList;
 import com.fs.sop.params.SopUserLogsParam;
 import com.fs.sop.params.SopUserLogsParamByDate;
-import com.fs.sop.service.IQwSopLogsService;
-import com.fs.sop.service.IQwSopTempDayService;
-import com.fs.sop.service.ISopUserLogsService;
+import com.fs.sop.service.*;
 import com.fs.sop.vo.QwRatingVO;
 import com.fs.sop.vo.ReplaceUserDto;
 import com.fs.sop.vo.SopUserLogsInfoVo;
@@ -96,6 +95,24 @@ public class SopUserLogsServiceImpl  implements ISopUserLogsService {
     @Autowired
     private QwExternalContactMapper qwExternalContactMapper;
 
+    @Autowired
+    private IQwSopTempService sopTempService;
+
+    @Autowired
+    private IQwSopTempRulesService qwSopTempRulesService;
+
+    @Autowired
+    private QwGroupChatMapper qwGroupChatMapper;
+
+    @Autowired
+    private QwGroupChatUserMapper qwGroupChatUserMapper;
+
+    @Autowired
+    private SopUserLogsInfoServiceImpl sopUserLogsInfoService;
+
+    @Autowired
+    private IFsCourseLinkService linkService;
+
     @Autowired
     private IQwSopTempDayService qwSopTempDayService;
 
@@ -152,6 +169,57 @@ public class SopUserLogsServiceImpl  implements ISopUserLogsService {
         sopUserLogsMapper.replaceUser(vo);
     }
 
+    @Override
+    public R getShortLink(String id, String sopId, String appId) {
+        QwSop qwSop = sopMapper.selectQwSopById(sopId);
+        QwSopTemp qwSopTemp = sopTempService.selectQwSopTempById(qwSop.getTempId());
+        SopUserLogs sopUserLogs = sopUserLogsMapper.selectSopUserLogsById(id);
+        String[] userKey = sopUserLogs.getUserId().split("\\|");
+        String qwUserId = userKey[0].trim();
+        QwUser qwUser = qwUserMapper.selectById(qwUserId);
+        Optional<QwSopTempDay> dayOptional = qwSopTemp.getList().stream().filter(e -> Objects.equals(e.getDayNum(), sopUserLogs.getCountDays())).findFirst();
+        if (dayOptional.isPresent()) {
+            List<QwSopTempRules> rulesList = qwSopTempRulesService.selectListByDayId(dayOptional.get().getId());
+            Optional<QwSopTempRules> rulesOptional = rulesList.stream().filter(r -> r.getCourseId() != null).findFirst();
+            if (rulesOptional.isPresent()) {
+                QwSopTempRules rules = rulesOptional.get();
+                QwGroupChat groupChat = qwGroupChatMapper.selectQwGroupChatByChatId(sopUserLogs.getChatId());
+                List<QwGroupChatUser> groupUserList = qwGroupChatUserMapper.selectQwGroupChatUserByChatIds(new String[]{sopUserLogs.getChatId()});
+                List<String> groupChatUserIds = PubFun.listToNewList(groupUserList, QwGroupChatUser::getUserId);
+                if (!groupChatUserIds.isEmpty()) {
+                    List<GroupUserExternalVo> userList = qwExternalContactMapper.selectByGroupUser(groupChatUserIds);
+                    Map<String, List<GroupUserExternalVo>> userMap = PubFun.listToMapByGroupList(userList, GroupUserExternalVo::getExternalUserId);
+                    groupUserList.forEach(e -> {
+                        e.setUserList(userMap.getOrDefault(e.getUserId(), Collections.emptyList()));
+                    });
+                }
+                try {
+                    groupUserList.stream().filter(e -> e.getUserList() != null && !e.getUserList().isEmpty()).forEach(e -> {
+                        Map<String, GroupUserExternalVo> userMap = PubFun.listToMapByGroupObject(e.getUserList(), GroupUserExternalVo::getUserId);
+                        GroupUserExternalVo vo = userMap.get(groupChat.getOwner());
+                        if (vo != null && vo.getId() != null) {
+                            sopUserLogsInfoService.addWatchLogIfNeeded(sopId, rules.getVideoId().intValue(), rules.getCourseId().intValue(), vo.getFsUserId(), qwUser.getId().toString(), qwUser.getCompanyUserId().toString(), qwUser.getCompanyId().toString(), vo.getId(), sopUserLogs.getStartTime(), new Date());
+                        }
+                    });
+                } catch (Exception e) {
+                    log.error("群聊创建看课记录失败!", e);
+                }
+                QwSopCourseFinishTempSetting.Setting st = new QwSopCourseFinishTempSetting.Setting();
+                st.setExpiresDays(1);
+                String json = configService.selectConfigByKey("course.config");
+                CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+                String linkByMiniApp = sopUserLogsInfoService.createLinkByMiniApp(st, sopUserLogs.getCorpId(), new Date(), rules.getCourseId().intValue(), rules.getVideoId().intValue(),
+                        qwUser.getId(), qwUser.getCompanyUserId().toString(), qwUser.getCompanyId().toString(), null, config, sopUserLogs.getChatId());
+                if(StringUtils.isNotEmpty(linkByMiniApp)){
+                    linkByMiniApp = linkByMiniApp.replaceAll(".html", "");
+                }
+                String link = linkService.getGotoWxAppLink(linkByMiniApp, appId);
+                return R.ok().put("urlLink", link);
+            }
+        }
+        return R.error("系统错误❌");
+    }
+
     @Override
     public int deleteSopUserLogsBySopId(String sopId) {
         return sopUserLogsMapper.deleteSopUserLogsBySopId(sopId);

+ 3 - 3
fs-service/src/main/resources/application-dev-yjb.yml

@@ -33,9 +33,9 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                    url: jdbc:mysql://139.186.77.83:3306/yjb_his_scrm_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                    username: Rtroot
-                    password: Rtroot
+                  url: jdbc:mysql://nj-cdb-6306xy90.sql.tencentcdb.com:27077/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  username: root
+                  password: Ylrz147..
                 # 初始连接数
                 initialSize: 5
                 # 最小连接池数量

+ 8 - 0
fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

@@ -786,4 +786,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectQwExternalContactVo"/>
         where user_id = #{userId} and corp_id = #{corpId} and external_user_id = #{externalUserId}
     </select>
+    <select id="getGroupChatUserByChatIdAndUserName"  resultType="com.fs.qw.domain.QwExternalContact">
+        select t1.* from qw_external_contact t1
+        inner join qw_group_chat_user t2 on t1.external_user_id  = t2.user_id and t2.chat_id = #{chatId}
+        where t1.name = #{userName}
+        and t1.user_id = #{userId}
+        and t1.corp_id = #{corpId}
+        and t1.status = 0
+    </select>
 </mapper>