瀏覽代碼

钱包交易明细管理

wangqi49 3 月之前
父節點
當前提交
dd39c776ff
共有 39 個文件被更改,包括 764 次插入455 次删除
  1. 44 0
      resources/database-sql/webchat-payment.sql
  2. 33 0
      webchat-admin/src/main/java/com/webchat/admin/config/AdminWebMvcConfig.java
  3. 56 0
      webchat-admin/src/main/java/com/webchat/admin/config/interceptor/ValidatePermissionInterceptor.java
  4. 0 1
      webchat-admin/src/main/java/com/webchat/admin/controller/AccountManagementController.java
  5. 0 2
      webchat-admin/src/main/java/com/webchat/admin/controller/FileController.java
  6. 33 0
      webchat-admin/src/main/java/com/webchat/admin/controller/WalletManagementController.java
  7. 36 0
      webchat-admin/src/main/java/com/webchat/admin/service/AccountRoleService.java
  8. 28 0
      webchat-admin/src/main/java/com/webchat/admin/service/AccountService.java
  9. 2 2
      webchat-admin/src/main/java/com/webchat/admin/service/UserSessionService.java
  10. 21 0
      webchat-admin/src/main/java/com/webchat/admin/service/WalletManagementService.java
  11. 2 2
      webchat-client-chat/src/main/java/com/webchat/client/chat/service/UserSessionService.java
  12. 0 55
      webchat-common/src/main/java/com/webchat/common/config/annotation/SafeClickInterceptor.java
  13. 0 37
      webchat-common/src/main/java/com/webchat/common/config/annotation/ValidateLoginInterceptor.java
  14. 0 54
      webchat-common/src/main/java/com/webchat/common/config/annotation/ValidatePermissionInterceptor.java
  15. 0 58
      webchat-common/src/main/java/com/webchat/common/config/configuration/WebChatWebMvcConfigurer.java
  16. 5 6
      webchat-common/src/main/java/com/webchat/common/constants/CookieConstants.java
  17. 13 0
      webchat-common/src/main/java/com/webchat/common/enums/WalletTransTypeEnum.java
  18. 4 2
      webchat-common/src/main/java/com/webchat/common/helper/SessionHelper.java
  19. 1 1
      webchat-common/src/main/java/com/webchat/common/helper/SseEmitterHelper.java
  20. 0 30
      webchat-connect/src/main/java/com/webchat/connect/config/CorsConfig.java
  21. 0 14
      webchat-connect/src/main/java/com/webchat/connect/config/WebSocketConfig.java
  22. 0 97
      webchat-connect/src/main/java/com/webchat/connect/websocket/ChatWebSocketEndPoint.java
  23. 28 0
      webchat-connect/src/main/java/com/webchat/connect/websocket/config/WebSocketConnectConfig.java
  24. 68 0
      webchat-connect/src/main/java/com/webchat/connect/websocket/handler/ChatWebSocketEndPointHandler.java
  25. 26 0
      webchat-connect/src/main/java/com/webchat/connect/websocket/interceptor/ChatWebSocketEndPointInterceptor.java
  26. 5 1
      webchat-domain/src/main/java/com/webchat/domain/vo/response/UserWalletDetailResponseVO.java
  27. 2 0
      webchat-pay/src/main/java/com/webchat/pay/WebchatPayApplication.java
  28. 30 0
      webchat-pay/src/main/java/com/webchat/pay/controller/PaymentServiceController.java
  29. 18 0
      webchat-pay/src/main/java/com/webchat/pay/repository/dao/IUserWalletDAO.java
  30. 28 0
      webchat-pay/src/main/java/com/webchat/pay/repository/entity/BaseEntity.java
  31. 36 0
      webchat-pay/src/main/java/com/webchat/pay/repository/entity/SimpleBaseEntity.java
  32. 60 0
      webchat-pay/src/main/java/com/webchat/pay/repository/entity/UserWalletEntity.java
  33. 85 0
      webchat-pay/src/main/java/com/webchat/pay/service/PaymentService.java
  34. 35 0
      webchat-pay/src/main/java/com/webchat/pay/service/UserService.java
  35. 0 17
      webchat-remote/src/main/java/com/webchat/rmi/pay/PayServiceClient.java
  36. 31 0
      webchat-remote/src/main/java/com/webchat/rmi/pay/PaymentServiceClient.java
  37. 14 0
      webchat-remote/src/main/java/com/webchat/rmi/user/UserServiceClient.java
  38. 9 0
      webchat-user/src/main/java/com/webchat/user/controller/UserServiceController.java
  39. 11 76
      webchat-user/src/main/java/com/webchat/user/service/UserService.java

+ 44 - 0
resources/database-sql/webchat-payment.sql

@@ -0,0 +1,44 @@
+-- 红包信息表
+CREATE TABLE webchat_payment.`web_chat_red_packet` (
+                                                       `ID` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
+                                                       `send_user_id` char(100) NOT NULL COMMENT '红包发送人',
+                                                       `receiver_user_id` char(100) NOT NULL COMMENT '接受人',
+                                                       `type` int(4) NOT NULL COMMENT '消息类型',
+                                                       `count` int(4) NOT NULL COMMENT '红包个数',
+                                                       `status` int(4) NOT NULL COMMENT '状态',
+                                                       `total_money` DECIMAL(10, 2) default '0.00' COMMENT '金额',
+                                                       `CREATE_BY` char(100) DEFAULT NULL COMMENT '创建人',
+                                                       `CREATE_DATE` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+                                                       `expire_date` datetime NOT NULL COMMENT '过期时间',
+                                                       `UPDATE_BY` char(100) DEFAULT NULL COMMENT '更新人',
+                                                       `UPDATE_DATE` datetime DEFAULT NULL COMMENT '更新时间',
+                                                       `VERSION` int DEFAULT '0' COMMENT '版本',
+                                                       PRIMARY KEY (`ID`),
+                                                       KEY `INDEX_SEND_USER_ID` (`send_user_id`),
+                                                       KEY `INDEX_STATUS_EXPIRE_DATE` (`status`, `expire_date`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='红包信息表';
+
+-- 红包拆分记录明细表
+CREATE TABLE webchat_payment.`web_chat_red_packet_record` (
+                                                              `ID` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
+                                                              `red_packet_id` bigint NOT NULL COMMENT '红包id',
+                                                              `user_id` char(100) NOT NULL COMMENT '领取人',
+                                                              `money` DECIMAL(10, 2) default '0.00' COMMENT '领取金额',
+                                                              `CREATE_DATE` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+                                                              PRIMARY KEY (`ID`),
+                                                              KEY `INDEX_RED_PACKET_ID` (`red_packet_id`),
+                                                              KEY `INDEX_USER_ID` (`user_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='红包拆分记录明细表';
+
+-- 用户钱包
+CREATE TABLE webchat_payment.`web_chat_user_wallet` (
+                                                        `ID` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
+                                                        `trans_event` int(4) NOT NULL COMMENT '事件类型',
+                                                        `trans_type` int(4) NOT NULL COMMENT '收入/支出',
+                                                        `user_id` char(100) NOT NULL COMMENT '用户id',
+                                                        `target_user_id` char(100) NOT NULL COMMENT '目标用户',
+                                                        `money` DECIMAL(10, 2) default '0.00' COMMENT '流转金额',
+                                                        `trans_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '流转时间',
+                                                        PRIMARY KEY (`ID`),
+                                                        KEY `INDEX_USER_ID` (`user_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户钱包';

+ 33 - 0
webchat-admin/src/main/java/com/webchat/admin/config/AdminWebMvcConfig.java

@@ -0,0 +1,33 @@
+package com.webchat.admin.config;
+
+import com.webchat.admin.config.interceptor.ValidatePermissionInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class AdminWebMvcConfig implements WebMvcConfigurer {
+
+    /**
+     * 注册自定义拦截器
+     * @param registry
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        /**
+         * 注册权限控制拦截器
+         */
+        registry.addInterceptor(validatePermissionInterceptor()).addPathPatterns("/**");
+    }
+
+    /***
+     * 登录核验拦截器
+     * @return
+     */
+    @Bean
+    public ValidatePermissionInterceptor validatePermissionInterceptor() {
+        return new ValidatePermissionInterceptor();
+    }
+
+}

+ 56 - 0
webchat-admin/src/main/java/com/webchat/admin/config/interceptor/ValidatePermissionInterceptor.java

@@ -0,0 +1,56 @@
+package com.webchat.admin.config.interceptor;
+
+
+import com.webchat.admin.service.AccountRoleService;
+import com.webchat.common.config.annotation.ValidatePermission;
+import com.webchat.common.enums.RoleCodeEnum;
+import com.webchat.common.exception.AuthException;
+import com.webchat.common.helper.SessionHelper;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import java.lang.reflect.Method;
+
+public class ValidatePermissionInterceptor implements HandlerInterceptor {
+
+    @Autowired
+    private AccountRoleService accountRoleService;
+
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+
+        HandlerMethod handlerMethod = (HandlerMethod) handler;
+        // 获取拦截到的方法
+        Method method = handlerMethod.getMethod();
+        // 获取方法到的RequestPermission注解
+        ValidatePermission requestPermission = method.getAnnotation(ValidatePermission.class);
+        if (requestPermission == null) {
+            // 未获取到权控注解,说明不需要拦截,直接放过
+            return true;
+        }
+
+        /***
+         * 权限校验
+         */
+        if (requestPermission.role().length > 0) {
+            RoleCodeEnum[] roleEnums = requestPermission.role();
+            // 获取当前登录的用户ID
+            String userId = SessionHelper.getCurrentUserId();
+            if (StringUtils.isBlank(userId)) {
+                // 未登录!权限校验失败
+                throw new AuthException("未登录!");
+            }
+            // 一个一个校验,或者的关系:即满足任一权限则通过
+            for (RoleCodeEnum roleEnum : roleEnums) {
+                // 用户任一权限校验通过,则认为拥有操作权限
+                if (accountRoleService.hasRole(userId, roleEnum.getCode())) {
+                    return true;
+                }
+            }
+        }
+        throw new AuthException("无权限!");
+    }
+}

+ 0 - 1
webchat-admin/src/main/java/com/webchat/admin/controller/AccountManagementController.java

@@ -21,7 +21,6 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/admin-service/account")
 public class AccountManagementController {
 
-
     @Autowired
     private AccountManagementService accountManagementService;
 

+ 0 - 2
webchat-admin/src/main/java/com/webchat/admin/controller/FileController.java

@@ -4,9 +4,7 @@ import com.webchat.common.bean.APIResponseBean;
 import com.webchat.common.bean.APIResponseBeanUtil;
 import com.webchat.common.service.MinioService;
 import com.webchat.common.util.DateUtils;
-import com.webchat.domain.dto.UploadResultDTO;
 import com.webchat.domain.vo.response.UploadResultVO;
-import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import org.apache.commons.lang3.StringUtils;

+ 33 - 0
webchat-admin/src/main/java/com/webchat/admin/controller/WalletManagementController.java

@@ -0,0 +1,33 @@
+package com.webchat.admin.controller;
+
+
+import com.webchat.admin.service.WalletManagementService;
+import com.webchat.common.bean.APIPageResponseBean;
+import com.webchat.common.config.annotation.ValidatePermission;
+import com.webchat.domain.vo.response.UserWalletDetailResponseVO;
+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;
+
+@RestController
+@RequestMapping("/admin-service/wallet")
+public class WalletManagementController {
+
+    @Autowired
+    private WalletManagementService walletManagementService;
+
+    @ValidatePermission
+    @GetMapping("/page")
+    public APIPageResponseBean<UserWalletDetailResponseVO> page(
+            @RequestParam(value = "transType", required = false) Integer transType,
+            @RequestParam(value = "eventType", required = false) Integer eventType,
+            @RequestParam(value = "userId", required = false) String userId,
+            @RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
+            @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
+
+        return walletManagementService.page(transType, eventType, userId, pageNo, pageSize);
+    }
+
+}

+ 36 - 0
webchat-admin/src/main/java/com/webchat/admin/service/AccountRoleService.java

@@ -0,0 +1,36 @@
+package com.webchat.admin.service;
+
+
+import com.webchat.domain.vo.response.UserBaseResponseInfoVO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+@Slf4j
+@Service
+public class AccountRoleService {
+
+
+    @Autowired
+    private AccountService accountService;
+
+    /**
+     * 校验账号是否拥有权限
+     *
+     * @param account   用户ID
+     * @param roleCode 权限CODE
+     * @return
+     */
+    public boolean hasRole(String account, Integer roleCode) {
+        if (StringUtils.isBlank(account) || roleCode == null) {
+            log.error("{} not has role: {}!", account, roleCode);
+            return false;
+        }
+        UserBaseResponseInfoVO accountInfo = accountService.accountInfo(account);
+        Assert.isTrue(accountInfo != null, "无权限");
+        return roleCode.equals(accountInfo.getRoleCode());
+    }
+
+}

+ 28 - 0
webchat-admin/src/main/java/com/webchat/admin/service/AccountService.java

@@ -0,0 +1,28 @@
+package com.webchat.admin.service;
+
+
+import com.webchat.common.bean.APIResponseBean;
+import com.webchat.common.bean.APIResponseBeanUtil;
+import com.webchat.domain.vo.response.UserBaseResponseInfoVO;
+import com.webchat.rmi.user.UserServiceClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AccountService {
+
+
+    @Autowired
+    private UserServiceClient userServiceClient;
+
+
+    public UserBaseResponseInfoVO accountInfo(String account) {
+
+        APIResponseBean<UserBaseResponseInfoVO> responseBean = userServiceClient.userInfo(account);
+        if (APIResponseBeanUtil.isOk(responseBean)) {
+            return responseBean.getData();
+        }
+        return null;
+    }
+
+}

+ 2 - 2
webchat-admin/src/main/java/com/webchat/admin/service/UserSessionService.java

@@ -21,7 +21,7 @@ public class UserSessionService {
         Cookie[] cookies = request.getCookies();
         if (cookies != null) {
             for (Cookie cookie : cookies) {
-                if (CookieConstants.WEB_CHAT_USER_COOKIE_KEY.equals(cookie.getName())) {
+                if (CookieConstants.WEB_CHAT_ADMIN_USER_COOKIE_KEY.equals(cookie.getName())) {
                     String sessionId = cookie.getValue();
                     return this.getUserIdBySessionId(sessionId);
                 }
@@ -34,7 +34,7 @@ public class UserSessionService {
         String sessionId = MD5Utils.md5(userId + DateUtils.getCurrentFormatDate());
         this.setUserIdBySessionId(sessionId, userId);
         // 种浏览器Cookie
-        Cookie cookie = new Cookie(CookieConstants.WEB_CHAT_USER_COOKIE_KEY, sessionId);
+        Cookie cookie = new Cookie(CookieConstants.WEB_CHAT_ADMIN_USER_COOKIE_KEY, sessionId);
         cookie.setPath("/");
         cookie.setMaxAge(CookieConstants.COOKIE_OUT_TIME);
         response.addCookie(cookie);

+ 21 - 0
webchat-admin/src/main/java/com/webchat/admin/service/WalletManagementService.java

@@ -0,0 +1,21 @@
+package com.webchat.admin.service;
+
+import com.webchat.common.bean.APIPageResponseBean;
+import com.webchat.domain.vo.response.UserWalletDetailResponseVO;
+import com.webchat.rmi.pay.PaymentServiceClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class WalletManagementService {
+
+
+    @Autowired
+    private PaymentServiceClient paymentServiceClient;
+
+    public APIPageResponseBean<UserWalletDetailResponseVO> page(Integer transType, Integer eventType, String userId,
+                                                                Integer pageNo, Integer pageSize) {
+
+        return paymentServiceClient.page(transType, eventType, userId, pageNo, pageSize);
+    }
+}

+ 2 - 2
webchat-client-chat/src/main/java/com/webchat/client/chat/service/UserSessionService.java

@@ -21,7 +21,7 @@ public class UserSessionService {
         Cookie[] cookies = request.getCookies();
         if (cookies != null) {
             for (Cookie cookie : cookies) {
-                if (CookieConstants.WEB_CHAT_USER_COOKIE_KEY.equals(cookie.getName())) {
+                if (CookieConstants.WEB_CHAT_CLIENT_USER_COOKIE_KEY.equals(cookie.getName())) {
                     String sessionId = cookie.getValue();
                     return this.getUserIdBySessionId(sessionId);
                 }
@@ -34,7 +34,7 @@ public class UserSessionService {
         String sessionId = MD5Utils.md5(userId + DateUtils.getCurrentFormatDate());
         this.setUserIdBySessionId(sessionId, userId);
         // 种浏览器Cookie
-        Cookie cookie = new Cookie(CookieConstants.WEB_CHAT_USER_COOKIE_KEY, sessionId);
+        Cookie cookie = new Cookie(CookieConstants.WEB_CHAT_CLIENT_USER_COOKIE_KEY, sessionId);
         cookie.setPath("/");
         cookie.setMaxAge(CookieConstants.COOKIE_OUT_TIME);
         response.addCookie(cookie);

+ 0 - 55
webchat-common/src/main/java/com/webchat/common/config/annotation/SafeClickInterceptor.java

@@ -1,55 +0,0 @@
-package com.webchat.common.config.annotation;
-
-import com.webchat.common.constants.WebConstant;
-import com.webchat.common.exception.AuthException;
-import com.webchat.common.exception.BusinessException;
-import com.webchat.common.helper.SessionHelper;
-import com.webchat.common.service.RedisService;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import java.lang.reflect.Method;
-
-/**
- * 异常点击事件拦截
- */
-@Slf4j
-public class SafeClickInterceptor implements HandlerInterceptor {
-
-    @Autowired
-    private RedisService redisService;
-    /**
-     * 在调用方法之前执行拦截
-     */
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
-
-        HandlerMethod handlerMethod = (HandlerMethod) handler;
-        Method method = handlerMethod.getMethod();
-        SafeClick safeClick = method.getAnnotation(SafeClick.class);
-        if (safeClick == null) {
-            return true;
-        }
-        // 操作人
-        String userId = SessionHelper.getCurrentUserId();
-        if (StringUtils.isBlank(userId)) {
-            throw new AuthException("未登录!");
-        }
-        // 事件
-        String action = safeClick.event().name();
-        // 允许多长时间操作一次
-        long liveTime = safeClick.time();
-        String key = action.concat("-").concat(userId);
-        boolean installLockResult = redisService.installLockForMS(key, WebConstant.CACHE_NONE, liveTime);
-        if (installLockResult) {
-            return true;
-        }
-        log.error("<<<< {} >>>>, userId: {}, action: {}", safeClick.message(), userId, action);
-        throw new BusinessException(safeClick.message());
-    }
-}

+ 0 - 37
webchat-common/src/main/java/com/webchat/common/config/annotation/ValidateLoginInterceptor.java

@@ -1,37 +0,0 @@
-package com.webchat.common.config.annotation;
-
-import com.webchat.common.exception.AuthException;
-import com.webchat.common.helper.SessionHelper;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import java.lang.reflect.Method;
-
-/**
- * @Author: 程序员七七
- * @Date: 27.11.21 12:07 上午
- */
-public class ValidateLoginInterceptor implements HandlerInterceptor {
-
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
-        HandlerMethod handlerMethod = (HandlerMethod) handler;
-        // 获取拦截到的方法
-        Method method = handlerMethod.getMethod();
-        // 获取方法到的ValidateLogin注解
-        ValidateLogin validateLogin = method.getAnnotation(ValidateLogin.class);
-        if (validateLogin == null) {
-            // 未获取到登录鉴权注解,说明不需要拦截,直接放过
-            return true;
-        }
-        String userId = SessionHelper.getCurrentUserId();
-        if (StringUtils.isBlank(userId)) {
-            // 未登录!权限校验失败
-            throw new AuthException("未登录!");
-        }
-        return true;
-    }
-}

+ 0 - 54
webchat-common/src/main/java/com/webchat/common/config/annotation/ValidatePermissionInterceptor.java

@@ -1,54 +0,0 @@
-package com.webchat.common.config.annotation;
-
-import com.webchat.common.enums.RoleCodeEnum;
-import com.webchat.common.exception.AuthException;
-import com.webchat.common.helper.SessionHelper;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import java.lang.reflect.Method;
-
-/**
- * @Author: 程序员七七
- * @Date: 27.11.21 12:07 上午
- */
-public class ValidatePermissionInterceptor implements HandlerInterceptor {
-
-//    @Autowired
-//    private RoleService roleService;
-//
-//    @Override
-//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
-//        HandlerMethod handlerMethod = (HandlerMethod) handler;
-//        // 获取拦截到的方法
-//        Method method = handlerMethod.getMethod();
-//        // 获取方法到的RequestPermission注解
-//        ValidatePermission requestPermission = method.getAnnotation(ValidatePermission.class);
-//        if (requestPermission == null) {
-//            // 未获取到权控注解,说明不需要拦截,直接放过
-//            return true;
-//        }
-//        /***
-//         * 权限校验
-//         */
-//        if (requestPermission.role().length > 0) {
-//            RoleCodeEnum[] roleEnums = requestPermission.role();
-//            // 获取当前登录的用户ID
-//            String userId = SessionHelper.getCurrentUserId();
-//            if (StringUtils.isBlank(userId)) {
-//                // 未登录!权限校验失败
-//                throw new AuthException("未登录!");
-//            }
-//            // 一个一个校验,或者的关系:即满足任一权限则通过
-//            for (RoleCodeEnum roleEnum : roleEnums) {
-//                // 用户任一权限校验通过,则认为拥有操作权限
-//                if (roleService.hasRole(userId, roleEnum.getCode())) {
-//                    return true;
-//                }
-//            }
-//        }
-//        throw new AuthException("无权限!");
-//    }
-}

+ 0 - 58
webchat-common/src/main/java/com/webchat/common/config/configuration/WebChatWebMvcConfigurer.java

@@ -1,58 +0,0 @@
-package com.webchat.common.config.configuration;
-
-import com.webchat.common.config.annotation.SafeClickInterceptor;
-import com.webchat.common.config.annotation.ValidateLoginInterceptor;
-import com.webchat.common.config.annotation.ValidatePermissionInterceptor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/***
- * Web 拦截器配置
- **/
-@Configuration
-public class WebChatWebMvcConfigurer implements WebMvcConfigurer {
-
-    /***
-     * 注册自定义拦截器
-     * @param registry
-     */
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        /**
-         * 注册权限控制拦截器
-         */
-        registry.addInterceptor(validatePermissionInterceptor()).addPathPatterns("/api/**");
-        /**
-         * 注册登录核验拦截器
-         */
-        registry.addInterceptor(validateLoginInterceptor()).addPathPatterns("/api/**");
-        /**
-         * 防重复操作,安全点击
-         */
-        registry.addInterceptor(safeClickInterceptor()).addPathPatterns("/api/**");
-    }
-
-    /***
-     * 登录核验拦截器
-     * @return
-     */
-    @Bean
-    public ValidateLoginInterceptor validateLoginInterceptor() {
-        return new ValidateLoginInterceptor();
-    }
-    /***
-     * 权限控制拦截器
-     * @return
-     */
-    @Bean
-    public ValidatePermissionInterceptor validatePermissionInterceptor() {
-        return new ValidatePermissionInterceptor();
-    }
-
-    @Bean
-    public SafeClickInterceptor safeClickInterceptor() {
-        return new SafeClickInterceptor();
-    }
-}

+ 5 - 6
webchat-common/src/main/java/com/webchat/common/constants/CookieConstants.java

@@ -5,13 +5,12 @@ package com.webchat.common.constants;
  */
 public class CookieConstants {
 
-    /***
-     * 用户登录Cookie
-     */
-    public static final String WEB_CHAT_USER_COOKIE_KEY = "WEB_CHAT_USER_SESSION";
+    public static final String WEB_CHAT_ADMIN_USER_COOKIE_KEY = "WEB_CHAT_ADMIN_USER_COOKIE_KEY";
+
+    public static final String WEB_CHAT_CLIENT_USER_COOKIE_KEY = "WEB_CHAT_CLIENT_USER_COOKIE_KEY";
 
     /***
-     * cookie过期时间 秒为单位,5
+     * cookie过期时间 秒为单位,3
      */
-    public static final int COOKIE_OUT_TIME = 60 * 60 * 24 * 5;
+    public static final int COOKIE_OUT_TIME = 60 * 60 * 24 * 3;
 }

+ 13 - 0
webchat-common/src/main/java/com/webchat/common/enums/WalletTransTypeEnum.java

@@ -20,4 +20,17 @@ public enum WalletTransTypeEnum {
     private Integer transType;
 
     private String transTypeName;
+
+
+    public static String getTransTypeName(Integer transType) {
+        if (transType == null) {
+            return "未知";
+        }
+        for (WalletTransTypeEnum walletTransTypeEnum : WalletTransTypeEnum.values()) {
+            if (walletTransTypeEnum.getTransType().equals(transType)) {
+                return walletTransTypeEnum.getTransTypeName();
+            }
+        }
+        return "未知";
+    }
 }

+ 4 - 2
webchat-common/src/main/java/com/webchat/common/helper/SessionHelper.java

@@ -33,6 +33,8 @@ public class SessionHelper {
 
     private static final String SESSION_KEY_TASK_ID = "TASK-ID";
 
+    public static final String CURRENT_USER_ID = "CURRENT_USER_ID";
+
 
     public static void setClientUserInfo(String userId, String ip, String taskId) {
         setUserId(userId);
@@ -45,7 +47,7 @@ public class SessionHelper {
      */
     public static void setUserId(String userId) {
         if (StringUtils.isNotBlank(userId)) {
-            setAttribute(CookieConstants.WEB_CHAT_USER_COOKIE_KEY, userId);
+            setAttribute(CURRENT_USER_ID, userId);
         }
     }
 
@@ -84,7 +86,7 @@ public class SessionHelper {
      * @return
      */
     public static String getCurrentUserId() {
-        Object userIdObj = getAttribute(CookieConstants.WEB_CHAT_USER_COOKIE_KEY);
+        Object userIdObj = getAttribute(CURRENT_USER_ID);
         return userIdObj == null ? null : userIdObj.toString();
     }
 

+ 1 - 1
webchat-common/src/main/java/com/webchat/common/helper/SseEmitterHelper.java

@@ -66,7 +66,7 @@ public class SseEmitterHelper {
         sseEmitter.onCompletion(completionCallBack(biz, userId));
         sseEmitter.onError(errorCallBack(biz, userId));
         sseEmitter.onTimeout(timeoutCallBack(biz, userId));
-        log.info("创建新链接=====> biz={}, userId={}", biz, userId);
+        log.info("SSE Connection created =====> biz={}, userId={}", biz, userId);
         return sseEmitter;
     }
 

+ 0 - 30
webchat-connect/src/main/java/com/webchat/connect/config/CorsConfig.java

@@ -1,30 +0,0 @@
-package com.webchat.connect.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-
-@Configuration
-public class CorsConfig {
-
-    // 当前跨域请求最大有效时长。这里默认1天
-    private static final long MAX_AGE = 24 * 60 * 60;
-
-    private CorsConfiguration buildConfig() {
-        CorsConfiguration corsConfiguration = new CorsConfiguration();
-        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
-        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
-        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
-        corsConfiguration.setMaxAge(MAX_AGE);
-        return corsConfiguration;
-    }
-
-    @Bean
-    public CorsFilter corsFilter() {
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
-        return new CorsFilter(source);
-    }
-}

+ 0 - 14
webchat-connect/src/main/java/com/webchat/connect/config/WebSocketConfig.java

@@ -1,14 +0,0 @@
-package com.webchat.connect.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 {
-
-    @Bean
-    public ServerEndpointExporter serverEndpointExporter() {
-        return new ServerEndpointExporter();
-    }
-}

+ 0 - 97
webchat-connect/src/main/java/com/webchat/connect/websocket/ChatWebSocketEndPoint.java

@@ -1,97 +0,0 @@
-package com.webchat.connect.websocket;
-
-import com.webchat.common.enums.RedisMessageChannelTopicEnum;
-import com.webchat.common.service.RedisMessageSender;
-import com.webchat.common.util.SpringContextUtil;
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import javax.websocket.*;
-import javax.websocket.server.PathParam;
-import javax.websocket.server.ServerEndpoint;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * OnOpen 表示有浏览器链接过来的时候被调用
- * OnClose 表示浏览器发出关闭请求的时候被调用
- * OnMessage 表示浏览器发消息的时候被调用
- * OnError 表示有错误发生,比如网络断开了等等
- */
-@Data
-@Slf4j
-@Component
-@ServerEndpoint("/connect-service/ws/chat/{userId}")
-public class ChatWebSocketEndPoint{
-
-    /**
-     * 在线人数
-     */
-    public static int onlineNumber = 0;
-
-    /**
-     * 以用户的Id作为key,WebSocket为对象保存起来
-     */
-    public static Map<String, ChatWebSocketEndPoint> clients = new ConcurrentHashMap<String, ChatWebSocketEndPoint>();
-
-    /**
-     * 会话
-     */
-    private Session session;
-
-    /**
-     * 用户ID
-     */
-    private String userId;
-
-    /**
-     * 建立连接
-     *
-     * @param session
-     */
-    @OnOpen
-    public void onOpen(@PathParam("userId") String userId, Session session) {
-        this.onlineNumber++;
-        this.userId = userId;
-        this.session = session;
-        clients.put(userId, this);
-        log.info("onOpen success. sessionId:{}, userId:{}, online user count:{}", session.getId(), userId, onlineNumber);
-    }
-
-    @OnError
-    public void onError(Session session, Throwable error) {
-        log.info("服务端发生了错误, error message:{}", error.getMessage());
-    }
-
-    /**
-     * 连接关闭
-     */
-    @OnClose
-    public void onClose() {
-        this.onlineNumber--;
-        this.clients.remove(userId);
-        log.info("onClose success! online user count:P{}", this.onlineNumber);
-    }
-
-    /**
-     * 收到客户端的消息
-     *
-     * @param message 消息
-     * @param session 会话
-     */
-    @OnMessage
-    public void onMessage(String message, Session session) {
-        if ("ping".equals(message)) {
-            // 心跳检测
-            clients.get(userId).session.getAsyncRemote().sendText("ok");
-            return;
-        }
-        /**
-         * 基于redis发布订阅模式的分布式WebSocketSession共享问题解决方案
-         * 发布消息事件到Chat Topic
-         */
-        RedisMessageSender redisMessageSender = SpringContextUtil.getBean(RedisMessageSender.class);
-        redisMessageSender.sendMessage(RedisMessageChannelTopicEnum.CHAT.getChannel(), message);
-    }
-}

+ 28 - 0
webchat-connect/src/main/java/com/webchat/connect/websocket/config/WebSocketConnectConfig.java

@@ -0,0 +1,28 @@
+package com.webchat.connect.websocket.config;
+
+import com.webchat.connect.websocket.handler.ChatWebSocketEndPointHandler;
+import com.webchat.connect.websocket.interceptor.ChatWebSocketEndPointInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+@Configuration
+@EnableWebSocket
+public class WebSocketConnectConfig implements WebSocketConfigurer {
+
+    private static final String CHAT_WEBSOCKET_PATH = "/connect-service/ws/chat/{userId}";
+
+    @Override
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+        registry.addHandler(chatWebSocketEndPointHandler(), CHAT_WEBSOCKET_PATH)
+                .setAllowedOrigins("*")
+                .addInterceptors(new ChatWebSocketEndPointInterceptor()); ;
+    }
+
+    @Bean
+    public ChatWebSocketEndPointHandler chatWebSocketEndPointHandler() {
+        return new ChatWebSocketEndPointHandler();
+    }
+}

+ 68 - 0
webchat-connect/src/main/java/com/webchat/connect/websocket/handler/ChatWebSocketEndPointHandler.java

@@ -0,0 +1,68 @@
+package com.webchat.connect.websocket.handler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+public class ChatWebSocketEndPointHandler extends TextWebSocketHandler {
+
+    private static Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
+
+    /**
+     * 连接建立
+     *
+     * @param session
+     * @throws Exception
+     */
+    @Override
+    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
+        // 获取路径参数
+        Map<String, Object> attributes = session.getAttributes();
+        String userId = (String) attributes.get("userId");
+        sessions.put(userId, session);
+        log.info("Chat WebSocket connection ====> userId:{}, sessionId:{}", userId, session.getId());
+    }
+
+    /**
+     * 收到消息
+     *
+     * @param session
+     * @param message
+     * @throws Exception
+     */
+    @Override
+    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+        String payload = message.getPayload();
+        System.out.println("Chat WebSocket Connection Received message: " + payload);
+
+    }
+
+    /**
+     * 断开连接
+     *
+     * @param session
+     * @param status
+     * @throws Exception
+     */
+    @Override
+    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
+        System.out.println("Chat WebSocket Connection closed: " + session.getId());
+    }
+
+    public void sendMessage(WebSocketSession session, String message) {
+        if (session != null && session.isOpen()) {
+            try {
+                session.sendMessage(new TextMessage(message));
+            } catch (IOException e) {
+                log.error("Chat WebSocket Connection sendMessage error. message:{}", message, e);
+            }
+        }
+    }
+}

+ 26 - 0
webchat-connect/src/main/java/com/webchat/connect/websocket/interceptor/ChatWebSocketEndPointInterceptor.java

@@ -0,0 +1,26 @@
+package com.webchat.connect.websocket.interceptor;
+
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.http.server.ServletServerHttpRequest;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import java.util.Map;
+
+public class ChatWebSocketEndPointInterceptor implements HandshakeInterceptor {
+
+    @Override
+    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
+        String path = request.getURI().getPath();
+        String userId = path.split("/")[4];
+        // 将userId存储到session属性中
+        attributes.put("userId", userId);
+        return true;
+    }
+
+    @Override
+    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
+        // 在这里处理握手完成后的逻辑
+    }
+}

+ 5 - 1
webchat-domain/src/main/java/com/webchat/domain/vo/response/UserWalletDetailResponseVO.java

@@ -13,11 +13,15 @@ import java.util.Date;
 public class UserWalletDetailResponseVO {
 
     private UserBaseResponseInfoVO user;
-    private String event;
+    private String userId;
+    private Integer event;
+    private String eventName;
     private Integer type;
+    private String typeName;
     private String money;
     private Long time;
 
+
     public String getTimeStr() {
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         return simpleDateFormat.format(new Date(time));

+ 2 - 0
webchat-pay/src/main/java/com/webchat/pay/WebchatPayApplication.java

@@ -3,9 +3,11 @@ package com.webchat.pay;
 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
+@EnableFeignClients("com.webchat.rmi")
 public class WebchatPayApplication {
 
     public static void main(String[] args) {

+ 30 - 0
webchat-pay/src/main/java/com/webchat/pay/controller/PaymentServiceController.java

@@ -0,0 +1,30 @@
+package com.webchat.pay.controller;
+
+import com.webchat.common.bean.APIPageResponseBean;
+import com.webchat.common.bean.APIResponseBean;
+import com.webchat.domain.vo.response.UserWalletDetailResponseVO;
+import com.webchat.pay.service.PaymentService;
+import com.webchat.rmi.pay.PaymentServiceClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+
+
+@RestController
+public class PaymentServiceController implements PaymentServiceClient {
+
+    @Autowired
+    private PaymentService paymentService;
+
+    @Override
+    public APIResponseBean<BigDecimal> getBalance(String userId) {
+        return null;
+    }
+
+    @Override
+    public APIPageResponseBean<UserWalletDetailResponseVO> page(Integer transType, Integer eventType, String userId, Integer pageNo, Integer pageSize) {
+
+        return paymentService.page(transType, eventType, userId, pageNo, pageSize);
+    }
+}

+ 18 - 0
webchat-pay/src/main/java/com/webchat/pay/repository/dao/IUserWalletDAO.java

@@ -0,0 +1,18 @@
+package com.webchat.pay.repository.dao;
+
+import com.webchat.pay.repository.entity.UserWalletEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.math.BigDecimal;
+
+
+@Repository
+public interface IUserWalletDAO extends JpaSpecificationExecutor<UserWalletEntity>,
+        JpaRepository<UserWalletEntity, Long> {
+
+    @Query(value = "select sum(uw.transType * uw.money) from UserWalletEntity uw where uw.userId = :userId")
+    BigDecimal findBalanceByUserId(String userId);
+}

+ 28 - 0
webchat-pay/src/main/java/com/webchat/pay/repository/entity/BaseEntity.java

@@ -0,0 +1,28 @@
+package com.webchat.pay.repository.entity;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.MappedSuperclass;
+import jakarta.persistence.PreUpdate;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 基础实体类
+ */
+@MappedSuperclass
+@Data
+public class BaseEntity extends SimpleBaseEntity implements Serializable {
+
+    @Column(name = "update_by")
+    private String updateBy;
+
+    @Column(name = "update_date")
+    private Date updateDate;
+
+    @PreUpdate
+    public void preUpdate() {
+        this.updateDate = new Date();
+    }
+}

+ 36 - 0
webchat-pay/src/main/java/com/webchat/pay/repository/entity/SimpleBaseEntity.java

@@ -0,0 +1,36 @@
+package com.webchat.pay.repository.entity;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.MappedSuperclass;
+import jakarta.persistence.PrePersist;
+import jakarta.persistence.Version;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 基础实体类
+ */
+@MappedSuperclass
+@Data
+public class SimpleBaseEntity implements Serializable {
+
+    @Column(name = "create_by")
+    private String createBy;
+
+    @Column(name = "create_date")
+    private Date createDate;
+
+    @Version
+    @Column(name = "version")
+    private Integer version;
+
+    @PrePersist
+    public void prePersist() {
+        Date now = new Date();
+        if (this.createDate == null) {
+            this.createDate = now;
+        }
+    }
+}

+ 60 - 0
webchat-pay/src/main/java/com/webchat/pay/repository/entity/UserWalletEntity.java

@@ -0,0 +1,60 @@
+package com.webchat.pay.repository.entity;
+
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@Entity
+@Table(name = "web_chat_user_wallet")
+public class UserWalletEntity {
+
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 事件类型
+     */
+    @Column(name = "trans_event")
+    private Integer transEvent;
+
+    /**
+     * 收入 / 支出
+     */
+    @Column(name = "trans_type")
+    private Integer transType;
+
+    /**
+     * 当前用户
+     */
+    @Column(name = "user_id")
+    private String userId;
+
+    /**
+     * 目前用户
+     */
+    @Column(name = "target_user_id")
+    private String targetUserId;
+
+    /**
+     * 总金额
+     */
+    @Column(name = "money")
+    private BigDecimal money;
+
+    /**
+     * 流转时间
+     */
+    @Column(name = "trans_date")
+    private Date transDate;
+}

+ 85 - 0
webchat-pay/src/main/java/com/webchat/pay/service/PaymentService.java

@@ -0,0 +1,85 @@
+package com.webchat.pay.service;
+
+
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import com.webchat.common.bean.APIPageResponseBean;
+import com.webchat.common.enums.WalletTransEventEnum;
+import com.webchat.common.enums.WalletTransTypeEnum;
+import com.webchat.domain.vo.response.UserBaseResponseInfoVO;
+import com.webchat.domain.vo.response.UserWalletDetailResponseVO;
+import com.webchat.pay.repository.dao.IUserWalletDAO;
+import com.webchat.pay.repository.entity.UserWalletEntity;
+import com.webchat.rmi.user.UserServiceClient;
+import jakarta.persistence.criteria.Predicate;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Service
+public class PaymentService {
+
+    @Autowired
+    private IUserWalletDAO userWalletDAO;
+
+    @Autowired
+    private UserService userService;
+
+
+    public APIPageResponseBean<UserWalletDetailResponseVO> page(Integer transType, Integer eventType, String userId,
+                                                           Integer pageNo, Integer pageSize) {
+        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Direction.DESC, "id"));
+        Specification<UserWalletEntity> specification = this.createSpecification(transType, eventType, userId);
+        Page<UserWalletEntity> userWalletEntityPage = userWalletDAO.findAll(specification, pageable);
+
+        List<UserWalletDetailResponseVO> userWalletDetailResponseVOS = new ArrayList<>();
+        List<UserWalletEntity> userWalletEntities = userWalletEntityPage.getContent();
+        if (CollectionUtils.isNotEmpty(userWalletEntities)) {
+            userWalletDetailResponseVOS = userWalletEntities.stream().map(this::convert).collect(Collectors.toList());
+            Set<String> userIdSet = userWalletEntities.stream().map(UserWalletEntity::getUserId).collect(Collectors.toSet());
+            Map<String, UserBaseResponseInfoVO> userMap = userService.batchGet(userIdSet);
+            userWalletDetailResponseVOS.forEach(uw -> uw.setUser(userMap.get(uw.getUserId())));
+        }
+        return APIPageResponseBean.success(pageNo, pageSize, userWalletEntityPage.getTotalElements(), userWalletDetailResponseVOS);
+    }
+
+    private UserWalletDetailResponseVO convert(UserWalletEntity entity) {
+        UserWalletDetailResponseVO vo = new UserWalletDetailResponseVO();
+        vo.setUserId(entity.getUserId());
+        vo.setEvent(entity.getTransEvent());
+        vo.setType(entity.getTransType());
+        vo.setMoney(entity.getMoney().toString());
+        vo.setTypeName(WalletTransTypeEnum.getTransTypeName(entity.getTransType()));
+        vo.setEventName(WalletTransEventEnum.getEventName(entity.getTransEvent()));
+        vo.setTime(entity.getTransDate() != null ? entity.getTransDate().getTime() : null);
+        return vo;
+    }
+
+    private Specification<UserWalletEntity> createSpecification(Integer transType, Integer eventType, String userId) {
+        return  ((root, criteriaQuery, criteriaBuilder) -> {
+            List<Predicate> predicates = new ArrayList<>();
+            if (transType != null) {
+                predicates.add(criteriaBuilder.equal(root.get("transType").as(Integer.class), transType));
+            }
+            if (eventType != null) {
+                predicates.add(criteriaBuilder.equal(root.get("eventType").as(Integer.class), eventType));
+            }
+            if (StringUtils.isNotBlank(userId)) {
+                predicates.add(criteriaBuilder.equal(root.get("userId").as(String.class), userId));
+            }
+            Predicate[] pre = new Predicate[predicates.size()];
+            criteriaQuery.where(predicates.toArray(pre));
+            return criteriaQuery.getRestriction();
+        });
+    }
+}

+ 35 - 0
webchat-pay/src/main/java/com/webchat/pay/service/UserService.java

@@ -0,0 +1,35 @@
+package com.webchat.pay.service;
+
+import com.webchat.common.bean.APIResponseBean;
+import com.webchat.common.bean.APIResponseBeanUtil;
+import com.webchat.domain.vo.response.UserBaseResponseInfoVO;
+import com.webchat.rmi.user.UserServiceClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+@Slf4j
+@Service
+public class UserService {
+
+
+    @Autowired
+    private UserServiceClient userServiceClient;
+
+
+    public Map<String, UserBaseResponseInfoVO> batchGet(Set<String> userIds) {
+        APIResponseBean<Map<String, UserBaseResponseInfoVO>> responseBean = userServiceClient.batchGet(userIds);
+        if (APIResponseBeanUtil.isOk(responseBean)) {
+            return responseBean.getData();
+        }
+        // TODO
+        log.error("UserServiceClient.batchGet error: {}", responseBean);
+        return Collections.emptyMap();
+    }
+
+
+}

+ 0 - 17
webchat-remote/src/main/java/com/webchat/rmi/pay/PayServiceClient.java

@@ -1,17 +0,0 @@
-package com.webchat.rmi.pay;
-
-import com.webchat.common.bean.APIResponseBean;
-import org.springframework.cloud.openfeign.FeignClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-
-import java.math.BigDecimal;
-
-@FeignClient(name = "webchat-pay-service")
-public interface PayServiceClient {
-
-
-    @GetMapping("/pay/wallet/balance/{userId}")
-    APIResponseBean<BigDecimal> getBalance(@PathVariable String userId);
-
-}

+ 31 - 0
webchat-remote/src/main/java/com/webchat/rmi/pay/PaymentServiceClient.java

@@ -0,0 +1,31 @@
+package com.webchat.rmi.pay;
+
+import com.webchat.common.bean.APIPageResponseBean;
+import com.webchat.common.bean.APIResponseBean;
+import com.webchat.common.config.annotation.ValidatePermission;
+import com.webchat.domain.vo.response.UserWalletDetailResponseVO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.math.BigDecimal;
+
+@FeignClient(name = "webchat-pay-service")
+public interface PaymentServiceClient {
+
+
+    @GetMapping("/pay-service/wallet/balance/{userId}")
+    APIResponseBean<BigDecimal> getBalance(@PathVariable String userId);
+
+
+    @ValidatePermission
+    @GetMapping("/pay-service/wallet/page")
+    APIPageResponseBean<UserWalletDetailResponseVO> page(
+            @RequestParam(value = "transType", required = false) Integer transType,
+            @RequestParam(value = "eventType", required = false) Integer eventType,
+            @RequestParam(value = "userId", required = false) String userId,
+            @RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
+            @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize);
+
+}

+ 14 - 0
webchat-remote/src/main/java/com/webchat/rmi/user/UserServiceClient.java

@@ -17,6 +17,9 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.Map;
+import java.util.Set;
+
 /**
  * @Author 程序员七七
  * @webSite https://www.coderutil.com
@@ -89,4 +92,15 @@ public interface UserServiceClient {
      */
     @PostMapping("/user-service/account/createPublicAccount")
     APIResponseBean createPublicAccount(@RequestBody CreatePublicAccountRequestVO requestPram);
+
+
+    /**
+     * 批量查询用户详情
+     * 底层走Redis
+     *
+     * @param userIds
+     * @return
+     */
+    @PostMapping("/user-service/account/batchGet")
+    APIResponseBean<Map<String, UserBaseResponseInfoVO>> batchGet(@RequestBody Set<String> userIds);
 }

+ 9 - 0
webchat-user/src/main/java/com/webchat/user/controller/UserServiceController.java

@@ -15,6 +15,9 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Map;
+import java.util.Set;
+
 /**
  * @Author 程序员七七
  * @webSite https://www.coderutil.com
@@ -62,4 +65,10 @@ public class UserServiceController implements UserServiceClient {
         userService.createPublicAccount(requestPram);
         return APIResponseBeanUtil.success("创建成功");
     }
+
+    @Override
+    public APIResponseBean<Map<String, UserBaseResponseInfoVO>> batchGet(@RequestBody Set<String> userIds) {
+        Map<String, UserBaseResponseInfoVO> map = userService.batchGet(userIds);
+        return APIResponseBeanUtil.success(map);
+    }
 }

+ 11 - 76
webchat-user/src/main/java/com/webchat/user/service/UserService.java

@@ -88,6 +88,17 @@ public class UserService {
         return null;
     }
 
+    /**
+     * 批量走redis查询用户详情
+     *
+     * @param userIds
+     * @return
+     */
+    public Map<String, UserBaseResponseInfoVO> batchGet(Set<String> userIds) {
+
+        return this.batchGetUserInfoFromCache(new ArrayList<>(userIds));
+    }
+
     public APIPageResponseBean<UserBaseResponseInfoVO> page(String userId, Integer roleCode, String userName, String mobile,
                                                             int pageNo, int pageSize) {
 
@@ -123,34 +134,6 @@ public class UserService {
         });
     }
 
-
-    /**
-     * 用户登录 - 登录成功返回用户基本信息
-     * @param mobile
-     * @param password
-     * @return
-     */
-    public UserBaseResponseInfoVO login(String mobile, String password) {
-        if (!hasUserInfo(mobile)) {
-            throw new BusinessException(APIErrorCommonEnum.USER_NOT_FOUND);
-        }
-        UserEntity userEntity = userDAO.findByMobileAndPassword(mobile, md5Pwd(password));
-        if (userEntity == null) {
-            throw new BusinessException("密码验证失败");
-        }
-        if (userEntity.getRoleCode().equals(RoleCodeEnum.BLACK.getCode())) {
-            throw new BusinessException("账号异常!联系管理员解封");
-        }
-        UserBaseResponseInfoVO user = userLogin(userEntity);
-        return user;
-    }
-
-    private UserBaseResponseInfoVO userLogin(UserEntity userEntity) {
-        // 创建用户登录会话数据
-        this.createLoginSession(userEntity.getUserId());
-        return this.convertBaseVo(userEntity);
-    }
-
     /**
      * 用户注册 - 注册成功自动登录
      * @param photo
@@ -442,28 +425,6 @@ public class UserService {
     }
 
     /**
-     * 退出登录
-     */
-    public void logout() {
-        String userId = getLoginCurrentUserId();
-        // 清理登录Session
-        Cookie[] cookies = request.getCookies();
-        for(Cookie cookie : cookies) {
-            if (CookieConstants.WEB_CHAT_USER_COOKIE_KEY.equals(cookie.getName())) {
-                cookie.setValue(null);
-                cookie.setMaxAge(0);
-                cookie.setPath("/");
-                response.addCookie(cookie);
-            }
-        }
-        // 清理缓存
-        if (StringUtils.isNotBlank(userId)) {
-            String sessionKey = RedisKeyEnum.USER_SESSION_PREFIX.getKey(MD5Utils.md5(userId));
-            redisService.remove(sessionKey);
-        }
-    }
-
-    /**
      * 注册用户到数据库
      *
      * @param userName
@@ -741,27 +702,6 @@ public class UserService {
     }
 
     /**
-     * 创建用户登录会话数据
-     * @param userId
-     */
-    private void createLoginSession(String userId) {
-        String sessionId = MD5Utils.md5(userId);
-        // sessionId:UserId缓存,用的String数据结构存储,有效期3天
-        String sessionKey = RedisKeyEnum.USER_SESSION_PREFIX.getKey(sessionId);
-        redisService.set(sessionKey, userId, RedisKeyEnum.USER_SESSION_PREFIX.getExpireTime());
-        // 种浏览器Cookie
-        Cookie cookie = new Cookie(CookieConstants.WEB_CHAT_USER_COOKIE_KEY, sessionId);
-        cookie.setPath("/");
-        cookie.setMaxAge(CookieConstants.COOKIE_OUT_TIME);
-        response.addCookie(cookie);
-    }
-
-    public String getUserIdBySessionId(String sessionId) {
-        String sessionKey = RedisKeyEnum.USER_SESSION_PREFIX.getKey(sessionId);
-        return redisService.get(sessionKey);
-    }
-
-    /**
      * 批量查询用户缓存
      *
      * @param userIdList
@@ -825,11 +765,6 @@ public class UserService {
         return userBaseResponseInfoVO;
     }
 
-    public String getUserLoginCookie(String userId) {
-        String sessionId = MD5Utils.md5(userId);
-        return CookieConstants.WEB_CHAT_USER_COOKIE_KEY.concat("=").concat(sessionId);
-    }
-
     public static UserBaseResponseInfoVO convertBaseVo(UserEntity entity) {
         if (entity == null) {
             return null;