Browse Source

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

caoliqin 1 week ago
parent
commit
9b717afe64
30 changed files with 568 additions and 83 deletions
  1. 1 1
      fs-admin/src/main/java/com/fs/course/controller/qw/QwFsCourseWatchLogController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/qw/controller/QwSopTempController.java
  3. 14 2
      fs-company-app/src/main/java/com/fs/app/controller/QwWorkTaskController.java
  4. 1 1
      fs-company/src/main/java/com/fs/course/controller/qw/QwFsCourseWatchLogController.java
  5. 1 0
      fs-company/src/main/java/com/fs/qw/QwQwWorkTaskController.java
  6. 1 1
      fs-company/src/main/java/com/fs/qw/QwSopTempController.java
  7. 6 5
      fs-company/src/main/java/com/fs/qw/QwUserController.java
  8. 34 6
      fs-company/src/main/java/com/fs/qw/qw/QwWorkTaskController.java
  9. 127 40
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  10. 160 0
      fs-qw-api-msg/src/main/java/com/fs/app/util/AudioUtils.java
  11. 14 1
      fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java
  12. 28 1
      fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  13. 2 0
      fs-service-system/src/main/java/com/fs/kingbos/service/impl/K9OrderServiceImpl.java
  14. 21 0
      fs-service-system/src/main/java/com/fs/qw/mapper/QwWorkTaskMapper.java
  15. 20 0
      fs-service-system/src/main/java/com/fs/qw/param/QwWorkTaskListParam.java
  16. 2 0
      fs-service-system/src/main/java/com/fs/qw/service/IQwUserService.java
  17. 3 0
      fs-service-system/src/main/java/com/fs/qw/service/IQwWorkTaskService.java
  18. 17 1
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java
  19. 6 4
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java
  20. 6 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwWorkTaskServiceImpl.java
  21. 2 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwContactListVO.java
  22. 22 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwWorkTaskAllListVO.java
  23. 0 4
      fs-service-system/src/main/java/com/fs/wx/mp/config/WxMpConfiguration.java
  24. 31 0
      fs-service-system/src/main/java/com/fs/wxwork/dto/WxDownloadFileDTO.java
  25. 7 0
      fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java
  26. 8 0
      fs-service-system/src/main/java/com/fs/wxwork/service/WxWorkService.java
  27. 12 0
      fs-service-system/src/main/java/com/fs/wxwork/service/WxWorkServiceImpl.java
  28. 11 11
      fs-service-system/src/main/resources/application-config-dev.yml
  29. 9 3
      fs-service-system/src/main/resources/mapper/qw/QwWorkTaskMapper.xml
  30. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

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

@@ -70,7 +70,7 @@ public class QwFsCourseWatchLogController extends BaseController
         return getDataTable(list);
     }
 
-    @PreAuthorize("@ss.hasPermi('course:courseWatchLog:statisticsList')")
+    @PreAuthorize("@ss.hasPermi('course:courseWatchLog:qw:statisticsList')")
     @GetMapping("/statisticsList")
     public TableDataInfo statisticsList(FsCourseWatchLogStatisticsListParam param)
     {

+ 1 - 1
fs-admin/src/main/java/com/fs/qw/controller/QwSopTempController.java

@@ -128,7 +128,7 @@ public class QwSopTempController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         qwSopTemp.setCreateBy(loginUser.getUser().getUserId().toString());
         int i = qwSopTempService.addNew(qwSopTemp);
-        if(qwSopTemp.getSendType() == 5){
+        if(qwSopTemp.getSendType() == 11){
             qwSopTempService.createSopTempRules(qwSopTemp);
         }
         return toAjax(i);

+ 14 - 2
fs-company-app/src/main/java/com/fs/app/controller/QwWorkTaskController.java

@@ -36,7 +36,7 @@ public class QwWorkTaskController extends AppBaseController {
     @Login
     @ApiOperation("企微任务看板列表")
     @GetMapping("/list")
-    public R list (@Valid QwWorkTaskQueryParam param) {
+    public R list(@Valid QwWorkTaskQueryParam param) {
         log.debug("企微任务看板列表:{}", JSON.toJSONString(param));
 
         Map<String, Object> params = new HashMap<>();
@@ -67,11 +67,23 @@ public class QwWorkTaskController extends AppBaseController {
     @ApiOperation("催课看板会员列表")
     @GetMapping("/getUserList")
     public R getUserList(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
-                      @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+                         @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
         Long userId = Long.parseLong(getUserId());
         PageHelper.startPage(pageNum, pageSize);
         List<UserVOs> list = qwUserService.getUserList(userId);
         return R.ok().put("data", new PageInfo<>(list));
     }
 
+    @Login
+    @ApiOperation("催课看板企微会员列表")
+    @GetMapping("/getQwUserList")
+    public R getQwUserList(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                           @RequestParam(required = false, defaultValue = "10") Integer pageSize,
+                           @RequestParam(required = false, defaultValue = "10") String qwUserId) {
+        Long userId = Long.parseLong(getUserId());
+        PageHelper.startPage(pageNum, pageSize);
+        List<UserVOs> list = qwUserService.getQwUserList(userId, qwUserId);
+        return R.ok().put("data", new PageInfo<>(list));
+    }
+
 }

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

@@ -71,7 +71,7 @@ public class QwFsCourseWatchLogController extends BaseController
         return getDataTable(list);
     }
 
-    @PreAuthorize("@ss.hasPermi('course:courseWatchLog:statisticsList')")
+    @PreAuthorize("@ss.hasPermi('course:courseWatchLog:qw:statisticsList')")
     @GetMapping("/statisticsList")
     public TableDataInfo statisticsList(FsCourseWatchLogStatisticsListParam param)
     {

+ 1 - 0
fs-company/src/main/java/com/fs/qw/QwQwWorkTaskController.java

@@ -17,6 +17,7 @@ import com.fs.qw.domain.QwWorkTask;
 import com.fs.qw.param.QwWorkTaskListParam;
 import com.fs.qw.service.IHyWorkTaskService;
 import com.fs.qw.service.IQwWorkTaskService;
+import com.fs.qw.vo.QwWorkTaskAllListVO;
 import com.fs.qw.vo.QwWorkTaskListVO;
 import com.github.pagehelper.PageInfo;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 1
fs-company/src/main/java/com/fs/qw/QwSopTempController.java

@@ -136,7 +136,7 @@ public class QwSopTempController extends BaseController
         qwSopTemp.setCompanyId(loginUser.getCompany().getCompanyId());
         qwSopTemp.setCreateBy(loginUser.getUser().getUserId().toString());
         int i = qwSopTempService.addNew(qwSopTemp);
-        if(qwSopTemp.getSendType() == 5){
+        if(qwSopTemp.getSendType() == 11){
             qwSopTempService.createSopTempRules(qwSopTemp);
         }
         return toAjax(i);

+ 6 - 5
fs-company/src/main/java/com/fs/qw/QwUserController.java

@@ -140,7 +140,7 @@ public class QwUserController extends BaseController
         return qwUserService.loginQwCode(loginParam);
     }
 
-    @PreAuthorize("@ss.hasPermi('qw:user:login')")
+    @PreAuthorize("@ss.hasPermi('qw:user:loginQwIpad')")
     @PostMapping("/loginQwIpad")
     public R loginQwIpad(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.loginQwIpad(loginParam);
@@ -151,28 +151,27 @@ public class QwUserController extends BaseController
      * @param loginParam
      * @return
      */
-    @PreAuthorize("@ss.hasPermi('qw:user:login')")
+    @PreAuthorize("@ss.hasPermi('qw:user:allocateRemoteHost')")
     @PostMapping("/allocateRemoteHost")
     @RepeatSubmit
     public R allocateRemoteHost(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.allocateRemoteHost(loginParam);
     }
 
-    @PreAuthorize("@ss.hasPermi('qw:user:login')")
+    @PreAuthorize("@ss.hasPermi('qw:user:getQwIpad')")
     @PostMapping("/getQwIpad")
     @RepeatSubmit
     public R getQwIpad(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.getQwIpad(loginParam);
     }
 
-    @PreAuthorize("@ss.hasPermi('qw:user:login')")
+    @PreAuthorize("@ss.hasPermi('qw:user:delQwIpad')")
     @PostMapping("/delQwIpad")
     @RepeatSubmit
     public R delQwIpad(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.delQwIpad(loginParam);
     }
 
-    @PreAuthorize("@ss.hasPermi('qw:user:login')")
     @PostMapping("/qrCodeStatus")
     public R qrCodeStatus(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.qrCodeStatus(loginParam);
@@ -183,11 +182,13 @@ public class QwUserController extends BaseController
         return qwUserService.qrCodeVerify(loginParam);
     }
 
+    @PreAuthorize("@ss.hasPermi('qw:user:outLoginQwIpad')")
     @PostMapping("/outLoginQwIpad")
     public R outLoginQwIpad(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.outLoginQwIpad(loginParam);
     }
 
+    @PreAuthorize("@ss.hasPermi('qw:user:twoCode')")
     @PostMapping("/twoCode")
     public R twoCode(@RequestBody QwLoginHookParam loginParam){
         return qwUserService.getTwoCode(loginParam);

+ 34 - 6
fs-company/src/main/java/com/fs/qw/qw/QwWorkTaskController.java

@@ -14,6 +14,7 @@ import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.qw.domain.QwWorkTask;
 import com.fs.qw.param.QwWorkTaskListParam;
 import com.fs.qw.service.IQwWorkTaskService;
+import com.fs.qw.vo.QwWorkTaskAllListVO;
 import com.fs.qw.vo.QwWorkTaskListVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -41,7 +42,7 @@ public class QwWorkTaskController extends BaseController
     /**
      * 查询企微任务看板列表
      */
-    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:list')")
+    @PreAuthorize("@ss.hasPermi('qw:qw:QwWorkTask:list')")
     @GetMapping("/list")
     public TableDataInfo list(QwWorkTaskListParam qwWorkTask)
     {
@@ -58,10 +59,37 @@ public class QwWorkTaskController extends BaseController
         return getDataTable(list);
     }
 
+    @GetMapping("/glList")
+    public TableDataInfo glList(QwWorkTaskListParam qwWorkTask)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        qwWorkTask.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<QwWorkTaskListVO> list = qwWorkTaskService.selectQwWorkTaskListVO(qwWorkTask);
+        for (QwWorkTaskListVO qwWorkTaskListVO : list) {
+            qwWorkTaskListVO.setLogs(fsCourseWatchLogMapper.selectFsCourseWatchLog7DayByExtId(qwWorkTaskListVO.getExtId()));
+        }
+        return getDataTable(list);
+    }
+
+    @GetMapping("/allList")
+    public TableDataInfo allList(QwWorkTaskListParam qwWorkTask)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        qwWorkTask.setCompanyId(loginUser.getCompany().getCompanyId());
+        if (qwWorkTask.getSTime()==null||qwWorkTask.getETime()==null){
+            return new TableDataInfo();
+        }
+        List<QwWorkTaskAllListVO> list = qwWorkTaskService.selectQwWorkTaskAllListVO(qwWorkTask);
+
+        return getDataTable(list);
+    }
+
     /**
      * 导出企微任务看板列表
      */
-    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:export')")
+    @PreAuthorize("@ss.hasPermi('qw:qw:QwWorkTask:export')")
     @Log(title = "企微任务看板", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
     public AjaxResult export(QwWorkTask qwWorkTask)
@@ -74,7 +102,7 @@ public class QwWorkTaskController extends BaseController
     /**
      * 获取企微任务看板详细信息
      */
-    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:query')")
+    @PreAuthorize("@ss.hasPermi('qw:qw:QwWorkTask:query')")
     @GetMapping(value = "/{id}")
     public AjaxResult getInfo(@PathVariable("id") Long id)
     {
@@ -84,7 +112,7 @@ public class QwWorkTaskController extends BaseController
     /**
      * 新增企微任务看板
      */
-    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:add')")
+    @PreAuthorize("@ss.hasPermi('qw:qw:QwWorkTask:add')")
     @Log(title = "企微任务看板", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@RequestBody QwWorkTask qwWorkTask)
@@ -95,7 +123,7 @@ public class QwWorkTaskController extends BaseController
     /**
      * 修改企微任务看板
      */
-    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:edit')")
+    @PreAuthorize("@ss.hasPermi('qw:qw:QwWorkTask:edit')")
     @Log(title = "企微任务看板处理", businessType = BusinessType.UPDATE)
     @PutMapping
     public AjaxResult edit(@RequestBody QwWorkTask qwWorkTask)
@@ -111,7 +139,7 @@ public class QwWorkTaskController extends BaseController
     /**
      * 删除企微任务看板
      */
-    @PreAuthorize("@ss.hasPermi('qw:QwWorkTask:remove')")
+    @PreAuthorize("@ss.hasPermi('qw:qw:QwWorkTask:remove')")
     @Log(title = "企微任务看板", businessType = BusinessType.DELETE)
 	@DeleteMapping("/{ids}")
     public AjaxResult remove(@PathVariable Long[] ids)

+ 127 - 40
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -2,7 +2,9 @@ package com.fs.app.controller;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.app.socket.QwImSocket;
+import com.fs.app.util.AudioUtils;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.uuid.IdUtils;
 import com.fs.fastGpt.service.AiHookService;
 import com.fs.qw.domain.QwUser;
@@ -143,14 +145,27 @@ public class QwMsgController {
                 if (wxWorkMessageDTO.getReferid()!=0){
                     break;
                 }
+
+                Long receiver = wxWorkMessageDTO.getReceiver();
+                Long sender = wxWorkMessageDTO.getSender();
+
+                // 1客户 2销售
+                int sendType = 2;
+
+                // 消息发送者用户ID
+                Long userId = receiver;
+                if (2000000000000000L - receiver > 0){
+                    sendType = 1;
+                    userId = sender;
+                }
+
                 if (wxWorkMessageDTO.getMsgtype()==2||wxWorkMessageDTO.getMsgtype()==0||wxWorkMessageDTO.getMsgtype()==16){
 
                     String content = wxWorkMessageDTO.getContent();
                     System.out.println("接收人:"+wxWorkMessageDTO.getReceiver());
                     System.out.println("发送人:"+wxWorkMessageDTO.getSender());
                     System.out.println("内容:"+content);
-                    Long receiver = wxWorkMessageDTO.getReceiver();
-                    Long sender = wxWorkMessageDTO.getSender();
+
                     if(wxWorkMessageDTO.getMsgtype()==16){
                         WxwSpeechToTextEntityDTO ste = new WxwSpeechToTextEntityDTO();
                         ste.setMsgid(wxWorkMessageDTO.getMsg_id());
@@ -164,26 +179,25 @@ public class QwMsgController {
                     if (2000000000000000L-receiver>0){
                         System.out.println("客户发送");
                         aiHookService.qwHookNotifyAiReply(id,sender,content,wxWorkMsgResp.getUuid(),wxWorkMessageDTO.getMsgtype());
-
-                        // 保存聊天消息
-                        QwMessageListVO message = aiHookService.saveQwMsg(id, sender, content, wxWorkMsgResp.getUuid(), 1, wxWorkMsgResp.getJson(), 1);
-                        QwImSocket.broadcast(message);
                     }else {
                         System.out.println("销售发送");
                         aiHookService.qwHookNotifyAddMsg(id,receiver,content,wxWorkMsgResp.getUuid());
-
-                        // 保存聊天消息
-                        QwMessageListVO message = aiHookService.saveQwMsg(id, receiver, content, wxWorkMsgResp.getUuid(), 2, wxWorkMsgResp.getJson(), 1);
-                        QwImSocket.broadcast(message);
                     }
 
+                    // 处理文本消息
+                    if (wxWorkMessageDTO.getMsgtype() == 2 || wxWorkMessageDTO.getMsgtype() == 0) {
+                        processTextMessage(id, userId, content, wxWorkMsgResp, sendType);
+                    }
+                    // 语音消息
+                    if (wxWorkMessageDTO.getMsgtype() == 16) {
+                        processVoiceMessage(serverId, content, wxWorkMessageDTO, wxWorkMsgResp, id, userId, sendType);
+                    }
                 }
                 //语音通话
                 if (wxWorkMessageDTO.getMsgtype()==40){
                     if (wxWorkMessageDTO.getRecordtype()==null){
                         break;
                     }
-                    Long receiver = wxWorkMessageDTO.getReceiver();
                     Long extId=null;
                     Integer totalSeconds=0;
                     if (2000000000000000L-receiver>0){
@@ -217,35 +231,11 @@ public class QwMsgController {
                 }
                 // 图片消息
                 else if (wxWorkMessageDTO.getMsgtype() == 101){
-                    System.out.println(json);
-                    System.out.println(wxWorkMsgResp.getJson());
-                    Long receiver = wxWorkMessageDTO.getReceiver();
-                    Long sender = wxWorkMessageDTO.getSender();
-
-                    long userId;
-                    int sendType;
-                    if (2000000000000000L - receiver > 0){
-                        System.out.println("客户发起");
-                        userId = sender;
-                        sendType= 1;
-                    }else {
-                        System.out.println("销售发起");
-                        userId = receiver;
-                        sendType= 2;
-                    }
-
-                    String fileName = IdUtils.fastSimpleUUID() + ".jpg";
-                    WxWorkResponseDTO<String> fileUrlResp =
-                            aiHookService.getFileUrl(wxWorkMsgResp.getUuid(), wxWorkMessageDTO.getFile_id(), wxWorkMessageDTO.getAes_key(), wxWorkMessageDTO.getOpenim_cdn_authkey(), fileName, wxWorkMessageDTO.getFile_size(), serverId);
-                    if (fileUrlResp.getErrcode() != 0) {
-                        log.warn("获取图片地址失败: {}", fileUrlResp.getErrmsg());
-                        break;
-                    }
-
-                    String content = fileUrlResp.getData();
-                    // 保存聊天消息
-                    QwMessageListVO message = aiHookService.saveQwMsg(id, userId, content, wxWorkMsgResp.getUuid(), sendType, wxWorkMsgResp.getJson(), 2);
-                    QwImSocket.broadcast(message);
+                    processImageMessage(serverId, wxWorkMessageDTO, wxWorkMsgResp, id, userId, sendType);
+                }
+                // gif 表情消息
+                else if (wxWorkMessageDTO.getMsgtype() == 104){
+                    processEmotionDynamicMessage(wxWorkMessageDTO, wxWorkMsgResp, id, userId, sendType);
                 }
 
                 break;
@@ -258,6 +248,103 @@ public class QwMsgController {
         return map;
     }
 
+    /**
+     * 处理文本消息
+     * @param id                企微用户ID
+     * @param userId            消息发送者ID
+     * @param content           消息内容
+     * @param wxWorkMsgResp     回调信息对象
+     * @param sendType          发送者类型 1客户 2销售
+     */
+    private void processTextMessage(Long id, Long userId, String content, WxWorkMsgResp wxWorkMsgResp, Integer sendType) {
+        // 保存聊天消息
+        QwMessageListVO message = aiHookService.saveQwMsg(id, userId, content, wxWorkMsgResp.getUuid(), sendType, wxWorkMsgResp.getJson(), 1);
+        QwImSocket.broadcast(message);
+    }
+
+    /**
+     * 处理语音消息
+     * @param serverId          服务器ID
+     * @param wxWorkMessageDTO  消息DTO
+     * @param content           翻译后的内容
+     * @param wxWorkMsgResp     回调信息对象
+     * @param id                企微用户ID
+     * @param userId            消息发送者ID
+     * @param sendType          发送者类型 1客户 2销售
+     */
+    private void processVoiceMessage(Long serverId, String content, WxWorkMessageDTO wxWorkMessageDTO, WxWorkMsgResp wxWorkMsgResp, Long id, Long userId, Integer sendType) {
+        String voiceFileName = IdUtils.fastSimpleUUID() + ".silk";
+        WxWorkResponseDTO<String> fileUrlResp =
+                aiHookService.getFileUrl(wxWorkMsgResp.getUuid(), wxWorkMessageDTO.getVoice_id(), wxWorkMessageDTO.getAes_key(), 5, voiceFileName, wxWorkMessageDTO.getVoice_size(), serverId);
+        if (fileUrlResp.getErrcode() != 0) {
+            log.warn("获取语音地址失败: {}", fileUrlResp.getErrmsg());
+            return;
+        }
+
+        // silk转map3
+        String url = AudioUtils.convertSilk2Mp3(fileUrlResp.getData());
+        if (StringUtils.isBlank(url)) {
+            log.warn("转换silk语音格式失败");
+            return;
+        }
+
+        // 转换内容为空时再尝试一次
+        if (StringUtils.isBlank(content)) {
+            WxwSpeechToTextEntityDTO ste = new WxwSpeechToTextEntityDTO();
+            ste.setMsgid(wxWorkMessageDTO.getMsg_id());
+            ste.setUuid(wxWorkMsgResp.getUuid());
+            WxWorkResponseDTO<WxwSpeechToTextEntityRespDTO> dto = wxWorkService.SpeechToTextEntity(ste, serverId);
+            content = dto.getData().getText();
+        }
+
+        JSONObject json = new JSONObject();
+        json.put("url", url);
+        json.put("content", content);
+
+        // 保存聊天消息
+        QwMessageListVO message = aiHookService.saveQwMsg(id, userId, json.toString(), wxWorkMsgResp.getUuid(), sendType, wxWorkMsgResp.getJson(), 4);
+        QwImSocket.broadcast(message);
+    }
+
+    /**
+     * 处理图片消息
+     * @param serverId          服务器ID
+     * @param wxWorkMessageDTO  消息DTO
+     * @param wxWorkMsgResp     回调信息对象
+     * @param id                企微用户ID
+     * @param userId            消息发送者ID
+     * @param sendType          发送者类型 1客户 2销售
+     */
+    private void processImageMessage(Long serverId, WxWorkMessageDTO wxWorkMessageDTO, WxWorkMsgResp wxWorkMsgResp, Long id, Long userId, Integer sendType) {
+        String fileName = IdUtils.fastSimpleUUID() + ".jpg";
+        WxWorkResponseDTO<String> fileUrlResp =
+                aiHookService.getFileUrl(wxWorkMsgResp.getUuid(), wxWorkMessageDTO.getFile_id(), wxWorkMessageDTO.getAes_key(), wxWorkMessageDTO.getOpenim_cdn_authkey(), fileName, wxWorkMessageDTO.getFile_size(), serverId);
+        if (fileUrlResp.getErrcode() != 0) {
+            log.warn("获取图片地址失败: {}", fileUrlResp.getErrmsg());
+            return;
+        }
+
+        String content = fileUrlResp.getData();
+        // 保存聊天消息
+        QwMessageListVO message = aiHookService.saveQwMsg(id, userId, content, wxWorkMsgResp.getUuid(), sendType, wxWorkMsgResp.getJson(), 2);
+        QwImSocket.broadcast(message);
+    }
+
+    /**
+     * 处理动态表情消息
+     * @param wxWorkMessageDTO  消息DTO
+     * @param wxWorkMsgResp     回调信息对象
+     * @param id                企微用户ID
+     * @param userId            消息发送者ID
+     * @param sendType          发送者类型 1客户 2销售
+     */
+    private void processEmotionDynamicMessage(WxWorkMessageDTO wxWorkMessageDTO, WxWorkMsgResp wxWorkMsgResp, Long id, Long userId, int sendType) {
+        String content = wxWorkMessageDTO.getUrl();
+        // 保存聊天消息
+        QwMessageListVO message = aiHookService.saveQwMsg(id, userId, content, wxWorkMsgResp.getUuid(), sendType, wxWorkMsgResp.getJson(), 3);
+        QwImSocket.broadcast(message);
+    }
+
     void qwUserStatus(String uid,Integer status){
         Long id = redisCache.getCacheObject("qrCode:uuid:"+uid);
         QwUser qwUser = new QwUser();

+ 160 - 0
fs-qw-api-msg/src/main/java/com/fs/app/util/AudioUtils.java

@@ -0,0 +1,160 @@
+package com.fs.app.util;
+
+import com.fs.common.utils.uuid.IdUtils;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.http.HttpStatus;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class AudioUtils {
+
+    /**
+     * silk转换为mp3
+     * @param silkUrl silk语音链接地址
+     * @return  mp3链接地址
+     */
+    public static String convertSilk2Mp3(String silkUrl) {
+        String uniqueId = IdUtils.fastSimpleUUID();
+        Path uploadDirPath = Paths.get(System.getProperty("java.io.tmpdir"), "/");
+        Path downloadedSilkFilePath = uploadDirPath.resolve(uniqueId + ".silk");
+        Path pcmFilePath = uploadDirPath.resolve(uniqueId + ".pcm");
+        Path mp3FilePath = uploadDirPath.resolve(uniqueId + ".mp3");
+
+        try {
+            // 1. 从网络下载 SILK 文件
+            downloadFile(silkUrl, downloadedSilkFilePath);
+            log.info("SILK file downloaded to: {}", downloadedSilkFilePath);
+
+            // 2. 使用 silk-v3-decoder 解码 SILK 到 PCM
+            List<String> silkDecodeCommand = new ArrayList<>();
+            silkDecodeCommand.add("silk_v3_decoder");
+            silkDecodeCommand.add(downloadedSilkFilePath.toString());
+            silkDecodeCommand.add(pcmFilePath.toString());
+
+            ProcessBuilder silkDecoderPb = new ProcessBuilder(silkDecodeCommand);
+            silkDecoderPb.redirectErrorStream(true); // 将错误流合并到标准输出
+            Process silkDecoderProcess = silkDecoderPb.start();
+
+            String silkDecoderOutput = readInputStreamToString(silkDecoderProcess.getInputStream());
+
+            boolean silkDecoderExited = silkDecoderProcess.waitFor(60, TimeUnit.SECONDS);
+            if (!silkDecoderExited || silkDecoderProcess.exitValue() != 0) {
+                log.error("silk conversion failed or timed out. error: {}", silkDecoderOutput);
+                return null;
+            }
+            log.info("SILK decoder to PCM successfully.");
+
+            // 3. 使用 FFmpeg 将 PCM 转码为 MP3
+            Process ffmpegProcess = getFfmpegProcess(pcmFilePath, mp3FilePath);
+            String ffmpegOutput = readInputStreamToString(ffmpegProcess.getInputStream());
+
+            boolean ffmpegExited = ffmpegProcess.waitFor(120, TimeUnit.SECONDS);
+            if (!ffmpegExited || ffmpegProcess.exitValue() != 0) {
+                log.error("ffmpeg conversion failed or timed out. error: {}", ffmpegOutput);
+                return null;
+            }
+            log.info("ffmpeg conversion to MP3 successfully.");
+
+            // 4. 上传oss
+            String fileName = mp3FilePath.getFileName().toString();
+            String suffix = fileName.substring(fileName.lastIndexOf("."));
+            CloudStorageService storage = OSSFactory.build();
+            return storage.uploadSuffix(Files.newInputStream(mp3FilePath), suffix);
+
+        } catch (IOException | InterruptedException | NullPointerException e) {
+            log.error("Conversion error: {}", e.getMessage());
+            return null;
+        } finally {
+            // 清理临时文件 (重要!)
+            try {
+                if (Files.exists(downloadedSilkFilePath)) Files.delete(downloadedSilkFilePath);
+                if (Files.exists(pcmFilePath)) Files.delete(pcmFilePath);
+                if (Files.exists(mp3FilePath)) Files.delete(mp3FilePath);
+            } catch (IOException e) {
+                log.error("Error cleaning up temporary files:: {}", e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * 执行ffmpeg
+     * @param pcmFilePath   pcm文件
+     * @param mp3FilePath   mp3地址
+     * @return  process
+     * @throws IOException exception
+     */
+    private static Process getFfmpegProcess(Path pcmFilePath, Path mp3FilePath) throws IOException {
+        List<String> ffmpegCommand = new ArrayList<>();
+        ffmpegCommand.add("ffmpeg");
+        ffmpegCommand.add("-y");
+        ffmpegCommand.add("-f");
+        ffmpegCommand.add("s16le");
+        ffmpegCommand.add("-ar");
+        ffmpegCommand.add("24000"); // 注意:这里假设是 24kHz,如果你的 SILK 文件是其他采样率,请调整
+        ffmpegCommand.add("-ac");
+        ffmpegCommand.add("1");
+        ffmpegCommand.add("-i");
+        ffmpegCommand.add(pcmFilePath.toString());
+        ffmpegCommand.add(mp3FilePath.toString());
+
+        ProcessBuilder ffmpegPb = new ProcessBuilder(ffmpegCommand);
+        ffmpegPb.redirectErrorStream(true);
+        return ffmpegPb.start();
+    }
+
+    /**
+     * 处理文件流
+     * @param is 输入流
+     * @return  输出
+     * @throws IOException exception
+     */
+    private static String readInputStreamToString(InputStream is) throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = is.read(buffer)) != -1) {
+            bos.write(buffer, 0, len);
+        }
+        return bos.toString("UTF-8"); // 使用 UTF-8 编码
+    }
+
+    /**
+     * 下载网络文件
+     * @param fileUrl       网络文件
+     * @param destination   临时文件
+     * @throws IOException  exception
+     */
+    private static void downloadFile(String fileUrl, Path destination) throws IOException {
+        try (CloseableHttpClient httpClient = HttpClients.createDefault();
+             CloseableHttpResponse response = httpClient.execute(new HttpGet(fileUrl));
+             InputStream inputStream = response.getEntity().getContent();
+             FileOutputStream outputStream = new FileOutputStream(destination.toFile())) {
+
+            if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
+                throw new IOException("Failed to download file from " + fileUrl + ", HTTP Status: " + response.getStatusLine().getStatusCode());
+            }
+
+            byte[] buffer = new byte[4096];
+            int bytesRead;
+            while ((bytesRead = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, bytesRead);
+            }
+        }
+    }
+}

+ 14 - 1
fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java

@@ -28,7 +28,7 @@ public interface AiHookService {
      * @param uuid     UUID
      * @param sendType 发送者类型 1用户 2客服
      * @param json     消息json
-     * @param msgType  消息类型 1文本 2图片
+     * @param msgType  消息类型 1文本 2图片 3动态表情 4语音
      */
     QwMessageListVO saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType, String json, int msgType);
 
@@ -44,4 +44,17 @@ public interface AiHookService {
      * @return  WxWorkResponseDTO
      */
     WxWorkResponseDTO<String> getFileUrl(String uuid, String fileId, String aesKey, String authKey, String fileName, Integer fileSize, Long serverId);
+
+    /**
+     * 获取文件地址
+     * @param uuid      uuid
+     * @param fileId    fileId
+     * @param aesKey    aesKey
+     * @param fileType  fileType
+     * @param fileName  fileName
+     * @param fileSize  fileSize
+     * @param serverId  serverId
+     * @return  WxWorkResponseDTO
+     */
+    WxWorkResponseDTO<String> getFileUrl(String uuid, String fileId, String aesKey, Integer fileType, String fileName, Integer fileSize, Long serverId);
 }

+ 28 - 1
fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -1269,7 +1269,7 @@ public class AiHookServiceImpl implements AiHookService {
      * @param uuid     UUID
      * @param sendType 发送者类型 1用户 2客服
      * @param json     消息json
-     * @param msgType  消息类型 1文本 2图片
+     * @param msgType  消息类型 1文本 2图片 3动态表情 4语音
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
@@ -1347,6 +1347,10 @@ public class AiHookServiceImpl implements AiHookService {
         String type = "text";
         if (msgType == 2) {
             type = "image";
+        } else if (msgType == 3) {
+            type = "emotionDynamic";
+        } else if (msgType == 4) {
+            type = "voice";
         }
         listVO.setType(type);
         listVO.setStatus("succeed");
@@ -1381,6 +1385,29 @@ public class AiHookServiceImpl implements AiHookService {
         return wxWorkService.downloadWeChatFile(weChatFileDTO, serverId);
     }
 
+    /**
+     * 获取文件地址
+     * @param uuid      uuid
+     * @param fileId    fileId
+     * @param aesKey    aesKey
+     * @param fileType  fileType
+     * @param fileName  fileName
+     * @param fileSize  fileSize
+     * @param serverId  serverId
+     * @return  WxWorkResponseDTO
+     */
+    @Override
+    public WxWorkResponseDTO<String> getFileUrl(String uuid, String fileId, String aesKey, Integer fileType, String fileName, Integer fileSize, Long serverId) {
+        WxDownloadFileDTO downloadFileDTO = new WxDownloadFileDTO();
+        downloadFileDTO.setUuid(uuid);
+        downloadFileDTO.setFileid(fileId);
+        downloadFileDTO.setAes_key(aesKey);
+        downloadFileDTO.setFiletype(fileType);
+        downloadFileDTO.setFile_name(fileName);
+        downloadFileDTO.setSize(fileSize);
+        return wxWorkService.downloadFile(downloadFileDTO, serverId);
+    }
+
     /**
      * 查询外部联系人
      * @param userId    用户ID

+ 2 - 0
fs-service-system/src/main/java/com/fs/kingbos/service/impl/K9OrderServiceImpl.java

@@ -75,6 +75,7 @@ public class K9OrderServiceImpl implements K9OrderService {
     }
 
 
+    //运单号已获取到
     @Override
     public KingbosOrderResponse refundOrder(KingbosRefundOrderRequest request) {
         JSONObject param = JSONUtil.createObj();
@@ -108,6 +109,7 @@ public class K9OrderServiceImpl implements K9OrderService {
         return new ErpOrderResponse();
     }
 
+    //运单号未获取到  改状态
     @Override
     public ErpOrderResponse refundOmsOrder(Long orderId) {
         try {

+ 21 - 0
fs-service-system/src/main/java/com/fs/qw/mapper/QwWorkTaskMapper.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.qw.domain.QwUserVoiceLog;
 import com.fs.qw.domain.QwWorkTask;
 import com.fs.qw.param.QwWorkTaskListParam;
+import com.fs.qw.vo.QwWorkTaskAllListVO;
 import com.fs.qw.vo.QwWorkTaskListVO;
 import com.fs.qw.vo.UserVOs;
 import org.apache.ibatis.annotations.Param;
@@ -130,4 +131,24 @@ public interface QwWorkTaskMapper extends BaseMapper<QwWorkTask>{
     List<UserVOs> getUserList(@Param("userId") Long userId);
 
     List<QwWorkTask> selectQwWorkTaskByExtIdAndQwUserId(QwUserVoiceLog qwUserVoiceLog);
+
+    List<UserVOs> getQwUserList(@Param("userId") Long userId, @Param("qwUserId") String qwUserId);
+
+    @Select({"<script> " +
+            "select t.qw_user_id,qw.qw_user_name,ANY_VALUE(cu.nick_name) companyUserName,DATE(t.create_time) createTime,\n" +
+            "\t\tSUM(CASE WHEN t.status = 0 THEN 1 ELSE 0 END) AS status0,\n" +
+            "    SUM(CASE WHEN t.status = 1 THEN 1 ELSE 0 END) AS status1,\n" +
+            "    SUM(CASE WHEN t.status = 2 THEN 1 ELSE 0 END) AS status2,\n" +
+            "    SUM(CASE WHEN t.status = 3 THEN 1 ELSE 0 END) AS status3\n" +
+            "\t\tfrom qw_work_task t  LEFT JOIN qw_user qw ON qw.id = t.qw_user_id LEFT JOIN company_user cu on cu.user_id=t.company_user_id  where  t.company_id=#{companyId} " +
+            "    <if test=\"companyUserId != null \"> and t.company_user_id = #{companyUserId}</if>\n" +
+            "    <if test=\"companyUserName != null and companyUserName != ''\"> and cu.nick_name = #{companyUserName}</if>\n" +
+            "    <if test=\"qwUserName != null and qwUserName != ''\"> and qw.qw_user_name = #{qwUserName}</if>\n" +
+            " " +
+            "    <if test=\"sTime != null \">  and DATE(t.create_time) &gt;= DATE(#{sTime})</if>\n" +
+            "    <if test=\"eTime != null \">  and DATE(t.create_time) &lt;= DATE(#{eTime})</if>\n" +
+            " " +
+            " GROUP BY t.qw_user_id,DATE(t.create_time) "+
+            "</script>"})
+    List<QwWorkTaskAllListVO> selectQwWorkTaskAllListVO(QwWorkTaskListParam qwWorkTask);
 }

+ 20 - 0
fs-service-system/src/main/java/com/fs/qw/param/QwWorkTaskListParam.java

@@ -1,8 +1,12 @@
 package com.fs.qw.param;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.Date;
+
 @Data
 public class QwWorkTaskListParam {
     private Long id;
@@ -41,6 +45,22 @@ public class QwWorkTaskListParam {
 
     private String title;
 
+    private String companyUserName;
+
+
+
+    private Long deptId;
+
+    private String qwUserName;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date eTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date sTime;
+
     private Long pageNum;
     private Long pageSize;
+
+
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/qw/service/IQwUserService.java

@@ -175,4 +175,6 @@ public interface IQwUserService
     R delQwIpad(QwLoginHookParam loginParam);
 
     R allocateRemoteHost(QwLoginHookParam loginParam);
+
+    List<UserVOs> getQwUserList(Long userId, String qwUserId);
 }

+ 3 - 0
fs-service-system/src/main/java/com/fs/qw/service/IQwWorkTaskService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.domain.QwWorkTask;
 import com.fs.qw.param.QwWorkTaskListParam;
+import com.fs.qw.vo.QwWorkTaskAllListVO;
 import com.fs.qw.vo.QwWorkTaskListVO;
 
 import java.util.List;
@@ -110,4 +111,6 @@ public interface IQwWorkTaskService extends IService<QwWorkTask>{
     List<QwWorkTask> selectQwWorkTaskListByMap(Map<String, Object> params);
 
     void addQwWorkByAiNotifyArtificial(QwUser user, Long extId, String content);
+
+    List<QwWorkTaskAllListVO> selectQwWorkTaskAllListVO(QwWorkTaskListParam qwWorkTask);
 }

+ 17 - 1
fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java

@@ -366,6 +366,8 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
         String type = "text";
         if (param.getMsgType() == 2) {
             type = "image";
+        } else if (param.getMsgType() == 3) {
+            type = "emotionDynamic";
         }
         listVO.setType(type);
         listVO.setStatus("succeed");
@@ -439,7 +441,17 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
                 qwContactListVOS.add(listVO);
                 break;
             }
-            listVO.setMsgId(qwMsgs.get(0).getMsgId());
+            QwMsg qwMsg = qwMsgs.get(0);
+            if (qwMsg.getMsgType() == 1) {
+                listVO.setType("text");
+            } else if (qwMsg.getMsgType() == 2) {
+                listVO.setType("image");
+            } else if (qwMsg.getMsgType() == 3) {
+                listVO.setType("emotionDynamic");
+            } else if (qwMsg.getMsgType() == 4) {
+                listVO.setType("voice");
+            }
+            listVO.setMsgId(qwMsg.getMsgId());
             listVO.setLastContent(qwMsgs.get(0).getContent());
             listVO.setLastSendTime(qwMsgs.get(0).getCreateTime().getTime());
             listVO.setUnread(0);
@@ -470,6 +482,10 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
             String type = "text";
             if (record.getMsgType() == 2) {
                 type = "image";
+            } else if (record.getMsgType() == 3) {
+                type = "emotionDynamic";
+            } else if (record.getMsgType() == 4) {
+                type = "voice";
             }
             listVO.setType(type);
             listVO.setStatus("succeed");

+ 6 - 4
fs-service-system/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java

@@ -45,10 +45,7 @@ import java.net.URL;
 import java.security.KeyFactory;
 import java.security.PrivateKey;
 import java.security.spec.PKCS8EncodedKeySpec;
-import java.util.Base64;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
@@ -1293,6 +1290,11 @@ public class QwUserServiceImpl implements IQwUserService
         return R.ok();
     }
 
+    @Override
+    public List<UserVOs> getQwUserList(Long userId, String qwUserId) {
+        return qwWorkTaskMapper.getQwUserList(userId, qwUserId);
+    }
+
     public R GetIPAdminAndPassWord(String ipAddress ) throws Exception {
 
         String bodyKey = HttpRequest.get("http://watch.ylrzcloud.com/prod-api/server/getKey?serverIp="+ipAddress)

+ 6 - 0
fs-service-system/src/main/java/com/fs/qw/service/impl/QwWorkTaskServiceImpl.java

@@ -18,6 +18,7 @@ import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwWorkTaskMapper;
 import com.fs.qw.param.QwWorkTaskListParam;
 import com.fs.qw.service.IQwWorkTaskService;
+import com.fs.qw.vo.QwWorkTaskAllListVO;
 import com.fs.qw.vo.QwWorkTaskListVO;
 import com.fs.sop.domain.QwSop;
 import com.fs.sop.domain.SopUserLogsInfo;
@@ -471,6 +472,11 @@ public class QwWorkTaskServiceImpl extends ServiceImpl<QwWorkTaskMapper, QwWorkT
         qwWorkTaskMapper.insertQwWorkTask(qwWorkTask);
     }
 
+    @Override
+    public List<QwWorkTaskAllListVO> selectQwWorkTaskAllListVO(QwWorkTaskListParam qwWorkTask) {
+        return qwWorkTaskMapper.selectQwWorkTaskAllListVO(qwWorkTask);
+    }
+
     /**
      * 根据SOP执行日志和特定条件,为符合要求的外部联系人添加企业微信工作任务。
      * <p>

+ 2 - 0
fs-service-system/src/main/java/com/fs/qw/vo/QwContactListVO.java

@@ -16,4 +16,6 @@ public class QwContactListVO {
     private String lastContent;
     // 消息ID
     private Long msgId;
+    // 消息类型
+    private String type;
 }

+ 22 - 0
fs-service-system/src/main/java/com/fs/qw/vo/QwWorkTaskAllListVO.java

@@ -0,0 +1,22 @@
+package com.fs.qw.vo;
+
+import lombok.Data;
+
+@Data
+public class QwWorkTaskAllListVO {
+    /** 外部联系人id */
+
+    private String qwUserName;
+
+    private String companyUserName;
+
+    private Integer status0;
+
+    private Integer status1;
+
+    private Integer status2;
+
+    private Integer status3;
+
+    private String createTime;
+}

+ 0 - 4
fs-service-system/src/main/java/com/fs/wx/mp/config/WxMpConfiguration.java

@@ -53,10 +53,6 @@ public class WxMpConfiguration {
         if (configs == null) {
             throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
         }
-        configs.forEach(e -> {
-            log.info("微信公众号APPID:{}", e.getAppId());
-        });
-
         WxMpService service = new WxMpServiceImpl();
         service.setMultiConfigStorages(configs
             .stream().map(a -> {

+ 31 - 0
fs-service-system/src/main/java/com/fs/wxwork/dto/WxDownloadFileDTO.java

@@ -0,0 +1,31 @@
+package com.fs.wxwork.dto;
+
+import lombok.Data;
+
+@Data
+public class WxDownloadFileDTO {
+    /**
+     * uuid
+     */
+    private String uuid;
+    /**
+     * 文件id
+     */
+    private String fileid;
+    /**
+     * aes_key
+     */
+    private String aes_key;
+    /**
+     * 下载文件类型1原图 2 中图 3缩略图 4视频 5文件语音
+     */
+    private Integer filetype;
+    /**
+     * 文件名
+     */
+    private String file_name;
+    /**
+     * 文件大小
+     */
+    private Integer size;
+}

+ 7 - 0
fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java

@@ -26,4 +26,11 @@ public class WxWorkMessageDTO {
     private Integer file_size;
     private String aes_key;
     private String openim_cdn_authkey;
+
+    // 动态表情
+    private String url;
+
+    // 语音
+    private String voice_id;
+    private Integer voice_size;
 }

+ 8 - 0
fs-service-system/src/main/java/com/fs/wxwork/service/WxWorkService.java

@@ -222,6 +222,14 @@ public interface WxWorkService {
      */
     WxWorkResponseDTO<String> downloadWeChatFile(WxwDownloadWeChatFileDTO param, Long serverId);
 
+    /**
+     * CDN下载文件重置版本
+     * @param param     参数
+     * @param serverId  服务器ID
+     * @return  WxWorkResponseDTO
+     */
+    WxWorkResponseDTO<String> downloadFile(WxDownloadFileDTO param, Long serverId);
+
     /**
      * CDN上传网络图片
      * @param param     参数

+ 12 - 0
fs-service-system/src/main/java/com/fs/wxwork/service/WxWorkServiceImpl.java

@@ -291,6 +291,18 @@ public class WxWorkServiceImpl implements WxWorkService {
         return WxWorkHttpUtil.postWithType(url, param, new TypeReference<WxWorkResponseDTO<String>>() {});
     }
 
+    /**
+     * CDN下载文件重置版本
+     * @param param     参数
+     * @param serverId  服务器ID
+     * @return  WxWorkResponseDTO
+     */
+    @Override
+    public WxWorkResponseDTO<String> downloadFile(WxDownloadFileDTO param, Long serverId) {
+        String url = getUrl(serverId) + "/DownloadFile";
+        return WxWorkHttpUtil.postWithType(url, param, new TypeReference<WxWorkResponseDTO<String>>() {});
+    }
+
     /**
      * CDN上传网络图片
      * @param param     参数

+ 11 - 11
fs-service-system/src/main/resources/application-config-dev.yml

@@ -71,18 +71,18 @@ wx:
         msgDataFormat: JSON
 
 ##  云联融智优选小程序,暂时使用
-#      - appid: wxd70f99287830cb51   #云联融智优选(暂时用于测试销售app)
-#        secret: 6e2684b3d48e6363018d4eedb8dae3e5
-#        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
-#        aesKey:
-#        msgDataFormat: JSON
-
-      - appid: wxb9b453d37c5fad45   #福本源小程序
-        secret: 45ee94e8c48edbafdcca2131a5e9d48d
+      - appid: wxd70f99287830cb51   #云联融智优选(暂时用于测试销售app)
+        secret: 6e2684b3d48e6363018d4eedb8dae3e5
         token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
         aesKey:
         msgDataFormat: JSON
 
+#      - appid: wxb9b453d37c5fad45   #福本源小程序
+#        secret: 45ee94e8c48edbafdcca2131a5e9d48d
+#        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+#        aesKey:
+#        msgDataFormat: JSON
+
   pay:
     appId: wx93ce67750e3cfba3 #微信公众号或者小程序等的appid
     mchId: 1703311381 #微信支付商户号
@@ -114,9 +114,9 @@ aifabu:  #爱链接
 tencent_cloud_config:
   secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
   secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
-  bucket: 1323137866
+  bucket: hylj-1323137866
   app_id: 1323137866
-  region: chongqing
-  proxy: hzyy
+  region: ap-chongqing
+  proxy: hylj
 cloud_host:
   company_name: 润天

+ 9 - 3
fs-service-system/src/main/resources/mapper/qw/QwWorkTaskMapper.xml

@@ -186,9 +186,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </delete>
 
     <select id="getUserList" resultType="com.fs.qw.vo.UserVOs">
-        select b.name,b.avatar,a.title,a.score,a.create_time,a.type from
-        qw_work_task a
-        inner join qw_external_contact b on a.ext_id = b.id
+        select b.nickname as name,b.avatar,a.title,a.score,a.create_time,a.type from
+            hy_work_task a
+                inner join fs_user b on a.user_id = b.user_id
         where a.company_user_id = #{userId}
     </select>
 
@@ -199,4 +199,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="qwUserId != null">and qw_user_id = #{qwUserId}</if>
         <if test="createTime != null">and date_format(create_time,'%Y-%m-%d') = date_format(#{createTime},'%Y-%m-%d')</if>
     </select>
+    <select id="getQwUserList" resultType="com.fs.qw.vo.UserVOs">
+        select b.name, b.avatar, a.title, a.score, a.create_time, a.type
+        from qw_work_task a
+                 inner join qw_external_contact b on a.ext_id = b.id
+        where a.company_user_id = #{userId}
+    </select>
 </mapper>

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

@@ -68,7 +68,7 @@ public class WxUserController extends AppBaseController{
             return R.error("code不存在");
         }
 
-        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(0).getAppid());
+        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(1).getAppid());
         try {
             // 获取微信会话信息
             WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());