mirror of
https://gitee.com/xiaonuobase/snowy.git
synced 2026-10-06 06:52:58 +08:00
【底座】skill技能优化、规范化
This commit is contained in:
@@ -85,10 +85,12 @@ Grep pattern: "interface |: string|: number| as [A-Z]|el-" path: snowy-admin-we
|
||||
| W5 | Lombok | entity/param/result 无 `@Data`(用 @Getter @Setter) |
|
||||
| W6 | XML 命名空间 | mapping/*.xml 的 namespace 指向同包 Mapper 全限定名 |
|
||||
| W7 | 分页参数 | PageParam 含 current/size/sortField/sortOrder/searchKey |
|
||||
| W8 | Javadoc | 类与方法有中文 Javadoc 且含 @author @date |
|
||||
| W8 | Javadoc | 类与方法有中文 Javadoc 且含 @author @date;**仅对新增文件**追加判定:四行式(一行中文摘要 + 空行 + @author + @date),出现 `@param`/`@return`/`@throws`/`<p>`/摘要下补充说明段即报(存量多行风格不报,见 code-patterns 技能「Javadoc 格式规范」) |
|
||||
| W9 | 对象转换 | 用 BeanUtil.toBean/copyProperties(出现 MapstructUtils/MapStruct = 错) |
|
||||
| W10 | 前端 api js | default export 对象;URL 前缀 `/{插件}/{域}/`;index.vue 用 s-table + loadData 函数模式 |
|
||||
| W11 | 按钮权限 | hasPerm 码为驼峰式且与菜单 SQL 的 BUTTON code 一致 |
|
||||
| W11b | 前端注释一行制 | **仅新增文件**:每处注释不超过一行,无连续 `//` 段落、无 JSDoc @param/@returns、无注释掉的废代码(见 frontend-pc 技能「注释规范」) |
|
||||
| W11c | SFC 块顺序 | .vue 顶级块顺序为 template → script → style,首个标签必须是 `<template`;script 带 `name=`(存量 script 前置文件不报) |
|
||||
| W12 | 命名前缀 | 类名前缀 = 插件缩写(Biz/Sys/Dev/Gen/Auth/Client/Mobile) |
|
||||
|
||||
# 建议级(提示即可)
|
||||
|
||||
@@ -36,7 +36,7 @@ description: 代码规范检查(后端 + 前端,三级清单)
|
||||
| W3 | 操作日志 | 写接口有 `@CommonLog(` |
|
||||
| W4 | checkSqlInjection | `new QueryWrapper` 后接 `.checkSqlInjection()` |
|
||||
| W5 | Lombok | entity/param 无 `@Data` |
|
||||
| W6 | Javadoc | 类头含 `@author` 与 `@date`、中文注释 |
|
||||
| W6 | Javadoc | 类头含 `@author` 与 `@date`、中文注释;**仅新增文件**再查四行式(一行中文摘要 + @author + @date),出现 `@param`/`@return`/`<p>`/多行说明段即报(存量不报) |
|
||||
| W7 | 主键 | `@TableId` 字段为 String |
|
||||
| W8 | PageParam | 含 current/size/sortField/sortOrder/searchKey |
|
||||
| W9 | 命名前缀 | biz 下类名 Biz 前缀 |
|
||||
@@ -51,6 +51,8 @@ description: 代码规范检查(后端 + 前端,三级清单)
|
||||
| F4 | s-table 模式 | index.vue 有 `:data="loadData"` 函数模式 |
|
||||
| F5 | defineExpose | form.vue 有 `defineExpose({ onOpen })` |
|
||||
| F6 | 权限码 | hasPerm 值为驼峰式 |
|
||||
| F7 | 注释一行制 | **仅新增文件**:无连续 2 行以上 `//` 段落、无 JSDoc `@param`/`@returns`、无注释掉的废代码(存量不报) |
|
||||
| F8 | SFC 块顺序 | .vue 首个顶级标签必须是 `<template`,顺序 template → script → style;script 带 `name=` |
|
||||
|
||||
## 执行方式
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ description: 元技能——教 AI 如何为本项目新增一个符合规范的
|
||||
## 流程(5 步)
|
||||
|
||||
1. **定边界**:新技能解决什么问题?与现有 26 个技能是否重叠?(重叠就合并进去,不新建)
|
||||
2. **核实事实**:技能里的每条规范、每个代码片段、每个参考路径,**必须先 Read 真实代码核实**,禁止凭模型先验写(本项目与 RuoYi 系大量反向,先验会写反)
|
||||
2. **核实事实**:技能里的每条规范、每个代码片段、每个参考路径,**必须先 Read 真实代码核实**,禁止凭模型先验写(本项目与同类快速开发框架大量反向,先验会写反)
|
||||
3. **写文件**:`.claude/skills/{name}/SKILL.md`,格式见下
|
||||
4. **注册**:更新 `.claude/hooks/skill-forced-eval.js` 里的技能清单(加一行)
|
||||
5. **验证**:参考路径 100% 存在;触发词演练(3 条该命中 + 2 条不该命中)
|
||||
@@ -65,7 +65,7 @@ description: 一句话定位。触发场景:1) ... 2) ... 3) ...。触发词
|
||||
|
||||
1. **写完忘注册 hook** → 技能永远不被激活
|
||||
2. **触发词太宽泛**(如"开发"、"代码")→ 到处误触发;触发词要具体
|
||||
3. **代码虚构**——凭 RuoYi/通用 Spring 先验写代码模板,与本项目规范相反
|
||||
3. **代码虚构**——凭同类框架/通用 Spring 先验写代码模板,与本项目规范相反
|
||||
4. **参考实现带行号**——代码一改就失效
|
||||
5. **与现有技能范围重叠**——知识分散且互相矛盾
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public CommonResult<String> add(...) {...}
|
||||
|
||||
- **所有写操作接口必须加**(add/edit/delete/业务动作);查询接口不加
|
||||
- 日志由 `snowy-plugin-dev` 的 DevLogAop 切面落 DEV_LOG 表,可在 开发工具→日志 查看
|
||||
- ❌ `@Log(title=..., businessType=...)` 是 RuoYi 的写法,本项目没有
|
||||
- ❌ `@Log(title=..., businessType=...)` 是同类快速开发框架的写法,本项目没有
|
||||
|
||||
## @CommonNoRepeat —— 防重复提交
|
||||
|
||||
@@ -55,7 +55,7 @@ public CommonResult<String> create(...) {...}
|
||||
|
||||
```java
|
||||
@SaCheckPermission("/biz/supplier/page") // ✅ 值 = 本接口 URL
|
||||
@SaCheckPermission("biz:supplier:page") // ❌ 冒号式是 RuoYi 的,校验必失败
|
||||
@SaCheckPermission("biz:supplier:page") // ❌ 冒号式是同类框架的,校验必失败
|
||||
```
|
||||
|
||||
- 权限来源:角色-资源授权生成的数据范围 apiUrl 列表(详见 security-auth 技能)
|
||||
@@ -115,7 +115,7 @@ public class BizSupplier extends CommonEntity { // 继承即有 DEL
|
||||
- [ ] @SaCheckPermission 值 = URL 全路径
|
||||
- [ ] 翻译字段 @Trans 的 ref 冗余字段有 @TableField(exist = false)
|
||||
- [ ] 校验消息中文、格式统一
|
||||
- [ ] 没有使用 RuoYi 特有注解(@Log、@RateLimiter、@DataPermission、@ExcelProperty 换 EasyExcel 注解)
|
||||
- [ ] 没有使用同类框架特有注解(@Log、@RateLimiter、@DataPermission、@ExcelProperty 换 EasyExcel 注解)
|
||||
|
||||
## 参考实现
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ description: Snowy 问题排查方法论与高发故障库:启动失败、401/
|
||||
1. 端口 82 被占?(`netstat -ano | findstr :82`)
|
||||
2. MySQL 连不上/库没导 → 导入 `_sql/snowy_mysql.sql`,核对 application.properties 的 master 段口令
|
||||
3. Redis 连不上 → 本地 6379 是否启动(database 1)
|
||||
4. JDK 版本 → 必须 17
|
||||
4. JDK 版本 → 至少 17(17 及以上,如 17/21/23 均可)
|
||||
5. 依赖没编译 → 根目录 `mvn clean install -DskipTests`
|
||||
6. Knife4j 401 → /doc.html 的 basic 认证是 admin/123456
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
name: code-patterns
|
||||
description: Snowy 全量编码禁令速查表(含"来自 RuoYi 的惯性错误"专栏)、命名规范、JSON/日期约定、Git 提交规范。触发场景:1) 写任何 Java/前端代码前的规范自查 2) 审查代码风格问题 3) 提交代码。触发词:编码规范、禁令、命名、代码风格、惯性错误、RuoYi、JSON、日期、Git 提交、commit。注意:本技能是速查表;分层结构见 crud-development,模块组织见 plugin-architecture。
|
||||
description: Snowy 全量编码禁令速查表(含"来自同类快速开发框架的惯性错误"专栏)、命名规范、JSON/日期约定、Git 提交规范。触发场景:1) 写任何 Java/前端代码前的规范自查 2) 审查代码风格问题 3) 提交代码。触发词:编码规范、禁令、命名、代码风格、惯性错误、JSON、日期、Git 提交、commit。注意:本技能是速查表;分层结构见 crud-development,模块组织见 plugin-architecture。
|
||||
---
|
||||
|
||||
# Snowy 编码禁令速查表
|
||||
|
||||
## ⚠️ 来自 RuoYi / RuoYi-Vue-Plus 的惯性错误(最高优先级)
|
||||
## ⚠️ 来自同类快速开发框架的惯性错误(最高优先级)
|
||||
|
||||
AI 对 RuoYi 系框架先验极强,**以下每条都是反向的**,写代码前先扫一遍:
|
||||
AI 对主流 Java 脚手架先验极强,**以下每条都是反向的**,写代码前先扫一遍:
|
||||
|
||||
| # | ❌ RuoYi 惯性写法 | ✅ Snowy 正确写法 |
|
||||
| # | ❌ 常见脚手架惯性写法 | ✅ Snowy 正确写法 |
|
||||
|---|---|---|
|
||||
| 1 | `implements IXxxService`(不继承) | `extends ServiceImpl<XxxMapper, Xxx> implements XxxService` |
|
||||
| 2 | `@RequiredArgsConstructor` + `private final` 构造器注入 | `@Resource` 字段注入(jakarta.annotation.Resource) |
|
||||
@@ -59,7 +59,51 @@ AI 对 RuoYi 系框架先验极强,**以下每条都是反向的**,写代码
|
||||
| Controller URL | `/biz/supplier/page` 小写驼峰域名 | — |
|
||||
| 数据库 | 全大写 | BIZ_SUPPLIER |
|
||||
| 枚举 | `XxxEnum`,含 getValue(),值用枚举不用魔法串 | BizNoticeStatusEnum |
|
||||
| Javadoc | 类与方法都带,含 `@author 名字` `@date yyyy/MM/dd HH:mm` | — |
|
||||
| Javadoc | 类与方法都带,含 `@author 名字` `@date yyyy/MM/dd HH:mm` | 格式见下节 |
|
||||
|
||||
## Javadoc 格式规范(求整齐,只写一行)
|
||||
|
||||
**固定四行,不多不少**:中文摘要一行 → 空行 → `@author` → `@date`。
|
||||
|
||||
```java
|
||||
/**
|
||||
* 解除订阅
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2026/08/27 10:00
|
||||
*/
|
||||
```
|
||||
|
||||
| 要求 | 说明 |
|
||||
|---|---|
|
||||
| 摘要**只有一行** | 一句话说清做什么,不换行、不加句号;写不下就说明方法职责太杂,该拆方法而不是加注释 |
|
||||
| 只允许 `@author` `@date` 两个标签 | date 格式 `yyyy/MM/dd HH:mm`;注释块 `*/` 收尾(平台老代码的 `**/` 不再沿用) |
|
||||
| 类头同样只写一行 | 类名已表达含义,`XXX控制器` / `XXX服务实现类` 即可 |
|
||||
|
||||
### ❌ 禁止出现在 Javadoc 里的东西
|
||||
|
||||
| 禁止 | 原因 |
|
||||
|---|---|
|
||||
| `@param` / `@return` / `@throws` | 参数名与 Param 类名已自解释,写了就是复述签名;改签名还容易漏改成为错误注释 |
|
||||
| 摘要下方的补充说明段落 | 属于实现细节,写在方法体内的行注释里,别占 Javadoc |
|
||||
| `<p>` `</p>` `<ul><li>` 等 HTML 标签 | 本项目 Javadoc 不追求 HTML 渲染,标签只会撑长注释 |
|
||||
| `1. xxx 2. xxx` 多条列举 | 同上,说明逻辑分支请写在代码里 |
|
||||
|
||||
❌ 反例(三种冗余同时出现):
|
||||
```java
|
||||
/**
|
||||
* 解除订阅(管理端强制退订单条明细)
|
||||
* <p>
|
||||
* 复用订阅审批权限,能审批订阅的角色即可解除订阅,无需另行授权
|
||||
*
|
||||
* @param param 明细ID参数
|
||||
* @return 操作结果
|
||||
* @author yubaoshan
|
||||
*/
|
||||
```
|
||||
✅ 正例:摘要压成一行,权限说明移到方法体内或 `@SaCheckPermission` 旁的行注释。
|
||||
|
||||
> 存量说明:仓库现有约 500 处多行 `<p>` 风格 Javadoc(含平台原生 CommonEntity、StpClientUtil 等),**不做批量回改**——本规范只约束新写与重构中顺手经过的代码,避免纯格式 diff 淹没 review。
|
||||
|
||||
## JSON / 日期约定
|
||||
|
||||
@@ -77,6 +121,8 @@ AI 对 RuoYi 系框架先验极强,**以下每条都是反向的**,写代码
|
||||
| 自造请求封装 | `src/utils/request.js` 的 baseRequest / clientRequest |
|
||||
| api 文件乱放 | `src/api/{插件}/{xxx}Api.js` |
|
||||
| 页面文案硬编码中文 | `$t('xxx')` + locales 补词条(遵循现有 i18n) |
|
||||
| 连续多行 `//` 注释段、JSDoc @param/@returns | 每处**一行** `//`;说不下的写进模块 `docs/`(详见 frontend-pc 技能「注释规范」) |
|
||||
| .vue 里 `<script>` 写在 `<template>` 前 | 固定 `template` → `script` → `style` 三块顺序,不可颠倒 |
|
||||
| 按钮权限乱写 | `hasPerm('bizXxxAdd')` 驼峰码,数组与 'and'/'or' 组合 |
|
||||
|
||||
## Git 提交规范
|
||||
@@ -103,8 +149,8 @@ docs: 补充后端开发指南的跨插件调用章节
|
||||
|
||||
## 检查清单(提交前)
|
||||
|
||||
- [ ] 17 条 RuoYi 惯性错误全部规避
|
||||
- [ ] 版权头齐全、注释中文、Javadoc 带 @author @date
|
||||
- [ ] 17 条常见脚手架惯性错误全部规避
|
||||
- [ ] 版权头齐全、注释中文;Javadoc 为「一行摘要 + @author + @date」四行式,无 @param/@return/`<p>`/补充段落
|
||||
- [ ] 命名符合前缀与后缀规范
|
||||
- [ ] 前端无 TS / Element Plus 残留
|
||||
- [ ] commit message 符合 type: 中文 描述
|
||||
|
||||
@@ -7,9 +7,9 @@ description: Snowy CRUD 全套开发规范(六件套 + 可选两件 + 前端
|
||||
|
||||
## 架构特征表(先背下来再写代码)
|
||||
|
||||
| 特征 | Snowy 约定 | 与 RuoYi 系相反点 |
|
||||
| 特征 | Snowy 约定 | 与同类快速开发框架相反点 |
|
||||
|---|---|---|
|
||||
| 包名 | `vip.xiaonuo.biz.modular.{域名}.{层}` | 不是 org.dromara / com.ruoyi |
|
||||
| 包名 | `vip.xiaonuo.biz.modular.{域名}.{层}` | 不是其他脚手架的 org.* / com.* 包名 |
|
||||
| 依赖注入 | `@Resource`(jakarta.annotation)字段注入 | ❌@Autowired ❌构造器注入 |
|
||||
| ServiceImpl | `extends ServiceImpl<XxxMapper, Xxx> implements XxxService` | ❌只 implements 不继承 |
|
||||
| 对象转换 | Hutool `BeanUtil.toBean / copyProperties` | ❌MapstructUtils |
|
||||
@@ -275,7 +275,7 @@ public class BizXxxIdParam {
|
||||
|
||||
## 常见错误正误对照
|
||||
|
||||
| ❌ 错误(RuoYi 惯性) | ✅ 正确(Snowy) |
|
||||
| ❌ 错误(同类框架惯性) | ✅ 正确(Snowy) |
|
||||
|---|---|
|
||||
| `@Autowired private XxxService x;` | `@Resource private XxxService x;` |
|
||||
| `public class XxxServiceImpl implements IXxxService` | `extends ServiceImpl<XxxMapper, Xxx> implements XxxService` |
|
||||
|
||||
@@ -7,16 +7,16 @@ description: Snowy 新环境搭建与首次启动 playbook:JDK/MySQL/Redis/前
|
||||
|
||||
## 就绪清单(按顺序)
|
||||
|
||||
| # | 依赖 | 要求 | 验证 |
|
||||
|---|---|---|---|
|
||||
| 1 | JDK | **17**(⚠️ 本机只有 IDEA 内置 JBR 25 时命令行编译会因 Lombok 1.18.30 失败,IDEA 里配 Project SDK 17 构建即可) | `java -version` |
|
||||
| 2 | MySQL | 8.0/5.7,建库 `snowy`(utf8mb4) | `mysql -e "SHOW DATABASES LIKE 'snowy'"` |
|
||||
| 3 | 导入种子数据 | 执行 `snowy-web-app/src/main/resources/_sql/snowy_mysql.sql`(33 张表) | `mysql snowy -e "SELECT COUNT(*) FROM SYS_USER"` 应 ≥2 |
|
||||
| 4 | Redis | 本地 6379,无密码,用 database 1 | `redis-cli -n 1 ping` |
|
||||
| # | 依赖 | 要求 | 验证 |
|
||||
|---|---|-------------------------------------------------------------------------------------------------------|---|
|
||||
| 1 | JDK | **17/21/23**(⚠️ 本机只有 IDEA 内置 JBR 25 时命令行编译会因 Lombok 1.18.30 失败,IDEA 里配 Project SDK 17 构建即可) | `java -version` |
|
||||
| 2 | MySQL | 8.0/5.7,建库 `snowy`(utf8mb4) | `mysql -e "SHOW DATABASES LIKE 'snowy'"` |
|
||||
| 3 | 导入种子数据 | 执行 `snowy-web-app/src/main/resources/_sql/snowy_mysql.sql`(33 张表) | `mysql snowy -e "SELECT COUNT(*) FROM SYS_USER"` 应 ≥2 |
|
||||
| 4 | Redis | 本地 6379,无密码,用 database 1 | `redis-cli -n 1 ping` |
|
||||
| 5 | 数据源核对 | `snowy-web-app/src/main/resources/application.properties` 的 dynamic master 段(默认 root/12345678,本机不同则改) | — |
|
||||
| 6 | 后端构建启动 | IDEA 启动 `vip.xiaonuo.Application`(snowy-web-app),端口 **82** | 浏览器开 `http://localhost:82` 应显示 WELCOME |
|
||||
| 7 | 前端依赖 | `snowy-admin-web/` 下 `npm install` | — |
|
||||
| 8 | 前端启动 | `npm run dev`,端口 **81**,代理 /api → 82 | 打开 `http://localhost:81` |
|
||||
| 6 | 后端构建启动 | IDEA 启动 `vip.xiaonuo.Application`(snowy-web-app),端口 **82** | 浏览器开 `http://localhost:82` 应显示 WELCOME |
|
||||
| 7 | 前端依赖 | `snowy-admin-web/` 下 `npm install` | — |
|
||||
| 8 | 前端启动 | `npm run dev`,端口 **81**,代理 /api → 82 | 打开 `http://localhost:81` |
|
||||
|
||||
## ★ 出厂登录账号(本仓库种子数据的真实值)
|
||||
|
||||
|
||||
@@ -12,6 +12,34 @@ description: snowy-admin-web 前端开发规范:api js 封装约定、index.vu
|
||||
- 组件自动导入(unplugin):a-xxx 组件、ref/computed 等 API **不需要 import**;自定义组件用 kebab-case 标签
|
||||
- 包管理 npm;目录 `snowy-admin-web/`
|
||||
|
||||
## SFC 块顺序(硬性,不可颠倒)
|
||||
|
||||
**每个 .vue 文件三块固定按 `template` → `script` → `style` 排列**,缺 style 可以,顺序错不行。
|
||||
|
||||
```vue
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup name="业务编码">
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
```
|
||||
|
||||
| 要求 | 说明 |
|
||||
|---|---|
|
||||
| `<template>` 永远第一 | 先看长什么样再看怎么实现;review diff 时结构稳定可预期 |
|
||||
| `<script setup name="业务编码">` 第二 | name 必填(keep-alive 缓存靠它),值为业务编码小驼峰 |
|
||||
| `<style scoped>` 第三 | 默认加 `scoped`;确需全局的另起一个不带 scoped 的块,仍排在最后 |
|
||||
|
||||
❌ 禁止把 `<script>` 写在 `<template>` 前面(Vue 官方 SFC 也支持,但本项目统一为 template 优先,混排会让文件之间没法快速对照)。
|
||||
|
||||
> 存量:`views/plugin/front/` 下有 29 个文件是 script 前置写法,**不做批量回改**,新写与重构经过时按本规范来。
|
||||
|
||||
## 三件套结构(一个业务域)
|
||||
|
||||
```
|
||||
@@ -220,6 +248,48 @@ export default {
|
||||
|
||||
要点:提交成功 `emit('successful')`;数组字段(多选)提交前 `JSON.stringify`(参考 notice 的 place);字典选项 `tool.dictList('BIZ_XXX_TYPE')`。
|
||||
|
||||
## 注释规范(求整齐,一行到底)
|
||||
|
||||
**与后端 Javadoc 同一原则:一行说清,说不清就是代码该拆了。**
|
||||
|
||||
| 位置 | 写法 |
|
||||
|---|---|
|
||||
| 文件头(api js) | 四行块注释:一行中文描述 + 空行 + `@author` + `@date`(见上文模板) |
|
||||
| 文件头(其他 js / vue) | 单行 `// 一句话说明本文件干什么` |
|
||||
| 常量块 / 导出对象 | 上方**一行** `//` |
|
||||
| 函数 / 方法 | 上方**一行** `//` |
|
||||
| 行内 | 句末 `// 一句话`,别换行续写 |
|
||||
|
||||
### ❌ 禁止
|
||||
|
||||
| 禁止 | 替代 |
|
||||
|---|---|
|
||||
| 连续 2 行以上 `//` 堆叠成段 | 压成一行;压不下的属于设计约束,写进 `docs/` 而不是源码 |
|
||||
| 解释「为什么这么设计」的长段说明 | 同上,源码只留结论 |
|
||||
| JSDoc `@param` / `@returns` / `@type` | 一行 `//` 描述即可(api js 文件头的 @author/@date 除外) |
|
||||
| 注释掉的废代码 | 直接删,git 里有 |
|
||||
|
||||
❌ 反例(`constants/enums.js` 旧写法,5 行注释配 1 行代码):
|
||||
```js
|
||||
// 数据中台枚举常量,统一管理所有枚举值,避免硬编码
|
||||
// 这里只放跨页面共用的值域;单个业务页自己用的选项一律放该页目录下的 xxxOptions.js,不要往这里堆
|
||||
|
||||
// 敏感类型枚举,取值与中文名须与后端 DataSecurityScanRuleServiceImpl.SENSITIVE_NAME_MAP 保持一致。
|
||||
// 顺序即扫描规则表单下拉的展示顺序,CUSTOM 固定放末位。
|
||||
// 注意:CUSTOM 规则的真实语义在规则自身的 sensitiveTypeName 上,列表展示优先取该字段
|
||||
export const SensitiveTypeEnum = { ... }
|
||||
```
|
||||
|
||||
✅ 正例(各留一行,约束信息移交文档):
|
||||
```js
|
||||
// 数据中台跨页面共用枚举常量
|
||||
|
||||
// 敏感类型枚举,须与后端 SENSITIVE_NAME_MAP 一致
|
||||
export const SensitiveTypeEnum = { ... }
|
||||
```
|
||||
|
||||
> 压不进一行的信息(模块边界约定、跨端契约、字段优先级规则)不是删掉,是**换地方**——放模块的 `docs/` 并在 INDEX.md 挂号。源码注释负责「这是什么」,文档负责「为什么、怎么配合」。
|
||||
|
||||
## 按钮权限
|
||||
|
||||
```vue
|
||||
@@ -270,16 +340,19 @@ v-if="hasPerm(['bizXxxEdit', 'bizXxxDelete'], 'and')" // 数组 + and/or(
|
||||
| `:data="tableData"` 数组 | s-table `:data="loadData"` 函数 |
|
||||
| 表单不用容器直接弹 a-modal | `xn-form-container` |
|
||||
| 忘 `defineExpose({ onOpen })` | 父组件打不开表单 |
|
||||
| `<script>` 写在 `<template>` 前面 | 固定 template → script → style |
|
||||
| 硬编码中文文案不进 i18n(公共区域) | $t + locales |
|
||||
|
||||
## 检查清单
|
||||
|
||||
- [ ] 每个 .vue 块顺序为 template → script → style,script 带 name
|
||||
- [ ] 三件套齐全(api js / index.vue / form.vue)
|
||||
- [ ] api js 的 URL 前缀与后端一致(/biz/xxx/)
|
||||
- [ ] s-table loadData 模式 + 时间范围拆分
|
||||
- [ ] 按钮权限 hasPerm 码与 SYS_RESOURCE BUTTON 行一致
|
||||
- [ ] 提交成功 emit('successful')
|
||||
- [ ] 无 TS / Element Plus 残留;Tab 缩进
|
||||
- [ ] 注释每处不超过一行,无连续 `//` 段落、无 JSDoc @param/@returns、无注释掉的废代码
|
||||
|
||||
## 参考实现
|
||||
|
||||
|
||||
Reference in New Issue
Block a user