From 176e13901770d2cb879c3af9a596eb37027f4ec5 Mon Sep 17 00:00:00 2001 From: sunlei Date: Fri, 12 Jun 2026 19:53:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20QQBot=20=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=AF=86=E7=A0=81=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antdv-next/src/api/core/auth.ts | 2 +- apps/web-antdv-next/src/api/qqbot/index.ts | 29 +++++++++++++++--- .../src/views/qqbot/account/list.tsx | 30 ++++++++++++++++++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/apps/web-antdv-next/src/api/core/auth.ts b/apps/web-antdv-next/src/api/core/auth.ts index ea91acc..963f22d 100644 --- a/apps/web-antdv-next/src/api/core/auth.ts +++ b/apps/web-antdv-next/src/api/core/auth.ts @@ -72,7 +72,7 @@ function arrayBufferToBase64(buffer: ArrayBuffer) { return window.btoa(binary); } -async function encryptPassword(password: string) { +export async function encryptPassword(password: string) { const { hash, publicKey } = await getPasswordPublicKeyApi(); const cryptoKey = await window.crypto.subtle.importKey( 'spki', diff --git a/apps/web-antdv-next/src/api/qqbot/index.ts b/apps/web-antdv-next/src/api/qqbot/index.ts index a2debf9..9fc2f9d 100644 --- a/apps/web-antdv-next/src/api/qqbot/index.ts +++ b/apps/web-antdv-next/src/api/qqbot/index.ts @@ -1,5 +1,6 @@ import type { Recordable } from '@vben/types'; +import { encryptPassword } from '#/api/core/auth'; import { requestClient } from '#/api/request'; export namespace QqbotApi { @@ -64,7 +65,9 @@ export namespace QqbotApi { accessToken?: string; connectionMode?: 'reverse-ws'; enabled?: boolean; + encryptedLoginPassword?: string; id?: string; + loginPassword?: string; name?: string; remark?: string; selfId: string; @@ -292,12 +295,30 @@ export function getQqbotEnabledAccounts() { return requestClient.get('/qqbot/account/enabled'); } -export function createQqbotAccount(data: QqbotApi.AccountBody) { - return requestClient.post('/qqbot/account/save', data); +export async function createQqbotAccount(data: QqbotApi.AccountBody) { + return requestClient.post( + '/qqbot/account/save', + await buildAccountRequest(data), + ); } -export function updateQqbotAccount(data: QqbotApi.AccountBody) { - return requestClient.post('/qqbot/account/update', data); +export async function updateQqbotAccount(data: QqbotApi.AccountBody) { + return requestClient.post( + '/qqbot/account/update', + await buildAccountRequest(data), + ); +} + +async function buildAccountRequest(data: QqbotApi.AccountBody) { + const { loginPassword, ...payload } = data; + const password = + loginPassword === undefined || loginPassword === null + ? '' + : `${loginPassword}`; + if (password.trim()) { + payload.encryptedLoginPassword = await encryptPassword(password); + } + return payload; } export function deleteQqbotAccount(id: string) { diff --git a/apps/web-antdv-next/src/views/qqbot/account/list.tsx b/apps/web-antdv-next/src/views/qqbot/account/list.tsx index bc90b4a..c206647 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/list.tsx +++ b/apps/web-antdv-next/src/views/qqbot/account/list.tsx @@ -101,6 +101,21 @@ export default defineComponent({ const scanProgressCurrent = computed(() => Math.max(scanProgressItems.value.length - 1, 0), ); + const scanQrcodePlaceholderText = computed(() => { + if ( + scanState.mode === 'refresh' && + scanState.errorMessage?.includes('正在尝试快速登录') + ) { + return '正在尝试快速登录'; + } + if ( + scanState.mode === 'refresh' && + scanState.errorMessage?.includes('正在尝试密码登录') + ) { + return '正在尝试密码登录'; + } + return '二维码生成中'; + }); let scanTimer: number | undefined; let scanEventSessionId = ''; let scanEventSource: EventSource | undefined; @@ -138,6 +153,16 @@ export default defineComponent({ fieldName: 'accessToken', label: 'Token', }, + { + component: 'InputPassword', + componentProps: () => ({ + placeholder: editingId.value + ? '留空表示不修改 QQ 登录密码' + : '可选,用于 NapCat 密码登录', + }), + fieldName: 'loginPassword', + label: '登录密码', + }, { component: 'Switch', fieldName: 'enabled', @@ -729,6 +754,7 @@ export default defineComponent({ accessToken: '', connectionMode: 'reverse-ws', enabled: true, + loginPassword: '', name: '', remark: '', selfId: '', @@ -764,6 +790,7 @@ export default defineComponent({ connectionMode: row.connectionMode, enabled: row.enabled, id: row.id, + loginPassword: '', name: row.name, remark: row.remark || '', selfId: row.selfId, @@ -791,6 +818,7 @@ export default defineComponent({ selfId, }; if (!payload.accessToken) delete payload.accessToken; + if (!payload.loginPassword) delete payload.loginPassword; await (editingId.value ? updateQqbotAccount(payload) : createQqbotAccount(payload)); @@ -907,7 +935,7 @@ export default defineComponent({ width: '240px', }} > - 二维码生成中 + {scanQrcodePlaceholderText.value} )}