修复货源查询 404 行被过滤且状态列置空:Python 404 的 ASIN 保留导出并标记「ASIN未找到」
Build Backend JAR / build (push) Has been cancelled
Build Backend JAR / build (push) Has been cancelled
线上现象:货源采集任务 26402(1212.xlsx)结果文件中存在 Python 端 404 Not Found 的行没有图,且状态列空白——这些行实际已完成采集但被后端过滤。 根因链: 1. Python 404 行 title/url/图全空 → isMissingRequired 必填校验拦截 → markRowsFailed(status=FAILED,error 保留 "404 Not Found"); 2. isExportableResultRow 对「其它错误需带 title/url/图」的判断把这类 404 行 过滤掉,即使存在也被 isSilentOutputFailure 把状态列置空。 修复: - 新增 isAsinNotFound 判定(404 / not found / 商品未找到 等文案,大小写不敏感); - resolveResultStatus 在图片判定后、rawStatus→失败 映射前插入 「ASIN未找到」状态;isExportableResultRow 对 404 行直接放行; - writeResultWorkbook 状态列 gate 排除 404 行(不再被置空); - 新增 2 条单元测试(404/中文文案命中、普通技术失败不误判)。
This commit is contained in:
+29
-1
@@ -4623,7 +4623,8 @@ public class SimilarAsinTaskService {
|
||||
String isConform = resultRow == null ? "" : userFacingLlmCellValue(resultRow, resultRow.getIsConform());
|
||||
String reason = resultRow == null ? "" : userFacingLlmCellValue(resultRow, resultRow.getReason());
|
||||
String category = resultRow == null ? "" : userFacingLlmCellValue(resultRow, resultRow.getCategory());
|
||||
String status = resultRow == null || isSilentOutputFailure(resultRow)
|
||||
String status = resultRow == null
|
||||
|| (isSilentOutputFailure(resultRow) && !isAsinNotFound(resultRow.getError()))
|
||||
? ""
|
||||
: resolveResultStatus(resultRow, isStock, similarity, isConform, reason, category);
|
||||
row.createCell(col++).setCellValue(isStock);
|
||||
@@ -4858,6 +4859,12 @@ public class SimilarAsinTaskService {
|
||||
if (hasText(row.getMainUrl()) || hasText(row.getPuzzleImg1()) || hasText(row.getPuzzleImg2())) {
|
||||
return "\u6210\u529f";
|
||||
}
|
||||
// Python \u7aef\u641c\u4e0d\u5230\u5546\u54c1\uff08404\uff09\u7684\u884c\uff1a\u72b6\u6001\u5217\u660e\u786e\u6807\u8bb0\uff0c\u4eba\u5de5\u590d\u6838\u65f6\u4e00\u773c\u53ef\u8fa8\u3002
|
||||
// \u653e\u5728\u56fe\u7247/\u72b6\u6001\u5224\u65ad\u4e4b\u524d\uff1a404 \u884c\u5fc5\u7136\u65e0\u56fe\u4e14 status \u5df2\u88ab markRowFailed \u7f6e\u4e3a FAILED\uff0c
|
||||
// \u4e0d\u80fd\u843d\u56de"\u5931\u8d25"\uff08\u90a3\u662f LLM/\u751f\u6210\u94fe\u8def\u5931\u8d25\u8bed\u4e49\uff0c\u4e0e"ASIN \u641c\u4e0d\u5230"\u662f\u4e24\u56de\u4e8b\uff09\u3002
|
||||
if (isAsinNotFound(row.getError())) {
|
||||
return "ASIN\u672a\u627e\u5230";
|
||||
}
|
||||
String rawStatus = row.getStatus() == null ? "" : row.getStatus().trim();
|
||||
if (!rawStatus.isBlank()) {
|
||||
return isFailedStatus(rawStatus) ? "\u5931\u8d25" : "\u6210\u529f";
|
||||
@@ -4872,6 +4879,22 @@ public class SimilarAsinTaskService {
|
||||
return hasText(row.getConclusion()) ? "\u6210\u529f" : "\u5931\u8d25";
|
||||
}
|
||||
|
||||
/**
|
||||
* \u5224\u5b9a\u662f\u5426"ASIN \u672a\u627e\u5230"\uff1aPython \u7aef\u6293\u53d6 404\uff08error="404 Not Found"\uff09\u6216\u7b49\u4ef7\u6587\u6848\u3002
|
||||
* \u547d\u4e2d\u8be5\u5224\u5b9a\u7684\u884c\u4e0d\u4f1a\u88ab\u5f53\u6210\u751f\u6210\u5931\u8d25\u8ba1\u91cd\u8bd5\uff0c\u4e5f\u4e0d\u4f1a\u88ab\u5bfc\u51fa\u8fc7\u6ee4\uff0c\u72b6\u6001\u5217\u663e\u793a"ASIN\u672a\u627e\u5230"\u3002
|
||||
*/
|
||||
static boolean isAsinNotFound(String error) {
|
||||
String normalized = error == null ? "" : error.toLowerCase(Locale.ROOT).trim();
|
||||
if (normalized.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
return normalized.contains("404")
|
||||
|| normalized.contains("not found")
|
||||
|| normalized.contains("asin \u672a\u627e\u5230")
|
||||
|| normalized.contains("asin\u4e0d\u5b58\u5728")
|
||||
|| normalized.contains("\u5546\u54c1\u672a\u627e\u5230");
|
||||
}
|
||||
|
||||
private static boolean isFailedStatus(String status) {
|
||||
String normalized = status == null ? "" : status.trim().toLowerCase(Locale.ROOT);
|
||||
return normalized.contains("fail")
|
||||
@@ -4895,6 +4918,11 @@ public class SimilarAsinTaskService {
|
||||
if (error.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
// Python 端搜不到商品的 404 行:虽然 title/url/图全空,也必须导出,
|
||||
// 并在状态列标记"ASIN未找到",供人工复核。在"其它错误需带 title/url/图"之前判断。
|
||||
if (isAsinNotFound(error)) {
|
||||
return true;
|
||||
}
|
||||
return !normalize(row.getTitle()).isBlank()
|
||||
|| !normalize(row.getUrl()).isBlank()
|
||||
|| row.hasImageUrl();
|
||||
|
||||
+35
@@ -54,6 +54,41 @@ class SimilarAsinTaskServiceTest {
|
||||
assertEquals("\u6210\u529f", SimilarAsinTaskService.resolveResultStatus(withVisibleResultData, "", "80%", "", "", ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resultStatusMarksAsinNotFoundRows() {
|
||||
// Python \u7aef 404 \u884c\uff1aerror="404 Not Found"\uff0cstatus \u88ab markRowFailed \u7f6e\u4e3a FAILED\uff0c
|
||||
// \u4f46\u72b6\u6001\u5217\u5fc5\u987b\u663e\u793a"ASIN\u672a\u627e\u5230"\uff0c\u4e0d\u80fd\u843d\u56de\u666e\u901a"\u5931\u8d25"\u3002
|
||||
SimilarAsinResultRowDto notFound = new SimilarAsinResultRowDto();
|
||||
notFound.setError("404 Not Found");
|
||||
notFound.setStatus("FAILED");
|
||||
notFound.setReason("required field missing (asin/title/url), skip LLM");
|
||||
assertEquals("ASIN\u672a\u627e\u5230", SimilarAsinTaskService.resolveResultStatus(notFound));
|
||||
|
||||
// \u5176\u5b83\u7b49\u4ef7\u6587\u6848\u540c\u6837\u547d\u4e2d
|
||||
SimilarAsinResultRowDto chinese = new SimilarAsinResultRowDto();
|
||||
chinese.setError("\u5546\u54c1\u672a\u627e\u5230");
|
||||
assertEquals("ASIN\u672a\u627e\u5230", SimilarAsinTaskService.resolveResultStatus(chinese));
|
||||
|
||||
// \u666e\u901a\u6280\u672f\u6027\u5931\u8d25\u4e0d\u8bef\u5224\uff1aerror \u4e0d\u542b 404/not found
|
||||
SimilarAsinResultRowDto llmFailure = new SimilarAsinResultRowDto();
|
||||
llmFailure.setError("LLM \u8c03\u7528\u8d85\u65f6");
|
||||
llmFailure.setStatus("FAILED");
|
||||
assertEquals("\u5931\u8d25", SimilarAsinTaskService.resolveResultStatus(llmFailure));
|
||||
}
|
||||
|
||||
@Test
|
||||
void asinNotFoundDetectionMatchesPythonErrors() {
|
||||
assertTrue(SimilarAsinTaskService.isAsinNotFound("404 Not Found"));
|
||||
assertTrue(SimilarAsinTaskService.isAsinNotFound("404 not found"));
|
||||
assertTrue(SimilarAsinTaskService.isAsinNotFound("404"));
|
||||
assertTrue(SimilarAsinTaskService.isAsinNotFound("\u5546\u54c1\u672a\u627e\u5230"));
|
||||
assertTrue(SimilarAsinTaskService.isAsinNotFound("ASIN \u672a\u627e\u5230"));
|
||||
assertFalse(SimilarAsinTaskService.isAsinNotFound(null));
|
||||
assertFalse(SimilarAsinTaskService.isAsinNotFound(""));
|
||||
assertFalse(SimilarAsinTaskService.isAsinNotFound("LLM \u8c03\u7528\u8d85\u65f6"));
|
||||
assertFalse(SimilarAsinTaskService.isAsinNotFound("\u4e0a\u4f20\u5931\u8d25"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileBuildProgressIsTerminalOnlyAfterTaskAndStageComplete() {
|
||||
assertTrue(SimilarAsinTaskService.isTerminalFileBuildProgress("SUCCESS", 3, 3));
|
||||
|
||||
Reference in New Issue
Block a user