提交 6f5c754d authored 作者: 窦馨雨's avatar 窦馨雨

合并分支 'dxy' 到 'qa'

勤策订单明细定时功能更新时间获取方式 查看合并请求 !134
package com.sfa.job.service.order;
import java.time.LocalDateTime;
/**
* @Author: DouXinYu
* @Date: 2026-02-27 18:33
......
......@@ -8,9 +8,14 @@ import com.sfa.job.service.order.IQinceOrderInformationSyncService;
import com.sfa.job.util.QinCeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @Author: DouXinYu
......@@ -27,6 +32,12 @@ public class QinceOrderInformationSyncServiceImpl implements IQinceOrderInformat
@Autowired
IQinceOrderCoreDao qinceOrderCoreDao;
@Autowired
private RedisTemplate<String, String> redisTemplate;
// Redis断点key(自定义,用于存储上一次拉取的结束时间)
private static final String QC_ORDER_BREAKPOINT_KEY = "qc:order:pull:breakpoint";
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 同步勤策订单信息
......@@ -34,10 +45,13 @@ public class QinceOrderInformationSyncServiceImpl implements IQinceOrderInformat
@Override
public void syncQinceOrderInformation() {
log.info("================= 开始同步勤策订单信息 ==================");
// 1. 获取上一次的断点(首次为昨天0点)
LocalDateTime startTime = getBreakpoint();
LocalDateTime endTime = LocalDateTime.now();
log.info("开始拉取勤策订单,断点起始时间:{}", startTime.format(FORMATTER));
try {
log.info("================ 开始查询前1天所有订单 ===================");
JSONArray orderList = qinCeUtils.queryLastDayAllOrder();
log.info("================ 开始查询订单 ===================");
JSONArray orderList = qinCeUtils.queryLastDayAllOrder(startTime);
log.info("查询前1天所有订单完成,订单数:{}", orderList.size());
if (CollectionUtils.isEmpty(orderList)){
......@@ -53,6 +67,9 @@ public class QinceOrderInformationSyncServiceImpl implements IQinceOrderInformat
log.info("处理第{}条订单数据完成", i + 1);
}
log.info("================== 处理订单数据完成 ====================");
updateBreakpoint(endTime);
log.info("================== 断点更新完成,新断点:{} ====================", endTime.format(FORMATTER));
} catch (Exception e) {
throw new RuntimeException(e);
......@@ -60,6 +77,36 @@ public class QinceOrderInformationSyncServiceImpl implements IQinceOrderInformat
}
/**
* 获取Redis中的断点(上一次拉取的结束时间)
* 首次/断点解析失败时,返回昨天0点
*/
private LocalDateTime getBreakpoint() {
try {
String breakpointStr = redisTemplate.opsForValue().get(QC_ORDER_BREAKPOINT_KEY);
if (breakpointStr != null && !breakpointStr.isEmpty()) {
return LocalDateTime.parse(breakpointStr, FORMATTER);
}
} catch (Exception e) {
log.error("解析Redis断点失败,初始化断点为昨天0点", e);
}
// 首次/解析失败:断点为昨天0点
LocalDate yesterday = LocalDate.now().minusDays(1);
return yesterday.atStartOfDay();
}
/**
* 更新断点到Redis(存储本次拉取的结束时间)
*/
private void updateBreakpoint(LocalDateTime endTime) {
try {
redisTemplate.opsForValue().set(QC_ORDER_BREAKPOINT_KEY, endTime.format(FORMATTER));
} catch (Exception e) {
log.error("更新Redis断点失败", e);
throw new RuntimeException("更新订单拉取断点失败:" + e.getMessage(), e);
}
}
private void processAndSaveData(JSONObject order) {
qinceOrderCoreDao.save(order);
......
......@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
......@@ -241,18 +242,16 @@ public class QinCeUtils {
return postQC(url, params);
}
public Map<String, Object> queryLastDayOrderParams(Integer pageNum, Integer rows) {
public Map<String, Object> queryLastDayOrderParams(Integer pageNum, Integer rows, LocalDateTime startTime) {
// 计算前一天
LocalDate today = LocalDate.now();
LocalDate yesterday = today.minusDays(1);
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String startTime = yesterday.atStartOfDay().format(formatter);
String endTime = yesterday.atTime(23, 59, 59).format(formatter);
String endTime = now.format(formatter);
Map<String, Object> params = new HashMap<>();
params.put("page_number", String.valueOf(pageNum));
params.put("page_length", String.valueOf(rows));
params.put("start_modify_date", startTime);
params.put("start_modify_date", startTime.format(formatter));
params.put("end_modify_date", endTime);
return params;
}
......@@ -260,16 +259,16 @@ public class QinCeUtils {
/**
* 拉取前一天所有订单
*/
public JSONArray queryLastDayAllOrder() throws Exception {
public JSONArray queryLastDayAllOrder(LocalDateTime startTime) throws Exception {
JSONArray allOrders = new JSONArray();
int currentPage = 1;
int pageSize = 1000;
// 循环分页拉取,直到无数据返回
while (true) {
Map<String, Object> params = queryLastDayOrderParams(currentPage, pageSize);
Map<String, Object> params = queryLastDayOrderParams(currentPage, pageSize,startTime);
String url = builderUrl(QUERY_ORDER_DETAIL, params);
log.info("自动查询前一天订单 - 第{}页,请求URL:{}", currentPage, url);
log.info("自动查询订单 - 第{}页,请求URL:{}", currentPage, url);
try {
JSONObject resp = postQC(url, params);
......@@ -277,7 +276,7 @@ public class QinCeUtils {
// 终止条件:当前页无数据,退出循环
if (pageData == null || pageData.isEmpty()) {
log.info("前一天订单查询完成,共拉取{}页,总订单数:{}", currentPage - 1, allOrders.size());
log.info("订单查询完成,共拉取{}页,总订单数:{}", currentPage - 1, allOrders.size());
break;
}
......@@ -286,7 +285,7 @@ public class QinCeUtils {
currentPage++;
} catch (Exception e) {
log.error("自动查询前一天订单第{}页失败", currentPage, e);
log.error("自动查询订单第{}页失败", currentPage, e);
throw new RuntimeException("自动分页拉取订单数据失败,页码:" + currentPage, e);
}
}
......
......@@ -19,7 +19,7 @@ public class QinceOrderInformationTask {
/**
* 同步勤策订单数据
* 每天 00:45:00 执行 0 45 0 * * ?
* 每2小时拉取一次数据 00:45:00
*/
@XxlJob("sync_qc_order_information")
public void syncQcOrderInformation(){
......@@ -31,6 +31,7 @@ public class QinceOrderInformationTask {
XxlJobHelper.log("xxl-job同步-勤策订单数据异常");
XxlJobHelper.log("失败信息如下:");
XxlJobHelper.log(e);
XxlJobHelper.handleFail("同步勤策订单失败:" + e.getMessage());
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论