.cursorrules 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. # 陇耘鲜达项目 - 数据库设计规范
  2. ## 表设计规则
  3. ### 1. 必须字段
  4. 所有数据库表必须包含以下字段:
  5. - `id` - 主键,VARCHAR(32),全局唯一
  6. - `is_del` - 是否删除,TINYINT,0=未删除,1=已删除
  7. - `create_at` - 创建时间,DATETIME
  8. - `create_by` - 创建人ID,VARCHAR(32)
  9. - `create_name` - 创建人姓名,VARCHAR(100)
  10. - `update_at` - 修改时间,DATETIME
  11. - `update_by` - 修改人ID,VARCHAR(32)
  12. ### 2. 删除策略
  13. - 所有表采用**虚拟删除**机制
  14. - 删除操作时,将 `is_del` 字段设为 1,不执行物理删除
  15. - 查询时默认添加 `WHERE is_del = 0` 条件
  16. ### 3. 历史表机制
  17. - **每个业务表**都需要创建一个对应的历史表
  18. - 历史表命名规则:`主表名 + _his`
  19. - 触发时机:在进行 UPDATE 操作时
  20. 1. 首先将原始数据完整复制到历史表
  21. 2. 然后再更新主表数据
  22. - 历史表结构:与主表结构相同
  23. - 历史表特殊处理:
  24. - 不需要任何索引
  25. - `id` 字段不需要唯一性限制(可以重复)
  26. - 不需要 `is_del` 字段(历史数据永久保留)
  27. ### 4. 其他规范
  28. - 表名使用下划线命名法,如:`sys_user`, `ord_order`
  29. - 字段名使用下划线命名法
  30. - 金额字段使用 DECIMAL(12, 2) 类型
  31. - 状态字段使用 VARCHAR(20) 或 INT
  32. - 时间字段使用 DATETIME 类型
  33. - 字符串类型根据实际长度选择 VARCHAR 或 TEXT
  34. ## 数据库命名约定
  35. - 数据库名称:`sanqiang`
  36. - 表前缀:无特殊前缀
  37. - 历史表后缀:`_his`
  38. ---
  39. ## UI 设计风格规范
  40. ### 1. 整体风格
  41. - **设计理念**:现代、专业、高效;运营 Web 管理端以 **Fresh Mint(薄荷绿)** 为品牌主色,中性色以 Slate 系为主
  42. - **艺术风格**:简洁、清爽;强调色集中用于主按钮、导航选中、主状态标签等,避免一屏多种高饱和彩色
  43. - **设计一致性**:**Web 管理端(`web-admin`)** 以设计源 `test/fresh-mint-green.html` 与文档 `docs/web-admin-ui-spec-fresh-mint.md` 为唯一视觉权威;**小程序各角色端** 可继续使用角色主题色(橙/绿/红),不必与 Web 管理端同色
  44. ### 2. Web端 - Fresh Mint(`web-admin`)
  45. #### 技术栈
  46. - Vue3 + TypeScript
  47. - Element Plus 组件库
  48. - Tailwind CSS
  49. - Pinia 状态管理
  50. #### 权威文档与实现方式
  51. - **完整 Token、布局、组件、与 Element 映射**:见 **`docs/web-admin-ui-spec-fresh-mint.md`**
  52. - **设计稿 / 对照 HTML**:`test/fresh-mint-green.html`
  53. - **`web-admin` 界面改造留痕**:对运营后台页面做 Fresh Mint 对齐、布局或组件级调整时,**约定将过程性与结论性说明同步写入** **`docs/web-admin-ui-spec-fresh-mint.md`**(如增补小节、实现清单、或某页的专用布局/交互约定),便于后续统一改版时对照,避免只改代码不更新规范。
  54. - 实现时优先:**全局 CSS 变量(与 demo `:root` 一致)→ Element 主题变量 → `el-ui.scss` / 布局组件覆盖**,与 demo 色值保持一致
  55. - **硬提醒(壳子与区块勿漏)**:侧栏/顶栏/内容区/Tab 条 **§3**;筛选区 **§5**(**含带清除输入**);按钮与 Loading **§6**;列表工具栏、表格、分页、标签 **§7**;树形子表 **§8**;弹窗/抽屉 **§9**;表单、迷你表与上传 **§10**;图标与无障碍 **§11**(如 **`.sr-only`**);细节与 HTML 不一致时以 **`test/fresh-mint-green.html`** 及规范 **§14–§15** 为准
  56. #### 色彩方案(运营 Web 管理端;与 demo 一致)
  57. ```scss
  58. // 主色 - 薄荷绿(Emerald)
  59. $primary-color: #10b981;
  60. $primary-dark: #059669;
  61. $primary-bg: #ecfdf5;
  62. // 中性色(Slate)
  63. $text-primary: #1e293b;
  64. $text-muted: #64748b;
  65. $border-color: #d9e8e2;
  66. // 背景
  67. $bg-page: #fefefe;
  68. $surface: #ffffff;
  69. $table-head: #f8fafc;
  70. $row-alt: #fafafa;
  71. $row-hover: #f1f5f9;
  72. // 语义色(列表状态等;与业务表配合,慎用大红大蓝)
  73. $success-color: #059669; // 成功/正向(可与 primary-dark 协调)
  74. $warning-color: #d97706; // 警告/待处理(琥珀,见 demo .stat.warn)
  75. $danger-color: #dc2626; // 危险/异常(强提醒、二次确认场景)
  76. ```
  77. #### 组件风格(对齐 demo)
  78. - 圆角:面板/大卡片 **10px**;按钮、输入、筛选控件多为 **8px**;行内操作按钮 **6px**
  79. - 阴影:`0 1px 3px rgba(0, 0, 0, 0.05)`(卡片/面板轻阴影)
  80. - 按钮:主按钮实心绿;次要/批量操作为 **中性描边**(demo 中批量删除非必选红色按钮)
  81. - 表格:表头 `#f8fafc`、斑马纹、hover、细边框;支持时末列操作 **sticky** 与 demo 一致
  82. - 表单:筛选区 label **11px** 灰色;控件高度 **36px**;focus 环 `0 0 0 2px rgba(16, 185, 129, 0.2)`
  83. #### 布局规范(对齐 demo)
  84. - 左侧菜单:**220px** 宽,可折叠
  85. - 顶部导航:**56px** 高(以 `fresh-mint-green.html` 为准),白底 + 底部分割线;面包屑 **13px**
  86. - 内容区:**24px** 内边距(`--content-padding`)
  87. - 字体:**Inter**(或项目已加载字体)+ 系统回退;正文 **14px**
  88. #### 状态标签样式(Web 管理端)
  89. ```scss
  90. .status-tag { padding: 2px 8px; border-radius: 6px; font-size: 12px; font-weight: 600; }
  91. .status-tag.primary { background: #ecfdf5; color: #059669; } // 待处理/进行中(主品牌绿)
  92. .status-tag.success { background: #d1fae5; color: #047857; } // 成功/已完成
  93. .status-tag.warning { background: #fffbeb; color: #d97706; } // 警告/待支付(琥珀)
  94. .status-tag.danger { background: #fef2f2; color: #dc2626; } // 危险/异常
  95. .status-tag.info { background: #f8fafc; color: #64748b; } // 信息/取消/禁用
  96. ```
  97. ### 3. 小程序端 - 移动端风格
  98. #### 技术栈
  99. - uni-app + Vue3 + TypeScript
  100. - Vant Weapp 组件库 (移动端适配版)
  101. - Pinia 状态管理
  102. #### 权威文档与实现方式(新增,强约束)
  103. - **小程序 UI 规范权威文档**:`docs/miniprogram-ui-spec-sanqiang.md`
  104. - **配送员端 UI 改造执行文档(强约束)**:`docs/小程序-配送员端UI改造指南.md`
  105. - **小程序 UI 设计基准 Demo**:
  106. - `mobile-ui/sanqiang-client-ui-demo.html`
  107. - `mobile-ui/sanqiang-client-cart-ui-demo.html`
  108. - `mobile-ui/sanqiang-client-order-ui-demo.html`
  109. - `mobile-ui/sanqiang-client-profile-ui-demo.html`
  110. - `mobile-ui/sanqiang-supplier-ui-demo.html`
  111. - `mobile-ui/sanqiang-deliverer-ui-demo.html`
  112. - 后续小程序 UI 改造(客户端/供应商端/配送员端)必须以以上文档和 Demo 为视觉标准,**不再使用旧风格自由发挥**。
  113. - **配送员小程序端特殊约束**:`miniprogram/src/pages/deliverer/**` 的 UI 改造必须遵循 `docs/小程序-配送员端UI改造指南.md`;其中首页 `pages/deliverer/home/home` 的布局与视觉层级必须严格对齐 `mobile-ui/sanqiang-deliverer-ui-demo.html`,功能保持现有逻辑不变。
  114. - **配送员卡片素材替换规则**:配送员端界面卡片中的 icon 与图片素材可按设计图与统一视觉方案进行替换,**不要求复用现有素材**;但需保持语义清晰、风格一致与交互可识别性。
  115. - **改造留痕强制规则**:配送员端每次完成 UI 改造后,必须同步回写 `docs/小程序-配送员端UI改造指南.md` 的“变更记录”小节,至少记录改造页面、视觉变更点、功能保持说明、遗留问题;禁止只改代码不更新文档。
  116. - 改造优先顺序:**Token(颜色/圆角/间距/字号)→ 页面骨架(头部/功能区/列表区)→ 组件映射(分类、卡片、状态、按钮)→ 交互细节(滑块、翻页、点击反馈)**。
  117. - 如遇历史页面样式冲突,以 `docs/miniprogram-ui-spec-sanqiang.md` 为准,并将差异回写该文档,避免只改代码不更新规范。
  118. #### 色彩方案(小程序端按角色区分;不必与 Web 管理端同色)
  119. ```scss
  120. // 主色调(可按角色换肤;示例沿用原角色色)
  121. $primary-color: #1989fa; // 示例:运营/默认蓝(小程序若独立配置可改)
  122. $success-color: #07c160;
  123. $warning-color: #ff976a;
  124. $danger-color: #ee0a24;
  125. // 背景色
  126. $bg-white: #ffffff;
  127. $bg-gray: #f5f5f5;
  128. ```
  129. #### 组件风格
  130. - 圆角:8px (按钮), 12px (卡片), 16px (弹窗)
  131. - 间距:20rpx (小), 30rpx (中), 40rpx (大)
  132. - 字体:28rpx (正文), 24rpx (辅助), 32rpx (标题)
  133. - 图标:简洁线条风格
  134. #### 布局规范
  135. - 顶部:角色名称 + 退出登录
  136. - 中部:功能卡片网格布局 (2列)
  137. - 底部:标签导航 (可选)
  138. #### 三端统一硬规则(新增)
  139. - **客户端首页分类区**:采用“一级分类两行五列(每页10个)+ 多页左右滑动 + 分页滑块(有几页就几个,支持点击翻页)+ 二级分类侧栏联动商品区”模式。
  140. - **客户端底部结算条**:信息结构固定为“数量 → 总价 → 去结算主按钮”,主按钮视觉优先级最高。
  141. - **供应商端与配送员端**:保持同一配色体系、同一卡片风格、同一菜单宫格视觉节奏。
  142. - **配送员端菜单位置**:放在任务列表上方,与供应商端布局逻辑一致。
  143. - **状态标签语义一致**:warning=待处理,success=进行中/已完成,danger=异常;禁止同屏滥用高饱和颜色。
  144. #### 状态标签样式
  145. ```scss
  146. .status-tag { padding: 4px 10px; border-radius: 4px; font-size: 12px; }
  147. .status-tag.primary { background: #e6f7ff; color: #1989fa; }
  148. .status-tag.success { background: #f6ffed; color: #07c160; }
  149. .status-tag.warning { background: #fff7e6; color: #ff976a; }
  150. .status-tag.danger { background: #fff1f0; color: #ee0a24; }
  151. .status-tag.info { background: #f5f5f5; color: #999; }
  152. ```
  153. ### 4. 角色主题色区分
  154. | 角色 | 主色调 | 渐变配色 | 场景 |
  155. |------|--------|----------|------|
  156. | 运营端(Web 管理后台) | #10b981 (薄荷绿) | linear-gradient(135deg, #10b981 0%, #34d399 100%) | `web-admin` 顶部/主按钮(见 `docs/web-admin-ui-spec-fresh-mint.md`) |
  157. | 供应商 | #ff976a (活力橙) | linear-gradient(135deg, #ff976a 0%, #ff4444 100%) | 小程序顶部/按钮 |
  158. | 客户 | #07c160 (清新绿) | linear-gradient(135deg, #07c160 0%, #1989fa 100%) | 小程序顶部/按钮 |
  159. | 配送员 | #ee0a24 (活力红) | linear-gradient(135deg, #ee0a24 0%, #ff976a 100%) | 小程序顶部/按钮 |
  160. ```scss
  161. // 运营端 Web 管理端 - Fresh Mint(与 demo 一致)
  162. $admin-primary: #10b981;
  163. $admin-gradient: linear-gradient(135deg, #10b981 0%, #34d399 100%);
  164. // 供应商端 - 活力橙
  165. $supplier-primary: #ff976a;
  166. $supplier-gradient: linear-gradient(135deg, #ff976a 0%, #ff4444 100%);
  167. // 客户端 - 清新绿
  168. $client-primary: #07c160;
  169. $client-gradient: linear-gradient(135deg, #07c160 0%, #1989fa 100%);
  170. // 配送员端 - 活力红
  171. $deliver-primary: #ee0a24;
  172. $deliver-gradient: linear-gradient(135deg, #ee0a24 0%, #ff976a 100%);
  173. ```
  174. ### 5. 通用规范
  175. #### 图标系统
  176. - Web端:使用 Element Plus Icons
  177. - 小程序端:使用 Vant Icons
  178. - 图标风格:简洁线条风格
  179. #### 间距系统
  180. - Web端:基于 4px 网格系统 (4, 8, 12, 16, 20, 24, 32, 40, 48)
  181. - 小程序端:基于 10rpx 网格系统 (10, 20, 30, 40)
  182. #### 响应式断点
  183. - Web端:1920px / 1440px / 1200px / 768px
  184. - 小程序端:375px / 414px (固定设计宽度)
  185. #### 字体规范
  186. - Web端(`web-admin`):Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif(与 `fresh-mint-green.html` 一致;以项目字体加载为准)
  187. - 小程序端:-apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', Arial, sans-serif
  188. ### 6. 页面通用元素
  189. #### 顶部导航 (Web端)
  190. - 高度:**56px**(以 `fresh-mint-green.html` / `docs/web-admin-ui-spec-fresh-mint.md` 为准)
  191. - 包含:面包屑或标题区、消息通知、个人下拉等(具体以 `web-admin` 布局组件为准)
  192. - 背景:白底 + 底部分割线(**不以**大色块渐变为主;主色用于按钮与选中态)
  193. #### 侧边菜单 (Web端)
  194. - 宽度:**220px** (可折叠)
  195. - 包含:一级分组、二级链接
  196. - 选中状态:浅绿底 `primary-bg` + 字色 `primary-dark`(与 demo `.nav a.active` 一致)
  197. #### 原型导航 (原型图专用)
  198. - 固定在页面右上角
  199. - 快速切换各页面
  200. - 包含页面名称和激活状态
  201. #### 手机框架 (小程序端)
  202. - 最大宽度:414px
  203. - 圆角:40px
  204. - 顶部状态栏模拟
  205. ### 7. 交互规范
  206. #### 按钮样式
  207. - 主要按钮:实心主色(Web 管理端 **#10b981**),圆角 **8px**(小程序可为 24rpx 等)
  208. - 次要按钮:白底 + 边框(`--border`),高度与主按钮对齐 **36px**
  209. - 文字/链接按钮:如筛选区「展开更多」——透明底、主色深绿字、hover 浅绿底(见 demo `.btn-link`)
  210. #### 表单验证
  211. - 实时校验
  212. - 错误提示:红色文字 + 底部提示
  213. - 必填标识:红色星号
  214. #### 列表操作
  215. - 查看:跳转详情
  216. - 编辑:弹窗或新页面
  217. - 删除:二次确认弹窗
  218. ### 8. 订单状态流转 (前端显示)
  219. | 状态 | 显示文本 | 颜色类 | 适用角色 |
  220. |------|----------|--------|----------|
  221. | pending_payment | 待支付 | warning | 客户/运营 |
  222. | pending_review_cancel | 待审核取消 | primary | 运营 |
  223. | pending_delivery | 待分配配送 | primary | 运营 |
  224. | delivering | 配送中 | info | 配送员/客户 |
  225. | partial_delivered | 部分送达 | warning | 运营 |
  226. | pending_confirm | 待确认收货 | primary | 客户 |
  227. | completed | 已完结 | success | 所有 |
  228. | cancelled | 已取消 | info | 所有 |
  229. ### 9. 配送任务状态 (前端显示)
  230. | 状态 | 显示文本 | 颜色类 |
  231. |------|----------|--------|
  232. | pending | 待取货 | warning |
  233. | picking | 取货中 | primary |
  234. | delivering | 配送中 | info |
  235. | completed | 已完成 | success |
  236. | cancelled | 已取消 | info |
  237. ---
  238. ## 接口设计规范
  239. ### 1. 通用约定
  240. #### 请求格式
  241. - 所有接口使用 **JSON** 格式进行数据交换
  242. - 请求头必须包含 `Content-Type: application/json`
  243. - 认证接口使用 Bearer Token 方式
  244. #### 响应格式
  245. ```json
  246. {
  247. "code": 200,
  248. "message": "success",
  249. "data": { },
  250. "timestamp": 1700000000000
  251. }
  252. ```
  253. #### 错误码规范
  254. ```json
  255. {
  256. "code": 400,
  257. "message": "错误描述",
  258. "data": null,
  259. "timestamp": 1700000000000
  260. }
  261. ```
  262. | 错误码 | 含义 |
  263. |--------|------|
  264. | 200 | 成功 |
  265. | 400 | 请求参数错误 |
  266. | 401 | 未授权/Token过期 |
  267. | 403 | 无权限 |
  268. | 404 | 资源不存在 |
  269. | 500 | 服务器内部错误 |
  270. ### 2. URL 规范
  271. #### 路由前缀
  272. - Web端API: `/api/web/`
  273. - 小程序端API: `/api/mini/`
  274. #### 资源命名
  275. - 复数形式:`/users`, `/orders`, `/products`
  276. - 单个资源:`/users/{id}`, `/orders/{id}`
  277. - 动作资源:`/orders/{id}/cancel`, `/orders/{id}/pay`
  278. #### 动词使用
  279. | 方法 | 用途 |
  280. |------|------|
  281. | GET | 查询/获取资源 |
  282. | POST | 创建新资源 |
  283. | PUT | 完整更新资源 |
  284. | PATCH | 部分更新资源 |
  285. | DELETE | 删除资源 |
  286. ### 3. 分页规范
  287. #### 请求参数
  288. | 参数 | 类型 | 必填 | 说明 |
  289. |------|------|------|------|
  290. | page | int | 否 | 页码,默认1 |
  291. | pageSize | int | 否 | 每页条数,默认10 |
  292. #### 响应格式
  293. ```json
  294. {
  295. "code": 200,
  296. "data": {
  297. "list": [ ],
  298. "total": 100,
  299. "page": 1,
  300. "pageSize": 10,
  301. "totalPages": 10
  302. }
  303. }
  304. ```
  305. ### 4. 排序规范
  306. #### 请求参数
  307. | 参数 | 类型 | 说明 |
  308. |------|------|------|
  309. | orderBy | string | 排序字段 |
  310. | orderType | string | 排序方式:asc/desc |
  311. #### 默认排序规则
  312. - **所有列表接口默认按创建时间倒序排列**(最新创建的记录显示在最前面)
  313. - 默认排序参数:`orderBy=create_at&orderType=desc`
  314. - 后端 CRUD 基类已统一实现此默认排序逻辑,无需前端重复指定
  315. - 特殊情况(如树形分类的 sortOrder 排序)可在具体接口中单独定义
  316. ### 5. 时间格式
  317. - 请求/响应中使用 **ISO 8601** 格式:`2026-03-19T10:30:00+08:00`
  318. - 数据库存储使用 **DATETIME** 类型
  319. - 前端展示格式:`YYYY-MM-DD HH:mm:ss`
  320. ### 6. 金额规范
  321. - 存储单位:**分**(整数)
  322. - 展示单位:**元**(除以100,保留2位小数)
  323. - API响应示例:`"amount": 1000` 表示 `10.00元`
  324. ### 7. 角色权限标识
  325. | 角色 | 标识 | 说明 |
  326. |------|------|------|
  327. | admin | 运营人员 | 全部权限 |
  328. | supplier | 供应商 | 本区域数据 |
  329. | client | 客户 | 本区域数据 |
  330. | deliver | 配送员 | 本区域数据 |
  331. ### 8. 区域数据隔离
  332. - 所有查询接口默认按当前用户所属区域过滤
  333. - 跨区域访问返回空列表或无权限错误
  334. ### 9. 审计日志记录
  335. 以下操作必须记录审计日志:
  336. - 用户创建/修改/删除/登录
  337. - 密码修改/重置
  338. - 价格发布/修改
  339. - 订单状态变更
  340. - 退款/结算操作
  341. - 配送任务分配
  342. ---
  343. ## 前后端交互规范
  344. ### 1. 命名约定
  345. #### 字段命名规范
  346. | 层级 | 命名风格 | 示例 |
  347. |------|----------|------|
  348. | 数据库 | 蛇形命名 | `is_required`, `sort_order`, `param_type` |
  349. | 后端 Schema | 蛇形命名 + Pydantic alias | `is_required: int = Field(..., alias="isRequired")` |
  350. | 后端 Model | 蛇形命名 | `is_required`, `sort_order` |
  351. | 前端 API 请求 | 驼峰命名 | `{ isRequired: 1, sortOrder: 10 }` |
  352. | 前端 API 响应 | 驼峰命名 | `{ isRequired: 1, sortOrder: 10, paramType: "select" }` |
  353. #### 关键字段映射对照表
  354. | 后端蛇形 | 后端 Model | 前端驼峰 |
  355. |----------|-----------|----------|
  356. | `is_required` | `is_required` | `isRequired` |
  357. | `is_active` | `is_active` | `isActive` |
  358. | `is_del` | `is_del` | `isDel` |
  359. | `sort_order` | `sort_order` | `sortOrder` |
  360. | `param_type` | `param_type` | `paramType` |
  361. | `param_value` | `param_value` | `paramValue` |
  362. | `product_id` | `product_id` | `productId` |
  363. | `category_id` | `category_id` | `categoryId` |
  364. | `create_at` | `create_at` | `createAt` |
  365. | `update_at` | `update_at` | `updateAt` |
  366. | `create_by` | `create_by` | `createBy` |
  367. | `create_name` | `create_name` | `createName` |
  368. ### 2. HTTP 响应数据处理
  369. #### 前端 HTTP 封装规范
  370. 前端 `utils/http/index.ts` 中的 `request` 函数已自动处理响应数据提取:
  371. ```typescript
  372. // request 函数返回的是 response.data,即 { code, message, data, timestamp } 中的 data 部分
  373. const res = await fetchProductParameterList(params)
  374. // res 已经是 { list: [...], total: 100 } 这样的数据结构
  375. // 不需要再访问 res.data
  376. ```
  377. #### 前端正确的数据访问方式
  378. ```typescript
  379. // ✅ 正确写法
  380. const loadData = async () => {
  381. const res: any = await fetchProductParameterList(params)
  382. if (res && res.list) {
  383. tableData.value = res.list
  384. pagination.total = res.total
  385. }
  386. }
  387. // ❌ 错误写法(多了一层 .data)
  388. if (res.code === 200) {
  389. tableData.value = res.data.list // 错误!
  390. }
  391. ```
  392. #### 删除/更新操作的简化处理
  393. ```typescript
  394. // ✅ 正确写法 - request 函数会自动处理 200 响应
  395. const handleDelete = async (row: any) => {
  396. await fetchDeleteProductParameter(row.id)
  397. ElMessage.success('删除成功')
  398. loadData()
  399. }
  400. // ✅ 正确写法 - 需要判断时
  401. const handleSubmit = async () => {
  402. await fetchCreateProductParameter(data)
  403. ElMessage.success('创建成功')
  404. dialogVisible.value = false
  405. loadData()
  406. }
  407. ```
  408. ### 3. 后端 Pydantic Schema 规范
  409. #### 必须添加 alias 和 populate_by_name
  410. ```python
  411. from pydantic import BaseModel, Field, ConfigDict
  412. class ProductParameterBase(BaseModel):
  413. """商品参数基础字段"""
  414. model_config = ConfigDict(populate_by_name=True)
  415. # 使用 alias 指定前端字段名
  416. name: str = Field(..., alias="name")
  417. param_type: str = Field(default="text", alias="paramType")
  418. is_required: int = Field(default=0, alias="isRequired")
  419. is_active: int = Field(default=1, alias="isActive")
  420. sort_order: int = Field(default=0, alias="sortOrder")
  421. class ProductParameterUpdate(BaseModel):
  422. """更新商品参数请求"""
  423. model_config = ConfigDict(populate_by_name=True)
  424. name: Optional[str] = Field(None, alias="name")
  425. param_type: Optional[str] = Field(None, alias="paramType")
  426. is_required: Optional[int] = Field(None, alias="isRequired")
  427. sort_order: Optional[int] = Field(None, alias="sortOrder")
  428. ```
  429. #### 关键点
  430. - `model_config = ConfigDict(populate_by_name=True)` - 允许使用 alias 填充
  431. - 每个字段必须指定 `alias="驼峰命名"` - 与前端字段对应
  432. ### 4. 后端 CRUD Base 规范
  433. #### 字段映射工具函数
  434. `backend/app/crud/base.py` 必须包含字段名映射逻辑:
  435. ```python
  436. import re
  437. def camel_to_snake(name: str) -> str:
  438. """驼峰命名转蛇形命名"""
  439. s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
  440. return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
  441. def get_model_attr(obj, key: str):
  442. """获取模型的属性名,支持驼峰转蛇形"""
  443. # 先尝试直接匹配
  444. if hasattr(obj, key):
  445. return key
  446. # 尝试驼峰转蛇形
  447. snake_key = camel_to_snake(key)
  448. if hasattr(obj, snake_key):
  449. return snake_key
  450. return None
  451. ```
  452. #### CRUD 方法中使用映射
  453. ```python
  454. class CRUDBase:
  455. def create(self, db: Session, obj_in: dict, creator: dict = None) -> ModelType:
  456. obj = self.model()
  457. for key, value in obj_in.items():
  458. attr_name = get_model_attr(obj, key) # 使用映射函数
  459. if attr_name:
  460. setattr(obj, attr_name, value)
  461. # ... 其他逻辑
  462. def update(self, db: Session, id: str, obj_in: dict, updater: dict = None):
  463. obj = self.get(db, id)
  464. if obj:
  465. for key, value in obj_in.items():
  466. attr_name = get_model_attr(obj, key) # 使用映射函数
  467. if attr_name and key not in ["id", "create_at", "create_by", "create_name"]:
  468. setattr(obj, attr_name, value)
  469. # ... 其他逻辑
  470. ```
  471. ### 5. API 响应字段映射
  472. #### 后端返回时使用驼峰命名
  473. ```python
  474. @router.get("", response_model=dict)
  475. def list_parameters(...):
  476. return success_response({
  477. "list": [{
  478. "id": p.id,
  479. "name": p.name,
  480. "code": p.code,
  481. "paramType": p.param_type, # 蛇形转驼峰
  482. "isRequired": p.is_required, # 蛇形转驼峰
  483. "isActive": p.is_active, # 蛇形转驼峰
  484. "sortOrder": p.sort_order, # 蛇形转驼峰
  485. "createAt": str(p.create_at) # 蛇形转驼峰
  486. } for p in items],
  487. "total": total,
  488. "page": page,
  489. "pageSize": pageSize
  490. })
  491. ```
  492. ### 6. 新增模块 Checklist
  493. 新增一个包含增删改查的模块时,必须完成以下步骤:
  494. #### 后端
  495. - [ ] 创建 Schema 类时,添加 `model_config = ConfigDict(populate_by_name=True)`
  496. - [ ] 所有字段添加 `alias="驼峰命名"`
  497. - [ ] API 返回数据时,将蛇形字段转为驼峰
  498. - [ ] 确认 CRUD base 已包含字段映射逻辑(已有通用逻辑)
  499. #### 前端
  500. - [ ] API 响应数据访问时,使用 `res.list` 而不是 `res.data.list`
  501. - [ ] 删除/更新操作后直接处理成功逻辑
  502. ### 7. 常见错误排查
  503. | 问题现象 | 原因 | 解决方案 |
  504. |----------|------|----------|
  505. | 前端新增的数据 `sortOrder` 为 0 | CRUD 未处理字段映射 | 确保 `get_model_attr` 函数生效 |
  506. | 前端提交的 `isRequired` 未保存 | Schema 缺少 alias | 添加 `alias="isRequired"` |
  507. | 列表数据无法展示 | 前端访问路径错误 | 使用 `res.list` 而非 `res.data.list` |
  508. | 编辑后数据未更新 | update 方法未映射字段 | 确保使用 `get_model_attr(obj, key)` |
  509. ---
  510. ## 测试执行留痕强制规则(P0)
  511. - 当代理执行任何 `P0` 回归测试(单条或批量)后,必须同步更新 `docs/P0-实际验证记录.md`。
  512. - 更新方式必须为“追加新执行批次”,禁止覆盖历史记录。
  513. - 每条已执行用例至少记录以下内容:
  514. - 请求流程与关键入参(敏感信息脱敏)
  515. - 接口结果(HTTP 状态码、业务 code、关键信息)
  516. - 数据库前后快照 SQL
  517. - 数据库前后结果与差异结论
  518. - 若存在失败用例,必须额外记录:
  519. - 失败响应体或报错摘要
  520. - 断言失败点
  521. - 下一步处理动作(修复建议/重试计划)
  522. - 若仅进行了口头汇报而未更新文档,视为流程未完成。
  523. ---
  524. ## Web 慢接口优化执行规范(强制)
  525. - 当识别到 `web-admin` 慢接口(建议阈值:`p95 >= 800ms`)后,后续执行必须遵循:
  526. 1. 基线采样(固定口径,记录 `avg/p95/p99/max`)
  527. 2. 慢点定位(代码 N+1 + SQL EXPLAIN)
  528. 3. 优化落地(代码优化优先,索引补强其次)
  529. 4. 同口径复测(输出前后对比)
  530. - 列表接口默认要求:
  531. - 禁止循环内逐条查库(必须批量查询 + map 回填)
  532. - 禁止无差别整行查询(必须字段投影)
  533. - `total` 统计优先 `func.count(id) + order_by(None)`
  534. - 索引策略默认要求:
  535. - 围绕 `is_del + 常用过滤列 + create_at(order by)` 设计联合索引
  536. - 索引变更需提供 `backend/scripts/*.sql` 脚本并在测试库验证
  537. - 文档留痕要求:
  538. - 必须同步更新 `docs/web-admin-接口性能测试报告-*.md`
  539. - 必须同步更新 `docs/后端接口全覆盖测试与数据库校验实施跟踪.md`
  540. - 未更新文档视为性能优化流程未完成。
  541. ---
  542. ## 小程序慢接口优化执行规范(强制)
  543. - 当识别到 `mini/client/*` 慢接口(建议阈值:`p95 >= 800ms`)后,必须执行完整闭环:
  544. 1. 基线采样(固定口径:账号、参数、采样次数,记录 `avg/p95/p99/max`)
  545. 2. 慢点定位(代码 N+1、循环查库、字段冗余;必要时 SQL EXPLAIN)
  546. 3. 优化落地(批量查询 + 字段投影 + count 优化 + 必要索引/缓存)
  547. 4. 同口径复测(输出前后对比,确认收益)
  548. 5. 文档留痕(报告 + 跟踪文档同步)
  549. - 列表接口强约束:
  550. - 禁止循环内逐条查询商品/分类/单位等关联数据
  551. - 必须优先使用批量查询与 map 回填
  552. - 必须按需字段投影,避免无差别整行读取
  553. - 规则适用范围:
  554. - 至少覆盖 `mini/client/products`、`mini/client/price-list/current`、`mini/client/cart*`、`mini/client/orders*` 等高频接口
  555. - 留痕要求:
  556. - 必须同步更新 `docs/sqxp-wx-接口性能排查报告-*.md`
  557. - 必须同步更新 `docs/后端接口全覆盖测试与数据库校验实施跟踪.md`
  558. - 未同步文档视为优化流程未完成。