import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const repo = 'd:/work/ylrz_saas'; const scriptDir = dirname(fileURLToPath(import.meta.url)); function u(s) { return s.replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16))); } function writeUtf8(rel, content) { let text = content.replace(/\r\n/g, '\n'); if (text.charCodeAt(0) === 0xfeff) text = text.slice(1); writeFileSync(join(repo, rel), text, 'utf8'); console.log('fixed', rel); } function stripBom(rel) { const path = join(repo, rel); const raw = readFileSync(path); if (raw.length >= 3 && raw[0] === 0xef && raw[1] === 0xbb && raw[2] === 0xbf) { writeFileSync(path, raw.slice(3), 'utf8'); console.log('stripped BOM', rel); } } writeUtf8( 'java/fs-saas-company/src/main/java/com/fs/company/controller/workflow/LobsterDeepDialogueController.java', u(`package com.fs.company.controller.workflow; import com.fs.common.core.controller.BaseController; import com.fs.common.core.domain.AjaxResult; import com.fs.common.utils.ServletUtils; import com.fs.company.service.workflow.deepdialogue.DeepDialogueDebugService; import com.fs.framework.security.LoginUser; import com.fs.framework.service.TokenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.Map; /** * UDD \u6df1\u5ea6\u5bf9\u8bdd\u8c03\u8bd5\uff08\u62c6\u89e3/\u8ba1\u5212/\u586b\u69fd/\u72b6\u6001\u67e5\u770b\uff09\u3002 */ @RestController @RequestMapping("/workflow/lobster/deep-dialogue") public class LobsterDeepDialogueController extends BaseController { @Autowired(required = false) private DeepDialogueDebugService debugService; @Autowired private TokenService tokenService; private Long companyId() { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); return loginUser != null && loginUser.getCompany() != null ? loginUser.getCompany().getCompanyId() : null; } @PreAuthorize("@ss.hasPermi('workflow:lobster:query')") @PostMapping("/debug") public AjaxResult debug(@RequestBody Map body) { if (debugService == null) { return AjaxResult.error("UDD \u8c03\u8bd5\u670d\u52a1\u672a\u542f\u7528"); } String userKey = body.get("userKey") != null ? body.get("userKey").toString() : "udd-debug-user"; String industryType = (String) body.get("industryType"); String message = (String) body.get("message"); if (message == null || message.isBlank()) { return AjaxResult.error("\u5ba2\u6237\u6d88\u606f\u4e0d\u80fd\u4e3a\u7a7a"); } boolean persistState = Boolean.TRUE.equals(body.get("persistState")); boolean skipLlmRender = body.get("skipLlmRender") == null || Boolean.parseBoolean(body.get("skipLlmRender").toString()); return AjaxResult.success(debugService.debugGenerate( companyId(), userKey, industryType, message.trim(), persistState, skipLlmRender)); } @PreAuthorize("@ss.hasPermi('workflow:lobster:query')") @GetMapping("/state") public AjaxResult state(@RequestParam String userKey) { if (debugService == null) { return AjaxResult.success(); } return AjaxResult.success(debugService.getState(companyId(), userKey)); } @PreAuthorize("@ss.hasPermi('workflow:lobster:edit')") @DeleteMapping("/state") public AjaxResult clearState(@RequestParam String userKey) { if (debugService != null) { debugService.clearState(companyId(), userKey); } return AjaxResult.success(); } @PreAuthorize("@ss.hasPermi('workflow:lobster:query')") @GetMapping("/scenario-suite") public AjaxResult scenarioSuite() { if (debugService == null) { return AjaxResult.success(); } return AjaxResult.success(debugService.runScenarioSuite()); } } `) ); { const rel = 'java/fs-saas-company/src/main/java/com/fs/company/controller/workflow/LobsterIndustryCorpusMatrixController.java'; let text = readFileSync(join(repo, rel), 'utf8').replace(/\r\n/g, '\n'); text = text.replace(/^ \* .*corpus_kind=industry_matrix.*$/m, u(' * \u884c\u4e1a\u8bed\u6599\u77e9\u9635\uff08corpus_kind=industry_matrix\uff09\uff0c\u4e0e\u9500\u51a0\u8bed\u6599\u5206\u5f00\u7ba1\u7406\u3002')); text = text.replace( /return AjaxResult\.error\("[^"]*"\);/g, (match, offset, whole) => { const ctx = whole.slice(Math.max(0, offset - 200), offset + 40); if (ctx.includes('matrixService == null')) { return u('return AjaxResult.error("\u884c\u4e1a\u8bed\u6599\u77e9\u9635\u670d\u52a1\u672a\u542f\u7528");'); } if (ctx.includes('customerQuestion == null')) { return u('return AjaxResult.error("\u884c\u4e1a\u3001\u5ba2\u6237\u95ee\u9898\u3001\u56de\u590d\u4e0d\u80fd\u4e3a\u7a7a");'); } if (ctx.includes('writeToKb && knowledgeBaseId')) { return u('return AjaxResult.error("\u5199\u5165\u77e5\u8bc6\u5e93\u65f6\u8bf7\u63d0\u4f9b knowledgeBaseId");'); } if (ctx.includes('industryType == null') || ctx.includes('industryType.isBlank()')) { return u('return AjaxResult.error("\u884c\u4e1a\u4e0d\u80fd\u4e3a\u7a7a");'); } return match; } ); text = text.replace( /data\.put\("message", count > 0 \? "[^"]*" \+ count \+ "[^"]*"[\s\S]*?: "[^"]*"\);/, u('data.put("message", count > 0 ? "\u5df2\u521d\u59cb\u5316 " + count + " \u6761\u884c\u4e1a\u8bed\u6599"\n : "\u8be5\u884c\u4e1a\u5df2\u6709\u8bed\u6599\uff0c\u672a\u91cd\u590d\u521d\u59cb\u5316\uff08\u53ef\u7528 force=true \u8ffd\u52a0\uff09");') ); text = text.replace( /data\.put\("message", count > 0 \? "[^"]*" \+ count \+ "[^"]*" : "[^"]*"\);/, u('data.put("message", count > 0 ? "\u5df2\u4ece\u9500\u51a0\u8bed\u6599\u5bfc\u5165 " + count + " \u6761\u5230\u884c\u4e1a\u77e9\u9635" : "\u6ca1\u6709\u53ef\u5bfc\u5165\u7684\u6761\u76ee");') ); writeUtf8(rel, text); } { const rel = 'java/fs-saas-company/src/main/java/com/fs/company/controller/workflow/LobsterUserSegmentController.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace( /return AjaxResult\.error\("[^"]*"\);/, u('return AjaxResult.error("\u7528\u6237\u5206\u7fa4\u4e0d\u5b58\u5728");') ); writeUtf8(rel, text); } { const rel = 'java/fs-service/src/main/java/com/fs/company/domain/CompanyTagBindingExecStats.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace(/^\/\*\*[\s\S]*?\*\//m, u(`/** * \u6807\u7b7e\u7ed1\u5b9a\u6267\u884c\u6982\u51b5\u7edf\u8ba1\uff08\u5217\u8868\u9875\u5c55\u793a\uff0c\u5b9a\u65f6/\u624b\u52a8\u5237\u65b0\uff09\u3002 */`)); writeUtf8(rel, text); } { const rel = 'java/fs-service/src/main/java/com/fs/company/service/workflow/scheduler/LobsterBindingExecStatsScheduler.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace(/^\/\*\*[\s\S]*?\*\//m, u(`/** * \u9f99\u8679\u6807\u7b7e\u7ed1\u5b9a\u6267\u884c\u6982\u51b5\u5b9a\u65f6\u7edf\u8ba1\uff0c\u9ed8\u8ba4\u6bcf 30 \u5206\u949f\u5168\u91cf\u5237\u65b0\u3002 */`)); writeUtf8(rel, text); } { const rel = 'java/fs-service/src/main/java/com/fs/company/service/workflow/scope/LobsterTemplateVisibleScopeUtil.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace(/^\/\*\*[\s\S]*?\*\//m, u(`/** * \u9f99\u8679\u5de5\u4f5c\u6d41\u6a21\u677f\u5206\u516c\u53f8\u53ef\u89c1\u8303\u56f4\uff1bvisible_company_ids \u9017\u53f7\u5206\u9694\uff0c\u7a7a\u8868\u793a\u4ec5\u6240\u5c5e company_id \u53ef\u89c1\u3002 */`)); writeUtf8(rel, text); } writeUtf8( 'java/fs-service/src/main/java/com/fs/company/service/workflow/trigger/TimeIntentDetector.java', readFileSync( join(repo, 'java/fs-service/src/main/java/com/fs/company/service/workflow/trigger/TimeIntentDetector.java'), 'utf8' ) .replace(/\r\n/g, '\n') .replace(/\[\\u70b9:\?\?\]/g, '[??:??]') .replace(/\[:?\?\?\]/g, '[:??]') .replace(/^\/\*\*[\s\S]*?\*\//m, u(`/** * \u4ece\u5ba2\u6237\u6d88\u606f\u89e3\u6790\u7ea6\u5b9a\u65f6\u95f4\u610f\u56fe\uff0c\u7528\u4e8e waitUntil \u8282\u70b9\u3002 */`)) .replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16))) ); { const rel = 'java/scripts/FindTenantManageMenu.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace( /FROM sys_menu WHERE menu_name LIKE '[^']*' OR path LIKE '%tenant%'[\s\S]*?LIMIT 80/, u("FROM sys_menu WHERE menu_name LIKE '%\u79df\u6237%' OR path LIKE '%tenant%' " + "OR menu_name LIKE '%\u7ba1\u7406%' ORDER BY menu_id LIMIT 80") ); writeUtf8(rel, text); } { const rel = 'java/scripts/ProbeSimulateLiquor.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace( /template_name LIKE '%\?\?%' OR template_name LIKE '%\?\?%'/, u("template_name LIKE '%\u9152%' OR template_name LIKE '%\u767d\u9152%'") ); writeUtf8(rel, text); } { const ddlSource = readFileSync( join(repo, 'java/fs-service/src/main/resources/db/tenant-initTable.sql'), 'utf8' ); const start = ddlSource.indexOf('CREATE TABLE `company_lobster_tag_user_rel`'); const tail = u(") ENGINE=InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='\u9f99\u8679\u6807\u7b7e-\u4f01\u5fae\u5ba2\u6237\u5173\u8054\u8868';"); const end = ddlSource.indexOf(tail, start); const tableDdl = ddlSource.slice(start, end + tail.length); const rel = 'java/scripts/ApplyCompanyLobsterTagUserRelTable.java'; let text = readFileSync(join(repo, rel), 'utf8'); text = text.replace( /private static final String DDL = """[\s\S]*?""";/, `private static final String DDL = """\n ${tableDdl.split('\n').map((l) => (l ? ' ' + l : l)).join('\n')}\n """;` ); writeUtf8(rel, text); } for (const rel of [ 'java/scripts/CheckMenuEncoding.java', 'java/scripts/CheckTables.java', 'java/scripts/ProbeCelery.java', 'java/scripts/QCols.java', ]) { stripBom(rel); } console.log('batch java garbled fix done');