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
This commit is contained in:
1 parent
9eaed2883f
commit
ba42ea2b45
1 file changed
+54
-24
@@ -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<string, string> = {
|
||||
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<string,string>; 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)' }}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`w-2.5 h-2.5 rounded-full ${a.enabled ? '' : ''}`}
|
||||
<div className="w-2.5 h-2.5 rounded-full"
|
||||
style={{ background: a.enabled ? 'var(--mx-tertiary-text)' : 'var(--mx-outline)' }} />
|
||||
<div>
|
||||
<p className="text-sm" style={{ color: 'var(--mx-text)' }}>{a.name}</p>
|
||||
<p className="text-xs" style={{ color: 'var(--mx-text-dim)' }}>
|
||||
{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)}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<button onClick={() => toggle(a)}
|
||||
className={`w-11 h-6 rounded-full relative transition-colors`}
|
||||
className="w-11 h-6 rounded-full relative transition-colors"
|
||||
style={{ background: a.enabled ? 'var(--mx-primary)' : 'var(--mx-outline)' }}
|
||||
>
|
||||
<div className={`absolute top-0.5 w-5 h-5 rounded-full bg-white transition-transform ${a.enabled ? 'translate-x-5.5' : 'translate-x-0.5'}`} />
|
||||
<div className={`absolute top-0.5 w-5 h-5 rounded-full bg-white shadow transition-transform ${a.enabled ? 'translate-x-5.5' : 'translate-x-0.5'}`} />
|
||||
</button>
|
||||
<button onClick={() => startEdit(a)} className="text-xs px-2 py-1 rounded-full" style={{ color: 'var(--mx-text-dim)' }}>编辑</button>
|
||||
<button onClick={() => remove(a.name)} className="text-xs px-2 py-1 rounded-full" style={{ color: 'var(--mx-error)' }}>删除</button>
|
||||
@@ -132,28 +150,40 @@ export default function BridgePage() {
|
||||
</div>
|
||||
|
||||
{fields.map(f => (
|
||||
<input key={f} value={settings[f] || ''} onChange={e => 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)' }} />
|
||||
<div key={f.key} className="space-y-1">
|
||||
<label className="text-xs" style={{ color: 'var(--mx-text-dim)' }}>{f.label}</label>
|
||||
{f.type === 'select' ? (
|
||||
<select value={settings[f.key] || 'client'} onChange={e => setSettings({...settings, [f.key]: e.target.value})}
|
||||
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)' }}>
|
||||
<option value="client">客户端模式 (主动连接 NapCat)</option>
|
||||
<option value="server">服务端模式 (等待 NapCat 连接)</option>
|
||||
</select>
|
||||
) : (
|
||||
<input value={settings[f.key] || ''} onChange={e => 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)' }} />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className="flex gap-2">
|
||||
<div className="flex gap-2 pt-2">
|
||||
<button onClick={save} className="px-4 py-2 rounded-full text-sm font-medium text-white" style={{ background: 'var(--mx-primary)' }}>保存</button>
|
||||
<button onClick={() => setEditing(false)} className="px-4 py-2 rounded-full text-sm" style={{ border: '1px solid var(--mx-outline)', color: 'var(--mx-text-dim)' }}>取消</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Group chat rules */}
|
||||
<div className="rounded-[18px] border p-4 mt-4" style={{ background: 'var(--mx-surface)', borderColor: 'var(--mx-outline)' }}>
|
||||
{/* Rules */}
|
||||
<div className="rounded-[18px] border p-4" style={{ background: 'var(--mx-surface)', borderColor: 'var(--mx-outline)' }}>
|
||||
<h3 className="text-sm font-medium mb-2" style={{ color: 'var(--mx-text)' }}>群聊行为规则</h3>
|
||||
<ul className="text-xs space-y-1 list-disc list-inside" style={{ color: 'var(--mx-text-dim)' }}>
|
||||
<li>消息最大 500 字,超出截断</li>
|
||||
<li>消息最大 500 字,超出自动截断</li>
|
||||
<li>最短发送间隔 3 秒</li>
|
||||
<li>每轮最多 2 条消息</li>
|
||||
<li>非 @ 消息走审查模式</li>
|
||||
<li>闭嘴关键词:闭嘴 / 别说话 / 安静</li>
|
||||
<li>非 @ 消息走审查模式(LLM 自主判断是否回复)</li>
|
||||
<li>闭嘴关键词:闭嘴 / 别说话 / 安静 / shut up</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user