fix: 拆分QQBot账号状态展示

This commit is contained in:
sunlei 2026-06-12 21:40:43 +08:00
parent 176e139017
commit ab43fe8632
3 changed files with 89 additions and 10 deletions

View File

@ -47,6 +47,7 @@ pnpm run build:antdv-next
## 业务页面 ## 业务页面
- 系统管理 / 站内信是日志级通知列表,只展示 API 错误、QQBot 下线、NapCat 离线等后端自动捕获事件;页面提供筛选、处理/重新打开、置顶和删除,不提供人工新增或编辑。 - 系统管理 / 站内信是日志级通知列表,只展示 API 错误、QQBot 下线、NapCat 离线等后端自动捕获事件;页面提供筛选、处理/重新打开、置顶和删除,不提供人工新增或编辑。
- QQBot / 账号连接页拆分 OneBot 连接、QQ 登录、NapCat 运行和运行说明列;更新登录通过 SSE 展示 quick / password / qrcode 每步进度。
## 部署说明 ## 部署说明

View File

@ -53,11 +53,21 @@ export namespace QqbotApi {
bindStatus?: 'bound' | 'disabled' | 'pending'; bindStatus?: 'bound' | 'disabled' | 'pending';
containerId?: string; containerId?: string;
containerName?: string; containerName?: string;
containerOnline?: boolean;
containerStatus?: 'creating' | 'error' | 'running' | 'stopped'; containerStatus?: 'creating' | 'error' | 'running' | 'stopped';
lastCheckedAt?: string; lastCheckedAt?: string;
lastError?: string; lastError?: string;
lastLoginAt?: string; lastLoginAt?: string;
lastStartedAt?: string; lastStartedAt?: string;
oneBotOnline?: boolean;
qqLoginMessage?: null | string;
qqLoginStatus?:
| 'offline'
| 'online'
| 'qrcode_expired'
| 'qrcode_pending'
| 'unknown';
webuiOnline?: boolean | null;
webuiPort?: null | number; webuiPort?: null | number;
} }

View File

@ -184,14 +184,20 @@ export default defineComponent({
{ {
dataIndex: 'connectStatus', dataIndex: 'connectStatus',
key: 'accountOnlineStatus', key: 'accountOnlineStatus',
title: '账号在线', title: 'OneBot 连接',
width: 130, width: 140,
},
{
dataIndex: 'napcat',
key: 'qqLoginStatus',
title: 'QQ 登录',
width: 150,
}, },
{ {
dataIndex: 'napcat', dataIndex: 'napcat',
key: 'napcatRuntime', key: 'napcatRuntime',
title: 'NapCat 容器', title: 'NapCat 运行',
width: 220, width: 240,
}, },
{ {
dataIndex: 'lastHeartbeatAt', dataIndex: 'lastHeartbeatAt',
@ -302,7 +308,7 @@ export default defineComponent({
], ],
}, },
fieldName: 'connectStatus', fieldName: 'connectStatus',
label: '账号在线', label: 'OneBot',
}, },
], ],
}, },
@ -626,19 +632,38 @@ export default defineComponent({
if (!row.enabled) { if (!row.enabled) {
return <Tag color="default"></Tag>; return <Tag color="default"></Tag>;
} }
const online = row.napcat?.oneBotOnline ?? row.connectStatus === 'online';
return ( return (
<Tag color={row.connectStatus === 'online' ? 'success' : 'default'}> <Tag color={online ? 'success' : 'default'}>
{row.connectStatus === 'online' ? 'OneBot 在线' : 'OneBot 离线'} {online ? 'OneBot 在线' : 'OneBot 离线'}
</Tag> </Tag>
); );
}; };
const renderQqLoginStatus = (row: QqbotApi.Account) => {
const meta = getQqLoginStatusMeta(row.napcat);
return (
<Space direction="vertical" size={2}>
<Tag color={meta.color}>{meta.label}</Tag>
{row.napcat?.qqLoginMessage ? (
<ATypographyText type="secondary">
{row.napcat.qqLoginMessage}
</ATypographyText>
) : null}
</Space>
);
};
const renderNapcatRuntime = (row: QqbotApi.Account) => { const renderNapcatRuntime = (row: QqbotApi.Account) => {
const napcat = row.napcat; const napcat = row.napcat;
const meta = getNapcatStatusMeta(napcat); const meta = getNapcatStatusMeta(napcat);
const webuiMeta = getNapcatWebuiMeta(napcat);
return ( return (
<Space direction="vertical" size={2}> <Space direction="vertical" size={2}>
<Space size={4} wrap>
<Tag color={meta.color}>{meta.label}</Tag> <Tag color={meta.color}>{meta.label}</Tag>
<Tag color={webuiMeta.color}>{webuiMeta.label}</Tag>
</Space>
{napcat?.containerName ? ( {napcat?.containerName ? (
<ATypographyText type="secondary"> <ATypographyText type="secondary">
{napcat.containerName} {napcat.containerName}
@ -694,6 +719,34 @@ export default defineComponent({
return statusMap[napcat.containerStatus]; return statusMap[napcat.containerStatus];
} }
function getNapcatWebuiMeta(napcat?: null | QqbotApi.AccountNapcatRuntime) {
if (!napcat) return { color: 'default', label: 'WebUI 未绑定' };
if (napcat.webuiOnline === true) {
return { color: 'success', label: 'WebUI 可用' };
}
if (napcat.webuiOnline === false) {
return { color: 'error', label: 'WebUI 不可用' };
}
return { color: 'default', label: 'WebUI 未检查' };
}
function getQqLoginStatusMeta(
napcat?: null | QqbotApi.AccountNapcatRuntime,
) {
if (!napcat) return { color: 'default', label: '未绑定容器' };
const statusMap: Record<
NonNullable<QqbotApi.AccountNapcatRuntime['qqLoginStatus']>,
{ color: string; label: string }
> = {
offline: { color: 'error', label: 'QQ 离线' },
online: { color: 'success', label: 'QQ 在线' },
qrcode_expired: { color: 'warning', label: '二维码过期' },
qrcode_pending: { color: 'processing', label: '等待扫码' },
unknown: { color: 'default', label: '状态未知' },
};
return statusMap[napcat.qqLoginStatus || 'unknown'];
}
function getRecentActivity(row: QqbotApi.Account) { function getRecentActivity(row: QqbotApi.Account) {
const candidates = [ const candidates = [
{ label: '最近心跳', value: row.lastHeartbeatAt }, { label: '最近心跳', value: row.lastHeartbeatAt },
@ -719,14 +772,26 @@ export default defineComponent({
if (row.lastError) { if (row.lastError) {
return { level: 'warning', text: `账号异常:${row.lastError}` }; return { level: 'warning', text: `账号异常:${row.lastError}` };
} }
if (row.napcat?.qqLoginMessage) {
return {
level: 'warning',
text: `QQ 登录:${row.napcat.qqLoginMessage}`,
};
}
if (row.napcat?.lastError) { if (row.napcat?.lastError) {
return { level: 'warning', text: `容器异常:${row.napcat.lastError}` }; return { level: 'warning', text: `NapCat${row.napcat.lastError}` };
}
if (row.napcat?.qqLoginStatus === 'qrcode_expired') {
return { level: 'warning', text: '二维码已过期,点击更新登录' };
} }
if (row.connectStatus === 'online') { if (row.connectStatus === 'online') {
return { level: 'normal', text: '消息链路可用' }; return { level: 'normal', text: '消息链路可用' };
} }
if (row.napcat?.qqLoginStatus === 'online') {
return { level: 'warning', text: 'QQ 在线,等待 OneBot 连接' };
}
if (row.napcat?.containerStatus === 'running') { if (row.napcat?.containerStatus === 'running') {
return { level: 'warning', text: '等待反向 WS' }; return { level: 'warning', text: 'NapCat 运行中,等待 OneBot 连接' };
} }
if (row.napcat?.containerStatus === 'creating') { if (row.napcat?.containerStatus === 'creating') {
return { level: 'warning', text: '容器创建中' }; return { level: 'warning', text: '容器创建中' };
@ -840,6 +905,9 @@ export default defineComponent({
if (column.key === 'accountOnlineStatus') { if (column.key === 'accountOnlineStatus') {
return renderAccountOnlineStatus(row); return renderAccountOnlineStatus(row);
} }
if (column.key === 'qqLoginStatus') {
return renderQqLoginStatus(row);
}
if (column.key === 'napcatRuntime') { if (column.key === 'napcatRuntime') {
return renderNapcatRuntime(row); return renderNapcatRuntime(row);
} }