From b549e30dd511045a9961cfb8e6ff1f52321e382f Mon Sep 17 00:00:00 2001 From: sunlei Date: Tue, 16 Jun 2026 01:01:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=94=B6=E6=95=9BAdmin=20QQBot?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/qqbot/index.spec.ts | 59 +++---- apps/web-antdv-next/src/api/qqbot/index.ts | 145 ---------------- .../src/api/qqbot/napcat.spec.ts | 78 ++++++++- apps/web-antdv-next/src/api/qqbot/napcat.ts | 93 +++++++++++ .../src/api/qqbot/plugin.spec.ts | 102 ++++++++++++ apps/web-antdv-next/src/api/qqbot/plugin.ts | 56 +++++++ .../account/components/AccountConfigPanel.tsx | 8 +- .../src/views/qqbot/account/list.tsx | 33 ++-- .../src/views/qqbot/command/list.tsx | 6 +- .../plugin/components/PluginManifestModal.tsx | 49 ++++++ .../components/PluginPlatformStateDrawer.tsx | 155 +++++++++++++++++ .../src/views/qqbot/plugin/list.tsx | 156 ++++-------------- 12 files changed, 607 insertions(+), 333 deletions(-) create mode 100644 apps/web-antdv-next/src/api/qqbot/plugin.spec.ts create mode 100644 apps/web-antdv-next/src/views/qqbot/plugin/components/PluginManifestModal.tsx create mode 100644 apps/web-antdv-next/src/views/qqbot/plugin/components/PluginPlatformStateDrawer.tsx diff --git a/apps/web-antdv-next/src/api/qqbot/index.spec.ts b/apps/web-antdv-next/src/api/qqbot/index.spec.ts index 9e2f9c1..7a7b750 100644 --- a/apps/web-antdv-next/src/api/qqbot/index.spec.ts +++ b/apps/web-antdv-next/src/api/qqbot/index.spec.ts @@ -1,49 +1,28 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { readFileSync } from 'node:fs'; -import { requestClient } from '#/api/request'; +import { describe, expect, it } from 'vitest'; -import { getQqbotPluginOperationPage } from './index'; +const readApiFile = (name: string) => + readFileSync(new URL(name, import.meta.url), 'utf8'); -vi.mock('#/api/request', () => ({ - requestClient: { - get: vi.fn(), - getBaseUrl: vi.fn(() => ''), - }, -})); +describe('qqbot core API caller boundary', () => { + it('keeps plugin platform and NapCat scan routes out of the core caller', () => { + const source = readApiFile('index.ts'); -describe('qqbot plugin API wrappers', () => { - beforeEach(() => { - vi.clearAllMocks(); + expect(source).not.toContain('/qqbot/plugin'); + expect(source).not.toContain('/qqbot/plugin-platform'); + expect(source).not.toContain('/qqbot/account/scan'); }); - it('uses the paged plugin operation endpoint for KtTable', async () => { - const pageResult = { - list: [], - pageNo: 2, - pageSize: 1, - total: 3, - }; - vi.mocked(requestClient.get).mockResolvedValueOnce(pageResult); - - await expect( - getQqbotPluginOperationPage({ - pageNo: 2, - pageSize: 1, - pluginKey: 'bangdream', - triggerMode: 'command', - }), - ).resolves.toBe(pageResult); - - expect(requestClient.get).toHaveBeenCalledWith( - '/qqbot/plugin/operation/page', - { - params: { - pageNo: 2, - pageSize: 1, - pluginKey: 'bangdream', - triggerMode: 'command', - }, - }, + it('keeps domain-specific caller routes in plugin and napcat callers', () => { + expect(readApiFile('plugin.ts')).toEqual( + expect.stringContaining('/qqbot/plugin/operation/page'), + ); + expect(readApiFile('plugin.ts')).toEqual( + expect.stringContaining('/qqbot/plugin-platform/runtime-events'), + ); + expect(readApiFile('napcat.ts')).toEqual( + expect.stringContaining('/qqbot/account/scan/events'), ); }); }); diff --git a/apps/web-antdv-next/src/api/qqbot/index.ts b/apps/web-antdv-next/src/api/qqbot/index.ts index 4fca431..6715231 100644 --- a/apps/web-antdv-next/src/api/qqbot/index.ts +++ b/apps/web-antdv-next/src/api/qqbot/index.ts @@ -1,7 +1,5 @@ import type { Recordable } from '@vben/types'; -import type { NapcatLoginNewDeviceStatus } from './napcat'; - import { encryptPassword } from '#/api/core/auth'; import { requestClient } from '#/api/request'; @@ -93,39 +91,6 @@ export namespace QqbotApi { selfId: string; } - export interface AccountScanResult { - accountId?: string; - captchaUrl?: string; - containerId?: string; - containerName?: string; - deviceVerifyUrl?: string; - errorMessage?: string; - expiresAt?: number; - mode: 'create' | 'refresh'; - newDeviceQrcode?: string; - newDeviceStatus?: NapcatLoginNewDeviceStatus; - qrcode?: string; - selfId?: string; - sessionId?: string; - status: 'error' | 'expired' | 'pending' | 'success'; - webuiPort?: null | number; - } - - export interface AccountScanEvent { - createdAt: number; - message: string; - result?: AccountScanResult; - status: 'error' | 'info' | 'processing' | 'success'; - step: string; - } - - export interface AccountScanCaptchaBody { - randstr: string; - sessionId: string; - sid?: string; - ticket: string; - } - export interface Rule { cooldownMs: number; enabled: boolean; @@ -391,62 +356,6 @@ export function kickQqbotAccount(selfId: string) { ); } -export function startQqbotAccountScanCreate() { - return requestClient.post( - '/qqbot/account/scan/create', - ); -} - -export function startQqbotAccountScanRefresh(id: string) { - return requestClient.post( - `/qqbot/account/scan/refresh?id=${id}`, - ); -} - -export function getQqbotAccountScanStatus(sessionId: string) { - return requestClient.get( - '/qqbot/account/scan/status', - { params: { sessionId } }, - ); -} - -export function refreshQqbotAccountScanQrcode(sessionId: string) { - return requestClient.post( - `/qqbot/account/scan/qrcode/refresh?sessionId=${sessionId}`, - ); -} - -export function submitQqbotAccountScanCaptcha( - data: QqbotApi.AccountScanCaptchaBody, -) { - return requestClient.post( - '/qqbot/account/scan/captcha/submit', - data, - ); -} - -export function cancelQqbotAccountScan(sessionId: string) { - return requestClient.post( - `/qqbot/account/scan/cancel?sessionId=${sessionId}`, - ); -} - -export function getQqbotAccountScanEventsUrl(sessionId: string) { - return buildApiUrl( - `/qqbot/account/scan/events?sessionId=${encodeURIComponent(sessionId)}`, - ); -} - -function buildApiUrl(path: string) { - const baseUrl = requestClient.getBaseUrl() || ''; - if (!baseUrl) return path; - if (/^https?:\/\//i.test(path)) return path; - if (/^https?:\/\//i.test(baseUrl)) { - return new URL(path, baseUrl).toString(); - } - return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`; -} - export function getQqbotRuleList(params: QqbotApi.Query) { return requestClient.get>( '/qqbot/rule/list', @@ -595,57 +504,3 @@ export function testQqbotCommand(data: { data, ); } - -export function getQqbotPluginList(triggerMode?: QqbotApi.PluginTriggerMode) { - return requestClient.get('/qqbot/plugin/list', { - params: { triggerMode }, - }); -} - -export function getQqbotPluginOperationList( - pluginKey?: string, - triggerMode?: QqbotApi.PluginTriggerMode, -) { - return requestClient.get( - '/qqbot/plugin/operation/list', - { params: { pluginKey, triggerMode } }, - ); -} - -export function getQqbotPluginOperationPage( - params: QqbotApi.PluginOperationQuery, -) { - return requestClient.get>( - '/qqbot/plugin/operation/page', - { params }, - ); -} - -export function getQqbotPluginHealth( - pluginKey?: string, - triggerMode?: QqbotApi.PluginTriggerMode, -) { - return requestClient.get('/qqbot/plugin/health', { - params: { pluginKey, triggerMode }, - }); -} - -export function getQqbotEventPluginList(params?: { selfId?: string }) { - return requestClient.get('/qqbot/plugin/event/list', { - params, - }); -} - -export function bindQqbotEventPlugin(selfId: string, pluginKey: string) { - const params = new URLSearchParams({ pluginKey, selfId }); - return requestClient.post( - `/qqbot/plugin/event/bind?${params.toString()}`, - ); -} - -export function unbindQqbotEventPlugin(selfId: string, pluginKey: string) { - const params = new URLSearchParams({ pluginKey, selfId }); - return requestClient.post( - `/qqbot/plugin/event/unbind?${params.toString()}`, - ); -} diff --git a/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts b/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts index ce4ca21..1cf3384 100644 --- a/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts +++ b/apps/web-antdv-next/src/api/qqbot/napcat.spec.ts @@ -1,12 +1,33 @@ -import { describe, expect, it } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { requestClient } from '#/api/request'; import { + cancelQqbotAccountScan, getNapcatNewDeviceStatusMessage, + getQqbotAccountScanEventsUrl, + getQqbotAccountScanStatus, NAPCAT_LOGIN_PROGRESS_LABELS, + refreshQqbotAccountScanQrcode, resolveNapcatLoginDisplayQrcode, + startQqbotAccountScanCreate, + startQqbotAccountScanRefresh, + submitQqbotAccountScanCaptcha, } from './napcat'; +vi.mock('#/api/request', () => ({ + requestClient: { + get: vi.fn(), + getBaseUrl: vi.fn(() => '/api'), + post: vi.fn(), + }, +})); + describe('napcat login display helpers', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + it('keeps all Chinese progress labels required by the login flow', () => { expect(NAPCAT_LOGIN_PROGRESS_LABELS).toMatchObject({ 'captcha-submit': '验证码已提交,等待确认', @@ -55,4 +76,59 @@ describe('napcat login display helpers', () => { 'new-device-verified', ]); }); + + it('owns create, refresh, status, QR refresh, captcha, cancel, and SSE caller routes', async () => { + const scanResult = { + mode: 'refresh' as const, + sessionId: 'scan-1', + status: 'pending' as const, + }; + vi.mocked(requestClient.post).mockResolvedValue(scanResult); + vi.mocked(requestClient.get).mockResolvedValue(scanResult); + + await expect(startQqbotAccountScanCreate()).resolves.toBe(scanResult); + await expect(startQqbotAccountScanRefresh('account-1')).resolves.toBe( + scanResult, + ); + await expect(getQqbotAccountScanStatus('scan-1')).resolves.toBe(scanResult); + await expect(refreshQqbotAccountScanQrcode('scan-1')).resolves.toBe( + scanResult, + ); + await expect( + submitQqbotAccountScanCaptcha({ + randstr: '@rand', + sessionId: 'scan-1', + ticket: 'ticket', + }), + ).resolves.toBe(scanResult); + await expect(cancelQqbotAccountScan('scan-1')).resolves.toBe(scanResult); + + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/account/scan/create', + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/account/scan/refresh?id=account-1', + ); + expect(requestClient.get).toHaveBeenCalledWith( + '/qqbot/account/scan/status', + { params: { sessionId: 'scan-1' } }, + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/account/scan/qrcode/refresh?sessionId=scan-1', + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/account/scan/captcha/submit', + { + randstr: '@rand', + sessionId: 'scan-1', + ticket: 'ticket', + }, + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/account/scan/cancel?sessionId=scan-1', + ); + expect(getQqbotAccountScanEventsUrl('scan 1')).toBe( + '/api/qqbot/account/scan/events?sessionId=scan%201', + ); + }); }); diff --git a/apps/web-antdv-next/src/api/qqbot/napcat.ts b/apps/web-antdv-next/src/api/qqbot/napcat.ts index 93b5147..d2b553b 100644 --- a/apps/web-antdv-next/src/api/qqbot/napcat.ts +++ b/apps/web-antdv-next/src/api/qqbot/napcat.ts @@ -1,3 +1,5 @@ +import { requestClient } from '#/api/request'; + export type NapcatLoginNewDeviceStatus = | 'confirming' | 'expired' @@ -6,6 +8,41 @@ export type NapcatLoginNewDeviceStatus = | 'scanned' | 'verified'; +export namespace QqbotNapcatApi { + export interface AccountScanResult { + accountId?: string; + captchaUrl?: string; + containerId?: string; + containerName?: string; + deviceVerifyUrl?: string; + errorMessage?: string; + expiresAt?: number; + mode: 'create' | 'refresh'; + newDeviceQrcode?: string; + newDeviceStatus?: NapcatLoginNewDeviceStatus; + qrcode?: string; + selfId?: string; + sessionId?: string; + status: 'error' | 'expired' | 'pending' | 'success'; + webuiPort?: null | number; + } + + export interface AccountScanEvent { + createdAt: number; + message: string; + result?: AccountScanResult; + status: 'error' | 'info' | 'processing' | 'success'; + step: string; + } + + export interface AccountScanCaptchaBody { + randstr: string; + sessionId: string; + sid?: string; + ticket: string; + } +} + export type NapcatLoginDisplayQrcodeSource = { captchaUrl?: string; newDeviceQrcode?: string; @@ -48,3 +85,59 @@ export function getNapcatNewDeviceStatusMessage( if (status === 'failed') return '新设备验证失败'; return '新设备二维码待扫码'; } + +export function startQqbotAccountScanCreate() { + return requestClient.post( + '/qqbot/account/scan/create', + ); +} + +export function startQqbotAccountScanRefresh(id: string) { + return requestClient.post( + `/qqbot/account/scan/refresh?id=${id}`, + ); +} + +export function getQqbotAccountScanStatus(sessionId: string) { + return requestClient.get( + '/qqbot/account/scan/status', + { params: { sessionId } }, + ); +} + +export function refreshQqbotAccountScanQrcode(sessionId: string) { + return requestClient.post( + `/qqbot/account/scan/qrcode/refresh?sessionId=${sessionId}`, + ); +} + +export function submitQqbotAccountScanCaptcha( + data: QqbotNapcatApi.AccountScanCaptchaBody, +) { + return requestClient.post( + '/qqbot/account/scan/captcha/submit', + data, + ); +} + +export function cancelQqbotAccountScan(sessionId: string) { + return requestClient.post( + `/qqbot/account/scan/cancel?sessionId=${sessionId}`, + ); +} + +export function getQqbotAccountScanEventsUrl(sessionId: string) { + return buildApiUrl( + `/qqbot/account/scan/events?sessionId=${encodeURIComponent(sessionId)}`, + ); +} + +function buildApiUrl(path: string) { + const baseUrl = requestClient.getBaseUrl() || ''; + if (!baseUrl) return path; + if (/^https?:\/\//i.test(path)) return path; + if (/^https?:\/\//i.test(baseUrl)) { + return new URL(path, baseUrl).toString(); + } + return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`; +} diff --git a/apps/web-antdv-next/src/api/qqbot/plugin.spec.ts b/apps/web-antdv-next/src/api/qqbot/plugin.spec.ts new file mode 100644 index 0000000..92091a7 --- /dev/null +++ b/apps/web-antdv-next/src/api/qqbot/plugin.spec.ts @@ -0,0 +1,102 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +import { requestClient } from '#/api/request'; + +import { + enableQqbotPluginInstallation, + getQqbotPluginAccountBindings, + getQqbotPluginOperationPage, + getQqbotPluginPlatformInstallations, + getQqbotPluginRuntimeEvents, + installLocalQqbotPluginPackage, + uploadQqbotPluginPackage, + validateQqbotPluginManifest, +} from './plugin'; + +vi.mock('#/api/request', () => ({ + requestClient: { + get: vi.fn(), + getBaseUrl: vi.fn(() => ''), + post: vi.fn(), + }, +})); + +describe('qqbot plugin API wrappers', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it('uses the paged plugin operation endpoint for KtTable', async () => { + const pageResult = { + list: [], + pageNo: 2, + pageSize: 1, + total: 3, + }; + vi.mocked(requestClient.get).mockResolvedValueOnce(pageResult); + + await expect( + getQqbotPluginOperationPage({ + pageNo: 2, + pageSize: 1, + pluginKey: 'bangdream', + triggerMode: 'command', + }), + ).resolves.toBe(pageResult); + + expect(requestClient.get).toHaveBeenCalledWith( + '/qqbot/plugin/operation/page', + { + params: { + pageNo: 2, + pageSize: 1, + pluginKey: 'bangdream', + triggerMode: 'command', + }, + }, + ); + }); + + it('owns plugin-platform management caller routes', async () => { + const manifest = { capabilities: [], key: 'demo' }; + const packageBody = { manifest, packagePath: '/tmp/demo.zip' }; + vi.mocked(requestClient.get).mockResolvedValue([]); + vi.mocked(requestClient.post).mockResolvedValue({}); + + await getQqbotPluginPlatformInstallations(); + await uploadQqbotPluginPackage(packageBody); + await validateQqbotPluginManifest(manifest); + await installLocalQqbotPluginPackage(packageBody); + await enableQqbotPluginInstallation('installation-1'); + await getQqbotPluginRuntimeEvents('demo'); + await getQqbotPluginAccountBindings('demo'); + + expect(requestClient.get).toHaveBeenCalledWith( + '/qqbot/plugin-platform/installations', + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/plugin-platform/upload', + packageBody, + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/plugin-platform/validate', + { manifest }, + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/plugin-platform/install-local', + packageBody, + ); + expect(requestClient.post).toHaveBeenCalledWith( + '/qqbot/plugin-platform/enable', + { id: 'installation-1' }, + ); + expect(requestClient.get).toHaveBeenCalledWith( + '/qqbot/plugin-platform/runtime-events', + { params: { pluginId: 'demo' } }, + ); + expect(requestClient.get).toHaveBeenCalledWith( + '/qqbot/plugin-platform/account-bindings', + { params: { pluginId: 'demo' } }, + ); + }); +}); diff --git a/apps/web-antdv-next/src/api/qqbot/plugin.ts b/apps/web-antdv-next/src/api/qqbot/plugin.ts index 1c8f44c..821992d 100644 --- a/apps/web-antdv-next/src/api/qqbot/plugin.ts +++ b/apps/web-antdv-next/src/api/qqbot/plugin.ts @@ -1,5 +1,7 @@ import type { Recordable } from '@vben/types'; +import type { QqbotApi } from './index'; + import { requestClient } from '#/api/request'; export namespace QqbotPluginPlatformApi { @@ -66,6 +68,60 @@ export namespace QqbotPluginPlatformApi { } } +export function getQqbotPluginList(triggerMode?: QqbotApi.PluginTriggerMode) { + return requestClient.get('/qqbot/plugin/list', { + params: { triggerMode }, + }); +} + +export function getQqbotPluginOperationList( + pluginKey?: string, + triggerMode?: QqbotApi.PluginTriggerMode, +) { + return requestClient.get( + '/qqbot/plugin/operation/list', + { params: { pluginKey, triggerMode } }, + ); +} + +export function getQqbotPluginOperationPage( + params: QqbotApi.PluginOperationQuery, +) { + return requestClient.get>( + '/qqbot/plugin/operation/page', + { params }, + ); +} + +export function getQqbotPluginHealth( + pluginKey?: string, + triggerMode?: QqbotApi.PluginTriggerMode, +) { + return requestClient.get('/qqbot/plugin/health', { + params: { pluginKey, triggerMode }, + }); +} + +export function getQqbotEventPluginList(params?: { selfId?: string }) { + return requestClient.get('/qqbot/plugin/event/list', { + params, + }); +} + +export function bindQqbotEventPlugin(selfId: string, pluginKey: string) { + const params = new URLSearchParams({ pluginKey, selfId }); + return requestClient.post( + `/qqbot/plugin/event/bind?${params.toString()}`, + ); +} + +export function unbindQqbotEventPlugin(selfId: string, pluginKey: string) { + const params = new URLSearchParams({ pluginKey, selfId }); + return requestClient.post( + `/qqbot/plugin/event/unbind?${params.toString()}`, + ); +} + export function getQqbotPluginPlatformInstallations() { return requestClient.get( '/qqbot/plugin-platform/installations', diff --git a/apps/web-antdv-next/src/views/qqbot/account/components/AccountConfigPanel.tsx b/apps/web-antdv-next/src/views/qqbot/account/components/AccountConfigPanel.tsx index 0972a1e..28b5046 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/components/AccountConfigPanel.tsx +++ b/apps/web-antdv-next/src/views/qqbot/account/components/AccountConfigPanel.tsx @@ -12,14 +12,16 @@ import { message, Spin, Tabs, Tag } from 'antdv-next'; import { bindQqbotAccountCommand, bindQqbotAccountRule, - bindQqbotEventPlugin, getQqbotCommandList, - getQqbotEventPluginList, getQqbotRuleList, unbindQqbotAccountCommand, unbindQqbotAccountRule, - unbindQqbotEventPlugin, } from '#/api/qqbot'; +import { + bindQqbotEventPlugin, + getQqbotEventPluginList, + unbindQqbotEventPlugin, +} from '#/api/qqbot/plugin'; import { KtTable } from '#/components/ktTable'; import { 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 5acc8ae..73d0e8f 100644 --- a/apps/web-antdv-next/src/views/qqbot/account/list.tsx +++ b/apps/web-antdv-next/src/views/qqbot/account/list.tsx @@ -1,7 +1,10 @@ import type { TableColumnType } from 'antdv-next'; import type { QqbotApi } from '#/api/qqbot'; -import type { NapcatLoginNewDeviceStatus } from '#/api/qqbot/napcat'; +import type { + NapcatLoginNewDeviceStatus, + QqbotNapcatApi, +} from '#/api/qqbot/napcat'; import type { KtTableApi, KtTableButton, @@ -27,22 +30,22 @@ import { import { useVbenForm } from '#/adapter/form'; import { - cancelQqbotAccountScan, createQqbotAccount, deleteQqbotAccount, getQqbotAccountList, - getQqbotAccountScanEventsUrl, - getQqbotAccountScanStatus, kickQqbotAccount, - refreshQqbotAccountScanQrcode, - startQqbotAccountScanCreate, - startQqbotAccountScanRefresh, - submitQqbotAccountScanCaptcha, updateQqbotAccount, } from '#/api/qqbot'; import { + cancelQqbotAccountScan, getNapcatNewDeviceStatusMessage, + getQqbotAccountScanEventsUrl, + getQqbotAccountScanStatus, + refreshQqbotAccountScanQrcode, resolveNapcatLoginDisplayQrcode, + startQqbotAccountScanCreate, + startQqbotAccountScanRefresh, + submitQqbotAccountScanCaptcha, } from '#/api/qqbot/napcat'; import { KtTable, useKtTable } from '#/components/ktTable'; @@ -87,7 +90,7 @@ export default defineComponent({ const scanQrcodeImageFailed = ref(false); const scanQrcodeRevision = ref(0); const scanQrcodeText = ref(''); - const scanEvents = ref([]); + const scanEvents = ref([]); const scanState = reactive<{ captchaUrl?: string; containerId?: string; @@ -434,7 +437,7 @@ export default defineComponent({ } async function applyScanResult( - result: QqbotApi.AccountScanResult, + result: QqbotNapcatApi.AccountScanResult, options: { reloadQrcode?: boolean } = {}, ) { scanState.captchaUrl = result.captchaUrl; @@ -572,7 +575,7 @@ export default defineComponent({ function handleScanEvent(payload: string) { try { - const event = JSON.parse(payload) as QqbotApi.AccountScanEvent; + const event = JSON.parse(payload) as QqbotNapcatApi.AccountScanEvent; const index = scanEvents.value.findIndex( (item) => item.step === event.step, ); @@ -666,7 +669,9 @@ export default defineComponent({ return '扫码登录请求失败'; } - function getScanStepStatus(status: QqbotApi.AccountScanEvent['status']) { + function getScanStepStatus( + status: QqbotNapcatApi.AccountScanEvent['status'], + ) { if (status === 'error') return 'error'; if (status === 'processing') return 'process'; if (status === 'success') return 'finish'; @@ -1192,7 +1197,7 @@ export default defineComponent({ function requestTencentCaptcha( proofWaterUrl: string, -): Promise> { +): Promise> { const params = parseUrlParams(proofWaterUrl); const appid = params.aid || '2081081773'; const sid = params.sid || ''; @@ -1209,7 +1214,7 @@ function requestTencentCaptcha( let settled = false; const finish = ( error?: Error, - value?: Omit, + value?: Omit, ) => { if (settled) return; settled = true; diff --git a/apps/web-antdv-next/src/views/qqbot/command/list.tsx b/apps/web-antdv-next/src/views/qqbot/command/list.tsx index 285dec5..ddb0403 100644 --- a/apps/web-antdv-next/src/views/qqbot/command/list.tsx +++ b/apps/web-antdv-next/src/views/qqbot/command/list.tsx @@ -19,12 +19,14 @@ import { createQqbotCommand, deleteQqbotCommand, getQqbotCommandList, - getQqbotPluginList, - getQqbotPluginOperationList, testQqbotCommand, toggleQqbotCommand, updateQqbotCommand, } from '#/api/qqbot'; +import { + getQqbotPluginList, + getQqbotPluginOperationList, +} from '#/api/qqbot/plugin'; import { KtTable, useKtTable } from '#/components/ktTable'; import { diff --git a/apps/web-antdv-next/src/views/qqbot/plugin/components/PluginManifestModal.tsx b/apps/web-antdv-next/src/views/qqbot/plugin/components/PluginManifestModal.tsx new file mode 100644 index 0000000..d8b3937 --- /dev/null +++ b/apps/web-antdv-next/src/views/qqbot/plugin/components/PluginManifestModal.tsx @@ -0,0 +1,49 @@ +import { defineComponent } from 'vue'; + +import { Modal } from 'antdv-next'; + +const AModal = Modal as any; + +export default defineComponent({ + name: 'QqBotPluginManifestModal', + props: { + loading: { + default: false, + type: Boolean, + }, + open: { + default: false, + type: Boolean, + }, + title: { + default: '', + type: String, + }, + value: { + default: '', + type: String, + }, + }, + emits: ['close', 'submit', 'update:value'], + setup(props, { emit }) { + return () => ( + emit('close')} + onOk={() => emit('submit')} + open={props.open} + title={props.title} + width={760} + > +