@zhin.js/client 1.0.0 → 1.0.1

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.
Files changed (43) hide show
  1. package/README.md +334 -67
  2. package/app/index.html +4 -3
  3. package/app/postcss.config.js +5 -0
  4. package/app/src/components/ThemeToggle.tsx +21 -0
  5. package/app/src/hooks/useTheme.ts +17 -0
  6. package/app/src/layouts/dashboard.tsx +259 -0
  7. package/app/src/main.tsx +121 -0
  8. package/app/src/pages/dashboard-bots.tsx +198 -0
  9. package/app/src/pages/dashboard-home.tsx +301 -0
  10. package/app/src/pages/dashboard-logs.tsx +298 -0
  11. package/app/src/pages/dashboard-plugin-detail.tsx +360 -0
  12. package/app/src/pages/dashboard-plugins.tsx +166 -0
  13. package/app/src/style.css +1105 -0
  14. package/app/src/theme/index.ts +92 -0
  15. package/app/tailwind.config.js +70 -0
  16. package/app/tsconfig.json +5 -0
  17. package/dist/index.js +15 -3
  18. package/package.json +20 -7
  19. package/src/index.ts +19 -3
  20. package/src/router/index.tsx +55 -0
  21. package/src/store/index.ts +111 -0
  22. package/src/store/reducers/index.ts +16 -0
  23. package/src/store/reducers/route.ts +122 -0
  24. package/src/store/reducers/script.ts +103 -0
  25. package/src/store/reducers/ui.ts +31 -0
  26. package/src/types.ts +11 -17
  27. package/src/websocket/index.ts +193 -0
  28. package/src/websocket/useWebSocket.ts +42 -0
  29. package/app/components.d.ts +0 -33
  30. package/app/src/App.vue +0 -7
  31. package/app/src/main.ts +0 -127
  32. package/app/src/pages/$.vue +0 -899
  33. package/app/src/pages/404.vue +0 -11
  34. package/app/src/pages/contexts/overview.vue +0 -177
  35. package/app/src/pages/dashboard.vue +0 -323
  36. package/app/src/pages/plugins/installed.vue +0 -734
  37. package/app/src/pages/system/status.vue +0 -241
  38. package/app/src/services/api.ts +0 -155
  39. package/app/src/styles/README.md +0 -202
  40. package/app/src/styles/common.css +0 -0
  41. package/global.d.ts +0 -19
  42. package/src/router.ts +0 -44
  43. package/src/store.ts +0 -53
@@ -1,241 +0,0 @@
1
- <template>
2
- <div class="page-layout">
3
- <!-- 页面头部 -->
4
- <Card class="page-header-card">
5
- <template #content>
6
- <div class="flex-row justify-between">
7
- <div class="flex-row">
8
- <div class="icon-container icon-primary">
9
- <i class="pi pi-info-circle"></i>
10
- </div>
11
- <div class="flex-column">
12
- <h1>系统状态</h1>
13
- <p>实时监控 Zhin Bot 框架运行状态</p>
14
- </div>
15
- </div>
16
- <Button
17
- icon="pi pi-refresh"
18
- label="刷新"
19
- @click="refreshData"
20
- :loading="refreshing"
21
- severity="secondary"
22
- outlined
23
- />
24
- </div>
25
- </template>
26
- </Card>
27
-
28
- <!-- 统计卡片 -->
29
- <div class="stats-container">
30
- <Card class="stats-card">
31
- <template #content>
32
- <div class="flex-row gap-large">
33
- <div class="icon-container icon-uptime">
34
- <i class="pi pi-clock"></i>
35
- </div>
36
- <div class="flex-column flex-1">
37
- <div class="stat-value">{{ formatUptime(systemData?.uptime) }}</div>
38
- <div class="stat-label">运行时间</div>
39
- <div class="stat-sub">系统持续运行</div>
40
- </div>
41
- </div>
42
- </template>
43
- </Card>
44
-
45
- <Card class="stats-card">
46
- <template #content>
47
- <div class="flex-row gap-large">
48
- <div class="icon-container icon-platform">
49
- <i class="pi pi-desktop"></i>
50
- </div>
51
- <div class="flex-column flex-1">
52
- <div class="stat-value">{{ systemData?.platform }}</div>
53
- <div class="stat-label">运行平台</div>
54
- <div class="stat-sub">操作系统</div>
55
- </div>
56
- </div>
57
- </template>
58
- </Card>
59
-
60
- <Card class="stats-card">
61
- <template #content>
62
- <div class="flex-row gap-large">
63
- <div class="icon-container icon-nodejs">
64
- <i class="pi pi-code"></i>
65
- </div>
66
- <div class="flex-column flex-1">
67
- <div class="stat-value">{{ systemData?.nodeVersion }}</div>
68
- <div class="stat-label">Node.js</div>
69
- <div class="stat-sub">运行时版本</div>
70
- </div>
71
- </div>
72
- </template>
73
- </Card>
74
- </div>
75
-
76
- <!-- 主要内容区域 -->
77
- <div class="layout-container">
78
- <!-- 左侧:系统信息 -->
79
- <div class="layout-main">
80
- <Card class="content-card">
81
- <template #title>
82
- <i class="pi pi-desktop"></i>
83
- <span>系统信息</span>
84
- </template>
85
- <template #content>
86
- <div class="detail-grid">
87
- <div class="detail-item">
88
- <div class="icon-container icon-small icon-blue">
89
- <i class="pi pi-hashtag"></i>
90
- </div>
91
- <div class="flex-column flex-1">
92
- <div class="detail-label">进程 ID</div>
93
- <div class="detail-value">{{ systemData?.pid }}</div>
94
- </div>
95
- </div>
96
-
97
- <div class="detail-item">
98
- <div class="icon-container icon-small icon-green">
99
- <i class="pi pi-clock"></i>
100
- </div>
101
- <div class="flex-column flex-1">
102
- <div class="detail-label">运行时间</div>
103
- <div class="detail-value">{{ formatUptime(systemData?.uptime) }}</div>
104
- </div>
105
- </div>
106
-
107
- <div class="detail-item">
108
- <div class="icon-container icon-small icon-purple">
109
- <i class="pi pi-desktop"></i>
110
- </div>
111
- <div class="flex-column flex-1">
112
- <div class="detail-label">操作系统</div>
113
- <div class="detail-value">{{ systemData?.platform }}</div>
114
- </div>
115
- </div>
116
-
117
- <div class="detail-item">
118
- <div class="icon-container icon-small icon-orange">
119
- <i class="pi pi-code"></i>
120
- </div>
121
- <div class="flex-column flex-1">
122
- <div class="detail-label">Node.js 版本</div>
123
- <div class="detail-value">{{ systemData?.nodeVersion }}</div>
124
- </div>
125
- </div>
126
- </div>
127
- </template>
128
- </Card>
129
- </div>
130
-
131
- <!-- 右侧:内存使用 -->
132
- <div class="layout-sidebar">
133
- <Card class="content-card">
134
- <template #title>
135
- <i class="pi pi-chart-bar"></i>
136
- <span>内存使用</span>
137
- </template>
138
- <template #content>
139
- <div class="detail-grid">
140
- <div class="detail-item">
141
- <div class="icon-container icon-small icon-blue">
142
- <i class="pi pi-chart-line"></i>
143
- </div>
144
- <div class="flex-column flex-1">
145
- <div class="detail-label">已用内存</div>
146
- <div class="detail-value">{{ formatMemory(systemData?.memory.heapUsed) }}</div>
147
- </div>
148
- </div>
149
-
150
- <div class="detail-item">
151
- <div class="icon-container icon-small icon-green">
152
- <i class="pi pi-chart-pie"></i>
153
- </div>
154
- <div class="flex-column flex-1">
155
- <div class="detail-label">总内存</div>
156
- <div class="detail-value">{{ formatMemory(systemData?.memory.heapTotal) }}</div>
157
- </div>
158
- </div>
159
-
160
- <div class="detail-item">
161
- <div class="icon-container icon-small icon-purple">
162
- <i class="pi pi-percentage"></i>
163
- </div>
164
- <div class="flex-column flex-1">
165
- <div class="detail-label">使用率</div>
166
- <div class="detail-value">{{ memoryUsagePercent }}%</div>
167
- <ProgressBar
168
- :value="memoryUsagePercent"
169
- :showValue="false"
170
- />
171
- </div>
172
- </div>
173
- </div>
174
- </template>
175
- </Card>
176
- </div>
177
- </div>
178
- </div>
179
- </template>
180
-
181
- <script setup lang="ts">
182
- import { computed, ref } from 'vue'
183
- import { useCommonStore } from '@zhin.js/client'
184
-
185
- const commonStore = useCommonStore()
186
- const refreshing = ref(false)
187
-
188
- // 系统数据
189
- const systemData = computed(() => (commonStore.store as any).system)
190
-
191
- // 内存使用百分比
192
- const memoryUsagePercent = computed(() => {
193
- if (!systemData.value?.memory) return 0
194
- const { heapUsed, heapTotal } = systemData.value.memory
195
- return Math.round((heapUsed / heapTotal) * 100)
196
- })
197
-
198
- // 格式化函数
199
- const formatUptime = (seconds?: number) => {
200
- if (!seconds) return '0秒'
201
-
202
- const hours = Math.floor(seconds / 3600)
203
- const minutes = Math.floor((seconds % 3600) / 60)
204
-
205
- if (hours > 0) {
206
- return `${hours}小时${minutes}分钟`
207
- } else if (minutes > 0) {
208
- return `${minutes}分钟`
209
- } else {
210
- return `${Math.floor(seconds)}秒`
211
- }
212
- }
213
-
214
- const formatMemory = (bytes?: number) => {
215
- if (!bytes) return '0B'
216
-
217
- const sizes = ['B', 'KB', 'MB', 'GB']
218
- const i = Math.floor(Math.log(bytes) / Math.log(1024))
219
- return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`
220
- }
221
-
222
- // 刷新数据
223
- const refreshData = async () => {
224
- refreshing.value = true
225
- try {
226
- if (window.ZhinDataAPI?.updateAllData) {
227
- await window.ZhinDataAPI.updateAllData()
228
- } else {
229
- throw new Error('全局API未就绪')
230
- }
231
- } catch (error) {
232
- // console.error 已替换为注释
233
- } finally {
234
- refreshing.value = false
235
- }
236
- }
237
- </script>
238
-
239
- <style scoped>
240
- /* 页面特定样式 - 所有样式已移至 common.css,使用PrimeVue组件类名控制 */
241
- </style>
@@ -1,155 +0,0 @@
1
- import { useCommonStore } from '@zhin.js/client'
2
-
3
- // API 基础配置
4
- const getBaseUrl = () => `${window.location.protocol}//${window.location.host}`
5
-
6
- // 通用的 API 请求函数
7
- const apiRequest = async (endpoint: string) => {
8
- try {
9
- const response = await fetch(`${getBaseUrl()}${endpoint}`)
10
- return await response.json()
11
- } catch (error) {
12
- // console.error 已替换为注释
13
- return { success: false, error: error.message }
14
- }
15
- }
16
-
17
- // 数据获取服务
18
- export const DataService = {
19
- // 获取系统状态
20
- async getSystemStatus() {
21
- return await apiRequest('/api/system/status')
22
- },
23
-
24
- // 获取插件列表
25
- async getPlugins() {
26
- return await apiRequest('/api/plugins')
27
- },
28
-
29
- // 获取适配器列表
30
- async getAdapters() {
31
- return await apiRequest('/api/adapters')
32
- },
33
-
34
- // 获取配置信息
35
- async getConfig() {
36
- return await apiRequest('/api/config')
37
- },
38
-
39
- // 获取日志
40
- async getLogs() {
41
- return await apiRequest('/api/logs')
42
- },
43
-
44
- // 健康检查
45
- async healthCheck() {
46
- return await apiRequest('/api/health')
47
- },
48
-
49
- // 发送消息
50
- async sendMessage(data: {
51
- context: string
52
- bot: string
53
- id: string
54
- type: string
55
- content: string
56
- }) {
57
- try {
58
- const response = await fetch(`${getBaseUrl()}/api/message/send`, {
59
- method: 'POST',
60
- headers: {
61
- 'Content-Type': 'application/json'
62
- },
63
- body: JSON.stringify(data)
64
- })
65
- return await response.json()
66
- } catch (error) {
67
- // console.error 已替换为注释
68
- return { success: false, error: error.message }
69
- }
70
- },
71
-
72
- // 重载插件
73
- async reloadPlugin(pluginName: string) {
74
- try {
75
- const response = await fetch(`${getBaseUrl()}/api/plugins/${pluginName}/reload`, {
76
- method: 'POST'
77
- })
78
- return await response.json()
79
- } catch (error) {
80
- // console.error 已替换为注释
81
- return { success: false, error: error.message }
82
- }
83
- }
84
- }
85
-
86
- // 全面更新所有数据
87
- export const updateAllData = async () => {
88
- const commonStore = useCommonStore()
89
-
90
- try {
91
- // console.log 已替换为注释
92
-
93
- const [systemRes, pluginsRes, adaptersRes, configRes] = await Promise.all([
94
- DataService.getSystemStatus(),
95
- DataService.getPlugins(),
96
- DataService.getAdapters(),
97
- DataService.getConfig()
98
- ])
99
-
100
- // 更新系统数据
101
- if (systemRes.success) {
102
- commonStore.syncData({ key: 'system', value: systemRes.data })
103
- // console.log 已替换为注释
104
- } else {
105
- // console.warn 已替换为注释
106
- }
107
-
108
- // 更新插件数据
109
- if (pluginsRes.success) {
110
- commonStore.syncData({ key: 'plugins', value: pluginsRes.data })
111
- // console.log 已替换为注释
112
- } else {
113
- // console.warn 已替换为注释
114
- }
115
-
116
- // 更新适配器数据
117
- if (adaptersRes.success) {
118
- commonStore.syncData({ key: 'adapters', value: adaptersRes.data })
119
- // console.log 已替换为注释
120
- } else {
121
- // console.warn 已替换为注释
122
- }
123
-
124
- // 更新配置数据
125
- if (configRes.success) {
126
- commonStore.syncData({ key: 'config', value: configRes.data })
127
- // console.log 已替换为注释
128
- } else {
129
- // console.warn 已替换为注释
130
- }
131
-
132
- return {
133
- success: true,
134
- results: { systemRes, pluginsRes, adaptersRes, configRes }
135
- }
136
-
137
- } catch (error) {
138
- // console.error 已替换为注释
139
- return { success: false, error }
140
- }
141
- }
142
-
143
- // 导出给全局使用
144
- declare global {
145
- interface Window {
146
- DataService: typeof DataService
147
- updateAllData: typeof updateAllData
148
- }
149
- }
150
-
151
- // 挂载到 window 对象,方便调试
152
- if (typeof window !== 'undefined') {
153
- window.DataService = DataService
154
- window.updateAllData = updateAllData
155
- }
@@ -1,202 +0,0 @@
1
- # 通用样式系统
2
-
3
- 基于 PrimeVue 的积木式页面构建系统,让开发者无需编写任何自定义样式,就能构建统一、美观、响应式的页面。
4
-
5
- ## 设计理念
6
-
7
- - **零自定义样式**: 页面组件的 `<style>` 部分只需要一行注释
8
- - **积木式构建**: 使用预定义的 class 和 PrimeVue 组件组合
9
- - **主题一致性**: 自动适配 PrimeVue 主题,支持明暗切换
10
- - **响应式优先**: 所有组件都包含完整的响应式断点
11
-
12
- ## 核心组件
13
-
14
- ### 页面布局
15
-
16
- ```vue
17
- <template>
18
- <div class="page-layout">
19
- <!-- 页面头部 -->
20
- <Card class="page-header-card">
21
- <template #content>
22
- <div class="flex-row justify-between">
23
- <div class="flex-row">
24
- <div class="icon-container icon-primary">
25
- <i class="pi pi-desktop"></i>
26
- </div>
27
- <div class="flex-column">
28
- <h1>页面标题</h1>
29
- <p>页面描述</p>
30
- </div>
31
- </div>
32
- <Button icon="pi pi-refresh" label="操作" />
33
- </div>
34
- </template>
35
- </Card>
36
-
37
- <!-- 统计卡片 -->
38
- <div class="stats-container">
39
- <Card class="stats-card">
40
- <template #content>
41
- <div class="flex-row gap-large">
42
- <div class="icon-container icon-blue">
43
- <i class="pi pi-chart-bar"></i>
44
- </div>
45
- <div class="flex-column flex-1">
46
- <div class="stat-value">123</div>
47
- <div class="stat-label">统计标签</div>
48
- <div class="stat-sub">辅助信息</div>
49
- </div>
50
- </div>
51
- </template>
52
- </Card>
53
- </div>
54
-
55
- <!-- 主内容区域 -->
56
- <div class="layout-container">
57
- <div class="layout-main">
58
- <Card class="content-card">
59
- <template #title>
60
- <i class="pi pi-list"></i>
61
- <span>内容标题</span>
62
- </template>
63
- <template #content>
64
- <!-- 内容 -->
65
- </template>
66
- </Card>
67
- </div>
68
- </div>
69
- </div>
70
- </template>
71
- ```
72
-
73
- ### 布局类
74
-
75
- | Class | 说明 | 用途 |
76
- |-------|------|------|
77
- | `page-layout` | 页面根容器 | 设置基础布局结构 |
78
- | `page-header-card` | 页面头部卡片 | 渐变背景的页面标题区域 |
79
- | `stats-container` | 统计卡片容器 | Flex 布局的统计卡片组 |
80
- | `stats-card` | 统计卡片 | 带悬停效果的统计卡片 |
81
- | `content-card` | 内容卡片 | 标准内容卡片样式 |
82
- | `layout-container` | 主布局容器 | 两栏布局容器 |
83
- | `layout-main` | 主内容区域 | 左侧主要内容 |
84
- | `layout-sidebar` | 侧边栏区域 | 右侧辅助内容 |
85
-
86
- ### Flex 工具类
87
-
88
- | Class | 说明 |
89
- |-------|------|
90
- | `flex-row` | 水平 Flex 布局 |
91
- | `flex-column` | 垂直 Flex 布局 |
92
- | `flex-1` | flex: 1 |
93
- | `flex-none` | flex: none |
94
- | `justify-between` | justify-content: space-between |
95
- | `gap-large` | 较大间距 |
96
-
97
- ### 图标容器
98
-
99
- ```vue
100
- <!-- 大图标容器 -->
101
- <div class="icon-container icon-primary">
102
- <i class="pi pi-desktop"></i>
103
- </div>
104
-
105
- <!-- 小图标容器 -->
106
- <div class="icon-container icon-small icon-blue">
107
- <i class="pi pi-user"></i>
108
- </div>
109
- ```
110
-
111
- #### 图标主题色
112
-
113
- | Class | 颜色 | 用途 |
114
- |-------|------|------|
115
- | `icon-primary` | 主题色 | 通用图标 |
116
- | `icon-blue` | 蓝色 | 信息类图标 |
117
- | `icon-green` | 绿色 | 成功/活跃类图标 |
118
- | `icon-purple` | 紫色 | 特殊功能图标 |
119
- | `icon-orange` | 橙色 | 警告/重要图标 |
120
-
121
- ### 详情项目
122
-
123
- ```vue
124
- <div class="detail-grid">
125
- <div class="detail-item">
126
- <div class="icon-container icon-small icon-blue">
127
- <i class="pi pi-user"></i>
128
- </div>
129
- <div class="flex-column flex-1">
130
- <div class="detail-label">标签</div>
131
- <div class="detail-value">值</div>
132
- </div>
133
- </div>
134
- </div>
135
- ```
136
-
137
- ### 上下文项目
138
-
139
- ```vue
140
- <div class="grid-auto-fit">
141
- <div class="context-item">
142
- <div class="icon-container icon-small icon-primary">
143
- <i class="pi pi-server"></i>
144
- </div>
145
- <div class="flex-column flex-1">
146
- <div class="detail-label">服务名称</div>
147
- <div class="detail-value">描述</div>
148
- </div>
149
- <Tag value="状态" severity="success" size="small" />
150
- </div>
151
- </div>
152
- ```
153
-
154
- ### 空状态
155
-
156
- ```vue
157
- <div class="empty-state">
158
- <div class="icon-container">
159
- <i class="pi pi-inbox"></i>
160
- </div>
161
- <h3>空状态标题</h3>
162
- <p>空状态描述</p>
163
- </div>
164
- ```
165
-
166
- ### 文本样式类
167
-
168
- | Class | 说明 |
169
- |-------|------|
170
- | `stat-value` | 统计数值 |
171
- | `stat-label` | 统计标签 |
172
- | `stat-sub` | 统计辅助信息 |
173
- | `detail-label` | 详情标签 |
174
- | `detail-value` | 详情值 |
175
-
176
- ## 响应式断点
177
-
178
- - **桌面**: `>1024px` - 完整的两栏布局
179
- - **平板**: `768px-1024px` - 垂直堆叠布局
180
- - **手机**: `<768px` - 紧凑单列布局
181
- - **小屏**: `<480px` - 极简垂直布局
182
-
183
- ## 主题支持
184
-
185
- 系统完全基于 PrimeVue CSS 变量,支持:
186
-
187
- - 明暗主题自动切换
188
- - 自定义主题色彩
189
- - 品牌色彩一致性
190
- - 无缝主题过渡
191
-
192
- ## 使用示例
193
-
194
- 参见 `components/StyleGuide.vue` 中的完整示例,展示了如何使用这个系统快速构建功能完整、外观统一的页面。
195
-
196
- ## 最佳实践
197
-
198
- 1. **始终使用预定义类**: 不要编写自定义样式
199
- 2. **保持组件简洁**: 让样式系统处理所有视觉呈现
200
- 3. **利用 PrimeVue 组件**: Card、Button、Tag 等组件已经集成到系统中
201
- 4. **响应式思维**: 系统已处理所有响应式场景
202
- 5. **主题一致性**: 使用标准的图标主题色和 PrimeVue 严重度级别
File without changes
package/global.d.ts DELETED
@@ -1,19 +0,0 @@
1
- /// <reference types="vite/client" />
2
- /// <reference types="@ionic/vue" />
3
-
4
- declare module '*.vue' {
5
- import { Component } from 'vue';
6
-
7
- const component: Component;
8
- export default component;
9
- }
10
-
11
- declare module '*.yaml' {
12
- const content: {};
13
- export default content;
14
- }
15
-
16
- declare module '*.yml' {
17
- const content: {};
18
- export default content;
19
- }
package/src/router.ts DELETED
@@ -1,44 +0,0 @@
1
- import { createRouter, createWebHistory } from 'vue-router';
2
- import { useCommonStore } from './store.js';
3
- import { MenuWithComponent, ToolInfo } from './types.js';
4
- export const router = createRouter({
5
- history: createWebHistory(),
6
- routes: [],
7
- });
8
-
9
- router.beforeEach(async (to, from, next) => {
10
- const commonStore = useCommonStore();
11
- if (!commonStore.initialized) {
12
- await commonStore.initial;
13
- return next({ ...to, replace: true });
14
- }
15
- return next();
16
- });
17
- export function addPage(menu: MenuWithComponent) {
18
- if (menu.parentName) {
19
- router.addRoute(menu.parentName, {
20
- path: menu.path,
21
- name: menu.name,
22
- component: menu.component,
23
- children: [],
24
- });
25
- } else {
26
- router.addRoute({
27
- path: menu.path,
28
- name: menu.name,
29
- component: menu.component,
30
- children: [],
31
- });
32
- }
33
- useCommonStore().addData({
34
- key: 'menus',
35
- value: menu,
36
- });
37
- return () => router.removeRoute(menu.name);
38
- }
39
- export function addTool(tool: ToolInfo) {
40
- useCommonStore().addData({
41
- key: 'tools',
42
- value: tool,
43
- });
44
- }