feat: 增加 QQBot 登录密码配置

This commit is contained in:
sunlei 2026-06-12 19:53:59 +08:00
parent c8729cb096
commit 176e139017
3 changed files with 55 additions and 6 deletions

View File

@ -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',

View File

@ -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<QqbotApi.Account[]>('/qqbot/account/enabled');
}
export function createQqbotAccount(data: QqbotApi.AccountBody) {
return requestClient.post<string>('/qqbot/account/save', data);
export async function createQqbotAccount(data: QqbotApi.AccountBody) {
return requestClient.post<string>(
'/qqbot/account/save',
await buildAccountRequest(data),
);
}
export function updateQqbotAccount(data: QqbotApi.AccountBody) {
return requestClient.post<boolean>('/qqbot/account/update', data);
export async function updateQqbotAccount(data: QqbotApi.AccountBody) {
return requestClient.post<boolean>(
'/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) {

View File

@ -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}
</div>
)}
</div>