From 29981e123293ccc92fc01f2271cfd26451210cfc Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 15:51:04 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E6=89=93=E5=8C=85=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9482455..b353404 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,9 +21,25 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22.12 cache: 'npm' + - name: Configure Windows SDK WinMD + shell: powershell + run: | + $sdkRoot = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\\10" + $unionRoot = Join-Path $sdkRoot "UnionMetadata" + $refsRoot = Join-Path $sdkRoot "References" + if (!(Test-Path $unionRoot)) { throw "UnionMetadata not found at $unionRoot" } + $winmdDir = Get-ChildItem $unionRoot -Directory | Sort-Object Name -Descending | Select-Object -First 1 + if (!$winmdDir) { throw "No UnionMetadata version directory found" } + $refsDir = Get-ChildItem $refsRoot -Directory | Sort-Object Name -Descending | Select-Object -First 1 + if (!$refsDir) { throw "No References version directory found" } + $libPath = "$($winmdDir.FullName);$($refsDir.FullName)" + "LIBPATH=$libPath" | Out-File -FilePath $env:GITHUB_ENV -Append + "WindowsSdkDir=$sdkRoot\\" | Out-File -FilePath $env:GITHUB_ENV -Append + "WindowsSdkVersion=$($winmdDir.Name)\\" | Out-File -FilePath $env:GITHUB_ENV -Append + - name: Install Dependencies run: npm ci @@ -58,4 +74,4 @@ jobs: [点击加入 Telegram 群](https://t.me/+hn3QzNc4DbA0MzNl) EOF - gh release edit "$GITHUB_REF_NAME" --notes-file release_notes.md \ No newline at end of file + gh release edit "$GITHUB_REF_NAME" --notes-file release_notes.md From baa949a301fd64c62d3f189aa0c6d23d105a6717 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 15:56:27 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=91=83=E5=91=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b353404..958ba50 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 22.12 + node-version: 20.20.0 cache: 'npm' - name: Configure Windows SDK WinMD From 2cfe0d8ee84b2adec5a5d32dbb6206e48e777da4 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 16:01:21 +0800 Subject: [PATCH 3/8] ee --- .github/workflows/release.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 958ba50..a9c565c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,14 +31,20 @@ jobs: $unionRoot = Join-Path $sdkRoot "UnionMetadata" $refsRoot = Join-Path $sdkRoot "References" if (!(Test-Path $unionRoot)) { throw "UnionMetadata not found at $unionRoot" } - $winmdDir = Get-ChildItem $unionRoot -Directory | Sort-Object Name -Descending | Select-Object -First 1 - if (!$winmdDir) { throw "No UnionMetadata version directory found" } - $refsDir = Get-ChildItem $refsRoot -Directory | Sort-Object Name -Descending | Select-Object -First 1 + $platformWinmd = Get-ChildItem $unionRoot -Recurse -Filter platform.winmd -ErrorAction SilentlyContinue | + Sort-Object FullName -Descending | Select-Object -First 1 + if (!$platformWinmd) { throw "platform.winmd not found under $unionRoot" } + $platformDir = Split-Path $platformWinmd.FullName -Parent + $versionDir = $platformWinmd.Directory.Name + $refsDir = Join-Path $refsRoot $versionDir + if (!(Test-Path $refsDir)) { + $refsDir = Get-ChildItem $refsRoot -Directory | Sort-Object Name -Descending | Select-Object -First 1 + } if (!$refsDir) { throw "No References version directory found" } - $libPath = "$($winmdDir.FullName);$($refsDir.FullName)" - "LIBPATH=$libPath" | Out-File -FilePath $env:GITHUB_ENV -Append - "WindowsSdkDir=$sdkRoot\\" | Out-File -FilePath $env:GITHUB_ENV -Append - "WindowsSdkVersion=$($winmdDir.Name)\\" | Out-File -FilePath $env:GITHUB_ENV -Append + $libPath = "$platformDir;$($refsDir.FullName)" + Add-Content -Path $env:GITHUB_ENV -Value "LIBPATH=$libPath" -Encoding utf8 + Add-Content -Path $env:GITHUB_ENV -Value "WindowsSdkDir=$sdkRoot\\" -Encoding utf8 + Add-Content -Path $env:GITHUB_ENV -Value "WindowsSdkVersion=$versionDir\\" -Encoding utf8 - name: Install Dependencies run: npm ci From cf292ca9e25ee4cb14ff246c4813a04a2bfcfba9 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 16:06:36 +0800 Subject: [PATCH 4/8] hh --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9c565c..5eedc11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ permissions: jobs: release: - runs-on: windows-latest + runs-on: windows-2022 steps: - name: Check out git repository From 97f0077e95df5148fa15309a3b76b70794163ab8 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 16:14:00 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E6=89=93=E5=8C=85=E4=BD=A0=E5=BF=AB?= =?UTF-8?q?=E4=BF=AE=E5=A5=BD=E5=95=8A=20=E6=88=91=E6=9C=8D=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 26 ++------------------------ package-lock.json | 13 +------------ package.json | 5 ++--- 3 files changed, 5 insertions(+), 39 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5eedc11..9f2fcc9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ permissions: jobs: release: - runs-on: windows-2022 + runs-on: windows-latest steps: - name: Check out git repository @@ -21,31 +21,9 @@ jobs: - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 20.20.0 + node-version: 22.12 cache: 'npm' - - name: Configure Windows SDK WinMD - shell: powershell - run: | - $sdkRoot = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\\10" - $unionRoot = Join-Path $sdkRoot "UnionMetadata" - $refsRoot = Join-Path $sdkRoot "References" - if (!(Test-Path $unionRoot)) { throw "UnionMetadata not found at $unionRoot" } - $platformWinmd = Get-ChildItem $unionRoot -Recurse -Filter platform.winmd -ErrorAction SilentlyContinue | - Sort-Object FullName -Descending | Select-Object -First 1 - if (!$platformWinmd) { throw "platform.winmd not found under $unionRoot" } - $platformDir = Split-Path $platformWinmd.FullName -Parent - $versionDir = $platformWinmd.Directory.Name - $refsDir = Join-Path $refsRoot $versionDir - if (!(Test-Path $refsDir)) { - $refsDir = Get-ChildItem $refsRoot -Directory | Sort-Object Name -Descending | Select-Object -First 1 - } - if (!$refsDir) { throw "No References version directory found" } - $libPath = "$platformDir;$($refsDir.FullName)" - Add-Content -Path $env:GITHUB_ENV -Value "LIBPATH=$libPath" -Encoding utf8 - Add-Content -Path $env:GITHUB_ENV -Value "WindowsSdkDir=$sdkRoot\\" -Encoding utf8 - Add-Content -Path $env:GITHUB_ENV -Value "WindowsSdkVersion=$versionDir\\" -Encoding utf8 - - name: Install Dependencies run: npm ci diff --git a/package-lock.json b/package-lock.json index 6a7f552..7a5223f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "weflow", - "version": "1.4.2", + "version": "1.4.3", "lockfileVersion": 3, "requires": true, "packages": { @@ -9,7 +9,6 @@ "version": "1.4.2", "hasInstallScript": true, "dependencies": { - "@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4", "better-sqlite3": "^12.5.0", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -1949,16 +1948,6 @@ "node": ">= 10.0.0" } }, - "node_modules/@nodert-win10-rs4/windows.security.credentials.ui": { - "version": "0.4.4", - "resolved": "https://registry.npmmirror.com/@nodert-win10-rs4/windows.security.credentials.ui/-/windows.security.credentials.ui-0.4.4.tgz", - "integrity": "sha512-P+EsJw5MCQXTxp7mwXfNDvIzIYsB6ple+HNg01QjPWg/PJfAodPuxL6XM7l0sPtYHsDYnfnvoefZMdZRa2Z1ig==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "nan": "latest" - } - }, "node_modules/@npmcli/agent": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/@npmcli/agent/-/agent-3.0.0.tgz", diff --git a/package.json b/package.json index ae8d645..6950122 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "weflow", - "version": "1.4.2", + "version": "1.4.3", "description": "WeFlow", "main": "dist-electron/main.js", "author": "cc", @@ -15,7 +15,6 @@ "electron:build": "npm run build" }, "dependencies": { - "@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4", "better-sqlite3": "^12.5.0", "echarts": "^5.5.1", "echarts-for-react": "^3.0.2", @@ -127,4 +126,4 @@ } ] } -} \ No newline at end of file +} From 014f57f152f14e4748736ca79be12aa942af6607 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 17:44:52 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=A7=98=E9=92=A5=E8=8E=B7=E5=8F=96=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/services/keyService.ts | 71 ++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/electron/services/keyService.ts b/electron/services/keyService.ts index de123ca..e17c285 100644 --- a/electron/services/keyService.ts +++ b/electron/services/keyService.ts @@ -43,6 +43,7 @@ export class KeyService { private GetWindowThreadProcessId: any = null private IsWindowVisible: any = null private EnumChildWindows: any = null + private PostMessageW: any = null private WNDENUMPROC_PTR: any = null // Advapi32 @@ -57,6 +58,7 @@ export class KeyService { private readonly HKEY_LOCAL_MACHINE = 0x80000002 private readonly HKEY_CURRENT_USER = 0x80000001 private readonly ERROR_SUCCESS = 0 + private readonly WM_CLOSE = 0x0010 private getDllPath(): string { const isPackaged = typeof app !== 'undefined' && app ? app.isPackaged : process.env.NODE_ENV === 'production' @@ -224,6 +226,7 @@ export class KeyService { this.EnumWindows = this.user32.func('EnumWindows', 'bool', [this.WNDENUMPROC_PTR, 'intptr_t']) this.EnumChildWindows = this.user32.func('EnumChildWindows', 'bool', ['void*', this.WNDENUMPROC_PTR, 'intptr_t']) + this.PostMessageW = this.user32.func('PostMessageW', 'bool', ['void*', 'uint32', 'uintptr_t', 'intptr_t']) this.GetWindowTextW = this.user32.func('GetWindowTextW', 'int', ['void*', this.koffi.out('uint16*'), 'int']) this.GetWindowTextLengthW = this.user32.func('GetWindowTextLengthW', 'int', ['void*']) @@ -437,14 +440,55 @@ export class KeyService { return fallbackPid ?? null } - private async killWeChatProcesses() { + private async waitForWeChatExit(timeoutMs = 8000): Promise { + const start = Date.now() + while (Date.now() - start < timeoutMs) { + const weixinPid = await this.findPidByImageName('Weixin.exe') + const wechatPid = await this.findPidByImageName('WeChat.exe') + if (!weixinPid && !wechatPid) return true + await new Promise(r => setTimeout(r, 400)) + } + return false + } + + private async closeWeChatWindows(timeoutMs = 8000): Promise { + if (!this.ensureUser32()) return false + let requested = false + + const enumWindowsCallback = this.koffi.register((hWnd: any, lParam: any) => { + if (!this.IsWindowVisible(hWnd)) return true + const title = this.getWindowTitle(hWnd) + const className = this.getClassName(hWnd) + const classLower = (className || '').toLowerCase() + const isWeChatWindow = this.isWeChatWindowTitle(title) || classLower.includes('wechat') || classLower.includes('weixin') + if (!isWeChatWindow) return true + + requested = true + try { + this.PostMessageW?.(hWnd, this.WM_CLOSE, 0, 0) + } catch { } + return true + }, this.WNDENUMPROC_PTR) + + this.EnumWindows(enumWindowsCallback, 0) + this.koffi.unregister(enumWindowsCallback) + + if (!requested) return true + return await this.waitForWeChatExit(timeoutMs) + } + + private async killWeChatProcesses(): Promise { + const gracefulOk = await this.closeWeChatWindows(8000) + if (gracefulOk) return true + try { - await execFileAsync('taskkill', ['/F', '/IM', 'Weixin.exe']) - await execFileAsync('taskkill', ['/F', '/IM', 'WeChat.exe']) + await execFileAsync('taskkill', ['/F', '/T', '/IM', 'Weixin.exe']) + await execFileAsync('taskkill', ['/F', '/T', '/IM', 'WeChat.exe']) } catch (e) { // Ignore if not found } - await new Promise(r => setTimeout(r, 1000)) + + return await this.waitForWeChatExit(5000) } // --- Window Detection --- @@ -605,15 +649,24 @@ export class KeyService { } // 2. Restart WeChat - onStatus?.('正在重启微信以进行获取...', 0) - await this.killWeChatProcesses() + onStatus?.('正在关闭微信以进行获取...', 0) + const closed = await this.killWeChatProcesses() + if (!closed) { + const err = '无法自动关闭微信,请手动退出后重试' + onStatus?.(err, 2) + return { success: false, error: err } + } - // 3. Launch +// 3. Launch onStatus?.('正在启动微信...', 0) - const sub = spawn(wechatPath, { detached: true, stdio: 'ignore' }) + const sub = spawn(wechatPath, { + detached: true, + stdio: 'ignore', + cwd: dirname(wechatPath) + }) sub.unref() - // 4. Wait for Window & Get PID (Crucial change: discover PID from window) +// 4. Wait for Window & Get PID (Crucial change: discover PID from window) onStatus?.('等待微信界面就绪...', 0) const pid = await this.waitForWeChatWindow() if (!pid) { From bfcd154a254463d078edefbfdd7ec8e84a46d286 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 18:11:55 +0800 Subject: [PATCH 7/8] =?UTF-8?q?wxid=E5=8F=AF=E4=BB=A5=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/main.ts | 4 ++ electron/preload.ts | 1 + electron/services/dbPathService.ts | 42 ++++++++++++++++ electron/services/keyService.ts | 13 +++-- src/pages/WelcomePage.scss | 54 ++++++++++++++++++++- src/pages/WelcomePage.tsx | 78 ++++++++++++++++++++++++++---- src/types/electron.d.ts | 1 + 7 files changed, 177 insertions(+), 16 deletions(-) diff --git a/electron/main.ts b/electron/main.ts index 4a219b8..f152dc3 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -674,6 +674,10 @@ function registerIpcHandlers() { return dbPathService.scanWxids(rootPath) }) + ipcMain.handle('dbpath:scanWxidCandidates', async (_, rootPath: string) => { + return dbPathService.scanWxidCandidates(rootPath) + }) + ipcMain.handle('dbpath:getDefault', async () => { return dbPathService.getDefaultPath() }) diff --git a/electron/preload.ts b/electron/preload.ts index c401232..7d6d5c3 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -71,6 +71,7 @@ contextBridge.exposeInMainWorld('electronAPI', { dbPath: { autoDetect: () => ipcRenderer.invoke('dbpath:autoDetect'), scanWxids: (rootPath: string) => ipcRenderer.invoke('dbpath:scanWxids', rootPath), + scanWxidCandidates: (rootPath: string) => ipcRenderer.invoke('dbpath:scanWxidCandidates', rootPath), getDefault: () => ipcRenderer.invoke('dbpath:getDefault') }, diff --git a/electron/services/dbPathService.ts b/electron/services/dbPathService.ts index 038ee2f..ee15b02 100644 --- a/electron/services/dbPathService.ts +++ b/electron/services/dbPathService.ts @@ -118,6 +118,48 @@ export class DbPathService { } } + /** + * 扫描目录名候选(仅包含下划线的文件夹,排除 all_users) + */ + scanWxidCandidates(rootPath: string): WxidInfo[] { + const wxids: WxidInfo[] = [] + + try { + if (existsSync(rootPath)) { + const entries = readdirSync(rootPath) + for (const entry of entries) { + const entryPath = join(rootPath, entry) + let stat: ReturnType + try { + stat = statSync(entryPath) + } catch { + continue + } + + if (!stat.isDirectory()) continue + const lower = entry.toLowerCase() + if (lower === 'all_users') continue + if (!entry.includes('_')) continue + + wxids.push({ wxid: entry, modifiedTime: stat.mtimeMs }) + } + } + + if (wxids.length === 0) { + const rootName = basename(rootPath) + if (rootName.includes('_') && rootName.toLowerCase() !== 'all_users') { + const rootStat = statSync(rootPath) + wxids.push({ wxid: rootName, modifiedTime: rootStat.mtimeMs }) + } + } + } catch { } + + return wxids.sort((a, b) => { + if (b.modifiedTime !== a.modifiedTime) return b.modifiedTime - a.modifiedTime + return a.wxid.localeCompare(b.wxid) + }) + } + /** * 扫描 wxid 列表 */ diff --git a/electron/services/keyService.ts b/electron/services/keyService.ts index e17c285..bdec7de 100644 --- a/electron/services/keyService.ts +++ b/electron/services/keyService.ts @@ -451,7 +451,7 @@ export class KeyService { return false } - private async closeWeChatWindows(timeoutMs = 8000): Promise { + private async closeWeChatWindows(): Promise { if (!this.ensureUser32()) return false let requested = false @@ -473,13 +473,15 @@ export class KeyService { this.EnumWindows(enumWindowsCallback, 0) this.koffi.unregister(enumWindowsCallback) - if (!requested) return true - return await this.waitForWeChatExit(timeoutMs) + return requested } private async killWeChatProcesses(): Promise { - const gracefulOk = await this.closeWeChatWindows(8000) - if (gracefulOk) return true + const requested = await this.closeWeChatWindows() + if (requested) { + const gracefulOk = await this.waitForWeChatExit(1500) + if (gracefulOk) return true + } try { await execFileAsync('taskkill', ['/F', '/T', '/IM', 'Weixin.exe']) @@ -491,6 +493,7 @@ export class KeyService { return await this.waitForWeChatExit(5000) } + // --- Window Detection --- private getWindowTitle(hWnd: any): string { diff --git a/src/pages/WelcomePage.scss b/src/pages/WelcomePage.scss index c115f75..395b24e 100644 --- a/src/pages/WelcomePage.scss +++ b/src/pages/WelcomePage.scss @@ -435,6 +435,58 @@ } } +.wxid-select { + position: relative; +} + +.wxid-dropdown { + position: absolute; + top: calc(100% + 6px); + left: 0; + right: 0; + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 6px; + max-height: 220px; + overflow: auto; + z-index: 20; + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08); +} + +.wxid-option { + width: 100%; + border: none; + background: transparent; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 10px 12px; + border-radius: 8px; + cursor: pointer; + color: var(--text-primary); + font-size: 13px; + + &:hover { + background: var(--bg-hover); + } + + &.active { + background: var(--primary-light); + } +} + +.wxid-name { + font-weight: 600; +} + +.wxid-time { + color: var(--text-tertiary); + font-size: 12px; + white-space: nowrap; +} + .field-with-toggle { position: relative; } @@ -750,4 +802,4 @@ transform: scale(1); opacity: 1; } -} \ No newline at end of file +} diff --git a/src/pages/WelcomePage.tsx b/src/pages/WelcomePage.tsx index c68c64f..a1e556b 100644 --- a/src/pages/WelcomePage.tsx +++ b/src/pages/WelcomePage.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useRef } from 'react' import { useNavigate } from 'react-router-dom' import { useAppStore } from '../stores/appStore' import { dialog } from '../services/ipc' @@ -35,6 +35,8 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { const [cachePath, setCachePath] = useState('') const [wxid, setWxid] = useState('') const [wxidOptions, setWxidOptions] = useState>([]) + const [showWxidSelect, setShowWxidSelect] = useState(false) + const wxidSelectRef = useRef(null) const [error, setError] = useState('') const [isConnecting, setIsConnecting] = useState(false) const [isDetectingPath, setIsDetectingPath] = useState(false) @@ -127,8 +129,22 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { useEffect(() => { setWxidOptions([]) setWxid('') + setShowWxidSelect(false) }, [dbPath]) + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (!showWxidSelect) return + const target = event.target as Node + if (wxidSelectRef.current && !wxidSelectRef.current.contains(target)) { + setShowWxidSelect(false) + } + } + + document.addEventListener('mousedown', handleClickOutside) + return () => document.removeEventListener('mousedown', handleClickOutside) + }, [showWxidSelect]) + const currentStep = steps[stepIndex] const rootClassName = `welcome-page${isClosing ? ' is-closing' : ''}${standalone ? ' is-standalone' : ''}` const showWindowControls = standalone @@ -217,6 +233,28 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { } } + const handleScanWxidCandidates = async () => { + if (!dbPath) { + setError('请先选择数据库目录') + return + } + if (isScanningWxid) return + setIsScanningWxid(true) + setError('') + try { + const wxids = await window.electronAPI.dbPath.scanWxidCandidates(dbPath) + setWxidOptions(wxids) + setShowWxidSelect(true) + if (!wxids.length) { + setError('未检测到可用的账号目录,请检查路径') + } + } catch (e) { + setError(`扫描失败: ${e}`) + } finally { + setIsScanningWxid(false) + } + } + const handleAutoGetDbKey = async () => { if (isFetchingDbKey) return setIsFetchingDbKey(true) @@ -556,14 +594,35 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { {currentStep.id === 'key' && (
- setWxid(e.target.value)} - /> +
+ setWxid(e.target.value)} + /> + {showWxidSelect && wxidOptions.length > 0 && ( +
+ {wxidOptions.map((opt) => ( + + ))} +
+ )} +
@@ -733,4 +792,3 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { } export default WelcomePage - diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts index 2e424ea..892f430 100644 --- a/src/types/electron.d.ts +++ b/src/types/electron.d.ts @@ -42,6 +42,7 @@ export interface ElectronAPI { dbPath: { autoDetect: () => Promise<{ success: boolean; path?: string; error?: string }> scanWxids: (rootPath: string) => Promise + scanWxidCandidates: (rootPath: string) => Promise getDefault: () => Promise } wcdb: { From 4ef821f45f5fb77e0c8e8751b3689f3bbf901ff2 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Sat, 31 Jan 2026 18:12:57 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a5223f..faac1e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "weflow", - "version": "1.4.3", + "version": "1.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "weflow", - "version": "1.4.2", + "version": "1.4.4", "hasInstallScript": true, "dependencies": { "better-sqlite3": "^12.5.0", diff --git a/package.json b/package.json index 6950122..f20bd33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "weflow", - "version": "1.4.3", + "version": "1.4.4", "description": "WeFlow", "main": "dist-electron/main.js", "author": "cc",