Browse Source

【第一版开发】
1.优化Assert工具类代码
2.优化Token凭据的代码生成逻辑
3.移除无效代码
4.增加缓存的使用,优化系统性能

ChenYL 9 months ago
parent
commit
5d3d1ab071
27 changed files with 254 additions and 206 deletions
  1. 1 0
      README.md
  2. 0 1
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/UserServiceImpl.java
  3. 3 0
      data-easy/src/main/java/com/dataeasy/server/common/utils/Assert.java
  4. 62 0
      data-easy/src/main/java/com/dataeasy/server/constant/CacheNameConstant.java
  5. 8 0
      data-easy/src/main/java/com/dataeasy/server/core/aop/GlobalExceptionHandler.java
  6. 7 3
      data-easy/src/main/java/com/dataeasy/server/core/config/BizProperties.java
  7. 16 0
      data-easy/src/main/java/com/dataeasy/server/core/config/CacheConfig.java
  8. 1 1
      data-easy/src/main/java/com/dataeasy/server/core/config/FeignConfig.java
  9. 20 21
      data-easy/src/main/java/com/dataeasy/server/core/interceptor/AuthInterceptor.java
  10. 2 2
      data-easy/src/main/java/com/dataeasy/server/service/controller/DataController.java
  11. 2 1
      data-easy/src/main/java/com/dataeasy/server/service/controller/SubscriptionController.java
  12. 0 30
      data-easy/src/main/java/com/dataeasy/server/service/controller/TokenController.java
  13. 2 1
      data-easy/src/main/java/com/dataeasy/server/service/controller/UserController.java
  14. 0 38
      data-easy/src/main/java/com/dataeasy/server/service/manager/ICacheManager.java
  15. 1 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/IDataManager.java
  16. 1 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/ISubscriptionManager.java
  17. 3 2
      data-easy/src/main/java/com/dataeasy/server/service/manager/ITokenManager.java
  18. 9 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/IUserManager.java
  19. 13 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/DataManagerImpl.java
  20. 3 3
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/OrderManagerImpl.java
  21. 14 25
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/SubscriptionManagerImpl.java
  22. 38 9
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/TokenManagerImpl.java
  23. 29 3
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/UserManagerImpl.java
  24. 8 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/WxManagerImpl.java
  25. 10 4
      data-easy/src/main/java/com/dataeasy/server/task/IpoStockTask.java
  26. 0 57
      data-easy/src/main/java/com/dataeasy/server/utiis/TokenUtils.java
  27. 1 0
      product-hunt/src/main/java/com/producthunt/server/core/aop/GlobalExceptionHandler.java

+ 1 - 0
README.md

@@ -26,4 +26,5 @@
 * [GraphQL 入门看这篇就够了](https://www.freecodecamp.org/chinese/news/a-detailed-guide-to-graphql/)
 * [Spring AI Prompt 提示模板:创建提示的实战指南](https://www.panziye.com/back/14793.html)
 * [Spring 项目接入 DeepSeek,分享两种超简单的方式!](https://zhuanlan.zhihu.com/p/23328349583)
+* [【SpringBoot教程】SpringBoot整合Caffeine本地缓存及Spring Cache注解的使用](https://blog.csdn.net/weixin_48235955/article/details/145765653)
 

+ 0 - 1
data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/UserServiceImpl.java

@@ -102,7 +102,6 @@ public class UserServiceImpl implements IUserService {
         updateUser.setId(userId);
         List<String> forceUpdateProperties = new ArrayList<>();
         forceUpdateProperties.add("maOpenId");
-        forceUpdateProperties.add("mp_open_id");
         userMapper.updateByPrimaryKeySelectiveForce(updateUser, forceUpdateProperties);
     }
 }

+ 3 - 0
data-easy/src/main/java/com/dataeasy/server/common/utils/Assert.java

@@ -45,6 +45,9 @@ public class Assert {
         if (Objects.isNull(object)) {
             throw new BusinessException(errorMsg);
         }
+        if (object instanceof String && ((String) object).isBlank()) {
+            throw new BusinessException(errorMsg);
+        }
     }
 
     /**

+ 62 - 0
data-easy/src/main/java/com/dataeasy/server/constant/CacheNameConstant.java

@@ -0,0 +1,62 @@
+package com.dataeasy.server.constant;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/3/17 12:48
+ * @description 缓存名称常量
+ */
+public class CacheNameConstant {
+
+    /**
+     * 用户信息
+     */
+    public static final String USER = "user";
+
+    /**
+     * 用户信息VO
+     */
+    public static final String USER_VO = "userVO";
+
+    /**
+     * 订阅源列表
+     */
+    public static final String SUBSCRIPTION_SOURCE_LIST = "subscriptionSourceList";
+
+    /**
+     * 订阅源信息
+     */
+    public static final String SUBSCRIPTION_SOURCE = "subscriptionSource";
+
+    /**
+     * 用户的订阅源配置列表
+     */
+    public static final String SUBSCRIPTION_USER_CONFIG_LIST = "subscriptionUserConfigList";
+
+    /**
+     * 新债数据列表
+     */
+    public static final String DATA_IPO_BOND_LIST = "dataIpoBondList";
+
+    /**
+     * 新股数据列表
+     */
+    public static final String DATA_IPO_STOCK_LIST = "dataIpoStockList";
+
+    /**
+     * ProductHunt热榜数据列表
+     */
+    public static final String DATA_PRODUCT_HUNT_POST_LIST = "dataProductHuntPostList";
+
+    /**
+     * 大乐透数据列表
+     */
+    public static final String DATA_DA_LE_TOU_LIST = "dataDaLeTouList";
+
+    /**
+     * 双色球数据列表
+     */
+    public static final String DATA_SHUANG_SE_QIU_LIST = "dataShuangSeQiuList";
+
+
+}

+ 8 - 0
data-easy/src/main/java/com/dataeasy/server/core/aop/GlobalExceptionHandler.java

@@ -11,6 +11,7 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.validation.ObjectError;
 import org.springframework.web.HttpRequestMethodNotSupportedException;
 import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.MissingServletRequestParameterException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
@@ -43,6 +44,7 @@ public class GlobalExceptionHandler {
      */
     @ExceptionHandler(LoginException.class)
     public ResponseEntity<Object> loginExceptionHandler(LoginException e) {
+        log.error(e.getMessage(), e);
         return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(JsonResponse.fail(e.getMessage()));
     }
 
@@ -77,6 +79,12 @@ public class GlobalExceptionHandler {
         return JsonResponse.fail(String.format("请求方法不支持,异常原因:%s", e.getMessage()));
     }
 
+    @ExceptionHandler(MissingServletRequestParameterException.class)
+    public JsonResponse missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
+        log.error("全局异常处理:请求参数异常", e);
+        return JsonResponse.fail(String.format("全局异常处理:请求参数异常:%s", e.getMessage()));
+    }
+
     @ExceptionHandler(HttpMessageNotReadableException.class)
     public JsonResponse httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
         log.error("全局异常处理:请求参数格式错误", e);

+ 7 - 3
data-easy/src/main/java/com/dataeasy/server/core/config/BizConfig.java → data-easy/src/main/java/com/dataeasy/server/core/config/BizProperties.java

@@ -1,15 +1,19 @@
 package com.dataeasy.server.core.config;
 
 import lombok.Data;
-import lombok.Getter;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
 
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 系统业务 配置类
+ * @date 2025/2/28 11:25
+ */
 @Data
 @Configuration
 @ConfigurationProperties(prefix = "biz")
-public class BizConfig {
+public class BizProperties {
 
     /**
      * 生成token的密钥

+ 16 - 0
data-easy/src/main/java/com/dataeasy/server/core/config/CacheConfig.java

@@ -2,6 +2,8 @@ package com.dataeasy.server.core.config;
 
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.Caffeine;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.caffeine.CaffeineCacheManager;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -25,4 +27,18 @@ public class CacheConfig {
     public Cache<String, AtomicInteger> orderNoCache() {
         return Caffeine.newBuilder().expireAfterWrite(3, TimeUnit.SECONDS).build();
     }
+
+    @Bean("caffeineCacheManager")
+    public CacheManager cacheManager() {
+        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
+        cacheManager.setCaffeine(Caffeine.newBuilder()
+                // 设置过期时间,
+                .expireAfterAccess(1, TimeUnit.HOURS)
+                // 初始化缓存空间大小
+                .initialCapacity(100)
+                // 最大的缓存条数
+                .maximumSize(500)
+        );
+        return cacheManager;
+    }
 }

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/core/config/FeignConfig.java

@@ -26,7 +26,7 @@ import feign.codec.Decoder;
 public class FeignConfig {
 
     @Autowired
-    private BizConfig bizConfig;
+    private BizProperties bizProperties;
 
 //    @Bean("myInterceptor")
 //    public RequestInterceptor requestInterceptor() {

+ 20 - 21
data-easy/src/main/java/com/dataeasy/server/core/interceptor/AuthInterceptor.java

@@ -1,22 +1,21 @@
 package com.dataeasy.server.core.interceptor;
 
-import com.auth0.jwt.interfaces.Claim;
+import java.util.Objects;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+
 import com.dataeasy.server.atomic.entity.User;
-import com.dataeasy.server.atomic.service.IUserService;
 import com.dataeasy.server.common.exception.LoginException;
-import com.dataeasy.server.common.utils.Assert;
-import com.dataeasy.server.utiis.TokenUtils;
+import com.dataeasy.server.service.manager.ITokenManager;
+import com.dataeasy.server.service.manager.IUserManager;
 import com.dataeasy.server.utiis.UserUtils;
+
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import java.util.Map;
-import java.util.Objects;
 
 /**
  * @author ChenYL
@@ -30,7 +29,10 @@ import java.util.Objects;
 public class AuthInterceptor implements HandlerInterceptor {
 
     @Autowired
-    private IUserService userService;
+    private IUserManager userManager;
+
+    @Autowired
+    private ITokenManager tokenManager;
 
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
@@ -43,19 +45,16 @@ public class AuthInterceptor implements HandlerInterceptor {
         }
 
         // token解析获取用户ID
-        Long currentUserId = null;
-        try {
-            Map<String, Claim> verify = TokenUtils.verify(token);
-            currentUserId = verify.get("userId").asLong();
-        } catch (Exception e) {
-            log.error("登录校验异常,token:{}", token, e);
-            throw LoginException.fail("登录校验异常");
+        Long currentUserId = tokenManager.getUserIdByToken(token);
+        if (Objects.isNull(currentUserId)) {
+            log.warn("登录校验异常,token中不存在有效的用户信息,token:{}", token);
+            throw LoginException.fail("登录校验异常,token中不存在有效的用户信息");
         }
 
         // 校验系统中是否存在该用户
-        User currentUser = userService.getById(currentUserId);
+        User currentUser = userManager.getByIdWithCache(currentUserId);
         if (Objects.isNull(currentUser)) {
-            throw LoginException.fail("不存在的用户,请重新登录");
+            throw LoginException.fail("不存在的用户,请尝试重新登录");
         }
 
         // 把用户信息设置如入上下文

+ 2 - 2
data-easy/src/main/java/com/dataeasy/server/service/controller/DataController.java

@@ -69,8 +69,8 @@ public class DataController {
     /**
      * 查询ProductHunt热榜数据
      */
-    @GetMapping("/queryProductHunt")
+    @GetMapping("/queryProductHuntPost")
     public List<ProductHuntPostVO> queryProductHunt(@RequestParam @NotBlank(message = "榜单日期不能为空") String rankDate) {
-        return dataManager.queryProductHunt(rankDate);
+        return dataManager.queryProductHuntPost(rankDate);
     }
 }

+ 2 - 1
data-easy/src/main/java/com/dataeasy/server/service/controller/SubscriptionController.java

@@ -2,6 +2,7 @@ package com.dataeasy.server.service.controller;
 
 import java.util.List;
 
+import com.dataeasy.server.utiis.UserUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -56,7 +57,7 @@ public class SubscriptionController {
      */
     @GetMapping("/querySubscriptionUserConfig")
     public List<SubscriptionUserConfigVO> querySubscriptionUserConfig() {
-        return subscriptionManager.querySubscriptionUserConfig();
+        return subscriptionManager.querySubscriptionUserConfig(UserUtils.getCurrentUserId());
     }
 
     /**

+ 0 - 30
data-easy/src/main/java/com/dataeasy/server/service/controller/TokenController.java

@@ -1,30 +0,0 @@
-package com.dataeasy.server.service.controller;
-
-import com.dataeasy.server.service.manager.ITokenManager;
-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;
-
-/**
- * @author myou
- * @version 1.0.0
- * @date 2024/12/28 21:28
- * @description JWT controller
- */
-@RestController
-@RequestMapping("/token")
-public class TokenController {
-
-    @Autowired
-    private ITokenManager tokenManager;
-
-    /**
-     * 刷新token
-     * @return
-     */
-    @GetMapping("/refreshToken")
-    public String refreshToken() {
-        return tokenManager.refreshToken();
-    }
-}

+ 2 - 1
data-easy/src/main/java/com/dataeasy/server/service/controller/UserController.java

@@ -4,6 +4,7 @@ import com.dataeasy.server.pojo.user.LoginRequest;
 import com.dataeasy.server.pojo.user.NicknameRequest;
 import com.dataeasy.server.pojo.user.UserInfoVO;
 import com.dataeasy.server.service.manager.IUserManager;
+import com.dataeasy.server.utiis.UserUtils;
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -42,7 +43,7 @@ public class UserController {
      */
     @GetMapping("/queryUserInfo")
     public UserInfoVO queryUserInfo() {
-        return userManager.queryUserInfo();
+        return userManager.queryUserInfo(UserUtils.getCurrentUserId());
     }
 
     /**

+ 0 - 38
data-easy/src/main/java/com/dataeasy/server/service/manager/ICacheManager.java

@@ -1,38 +0,0 @@
-package com.dataeasy.server.service.manager;
-
-/**
- * @author tyuio
- * @version 1.0.0
- * @date 2025/3/11 11:14
- * @description 缓存服务类
- */
-public interface ICacheManager {
-
-    /**
-     * 添加缓存
-     *
-     * @param cacheName 缓存名称
-     * @param key 缓存key
-     * @param value 缓存值
-     */
-    void put(String cacheName, String key, Object value) ;
-
-    /**
-     * 获取缓存(泛型)
-     *
-     * @param cacheName 缓存名称
-     * @param key 缓存key
-     * @param clazz 缓存类
-     * @param <T> 返回值泛型
-     * @return
-     */
-    <T> T get(String cacheName, String key, Class<T> clazz);
-
-    /**
-     * 失效缓存
-     *
-     * @param cacheName 缓存名称
-     * @param key 缓存key
-     */
-     void evict(String cacheName, String key);
-}

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/service/manager/IDataManager.java

@@ -46,5 +46,5 @@ public interface IDataManager {
      * 查询ProductHunt热榜数据
      * @param rankDate 榜单日期
      */
-    List<ProductHuntPostVO> queryProductHunt(String rankDate);
+    List<ProductHuntPostVO> queryProductHuntPost(String rankDate);
 }

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/service/manager/ISubscriptionManager.java

@@ -30,7 +30,7 @@ public interface ISubscriptionManager {
     /**
      * 查询用户已订阅的订阅源
      */
-    List<SubscriptionUserConfigVO> querySubscriptionUserConfig();
+    List<SubscriptionUserConfigVO> querySubscriptionUserConfig(Long userId);
 
     /**
      * 修改消息推送选项

+ 3 - 2
data-easy/src/main/java/com/dataeasy/server/service/manager/ITokenManager.java

@@ -16,8 +16,9 @@ public interface ITokenManager {
     String createToken(Long userId);
 
     /**
-     * 刷新token
+     * 从token中获取用户ID
+     * @param token
      * @return
      */
-    String refreshToken();
+    Long getUserIdByToken(String token);
 }

+ 9 - 1
data-easy/src/main/java/com/dataeasy/server/service/manager/IUserManager.java

@@ -22,12 +22,20 @@ public interface IUserManager {
 
     /**
      * 查询当前用户信息
+     * @param userId 用户id
      * @return
      */
-    UserInfoVO queryUserInfo();
+    UserInfoVO queryUserInfo(Long userId);
 
     /**
      * 修改昵称
      */
     void modifyNickname(NicknameRequest request);
+
+    /**
+     * 根据id获取用户信息(含缓存)
+     * @param id
+     * @return
+     */
+    User getByIdWithCache(Long id);
 }

+ 13 - 1
data-easy/src/main/java/com/dataeasy/server/service/manager/impl/DataManagerImpl.java

@@ -10,6 +10,7 @@ import com.dataeasy.server.atomic.service.IDataIpoBondService;
 import com.dataeasy.server.atomic.service.IDataIpoStockService;
 import com.dataeasy.server.atomic.service.IDataProductHuntPostService;
 import com.dataeasy.server.atomic.service.IDataShuangSeQiuService;
+import com.dataeasy.server.constant.CacheNameConstant;
 import com.dataeasy.server.pojo.data.DaLeTouVO;
 import com.dataeasy.server.pojo.data.IpoBondVO;
 import com.dataeasy.server.pojo.data.IpoStockVO;
@@ -19,6 +20,7 @@ import com.dataeasy.server.service.manager.IDataManager;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 
@@ -53,6 +55,8 @@ public class DataManagerImpl implements IDataManager {
     private IDataShuangSeQiuService shuangSeQiuService;
 
     @Override
+    @Cacheable(cacheNames = CacheNameConstant.DATA_IPO_BOND_LIST, key = "#subscriptionDate",
+            condition = "#subscriptionDate != null and !#subscriptionDate.isBlank()")
     public List<IpoBondVO> queryIpoBond(String subscriptionDate) {
         List<DataIpoBond> ipoBonds = ipoBondService.getBySubscriptionDate(subscriptionDate);
         if (CollectionUtils.isEmpty(ipoBonds)) {
@@ -67,6 +71,8 @@ public class DataManagerImpl implements IDataManager {
     }
 
     @Override
+    @Cacheable(cacheNames = CacheNameConstant.DATA_IPO_STOCK_LIST, key = "#subscriptionDate",
+            condition = "#subscriptionDate != null and !#subscriptionDate.isBlank()")
     public List<IpoStockVO> queryIpoStock(String subscriptionDate) {
         List<DataIpoStock> ipoStocks = ipoStockService.getBySubscriptionDate(subscriptionDate);
         if (CollectionUtils.isEmpty(ipoStocks)) {
@@ -81,6 +87,8 @@ public class DataManagerImpl implements IDataManager {
     }
 
     @Override
+    @Cacheable(cacheNames = CacheNameConstant.DATA_DA_LE_TOU_LIST, key = "#drawDate",
+            condition = "#drawDate != null and !#drawDate.isBlank()")
     public DaLeTouVO queryDaLeTou(String drawDate) {
         DataDaLeTou daLeTou = daLeTouService.getByDrawDate(drawDate);
         if (Objects.isNull(daLeTou)) {
@@ -93,6 +101,8 @@ public class DataManagerImpl implements IDataManager {
     }
 
     @Override
+    @Cacheable(cacheNames = CacheNameConstant.DATA_SHUANG_SE_QIU_LIST, key = "#drawDate",
+            condition = "#drawDate != null and !#drawDate.isBlank()")
     public ShuangSeQiuVO queryShuangSeQiu(String drawDate) {
         DataShuangSeQiu shuangSeQiu = shuangSeQiuService.getByDrawDate(drawDate);
         if (Objects.isNull(shuangSeQiu)) {
@@ -105,7 +115,9 @@ public class DataManagerImpl implements IDataManager {
     }
 
     @Override
-    public List<ProductHuntPostVO> queryProductHunt(String rankDate) {
+    @Cacheable(cacheNames = CacheNameConstant.DATA_PRODUCT_HUNT_POST_LIST, key = "#rankDate",
+            condition = "#rankDate != null and !#rankDate.isBlank()")
+    public List<ProductHuntPostVO> queryProductHuntPost(String rankDate) {
         List<DataProductHuntPost> posts = productHuntPostService.getByRankDate(rankDate);
         if (CollectionUtils.isEmpty(posts)) {
             return List.of();

+ 3 - 3
data-easy/src/main/java/com/dataeasy/server/service/manager/impl/OrderManagerImpl.java

@@ -23,7 +23,7 @@ import com.dataeasy.server.atomic.service.IUserService;
 import com.dataeasy.server.common.exception.BusinessException;
 import com.dataeasy.server.constant.OrderTypeEnum;
 import com.dataeasy.server.constant.PaymentStatusEnum;
-import com.dataeasy.server.core.config.BizConfig;
+import com.dataeasy.server.core.config.BizProperties;
 import com.dataeasy.server.pojo.order.SubscriptionOrderRequest;
 import com.dataeasy.server.service.manager.IOrderManager;
 import com.dataeasy.server.utiis.DateUtils;
@@ -69,7 +69,7 @@ public class OrderManagerImpl implements IOrderManager {
     private IUserService userService;
 
     @Autowired
-    private BizConfig bizConfig;
+    private BizProperties bizProperties;
 
     @Autowired
     @Qualifier("orderNoCache")
@@ -125,7 +125,7 @@ public class OrderManagerImpl implements IOrderManager {
         payer.setOpenid(user.getMaOpenId());
 
         // 设置订单的过期时间
-        LocalDateTime expireDateTime = LocalDateTime.now().plusMinutes(bizConfig.getOrderExpire());
+        LocalDateTime expireDateTime = LocalDateTime.now().plusMinutes(bizProperties.getOrderExpire());
         String timeExpire = expireDateTime.format(DateUtils.YYYYMMDDTHHMMSS_OFFSET_ZONE_FORMATTER);
 
         // 发送到微信的报文

+ 14 - 25
data-easy/src/main/java/com/dataeasy/server/service/manager/impl/SubscriptionManagerImpl.java

@@ -8,6 +8,7 @@ import com.dataeasy.server.atomic.service.ISubscriptionSourceService;
 import com.dataeasy.server.atomic.service.ISubscriptionUserConfigService;
 import com.dataeasy.server.common.exception.BusinessException;
 import com.dataeasy.server.common.utils.Assert;
+import com.dataeasy.server.constant.CacheNameConstant;
 import com.dataeasy.server.pojo.subscription.PushOptionRequest;
 import com.dataeasy.server.pojo.subscription.SubscriptionSourcePlanVO;
 import com.dataeasy.server.pojo.subscription.SubscriptionSourceVO;
@@ -21,6 +22,8 @@ import com.dataeasy.server.utiis.UserUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
@@ -54,7 +57,11 @@ public class SubscriptionManagerImpl implements ISubscriptionManager {
     @Autowired
     private ISubscriptionUserConfigService subscriptionUserConfigService;
 
+    @Autowired
+    private CacheManager cacheManager;
+
     @Override
+    @Cacheable(cacheNames = CacheNameConstant.SUBSCRIPTION_SOURCE_LIST)
     public List<SubscriptionSourceVO> querySubscriptionSource() {
         SubscriptionSourceQuery subscriptionSourceQuery = new SubscriptionSourceQuery();
         List<SubscriptionSource> sourceList = subscriptionSourceService.getByCondition(subscriptionSourceQuery);
@@ -70,6 +77,7 @@ public class SubscriptionManagerImpl implements ISubscriptionManager {
     }
 
     @Override
+    @Cacheable(cacheNames = CacheNameConstant.SUBSCRIPTION_SOURCE, key = "#id")
     public SubscriptionSourceDetailVO querySubscriptionSourceDetail(Long id) {
         SubscriptionSource subscriptionSource = subscriptionSourceService.getById(id);
         Assert.isNullInBusiness(subscriptionSource, "找不到对应的订阅源");
@@ -106,10 +114,11 @@ public class SubscriptionManagerImpl implements ISubscriptionManager {
     }
 
     @Override
-    public List<SubscriptionUserConfigVO> querySubscriptionUserConfig() {
+    @Cacheable(cacheNames = CacheNameConstant.SUBSCRIPTION_USER_CONFIG_LIST, key = "#userId")
+    public List<SubscriptionUserConfigVO> querySubscriptionUserConfig(Long userId) {
         // 查询当前用户拥有的订阅源
         SubscriptionUserConfigQuery subscriptionUserConfigQuery = new SubscriptionUserConfigQuery();
-        subscriptionUserConfigQuery.setUserId(UserUtils.getCurrentUserId());
+        subscriptionUserConfigQuery.setUserId(userId);
         List<SubscriptionUserConfig> userConfigList = subscriptionUserConfigService.getByCondition(subscriptionUserConfigQuery);
         if (CollectionUtils.isEmpty(userConfigList)) {
             return List.of();
@@ -143,31 +152,11 @@ public class SubscriptionManagerImpl implements ISubscriptionManager {
         }).toList();
     }
 
-    /**
-     * 根据条件查询订阅源
-     * @return
-     */
-    private List<SubscriptionSourceDetailVO> querySubscriptionSourceVO(SubscriptionSourceQuery query) {
-        if (Objects.isNull(query)) {
-            return List.of();
-        }
-        List<SubscriptionSource> sourceList = subscriptionSourceService.getByCondition(query);
-        if (CollectionUtils.isEmpty(sourceList)) {
-            return List.of();
-        }
-        return sourceList.stream().map(source -> {
-            SubscriptionSourceDetailVO sourceVO = new SubscriptionSourceDetailVO();
-            BeanUtils.copyProperties(source, sourceVO);
-            if (StringUtils.hasText(source.getPics())) {
-                List<String> picList = Arrays.stream(source.getPics().split(",")).toList();
-                sourceVO.setPics(picList);
-            }
-            return sourceVO;
-        }).toList();
-    }
-
     @Override
     public void modifyPushOption(PushOptionRequest request) {
+        // 清除缓存
+        cacheManager.getCache(CacheNameConstant.SUBSCRIPTION_USER_CONFIG_LIST).evict(UserUtils.getCurrentUserId());
+
         SubscriptionUserConfig subscriptionUserConfig = new SubscriptionUserConfig();
         subscriptionUserConfig.setId(request.getId());
         subscriptionUserConfig.setPushOption(request.getPushOption());

+ 38 - 9
data-easy/src/main/java/com/dataeasy/server/service/manager/impl/TokenManagerImpl.java

@@ -1,14 +1,17 @@
 package com.dataeasy.server.service.manager.impl;
 
 import java.util.Calendar;
-import java.util.Optional;
+import java.util.Map;
 
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.Claim;
 import com.dataeasy.server.common.exception.BusinessException;
 import com.dataeasy.server.common.utils.Assert;
-import com.dataeasy.server.core.config.BizConfig;
+import com.dataeasy.server.core.config.BizProperties;
 import com.dataeasy.server.service.manager.ITokenManager;
-import com.dataeasy.server.utiis.TokenUtils;
-import com.dataeasy.server.utiis.UserUtils;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -18,22 +21,48 @@ import org.springframework.stereotype.Service;
  * @date 2024/12/28 21:24
  * @description Json Web Token 管理类
  */
+@Slf4j
 @Service
 public class TokenManagerImpl implements ITokenManager {
 
+    private static final String CLAIM_USER_ID = "userId";
+
     @Autowired
-    private BizConfig bizConfig;
+    private BizProperties bizProperties;
+
+    /**
+     * token算法
+     */
+    private Algorithm tokenAlgorithm;
+
+    /**
+     * token校验工具
+     */
+    private JWTVerifier jwtVerifier;
+
+
+    public TokenManagerImpl(BizProperties bizProperties) {
+        this.bizProperties = bizProperties;
+        tokenAlgorithm = Algorithm.HMAC256(bizProperties.getTokenPassword());
+        jwtVerifier = JWT.require(tokenAlgorithm).build();
+    }
 
     @Override
     public String createToken(Long userId) {
         Assert.isNullInBusiness(userId, "请传入用户ID");
         Calendar instance = Calendar.getInstance();
-        instance.add(Calendar.DATE, bizConfig.getTokenExpire());
-        return TokenUtils.createToken(userId, instance.getTime());
+        instance.add(Calendar.DATE, bizProperties.getTokenExpire());
+        return JWT.create().withClaim(CLAIM_USER_ID, userId).withExpiresAt(instance.getTime()).sign(tokenAlgorithm);
     }
 
     @Override
-    public String refreshToken() {
-        return createToken(UserUtils.getCurrentUserId());
+    public Long getUserIdByToken(String token) {
+        try {
+            Map<String, Claim> verify = jwtVerifier.verify(token).getClaims();
+            return verify.get(CLAIM_USER_ID).asLong();
+        } catch (Exception e) {
+            log.error("解析token异常", e);
+            throw BusinessException.fail("解析token异常");
+        }
     }
 }

+ 29 - 3
data-easy/src/main/java/com/dataeasy/server/service/manager/impl/UserManagerImpl.java

@@ -4,11 +4,14 @@ import java.util.Objects;
 
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.dataeasy.server.atomic.entity.User;
 import com.dataeasy.server.atomic.service.IUserService;
+import com.dataeasy.server.constant.CacheNameConstant;
 import com.dataeasy.server.pojo.user.LoginRequest;
 import com.dataeasy.server.pojo.user.NicknameRequest;
 import com.dataeasy.server.pojo.user.UserInfoVO;
@@ -40,6 +43,9 @@ public class UserManagerImpl implements IUserManager {
     @Autowired
     private ITokenManager tokenManager;
 
+    @Autowired
+    private CacheManager cacheManager;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String login(LoginRequest request) throws WxErrorException {
@@ -56,11 +62,18 @@ public class UserManagerImpl implements IUserManager {
             user.setMaOpenId(wxMaJscode2SessionResult.getOpenid());
             user.setNickname(request.getNickname());
             userService.insert(user);
+
+            // 构建缓存
+            cacheManager.getCache(CacheNameConstant.USER).put(user.getId(), user);
         } else {
             User updateUser = new User();
             updateUser.setId(user.getId());
             updateUser.setNickname(request.getNickname());
             userService.updateById(updateUser);
+
+            // 清除缓存
+            cacheManager.getCache(CacheNameConstant.USER).evict(user.getId());
+            cacheManager.getCache(CacheNameConstant.USER_VO).evict(user.getId());
         }
 
         // 创建token
@@ -68,8 +81,9 @@ public class UserManagerImpl implements IUserManager {
     }
 
     @Override
-    public UserInfoVO queryUserInfo() {
-        User user = userService.getById(UserUtils.getCurrentUserId());
+    @Cacheable(cacheNames = CacheNameConstant.USER_VO, key = "#userId", condition = "#userId != null")
+    public UserInfoVO queryUserInfo(Long userId) {
+        User user = userService.getById(userId);
         UserInfoVO userInfoVO = new UserInfoVO();
         BeanUtils.copyProperties(user, userInfoVO);
         return userInfoVO;
@@ -77,9 +91,21 @@ public class UserManagerImpl implements IUserManager {
 
     @Override
     public void modifyNickname(NicknameRequest request) {
+        // 获取当前用户id
+        Long currentUserId = UserUtils.getCurrentUserId();
+        // 清除缓存
+        cacheManager.getCache(CacheNameConstant.USER).evict(currentUserId);
+        cacheManager.getCache(CacheNameConstant.USER_VO).evict(currentUserId);
+        // 更新数据库
         User user = new User();
-        user.setId(UserUtils.getCurrentUserId());
+        user.setId(currentUserId);
         user.setNickname(request.getNickname());
         userService.updateById(user);
     }
+
+    @Override
+    @Cacheable(cacheNames = CacheNameConstant.USER, key = "#id", condition = "#id != null")
+    public User getByIdWithCache(Long id) {
+        return userService.getById(id);
+    }
 }

+ 8 - 1
data-easy/src/main/java/com/dataeasy/server/service/manager/impl/WxManagerImpl.java

@@ -3,9 +3,9 @@ package com.dataeasy.server.service.manager.impl;
 import com.dataeasy.server.atomic.entity.SubscriptionOrder;
 import com.dataeasy.server.atomic.entity.SubscriptionUserConfig;
 import com.dataeasy.server.atomic.service.ISubscriptionOrderService;
-import com.dataeasy.server.atomic.service.ISubscriptionSourceService;
 import com.dataeasy.server.atomic.service.ISubscriptionUserConfigService;
 import com.dataeasy.server.common.exception.BusinessException;
+import com.dataeasy.server.constant.CacheNameConstant;
 import com.dataeasy.server.constant.PaymentStatusEnum;
 import com.dataeasy.server.constant.PushOptionEnum;
 import com.dataeasy.server.utiis.DateUtils;
@@ -17,6 +17,7 @@ import jakarta.servlet.http.HttpServletRequest;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
 import org.springframework.stereotype.Service;
 
 import com.dataeasy.server.service.manager.IWxManager;
@@ -57,6 +58,9 @@ public class WxManagerImpl implements IWxManager {
     @Autowired
     private ISubscriptionUserConfigService subscriptionUserConfigService;
 
+    @Autowired
+    private CacheManager cacheManager;
+
     @Override
     public String mpEntry(String signature, String timestamp, String nonce, String echoStr) {
         log.info("微信公众号/服务号接入传递的参数 signature:[{}],timestamp:[{}],nonce:[{}],echostr:[{}]", signature, timestamp, nonce,
@@ -136,6 +140,9 @@ public class WxManagerImpl implements IWxManager {
             updateSubscriptionOrder.setPaymentStatus(PaymentStatusEnum.SUCCESS);
             subscriptionOrderService.updateById(updateSubscriptionOrder);
 
+            // 清除缓存
+            cacheManager.getCache(CacheNameConstant.SUBSCRIPTION_USER_CONFIG_LIST).evict(subscriptionOrder.getUserId());
+
             // 支付成功创建用户配置
             SubscriptionUserConfig addSubscriptionUserConfig = new SubscriptionUserConfig();
             addSubscriptionUserConfig.setPushOption(PushOptionEnum.ENABLED);

+ 10 - 4
data-easy/src/main/java/com/dataeasy/server/task/IpoStockTask.java

@@ -2,16 +2,15 @@ package com.dataeasy.server.task;
 
 import java.time.LocalDate;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 
-import com.dataeasy.server.utiis.DateUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 
 import com.dataeasy.server.atomic.entity.DataIpoStock;
 import com.dataeasy.server.atomic.service.IDataIpoStockService;
@@ -20,10 +19,10 @@ import com.dataeasy.server.constant.ScheduleTaskEnum;
 import com.dataeasy.server.feign.FinanceFeign;
 import com.dataeasy.server.feign.dto.finance.FinanceRequest;
 import com.dataeasy.server.feign.dto.finance.StockResponse;
+import com.dataeasy.server.utiis.DateUtils;
 
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
-import org.springframework.util.StringUtils;
 
 /**
  * @author tyuio
@@ -60,14 +59,21 @@ public class IpoStockTask extends AbstractDataTask {
 
         // 过滤当天新股数据
         String todayStr = DateUtils.YYYY_MM_DD_FORMATTER.format(LocalDate.now());
+        String subscriptionDateStr = String.format("%sT00:00:00.000", todayStr);
         List<DataIpoStock> ipoStocks = stockXgsglbEmList.stream().filter(v -> StringUtils.hasText(v.getSubscriptionDate()))
-                .filter(v -> todayStr.equals(v.getSubscriptionDate()))
+                .filter(v -> subscriptionDateStr.equals(v.getSubscriptionDate()))
                 .map(v -> {
             DataIpoStock ipoStock = new DataIpoStock();
             BeanUtils.copyProperties(v, ipoStock);
             return ipoStock;
         }).collect(Collectors.toList());
 
+        // 判断当天没有新股数据
+        if (CollectionUtils.isEmpty(ipoStocks)) {
+            log.info("当天没有新股数据,执行结束");
+            return false;
+        }
+
         // 数据入库
         ipoStockService.insertList(ipoStocks);
 

+ 0 - 57
data-easy/src/main/java/com/dataeasy/server/utiis/TokenUtils.java

@@ -1,57 +0,0 @@
-package com.dataeasy.server.utiis;
-
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.JWTVerifier;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.auth0.jwt.interfaces.Claim;
-import com.dataeasy.server.core.config.BizConfig;
-
-import java.util.Date;
-import java.util.Map;
-
-/**
- * @className JwtUtils
- * @description Token凭证工具
- * @author ChenYL
- * @date 2023/07/29 16:25
- * @version V1.0
- **/
-public class TokenUtils {
-
-    /**
-     * token算法
-     */
-    private static Algorithm tokenAlgorithm;
-
-    /**
-     * token校验工具
-     */
-    private static JWTVerifier jwtVerifier;
-
-    static {
-        BizConfig bizConfig = SpringUtils.getBean(BizConfig.class);
-        tokenAlgorithm = Algorithm.HMAC256(bizConfig.getTokenPassword());
-        jwtVerifier = JWT.require(tokenAlgorithm).build();
-    }
-
-    /**
-     * 创建token
-     * 
-     * @param userId
-     * @param expiresAt
-     * @return
-     */
-    public static String createToken(Long userId, Date expiresAt) {
-        return JWT.create().withClaim("userId", userId).withExpiresAt(expiresAt).sign(tokenAlgorithm);
-    }
-
-    /**
-     * 校验token
-     * 
-     * @param token
-     * @return
-     */
-    public static Map<String, Claim> verify(String token) {
-        return jwtVerifier.verify(token).getClaims();
-    }
-}

+ 1 - 0
product-hunt/src/main/java/com/producthunt/server/core/aop/GlobalExceptionHandler.java

@@ -42,6 +42,7 @@ public class GlobalExceptionHandler {
      */
     @ExceptionHandler(LoginException.class)
     public ResponseEntity<Object> loginExceptionHandler(LoginException e) {
+        log.error(e.getMessage(), e);
         return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(JsonResponse.fail(e.getMessage()));
     }