Zhangbw 2 месяцев назад
Родитель
Сommit
a64cdf10c2

+ 2 - 0
src/main/java/com/yingpai/gupiao/GupiaoApplication.java

@@ -3,9 +3,11 @@ package com.yingpai.gupiao;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
 @MapperScan("com.yingpai.gupiao.mapper")
+@EnableScheduling
 public class GupiaoApplication {
 
     public static void main(String[] args) {

+ 17 - 10
src/main/java/com/yingpai/gupiao/config/WebMvcConfig.java

@@ -24,17 +24,24 @@ public class WebMvcConfig implements WebMvcConfigurer {
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(authInterceptor)
-                // 需要认证的路径
-                .addPathPatterns("/v1/user/**")
-                .addPathPatterns("/v1/order/**")
+                // 需要认证的路径(按优先级排列)
+                .addPathPatterns("/v1/user/**")           // 用户相关(包括自选股票)
+                .addPathPatterns("/v1/order/**")          // 订单相关
+                .addPathPatterns("/v1/stock/history/**")  // 历史查询(需要订阅)
+                .addPathPatterns("/v1/file/**")           // 文件上传
                 // 排除不需要认证的路径
-                .excludePathPatterns("/v1/auth/**")
-                .excludePathPatterns("/v1/stock/**")
-                .excludePathPatterns("/v1/order/notify/**")
-                .excludePathPatterns("/v1/order/config/**")
-                .excludePathPatterns("/v1/agreement/**")
-                .excludePathPatterns("/api/**")
-                .excludePathPatterns("/uploads/**");
+                .excludePathPatterns("/v1/auth/**")       // 认证接口
+                .excludePathPatterns("/v1/stock/pool/**") // 股票池列表(公开)
+                .excludePathPatterns("/v1/stock/search")  // 股票搜索(公开)
+                .excludePathPatterns("/v1/stock/suggestion") // 搜索建议(公开)
+                .excludePathPatterns("/v1/stock/history/stats") // 历史统计(公开,用于性能指标展示)
+                .excludePathPatterns("/v1/stock/history/search") // 历史搜索(公开,用于打分查询)
+                .excludePathPatterns("/v1/order/notify/**")  // 支付回调
+                .excludePathPatterns("/v1/order/config")     // 支付配置(公开)
+                .excludePathPatterns("/v1/order/check-subscription") // 订阅检查
+                .excludePathPatterns("/v1/agreement/**")  // 协议内容(公开)
+                .excludePathPatterns("/api/**")           // 外部API
+                .excludePathPatterns("/uploads/**");      // 静态资源
         log.info("认证拦截器已注册");
     }
 

+ 5 - 1
src/main/java/com/yingpai/gupiao/service/impl/OrderServiceImpl.java

@@ -45,8 +45,12 @@ public class OrderServiceImpl implements OrderService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public WxPayVO createOrder(Long userId, String openid, CreateOrderDTO dto) {
+        if (hasActiveSubscription(userId, dto.getPoolType())) {
+            throw new RuntimeException("您已订阅该池,无需重复购买");
+        }
+
         PaymentConfigVO config = configService.getConfig(dto.getPoolType());
-        
+
         String orderNo = generateOrderNo();
         int amountFen = config.getPrice().multiply(new BigDecimal("100")).intValue();
 

+ 6 - 4
src/main/resources/application.yml

@@ -18,10 +18,12 @@ spring:
   
   datasource:
     url: jdbc:mysql://localhost:3306/ry_vue_5.x?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
-    username: root
-    password: 121380
+#    username: root
+    username: gupiao
+#    password: 121380
+    password: zQpdD3AmAPNCTFMyYARWMXnHSAbeHKEDNDHDYDZrFTAYGXGNVs
     driver-class-name: com.mysql.cj.jdbc.Driver
-  
+
   servlet:
     multipart:
       max-file-size: 10MB
@@ -32,7 +34,6 @@ mybatis-plus:
   configuration:
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 
-
 # 日志配置
 logging:
   level:
@@ -41,6 +42,7 @@ logging:
     com.baomidou.mybatisplus: debug
     org.springframework.jdbc.datasource.DataSourceTransactionManager: debug
     org.springframework.jdbc.core.JdbcTemplate: debug
+  config: classpath:logback-plus.xml
 
 # JWT配置
 jwt:

+ 129 - 0
src/main/resources/logback-plus.xml

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <property name="log.path" value="./logs"/>
+    <property name="console.log.pattern"
+              value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
+    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${console.log.pattern}</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+
+    <!-- 控制台输出 -->
+    <appender name="file_console" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sys-console.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-console.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大 1天 -->
+            <maxHistory>1</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+        </filter>
+    </appender>
+
+    <!-- 系统日志输出 -->
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sys-info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sys-error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- info异步输出 -->
+    <appender name="async_info" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
+        <queueSize>512</queueSize>
+        <!-- 添加附加的appender,最多只能添加一个 -->
+        <appender-ref ref="file_info"/>
+    </appender>
+
+    <!-- error异步输出 -->
+    <appender name="async_error" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
+        <queueSize>512</queueSize>
+        <!-- 添加附加的appender,最多只能添加一个 -->
+        <appender-ref ref="file_error"/>
+    </appender>
+
+    <!-- 整合 skywalking 控制台输出 tid -->
+<!--    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">-->
+<!--        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
+<!--            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
+<!--                <pattern>[%tid] ${console.log.pattern}</pattern>-->
+<!--            </layout>-->
+<!--            <charset>utf-8</charset>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!-- 整合 skywalking 推送采集日志 -->
+<!--    <appender name="sky_log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">-->
+<!--        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">-->
+<!--            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">-->
+<!--                <pattern>[%tid] ${console.log.pattern}</pattern>-->
+<!--            </layout>-->
+<!--            <charset>utf-8</charset>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="console" />
+        <appender-ref ref="async_info" />
+        <appender-ref ref="async_error" />
+        <appender-ref ref="file_console" />
+<!--        <appender-ref ref="sky_log"/>-->
+    </root>
+
+</configuration>

+ 2 - 0
src/main/resources/sql/stock_pool.sql

@@ -24,4 +24,6 @@ CREATE TABLE IF NOT EXISTS `stock_pool` (
     UNIQUE KEY `uk_stock_pool_type` (`stock_code`, `pool_type`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='股票池表(超短池/强势池)';
 
+SET FOREIGN_KEY_CHECKS = 1;
+