From 24c196c8a35c91fa67c0996b83bece85424cb6fa Mon Sep 17 00:00:00 2001 From: Van0313 <60689272+Van0313@users.noreply.github.com> Date: Sun, 1 Jun 2025 17:11:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=8A=93=E8=AF=84=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/van/business/util/JDScheduleJob.java | 119 ++++++++++++++++-- .../java/cn/van/business/util/JDUtil.java | 5 +- 2 files changed, 116 insertions(+), 8 deletions(-) diff --git a/src/main/java/cn/van/business/util/JDScheduleJob.java b/src/main/java/cn/van/business/util/JDScheduleJob.java index 7cea3c3..fa3865c 100644 --- a/src/main/java/cn/van/business/util/JDScheduleJob.java +++ b/src/main/java/cn/van/business/util/JDScheduleJob.java @@ -1,6 +1,10 @@ package cn.van.business.util; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; import cn.van.business.model.jd.OrderRow; +import cn.van.business.model.pl.Comment; +import cn.van.business.repository.CommentRepository; import cn.van.business.repository.OrderRowRepository; import cn.van.business.util.jdReq.*; import com.alibaba.fastjson2.util.DateUtils; @@ -23,9 +27,8 @@ import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.ZoneId; -import java.util.Arrays; -import java.util.Date; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; import static cn.van.business.util.JDUtil.DATE_TIME_FORMATTER; import static cn.van.business.util.WXUtil.super_admins; @@ -48,6 +51,10 @@ public class JDScheduleJob { private final StringRedisTemplate redisTemplate; private final OrderRowRepository orderRowRepository; private final OrderUtil orderUtil; + private final JDUtil jdUtil; + private final CommentRepository commentRepository; + + @Getter @Value("${isRunning.wx}") private String isRunning_wx; @@ -55,13 +62,17 @@ public class JDScheduleJob { @Getter @Value("${isRunning.jd}") private String isRunning_jd; + // 构造函数中注入StringRedisTemplate @Autowired - public JDScheduleJob(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, OrderUtil orderUtil) { + public JDScheduleJob(StringRedisTemplate redisTemplate, OrderRowRepository orderRowRepository, OrderUtil orderUtil, JDUtil jdUtil, CommentRepository commentRepository) { this.redisTemplate = redisTemplate; this.orderRowRepository = orderRowRepository; this.orderUtil = orderUtil; + this.jdUtil = jdUtil; + this.commentRepository = commentRepository; } + /** * 将 响应参数转化为 OrderRow,并返回 */ @@ -136,6 +147,7 @@ public class JDScheduleJob { orderRow.setTraceType(orderRowResp.getTraceType()); return orderRow; } + /** * 根据指定的日期时间拉取订单 * @@ -197,6 +209,7 @@ public class JDScheduleJob { private void processOrderResponse(UnionOpenOrderRowQueryResponse response, WXUtil.SuperAdmin admin) { Arrays.stream(response.getQueryResult().getData()).parallel().map(this::createOrderRow).forEach(orderRowRepository::save); } + public int fetchOrders(OrderFetchStrategy strategy, String appKey, String secretKey) { TimeRange range = strategy.calculateRange(LocalDateTime.now()); @@ -270,6 +283,7 @@ public class JDScheduleJob { }); } } + /** * 扫描订单发送到微信 * 每分钟的30秒执行一次 @@ -285,7 +299,7 @@ public class JDScheduleJob { for (OrderRow orderRow : orderRows) { - orderUtil.orderToWx(orderRow, true,false); + orderUtil.orderToWx(orderRow, true, false); } @@ -305,7 +319,7 @@ public class JDScheduleJob { OrderFetchStrategy strategy = new Days3090Strategy(); for (WXUtil.SuperAdmin admin : super_admins.values()) { try { - if (Util.isAnyEmpty(admin.getAppKey(), admin.getSecretKey())){ + if (Util.isAnyEmpty(admin.getAppKey(), admin.getSecretKey())) { continue; } int count = fetchOrders(strategy, admin.getAppKey(), admin.getSecretKey()); @@ -332,7 +346,7 @@ public class JDScheduleJob { OrderFetchStrategy strategy = new Days1430Strategy(); // 需补充Days1430Strategy实现 for (WXUtil.SuperAdmin admin : super_admins.values()) { try { - if (Util.isAnyEmpty(admin.getAppKey(), admin.getSecretKey())){ + if (Util.isAnyEmpty(admin.getAppKey(), admin.getSecretKey())) { continue; } int count = fetchOrders(strategy, admin.getAppKey(), admin.getSecretKey()); @@ -398,6 +412,7 @@ public class JDScheduleJob { } } + /** * 获取订单列表 * @@ -435,4 +450,94 @@ public class JDScheduleJob { return client.execute(request); } +@Scheduled(cron = "0 0 8-20 * * ?") // 每天从 8:00 到 20:00,每小时执行一次 +public void fetchPL() { + // 设置每天最多执行 3 次 + String cacheKey = "fetchPL:executedHours"; + Set executedHours = getExecutedHoursFromRedis(); // 从 Redis 获取已执行的小时数 + + LocalDateTime now = LocalDateTime.now(); + String currentHour = String.valueOf(now.getHour()); + + // 如果今天已经执行了3次,则跳过 + if (executedHours.size() >= 3) { + return; + } + + // 随机决定是否执行本次任务(例如 50% 概率) + if (new Random().nextBoolean()) { + // 执行任务逻辑 + executeFetchPL(); + // 记录该小时已执行 + executedHours.add(currentHour); + saveExecutedHoursToRedis(executedHours); // 存入 Redis + } +} + + + private void executeFetchPL() { + HashMap productTypeMap = jdUtil.getProductTypeMap(); + int allCommentCount = 0; + int usedCommentCount = 0; + int canUseComentCount = 0; + int addCommentCount = 0; + for (Map.Entry entry : productTypeMap.entrySet()) { + + // 随机睡眠1-5分钟 + int sleepTime = new Random().nextInt(300) + 60; + try { + Thread.sleep(sleepTime * 1000); + } catch (InterruptedException e) { + logger.error("线程中断", e); + } + + String product_id = entry.getKey(); + List availableComments = commentRepository.findByProductIdAndIsUseNotAndPictureUrlsIsNotNull(product_id, 1); + List usedComments = commentRepository.findByProductIdAndIsUseNotAndPictureUrlsIsNotNull(product_id, 0); + + canUseComentCount = availableComments.size(); + usedCommentCount = usedComments.size(); + if (canUseComentCount > 5){ + logger.info("商品{} 评论可用数量大于5:{}", product_id, canUseComentCount); + return; + } + + + try { + String fetchUrl = "http://192.168.8.6:5000/fetch_comments?product_id=" + product_id; + // 用hutool发起post请求 + HttpResponse response = HttpRequest.post(fetchUrl).timeout(60000).execute(); + + logger.info("fetchUrl: {}", fetchUrl); +// code = 200 表示成功,-200 表示失败 + if (response.getStatus() == 200) { + // ✅ 关键修改:重新从数据库中查询,而不是使用内存中的 fetchedComments + availableComments = commentRepository.findByProductIdAndIsUseNotAndPictureUrlsIsNotNull(product_id, 1); + if (!availableComments.isEmpty()) { + addCommentCount = availableComments.size() - canUseComentCount; + logger.info("自动刷新并且获取评论成功"); + logger.info("型号{} 总评论数量 {} 可用数量 {} 新增评论数量:{}", entry.getValue(), availableComments.size() + usedCommentCount, canUseComentCount, addCommentCount); + } + } else if (response.getStatus() == -200) { + return; + } + } catch (Exception e) { + logger.error("调用外部接口获取评论失败", e); + return; + } + } + } + + private Set getExecutedHoursFromRedis() { + String key = "fetchPL:executedHours"; + HashOperations hashOps = redisTemplate.opsForHash(); + return hashOps.entries(key).keySet(); + } + + private void saveExecutedHoursToRedis(Set hours) { + String key = "fetchPL:executedHours"; + HashOperations hashOps = redisTemplate.opsForHash(); + hashOps.putAll(key, hours.stream().collect(Collectors.toMap(h -> h, h -> "1"))); + } + } diff --git a/src/main/java/cn/van/business/util/JDUtil.java b/src/main/java/cn/van/business/util/JDUtil.java index 52307da..a14f5fd 100644 --- a/src/main/java/cn/van/business/util/JDUtil.java +++ b/src/main/java/cn/van/business/util/JDUtil.java @@ -1771,7 +1771,7 @@ public class JDUtil { } //getProductTypeMap 从redis中获取PRODUCT_TYPE_MAP_PREFIX - public void getProductTypeMap() { + public HashMap getProductTypeMap() { Map rawMap = redisTemplate.opsForHash().entries(PRODUCT_TYPE_MAP_PREFIX); if (!rawMap.isEmpty()) { @@ -1781,9 +1781,11 @@ public class JDUtil { } // 排序 productTypeMap = productTypeMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + return productTypeMap; } else { logger.warn("Redis 中未找到键为 {} 的 Hash 数据", PRODUCT_TYPE_MAP_PREFIX); } + return null; } public void addProductTypeMap(String key, String value) { @@ -1819,6 +1821,7 @@ public class JDUtil { * 生成评论内容 */ private synchronized void generateComment(String fromWxid, String productType) { + //wxUtil.sendTextMessage(fromWxid, "已接收到评论生成指令,等候过程请勿重复输入", 1, fromWxid, true); int allCommentCount = 0; int usedCommentCount = 0;