From d30fb5cdf37b183ff46d191660fbf64e2fcbfa1b Mon Sep 17 00:00:00 2001 From: Niko <1377382065@qq.com> Date: Tue, 5 May 2026 15:26:30 +0800 Subject: [PATCH] Add auto-import to ets-proxy after downloading Excel After successful export download, automatically login to ets-proxy to get JWT token and upload the file via /api/bill/import endpoint. Co-Authored-By: Claude Opus 4.7 --- src/main/java/com/ets/scraper/EtsScraper.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/src/main/java/com/ets/scraper/EtsScraper.java b/src/main/java/com/ets/scraper/EtsScraper.java index 7a1ccde..5ef6911 100644 --- a/src/main/java/com/ets/scraper/EtsScraper.java +++ b/src/main/java/com/ets/scraper/EtsScraper.java @@ -31,6 +31,7 @@ public class EtsScraper { private static final Path SCREENSHOT_DIR = Path.of("screenshots"); private static final String OLLAMA_URL = "http://10.0.1.39:11434"; private static final String OLLAMA_MODEL = "qwen3-vl:4b"; + private static final String PROXY_HOST = "http://127.0.0.1:8081"; public static void main(String[] args) throws Exception { try { @@ -167,6 +168,8 @@ public class EtsScraper { } else { System.out.println("[+] Download size: " + java.nio.file.Files.size(savedFile) + " bytes"); } + // Auto-import to ets-proxy + autoImportBill(savedFile); } screenshot(page, "after_export"); System.out.println("[+] Query and export completed!"); @@ -426,4 +429,99 @@ public class EtsScraper { s = s.replaceAll("^[`'\\\"]|[`'\\\"]+$", ""); return s; } + + public static void autoImportBill(Path filePath) { + String token = proxyLogin(); + if (token == null) { + System.out.println("[-] Proxy login failed, skipping import"); + return; + } + proxyImport(filePath, token); + } + + public static String proxyLogin() { + try { + String loginUrl = PROXY_HOST + "/api/auth/login?username=" + USERNAME + "&password=" + PASSWORD; + java.net.URI uri = java.net.URI.create(loginUrl); + java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder() + .connectTimeout(java.time.Duration.ofSeconds(10)) + .build(); + java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder() + .uri(uri) + .GET() + .header("Content-Type", "application/json") + .build(); + java.net.http.HttpResponse response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString()); + String body = response.body(); + int dataIdx = body.indexOf("\"data\""); + int tokenIdx = body.indexOf("\"accessToken\""); + if (dataIdx < 0 || tokenIdx < 0) { + System.out.println("[-] Login response unexpected: " + body.substring(0, Math.min(200, body.length()))); + return null; + } + // Extract accessToken value + int colonStart = body.indexOf("\":", tokenIdx); + if (colonStart < 0) return null; + int quoteStart = body.indexOf("\"", colonStart + 2); + int quoteEnd = body.indexOf("\"", quoteStart + 1); + if (quoteStart < 0 || quoteEnd <= quoteStart) return null; + String token = body.substring(quoteStart + 1, quoteEnd); + System.out.println("[+] Proxy login successful, token: " + token.substring(0, Math.min(20, token.length())) + "..."); + return token; + } catch (Exception e) { + System.out.println("[-] Proxy login failed: " + e.getMessage()); + return null; + } + } + + public static void proxyImport(Path filePath, String token) { + try { + java.io.File file = filePath.toFile(); + String boundary = "----FormBoundary" + System.currentTimeMillis(); + String boundaryLine = "--" + boundary; + java.net.URI uri = java.net.URI.create(PROXY_HOST + "/api/bill/import"); + + java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream(); + java.io.OutputStream os = out; + + // Write file part + os.write((boundaryLine + "\r\n").getBytes()); + os.write(("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n").getBytes()); + os.write("Content-Type: application/octet-stream\r\n\r\n".getBytes()); + os.flush(); + + // Write file bytes + try (java.io.FileInputStream fis = new java.io.FileInputStream(file)) { + byte[] buf = new byte[8192]; + int n; + while ((n = fis.read(buf)) > 0) { + os.write(buf, 0, n); + } + } + os.flush(); + + // Write closing boundary + os.write(("\r\n" + boundaryLine + "--\r\n").getBytes()); + os.flush(); + + byte[] entityBytes = out.toByteArray(); + + java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder() + .connectTimeout(java.time.Duration.ofSeconds(30)) + .build(); + java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder() + .uri(uri) + .header("Content-Type", "multipart/form-data; boundary=" + boundary) + .header("Authorization", "Bearer " + token) + .POST(java.net.http.HttpRequest.BodyPublishers.ofByteArray(entityBytes)) + .build(); + + java.net.http.HttpResponse response = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString()); + String body = response.body(); + System.out.println("[+] Import response (" + response.statusCode() + "): " + body); + } catch (Exception e) { + System.out.println("[-] Import failed: " + e.getMessage()); + e.printStackTrace(); + } + } }