稳定组成这个文件优化
This commit is contained in:
4
app/.env
4
app/.env
@@ -11,9 +11,9 @@ zn_username=%E8%87%AA%E5%8A%A8%E5%8C%96_Robot
|
||||
client_name=ShuFuAI
|
||||
|
||||
|
||||
# java_api_base=http://47.111.163.154:18080
|
||||
java_api_base=http://47.111.163.154:18080
|
||||
# java_api_base=http://127.0.0.1:18080
|
||||
# java_api_base=http://8.136.19.173:18080
|
||||
java_api_base=http://121.196.149.225:18080
|
||||
# java_api_base=http://121.196.149.225:18080
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
import{aZ as r}from"./pywebview-BWNiqXug.js";const n="";function a(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{a as e};
|
||||
1
app/assets/convert-BKSNvX8i.css
Normal file
1
app/assets/convert-BKSNvX8i.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/assets/dedupe-DNlVfFj-.css
Normal file
1
app/assets/dedupe-DNlVfFj-.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/assets/patrol-delete-CBBdonF4.css
Normal file
1
app/assets/patrol-delete-CBBdonF4.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/assets/split-BoBVrLdC.css
Normal file
1
app/assets/split-BoBVrLdC.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,10 +5,10 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>格式转换 - 数富AI</title>
|
||||
<script type="module" crossorigin src="/assets/convert.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BWNiqXug.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-CABpTGPu.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-BFZO8_3q.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/convert-r7MSXq7I.css">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BtdhG28Q.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-Lp7YWffz.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-Dp5dN8OO.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/convert-BKSNvX8i.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>数据去重 - 数富AI</title>
|
||||
<script type="module" crossorigin src="/assets/dedupe.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BWNiqXug.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-CABpTGPu.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-BFZO8_3q.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/dedupe-DMeaPUMZ.css">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BtdhG28Q.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-Lp7YWffz.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-Dp5dN8OO.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/dedupe-DNlVfFj-.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>删除品牌 - 数富AI</title>
|
||||
<script type="module" crossorigin src="/assets/delete-brand.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BWNiqXug.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-CABpTGPu.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BtdhG28Q.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-Lp7YWffz.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/categorized-timers-JPA-olTr.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-BFZO8_3q.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/delete-brand-B5ChOXZY.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-Dp5dN8OO.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/delete-brand-BfMLVSQU.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>数据拆分 - 数富AI</title>
|
||||
<script type="module" crossorigin src="/assets/split.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BWNiqXug.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-CABpTGPu.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-BFZO8_3q.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/split-Cw6sXhAg.css">
|
||||
<link rel="modulepreload" crossorigin href="/assets/pywebview-BtdhG28Q.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/brand-Lp7YWffz.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/pywebview-Dp5dN8OO.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/split-BoBVrLdC.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -86,6 +86,8 @@ public class AppearancePatentTaskService {
|
||||
private static final String STATUS_SUCCESS = "SUCCESS";
|
||||
private static final String STATUS_FAILED = "FAILED";
|
||||
private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
private static final int RESULT_ROWS_READ_RETRY_LIMIT = 3;
|
||||
private static final long RESULT_ROWS_READ_RETRY_DELAY_MS = 500L;
|
||||
private static final List<String> RESULT_HEADERS = List.of(
|
||||
"id",
|
||||
"asin",
|
||||
@@ -759,12 +761,17 @@ public class AppearancePatentTaskService {
|
||||
}
|
||||
String payloadJson = writeJson(rows == null ? List.of() : rows, "结果序列化失败");
|
||||
payloadJson = writeJson(new ArrayList<>(persistedRows.values()), "appearance patent chunk payload merge failed");
|
||||
String storedPayload = transientPayloadStorageService.storeChunkPayload(MODULE_TYPE, taskId, scopeHash, chunkIndex, payloadJson);
|
||||
transientPayloadStorageService.deleteReplacedPayloadIfNeeded(chunk.getPayloadJson(), storedPayload);
|
||||
String oldPayload = chunk.getPayloadJson();
|
||||
String storedPayload = transientPayloadStorageService.storeChunkPayloadVersioned(MODULE_TYPE, taskId, scopeHash, chunkIndex, payloadJson);
|
||||
chunk.setPayloadJson(storedPayload);
|
||||
chunk.setPayloadHash(DigestUtil.sha256Hex(payloadJson));
|
||||
chunk.setUpdatedAt(LocalDateTime.now());
|
||||
taskChunkMapper.updateById(chunk);
|
||||
int updated = taskChunkMapper.updateById(chunk);
|
||||
if (updated <= 0) {
|
||||
transientPayloadStorageService.deletePayloadIfPresent(storedPayload);
|
||||
throw new IllegalStateException("appearance patent chunk payload update failed");
|
||||
}
|
||||
transientPayloadStorageService.deleteReplacedPayloadIfNeeded(oldPayload, storedPayload);
|
||||
}
|
||||
|
||||
private List<AppearancePatentResultRowDto> expandRows(List<AppearancePatentResultRowDto> representatives,
|
||||
@@ -1122,7 +1129,7 @@ public class AppearancePatentTaskService {
|
||||
|
||||
private void assembleResultWorkbook(FileTaskEntity task, FileResultEntity result) {
|
||||
AppearancePatentParsedPayloadDto parsed = readParsedPayload(task);
|
||||
Map<String, AppearancePatentResultRowDto> resultMap = loadPersistedResultRows(task.getId());
|
||||
Map<String, AppearancePatentResultRowDto> resultMap = loadPersistedResultRowsWithRetry(task.getId(), parsed.getAllItems().size());
|
||||
long resolvedRows = parsed.getAllItems().stream()
|
||||
.filter(row -> findResultRow(row, resultMap) != null || findResultRowByAsin(row.getAsin(), resultMap) != null)
|
||||
.count();
|
||||
@@ -1131,6 +1138,9 @@ public class AppearancePatentTaskService {
|
||||
.count();
|
||||
log.info("[appearance-patent] assemble workbook taskId={} parsedRows={} resultRows={} resolvedRows={} reasonRows={}",
|
||||
task.getId(), parsed.getAllItems().size(), resultMap.size(), resolvedRows, reasonRows);
|
||||
if (!parsed.getAllItems().isEmpty() && resultMap.isEmpty()) {
|
||||
throw new BusinessException("外观专利检测结果为空,请稍后重试生成结果文件");
|
||||
}
|
||||
File outputDir = new File(storageProperties.getLocalTempDir(), "appearance-patent-result");
|
||||
if (!outputDir.exists() && !outputDir.mkdirs()) {
|
||||
throw new BusinessException("创建结果目录失败");
|
||||
@@ -1164,6 +1174,33 @@ public class AppearancePatentTaskService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, AppearancePatentResultRowDto> loadPersistedResultRowsWithRetry(Long taskId, int expectedParsedRows) {
|
||||
Map<String, AppearancePatentResultRowDto> result = loadPersistedResultRows(taskId);
|
||||
if (expectedParsedRows <= 0 || !result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
for (int attempt = 1; attempt <= RESULT_ROWS_READ_RETRY_LIMIT && result.isEmpty(); attempt++) {
|
||||
sleepBeforeResultRowsRetry(attempt);
|
||||
result = loadPersistedResultRows(taskId);
|
||||
if (!result.isEmpty()) {
|
||||
log.info("[appearance-patent] result rows recovered after retry taskId={} attempt={} rows={}",
|
||||
taskId, attempt, result.size());
|
||||
return result;
|
||||
}
|
||||
log.warn("[appearance-patent] result rows still empty after retry taskId={} attempt={}/{}",
|
||||
taskId, attempt, RESULT_ROWS_READ_RETRY_LIMIT);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void sleepBeforeResultRowsRetry(int attempt) {
|
||||
try {
|
||||
Thread.sleep(RESULT_ROWS_READ_RETRY_DELAY_MS * attempt);
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeResultWorkbook(File xlsx, AppearancePatentParsedPayloadDto parsed, Map<String, AppearancePatentResultRowDto> resultMap) {
|
||||
try (SXSSFWorkbook workbook = new SXSSFWorkbook(200); FileOutputStream fos = new FileOutputStream(xlsx)) {
|
||||
Sheet sheet = workbook.createSheet("外观专利检测结果");
|
||||
|
||||
@@ -55,6 +55,13 @@ public class TransientPayloadStorageService {
|
||||
return store("task-chunk", moduleType, taskId, scopeHash, entryKey, content, true);
|
||||
}
|
||||
|
||||
public String storeChunkPayloadVersioned(String moduleType, Long taskId, String scopeHash, Integer chunkIndex, String content) {
|
||||
String entryKey = chunkIndex == null
|
||||
? UUID.randomUUID().toString()
|
||||
: "chunk-" + chunkIndex + "-" + UUID.randomUUID();
|
||||
return store("task-chunk", moduleType, taskId, scopeHash, entryKey, content, true);
|
||||
}
|
||||
|
||||
public String resolvePayload(String value, String errorMessage) {
|
||||
String pointer = extractPointer(value);
|
||||
if (pointer == null) {
|
||||
|
||||
Reference in New Issue
Block a user