This commit is contained in:
2025-11-06 17:23:34 +08:00
parent 3970cbbbe6
commit bd61ef108c
2 changed files with 67 additions and 9 deletions

View File

@@ -90,6 +90,22 @@ public class TencentDocConfigController extends BaseController {
config.put("appId", tencentDocConfig.getAppId());
config.put("apiBaseUrl", tencentDocConfig.getApiBaseUrl());
// 获取当前同步进度(如果有配置)
if (fileId != null && !fileId.isEmpty() && sheetId != null && !sheetId.isEmpty()) {
String syncProgressKey = "tencent:doc:sync:last_row:" + fileId + ":" + sheetId;
Integer currentProgress = redisCache.getCacheObject(syncProgressKey);
if (currentProgress != null) {
config.put("currentProgress", currentProgress);
config.put("nextStartRow", currentProgress + 1);
config.put("progressHint", String.format("已同步到第 %d 行,下次将从第 %d 行继续",
currentProgress, currentProgress + 1));
} else {
config.put("currentProgress", null);
config.put("nextStartRow", startRow);
config.put("progressHint", String.format("尚未开始同步,将从第 %d 行开始", startRow));
}
}
// 检查配置是否完整
boolean isConfigured = hasAccessToken &&
fileId != null && !fileId.isEmpty() &&
@@ -157,6 +173,13 @@ public class TencentDocConfigController extends BaseController {
redisCache.setCacheObject(REDIS_KEY_PREFIX + "sheetId", sheetId.trim(), 180, TimeUnit.DAYS);
redisCache.setCacheObject(REDIS_KEY_PREFIX + "startRow", startRow, 180, TimeUnit.DAYS);
// 清除该文档的同步进度配置更新时重置进度从新的startRow重新开始
String syncProgressKey = "tencent:doc:sync:last_row:" + fileId.trim() + ":" + sheetId.trim();
String configVersionKey = "tencent:doc:sync:config_version:" + fileId.trim() + ":" + sheetId.trim();
redisCache.deleteObject(syncProgressKey);
redisCache.deleteObject(configVersionKey);
log.info("配置已更新,已清除同步进度,将从第 {} 行重新开始同步", startRow);
// 同时更新TencentDocConfig对象内存中
tencentDocConfig.setFileId(fileId.trim());
tencentDocConfig.setSheetId(sheetId.trim());

View File

@@ -314,6 +314,7 @@ public class TencentDocController extends BaseController {
return AjaxResult.error("上传物流信息失败: " + e.getMessage());
}
}
/**
* 将单个订单的物流信息追加到表格
@@ -501,29 +502,48 @@ public class TencentDocController extends BaseController {
return AjaxResult.error("文档配置不完整,请先配置 fileId 和 sheetId");
}
log.info("同步物流配置 - fileId: {}, sheetId: {}, 数据起始行: {}, 表头行: {}",
log.info("同步物流配置 - fileId: {}, sheetId: {}, 配置起始行: {}, 表头行: {}",
fileId, sheetId, configStartRow, headerRow);
// 生成Redis key用于存储该文件的工作表的上次处理最大行数
// 生成Redis key用于存储该文件的工作表的动态处理进度
String redisKey = LAST_PROCESSED_ROW_KEY_PREFIX + fileId + ":" + sheetId;
// 生成配置版本key用于检测配置是否被重新设置
String configVersionKey = "tencent:doc:sync:config_version:" + fileId + ":" + sheetId;
String currentConfigVersion = configStartRow + "_" + headerRow; // 配置版本起始行_表头行
// 获取上次处理的最大行数
// 检查配置是否被更新(如果配置版本变化,则重置动态进度)
String savedConfigVersion = redisCache.getCacheObject(configVersionKey);
if (savedConfigVersion == null || !savedConfigVersion.equals(currentConfigVersion)) {
// 配置已更新,清除旧的处理进度
redisCache.deleteObject(redisKey);
redisCache.setCacheObject(configVersionKey, currentConfigVersion, 180, TimeUnit.DAYS);
log.info("检测到配置更新,重置同步进度 - 新配置版本: {}", currentConfigVersion);
}
// 获取动态处理进度(上次处理到的最大行数)
Integer lastMaxRow = null;
if (!forceStart && redisCache.hasKey(redisKey)) {
Object cacheObj = redisCache.getCacheObject(redisKey);
if (cacheObj != null) {
lastMaxRow = Integer.valueOf(cacheObj.toString());
log.info("读取到上次处理进度 - 最大行: {}", lastMaxRow);
}
}
// 计算起始行:从上次最大行数-100开始或者从强制指定的行开始或者从表头下一行开始
// 计算本次同步的起始行
int startRow;
if (forceStartRow != null) {
// 强制指定行(手动指定)
startRow = forceStartRow;
} else if (lastMaxRow != null && lastMaxRow > headerRow) {
startRow = Math.max(headerRow + 1, lastMaxRow - 100); // 从最大行数-100开始但至少是表头下一行
log.info("使用强制指定的起始行: {}", startRow);
} else if (lastMaxRow != null && lastMaxRow >= configStartRow) {
// 有上次进度,且大于等于配置的起始行,则从上次进度+1继续增量同步
startRow = lastMaxRow + 1;
log.info("继续上次进度,从第 {} 行开始(上次到 {} 行)", startRow, lastMaxRow);
} else {
startRow = headerRow + 1; // 默认从表头下一行开始
// 首次同步或配置被重置,使用配置的起始行
startRow = configStartRow != null ? configStartRow : (headerRow + 1);
log.info("首次同步或配置已重置,从配置的起始行开始: {}", startRow);
}
// 计算读取范围:从起始行开始,读取足够多的行
@@ -799,18 +819,33 @@ public class TencentDocController extends BaseController {
log.info("更新上次处理的最大行数 - 文件ID: {}, 工作表ID: {}, 最大行: {}", fileId, sheetId, currentMaxRow);
}
// 计算下次同步的起始行
int nextStartRow = currentMaxRow + 1;
JSONObject result = new JSONObject();
result.put("startRow", startRow);
result.put("endRow", endRow);
result.put("currentMaxRow", currentMaxRow);
result.put("lastMaxRow", lastMaxRow);
result.put("nextStartRow", nextStartRow);
result.put("filledCount", filledCount);
result.put("skippedCount", skippedCount);
result.put("errorCount", errorCount);
result.put("orderNoColumn", orderNoColumn);
result.put("logisticsLinkColumn", logisticsLinkColumn);
result.put("message", String.format("处理完成:成功填充 %d 条,跳过 %d 条,错误 %d 条,最大行号: %d",
filledCount, skippedCount, errorCount, currentMaxRow));
// 构建详细的提示信息
String message = String.format(
"✓ 同步完成:成功填充 %d 条,跳过 %d 条,错误 %d 条\n" +
" 本次范围:第 %d-%d 行\n" +
" 当前进度:第 %d 行\n" +
" 下次将从第 %d 行继续(增量同步)",
filledCount, skippedCount, errorCount,
startRow, currentMaxRow,
currentMaxRow,
nextStartRow
);
result.put("message", message);
return AjaxResult.success("填充物流链接完成", result);
} catch (Exception e) {