ワンクリックで
expert-ruoyi
若依(RuoYi)框架开发专家,精通项目搭建、代码生成和架构优化。当用户涉及若依框架开发、权限配置或菜单路由配置时自动触发。支持中文触发:若依框架、RuoYi、SpringBoot后台、权限配置。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
若依(RuoYi)框架开发专家,精通项目搭建、代码生成和架构优化。当用户涉及若依框架开发、权限配置或菜单路由配置时自动触发。支持中文触发:若依框架、RuoYi、SpringBoot后台、权限配置。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
"PDD框架下的业务分析Skill,运用专业方法论进行需求分析和业务建模。当用户输入/analyze、/audit、/doc等命令,或需要对业务流程、管理制度、Excel表单进行专业分析时触发。支持中文触发:业务分析、需求分析、需求建模、5W1H分析、MECE、流程分析。"
"PDD熵减智能体,持续监控和偿还技术债务,防止系统腐化。当用户需要代码清理、文档更新、技术债务管理、架构对齐、熵减、垃圾回收、清理技术债务时自动触发。即使用户只说'熵减'、'清理技术债务'或'垃圾回收',也应触发此Skill。支持中文触发:熵减、技术债务、代码清理、文档更新、架构对齐、垃圾回收。"
根据开发规格实现功能点代码的核心Skill。当用户想要开始编码实现、根据规格文档生成代码、实现功能点时调用此Skill。此Skill会自动调用pdd-template-engine生成基础代码框架,然后由software-engineer补充业务逻辑。即使只有规格文档没有明确说'实现',只要涉及代码生成、功能开发,都应触发此Skill。支持中文触发:实现功能点、编码实现、开始编码、功能开发、代码实现、PDD实现。
PRD驱动开发的主入口Skill,协调整个开发流程。当用户想要基于PRD文档进行功能开发、从需求文档生成代码、执行PDD方法论流程、开发业务模块、实现完整功能、'搞个功能'、'资产转让'、'国有产权转让'、'帮我搞个资产转让的功能'时必须调用此Skill。即使用户没有明确说'使用PDD',只要涉及PRD文档、需求文档、功能点开发、规格文档、模块开发、根据文档开发、业务功能实现、'开发ZCCZ'、'我想开发'、'搞个功能'等场景,都应触发此Skill。此Skill会自动协调pdd-ba、pdd-extract-features、pdd-generate-spec、pdd-implement-feature等子Skill完成从需求分析到代码交付的完整流程。注意:单一接口设计、调试问题、文档查询等场景不应触发此Skill。支持中文触发:PRD驱动开发、PDD开发、功能开发、启动PDD。
"交通事故责任评估与判定专业技能。当用户需要交通事故责任分析、事故现场照片评估、交通法规咨询、事故责任划分、法律依据查询时触发此技能。适用于车辆碰撞事故、行人事故、非机动车事故等各类道路交通事故的责任认定场景。无论用户使用'交通事故'、'车祸'、'责任判定'、'交通法规'、'事故定责'等何种表述,只要涉及交通事故评估或责任认定,均应调用此技能。支持中文触发:交通事故、车祸、责任判定、交通法规、事故定责、责任划分、事故评估、追尾、碰撞、违章、赔偿。"
自动化重构专家技能,将收集到的质量改进任务转化为具体的代码操作。当用户需要代码重构、消除重复、简化复杂度时自动触发。即使用户只说'重构代码'、'消除重复'或'简化代码',也应触发此Skill。支持中文触发:重构代码、消除重复、简化复杂度、自动重构、代码重构、PDD重构。
| name | expert-ruoyi |
| description | 若依(RuoYi)框架开发专家,精通项目搭建、代码生成和架构优化。当用户涉及若依框架开发、权限配置或菜单路由配置时自动触发。支持中文触发:若依框架、RuoYi、SpringBoot后台、权限配置。 |
核心能力:
- 项目搭建: SpringBoot + MyBatis + Shiro/Security
- 代码生成: CRUD代码自动生成
- 权限管理: 菜单权限、按钮权限、数据权限
- 动态路由: 基于sys_menu表的动态路由
- 最佳实践: 若依框架开发规范
适用场景:
- 新功能开发遇到权限问题
- 菜单配置后页面404
- 代码生成器使用
- 权限注解不生效
- 数据范围过滤异常
| 协作技能 | 协作方式 | 传入数据 | 期望输出 |
|---|---|---|---|
| pdd-implement-feature | Consultation | 若依技术问题 | 解决方案 |
| pdd-code-reviewer | Reference | 发现若依问题 | 框架最佳实践 |
| software-engineer | Delegation | 代码实现任务 | 符合规范的代码 |
问题类型:
路由问题:
- 页面404
- 菜单不显示
- 路由404
权限问题:
- 权限注解不生效
- 按钮不显示
- 数据范围错误
代码生成问题:
- 生成代码报错
- 生成后需要调整
配置问题:
- 数据库配置
- Redis缓存
- 会话管理
问题: 点击菜单后页面404
诊断流程:
1. 检查 sys_menu 表配置
SELECT * FROM sys_menu WHERE menu_name = 'XXX';
2. 检查 component 路径
- 路径相对于 src/views
- 文件必须存在
3. 检查 visible 字段
- '0' = 显示菜单
- '1' = 隐藏菜单
4. 检查父菜单是否存在
SELECT * FROM sys_menu WHERE menu_id = parent_id;
5. 检查角色权限分配
SELECT * FROM sys_role_menu WHERE menu_id = menu_id;
问题: @PreAuthorize 注解不生效
诊断流程:
1. 检查注解是否正确
@PreAuthorize("@ss.hasPermi('xxx:xxx:xxx')")
2. 检查 sys_menu 表中权限标识符
- perms 字段必须与注解中一致
3. 检查角色菜单分配
SELECT * FROM sys_role_menu WHERE menu_id IN
(SELECT menu_id FROM sys_menu WHERE perms = 'xxx:xxx:xxx');
4. 检查用户角色
SELECT * FROM sys_user_role WHERE user_id = user_id;
5. 清除Redis缓存
FLUSHDB
-- 目录类型 (M)
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms, icon)
VALUES ('资产管理', 0, 1, 'asset', NULL, 'M', '0', NULL, 'asset');
-- 菜单类型 (C) - 列表页
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms, icon)
VALUES ('资产列表', parent_id, 1, 'list', 'asset/index', 'C', '0', 'asset:list:list', 'list');
-- 菜单类型 (C) - 隐藏页面 (新增/编辑/详情)
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms)
VALUES ('资产新增', parent_id, 10, 'add', 'asset/form', 'C', '1', 'asset:list:add');
-- 按钮类型 (F) - 权限控制
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms)
VALUES ('资产新增按钮', menu_id, 1, '', '', 'F', '0', 'asset:list:add');
// Controller 层
@RestController
@RequestMapping("/asset/list")
public class AssetListController {
// 列表查询 - 需要 list 权限
@PreAuthorize("@ss.hasPermi('asset:list:list')")
@GetMapping
public AjaxResult list() { }
// 新增 - 需要 add 权限
@PreAuthorize("@ss.hasPermi('asset:list:add')")
@PostMapping
public AjaxResult add() { }
// 修改 - 需要 edit 权限
@PreAuthorize("@ss.hasPermi('asset:list:edit')")
@PutMapping
public AjaxResult edit() { }
// 删除 - 需要 remove 权限
@PreAuthorize("@ss.hasPermi('asset:list:remove')")
@DeleteMapping
public AjaxResult remove() { }
// 导出 - 需要 export 权限
@PreAuthorize("@ss.hasPermi('asset:list:export')")
@GetMapping("/export")
public void export() { }
}
// Service 层
public interface IAssetService {
// 添加 @DataScope 注解
@DataScope(deptAlias = "d", userAlias = "u")
List<Asset> selectAssetList(Asset asset);
}
// Mapper XML
<select id="selectAssetList" resultMap="AssetResult">
SELECT a.*, d.dept_name
FROM asset a
LEFT JOIN sys_dept d ON a.dept_id = d.dept_id
LEFT JOIN sys_user u ON a.create_by = u.user_name
WHERE a.del_flag = '0'
${params.dataScope}
</select>
| 调整项 | 原因 | 优先级 |
|---|---|---|
| 添加 @Validated 注解 | 参数校验 | P0 |
| 添加 @DataScope 注解 | 数据权限 | P0 |
| 添加 @Xss 注解 | XSS防护 | P0 |
| 配置 sys_menu 表 | 菜单路由 | P0 |
| 分配角色菜单权限 | 权限生效 | P0 |
| 清除Redis缓存 | 刷新权限缓存 | P0 |
// 调整前 (生成器默认)
@PostMapping
public AjaxResult add(Asset asset) {
return AjaxResult.success(assetService.insertAsset(asset));
}
// 调整后 (添加参数校验)
@PreAuthorize("@ss.hasPermi('asset:list:add')")
@Log(title = "资产管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody Asset asset) {
return AjaxResult.success(assetService.insertAsset(asset));
}
// 实体类添加 XSS 防护
@Excel(name = "资产名称")
@Xss
private String assetName;
// 列表查询添加数据权限
@DataScope(deptAlias = "d", userAlias = "u")
List<Asset> selectAssetList(Asset asset);
问题: 点击菜单后页面404
排查步骤:
-- Step 1: 检查菜单是否存在
SELECT * FROM sys_menu WHERE menu_name LIKE '%XXX%';
-- Step 2: 检查 component 路径是否正确
-- 路径格式: module/path (相对于 src/views)
-- 例如: equity-transfer/apply/index
-- Step 3: 检查文件是否存在
-- src/views/equity-transfer/apply/index.vue
-- Step 4: 检查父菜单
SELECT * FROM sys_menu WHERE menu_id = parent_id;
-- Step 5: 检查角色权限
SELECT * FROM sys_role_menu WHERE menu_id = menu_id;
解决方案:
问题: @PreAuthorize 注解不生效,所有用户都能访问
排查步骤:
-- Step 1: 检查权限标识符是否匹配
SELECT perms FROM sys_menu WHERE menu_name = 'XXX';
-- Step 2: 检查角色菜单分配
SELECT r.role_name, m.menu_name
FROM sys_role_menu rm
JOIN sys_menu m ON rm.menu_id = m.menu_id
WHERE m.perms = 'xxx:xxx:xxx';
-- Step 3: 检查用户角色
SELECT u.user_name, r.role_name
FROM sys_user_role ur
JOIN sys_role r ON ur.role_id = r.role_id
WHERE ur.user_id = user_id;
解决方案:
问题: 用户能看到不属于自己部门的数据
排查步骤:
-- Step 1: 检查用户所属部门
SELECT u.user_name, d.dept_name, d.dept_id
FROM sys_user u
JOIN sys_dept d ON u.dept_id = d.dept_id
WHERE u.user_id = user_id;
-- Step 2: 检查数据权限配置
-- 查看 Mapper XML 是否正确配置了 ${params.dataScope}
-- Step 3: 检查 @DataScope 注解
-- 确认 deptAlias 和 userAlias 与 SQL 别名一致
解决方案:
问题: 用户有权限但按钮不显示
排查步骤:
// 检查前端是否有 v-hasPermi 指令
<el-button v-hasPermi="['asset:list:add']">
新增
</el-button>
// 检查权限标识符是否一致
// 前端: asset:list:add
// 后端: @PreAuthorize("@ss.hasPermi('asset:list:add')")
// 数据库: sys_menu.perms = 'asset:list:add'
解决方案:
新增功能检查项:
- [ ] sys_menu 表配置完整 (目录/菜单/按钮)
- [ ] component 路径正确
- [ ] 权限标识符唯一且规范
- [ ] 角色菜单权限已分配
- [ ] @PreAuthorize 注解配置正确
- [ ] @DataScope 注解配置正确 (如需要)
- [ ] @Validated 参数校验添加
- [ ] @Xss 文本字段防护添加
- [ ] @Log 操作日志添加
- [ ] Redis缓存已清除
- [ ] 用户重新登录
// 标准API命名
export function listAsset(query) {
return request({ url: '/asset/list', method: 'get', params: query });
}
export function getAsset(assetId) {
return request({ url: '/asset/' + assetId, method: 'get' });
}
export function addAsset(data) {
return request({ url: '/asset', method: 'post', data });
}
export function updateAsset(data) {
return request({ url: '/asset', method: 'put', data });
}
export function delAsset(assetId) {
return request({ url: '/asset/' + assetId, method: 'delete' });
}
export function exportAsset(query) {
return request({ url: '/asset/export', method: 'get', params: query });
}
当pdd-generate-spec为若依项目生成开发规格时,expert-ruoyi应提供以下模板参考:
| 章节 | 内容 | 若依特有要求 |
|---|---|---|
| 数据模型 | 实体类定义 | 必须包含BaseEntity继承、@Data/@TableName注解 |
| 接口设计 | Controller/Service/Mapper | 必须包含@PreAuthorize权限注解、@Log操作日志 |
| 菜单配置 | sys_menu INSERT语句 | 必须包含目录(M)+菜单(C)+按钮(F)三层配置 |
| 权限矩阵 | 权限标识符列表 | 格式:模块:功能:操作(如asset:list:add) |
| 数据权限 | @DataScope配置 | 必须指定deptAlias和userAlias |
| 前端API | request封装 | 必须遵循listXxx/getXxx/addXxx/updateXxx/delXxx命名 |
## 数据模型
### {EntityName} 实体
- 继承: BaseEntity
- 注解: @Data, @TableName("{table_name}")
- 字段:
| 字段名 | 类型 | 注解 | 说明 |
|--------|------|------|------|
| {fieldName} | {type} | @Excel(name="{label}") | {desc} |
## 接口设计
### {EntityName}Controller
- 路径: @RequestMapping("/{module}/{feature}")
- 权限前缀: {module}:{feature}
| 方法 | 路径 | 权限标识 | 注解 |
|------|------|---------|------|
| list | GET / | {module}:{feature}:list | @PreAuthorize |
| getInfo | GET /{id} | {module}:{feature}:query | @PreAuthorize |
| add | POST / | {module}:{feature}:add | @PreAuthorize + @Log |
| edit | PUT / | {module}:{feature}:edit | @PreAuthorize + @Log |
| remove | DELETE /{ids} | {module}:{feature}:remove | @PreAuthorize + @Log |
## 菜单配置SQL
-- 目录(M)
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms, icon)
VALUES ('{菜单名}', 0, {排序}, '{path}', NULL, 'M', '0', NULL, '{icon}');
-- 菜单(C) - 列表页
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms)
VALUES ('{菜单名}列表', {parent_id}, 1, '{path}', '{module}/{feature}/index', 'C', '0', '{module}:{feature}:list');
-- 按钮(F) - 新增/修改/删除/导出
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, perms)
VALUES ('{菜单名}新增', {menu_id}, 1, '', '', 'F', '0', '{module}:{feature}:add');
完整模式定义:
config/bug-patterns.yaml(categories.ruoyi)
expert-ruoyi在提供解决方案时,必须主动检查并避免以下已知Bug模式:
| 模式编号 | 模式名称 | 典型表现 | 预防措施 |
|---|---|---|---|
| PATTERN-R001 | 权限注解缺失 | Controller方法缺少@PreAuthorize | 每个接口方法必须配置权限注解 |
| PATTERN-R002 | 菜单配置不完整 | 新增页面404/按钮不显示 | 所有页面(含隐藏页)必须配置sys_menu |
| PATTERN-R003 | 数据权限未配置 | 用户看到跨部门数据 | Service方法添加@DataScope注解 |
| PATTERN-R004 | Redis缓存未清除 | 权限修改后不生效 | 修改权限/菜单后必须清除Redis |
| PATTERN-R005 | 参数校验缺失 | @RequestBody参数无@Validated | 所有@RequestBody参数添加@Validated |
| PATTERN-R006 | XSS防护缺失 | 文本字段未添加@Xss | 所有String类型文本字段添加@Xss |
| PATTERN-R007 | 操作日志缺失 | 增删改操作无@Log | 所有CUD操作添加@Log注解 |
| PATTERN-R008 | API路径拼接断层 | 前端请求404 | 前端API路径=类级@RequestMapping+方法级@XXXMapping |
| PATTERN-R009 | 附件入参类型错误 | 参数解析异常 | 通用上传后用List接收URL,不用MultipartFile |
| PATTERN-R010 | 状态流转审批日志遗漏 | 审批历史缺记录 | 状态变更方法加@Transactional并同步插入审批记录 |
| PATTERN-R011 | 状态字典映射不完整 | 状态显示英文原文 | 新增状态值时全局搜索所有映射方法并同步 |
| PATTERN-R012 | MyBatis多参数@Param缺失 | 参数绑定异常 | 多参数Mapper方法每个参数加@Param |
检查原则: 每次提供若依相关建议时,必须对照以上12个模式逐一检查,确保建议的代码不会触犯已知模式。新增模式时只需修改 config/bug-patterns.yaml,无需修改此文件。
@RequestMapping + 方法 @XXXMapping// 后端: @RequestMapping("/evaluation/approval") + @GetMapping("/review/manage/detail/{id}")
// ❌ 错误: 遗漏类级路径
request({ url: '/review/manage/detail/' + id })
// ✅ 正确: 完整拼接
request({ url: '/evaluation/approval/review/manage/detail/' + id })
MultipartFile,适用于单文件简单上传/common/upload 获取 URL,业务接口统一接收 List<String>@RequestMapping + method @XXXMappingMultipartFile, for simple single-file uploads/common/upload to get URL first, business API receives List<String>this.$router.push() 跳转到详情/处理页this.$store.dispatch('tagsView/delView', this.$route) 关闭标签this.$router.back() 返回列表activated() 钩子,在 keep-alive 激活时刷新数据// 列表页 index.vue
activated() {
this.getList();
}
// 详情页 form.vue - 提交成功后
this.$store.dispatch('tagsView/delView', this.$route).then(() => {
this.$router.back();
});
getStatusLabel / getNodeLabel 等大段映射src/utils/constants.js 或使用若依字典管理 dict.type.xxxthis.$router.push() to navigate to detail/process pagethis.$store.dispatch('tagsView/delView', this.$route) to close tagthis.$router.back() to return to listactivated() hook to refresh data on keep-alive activationgetStatusLabel / getNodeLabel mappings in individual Vue componentssrc/utils/constants.js or use RuoYi dictionary management dict.type.xxxstatus 字段变更的操作,必须在同一事务中记录审批日志@Transactional 确保原子性// ❌ 错误: 通过推断获取状态
if (project.getApprovalRecords().size() >= requiredApprovals) {
// 推断为已通过
}
// ✅ 正确: 直接查询数据库状态字段
String status = projectMapper.selectStatusById(id);
if ("approved".equals(status)) { ... }
status field changes must record approval logs in the same transaction@Transactional to ensure atomicity本项目有特定的开发规范和历史经验,请在提供建议时优先参考:
| 文件 | 路径 | 内容 |
|---|---|---|
| 项目规则 | .trae/rules/project_rules.md | 目录结构、命名规范、开发规范、API命名规范 |
| 经验教训 | .trae/rules/lessons.md | 历史问题和解决方案,包含若依框架特定问题 |
| 文档 | 路径 | 内容 |
|---|---|---|
| 若依框架样式修改方案 | docs/plans/若依框架样式修改方案.md | 样式调整、主题配置、品牌一致性 |
在 .trae/rules/lessons.md 中记录了以下若依框架相关问题:
菜单路由配置问题 (2026-03-08)
API方法命名规范问题 (2026-03-08)
FP-ZCCZ1-001 Code Review实践 (2026-03-08)
项目特定检查项:
- [ ] 检查 lessons.md 中是否有相关问题的解决方案
- [ ] 遵循 project_rules.md 中的命名规范
- [ ] 参考现有代码的实现模式
- [ ] 确认数据库配置:mysql6.sqlpub.com:3311/asset_ruoyi
| 版本 | 日期 | 变更内容 |
|---|---|---|
| 3.2 | 2026-04-28 | 新增§7.7前后端契约规范、§7.8页面生命周期规范、§7.9状态流转规范;Bug模式库表扩充至12个(+R008~R012) |
| 3.1 | 2026-03-22 | 添加本地开发指南和文档引用 |
| 3.0 | 2026-03-21 | 标准化结构,添加诊断模式,增强协作指导 |
| 2.0 | 早期 | 完善问题解决方案 |
| 1.0 | 早期 | 初始版本 |