Parcourir la source

订阅记录定时器检查添加
http请求工具修改

Zhangbw il y a 2 mois
Parent
commit
b52220cd3b

+ 30 - 0
src/main/java/com/yingpai/gupiao/scheduled/OrderScheduledTask.java

@@ -2,7 +2,9 @@ package com.yingpai.gupiao.scheduled;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yingpai.gupiao.domain.po.PaymentOrder;
+import com.yingpai.gupiao.domain.po.UserSubscription;
 import com.yingpai.gupiao.mapper.PaymentOrderMapper;
+import com.yingpai.gupiao.mapper.UserSubscriptionMapper;
 import jakarta.annotation.PostConstruct;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -18,6 +20,7 @@ import java.util.List;
 public class OrderScheduledTask {
 
     private final PaymentOrderMapper orderMapper;
+    private final UserSubscriptionMapper subscriptionMapper;
 
     @PostConstruct
     public void init() {
@@ -49,4 +52,31 @@ public class OrderScheduledTask {
 
         log.info("自动取消超时订单完成,共取消{}个订单", expiredOrders.size());
     }
+
+    @Scheduled(cron = "*/10 * * * * *")
+    public void expireSubscriptions() {
+        log.info("定时任务开始执行 - expireSubscriptions");
+        LocalDateTime now = LocalDateTime.now();
+
+        List<UserSubscription> expiredSubscriptions = subscriptionMapper.selectList(
+            new LambdaQueryWrapper<UserSubscription>()
+                .eq(UserSubscription::getStatus, UserSubscription.STATUS_ACTIVE)
+                .lt(UserSubscription::getExpireTime, now)
+        );
+
+        if (expiredSubscriptions.isEmpty()) {
+            log.info("没有需要过期的订阅");
+            return;
+        }
+
+        for (UserSubscription subscription : expiredSubscriptions) {
+            subscription.setStatus(UserSubscription.STATUS_EXPIRED);
+            subscription.setUpdateTime(now);
+            subscriptionMapper.updateById(subscription);
+            log.info("订阅已过期,userId: {}, poolType: {}, expireTime: {}",
+                subscription.getUserId(), subscription.getPoolType(), subscription.getExpireTime());
+        }
+
+        log.info("订阅过期处理完成,共处理{}个订阅", expiredSubscriptions.size());
+    }
 }

+ 3 - 5
src/main/java/com/yingpai/gupiao/service/impl/H5AuthServiceImpl.java

@@ -1,6 +1,7 @@
 package com.yingpai.gupiao.service.impl;
 
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.yingpai.gupiao.config.WxConfig;
@@ -11,12 +12,10 @@ import com.yingpai.gupiao.domain.vo.WxH5UserInfoVO;
 import com.yingpai.gupiao.mapper.UserMapper;
 import com.yingpai.gupiao.service.H5AuthService;
 import com.yingpai.gupiao.util.JwtUtil;
-import com.yingpai.gupiao.util.WxApiUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.client.RestTemplate;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
@@ -35,7 +34,6 @@ public class H5AuthServiceImpl implements H5AuthService {
     private final WxConfig wxConfig;
     private final UserMapper userMapper;
     private final JwtUtil jwtUtil;
-    private final RestTemplate restTemplate = new RestTemplate();
     private final ObjectMapper objectMapper = new ObjectMapper();
 
     // 微信OAuth2.0授权URL
@@ -83,7 +81,7 @@ public class H5AuthServiceImpl implements H5AuthService {
                 code
             );
 
-            String tokenResponse = restTemplate.getForObject(tokenUrl, String.class);
+            String tokenResponse = HttpUtil.get(tokenUrl);
             log.info("获取access_token响应: {}", tokenResponse);
 
             @SuppressWarnings("unchecked")
@@ -110,7 +108,7 @@ public class H5AuthServiceImpl implements H5AuthService {
                 openid
             );
 
-            String userInfoResponse = restTemplate.getForObject(userInfoUrl, String.class);
+            String userInfoResponse = HttpUtil.get(userInfoUrl);
             log.info("获取用户信息响应: {}", userInfoResponse);
 
             @SuppressWarnings("unchecked")

+ 11 - 34
src/main/java/com/yingpai/gupiao/service/impl/StockDataServiceImpl.java

@@ -1,5 +1,6 @@
 package com.yingpai.gupiao.service.impl;
 
+import cn.hutool.http.HttpUtil;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.yingpai.gupiao.domain.vo.StockInfoVO;
@@ -9,11 +10,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -28,10 +24,6 @@ public class StockDataServiceImpl implements StockDataService {
     //指数数据接口
     private static final String INDEX_URL = "https://web.ifzq.gtimg.cn/appstock/app/fqkline/get";
 
-    private final HttpClient httpClient = HttpClient.newBuilder()
-            .connectTimeout(Duration.ofSeconds(3))
-            .build();
-
     private final ObjectMapper objectMapper = new ObjectMapper();
 
     @Override
@@ -62,17 +54,12 @@ public class StockDataServiceImpl implements StockDataService {
         }
 
         String fullUrl = BASE_URL + queryBuilder.toString();
-        HttpRequest request = HttpRequest.newBuilder()
-                .uri(URI.create(fullUrl))
-                .GET()
-                .build();
 
         try {
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
-            log.debug("[批量查询] 响应: {}", response.body());
+            String body = HttpUtil.get(fullUrl);
+            log.debug("[批量查询] 响应: {}", body);
 
-            if (response.statusCode() == 200) {
-                String body = response.body();
+            if (body != null && !body.isEmpty()) {
                 String[] lines = body.split(";");
 
                 for (String line : lines) {
@@ -103,16 +90,11 @@ public class StockDataServiceImpl implements StockDataService {
             String today = java.time.LocalDate.now().toString();
             String fullUrl = INDEX_URL + "?param=sh" + code + ",day," + today + ",,640,qfq";
 
-            HttpRequest request = HttpRequest.newBuilder()
-                    .uri(URI.create(fullUrl))
-                    .GET()
-                    .build();
-
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
-            log.debug("[指数查询] 响应: {}", response.body());
+            String body = HttpUtil.get(fullUrl);
+            log.debug("[指数查询] 响应: {}", body);
 
-            if (response.statusCode() == 200) {
-                JsonNode root = objectMapper.readTree(response.body());
+            if (body != null && !body.isEmpty()) {
+                JsonNode root = objectMapper.readTree(body);
                 JsonNode qtData = root.path("data").path("sh" + code).path("qt").path("sh" + code);
 
                 if (qtData != null && qtData.isArray() && qtData.size() > 32) {
@@ -189,15 +171,10 @@ public class StockDataServiceImpl implements StockDataService {
 
             String fullUrl = TREND_URL + "?code=" + marketPrefix + stockCode;
 
-            HttpRequest request = HttpRequest.newBuilder()
-                    .uri(URI.create(fullUrl))
-                    .GET()
-                    .build();
-
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+            String body = HttpUtil.get(fullUrl);
 
-            if (response.statusCode() == 200) {
-                JsonNode root = objectMapper.readTree(response.body());
+            if (body != null && !body.isEmpty()) {
+                JsonNode root = objectMapper.readTree(body);
                 JsonNode data = root.path("data").path(marketPrefix + stockCode).path("data").path("data");
 
                 if (data != null && data.isArray()) {

+ 5 - 25
src/main/java/com/yingpai/gupiao/service/impl/StockPoolServiceImpl.java

@@ -1,5 +1,6 @@
 package com.yingpai.gupiao.service.impl;
 
+import cn.hutool.http.HttpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yingpai.gupiao.domain.po.StockInfo;
 import com.yingpai.gupiao.domain.po.StockPool;
@@ -14,11 +15,6 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
@@ -43,10 +39,6 @@ public class StockPoolServiceImpl implements StockPoolService {
     
     // 腾讯股票行情接口
     private static final String BASE_URL = "http://qt.gtimg.cn/q=";
-
-    private final HttpClient httpClient = HttpClient.newBuilder()
-            .connectTimeout(Duration.ofSeconds(5))
-            .build();
     
     @Override
     public List<StockPoolVO> getPoolStocks(Integer poolType) {
@@ -106,15 +98,9 @@ public class StockPoolServiceImpl implements StockPoolService {
 
             String url = BASE_URL + codes;
 
-            HttpRequest request = HttpRequest.newBuilder()
-                    .uri(URI.create(url))
-                    .GET()
-                    .build();
-
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+            String body = HttpUtil.get(url);
 
-            if (response.statusCode() == 200) {
-                String body = response.body();
+            if (body != null && !body.isEmpty()) {
                 String[] lines = body.split(";");
 
                 for (String line : lines) {
@@ -253,15 +239,9 @@ public class StockPoolServiceImpl implements StockPoolService {
 
             String url = BASE_URL + marketPrefix + stockCode;
 
-            HttpRequest request = HttpRequest.newBuilder()
-                    .uri(URI.create(url))
-                    .GET()
-                    .build();
-
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+            String body = HttpUtil.get(url);
 
-            if (response.statusCode() == 200) {
-                String body = response.body();
+            if (body != null && !body.isEmpty()) {
 
                 // 解析腾讯API返回格式: v_sh600519="1~贵州茅台~600519~2076.91~..."
                 int startIndex = body.indexOf("=\"");

+ 4 - 18
src/main/java/com/yingpai/gupiao/service/impl/StockSearchServiceImpl.java

@@ -1,5 +1,6 @@
 package com.yingpai.gupiao.service.impl;
 
+import cn.hutool.http.HttpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yingpai.gupiao.domain.dto.StockSearchRequest;
 import com.yingpai.gupiao.domain.dto.StockSuggestionDTO;
@@ -15,11 +16,6 @@ import org.springframework.util.StringUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.time.Duration;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -33,10 +29,6 @@ public class StockSearchServiceImpl implements StockSearchService {
     // 腾讯股票行情接口
     private static final String BASE_URL = "http://qt.gtimg.cn/q=";
 
-    private final HttpClient httpClient = HttpClient.newBuilder()
-            .connectTimeout(Duration.ofSeconds(3))
-            .build();
-
     @Override
     public StockDetailResponse search(StockSearchRequest request) {
         String keyword = request.getKeyword();
@@ -147,17 +139,11 @@ public class StockSearchServiceImpl implements StockSearchService {
 
         String fullUrl = BASE_URL + marketPrefix + stockCode;
 
-        HttpRequest request = HttpRequest.newBuilder()
-                .uri(URI.create(fullUrl))
-                .GET()
-                .build();
-
         try {
-            HttpResponse<String> httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
-            log.debug("[实时行情 {}] 响应: {}", stockCode, httpResponse.body());
+            String body = HttpUtil.get(fullUrl);
+            log.debug("[实时行情 {}] 响应: {}", stockCode, body);
 
-            if (httpResponse.statusCode() == 200) {
-                String body = httpResponse.body();
+            if (body != null && !body.isEmpty()) {
 
                 // 解析腾讯API返回格式: v_sh600519="1~贵州茅台~600519~2076.91~..."
                 int startIndex = body.indexOf("=\"");

+ 6 - 25
src/main/java/com/yingpai/gupiao/service/impl/UserStockServiceImpl.java

@@ -1,5 +1,6 @@
 package com.yingpai.gupiao.service.impl;
 
+import cn.hutool.http.HttpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -15,11 +16,6 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpResponse;
-import java.time.Duration;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
@@ -42,10 +38,6 @@ public class UserStockServiceImpl implements UserStockService {
     private static final String BASE_URL = "http://qt.gtimg.cn/q=";
     private static final String TREND_URL = "https://web.ifzq.gtimg.cn/appstock/app/minute/query";
 
-    private final HttpClient httpClient = HttpClient.newBuilder()
-            .connectTimeout(Duration.ofSeconds(3))
-            .build();
-
     private final ObjectMapper objectMapper = new ObjectMapper();
 
     @Override
@@ -129,15 +121,9 @@ public class UserStockServiceImpl implements UserStockService {
 
             String url = BASE_URL + codes;
 
-            HttpRequest request = HttpRequest.newBuilder()
-                    .uri(URI.create(url))
-                    .GET()
-                    .build();
-
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+            String body = HttpUtil.get(url);
 
-            if (response.statusCode() == 200) {
-                String body = response.body();
+            if (body != null && !body.isEmpty()) {
                 String[] lines = body.split(";");
 
                 for (String line : lines) {
@@ -271,15 +257,10 @@ public class UserStockServiceImpl implements UserStockService {
 
             String fullUrl = TREND_URL + "?code=" + marketPrefix + stockCode;
 
-            HttpRequest request = HttpRequest.newBuilder()
-                    .uri(URI.create(fullUrl))
-                    .GET()
-                    .build();
-
-            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+            String body = HttpUtil.get(fullUrl);
 
-            if (response.statusCode() == 200) {
-                JsonNode root = objectMapper.readTree(response.body());
+            if (body != null && !body.isEmpty()) {
+                JsonNode root = objectMapper.readTree(body);
                 JsonNode data = root.path("data").path(marketPrefix + stockCode).path("data").path("data");
 
                 if (data != null && data.isArray()) {

+ 4 - 9
src/main/java/com/yingpai/gupiao/util/WxApiUtil.java

@@ -1,12 +1,12 @@
 package com.yingpai.gupiao.util;
 
+import cn.hutool.http.HttpUtil;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.yingpai.gupiao.config.WxConfig;
 import com.yingpai.gupiao.domain.dto.WxLoginResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
 
 import java.util.Map;
 
@@ -20,7 +20,6 @@ import java.util.Map;
 public class WxApiUtil {
     
     private final WxConfig wxConfig;
-    private final RestTemplate restTemplate = new RestTemplate();
     private final ObjectMapper objectMapper = new ObjectMapper();
     
     /**
@@ -63,7 +62,7 @@ public class WxApiUtil {
         
         try {
             // 调用微信API
-            String response = restTemplate.getForObject(url, String.class);
+            String response = HttpUtil.get(url);
             log.info("微信API响应: {}", response);
             
             // 解析响应
@@ -115,7 +114,7 @@ public class WxApiUtil {
         
         try {
             // 调用微信API
-            String response = restTemplate.getForObject(url, String.class);
+            String response = HttpUtil.get(url);
             log.info("获取access_token响应: {}", response);
             
             // 解析响应
@@ -181,11 +180,7 @@ public class WxApiUtil {
             log.info("调用获取手机号接口,code: {}", code);
 
             // 4. 发送POST请求
-            org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
-            headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
-            org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<>(requestJson, headers);
-
-            String response = restTemplate.postForObject(url, entity, String.class);
+            String response = HttpUtil.post(url, requestJson);
             log.info("获取手机号响应: {}", response);
 
             // 5. 解析响应

+ 1 - 1
src/main/resources/application.yml

@@ -15,7 +15,7 @@ file:
 spring:
   application:
     name: gupiao
-  
+
   datasource:
     url: jdbc:mysql://localhost:3306/ry_vue_5.x?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
 #    username: root