---
name: Jimubi Bigscreen
slug: jimubi-bigscreen
category: Frontend
description: Jimubi Bigscreen generates and edits full-screen data visualizations for big-screen layouts. Use it for 大屏, monitoring screens, sales displays, and other full-screen dashboard-style pages, not standard dashboards.
github: "https://github.com/jeecgboot/skills/tree/main/jimubi-bigscreen"
language: Python
stars: 225
forks: 67
install: "npx degit https://github.com/jeecgboot/skills/tree/main/jimubi-bigscreen ~/.claude/skills/jimubi-bigscreen"
installs_to: ~/.claude/skills/jimubi-bigscreen
source_path: jimubi-bigscreen/SKILL.md
collection_size: 14
category_size: 621
collection_url: "https://dirskills.com/collections/jeecgboot/skills"
added: 2026-09-03T06:05:07.052Z
last_synced: 2026-09-03T06:05:07.052Z
canonical_url: "https://dirskills.com/skills/jimubi-bigscreen"
---

# Jimubi Bigscreen

Jimubi Bigscreen generates and edits full-screen data visualizations for big-screen layouts. Use it for 大屏, monitoring screens, sales displays, and other full-screen dashboard-style pages, not standard dashboards.

**Install:**

```bash
npx degit https://github.com/jeecgboot/skills/tree/main/jimubi-bigscreen ~/.claude/skills/jimubi-bigscreen
```

## README

# JeecgBoot 大屏 AI 自动生成器

> 本 skill 处理大屏（bigScreen）。仪表盘（看板）请用 `jimubi-dashboard` skill。

## ⚠️ 核心强制规则（9条）

1. 所有大屏操作必须通过本 skill（禁止未调用 skill 直接读 memory 凭据自行执行）
2. **入口即分叉**：按场景决策树选路径，禁止默认走 spec_builder。spec_builder 仅用于"整屏生成（含组件）"场景。禁止逐组件拼 Python 脚本
3. 🚨 删除/重写/清空前必须询问用户确认（除非用户明确说"删除/去掉/移除/清空/清除"）
4. 🚨 编写 SQL 前必须 SHOW TABLES 确认表名（onl_drag_page ≠ jimu_drag_page）
5. `dataMapping.filed` 拼写：少一个 d（不是 field）
6. Windows：用 `py` 不是 `python`；所有脚本加 `PYTHONIOENCODING=utf-8`
7. 🚨 **用户未指定数据来源时必须先问**（纯静态布局/纯装饰除外）。可选项：静态 mock / YApi 接口 / SQL 数据集 / Excel-CSV 文件 / 存储过程 / 自写 Java API / **BI 直连 Online 表/设计器表单/Online 报表（`dataType=4`）**。⚠️ 用户说"用某 Online 表 / cgform / jeecg 表 / Online 报表 / desform 作为数据源"时**优先 BI 模式**而非 SQL 数据集（详见 `references/bi-mode-online.md`）。禁止默认编造静态数据
8. **真相源优先级（写组件配置 / 数据集绑定都遵循）**：
   - **数据集绑定字段映射** → `references/data-binding-mapping.md`（唯一真相源，描述冲突以此为准；按 §0 检测算法对照 `defaults/<CompType>.json` 判定 A/B/无映射 三型，别猜）
   - **组件 option 字段名（passthrough 自定义组件 JScrollList / JScrollBoard / JScrollTable / JText / JCurrentTime / JStatsSummary / JDragDecoration / JDragBorder / JFlashList / JRectangle / JLiquid / JSemiGauge / JCustomProgress / JListProgress 等，非穷举）**，按以下四级顺序查，找到即止：
     - ① `references/scripts/defaults/<CompType>.json`（初始加载真相源，`--schema <CompType> --full` 调取）
     - ② `references/<comp>-option-config.md`（组件专项文档）
     - ③ `references/bi-comp-option-config.md`（兜底）
     - ④ **以上三级仍找不到 → 说明该字段是 UI 运行时动态写入的**（不在 defaults 里）。正确做法：在页面上手动操作一次该属性，再 `query_page` 观察实际写入了哪些字段，以观察结果为准。典型案例：`JRing` 的环形尺寸，defaults 只有 `series[0].radius`（百分比），但 UI 实际写的是 `option.outRadius` / `option.innerRadius`（像素整数），不查 ④ 直接写百分比字段会被 Vue 渲染器忽略（实测 2026-04-28）
   - 错字段不报错只会被默认值覆盖（看似"有效"实则无效）。禁止按 Vue/React/Bootstrap 习惯拍脑袋写 `bgColor`/`fontColor`/`borderColor`——实际可能是 `backgroundColor`/`alternateBackgroundColor`/`BGC` 等平台自定义名
   - ECharts 标准字段（`series[*].itemStyle.color` / `xAxis.axisLabel.color` 等）可凭记忆写，不受此规则限制
9. **配色禁止 AI 自编色值**——用户说"复古/商务/科技/红涨绿跌"等命名色板，必走 `style_ops.py set-palette --name <名称>`（或 spec 顶层 `palette`）。查色值用 `style_ops.py list-palettes`，不调 API 不耗 token
10. 🚨 **用户已指定风格/配色/背景时，立即执行，禁止内部反复推翻**——用户说"浅色/深色/科技感/复古风/XX 风格"，选一个合理实现方案后直接执行，不得多轮权衡"技术上是否可行"。平台默认深色主题不是拒绝浅色的理由，遇到技术限制先执行再调整。post-creation 颜色调整必须合并批量：`style_ops.py` 多个子命令尽量串联为 1-2 次调用（`set-axis-color` + `set-title-color` + `set-grid-color` 可各自独立，但禁止因犹豫在 spec 生成后串行执行 6+ 次单独 HTTP 操作）

## ⚡ 写/改任何组件 option 字段前——强制预检（不可跳过）

在编写任何组件 config 脚本、`comp_ops.py edit --set`、或手写 Python patch 之前，**必须先确认字段名，不允许凭 ECharts 文档或经验直接写**。按以下优先级判断：

| 情况 | 做什么 |
|------|--------|
| 当前上下文已有该组件 config（刚 query_page / dump 过） | **直接看它**，从中确认字段名和现有结构 |
| Config 中没有目标字段、或字段名不确定 | **查 `bi-comp-option-config.md`** 对应 CompType section（平台缩写字段如 `legend.t` 只在这里，defaults JSON 里没有） |
| 从零建组件、需要确认初始字段结构 | 先查 `defaults/<CompType>.json`（`--schema <CompType> --full`），再查 `bi-comp-option-config.md` 补充 |
| 以上三处均无 | 在 UI 手动操作一次，`query_page` 观察实际写入字段，以观察结果为准 |

**找到即止，立即执行，禁止从多个来源重复确认同一字段**。任一来源确认字段名后直接跑命令，不再查第二个来源。`comp_ops.py edit` 的 `true/false/数字` 自动类型转换是固定行为，无需每次验证源码。

**错字段不报错不报 warning，只会被默认值静默覆盖**（典型案例：`option.legend.top` 无效，正确字段是 `option.legend.t`；`option.outRadius/innerRadius` 与 `series[0].radius` 同理）。

---

## 大屏平台默认值

- 分辨率 1920×1080（后端默认，spec_builder 不写）| style bigScreen | designType 100
- 主题 dark（spec_builder L797）| 背景 `/img/bg/bg4.png` 深空星空（spec_builder L798）| 图层 bg/border 透明 `#FFFFFF00`
- bg4 色板（spec_builder 内置）：主标题 `#f0c040`，副标题 `#00d4ff`，数值 `#d4e8ff`，轴 `#8ab8d0`，分割线 `#1a3a5a55`
- A股红涨绿跌：`#ff4d4f` / `#52c41a`

---

## 入口判断（先做这一步）

**1. 新建 vs 已有大屏？**

| 用户语境 | 走哪 |
|---------|------|
| 含 page_id / 提到"当前大屏 / 刚才那个屏 / 这个大屏" | **C 组件操作**（已有屏） |
| 说"做一个 / 创建 / 新建 / 设计 XX 大屏" | **B 整屏生成**（新建） |
| 仅说"删除 / 改名 / 换背景 / 克隆" | **A 页面级** |
| 仅说"换数据源 / 绑数据集 / 接 SQL/API" | **D 数据绑定** |
| 模糊（"帮我做大屏"，无 page_id 也无具体诉求） | **必须先问用户**：新建还是修改已有？数据来源？组件清单？ |

**2. 模糊需求兜底（用户没指定组件、数据、布局）**

禁止默认 spec_builder 编造一通。优先动作：
- 问 1-2 个关键问题（业务主题 / 大致 5-8 个图想看什么 / 数据从哪来）
- 或者直接命中 B-Step1 模板时，向用户确认"我用 XX 模板复制后再改"

**3. 高频意图 → 脚本/组件 速查**

| 用户说 | 路径 |
|-------|------|
| "排行 / TOP N / 排名" | 组件首选 `JScrollRankingBoard`，动画版 `JDynamicBar` |
| "KPI / 核心数字 / 大数字" | **≥3 个一组并排（二选一，按数据项数决定）**：① `JStatsSummary` — label/value/unit + 环比/同比对比 + 涨跌箭头，文档化驾驶舱风格，**需要展示同/环比对比、或项数不能整除 24（如 5/7/9-11 项）时首选**；② `JColorBlock` — 每项独立色块背景（每条数据自带 `backgroundColor`），可语义化配色（红/橙=警示、绿=正向、蓝/青=中性），**视觉冲击/状态可视化场景首选**——**🚨 强约束：源码 colorBlock.vue:122-124 用 Antd 24 栅格 `span = ceil(24/lineNum)` 渲染，数据项数必须 = `lineNum` 且能整除 24，KPI 行实用项数仅 {2, 3, 4, 6, 8}（4-6 最饱满）；5/7/9-11/13-23 项会折行错位（5 项变 4+1、7 项变 6+1）→ 改用 JStatsSummary**。单个突出大数字 → `JCountTo`（翻牌动画）/ `JNumber`（静态）。⛔ 禁止 N 个 JNumber/JCountTo 横排凑 KPI 行 |
| "完成率 / 达标率" | `JGauge`（指针）/ `JLiquid`（液位）/ `JRingProgress`（环形），value 是 **0-100** 整数 |
| "占比 / 比例 / 分布" | `JPie` / `JRing` / `JRose` |
| "趋势 / 走势 / 时序" | `JLine` / `JSmoothLine` / `JArea` |
| "对比 / 多组数据" | `JBar` / `JMultipleBar` / `JStackBar` |
| "转化 / 漏斗" | `JFunnel` |
| "地图 / 区域 / 飞线 / 热力" | `JAreaMap` / `JFlyLineMap` / `JHeatMap` |
| "装饰 / 好看点" | `JDragDecoration`（12 套预设，禁止与 JDragBorder 混） |
| "边框 / 框一下" | `JDragBorder`（13 套预设，选哪种看 `references/border-style-guide.md`） |
| "标题 / 文字 / 标语" | `JText` |
| "时钟 / 实时时间" | `JCurrentTime` |
| "日历" | `JPermanentCalendar` |
| "换配色 / 复古 / 商务 / 科技色" | `style_ops.py set-palette --name <名称>` |
| "联动 / 点饼图筛柱图" | `linkage_ops.py`（已有屏加联动） |
| "新建多图带联动" | `multi_chart_linkage.py`（一次建多图+联动） |
| "弹窗 / Modal" | `references/popup-guide.md` |
| "外链 / 跳转 / 自定义 JS" | `link_ops.py` |
| "克隆 / 备份 / 恢复" | `backup_ops.py` |
| "看现在有哪些组件" | `comp_ops.py list` |
| "通用组件 / 自由写 ECharts JS / customOption / 写个 JS option 串 / 桑基/树图/自定义图" | **`JCommon`**（菜单"通用组件"） — 写 `config.customOption`（**JS 字符串**，须 `option = {...}; return option;` 结尾），可写 function 等动态逻辑。spec_builder 不会自动写此字段，需 spec 建壳后用 bi_utils patch |
| "自定义组件 / 自定义 echarts / 直接写 echarts JSON" | **`JCustomEchart`**（菜单"自定义组件"） — 写 `config.definitionOption`（**JSON 对象**，纯静态，不能含 function）。spec_builder 不会自动写此字段，需 spec 建壳后用 bi_utils patch |
| "用 Online 表 / cgform / jeecg 表 / Online 报表 / desform 作为数据源" | **BI 模式 (`dataType=4`)** — 见 `references/bi-mode-online.md`，禁止默认套 SQL 数据集 |

> ⚠️ **JCommon ≠ ECharts 内置组件（JBar/JLine/JPie 等）**。"通用组件"是平台菜单分类，专指 JCommon；用户说"通用组件"时**默认指 JCommon**，禁止误映射到 builtin handler 图表。区别看 `references/data-binding-mapping.md` §3。

---

## ⭐ 模糊需求 → 快速好看大屏 SOP（核心）

> **目标**：用户没指定组件/布局/数据时，AI 也能 1 次往返产出"快 + 好看 + 不丑"的大屏。

### 速度铁律（HTTP 越少越快）

| 优先级 | 路径 | HTTP 次数 | 适用 |
|-------|------|-----------|------|
| 🥇 最快 | `template_ops.py copy --replace` | **1** | B-Step1 模板触发词命中 |
| 🥈 次快 | `spec_builder.py` 单次生成全部组件 | **1** | 模板未命中 / 自定义布局 |
| ⛔ 禁止 | 循环 `comp_ops.py add` 逐个加 | N | 任何"建多个组件"的场景都禁止 |

**潜规则**：spec_builder 一个 spec 写 N 个组件 = 1 次 HTTP；逐个 add 一个组件 1 次 HTTP。建 8 个图，前者 1 次，后者 8 次，速度差 ~6-8 倍。

### 组件挑选原则：5 维结构（用户没指定组件时按这个组）

> 不靠行业专属清单，靠**通用结构**——每张大屏从下面 5-7 维选 4-6 项即可，AI 据用户业务描述映射到具体组件。

| 维度 | 用途 | 候选组件（按"高频意图→组件"速查决定具体选哪个） |
|------|------|------------------------------------------------|
| **KPI 数字** | 顶部 KPI 行 ≥3 项 → **`JStatsSummary`**（带环比/同比对比卡，任意项数）/ **`JColorBlock`**（每项独立色块、可语义化配色，**仅项数 ∈ {2,3,4,6,8} 才视觉饱满**——24 栅格约束，详见上方"高频意图"速查）二选一；单大数字 → `JCountTo` / `JNumber` | — |
| **趋势** | 时间维度变化 | JLine / JArea / JSmoothLine / JStepLine |
| **对比** | 多类目/多组对比 | JBar / JStackBar / JMultipleBar / JMixLineBar |
| **占比** | 部分/整体 | JPie / JRing / JRose / JFunnel |
| **排行** | TOP N | JScrollRankingBoard / JDynamicBar / JBubbleRank |
| **地理**（可选） | 业务含地理属性 | JAreaMap / JFlyLineMap / JBubbleMap / JHeatMap |
| **明细/告警**（可选） | 列表/动态信息 | JScrollList / JScrollBoard / JScrollTable / JFlashList |

**挑选流程**：
1. 读用户描述，提取"想看的指标关键词"
2. 用上方"高频意图→组件"速查表把每个指标映射到具体组件类型
3. 缺维度（如完全没说时间/对比）就**反问**而非自己脑补
4. 行业模板若 B-Step1 命中，**优先 copy 模板**再按需替换组件，比从 0 拼快

### 布局规则（按画布等比例算，不写死坐标）

> 画布尺寸由用户决定（默认 1920×1080；竖屏 1080×1920；4K 等比例放大）。AI 按下面比例规则算坐标，**不要硬背像素**。

**通用比例**（让"不丑"的最小约束）：
- 边距（画布外沿到组件） ≥ 短边 × 4%
- 组件间距 ≥ 短边 × 1.5%–2%
- 标题区高度 ≈ 短边 × 5%–7%
- 所有 x/y/w/h 对齐到 10 或 20 的倍数（防像素错位）
- 检查：组件不重叠（前一个 x+w + 间距 ≤ 后一个 x）、不贴边、不留大块孤儿空白

**三种推荐布局形态**（描述结构，不锁坐标）：
| 形态 | 结构 | 适合 |
|------|------|------|
| **A 顶 KPI 行 + 主图网格** | 顶部 1 行 4-5 个 KPI；下方 2-3 行 × 3 列主图网格 | 最通用驾驶舱 |
| **B 左侧栏 + 中央大图 + 右侧栏** | 两侧各 2-3 个小图；中央 1 大图占 ~50% 宽 | 突出核心趋势/地图 |
| **C 四角 KPI + 中央大图** | 中央大图占主视觉；四角各 1 个 KPI | 监控/指挥中心 |

**默认搭配**：主题 `dark` + 平台命名色板（用户说"复古/商务/科技"等走 `style_ops.py set-palette`）。

### 演示数据量原则（AI 编 mock 时必读）

> **总则**：用户没给真实数据让 AI 编演示数据时，**数据条数尽可能多**。默认值偏少（多数 5-7 条），照抄会让大屏空旷且滚动/分页/排行类组件不触发动效。

| 组件类型 | 推荐演示数据量 | 触发条件 |
|---------|---------------|---------|
| **滚动类**（JScrollList / JScrollTable / JScrollBoard / JFlashCloud / JCardScroll） | ≥ 可视行数 × 1.5（按容器 h / 行高估算可视行数） | 数据 ≤ 可视时不滚 |
| **排行类**（JScrollRankingBoard / JDynamicBar / JCapsuleChart / JBubbleRank / JFlashList） | 取上限 — JBubbleRank 5 / JFlashList 4 / **JScrollRankingBoard：data_count ≥ rowNum+3**（rowNum=floor(h/40)，≈ 10 时 h≈400；h=195 时 rowNum=4） | **data_count > rowNum 才滚动**；两者相等全部展示完毕→不滚动 |
| **类目对比**（JBar / JStackBar / JLine / JArea） | ≥ 8-12 类目（柱图）/ ≥ 12-24 时间点（折线） | 太少视觉空 |
| **占比类**（JPie / JRing / JRose / JFunnel） | 5-8 项（占比类反而忌过多） | — |
| **KPI / 单值类**（JNumber / JCountTo / JGauge / JLiquid） | 1 个值，数据量与该规则无关 | — |
| **地图类**（JAreaMap / JFlyLineMap / JBubbleMap / JHeatMap） | 全国铺满（≥ 25 省份）或 ≥ 30 飞线/热点 | 稀疏会显假 |
| **明细/告警**（JList / JCommonTable / JDevHistory） | ≥ 10-15 行 | 撑满容器才耐看 |

**自检 checklist**：
- 滚动组件保存后回查 `数据行数 vs (h / row.height + marginBottom)` 比值，低于 1.5 倍直接补数据
- spec_builder 默认 chartData 多数是 5-7 条，**禁止照抄默认 chartData 当成"演示数据已够"**
- 真实接口/数据集到位后此规则失效（取真实数据，量由业务定）

### AI 模糊需求处理 SOP（按顺序走）

1. **B-Step1 行业模板命中？**
   - 是 → `template_ops.py copy` → 与用户确认改文案/数据 → 完成
   - 否 → 进入 2
2. **5 维结构 + 高频意图速查 = 选 4-6 个组件**，按形态 A 默认排版
   → `spec_builder.py` 单次生成 → 给用户预览
3. **数据来源未指定** → 必须先问（强制规则 #7）；用户允许 mock 时首选静态 mock 让效果最快出，后续再换真实数据集

---

## 场景决策树（入口即分叉，直达最短路径）

> 先判断操作类型，再判断子场景，**不要默认走 spec_builder**。

---

### A. 页面级操作

| 场景 | 脚本 | 备注 |
|------|------|------|
| **创建空白大屏** | 直接调 `bi_utils.create_page()`（见下方模板） | 禁止用 spec_builder；`page_ops.py` 无 create 子命令 |
| 删除大屏 | `page_ops.py delete` | 必须先确认 |
| 重命名/换背景/加水印 | `page_ops.py` | 读 `references/page-config-guide.md` |
| 标记/取消模板 | `page_ops.py set-template --flag 0\|1` | 单字段改 `izTemplate`，最小 payload |
| 克隆/导出/导入/对比 | `backup_ops.py`（子命令：`clone` / `export` / `import` / `diff`） | |

**创建空白大屏标准调用：**
```bash
cd <skill目录> && python3 - <<'EOF'
import sys, time; sys.path.insert(0, 'references')
import bi_utils
t0 = time.time()
bi_utils.init_api('<API>', '<TOKEN>')
page_id = bi_utils.create_page('<名称>', style='bigScreen', theme='dark', background_image='/img/bg/bg4.png')
wprint(f'预览: <API>/drag/share/view/{page_id}?token=<TOKEN>&tenantId=<TENANT_ID>')
print(f'耗时: {time.time()-t0:.2f}s')
EOF
```

---

### B. 整屏生成（从头新建含组件的大屏）

**Step 1：模板匹配**（用户说"从0开始"则跳过）

| 触发词（含近义） | 模板名 | 模板ID |
|--------|-------|--------|
| 金融/银行/普惠/乡村/信贷/财务/资产/贷款 | 乡村振兴普惠金融服务平台 | 1024608431274250240 |
| 环境/污水/排放/生态/水务/环保/碳排/双碳 | 北京市污水排放总量 | 1022392593179791360 |
| 科技/工业/IoT/能源/电力/制造/工厂/车间/产线/物联网 | 北京科技数字化云平台 | 1014376428645961728 |
| 医院/医疗/机构管理/卫生/诊疗/床位 | 医院实时数据监控 | 1011800681234354176 |
| 旅游/景区/客流/公园/展厅/展会 | 旅游数据分析中心大屏 | 1016994272231608320 |
| 房产/房地产/楼市/租房/物业 | 杭州房地产市场宏观监控 | 1024545852833189888 |
| 警务/安防/治安/监控室/指挥中心/应急 | 警务监控系统 | 1024545264544305152 |
| 交通/车辆/物流/配送/仓储/运输 | 车辆分布图 | 1017325669831987200 |
| 销售/订单/驾驶舱/营收/营销/电商/GMV/CRM | 集团综合数据大屏 | 1151069555267260416 |
| 公园/自然/景点/文旅/园区 | 香山公园客流大数据 | 1027085484978388992 |

**命中** → `template_ops.py copy --replace '{"旧文本":"新文本",...}'`（`--replace` 是 JSON 全局文本替换：对模板内 componentName / chartData / option 的所有匹配文本做 replace），完成，无需进入 Step 2。建议向用户确认"我先用 XX 模板复制再改文案/数据，可以吗？"  
**未命中** → 不许模糊套用（"教育/政务/HR/人力/营业厅/学校"等不在表里的领域，禁止硬塞最近的科技/金融模板）。直接进入 Step 2。  
**领域不在表 + 用户没给组件清单** → 必须先问业务主题与想看的核心指标，再走 Step 2。

**Step 2：数据来源决定路径**

```
数据来源？
├── 静态 mock 数据（用户给数据 / 让 AI 编造）
│     └── spec_builder（一次生成所有组件）
│           1. 读 references/spec-builder.md
│           2. 写 /tmp/<名称>.spec.json
│           3. 执行 spec_builder.py <API> <TOKEN> /tmp/<名称>.spec.json
│
├── YApi mock 接口
│     └── spec_builder 生成布局 → yapi_ops.py 绑定数据集
│
├── SQL 数据集（查数据库）
│     └── spec_builder 生成布局 → dataset_ops.py 绑定
│           注意：SQL 含 ${} 时用 --sql-file，禁止命令行传递
│           必须先 SHOW TABLES 确认表名
│
├── 文件数据集（Excel/CSV）
│     └── spec_builder 生成布局 → files_ops.py 绑定
│           用户未提供文件路径时：自动从 chartData/mock 数据生成 CSV，用 --mock-data 传入
│           示例: files_ops.py create-bind <api> <token> <page_id> --mock-data '<JSON数组>' --comp JBar --title "标题"
│           禁止提示"请先上传文件"——有数据就能自动建文件
│
├── 存储过程
│     └── spec_builder 生成布局 → proc_ops.py 绑定
│
└── BI 直连 Online 表 / 设计器表单 / Online 报表（dataType=4）
      触发：用户说"用 X 表 / cgform / jeecg 表 / Online 报表 / desform 作为数据源"
      特点：直接绑表字段，不创建独立数据集；自带字段级时间过滤(timeCondition)和字典翻译
      → 走 references/bi-mode-online.md 的脚本模板（spec_builder 当前不支持，需手写组件 config）
        已有参考大屏时优先 deepcopy 其组件 config（见 bi-mode-online.md §七）
```

**用户未指定数据来源时必须先问**（纯静态布局除外）。

**spec_builder 用法：**
> `--page-id <ID>` 追加组件到已有页面（保留原有组件）；不传则新建页面。
```bash
# 查组件 schema（字段不确定时）
python3 references/scripts/spec_builder.py --schema JStatsSummary        # L1 精简
python3 references/scripts/spec_builder.py --schema JColorGauge --full   # L2 完整
python3 references/scripts/spec_builder.py --schema --list               # L3 总览

# 生成
python3 \
  references/scripts/spec_builder.py <API> <TOKEN> /tmp/<名称>.spec.json
```
spec_builder 自动处理：chartData 序列化、透明 bg、dark 主题、ECharts 轴样式、gradient 展开、pie 无 xAxis/yAxis、compareState 转换、命名色板应用、布局约束预警。

**变体（variant）写法**：spec 中 `type` **不带后缀**（如 `"type":"JStatsSummary"`），变体通过同级 `"variant":"1"` 字段指定（生成 JStatsSummary_1）。直接写 `"type":"JStatsSummary_1"` 会找不到 handler。

**🚨 spec JSON 核心字段速查（写错=脚本多跑一次，每次 +2-3 min）**

| 字段 | ✅ 正确写法 | ❌ 错误写法（直觉陷阱） |
|------|-----------|----------------------|
| 位置/尺寸 | `"pos": [x, y, w, h]`（4 元素数组） | `"x":60,"y":90,"w":1800,"h":950`（分离字段） |
| 静态数据 | `"data": [{"name":"A","value":1}]` | `"chartData": [...]`（这是 config 存储字段名，spec 里无效） |
| 组件变体 | `"variant": "2"`（同级顶层字段） | `"type": "JStatsSummary_2"`（带后缀找不到 handler） |
| JText 文字 | `"text": "内容"`（顶层） | `"option.body.text"` / `"data[0].value"`（handler 不读这里） |

**禁止直接 Read `references/scripts/defaults/*.json`**，统一经 `--schema --full` 调取。

---

### C. 组件操作（修改已有大屏）

```
组件操作？
├── 查看当前有哪些组件
│     → comp_ops.py list
│
├── ⭐ 迭代替换（删旧+加新+改色一把梭，单次 HTTP 往返）
│     触发：用户说"换别图表"、"把 XX 换成 YY"、"替换饼图为柱形图" 等
│     → spec_builder --page-id <ID>，spec 顶层同时写 delete + components + palette：
│       {
│         "page": {"name":"..."},
│         "palette": "科技",                              // 可选，自动应用命名色板
│         "delete": {"types": ["JPie","JRing","JAntvGauge"]},  // 按 types/names/ids 任一批量删
│         "components": [ ...仅新增组件... ]
│       }
│     优势：1 次 query_page → 过滤旧 → append 新 → 应用色板 → 1 次 save_page
│           （替代原 3 次 comp_ops delete + 1 次 spec_builder append + 2 次 set-palette = 6 HTTP）
│
├── 添加组件（纯布局 / 静态数据 / 1个或多个）
│     → spec_builder --page-id <ID> /tmp/x.spec.json
│       （spec 只写要新增的组件，自动追加，保留已有组件）
│
├── 添加单组件 + 同时绑定 SQL/文件数据集
│     → comp_ops.py add --comp <type> --create-sql / --sql-file / ...
│
├── 添加多组件 + 联动（≥2图）
│     → multi_chart_linkage.py（省 80% 步骤）
│
├── 删除单个/部分组件（必须先确认）
│     → 用户给了名称且唯一：直接 comp_ops.py delete ... --name <名称>（无需先 list）
│       用户给了类型且页面只有 1 个该类型：直接 comp_ops.py delete ... --type <类型>
│       ⚠️ 名称/类型不唯一（如说"删饼图"但页面有 3 个 JPie / 多个组件同名）：
│         必须先 comp_ops.py list 让用户指认 ID，再 --id 删；禁止盲删导致误删
│       批量多类型：comp_ops.py delete ... --types "JPie,JRing,JAntvGauge"（逗号分隔，1 次 HTTP）
│       批量多名称：comp_ops.py delete ... --names "饼图1,柱图2"
│       名称不确定时才先 list，再 comp_ops.py delete ... --id <组件ID>
│
├── 清空所有组件（必须先确认）
│     → bi_utils.query_page(page_id)                     # 加载元数据
│       bi_utils._page_components[page_id] = []
│       bi_utils.save_page(page_id)
│
├── 切换全屏配色（命名色板，与产品 UI "配色" 下拉一致）
│     → style_ops.py set-palette --name <名称>    # 独立操作
│       或 spec_builder spec 顶层 "palette":"<名称>"   # 建屏/迭代时内嵌
│       可选：默认/复古/淡雅/未来/渐变/简洁/商务/柔和/科技/明亮/经典/清新/活力/火红/轻快/灵动
│       自动处理：option.color + customColor + 清除 series 硬编码 color；
│       默认按 y/x 轮转色板起点，--no-rotate 则所有图从 color[0] 起
│       查色值：style_ops.py list-palettes（无需 API/token）
│
├── 批量修改所有组件属性（如隐藏标题/改颜色/改渐变）
│     ⚠️ Step 0 — 组件清单来源优先级（决定是否跳过 query_page）：
│       1. 本会话刚写的 spec JSON / 刚 query_page 的返回值 → 直接用，跳过 query
│       2. 否则 query_page 拿当前清单
│       3. 拿到 unique(c['component']) 集合后，对 references/bi-comp-option-config.md
│          或 references/<comp-group>-option-config.md 定点搜"<CompType>"
│       ⛔ 禁止对整个 references/ 广义 grep "渐变/gradient/color/字体" ——
│          会扫到 99 个无关组件的文档（如 JCurrentTime / JStatsSummary / JOrbitRing
│          / JListProgress / JScrollList / JTabToggle），浪费上下文且延迟决策。
│
│     → 正确修改模式（query_page 返回值取组件，不能从 _page_components 取）：
│       page = bi_utils.query_page(page_id)
│       comps = page.get('template', [])                  # 从返回值取，非 _page_components
│       if isinstance(comps, str): comps = json.loads(comps)
│       for comp in comps: <修改 comp['config']>
│       bi_utils._page_components[page_id] = comps       # 写回缓存
│       bi_utils.save_page(page_id)
│
├── 修改组件配置（标题/颜色/数据/位置）
│     🚨 Step 0 — 先确认字段名（强制预检）：
│       上下文已有该组件 config → 直接看；字段不确定 → 查 bi-comp-option-config.md 对应 section
│
│     Step 1 — 选执行方式（字段名确认后再选）：
│
│       ┌─ 纯赋值（1个或多个字段，无条件判断/计算/循环）
│       │    → comp_ops.py edit --set（支持嵌套路径和数组下标 series[0].top）
│       │    ⚠️ "上下文已有 config"不是写临时脚本的理由——有 config 也用 comp_ops.py edit
│       │    ⚠️ --set 路径从 config 起算，禁止加 config. 前缀；x/y/w/h/componentName 例外写顶层名
│       │
│       └─ 需要 Python 逻辑（条件判断 / 计算值 / 循环遍历）
│            → 临时脚本
│
├── 组件群组/解组
│     → group_ops.py
│
├── 添加联动/钻取
│     → linkage_ops.py（读 references/linkage-drill-guide.md）
│
├── 添加外链/自定义 JS
│     → link_ops.py
│
└── 批量修改样式
      → style_ops.py（10 个子命令）：
        show-colors（看当前色） / set-title-color / set-axis-color / set-grid-color / set-legend-color
        set-font-size / set-bg-all / set-palette / list-palettes
        batch-edit（任意 config 路径赋值，--path/--value/--type/--name 过滤）
```

---

### D. 数据绑定（给已有组件换数据源）

> **📌 绑定前必读**：`references/data-binding-mapping.md`（两套映射机制：顶层 dataMapping vs 组件自带 option.fieldMap/header.key）——否则绑了也不显示数据。

> **🚨 一律走 `dataset_ops.py bind` / `bind-batch`，禁止手写临时 `.py` 直接改 `cfg['dataType']=2 / dataSetId / dataMapping`**。原因：脚本封装了 4 项**前端必读**的字段元信息回填（`option.columns` JCommonTable 列定义、`fieldOption` UI 字段下拉、`paramOption`、`dataSetIzAgent / dataSetMethod / dataSetApi`），靠 `getAllChartData` 拿真实 API 字段名 fallback。手写绑定漏写 → JCommonTable 表头/表体全空（`useTableBiz.ts:339` 直接读 `config.option.columns`，缺失时 `columns=[]`）。UI 复制组件能显示是因为 `dataSetCompService` 在保存时回填，**API 路径不会触发前端的回填逻辑**——这是 AI 最容易踩的"看似都改了实则缺关键字段"陷阱。

> **🚨 ≥2 个组件绑定一律用 `dataset_ops.py bind-batch`，禁止 shell 并行调多次 `bind`**。每次 `bind` 都是「query → 改 target → 整页 save」，并发会互相覆盖快照，导致**非 target 组件的 option 出现脏写**（实测：JRingProgress 的 `valueFontSize` 被改成 38、`lineHeight` 被改成 0，KPI 数值不显示）。`bind-batch` 一次 query → 内存改 N 个 target → 一次 save 彻底规避。

**易混脚本对照（防止选错）**：

| 脚本 | 作用 | 何时用 |
|------|------|--------|
| `dataset_ops.py` | 创建/绑定 **数据集**（SQL/API/JSON 等数据集对象） | 大屏组件取数主入口；自写 Java API 也走这里 `create-api`；多组件绑定走 `bind-batch` |
| `datasource_ops.py` | 配置 **数据源连接**（JDBC/NoSQL/Redis/ES/MongoDB） | 数据集底层缺 DB 连接时新建连接 |
| `linkage_ops.py` | 给**已有大屏**加联动/钻取（点 A 筛 B） | 大屏已存在，只想加交互 |
| `multi_chart_linkage.py` | **一次性建多图 + 联动**（省 80% 步骤） | 新建多图同时配联动 |
| `link_ops.py` | 组件外链跳转 + **自定义 JS 拦截器**（jsConfig） | 点击跳外部链接 / 前置 JS 逻辑 |
| `yapi_ops.py` | YApi mock 接口的创建 / 高级 mock 脚本（advmock） | 数据来源是 YApi |
| `files_ops.py` | Excel/CSV 文件数据集；**用户无文件时自动从 `--mock-data` JSON 数组生成 CSV 上传** | 用户上传文件做数据源，或 AI 自动生成 mock 文件 |
| `proc_ops.py` | 数据库存储过程作为数据集 | 数据来源是 SP |

| 数据源类型 | 脚本 | 参考文档 |
|----------|------|---------|
| YApi mock 接口 | `yapi_ops.py`（`create-mock` / `create-mock-batch` / `set-advmock`） | `references/api-dataset-examples.md` |
| YApi mock + 联动/钻取（按参数分支返参） | `yapi_ops.py create-mock --advmock-script/--advmock-file` 或 `set-advmock`；数据集用 `dataset_ops.py create-api --params` | `references/linkage-drill-guide.md` §API 数据集联动 |
| SQL 数据集 | `dataset_ops.py` | `references/dataset-guide.md` |
| 文件数据集（Excel/CSV）；用户无文件 → AI 自动生成 | `files_ops.py create-bind --mock-dat
