feat: add user-level WeChat channel accounts
This commit is contained in:
1 parent
46e7f6f1cd
commit
b7d8b1298f
15 files changed
+575
-63
No files matched your search
@@ -7,7 +7,6 @@ import { cloudAgentsApi } from '@/lib/cloud-agents-api';
|
||||
import type { CloudAccess as Access, CloudApplication, CloudKey } from '../../../shared/cloud-agents';
|
||||
import { CloudCosts } from './CloudCosts';
|
||||
import { CloudLifecycle } from './CloudLifecycle';
|
||||
import { CloudChannelPanel } from './CloudChannelPanel';
|
||||
import type { CloudAgentDraft } from '../../../shared/cloud-agents';
|
||||
import type { CloudAgentOperations } from '../../../shared/cloud-agents';
|
||||
import { cloudStatus } from './CloudChat';
|
||||
@@ -71,7 +70,7 @@ export function CloudAccessPanel({ slug, revision, onPublished, onChanged, activ
|
||||
<Button variant="outline" size="sm" disabled={busy} onClick={() => void act(() => cloudAgentsApi.call('setEnabled', { slug, enabled: !access.enabled }))}>
|
||||
{access.enabled ? '停用智能体' : '启用智能体'}</Button></div>}
|
||||
</section>
|
||||
{access?.published_version && <CloudChannelPanel slug={slug} publishedVersion={access.published_version} activeView={activeView} />}
|
||||
{access?.published_version && <LinkedChannels slug={slug} activeView={activeView} />}
|
||||
{error && <p role="alert" className="text-sm text-destructive">{error} <Button variant="ghost" onClick={() => void act(refresh)}>刷新状态</Button></p>}
|
||||
{notice && <p role="status" className="text-sm text-muted-foreground">{notice}</p>}
|
||||
<section className="space-y-4"><h2 className="font-medium">分享给指定用户</h2>
|
||||
@@ -108,6 +107,31 @@ export function CloudAccessPanel({ slug, revision, onPublished, onChanged, activ
|
||||
</div>;
|
||||
}
|
||||
|
||||
function LinkedChannels({ slug, activeView }: { slug: string; activeView: boolean }) {
|
||||
const [items, setItems] = useState<CloudAgentOperations['channelBindings']['output']['items']>([]);
|
||||
const [error, setError] = useState('');
|
||||
useEffect(() => {
|
||||
if (!activeView) return;
|
||||
let live = true;
|
||||
void cloudAgentsApi.call('channelBindings', { slug }).then(result => {
|
||||
if (live) { setItems(result.items); setError(''); }
|
||||
}).catch(error => { if (live) setError(errorText(error)); });
|
||||
return () => { live = false; };
|
||||
}, [activeView, slug]);
|
||||
return <section aria-label="已关联渠道" className="space-y-3 rounded-xl border border-border p-5">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3"><div><h2 className="font-medium">已关联渠道</h2>
|
||||
<p className="mt-1 text-sm text-muted-foreground">微信账号统一在“渠道”中连接、切换目标和管理使用权限。</p></div>
|
||||
<Button variant="outline" onClick={() => { window.location.hash = `#/cloud-agents/channels?target=${encodeURIComponent(slug)}`; }}>打开渠道</Button></div>
|
||||
{error && <p role="alert" className="text-sm text-destructive">{error}</p>}
|
||||
{!error && items.length === 0 && <p className="text-sm text-muted-foreground">暂时没有关联的微信账号。打开渠道后会预选当前智能体。</p>}
|
||||
{items.map(item => <button key={item.id} type="button" className="flex w-full items-center justify-between gap-3 rounded-lg bg-muted/30 p-3 text-left text-sm"
|
||||
onClick={() => { window.location.hash = `#/cloud-agents/channels?account=${encodeURIComponent(item.id)}`; }}>
|
||||
<span><strong>{item.display_name}</strong><span className="mt-1 block text-xs text-muted-foreground">{item.health === 'connected' ? '微信已连接' : '微信待连接'}</span></span>
|
||||
<span className="text-xs text-muted-foreground">{item.enabled ? '已启用' : '已暂停'} · 管理</span>
|
||||
</button>)}
|
||||
</section>;
|
||||
}
|
||||
|
||||
function ApplicationKeys({ application, onUpdated }: { application: CloudApplication; onUpdated: () => Promise<void> }) {
|
||||
const [keys, setKeys] = useState<CloudKey[]>([]);
|
||||
const [secret, setSecret] = useState('');
|
||||
|
||||
Reference in new issue
Block a user