Browse Source

feat:websocket相关接口及上游服务补充

zhangwei 1 week ago
parent
commit
66820b2223
41 changed files with 1025 additions and 60 deletions
  1. 8 0
      edu-travel-adapter/edu-travel-adapter-commodity/pom.xml
  2. 30 0
      edu-travel-adapter/edu-travel-adapter-commodity/src/main/java/edu/travel/adapter/service/commodity/ShopMessageAdapter.java
  3. 25 0
      edu-travel-adapter/edu-travel-adapter-commodity/src/main/java/edu/travel/adapter/service/commodity/ShopUserSessionAdapter.java
  4. 19 0
      edu-travel-adapter/edu-travel-adapter-tenant/src/main/java/edu/travel/adapter/service/tenant/SysUserRoleAdapter.java
  5. 2 2
      edu-travel-adapter/edu-travel-adapter-tenant/src/main/java/edu/travel/adapter/service/tenant/TenantAdapter.java
  6. 83 7
      edu-travel-api/edu-travel-api-web/pom.xml
  7. 44 0
      edu-travel-api/edu-travel-api-web/src/main/java/edu/travel/controller/ShopUserSessionController.java
  8. 24 0
      edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/commodity/ShopMessageRemoteController.java
  9. 17 0
      edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/commodity/ShopUserSessionRemoteController.java
  10. 14 0
      edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/dto/MessageDto.java
  11. 34 0
      edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/dto/SaveMessageDto.java
  12. 38 0
      edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/vo/MessageVo.java
  13. 21 0
      edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/vo/ShopUserSessionVo.java
  14. 14 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/SysUserRoleRemoteController.java
  15. 1 1
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/TenantRemoteController.java
  16. 64 0
      edu-travel-remote/edu-travel-remote-websocket/pom.xml
  17. 35 0
      edu-travel-remote/edu-travel-remote-websocket/src/main/java/edu/travel/remote/dto/MessageDto.java
  18. 16 0
      edu-travel-remote/edu-travel-remote-websocket/src/main/java/edu/travel/remote/vo/MessageVo.java
  19. 8 0
      edu-travel-remote/edu-travel-remote-websocket/src/main/java/edu/travel/remote/websocket/WebSocketRemoteController.java
  20. 1 0
      edu-travel-remote/pom.xml
  21. 8 0
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/entity/ShopMessage.java
  22. 8 0
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/ShopMessageService.java
  23. 72 0
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopMessageServiceImpl.java
  24. 7 5
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopProductServiceImpl.java
  25. 1 2
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopReviewServiceImpl.java
  26. 0 1
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/utils/IdUtils.java
  27. 0 19
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/utils/ObjectUtils.java
  28. 30 5
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/web/ShopMessageController.java
  29. 80 4
      edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/web/ShopUserSessionController.java
  30. 2 1
      edu-travel-service/edu-travel-service-commodity/src/main/resources/mapper/ShopMessageMapper.xml
  31. 30 1
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysUserRoleController.java
  32. 7 2
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/TenantController.java
  33. 10 0
      edu-travel-service/edu-travel-service-ws/pom.xml
  34. 2 2
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/WsApplication.java
  35. 1 1
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/config/WebSocketAutoConfig.java
  36. 26 0
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/enums/MessageEnum.java
  37. 45 0
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/factoryandstragy/MessageFactory.java
  38. 116 5
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/handle/TravelMessageHandler.java
  39. 16 0
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/service/MessageService.java
  40. 64 0
      edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/service/impl/ShopMessageService.java
  41. 2 2
      pom.xml

+ 8 - 0
edu-travel-adapter/edu-travel-adapter-commodity/pom.xml

@@ -19,6 +19,14 @@
 
     <dependencies>
         <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
             <scope>provided</scope>

+ 30 - 0
edu-travel-adapter/edu-travel-adapter-commodity/src/main/java/edu/travel/adapter/service/commodity/ShopMessageAdapter.java

@@ -0,0 +1,30 @@
+package edu.travel.adapter.service.commodity;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import edu.travel.adapter.annotation.AdapterAnnotation;
+import edu.travel.remote.commodity.ShopMessageRemoteController;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.remote.dto.SaveMessageDto;
+import edu.travel.remote.vo.MessageVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.openfeign.SpringQueryMap;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@Component
+public class ShopMessageAdapter {
+    @Autowired
+    private ShopMessageRemoteController shopMessageRemoteController;
+
+    @AdapterAnnotation
+    public RPCBaseResponse<Page<MessageVo>> getMessage(@SpringQueryMap MessageDto messageDto){
+        return shopMessageRemoteController.getMessage(messageDto);
+    }
+
+    @AdapterAnnotation
+    public RPCBaseResponse<Boolean> savaMessage(@RequestBody SaveMessageDto params){
+        return shopMessageRemoteController.savaMessage(params);
+    }
+
+}

+ 25 - 0
edu-travel-adapter/edu-travel-adapter-commodity/src/main/java/edu/travel/adapter/service/commodity/ShopUserSessionAdapter.java

@@ -0,0 +1,25 @@
+package edu.travel.adapter.service.commodity;
+
+import edu.travel.adapter.annotation.AdapterAnnotation;
+import edu.travel.remote.commodity.ShopUserSessionRemoteController;
+import edu.travel.remote.vo.ShopUserSessionVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ShopUserSessionAdapter {
+    @Autowired
+    private ShopUserSessionRemoteController shopUserSessionRemoteController;
+
+    @AdapterAnnotation
+    public RPCBaseResponse<ShopUserSessionVo> getUserSession(){
+        return shopUserSessionRemoteController.getUserSession();
+    }
+
+    @AdapterAnnotation
+    public RPCBaseResponse<ShopUserSessionVo> getSessionInfo(String sessionId){
+        return shopUserSessionRemoteController.getSessionInfo(sessionId);
+    }
+
+}

+ 19 - 0
edu-travel-adapter/edu-travel-adapter-tenant/src/main/java/edu/travel/adapter/service/tenant/SysUserRoleAdapter.java

@@ -0,0 +1,19 @@
+package edu.travel.adapter.service.tenant;
+
+import edu.travel.adapter.annotation.AdapterAnnotation;
+import edu.travel.rpc.RPCBaseResponse;
+import edu.travel.tenant.SysUserRoleRemoteController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class SysUserRoleAdapter {
+    @Autowired
+    private SysUserRoleRemoteController sysUserRoleRemoteController;
+    @AdapterAnnotation
+    public RPCBaseResponse<List<String>> getAdmins(){
+        return sysUserRoleRemoteController.getAdmins();
+    }
+}

+ 2 - 2
edu-travel-adapter/edu-travel-adapter-tenant/src/main/java/edu/travel/adapter/service/tenant/TenantAdapter.java

@@ -26,8 +26,8 @@ public class TenantAdapter {
      * 根据用户id获取用户角色列表(未分页)
      */
     @AdapterAnnotation
-    public BaseResponse<List<SysRoleVo>> getRoleListByUserId(){
-        return tenantRemoteController.getRoleListByUserId();
+    public BaseResponse<List<SysRoleVo>> getRoleListByUserId(String userId){
+        return tenantRemoteController.getRoleListByUserId(userId);
     };
     /**
      * 通过id查询商城用户信息

+ 83 - 7
edu-travel-api/edu-travel-api-web/pom.xml

@@ -91,6 +91,10 @@
             <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
         </dependency>
         <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.alibaba.csp</groupId>
             <artifactId>sentinel-datasource-nacos</artifactId>
         </dependency>
@@ -100,38 +104,110 @@
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-remote-tenant</artifactId>
+            <artifactId>edu-travel-common-util</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-remote-upload</artifactId>
+            <artifactId>edu-travel-model-base</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-common-util</artifactId>
+            <artifactId>edu-travel-common-constant</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-model-base</artifactId>
+            <artifactId>edu-travel-common-core</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-common-constant</artifactId>
+            <artifactId>edu-travel-common-cache</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-common-core</artifactId>
+            <artifactId>edu-travel-adapter-commodity</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
-            <artifactId>edu-travel-common-cache</artifactId>
+            <artifactId>edu-travel-adapter-upload</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-adapter-order</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-adapter-country</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
     </dependencies>
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <env>dev</env>
+                <versionCode>${version}-SNAPSHOT</versionCode>
+                <spark.compiler.score>compile</spark.compiler.score>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>prod</id>
+            <properties>
+                <env>prod</env>
+                <versionCode>${version}</versionCode>
+                <spark.compiler.score>provided</spark.compiler.score>
+            </properties>
+        </profile>
+    </profiles>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <delimiters>@</delimiters>
+                    <useDefaultDelimiters>false</useDefaultDelimiters>
+                </configuration>
+            </plugin>
+            <!-- 打包插件 -->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <!-- maven 打包时跳过测试 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <!--开启过滤,用指定的参数替换directory下的文件中的参数-->
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
 </project>

+ 44 - 0
edu-travel-api/edu-travel-api-web/src/main/java/edu/travel/controller/ShopUserSessionController.java

@@ -0,0 +1,44 @@
+package edu.travel.controller;
+
+import edu.travel.adapter.service.commodity.ShopUserSessionAdapter;
+import edu.travel.remote.vo.ShopUserSessionVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 用户客服关联(shop_user_session)表控制层
+ *
+ * @author xxxxx
+ */
+@RestController
+@RequestMapping("/shopUserSession")
+public class ShopUserSessionController {
+    @Autowired
+    private ShopUserSessionAdapter shopUserSessionAdapter;
+    /**
+     *  获取用户客服关联
+     * @param
+     * @return {@link RPCBaseResponse }<{@link String }>
+     */
+
+    @GetMapping("/getUserSession")
+    public RPCBaseResponse<ShopUserSessionVo> getUserSession()
+    {
+        return shopUserSessionAdapter.getUserSession();
+    }
+
+    /**
+     *  获取会话详情
+     * @param sessionId
+     * @return {@link RPCBaseResponse }<{@link ShopUserSessionVo }>
+     */
+
+    @GetMapping("/getSessionInfo")
+    public RPCBaseResponse<ShopUserSessionVo> getSessionInfo(@RequestParam("sessionId") String sessionId){
+        return shopUserSessionAdapter.getSessionInfo(sessionId);
+    }
+}

+ 24 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/commodity/ShopMessageRemoteController.java

@@ -0,0 +1,24 @@
+package edu.travel.remote.commodity;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.remote.dto.SaveMessageDto;
+import edu.travel.remote.vo.MessageVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.cloud.openfeign.SpringQueryMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@FeignClient(name="commodity-dev",path = "/shopMessage")
+public interface ShopMessageRemoteController {
+
+    @GetMapping("/getMessage")
+    public RPCBaseResponse<Page<MessageVo>> getMessage(@SpringQueryMap MessageDto messageDto);
+
+
+    @PostMapping("/savaMessage")
+    public RPCBaseResponse<Boolean> savaMessage(@RequestBody SaveMessageDto params);
+
+}

+ 17 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/commodity/ShopUserSessionRemoteController.java

@@ -0,0 +1,17 @@
+package edu.travel.remote.commodity;
+
+import edu.travel.remote.vo.ShopUserSessionVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(name="commodity-dev",path = "/shopUserSession")
+public interface ShopUserSessionRemoteController {
+
+    @GetMapping("/getUserSession")
+    public RPCBaseResponse<ShopUserSessionVo> getUserSession();
+
+    @GetMapping("/getSessionInfo")
+    public RPCBaseResponse<ShopUserSessionVo> getSessionInfo(@RequestParam("sessionId") String sessionId);
+}

+ 14 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/dto/MessageDto.java

@@ -0,0 +1,14 @@
+package edu.travel.remote.dto;
+
+import lombok.Data;
+
+@Data
+public class MessageDto{
+    private Integer currentPage = 1;
+
+    private Integer pageSize = 10;
+    /**
+     * 会话ID
+     */
+    private String sessionId;
+}

+ 34 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/dto/SaveMessageDto.java

@@ -0,0 +1,34 @@
+package edu.travel.remote.dto;
+
+import lombok.Data;
+
+@Data
+public class SaveMessageDto {
+
+    /**
+     * 消息内容
+     */
+    private String message;
+
+    /**
+     * 消息类型
+     */
+    private String messageType;
+
+
+    /**
+     * 发送人
+     */
+    private String sendUserId;
+
+
+    /**
+     * 接收人
+     */
+    private String toUserId;
+
+    /**
+     * session_id
+     */
+    private String sessionId;
+}

+ 38 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/vo/MessageVo.java

@@ -0,0 +1,38 @@
+package edu.travel.remote.vo;
+
+import lombok.Data;
+
+@Data
+public class MessageVo {
+
+    /**
+     * 消息内容
+     */
+    private String message;
+
+    /**
+     * 消息类型
+     */
+    private String messageType;
+
+    /**
+     * 消息发送人
+     */
+    private String sendUserId;
+
+    /**
+     * 消息发送人
+     */
+    private Object sendUserInfo;
+
+    /**
+     * 接收人
+     */
+    private String toUserId;
+
+    /**
+     * 接收人
+     */
+    private Object toUserInfo;
+
+}

+ 21 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/vo/ShopUserSessionVo.java

@@ -0,0 +1,21 @@
+package edu.travel.remote.vo;
+
+import lombok.Data;
+
+@Data
+public class ShopUserSessionVo {
+    /**
+     * 会话ID
+     */
+    private String id;
+
+    /**
+     * 用户ID
+     */
+    private String userId;
+
+    /**
+     * 客服ID
+     */
+    private String customerId;
+}

+ 14 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/SysUserRoleRemoteController.java

@@ -0,0 +1,14 @@
+package edu.travel.tenant;
+
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import java.util.List;
+
+@FeignClient(name = "tenant-dev",path = "/sysUserRole")
+public interface SysUserRoleRemoteController {
+
+    @GetMapping("/getAdmins")
+    public RPCBaseResponse<List<String>> getAdmins();
+}

+ 1 - 1
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/TenantRemoteController.java

@@ -85,7 +85,7 @@ public interface TenantRemoteController  extends RemoteBaseController<EduTenantV
      */
     @GetMapping("/getRoleListByUserId")
 //    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<SysRoleVo>> getRoleListByUserId();
+    public BaseResponse<List<SysRoleVo>> getRoleListByUserId(@RequestParam("userId")String userId);
 
     /**
      * 根据用户id给用户分配角色(可以多个角色)

+ 64 - 0
edu-travel-remote/edu-travel-remote-websocket/pom.xml

@@ -0,0 +1,64 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>edu.travel</groupId>
+        <artifactId>edu-travel-remote</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>edu-travel-remote-websocket</artifactId>
+    <packaging>jar</packaging>
+
+    <name>edu-travel-remote-websocket</name>
+    <url>http://maven.apache.org</url>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-common-resp</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-common-openfeign</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-model-base</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.validation</groupId>
+            <artifactId>jakarta.validation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>6.0.13.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-common-core</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-remote-base</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+</project>

+ 35 - 0
edu-travel-remote/edu-travel-remote-websocket/src/main/java/edu/travel/remote/dto/MessageDto.java

@@ -0,0 +1,35 @@
+package edu.travel.remote.dto;
+
+import lombok.Data;
+
+@Data
+public class MessageDto {
+    /**
+     * 消息接收者ID
+     */
+    private String toUserId;
+    /**
+     * 消息发送者ID
+     */
+    private String sendUserId;
+    /**
+     * 消息内容
+     */
+    private String content;
+
+    /**
+     * 消息类型
+     */
+    private String type;
+
+    /**
+     * 会话Id
+     */
+    private String sessionId;
+
+
+    /**
+     *  消息处理工厂标识 MessageEnum 枚举
+     */
+    private Integer code;
+}

+ 16 - 0
edu-travel-remote/edu-travel-remote-websocket/src/main/java/edu/travel/remote/vo/MessageVo.java

@@ -0,0 +1,16 @@
+package edu.travel.remote.vo;
+
+import lombok.Data;
+
+@Data
+public class MessageVo {
+    /**
+     * 消息内容
+     */
+    private String content;
+
+    /**
+     * 消息类型
+     */
+    private String type;
+}

+ 8 - 0
edu-travel-remote/edu-travel-remote-websocket/src/main/java/edu/travel/remote/websocket/WebSocketRemoteController.java

@@ -0,0 +1,8 @@
+package edu.travel.remote.websocket;
+
+import org.springframework.cloud.openfeign.FeignClient;
+
+@FeignClient(name = "websocket-dev",path = "/system/message")
+public interface WebSocketRemoteController {
+
+}

+ 1 - 0
edu-travel-remote/pom.xml

@@ -20,6 +20,7 @@
         <module>edu-travel-remote-country</module>
         <module>edu-travel-remote-warehouse</module>
         <module>edu-travel-remote-order</module>
+        <module>edu-travel-remote-websocket</module>
     </modules>
 
     <properties>

+ 8 - 0
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/entity/ShopMessage.java

@@ -94,4 +94,12 @@ public class ShopMessage {
      */
     @TableField(value = "delete_flag")
     private Integer deleteFlag;
+
+    /**
+     * 会话ID
+     */
+    @TableField(value = "session_id")
+    private Integer sessionId;
+
+
 }

+ 8 - 0
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/ShopMessageService.java

@@ -1,8 +1,16 @@
 package edu.travel.commodity.service;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import edu.travel.commodity.entity.ShopMessage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.remote.dto.SaveMessageDto;
+import edu.travel.remote.vo.MessageVo;
+
 public interface ShopMessageService extends IService<ShopMessage>{
 
 
+    Page<MessageVo> getMessage(MessageDto messageDto);
+
+    Boolean savaMessage(SaveMessageDto params);
 }

+ 72 - 0
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopMessageServiceImpl.java

@@ -1,12 +1,84 @@
 package edu.travel.commodity.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import edu.travel.adapter.service.tenant.TenantAdapter;
+import edu.travel.commodity.entity.ShopUserSession;
 import edu.travel.commodity.service.ShopMessageService;
+import edu.travel.commodity.service.ShopUserSessionService;
+import edu.travel.commodity.utils.PageUtil;
+import edu.travel.exception.BaseException;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.remote.dto.SaveMessageDto;
+import edu.travel.remote.feign.mode.vo.tenant.EduTenantVo;
+import edu.travel.remote.vo.MessageVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import edu.travel.commodity.mapper.ShopMessageMapper;
 import edu.travel.commodity.entity.ShopMessage;
 
+import java.util.*;
+
 @Service
 public class ShopMessageServiceImpl extends ServiceImpl<ShopMessageMapper, ShopMessage> implements ShopMessageService {
+    @Autowired
+    private TenantAdapter tenantAdapter;
+    @Autowired
+    private ShopUserSessionService shopUserSessionService;
+
+
+    @Override
+    public Page<MessageVo> getMessage(MessageDto messageDto) {
+        LambdaQueryWrapper<ShopMessage> query = Wrappers.<ShopMessage>lambdaQuery()
+                .eq(ShopMessage::getSessionId, messageDto.getSessionId())
+                .orderByDesc(ShopMessage::getCreateTime);
+        Page<ShopMessage> page = page(new Page<>(messageDto.getCurrentPage(), messageDto.getPageSize()), query);
+        Page<MessageVo> pageEntity = PageUtil.toPageEntity(page, MessageVo.class);
+        List<ShopMessage> records = page.getRecords();
+
+        Set<String> userIds = new HashSet<>();
+        if(!ObjectUtil.isEmpty(records)){
+            ShopMessage message = records.get(0);
+            userIds.add(message.getToUserId());
+            userIds.add(message.getSendUserId());
+        }
+        RPCBaseResponse<List<EduTenantVo>> result = tenantAdapter.getTenantByIds(userIds);
+        if(result.getCode()!=200){
+            throw new BaseException(result.getCode(),result.getMsg());
+        }
+
+        List<EduTenantVo> data = result.getData();
+
+        HashMap<String, EduTenantVo> map = new HashMap<>();
+        for (EduTenantVo datum : data) {
+            map.put(datum.getId(),datum);
+        }
+        //填充用户
+        if(!ObjectUtil.isEmpty(data)){
+            List<MessageVo> list = pageEntity.getRecords();
+            for (MessageVo messageVo : list) {
+                EduTenantVo from = map.get(messageVo.getSendUserId());
+                if(!ObjectUtil.isEmpty(from)){
+                    messageVo.setSendUserInfo(from);
+                }
+
+                EduTenantVo to = map.get(messageVo.getToUserId());
+                if(!ObjectUtil.isEmpty(to)){
+                    messageVo.setToUserInfo(to);
+                }
+            }
+        }
+        return pageEntity;
+    }
 
+    @Override
+    public Boolean savaMessage(SaveMessageDto params) {
+        ShopMessage bean = BeanUtil.toBean(params, ShopMessage.class);
+        return save(bean);
+    }
 }

+ 7 - 5
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopProductServiceImpl.java

@@ -10,8 +10,8 @@ import edu.travel.commodity.constant.BaseConstant;
 import edu.travel.commodity.entity.ShopProduct;
 import edu.travel.commodity.mapper.ShopProductMapper;
 import edu.travel.commodity.service.*;
-import edu.travel.commodity.utils.ObjectUtils;
 import edu.travel.commodity.utils.PageUtil;
+import edu.travel.exception.BaseException;
 import edu.travel.remote.dto.*;
 import edu.travel.remote.vo.ShopProductVo;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -63,9 +63,11 @@ public class ShopProductServiceImpl extends ServiceImpl<ShopProductMapper, ShopP
     @Transactional
     public void insertProduct(InsertProductDto params) {
         ShopProduct bean = BeanUtil.toBean(params, ShopProduct.class);
-
-        List<FileDto> imageList = ObjectUtils.castList(params.getImages(), FileDto.class);
-        bean.setMainImageUrl(imageList.get(0).getFilePath());
+        if(ObjectUtil.isEmpty(params.getImages())){
+            throw new BaseException("至少需要一张图片");
+        }
+        List<FileDto> images = params.getImages();
+        bean.setMainImageUrl(images.get(0).getFilePath());
         //保存商品
         this.save(bean);
         List<InsertProductSpecDto> specs = params.getSpecs();
@@ -74,7 +76,7 @@ public class ShopProductServiceImpl extends ServiceImpl<ShopProductMapper, ShopP
         boolean b1 = shopProductSpecService.insertProductSpec(specs, bean);
 
         //保存商品图片
-        boolean b2 = shopProductImageService.saveProductImage(bean.getId(), imageList);
+        boolean b2 = shopProductImageService.saveProductImage(bean.getId(), images);
 
         //添加一个空的sku
         boolean b3 = shopProductSkuService.insertProductSku(params.getSpecs(),params.getSkus(), bean);

+ 1 - 2
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopReviewServiceImpl.java

@@ -137,8 +137,7 @@ public class ShopReviewServiceImpl extends ServiceImpl<ShopReviewMapper, ShopRev
             //订单快照对象
             ShopSnapshotVo bean1 = JSONUtil.toBean(snapshot, ShopSnapshotVo.class);
             List<SpecValueVo> snapshotSpec = bean1.getSnapshotSpec();
-            List<SpecValueVo> snapshot1 = ObjectUtils.castList(snapshotSpec, SpecValueVo.class);
-            String jsonStr = JSONUtil.toJsonStr(snapshot1);
+            String jsonStr = JSONUtil.toJsonStr(snapshotSpec);
             bean.setSkuDetails(jsonStr);
         }
         bean.setUpdateUserId(userId);

+ 0 - 1
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/utils/IdUtils.java

@@ -2,7 +2,6 @@ package edu.travel.commodity.utils;
 
 import cn.hutool.core.lang.Singleton;
 import cn.hutool.core.lang.Snowflake;
-import cn.hutool.core.util.IdUtil;
 import lombok.Data;
 
 @Data

+ 0 - 19
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/utils/ObjectUtils.java

@@ -1,19 +0,0 @@
-package edu.travel.commodity.utils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ObjectUtils {
-
-
-    public static <T> List<T> castList(Object obj, Class<T> clazz) {
-        List<T> result = new ArrayList<T>();
-        if (obj instanceof List<?>) {
-            for (Object o : (List<?>) obj) {
-                result.add(clazz.cast(o));
-            }
-            return result;
-        }
-        return null;
-    }
-}

+ 30 - 5
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/web/ShopMessageController.java

@@ -1,6 +1,11 @@
 package edu.travel.commodity.web;
-import edu.travel.commodity.entity.ShopMessage;
-import edu.travel.commodity.service.impl.ShopMessageServiceImpl;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import edu.travel.commodity.service.ShopMessageService;
+import edu.travel.remote.commodity.ShopMessageRemoteController;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.remote.dto.SaveMessageDto;
+import edu.travel.remote.vo.MessageVo;
+import edu.travel.rpc.RPCBaseResponse;
 import org.springframework.web.bind.annotation.*;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -11,13 +16,33 @@ import org.springframework.beans.factory.annotation.Autowired;
 * @author xxxxx
 */
 @RestController
-@RequestMapping("/shop_message")
-public class ShopMessageController {
+@RequestMapping("/shopMessage")
+public class ShopMessageController implements ShopMessageRemoteController {
 /**
 * 服务对象
 */
     @Autowired
-    private ShopMessageServiceImpl shopMessageServiceImpl;
+    private ShopMessageService shopMessageService;
+
+    /**
+     *  获取消息记录
+     * @param messageDto
+     * @return {@link RPCBaseResponse }<{@link Page }<{@link MessageVo }>>
+     */
+    @GetMapping("/getMessage")
+    public RPCBaseResponse<Page<MessageVo>> getMessage(MessageDto messageDto){
+        return RPCBaseResponse.success(shopMessageService.getMessage(messageDto));
+    }
+
+    /**
+     * 保存消息
+     * @param params
+     * @return
+     */
+    @PostMapping("/savaMessage")
+    public RPCBaseResponse<Boolean> savaMessage(@RequestBody SaveMessageDto params){
+        return RPCBaseResponse.success(shopMessageService.savaMessage(params));
+    }
 
 
 }

+ 80 - 4
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/web/ShopUserSessionController.java

@@ -1,23 +1,99 @@
 package edu.travel.commodity.web;
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import edu.travel.adapter.service.tenant.SysUserRoleAdapter;
+import edu.travel.adapter.service.tenant.TenantAdapter;
 import edu.travel.commodity.entity.ShopUserSession;
-import edu.travel.commodity.service.impl.ShopUserSessionServiceImpl;
+import edu.travel.commodity.service.ShopUserSessionService;
+import edu.travel.commodity.utils.TokenData;
+import edu.travel.exception.BaseException;
+import edu.travel.remote.commodity.ShopUserSessionRemoteController;
+import edu.travel.remote.feign.mode.vo.tenant.SysRoleVo;
+import edu.travel.remote.vo.ShopUserSessionVo;
+import edu.travel.resp.BaseResponse;
+import edu.travel.rpc.RPCBaseResponse;
 import org.springframework.web.bind.annotation.*;
 
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.Collectors;
+
 /**
 * 用户客服关联(shop_user_session)表控制层
 *
 * @author xxxxx
 */
 @RestController
-@RequestMapping("/shop_user_session")
-public class ShopUserSessionController {
+@RequestMapping("/shopUserSession")
+public class ShopUserSessionController implements ShopUserSessionRemoteController {
 /**
 * 服务对象
 */
     @Autowired
-    private ShopUserSessionServiceImpl shopUserSessionServiceImpl;
+    private ShopUserSessionService shopUserSessionService;
+    @Autowired
+    private TenantAdapter tenantAdapter;
+    @Autowired
+    private SysUserRoleAdapter sysUserRoleAdapter;
+
+    /**
+     *  获取用户客服关联
+     * @param
+     * @return {@link RPCBaseResponse }<{@link String }>
+     */
+
+    @GetMapping("/getUserSession")
+    public RPCBaseResponse<ShopUserSessionVo> getUserSession()
+    {
+        String userId = TokenData.getUserId();
+        LambdaQueryWrapper<ShopUserSession> query = Wrappers.<ShopUserSession>lambdaQuery().eq(ShopUserSession::getUserId, userId)
+                .or()
+                .eq(ShopUserSession::getCustomerId, userId);
+        ShopUserSession one = shopUserSessionService.getOne(query);
+        if(one==null){
+            return getSessionInfo("");
+        }else {
+            return getSessionInfo(one.getId().toString());
+        }
+    }
+
+    @GetMapping("/getSessionInfo")
+    public RPCBaseResponse<ShopUserSessionVo> getSessionInfo(@RequestParam("sessionId") String sessionId){
+        String userId = TokenData.getUserId();
+        ShopUserSession one = shopUserSessionService.getById(sessionId);
+        if(one!=null){
+            Long customerId = one.getCustomerId();
+            BaseResponse<List<SysRoleVo>> result = tenantAdapter.getRoleListByUserId(customerId.toString());
+            if(result.getCode()!=200){
+                throw new BaseException(result.getCode(),result.getMsg());
+            }
+            List<SysRoleVo> data = result.getData();
+            List<String> collect = data.stream().map(SysRoleVo::getName).collect(Collectors.toList());
+            if(collect.contains("超级管理员")){
+                //创建会话
+                return RPCBaseResponse.success("success",BeanUtil.toBean(one, ShopUserSessionVo.class));
+            }
+        }
+        //获取全部管理员
+        RPCBaseResponse<List<String>> admins = sysUserRoleAdapter.getAdmins();
+        if(admins.getCode()!=200){
+            throw new BaseException(admins.getCode(),admins.getMsg());
+        }
+        List<String> data = admins.getData();
+        int randomIndex = ThreadLocalRandom.current().nextInt(data.size());
+        String s = data.get(randomIndex);
+        //新增会话
+        ShopUserSession shopUserSession = new ShopUserSession();
+        shopUserSession.setCustomerId(Long.valueOf(s));
+        shopUserSession.setUserId(Long.valueOf(userId));
+        shopUserSessionService.save(shopUserSession);
+        ShopUserSessionVo bean = BeanUtil.toBean(shopUserSession, ShopUserSessionVo.class);
+        return RPCBaseResponse.success("success",bean);
+    }
+
 
 
 }

+ 2 - 1
edu-travel-service/edu-travel-service-commodity/src/main/resources/mapper/ShopMessageMapper.xml

@@ -17,10 +17,11 @@
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
     <result column="update_user_id" jdbcType="VARCHAR" property="updateUserId" />
     <result column="delete_flag" jdbcType="INTEGER" property="deleteFlag" />
+    <result column="session_id" jdbcType="VARCHAR" property="sessionId" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--@mbg.generated-->
     id, message_type, message, send_user_id, to_user_id, is_read, deleted_by_users, project, 
-    create_time, create_user_id, update_time, update_user_id, delete_flag
+    create_time, create_user_id, update_time, update_user_id, delete_flag,session_id
   </sql>
 </mapper>

+ 30 - 1
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysUserRoleController.java

@@ -1,10 +1,25 @@
 package edu.travel.tenant.web;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import edu.travel.remote.feign.mode.vo.tenant.EduTenantVo;
+import edu.travel.rpc.RPCBaseResponse;
+import edu.travel.tenant.SysUserRoleRemoteController;
+import edu.travel.tenant.entity.EduTenant;
+import edu.travel.tenant.entity.SysRole;
+import edu.travel.tenant.service.ISysRoleService;
+import edu.travel.tenant.service.ISysUserRoleService;
 import edu.travel.web.BaseController;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import edu.travel.tenant.entity.SysUserRole;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 /**
  * SysMenuController 类。
  * <p>
@@ -16,6 +31,20 @@ import edu.travel.tenant.entity.SysUserRole;
 
 @RestController
 @RequestMapping("/sysUserRole")
-public class SysUserRoleController extends BaseController<SysUserRole> {
+public class SysUserRoleController extends BaseController<SysUserRole> implements SysUserRoleRemoteController {
+    @Autowired
+    private ISysUserRoleService iSysUserRoleService;
+    @Autowired
+    private ISysRoleService sysRoleService;
+    @GetMapping("/getAdmins")
+    public RPCBaseResponse<List<String>> getAdmins() {
+        LambdaQueryWrapper<SysRole> query = Wrappers.<SysRole>lambdaQuery().eq(SysRole::getName, "超级管理员");
+        SysRole one = sysRoleService.getOne(query);
+        LambdaQueryWrapper<SysUserRole> queryWrapper = Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getRoleId, one.getId());
+        List<SysUserRole> list = iSysUserRoleService.list(queryWrapper);
+        List<String> collect = list.stream().map(sysUserRole -> sysUserRole.getUserId().toString()).collect(Collectors.toList());
+        return RPCBaseResponse.success(collect);
+    }
+
 
 }

+ 7 - 2
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/TenantController.java

@@ -196,8 +196,13 @@ public class TenantController  extends BaseController<EduTenant> implements Tena
      */
     @GetMapping("/getRoleListByUserId")
 //    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<SysRoleVo>> getRoleListByUserId() {
-        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+    public BaseResponse<List<SysRoleVo>> getRoleListByUserId(@RequestParam("userId")String userId) {
+        EduTenant principal = null;
+        if(userId!=null){
+            principal = tenantService.getTenantById(Long.valueOf(userId));
+        }else {
+            principal =(EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        }
         List<SysRole> roleList = tenantService.getRoleListByUserId(principal);
         List<SysRoleVo> sysRoleVos = BeanUtil.copyToList(roleList, SysRoleVo.class);
         return PageResponse.out(200, "success", sysRoleVos);

+ 10 - 0
edu-travel-service/edu-travel-service-ws/pom.xml

@@ -137,6 +137,16 @@
             <artifactId>edu-travel-common-constant</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-remote-websocket</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-adapter-commodity</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
     </dependencies>
     <profiles>
         <profile>

+ 2 - 2
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/WsApplication.java

@@ -1,14 +1,14 @@
 package edu.travel;
 
-import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 
 
 @SpringBootApplication
 @EnableDiscoveryClient
-@MapperScan
+@EnableFeignClients
 public class WsApplication
 {
     public static void main( String[] args )

+ 1 - 1
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/config/WebSocketAutoConfig.java

@@ -18,7 +18,7 @@ public class WebSocketAutoConfig implements WebSocketConfigurer {
 
     @Override
     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
-        registry.addHandler(new TravelMessageHandler(applicationContext), "/system/message")
+        registry.addHandler(new TravelMessageHandler(), "/system/message")
                 .addInterceptors(new SystemMessageInterceptor(applicationContext))
                 .setAllowedOrigins("*");
     }

+ 26 - 0
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/enums/MessageEnum.java

@@ -0,0 +1,26 @@
+package edu.travel.ws.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum MessageEnum {
+    SHOP_MESSAGE(0, "商城客服消息"),
+    TRAVEL_MESSAGE(1, "...");
+
+    private final int code;
+    private final String name;
+
+
+    public static MessageEnum getByCode(int code){
+        for (MessageEnum orderState : values()) {
+            if (orderState.getCode() == code) {
+                return orderState;
+            }
+        }
+        throw new IllegalArgumentException("No matching enum found for state: " + code);
+    }
+
+
+}

+ 45 - 0
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/factoryandstragy/MessageFactory.java

@@ -0,0 +1,45 @@
+package edu.travel.ws.factoryandstragy;
+
+import edu.travel.ws.enums.MessageEnum;
+import edu.travel.ws.service.MessageService;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+public class MessageFactory implements InitializingBean {
+
+    /**
+     * 所有的具体支付策略的对象逻辑会被注入到这里
+     */
+    @Resource
+    private List<MessageService> list;
+
+    /**
+     * 存储策略标识和具体策略的map
+     */
+    private Map<MessageEnum, MessageService> handlerMap = new ConcurrentHashMap<>();
+
+
+    /**
+     * 根据枚举的code来获取对应的策略
+     * @param code
+     * @return
+     */
+    public MessageService getHandlerByCode(int code) {
+        MessageEnum byCode = MessageEnum.getByCode(code);
+        return handlerMap.get(byCode);
+    }
+
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        for (MessageService service : list) {
+            handlerMap.put(service.getCode(), service);
+        }
+    }
+}

+ 116 - 5
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/handle/TravelMessageHandler.java

@@ -1,17 +1,44 @@
 package edu.travel.ws.handle;
 
-import org.springframework.context.ApplicationContext;
+import com.alibaba.fastjson.JSON;
+import edu.travel.adapter.service.commodity.ShopUserSessionAdapter;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.ws.factoryandstragy.MessageFactory;
+import edu.travel.ws.service.MessageService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.PongMessage;
+import org.springframework.web.socket.TextMessage;
 import org.springframework.web.socket.WebSocketSession;
 import org.springframework.web.socket.handler.AbstractWebSocketHandler;
 
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
+@Component
 public class TravelMessageHandler extends AbstractWebSocketHandler {
-    private ApplicationContext applicationContext;
 
-    public TravelMessageHandler(ApplicationContext applicationContext) {
-        this.applicationContext = applicationContext;
+    private static ConcurrentHashMap<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();
+
+    private static  MessageFactory messageFactory;
+
+    @Autowired
+    public void setDeviceListenerService(MessageFactory messageFactory) {
+        TravelMessageHandler.messageFactory = messageFactory;
+    }
+
+
+    public static Map<String, WebSocketSession> getSessionMap() {
+        return sessionMap;
     }
 
+
     /**
      * 连接时调用方法
      * @param session
@@ -19,6 +46,90 @@ public class TravelMessageHandler extends AbstractWebSocketHandler {
      */
     @Override
     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
-        System.out.println("============================================");
+        Map<String, Object> attributes = session.getAttributes();
+
     }
+    /**
+     * 连接出错时调用
+     * @param session
+     * @param exception
+     * @throws Exception
+     */
+    @Override
+    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
+        exception.printStackTrace();
+        Map<String, Object> attributes = session.getAttributes();
+
+    }
+
+    /**
+     * 连接关闭调用的方法
+     */
+    @Override
+    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
+
+
+    }
+
+
+    /**
+     * 心跳
+     * @param session
+     * @param message
+     * @throws Exception
+     */
+    @Override
+    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
+        session.sendMessage(message);
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED)
+    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+        String payload = message.getPayload();
+        if (StringUtils.isBlank(payload)) {
+            return;
+        }
+
+        MessageDto messageDto = JSON.parseObject(payload, MessageDto.class);
+        MessageService handlerByCode = messageFactory.getHandlerByCode(messageDto.getCode());
+        List<String> ids = handlerByCode.sendMessage(messageDto);
+
+        //对方session
+        for (String id : ids) {
+            WebSocketSession toSession = sessionMap.get(id);
+            if(toSession!=null){
+                sendMessage(messageDto,toSession);
+            }
+        }
+    }
+
+    /**
+     * 发送系统消息给所有人系统消息
+     * @param message
+     * @throws Exception
+     */
+    public void sendAllMessage(TextMessage message) throws Exception {
+        sessionMap.forEach( (key,value) ->{
+            if (value.isOpen()) {
+                try {
+                    value.sendMessage(message);
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+    }
+
+    /**
+     * 给单个人系统发送消息
+     * @param message
+     */
+    public void sendMessage(MessageDto message, WebSocketSession session) throws Exception {
+        if (session.isOpen()) {
+            session.sendMessage(new TextMessage(message.getContent()));
+        }
+    }
+
+
 }

+ 16 - 0
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/service/MessageService.java

@@ -0,0 +1,16 @@
+package edu.travel.ws.service;
+
+
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.ws.enums.MessageEnum;
+
+import java.util.List;
+
+public interface MessageService {
+
+
+    public MessageEnum getCode();
+
+    public List<String> sendMessage(MessageDto messageDto);
+
+}

+ 64 - 0
edu-travel-service/edu-travel-service-ws/src/main/java/edu/travel/ws/service/impl/ShopMessageService.java

@@ -0,0 +1,64 @@
+package edu.travel.ws.service.impl;
+
+
+import edu.travel.adapter.service.commodity.ShopMessageAdapter;
+import edu.travel.adapter.service.commodity.ShopUserSessionAdapter;
+import edu.travel.exception.BaseException;
+import edu.travel.remote.dto.MessageDto;
+import edu.travel.remote.dto.SaveMessageDto;
+import edu.travel.remote.vo.ShopUserSessionVo;
+import edu.travel.rpc.RPCBaseResponse;
+import edu.travel.ws.enums.MessageEnum;
+import edu.travel.ws.service.MessageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+@Component
+public class ShopMessageService implements MessageService {
+    @Autowired
+    private ShopUserSessionAdapter shopUserSessionAdapter;
+    @Autowired
+    private ShopMessageAdapter shopMessageAdapter;
+
+    @Override
+    public MessageEnum getCode() {
+        return MessageEnum.SHOP_MESSAGE;
+    }
+
+
+    @Override
+    public List<String> sendMessage(MessageDto messageDto) {
+        //获取接收人
+        RPCBaseResponse<ShopUserSessionVo> sessionInfo =
+                shopUserSessionAdapter.getSessionInfo(messageDto.getSessionId());
+        ShopUserSessionVo data = sessionInfo.getData();
+        //判断聊天的人和数据库会话的人 是否是相同
+        HashSet<String> ids = new HashSet<>();
+        ids.add(data.getUserId());
+        ids.add(data.getCustomerId());
+        ids.add(messageDto.getSendUserId());
+        ids.add(messageDto.getToUserId());
+        if(ids.size()!=2){
+            throw new BaseException("聊天对象错误");
+        }
+        //保存消息
+        SaveMessageDto saveMessageDto = new SaveMessageDto();
+
+        saveMessageDto.setMessage(messageDto.getContent());
+        saveMessageDto.setMessageType(messageDto.getType());
+        saveMessageDto.setSendUserId(messageDto.getSendUserId());
+        saveMessageDto.setToUserId(messageDto.getToUserId());
+        saveMessageDto.setSessionId(data.getId());
+
+        shopMessageAdapter.savaMessage(saveMessageDto);
+        ArrayList<String> list = new ArrayList<>();
+        list.add(messageDto.getToUserId());
+        return list;
+    }
+
+
+}

+ 2 - 2
pom.xml

@@ -13,8 +13,8 @@
     <module>edu-travel-remote</module>
     <module>edu-travel-oauth</module>
     <module>edu-travel-model</module>
-      <module>edu-travel-api</module>
-      <module>edu-travel-adapter</module>
+    <module>edu-travel-api</module>
+    <module>edu-travel-adapter</module>
   </modules>
   <parent>
     <groupId>org.springframework.boot</groupId>