Forráskód Böngészése

Merge remote-tracking branch 'origin/master' into matser

吴树波 1 hete
szülő
commit
5904c6e792
28 módosított fájl, 260 hozzáadás és 123 törlés
  1. 2 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreUserEndCategoryScrmController.java
  2. 7 2
      fs-company/src/main/java/com/fs/company/controller/company/CompanyVoiceRoboticController.java
  3. 65 0
      fs-ipad-task/src/main/java/com/fs/app/controller/CommonController.java
  4. 4 0
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  5. 1 1
      fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java
  6. 49 95
      fs-ipad-task/src/main/java/com/fs/app/task/SendSmsMsg.java
  7. 14 0
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  8. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  9. 2 0
      fs-service/src/main/java/com/fs/course/param/FsCourseH5ListParam.java
  10. 2 0
      fs-service/src/main/java/com/fs/course/service/IFsCourseLinkService.java
  11. 15 0
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  12. 6 3
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java
  13. 2 2
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductUserEndCategoryMapper.java
  14. 2 2
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreProductScrmService.java
  15. 2 2
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreUserEndCategoryScrmService.java
  16. 4 2
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java
  17. 5 5
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreUserEndCategoryScrmServiceImpl.java
  18. 1 1
      fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java
  19. 2 0
      fs-service/src/main/java/com/fs/statis/mapper/ConsumptionBalanceMapper.java
  20. 10 1
      fs-service/src/main/java/com/fs/statis/service/impl/StatisticsCompanyServiceImpl.java
  21. 9 2
      fs-service/src/main/java/com/fs/statis/service/impl/StatisticsServiceImpl.java
  22. 9 0
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  23. 6 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  24. 6 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductUserEndCategoryMapper.xml
  25. 1 1
      fs-service/src/main/resources/mapper/sop/QwSopLogsMapper.xml
  26. 13 0
      fs-service/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml
  27. 13 0
      fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserController.java
  28. 5 3
      fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

+ 2 - 1
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreUserEndCategoryScrmController.java

@@ -47,10 +47,11 @@ public class FsStoreUserEndCategoryScrmController extends BaseController {
     @GetMapping("/products")
     public TableDataInfo listProductsByCategoryId(
             @RequestParam Long id,
+            @RequestParam(value = "keyword", required = false) String keyword,
             @RequestParam(defaultValue = "1") Integer pageNum,
             @RequestParam(defaultValue = "10") Integer pageSize) {
         startPage();
-        List<FsStoreUserEndCategoryProductVO> list = userEndCategoryService.listProductsByCategoryId(id);
+        List<FsStoreUserEndCategoryProductVO> list = userEndCategoryService.listProductsByCategoryId(id,keyword);
         return getDataTable(list);
     }
 

+ 7 - 2
fs-company/src/main/java/com/fs/company/controller/company/CompanyVoiceRoboticController.java

@@ -1,5 +1,6 @@
 package com.fs.company.controller.company;
 
+import com.alibaba.fastjson.JSONObject;
 import com.fs.aicall.domain.BaseDomain;
 import com.fs.aicall.domain.TaskInfo;
 import com.fs.aicall.domain.apiresult.PushIIntentionResult;
@@ -28,6 +29,7 @@ import com.fs.company.vo.CdrDetailVo;
 import com.fs.company.vo.WorkflowExecRecordVo;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
@@ -45,6 +47,7 @@ import java.util.stream.Collectors;
  */
 @RestController
 @RequestMapping("/company/companyVoiceRobotic")
+@Slf4j
 public class CompanyVoiceRoboticController extends BaseController
 {
     @Autowired
@@ -225,8 +228,10 @@ public class CompanyVoiceRoboticController extends BaseController
     }
 
     @PostMapping("/callerResult4EasyCall")
-    public R callerResult4EasyCall(CdrDetailVo cdr) {
-        companyVoiceRoboticService.callerResult4EasyCall(cdr);
+    public R callerResult4EasyCall(@RequestBody String cdrStr) {
+        log.info(cdrStr);
+        CdrDetailVo cdrDetailVo = JSONObject.parseObject(cdrStr, CdrDetailVo.class);
+        companyVoiceRoboticService.callerResult4EasyCall(cdrDetailVo);
         return R.ok();
     }
     /**

+ 65 - 0
fs-ipad-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -0,0 +1,65 @@
+package com.fs.app.controller;
+
+
+import com.baidu.dev2.thirdparty.swagger.annotations.Api;
+import com.fs.app.service.IpadSendServer;
+import com.fs.app.task.SendSmsMsg;
+import com.fs.common.core.redis.RedisCacheT;
+import com.fs.course.service.IFsCourseWatchLogService;
+import com.fs.qw.mapper.QwPushCountMapper;
+import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.impl.AsyncSopTestService;
+import com.fs.sop.mapper.QwSopLogsMapper;
+import com.fs.sop.service.IQwSopLogsService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Api("公共接口")
+@RestController
+@RequestMapping(value="/app/common")
+@Slf4j
+public class CommonController {
+
+    private final SendSmsMsg sendSmsMsg;
+    @Autowired
+    private QwUserMapper qwUserMapper;
+    @Autowired
+    private QwSopLogsMapper qwSopLogsMapper;
+    @Autowired
+    private IQwSopLogsService qwSopLogsService;
+    @Autowired
+    private AsyncSopTestService asyncSopTestService;
+
+    @Autowired
+    private RedisCacheT<Long> redisCache;
+    @Autowired
+    private QwPushCountMapper qwPushCountMapper;
+
+
+    @Autowired
+    private IFsCourseWatchLogService watchLogService;
+
+    @Autowired
+    private IpadSendServer sendServer;
+
+    private final Map<Long, Long> qwMap = new ConcurrentHashMap<>();
+
+    @Autowired
+    public CommonController(SendSmsMsg sendSmsMsg) {
+        this.sendSmsMsg = sendSmsMsg;
+    }
+
+
+    @RequestMapping("/startSendSmsMsg/{num}")
+    public void startSendSmsMsg(@PathVariable String  num) {
+        log.info("开始启动定时任务");
+        sendSmsMsg.sendSms(num);
+    }
+
+}

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

@@ -719,6 +719,10 @@ public class IpadSendServer {
                     // 发送直播短链
                     sendLiveShortLink(vo, content, miniMap);
                     break;
+                case "21":
+                    content.setSendStatus(0);
+                    content.setSendRemarks("短信待发送");
+                    break;
                 case "99":
                     // 群发
                     sendTxtAtMsg(vo);

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

@@ -208,7 +208,7 @@ public class SendMsg {
                 }
             }
             else{
-                // 判断消息状态是否满足发送条件
+                // 判断消息状态是否满足发isSendLogs送条件
                 if (!sendServer.isSendLogs(qwSopLogs, setting, user)) {
                     log.info("销售:{}, 消息发送条件未满足:{}", user.getQwUserName(), qwSopLogs.getId());
                     continue;

+ 49 - 95
fs-ipad-task/src/main/java/com/fs/app/task/SendSmsMsg.java

@@ -16,6 +16,7 @@ import com.fs.his.service.IFsUserService;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.qw.domain.QwIpadServer;
 import com.fs.qw.domain.QwSopSmsLogs;
+import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwIpadServerMapper;
 import com.fs.qw.service.IQwSopSmsLogsService;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
@@ -260,10 +261,13 @@ public class SendSmsMsg {
                 continue;
             }
             QwSopLogs qwSopLogs = sopLogsMap.get(logRecord.getSopLogId());
-            QwSopCourseFinishTempSetting setting = JSON.parseObject(qwSopLogs.getContentJson(), QwSopCourseFinishTempSetting.class);
+
             // 判断消息状态是否满足发送条件
-            if (!isSendLogs(qwSopLogs, setting)) {
+            SendResultDetailDTO checkDto= isSendLogs(qwSopLogs,logRecord);
+            if (!checkDto.isSuccess()) {
                 log.info("销售:{}, 消息发送条件未满足:{}", qwSopLogs.getQwUserKey(), qwSopLogs.getId());
+                failReasonsList.add(checkDto);
+                failedIds.add(logRecord.getId());
                 continue;
             }
 
@@ -382,34 +386,51 @@ public class SendSmsMsg {
             try {
                 qwSopSmsLogsService.updateStatusByIds(failedIds, "3"); // 失败状态
                 if (!failReasonsList.isEmpty()) {
+
                     //组装数据
                     List<QwSopLogs> updateList = failReasonsList.stream().map(f -> {
-                        QwSopLogs update = new QwSopLogs();
-                        update.setSmsLogsId(f.getSopLogId());
-                        update.setRemark(f.getFailReason());
-                        //同步json发送状态
-                        if (sopLogsMap != null && sopLogsMap.containsKey(f.getSopLogId())) {
-                            try {
-                                String contentJson = sopLogsMap.get(f.getSopLogId()).getContentJson();
-                                JSONObject jsonObject = JSONObject.parseObject(contentJson);
-                                JSONArray settingArray = jsonObject.getJSONArray("setting");
-                                if (settingArray != null && !settingArray.isEmpty()) {
-                                    for (int i = 0; i < settingArray.size(); i++) {
-                                        JSONObject item = settingArray.getJSONObject(i);
-                                        item.put("sendStatus", "0");
+
+                                QwSopLogs qwSopLogs = sopLogsMap.get(f.getSopLogId());
+
+                                if (qwSopLogs == null) {
+                                    return null;
+                                }
+
+                                //已经标记过的  节约资源不再走update
+                                if (qwSopLogs.getSendStatus()==5 || qwSopLogs.getReceivingStatus()==4){
+                                    return null;
+                                }
+
+                                QwSopLogs update = new QwSopLogs();
+                                update.setSmsLogsId(f.getSopLogId());
+                                update.setRemark(f.getFailReason());
+                                //同步json发送状态
+                                if (sopLogsMap.containsKey(f.getSopLogId())) {
+                                    try {
+                                        String contentJson = sopLogsMap.get(f.getSopLogId()).getContentJson();
+                                        JSONObject jsonObject = JSONObject.parseObject(contentJson);
+                                        JSONArray settingArray = jsonObject.getJSONArray("setting");
+                                        if (settingArray != null && !settingArray.isEmpty()) {
+                                            for (int i = 0; i < settingArray.size(); i++) {
+                                                JSONObject item = settingArray.getJSONObject(i);
+                                                item.put("sendStatus", "0");
+                                            }
+                                            update.setContentJson(jsonObject.toJSONString());
+                                        }
+                                    } catch (Exception e) {
+                                        log.warn("解析ContentJson失败,sopLogId:{}", f.getSopLogId(), e);
+                                        update.setContentJson(sopLogsMap.get(f.getSopLogId()).getContentJson());
                                     }
-                                    update.setContentJson(jsonObject.toJSONString());
                                 }
-                            } catch (Exception e) {
-                                log.warn("解析ContentJson失败,sopLogId:{}", f.getSopLogId(), e);
-                                update.setContentJson(sopLogsMap.get(f.getSopLogId()).getContentJson());
-                            }
-                        }
-                        return update;
-                    }).collect(Collectors.toList());
+                                return update;
+                            })
+                            .filter(Objects::nonNull)
+                            .collect(Collectors.toList());
 
                     //批量同步执行记录表
-                    qwSopLogsMapper.batchUpdateQwSopLogsBySmsLogsId(updateList);
+                    if (!updateList.isEmpty()) {
+                        qwSopLogsMapper.batchUpdateQwSopLogsBySmsLogsId(updateList);
+                    }
                 }
                 log.debug("批量更新失败状态完成,条数:{}", failedIds.size());
             } catch (Exception e) {
@@ -465,81 +486,14 @@ public class SendSmsMsg {
 
 
 
-    public boolean isSendLogs(QwSopLogs qwSopLogs, QwSopCourseFinishTempSetting setting) {
-        Long qwUserId = qwSopLogs.getQwUserKey();
-        if(qwSopLogs.getSendStatus() != 3){
-            log.info("状态异常不发送:{}, LOGID: {}", qwSopLogs.getQwUserKey(), qwSopLogs.getId());
-            return false;
-        }
-
-        boolean noSop = qwSopLogs.getSendType() != 3 && qwSopLogs.getSendType() != 7;
-
-        if (qwSopLogs.getExpiryTime() == null && noSop) {
-            // 作废消息
-            log.info("SOP_LOG_ID:{}, SOP任务被删除", qwSopLogs.getId());
-            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "SOP任务被删除");
-            return false;
-        }
-
-        LocalDateTime sendTime = DateUtil.stringToLocalDateTime(qwSopLogs.getSendTime());
-        LocalDateTime expiryDateTime;
-
-        // 判断是否过期
-        if(qwSopLogs.getSendType() == 3 || qwSopLogs.getSendType() == 7){
-            expiryDateTime = sendTime.plusHours(12);
-        }else{
-            expiryDateTime = sendTime.plusHours(qwSopLogs.getExpiryTime());
-        }
+    public SendResultDetailDTO isSendLogs(QwSopLogs qwSopLogs,QwSopSmsLogs logRecord) {
 
-        if (LocalDateTime.now().isAfter(expiryDateTime)  ) {
-            // 作废消息
-            log.info("SOP_LOG_ID:{}, 已过期,不发送", qwSopLogs.getId());
-            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "已过期,不发送");
-            return false;
-        }
+        if (qwSopLogs.getSendStatus()==5 || qwSopLogs.getReceivingStatus()==4) {
 
-        if (setting.getCourseType() == null && noSop && setting.getType() == 2) {
-            log.info("SOP_LOG_ID:{}, 模板未选消息类型,不发送", qwSopLogs.getId());
-            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "模板未选消息类型,不发送");
-            return false;
-        }
-        Integer cacheValue = redisCache.getCacheObject("sopCourse:video:isPause:" + setting.getVideoId());
-        int isPause = (cacheValue != null) ? cacheValue : 0;
-        log.info("SOP_LOG_ID:{},判断课程({})当前状态:{}", qwSopLogs.getId(), setting.getVideoId(), isPause);
-        if (isPause == 1){
-            log.info("SOP_LOG_ID:{}, 课程暂停,不发送", qwSopLogs.getId());
-            qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "课程暂停,AI不发送");
-            return false;
+            return new SendResultDetailDTO(false, qwSopLogs.getRemark(), logRecord.getSopLogId());
         }
 
-        if (qwSopLogs.getSendType() != 12 && noSop) {
-            // 客户的信息
-            Integer courseType = setting.getCourseType();
-            if (setting.getType() == 2 && courseType != 0) {// 课程消息,进行复杂的条件判断
-                FsCourseWatchLog watchLog = watchLogService.getWatchCourseLogVideoBySop(
-                        setting.getVideoId().longValue(),
-                        String.valueOf(qwUserId),
-                        qwSopLogs.getExternalId()
-                );
-                log.debug("ID:{}-看课记录参数:videoID:{}, qwUserID:{}, extID:{}", qwSopLogs.getId(), setting.getVideoId().longValue(), qwUserId, qwSopLogs.getExternalId());
-                log.debug("ID:{}-看课记录:{}", qwSopLogs.getId(), watchLog);
-                String logId = qwSopLogs.getId();
-                if (watchLog != null) {
-                    //新逻辑
-                    if (!QwSopLogsServiceImpl.isCourseTypeValid(courseType, watchLog.getLogType())) {
-                        // 作废消息
-                        log.info("SOP_LOG_ID:{}, 看课状态未满足,不发送", qwSopLogs.getId());
-                        qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "看课状态未满足,不发送");
-                        return false;
-                    }
-                } else {
-                    log.info("SOP_LOG_ID:{}, 无观看记录,不发送", qwSopLogs.getId());
-                    qwSopLogsService.updateQwSopLogsByWatchLogType(logId, "无观看记录,不发送");
-                    return false;
-                }
-            }
-        }
-        return true;
+        return new SendResultDetailDTO(true, "检测通过", logRecord.getSopLogId());
     }
 
 }

+ 14 - 0
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -190,6 +190,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
     // Executors for consumer threads
     private ExecutorService qwSopLogsExecutor;
+    private ExecutorService qwSopSmsLogsExecutor;
     private ExecutorService watchLogsExecutor;
     private ExecutorService courseLinkExecutor;
     private ExecutorService courseSopAppLinkExecutor;
@@ -250,6 +251,13 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             t.setDaemon(true);
             return t;
         });
+
+        qwSopSmsLogsExecutor = Executors.newSingleThreadExecutor(r -> {
+            Thread t = new Thread(r, "QwSopSmsLogsConsumer");
+            t.setDaemon(true);
+            return t;
+        });
+
         watchLogsExecutor = Executors.newSingleThreadExecutor(r -> {
             Thread t = new Thread(r, "WatchLogsConsumer");
             t.setDaemon(true);
@@ -274,6 +282,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         });
 
         qwSopLogsExecutor.submit(this::consumeQwSopLogs);
+        qwSopSmsLogsExecutor.submit(this::consumeQwSopSmsLogs);
         watchLogsExecutor.submit(this::consumeWatchLogs);
         courseLinkExecutor.submit(this::consumeCourseLink);
         courseSopAppLinkExecutor.submit(this::consumeCourseSopAppLink);
@@ -304,6 +313,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     public void shutdownConsumers() {
         running = false;
         qwSopLogsExecutor.shutdown();
+        qwSopSmsLogsExecutor.shutdown();
         watchLogsExecutor.shutdown();
         courseLinkExecutor.shutdown();
         courseSopAppLinkExecutor.shutdown();
@@ -312,6 +322,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             if (!qwSopLogsExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                 qwSopLogsExecutor.shutdownNow();
             }
+            if (!qwSopSmsLogsExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
+                qwSopSmsLogsExecutor.shutdownNow();
+            }
             if (!watchLogsExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
                 watchLogsExecutor.shutdownNow();
             }
@@ -326,6 +339,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             }
         } catch (InterruptedException e) {
             qwSopLogsExecutor.shutdownNow();
+            qwSopSmsLogsExecutor.shutdownNow();
             watchLogsExecutor.shutdownNow();
             courseLinkExecutor.shutdownNow();
             courseSopAppLinkExecutor.shutdownNow();

+ 3 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -752,4 +752,7 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     List<FsSopMyCourseH5LinkVO> getSopCourseH5StudyList(@Param("userId") Long userId);
 
     List<FsCourseWatchLog> selectFsUserWatchLogByExtId(QwExternalContact qwExternalContact);
+
+    List<FsSopMyCourseH5LinkVO> getSopCourseH5StudyListByQwExId(@Param("qwExternalId") Long qwExternalId);
+
 }

+ 2 - 0
fs-service/src/main/java/com/fs/course/param/FsCourseH5ListParam.java

@@ -17,4 +17,6 @@ public class FsCourseH5ListParam {
     private Long userId;
 
     private Long logId;
+
+    private String link;
 }

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

@@ -112,4 +112,6 @@ public interface IFsCourseLinkService
     List<FsCourseLinkDTO> selectFsCourseLinkListByQwUserId(FsCourseH5ListParam param);
 
     R getLinkInfo(Long logId);
+
+    R getSopCourseH5StudyListByMsg(FsCourseH5ListParam param);
 }

+ 15 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java

@@ -30,6 +30,7 @@ import com.fs.course.param.FsCourseLinkRoomParam;
 import com.fs.course.service.IFsCourseLinkService;
 import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.course.service.IFsUserCourseService;
+import com.fs.course.vo.FsSopMyCourseH5LinkVO;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.his.utils.HttpUtil;
@@ -45,6 +46,8 @@ import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
 import lombok.Synchronized;
@@ -1032,6 +1035,18 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
         return R.ok().put("data",map);
     }
 
+    @Override
+    public R getSopCourseH5StudyListByMsg(FsCourseH5ListParam param) {
+        FsCourseLink courseLink = fsCourseLinkMapper.selectFsCourseLinkByLink(param.getLink());
+        if (courseLink != null && courseLink.getQwExternalId()!=null) {
+            PageHelper.startPage(param.getPageNum(), param.getPageSize());
+            List<FsSopMyCourseH5LinkVO> list = fsCourseWatchLogMapper.getSopCourseH5StudyListByQwExId(courseLink.getQwExternalId());
+            return R.ok().put("data",new PageInfo(list));
+        }
+
+        return R.error("链接失效或未绑定销售");
+    }
+
     @Override
     public R getLiveWxaCodeGenerateScheme(String linkStr, String appId) {
         CloseableHttpClient client = null;

+ 6 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java

@@ -1805,9 +1805,12 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
 
         FsInquiryOrderPatientDTO dto=new FsInquiryOrderPatientDTO();
         BeanUtils.copyProperties(patient,dto);
-        dto.setAge(String.valueOf( DateUtil.ageOfNow(patient.getBirthday())));
-        // 使用 SimpleDateFormat 格式化日期对象
-        dto.setBirthday(new SimpleDateFormat("yyyy-MM-dd").format(patient.getBirthday()));
+        // 鸿森堂的特殊判断
+        if(fsPackage.getIsHealthProductType() == 0){
+            dto.setAge(String.valueOf( DateUtil.ageOfNow(patient.getBirthday())));
+            // 使用 SimpleDateFormat 格式化日期对象
+            dto.setBirthday(new SimpleDateFormat("yyyy-MM-dd").format(patient.getBirthday()));
+        }
         FsInquiryOrder order=new FsInquiryOrder();
         order.setOrderSn(packageOrder.getOrderSn());
         order.setOrderType(2);

+ 2 - 2
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductUserEndCategoryMapper.java

@@ -20,8 +20,8 @@ public interface FsStoreProductUserEndCategoryMapper {
     int deleteByCategoryIds(@Param("categoryIds") Long[] categoryIds);
 
     /** 按用户端分类ID查询去重后的商品ID列表(用于分页,配合 PageHelper) */
-    List<Long> selectDistinctProductIdsByCategoryId(@Param("categoryId") Long categoryId);
+    List<Long> selectDistinctProductIdsByCategoryId(@Param("categoryId") Long categoryId, @Param("keyword") String keyword);
 
     /** 关联表内全部去重商品ID(不按分类,配合 PageHelper 用于「全部」) */
-    List<Long> selectDistinctProductIds();
+    List<Long> selectDistinctProductIds(@Param("keyword") String keyword);
 }

+ 2 - 2
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreProductScrmService.java

@@ -105,10 +105,10 @@ public interface IFsStoreProductScrmService
     List<FsStoreProductListQueryVO> selectFsStoreProductHotQuery(int count, String appId);
 
     /** 绿色有机分页(与 selectFsStoreProductNewQuery 条件一致,支持分页) */
-    List<FsStoreProductListQueryVO> selectFsStoreProductNewQueryPage(int pageNum, int pageSize, String appId);
+    List<FsStoreProductListQueryVO> selectFsStoreProductNewQueryPage(int pageNum, int pageSize, String appId, String keyword);
 
     /** 上新推荐分页(与 selectFsStoreProductHotQuery 条件一致,支持分页) */
-    List<FsStoreProductListQueryVO> selectFsStoreProductHotQueryPage(int pageNum, int pageSize, String appId);
+    List<FsStoreProductListQueryVO> selectFsStoreProductHotQueryPage(int pageNum, int pageSize, String appId, String keyword);
 
     List<FsStoreProductListQueryVO> selectFsStoreProductGoodQuery(int count);
 

+ 2 - 2
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreUserEndCategoryScrmService.java

@@ -24,10 +24,10 @@ public interface IFsStoreUserEndCategoryScrmService {
     List<FsStoreUserEndCategoryScrm> selectTop8ByPosition(Long storeId, Integer position);
 
     /** 按用户端分类ID分页查询关联商品(去重商品ID分页,再查商品简表+标签并组装) */
-    List<FsStoreUserEndCategoryProductVO> listProductsByCategoryId(Long categoryId);
+    List<FsStoreUserEndCategoryProductVO> listProductsByCategoryId(Long categoryId, String keyword);
 
     /** 首页商品列表:id 为空查全部(分页商品ID后查简表+标签),id 不为空按用户端分类查;返回 list+total */
-    java.util.Map<String, Object> listProductsForApp(Long id, Integer pageNum, Integer pageSize);
+    java.util.Map<String, Object> listProductsForApp(Long id, String keyword, Integer pageNum, Integer pageSize);
 
     int insert(FsStoreUserEndCategoryScrm entity);
 

+ 4 - 2
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java

@@ -1177,19 +1177,21 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
     }
 
     @Override
-    public List<FsStoreProductListQueryVO> selectFsStoreProductNewQueryPage(int pageNum, int pageSize, String appId) {
+    public List<FsStoreProductListQueryVO> selectFsStoreProductNewQueryPage(int pageNum, int pageSize, String appId, String keyword) {
         HashMap<String, Object> map = new HashMap<>();
         map.put("config", medicalMallConfig);
         map.put("appId", appId);
+        map.put("keyword", keyword);
         com.github.pagehelper.PageHelper.startPage(pageNum, pageSize);
         return fsStoreProductMapper.selectFsStoreProductNewQueryPage(map);
     }
 
     @Override
-    public List<FsStoreProductListQueryVO> selectFsStoreProductHotQueryPage(int pageNum, int pageSize, String appId) {
+    public List<FsStoreProductListQueryVO> selectFsStoreProductHotQueryPage(int pageNum, int pageSize, String appId, String keyword) {
         HashMap<String, Object> map = new HashMap<>();
         map.put("config", medicalMallConfig);
         map.put("appId", appId);
+        map.put("keyword", keyword);
         com.github.pagehelper.PageHelper.startPage(pageNum, pageSize);
         return fsStoreProductMapper.selectFsStoreProductHotQueryPage(map);
     }

+ 5 - 5
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreUserEndCategoryScrmServiceImpl.java

@@ -41,9 +41,9 @@ public class FsStoreUserEndCategoryScrmServiceImpl implements IFsStoreUserEndCat
     private FsStoreProductTagRelationScrmMapper productTagRelationMapper;
 
     @Override
-    public List<FsStoreUserEndCategoryProductVO> listProductsByCategoryId(Long categoryId) {
+    public List<FsStoreUserEndCategoryProductVO> listProductsByCategoryId(Long categoryId, String keyword) {
         if (categoryId == null) return new ArrayList<>();
-        List<Long> productIds = productUserEndCategoryMapper.selectDistinctProductIdsByCategoryId(categoryId);
+        List<Long> productIds = productUserEndCategoryMapper.selectDistinctProductIdsByCategoryId(categoryId, keyword);
         if (productIds == null || productIds.isEmpty()) return new ArrayList<>();
         List<FsStoreProductScrm> products = fsStoreProductScrmMapper.getStoreProductInProductIds(productIds);
         Map<Long, FsStoreProductScrm> productMap = products.stream().collect(Collectors.toMap(FsStoreProductScrm::getProductId, p -> p, (a, b) -> a));
@@ -79,15 +79,15 @@ public class FsStoreUserEndCategoryScrmServiceImpl implements IFsStoreUserEndCat
     }
 
     @Override
-    public Map<String, Object> listProductsForApp(Long id, Integer pageNum, Integer pageSize) {
+    public Map<String, Object> listProductsForApp(Long id, String keyword, Integer pageNum, Integer pageSize) {
         Map<String, Object> out = new HashMap<>();
         out.put("list", new ArrayList<FsStoreUserEndCategoryProductVO>());
         out.put("total", 0L);
         if (pageNum == null || pageSize == null || pageSize <= 0) return out;
         PageHelper.startPage(pageNum, pageSize);
         List<Long> productIds = (id != null && id != 0L)
-                ? productUserEndCategoryMapper.selectDistinctProductIdsByCategoryId(id)
-                : productUserEndCategoryMapper.selectDistinctProductIds();
+                ? productUserEndCategoryMapper.selectDistinctProductIdsByCategoryId(id, keyword)
+                : productUserEndCategoryMapper.selectDistinctProductIds(keyword);
         long total = productIds instanceof Page ? ((Page<?>) productIds).getTotal() : (productIds != null ? productIds.size() : 0);
         if (productIds == null || productIds.isEmpty()) {
             out.put("total", total);

+ 1 - 1
fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java

@@ -47,7 +47,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
 
     public List<QwUser> batchGetQwUser(@Param("list") List<QwUserKeyDTO> qwUserId);
 
-    @Select("select company_user_id,company_id,welcome_text,qw_user_name,send_msg_type from qw_user where id = #{id}")
+    @Select("select id,company_user_id,company_id,welcome_text,qw_user_name,send_msg_type,server_id from qw_user where id = #{id}")
     public QwUser selectQwUserByIdByWeComeText(@Param("id") Long id);
 
     @Select("select * from qw_user where qw_user_id = #{qwUserId} and corp_id = #{corpId} ")

+ 2 - 0
fs-service/src/main/java/com/fs/statis/mapper/ConsumptionBalanceMapper.java

@@ -141,4 +141,6 @@ public interface ConsumptionBalanceMapper {
     BigDecimal getCurrentBalanceCompanyId(@Param("companyId") Long companyId);
 
     Long smsBalanceCompany(@Param("companyId") Long companyId);
+
+    Long selectFsCourseTrafficLogCount(AnalysisPreviewQueryDTO param);
 }

+ 10 - 1
fs-service/src/main/java/com/fs/statis/service/impl/StatisticsCompanyServiceImpl.java

@@ -29,6 +29,7 @@ import com.hc.openapi.tool.util.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.util.Asserts;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -83,6 +84,9 @@ public class StatisticsCompanyServiceImpl implements IStatisticsCompanyService {
 
     @Autowired
     private QwUserMapper qwUserMapper;
+
+    @Value("${cloud_host.company_name}")
+    private String signProjectName;
     @Override
     public void dataOverviewTask() {
         List<OptionsVO> optionsVOS = companyService.selectAllCompanyList(null);
@@ -882,7 +886,12 @@ public class StatisticsCompanyServiceImpl implements IStatisticsCompanyService {
             dto.setCompletedRate("0");
         }
 
-        Long watchCount = consumptionBalanceMapper.queryWatchCount(param);
+        Long watchCount = null;
+        if("泽林文化".equals(signProjectName)){
+            watchCount =   consumptionBalanceMapper.selectFsCourseTrafficLogCount(param);
+        }else {
+            watchCount = consumptionBalanceMapper.queryWatchCount(param);
+        }
         Long completedCount = consumptionBalanceMapper.queryCompletedCount(param);
 
         if(watchCount == null){

+ 9 - 2
fs-service/src/main/java/com/fs/statis/service/impl/StatisticsServiceImpl.java

@@ -34,6 +34,7 @@ import com.hc.openapi.tool.util.ObjectUtils;
 import com.hc.openapi.tool.util.StringUtils;
 import org.apache.http.util.Asserts;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -89,7 +90,8 @@ public class StatisticsServiceImpl implements IStatisticsService {
     @Autowired
     private IQwIpadServerService qwIpadServerService;
 
-
+    @Value("${cloud_host.company_name}")
+    private String signProjectName;
 
     @Override
     public void dataOverviewTask() {
@@ -792,7 +794,12 @@ public class StatisticsServiceImpl implements IStatisticsService {
             dto.setCompletedRate("0");
         }
 
-        Long watchCount = consumptionBalanceMapper.queryWatchCount(param);
+        Long watchCount = null;
+        if("泽林文化".equals(signProjectName)){
+            watchCount =   consumptionBalanceMapper.selectFsCourseTrafficLogCount(param);
+        }else {
+            watchCount = consumptionBalanceMapper.queryWatchCount(param);
+        }
         Long completedCount = consumptionBalanceMapper.queryCompletedCount(param);
 
         if(watchCount == null){

+ 9 - 0
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -1352,4 +1352,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select log_id logId from fs_course_watch_log where qw_external_contact_id = #{id}
                                                        and qw_user_id = #{qwUserId} and user_id is null
     </select>
+    <select id="getSopCourseH5StudyListByQwExId" resultType="com.fs.course.vo.FsSopMyCourseH5LinkVO">
+        select  c.img_url courseUrl,v.title courseName,c.title,l.log_id logId,u.qw_user_name qwUserName from fs_course_watch_log l
+         left join fs_user_course c on c.course_id = l.course_id
+         left join qw_user u on l.qw_user_id = u.id
+         left join fs_user_course_video v on l.video_id =v.video_id
+        where l.qw_external_contact_id = #{qwExternalId}  AND l.create_time &gt;= CURDATE()
+          AND l.create_time &lt; CURDATE() + INTERVAL 1 DAY
+        order by l.create_time desc
+    </select>
 </mapper>

+ 6 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -534,6 +534,9 @@
         <if test='appId != null and appId != ""'>
             and ((FIND_IN_SET(#{appId}, p.app_ids) > 0))
         </if>
+        <if test='keyword != null and keyword != ""'>
+            and p.product_name like CONCAT('%', #{keyword}, '%')
+        </if>
         and p.is_new=1 and p.is_display=1 order by p.sort desc
     </select>
     <select id="selectFsStoreProductHotQuery" resultType="com.fs.hisStore.vo.FsStoreProductListQueryVO">
@@ -562,6 +565,9 @@
         <if test='appId != null and appId != ""'>
             and ((FIND_IN_SET(#{appId}, p.app_ids) > 0))
         </if>
+        <if test='keyword != null and keyword != ""'>
+            and p.product_name like CONCAT('%', #{keyword}, '%')
+        </if>
         and  p.is_hot=1 and p.is_display=1 order by p.sort desc
     </select>
     <select id="selectFsStoreProductGoodListQuery" resultType="com.fs.hisStore.vo.FsStoreProductListQueryVO">

+ 6 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreProductUserEndCategoryMapper.xml

@@ -23,12 +23,18 @@
     <select id="selectDistinctProductIdsByCategoryId" resultType="java.lang.Long">
         select distinct a.product_id from fs_store_product_user_end_category a left join fs_store_product_scrm c on a.product_id = c.product_id
         where a.user_end_category_id = #{categoryId} and c.is_del = 0 and c.is_show = 1
+        <if test="keyword != null and keyword != ''">
+            and c.product_name like CONCAT('%', #{keyword}, '%')
+        </if>
         order by c.sort desc, c.create_time desc, a.product_id
     </select>
 
     <select id="selectDistinctProductIds" resultType="java.lang.Long">
         select distinct a.product_id from fs_store_product_user_end_category  a left join fs_store_product_scrm c on a.product_id = c.product_id
         where c.is_del = 0 and c.is_show = 1
+        <if test="keyword != null and keyword != ''">
+            and c.product_name like CONCAT('%', #{keyword}, '%')
+        </if>
         order by c.sort desc, c.create_time desc, a.product_id
     </select>
 </mapper>

+ 1 - 1
fs-service/src/main/resources/mapper/sop/QwSopLogsMapper.xml

@@ -966,7 +966,7 @@
     </update>
 
     <select id="getQwSopInfoByUid" resultType="com.fs.sop.domain.QwSopLogs">
-        select id,send_status,expiration_time,send_time,external_id,send_type,sms_logs_id,content_json,qw_user_key from qw_sop_logs where sms_logs_id IN
+        select id,send_status,receiving_status,expiration_time,send_time,external_id,send_type,sms_logs_id,content_json,qw_user_key from qw_sop_logs where sms_logs_id IN
         <foreach item="item" collection="sopSmsLogIds" separator="," open="(" close=")">
             #{item}
         </foreach>

+ 13 - 0
fs-service/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml

@@ -523,5 +523,18 @@
             AND is_del=0
         </where>
     </select>
+    <select id="selectFsCourseTrafficLogCount" resultType="java.lang.Long">
+        SELECT COUNT(*)
+        FROM fs_course_traffic_log
+        <where>
+            <if test="startTime != null and endTime != null">
+                and create_time &gt;= #{startTime}
+                and create_time &lt;= #{endTime}
+            </if>
+            <if test="companyId != null">
+                AND company_id = #{companyId}
+            </if>
+        </where>
+    </select>
 
 </mapper>

+ 13 - 0
fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserController.java

@@ -174,4 +174,17 @@ public class CourseFsUserController extends AppBaseController {
         logger.error("zyp \n【h5看课中途报错】:{}",msg);
     }
 
+    @ApiOperation("获取我的sop课程-短信链接")
+    @PostMapping("/getSopCourseH5StudyListByMsg")
+    public R getSopCourseH5StudyListByMsg(@RequestBody FsCourseH5ListParam param ){
+        return  courseLinkService.getSopCourseH5StudyListByMsg(param);
+    }
+
+    @ApiOperation("获取我的sop课程详情")
+    @PostMapping("/getSopCourseH5StudyInfo")
+    public R getSopCourseH5StudyInfo(@RequestBody FsCourseH5ListParam  param ){
+        // 查询看课记录
+        return courseLinkService.getLinkInfo(param.getLogId());
+    }
+
 }

+ 5 - 3
fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

@@ -120,9 +120,10 @@ public class IndexScrmController extends AppBaseController {
 	@ApiOperation("首页商品列表")
 	@GetMapping("/home/goods")
 	public R homeGoods(@RequestParam(value = "id", required = false) Long id,
+					   @RequestParam(value = "keyword", required = false) String keyword,
 					   @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
 					   @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
-		java.util.Map<String, Object> data = userEndCategoryScrmService.listProductsForApp(id, pageNum, pageSize);
+		java.util.Map<String, Object> data = userEndCategoryScrmService.listProductsForApp(id, keyword, pageNum, pageSize);
 		return R.ok().put("data", data);
 	}
 
@@ -133,6 +134,7 @@ public class IndexScrmController extends AppBaseController {
 	@GetMapping("/home/goods/recommend")
 	public R homeGoodsRecommend(HttpServletRequest request,
 								@RequestParam(value = "type") String type,
+								@RequestParam(value = "keyword", required = false) String keyword,
 								@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
 								@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
 		String appId = request.getParameter("appId");
@@ -140,8 +142,8 @@ public class IndexScrmController extends AppBaseController {
 			return R.ok().put("data", new PageInfo<>(Collections.emptyList()));
 		}
 		List<FsStoreProductListQueryVO> list = "green".equalsIgnoreCase(type)
-				? productService.selectFsStoreProductNewQueryPage(pageNum, pageSize, appId)
-				: productService.selectFsStoreProductHotQueryPage(pageNum, pageSize, appId);
+				? productService.selectFsStoreProductNewQueryPage(pageNum, pageSize, appId, keyword)
+				: productService.selectFsStoreProductHotQueryPage(pageNum, pageSize, appId, keyword);
 		PageInfo<FsStoreProductListQueryVO> pageInfo = new PageInfo<>(list);
 		return R.ok().put("data", pageInfo);
 	}