@zhin.js/adapter-discord 1.0.66 → 1.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @zhin.js/adapter-discord
2
2
 
3
+ ## 1.0.68
4
+
5
+ ### Patch Changes
6
+
7
+ - ba30934: fix: web 优化
8
+ - Updated dependencies [ba30934]
9
+ - @zhin.js/console@2.0.5
10
+ - @zhin.js/http@1.0.58
11
+ - zhin.js@1.0.63
12
+
13
+ ## 1.0.67
14
+
15
+ ### Patch Changes
16
+
17
+ - zhin.js@1.0.62
18
+ - @zhin.js/http@1.0.57
19
+
3
20
  ## 1.0.66
4
21
 
5
22
  ### Patch Changes
@@ -0,0 +1,195 @@
1
+ import { useEffect, useState, useCallback } from 'react'
2
+ import { apiFetch } from './utils/api'
3
+ import { RefreshCw, Server, Wifi, WifiOff, Power, PowerOff, Users, Loader2, Globe } from 'lucide-react'
4
+
5
+ interface BotInfo {
6
+ name: string
7
+ connected: boolean
8
+ mode: string
9
+ guildCount: number
10
+ channelCount: number
11
+ status: string
12
+ user: { tag: string; id: string } | null
13
+ }
14
+
15
+ interface GuildInfo {
16
+ id: string
17
+ name: string
18
+ memberCount: number
19
+ icon: string | null
20
+ }
21
+
22
+ type Tab = 'overview' | 'guilds'
23
+
24
+ export default function DiscordDashboard() {
25
+ const [bots, setBots] = useState<BotInfo[]>([])
26
+ const [loading, setLoading] = useState(true)
27
+ const [error, setError] = useState('')
28
+ const [tab, setTab] = useState<Tab>('overview')
29
+ const [actionLoading, setActionLoading] = useState<Record<string, boolean>>({})
30
+
31
+ // Guild browser state
32
+ const [selectedBot, setSelectedBot] = useState('')
33
+ const [guilds, setGuilds] = useState<GuildInfo[]>([])
34
+ const [guildsLoading, setGuildsLoading] = useState(false)
35
+
36
+ const fetchData = useCallback(async () => {
37
+ setLoading(true)
38
+ setError('')
39
+ try {
40
+ const res = await apiFetch('/api/discord/bots')
41
+ const json = await res.json()
42
+ if (json.success) setBots(json.data)
43
+ else setError(json.error || '获取数据失败')
44
+ } catch {
45
+ setError('无法连接服务器')
46
+ } finally {
47
+ setLoading(false)
48
+ }
49
+ }, [])
50
+
51
+ useEffect(() => { fetchData() }, [fetchData])
52
+
53
+ const toggleConnect = async (name: string, connected: boolean) => {
54
+ setActionLoading(prev => ({ ...prev, [name]: true }))
55
+ try {
56
+ const endpoint = connected ? 'disconnect' : 'connect'
57
+ const res = await apiFetch(`/api/discord/bots/${encodeURIComponent(name)}/${endpoint}`, { method: 'POST' })
58
+ const json = await res.json()
59
+ if (!json.success) setError(json.error || '操作失败')
60
+ await fetchData()
61
+ } catch {
62
+ setError('操作失败')
63
+ } finally {
64
+ setActionLoading(prev => ({ ...prev, [name]: false }))
65
+ }
66
+ }
67
+
68
+ const loadGuilds = async (botName: string) => {
69
+ setSelectedBot(botName)
70
+ setGuildsLoading(true)
71
+ setGuilds([])
72
+ try {
73
+ const res = await apiFetch(`/api/discord/bots/${encodeURIComponent(botName)}/guilds`)
74
+ const json = await res.json()
75
+ if (json.success) setGuilds(json.data)
76
+ else setError(json.error || '获取服务器列表失败')
77
+ } catch {
78
+ setError('获取服务器列表失败')
79
+ } finally {
80
+ setGuildsLoading(false)
81
+ }
82
+ }
83
+
84
+ const gatewayBots = bots.filter(b => b.connected && b.mode === 'gateway')
85
+
86
+ return (
87
+ <div className="p-6 max-w-5xl mx-auto">
88
+ <div className="flex items-center justify-between mb-6">
89
+ <h1 className="text-2xl font-bold flex items-center gap-2">
90
+ <Server className="w-6 h-6" /> Discord 机器人
91
+ </h1>
92
+ <button onClick={fetchData} disabled={loading}
93
+ className="flex items-center gap-1 px-3 py-1.5 rounded bg-indigo-500 text-white hover:bg-indigo-600 disabled:opacity-50 text-sm">
94
+ <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} /> 刷新
95
+ </button>
96
+ </div>
97
+
98
+ {error && <div className="mb-4 p-3 bg-red-50 text-red-600 rounded border border-red-200">{error}</div>}
99
+
100
+ {/* Tabs */}
101
+ <div className="flex gap-1 mb-6 border-b">
102
+ <button onClick={() => setTab('overview')}
103
+ className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${tab === 'overview' ? 'border-indigo-500 text-indigo-600' : 'border-transparent text-gray-500 hover:text-gray-700'}`}>
104
+ 概览
105
+ </button>
106
+ <button onClick={() => setTab('guilds')}
107
+ className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${tab === 'guilds' ? 'border-indigo-500 text-indigo-600' : 'border-transparent text-gray-500 hover:text-gray-700'}`}>
108
+ 服务器列表
109
+ </button>
110
+ </div>
111
+
112
+ {/* Overview Tab */}
113
+ {tab === 'overview' && (
114
+ <>
115
+ {!loading && !bots.length && !error && (
116
+ <div className="text-center text-gray-500 py-12">暂无 Discord 机器人实例</div>
117
+ )}
118
+ <div className="grid gap-4 md:grid-cols-2">
119
+ {bots.map((bot) => (
120
+ <div key={bot.name} className="border rounded-lg p-4 bg-card shadow-sm">
121
+ <div className="flex items-center justify-between mb-3">
122
+ <span className="font-medium text-lg">{bot.name}</span>
123
+ {bot.connected
124
+ ? <span className="flex items-center gap-1 text-green-600 text-sm"><Wifi className="w-4 h-4" /> 在线</span>
125
+ : <span className="flex items-center gap-1 text-gray-400 text-sm"><WifiOff className="w-4 h-4" /> 离线</span>}
126
+ </div>
127
+ {bot.user && <div className="text-sm text-gray-500 mb-2">@{bot.user.tag}</div>}
128
+ <div className="grid grid-cols-2 gap-2 text-sm text-gray-600 mb-3">
129
+ <div className="flex justify-between"><span>模式</span><span className="font-mono">{bot.mode}</span></div>
130
+ <div className="flex justify-between"><span>服务器</span><span className="font-mono">{bot.guildCount}</span></div>
131
+ <div className="flex justify-between"><span>频道</span><span className="font-mono">{bot.channelCount}</span></div>
132
+ </div>
133
+ <div className="flex gap-2">
134
+ <button
135
+ onClick={() => toggleConnect(bot.name, bot.connected)}
136
+ disabled={actionLoading[bot.name]}
137
+ className={`flex items-center gap-1 px-3 py-1.5 rounded text-sm text-white ${bot.connected ? 'bg-red-500 hover:bg-red-600' : 'bg-green-500 hover:bg-green-600'} disabled:opacity-50`}>
138
+ {actionLoading[bot.name]
139
+ ? <Loader2 className="w-3.5 h-3.5 animate-spin" />
140
+ : bot.connected ? <PowerOff className="w-3.5 h-3.5" /> : <Power className="w-3.5 h-3.5" />}
141
+ {bot.connected ? '断开' : '连接'}
142
+ </button>
143
+ {bot.connected && bot.mode === 'gateway' && (
144
+ <button onClick={() => { setTab('guilds'); loadGuilds(bot.name) }}
145
+ className="flex items-center gap-1 px-3 py-1.5 rounded text-sm bg-gray-100 hover:bg-gray-200 text-gray-700">
146
+ <Globe className="w-3.5 h-3.5" /> 查看服务器
147
+ </button>
148
+ )}
149
+ </div>
150
+ </div>
151
+ ))}
152
+ </div>
153
+ </>
154
+ )}
155
+
156
+ {/* Guilds Tab */}
157
+ {tab === 'guilds' && (
158
+ <div>
159
+ {gatewayBots.length > 0 && (
160
+ <div className="mb-4 flex items-center gap-2">
161
+ <label className="text-sm text-gray-500">选择机器人:</label>
162
+ <select value={selectedBot} onChange={(e) => loadGuilds(e.target.value)}
163
+ className="border rounded px-2 py-1 text-sm">
164
+ <option value="">--</option>
165
+ {gatewayBots.map(b => <option key={b.name} value={b.name}>{b.name}</option>)}
166
+ </select>
167
+ <span className="text-xs text-gray-400 ml-2">仅 Gateway 模式支持</span>
168
+ </div>
169
+ )}
170
+ {!gatewayBots.length && <div className="text-center text-gray-500 py-8">暂无 Gateway 模式在线机器人</div>}
171
+ {guildsLoading && <div className="flex justify-center py-8"><Loader2 className="w-6 h-6 animate-spin text-indigo-500" /></div>}
172
+
173
+ {!guildsLoading && guilds.length > 0 && (
174
+ <div className="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
175
+ {guilds.map(g => (
176
+ <div key={g.id} className="border rounded-lg p-3 bg-card shadow-sm flex items-center gap-3">
177
+ {g.icon
178
+ ? <img src={g.icon} alt="" className="w-10 h-10 rounded-full" />
179
+ : <div className="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-500 font-bold text-sm">{g.name[0]}</div>}
180
+ <div className="flex-1 min-w-0">
181
+ <div className="font-medium text-sm truncate">{g.name}</div>
182
+ <div className="flex items-center gap-1 text-xs text-gray-400">
183
+ <Users className="w-3 h-3" /> {g.memberCount} 成员
184
+ </div>
185
+ </div>
186
+ </div>
187
+ ))}
188
+ </div>
189
+ )}
190
+ {!guildsLoading && selectedBot && !guilds.length && <div className="text-center text-gray-400 py-8">该机器人未加入任何服务器</div>}
191
+ </div>
192
+ )}
193
+ </div>
194
+ )
195
+ }
@@ -0,0 +1,11 @@
1
+ import { addPage } from '@zhin.js/client'
2
+ import { Gamepad2 } from 'lucide-react'
3
+ import DiscordDashboard from './Dashboard'
4
+
5
+ addPage({
6
+ key: 'discord-management',
7
+ path: '/discord',
8
+ title: 'Discord',
9
+ icon: <Gamepad2 className="w-5 h-5" />,
10
+ element: <DiscordDashboard />,
11
+ })
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../node_modules/@zhin.js/console/browser.tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../dist"
5
+ },
6
+ "include": ["./**/*"]
7
+ }
@@ -0,0 +1,17 @@
1
+ const TOKEN_KEY = "zhin_api_token";
2
+
3
+ export function getToken(): string | null {
4
+ return localStorage.getItem(TOKEN_KEY);
5
+ }
6
+
7
+ export async function apiFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
8
+ const token = getToken();
9
+ const headers = new Headers(init?.headers);
10
+ if (token) headers.set("Authorization", `Bearer ${token}`);
11
+ const res = await fetch(input, { ...init, headers });
12
+ if (res.status === 401) {
13
+ localStorage.removeItem(TOKEN_KEY);
14
+ window.dispatchEvent(new CustomEvent("zhin:auth-required"));
15
+ }
16
+ return res;
17
+ }
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{addPage as e}from"@zhin.js/client";import{Gamepad2 as t,Globe as n,Loader2 as r,Power as i,PowerOff as a,RefreshCw as o,Server as s,Users as c,Wifi as l,WifiOff as u}from"lucide-react";import{useCallback as d,useEffect as f,useState as p}from"react";import{Fragment as m,jsx as h,jsxs as g}from"react/jsx-runtime";var _="zhin_api_token";function v(){return localStorage.getItem(_)}async function y(e2,t2){let n2=v(),r2=new Headers(t2?.headers);n2&&r2.set("Authorization",`Bearer ${n2}`);let i2=await fetch(e2,{...t2,headers:r2});return i2.status===401&&(localStorage.removeItem(_),window.dispatchEvent(new CustomEvent("zhin:auth-required"))),i2}function b(){let[e2,t2]=p([]),[_2,v2]=p(true),[b2,x]=p(""),[S,C]=p("overview"),[w,T]=p({}),[E,D]=p(""),[O,k]=p([]),[A,j]=p(false),M=d(async()=>{v2(true),x("");try{let e3=await(await y("/api/discord/bots")).json();e3.success?t2(e3.data):x(e3.error||"获取数据失败")}catch{x("无法连接服务器")}finally{v2(false)}},[]);f(()=>{M()},[M]);let N=async(e3,t3)=>{T(t4=>({...t4,[e3]:true}));try{let n2=t3?"disconnect":"connect",r2=await(await y(`/api/discord/bots/${encodeURIComponent(e3)}/${n2}`,{method:"POST"})).json();r2.success||x(r2.error||"操作失败"),await M()}catch{x("操作失败")}finally{T(t4=>({...t4,[e3]:false}))}},P=async e3=>{D(e3),j(true),k([]);try{let t3=await(await y(`/api/discord/bots/${encodeURIComponent(e3)}/guilds`)).json();t3.success?k(t3.data):x(t3.error||"获取服务器列表失败")}catch{x("获取服务器列表失败")}finally{j(false)}},F=e2.filter(e3=>e3.connected&&e3.mode==="gateway");return g("div",{className:"p-6 max-w-5xl mx-auto",children:[g("div",{className:"flex items-center justify-between mb-6",children:[g("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[h(s,{className:"w-6 h-6"})," Discord 机器人"]}),g("button",{onClick:M,disabled:_2,className:"flex items-center gap-1 px-3 py-1.5 rounded bg-indigo-500 text-white hover:bg-indigo-600 disabled:opacity-50 text-sm",children:[h(o,{className:`w-4 h-4 ${_2?"animate-spin":""}`})," 刷新"]})]}),b2&&h("div",{className:"mb-4 p-3 bg-red-50 text-red-600 rounded border border-red-200",children:b2}),g("div",{className:"flex gap-1 mb-6 border-b",children:[h("button",{onClick:()=>C("overview"),className:`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${S==="overview"?"border-indigo-500 text-indigo-600":"border-transparent text-gray-500 hover:text-gray-700"}`,children:"概览"}),h("button",{onClick:()=>C("guilds"),className:`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${S==="guilds"?"border-indigo-500 text-indigo-600":"border-transparent text-gray-500 hover:text-gray-700"}`,children:"服务器列表"})]}),S==="overview"&&g(m,{children:[!_2&&!e2.length&&!b2&&h("div",{className:"text-center text-gray-500 py-12",children:"暂无 Discord 机器人实例"}),h("div",{className:"grid gap-4 md:grid-cols-2",children:e2.map(e3=>g("div",{className:"border rounded-lg p-4 bg-card shadow-sm",children:[g("div",{className:"flex items-center justify-between mb-3",children:[h("span",{className:"font-medium text-lg",children:e3.name}),e3.connected?g("span",{className:"flex items-center gap-1 text-green-600 text-sm",children:[h(l,{className:"w-4 h-4"})," 在线"]}):g("span",{className:"flex items-center gap-1 text-gray-400 text-sm",children:[h(u,{className:"w-4 h-4"})," 离线"]})]}),e3.user&&g("div",{className:"text-sm text-gray-500 mb-2",children:["@",e3.user.tag]}),g("div",{className:"grid grid-cols-2 gap-2 text-sm text-gray-600 mb-3",children:[g("div",{className:"flex justify-between",children:[h("span",{children:"模式"}),h("span",{className:"font-mono",children:e3.mode})]}),g("div",{className:"flex justify-between",children:[h("span",{children:"服务器"}),h("span",{className:"font-mono",children:e3.guildCount})]}),g("div",{className:"flex justify-between",children:[h("span",{children:"频道"}),h("span",{className:"font-mono",children:e3.channelCount})]})]}),g("div",{className:"flex gap-2",children:[g("button",{onClick:()=>N(e3.name,e3.connected),disabled:w[e3.name],className:`flex items-center gap-1 px-3 py-1.5 rounded text-sm text-white ${e3.connected?"bg-red-500 hover:bg-red-600":"bg-green-500 hover:bg-green-600"} disabled:opacity-50`,children:[w[e3.name]?h(r,{className:"w-3.5 h-3.5 animate-spin"}):e3.connected?h(a,{className:"w-3.5 h-3.5"}):h(i,{className:"w-3.5 h-3.5"}),e3.connected?"断开":"连接"]}),e3.connected&&e3.mode==="gateway"&&g("button",{onClick:()=>{C("guilds"),P(e3.name)},className:"flex items-center gap-1 px-3 py-1.5 rounded text-sm bg-gray-100 hover:bg-gray-200 text-gray-700",children:[h(n,{className:"w-3.5 h-3.5"})," 查看服务器"]})]})]},e3.name))})]}),S==="guilds"&&g("div",{children:[F.length>0&&g("div",{className:"mb-4 flex items-center gap-2",children:[h("label",{className:"text-sm text-gray-500",children:"选择机器人:"}),g("select",{value:E,onChange:e3=>P(e3.target.value),className:"border rounded px-2 py-1 text-sm",children:[h("option",{value:"",children:"--"}),F.map(e3=>h("option",{value:e3.name,children:e3.name},e3.name))]}),h("span",{className:"text-xs text-gray-400 ml-2",children:"仅 Gateway 模式支持"})]}),!F.length&&h("div",{className:"text-center text-gray-500 py-8",children:"暂无 Gateway 模式在线机器人"}),A&&h("div",{className:"flex justify-center py-8",children:h(r,{className:"w-6 h-6 animate-spin text-indigo-500"})}),!A&&O.length>0&&h("div",{className:"grid gap-3 md:grid-cols-2 lg:grid-cols-3",children:O.map(e3=>g("div",{className:"border rounded-lg p-3 bg-card shadow-sm flex items-center gap-3",children:[e3.icon?h("img",{src:e3.icon,alt:"",className:"w-10 h-10 rounded-full"}):h("div",{className:"w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-500 font-bold text-sm",children:e3.name[0]}),g("div",{className:"flex-1 min-w-0",children:[h("div",{className:"font-medium text-sm truncate",children:e3.name}),g("div",{className:"flex items-center gap-1 text-xs text-gray-400",children:[h(c,{className:"w-3 h-3"})," ",e3.memberCount," 成员"]})]})]},e3.id))}),!A&&E&&!O.length&&h("div",{className:"text-center text-gray-400 py-8",children:"该机器人未加入任何服务器"})]})]})}e({key:"discord-management",path:"/discord",title:"Discord",icon:h(t,{className:"w-5 h-5"}),element:h(b,{})});
package/lib/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
+ import type { WebServer } from "@zhin.js/console";
1
2
  import { DiscordAdapter } from "./adapter.js";
2
3
  declare module "zhin.js" {
3
4
  namespace Plugin {
4
5
  interface Contexts {
5
6
  router: import("@zhin.js/http").Router;
7
+ web: WebServer;
6
8
  }
7
9
  }
8
10
  interface Adapters {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AAEnE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM,CAAC;QACf,UAAU,QAAQ;YAChB,MAAM,EAAE,OAAO,eAAe,EAAE,MAAM,CAAC;SACxC;KACF;IACD,UAAU,QAAQ;QAChB,OAAO,EAAE,cAAc,CAAC;KACzB;CACF;AAED,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AAEnE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM,CAAC;QACf,UAAU,QAAQ;YAChB,MAAM,EAAE,OAAO,eAAe,EAAE,MAAM,CAAC;YACvC,GAAG,EAAE,SAAS,CAAC;SAChB;KACF;IACD,UAAU,QAAQ;QAChB,OAAO,EAAE,cAAc,CAAC;KACzB;CACF;AAED,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Discord 适配器入口:单一适配器,支持 Gateway / Interactions(connection: gateway | interactions)
3
3
  */
4
+ import path from "node:path";
4
5
  import { usePlugin, createGroupManagementTools } from "zhin.js";
5
6
  import { DiscordAdapter } from "./adapter.js";
6
7
  export * from "./types.js";
@@ -211,4 +212,106 @@ useContext('tool', 'discord', (toolService, discord) => {
211
212
  }, 'discord'));
212
213
  return () => disposers.forEach(d => d());
213
214
  });
215
+ // ── Web 控制台 ─────────────────────────────────────────────────────────
216
+ useContext("web", (web) => {
217
+ return web.addEntry(path.resolve(import.meta.dirname, "../client/index.tsx"));
218
+ });
219
+ useContext("router", "discord", (router, discord) => {
220
+ router.get("/api/discord/bots", async (ctx) => {
221
+ try {
222
+ const bots = Array.from(discord.bots.values());
223
+ const result = bots.map((bot) => {
224
+ try {
225
+ const client = bot.client || bot;
226
+ return {
227
+ name: bot.$config.name,
228
+ connected: bot.$connected || false,
229
+ mode: bot.$config.connection || "gateway",
230
+ guildCount: client.guilds?.cache?.size || 0,
231
+ channelCount: client.channels?.cache?.size || 0,
232
+ status: bot.$connected ? "online" : "offline",
233
+ user: client.user ? { tag: client.user.tag, id: client.user.id } : null,
234
+ };
235
+ }
236
+ catch {
237
+ return { name: bot.$config.name, connected: false, mode: "unknown", guildCount: 0, channelCount: 0, status: "error", user: null };
238
+ }
239
+ });
240
+ ctx.body = { success: true, data: result };
241
+ }
242
+ catch {
243
+ ctx.status = 500;
244
+ ctx.body = { success: false, error: "获取机器人数据失败" };
245
+ }
246
+ });
247
+ // Bot 连接/断开
248
+ router.post("/api/discord/bots/:name/connect", async (ctx) => {
249
+ try {
250
+ const bot = discord.bots.get(ctx.params.name);
251
+ if (!bot) {
252
+ ctx.status = 404;
253
+ ctx.body = { success: false, error: "Bot 不存在" };
254
+ return;
255
+ }
256
+ if (bot.$connected) {
257
+ ctx.body = { success: true, message: "已经在线" };
258
+ return;
259
+ }
260
+ await bot.$connect();
261
+ ctx.body = { success: true, message: "连接成功" };
262
+ }
263
+ catch (e) {
264
+ ctx.status = 500;
265
+ ctx.body = { success: false, error: e?.message || "连接失败" };
266
+ }
267
+ });
268
+ router.post("/api/discord/bots/:name/disconnect", async (ctx) => {
269
+ try {
270
+ const bot = discord.bots.get(ctx.params.name);
271
+ if (!bot) {
272
+ ctx.status = 404;
273
+ ctx.body = { success: false, error: "Bot 不存在" };
274
+ return;
275
+ }
276
+ if (!bot.$connected) {
277
+ ctx.body = { success: true, message: "已经离线" };
278
+ return;
279
+ }
280
+ await bot.$disconnect();
281
+ ctx.body = { success: true, message: "已断开" };
282
+ }
283
+ catch (e) {
284
+ ctx.status = 500;
285
+ ctx.body = { success: false, error: e?.message || "断开失败" };
286
+ }
287
+ });
288
+ // 服务器列表(仅 Gateway 模式)
289
+ router.get("/api/discord/bots/:name/guilds", async (ctx) => {
290
+ try {
291
+ const bot = discord.bots.get(ctx.params.name);
292
+ if (!bot) {
293
+ ctx.status = 404;
294
+ ctx.body = { success: false, error: "Bot 不存在" };
295
+ return;
296
+ }
297
+ if (!bot.$connected) {
298
+ ctx.status = 400;
299
+ ctx.body = { success: false, error: "Bot 未连接" };
300
+ return;
301
+ }
302
+ const client = bot.client || bot;
303
+ const guilds = client.guilds?.cache?.map((g) => ({
304
+ id: g.id,
305
+ name: g.name,
306
+ memberCount: g.memberCount,
307
+ icon: g.iconURL({ size: 64 }),
308
+ })) || [];
309
+ ctx.body = { success: true, data: guilds };
310
+ }
311
+ catch (e) {
312
+ ctx.status = 500;
313
+ ctx.body = { success: false, error: e?.message || "获取服务器列表失败" };
314
+ }
315
+ });
316
+ });
214
317
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-discord",
3
- "version": "1.0.66",
3
+ "version": "1.0.68",
4
4
  "description": "Zhin.js adapter for Discord",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -38,12 +38,26 @@
38
38
  "devDependencies": {
39
39
  "@types/koa": "^3.0.0",
40
40
  "@types/node": "^22.9.0",
41
+ "@types/react": "^19.2.2",
42
+ "@types/react-dom": "^19.2.1",
43
+ "lucide-react": "^0.469.0",
41
44
  "typescript": "^5.9.3",
42
- "zhin.js": "1.0.61"
45
+ "@zhin.js/console": "2.0.5",
46
+ "zhin.js": "1.0.63"
43
47
  },
44
48
  "peerDependencies": {
45
- "zhin.js": "1.0.61",
46
- "@zhin.js/http": "1.0.56"
49
+ "@zhin.js/client": "1.0.15",
50
+ "@zhin.js/console": "2.0.5",
51
+ "@zhin.js/http": "1.0.58",
52
+ "zhin.js": "1.0.63"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "@zhin.js/client": {
56
+ "optional": true
57
+ },
58
+ "@zhin.js/console": {
59
+ "optional": true
60
+ }
47
61
  },
48
62
  "files": [
49
63
  "src",
@@ -60,8 +74,8 @@
60
74
  "registry": "https://registry.npmjs.org"
61
75
  },
62
76
  "scripts": {
63
- "build": "pnpm build:node",
64
- "clean": "rimraf lib",
77
+ "build": "tsc && (test -f ../../services/console/lib/bin.js && node ../../services/console/lib/bin.js build || echo 'Skipping client build: console not built yet')",
78
+ "clean": "rimraf lib dist",
65
79
  "build:node": "tsc"
66
80
  }
67
81
  }
package/src/index.ts CHANGED
@@ -1,14 +1,17 @@
1
1
  /**
2
2
  * Discord 适配器入口:单一适配器,支持 Gateway / Interactions(connection: gateway | interactions)
3
3
  */
4
+ import path from "node:path";
4
5
  import { usePlugin, type Plugin, type Context, type IGroupManagement, createGroupManagementTools, type ToolFeature } from "zhin.js";
5
6
  import type { Router } from "@zhin.js/http";
7
+ import type { WebServer } from "@zhin.js/console";
6
8
  import { DiscordAdapter, type DiscordBotLike } from "./adapter.js";
7
9
 
8
10
  declare module "zhin.js" {
9
11
  namespace Plugin {
10
12
  interface Contexts {
11
13
  router: import("@zhin.js/http").Router;
14
+ web: WebServer;
12
15
  }
13
16
  }
14
17
  interface Adapters {
@@ -232,3 +235,83 @@ useContext('tool', 'discord', (toolService: ToolFeature, discord: DiscordAdapter
232
235
 
233
236
  return () => disposers.forEach(d => d());
234
237
  });
238
+
239
+ // ── Web 控制台 ─────────────────────────────────────────────────────────
240
+ useContext("web", (web: WebServer) => {
241
+ return web.addEntry(path.resolve(import.meta.dirname, "../client/index.tsx"));
242
+ });
243
+
244
+ useContext("router", "discord", (router: Router, discord: DiscordAdapter) => {
245
+ router.get("/api/discord/bots", async (ctx: any) => {
246
+ try {
247
+ const bots = Array.from(discord.bots.values());
248
+ const result = bots.map((bot: any) => {
249
+ try {
250
+ const client = bot.client || bot;
251
+ return {
252
+ name: bot.$config.name,
253
+ connected: bot.$connected || false,
254
+ mode: bot.$config.connection || "gateway",
255
+ guildCount: client.guilds?.cache?.size || 0,
256
+ channelCount: client.channels?.cache?.size || 0,
257
+ status: bot.$connected ? "online" : "offline",
258
+ user: client.user ? { tag: client.user.tag, id: client.user.id } : null,
259
+ };
260
+ } catch {
261
+ return { name: bot.$config.name, connected: false, mode: "unknown", guildCount: 0, channelCount: 0, status: "error", user: null };
262
+ }
263
+ });
264
+ ctx.body = { success: true, data: result };
265
+ } catch {
266
+ ctx.status = 500;
267
+ ctx.body = { success: false, error: "获取机器人数据失败" };
268
+ }
269
+ });
270
+
271
+ // Bot 连接/断开
272
+ router.post("/api/discord/bots/:name/connect", async (ctx: any) => {
273
+ try {
274
+ const bot = discord.bots.get(ctx.params.name);
275
+ if (!bot) { ctx.status = 404; ctx.body = { success: false, error: "Bot 不存在" }; return; }
276
+ if (bot.$connected) { ctx.body = { success: true, message: "已经在线" }; return; }
277
+ await bot.$connect();
278
+ ctx.body = { success: true, message: "连接成功" };
279
+ } catch (e: any) {
280
+ ctx.status = 500;
281
+ ctx.body = { success: false, error: e?.message || "连接失败" };
282
+ }
283
+ });
284
+
285
+ router.post("/api/discord/bots/:name/disconnect", async (ctx: any) => {
286
+ try {
287
+ const bot = discord.bots.get(ctx.params.name);
288
+ if (!bot) { ctx.status = 404; ctx.body = { success: false, error: "Bot 不存在" }; return; }
289
+ if (!bot.$connected) { ctx.body = { success: true, message: "已经离线" }; return; }
290
+ await bot.$disconnect();
291
+ ctx.body = { success: true, message: "已断开" };
292
+ } catch (e: any) {
293
+ ctx.status = 500;
294
+ ctx.body = { success: false, error: e?.message || "断开失败" };
295
+ }
296
+ });
297
+
298
+ // 服务器列表(仅 Gateway 模式)
299
+ router.get("/api/discord/bots/:name/guilds", async (ctx: any) => {
300
+ try {
301
+ const bot: any = discord.bots.get(ctx.params.name);
302
+ if (!bot) { ctx.status = 404; ctx.body = { success: false, error: "Bot 不存在" }; return; }
303
+ if (!bot.$connected) { ctx.status = 400; ctx.body = { success: false, error: "Bot 未连接" }; return; }
304
+ const client = bot.client || bot;
305
+ const guilds = client.guilds?.cache?.map((g: any) => ({
306
+ id: g.id,
307
+ name: g.name,
308
+ memberCount: g.memberCount,
309
+ icon: g.iconURL({ size: 64 }),
310
+ })) || [];
311
+ ctx.body = { success: true, data: guilds };
312
+ } catch (e: any) {
313
+ ctx.status = 500;
314
+ ctx.body = { success: false, error: e?.message || "获取服务器列表失败" };
315
+ }
316
+ });
317
+ });