diff --git a/.claude/settings.local.json b/.claude/settings.local.json index ed02e20..47e8238 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -8,7 +8,19 @@ "Bash(iconv:*)", "Bash(powershell:*)", "Bash(del:*)", - "Bash(git -C \"c:\\code\\gitea\\NPQS-9100\\pqs-9100_client\" log -1 --oneline)" + "Bash(git -C \"c:\\code\\gitea\\NPQS-9100\\pqs-9100_client\" log -1 --oneline)", + "Bash(npm run icon:*)", + "Bash(node:*)", + "Bash(xxd:*)", + "Bash(awk:*)", + "Bash(md5sum:*)", + "Bash(if exist \"out\" rd /s /q \"out\")", + "Bash(findstr:*)", + "Read(//c/code/gitea/NPQS-9100/pqs-9100_tool_client/cmd/**)", + "Bash(copy:*)", + "Bash(npm run build-w:*)", + "Read(//c/code/gitea/NPQS-9100/pqs-9100_tool_client/**)", + "Bash(npm install:*)" ], "deny": [], "ask": [] diff --git a/build/extraResources/java/application.yml.template b/build/extraResources/java/application.yml.template index f554634..1118bc3 100644 --- a/build/extraResources/java/application.yml.template +++ b/build/extraResources/java/application.yml.template @@ -1,5 +1,5 @@ server: - port: 18092 + port: 18093 spring: application: name: entrance @@ -51,7 +51,7 @@ socket: port: 61000 webSocket: - port: 7777 + port: 7778 #源参数下发,暂态数据默认值 Dip: diff --git a/build/extraResources/java/entrance.jar b/build/extraResources/java/entrance.jar index 0ce735f..8d21c1e 100644 Binary files a/build/extraResources/java/entrance.jar and b/build/extraResources/java/entrance.jar differ diff --git a/build/extraResources/templates/比对检测报告/V1.0.0/base-template.docx b/build/extraResources/templates/比对检测报告/V1.0.0/base-template.docx new file mode 100644 index 0000000..c59129a Binary files /dev/null and b/build/extraResources/templates/比对检测报告/V1.0.0/base-template.docx differ diff --git a/build/extraResources/templates/比对检测报告/V1.0.0/data-template.docx b/build/extraResources/templates/比对检测报告/V1.0.0/data-template.docx new file mode 100644 index 0000000..ae9da67 Binary files /dev/null and b/build/extraResources/templates/比对检测报告/V1.0.0/data-template.docx differ diff --git a/build/icons/128x128.png b/build/icons/128x128.png deleted file mode 100644 index 5c52682..0000000 Binary files a/build/icons/128x128.png and /dev/null differ diff --git a/build/icons/16x16.png b/build/icons/16x16.png deleted file mode 100644 index 9998a2c..0000000 Binary files a/build/icons/16x16.png and /dev/null differ diff --git a/build/icons/256x256.png b/build/icons/256x256.png deleted file mode 100644 index 802a3e1..0000000 Binary files a/build/icons/256x256.png and /dev/null differ diff --git a/build/icons/32x32.png b/build/icons/32x32.png deleted file mode 100644 index f02c0dd..0000000 Binary files a/build/icons/32x32.png and /dev/null differ diff --git a/build/icons/48x48.png b/build/icons/48x48.png deleted file mode 100644 index 430e97d..0000000 Binary files a/build/icons/48x48.png and /dev/null differ diff --git a/build/icons/512x512.png b/build/icons/512x512.png deleted file mode 100644 index 1c2bbe7..0000000 Binary files a/build/icons/512x512.png and /dev/null differ diff --git a/build/icons/64x64.png b/build/icons/64x64.png deleted file mode 100644 index 21f80f9..0000000 Binary files a/build/icons/64x64.png and /dev/null differ diff --git a/build/icons/favicon.ico b/build/icons/favicon.ico new file mode 100644 index 0000000..4da7a78 Binary files /dev/null and b/build/icons/favicon.ico differ diff --git a/build/icons/icon-original-backup.png b/build/icons/icon-original-backup.png deleted file mode 100644 index 802a3e1..0000000 Binary files a/build/icons/icon-original-backup.png and /dev/null differ diff --git a/build/icons/icon-reference.ico b/build/icons/icon-reference.ico new file mode 100644 index 0000000..f67e8c4 Binary files /dev/null and b/build/icons/icon-reference.ico differ diff --git a/build/icons/icon-square-256.png b/build/icons/icon-square-256.png deleted file mode 100644 index dd02cdb..0000000 Binary files a/build/icons/icon-square-256.png and /dev/null differ diff --git a/build/icons/icon-square-512.png b/build/icons/icon-square-512.png deleted file mode 100644 index a9a59e4..0000000 Binary files a/build/icons/icon-square-512.png and /dev/null differ diff --git a/build/icons/icon.icns b/build/icons/icon.icns deleted file mode 100644 index aa79460..0000000 Binary files a/build/icons/icon.icns and /dev/null differ diff --git a/build/icons/icon.ico b/build/icons/icon.ico deleted file mode 100644 index fe16b5a..0000000 Binary files a/build/icons/icon.ico and /dev/null differ diff --git a/build/icons/icon.png b/build/icons/icon.png deleted file mode 100644 index dd02cdb..0000000 Binary files a/build/icons/icon.png and /dev/null differ diff --git a/build/icons/icon_backup.ico b/build/icons/icon_backup.ico deleted file mode 100644 index da8b5a2..0000000 Binary files a/build/icons/icon_backup.ico and /dev/null differ diff --git a/build/remove-mysql-service.bat b/build/remove-mysql-service.bat deleted file mode 100644 index 4775b5e..0000000 --- a/build/remove-mysql-service.bat +++ /dev/null @@ -1,81 +0,0 @@ -@echo off -chcp 65001 >nul -title 检查并清除 MySQL9100 服务 -color 0E - -echo ======================================== -echo 检查并清除 MySQL9100 服务 -echo ======================================== -echo. - -REM 检查是否有管理员权限 -net session >nul 2>&1 -if %errorlevel% neq 0 ( - echo [错误] 需要管理员权限来操作 Windows 服务 - echo. - echo 请右键点击此脚本,选择"以管理员身份运行" - echo. - pause - exit /b 1 -) - -echo [✓] 已具有管理员权限 -echo. - -REM 检查服务是否存在 -echo [1/4] 检查 mysql9100 服务是否存在... -sc query mysql9100 >nul 2>&1 -if %errorlevel% equ 0 ( - echo [✓] 发现 mysql9100 服务 - echo. - - REM 显示服务状态 - echo [2/4] 服务状态信息: - sc query mysql9100 - echo. - - REM 停止服务 - echo [3/4] 正在停止 mysql9100 服务... - sc stop mysql9100 >nul 2>&1 - if %errorlevel% equ 0 ( - echo [✓] 服务已停止 - ) else ( - echo [!] 服务可能已经停止或停止失败(继续删除) - ) - - REM 等待服务完全停止 - timeout /t 2 /nobreak >nul - echo. - - REM 删除服务 - echo [4/4] 正在删除 mysql9100 服务... - sc delete mysql9100 - if %errorlevel% equ 0 ( - echo [✓] 服务已成功删除 - echo. - echo ======================================== - echo 清除完成! - echo ======================================== - ) else ( - echo [✗] 删除服务失败 - echo. - echo 可能的原因: - echo 1. 服务仍在运行中(请重启电脑后重试) - echo 2. 权限不足 - echo 3. 服务被其他程序锁定 - echo. - pause - exit /b 1 - ) -) else ( - echo [!] 未发现 mysql9100 服务 - echo. - echo 系统中没有名为 mysql9100 的服务,无需清除。 -) - -echo. -echo 提示:如果需要完全清理,还可以: -echo 1. 删除 MySQL 数据目录(mysql/data) -echo 2. 删除 MySQL 配置文件(mysql/my.ini) -echo. -pause diff --git a/build/upgrade/README.txt b/build/upgrade/README.txt new file mode 100644 index 0000000..bc1a646 --- /dev/null +++ b/build/upgrade/README.txt @@ -0,0 +1,20 @@ +# 升级包放置目录 + +## 使用方法 + +1. 将升级文件放入此目录: + - app.asar (前端升级包 - 文件) + - app.asar.unpacked/ (前端升级包 - 文件夹) + - entrance.jar (后端升级包) + +2. 双击运行根目录的 upgrade.bat 脚本 + +3. 升级完成后重启应用 + +## 注意事项 + +- 可以只放前端或只放后端,支持单独升级 +- 升级前会自动备份到 backup/ 目录 +- 如果升级失败,运行 rollback.bat 可回滚 + +详细说明请参考:README-升级回滚.txt diff --git a/cmd/builder.json b/cmd/builder.json index 8e161e5..7d2d08c 100644 --- a/cmd/builder.json +++ b/cmd/builder.json @@ -5,6 +5,7 @@ "directories": { "output": "out" }, + "npmRebuild": false, "asar": true, "asarUnpack": [ "public/images/**/*" @@ -21,23 +22,19 @@ "!python/" ], "extraResources": [ - { - "from": "build/extraResources/dll", - "to": "extraResources/dll", - "filter": ["**/*"] - }, { "from": "build/extraResources/java", "to": "extraResources/java", "filter": ["**/*"] }, { - "from": "build/extraResources/read.txt", - "to": "extraResources/read.txt" + "from": "build/extraResources/templates", + "to": "extraResources/templates", + "filter": ["**/*"] }, { - "from": "build/extraResources/使用说明.txt", - "to": "extraResources/使用说明.txt" + "from": "build/extraResources/read.txt", + "to": "extraResources/read.txt" }, { "from": "scripts/", @@ -57,12 +54,9 @@ "filter": ["**/*"] }, { - "from": "build/NPQS9100.bat", - "to": "NPQS9100.bat" - }, - { - "from": "build/extraResources/使用说明.txt", - "to": "使用说明.txt" + "from": "build/upgrade", + "to": "upgrade", + "filter": ["**/*"] }, { "from": "build/upgrade.bat", @@ -78,7 +72,7 @@ } ], "win": { - "icon": "public/images/icon.png", + "icon": "build/icons/icon.ico", "requestedExecutionLevel": "requireAdministrator", "signAndEditExecutable": false, "verifyUpdateCodeSignature": false, @@ -90,5 +84,16 @@ } ] }, + "nsis": { + "oneClick": false, + "allowElevation": true, + "allowToChangeInstallationDirectory": true, + "installerIcon": "build/icons/icon.ico", + "uninstallerIcon": "build/icons/icon.ico", + "installerHeaderIcon": "build/icons/icon.ico", + "createDesktopShortcut": true, + "createStartMenuShortcut": true, + "shortcutName": "NPQS9100" + }, "compression": "store" } diff --git a/doc/管理员权限说明.md b/doc/管理员权限说明.md new file mode 100644 index 0000000..2c2aae2 --- /dev/null +++ b/doc/管理员权限说明.md @@ -0,0 +1,65 @@ +# 管理员权限说明 + +> ⚠️ **文档已过期** - 本文档描述的是旧版服务模式,自 2025-12-01 起已改用**进程模式(绿色包)**。 +> +> 🎉 **新版本不再需要管理员权限!** +> +> 参考最新文档:`MySQL进程模式改造方案.md` 和 `NPQS-9100绿色包完整指南.md` + +--- + +## ~~🔐 为什么需要管理员权限?~~(已废弃) + +~~NPQS9100 需要管理 MySQL Windows 服务,执行以下操作:~~ +- ~~✅ 安装 MySQL 服务 (`mysql9100`)~~ +- ~~✅ 启动/停止服务~~ +- ~~✅ 删除服务(重新安装时)~~ + +~~这些操作都需要 **Windows 管理员权限**。~~ + +**现状**:已改用进程模式,直接启动 `mysqld.exe` 进程,无需注册 Windows 服务,**完全不需要管理员权限**。 + +## 🎉 新版启动方式(进程模式) + +**当前版本启动非常简单**: + +1. ✅ 双击 `NPQS9100.exe` 即可启动 +2. ✅ 无需管理员权限 +3. ✅ 无 UAC 弹窗 +4. ✅ 解压即用,完全绿色 + +**MySQL 和 Spring Boot 会在应用启动时自动启动,退出时自动清理。** + +--- + +## ~~以下内容已废弃(保留作为历史参考)~~ + +
+点击展开查看旧版(服务模式)说明 + +### ~~两种启动方式(已废弃)~~ + +#### ~~方式 1:使用启动器(推荐)~~ + +~~打包后的目录中有一个 `NPQS9100-启动器.bat` 文件。~~ + +#### ~~方式 2:手动以管理员身份运行~~ + +~~右键点击 `NPQS9100.exe` 选择"以管理员身份运行"~~ + +### ~~常见问题(已废弃)~~ + +~~Q: MySQL 服务安装后还需要管理员权限吗?~~ +A: **新版本不使用 Windows 服务,因此完全不需要管理员权限。** + +
+ +--- + +## 📝 版本历史 + +| 日期 | 版本 | 说明 | +|------|------|------| +| 2025-12-01 | v2.0 | 改用进程模式,无需管理员权限 ✅ | +| 2025-10-17 | v1.0 | 服务模式,需要管理员权限(已废弃)| + diff --git a/electron/config/config.default.js b/electron/config/config.default.js index 3a9f88d..ed74082 100644 --- a/electron/config/config.default.js +++ b/electron/config/config.default.js @@ -25,7 +25,7 @@ module.exports = () => { }, frame: true, show: false, // 初始不显示,等待服务启动完成后再显示 - icon: path.join(getBaseDir(), 'public', 'images', 'icon.png'), + icon: path.join(getBaseDir(), 'public', 'images', 'logo-32.png'), }, logger: { level: 'INFO', diff --git a/electron/preload/lifecycle.js b/electron/preload/lifecycle.js index 3dfd3da..f5e8f81 100644 --- a/electron/preload/lifecycle.js +++ b/electron/preload/lifecycle.js @@ -125,34 +125,34 @@ class Lifecycle { } // 步骤5: 检测 Java 端口 - this.logWindowManager.addLog('system', '▶ 步骤7: 检测可用的 Java 端口(从18092开始)...'); + this.logWindowManager.addLog('system', '▶ 步骤7: 检测可用的 Java 端口(从18093开始)...'); this.startupManager.updateProgress('check-java-port', { mysqlPort: this.mysqlPort }); - - this.javaPort = await PortChecker.findAvailablePort(18092, 100); - + + this.javaPort = await PortChecker.findAvailablePort(18093, 100); + if (this.javaPort === -1) { - this.logWindowManager.addLog('error', 'Java 端口检测失败:18092-18191 全部被占用'); - throw new Error('无法找到可用的后端服务端口(18092-18191 全部被占用)'); + this.logWindowManager.addLog('error', 'Java 端口检测失败:18093-18192 全部被占用'); + throw new Error('无法找到可用的后端服务端口(18093-18192 全部被占用)'); } - + // 步骤5.5: 检测 WebSocket 端口 - this.logWindowManager.addLog('system', '▶ 步骤8: 检测可用的 WebSocket 端口(从7777开始)...'); - - this.websocketPort = await PortChecker.findAvailablePort(7777, 100); - + this.logWindowManager.addLog('system', '▶ 步骤8: 检测可用的 WebSocket 端口(从7778开始)...'); + + this.websocketPort = await PortChecker.findAvailablePort(7778, 100); + if (this.websocketPort === -1) { - this.logWindowManager.addLog('error', 'WebSocket 端口检测失败:7777-7876 全部被占用'); - throw new Error('无法找到可用的 WebSocket 端口(7777-7876 全部被占用)'); + this.logWindowManager.addLog('error', 'WebSocket 端口检测失败:7778-7877 全部被占用'); + throw new Error('无法找到可用的 WebSocket 端口(7778-7877 全部被占用)'); } - - if (this.javaPort !== 18092) { - this.logWindowManager.addLog('warn', `⚠ Java 默认端口 18092 已被占用,自动切换到端口: ${this.javaPort}`); + + if (this.javaPort !== 18093) { + this.logWindowManager.addLog('warn', `⚠ Java 默认端口 18093 已被占用,自动切换到端口: ${this.javaPort}`); } else { this.logWindowManager.addLog('success', `✓ Java 将使用默认端口: ${this.javaPort}`); } - - if (this.websocketPort !== 7777) { - this.logWindowManager.addLog('warn', `⚠ WebSocket 默认端口 7777 已被占用,自动切换到端口: ${this.websocketPort}`); + + if (this.websocketPort !== 7778) { + this.logWindowManager.addLog('warn', `⚠ WebSocket 默认端口 7778 已被占用,自动切换到端口: ${this.websocketPort}`); } else { this.logWindowManager.addLog('success', `✓ WebSocket 将使用默认端口: ${this.websocketPort}`); } @@ -434,8 +434,17 @@ class Lifecycle { ? path.join(__dirname, '..', 'build', 'extraResources', 'java', 'entrance.jar') : path.join(process.resourcesPath, 'extraResources', 'java', 'entrance.jar'); + // 获取日志路径(与 config-generator.js 中的 dataPath 保持一致) + const isDev2 = !process.resourcesPath; + const baseDir = isDev2 + ? path.join(__dirname, '..', '..') + : path.dirname(process.resourcesPath); + const dataPath = path.join(baseDir, 'NPQS9100_Data'); + const logPath = path.join(dataPath, 'logs'); + const javaProcess = this.javaRunner.runSpringBoot(jarPath, configPath, { - javaPort: this.javaPort + javaPort: this.javaPort, + logPath: logPath // 传递日志路径 }); // 监听Java进程输出 diff --git a/frontend/.env.production b/frontend/.env.production index 2822720..af9d60b 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -23,6 +23,6 @@ VITE_PWA=true # 线上环境接口地址 #VITE_API_URL="/api" # 打包时用 -VITE_API_URL="http://127.0.0.1:18092/" +VITE_API_URL="http://127.0.0.1:18093/" # 开启激活验证 VITE_ACTIVATE_OPEN=true \ No newline at end of file diff --git a/frontend/src/utils/webSocketClient.ts b/frontend/src/utils/webSocketClient.ts index f8d7901..0490933 100644 --- a/frontend/src/utils/webSocketClient.ts +++ b/frontend/src/utils/webSocketClient.ts @@ -190,7 +190,7 @@ export default class SocketService { * WebSocket连接配置 */ private config: SocketConfig = { - url: 'ws://127.0.0.1:7777/hello', + url: 'ws://127.0.0.1:7778/hello', //url: 'ws://192.168.1.124:7777/hello', heartbeatInterval: 9000, // 9秒心跳间隔 reconnectDelay: 5000, // 5秒重连延迟 diff --git a/frontend/src/views/home/components/compareDataCheckRawDataTable.vue b/frontend/src/views/home/components/compareDataCheckRawDataTable.vue index 6a88ca7..b3c302a 100644 --- a/frontend/src/views/home/components/compareDataCheckRawDataTable.vue +++ b/frontend/src/views/home/components/compareDataCheckRawDataTable.vue @@ -12,14 +12,14 @@ - + - + diff --git a/frontend/src/views/home/components/compareDataCheckResultTable.vue b/frontend/src/views/home/components/compareDataCheckResultTable.vue index b12aafd..f138b3d 100644 --- a/frontend/src/views/home/components/compareDataCheckResultTable.vue +++ b/frontend/src/views/home/components/compareDataCheckResultTable.vue @@ -2,11 +2,13 @@
- diff --git a/frontend/src/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue b/frontend/src/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue index 3849a57..12412ce 100644 --- a/frontend/src/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue +++ b/frontend/src/views/home/components/compareDataCheckSingleChannelSingleTestPopup.vue @@ -159,10 +159,10 @@ diff --git a/frontend/src/views/plan/planList/components/planPopup.vue b/frontend/src/views/plan/planList/components/planPopup.vue index 305d7d5..996f1e8 100644 --- a/frontend/src/views/plan/planList/components/planPopup.vue +++ b/frontend/src/views/plan/planList/components/planPopup.vue @@ -1131,7 +1131,7 @@ const open = async (sign: string, data: Plan.ReqPlan, currentMode: string, plan: formContent.name = '' // 新建子计划允许选择数据源 const datasourceDicts = dictStore.getDictData('Datasource') - formContent.datasourceIds = [datasourceDicts[0]?.code] ?? [] + formContent.datasourceIds = datasourceDicts[0]?.code ? [datasourceDicts[0].code] : [] formContent.memberIds = [] } generateData() diff --git a/package.json b/package.json index e220862..76481fd 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,8 @@ "debug": "^4.4.0", "ee-bin": "^4.1.4", "electron": "^31.7.6", - "electron-builder": "^25.1.8" + "electron-builder": "^25.1.8", + "icon-gen": "^5.0.0" }, "dependencies": { "autofit.js": "^3.2.8", diff --git a/public/images/example/aw-3.png b/public/images/example/aw-3.png deleted file mode 100644 index ddebf47..0000000 Binary files a/public/images/example/aw-3.png and /dev/null differ diff --git a/public/images/example/ee-mac-home.png b/public/images/example/ee-mac-home.png deleted file mode 100644 index 7fd5093..0000000 Binary files a/public/images/example/ee-mac-home.png and /dev/null differ diff --git a/public/images/example/ee-project-7.png b/public/images/example/ee-project-7.png deleted file mode 100644 index adc4a31..0000000 Binary files a/public/images/example/ee-project-7.png and /dev/null differ diff --git a/public/images/example/ee-win-home.png b/public/images/example/ee-win-home.png deleted file mode 100644 index 5a83862..0000000 Binary files a/public/images/example/ee-win-home.png and /dev/null differ diff --git a/public/images/example/ee-zs.png b/public/images/example/ee-zs.png deleted file mode 100644 index ab27baa..0000000 Binary files a/public/images/example/ee-zs.png and /dev/null differ diff --git a/public/images/example/ee_game_1.png b/public/images/example/ee_game_1.png deleted file mode 100644 index c08dcb7..0000000 Binary files a/public/images/example/ee_game_1.png and /dev/null differ diff --git a/public/images/example/fm-p1.png b/public/images/example/fm-p1.png deleted file mode 100644 index 45ae065..0000000 Binary files a/public/images/example/fm-p1.png and /dev/null differ diff --git a/public/images/example/fm-p2.png b/public/images/example/fm-p2.png deleted file mode 100644 index 37360c9..0000000 Binary files a/public/images/example/fm-p2.png and /dev/null differ diff --git a/public/images/example/fm-p4.png b/public/images/example/fm-p4.png deleted file mode 100644 index 8ed280a..0000000 Binary files a/public/images/example/fm-p4.png and /dev/null differ diff --git a/public/images/example/gaiyan-1.jpg b/public/images/example/gaiyan-1.jpg deleted file mode 100644 index 91f9623..0000000 Binary files a/public/images/example/gaiyan-1.jpg and /dev/null differ diff --git a/public/images/example/gaiyan-2.png b/public/images/example/gaiyan-2.png deleted file mode 100644 index c3266f5..0000000 Binary files a/public/images/example/gaiyan-2.png and /dev/null differ diff --git a/public/images/example/gaiyan-3.jpg b/public/images/example/gaiyan-3.jpg deleted file mode 100644 index 55b7b37..0000000 Binary files a/public/images/example/gaiyan-3.jpg and /dev/null differ diff --git a/public/images/example/im-p1.png b/public/images/example/im-p1.png deleted file mode 100644 index 440a47c..0000000 Binary files a/public/images/example/im-p1.png and /dev/null differ diff --git a/public/images/example/im-p5.png b/public/images/example/im-p5.png deleted file mode 100644 index 0b7ac54..0000000 Binary files a/public/images/example/im-p5.png and /dev/null differ diff --git a/public/images/example/im2-p1.png b/public/images/example/im2-p1.png deleted file mode 100644 index 44d7145..0000000 Binary files a/public/images/example/im2-p1.png and /dev/null differ diff --git a/public/images/example/logo.png b/public/images/example/logo.png deleted file mode 100644 index 95dc60b..0000000 Binary files a/public/images/example/logo.png and /dev/null differ diff --git a/public/images/example/lol-zhanji.png b/public/images/example/lol-zhanji.png deleted file mode 100644 index 7166c2d..0000000 Binary files a/public/images/example/lol-zhanji.png and /dev/null differ diff --git a/public/images/example/rq-1.png b/public/images/example/rq-1.png deleted file mode 100644 index aeca28e..0000000 Binary files a/public/images/example/rq-1.png and /dev/null differ diff --git a/public/images/example/rq-2.png b/public/images/example/rq-2.png deleted file mode 100644 index ec793a1..0000000 Binary files a/public/images/example/rq-2.png and /dev/null differ diff --git a/public/images/example/ubuntu-db.png b/public/images/example/ubuntu-db.png deleted file mode 100644 index fbcf44e..0000000 Binary files a/public/images/example/ubuntu-db.png and /dev/null differ diff --git a/public/images/example/uos-home.png b/public/images/example/uos-home.png deleted file mode 100644 index b20c3dd..0000000 Binary files a/public/images/example/uos-home.png and /dev/null differ diff --git a/public/images/example/v3-home.png b/public/images/example/v3-home.png deleted file mode 100644 index 7535541..0000000 Binary files a/public/images/example/v3-home.png and /dev/null differ diff --git a/public/images/example/vue-antd.png b/public/images/example/vue-antd.png deleted file mode 100644 index 4747cfc..0000000 Binary files a/public/images/example/vue-antd.png and /dev/null differ diff --git a/public/images/icon.ico b/public/images/icon.ico new file mode 100644 index 0000000..1de1c87 Binary files /dev/null and b/public/images/icon.ico differ diff --git a/public/images/logo-32.png b/public/images/logo-32.png index f02c0dd..7fdd308 100644 Binary files a/public/images/logo-32.png and b/public/images/logo-32.png differ diff --git a/public/images/tray.png b/public/images/tray.png index e88d02d..3bee245 100644 Binary files a/public/images/tray.png and b/public/images/tray.png differ diff --git a/scripts/config-generator.js b/scripts/config-generator.js index b58ae76..02e7e7f 100644 --- a/scripts/config-generator.js +++ b/scripts/config-generator.js @@ -88,15 +88,15 @@ class ConfigGenerator { console.log('[ConfigGenerator] Data path:', this.dataPath); console.log('[ConfigGenerator] MySQL port:', options.mysqlPort || 3306); console.log('[ConfigGenerator] MySQL password:', options.mysqlPassword || 'njcnpqs'); - console.log('[ConfigGenerator] Java port:', options.javaPort || 18092); - console.log('[ConfigGenerator] WebSocket port:', options.websocketPort || 7777); - + console.log('[ConfigGenerator] Java port:', options.javaPort || 18093); + console.log('[ConfigGenerator] WebSocket port:', options.websocketPort || 7778); + resolve({ configPath: this.configPath, dataPath: this.dataPath, mysqlPort: options.mysqlPort || 3306, - javaPort: options.javaPort || 18092, - websocketPort: options.websocketPort || 7777 + javaPort: options.javaPort || 18093, + websocketPort: options.websocketPort || 7778 }); } catch (error) { console.error('[ConfigGenerator] Failed to generate config:', error); @@ -123,6 +123,75 @@ class ConfigGenerator { console.log('[ConfigGenerator] Created directory:', dir); } }); + + // 复制内置的报告模板文件 + this.copyBuiltInTemplates(); + } + + /** + * 复制内置的报告模板文件到用户数据目录 + */ + copyBuiltInTemplates() { + try { + const isDev = !process.resourcesPath; + const baseDir = isDev + ? path.join(__dirname, '..') + : path.dirname(process.resourcesPath); + + // 内置模板源路径 + const templateSource = isDev + ? path.join(baseDir, 'build', 'extraResources', 'templates') + : path.join(process.resourcesPath, 'extraResources', 'templates'); + + // 目标路径:用户数据目录/template/ + const templateDest = path.join(this.dataPath, 'template'); + + // 检查源模板是否存在 + if (!fs.existsSync(templateSource)) { + console.log('[ConfigGenerator] Built-in templates not found, skipping copy'); + return; + } + + // 递归复制模板文件(只复制不存在的文件,不覆盖已有文件) + this.copyTemplatesRecursive(templateSource, templateDest); + + console.log('[ConfigGenerator] Built-in templates copied successfully'); + } catch (error) { + console.error('[ConfigGenerator] Failed to copy templates:', error); + } + } + + /** + * 递归复制模板文件(不覆盖已存在的文件) + * @param {string} src 源目录 + * @param {string} dest 目标目录 + */ + copyTemplatesRecursive(src, dest) { + // 确保目标目录存在 + if (!fs.existsSync(dest)) { + fs.mkdirSync(dest, { recursive: true }); + } + + // 读取源目录内容 + const entries = fs.readdirSync(src, { withFileTypes: true }); + + entries.forEach(entry => { + const srcPath = path.join(src, entry.name); + const destPath = path.join(dest, entry.name); + + if (entry.isDirectory()) { + // 递归复制子目录 + this.copyTemplatesRecursive(srcPath, destPath); + } else { + // 只复制不存在的文件(不覆盖用户修改过的文件) + if (!fs.existsSync(destPath)) { + fs.copyFileSync(srcPath, destPath); + console.log('[ConfigGenerator] Copied template:', destPath); + } else { + console.log('[ConfigGenerator] Template already exists, skipping:', destPath); + } + } + }); } /** diff --git a/scripts/java-runner.js b/scripts/java-runner.js index 11df35d..915464a 100644 --- a/scripts/java-runner.js +++ b/scripts/java-runner.js @@ -166,11 +166,20 @@ class JavaRunner { '-Dfile.encoding=UTF-8', // 设置文件编码为UTF-8,解决中文乱码 '-Duser.language=zh', // 设置语言为中文 '-Duser.region=CN', // 设置地区为中国 - '-jar', - jarPath, - `--spring.config.location=${configPath}` ]; + // 如果提供了 logPath,通过 JVM 系统属性传递给 logback + if (options.logPath) { + // Windows 路径使用正斜杠或保持原样,JVM 会自动处理 + // 方案1:转换为正斜杠(跨平台兼容) + const normalizedLogPath = options.logPath.replace(/\\/g, '/'); + javaArgs.push(`-DlogHomeDir=${normalizedLogPath}`); + console.log('[Java] Setting log path to:', normalizedLogPath); + console.log('[Java] Original log path:', options.logPath); + } + + javaArgs.push('-jar', jarPath, `--spring.config.location=${configPath}`); + const defaultOptions = { cwd: path.dirname(jarPath), stdio: ['ignore', 'pipe', 'pipe'], diff --git a/scripts/mysql-service-manager.js b/scripts/mysql-service-manager.js index 6b99e2e..22082ed 100644 --- a/scripts/mysql-service-manager.js +++ b/scripts/mysql-service-manager.js @@ -300,6 +300,7 @@ default-character-set=utf8mb4 // 如果还没退出,强制杀死 this.log('warn', '优雅关闭超时,强制终止...'); this.mysqlProcess.kill('SIGTERM'); + await this.sleep(1000); } this.log('success', 'MySQL 进程已关闭'); @@ -309,16 +310,30 @@ default-character-set=utf8mb4 if (this.mysqlProcess) { this.mysqlProcess.kill('SIGTERM'); + await this.sleep(1000); } // 确保进程被杀死 try { await this.execCommand('taskkill /F /IM mysqld.exe'); + await this.sleep(2000); // 等待文件句柄释放 } catch (e) { // 忽略 } } + // 最终检查:确保所有 mysqld.exe 进程都被终止 + try { + const { stdout } = await this.execCommand('tasklist /FI "IMAGENAME eq mysqld.exe" /FO CSV /NH'); + if (stdout.includes('mysqld.exe')) { + this.log('warn', '检测到残留进程,强制清理...'); + await this.execCommand('taskkill /F /IM mysqld.exe'); + await this.sleep(2000); // 额外等待以确保文件句柄释放 + } + } catch (e) { + // 忽略 + } + this.mysqlProcess = null; this.currentPort = null; }