1
This commit is contained in:
@@ -57,8 +57,10 @@ public class TencentDocController extends BaseController {
|
||||
/** Redis key前缀,用于存储上次处理的最大行数 */
|
||||
private static final String LAST_PROCESSED_ROW_KEY_PREFIX = "tendoc:last_row:";
|
||||
|
||||
/** 单次请求最大行数(腾讯文档 API range 限制,避免 invalid param range) */
|
||||
private static final int API_MAX_ROWS_PER_REQUEST = 200;
|
||||
/** 单次请求最大行数(腾讯文档 API:行数≤1000,一次拉 500 行) */
|
||||
private static final int API_MAX_ROWS_PER_REQUEST = 500;
|
||||
/** 数据区 range 列尾(30 列 = A 到 AD,API 列数≤200) */
|
||||
private static final String DATA_RANGE_COL_END = "AD";
|
||||
/** 回溯行数:下次起始行 = 本次扫描终点 + 1 - 回溯,用于覆盖物流变更或延后补填 */
|
||||
private static final int BACKTRACK_ROWS = 80;
|
||||
/** 整批都跳过(0 写入)时使用的回溯行数,减小回溯以尽快扫到后续行(如 308) */
|
||||
@@ -1168,7 +1170,7 @@ public class TencentDocController extends BaseController {
|
||||
if (tryEndRow < startRow) {
|
||||
continue;
|
||||
}
|
||||
String range = String.format("A%d:Z%d", startRow, tryEndRow);
|
||||
String range = String.format("A%d:%s%d", startRow, DATA_RANGE_COL_END, tryEndRow);
|
||||
log.info("开始读取数据行 - 行号: {} ~ {} (共 {} 行), range: {} (尝试 decrement={})", startRow, tryEndRow, tryRowCount, range, decrement);
|
||||
try {
|
||||
sheetData = tencentDocService.readSheetData(accessToken, fileId, sheetId, range);
|
||||
@@ -1198,7 +1200,7 @@ public class TencentDocController extends BaseController {
|
||||
for (int decrement : new int[] { 1, 10 }) {
|
||||
int tryEndRow = Math.max(startRow, effectiveEndRow - decrement);
|
||||
if (tryEndRow >= startRow) {
|
||||
String retryRange = String.format("A%d:Z%d", startRow, tryEndRow);
|
||||
String retryRange = String.format("A%d:%s%d", startRow, DATA_RANGE_COL_END, tryEndRow);
|
||||
try {
|
||||
sheetData = tencentDocService.readSheetData(accessToken, fileId, sheetId, retryRange);
|
||||
if (sheetData != null) {
|
||||
@@ -1221,7 +1223,7 @@ public class TencentDocController extends BaseController {
|
||||
}
|
||||
}
|
||||
endRow = effectiveEndRow; // 后续统一使用实际读取成功的 endRow
|
||||
String range = String.format("A%d:Z%d", startRow, endRow);
|
||||
String range = String.format("A%d:%s%d", startRow, DATA_RANGE_COL_END, endRow);
|
||||
log.info("解析后的数据行数: {}", values != null ? values.size() : "null");
|
||||
|
||||
if (values == null || values.isEmpty()) {
|
||||
@@ -2122,8 +2124,8 @@ public class TencentDocController extends BaseController {
|
||||
int skippedCount = 0;
|
||||
int errorCount = 0;
|
||||
|
||||
// 分批读取数据,每批200行(避免单次读取过多数据导致API限制)
|
||||
final int BATCH_SIZE = 200;
|
||||
// 分批读取数据,每批500行(API 行数≤1000,列数≤200)
|
||||
final int BATCH_SIZE = 500;
|
||||
int currentStartRow = startRow;
|
||||
int totalBatches = (int) Math.ceil((double)(endRow - startRow + 1) / BATCH_SIZE);
|
||||
int currentBatch = 0;
|
||||
@@ -2421,8 +2423,8 @@ public class TencentDocController extends BaseController {
|
||||
int errorCount = 0; // 错误数量
|
||||
java.util.List<String> updatedOrderNos = new java.util.ArrayList<>(); // 更新的单号列表
|
||||
|
||||
// 分批读取数据,每批200行(避免单次读取过多数据导致API限制)
|
||||
final int BATCH_SIZE = 200;
|
||||
// 分批读取数据,每批500行(API 行数≤1000,列数≤200)
|
||||
final int BATCH_SIZE = 500;
|
||||
int currentStartRow = startRow;
|
||||
int totalBatches = (int) Math.ceil((double)(endRow - startRow + 1) / BATCH_SIZE);
|
||||
int currentBatch = 0;
|
||||
|
||||
@@ -292,7 +292,7 @@ public class TencentDocDelayedPushServiceImpl implements ITencentDocDelayedPushS
|
||||
"AUTO",
|
||||
"DELAYED_TIMER",
|
||||
startRow,
|
||||
startRow + 199 // 与 Controller API_MAX_ROWS_PER_REQUEST=200 一致(单批最多200行)
|
||||
startRow + 499 // 与 Controller API_MAX_ROWS_PER_REQUEST=500 一致(单批最多500行)
|
||||
);
|
||||
log.info("✓ 创建批量推送记录,批次ID: {}", batchId);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -344,9 +345,15 @@ public class TencentDocApiUtil {
|
||||
*/
|
||||
public static JSONObject readSheetData(String accessToken, String appId, String openId, String fileId, String sheetId, String range, String apiBaseUrl) {
|
||||
// V3版本API路径格式:/openapi/spreadsheet/v3/files/{fileId}/{sheetId}/{range}
|
||||
// range格式:A1表示法(Excel格式),如 A10:D11
|
||||
String apiUrl = String.format("%s/files/%s/%s/%s", apiBaseUrl, fileId, sheetId, range);
|
||||
log.info("读取表格数据 - fileId: {}, sheetId: {}, range: {}, apiUrl: {}", fileId, sheetId, range, apiUrl);
|
||||
// range 需 URL 编码,否则 path 中的 ":" 会导致网关/服务端报 range invalid (400001)
|
||||
String encodedRange;
|
||||
try {
|
||||
encodedRange = URLEncoder.encode(range, StandardCharsets.UTF_8.name());
|
||||
} catch (java.io.UnsupportedEncodingException e) {
|
||||
encodedRange = range.replace(":", "%3A");
|
||||
}
|
||||
String apiUrl = String.format("%s/files/%s/%s/%s", apiBaseUrl, fileId, sheetId, encodedRange);
|
||||
log.info("读取表格数据 - fileId: {}, sheetId: {}, range: {} (encoded: {}), apiUrl: {}", fileId, sheetId, range, encodedRange, apiUrl);
|
||||
return callApi(accessToken, appId, openId, apiUrl, "GET", null);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user