# Jeecg Onlform

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-jeecgboot-skills-jeecg-onlform`
- **Verified:** Pending review
- **Seller:** [jeecgboot](https://agentstack.voostack.com/s/jeecgboot)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [jeecgboot](https://github.com/jeecgboot)
- **Source:** https://github.com/jeecgboot/skills/tree/main/jeecg-onlform
- **Website:** https://jeecg.com

## Install

```sh
agentstack add skill-jeecgboot-skills-jeecg-onlform
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# JeecgBoot Online 表单 AI 自动生成器

将自然语言的表单需求描述转换为 Online 表单配置 JSON，并通过 API 在 JeecgBoot 系统中自动创建/编辑表单。

> **重要：本 skill 处理「Online 表单」（元数据驱动，运行时 CRUD），不涉及「设计器表单」（desform）。两者是完全独立的表单体系。**

## 选择正确的技能

| 用户需求 | 应使用的技能 |
|---------|------------|
| 元数据驱动的表/表单配置（字段定义、控件类型、数据库建表） | **本技能 (jeecg-onlform)** |
| 拖拽式可视化表单设计（自由布局、表单设计器） | jeecg-desform |
| SQL查询结果以**列表**展示 | jeecg-onlreport |
| SQL查询结果以**图形**展示（柱状图/饼图/折线图） | jeecg-onlchart |
| 复杂Excel样式报表（打印、分组、循环） | jimureport |

## 目录结构

```
scripts/
├── onlform_creator.py      # 表单创建/编辑（单表/主子表/树表）
├── onlform_jimureport.py   # 积木报表集成（创建/删除报表并关联）
├── onlform_enhance.py      # JS/Java/SQL增强 + 自定义按钮
├── onlform_auth.py         # 权限配置（字段/按钮/数据权限）
├── onlform_data.py         # 数据 CRUD（增删改查/树数据/导出CSV）
└── onlform_menu.py         # 菜单挂载 + 路由缓存 + 角色授权

templates/                  # ⚡ 可直接复用的 JSON 模板（优先读取，不要现场设计）
└── all_controls_master_sub.json  # 全控件主子表（26种控件，主表+一对多+一对一）
                                  # ⚠️ 模板内的表名仅为占位符，创建时必须按业务语义自定义表名，不能原样照用

references/
├── onlform-field-types.md  # 字段类型/控件/字典/校验/默认值/扩展配置
├── onlform-widget-types.md       # 控件速查表（fieldShowType 完整清单）
├── onlform-head-field-types.md   # head 级字段说明（tableType/themeTemplate 等）
├── onlform-full-widget-template.md # 26种控件配置速查（dictTable/dictField/fieldExtendJson）
├── onlform-enhance-js.md   # JS增强参考（onlChange/loaded/列表拦截/API，~310行）
├── onlform-enhance-java.md # Java增强参考 + 实战案例（~140行）
├── onlform-enhance-misc.md # SQL增强/自定义按钮/fieldHref/实战（~130行）
├── onlform-auth.md         # 权限配置（字段/按钮/数据权限 API）
├── onlform-data-crud.md    # 数据 CRUD API + 存储格式
├── onlform-jimureport.md   # 积木报表集成 8 步流程
├── onlform-misc.md         # 杂项：表类型/布局/BPM/视图/错误处理
├── onlform-api-reference.md # 完整 JSON 数据结构和字段枚举
└── onlform-route-cache.md  # 路由缓存配置（动态/静态路由、组件名称映射）
```

## 前置条件

用户必须提供以下信息（或由 AI 引导确认）：

1. **API 地址**：JeecgBoot 后端地址（如 `https://boot3.jeecg.com/jeecgboot`）
2. **X-Access-Token**：JWT 登录令牌（从浏览器 F12 获取）

## 执行效率规则（减少无谓等待）

所有 HTTP 调用必须遵循，否则用户会感到响应明显变慢。**本节为强制要求，违反会直接被用户吐槽"太慢了"。**

### 0. Windows 环境下**必须**用 PowerShell tool 跑 python（最容易踩的坑）

**现象**：Windows 的 Bash tool 会把 `python` / `python -c` / skill 脚本当作长命令自动 `run_in_background`，tool 立即返回一个 background ID，真正的执行输出要等系统通知才到——把毫秒级调用放大到数秒，用户会立即感到"卡"。

**规则**：
- **Windows（platform=win32）** → 所有 python 调用（skill 脚本 + `python -c` 探测）都用 **PowerShell tool**，不要用 Bash tool。
- **Linux / macOS（platform=linux/darwin）** → 用 Bash tool 即可，python 不会被后台化。
- `curl` 在任何平台都不用——跨平台不一致，且 Windows Bash 下同样被后台化。

**Windows 正确示例**：
```
PowerShell: python C:/path/to/onlform_creator.py --api-base http://localhost:8080 --token xxx --config config.json
PowerShell: python -X utf8 -c "import urllib.request as u, json; r=u.urlopen(...); print(r.read().decode())"
```

**Windows 错误示例**（会被后台化）：
```
Bash: python onlform_creator.py ...       ← 会返回 "Command running in background"
Bash: python -c "..."                     ← 同上
Bash: curl -X POST ...                    ← 同上
```

> **历史教训**：本 skill 早期版本错误地声称"Python 在所有 shell 下都同步返回"——实测 Windows Bash tool 对 python 也会后台化。曾因此被用户连续吐槽"执行太慢了"。

> **Windows 中文编码规则（`python -c` 必须加 `-X utf8`）**：
> PowerShell 默认编码为 UTF-16 LE，`python -c "..."` inline 代码中含中文字面量时，shell 传参过程会乱码，导致 `SyntaxError: unterminated string literal`。
> - **解法**：始终用 `python -X utf8 -c "..."` 而不是 `python -c "..."`
> - **含中文的复杂逻辑**：写入临时 `.py` 文件再执行，彻底避免 inline 中文
> - **结果含中文的 print**：在 inline 脚本开头加 `import sys; sys.stdout.reconfigure(encoding='utf-8')`

### 1. 并行读取 reference 文件，不要串行

需要多个 reference 文件时，在**同一条消息**中并发发出所有 Read 调用，不要一个读完再读下一个。

```
// ✅ 正确：一条消息同时 Read 多个文件（并发）
Read(onlform-field-types.md) + Read(onlform-master-detail-checklist.md) + Read(onlform-enhance-js.md)

// ❌ 错误：串行读取
Read(field-types) → 等结果 → Read(checklist) → 等结果 → Read(enhance)
```

> **常用并发组合**：建表 → 同时读 `field-types.md` + `master-detail-checklist.md`；JS增强 → 同时读 `enhance.md`（若已在建表时读过则跳过）。

### 2（原1）. 优先用 skill 自带的 Python 脚本，不要自己另起 HTTP 封装

skill 已提供 `onlform_creator.py` / `onlform_jimureport.py` 等脚本，它们封装了鉴权、重试、head 解析、主子表关联等细节。需要一次性 HTTP 探测再用 `python -c`。

### 3（原2）. 跳过非必要前置检查，直接跑脚本

- **表名查重**：仅在"用户暗示要复用已有表 / 表名看上去像已有资源"时才查。普通新建场景直接跑 `onlform_creator.py`——遇重名接口会返回明确错误，预查反而增加一次往返。`onlform_creator.py` 已内置自动加 `_1`/`_2` 后缀重试，主表冲突无需手动干预。
- **字典存在性**：以下系统内置字典**直接使用，禁止发 API 查询**，值已固化：

  | 字典编码 | 值 → 含义 | 控件类型 |
  |---------|----------|---------|
  | `yn` | `1`=是 / `0`=否 | list / radio / switch |
  | `sex` | `1`=男 / `2`=女 | list / radio |
  | `valid_status` | `1`=有效 / `0`=无效 | list / radio |
  | `priority` | `L`=低 / `M`=中 / `H`=高 | list / radio |
  | `bpm_status` | `1`=待提交 / `2`=审批中 / `3`=审批通过 / `4`=审批拒绝 | list |

  仅在字典编码**明显是业务自定义**且不确定是否创建过时才发 `sys/dict/list` 查询。

- **❌ 严禁拼造 `/sys/dict/queryDictItemsByCode/{code}` 这种 RESTful 风格的字典查询路径**：后端根本没有这个端点，会返回 `"路径不存在，请检查路径是否正确"`。
  - 正确的「按 dictCode 直接拿字典项」接口是 `GET /sys/api/queryDictItemsByCode?code={dictCode}`（`code` 走 query 串，不是 path variable）。
  - 但对上表中的内置字典，**仍然不要调用任何接口**——直接用固化值。
  - 业务自定义字典优先走 `sys/dict/list?dictCode=xxx` + `sys/dictItem/list?dictId={id}` 两步法（见 `references/onlform-data-crud.md`）。

- **link_table 引用表存在性**：这项仍然必须查（见 `references/onlform-field-types.md`），引用不存在的表会让创建成功但运行时报错，排查成本高。

### 4（原3）. 并行多个 GET 检查时，一个 Python 调用里顺序打完，不要拆成多条 shell

一次 tool call 拿到所有结果；拆成多条 shell 既有进程启动开销，在 Windows 下还会被后台化。
```python
# 用 shell tool 跑（Windows: PowerShell，Linux/macOS: Bash）
python -c "
import urllib.request as u, json
h = {'X-Access-Token':''}; base = 'http://host'
def g(p): return json.loads(u.urlopen(u.Request(base+p, headers=h), timeout=10).read())
dup = g('/sys/duplicate/check?tableName=onl_cgform_head&fieldName=table_name&fieldVal=xxx')
dct = g('/sys/dict/list?dictCode=xxx')
print('dup=', dup.get('result'), '; dict.total=', dct.get('result', {}).get('total'))
"
```

### 5（原4）. API base 确认（避免"路径不存在"返工）

JeecgBoot 后端的 context path 因部署而异：
- 较老版本 / 标准部署：`http://host:port/jeecg-boot`
- 较新版本 / 根路径部署：`http://host:port`（无 `/jeecg-boot` 后缀）

**首次不确定时**：直接按用户给的原样用。如果 `onlform_creator.py` 返回 `"路径不存在，请检查路径是否正确"`，去掉 `/jeecg-boot` 重试一次（或反之）——这个错误是确定性的，不要改别的参数。

**「路径不存在」也可能是接口路径本身写错了**（context path 没问题，但端点本身后端没有）。常见反例：
- ❌ `/sys/dict/queryDictItemsByCode/{code}` —— 路径 + 风格全错，后端没有这个端点
- ✅ 正确：`GET /sys/api/queryDictItemsByCode?code={code}`（注意是 `/sys/api`，参数走 query）

排查顺序：先按 context path 加/去 `/jeecg-boot` 重试；仍然 404 时，回到 SKILL 文档/references 里复核接口路径——**不要凭印象拼 RESTful 风格的 URL**。

### 6. 编辑前查字段顺序：直接用 `listByHeadId`，禁止其他接口

> **历史教训**：曾因依次试错 `field/list`（返回跨表乱序垃圾）→ 读脚本源码 → `getByHead`（返回空）→ 才到 `listByHeadId`，浪费了 4 次往返，被用户吐槽"不应该 30s 就搞定吗"。

**强制规则（新增/删除/修改字段前获取现有字段时必须遵守）：**

- ✅ 唯一正确接口：`GET /online/cgform/field/listByHeadId?headId={headId}`
- ❌ 禁止用 `field/list`——不带 `cgformHeadId` 过滤时会返回所有表的混合数据
- ❌ 禁止用 `getByHead`——实测返回空 fields
- ❌ 禁止为了查接口用法去读 `onlform_creator.py` 源码——直接用上面的接口即可

**多表并行查询（一次 shell tool 调用，不要串行；Windows: PowerShell，Linux/macOS: Bash）：**
```python
for tbl, hid in [('t1','id1'), ('t2','id2')]:
    req = u.Request(base + '/online/cgform/field/listByHeadId?headId=' + hid, headers=h)
    fields = json.loads(u.urlopen(req, timeout=10).read()).get('result', [])
    # 按 orderNum 排序后直接使用
    fields.sort(key=lambda f: f.get('orderNum', 999))
```

### 7. 建表时必须加日期后缀，避免冲突重试链

> **历史教训**：`dept_info` 冲突 → 改名 dept_info_1 → 子表再次冲突 → 再改名 → 额外更新 subTableStr，三步重试链浪费 ~50s。

**强制规则：** 从用户描述推导业务表名后，立即拼上当日日期后缀再写入 config JSON，无需查重，直接创建。

```
# 格式：业务名_YYYYMMDD
dept_info_20260509      ← 主表
dept_archive_20260509   ← 一对一子表
dept_employee_20260509  ← 一对多子表
```

- 日期后缀保证全局唯一，彻底跳过自动重试逻辑
- 子表同步加后缀，保持命名一致性
- 完成后在汇总中告知用户实际表名

### 8. 所有临时 JSON 配置在一个 Python 脚本里批量写入

> **历史教训**：3 个 JSON 文件拆成 3 次 Write tool call，每次有固定开销，合计浪费 ~12s。

**强制规则：** 多个临时 JSON 配置必须在**同一个 Python 脚本**里批量写入，禁止逐个调用 Write tool。用 Python 的 `json.dump` 写文件——跨平台一致，无 BOM 风险。

```python
# 正确：在同一个 Python 脚本里批量写入多个 JSON（跨平台）
import tempfile, json, os, subprocess

tmp = tempfile.gettempdir()  # 自动适配 Windows %TEMP% / Linux /tmp / macOS /var/folders/.../T
CREATOR = r'/scripts/onlform_creator.py'

configs = {
    'onl_main.json':  {"action": "create", "tables": [{"tableName": "...", ...}]},
    'onl_sub1.json':  {"action": "create", "tables": [{"tableName": "...", ...}]},
}
paths = {}
for fname, cfg in configs.items():
    path = os.path.join(tmp, fname)
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(cfg, f, ensure_ascii=False)
    paths[fname] = path

# 依次调用 onlform_creator.py
for path in paths.values():
    subprocess.run(['python', CREATOR, '--api-base', BASE, '--token', TOKEN, '--config', path], check=True)
```

### 9. 字段编辑"查询 + 生成配置 + 执行"合并为 1 个 Python 脚本

> **历史教训**：查 orderNum → Write tool 写 JSON → 再调用 creator，拆成 3 步 tool call 浪费 ~10s。

**强制规则：** 编辑字段时，把 listByHeadId 查询、edit config 生成、写临时文件、调用 creator 全部写进**一个 Python 脚本**，在单次 shell tool call（Windows: PowerShell，Linux/macOS: Bash）里跑完。

```python
# 模板：查询 → 生成 config → 写文件 → 调用 creator（一个脚本搞定）
import subprocess, json, os, tempfile
import urllib.request as u

# 1. 查询现有字段
fields = query_fields(head_id)

# 2. 在内存中构建 edit config（无需 Write tool）
cfg = {"action": "edit", "tableName": tname, "addFields": [...], "modifyFields": [...]}
path = os.path.join(tempfile.gettempdir(), f'onl_edit_{tname}.json')
with open(path, 'w', encoding='utf-8') as f:
    json.dump(cfg, f, ensure_ascii=False)

# 3. 直接调用 creator
subprocess.run(['python', '-X', 'utf8', CREATOR, '--api-base', BASE, '--token', TOKEN, '--config', path], check=True)
```

### 10. 多表编辑必须用 `tables: []` 并行 + 单表 add/modify 一次提交（节省 ~20s）

> **历史教训**：曾分两轮编辑 3 张表 = 6 次串行 `subprocess.run(creator)`。每次 creator 启动 ~1s + addAll/syncDb HTTP 各 ~1s ≈ 共 18-25s。三个症状叠加：
> 1. 同一张表的 `addFields`（新增）和 `modifyFields`（重排）拆成两轮调用 → HTTP/syncDb 翻倍
> 2. 多张表的 edit 串行 spawn 子进程 → 表数 × Python 冷启动
> 3. 每次都重新 import 模块 → Windows 上每次 ~800ms 启动开销

**强制规则（多表/复合编辑必须遵守）：**

1. **同一张表的所有变更合并为一次 editAll**：`addFields` + `modifyFields` + `deleteFields` 写在同一个 config，creator 内部一次提交即完成。

   > ⚠️ **addFields 的 orderNum 不被后端采纳——新字段始终追加到末尾（实测）。**
   > 同一次 editAll 里 `modifyFields` 只对已存在字段生效，对同批 `addFields` 新建的字段无效。
   > **教训来源**：2026-05-09 给员工子表插入 `sex` 字段，指定 `orderNum=9` 并在 `modifyFields` 里后移 `id_card/phone`，结果 `sex` 仍追加到末尾（orderNum=11），需第二次单独 `modifyFields` 才修正。

   **插入到中间位置的正确两步法：**
   - **第一步**：`addFields` 创建字段（orderNum 随便填，后端忽略，字段追加到末尾）；`modifyFields` 里只后移已有字段
   - **第二步**：单独再跑一次 `modifyFields`，把新建字段的 orderNum 设到目标位置

   ```python
   # 第一步：创建字段 + 后移已有字段（新字段 orderNum 会被忽略，先追加到末尾）
   cfg1 = {"action":"edit","tableName":"t","addFields":[{"dbFieldName":"sex",...}],
           "modifyFields":[{"dbFieldName":"id_card","orderNum":10},{"dbFieldName":"phone","orderNum":11}]}
   # 第二步：修正新字段的 orderNum（必须在第一步完成后执行）
   cfg2 = {"action":"edit","tableName":"t","modifyFields":[{"dbFieldName":"sex","orderNum":9}]}
   ```

2. **多表编辑用顶层 `tables: []`**：`onlform_creator.py` 的 `action: "edit"` 现在支持 `tables` 数组，会用线程池并发执行 N 张表的编辑。表数 ≥ 2 时**必须**用此格式，不要写 N 个单表 config 串行 spawn。

```python
# ✅ 正确：一次 creator 调用，N 张表并行
cfg = {"action": "edit", "tables": [
    {"tableName": "t1", "addFields": [...], "modifyFields": [...]},
    {"tableName": "t2", "addFields": [...]},
    {"tableName": "t3", "modifyFields": [...]}
]}
subprocess.run(['python', '-X', 'utf8', CREATOR, '--api-base', BASE, '--token', TOKEN, '--config', path], check=True)

# ❌ 错误：串行 spawn 3 次 creator
for cfg in [cfg1, cfg2, cfg3]:
    subprocess.run([..., '--config', path], check=True)  # 每次 ~3-5s

# ❌ 错误：同一张表 add 一轮、reorder 一轮
subprocess.run([..., '--config', add_only_config])    # 第一轮：add
subprocess.run([..., '--config', reorder_only_config]) # 第二轮：reorder（多余的 syncDb）
```

**收益**：3 张表的「add + reorder」从 6 次 creator 调用（~25s）降到 1 次（~5s）。

### 11. 自定义字典用 batchAddDictWithItems 一次搞定

> **历史教训**：早期用 `dict/add` + `dictItem/add` 逐条写入，遇到 `result=null` 时还会 TypeError 崩溃触发重跑。实际上 JeecgBoot 有批量接口，1 次 HTTP 完成所有字典+items，且内置"已存在跳过"逻辑。

**接口**：`POST /sys/dict/batchAddDictWithItems`

- 请求体：`{"dictList": [{...}, {...}]}`，每项含 `sysDictItemList`
- 已存在的字典编码自动跳过（服务端 catch 唯一约束异常），不影响其他字典
- 返回：`{"successCount": N, "failureCount": M, "failureList": [...]}`

```python
def ensure_dicts_batch(base, token, dicts):
    """
    dicts = [
      {"dictName":"订单类型","dictCode":"order_type","description":"...","items":[("国内","1",1),...]},
      ...
    ]
    """
    payload = {"dictList": [
        {
            "dictName": d["dictName"],
            "dictCode": d["dictCode"],
            "description": d.get("description", ""),
            "sysDictItemList": [
                {"itemText": t, "itemValue": v, "sortOrder": o, "status": 1}
                for t, v, o in d["items"]
            ]
        }
        for d in dicts
    ]}
    H = {'X-Access-Token': token, 'Content-Type': 'application/json'}
    body = json.dumps(payload, ensure_ascii=False).encode('utf-8')
    req = urllib.request.Request(base + '/sys/dict/batchAddDictWithItems', data=body, headers=H, method='POST')
    r = json.loads(urllib.request.urlopen(req, timeout=15).read().decode('utf-8'))
      # ⚠️ 全部已存在时接口返回 success=false + code 500，需判断 failList 区分"真失败"和"已存在跳过"
    result = r.get('result') or {}
    fail_list = result.get('failList') or []
    real_fails = [f for f in fail_list if '已经存在' not in f.get('errorMsg', '')]
    if real_fails:
        raise RuntimeError(f'字典创建失败: {real_fails}')
    skip_count = len([f for f in fail_list if '已经存在' in f.get('errorMsg', '')])
    print(f'  字典批量: 新建={result.get("successCount",0)}, 已存在跳过={skip_count}')
    return r

# 调用示例（N 个字典 1 次 HTTP）
ensure_dicts_batch(BASE, TOKEN, [
    {"dictName":"订单类型",  "dictCode":"order_type",    "description":"国内/国际",    "items":[("国内","1",1),("国际","2",2)]},
    {"dictName":"运输方式",  "dictCode":"transport_mode", "description":"运输方式(全量)","items":[("陆运","land",1),("铁运","rail",2),("空运","air",3),("海运","sea",4)]},
])
```

> ⚠️ **接口行为陷阱（实测）**：全部字典已存在时，接口返回 `success=false` + `code=500`，而不是静默跳过。
> 判断方式：遍历 `result.failList`，`errorMsg` 含"字典编码已经存在"的视为正常跳过，其余才是真失败。

**收益**：N 个字典 + M 个 items 从 `1+N×M` 次 HTTP → **1 次 HTTP**，无 result=null 防御问题。

### 5. 建表遇到「数据库表 [xxx] 已存在」时的处理

错误 `数据库表[xxx]已存在,请从数据库导入表单` 表示：**物理 DB 表残留，但 Online 配置不存在**（通常是之前创建后被手动删了 Online 头）。

> **`onlform_creator.py` 和 `onlform_pipeline.py` 已内置自动加后缀重试**，并自动更新关联子表的 `mainTable` 引用。主表冲突无需手动干预，脚本会自动完成。执行后在汇总输出中确认实际使用的表名即可。

1. **首选：换表名**（在 config 中指定新名称）——最快，避免污染现有物理表。
2. **次选：导入**：`GET /online/cgform/head/transTables/{tableName}` 把物理表导入为 Online 配置，再用 `action=edit` 调整字段。
3. **慎用：删除物理表**（通过 DB 直连 DROP TABLE）——只在确认无数据且用户明确要求时做。

> **主子表场景特别注意**：主表建失败且脚本未自动重试时，子表如果已创建会成为"孤儿"。此时先 `DELETE /online/cgform/head/delete?id={孤儿子表headId}` 删干净，再整体重建。

## 主数据复用规则

> **重要：** 配置表单字段的字典、用户选择、部门选择等数据源时，必须遵循"先查后建"原则。
> 使用 `jeecg-system` skill 的 `system_utils.py` 查询和管理主数据。

## 临时配置文件规则（强制）

所有传给脚本的 `--config ` 必须写到**系统临时目录**，由 OS 自动清理；skill 和脚本都不主动 `rm`。

```python
import tempfile, os, json
config_path = os.path.join(tempfile.gettempdir(), 'onl__.json')
with open(config_path, 'w', encoding='utf-8') as f:
    json.dump(cfg, f, ensure_ascii=False, indent=2)
```

`tempfile.gettempdir()` 自动适配：Windows `%TEMP%` / Linux `/tmp` / macOS `/var/folders/.../T`（注意 macOS 不是 `/tmp`）。命名建议带表名+步骤前缀（如 `onl_sk_audit_create.json`）便于排错。

**❌ 禁止：**
- 写到 `/tmp/` 或当前工作目录（污染 skill / 用户项目）
- 硬编码 `/tmp` / `C:\Temp`（不跨平台）
- 每步完成后主动 `rm` / `Remove-Item`（OS 会清，多余 tool call）
- **主动 `os.path.exists()` 检查**（自身就是一次 tool call）

**临时文件可能被 OS 异步清理**，但**乐观调用 + 报错再补救**：仅当脚本返回 `FileNotFoundError` / `配置文件不存在` 时，用相同内容重写后重试，不要换路径或去 skill 目录找。

## 交互流程

### Step 0: 判断操作类型

| 用户意图关键词 | 操作类型 | 使用脚本 |
|---------------|---------|---------|
| 创建/新建/做一个/生成 | 新增表单 → Step 1A | `onlform_creator.py` |
| 加字段/增加字段/修改字段/删除字段 | 编辑表单 → Step 1B | `onlform_creator.py` |
| 集成积木/关联打印/打印报表 | 积木报表集成 → Step 8 | `onlform_jimureport.py` |
| JS增强/按钮/增强功能 | 增强配置 → Step 9 | `onlform_enhance.py` |
| 权限/授权/数据规则 | 权限配置 → Step 10 | `onlform_auth.py` |
| 造数据/插入/查询/导出 | 数据操作 → Step 11 | `onlform_data.py` |
| 挂载菜单/加到菜单/预览地址/缓存路由 | 菜单挂载 → Step 12 | `onlform_menu.py` |

### Step 1A: 新增表单 — 解析需求

从用户描述中提取：

| 信息 | 默认值 | 示例 |
|------|--------|------|
| 表名 (tableName) | 自动生成 snake_case | `leave_application` |
| 表描述 (tableTxt) | 用户指定 | "请假申请" |
| 表类型 (tableType) | 1=单表 | 提到"主子表"→2/3，提到"树形"→1+isTree |
| 字段列表 | 从描述中解析 | 姓名(必填)、请假天

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [jeecgboot](https://github.com/jeecgboot)
- **Source:** [jeecgboot/skills](https://github.com/jeecgboot/skills)
- **License:** Apache-2.0
- **Homepage:** https://jeecg.com

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jeecgboot-skills-jeecg-onlform
- Seller: https://agentstack.voostack.com/s/jeecgboot
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
