Quellcode durchsuchen

【第一版开发】
1.增加订阅相关代码
2.优化代码逻辑:当前用户ID的获取
3.优化代码逻辑:Tk MaBatis的Weekend对象的创建
4.修改表设计

ChenYL vor 11 Monaten
Ursprung
Commit
518f5fb969
40 geänderte Dateien mit 529 neuen und 131 gelöschten Zeilen
  1. 6 0
      data-easy/pom.xml
  2. 3 1
      data-easy/src/main/java/com/dataeasy/server/atomic/entity/SubscriptionPlan.java
  3. 11 0
      data-easy/src/main/java/com/dataeasy/server/atomic/service/ISubscriptionPlanService.java
  4. 7 0
      data-easy/src/main/java/com/dataeasy/server/atomic/service/ISubscriptionSourceService.java
  5. 2 1
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/DataProductHuntPostServiceImpl.java
  6. 23 1
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionPlanServiceImpl.java
  7. 11 10
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionSourceServiceImpl.java
  8. 2 7
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionTaskConfigServiceImpl.java
  9. 2 9
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionUserConfigServiceImpl.java
  10. 2 7
      data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/UserServiceImpl.java
  11. 2 2
      data-easy/src/main/java/com/dataeasy/server/common/pojo/BaseEntity.java
  12. 20 0
      data-easy/src/main/java/com/dataeasy/server/constant/PaidOptionEnum.java
  13. 3 3
      data-easy/src/main/java/com/dataeasy/server/constant/PushOptionEnum.java
  14. 28 1
      data-easy/src/main/java/com/dataeasy/server/core/aop/GlobalExceptionHandler.java
  15. 1 1
      data-easy/src/main/java/com/dataeasy/server/core/aop/ResponseControllerAdvice.java
  16. 1 1
      data-easy/src/main/java/com/dataeasy/server/core/aop/WebOperateLogAspect.java
  17. 1 1
      data-easy/src/main/java/com/dataeasy/server/core/config/WebMvcConfig.java
  18. 1 1
      data-easy/src/main/java/com/dataeasy/server/core/interceptor/MybatisAuditDataInterceptor.java
  19. 2 0
      data-easy/src/main/java/com/dataeasy/server/feign/ProductHuntFeign.java
  20. 20 0
      data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionPlanQuery.java
  21. 55 0
      data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionSourceDetailVO.java
  22. 37 0
      data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionSourcePlanVO.java
  23. 3 18
      data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionSourceVO.java
  24. 53 0
      data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionUserConfigVO.java
  25. 26 6
      data-easy/src/main/java/com/dataeasy/server/service/controller/SubscriptionController.java
  26. 10 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/ISubscriptionManager.java
  27. 105 15
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/SubscriptionManagerImpl.java
  28. 1 4
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/TokenManagerImpl.java
  29. 9 11
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/UserManagerImpl.java
  30. 1 1
      data-easy/src/main/java/com/dataeasy/server/task/AbstractTask.java
  31. 1 1
      data-easy/src/main/java/com/dataeasy/server/task/DaLeTouTask.java
  32. 1 1
      data-easy/src/main/java/com/dataeasy/server/task/IpoBondTask.java
  33. 1 1
      data-easy/src/main/java/com/dataeasy/server/task/IpoStockTask.java
  34. 1 1
      data-easy/src/main/java/com/dataeasy/server/task/ProductHuntTask.java
  35. 1 1
      data-easy/src/main/java/com/dataeasy/server/task/ShuangSeQiuTask.java
  36. 17 1
      data-easy/src/main/java/com/dataeasy/server/utiis/UserUtils.java
  37. 34 0
      data-easy/src/main/java/com/dataeasy/server/utiis/WeekendUtils.java
  38. 4 0
      data-easy/src/main/resources/application-dev.yaml
  39. 2 0
      doc/sql/schema.sql
  40. 19 23
      doc/技术文档.md

+ 6 - 0
data-easy/pom.xml

@@ -46,6 +46,12 @@
         <dependency>
             <groupId>org.springframework.ai</groupId>
             <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.validation</groupId>
+                    <artifactId>validation-api</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 3 - 1
data-easy/src/main/java/com/dataeasy/server/atomic/entity/SubscriptionPlan.java

@@ -1,6 +1,7 @@
 package com.dataeasy.server.atomic.entity;
 
 import com.dataeasy.server.common.pojo.BaseEntity;
+import com.dataeasy.server.constant.PaidOptionEnum;
 import jakarta.persistence.Column;
 import jakarta.persistence.Table;
 import lombok.Data;
@@ -32,9 +33,10 @@ public class SubscriptionPlan extends BaseEntity implements Serializable {
 
     /**
      * 付费选项(FREE-免费、PAID-付费)
+     * @see PaidOptionEnum
      */
     @Column(name = "paid_option")
-    private String paidOption;
+    private PaidOptionEnum paidOption;
 
     /**
      * 订阅价格(单位:元)

+ 11 - 0
data-easy/src/main/java/com/dataeasy/server/atomic/service/ISubscriptionPlanService.java

@@ -1,5 +1,10 @@
 package com.dataeasy.server.atomic.service;
 
+import com.dataeasy.server.atomic.entity.SubscriptionPlan;
+import com.dataeasy.server.pojo.subscription.SubscriptionPlanQuery;
+
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -8,4 +13,10 @@ package com.dataeasy.server.atomic.service;
  */
 public interface ISubscriptionPlanService {
 
+    /**
+     * 按条件查询
+     * @param query
+     * @return
+     */
+    List<SubscriptionPlan> getByCondition(SubscriptionPlanQuery query);
 }

+ 7 - 0
data-easy/src/main/java/com/dataeasy/server/atomic/service/ISubscriptionSourceService.java

@@ -19,4 +19,11 @@ public interface ISubscriptionSourceService {
      * @return
      */
     List<SubscriptionSource> getByCondition(SubscriptionSourceQuery query);
+
+    /**
+     * 按id查询订阅源
+     * @param id
+     * @return
+     */
+    SubscriptionSource getById(Long id);
 }

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

@@ -2,6 +2,7 @@ package com.dataeasy.server.atomic.service.impl;
 
 import java.util.List;
 
+import com.dataeasy.server.utiis.WeekendUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
@@ -38,7 +39,7 @@ public class DataProductHuntPostServiceImpl implements IDataProductHuntPostServi
             return List.of();
         }
 
-        Weekend<DataProductHuntPost> weekend = Weekend.of(DataProductHuntPost.class);
+        Weekend<DataProductHuntPost> weekend = WeekendUtils.createExcludeAuditFields(DataProductHuntPost.class);
         WeekendCriteria<DataProductHuntPost, Object> criteria = weekend.weekendCriteria();
         criteria.andEqualTo(DataProductHuntPost::getRankDate, rankDate);
         weekend.orderBy(DataProductHuntPost::getRankNum);

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

@@ -1,10 +1,19 @@
 package com.dataeasy.server.atomic.service.impl;
 
+import com.dataeasy.server.atomic.entity.SubscriptionPlan;
+import com.dataeasy.server.pojo.subscription.SubscriptionPlanQuery;
+import com.dataeasy.server.utiis.WeekendUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import com.dataeasy.server.atomic.mapper.SubscriptionPlanMapper;
 import com.dataeasy.server.atomic.service.ISubscriptionPlanService;
+import org.springframework.util.CollectionUtils;
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
+
+import java.util.List;
+import java.util.Objects;
 
 /**
  * @author tyuio
@@ -16,6 +25,19 @@ import com.dataeasy.server.atomic.service.ISubscriptionPlanService;
 public class SubscriptionPlanServiceImpl implements ISubscriptionPlanService {
 
     @Autowired
-    private SubscriptionPlanMapper mapper;
+    private SubscriptionPlanMapper subscriptionPlanMapper;
+
+    @Override
+    public List<SubscriptionPlan> getByCondition(SubscriptionPlanQuery query) {
+        if (Objects.isNull(query)) {
+            return List.of();
+        }
 
+        Weekend<SubscriptionPlan> weekend = WeekendUtils.createExcludeAuditFields(SubscriptionPlan.class);
+        WeekendCriteria<SubscriptionPlan, Object> weekendCriteria = weekend.weekendCriteria();
+        if (!CollectionUtils.isEmpty(query.getSubscriptionSourceIds())) {
+            weekendCriteria.andIn(SubscriptionPlan::getSubscriptionSourceId, query.getSubscriptionSourceIds());
+        }
+        return subscriptionPlanMapper.selectByExample(weekend);
+    }
 }

+ 11 - 10
data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionSourceServiceImpl.java

@@ -2,6 +2,7 @@ package com.dataeasy.server.atomic.service.impl;
 
 import com.dataeasy.server.atomic.entity.SubscriptionSource;
 import com.dataeasy.server.pojo.subscription.SubscriptionSourceQuery;
+import com.dataeasy.server.utiis.WeekendUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -32,20 +33,20 @@ public class SubscriptionSourceServiceImpl implements ISubscriptionSourceService
             return List.of();
         }
 
-        Weekend<SubscriptionSource> weekend = Weekend.of(SubscriptionSource.class);
+        Weekend<SubscriptionSource> weekend = WeekendUtils.createExcludeAuditFields(SubscriptionSource.class);
         WeekendCriteria<SubscriptionSource, Object> weekendCriteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(query.getIds())) {
             weekendCriteria.andIn(SubscriptionSource::getId, query.getIds());
         }
-        weekend.selectProperties(
-                SubscriptionSource::getId,
-                SubscriptionSource::getTitle,
-                SubscriptionSource::getSubTitle,
-                SubscriptionSource::getPics,
-                SubscriptionSource::getPushChannel,
-                SubscriptionSource::getPushFrequency,
-                SubscriptionSource::getDescription
-        );
         return subscriptionSourceMapper.selectByExample(weekend);
     }
+
+    @Override
+    public SubscriptionSource getById(Long id) {
+        if (Objects.isNull(id)) {
+            return null;
+        }
+
+        return subscriptionSourceMapper.selectByPrimaryKey(id);
+    }
 }

+ 2 - 7
data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionTaskConfigServiceImpl.java

@@ -3,6 +3,7 @@ package com.dataeasy.server.atomic.service.impl;
 import java.util.List;
 import java.util.Objects;
 
+import com.dataeasy.server.utiis.WeekendUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
@@ -32,7 +33,7 @@ public class SubscriptionTaskConfigServiceImpl implements ISubscriptionTaskConfi
         if (Objects.isNull(query)) {
             return List.of();
         }
-        Weekend<SubscriptionTaskConfig> weekend = Weekend.of(SubscriptionTaskConfig.class);
+        Weekend<SubscriptionTaskConfig> weekend = WeekendUtils.createExcludeAuditFields(SubscriptionTaskConfig.class);
         WeekendCriteria<SubscriptionTaskConfig, Object> weekendCriteria = weekend.weekendCriteria();
         if (StringUtils.hasText(query.getTaskCode())) {
             weekendCriteria.andEqualTo(SubscriptionTaskConfig::getTaskCode, query.getTaskCode());
@@ -40,12 +41,6 @@ public class SubscriptionTaskConfigServiceImpl implements ISubscriptionTaskConfi
         if (StringUtils.hasText(query.getExecuteOption())) {
             weekendCriteria.andEqualTo(SubscriptionTaskConfig::getExecuteOption, query.getExecuteOption());
         }
-        weekend.selectProperties(
-                SubscriptionTaskConfig::getId,
-                SubscriptionTaskConfig::getTaskCode,
-                SubscriptionTaskConfig::getTaskName,
-                SubscriptionTaskConfig::getExecuteOption,
-                SubscriptionTaskConfig::getSubscriptionSourceId);
         return taskConfigMapper.selectByExample(weekend);
     }
 }

+ 2 - 9
data-easy/src/main/java/com/dataeasy/server/atomic/service/impl/SubscriptionUserConfigServiceImpl.java

@@ -3,6 +3,7 @@ package com.dataeasy.server.atomic.service.impl;
 import com.dataeasy.server.atomic.entity.SubscriptionUserConfig;
 import com.dataeasy.server.common.utils.Assert;
 import com.dataeasy.server.pojo.subscription.SubscriptionUserConfigQuery;
+import com.dataeasy.server.utiis.WeekendUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -32,7 +33,7 @@ public class SubscriptionUserConfigServiceImpl implements ISubscriptionUserConfi
         if (Objects.isNull(query)) {
             return List.of();
         }
-        Weekend<SubscriptionUserConfig> weekend = Weekend.of(SubscriptionUserConfig.class);
+        Weekend<SubscriptionUserConfig> weekend = WeekendUtils.createExcludeAuditFields(SubscriptionUserConfig.class);
         WeekendCriteria<SubscriptionUserConfig, Object> weekendCriteria = weekend.weekendCriteria();
         if (!CollectionUtils.isEmpty(query.getSubscriptionSourceIds())) {
             weekendCriteria.andIn(SubscriptionUserConfig::getSubscriptionSourceId, query.getSubscriptionSourceIds());
@@ -47,14 +48,6 @@ public class SubscriptionUserConfigServiceImpl implements ISubscriptionUserConfi
         if (Objects.nonNull(query.getUserId())) {
             weekendCriteria.andEqualTo(SubscriptionUserConfig::getUserId, query.getUserId());
         }
-        weekend.selectProperties(
-                SubscriptionUserConfig::getId,
-                SubscriptionUserConfig::getSubscriptionSourceId,
-                SubscriptionUserConfig::getPushOption,
-                SubscriptionUserConfig::getStartTime,
-                SubscriptionUserConfig::getEndTime,
-                SubscriptionUserConfig::getUserId
-        );
         return userConfigMapper.selectByExample(weekend);
     }
 

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

@@ -4,6 +4,7 @@ import com.dataeasy.server.atomic.entity.User;
 import com.dataeasy.server.atomic.mapper.UserMapper;
 import com.dataeasy.server.atomic.service.IUserService;
 import com.dataeasy.server.common.utils.Assert;
+import com.dataeasy.server.utiis.WeekendUtils;
 import io.micrometer.common.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -41,15 +42,9 @@ public class UserServiceImpl implements IUserService {
         if (CollectionUtils.isEmpty(ids)) {
             return List.of();
         }
-        Weekend<User> weekend = Weekend.of(User.class);
+        Weekend<User> weekend = WeekendUtils.createExcludeAuditFields(User.class);
         WeekendCriteria<User, Object> weekendCriteria = weekend.weekendCriteria();
         weekendCriteria.andIn(User::getId, ids);
-
-        weekend.selectProperties(User::getId,
-                User::getMaOpenId,
-                User::getMpOpenId,
-                User::getUnionId,
-                User::getNickname);
         return userMapper.selectByExample(weekend);
     }
 

+ 2 - 2
data-easy/src/main/java/com/dataeasy/server/common/pojo/BaseEntity.java

@@ -1,13 +1,13 @@
 package com.dataeasy.server.common.pojo;
 
+import java.sql.Timestamp;
+
 import jakarta.persistence.Column;
 import jakarta.persistence.Id;
 import lombok.Data;
 import tk.mybatis.mapper.annotation.KeySql;
 import tk.mybatis.mapper.annotation.LogicDelete;
 
-import java.sql.Timestamp;
-
 /**
  * @description 实体类基类(6个通用审计字段)
  * @version 1.0.0

+ 20 - 0
data-easy/src/main/java/com/dataeasy/server/constant/PaidOptionEnum.java

@@ -0,0 +1,20 @@
+package com.dataeasy.server.constant;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 付费选项(FREE-免费、PAID-付费) 枚举
+ * @date 2025/3/7 8:53
+ */
+@Getter
+@AllArgsConstructor
+public enum PaidOptionEnum {
+
+    FREE("免费"),
+    PAID("付费");
+
+    private String name;
+}

+ 3 - 3
data-easy/src/main/java/com/dataeasy/server/constant/PushOptionEnum.java

@@ -6,15 +6,15 @@ import lombok.Getter;
 /**
  * @author tyuio
  * @version 1.0.0
- * @description 消息推送选项(ENABLE-开启、DISABLE-关闭)
+ * @description 消息推送选项(ENABLED-开启、DISABLED-关闭)
  * @date 2025/3/7 8:53
  */
 @Getter
 @AllArgsConstructor
 public enum PushOptionEnum {
 
-    ENABLE("开启"),
-    DISABLE("关闭");
+    ENABLED("开启"),
+    DISABLED("关闭");
 
     private String name;
 }

+ 28 - 1
data-easy/src/main/java/com/dataeasy/server/core/aop/GlobalExceptionHandler.java

@@ -3,10 +3,13 @@ package com.dataeasy.server.core.aop;
 import com.dataeasy.server.common.exception.BusinessException;
 import com.dataeasy.server.common.exception.LoginException;
 import com.dataeasy.server.common.pojo.JsonResponse;
+import jakarta.validation.ConstraintViolationException;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+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.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -56,12 +59,36 @@ public class GlobalExceptionHandler {
         return JsonResponse.fail(String.format("参数错误:%s", errorMsg));
     }
 
+    /**
+     * 方法参数校验异常处理
+     * @param e
+     * @return
+     */
+    @ExceptionHandler(ConstraintViolationException.class)
+    public JsonResponse constraintViolationExceptionHandler(ConstraintViolationException e) {
+        String errorMsg = e.getConstraintViolations().stream().map(error -> error.getMessage())
+                .collect(Collectors.joining(";"));
+        return JsonResponse.fail(String.format("参数错误:%s", errorMsg));
+    }
+
+    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+    public JsonResponse httpRequestMethodNotSupportedExceptionHandler(HttpRequestMethodNotSupportedException e) {
+        log.error("全局异常处理:请求方法不支持", e);
+        return JsonResponse.fail(String.format("请求方法不支持,异常原因:%s", e.getMessage()));
+    }
+
+    @ExceptionHandler(HttpMessageNotReadableException.class)
+    public JsonResponse httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
+        log.error("全局异常处理:请求参数格式错误", e);
+        return JsonResponse.fail(String.format("请求参数格式错误,异常原因:%s", e.getMessage()));
+    }
+
     /**
      * 全局异常处理
      */
     @ExceptionHandler(Exception.class)
     public JsonResponse exceptionHandler(Exception e) {
-        log.error(e.getMessage(), e);
+        log.error("全局异常处理", e);
         return JsonResponse.fail("系统异常,请稍后再试");
     }
 }

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/core/aop/ResponseControllerAdvice.java

@@ -16,7 +16,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
 /**
  * 接口返回统一处理
  */
-@RestControllerAdvice(basePackages = {"com.punchsettle.server.service.controller"})
+@RestControllerAdvice(basePackages = {"com.dataeasy.server.service.controller"})
 public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {
     @Override
     public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/core/aop/WebOperateLogAspect.java

@@ -18,7 +18,7 @@ import java.util.Arrays;
 @Component
 public class WebOperateLogAspect {
 
-    @Pointcut("execution(* com.punchsettle.server.service.controller..*.*(..))")
+    @Pointcut("execution(* com.dataeasy.server.service.controller..*.*(..))")
     public void pointcut() {}
 
     @Around("pointcut()")

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

@@ -20,7 +20,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(authInterceptor)
-                .excludePathPatterns("/health/**", "/wechat/miniprogram/login");
+                .excludePathPatterns("/health/**", "/wx/mp/entry", "/wx/mp/callback");
     }
 
     /**

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/core/interceptor/MybatisAuditDataInterceptor.java

@@ -43,7 +43,7 @@ public class MybatisAuditDataInterceptor implements Interceptor {
         /**
          * 插入或更新的时候,赋予createBy、updateBy、creationTime、lastUpdateTime值
          */
-        Long currentUserId = Optional.ofNullable(UserUtils.getCurrentUserId()).orElse(1L);
+        Long currentUserId = UserUtils.getCurrentUserId(1L);
         Timestamp currentTime = new Timestamp(System.currentTimeMillis());
 
         // 识别SQL类型,看是INSERT还是UPDATE

+ 2 - 0
data-easy/src/main/java/com/dataeasy/server/feign/ProductHuntFeign.java

@@ -3,6 +3,7 @@ package com.dataeasy.server.feign;
 import com.dataeasy.server.common.pojo.JsonResponse;
 import com.dataeasy.server.feign.dto.PostNode;
 import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
 
 import java.util.List;
 
@@ -19,5 +20,6 @@ public interface ProductHuntFeign {
      * 获取产品热榜TOP30
      * @return
      */
+    @GetMapping("/getTop30Posts")
     JsonResponse<List<PostNode>> getTop30Posts();
 }

+ 20 - 0
data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionPlanQuery.java

@@ -0,0 +1,20 @@
+package com.dataeasy.server.pojo.subscription;
+
+import lombok.Data;
+
+import java.util.Collection;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 订阅价格计划 查询类
+ * @date 2025/3/7 16:03
+ */
+@Data
+public class SubscriptionPlanQuery {
+
+    /**
+     * 订阅源id集合
+     */
+    private Collection<Long> subscriptionSourceIds;
+}

+ 55 - 0
data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionSourceDetailVO.java

@@ -0,0 +1,55 @@
+package com.dataeasy.server.pojo.subscription;
+
+import java.util.List;
+
+import lombok.Data;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 订阅源详情 VO
+ * @date 2025/3/7 15:35
+ */
+@Data
+public class SubscriptionSourceDetailVO {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 主标题
+     */
+    private String title;
+
+    /**
+     * 副标题
+     */
+    private String subTitle;
+
+    /**
+     * 推送渠道(WXMP-微信服务号)
+     */
+    private String pushChannel;
+
+    /**
+     * 推送频率
+     */
+    private String pushFrequency;
+
+    /**
+     * 详情描述
+     */
+    private String description;
+
+    /**
+     * 详情图片
+     */
+    private List<String> pics;
+
+    /**
+     * 价格计划
+     */
+    private List<SubscriptionSourcePlanVO> subscriptionPlans;
+}

+ 37 - 0
data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionSourcePlanVO.java

@@ -0,0 +1,37 @@
+package com.dataeasy.server.pojo.subscription;
+
+import java.math.BigDecimal;
+
+import com.dataeasy.server.constant.PaidOptionEnum;
+import lombok.Data;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 订阅价格 VO
+ * @date 2025/3/7 15:35
+ */
+@Data
+public class SubscriptionSourcePlanVO {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 付费选项(FREE-免费、PAID-付费)
+     * @see PaidOptionEnum
+     */
+    private PaidOptionEnum paidOption;
+
+    /**
+     * 订阅价格(单位:元)
+     */
+    private BigDecimal subscriptionPrice;
+
+    /**
+     * 订阅时长(单位:天)
+     */
+    private Integer subscriptionDuration;
+}

+ 3 - 18
data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionSourceVO.java

@@ -1,6 +1,6 @@
 package com.dataeasy.server.pojo.subscription;
 
-import java.util.List;
+import java.math.BigDecimal;
 
 import lombok.Data;
 
@@ -29,22 +29,7 @@ public class SubscriptionSourceVO {
     private String subTitle;
 
     /**
-     * 推送渠道(WXMP-微信服务号)
+     * 订阅价格
      */
-    private String pushChannel;
-
-    /**
-     * 推送频率
-     */
-    private String pushFrequency;
-
-    /**
-     * 详情描述
-     */
-    private String description;
-
-    /**
-     * 详情图片
-     */
-    private List<String> pics;
+    private BigDecimal subscriptionPrice;
 }

+ 53 - 0
data-easy/src/main/java/com/dataeasy/server/pojo/subscription/SubscriptionUserConfigVO.java

@@ -0,0 +1,53 @@
+package com.dataeasy.server.pojo.subscription;
+
+import java.sql.Timestamp;
+
+import com.dataeasy.server.constant.PushOptionEnum;
+
+import lombok.Data;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 用户的订阅源配置 VO
+ * @date 2025/3/7 15:35
+ */
+@Data
+public class SubscriptionUserConfigVO {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 主标题
+     */
+    private String title;
+
+    /**
+     * 副标题
+     */
+    private String subTitle;
+
+    /**
+     * 订阅源ID
+     */
+    private Long subscriptionSourceId;
+
+    /**
+     * 订阅开始时间
+     */
+    private Timestamp startTime;
+
+    /**
+     * 订阅结束时间
+     */
+    private Timestamp endTime;
+
+    /**
+     * 消息推送选项(ENABLE-开启、DISABLE-关闭)
+     * @see PushOptionEnum
+     */
+    private PushOptionEnum pushOption;
+}

+ 26 - 6
data-easy/src/main/java/com/dataeasy/server/service/controller/SubscriptionController.java

@@ -2,15 +2,22 @@ package com.dataeasy.server.service.controller;
 
 import java.util.List;
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import com.dataeasy.server.pojo.subscription.PushOptionRequest;
+import com.dataeasy.server.pojo.subscription.SubscriptionSourceDetailVO;
 import com.dataeasy.server.pojo.subscription.SubscriptionSourceVO;
+import com.dataeasy.server.pojo.subscription.SubscriptionUserConfigVO;
+import com.dataeasy.server.service.manager.ISubscriptionManager;
+
+import jakarta.validation.constraints.NotNull;
 
 /**
  * @author tyuio
@@ -23,27 +30,40 @@ import com.dataeasy.server.pojo.subscription.SubscriptionSourceVO;
 @RequestMapping("/subscription")
 public class SubscriptionController {
 
+    @Autowired
+    private ISubscriptionManager subscriptionManager;
+
     /**
      * 查询订阅源
      */
     @GetMapping("/querySource")
     public List<SubscriptionSourceVO> querySource() {
-        return null;
+        return subscriptionManager.querySource();
+    }
+
+    /**
+     * 查询指定订阅源详情
+     * @param id 订阅源ID
+     * @return
+     */
+    @GetMapping("/querySourceDetail")
+    public SubscriptionSourceDetailVO querySourceDetail(@RequestParam(required = false) @NotNull(message = "订阅源id不能为空") Long id) {
+        return subscriptionManager.querySourceDetail(id);
     }
 
     /**
      * 查询用户已订阅的订阅源
      */
-    @GetMapping("/queryUserSubSource")
-    public List<SubscriptionSourceVO> queryUserSubSource() {
-        return null;
+    @GetMapping("/querySourceUserConfig")
+    public List<SubscriptionUserConfigVO> querySourceUserConfig() {
+        return subscriptionManager.querySourceUserConfig();
     }
 
     /**
      * 修改消息推送选项
      */
     @PostMapping("/modifyPushOption")
-    public void modifyPushOption(@RequestBody PushOptionRequest request) {
-        return;
+    public void modifyPushOption(@Validated @RequestBody PushOptionRequest request) {
+        subscriptionManager.modifyPushOption(request);
     }
 }

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

@@ -3,7 +3,9 @@ package com.dataeasy.server.service.manager;
 import java.util.List;
 
 import com.dataeasy.server.pojo.subscription.PushOptionRequest;
+import com.dataeasy.server.pojo.subscription.SubscriptionSourceDetailVO;
 import com.dataeasy.server.pojo.subscription.SubscriptionSourceVO;
+import com.dataeasy.server.pojo.subscription.SubscriptionUserConfigVO;
 
 /**
  * @author tyuio
@@ -18,10 +20,17 @@ public interface ISubscriptionManager {
      */
     List<SubscriptionSourceVO> querySource();
 
+    /**
+     * 查询指定订阅源详情
+     * @param id 订阅源ID
+     * @return
+     */
+    SubscriptionSourceDetailVO querySourceDetail(Long id);
+
     /**
      * 查询用户已订阅的订阅源
      */
-    List<SubscriptionSourceVO> queryUserSubSource();
+    List<SubscriptionUserConfigVO> querySourceUserConfig();
 
     /**
      * 修改消息推送选项

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

@@ -1,14 +1,21 @@
 package com.dataeasy.server.service.manager.impl;
 
+import com.dataeasy.server.atomic.entity.SubscriptionPlan;
 import com.dataeasy.server.atomic.entity.SubscriptionSource;
 import com.dataeasy.server.atomic.entity.SubscriptionUserConfig;
+import com.dataeasy.server.atomic.service.ISubscriptionPlanService;
 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.pojo.subscription.PushOptionRequest;
-import com.dataeasy.server.pojo.subscription.SubscriptionSourceQuery;
+import com.dataeasy.server.pojo.subscription.SubscriptionSourcePlanVO;
 import com.dataeasy.server.pojo.subscription.SubscriptionSourceVO;
+import com.dataeasy.server.pojo.subscription.SubscriptionPlanQuery;
+import com.dataeasy.server.pojo.subscription.SubscriptionSourceQuery;
+import com.dataeasy.server.pojo.subscription.SubscriptionSourceDetailVO;
 import com.dataeasy.server.pojo.subscription.SubscriptionUserConfigQuery;
+import com.dataeasy.server.pojo.subscription.SubscriptionUserConfigVO;
 import com.dataeasy.server.service.manager.ISubscriptionManager;
 import com.dataeasy.server.utiis.UserUtils;
 import lombok.extern.slf4j.Slf4j;
@@ -20,9 +27,10 @@ import org.springframework.util.StringUtils;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -38,38 +46,120 @@ public class SubscriptionManagerImpl implements ISubscriptionManager {
     @Autowired
     private ISubscriptionSourceService subscriptionSourceService;
 
+    @Autowired
+    private ISubscriptionPlanService subscriptionPlanService;
+
     @Autowired
     private ISubscriptionUserConfigService subscriptionUserConfigService;
 
     @Override
     public List<SubscriptionSourceVO> querySource() {
-        SubscriptionSourceQuery query = new SubscriptionSourceQuery();
-        return querySubscriptionSourceVO(query);
+        SubscriptionSourceQuery subscriptionSourceQuery = new SubscriptionSourceQuery();
+        List<SubscriptionSource> sourceList = subscriptionSourceService.getByCondition(subscriptionSourceQuery);
+        if (CollectionUtils.isEmpty(sourceList)) {
+            return List.of();
+        }
+
+        // 获取订阅源与价格的对应关系
+        List<Long> sourceIds = sourceList.stream().map(SubscriptionSource::getId).collect(Collectors.toList());
+        SubscriptionPlanQuery subscriptionPlanQuery = new SubscriptionPlanQuery();
+        subscriptionPlanQuery.setSubscriptionSourceIds(sourceIds);
+        List<SubscriptionPlan> planList = subscriptionPlanService.getByCondition(subscriptionPlanQuery);
+        Map<Long, List<SubscriptionPlan>> sourcePlanMap = planList.stream().collect(Collectors.groupingBy(SubscriptionPlan::getSubscriptionSourceId));
+        // 对价格进行排序
+        sourcePlanMap.forEach((sourceId, pList) -> {
+            pList.sort((o1, o2) -> {
+                if (Objects.isNull(o1.getSubscriptionDuration()) || Objects.isNull(o2.getSubscriptionDuration())) {
+                    return 0;
+                }
+                return o1.getSubscriptionDuration().compareTo(o2.getSubscriptionDuration());
+            });
+        });
+
+        return sourceList.stream().map(source -> {
+            SubscriptionSourceVO subscriptionSourceVO = new SubscriptionSourceVO();
+            BeanUtils.copyProperties(source, subscriptionSourceVO);
+            List<SubscriptionPlan> subscriptionPlans = sourcePlanMap.get(source.getId());
+            if (!CollectionUtils.isEmpty(subscriptionPlans)) {
+                subscriptionSourceVO.setSubscriptionPrice(subscriptionPlans.get(0).getSubscriptionPrice());
+            }
+            return subscriptionSourceVO;
+        }).toList();
     }
 
     @Override
-    public List<SubscriptionSourceVO> queryUserSubSource() {
-        Long userId = Optional.ofNullable(UserUtils.getCurrentUserId()).orElseThrow(() -> BusinessException.fail("无法获取当前用户ID"));
+    public SubscriptionSourceDetailVO querySourceDetail(Long id) {
+        SubscriptionSource subscriptionSource = subscriptionSourceService.getById(id);
+        Assert.isNullInBusiness(subscriptionSource, "找不到对应的订阅源");
+
+        // 处理图片
+        SubscriptionSourceDetailVO subscriptionSourceDetailVO = new SubscriptionSourceDetailVO();
+        BeanUtils.copyProperties(subscriptionSource, subscriptionSourceDetailVO);
+        if (StringUtils.hasText(subscriptionSource.getPics())) {
+            subscriptionSourceDetailVO.setPics(Arrays.asList(subscriptionSource.getPics().split(",")));
+        }
+
+        SubscriptionPlanQuery subscriptionPlanQuery = new SubscriptionPlanQuery();
+        subscriptionPlanQuery.setSubscriptionSourceIds(Arrays.asList(subscriptionSource.getId()));
+        List<SubscriptionPlan> planList = subscriptionPlanService.getByCondition(subscriptionPlanQuery);
+        if (CollectionUtils.isEmpty(planList)) {
+            return subscriptionSourceDetailVO;
+        }
+
+        // 按价格进行排序
+        planList.sort((o1, o2) -> {
+            if (Objects.isNull(o1.getSubscriptionDuration()) || Objects.isNull(o2.getSubscriptionDuration())) {
+                return 0;
+            }
+            return o1.getSubscriptionDuration().compareTo(o2.getSubscriptionDuration());
+        });
+        List<SubscriptionSourcePlanVO> subscriptionSourcePlanVOS = planList.stream().map(plan -> {
+            SubscriptionSourcePlanVO subscriptionSourcePlanVO = new SubscriptionSourcePlanVO();
+            BeanUtils.copyProperties(plan, subscriptionSourcePlanVO);
+            return subscriptionSourcePlanVO;
+        }).toList();
+        subscriptionSourceDetailVO.setSubscriptionPlans(subscriptionSourcePlanVOS);
+
+        return subscriptionSourceDetailVO;
+    }
+
+    @Override
+    public List<SubscriptionUserConfigVO> querySourceUserConfig() {
         // 查询当前用户拥有的订阅源
-        SubscriptionUserConfigQuery configQuery = new SubscriptionUserConfigQuery();
-        configQuery.setUserId(userId);
-        List<SubscriptionUserConfig> userConfigList = subscriptionUserConfigService.getByCondition(configQuery);
+        SubscriptionUserConfigQuery subscriptionUserConfigQuery = new SubscriptionUserConfigQuery();
+        subscriptionUserConfigQuery.setUserId(UserUtils.getCurrentUserId());
+        List<SubscriptionUserConfig> userConfigList = subscriptionUserConfigService.getByCondition(subscriptionUserConfigQuery);
         if (CollectionUtils.isEmpty(userConfigList)) {
             return List.of();
         }
 
         //查询订阅源信息
-        Set<Long> sourceIds = userConfigList.stream().map(SubscriptionUserConfig::getSubscriptionSourceId).collect(Collectors.toSet());
-        SubscriptionSourceQuery sourceQuery = new SubscriptionSourceQuery();
-        sourceQuery.setIds(sourceIds);
-        return querySubscriptionSourceVO(sourceQuery);
+        Set<Long> subscriptionSourceIds = userConfigList.stream().map(SubscriptionUserConfig::getSubscriptionSourceId).collect(Collectors.toSet());
+        SubscriptionSourceQuery subscriptionSourceQuery = new SubscriptionSourceQuery();
+        subscriptionSourceQuery.setIds(subscriptionSourceIds);
+        List<SubscriptionSource> subscriptionSourceList = subscriptionSourceService.getByCondition(subscriptionSourceQuery);
+        if (CollectionUtils.isEmpty(subscriptionSourceList)) {
+            throw BusinessException.fail("根据配置找不到对应的订阅源信息");
+        }
+
+        Map<Long, SubscriptionSource> subscriptionSourceMap = subscriptionSourceList.stream().collect(Collectors.toMap(SubscriptionSource::getId, Function.identity()));
+        return userConfigList.stream().map(userConfig -> {
+            SubscriptionUserConfigVO subscriptionUserConfigVO = new SubscriptionUserConfigVO();
+            BeanUtils.copyProperties(userConfig, subscriptionUserConfigVO);
+            SubscriptionSource subscriptionSource = subscriptionSourceMap.get(userConfig.getSubscriptionSourceId());
+            if (Objects.nonNull(subscriptionSource)) {
+                subscriptionUserConfigVO.setTitle(subscriptionSource.getTitle());
+                subscriptionUserConfigVO.setSubTitle(subscriptionSource.getSubTitle());
+            }
+            return subscriptionUserConfigVO;
+        }).toList();
     }
 
     /**
      * 根据条件查询订阅源
      * @return
      */
-    private List<SubscriptionSourceVO> querySubscriptionSourceVO(SubscriptionSourceQuery query) {
+    private List<SubscriptionSourceDetailVO> querySubscriptionSourceVO(SubscriptionSourceQuery query) {
         if (Objects.isNull(query)) {
             return List.of();
         }
@@ -78,7 +168,7 @@ public class SubscriptionManagerImpl implements ISubscriptionManager {
             return List.of();
         }
         return sourceList.stream().map(source -> {
-            SubscriptionSourceVO sourceVO = new SubscriptionSourceVO();
+            SubscriptionSourceDetailVO sourceVO = new SubscriptionSourceDetailVO();
             BeanUtils.copyProperties(source, sourceVO);
             if (StringUtils.hasText(source.getPics())) {
                 List<String> picList = Arrays.stream(source.getPics().split(",")).toList();

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

@@ -34,9 +34,6 @@ public class TokenManagerImpl implements ITokenManager {
 
     @Override
     public String refreshToken() {
-        // 获取用户信息
-        Long currentUserId =
-            Optional.ofNullable(UserUtils.getCurrentUserId()).orElseThrow(() -> BusinessException.fail("无法获取当前用户ID"));
-        return createToken(currentUserId);
+        return createToken(UserUtils.getCurrentUserId());
     }
 }

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

@@ -1,26 +1,25 @@
 package com.dataeasy.server.service.manager.impl;
 
-import java.math.BigDecimal;
 import java.util.Objects;
 
-import cn.binarywang.wx.miniapp.api.WxMaService;
-import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.common.utils.Assert;
 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.ITokenManager;
 import com.dataeasy.server.service.manager.IUserManager;
 import com.dataeasy.server.utiis.UserUtils;
-import me.chanjar.weixin.common.error.WxErrorException;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
 
 /**
  * @author tyuio
@@ -70,8 +69,7 @@ public class UserManagerImpl implements IUserManager {
 
     @Override
     public UserInfoVO queryUserInfo() {
-        Long currentUserId = UserUtils.getCurrentUserId();
-        User user = userService.getById(currentUserId);
+        User user = userService.getById(UserUtils.getCurrentUserId());
         UserInfoVO userInfoVO = new UserInfoVO();
         BeanUtils.copyProperties(user, userInfoVO);
         return userInfoVO;

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/task/AbstractTask.java

@@ -93,7 +93,7 @@ public abstract class AbstractTask {
         // 寻找要推送数据的用户
         SubscriptionUserConfigQuery userConfigQuery = new SubscriptionUserConfigQuery();
         userConfigQuery.setSubscriptionSourceIds(subscriptionSourceIds);
-        userConfigQuery.setPushOption(PushOptionEnum.ENABLE);
+        userConfigQuery.setPushOption(PushOptionEnum.ENABLED);
         userConfigQuery.setCurrentTime(new Timestamp(System.currentTimeMillis()));
         List<SubscriptionUserConfig> userConfigList = userConfigService.getByCondition(userConfigQuery);
         if (CollectionUtils.isEmpty(userConfigList)) {

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/task/DaLeTouTask.java

@@ -33,7 +33,7 @@ public class DaLeTouTask extends AbstractHzApiTask {
     @Autowired
     private IDataDaLeTouService daLeTouService;
 
-    @Scheduled(cron = "30 21 * * 1,3,6")
+    @Scheduled(cron = "30 21 * * 1,3,6 *")
     @Transactional(rollbackFor = Exception.class)
     public void exec() {
         executeMain();

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/task/IpoBondTask.java

@@ -39,7 +39,7 @@ public class IpoBondTask extends AbstractTask {
     @Autowired
     private IDataIpoBondService ipoBondService;
 
-    @Scheduled(cron = "45 8 * * *")
+    @Scheduled(cron = "45 8 * * * *")
     @Transactional(rollbackFor = Exception.class)
     public void exec() {
         executeMain();

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

@@ -37,7 +37,7 @@ public class IpoStockTask extends AbstractTask {
     @Autowired
     private IDataIpoStockService ipoStockService;
 
-    @Scheduled(cron = "45 8 * * *")
+    @Scheduled(cron = "45 8 * * * *")
     @Transactional(rollbackFor = Exception.class)
     public void exec() {
         executeMain();

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/task/ProductHuntTask.java

@@ -41,7 +41,7 @@ public class ProductHuntTask extends AbstractTask {
     @Autowired
     private IDataProductHuntPostService productHuntPostService;
 
-    @Scheduled(cron = "0 16 * * *")
+    @Scheduled(cron = "0 16 * * * *")
     @Transactional(rollbackFor = Exception.class)
     public void exec() {
         executeMain();

+ 1 - 1
data-easy/src/main/java/com/dataeasy/server/task/ShuangSeQiuTask.java

@@ -33,7 +33,7 @@ public class ShuangSeQiuTask extends AbstractHzApiTask {
     @Autowired
     private IDataShuangSeQiuService shuangSeQiuService;
 
-    @Scheduled(cron = "40 21 * * 2,4,7")
+    @Scheduled(cron = "40 21 * * 2,4,7 *")
     @Transactional(rollbackFor = Exception.class)
     public void exec() {
         executeMain();

+ 17 - 1
data-easy/src/main/java/com/dataeasy/server/utiis/UserUtils.java

@@ -1,5 +1,10 @@
 package com.dataeasy.server.utiis;
 
+import java.util.Optional;
+
+import com.dataeasy.server.common.exception.BusinessException;
+import com.dataeasy.server.common.utils.Assert;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -20,9 +25,20 @@ public class UserUtils {
 
     /**
      * 获取当前用户的ID
+     * @throws BusinessException 获取不到用户ID时会抛出异常
      * @return
      */
     public static Long getCurrentUserId() {
-        return threadLocal.get();
+        return Optional.ofNullable(threadLocal.get()).orElseThrow(() -> BusinessException.fail("无法获取当前用户ID"));
+    }
+
+    /**
+     * 获取当前用户的ID,没有则使用默认值
+     * @param userId 默认值用户ID
+     * @return 默认值
+     */
+    public static Long getCurrentUserId(Long userId) {
+        Assert.isNull(userId, "请传入默认值用户ID");
+        return Optional.ofNullable(threadLocal.get()).orElse(userId);
     }
 }

+ 34 - 0
data-easy/src/main/java/com/dataeasy/server/utiis/WeekendUtils.java

@@ -0,0 +1,34 @@
+package com.dataeasy.server.utiis;
+
+import com.dataeasy.server.common.pojo.BaseEntity;
+
+import tk.mybatis.mapper.weekend.Weekend;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @date 2025/03/09 10:15
+ * @description Tk NyBatis Weekend 工具类
+ */
+public class WeekendUtils {
+
+    /**
+     * 创建Weekend对象并排除审计字段
+     *
+     * @param entityClass 实体类的Class对象
+     * @param <T>         实体类类型
+     * @return Weekend对象
+     */
+    public static <T extends BaseEntity> Weekend<T> createExcludeAuditFields(Class<T> entityClass) {
+        Weekend<T> weekend = Weekend.of(entityClass);
+        weekend.excludeProperties(
+                BaseEntity::getCreatedBy,
+                BaseEntity::getCreationTime,
+                BaseEntity::getLastUpdatedBy,
+                BaseEntity::getLastUpdateTime,
+                BaseEntity::getVersion,
+                BaseEntity::getDeleteFlag
+        );
+        return weekend;
+    }
+}

+ 4 - 0
data-easy/src/main/resources/application-dev.yaml

@@ -7,6 +7,10 @@ spring:
       base-url: ENC(H4FobFSxLct+ZapdAa5GWKbBC3u32wRgWrVaksCJyHvyTPmpqz2P4gq7QfFPIARI)
       api-key: ENC(CXar5AEVP7jIiOpZfEzkh/4TEi0CePm+sx3ObEgYcUn4ZvDfFlprjyiU3j22x3n/bVmmC5hQlm4Zs23FnGNCB66SQ0ATB2hJ)
 
+logging:
+  level:
+    com.dataeasy.server.atomic.mapper: debug
+
 # 微信配置
 wx:
   # 服务号(TODO:目前是测试号需要修改)

+ 2 - 0
doc/sql/schema.sql

@@ -353,3 +353,5 @@ CREATE TABLE `subscription_order` (
 
 ALTER TABLE data_easy.sys_schedule_task_log ADD error_message varchar(300) NULL COMMENT '错误信息';
 ALTER TABLE data_easy.sys_schedule_task_log CHANGE error_message error_message varchar(300) NULL COMMENT '错误信息' AFTER process_status;
+ALTER TABLE data_easy.subscription_user_config MODIFY COLUMN push_option varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '消息推送选项(ENABLED-开启、DISABLED-关闭)';
+

+ 19 - 23
doc/技术文档.md

@@ -7,18 +7,14 @@
 * 用户
   * (已开发,待测试)登录
   * (小程序支持即可)注销
-  * (已开发,测试)修改昵称
-  * (已开发,测试)查询用户基本信息
+  * (已开发,测试)修改昵称
+  * (已开发,测试)查询用户基本信息
   
 * 小程序
-  * (已开发,待测试)可订阅列表查询/订阅源详情查看
-  
-    这里可以用同一个接口查看
-  
-  * (已开发,待测试)已订阅列表查询
-  
-  * (已开发,待测试)已订阅源的消息发送控制配置
-  
+  * (已开发,已测试)可订阅列表查询
+  * 订阅源详情查看
+  * (已开发,已测试)已订阅列表查询
+  * (已开发,已测试)已订阅源的消息发送控制配置
   * (已开发,待测试)每天推送的订阅源数据查看
     * 新股
     * 新债
@@ -384,19 +380,19 @@
 
 表名:subscription_task_config
 
-| 字段                   | 类型         | 描述                                |
-| ---------------------- | ------------ | ----------------------------------- |
-| id                     | bigint       | 主键                                |
-| task_code              | varchar(30)  | 定时任务编码                        |
-| task_name              | varchar(100) | 定时任务名称                        |
-| subscription_source_id | bigint       | 订阅源ID                            |
-| execute_option         | varchar(10)  | 执行选项(ENABLE-开启、DISABLE-关闭) |
-| created_by             | bigint       | 创建人                              |
-| creation_time          | timestamp    | 创建时间                            |
-| last_updated_by        | bigint       | 最后更新人                          |
-| last_update_time       | timestamp    | 最后更新时间                        |
-| version                | bigint       | 版本号                              |
-| delete_flag            | tinyint      | 逻辑删除标志(0-未删除,1-已删除)  |
+| 字段                   | 类型         | 描述                                  |
+| ---------------------- | ------------ | ------------------------------------- |
+| id                     | bigint       | 主键                                  |
+| task_code              | varchar(30)  | 定时任务编码                          |
+| task_name              | varchar(100) | 定时任务名称                          |
+| subscription_source_id | bigint       | 订阅源ID                              |
+| execute_option         | varchar(10)  | 执行选项(ENABLED-开启、DISABLED-关闭) |
+| created_by             | bigint       | 创建人                                |
+| creation_time          | timestamp    | 创建时间                              |
+| last_updated_by        | bigint       | 最后更新人                            |
+| last_update_time       | timestamp    | 最后更新时间                          |
+| version                | bigint       | 版本号                                |
+| delete_flag            | tinyint      | 逻辑删除标志(0-未删除,1-已删除)    |