From ba42ea2b451b384a9697c19863fb3a9280249cbf Mon Sep 17 00:00:00 2001 From: Aska Date: Wed, 12 Aug 2026 18:12:39 +0800 Subject: [PATCH] fix(bridge): add complete OBv11 fields matching v1 ethend - OBv11: mode (client/server), remote_url, access_token, http_url, http_token, bot_port, send_interval_ms, admin_uids (8 fields) - Telegram: bot_token, webhook_url, admin_uids - Discord/Webhook: proper fields with labels - Mode dropdown selector for client/server - Field labels and placeholders matching v1 --- frontend/web/src/pages/admin/BridgePage.tsx | 78 ++++++++++++++------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/frontend/web/src/pages/admin/BridgePage.tsx b/frontend/web/src/pages/admin/BridgePage.tsx index e3b957c..7b0ace1 100644 --- a/frontend/web/src/pages/admin/BridgePage.tsx +++ b/frontend/web/src/pages/admin/BridgePage.tsx @@ -1,17 +1,34 @@ import { useEffect, useState } from 'react' import { getToken } from '../../api/client' -const platformTypes = [ - { value: 'qq-obv11', label: 'QQ (OBv11)', fields: ['ws_url', 'access_token', 'bot_qq'] }, - { value: 'telegram', label: 'Telegram', fields: ['token'] }, - { value: 'discord', label: 'Discord', fields: ['token'] }, - { value: 'webhook', label: 'Webhook', fields: ['listen_addr'] }, -] +interface FieldDef { key: string; label: string; placeholder: string; type?: string } +interface PlatformDef { value: string; label: string; fields: FieldDef[] } -const fieldLabels: Record = { - ws_url: 'WebSocket 地址', access_token: 'Access Token', bot_qq: 'Bot QQ 号', - token: 'Bot Token', listen_addr: '监听地址', -} +const platformTypes: PlatformDef[] = [ + { value: 'qq-obv11', label: 'QQ (OBv11)', fields: [ + { key: 'mode', label: '连接模式', placeholder: '', type: 'select' }, + { key: 'remote_url', label: 'NapCat OneBot WS 地址', placeholder: 'ws://127.0.0.1:10311' }, + { key: 'access_token', label: 'Access Token (可选)', placeholder: '留空则不验证' }, + { key: 'http_url', label: 'NapCat HTTP API 地址 (可选)', placeholder: 'http://127.0.0.1:6099' }, + { key: 'http_token', label: 'HTTP API Token (可选)', placeholder: '留空则使用 Access Token' }, + { key: 'bot_port', label: '本地监听端口', placeholder: '8096' }, + { key: 'send_interval_ms', label: '消息发送间隔 (ms, 防封控)', placeholder: '2000' }, + { key: 'admin_uids', label: '管理员 QQ 号 (逗号分隔)', placeholder: '123456789,987654321' }, + ]}, + { value: 'telegram', label: 'Telegram', fields: [ + { key: 'bot_token', label: 'Bot Token', placeholder: '123456:ABC-DEF...' }, + { key: 'webhook_url', label: 'Webhook URL', placeholder: 'https://your-domain.com' }, + { key: 'admin_uids', label: '管理员账号ID (逗号分隔)', placeholder: '123456789,987654321' }, + ]}, + { value: 'discord', label: 'Discord', fields: [ + { key: 'bot_token', label: 'Bot Token', placeholder: '...' }, + { key: 'webhook_url', label: 'Webhook URL (可选)', placeholder: 'https://...' }, + ]}, + { value: 'webhook', label: 'Webhook', fields: [ + { key: 'webhook_url', label: 'Webhook URL', placeholder: 'https://hook.example.com/chat' }, + { key: 'secret', label: 'Secret Token (可选)', placeholder: '' }, + ]}, +] interface Adapter { name:string; type:string; enabled:boolean; settings:Record; created_at:string } @@ -58,7 +75,7 @@ export default function BridgePage() { const startEdit = (a?: Adapter) => { if (a) { setName(a.name); setAdType(a.type); setSettings(a.settings || {}) } - else { setName(''); setSettings({}) } + else { setName(''); setAdType('qq-obv11'); setSettings({}) } setEditing(true) } @@ -91,22 +108,23 @@ export default function BridgePage() { style={{ background: 'var(--mx-surface)', borderColor: 'var(--mx-outline)' }} >
-

{a.name}

{platformTypes.find(p=>p.value===a.type)?.label || a.type} + {a.settings?.mode && ` · ${a.settings.mode === 'server' ? '服务端模式' : '客户端模式'}`} {a.created_at && ` · ${a.created_at.slice(0,10)}`}

@@ -132,28 +150,40 @@ export default function BridgePage() {
{fields.map(f => ( - setSettings({...settings, [f]: e.target.value})} - placeholder={fieldLabels[f] || f} - className="w-full rounded-[14px] border px-3 py-2 text-sm outline-none" - style={{ background: 'var(--mx-surface)', borderColor: 'var(--mx-outline)', color: 'var(--mx-text)' }} /> +
+ + {f.type === 'select' ? ( + + ) : ( + setSettings({...settings, [f.key]: e.target.value})} + placeholder={f.placeholder} + className="w-full rounded-[14px] border px-3 py-2 text-sm outline-none" + style={{ background: 'var(--mx-surface)', borderColor: 'var(--mx-outline)', color: 'var(--mx-text)' }} /> + )} +
))} -
+
)} - {/* Group chat rules */} -
+ {/* Rules */} +

群聊行为规则

    -
  • 消息最大 500 字,超出截断
  • +
  • 消息最大 500 字,超出自动截断
  • 最短发送间隔 3 秒
  • 每轮最多 2 条消息
  • -
  • 非 @ 消息走审查模式
  • -
  • 闭嘴关键词:闭嘴 / 别说话 / 安静
  • +
  • 非 @ 消息走审查模式(LLM 自主判断是否回复)
  • +
  • 闭嘴关键词:闭嘴 / 别说话 / 安静 / shut up