Преглед на файлове

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

caoliqin преди 2 седмици
родител
ревизия
e43d06f760
променени са 51 файла, в които са добавени 380 реда и са изтрити 92 реда
  1. 4 1
      fs-qw-api-msg/pom.xml
  2. 16 3
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  3. 101 0
      fs-qw-api-msg/src/main/java/com/fs/app/socket/QwImSocket.java
  4. 22 0
      fs-qw-api-msg/src/main/java/com/fs/app/socket/configurator/QwImConfigurator.java
  5. 3 3
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataScopeAspect.java
  6. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataSourceAspect.java
  7. 5 5
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/LogAspect.java
  8. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/RateLimiterAspect.java
  9. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ApplicationConfig.java
  10. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ArrayStringTypeHandler.java
  11. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/CaptchaConfig.java
  12. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/config/DataSourceConfig.java
  13. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/FastJson2JsonRedisSerializer.java
  14. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/FilterConfig.java
  15. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/KaptchaTextCreator.java
  16. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/MyBatisConfig.java
  17. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/RedisConfig.java
  18. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/config/ResourcesConfig.java
  19. 6 5
      fs-qw-api-msg/src/main/java/com/fs/core/config/SecurityConfig.java
  20. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ServerConfig.java
  21. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/SwaggerConfig.java
  22. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ThreadPoolConfig.java
  23. 17 0
      fs-qw-api-msg/src/main/java/com/fs/core/config/WebSocketConfig.java
  24. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/properties/DruidProperties.java
  25. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSource.java
  26. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSourceContextHolder.java
  27. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/exception/GlobalExceptionHandler.java
  28. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/interceptor/RepeatSubmitInterceptor.java
  29. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/interceptor/impl/SameUrlDataInterceptor.java
  30. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/manager/AsyncManager.java
  31. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/manager/ShutdownManager.java
  32. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/manager/factory/AsyncFactory.java
  33. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/LoginBody.java
  34. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/LoginUser.java
  35. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/SecurityUtils.java
  36. 4 4
      fs-qw-api-msg/src/main/java/com/fs/core/security/filter/JwtAuthenticationTokenFilter.java
  37. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/handle/AuthenticationEntryPointImpl.java
  38. 5 5
      fs-qw-api-msg/src/main/java/com/fs/core/security/handle/LogoutSuccessHandlerImpl.java
  39. 4 4
      fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyLoginService.java
  40. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyPermissionService.java
  41. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/service/PermissionService.java
  42. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/service/TokenService.java
  43. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/service/UserDetailsServiceImpl.java
  44. 1 1
      fs-qw-api-msg/src/main/resources/mybatis/mybatis-config.xml
  45. 9 6
      fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java
  46. 35 8
      fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  47. 95 7
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java
  48. 1 1
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java
  49. 3 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwMessageListVO.java
  50. 6 0
      fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java
  51. 4 0
      fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkUserId2VidDTO.java

+ 4 - 1
fs-qw-api-msg/pom.xml

@@ -117,7 +117,10 @@
             <artifactId>vosk</artifactId>
             <version>0.3.32</version>
         </dependency>
-
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 16 - 3
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -1,11 +1,13 @@
 package com.fs.app.controller;
 
 import com.alibaba.fastjson.JSON;
+import com.fs.app.socket.QwImSocket;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.fastGpt.service.AiHookService;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwUserVoiceLogService;
+import com.fs.qw.vo.QwMessageListVO;
 import com.fs.wxwork.dto.*;
 import com.fs.wxwork.service.WxWorkService;
 import io.swagger.annotations.Api;
@@ -132,7 +134,7 @@ public class QwMsgController {
                 qwUserStatus(wxWorkMsgResp.getUuid(),0);
                 break;
             case 102000:
-
+                System.out.println(wxWorkMsgResp.getJson());
                 WxWorkMessageDTO wxWorkMessageDTO = JSON.parseObject(wxWorkMsgResp.getJson(), WxWorkMessageDTO.class);
                 if (wxWorkMessageDTO.getIs_room()!=0){
                     break;
@@ -163,13 +165,15 @@ public class QwMsgController {
                         aiHookService.qwHookNotifyAiReply(id,sender,content,wxWorkMsgResp.getUuid(),wxWorkMessageDTO.getMsgtype());
 
                         // 保存聊天消息
-                        aiHookService.saveQwMsg(id, sender, content, wxWorkMsgResp.getUuid(), 1);
+                        QwMessageListVO message = aiHookService.saveQwMsg(id, sender, content, wxWorkMsgResp.getUuid(), 1, wxWorkMsgResp.getJson());
+                        QwImSocket.broadcast(message);
                     }else {
                         System.out.println("销售发送");
                         aiHookService.qwHookNotifyAddMsg(id,receiver,content,wxWorkMsgResp.getUuid());
 
                         // 保存聊天消息
-                        aiHookService.saveQwMsg(id, receiver, content, wxWorkMsgResp.getUuid(), 2);
+                        QwMessageListVO message = aiHookService.saveQwMsg(id, receiver, content, wxWorkMsgResp.getUuid(), 2, wxWorkMsgResp.getJson());
+                        QwImSocket.broadcast(message);
                     }
 
                 }
@@ -210,6 +214,15 @@ public class QwMsgController {
 
                     qwUserVoiceLogService.addQuUserVoiceByIpadCallback(id,extId,recordType,totalSeconds,wxWorkMsgResp.getUuid());
                 }
+                // 图片消息
+                else if (wxWorkMessageDTO.getMsgtype() == 101){
+                    Long receiver = wxWorkMessageDTO.getReceiver();
+                    if (2000000000000000L - receiver > 0){
+                        System.out.println("客户发起");
+                    }else {
+                        System.out.println("销售发起");
+                    }
+                }
 
                 break;
 

+ 101 - 0
fs-qw-api-msg/src/main/java/com/fs/app/socket/QwImSocket.java

@@ -0,0 +1,101 @@
+package com.fs.app.socket;
+
+import com.alibaba.fastjson.JSON;
+import com.fs.app.socket.configurator.QwImConfigurator;
+import com.fs.qw.vo.QwMessageListVO;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+@ServerEndpoint(value = "/qwImSocket/{companyId}", configurator = QwImConfigurator.class)
+@Component
+public class QwImSocket {
+
+    private static final ConcurrentHashMap<Long, CopyOnWriteArraySet<Session>> companySessions = new ConcurrentHashMap<>();
+
+    /**
+     * 连接建立成功调用的方法
+     * @param session   连接会话
+     * @param companyId 公司ID
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("companyId") Long companyId) {
+        // 将当前会话加入到会话池中
+        companySessions.computeIfAbsent(companyId, k -> new CopyOnWriteArraySet<>()).add(session);
+    }
+
+    /**
+     * 连接关闭调用的方法
+     * @param session   连接会话
+     * @param companyId 公司ID
+     */
+    @OnClose
+    public void onClose(Session session, @PathParam("companyId") Long companyId) {
+        // 从会话池中移除当前会话
+        CopyOnWriteArraySet<Session> sessions = companySessions.get(companyId);
+        if (sessions != null) {
+            sessions.remove(session);
+            // 如果直播间没人了,可以移除该直播间
+            if (sessions.isEmpty()) {
+                companySessions.remove(companyId);
+            }
+        }
+    }
+
+    /**
+     * 发生错误时调用的方法
+     * @param session   连接会话
+     * @param companyId 公司ID
+     * @param error     错误对象
+     */
+    @OnError
+    public void onError(Session session, @PathParam("companyId") Long companyId, Throwable error) {
+        System.err.println("发生错误!会话ID: " + session.getId());
+        CopyOnWriteArraySet<Session> sessions = companySessions.get(companyId);
+        if (sessions != null) {
+            sessions.remove(session);
+            // 如果直播间没人了,可以移除该直播间
+            if (sessions.isEmpty()) {
+                companySessions.remove(companyId);
+            }
+        }
+    }
+
+    /**
+     * 群发消息
+     * @param message   要发送的消息
+     */
+    public static void broadcast(QwMessageListVO message) {
+        if (Objects.isNull(message)) {
+            return;
+        }
+
+        String msg = JSON.toJSONString(message);
+        CopyOnWriteArraySet<Session> sessions = companySessions.get(message.getCompanyId());
+        if (sessions != null) {
+            for (Session session : sessions) {
+                if (session.isOpen()) {
+                    try {
+                        session.getBasicRemote().sendText(msg);
+                    } catch (IOException e) {
+                        System.err.println("发送消息给会话[" + session.getId() + "]失败: " + e.getMessage());
+                        // 移除无效会话
+                        sessions.remove(session);
+                    }
+                } else {
+                    sessions.remove(session); // 移除已关闭的会话
+                }
+            }
+        }
+    }
+
+}

+ 22 - 0
fs-qw-api-msg/src/main/java/com/fs/app/socket/configurator/QwImConfigurator.java

@@ -0,0 +1,22 @@
+package com.fs.app.socket.configurator;
+
+import com.fs.app.exception.FSException;
+
+import javax.websocket.HandshakeResponse;
+import javax.websocket.server.HandshakeRequest;
+import javax.websocket.server.ServerEndpointConfig;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class QwImConfigurator extends ServerEndpointConfig.Configurator {
+
+    @Override
+    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
+        Map<String, List<String>> parameterMap = request.getParameterMap();
+        List<String> token = parameterMap.get("token");
+        if (Objects.isNull(token)) {
+            throw new FSException("Unauthorized access to WebSocket endpoint.");
+        }
+    }
+}

+ 3 - 3
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/DataScopeAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataScopeAspect.java

@@ -1,4 +1,4 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.fs.common.annotation.DataScope;
 import com.fs.common.core.domain.BaseEntity;
@@ -7,8 +7,8 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.CompanyRole;
 import com.fs.company.domain.CompanyUser;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
+import com.fs.core.security.LoginUser;
+import com.fs.core.service.TokenService;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.Signature;
 import org.aspectj.lang.annotation.Aspect;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/DataSourceAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataSourceAspect.java

@@ -1,8 +1,8 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.fs.common.annotation.DataSource;
 import com.fs.common.utils.StringUtils;
-import com.fs.framework.datasource.DynamicDataSourceContextHolder;
+import com.fs.core.datasource.DynamicDataSourceContextHolder;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;

+ 5 - 5
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/LogAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/LogAspect.java

@@ -1,4 +1,4 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
@@ -9,10 +9,10 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.CompanyOperLog;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
+import com.fs.core.manager.AsyncManager;
+import com.fs.core.manager.factory.AsyncFactory;
+import com.fs.core.security.LoginUser;
+import com.fs.core.service.TokenService;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.Signature;
 import org.aspectj.lang.annotation.AfterReturning;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/RateLimiterAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/RateLimiterAspect.java

@@ -1,4 +1,4 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.fs.common.annotation.RateLimiter;
 import com.fs.common.enums.LimitType;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ApplicationConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ApplicationConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ArrayStringTypeHandler.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ArrayStringTypeHandler.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import org.apache.ibatis.type.BaseTypeHandler;
 import org.apache.ibatis.type.JdbcType;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/CaptchaConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/CaptchaConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.google.code.kaptcha.impl.DefaultKaptcha;
 import com.google.code.kaptcha.util.Config;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/config/DataSourceConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/DataSourceConfig.java

@@ -1,10 +1,10 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
 import com.alibaba.druid.util.Utils;
 import com.fs.common.enums.DataSourceType;
-import com.fs.framework.datasource.DynamicDataSource;
+import com.fs.core.datasource.DynamicDataSource;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.ConfigurationProperties;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/FastJson2JsonRedisSerializer.java → fs-qw-api-msg/src/main/java/com/fs/core/config/FastJson2JsonRedisSerializer.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.parser.ParserConfig;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/FilterConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/FilterConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.filter.RepeatableFilter;
 import com.fs.common.filter.XssFilter;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/KaptchaTextCreator.java → fs-qw-api-msg/src/main/java/com/fs/core/config/KaptchaTextCreator.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.google.code.kaptcha.text.impl.DefaultTextCreator;
 

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/MyBatisConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/MyBatisConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import org.apache.ibatis.io.VFS;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/RedisConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/RedisConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/config/ResourcesConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ResourcesConfig.java

@@ -1,8 +1,8 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.config.FSConfig;
 import com.fs.common.constant.Constants;
-import com.fs.framework.interceptor.RepeatSubmitInterceptor;
+import com.fs.core.interceptor.RepeatSubmitInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;

+ 6 - 5
fs-qw-api-msg/src/main/java/com/fs/framework/config/SecurityConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/SecurityConfig.java

@@ -1,9 +1,9 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 
-import com.fs.framework.security.filter.JwtAuthenticationTokenFilter;
-import com.fs.framework.security.handle.AuthenticationEntryPointImpl;
-import com.fs.framework.security.handle.LogoutSuccessHandlerImpl;
+import com.fs.core.security.filter.JwtAuthenticationTokenFilter;
+import com.fs.core.security.handle.AuthenticationEntryPointImpl;
+import com.fs.core.security.handle.LogoutSuccessHandlerImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.http.HttpMethod;
@@ -106,7 +106,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                         "/**/*.html",
                         "/**/*.css",
                         "/**/*.js",
-                        "/profile/**"
+                        "/profile/**",
+                        "/qwImSocket/**"
                 ).permitAll()
 
                 .antMatchers("/**").anonymous()

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ServerConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ServerConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.utils.ServletUtils;
 import org.springframework.stereotype.Component;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/SwaggerConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/SwaggerConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.config.FSConfig;
 import io.swagger.annotations.ApiOperation;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ThreadPoolConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ThreadPoolConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.utils.Threads;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;

+ 17 - 0
fs-qw-api-msg/src/main/java/com/fs/core/config/WebSocketConfig.java

@@ -0,0 +1,17 @@
+package com.fs.core.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+    /**
+     * ServerEndpointExporter 作用
+     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
+     */
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+}

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/properties/DruidProperties.java → fs-qw-api-msg/src/main/java/com/fs/core/config/properties/DruidProperties.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config.properties;
+package com.fs.core.config.properties;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import org.springframework.beans.factory.annotation.Value;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/datasource/DynamicDataSource.java → fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSource.java

@@ -1,4 +1,4 @@
-package com.fs.framework.datasource;
+package com.fs.core.datasource;
 
 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/datasource/DynamicDataSourceContextHolder.java → fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSourceContextHolder.java

@@ -1,4 +1,4 @@
-package com.fs.framework.datasource;
+package com.fs.core.datasource;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/exception/GlobalExceptionHandler.java → fs-qw-api-msg/src/main/java/com/fs/core/exception/GlobalExceptionHandler.java

@@ -1,4 +1,4 @@
-package com.fs.framework.exception;
+package com.fs.core.exception;
 
 import com.fs.common.constant.HttpStatus;
 import com.fs.common.core.domain.AjaxResult;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/interceptor/RepeatSubmitInterceptor.java → fs-qw-api-msg/src/main/java/com/fs/core/interceptor/RepeatSubmitInterceptor.java

@@ -1,4 +1,4 @@
-package com.fs.framework.interceptor;
+package com.fs.core.interceptor;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.annotation.RepeatSubmit;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/interceptor/impl/SameUrlDataInterceptor.java → fs-qw-api-msg/src/main/java/com/fs/core/interceptor/impl/SameUrlDataInterceptor.java

@@ -1,4 +1,4 @@
-package com.fs.framework.interceptor.impl;
+package com.fs.core.interceptor.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.constant.Constants;
@@ -6,7 +6,7 @@ import com.fs.common.core.redis.RedisCache;
 import com.fs.common.filter.RepeatedlyRequestWrapper;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.http.HttpHelper;
-import com.fs.framework.interceptor.RepeatSubmitInterceptor;
+import com.fs.core.interceptor.RepeatSubmitInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/manager/AsyncManager.java → fs-qw-api-msg/src/main/java/com/fs/core/manager/AsyncManager.java

@@ -1,4 +1,4 @@
-package com.fs.framework.manager;
+package com.fs.core.manager;
 
 import com.fs.common.utils.Threads;
 import com.fs.common.utils.spring.SpringUtils;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/manager/ShutdownManager.java → fs-qw-api-msg/src/main/java/com/fs/core/manager/ShutdownManager.java

@@ -1,4 +1,4 @@
-package com.fs.framework.manager;
+package com.fs.core.manager;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/manager/factory/AsyncFactory.java → fs-qw-api-msg/src/main/java/com/fs/core/manager/factory/AsyncFactory.java

@@ -1,4 +1,4 @@
-package com.fs.framework.manager.factory;
+package com.fs.core.manager.factory;
 
 import com.fs.common.constant.Constants;
 import com.fs.common.utils.LogUtils;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/LoginBody.java → fs-qw-api-msg/src/main/java/com/fs/core/security/LoginBody.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security;
+package com.fs.core.security;
 
 /**
  * 用户登录对象

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/LoginUser.java → fs-qw-api-msg/src/main/java/com/fs/core/security/LoginUser.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security;
+package com.fs.core.security;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fs.company.domain.Company;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/SecurityUtils.java → fs-qw-api-msg/src/main/java/com/fs/core/security/SecurityUtils.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security;
+package com.fs.core.security;
 
 import com.fs.common.constant.HttpStatus;
 import com.fs.common.exception.CustomException;

+ 4 - 4
fs-qw-api-msg/src/main/java/com/fs/framework/security/filter/JwtAuthenticationTokenFilter.java → fs-qw-api-msg/src/main/java/com/fs/core/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,10 +1,10 @@
-package com.fs.framework.security.filter;
+package com.fs.core.security.filter;
 
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.StringUtils;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.security.SecurityUtils;
-import com.fs.framework.service.TokenService;
+import com.fs.core.security.LoginUser;
+import com.fs.core.security.SecurityUtils;
+import com.fs.core.service.TokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContextHolder;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/handle/AuthenticationEntryPointImpl.java → fs-qw-api-msg/src/main/java/com/fs/core/security/handle/AuthenticationEntryPointImpl.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security.handle;
+package com.fs.core.security.handle;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.common.constant.HttpStatus;

+ 5 - 5
fs-qw-api-msg/src/main/java/com/fs/framework/security/handle/LogoutSuccessHandlerImpl.java → fs-qw-api-msg/src/main/java/com/fs/core/security/handle/LogoutSuccessHandlerImpl.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security.handle;
+package com.fs.core.security.handle;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.common.constant.Constants;
@@ -6,10 +6,10 @@ import com.fs.common.constant.HttpStatus;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
+import com.fs.core.manager.AsyncManager;
+import com.fs.core.manager.factory.AsyncFactory;
+import com.fs.core.security.LoginUser;
+import com.fs.core.service.TokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.core.Authentication;

+ 4 - 4
fs-qw-api-msg/src/main/java/com/fs/framework/service/CompanyLoginService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyLoginService.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCache;
@@ -7,9 +7,9 @@ import com.fs.common.exception.user.CaptchaException;
 import com.fs.common.exception.user.CaptchaExpireException;
 import com.fs.common.exception.user.UserPasswordNotMatchException;
 import com.fs.common.utils.MessageUtils;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.manager.AsyncManager;
+import com.fs.core.manager.factory.AsyncFactory;
+import com.fs.core.security.LoginUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/service/CompanyPermissionService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyPermissionService.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyMenuService;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/service/PermissionService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/PermissionService.java

@@ -1,9 +1,9 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyRole;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.security.LoginUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/service/TokenService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/TokenService.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCache;
@@ -7,7 +7,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.AddressUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.uuid.IdUtils;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.security.LoginUser;
 import eu.bitwalker.useragentutils.UserAgent;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/service/UserDetailsServiceImpl.java → fs-qw-api-msg/src/main/java/com/fs/core/service/UserDetailsServiceImpl.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 
 import com.fs.common.enums.UserStatus;
@@ -8,7 +8,7 @@ import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.security.LoginUser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 1
fs-qw-api-msg/src/main/resources/mybatis/mybatis-config.xml

@@ -13,7 +13,7 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 	</settings>
 
 	<typeHandlers>
-		<typeHandler handler="com.fs.framework.config.ArrayStringTypeHandler"/>
+		<typeHandler handler="com.fs.core.config.ArrayStringTypeHandler"/>
 	</typeHandlers>
 
 </configuration>

+ 9 - 6
fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java

@@ -1,6 +1,7 @@
 package com.fs.fastGpt.service;
 
 import com.fs.common.core.domain.R;
+import com.fs.qw.vo.QwMessageListVO;
 import com.fs.qwHookApi.vo.QwHookVO;
 
 public interface AiHookService {
@@ -19,11 +20,13 @@ public interface AiHookService {
 
     /**
      * 保存企微聊天信息
-     * @param qwUserId  企微用户ID
-     * @param userId    用户ID
-     * @param content   聊天内容
-     * @param uuid      UUID
-     * @param sendType  发送者类型 1用户 2客服
+     *
+     * @param qwUserId 企微用户ID
+     * @param userId   用户ID
+     * @param content  聊天内容
+     * @param uuid     UUID
+     * @param sendType 发送者类型 1用户 2客服
+     * @param json     消息json
      */
-    void saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType);
+    QwMessageListVO saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType, String json);
 }

+ 35 - 8
fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -28,6 +28,7 @@ import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.qw.domain.*;
 import com.fs.qw.mapper.*;
 import com.fs.qw.service.*;
+import com.fs.qw.vo.QwMessageListVO;
 import com.fs.qwApi.param.QwSendMsgParam;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.qwHookApi.param.QwHookSendMsgParam;
@@ -1261,27 +1262,29 @@ public class AiHookServiceImpl implements AiHookService {
 
     /**
      * 保存企微聊天信息
-     * @param qwUserId  企微用户ID
-     * @param userId    用户ID
-     * @param content   聊天内容
-     * @param uuid      UUID
-     * @param sendType  发送者类型 1用户 2客服
+     *
+     * @param qwUserId 企微用户ID
+     * @param userId   用户ID
+     * @param content  聊天内容
+     * @param uuid     UUID
+     * @param sendType 发送者类型 1用户 2客服
+     * @param json     消息json
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType) {
+    public QwMessageListVO saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType, String json) {
         // 查询企微用户
         QwUser qwUser = qwUserService.selectQwUserById(qwUserId);
         if (Objects.isNull(qwUser)){
             log.warn("企微用户不存在 qwUserId: {}", qwUserId);
-            return;
+            return null;
         }
 
         // 查询外部联系人
         QwExternalContact qwExternalContact = getExternalContact(userId, uuid, qwUser.getServerId(), qwUser.getCorpId(), qwUser.getQwUserId());
         if (Objects.isNull(qwExternalContact)){
             log.warn("外部联系人不存在 userId: {}, uuid: {}, serverId: {}, corpId: {}, qwUserId: {}", userId, uuid, qwUser.getServerId(), qwUser.getCorpId(), qwUser.getQwUserId());
-            return;
+            return null;
         }
 
         // 查询会话
@@ -1316,6 +1319,7 @@ public class AiHookServiceImpl implements AiHookService {
         qwMsg.setCompanyId(qwUser.getCompanyId());
         qwMsg.setCompanyUserId(qwUser.getCompanyUserId());
         qwMsg.setMsgType(1);
+        qwMsg.setMsgJson(json);
         qwMsg.setStatus(0);
         qwMsg.setQwUserId(qwSession.getQwUserId());
         qwMsg.setQwExtId(qwSession.getQwExtId());
@@ -1324,6 +1328,29 @@ public class AiHookServiceImpl implements AiHookService {
         qwMsg.setCreateTime(new Date());
         qwMsgMapper.insertQwMsg(qwMsg);
         log.debug("保存企微聊天记录 msgId: {}", qwMsg.getMsgId());
+
+        // 组装返回消息结构
+        QwMessageListVO listVO = new QwMessageListVO();
+        QWFromUser qwFromUser = new QWFromUser();
+        if (sendType == 1) {
+            qwFromUser.setId(Long.parseLong(qwMsg.getQwExtId()));
+            qwFromUser.setAvatar(qwMsg.getAvatar());
+            qwFromUser.setDisplayName(qwMsg.getNickName());
+        }else if(sendType == 2){
+            qwFromUser.setId(Long.parseLong(qwMsg.getQwUserId()));
+            qwFromUser.setDisplayName(qwUser.getQwUserName());
+            qwFromUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20241231/22a765a96da247d1b83ea94fef438a41.png");
+        }
+
+        listVO.setCompanyId(qwUser.getCompanyId());
+        listVO.setType("text");
+        listVO.setStatus("succeed");
+        listVO.setFromUser(qwFromUser);
+        listVO.setSendTime(qwMsg.getCreateTime().getTime());
+        listVO.setId(qwMsg.getMsgId().toString());
+        listVO.setContent(qwMsg.getContent());
+        listVO.setToContactId(String.valueOf(qwSession.getSessionId()));
+        return listVO;
     }
 
     /**

+ 95 - 7
fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java

@@ -2,12 +2,12 @@ package com.fs.qw.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.http.HttpRequest;
-import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.qw.Bean.MsgBean;
@@ -23,6 +23,8 @@ import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.QwContactListVO;
 import com.fs.qw.vo.QwMessageListVO;
 import com.fs.qwHookApi.vo.QwHookMsgVO;
+import com.fs.wxwork.dto.*;
+import com.fs.wxwork.service.WxWorkService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -50,6 +52,8 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
 
     @Autowired
     private ConfigUtil configUtil;
+    @Autowired
+    private WxWorkService wxWorkService;
 
     /**
      * 查询企微聊天记录
@@ -244,12 +248,96 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
 
     @Override
     public R sendMsg(QwMsgSendParam param) {
-        FsSysConfig config = configUtil.getSysConfig();
-        String domainName = config.getHookUrl();
-        HttpRequest.post(domainName+"/app/qwmsg/sendMsg")
-                .body(JSON.toJSONString(param),"application/json;charset=UTF-8")
-                .execute().body();
-        return R.ok();
+        if (StringUtils.isBlank(param.getContent())) {
+            return R.error("消息内容不能为空");
+        }
+
+        if (Objects.isNull(param.getSessionId())) {
+            return R.error("会话ID不能为空");
+        }
+
+        // 查询会话
+        QwSession qwSession = qwSessionMapper.selectQwSessionBySessionId(param.getSessionId());
+        if (Objects.isNull(qwSession)) {
+            return R.error("会话不存在");
+        }
+
+        // 外部联系人
+        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(Long.valueOf(qwSession.getQwExtId()));
+        if (Objects.isNull(qwExternalContact)) {
+            return R.error("联系人不存在");
+        }
+
+        // 企微用户
+        QwUser qwUser = qwUserMapper.selectQwUserById(Long.parseLong(qwSession.getQwUserId()));
+        if (Objects.isNull(qwUser)) {
+            return R.error("用户不存在");
+        }
+
+        Long serverId = qwUser.getServerId();
+        String uuid = qwUser.getUid();
+        String openId = qwExternalContact.getExternalUserId();
+        String sCorpId = qwUser.getCorpId();
+
+        WxWorkUserId2VidDTO params = new WxWorkUserId2VidDTO();
+        params.setOpenid(Collections.singletonList(openId));
+        params.setUuid(uuid);
+        params.setScorpid(sCorpId);
+        WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> listWxWorkResponseDTO = wxWorkService.UserId2Vid(params, serverId);
+
+        if (listWxWorkResponseDTO.getErrcode() != 0) {
+            return R.error(listWxWorkResponseDTO.getErrmsg());
+        }
+
+        // 发送消息
+        WxWorkSendTextMsgDTO textMsgDTO = new WxWorkSendTextMsgDTO();
+        textMsgDTO.setUuid(uuid);
+        textMsgDTO.setSend_userid(listWxWorkResponseDTO.getData().get(0).getUser_id());
+        textMsgDTO.setIsRoom(false);
+        textMsgDTO.setContent(param.getContent());
+        WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> msgRespDTOWxWorkResponseDTO = wxWorkService.SendTextMsg(textMsgDTO, serverId);
+
+        if (msgRespDTOWxWorkResponseDTO.getErrcode() != 0) {
+            return R.error(msgRespDTOWxWorkResponseDTO.getErrmsg());
+        }
+
+        String msg = msgRespDTOWxWorkResponseDTO.getErrmsg();
+        if ("ok".equals(msg)) {
+            // 消息保存本地数据库
+            QwMsg qwMsg = new QwMsg();
+            qwMsg.setContent(param.getContent());
+            qwMsg.setSessionId(qwSession.getSessionId());
+            qwMsg.setSendType(2);
+            qwMsg.setCompanyId(qwUser.getCompanyId());
+            qwMsg.setCompanyUserId(qwUser.getCompanyUserId());
+            qwMsg.setMsgType(1);
+            qwMsg.setMsgJson(JSONObject.toJSONString(textMsgDTO));
+            qwMsg.setStatus(0);
+            qwMsg.setQwUserId(qwSession.getQwUserId());
+            qwMsg.setQwExtId(qwSession.getQwExtId());
+            qwMsg.setAvatar(qwExternalContact.getAvatar());
+            qwMsg.setNickName(qwExternalContact.getRemark());
+            qwMsg.setCreateTime(new Date());
+            qwMsgMapper.insertQwMsg(qwMsg);
+
+            // 组装返回消息结构
+            QwMessageListVO listVO = new QwMessageListVO();
+            QWFromUser qwFromUser = new QWFromUser();
+            qwFromUser.setId(Long.parseLong(qwMsg.getQwUserId()));
+            qwFromUser.setDisplayName(qwUser.getQwUserName());
+            qwFromUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20241231/22a765a96da247d1b83ea94fef438a41.png");
+
+            listVO.setType("text");
+            listVO.setStatus("succeed");
+            listVO.setFromUser(qwFromUser);
+            listVO.setSendTime(qwMsg.getCreateTime().getTime());
+            listVO.setId(qwMsg.getMsgId().toString());
+            listVO.setContent(qwMsg.getContent());
+            listVO.setToContactId(String.valueOf(param.getSessionId()));
+            return R.ok().put("data", listVO);
+        } else {
+            return R.error(msg);
+        }
     }
 
     @Override

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

@@ -1008,7 +1008,7 @@ public class QwUserServiceImpl implements IQwUserService
             return R.ok("登录成功");
         }
         WxWorkSetCallbackUrlDTO wxWorkSetCallbackUrlDTO = new WxWorkSetCallbackUrlDTO();
-        wxWorkSetCallbackUrlDTO.setUrl("http://c38da856.natappfree.cc/msg/callback/"+serverId);
+        wxWorkSetCallbackUrlDTO.setUrl("http://1.14.207.209:8008/msg/callback/"+serverId);
         wxWorkSetCallbackUrlDTO.setUuid(data.getUuid());
         wxWorkService.SetCallbackUrl(wxWorkSetCallbackUrlDTO,serverId);
 

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

@@ -1,5 +1,6 @@
 package com.fs.qw.vo;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.fs.qw.domain.QWFromUser;
 import com.fs.qw.domain.QwMsg;
 import lombok.Data;
@@ -19,6 +20,8 @@ public class QwMessageListVO {
     private Integer duration; //时长
     private String toContactId;
     private QWFromUser fromUser;
+    @JSONField(serialize = false)
+    private Long companyId;
 
     //获取fromUser
     public  QWFromUser getQwFromUser(Long senderId,QwMsg qwMsg){

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

@@ -20,4 +20,10 @@ public class WxWorkMessageDTO {
     private Integer msgtype;         // 对应 "msgtype": 2 (消息类型 0 和 2文本消息)
     private String recordwording;    //通话时长
     private Integer recordtype;         //通话5
+
+    // 图片
+    private String file_id;
+    private Integer file_size;
+    private String aes_key;
+    private String openim_cdn_authkey;
 }

+ 4 - 0
fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkUserId2VidDTO.java

@@ -6,8 +6,12 @@ import java.util.List;
 
 @Data
 public class WxWorkUserId2VidDTO {
+    // qw_user uid
     private String uuid;
+    // qw_user corp_id
     private String scorpid;
+    //
     private String corpid;
+    // qw_external_contact external_user_id
     private List<String> openid;
 }