自动抓评论
This commit is contained in:
@@ -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秒执行一次
|
||||
@@ -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<String> 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<String, String> productTypeMap = jdUtil.getProductTypeMap();
|
||||
int allCommentCount = 0;
|
||||
int usedCommentCount = 0;
|
||||
int canUseComentCount = 0;
|
||||
int addCommentCount = 0;
|
||||
for (Map.Entry<String, String> 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<Comment> availableComments = commentRepository.findByProductIdAndIsUseNotAndPictureUrlsIsNotNull(product_id, 1);
|
||||
List<Comment> 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<String> getExecutedHoursFromRedis() {
|
||||
String key = "fetchPL:executedHours";
|
||||
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
|
||||
return hashOps.entries(key).keySet();
|
||||
}
|
||||
|
||||
private void saveExecutedHoursToRedis(Set<String> hours) {
|
||||
String key = "fetchPL:executedHours";
|
||||
HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
|
||||
hashOps.putAll(key, hours.stream().collect(Collectors.toMap(h -> h, h -> "1")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1771,7 +1771,7 @@ public class JDUtil {
|
||||
}
|
||||
|
||||
//getProductTypeMap 从redis中获取PRODUCT_TYPE_MAP_PREFIX
|
||||
public void getProductTypeMap() {
|
||||
public HashMap<String, String> getProductTypeMap() {
|
||||
Map<Object, Object> 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;
|
||||
|
||||
Reference in New Issue
Block a user