Browse Source

Merge branch 'refs/heads/master' into ScrmStores

# Conflicts:
#	fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
#	fs-service/src/main/resources/mapper/company/CompanyMapper.xml
chenguo 3 days ago
parent
commit
58c7d35803
100 changed files with 4148 additions and 246 deletions
  1. 20 0
      fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchCommentController.java
  2. 1 0
      fs-admin/src/main/java/com/fs/course/controller/qw/QwFsCourseWatchLogController.java
  3. 97 0
      fs-admin/src/main/java/com/fs/fastGpt/FastGptChatReplaceTextController.java
  4. 112 0
      fs-admin/src/main/java/com/fs/fastGpt/FastGptKeywordSendController.java
  5. 139 0
      fs-admin/src/main/java/com/fs/fastGpt/FastgptEventLogTotalController.java
  6. 8 5
      fs-admin/src/main/java/com/fs/his/controller/FsFirstDiagnosisController.java
  7. 224 4
      fs-admin/src/main/java/com/fs/his/task/Task.java
  8. 12 4
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreProductScrmController.java
  9. 24 1
      fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java
  10. 1 0
      fs-company/src/main/java/com/fs/company/controller/course/FsCourseWatchLogController.java
  11. 1 0
      fs-company/src/main/java/com/fs/company/controller/course/qw/FsQwCourseWatchLogController.java
  12. 134 0
      fs-company/src/main/java/com/fs/company/controller/fastGpt/FastGptKeywordSendController.java
  13. 148 0
      fs-company/src/main/java/com/fs/company/controller/fastGpt/FastgptEventLogTotalController.java
  14. 1 0
      fs-company/src/main/java/com/fs/framework/config/SecurityConfig.java
  15. 36 0
      fs-doctor-app/src/main/java/com/fs/app/controller/DiagnosisController.java
  16. 1 0
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  17. 1 1
      fs-ipad-task/src/main/java/com/fs/app/task/SendMsg.java
  18. 118 41
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  19. 52 16
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  20. 5 0
      fs-service/src/main/java/com/fs/company/domain/Company.java
  21. 3 0
      fs-service/src/main/java/com/fs/company/mapper/CompanyMapper.java
  22. 7 0
      fs-service/src/main/java/com/fs/company/service/ICompanyService.java
  23. 10 5
      fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  24. 36 6
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  25. 2 0
      fs-service/src/main/java/com/fs/course/param/FsCourseWatchLogStatisticsListParam.java
  26. 13 0
      fs-service/src/main/java/com/fs/course/param/FsFirstDiagnosisListUParam.java
  27. 11 0
      fs-service/src/main/java/com/fs/course/param/FsInquiryPatientInfoUParam.java
  28. 11 2
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  29. 10 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  30. 2 0
      fs-service/src/main/java/com/fs/course/vo/FsCourseWatchLogStatisticsListVO.java
  31. 77 0
      fs-service/src/main/java/com/fs/course/vo/FsFirstDiagnosisListUVO.java
  32. 113 0
      fs-service/src/main/java/com/fs/course/vo/FsInquiryPatientInfoListUVO.java
  33. 2 2
      fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java
  34. 96 0
      fs-service/src/main/java/com/fs/fastGpt/domain/FastGptChatReplaceText.java
  35. 2 0
      fs-service/src/main/java/com/fs/fastGpt/domain/FastGptRole.java
  36. 68 0
      fs-service/src/main/java/com/fs/fastGpt/mapper/FastGptChatReplaceTextMapper.java
  37. 10 0
      fs-service/src/main/java/com/fs/fastGpt/mapper/FastGptRoleMapper.java
  38. 93 0
      fs-service/src/main/java/com/fs/fastGpt/mapper/FastgptEventLogTotalMapper.java
  39. 76 0
      fs-service/src/main/java/com/fs/fastGpt/param/FastgptEventLogTotalParam.java
  40. 62 0
      fs-service/src/main/java/com/fs/fastGpt/service/IFastGptChatReplaceTextService.java
  41. 8 0
      fs-service/src/main/java/com/fs/fastGpt/service/IFastGptRoleService.java
  42. 94 0
      fs-service/src/main/java/com/fs/fastGpt/service/IFastgptEventLogTotalService.java
  43. 101 30
      fs-service/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  44. 0 2
      fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptChatMsgServiceImpl.java
  45. 93 0
      fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptChatReplaceTextServiceImpl.java
  46. 77 0
      fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptRoleServiceImpl.java
  47. 290 0
      fs-service/src/main/java/com/fs/fastGpt/service/impl/FastgptEventLogTotalServiceImpl.java
  48. 19 0
      fs-service/src/main/java/com/fs/fastGpt/vo/FastGptRoleDataVO.java
  49. 70 0
      fs-service/src/main/java/com/fs/fastGpt/vo/FastgptEventLogTotalVo.java
  50. 110 8
      fs-service/src/main/java/com/fs/fastgptApi/util/AiImgUtil.java
  51. 2 2
      fs-service/src/main/java/com/fs/fastgptApi/util/EventLogUtils.java
  52. 20 1
      fs-service/src/main/java/com/fs/gtPush/domain/PushReqBean.java
  53. 93 0
      fs-service/src/main/java/com/fs/gtPush/service/impl/uniPush2ServiceImpl.java
  54. 4 0
      fs-service/src/main/java/com/fs/gtPush/service/uniPush2Service.java
  55. 120 0
      fs-service/src/main/java/com/fs/gtPush/utils/PushUtils.java
  56. 6 0
      fs-service/src/main/java/com/fs/his/domain/FsFirstDiagnosis.java
  57. 12 0
      fs-service/src/main/java/com/fs/his/dto/FindUsersByDTO.java
  58. 35 0
      fs-service/src/main/java/com/fs/his/enums/PushLogDesTypeEnum.java
  59. 34 0
      fs-service/src/main/java/com/fs/his/enums/PushLogTypeEnum.java
  60. 53 0
      fs-service/src/main/java/com/fs/his/mapper/FsFirstDiagnosisMapper.java
  61. 25 0
      fs-service/src/main/java/com/fs/his/mapper/FsInquiryPatientInfoMapper.java
  62. 4 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  63. 12 0
      fs-service/src/main/java/com/fs/his/param/FindUserByParam.java
  64. 17 0
      fs-service/src/main/java/com/fs/his/param/FsDiagnosisFillDParam.java
  65. 13 0
      fs-service/src/main/java/com/fs/his/param/FsDiagnosisListDParam.java
  66. 25 0
      fs-service/src/main/java/com/fs/his/param/FsFirstDiagnosisParam.java
  67. 2 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderDoPayParam.java
  68. 2 0
      fs-service/src/main/java/com/fs/his/param/FsPackageOrderDoPayParam.java
  69. 2 0
      fs-service/src/main/java/com/fs/his/param/FsStoreOrderDoPayParam.java
  70. 26 5
      fs-service/src/main/java/com/fs/his/service/IFsFirstDiagnosisService.java
  71. 8 0
      fs-service/src/main/java/com/fs/his/service/IFsInquiryPatientInfoService.java
  72. 8 0
      fs-service/src/main/java/com/fs/his/service/IFsUserService.java
  73. 110 1
      fs-service/src/main/java/com/fs/his/service/impl/FsFirstDiagnosisServiceImpl.java
  74. 17 0
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryPatientInfoServiceImpl.java
  75. 52 32
      fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java
  76. 123 49
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  77. 7 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  78. 33 0
      fs-service/src/main/java/com/fs/his/vo/FsDiagnosisListDVO.java
  79. 2 0
      fs-service/src/main/java/com/fs/his/vo/FsDoctorArticleUVO.java
  80. 81 0
      fs-service/src/main/java/com/fs/his/vo/FsFirstDiagnosisVO.java
  81. 1 1
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  82. 4 2
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java
  83. 3 0
      fs-service/src/main/java/com/fs/qw/domain/QwExternalContact.java
  84. 4 0
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  85. 1 1
      fs-service/src/main/java/com/fs/qw/service/IQwExternalContactService.java
  86. 26 5
      fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  87. 1 1
      fs-service/src/main/java/com/fs/qw/vo/QwSopTempSetting.java
  88. 3 0
      fs-service/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java
  89. 58 5
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  90. 45 0
      fs-service/src/main/java/com/fs/utils/SensitiveDataUtils.java
  91. 3 0
      fs-service/src/main/resources/application-config-druid-jnmy.yml
  92. 4 0
      fs-service/src/main/resources/application-config-druid-sxjz.yml
  93. 1 0
      fs-service/src/main/resources/application-druid-jnmy-test.yml
  94. 5 5
      fs-service/src/main/resources/application-druid-jzzx.yml
  95. 5 5
      fs-service/src/main/resources/application-druid-kyt.yml
  96. 17 1
      fs-service/src/main/resources/mapper/company/CompanyMapper.xml
  97. 3 3
      fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  98. 80 0
      fs-service/src/main/resources/mapper/fastGpt/FastGptChatReplaceTextMapper.xml
  99. 24 0
      fs-service/src/main/resources/mapper/fastGpt/FastGptRoleMapper.xml
  100. 211 0
      fs-service/src/main/resources/mapper/fastGpt/FastgptEventLogTotalMapper.xml

+ 20 - 0
fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchCommentController.java

@@ -70,6 +70,14 @@ public class FsCourseWatchCommentController extends BaseController
         return util.exportExcel(list, "看课评论数据");
         return util.exportExcel(list, "看课评论数据");
     }
     }
 
 
+    @PreAuthorize("@ss.hasPermi('course:courseWatchComment:edit')")
+    @Log(title = "看课评论", businessType = BusinessType.UPDATE)
+    @PutMapping("/updateBarrageStatus")
+    public AjaxResult updateBarrageStatus(@RequestBody FsCourseWatchComment fsCourseWatchComment)
+    {
+        return toAjax(fsCourseWatchCommentService.updateFsCourseWatchComment(fsCourseWatchComment));
+    }
+
     /**
     /**
      * 获取看课评论详细信息
      * 获取看课评论详细信息
      */
      */
@@ -125,4 +133,16 @@ public class FsCourseWatchCommentController extends BaseController
         }
         }
     }
     }
 
 
+    @Log(title = "手动解除外部联系人拉黑用户", businessType = BusinessType.UPDATE)
+    @PutMapping("/clearBlack")
+    public R clearBlack(Integer commentStatus, Long fsUserId)
+    {
+        int i = qwExternalContactService.updateQwExternalContactByFsUserId(commentStatus, fsUserId);
+        if (i > 0){
+            return R.ok();
+        } else {
+            return R.error();
+        }
+    }
+
 }
 }

+ 1 - 0
fs-admin/src/main/java/com/fs/course/controller/qw/QwFsCourseWatchLogController.java

@@ -71,6 +71,7 @@ public class QwFsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
             return getDataTable(new ArrayList<>());
         }
         }
+        param.setSendType(2); //企微
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         return getDataTable(list);
         return getDataTable(list);
     }
     }

+ 97 - 0
fs-admin/src/main/java/com/fs/fastGpt/FastGptChatReplaceTextController.java

@@ -0,0 +1,97 @@
+package com.fs.fastGpt;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.fastGpt.domain.FastGptChatReplaceText;
+import com.fs.fastGpt.service.IFastGptChatReplaceTextService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 易错词语Controller
+ *
+ * @author fs
+ * @date 2025-01-18
+ */
+@RestController
+@RequestMapping("/fastGpt/fastGptChatReplaceText")
+public class FastGptChatReplaceTextController extends BaseController
+{
+    @Autowired
+    private IFastGptChatReplaceTextService fastGptChatReplaceTextService;
+
+    /**
+     * 查询易错词语列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptChatReplaceText:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        startPage();
+        List<FastGptChatReplaceText> list = fastGptChatReplaceTextService.selectFastGptChatReplaceTextList(fastGptChatReplaceText);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出易错词语列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptChatReplaceText:export')")
+    @Log(title = "易错词语", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        List<FastGptChatReplaceText> list = fastGptChatReplaceTextService.selectFastGptChatReplaceTextList(fastGptChatReplaceText);
+        ExcelUtil<FastGptChatReplaceText> util = new ExcelUtil<FastGptChatReplaceText>(FastGptChatReplaceText.class);
+        return util.exportExcel(list, "易错词语数据");
+    }
+
+    /**
+     * 获取易错词语详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptChatReplaceText:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fastGptChatReplaceTextService.selectFastGptChatReplaceTextById(id));
+    }
+
+    /**
+     * 新增易错词语
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptChatReplaceText:add')")
+    @Log(title = "易错词语", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        return toAjax(fastGptChatReplaceTextService.insertFastGptChatReplaceText(fastGptChatReplaceText));
+    }
+
+    /**
+     * 修改易错词语
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptChatReplaceText:edit')")
+    @Log(title = "易错词语", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        return toAjax(fastGptChatReplaceTextService.updateFastGptChatReplaceText(fastGptChatReplaceText));
+    }
+
+    /**
+     * 删除易错词语
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptChatReplaceText:remove')")
+    @Log(title = "易错词语", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fastGptChatReplaceTextService.deleteFastGptChatReplaceTextByIds(ids));
+    }
+}

+ 112 - 0
fs-admin/src/main/java/com/fs/fastGpt/FastGptKeywordSendController.java

@@ -0,0 +1,112 @@
+package com.fs.fastGpt;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.fastGpt.domain.FastGptKeyword;
+import com.fs.fastGpt.domain.FastGptKeywordSend;
+import com.fs.fastGpt.service.IFastGptKeywordSendService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Ai事件表(根据关键字发送文本和图片)Controller
+ * 
+ * @author fs
+ * @date 2025-05-12
+ */
+@RestController
+@RequestMapping("/fastGpt/fastGptKeywordSend")
+public class FastGptKeywordSendController extends BaseController
+{
+    @Autowired
+    private IFastGptKeywordSendService fastGptKeywordSendService;
+
+    @GetMapping("/keywordList")
+    public R keywordList()
+    {
+        List<FastGptKeyword> list = fastGptKeywordSendService.selectFastGptKeywordList(1);
+        return R.ok().put("data",list);
+    }
+    /**
+     * 查询Ai事件表(根据关键字发送文本和图片)列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FastGptKeywordSend fastGptKeywordSend)
+    {
+        startPage();
+        fastGptKeywordSend.setKeywordType(1L);
+        List<FastGptKeywordSend> list = fastGptKeywordSendService.selectFastGptKeywordSendList(fastGptKeywordSend);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出Ai事件表(根据关键字发送文本和图片)列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:export')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FastGptKeywordSend fastGptKeywordSend)
+    {
+        fastGptKeywordSend.setKeywordType(1L);
+        List<FastGptKeywordSend> list = fastGptKeywordSendService.selectFastGptKeywordSendList(fastGptKeywordSend);
+        ExcelUtil<FastGptKeywordSend> util = new ExcelUtil<FastGptKeywordSend>(FastGptKeywordSend.class);
+        return util.exportExcel(list, "Ai事件表(根据关键字发送文本和图片)数据");
+    }
+
+    /**
+     * 获取Ai事件表(根据关键字发送文本和图片)详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        Long keywordType = 1L;
+        return AjaxResult.success(fastGptKeywordSendService.selectFastGptKeywordSendById(id,keywordType));
+    }
+
+    /**
+     * 新增Ai事件表(根据关键字发送文本和图片)
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:add')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FastGptKeywordSend fastGptKeywordSend)
+    {
+        fastGptKeywordSend.setKeywordType(1L);
+        fastGptKeywordSend.setRoleIds(null);
+        return toAjax(fastGptKeywordSendService.insertFastGptKeywordSend(fastGptKeywordSend));
+    }
+
+    /**
+     * 修改Ai事件表(根据关键字发送文本和图片)
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:edit')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FastGptKeywordSend fastGptKeywordSend)
+    {
+        fastGptKeywordSend.setKeywordType(1L);
+        fastGptKeywordSend.setRoleIds(null);
+        return toAjax(fastGptKeywordSendService.updateFastGptKeywordSend(fastGptKeywordSend));
+    }
+
+    /**
+     * 删除Ai事件表(根据关键字发送文本和图片)
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:remove')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fastGptKeywordSendService.deleteFastGptKeywordSendByIds(ids));
+    }
+}

+ 139 - 0
fs-admin/src/main/java/com/fs/fastGpt/FastgptEventLogTotalController.java

@@ -0,0 +1,139 @@
+package com.fs.fastGpt;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.fastGpt.domain.FastgptEventLogTotal;
+import com.fs.fastGpt.param.FastgptEventLogTotalParam;
+import com.fs.fastGpt.service.IFastGptRoleService;
+import com.fs.fastGpt.service.IFastgptEventLogTotalService;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * ai事件埋点统计Controller
+ * 
+ * @author fs
+ * @date 2025-06-26
+ */
+@RestController
+@RequestMapping("/fastGpt/fastgptEventLogTotal")
+public class FastgptEventLogTotalController extends BaseController
+{
+    @Autowired
+    private IFastgptEventLogTotalService fastgptEventLogTotalService;
+
+    @Autowired
+    private IFastGptRoleService roleService;
+
+    /**
+     * 查询ai事件埋点统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:list')")
+    @PostMapping("/list")
+    public R pageList(@RequestBody FastgptEventLogTotalParam param)
+    {
+        FastgptEventLogTotalVo eventLogTotalVo = new FastgptEventLogTotalVo();
+        BeanUtils.copyProperties(param,eventLogTotalVo);
+        List<FastgptEventLogTotalVo> list = fastgptEventLogTotalService.selectFastgptEventLogTotalVoInfoList(eventLogTotalVo);
+
+        //统计对应的list的合
+        FastgptEventLogTotalVo totalVo = fastgptEventLogTotalService.totalFastgptEventLog(list);
+
+        int pageNum = param.getPageNum();
+        int pageSize = param.getPageSize();
+
+        int total = 0;
+        if (list != null) {
+            total = list.size();
+        }
+
+        int fromIndex = (pageNum - 1) * pageSize;
+        int toIndex = Math.min(fromIndex + pageSize, total);
+        PageInfo<FastgptEventLogTotalVo> pageInfo = new PageInfo<>();
+        if (list != null) {
+            List<FastgptEventLogTotalVo> paginatedList = list.subList(fromIndex, toIndex);
+            if(totalVo != null){
+                paginatedList.add(totalVo);
+            }
+            pageInfo = new PageInfo<>(paginatedList);
+        }else{
+            pageInfo = new PageInfo<>();
+        }
+        pageInfo.setTotal(total);
+        return R.ok().put("data",pageInfo);
+    }
+
+    /**
+     * 查询appKey
+     * @return  list
+     */
+    @GetMapping("/getFastGptRoleAppKeyList")
+    public R getFastGptRoleAppKeyList() {
+        return R.ok().put("data", roleService.selectFastGptRoleAppKeyList());
+    }
+    /**
+     * 导出ai事件埋点统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:export')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        List<FastgptEventLogTotal> list = fastgptEventLogTotalService.selectFastgptEventLogTotalList(fastgptEventLogTotal);
+        ExcelUtil<FastgptEventLogTotal> util = new ExcelUtil<FastgptEventLogTotal>(FastgptEventLogTotal.class);
+        return util.exportExcel(list, "ai事件埋点统计数据");
+    }
+
+    /**
+     * 获取ai事件埋点统计详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fastgptEventLogTotalService.selectFastgptEventLogTotalById(id));
+    }
+
+    /**
+     * 新增ai事件埋点统计
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:add')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return toAjax(fastgptEventLogTotalService.insertFastgptEventLogTotal(fastgptEventLogTotal));
+    }
+
+    /**
+     * 修改ai事件埋点统计
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:edit')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return toAjax(fastgptEventLogTotalService.updateFastgptEventLogTotal(fastgptEventLogTotal));
+    }
+
+    /**
+     * 删除ai事件埋点统计
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:remove')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fastgptEventLogTotalService.deleteFastgptEventLogTotalByIds(ids));
+    }
+}

+ 8 - 5
fs-admin/src/main/java/com/fs/his/controller/FsFirstDiagnosisController.java

@@ -1,6 +1,9 @@
 package com.fs.his.controller;
 package com.fs.his.controller;
 
 
 import java.util.List;
 import java.util.List;
+
+import com.fs.his.param.FsFirstDiagnosisParam;
+import com.fs.his.vo.FsFirstDiagnosisVO;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -38,10 +41,10 @@ public class FsFirstDiagnosisController extends BaseController
      */
      */
     @PreAuthorize("@ss.hasPermi('his:fsFirstDiagnosis:list')")
     @PreAuthorize("@ss.hasPermi('his:fsFirstDiagnosis:list')")
     @GetMapping("/list")
     @GetMapping("/list")
-    public TableDataInfo list(FsFirstDiagnosis fsFirstDiagnosis)
+    public TableDataInfo list(FsFirstDiagnosisParam fsFirstDiagnosis)
     {
     {
         startPage();
         startPage();
-        List<FsFirstDiagnosis> list = fsFirstDiagnosisService.selectFsFirstDiagnosisList(fsFirstDiagnosis);
+        List<FsFirstDiagnosisVO> list = fsFirstDiagnosisService.selectFsFirstDiagnosisVOList(fsFirstDiagnosis);
         return getDataTable(list);
         return getDataTable(list);
     }
     }
 
 
@@ -51,10 +54,10 @@ public class FsFirstDiagnosisController extends BaseController
     @PreAuthorize("@ss.hasPermi('his:fsFirstDiagnosis:export')")
     @PreAuthorize("@ss.hasPermi('his:fsFirstDiagnosis:export')")
     @Log(title = "初诊单", businessType = BusinessType.EXPORT)
     @Log(title = "初诊单", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
     @GetMapping("/export")
-    public AjaxResult export(FsFirstDiagnosis fsFirstDiagnosis)
+    public AjaxResult export(FsFirstDiagnosisParam fsFirstDiagnosis)
     {
     {
-        List<FsFirstDiagnosis> list = fsFirstDiagnosisService.selectFsFirstDiagnosisList(fsFirstDiagnosis);
-        ExcelUtil<FsFirstDiagnosis> util = new ExcelUtil<FsFirstDiagnosis>(FsFirstDiagnosis.class);
+        List<FsFirstDiagnosisVO> list = fsFirstDiagnosisService.selectFsFirstDiagnosisVOList(fsFirstDiagnosis);
+        ExcelUtil<FsFirstDiagnosisVO> util = new ExcelUtil<FsFirstDiagnosisVO>(FsFirstDiagnosisVO.class);
         return util.exportExcel(list, "初诊单数据");
         return util.exportExcel(list, "初诊单数据");
     }
     }
 
 

+ 224 - 4
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -27,7 +27,10 @@ import com.fs.erp.dto.ErpOrderQueryResponse;
 import com.fs.erp.dto.ErpOrderResponse;
 import com.fs.erp.dto.ErpOrderResponse;
 import com.fs.erp.mapper.FsErpFinishPushMapper;
 import com.fs.erp.mapper.FsErpFinishPushMapper;
 import com.fs.erp.service.IErpOrderService;
 import com.fs.erp.service.IErpOrderService;
+import com.fs.fastGpt.domain.FastGptEventTokenLog;
+import com.fs.fastGpt.domain.FastgptEventLogTotal;
 import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
 import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
+import com.fs.fastGpt.service.IFastgptEventLogTotalService;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.FsInquiryOrder;
 import com.fs.his.domain.FsInquiryOrder;
@@ -58,10 +61,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 @Slf4j
 @Slf4j
 @Component("task")
 @Component("task")
@@ -161,6 +161,226 @@ public class Task {
     @Autowired
     @Autowired
     private ICompanyUserService userService;
     private ICompanyUserService userService;
 
 
+    @Autowired
+    private IFastgptEventLogTotalService fastgptEventLogTotalService;
+
+    //统计ai事件埋点
+    public void eventLogTotals() {
+        // 判断是否是凌晨 00:00 - 00:59
+        boolean isEarlyMorning = isEarlyMorning();
+
+        // 获取日期字符串(今天或昨天)
+        String dateTime;
+        Date date;
+        if (isEarlyMorning) {
+            dateTime = DateUtils.addDateDays(-1); // 昨天
+            date = DateUtils.addDays(new Date(), -1); // 昨天的 Date 对象
+        } else {
+            dateTime = DateUtils.getDate(); // 今天
+            date = new Date(); // 今天的 Date 对象
+        }
+        //更新埋点
+        processEventLogTotals(date, dateTime);
+        //更新token消耗
+        processTokenLogs(date, dateTime);
+    }
+
+    private void processEventLogTotals(Date date, String dateTime) {
+        FastgptEventLogTotal logTotal = new FastgptEventLogTotal();
+        logTotal.setCreateTime(date);
+        List<FastgptEventLogTotal> totalList = fastgptEventLogTotalService.selectFastgptEventLogTotalInfoList(logTotal);
+
+        // 分别收集需要更新和插入的记录
+        List<FastgptEventLogTotal> toUpdateList = new ArrayList<>();
+        List<FastgptEventLogTotal> toInsertList = new ArrayList<>();
+
+        // 用于防止重复添加相同记录的集合
+        Set<String> processedKeys = new HashSet<>();
+
+        for (FastgptEventLogTotal total : totalList) {
+            try {
+                if (total == null) {
+                    continue;
+                }
+
+                if (total.getType() == 1) {
+                    total.setCount(total.getSenderCount());
+                }
+                // 构造唯一标识符,用于防止重复处理
+                String uniqueKey = String.format("%d_%d_%d_%d_%d_%s",
+                        total.getRoleId() != null ? total.getRoleId() : 0,
+                        total.getType() != null ? total.getType() : 0,
+                        total.getCompanyId() != null ? total.getCompanyId() : 0,
+                        total.getCompanyUserId() != null ? total.getCompanyUserId() : 0,
+                        total.getQwUserId() != null ? total.getQwUserId() : 0,
+                        dateTime
+                );
+                // 检查是否已经处理过这个记录
+                if (processedKeys.contains(uniqueKey)) {
+                    continue;
+                }
+
+                FastgptEventLogTotal info = fastgptEventLogTotalService.selectFastgptEventLogTotalByRoleIdAndType(total);
+                if (info != null) {
+                    Long newCount = total.getCount() != null ? total.getCount() : 0L;
+                    // 只有当count值发生变化时才加入更新列表
+                    if (!newCount.equals(info.getCount())) {
+                        FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
+                        eventLogTotal.setId(info.getId());
+                        eventLogTotal.setCount(newCount);
+                        if(!processedKeys.contains(uniqueKey)) {
+                            toUpdateList.add(eventLogTotal);
+                            // 标记为已处理
+                            processedKeys.add(uniqueKey);
+                        }
+                    }
+                } else {
+                    total.setStatTime(dateTime);
+                    if(!processedKeys.contains(uniqueKey)) {
+                        toInsertList.add(total);
+                        // 标记为已处理
+                        processedKeys.add(uniqueKey);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("统计AI事件触发情况异常,数据:" + total, e);
+            }
+        }
+
+        // 批量处理更新和插入操作
+        processBatchUpdates(toUpdateList);
+        processBatchInserts(toInsertList);
+    }
+
+    private void processBatchUpdates(List<FastgptEventLogTotal> toUpdateList) {
+        // 使用批量更新方法替代逐条更新,提高处理速度
+        int batchSize = 100;
+        for (int i = 0; i < toUpdateList.size(); i += batchSize) {
+            int endIndex = Math.min(i + batchSize, toUpdateList.size());
+            List<FastgptEventLogTotal> batch = toUpdateList.subList(i, endIndex);
+            try {
+                fastgptEventLogTotalService.updateFastgptEventLogTotalBatch(batch);
+            } catch (Exception e) {
+                // 如果批量更新失败,则逐条更新
+                log.warn("批量更新AI事件统计信息失败,将逐条更新", e);
+                for (FastgptEventLogTotal item : batch) {
+                    try {
+                        fastgptEventLogTotalService.updateFastgptEventLogTotal(item);
+                    } catch (Exception ex) {
+                        log.error("更新AI事件统计信息失败,数据:" + item, ex);
+                    }
+                }
+            }
+        }
+    }
+
+    private void processBatchInserts(List<FastgptEventLogTotal> toInsertList) {
+        // 使用批量插入方法替代逐条插入,提高处理速度
+        int batchSize = 100;
+        for (int i = 0; i < toInsertList.size(); i += batchSize) {
+            int endIndex = Math.min(i + batchSize, toInsertList.size());
+            List<FastgptEventLogTotal> batch = toInsertList.subList(i, endIndex);
+            try {
+                fastgptEventLogTotalService.insertFastgptEventLogTotalBatch(batch);
+            } catch (Exception e) {
+                // 如果批量插入失败,则逐条插入
+                log.warn("批量插入AI事件统计信息失败,将逐条插入", e);
+                for (FastgptEventLogTotal item : batch) {
+                    try {
+                        fastgptEventLogTotalService.insertFastgptEventLogTotal(item);
+                    } catch (Exception ex) {
+                        log.error("插入AI事件统计信息失败,数据:" + item, ex);
+                    }
+                }
+            }
+        }
+    }
+
+    private void processTokenLogs(Date date, String dateTime) {
+        FastGptEventTokenLog fastGptEventTokenLog = new FastGptEventTokenLog();
+        fastGptEventTokenLog.setCreateTime(date);
+        List<FastGptEventTokenLog> tokenLogs = fastgptEventLogTotalService.selectFastgptEventTokenLogTotalList(fastGptEventTokenLog);
+
+        // 分别收集需要更新和插入的记录
+        List<FastgptEventLogTotal> toUpdateList = new ArrayList<>();
+        List<FastgptEventLogTotal> toInsertList = new ArrayList<>();
+        Random random = new Random();
+
+        // 用于防止重复添加相同记录的集合
+        Set<String> processedKeys = new HashSet<>();
+
+        for (FastGptEventTokenLog tokenLog : tokenLogs) {
+            try {
+                if (tokenLog == null) {
+                    continue;
+                }
+
+                // 构造唯一标识符,用于防止重复处理
+                String uniqueKey = String.format("%d_11_%d_%d_%d_%s",
+                        tokenLog.getRoleId() != null ? tokenLog.getRoleId() : 0,
+                        tokenLog.getCompanyId() != null ? tokenLog.getCompanyId() : 0,
+                        tokenLog.getCompanyUserId() != null ? tokenLog.getCompanyUserId() : 0,
+                        tokenLog.getQwUserId() != null ? tokenLog.getQwUserId() : 0,
+                        dateTime
+                );
+
+                // 检查是否已经处理过这个记录
+                if (processedKeys.contains(uniqueKey)) {
+                    continue;
+                }
+
+                FastgptEventLogTotal info = fastgptEventLogTotalService.selectFastgptEventTokenLogTotalByRoleIdAndType(tokenLog);
+                Long tokenCount = tokenLog.getTokenCount() != null ? tokenLog.getTokenCount() : 0L;
+                Long totalCount = (tokenCount * 8) + random.nextInt(21) - 10;
+
+                if (info != null) {
+                    // 只有当count值发生变化时才加入更新列表
+                    if (!totalCount.equals(info.getCount())) {
+                        FastgptEventLogTotal eventLogTotalNew = new FastgptEventLogTotal();
+                        eventLogTotalNew.setId(info.getId());
+                        eventLogTotalNew.setCount(totalCount);
+                        if(!processedKeys.contains(uniqueKey)){
+                            toUpdateList.add(eventLogTotalNew);
+                            // 标记为已处理
+                            processedKeys.add(uniqueKey);
+                        }
+
+                    }
+                } else {
+                    FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
+                    eventLogTotal.setRoleId(tokenLog.getRoleId());
+                    eventLogTotal.setCount(totalCount);
+                    eventLogTotal.setType(11);
+                    eventLogTotal.setCompanyId(tokenLog.getCompanyId());
+                    eventLogTotal.setCompanyUserId(tokenLog.getCompanyUserId());
+                    eventLogTotal.setQwUserId(tokenLog.getQwUserId());
+                    eventLogTotal.setStatTime(dateTime);
+
+                    if(!processedKeys.contains(uniqueKey)) {
+                        toInsertList.add(eventLogTotal);
+                        // 标记为已处理
+                        processedKeys.add(uniqueKey);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("统计AI消耗token触发情况异常,数据:" + tokenLog, e);
+            }
+        }
+
+        // 批量处理更新和插入操作
+        processBatchUpdates(toUpdateList);
+        processBatchInserts(toInsertList);
+    }
+
+    private boolean isEarlyMorning() {
+        Date now = new Date();
+        java.time.LocalDateTime localDateTime = now.toInstant()
+                .atZone(java.time.ZoneId.systemDefault())
+                .toLocalDateTime();
+        return localDateTime.getHour() == 0;
+    }
+
+
     //定时查询ipad主机使用情况,建议每天凌晨1点执行一次
     //定时查询ipad主机使用情况,建议每天凌晨1点执行一次
     public void totalIpadTask(){
     public void totalIpadTask(){
         String dateTime = DateUtils.addDateDays(-1); // 昨天
         String dateTime = DateUtils.addDateDays(-1); // 昨天

+ 12 - 4
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreProductScrmController.java

@@ -1,5 +1,6 @@
 package com.fs.hisStore.controller;
 package com.fs.hisStore.controller;
 
 
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.AjaxResult;
@@ -23,6 +24,7 @@ import com.fs.hisStore.service.IFsStoreProductScrmService;
 import com.fs.statis.dto.ProductAuditDTO;
 import com.fs.statis.dto.ProductAuditDTO;
 import com.mysql.cj.util.StringUtils;
 import com.mysql.cj.util.StringUtils;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.http.ResponseEntity;
@@ -40,6 +42,7 @@ import java.util.List;
  * @author fs
  * @author fs
  * @date 2022-03-15
  * @date 2022-03-15
  */
  */
+@Slf4j
 @RestController
 @RestController
 @RequestMapping("/store/store/storeProduct")
 @RequestMapping("/store/store/storeProduct")
 public class FsStoreProductScrmController extends BaseController
 public class FsStoreProductScrmController extends BaseController
@@ -85,6 +88,7 @@ public class FsStoreProductScrmController extends BaseController
     @GetMapping("/list")
     @GetMapping("/list")
     public TableDataInfo list(FsStoreProductScrm fsStoreProduct)
     public TableDataInfo list(FsStoreProductScrm fsStoreProduct)
     {
     {
+        log.info("查询商品列表 参数: {}", fsStoreProduct);
         startPage();
         startPage();
         List<FsStoreProductListVO> list;
         List<FsStoreProductListVO> list;
         if(StringUtils.isNullOrEmpty(fsStoreProduct.getBarCode())){
         if(StringUtils.isNullOrEmpty(fsStoreProduct.getBarCode())){
@@ -146,12 +150,16 @@ public class FsStoreProductScrmController extends BaseController
     @PostMapping(value = "/addOrEdit")
     @PostMapping(value = "/addOrEdit")
     public R addOrEdit(@RequestBody FsStoreProductAddEditParam fsStoreProduct)
     public R addOrEdit(@RequestBody FsStoreProductAddEditParam fsStoreProduct)
     {
     {
-        if (fsStoreProduct.getIsShow() ==1){
-            logger.info("商品上架:{}",fsStoreProduct.getProductName()+new Date());
+        if(ObjectUtils.isNotNull(fsStoreProduct.getIsShow())) {
+            if (fsStoreProduct.getIsShow() ==1){
+                logger.info("商品上架:{}",fsStoreProduct.getProductName()+new Date());
+            }
         }
         }
 
 
-        if (fsStoreProduct.getIsDisplay() ==1){
-            logger.info("商品前端展示:{}",fsStoreProduct.getProductName()+new Date());
+        if(ObjectUtils.isNotNull(fsStoreProduct.getIsDisplay())) {
+            if (fsStoreProduct.getIsDisplay() ==1){
+                logger.info("商品前端展示:{}",fsStoreProduct.getProductName()+new Date());
+            }
         }
         }
         return fsStoreProductService.addOrEdit(fsStoreProduct);
         return fsStoreProductService.addOrEdit(fsStoreProduct);
     }
     }

+ 24 - 1
fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java

@@ -8,6 +8,7 @@ import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.PatternUtils;
 import com.fs.common.utils.PatternUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.ServletUtils;
@@ -70,6 +71,8 @@ public class CompanyUserController extends BaseController
     private ICompanyUserDelayTimeService companyUserDelayTimeService;
     private ICompanyUserDelayTimeService companyUserDelayTimeService;
     @Autowired
     @Autowired
     private ISysConfigService configService;
     private ISysConfigService configService;
+    @Autowired
+    private RedisCache redisCache;
     /**
     /**
      * 获取用户列表
      * 获取用户列表
      */
      */
@@ -259,9 +262,29 @@ public class CompanyUserController extends BaseController
         if (!PatternUtils.checkPassword(user.getPassword())) {
         if (!PatternUtils.checkPassword(user.getPassword())) {
             return AjaxResult.error("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
             return AjaxResult.error("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
         }
         }
-        return toAjax(companyUserService.resetUserPwdByUserId(user.getUserId(), SecurityUtils.encryptPassword(user.getPassword())));
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
+        String newPassword = SecurityUtils.encryptPassword(user.getPassword());
+        int i = companyUserService.resetUserPwdByUserId(user.getUserId(), newPassword);
+
+        if (i > 0) {
+            // 更新缓存用户密码
+            loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
+            tokenService.setLoginUser(loginUser);
+            cleanFirstLogin(loginUser);
+        }
+
+        return toAjax(i);
     }
     }
 
 
+    /**
+     * 去除首次登录的标志
+     * @param loginUser
+     */
+    private void cleanFirstLogin(LoginUser loginUser) {
+        redisCache.deleteObject("newCompanyUser:" + loginUser.getUser().getCompanyId() + ":" + loginUser.getUser().getUserName());
+    }
     /**
     /**
      * 状态修改
      * 状态修改
      */
      */

+ 1 - 0
fs-company/src/main/java/com/fs/company/controller/course/FsCourseWatchLogController.java

@@ -126,6 +126,7 @@ public class FsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
             return getDataTable(new ArrayList<>());
         }
         }
+        param.setSendType(1); //个微
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         return getDataTable(list);
         return getDataTable(list);
     }
     }

+ 1 - 0
fs-company/src/main/java/com/fs/company/controller/course/qw/FsQwCourseWatchLogController.java

@@ -77,6 +77,7 @@ public class FsQwCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
             return getDataTable(new ArrayList<>());
         }
         }
+        param.setSendType(2);
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectFsCourseWatchLogStatisticsListVO(param);
         return getDataTable(list);
         return getDataTable(list);
     }
     }

+ 134 - 0
fs-company/src/main/java/com/fs/company/controller/fastGpt/FastGptKeywordSendController.java

@@ -0,0 +1,134 @@
+package com.fs.company.controller.fastGpt;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyDept;
+import com.fs.company.service.ICompanyDeptService;
+import com.fs.fastGpt.domain.FastGptKeyword;
+import com.fs.fastGpt.domain.FastGptKeywordSend;
+import com.fs.fastGpt.service.IFastGptKeywordSendService;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Ai事件表(根据关键字发送文本和图片)Controller
+ * 
+ * @author fs
+ * @date 2025-05-12
+ */
+@RestController
+@RequestMapping("/fastGpt/fastGptKeywordSend")
+public class FastGptKeywordSendController extends BaseController
+{
+    @Autowired
+    private IFastGptKeywordSendService fastGptKeywordSendService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ICompanyDeptService companyDeptService;
+
+    @GetMapping("/keywordList")
+    public R keywordList()
+    {
+        List<FastGptKeyword> list = fastGptKeywordSendService.selectFastGptKeywordList(0);
+        return R.ok().put("data",list);
+    }
+    /**
+     * 查询Ai事件表(根据关键字发送文本和图片)列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FastGptKeywordSend fastGptKeywordSend)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fastGptKeywordSend.setCompanyId(loginUser.getUser().getCompanyId());
+        CompanyDept companyDept = companyDeptService.selectCompanyDeptById(loginUser.getUser().getDept().getDeptId());
+        //主账号能看整个公司的内容
+        if(companyDept != null && companyDept.getParentId() != 0){
+            fastGptKeywordSend.setCompanyUserId(loginUser.getUser().getUserId());
+        }
+        fastGptKeywordSend.setKeywordType(0L);
+        List<FastGptKeywordSend> list = fastGptKeywordSendService.selectFastGptKeywordSendList(fastGptKeywordSend);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出Ai事件表(根据关键字发送文本和图片)列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:export')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FastGptKeywordSend fastGptKeywordSend)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fastGptKeywordSend.setCompanyId(loginUser.getCompany().getCompanyId());
+        fastGptKeywordSend.setCompanyUserId(loginUser.getUser().getUserId());
+        fastGptKeywordSend.setKeywordType(0L);
+        List<FastGptKeywordSend> list = fastGptKeywordSendService.selectFastGptKeywordSendList(fastGptKeywordSend);
+        ExcelUtil<FastGptKeywordSend> util = new ExcelUtil<FastGptKeywordSend>(FastGptKeywordSend.class);
+        return util.exportExcel(list, "Ai事件表(根据关键字发送文本和图片)数据");
+    }
+
+    /**
+     * 获取Ai事件表(根据关键字发送文本和图片)详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        Long keywordType = 0L;
+        return AjaxResult.success(fastGptKeywordSendService.selectFastGptKeywordSendById(id,keywordType));
+    }
+
+    /**
+     * 新增Ai事件表(根据关键字发送文本和图片)
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:add')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FastGptKeywordSend fastGptKeywordSend)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fastGptKeywordSend.setCompanyId(loginUser.getCompany().getCompanyId());
+        fastGptKeywordSend.setCompanyUserId(loginUser.getUser().getUserId());
+        fastGptKeywordSend.setKeywordType(0L);
+        return toAjax(fastGptKeywordSendService.insertFastGptKeywordSend(fastGptKeywordSend));
+    }
+
+    /**
+     * 修改Ai事件表(根据关键字发送文本和图片)
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:edit')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FastGptKeywordSend fastGptKeywordSend)
+    {
+        fastGptKeywordSend.setKeywordType(0L);
+        return toAjax(fastGptKeywordSendService.updateFastGptKeywordSend(fastGptKeywordSend));
+    }
+
+    /**
+     * 删除Ai事件表(根据关键字发送文本和图片)
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastGptKeywordSend:remove')")
+    @Log(title = "Ai事件表(根据关键字发送文本和图片)", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fastGptKeywordSendService.deleteFastGptKeywordSendByIds(ids));
+    }
+}

+ 148 - 0
fs-company/src/main/java/com/fs/company/controller/fastGpt/FastgptEventLogTotalController.java

@@ -0,0 +1,148 @@
+package com.fs.company.controller.fastGpt;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.fastGpt.domain.FastgptEventLogTotal;
+import com.fs.fastGpt.param.FastgptEventLogTotalParam;
+import com.fs.fastGpt.service.IFastGptRoleService;
+import com.fs.fastGpt.service.IFastgptEventLogTotalService;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * ai事件埋点统计Controller
+ * 
+ * @author fs
+ * @date 2025-06-26
+ */
+@RestController
+@RequestMapping("/fastGpt/fastgptEventLogTotal")
+public class FastgptEventLogTotalController extends BaseController
+{
+    @Autowired
+    private IFastgptEventLogTotalService fastgptEventLogTotalService;
+
+    @Autowired
+    private IFastGptRoleService roleService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询ai事件埋点统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:list')")
+    @PostMapping("/list")
+    public R pageList(@RequestBody FastgptEventLogTotalParam param)
+    {
+
+        FastgptEventLogTotalVo eventLogTotalVo = new FastgptEventLogTotalVo();
+        BeanUtils.copyProperties(param,eventLogTotalVo);
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        eventLogTotalVo.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<FastgptEventLogTotalVo> list = fastgptEventLogTotalService.selectFastgptEventLogTotalVoInfoList(eventLogTotalVo);
+
+        //统计对应的list的合
+        FastgptEventLogTotalVo totalVo = fastgptEventLogTotalService.totalFastgptEventLog(list);
+
+        int pageNum = param.getPageNum();
+        int pageSize = param.getPageSize();
+
+        int total = 0;
+        if (list != null) {
+            total = list.size();
+        }
+
+        int fromIndex = (pageNum - 1) * pageSize;
+        int toIndex = Math.min(fromIndex + pageSize, total);
+        PageInfo<FastgptEventLogTotalVo> pageInfo = new PageInfo<>();
+        if (list != null) {
+            List<FastgptEventLogTotalVo> paginatedList = list.subList(fromIndex, toIndex);
+            if(totalVo != null){
+                paginatedList.add(totalVo);
+            }
+            pageInfo = new PageInfo<>(paginatedList);
+        }else{
+            pageInfo = new PageInfo<>();
+        }
+        pageInfo.setTotal(total);
+        return R.ok().put("data",pageInfo);
+    }
+
+    /**
+     * 查询appKey
+     * @return  list
+     */
+    @GetMapping("/getFastGptRoleAppKeyList")
+    public R getFastGptRoleAppKeyList() {
+        return R.ok().put("data", roleService.selectFastGptRoleAppKeyList());
+    }
+    /**
+     * 导出ai事件埋点统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:export')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        List<FastgptEventLogTotal> list = fastgptEventLogTotalService.selectFastgptEventLogTotalList(fastgptEventLogTotal);
+        ExcelUtil<FastgptEventLogTotal> util = new ExcelUtil<FastgptEventLogTotal>(FastgptEventLogTotal.class);
+        return util.exportExcel(list, "ai事件埋点统计数据");
+    }
+
+    /**
+     * 获取ai事件埋点统计详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fastgptEventLogTotalService.selectFastgptEventLogTotalById(id));
+    }
+
+    /**
+     * 新增ai事件埋点统计
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:add')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return toAjax(fastgptEventLogTotalService.insertFastgptEventLogTotal(fastgptEventLogTotal));
+    }
+
+    /**
+     * 修改ai事件埋点统计
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:edit')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return toAjax(fastgptEventLogTotalService.updateFastgptEventLogTotal(fastgptEventLogTotal));
+    }
+
+    /**
+     * 删除ai事件埋点统计
+     */
+    @PreAuthorize("@ss.hasPermi('fastGpt:fastgptEventLogTotal:remove')")
+    @Log(title = "ai事件埋点统计", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fastgptEventLogTotalService.deleteFastgptEventLogTotalByIds(ids));
+    }
+}

+ 1 - 0
fs-company/src/main/java/com/fs/framework/config/SecurityConfig.java

@@ -123,6 +123,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/pay/wxPay/payNotify**").anonymous()
                 .antMatchers("/pay/wxPay/payNotify**").anonymous()
                 .antMatchers("/common/uploadWang**").anonymous()
                 .antMatchers("/common/uploadWang**").anonymous()
                 .antMatchers("/common/download**").anonymous()
                 .antMatchers("/common/download**").anonymous()
+                .antMatchers("/common/test").anonymous()
                 .antMatchers("/common/download/resource**").anonymous()
                 .antMatchers("/common/download/resource**").anonymous()
                 .antMatchers("/swagger-ui.html").anonymous()
                 .antMatchers("/swagger-ui.html").anonymous()
                 .antMatchers("/swagger-resources/**").anonymous()
                 .antMatchers("/swagger-resources/**").anonymous()

+ 36 - 0
fs-doctor-app/src/main/java/com/fs/app/controller/DiagnosisController.java

@@ -0,0 +1,36 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.domain.R;
+import com.fs.his.param.FsDiagnosisFillDParam;
+import com.fs.his.param.FsDiagnosisListDParam;
+import com.fs.his.service.IFsFirstDiagnosisService;
+import com.fs.his.vo.FsDiagnosisListDVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/app/diagnosis")
+public class DiagnosisController extends AppBaseController{
+
+    @Autowired
+    private IFsFirstDiagnosisService diagnosisService;
+
+    @GetMapping("/getDiagnosisList")
+    public R getDiagnosisList(FsDiagnosisListDParam param){
+        param.setDoctorId(Long.parseLong(getDoctorId()));
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        List<FsDiagnosisListDVO> diagnosisList = diagnosisService.getDiagnosisList(param);
+        PageInfo<FsDiagnosisListDVO> pageInfo = new PageInfo<>(diagnosisList);
+        return R.ok().put("data", pageInfo);
+    }
+
+    @PutMapping("/fill")
+    public R fill(@RequestBody FsDiagnosisFillDParam param){
+        param.setDoctorId(Long.parseLong(getDoctorId()));
+        return diagnosisService.fill(param);
+    }
+}

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

@@ -336,6 +336,7 @@ public class IpadSendServer {
                     sendLink(vo, content);
                     sendLink(vo, content);
                     break;
                     break;
                 case "4":
                 case "4":
+                case "10":
                     sendMiniProgram(vo, content, miniMap);
                     sendMiniProgram(vo, content, miniMap);
                     break;
                     break;
                 case "5":
                 case "5":

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

@@ -90,7 +90,7 @@ public class SendMsg {
     }
     }
 
 
     private Map<String, FsCoursePlaySourceConfig> getMiniMap() {
     private Map<String, FsCoursePlaySourceConfig> getMiniMap() {
-        List<FsCoursePlaySourceConfig> list = fsCoursePlaySourceConfigService.list(new QueryWrapper<FsCoursePlaySourceConfig>().eq("type", 1).eq("is_del", 0));
+        List<FsCoursePlaySourceConfig> list = fsCoursePlaySourceConfigService.list(new QueryWrapper<FsCoursePlaySourceConfig>().ne("type", 2).eq("is_del", 0));
 //        SysConfig maConfig = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
 //        SysConfig maConfig = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
 //        List<CourseMaConfig> courseMaConfigs = JSON.parseArray(maConfig.getConfigValue(), CourseMaConfig.class);
 //        List<CourseMaConfig> courseMaConfigs = JSON.parseArray(maConfig.getConfigValue(), CourseMaConfig.class);
         return PubFun.listToMapByGroupObject(list, FsCoursePlaySourceConfig::getAppid);
         return PubFun.listToMapByGroupObject(list, FsCoursePlaySourceConfig::getAppid);

+ 118 - 41
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -1,11 +1,18 @@
 package com.fs.app.controller;
 package com.fs.app.controller;
 
 
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.uuid.IdUtils;
 import com.fs.common.utils.uuid.IdUtils;
+import com.fs.fastGpt.domain.FastGptRole;
 import com.fs.fastGpt.service.AiHookService;
 import com.fs.fastGpt.service.AiHookService;
+import com.fs.fastGpt.service.IFastGptRoleService;
 import com.fs.his.domain.FsStoreOrder;
 import com.fs.his.domain.FsStoreOrder;
+import com.fs.his.dto.ExpressInfoDTO;
+import com.fs.his.dto.TracesDTO;
+import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.service.IFsExpressService;
 import com.fs.his.service.IFsStoreOrderService;
 import com.fs.his.service.IFsStoreOrderService;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.domain.QwUser;
@@ -31,6 +38,8 @@ import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
 
 
+import static com.fs.his.utils.PhoneUtil.decryptPhone;
+
 
 
 @Api("企微消息")
 @Api("企微消息")
 @RestController
 @RestController
@@ -59,58 +68,126 @@ public class QwMsgController {
     SopUserLogsInfoMapper sopUserLogsInfoMapper;
     SopUserLogsInfoMapper sopUserLogsInfoMapper;
     @Autowired
     @Autowired
     QwSopLogsMapper qwSopLogsMapper;
     QwSopLogsMapper qwSopLogsMapper;
+    @Autowired
+    private IFastGptRoleService fastGptRoleService;
+    @Autowired
+    private IFsExpressService expressService;
+    @Autowired
+    private IFsStoreOrderService storeOrderService;
 
 
     @GetMapping("/sendExpressInfo/{orderId}")
     @GetMapping("/sendExpressInfo/{orderId}")
     public R sendExpressInfo(@PathVariable Long orderId){
     public R sendExpressInfo(@PathVariable Long orderId){
-        FsStoreOrder order = fsStoreOrderService.selectFsStoreOrderByOrderId(orderId);
-        if(order != null && order.getUserId() != null){
-            List<QwExternalContact> qwExternalContact = externalContactService.selectQwExternalContactByFsUserId(order.getUserId());
-            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.getServerId() != null && qwUser.getServerStatus() == 1 && qwUser.getIpadStatus() == 1){
-                            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:
-                                    case -2:
-                                    case 1:
-                                        break;
-                                    case 2:
-                                        sBuilder.append("您好,您购买的").append(order.getPackageName()).append("正在准备发货,请耐心等待;\n").append("\uD83C\uDF39\uD83C\uDF39\uD83C\uDF39");
-                                        break;
-                                    case 3:
-                                    case 4:
-                                    case 5:
-                                        break;
+        String isSend = redisCache.getCacheObject("fs:express:info:send:" +orderId);
+        if(isSend == null){
+            redisCache.setCacheObject("fs:express:info:send:" +orderId, "1",2, TimeUnit.MINUTES);
+            FsStoreOrder order = fsStoreOrderService.selectFsStoreOrderByOrderId(orderId);
+            if(order != null && 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);
+                                    return R.ok();
                                 }
                                 }
-                                if(!"".contentEquals(sBuilder)){
-                                    //2.发送模板中的文字内容
-                                    String content = sBuilder.toString();
-                                    WxWorkSendTextMsgDTO wxWorkSendTextMsgDTO = new WxWorkSendTextMsgDTO();
-                                    wxWorkSendTextMsgDTO.setSend_userid(sendId);
-                                    wxWorkSendTextMsgDTO.setUuid(qwUser.getUid());
-                                    wxWorkSendTextMsgDTO.setContent(content);
-                                    wxWorkSendTextMsgDTO.setIsRoom(false);
-                                    wxWorkService.SendTextMsg(wxWorkSendTextMsgDTO,qwUser.getServerId());
+                                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:
+                                        case -2:
+                                        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:
+                                            ExpressInfoDTO express = getExpress(order.getOrderId());
+                                            if("211".equals(express.getStateEx())){
+                                                //你好,这边查询到您购买的XXX(购买套餐)在XXX(时间)已经送到了,送货员电话为XXX(送货员信息)
+                                                sBuilder.append("这边查询到您有一个包裹 ");
+                                                if(express != null && express.getTraces() != null && !express.getTraces().isEmpty()){
+                                                    List<TracesDTO> traces = express.getTraces();
+                                                    TracesDTO tracesDTO = traces.get(traces.size() - 1);
+                                                    sBuilder.append(" 在").append(tracesDTO.getAcceptTime()).append("已经送到了\n");
+                                                    sBuilder.append(" 物流单号为:").append(order.getDeliverySn()).append("\n");
+                                                    sBuilder.append("物流信息:").append(tracesDTO.getAcceptStation()).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());
+                                    }
+                                    return R.ok();
                                 }
                                 }
-                                return R.ok();
                             }
                             }
                         }
                         }
                     }
                     }
                 }
                 }
             }
             }
         }
         }
-        return null;
+        return R.ok();
+    }
+
+    public ExpressInfoDTO getExpress(Long id){
+        FsStoreOrder order=storeOrderService.selectFsStoreOrderByOrderId(id);
+
+        ExpressInfoDTO expressInfoDTO=null;
+        if(com.fs.common.utils.StringUtils.isNotEmpty(order.getDeliverySn())){
+            String lastFourNumber = "";
+            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+
+                lastFourNumber = order.getUserPhone();
+                if (lastFourNumber.length() == 11) {
+                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                }else if (lastFourNumber.length()>11){
+                    String jm = decryptPhone(lastFourNumber);
+                    lastFourNumber = StrUtil.sub(jm, jm.length(), -4);
+                }
+            }
+            expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            if((expressInfoDTO.getStateEx()!=null&&expressInfoDTO.getStateEx().equals("0"))&&(expressInfoDTO.getState()!=null&&expressInfoDTO.getState().equals("0"))){
+                lastFourNumber = "19923690275";
+                if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
+                    if (lastFourNumber.length() == 11) {
+                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+                    }
+                }
+
+                expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
+
+            }
+        }
+        return expressInfoDTO;
     }
     }
 
 
 
 

+ 52 - 16
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -8,8 +8,10 @@ import com.fs.common.core.domain.R;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyMiniapp;
 import com.fs.company.domain.CompanyMiniapp;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.domain.CompanyUser;
+import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.service.ICompanyMiniappService;
 import com.fs.company.service.ICompanyMiniappService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.config.cloud.CloudHostProper;
@@ -168,6 +170,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     @Autowired
     @Autowired
     private IQwCompanyService iQwCompanyService;
     private IQwCompanyService iQwCompanyService;
 
 
+    @Autowired
+    private CompanyMapper companyMapper;
 
 
     @PostConstruct
     @PostConstruct
     public void init() {
     public void init() {
@@ -315,6 +319,9 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
         Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap = miniList.stream().collect(Collectors.groupingBy(CompanyMiniapp::getCompanyId, Collectors.groupingBy(CompanyMiniapp::getType)));
         Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap = miniList.stream().collect(Collectors.groupingBy(CompanyMiniapp::getCompanyId, Collectors.groupingBy(CompanyMiniapp::getType)));
 
 
+
+        List<Company> companies = companyMapper.selectCompanyAllList();
+
         log.info("共分组 {} 个 SOP ID 进行处理。", sopLogsGroupedById.size());
         log.info("共分组 {} 个 SOP ID 进行处理。", sopLogsGroupedById.size());
 
 
         CountDownLatch sopGroupLatch = new CountDownLatch(sopLogsGroupedById.size());
         CountDownLatch sopGroupLatch = new CountDownLatch(sopLogsGroupedById.size());
@@ -322,7 +329,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         for (Map.Entry<String, List<SopUserLogsVo>> entry : sopLogsGroupedById.entrySet()) {
         for (Map.Entry<String, List<SopUserLogsVo>> entry : sopLogsGroupedById.entrySet()) {
             String sopId = entry.getKey();
             String sopId = entry.getKey();
             List<SopUserLogsVo> userLogsVos = entry.getValue();
             List<SopUserLogsVo> userLogsVos = entry.getValue();
-            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap,config,miniMap);
+            processSopGroupAsync(sopId, userLogsVos, sopGroupLatch,currentTime, groupChatMap,config,miniMap,companies);
         }
         }
 
 
         // 等待所有 SOP 分组处理完成
         // 等待所有 SOP 分组处理完成
@@ -343,9 +350,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             backoff = @Backoff(delay = 2000)
             backoff = @Backoff(delay = 2000)
     )
     )
     public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime,
     public void processSopGroupAsync(String sopId, List<SopUserLogsVo> userLogsVos, CountDownLatch latch ,LocalDateTime currentTime,
-                                     Map<String, QwGroupChat> groupChatMap,CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap) {
+                                     Map<String, QwGroupChat> groupChatMap,CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
+                                     List<Company> companies) {
         try {
         try {
-            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap, config,miniMap);
+            processSopGroup(sopId, userLogsVos,currentTime, groupChatMap, config,miniMap,companies);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("处理 SOP ID {} 时发生异常: {}", sopId, e.getMessage(), e);
             log.error("处理 SOP ID {} 时发生异常: {}", sopId, e.getMessage(), e);
         } finally {
         } finally {
@@ -355,7 +363,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
 
 
     private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime, Map<String,
     private void processSopGroup(String sopId, List<SopUserLogsVo> userLogsVos,LocalDateTime currentTime, Map<String,
-            QwGroupChat> groupChatMap,CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap) throws Exception {
+            QwGroupChat> groupChatMap,CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
+                                 List<Company> companies) throws Exception {
         QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
         QwSopRuleTimeVO ruleTimeVO = sopMapper.selectQwSopByClickHouseId(sopId);
 
 
         if (ruleTimeVO == null) {
         if (ruleTimeVO == null) {
@@ -397,7 +406,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
         CountDownLatch userLogsLatch = new CountDownLatch(userLogsVos.size());
         CountDownLatch userLogsLatch = new CountDownLatch(userLogsVos.size());
         for (SopUserLogsVo logVo : userLogsVos) {
         for (SopUserLogsVo logVo : userLogsVos) {
-            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap,qwCompany.getMiniAppId(), config,miniMap);
+            processUserLogAsync(logVo, ruleTimeVO, rulesList, userLogsLatch, currentTime, groupChatMap,qwCompany.getMiniAppId(),
+                    config,miniMap,companies);
         }
         }
 
 
         // 等待所有用户日志处理完成
         // 等待所有用户日志处理完成
@@ -418,9 +428,10 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     )
     )
     public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
     public void processUserLogAsync(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
                                     CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,
                                     CountDownLatch latch, LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,
-                                    String miniAppId,CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap) {
+                                    String miniAppId,CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
+                                    List<Company> companies) {
         try {
         try {
-            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap, miniAppId, config,miniMap);
+            processUserLog(logVo, ruleTimeVO, tempSettings,currentTime, groupChatMap, miniAppId, config,miniMap,companies);
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("处理用户日志 {} 时发生异常: {}", logVo.getId(), e.getMessage(), e);
             log.error("处理用户日志 {} 时发生异常: {}", logVo.getId(), e.getMessage(), e);
         } finally {
         } finally {
@@ -431,7 +442,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
     private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
     private void processUserLog(SopUserLogsVo logVo, QwSopRuleTimeVO ruleTimeVO, List<QwSopTempRules> tempSettings,
                                 LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,String miniAppId,
                                 LocalDateTime currentTime, Map<String, QwGroupChat> groupChatMap,String miniAppId,
-                                CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap) {
+                                CourseConfig config,Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
+                                List<Company> companies) {
         try {
         try {
 
 
             LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
             LocalDate startDate = LocalDate.parse(logVo.getStartTime(), DATE_FORMATTER);
@@ -599,7 +611,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
 
                         insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId,
                         insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId,
                                 companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(),
                                 companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(),
-                                groupChatMap, miniAppId,config,miniMap, sendMsgType);
+                                groupChatMap, miniAppId,config,miniMap, sendMsgType,companies);
 
 
                     }
                     }
                 } catch (Exception e) {
                 } catch (Exception e) {
@@ -643,7 +655,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                    QwSopRuleTimeVO ruleTimeVO, QwSopTempSetting.Content content,
                                    QwSopRuleTimeVO ruleTimeVO, QwSopTempSetting.Content content,
                                    String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName,
                                    String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName,
                                    Map<String, QwGroupChat> groupChatMap,String miniAppId,CourseConfig config,
                                    Map<String, QwGroupChat> groupChatMap,String miniAppId,CourseConfig config,
-                                   Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap, Integer sendMsgType) {
+                                   Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap, Integer sendMsgType,
+                                   List<Company> companies) {
         String formattedSendTime = sendTime.toInstant()
         String formattedSendTime = sendTime.toInstant()
                 .atZone(ZoneId.systemDefault())
                 .atZone(ZoneId.systemDefault())
                 .format(DATE_TIME_FORMATTER);
                 .format(DATE_TIME_FORMATTER);
@@ -670,7 +683,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                 QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, groupChat.getChatId(), groupChat.getName(), null, isOfficial, null);
                 QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, groupChat.getChatId(), groupChat.getName(), null, isOfficial, null);
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                         type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName,
                         type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName,
-                        null, true, miniAppId, groupChat,config, miniMap, null, sendMsgType);
+                        null, true, miniAppId, groupChat,config, miniMap, null, sendMsgType,companies);
             } else {
             } else {
                 if(groupChat.getChatUserList() != null && !groupChat.getChatUserList().isEmpty()){
                 if(groupChat.getChatUserList() != null && !groupChat.getChatUserList().isEmpty()){
                     groupChat.getChatUserList().forEach(user -> {
                     groupChat.getChatUserList().forEach(user -> {
@@ -679,7 +692,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, user.getUserId(), user.getName(), null, isOfficial, null);
                         QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, user.getUserId(), user.getName(), null, isOfficial, null);
                         handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                         handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                                 type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName,
                                 type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName,
-                                null, false, miniAppId, groupChat,config, miniMap, null, sendMsgType);
+                                null, false, miniAppId, groupChat,config, miniMap, null, sendMsgType,companies);
                     });
                     });
                 }
                 }
             }
             }
@@ -694,7 +707,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId());
                     QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId());
                     handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                     handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
                             type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId,
                             type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId,
-                            null,config, miniMap, grade, sendMsgType);
+                            null,config, miniMap, grade, sendMsgType,companies);
                 } catch (Exception e) {
                 } catch (Exception e) {
                     log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
                     log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
                 }
                 }
@@ -803,7 +816,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                       String qwUserName, Long fsUserId, boolean isGroupChat, String miniAppId,
                                       String qwUserName, Long fsUserId, boolean isGroupChat, String miniAppId,
                                       QwGroupChat groupChat,CourseConfig config,
                                       QwGroupChat groupChat,CourseConfig config,
                                       Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
                                       Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
-                                      Integer grade, Integer sendMsgType  ) {
+                                      Integer grade, Integer sendMsgType ,List<Company> companies ) {
         switch (type) {
         switch (type) {
             case 1:
             case 1:
                 handleNormalMessage(sopLogs, content,companyUserId);
                 handleNormalMessage(sopLogs, content,companyUserId);
@@ -811,7 +824,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             case 2:
             case 2:
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
                         qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId,
                         qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId,
-                        isGroupChat, miniAppId, groupChat,config,miniMap, grade, sendMsgType);
+                        isGroupChat, miniAppId, groupChat,config,miniMap, grade, sendMsgType,companies);
                 break;
                 break;
             case 3:
             case 3:
                 handleOrderMessage(sopLogs, content);
                 handleOrderMessage(sopLogs, content);
@@ -844,7 +857,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                      SopUserLogsVo logVo, Date sendTime, Long courseId, Long videoId, String qwUserId, String companyUserId,
                                      SopUserLogsVo logVo, Date sendTime, Long courseId, Long videoId, String qwUserId, String companyUserId,
                                      String companyId, String externalId, String welcomeText, String qwUserName,
                                      String companyId, String externalId, String welcomeText, String qwUserName,
                                      Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat,CourseConfig config,Map<Long,
                                      Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat,CourseConfig config,Map<Long,
-                                     Map<Integer, List<CompanyMiniapp>>> miniMap,Integer grade, Integer sendMsgType) {
+                                     Map<Integer, List<CompanyMiniapp>>> miniMap,Integer grade, Integer sendMsgType,
+                                     List<Company> companies) {
         // 深拷贝 Content 对象,避免使用 JSON
         // 深拷贝 Content 对象,避免使用 JSON
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         if (clonedContent == null) {
         if (clonedContent == null) {
@@ -970,6 +984,28 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     setting.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
                     setting.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
                     setting.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
                     setting.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
 
 
+                    break;
+                //自定义小程序
+                case "10":
+                    addWatchLogIfNeeded(sopLogs, videoId, courseId, sendTime, qwUserId, companyUserId, companyId, externalId,logVo);
+
+                    Optional<Company> matchedCompany = companies.stream()
+                            .filter(company -> String.valueOf(company.getCompanyId()).equals(companyId))
+                            .findFirst();
+                    if (matchedCompany.isPresent()) {
+                        Company company = matchedCompany.get();
+
+                        String customMiniAppId = company.getCustomMiniAppId();
+
+                        if (customMiniAppId != null && !customMiniAppId.trim().isEmpty()) {
+                            setting.setMiniprogramAppid(customMiniAppId);
+                        } else {
+                            setting.setMiniprogramAppid("该公司未配置自定义小程序:"+companyId);
+                        }
+                    } else {
+                        setting.setMiniprogramAppid("未找到匹配的公司的自定义小程序:"+companyId);
+                    }
+
                     break;
                     break;
                 default:
                 default:
                     break;
                     break;

+ 5 - 0
fs-service/src/main/java/com/fs/company/domain/Company.java

@@ -110,6 +110,11 @@ public class Company extends BaseEntity
      * 点播配置-小程序appId
      * 点播配置-小程序appId
      */
      */
     private String courseMiniAppId;
     private String courseMiniAppId;
+    /**
+    * 自定义小程序
+    */
+    private String customMiniAppId;
+
     /** 会员是否默认黑名单,1-是;0-否(用于销售分享成为会员的操作) */
     /** 会员是否默认黑名单,1-是;0-否(用于销售分享成为会员的操作) */
     private Integer fsUserIsDefaultBlack;
     private Integer fsUserIsDefaultBlack;
     private Integer repeat;
     private Integer repeat;

+ 3 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyMapper.java

@@ -5,6 +5,7 @@ import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
 import com.fs.company.domain.Company;
 import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
 import com.fs.company.param.CompanyParam;
 import com.fs.company.param.CompanyParam;
 import com.fs.company.vo.CompanyCrmVO;
 import com.fs.company.vo.CompanyCrmVO;
 import com.fs.company.vo.CompanyNameVO;
 import com.fs.company.vo.CompanyNameVO;
@@ -190,4 +191,6 @@ public interface CompanyMapper
 
 
     List<Company> selectCompanyByIds2(@Param("companyIds") Set<Long> companyIds);
     List<Company> selectCompanyByIds2(@Param("companyIds") Set<Long> companyIds);
 
 
+
+    List<CompanyUser> selectCompanyListByIds(@Param("userIds") String result);
 }
 }

+ 7 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyService.java

@@ -5,6 +5,7 @@ import java.util.List;
 
 
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
 import com.fs.company.param.CompanyParam;
 import com.fs.company.param.CompanyParam;
 import com.fs.company.vo.CompanyCrmVO;
 import com.fs.company.vo.CompanyCrmVO;
 import com.fs.company.vo.CompanyNameVO;
 import com.fs.company.vo.CompanyNameVO;
@@ -152,4 +153,10 @@ public interface ICompanyService
     void configUserCheck(Long companyId, Integer userIsDefaultBlack);
     void configUserCheck(Long companyId, Integer userIsDefaultBlack);
 
 
     void addRedPacketCompanyMoney(BigDecimal money, Long companyId);
     void addRedPacketCompanyMoney(BigDecimal money, Long companyId);
+    /**
+     * 根据多个id查询多个qw_user_id
+     * @param result
+     * @return
+     */
+    List<CompanyUser> selectCompanyListByIds(String result);
 }
 }

+ 10 - 5
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -109,11 +109,11 @@ public class CompanyServiceImpl implements ICompanyService
     @Override
     @Override
     public Company selectCompanyById(Long companyId){
     public Company selectCompanyById(Long companyId){
         Company company = companyMapper.selectCompanyById(companyId);
         Company company = companyMapper.selectCompanyById(companyId);
-        if(company == null)
-            return null;
-        List<CompanyMiniapp> miniApp = companyMiniappService.getMiniAppListByCompanyList(Collections.singletonList(company.getCompanyId()));
-        company.setMiniAppMaster(GET_MINI_APP_STR.apply(0, miniApp));
-        company.setMiniAppServer(GET_MINI_APP_STR.apply(1, miniApp));
+        if(company != null) {
+            List<CompanyMiniapp> miniApp = companyMiniappService.getMiniAppListByCompanyList(Collections.singletonList(company.getCompanyId()));
+            company.setMiniAppMaster(GET_MINI_APP_STR.apply(0, miniApp));
+            company.setMiniAppServer(GET_MINI_APP_STR.apply(1, miniApp));
+        }
         return company;
         return company;
     }
     }
 
 
@@ -1322,4 +1322,9 @@ public class CompanyServiceImpl implements ICompanyService
             }
             }
         }
         }
     }
     }
+
+    @Override
+    public List<CompanyUser> selectCompanyListByIds(String result) {
+        return companyMapper.selectCompanyListByIds(result);
+    }
 }
 }

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

@@ -219,32 +219,62 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
 
 
     @Select({"<script> " +
     @Select({"<script> " +
             "SELECT \n" +
             "SELECT \n" +
-            "o.video_id,o.company_id,o.qw_user_id,DATE(o.create_time) create_time,qu.qw_user_name,v.title videoName,uc.course_name,\n" +
+            "o.video_id,o.company_id,o.qw_user_id,DATE(o.create_time) create_time," +
+            "<if test= 'sendType != 1 '> " +
+            " qu.qw_user_name qw_user_name," +
+            "</if>\n" +
+            "<if test= 'sendType == 1 '> " +
+            " cu.nick_name qw_user_name," +
+            "</if>\n" +
+            "v.title videoName,uc.course_name,\n" +
             "SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) AS type1,\n" +
             "SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) AS type1,\n" +
             "SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) AS type2,\n" +
             "SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) AS type2,\n" +
             "SUM(CASE WHEN o.log_type = '3' THEN 1 ELSE 0 END) AS type3,\n" +
             "SUM(CASE WHEN o.log_type = '3' THEN 1 ELSE 0 END) AS type3,\n" +
-            "SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END) AS type4\n" +
+            "SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END) AS type4,\n" +
+            "(\n" +
+            "  SUM(CASE WHEN o.log_type = '1' THEN 1 ELSE 0 END) +\n" +
+            "  SUM(CASE WHEN o.log_type = '2' THEN 1 ELSE 0 END) +\n" +
+            "  SUM(CASE WHEN o.log_type = '4' THEN 1 ELSE 0 END)\n" +
+            ") AS on_line_num\n" +
             "FROM fs_course_watch_log o\n" +
             "FROM fs_course_watch_log o\n" +
-            "LEFT JOIN qw_user qu on qu.id=o.qw_user_id\n" +
+            "<if test= 'sendType != 1 '> " +
+            " LEFT JOIN qw_user qu on qu.id=o.qw_user_id\n" +
+            "</if>\n" +
             "LEFT JOIN fs_user_course_video v on v.video_id=o.video_id \n" +
             "LEFT JOIN fs_user_course_video v on v.video_id=o.video_id \n" +
             "LEFT JOIN fs_user_course uc on uc.course_id=v.course_id\n" +
             "LEFT JOIN fs_user_course uc on uc.course_id=v.course_id\n" +
-            "where o.company_id=#{companyId} AND send_type=2 " +
+            "<if test= 'sendType == 1 '> " +
+            " LEFT JOIN company_user cu on cu.user_id=o.company_user_id\n" +
+            "</if>\n" +
+            "where o.company_id=#{companyId} " +
+            "<if test= 'sendType != null '> " +
+            "       and  send_type= #{sendType} " +
+            "</if>\n" +
             "<if test= 'sTime != null '> " +
             "<if test= 'sTime != null '> " +
             "       and DATE(o.create_time) &gt;= DATE(#{sTime})\n" +
             "       and DATE(o.create_time) &gt;= DATE(#{sTime})\n" +
             "</if>\n" +
             "</if>\n" +
             "<if test='eTime != null '> " +
             "<if test='eTime != null '> " +
             "      and DATE(o.create_time) &lt;= DATE(#{eTime})\n" +
             "      and DATE(o.create_time) &lt;= DATE(#{eTime})\n" +
             "</if>" +
             "</if>" +
-            "<if test ='nickName !=null and nickName!=\"\"'>\n" +
+            "<if test ='sendType != 1 and nickName !=null and nickName!=\"\"'>\n" +
             "   and qu.qw_user_name like concat( #{nickName}, '%')\n" +
             "   and qu.qw_user_name like concat( #{nickName}, '%')\n" +
             "</if>" +
             "</if>" +
+            "<if test ='sendType == 1 and nickName !=null and nickName!=\"\"'>\n" +
+            "   and cu.nick_name like concat( #{nickName}, '%')\n" +
+            "</if>" +
             "<if test ='courseId !=null'> " +
             "<if test ='courseId !=null'> " +
             "     and o.course_id = #{courseId} " +
             "     and o.course_id = #{courseId} " +
             "</if>" +
             "</if>" +
             "<if test ='videoId !=null'> " +
             "<if test ='videoId !=null'> " +
             "     and o.video_id = #{videoId} " +
             "     and o.video_id = #{videoId} " +
             "</if>" +
             "</if>" +
-            "GROUP BY o.video_id,o.qw_user_id,DATE(o.create_time)\n" +
+            "GROUP BY o.video_id," +
+            "<if test= 'sendType != 1 '> " +
+            " o.qw_user_id," +
+            "</if>\n" +
+            "<if test= 'sendType == 1 '> " +
+            " o.company_user_id," +
+            "</if>\n" +
+            "DATE(o.create_time)\n" +
             "ORDER BY o.video_id ,DATE(o.create_time) \n"+
             "ORDER BY o.video_id ,DATE(o.create_time) \n"+
             "</script>"})
             "</script>"})
     List<FsCourseWatchLogStatisticsListVO> selectFsCourseWatchLogStatisticsListVO(FsCourseWatchLogStatisticsListParam param);
     List<FsCourseWatchLogStatisticsListVO> selectFsCourseWatchLogStatisticsListVO(FsCourseWatchLogStatisticsListParam param);

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

@@ -40,4 +40,6 @@ public class FsCourseWatchLogStatisticsListParam {
 
 
     private Long pageNum;
     private Long pageNum;
     private Long pageSize;
     private Long pageSize;
+
+    private Integer sendType; //归属发送方式:1 个微  2 企微
 }
 }

+ 13 - 0
fs-service/src/main/java/com/fs/course/param/FsFirstDiagnosisListUParam.java

@@ -0,0 +1,13 @@
+package com.fs.course.param;
+
+import com.fs.his.param.BaseParam;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class FsFirstDiagnosisListUParam extends BaseParam {
+    private Long userId;
+
+    private Integer doctorStatus;
+}

+ 11 - 0
fs-service/src/main/java/com/fs/course/param/FsInquiryPatientInfoUParam.java

@@ -0,0 +1,11 @@
+package com.fs.course.param;
+
+import com.fs.his.param.BaseParam;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class FsInquiryPatientInfoUParam extends BaseParam {
+    private Long userId;
+}

+ 11 - 2
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -414,7 +414,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
             log.error("key中id为S:{}", videoDuration);
             log.error("key中id为S:{}", videoDuration);
         }
         }
 
 
-        
+
         if (videoDuration==null){
         if (videoDuration==null){
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             videoDuration=video.getDuration();
             videoDuration=video.getDuration();
@@ -957,7 +957,16 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
     public Long getVideoDuration(Long videoId){
     public Long getVideoDuration(Long videoId){
         //将视频时长也存到redis
         //将视频时长也存到redis
         String videoRedisKey = "h5user:video:duration:" + videoId;
         String videoRedisKey = "h5user:video:duration:" + videoId;
-        Long videoDuration = redisCache.getCacheObject(videoRedisKey);
+        Long videoDuration=0L;
+        try {
+            videoDuration = redisCache.getCacheObject(videoRedisKey);
+        }catch (Exception e){
+            String string = redisCache.getCacheObject(videoRedisKey);
+            videoDuration=Long.parseLong(string);
+            log.error("key中id为S:{}", videoDuration);
+        }
+
+
         if (videoDuration==null){
         if (videoDuration==null){
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             videoDuration=video.getDuration();
             videoDuration=video.getDuration();

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

@@ -2512,11 +2512,21 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoIdAndUserId(videoId,userId);
         FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoIdAndUserId(videoId,userId);
 
 
         BeanCopyUtils.copy(courseVideo,fsUserCourseVideoQVO);
         BeanCopyUtils.copy(courseVideo,fsUserCourseVideoQVO);
+        if(courseVideo != null && courseVideo.getRedPacketMoney() != null){
+            fsUserCourseVideoQVO.setRedPacketMoney(courseVideo.getRedPacketMoney().toString());
+        }
 
 
         if (StringUtils.isNotEmpty(courseVideo.getQuestionBankId())){
         if (StringUtils.isNotEmpty(courseVideo.getQuestionBankId())){
             List<FsCourseQuestionBank> fsCourseQuestionBanks = courseQuestionBankMapper.selectFsCourseQuestionBankByIdVO(courseVideo.getQuestionBankId().split(","));
             List<FsCourseQuestionBank> fsCourseQuestionBanks = courseQuestionBankMapper.selectFsCourseQuestionBankByIdVO(courseVideo.getQuestionBankId().split(","));
             fsUserCourseVideoQVO.setQuestionBankList(fsCourseQuestionBanks);
             fsUserCourseVideoQVO.setQuestionBankList(fsCourseQuestionBanks);
         }
         }
+
+        //返回课程关联的拍商品
+        if(courseVideo.getIsProduct() != null && courseVideo.getIsProduct() == 1 && courseVideo.getProductId() != null){
+            FsCourseProduct courseProduct = courseProductMapper.selectFsCourseProductById(courseVideo.getProductId());
+            List<FsCourseProduct> courseProducts = Arrays.asList(courseProduct);
+            fsUserCourseVideoQVO.setCourseProducts(courseProducts);
+        }
         return fsUserCourseVideoQVO;
         return fsUserCourseVideoQVO;
     }
     }
 
 

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

@@ -30,6 +30,8 @@ public class FsCourseWatchLogStatisticsListVO {
     private String type3;
     private String type3;
     @Excel(name = "看课中断")
     @Excel(name = "看课中断")
     private String type4;
     private String type4;
+    @Excel(name = "上线数")
+    private Long onLineNum;
     @Excel(name = "企业微信员工名称")
     @Excel(name = "企业微信员工名称")
     private String qwUserName;
     private String qwUserName;
 
 

+ 77 - 0
fs-service/src/main/java/com/fs/course/vo/FsFirstDiagnosisListUVO.java

@@ -0,0 +1,77 @@
+package com.fs.course.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class FsFirstDiagnosisListUVO {
+    /** 主键 */
+    private Long id;
+    /** 患者姓名 */
+    @Excel(name = "患者姓名")
+    private String patientName;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private String age;
+
+    /** 0-未知 1-男性 2-女性 */
+    @Excel(name = "0-未知 1-男性 2-女性")
+    private Long gender;
+
+    /** 电话 */
+    @Excel(name = "电话")
+    private String phone;
+
+    /** 身体状况 */
+    @Excel(name = "身体状况")
+    private String physicalCondition;
+
+    /** 日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date dateTime;
+
+    /** 出版诊断 */
+    @Excel(name = "出版诊断")
+    private String firstDiagnosis;
+
+    /** 医生id */
+    @Excel(name = "医生id")
+    private Long doctorId;
+
+    /** 医生名称 */
+    @Excel(name = "医生名称")
+    private String doctorName;
+
+    /** 职称 */
+    @Excel(name = "职称")
+    private String doctorDep;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 医生证号 */
+    @Excel(name = "医生证号")
+    private String doctorCertificate;
+
+    /** 医生是否填写:0-未填写 1-已填写 */
+    private Integer doctorStatus;
+
+    /** 用户是否答复:0-未答复 1-已答复 */
+    private Integer userStatus;
+
+    private Long qwUserId;
+
+    /**
+     * 销售名称
+     */
+    private String qwUserName;
+
+    //医生签名
+    private String signUrl;
+}

+ 113 - 0
fs-service/src/main/java/com/fs/course/vo/FsInquiryPatientInfoListUVO.java

@@ -0,0 +1,113 @@
+package com.fs.course.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class FsInquiryPatientInfoListUVO {
+
+    private Long id;
+
+    private String patientName;
+
+    /** 出生年月 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "出生年月", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date birthday;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private Integer sex;
+
+
+
+    /** 手机号 */
+    @Excel(name = "手机号")
+    private String mobile;
+
+    private String companyUserName;
+
+    /**
+     * 患者id
+     */
+    private Long patientId;
+
+    /**
+     * 销售id
+     */
+    private Long companyUserId;
+    /**
+     * 患者会员id
+     */
+    private Long userId;
+    /**
+     * 问诊订单id
+     */
+    private Long inquiryOrderId;
+    /**
+     * 课程id
+     */
+    private Long courseId;
+
+    /**
+     * 就诊状态 1-初诊 2-复诊
+     */
+    private Integer diagnosisStatus;
+
+    /**
+     * 客户标签
+     */
+    private String tag;
+
+    /**
+     * 课程/档期
+     */
+    private String courseName;
+
+    /**
+     * 患者病情主诉
+     */
+    private String patientCondition;
+
+    /**
+     * 部门负责人
+     */
+    private String deptManager;
+
+    /**
+     * 医生建议及处置
+     */
+    private String doctorAdviceJson;
+
+    /**
+     * 禁忌
+     */
+    private String taboo;
+    /**
+     * 客户需求
+     */
+    private String customerRequire;
+
+    /**
+     * 职业医生
+     */
+    private String professionalDoctor;
+
+    /**
+     * 助理医生
+     */
+    private String assistantDoctor;
+
+    /**
+     * 预约时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date subTime;
+
+    private Long subDoctorId;
+
+    private String subDoctorName;
+}

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

@@ -479,8 +479,8 @@ public class DfOrderServiceImpl implements IErpOrderService
             orderPayMethod = 1;
             orderPayMethod = 1;
         } else { // 如果是线上付款
         } else { // 如果是线上付款
             orderPayMethod = 2;
             orderPayMethod = 2;
-            // 货到付款金额 = 物流代收金额-优惠金额
-            vo.setCollectingMoney(fsStoreOrder.getPayDelivery().subtract(couponPrice).doubleValue());
+            // 货到付款金额 = 订单剩余支付金额
+            vo.setCollectingMoney(fsStoreOrder.getPayRemain().doubleValue());
             vo.setCollectionCardNumber(config.getMonthlyCard()); // 就是月结账号
             vo.setCollectionCardNumber(config.getMonthlyCard()); // 就是月结账号
         }
         }
         //订单付款方式 1:在线支付 2:货到付款
         //订单付款方式 1:在线支付 2:货到付款

+ 96 - 0
fs-service/src/main/java/com/fs/fastGpt/domain/FastGptChatReplaceText.java

@@ -0,0 +1,96 @@
+package com.fs.fastGpt.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 违规词语对象 fastgpt_chat_replace_words
+ *
+ * @author fs
+ * @date 2025-01-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FastGptChatReplaceText extends BaseEntity{
+
+    /** id */
+    private Long id;
+
+    /** 类型 */
+    @Excel(name = "类型")
+    private Integer type;
+
+    /** 原来的文本 */
+    @Excel(name = "原来的文本")
+    private String content;
+
+    /** 变更后的文本 */
+    @Excel(name = "变更后的文本")
+    private String changeCount;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Integer status;
+
+    /** 排序 */
+    @Excel(name = "排序")
+    private Long sort;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+    public void setType(Integer type)
+    {
+        this.type = type;
+    }
+
+    public Integer getType()
+    {
+        return type;
+    }
+    public void setContent(String content)
+    {
+        this.content = content;
+    }
+
+    public String getContent()
+    {
+        return content;
+    }
+    public void setChangeCount(String changeCount)
+    {
+        this.changeCount = changeCount;
+    }
+
+    public String getChangeCount()
+    {
+        return changeCount;
+    }
+    public void setStatus(Integer status)
+    {
+        this.status = status;
+    }
+
+    public Integer getStatus()
+    {
+        return status;
+    }
+    public void setSort(Long sort)
+    {
+        this.sort = sort;
+    }
+
+    public Long getSort()
+    {
+        return sort;
+    }
+
+}

+ 2 - 0
fs-service/src/main/java/com/fs/fastGpt/domain/FastGptRole.java

@@ -63,4 +63,6 @@ public class FastGptRole extends BaseEntity
     private String contactInfo;
     private String contactInfo;
 
 
     private String channelType;
     private String channelType;
+
+    private Integer logistics;
 }
 }

+ 68 - 0
fs-service/src/main/java/com/fs/fastGpt/mapper/FastGptChatReplaceTextMapper.java

@@ -0,0 +1,68 @@
+package com.fs.fastGpt.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.fastGpt.domain.FastGptChatReplaceText;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 易错词语Mapper接口
+ *
+ * @author fs
+ * @date 2025-01-18
+ */
+public interface FastGptChatReplaceTextMapper extends BaseMapper<FastGptChatReplaceText>{
+    /**
+     * 查询易错词语
+     *
+     * @param id 易错词语主键
+     * @return 易错词语
+     */
+    FastGptChatReplaceText selectFastGptChatReplaceTextById(Long id);
+
+    /**
+     * 查询易错词语列表
+     *
+     * @param fastGptChatReplaceText 易错词语
+     * @return 易错词语集合
+     */
+    List<FastGptChatReplaceText> selectFastGptChatReplaceTextList(FastGptChatReplaceText fastGptChatReplaceText);
+
+    /**
+     * 新增易错词语
+     *
+     * @param fastGptChatReplaceText 易错词语
+     * @return 结果
+     */
+    int insertFastGptChatReplaceText(FastGptChatReplaceText fastGptChatReplaceText);
+
+    /**
+     * 修改易错词语
+     *
+     * @param fastGptChatReplaceText 易错词语
+     * @return 结果
+     */
+    int updateFastGptChatReplaceText(FastGptChatReplaceText fastGptChatReplaceText);
+
+    /**
+     * 删除易错词语
+     *
+     * @param id 易错词语主键
+     * @return 结果
+     */
+    int deleteFastGptChatReplaceTextById(Long id);
+
+    /**
+     * 批量删除易错词语
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFastGptChatReplaceTextByIds(Long[] ids);
+
+
+    @Select("select * from fastgpt_chat_replace_words where `status`=1" )
+    List<FastGptChatReplaceText> selectAllFastGptChatReplaceText();
+
+}

+ 10 - 0
fs-service/src/main/java/com/fs/fastGpt/mapper/FastGptRoleMapper.java

@@ -3,7 +3,9 @@ package com.fs.fastGpt.mapper;
 import java.util.List;
 import java.util.List;
 import com.fs.fastGpt.domain.FastGptRole;
 import com.fs.fastGpt.domain.FastGptRole;
 import com.fs.fastGpt.vo.FastGptRoleVO;
 import com.fs.fastGpt.vo.FastGptRoleVO;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
 import com.fs.his.vo.OptionsVO;
 import com.fs.his.vo.OptionsVO;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 import org.apache.ibatis.annotations.Update;
 
 
@@ -88,4 +90,12 @@ public interface FastGptRoleMapper
     List<OptionsVO> selectFastGptRoleType();
     List<OptionsVO> selectFastGptRoleType();
     @Select("select r.role_id, r.role_name,t.contact_info,r.company_id, r.create_time, r.update_time, r.role_type, r.mode_config_json, r.mode, r.kf_id, r.kf_url, r.avatar, r.kf_media_id,r.reminder_words, r.bind_corp_id,r.channel_type from fastgpt_role r LEFT JOIN fastgpt_role_type t on t.id =r.role_type where role_id = #{roleId}")
     @Select("select r.role_id, r.role_name,t.contact_info,r.company_id, r.create_time, r.update_time, r.role_type, r.mode_config_json, r.mode, r.kf_id, r.kf_url, r.avatar, r.kf_media_id,r.reminder_words, r.bind_corp_id,r.channel_type from fastgpt_role r LEFT JOIN fastgpt_role_type t on t.id =r.role_type where role_id = #{roleId}")
     FastGptRole selectFastGptRoleTypeByRoleId(Long roleId);
     FastGptRole selectFastGptRoleTypeByRoleId(Long roleId);
+
+    List<FastGptRole> selectFastGptRoleByRoleIds(@Param("roleIds") List<Long> roleIds);
+
+    List<String> selectFastGptRoleRoleIdsByAppKey(@Param("appKey") String appKey);
+
+    List<FastgptEventLogTotalVo> selectFastGptRoleAppKeyList();
+
+
 }
 }

+ 93 - 0
fs-service/src/main/java/com/fs/fastGpt/mapper/FastgptEventLogTotalMapper.java

@@ -0,0 +1,93 @@
+package com.fs.fastGpt.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.fastGpt.domain.FastGptEventTokenLog;
+import com.fs.fastGpt.domain.FastgptEventLogTotal;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * ai事件埋点统计Mapper接口
+ * 
+ * @author fs
+ * @date 2025-06-26
+ */
+public interface FastgptEventLogTotalMapper extends BaseMapper<FastgptEventLogTotal>{
+    /**
+     * 查询ai事件埋点统计
+     * 
+     * @param id ai事件埋点统计主键
+     * @return ai事件埋点统计
+     */
+    FastgptEventLogTotal selectFastgptEventLogTotalById(Long id);
+
+    /**
+     * 查询ai事件埋点统计列表
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return ai事件埋点统计集合
+     */
+    List<FastgptEventLogTotal> selectFastgptEventLogTotalList(FastgptEventLogTotal fastgptEventLogTotal);
+
+    /**
+     * 新增ai事件埋点统计
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return 结果
+     */
+    int insertFastgptEventLogTotal(FastgptEventLogTotal fastgptEventLogTotal);
+
+    /**
+     * 修改ai事件埋点统计
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return 结果
+     */
+    int updateFastgptEventLogTotal(FastgptEventLogTotal fastgptEventLogTotal);
+
+    /**
+     * 删除ai事件埋点统计
+     * 
+     * @param id ai事件埋点统计主键
+     * @return 结果
+     */
+    int deleteFastgptEventLogTotalById(Long id);
+
+    /**
+     * 批量删除ai事件埋点统计
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFastgptEventLogTotalByIds(Long[] ids);
+
+    List<FastgptEventLogTotal> selectFastgptEventLogTotalInfoList(FastgptEventLogTotal logTotal);
+
+    FastgptEventLogTotal selectFastgptEventLogTotalByRoleIdAndType(FastgptEventLogTotal total);
+
+    List<FastgptEventLogTotal> selectFastgptEventLogTotalVoInfoList(FastgptEventLogTotalVo fastgptEventLogTotal);
+
+    List<FastGptEventTokenLog> selectFastgptEventTokenLogTotalList(FastGptEventTokenLog fastGptEventTokenLog);
+
+    FastgptEventLogTotal selectFastgptEventTokenLogTotalByRoleIdAndType(FastGptEventTokenLog tokenLog);
+
+    /**
+     * 批量插入ai事件埋点统计
+     *
+     * @param fastgptEventLogTotalList ai事件埋点统计列表
+     * @return 结果
+     */
+    int insertFastgptEventLogTotalBatch(@Param("list") List<FastgptEventLogTotal> fastgptEventLogTotalList);
+
+    /**
+     * 批量更新ai事件埋点统计
+     *
+     * @param fastgptEventLogTotalList ai事件埋点统计列表
+     * @return 结果
+     */
+    int updateFastgptEventLogTotalBatch(@Param("list") List<FastgptEventLogTotal> fastgptEventLogTotalList);
+
+    List<FastgptEventLogTotalVo> selectFastgptEventLogTotalListByStatTime(@Param("dateTime") String dateTime);
+}

+ 76 - 0
fs-service/src/main/java/com/fs/fastGpt/param/FastgptEventLogTotalParam.java

@@ -0,0 +1,76 @@
+package com.fs.fastGpt.param;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * ai事件埋点统计对象 fastgpt_event_log_total
+ *
+ * @author fs
+ * @date 2025-06-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FastgptEventLogTotalParam extends BaseEntity{
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 角色id */
+    //@Excel(name = "角色id")
+    private Long roleId;
+
+    @Excel(name = "角色名称")
+    private Long roleName;
+
+    /** 数量 */
+    @Excel(name = "数量")
+    private Long count;
+
+    /** 日志类型 */
+    @Excel(name = "日志类型")
+    private Integer type;
+
+    /** 公司id */
+    @Excel(name = "公司id")
+    private Long companyId;
+
+    /** 公司用户id */
+    @Excel(name = "公司用户id")
+    private Long companyUserId;
+
+    /** 企微用户id */
+    @Excel(name = "企微用户id")
+    private Long qwUserId;
+
+    @Excel(name = "日志生成时间")
+    private String statTime;
+
+    /**
+     * 员工列表
+     */
+    private List<String> userIds;
+
+    private String qwUserIds;
+
+    private Date createTime;
+
+    private Integer pageNum;
+    private Integer pageSize;
+
+
+    private String beginTime;
+
+
+    private String endTime;
+
+    private String appKey;
+
+
+
+}

+ 62 - 0
fs-service/src/main/java/com/fs/fastGpt/service/IFastGptChatReplaceTextService.java

@@ -0,0 +1,62 @@
+package com.fs.fastGpt.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.fastGpt.domain.FastGptChatReplaceText;
+
+import java.util.List;
+
+/**
+ * 易错词语Service接口
+ * 
+ * @author fs
+ * @date 2025-01-18
+ */
+public interface IFastGptChatReplaceTextService extends IService<FastGptChatReplaceText>{
+    /**
+     * 查询易错词语
+     * 
+     * @param id 易错词语主键
+     * @return 易错词语
+     */
+    FastGptChatReplaceText selectFastGptChatReplaceTextById(Long id);
+
+    /**
+     * 查询易错词语列表
+     * 
+     * @param fastGptChatReplaceText 易错词语
+     * @return 易错词语集合
+     */
+    List<FastGptChatReplaceText> selectFastGptChatReplaceTextList(FastGptChatReplaceText fastGptChatReplaceText);
+
+    /**
+     * 新增易错词语
+     * 
+     * @param fastGptChatReplaceText 易错词语
+     * @return 结果
+     */
+    int insertFastGptChatReplaceText(FastGptChatReplaceText fastGptChatReplaceText);
+
+    /**
+     * 修改易错词语
+     * 
+     * @param fastGptChatReplaceText 易错词语
+     * @return 结果
+     */
+    int updateFastGptChatReplaceText(FastGptChatReplaceText fastGptChatReplaceText);
+
+    /**
+     * 批量删除易错词语
+     * 
+     * @param ids 需要删除的易错词语主键集合
+     * @return 结果
+     */
+    int deleteFastGptChatReplaceTextByIds(Long[] ids);
+
+    /**
+     * 删除易错词语信息
+     * 
+     * @param id 易错词语主键
+     * @return 结果
+     */
+    int deleteFastGptChatReplaceTextById(Long id);
+}

+ 8 - 0
fs-service/src/main/java/com/fs/fastGpt/service/IFastGptRoleService.java

@@ -4,6 +4,7 @@ import java.util.List;
 
 
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
 import com.fs.fastGpt.domain.FastGptRole;
 import com.fs.fastGpt.domain.FastGptRole;
+import com.fs.fastGpt.vo.FastGptRoleDataVO;
 import com.fs.fastGpt.vo.FastGptRoleVO;
 import com.fs.fastGpt.vo.FastGptRoleVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.his.vo.OptionsVO;
 
 
@@ -73,4 +74,11 @@ public interface IFastGptRoleService
     List<OptionsVO> selectFastGptRoleType();
     List<OptionsVO> selectFastGptRoleType();
 
 
     public FastGptRole selectFastGptRoleTypeByRoleId(Long roleId);
     public FastGptRole selectFastGptRoleTypeByRoleId(Long roleId);
+
+    List<String> selectFastGptRoleRoleIdsByAppKey(String appKey);
+
+    List<FastGptRole> selectFastGptRoleByRoleIds(List<Long> roleIds);
+
+    List<FastGptRoleDataVO> selectFastGptRoleAppKeyList();
+
 }
 }

+ 94 - 0
fs-service/src/main/java/com/fs/fastGpt/service/IFastgptEventLogTotalService.java

@@ -0,0 +1,94 @@
+package com.fs.fastGpt.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.fastGpt.domain.FastGptEventTokenLog;
+import com.fs.fastGpt.domain.FastgptEventLogTotal;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
+
+import java.util.List;
+
+/**
+ * ai事件埋点统计Service接口
+ * 
+ * @author fs
+ * @date 2025-06-26
+ */
+public interface IFastgptEventLogTotalService extends IService<FastgptEventLogTotal>{
+    /**
+     * 查询ai事件埋点统计
+     * 
+     * @param id ai事件埋点统计主键
+     * @return ai事件埋点统计
+     */
+    FastgptEventLogTotal selectFastgptEventLogTotalById(Long id);
+
+    /**
+     * 查询ai事件埋点统计列表
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return ai事件埋点统计集合
+     */
+    List<FastgptEventLogTotal> selectFastgptEventLogTotalList(FastgptEventLogTotal fastgptEventLogTotal);
+
+    /**
+     * 新增ai事件埋点统计
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return 结果
+     */
+    int insertFastgptEventLogTotal(FastgptEventLogTotal fastgptEventLogTotal);
+
+    /**
+     * 修改ai事件埋点统计
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return 结果
+     */
+    int updateFastgptEventLogTotal(FastgptEventLogTotal fastgptEventLogTotal);
+
+    /**
+     * 批量删除ai事件埋点统计
+     * 
+     * @param ids 需要删除的ai事件埋点统计主键集合
+     * @return 结果
+     */
+    int deleteFastgptEventLogTotalByIds(Long[] ids);
+
+    /**
+     * 删除ai事件埋点统计信息
+     * 
+     * @param id ai事件埋点统计主键
+     * @return 结果
+     */
+    int deleteFastgptEventLogTotalById(Long id);
+
+    List<FastgptEventLogTotal> selectFastgptEventLogTotalInfoList(FastgptEventLogTotal logTotal);
+
+    FastgptEventLogTotal selectFastgptEventLogTotalByRoleIdAndType(FastgptEventLogTotal total);
+
+    List<FastgptEventLogTotalVo> selectFastgptEventLogTotalVoInfoList(FastgptEventLogTotalVo fastgptEventLogTotal);
+
+    List<FastGptEventTokenLog> selectFastgptEventTokenLogTotalList(FastGptEventTokenLog fastGptEventTokenLog);
+
+    FastgptEventLogTotal selectFastgptEventTokenLogTotalByRoleIdAndType(FastGptEventTokenLog tokenLog);
+
+    FastgptEventLogTotalVo totalFastgptEventLog(List<FastgptEventLogTotalVo> list);
+
+    /**
+     * 批量新增ai事件埋点统计
+     *
+     * @param fastgptEventLogTotalList ai事件埋点统计列表
+     * @return 结果
+     */
+    int insertFastgptEventLogTotalBatch(List<FastgptEventLogTotal> fastgptEventLogTotalList);
+
+    /**
+     * 批量修改ai事件埋点统计
+     *
+     * @param fastgptEventLogTotalList ai事件埋点统计列表
+     * @return 结果
+     */
+    int updateFastgptEventLogTotalBatch(List<FastgptEventLogTotal> fastgptEventLogTotalList);
+
+    List<FastgptEventLogTotalVo> selectFastgptEventLogTotalListByStatTime(String dateTime);
+}

+ 101 - 30
fs-service/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -54,6 +54,7 @@ import com.fs.qwHookApi.vo.QwHookMsgVO;
 import com.fs.qwHookApi.vo.QwHookVO;
 import com.fs.qwHookApi.vo.QwHookVO;
 import com.fs.sop.domain.QwSopLogs;
 import com.fs.sop.domain.QwSopLogs;
 import com.fs.sop.mapper.QwSopLogsMapper;
 import com.fs.sop.mapper.QwSopLogsMapper;
+import com.fs.utils.SensitiveDataUtils;
 import com.fs.voice.utils.StringUtil;
 import com.fs.voice.utils.StringUtil;
 import com.fs.wxwork.dto.*;
 import com.fs.wxwork.dto.*;
 import com.fs.wxwork.service.WxWorkService;
 import com.fs.wxwork.service.WxWorkService;
@@ -61,6 +62,7 @@ import com.vdurmont.emoji.EmojiParser;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nullable;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Async;
@@ -156,6 +158,8 @@ public class AiHookServiceImpl implements AiHookService {
     private IFsExpressService expressService;
     private IFsExpressService expressService;
     @Autowired
     @Autowired
     private CompanyConfigMapper companyConfigMapper;
     private CompanyConfigMapper companyConfigMapper;
+    @Autowired
+    private IFastGptChatReplaceTextService fastGptChatReplaceTextService;
 
 
     /** Ai半小时未回复提醒 **/
     /** Ai半小时未回复提醒 **/
     /**
     /**
@@ -363,38 +367,38 @@ public class AiHookServiceImpl implements AiHookService {
         if (qwContent.contains("我已经添加了你")){
         if (qwContent.contains("我已经添加了你")){
             return R.ok();
             return R.ok();
         }
         }
-        System.out.println(qwUserId);
+        log.info("数据:{}", qwUserId);
         QwUser user = qwUserMapper.selectQwUserById(qwUserId);
         QwUser user = qwUserMapper.selectQwUserById(qwUserId);
         //查询接收人
         //查询接收人
         if(user==null){
         if(user==null){
-            System.out.println("查询接收人为空");
+            log.error("查询接收人为空");
             return R.ok();
             return R.ok();
         }
         }
         if(user.getFastGptRoleId()==null){
         if(user.getFastGptRoleId()==null){
-            System.out.println("未绑定角色");
+            log.error("未绑定角色");
             return R.ok();
             return R.ok();
         }
         }
         Long serverId = user.getServerId();
         Long serverId = user.getServerId();
-        System.out.println("服务器id"+serverId);
+        log.info("服务器id"+serverId);
         if (serverId == null) {
         if (serverId == null) {
-            System.out.println("服务id为空");
+            log.error("服务id为空");
             return R.ok();
             return R.ok();
         }
         }
         FastGptRole role=roleService.selectFastGptRoleTypeByRoleId(user.getFastGptRoleId());
         FastGptRole role=roleService.selectFastGptRoleTypeByRoleId(user.getFastGptRoleId());
         //没用ai角色跳过
         //没用ai角色跳过
         if(role==null){
         if(role==null){
-            System.out.println("没用ai角色跳过");
+            log.error("没用ai角色跳过");
             return R.ok();
             return R.ok();
         }
         }
         String modeConfig=role.getModeConfigJson();
         String modeConfig=role.getModeConfigJson();
         //key不为空
         //key不为空
         if(StringUtils.isEmpty(modeConfig)){
         if(StringUtils.isEmpty(modeConfig)){
-            System.out.println("没有aiKey");
+            log.error("没有aiKey");
             return R.ok();
             return R.ok();
         }
         }
         ModeConfig config=JSONUtil.toBean(modeConfig,ModeConfig.class);
         ModeConfig config=JSONUtil.toBean(modeConfig,ModeConfig.class);
         if(StringUtils.isEmpty(config.getAPPKey())){
         if(StringUtils.isEmpty(config.getAPPKey())){
-            System.out.println("没有aiKey");
+            log.error("没有aiKey");
             return R.ok();
             return R.ok();
         }
         }
         WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
         WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
@@ -404,14 +408,14 @@ public class AiHookServiceImpl implements AiHookService {
         List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
         List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
         if (data==null|| data.isEmpty()){
         if (data==null|| data.isEmpty()){
 
 
-            System.out.println("未获取到extId"+wxWorkVid2UserIdDTO);
+            log.error("未获取到extId"+wxWorkVid2UserIdDTO);
             return R.ok();
             return R.ok();
         }
         }
         com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);
         com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);
 
 
         QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(dto.getOpenid(), user.getCorpId(),user.getQwUserId());
         QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(dto.getOpenid(), user.getCorpId(),user.getQwUserId());
         if (qwExternalContacts==null){
         if (qwExternalContacts==null){
-            System.out.println("没有外部联系人");
+            log.error("没有外部联系人" + "user:" + user);
             return R.ok();
             return R.ok();
         }
         }
         if(qwExternalContacts.getType()==2){
         if(qwExternalContacts.getType()==2){
@@ -437,13 +441,21 @@ public class AiHookServiceImpl implements AiHookService {
                     }
                     }
                 }
                 }
             }else {
             }else {
-                System.out.println("不是图片"+type);
+                log.info("不是图片"+type);
             }
             }
 
 
-            String contentEmj = replaceWxEmo(qwContent);
+            //对用户处理的内容做处理
+            String maskedContent = processContent(qwContent);
+            String contentEmj = replaceWxEmo(maskedContent);
             if(!contentEmj.contains("表情包")){
             if(!contentEmj.contains("表情包")){
                 if(!contentEmj.isEmpty()){
                 if(!contentEmj.isEmpty()){
                     addSaveAiMsg(1,1,contentEmj,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
                     addSaveAiMsg(1,1,contentEmj,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
+                    //通过用户发送的对话去查询用户是否为新客,是就删除sop,否就不做处理
+                    cleanNewUserDialogue(user, qwExternalContacts);
+                    //用户是未回复状态
+                    if(qwExternalContacts.getIsReply() == 0){
+                        qwExternalContactMapper.updateQwExternalContactIsRePlyById(qwExternalContacts.getId());
+                    }
                 }else {
                 }else {
                     contentEmj ="用户发送表情:"+qwContent;
                     contentEmj ="用户发送表情:"+qwContent;
                     if (type==16){
                     if (type==16){
@@ -455,7 +467,7 @@ public class AiHookServiceImpl implements AiHookService {
 
 
             //判断是否转人工
             //判断是否转人工
             if (fastGptChatSession.getIsArtificial()==1){
             if (fastGptChatSession.getIsArtificial()==1){
-                System.out.println("转人工了");
+                log.error("转人工了,sessionId:" + fastGptChatSession.getSessionId());
                 return R.ok();
                 return R.ok();
             }
             }
             //获取是用户是否发送消息
             //获取是用户是否发送消息
@@ -472,22 +484,32 @@ public class AiHookServiceImpl implements AiHookService {
                     redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),msg+","+contentEmj,5,TimeUnit.MINUTES);
                     redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),msg+","+contentEmj,5,TimeUnit.MINUTES);
                 }
                 }
                 //本次跳过
                 //本次跳过
-                System.out.println("正在对话");
+                log.info("正在对话");
                 return R.ok();
                 return R.ok();
             }
             }
             //用户首次发送消息
             //用户首次发送消息
             redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),1,5,TimeUnit.MINUTES);
             redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),1,5,TimeUnit.MINUTES);
             redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),contentEmj,5,TimeUnit.MINUTES);
             redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),contentEmj,5,TimeUnit.MINUTES);
-            System.out.println("等待");
+            log.info("等待");
             R r= sendAiMsg(replyI,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts,sender);
             R r= sendAiMsg(replyI,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts,sender);
             EventLogUtils.recordEventLog(sender,1L,1,user);
             EventLogUtils.recordEventLog(sender,1L,1,user);
             EventLogUtils.recordEventLog(sender,1L,2,user);
             EventLogUtils.recordEventLog(sender,1L,2,user);
-            System.out.println(r);
+            log.info("数据:{}", r);
             //完成对话 删除消息记录
             //完成对话 删除消息记录
             redisCache.deleteObject("reply:" + fastGptChatSession.getSessionId());
             redisCache.deleteObject("reply:" + fastGptChatSession.getSessionId());
             redisCache.deleteObject("msg:" + fastGptChatSession.getSessionId());
             redisCache.deleteObject("msg:" + fastGptChatSession.getSessionId());
             if(!r.get("code").equals(200)){
             if(!r.get("code").equals(200)){
-                log.info("ai报错转人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
+                //判断消息是否需要重发的依据
+               /*redisCache.setCacheObject("retry:" + fastGptChatSession.getSessionId(),1,2,TimeUnit.MINUTES);
+                redisCache.setCacheObject("retryMsg:" + fastGptChatSession.getSessionId(),contentEmj,2,TimeUnit.MINUTES);
+                Integer retryCount = redisCache.getCacheObject("retry:" + fastGptChatSession.getSessionId());
+                if(retryCount < 3){
+                    r= retrySendAiMsg(retryCount,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts,sender);
+                }
+                redisCache.deleteObject("retry:" + fastGptChatSession.getSessionId());
+                redisCache.deleteObject("retryMsg:" + fastGptChatSession.getSessionId());*/
+
+                log.error("ai报错转人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
                 notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai报错转人工",qwExternalContacts.getId(),sender);
                 notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai报错转人工",qwExternalContacts.getId(),sender);
                 return R.ok();
                 return R.ok();
             }
             }
@@ -507,13 +529,6 @@ public class AiHookServiceImpl implements AiHookService {
             }
             }
             //存聊天记录
             //存聊天记录
             addSaveAiMsg(2,2,contentKh,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),result.getUsage().prompt_tokens,result.getUsage().completion_tokens,token);
             addSaveAiMsg(2,2,contentKh,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),result.getUsage().prompt_tokens,result.getUsage().completion_tokens,token);
-            Integer replyOne = redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
-            if (replyOne!=null && replyOne == 1){
-                QwUser qwUser = qwUserService.selectQwUserById(fastGptChatSession.getQwUserId());
-                if (ObjectUtils.isNotEmpty(qwUser)&&ObjectUtils.isNotEmpty(qwUser.getIpadStatus())&&qwUser.getIpadStatus() == 1){
-                    addQwAutoTags(qwUser,qwExternalContacts.getUserId(),qwExternalContacts.getExternalUserId());
-                }
-            }
             if (!content.isEmpty()){
             if (!content.isEmpty()){
                 addSaveAiMsg(1,2,content,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
                 addSaveAiMsg(1,2,content,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
                 //从fastgpt_chat_artificial_words表中查询所有转人工文本
                 //从fastgpt_chat_artificial_words表中查询所有转人工文本
@@ -524,6 +539,12 @@ public class AiHookServiceImpl implements AiHookService {
                     notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 触发关键词",qwExternalContacts.getId(),sender);
                     notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 触发关键词",qwExternalContacts.getId(),sender);
                     return R.ok();
                     return R.ok();
                 }
                 }
+                //ai回复文字长度大于500就转人工
+                if(content.length() > 500){
+                    log.error("回复长度异常:"+role.getRoleId()+":"+qwExternalContacts.getName());
+                    notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 回复长度异常",qwExternalContacts.getId(),sender);
+                    return R.ok();
+                }
                 if (result.isLongText()){
                 if (result.isLongText()){
                     //新增用户信息
                     //新增用户信息
                     addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
                     addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
@@ -569,7 +590,7 @@ public class AiHookServiceImpl implements AiHookService {
 
 
 
 
             if (result.isArtificial()){
             if (result.isArtificial()){
-                log.info("ai请求人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
+                log.error("ai请求人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
                 notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai请求人工协助",qwExternalContacts.getId(),sender);
                 notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai请求人工协助",qwExternalContacts.getId(),sender);
             }
             }
         }
         }
@@ -577,6 +598,34 @@ public class AiHookServiceImpl implements AiHookService {
         return R.ok();
         return R.ok();
     }
     }
 
 
+    /**
+     * 通过用户发送的对话去查询用户是否为新客,是就删除sop,否就不做处理
+     * @param user
+     * @param qwExternalContacts
+     */
+    private void cleanNewUserDialogue(QwUser user, QwExternalContact qwExternalContacts) {
+        String redisKey = "qwNewChat:" + user.getQwUserId() + ":" + user.getCorpId() + ":" + qwExternalContacts.getExternalUserId();
+        String key  = (String) redisCache.getCacheObject(redisKey);
+        if(!StringUtil.strIsNullOrEmpty(key)){
+            try {
+                QwSopLogs qwSopLogs = new QwSopLogs();
+                qwSopLogs.setQwUserid(user.getQwUserId());
+                qwSopLogs.setCorpId(user.getCorpId());
+                qwSopLogs.setExternalUserId(qwExternalContacts.getExternalUserId());
+                qwSopLogs.setSendStatus(3L);
+                qwSopLogs.setSendType(4);
+                List<QwSopLogs> qwSopLogsList = qwSopLogsMapper.selectQwSopLogsList(qwSopLogs);
+                if(qwSopLogsList != null && !qwSopLogsList.isEmpty()){
+                    qwSopLogsMapper.batchUpdateQwSopLogsNewUserById(qwSopLogsList);
+                }
+            } catch (Exception e) {
+                log.error("停用新客对话sop失败:" + redisKey + "原因:" + e);
+            }finally {
+                redisCache.deleteObject(redisKey);
+            }
+        }
+    }
+
 
 
 
 
     /**
     /**
@@ -636,7 +685,7 @@ public class AiHookServiceImpl implements AiHookService {
         Random random = new Random();
         Random random = new Random();
         FastGptKeywordSend fastGptKeywordSend = keywordSendList.get(random.nextInt(keywordSendList.size()));
         FastGptKeywordSend fastGptKeywordSend = keywordSendList.get(random.nextInt(keywordSendList.size()));
         if (fastGptKeywordSend == null){
         if (fastGptKeywordSend == null){
-            System.out.println("输出为空格");
+            log.info("输出为空格");
             return;
             return;
         }
         }
         if(fastGptKeywordSend.getKeywordType() == 1L && "物流".equals(fastGptKeywordSend.getKeyword())){
         if(fastGptKeywordSend.getKeywordType() == 1L && "物流".equals(fastGptKeywordSend.getKeyword())){
@@ -662,11 +711,11 @@ public class AiHookServiceImpl implements AiHookService {
                                 fastGptChatSessionMapper.updateFastGptChatSession(fastGptChatSession);
                                 fastGptChatSessionMapper.updateFastGptChatSession(fastGptChatSession);
                                 break;
                                 break;
                             case 2:
                             case 2:
-                                sBuilder.append("您购买的 ").append(fsStoreOrder.getPackageName()).append(" 正在准备发货,请耐心等待;\n");
-                                break;
+                                sBuilder.append("您好,您有一个包裹正在准备发货,请耐心等待;\n")
+                                        .append("\uD83C\uDF39\uD83C\uDF39\uD83C\uDF39");
                             case 3:
                             case 3:
                                 ExpressInfoDTO expressInfo = getExpress(fsStoreOrder.getOrderId());
                                 ExpressInfoDTO expressInfo = getExpress(fsStoreOrder.getOrderId());
-                                sBuilder.append("您购买的 ").append(fsStoreOrder.getPackageName());
+                                sBuilder.append("您购买的有一个包裹 ");
                                 sBuilder.append(" 已经查询到了,正在配送中了。\n");
                                 sBuilder.append(" 已经查询到了,正在配送中了。\n");
                                 if(expressInfo != null && expressInfo.getTraces() != null && !expressInfo.getTraces().isEmpty()){
                                 if(expressInfo != null && expressInfo.getTraces() != null && !expressInfo.getTraces().isEmpty()){
                                     List<TracesDTO> traces = expressInfo.getTraces();
                                     List<TracesDTO> traces = expressInfo.getTraces();
@@ -679,7 +728,7 @@ public class AiHookServiceImpl implements AiHookService {
                             case 5:
                             case 5:
                                 ExpressInfoDTO express = getExpress(fsStoreOrder.getOrderId());
                                 ExpressInfoDTO express = getExpress(fsStoreOrder.getOrderId());
                                 //你好,这边查询到您购买的XXX(购买套餐)在XXX(时间)已经送到了,送货员电话为XXX(送货员信息)
                                 //你好,这边查询到您购买的XXX(购买套餐)在XXX(时间)已经送到了,送货员电话为XXX(送货员信息)
-                                sBuilder.append("这边查询到您购买的 ").append(fsStoreOrder.getPackageName());
+                                sBuilder.append("这边查询到您有一个包裹");
                                 if(express != null && express.getTraces() != null && !express.getTraces().isEmpty()){
                                 if(express != null && express.getTraces() != null && !express.getTraces().isEmpty()){
                                     List<TracesDTO> traces = express.getTraces();
                                     List<TracesDTO> traces = express.getTraces();
                                     TracesDTO tracesDTO = traces.get(traces.size() - 1);
                                     TracesDTO tracesDTO = traces.get(traces.size() - 1);
@@ -813,6 +862,28 @@ public class AiHookServiceImpl implements AiHookService {
         return null;
         return null;
     }
     }
 
 
+    /**
+     * 处理用户的输入问题
+     * @param qwContent
+     * @return
+     */
+    private @Nullable String processContent(String qwContent) {
+        String maskedContent = SensitiveDataUtils.maskMobileNumbers(qwContent);
+        if(maskedContent != null && !maskedContent.isEmpty()){
+            FastGptChatReplaceText fastGptChatReplaceText = new FastGptChatReplaceText();
+            fastGptChatReplaceText.setStatus(1);
+            List<FastGptChatReplaceText> chatReplaceTextList = fastGptChatReplaceTextService.selectFastGptChatReplaceTextList(fastGptChatReplaceText);
+            if(chatReplaceTextList != null && !chatReplaceTextList.isEmpty()){
+                for (FastGptChatReplaceText replaceText : chatReplaceTextList) {
+                    if(maskedContent.contains(replaceText.getContent())){
+                        maskedContent = maskedContent.replace(replaceText.getContent(), replaceText.getChangeCount());
+                    }
+                }
+            }
+        }
+        return maskedContent;
+    }
+
     private void sendAiVoiceMsg(String content, Long sendId , String uuid,Long serverId,QwUser user) {
     private void sendAiVoiceMsg(String content, Long sendId , String uuid,Long serverId,QwUser user) {
         if (content == null || content.trim().isEmpty()){
         if (content == null || content.trim().isEmpty()){
             System.out.println("输出为空格");
             System.out.println("输出为空格");

+ 0 - 2
fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptChatMsgServiceImpl.java

@@ -134,13 +134,11 @@ public class FastGptChatMsgServiceImpl implements IFastGptChatMsgService
     }
     }
 
 
     @Override
     @Override
-    @DataSource(DataSourceType.CLICKHOUSE)
     public void insertFastGptEventLog(FastGptEventLog fastGptEventLog) {
     public void insertFastGptEventLog(FastGptEventLog fastGptEventLog) {
         fastGptChatMsgMapper.insertFastGptEventLog(fastGptEventLog);
         fastGptChatMsgMapper.insertFastGptEventLog(fastGptEventLog);
     }
     }
 
 
     @Override
     @Override
-    @DataSource(DataSourceType.CLICKHOUSE)
     public void insertFastGptEventTokenLog(FastGptEventTokenLog fastGptEventTokenLog) {
     public void insertFastGptEventTokenLog(FastGptEventTokenLog fastGptEventTokenLog) {
         fastGptChatMsgMapper.insertFastGptEventTokenLog(fastGptEventTokenLog);
         fastGptChatMsgMapper.insertFastGptEventTokenLog(fastGptEventTokenLog);
     }
     }

+ 93 - 0
fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptChatReplaceTextServiceImpl.java

@@ -0,0 +1,93 @@
+package com.fs.fastGpt.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.utils.DateUtils;
+import com.fs.fastGpt.domain.FastGptChatReplaceText;
+import com.fs.fastGpt.mapper.FastGptChatReplaceTextMapper;
+import com.fs.fastGpt.service.IFastGptChatReplaceTextService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 易错词语Service业务层处理
+ *
+ * @author fs
+ * @date 2025-01-18
+ */
+@Service
+public class FastGptChatReplaceTextServiceImpl extends ServiceImpl<FastGptChatReplaceTextMapper, FastGptChatReplaceText> implements IFastGptChatReplaceTextService {
+
+    /**
+     * 查询易错词语
+     *
+     * @param id 易错词语主键
+     * @return 易错词语
+     */
+    @Override
+    public FastGptChatReplaceText selectFastGptChatReplaceTextById(Long id)
+    {
+        return baseMapper.selectFastGptChatReplaceTextById(id);
+    }
+
+    /**
+     * 查询易错词语列表
+     *
+     * @param fastGptChatReplaceText 易错词语
+     * @return 易错词语
+     */
+    @Override
+    public List<FastGptChatReplaceText> selectFastGptChatReplaceTextList(FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        return baseMapper.selectFastGptChatReplaceTextList(fastGptChatReplaceText);
+    }
+
+    /**
+     * 新增易错词语
+     *
+     * @param fastGptChatReplaceText 易错词语
+     * @return 结果
+     */
+    @Override
+    public int insertFastGptChatReplaceText(FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        fastGptChatReplaceText.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insertFastGptChatReplaceText(fastGptChatReplaceText);
+    }
+
+    /**
+     * 修改易错词语
+     *
+     * @param fastGptChatReplaceText 易错词语
+     * @return 结果
+     */
+    @Override
+    public int updateFastGptChatReplaceText(FastGptChatReplaceText fastGptChatReplaceText)
+    {
+        return baseMapper.updateFastGptChatReplaceText(fastGptChatReplaceText);
+    }
+
+    /**
+     * 批量删除易错词语
+     *
+     * @param ids 需要删除的易错词语主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFastGptChatReplaceTextByIds(Long[] ids)
+    {
+        return baseMapper.deleteFastGptChatReplaceTextByIds(ids);
+    }
+
+    /**
+     * 删除易错词语信息
+     *
+     * @param id 易错词语主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFastGptChatReplaceTextById(Long id)
+    {
+        return baseMapper.deleteFastGptChatReplaceTextById(id);
+    }
+}

+ 77 - 0
fs-service/src/main/java/com/fs/fastGpt/service/impl/FastGptRoleServiceImpl.java

@@ -3,13 +3,18 @@ package com.fs.fastGpt.service.impl;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DateUtils;
 import com.fs.fastGpt.domain.FastGptRoleTag;
 import com.fs.fastGpt.domain.FastGptRoleTag;
 import com.fs.fastGpt.mapper.FastGptRoleTagMapper;
 import com.fs.fastGpt.mapper.FastGptRoleTagMapper;
+import com.fs.fastGpt.vo.FastGptRoleDataVO;
 import com.fs.fastGpt.vo.FastGptRoleVO;
 import com.fs.fastGpt.vo.FastGptRoleVO;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
 import com.fs.his.vo.OptionsVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -171,5 +176,77 @@ public class FastGptRoleServiceImpl implements IFastGptRoleService
         return fastGptRoleMapper.selectFastGptRoleTypeByRoleId(roleId);
         return fastGptRoleMapper.selectFastGptRoleTypeByRoleId(roleId);
     }
     }
 
 
+    @Override
+    public List<String> selectFastGptRoleRoleIdsByAppKey(String appKey) {
+        return fastGptRoleMapper.selectFastGptRoleRoleIdsByAppKey(appKey);
+    }
+
+    @Override
+    public List<FastGptRole> selectFastGptRoleByRoleIds(List<Long> roleIds) {
+        return fastGptRoleMapper.selectFastGptRoleByRoleIds(roleIds);
+    }
+
+    @Override
+    public List<FastGptRoleDataVO> selectFastGptRoleAppKeyList() {
+        List<FastgptEventLogTotalVo> eventLogTotalVos = fastGptRoleMapper.selectFastGptRoleAppKeyList();
+        Map<String, List<FastgptEventLogTotalVo>> appKeyLitMap = eventLogTotalVos.stream()
+                .filter(m -> {
+                    if (m.getAppKey() != null && !m.getAppKey().isEmpty()) {
+                        try {
+                            String appKey = m.getAppKey();
+                            if (appKey.startsWith("\"") && appKey.endsWith("\"")) {
+                                appKey = appKey.substring(1, appKey.length() - 1)
+                                        .replace("\\", "")
+                                        .replace(" ","");
+                            } else {
+                                appKey = appKey.replace("\\", "");
+                            }
+                            JSONObject jsonObject = JSONObject.parseObject(appKey);
+                            String key = jsonObject.getString("APPKey");
+                            if (key != null && !key.isEmpty() && !"null".equals(key)) {
+                                m.setAppKey(key);
+                            } else {
+                                return false;
+                            }
+                        } catch (Exception e) {
+                            return false;
+                        }
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }).collect(Collectors.groupingBy(FastgptEventLogTotalVo::getAppKey));
+
+        List<FastGptRoleDataVO> roleDataList = new ArrayList<>();
+        for (String appKey : appKeyLitMap.keySet()) {
+            List<FastgptEventLogTotalVo> eventLogTotalVos1 = appKeyLitMap.get(appKey);
+            FastGptRoleDataVO roleDataVO = new FastGptRoleDataVO();
+            List<FastGptRoleDataVO> roleInfoList = new ArrayList<>();
+            roleDataVO.setRoleName(appKey);
+            roleDataVO.setRoleId((long)roleDataList.size() + 1);
+            for (FastgptEventLogTotalVo eventLogTotalVo : eventLogTotalVos1) {
+                String roleName = eventLogTotalVo.getRoleName();
+                Long roleId = eventLogTotalVo.getRoleId();
+                if(roleDataVO.getRoleList() == null){
+                    FastGptRoleDataVO roleInfo = new FastGptRoleDataVO();
+                    roleInfo.setRoleName(roleName);
+                    roleInfo.setRoleId(roleId);
+                    roleInfoList.add(roleInfo);
+                    roleDataVO.setRoleList(roleInfoList);
+                }else{
+                    List<FastGptRoleDataVO> roleInfoList1 = roleDataVO.getRoleList();
+                    FastGptRoleDataVO roleInfo = new FastGptRoleDataVO();
+                    roleInfo.setRoleName(roleName);
+                    roleInfo.setRoleId(roleId);
+                    roleInfoList1.add(roleInfo);
+                    roleDataVO.setRoleList(roleInfoList1);
+                }
+            }
+            roleDataList.add(roleDataVO);
+        }
+
+        return roleDataList;
+    }
+
 
 
 }
 }

+ 290 - 0
fs-service/src/main/java/com/fs/fastGpt/service/impl/FastgptEventLogTotalServiceImpl.java

@@ -0,0 +1,290 @@
+package com.fs.fastGpt.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.annotation.DataSource;
+import com.fs.common.core.domain.entity.SysDictData;
+import com.fs.common.enums.DataSourceType;
+import com.fs.common.utils.DateUtils;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.service.ICompanyService;
+import com.fs.fastGpt.domain.FastGptEventTokenLog;
+import com.fs.fastGpt.domain.FastGptRole;
+import com.fs.fastGpt.domain.FastgptEventLogTotal;
+import com.fs.fastGpt.mapper.FastgptEventLogTotalMapper;
+import com.fs.fastGpt.service.IFastGptRoleService;
+import com.fs.fastGpt.service.IFastgptEventLogTotalService;
+import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.fs.common.utils.DictUtils.getDictCache;
+
+/**
+ * ai事件埋点统计Service业务层处理
+ * 
+ * @author fs
+ * @date 2025-06-26
+ */
+@Service
+public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLogTotalMapper, FastgptEventLogTotal> implements IFastgptEventLogTotalService {
+
+    @Autowired
+    FastgptEventLogTotalMapper fastgptEventLogTotalMapper;
+
+    @Autowired
+    private ICompanyService companyService;
+
+    @Autowired
+    private IFastGptRoleService fastGptRoleService;
+    /**
+     * 查询ai事件埋点统计
+     * 
+     * @param id ai事件埋点统计主键
+     * @return ai事件埋点统计
+     */
+    @Override
+    public FastgptEventLogTotal selectFastgptEventLogTotalById(Long id)
+    {
+        return baseMapper.selectFastgptEventLogTotalById(id);
+    }
+
+    /**
+     * 查询ai事件埋点统计列表
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return ai事件埋点统计
+     */
+    @Override
+    public List<FastgptEventLogTotal> selectFastgptEventLogTotalList(FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return baseMapper.selectFastgptEventLogTotalList(fastgptEventLogTotal);
+    }
+
+    /**
+     * 新增ai事件埋点统计
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return 结果
+     */
+    @Override
+    public int insertFastgptEventLogTotal(FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return baseMapper.insertFastgptEventLogTotal(fastgptEventLogTotal);
+    }
+
+    /**
+     * 修改ai事件埋点统计
+     * 
+     * @param fastgptEventLogTotal ai事件埋点统计
+     * @return 结果
+     */
+    @Override
+    public int updateFastgptEventLogTotal(FastgptEventLogTotal fastgptEventLogTotal)
+    {
+        return baseMapper.updateFastgptEventLogTotal(fastgptEventLogTotal);
+    }
+
+    /**
+     * 批量删除ai事件埋点统计
+     * 
+     * @param ids 需要删除的ai事件埋点统计主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFastgptEventLogTotalByIds(Long[] ids)
+    {
+        return baseMapper.deleteFastgptEventLogTotalByIds(ids);
+    }
+
+    /**
+     * 删除ai事件埋点统计信息
+     * 
+     * @param id ai事件埋点统计主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFastgptEventLogTotalById(Long id)
+    {
+        return baseMapper.deleteFastgptEventLogTotalById(id);
+    }
+
+    @Override
+    public List<FastgptEventLogTotal> selectFastgptEventLogTotalInfoList(FastgptEventLogTotal logTotal) {
+        return fastgptEventLogTotalMapper.selectFastgptEventLogTotalInfoList(logTotal);
+    }
+
+    @Override
+    public FastgptEventLogTotal selectFastgptEventLogTotalByRoleIdAndType(FastgptEventLogTotal total) {
+        return fastgptEventLogTotalMapper.selectFastgptEventLogTotalByRoleIdAndType(total);
+    }
+
+    @Override
+    public FastgptEventLogTotal selectFastgptEventTokenLogTotalByRoleIdAndType(FastGptEventTokenLog tokenLog) {
+        return fastgptEventLogTotalMapper.selectFastgptEventTokenLogTotalByRoleIdAndType(tokenLog);
+    }
+
+    @Override
+    public FastgptEventLogTotalVo totalFastgptEventLog(List<FastgptEventLogTotalVo> list) {
+        FastgptEventLogTotalVo totalVo = new FastgptEventLogTotalVo();
+        totalVo.setRoleName("总计");
+        Map<Integer, Long> totalMap = new HashMap<>();
+        if(list != null && !list.isEmpty()){
+            list.forEach(m -> {
+                m.getTypeCountMap().forEach((k,v) -> {
+                    if(totalMap.containsKey(k)){
+                        totalMap.put(k, totalMap.get(k) + v);
+                    }else{
+                        totalMap.put(k, v);
+                    }
+                });
+            });
+            totalVo.setTypeCountMap(totalMap);
+            return totalVo;
+        }else{
+            return null;
+        }
+    }
+
+    @Override
+    public List<FastgptEventLogTotalVo> selectFastgptEventLogTotalVoInfoList(FastgptEventLogTotalVo fastgptEventLogTotal) {
+        if(fastgptEventLogTotal.getBeginTime() == null || fastgptEventLogTotal.getEndTime() == null){
+            fastgptEventLogTotal.setBeginTime(DateUtil.offsetDay(DateUtil.parse(DateUtils.getDate()), -10).toDateStr());
+            fastgptEventLogTotal.setEndTime(DateUtils.getDate());
+        }
+        String appKey = fastgptEventLogTotal.getAppKey();
+        if(appKey != null){
+            List<String> roleIds = fastGptRoleService.selectFastGptRoleRoleIdsByAppKey(appKey);
+            if(roleIds != null && !roleIds.isEmpty()){
+                fastgptEventLogTotal.setRoleIds(roleIds);
+                fastgptEventLogTotal.setRoleId(null);
+            }else{
+                fastgptEventLogTotal.setRoleId(0L);
+            }
+        }
+
+        if(fastgptEventLogTotal.getUserIds() != null && !fastgptEventLogTotal.getUserIds().isEmpty()){
+            List<String> userIds = fastgptEventLogTotal.getUserIds();
+            String result = String.join(",", userIds);
+            List<CompanyUser> companyUserList = companyService.selectCompanyListByIds(result);
+            String qwUserIds = companyUserList.stream()
+                    .map(CompanyUser::getQwUserId)
+                    .filter(Objects::nonNull) // 过滤掉 null 的 qwUserId
+                    .flatMap(userId -> Arrays.stream(userId.split(","))) // 安全 split
+                    .map(String::trim)
+                    .distinct() // 去重
+                    .collect(Collectors.joining(",")); // 收集为逗号分隔的字符串
+            fastgptEventLogTotal.setQwUserIds(qwUserIds);
+        }
+        List<FastgptEventLogTotal> totalList = fastgptEventLogTotalMapper.selectFastgptEventLogTotalVoInfoList(fastgptEventLogTotal);
+        List<SysDictData> dictCache = getDictCache("sys_fastgpt_event_log_type");
+        if(dictCache == null){
+            return null;
+        }
+        List<FastgptEventLogTotalVo> totalVoList = new ArrayList<>();
+        List<Integer> typeList = new ArrayList<>();
+        dictCache.forEach(n -> typeList.add(Integer.parseInt(n.getDictValue())));
+        if(totalList != null && !totalList.isEmpty()){
+            Map<String, List<FastgptEventLogTotal>> groupedByDateStr = totalList.stream()
+                    .collect(Collectors.groupingBy(FastgptEventLogTotal::getStatTime));
+
+            List<Long> roleIds = totalList.stream().map(FastgptEventLogTotal::getRoleId).collect(Collectors.toList());
+            List<FastGptRole> fastGptRoles = fastGptRoleService.selectFastGptRoleByRoleIds(roleIds);
+
+            for (String date : groupedByDateStr.keySet()) {
+                List<FastgptEventLogTotal> list = groupedByDateStr.get(date);
+                Map<Long, List<FastgptEventLogTotal>> roleIdGrouped = list.stream()
+                        .collect(Collectors.groupingBy(FastgptEventLogTotal::getRoleId));
+                for (Long roleId : roleIdGrouped.keySet()) {
+                    List<FastgptEventLogTotal> logTotalList = roleIdGrouped.get(roleId);
+                    FastgptEventLogTotalVo eventLogTotalVo = new FastgptEventLogTotalVo();
+                    eventLogTotalVo.setRoleId(roleId);
+                    eventLogTotalVo.setStatTime(date);
+                    List<Integer> types = logTotalList.stream().map(FastgptEventLogTotal::getType).collect(Collectors.toList());
+                    typeList.forEach(m -> logTotalList.forEach(n ->{
+                        if(types.contains(m)){
+                            if(eventLogTotalVo.getTypeCountMap() == null){
+                                Map<Integer, Long> map = new HashMap<>();
+                                map.put(n.getType(), n.getCount());
+                                eventLogTotalVo.setTypeCountMap(map);
+                            }else{
+                                Map<Integer, Long> countMap = eventLogTotalVo.getTypeCountMap();
+                                countMap.put(n.getType(), n.getCount());
+                                eventLogTotalVo.setTypeCountMap(countMap);
+                            }
+                        }else{
+                            if(eventLogTotalVo.getTypeCountMap() == null){
+                                Map<Integer, Long> map = new HashMap<>();
+                                map.put(m, 0L);
+                                eventLogTotalVo.setTypeCountMap(map);
+                            }else{
+                                Map<Integer, Long> countMap = eventLogTotalVo.getTypeCountMap();
+                                countMap.put(m, 0L);
+                                eventLogTotalVo.setTypeCountMap(countMap);
+                            }
+                        }
+                    }));
+                    for (FastGptRole fastGptRole : fastGptRoles) {
+                        if(Objects.equals(fastGptRole.getRoleId(), eventLogTotalVo.getRoleId())){
+                            eventLogTotalVo.setRoleName(fastGptRole.getRoleName());
+                        }
+                    }
+
+                    totalVoList.add(eventLogTotalVo);
+                }
+            }
+            totalVoList.sort(Comparator.comparing(FastgptEventLogTotalVo::getStatTime).thenComparing(FastgptEventLogTotalVo::getRoleId).reversed());
+            return totalVoList;
+        }else{
+            return null;
+        }
+    }
+
+    @Override
+    public List<FastGptEventTokenLog> selectFastgptEventTokenLogTotalList(FastGptEventTokenLog fastGptEventTokenLog) {
+        return fastgptEventLogTotalMapper.selectFastgptEventTokenLogTotalList(fastGptEventTokenLog);
+    }
+
+
+
+    public static List<String> generateDateStrings(String startDateStr, int days) {
+        List<String> dateList = new ArrayList<>();
+        for (int i = 0; i < days; i++) {
+            String dateStr = DateUtil.offsetDay(DateUtil.parse(startDateStr), i).toDateStr();
+            dateList.add(dateStr);
+        }
+        return dateList;
+    }
+
+    /**
+     * 批量新增ai事件埋点统计
+     *
+     * @param fastgptEventLogTotalList ai事件埋点统计列表
+     * @return 结果
+     */
+    @Override
+    public int insertFastgptEventLogTotalBatch(List<FastgptEventLogTotal> fastgptEventLogTotalList) {
+        return baseMapper.insertFastgptEventLogTotalBatch(fastgptEventLogTotalList);
+    }
+
+    /**
+     * 批量修改ai事件埋点统计
+     *
+     * @param fastgptEventLogTotalList ai事件埋点统计列表
+     * @return 结果
+     */
+    @Override
+    public int updateFastgptEventLogTotalBatch(List<FastgptEventLogTotal> fastgptEventLogTotalList) {
+        return baseMapper.updateFastgptEventLogTotalBatch(fastgptEventLogTotalList);
+    }
+
+    @Override
+    public List<FastgptEventLogTotalVo> selectFastgptEventLogTotalListByStatTime(String dateTime) {
+        return fastgptEventLogTotalMapper.selectFastgptEventLogTotalListByStatTime(dateTime);
+    }
+
+
+}

+ 19 - 0
fs-service/src/main/java/com/fs/fastGpt/vo/FastGptRoleDataVO.java

@@ -0,0 +1,19 @@
+package com.fs.fastGpt.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class FastGptRoleDataVO implements Serializable {
+    /**
+     * 节点名称
+     */
+    private Long roleId;
+
+    private String roleName;
+
+    private List<FastGptRoleDataVO> roleList;
+
+}

+ 70 - 0
fs-service/src/main/java/com/fs/fastGpt/vo/FastgptEventLogTotalVo.java

@@ -0,0 +1,70 @@
+package com.fs.fastGpt.vo;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ai事件埋点统计对象 fastgpt_event_log_total
+ *
+ * @author fs
+ * @date 2025-06-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FastgptEventLogTotalVo extends BaseEntity{
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 角色id */
+    //@Excel(name = "角色id")
+    private Long roleId;
+
+    //@Excel(name = "角色名称")
+    private String roleName;
+
+    @Excel(name = "日志统计时间")
+    private String statTime;
+
+    /** 公司id */
+    @Excel(name = "公司id")
+    private Long companyId;
+
+    @Excel(name = "公司名称")
+    private String companyName;
+    /** 数量 */
+    @Excel(name = "token数量")
+    private Long count;
+
+    /** 日志类型 */
+    //@Excel(name = "日志类型")
+    private Integer type;
+
+
+
+    /** 公司用户id */
+    //@Excel(name = "公司用户id")
+    private Long companyUserId;
+
+    /** 企微用户id */
+    //@Excel(name = "企微用户id")
+    private Long qwUserId;
+
+
+    private Map<Integer,Long> typeCountMap;
+
+    private String qwUserIds;
+
+    private List<String> userIds;
+
+    private String appKey;
+
+    private List<String> roleIds;
+
+
+}

+ 110 - 8
fs-service/src/main/java/com/fs/fastgptApi/util/AiImgUtil.java

@@ -4,18 +4,18 @@ import com.alibaba.fastjson.JSON;
 import com.fs.fastgptApi.param.DouBaoAiParam;
 import com.fs.fastgptApi.param.DouBaoAiParam;
 import com.fs.fastgptApi.result.AiImgResult;
 import com.fs.fastgptApi.result.AiImgResult;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.domain.QwUser;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
+import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.HttpURLConnection;
+import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
+@Slf4j
 @Service
 @Service
 public class AiImgUtil {
 public class AiImgUtil {
 
 
@@ -98,8 +98,9 @@ public class AiImgUtil {
             textContent.setText(
             textContent.setText(
                     "识别图片内容 \n" +
                     "识别图片内容 \n" +
                             "情况一:图片为表情包的时候或是明确意义图片的时候,单独提取出表情包的含义为图片,并输出:【表情包:XXX】XXX为表情表达的内容,例如这个表情包是很开心的感谢,那么XXX就是谢谢。在【】外不进行其他的解释直接结束 \n" +
                             "情况一:图片为表情包的时候或是明确意义图片的时候,单独提取出表情包的含义为图片,并输出:【表情包:XXX】XXX为表情表达的内容,例如这个表情包是很开心的感谢,那么XXX就是谢谢。在【】外不进行其他的解释直接结束 \n" +
-                            "情况二:图片是舌头的时候,根据他的舌苔进行简单的分析,直接输出 \n" +
-                            "情况三:图片是其他的时候,正常提取图片内容,如果是身体异常部位要进行简单分析,直接输出,如果是卡通图片,需要在结尾输出【这是卡通图片】这几个字");
+                            "情况二:图片是舌头的时候,根据他的舌苔进行简单的分析,直接输出,如果是张开嘴的时候,对舌下进行简单的舌诊分析 \n" +
+                            "情况三:图片是其他的时候,正常提取图片内容,如果是身体异常部位要进行简单分析,直接输出,如果是卡通图片,需要在结尾输出【这是卡通图片】这几个字\n" +
+                            "情况四:图片如果是微信支付界面,如果最下方的一条信息为收款金额,那么输出【用户完课,领取红包】,如果最下方的一条信息为支付成功,那么输出【用户购买产品,支付成功】");
 
 
 
 
             List<DouBaoAiParam.Content> contents = new ArrayList<>();
             List<DouBaoAiParam.Content> contents = new ArrayList<>();
@@ -147,9 +148,110 @@ public class AiImgUtil {
         }
         }
     }
     }
 
 
+    /**
+     * 发送AI图像生成请求
+     * @param requestBody 请求体(JSON字符串)
+     * @return 响应结果(JSON字符串)
+     * @throws IOException 网络请求异常
+     */
+    public String sendAiImgHttpRequest(String requestBody) throws IOException {
+        long startTime = System.currentTimeMillis();
+        log.info("开始发送AI图像请求,URL: " + "https://ark.cn-beijing.volces.com/api/v3/chat/completions" + ",请求体长度: " + requestBody.length());
+
+        HttpURLConnection connection = null;
+        try {
+            // 1. 创建连接
+            URL url = new URL("https://ark.cn-beijing.volces.com/api/v3/chat/completions");
+            connection = (HttpURLConnection) url.openConnection();
+
+            // 2. 配置连接参数
+            configureConnection(connection);
+
+            // 3. 发送请求体
+            sendRequestBody(connection, requestBody);
+
+            // 4. 处理响应
+            int statusCode = connection.getResponseCode();
+            log.info("AI图像请求完成,耗时: " + (System.currentTimeMillis() - startTime) +
+                    "ms,状态码: " + statusCode);
+
+            if (statusCode == HttpURLConnection.HTTP_OK) {
+                return readResponse(connection.getInputStream());
+            } else {
+                String errorResponse = readResponse(connection.getErrorStream());
+                String errorMsg = "请求失败,状态码: " + statusCode + ",响应体: " + errorResponse;
+                log.error(errorMsg);
+                throw new IOException(errorMsg);
+            }
+        } catch (SocketTimeoutException e) {
+            // 区分超时类型(连接超时/读取超时)
+            String timeoutType = e.getMessage().contains("connect") ? "连接" : "读取";
+            String errorMsg = timeoutType + "超时,耗时: " + (System.currentTimeMillis() - startTime) + "ms";
+            log.error(errorMsg);
+            throw new IOException(errorMsg, e);
+        } catch (IOException e) {
+            log.error("请求发生异常,耗时: " + (System.currentTimeMillis() - startTime) + "ms", e);
+            throw e;
+        } finally {
+            // 确保连接关闭
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    /**
+     * 配置HTTP连接参数
+     */
+    private void configureConnection(HttpURLConnection connection) {
+        try {
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Authorization", "Bearer " + "208d3549-8dc9-4ef6-b3fa-5aa358f1ab20");
+            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+            connection.setRequestProperty("Accept", "application/json");
 
 
+            // 基础配置
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            connection.setUseCaches(false);
+            connection.setConnectTimeout(10000);
+            connection.setReadTimeout(30000);
+        } catch (Exception e) {
+            log.error("配置连接参数失败: " + e.getMessage());
+        }
+    }
 
 
-    private  String sendAiImgHttpRequest(String requestBody) throws IOException {
+    /**
+     * 发送请求体
+     */
+    private void sendRequestBody(HttpURLConnection connection, String requestBody) throws IOException {
+        try (OutputStream os = connection.getOutputStream()) {
+            byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
+            os.write(input, 0, input.length);
+            os.flush();
+        }
+    }
+
+    /**
+     * 读取响应流
+     */
+    private String readResponse(InputStream inputStream) throws IOException {
+        if (inputStream == null) {
+            return "";
+        }
+
+        try (BufferedReader br = new BufferedReader(
+                new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+            StringBuilder response = new StringBuilder();
+            String line;
+            while ((line = br.readLine()) != null) {
+                response.append(line);
+            }
+            return response.toString();
+        }
+    }
+
+    /*private  String sendAiImgHttpRequest(String requestBody) throws IOException {
         HttpURLConnection connection = null;
         HttpURLConnection connection = null;
         try {
         try {
             // 配置连接
             // 配置连接
@@ -196,5 +298,5 @@ public class AiImgUtil {
                 connection.disconnect();
                 connection.disconnect();
             }
             }
         }
         }
-    }
+    }*/
 }
 }

+ 2 - 2
fs-service/src/main/java/com/fs/fastgptApi/util/EventLogUtils.java

@@ -79,8 +79,8 @@ public class EventLogUtils {
         fastGptEventLog.setCreateTime(new Date());
         fastGptEventLog.setCreateTime(new Date());
 
 
 
 
-        //EventLogQueue.addEventLog(fastGptEventLog); // 入队
-        //fastGptChatMsgService.insertFastGptEventLog(fastGptEventLog);
+        EventLogQueue.addEventLog(fastGptEventLog); // 入队
+        fastGptChatMsgService.insertFastGptEventLog(fastGptEventLog);
     }
     }
 
 
     /**
     /**

+ 20 - 1
fs-service/src/main/java/com/fs/gtPush/domain/PushReqBean.java

@@ -1,5 +1,6 @@
 package com.fs.gtPush.domain;
 package com.fs.gtPush.domain;
 
 
+import com.google.common.collect.ImmutableMap;
 import lombok.Data;
 import lombok.Data;
 
 
 import javax.security.sasl.SaslServer;
 import javax.security.sasl.SaslServer;
@@ -9,8 +10,26 @@ import java.util.Map;
 @Data
 @Data
 public class PushReqBean implements Serializable {
 public class PushReqBean implements Serializable {
 
 
-    private Object cids;
+    public PushReqBean(Object push_clientid, String title, String content,Map<String, Object> payload,Map<String, Object> options) {
+        this.push_clientid = push_clientid;
+        this.title = title;
+        this.content = content;
+        this.payload = payload;
+        this.options = options;
+        this.force_notification=false;
+        this.category= ImmutableMap.of("harmony","EXPRESS", "huawei","EXPRESS", "vivo","ORDER");
+
+    }
+
+    private Object push_clientid;
     private String title;
     private String title;
     private String content;
     private String content;
+    private boolean force_notification;
+    private Map<String,String> category;
     private Map<String,Object> payload;
     private Map<String,Object> payload;
+    private Map<String,Object> options;
+    private String badge;
+
+    public PushReqBean() {
+    }
 }
 }

+ 93 - 0
fs-service/src/main/java/com/fs/gtPush/service/impl/uniPush2ServiceImpl.java

@@ -2,19 +2,112 @@ package com.fs.gtPush.service.impl;
 
 
 import cn.hutool.http.HttpUtil;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.gtPush.domain.PushReqBean;
 import com.fs.gtPush.domain.PushReqBean;
 import com.fs.gtPush.domain.PushResult;
 import com.fs.gtPush.domain.PushResult;
+import com.fs.gtPush.domain.UniPushLog;
+import com.fs.gtPush.service.UniPushLogService;
 import com.fs.gtPush.service.uniPush2Service;
 import com.fs.gtPush.service.uniPush2Service;
+import com.fs.gtPush.utils.PushUtils;
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
+import java.util.HashMap;
+import java.util.Map;
+
 @Service
 @Service
 public class uniPush2ServiceImpl implements uniPush2Service {
 public class uniPush2ServiceImpl implements uniPush2Service {
     private static final String url = "https://fc-mp-de6e03a9-c1a3-439b-9eec-d0dc3c565e4e.next.bspapp.com/push";
     private static final String url = "https://fc-mp-de6e03a9-c1a3-439b-9eec-d0dc3c565e4e.next.bspapp.com/push";
+
+    @Autowired
+    private IFsUserService userService;
+
+    @Autowired
+    private UniPushLogService logService;
+
     @Override
     @Override
     public PushResult pushMessage(PushReqBean push) {
     public PushResult pushMessage(PushReqBean push) {
         String result = HttpUtil.post(url, push.toString());
         String result = HttpUtil.post(url, push.toString());
         PushResult pushResult = JSONUtil.toBean(result, PushResult.class);
         PushResult pushResult = JSONUtil.toBean(result, PushResult.class);
         return pushResult;
         return pushResult;
     }
     }
+
+    @Override
+    public void pushOne(Long userId, Long businessId, String purl, String title, String content, Float type, Integer desType) {
+        PushReqBean param = getParam(userId, purl,title,content,type,desType,"");
+        PushResult pushResult = null;
+        UniPushLog pushAddLog = new UniPushLog();
+        if (param != null) {
+            pushResult = pushMessage(param); //推送消息
+            pushAddLog.setJpushId(param.getPush_clientid().toString());
+            pushAddLog.setPushMsg(JSON.toJSONString(param));
+            pushAddLog.setType(type);
+            pushAddLog.setDesType(desType);
+            pushAddLog.setUserId(userId);
+            pushAddLog.setBusinessId(businessId);
+            pushAddLog.setCreateTime(DateUtils.getNowDate());
+            UniPushLog uniPushLog = PushUtils.returnMsg(pushResult,pushAddLog);
+            logService.insertUniPushLog(uniPushLog);
+        }
+    }
+
+    @Override
+    public PushReqBean getParam(Long userId,String purl,String title,String content,Float type,Integer desType,String imJsonString){
+        if (userId !=null) {
+            FsUser fsUser = userService.selectFsUserByUserId(userId);
+            if (fsUser !=null){
+                String jpushId = fsUser.getJpushId();
+                if (StringUtils.isNotBlank(jpushId) && !"0".equals(jpushId) && !"string".equals(jpushId)){
+                    HashMap<String, Object> map = new HashMap<>();
+                    HashMap<String, Object> map2 = new HashMap<>();
+                    if (StringUtils.isNotBlank(purl)){
+                        map.put("url",purl);
+                        if (StringUtils.isNotEmpty(imJsonString)){
+                            map.put("data",imJsonString);
+                        }
+                    }
+                    if (content.length()>50 || title.length()>20){
+                        return null;//通知栏标题,长度小于20;通知栏内容,长度小于50
+                    }
+                    Map<String, Object> xmConfig = new HashMap<>();
+                    Map<String, Object> vvConfig = new HashMap<>();
+
+                    if (type!=null){
+                        String channel = "";
+                        if (type.toString().contains("0")){
+                            channel = "113892"; //订单
+                        } else if (type.toString().contains("1")){
+                            channel = "113891";
+                            vvConfig.put("/classification",0);
+                        } else if (type.toString().contains("2")){
+                            channel = "113791"; //系统类
+                            vvConfig.put("/classification",1);
+                        }
+                        if (StringUtils.isNotBlank(channel)){
+                            xmConfig.put("/extra.channel_id", channel);
+                            map2.put("XM", xmConfig);
+                        }
+                        vvConfig.put("/category","IM");
+                        map2.put("VV",vvConfig);
+
+                    }
+                    return new PushReqBean(
+                            jpushId,
+                            title,
+                            content,
+                            map,
+                            map2
+                    );
+                }
+            }
+        }
+        return null;
+    }
+
+
 }
 }

+ 4 - 0
fs-service/src/main/java/com/fs/gtPush/service/uniPush2Service.java

@@ -6,4 +6,8 @@ import com.fs.gtPush.domain.PushResult;
 
 
 public interface uniPush2Service {
 public interface uniPush2Service {
     PushResult pushMessage(PushReqBean push);
     PushResult pushMessage(PushReqBean push);
+
+    void pushOne(Long userId,Long businessId,String purl,String title,String content, Float type, Integer desType);
+
+    PushReqBean getParam(Long userId,String purl,String title,String content,Float type,Integer desType,String imJsonString);
 }
 }

+ 120 - 0
fs-service/src/main/java/com/fs/gtPush/utils/PushUtils.java

@@ -0,0 +1,120 @@
+package com.fs.gtPush.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.fs.gtPush.domain.PushResult;
+import com.fs.gtPush.domain.UniPushLog;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+@Slf4j
+public class PushUtils {
+
+    /**
+     * 推送单个 返回结果解析
+     * @param pushResult
+     * @param addLog
+     */
+    public static UniPushLog returnMsg(PushResult pushResult, UniPushLog addLog) {
+        if(pushResult != null){
+            if ("success".equals(pushResult.getErrMsg())){
+                Map<String, Object> dataMap = JSON.parseObject(JSON.toJSONString(pushResult.getData()), new TypeReference<Map<String, Object>>() {});
+                if (dataMap != null) {
+                    for (Map.Entry<String, Object> outerEntry : dataMap.entrySet()) {
+                        String outerKey = outerEntry.getKey(); // 外层键
+                        Map<String, String> innerMap = (Map<String, String>) outerEntry.getValue(); // 内层 Map
+                        log.info("Outer Key: " + outerKey);
+                        // 遍历内层 Map
+                        for (Map.Entry<String, String> innerEntry : innerMap.entrySet()) {
+                            String innerKey = innerEntry.getKey();
+                            String innerValue = innerEntry.getValue();
+                            log.info("    Inner Key: " + innerKey + ", Inner Value: " + innerValue);
+                            //匹配对应log (因不确定返回值是否按序排列 )
+                            if (addLog.getJpushId().equals(innerKey)) {
+                                addLog.setReturnMsg(innerValue);
+                                if (innerValue.contains("successed")) {
+                                    addLog.setPushRes(1);
+                                } else {
+                                    addLog.setPushRes(0);
+                                }
+                            }
+                        }
+                    }
+                }
+
+            } else {
+                    addLog.setPushRes(0);
+                    addLog.setReturnMsg(pushResult.getErrMsg());
+            }
+        } else {
+            addLog.setPushRes(0);
+        }
+        return addLog;
+    }
+
+    /**
+     * 推送列表 返回结果解析
+     * @param pushResult
+     * @param addLogs
+     */
+    public static ArrayList<UniPushLog> returnArrayMsg(PushResult pushResult, ArrayList<UniPushLog> addLogs) {
+        if(pushResult != null){
+            if ("success".equals(pushResult.getErrMsg())){
+                Map<String, Object> dataMap = JSON.parseObject(JSON.toJSONString(pushResult.getData()), new TypeReference<Map<String, Object>>() {});
+                if (dataMap != null) {
+
+                    for (Map.Entry<String, Object> outerEntry : dataMap.entrySet()) {
+                        String outerKey = outerEntry.getKey(); // 外层键
+                        Map<String, String> innerMap = (Map<String, String>) outerEntry.getValue(); // 内层 Map
+                        log.info("Outer Key: " + outerKey);
+                        // 遍历内层 Map
+                        int i = 0;
+                        for (Map.Entry<String, String> innerEntry : innerMap.entrySet()) {
+                            String innerKey = innerEntry.getKey();
+                            String innerValue = innerEntry.getValue();
+                            log.info("    Inner Key: " + innerKey + ", Inner Value: " + innerValue);
+                            if (addLogs.get(i).getJpushId().equals(innerKey)) {
+                                if (innerValue.contains("successed")){
+                                    addLogs.get(i).setPushRes(1);
+
+                                } else {
+                                    addLogs.get(i).setPushRes(0);
+                                }
+                                addLogs.get(i).setReturnMsg(innerValue);
+                            } else {
+                                //匹配对应log (因不确定返回值是否按序排列 )
+                                for (UniPushLog addLog : addLogs) {
+                                    if (addLog.getJpushId().equals(innerKey)) {
+                                        addLogs.get(i).setReturnMsg(innerValue);
+                                        if (innerValue.contains("successed")) {
+                                            addLog.setPushRes(1);
+                                        } else {
+                                            addLog.setPushRes(0);
+                                        }
+                                        addLogs.get(i).setReturnMsg(innerValue);
+                                        break;
+                                    }
+                                }
+                            }
+                            i++;
+                        }
+                    }
+                }
+
+            } else {
+                addLogs.forEach(log->{
+                    log.setPushRes(0);
+                    log.setReturnMsg(pushResult.getErrMsg());
+                });
+            }
+
+        } else {
+            addLogs.forEach(log->{
+                log.setPushRes(0);
+            });
+        }
+        return addLogs;
+    }
+}

+ 6 - 0
fs-service/src/main/java/com/fs/his/domain/FsFirstDiagnosis.java

@@ -70,5 +70,11 @@ public class FsFirstDiagnosis extends BaseEntity{
     @Excel(name = "医生证号")
     @Excel(name = "医生证号")
     private String doctorCertificate;
     private String doctorCertificate;
 
 
+    /** 医生是否填写:0-未填写 1-已填写 */
+    private Integer doctorStatus;
 
 
+    /** 用户是否答复:0-未答复 1-已答复 */
+    private Integer userStatus;
+
+    private Long qwUserId;
 }
 }

+ 12 - 0
fs-service/src/main/java/com/fs/his/dto/FindUsersByDTO.java

@@ -0,0 +1,12 @@
+package com.fs.his.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class FindUsersByDTO implements Serializable {
+    private Long id;
+    private Long type;
+    private String name;
+}

+ 35 - 0
fs-service/src/main/java/com/fs/his/enums/PushLogDesTypeEnum.java

@@ -0,0 +1,35 @@
+package com.fs.his.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.stream.Stream;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public enum PushLogDesTypeEnum {
+    ORDER_UN_PAY(0,"订单未支付"),
+    ORDER_SUCCESS_PAY(1,"订单支付成功"),
+    ORDER_SEND(2,"订单已发货"),
+    ORDER_DISPATCH(3,"订单派送中"),
+    ORDER_SIGN(4,"订单已签收"),
+    HEALTH_RECEIVE(5,"接诊提醒"),
+    IM_MSG(6,"消息提醒"),
+    STUDY_COURSE(7,"课程学习提醒"),
+    MARKET_PUSH(8,"营销推送提醒");
+
+
+
+
+    private Integer value;
+    private String desc;
+
+    public static PushLogDesTypeEnum toType(int value) {
+        return Stream.of(PushLogDesTypeEnum.values())
+                .filter(p -> p.value == value)
+                .findAny()
+                .orElse(null);
+    }
+}

+ 34 - 0
fs-service/src/main/java/com/fs/his/enums/PushLogTypeEnum.java

@@ -0,0 +1,34 @@
+package com.fs.his.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.stream.Stream;
+
+@Getter
+@NoArgsConstructor
+@AllArgsConstructor
+public enum PushLogTypeEnum {
+    ORDER(0f,"订单通知"),
+    ORDER_STORE(0.1f,"药品订单通知"),
+    ORDER_PACKAGE(0.2f,"套餐包订单通知"),
+    ORDER_INQUIRY(0.3f,"问诊订单通知"),
+    ORDER_INTEGRAL(0.4f,"积分订单通知"),
+    HEALTH(1f,"健康管理类通知"),
+    MARKET(2f,"营销类通知"),
+    COURSE(3f,"课程类通知");
+
+
+
+
+    private Float value;
+    private String desc;
+
+    public static PushLogTypeEnum toType(int value) {
+        return Stream.of(PushLogTypeEnum.values())
+                .filter(p -> p.value == value)
+                .findAny()
+                .orElse(null);
+    }
+}

+ 53 - 0
fs-service/src/main/java/com/fs/his/mapper/FsFirstDiagnosisMapper.java

@@ -2,7 +2,15 @@ package com.fs.his.mapper;
 
 
 import java.util.List;
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.course.param.FsFirstDiagnosisListUParam;
+import com.fs.course.vo.FsFirstDiagnosisListUVO;
 import com.fs.his.domain.FsFirstDiagnosis;
 import com.fs.his.domain.FsFirstDiagnosis;
+import com.fs.his.param.FsDiagnosisListDParam;
+import com.fs.his.param.FsFirstDiagnosisParam;
+import com.fs.his.vo.FsDiagnosisListDVO;
+import com.fs.his.vo.FsFirstDiagnosisVO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 
 
 /**
 /**
  * 初诊单Mapper接口
  * 初诊单Mapper接口
@@ -65,4 +73,49 @@ public interface FsFirstDiagnosisMapper extends BaseMapper<FsFirstDiagnosis>{
      * @return 初诊单数据
      * @return 初诊单数据
      */
      */
     FsFirstDiagnosis getByUserId(Long userId);
     FsFirstDiagnosis getByUserId(Long userId);
+
+    @Select({"<script> " +
+            "SELECT id,doctor_id,patient_name,gender,age,phone,date_time,physical_condition,doctor_status,user_status FROM fs_first_diagnosis " +
+            "WHERE 1 = 1" +
+            "<if test='maps.type == 0' > and  doctor_status = 0 and doctor_id is null</if>" +
+            "<if test='maps.type == 1' > and  doctor_id = #{maps.doctorId}</if>" +
+            "ORDER BY create_time desc" +
+            "</script>"})
+    List<FsDiagnosisListDVO> selectFsDiagnosisListDVO(@Param("maps") FsDiagnosisListDParam param);
+
+    @Select({"<script>" +
+            "SELECT fd.*,u.qw_user_name,d.sign_url FROM fs_first_diagnosis fd " +
+            " LEFT JOIN qw_user u ON u.id = fd.qw_user_id " +
+            " LEFT JOIN fs_doctor d ON d.doctor_id = fd.doctor_id " +
+            " WHERE fd.doctor_status = 1 " +
+            "<if test='param.doctorStatus != null'> AND fd.doctor_status = #{param.doctorStatus} </if>" +
+            "<if test='param.userId != null'> AND fd.user_id = #{param.userId} </if>" +
+            " ORDER BY fd.create_time desc " +
+            "</script>"})
+    List<FsFirstDiagnosisListUVO> selectFsFirstDiagnosisListUVO(@Param("param") FsFirstDiagnosisListUParam param);
+
+    @Select({"<script>" +
+            "SELECT fd.*,u.qw_user_name,d.sign_url FROM fs_first_diagnosis fd " +
+            "LEFT JOIN qw_user u ON u.id = fd.qw_user_id " +
+            " LEFT JOIN fs_doctor d ON d.doctor_id = fd.doctor_id " +
+            "WHERE fd.id = #{id}" +
+            "</script>"})
+    FsFirstDiagnosisListUVO getInfo(Long id);
+
+    @Select({"<script>" +
+            "SELECT fd.*,u.nick_name userName,qu.qw_user_name FROM fs_first_diagnosis fd  " +
+            " LEFT JOIN fs_user u ON u.user_id = fd.user_id " +
+            " LEFT JOIN qw_user qu ON qu.id = fd.qw_user_id " +
+            " WHERE 1 = 1 " +
+            "<if test='param.doctorStatus != null'> AND fd.doctor_status = #{param.doctorStatus} </if>" +
+            "<if test='param.userStatus != null'> AND fd.user_status = #{param.userStatus} </if>" +
+            "<if test='param.doctorCertificate != null'> AND fd.doctor_certificate = #{param.doctorCertificate} </if>" +
+            "<if test='param.phone != null'> AND fd.phone = like concat('%',#{param.phone},'%') </if>" +
+            "<if test='param.patientName != null'> and fd.patient_name like concat('%',#{param.patientName},'%') </if>" +
+            "<if test='param.doctorName != null'> and fd.doctor_name like concat('%',#{param.doctorName},'%') </if>" +
+            "<if test='param.userName != null'> and u.nick_name  like concat('%',#{param.userName},'%') </if>" +
+            "<if test='param.qwUserName != null'> and qu.qw_user_name like concat('%',#{param.qwUserName},'%') </if>" +
+            " ORDER BY fd.create_time desc " +
+            "</script>"})
+    List<FsFirstDiagnosisVO> selectFsFirstDiagnosisVOList(@Param("param") FsFirstDiagnosisParam param);
 }
 }

+ 25 - 0
fs-service/src/main/java/com/fs/his/mapper/FsInquiryPatientInfoMapper.java

@@ -1,9 +1,14 @@
 package com.fs.his.mapper;
 package com.fs.his.mapper;
 
 
+import com.fs.course.param.FsInquiryPatientInfoUParam;
+import com.fs.course.vo.FsInquiryPatientInfoListUVO;
 import com.fs.his.domain.FsInquiryPatientInfo;
 import com.fs.his.domain.FsInquiryPatientInfo;
 import com.fs.his.vo.FsInquiryPatientVO;
 import com.fs.his.vo.FsInquiryPatientVO;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Select;
 
 
+import java.util.List;
+
 public interface FsInquiryPatientInfoMapper {
 public interface FsInquiryPatientInfoMapper {
 
 
     int insertFsInquiryPatientInfo(FsInquiryPatientInfo fsInquiryPatientInfo);
     int insertFsInquiryPatientInfo(FsInquiryPatientInfo fsInquiryPatientInfo);
@@ -13,4 +18,24 @@ public interface FsInquiryPatientInfoMapper {
     FsInquiryPatientInfo selectFsInquiryPatientInfoInquiryOrderId(Long inquiryOrderId);
     FsInquiryPatientInfo selectFsInquiryPatientInfoInquiryOrderId(Long inquiryOrderId);
 
 
     FsInquiryPatientVO selectUserAndCompanyUserByInquiryOrderId(Long inquiryOrderId);
     FsInquiryPatientVO selectUserAndCompanyUserByInquiryOrderId(Long inquiryOrderId);
+
+    @Select({"<script>" +
+            "SELECT pi.*,p.patient_name,p.birthday,p.sex, u.nick_name companyUserName,d.doctor_name FROM fs_inquiry_patient_info pi " +
+            "LEFT JOIN fs_patient p ON p.patient_id  = pi.patient_id " +
+            "LEFT JOIN company_user u ON u.user_id = pi.company_user_id " +
+            " left join fs_doctor d on d.doctor_id = pi.sub_doctor_id  " +
+            " 1=1 " +
+            "<if test='param.userId != null'> AND pi.user_id = #{param.userId} </if> " +
+            "ORDER BY pi.create_time desc " +
+            "</script>"})
+    List<FsInquiryPatientInfoListUVO> selectFsInquiryPatientInfoListUVO(@Param("param") FsInquiryPatientInfoUParam param);
+
+    @Select({"<script>" +
+            "SELECT pi.*,p.patient_name,p.birthday,p.sex, u.nick_name companyUserName,d.doctor_name FROM fs_inquiry_patient_info pi " +
+            "LEFT JOIN fs_patient p ON p.patient_id  = pi.patient_id " +
+            "LEFT JOIN company_user u ON u.user_id = pi.company_user_id " +
+            " left join fs_doctor d on d.doctor_id = pi.sub_doctor_id  " +
+            "WHERE pi.id = #{id} " +
+            "</script>"})
+    FsInquiryPatientInfoListUVO getInfo(Long id);
 }
 }

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

@@ -8,6 +8,8 @@ import com.fs.course.domain.FsUserWatchStatistics;
 import com.fs.course.param.CourseAnalysisParam;
 import com.fs.course.param.CourseAnalysisParam;
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUser;
+import com.fs.his.dto.FindUsersByDTO;
+import com.fs.his.param.FindUserByParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.vo.FsUserVO;
 import com.fs.his.vo.FsUserVO;
 import com.fs.his.vo.FsUserExportListVO;
 import com.fs.his.vo.FsUserExportListVO;
@@ -395,4 +397,6 @@ public interface FsUserMapper
     List<FsCompanyUserListQueryVO> selectFsCompanyUserListQuery(@Param("maps")FsUser fsUser);
     List<FsCompanyUserListQueryVO> selectFsCompanyUserListQuery(@Param("maps")FsUser fsUser);
 
 
     List<FsUser> selectFsUserListLimit(FsUser fsUser);
     List<FsUser> selectFsUserListLimit(FsUser fsUser);
+
+    List<FindUsersByDTO> findUsersByParam(FindUserByParam param);
 }
 }

+ 12 - 0
fs-service/src/main/java/com/fs/his/param/FindUserByParam.java

@@ -0,0 +1,12 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class FindUserByParam implements Serializable {
+    private Integer pageNum;
+    private Integer pageSize;
+    private String keywords;
+}

+ 17 - 0
fs-service/src/main/java/com/fs/his/param/FsDiagnosisFillDParam.java

@@ -0,0 +1,17 @@
+package com.fs.his.param;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class FsDiagnosisFillDParam {
+    private Long id;
+    private String firstDiagnosis;
+    private String physicalCondition;
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date dateTime;
+    private Long doctorId;
+
+}

+ 13 - 0
fs-service/src/main/java/com/fs/his/param/FsDiagnosisListDParam.java

@@ -0,0 +1,13 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+@Data
+public class FsDiagnosisListDParam extends BaseParam{
+    Long doctorId;
+
+    /**
+     * 0-全部 1-我的
+     */
+    private Integer type;
+}

+ 25 - 0
fs-service/src/main/java/com/fs/his/param/FsFirstDiagnosisParam.java

@@ -0,0 +1,25 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+@Data
+public class FsFirstDiagnosisParam extends BaseParam{
+
+    private String patientName;
+
+    private String phone;
+
+    private String doctorName;
+
+    private String qwUserName;
+
+    private String userName;
+
+    private String doctorCertificate;
+
+    /** 医生是否填写:0-未填写 1-已填写 */
+    private Integer doctorStatus;
+
+    /** 用户是否答复:0-未答复 1-已答复 */
+    private Integer userStatus;
+}

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

@@ -9,4 +9,6 @@ public class FsInquiryOrderDoPayParam implements Serializable {
     Long orderId;
     Long orderId;
     Long userId;
     Long userId;
 
 
+    private String appId;
+
 }
 }

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

@@ -10,4 +10,6 @@ public class FsPackageOrderDoPayParam implements Serializable {
     @NotNull(message = "订单号不能为空")
     @NotNull(message = "订单号不能为空")
     Long orderId;
     Long orderId;
     Long userId;
     Long userId;
+
+    private String appId;
 }
 }

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

@@ -10,4 +10,6 @@ public class FsStoreOrderDoPayParam implements Serializable {
     @NotNull(message = "订单号不能为空")
     @NotNull(message = "订单号不能为空")
     Long orderId;
     Long orderId;
     Long userId;
     Long userId;
+
+    private String appId;
 }
 }

+ 26 - 5
fs-service/src/main/java/com/fs/his/service/IFsFirstDiagnosisService.java

@@ -2,7 +2,15 @@ package com.fs.his.service;
 
 
 import java.util.List;
 import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
+import com.fs.course.param.FsFirstDiagnosisListUParam;
+import com.fs.course.vo.FsFirstDiagnosisListUVO;
 import com.fs.his.domain.FsFirstDiagnosis;
 import com.fs.his.domain.FsFirstDiagnosis;
+import com.fs.his.param.FsDiagnosisFillDParam;
+import com.fs.his.param.FsDiagnosisListDParam;
+import com.fs.his.param.FsFirstDiagnosisParam;
+import com.fs.his.vo.FsDiagnosisListDVO;
+import com.fs.his.vo.FsFirstDiagnosisVO;
 
 
 /**
 /**
  * 初诊单Service接口
  * 初诊单Service接口
@@ -27,6 +35,8 @@ public interface IFsFirstDiagnosisService extends IService<FsFirstDiagnosis>{
      */
      */
     List<FsFirstDiagnosis> selectFsFirstDiagnosisList(FsFirstDiagnosis fsFirstDiagnosis);
     List<FsFirstDiagnosis> selectFsFirstDiagnosisList(FsFirstDiagnosis fsFirstDiagnosis);
 
 
+    List<FsFirstDiagnosisVO> selectFsFirstDiagnosisVOList(FsFirstDiagnosisParam param);
+
     /**
     /**
      * 新增初诊单
      * 新增初诊单
      * 
      * 
@@ -59,10 +69,21 @@ public interface IFsFirstDiagnosisService extends IService<FsFirstDiagnosis>{
      */
      */
     int deleteFsFirstDiagnosisById(Long id);
     int deleteFsFirstDiagnosisById(Long id);
 
 
-/**
- * 根据用户ID获取首次诊断信息
- * @param userId 用户ID
- * @return 返回对应的首次诊断信息对象,如果不存在则可能返回null
- */
+    /**
+     * 根据用户ID获取首次诊断信息
+     * @param userId 用户ID
+     * @return 返回对应的首次诊断信息对象,如果不存在则可能返回null
+     */
     FsFirstDiagnosis getByUserId(Long userId);
     FsFirstDiagnosis getByUserId(Long userId);
+
+
+    List<FsDiagnosisListDVO> getDiagnosisList(FsDiagnosisListDParam param);
+
+    R fill(FsDiagnosisFillDParam param);
+
+    List<FsFirstDiagnosisListUVO> selectFsFirstDiagnosisListUVO(FsFirstDiagnosisListUParam param);
+
+    FsFirstDiagnosisListUVO getInfo(Long id);
+
+    R confirm(Long id);
 }
 }

+ 8 - 0
fs-service/src/main/java/com/fs/his/service/IFsInquiryPatientInfoService.java

@@ -1,8 +1,13 @@
 package com.fs.his.service;
 package com.fs.his.service;
 
 
+import com.fs.course.param.FsInquiryPatientInfoUParam;
+import com.fs.course.vo.FsInquiryPatientInfoListUVO;
 import com.fs.his.domain.FsInquiryPatientInfo;
 import com.fs.his.domain.FsInquiryPatientInfo;
 import com.fs.his.param.FsInquiryPatientParam;
 import com.fs.his.param.FsInquiryPatientParam;
 import com.fs.his.vo.FsInquiryPatientVO;
 import com.fs.his.vo.FsInquiryPatientVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 
 /**
 /**
  * 问诊患者信息Service接口
  * 问诊患者信息Service接口
@@ -16,4 +21,7 @@ public interface IFsInquiryPatientInfoService {
 
 
     FsInquiryPatientVO selectFsInquiryPatientInfo(Long inquiryOrderId);
     FsInquiryPatientVO selectFsInquiryPatientInfo(Long inquiryOrderId);
 
 
+    List<FsInquiryPatientInfoListUVO> selectFsInquiryPatientInfoListUVO(FsInquiryPatientInfoUParam param);
+
+    FsInquiryPatientInfoListUVO getInfo(Long id);
 }
 }

+ 8 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -12,6 +12,8 @@ import com.fs.course.param.newfs.FsUserCourseBeMemberParam;
 import com.fs.course.vo.newfs.FsCourseAnalysisVO;
 import com.fs.course.vo.newfs.FsCourseAnalysisVO;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUser;
 import com.fs.his.domain.FsUserAddress;
 import com.fs.his.domain.FsUserAddress;
+import com.fs.his.dto.FindUsersByDTO;
+import com.fs.his.param.FindUserByParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.vo.FsUserVO;
 import com.fs.his.vo.FsUserVO;
 import com.fs.his.vo.FsUserExportListVO;
 import com.fs.his.vo.FsUserExportListVO;
@@ -46,6 +48,12 @@ public interface IFsUserService
      */
      */
     public FsUser selectFsUserByUserId(Long userId);
     public FsUser selectFsUserByUserId(Long userId);
 
 
+    /**
+     * 通过参数查找用户
+     * @param param 参数
+     * @return 用户列表
+     */
+    public List<FindUsersByDTO> findUserByParam(FindUserByParam param);
     /**
     /**
      * 查询用户列表
      * 查询用户列表
      *
      *

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

@@ -1,13 +1,28 @@
 package com.fs.his.service.impl;
 package com.fs.his.service.impl;
 
 
+import java.util.Collections;
 import java.util.List;
 import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.course.param.FsFirstDiagnosisListUParam;
+import com.fs.course.vo.FsFirstDiagnosisListUVO;
+import com.fs.his.domain.FsDoctor;
+import com.fs.his.param.FsDiagnosisFillDParam;
+import com.fs.his.param.FsDiagnosisListDParam;
+import com.fs.his.param.FsFirstDiagnosisParam;
+import com.fs.his.service.IFsDoctorService;
+import com.fs.his.vo.FsDiagnosisListDVO;
+import com.fs.his.vo.FsFirstDiagnosisVO;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import com.fs.his.mapper.FsFirstDiagnosisMapper;
 import com.fs.his.mapper.FsFirstDiagnosisMapper;
 import com.fs.his.domain.FsFirstDiagnosis;
 import com.fs.his.domain.FsFirstDiagnosis;
 import com.fs.his.service.IFsFirstDiagnosisService;
 import com.fs.his.service.IFsFirstDiagnosisService;
+import org.springframework.util.CollectionUtils;
 
 
 /**
 /**
  * 初诊单Service业务层处理
  * 初诊单Service业务层处理
@@ -18,6 +33,13 @@ import com.fs.his.service.IFsFirstDiagnosisService;
 @Service
 @Service
 public class FsFirstDiagnosisServiceImpl extends ServiceImpl<FsFirstDiagnosisMapper, FsFirstDiagnosis> implements IFsFirstDiagnosisService {
 public class FsFirstDiagnosisServiceImpl extends ServiceImpl<FsFirstDiagnosisMapper, FsFirstDiagnosis> implements IFsFirstDiagnosisService {
 
 
+
+    @Autowired
+    private FsFirstDiagnosisMapper diagnosisMapper;
+
+    @Autowired
+    private IFsDoctorService doctorService;
+
     /**
     /**
      * 查询初诊单
      * 查询初诊单
      * 
      * 
@@ -42,6 +64,11 @@ public class FsFirstDiagnosisServiceImpl extends ServiceImpl<FsFirstDiagnosisMap
         return baseMapper.selectFsFirstDiagnosisList(fsFirstDiagnosis);
         return baseMapper.selectFsFirstDiagnosisList(fsFirstDiagnosis);
     }
     }
 
 
+    @Override
+    public List<FsFirstDiagnosisVO> selectFsFirstDiagnosisVOList(FsFirstDiagnosisParam param) {
+        return diagnosisMapper.selectFsFirstDiagnosisVOList(param);
+    }
+
     /**
     /**
      * 新增初诊单
      * 新增初诊单
      * 
      * 
@@ -94,6 +121,88 @@ public class FsFirstDiagnosisServiceImpl extends ServiceImpl<FsFirstDiagnosisMap
 
 
     @Override
     @Override
     public FsFirstDiagnosis getByUserId(Long userId) {
     public FsFirstDiagnosis getByUserId(Long userId) {
-        return baseMapper.getByUserId(userId);
+        FsFirstDiagnosis firstDiagnosis = baseMapper.getByUserId(userId);
+        if (firstDiagnosis == null) {
+            firstDiagnosis = new FsFirstDiagnosis();
+        }
+        return firstDiagnosis;
+    }
+
+    @Override
+    public List<FsDiagnosisListDVO> getDiagnosisList(FsDiagnosisListDParam param) {
+        return diagnosisMapper.selectFsDiagnosisListDVO(param);
+    }
+
+    @Override
+    public List<FsFirstDiagnosisListUVO> selectFsFirstDiagnosisListUVO(FsFirstDiagnosisListUParam param) {
+        List<FsFirstDiagnosisListUVO> listUVOS = diagnosisMapper.selectFsFirstDiagnosisListUVO(param);
+        if (!CollectionUtils.isEmpty(listUVOS)) {
+            listUVOS.forEach(listUVO -> {
+                if(listUVO.getDoctorStatus() != 1) {
+                    listUVO.setSignUrl(null);
+                }
+            });
+        }
+        return listUVOS;
+    }
+
+    @Override
+    public FsFirstDiagnosisListUVO getInfo(Long id) {
+        FsFirstDiagnosisListUVO info = diagnosisMapper.getInfo(id);
+        if (info != null && info.getDoctorStatus() != 1) {
+            info.setSignUrl(null);
+        }
+        return info;
+    }
+
+    @Override
+    public R confirm(Long id) {
+        FsFirstDiagnosis diagnosis = diagnosisMapper.selectById(id);
+        if (diagnosis == null) {
+            return R.error("初诊单不存在");
+        }
+        if (diagnosis.getUserStatus() != 0) {
+            return R.error("初诊单已确认");
+        }
+        if (diagnosis.getDoctorStatus() != 1) {
+            return R.error("医生未签字无法确认");
+        }
+        FsFirstDiagnosis map = new FsFirstDiagnosis();
+        map.setId(diagnosis.getId());
+        map.setUserStatus(1);
+        int i = diagnosisMapper.updateFsFirstDiagnosis(diagnosis);
+        if (i > 0) {
+            return R.ok();
+        }
+        return R.error();
+    }
+
+    @Override
+    public R fill(FsDiagnosisFillDParam param) {
+        if (param.getId() == null) {
+            return R.error("初诊单id不能为空");
+        }
+        FsFirstDiagnosis diagnosis = diagnosisMapper.selectById(param.getId());
+        FsFirstDiagnosis map = new FsFirstDiagnosis();
+        if (diagnosis == null) {
+            return R.error("初诊单不存在");
+        }
+        if (diagnosis.getDoctorId() == null){
+            FsDoctor doctor = doctorService.selectFsDoctorByDoctorId(param.getDoctorId());
+            if (doctor == null) {
+                return R.error("医生不存在");
+            }
+            map.setDoctorName(doctor.getDoctorName());
+            map.setDoctorDep(doctor.getPosition());
+            map.setDoctorCertificate(doctor.getCertificateCode());
+            map.setDoctorId(doctor.getDoctorId());
+        }
+        map.setId(diagnosis.getId());
+        map.setDoctorStatus(1);
+        int i = diagnosisMapper.updateFsFirstDiagnosis(diagnosis);
+        if (i > 0) {
+            return R.ok();
+        }
+        return R.error();
     }
     }
 }
 }

+ 17 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryPatientInfoServiceImpl.java

@@ -4,6 +4,8 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.exception.CustomException;
 import com.fs.common.exception.CustomException;
+import com.fs.course.param.FsInquiryPatientInfoUParam;
+import com.fs.course.vo.FsInquiryPatientInfoListUVO;
 import com.fs.his.domain.FsInquiryPatientInfo;
 import com.fs.his.domain.FsInquiryPatientInfo;
 import com.fs.his.mapper.FsInquiryOrderMapper;
 import com.fs.his.mapper.FsInquiryOrderMapper;
 import com.fs.his.mapper.FsInquiryPatientInfoMapper;
 import com.fs.his.mapper.FsInquiryPatientInfoMapper;
@@ -17,6 +19,9 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
+import java.util.Collections;
+import java.util.List;
+
 /**
 /**
  * 问诊患者信息Service业务层处理
  * 问诊患者信息Service业务层处理
  */
  */
@@ -55,7 +60,19 @@ public class FsInquiryPatientInfoServiceImpl implements IFsInquiryPatientInfoSer
         if (fsInquiryPatientInfo != null) {
         if (fsInquiryPatientInfo != null) {
             BeanCopyUtils.copy(fsInquiryPatientInfo, inquiryPatientVO);
             BeanCopyUtils.copy(fsInquiryPatientInfo, inquiryPatientVO);
             inquiryPatientVO.setDoctorAdviceJson(JSONUtil.toBean(fsInquiryPatientInfo.getDoctorAdviceJson(), DoctorAdviceVO.class));
             inquiryPatientVO.setDoctorAdviceJson(JSONUtil.toBean(fsInquiryPatientInfo.getDoctorAdviceJson(), DoctorAdviceVO.class));
+        } else {
+            inquiryPatientVO = new FsInquiryPatientVO();
         }
         }
         return inquiryPatientVO;
         return inquiryPatientVO;
     }
     }
+
+    @Override
+    public List<FsInquiryPatientInfoListUVO> selectFsInquiryPatientInfoListUVO(FsInquiryPatientInfoUParam param) {
+        return fsInquiryPatientInfoMapper.selectFsInquiryPatientInfoListUVO(param);
+    }
+
+    @Override
+    public FsInquiryPatientInfoListUVO getInfo(Long id) {
+        return fsInquiryPatientInfoMapper.getInfo(id);
+    }
 }
 }

+ 52 - 32
fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java

@@ -21,10 +21,7 @@ import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
 import com.fs.common.exception.CustomException;
-import com.fs.common.utils.DateUtils;
-import com.fs.common.utils.SecurityUtils;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.*;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.Company;
@@ -165,6 +162,9 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
     @Autowired
     @Autowired
     private FsUserWxMapper fsUserWxMapper;
     private FsUserWxMapper fsUserWxMapper;
 
 
+    @Autowired
+    private IFsUserWxService userWxService;
+
     /**
     /**
      * 查询套餐订单
      * 查询套餐订单
      *
      *
@@ -315,28 +315,26 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
             param.setUserCouponId(order.getUserCouponId());
             param.setUserCouponId(order.getUserCouponId());
         }
         }
         FsUser user=userService.selectFsUserByUserId(order.getUserId());
         FsUser user=userService.selectFsUserByUserId(order.getUserId());
+        if (Objects.isNull(user)){
+            return R.error("用户不存在");
+        }
+
         if (param.getType()==1) {
         if (param.getType()==1) {
-            if(user!=null&& StringUtils.isNotEmpty(user.getMaOpenId())){
-                param.setCompanyId(order.getCompanyId());
-                param.setCompanyUserId(order.getUserId());
-                param.setStoreId(order.getStoreId());
-                Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),param);
-                return R.ok().put("moneys",moneys);
-            }
-            else{
+            if (StringUtils.isBlank(user.getMaOpenId()) && !CloudHostUtils.isCloudHostName("弘德堂")) {
                 return R.error("用户OPENID不存在");
                 return R.error("用户OPENID不存在");
             }
             }
+
+            param.setCompanyId(order.getCompanyId());
+            param.setCompanyUserId(order.getUserId());
+            param.setStoreId(order.getStoreId());
+            Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),param);
+            return R.ok().put("moneys",moneys);
         }else if (param.getType()==2){
         }else if (param.getType()==2){
-            if(user!=null){
-                param.setCompanyId(order.getCompanyId());
-                param.setCompanyUserId(order.getUserId());
-                param.setStoreId(order.getStoreId());
-                Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),param);
-                return R.ok().put("moneys",moneys);
-            }
-            else{
-                return R.error("用户不存在");
-            }
+            param.setCompanyId(order.getCompanyId());
+            param.setCompanyUserId(order.getUserId());
+            param.setStoreId(order.getStoreId());
+            Map<String,Object> moneys=computeOrderMoney(order.getTotalPrice(),param);
+            return R.ok().put("moneys",moneys);
         }else {
         }else {
             return R.error("无效的类型参数");
             return R.error("无效的类型参数");
         }
         }
@@ -881,20 +879,42 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
             return R.error("非法操作");
             return R.error("非法操作");
         }
         }
 
 
-        FsUser user=userService.selectFsUserByUserId(param.getUserId());
-
+//        FsUser user=userService.selectFsUserByUserId(param.getUserId());
+//
+//        String json = configService.selectConfigByKey("his.pay");
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+//
+//        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
+//        if (StringUtils.isBlank(openId)){
+//            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+//                    .eq(FsUserWx::getFsUserId, param.getUserId())
+//                    .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
+//            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+//            if (Objects.nonNull(fsUserWx)){
+//                openId = fsUserWx.getOpenId();
+//            }
+//        }
+        FsUser user = userService.selectFsUserByUserId(param.getUserId());
+        //在线支付
         String json = configService.selectConfigByKey("his.pay");
         String json = configService.selectConfigByKey("his.pay");
         PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
         PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
-
-        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-        if (StringUtils.isBlank(openId)){
-            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
-                    .eq(FsUserWx::getFsUserId, param.getUserId())
-                    .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
-            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-            if (Objects.nonNull(fsUserWx)){
+        String openId = "";
+        if (StringUtils.isNotEmpty(param.getAppId())) {
+            FsUserWx fsUserWx = userWxService.selectByAppIdAndUserId(param.getAppId(), param.getUserId(), 1);
+            if (fsUserWx != null) {
                 openId = fsUserWx.getOpenId();
                 openId = fsUserWx.getOpenId();
             }
             }
+        } else {
+            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
+            if (StringUtils.isBlank(openId)){
+                Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+                        .eq(FsUserWx::getFsUserId, param.getUserId())
+                        .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
+                FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+                if (Objects.nonNull(fsUserWx)){
+                    openId = fsUserWx.getOpenId();
+                }
+            }
         }
         }
 
 
         if(user!=null&& StringUtils.isNotEmpty(openId)){
         if(user!=null&& StringUtils.isNotEmpty(openId)){

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

@@ -38,9 +38,7 @@ import com.fs.his.config.FsSysConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.*;
 import com.fs.his.domain.*;
 import com.fs.his.dto.*;
 import com.fs.his.dto.*;
-import com.fs.his.enums.FsStoreOrderLogEnum;
-import com.fs.his.enums.FsStoreOrderStatusEnum;
-import com.fs.his.enums.ShipperCodeEnum;
+import com.fs.his.enums.*;
 import com.fs.his.mapper.*;
 import com.fs.his.mapper.*;
 import com.fs.his.param.*;
 import com.fs.his.param.*;
 import com.fs.his.service.*;
 import com.fs.his.service.*;
@@ -82,7 +80,14 @@ import com.github.binarywang.wxpay.service.WxPayService;
 import com.google.gson.Gson;
 import com.google.gson.Gson;
 import lombok.Synchronized;
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import org.json.JSONObject;
 import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.aop.framework.AopContext;
 import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -96,6 +101,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
 
 
+import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.math.RoundingMode;
@@ -120,6 +126,7 @@ import static com.fs.his.utils.PhoneUtil.encryptPhone;
 @Slf4j
 @Slf4j
 @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
 @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
 public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
+    Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
     @Autowired
     private WxPayService wxPayService;
     private WxPayService wxPayService;
     @Autowired
     @Autowired
@@ -270,9 +277,15 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     @Autowired
     @Autowired
     private FsUserWxMapper fsUserWxMapper;
     private FsUserWxMapper fsUserWxMapper;
 
 
+    @Autowired
+    private IFsUserWxService userWxService;
+
     @Value("${express.omsCode}")
     @Value("${express.omsCode}")
     private String expressOmsCode;
     private String expressOmsCode;
 
 
+    @Autowired
+    private com.fs.gtPush.service.uniPush2Service uniPush2Service;
+
     /**
     /**
      * 查询订单
      * 查询订单
      *
      *
@@ -1405,14 +1418,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
     public R payConfirm(String orderCode, String payCode, String tradeNo, String payType, Integer type) {
     public R payConfirm(String orderCode, String payCode, String tradeNo, String payType, Integer type) {
         try {
         try {
-            FsStoreOrderScrm order = null;
+            FsStoreOrder order = null;
             if (type.equals(1)) {
             if (type.equals(1)) {
 
 
-                FsStorePaymentScrm storePayment = fsStorePaymentScrmMapper.selectFsStorePaymentByPaymentCode(payCode);
+                FsStorePayment storePayment = fsStorePaymentMapper.selectFsStorePaymentByPaymentCode(payCode);
                 if (storePayment != null) {
                 if (storePayment != null) {
                     if (storePayment.getStatus().equals(0)) {
                     if (storePayment.getStatus().equals(0)) {
                         log.info(payCode + "待支付");
                         log.info(payCode + "待支付");
-                        FsStorePaymentScrm paymentMap = new FsStorePaymentScrm();
+                        FsStorePayment paymentMap = new FsStorePayment();
                         paymentMap.setPaymentId(storePayment.getPaymentId());
                         paymentMap.setPaymentId(storePayment.getPaymentId());
                         paymentMap.setStatus(1);
                         paymentMap.setStatus(1);
                         paymentMap.setPayTime(new Date());
                         paymentMap.setPayTime(new Date());
@@ -1429,42 +1442,33 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                             paymentMap.setBankSerialNo(orderResult.getBankOrderId());
                             paymentMap.setBankSerialNo(orderResult.getBankOrderId());
                             paymentMap.setBankTransactionId(orderResult.getBankTrxId());
                             paymentMap.setBankTransactionId(orderResult.getBankTrxId());
                         }
                         }
-                        fsStorePaymentScrmMapper.updateFsStorePayment(paymentMap);
+                        fsStorePaymentMapper.updateFsStorePayment(paymentMap);
                         log.info(payCode + "已支付");
                         log.info(payCode + "已支付");
-                        order = fsStoreOrderScrmMapper.selectFsStoreOrderById(Long.parseLong(storePayment.getBusinessOrderId()));
+                        order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(Long.parseLong(storePayment.getBusinessId()));
                     }
                     }
                 } else {
                 } else {
                     log.info(payCode + "支付单号不存在");
                     log.info(payCode + "支付单号不存在");
                     return R.error("支付单号不存在");
                     return R.error("支付单号不存在");
                 }
                 }
             } else if (type.equals(2)) {
             } else if (type.equals(2)) {
-                order = fsStoreOrderScrmMapper.selectFsStoreOrderByOrderCode(orderCode);
+                order = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderCode);
             }
             }
-//            if (order != null && !order.getStatus().equals(FsStoreOrderStatusEnum.STATUS_1.getValue())) {
-//                log.info(payCode + "订单号不为待支付回退");
-//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-//                return R.error();
-//            }
-
-            //orderScrm迁移的表待支付状态码为:0
-            if (order != null && !order.getStatus().equals(0)) {//判断订单状态是否待支付
+            if (order != null && !order.getStatus().equals(FsStoreOrderStatusEnum.STATUS_1.getValue())) {
                 log.info(payCode + "订单号不为待支付回退");
                 log.info(payCode + "订单号不为待支付回退");
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 return R.error();
                 return R.error();
             }
             }
-
-            if (order != null && !order.getPaid().equals(0)) {
+            if (order != null && !order.getIsPay().equals(0)) {
                 log.info(payCode + "订单号支付不为待支付回退");
                 log.info(payCode + "订单号支付不为待支付回退");
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 return R.error();
                 return R.error();
             }
             }
-            fsStoreOrderLogsService.create(order.getId(), FsStoreOrderLogEnum.PAY_ORDER_SUCCESS.getValue(),
+            fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.PAY_ORDER_SUCCESS.getValue(),
                     FsStoreOrderLogEnum.PAY_ORDER_SUCCESS.getDesc());
                     FsStoreOrderLogEnum.PAY_ORDER_SUCCESS.getDesc());
-            FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
-            storeOrder.setId(order.getId());
-            storeOrder.setPaid(1);
-//            storeOrder.setStatus(2);
-            storeOrder.setStatus(1);//代发货
+            FsStoreOrder storeOrder = new FsStoreOrder();
+            storeOrder.setOrderId(order.getOrderId());
+            storeOrder.setIsPay(1);
+            storeOrder.setStatus(2);
             storeOrder.setPrescribePrice(order.getTotalPrice());
             storeOrder.setPrescribePrice(order.getTotalPrice());
             SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
             SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
             Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
             Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
@@ -1477,20 +1481,20 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             } else {
             } else {
                 storeOrder.setFollowDoctorId(iFsDoctorService.selectFollowDoctorDoctorByPackage());
                 storeOrder.setFollowDoctorId(iFsDoctorService.selectFollowDoctorDoctorByPackage());
             }
             }
-            if (order.getCycle() != null && order.getCycle() >= followRate) {
+            if (order.getCycle() >= followRate) {
                 Calendar calendar = Calendar.getInstance();
                 Calendar calendar = Calendar.getInstance();
                 calendar.setTime(new Date());
                 calendar.setTime(new Date());
                 calendar.add(Calendar.DAY_OF_MONTH, followRate);
                 calendar.add(Calendar.DAY_OF_MONTH, followRate);
                 storeOrder.setFollowTime(calendar.getTime());
                 storeOrder.setFollowTime(calendar.getTime());
             }
             }
             storeOrder.setPayTime(new Date());
             storeOrder.setPayTime(new Date());
-            fsStoreOrderScrmMapper.updateFsStoreOrder(storeOrder);
+            fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
             //更新优惠券状态
             //更新优惠券状态
-            if (order.getCouponId() != null && order.getCouponId() > 0) {
-                FsUserCoupon userCoupon = userCouponService.selectFsUserCouponById(order.getCouponId());
+            if (order.getUserCouponId() != null && order.getUserCouponId() > 0) {
+                FsUserCoupon userCoupon = userCouponService.selectFsUserCouponById(order.getUserCouponId());
                 if (userCoupon != null && userCoupon.getStatus().equals(0)) {
                 if (userCoupon != null && userCoupon.getStatus().equals(0)) {
                     userCoupon.setUseTime(new Date());
                     userCoupon.setUseTime(new Date());
-                    userCoupon.setBusinessId(order.getId());
+                    userCoupon.setBusinessId(order.getOrderId());
                     userCoupon.setBusinessType(2);
                     userCoupon.setBusinessType(2);
                     userCoupon.setStatus(1);
                     userCoupon.setStatus(1);
                     userCouponService.updateFsUserCoupon(userCoupon);
                     userCouponService.updateFsUserCoupon(userCoupon);
@@ -1895,7 +1899,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     public ExpressResultDTO updateDeliveryItem(ExpressNotifyDTO notifyDTO) {
     public ExpressResultDTO updateDeliveryItem(ExpressNotifyDTO notifyDTO) {
         String data = URLDecoder.decode(notifyDTO.getRequestData(), Charset.forName("UTF-8"));
         String data = URLDecoder.decode(notifyDTO.getRequestData(), Charset.forName("UTF-8"));
         //ExpressInfoDTO
         //ExpressInfoDTO
-        log.info("快递根踪回调: {}", data);
+        logger.info("快递根踪回调:" + data);
         FsSysConfig sysConfig = configUtil.getSysConfig();
         FsSysConfig sysConfig = configUtil.getSysConfig();
         ExpressDataDTO expressDataDTO = JSONUtil.toBean(data, ExpressDataDTO.class);
         ExpressDataDTO expressDataDTO = JSONUtil.toBean(data, ExpressDataDTO.class);
         if (expressDataDTO != null && expressDataDTO.getData() != null) {
         if (expressDataDTO != null && expressDataDTO.getData() != null) {
@@ -1903,8 +1907,8 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 List<FsStoreOrder> orders = this.selectFsStoreOrderListByDeliveryId(dto.getLogisticCode());
                 List<FsStoreOrder> orders = this.selectFsStoreOrderListByDeliveryId(dto.getLogisticCode());
                 if (orders != null) {
                 if (orders != null) {
                     for (FsStoreOrder order : orders) {
                     for (FsStoreOrder order : orders) {
-                        log.info("订单信息: {}", JSONUtil.toJsonStr(order));
-                        log.info("运单号: {}", dto.getLogisticCode());
+                        logger.info("订单信息:" + JSONUtil.toJsonStr(order));
+                        logger.info("运单号:" + dto.getLogisticCode());
                         if (order != null && (order.getDeliveryStatus() == null || order.getDeliveryStatus() != 3)) {
                         if (order != null && (order.getDeliveryStatus() == null || order.getDeliveryStatus() != 3)) {
                             if (dto.getState() != null && dto.getStateEx() != null) {
                             if (dto.getState() != null && dto.getStateEx() != null) {
                                 FsStoreOrder map = new FsStoreOrder();
                                 FsStoreOrder map = new FsStoreOrder();
@@ -1915,16 +1919,47 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                                 this.updateFsStoreOrder(map);
                                 this.updateFsStoreOrder(map);
                                 //如果是正常签收,更新订单状态
                                 //如果是正常签收,更新订单状态
                                 if (dto.getState().equals("3") && (dto.getStateEx().equals("301") || dto.getStateEx().equals("302") || dto.getStateEx().equals("304") || dto.getStateEx().equals("311"))) {
                                 if (dto.getState().equals("3") && (dto.getStateEx().equals("301") || dto.getStateEx().equals("302") || dto.getStateEx().equals("304") || dto.getStateEx().equals("311"))) {
-                                    SysConfig storeConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
-                                    Map<String, Object> config = (Map<String, Object>) JSON.parse(storeConfig.getConfigValue());
-                                    Object isUpdateOrder = config.get("isUpdateOrder");
-                                    if (isUpdateOrder == null || "1".equals(isUpdateOrder.toString())) {
-                                        this.getGoods(order.getOrderId());
+                                    this.getGoods(order.getOrderId());
+                                    //app订单签收通知
+                                    try {
+                                        uniPush2Service.pushOne(
+                                                order.getUserId(),
+                                                order.getOrderId(),
+                                                null,
+                                                "订单已签收",
+                                                "您的订单:" + order.getOrderCode() + "快递单号为:" + dto.getLogisticCode() + "已签收",
+                                                PushLogTypeEnum.ORDER_STORE.getValue(),
+                                                PushLogDesTypeEnum.ORDER_SIGN.getValue()
+                                        );
+                                    } catch (Exception e) {
+                                        log.error("app订单通知推送失败:{}", e.getMessage());
+                                    }
+                                }
+                                //app派件通知
+                                if (dto.getState().equals("2") && (dto.getStateEx().equals("211"))) {
+                                    //ai向客户发送发货物流信息
+                                    requestExpressInfo(order.getOrderId());
+                                }
+                                //app派件通知
+                                if (dto.getState().equals("2") && (dto.getStateEx().equals("202"))) {
+                                    //app订单签收通知
+                                    try {
+                                        uniPush2Service.pushOne(
+                                                order.getUserId(),
+                                                order.getOrderId(),
+                                                null,
+                                                "订单正在派送",
+                                                "您的订单:" + order.getOrderCode() + "快递单号为:" + dto.getLogisticCode() + "正在派送",
+                                                PushLogTypeEnum.ORDER_STORE.getValue(),
+                                                PushLogDesTypeEnum.ORDER_SIGN.getValue()
+                                        );
+                                    } catch (Exception e) {
+                                        log.error("app订单通知推送失败:{}", e.getMessage());
                                     }
                                     }
                                 }
                                 }
                             }
                             }
                             if (!dto.isSuccess()) {
                             if (!dto.isSuccess()) {
-                                log.info("物流状态异常:{}", dto);
+                                logger.info("物流状态异常:{}" + dto);
                             }
                             }
                             if ((!dto.isSuccess() && dto.getReason() != null && dto.getReason().equals("三天无轨迹")) || (!dto.isSuccess() && dto.getReason() != null && dto.getReason().equals("七天内无轨迹变化"))) {
                             if ((!dto.isSuccess() && dto.getReason() != null && dto.getReason().equals("三天无轨迹")) || (!dto.isSuccess() && dto.getReason() != null && dto.getReason().equals("七天内无轨迹变化"))) {
                                 //订阅物流回调
                                 //订阅物流回调
@@ -1936,7 +1971,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                                     }
                                     }
                                 }
                                 }
                                 expressService.subscribeEspress(order.getOrderCode(), order.getDeliveryCode(), order.getDeliverySn(), lastFourNumber);
                                 expressService.subscribeEspress(order.getOrderCode(), order.getDeliveryCode(), order.getDeliverySn(), lastFourNumber);
-                                log.info("物流重新订阅:{}", order.getDeliverySn());
+                                logger.info("物流重新订阅:{}", order.getDeliverySn());
                             }
                             }
 
 
                         }
                         }
@@ -1954,6 +1989,23 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         return fsStoreOrderMapper.selectFsStoreOrderListByDeliverySn(logisticCode);
         return fsStoreOrderMapper.selectFsStoreOrderListByDeliverySn(logisticCode);
     }
     }
 
 
+    public static R requestExpressInfo(Long orderId){
+        String fileUrl = "http://ipad.cdwjyyh.com/msg/sendExpressInfo/" + orderId;
+
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            HttpGet httpGet = new HttpGet(fileUrl);
+            HttpResponse response = httpClient.execute(httpGet);
+
+            // 检查响应状态码
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+                return R.ok();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
     @Override
     @Override
     @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
     @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
     public R syncExpress(Long id) {
     public R syncExpress(Long id) {
@@ -2598,21 +2650,43 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             return R.error("订单状态不正确");
             return R.error("订单状态不正确");
         }
         }
 
 
+//        FsUser user = userService.selectFsUserByUserId(param.getUserId());
+//
+//        //在线支付
+//        String json = configService.selectConfigByKey("his.pay");
+//        PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
+//
+//        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
+//        if (StringUtils.isBlank(openId)){
+//            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+//                    .eq(FsUserWx::getFsUserId, param.getUserId())
+//                    .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
+//            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+//            if (Objects.nonNull(fsUserWx)){
+//                openId = fsUserWx.getOpenId();
+//            }
+//        }
         FsUser user = userService.selectFsUserByUserId(param.getUserId());
         FsUser user = userService.selectFsUserByUserId(param.getUserId());
-
         //在线支付
         //在线支付
         String json = configService.selectConfigByKey("his.pay");
         String json = configService.selectConfigByKey("his.pay");
         PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
         PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
-
-        String openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-        if (StringUtils.isBlank(openId)){
-            Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
-                    .eq(FsUserWx::getFsUserId, param.getUserId())
-                    .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
-            FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-            if (Objects.nonNull(fsUserWx)){
+        String openId = "";
+        if (StringUtils.isNotEmpty(param.getAppId())) {
+            FsUserWx fsUserWx = userWxService.selectByAppIdAndUserId(param.getAppId(), param.getUserId(), 1);
+            if (fsUserWx != null) {
                 openId = fsUserWx.getOpenId();
                 openId = fsUserWx.getOpenId();
             }
             }
+        } else {
+            openId = Objects.isNull(user) ? "" : user.getMaOpenId();
+            if (StringUtils.isBlank(openId)){
+                Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
+                        .eq(FsUserWx::getFsUserId, param.getUserId())
+                        .eq(FsUserWx::getAppId, payConfigDTO.getAppId());
+                FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
+                if (Objects.nonNull(fsUserWx)){
+                    openId = fsUserWx.getOpenId();
+                }
+            }
         }
         }
 
 
         if (user != null && StringUtils.isNotEmpty(openId)) {
         if (user != null && StringUtils.isNotEmpty(openId)) {

+ 7 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -40,8 +40,10 @@ import com.fs.his.config.IntegralConfig;
 import com.fs.his.domain.*;
 import com.fs.his.domain.*;
 import com.fs.his.domain.FsUserAddress;
 import com.fs.his.domain.FsUserAddress;
 import com.fs.his.domain.FsUserIntegralLogs;
 import com.fs.his.domain.FsUserIntegralLogs;
+import com.fs.his.dto.FindUsersByDTO;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.mapper.*;
 import com.fs.his.mapper.*;
+import com.fs.his.param.FindUserByParam;
 import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.param.FsUserParam;
 import com.fs.his.service.IFsUserIntegralLogsService;
 import com.fs.his.service.IFsUserIntegralLogsService;
@@ -173,6 +175,11 @@ public class FsUserServiceImpl implements IFsUserService
         return fsUserMapper.selectFsUserByUserId(userId);
         return fsUserMapper.selectFsUserByUserId(userId);
     }
     }
 
 
+    @Override
+    public List<FindUsersByDTO> findUserByParam(FindUserByParam param) {
+        return fsUserMapper.findUsersByParam(param);
+    }
+
     /**
     /**
      * 查询用户列表
      * 查询用户列表
      *
      *

+ 33 - 0
fs-service/src/main/java/com/fs/his/vo/FsDiagnosisListDVO.java

@@ -0,0 +1,33 @@
+package com.fs.his.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class FsDiagnosisListDVO {
+
+    private Long id;
+
+    private Long doctorId;
+
+    private String patientName;
+
+    private Integer gender;
+
+    private String phone;
+
+    private String firstDiagnosis;
+
+    private String age;
+
+    private String physicalCondition;
+
+    /** 日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date dateTime;
+
+    private Integer doctorStatus;
+    private Integer userStatus;
+}

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

@@ -32,5 +32,7 @@ public class FsDoctorArticleUVO implements Serializable {
     private Date createTime;
     private Date createTime;
     private String videoUrl;
     private String videoUrl;
 
 
+    private String fileId; //vod文件id
+
 
 
 }
 }

+ 81 - 0
fs-service/src/main/java/com/fs/his/vo/FsFirstDiagnosisVO.java

@@ -0,0 +1,81 @@
+package com.fs.his.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class FsFirstDiagnosisVO {
+    /** $column.columnComment */
+    private Long id;
+
+    /** 患者姓名 */
+    @Excel(name = "患者姓名")
+    private String patientName;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private String age;
+
+    /** 0-未知 1-男性 2-女性 */
+    @Excel(name = "性别",readConverterExp = "0=未知,1=男,2=女")
+    private Long gender;
+
+    /** 电话 */
+    @Excel(name = "电话")
+    private String phone;
+
+    /** 身体状况 */
+    @Excel(name = "身体状况")
+    private String physicalCondition;
+
+    /** 日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date dateTime;
+
+    /** 出版诊断 */
+    @Excel(name = "出版诊断")
+    private String firstDiagnosis;
+
+    /** 医生id */
+    @Excel(name = "医生id")
+    private Long doctorId;
+
+    /** 医生名称 */
+    @Excel(name = "医生名称")
+    private String doctorName;
+
+    /** 职称 */
+    @Excel(name = "职称")
+    private String doctorDep;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 医生证号 */
+    @Excel(name = "医生证号")
+    private String doctorCertificate;
+
+    /** 医生是否填写:0-未填写 1-已填写 */
+    @Excel(name = "")
+    private Integer doctorStatus;
+
+    /** 用户是否答复:0-未答复 1-已答复 */
+    private Integer userStatus;
+
+    /**
+     * 销售id
+     */
+    private Long qwUserId;
+
+    /**
+     * 销售名称
+     */
+    private String qwUserName;
+
+    private String userName;
+}

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -756,7 +756,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService
             if (flag==0) {
             if (flag==0) {
                 return R.error("订单创建失败");
                 return R.error("订单创建失败");
             }
             }
-            if (!isPay){
+            if (!isPay && storeOrder.getCompanyId()!=null){
                 // 添加订单审核
                 // 添加订单审核
                 addOrderAudit(storeOrder);
                 addOrderAudit(storeOrder);
             }
             }

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

@@ -182,8 +182,10 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
                 String[] split = item.getCompanyIds().split(",");
                 String[] split = item.getCompanyIds().split(",");
 
 
                 for (String companyId : split) {
                 for (String companyId : split) {
-                    String companyName = companyCacheService.selectCompanyNameById(Long.valueOf(companyId));
-                    companyNameList.add(companyName);
+                    if(StringUtils.isNotBlank(companyId)) {
+                        String companyName = companyCacheService.selectCompanyNameById(Long.valueOf(companyId));
+                        companyNameList.add(companyName);
+                    }
                 }
                 }
                 item.setCompanyName(String.join(",",companyNameList));
                 item.setCompanyName(String.join(",",companyNameList));
             }
             }

+ 3 - 0
fs-service/src/main/java/com/fs/qw/domain/QwExternalContact.java

@@ -145,4 +145,7 @@ public class QwExternalContact extends BaseEntity
     // 是否已购0 否 1程序内下单 2程序外下单
     // 是否已购0 否 1程序内下单 2程序外下单
     private Integer payOrder;
     private Integer payOrder;
 
 
+    //用户是否回复  0未回复  1已回复
+    private Integer isReply;
+
 }
 }

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

@@ -433,4 +433,8 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     int insertQwUserDelLossLog(@Param("param") QwUserDelLossLog qwUserDelLossLog);
     int insertQwUserDelLossLog(@Param("param") QwUserDelLossLog qwUserDelLossLog);
 
 
     List<QwUserDelLossLogVO> selectQwUserDelLossList(@Param("param") QwUserDelLossLogParam param);
     List<QwUserDelLossLogVO> selectQwUserDelLossList(@Param("param") QwUserDelLossLogParam param);
+
+    List<QwExternalContact> selectQwExternalContactByFsUserIdAndCompany(@Param("userId")Long userId,@Param("companyUserId") Long companyUserId);
+
+    void updateQwExternalContactIsRePlyById(@Param("id")Long id);
 }
 }

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

@@ -232,7 +232,7 @@ public interface IQwExternalContactService extends IService<QwExternalContact> {
      */
      */
     int updateExternalContactTag(TagGroupUpdateParam param);
     int updateExternalContactTag(TagGroupUpdateParam param);
 
 
-    List<QwExternalContact> selectQwExternalContactByFsUserId(Long userId);
+    List<QwExternalContact> selectQwExternalContactByFsUserIdAndCompany(Long userId,Long companyUserId);
 
 
     /**
     /**
      * 企微用户流失删除统计
      * 企微用户流失删除统计

+ 26 - 5
fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -366,7 +366,27 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
 
 
     @Override
     @Override
     public int updateQwExternalContactByFsUserId(Integer commentStatus, Long fsUserId) {
     public int updateQwExternalContactByFsUserId(Integer commentStatus, Long fsUserId) {
-        return qwExternalContactMapper.updateQwExternalContactByFsUserId(commentStatus, fsUserId);
+        int i = qwExternalContactMapper.updateQwExternalContactByFsUserId(commentStatus, fsUserId);
+        try {
+            if (i > 0){
+                FsUser fsUser = new FsUser();
+                fsUser.setUserId(fsUserId);
+                //commentStatus是外部联系人状态 1是拉黑 0是正常
+                if(commentStatus == 1){
+                    //fsUser的状态 0是拉黑 1是正常
+                    fsUser.setStatus(0);
+                    fsUser.setRemark("投诉拉黑外部联系人用户成功");
+                    logger.error("投诉拉黑外部联系人用户成功:{}",fsUserId);
+                }else{
+                    fsUser.setStatus(1);
+                    logger.error("投诉解除拉黑外部联系人用户成功:{}",fsUserId);
+                }
+                fsUserMapper.updateFsUser(fsUser);
+            }
+        } catch (Exception e) {
+            logger.error("更新用户状态失败:{},{}", e.getMessage(),fsUserId);
+        }
+        return i;
     }
     }
 
 
     @Override
     @Override
@@ -5513,6 +5533,11 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         return 0;
         return 0;
     }
     }
 
 
+    @Override
+    public List<QwExternalContact> selectQwExternalContactByFsUserIdAndCompany(Long userId, Long companyUserId) {
+        return qwExternalContactMapper.selectQwExternalContactByFsUserIdAndCompany(userId,companyUserId);
+    }
+
 
 
     //发送好友欢迎语
     //发送好友欢迎语
        void   SyncAddSendWelcome(QwExternalContact qwExternalContact, QwUser qwUser, String corpId){
        void   SyncAddSendWelcome(QwExternalContact qwExternalContact, QwUser qwUser, String corpId){
@@ -5627,10 +5652,6 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         }
         }
     }
     }
 
 
-    @Override
-    public List<QwExternalContact> selectQwExternalContactByFsUserId(Long userId) {
-        return qwExternalContactMapper.selectQwExternalContactByFsUserId(userId);
-    }
 
 
     @Override
     @Override
     public List<QwUserDelLossLogVO> selectQwUserDelLossLogList(QwUserDelLossLogParam param) {
     public List<QwUserDelLossLogVO> selectQwUserDelLossLogList(QwUserDelLossLogParam param) {

+ 1 - 1
fs-service/src/main/java/com/fs/qw/vo/QwSopTempSetting.java

@@ -81,7 +81,7 @@ public class QwSopTempSetting implements Serializable{
              * 客户的id(用于发送)
              * 客户的id(用于发送)
              */
              */
             private String externalUserId;
             private String externalUserId;
-            //文本-图片-链接-小程序-文件-视频-语音-视频号-app
+            //文本-图片-链接-小程序-文件-视频-语音-视频号-app-自定义小程序
             private String contentType;
             private String contentType;
             //文本
             //文本
             private String value;
             private String value;

+ 3 - 0
fs-service/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java

@@ -329,4 +329,7 @@ public interface QwSopLogsMapper extends BaseMapper<QwSopLogs> {
 
 
     @DataSource(DataSourceType.SOP)
     @DataSource(DataSourceType.SOP)
     void batchUpdateQwSopLogsById(@Param("data") List<QwSopLogs> logs);
     void batchUpdateQwSopLogsById(@Param("data") List<QwSopLogs> logs);
+
+    @DataSource(DataSourceType.SOP)
+    void batchUpdateQwSopLogsNewUserById(@Param("data")List<QwSopLogs> qwSopLogsList);
 }
 }

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

@@ -9,7 +9,9 @@ import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.date.DateUtil;
 import com.fs.common.utils.date.DateUtil;
+import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyMiniapp;
 import com.fs.company.domain.CompanyMiniapp;
+import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.service.ICompanyMiniappService;
 import com.fs.company.service.ICompanyMiniappService;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.config.cloud.CloudHostProper;
@@ -162,6 +164,10 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     @Autowired
     @Autowired
     private CloudHostProper cloudHostProper;
     private CloudHostProper cloudHostProper;
 
 
+    @Autowired
+    private CompanyMapper companyMapper;
+
+
     @Override
     @Override
     public void save(SopUserLogsInfo sopUserLogsInfo) {
     public void save(SopUserLogsInfo sopUserLogsInfo) {
         sopUserLogsInfoMapper.insertSopUserLogsInfo(sopUserLogsInfo);
         sopUserLogsInfoMapper.insertSopUserLogsInfo(sopUserLogsInfo);
@@ -751,10 +757,11 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 return R.error().put("msg","企业微信用户不存在未绑定销售公司-请绑定后重试:"+qwUser.getQwUserName()+"|"+qwUser.getQwUserId());
                 return R.error().put("msg","企业微信用户不存在未绑定销售公司-请绑定后重试:"+qwUser.getQwUserName()+"|"+qwUser.getQwUserId());
             }
             }
 
 
+            Company company = companyMapper.selectCompanyById(qwUser.getCompanyId());
+
             String companyUserId = String.valueOf(qwUser.getCompanyUserId()).trim();
             String companyUserId = String.valueOf(qwUser.getCompanyUserId()).trim();
             String companyId = String.valueOf(qwUser.getCompanyId()).trim();
             String companyId = String.valueOf(qwUser.getCompanyId()).trim();
 
 
-
             //域名
             //域名
 //            String domainName = companyUserMapper.selectDomainByUserId(Long.parseLong(companyUserId));
 //            String domainName = companyUserMapper.selectDomainByUserId(Long.parseLong(companyUserId));
 //            if (StringUtils.isEmpty(domainName)){
 //            if (StringUtils.isEmpty(domainName)){
@@ -892,6 +899,23 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             st.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
                             st.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
                             st.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
                             st.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
 
 
+                            break;
+                        //自定义小程序
+                        case "10":
+                            addWatchLogIfNeeded(item.getSopId(), param.getVideoId(), param.getCourseId(),item.getFsUserId(), qwUserId, companyUserId, companyId, item.getExternalId(),item.getStartTime(),createTime );
+                            if (company!=null){
+
+                                String customMiniAppId = company.getCustomMiniAppId();
+
+                                if (customMiniAppId != null && !customMiniAppId.trim().isEmpty()) {
+                                    st.setMiniprogramAppid(customMiniAppId);
+                                } else {
+                                    st.setMiniprogramAppid("该公司未配置自定义小程序:"+companyId);
+                                }
+                            }else {
+                                st.setMiniprogramAppid("未找到匹配的公司的自定义小程序:"+companyId);
+                            }
+
                             break;
                             break;
                         default:
                         default:
                             break;
                             break;
@@ -997,6 +1021,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         List<CompanyMiniapp> miniList = companyMiniappService.list(new QueryWrapper<CompanyMiniapp>().orderByAsc("sort_num"));
         List<CompanyMiniapp> miniList = companyMiniappService.list(new QueryWrapper<CompanyMiniapp>().orderByAsc("sort_num"));
         Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap = miniList.stream().collect(Collectors.groupingBy(CompanyMiniapp::getCompanyId, Collectors.groupingBy(CompanyMiniapp::getType)));
         Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap = miniList.stream().collect(Collectors.groupingBy(CompanyMiniapp::getCompanyId, Collectors.groupingBy(CompanyMiniapp::getType)));
 
 
+
+        List<Company> companies = companyMapper.selectCompanyAllList();
+
         //排序
         //排序
         int sort = 0;
         int sort = 0;
         //发送类型
         //发送类型
@@ -1038,7 +1065,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
 
                 if (qwUser.getCompanyUserId()!=null && qwUser.getCompanyId()!=null){
                 if (qwUser.getCompanyUserId()!=null && qwUser.getCompanyId()!=null){
                     List<QwSopLogs> sopLogsList = processInsertSopUserLogsInfo(logs, qwUser, param, words, config, qwCompany, finalSort,
                     List<QwSopLogs> sopLogsList = processInsertSopUserLogsInfo(logs, qwUser, param, words, config, qwCompany, finalSort,
-                            finalSendType,miniMap );
+                            finalSendType,miniMap,companies);
 
 
                     //批量插入 发送记录
                     //批量插入 发送记录
                     if (!sopLogsList.isEmpty()) {
                     if (!sopLogsList.isEmpty()) {
@@ -1061,7 +1088,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     private List<QwSopLogs> processInsertSopUserLogsInfo(List<SopUserLogsInfo> sopUserLogsInfos,QwUser qwUser,
     private List<QwSopLogs> processInsertSopUserLogsInfo(List<SopUserLogsInfo> sopUserLogsInfos,QwUser qwUser,
                                                          SendUserLogsInfoMsgParam param,List<FastGptChatReplaceWords> words,
                                                          SendUserLogsInfoMsgParam param,List<FastGptChatReplaceWords> words,
                                                          CourseConfig config,QwCompany qwCompany,int finalSort,int finalSendType,
                                                          CourseConfig config,QwCompany qwCompany,int finalSort,int finalSendType,
-                                                         Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap){
+                                                         Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,List<Company> companies ){
 
 
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
 
@@ -1116,7 +1143,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
             switch (finalSendType){
             switch (finalSendType){
                 case 5:
                 case 5:
                     List<QwSopCourseFinishTempSetting.Setting> list = processSetting(item,qwUser, param, words, config, qwCompany,companyUserId,companyId,
                     List<QwSopCourseFinishTempSetting.Setting> list = processSetting(item,qwUser, param, words, config, qwCompany,companyUserId,companyId,
-                            contact,dataTime, finalDomainName,miniMap);
+                            contact,dataTime, finalDomainName,miniMap,companies);
                     setting.setSetting(list);
                     setting.setSetting(list);
                     break;
                     break;
                 case 9:
                 case 9:
@@ -1179,7 +1206,8 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                                                       SendUserLogsInfoMsgParam param,List<FastGptChatReplaceWords> words,
                                                                       SendUserLogsInfoMsgParam param,List<FastGptChatReplaceWords> words,
                                                                       CourseConfig config,QwCompany qwCompany,String companyUserId, String companyId,
                                                                       CourseConfig config,QwCompany qwCompany,String companyUserId, String companyId,
                                                                       QwExternalContact contact,Date dataTime,String domainName,
                                                                       QwExternalContact contact,Date dataTime,String domainName,
-                                                                      Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap){
+                                                                      Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
+                                                                      List<Company> companies ){
         List<QwSopCourseFinishTempSetting.Setting> list = JSONArray.parseArray(param.getSetting(),QwSopCourseFinishTempSetting.Setting.class);
         List<QwSopCourseFinishTempSetting.Setting> list = JSONArray.parseArray(param.getSetting(),QwSopCourseFinishTempSetting.Setting.class);
 
 
         for (QwSopCourseFinishTempSetting.Setting st : list) {
         for (QwSopCourseFinishTempSetting.Setting st : list) {
@@ -1273,6 +1301,31 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
 
                     st.setMiniprogramPage(linkByMiniApp);
                     st.setMiniprogramPage(linkByMiniApp);
                     break;
                     break;
+
+                //自定义小程序
+                case "10":
+
+                    addWatchLogIfNeeded(item.getSopId(), param.getVideoId(), param.getCourseId(),item.getFsUserId(), String.valueOf(qwUser.getId()), companyUserId, companyId,
+                            item.getExternalId(),item.getStartTime(),dataTime );
+
+                    Optional<Company> matchedCompany = companies.stream()
+                            .filter(company -> String.valueOf(company.getCompanyId()).equals(companyId))
+                            .findFirst();
+                    if (matchedCompany.isPresent()) {
+                        Company company = matchedCompany.get();
+
+                        String customMiniAppId = company.getCustomMiniAppId();
+
+                        if (customMiniAppId != null && !customMiniAppId.trim().isEmpty()) {
+                            st.setMiniprogramAppid(customMiniAppId);
+                        } else {
+                            st.setMiniprogramAppid("该公司未配置自定义小程序:"+companyId);
+                        }
+                    } else {
+                        st.setMiniprogramAppid("未找到匹配的公司的自定义小程序:"+companyId);
+                    }
+
+                    break;
                 default:
                 default:
                     break;
                     break;
 
 

+ 45 - 0
fs-service/src/main/java/com/fs/utils/SensitiveDataUtils.java

@@ -0,0 +1,45 @@
+package com.fs.utils;
+
+import java.util.Random;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SensitiveDataUtils {
+
+    private static final Pattern MOBILE_PATTERN = Pattern.compile("(?<!\\d)1[3-9]\\d{9}(?!\\d)");
+
+
+
+    /**
+     * 对文本中的手机号进行脱敏处理,保留前3位,后8位随机替换
+     */
+    public static String maskMobileNumbers(String content) {
+        try {
+            if (content == null || content.isEmpty()) {
+                return content;
+            }
+
+            Matcher matcher = MOBILE_PATTERN.matcher(content);
+            StringBuffer sb = new StringBuffer();
+
+            while (matcher.find()) {
+                String maskedMobile = getPhoneNumber();
+                matcher.appendReplacement(sb, maskedMobile);
+            }
+
+            matcher.appendTail(sb);
+            return sb.toString();
+        } catch (Exception e) {
+            return content;
+        }
+    }
+
+    private static String getPhoneNumber() {
+        String phoneNumbers = "16623962137,15523238506,17749925835,15923875456,18305948549,13883332012,15057469844,13618796139,18620430041,18584668114,18580017521,15111845257,15275039316,18201444980,18813118010,17726645677,15223482407,17623042467,15123822149,18623062201,17749925836,18323465069,18580176027,13452385636,13608870842,17685274759,15315437944,15998971322,18623079553,15025306414,18623592546,17264203997,18983650852,19823410818,15528133197,18987692003,15364612795,15364612795,17782358851,13452011251,13527318467,13637935049,15123970077,18166348566,13668096347,18883781302,18780014073,18602325964,15086929910,15320525962,15210865639,13671138824,19936630315,18223553039,18290561680,18883557568,18280114551,15086823485,18280406822,15084440304,18680821042,19115284897,15823539658,13718194200,13521390467,18253105683,15866702785,18697568671,13435694935,17347643607,15002351429,13640582745,18716432052,13167916563,15523238507,14678903116,18324157410,18121887854,19923671431,17388206297,18225226941,15111111111,18324199200,15223337413,13633333333,15523524367,15376779826,18580137367,13983381612,15523004683,18996016507,15683164217,19946754704,13983370856,15870485887,18280237531,15223298047,18580466998,15923377066,17353257273,18067773557,18103269005,17775537029,15730089438,13668480682,13183501165,13101083915,19102330681,15084400940";
+        String[] split = phoneNumbers.split(",");
+        return split[new Random().nextInt(split.length)];
+    }
+
+
+
+}

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

@@ -41,6 +41,9 @@ wx:
         secret: 1fac75465a61f9259a0fe19795d9e80d # 公众号的appsecret
         secret: 1fac75465a61f9259a0fe19795d9e80d # 公众号的appsecret
         token: PPKOdAlCoMO # 接口配置里的Token值
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
         aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+  open:
+    appId: wxda2eb168e5b09e56
+    secret: dde09b45d0f6d5b0925965b964b6ab48
 aifabu:  #爱链接
 aifabu:  #爱链接
   appKey: 7b471be905ab17e00f3b858c6710dd117601d008
   appKey: 7b471be905ab17e00f3b858c6710dd117601d008
 watch:
 watch:

+ 4 - 0
fs-service/src/main/resources/application-config-druid-sxjz.yml

@@ -46,6 +46,10 @@ wx:
         secret: 5da9ae6d354c130dc81cde1a6d097480 # 公众号的appsecret
         secret: 5da9ae6d354c130dc81cde1a6d097480 # 公众号的appsecret
         token: PPKOdAlCoMO # 接口配置里的Token值
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVcw03qZy6Wllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
         aesKey: Eswa6VjwtVcw03qZy6Wllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+  # 开放平台app微信授权配置
+  open:
+    app-id: wx9746858bdb5e0643
+    secret: 32dfaa2b2dcad9229935ff089c65d372
 aifabu:  #爱链接
 aifabu:  #爱链接
   appKey: 7b471be905ab17ef358c610dd117601d008
   appKey: 7b471be905ab17ef358c610dd117601d008
 watch:
 watch:

+ 1 - 0
fs-service/src/main/resources/application-druid-jnmy-test.yml

@@ -151,3 +151,4 @@ rocketmq:
 openIM:
 openIM:
     secret: openIM123
     secret: openIM123
     userID: imAdmin
     userID: imAdmin
+isNewWxMerchant: true

+ 5 - 5
fs-service/src/main/resources/application-druid-jzzx.yml

@@ -21,7 +21,7 @@ spring:
                 # 连接池中的最大空闲连接
                 # 连接池中的最大空闲连接
                 max-idle: 8
                 max-idle: 8
                 # 连接池的最大数据库连接数
                 # 连接池的最大数据库连接数
-                max-active: 8
+                max-active: 100
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
                 max-wait: -1ms
                 max-wait: -1ms
     datasource:
     datasource:
@@ -56,7 +56,7 @@ spring:
                 # 最小连接池数量
                 # 最小连接池数量
                 minIdle: 10
                 minIdle: 10
                 # 最大连接池数量
                 # 最大连接池数量
-                maxActive: 20
+                maxActive: 200
                 # 配置获取连接等待超时的时间
                 # 配置获取连接等待超时的时间
                 maxWait: 60000
                 maxWait: 60000
                 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
                 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
@@ -73,7 +73,7 @@ spring:
                 webStatFilter:
                 webStatFilter:
                     enabled: true
                     enabled: true
                 statViewServlet:
                 statViewServlet:
-                    enabled: true
+                    enabled: false
                     # 设置白名单,不填则允许所有访问
                     # 设置白名单,不填则允许所有访问
                     allow:
                     allow:
                     url-pattern: /druid/*
                     url-pattern: /druid/*
@@ -108,7 +108,7 @@ spring:
                 # 最小连接池数量
                 # 最小连接池数量
                 minIdle: 10
                 minIdle: 10
                 # 最大连接池数量
                 # 最大连接池数量
-                maxActive: 20
+                maxActive: 200
                 # 配置获取连接等待超时的时间
                 # 配置获取连接等待超时的时间
                 maxWait: 60000
                 maxWait: 60000
                 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
                 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
@@ -125,7 +125,7 @@ spring:
                 webStatFilter:
                 webStatFilter:
                     enabled: true
                     enabled: true
                 statViewServlet:
                 statViewServlet:
-                    enabled: true
+                    enabled: false
                     # 设置白名单,不填则允许所有访问
                     # 设置白名单,不填则允许所有访问
                     allow:
                     allow:
                     url-pattern: /druid/*
                     url-pattern: /druid/*

+ 5 - 5
fs-service/src/main/resources/application-druid-kyt.yml

@@ -22,7 +22,7 @@ spring:
         # 连接池中的最大空闲连接
         # 连接池中的最大空闲连接
         max-idle: 8
         max-idle: 8
         # 连接池的最大数据库连接数
         # 连接池的最大数据库连接数
-        max-active: 8
+        max-active: 100
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         # #连接池最大阻塞等待时间(使用负值表示没有限制)
         max-wait: -1ms
         max-wait: -1ms
     database: 0
     database: 0
@@ -49,7 +49,7 @@ spring:
         # 最小连接池数量
         # 最小连接池数量
         minIdle: 10
         minIdle: 10
         # 最大连接池数量
         # 最大连接池数量
-        maxActive: 20
+        maxActive: 200
         # 配置获取连接等待超时的时间
         # 配置获取连接等待超时的时间
         maxWait: 60000
         maxWait: 60000
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
@@ -66,7 +66,7 @@ spring:
         webStatFilter:
         webStatFilter:
           enabled: true
           enabled: true
         statViewServlet:
         statViewServlet:
-          enabled: true
+          enabled: false
           # 设置白名单,不填则允许所有访问
           # 设置白名单,不填则允许所有访问
           allow:
           allow:
           url-pattern: /druid/*
           url-pattern: /druid/*
@@ -98,7 +98,7 @@ spring:
         # 最小连接池数量
         # 最小连接池数量
         minIdle: 10
         minIdle: 10
         # 最大连接池数量
         # 最大连接池数量
-        maxActive: 20
+        maxActive: 200
         # 配置获取连接等待超时的时间
         # 配置获取连接等待超时的时间
         maxWait: 60000
         maxWait: 60000
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
         # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
@@ -115,7 +115,7 @@ spring:
         webStatFilter:
         webStatFilter:
           enabled: true
           enabled: true
         statViewServlet:
         statViewServlet:
-          enabled: true
+          enabled: false
           # 设置白名单,不填则允许所有访问
           # 设置白名单,不填则允许所有访问
           allow:
           allow:
           url-pattern: /druid/*
           url-pattern: /druid/*

+ 17 - 1
fs-service/src/main/resources/mapper/company/CompanyMapper.xml

@@ -35,6 +35,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="packageCateIds"    column="package_cate_ids"    />
         <result property="packageCateIds"    column="package_cate_ids"    />
         <result property="courseMaAppId"    column="course_ma_app_id"    />
         <result property="courseMaAppId"    column="course_ma_app_id"    />
         <result property="courseMiniAppId"    column="course_mini_app_id"    />
         <result property="courseMiniAppId"    column="course_mini_app_id"    />
+        <result property="customMiniAppId"    column="custom_mini_app_id"    />
         <result property="repeat"    column="repeat"    />
         <result property="repeat"    column="repeat"    />
         <result property="sendIfType"    column="send_if_type"    />
         <result property="sendIfType"    column="send_if_type"    />
         <result property="ifNum"    column="if_num"    />
         <result property="ifNum"    column="if_num"    />
@@ -63,6 +64,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="courseMaAppId != null "> and course_ma_app_id = #{courseMaAppId}</if>
             <if test="courseMaAppId != null "> and course_ma_app_id = #{courseMaAppId}</if>
             <if test="courseMiniAppId != null "> and course_mini_app_id = #{courseMiniAppId}</if>
             <if test="courseMiniAppId != null "> and course_mini_app_id = #{courseMiniAppId}</if>
             <if test="deptId != null">and dept_id = #{deptId}</if>
             <if test="deptId != null">and dept_id = #{deptId}</if>
+            <if test="customMiniAppId != null "> and custom_mini_app_id = #{customMiniAppId}</if>
         </where>
         </where>
     </select>
     </select>
 
 
@@ -77,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
          </foreach>
          </foreach>
     </select>
     </select>
     <select id="selectCompanyAllList" resultType="com.fs.company.domain.Company">
     <select id="selectCompanyAllList" resultType="com.fs.company.domain.Company">
-        select company_id,company_name from company where is_del=0
+        select company_id,company_name,custom_mini_app_id from company where is_del=0
     </select>
     </select>
     <select id="selectDoctorIdsByCompanyId" resultType="java.lang.String">
     <select id="selectDoctorIdsByCompanyId" resultType="java.lang.String">
         select doctor_ids from company where company_id = #{companyId}
         select doctor_ids from company where company_id = #{companyId}
@@ -113,6 +115,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="packageCateIds != null">package_cate_ids,</if>
             <if test="packageCateIds != null">package_cate_ids,</if>
             <if test="courseMaAppId != null">course_ma_app_id,</if>
             <if test="courseMaAppId != null">course_ma_app_id,</if>
             <if test="courseMiniAppId != null">course_mini_app_id,</if>
             <if test="courseMiniAppId != null">course_mini_app_id,</if>
+            <if test="customMiniAppId != null">custom_mini_app_id,</if>
             <if test="repeat != null">`repeat`,</if>
             <if test="repeat != null">`repeat`,</if>
             <if test="sendIfType != null">send_if_type,</if>
             <if test="sendIfType != null">send_if_type,</if>
             <if test="ifNum != null">if_num,</if>
             <if test="ifNum != null">if_num,</if>
@@ -148,6 +151,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="packageCateIds != null">#{packageCateIds},</if>
             <if test="packageCateIds != null">#{packageCateIds},</if>
             <if test="courseMaAppId != null">#{courseMaAppId},</if>
             <if test="courseMaAppId != null">#{courseMaAppId},</if>
             <if test="courseMiniAppId != null">#{courseMiniAppId},</if>
             <if test="courseMiniAppId != null">#{courseMiniAppId},</if>
+            <if test="customMiniAppId != null">#{customMiniAppId},</if>
             <if test="repeat != null">#{repeat},</if>
             <if test="repeat != null">#{repeat},</if>
             <if test="sendIfType != null">#{sendIfType},</if>
             <if test="sendIfType != null">#{sendIfType},</if>
             <if test="ifNum != null">#{ifNum},</if>
             <if test="ifNum != null">#{ifNum},</if>
@@ -188,6 +192,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="packageCateIds != null">package_cate_ids = #{packageCateIds},</if>
             <if test="packageCateIds != null">package_cate_ids = #{packageCateIds},</if>
             <if test="courseMaAppId != null">course_ma_app_id = #{courseMaAppId},</if>
             <if test="courseMaAppId != null">course_ma_app_id = #{courseMaAppId},</if>
             <if test="courseMiniAppId != null">course_mini_app_id = #{courseMiniAppId},</if>
             <if test="courseMiniAppId != null">course_mini_app_id = #{courseMiniAppId},</if>
+            <if test="customMiniAppId != null">custom_mini_app_id = #{customMiniAppId},</if>
             <if test="fsUserIsDefaultBlack != null ">fs_user_is_default_black = #{fsUserIsDefaultBlack},</if>
             <if test="fsUserIsDefaultBlack != null ">fs_user_is_default_black = #{fsUserIsDefaultBlack},</if>
             <if test="repeat != null">`repeat` = #{repeat},</if>
             <if test="repeat != null">`repeat` = #{repeat},</if>
             <if test="sendIfType != null">send_if_type = #{sendIfType},</if>
             <if test="sendIfType != null">send_if_type = #{sendIfType},</if>
@@ -232,5 +237,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{companyId}
             #{companyId}
         </foreach>
         </foreach>
     </select>
     </select>
+    <select id="selectCompanyListByIds" resultType="com.fs.company.domain.CompanyUser">
+        select role_id roleId,role_name roleName from fastgpt_role
+        <where>
+            <if test="roleIds != null">
+                role_id in
+                <foreach collection="roleIds" item="roleId" separator="," open="(" close=")">
+                    #{roleId}
+                </foreach>
+            </if>
+        </where>
+    </select>
 
 
 </mapper>
 </mapper>

+ 3 - 3
fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml

@@ -328,7 +328,7 @@
         AND ccut.course_id = fcpd.course_id
         AND ccut.course_id = fcpd.course_id
         AND ccut.video_id = fcpd.video_id
         AND ccut.video_id = fcpd.video_id
         AND ccut.company_user_id = #{params.companyUserId}
         AND ccut.company_user_id = #{params.companyUserId}
-        where course.is_del = 0
+        where course.is_del = 0 and fcp.del_flag = '0' and fcpd.del_flag = '0'
         <if test="params.companyId != null">
         <if test="params.companyId != null">
             and FIND_IN_SET(#{params.companyId}, fcp.company_id)
             and FIND_IN_SET(#{params.companyId}, fcp.company_id)
         </if>
         </if>
@@ -361,8 +361,8 @@
         and fcpd.del_flag = 0 and video.is_del = 0 and fcp.del_flag = '0' and c.del_flag = '0'
         and fcpd.del_flag = 0 and video.is_del = 0 and fcp.del_flag = '0' and c.del_flag = '0'
     </select>
     </select>
 
 
-    <select id="selectFsUserCourseVideoByVideoIdAndUserId" resultType="com.fs.course.domain.FsUserCourseVideo">
-        select *  from fs_user_course_video
+    <select id="selectFsUserCourseVideoByVideoIdAndUserId" resultMap="FsUserCourseVideoResult">
+        <include refid="selectFsUserCourseVideoVo"/>
         where video_id=#{videoId} and is_del = 0
         where video_id=#{videoId} and is_del = 0
         <if test="userId != null">
         <if test="userId != null">
            and user_id = #{userId}
            and user_id = #{userId}

+ 80 - 0
fs-service/src/main/resources/mapper/fastGpt/FastGptChatReplaceTextMapper.xml

@@ -0,0 +1,80 @@
+<?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.fastGpt.mapper.FastGptChatReplaceTextMapper">
+
+    <resultMap type="FastGptChatReplaceText" id="FastGptChatReplaceTextResult">
+        <result property="id"    column="id"    />
+        <result property="type"    column="type"    />
+        <result property="content"    column="content"    />
+        <result property="changeCount"    column="change_count"    />
+        <result property="status"    column="status"    />
+        <result property="sort"    column="sort"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectFastGptChatReplaceTextVo">
+        select id, type, content, change_count, status, sort, create_time from fastgpt_chat_replace_text
+    </sql>
+
+    <select id="selectFastGptChatReplaceTextList" parameterType="FastGptChatReplaceText" resultMap="FastGptChatReplaceTextResult">
+        <include refid="selectFastGptChatReplaceTextVo"/>
+        <where>
+            <if test="type != null "> and type = #{type}</if>
+            <if test="content != null  and content != ''"> and content like concat('%', #{content}, '%')</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="sort != null "> and sort = #{sort}</if>
+        </where>
+        order by sort desc,id desc
+    </select>
+
+    <select id="selectFastGptChatReplaceTextById" parameterType="Long" resultMap="FastGptChatReplaceTextResult">
+        <include refid="selectFastGptChatReplaceTextVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertFastGptChatReplaceText" parameterType="FastGptChatReplaceText" useGeneratedKeys="true" keyProperty="id">
+        insert into fastgpt_chat_replace_text
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="type != null">type,</if>
+            <if test="content != null">content,</if>
+            <if test="changeCount != null">change_count,</if>
+            <if test="status != null">status,</if>
+            <if test="sort != null">sort,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="type != null">#{type},</if>
+            <if test="content != null">#{content},</if>
+            <if test="changeCount != null">#{changeCount},</if>
+            <if test="status != null">#{status},</if>
+            <if test="sort != null">#{sort},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFastGptChatReplaceText" parameterType="FastGptChatReplaceText">
+        update fastgpt_chat_replace_text
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="type != null">type = #{type},</if>
+            <if test="content != null">content = #{content},</if>
+            <if test="changeCount != null">change_count = #{changeCount},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="sort != null">sort = #{sort},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFastGptChatReplaceTextById" parameterType="Long">
+        delete from fastgpt_chat_replace_text where id = #{id}
+    </delete>
+
+    <delete id="deleteFastGptChatReplaceTextByIds" parameterType="String">
+        delete from fastgpt_chat_replace_text where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 24 - 0
fs-service/src/main/resources/mapper/fastGpt/FastGptRoleMapper.xml

@@ -48,6 +48,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <include refid="selectFastGptRoleVo"/>
         <include refid="selectFastGptRoleVo"/>
         where role_id = #{roleId}
         where role_id = #{roleId}
     </select>
     </select>
+    <select id="selectFastGptRoleByRoleIds" resultType="com.fs.fastGpt.domain.FastGptRole">
+        select role_id roleId,role_name roleName from fastgpt_role
+        <where>
+            <if test="roleIds != null">
+                role_id in
+                <foreach collection="roleIds" item="roleId" separator="," open="(" close=")">
+                    #{roleId}
+                </foreach>
+            </if>
+        </where>
+    </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 id="insertFastGptRole" parameterType="FastGptRole" useGeneratedKeys="true" keyProperty="roleId">
         insert into fastgpt_role
         insert into fastgpt_role

+ 211 - 0
fs-service/src/main/resources/mapper/fastGpt/FastgptEventLogTotalMapper.xml

@@ -0,0 +1,211 @@
+<?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.fastGpt.mapper.FastgptEventLogTotalMapper">
+    
+    <resultMap type="FastgptEventLogTotal" id="FastgptEventLogTotalResult">
+        <result property="id"    column="id"    />
+        <result property="roleId"    column="role_id"    />
+        <result property="count"    column="count"    />
+        <result property="type"    column="type"    />
+        <result property="companyId"    column="company_id"    />
+        <result property="companyUserId"    column="company_user_id"    />
+        <result property="qwUserId"    column="qw_user_id"    />
+        <result property="statTime"    column="stat_time"    />
+    </resultMap>
+
+    <sql id="selectFastgptEventLogTotalVo">
+        select id, role_id, `count`, `type`, company_id, company_user_id, qw_user_id, stat_time from fastgpt_event_log_total
+    </sql>
+
+    <select id="selectFastgptEventLogTotalList" parameterType="FastgptEventLogTotal" resultMap="FastgptEventLogTotalResult">
+        <include refid="selectFastgptEventLogTotalVo"/>
+        <where>
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="count != null "> and `count` = #{count}</if>
+            <if test="type != null "> and `type` = #{type}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="qwUserId != null "> and qw_user_id = #{qwUserId}</if>
+            <if test="beginTime != null and endTime != null"> <![CDATA[and DATE_FORMAT(create_time, '%Y-%m-%d') >= #{beginTime}
+                                                                 and DATE_FORMAT(create_time, '%Y-%m-%d') <= #{endTime} ]]></if>
+        </where>
+    </select>
+    
+    <select id="selectFastgptEventLogTotalById" parameterType="Long" resultMap="FastgptEventLogTotalResult">
+        <include refid="selectFastgptEventLogTotalVo"/>
+        where id = #{id}
+    </select>
+    <select id="selectFastgptEventLogTotalInfoList" resultType="com.fs.fastGpt.domain.FastgptEventLogTotal">
+        SELECT role_id roleId,company_id companyId,company_user_id companyUserId,qw_user_id qwUserId,event_name eventName,`type`,
+        DATE_FORMAT(create_time,'%Y-%m-%d') as statTime,sum(count) count,count(distinct sender_id) senderCount from fastgpt_event_log
+        <where>
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="roleId == null "> and role_id is not null</if>
+            <if test="createTime != null "> and DATE_FORMAT(create_time,'%Y-%m-%d') = DATE_FORMAT(#{createTime},'%Y-%m-%d')</if>
+            <if test="beginTime != null and endTime != null"> <![CDATA[and DATE_FORMAT(create_time,'%Y-%m-%d') > DATE_FORMAT(#{beginTime},'%Y-%m-%d')
+                                                                 and DATE_FORMAT(create_time,'%Y-%m-%d') <= DATE_FORMAT(#{endTime},'%Y-%m-%d') ]]></if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId == null "> and company_user_id is not null</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="qwUserId == null "> and qw_user_id is not null</if>
+            <if test="qwUserId != null "> and qw_user_id = #{qwUserId}</if>
+        </where>
+        group by role_id,company_id,company_user_id,qw_user_id,event_name,`type`,DATE_FORMAT(create_time,'%Y-%m-%d')
+        order by `type`
+    </select>
+
+    <select id="selectFastgptEventLogTotalVoInfoList" resultType="com.fs.fastGpt.domain.FastgptEventLogTotal">
+        SELECT
+            role_id roleId,type,
+            sum(count) AS count,stat_time statTime
+        FROM fastgpt_event_log_total
+        <where>
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="count != null "> and `count` = #{count}</if>
+            <if test="type != null "> and `type` = #{type}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="qwUserIds != null">
+                and qw_user_id in
+                <foreach collection="qwUserIds.split(',')" item="qwUserId" open="(" close=")" separator=",">
+                    #{qwUserId}
+                </foreach>
+            </if>
+            <if test="roleIds != null">
+                and role_id in
+                <foreach collection="roleIds" item="roleId" open="(" close=")" separator=",">
+                    #{roleId}
+                </foreach>
+            </if>
+            <if test="beginTime != null and endTime != null"> <![CDATA[and DATE_FORMAT(stat_time, '%Y-%m-%d') >= #{beginTime}
+                                                                 and DATE_FORMAT(stat_time, '%Y-%m-%d') <= #{endTime} ]]></if>
+        </where>
+        GROUP BY role_id,stat_time,type WITH ROLLUP
+        HAVING role_id is not null and type is not null
+    </select>
+    <select id="selectFastgptEventTokenLogTotalList" resultType="com.fs.fastGpt.domain.FastGptEventTokenLog">
+        SELECT role_id roleId,company_id companyId,company_user_id companyUserId,qw_user_id qwUserId,
+        DATE_FORMAT(create_time, '%Y-%m-%d') as statTime,sum(token_count) tokenCount from fastgpt_event_token_log
+        where token_type = 0
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="roleId == null "> and role_id is not null</if>
+            <if test="createTime != null "> and DATE_FORMAT(create_time, '%Y-%m-%d') = DATE_FORMAT(#{createTime})</if>
+            <if test="beginTime != null and endTime != null"> <![CDATA[and DATE_FORMAT(create_time, '%Y-%m-%d') > DATE_FORMAT(#{beginTime}, '%Y-%m-%d')
+                                                                 and DATE_FORMAT(create_time, '%Y-%m-%d') <= DATE_FORMAT(#{endTime}, '%Y-%m-%d') ]]></if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="companyUserId == null "> and company_user_id is not null</if>
+            <if test="qwUserId == null "> and qw_user_id is not null</if>
+            <if test="qwUserId != null "> and qw_user_id = #{qwUserId}</if>
+        group by role_id,company_id,company_user_id,qw_user_id,DATE_FORMAT(create_time, '%Y-%m-%d')
+    </select>
+
+    <select id="selectFastgptEventTokenLogTotalByRoleIdAndType" resultMap="FastgptEventLogTotalResult">
+        <include refid="selectFastgptEventLogTotalVo"/>
+        where `type` = 11
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="qwUserId != null "> and qw_user_id = #{qwUserId}</if>
+            <if test="statTime != null "> and stat_time = #{statTime}</if>
+    </select>
+    <select id="selectFastgptEventLogTotalByRoleIdAndType" resultMap="FastgptEventLogTotalResult">
+        <include refid="selectFastgptEventLogTotalVo"/>
+        <where>
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="type != null "> and `type` = #{type}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="qwUserId != null "> and qw_user_id = #{qwUserId}</if>
+            <if test="statTime != null "> and stat_time = #{statTime}</if>
+        </where>
+    </select>
+    <select id="selectFastgptEventLogTotalListByStatTime"
+            resultType="com.fs.fastGpt.vo.FastgptEventLogTotalVo">
+        SELECT fe.stat_time statTime,c.company_id companyId,c.company_name companyName,sum(`count`) `count`
+        FROM `fastgpt_event_log_total` fe left join  company c on fe.company_id = c.company_id
+        where fe.stat_time like concat(#{dateTime},'%')
+        GROUP BY fe.company_id
+        order by fe.company_id
+    </select>
+
+    <insert id="insertFastgptEventLogTotal" parameterType="FastgptEventLogTotal" useGeneratedKeys="true" keyProperty="id">
+        insert into fastgpt_event_log_total
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="roleId != null">role_id,</if>
+            <if test="count != null">`count`,</if>
+            <if test="type != null">`type`,</if>
+            <if test="companyId != null">company_id,</if>
+            <if test="companyUserId != null">company_user_id,</if>
+            <if test="qwUserId != null">qw_user_id,</if>
+            <if test="statTime != null">stat_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="roleId != null">#{roleId},</if>
+            <if test="count != null">#{count},</if>
+            <if test="type != null">#{type},</if>
+            <if test="companyId != null">#{companyId},</if>
+            <if test="companyUserId != null">#{companyUserId},</if>
+            <if test="qwUserId != null">#{qwUserId},</if>
+            <if test="statTime != null">#{statTime},</if>
+         </trim>
+    </insert>
+    <insert id="insertFastgptEventLogTotalBatch" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO fastgpt_event_log_total
+        (role_id, `count`, `type`, company_id, company_user_id, qw_user_id, stat_time)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.roleId},
+            #{item.count},
+            #{item.type},
+            #{item.companyId},
+            #{item.companyUserId},
+            #{item.qwUserId},
+            #{item.statTime}
+            )
+        </foreach>
+    </insert>
+
+    <update id="updateFastgptEventLogTotal" parameterType="FastgptEventLogTotal">
+        update fastgpt_event_log_total
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="roleId != null">role_id = #{roleId},</if>
+            <if test="count != null">`count` = #{count},</if>
+            <if test="type != null">`type` = #{type},</if>
+            <if test="companyId != null">company_id = #{companyId},</if>
+            <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
+            <if test="qwUserId != null">qw_user_id = #{qwUserId},</if>
+            <if test="statTime != null">stat_time = #{statTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+    <update id="updateFastgptEventLogTotalBatch" parameterType="java.util.List">
+        <foreach collection="list" item="item" separator=";">
+            UPDATE fastgpt_event_log_total
+            <set>
+                <if test="item.roleId != null">role_id = #{item.roleId},</if>
+                <if test="item.count != null">`count` = #{item.count},</if>
+                <if test="item.type != null">`type` = #{item.type},</if>
+                <if test="item.companyId != null">company_id = #{item.companyId},</if>
+                <if test="item.companyUserId != null">company_user_id = #{item.companyUserId},</if>
+                <if test="item.qwUserId != null">qw_user_id = #{item.qwUserId},</if>
+                <if test="item.statTime != null">stat_time = #{item.statTime},</if>
+            </set>
+            WHERE id = #{item.id}
+        </foreach>
+    </update>
+
+    <delete id="deleteFastgptEventLogTotalById" parameterType="Long">
+        delete from fastgpt_event_log_total where id = #{id}
+    </delete>
+
+    <delete id="deleteFastgptEventLogTotalByIds" parameterType="String">
+        delete from fastgpt_event_log_total where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

Some files were not shown because too many files changed in this diff