Bläddra i källkod

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

15376779826 2 veckor sedan
förälder
incheckning
58c400885c
94 ändrade filer med 2377 tillägg och 338 borttagningar
  1. 17 1
      fs-admin/src/main/java/com/fs/api/controller/StatisticManageController.java
  2. 1 9
      fs-admin/src/main/java/com/fs/company/controller/CompanyDeductController.java
  3. 1 10
      fs-admin/src/main/java/com/fs/company/controller/CompanyRechargeController.java
  4. 1 2
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseCategoryController.java
  5. 29 0
      fs-admin/src/main/java/com/fs/his/controller/FsInquiryOrderController.java
  6. 27 4
      fs-admin/src/main/java/com/fs/his/controller/FsInquiryOrderReportController.java
  7. 30 4
      fs-admin/src/main/java/com/fs/his/controller/FsPackageOrderController.java
  8. 42 1
      fs-admin/src/main/java/com/fs/his/controller/FsPrescribeController.java
  9. 29 0
      fs-admin/src/main/java/com/fs/his/controller/FsStoreAfterSalesController.java
  10. 51 5
      fs-admin/src/main/java/com/fs/his/controller/FsStoreOrderController.java
  11. 29 0
      fs-admin/src/main/java/com/fs/his/controller/FsStoreSubOrderController.java
  12. 13 0
      fs-admin/src/main/java/com/fs/his/task/Task.java
  13. 4 0
      fs-admin/src/main/java/com/fs/live/controller/LiveCouponController.java
  14. 1 1
      fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java
  15. 31 4
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java
  16. 1 0
      fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java
  17. 13 0
      fs-common/src/main/java/com/fs/common/core/domain/entity/SysUser.java
  18. 1 2
      fs-company/src/main/java/com/fs/company/controller/course/FsUserCourseCategoryController.java
  19. 100 0
      fs-company/src/main/java/com/fs/company/controller/crm/ComprehensiveStatisticsController.java
  20. 4 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveCouponController.java
  21. 28 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java
  22. 7 0
      fs-company/src/main/java/com/fs/company/controller/qw/QwSopTempController.java
  23. 5 0
      fs-company/src/main/resources/logback.xml
  24. 1 1
      fs-live-app/src/main/java/com/fs/live/controller/LiveController.java
  25. 1 0
      fs-live-app/src/main/java/com/fs/live/websocket/bean/SendMsgVo.java
  26. 5 0
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  27. 2 0
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  28. 40 5
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/AsyncCourseWatchFinishService.java
  29. 22 0
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  30. 17 0
      fs-service/src/main/java/com/fs/company/mapper/CrmStatisticManageMapper.java
  31. 27 0
      fs-service/src/main/java/com/fs/company/service/ICrmStatisticManageService.java
  32. 3 1
      fs-service/src/main/java/com/fs/company/service/IStatisticManageService.java
  33. 3 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  34. 129 0
      fs-service/src/main/java/com/fs/company/service/impl/CrmStatisticManageServiceImpl.java
  35. 94 185
      fs-service/src/main/java/com/fs/company/service/impl/StatisticManageServiceImpl.java
  36. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseCategoryMapper.java
  37. 1 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseCategoryService.java
  38. 13 2
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseFinishTempParentServiceImpl.java
  39. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java
  40. 5 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseCategoryServiceImpl.java
  41. 17 3
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  42. 123 7
      fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java
  43. 5 0
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  44. 3 0
      fs-service/src/main/java/com/fs/his/mapper/FsStorePaymentMapper.java
  45. 9 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  46. 2 0
      fs-service/src/main/java/com/fs/his/service/IFsStorePaymentService.java
  47. 1 1
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  48. 15 0
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  49. 2 2
      fs-service/src/main/java/com/fs/live/domain/LiveCoupon.java
  50. 4 0
      fs-service/src/main/java/com/fs/live/domain/LiveCouponIssue.java
  51. 9 0
      fs-service/src/main/java/com/fs/live/domain/LiveOrder.java
  52. 85 0
      fs-service/src/main/java/com/fs/live/dto/LiveOrderCustomerExportDTO.java
  53. 1 1
      fs-service/src/main/java/com/fs/live/mapper/LiveAfterSalesMapper.java
  54. 1 1
      fs-service/src/main/java/com/fs/live/mapper/LiveCouponUserMapper.java
  55. 1 1
      fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java
  56. 1 1
      fs-service/src/main/java/com/fs/live/mapper/LiveMsgMapper.java
  57. 3 0
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java
  58. 3 0
      fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java
  59. 10 1
      fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java
  60. 26 26
      fs-service/src/main/java/com/fs/live/service/impl/LiveDataServiceImpl.java
  61. 8 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  62. 1 1
      fs-service/src/main/java/com/fs/live/service/impl/LiveRedConfServiceImpl.java
  63. 17 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  64. 2 2
      fs-service/src/main/java/com/fs/live/vo/LiveDashBoardDataVo.java
  65. 2 0
      fs-service/src/main/java/com/fs/live/vo/LiveDataListVo.java
  66. 2 0
      fs-service/src/main/java/com/fs/live/vo/LiveDataStatisticsVo.java
  67. 59 0
      fs-service/src/main/java/com/fs/live/vo/LiveMsgVo.java
  68. 467 0
      fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java
  69. 2 0
      fs-service/src/main/java/com/fs/live/vo/LiveVo.java
  70. 1 1
      fs-service/src/main/java/com/fs/qw/mapper/QwFriendWelcomeMapper.java
  71. 1 1
      fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java
  72. 3 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwUserVoiceLogServiceImpl.java
  73. 11 3
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java
  74. 10 0
      fs-service/src/main/java/com/fs/statis/dto/ComprehensiveStatisticsDTO.java
  75. 2 0
      fs-service/src/main/java/com/fs/statis/param/ComprehensiveStatisticsParam.java
  76. 59 0
      fs-service/src/main/java/com/fs/utils/MyDateUtils.java
  77. 1 1
      fs-service/src/main/resources/application-config-druid-bjzm-test.yml
  78. 2 2
      fs-service/src/main/resources/application-config-druid-bjzm.yml
  79. 1 1
      fs-service/src/main/resources/application-config-druid-hst.yml
  80. 1 1
      fs-service/src/main/resources/application-config-druid-qdtst.yml
  81. 108 0
      fs-service/src/main/resources/application-config-druid-sczy.yml
  82. 180 0
      fs-service/src/main/resources/application-druid-sczy.yml
  83. 18 0
      fs-service/src/main/resources/mapper/company/CrmStatisticManageMapper.xml
  84. 4 2
      fs-service/src/main/resources/mapper/company/StatisticManageMapper.xml
  85. 14 7
      fs-service/src/main/resources/mapper/fastGpt/FastGptRoleMapper.xml
  86. 4 0
      fs-service/src/main/resources/mapper/live/LiveCouponIssueMapper.xml
  87. 6 1
      fs-service/src/main/resources/mapper/live/LiveCouponMapper.xml
  88. 141 0
      fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml
  89. 29 24
      fs-service/src/main/resources/mapper/system/SysUserMapper.xml
  90. 9 0
      fs-user-app/pom.xml
  91. 24 0
      fs-user-app/src/main/java/com/fs/app/controller/CommonController.java
  92. 2 0
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveMsgController.java
  93. 12 9
      fs-user-app/src/main/java/com/fs/app/facade/impl/LiveFacadeServiceImpl.java
  94. 21 0
      fs-user-app/src/main/java/com/fs/app/param/TestMoneyParam.java

+ 17 - 1
fs-admin/src/main/java/com/fs/api/controller/StatisticManageController.java

@@ -23,13 +23,26 @@ public class StatisticManageController {
     private IStatisticManageService statisticManageService;
 
     /**
-     * 获取统计信息
+     * 日综合获取统计信息(需要按时间分组)
      * @param param
      * @return
      */
     @PostMapping("/statisticMain")
     public R statisticMain(@RequestBody ComprehensiveStatisticsParam param) {
         Assert.notNull(param.getDimension(), "请选择统计维度");
+        param.setTimeGroupFlag(true);
+        return R.ok().put("data", statisticManageService.statisticMain(param));
+    }
+
+    /**
+     * 获取综合统计信息(不需要按时间分组)
+     * @param param
+     * @return
+     */
+    @PostMapping("/statisticMainN")
+    public R statisticMainN(@RequestBody ComprehensiveStatisticsParam param) {
+        Assert.notNull(param.getDimension(), "请选择统计维度");
+        param.setTimeGroupFlag(false);
         return R.ok().put("data", statisticManageService.statisticMain(param));
     }
 
@@ -59,4 +72,7 @@ public class StatisticManageController {
     public R getSearchUserInfo(@RequestParam("id") Long id){
         return R.ok().put("data", statisticManageService.getSearchUserInfo(id));
     }
+
+
+
 }

+ 1 - 9
fs-admin/src/main/java/com/fs/company/controller/CompanyDeductController.java

@@ -133,15 +133,7 @@ public class CompanyDeductController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         if(deduct.getIsAudit()==1){
             Company company=companyService.selectCompanyByIdForUpdate(deduct.getCompanyId());
-
-            // 同步redis缓存
-            R r = companyRechargeService.syncUpdateRedisCompanyRecharge(company, deduct.getMoney(), 2);
-            if(!"200".equals(r.get("code").toString())){
-                return r;
-            }
-            // 充值后,需要同步更新余额到数据库,否则余额与缓存中的不一致
-            String newMoney = r.get("newMoney").toString();
-            company.setMoney(new BigDecimal(newMoney));
+            company.setMoney(company.getMoney().subtract(deduct.getMoney()));
             companyService.updateCompany(company);
             CompanyMoneyLogs log=new CompanyMoneyLogs();
             log.setCompanyId(deduct.getCompanyId());

+ 1 - 10
fs-admin/src/main/java/com/fs/company/controller/CompanyRechargeController.java

@@ -122,16 +122,7 @@ public class CompanyRechargeController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         if(companyRecharge.getIsAudit()==1){
             Company company=companyService.selectCompanyById(companyRecharge.getCompanyId());
-
-            // 同步redis缓存
-            // 注意:在进行充值审核之前,需要先执行一下定时任务同步缓存数据到数据库,再进行后续操作,否则金额不正确
-            R r = companyRechargeService.syncUpdateRedisCompanyRecharge(company, companyRecharge.getMoney(), 1);
-            if(!"200".equals(r.get("code").toString())){
-                return r;
-            }
-            // 充值后,需要同步更新余额到数据库,否则余额与缓存中的不一致
-            String newMoney = r.get("newMoney").toString();
-            company.setMoney(new BigDecimal(newMoney));
+            company.setMoney(company.getMoney().add(companyRecharge.getMoney()));
             companyService.updateCompany(company);
             CompanyMoneyLogs log=new CompanyMoneyLogs();
             log.setCompanyId(companyRecharge.getCompanyId());

+ 1 - 2
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseCategoryController.java

@@ -163,8 +163,7 @@ public class FsUserCourseCategoryController extends BaseController
             List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList(userId);
             return R.ok().put("data", list);
         }
-        Integer isShow = null;
-        List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList(isShow);
+        List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList();
         return R.ok().put("data", list);
     }
 

+ 29 - 0
fs-admin/src/main/java/com/fs/his/controller/FsInquiryOrderController.java

@@ -30,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -57,6 +58,20 @@ public class FsInquiryOrderController extends BaseController
    public TableDataInfo list(FsInquiryOrderParam fsInquiryOrder)
     {
         startPage();
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsInquiryOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsInquiryOrder.getCompanyId())) {
+                        return getDataTable(new ArrayList<>());
+                    }
+                }
+                fsInquiryOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         if(!StringUtils.isEmpty(fsInquiryOrder.getCreateTimeRange())){
             fsInquiryOrder.setCreateTimeList(fsInquiryOrder.getCreateTimeRange().split("--"));
         }
@@ -84,6 +99,20 @@ public class FsInquiryOrderController extends BaseController
         }
         Integer inquiryType = fsInquiryOrder.getInquiryType();
         fsInquiryOrder.setInquiryType(null);
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsInquiryOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsInquiryOrder.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsInquiryOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         logger.info("导出问诊订单:"+ SecurityUtils.getUserId());
         if (fsInquiryOrderService.isEntityNull(fsInquiryOrder)){
             return AjaxResult.error("请筛选数据导出");

+ 27 - 4
fs-admin/src/main/java/com/fs/his/controller/FsInquiryOrderReportController.java

@@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -51,8 +52,19 @@ public class FsInquiryOrderReportController extends BaseController
     public TableDataInfo list(FsInquiryOrderReportParam fsInquiryOrderReport)
     {
         startPage();
-        if (getUserId().equals(54L)||getUserId().equals(211L)){
-            fsInquiryOrderReport.setCompanyId(188L);
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsInquiryOrderReport.getCompanyId()!=null){
+                    if (!companyId.equals(fsInquiryOrderReport.getCompanyId())) {
+                        return getDataTable(new ArrayList<>());
+                    }
+                }
+                fsInquiryOrderReport.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
         }
         List<FsInquiryOrderReportListVO> list = fsInquiryOrderReportService.selectFsInquiryOrderReportListVO(fsInquiryOrderReport);
         for (FsInquiryOrderReportListVO vo : list){
@@ -78,8 +90,19 @@ public class FsInquiryOrderReportController extends BaseController
         if (fsInquiryOrderReportService.isEntityNull(fsInquiryOrderReport)){
             return AjaxResult.error("请筛选数据导出");
         }
-        if (getUserId().equals(54L)||getUserId().equals(211L)){
-            fsInquiryOrderReport.setCompanyId(188L);
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsInquiryOrderReport.getCompanyId()!=null){
+                    if (!companyId.equals(fsInquiryOrderReport.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsInquiryOrderReport.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
         }
         Integer exportType1 = exportTaskService.isExportType1(SecurityUtils.getUserId());
         if (exportType1>0){

+ 30 - 4
fs-admin/src/main/java/com/fs/his/controller/FsPackageOrderController.java

@@ -1,5 +1,6 @@
 package com.fs.his.controller;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -10,10 +11,7 @@ import com.fs.his.domain.FsExportTask;
 import com.fs.his.mapper.FsStorePaymentMapper;
 import com.fs.his.param.FsPackageOrderParam;
 import com.fs.his.service.IFsExportTaskService;
-import com.fs.his.vo.FsPackageOrderExcelVO;
-import com.fs.his.vo.FsPackageOrderListVO;
-import com.fs.his.vo.FsPackageOrderVO;
-import com.fs.his.vo.FsStoreOrderVO;
+import com.fs.his.vo.*;
 import com.fs.ybPay.service.IPayService;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -62,6 +60,20 @@ public class FsPackageOrderController extends BaseController
     public TableDataInfo list(FsPackageOrderParam  fsPackageOrder)
     {
         startPage();
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsPackageOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsPackageOrder.getCompanyId())) {
+                        return getDataTable(new ArrayList<FsStoreOrderListAndStatisticsVo>());
+                    }
+                }
+                fsPackageOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         if (fsPackageOrder.getPhoneMk()!=null&&fsPackageOrder.getPhoneMk()!=""){
             fsPackageOrder.setPhone(encryptPhone(fsPackageOrder.getPhoneMk()));
         }
@@ -86,6 +98,20 @@ public class FsPackageOrderController extends BaseController
         if (fsPackageOrderService.isEntityNull(fsPackageOrder)){
             return AjaxResult.error("请筛选数据导出");
         }
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsPackageOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsPackageOrder.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsPackageOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         fsPackageOrder.setStatus(status); //解决isEntityNull方法后status缺失
         Long count = fsPackageOrderService.selectFsPackageOrderExcelListVOCount(fsPackageOrder);
         if (count>30000){

+ 42 - 1
fs-admin/src/main/java/com/fs/his/controller/FsPrescribeController.java

@@ -72,6 +72,20 @@ public class FsPrescribeController extends BaseController
     public TableDataInfo list(FsPrescribeParam fsPrescribe)
     {
         startPage();
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsPrescribe.getCompanyId()!=null){
+                    if (!companyId.equals(fsPrescribe.getCompanyId())) {
+                        return getDataTable(new ArrayList<>());
+                    }
+                }
+                fsPrescribe.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         List<FsPrescribeListVO> list = fsPrescribeService.selectFsPrescribeListVO(fsPrescribe);
         for (FsPrescribeListVO vo : list){
             if (vo.getPatientTel()!=null){
@@ -97,6 +111,20 @@ public class FsPrescribeController extends BaseController
             return AjaxResult.error("请筛选数据导出");
         }
         logger.info("tc>\n【导出处方】:{}", SecurityUtils.getUserId());
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsPrescribe.getCompanyId()!=null){
+                    if (!companyId.equals(fsPrescribe.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsPrescribe.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         Long count = fsPrescribeService.selectFsPrescribeExcelListVOCount(fsPrescribe);
         if (count>30000){
             return AjaxResult.error("导出数据不可超过3w条");
@@ -131,7 +159,20 @@ public class FsPrescribeController extends BaseController
         if (exportType1>0){
             return AjaxResult.error("你已经有正在导出的任务");
         }
-
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsPrescribe.getCompanyId()!=null){
+                    if (!companyId.equals(fsPrescribe.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsPrescribe.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         FsExportTask task=new FsExportTask();
         task.setTaskType(6);
         task.setStatus(0);

+ 29 - 0
fs-admin/src/main/java/com/fs/his/controller/FsStoreAfterSalesController.java

@@ -1,5 +1,6 @@
 package com.fs.his.controller;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -66,6 +67,20 @@ public class FsStoreAfterSalesController extends BaseController
     public TableDataInfo list(FsStoreAfterSalesParam fsStoreAfterSales)
     {
         startPage();
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsStoreAfterSales.getCompanyId()!=null){
+                    if (!companyId.equals(fsStoreAfterSales.getCompanyId())) {
+                        return getDataTable(new ArrayList<FsStoreAfterSalesListVO>());
+                    }
+                }
+                fsStoreAfterSales.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         if(!StringUtils.isEmpty(fsStoreAfterSales.getCreateTimeRange())){
             fsStoreAfterSales.setCreateTimeList(fsStoreAfterSales.getCreateTimeRange().split("--"));
         }
@@ -88,6 +103,20 @@ public class FsStoreAfterSalesController extends BaseController
         if (exportType1>0){
             return AjaxResult.error("你已经有正在导出的任务");
         }
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsStoreAfterSales.getCompanyId()!=null){
+                    if (!companyId.equals(fsStoreAfterSales.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsStoreAfterSales.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         if(!StringUtils.isEmpty(fsStoreAfterSales.getCreateTimeRange())){
             fsStoreAfterSales.setCreateTimeList(fsStoreAfterSales.getCreateTimeRange().split("--"));
         }

+ 51 - 5
fs-admin/src/main/java/com/fs/his/controller/FsStoreOrderController.java

@@ -131,10 +131,28 @@ public class FsStoreOrderController extends BaseController
     @PostMapping("/list")
     public FsStoreOrderListAndStatisticsVo list(@RequestBody FsStoreOrderParam fsStoreOrder)
     {
+        FsStoreOrderListAndStatisticsVo vo = new FsStoreOrderListAndStatisticsVo();
         PageHelper.startPage(fsStoreOrder);
         if (fsStoreOrder.getUserPhoneMk()!=null&& !fsStoreOrder.getUserPhoneMk().isEmpty()){
             fsStoreOrder.setUserPhone(encryptPhone(fsStoreOrder.getUserPhoneMk()));
         }
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsStoreOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsStoreOrder.getCompanyId())) {
+                        vo.setRows(new ArrayList<FsStoreOrderListAndStatisticsVo>());
+                        vo.setTotal(0);
+                        return vo;
+                    }
+                }
+                fsStoreOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
+
         List<FsStoreOrderListVO> list;
         if (StringUtils.isNotBlank(fsStoreOrder.getErpAccount())){
             //金牛erp查询
@@ -146,17 +164,17 @@ public class FsStoreOrderController extends BaseController
         TableDataInfo dataTable = getDataTable(list);
         if ("金牛明医".equals(cloudHostProper.getCompanyName())){
             if (fsStoreOrder.getStatus() !=null && fsStoreOrder.getStatus() != 1){
-                list.forEach(vo->{
+                list.forEach(fsStoreOrderListVO->{
                     //查询顺丰代服账号
-                    FsStoreOrderDf df = fsStoreOrderDfService.selectFsStoreOrderDfByOrderId(vo.getOrderId());
+                    FsStoreOrderDf df = fsStoreOrderDfService.selectFsStoreOrderDfByOrderId(fsStoreOrderListVO.getOrderId());
                     if (df != null){
-                        vo.setErpAccount(df.getLoginAccount());
+                        fsStoreOrderListVO.setErpAccount(df.getLoginAccount());
                     }
                 });
             }
             dataTable.setMsg("jnmy");
         }
-        FsStoreOrderListAndStatisticsVo vo = new FsStoreOrderListAndStatisticsVo();
+
         BeanUtils.copyProperties(dataTable, vo);
         if (dataTable.getTotal()>0){
             Map<String,BigDecimal> statistics= fsStoreOrderService.selectFsStoreOrderStatistics(fsStoreOrder);
@@ -197,6 +215,20 @@ public class FsStoreOrderController extends BaseController
             return AjaxResult.error("请筛选数据导出");
         }
         logger.info("tc>\n【订单导出】:{}", SecurityUtils.getUserId());
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsStoreOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsStoreOrder.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsStoreOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         Long count = fsStoreOrderService.selectFsStoreOrderExcelListVOCount(fsStoreOrder);
         if (count>30000){
             return AjaxResult.error("导出数据不可超过3w条");
@@ -239,7 +271,21 @@ public class FsStoreOrderController extends BaseController
             return AjaxResult.error("请筛选数据导出");
         }
         logger.info("tc>\n【咨询报告】:{}", SecurityUtils.getUserId());
-        Long count;
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (param.getCompanyId()!=null){
+                    if (!companyId.equals(param.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                param.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
+        Long count = 0L;
         if (StringUtils.isNotBlank(param.getErpAccount())){
             //金牛erp查询
             count = fsStoreOrderService.selectFsStoreOrderListVOByErpAccountByExportCount(param);

+ 29 - 0
fs-admin/src/main/java/com/fs/his/controller/FsStoreSubOrderController.java

@@ -1,5 +1,6 @@
 package com.fs.his.controller;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import com.fs.his.domain.FsStoreOrder;
@@ -46,6 +47,20 @@ public class FsStoreSubOrderController extends BaseController
     public TableDataInfo list(FsStoreOrderParam fsStoreSubOrder)
     {
         startPage();
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsStoreSubOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsStoreSubOrder.getCompanyId())) {
+                        return getDataTable(new ArrayList<>());
+                    }
+                }
+                fsStoreSubOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         List<FsStoreSubOrderListVO> list = fsStoreSubOrderService.selectFsStoreSubOrderList(fsStoreSubOrder);
         return getDataTable(list);
     }
@@ -61,6 +76,20 @@ public class FsStoreSubOrderController extends BaseController
         if (fsStoreSubOrderService.isEntityNull(fsStoreSubOrder)){
             return AjaxResult.error("请筛选数据导出");
         }
+        //根据订单权限查询相关公司订单
+        try {
+            Long companyId = getLoginUser().getUser().getCompanyId();
+            if (companyId!=null){
+                if (fsStoreSubOrder.getCompanyId()!=null){
+                    if (!companyId.equals(fsStoreSubOrder.getCompanyId())) {
+                        return AjaxResult.error("请筛选数据自己公司数据");
+                    }
+                }
+                fsStoreSubOrder.setCompanyId(companyId);
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
         Long count = fsStoreSubOrderService.selectFsStoreSubOrderListCount(fsStoreSubOrder);
         if (count>30000){
             return AjaxResult.error("导出数据不可超过3w条");

+ 13 - 0
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -528,6 +528,19 @@ public class Task {
         }
     }
 
+    public void payment(){
+        List<FsStorePayment> fsStorePayments = fsStorePaymentService.selectAllPayment();
+        for (FsStorePayment fsStorePayment : fsStorePayments) {
+            try{
+                fsStorePaymentService.updateFsStorePaymentByDecryptForm(fsStorePayment.getPaymentId());
+            }catch (Exception e){
+                logger.error("同步支付失败:"+fsStorePayment.getPaymentId());
+            }
+
+        }
+
+    }
+
     public void addQwUserName() {
         QwCompany qwCompany = new QwCompany();
         List<QwCompany> companyList = qwCompanyService.selectQwCompanyList(qwCompany);

+ 4 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveCouponController.java

@@ -122,6 +122,8 @@ public class LiveCouponController extends BaseController
         issue.setIsPermanent(0);
         issue.setStatus(1);
         issue.setCreateTime(new Date());
+        // 继承优惠券的领取上限字段
+        issue.setLimitReceiveCount(coupon.getLimitReceiveCount());
         return toAjax( liveCouponIssueService.insertLiveCouponIssue(issue));
     }
 
@@ -143,6 +145,8 @@ public class LiveCouponController extends BaseController
             issue.setIsPermanent(0);
             issue.setStatus(1);
             issue.setCreateTime(new Date());
+            // 继承优惠券的领取上限字段
+            issue.setLimitReceiveCount(coupon.getLimitReceiveCount());
             liveCouponIssueService.insertLiveCouponIssue(issue);
         }
         return R.ok();

+ 1 - 1
fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java

@@ -17,7 +17,7 @@ import java.util.Map;
 
 
 @RestController
-@RequestMapping("/live/liveData")
+@RequestMapping("/liveData/liveData")
 public class LiveDataController extends BaseController {
 
     @Autowired

+ 31 - 4
fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java

@@ -34,14 +34,12 @@ import com.fs.hisStore.dto.StoreOrderExpressExportDTO;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.vo.FsStoreOrderVO;
 import com.fs.live.domain.*;
+import com.fs.live.dto.LiveOrderCustomerExportDTO;
 import com.fs.live.dto.LiveOrderExpressExportDTO;
 import com.fs.live.enums.LiveOrderCancleReason;
 import com.fs.live.param.LiveOrderScrmSetErpPhoneParam;
 import com.fs.live.service.*;
-import com.fs.live.vo.LiveGoodsVo;
-import com.fs.live.vo.LiveOrderPaymentVo;
-import com.fs.live.vo.LiveOrderTimeVo;
-import com.fs.live.vo.LiveOrderVO;
+import com.fs.live.vo.*;
 import com.fs.store.domain.FsStoreDelivers;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
@@ -144,6 +142,35 @@ public class LiveOrderController extends BaseController
         return util.exportExcel(list, "订单数据");
     }
 
+    /**
+     * 查询订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:list')")
+    @GetMapping("/listZm")
+    public TableDataInfo listZm(LiveOrder liveOrder)
+    {
+        startPage();
+        List<LiveOrderVoZm> list = liveOrderService.selectLiveOrderListZm(liveOrder);
+        for (LiveOrderVoZm vo : list){
+            vo.setUserPhone(ParseUtils.parsePhone(vo.getUserPhone()));
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:export')")
+    @Log(title = "订单", businessType = BusinessType.EXPORT)
+    @GetMapping("/exportZm")
+    public AjaxResult exportZm(LiveOrder liveOrder)
+    {
+        List<LiveOrderVoZm> list = liveOrderService.selectLiveOrderListZm(liveOrder);
+        ExcelUtil<LiveOrderVoZm> util = new ExcelUtil<LiveOrderVoZm>(LiveOrderVoZm.class);
+        return util.exportExcel(list, "订单数据");
+    }
+
+
     /**
      * 获取订单详细信息
      */

+ 1 - 0
fs-common/src/main/java/com/fs/common/constant/LiveKeysConstant.java

@@ -25,6 +25,7 @@ public class LiveKeysConstant {
     public static final String LIVE_HOME_PAGE_CONFIG_RED = "live:config:%s:red:%s"; //红包记录
     public static final String LIVE_HOME_PAGE_CONFIG_COUPON = "live:config:%s:coupon:%s"; //优惠券记录
     public static final String LIVE_HOME_PAGE_CONFIG_DRAW = "live:config:%s:draw:%s"; //抽奖记录
+    public static final String TOP_MSG = "topMsg"; //抽奖记录
 
 
 

+ 13 - 0
fs-common/src/main/java/com/fs/common/core/domain/entity/SysUser.java

@@ -95,6 +95,11 @@ public class SysUser extends BaseEntity
     /** 角色ID */
     private Long roleId;
 
+
+
+    /**  公司相关数据权限,如订单类的,为空时查所有 **/
+    private Long companyId;
+
     @Excel(name = "角色名称")
     private List<String> roleName;
 
@@ -323,6 +328,13 @@ public class SysUser extends BaseEntity
     {
         this.roleId = roleId;
     }
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
 
     @Override
     public String toString() {
@@ -347,6 +359,7 @@ public class SysUser extends BaseEntity
             .append("updateTime", getUpdateTime())
             .append("remark", getRemark())
             .append("dept", getDept())
+            .append("companyId", getCompanyId())
             .toString();
     }
 }

+ 1 - 2
fs-company/src/main/java/com/fs/company/controller/course/FsUserCourseCategoryController.java

@@ -109,8 +109,7 @@ public class FsUserCourseCategoryController extends BaseController
     @GetMapping("/getCatePidList")
     public R getCatePidList()
     {
-        Integer isShow = null;
-        List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList(isShow);
+        List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList();
         return R.ok().put("data", list);
     }
 

+ 100 - 0
fs-company/src/main/java/com/fs/company/controller/crm/ComprehensiveStatisticsController.java

@@ -0,0 +1,100 @@
+package com.fs.company.controller.crm;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.security.SecurityUtils;
+import com.fs.company.service.ICrmStatisticManageService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.statis.dto.ComprehensiveStatisticsDTO;
+import com.fs.statis.param.ComprehensiveStatisticsParam;
+import org.springframework.util.Assert;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @description:
+ * @author: Guos
+ * @time: 2025/11/13 下午3:19
+ */
+@RestController
+@RequestMapping("/crm/ComprehensiveStatistics")
+public class ComprehensiveStatisticsController extends BaseController {
+
+    @Resource
+    private ICrmStatisticManageService iCrmStatisticManageService;
+
+    /**
+     * 获取综合统计信息
+     * @param param
+     * @return
+     */
+    @PostMapping("/statisticMainN")
+    public R statisticMainN(@RequestBody ComprehensiveStatisticsParam param) {
+        Assert.notNull(param.getDimension(), "请选择统计维度");
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+        param.setTimeGroupFlag(false);
+        return R.ok().put("data", iCrmStatisticManageService.statisticMain(param));
+    }
+
+    /**
+     * 日综合获取统计信息(需要按时间分组)
+     * @param param
+     * @return
+     */
+    @PostMapping("/statisticMain")
+    public R statisticMain(@RequestBody ComprehensiveStatisticsParam param) {
+        Assert.notNull(param.getDimension(), "请选择统计维度");
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+        param.setTimeGroupFlag(true);
+        return R.ok().put("data", iCrmStatisticManageService.statisticMain(param));
+    }
+
+    /**
+     * 获取公司下拉
+     * @return
+     */
+    @GetMapping("/getSearchCompanyInfo")
+    public R getSearchCompanyInfo(){
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        Long companyId = loginUser.getCompany().getCompanyId();
+        return R.ok().put("data", iCrmStatisticManageService.getSearchCompanyInfo(companyId));
+    }
+
+    /**
+     * 根据公司id获取部门下拉
+     * @return
+     */
+    @GetMapping("/getSearchDeptInfo")
+    public R getSearchDeptInfo(@RequestParam("id") Long id){
+        return R.ok().put("data", iCrmStatisticManageService.getSearchDeptInfo(id));
+    }
+
+    /**
+     * 根据部门id获取用户下拉信息
+     * @return
+     */
+    @GetMapping("/getSearchUserInfo")
+    public R getSearchUserInfo(@RequestParam("id") Long id){
+        return R.ok().put("data", iCrmStatisticManageService.getSearchUserInfo(id));
+    }
+
+    /**
+     * 导出综合统计列表
+     */
+    @GetMapping("/export")
+    public AjaxResult export(@RequestBody ComprehensiveStatisticsParam param) {
+        R r = statisticMain(param);
+        List<ComprehensiveStatisticsDTO> data = (List<ComprehensiveStatisticsDTO>)r.get("data");
+        ExcelUtil<ComprehensiveStatisticsDTO> util = new ExcelUtil<ComprehensiveStatisticsDTO>(ComprehensiveStatisticsDTO.class);
+        return util.exportExcel(data, "综合统计");
+    }
+
+}

+ 4 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveCouponController.java

@@ -122,6 +122,8 @@ public class LiveCouponController extends BaseController
         issue.setIsPermanent(0);
         issue.setStatus(1);
         issue.setCreateTime(new Date());
+        // 继承优惠券的领取上限字段
+        issue.setLimitReceiveCount(coupon.getLimitReceiveCount());
         return toAjax( liveCouponIssueService.insertLiveCouponIssue(issue));
     }
 
@@ -143,6 +145,8 @@ public class LiveCouponController extends BaseController
             issue.setIsPermanent(0);
             issue.setStatus(1);
             issue.setCreateTime(new Date());
+            // 继承优惠券的领取上限字段
+            issue.setLimitReceiveCount(coupon.getLimitReceiveCount());
             liveCouponIssueService.insertLiveCouponIssue(issue);
         }
         return R.ok();

+ 28 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java

@@ -109,6 +109,34 @@ public class LiveOrderController extends BaseController
         return R.ok().put("payments",payments);
     }
 
+    /**
+     * 查询订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:list')")
+    @GetMapping("/listZm")
+    public TableDataInfo listZm(LiveOrder liveOrder)
+    {
+        startPage();
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        for (LiveOrder vo : list){
+            vo.setUserPhone(ParseUtils.parsePhone(vo.getUserPhone()));
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出订单列表
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:export')")
+    @Log(title = "订单", businessType = BusinessType.EXPORT)
+    @GetMapping("/exportZm")
+    public AjaxResult exportZm(LiveOrder liveOrder)
+    {
+        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
+        ExcelUtil<LiveOrder> util = new ExcelUtil<LiveOrder>(LiveOrder.class);
+        return util.exportExcel(list, "订单数据");
+    }
+
 
 //    @Log(title = "订单凭证上传", businessType = BusinessType.UPDATE)
 ////    @PreAuthorize("@ss.hasPermi('live:liveOrder:uploadCredentials')")

+ 7 - 0
fs-company/src/main/java/com/fs/company/controller/qw/QwSopTempController.java

@@ -24,6 +24,7 @@ import com.fs.sop.service.IQwSopTempService;
 import com.fs.sop.vo.UpdateRedVo;
 import com.fs.voice.utils.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
@@ -50,6 +51,8 @@ public class QwSopTempController extends BaseController
     @Autowired
     private IQwUserService iQwUserService;
 
+    @Value("${cloud_host.company_name}")
+    private String signProjectName;
 
     @Autowired
     private CompanyDeptServiceImpl companyDeptService;
@@ -141,6 +144,10 @@ public class QwSopTempController extends BaseController
     public TableDataInfo deptList(QwSopTemp qwSopTemp)
     {
 
+        if ("济南联志健康".equals(signProjectName)) {
+            return list(qwSopTemp);
+        }
+
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         qwSopTemp.setCompanyId(loginUser.getCompany().getCompanyId());
 

+ 5 - 0
fs-company/src/main/resources/logback.xml

@@ -86,6 +86,11 @@
         <appender-ref ref="file_error" />
     </root>
 
+    <!-- log4j2.xml -->
+    <Logger name="com.fs.his.mapper" level="debug"/>
+    <Logger name="com.fs.company.mapper" level="debug"/>
+    <Logger name="org.apache.ibatis" level="debug"/>
+
 	<!--系统用户操作日志-->
     <logger name="sys-user" level="info">
         <appender-ref ref="sys-user"/>

+ 1 - 1
fs-live-app/src/main/java/com/fs/live/controller/LiveController.java

@@ -125,7 +125,7 @@ public class LiveController {
 
 		LinkedHashMap<String,Object> result = (LinkedHashMap<String,Object>) params.get("WorkflowExecution");
 		String string = result.get("Object").toString();
-		videoService.updateFinishStatus("https://fs-1319721001.cos.ap-chongqing.myqcloud.com/" + string.replace(".mp4", ".m3u8"));
+		videoService.updateFinishStatus("https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/" + string.replace(".mp4", ".m3u8"));
 
 		return R.ok();
 //		{app=200149.push.tlivecloud.com, appid=1319721001, appname=live, channel_id=673,

+ 1 - 0
fs-live-app/src/main/java/com/fs/live/websocket/bean/SendMsgVo.java

@@ -33,5 +33,6 @@ public class SendMsgVo {
     private String avatar;
     private boolean on = false;
     private Integer status;
+    private Integer duration;
 
 }

+ 5 - 0
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -346,10 +346,15 @@ public class WebSocketServer {
                     liveMsg.setNickName(msg.getNickName());
                     liveMsg.setAvatar(msg.getAvatar());
                     liveMsg.setMsg(msg.getMsg());
+                    liveMsg.setEndTime(DateUtils.addMinutes(new Date(),msg.getDuration()).toString());
                     msg.setOn(true);
                     msg.setData(JSONObject.toJSONString(liveMsg));
                     // 广播消息
                     broadcastMessage(liveId, JSONObject.toJSONString(R.ok().put("data", msg)));
+                    // 放在当前活动里面
+                    redisCache.deleteObject(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG, liveId, TOP_MSG));
+                    redisCache.setCacheObject(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG, liveId, TOP_MSG), JSONObject.toJSONString(liveMsg));
+                    redisCache.expire(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG, liveId, TOP_MSG), msg.getDuration(), TimeUnit.MINUTES);
                     break;
                 case "globalVisible":
                     msg.setOn(true);

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

@@ -429,6 +429,8 @@ public class QwMsgController {
                         }
                     } else if (recordType==2){
                         log.info("id:{}, 通话挂断", id);
+                    }else if (recordType==3){
+                        log.info("通话未接听");
                     }else {
                         break;
                     }

+ 40 - 5
fs-qw-task/src/main/java/com/fs/app/taskService/impl/AsyncCourseWatchFinishService.java

@@ -184,13 +184,23 @@ public class AsyncCourseWatchFinishService {
 
             @Override
             public void onException(Throwable e) {
+//                if (isFlowControlException(e)) {
+//                    // 流控异常处理
+//                    handleFlowControlRetry(TOPIC, finishLog, validationResult, retryCount, e);
+//                    log.error("推送完课打备注失败1流控异常:finishLog={},e={}",JSON.toJSONString(finishLog),e.getMessage());
+//                } else {
+//                    // 其他异常
+//                    log.error("推送完课打备注失败1:{},{}",JSON.toJSONString(finishLog),e.getMessage());
+//                }
                 if (isFlowControlException(e)) {
                     // 流控异常处理
                     handleFlowControlRetry(TOPIC, finishLog, validationResult, retryCount, e);
-                    log.error("推送完课打备注失败1流控异常:finishLog={},e={}",JSON.toJSONString(finishLog),e.getMessage());
+                    log.error("推送完课打备注流控异常,准备重试。retryCount: {}, topic: {}, finishLogId: {}",
+                            retryCount, TOPIC, finishLog.getLogId()); // 只记录关键信息
                 } else {
-                    // 其他异常
-                    log.error("推送完课打备注失败1:{},{}",JSON.toJSONString(finishLog),e.getMessage());
+                    // 其他异常 - 记录完整堆栈
+                    log.error("推送完课打备注失败,非流控异常。finishLog: {}",
+                            JSON.toJSONString(finishLog), e); // 注意这里传 e 而不是 e.getMessage()
                 }
             }
         });
@@ -245,6 +255,15 @@ public class AsyncCourseWatchFinishService {
      * 判断是否为流控异常
      */
     private boolean isFlowControlException(Throwable e) {
+        // 检查异常消息中是否包含流控关键词(双重保障)
+        String errorMessage = e.getMessage();
+        if (errorMessage != null && (
+                errorMessage.contains("flow control") ||
+                errorMessage.contains("exhausted the send quota") ||
+                errorMessage.contains("CODE: 215"))) {
+            return true;
+        }
+
         if (e instanceof MQClientException) {
             return ((MQClientException) e).getResponseCode() == 215;
         }
@@ -256,11 +275,20 @@ public class AsyncCourseWatchFinishService {
         return false;
     }
 
+    private static final int MAX_FLOW_CONTROL_RETRY = 5;
     /**
      * 流控重试处理
      */
     private void handleFlowControlRetry(String topic, FsCourseWatchLog finishLog,
                                         ValidationResult validationResult, int retryCount, Throwable e) {
+        // 检查重试次数限制
+//        if (retryCount >= MAX_FLOW_CONTROL_RETRY) {
+//            log.error("流控重试达到最大次数 {},放弃重试。topic: {}, qwUserId: {}, logId: {}",
+//                    MAX_FLOW_CONTROL_RETRY, topic, finishLog.getQwUserId(), finishLog.getLogId());
+//            //todo 可以记录到数据库或发送告警
+//            return;
+//        }
+
         long backoffTime = calculateBackoffTime(retryCount);
         log.warn("流控触发,{}ms后第{}次重试: topic={}, qwUserId={}",
                 backoffTime, retryCount + 1, topic, finishLog.getQwUserId());
@@ -270,7 +298,8 @@ public class AsyncCourseWatchFinishService {
             try {
                 sendWithFlowControl(finishLog, validationResult, retryCount + 1);
             } catch (Exception ex) {
-                log.error("延迟重试执行异常: {}", ex.getMessage(), ex);
+                log.error("延迟重试执行异常 - qwUserId: {}, logId: {}, error: {}",
+                        finishLog.getQwUserId(), finishLog.getLogId(), ex.getMessage(), ex);
             }
         }, backoffTime, TimeUnit.MILLISECONDS);
     }
@@ -278,7 +307,13 @@ public class AsyncCourseWatchFinishService {
      * 计算退避时间(指数退避)
      */
     private long calculateBackoffTime(int retryCount) {
-        return Math.min(1000 * (long) Math.pow(2, retryCount), 10000); // 最大10秒
+//        return Math.min(1000 * (long) Math.pow(2, retryCount), 10000); // 最大10秒
+        // 基础退避:1s, 2s, 4s, 8s, 16s, 32s
+        long baseDelay = Math.min(1000L * (1L << Math.min(retryCount, 5)), 32000L);
+        // 添加随机抖动 (0~2s),避免多个客户端同时重试
+        long jitter = (long) (Math.random() * 1000);
+
+        return baseDelay + jitter;
     }
 
     @PreDestroy

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

@@ -179,6 +179,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     @Autowired
     private IFsUserCompanyBindService fsUserCompanyBindService;
 
+
+    @Autowired
+    private IQwSopTempVoiceService sopTempVoiceService;
+
     @PostConstruct
     public void init() {
         loadCourseConfig();
@@ -2019,6 +2023,24 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         //完课后若是小程序发送另外一堂课
         saveWacthLogOfCourseLink(settings,sopLogs,newTimeString,finishLog,finishTemp);
         // 处理音频内容
+        for (QwSopCourseFinishTempSetting.Setting st : settings) {
+            if (st.getContentType().equals("7")) {
+                Long companyUserId = finishLog.getCompanyUserId();
+                QwSopTempVoice qwSopTempVoice = sopTempVoiceService.selectQwSopTempVoiceByCompanyUserIdAndVoiceTxt(companyUserId, st.getValue());
+                if (qwSopTempVoice != null && qwSopTempVoice.getVoiceUrl() != null && qwSopTempVoice.getRecordType() == 1) {
+                    st.setVoiceUrl(qwSopTempVoice.getVoiceUrl());
+                    st.setVoiceDuration(String.valueOf(qwSopTempVoice.getDuration()));
+                } else if (qwSopTempVoice == null) {
+                    if(companyUserId != null && st.getValue() != null){
+                        qwSopTempVoice = new QwSopTempVoice();
+                        qwSopTempVoice.setCompanyUserId(companyUserId);
+                        qwSopTempVoice.setVoiceTxt(st.getValue());
+                        qwSopTempVoice.setRecordType(0);
+                        sopTempVoiceService.insertQwSopTempVoice(qwSopTempVoice);
+                    }
+                }
+            }
+        }
 //        for (QwSopCourseFinishTempSetting.Setting st : settings) {
 //            if (st.getContentType().equals("7")) {
 //                try {

+ 17 - 0
fs-service/src/main/java/com/fs/company/mapper/CrmStatisticManageMapper.java

@@ -0,0 +1,17 @@
+package com.fs.company.mapper;
+
+import com.fs.company.domain.CompanyDeptUserInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @description:
+ * @author: Guos
+ * @time: 2025/11/13 下午4:27
+ */
+public interface CrmStatisticManageMapper {
+
+    List<CompanyDeptUserInfo> getSearchCompanyInfo(@Param("companyId") Long companyId);
+
+}

+ 27 - 0
fs-service/src/main/java/com/fs/company/service/ICrmStatisticManageService.java

@@ -0,0 +1,27 @@
+package com.fs.company.service;
+
+import com.fs.company.domain.CompanyDeptUserInfo;
+import com.fs.statis.dto.ComprehensiveStatisticsDTO;
+import com.fs.statis.param.ComprehensiveStatisticsParam;
+
+import java.util.List;
+
+/**
+ * @description: 销售端的统计服务
+ * @author: Guos
+ * @time: 2025/11/13 下午4:21
+ */
+public interface ICrmStatisticManageService {
+
+    Object getSearchUserInfo(Long id);
+
+    List<CompanyDeptUserInfo> getSearchCompanyInfo(Long companyId);
+
+    /**
+     * @param id
+     * @return
+     */
+    List<CompanyDeptUserInfo> getSearchDeptInfo(Long id);
+
+    List<ComprehensiveStatisticsDTO> statisticMain(ComprehensiveStatisticsParam param);
+}

+ 3 - 1
fs-service/src/main/java/com/fs/company/service/IStatisticManageService.java

@@ -1,7 +1,9 @@
 package com.fs.company.service;
 
 import com.fs.company.domain.CompanyDeptUserInfo;
+import com.fs.statis.dto.ComprehensiveStatisticsDTO;
 import com.fs.statis.param.ComprehensiveStatisticsParam;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
 import java.util.List;
@@ -18,7 +20,7 @@ public interface IStatisticManageService {
      * @param param
      * @return
      */
-    Object statisticMain(ComprehensiveStatisticsParam param);
+    List<ComprehensiveStatisticsDTO> statisticMain(ComprehensiveStatisticsParam param);
 
     /**
      * 获取搜索公司信息

+ 3 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -234,6 +234,9 @@ public class CompanyUserServiceImpl implements ICompanyUserService
 
                 Integer count=companyUserService.selectCompanyUserCountByCompanyId(copy.getCompanyId());
                 Company company=companyService.selectCompanyById(copy.getCompanyId());
+                if (company== null) {
+                    throw new CustomException("未查询到相应的销售公司!");
+                }
 
                 if(count>company.getLimitUserCount()){
                     throw new CustomException("销售公司的销售数量已达到上限!");

+ 129 - 0
fs-service/src/main/java/com/fs/company/service/impl/CrmStatisticManageServiceImpl.java

@@ -0,0 +1,129 @@
+package com.fs.company.service.impl;
+
+import com.fs.common.enums.DimensionEnum;
+import com.fs.company.domain.CompanyDeptUserInfo;
+import com.fs.company.mapper.CrmStatisticManageMapper;
+import com.fs.company.mapper.StatisticManageMapper;
+import com.fs.company.service.ICrmStatisticManageService;
+import com.fs.statis.dto.ComprehensiveStatisticsDTO;
+import com.fs.statis.param.ComprehensiveStatisticsParam;
+import com.fs.utils.MyDateUtils;
+import com.google.common.collect.Lists;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @description:
+ * @author: Guos
+ * @time: 2025/11/13 下午4:21
+ */
+@Service
+public class CrmStatisticManageServiceImpl implements ICrmStatisticManageService {
+
+    @Resource
+    private CrmStatisticManageMapper crmStatisticManageMapper;
+
+    @Resource
+    private StatisticManageMapper statisticManageMapper;
+
+    @Resource
+    private StatisticManageServiceImpl statisticManageService;
+
+    @Override
+    public Object getSearchUserInfo(Long id) {
+        return null;
+    }
+
+    @Override
+    public List<CompanyDeptUserInfo> getSearchCompanyInfo(Long companyId) {
+        return crmStatisticManageMapper.getSearchCompanyInfo(companyId);
+    }
+
+    @Override
+    public List<CompanyDeptUserInfo> getSearchDeptInfo(Long id) {
+        return statisticManageService.getSearchDeptInfo(id);
+    }
+
+    @Override
+    public List<ComprehensiveStatisticsDTO> statisticMain(ComprehensiveStatisticsParam param) {
+        if(param.getDimension() == DimensionEnum.COMPANY.getValue()){
+            List<CompanyDeptUserInfo> searchCompanyInfo =
+                    crmStatisticManageMapper.getSearchCompanyInfo(param.getCompanyId());
+            if(CollectionUtils.isEmpty(searchCompanyInfo)){return null;}
+            CompanyDeptUserInfo companyDeptUserInfo = searchCompanyInfo.get(0);
+            param.setCompanyId(companyDeptUserInfo.getCompanyId());
+            param.setCompanyName(companyDeptUserInfo.getCompanyName());
+            return getStatisticNumByCompany(param);
+        }
+        if(param.getDimension() == DimensionEnum.DEPARTMENT.getValue()){
+            Assert.notNull(param.getId(), "按部门展示查询条件不能为空!");
+            return getStatisticNumByCompanyId(param);
+        }
+        if (param.getDimension() == DimensionEnum.PERSONAL.getValue()){
+            Assert.notNull(param.getId(), "按个人展示查询条件不能为空!");
+            return getStatisticNumByDeptId(param);
+        }
+        return null;
+    }
+
+    /**
+     * 按照公司维度统计数据
+     */
+    public List<ComprehensiveStatisticsDTO> getStatisticNumByCompany(ComprehensiveStatisticsParam param) {
+        List result = Lists.newArrayList();
+        if(param.getTimeGroupFlag()){
+            List<Date> dates = MyDateUtils.generateDateList(param.getStartTime(), param.getEndTime());
+            for (Date date : dates){
+                param.setStartTime(date);
+                param.setEndTime(date);
+                performStatistic(param, date, result);
+            }
+        }else{
+            performStatistic(param, null, result);
+        }
+        return result;
+    }
+
+    //计算
+    public void performStatistic(ComprehensiveStatisticsParam param, Date date, List result) {
+        ComprehensiveStatisticsDTO statisticDataByDeptId =
+                statisticManageMapper.getStatisticDataByDeptId(param);
+        if(ObjectUtils.isEmpty(statisticDataByDeptId)){
+            statisticDataByDeptId = new ComprehensiveStatisticsDTO();
+            statisticDataByDeptId.setAnswerNum(BigDecimal.ZERO.intValue());
+            statisticDataByDeptId.setRedPacketNum(BigDecimal.ZERO.intValue());
+            statisticDataByDeptId.setSendCount(BigDecimal.ZERO.intValue());
+            statisticDataByDeptId.setRedPacketAmount(BigDecimal.ZERO);
+            statisticDataByDeptId.setCompleteNum(BigDecimal.ZERO.intValue());
+        }
+        statisticDataByDeptId.setCompanyName(param.getCompanyName());
+        statisticDataByDeptId.setCompanyId(param.getCompanyId());
+        if(date == null){
+            statisticDataByDeptId.setStatisticsTime(date);
+        }
+        result.add(statisticDataByDeptId);
+    }
+
+    /**
+     * 根据公司获取统部门的计数据
+     */
+    public List<ComprehensiveStatisticsDTO> getStatisticNumByCompanyId(ComprehensiveStatisticsParam param) {
+        return statisticManageService.getStatisticNumByCompanyId(param);
+    }
+
+    /**
+     * 根据部门id获取个人统计数据
+     */
+    public List<ComprehensiveStatisticsDTO> getStatisticNumByDeptId(ComprehensiveStatisticsParam param) {
+        return statisticManageService.getStatisticNumByDeptId(param);
+    }
+
+
+}

+ 94 - 185
fs-service/src/main/java/com/fs/company/service/impl/StatisticManageServiceImpl.java

@@ -11,10 +11,12 @@ import com.fs.company.service.IStatisticManageService;
 import java.util.function.Function;
 import com.fs.statis.dto.ComprehensiveStatisticsDTO;
 import com.fs.statis.param.ComprehensiveStatisticsParam;
+import com.fs.utils.MyDateUtils;
 import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 
@@ -28,6 +30,7 @@ import java.util.stream.Collectors;
  * @author: Guos
  * @time: 2025/10/30 上午9:21
  */
+@Lazy
 @Slf4j
 @Service
 public class StatisticManageServiceImpl implements IStatisticManageService {
@@ -44,7 +47,7 @@ public class StatisticManageServiceImpl implements IStatisticManageService {
      * @return
      */
     @Override
-    public Object statisticMain(ComprehensiveStatisticsParam param) {
+    public List<ComprehensiveStatisticsDTO> statisticMain(ComprehensiveStatisticsParam param) {
         if(param.getDimension() == DimensionEnum.COMPANY.getValue()){
             return getStatisticNumByCompany(param);
         }
@@ -62,10 +65,10 @@ public class StatisticManageServiceImpl implements IStatisticManageService {
     /**
      * 按照公司维度统计数据
      */
-    public List getStatisticNumByCompany(ComprehensiveStatisticsParam param) {
+    public List<ComprehensiveStatisticsDTO> getStatisticNumByCompany(ComprehensiveStatisticsParam param) {
         List<CompanyDeptUserInfo> companyInfo = statisticManageMapper.getCompanyInfo();
         List result = Lists.newArrayList();
-        List<Date> dates = generateDateList(param.getStartTime(), param.getEndTime());
+        List<Date> dates = MyDateUtils.generateDateList(param.getStartTime(), param.getEndTime());
         for (Date date : dates){
             param.setStartTime(date);
             param.setEndTime(date);
@@ -97,143 +100,116 @@ public class StatisticManageServiceImpl implements IStatisticManageService {
     /**
      * 根据部门id获取个人统计数据
      */
-    public List getStatisticNumByDeptId(ComprehensiveStatisticsParam param){
+    public List<ComprehensiveStatisticsDTO> getStatisticNumByDeptId(ComprehensiveStatisticsParam param){
         //先获取部门下的用户的信息
         Long id = param.getId();
         List<CompanyDeptUserInfo> searchUserInfo = statisticManageMapper.getSearchUserInfo(id);
         List result = Lists.newArrayList();
-        List<Date> dates = generateDateList(param.getStartTime(), param.getEndTime());
-        for (Date date : dates) {
-            param.setStartTime(date);
-            param.setEndTime(date);
-            for (CompanyDeptUserInfo companyDeptUserInfo : searchUserInfo) {
-                Long parentId = companyDeptUserInfo.getParentId();
-                Long deptId = companyDeptUserInfo.getDeptId();
-                if (parentId != BigDecimal.ZERO.longValue()) {
-                    Optional<CompanyDeptUserInfo> first = searchUserInfo.stream().filter(dept -> dept.getDeptId().equals(parentId)).findFirst();
-                    if (first.isPresent()){
-                        CompanyDeptUserInfo findParentDept = first.get();
-                        String parentDeptName = findParentDept.getDeptName();
-                        String deptName = companyDeptUserInfo.getDeptName();
-                        companyDeptUserInfo.setDeptName(parentDeptName + "/" + deptName);
-                    }
-                }
-                String companyName = companyDeptUserInfo.getCompanyName();
-                Long companyId = companyDeptUserInfo.getCompanyId();
-                param.setUserId(companyDeptUserInfo.getUserId());
-                ComprehensiveStatisticsDTO statisticDataByDeptId =
-                        statisticManageMapper.getStatisticDataByDeptId(param);
-                if(ObjectUtils.isEmpty(statisticDataByDeptId)){
-                    statisticDataByDeptId = new ComprehensiveStatisticsDTO();
-                    statisticDataByDeptId.setAnswerNum(BigDecimal.ZERO.intValue());
-                    statisticDataByDeptId.setRedPacketNum(BigDecimal.ZERO.intValue());
-                    statisticDataByDeptId.setSendCount(BigDecimal.ZERO.intValue());
-                    statisticDataByDeptId.setRedPacketAmount(BigDecimal.ZERO);
-                    statisticDataByDeptId.setCompleteNum(BigDecimal.ZERO.intValue());
-                }
-                statisticDataByDeptId.setCompanyUserName(companyDeptUserInfo.getNickName());
-                statisticDataByDeptId.setCompanyUserId(companyDeptUserInfo.getUserId());
-                statisticDataByDeptId.setDeptName(companyDeptUserInfo.getDeptName());
-                statisticDataByDeptId.setDeptId(deptId.intValue());
-                statisticDataByDeptId.setCompanyName(companyName);
-                statisticDataByDeptId.setCompanyId(companyId);
-                statisticDataByDeptId.setStatisticsTime(date);
-                result.add(statisticDataByDeptId);
+
+        if(param.getTimeGroupFlag()){
+            List<Date> dates = MyDateUtils.generateDateList(param.getStartTime(), param.getEndTime());
+            for (Date date : dates) {
+                param.setStartTime(date);
+                param.setEndTime(date);
+                personalDimension(param, date, searchUserInfo, result);
             }
+        }else{
+            personalDimension(param, null, searchUserInfo, result);
         }
         return result;
     }
 
-    /**
-     * 根据公司获取统部门的计数据
-     */
-    public List getStatisticNumByCompanyId(ComprehensiveStatisticsParam param){
-        //先从公司拿到公司和部门的信息
-        List<CompanyDeptUserInfo> searchDeptInfo = statisticManageMapper.getSearchDeptInfo(param.getId());;
-        List result = Lists.newArrayList();
-        List<Date> dates = generateDateList(param.getStartTime(), param.getEndTime());
-        for (Date date : dates){
-            param.setStartTime(date);
-            param.setEndTime(date);
-            for (CompanyDeptUserInfo companyDeptUserInfo : searchDeptInfo) {
-                //判断当前部门的父级id不是0就组装名称
-                Long parentId = companyDeptUserInfo.getParentId();
-                if(parentId != BigDecimal.ZERO.longValue()){
-                    String parentDeptName = searchDeptInfo.stream().filter(dept -> dept.getDeptId().equals(parentId)).findFirst().get().getDeptName();
+    private void personalDimension(ComprehensiveStatisticsParam param, Date date, List<CompanyDeptUserInfo> searchUserInfo, List result) {
+        for (CompanyDeptUserInfo companyDeptUserInfo : searchUserInfo) {
+            Long parentId = companyDeptUserInfo.getParentId();
+            Long deptId = companyDeptUserInfo.getDeptId();
+            if (parentId != BigDecimal.ZERO.longValue()) {
+                Optional<CompanyDeptUserInfo> first = searchUserInfo.stream().filter(dept -> dept.getDeptId().equals(parentId)).findFirst();
+                if (first.isPresent()){
+                    CompanyDeptUserInfo findParentDept = first.get();
+                    String parentDeptName = findParentDept.getDeptName();
                     String deptName = companyDeptUserInfo.getDeptName();
                     companyDeptUserInfo.setDeptName(parentDeptName + "/" + deptName);
                 }
-                String companyName = companyDeptUserInfo.getCompanyName();
-                Long deptId = companyDeptUserInfo.getDeptId();
-                Long companyId = companyDeptUserInfo.getCompanyId();
-                param.setDeptId(deptId);
-                ComprehensiveStatisticsDTO statisticDataByDeptId =
-                        statisticManageMapper.getStatisticDataByDeptId(param);
-                if(ObjectUtils.isEmpty(statisticDataByDeptId)){
-                    statisticDataByDeptId = new ComprehensiveStatisticsDTO();
-                    statisticDataByDeptId.setAnswerNum(BigDecimal.ZERO.intValue());
-                    statisticDataByDeptId.setRedPacketNum(BigDecimal.ZERO.intValue());
-                    statisticDataByDeptId.setSendCount(BigDecimal.ZERO.intValue());
-                    statisticDataByDeptId.setRedPacketAmount(BigDecimal.ZERO);
-                    statisticDataByDeptId.setCompleteNum(BigDecimal.ZERO.intValue());
-                }
-                statisticDataByDeptId.setDeptName(companyDeptUserInfo.getDeptName());
-                statisticDataByDeptId.setDeptId(deptId.intValue());
-                statisticDataByDeptId.setCompanyName(companyName);
-                statisticDataByDeptId.setCompanyId(companyId);
+            }
+            String companyName = companyDeptUserInfo.getCompanyName();
+            Long companyId = companyDeptUserInfo.getCompanyId();
+            param.setUserId(companyDeptUserInfo.getUserId());
+            ComprehensiveStatisticsDTO statisticDataByDeptId =
+                    statisticManageMapper.getStatisticDataByDeptId(param);
+            if(ObjectUtils.isEmpty(statisticDataByDeptId)){
+                statisticDataByDeptId = new ComprehensiveStatisticsDTO();
+                statisticDataByDeptId.setAnswerNum(BigDecimal.ZERO.intValue());
+                statisticDataByDeptId.setRedPacketNum(BigDecimal.ZERO.intValue());
+                statisticDataByDeptId.setSendCount(BigDecimal.ZERO.intValue());
+                statisticDataByDeptId.setRedPacketAmount(BigDecimal.ZERO);
+                statisticDataByDeptId.setCompleteNum(BigDecimal.ZERO.intValue());
+            }
+            statisticDataByDeptId.setCompanyUserName(companyDeptUserInfo.getNickName());
+            statisticDataByDeptId.setCompanyUserId(companyDeptUserInfo.getUserId());
+            statisticDataByDeptId.setDeptName(companyDeptUserInfo.getDeptName());
+            statisticDataByDeptId.setDeptId(deptId.intValue());
+            statisticDataByDeptId.setCompanyName(companyName);
+            statisticDataByDeptId.setCompanyId(companyId);
+            if(date != null){
                 statisticDataByDeptId.setStatisticsTime(date);
-                result.add(statisticDataByDeptId);
             }
+            result.add(statisticDataByDeptId);
         }
-        return result;
     }
 
     /**
-     * 生成开始时间到结束时间之间的每日时间数组
-     * @param startTime 开始时间
-     * @param endTime 结束时间
-     * @return 时间数组列表
+     * 根据公司获取统部门的计数据
      */
-    public List<Date> generateDateList(Date startTime, Date endTime) {
-        List<Date> dateList = new ArrayList<>();
-        if (startTime == null || endTime == null) {
-            return dateList;
-        }
-
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(startTime);
-
-        // 设置时间为当天00:00:00,确保按天计算
-        calendar.set(Calendar.HOUR_OF_DAY, 0);
-        calendar.set(Calendar.MINUTE, 0);
-        calendar.set(Calendar.SECOND, 0);
-        calendar.set(Calendar.MILLISECOND, 0);
-
-        Date currentDate = calendar.getTime();
-        Date finalEndTime = getStartOfDay(endTime);
-
-        while (!currentDate.after(finalEndTime)) {
-            dateList.add(currentDate);
-            calendar.add(Calendar.DAY_OF_MONTH, 1);
-            currentDate = calendar.getTime();
+    public List<ComprehensiveStatisticsDTO> getStatisticNumByCompanyId(ComprehensiveStatisticsParam param){
+        //先从公司拿到公司和部门的信息
+        List<CompanyDeptUserInfo> searchDeptInfo = statisticManageMapper.getSearchDeptInfo(param.getId());;
+        List result = Lists.newArrayList();
+        if(param.getTimeGroupFlag()){
+            List<Date> dates = MyDateUtils.generateDateList(param.getStartTime(), param.getEndTime());
+            for (Date date : dates){
+                param.setStartTime(date);
+                param.setEndTime(date);
+                deptDimension(param, date, searchDeptInfo, result);
+            }
+        }else{
+            deptDimension(param, null, searchDeptInfo, result);
         }
-
-        return dateList;
+        return result;
     }
 
-    /**
-     * 获取指定日期的开始时间(00:00:00)
-     * @param date 指定日期
-     * @return 当天开始时间
-     */
-    private Date getStartOfDay(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        calendar.set(Calendar.HOUR_OF_DAY, 0);
-        calendar.set(Calendar.MINUTE, 0);
-        calendar.set(Calendar.SECOND, 0);
-        calendar.set(Calendar.MILLISECOND, 0);
-        return calendar.getTime();
+    private void deptDimension(ComprehensiveStatisticsParam param, Date date, List<CompanyDeptUserInfo> searchDeptInfo, List result) {
+        for (CompanyDeptUserInfo companyDeptUserInfo : searchDeptInfo) {
+            //判断当前部门的父级id不是0就组装名称
+            Long parentId = companyDeptUserInfo.getParentId();
+            if(parentId != BigDecimal.ZERO.longValue()){
+                String parentDeptName = searchDeptInfo.stream().filter(dept -> dept.getDeptId().equals(parentId)).findFirst().get().getDeptName();
+                String deptName = companyDeptUserInfo.getDeptName();
+                companyDeptUserInfo.setDeptName(parentDeptName + "/" + deptName);
+            }
+            String companyName = companyDeptUserInfo.getCompanyName();
+            Long deptId = companyDeptUserInfo.getDeptId();
+            Long companyId = companyDeptUserInfo.getCompanyId();
+            param.setDeptId(deptId);
+            ComprehensiveStatisticsDTO statisticDataByDeptId =
+                    statisticManageMapper.getStatisticDataByDeptId(param);
+            if(ObjectUtils.isEmpty(statisticDataByDeptId)){
+                statisticDataByDeptId = new ComprehensiveStatisticsDTO();
+                statisticDataByDeptId.setAnswerNum(BigDecimal.ZERO.intValue());
+                statisticDataByDeptId.setRedPacketNum(BigDecimal.ZERO.intValue());
+                statisticDataByDeptId.setSendCount(BigDecimal.ZERO.intValue());
+                statisticDataByDeptId.setRedPacketAmount(BigDecimal.ZERO);
+                statisticDataByDeptId.setCompleteNum(BigDecimal.ZERO.intValue());
+            }
+            statisticDataByDeptId.setDeptName(companyDeptUserInfo.getDeptName());
+            statisticDataByDeptId.setDeptId(deptId.intValue());
+            statisticDataByDeptId.setCompanyName(companyName);
+            statisticDataByDeptId.setCompanyId(companyId);
+            if(date != null){
+                statisticDataByDeptId.setStatisticsTime(date);
+            }
+            result.add(statisticDataByDeptId);
+        }
     }
 
     /**
@@ -436,73 +412,6 @@ public class StatisticManageServiceImpl implements IStatisticManageService {
         return build;
     }
 
-
-//    /**
-//     * 执行定时任务
-//     * 还需要考虑在统计部门数据时,部门下面没有用户,某个时候这个部门下面又加入新的用户了,这个时候就会出现数据偏差
-//     */
-//    @Override
-//    public void executeTask() {
-//        StopWatch stopWatch = new StopWatch();
-//        stopWatch.start("gs-执行数据统计任务");
-//        List<CompanyDeptUserInfo> companyDeptdUserList = statisticManageMapper.getCompanyAndDeptAndDeptUserList(null);
-//        log.info("统计人数列表:{}", companyDeptdUserList.size());
-//        companyDeptdUserList.forEach(companyDeptUserInfo -> {
-//            CompanyDeptUserInfoDTO statisticNum =  new CompanyDeptUserInfoDTO();
-//            boolean empty = null == companyDeptUserInfo.getUserId(); //用户id为空返回true
-//            if(!empty){
-//                statisticNum = statisticManageMapper.getStatisticNum(companyDeptUserInfo.getUserId());
-//            }
-//            ComprehensiveDailyStats comprehensiveDailyStats = component(companyDeptUserInfo, statisticNum);
-//            ComprehensiveDailyStats selectResult = null;
-//            if(!empty){
-//                //用户id不为空,我们就用用户id去查询这个日期是否有数据
-//                selectResult = statisticManageMapper.selectByUserAndDate(comprehensiveDailyStats.getUserId(), comprehensiveDailyStats.getStatisticsTime());
-//            }else{
-//                //如果用户id为空,说明部门下面没有人(没人情况下,部门id只会在当天的日期中存在一条),先按照部门去查询后删除(或者直接按照id更新就可以了)
-//                selectResult = statisticManageMapper.selectByDeptAndDate(companyDeptUserInfo.getDeptId(), comprehensiveDailyStats.getStatisticsTime());
-//            }
-//            if(!ObjectUtils.isEmpty(selectResult)){
-//                comprehensiveDailyStats.setId(selectResult.getId());
-//                statisticManageMapper.updateById(comprehensiveDailyStats);
-//            }else{
-//                statisticManageMapper.insert(comprehensiveDailyStats);
-//            }
-//        });
-//        stopWatch.stop();
-//        log.info("gs-执行数据统计任务完成,耗时:{}", stopWatch.getTotalTimeSeconds());
-//    }
-//
-//    private ComprehensiveDailyStats component(CompanyDeptUserInfo source, CompanyDeptUserInfoDTO statisticNum){
-//        ComprehensiveDailyStats target = new ComprehensiveDailyStats();
-//        target.setCompanyId(source.getCompanyId());
-//        target.setCompanyName(source.getCompanyName());
-//        target.setDeptId(source.getDeptId());
-//        target.setDeptName(source.getDeptName());
-//        target.setStatisticsTime(new Date());
-//        target.setCreateTime(new Date());
-//        target.setUpdateTime(new Date());
-//        if(null != source.getUserId()){
-//            target.setUserId(source.getUserId());
-//            target.setUserName(source.getUserName());
-//            target.setNickName(source.getNickName());
-//            target.setAnswerNum(statisticNum.getAnswerNum());
-//            target.setCompleteNum(statisticNum.getCompleteNum());
-//            target.setLineNum(statisticNum.getLineNum());
-//            target.setActiveNum(statisticNum.getActiveNum());
-//            target.setRedPacketNum(statisticNum.getRedPacketNum());
-//            target.setRedPacketAmount(new BigDecimal(0.00));
-//        }else{
-//            target.setAnswerNum(0);
-//            target.setCompleteNum(0);
-//            target.setLineNum(0);
-//            target.setActiveNum(0);
-//            target.setRedPacketNum(0);
-//            target.setRedPacketAmount(new BigDecimal(0.00));
-//        }
-//      return target;
-//    }
-
 }
 
 

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

@@ -98,4 +98,7 @@ public interface FsUserCourseCategoryMapper
     @Select("select cate_id as cateId,cate_name as cateName from fs_user_course_category where is_del = 0")
     @MapKey("cateId")
     Map<Long, FsUserCourseCategory> queryAllIdKeyCategoryData();
+
+    @Select("select cate_id dict_value, cate_name dict_label  from fs_user_course_category WHERE pid = 0 and is_del=0 ")
+    List<OptionsVO> selectAllFsUserCourseCategoryPidList();
 }

+ 1 - 0
fs-service/src/main/java/com/fs/course/service/IFsUserCourseCategoryService.java

@@ -64,6 +64,7 @@ public interface IFsUserCourseCategoryService
     List<OptionsVO> selectFsUserCoursePidList();
 
     List<OptionsVO> selectFsUserCourseCategoryPidList(Integer isShow);
+    List<OptionsVO> selectFsUserCourseCategoryPidList();
     List<OptionsVO> selectFsUserCourseCategoryPidList(Long userId);
 
     List<OptionsVO> selectCateListByPid(Long pid);

+ 13 - 2
fs-service/src/main/java/com/fs/course/service/impl/FsCourseFinishTempParentServiceImpl.java

@@ -4,8 +4,11 @@ import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.utils.StringUtils;
 import com.fs.course.domain.FsCourseFinishTemp;
 import com.fs.course.domain.FsUserCourse;
 import com.fs.course.domain.FsUserCourseVideo;
@@ -13,7 +16,10 @@ import com.fs.course.service.IFsCourseFinishTempService;
 import com.fs.course.service.IFsUserCourseService;
 import com.fs.course.service.IFsUserCourseVideoService;
 import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import com.fs.course.mapper.FsCourseFinishTempParentMapper;
 import com.fs.course.domain.FsCourseFinishTempParent;
@@ -26,9 +32,13 @@ import com.fs.course.service.IFsCourseFinishTempParentService;
  * @date 2025-05-22
  */
 @Service
-@AllArgsConstructor
+@RequiredArgsConstructor
 public class FsCourseFinishTempParentServiceImpl extends ServiceImpl<FsCourseFinishTempParentMapper, FsCourseFinishTempParent> implements IFsCourseFinishTempParentService {
 
+
+    @Value("${cloud_host.company_name}")
+    private String signProjectName;
+
     private final IFsUserCourseService fsUserCourseService;
     private final IFsUserCourseVideoService fsUserCourseVideoService;
     private final IFsCourseFinishTempService fsCourseFinishTempService;
@@ -71,10 +81,11 @@ public class FsCourseFinishTempParentServiceImpl extends ServiceImpl<FsCourseFin
         List<FsUserCourseVideo> videoList = fsUserCourseVideoService.selectFsUserCourseVideoListByCourseId(fsUserCourseVideo);
         int insert = baseMapper.insert(fsCourseFinishTempParent);
         fsCourseFinishTempParent.setCreateTime(DateUtils.getNowDate());
+        Long currentStatus = "济南联志健康".equals(signProjectName) ? fsCourseFinishTempParent.getStatus() : 0L;
         videoList.forEach(e -> {
             FsCourseFinishTemp temp = new FsCourseFinishTemp();
             temp.setName(e.getFileName());
-            temp.setStatus(0L);
+            temp.setStatus(currentStatus);
             temp.setSetting(fsCourseFinishTempParent.getSetting());
             temp.setChatSetting(fsCourseFinishTempParent.getChatSetting());
             temp.setCompanyId(fsCourseFinishTempParent.getCompanyId());

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

@@ -361,7 +361,7 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
                         fsCourseRedPacketLog.setLogId(redPacket.getLogId());
                         fsCourseRedPacketLog.setStatus(1); // 已发送
                         fsCourseRedPacketLog.setUpdateTime(new Date());
-//                        updateFsCourseRedPacketLog(fsCourseRedPacketLog);
+                        updateFsCourseRedPacketLog(fsCourseRedPacketLog);
                     }
                 } catch (WxPayException e) {
                     logger.error(e.getMessage());

+ 5 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseCategoryServiceImpl.java

@@ -105,6 +105,11 @@ public class FsUserCourseCategoryServiceImpl implements IFsUserCourseCategorySer
         return fsUserCourseCategoryMapper.selectFsUserCourseCategoryPidList(isShow);
     }
 
+    @Override
+    public List<OptionsVO> selectFsUserCourseCategoryPidList() {
+        return fsUserCourseCategoryMapper.selectAllFsUserCourseCategoryPidList();
+    }
+
     @Override
     public List<OptionsVO> selectFsUserCourseCategoryPidList(Long userId) {
         return fsUserCourseCategoryMapper.selectFsUserCourseCategoryPidListByUserId(userId);

+ 17 - 3
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -604,17 +604,31 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if(qwGroupChatUsers == null || qwGroupChatUsers.isEmpty()){
             return R.error("群参数异常");
         }
-        //修改成通过昵称匹配
         QwExternalContact qwExternalContact =
                 qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
                         .eq("user_id", qwGroupChat.getOwner())
-                        .eq("name", user.getNickName())
+                        .eq("fs_user_id", param.getUserId())
                         .eq("corp_id", param.getCorpId())
                         .eq("status",0));
+        if(null == qwExternalContact){
+            try{
+                //修改成通过昵称匹配
+                qwExternalContact =
+                        qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+                                .eq("user_id", qwGroupChat.getOwner())
+                                .eq("name", user.getNickName())
+                                .eq("corp_id", param.getCorpId())
+                                .eq("status",0));
+            } catch(Exception e){
+                log.error("群聊用户昵称匹配异常,参数user_id:{},name:{},corp_id:{}",qwGroupChat.getOwner(),user.getNickName(),param.getCorpId(),e);
+            }
+
+        }
         if(qwExternalContact==null){
             return addCustomerService(param.getQwUserId(),msg);
         }
-        if(qwGroupChatUsers.stream().noneMatch(e -> e.getUserId().equals(qwExternalContact.getExternalUserId()))){
+        QwExternalContact finalQwExternalContact = qwExternalContact;
+        if(qwGroupChatUsers.stream().noneMatch(e -> e.getUserId().equals(finalQwExternalContact.getExternalUserId()))){
             log.error("客户不在群:{},里面:{}", qwGroupChat.getChatId(), qwExternalContact.getExternalUserId());
             return addCustomerService(param.getQwUserId(),msg);
         }

+ 123 - 7
fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java

@@ -21,6 +21,8 @@ import com.fs.erp.dto.df.*;
 import com.fs.erp.dto.sdk.df.DfClient;
 import com.fs.erp.dto.sdk.df.enums.RequestUrlEnum;
 import com.fs.erp.service.IErpOrderService;
+import com.fs.fastGpt.domain.FastGptRole;
+import com.fs.fastGpt.service.IFastGptRoleService;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
 import com.fs.his.enums.FsStoreOrderLogEnum;
@@ -45,9 +47,18 @@ import com.fs.hisStore.param.FsStoreAfterSalesParam;
 import com.fs.hisStore.service.IFsExpressScrmService;
 import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisStore.vo.FsStoreOrderItemVO;
+import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.domain.QwUser;
+import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.IQwExternalContactService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.fs.utils.OrderContextHolder;
+import com.fs.wxwork.dto.WxWorkResponseDTO;
+import com.fs.wxwork.dto.WxWorkSendTextMsgDTO;
+import com.fs.wxwork.dto.WxWorkUserId2VidDTO;
+import com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO;
+import com.fs.wxwork.service.WxWorkService;
 import com.hc.openapi.tool.util.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.util.Asserts;
@@ -128,6 +139,14 @@ public class DfOrderServiceImpl implements IErpOrderService {
 
     @Autowired
     private RedisCache redisCache;
+    @Autowired
+    private IQwExternalContactService externalContactService;
+    @Autowired
+    private QwUserMapper qwUserMapper;
+    @Autowired
+    private IFastGptRoleService fastGptRoleService;
+    @Autowired
+    private WxWorkService wxWorkService;
 
 
     @Override
@@ -401,7 +420,8 @@ public class DfOrderServiceImpl implements IErpOrderService {
     @Override
     public void getOrderDeliveryStatus(FsStoreOrder order) {
         Map<String, Object> map = new HashMap<>();
-        Long dfAccountId = getSFAccountIndex(order.getOrderId());
+        Long orderId = order.getOrderId();
+        Long dfAccountId = getSFAccountIndex(orderId);
         map.put("orderNumber", order.getOrderCode());
         map.put("mailNumber", order.getDeliverySn());
         try {
@@ -423,7 +443,7 @@ public class DfOrderServiceImpl implements IErpOrderService {
                 Integer deliveryStatus = 0;
                 String stateEx = "0";
                 FsStoreOrder fsStoreOrderMap = new FsStoreOrder();
-                fsStoreOrderMap.setOrderId(order.getOrderId());
+                fsStoreOrderMap.setOrderId(orderId);
                 Integer status = temp.getStatus();
                 switch (status) {
                     case 0:
@@ -469,7 +489,7 @@ public class DfOrderServiceImpl implements IErpOrderService {
                         Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
                         Object isUpdateOrder = config.get("isUpdateOrder");
                         if (isUpdateOrder == null || "1".equals(isUpdateOrder.toString())) {
-                            fsStoreOrderService.getGoods(order.getOrderId(), "物流自动");
+                            fsStoreOrderService.getGoods(orderId, "物流自动");
                         }
                         break;
                     case 10:
@@ -484,6 +504,16 @@ public class DfOrderServiceImpl implements IErpOrderService {
                         }
                         break;
                 }
+
+
+                //判断物流状态是否更新 更新ai发送物流给客户
+                try {
+                    aiSendExpress(order, stateEx);
+                } catch (Exception e) {
+                    log.error("ai发送物流信息错误:{}", e.getMessage());
+                }
+
+
                 fsStoreOrderMap.setDeliveryStatus(deliveryStatus); //物流状态:0-暂无轨迹信息 1-已揽收 2-在途中,3-签收,4-问题件
                 fsStoreOrderMap.setDeliveryType(stateEx);
                 fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrderMap);
@@ -493,6 +523,91 @@ public class DfOrderServiceImpl implements IErpOrderService {
         }
     }
 
+    private void aiSendExpress(FsStoreOrder order, String stateEx) {
+        Long orderId = order.getOrderId();
+        if (!Objects.equals(order.getDeliveryType(), stateEx)) {
+            //判断是否添加相关企微员工
+            if(order.getUserId() != null){
+                List<QwExternalContact> qwExternalContact = externalContactService.selectQwExternalContactByFsUserIdAndCompany(order.getUserId(), order.getCompanyUserId());
+                if(qwExternalContact != null && !qwExternalContact.isEmpty()) {
+                    for (QwExternalContact externalContact : qwExternalContact) {
+                        Long qwUserId = externalContact.getQwUserId();
+                        if (qwUserId != null) {
+                            QwUser qwUser = qwUserMapper.selectQwUserById(qwUserId);
+                            if (qwUser != null && qwUser.getUid() != null && qwUser.getFastGptRoleId() != null && qwUser.getServerId() != null && qwUser.getServerStatus() == 1 && qwUser.getIpadStatus() == 1) {
+                                FastGptRole fastGptRole = fastGptRoleService.selectFastGptRoleByRoleId(qwUser.getFastGptRoleId());
+                                if (fastGptRole.getLogistics() == 0) {
+                                    log.error("物流功能未开启,roleId:" + qwUser.getFastGptRoleId() + "订单号:" + orderId);
+                                }
+                                WxWorkUserId2VidDTO wxWorkUserId2VidDTO = new WxWorkUserId2VidDTO();
+                                wxWorkUserId2VidDTO.setOpenid(Collections.singletonList(externalContact.getExternalUserId()));
+                                wxWorkUserId2VidDTO.setUuid(qwUser.getUid());
+                                WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.UserId2Vid(wxWorkUserId2VidDTO, qwUser.getServerId());
+                                List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
+                                StringBuilder sBuilder = new StringBuilder();
+                                if (data != null && !data.isEmpty()) {
+                                    Long sendId = data.get(0).getUser_id();
+                                    switch (order.getStatus()) {
+                                        case -1:
+                                            break;
+                                        case -2:
+                                            break;
+                                        case 1:
+                                            break;
+                                        case 2:
+                                            sBuilder.append("您好,您有一个包裹正在准备发货,请耐心等待;\n");
+                                            if (order.getDeliverySn() != null && !order.getDeliverySn().isEmpty()) {
+                                                sBuilder.append(" 物流单号为:").append(order.getDeliverySn()).append("\n");
+                                            }
+                                            sBuilder.append("\uD83C\uDF39\uD83C\uDF39\uD83C\uDF39");
+                                            break;
+                                        case 3:
+                                            if ("202".equals(stateEx)) {
+                                                //211
+                                                //你好,这边查询到您购买的XXX(购买套餐)在XXX(时间)已经送到了,送货员电话为XXX(送货员信息)
+                                                ErpDeliverysRequest erpDeliverysRequest = new ErpDeliverysRequest();
+                                                erpDeliverysRequest.setCode(order.getOrderCode());
+                                                ErpDeliverysResponse express = null;
+                                                express = getDeliver(erpDeliverysRequest);
+                                                sBuilder.append("这边查询到您有一个包裹 ");
+                                                if (express != null && express.getDeliverys() != null && !express.getDeliverys().isEmpty()) {
+                                                    List<ErpDeliverys> deliverys = express.getDeliverys();
+                                                    ErpDeliverys tracesDTO = deliverys.get(deliverys.size() - 1);
+                                                    String remark = tracesDTO.getRemark();
+                                                    if ("派送至".equals(remark)) {
+                                                        sBuilder.append(" 在").append(tracesDTO.getAcceptTime()).append("已经送到了\n");
+                                                        sBuilder.append(" 物流单号为:").append(order.getDeliverySn()).append("\n");
+                                                        sBuilder.append("物流信息:").append(remark).append("\n");
+                                                    }
+                                                } else {
+                                                    sBuilder.append(" 已经送到了\n");
+                                                }
+                                                sBuilder.append("\uD83C\uDF39\uD83C\uDF39\uD83C\uDF39");
+                                            }
+                                            break;
+                                        case 4:
+                                        case 5:
+                                    }
+                                    if (!"".contentEquals(sBuilder)) {
+                                        //2.发送模板中的文字内容
+                                        String content = sBuilder.toString();
+                                        content = content.replace("(有事呼叫我,勿找平台,少一次投诉,多一份感恩)", "");
+                                        WxWorkSendTextMsgDTO wxWorkSendTextMsgDTO = new WxWorkSendTextMsgDTO();
+                                        wxWorkSendTextMsgDTO.setSend_userid(sendId);
+                                        wxWorkSendTextMsgDTO.setUuid(qwUser.getUid());
+                                        wxWorkSendTextMsgDTO.setContent(content);
+                                        wxWorkSendTextMsgDTO.setIsRoom(false);
+                                        wxWorkService.SendTextMsg(wxWorkSendTextMsgDTO, qwUser.getServerId());
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public void getOrderScrmDeliveryStatus(FsStoreOrderScrm order) {
         Map<String, Object> map = new HashMap<>();
@@ -589,6 +704,7 @@ public class DfOrderServiceImpl implements IErpOrderService {
     }
 
     private void cancelOrder(FsStoreOrder order) {
+        Long orderId = order.getOrderId();
         Integer deliveryStatus = order.getDeliveryStatus();
         if (deliveryStatus == null || deliveryStatus == 0) {
             //没有物流信息
@@ -597,21 +713,21 @@ public class DfOrderServiceImpl implements IErpOrderService {
             order.setExtendOrderId("");
             order.setDeliverySn("");
             fsStoreOrderMapper.updateFsStoreOrder(order);
-            fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.UPDATE_ORDER_DF.getValue(),
+            fsStoreOrderLogsService.create(orderId, FsStoreOrderLogEnum.UPDATE_ORDER_DF.getValue(),
                     "运单不存在," + FsStoreOrderLogEnum.UPDATE_ORDER_DF.getDesc());
         } else {
             //有物流信息->售后处理
             //取消订单
             FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
-            afterSalesParam.setOrderId(order.getOrderId());
+            afterSalesParam.setOrderId(orderId);
             afterSalesParam.setReasons("代服管家取消订单");
             afterSalesParam.setOperator("代服管家");
             fsStoreOrderService.afterSales(afterSalesParam);
-            fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.REFUND_ORDER_DF.getValue(),
+            fsStoreOrderLogsService.create(orderId, FsStoreOrderLogEnum.REFUND_ORDER_DF.getValue(),
                     "运单不存在," + FsStoreOrderLogEnum.REFUND_ORDER_DF.getDesc());
         }
         FsStoreOrderDf df = new FsStoreOrderDf();
-        df.setOrderId(order.getOrderId());
+        df.setOrderId(orderId);
         df.setStatus(2);
         df.setUpdateTime(new Date());
         fsStoreOrderDfMapper.updateFsStoreOrderDf(df);

+ 5 - 0
fs-service/src/main/java/com/fs/his/domain/FsUser.java

@@ -155,6 +155,11 @@ public class FsUser extends BaseEntity
 
     /** 下单次数 */
     private Long orderCount;
+
+    /** 累计成交总额 */
+    @Excel(name = "累计成交总额")
+    private BigDecimal totalAmount;
+
     /**
      * 企微销售ID
      * **/

+ 3 - 0
fs-service/src/main/java/com/fs/his/mapper/FsStorePaymentMapper.java

@@ -335,4 +335,7 @@ public interface FsStorePaymentMapper
     List<FsStorePaymentVO> selectFsStorePaymentListQueryVO(@Param("maps") FsStorePaymentParam fsStorePayment);
 
     FsStorePayment selectLastByBusinessCode(@Param("orderSn")String orderSn);
+
+    @Select(" select  * from fs_store_payment where status = 0 ")
+    List<FsStorePayment> selectAllPayment();
 }

+ 9 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -1,5 +1,6 @@
 package com.fs.his.mapper;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
@@ -456,4 +457,12 @@ public interface FsUserMapper
     @Update("update fs_user set pay_count=pay_count+1" +
             " where user_id=#{userId}")
     void incPayCount(Long aLong);
+
+    /**
+     * 更新用户下单次数和累计成交总额
+     * @param userId 用户ID
+     * @param amount 成交金额
+     */
+    @Update("update fs_user set order_count = order_count + 1, total_amount = IFNULL(total_amount, 0) + #{amount} where user_id = #{userId}")
+    void updateUserOrderCountAndAmount(@Param("userId") Long userId, @Param("amount") BigDecimal amount);
 }

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

@@ -137,4 +137,6 @@ public interface IFsStorePaymentService
     String payConfirm(String payCode,String tradeNo,String bankTransactionId,String bankSerialNo);
 
     void synchronizePayStatus();
+
+    List<FsStorePayment> selectAllPayment();
 }

+ 1 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -846,7 +846,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
         Map<String, Object> packageJson = (Map) JSON.parse(packageOrder.getPackageJson());
         Integer packageSubType = (Integer) packageJson.get("packageSubType");
-        if (packageSubType == 3) {
+        if (packageSubType == 3 && !CloudHostUtils.hasCloudHostName("金牛明医")) {
             inquiryOrderService.createOrderByPackageOrderStatus4(packageOrder);
         }
         Long prescribeId = fsPrescribeService.insertFsPrescribeByPackageOrder(packageOrder);

+ 15 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -214,6 +214,9 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
     @Autowired
     private ICompanyDivItemService companyDivItemService;
 
+    @Value("${cloud_host.company_name}")
+    private String signProjectName;
+
     /**
      * 红包账户锁
      */
@@ -649,6 +652,13 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             return result;
         }catch (Exception e){
             logger.error("领取红包失败原因:{}", ExceptionUtils.getMessage(e),e);
+            if (e instanceof WxPayException && "济南联志健康".equals(signProjectName)) {
+                WxPayException wxPayException = (WxPayException) e;
+                String customErrorMsg = wxPayException.getCustomErrorMsg();
+                if (null != customErrorMsg && customErrorMsg.startsWith("商户运营账户资金不足")) {
+                    return R.error("[红包领取] 账户余额不足,请联系管理员!");
+                }
+            }
             throw new RuntimeException(e);
         }finally {
             if (lock.isHeldByCurrentThread()) {
@@ -1603,6 +1613,11 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         }
     }
 
+    @Override
+    public List<FsStorePayment> selectAllPayment() {
+        return fsStorePaymentMapper.selectAllPayment();
+    }
+
     @Override
     public R paymentByWxaCode(FsStorePaymentPayParam param) {
         FsUser user = userMapper.selectFsUserById(param.getUserId());

+ 2 - 2
fs-service/src/main/java/com/fs/live/domain/LiveCoupon.java

@@ -59,8 +59,8 @@ public class LiveCoupon extends BaseEntity
     @Excel(name = "套餐分类ids")
     private String packageCateIds;
 
-    /** 优惠券类型 0-通用 1-商品券 2-无门槛券 */
-    @Excel(name = "优惠券类型 0-通用 1-商品券 2-无门槛券")
+    /** 优惠券类型 0-普通 1-套餐 2-制单 3.无门槛 */
+    @Excel(name = "优惠券类型")
     private Long type;
 
     /** 是否删除 */

+ 4 - 0
fs-service/src/main/java/com/fs/live/domain/LiveCouponIssue.java

@@ -69,4 +69,8 @@ public class LiveCouponIssue extends BaseEntity
     private BigDecimal useMinPrice;
     private Long couponTime;
 
+    /** 限制领取次数(针对无门槛优惠券,每个用户可以领取的最大张数) */
+    @Excel(name = "限制领取次数")
+    private Integer limitReceiveCount;
+
 }

+ 9 - 0
fs-service/src/main/java/com/fs/live/domain/LiveOrder.java

@@ -335,6 +335,15 @@ public class LiveOrder extends BaseEntity {
 
     /** 优惠券金额 */
     private BigDecimal couponPrice;
+    // 卓美新增筛选条件
+    private String productName;
+    private String productSpec;
+    private String productNum;
+    private Date createTimeStart;
+    private Date createTimeEnd;
+
+    private Integer price;
+    private Integer cost;
 
 
 }

+ 85 - 0
fs-service/src/main/java/com/fs/live/dto/LiveOrderCustomerExportDTO.java

@@ -0,0 +1,85 @@
+package com.fs.live.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 直播订单客户导出DTO
+ * 
+ * @author fs
+ * @date 2025-11-13
+ */
+@Data
+public class LiveOrderCustomerExportDTO {
+
+    /** 销售id */
+    @Excel(name = "销售ID")
+    private Long companyUserId;
+
+    /** 绑定销售昵称 */
+    @Excel(name = "销售昵称")
+    private String companyUserNickName;
+
+    /** 客户编码 */
+    @Excel(name = "客户编码")
+    private String customerCode;
+
+    /** 会员等级 */
+    @Excel(name = "会员等级")
+    private Integer userLevel;
+
+    /** 销售绑定手机号 */
+    @Excel(name = "销售手机号")
+    private String companyUserPhone;
+
+    /** 销售创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "销售创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date companyUserCreateTime;
+
+    /** 客户id */
+    @Excel(name = "客户ID")
+    private Long userId;
+
+    /** 客户昵称 */
+    @Excel(name = "客户昵称")
+    private String nickName;
+
+    /** 客户绑定手机号 */
+    @Excel(name = "客户手机号")
+    private String userPhone;
+
+    /** 收货手机号 */
+    @Excel(name = "收货手机号")
+    private String receivePhone;
+
+    /** 累计成交笔数 */
+    @Excel(name = "累计成交笔数")
+    private Long totalOrderCount;
+
+    /** 累计成交总额 */
+    @Excel(name = "累计成交总额", cellType = Excel.ColumnType.NUMERIC)
+    private BigDecimal totalOrderAmount;
+
+    /** 最新绑定时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "最新绑定时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date latestBindTime;
+
+    /** 客户状态 */
+    @Excel(name = "客户状态", dictType = "user_status")
+    private Integer userStatus;
+
+    /** 所属店铺 */
+    @Excel(name = "所属店铺ID")
+    private Long storeId;
+
+    /** 所属店铺名称 */
+    @Excel(name = "所属店铺名称")
+    private String storeName;
+}
+

+ 1 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveAfterSalesMapper.java

@@ -123,7 +123,7 @@ public interface LiveAfterSalesMapper {
             "</if>" +
             "order by create_time desc "+
             "</script>"})
-    List<LiveAfterSalesQueryVO> selectLiveAfterSalesListQuery(LiveAfterSalesQueryParam param);
+    List<LiveAfterSalesQueryVO> selectLiveAfterSalesListQuery(@Param("maps") LiveAfterSalesQueryParam param);
 
     @Select({"<script> " +
             "select ifnull(count(1),0) from live_after_sales   " +

+ 1 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveCouponUserMapper.java

@@ -68,7 +68,7 @@ public interface LiveCouponUserMapper
     @Select("<script>" +
             "select lcu.* from live_coupon_user lcu where lcu.user_id= #{coupon.userId} " +
             " <if test='coupon.goodsId != null'>" +
-            " and lcu.goods_id= #{coupon.goodsId}" +
+            " and (lcu.goods_id= #{coupon.goodsId} or lcu.goods_id is null or lcu.goods_id = 0)" +
             " </if>" +
             "</script>")
     List<LiveCouponUser> curCoupon(@Param("coupon") CouponPO coupon);

+ 1 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java

@@ -155,6 +155,6 @@ public interface LiveGoodsMapper {
      * @param goodsId 商品ID
      * @param status 状态:1-上架 0-下架
      */
-    @Update("update live_goods set is_show = #{status} where goods_id = #{goodsId}")
+    @Update("update live_goods set status = #{status} where goods_id = #{goodsId}")
     void updateLiveGoodsStatus(@Param("goodsId") Long goodsId, @Param("status") Integer status);
 }

+ 1 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveMsgMapper.java

@@ -81,7 +81,7 @@ public interface LiveMsgMapper
             "    SUM(CASE WHEN live_flag = 1 THEN 1 ELSE 0 END) AS liveCommentNum, " +
             "    SUM(CASE WHEN replay_flag = 1 THEN 1 ELSE 0 END) AS replayCommentNum " +
             "FROM live_msg WHERE live_id = #{liveId}")
-    Map<String, Long> selectDashboardCount(@Param("liveId") Long liveId);
+    Map<String, BigDecimal> selectDashboardCount(@Param("liveId") Long liveId);
 
     List<LiveMsg> selectLiveMsgSingleList(LiveMsg liveMsg);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java

@@ -421,4 +421,7 @@ public interface LiveOrderMapper {
             "where o.user_id=#{userId}  and o.status =#{status} " +
             "</script>"})
     Integer selectLiveOrderCount(long userId, int status);
+
+
+    List<LiveOrderVoZm> selectLiveOrderListZm(LiveOrder liveOrder);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java

@@ -231,4 +231,7 @@ public interface ILiveOrderService {
     Integer selectFsStoreOrderCount(long l, int i);
 
     R payConfirmReward(LiveOrder liveOrder);
+
+
+    List<LiveOrderVoZm> selectLiveOrderListZm(LiveOrder liveOrder);
 }

+ 10 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java

@@ -170,7 +170,16 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         }
         Long couponId = Long.valueOf(payload.get("couponId").toString());
         LiveCouponIssueRelation liveCouponIssueRelation = liveCouponMapper.selectRelation(liveId,couponId);
-        if(ObjectUtil.isEmpty(liveCouponIssueRelation.getGoodsId())) return R.error("未绑定商品,无法发布!");
+
+        // 查询优惠券类型
+        LiveCoupon liveCoupon = liveCouponMapper.selectLiveCouponById(couponId);
+        boolean isNoThresholdCoupon = liveCoupon != null && liveCoupon.getType() != null && liveCoupon.getType() == 3L;
+
+        // 如果不是无门槛优惠券,需要检查是否绑定了商品
+        if (!isNoThresholdCoupon && ObjectUtil.isEmpty(liveCouponIssueRelation.getGoodsId())) {
+            return R.error("未绑定商品,无法发布!");
+        }
+
         liveCouponMapper.updateShow(liveId, couponId, isShow ? 1 : 0);
         return R.ok("操作成功");
     }

+ 26 - 26
fs-service/src/main/java/com/fs/live/service/impl/LiveDataServiceImpl.java

@@ -77,56 +77,56 @@ public class LiveDataServiceImpl implements ILiveDataService {
         // 查询观看和点赞数据(直播和回放)
         Map<String, Integer> liveDataMap = baseMapper.selectDashboardCount(liveId);
         // 查询评论数据(直播和回放)
-        Map<String, Long> msgMap = liveMsgMapper.selectDashboardCount(liveId);
+        Map<String, BigDecimal> msgMap = liveMsgMapper.selectDashboardCount(liveId);
         // 查询分享和直接访问数据
         Map<String, BigDecimal> firstEntryMap = liveUserFirstEntryMapper.selectDashboardCount(liveId);
-        
+
         LiveDashBoardDataVo result = new LiveDashBoardDataVo();
-        
+
         // 在线人数
-        result.setOnlineNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+        result.setOnlineNum(watchUserMap == null ? BigDecimal.valueOf(0) :
             watchUserMap.getOrDefault("onlineNum", BigDecimal.valueOf(0)));
-        
+
         // 直播用户数据
-        result.setLiveNewUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+        result.setLiveNewUserNum(watchUserMap == null ? BigDecimal.valueOf(0) :
             watchUserMap.getOrDefault("liveNewUserNum", BigDecimal.valueOf(0)));
-        result.setLiveOldUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+        result.setLiveOldUserNum(watchUserMap == null ? BigDecimal.valueOf(0) :
             watchUserMap.getOrDefault("liveOldUserNum", BigDecimal.valueOf(0)));
-        
+
         // 回放用户数据
-        result.setReplayNewUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+        result.setReplayNewUserNum(watchUserMap == null ? BigDecimal.valueOf(0) :
             watchUserMap.getOrDefault("replayNewUserNum", BigDecimal.valueOf(0)));
-        result.setReplayOldUserNum(watchUserMap == null ? BigDecimal.valueOf(0) : 
+        result.setReplayOldUserNum(watchUserMap == null ? BigDecimal.valueOf(0) :
             watchUserMap.getOrDefault("replayOldUserNum", BigDecimal.valueOf(0)));
-        
+
         // 直播观看和点赞数据
-        result.setLiveViewNum(liveDataMap == null ? 0 : 
+        result.setLiveViewNum(liveDataMap == null ? 0 :
             liveDataMap.getOrDefault("liveViewNum", 0));
-        result.setLiveLikeNum(liveDataMap == null ? 0 : 
+        result.setLiveLikeNum(liveDataMap == null ? 0 :
             liveDataMap.getOrDefault("liveLikeNum", 0));
-        
+
         // 回放观看和点赞数据
-        result.setReplayViewNum(liveDataMap == null ? 0 : 
+        result.setReplayViewNum(liveDataMap == null ? 0 :
             liveDataMap.getOrDefault("replayViewNum", 0));
-        result.setReplayLikeNum(liveDataMap == null ? 0 : 
+        result.setReplayLikeNum(liveDataMap == null ? 0 :
             liveDataMap.getOrDefault("replayLikeNum", 0));
-        
+
         // 直播和回放评论数据
-        result.setLiveCommentNum(msgMap == null ? 0L : 
-            msgMap.getOrDefault("liveCommentNum", 0L));
-        result.setReplayCommentNum(msgMap == null ? 0L : 
-            msgMap.getOrDefault("replayCommentNum", 0L));
-        
+        result.setLiveCommentNum(msgMap == null ? BigDecimal.valueOf(0) :
+            msgMap.getOrDefault("liveCommentNum", BigDecimal.valueOf(0)));
+        result.setReplayCommentNum(msgMap == null ? BigDecimal.valueOf(0) :
+            msgMap.getOrDefault("replayCommentNum", BigDecimal.valueOf(0)));
+
         // 分享和直接访问数据
-        result.setShareUrlNum(firstEntryMap == null ? BigDecimal.valueOf(0) : 
+        result.setShareUrlNum(firstEntryMap == null ? BigDecimal.valueOf(0) :
             firstEntryMap.getOrDefault("shareUrlNum", BigDecimal.valueOf(0)));
-        result.setDirectAccessNum(firstEntryMap == null ? BigDecimal.valueOf(0) : 
+        result.setDirectAccessNum(firstEntryMap == null ? BigDecimal.valueOf(0) :
             firstEntryMap.getOrDefault("directAccessNum", BigDecimal.valueOf(0)));
-        
+
         // 邀请用户列表
         List<LiveUserFirstVo> liveUserFirstVos = liveUserFirstEntryMapper.selectDashboardInviteCount(liveId);
         result.setInviteUserList(liveUserFirstVos);
-        
+
         return R.ok().put("data", result);
     }
 

+ 8 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -77,6 +77,7 @@ import com.fs.hisStore.vo.FsStoreOrderItemVO;
 import com.fs.hisStore.vo.FsStoreOrderVO;
 import com.fs.live.domain.*;
 import com.fs.live.dto.LiveOrderComputeDTO;
+import com.fs.live.dto.LiveOrderCustomerExportDTO;
 import com.fs.live.dto.LiveOrderItemDTO;
 import com.fs.live.mapper.*;
 import com.fs.live.param.*;
@@ -2456,6 +2457,8 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
             }
             //增加用户购买次数
             userMapper.incPayCount(Long.valueOf(liveOrder.getUserId()));
+            //更新用户下单次数和累计成交总额
+            userMapper.updateUserOrderCountAndAmount(Long.valueOf(liveOrder.getUserId()), liveOrder.getPayMoney());
 
             liveOrder.setStatus(2);
             liveOrder.setPayTime(LocalDateTime.now());
@@ -2475,6 +2478,11 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         }
     }
 
+    @Override
+    public List<LiveOrderVoZm> selectLiveOrderListZm(LiveOrder liveOrder) {
+        return baseMapper.selectLiveOrderListZm(liveOrder);
+    }
+
 
     @Override
     @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)

+ 1 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveRedConfServiceImpl.java

@@ -192,7 +192,7 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
             return R.error("您已经领取过红包了!");
         }
         /*try {*/
-/*            //获取红包锁
+/*            //获取红包锁w
             if (!tryLock(claimKey, red.getUserId().toString(), 5)) {
                 return R.error("您已经领取过红包了!");
             }*/

+ 17 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java

@@ -750,6 +750,7 @@ public class LiveServiceImpl implements ILiveService
         List<LiveAutoTask> goodsTaskList = liveAutoTasksList.stream().filter(liveAutoTask -> liveAutoTask.getTaskType() == 1L).collect(Collectors.toList());
         List<LiveAutoTask> redTaskList = liveAutoTasksList.stream().filter(liveAutoTask -> liveAutoTask.getTaskType() == 2L).collect(Collectors.toList());
         List<LiveAutoTask> lotteryTaskList = liveAutoTasksList.stream().filter(liveAutoTask -> liveAutoTask.getTaskType() == 4L).collect(Collectors.toList());
+        List<LiveAutoTask> shelfTaskList = liveAutoTasksList.stream().filter(liveAutoTask -> liveAutoTask.getTaskType() == 6L).collect(Collectors.toList());
         List<LiveAutoTask> addList = new ArrayList<>();
         if (!barrageTask.isEmpty()) {
             for (LiveAutoTask liveAutoTask : barrageTask) {
@@ -868,6 +869,22 @@ public class LiveServiceImpl implements ILiveService
                 liveAutoTaskEntity.setContent(JSON.toJSONString(liveGoods));
                 liveAutoTaskService.directInsertLiveAutoTask(liveAutoTaskEntity);
 
+                // 处理上下架任务 taskType=6
+                LiveAutoTask shelfTask = shelfTaskList.stream().filter(item -> parseIdFromContent(item.getContent(), "goodsId").equals(liveGoods.getGoodsId())).findFirst().orElse(null);
+                if(shelfTask != null) {
+                    LiveAutoTask shelfAutoTaskEntity = new LiveAutoTask();
+                    BeanUtils.copyBeanProp(shelfAutoTaskEntity, shelfTask);
+                    shelfAutoTaskEntity.setId(null);
+                    shelfAutoTaskEntity.setLiveId(newLiveId);
+                    shelfAutoTaskEntity.setCreateTime(now);
+                    shelfAutoTaskEntity.setUpdateTime(now);
+                    shelfAutoTaskEntity.setFinishStatus(0L);
+                    // 更新content中的goodsId为新的goodsId
+                    JSONObject contentJson = JSON.parseObject(shelfTask.getContent());
+                    contentJson.put("goodsId", liveGoodsEntity.getGoodsId());
+                    shelfAutoTaskEntity.setContent(contentJson.toJSONString());
+                    liveAutoTaskService.directInsertLiveAutoTask(shelfAutoTaskEntity);
+                }
             }
         }
         for (LiveCouponIssueRelation liveCouponIssueRelation : liveCouponIssueRelations) {

+ 2 - 2
fs-service/src/main/java/com/fs/live/vo/LiveDashBoardDataVo.java

@@ -24,10 +24,10 @@ public class LiveDashBoardDataVo {
     private Integer replayLikeNum;
 
     // 直播评论数量 liveMsg
-    private Long liveCommentNum;
+    private BigDecimal liveCommentNum;
 
     // 回放评论数量 liveMsg
-    private Long replayCommentNum;
+    private BigDecimal replayCommentNum;
 
     // 直播新用户数量 liveWatchUser
     private BigDecimal liveNewUserNum;

+ 2 - 0
fs-service/src/main/java/com/fs/live/vo/LiveDataListVo.java

@@ -72,3 +72,5 @@ public class LiveDataListVo {
 }
 
 
+
+

+ 2 - 0
fs-service/src/main/java/com/fs/live/vo/LiveDataStatisticsVo.java

@@ -53,3 +53,5 @@ public class LiveDataStatisticsVo {
 }
 
 
+
+

+ 59 - 0
fs-service/src/main/java/com/fs/live/vo/LiveMsgVo.java

@@ -0,0 +1,59 @@
+package com.fs.live.vo;
+
+
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 直播讨论对象 live_msg
+ *
+ * @author fs
+ * @date 2025-01-17
+ */
+@Data
+public class LiveMsgVo {
+
+    /** id */
+
+    private Long msgId;
+
+    /** 直播ID */
+    @Excel(name = "直播ID")
+    private Long liveId;
+
+    /** 用户ID */
+    @Excel(name = "用户ID")
+    private Long userId;
+
+    /** 用户ID */
+    @Excel(name = "用户ID")
+    private String nickName;
+
+    /** 用户ID */
+    @Excel(name = "用户ID")
+    private String avatar;
+
+    /** 消息 */
+    @Excel(name = "消息")
+    private String msg;
+
+    @TableField(exist = false)
+    private Integer singleVisible;
+
+    /** 直播消息标记:0-否 1-是 */
+    @Excel(name = "直播消息标记")
+    private Integer liveFlag = 0;
+
+    /** 回放消息标记:0-否 1-是 */
+    @Excel(name = "回放消息标记")
+    private Integer replayFlag = 0;
+
+    private String endTime;
+}

+ 467 - 0
fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java

@@ -0,0 +1,467 @@
+package com.fs.live.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 订单对象 live_order
+ *
+ * @author fs
+ * @date 2025-07-08
+ */
+@Data
+public class LiveOrderVoZm{
+
+    /** 订单ID */
+    private Long orderId;
+
+    /** 公司员工id */
+    @Excel(name = "销售id")
+    private Long companyUserId;
+
+    /** 绑定销售昵称 */
+    @Excel(name = "绑定销售昵称")
+    private String companyUserNickName;
+
+    /** 客户编码 */
+//    @Excel(name = "客户编码")
+    private String userCode;
+
+    /** 会员等级 */
+    @Excel(name = "会员等级")
+    private Integer userLevel;
+
+
+    /** 销售绑定手机号 */
+    @Excel(name = "销售手机号")
+    private String companyUserPhone;
+
+    /** 销售加入时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "销售加入时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date companyUserCreateTime;
+
+
+    /** 用户id */
+    @Excel(name = "客户ID")
+    private String userId;
+
+    /** 客户昵称 */
+    @Excel(name = "客户昵称")
+    private String nickName;
+
+    /** 客户绑定手机号 */
+    @Excel(name = "客户手机号")
+    private String userBindPhone;
+
+    /** 收货人电话 */
+    @Excel(name = "收货手机号")
+    private String userPhone;
+
+
+    /** 累计成交笔数 */
+    @Excel(name = "累计成交笔数")
+    private Long totalOrderCount;
+
+
+
+    /** 累计成交总额 */
+    @Excel(name = "累计成交总额", cellType = Excel.ColumnType.NUMERIC)
+    private BigDecimal totalOrderAmount;
+
+    /** 最新绑定时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "最新绑定时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date latestBindTime;
+
+
+    /** 客户状态 */
+    @Excel(name = "客户状态")
+    private Integer userStatus;
+
+    @Excel(name = "所属店铺")
+    private Long storeId;
+
+
+    /** 所属门店名称 */
+    @Excel(name = "所属店铺名称")
+    private String storeName;
+
+    @Excel(name = "商品ID")
+    private Long productId;
+
+    /** 商品名称 */
+    @Excel(name = "商品名称")
+    private String productName;
+
+
+    /** 商品规格 */
+    @Excel(name = "商品规格")
+    private String productSpec;
+
+    /** 订单商品总数 */
+    @Excel(name = "商品数量")
+    private String totalNum;
+
+    @Excel(name = "销售价格")
+    private BigDecimal price;
+
+    @Excel(name = "成本价格")
+    private BigDecimal cost;
+
+    /** 详细地址 */
+    @Excel(name = "收货地址")
+    private String userAddress;
+
+    /** 支付时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime payTime;
+
+
+
+
+    /** 直播ID */
+//    @Excel(name = "直播ID")
+    private Long liveId;
+
+
+
+
+
+    /** 订单号 */
+//    @Excel(name = "订单号")
+    private String orderCode;
+
+
+    /** 收货人 */
+//    @Excel(name = "收货人")
+    private String userName;
+
+
+
+
+    /** 购物车id */
+//    @Excel(name = "购物车id")
+    private String cartId;
+
+
+
+    /** 订单总价 */
+//    @Excel(name = "订单总价")
+    private BigDecimal totalPrice;
+
+    /** 实际支付金额 */
+//    @Excel(name = "实际支付金额")
+    private BigDecimal payPrice;
+
+    /** 支付金额 */
+//    @Excel(name = "支付金额")
+    private BigDecimal payMoney;
+
+    /** 支付状态 待支付 1已支付 */
+//    @Excel(name = "支付状态 待支付 1已支付")
+    private String isPay;
+
+    /** 取消理由*/
+//    @Excel(name = "取消理由")
+    private String cancelReason;
+
+
+
+    // 支付开始时间
+    private String payStartTime;
+    // 支付结束时间
+    private String payEndTime;
+
+    /** 支付方式 1微信 */
+//    @Excel(name = "支付方式 1微信")
+    private String payType;
+
+    /** 订单状态(-1 : 申请退款 -2 : 退货成功 0:已取消 1:待支付 2:待发货;3:待收货;4:待评价;5:已完成) */
+    @Excel(name = "订单状态",dictType="sys_order_status")
+    private Integer status;
+
+    /** 对应供应商 */
+    @Excel(name = "对应供应商")
+    private String supplierName;
+
+    /** 0 未退款 1 申请中 2 已退款 */
+//    @Excel(name = "0 未退款 1 申请中 2 已退款")
+    private String refundStatus;
+    /** 收货人 */
+//    @Excel(name = "收货人")
+    private String realName;
+
+
+    /** 退款图片 */
+//    @Excel(name = "退款图片")
+    private String refundImg;
+
+    /** 退款用户说明 */
+//    @Excel(name = "退款用户说明")
+    private String refundExplain;
+
+    /** 退款时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+//    @Excel(name = "退款时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date refundTime;
+
+    /** 不退款的理由 */
+//    @Excel(name = "不退款的理由")
+    private String refundReason;
+
+    /** 退款金额 */
+//    @Excel(name = "退款金额")
+    private BigDecimal refundMoney;
+
+    /** 快递公司编号 */
+//    @Excel(name = "快递公司编号")
+    private String deliveryCode;
+
+    /** 快递名称 */
+//    @Excel(name = "快递名称")
+    private String deliveryName;
+
+    /** 快递单号 */
+//    @Excel(name = "快递单号")
+    private String deliverySn;
+
+    /** 是否删除 */
+//    @Excel(name = "是否删除")
+    private String isDel;
+
+    /** 成本价 */
+//    @Excel(name = "成本价")
+    private BigDecimal costPrice;
+
+    /** 核销码 */
+//    @Excel(name = "核销码")
+    private String verifyCode;
+
+    /** 配送方式 1=快递 ,2=门店自提 */
+//    @Excel(name = "配送方式 1=快递 ,2=门店自提")
+    private Integer shippingType;
+
+    /** 支付渠道(1微信小程序) */
+//    @Excel(name = "支付渠道(1微信小程序)")
+    private String isChannel;
+
+    /** $column.columnComment */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+//    @Excel(name = "支付渠道(1微信小程序)", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date finishTime;
+
+    // 完成时间-开始
+    private String finishTimeStart;
+    // 完成时间-结束
+    private String finishTimeEnd;
+
+    /** 发货时间 */
+//    @Excel(name = "发货时间")
+    private String deliveryTime;
+
+    /** 推广佣金 */
+//    @Excel(name = "推广佣金")
+    private BigDecimal tuiMoney;
+
+    /** 推广佣金状态 1已发放 0待发放 */
+//    @Excel(name = "推广佣金状态 1已发放 0待发放")
+    private Integer tuiMoneyStatus;
+
+    /** 上级推荐人ID */
+//    @Excel(name = "上级推荐人ID")
+    private Long tuiUserId;
+
+    /** orderItem字符串 */
+//    @Excel(name = "orderItem字符串")
+    private String itemJson;
+
+    /** 优惠金额 */
+//    @Excel(name = "优惠金额")
+    private BigDecimal discountMoney;
+
+    /** $column.columnComment */
+//    @Excel(name = "优惠金额")
+    private Long userCouponId;
+
+    /** 公司id */
+//    @Excel(name = "公司id")
+    private Long companyId;
+
+
+
+    /** 仓库代码 */
+//    @Excel(name = "仓库代码")
+    private String storeHouseCode;
+
+    /** 扩展订单ID */
+//    @Excel(name = "扩展订单ID")
+    private String extendOrderId;
+
+    /** 支付运费 */
+//    @Excel(name = "支付运费")
+    private BigDecimal payDelivery;
+
+    /** 剩余金额 */
+//    @Excel(name = "剩余金额")
+    private BigDecimal payRemain;
+
+    /** 物流状态 */
+//    @Excel(name = "物流状态")
+    private Integer deliveryStatus;
+
+    /** 物流结算状态 */
+//    @Excel(name = "物流结算状态")
+    private Integer deliveryPayStatus;
+
+    /** $column.columnComment */
+//    @Excel(name = "物流结算状态")
+    private String deliveryPayTime;
+
+    /** 物流跟踪状态 */
+//    @Excel(name = "物流跟踪状态")
+    private String deliveryType;
+
+    /** 物流结算金额 */
+//    @Excel(name = "物流结算金额")
+    private BigDecimal deliveryPayMoney;
+
+    /** 回单导入时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+//    @Excel(name = "回单导入时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date deliveryImportTime;
+
+    /** 发货时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+//    @Excel(name = "发货时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date deliverySendTime;
+
+    /** 是否可售后 */
+//    @Excel(name = "是否可售后")
+    private Integer isAfterSales;
+
+    /** 部门id */
+//    @Excel(name = "部门id")
+    private Long deptId;
+
+    /** 渠道 */
+//    @Excel(name = "渠道")
+    private String channel;
+
+    /** 订单来源 */
+//    @Excel(name = "订单来源")
+    private Long source;
+
+    /** 开票金额 */
+//    @Excel(name = "开票金额")
+    private BigDecimal billPrice;
+
+    /** 邮费 */
+//    @Excel(name = "邮费")
+    private BigDecimal totalPostage;
+
+    /** 支付邮费 */
+//    @Excel(name = "支付邮费")
+    private BigDecimal payPostage;
+
+    /** 消费赚取积分 */
+//    @Excel(name = "消费赚取积分")
+    private BigDecimal gainIntegral;
+
+    /** 使用积分 */
+//    @Excel(name = "使用积分")
+    private BigDecimal useIntegral;
+
+    /** 实际支付积分 */
+//    @Excel(name = "实际支付积分")
+    private BigDecimal payIntegral;
+
+    /** 给用户退了多少积分 */
+//    @Excel(name = "给用户退了多少积分")
+    private BigDecimal backIntegral;
+
+    /** 是否改价 */
+//    @Excel(name = "是否改价")
+    private Integer isEditMoney;
+
+    /** 创建时间*/
+//    @Excel(name = "创建时间")
+    private Date createTime;
+
+    /** 更新时间*/
+//    @Excel(name = "更新时间")
+    private Date updateTime;
+
+    /** 备注*/
+//    @Excel(name = "备注")
+    private String remark;
+
+    /** 备注*/
+//    @Excel(name = "订单名称")
+    private String orderName;
+
+    /** 备注*/
+//    @Excel(name = "订单名称")
+    private String productIntroduce;
+
+    /** 备注*/
+//    @Excel(name = "订单key")
+    private String orderKey;
+
+    /** 城市Id*/
+    private Long cityId;
+
+    private String companyName;
+    private String companyUserName;
+
+    private Long customerId;
+    private Long couponUserId;
+    private Long recordId;
+
+    /** 优惠券金额 */
+    private BigDecimal couponPrice;
+
+    // ========== 新增字段 ==========
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    // 筛选条件字段
+    private String productNameQuery;
+    private String productSpecQuery;
+    private String supplierNameQuery;
+    private String createTimeStart;
+    private String createTimeEnd;
+
+
+
+}

+ 2 - 0
fs-service/src/main/java/com/fs/live/vo/LiveVo.java

@@ -2,6 +2,7 @@ package com.fs.live.vo;
 
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.models.auth.In;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -51,4 +52,5 @@ public class LiveVo {
     private String previewUrl;
     private Integer previewVideoType;
     private Long previewVideoId;
+    private Integer globalVisible;
 }

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

@@ -85,7 +85,7 @@ public interface QwFriendWelcomeMapper
             "           SELECT 1 FROM qw_user qu " +
             "           JOIN company_user cu ON cu.user_id = qu.company_user_id " +
             "           WHERE FIND_IN_SET(qu.id, REPLACE(REPLACE(REPLACE(qfw.qw_user_ids, '[', ''), ']', ''), ' ', '')) > 0 " +
-            "           AND qu.id = #{qwUserIds} " +
+            "           AND qu.qw_user_id = #{qwUserIds} " +
             "       ) AND " +
             "   </if>" +
             "   <if test=\"isSendMsg != null\"> qfw.is_send_msg = #{isSendMsg} AND </if>" +

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

@@ -152,7 +152,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
             "left join fastgpt_role fr on fr.role_id=qu.fastGpt_role_id " +
             "where qu.company_user_id is not null "+
             "            <if test=\"qwUserId != null  and qwUserId != ''\"> and qu.qw_user_id = #{qwUserId}</if>\n" +
-            "            <if test=\"loginStatus != null  and loginStatus != ''\"> and qu.ipad_status = #{loginStatus}</if>\n" +
+            "            <if test=\"loginStatus != null \"> and qu.ipad_status = #{loginStatus}</if>\n" +
             "            <if test=\"appKey != null  and appKey != ''\"> and qu.app_key = #{appKey}</if>\n" +
             "            <if test=\"nickName != null  and nickName != ''\"> and cu.nick_name like concat( #{nickName}, '%') </if>\n" +
             "            <if test=\"qwUserName != null  and qwUserName != ''\"> and qu.qw_user_name like concat('%', #{qwUserName}, '%') </if> " +

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

@@ -217,6 +217,9 @@ public class QwUserVoiceLogServiceImpl extends ServiceImpl<QwUserVoiceLogMapper,
                 if (recordType == 2) {//2是未接通的处理
                     qwUserVoiceLog.setStatus(recordType);
                     qwUserVoiceLog.setTitle("通话拒接");
+                }else if(recordType == 3){
+                    qwUserVoiceLog.setStatus(recordType);
+                    qwUserVoiceLog.setTitle("通话未接听");
                 } else {
                     qwUserVoiceLog.setStatus(1);
                     if (totalSeconds != null) {

+ 11 - 3
fs-service/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java

@@ -993,10 +993,19 @@ public class QwSopLogsServiceImpl extends ServiceImpl<QwSopLogsMapper, QwSopLogs
     public SendSopParamDetailsC getQwSopLogsByJsApi(GetQwSopLogsByJsApiParam param) {
         //写入企业微信 在线状态 10分钟 通过订阅方式,如果10分钟没有请求此接口,调用一个LOGIN方法
 //        redisCache.setCacheObject("qwActive:"+param.getCorpId()+":"+param.getQwUserId(),1,30 ,TimeUnit.MINUTES);
-        logger.info("主动获取发送信息:"+param);
 
         // 封装消息体
         SendSopParamDetailsC sopParamDetailsC = new SendSopParamDetailsC();
+        // 查询员工信息的id
+        QwUser qwUser = qwExternalContactService.getQwUserByRedis(param.getCorpId().trim(),param.getQwUserId().trim());
+        // 如果发送方式不等于侧边栏跳过
+        if(qwUser.getSendMsgType() != 0){
+            return sopParamDetailsC;
+        }
+
+        logger.info("主动获取发送信息:"+param);
+
+
 //        sendDelayTime(sopParamDetailsC,param);
         // 使用线程安全的集合
         List<QwSopLogsDoSendListTVO> sendJsApiList = Collections.synchronizedList(new ArrayList<>());
@@ -1044,8 +1053,7 @@ public class QwSopLogsServiceImpl extends ServiceImpl<QwSopLogsMapper, QwSopLogs
                             }
                     ));
 
-            // 查询员工信息的id
-            QwUser qwUser = qwExternalContactService.getQwUserByRedis(param.getCorpId().trim(),param.getQwUserId().trim());
+
 
             Long qwId=qwUser.getId();
 

+ 10 - 0
fs-service/src/main/java/com/fs/statis/dto/ComprehensiveStatisticsDTO.java

@@ -1,5 +1,6 @@
 package com.fs.statis.dto;
 
+import com.fs.common.annotation.Excel;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -15,28 +16,37 @@ public class ComprehensiveStatisticsDTO {
 
     private Long companyId;
 
+    @Excel(name = "公司名称")
     private String companyName;
 
     private Long companyUserId;
 
+    @Excel(name = "人员名称")
     private String companyUserName;
 
     private Integer deptId;
 
+    @Excel(name = "部门名称")
     private String deptName;
 
+    @Excel(name = "统计时间")
     private Integer sendCount;
 
     private Integer logType;
 
+    @Excel(name = "完课数")
     private Integer completeNum; //完成数
 
+    @Excel(name = "答题数")
     private Integer answerNum;
 
+    @Excel(name = "红包数")
     private Integer redPacketNum;
 
+    @Excel(name = "红包领取金额")
     private BigDecimal redPacketAmount;
 
+    @Excel(name = "统计时间")
     private Date statisticsTime;
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/statis/param/ComprehensiveStatisticsParam.java

@@ -55,5 +55,7 @@ public class ComprehensiveStatisticsParam {
 
     private Long logType;
 
+    private Boolean timeGroupFlag; //时间分组条件是否生效
+
 }
 

+ 59 - 0
fs-service/src/main/java/com/fs/utils/MyDateUtils.java

@@ -0,0 +1,59 @@
+package com.fs.utils;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @description:
+ * @author: Guos
+ * @time: 2025/11/13 下午4:48
+ */
+public class MyDateUtils {
+
+    /**
+     * 生成开始时间到结束时间之间的每日时间数组
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @return 时间数组列表
+     */
+    public static List<Date> generateDateList(Date startTime, Date endTime) {
+        List<Date> dateList = new ArrayList<>();
+        if (startTime == null || endTime == null) {
+            return dateList;
+        }
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(startTime);
+        // 设置时间为当天00:00:00,确保按天计算
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        Date currentDate = calendar.getTime();
+        Date finalEndTime = getStartOfDay(endTime);
+        while (!currentDate.after(finalEndTime)) {
+            dateList.add(currentDate);
+            calendar.add(Calendar.DAY_OF_MONTH, 1);
+            currentDate = calendar.getTime();
+        }
+        return dateList;
+    }
+
+    /**
+     * 获取指定日期的开始时间(00:00:00)
+     * @param date 指定日期
+     * @return 当天开始时间
+     */
+    private static Date getStartOfDay(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        return calendar.getTime();
+    }
+
+
+}

+ 1 - 1
fs-service/src/main/resources/application-config-druid-bjzm-test.yml

@@ -73,7 +73,7 @@ tencent_cloud_config:
   secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
   bucket: bjzm-1323137866
   app_id: 1323137866
-  region: ap-guangzhou
+  region: ap-chongqing
   proxy: bjzm
 tmp_secret_config:
   secret_id: AKIDCj7NSNAovtqeJpBau8GZ4CGB71thXIxX

+ 2 - 2
fs-service/src/main/resources/application-config-druid-bjzm.yml

@@ -73,7 +73,7 @@ tencent_cloud_config:
   secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
   bucket: bjzmky-1323137866
   app_id: 1323137866
-  region: ap-guangzhou
+  region: ap-chongqing
   proxy: bjzm
 tmp_secret_config:
   secret_id: AKIDCj7NSNAovtqeJpBau8GZ4CGB71thXIxX
@@ -89,7 +89,7 @@ headerImg:
   imgUrl:
 
 ipad:
-  ipadUrl: http://ipad.cdwjyyh.com
+  ipadUrl: http://aipad.klbycp.com
   aiApi: 1212121212
   voiceApi:
   commonApi:

+ 1 - 1
fs-service/src/main/resources/application-config-druid-hst.yml

@@ -64,7 +64,7 @@ fs :
   h5CommonApi: http://172.16.0.26:7771
   jwt:
     # 加密秘钥
-    secret: f4e2e52034348f86b67cde581c0f9eb5
+    secret: f4e2e52034348f86b67cde581c632eb5
     # token有效时长,7天,单位秒
     expire: 31536000
     header: AppToken

+ 1 - 1
fs-service/src/main/resources/application-config-druid-qdtst.yml

@@ -64,7 +64,7 @@ fs :
   h5CommonApi: http://10.206.0.16:8010
   jwt:
     # 加密秘钥
-    secret: f4e2e52034348f86b67cde581c0f9eb5
+    secret: f4q2d52034348t86b67ste581c0f9eb5
     # token有效时长,7天,单位秒
     expire: 31536000
     header: AppToken

+ 108 - 0
fs-service/src/main/resources/application-config-druid-sczy.yml

@@ -0,0 +1,108 @@
+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: wx4115995705bb0ea0   #中康智慧
+        secret: 58910ae743005c396012b029c7def579
+        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+        msgDataFormat: JSON
+      - appid: wxedde588767b358b1   #中康未来智慧药房
+        secret: 928d2961c81610d8f64b019597212fcd
+        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+        msgDataFormat: JSON
+  cp:
+    corpId: wwb2a1055fb6c9a7c2
+    appConfigs:
+      - agentId: 1000005
+        secret: ec7okROXJqkNafq66-L6aKNv0asTzQIG0CYrj3vyBbo
+        token: PPKOdAlCoMO
+        aesKey: PKvaxtpSv8NGpfTDm7VUHIK8Wok2ESyYX24qpXJAdMP
+  pay:
+    appId: wx73f85f8d62769119 #微信公众号或者小程序等的appid
+    mchId: 1611402045 #微信支付商户号
+    mchKey: 8cab128997a3547c1363b0898b877f38 #微信支付商户密钥
+    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: wx75c1870516078d81 # 第一个公众号的appid  //公众号名称:吉林港森
+        secret: 40b40e50e0439fb77d438ea31b053ab0 # 公众号的appsecret
+        token: PPKOdAlCoMO # 接口配置里的Token值
+        aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+  # 开放平台app微信授权配置
+  open:
+    app-id: wxe4d352ea8ddbcf3c
+    secret: be6c179d79fcf97cbfb0b36c08877220
+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://8.130.78.34:8010
+  h5CommonApi: http://8.130.78.34:8010
+  jwt:
+    # 加密秘钥
+    secret: f4e2e52034348f86b67cde581c0f9e14
+    # token有效时长,7天,单位秒
+    expire: 31536000
+    header: AppToken
+nuonuo:
+  key: 10924508
+  secret: A2EB20764D304D16
+
+# 存储捅配置
+tencent_cloud_config:
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: sczy-1323137866
+  app_id: 1323137866
+  region: ap-chongqing
+  proxy: sczy
+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: SCZY
+headerImg:
+  imgUrl: https://jiuzhouzaixian.obs.cn-southwest-2.myhuaweicloud.com/fs/20250623/1750665141214.png
+ipad:
+  ipadUrl: http://ipad.beijingzhuomei.com
+  aiApi:
+  voiceApi:
+  commonApi:
+wx_miniapp_temp:
+  pay_order_temp_id: VXEvKaGNPFuJmhWK9O_QPrTZxe9umDCukq-maI8Vdek
+  inquiry_temp_id: 9POPYeqhI48LOPvq-Rfoklze7H-9SlunJKh10Qt4_2I
+# 0 代表关闭 1代表开启(润天老商户号的扣款限制)
+enableRedPackAccount: 1

+ 180 - 0
fs-service/src/main/resources/application-druid-sczy.yml

@@ -0,0 +1,180 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-sczy,common
+    # redis 配置
+    redis:
+        # 地址
+        host: 8.130.165.154
+        # 端口,默认为6379
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password: Ylrztek250218!3@.
+        # 连接超时时间
+        timeout: 20s
+        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://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://rm-0jl66x1uoytye36x8.mysql.rds.aliyuncs.com:3306/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: 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: false
+                    # 设置白名单,不填则允许所有访问
+                    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://rm-0jl66x1uoytye36x8.mysql.rds.aliyuncs.com:3306/sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                read:
+                    url: jdbc:mysql://rm-0jl66x1uoytye36x8.mysql.rds.aliyuncs.com:3306/sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                # 初始连接数
+                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: false
+                    # 设置白名单,不填则允许所有访问
+                    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-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+    consumer:
+        group: test-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+custom:
+    token: "1o62d3YxvdHd4LEUiltnu7sK"
+    encoding-aes-key: "UJfTQ5qKTKlegjkXtp1YuzJzxeHlUKvq5GyFbERN1iU"
+    corp-id: "ww51717e2b71d5e2d3"
+    secret: "6ODAmw-8W4t6h9mdzHh2Z4Apwj8mnsyRnjEDZOHdA7k"
+    private-key-path: "privatekey.pem"
+    webhook-url: "https://your-server.com/wecom/archive"
+# token配置
+token:
+    # 令牌自定义标识
+    header: Authorization
+    # 令牌密钥
+    secret: abcdefghijklmnopqrstuvwxyz
+    # 令牌有效期(默认30分钟)
+    expireTime: 180
+openIM:
+    secret: openIM123
+    userID: imAdmin
+    url: https://web.im.fbylive.com/api
+#是否使用新im
+im:
+    type: NONE
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: false
+
+enableRedPackAccount: 1

+ 18 - 0
fs-service/src/main/resources/mapper/company/CrmStatisticManageMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.company.mapper.CrmStatisticManageMapper">
+
+
+    <select id="getSearchCompanyInfo" resultType="com.fs.company.domain.CompanyDeptUserInfo">
+        select
+            c.company_id as companyId,
+            c.company_name as companyName
+        from company as c
+        where c.is_del = 0
+        <if test="companyId != null">
+            and c.company_id =  #{companyId}
+        </if>
+    </select>
+</mapper>

+ 4 - 2
fs-service/src/main/resources/mapper/company/StatisticManageMapper.xml

@@ -340,8 +340,10 @@
         <if test="courseId != null">
             and fs.course_id = #{courseId}
         </if>
-        GROUP BY fs.statistics_time
-        order by fs.statistics_time
+        <if test="timeGroupFlag">
+            GROUP BY fs.statistics_time
+        </if>
+            order by fs.statistics_time
         <if test="dimension != null">
             <if test="dimension == 2">
                 , fs.company_id

+ 14 - 7
fs-service/src/main/resources/mapper/fastGpt/FastGptRoleMapper.xml

@@ -21,10 +21,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="bindCorpId"    column="bind_corp_id"    />
         <result property="contactInfo"    column="contact_info"    />
         <result property="channelType"    column="channel_type"    />
+        <result property="logistics"    column="logistics"    />
     </resultMap>
 
     <sql id="selectFastGptRoleVo">
-        select role_id, role_name,contact_info,company_id, create_time, update_time, role_type, mode_config_json, mode, kf_id, kf_url, avatar, kf_media_id,reminder_words, bind_corp_id,channel_type from fastgpt_role
+        select role_id, role_name,contact_info,company_id, create_time, update_time, role_type, mode_config_json, mode, kf_id, kf_url, avatar, kf_media_id,reminder_words, bind_corp_id,channel_type,logistics from fastgpt_role
     </sql>
 
     <select id="selectFastGptRoleList" parameterType="FastGptRole" resultMap="FastGptRoleResult">
@@ -59,20 +60,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </if>
         </where>
     </select>
-
+    <select id="selectFastGptRoleRoleIdsByLikeAppKey" resultType="com.fs.his.vo.OptionsVO">
+        select
+            role_name as dictLabel,
+            mode_config_json as dictImgUrl,
+            role_id as dictValue
+        from fastgpt_role
+        where mode_config_json like concat('{"APPKey":"', #{appKey}, '%')
+    </select>
     <select id="selectFastGptRoleRoleIdsByAppKey" resultType="java.lang.String">
         select
             role_id as roleId
         from fastgpt_role
         where mode_config_json like concat('{"APPKey":"', #{appKey}, '%')
     </select>
-
     <select id="selectFastGptRoleAppKeyList" resultType="com.fs.fastGpt.vo.FastgptEventLogTotalVo">
         select
             role_id as roleId,role_name as roleName,mode_config_json as appKey
         from fastgpt_role
     </select>
 
+
     <insert id="insertFastGptRole" parameterType="FastGptRole" useGeneratedKeys="true" keyProperty="roleId">
         insert into fastgpt_role
         <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -90,8 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="reminderWords != null">reminder_words,</if>
             <if test="bindCorpId != null">bind_corp_id,</if>
             <if test="contactInfo != null">contact_info,</if>
-            <if test="channelType != null">channel_type,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="roleName != null">#{roleName},</if>
             <if test="companyId != null">#{companyId},</if>
@@ -107,8 +114,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="reminderWords != null">#{reminderWords},</if>
             <if test="bindCorpId != null">#{bindCorpId},</if>
             <if test="contactInfo != null">#{contactInfo},</if>
-            <if test="channelType != null">#{channelType},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateFastGptRole" parameterType="FastGptRole">
@@ -129,6 +135,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="bindCorpId != null">bind_corp_id = #{bindCorpId},</if>
             <if test="contactInfo != null">contact_info = #{contactInfo},</if>
             <if test="channelType != null">channel_type = #{channelType},</if>
+            <if test="logistics != null">logistics = #{logistics},</if>
         </trim>
         where role_id = #{roleId}
     </update>

+ 4 - 0
fs-service/src/main/resources/mapper/live/LiveCouponIssueMapper.xml

@@ -21,6 +21,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="couponPrice"    column="coupon_price"    />
         <result property="useMinPrice"    column="use_min_price"    />
         <result property="couponTime"    column="coupon_time"    />
+        <result property="limitReceiveCount"    column="limit_receive_count"    />
     </resultMap>
 
     <sql id="selectLiveCouponIssueVo">
@@ -65,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isDel != null">is_del,</if>
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
+            <if test="limitReceiveCount != null">limit_receive_count,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="couponName != null">#{couponName},</if>
@@ -79,6 +81,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isDel != null">#{isDel},</if>
             <if test="createTime != null">#{createTime},</if>
             <if test="updateTime != null">#{updateTime},</if>
+            <if test="limitReceiveCount != null">#{limitReceiveCount},</if>
          </trim>
     </insert>
 
@@ -97,6 +100,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isDel != null">is_del = #{isDel},</if>
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="limitReceiveCount != null">limit_receive_count = #{limitReceiveCount},</if>
         </trim>
         where id = #{id}
     </update>

+ 6 - 1
fs-service/src/main/resources/mapper/live/LiveCouponMapper.xml

@@ -19,10 +19,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
         <result property="isDel"    column="is_del"    />
+        <result property="limitReceiveCount"    column="limit_receive_count"    />
     </resultMap>
 
     <sql id="selectLiveCouponVo">
-        select coupon_id, title, integral, coupon_price, use_min_price, coupon_time, sort, status, product_ids, package_cate_ids, type, create_time, update_time, is_del from live_coupon
+        select coupon_id, title, integral, coupon_price, use_min_price, coupon_time, sort, status, product_ids, package_cate_ids, type, create_time, update_time, is_del,limit_receive_count from live_coupon
     </sql>
 
     <select id="selectLiveCouponList" parameterType="LiveCoupon" resultMap="LiveCouponResult">
@@ -39,6 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="packageCateIds != null  and packageCateIds != ''"> and package_cate_ids = #{packageCateIds}</if>
             <if test="type != null "> and type = #{type}</if>
             <if test="isDel != null "> and is_del = #{isDel}</if>
+            <if test="limitReceiveCount != null "> and limit_receive_count = #{limitReceiveCount}</if>
         </where>
     </select>
 
@@ -63,6 +65,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
             <if test="isDel != null">is_del,</if>
+            <if test="limitReceiveCount != null">limit_receive_count,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="title != null and title != ''">#{title},</if>
@@ -78,6 +81,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">#{createTime},</if>
             <if test="updateTime != null">#{updateTime},</if>
             <if test="isDel != null">#{isDel},</if>
+            <if test="limitReceiveCount != null">#{limitReceiveCount},</if>
          </trim>
     </insert>
 
@@ -97,6 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time = #{createTime},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="isDel != null">is_del = #{isDel},</if>
+            <if test="limitReceiveCount != null">limit_receive_count = #{limitReceiveCount},</if>
         </trim>
         where coupon_id = #{couponId}
     </update>

+ 141 - 0
fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml

@@ -917,4 +917,145 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ${maps.params.dataScope} GROUP BY sp.product_id
         ) AS t
     </select>
+
+    <!-- 查询订单列表Zm -->
+    <select id="selectLiveOrderListZm" parameterType="LiveOrder" resultType="com.fs.live.vo.LiveOrderVoZm">
+        SELECT
+            o.order_id,
+            o.live_id,
+            o.store_id,
+            o.order_code,
+            o.user_id,
+            o.user_name,
+            o.user_phone,
+            o.user_address,
+            o.cart_id,
+            o.total_num,
+            o.total_price,
+            o.pay_price,
+            o.pay_money,
+            o.is_pay,
+            o.pay_time,
+            o.pay_type,
+            o.create_time,
+            o.update_time,
+            o.status,
+            o.refund_status,
+            o.refund_img,
+            o.refund_explain,
+            o.refund_time,
+            o.refund_reason,
+            o.refund_money,
+            o.delivery_code,
+            o.delivery_name,
+            o.delivery_sn,
+            o.remark,
+            o.is_del,
+            o.cost_price,
+            o.company_id,
+            o.company_user_id,
+            o.product_id,
+            o.customer_id,
+            o.coupon_price,
+            o.cancel_reason,
+
+            <!-- 销售信息 -->
+            cu.nick_name AS companyUserNickName,
+            cu.phonenumber AS companyUserPhone,
+            cu.create_time AS companyUserCreateTime,
+
+            <!-- 客户信息 -->
+            u.user_code AS userCode,
+            u.level AS userLevel,
+            u.nick_name AS nickName,
+            u.phone AS userBindPhone,
+            u.order_count AS totalOrderCount,
+            u.total_amount AS totalOrderAmount,
+            u.status AS userStatus,
+            u.update_time AS latestBindTime,
+
+            <!-- 商品信息 -->
+            p.product_name AS productName,
+            p.cost AS costPrice,
+            p.price AS price,
+            p.cost AS cost,
+            p.prescribe_spec AS productSpec,
+            p.prescribe_factory AS supplierName,
+
+            <!-- 门店信息 -->
+            s.store_name AS storeName,
+            s.store_id AS storeId
+
+        FROM
+            live_order o
+            LEFT JOIN fs_user u ON o.user_id = u.user_id
+            LEFT JOIN company_user cu ON o.company_user_id = cu.user_id
+            LEFT JOIN fs_store_product_scrm p ON o.product_id = p.product_id
+            LEFT JOIN fs_store_scrm s ON p.store_id = s.store_id
+        <where>
+            o.is_del = 0
+            <if test="orderId != null">
+                AND o.order_id = #{orderId}
+            </if>
+            <if test="liveId != null">
+                AND o.live_id = #{liveId}
+            </if>
+            <if test="storeId != null">
+                AND o.store_id = #{storeId}
+            </if>
+            <if test="orderCode != null and orderCode != ''">
+                AND o.order_code LIKE CONCAT('%', #{orderCode}, '%')
+            </if>
+            <if test="userId != null and userId != ''">
+                AND o.user_id = #{userId}
+            </if>
+            <if test="status != null">
+                AND o.status = #{status}
+            </if>
+            <if test="companyId != null">
+                AND o.company_id = #{companyId}
+            </if>
+            <if test="totalNum != null">
+                AND o.total_num = #{totalNum}
+            </if>
+            <if test="price != null">
+                AND p.price = #{price}
+            </if>
+            <if test="cost != null">
+                AND p.cost = #{cost}
+            </if>
+            <if test="companyUserId != null">
+                AND o.company_user_id = #{companyUserId}
+            </if>
+            <if test="productId != null">
+                AND o.product_id = #{productId}
+            </if>
+            <!-- 新增筛选条件 -->
+            <if test="productName != null and productName != ''">
+                AND p.product_name LIKE CONCAT('%', #{productName}, '%')
+            </if>
+            <if test="productSpec != null and productSpec != ''">
+                AND p.prescribe_spec LIKE CONCAT('%', #{productSpec}, '%')
+            </if>
+            <if test="storeId != null and storeId != ''">
+                AND p.store_id #{storeId}
+            </if>
+            <if test="userAddress != null and userAddress != ''">
+                AND o.user_address LIKE CONCAT('%', #{userAddress}, '%')
+            </if>
+            <if test="createTimeStart != null and createTimeStart != ''">
+                AND o.create_time &gt;= #{createTimeStart}
+            </if>
+            <if test="createTimeEnd != null and createTimeEnd != ''">
+                AND o.create_time &lt;= #{createTimeEnd}
+            </if>
+            <if test="payStartTime != null and payStartTime != ''">
+                AND o.pay_time &gt;= #{payStartTime}
+            </if>
+            <if test="payEndTime != null and payEndTime != ''">
+                AND o.pay_time &lt;= #{payEndTime}
+            </if>
+        </where>
+        ORDER BY o.create_time DESC
+    </select>
 </mapper>

+ 29 - 24
fs-service/src/main/resources/mapper/system/SysUserMapper.xml

@@ -23,6 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="updateBy"     column="update_by"    />
 		<result property="updateTime"   column="update_time"  />
 		<result property="remark"       column="remark"       />
+		<result property="companyId"       column="company_id"       />
 		<association property="dept"    column="dept_id" javaType="SysDept" resultMap="deptResult" />
 		<collection  property="roles"   javaType="java.util.List"        resultMap="RoleResult" />
 		<collection property="roleName" ofType="java.lang.String" javaType="java.util.ArrayList">
@@ -48,10 +49,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="updateBy"     column="update_by"    />
 		<result property="updateTime"   column="update_time"  />
 		<result property="remark"       column="remark"       />
+		<result property="companyId"       column="company_id"       />
 		<association property="dept"    column="dept_id" javaType="SysDept" resultMap="deptResult" />
 		<collection  property="roles"   javaType="java.util.List"        resultMap="RoleResult" />
 	</resultMap>
-	
+
 	<resultMap id="deptResult" type="SysDept">
 		<id     property="deptId"   column="dept_id"     />
 		<result property="parentId" column="parent_id"   />
@@ -60,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="leader"   column="leader"      />
 		<result property="status"   column="dept_status" />
 	</resultMap>
-	
+
 	<resultMap id="RoleResult" type="SysRole">
 		<id     property="roleId"       column="role_id"        />
 		<result property="roleName"     column="role_name"      />
@@ -69,11 +71,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="dataScope"     column="data_scope"    />
 		<result property="status"       column="role_status"    />
 	</resultMap>
-	
+
 	<sql id="selectUserVo">
-        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, 
+        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
         d.dept_id, d.parent_id, d.dept_name, d.order_num, d.leader, d.status as dept_status,
-        r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
+        r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status,u.company_id
         from sys_user u
 		    left join sys_dept d on u.dept_id = d.dept_id
 		    left join sys_user_role ur on u.user_id = ur.user_id
@@ -146,7 +148,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	<select id="selectUserListByIds" parameterType="java.util.List" resultMap="SysUserResults">
 		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber,
 		u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by,
-		u.create_time, u.remark, d.dept_name, d.leader, r.role_name
+		u.create_time, u.remark, d.dept_name, d.leader, r.role_name,u.company_id
 		from sys_user u
 		left join sys_dept d on u.dept_id = d.dept_id
 		left join sys_user_role sur on u.user_id = sur.user_id
@@ -158,7 +160,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		order by u.user_id
 	</select>
     <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResults">
-		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader,r.role_name from sys_user u
+		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader,r.role_name,u.company_id from sys_user u
 		left join sys_dept d on u.dept_id = d.dept_id
 		left join sys_user_role sur on u.user_id = sur.user_id
 		left join sys_role r on r.role_id = sur.role_id
@@ -187,7 +189,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<!-- 数据范围过滤 -->
 		${params.dataScope}
 	</select>
-	
+
 	<select id="selectAllocatedList" parameterType="SysUser" resultMap="SysUserResult">
 	    select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
 	    from sys_user u
@@ -204,7 +206,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<!-- 数据范围过滤 -->
 		${params.dataScope}
 	</select>
-	
+
 	<select id="selectUnallocatedList" parameterType="SysUser" resultMap="SysUserResult">
 	    select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
 	    from sys_user u
@@ -222,29 +224,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<!-- 数据范围过滤 -->
 		${params.dataScope}
 	</select>
-	
+
 	<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
 	    <include refid="selectUserVo"/>
 		where u.user_name = #{userName}
 	</select>
-	
+
 	<select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
 		<include refid="selectUserVo"/>
 		where u.user_id = #{userId}
 	</select>
-	
+
 	<select id="checkUserNameUnique" parameterType="String" resultType="int">
 		select count(1) from sys_user where user_name = #{userName} limit 1
 	</select>
-	
+
 	<select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult">
 		select user_id, phonenumber from sys_user where phonenumber = #{phonenumber} limit 1
 	</select>
-	
+
 	<select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
 		select user_id, email from sys_user where email = #{email} limit 1
 	</select>
-	
+
 	<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
  		insert into sys_user(
  			<if test="userId != null and userId != 0">user_id,</if>
@@ -259,6 +261,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="status != null and status != ''">status,</if>
  			<if test="createBy != null and createBy != ''">create_by,</if>
  			<if test="remark != null and remark != ''">remark,</if>
+ 			<if test="companyId != null">company_id,</if>
  			create_time
  		)values(
  			<if test="userId != null and userId != ''">#{userId},</if>
@@ -273,10 +276,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="status != null and status != ''">#{status},</if>
  			<if test="createBy != null and createBy != ''">#{createBy},</if>
  			<if test="remark != null and remark != ''">#{remark},</if>
+ 			<if test="companyId != null">#{companyId},</if>
  			sysdate()
  		)
 	</insert>
-	
+
 	<update id="updateUser" parameterType="SysUser">
  		update sys_user
  		<set>
@@ -293,32 +297,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="loginDate != null">login_date = #{loginDate},</if>
  			<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
  			<if test="remark != null">remark = #{remark},</if>
+ 			<if test="companyId != null">company_id = #{companyId},</if>
  			update_time = sysdate()
  		</set>
  		where user_id = #{userId}
 	</update>
-	
+
 	<update id="updateUserStatus" parameterType="SysUser">
  		update sys_user set status = #{status} where user_id = #{userId}
 	</update>
-	
+
 	<update id="updateUserAvatar" parameterType="SysUser">
  		update sys_user set avatar = #{avatar} where user_name = #{userName}
 	</update>
-	
+
 	<update id="resetUserPwd" parameterType="SysUser">
  		update sys_user set password = #{password} where user_name = #{userName}
 	</update>
-	
+
 	<delete id="deleteUserById" parameterType="Long">
 		update sys_user set del_flag = '2' where user_id = #{userId}
  	</delete>
- 	
+
  	<delete id="deleteUserByIds" parameterType="Long">
  		update sys_user set del_flag = '2' where user_id in
  		<foreach collection="array" item="userId" open="(" separator="," close=")">
  			#{userId}
-        </foreach> 
+        </foreach>
  	</delete>
-	
-</mapper> 
+
+</mapper>

+ 9 - 0
fs-user-app/pom.xml

@@ -136,6 +136,15 @@
                     <warName>${project.artifactId}</warName>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <compilerArgs>
+                        <arg>-parameters</arg>
+                    </compilerArgs>
+                </configuration>
+            </plugin>
         </plugins>
         <finalName>${project.artifactId}</finalName>
     </build>

+ 24 - 0
fs-user-app/src/main/java/com/fs/app/controller/CommonController.java

@@ -9,6 +9,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fs.ai.service.IBaiduAIService;
 import com.fs.ai.vo.BaiduAIMsgResultVO;
 import com.fs.app.param.SignParam;
+import com.fs.app.param.TestMoneyParam;
 import com.fs.app.utils.CityTreeUtil;
 import com.fs.app.utils.JwtUtils;
 import com.fs.app.vo.CityVO;
@@ -28,6 +29,8 @@ import com.fs.common.exception.file.OssException;
 import com.fs.common.utils.file.FileUploadUtils;
 import com.fs.common.utils.http.HttpUtils;
 import com.fs.common.utils.sign.Md5Utils;
+import com.fs.company.domain.CompanyMoneyLogs;
+import com.fs.company.service.ICompanyMoneyLogsService;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.service.IHuaweiVodService;
@@ -73,6 +76,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.*;
+import java.math.BigDecimal;
 import java.util.*;
 
 import static com.fs.common.utils.SecurityUtils.getUserId;
@@ -142,6 +146,26 @@ public class CommonController {
 //		return R.ok();
 //	}
 
+	@Autowired
+	ICompanyMoneyLogsService logsService;
+	@ApiOperation("同步企业金额")
+	@PostMapping("testUpdateCompanyMoney")
+	public R testUpdateCompanyMoney(@RequestBody TestMoneyParam param) throws Exception
+	{
+		List<CompanyMoneyLogs> logs=logsService.selectCompanyMoneyLogsByCompanyId(param.getCompanyId(),param.getLogsId().toString());
+		if(logs!=null){
+			BigDecimal companyMoney=param.getMoney();
+			for(CompanyMoneyLogs log:logs){
+				companyMoney=companyMoney.add(log.getMoney());
+				CompanyMoneyLogs logMap=new CompanyMoneyLogs();
+				logMap.setLogsId(log.getLogsId());
+				logMap.setBalance(companyMoney);
+				logsService.updateCompanyMoneyLogs(logMap);
+			}
+		}
+		return R.ok();
+	}
+
 
 	@ApiOperation("excel")
 	@GetMapping(value = "/exportExcel")

+ 2 - 0
fs-user-app/src/main/java/com/fs/app/controller/live/LiveMsgController.java

@@ -1,5 +1,6 @@
 package com.fs.app.controller.live;
 
+import com.fs.app.annotation.Login;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -40,6 +41,7 @@ public class LiveMsgController extends BaseController
     /**
      * 查询直播讨论列表
      */
+    @Login
     @GetMapping("/myList")
     public TableDataInfo myList(LiveMsg liveMsg)
     {

+ 12 - 9
fs-user-app/src/main/java/com/fs/app/facade/impl/LiveFacadeServiceImpl.java

@@ -11,19 +11,13 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.page.PageRequest;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.core.redis.RedisCache;
-import com.fs.live.domain.Live;
-import com.fs.live.domain.LiveLotteryRegistration;
+import com.fs.live.domain.*;
 import com.fs.framework.aspectj.lock.DistributeLock;
-import com.fs.live.domain.LiveRedConf;
-import com.fs.live.domain.LiveWatchUser;
 import com.fs.live.param.CouponPO;
 import com.fs.live.param.LotteryPO;
 import com.fs.live.param.RedPO;
 import com.fs.live.service.*;
-import com.fs.live.vo.LiveConfigVo;
-import com.fs.live.vo.LiveLotteryConfVo;
-import com.fs.live.vo.LiveVo;
-import com.fs.live.vo.LiveWatchUserVO;
+import com.fs.live.vo.*;
 import com.github.pagehelper.PageInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -153,10 +147,19 @@ public class LiveFacadeServiceImpl extends BaseController implements LiveFacadeS
                 .stream()
                 .filter(item -> ObjectUtil.isEmpty(redisCache.hashGet(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_RED, liveId, item.getLotteryId()), userId)))
                 .collect(Collectors.toList());
+        Object cacheObject = redisCache.getCacheObject(String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG, liveId, LiveKeysConstant.TOP_MSG));
+        LiveMsgVo liveMsg;
+        if (ObjectUtil.isNotEmpty(cacheObject)) {
+            liveMsg = JSON.parseObject(cacheObject.toString(), LiveMsgVo.class);
+        } else {
+            liveMsg = null;
+        }
+
         return R.ok()
                 .put("red", redConfs)
                 .put("lottery", lotteryConfs)
-                .put("goods", liveConfigVo.getLiveGoodsVo());
+                .put("goods", liveConfigVo.getLiveGoodsVo())
+                .put("topMsg", liveMsg);
     }
 
     @Override

+ 21 - 0
fs-user-app/src/main/java/com/fs/app/param/TestMoneyParam.java

@@ -0,0 +1,21 @@
+package com.fs.app.param;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Getter
+@Setter
+@ToString
+public class TestMoneyParam implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long companyId;
+    private Long logsId;
+    private BigDecimal money;
+
+
+}