@loom-framework/core 0.1.0-alpha.178 → 0.1.0-alpha.179
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/builtin-skills/loom/SKILL.md +7 -7
- package/builtin-skills/loom/references/README.md +19 -19
- package/builtin-skills/loom/references/dashboard.md +39 -39
- package/builtin-skills/loom/references/data-model.md +10 -6
- package/dist/cli/templates/login-page.d.ts +1 -1
- package/dist/cli/templates/login-page.js +1 -1
- package/dist/cli/templates/model-management-page.d.ts +1 -1
- package/dist/cli/templates/model-management-page.js +1 -1
- package/dist/cli/templates/notification-center-page.d.ts +1 -1
- package/dist/cli/templates/notification-center-page.js +8 -8
- package/dist/cli/templates/notification-detail-page.d.ts +1 -1
- package/dist/cli/templates/notification-detail-page.js +1 -1
- package/dist/cli/templates/process-management-page.d.ts +1 -1
- package/dist/cli/templates/process-management-page.js +1 -1
- package/dist/cli/templates/skill-management-page.d.ts +1 -1
- package/dist/cli/templates/skill-management-page.js +1 -1
- package/dist/cli/templates/user-management-page.d.ts +1 -1
- package/dist/cli/templates/user-management-page.js +1 -1
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@ Loom 是**配置驱动的 AI 平台开发框架**——你描述需求,AI 通
|
|
|
17
17
|
|
|
18
18
|
典型使用方式:
|
|
19
19
|
|
|
20
|
-
1. **用自然语言描述需求** — 告诉 Claude Code(或其它支持Skill的 Agent) 你要做什么(如"用 loom
|
|
20
|
+
1. **用自然语言描述需求** — 告诉 Claude Code(或其它支持Skill的 Agent) 你要做什么(如"用 loom 开发一个告警管理平台"),Claude Code 会交互式地向你确认完整需求,然后调用本 Skill 读取配置、生成页面、启动服务
|
|
21
21
|
2. **对话迭代** — 通过Claude Code 或 创建的项目 AI 对话面板改需求、加字段、调样式,AI 理解 loom 的工作方式,知道何时改配置、何时跑命令、何时直接改代码
|
|
22
22
|
3. **日常运营** — 通过 AI 对话面板或 `loom data` CLI 查看、创建、更新数据
|
|
23
23
|
|
|
@@ -96,7 +96,7 @@ loom generate capabilities
|
|
|
96
96
|
|
|
97
97
|
每次修改数据模型或 AI 按钮后,重新运行此命令即可更新 `references/` 下的自动生成内容,`SKILL.md` 中手动补充的内容不会被覆盖。
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
首次生成项目SKILL后,需要补充其 `SKILL.md` 主文档中的 TODO 内容,AI 对话时才能正确理解项目业务语义:
|
|
100
100
|
|
|
101
101
|
1. **frontmatter `description`**:写入用户在 AI 对话中会说的触发短语。格式参考:
|
|
102
102
|
```
|
|
@@ -161,7 +161,7 @@ loom dev --frontend-port 8080 # 临时覆盖前端端口
|
|
|
161
161
|
|
|
162
162
|
**`--force` 重建(默认)**:字段变更时直接 `--force` 重建页面,是最快最干净的方式,页面与配置立即同步。`--force` 会自动将旧页面备份到 `.loom/backup/<时间戳>/` 目录,如需恢复直接复制回来即可。
|
|
163
163
|
|
|
164
|
-
**AI 增量更新(有定制时)**:如果用户说"保留我的定制"或明确表示页面有手动修改过,才让 AI 增量更新。告诉 AI 你改了什么(如"
|
|
164
|
+
**AI 增量更新(有定制时)**:如果用户说"保留我的定制"或明确表示页面有手动修改过,才让 AI 增量更新。告诉 AI 你改了什么(如"我在配置里加了一个严重等级字段"),AI 会精确添加新字段的列和表单项,保留定制代码。如果AI进行了定制化开发,务必将定制化开发内容更新到CLAUDE.md,使得后续新启动会话时Claude Code可掌握项目定制化情况。
|
|
165
165
|
|
|
166
166
|
```bash
|
|
167
167
|
# 只改了 AI 按钮或 enum → 重启后端即可
|
|
@@ -255,8 +255,8 @@ export default defineConfig({
|
|
|
255
255
|
{
|
|
256
256
|
id: 'analyze', // 带变量的示例
|
|
257
257
|
label: { 'zh-CN': '分析', 'en-US': 'Analyze' },
|
|
258
|
-
prompt: '
|
|
259
|
-
placement: '
|
|
258
|
+
prompt: '分析告警原因:{{description}},当前状态:{{status}}',
|
|
259
|
+
placement: 'alerts', // 可选:限制按钮只出现在指定模型页面,逗号分隔多个模型名;省略则出现在所有页面
|
|
260
260
|
}],
|
|
261
261
|
dashboards: [{ // 可选:数据概览,widget/图表类型/筛选配置详见 references/dashboard.md
|
|
262
262
|
name: 'overview', // 必填:唯一标识
|
|
@@ -330,8 +330,8 @@ export default defineConfig({
|
|
|
330
330
|
|
|
331
331
|
所有面向用户的展示字段均支持 `LocaleString` 格式:`string | Record<string, string>`。
|
|
332
332
|
|
|
333
|
-
- **简单写法**:`description: '
|
|
334
|
-
- **多语言写法**:`description: { 'zh-CN': '
|
|
333
|
+
- **简单写法**:`description: '级别'` — 所有语言显示相同文本
|
|
334
|
+
- **多语言写法**:`description: { 'zh-CN': '级别', 'en-US': 'Level' }` — 切换语言时自动翻译
|
|
335
335
|
- **enum 值**:`enum` 始终是存储值(不分语言),显示文本通过 `enumLabels` 翻译
|
|
336
336
|
- **回退规则**:请求的 locale → `'zh-CN'` → 第一个可用值
|
|
337
337
|
|
|
@@ -22,15 +22,15 @@ Loom 项目的主要交互方式是**和 AI 对话**。你告诉 AI 想要什么
|
|
|
22
22
|
|
|
23
23
|
## 第一个项目
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
假设你要做一个**告警管理平台**。
|
|
26
26
|
|
|
27
27
|
### 第 1 步:告诉 AI 你的想法
|
|
28
28
|
|
|
29
29
|
在 Claude Code 中说:
|
|
30
30
|
|
|
31
|
-
> 用 loom
|
|
32
|
-
>
|
|
33
|
-
> AI
|
|
31
|
+
> 用 loom 创建一个告警管理平台,项目名 alert-manager,filesystem 适配器。
|
|
32
|
+
> 需要两个模型:告警记录(级别、描述、来源、严重度、状态)和处理记录(告警ID、处理人、处理时间、状态)。
|
|
33
|
+
> AI 按钮要能分析告警根因和生成处置建议。
|
|
34
34
|
|
|
35
35
|
AI 会读取 Loom Skill,自动执行:
|
|
36
36
|
|
|
@@ -51,9 +51,9 @@ loom dev
|
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
打开 http://localhost:5173 ,你的平台已经能用了:
|
|
54
|
-
-
|
|
54
|
+
- 顶部导航有「告警记录」和「处理记录」页面
|
|
55
55
|
- 每个页面有新增、编辑、删除、筛选
|
|
56
|
-
-
|
|
56
|
+
- 告警记录每行有 AI 按钮:分析根因、生成处置建议
|
|
57
57
|
- 右侧 AI 面板可以自然语言操作数据
|
|
58
58
|
|
|
59
59
|
### 第 3 步:继续和 AI 聊
|
|
@@ -62,11 +62,11 @@ loom dev
|
|
|
62
62
|
|
|
63
63
|
| 你说的 | AI 做的 |
|
|
64
64
|
|-------|--------|
|
|
65
|
-
| "
|
|
66
|
-
| "
|
|
65
|
+
| "帮我记一条告警,服务器CPU过载,当前状态未处理" | 用 `loom data write` 创建记录 |
|
|
66
|
+
| "看看哪些告警还没处理" | 查数据并展示 |
|
|
67
67
|
| "把这个页面改成卡片布局" | 修改页面 TSX |
|
|
68
|
-
| "
|
|
69
|
-
| "
|
|
68
|
+
| "加一个严重等级字段" | 改 loom.config.ts + 改页面 + 更新 Skill references |
|
|
69
|
+
| "加一个级别分布的饼图" | 修改 Dashboard 页面 |
|
|
70
70
|
|
|
71
71
|
这些操作在终端 Claude Code 和页面对话框里都能做。
|
|
72
72
|
|
|
@@ -81,7 +81,7 @@ loom dev
|
|
|
81
81
|
| 新增数据模型 | 需要生成新页面 | 改配置 → `loom generate capabilities` + `loom generate page <Name> --model <model>` → 重启后端 |
|
|
82
82
|
| 新增/删除字段 | 需要 | 改配置 → AI 更新页面(推荐)或 `--force` 重建 → `loom generate capabilities` 更新 Skill |
|
|
83
83
|
|
|
84
|
-
**推荐:AI 辅助迭代**。告诉 AI 你改了什么(比如"
|
|
84
|
+
**推荐:AI 辅助迭代**。告诉 AI 你改了什么(比如"我在配置里加了一个严重等级字段"),AI 会在页面中精确添加新字段的列和表单项,**保留你之前做的视觉定制代码**。
|
|
85
85
|
|
|
86
86
|
**谨慎使用 `--force`**。它会用最新配置全量覆盖页面,之前对页面做的任何定制修改都会丢失。
|
|
87
87
|
|
|
@@ -89,7 +89,7 @@ loom dev
|
|
|
89
89
|
# 只改了 AI 按钮或 enum → 重启后端即可,不用碰页面
|
|
90
90
|
# 加了新字段 → 让 AI 更新页面
|
|
91
91
|
# 想重来一个干净页面 → --force
|
|
92
|
-
loom generate page
|
|
92
|
+
loom generate page Alerts --model alerts --force
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
页面不存在时直接 `loom generate page` 即可,不需要 `--force`。
|
|
@@ -150,22 +150,22 @@ export default defineConfig({
|
|
|
150
150
|
|
|
151
151
|
每个项目的 `.claude/skills/<项目名>/SKILL.md` 是 AI 理解你业务的入口。`loom generate capabilities` 生成骨架(`references/` 下的内容自动维护),但 SKILL.md 主文档需要你补充三个地方:
|
|
152
152
|
|
|
153
|
-
1. **description**:写用户会说的话,如 `"
|
|
153
|
+
1. **description**:写用户会说的话,如 `"记录告警", "查看告警", "分析根因"`
|
|
154
154
|
2. **Overview**:2-3 句话描述平台做什么
|
|
155
155
|
3. **Usage Scenarios**:5-10 个典型用户请求及对应的 `loom data` 命令
|
|
156
156
|
|
|
157
|
-
补充后,AI 在终端和对话框里都能理解"
|
|
157
|
+
补充后,AI 在终端和对话框里都能理解"帮我查未处理告警"这类业务请求。
|
|
158
158
|
|
|
159
159
|
## 数据操作
|
|
160
160
|
|
|
161
161
|
不打开页面也能操作数据。你可以自己跑命令,也可以让 AI 跑:
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
-
loom data read
|
|
165
|
-
loom data write
|
|
166
|
-
loom data update
|
|
167
|
-
loom data delete
|
|
168
|
-
loom data schema
|
|
164
|
+
loom data read alerts --filter '{"level":"critical"}' --limit 10
|
|
165
|
+
loom data write alerts --data '{"level":"critical","description":"CPU使用率超过95%","source":"monitor","status":"open"}'
|
|
166
|
+
loom data update alerts --id rec_xxx --data '{"status":"resolved"}'
|
|
167
|
+
loom data delete alerts --id rec_xxx
|
|
168
|
+
loom data schema alerts # 查看字段结构
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
## 后端扩展
|
|
@@ -47,7 +47,7 @@ export default defineConfig({
|
|
|
47
47
|
field: 'score', // aggregate 为 sum/avg/min/max 时必填:数值字段名
|
|
48
48
|
filter: { status: 'active' }, // 可选:聚合前筛选条件
|
|
49
49
|
groupBy: 'category', // 可选:分组字段(string/enum/date/boolean)
|
|
50
|
-
crossGroupBy: '
|
|
50
|
+
crossGroupBy: 'source', // 可选:第二分组字段,用于二维图表
|
|
51
51
|
interval: 'month', // 可选:date 字段分组粒度 minute|hour|day|week|month(默认 month)
|
|
52
52
|
dateField: 'createdAt', // 可选:单组件日期筛选字段,覆盖 dashboard 级 defaultDateField
|
|
53
53
|
}]
|
|
@@ -61,7 +61,7 @@ export default defineConfig({
|
|
|
61
61
|
|------|------|------|
|
|
62
62
|
| `aggregate` | `count\|sum\|avg\|min\|max\|ratio` | 聚合方式。`ratio` = 符合 filter 条件的记录数/总记录数,用于 gauge/liquid/stat 百分比 |
|
|
63
63
|
| `field` | string | 聚合目标字段。仅 aggregate 为 sum/avg/min/max 时需要 |
|
|
64
|
-
| `filter` | object | 筛选条件,键值对。如 `{
|
|
64
|
+
| `filter` | object | 筛选条件,键值对。如 `{isResolved: true}` 筛选已处理的记录 |
|
|
65
65
|
| `groupBy` | string | 主分组字段。string/enum 字段按值分组计数;boolean 字段自动映射为"是/否";date 字段按 interval 分段 |
|
|
66
66
|
| `crossGroupBy` | string | 第二分组维度。配合 groupBy 使用,产生交叉分组数据,用于二维图表 |
|
|
67
67
|
| `interval` | `minute\|hour\|day\|week\|month` | date 字段的分组粒度,仅 groupBy 指向 date 字段时有效 |
|
|
@@ -81,7 +81,7 @@ export default defineConfig({
|
|
|
81
81
|
```typescript
|
|
82
82
|
{
|
|
83
83
|
field: 'subject', // 必填:筛选字段名
|
|
84
|
-
label: { 'zh-CN': '
|
|
84
|
+
label: { 'zh-CN': '级别' }, // 必填:显示标签,支持多语言
|
|
85
85
|
type: 'select', // 必填:当前仅支持 'select'('dateRange' 已定义但暂未实现)
|
|
86
86
|
options: ['语文', '数学'], // 可选:select 类型的选项。省略则从数据中自动提取去重值
|
|
87
87
|
}
|
|
@@ -94,11 +94,11 @@ export default defineConfig({
|
|
|
94
94
|
```typescript
|
|
95
95
|
dashboards: [{
|
|
96
96
|
name: 'overview',
|
|
97
|
-
models: ['
|
|
97
|
+
models: ['alerts'],
|
|
98
98
|
defaultDateField: 'createdAt', // 启用日期范围筛选
|
|
99
99
|
filterDimensions: [ // 启用 select 下拉筛选(日期范围用 defaultDateField)
|
|
100
|
-
{ field: 'subject', label: { 'zh-CN': '
|
|
101
|
-
{ field: 'difficulty', label: { 'zh-CN': '
|
|
100
|
+
{ field: 'subject', label: { 'zh-CN': '级别', 'en-US': 'Level' }, type: 'select' },
|
|
101
|
+
{ field: 'difficulty', label: { 'zh-CN': '严重度', 'en-US': 'Severity' }, type: 'select' },
|
|
102
102
|
],
|
|
103
103
|
layout: [/* ... */],
|
|
104
104
|
}]
|
|
@@ -111,28 +111,28 @@ dashboards: [{
|
|
|
111
111
|
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
112
112
|
|------|---------|---------|---------|---------|
|
|
113
113
|
| `stat` | 统计卡片 | — | `{ aggregate: "count" }` 或 `{ aggregate: "avg", field: "score" }` 或 `{ aggregate: "ratio", filter: { passed: true } }` | Ant Design Statistic 数值卡片 |
|
|
114
|
-
| `gauge` | 仪表盘 | `aggregate: "ratio"` + `filter` | `{ aggregate: "ratio", filter: {
|
|
115
|
-
| `liquid` | 水波图 | `aggregate: "ratio"` + `filter` | `{ aggregate: "ratio", filter: {
|
|
114
|
+
| `gauge` | 仪表盘 | `aggregate: "ratio"` + `filter` | `{ aggregate: "ratio", filter: { isResolved: true } }` | G2 仪表盘(百分比进度) |
|
|
115
|
+
| `liquid` | 水波图 | `aggregate: "ratio"` + `filter` | `{ aggregate: "ratio", filter: { isResolved: true } }` | G2 水波图(百分比进度) |
|
|
116
116
|
|
|
117
|
-
> **说明**:gauge 和 liquid 使用 `aggregate: "ratio"` + `filter`
|
|
117
|
+
> **说明**:gauge 和 liquid 使用 `aggregate: "ratio"` + `filter` 来计算百分比(如处理率 = 已处理数/总数),ratio 自动算出 0-1 之间的值。
|
|
118
118
|
|
|
119
119
|
#### 占比类 — 展示分布构成
|
|
120
120
|
|
|
121
121
|
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
122
122
|
|------|---------|---------|---------|---------|
|
|
123
123
|
| `pie` | 饼图 | `groupBy` (enum/string) | `{ groupBy: "subject" }` | G2 饼图(分布占比) |
|
|
124
|
-
| `ring` | 环形图 | `groupBy` (boolean/enum) | `{ groupBy: "difficulty" }` 或 `{ groupBy: "
|
|
124
|
+
| `ring` | 环形图 | `groupBy` (boolean/enum) | `{ groupBy: "difficulty" }` 或 `{ groupBy: "isResolved" }` | G2 环形图(占比对比,boolean 自动映射"是/否") |
|
|
125
125
|
| `treemap` | 矩形树图 | `groupBy` + 可选 `crossGroupBy` | `{ groupBy: "subject" }` 或 `{ groupBy: "subject", crossGroupBy: "difficulty" }` | G2 矩形树图(层级占比,有 crossGroupBy 则两层) |
|
|
126
126
|
|
|
127
127
|
#### 对比类 — 跨类别比较
|
|
128
128
|
|
|
129
129
|
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
130
130
|
|------|---------|---------|---------|---------|
|
|
131
|
-
| `bar` | 条形图 | `groupBy` | `{ groupBy: "
|
|
132
|
-
| `stacked_bar` | 堆叠条形图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "
|
|
131
|
+
| `bar` | 条形图 | `groupBy` | `{ groupBy: "source" }` | G2 条形图(横向分类对比) |
|
|
132
|
+
| `stacked_bar` | 堆叠条形图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "source" }` | G2 堆叠条形图(组成+对比) |
|
|
133
133
|
| `grouped_bar` | 分组条形图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "difficulty" }` | G2 分组条形图(并列对比) |
|
|
134
134
|
| `radar` | 雷达图 | `groupBy` | `{ groupBy: "subject" }` | G2 雷达图(多维度闭合多边形) |
|
|
135
|
-
| `funnel` | 漏斗图 | `groupBy` | `{ groupBy: "
|
|
135
|
+
| `funnel` | 漏斗图 | `groupBy` | `{ groupBy: "source" }` | G2 漏斗图(阶段转化,柱条宽度反映数值) |
|
|
136
136
|
|
|
137
137
|
#### 趋势类 — 时间维度变化
|
|
138
138
|
|
|
@@ -146,7 +146,7 @@ dashboards: [{
|
|
|
146
146
|
| type | 中文名称 | 必填字段 | 典型配置 | 生成效果 |
|
|
147
147
|
|------|---------|---------|---------|---------|
|
|
148
148
|
| `scatter` | 散点图 | `groupBy` | `{ groupBy: "subject" }` | G2 散点图(相关性/分布) |
|
|
149
|
-
| `heatmap` | 热力图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "
|
|
149
|
+
| `heatmap` | 热力图 | `groupBy` + `crossGroupBy` | `{ groupBy: "subject", crossGroupBy: "source" }` | G2 热力图(密度/交叉分析,颜色深浅表示数量) |
|
|
150
150
|
|
|
151
151
|
## 执行 generate dashboard
|
|
152
152
|
|
|
@@ -171,63 +171,63 @@ cd frontend && pnpm add @antv/g2
|
|
|
171
171
|
|
|
172
172
|
## 完整配置示例
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
以小学生告警管理平台为例,展示所有 15 种图表的配置:
|
|
175
175
|
|
|
176
176
|
```typescript
|
|
177
177
|
import { defineConfig } from '@loom-framework/core';
|
|
178
178
|
|
|
179
179
|
export default defineConfig({
|
|
180
|
-
project: { name: '
|
|
180
|
+
project: { name: 'alert-manager' },
|
|
181
181
|
data: { /* ... */ },
|
|
182
182
|
dashboards: [{
|
|
183
183
|
name: 'overview',
|
|
184
|
-
description: { 'zh-CN': '
|
|
185
|
-
models: ['
|
|
184
|
+
description: { 'zh-CN': '告警数据概览', 'en-US': 'Overview' },
|
|
185
|
+
models: ['alerts', 'alert_handlers'],
|
|
186
186
|
defaultDateField: 'createdAt',
|
|
187
187
|
filterDimensions: [
|
|
188
|
-
{ field: 'subject', label: { 'zh-CN': '
|
|
189
|
-
{ field: 'difficulty', label: { 'zh-CN': '
|
|
188
|
+
{ field: 'subject', label: { 'zh-CN': '级别', 'en-US': 'Level' }, type: 'select' },
|
|
189
|
+
{ field: 'difficulty', label: { 'zh-CN': '严重度', 'en-US': 'Severity' }, type: 'select' },
|
|
190
190
|
],
|
|
191
191
|
layout: [
|
|
192
192
|
{
|
|
193
193
|
row: [
|
|
194
|
-
{ type: 'stat', title: { 'zh-CN': '
|
|
195
|
-
{ type: 'stat', title: { 'zh-CN': '
|
|
196
|
-
{ type: 'gauge', title: { 'zh-CN': '
|
|
197
|
-
{ type: 'liquid', title: { 'zh-CN': '
|
|
198
|
-
{ type: 'stat', title: { 'zh-CN': '
|
|
194
|
+
{ type: 'stat', title: { 'zh-CN': '告警总数', 'en-US': 'Total Alerts' }, model: 'alerts', aggregate: 'count', span: 4 },
|
|
195
|
+
{ type: 'stat', title: { 'zh-CN': '处理率', 'en-US': 'Resolution Rate' }, model: 'alerts', aggregate: 'ratio', filter: { isResolved: true }, span: 4 },
|
|
196
|
+
{ type: 'gauge', title: { 'zh-CN': '处理率仪表盘', 'en-US': 'Resolution Gauge' }, model: 'alerts', aggregate: 'ratio', filter: { isResolved: true }, span: 6 },
|
|
197
|
+
{ type: 'liquid', title: { 'zh-CN': '处理率水波图', 'en-US': 'Resolution Liquid' }, model: 'alerts', aggregate: 'ratio', filter: { isResolved: true }, span: 5 },
|
|
198
|
+
{ type: 'stat', title: { 'zh-CN': '平均处理时长', 'en-US': 'Avg Resolution Time' }, model: 'alerts', aggregate: 'avg', field: 'resolutionTime', span: 5 }
|
|
199
199
|
]
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
202
|
row: [
|
|
203
|
-
{ type: 'pie', title: { 'zh-CN': '
|
|
204
|
-
{ type: 'ring', title: { 'zh-CN': '
|
|
205
|
-
{ type: 'bar', title: { 'zh-CN': '
|
|
203
|
+
{ type: 'pie', title: { 'zh-CN': '级别分布', 'en-US': 'By Level' }, model: 'alerts', groupBy: 'subject', span: 8 },
|
|
204
|
+
{ type: 'ring', title: { 'zh-CN': '严重度分布', 'en-US': 'By Severity' }, model: 'alerts', groupBy: 'difficulty', span: 8 },
|
|
205
|
+
{ type: 'bar', title: { 'zh-CN': '告警来源分布', 'en-US': 'By Source' }, model: 'alerts', groupBy: 'source', span: 8 }
|
|
206
206
|
]
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
209
|
row: [
|
|
210
|
-
{ type: 'line', title: { 'zh-CN': '
|
|
211
|
-
{ type: 'area', title: { 'zh-CN': '
|
|
210
|
+
{ type: 'line', title: { 'zh-CN': '告警趋势', 'en-US': 'Alerts Trend' }, model: 'alerts', groupBy: 'createdAt', interval: 'month', span: 12 },
|
|
211
|
+
{ type: 'area', title: { 'zh-CN': '处理记录趋势', 'en-US': 'Handlers Trend' }, model: 'alert_handlers', groupBy: 'createdAt', interval: 'month', span: 12 }
|
|
212
212
|
]
|
|
213
213
|
},
|
|
214
214
|
{
|
|
215
215
|
row: [
|
|
216
|
-
{ type: 'radar', title: { 'zh-CN': '
|
|
217
|
-
{ type: 'stacked_bar', title: { 'zh-CN': '
|
|
218
|
-
{ type: 'grouped_bar', title: { 'zh-CN': '
|
|
216
|
+
{ type: 'radar', title: { 'zh-CN': '各级别概览', 'en-US': 'Level Overview' }, model: 'alerts', groupBy: 'subject', span: 8 },
|
|
217
|
+
{ type: 'stacked_bar', title: { 'zh-CN': '级别×错误类型', 'en-US': 'Level × Error Type' }, model: 'alerts', groupBy: 'subject', crossGroupBy: 'source', span: 8 },
|
|
218
|
+
{ type: 'grouped_bar', title: { 'zh-CN': '级别×严重度', 'en-US': 'Level × Severity' }, model: 'alerts', groupBy: 'subject', crossGroupBy: 'difficulty', span: 8 }
|
|
219
219
|
]
|
|
220
220
|
},
|
|
221
221
|
{
|
|
222
222
|
row: [
|
|
223
|
-
{ type: 'scatter', title: { 'zh-CN': '
|
|
224
|
-
{ type: 'funnel', title: { 'zh-CN': '
|
|
225
|
-
{ type: 'treemap', title: { 'zh-CN': '
|
|
223
|
+
{ type: 'scatter', title: { 'zh-CN': '级别分布散点', 'en-US': 'Level Scatter' }, model: 'alerts', groupBy: 'subject', span: 8 },
|
|
224
|
+
{ type: 'funnel', title: { 'zh-CN': '告警来源漏斗', 'en-US': 'Source Funnel' }, model: 'alerts', groupBy: 'source', span: 8 },
|
|
225
|
+
{ type: 'treemap', title: { 'zh-CN': '级别×严重度树图', 'en-US': 'Level × Severity Tree' }, model: 'alerts', groupBy: 'subject', crossGroupBy: 'difficulty', span: 8 }
|
|
226
226
|
]
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
229
|
row: [
|
|
230
|
-
{ type: 'heatmap', title: { 'zh-CN': '
|
|
230
|
+
{ type: 'heatmap', title: { 'zh-CN': '级别×年级热力图', 'en-US': 'Level × Grade Heatmap' }, model: 'alerts', groupBy: 'subject', crossGroupBy: 'source', span: 24 }
|
|
231
231
|
]
|
|
232
232
|
}
|
|
233
233
|
]
|
|
@@ -243,11 +243,11 @@ export default defineConfig({
|
|
|
243
243
|
2. 使用 `/antv-g2-chart` skill 生成 G2 v5 Spec 代码
|
|
244
244
|
3. 添加 `<DashboardChart spec={...} />` 组件
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
示例——追加一个级别×年级的堆叠柱状图:
|
|
247
247
|
|
|
248
248
|
```tsx
|
|
249
249
|
// 在已有的 Dashboard 页面中追加
|
|
250
|
-
const
|
|
250
|
+
const levelSourceData = useCrossGroupChartData(alertsList, { groupBy: 'level', crossGroupBy: 'source' });
|
|
251
251
|
|
|
252
252
|
<DashboardChart spec={{
|
|
253
253
|
type: 'interval',
|
|
@@ -79,7 +79,7 @@ aiButtons: [{
|
|
|
79
79
|
label: { 'zh-CN': '总结', 'en-US': 'Summarize' }, // required: LocaleString, button text
|
|
80
80
|
icon: 'FileTextOutlined', // optional: Ant Design icon component name
|
|
81
81
|
prompt: '请总结以下内容', // required: supports {{var}} placeholders, replaced with current row field values
|
|
82
|
-
placement: '
|
|
82
|
+
placement: 'alerts', // optional: limit to specific model pages, comma-separated; omit for all pages
|
|
83
83
|
}]
|
|
84
84
|
```
|
|
85
85
|
|
|
@@ -99,6 +99,10 @@ ai: {
|
|
|
99
99
|
authToken: 'sk-xxx', // optional: ANTHROPIC_AUTH_TOKEN, passed via --settings
|
|
100
100
|
baseUrl: 'https://api.example.com', // optional: ANTHROPIC_BASE_URL, passed via --settings
|
|
101
101
|
isDefault: true, // optional: default model for new chats
|
|
102
|
+
tier: "max",
|
|
103
|
+
tags: [
|
|
104
|
+
"自然语言"
|
|
105
|
+
]
|
|
102
106
|
},
|
|
103
107
|
],
|
|
104
108
|
},
|
|
@@ -148,9 +152,9 @@ ui: {
|
|
|
148
152
|
```typescript
|
|
149
153
|
relations: [{
|
|
150
154
|
name: 'question_reviews', // required: unique relation identifier
|
|
151
|
-
label: { 'zh-CN': '
|
|
152
|
-
from: '
|
|
153
|
-
to: '
|
|
155
|
+
label: { 'zh-CN': '处理记录', 'en-US': 'Handler Records' }, // optional: LocaleString
|
|
156
|
+
from: 'alerts', // required: source model name
|
|
157
|
+
to: 'alert_handlers', // required: target model name
|
|
154
158
|
foreignKey: 'questionId', // required: foreign key field in target model
|
|
155
159
|
type: 'hasMany', // required: 'hasOne' | 'hasMany' | 'manyToMany'
|
|
156
160
|
through: 'enrollments', // optional: pivot model for manyToMany
|
|
@@ -215,8 +219,8 @@ enumLabel(schema, 'status', 'active') // → '激活'
|
|
|
215
219
|
|
|
216
220
|
All user-facing string fields support `LocaleString` format: `string | Record<string, string>`.
|
|
217
221
|
|
|
218
|
-
- **Simple**: `description: '
|
|
219
|
-
- **Multi-locale**: `description: { 'zh-CN': '
|
|
222
|
+
- **Simple**: `description: '级别'` — same text for all locales
|
|
223
|
+
- **Multi-locale**: `description: { 'zh-CN': '级别', 'en-US': 'Level' }` — auto-translated on locale switch
|
|
220
224
|
- **Fallback**: requested locale → `'zh-CN'` → first available value
|
|
221
225
|
|
|
222
226
|
Supported fields: `project.description`, `ModelSchema.description`, `FieldDefinition.description`, `AIButtonConfig.label`, `DashboardConfig.description`, `DashboardWidget.title`, `RelationConfig.label`, `DashboardFilterDimension.label`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Login page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/auth/login-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function loginPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Login page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/auth/login-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function loginPageTemplate() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Model Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/auth/model-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function modelManagementPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Model Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/auth/model-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function modelManagementPageTemplate() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NotificationCenter page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/NotificationCenter.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function notificationCenterPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NotificationCenter page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/NotificationCenter.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function notificationCenterPageTemplate() {
|
|
@@ -98,6 +98,13 @@ function NotificationCenterPage() {
|
|
|
98
98
|
width: 80,
|
|
99
99
|
render: (type: string) => <Tag color={NOTIFICATION_TYPE_COLORS[type] || 'default'}>{t(\`notification.type.\${type}\`)}</Tag>,
|
|
100
100
|
},
|
|
101
|
+
{
|
|
102
|
+
title: t('field.createdAt'),
|
|
103
|
+
dataIndex: 'createdAt',
|
|
104
|
+
key: 'createdAt',
|
|
105
|
+
width: 140,
|
|
106
|
+
render: (val: string) => <Tooltip title={new Date(val).toLocaleString(undefined, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })}><Typography.Text type="secondary">{formatTime(val)}</Typography.Text></Tooltip>,
|
|
107
|
+
},
|
|
101
108
|
{
|
|
102
109
|
title: t('notification.colTitle'),
|
|
103
110
|
dataIndex: 'title',
|
|
@@ -122,13 +129,6 @@ function NotificationCenterPage() {
|
|
|
122
129
|
width: 90,
|
|
123
130
|
render: (source: string) => <Tag color={NOTIFICATION_SOURCE_COLORS[source] || 'default'}>{t(\`notification.source.\${source}\`) || source}</Tag>,
|
|
124
131
|
},
|
|
125
|
-
{
|
|
126
|
-
title: t('field.createdAt'),
|
|
127
|
-
dataIndex: 'createdAt',
|
|
128
|
-
key: 'createdAt',
|
|
129
|
-
width: 140,
|
|
130
|
-
render: (val: string) => <Typography.Text type="secondary">{formatTime(val)}</Typography.Text>,
|
|
131
|
-
},
|
|
132
132
|
{
|
|
133
133
|
title: t('common.action'),
|
|
134
134
|
key: 'action',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NotificationDetail page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/NotificationDetail.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function notificationDetailPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NotificationDetail page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/NotificationDetail.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function notificationDetailPageTemplate() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Process Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/process-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function processManagementPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Process Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/process-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function processManagementPageTemplate() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Skill Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/skill-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function skillManagementPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Skill Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/components/pages/skill-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function skillManagementPageTemplate() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/auth/user-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export declare function userManagementPageTemplate(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User Management page template
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.
|
|
4
|
+
* GENERATED by scripts/generate-templates.ts — v0.1.0-alpha.179 — DO NOT EDIT MANUALLY.
|
|
5
5
|
* Source: packages/frontend-antd/src/auth/user-management-page.tsx
|
|
6
6
|
*/
|
|
7
7
|
export function userManagementPageTemplate() {
|
package/package.json
CHANGED