提交更新

This commit is contained in:
super
2026-05-06 00:01:49 +08:00
parent b16c63225f
commit c3810fdb7b
36 changed files with 40057 additions and 14870 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{b6 as r}from"./pywebview-RBTI4RuH.js";const n="";function s(e){return r(`${n}/api/brand/expand-folder-recursive`,{folder:e})}export{s as e};

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

View File

@@ -399,10 +399,11 @@
<div class="nav-section-title">前端工具</div> <div class="nav-section-title">前端工具</div>
<div class="nav-section-items"> <div class="nav-section-items">
<span class="nav-item disabled">采集数据</span> <span class="nav-item disabled">采集数据</span>
<span class="nav-item disabled">变体分析</span> <span class="nav-item disabled">变体分析</span>
<button type="button" class="nav-item active" data-panel="brandCheck">品牌检测</button> <button type="button" class="nav-item active" data-panel="brandCheck">品牌检测</button>
<a class="nav-item" href="/new_web_source/appearance-patent.html">外观专利检测</a> <a class="nav-item" href="/new_web_source/appearance-patent.html">外观专利检测</a>
<a class="nav-item" href="/new_web_source/dedupe.html">数据去重</a> <a class="nav-item" href="/new_web_source/similar-asin.html">相似ASIN检测</a>
<a class="nav-item" href="/new_web_source/dedupe.html">数据去重</a>
<a class="nav-item" href="/new_web_source/split.html">数据拆分</a> <a class="nav-item" href="/new_web_source/split.html">数据拆分</a>
<a class="nav-item" href="/new_web_source/convert.html">格式转换</a> <a class="nav-item" href="/new_web_source/convert.html">格式转换</a>
</div> </div>

View File

@@ -14,8 +14,8 @@ public class AppearancePatentProperties {
private int cozeBatchSize = 10; private int cozeBatchSize = 10;
private int cozeConnectTimeoutMillis = 10000; private int cozeConnectTimeoutMillis = 10000;
private int cozeReadTimeoutMillis = 60000; private int cozeReadTimeoutMillis = 60000;
private int cozePollIntervalMillis = 2000; private int cozePollIntervalMillis = 5000;
private int cozePollTimeoutMillis = 120000; private int cozePollTimeoutMillis = 600000;
private int staleTimeoutMinutes = 20; private int staleTimeoutMinutes = 20;
private String staleFinalizeCron = "0 */2 * * * *"; private String staleFinalizeCron = "0 */2 * * * *";
} }

View File

@@ -14,8 +14,8 @@ public class SimilarAsinProperties {
private int cozeBatchSize = 10; private int cozeBatchSize = 10;
private int cozeConnectTimeoutMillis = 10000; private int cozeConnectTimeoutMillis = 10000;
private int cozeReadTimeoutMillis = 60000; private int cozeReadTimeoutMillis = 60000;
private int cozePollIntervalMillis = 2000; private int cozePollIntervalMillis = 5000;
private int cozePollTimeoutMillis = 120000; private int cozePollTimeoutMillis = 600000;
private int staleTimeoutMinutes = 20; private int staleTimeoutMinutes = 20;
private String staleFinalizeCron = "0 */2 * * * *"; private String staleFinalizeCron = "0 */2 * * * *";
} }

View File

@@ -32,7 +32,9 @@ public class TaskOperationLockConfig implements WebMvcConfigurer {
private static final class TaskOperationLockInterceptor implements HandlerInterceptor { private static final class TaskOperationLockInterceptor implements HandlerInterceptor {
private static final Pattern TASK_PATH = Pattern.compile(".*/api/([^/]+)/tasks/(\\d+)(?:/.*)?$"); private static final Pattern TASK_PATH = Pattern.compile(".*/api/([^/]+)/tasks/(\\d+)(?:/.*)?$");
private static final Pattern TASK_RESULT_PATH = Pattern.compile(".*/api/([^/]+)/tasks/(\\d+)/result/?$");
private static final Set<String> MUTATING_METHODS = Set.of("POST", "PUT", "PATCH", "DELETE"); private static final Set<String> MUTATING_METHODS = Set.of("POST", "PUT", "PATCH", "DELETE");
private static final long RESULT_SUBMIT_WAIT_MILLIS = 10 * 60 * 1000L;
private static final String LOCK_ATTRIBUTE = TaskOperationLockInterceptor.class.getName() + ".LOCK"; private static final String LOCK_ATTRIBUTE = TaskOperationLockInterceptor.class.getName() + ".LOCK";
private final TaskDistributedLockService taskDistributedLockService; private final TaskDistributedLockService taskDistributedLockService;
@@ -53,17 +55,25 @@ public class TaskOperationLockConfig implements WebMvcConfigurer {
} }
String moduleType = matcher.group(1).trim().toUpperCase(Locale.ROOT).replace('-', '_'); String moduleType = matcher.group(1).trim().toUpperCase(Locale.ROOT).replace('-', '_');
Long taskId = Long.valueOf(matcher.group(2)); Long taskId = Long.valueOf(matcher.group(2));
long waitMillis = resolveWaitMillis(request.getMethod(), uri);
TaskDistributedLockService.LockHandle lockHandle = TaskDistributedLockService.LockHandle lockHandle =
taskDistributedLockService.acquire(moduleType, taskId, TaskDistributedLockService.DEFAULT_WAIT_MILLIS); taskDistributedLockService.acquire(moduleType, taskId, waitMillis);
if (lockHandle == null) { if (lockHandle == null) {
log.info("[task-operation-lock] rejected busy task operation method={} uri={} moduleType={} taskId={}", log.info("[task-operation-lock] rejected busy task operation method={} uri={} moduleType={} taskId={} waitMillis={}",
request.getMethod(), uri, moduleType, taskId); request.getMethod(), uri, moduleType, taskId, waitMillis);
throw new BusinessException(40902, "TASK_LOCK_BUSY"); throw new BusinessException(40902, "TASK_LOCK_BUSY");
} }
request.setAttribute(LOCK_ATTRIBUTE, lockHandle); request.setAttribute(LOCK_ATTRIBUTE, lockHandle);
return true; return true;
} }
private long resolveWaitMillis(String method, String uri) {
if ("POST".equals(method) && TASK_RESULT_PATH.matcher(uri == null ? "" : uri).matches()) {
return RESULT_SUBMIT_WAIT_MILLIS;
}
return TaskDistributedLockService.DEFAULT_WAIT_MILLIS;
}
@Override @Override
public void afterCompletion(HttpServletRequest request, public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,

View File

@@ -30,7 +30,7 @@ public class AppearancePatentCozeClient {
private final AppearancePatentProperties properties; private final AppearancePatentProperties properties;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
public List<AppearancePatentResultRowDto> inspect(List<AppearancePatentResultRowDto> rows, String prompt) { public List<AppearancePatentResultRowDto> inspect(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) {
if (rows == null || rows.isEmpty()) { if (rows == null || rows.isEmpty()) {
return List.of(); return List.of();
} }
@@ -39,7 +39,7 @@ public class AppearancePatentCozeClient {
return rows.stream().map(this::copy).toList(); return rows.stream().map(this::copy).toList();
} }
try { try {
return inspectWithFallback(rows, prompt); return inspectWithFallback(rows, prompt, apiKey);
} catch (Exception ex) { } catch (Exception ex) {
String failureMessage = failureMessage(ex); String failureMessage = failureMessage(ex);
log.warn("[appearance-patent] coze batch failed size={} err={}", rows.size(), failureMessage); log.warn("[appearance-patent] coze batch failed size={} err={}", rows.size(), failureMessage);
@@ -47,8 +47,8 @@ public class AppearancePatentCozeClient {
} }
} }
public CozeSubmitResponse submitWorkflow(List<AppearancePatentResultRowDto> rows, String prompt) throws Exception { public CozeSubmitResponse submitWorkflow(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) throws Exception {
JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt)); JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt, apiKey));
ensureSuccess(submitRoot); ensureSuccess(submitRoot);
return new CozeSubmitResponse( return new CozeSubmitResponse(
extractExecuteId(submitRoot), extractExecuteId(submitRoot),
@@ -83,12 +83,12 @@ public class AppearancePatentCozeClient {
return rows.stream().map(this::copy).map(row -> markFailed(row, failureMessage)).toList(); return rows.stream().map(this::copy).map(row -> markFailed(row, failureMessage)).toList();
} }
private List<AppearancePatentResultRowDto> inspectWithFallback(List<AppearancePatentResultRowDto> rows, String prompt) { private List<AppearancePatentResultRowDto> inspectWithFallback(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) {
try { try {
if (rows.size() == 1) { if (rows.size() == 1) {
return inspectSingleRowWithRetry(rows, prompt); return inspectSingleRowWithRetry(rows, prompt, apiKey);
} }
InspectAttempt attempt = inspectOnce(rows, prompt); InspectAttempt attempt = inspectOnce(rows, prompt, apiKey);
if (attempt.resolvedCount() < rows.size()) { if (attempt.resolvedCount() < rows.size()) {
throw new PartialCozeResultException(attempt.resolvedCount(), rows.size(), attempt.rawResultCount()); throw new PartialCozeResultException(attempt.resolvedCount(), rows.size(), attempt.rawResultCount());
} }
@@ -99,17 +99,17 @@ public class AppearancePatentCozeClient {
log.warn("[appearance-patent] coze batch fallback split size={} left={} right={} err={}", log.warn("[appearance-patent] coze batch fallback split size={} left={} right={} err={}",
rows.size(), middle, rows.size() - middle, failureMessage(ex)); rows.size(), middle, rows.size() - middle, failureMessage(ex));
List<AppearancePatentResultRowDto> merged = new ArrayList<>(rows.size()); List<AppearancePatentResultRowDto> merged = new ArrayList<>(rows.size());
merged.addAll(inspectPartitionWithFailureFallback(rows.subList(0, middle), prompt)); merged.addAll(inspectPartitionWithFailureFallback(rows.subList(0, middle), prompt, apiKey));
merged.addAll(inspectPartitionWithFailureFallback(rows.subList(middle, rows.size()), prompt)); merged.addAll(inspectPartitionWithFailureFallback(rows.subList(middle, rows.size()), prompt, apiKey));
return merged; return merged;
} }
throw propagate(ex); throw propagate(ex);
} }
} }
private List<AppearancePatentResultRowDto> inspectPartitionWithFailureFallback(List<AppearancePatentResultRowDto> rows, String prompt) { private List<AppearancePatentResultRowDto> inspectPartitionWithFailureFallback(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) {
try { try {
return inspectWithFallback(rows, prompt); return inspectWithFallback(rows, prompt, apiKey);
} catch (Exception ex) { } catch (Exception ex) {
String failureMessage = failureMessage(ex); String failureMessage = failureMessage(ex);
log.warn("[appearance-patent] coze partition failed size={} err={}", rows.size(), failureMessage); log.warn("[appearance-patent] coze partition failed size={} err={}", rows.size(), failureMessage);
@@ -117,12 +117,12 @@ public class AppearancePatentCozeClient {
} }
} }
private List<AppearancePatentResultRowDto> inspectSingleRowWithRetry(List<AppearancePatentResultRowDto> rows, String prompt) throws Exception { private List<AppearancePatentResultRowDto> inspectSingleRowWithRetry(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) throws Exception {
AppearancePatentResultRowDto row = rows.getFirst(); AppearancePatentResultRowDto row = rows.getFirst();
PartialCozeResultException lastFailure = null; PartialCozeResultException lastFailure = null;
for (int attemptIndex = 1; attemptIndex <= 3; attemptIndex++) { for (int attemptIndex = 1; attemptIndex <= 3; attemptIndex++) {
try { try {
InspectAttempt attempt = inspectOnce(rows, prompt); InspectAttempt attempt = inspectOnce(rows, prompt, apiKey);
if (attempt.resolvedCount() == rows.size()) { if (attempt.resolvedCount() == rows.size()) {
return attempt.mergedRows(); return attempt.mergedRows();
} }
@@ -153,8 +153,8 @@ public class AppearancePatentCozeClient {
throw lastFailure == null ? new PartialCozeResultException(0, rows.size(), 0) : lastFailure; throw lastFailure == null ? new PartialCozeResultException(0, rows.size(), 0) : lastFailure;
} }
private InspectAttempt inspectOnce(List<AppearancePatentResultRowDto> rows, String prompt) throws Exception { private InspectAttempt inspectOnce(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) throws Exception {
String raw = runWorkflowAsyncAndWait(rows, prompt); String raw = runWorkflowAsyncAndWait(rows, prompt, apiKey);
List<CozeResult> results = parseResults(raw); List<CozeResult> results = parseResults(raw);
if (rows.size() > 1 && !results.isEmpty() && results.stream().noneMatch(this::hasIdentity)) { if (rows.size() > 1 && !results.isEmpty() && results.stream().noneMatch(this::hasIdentity)) {
throw new PartialCozeResultException(0, rows.size(), results.size()); throw new PartialCozeResultException(0, rows.size(), results.size());
@@ -163,8 +163,8 @@ public class AppearancePatentCozeClient {
return new InspectAttempt(raw, merged, resolvedCount(merged), results.size()); return new InspectAttempt(raw, merged, resolvedCount(merged), results.size());
} }
private String runWorkflowAsyncAndWait(List<AppearancePatentResultRowDto> rows, String prompt) throws Exception { private String runWorkflowAsyncAndWait(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) throws Exception {
JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt)); JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt, apiKey));
ensureSuccess(submitRoot); ensureSuccess(submitRoot);
String immediateData = extractResultDataText(submitRoot); String immediateData = extractResultDataText(submitRoot);
@@ -205,15 +205,15 @@ public class AppearancePatentCozeClient {
throw new IllegalStateException("Coze async workflow poll timeout"); throw new IllegalStateException("Coze async workflow poll timeout");
} }
private String postWorkflow(List<AppearancePatentResultRowDto> rows, String prompt) { private String postWorkflow(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) {
Map<String, Object> parameters = buildParameters(rows, prompt); Map<String, Object> parameters = buildParameters(rows, prompt, apiKey);
Map<String, Object> body = new LinkedHashMap<>(); Map<String, Object> body = new LinkedHashMap<>();
body.put("workflow_id", properties.getCozeWorkflowId()); body.put("workflow_id", properties.getCozeWorkflowId());
body.put("parameters", parameters); body.put("parameters", parameters);
body.put("is_async", Boolean.TRUE); body.put("is_async", Boolean.TRUE);
log.info("[appearance-patent] coze request url={} body={}", log.info("[appearance-patent] coze request url={} body={}",
joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath()), joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath()),
writeJson(body)); writeJson(maskCozeRequestBody(body)));
RestClient.RequestBodySpec request = restClient().post() RestClient.RequestBodySpec request = restClient().post()
.uri(joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath())) .uri(joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath()))
@@ -255,7 +255,7 @@ public class AppearancePatentCozeClient {
}); });
} }
private Map<String, Object> buildParameters(List<AppearancePatentResultRowDto> rows, String prompt) { private Map<String, Object> buildParameters(List<AppearancePatentResultRowDto> rows, String prompt, String apiKey) {
List<String> groupKeys = rows.stream().map(row -> nonBlank(row.getGroupKey(), rowKey(row))).toList(); List<String> groupKeys = rows.stream().map(row -> nonBlank(row.getGroupKey(), rowKey(row))).toList();
List<String> rowIds = rows.stream().map(row -> nonBlank(row.getId(), "")).toList(); List<String> rowIds = rows.stream().map(row -> nonBlank(row.getId(), "")).toList();
List<String> asins = rows.stream().map(row -> nonBlank(row.getAsin(), "")).toList(); List<String> asins = rows.stream().map(row -> nonBlank(row.getAsin(), "")).toList();
@@ -268,9 +268,38 @@ public class AppearancePatentCozeClient {
parameters.put("url_list", urls); parameters.put("url_list", urls);
parameters.put("items", buildItemObjects(rows, groupKeys, rowIds, asins, countries, titles, urls)); parameters.put("items", buildItemObjects(rows, groupKeys, rowIds, asins, countries, titles, urls));
parameters.put("prompt", prompt == null ? "" : prompt); parameters.put("prompt", prompt == null ? "" : prompt);
if (apiKey != null && !apiKey.isBlank()) {
parameters.put("api_key", apiKey.trim());
}
return parameters; return parameters;
} }
@SuppressWarnings("unchecked")
private Map<String, Object> maskCozeRequestBody(Map<String, Object> body) {
Map<String, Object> masked = new LinkedHashMap<>(body);
Object parametersObj = masked.get("parameters");
if (parametersObj instanceof Map<?, ?> parameters) {
Map<String, Object> maskedParameters = new LinkedHashMap<>((Map<String, Object>) parameters);
Object apiKey = maskedParameters.get("api_key");
if (apiKey instanceof String apiKeyText && !apiKeyText.isBlank()) {
maskedParameters.put("api_key", maskSecret(apiKeyText));
}
masked.put("parameters", maskedParameters);
}
return masked;
}
private String maskSecret(String secret) {
String normalized = secret == null ? "" : secret.trim();
if (normalized.isBlank()) {
return "";
}
if (normalized.length() <= 10) {
return "***";
}
return normalized.substring(0, 6) + "***" + normalized.substring(normalized.length() - 4);
}
private List<Map<String, Object>> buildItemObjects(List<AppearancePatentResultRowDto> rows, private List<Map<String, Object>> buildItemObjects(List<AppearancePatentResultRowDto> rows,
List<String> groupKeys, List<String> groupKeys,
List<String> rowIds, List<String> rowIds,

View File

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@@ -25,4 +26,10 @@ public class AppearancePatentParseRequest {
@JsonAlias({"aiPrompt", "prompt"}) @JsonAlias({"aiPrompt", "prompt"})
@Schema(description = "AI 提示词。非必填;为空时前端会使用默认提示词。后端会保存该提示词,并在调用 Coze workflow 时作为 prompt 参数传入。", example = "请排查这些亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。") @Schema(description = "AI 提示词。非必填;为空时前端会使用默认提示词。后端会保存该提示词,并在调用 Coze workflow 时作为 prompt 参数传入。", example = "请排查这些亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。")
private String aiPrompt; private String aiPrompt;
@JsonProperty("api_key")
@JsonAlias({"apiKey"})
@Schema(description = "传递给 Coze workflow parameters.api_key 的任务级密钥。")
@NotBlank(message = "密钥不能为空")
private String apiKey;
} }

View File

@@ -14,6 +14,9 @@ public class AppearancePatentParsedPayloadDto {
@Schema(description = "AI 提示词") @Schema(description = "AI 提示词")
private String aiPrompt; private String aiPrompt;
@Schema(description = "传递给 Coze workflow parameters.api_key 的任务级密钥")
private String apiKey;
@Schema(description = "本次解析的源文件列表") @Schema(description = "本次解析的源文件列表")
private List<AppearancePatentSourceFileDto> sourceFiles = new ArrayList<>(); private List<AppearancePatentSourceFileDto> sourceFiles = new ArrayList<>();

View File

@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.nanri.aiimage.common.exception.BusinessException; import com.nanri.aiimage.common.exception.BusinessException;
import com.nanri.aiimage.common.service.DistributedJobLockService; import com.nanri.aiimage.common.service.DistributedJobLockService;
import com.nanri.aiimage.config.AppearancePatentProperties; import com.nanri.aiimage.config.AppearancePatentProperties;
import com.nanri.aiimage.config.InstanceMetadata;
import com.nanri.aiimage.config.StorageProperties; import com.nanri.aiimage.config.StorageProperties;
import com.nanri.aiimage.modules.appearancepatent.client.AppearancePatentCozeClient; import com.nanri.aiimage.modules.appearancepatent.client.AppearancePatentCozeClient;
import com.nanri.aiimage.modules.appearancepatent.model.dto.AppearancePatentParseRequest; import com.nanri.aiimage.modules.appearancepatent.model.dto.AppearancePatentParseRequest;
@@ -131,6 +132,7 @@ public class AppearancePatentTaskService {
private final PlatformTransactionManager transactionManager; private final PlatformTransactionManager transactionManager;
private final DistributedJobLockService distributedJobLockService; private final DistributedJobLockService distributedJobLockService;
private final TaskDistributedLockService taskDistributedLockService; private final TaskDistributedLockService taskDistributedLockService;
private final InstanceMetadata instanceMetadata;
@Autowired @Autowired
@Qualifier("cozeTaskExecutor") @Qualifier("cozeTaskExecutor")
private TaskExecutor cozeTaskExecutor; private TaskExecutor cozeTaskExecutor;
@@ -199,11 +201,11 @@ public class AppearancePatentTaskService {
String aggregateScopeKey = buildAggregateScopeKey(sourceFiles); String aggregateScopeKey = buildAggregateScopeKey(sourceFiles);
String sourceScopeHash = DigestUtil.sha256Hex(aggregateScopeKey); String sourceScopeHash = DigestUtil.sha256Hex(aggregateScopeKey);
String parsedPayload = buildParsedPayloadJson(request.getAiPrompt(), sourceFiles, mergedHeaders, groups, allRows); String parsedPayload = buildParsedPayloadJson(request.getAiPrompt(), request.getApiKey(), sourceFiles, mergedHeaders, groups, allRows);
long payloadBuiltAt = System.nanoTime(); long payloadBuiltAt = System.nanoTime();
String parsedPayloadPointer = storeParsedPayload(task.getId(), sourceScopeHash, parsedPayload); String parsedPayloadPointer = storeParsedPayload(task.getId(), sourceScopeHash, parsedPayload);
long payloadStoredAt = System.nanoTime(); long payloadStoredAt = System.nanoTime();
task.setResultJson(buildTaskResultJson(request.getAiPrompt(), sourceFiles, parsedPayloadPointer)); task.setResultJson(buildTaskResultJson(request.getAiPrompt(), request.getApiKey(), sourceFiles, parsedPayloadPointer));
task.setUpdatedAt(LocalDateTime.now()); task.setUpdatedAt(LocalDateTime.now());
fileTaskMapper.updateById(task); fileTaskMapper.updateById(task);
@@ -267,6 +269,7 @@ public class AppearancePatentTaskService {
if (task == null || !MODULE_TYPE.equals(task.getModuleType()) || userId != null && !Objects.equals(userId, task.getUserId())) { if (task == null || !MODULE_TYPE.equals(task.getModuleType()) || userId != null && !Objects.equals(userId, task.getUserId())) {
throw new BusinessException("任务不存在"); throw new BusinessException("任务不存在");
} }
ensureTaskOwnedByCurrentInstance(task, "activate");
if (STATUS_SUCCESS.equals(task.getStatus()) || STATUS_FAILED.equals(task.getStatus())) { if (STATUS_SUCCESS.equals(task.getStatus()) || STATUS_FAILED.equals(task.getStatus())) {
throw new BusinessException("任务已结束"); throw new BusinessException("任务已结束");
} }
@@ -429,6 +432,7 @@ public class AppearancePatentTaskService {
if (task == null || !MODULE_TYPE.equals(task.getModuleType())) { if (task == null || !MODULE_TYPE.equals(task.getModuleType())) {
throw new BusinessException("任务不存在"); throw new BusinessException("任务不存在");
} }
ensureTaskOwnedByCurrentInstance(task, "submit result");
if (!STATUS_RUNNING.equals(task.getStatus())) { if (!STATUS_RUNNING.equals(task.getStatus())) {
throw new BusinessException("任务不是运行中状态"); throw new BusinessException("任务不是运行中状态");
} }
@@ -620,6 +624,7 @@ public class AppearancePatentTaskService {
throw new BusinessException("任务不是运行中状态"); throw new BusinessException("任务不是运行中状态");
} }
ensureTaskOwnedByCurrentInstance(task, "submit result");
int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex(); int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex();
int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal(); int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal();
boolean done = Boolean.TRUE.equals(request.getDone()); boolean done = Boolean.TRUE.equals(request.getDone());
@@ -772,10 +777,11 @@ public class AppearancePatentTaskService {
return List.of(); return List.of();
} }
String prompt = readAiPrompt(task); String prompt = readAiPrompt(task);
String apiKey = readApiKey(task);
int batchSize = Math.max(1, properties.getCozeBatchSize()); int batchSize = Math.max(1, properties.getCozeBatchSize());
List<AppearancePatentResultRowDto> result = new ArrayList<>(); List<AppearancePatentResultRowDto> result = new ArrayList<>();
for (int i = 0; i < items.size(); i += batchSize) { for (int i = 0; i < items.size(); i += batchSize) {
result.addAll(cozeClient.inspect(items.subList(i, Math.min(i + batchSize, items.size())), prompt)); result.addAll(cozeClient.inspect(items.subList(i, Math.min(i + batchSize, items.size())), prompt, apiKey));
if (progressHook != null) { if (progressHook != null) {
progressHook.run(); progressHook.run();
} }
@@ -1060,6 +1066,14 @@ public class AppearancePatentTaskService {
} }
} }
private String readApiKey(FileTaskEntity task) {
try {
return normalize(readParsedPayload(task).getApiKey());
} catch (Exception ignored) {
return "";
}
}
private void finalizeTask(FileTaskEntity task, String error, int rowCount, boolean assembleWorkbook) { private void finalizeTask(FileTaskEntity task, String error, int rowCount, boolean assembleWorkbook) {
String finalError = error; String finalError = error;
FileResultEntity result = null; FileResultEntity result = null;
@@ -1098,7 +1112,7 @@ public class AppearancePatentTaskService {
} }
fileResultMapper.updateById(result); fileResultMapper.updateById(result);
if (!failed && assembleWorkbook) { if (!failed && assembleWorkbook) {
taskFileJobService.enqueueAssembleResult(task.getId(), MODULE_TYPE, result.getId(), "task:" + task.getId()); taskFileJobService.enqueueAssembleResult(task.getId(), MODULE_TYPE, result.getId(), buildTaskOwnerScopeKey(task.getId()));
} }
} }
taskCacheService.deleteTaskCache(task.getId()); taskCacheService.deleteTaskCache(task.getId());
@@ -1112,6 +1126,11 @@ public class AppearancePatentTaskService {
if (job == null || job.getTaskId() == null || job.getResultId() == null) { if (job == null || job.getTaskId() == null || job.getResultId() == null) {
throw new BusinessException("result file job arguments are incomplete"); throw new BusinessException("result file job arguments are incomplete");
} }
if (!isJobOwnedByCurrentInstance(job)) {
log.info("[appearance-patent] skip result file job because owner is another instance jobId={} taskId={} owner={} current={}",
job.getId(), job.getTaskId(), ownerFromScopeKey(job.getScopeKey()), currentInstanceId());
return false;
}
TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(job.getTaskId(), TASK_LOCK_WAIT_MILLIS); TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(job.getTaskId(), TASK_LOCK_WAIT_MILLIS);
if (lockHandle == null) { if (lockHandle == null) {
taskFileJobService.requeue(job.getId(), "Task is busy, waiting for appearance patent result merge"); taskFileJobService.requeue(job.getId(), "Task is busy, waiting for appearance patent result merge");
@@ -1159,38 +1178,31 @@ public class AppearancePatentTaskService {
@Scheduled(fixedDelayString = "${aiimage.appearance-patent.coze-poll-delay-ms:5000}") @Scheduled(fixedDelayString = "${aiimage.appearance-patent.coze-poll-delay-ms:5000}")
public void pollPendingCozeJobs() { public void pollPendingCozeJobs() {
DistributedJobLockService.LockHandle lockHandle = List<TaskScopeStateEntity> states = taskScopeStateMapper.selectList(new LambdaQueryWrapper<TaskScopeStateEntity>()
distributedJobLockService.tryLock("appearance-patent:coze-poll", Duration.ofMinutes(1)); .eq(TaskScopeStateEntity::getModuleType, MODULE_TYPE)
if (lockHandle == null) { .in(TaskScopeStateEntity::getCozeStatus, List.of(COZE_STATUS_SUBMITTED, COZE_STATUS_RUNNING))
.isNotNull(TaskScopeStateEntity::getCozeExecuteId)
.orderByAsc(TaskScopeStateEntity::getUpdatedAt)
.last("limit 50"));
if (states == null || states.isEmpty()) {
return; return;
} }
try (lockHandle) { log.info("[appearance-patent] coze poll picked pending states count={}", states.size());
List<TaskScopeStateEntity> states = taskScopeStateMapper.selectList(new LambdaQueryWrapper<TaskScopeStateEntity>() for (TaskScopeStateEntity state : states) {
.eq(TaskScopeStateEntity::getModuleType, MODULE_TYPE) if (state == null || state.getId() == null || !isCozeStateOwnedByCurrentInstance(state)) {
.in(TaskScopeStateEntity::getCozeStatus, List.of(COZE_STATUS_SUBMITTED, COZE_STATUS_RUNNING)) continue;
.isNotNull(TaskScopeStateEntity::getCozeExecuteId)
.orderByAsc(TaskScopeStateEntity::getUpdatedAt)
.last("limit 50"));
if (states == null || states.isEmpty()) {
return;
} }
log.info("[appearance-patent] coze poll picked pending states count={}", states.size()); Long stateId = state.getId();
for (TaskScopeStateEntity state : states) { try {
if (state == null || state.getId() == null) { cozeTaskExecutor.execute(() -> {
continue; log.info("[appearance-patent] coze poll worker entered stateId={} taskId={} executeId={}",
} stateId, state.getTaskId(), state.getCozeExecuteId());
Long stateId = state.getId(); pollPendingCozeState(stateId);
try { });
cozeTaskExecutor.execute(() -> { } catch (Exception ex) {
log.info("[appearance-patent] coze poll worker entered stateId={} taskId={} executeId={}", log.warn("[appearance-patent] coze poll dispatch failed stateId={} taskId={} executeId={} err={}",
stateId, state.getTaskId(), state.getCozeExecuteId()); stateId, state.getTaskId(), state.getCozeExecuteId(),
pollPendingCozeState(stateId); firstNonBlank(ex.getMessage(), ex.getClass().getSimpleName()), ex);
});
} catch (Exception ex) {
log.warn("[appearance-patent] coze poll dispatch failed stateId={} taskId={} executeId={} err={}",
stateId, state.getTaskId(), state.getCozeExecuteId(),
firstNonBlank(ex.getMessage(), ex.getClass().getSimpleName()), ex);
}
} }
} }
} }
@@ -1209,6 +1221,7 @@ public class AppearancePatentTaskService {
return false; return false;
} }
String prompt = readAiPrompt(task); String prompt = readAiPrompt(task);
String apiKey = readApiKey(task);
int batchSize = Math.max(1, properties.getCozeBatchSize()); int batchSize = Math.max(1, properties.getCozeBatchSize());
boolean pending = false; boolean pending = false;
for (TaskChunkEntity chunk : chunks) { for (TaskChunkEntity chunk : chunks) {
@@ -1225,7 +1238,7 @@ public class AppearancePatentTaskService {
for (int i = 0; i < unresolvedRows.size(); i += batchSize) { for (int i = 0; i < unresolvedRows.size(); i += batchSize) {
List<AppearancePatentResultRowDto> batchRows = List<AppearancePatentResultRowDto> batchRows =
unresolvedRows.subList(i, Math.min(i + batchSize, unresolvedRows.size())); unresolvedRows.subList(i, Math.min(i + batchSize, unresolvedRows.size()));
pending |= submitCozeBatch(task, result, job, chunk, batchRows, batchIndex, batchTotal, prompt, allRowsByBaseId); pending |= submitCozeBatch(task, result, job, chunk, batchRows, batchIndex, batchTotal, prompt, apiKey, allRowsByBaseId);
batchIndex++; batchIndex++;
} }
} }
@@ -1240,6 +1253,7 @@ public class AppearancePatentTaskService {
int batchIndex, int batchIndex,
int batchTotal, int batchTotal,
String prompt, String prompt,
String apiKey,
Map<String, List<AppearancePatentParsedRowVo>> allRowsByBaseId) { Map<String, List<AppearancePatentParsedRowVo>> allRowsByBaseId) {
if (batchRows == null || batchRows.isEmpty()) { if (batchRows == null || batchRows.isEmpty()) {
return false; return false;
@@ -1256,7 +1270,7 @@ public class AppearancePatentTaskService {
|| COZE_STATUS_RUNNING.equals(existing.getCozeStatus()); || COZE_STATUS_RUNNING.equals(existing.getCozeStatus());
} }
try { try {
AppearancePatentCozeClient.CozeSubmitResponse submit = cozeClient.submitWorkflow(batchRows, prompt); AppearancePatentCozeClient.CozeSubmitResponse submit = cozeClient.submitWorkflow(batchRows, prompt, apiKey);
if (submit.immediateData() != null && !submit.immediateData().isBlank()) { if (submit.immediateData() != null && !submit.immediateData().isBlank()) {
List<AppearancePatentResultRowDto> cozeRows = cozeClient.mergeRowsFromDataText(batchRows, submit.immediateData()); List<AppearancePatentResultRowDto> cozeRows = cozeClient.mergeRowsFromDataText(batchRows, submit.immediateData());
mergeCozeRowsIntoChunk(task, chunk.getScopeHash(), chunk.getChunkIndex(), cozeRows, allRowsByBaseId); mergeCozeRowsIntoChunk(task, chunk.getScopeHash(), chunk.getChunkIndex(), cozeRows, allRowsByBaseId);
@@ -1305,7 +1319,8 @@ public class AppearancePatentTaskService {
chunk.getScopeHash(), chunk.getScopeHash(),
chunk.getChunkIndex(), chunk.getChunkIndex(),
batchIndex, batchIndex,
batchTotal batchTotal,
currentInstanceId()
); );
String batchPayload = writeJson(batchRows, "serialize coze batch payload failed"); String batchPayload = writeJson(batchRows, "serialize coze batch payload failed");
String storedBatchPayload = storeSharedCozeBatchPayload(task.getId(), batchScopeHash, batchPayload); String storedBatchPayload = storeSharedCozeBatchPayload(task.getId(), batchScopeHash, batchPayload);
@@ -1341,6 +1356,11 @@ public class AppearancePatentTaskService {
if (lockState != null) { if (lockState != null) {
taskIdForLock = lockState.getTaskId(); taskIdForLock = lockState.getTaskId();
} }
if (!isCozeStateOwnedByCurrentInstance(lockState)) {
log.info("[appearance-patent] coze poll skipped because owner is another instance taskId={} stateId={} owner={} current={}",
taskIdForLock, stateId, ownerFromCozeState(lockState), currentInstanceId());
return;
}
TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(taskIdForLock, 0L); TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(taskIdForLock, 0L);
if (lockHandle == null) { if (lockHandle == null) {
if (taskIdForLock != null) { if (taskIdForLock != null) {
@@ -1375,6 +1395,11 @@ public class AppearancePatentTaskService {
markCozeStateTerminal(state, COZE_STATUS_FAILED, "Coze batch context missing"); markCozeStateTerminal(state, COZE_STATUS_FAILED, "Coze batch context missing");
return; return;
} }
if (!isOwnerCurrent(context.ownerInstanceId())) {
log.info("[appearance-patent] coze poll skipped after context refresh because owner is another instance taskId={} stateId={} owner={} current={}",
state.getTaskId(), state.getId(), context.ownerInstanceId(), currentInstanceId());
return;
}
taskFileJobService.touchRunning(context.jobId()); taskFileJobService.touchRunning(context.jobId());
log.info("[appearance-patent] coze poll start taskId={} stateId={} executeId={} jobId={} chunk={} batch={}/{}", log.info("[appearance-patent] coze poll start taskId={} stateId={} executeId={} jobId={} chunk={} batch={}/{}",
state.getTaskId(), state.getId(), state.getCozeExecuteId(), state.getTaskId(), state.getId(), state.getCozeExecuteId(),
@@ -1664,6 +1689,69 @@ public class AppearancePatentTaskService {
+ ":batch:" + batchIndex; + ":batch:" + batchIndex;
} }
private String buildTaskOwnerScopeKey(Long taskId) {
return "task:" + taskId + ":owner:" + currentInstanceId();
}
private String currentInstanceId() {
String instanceId = instanceMetadata == null ? null : instanceMetadata.getInstanceId();
return firstNonBlank(instanceId, "unknown-instance");
}
private boolean isJobOwnedByCurrentInstance(TaskFileJobEntity job) {
return job == null || isOwnerCurrent(ownerFromScopeKey(job.getScopeKey()));
}
private void ensureTaskOwnedByCurrentInstance(FileTaskEntity task, String operation) {
String owner = ownerFromTask(task);
if (isOwnerCurrent(owner)) {
return;
}
log.warn("[appearance-patent] reject task operation because owner is another instance taskId={} operation={} owner={} current={}",
task == null ? null : task.getId(), operation, owner, currentInstanceId());
throw new BusinessException(40903, "该任务已绑定到另一台服务实例处理,请通过原实例继续处理");
}
private boolean isCozeStateOwnedByCurrentInstance(TaskScopeStateEntity state) {
return state == null || isOwnerCurrent(ownerFromCozeState(state));
}
private boolean isOwnerCurrent(String owner) {
return owner == null || owner.isBlank() || Objects.equals(owner, currentInstanceId());
}
private String ownerFromCozeState(TaskScopeStateEntity state) {
CozeBatchContext context = readCozeBatchContext(state);
return context == null ? null : context.ownerInstanceId();
}
private String ownerFromTask(FileTaskEntity task) {
if (task == null || task.getResultJson() == null || task.getResultJson().isBlank()) {
return null;
}
try {
String owner = objectMapper.readTree(task.getResultJson()).path("ownerInstanceId").asText("");
return owner.isBlank() ? null : owner;
} catch (Exception ex) {
log.warn("[appearance-patent] read task owner failed taskId={} err={}",
task.getId(), ex.getMessage());
return null;
}
}
private String ownerFromScopeKey(String scopeKey) {
if (scopeKey == null || scopeKey.isBlank()) {
return null;
}
String marker = ":owner:";
int index = scopeKey.lastIndexOf(marker);
if (index < 0) {
return null;
}
String owner = scopeKey.substring(index + marker.length()).trim();
return owner.isBlank() ? null : owner;
}
private String abbreviate(String value, int maxLength) { private String abbreviate(String value, int maxLength) {
if (value == null) { if (value == null) {
return ""; return "";
@@ -2340,7 +2428,9 @@ public class AppearancePatentTaskService {
LocalDateTime baseTime = snapshot.getUpdatedAt() != null ? snapshot.getUpdatedAt() : job.getUpdatedAt(); LocalDateTime baseTime = snapshot.getUpdatedAt() != null ? snapshot.getUpdatedAt() : job.getUpdatedAt();
long elapsedSeconds = baseTime == null ? 0 : Math.max(0, Duration.between(baseTime, LocalDateTime.now()).getSeconds()); long elapsedSeconds = baseTime == null ? 0 : Math.max(0, Duration.between(baseTime, LocalDateTime.now()).getSeconds());
if (current <= 0) { if (current <= 0) {
percent = Math.max(percent, Math.min(35, 8 + (int) (elapsedSeconds / 6))); int firstRealProgressPercent = Math.max(1, Math.min(99, (int) Math.floor(100.0 / total)));
int waitingCap = Math.max(8, Math.min(35, firstRealProgressPercent - 1));
percent = Math.max(percent, Math.min(waitingCap, 8 + (int) (elapsedSeconds / 6)));
} else if (current < total) { } else if (current < total) {
percent = Math.max(percent, Math.min(92, percent + (int) (elapsedSeconds / 10))); percent = Math.max(percent, Math.min(92, percent + (int) (elapsedSeconds / 10)));
} }
@@ -2379,9 +2469,10 @@ public class AppearancePatentTaskService {
return val == null ? "" : val.replace(String.valueOf((char) 0xFEFF), "").replace((char) 0x3000, ' ').trim().replaceAll("\\s+", " "); return val == null ? "" : val.replace(String.valueOf((char) 0xFEFF), "").replace((char) 0x3000, ' ').trim().replaceAll("\\s+", " ");
} }
private String buildParsedPayloadJson(String aiPrompt, List<AppearancePatentSourceFileDto> sourceFiles, List<String> headers, List<AppearancePatentParsedGroupVo> groups, List<AppearancePatentParsedRowVo> allRows) { private String buildParsedPayloadJson(String aiPrompt, String apiKey, List<AppearancePatentSourceFileDto> sourceFiles, List<String> headers, List<AppearancePatentParsedGroupVo> groups, List<AppearancePatentParsedRowVo> allRows) {
AppearancePatentParsedPayloadDto payload = new AppearancePatentParsedPayloadDto(); AppearancePatentParsedPayloadDto payload = new AppearancePatentParsedPayloadDto();
payload.setAiPrompt(normalize(aiPrompt)); payload.setAiPrompt(normalize(aiPrompt));
payload.setApiKey(normalize(apiKey));
payload.setSourceFiles(sourceFiles == null ? List.of() : sourceFiles); payload.setSourceFiles(sourceFiles == null ? List.of() : sourceFiles);
payload.setHeaders(headers == null ? List.of() : headers); payload.setHeaders(headers == null ? List.of() : headers);
payload.setItems(List.of()); payload.setItems(List.of());
@@ -2390,14 +2481,16 @@ public class AppearancePatentTaskService {
return writeJson(payload, "保存解析结果失败"); return writeJson(payload, "保存解析结果失败");
} }
private String buildTaskResultJson(String aiPrompt, List<AppearancePatentSourceFileDto> sourceFiles, String parsedPayloadPointer) { private String buildTaskResultJson(String aiPrompt, String apiKey, List<AppearancePatentSourceFileDto> sourceFiles, String parsedPayloadPointer) {
Map<String, Object> payload = new LinkedHashMap<>(); Map<String, Object> payload = new LinkedHashMap<>();
payload.put("aiPrompt", normalize(aiPrompt)); payload.put("aiPrompt", normalize(aiPrompt));
payload.put("apiKey", normalize(apiKey));
payload.put("sourceFileKeys", sourceFiles == null ? List.of() : sourceFiles.stream() payload.put("sourceFileKeys", sourceFiles == null ? List.of() : sourceFiles.stream()
.map(AppearancePatentSourceFileDto::getFileKey) .map(AppearancePatentSourceFileDto::getFileKey)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.toList()); .toList());
payload.put("parsedPayloadRef", parsedPayloadPointer); payload.put("parsedPayloadRef", parsedPayloadPointer);
payload.put("ownerInstanceId", currentInstanceId());
return writeJson(payload, "保存任务结果索引失败"); return writeJson(payload, "保存任务结果索引失败");
} }
@@ -2661,7 +2754,8 @@ public class AppearancePatentTaskService {
String chunkScopeHash, String chunkScopeHash,
Integer chunkIndex, Integer chunkIndex,
Integer batchIndex, Integer batchIndex,
Integer batchTotal) { Integer batchTotal,
String ownerInstanceId) {
} }
private record ParsedWorkbook(int totalRows, int droppedRows, List<String> headers, List<AppearancePatentParsedRowVo> allRows) { private record ParsedWorkbook(int totalRows, int droppedRows, List<String> headers, List<AppearancePatentParsedRowVo> allRows) {

View File

@@ -30,7 +30,7 @@ public class SimilarAsinCozeClient {
private final SimilarAsinProperties properties; private final SimilarAsinProperties properties;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
public List<SimilarAsinResultRowDto> inspect(List<SimilarAsinResultRowDto> rows, String prompt) { public List<SimilarAsinResultRowDto> inspect(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) {
if (rows == null || rows.isEmpty()) { if (rows == null || rows.isEmpty()) {
return List.of(); return List.of();
} }
@@ -39,7 +39,7 @@ public class SimilarAsinCozeClient {
return rows.stream().map(this::copy).toList(); return rows.stream().map(this::copy).toList();
} }
try { try {
return inspectWithFallback(rows, prompt); return inspectWithFallback(rows, prompt, apiKey);
} catch (Exception ex) { } catch (Exception ex) {
String failureMessage = failureMessage(ex); String failureMessage = failureMessage(ex);
log.warn("[similar-asin] coze batch failed size={} err={}", rows.size(), failureMessage); log.warn("[similar-asin] coze batch failed size={} err={}", rows.size(), failureMessage);
@@ -47,8 +47,8 @@ public class SimilarAsinCozeClient {
} }
} }
public CozeSubmitResponse submitWorkflow(List<SimilarAsinResultRowDto> rows, String prompt) throws Exception { public CozeSubmitResponse submitWorkflow(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) throws Exception {
JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt)); JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt, apiKey));
ensureSuccess(submitRoot); ensureSuccess(submitRoot);
return new CozeSubmitResponse( return new CozeSubmitResponse(
extractExecuteId(submitRoot), extractExecuteId(submitRoot),
@@ -83,12 +83,12 @@ public class SimilarAsinCozeClient {
return rows.stream().map(this::copy).map(row -> markFailed(row, failureMessage)).toList(); return rows.stream().map(this::copy).map(row -> markFailed(row, failureMessage)).toList();
} }
private List<SimilarAsinResultRowDto> inspectWithFallback(List<SimilarAsinResultRowDto> rows, String prompt) { private List<SimilarAsinResultRowDto> inspectWithFallback(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) {
try { try {
if (rows.size() == 1) { if (rows.size() == 1) {
return inspectSingleRowWithRetry(rows, prompt); return inspectSingleRowWithRetry(rows, prompt, apiKey);
} }
InspectAttempt attempt = inspectOnce(rows, prompt); InspectAttempt attempt = inspectOnce(rows, prompt, apiKey);
if (attempt.resolvedCount() < rows.size()) { if (attempt.resolvedCount() < rows.size()) {
throw new PartialCozeResultException(attempt.resolvedCount(), rows.size(), attempt.rawResultCount()); throw new PartialCozeResultException(attempt.resolvedCount(), rows.size(), attempt.rawResultCount());
} }
@@ -99,17 +99,17 @@ public class SimilarAsinCozeClient {
log.warn("[similar-asin] coze batch fallback split size={} left={} right={} err={}", log.warn("[similar-asin] coze batch fallback split size={} left={} right={} err={}",
rows.size(), middle, rows.size() - middle, failureMessage(ex)); rows.size(), middle, rows.size() - middle, failureMessage(ex));
List<SimilarAsinResultRowDto> merged = new ArrayList<>(rows.size()); List<SimilarAsinResultRowDto> merged = new ArrayList<>(rows.size());
merged.addAll(inspectPartitionWithFailureFallback(rows.subList(0, middle), prompt)); merged.addAll(inspectPartitionWithFailureFallback(rows.subList(0, middle), prompt, apiKey));
merged.addAll(inspectPartitionWithFailureFallback(rows.subList(middle, rows.size()), prompt)); merged.addAll(inspectPartitionWithFailureFallback(rows.subList(middle, rows.size()), prompt, apiKey));
return merged; return merged;
} }
throw propagate(ex); throw propagate(ex);
} }
} }
private List<SimilarAsinResultRowDto> inspectPartitionWithFailureFallback(List<SimilarAsinResultRowDto> rows, String prompt) { private List<SimilarAsinResultRowDto> inspectPartitionWithFailureFallback(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) {
try { try {
return inspectWithFallback(rows, prompt); return inspectWithFallback(rows, prompt, apiKey);
} catch (Exception ex) { } catch (Exception ex) {
String failureMessage = failureMessage(ex); String failureMessage = failureMessage(ex);
log.warn("[similar-asin] coze partition failed size={} err={}", rows.size(), failureMessage); log.warn("[similar-asin] coze partition failed size={} err={}", rows.size(), failureMessage);
@@ -117,12 +117,12 @@ public class SimilarAsinCozeClient {
} }
} }
private List<SimilarAsinResultRowDto> inspectSingleRowWithRetry(List<SimilarAsinResultRowDto> rows, String prompt) throws Exception { private List<SimilarAsinResultRowDto> inspectSingleRowWithRetry(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) throws Exception {
SimilarAsinResultRowDto row = rows.getFirst(); SimilarAsinResultRowDto row = rows.getFirst();
PartialCozeResultException lastFailure = null; PartialCozeResultException lastFailure = null;
for (int attemptIndex = 1; attemptIndex <= 3; attemptIndex++) { for (int attemptIndex = 1; attemptIndex <= 3; attemptIndex++) {
try { try {
InspectAttempt attempt = inspectOnce(rows, prompt); InspectAttempt attempt = inspectOnce(rows, prompt, apiKey);
if (attempt.resolvedCount() == rows.size()) { if (attempt.resolvedCount() == rows.size()) {
return attempt.mergedRows(); return attempt.mergedRows();
} }
@@ -153,8 +153,8 @@ public class SimilarAsinCozeClient {
throw lastFailure == null ? new PartialCozeResultException(0, rows.size(), 0) : lastFailure; throw lastFailure == null ? new PartialCozeResultException(0, rows.size(), 0) : lastFailure;
} }
private InspectAttempt inspectOnce(List<SimilarAsinResultRowDto> rows, String prompt) throws Exception { private InspectAttempt inspectOnce(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) throws Exception {
String raw = runWorkflowAsyncAndWait(rows, prompt); String raw = runWorkflowAsyncAndWait(rows, prompt, apiKey);
List<CozeResult> results = parseResults(raw); List<CozeResult> results = parseResults(raw);
if (rows.size() > 1 && !results.isEmpty() && results.stream().noneMatch(this::hasIdentity)) { if (rows.size() > 1 && !results.isEmpty() && results.stream().noneMatch(this::hasIdentity)) {
throw new PartialCozeResultException(0, rows.size(), results.size()); throw new PartialCozeResultException(0, rows.size(), results.size());
@@ -163,8 +163,8 @@ public class SimilarAsinCozeClient {
return new InspectAttempt(raw, merged, resolvedCount(merged), results.size()); return new InspectAttempt(raw, merged, resolvedCount(merged), results.size());
} }
private String runWorkflowAsyncAndWait(List<SimilarAsinResultRowDto> rows, String prompt) throws Exception { private String runWorkflowAsyncAndWait(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) throws Exception {
JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt)); JsonNode submitRoot = objectMapper.readTree(postWorkflow(rows, prompt, apiKey));
ensureSuccess(submitRoot); ensureSuccess(submitRoot);
String immediateData = extractResultDataText(submitRoot); String immediateData = extractResultDataText(submitRoot);
@@ -205,15 +205,15 @@ public class SimilarAsinCozeClient {
throw new IllegalStateException("Coze async workflow poll timeout"); throw new IllegalStateException("Coze async workflow poll timeout");
} }
private String postWorkflow(List<SimilarAsinResultRowDto> rows, String prompt) { private String postWorkflow(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) {
Map<String, Object> parameters = buildParameters(rows, prompt); Map<String, Object> parameters = buildParameters(rows, prompt, apiKey);
Map<String, Object> body = new LinkedHashMap<>(); Map<String, Object> body = new LinkedHashMap<>();
body.put("workflow_id", properties.getCozeWorkflowId()); body.put("workflow_id", properties.getCozeWorkflowId());
body.put("parameters", parameters); body.put("parameters", parameters);
body.put("is_async", Boolean.TRUE); body.put("is_async", Boolean.TRUE);
log.info("[similar-asin] coze request url={} body={}", log.info("[similar-asin] coze request url={} body={}",
joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath()), joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath()),
writeJson(body)); writeJson(maskCozeRequestBody(body)));
RestClient.RequestBodySpec request = restClient().post() RestClient.RequestBodySpec request = restClient().post()
.uri(joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath())) .uri(joinUrl(properties.getCozeBaseUrl(), properties.getCozeWorkflowPath()))
@@ -255,11 +255,12 @@ public class SimilarAsinCozeClient {
}); });
} }
private Map<String, Object> buildParameters(List<SimilarAsinResultRowDto> rows, String prompt) { private Map<String, Object> buildParameters(List<SimilarAsinResultRowDto> rows, String prompt, String apiKey) {
List<String> groupKeys = rows.stream().map(row -> nonBlank(row.getGroupKey(), rowKey(row))).toList(); List<String> groupKeys = rows.stream().map(row -> nonBlank(row.getGroupKey(), rowKey(row))).toList();
List<String> rowIds = rows.stream().map(row -> nonBlank(row.getId(), "")).toList(); List<String> rowIds = rows.stream().map(row -> nonBlank(row.getId(), "")).toList();
List<String> asins = rows.stream().map(row -> nonBlank(row.getAsin(), "")).toList(); List<String> asins = rows.stream().map(row -> nonBlank(row.getAsin(), "")).toList();
List<String> countries = rows.stream().map(row -> nonBlank(row.getCountry(), "")).toList(); List<String> countries = rows.stream().map(row -> nonBlank(row.getCountry(), "")).toList();
List<String> prices = rows.stream().map(row -> nonBlank(row.getPrice(), "")).toList();
List<String> titles = rows.stream().map(row -> nonBlank(row.getTitle(), row.getAsin())).toList(); List<String> titles = rows.stream().map(row -> nonBlank(row.getTitle(), row.getAsin())).toList();
List<String> urls = rows.stream().map(row -> nonBlank(row.getUrl(), "")).toList(); List<String> urls = rows.stream().map(row -> nonBlank(row.getUrl(), "")).toList();
List<List<String>> urlLists = rows.stream().map(SimilarAsinResultRowDto::getUrls).toList(); List<List<String>> urlLists = rows.stream().map(SimilarAsinResultRowDto::getUrls).toList();
@@ -268,17 +269,48 @@ public class SimilarAsinCozeClient {
parameters.put("title_list", titles); parameters.put("title_list", titles);
parameters.put("url_list", urls); parameters.put("url_list", urls);
parameters.put("url_lists", urlLists); parameters.put("url_lists", urlLists);
parameters.put("items", buildItemObjects(rows, groupKeys, rowIds, asins, countries, titles, urlLists)); parameters.put("items", buildItemObjects(rows, groupKeys, rowIds, asins, countries, prices, titles, urls, urlLists));
parameters.put("prompt", prompt == null ? "" : prompt); parameters.put("prompt", prompt == null ? "" : prompt);
if (apiKey != null && !apiKey.isBlank()) {
parameters.put("api_key", apiKey.trim());
}
return parameters; return parameters;
} }
@SuppressWarnings("unchecked")
private Map<String, Object> maskCozeRequestBody(Map<String, Object> body) {
Map<String, Object> masked = new LinkedHashMap<>(body);
Object parametersObj = masked.get("parameters");
if (parametersObj instanceof Map<?, ?> parameters) {
Map<String, Object> maskedParameters = new LinkedHashMap<>((Map<String, Object>) parameters);
Object apiKey = maskedParameters.get("api_key");
if (apiKey instanceof String apiKeyText && !apiKeyText.isBlank()) {
maskedParameters.put("api_key", maskSecret(apiKeyText));
}
masked.put("parameters", maskedParameters);
}
return masked;
}
private String maskSecret(String secret) {
String normalized = secret == null ? "" : secret.trim();
if (normalized.isBlank()) {
return "";
}
if (normalized.length() <= 10) {
return "***";
}
return normalized.substring(0, 6) + "***" + normalized.substring(normalized.length() - 4);
}
private List<Map<String, Object>> buildItemObjects(List<SimilarAsinResultRowDto> rows, private List<Map<String, Object>> buildItemObjects(List<SimilarAsinResultRowDto> rows,
List<String> groupKeys, List<String> groupKeys,
List<String> rowIds, List<String> rowIds,
List<String> asins, List<String> asins,
List<String> countries, List<String> countries,
List<String> prices,
List<String> titles, List<String> titles,
List<String> urls,
List<List<String>> urlLists) { List<List<String>> urlLists) {
List<Map<String, Object>> items = new ArrayList<>(rows.size()); List<Map<String, Object>> items = new ArrayList<>(rows.size());
for (int i = 0; i < rows.size(); i++) { for (int i = 0; i < rows.size(); i++) {
@@ -287,9 +319,11 @@ public class SimilarAsinCozeClient {
item.put("row_id", rowIds.get(i)); item.put("row_id", rowIds.get(i));
item.put("asin", asins.get(i)); item.put("asin", asins.get(i));
item.put("country", countries.get(i)); item.put("country", countries.get(i));
item.put("price", prices.get(i));
item.put("title", titles.get(i)); item.put("title", titles.get(i));
item.put("url", urlLists.get(i)); item.put("url", urls.get(i));
item.put("urls", urlLists.get(i)); item.put("urls", urlLists.get(i));
item.put("target_urls", urlLists.get(i));
items.add(item); items.add(item);
} }
return items; return items;
@@ -319,7 +353,16 @@ public class SimilarAsinCozeClient {
text(firstNonNull( text(firstNonNull(
firstNonNull(node.get("country"), node.get("site")), firstNonNull(node.get("country"), node.get("site")),
firstNonNull(itemNode.get("country"), itemNode.get("site")))), firstNonNull(itemNode.get("country"), itemNode.get("site")))),
text(firstNonNull(
firstNonNull(node.get("price"), node.get("价格")),
firstNonNull(itemNode.get("price"), itemNode.get("价格")))),
text(firstNonNull(node.get("title"), firstNonNull(itemNode.get("title"), itemNode.get("title_risk")))), text(firstNonNull(node.get("title"), firstNonNull(itemNode.get("title"), itemNode.get("title_risk")))),
text(firstNonNull(
firstNonNull(node.get("is_stock"), firstNonNull(node.get("isStock"), firstNonNull(node.get("stock"), node.get("是否有货")))),
firstNonNull(itemNode.get("is_stock"), firstNonNull(itemNode.get("isStock"), firstNonNull(itemNode.get("stock"), itemNode.get("是否有货")))))),
text(firstNonNull(
firstNonNull(node.get("similarity"), firstNonNull(node.get("similarity_rate"), node.get("相似度"))),
firstNonNull(itemNode.get("similarity"), firstNonNull(itemNode.get("similarity_rate"), itemNode.get("相似度"))))),
text(firstNonNull(node.get("appearance"), text(firstNonNull(node.get("appearance"),
firstNonNull(node.get("appearance_risk"), firstNonNull(node.get("appearance_risk"),
firstNonNull(itemNode.get("appearance"), itemNode.get("appearance_risk"))))), firstNonNull(itemNode.get("appearance"), itemNode.get("appearance_risk"))))),
@@ -396,6 +439,9 @@ public class SimilarAsinCozeClient {
if (result == null) { if (result == null) {
result = resultByCompositeKey.get(rowKey(row.getId(), row.getAsin(), row.getCountry())); result = resultByCompositeKey.get(rowKey(row.getId(), row.getAsin(), row.getCountry()));
} }
if (result == null && i < results.size() && isIndexedResultForRow(results.get(i), row)) {
result = results.get(i);
}
if (result == null) { if (result == null) {
result = resultByAsinCountry.get(asinCountryKey(row.getAsin(), row.getCountry())); result = resultByAsinCountry.get(asinCountryKey(row.getAsin(), row.getCountry()));
} }
@@ -431,11 +477,25 @@ public class SimilarAsinCozeClient {
|| !normalize(result.asin()).isBlank(); || !normalize(result.asin()).isBlank();
} }
private boolean isIndexedResultForRow(CozeResult result, SimilarAsinResultRowDto row) {
if (result == null || row == null) {
return false;
}
if (!normalize(result.groupKey()).isBlank() || !normalize(result.rowId()).isBlank()) {
return false;
}
String resultAsin = normalize(result.asin()).toUpperCase(Locale.ROOT);
return resultAsin.isBlank() || resultAsin.equals(normalize(row.getAsin()).toUpperCase(Locale.ROOT));
}
private void applyResult(SimilarAsinResultRowDto row, CozeResult result) { private void applyResult(SimilarAsinResultRowDto row, CozeResult result) {
if (row == null || result == null) { if (row == null || result == null) {
return; return;
} }
row.setTitleRisk(result.title()); row.setTitleRisk(result.title());
row.setPrice(nonBlank(result.price(), row.getPrice()));
row.setIsStock(result.isStock());
row.setSimilarity(result.similarity());
row.setAppearanceRisk(result.appearance()); row.setAppearanceRisk(result.appearance());
row.setPatentRisk(result.patent()); row.setPatentRisk(result.patent());
row.setConclusion(result.result()); row.setConclusion(result.result());
@@ -460,6 +520,7 @@ public class SimilarAsinCozeClient {
row.setId(source.getId()); row.setId(source.getId());
row.setAsin(source.getAsin()); row.setAsin(source.getAsin());
row.setCountry(source.getCountry()); row.setCountry(source.getCountry());
row.setPrice(source.getPrice());
row.setUrls(source.getUrls()); row.setUrls(source.getUrls());
row.setTitle(source.getTitle()); row.setTitle(source.getTitle());
row.setError(source.getError()); row.setError(source.getError());
@@ -468,6 +529,8 @@ public class SimilarAsinCozeClient {
row.setAppearanceRisk(source.getAppearanceRisk()); row.setAppearanceRisk(source.getAppearanceRisk());
row.setPatentRisk(source.getPatentRisk()); row.setPatentRisk(source.getPatentRisk());
row.setConclusion(source.getConclusion()); row.setConclusion(source.getConclusion());
row.setIsStock(source.getIsStock());
row.setSimilarity(source.getSimilarity());
row.setTitleReason(source.getTitleReason()); row.setTitleReason(source.getTitleReason());
row.setAppearanceReason(source.getAppearanceReason()); row.setAppearanceReason(source.getAppearanceReason());
row.setPatentReason(source.getPatentReason()); row.setPatentReason(source.getPatentReason());
@@ -529,7 +592,9 @@ public class SimilarAsinCozeClient {
return !normalize(row.getTitleRisk()).isBlank() return !normalize(row.getTitleRisk()).isBlank()
|| !normalize(row.getAppearanceRisk()).isBlank() || !normalize(row.getAppearanceRisk()).isBlank()
|| !normalize(row.getPatentRisk()).isBlank() || !normalize(row.getPatentRisk()).isBlank()
|| !normalize(row.getConclusion()).isBlank(); || !normalize(row.getConclusion()).isBlank()
|| !normalize(row.getIsStock()).isBlank()
|| !normalize(row.getSimilarity()).isBlank();
} }
private void ensureSuccess(JsonNode root) { private void ensureSuccess(JsonNode root) {
@@ -656,6 +721,13 @@ public class SimilarAsinCozeClient {
|| item.has("patent_risk") || item.has("patent_risk")
|| item.has("result") || item.has("result")
|| item.has("conclusion") || item.has("conclusion")
|| item.has("is_stock")
|| item.has("isStock")
|| item.has("stock")
|| item.has("是否有货")
|| item.has("similarity")
|| item.has("similarity_rate")
|| item.has("相似度")
|| item.has("title_reason") || item.has("title_reason")
|| item.has("titleReason") || item.has("titleReason")
|| item.has("appearance_reason") || item.has("appearance_reason")
@@ -909,7 +981,10 @@ public class SimilarAsinCozeClient {
String rowId, String rowId,
String asin, String asin,
String country, String country,
String price,
String title, String title,
String isStock,
String similarity,
String appearance, String appearance,
String patent, String patent,
String result, String result,

View File

@@ -3,6 +3,7 @@ package com.nanri.aiimage.modules.similarasin.model.dto;
import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@@ -25,4 +26,10 @@ public class SimilarAsinParseRequest {
@JsonAlias({"aiPrompt", "prompt"}) @JsonAlias({"aiPrompt", "prompt"})
@Schema(description = "AI 提示词。非必填;为空时前端会使用默认提示词。后端会保存该提示词,并在调用 Coze workflow 时作为 prompt 参数传入。", example = "请排查这些亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。") @Schema(description = "AI 提示词。非必填;为空时前端会使用默认提示词。后端会保存该提示词,并在调用 Coze workflow 时作为 prompt 参数传入。", example = "请排查这些亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。")
private String aiPrompt; private String aiPrompt;
@JsonProperty("api_key")
@JsonAlias({"apiKey"})
@Schema(description = "传递给 Coze workflow parameters.api_key 的任务级密钥。")
@NotBlank(message = "密钥不能为空")
private String apiKey;
} }

View File

@@ -14,6 +14,9 @@ public class SimilarAsinParsedPayloadDto {
@Schema(description = "AI 提示词") @Schema(description = "AI 提示词")
private String aiPrompt; private String aiPrompt;
@Schema(description = "传递给 Coze workflow parameters.api_key 的任务级密钥")
private String apiKey;
@Schema(description = "本次解析的源文件列表") @Schema(description = "本次解析的源文件列表")
private List<SimilarAsinSourceFileDto> sourceFiles = new ArrayList<>(); private List<SimilarAsinSourceFileDto> sourceFiles = new ArrayList<>();

View File

@@ -39,6 +39,10 @@ public class SimilarAsinResultRowDto {
@Schema(description = "站点或国家。来自 Excel 的国家列,例如英国、德国、法国。", example = "英国") @Schema(description = "站点或国家。来自 Excel 的国家列,例如英国、德国、法国。", example = "英国")
private String country; private String country;
@JsonAlias({"price", "价格"})
@Schema(description = "商品价格。来自 Excel 解析或 Python 回传。", example = "12.29")
private String price;
@Schema(description = "兼容旧链路的首个图片 URL。新链路允许 url 传字符串或数组;数组会同步写入 urls。", example = "https://webstatic.aiproxy.vip/output/20260425/103322/demo.jpg") @Schema(description = "兼容旧链路的首个图片 URL。新链路允许 url 传字符串或数组;数组会同步写入 urls。", example = "https://webstatic.aiproxy.vip/output/20260425/103322/demo.jpg")
private String url; private String url;
@@ -49,23 +53,31 @@ public class SimilarAsinResultRowDto {
@JsonAlias({"productTitle", "product_title", "itemTitle", "item_title", "商品标题", "商品名称", "标题"}) @JsonAlias({"productTitle", "product_title", "itemTitle", "item_title", "商品标题", "商品名称", "标题"})
private String title; private String title;
@JsonAlias({"is_stock", "isStock", "stock", "是否有货"})
@Schema(description = "Coze 返回的是否有货结果。", example = "有货", accessMode = Schema.AccessMode.READ_ONLY)
private String isStock;
@JsonAlias({"similarity", "similarity_rate", "similarityRate", "相似度"})
@Schema(description = "Coze 返回的相似度结果。", example = "80%", accessMode = Schema.AccessMode.READ_ONLY)
private String similarity;
@Schema(description = "单行错误信息。通常用于记录 Python 单行处理异常Coze 失败时后端会尽量保留原始行,不强行写入风险结果。", example = "图片地址为空") @Schema(description = "单行错误信息。通常用于记录 Python 单行处理异常Coze 失败时后端会尽量保留原始行,不强行写入风险结果。", example = "图片地址为空")
private String error; private String error;
@Schema(description = "单行完成标记。当前主要使用请求体顶层 done 控制任务收尾,该字段仅作兼容。", example = "true") @Schema(description = "单行完成标记。当前主要使用请求体顶层 done 控制任务收尾,该字段仅作兼容。", example = "true")
private Boolean done; private Boolean done;
@Schema(description = "Java 调用 Coze 后生成的标题维度检测结果,对应最终 xlsx 的“标题维度商标”列。Python 回传请求中不要传该字段;即使传入,后端也会以 Java/Coze 处理结果为准", example = "标题未发现明显商标侵权风险。", accessMode = Schema.AccessMode.READ_ONLY) @Schema(description = "兼容旧版 Coze 返回中的标题维度结果字段;当前相似 ASIN 结果文件不再输出该列", example = "标题未发现明显商标侵权风险。", accessMode = Schema.AccessMode.READ_ONLY)
private String titleRisk; private String titleRisk;
@Schema(description = "Java 调用 Coze 后生成的外观维度检测结果,对应最终 xlsx 的“外观维度外观设计专利”列。Python 回传请求中不要传该字段", example = "未发现明显外观设计专利侵权风险。", accessMode = Schema.AccessMode.READ_ONLY) @Schema(description = "兼容旧版 Coze 返回中的外观维度结果字段;当前相似 ASIN 结果文件不再输出该列", example = "未发现明显外观设计专利侵权风险。", accessMode = Schema.AccessMode.READ_ONLY)
private String appearanceRisk; private String appearanceRisk;
@JsonAlias({"patent ", "patent"}) @JsonAlias({"patent ", "patent"})
@Schema(description = "Java 调用 Coze 后生成的专利维度检测结果,对应最终 xlsx 的“专利维度(发明/实用新型专利)”列。兼容 Coze 返回字段 patent 和 patent 后带空格的情况Python 回传请求中不要传该字段", example = "未发现明显发明或实用新型专利侵权风险。", accessMode = Schema.AccessMode.READ_ONLY) @Schema(description = "兼容旧版 Coze 返回中的专利维度结果字段;当前相似 ASIN 结果文件不再输出该列", example = "未发现明显发明或实用新型专利侵权风险。", accessMode = Schema.AccessMode.READ_ONLY)
private String patentRisk; private String patentRisk;
@Schema(description = "Java 调用 Coze 后生成的最终结论,对应最终 xlsx 的“结论”列。Python 回传请求中不要传该字段", example = "未发现明显侵权风险", accessMode = Schema.AccessMode.READ_ONLY) @Schema(description = "兼容旧版 Coze 返回中的结论字段;当前相似 ASIN 结果文件不再输出该列", example = "未发现明显侵权风险", accessMode = Schema.AccessMode.READ_ONLY)
private String conclusion; private String conclusion;
@JsonAlias({"title_reason", "titleReason"}) @JsonAlias({"title_reason", "titleReason"})
@@ -118,6 +130,7 @@ public class SimilarAsinResultRowDto {
"mainImages", "main_images", "mainImageUrls", "main_image_urls", "mainImages", "main_images", "mainImageUrls", "main_image_urls",
"productImages", "product_images", "productImageUrls", "product_image_urls", "productImages", "product_images", "productImageUrls", "product_image_urls",
"images", "imgs", "pics", "pictures", "links", "imageLinks", "image_links", "images", "imgs", "pics", "pictures", "links", "imageLinks", "image_links",
"target_urls", "targetUrls", "图片链接数组",
"图片链接", "商品图片", "商品主图", "主图", "主图链接" "图片链接", "商品图片", "商品主图", "主图", "主图链接"
}) })
public void setUrls(Object urls) { public void setUrls(Object urls) {

View File

@@ -36,6 +36,9 @@ public class SimilarAsinParsedRowVo {
@Schema(description = "国家或站点。", example = "英国") @Schema(description = "国家或站点。", example = "英国")
private String country; private String country;
@Schema(description = "商品价格。", example = "12.29")
private String price;
@Schema(description = "商品图片 URL 或商品 URL供 Coze 检测使用。", example = "https://webstatic.aiproxy.vip/output/demo.jpg") @Schema(description = "商品图片 URL 或商品 URL供 Coze 检测使用。", example = "https://webstatic.aiproxy.vip/output/demo.jpg")
private String url; private String url;

View File

@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.nanri.aiimage.common.exception.BusinessException; import com.nanri.aiimage.common.exception.BusinessException;
import com.nanri.aiimage.common.service.DistributedJobLockService; import com.nanri.aiimage.common.service.DistributedJobLockService;
import com.nanri.aiimage.config.InstanceMetadata;
import com.nanri.aiimage.config.SimilarAsinProperties; import com.nanri.aiimage.config.SimilarAsinProperties;
import com.nanri.aiimage.config.StorageProperties; import com.nanri.aiimage.config.StorageProperties;
import com.nanri.aiimage.modules.similarasin.client.SimilarAsinCozeClient; import com.nanri.aiimage.modules.similarasin.client.SimilarAsinCozeClient;
@@ -99,15 +100,15 @@ public class SimilarAsinTaskService {
private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 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 int RESULT_ROWS_READ_RETRY_LIMIT = 3;
private static final long RESULT_ROWS_READ_RETRY_DELAY_MS = 500L; private static final long RESULT_ROWS_READ_RETRY_DELAY_MS = 500L;
private static final Duration TASK_LOCK_TTL = Duration.ofMinutes(5);
private static final long TASK_LOCK_WAIT_MILLIS = 10000L;
private static final List<String> RESULT_HEADERS = List.of( private static final List<String> RESULT_HEADERS = List.of(
"id", "id",
"asin", "asin",
"国家", "国家",
"价格", "价格",
"标题维度(商标)", "是否有货",
"外观维度(外观设计专利)", "相似度"
"专利维度(发明/实用新型专利)",
"结论"
); );
private final LocalFileStorageService localFileStorageService; private final LocalFileStorageService localFileStorageService;
@@ -127,6 +128,7 @@ public class SimilarAsinTaskService {
private final TransientPayloadStorageService transientPayloadStorageService; private final TransientPayloadStorageService transientPayloadStorageService;
private final PlatformTransactionManager transactionManager; private final PlatformTransactionManager transactionManager;
private final DistributedJobLockService distributedJobLockService; private final DistributedJobLockService distributedJobLockService;
private final InstanceMetadata instanceMetadata;
@Autowired @Autowired
@Qualifier("cozeTaskExecutor") @Qualifier("cozeTaskExecutor")
private TaskExecutor cozeTaskExecutor; private TaskExecutor cozeTaskExecutor;
@@ -195,11 +197,11 @@ public class SimilarAsinTaskService {
String aggregateScopeKey = buildAggregateScopeKey(sourceFiles); String aggregateScopeKey = buildAggregateScopeKey(sourceFiles);
String sourceScopeHash = DigestUtil.sha256Hex(aggregateScopeKey); String sourceScopeHash = DigestUtil.sha256Hex(aggregateScopeKey);
String parsedPayload = buildParsedPayloadJson(request.getAiPrompt(), sourceFiles, mergedHeaders, groups, allRows); String parsedPayload = buildParsedPayloadJson(request.getAiPrompt(), request.getApiKey(), sourceFiles, mergedHeaders, groups, allRows);
long payloadBuiltAt = System.nanoTime(); long payloadBuiltAt = System.nanoTime();
String parsedPayloadPointer = storeParsedPayload(task.getId(), sourceScopeHash, parsedPayload); String parsedPayloadPointer = storeParsedPayload(task.getId(), sourceScopeHash, parsedPayload);
long payloadStoredAt = System.nanoTime(); long payloadStoredAt = System.nanoTime();
task.setResultJson(buildTaskResultJson(request.getAiPrompt(), sourceFiles, parsedPayloadPointer)); task.setResultJson(buildTaskResultJson(request.getAiPrompt(), request.getApiKey(), sourceFiles, parsedPayloadPointer));
task.setUpdatedAt(LocalDateTime.now()); task.setUpdatedAt(LocalDateTime.now());
fileTaskMapper.updateById(task); fileTaskMapper.updateById(task);
@@ -386,6 +388,16 @@ public class SimilarAsinTaskService {
} }
public void submitResult(Long taskId, SimilarAsinSubmitResultRequest request) { public void submitResult(Long taskId, SimilarAsinSubmitResultRequest request) {
TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(taskId, TASK_LOCK_WAIT_MILLIS);
if (lockHandle == null) {
throw new BusinessException(40902, "Task is processing the previous result chunk, please retry later");
}
try (lockHandle) {
submitResultLocked(taskId, request);
}
}
private void submitResultLocked(Long taskId, SimilarAsinSubmitResultRequest request) {
if (transactionManager != null) { if (transactionManager != null) {
SubmitContext context = inNewTransaction(() -> persistSubmittedChunk(taskId, request)); SubmitContext context = inNewTransaction(() -> persistSubmittedChunk(taskId, request));
inNewTransaction(() -> { inNewTransaction(() -> {
@@ -402,6 +414,7 @@ public class SimilarAsinTaskService {
throw new BusinessException("任务不是运行中状态"); throw new BusinessException("任务不是运行中状态");
} }
ensureTaskOwnedByCurrentInstance(task, "submit result");
int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex(); int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex();
int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal(); int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal();
String scopeKey = firstNonBlank(request.getSubmissionId(), "task:" + taskId); String scopeKey = firstNonBlank(request.getSubmissionId(), "task:" + taskId);
@@ -530,6 +543,9 @@ public class SimilarAsinTaskService {
.lt(FileTaskEntity::getUpdatedAt, threshold) .lt(FileTaskEntity::getUpdatedAt, threshold)
.last("limit 50")); .last("limit 50"));
for (FileTaskEntity task : tasks) { for (FileTaskEntity task : tasks) {
if (!isOwnerCurrent(ownerFromTask(task))) {
continue;
}
if (isJavaSideProcessing(task.getId())) { if (isJavaSideProcessing(task.getId())) {
touchJavaSideTaskActivity(task.getId()); touchJavaSideTaskActivity(task.getId());
continue; continue;
@@ -559,6 +575,9 @@ public class SimilarAsinTaskService {
.lt(FileTaskEntity::getUpdatedAt, threshold) .lt(FileTaskEntity::getUpdatedAt, threshold)
.last("limit 50")); .last("limit 50"));
for (FileTaskEntity task : tasks) { for (FileTaskEntity task : tasks) {
if (!isOwnerCurrent(ownerFromTask(task))) {
continue;
}
if (isJavaSideProcessing(task.getId())) { if (isJavaSideProcessing(task.getId())) {
touchJavaSideTaskActivity(task.getId()); touchJavaSideTaskActivity(task.getId());
continue; continue;
@@ -586,6 +605,7 @@ public class SimilarAsinTaskService {
throw new BusinessException("任务不是运行中状态"); throw new BusinessException("任务不是运行中状态");
} }
ensureTaskOwnedByCurrentInstance(task, "submit result");
int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex(); int chunkIndex = request.getChunkIndex() == null ? 0 : request.getChunkIndex();
int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal(); int chunkTotal = request.getChunkTotal() == null ? 1 : request.getChunkTotal();
boolean done = Boolean.TRUE.equals(request.getDone()); boolean done = Boolean.TRUE.equals(request.getDone());
@@ -738,10 +758,11 @@ public class SimilarAsinTaskService {
return List.of(); return List.of();
} }
String prompt = readAiPrompt(task); String prompt = readAiPrompt(task);
String apiKey = readApiKey(task);
int batchSize = Math.max(1, properties.getCozeBatchSize()); int batchSize = Math.max(1, properties.getCozeBatchSize());
List<SimilarAsinResultRowDto> result = new ArrayList<>(); List<SimilarAsinResultRowDto> result = new ArrayList<>();
for (int i = 0; i < items.size(); i += batchSize) { for (int i = 0; i < items.size(); i += batchSize) {
result.addAll(cozeClient.inspect(items.subList(i, Math.min(i + batchSize, items.size())), prompt)); result.addAll(cozeClient.inspect(items.subList(i, Math.min(i + batchSize, items.size())), prompt, apiKey));
if (progressHook != null) { if (progressHook != null) {
progressHook.run(); progressHook.run();
} }
@@ -818,17 +839,9 @@ public class SimilarAsinTaskService {
List<SimilarAsinResultRowDto> result = new ArrayList<>(); List<SimilarAsinResultRowDto> result = new ArrayList<>();
Set<String> emittedKeys = new LinkedHashSet<>(); Set<String> emittedKeys = new LinkedHashSet<>();
for (SimilarAsinResultRowDto representative : representatives) { for (SimilarAsinResultRowDto representative : representatives) {
List<SimilarAsinParsedRowVo> siblings = resolveSiblingRows(representative, allRowsByBaseId); String key = firstNonBlank(normalize(representative.getRowToken()), rowKey(representative));
if (siblings == null || siblings.isEmpty()) { if (emittedKeys.add(key)) {
result.add(representative); result.add(representative);
continue;
}
for (SimilarAsinParsedRowVo sibling : siblings) {
String key = rowKey(sibling);
if (!emittedKeys.add(key)) {
continue;
}
result.add(copyResultToSibling(representative, sibling));
} }
} }
return result; return result;
@@ -877,32 +890,13 @@ public class SimilarAsinTaskService {
} }
private List<SimilarAsinResultRowDto> pickGroupRepresentativesForCoze(java.util.Collection<SimilarAsinResultRowDto> rows) { private List<SimilarAsinResultRowDto> pickGroupRepresentativesForCoze(java.util.Collection<SimilarAsinResultRowDto> rows) {
Map<String, List<SimilarAsinResultRowDto>> groupedRows = new LinkedHashMap<>();
if (rows == null) { if (rows == null) {
return List.of(); return List.of();
} }
for (SimilarAsinResultRowDto row : rows) {
if (row == null) {
continue;
}
String key = firstNonBlank(normalize(row.getGroupKey()), rowKey(row));
groupedRows.computeIfAbsent(key, ignored -> new ArrayList<>()).add(row);
}
List<SimilarAsinResultRowDto> representatives = new ArrayList<>(); List<SimilarAsinResultRowDto> representatives = new ArrayList<>();
for (List<SimilarAsinResultRowDto> siblings : groupedRows.values()) { for (SimilarAsinResultRowDto row : rows) {
boolean alreadyResolved = siblings.stream().anyMatch(this::hasResolvedCozeFields); if (row != null && !hasResolvedCozeFields(row) && shouldInspectRow(row)) {
if (alreadyResolved) { representatives.add(row);
continue;
}
SimilarAsinResultRowDto candidate = null;
for (SimilarAsinResultRowDto sibling : siblings) {
if (shouldInspectRow(sibling)) {
candidate = sibling;
break;
}
}
if (candidate != null) {
representatives.add(candidate);
} }
} }
return representatives; return representatives;
@@ -1004,6 +998,7 @@ public class SimilarAsinTaskService {
row.setId(sibling.getDisplayId()); row.setId(sibling.getDisplayId());
row.setAsin(sibling.getAsin()); row.setAsin(sibling.getAsin());
row.setCountry(sibling.getCountry()); row.setCountry(sibling.getCountry());
row.setPrice(firstNonBlank(representative.getPrice(), sibling.getPrice()));
if (representative.hasImageUrl()) { if (representative.hasImageUrl()) {
row.setUrls(representative.getUrls()); row.setUrls(representative.getUrls());
} else { } else {
@@ -1015,6 +1010,8 @@ public class SimilarAsinTaskService {
row.setAppearanceRisk(representative.getAppearanceRisk()); row.setAppearanceRisk(representative.getAppearanceRisk());
row.setPatentRisk(representative.getPatentRisk()); row.setPatentRisk(representative.getPatentRisk());
row.setConclusion(representative.getConclusion()); row.setConclusion(representative.getConclusion());
row.setIsStock(representative.getIsStock());
row.setSimilarity(representative.getSimilarity());
row.setTitleReason(representative.getTitleReason()); row.setTitleReason(representative.getTitleReason());
row.setAppearanceReason(representative.getAppearanceReason()); row.setAppearanceReason(representative.getAppearanceReason());
row.setPatentReason(representative.getPatentReason()); row.setPatentReason(representative.getPatentReason());
@@ -1030,6 +1027,14 @@ public class SimilarAsinTaskService {
} }
} }
private String readApiKey(FileTaskEntity task) {
try {
return normalize(readParsedPayload(task).getApiKey());
} catch (Exception ignored) {
return "";
}
}
private void finalizeTask(FileTaskEntity task, String error, int rowCount, boolean assembleWorkbook) { private void finalizeTask(FileTaskEntity task, String error, int rowCount, boolean assembleWorkbook) {
String finalError = error; String finalError = error;
FileResultEntity result = null; FileResultEntity result = null;
@@ -1068,7 +1073,7 @@ public class SimilarAsinTaskService {
} }
fileResultMapper.updateById(result); fileResultMapper.updateById(result);
if (!failed && assembleWorkbook) { if (!failed && assembleWorkbook) {
taskFileJobService.enqueueAssembleResult(task.getId(), MODULE_TYPE, result.getId(), "task:" + task.getId()); taskFileJobService.enqueueAssembleResult(task.getId(), MODULE_TYPE, result.getId(), buildTaskOwnerScopeKey(task));
} }
} }
taskCacheService.deleteTaskCache(task.getId()); taskCacheService.deleteTaskCache(task.getId());
@@ -1082,6 +1087,11 @@ public class SimilarAsinTaskService {
if (job == null || job.getTaskId() == null || job.getResultId() == null) { if (job == null || job.getTaskId() == null || job.getResultId() == null) {
throw new BusinessException("result file job arguments are incomplete"); throw new BusinessException("result file job arguments are incomplete");
} }
if (!isJobOwnedByCurrentInstance(job)) {
log.info("[similar-asin] skip result file job because owner is another instance jobId={} taskId={} owner={} current={}",
job.getId(), job.getTaskId(), ownerFromScopeKey(job.getScopeKey()), currentInstanceId());
return false;
}
FileTaskEntity task = fileTaskMapper.selectById(job.getTaskId()); FileTaskEntity task = fileTaskMapper.selectById(job.getTaskId());
if (task == null || !MODULE_TYPE.equals(task.getModuleType())) { if (task == null || !MODULE_TYPE.equals(task.getModuleType())) {
throw new BusinessException("task not found"); throw new BusinessException("task not found");
@@ -1128,7 +1138,7 @@ public class SimilarAsinTaskService {
} }
log.info("[similar-asin] coze poll picked pending states count={}", states.size()); log.info("[similar-asin] coze poll picked pending states count={}", states.size());
for (TaskScopeStateEntity state : states) { for (TaskScopeStateEntity state : states) {
if (state == null || state.getId() == null) { if (state == null || state.getId() == null || !isCozeStateOwnedByCurrentInstance(state)) {
continue; continue;
} }
cozeTaskExecutor.execute(() -> pollPendingCozeState(state.getId())); cozeTaskExecutor.execute(() -> pollPendingCozeState(state.getId()));
@@ -1150,6 +1160,7 @@ public class SimilarAsinTaskService {
return false; return false;
} }
String prompt = readAiPrompt(task); String prompt = readAiPrompt(task);
String apiKey = readApiKey(task);
int batchSize = Math.max(1, properties.getCozeBatchSize()); int batchSize = Math.max(1, properties.getCozeBatchSize());
boolean pending = false; boolean pending = false;
for (TaskChunkEntity chunk : chunks) { for (TaskChunkEntity chunk : chunks) {
@@ -1166,7 +1177,7 @@ public class SimilarAsinTaskService {
for (int i = 0; i < unresolvedRows.size(); i += batchSize) { for (int i = 0; i < unresolvedRows.size(); i += batchSize) {
List<SimilarAsinResultRowDto> batchRows = List<SimilarAsinResultRowDto> batchRows =
unresolvedRows.subList(i, Math.min(i + batchSize, unresolvedRows.size())); unresolvedRows.subList(i, Math.min(i + batchSize, unresolvedRows.size()));
pending |= submitCozeBatch(task, result, job, chunk, batchRows, batchIndex, batchTotal, prompt, allRowsByBaseId); pending |= submitCozeBatch(task, result, job, chunk, batchRows, batchIndex, batchTotal, prompt, apiKey, allRowsByBaseId);
batchIndex++; batchIndex++;
} }
} }
@@ -1181,6 +1192,7 @@ public class SimilarAsinTaskService {
int batchIndex, int batchIndex,
int batchTotal, int batchTotal,
String prompt, String prompt,
String apiKey,
Map<String, List<SimilarAsinParsedRowVo>> allRowsByBaseId) { Map<String, List<SimilarAsinParsedRowVo>> allRowsByBaseId) {
if (batchRows == null || batchRows.isEmpty()) { if (batchRows == null || batchRows.isEmpty()) {
return false; return false;
@@ -1197,7 +1209,7 @@ public class SimilarAsinTaskService {
|| COZE_STATUS_RUNNING.equals(existing.getCozeStatus()); || COZE_STATUS_RUNNING.equals(existing.getCozeStatus());
} }
try { try {
SimilarAsinCozeClient.CozeSubmitResponse submit = cozeClient.submitWorkflow(batchRows, prompt); SimilarAsinCozeClient.CozeSubmitResponse submit = cozeClient.submitWorkflow(batchRows, prompt, apiKey);
if (submit.immediateData() != null && !submit.immediateData().isBlank()) { if (submit.immediateData() != null && !submit.immediateData().isBlank()) {
List<SimilarAsinResultRowDto> cozeRows = cozeClient.mergeRowsFromDataText(batchRows, submit.immediateData()); List<SimilarAsinResultRowDto> cozeRows = cozeClient.mergeRowsFromDataText(batchRows, submit.immediateData());
mergeCozeRowsIntoChunk(task, chunk.getScopeHash(), chunk.getChunkIndex(), cozeRows, allRowsByBaseId); mergeCozeRowsIntoChunk(task, chunk.getScopeHash(), chunk.getChunkIndex(), cozeRows, allRowsByBaseId);
@@ -1246,7 +1258,8 @@ public class SimilarAsinTaskService {
chunk.getScopeHash(), chunk.getScopeHash(),
chunk.getChunkIndex(), chunk.getChunkIndex(),
batchIndex, batchIndex,
batchTotal batchTotal,
currentInstanceId()
); );
String batchPayload = writeJson(batchRows, "serialize coze batch payload failed"); String batchPayload = writeJson(batchRows, "serialize coze batch payload failed");
String storedBatchPayload = transientPayloadStorageService.storeParsedPayloadFast( String storedBatchPayload = transientPayloadStorageService.storeParsedPayloadFast(
@@ -1278,6 +1291,25 @@ public class SimilarAsinTaskService {
} }
private void pollPendingCozeState(Long stateId) { private void pollPendingCozeState(Long stateId) {
TaskScopeStateEntity lockState = taskScopeStateMapper.selectById(stateId);
if (lockState == null || lockState.getCozeExecuteId() == null || lockState.getCozeExecuteId().isBlank()) {
return;
}
if (!isCozeStateOwnedByCurrentInstance(lockState)) {
log.info("[similar-asin] coze poll skipped because owner is another instance taskId={} stateId={} owner={} current={}",
lockState.getTaskId(), stateId, ownerFromCozeState(lockState), currentInstanceId());
return;
}
TaskDistributedLockService.LockHandle taskLockHandle = acquireTaskLock(lockState.getTaskId(), 0L);
if (taskLockHandle == null) {
return;
}
try (taskLockHandle) {
pollPendingCozeStateLocked(stateId);
}
}
private void pollPendingCozeStateLocked(Long stateId) {
TaskScopeStateEntity state = taskScopeStateMapper.selectById(stateId); TaskScopeStateEntity state = taskScopeStateMapper.selectById(stateId);
if (state == null || state.getCozeExecuteId() == null || state.getCozeExecuteId().isBlank()) { if (state == null || state.getCozeExecuteId() == null || state.getCozeExecuteId().isBlank()) {
return; return;
@@ -1285,16 +1317,7 @@ public class SimilarAsinTaskService {
if (!(COZE_STATUS_SUBMITTED.equals(state.getCozeStatus()) || COZE_STATUS_RUNNING.equals(state.getCozeStatus()))) { if (!(COZE_STATUS_SUBMITTED.equals(state.getCozeStatus()) || COZE_STATUS_RUNNING.equals(state.getCozeStatus()))) {
return; return;
} }
TaskDistributedLockService.LockHandle taskLockHandle = acquireTaskLock(state.getTaskId(), 0L); if (!isCozeStateOwnedByCurrentInstance(state)) {
if (taskLockHandle == null) {
return;
}
try (taskLockHandle) {
state = taskScopeStateMapper.selectById(stateId);
if (state == null || state.getCozeExecuteId() == null || state.getCozeExecuteId().isBlank()) {
return;
}
if (!(COZE_STATUS_SUBMITTED.equals(state.getCozeStatus()) || COZE_STATUS_RUNNING.equals(state.getCozeStatus()))) {
return; return;
} }
if (!tryClaimCozeStateForPoll(state)) { if (!tryClaimCozeStateForPoll(state)) {
@@ -1305,6 +1328,11 @@ public class SimilarAsinTaskService {
markCozeStateTerminal(state, COZE_STATUS_FAILED, "Coze batch context missing"); markCozeStateTerminal(state, COZE_STATUS_FAILED, "Coze batch context missing");
return; return;
} }
if (!isOwnerCurrent(context.ownerInstanceId())) {
log.info("[similar-asin] coze poll skipped after context refresh because owner is another instance taskId={} stateId={} owner={} current={}",
state.getTaskId(), state.getId(), context.ownerInstanceId(), currentInstanceId());
return;
}
taskFileJobService.touchRunning(context.jobId()); taskFileJobService.touchRunning(context.jobId());
try { try {
SimilarAsinCozeClient.CozePollResponse poll = cozeClient.pollWorkflow(state.getCozeExecuteId()); SimilarAsinCozeClient.CozePollResponse poll = cozeClient.pollWorkflow(state.getCozeExecuteId());
@@ -1321,6 +1349,9 @@ public class SimilarAsinTaskService {
: "Coze async workflow completed without output"; : "Coze async workflow completed without output";
} }
List<SimilarAsinResultRowDto> batchRows = readCozeBatchRows(state); List<SimilarAsinResultRowDto> batchRows = readCozeBatchRows(state);
if (batchRows.isEmpty() && failureMessage.isBlank()) {
failureMessage = "Coze batch payload missing";
}
List<SimilarAsinResultRowDto> cozeRows = failureMessage.isBlank() List<SimilarAsinResultRowDto> cozeRows = failureMessage.isBlank()
? cozeClient.mergeRowsFromDataText(batchRows, poll.resolvedPayloadText()) ? cozeClient.mergeRowsFromDataText(batchRows, poll.resolvedPayloadText())
: cozeClient.markRowsFailed(batchRows, failureMessage); : cozeClient.markRowsFailed(batchRows, failureMessage);
@@ -1354,7 +1385,6 @@ public class SimilarAsinTaskService {
state.getTaskId(), state.getId(), state.getCozeExecuteId(), message); state.getTaskId(), state.getId(), state.getCozeExecuteId(), message);
updateCozeStateRunning(state, message); updateCozeStateRunning(state, message);
} }
}
} }
private void updateCozeStateRunning(TaskScopeStateEntity state, String error) { private void updateCozeStateRunning(TaskScopeStateEntity state, String error) {
@@ -1410,6 +1440,9 @@ public class SimilarAsinTaskService {
if (taskId == null || context == null || countPendingCozeStates(taskId) > 0) { if (taskId == null || context == null || countPendingCozeStates(taskId) > 0) {
return; return;
} }
if (!isOwnerCurrent(context.ownerInstanceId())) {
return;
}
TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(taskId, 0L); TaskDistributedLockService.LockHandle lockHandle = acquireTaskLock(taskId, 0L);
if (lockHandle == null) { if (lockHandle == null) {
return; return;
@@ -1442,7 +1475,7 @@ public class SimilarAsinTaskService {
} }
private TaskDistributedLockService.LockHandle acquireTaskLock(Long taskId, long waitMillis) { private TaskDistributedLockService.LockHandle acquireTaskLock(Long taskId, long waitMillis) {
TaskDistributedLockService.LockHandle lockHandle = taskDistributedLockService.acquire(MODULE_TYPE, taskId, waitMillis); TaskDistributedLockService.LockHandle lockHandle = taskDistributedLockService.acquire(MODULE_TYPE, taskId, TASK_LOCK_TTL, waitMillis);
if (lockHandle == null) { if (lockHandle == null) {
log.info("[similar-asin] skip task operation because task lock is busy taskId={}", taskId); log.info("[similar-asin] skip task operation because task lock is busy taskId={}", taskId);
} }
@@ -1454,6 +1487,9 @@ public class SimilarAsinTaskService {
TaskFileJobEntity job, TaskFileJobEntity job,
int totalProgressUnits, int totalProgressUnits,
int cozeWorkUnits) { int cozeWorkUnits) {
if (countPendingCozeStates(task.getId()) > 0) {
throw new BusinessException("Coze result is still processing, cannot generate result file yet");
}
int assembleProgress = Math.max(1, Math.min(totalProgressUnits - 2, cozeWorkUnits)); int assembleProgress = Math.max(1, Math.min(totalProgressUnits - 2, cozeWorkUnits));
saveFileBuildProgress(task, job, totalProgressUnits, assembleProgress, "Assembling xlsx"); saveFileBuildProgress(task, job, totalProgressUnits, assembleProgress, "Assembling xlsx");
assembleResultWorkbook(task, result); assembleResultWorkbook(task, result);
@@ -1572,6 +1608,69 @@ public class SimilarAsinTaskService {
+ ":batch:" + batchIndex; + ":batch:" + batchIndex;
} }
private String buildTaskOwnerScopeKey(FileTaskEntity task) {
Long taskId = task == null ? null : task.getId();
return "task:" + taskId + ":owner:" + firstNonBlank(ownerFromTask(task), currentInstanceId());
}
private String currentInstanceId() {
String instanceId = instanceMetadata == null ? null : instanceMetadata.getInstanceId();
return firstNonBlank(instanceId, "unknown-instance");
}
private boolean isJobOwnedByCurrentInstance(TaskFileJobEntity job) {
return job == null || isOwnerCurrent(ownerFromScopeKey(job.getScopeKey()));
}
private void ensureTaskOwnedByCurrentInstance(FileTaskEntity task, String operation) {
String owner = ownerFromTask(task);
if (isOwnerCurrent(owner)) {
return;
}
log.warn("[similar-asin] reject task operation because owner is another instance taskId={} operation={} owner={} current={}",
task == null ? null : task.getId(), operation, owner, currentInstanceId());
throw new BusinessException(40903, "This task is bound to another service instance");
}
private boolean isCozeStateOwnedByCurrentInstance(TaskScopeStateEntity state) {
return state == null || isOwnerCurrent(ownerFromCozeState(state));
}
private boolean isOwnerCurrent(String owner) {
return owner == null || owner.isBlank() || Objects.equals(owner, currentInstanceId());
}
private String ownerFromCozeState(TaskScopeStateEntity state) {
CozeBatchContext context = readCozeBatchContext(state);
return context == null ? null : context.ownerInstanceId();
}
private String ownerFromTask(FileTaskEntity task) {
if (task == null || task.getResultJson() == null || task.getResultJson().isBlank()) {
return null;
}
try {
String owner = objectMapper.readTree(task.getResultJson()).path("ownerInstanceId").asText("");
return owner.isBlank() ? null : owner;
} catch (Exception ex) {
log.warn("[similar-asin] read task owner failed taskId={} err={}", task.getId(), ex.getMessage());
return null;
}
}
private String ownerFromScopeKey(String scopeKey) {
if (scopeKey == null || scopeKey.isBlank()) {
return null;
}
String marker = ":owner:";
int index = scopeKey.lastIndexOf(marker);
if (index < 0) {
return null;
}
String owner = scopeKey.substring(index + marker.length()).trim();
return owner.isBlank() ? null : owner;
}
private int countCozeWorkUnits(List<TaskChunkEntity> chunks, int batchSize) { private int countCozeWorkUnits(List<TaskChunkEntity> chunks, int batchSize) {
if (chunks == null || chunks.isEmpty()) { if (chunks == null || chunks.isEmpty()) {
return 0; return 0;
@@ -1632,11 +1731,8 @@ public class SimilarAsinTaskService {
long resolvedRows = parsed.getAllItems().stream() long resolvedRows = parsed.getAllItems().stream()
.filter(row -> findResultRow(row, resultMap) != null || findResultRowByAsin(row.getAsin(), resultMap) != null) .filter(row -> findResultRow(row, resultMap) != null || findResultRowByAsin(row.getAsin(), resultMap) != null)
.count(); .count();
long reasonRows = resultMap.values().stream() log.info("[similar-asin] assemble workbook taskId={} parsedRows={} resultRows={} resolvedRows={}",
.filter(this::hasReasonFields) task.getId(), parsed.getAllItems().size(), resultMap.size(), resolvedRows);
.count();
log.info("[similar-asin] assemble workbook taskId={} parsedRows={} resultRows={} resolvedRows={} reasonRows={}",
task.getId(), parsed.getAllItems().size(), resultMap.size(), resolvedRows, reasonRows);
if (!parsed.getAllItems().isEmpty() && resultMap.isEmpty()) { if (!parsed.getAllItems().isEmpty() && resultMap.isEmpty()) {
throw new BusinessException("相似ASIN检测结果为空请稍后重试生成结果文件"); throw new BusinessException("相似ASIN检测结果为空请稍后重试生成结果文件");
} }
@@ -1707,15 +1803,13 @@ public class SimilarAsinTaskService {
private void writeResultWorkbook(File xlsx, SimilarAsinParsedPayloadDto parsed, Map<String, SimilarAsinResultRowDto> resultMap) { private void writeResultWorkbook(File xlsx, SimilarAsinParsedPayloadDto parsed, Map<String, SimilarAsinResultRowDto> resultMap) {
try (SXSSFWorkbook workbook = new SXSSFWorkbook(200); FileOutputStream fos = new FileOutputStream(xlsx)) { try (SXSSFWorkbook workbook = new SXSSFWorkbook(200); FileOutputStream fos = new FileOutputStream(xlsx)) {
Sheet sheet = workbook.createSheet("相似ASIN检测结果"); Sheet sheet = workbook.createSheet("相似asin检测");
CellStyle headerStyle = workbook.createCellStyle(); CellStyle headerStyle = workbook.createCellStyle();
Font font = workbook.createFont(); Font font = workbook.createFont();
font.setBold(true); font.setBold(true);
headerStyle.setFont(font); headerStyle.setFont(font);
List<String> resultHeaders = new ArrayList<>(RESULT_HEADERS); List<String> resultHeaders = new ArrayList<>(RESULT_HEADERS);
resultHeaders.add(4, "标题");
resultHeaders.add(5, "图片链接");
Row header = sheet.createRow(0); Row header = sheet.createRow(0);
for (int i = 0; i < resultHeaders.size(); i++) { for (int i = 0; i < resultHeaders.size(); i++) {
Cell cell = header.createCell(i); Cell cell = header.createCell(i);
@@ -1729,24 +1823,17 @@ public class SimilarAsinTaskService {
if (resultRow == null) { if (resultRow == null) {
resultRow = findResultRowByAsin(parsedRow.getAsin(), resultMap); resultRow = findResultRowByAsin(parsedRow.getAsin(), resultMap);
} }
String missingReason = "";
if (resultRow == null) {
missingReason = hasPromptFields(parsedRow) ? "未匹配到检测结果" : "未送检:缺少标题或图片";
}
Row row = sheet.createRow(rowIndex++); Row row = sheet.createRow(rowIndex++);
int col = 0; int col = 0;
row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getDisplayId(), parsedRow.getSourceId())); row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getDisplayId(), parsedRow.getSourceId()));
row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getAsin(), "")); row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getAsin(), ""));
row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getCountry(), "")); row.createCell(col++).setCellValue(firstNonBlank(parsedRow.getCountry(), ""));
row.createCell(col++).setCellValue(readValueByHeader(parsedRow, "价格", "price")); row.createCell(col++).setCellValue(resultRow == null
row.createCell(col++).setCellValue(resultRow == null ? firstNonBlank(parsedRow.getTitle(), "") : firstNonBlank(resultRow.getTitle(), parsedRow.getTitle())); ? firstNonBlank(parsedRow.getPrice(), readValueByHeader(parsedRow, "价格", "price"))
row.createCell(col++).setCellValue(resultRow == null ? firstNonBlank(parsedRow.getUrl(), "") : imageUrlCellValue(resultRow, parsedRow.getUrl())); : firstNonBlank(resultRow.getPrice(), firstNonBlank(parsedRow.getPrice(), readValueByHeader(parsedRow, "价格", "price"))));
row.createCell(col++).setCellValue(resultRow == null ? missingReason : userFacingCozeCellValue(resultRow, resultRow.getTitleRisk())); row.createCell(col++).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getIsStock(), ""));
row.createCell(col++).setCellValue(resultRow == null ? missingReason : userFacingCozeCellValue(resultRow, resultRow.getAppearanceRisk())); row.createCell(col).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getSimilarity(), ""));
row.createCell(col++).setCellValue(resultRow == null ? missingReason : userFacingCozeCellValue(resultRow, resultRow.getPatentRisk()));
row.createCell(col).setCellValue(resultRow == null ? "未送检" : userFacingConclusion(resultRow));
} }
writeReasonSheet(workbook, headerStyle, parsed, resultMap);
workbook.write(fos); workbook.write(fos);
workbook.dispose(); workbook.dispose();
} catch (Exception ex) { } catch (Exception ex) {
@@ -1754,39 +1841,6 @@ public class SimilarAsinTaskService {
} }
} }
private void writeReasonSheet(SXSSFWorkbook workbook,
CellStyle headerStyle,
SimilarAsinParsedPayloadDto parsed,
Map<String, SimilarAsinResultRowDto> resultMap) {
Sheet sheet = workbook.createSheet("原因");
Row header = sheet.createRow(0);
List<String> headers = List.of("ASIN", "外观原因", "专利原因", "标题原因");
for (int i = 0; i < headers.size(); i++) {
Cell cell = header.createCell(i);
cell.setCellValue(headers.get(i));
cell.setCellStyle(headerStyle);
}
Set<String> writtenAsins = new LinkedHashSet<>();
int rowIndex = 1;
for (SimilarAsinParsedRowVo parsedRow : parsed.getAllItems()) {
String asin = normalize(parsedRow.getAsin()).toUpperCase(Locale.ROOT);
if (asin.isBlank() || !writtenAsins.add(asin)) {
continue;
}
SimilarAsinResultRowDto resultRow = findResultRow(parsedRow, resultMap);
if (resultRow == null) {
resultRow = findResultRowByAsin(asin, resultMap);
}
Row row = sheet.createRow(rowIndex++);
row.createCell(0).setCellValue(asin);
row.createCell(1).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getAppearanceReason(), ""));
row.createCell(2).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getPatentReason(), ""));
row.createCell(3).setCellValue(resultRow == null ? "" : firstNonBlank(resultRow.getTitleReason(), ""));
rowIndex++;
}
}
private SimilarAsinResultRowDto findResultRowByAsin(String asin, Map<String, SimilarAsinResultRowDto> resultMap) { private SimilarAsinResultRowDto findResultRowByAsin(String asin, Map<String, SimilarAsinResultRowDto> resultMap) {
String normalizedAsin = normalize(asin).toUpperCase(Locale.ROOT); String normalizedAsin = normalize(asin).toUpperCase(Locale.ROOT);
if (normalizedAsin.isBlank() || resultMap == null || resultMap.isEmpty()) { if (normalizedAsin.isBlank() || resultMap == null || resultMap.isEmpty()) {
@@ -1797,7 +1851,7 @@ public class SimilarAsinTaskService {
if (row == null || !normalizedAsin.equals(normalize(row.getAsin()).toUpperCase(Locale.ROOT))) { if (row == null || !normalizedAsin.equals(normalize(row.getAsin()).toUpperCase(Locale.ROOT))) {
continue; continue;
} }
if (hasResolvedCozeFields(row) || hasReasonFields(row)) { if (hasResolvedCozeFields(row)) {
return row; return row;
} }
if (fallback == null) { if (fallback == null) {
@@ -1807,15 +1861,6 @@ public class SimilarAsinTaskService {
return fallback; return fallback;
} }
private boolean hasReasonFields(SimilarAsinResultRowDto row) {
if (row == null) {
return false;
}
return !normalize(row.getAppearanceReason()).isBlank()
|| !normalize(row.getPatentReason()).isBlank()
|| !normalize(row.getTitleReason()).isBlank();
}
private String imageUrlCellValue(SimilarAsinResultRowDto resultRow, String fallbackUrl) { private String imageUrlCellValue(SimilarAsinResultRowDto resultRow, String fallbackUrl) {
if (resultRow == null) { if (resultRow == null) {
return firstNonBlank(fallbackUrl, ""); return firstNonBlank(fallbackUrl, "");
@@ -1840,6 +1885,7 @@ public class SimilarAsinTaskService {
int idCol = findRequiredHeader(headerMap, "id"); int idCol = findRequiredHeader(headerMap, "id");
int asinCol = findRequiredHeader(headerMap, "asin"); int asinCol = findRequiredHeader(headerMap, "asin");
int countryCol = findRequiredHeader(headerMap, "国家", "country"); int countryCol = findRequiredHeader(headerMap, "国家", "country");
int priceCol = findOptionalHeaderExact(headerMap, "价格", "price");
int urlCol = findOptionalHeaderExact(headerMap, int urlCol = findOptionalHeaderExact(headerMap,
"url", "rul", "link", "image", "img", "pic", "picture", "url", "rul", "link", "image", "img", "pic", "picture",
"链接", "商品链接", "图片", "商品图片", "主图", "商品主图", "图片链接", "主图链接"); "链接", "商品链接", "图片", "商品图片", "主图", "商品主图", "图片链接", "主图链接");
@@ -1882,6 +1928,7 @@ public class SimilarAsinTaskService {
vo.setRowToken(buildRowToken(source.getFileKey(), vo.getRowIndex())); vo.setRowToken(buildRowToken(source.getFileKey(), vo.getRowIndex()));
vo.setAsin(asin); vo.setAsin(asin);
vo.setCountry(country); vo.setCountry(country);
vo.setPrice(priceCol >= 0 ? cell(row, priceCol, formatter) : "");
vo.setUrl(urlCol >= 0 ? cell(row, urlCol, formatter) : ""); vo.setUrl(urlCol >= 0 ? cell(row, urlCol, formatter) : "");
vo.setTitle(titleCol >= 0 ? cell(row, titleCol, formatter) : ""); vo.setTitle(titleCol >= 0 ? cell(row, titleCol, formatter) : "");
vo.setValues(readRowValues(row, headers, formatter)); vo.setValues(readRowValues(row, headers, formatter));
@@ -1938,7 +1985,9 @@ public class SimilarAsinTaskService {
return hasUsableCozeField(row.getTitleRisk()) return hasUsableCozeField(row.getTitleRisk())
|| hasUsableCozeField(row.getAppearanceRisk()) || hasUsableCozeField(row.getAppearanceRisk())
|| hasUsableCozeField(row.getPatentRisk()) || hasUsableCozeField(row.getPatentRisk())
|| hasUsableCozeField(row.getConclusion()); || hasUsableCozeField(row.getConclusion())
|| hasUsableCozeField(row.getIsStock())
|| hasUsableCozeField(row.getSimilarity());
} }
private boolean hasUsableCozeField(String value) { private boolean hasUsableCozeField(String value) {
@@ -2183,9 +2232,10 @@ public class SimilarAsinTaskService {
return val == null ? "" : val.replace(String.valueOf((char) 0xFEFF), "").replace((char) 0x3000, ' ').trim().replaceAll("\\s+", " "); return val == null ? "" : val.replace(String.valueOf((char) 0xFEFF), "").replace((char) 0x3000, ' ').trim().replaceAll("\\s+", " ");
} }
private String buildParsedPayloadJson(String aiPrompt, List<SimilarAsinSourceFileDto> sourceFiles, List<String> headers, List<SimilarAsinParsedGroupVo> groups, List<SimilarAsinParsedRowVo> allRows) { private String buildParsedPayloadJson(String aiPrompt, String apiKey, List<SimilarAsinSourceFileDto> sourceFiles, List<String> headers, List<SimilarAsinParsedGroupVo> groups, List<SimilarAsinParsedRowVo> allRows) {
SimilarAsinParsedPayloadDto payload = new SimilarAsinParsedPayloadDto(); SimilarAsinParsedPayloadDto payload = new SimilarAsinParsedPayloadDto();
payload.setAiPrompt(normalize(aiPrompt)); payload.setAiPrompt(normalize(aiPrompt));
payload.setApiKey(normalize(apiKey));
payload.setSourceFiles(sourceFiles == null ? List.of() : sourceFiles); payload.setSourceFiles(sourceFiles == null ? List.of() : sourceFiles);
payload.setHeaders(headers == null ? List.of() : headers); payload.setHeaders(headers == null ? List.of() : headers);
payload.setItems(List.of()); payload.setItems(List.of());
@@ -2194,14 +2244,16 @@ public class SimilarAsinTaskService {
return writeJson(payload, "保存解析结果失败"); return writeJson(payload, "保存解析结果失败");
} }
private String buildTaskResultJson(String aiPrompt, List<SimilarAsinSourceFileDto> sourceFiles, String parsedPayloadPointer) { private String buildTaskResultJson(String aiPrompt, String apiKey, List<SimilarAsinSourceFileDto> sourceFiles, String parsedPayloadPointer) {
Map<String, Object> payload = new LinkedHashMap<>(); Map<String, Object> payload = new LinkedHashMap<>();
payload.put("aiPrompt", normalize(aiPrompt)); payload.put("aiPrompt", normalize(aiPrompt));
payload.put("apiKey", normalize(apiKey));
payload.put("sourceFileKeys", sourceFiles == null ? List.of() : sourceFiles.stream() payload.put("sourceFileKeys", sourceFiles == null ? List.of() : sourceFiles.stream()
.map(SimilarAsinSourceFileDto::getFileKey) .map(SimilarAsinSourceFileDto::getFileKey)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.toList()); .toList());
payload.put("parsedPayloadRef", parsedPayloadPointer); payload.put("parsedPayloadRef", parsedPayloadPointer);
payload.put("ownerInstanceId", currentInstanceId());
return writeJson(payload, "保存任务结果索引失败"); return writeJson(payload, "保存任务结果索引失败");
} }
@@ -2435,11 +2487,12 @@ public class SimilarAsinTaskService {
} }
private record CozeBatchContext(Long jobId, private record CozeBatchContext(Long jobId,
Long resultId, Long resultId,
String chunkScopeHash, String chunkScopeHash,
Integer chunkIndex, Integer chunkIndex,
Integer batchIndex, Integer batchIndex,
Integer batchTotal) { Integer batchTotal,
String ownerInstanceId) {
} }
private record ParsedWorkbook(int totalRows, int droppedRows, List<String> headers, List<SimilarAsinParsedRowVo> allRows) { private record ParsedWorkbook(int totalRows, int droppedRows, List<String> headers, List<SimilarAsinParsedRowVo> allRows) {

View File

@@ -33,9 +33,12 @@ public class TaskFileJobDispatchCoordinator {
if (published) { if (published) {
return; return;
} }
boolean dispatched = taskFileJobLocalDispatcher.dispatch(event.jobId(), event.taskId(), event.moduleType()); boolean dispatched = taskFileJobLocalDispatcher.dispatch(event.jobId(), event.taskId(), event.moduleType(), true);
if (dispatched) { if (dispatched) {
log.info("[task-file-job] local async dispatch scheduled jobId={} taskId={} moduleType={}", log.info("[task-file-job] forced local async dispatch scheduled jobId={} taskId={} moduleType={}",
event.jobId(), event.taskId(), event.moduleType());
} else {
log.warn("[task-file-job] local dispatch unavailable after mq publish fallback jobId={} taskId={} moduleType={}",
event.jobId(), event.taskId(), event.moduleType()); event.jobId(), event.taskId(), event.moduleType());
} }
} }

View File

@@ -27,35 +27,50 @@ public class TaskFileJobLocalDispatcher {
private boolean localDispatchEnabled; private boolean localDispatchEnabled;
public boolean dispatch(Long jobId, Long taskId, String moduleType) { public boolean dispatch(Long jobId, Long taskId, String moduleType) {
if (!localDispatchEnabled || jobId == null || jobId <= 0) { return dispatch(jobId, taskId, moduleType, false);
}
public boolean dispatch(Long jobId, Long taskId, String moduleType, boolean force) {
if (jobId == null || jobId <= 0) {
return false;
}
if (!force && !localDispatchEnabled) {
log.info("[task-file-job] local dispatch disabled jobId={} taskId={} moduleType={}",
jobId, taskId, moduleType);
return false; return false;
} }
try { try {
taskFileJobDispatchExecutor.execute(() -> { taskFileJobDispatchExecutor.execute(() -> processLocally(jobId, taskId, moduleType));
try {
TaskFileJobEntity job = taskFileJobMapper.selectById(jobId);
if (job == null) {
log.warn("[task-file-job] local dispatch ignored, job not found jobId={} taskId={} moduleType={}",
jobId, taskId, moduleType);
return;
}
TaskResultFileJobWorker taskResultFileJobWorker = taskResultFileJobWorkerProvider.getIfAvailable();
if (taskResultFileJobWorker == null) {
log.warn("[task-file-job] local dispatch ignored, worker unavailable jobId={} taskId={} moduleType={}",
jobId, taskId, moduleType);
return;
}
taskResultFileJobWorker.process(job);
} catch (Exception ex) {
log.warn("[task-file-job] local dispatch failed jobId={} taskId={} moduleType={} msg={}",
jobId, taskId, moduleType, ex.getMessage(), ex);
}
});
return true; return true;
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
log.warn("[task-file-job] local dispatch executor rejected jobId={} taskId={} moduleType={} msg={}", log.warn("[task-file-job] local dispatch executor rejected jobId={} taskId={} moduleType={} msg={}",
jobId, taskId, moduleType, ex.getMessage(), ex); jobId, taskId, moduleType, ex.getMessage(), ex);
if (force) {
processLocally(jobId, taskId, moduleType);
return true;
}
return false; return false;
} }
} }
private void processLocally(Long jobId, Long taskId, String moduleType) {
try {
TaskFileJobEntity job = taskFileJobMapper.selectById(jobId);
if (job == null) {
log.warn("[task-file-job] local dispatch ignored, job not found jobId={} taskId={} moduleType={}",
jobId, taskId, moduleType);
return;
}
TaskResultFileJobWorker taskResultFileJobWorker = taskResultFileJobWorkerProvider.getIfAvailable();
if (taskResultFileJobWorker == null) {
log.warn("[task-file-job] local dispatch ignored, worker unavailable jobId={} taskId={} moduleType={}",
jobId, taskId, moduleType);
return;
}
taskResultFileJobWorker.process(job);
} catch (Exception ex) {
log.warn("[task-file-job] local dispatch failed jobId={} taskId={} moduleType={} msg={}",
jobId, taskId, moduleType, ex.getMessage(), ex);
}
}
} }

View File

@@ -1,6 +1,7 @@
package com.nanri.aiimage.modules.task.service; package com.nanri.aiimage.modules.task.service;
import com.nanri.aiimage.modules.appearancepatent.service.AppearancePatentTaskService; import com.nanri.aiimage.modules.appearancepatent.service.AppearancePatentTaskService;
import com.nanri.aiimage.config.InstanceMetadata;
import com.nanri.aiimage.modules.brand.service.BrandTaskService; import com.nanri.aiimage.modules.brand.service.BrandTaskService;
import com.nanri.aiimage.modules.deletebrand.service.DeleteBrandRunService; import com.nanri.aiimage.modules.deletebrand.service.DeleteBrandRunService;
import com.nanri.aiimage.modules.patroldelete.service.PatrolDeleteTaskService; import com.nanri.aiimage.modules.patroldelete.service.PatrolDeleteTaskService;
@@ -33,6 +34,7 @@ public class TaskResultFileJobWorker {
private final TaskResultPayloadService taskResultPayloadService; private final TaskResultPayloadService taskResultPayloadService;
private final FileResultMapper fileResultMapper; private final FileResultMapper fileResultMapper;
private final TaskFileJobLocalDispatcher taskFileJobLocalDispatcher; private final TaskFileJobLocalDispatcher taskFileJobLocalDispatcher;
private final InstanceMetadata instanceMetadata;
private final ShopMatchTaskService shopMatchTaskService; private final ShopMatchTaskService shopMatchTaskService;
private final PriceTrackTaskService priceTrackTaskService; private final PriceTrackTaskService priceTrackTaskService;
private final ProductRiskTaskService productRiskTaskService; private final ProductRiskTaskService productRiskTaskService;
@@ -86,6 +88,11 @@ public class TaskResultFileJobWorker {
} }
public void process(TaskFileJobEntity job) { public void process(TaskFileJobEntity job) {
if (isOwnerScopedCozeJob(job) && !isOwnedByCurrentInstance(job)) {
log.info("[task-file-job] skip owner-scoped job because owner is another instance jobId={} taskId={} moduleType={} owner={} current={}",
job.getId(), job.getTaskId(), job.getModuleType(), ownerFromScopeKey(job.getScopeKey()), currentInstanceId());
return;
}
if (job == null || job.getId() == null || !taskFileJobService.markRunning(job.getId())) { if (job == null || job.getId() == null || !taskFileJobService.markRunning(job.getId())) {
return; return;
} }
@@ -147,6 +154,36 @@ public class TaskResultFileJobWorker {
return result == null ? null : result.getResultFileUrl(); return result == null ? null : result.getResultFileUrl();
} }
private boolean isOwnerScopedCozeJob(TaskFileJobEntity job) {
if (job == null || job.getModuleType() == null) {
return false;
}
return "APPEARANCE_PATENT".equals(job.getModuleType()) || "SIMILAR_ASIN".equals(job.getModuleType());
}
private boolean isOwnedByCurrentInstance(TaskFileJobEntity job) {
String owner = ownerFromScopeKey(job == null ? null : job.getScopeKey());
return owner == null || owner.isBlank() || owner.equals(currentInstanceId());
}
private String currentInstanceId() {
String instanceId = instanceMetadata == null ? null : instanceMetadata.getInstanceId();
return instanceId == null || instanceId.isBlank() ? "unknown-instance" : instanceId;
}
private String ownerFromScopeKey(String scopeKey) {
if (scopeKey == null || scopeKey.isBlank()) {
return null;
}
String marker = ":owner:";
int index = scopeKey.lastIndexOf(marker);
if (index < 0) {
return null;
}
String owner = scopeKey.substring(index + marker.length()).trim();
return owner.isBlank() ? null : owner;
}
private boolean dispatch(TaskFileJobEntity job) { private boolean dispatch(TaskFileJobEntity job) {
String moduleType = job.getModuleType(); String moduleType = job.getModuleType();
if ("SHOP_MATCH".equals(moduleType)) { if ("SHOP_MATCH".equals(moduleType)) {

View File

@@ -150,6 +150,8 @@ aiimage:
coze-batch-size: ${AIIMAGE_APPEARANCE_PATENT_COZE_BATCH_SIZE:10} coze-batch-size: ${AIIMAGE_APPEARANCE_PATENT_COZE_BATCH_SIZE:10}
coze-connect-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_CONNECT_TIMEOUT_MILLIS:10000} coze-connect-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_CONNECT_TIMEOUT_MILLIS:10000}
coze-read-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_READ_TIMEOUT_MILLIS:60000} coze-read-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_READ_TIMEOUT_MILLIS:60000}
coze-poll-interval-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_POLL_INTERVAL_MILLIS:5000}
coze-poll-timeout-millis: ${AIIMAGE_APPEARANCE_PATENT_COZE_POLL_TIMEOUT_MILLIS:600000}
stale-timeout-minutes: ${AIIMAGE_APPEARANCE_PATENT_STALE_TIMEOUT_MINUTES:20} stale-timeout-minutes: ${AIIMAGE_APPEARANCE_PATENT_STALE_TIMEOUT_MINUTES:20}
stale-finalize-cron: ${AIIMAGE_APPEARANCE_PATENT_STALE_FINALIZE_CRON:0 */2 * * * *} stale-finalize-cron: ${AIIMAGE_APPEARANCE_PATENT_STALE_FINALIZE_CRON:0 */2 * * * *}
similar-asin: similar-asin:
@@ -160,6 +162,8 @@ aiimage:
coze-batch-size: ${AIIMAGE_SIMILAR_ASIN_COZE_BATCH_SIZE:10} coze-batch-size: ${AIIMAGE_SIMILAR_ASIN_COZE_BATCH_SIZE:10}
coze-connect-timeout-millis: ${AIIMAGE_SIMILAR_ASIN_COZE_CONNECT_TIMEOUT_MILLIS:10000} coze-connect-timeout-millis: ${AIIMAGE_SIMILAR_ASIN_COZE_CONNECT_TIMEOUT_MILLIS:10000}
coze-read-timeout-millis: ${AIIMAGE_SIMILAR_ASIN_COZE_READ_TIMEOUT_MILLIS:60000} coze-read-timeout-millis: ${AIIMAGE_SIMILAR_ASIN_COZE_READ_TIMEOUT_MILLIS:60000}
coze-poll-interval-millis: ${AIIMAGE_SIMILAR_ASIN_COZE_POLL_INTERVAL_MILLIS:5000}
coze-poll-timeout-millis: ${AIIMAGE_SIMILAR_ASIN_COZE_POLL_TIMEOUT_MILLIS:600000}
stale-timeout-minutes: ${AIIMAGE_SIMILAR_ASIN_STALE_TIMEOUT_MINUTES:20} stale-timeout-minutes: ${AIIMAGE_SIMILAR_ASIN_STALE_TIMEOUT_MINUTES:20}
stale-finalize-cron: ${AIIMAGE_SIMILAR_ASIN_STALE_FINALIZE_CRON:0 */2 * * * *} stale-finalize-cron: ${AIIMAGE_SIMILAR_ASIN_STALE_FINALIZE_CRON:0 */2 * * * *}
security: security:

View File

@@ -24,6 +24,11 @@
<div class="prompt-preview">{{ defaultAiPrompt }}</div> <div class="prompt-preview">{{ defaultAiPrompt }}</div>
</div> </div>
<div class="secret-card">
<div class="section-title">密钥</div>
<input v-model="cozeApiKey" class="secret-input" type="password" autocomplete="off" spellcheck="false" />
</div>
<div class="run-row"> <div class="run-row">
<button type="button" class="btn-run" :disabled="parsing || !uploadedFiles.length" @click="parseFiles"> <button type="button" class="btn-run" :disabled="parsing || !uploadedFiles.length" @click="parseFiles">
{{ parsing ? '解析中...' : '解析并创建任务' }} {{ parsing ? '解析中...' : '解析并创建任务' }}
@@ -34,9 +39,9 @@
</div> </div>
<p class="loading-msg">Python 回传字段按 asin国家url标题提交后端接收分片后按 10 条一批调用 Coze</p> <p class="loading-msg">Python 回传字段按 asin国家url标题提交后端接收分片后按 10 条一批调用 Coze</p>
<div v-if="parseResult" class="parse-card"> <div v-if="visibleTaskSummary" class="parse-card">
<div>任务 ID{{ parseResult.taskId }}</div> <div>任务 ID{{ visibleTaskSummary.taskId }}</div>
<div>总行数{{ parseResult.totalRows }}有效{{ parseResult.acceptedRows }}分组{{ parseResult.groupCount || 0 }}过滤{{ parseResult.droppedRows }}</div> <div>总行数{{ visibleTaskSummary.totalRows }}有效{{ visibleTaskSummary.acceptedRows }}分组{{ visibleTaskSummary.groupCount || 0 }}过滤{{ visibleTaskSummary.droppedRows }}</div>
</div> </div>
<pre v-if="queuePayloadText" class="queue-payload">{{ queuePayloadText }}</pre> <pre v-if="queuePayloadText" class="queue-payload">{{ queuePayloadText }}</pre>
</aside> </aside>
@@ -171,6 +176,8 @@ const selectedFileNames = ref<string[]>([])
const uploadedFiles = ref<UploadFileVo[]>([]) const uploadedFiles = ref<UploadFileVo[]>([])
const parseResult = ref<AppearancePatentParseVo | null>(null) const parseResult = ref<AppearancePatentParseVo | null>(null)
const parsedGroups = ref<AppearancePatentParsedGroup[]>([]) const parsedGroups = ref<AppearancePatentParsedGroup[]>([])
type TaskSummary = Pick<AppearancePatentParseVo, 'taskId' | 'totalRows' | 'acceptedRows' | 'groupCount' | 'droppedRows'>
const queuedTaskSummary = ref<TaskSummary | null>(null)
const defaultAiPrompt = `请帮我排查以下亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。 const defaultAiPrompt = `请帮我排查以下亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。
请直接给出明确结论(有侵权风险 或 未发现明显侵权风险),并严格按照以下三个维度提供精简的排查理由: 请直接给出明确结论(有侵权风险 或 未发现明显侵权风险),并严格按照以下三个维度提供精简的排查理由:
外观维度: 评估产品外形、图案设计是否与欧洲/英国常见外观专利雷同。 外观维度: 评估产品外形、图案设计是否与欧洲/英国常见外观专利雷同。
@@ -178,6 +185,7 @@ const defaultAiPrompt = `请帮我排查以下亚马逊商品在英国及欧洲
标题维度: 排查标题中是否包含大牌商标、敏感词或版权保护词汇。 标题维度: 排查标题中是否包含大牌商标、敏感词或版权保护词汇。
结论XX` 结论XX`
const aiPrompt = ref('') const aiPrompt = ref('')
const cozeApiKey = ref('')
const parsing = ref(false) const parsing = ref(false)
const pushing = ref(false) const pushing = ref(false)
const queuePayloadText = ref('') const queuePayloadText = ref('')
@@ -203,6 +211,7 @@ const parsedRows = computed<AppearancePatentParsedRow[]>(() =>
parsedGroups.value.flatMap((group) => group.items || []), parsedGroups.value.flatMap((group) => group.items || []),
) )
const previewRows = computed(() => parsedGroups.value[0]?.items || []) const previewRows = computed(() => parsedGroups.value[0]?.items || [])
const visibleTaskSummary = computed(() => parseResult.value || queuedTaskSummary.value)
const currentItems = computed(() => historyItems.value.filter((i) => i.taskId != null && pollingTaskIds.value.includes(i.taskId))) const currentItems = computed(() => historyItems.value.filter((i) => i.taskId != null && pollingTaskIds.value.includes(i.taskId)))
const historyOnlyItems = computed(() => const historyOnlyItems = computed(() =>
historyItems.value.filter((i) => { historyItems.value.filter((i) => {
@@ -215,6 +224,28 @@ function effectiveAiPrompt() {
return aiPrompt.value.trim() || defaultAiPrompt return aiPrompt.value.trim() || defaultAiPrompt
} }
function effectiveCozeApiKey() {
return cozeApiKey.value.trim()
}
function maskSecret(secret: string) {
if (!secret) return ''
if (secret.length <= 10) return '***'
return `${secret.slice(0, 6)}***${secret.slice(-4)}`
}
function payloadForDisplay<T extends { data?: Record<string, unknown> }>(payload: T) {
return {
...payload,
data: payload.data
? {
...payload.data,
api_key: maskSecret(String(payload.data.api_key || '')),
}
: payload.data,
}
}
function uidForStorage() { function uidForStorage() {
return typeof window !== 'undefined' ? window.localStorage.getItem('uid') || '0' : '0' return typeof window !== 'undefined' ? window.localStorage.getItem('uid') || '0' : '0'
} }
@@ -223,6 +254,16 @@ function pollingKey() {
return `appearance-patent:tasks:${uidForStorage()}` return `appearance-patent:tasks:${uidForStorage()}`
} }
function toTaskSummary(result: AppearancePatentParseVo): TaskSummary {
return {
taskId: result.taskId,
totalRows: result.totalRows,
acceptedRows: result.acceptedRows,
groupCount: result.groupCount,
droppedRows: result.droppedRows,
}
}
function savePollingIds() { function savePollingIds() {
if (typeof window === 'undefined') return if (typeof window === 'undefined') return
const ids = Array.from(new Set([...pollingTaskIds.value, ...pendingFileTaskIds.value])) const ids = Array.from(new Set([...pollingTaskIds.value, ...pendingFileTaskIds.value]))
@@ -274,6 +315,7 @@ async function selectFiles() {
selectedFileNames.value = files.map((f) => f.relativePath || f.originalFilename || f.fileKey) selectedFileNames.value = files.map((f) => f.relativePath || f.originalFilename || f.fileKey)
parseResult.value = null parseResult.value = null
parsedGroups.value = [] parsedGroups.value = []
queuedTaskSummary.value = null
queuePayloadText.value = '' queuePayloadText.value = ''
} }
@@ -296,6 +338,7 @@ async function selectFolder() {
selectedFileNames.value = result.items.map((item) => item.relativePath || item.absolutePath) selectedFileNames.value = result.items.map((item) => item.relativePath || item.absolutePath)
parseResult.value = null parseResult.value = null
parsedGroups.value = [] parsedGroups.value = []
queuedTaskSummary.value = null
queuePayloadText.value = '' queuePayloadText.value = ''
ElMessage.success(`已选择文件夹内 ${result.items.length} 个 Excel 文件`) ElMessage.success(`已选择文件夹内 ${result.items.length} 个 Excel 文件`)
} catch (error) { } catch (error) {
@@ -308,6 +351,10 @@ async function parseFiles() {
ElMessage.warning('请先选择 Excel') ElMessage.warning('请先选择 Excel')
return return
} }
if (!effectiveCozeApiKey()) {
ElMessage.warning('请先填写密钥')
return
}
parsing.value = true parsing.value = true
try { try {
const files: UploadedFileRef[] = uploadedFiles.value.map((f) => ({ const files: UploadedFileRef[] = uploadedFiles.value.map((f) => ({
@@ -315,8 +362,9 @@ async function parseFiles() {
originalFilename: f.originalFilename, originalFilename: f.originalFilename,
relativePath: f.relativePath, relativePath: f.relativePath,
})) }))
const res = await parseAppearancePatent(files, effectiveAiPrompt()) const res = await parseAppearancePatent(files, effectiveAiPrompt(), effectiveCozeApiKey())
parseResult.value = res parseResult.value = res
queuedTaskSummary.value = null
parsedGroups.value = res.groups?.length parsedGroups.value = res.groups?.length
? res.groups ? res.groups
: (res.items?.length : (res.items?.length
@@ -341,7 +389,8 @@ async function parseFiles() {
async function pushToPythonQueue() { async function pushToPythonQueue() {
const api = getPywebviewApi() const api = getPywebviewApi()
const taskId = parseResult.value?.taskId const currentParseResult = parseResult.value
const taskId = currentParseResult?.taskId
if (!taskId || !parsedRows.value.length) { if (!taskId || !parsedRows.value.length) {
ElMessage.warning('请先解析文件') ElMessage.warning('请先解析文件')
return return
@@ -357,7 +406,8 @@ async function pushToPythonQueue() {
ts: Date.now(), ts: Date.now(),
data: { data: {
taskId, taskId,
prompt: parseResult.value?.aiPrompt || effectiveAiPrompt(), prompt: currentParseResult.aiPrompt || effectiveAiPrompt(),
api_key: effectiveCozeApiKey(),
groups: parsedGroups.value.map((group) => ({ groups: parsedGroups.value.map((group) => ({
sourceFileKey: group.sourceFileKey || '', sourceFileKey: group.sourceFileKey || '',
sourceFilename: group.sourceFilename || '', sourceFilename: group.sourceFilename || '',
@@ -389,13 +439,14 @@ async function pushToPythonQueue() {
})), })),
}, },
} }
queuePayloadText.value = JSON.stringify(payload, null, 2) queuePayloadText.value = JSON.stringify(payloadForDisplay(payload), null, 2)
await activateAppearancePatentTask(taskId) await activateAppearancePatentTask(taskId)
const result = await api.enqueue_json(payload) const result = await api.enqueue_json(payload)
if (!result?.success) { if (!result?.success) {
ElMessage.error(result?.error || '推送失败') ElMessage.error(result?.error || '推送失败')
return return
} }
queuedTaskSummary.value = toTaskSummary(currentParseResult)
addPollingTask(taskId) addPollingTask(taskId)
clearParsedTask() clearParsedTask()
await loadDashboard() await loadDashboard()
@@ -721,9 +772,10 @@ onUnmounted(() => {
.btn-run:disabled { opacity: .55; cursor: not-allowed; } .btn-run:disabled { opacity: .55; cursor: not-allowed; }
.selected-files { margin-top: 14px; color: #999; font-size: 12px; word-break: break-all; } .selected-files { margin-top: 14px; color: #999; font-size: 12px; word-break: break-all; }
.selected-files span { display: block; margin: 4px 0; } .selected-files span { display: block; margin: 4px 0; }
.prompt-card { margin-bottom: 18px; } .prompt-card, .secret-card { margin-bottom: 18px; }
.prompt-input { width: 100%; box-sizing: border-box; resize: vertical; min-height: 180px; padding: 10px 12px; border: 1px solid #333; border-radius: 8px; background: #202020; color: #d8d8d8; font-size: 12px; line-height: 1.6; outline: none; } .prompt-input { width: 100%; box-sizing: border-box; resize: vertical; min-height: 180px; padding: 10px 12px; border: 1px solid #333; border-radius: 8px; background: #202020; color: #d8d8d8; font-size: 12px; line-height: 1.6; outline: none; }
.prompt-input:focus { border-color: #3498db; } .secret-input { width: 100%; box-sizing: border-box; height: 38px; padding: 0 12px; border: 1px solid #333; border-radius: 8px; background: #202020; color: #d8d8d8; font-size: 12px; outline: none; }
.prompt-input:focus, .secret-input:focus { border-color: #3498db; }
.prompt-default-label { margin-top: 10px; color: #8d8d8d; font-size: 12px; } .prompt-default-label { margin-top: 10px; color: #8d8d8d; font-size: 12px; }
.prompt-preview { margin-top: 10px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #9ea7b3; font-size: 12px; line-height: 1.6; white-space: pre-wrap; } .prompt-preview { margin-top: 10px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #9ea7b3; font-size: 12px; line-height: 1.6; white-space: pre-wrap; }
.parse-card, .queue-payload { margin-top: 14px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #b8c1cc; font-size: 12px; } .parse-card, .queue-payload { margin-top: 14px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #b8c1cc; font-size: 12px; }

View File

@@ -6,7 +6,7 @@
<aside class="left-panel"> <aside class="left-panel">
<div class="section-title">上传文件</div> <div class="section-title">上传文件</div>
<div class="upload-zone"> <div class="upload-zone">
<div class="hint">选择 Excel 后点击解析后端会提取 idASIN国家并保留整数 id 与子数据的第一条</div> <div class="hint">选择 Excel 后点击解析后端会提取 idASIN国家价格每一行都会独立送检</div>
<div class="btns"> <div class="btns">
<button type="button" class="opt-btn" @click="selectFiles">选择 Excel</button> <button type="button" class="opt-btn" @click="selectFiles">选择 Excel</button>
<button type="button" class="opt-btn" @click="selectFolder">选择文件夹</button> <button type="button" class="opt-btn" @click="selectFolder">选择文件夹</button>
@@ -24,6 +24,11 @@
<div class="prompt-preview">{{ defaultAiPrompt }}</div> <div class="prompt-preview">{{ defaultAiPrompt }}</div>
</div> </div>
<div class="secret-card">
<div class="section-title">密钥</div>
<input v-model="cozeApiKey" class="secret-input" type="password" autocomplete="off" spellcheck="false" />
</div>
<div class="run-row"> <div class="run-row">
<button type="button" class="btn-run" :disabled="parsing || !uploadedFiles.length" @click="parseFiles"> <button type="button" class="btn-run" :disabled="parsing || !uploadedFiles.length" @click="parseFiles">
{{ parsing ? '解析中...' : '解析并创建任务' }} {{ parsing ? '解析中...' : '解析并创建任务' }}
@@ -32,11 +37,11 @@
{{ pushing ? '推送中...' : '推送到 Python 队列' }} {{ pushing ? '推送中...' : '推送到 Python 队列' }}
</button> </button>
</div> </div>
<p class="loading-msg">Python 回传字段按 asin国家url标题提交后端接收分片后按 10 条一批调用 Coze</p> <p class="loading-msg">Python 回传字段按 idasin国家价格标题图片链接数组提交后端接收分片后按 10 条一批送检</p>
<div v-if="parseResult" class="parse-card"> <div v-if="visibleTaskSummary" class="parse-card">
<div>任务 ID{{ parseResult.taskId }}</div> <div>任务 ID{{ visibleTaskSummary.taskId }}</div>
<div>总行数{{ parseResult.totalRows }}有效{{ parseResult.acceptedRows }}分组{{ parseResult.groupCount || 0 }}过滤{{ parseResult.droppedRows }}</div> <div>总行数{{ visibleTaskSummary.totalRows }}有效{{ visibleTaskSummary.acceptedRows }}过滤{{ visibleTaskSummary.droppedRows }}</div>
</div> </div>
<pre v-if="queuePayloadText" class="queue-payload">{{ queuePayloadText }}</pre> <pre v-if="queuePayloadText" class="queue-payload">{{ queuePayloadText }}</pre>
</aside> </aside>
@@ -67,13 +72,14 @@
<div class="result-list-wrap preview-wrap"> <div class="result-list-wrap preview-wrap">
<div class="result-list-header"> <div class="result-list-header">
<span>解析结果</span> <span>解析结果</span>
<span v-if="parsedRows.length" class="muted">显示首组 {{ previewRows.length }} / {{ parseResult?.groupCount || parsedGroups.length }} {{ parsedRows.length }} </span> <span v-if="parsedRows.length" class="muted"> {{ parsedRows.length }} </span>
</div> </div>
<div v-if="!parsedRows.length" class="empty-tasks">暂无解析结果</div> <div v-if="!parsedRows.length" class="empty-tasks">暂无解析结果</div>
<el-table v-else :data="previewRows" height="120" class="result-table"> <el-table v-else :data="previewRows" height="120" class="result-table">
<el-table-column prop="displayId" label="ID" width="90" /> <el-table-column prop="displayId" label="ID" width="90" />
<el-table-column prop="asin" label="ASIN" width="130" /> <el-table-column prop="asin" label="ASIN" width="130" />
<el-table-column prop="country" label="国家" width="100" /> <el-table-column prop="country" label="国家" width="100" />
<el-table-column prop="price" label="价格" width="90" />
<el-table-column prop="title" label="标题" min-width="160" show-overflow-tooltip /> <el-table-column prop="title" label="标题" min-width="160" show-overflow-tooltip />
<el-table-column prop="url" label="URL" min-width="160" show-overflow-tooltip /> <el-table-column prop="url" label="URL" min-width="160" show-overflow-tooltip />
</el-table> </el-table>
@@ -171,13 +177,14 @@ const selectedFileNames = ref<string[]>([])
const uploadedFiles = ref<UploadFileVo[]>([]) const uploadedFiles = ref<UploadFileVo[]>([])
const parseResult = ref<SimilarAsinParseVo | null>(null) const parseResult = ref<SimilarAsinParseVo | null>(null)
const parsedGroups = ref<SimilarAsinParsedGroup[]>([]) const parsedGroups = ref<SimilarAsinParsedGroup[]>([])
const defaultAiPrompt = `请帮我排查以下亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。 type TaskSummary = Pick<SimilarAsinParseVo, 'taskId' | 'totalRows' | 'acceptedRows' | 'groupCount' | 'droppedRows'>
请直接给出明确结论(有侵权风险 或 未发现明显侵权风险),并严格按照以下三个维度提供精简的排查理由: const queuedTaskSummary = ref<TaskSummary | null>(null)
外观维度: 评估产品外形、图案设计是否与欧洲/英国常见外观专利雷同 const defaultAiPrompt = `1. 图案与形象限制不含各国国旗及类似图案无各国领导人画像不含圣诞老人形象排除迪士尼、漫威、三丽鸥等所有指定动漫IP的图案与关联物品且不涉及知名油画作品图案
专利维度: 评估产品的核心技术或物理结构是否存在侵权可能 2. 品类排除:非图书、刀具、服装;不含药品、带容器的粉末及液体;与吸烟行为无关,无医疗标志
标题维度: 排查标题中是否包含大牌商标、敏感词或版权保护词汇 3. 功能与配件要求:不可充电且不带电池,无磁吸功能;配件多的情况下需完全匹配
结论XX` 4. 规格与外观限制不含体积大的家具类物品如椅子、桌子、大镜子、柜子不带任何品牌logo无多种款式可选。`
const aiPrompt = ref('') const aiPrompt = ref('')
const cozeApiKey = ref('')
const parsing = ref(false) const parsing = ref(false)
const pushing = ref(false) const pushing = ref(false)
const queuePayloadText = ref('') const queuePayloadText = ref('')
@@ -200,9 +207,12 @@ const dashboard = ref<SimilarAsinDashboardVo>({
const historyItems = ref<SimilarAsinHistoryItem[]>([]) const historyItems = ref<SimilarAsinHistoryItem[]>([])
const parsedRows = computed<SimilarAsinParsedRow[]>(() => const parsedRows = computed<SimilarAsinParsedRow[]>(() =>
parsedGroups.value.flatMap((group) => group.items || []), parseResult.value?.items?.length
? parseResult.value.items
: parsedGroups.value.flatMap((group) => group.items || []),
) )
const previewRows = computed(() => parsedGroups.value[0]?.items || []) const previewRows = computed(() => parsedRows.value)
const visibleTaskSummary = computed(() => parseResult.value || queuedTaskSummary.value)
const currentItems = computed(() => historyItems.value.filter((i) => i.taskId != null && pollingTaskIds.value.includes(i.taskId))) const currentItems = computed(() => historyItems.value.filter((i) => i.taskId != null && pollingTaskIds.value.includes(i.taskId)))
const historyOnlyItems = computed(() => const historyOnlyItems = computed(() =>
historyItems.value.filter((i) => { historyItems.value.filter((i) => {
@@ -215,6 +225,28 @@ function effectiveAiPrompt() {
return aiPrompt.value.trim() || defaultAiPrompt return aiPrompt.value.trim() || defaultAiPrompt
} }
function effectiveCozeApiKey() {
return cozeApiKey.value.trim()
}
function maskSecret(secret: string) {
if (!secret) return ''
if (secret.length <= 10) return '***'
return `${secret.slice(0, 6)}***${secret.slice(-4)}`
}
function payloadForDisplay<T extends { data?: Record<string, unknown> }>(payload: T) {
return {
...payload,
data: payload.data
? {
...payload.data,
api_key: maskSecret(String(payload.data.api_key || '')),
}
: payload.data,
}
}
function uidForStorage() { function uidForStorage() {
return typeof window !== 'undefined' ? window.localStorage.getItem('uid') || '0' : '0' return typeof window !== 'undefined' ? window.localStorage.getItem('uid') || '0' : '0'
} }
@@ -223,6 +255,16 @@ function pollingKey() {
return `similar-asin:tasks:${uidForStorage()}` return `similar-asin:tasks:${uidForStorage()}`
} }
function toTaskSummary(result: SimilarAsinParseVo): TaskSummary {
return {
taskId: result.taskId,
totalRows: result.totalRows,
acceptedRows: result.acceptedRows,
groupCount: result.groupCount,
droppedRows: result.droppedRows,
}
}
function savePollingIds() { function savePollingIds() {
if (typeof window === 'undefined') return if (typeof window === 'undefined') return
const ids = Array.from(new Set([...pollingTaskIds.value, ...pendingFileTaskIds.value])) const ids = Array.from(new Set([...pollingTaskIds.value, ...pendingFileTaskIds.value]))
@@ -274,6 +316,7 @@ async function selectFiles() {
selectedFileNames.value = files.map((f) => f.relativePath || f.originalFilename || f.fileKey) selectedFileNames.value = files.map((f) => f.relativePath || f.originalFilename || f.fileKey)
parseResult.value = null parseResult.value = null
parsedGroups.value = [] parsedGroups.value = []
queuedTaskSummary.value = null
queuePayloadText.value = '' queuePayloadText.value = ''
} }
@@ -296,6 +339,7 @@ async function selectFolder() {
selectedFileNames.value = result.items.map((item) => item.relativePath || item.absolutePath) selectedFileNames.value = result.items.map((item) => item.relativePath || item.absolutePath)
parseResult.value = null parseResult.value = null
parsedGroups.value = [] parsedGroups.value = []
queuedTaskSummary.value = null
queuePayloadText.value = '' queuePayloadText.value = ''
ElMessage.success(`已选择文件夹内 ${result.items.length} 个 Excel 文件`) ElMessage.success(`已选择文件夹内 ${result.items.length} 个 Excel 文件`)
} catch (error) { } catch (error) {
@@ -308,6 +352,10 @@ async function parseFiles() {
ElMessage.warning('请先选择 Excel') ElMessage.warning('请先选择 Excel')
return return
} }
if (!effectiveCozeApiKey()) {
ElMessage.warning('请先填写密钥')
return
}
parsing.value = true parsing.value = true
try { try {
const files: UploadedFileRef[] = uploadedFiles.value.map((f) => ({ const files: UploadedFileRef[] = uploadedFiles.value.map((f) => ({
@@ -315,23 +363,22 @@ async function parseFiles() {
originalFilename: f.originalFilename, originalFilename: f.originalFilename,
relativePath: f.relativePath, relativePath: f.relativePath,
})) }))
const res = await parseSimilarAsin(files, effectiveAiPrompt()) const res = await parseSimilarAsin(files, effectiveAiPrompt(), effectiveCozeApiKey())
parseResult.value = res parseResult.value = res
parsedGroups.value = res.groups?.length queuedTaskSummary.value = null
? res.groups parsedGroups.value = res.items?.length
: (res.items?.length ? [{
? [{ sourceFileKey: res.items[0]?.sourceFileKey,
sourceFileKey: res.items[0]?.sourceFileKey, sourceFilename: res.items[0]?.sourceFilename,
sourceFilename: res.items[0]?.sourceFilename, groupKey: `similar-asin:${res.taskId}`,
groupKey: res.items[0]?.groupKey, baseId: '',
baseId: '', displayId: res.items[0]?.displayId,
displayId: res.items[0]?.displayId, itemCount: res.items.length,
itemCount: res.items.length, items: res.items,
items: res.items, }]
}] : []
: [])
queuePayloadText.value = '' queuePayloadText.value = ''
ElMessage.success(`解析完成,共 ${res.groupCount || 0} 组 / ${res.acceptedRows}`) ElMessage.success(`解析完成,共 ${res.acceptedRows}`)
} catch (e) { } catch (e) {
ElMessage.error(e instanceof Error ? e.message : '解析失败') ElMessage.error(e instanceof Error ? e.message : '解析失败')
} finally { } finally {
@@ -341,7 +388,8 @@ async function parseFiles() {
async function pushToPythonQueue() { async function pushToPythonQueue() {
const api = getPywebviewApi() const api = getPywebviewApi()
const taskId = parseResult.value?.taskId const currentParseResult = parseResult.value
const taskId = currentParseResult?.taskId
if (!taskId || !parsedRows.value.length) { if (!taskId || !parsedRows.value.length) {
ElMessage.warning('请先解析文件') ElMessage.warning('请先解析文件')
return return
@@ -350,6 +398,10 @@ async function pushToPythonQueue() {
ElMessage.error('当前环境未启用 pywebview enqueue_json') ElMessage.error('当前环境未启用 pywebview enqueue_json')
return return
} }
if (!effectiveCozeApiKey()) {
ElMessage.warning('请先填写密钥')
return
}
pushing.value = true pushing.value = true
try { try {
const payload = { const payload = {
@@ -357,7 +409,8 @@ async function pushToPythonQueue() {
ts: Date.now(), ts: Date.now(),
data: { data: {
taskId, taskId,
prompt: parseResult.value?.aiPrompt || effectiveAiPrompt(), prompt: currentParseResult.aiPrompt || effectiveAiPrompt(),
api_key: effectiveCozeApiKey(),
groups: parsedGroups.value.map((group) => ({ groups: parsedGroups.value.map((group) => ({
sourceFileKey: group.sourceFileKey || '', sourceFileKey: group.sourceFileKey || '',
sourceFilename: group.sourceFilename || '', sourceFilename: group.sourceFilename || '',
@@ -372,8 +425,10 @@ async function pushToPythonQueue() {
id: row.displayId, id: row.displayId,
asin: row.asin, asin: row.asin,
country: row.country, country: row.country,
price: row.price || '',
url: row.url || '', url: row.url || '',
title: row.title || '', title: row.title || '',
target_urls: [],
})), })),
})), })),
rows: parsedRows.value.map((row) => ({ rows: parsedRows.value.map((row) => ({
@@ -384,18 +439,21 @@ async function pushToPythonQueue() {
id: row.displayId, id: row.displayId,
asin: row.asin, asin: row.asin,
country: row.country, country: row.country,
price: row.price || '',
url: row.url || '', url: row.url || '',
title: row.title || '', title: row.title || '',
target_urls: [],
})), })),
}, },
} }
queuePayloadText.value = JSON.stringify(payload, null, 2) queuePayloadText.value = JSON.stringify(payloadForDisplay(payload), null, 2)
await activateSimilarAsinTask(taskId) await activateSimilarAsinTask(taskId)
const result = await api.enqueue_json(payload) const result = await api.enqueue_json(payload)
if (!result?.success) { if (!result?.success) {
ElMessage.error(result?.error || '推送失败') ElMessage.error(result?.error || '推送失败')
return return
} }
queuedTaskSummary.value = toTaskSummary(currentParseResult)
addPollingTask(taskId) addPollingTask(taskId)
clearParsedTask() clearParsedTask()
await loadDashboard() await loadDashboard()
@@ -721,9 +779,10 @@ onUnmounted(() => {
.btn-run:disabled { opacity: .55; cursor: not-allowed; } .btn-run:disabled { opacity: .55; cursor: not-allowed; }
.selected-files { margin-top: 14px; color: #999; font-size: 12px; word-break: break-all; } .selected-files { margin-top: 14px; color: #999; font-size: 12px; word-break: break-all; }
.selected-files span { display: block; margin: 4px 0; } .selected-files span { display: block; margin: 4px 0; }
.prompt-card { margin-bottom: 18px; } .prompt-card, .secret-card { margin-bottom: 18px; }
.prompt-input { width: 100%; box-sizing: border-box; resize: vertical; min-height: 180px; padding: 10px 12px; border: 1px solid #333; border-radius: 8px; background: #202020; color: #d8d8d8; font-size: 12px; line-height: 1.6; outline: none; } .prompt-input { width: 100%; box-sizing: border-box; resize: vertical; min-height: 180px; padding: 10px 12px; border: 1px solid #333; border-radius: 8px; background: #202020; color: #d8d8d8; font-size: 12px; line-height: 1.6; outline: none; }
.prompt-input:focus { border-color: #3498db; } .secret-input { width: 100%; box-sizing: border-box; height: 38px; padding: 0 12px; border: 1px solid #333; border-radius: 8px; background: #202020; color: #d8d8d8; font-size: 12px; outline: none; }
.prompt-input:focus, .secret-input:focus { border-color: #3498db; }
.prompt-default-label { margin-top: 10px; color: #8d8d8d; font-size: 12px; } .prompt-default-label { margin-top: 10px; color: #8d8d8d; font-size: 12px; }
.prompt-preview { margin-top: 10px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #9ea7b3; font-size: 12px; line-height: 1.6; white-space: pre-wrap; } .prompt-preview { margin-top: 10px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #9ea7b3; font-size: 12px; line-height: 1.6; white-space: pre-wrap; }
.parse-card, .queue-payload { margin-top: 14px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #b8c1cc; font-size: 12px; } .parse-card, .queue-payload { margin-top: 14px; padding: 12px; border: 1px solid #2a2a2a; border-radius: 8px; background: #202020; color: #b8c1cc; font-size: 12px; }

View File

@@ -1531,15 +1531,16 @@ export interface AppearancePatentTaskBatchVo {
missingTaskIds?: number[]; missingTaskIds?: number[];
} }
export function parseAppearancePatent(files: UploadedFileRef[], aiPrompt: string) { export function parseAppearancePatent(files: UploadedFileRef[], aiPrompt: string, apiKey?: string) {
return unwrapJavaResponse( return unwrapJavaResponse(
post< post<
JavaApiResponse<AppearancePatentParseVo>, JavaApiResponse<AppearancePatentParseVo>,
{ user_id: number; files: UploadedFileRef[]; ai_prompt: string } { user_id: number; files: UploadedFileRef[]; ai_prompt: string; api_key?: string }
>(`${JAVA_API_PREFIX}/appearance-patent/parse`, { >(`${JAVA_API_PREFIX}/appearance-patent/parse`, {
user_id: getCurrentUserId(), user_id: getCurrentUserId(),
files, files,
ai_prompt: aiPrompt, ai_prompt: aiPrompt,
api_key: apiKey,
}), }),
); );
} }
@@ -1615,6 +1616,7 @@ export interface SimilarAsinParsedRow {
groupKey?: string; groupKey?: string;
asin: string; asin: string;
country: string; country: string;
price?: string;
url?: string; url?: string;
title?: string; title?: string;
} }
@@ -1694,15 +1696,16 @@ export interface SimilarAsinTaskBatchVo {
missingTaskIds?: number[]; missingTaskIds?: number[];
} }
export function parseSimilarAsin(files: UploadedFileRef[], aiPrompt: string) { export function parseSimilarAsin(files: UploadedFileRef[], aiPrompt: string, apiKey?: string) {
return unwrapJavaResponse( return unwrapJavaResponse(
post< post<
JavaApiResponse<SimilarAsinParseVo>, JavaApiResponse<SimilarAsinParseVo>,
{ user_id: number; files: UploadedFileRef[]; ai_prompt: string } { user_id: number; files: UploadedFileRef[]; ai_prompt: string; api_key?: string }
>(`${JAVA_API_PREFIX}/similar-asin/parse`, { >(`${JAVA_API_PREFIX}/similar-asin/parse`, {
user_id: getCurrentUserId(), user_id: getCurrentUserId(),
files, files,
ai_prompt: aiPrompt, ai_prompt: aiPrompt,
api_key: apiKey,
}), }),
); );
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,732 @@
java-server | 08:17:25.47 INFO ==>
java-server | 08:17:25.47 INFO ==> Welcome to the Bitnami java container
java-server | 08:17:25.48 INFO ==> Subscribe to project updates by watching https://github.com/bitnami/containers
java-server | 08:17:25.48 INFO ==> Did you know there are enterprise versions of the Bitnami catalog? For enhanced secure software supply chain features, unlimited pulls from Docker, LTS support, or application customization, see Bitnami Premium or Tanzu Application Catalog. See https://www.arrow.com/globalecs/na/vendors/bitnami/ for more information.
java-server | 08:17:25.48 INFO ==>
java-server |
java-server | Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
java-server |
java-server | . ____ _ __ _ _
java-server | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
java-server | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
java-server | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
java-server | ' |____| .__|_| |_|_| |_\__, | / / / /
java-server | =========|_|==============|___/=/_/_/_/
java-server |
java-server | :: Spring Boot :: (v3.3.9)
java-server |
java-server | 2026-05-05 16:17:26.296 [background-preinit] INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 8.0.2.Final
java-server | 2026-05-05 16:17:26.332 [main] INFO c.nanri.aiimage.AiImageApplication - Starting AiImageApplication v0.0.1-SNAPSHOT using Java 21.0.7 with PID 12 (/app/aiimage-backend-0.0.1-SNAPSHOT.jar started by root in /app)
java-server | 2026-05-05 16:17:26.332 [main] INFO c.nanri.aiimage.AiImageApplication - No active profile set, falling back to 1 default profile: "default"
java-server | 2026-05-05 16:17:27.253 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
java-server | 2026-05-05 16:17:27.255 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
java-server | 2026-05-05 16:17:27.282 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 14 ms. Found 0 Redis repository interfaces.
java-server | 2026-05-05 16:17:27.882 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 18080 (http)
java-server | 2026-05-05 16:17:27.890 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18080"]
java-server | 2026-05-05 16:17:27.891 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
java-server | 2026-05-05 16:17:27.891 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.36]
java-server | 2026-05-05 16:17:27.910 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
java-server | 2026-05-05 16:17:27.910 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1549 ms
java-server | Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
java-server | _ _ |_ _ _|_. ___ _ | _
java-server | | | |\/|_)(_| | |_\ |_)||_|_\
java-server | / |
java-server | 3.5.7
java-server | 2026-05-05 16:17:29.176 [main] WARN c.b.m.core.metadata.TableInfoHelper - Can not find table primary key in Class: "com.nanri.aiimage.modules.permission.model.entity.UserColumnPermissionEntity".
java-server | 2026-05-05 16:17:29.176 [main] WARN c.b.m.c.injector.DefaultSqlInjector - class com.nanri.aiimage.modules.permission.model.entity.UserColumnPermissionEntity ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.
java-server | 2026-05-05 16:17:29.476 [main] INFO o.a.r.s.s.RocketMQMessageListenerContainerRegistrar - Register the listener to container, listenerBeanName:taskFileJobConsumer, containerBeanName:org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1
java-server | 2026-05-05 16:17:29.569 [main] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
java-server |
java-server | Using generated security password: b8933522-c036-4732-bc90-2809f85408b4
java-server |
java-server | This generated password is for development use only. Your security configuration must be updated before running your application in production.
java-server |
java-server | 2026-05-05 16:17:29.582 [main] INFO o.s.s.c.a.a.c.InitializeUserDetailsBeanManagerConfigurer$InitializeUserDetailsManagerConfigurer - Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
java-server | 2026-05-05 16:17:29.849 [main] INFO o.a.r.s.a.RocketMQAutoConfiguration - a producer (aiimage-backend-producer) init on namesrv 121.196.149.225:9876
java-server | 2026-05-05 16:17:30.220 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 1 endpoint beneath base path '/actuator'
java-server | 2026-05-05 16:17:30.276 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18080"]
java-server | 2026-05-05 16:17:30.285 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port 18080 (http) with context path '/'
java-server | 2026-05-05 16:17:30.393 [main] INFO o.a.r.s.s.DefaultRocketMQListenerContainer - running container: DefaultRocketMQListenerContainer{consumerGroup='aiimage-result-file-job-consumer', namespace='', namespaceV2='', nameServer='121.196.149.225:9876', topic='aiimage-result-file-job', consumeMode=CONCURRENTLY, selectorType=TAG, selectorExpression='*', messageModel=CLUSTERING', tlsEnable=false, instanceName=DEFAULT}
java-server | 2026-05-05 16:17:30.407 [main] INFO c.nanri.aiimage.AiImageApplication - Started AiImageApplication in 4.495 seconds (process running for 4.922)
java-server | 2026-05-05 16:17:30.419 [aiimage-scheduling-2] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
java-server | 2026-05-05 16:17:30.569 [aiimage-scheduling-2] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@31f426dd
java-server | 2026-05-05 16:17:30.572 [aiimage-scheduling-2] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
java-server | 2026-05-05 16:17:30.608 [http-nio-18080-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
java-server | 2026-05-05 16:17:30.608 [http-nio-18080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
java-server | 2026-05-05 16:17:30.610 [http-nio-18080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 2 ms
java-server | 2026-05-05 16:17:30.801 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6363 status=SUCCESS
java-server | 2026-05-05 16:17:30.831 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6363/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=191
java-server | 2026-05-05 16:17:31.055 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:17:31.061 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=24
java-server | 2026-05-05 16:17:31.386 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:17:31.391 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=22
java-server | 2026-05-05 16:17:44.290 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/brand/tasks status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=35
java-server | 2026-05-05 16:17:45.747 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:17:45.752 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/history status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=33
java-server | 2026-05-05 16:17:45.896 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=43
java-server | 2026-05-05 16:17:46.015 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:17:46.116 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:17:46.122 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:17:48.143 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/files/upload status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=50
java-server | 2026-05-05 16:17:50.648 [http-nio-18080-exec-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] parse timing taskId=6594 files=1 rows=12 groups=8 totalMs=1030 parseMs=380 groupMs=0 taskInsertMs=31 payloadJsonMs=233 payloadStoreMs=335 persistMs=48 responseMs=0
java-server | 2026-05-05 16:17:50.651 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/parse status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=1041
java-server | 2026-05-05 16:17:51.477 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/6594/activate status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=54
java-server | 2026-05-05 16:17:51.592 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:17:51.712 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/history status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:17:56.017 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=24
java-server | 2026-05-05 16:17:56.134 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:17:57.289 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:17:57.294 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:18:00.005 [aiimage-scheduling-1] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:18:00.013 [aiimage-scheduling-3] INFO c.n.a.m.b.service.BrandTaskService - [brand-stale-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:18:03.991 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:18:03.996 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:18:06.142 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=24
java-server | 2026-05-05 16:18:06.245 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:18:16.284 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=32
java-server | 2026-05-05 16:18:16.398 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:18:19.848 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:18:19.854 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:18:26.405 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=25
java-server | 2026-05-05 16:18:26.524 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:18:30.008 [aiimage-scheduling-1] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [finalize-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:18:30.009 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:18:30.014 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=30
java-server | 2026-05-05 16:18:33.287 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:18:33.293 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:18:36.542 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:18:36.651 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:18:40.422 [http-nio-18080-exec-10] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:18:40.427 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:18:46.686 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:18:46.802 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:18:56.826 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:18:56.959 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=21
java-server | 2026-05-05 16:18:57.163 [http-nio-18080-exec-10] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:18:57.169 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:19:06.967 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=33
java-server | 2026-05-05 16:19:07.077 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:19:07.374 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:19:07.379 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:19:17.101 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=29
java-server | 2026-05-05 16:19:17.211 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:19:17.970 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:19:17.976 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:19:23.559 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:19:23.565 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:19:27.333 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:19:27.466 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:19:36.358 [http-nio-18080-exec-10] ERROR c.n.a.c.e.GlobalExceptionHandler - Unhandled exception
java-server | org.springframework.web.servlet.resource.NoResourceFoundException: No static resource .
java-server | at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:586)
java-server | at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
java-server | at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
java-server | at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
java-server | at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
java-server | at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
java-server | at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
java-server | at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
java-server | at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at com.nanri.aiimage.config.RequestTraceFilter.doFilterInternal(RequestTraceFilter.java:48)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
java-server | at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:479)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:340)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator.lambda$wrapSecured$0(ObservationFilterChainDecorator.java:82)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:128)
java-server | at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
java-server | at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:181)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
java-server | at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
java-server | at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82)
java-server | at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$0(ObservationFilterChainDecorator.java:323)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:224)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233)
java-server | at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
java-server | at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
java-server | at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195)
java-server | at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
java-server | at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
java-server | at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230)
java-server | at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:362)
java-server | at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:278)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:113)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
java-server | at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
java-server | at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
java-server | at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
java-server | at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
java-server | at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
java-server | at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
java-server | at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
java-server | at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
java-server | at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
java-server | at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
java-server | at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
java-server | at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
java-server | at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
java-server | at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
java-server | at java.base/java.lang.Thread.run(Thread.java:1583)
java-server | 2026-05-05 16:19:36.360 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/ status=200 remote=59.82.83.216 forwardedHost=121.196.149.225 forwardedProto=http forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.2231.103 Safari/537.36 costMs=4
java-server | 2026-05-05 16:19:36.459 [http-nio-18080-exec-9] ERROR c.n.a.c.e.GlobalExceptionHandler - Unhandled exception
java-server | org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
java-server | at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:586)
java-server | at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
java-server | at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
java-server | at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
java-server | at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
java-server | at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
java-server | at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
java-server | at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
java-server | at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at com.nanri.aiimage.config.RequestTraceFilter.doFilterInternal(RequestTraceFilter.java:48)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
java-server | at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:479)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:340)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator.lambda$wrapSecured$0(ObservationFilterChainDecorator.java:82)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:128)
java-server | at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
java-server | at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:181)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
java-server | at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
java-server | at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82)
java-server | at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:227)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$0(ObservationFilterChainDecorator.java:323)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$ObservationFilter.doFilter(ObservationFilterChainDecorator.java:224)
java-server | at org.springframework.security.web.ObservationFilterChainDecorator$VirtualFilterChain.doFilter(ObservationFilterChainDecorator.java:137)
java-server | at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233)
java-server | at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191)
java-server | at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
java-server | at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195)
java-server | at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113)
java-server | at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
java-server | at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230)
java-server | at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:362)
java-server | at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:278)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:113)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
java-server | at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
java-server | at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
java-server | at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
java-server | at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
java-server | at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
java-server | at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
java-server | at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
java-server | at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
java-server | at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
java-server | at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
java-server | at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
java-server | at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
java-server | at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
java-server | at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
java-server | at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
java-server | at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
java-server | at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
java-server | at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
java-server | at java.base/java.lang.Thread.run(Thread.java:1583)
java-server | 2026-05-05 16:19:36.463 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/favicon.ico status=200 remote=59.82.83.216 forwardedHost=121.196.149.225 forwardedProto=http forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.2231.103 Safari/537.36 costMs=5
java-server | 2026-05-05 16:19:37.465 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=29
java-server | 2026-05-05 16:19:37.606 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:19:37.877 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6384 status=SUCCESS
java-server | 2026-05-05 16:19:37.883 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6384/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=34
java-server | 2026-05-05 16:19:40.514 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:19:40.519 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:19:42.757 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:19:42.762 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:19:42.765 [http-nio-18080-exec-10] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/6586/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=211
java-server | 2026-05-05 16:19:47.603 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:19:47.719 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:19:47.736 [http-nio-18080-exec-6] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:19:47.741 [http-nio-18080-exec-6] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:19:56.837 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:19:56.842 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:19:57.745 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:19:57.860 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:20:00.005 [aiimage-scheduling-2] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:20:00.005 [aiimage-scheduling-1] INFO c.n.a.m.z.s.ZiniaoShopIndexRefreshService - [ziniao-index] skip refresh because another instance holds the distributed lock
java-server | 2026-05-05 16:20:00.013 [aiimage-scheduling-3] INFO c.n.a.m.b.service.BrandTaskService - [brand-stale-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:20:00.472 [http-nio-18080-exec-5] INFO c.n.a.m.t.s.TaskFileJobPublisher - [task-file-job] mq published jobId=1365 taskId=6594 moduleType=APPEARANCE_PATENT topic=aiimage-result-file-job
java-server | 2026-05-05 16:20:00.482 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/6594/result status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=221
java-server | 2026-05-05 16:20:00.585 [coze-task-0] INFO c.n.a.m.a.c.AppearancePatentCozeClient - [appearance-patent] coze request url=https://api.coze.cn/v1/workflow/run body={"workflow_id":"7632683471312355338","parameters":{"title_list":["KOPOX 170PCS Hook and Eye Sewing Kit with Garment Buttons, Hook and Eye Closures, Fabric Snap Buttons, Garment Snap Buttons for Skirts Pants Dresses, Clothing and DIY Crafts","WIRESTER Green Aluminum Round Bike Bell, Classic Ring Bicycle Bell, Bike Accessories Bell Ring for Adults Kids Girls Boys","Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can Bring Good Luck and Peace to Motorcycle Accessories","Motorcycle Bell - Bicycle Bells for Men, Stainless Steel Bring Good Luck and Peace","Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can bring good luck and peace to motorcycle accessories","Motorcycle for Bell, Bicycle Bells for Men, Stainless Steel Brings Good Luck and Peace for Motorcycle Accessories, One Size, Metal, Una talla, Metal","Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel Provides Good Treats and Peace for Motorcycle Accessories, Metal, No Gemstone, Metal, No Gemstone","Motorcycle for Bells - Bicycle bells for men, stainless steel can bring good luck and peace to motorcycle accessories"],"url_list":["https://m.media-amazon.com/images/I/91KtKyLQstL._AC_SX425_.jpg","https://m.media-amazon.com/images/I/51dETWpSQXL._AC_SX466_.jpg","https://m.media-amazon.com/images/I/81vJjZcgf5L._AC_SX466_.jpg","https://m.media-amazon.com/images/I/71sGtlqHXzL._AC_SX466_.jpg","https://m.media-amazon.com/images/I/71IzidKhklL._AC_SX385_.jpg","https://m.media-amazon.com/images/I/71ASKPXDUHL._AC_SX385_.jpg","https://m.media-amazon.com/images/I/71jfXEIPGOL._AC_SX385_.jpg","https://m.media-amazon.com/images/I/71tYUk0XWvL._AC_SX466_.jpg"],"items":[{"group_key":"f037a1b87dbf486d940ea2e25f194027::1@2","row_id":"1","asin":"B0D792ND9V","country":"英国","title":"KOPOX 170PCS Hook and Eye Sewing Kit with Garment Buttons, Hook and Eye Closures, Fabric Snap Buttons, Garment Snap Buttons for Skirts Pants Dresses, Clothing and DIY Crafts","url":"https://m.media-amazon.com/images/I/91KtKyLQstL._AC_SX425_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::2@3","row_id":"2_1","asin":"B0D14L34S7","country":"英国","title":"WIRESTER Green Aluminum Round Bike Bell, Classic Ring Bicycle Bell, Bike Accessories Bell Ring for Adults Kids Girls Boys","url":"https://m.media-amazon.com/images/I/51dETWpSQXL._AC_SX466_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::3@7","row_id":"3_1","asin":"B0CWQFZMGY","country":"英国","title":"Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can Bring Good Luck and Peace to Motorcycle Accessories","url":"https://m.media-amazon.com/images/I/81vJjZcgf5L._AC_SX466_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::4@9","row_id":"4_1","asin":"B0CX87XXWJ","country":"英国","title":"Motorcycle Bell - Bicycle Bells for Men, Stainless Steel Bring Good Luck and Peace","url":"https://m.media-amazon.com/images/I/71sGtlqHXzL._AC_SX466_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::5@10","row_id":"5_1","asin":"B0CR3PMR8L","country":"英国","title":"Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can bring good luck and peace to motorcycle accessories","url":"https://m.media-amazon.com/images/I/71IzidKhklL._AC_SX385_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::6@11","row_id":"6","asin":"B0DK3L6FD4","country":"英国","title":"Motorcycle for Bell, Bicycle Bells for Men, Stainless Steel Brings Good Luck and Peace for Motorcycle Accessories, One Size, Metal, Una talla, Metal","url":"https://m.media-amazon.com/images/I/71ASKPXDUHL._AC_SX385_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::8@12","row_id":"8","asin":"B0D9QNV6FT","country":"英国","title":"Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel Provides Good Treats and Peace for Motorcycle Accessories, Metal, No Gemstone, Metal, No Gemstone","url":"https://m.media-amazon.com/images/I/71jfXEIPGOL._AC_SX385_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::10@13","row_id":"10_1","asin":"B0DBZG716J","country":"英国","title":"Motorcycle for Bells - Bicycle bells for men, stainless steel can bring good luck and peace to motorcycle accessories","url":"https://m.media-amazon.com/images/I/71tYUk0XWvL._AC_SX466_.jpg"}],"prompt":"请帮我排查以下亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。 请直接给出明确结论(有侵权风险 或 未发现明显侵权风险),并严格按照以下三个维度提供精简的排查理由: 外观维度: 评估产品外形、图案设计是否与欧洲/英国常见外观专利雷同。 专利维度: 评估产品的核心技术或物理结构是否存在侵权可能。 标题维度: 排查标题中是否包含大牌商标、敏感词或版权保护词汇。 结论XX"},"is_async":true}
java-server | 2026-05-05 16:20:00.967 [coze-task-0] INFO c.n.a.m.a.c.AppearancePatentCozeClient - [appearance-patent] coze submit response status=200 OK body={"execute_id":"7636319564359794723","detail":{"logid":"202605051620001443DB557D71573D26D7"},"code":0,"msg":"","debug_url":"https://www.coze.cn/work_flow?execute_id=7636319564359794723&space_id=7519005192466022436&workflow_id=7632683471312355338&execute_mode=2"}
java-server | 2026-05-05 16:20:01.005 [coze-task-0] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze async submitted taskId=6594 jobId=1365 chunk=8 batch=1/1 executeId=7636319564359794723
java-server | 2026-05-05 16:20:01.081 [coze-task-0] INFO c.n.a.m.t.s.TaskResultFileJobWorker - [task-file-job] process deferred jobId=1365 taskId=6594 moduleType=APPEARANCE_PATENT resultId=8943 elapsedMs=580
java-server | 2026-05-05 16:20:01.237 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:01.237 [coze-task-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:01.284 [coze-task-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll start taskId=6594 stateId=4138 executeId=7636319564359794723 jobId=1365 chunk=8 batch=1/1
java-server | 2026-05-05 16:20:01.405 [coze-task-1] INFO c.n.a.m.a.c.AppearancePatentCozeClient - [appearance-patent] coze history response executeId=7636319564359794723 status=200 OK body={"code":0,"msg":"","data":[{"debug_url":"https://www.coze.cn/work_flow?execute_id=7636319564359794723&space_id=7519005192466022436&workflow_id=7632683471312355338&execute_mode=2","output":"{\"node_status\":\"{}\",\"Output\":\"\"}","error_code":"","update_time":1777969201,"token":"0","usage":{"token_count":0,"output_count":0,"input_count":0},"connector_id":"1024","create_time":1777969201,"is_output_trimmed":false,"connector_uid":"2939430754097600","run_mode":2,"node_execute_status":{},"execute_id":"7636319564359794723","bot_id":"0","execute_status":"Running","logid":"202605051620001443DB557D71573D26D7"}],"detail":{"logid":"20260505162001F6047AEE90C5EC5A6965"}}
java-server | 2026-05-05 16:20:01.406 [coze-task-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll pending taskId=6594 stateId=4138 executeId=7636319564359794723 status=RUNNING
java-server | 2026-05-05 16:20:06.256 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:06.256 [coze-task-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:06.270 [coze-task-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:06
java-server | 2026-05-05 16:20:07.863 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:20:07.975 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:20:10.506 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:20:10.512 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:20:11.274 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:11.274 [coze-task-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:11.293 [coze-task-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:11
java-server | 2026-05-05 16:20:16.292 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:16.292 [coze-task-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:16.306 [coze-task-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:16
java-server | 2026-05-05 16:20:18.009 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=31
java-server | 2026-05-05 16:20:18.133 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:20:19.379 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:20:19.385 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:20:21.309 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:21.309 [coze-task-5] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:21.328 [coze-task-5] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:21
java-server | 2026-05-05 16:20:22.521 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:20:22.527 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:20:26.328 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:26.328 [coze-task-6] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:26.343 [coze-task-6] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:26
java-server | 2026-05-05 16:20:28.139 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:20:28.264 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:20:30.005 [aiimage-scheduling-1] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [finalize-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:20:31.346 [aiimage-scheduling-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:31.346 [coze-task-7] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:31.360 [coze-task-7] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:31
java-server | 2026-05-05 16:20:35.362 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:20:35.368 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:20:36.364 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:36.364 [coze-task-8] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:36.378 [coze-task-8] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:36
java-server | 2026-05-05 16:20:38.275 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:20:38.386 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:20:41.383 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:41.383 [coze-task-9] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:41.402 [coze-task-9] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:41
java-server | 2026-05-05 16:20:44.456 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:20:44.461 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:20:46.402 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:46.402 [coze-task-10] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:46.416 [coze-task-10] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:46
java-server | 2026-05-05 16:20:48.410 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=30
java-server | 2026-05-05 16:20:48.525 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=21
java-server | 2026-05-05 16:20:51.081 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:20:51.087 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:20:51.419 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:51.419 [coze-task-11] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:51.438 [coze-task-11] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:51
java-server | 2026-05-05 16:20:56.438 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:20:56.438 [coze-task-12] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:20:56.454 [coze-task-12] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:20:56
java-server | 2026-05-05 16:20:58.564 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=34
java-server | 2026-05-05 16:20:58.691 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=22
java-server | 2026-05-05 16:20:59.581 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:20:59.587 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:21:01.456 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:21:01.456 [coze-task-13] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4138 taskId=6594 executeId=7636319564359794723
java-server | 2026-05-05 16:21:01.469 [coze-task-13] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6594 stateId=4138 executeId=7636319564359794723 lastPolledAt=2026-05-05T16:21:01
java-server | 2026-05-05 16:21:03.723 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6449 status=FAILED
java-server | 2026-05-05 16:21:03.728 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6449/result status=200 remote=8.139.195.39 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=33
java-server | 2026-05-05 16:21:08.709 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:21:08.822 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:21:13.311 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:21:13.316 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:18.832 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=22
java-server | 2026-05-05 16:21:18.950 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:21:19.067 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/history status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:21:22.898 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:21:22.904 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:24.906 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/results/8943/download status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=142
java-server | 2026-05-05 16:21:26.669 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:21:26.675 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:28.958 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:21:29.068 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:21:31.247 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:21:31.252 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:35.479 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6378 status=SUCCESS
java-server | 2026-05-05 16:21:35.484 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6378/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:39.074 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=19
java-server | 2026-05-05 16:21:39.180 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:21:43.039 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6331 status=SUCCESS
java-server | 2026-05-05 16:21:43.044 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6331/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:45.526 [http-nio-18080-exec-9] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] parse timing taskId=6595 files=1 rows=12 groups=8 totalMs=98 parseMs=20 groupMs=0 taskInsertMs=17 payloadJsonMs=0 payloadStoreMs=4 persistMs=54 responseMs=0
java-server | 2026-05-05 16:21:45.527 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/parse status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=100
java-server | 2026-05-05 16:21:45.768 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6403 status=SUCCESS
java-server | 2026-05-05 16:21:45.773 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6403/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=34
java-server | 2026-05-05 16:21:46.730 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:21:46.736 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=24
java-server | 2026-05-05 16:21:46.811 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/6595/activate status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=47
java-server | 2026-05-05 16:21:46.934 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:21:47.075 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/history status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=40
java-server | 2026-05-05 16:21:49.205 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:21:49.313 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:21:55.237 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:21:55.243 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:21:59.346 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:21:59.460 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:22:00.004 [aiimage-scheduling-4] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:22:00.013 [aiimage-scheduling-3] INFO c.n.a.m.b.service.BrandTaskService - [brand-stale-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:22:01.969 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:22:01.975 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:22:05.389 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:22:05.394 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:22:09.473 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:22:09.602 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:22:19.607 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:22:19.742 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:22:20.372 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:22:20.377 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:22:20.942 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6280 status=SUCCESS
java-server | 2026-05-05 16:22:20.947 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6280/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=25
java-server | 2026-05-05 16:22:25.123 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:22:25.128 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:22:29.758 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:22:29.890 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:22:30.004 [aiimage-scheduling-2] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [finalize-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:22:36.061 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:22:36.067 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:22:38.294 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:22:38.299 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:22:39.882 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:22:40.013 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=19
java-server | 2026-05-05 16:22:50.019 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:22:50.132 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:22:52.102 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:22:52.107 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=29
java-server | 2026-05-05 16:22:53.681 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:22:53.686 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:23:00.157 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:23:00.271 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=21
java-server | 2026-05-05 16:23:03.853 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6356 status=SUCCESS
java-server | 2026-05-05 16:23:03.858 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6356/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:23:09.399 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:23:09.405 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:23:10.306 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:23:10.427 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:23:11.669 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:23:11.675 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:23:20.447 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:23:20.568 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:23:27.437 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:23:27.442 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:23:30.501 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:23:30.507 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=30
java-server | 2026-05-05 16:23:30.580 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:23:30.706 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:23:40.719 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=28
java-server | 2026-05-05 16:23:40.897 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:23:43.488 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:23:43.494 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:23:50.892 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:23:51.027 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:23:51.651 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:23:51.656 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:23:58.091 [http-nio-18080-exec-7] INFO c.n.a.m.t.s.TaskFileJobPublisher - [task-file-job] mq published jobId=1366 taskId=6595 moduleType=APPEARANCE_PATENT topic=aiimage-result-file-job
java-server | 2026-05-05 16:23:58.100 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/6595/result status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=174
java-server | 2026-05-05 16:23:58.178 [coze-task-14] INFO c.n.a.m.a.c.AppearancePatentCozeClient - [appearance-patent] coze request url=https://api.coze.cn/v1/workflow/run body={"workflow_id":"7632683471312355338","parameters":{"title_list":["KOPOX 170PCS Hook and Eye Sewing Kit with Garment Buttons, Hook and Eye Closures, Fabric Snap Buttons, Garment Snap Buttons for Skirts Pants Dresses, Clothing and DIY Crafts","WIRESTER Green Aluminum Round Bike Bell, Classic Ring Bicycle Bell, Bike Accessories Bell Ring for Adults Kids Girls Boys","Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can Bring Good Luck and Peace to Motorcycle Accessories","Motorcycle Bell - Bicycle Bells for Men, Stainless Steel Bring Good Luck and Peace","Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can bring good luck and peace to motorcycle accessories","Motorcycle for Bell, Bicycle Bells for Men, Stainless Steel Brings Good Luck and Peace for Motorcycle Accessories, One Size, Metal, Una talla, Metal","Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel Provides Good Treats and Peace for Motorcycle Accessories, Metal, No Gemstone, Metal, No Gemstone","Motorcycle for Bells - Bicycle bells for men, stainless steel can bring good luck and peace to motorcycle accessories"],"url_list":["https://m.media-amazon.com/images/I/91KtKyLQstL._AC_SX425_.jpg","https://m.media-amazon.com/images/I/51dETWpSQXL._AC_SX466_.jpg","https://m.media-amazon.com/images/I/81vJjZcgf5L._AC_SX466_.jpg","https://m.media-amazon.com/images/I/71sGtlqHXzL._AC_SX466_.jpg","https://m.media-amazon.com/images/I/71IzidKhklL._AC_SX385_.jpg","https://m.media-amazon.com/images/I/71ASKPXDUHL._AC_SX385_.jpg","https://m.media-amazon.com/images/I/71jfXEIPGOL._AC_SX385_.jpg","https://m.media-amazon.com/images/I/71tYUk0XWvL._AC_SX466_.jpg"],"items":[{"group_key":"f037a1b87dbf486d940ea2e25f194027::1@2","row_id":"1","asin":"B0D792ND9V","country":"英国","title":"KOPOX 170PCS Hook and Eye Sewing Kit with Garment Buttons, Hook and Eye Closures, Fabric Snap Buttons, Garment Snap Buttons for Skirts Pants Dresses, Clothing and DIY Crafts","url":"https://m.media-amazon.com/images/I/91KtKyLQstL._AC_SX425_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::2@3","row_id":"2_1","asin":"B0D14L34S7","country":"英国","title":"WIRESTER Green Aluminum Round Bike Bell, Classic Ring Bicycle Bell, Bike Accessories Bell Ring for Adults Kids Girls Boys","url":"https://m.media-amazon.com/images/I/51dETWpSQXL._AC_SX466_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::3@7","row_id":"3_1","asin":"B0CWQFZMGY","country":"英国","title":"Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can Bring Good Luck and Peace to Motorcycle Accessories","url":"https://m.media-amazon.com/images/I/81vJjZcgf5L._AC_SX466_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::4@9","row_id":"4_1","asin":"B0CX87XXWJ","country":"英国","title":"Motorcycle Bell - Bicycle Bells for Men, Stainless Steel Bring Good Luck and Peace","url":"https://m.media-amazon.com/images/I/71sGtlqHXzL._AC_SX466_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::5@10","row_id":"5_1","asin":"B0CR3PMR8L","country":"英国","title":"Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel can bring good luck and peace to motorcycle accessories","url":"https://m.media-amazon.com/images/I/71IzidKhklL._AC_SX385_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::6@11","row_id":"6","asin":"B0DK3L6FD4","country":"英国","title":"Motorcycle for Bell, Bicycle Bells for Men, Stainless Steel Brings Good Luck and Peace for Motorcycle Accessories, One Size, Metal, Una talla, Metal","url":"https://m.media-amazon.com/images/I/71ASKPXDUHL._AC_SX385_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::8@12","row_id":"8","asin":"B0D9QNV6FT","country":"英国","title":"Motorcycle for Bells - Bicycle Bells for Men, Stainless Steel Provides Good Treats and Peace for Motorcycle Accessories, Metal, No Gemstone, Metal, No Gemstone","url":"https://m.media-amazon.com/images/I/71jfXEIPGOL._AC_SX385_.jpg"},{"group_key":"f037a1b87dbf486d940ea2e25f194027::10@13","row_id":"10_1","asin":"B0DBZG716J","country":"英国","title":"Motorcycle for Bells - Bicycle bells for men, stainless steel can bring good luck and peace to motorcycle accessories","url":"https://m.media-amazon.com/images/I/71tYUk0XWvL._AC_SX466_.jpg"}],"prompt":"请帮我排查以下亚马逊商品在英国及欧洲地区是否存在知识产权侵权风险。 请直接给出明确结论(有侵权风险 或 未发现明显侵权风险),并严格按照以下三个维度提供精简的排查理由: 外观维度: 评估产品外形、图案设计是否与欧洲/英国常见外观专利雷同。 专利维度: 评估产品的核心技术或物理结构是否存在侵权可能。 标题维度: 排查标题中是否包含大牌商标、敏感词或版权保护词汇。 结论XX"},"is_async":true}
java-server | 2026-05-05 16:23:58.351 [coze-task-14] INFO c.n.a.m.a.c.AppearancePatentCozeClient - [appearance-patent] coze submit response status=200 OK body={"execute_id":"7636320588616892443","detail":{"logid":"20260505162358630B5DA5EDD272894E15"},"code":0,"msg":"","debug_url":"https://www.coze.cn/work_flow?execute_id=7636320588616892443&space_id=7519005192466022436&workflow_id=7632683471312355338&execute_mode=2"}
java-server | 2026-05-05 16:23:58.377 [coze-task-14] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze async submitted taskId=6595 jobId=1366 chunk=8 batch=1/1 executeId=7636320588616892443
java-server | 2026-05-05 16:23:58.433 [coze-task-14] INFO c.n.a.m.t.s.TaskResultFileJobWorker - [task-file-job] process deferred jobId=1366 taskId=6595 moduleType=APPEARANCE_PATENT resultId=8944 elapsedMs=322
java-server | 2026-05-05 16:23:58.489 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:23:58.494 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:24:00.004 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] scan started thread=aiimage-scheduling-3
java-server | 2026-05-05 16:24:00.037 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] product-risk summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=33 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:24:00.037 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] price-track summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=33 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:24:00.037 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] shop-match summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=33 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:24:00.037 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] patrol-delete summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=33 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:24:01.024 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:24:01.159 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:24:02.099 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:02.100 [coze-task-15] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:02.113 [coze-task-15] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:02
java-server | 2026-05-05 16:24:07.117 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:07.118 [coze-task-16] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:07.135 [coze-task-16] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:07
java-server | 2026-05-05 16:24:08.518 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:24:08.523 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:24:11.173 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:24:11.283 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:24:12.135 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:12.135 [coze-task-17] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:12.151 [coze-task-17] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:12
java-server | 2026-05-05 16:24:16.059 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:24:16.064 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:24:17.152 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:17.153 [coze-task-18] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:17.170 [coze-task-18] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:17
java-server | 2026-05-05 16:24:21.306 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:24:21.417 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:24:22.171 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:22.171 [coze-task-19] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:22.185 [coze-task-19] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:22
java-server | 2026-05-05 16:24:27.189 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:27.189 [coze-task-20] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:27.208 [coze-task-20] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:27
java-server | 2026-05-05 16:24:30.301 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:24:30.306 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:24:30.950 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:24:30.955 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=24
java-server | 2026-05-05 16:24:31.446 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:24:31.559 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:24:32.206 [aiimage-scheduling-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:32.206 [coze-task-21] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:32.224 [coze-task-21] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:32
java-server | 2026-05-05 16:24:37.224 [aiimage-scheduling-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:37.224 [coze-task-22] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:37.237 [coze-task-22] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:37
java-server | 2026-05-05 16:24:41.586 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:24:41.701 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:24:42.242 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:42.242 [coze-task-23] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:42.260 [coze-task-23] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:42
java-server | 2026-05-05 16:24:44.457 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:24:44.462 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:24:47.260 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:47.260 [coze-task-24] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:47.273 [coze-task-24] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:47
java-server | 2026-05-05 16:24:51.723 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:24:51.838 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=17
java-server | 2026-05-05 16:24:52.276 [aiimage-scheduling-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:52.276 [coze-task-25] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:52.290 [coze-task-25] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:52
java-server | 2026-05-05 16:24:54.602 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6383 status=SUCCESS
java-server | 2026-05-05 16:24:54.607 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6383/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=32
java-server | 2026-05-05 16:24:57.294 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:24:57.294 [coze-task-26] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:24:57.312 [coze-task-26] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:24:57
java-server | 2026-05-05 16:24:57.425 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:24:57.430 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:25:01.851 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:25:01.996 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=19
java-server | 2026-05-05 16:25:02.311 [aiimage-scheduling-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:02.311 [coze-task-27] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:02.324 [coze-task-27] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:02
java-server | 2026-05-05 16:25:02.957 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:25:02.963 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:25:06.882 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:25:06.887 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:25:07.327 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:07.328 [coze-task-28] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:07.345 [coze-task-28] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:07
java-server | 2026-05-05 16:25:11.977 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:25:12.086 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=19
java-server | 2026-05-05 16:25:12.341 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:12.341 [coze-task-29] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:12.355 [coze-task-29] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:12
java-server | 2026-05-05 16:25:14.298 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/6586/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=156
java-server | 2026-05-05 16:25:17.359 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:17.360 [coze-task-30] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:17.377 [coze-task-30] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:17
java-server | 2026-05-05 16:25:17.937 [http-nio-18080-exec-3] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:25:17.942 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:25:22.123 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:25:22.227 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:25:22.376 [aiimage-scheduling-2] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:22.376 [coze-task-31] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:22.390 [coze-task-31] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:22
java-server | 2026-05-05 16:25:27.394 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:27.394 [coze-task-32] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:27.411 [coze-task-32] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:27
java-server | 2026-05-05 16:25:31.413 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:25:31.418 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:25:32.266 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=27
java-server | 2026-05-05 16:25:32.396 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:25:32.411 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:32.411 [coze-task-33] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:32.425 [coze-task-33] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:32
java-server | 2026-05-05 16:25:35.252 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:25:35.257 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:25:37.429 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:37.429 [coze-task-34] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:37.442 [coze-task-34] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:37
java-server | 2026-05-05 16:25:39.554 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6435 status=SUCCESS
java-server | 2026-05-05 16:25:39.560 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6435/result status=200 remote=8.139.195.39 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=33
java-server | 2026-05-05 16:25:41.409 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:25:41.414 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:25:42.409 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=26
java-server | 2026-05-05 16:25:42.445 [aiimage-scheduling-1] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:42.446 [coze-task-35] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:42.459 [coze-task-35] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:42
java-server | 2026-05-05 16:25:42.527 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:25:47.464 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:47.464 [coze-task-36] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:47.478 [coze-task-36] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:47
java-server | 2026-05-05 16:25:52.481 [aiimage-scheduling-3] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:52.481 [coze-task-37] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:52.499 [coze-task-37] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:52
java-server | 2026-05-05 16:25:52.554 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=21
java-server | 2026-05-05 16:25:52.672 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:25:57.172 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:25:57.177 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:25:57.499 [aiimage-scheduling-4] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll picked pending states count=1
java-server | 2026-05-05 16:25:57.499 [coze-task-38] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll worker entered stateId=4141 taskId=6595 executeId=7636320588616892443
java-server | 2026-05-05 16:25:57.512 [coze-task-38] INFO c.n.a.m.a.s.AppearancePatentTaskService - [appearance-patent] coze poll skipped by claim guard taskId=6595 stateId=4141 executeId=7636320588616892443 lastPolledAt=2026-05-05T16:25:57
java-server | 2026-05-05 16:26:00.004 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] scan started thread=aiimage-scheduling-3
java-server | 2026-05-05 16:26:00.033 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] product-risk summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=29 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:26:00.033 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] price-track summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=29 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:26:00.033 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] shop-match summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=29 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:26:00.033 [aiimage-scheduling-3] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [stale-check] patrol-delete summary scanned=0 finalized=0 failed=0 skipped=0 elapsedMs=29 thread=aiimage-scheduling-3
java-server | 2026-05-05 16:26:02.669 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=23
java-server | 2026-05-05 16:26:02.775 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=15
java-server | 2026-05-05 16:26:06.707 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:26:06.712 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:26:08.604 [http-nio-18080-exec-7] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6325 status=SUCCESS
java-server | 2026-05-05 16:26:08.609 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6325/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:26:12.798 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=22
java-server | 2026-05-05 16:26:12.903 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:26:13.013 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/history status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=18
java-server | 2026-05-05 16:26:14.912 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6329 status=SUCCESS
java-server | 2026-05-05 16:26:14.918 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6329/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:26:17.829 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/results/8944/download status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=94
java-server | 2026-05-05 16:26:19.674 [http-nio-18080-exec-9] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6269 status=SUCCESS
java-server | 2026-05-05 16:26:19.679 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6269/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27
java-server | 2026-05-05 16:26:22.908 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:26:23.021 [http-nio-18080-exec-3] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=16
java-server | 2026-05-05 16:26:29.144 [http-nio-18080-exec-5] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6348 status=SUCCESS
java-server | 2026-05-05 16:26:29.150 [http-nio-18080-exec-5] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6348/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=28
java-server | 2026-05-05 16:26:30.004 [aiimage-scheduling-4] INFO c.n.a.m.d.s.DeleteBrandStaleTaskService - [finalize-check] skip because another instance holds the distributed lock
java-server | 2026-05-05 16:26:33.031 [http-nio-18080-exec-7] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/appearance-patent/tasks/progress/batch status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=11
java-server | 2026-05-05 16:26:33.142 [http-nio-18080-exec-9] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=GET uri=/api/appearance-patent/dashboard status=200 remote=171.222.250.173 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0 costMs=20
java-server | 2026-05-05 16:26:38.915 [http-nio-18080-exec-1] WARN c.n.a.m.p.s.PriceTrackTaskService - [price-track] submitResult rejected taskId=6323 status=SUCCESS
java-server | 2026-05-05 16:26:38.920 [http-nio-18080-exec-1] INFO c.n.a.config.RequestTraceFilter - request-trace instance=81fe57de426c host=81fe57de426c method=POST uri=/api/price-track/tasks/6323/result status=200 remote=121.199.179.245 forwardedHost=121.196.149.225:18080 forwardedProto=- forwardedPort=- requestId=- userAgent=python-requests/2.32.5 costMs=27

38458
java-server-20260505163034.log Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,18 +1,18 @@
<!doctype html> <!doctype html>
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>外观专利检测</title> <title>外观专利检测</title>
<script type="module" crossorigin src="/assets/appearance-patent.js"></script> <script type="module" crossorigin src="/assets/appearance-patent.js"></script>
<link rel="modulepreload" crossorigin href="/assets/pywebview-BWNiqXug.js"> <link rel="modulepreload" crossorigin href="/assets/pywebview-RBTI4RuH.js">
<link rel="modulepreload" crossorigin href="/assets/brand-CABpTGPu.js"> <link rel="modulepreload" crossorigin href="/assets/brand-1lGM3Wzk.js">
<link rel="modulepreload" crossorigin href="/assets/categorized-timers-JPA-olTr.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/pywebview-C-qhaDJK.css">
<link rel="stylesheet" crossorigin href="/assets/appearance-patent-TI-osB39.css"> <link rel="stylesheet" crossorigin href="/assets/appearance-patent-DaODE9AU.css">
<link rel="stylesheet" crossorigin href="/assets/el-table-column-Cy4YJvw0.css"> <link rel="stylesheet" crossorigin href="/assets/el-table-column-Cy4YJvw0.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
</body>
</body> </html>

View File

@@ -0,0 +1,18 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>相似ASIN检测</title>
<script type="module" crossorigin src="/assets/similar-asin.js"></script>
<link rel="modulepreload" crossorigin href="/assets/pywebview-RBTI4RuH.js">
<link rel="modulepreload" crossorigin href="/assets/brand-1lGM3Wzk.js">
<link rel="modulepreload" crossorigin href="/assets/categorized-timers-JPA-olTr.js">
<link rel="stylesheet" crossorigin href="/assets/pywebview-C-qhaDJK.css">
<link rel="stylesheet" crossorigin href="/assets/similar-asin-B2xrJRis.css">
<link rel="stylesheet" crossorigin href="/assets/el-table-column-Cy4YJvw0.css">
</head>
<body>
<div id="app"></div>
</body>
</html>