Install
$ agentstack add skill-jeecgboot-skills-uniapp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
JeecgBoot UniApp3 移动端 CRUD 代码生成器
将自然语言需求或已有后端接口信息转换为 JeecgBoot UniApp3 移动端全套 CRUD 代码(列表页 + 表单页 + 数据定义),支持单表 CRUD、一对多主子表、树表等场景。
> 项目路径: `(动态,使用前需向用户确认,见 Step 0) > **后端模板参考:** ` 同级目录下的后端项目(如有)
前置知识
生成代码前必须理解以下项目核心约定,具体细节见 references/ 目录下的参考文件:
| 参考文件 | 内容 | |---------|------| | references/project-architecture.md | 项目结构、目录约定、页面注册机制 | | references/component-patterns.md | 组件库用法、表单控件映射、在线组件清单 | | references/code-templates.md | 三个核心前端文件的完整模板和变量说明 |
交互流程
Step 0: 确认项目路径
在执行任何操作之前,必须先询问用户以下信息(一次性展示,用户说"确认"使用默认值):
| 配置项 | 默认值 | 说明 | |--------|--------|------| | UniApp3 项目根目录 | —(必填) | 如 D:\projects\jeecgboot-uniapp3 |
用户回复后,记为:
- `` — 前端项目根目录
> 路径记忆规则: 同一对话中用户提供一次后,后续步骤直接复用,不再重复询问。
Step 1: 判断生成场景
场景 A — 已有后端接口(用户给了表名/实体名/接口路径):
- 向用户确认后端 API 路径前缀(如
/test/demo) - 从用户信息中提取:实体名(如
Demo)、包路径(如test)、字段列表 - 如果用户能提供后端 Entity 类,从中解析全部字段及类型
- 根据字段类型自动推导前端控件
- 只生成前端代码
场景 B — 从需求描述生成前端:
- 从用户描述中提取:模块名、功能描述、字段列表
- 用"智能控件推导"规则推导每个字段的
classType - 只生成前端 3 个文件(List.vue / Form.vue / Data.ts)
Step 2: 确认生成信息
一次性展示所有选项及默认值,用户说"确认"即可全部采用:
| 配置项 | 默认值 | 说明 | |--------|--------|------| | 实体名 | 从需求推导(PascalCase) | 如 BizGoods | | 功能描述 | 从需求推导 | 导航栏标题,如 "商品管理" | | 页面目录 | /src/pages-home/{模块名}/ | 生成文件的存放目录 | | API路径前缀 | /{模块包路径}/{实体名首字母小写} | 如 /biz/bizGoods | | 列表展示字段 | 前3个非id非系统字段 | 列表卡片上显示的字段 |
Step 3: 生成代码文件
前端文件
每个单表 CRUD 模块生成 3 个文件,路径基于 ``:
/src/pages-home/{模块名}/
├── {EntityName}List.vue # 列表页(分页 + 滑动删除 + 新增入口)
├── {EntityName}Form.vue # 表单页(新增/编辑 + 表单校验 + 提交)
└── {EntityName}Data.ts # 列表字段列定义
Step 4: 注册页面路由
在 /src/pages.json 的 subPackages 中注册新页面(如果目标目录已是 subPackage 则追加 pages,否则新增 subPackage)。
Step 5: 输出生成摘要
展示生成的文件清单、页面路由配置、后续操作说明。
字段控件类型推导规则
根据字段信息推导 classType(决定表单使用哪个组件):
| 字段特征 | classType | 表单组件 | |----------|-----------|----------| | 名称含"图片/头像/照片/logo" | image | ` | | 名称含"文件/附件/简历" | file | | | 名称含"日期" 且无"时间" | date | | | 名称含"时间" 或 "datetime" | datetime | | | 名称含"开关/启用/是否" | switch | | | 有字典值(枚举选项 | | 有字典值(枚举选项 > 5个) | list | ` | | 名称含"多选" 或需多选字典 | checkbox | | | 名称含"备注/描述/内容/简介" | textarea | | | 名称含"密码" | password | | | 名称含"省市区/地址" | pca | | | 名称含"部门" | seldepart | | | 名称含"用户/人员/负责人" | seluser | | | 名称含"分类" 且有树结构 | cat_tree | | | DB类型为 int/long/double/BigDecimal | 数字输入 | | | 默认(字符串类型) | 文本输入 | ` |
字段校验规则推导
| 场景 | 校验规则 | |------|----------| | 必填字段(nullable=N) | { required: true, message: '请输入${comment}!' } | | 手机号 | { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!' } | | 邮箱 | { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}\|)$/, message: '请输入正确的电子邮件!' } | | 网址 | { pattern: /^((ht\|f)tps?):\/\/.../, message: '请输入正确的网址!' } | | 数字 | { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!' } | | 整数 | { pattern: /^-?\d+$/, message: '请输入整数!' } | | 金额 | { pattern: /^(([1-9][0-9]*)\|([0]\.\d{0,2}\|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!' } |
生成代码的核心规范
1. 列表页({EntityName}List.vue)规范
关键特征:
- 使用 标签声明页面路由信息(layout、style、navigationBarTitleText)
- 使用 包裹,设置 navTitle 和 backRouteName
- 使用 z-paging 实现分页加载
- 使用 wd-swipe-action 实现左滑删除
- 使用 usePageList hook 管理列表数据加载
- 引入 {EntityName}Data.ts 的 columns 定义
- 列表卡片默认展示前3个字段
- 固定定位的"+"按钮用于新增
- uni.$on('refreshList') 监听表单提交后的列表刷新
详细模板见 references/code-templates.md 的"列表页模板"章节。
2. 表单页({EntityName}Form.vue)规范
关键特征:
- 使用 标签声明页面路由信息
- 使用 包裹,navTitle 动态切换"新增/编辑"
- 使用 wd-form + wd-cell-group 组织表单
- 通过 onLoad 获取 route params 中的 dataId 判断新增/编辑
- 编辑时调用 queryById 接口加载数据
- 表单数据用 reactive({}) 定义
- 提交时先 form.validate(),再根据 dataId 调用 add 或 edit 接口
- 提交成功后 uni.$emit('refreshList') 通知列表刷新,然后 router.back()
- 根据字段 classType 渲染对应组件(见组件映射表)
- 支持唯一性校验(调用 duplicateCheck API)
- label 超过4个字符时自动截断(get4Label)
详细模板见 references/code-templates.md 的"表单页模板"章节。
3. 数据定义({EntityName}Data.ts)规范
关键特征:
- 导出 columns 数组,定义列表显示的字段
- 每个字段包含 title(显示名)和 dataIndex(字段名)
- 字典类型字段的 dataIndex 使用 `${fieldName}_dictText` 后缀
- 图片类型字段添加 customRender: render.renderImage
- 开关类型字段添加 customRender 渲染是/否文本
- Blob 类型字段的 dataIndex 使用 `${fieldName}String` 后缀
详细模板见 references/code-templates.md 的"数据定义模板"章节。
4. 页面路由注册
生成的页面需要在 src/pages.json 的 subPackages 中注册。使用 `` 标签方式(uni-pages 插件自动解析),或手动在 pages.json 中添加。
`` 标签格式(推荐,写在 .vue 文件顶部):
{
layout: 'default',
style: {
navigationBarTitleText: '功能标题',
navigationStyle: 'custom',
},
}
如果目标目录不在已有 subPackages 中,需要手动在 pages.json 添加:
{
"root": "pages-home",
"pages": [
{
"path": "模块目录/EntityNameList",
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "功能标题",
"navigationStyle": "custom"
}
},
{
"path": "模块目录/EntityNameForm",
"type": "page",
"layout": "default",
"style": {
"navigationBarTitleText": "功能标题",
"navigationStyle": "custom"
}
}
]
}
API 约定
JeecgBoot 后端标准 CRUD 接口路径:
| 操作 | 方法 | 路径 | |------|------|------| | 分页列表 | GET | /{packagePath}/{entityName}/list | | 查询单条 | GET | /{packagePath}/{entityName}/queryById?id=xxx | | 新增 | POST | /{packagePath}/{entityName}/add | | 编辑 | POST | /{packagePath}/{entityName}/edit | | 删除 | DELETE | /{packagePath}/{entityName}/delete?id=xxx | | 唯一性校验 | GET | /sys/duplicate/check |
HTTP 工具使用 @/utils/http 的 http 对象,支持 http.get() / http.post() / http.delete() / http.put() 方法。
导入约定
列表页必须导入
import { ref, onMounted, computed } from 'vue'
import { http } from '@/utils/http'
import usePageList from '@/hooks/usePageList'
import { columns } from './{EntityName}Data'
表单页必须导入
import { onLoad } from '@dcloudio/uni-app'
import { http } from '@/utils/http'
import { useToast } from 'wot-design-uni'
import { useRouter } from '@/plugin/uni-mini-router'
import { ref, onMounted, computed, reactive } from 'vue'
import { duplicateCheck } from '@/service/api'
根据字段 classType 按需导入的组件
| classType | 导入语句 | |-----------|----------| | image | import OnlineImage from '@/components/online/view/online-image.vue' | | file | import OnlineFileCustom from '@/components/online/view/online-file-custom.vue' | | datetime / time | ` 组件(easycom 自动注册,位于 @/components/DateTime/DateTime.vue) | | date | import OnlineDate from '@/components/online/view/online-date.vue' | | list / selsearch | import OnlineSelect from '@/components/online/view/online-select.vue' | | checkbox | import OnlineCheckbox from '@/components/online/view/online-checkbox.vue' | | radio | import OnlineRadio from '@/components/online/view/online-radio.vue' | | listmulti | import OnlineMulti from '@/components/online/view/online-multi.vue' | | textarea | 无需导入(使用 wot-design-uni 的 ,easycom 自动注册) | | password | 无需导入(使用 ,easycom 自动注册) | | pca | import OnlinePca from '@/components/online/view/online-pca.vue' | | seldepart | import SelectDept from '@/components/SelectDept/SelectDept.vue' | | seluser | import SelectUser from '@/components/SelectUser/SelectUser.vue' | | popupdict | 组件(easycom 自动注册,位于 @/components/PopupDict/PopupDict.vue) | | popup | 组件(easycom 自动注册,位于 @/components/Popup/Popup.vue) | | linktable | import OnlinePopupLinkRecord from '@/components/online/view/online-popup-link-record.vue' | | cattree | 组件(easycom 自动注册,位于 @/components/CategorySelect/CategorySelect.vue) | | seltree | 组件(easycom 自动注册,位于 @/components/TreeSelect/TreeSelect.vue) | | switch | 无需导入(使用 `,easycom 自动注册) |
> easycom 说明: 位于 src/components/ 下且目录名与组件名一致的组件会被 easycom 自动注册,无需手动 import。 > wd-* 前缀的组件由 wot-design-uni 提供,也通过 easycom 自动注册。 > online-* 前缀的组件位于 src/components/online/view/,不符合 easycom 规则,必须手动 import。
一对多(主子表)场景
当前后端代码生成模板仅有单表模板,一对多场景需手动编写。核心模式:
- 列表页:与单表列表页相同,展示主表数据
- 表单页:在主表表单下方增加 Tab 切换子表,每个子表用独立的列表+新增/编辑弹窗
- 子表数据:使用主表 ID 作为外键查询,新增时传入主表 ID
这是高级场景,参考 references/advanced-patterns.md(如需要时创建)。
树表场景
当前后端代码生成模板无树表 uniapp3 模板。树表移动端通常采用:
- 使用 `` 组件展示树形数据
- 列表页改为树形选择 + 子节点列表的组合
- 表单页增加"上级节点"选择器
这是高级场景,参考 references/advanced-patterns.md(如需要时创建)。
⛔ 表单属性铁律(高频翻车点)
> wd-input / wd-textarea 等表单组件的 name 和 prop 属性值必须直接写字段名,禁止用单引号包裹。 > > ``vue > > > > > > ` > > **Why:** wot-design-uni 的 wd-form 校验时用 name/prop 的字面值去匹配 :rules 中的规则和 myFormData 的键。若写成 name="'productName'",传入的是带单引号的字符串字面量 'productName',而不是 productName,导致校验规则永远匹配不上,表单即使有值也提示必填错误。 > > **How to apply:** 生成每一个表单字段时,name= 和 prop=` 后面的双引号内只写驼峰字段名本身,不加任何额外引号或花括号。
生成检查清单
生成代码后自查:
- [ ] 所有
.vue文件顶部有 `` 标签 - [ ]
defineOptions中的name与文件名一致 - [ ] 列表页的
usePageList参数路径正确(与后端 API 匹配) - [ ] 表单页的
backRouteName指向列表页名称 - [ ] 列表页的
handleAdd跳转到{EntityName}Form - [ ] 表单页的
add/edit/queryByIdAPI 路径正确 - [ ] 字典类型字段传入了正确的
dict属性值 - [ ] 必填字段设置了
:required="true"和rules - [ ] 表单页导入了所有用到的 online 组件
- [ ]
{EntityName}Data.ts中字典字段的dataIndex使用了_dictText后缀 - [ ] pages.json 中已注册新页面(或 `` 标签能被 uni-pages 插件识别)
- [ ] ⛔ 所有
name=和prop=均为裸字段名,无多余单引号(如name="fieldName",而非name="'fieldName'")
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jeecgboot
- Source: jeecgboot/skills
- License: Apache-2.0
- Homepage: https://jeecg.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.