فهرست منبع

Merge remote-tracking branch 'origin/master'

xgb 3 روز پیش
والد
کامیت
c1a459e8d5
44فایلهای تغییر یافته به همراه1145 افزوده شده و 238 حذف شده
  1. 27 0
      fs-admin/src/main/java/com/fs/company/controller/CompanyStatisticsController.java
  2. 3 6
      fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java
  3. 153 161
      fs-admin/src/main/java/com/fs/his/task/Task.java
  4. 1 1
      fs-admin/src/main/resources/application.yml
  5. 2 1
      fs-company/src/main/resources/application.yml
  6. 2 1
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  7. 16 5
      fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java
  8. 11 0
      fs-qw-task/src/main/java/com/fs/app/task/qwTask.java
  9. 10 0
      fs-qw-task/src/main/java/com/fs/app/taskService/SyncQwExternalContactService.java
  10. 10 3
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  11. 78 0
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SyncQwExternalContactServiceImpl.java
  12. 1 1
      fs-repeat-api/src/main/java/com/fs/app/mq/RocketMQConsumerService.java
  13. 23 5
      fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  14. 4 1
      fs-service/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java
  15. 6 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  16. 3 0
      fs-service/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java
  17. 5 6
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java
  18. 0 2
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseTrafficLogServiceImpl.java
  19. 97 5
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  20. 86 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  21. 14 3
      fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogListVO.java
  22. 6 3
      fs-service/src/main/java/com/fs/his/dto/FsStoreOrderAmountScrmStatsQueryDto.java
  23. 6 3
      fs-service/src/main/java/com/fs/his/dto/FsStoreOrderAmountStatsQueryDto.java
  24. 7 6
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  25. 4 0
      fs-service/src/main/java/com/fs/qw/domain/QwContactWay.java
  26. 13 1
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  27. 2 0
      fs-service/src/main/java/com/fs/qw/param/QwWatchLogStatisticsListParam.java
  28. 3 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwContactWayServiceImpl.java
  29. 3 2
      fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  30. 4 1
      fs-service/src/main/java/com/fs/qw/service/impl/QwWatchLogServiceImpl.java
  31. 10 0
      fs-service/src/main/java/com/fs/qw/vo/QwExternalContactVO.java
  32. 8 6
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  33. 1 0
      fs-service/src/main/java/com/fs/sop/vo/SopUserLogsVo.java
  34. 1 1
      fs-service/src/main/java/com/fs/statis/mapper/FsStatisSalerWatchMapper.java
  35. 94 0
      fs-service/src/main/resources/application-config-dev-jnlzjk.yml
  36. 3 3
      fs-service/src/main/resources/application-config-druid-jnlzjk.yml
  37. 94 0
      fs-service/src/main/resources/application-config-druid-jnsyj.yml
  38. 153 0
      fs-service/src/main/resources/application-dev-jnlzjk.yml
  39. 162 0
      fs-service/src/main/resources/application-druid-jnsyj.yml
  40. 3 1
      fs-service/src/main/resources/application-druid-sxjz.yml
  41. 8 5
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  42. 5 2
      fs-service/src/main/resources/mapper/qw/QwContactWayMapper.xml
  43. 2 2
      fs-service/src/main/resources/mapper/qw/QwWatchLogMapper.xml
  44. 1 1
      fs-user-app/src/main/resources/application.yml

+ 27 - 0
fs-admin/src/main/java/com/fs/company/controller/CompanyStatisticsController.java

@@ -19,9 +19,14 @@ import com.fs.crm.service.ICrmCustomerService;
 import com.fs.crm.service.ICrmCustomerVisitService;
 import com.fs.crm.vo.CrmCustomerStatisticsVO;
 import com.fs.crm.vo.CrmCustomerVisitStatisticsVO;
+import com.fs.his.dto.FsStoreOrderAmountScrmStatsQueryDto;
+import com.fs.his.dto.FsStoreOrderAmountStatsQueryDto;
 import com.fs.his.service.IFsStoreAfterSalesService;
 import com.fs.his.service.IFsStoreOrderService;
 import com.fs.his.service.IFsStorePaymentService;
+import com.fs.his.vo.FsStoreOrderAmountScrmStatsVo;
+import com.fs.his.vo.FsStoreOrderAmountStatsVo;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -67,6 +72,10 @@ public class CompanyStatisticsController extends BaseController
     private ICrmCustomerService crmCustomerService;
     @Autowired
     private ICrmCustomerVisitService crmCustomerVisitService;
+
+    //app商城订单接口Service
+    @Autowired
+    private IFsStoreOrderScrmService fsStoreOrderScrmService;
     @GetMapping("/storeOrder")
     public R storeOrder(FsStoreStatisticsParam param)
     {
@@ -724,4 +733,22 @@ public class CompanyStatisticsController extends BaseController
         return util.exportExcel(qwIpadTotalVos, "visit");
     }
 
+    /**
+     * 获取互联网医院订单统计数据
+     * */
+    @GetMapping("/hisOrderCountStats")
+    public AjaxResult getHisOrderCount(FsStoreOrderAmountStatsQueryDto statsQueryDto){
+        FsStoreOrderAmountStatsVo fsStoreOrderAmountStatsVo = storeOrderService.selectFsStoreOrderAmountStats(statsQueryDto);
+        return AjaxResult.success(fsStoreOrderAmountStatsVo);
+    }
+
+    /**
+     * 获取App商城订单统计数据
+     * */
+    @GetMapping("/appOrderCountStats")
+    public AjaxResult getAppOrderCount(FsStoreOrderAmountScrmStatsQueryDto statsQueryDto){
+        FsStoreOrderAmountScrmStatsVo scrmStatsVo = fsStoreOrderScrmService.selectFsStoreOrderAmountScrmStats(statsQueryDto);
+        return AjaxResult.success(scrmStatsVo);
+    }
+
 }

+ 3 - 6
fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java

@@ -103,13 +103,10 @@ public class FsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
             throw new CustomException("必须选择开始时间和结束时间!");
         }
+        startPage();
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVONew(param);
-        TableDataInfo rspData = new TableDataInfo();
-        rspData.setCode(HttpStatus.SUCCESS);
-        rspData.setMsg("查询成功");
-        rspData.setRows(list);
-        rspData.setTotal(fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVONewCount(param));
-        return rspData;
+
+        return getDataTable(list);
     }
 
     /**

+ 153 - 161
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -67,6 +67,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
@@ -92,7 +94,7 @@ public class Task {
     private IFsFollowService fsFollowService;
     @Autowired
     private IFsStoreAfterSalesService fsStoreAfterSalesService;
-//    @Autowired
+    //    @Autowired
 //    IErpOrderService erpOrderService;
     @Autowired
     FsIntegralOrderMapper integralOrderMapper;
@@ -133,7 +135,7 @@ public class Task {
     FsPackageOrderServiceImpl packageOrderService;
     @Autowired
     private IFsStoreOrderLogsService fsStoreOrderLogsService;
-    org.slf4j.Logger logger= LoggerFactory.getLogger(getClass());
+    org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
     IFsDoctorService doctorService;
     @Autowired
@@ -185,15 +187,15 @@ public class Task {
     public void ConsumerSopTempVoice() {
         try {
             Long newCompanyUserId = redisCache.popVoiceKey(SOP_TEMP_VOICE_KEY);
-            if(newCompanyUserId != null){
-                List<QwSopTempVoice> sopTempVoices = redisCache.getVoiceAllList(SOP_TEMP_VOICE_KEY + ":" +newCompanyUserId);
-                if(sopTempVoices != null && !sopTempVoices.isEmpty()) {
+            if (newCompanyUserId != null) {
+                List<QwSopTempVoice> sopTempVoices = redisCache.getVoiceAllList(SOP_TEMP_VOICE_KEY + ":" + newCompanyUserId);
+                if (sopTempVoices != null && !sopTempVoices.isEmpty()) {
                     try {
                         for (QwSopTempVoice qwSopTempVoice : sopTempVoices) {
                             try {
                                 AudioVO audioVO = new AudioVO();
                                 List<FastgptChatVoiceHomo> homos = fastgptChatVoiceHomoMapper.selectFastgptChatVoiceHomoList(new FastgptChatVoiceHomo());
-                                audioVO = AudioUtils.createUserUrlAndUrl(homos,qwSopTempVoice.getCompanyUserId(), qwSopTempVoice.getVoiceTxt());
+                                audioVO = AudioUtils.createUserUrlAndUrl(homos, qwSopTempVoice.getCompanyUserId(), qwSopTempVoice.getVoiceTxt());
                                 if (audioVO != null && audioVO.getWavUrl() != null && audioVO.getUrl() != null) {
                                     qwSopTempVoice.setVoiceUrl(audioVO.getUrl());
                                     qwSopTempVoice.setUserVoiceUrl(audioVO.getWavUrl());
@@ -209,7 +211,7 @@ public class Task {
                         redisCache.deleteObject(SOP_TEMP_VOICE_KEY + ":" + newCompanyUserId);
                     }
                 }
-            }else{
+            } else {
                 log.info("没有需要生成的语音");
             }
         } catch (Exception e) {
@@ -281,7 +283,7 @@ public class Task {
                         FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
                         eventLogTotal.setId(info.getId());
                         eventLogTotal.setCount(newCount);
-                        if(!processedKeys.contains(uniqueKey)) {
+                        if (!processedKeys.contains(uniqueKey)) {
                             toUpdateList.add(eventLogTotal);
                             // 标记为已处理
                             processedKeys.add(uniqueKey);
@@ -289,7 +291,7 @@ public class Task {
                     }
                 } else {
                     total.setStatTime(dateTime);
-                    if(!processedKeys.contains(uniqueKey)) {
+                    if (!processedKeys.contains(uniqueKey)) {
                         toInsertList.add(total);
                         // 标记为已处理
                         processedKeys.add(uniqueKey);
@@ -392,7 +394,7 @@ public class Task {
                         FastgptEventLogTotal eventLogTotalNew = new FastgptEventLogTotal();
                         eventLogTotalNew.setId(info.getId());
                         eventLogTotalNew.setCount(totalCount);
-                        if(!processedKeys.contains(uniqueKey)){
+                        if (!processedKeys.contains(uniqueKey)) {
                             toUpdateList.add(eventLogTotalNew);
                             // 标记为已处理
                             processedKeys.add(uniqueKey);
@@ -409,7 +411,7 @@ public class Task {
                     eventLogTotal.setQwUserId(tokenLog.getQwUserId());
                     eventLogTotal.setStatTime(dateTime);
 
-                    if(!processedKeys.contains(uniqueKey)) {
+                    if (!processedKeys.contains(uniqueKey)) {
                         toInsertList.add(eventLogTotal);
                         // 标记为已处理
                         processedKeys.add(uniqueKey);
@@ -435,23 +437,23 @@ public class Task {
 
 
     //定时查询ipad主机使用情况,建议每天凌晨1点执行一次
-    public void totalIpadTask(){
+    public void totalIpadTask() {
         String dateTime = DateUtils.addDateDays(-1); // 昨天
         List<QwIpadTotalVo> qwIpadTotalVos = userService.selectCompanyByIpadStatusCount();
-        if(qwIpadTotalVos != null && !qwIpadTotalVos.isEmpty()){
+        if (qwIpadTotalVos != null && !qwIpadTotalVos.isEmpty()) {
             qwIpadTotalVos.forEach(qwIpadTotalVo ->
                     qwIpadTotalVo.setStatTime(dateTime)
             );
             int a = userService.insertQwIpadTotal(qwIpadTotalVos);
-            if(a == 0){
+            if (a == 0) {
                 log.error("插入ipad主机失败");
             }
-        }else{
+        } else {
             log.error("查询没有数据");
         }
     }
 
-    public void addQwUserName(){
+    public void addQwUserName() {
         QwCompany qwCompany = new QwCompany();
         List<QwCompany> companyList = qwCompanyService.selectQwCompanyList(qwCompany);
         for (QwCompany company : companyList) {
@@ -459,50 +461,56 @@ public class Task {
         }
     }
 
-    public void videoTranscode() throws Exception
-    {
+    public void videoTranscode() throws Exception {
 
         tencentCloudCosService.videoTranscode();
     }
 
-    public void updateUrl() throws Exception
-    {
+    public void updateUrl() throws Exception {
 
         tencentCloudCosService.updateUrl();
     }
-    public void addPrescribeImg() throws Exception
-    {
-       List<Long> ids= fsPrescribeService.selectFsPrescribeByPrescribeIdByOrderType();
+
+    public void addPrescribeImg() throws Exception {
+        List<Long> ids = fsPrescribeService.selectFsPrescribeByPrescribeIdByOrderType();
         for (Long id : ids) {
             System.out.println(id);
             fsPrescribeService.PrescribeStoreImg(id);
         }
     }
 
-    public void addQwWatchLog() throws Exception
-    {
+    public void addQwWatchLog() throws Exception {
+        LocalDateTime now = LocalDateTime.now().withSecond(0);
         fsCourseWatchLogService.addCourseWatchLogDay();
     }
 
 
-    public void transferLog() throws Exception
-    {
+    public void addQwWatchLogMinute(Integer minute) throws Exception{
+        log.info("定时更新看课111");
+        if(minute == null) minute = 30;
+        LocalDateTime now = LocalDateTime.now().withSecond(0);
+        LocalDateTime start = now.minusMinutes(minute);
+        LocalDateTime end = now.minusSeconds(1);
+        fsCourseWatchLogService.addCourseWatchLogDayMinute(start, end);
+    }
+
+    public void transferLog() throws Exception {
         qwExternalContactTransferLogService.updateQwExternalContactTransferLogByStatus();
 
 
     }
 
-    public void isArtificial() throws Exception
-    {
+    public void isArtificial() throws Exception {
         fastGptChatSessionMapper.updateFastGptChatSessionByIsReply();
 
     }
-    public void expirationQwAppCountWay(){
+
+    public void expirationQwAppCountWay() {
         qwAppContactWayService.expirationQwAppCountWay();
 
     }
-    public void sendOrderMsg() throws Exception
-    {
+
+    public void sendOrderMsg() throws Exception {
         List<FsStoreOrder> fsStoreOrders = fsStoreOrderMapper.selectStoreOrderIdByFollow();
         for (FsStoreOrder fsStoreOrder : fsStoreOrders) {
 
@@ -510,81 +518,77 @@ public class Task {
         }
 
     }
-    public void redPacketSubMoney() throws Exception
-    {
+
+    public void redPacketSubMoney() throws Exception {
         List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
         for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
+            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
         }
     }
 
 
-    public void redPacketAddMoney() throws Exception
-    {
+    public void redPacketAddMoney() throws Exception {
         List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
         for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
+            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
         }
     }
 
-    public void updateCompanyUserStatus()
-    {
+    public void updateCompanyUserStatus() {
         CompanyUser user = new CompanyUser();
         user.setStatus("0");
         user.setDelFlag("0");
         List<CompanyUser> companyUsers = companyUserMapper.selectCompanyUserList(user);
         for (CompanyUser companyUser : companyUsers) {
-            if(SecurityUtils.matchesPassword("123456", companyUser.getPassword())){
+            if (SecurityUtils.matchesPassword("123456", companyUser.getPassword())) {
                 companyUser.setStatus("1");
                 companyUserMapper.updateCompanyUser(companyUser);
-                logger.info("密码为123456 停用账号:"+companyUser.getUserId()+":"+companyUser.getNickName());
+                logger.info("密码为123456 停用账号:" + companyUser.getUserId() + ":" + companyUser.getNickName());
             }
         }
     }
-    public void couponStatus()
-    {
+
+    public void couponStatus() {
         fsUserCouponMapper.updateFsUserCouponStatusByLimtTime();
     }
 
     //每10秒执行一次
-    public void auditPrescribe()
-    {
+    public void auditPrescribe() {
         SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.inquiryConfig");
         String configValue = sysConfig.getConfigValue();
         Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
-        boolean isAudit = (boolean)config.get("isAutoPrescribeAudit");
-        if (isAudit){
+        boolean isAudit = (boolean) config.get("isAutoPrescribeAudit");
+        if (isAudit) {
             fsPrescribeService.auditPrescribe();
         }
     }
 
-    public void deliveryOp()
-    {
+    public void deliveryOp() {
         IErpOrderService erpOrderService = getErpService();
         List<FsStoreOrder> orders = null;
-        if (erpOrderService == gyOrderService){
+        if (erpOrderService == gyOrderService) {
             orders = fsStoreOrderMapper.selectOmsOrderdeliveryOp();
-        } else if (erpOrderService == wdtOrderService || erpOrderService == dfOrderService || erpOrderService == jSTOrderService){
+        } else if (erpOrderService == wdtOrderService || erpOrderService == dfOrderService || erpOrderService == jSTOrderService) {
             orders = fsStoreOrderMapper.selectWdtOmsOrderdeliveryOp();
         }
 
 
-        for(FsStoreOrder order:orders){
+        for (FsStoreOrder order : orders) {
 
-            ErpOrderQueryRequert request=new ErpOrderQueryRequert();
+            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
 
             request.setCode(order.getExtendOrderId());
-            if (erpOrderService != null){
-                ErpOrderQueryResponse response=erpOrderService.getOrder(request);
-                if (erpOrderService != dfOrderService){
-                    if(response.getOrders()!=null&&response.getOrders().size()>0){
-                        for(ErpOrderQuery orderQuery : response.getOrders()){
-                            if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
-                                for(ErpDeliverys delivery:orderQuery.getDeliverys()){
-                                    if(delivery.getDelivery()&& StringUtils.isNotEmpty(delivery.getMail_no())){
+            if (erpOrderService != null) {
+                ErpOrderQueryResponse response = erpOrderService.getOrder(request);
+                if (erpOrderService != dfOrderService) {
+                    if (response.getOrders() != null && response.getOrders().size() > 0) {
+                        for (ErpOrderQuery orderQuery : response.getOrders()) {
+                            if (orderQuery.getDeliverys() != null && orderQuery.getDeliverys().size() > 0) {
+                                for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
+                                    if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
                                         //更新商订单状态 删除REDIS
-                                        fsStoreOrderService.deliveryOrder(order.getOrderCode(),delivery.getMail_no(),delivery.getExpress_code(),delivery.getExpress_name());
-                                        redisCache.deleteObject("delivery"+":"+order.getExtendOrderId());
+                                        fsStoreOrderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
+                                        redisCache.deleteObject("delivery" + ":" + order.getExtendOrderId());
                                     }
                                 }
 
@@ -597,19 +601,17 @@ public class Task {
         }
 
 
-
     }
 
 
-    public void getOrderDeliveryStatus()
-    {
+    public void getOrderDeliveryStatus() {
         IErpOrderService erpOrderService = getErpService();
         List<FsStoreOrder> orders = null;
-        if (erpOrderService !=null && erpOrderService == dfOrderService){
+        if (erpOrderService != null && erpOrderService == dfOrderService) {
             orders = fsStoreOrderMapper.selectShippedOrder();
-            if(orders!=null&& !orders.isEmpty()){
+            if (orders != null && !orders.isEmpty()) {
                 List<CompletableFuture<Void>> futures = new ArrayList<>();
-                for(FsStoreOrder order:orders){
+                for (FsStoreOrder order : orders) {
                     CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                         erpOrderService.getOrderDeliveryStatus(order);
                     });
@@ -620,15 +622,14 @@ public class Task {
         }
     }
 
-    public void CreateOmsAndHis()
-    {
+    public void CreateOmsAndHis() {
         List<Long> omsList = fsStoreOrderMapper.selectFsStoreOrderNoCreateOms();
-        logger.info("推送订单id====>{}",omsList);
+        logger.info("推送订单id====>{}", omsList);
         for (Long l : omsList) {
             try {
                 fsStoreOrderService.createOmsOrder(l);
             } catch (Exception e) {
-                logger.error("推送订单异常:",e);
+                logger.error("推送订单异常:", e);
             }
         }
 //        List<Long> tuiOrderList = fsStoreOrderMapper.selectFsStoreOrderNoTuiOrder();
@@ -641,31 +642,30 @@ public class Task {
 //        }
     }
 
-    public void createFollow()
-    {
+    public void createFollow() {
         List<FsStoreOrder> orders = fsStoreOrderMapper.selectStoreOrderIdByFollow();
         for (FsStoreOrder order : orders) {
             try {
 
                 fsStoreOrderService.addFsFollowByStoreOrder(order);
-            }catch (Exception e){
-                logger.info("创建随访错误:"+order);
+            } catch (Exception e) {
+                logger.info("创建随访错误:" + order);
             }
         }
     }
+
     @Autowired
     IFsStoreSubOrderService fsStoreSubOrderService;
 
 
-    public void puSubStoreOrder()
-    {
+    public void puSubStoreOrder() {
         List<Long> longs = fsStoreSubOrderService.selectFsStoreSubOrderByNoPush();
-        int i=0;
+        int i = 0;
         for (Long aLong : longs) {
             FsSubOrderResultVO fsSubOrderResultVO = fsStoreSubOrderService.TuiFsStoreSubOrderByStoreOrder(aLong);
-            if (fsSubOrderResultVO!=null&&fsSubOrderResultVO.getCode()!=null&&fsSubOrderResultVO.getCode()==1){
+            if (fsSubOrderResultVO != null && fsSubOrderResultVO.getCode() != null && fsSubOrderResultVO.getCode() == 1) {
                 i++;
-                if (i>65){
+                if (i > 65) {
                     return;
                 }
             }
@@ -673,14 +673,13 @@ public class Task {
         }
     }
 
-    public void refundOp()
-    {
-        List<FsStoreAfterSales> list=fsStoreAfterSalesService.selectFsStoreAfterSalesByDoAudit();
-        if(list!=null){
-            for(FsStoreAfterSales afterSales:list){
+    public void refundOp() {
+        List<FsStoreAfterSales> list = fsStoreAfterSalesService.selectFsStoreAfterSalesByDoAudit();
+        if (list != null) {
+            for (FsStoreAfterSales afterSales : list) {
                 try {
                     fsStoreAfterSalesService.auditing(afterSales);
-                }catch (Exception e){
+                } catch (Exception e) {
 
                 }
 
@@ -688,16 +687,17 @@ public class Task {
         }
 
     }
+
     public void isAfterSales() {
         SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
         String configValue = sysConfig.getConfigValue();
         Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
-        Integer storeAfterSalesDay = (Integer)config.get("storeAfterSalesDay");
+        Integer storeAfterSalesDay = (Integer) config.get("storeAfterSalesDay");
         List<FsStoreOrder> fsStoreOrders = fsStoreOrderMapper.selectFsStoreOrderNoIsAfterSales(storeAfterSalesDay);
         for (FsStoreOrder fsStoreOrder : fsStoreOrders) {
             try {
                 fsStoreOrderService.addIntegralAndShareByStoreOrder(fsStoreOrder);
-            }catch (Exception e) {
+            } catch (Exception e) {
                 logger.info("分账错误: " + fsStoreOrder.getOrderCode());
             }
         }
@@ -705,42 +705,41 @@ public class Task {
     }
 
 
-    public void integralOrderStatus(){
+    public void integralOrderStatus() {
         integralOrderMapper.updatePackageOrderStatusByDeliveryTime();
     }
 
-    public void packageStatus()
-    {
+    public void packageStatus() {
         fsPackageOrderMapper.updatePackageOrderStatusByFinishTime();
         SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
         String configValue = sysConfig.getConfigValue();
         Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
-        Integer unPayTime = (Integer)config.get("unPayTime");
+        Integer unPayTime = (Integer) config.get("unPayTime");
         fsPackageOrderMapper.updatePackageOrderStatusByStatus(unPayTime);
     }
 
-    public void endFollow(){
+    public void endFollow() {
         fsStoreOrderService.endFollow();
     }
 
 
-    public void erDelivery(){
+    public void erDelivery() {
         fsStoreOrderService.endDeliveryOrder();
     }
 
 
-
     @Autowired
     private ICompanyService companyService;
-    public void addCompanyMoney(){
+
+    public void addCompanyMoney() {
         List<FsStoreOrder> orders = fsStoreOrderMapper.selectOrderIds();
-        for (FsStoreOrder order : orders){
+        for (FsStoreOrder order : orders) {
             CompanyMoneyLogs moneyLog1 = moneyLogsMapper.selectCompanyMoneyLogsByOrderId(order.getOrderId(), 5);
-            CompanyMoneyLogs moneyLog2 = moneyLogsMapper.selectCompanyMoneyLogsByOrderId(order.getOrderId(),3);
-            if (moneyLog1==null){
+            CompanyMoneyLogs moneyLog2 = moneyLogsMapper.selectCompanyMoneyLogsByOrderId(order.getOrderId(), 3);
+            if (moneyLog1 == null) {
                 companyService.subtractCompanyMoney(order);
             }
-            if (moneyLog2==null){
+            if (moneyLog2 == null) {
                 companyService.addCompanyMoney(order);
                 FsStoreOrder orderMap = new FsStoreOrder();
                 orderMap.setOrderId(order.getOrderId());
@@ -751,28 +750,26 @@ public class Task {
     }
 
     //每天执行一次
-    public void syncExpress()
-    {
-        List<Long> ids =fsStoreOrderMapper.selectSyncExpressIds();
+    public void syncExpress() {
+        List<Long> ids = fsStoreOrderMapper.selectSyncExpressIds();
         for (Long id : ids) {
             fsStoreOrderService.syncExpress(id);
         }
 
     }
 
-    public void refundCompanyMoney(){
+    public void refundCompanyMoney() {
         List<FsStoreOrder> list = fsStoreOrderMapper.selectOrders();
-        for (FsStoreOrder order : list ){
+        for (FsStoreOrder order : list) {
             companyService.refundCompanyMoney(order);
         }
     }
 
-    public void subIntegral()
-    {
+    public void subIntegral() {
         fsUserIntegralLogsService.subFsUserIntegralLogsByOrder5();
     }
 
-    public void finishInquiry(){
+    public void finishInquiry() {
         List<FsInquiryOrder> orders = inquiryOrderMapper.selectFsInquiryOrderByFinish();
         for (FsInquiryOrder order : orders) {
             // 订单已超过48小时,执行关闭操作
@@ -781,20 +778,20 @@ public class Task {
             param.setDoctorId(order.getDoctorId());
             try {
                 iFsInquiryOrderService.autoFinishOrder(param);
-            }catch (Exception e){
-                logger.info("订单已超过48小时关闭异常"+param);
+            } catch (Exception e) {
+                logger.info("订单已超过48小时关闭异常" + param);
             }
 
         }
     }
 
 
-    public void finishStoreOrderByXN(){
+    public void finishStoreOrderByXN() {
         List<FsStoreOrder> orders = fsStoreOrderMapper.selectFinishStoreOrderByXN();
-        if (orders!=null&&orders.size()>0){
+        if (orders != null && orders.size() > 0) {
             for (FsStoreOrder o : orders) {
                 FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(o.getOrderId());
-                if (order.getStatus()!= 2) {
+                if (order.getStatus() != 2) {
                     continue;
                 }
                 FsStoreOrder o1 = new FsStoreOrder();
@@ -805,20 +802,20 @@ public class Task {
                 int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
                 fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.FINISH_ORDER.getValue(),
                         FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
-                if (order.getCompanyId()!=null&&order.getTuiMoneyStatus()==0&&order.getPayType()==1){
+                if (order.getCompanyId() != null && order.getTuiMoneyStatus() == 0 && order.getPayType() == 1) {
                     companyService.addCompanyMoney(order);
                 }
             }
         }
     }
 
-    public void inquirySendSms(){
+    public void inquirySendSms() {
         List<FsInquiryOrder> orders = inquiryOrderMapper.selectFsInquiryOrderBySendSms();
-        for (FsInquiryOrder order : orders){
-            FsInquiryOrderPatientDTO patientDTO = JSON.parseObject(order.getPatientJson(),FsInquiryOrderPatientDTO.class);
-            if (patientDTO!=null&&patientDTO.getPatientName()!=null){
+        for (FsInquiryOrder order : orders) {
+            FsInquiryOrderPatientDTO patientDTO = JSON.parseObject(order.getPatientJson(), FsInquiryOrderPatientDTO.class);
+            if (patientDTO != null && patientDTO.getPatientName() != null) {
                 FsUser fsUser = fsUserMapper.selectFsUserByUserId(order.getUserId());
-                if (fsUser!=null&&fsUser.getPhone()!=null){
+                if (fsUser != null && fsUser.getPhone() != null) {
                     smsService.sendUserSms(fsUser.getPhone(), patientDTO.getPatientName(), "2");
                     order.setIsSendSms(1);
                     inquiryOrderMapper.updateFsInquiryOrder(order);
@@ -829,9 +826,9 @@ public class Task {
     }
 
     //处理30天问题件
-    public void clearProblemOrder(){
+    public void clearProblemOrder() {
         List<FsStoreOrder> orders = fsStoreOrderMapper.selectFsStoreOrderByProblemOrder();
-        for (FsStoreOrder order : orders){
+        for (FsStoreOrder order : orders) {
             FsStoreOrder map = new FsStoreOrder();
             map.setStatus(4);
             map.setOrderId(order.getOrderId());
@@ -842,14 +839,14 @@ public class Task {
 
 
     //30天无通话记录回收坐席
-    public void recoverCompanyCaller(){
+    public void recoverCompanyCaller() {
         SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
         StoreConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), StoreConfig.class);
         Integer days = fsPayConfig.getStoreCall();
         List<CompanyVoiceCaller> list = companyVoiceCallerMapper.selectCompanyVoiceCallerByRecover(days);
-        for (CompanyVoiceCaller caller : list){
-            Long count = companyVoiceLogsMapper.selectCompanyVoiceLogsCountByCallerNo(caller.getCallerNo(),caller.getBindTime());
-            if (count==0){
+        for (CompanyVoiceCaller caller : list) {
+            Long count = companyVoiceLogsMapper.selectCompanyVoiceLogsCountByCallerNo(caller.getCallerNo(), caller.getBindTime());
+            if (count == 0) {
                 caller.setCompanyId(0l);
                 caller.setCompanyUserId(0l);
                 caller.setMobile("");
@@ -862,32 +859,27 @@ public class Task {
 
 
     public void tb() {
-        packageOrderService.payConfirm("", "1780763211956486144", "1075999515888117190", "14", 1,null,null);
+        packageOrderService.payConfirm("", "1780763211956486144", "1075999515888117190", "14", 1, null, null);
     }
 
 
-
-
-
-
-
-    public void addSend(){
-       String userId="4048905872";
-       String doctorId="147";
-        String storeOrderId="470920";
-        String followId="1062986";
+    public void addSend() {
+        String userId = "4048905872";
+        String doctorId = "147";
+        String storeOrderId = "470920";
+        String followId = "1062986";
         //发送给用户
-        MsgDTO msgDTO=new MsgDTO();
-        MsgCustomDTO customDTO=new MsgCustomDTO();
+        MsgDTO msgDTO = new MsgDTO();
+        MsgCustomDTO customDTO = new MsgCustomDTO();
         customDTO.setType("startDrugReport");
         customDTO.setImType(2);
         customDTO.setOrderId(storeOrderId);
         customDTO.setFollowId(followId);
         msgDTO.setCloudCustomData(JSONUtil.toJsonStr(customDTO));
-        msgDTO.setFrom_Account("U-"+userId);
-        msgDTO.setTo_Account("D-"+doctorId);
-        List<MsgDataDTO> msgs=new ArrayList<>();
-        MsgDataDTO msg=new MsgDataDTO();
+        msgDTO.setFrom_Account("U-" + userId);
+        msgDTO.setTo_Account("D-" + doctorId);
+        List<MsgDataDTO> msgs = new ArrayList<>();
+        MsgDataDTO msg = new MsgDataDTO();
         msg.setMsgType("TIMTextElem");
         msg.setMsgContent(new MsgDataFormatDTO("您好"));
         msgs.add(msg);
@@ -1166,7 +1158,7 @@ public class Task {
 //                iFsPackageOrderService.updateFsPackageOrder(order);
 //                num++;
 //            }
-////
+    /// /
 //        }
 //
 //        logger.info("所有订单同步完成:"+num);
@@ -1242,7 +1234,7 @@ public class Task {
 //}
 
 
-        //同步流水
+    //同步流水
 //    public void task(){
 //        CompanyMoneyLogs item = moneyLogsMapper.selectCompanyMoneyLogsById(248884L);
 //        String logsId=item.getLogsId().toString();
@@ -1345,27 +1337,27 @@ public class Task {
     private IErpOrderService getErpService() {
         FsSysConfig sysConfig = configUtil.getSysConfig();
         Integer erpOpen = sysConfig.getErpOpen();
-        if (erpOpen != null && erpOpen == 1){
+        if (erpOpen != null && erpOpen == 1) {
             //判断erp类型
             Integer erpType = sysConfig.getErpType();
-            if (erpType != null){
+            if (erpType != null) {
                 IErpOrderService erpOrderService = null;
-                if (erpType == 1){
+                if (erpType == 1) {
                     //管易
-                    erpOrderService =  gyOrderService;
-                } else if (erpType == 2){
+                    erpOrderService = gyOrderService;
+                } else if (erpType == 2) {
                     //旺店通
-                    erpOrderService =  wdtOrderService;
-                } else if (erpType == 3){
+                    erpOrderService = wdtOrderService;
+                } else if (erpType == 3) {
                     //
-                    erpOrderService =  hzOMSErpOrderService;
-                } else if (erpType == 4){
+                    erpOrderService = hzOMSErpOrderService;
+                } else if (erpType == 4) {
                     //代服
-                    erpOrderService =  dfOrderService;
-                }else if(erpType == 5){
-                    erpOrderService=jSTOrderService;
-                }else if(erpType == 6){
-                    erpOrderService=k9OrderService;
+                    erpOrderService = dfOrderService;
+                } else if (erpType == 5) {
+                    erpOrderService = jSTOrderService;
+                } else if (erpType == 6) {
+                    erpOrderService = k9OrderService;
                 }
                 return erpOrderService;
 

+ 1 - 1
fs-admin/src/main/resources/application.yml

@@ -4,7 +4,7 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: druid-jnmy-test
+    active: dev
 #    active: druid-hdt
 #    active: druid-yzt
 #    active: druid-sxjz

+ 2 - 1
fs-company/src/main/resources/application.yml

@@ -4,11 +4,12 @@ server:
 spring:
   profiles:
 #    active: druid-fcky-test
-    active: druid-jnmy-test
+#    active: druid-jnmy-test
 #    active: druid-jzzx-test
 #    active: druid-hdt
 #    active: druid-sxjz
 #    active: druid-yzt
 #    active: druid-myhk
 #    active: druid-sft
+    active: dev-jnlzjk
 #    active: dev-yjb

+ 2 - 1
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -308,7 +308,7 @@ public class QwMsgController {
                 if (wxWorkMessageDTO.getReferid()!=0){
                     break;
                 }
-                if (wxWorkMessageDTO.getMsgtype()==2||wxWorkMessageDTO.getMsgtype()==0||wxWorkMessageDTO.getMsgtype()==16||wxWorkMessageDTO.getMsgtype() == 101||wxWorkMessageDTO.getMsgtype() == 104){
+                if (wxWorkMessageDTO.getMsgtype()==2||wxWorkMessageDTO.getMsgtype()==0||wxWorkMessageDTO.getMsgtype()==16||wxWorkMessageDTO.getMsgtype() == 101||wxWorkMessageDTO.getMsgtype() == 104||wxWorkMessageDTO.getMsgtype()==141){
 
                     String content = wxWorkMessageDTO.getContent();
                     log.info("id:{}, 接收人:"+wxWorkMessageDTO.getReceiver(), id);
@@ -354,6 +354,7 @@ public class QwMsgController {
                             if(qwUserVideo == null){
                                 QwUserVideo userVideo=new QwUserVideo();
                                 userVideo.setSenderName(wxWorkMessageDTO.getSender_name());
+                                userVideo.setAppKey(qwUserByAppKey.getAppKey());
                                 userVideo.setNickName(wxWorkMessageDTO.getNickname());
                                 userVideo.setObjectId(wxWorkMessageDTO.getObjectId());
                                 userVideo.setCoverUrl(wxWorkMessageDTO.getCover_url());

+ 16 - 5
fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -2,12 +2,11 @@ package com.fs.app.controller;
 
 
 import cn.hutool.core.date.DateUtil;
-import com.fs.app.taskService.QwExternalContactRatingService;
-import com.fs.app.taskService.SopLogsChatTaskService;
-import com.fs.app.taskService.SopLogsTaskService;
-import com.fs.app.taskService.SopWxLogsService;
+import com.fs.app.taskService.*;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.StringUtils;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
@@ -18,10 +17,12 @@ import com.fs.his.domain.FsUser;
 import com.fs.his.service.IFsInquiryOrderService;
 import com.fs.his.utils.qrcode.QRCodeUtils;
 import com.fs.qw.domain.QwCompany;
+import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.IQwMaterialService;
+import com.fs.qwApi.domain.QwExternalContactResult;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.sop.mapper.QwSopLogsMapper;
 import com.fs.sop.mapper.QwSopMapper;
@@ -40,6 +41,7 @@ import org.springframework.web.bind.annotation.RestController;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -114,10 +116,13 @@ public class CommonController {
     @Autowired
     private IQwMaterialService iQwMaterialService;
 
-
     @Autowired
     private IFsCourseLinkService iFsCourseLinkService;
 
+    @Autowired
+    private SyncQwExternalContactService syncQwExternalContactService;
+
+
     /**
     * 发官方通连
     */
@@ -318,6 +323,12 @@ public class CommonController {
         return R.ok();
     }
 
+    @GetMapping("/syncQwExternalContactUnionid")
+    public R syncQwExternalContactUnionid(){
+        return syncQwExternalContactService.syncQwExternalContactUnionid();
+    }
+
+
     @GetMapping("/queryRedPacketResult")
     public R queryRedPacketResult(String startTime , String  endTime) {
         fsCourseRedPacketLogService.queryRedPacketResult(startTime, endTime);

+ 11 - 0
fs-qw-task/src/main/java/com/fs/app/task/qwTask.java

@@ -78,6 +78,9 @@ public class qwTask {
     @Autowired
     private QwExternalContactRatingMoreSevenDaysService qwExternalContactRatingMoreSevenDaysService;
 
+    @Autowired
+    private SyncQwExternalContactService syncQwExternalContactService;
+
     /**
      * 定时任务:检查SOP规则时间
      * 执行时间:每天凌晨 1:10:00
@@ -374,4 +377,12 @@ public class qwTask {
         long endTimeMillis = System.currentTimeMillis();
         log.info("====== 更新掉所有前一天的所有待发送,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
     }
+
+    @Scheduled(cron = "0 1 0 */2 * ?")
+    public void updateQwExternalContactUnionid() {
+        long startTimeMillis = System.currentTimeMillis();
+        log.info("====== 同步外部联系人的UnionId ======");
+        syncQwExternalContactService.syncQwExternalContactUnionid();
+
+    }
 }

+ 10 - 0
fs-qw-task/src/main/java/com/fs/app/taskService/SyncQwExternalContactService.java

@@ -0,0 +1,10 @@
+package com.fs.app.taskService;
+
+import com.fs.common.core.domain.R;
+
+public interface SyncQwExternalContactService {
+
+    R syncQwExternalContactUnionid();
+
+
+}

+ 10 - 3
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -899,6 +899,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                      Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat,CourseConfig config,Map<Long,
                     Map<Integer, List<CompanyMiniapp>>> miniMap,Integer grade, Integer sendMsgType,
                                      List<Company> companies) {
+        QwExternalContact contact = null;
+        if(logVo.getExternalId() != null){
+            contact = qwExternalContactMapper.selectById(logVo.getExternalId());
+        }
         // 深拷贝 Content 对象,避免使用 JSON
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         if (clonedContent == null) {
@@ -968,6 +972,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                 } else {
                                     setting.setValue(currentValue
                                             .replaceAll("#销售称呼#", StringUtil.strIsNullOrEmpty(welcomeText) ? "" : welcomeText)
+                                            .replaceAll("#客户称呼#", contact == null || StringUtil.strIsNullOrEmpty(contact.getStageStatus())|| "0".equals(contact.getStageStatus())?"同学":contact.getStageStatus())
                                             + "\n" + link);
                                 }
                             }
@@ -978,7 +983,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     } else {
                         if ("1".equals(setting.getContentType())) {
                             setting.setValue(setting.getValue()
-                                    .replaceAll("#销售称呼#", StringUtil.strIsNullOrEmpty(welcomeText) ? "" : welcomeText));
+                                    .replaceAll("#销售称呼#", StringUtil.strIsNullOrEmpty(welcomeText) ? "" : welcomeText)
+                                    .replaceAll("#客户称呼#", contact == null || StringUtil.strIsNullOrEmpty(contact.getStageStatus())|| "0".equals(contact.getStageStatus())?"同学":contact.getStageStatus()));
                         }
                     }
                     break;
@@ -988,7 +994,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
 
                     String sortLink = createLinkByMiniApp(setting, logVo, sendTime, courseId, videoId,
-                            qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId());
+                            qwUserId, companyUserId, companyId, externalId,isOfficial,sopLogs.getFsUserId(), isGroupChat ? groupChat.getChatId() : null);
 
                     if(sopLogs.getSendType()==1){
                         setting.setMiniprogramAppid(miniAppId);
@@ -1323,7 +1329,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
     private String createLinkByMiniApp(QwSopTempSetting.Content.Setting setting, SopUserLogsVo logVo, Date sendTime,
                                        Long courseId, Long videoId, String qwUserId,
-                                       String companyUserId, String companyId, String externalId,String isOfficial,Long fsUserId) {
+                                       String companyUserId, String companyId, String externalId,String isOfficial,Long fsUserId, String chatId) {
         // 获取缓存的配置
         CourseConfig config;
         synchronized(configLock) {
@@ -1351,6 +1357,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         link.setCourseId(courseId.longValue());
         link.setQwExternalId(Long.parseLong(externalId));
         link.setProjectCode(cloudHostProper.getProjectCode());
+        link.setChatId(chatId);
 
         if (StringUtil.strIsNullOrEmpty(isOfficial)){
             link.setLinkType(3);

+ 78 - 0
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SyncQwExternalContactServiceImpl.java

@@ -0,0 +1,78 @@
+package com.fs.app.taskService.impl;
+
+import com.fs.app.taskService.SyncQwExternalContactService;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.StringUtils;
+import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.mapper.QwExternalContactMapper;
+import com.fs.qwApi.domain.QwExternalContactResult;
+import com.fs.qwApi.service.QwApiService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@Slf4j
+public class SyncQwExternalContactServiceImpl implements SyncQwExternalContactService {
+    @Autowired
+    private RedisCache redisCache;
+    @Autowired
+    private QwExternalContactMapper qwExternalContactMapper;
+    @Autowired
+    private QwApiService qwApiService;
+    @Override
+    public R syncQwExternalContactUnionid() {
+        // 测试环境需要在sql加上:and corp_id='ww51717e2b71d5e2d3'
+        // 查询这次同步的最大id
+        Long maxId = qwExternalContactMapper.selectSyncMaxId();
+        log.info("同步最大id值:"+maxId);
+        if (maxId == null) {
+            return R.ok("无需同步");
+        }
+        Long recordId = 0L;
+        String recordIdStr = redisCache.getCacheObject("syncQwExternalContactUnionId");
+        if (StringUtils.isNotEmpty(recordIdStr)) {
+            try {
+                recordId = Long.parseLong(recordIdStr);
+            } catch (NumberFormatException e) {
+                log.info("Failed to parse recordId from redis: {}", recordIdStr);
+                recordId = 0L;
+            }
+        }
+        log.info("开始同步的recordId值:"+recordId);
+        // 循环同步直到recordId等于maxId
+        while (recordId < maxId) {
+            // 每次查询500条数据
+            List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectSyncData(recordId, maxId);
+            if (qwExternalContacts.isEmpty()) {
+                break;
+            }
+            List<QwExternalContact> batchList = new ArrayList<>();
+            // 调用接口
+            for (QwExternalContact info : qwExternalContacts) {
+                QwExternalContactResult externalcontact = qwApiService.getExternalcontact(info.getExternalUserId(), info.getCorpId());
+                if (null!=externalcontact && null!=externalcontact.getExternal_contact() && null!=externalcontact.getExternal_contact().getUnionid() ) {
+                    info.setUnionid(externalcontact.getExternal_contact().getUnionid());
+                    batchList.add(info);
+                }
+            }
+            if (!batchList.isEmpty()) {
+                for (QwExternalContact qwExternalContact : batchList) {
+                    qwExternalContactMapper.batchUpdateUnionId(qwExternalContact);
+                }
+            }else{
+                log.info("集合为空:{recordId->"+recordId+";syncId->"+qwExternalContacts.get(qwExternalContacts.size() - 1).getId()+"}");
+            }
+            // 更新recordId为本次处理的最后一条记录的id
+            recordId = qwExternalContacts.get(qwExternalContacts.size() - 1).getId();
+            // 更新redis中的记录值
+            redisCache.setCacheObject("syncQwExternalContactUnionId", recordId.toString());
+        }
+        log.info("同步成功,同步完之后的recordId:"+recordId);
+        return R.ok();
+    }
+}

+ 1 - 1
fs-repeat-api/src/main/java/com/fs/app/mq/RocketMQConsumerService.java

@@ -20,7 +20,7 @@ import java.util.function.Function;
 @Slf4j
 @Service
 @AllArgsConstructor
-@RocketMQMessageListener(topic = "${rocketmq.consumer.topic}", consumerGroup = "${rocketmq.consumer.group}")
+@RocketMQMessageListener(topic = "repeat-upload", consumerGroup = "common-group")
 public class RocketMQConsumerService implements RocketMQListener<String> {
 
     private final RepeatService repeatService;

+ 23 - 5
fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.company.service.impl;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.QRutils;
 import com.fs.common.annotation.DataScope;
@@ -22,10 +23,7 @@ import com.fs.company.mapper.*;
 import com.fs.company.param.CompanyUserAreaParam;
 import com.fs.company.param.CompanyUserCodeParam;
 import com.fs.company.param.CompanyUserQwParam;
-import com.fs.company.service.ICompanyRoleService;
-import com.fs.company.service.ICompanyService;
-import com.fs.company.service.ICompanyUserRoleService;
-import com.fs.company.service.ICompanyUserService;
+import com.fs.company.service.*;
 import com.fs.company.vo.*;
 import com.fs.course.service.IFsUserCompanyUserService;
 import com.fs.his.mapper.FsUserMapper;
@@ -45,8 +43,11 @@ import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwOptionsVO;
 import com.fs.qw.vo.QwUserVO;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
+import com.fs.system.service.ISysConfigService;
 import com.fs.system.service.ISysRoleService;
 import com.fs.system.service.ISysUserService;
 import com.fs.voice.utils.StringUtil;
@@ -104,6 +105,7 @@ public class CompanyUserServiceImpl implements ICompanyUserService
 
     @Autowired
     private FsUserMapper fsUserMapper;
+
     @Autowired
     private IFsUserCompanyUserService userCompanyUserService;
 
@@ -119,6 +121,9 @@ public class CompanyUserServiceImpl implements ICompanyUserService
     @Autowired
     private ISysRoleService sysRoleService;
 
+    @Autowired
+    private ICompanyConfigService companyConfigService;
+
 //    @Autowired
 //    private ICompanyUserRoleService userRoleService;
 
@@ -660,7 +665,20 @@ public class CompanyUserServiceImpl implements ICompanyUserService
     @Override
     @DataScope(deptAlias = "u", userAlias = "u")
     public List<CompanyUserQwListVO> selectCompanyUserQwListVO(CompanyUserQwParam user) {
-        return companyUserMapper.selectCompanyUserQwListVO(user);
+//        CompanyConfig companyConfig = companyConfigService.selectCompanyConfigByKey(user.getCompanyId(), "company:admin:show");
+        boolean  isAdminShow = false;
+//        if(!StringUtils.isEmpty(companyConfig.getConfigValue())){
+//            isAdminShow = Boolean.parseBoolean(companyConfig.getConfigValue());
+//        }
+        List<CompanyUserQwListVO> companyUserQwListVOS = companyUserMapper.selectCompanyUserQwListVO(user);
+        if(!isAdminShow){
+            Company company = companyService.selectCompanyById(user.getCompanyId());
+            Long userId = company.getUserId();
+            companyUserQwListVOS = companyUserQwListVOS.stream()
+                    .filter(vo -> !vo.getUserId().equals(userId))
+                    .collect(Collectors.toList());
+        }
+        return companyUserQwListVOS;
     }
 
     @Override

+ 4 - 1
fs-service/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java

@@ -117,8 +117,11 @@ public interface FsCourseAnswerLogsMapper
             "<if test = 'qwUserId !=null '> " +
             "and qw_user_id = #{qwUserId} " +
             "</if>" +
+            "<if test = 'project !=null '> " +
+            "and project = #{project} " +
+            "</if>" +
             "</script>"})
-    int selectErrorCountByCourseVideo(@Param("videoId") Long videoId,@Param("userId") Long userId,@Param("qwUserId") String qwUserId);
+    int selectErrorCountByCourseVideo(@Param("videoId") Long videoId, @Param("userId") Long userId, @Param("qwUserId") String qwUserId,@Param("project") Long project);
 
     Long selectRedStatus(@Param("userId") Long userId, @Param("videoId") Long videoId, @Param("periodId") Long periodId);
 

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

@@ -11,6 +11,7 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -310,6 +311,11 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
             " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.video_id =#{videoId}")
     List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByNoDayAndVoidId(Long videoId);
 
+    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
+            "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
+            " WHERE  l.create_time between #{start} and #{end} and l.video_id =#{videoId}")
+    List<FsQwCourseWatchLogVO> selectFsCourseWatchLogByNoDayAndVoidIdByTime(@Param("videoId") Long videoId, @Param("start") String start, @Param("end") String end);
+
     @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time ,u.first_time,u.create_time lineTime FROM fs_course_watch_log  l " +
             "LEFT JOIN qw_external_contact u ON u.id=l.qw_external_contact_id  " +
             " WHERE  DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 2 DAY) and l.video_id =#{videoId}")

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

@@ -10,6 +10,8 @@ import com.fs.course.vo.FsCourseWatchLogStatisticsListVO;
 import com.fs.qw.param.QwWatchLogStatisticsListParam;
 import com.fs.qw.vo.QwWatchLogStatisticsListVO;
 
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.List;
 import java.util.Map;
 
@@ -100,6 +102,7 @@ public interface IFsCourseWatchLogService extends IService<FsCourseWatchLog> {
     List<FsCourseOverVO> selectFsCourseWatchLogOverStatisticsListVO(FsCourseOverParam param);
 
     void addCourseWatchLogDay();
+    void addCourseWatchLogDayMinute(LocalDateTime start, LocalDateTime end);
 
     void addCourseWatchLogDay2();
 

+ 5 - 6
fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java

@@ -23,7 +23,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.validation.constraints.Size;
 import java.util.*;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
@@ -177,7 +176,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
                 return R.ok("答题成功");
             }
         }
-        errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),param.getQwUserId());
+        errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),param.getQwUserId(),log.getProject());
 
 
 
@@ -263,7 +262,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
             if (rightLog!=null){
                 return R.error("该课程已答题完成,不可重复答题");
             }
-            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),null);
+            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),null, null);
 
         }else {
             FsCourseWatchLog log;
@@ -284,7 +283,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
             if (rightLog != null) {
                 return R.ok("答题成功");
             }
-            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),param.getQwUserId());
+            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),param.getQwUserId(), log.getProject());
         }
 
 
@@ -368,7 +367,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
             if (rightLog!=null){
                 return R.error("该课程已答题完成,不可重复答题");
             }
-            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),null);
+            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),null, null);
 
         }else {
             FsCourseWatchLog log;
@@ -399,7 +398,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
                     return R.ok("答题成功");
                 }
             }
-            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),param.getQwUserId());
+            errorCount = courseAnswerLogsMapper.selectErrorCountByCourseVideo(param.getVideoId(), param.getUserId(),param.getQwUserId(), log.getProject());
         }
 
 

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

@@ -185,8 +185,6 @@ public class FsCourseTrafficLogServiceImpl implements IFsCourseTrafficLogService
         }
         if (ObjectUtils.isNotEmpty(param.getTabType())&&param.getTabType().equals("common")){
             param.setCommon(param.getTabType());
-        }else if(ObjectUtils.isNotNull(param.getCompanyId())){
-            param.setCommon("company");
         }
         List<FsCourseTrafficLogListVO> fsCourseTrafficLogListVOS = fsCourseTrafficLogMapper.selectTrafficNew(param);
         for (FsCourseTrafficLogListVO log : fsCourseTrafficLogListVOS) {

+ 97 - 5
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -10,18 +10,17 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DictUtils;
+import com.fs.common.utils.date.DateUtil;
 import com.fs.company.cache.ICompanyCacheService;
 import com.fs.company.cache.ICompanyUserCacheService;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.course.config.CourseConfig;
-import com.fs.course.domain.FsCourseFinishTemp;
-import com.fs.course.domain.FsCourseWatchLog;
-import com.fs.course.domain.FsUserCourse;
-import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.course.domain.*;
 import com.fs.course.mapper.*;
 import com.fs.course.param.*;
 import com.fs.course.service.IFsCourseWatchLogService;
+import com.fs.course.service.IFsUserCoursePeriodService;
 import com.fs.course.service.cache.IFsUserCourseVideoCacheService;
 import com.fs.course.vo.*;
 import com.fs.his.config.FsSysConfig;
@@ -126,6 +125,9 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
     @Autowired
     private HyWatchLogMapper hyWatchLogMapper;
 
+    @Autowired
+    private IFsUserCoursePeriodService userCoursePeriodService;
+
     /**
      * 查询短链课程看课记录
      *
@@ -615,7 +617,26 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
 
     @Override
     public List<FsCourseWatchLogListVO> selectFsCourseWatchLogListVO(FsCourseWatchLogListParam param) {
-        return fsCourseWatchLogMapper.selectFsCourseWatchLogListVO(param);
+        List<FsCourseWatchLogListVO> fsCourseWatchLogListVOS = fsCourseWatchLogMapper.selectFsCourseWatchLogListVO(param);
+        List<FsUserCoursePeriod> fsUserCoursePeriods = userCoursePeriodService.selectFsUserCoursePeriodList(new FsUserCoursePeriod());
+
+        // 将 fsUserCoursePeriods 转换为 Map,便于快速查找
+        Map<Long, String> periodIdToNameMap = fsUserCoursePeriods.stream()
+                .collect(Collectors.toMap(
+                        FsUserCoursePeriod::getPeriodId,
+                        FsUserCoursePeriod::getPeriodName,
+                        (existing, replacement) -> existing // 如果有重复key,保留现有的
+                ));
+
+        // 遍历并赋值
+        fsCourseWatchLogListVOS.forEach(vo -> {
+            String periodName = periodIdToNameMap.get(vo.getPeriodId());
+            if (periodName != null) {
+                vo.setPeriodIdName(periodName);
+            }
+        });
+
+        return fsCourseWatchLogListVOS;
     }
 
     @Override
@@ -850,6 +871,60 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
         return fsCourseWatchLogMapper.selectFsCourseWatchLogOverStatisticsListVO(param);
     }
 
+    @Override
+    public void addCourseWatchLogDayMinute(LocalDateTime start, LocalDateTime end) {
+        List<FsUserCourse> courses = fsUserCourseMapper.selectFsUserCourseAllCourse();
+        for (FsUserCourse course : courses) {
+            Long project = course.getProject();
+            List<FsUserCourseVideo> fsUserCourseVideos = fsUserCourseVideoMapper.selectVideoByCourseId(course.getCourseId());
+            for (FsUserCourseVideo fsUserCourseVideo : fsUserCourseVideos) {
+                ArrayList<QwWatchLog> QwWatchLogs = new ArrayList<>();
+                List<FsQwCourseWatchLogVO> watchLogs = fsCourseWatchLogMapper.selectFsCourseWatchLogByNoDayAndVoidIdByTime(fsUserCourseVideo.getVideoId(), DateUtil.formatLocalDateTime(start), DateUtil.formatLocalDateTime(end));
+                for (FsQwCourseWatchLogVO fsCourseWatchLog : watchLogs) {
+                    Date firstTime = fsCourseWatchLog.getFirstTime();
+                    Long day=1L;
+                    if (fsCourseWatchLog.getLineTime()==null){
+                        continue;
+                    }
+                    //不是第一次 看课程
+                    if (firstTime!=null){
+                        LocalDate firstLocalDate = firstTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+                        LocalDate currentDate = LocalDate.now();
+                        day = ChronoUnit.DAYS.between(firstLocalDate, currentDate);
+                    }else {
+                        //是先导课
+                        if (fsUserCourseVideo.getIsFirst()!=null&&fsUserCourseVideo.getIsFirst()==1){
+                            int count = qwWatchLogMapper.selectQwWatchLogIsFirst(fsCourseWatchLog.getQwExternalContactId());
+                            if (count>0){
+                                continue;
+                            }
+                            day=0L;
+                            //不是先导课
+                        }else {
+                            day=1L;
+                            QwExternalContact qwExternalContact = new QwExternalContact();
+                            qwExternalContact.setId(fsCourseWatchLog.getQwExternalContactId());
+                            qwExternalContact.setFirstTime(fsCourseWatchLog.getCreateTime());
+                            qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
+                        }
+                    }
+                    QwWatchLog qwWatchLog = new QwWatchLog();
+                    qwWatchLog.setExtId(fsCourseWatchLog.getQwExternalContactId());
+                    qwWatchLog.setLineTime(fsCourseWatchLog.getLineTime());
+                    qwWatchLog.setQwUserId(Long.parseLong(fsCourseWatchLog.getQwUserId()));
+                    qwWatchLog.setDay(day);
+                    qwWatchLog.setStatus(fsCourseWatchLog.getLogType()==3?0:fsCourseWatchLog.getLogType()==2?2:1);
+                    qwWatchLog.setProject(project);
+                    qwWatchLog.setCreateTime(fsCourseWatchLog.getCreateTime());
+                    QwWatchLogs.add(qwWatchLog);
+                }
+                if (!QwWatchLogs.isEmpty()){
+                    qwWatchLogMapper.insertQwWatchLogBatch(QwWatchLogs);
+                }
+
+            }
+        }
+    }
     @Override
     public void addCourseWatchLogDay() {
 
@@ -1041,7 +1116,24 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
     public List<FsCourseWatchLogListVO> selectFsCourseWatchLogListVOexport(FsCourseWatchLogListParam param) {
 
         List<FsCourseWatchLogListVO> list = fsCourseWatchLogMapper.selectFsCourseWatchLogListVOexport(param);
+
+        //查询所有营期
+        List<FsUserCoursePeriod> fsUserCoursePeriods = userCoursePeriodService.selectFsUserCoursePeriodList(new FsUserCoursePeriod());
+
         for (FsCourseWatchLogListVO item : list) {
+            //营期名称
+            if (ObjectUtils.isNotNull(item.getPeriodId())) {
+                // 获取匹配的periodName
+                String periodName = fsUserCoursePeriods.stream()
+                        .filter(period -> item.getPeriodId().equals(period.getPeriodId()))
+                        .map(FsUserCoursePeriod::getPeriodName)
+                        .findFirst()
+                        .orElse("无营期名称");
+                item.setPeriodIdName(periodName);
+            }else {
+                item.setPeriodIdName("自动发课无营期名称");
+            }
+
             // 项目
             if(ObjectUtils.isNotNull(item.getProject())) {
                 String sysCourseProject = DictUtils.getDictLabel("sys_course_project", String.valueOf(item.getProject()));

+ 86 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.BeanCopyUtils;
@@ -55,6 +56,7 @@ import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qwApi.Result.QwAddContactWayResult;
+import com.fs.qwApi.Result.QwGroupChatDetailsResult;
 import com.fs.qwApi.param.QwAddContactWayParam;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.sop.mapper.QwSopLogsMapper;
@@ -479,6 +481,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         Integer isRoom = param.getIsRoom();
 
         // 处理逻辑
+        if(StringUtils.isNotEmpty(param.getChatId())){
+            return handleQwRoom(param, fsUser);
+        }
         if (isRoom == null || isRoom == 0) {
             // 当 isRoom 为 null 或 0 时走 handleExt
             return handleExt(param,msg, oneCompanyCourse);
@@ -492,7 +497,88 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         }
 
     }
+    private R handleQwRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
+        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>";
+        QwGroupChatDetailsResult result = qwApiService.groupChatDetails(courseLink.getChatId(), param.getCorpId());
+        log.info("群聊参数:{},链接参数:{}, 企微返回:{}", JSON.toJSONString(param), JSON.toJSONString(courseLink), JSON.toJSONString(result));
+        if(result.getErrCode() != 0){
+            return R.error("企微接口请求失败,请联系管理员:" +result.getErrMsg());
+        }
+//            List<QwGroupChatDetailsResult.Member> collect = result.getGroupChat().getMemberList().stream().filter(e -> e.getType() == 2).collect(Collectors.toList());
+//            if(collect.isEmpty()){
+//                return addCustomerService(param.getQwUserId(),msg);
+//            }
+//            Optional<QwGroupChatDetailsResult.Member> optional = collect.stream().filter(e -> e.getName().equals(fsUser.getNickName()) || e.getName().equals(param.getNickName())).findFirst();
+//            if(!optional.isPresent()){
+//                return addCustomerService(param.getQwUserId(),msg);
+//            }
+//            QwGroupChatDetailsResult.Member member = optional.get();
+//            QwExternalContact qwExternalContact =
+//                    qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+//                    .eq("user_id", result.getGroupChat().getOwner())
+//                    .eq("external_user_id", member.getUserId())
+//                    );
+        QwExternalContact qwExternalContact =
+                qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+                        .eq("user_id", result.getGroupChat().getOwner())
+                        .eq("fs_user_id", param.getUserId())
+                        .eq("corp_id", param.getCorpId())
+                        .eq("status",0));
+        if(qwExternalContact==null){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        log.info("外部联系人数据:{}", qwExternalContact);
+        if(result.getGroupChat().getMemberList().stream().noneMatch(e -> e.getUserId().equals(qwExternalContact.getExternalUserId()))){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        Long qwExternalId = qwExternalContact.getId();
+//        addCompanyCompanyFsUser(param);
+        FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(qwExternalId, param.getVideoId(),param.getQwUserId());
+        if (log==null ){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        //判断外部联系人有没有绑定userId
+        if (qwExternalContact.getFsUserId()!=null){
+            //有客户有小程序id  但 登录的小程序id和根据外部联系人id查出来的小程序id不一致
+            if (!qwExternalContact.getFsUserId().equals(param.getUserId())) {
+                return addCustomerService(param.getQwUserId(),msg);
+            }
+            List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByMiniUserId(param.getUserId());
+            //匹配客户公司id
+            if (qwExternalContacts.stream().noneMatch(contact -> contact.getCorpId().equals(param.getCorpId()))){
+                return addCustomerService(param.getQwUserId(),msg);
+            }
+
+            //看课记录中userId为0绑定userId
+            if (log.getUserId()==null||log.getUserId().equals(0L) || !log.getUserId().equals(param.getUserId())){
+                log.setUserId(param.getUserId());
+            }
 
+            log.setUpdateTime(new Date());
+//            fsUserCompanyBindService.bindFsUser(fsUser.getUserId(), qwExternalId, log.getLogId());
+            courseWatchLogMapper.updateFsCourseWatchLog(log);
+
+        }else {
+            //没绑定fsUser直接绑定fsUser
+            QwExternalContact contact = new QwExternalContact();
+            contact.setId(qwExternalId);
+            contact.setFsUserId(param.getUserId());
+            qwExternalContactMapper.updateQwExternalContact(contact);
+            FsUser fsUser = new FsUser();
+            fsUser.setUserId(user.getUserId());
+            fsUser.setIsAddQw(1);
+            fsUserMapper.updateFsUser(fsUser);
+            //绑定上之后 更新观看记录
+            //看课记录中userId为0绑定userId
+            log.setUserId(param.getUserId());
+            log.setUpdateTime(new Date());
+            courseWatchLogMapper.updateFsCourseWatchLog(log);
+        }
+//        fsUserCompanyBindService.bindFsUser(fsUser.getUserId(), qwExternalId, log.getLogId());
+        return R.error(567,"群聊通用链接").put("qwExternalId", qwExternalContact.getId());
+    }
     private R handleRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
         //查询客户列表
         List<QwExternalContact> contacts = qwExternalContactMapper.selectQwExternalContactListVOByfsUserId(user.getUserId());

+ 14 - 3
fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogListVO.java

@@ -44,9 +44,16 @@ public class FsCourseWatchLogListVO extends BaseEntity
      * 项目
      */
     private Integer project;
+
+    /** 营期id */
+    private Long periodId;
+
     @Excel(name = "项目名称")
     private String projectName;
 
+    @Excel(name = "营期名称")
+    private String periodIdName;
+
     @Excel(name = "课程名称")
     private String courseName;
 
@@ -75,6 +82,13 @@ public class FsCourseWatchLogListVO extends BaseEntity
     @Excel(name = "所属销售")
     private String companyUserName;
 
+    @Excel(name = "所属sop任务")
+    private String sopId;
+
+    @Excel(name = "营期时间",dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date campPeriodTime;
+
     /** 所属团队 */
 //    @Excel(name = "所属团队")
     private String companyName;
@@ -105,9 +119,6 @@ public class FsCourseWatchLogListVO extends BaseEntity
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date finishTime;
 
-    @Excel(name = "营期时间",dateFormat = "yyyy-MM-dd HH:mm:ss")
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    private Date campPeriodTime;
 
     @Excel(name = "进线时间",dateFormat = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

+ 6 - 3
fs-service/src/main/java/com/fs/his/dto/FsStoreOrderAmountScrmStatsQueryDto.java

@@ -1,19 +1,22 @@
 package com.fs.his.dto;
 
 import lombok.Data;
+
+import java.io.Serializable;
+
 /**
  * app商城订单金额统计queryDto对象
  * */
 @Data
-public class FsStoreOrderAmountScrmStatsQueryDto {
+public class FsStoreOrderAmountScrmStatsQueryDto implements Serializable {
     /**
      * 销售公司id
      * */
-    private String companyId;
+    private Long companyId;
     /**
      * 销售人员id
      * */
-    private String companyUserId;
+    private Long companyUserId;
     /**
      * 订单开始时间
      * */

+ 6 - 3
fs-service/src/main/java/com/fs/his/dto/FsStoreOrderAmountStatsQueryDto.java

@@ -1,19 +1,22 @@
 package com.fs.his.dto;
 
 import lombok.Data;
+
+import java.io.Serializable;
+
 /**
  * 互联网医院订单金额统计queryDto对象
  * */
 @Data
-public class FsStoreOrderAmountStatsQueryDto {
+public class FsStoreOrderAmountStatsQueryDto  implements Serializable {
     /**
      * 销售公司id
      * */
-    private String companyId;
+    private Long companyId;
     /**
      * 销售人员id
      * */
-    private String companyUserId;
+    private Long companyUserId;
     /**
      * 订单开始时间
      * */

+ 7 - 6
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -553,10 +553,10 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         try{
             boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
 
-            if (!locked) {
-                logger.error("获取锁失败");
-                return R.error("[红包领取] 系统繁忙,请重试!");
-            }
+//            if (!locked) {
+//                logger.error("获取锁失败");
+//                return R.error("[红包领取] 系统繁忙,请重试!");
+//            }
 
 
             // 判断当前用户是否限流
@@ -998,7 +998,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
 
     @Override
     public String v3TransferNotify(String notifyData, HttpServletRequest request) {
-        logger.info("zyp \n【收到转账回调】:{}",notifyData);
+        logger.info("zyp \n【收到转账回调V3】:{}",notifyData);
         try {
             String json = configService.selectConfigByKey("redPacket.config");
             RedPacketConfig config = JSONUtil.toBean(json, RedPacketConfig.class);
@@ -1013,7 +1013,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             signatureHeader.setSerial(request.getHeader("Wechatpay-Serial"));
             signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
             TransferBillsNotifyResult result = wxPayService.parseTransferBillsNotifyV3Result(notifyData,signatureHeader);
-            logger.info("到零钱回调:{}",result.getResult());
+            logger.info("到零钱回调1:{}",result.getResult());
             if (result.getResult().getState().equals("SUCCESS")) {
                 R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo(),result.getResult().getTransferBillNo());
                 logger.info("result:{}",r);
@@ -1026,6 +1026,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
                 return WxPayNotifyResponse.fail("");
             }
         } catch (WxPayException e) {
+            e.printStackTrace();
             logger.error("zyp \n【转账回调异常】:{}", e.getReturnMsg());
             return WxPayNotifyResponse.fail(e.getMessage());
         }

+ 4 - 0
fs-service/src/main/java/com/fs/qw/domain/QwContactWay.java

@@ -141,4 +141,8 @@ public class QwContactWay extends BaseEntity
     private String welcomeJson;
 
     private Long informationId;
+
+    /** 序号 */
+    private Integer sort;
+
 }

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

@@ -227,10 +227,12 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     public int deleteQwExternalContactByIds(Long[] ids);
 
     @Select({"<script> " +
-            "select ec.*,qu.qw_user_name,qd.dept_name as departmentName from qw_external_contact ec " +
+            "select ec.*,qu.qw_user_name,qd.dept_name as departmentName,cw.name way_name,wg.group_name way_group_name from qw_external_contact ec " +
             "left join qw_user qu on ec.user_id=qu.qw_user_id and qu.corp_id=ec.corp_id " +
             "left join qw_dept qd on qd.dept_id=qu.department and qd.corp_id=qu.corp_id " +
             "left join company_user cu on ec.company_user_id=cu.user_id " +
+            "left join qw_contact_way cw on cw.id = ec.way_id " +
+            "left join qw_contact_way_group wg on wg.id=cw.group_id" +
             "<where>  \n" +
             "            <if test=\"userId != null  and userId != ''\"> and ec.user_id   like concat( #{userId}, '%') </if>\n" +
             "            <if test=\"qwUserName != null  and qwUserName != ''\"> and qu.qw_user_name   like concat( #{qwUserName}, '%') </if>\n" +
@@ -505,4 +507,14 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     List<QwExternalContact> selectQwExternalContactByFsUserIdAndCompany(@Param("userId")Long userId,@Param("companyUserId") Long companyUserId);
 
     void updateQwExternalContactIsRePlyById(@Param("id")Long id);
+
+    @Select("SELECT max(id) FROM qw_external_contact where status <>'4' and unionid is NULL")
+    Long selectSyncMaxId();
+
+    @Select("SELECT * FROM qw_external_contact where id >#{recordId} and id <=#{maxId} and status <>'4' and unionid is NULL order by id asc limit 500")
+    List<QwExternalContact> selectSyncData(@Param("recordId")Long recordId,@Param("maxId")Long maxId);
+
+    @Update("update qw_external_contact set unionid = #{item.unionid} where id = #{item.id}")
+    int batchUpdateUnionId(@Param("item") QwExternalContact item);
+
 }

+ 2 - 0
fs-service/src/main/java/com/fs/qw/param/QwWatchLogStatisticsListParam.java

@@ -5,6 +5,7 @@ import com.fs.common.utils.DateUtils;
 import lombok.Data;
 
 import java.util.Date;
+import java.util.List;
 
 @Data
 public class QwWatchLogStatisticsListParam {
@@ -30,6 +31,7 @@ public class QwWatchLogStatisticsListParam {
     private Long companyUserId;
     private Long id;
     private String ids;
+    private List<String> idsList;
     private Long project;
     private Long courseId;
     private Long videoId;

+ 3 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwContactWayServiceImpl.java

@@ -104,6 +104,9 @@ public class QwContactWayServiceImpl implements IQwContactWayService
         log.info("新增企微活码corpId"+corpId);
         qwContactWay.setType(type);
         qwContactWay.setCreateTime(DateUtils.getNowDate());
+        if (null==qwContactWay.getSort()) {
+            qwContactWay.setSort(0);
+        }
         qwContactWayMapper.insertQwContactWay(qwContactWay);
         Long id = qwContactWay.getId();
         qwAddContactWayParam.setType(type);

+ 3 - 2
fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -2178,8 +2178,8 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
 
     @Override
     public QwUser getQwUserByRedisForId(String qwUserId) {
-        if(qwUserId==null|| !qwUserId.isEmpty()){
-            return  null;
+        if(StringUtils.isEmpty(qwUserId)){
+            return null;
         }
         String redisKey = "qwUserRdById:" + qwUserId;
 
@@ -2450,6 +2450,7 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
 
                     if (wayLogs==null){
 
+
                         QwAppContactWayLogs qwAppContactWayLogs = new QwAppContactWayLogs();
                         qwAppContactWayLogs.setAppWayId(qwAppContactWay.getId());
                         qwAppContactWayLogs.setUserId(qwAppContactWay.getUserId());

+ 4 - 1
fs-service/src/main/java/com/fs/qw/service/impl/QwWatchLogServiceImpl.java

@@ -175,7 +175,10 @@ public class QwWatchLogServiceImpl extends ServiceImpl<QwWatchLogMapper, QwWatch
             vo.setFirstOnline(stat.getFirstOnline());
             vo.setFirstOver(stat.getFirstOver());
         }
-
+        if (StringUtils.isNotBlank(param.getIds())) {
+            String replace = param.getIds().replace("(", "").replace(")", "");
+            param.setIdsList(Arrays.asList(replace.split(",")));
+        }
         Long total = qwWatchLogMapper.selectQwExtCountByDayAndCount(param);
         rspData.setRows(vos);
         rspData.setTotal(total);

+ 10 - 0
fs-service/src/main/java/com/fs/qw/vo/QwExternalContactVO.java

@@ -129,4 +129,14 @@ public class QwExternalContactVO {
      * 是否回复
      */
     private Integer isReply;
+
+    /**
+     * 联系我名称
+     */
+    private String wayName;
+
+    /**
+     * 联系我分组名称
+     */
+    private String wayGroupName;
 }

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

@@ -545,6 +545,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     sopLogs.setSort(30000001);
                     sopLogs.setSendType(6);
                     sopLogs.setExternalUserName(groupUser.getName());
+                    sopLogs.setQwUserKey(qwUser.getId());
                     //域名
                     String companyUserId = qwUser.getCompanyUserId().toString();
                     String domainName = companyUserMapper.selectDomainByUserId(Long.parseLong(companyUserId));
@@ -608,7 +609,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             //小程序单独
                             case "4":
                                 String linkByMiniApp = createLinkByMiniApp(st, param.getCorpId(), new Date(), param.getCourseId(), param.getVideoId(),
-                                        qwUser.getId(), qwUser.getCompanyUserId().toString(), qwUser.getCompanyId().toString(), null, config);
+                                        qwUser.getId(), qwUser.getCompanyUserId().toString(), qwUser.getCompanyId().toString(), null, config, qwGroupChat.getChatId());
 
                                 if (StringUtil.strIsNullOrEmpty(config.getMiniprogramAppid())) {
                                     log.error("配置中无小程序id,采用默认的");
@@ -655,6 +656,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     sopLogs.setSort(2);
                     sopLogs.setSendType(12);
                     sopLogs.setExternalUserName(groupChat.getName());
+                    sopLogs.setQwUserKey(qwUser.getId());
 
                     QwSopCourseFinishTempSetting setting = new QwSopCourseFinishTempSetting();
 
@@ -712,7 +714,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             //小程序单独
                             case "4":
                                 String linkByMiniApp = createLinkByMiniApp(st, param.getCorpId(), new Date(), param.getCourseId(), param.getVideoId(),
-                                        qwUser.getId(), qwUser.getCompanyUserId().toString(), qwUser.getCompanyId().toString(), null, config);
+                                        qwUser.getId(), qwUser.getCompanyUserId().toString(), qwUser.getCompanyId().toString(), null, config, groupChat.getChatId());
 
                                 if (StringUtil.strIsNullOrEmpty(config.getMiniprogramAppid())) {
                                     log.error("配置中无小程序id,采用默认的");
@@ -869,7 +871,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             addWatchLogIfNeeded(item.getSopId(), param.getVideoId(), param.getCourseId(),item.getFsUserId(), qwUserId, companyUserId, companyId, item.getExternalId(),item.getStartTime(),createTime );
 
                             String linkByMiniApp = createLinkByMiniApp(st, param.getCorpId(), createTime, param.getCourseId(), param.getVideoId(),
-                                    Long.valueOf(qwUserId), companyUserId, companyId, item.getExternalId(), config);
+                                    Long.valueOf(qwUserId), companyUserId, companyId, item.getExternalId(), config, null);
 
                             String miniAppId = null;
 
@@ -1304,7 +1306,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             item.getExternalId(),item.getStartTime(),dataTime );
 
                     String linkByMiniApp = createLinkByMiniApp(st, param.getCorpId(), dataTime, param.getCourseId(), param.getVideoId(),
-                            qwUser.getId(), companyUserId, companyId, item.getExternalId(), config);
+                            qwUser.getId(), companyUserId, companyId, item.getExternalId(), config, null);
 
 
                     String miniAppId = null;
@@ -1480,10 +1482,10 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
     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 companyUserId, String companyId, Long externalId,CourseConfig config, String chatId) {
 
         FsCourseLink link = createFsCourseLink(corpId, sendTime, courseId, videoId, qwUserId,
-                                                companyUserId, companyId, externalId,3,null);
+                                                companyUserId, companyId, externalId,3,chatId);
 
         FsCourseRealLink courseMap = new FsCourseRealLink();
         BeanUtils.copyProperties(link,courseMap);

+ 1 - 0
fs-service/src/main/java/com/fs/sop/vo/SopUserLogsVo.java

@@ -17,6 +17,7 @@ public class SopUserLogsVo  {
     private Integer minConversionDay;
     private Integer maxConversionDay;
     private Integer minSend;
+    private Long externalId;
     private Integer maxSend;
 
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

+ 1 - 1
fs-service/src/main/java/com/fs/statis/mapper/FsStatisSalerWatchMapper.java

@@ -79,7 +79,7 @@ public interface FsStatisSalerWatchMapper {
     @Delete("DELETE FROM fs_statis_saler_watch WHERE id = #{id}")
     int deleteById(@Param("id") Integer id);
 
-    @DataSource(DataSourceType.SLAVE)
+//    @DataSource(DataSourceType.SLAVE)
     List<FsStatisSalerWatch> queryList(StatsWatchLogPageListDTO param);
 
     void batchSave(@Param("list") List<FsStatisSalerWatch> writeData);

+ 94 - 0
fs-service/src/main/resources/application-config-dev-jnlzjk.yml

@@ -0,0 +1,94 @@
+baidu:
+  token: 12313231232
+  back-domain: https://www.xxxx.com
+#配置
+logging:
+  level:
+    org.springframework.web: INFO
+    com.github.binarywang.demo.wx.cp: DEBUG
+    me.chanjar.weixin: DEBUG
+wx:
+  miniapp:
+    configs:
+      - appid: wx94951f52d3ac5e25   #北京存在文化
+        secret: bfe27b20c6e3c4232a1d4ef36228e84b #北京存在文化
+        token: Ncbnd7lJvkripxxna6NAWCxCrvC
+        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+        msgDataFormat: JSON
+  cp:
+    corpId: wwa46ffb9ff6ac35b8 #企业ID北京存在文化
+    appConfigs:
+      - agentId: 1000070       #北京存在文化
+        secret: pu2EFz6gY2Fo2K-aRUxLPaAkKIaMJJRp8ES9JdpHkp4 #北京存在文化
+        token: PPKOdAlCoMO
+        aesKey: PKvaxtpSv8NGpfTDm7VUHIK8Wok2ESyYX24qpXJAdMP
+  pay:
+    appId:  #微信公众号或者小程序等的appid
+    mchId:  #微信支付商户号
+    mchKey:  #微信支付商户密钥
+    subAppId:  #服务商模式下的子商户公众账号ID
+    subMchId:  #服务商模式下的子商户号
+    keyPath: c:\\cert\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
+    notifyUrl: https://userapp.his.runtzh.com/app/wxpay/wxPayNotify
+  mp:
+    useRedis: false
+    redisConfig:
+      host: 127.0.0.1
+      port: 6379
+      timeout: 2000
+    configs:
+      - appId: wxd6905bed94e45ef0 # 第一个公众号的appid  //公众号名称:济南联智健康
+        secret: a7a59d1536e9eae16108a5ad627fa4a3 # 公众号的appsecret--济南联智健康
+        token: PPKOdAlCoMO # 接口配置里的Token值
+        aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+aifabu:  #爱链接
+  appKey: 7b471be905ab17e00f3b858c6710dd117601d008
+watch:
+  watchUrl: watch.ylrzcloud.com/prod-api
+  #  account: tcloud
+  #  password: mdf-m2h_6yw2$hq
+  account1: ccif #866655060138751
+  password1: cp-t5or_6xw7$mt
+  account2: tcloud #rt500台
+  password2: mdf-m2h_6yw2$hq
+  account3: whr
+  password3: v9xsKuqn_$d2y
+
+fs :
+  commonApi: http://127.0.0.1:7771
+  h5CommonApi: http://127.0.0.1:7771
+nuonuo:
+  key: 10924508
+  secret: A2EB20764D304D16
+
+# 存储捅配置
+tencent_cloud_config:
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: jnlzjk-1323137866
+  app_id: 1323137866
+  region: ap-chongqing
+  proxy: jnlzjk
+tmp_secret_config:
+  secret_id: AKIDCj7NSNAovtqeJpBau8GZ4CGB71thXIxX
+  secret_key: lTB5zwqqz7CNhzDOWivFWedgfTBgxgBT
+  bucket: fs-1319721001
+  app_id: 1319721001
+  region: ap-chongqing
+  proxy: fs
+cloud_host:
+  company_name: 济南联志健康
+  projectCode: LZJK
+headerImg:
+  imgUrl:
+
+ipad:
+  ipadUrl: http://ipadjnlzjk.ylrztop.com
+  aiApi: http://49.232.181.28:3000/
+  voiceApi:
+  commonApi:
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:
+
+

+ 3 - 3
fs-service/src/main/resources/application-config-druid-jnlzjk.yml

@@ -84,9 +84,9 @@ headerImg:
 
 ipad:
   ipadUrl: http://ipadjnlzjk.ylrztop.com
-  aiApi: http://49.232.181.28:3000/
-  voiceApi:
-  commonApi:
+  aiApi: http://49.232.181.28:3000/api
+  voiceApi: http://129.28.187.88:8667
+  commonApi: http://129.28.187.88:7771
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:

+ 94 - 0
fs-service/src/main/resources/application-config-druid-jnsyj.yml

@@ -0,0 +1,94 @@
+baidu:
+  token: 1231323123
+  back-domain: https://www.xxxx.com
+#配置
+logging:
+  level:
+    org.springframework.web: INFO
+    com.github.binarywang.demo.wx.cp: DEBUG
+    me.chanjar.weixin: DEBUG
+wx:
+  miniapp:
+    configs:
+#      - appid: wx4115995705bb0ea0   #中康智慧
+#        secret: 58910ae743005c396012b029c7def579
+#        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+#        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+#        msgDataFormat: JSON
+#      - appid: wxedde588767b358b1   #中康未来智慧药房
+#        secret: 928d2961c81610d8f64b019597212fcd
+#        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+#        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+#        msgDataFormat: JSON
+  cp:
+    corpId: wwb2a10556ca7c2
+    appConfigs:
+      - agentId: 10005
+        secret: ec7okROXJqkNafq66aKNv0asTQIG0CYrj3vyBbo
+        token: PPKOdAoMO
+        aesKey: PKvaxtpSvNGpfTDmVUHIK8Wok2ESyYX24qpXJAdMP
+  pay:
+    appId: wx73f85fd6119 #微信公众号或者小程序等的appid
+    mchId: 161145 #微信支付商户号
+    mchKey: 8cab128997a347c10898b877f38 #微信支付商户密钥
+    subAppId:  #服务商模式下的子商户公众账号ID
+    subMchId:  #服务商模式下的子商户号
+    keyPath: c:\\cert\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
+    notifyUrl: https://usepp.his.runtzh.com/app/wxpay/wxPayNotify
+  mp:
+    useRedis: false
+    redisConfig:
+      host: 127.0.0.1
+      port: 6379
+      timeout: 2000
+    configs:
+      - appId: wx961e754dd68694f7 # 第一个公众号的appid  //公众号名称:顺亿景服务中心
+        secret: 60ed7cf5a079664b3513a1b9eafab2d4 # 公众号的appsecret
+        token: PPKOdAlCoMO # 接口配置里的Token值抖音免领及代运营        aesKey: Eswa6VjwtVcw03qZy6Wllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+  open:
+    appId: wx0943a6f6d040ca3a
+    secret: 602e2a9ea639b6cd18eb80e715c4b22e
+aifabu:  #爱链接
+  appKey: 7b471be905ab17ef358c610d117601d008
+
+watch:
+  watchUrl: watch.ylrzcloud.com/prod-api
+#  account: tcloud
+#  password: mdf-m2h_6yw2$hq
+  account1: ccif #866655060138751
+  password1: cp-t5or_6xw7$mt
+  account2: tcloud #rt500台
+  password2: mdf-m2h_6yw2$hq
+  account3: whr
+  password3: v9xsKuqn_$d2y
+
+fs :
+  commonApi: http://172.16.0.29:8010
+  h5CommonApi: http://119.29.195.254:8010
+nuonuo:
+  key: 10924508
+  secret: A2EB20764D304D16
+# 存储捅配置
+tencent_cloud_config:
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: jnsyj-1323137866
+  app_id: 1323137866
+  region: ap-chongqing
+  proxy: jnsyj
+cloud_host:
+  company_name: 济南顺亿景
+  projectCode: JNSYJ
+#看课授权时显示的头像
+headerImg:
+  imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
+ipad:
+  ipadUrl: http://ipad.hebeihdt.com
+#  aiApi: http://152.136.202.157:3000/api
+  aiApi: http://49.232.181.28:3000/api
+  voiceApi:
+  commonApi:
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:
+

+ 153 - 0
fs-service/src/main/resources/application-dev-jnlzjk.yml

@@ -0,0 +1,153 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-dev-jnlzjk,common
+    # redis 配置
+    redis:
+        host: localhost
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 30s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 100
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+#        clickhouse:
+#            type: com.alibaba.druid.pool.DruidDataSource
+#            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+#            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+#            username: rt_2024
+#            password: Yzx_19860213
+#            initialSize: 10
+#            maxActive: 100
+#            minIdle: 10
+#            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                  url: jdbc:mysql://nj-cdb-22nvjajz.sql.tencentcdb.com:29237/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  username: root
+                  password: Ylrz_1q2w3e4r5t6y
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://nj-cdb-22nvjajz.sql.tencentcdb.com:29237/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: rmq-16xj8o92zp.rocketmq.cd.qcloud.tencenttdmq.com:8080
+    producer:
+        group: my-producer-group
+        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
+        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+    consumer:
+        group: common-group
+        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
+        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+openIM:
+    secret: openIM123
+    userID: imAdmin
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: true

+ 162 - 0
fs-service/src/main/resources/application-druid-jnsyj.yml

@@ -0,0 +1,162 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-jnsyj,common
+    # redis 配置
+    redis:
+        # 地址  localhost
+        host: 172.16.0.17
+#        host: localhost
+        # 端口,默认为6379
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password: Ylrz_c123232014^$
+#        password:
+        # 连接超时时间
+        timeout: 10s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 8
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+        #        clickhouse:
+        #            type: com.alibaba.druid.pool.DruidDataSource
+        #            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+        #            url: jdbc:clickhouse://cc-2vc8zzo26w0l7m2l6.public.clickhouse.ads.aliyuncs.com/sop?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+        #            username: rt_2024
+        #            password: Yzx_19860213
+        #            initialSize: 10
+        #            maxActive: 100
+        #            minIdle: 10
+        #            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://172.16.0.26:3306/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_c123232014^$
+                # 从库数据源
+                slave:
+                    url: jdbc:mysql://172.16.0.33:3306/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_c123232014^$
+                    # 从数据源开关/默认关闭
+                    enabled: true
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 1000
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://172.16.0.26:3306/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_c123232014^$
+                read:
+
+                    url: jdbc:mysql://172.16.0.33:3306/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_c123232014^$
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 200
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: 1:8100 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group   # 生产者组名(必须唯一)
+        access-key: default
+        secret-key: aZS4z!88dNndKTfhITzTpTxRrVUShtH3
+    consumer:
+        group: common-group
+        access-key: default
+        secret-key: aZS4z!88dNndKTfhITzTpTxRrVUShtH3
+openIM:
+    secret: openIM123
+    userID: imAdmin
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: false

+ 3 - 1
fs-service/src/main/resources/application-druid-sxjz.yml

@@ -165,4 +165,6 @@ openIM:
     secret: openIM123
     userID: imAdmin
 #是否为新商户,新商户不走mpOpenId
-isNewWxMerchant: true
+isNewWxMerchant: false
+
+enableRedPackAccount: 0

+ 8 - 5
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -25,10 +25,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="campPeriodTime"    column="camp_period_time"    />
         <result property="lastHeartbeatTime"    column="last_heartbeat_time"    />
         <result property="project"    column="project"    />
+        <result property="periodId"    column="period_id"    />
     </resultMap>
 
     <sql id="selectFsCourseWatchLogVo">
-        select log_id, user_id,finish_time,send_finish_msg,sop_id,video_id,reward_type, log_type, create_time, update_time, qw_external_contact_id, duration, qw_user_id, company_user_id, company_id, course_id,camp_period_time,project from fs_course_watch_log
+        select log_id, user_id,finish_time,send_finish_msg,sop_id,video_id,reward_type, log_type, create_time, update_time, qw_external_contact_id, duration, qw_user_id, company_user_id, company_id, course_id,camp_period_time,project,period_id  from fs_course_watch_log
     </sql>
 
     <select id="selectFsCourseWatchLogList" parameterType="FsCourseWatchLog" resultMap="FsCourseWatchLogResult">
@@ -55,7 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </select>
 
     <select id="selectFsCourseWatchLogListVO" resultType="com.fs.course.vo.FsCourseWatchLogListVO">
-        select l.log_id,l.project,l.user_id,uc.course_name,v.title as video_name,qec.avatar as external_user_avatar,
+        select l.log_id,l.project,l.period_id,l.user_id,uc.course_name,v.title as video_name,qec.avatar as external_user_avatar,
         l.log_type,SEC_TO_TIME(l.duration) as duration,c.company_name,l.camp_period_time,l.finish_time,
         cu.nick_name as company_user_name ,l.send_type,l.create_time,l.update_time,l.last_heartbeat_time,
         qu.qw_user_name,qec.name as external_user_name,c.company_id,u.avatar as fsAvatar,u.nick_name as fsNickName,qec.create_time as qec_create_time,
@@ -459,10 +460,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 and o.company_id=#{companyId}
             </if>
             <if test= 'sTime != null '>
-                and o.create_time &gt;= #{sTime}
+                and DATE(o.create_time) &gt;= #{sTime}
             </if>
             <if test='eTime != null '>
-                and o.create_time &lt;= #{eTime}
+                and DATE(o.create_time) &lt;= #{eTime}
             </if>
             <if test ='courseId !=null'>
                 and o.course_id = #{courseId}
@@ -484,7 +485,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         GROUP BY o.video_id,o.user_id,DATE(o.create_time),o.project,o.course_id
         ORDER BY o.video_id ,DATE(o.create_time)
 
-        limit ${(pageNum-1)*pageSize},${pageSize}
+<!--        limit ${(pageNum-1)*pageSize},${pageSize}-->
     </select>
     <select id="selectFsCourseWatchLogStatisticsListVONewCount" resultType="java.lang.Long">
         SELECT COUNT(*)
@@ -741,6 +742,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT
         l.log_id,
         l.project AS project,
+        l.period_id,
         l.user_id,
         l.log_type,
         SEC_TO_TIME(l.duration) AS duration,
@@ -756,6 +758,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         l.video_id,
         l.qw_user_id,
         l.qw_external_contact_id,
+        l.sop_id,
         qec.create_time as qec_create_time
         FROM
         fs_course_watch_log l LEFT JOIN qw_external_contact qec on l.qw_external_contact_id = qec.id

+ 5 - 2
fs-service/src/main/resources/mapper/qw/QwContactWayMapper.xml

@@ -42,10 +42,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="welcomeJson"    column="welcome_json"    />
         <result property="corpId"    column="corp_id"    />
         <result property="informationId"    column="information_id"    />
+        <result property="sort"    column="sort"    />
     </resultMap>
 
     <sql id="selectQwContactWayVo">
-        select id, type,corp_id,information_id, name,welcome_json, remark, skip_verify, state, user_ids, add_num, delete_num, num, qr_code, config_id, is_del, create_time, company_id, is_welcome, text_content, image_pic_url, is_user_limit, is_span_welcome, is_close_welcome, close_welcome_word, is_tag, tags, is_remark, remark_status, description, is_description, spare_user_ids, group_id, user_limit_json, user_time_json, user_type from qw_contact_way
+        select id, type,corp_id,information_id, name,welcome_json, remark, skip_verify, state, user_ids, add_num, delete_num, num, qr_code, config_id, is_del, create_time, company_id, is_welcome, text_content, image_pic_url, is_user_limit, is_span_welcome, is_close_welcome, close_welcome_word, is_tag, tags, is_remark, remark_status, description, is_description, spare_user_ids, group_id, user_limit_json, user_time_json, user_type,sort
+        from qw_contact_way
     </sql>
 
     <select id="selectQwContactWayList" parameterType="QwContactWay" resultMap="QwContactWayResult">
@@ -82,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="userLimitJson != null  and userLimitJson != ''"> and user_limit_json = #{userLimitJson}</if>
             <if test="userTimeJson != null  and userTimeJson != ''"> and user_time_json = #{userTimeJson}</if>
             <if test="userType != null "> and user_type = #{userType}</if>
-        </where> order by id desc
+        </where> order by sort asc,create_time desc
     </select>
 
     <select id="selectQwContactWayById" parameterType="Long" resultMap="QwContactWayResult">
@@ -206,6 +208,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="welcomeJson != null">welcome_json = #{welcomeJson},</if>
             <if test="corpId != null">corp_id = #{corpId},</if>
             <if test="informationId != null">information_id = #{informationId},</if>
+            <if test="sort != null">sort = #{sort},</if>
         </trim>
         where id = #{id}
     </update>

+ 2 - 2
fs-service/src/main/resources/mapper/qw/QwWatchLogMapper.xml

@@ -218,9 +218,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test='nickName != null and nickName != ""'>
             AND qu.qw_user_name LIKE CONCAT(#{nickName}, '%')
         </if>
-        <if test='ids != null and ids != ""'>
+        <if test='idsList != null and !idsList.isEmpty()'>
             AND qec.qw_user_id IN
-            <foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
+            <foreach item="item" index="index" collection="idsList" open="(" separator="," close=")">
                 #{item}
             </foreach>
         </if>

+ 1 - 1
fs-user-app/src/main/resources/application.yml

@@ -13,4 +13,4 @@ spring:
 #    active: druid-sxjz
 #    active: druid-qdtst
 #    active: druid-yzt
-    active: druid-knt-test
+    active: dev-jnlzjk