From 8922a3eef6d85cfbf5a5d39b3fd0bbdc542c49db Mon Sep 17 00:00:00 2001 From: cat-shark Date: Sat, 20 Jun 2026 10:13:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5=E6=9C=AC=E5=9C=B0=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E5=90=AF=E5=8A=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 6 ++- scripts/start-local.cjs | 90 +++++++++++++++++++++++++++++++++++------ src/config.ts | 2 +- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 7c9b449..341bfe1 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "scripts": { "start:local": "node scripts/start-local.cjs", "start:check": "node scripts/start-local.cjs --check", - "dev": "set VITE_DEV_SERVER_URL=http://127.0.0.1:3354&& vite --host 127.0.0.1 --port 3354 --strictPort", + "auth:local": "node scripts/local-auth-server.cjs", + "admin:local": "node server/local-auth/index.cjs", + "dev": "set AUTH_SERVER_URL=http://127.0.0.1:3302&& set VITE_DEV_SERVER_URL=http://127.0.0.1:3354&& vite --host 127.0.0.1 --port 3354 --strictPort", "typecheck": "vue-tsc --noEmit", "build": "node scripts/clean-build-artifacts.cjs && vite build", "build:dev": "node scripts/clean-build-artifacts.cjs && vite build --mode development", @@ -22,7 +24,7 @@ "version:sync": "node scripts/sync-version.cjs", "dev:all": "npm run dev:electron", "dev:win": "npm run dev:electron", - "dev:electron": "concurrently \"set VITE_DEV_SERVER_URL=http://127.0.0.1:3354&& set EXTERNAL_ELECTRON_DEV=1&& vite --host 127.0.0.1 --port 3354 --strictPort\" \"set VITE_DEV_SERVER_URL=http://127.0.0.1:3354&& node scripts/dev-electron.cjs\"", + "dev:electron": "concurrently \"set AUTH_SERVER_URL=http://127.0.0.1:3302&& set VITE_DEV_SERVER_URL=http://127.0.0.1:3354&& set EXTERNAL_ELECTRON_DEV=1&& vite --host 127.0.0.1 --port 3354 --strictPort\" \"set AUTH_SERVER_URL=http://127.0.0.1:3302&& set VITE_DEV_SERVER_URL=http://127.0.0.1:3354&& node scripts/dev-electron.cjs\"", "prepare-package": "node apply-oem.cjs && py -3 scripts/export-runtime-system-templates.py && node scripts/prepare-package.cjs", "build:win": "npm run prepare-package && npm run build && node scripts/build-resource-artifacts.cjs && electron-builder --win --x64 && node scripts/fix-latest-yml.cjs && node scripts/assemble-release-artifacts.cjs", "build:win:only": "electron-builder --win --x64", diff --git a/scripts/start-local.cjs b/scripts/start-local.cjs index b8d2df1..2a2cf69 100644 --- a/scripts/start-local.cjs +++ b/scripts/start-local.cjs @@ -5,6 +5,7 @@ const { spawn, spawnSync } = require("node:child_process"); const projectRoot = path.resolve(__dirname, ".."); const serverUrl = process.env.VITE_DEV_SERVER_URL || "http://127.0.0.1:3354"; +const authServerUrl = process.env.AUTH_SERVER_URL || "http://127.0.0.1:3302"; const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm"; const requiredNodeMajor = 20; const checkOnly = process.argv.includes("--check"); @@ -18,11 +19,11 @@ function fail(message) { process.exit(1); } -function parseServerUrl(url) { +function parseUrl(url, name) { try { return new URL(url); } catch { - fail(`VITE_DEV_SERVER_URL 无效:${url}`); + fail(`${name} 无效:${url}`); } } @@ -57,13 +58,13 @@ function checkDependencies() { } } -function assertPortAvailable(host, port) { +function assertPortAvailable(host, port, label) { return new Promise((resolve, reject) => { const server = net.createServer(); server.once("error", error => { if (error.code === "EADDRINUSE") { - reject(new Error(`端口 ${port} 已被占用,请先关闭已有 Vite/Electron 开发进程。`)); + reject(new Error(`${label} 端口 ${port} 已被占用,请先关闭已有进程。`)); return; } reject(error); @@ -77,24 +78,75 @@ function assertPortAvailable(host, port) { }); } +function canConnect(host, port) { + return new Promise(resolve => { + const socket = net.createConnection({ host, port }); + const finish = ok => { + socket.destroy(); + resolve(ok); + }; + socket.setTimeout(500); + socket.once("connect", () => finish(true)); + socket.once("timeout", () => finish(false)); + socket.once("error", () => finish(false)); + }); +} + +async function startLocalAuth(authUrl) { + const authHost = authUrl.hostname || "127.0.0.1"; + const authPort = Number(authUrl.port || 3302); + + if (await canConnect(authHost, authPort)) { + log(`本地认证服务已在运行:${authServerUrl}`); + return null; + } + + const child = spawn(process.execPath, ["scripts/local-auth-server.cjs"], { + cwd: projectRoot, + stdio: "inherit", + env: { + ...process.env, + LOCAL_AUTH_HOST: authHost, + LOCAL_AUTH_PORT: String(authPort), + }, + shell: false, + }); + + child.on("error", error => { + fail(`本地认证服务启动失败:${error.message}`); + }); + + for (let attempt = 0; attempt < 40; attempt++) { + if (await canConnect(authHost, authPort)) { + return child; + } + await new Promise(resolve => setTimeout(resolve, 250)); + } + + child.kill(); + fail(`本地认证服务未能在 ${authServerUrl} 启动。`); +} + async function main() { process.chdir(projectRoot); - const parsedUrl = parseServerUrl(serverUrl); - const host = parsedUrl.hostname || "127.0.0.1"; - const port = Number(parsedUrl.port || 3344); + const parsedServerUrl = parseUrl(serverUrl, "VITE_DEV_SERVER_URL"); + const parsedAuthUrl = parseUrl(authServerUrl, "AUTH_SERVER_URL"); + const viteHost = parsedServerUrl.hostname || "127.0.0.1"; + const vitePort = Number(parsedServerUrl.port || 3354); log("========================================"); - log(" 本地快速启动:Vite + Electron"); + log(" 本地快速启动:Local Auth + Vite + Electron"); log("========================================"); log(`项目目录:${projectRoot}`); + log(`认证服务:${authServerUrl}`); log(`开发地址:${serverUrl}`); log(""); checkNodeVersion(); const npmVersion = checkCommand(npmCommand, ["--version"], "npm"); checkDependencies(); - await assertPortAvailable(host, port); + await assertPortAvailable(viteHost, vitePort, "Vite"); log(`Node.js:${process.version}`); log(`npm:${npmVersion}`); @@ -105,24 +157,36 @@ async function main() { return; } + const authChild = await startLocalAuth(parsedAuthUrl); + + log(""); log("正在启动应用,关闭此窗口即可停止开发服务。"); + log("默认本地账号:13800138000 / 123456"); log(""); - const child = spawn(npmCommand, ["run", "dev:electron"], { + const appChild = spawn(npmCommand, ["run", "dev:electron"], { cwd: projectRoot, stdio: "inherit", env: { ...process.env, VITE_DEV_SERVER_URL: serverUrl, + AUTH_SERVER_URL: authServerUrl, }, shell: process.platform === "win32", }); - child.on("exit", code => { + const shutdown = code => { + if (authChild && !authChild.killed) { + authChild.kill(); + } process.exit(code ?? 0); - }); + }; - child.on("error", error => { + process.on("SIGINT", () => shutdown(0)); + process.on("SIGTERM", () => shutdown(0)); + + appChild.on("exit", shutdown); + appChild.on("error", error => { fail(`启动失败:${error.message}`); }); } diff --git a/src/config.ts b/src/config.ts index f9ae97c..ff44148 100644 --- a/src/config.ts +++ b/src/config.ts @@ -12,7 +12,7 @@ export const AppConfig = { website: ``, websiteGithub: "", websiteGitee: "", - apiBaseUrl: `http://49.233.157.120:3002/api`, + apiBaseUrl: `http://127.0.0.1:3302/api`, updaterUrl: ``, downloadUrl: ``, feedbackUrl: ``,