From 92ab782943c1c5b188dcbecefc799087ff6a8c6d Mon Sep 17 00:00:00 2001 From: zhangzijienbplus <17738440858@163.com> Date: Mon, 10 Nov 2025 11:21:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor(utils):=E4=BC=98=E5=8C=96=E5=95=86?= =?UTF-8?q?=E6=A0=87=E6=9F=A5=E8=AF=A2=E9=87=8D=E8=AF=95=E6=9C=BA=E5=88=B6?= =?UTF-8?q?-=20=E5=B0=86=E5=88=9D=E5=A7=8B=E5=8C=96=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E6=AC=A1=E6=95=B0=E4=BB=8E3=E6=AC=A1?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=B05=E6=AC=A1=20-=20=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=9F=A5=E8=AF=A2=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8D=95=E4=B8=AA=E5=93=81=E7=89=8C=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E9=87=8D=E8=AF=95-=20=E6=B7=BB=E5=8A=A0=E9=92=88?= =?UTF-8?q?=E5=AF=B9HTTP=20403=E3=80=81=E7=BD=91=E7=BB=9C=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=AD=89=E5=BC=82=E5=B8=B8=E7=9A=84=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E6=9C=BA=E5=88=B6-=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E8=84=9A=E6=9C=AC=E6=9E=84=E9=80=A0=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E6=8F=90=E9=AB=98=E6=89=A7=E8=A1=8C=E7=A8=B3?= =?UTF-8?q?=E5=AE=9A=E6=80=A7=20-=20=E5=A2=9E=E5=BC=BA=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=92=8C=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20-=20=E7=A7=BB=E9=99=A4=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E4=B8=AD=E5=86=97=E4=BD=99=E7=9A=84=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../erp/controller/TrademarkController.java | 5 +- .../tashow/erp/utils/TrademarkCheckUtil.java | 181 +++++++++--------- 2 files changed, 88 insertions(+), 98 deletions(-) diff --git a/erp_client_sb/src/main/java/com/tashow/erp/controller/TrademarkController.java b/erp_client_sb/src/main/java/com/tashow/erp/controller/TrademarkController.java index bc87519..49ffa2e 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/controller/TrademarkController.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/controller/TrademarkController.java @@ -21,7 +21,7 @@ import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; /** - * 商标检查控制器 - 极速版(浏览器内并发) + * 商标检查控制器 */ @RestController @RequestMapping("/api/trademark") @@ -63,12 +63,9 @@ public class TrademarkController { .filter(b -> b != null && !b.trim().isEmpty()) .map(String::trim) .collect(Collectors.toList()); - long start = System.currentTimeMillis(); - // 1. 先从全局缓存获取 Map cached = cacheService.getCached(list); - // 2. 找出缓存未命中的品牌 List toQuery = list.stream() .filter(b -> !cached.containsKey(b)) diff --git a/erp_client_sb/src/main/java/com/tashow/erp/utils/TrademarkCheckUtil.java b/erp_client_sb/src/main/java/com/tashow/erp/utils/TrademarkCheckUtil.java index 675cbce..e96ab38 100644 --- a/erp_client_sb/src/main/java/com/tashow/erp/utils/TrademarkCheckUtil.java +++ b/erp_client_sb/src/main/java/com/tashow/erp/utils/TrademarkCheckUtil.java @@ -28,7 +28,7 @@ public class TrademarkCheckUtil { Thread.sleep(6000); return; // 成功则返回 } catch (Exception e) { - System.err.println("初始化失败(尝试" + (i+1) + "/3): " + e.getMessage()); + System.err.println("初始化失败(尝试" + (i+1) + "/5): " + e.getMessage()); if (driver != null) { try { driver.quit(); } catch (Exception ex) {} driver = null; @@ -40,106 +40,99 @@ public class TrademarkCheckUtil { } public synchronized Map batchCheck(List brands, Map alreadyQueried) { - ensureInit(); - - // 构建批量查询脚本(带错误诊断) - String script = """ - const brands = arguments[0]; - const callback = arguments[arguments.length - 1]; - - Promise.all(brands.map(brand => - fetch('https://tmsearch.uspto.gov/prod-stage-v1-0-0/tmsearch', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ - query: {bool: {must: [{bool: {should: [ - {match_phrase: {WM: {query: brand, boost: 5}}}, - {match: {WM: {query: brand, boost: 2}}}, - {match_phrase: {PM: {query: brand, boost: 2}}} - ]}}]}}, - size: 1, _source: ['alive'] - }) - }) - .then(r => { - if (!r.ok) { - return {brand, alive: false, error: `HTTP ${r.status}: ${r.statusText}`}; - } - return r.json().then(d => ({ - brand, - alive: d?.hits?.hits?.[0]?.source?.alive || false, - error: null - })); - }) - .catch(e => ({ - brand, - alive: false, - error: e.name + ': ' + e.message - })) - )).then(callback); - """; - - try { - @SuppressWarnings("unchecked") - List> results = (List>) - ((JavascriptExecutor) driver).executeAsyncScript(script, brands); - - // 检测是否有网络错误(包括403、Failed to fetch等) - boolean hasNetworkError = results.stream() - .anyMatch(item -> { + Map resultMap = new HashMap<>(); + int maxRetries = 5; + + for (String brand : brands) { + int retryCount = 0; + boolean success = false; + + while (retryCount < maxRetries && !success) { + try { + ensureInit(); + + String script = "const brands = ['" + brand.replace("'", "\\'") + "'];\n" + + "const callback = arguments[arguments.length - 1];\n" + + "Promise.all(brands.map(b => \n" + + " fetch('https://tmsearch.uspto.gov/prod-stage-v1-0-0/tmsearch', {\n" + + " method: 'POST',\n" + + " headers: {'Content-Type': 'application/json'},\n" + + " body: JSON.stringify({\n" + + " query: {bool: {must: [{bool: {should: [\n" + + " {match_phrase: {WM: {query: b, boost: 5}}},\n" + + " {match: {WM: {query: b, boost: 2}}},\n" + + " {match_phrase: {PM: {query: b, boost: 2}}}\n" + + " ]}}]}},\n" + + " size: 1, _source: ['alive']\n" + + " })\n" + + " })\n" + + " .then(r => {\n" + + " if (!r.ok) {\n" + + " return {brand: b, alive: false, error: 'HTTP ' + r.status + ': ' + r.statusText};\n" + + " }\n" + + " return r.json().then(d => ({\n" + + " brand: b,\n" + + " alive: d?.hits?.hits?.[0]?.source?.alive || false,\n" + + " error: null\n" + + " }));\n" + + " })\n" + + " .catch(e => ({\n" + + " brand: b,\n" + + " alive: false,\n" + + " error: e.name + ': ' + e.message\n" + + " }))\n" + + ")).then(callback);"; + + @SuppressWarnings("unchecked") + List> results = (List>) + ((JavascriptExecutor) driver).executeAsyncScript(script); + + Map item = results.get(0); String error = (String) item.get("error"); - return error != null && ( - error.contains("HTTP 403") || + + if (error != null && ( + error.contains("HTTP 403") || error.contains("Failed to fetch") || error.contains("NetworkError") || - error.contains("TypeError") - ); - }); - - // 如果有网络错误,切换代理并重试 - if (hasNetworkError) { - System.err.println("检测到网络错误,切换代理并重试..."); - - // 切换代理前保存已查询的品牌 - if (alreadyQueried != null && !alreadyQueried.isEmpty()) { - try { - cacheService.saveResults(alreadyQueried); - System.out.println("代理切换,已保存 " + alreadyQueried.size() + " 个品牌到缓存"); - } catch (Exception e) { - System.err.println("保存缓存失败: " + e.getMessage()); + error.contains("TypeError") || + error.contains("script timeout"))) { + + System.err.println(brand + " 查询失败(" + (retryCount + 1) + "/" + maxRetries + "): " + error + ",切换代理..."); + + // 切换代理 + try { driver.quit(); } catch (Exception e) {} + driver = null; + retryCount++; + continue; } - } - - try { driver.quit(); } catch (Exception e) {} - driver = null; - ensureInit(); - - // 重新执行查询 - @SuppressWarnings("unchecked") - List> retryResults = (List>) - ((JavascriptExecutor) driver).executeAsyncScript(script, brands); - results = retryResults; - } - - Map resultMap = new HashMap<>(); - for (Map item : results) { - String brand = (String) item.get("brand"); - Boolean alive = (Boolean) item.get("alive"); - String error = (String) item.get("error"); - - if (error != null) { - // 查询失败,不放入结果,只打印错误 - System.err.println(brand + " -> [查询失败: " + error + "]"); - } else { - // 查询成功,放入结果 - resultMap.put(brand, alive); - System.out.println(brand + " -> " + (alive ? "✓ 已注册" : "✗ 未注册")); + + // 成功或非网络错误 + if (error == null) { + Boolean alive = (Boolean) item.get("alive"); + resultMap.put(brand, alive); + System.out.println(brand + " -> " + (alive ? "✓ 已注册" : "✗ 未注册")); + success = true; + } else { + System.err.println(brand + " -> [查询失败: " + error + "]"); + resultMap.put(brand, false); // 失败也记录为未注册 + success = true; + } + + } catch (Exception e) { + System.err.println(brand + " 查询异常(" + (retryCount + 1) + "/" + maxRetries + "): " + e.getMessage()); + try { driver.quit(); } catch (Exception ex) {} + driver = null; + retryCount++; } } - return resultMap; - } catch (Exception e) { - System.err.println("批量查询失败: " + e.getMessage()); - return new HashMap<>(); + + if (!success) { + System.err.println(brand + " -> [查询失败: 已重试" + maxRetries + "次]"); + resultMap.put(brand, false); // 失败也记录为未注册 + } } + + return resultMap; } public synchronized void closeDriver() {