Explorar o código

会员管理代码

wwh hai 2 semanas
pai
achega
5cd6b2899f

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 16 - 0
doc/店铺后台/商品管理/商品列表/商品列表功能需求-草稿.md


+ 667 - 0
doc/店铺后台/商品管理/商品列表/商品列表功能需求.md

@@ -0,0 +1,667 @@
1
+# 店铺商品列表 — 功能需求说明
2
+
3
+> 本文档在《商品列表功能需求-草稿》基础上整理,并关联 **《关联需求分析.md》**、平台侧 **《商品审核功能需求》**、**《商品分类功能需求》**、**《商品服务管理功能需求》**、**《店铺管理功能需求》** 及商家侧 **《店铺商品分类功能需求》** 做边界与流程对齐。  
4
+> 范围:**店铺经营管理端 · 商品管理** 对 **当前店铺下商品** 的列表、检索、发品、编辑、提交上架、下架与删除。  
5
+> **说明:** 本文档 **仅描述功能需求与业务规则**;不涉及数据库结构、接口定义及技术实现细节。  
6
+> **v1.0:** 首版定稿;对齐草稿 §1~§7;补全五态状态机、店铺上下文、与平台审核/分类/服务的协作链。
7
+
8
+---
9
+
10
+## 1. 模块定位
11
+
12
+### 1.1 业务目标
13
+
14
+在农资商城 **店铺经营管理端(Web)· 商品管理** 提供 **商品列表** 能力,使 **店铺管理员**(商户经营账号及已授权子管理员)能够:
15
+
16
+- 浏览 **当前店铺** 下全部商品;
17
+- **添加、编辑** 商品资料;
18
+- **提交上架**、**下架**、**删除** 商品(单独 / 批量);
19
+- 按编号、名称、分类等 **检索** 商品;
20
+- 查看各状态商品的 **详情** 及平台 **驳回原因**。
21
+
22
+**不包含(本期或与它模块分工):**
23
+
24
+| 能力 | 说明 |
25
+|------|------|
26
+| **平台 · 商品审核** | 见平台 **商品审核**;平台对待审核商品通过/驳回、对出售中商品下架 |
27
+| **平台 · 商品分类 / 服务目录维护** | 见平台 **商品分类**、**商品服务管理**;商家 **只选** 不维护目录 |
28
+| **店铺商品分类维护** | 见 **店铺商品分类**;本模块 **消费** 其数据 |
29
+| **属性模版维护** | 模版配置 **非本期**(若后续单独立项);发品时 **选用** 已有模版 |
30
+| **C 端下单 / 订单履约** | 见 **订单管理**;本模块不处理发货、退款 |
31
+
32
+### 1.2 与草稿的对应关系
33
+
34
+| 草稿条目 | 定稿处理 |
35
+|----------|----------|
36
+| §1 列表字段 | §5.1 |
37
+| §2 添加商品 | §8 |
38
+| §3 高级检索 | §6 |
39
+| §4 商品状态 | §4、§12(「待上架」定稿称 **未上架**) |
40
+| §5 操作(详情/上下架/编辑/删除) | §7、§9~§11 |
41
+| §6 按当前店铺查列表 | §5.2、§13 |
42
+| §7 店铺上下文 | §13 |
43
+| §8 异常返回 | **不纳入** |
44
+| §9 技术栈 | **不纳入** |
45
+
46
+### 1.3 在供给链中的位置
47
+
48
+依据 **《关联需求分析.md》§5.1、§5.4**:
49
+
50
+```text
51
+【平台】商户管理 → 店铺管理 → 商品服务目录 / 商品分类(平台树)
52
+            ↓
53
+【商家】登录 → 选择当前店铺
54
+            ↓
55
+【商家】店铺商品分类(可选)── 维护本店店铺商品分类
56
+            ↓
57
+【商家】商品列表(本模块)── 发品 / 提交上架 / 下架 / 删除
58
+            ↓
59
+    ┌─ 店铺「默认审核通过」= 关 ─► 待审核 ──【平台】审核──► 出售中 / 审核失败
60
+    └─ 店铺「默认审核通过」= 开 ─► 直接出售中
61
+            ↓
62
+【C 端】出售中 + 店铺开业 + 库存等 → 可下单
63
+```
64
+
65
+| 关联模块 | 关系 | 边界说明 |
66
+|----------|------|----------|
67
+| **店铺管理** | 上游 | 商品 **归属当前店铺**,创建后 **不可换店** |
68
+| **店铺设置** | 策略 | **商品默认审核通过** 决定提交上架后进入 **待审核** 或 **出售中** |
69
+| **商品分类(平台文档)** | 发品必选 | 商品须挂 **本店二级「商品分类」** |
70
+| **店铺商品分类** | 发品可选/并列字段 | 发品时 **「店铺商品分类」** 数据源来自该模块 |
71
+| **商品服务管理** | 发品多选 | 勾选平台服务目录项;保存时生成 **展示快照** |
72
+| **商品审核(平台)** | 下游协作 | 待审核 → 平台审;出售中 → 平台/商家均可下架 |
73
+| **订单管理** | 下架约束 | 草稿要求下架前订单须完结;见 §10.2 |
74
+
75
+### 1.4 使用端与角色
76
+
77
+| 端 | 可操作角色 | 能力 |
78
+|----|------------|------|
79
+| **店铺经营管理端** | **商户经营账号** | 本模块全部能力(含切换店铺后操作对应店商品) |
80
+| **店铺经营管理端** | 员工(子管理员) | 是否可访问由 **角色管理** 中商家端菜单权限决定 |
81
+| **平台管理端** | 平台管理员 | **不使用** 本模块;在 **商品审核/商品管理** 监管 |
82
+| **C 端** | 买家/访客 | **不可** 直接访问;仅消费 **出售中** 等可售结果 |
83
+
84
+### 1.5 数据范围
85
+
86
+- **纳入:** 当前 **所属店铺** 下全部 **未逻辑删除** 的商品;
87
+- **排除:** 其他店铺商品;已逻辑删除商品;
88
+- **上下文:** 页头展示 **当前店铺名称**(只读);切换店铺后列表 **整页刷新**。
89
+
90
+---
91
+
92
+## 2. 关联需求分析
93
+
94
+### 2.1 与《关联需求分析》— 供给链
95
+
96
+| 关联点 | 定稿 |
97
+|--------|------|
98
+| **§3 模块职责** | 商家在本模块 **发品与状态流转**;平台在 **商品审核** **监管** |
99
+| **§5.1 开业流程** | 须 **先选当前店铺**,再维护分类并发品 |
100
+| **§5.4 五态** | 本模块与平台 **共用** 同一套状态机,**不得** 另立规则 |
101
+| **§6.2 S-P1~S-P5** | 默认审核策略、停业不自动下架、删店前置、商品不可换店 |
102
+| **§6.3 C-P1** | 商品 **仅挂本店二级商品分类** |
103
+| **§6.5 GS-P1~P9** | 服务目录全平台共用;保存写快照;改目录不追溯 |
104
+| **§8 不级联** | 店铺停业、分类隐藏、服务目录变更 **不自动** 改商品状态 |
105
+| **§9.1 经营账号** | 登录后 **切换当前店铺** 再操作本模块 |
106
+
107
+### 2.2 与平台《商品审核功能需求》
108
+
109
+| 项 | 商家端(本模块) | 平台端 |
110
+|----|------------------|--------|
111
+| 列表可见 **未上架** | **是**(草稿) | **否** |
112
+| **待审核** 编辑 | **允许**(P14;草稿 §5(2) 与之冲突,以 **P14** 为准) | 只读详情 + 审核 |
113
+| **出售中** 编辑 | **允许**(关联分析 §8;资料可变、状态不变) | 只读 + 下架 |
114
+| 审核驳回原因 | **详情可见**,便于修改后重提 | 必填 |
115
+| 批量审核/下架 | **不涉及** | 整批失败策略 |
116
+
117
+### 2.3 与平台《商品分类功能需求》
118
+
119
+| 项 | 定稿 |
120
+|----|------|
121
+| 发品字段「商品分类」 | 必选 **本店二级分类**;不可挂一级 |
122
+| 分类下拉范围 | 仅 **当前店铺**、**未删除** 分类 |
123
+| 删分类 | 有关联商品则 **不可删**(分类模块规则);商家须先改商品分类 |
124
+
125
+### 2.4 与《店铺商品分类功能需求》
126
+
127
+| 项 | 定稿 |
128
+|----|------|
129
+| 发品字段「店铺商品分类」 | 数据源来自 **店铺商品分类** 模块;**仅可选本店二级**(展示「一级 > 二级」) |
130
+| 与「商品分类」关系 | **并列、独立** 字段;互不影响校验 |
131
+| 删除协作 | **二级** 下有商品则 **不可删**;删 **一级** 须全部下属二级均无商品 |
132
+
133
+### 2.5 与《商品服务管理功能需求》
134
+
135
+| 项 | 定稿 |
136
+|----|------|
137
+| 发品勾选 | 多选平台 **未删除** 服务项;「默认显示 = 是」的项 **默认勾选**,可取消 |
138
+| 展示快照 | **保存商品** 时写入名称、简介、图标快照 |
139
+| 平台删服务 | C 端不展示已删项;商家 **再次保存** 时自动剔除 |
140
+| 改服务文案 | **不自动** 更新已保存商品的展示 |
141
+
142
+### 2.6 与《店铺管理》《店铺设置》
143
+
144
+| 项 | 定稿 |
145
+|----|------|
146
+| 店铺停业 | 商家端 **仍可** 维护商品;C 端该店 **禁止下单** |
147
+| 默认审核通过 | **全局** 配置(店铺设置);**关闭**(默认)→ 提交上架进 **待审核**;**开启** → 直接 **出售中** |
148
+| 修改审核开关 | **不追溯** 已有商品;仅影响 **此后** 新提交上架 |
149
+
150
+### 2.7 与《角色管理》《员工管理》— 权限
151
+
152
+| 项 | 定稿 |
153
+|----|------|
154
+| 菜单权限 | 本模块对应商家端「商品列表」等菜单;由 **角色管理** 配置 |
155
+| 经营账号 | 默认具备商家端全部菜单 |
156
+| 无权限 | 不可见菜单;直接访问须拒绝 |
157
+
158
+---
159
+
160
+## 3. 业务概念
161
+
162
+| 概念 | 说明 |
163
+|------|------|
164
+| **当前店铺** | 登录会话内选定的店铺;本模块全部操作均限定于此 |
165
+| **商品编号** | 系统生成、**全平台唯一**;列表与检索主键之一 |
166
+| **未上架** | 草稿称「待上架」;保存商品后的 **草稿态**,仅商家端可见 |
167
+| **待审核** | 商家 **提交上架** 后、平台未处理;须等平台审核(免审店除外) |
168
+| **出售中** | 审核通过或免审直达;C 端在满足其他条件时可售 |
169
+| **审核失败** | 平台驳回;须查看 **驳回原因** 后修改重提 |
170
+| **已下架** | 商家或平台将 **出售中** 商品下架后的状态 |
171
+| **提交上架** | 将未上架/审核失败/已下架商品 **送入** 审核或直接出售流程的 **独立动作**(非编辑保存) |
172
+| **商品分类** | 平台文档中的 **本店二级分类**;发品 **必选** |
173
+| **店铺商品分类** | 本店 **店铺商品分类** 模块 **二级** 数据;发品 **可选**(是否必填以原型为准) |
174
+| **展示快照** | 商品已选 **商品服务** 项在保存时的名称、简介、图标副本 |
175
+
176
+### 3.1 术语对照(草稿 → 定稿)
177
+
178
+| 草稿用语 | 定稿用语 | 说明 |
179
+|----------|----------|------|
180
+| 待上架 | **未上架** | 与平台、关联分析一致 |
181
+| 上架 | **提交上架** | 强调是状态流转动作,非简单保存 |
182
+
183
+---
184
+
185
+## 4. 功能结构
186
+
187
+```text
188
+商品列表(店铺 · 商品管理)
189
+├── 商品列表(当前店铺、分页)
190
+├── 高级检索
191
+├── 查看详情(全状态)
192
+├── 添加商品
193
+├── 编辑商品
194
+├── 提交上架(单独 / 批量)
195
+├── 下架商品(单独 / 批量)
196
+└── 删除商品(单独 / 批量)
197
+```
198
+
199
+---
200
+
201
+## 5. 商品列表
202
+
203
+### 5.1 列表字段(对齐草稿 §1)
204
+
205
+| 字段 | 说明 |
206
+|------|------|
207
+| 商品编号 | 系统生成,全平台唯一 |
208
+| 商品主图 | 缩略图 |
209
+| 商品名称 | — |
210
+| 售价 | 首期 **单规格** 销售价 |
211
+| 销量 | 累计销量 |
212
+| 商品状态 | 未上架 / 待审核 / 出售中 / 审核失败 / 已下架 |
213
+| 操作 | 见 §5.3 |
214
+
215
+**建议扩展列(非草稿必列):** 库存、商品分类(一级 > 二级)、店铺商品分类(一级 > 二级)、提交上架时间。
216
+
217
+### 5.2 列表行为
218
+
219
+| 规则 | 说明 |
220
+|------|------|
221
+| 数据范围 | **仅当前店铺** 下未删除商品 |
222
+| 分页 | 支持 |
223
+| 默认排序 | 建议按 **更新时间降序**;**待审核** Tab 可按 **提交上架时间升序**(先报先审) |
224
+| 状态筛选 | 支持按状态 Tab 或下拉筛选 **五种状态** |
225
+| 店铺上下文 | 页头展示 **当前店铺名称**;切换店铺后 **整页刷新** |
226
+
227
+### 5.3 行操作(按状态)
228
+
229
+| 商品状态 | 可用操作 |
230
+|----------|----------|
231
+| 未上架 | 查看详情、编辑、**提交上架**、删除 |
232
+| 待审核 | 查看详情、**编辑**(P14)、— |
233
+| 出售中 | 查看详情、编辑、**下架** |
234
+| 审核失败 | 查看详情、编辑、**提交上架**、删除 |
235
+| 已下架 | 查看详情、编辑、**提交上架**、删除 |
236
+
237
+支持 **多选** 以触发批量 **提交上架**、**下架**、**删除**(须满足各节状态与校验规则)。
238
+
239
+---
240
+
241
+## 6. 高级检索
242
+
243
+> 对齐草稿 §3。
244
+
245
+| 检索项 | 规则 |
246
+|--------|------|
247
+| 商品编号 | 精确或模糊(与平台统一) |
248
+| 商品名称 | 模糊匹配 |
249
+| 商品分类 | 选择 **二级分类** 或展示「一级 > 二级」路径 |
250
+
251
+| 行为 | 说明 |
252
+|------|------|
253
+| 查询 | 条件 **与** 组合;结果分页;范围仍限定 **当前店铺** |
254
+| 重置 | 清空条件并恢复默认列表 |
255
+
256
+**可选扩展:** 按 **店铺商品分类**、商品状态筛选(列表 Tab 已覆盖状态时可不再重复)。
257
+
258
+---
259
+
260
+## 7. 查看详情
261
+
262
+> 对齐草稿:全部商品均可查看详情。
263
+
264
+### 7.1 展示内容
265
+
266
+| 类别 | 内容 |
267
+|------|------|
268
+| 基础信息 | 编号、名称、主图/详情图、售价、库存、销量、重量、条码、关键词、简述等 |
269
+| 分类 | **商品分类**(一级 > 二级)、**店铺商品分类**(一级 > 二级,若有) |
270
+| 规格与运费 | 销售规格(统一/多规格)、规格明细(市场价、库存);快递运费(固定/模版) |
271
+| 属性 | 基于 **属性模版** 扩展的属性项、规格项及其值 |
272
+| 详情内容 | 图文详情(图片块 + 文本块) |
273
+| 服务快照 | 已勾选 **商品服务** 项的快照(只读) |
274
+| 状态信息 | 当前状态;**待审核/审核失败** 展示提交时间、审核时间(若有)、**驳回原因** |
275
+| 操作区 | 与列表行操作 **一致**(按状态启用) |
276
+
277
+### 7.2 边界
278
+
279
+- 详情 **不提供** 直接修改状态(须通过 **提交上架 / 下架** 等专用动作)。
280
+- 详情 **不维护** 平台服务目录、平台分类树。
281
+
282
+---
283
+
284
+## 8. 添加商品
285
+
286
+> 对齐草稿 §2。
287
+
288
+### 8.1 填写项概览
289
+
290
+| 分组 | 字段 | 必填 | 说明 |
291
+|------|------|:----:|------|
292
+| 基础 | 商品编号 | — | **系统生成**,创建后展示 |
293
+| 基础 | 商品图片 | 是 | **多张**;首张或指定一张为主图 |
294
+| 基础 | 商品名称 | 是 | — |
295
+| 分类 | 商品分类 | 是 | **本店二级分类** |
296
+| 分类 | 店铺商品分类 | 视产品 | **本店二级**;来自 **店铺商品分类** 模块 |
297
+| 基础 | 商品重量 | 视产品 | — |
298
+| 基础 | 商品条码 | 否 | — |
299
+| 基础 | 搜索关键词 | 否 | — |
300
+| 基础 | 商品简述 | 视产品 | — |
301
+| 属性 | 属性模版 | 视产品 | 在模版基础上 **可增删** 属性项、属性值、规格项、规格值 |
302
+| 销售 | 销售规格 | 是 | **统一规格 / 多规格** |
303
+| 销售 | 规格明细 | 是 | 每种规格:**市场价、库存**(首期单规格时一行) |
304
+| 物流 | 快递运费 | 是 | **固定运费 / 运费模版** |
305
+| 详情 | 商品详情 | 是 | **添加图片 / 添加文本** 组合 |
306
+| 服务 | 服务说明 | 否 | 多选平台服务项(如 24 小时发货、7 天无理由退换货等) |
307
+
308
+### 8.2 保存后状态
309
+
310
+```text
311
+填写表单 → 保存
312
+    → 校验通过
313
+    → 商品状态 = 【未上架】
314
+    → 返回列表,可继续编辑或提交上架
315
+```
316
+
317
+### 8.3 前置依赖
318
+
319
+| 前置 | 说明 |
320
+|------|------|
321
+| 当前店铺有效 | 停业店仍可发品;**已逻辑删除** 店铺不可用 |
322
+| 商品分类 | 须已维护 **本店二级分类**(至少一条可选) |
323
+| 商品服务 | 平台已配置目录则可选;无目录时服务区域为空 |
324
+| 属性模版 | 若启用模版能力,须已有可选模版(**非本期** 则手工维护属性) |
325
+
326
+---
327
+
328
+## 9. 编辑商品
329
+
330
+> 对齐草稿 §5(4);与平台 P14、关联分析 §8 对齐。
331
+
332
+### 9.1 可编辑状态
333
+
334
+| 状态 | 是否可编辑 | 说明 |
335
+|------|:----------:|------|
336
+| 未上架 | ✓ | 草稿编辑 |
337
+| 待审核 | ✓ | 保存后 **仍为待审核**,不自动通过(P14) |
338
+| 出售中 | ✓ | 资料可变,**状态仍为出售中** |
339
+| 审核失败 | ✓ | 可改后 **提交上架** |
340
+| 已下架 | ✓ | 可改后 **提交上架** |
341
+
342
+> **定稿说明:** 草稿 §5(2)「上架后不支持编辑」以 **平台 P14** 及 **关联分析** 为准调整为:**待审核、出售中均可编辑**;**删除** 仍按 §11 状态限制。
343
+
344
+### 9.2 不可通过编辑变更的内容
345
+
346
+| 项 | 说明 |
347
+|----|------|
348
+| 商品编号 | 系统生成,**不可改** |
349
+| 归属店铺 | **不可换店**(S-P5) |
350
+| 商品状态 | **不可** 在编辑保存中直接改为出售中/未上架等;须走 **提交上架 / 下架** |
351
+
352
+### 9.3 保存后对服务快照
353
+
354
+- 修改服务勾选后 **再次保存** → 刷新 **展示快照**;
355
+- 已逻辑删除的平台服务项 → **自动剔除**(P21)。
356
+
357
+---
358
+
359
+## 10. 提交上架
360
+
361
+> 对齐草稿 §5(2);对应关联分析「提交上架」动作。
362
+
363
+### 10.1 方式
364
+
365
+| 方式 | 说明 |
366
+|------|------|
367
+| 单独提交 | 列表行或详情 |
368
+| 批量提交 | 勾选多条 **未上架 / 审核失败 / 已下架** |
369
+
370
+### 10.2 前置与校验
371
+
372
+| 校验 | 失败提示(示例) |
373
+|------|------------------|
374
+| 含 **待审核 / 出售中** | 所选商品含不可提交状态,请重新选择(**整批失败**) |
375
+| 资料不完整 | 请完善必填项后再提交上架 |
376
+| 未勾选任何行 | 请选择要提交的商品 |
377
+
378
+### 10.3 提交后状态流转
379
+
380
+```text
381
+商家:提交上架
382
+    │
383
+    ├── 店铺「默认审核通过」= 开启 ──►【出售中】
384
+    │
385
+    └── 店铺「默认审核通过」= 关闭 ──►【待审核】
386
+                │
387
+                ├── 平台:审核通过 ──►【出售中】
388
+                └── 平台:审核驳回 ──►【审核失败】(须驳回原因)
389
+```
390
+
391
+| 项 | 说明 |
392
+|----|------|
393
+| 首次提交时间 | 记录 **提交上架时间**;待审核排序可参考该时间 |
394
+| 再次提交 | 审核失败/已下架修改后 **重新提交**,仍受 **免审策略** 约束 |
395
+| 待审核期间编辑 | 允许;保存后 **仍为待审核**(P14) |
396
+
397
+### 10.4 提交上架流程
398
+
399
+```text
400
+选择未上架 / 审核失败 / 已下架商品
401
+    → 点击「提交上架」(单独或批量)
402
+    → 校验状态与资料完整性
403
+    ├── 含非法状态 → 整批失败
404
+    └── 通过 → 按店铺审核策略进入「待审核」或「出售中」
405
+```
406
+
407
+---
408
+
409
+## 11. 下架商品
410
+
411
+> 对齐草稿 §5(3)。
412
+
413
+### 11.1 方式
414
+
415
+| 方式 | 说明 |
416
+|------|------|
417
+| 单独下架 | 列表行或详情 |
418
+| 批量下架 | 勾选多条 **出售中** |
419
+
420
+### 11.2 规则
421
+
422
+| 规则 | 说明 |
423
+|------|------|
424
+| 前置状态 | 仅 **出售中** |
425
+| 结果状态 | **已下架** |
426
+| 订单约束(草稿) | 该商品 **相关订单全部完成后** 方可下架;存在 **未完成订单** 时 **阻断** 并提示 |
427
+| 平台权限 | 平台亦可在 **商品审核** 模块下架;下架后商家可编辑、重新提交上架 |
428
+| 批量含非法状态 | **整批失败** |
429
+| 确认 | 建议二次确认:「下架后 C 端不可购买」 |
430
+
431
+> **未完成订单** 语义与 **《订单管理功能需求》O10** 一致:待支付、待发货、已发货;**已关闭、已完成** 不属于阻塞下架的未完成订单(若产品确认草稿「全部完成」指 **无 O10 订单**,则与此一致)。
432
+
433
+### 11.3 下架后
434
+
435
+| 项 | 说明 |
436
+|----|------|
437
+| 商家 | 可 **编辑**;可 **重新提交上架** |
438
+| 已有订单 | **不自动** 关闭(订单模块规则) |
439
+| C 端 | 不可新下单该商品 |
440
+
441
+### 11.4 下架流程
442
+
443
+```text
444
+选择「出售中」商品 → 下架
445
+    → 校验是否存在未完成订单(草稿)
446
+    → 校验状态
447
+    ├── 含非出售中 / 有未完成订单 → 整批失败或单独阻断
448
+    └── 通过 → 二次确认 → 已下架
449
+```
450
+
451
+---
452
+
453
+## 12. 删除商品
454
+
455
+> 对齐草稿 §5(5)。
456
+
457
+### 12.1 可删除状态
458
+
459
+| 状态 | 可删除 |
460
+|------|:------:|
461
+| 未上架 | ✓ |
462
+| 待审核 | **否**(须等平台审完或 **平台驳回** 后再删;或产品改为须先撤回——**非草稿**,本期 **不可删**) |
463
+| 出售中 | **否** |
464
+| 审核失败 | ✓ |
465
+| 已下架 | ✓ |
466
+
467
+> **定稿说明:** 草稿未明确 **待审核** 可否删;与平台监管衔接,**待审核、出售中不可删**;须先 **驳回/下架** 再处理。
468
+
469
+### 12.2 方式与校验
470
+
471
+| 方式 | 说明 |
472
+|------|------|
473
+| 单独删除 | 行操作 |
474
+| 批量删除 | 勾选多条;含 **不可删状态** → **整批失败** |
475
+
476
+```text
477
+选择可删状态商品 → 删除
478
+    → 校验状态
479
+    ├── 含待审核/出售中等 → 整批失败
480
+    └── 通过 → 二次确认 → 逻辑删除
481
+```
482
+
483
+---
484
+
485
+## 13. 商品状态与流转(定稿)
486
+
487
+> 与 **《关联需求分析》§5.4**、**《商品审核功能需求》§3** **一致**。
488
+
489
+```text
490
+【保存商品】────────────────────────────►【未上架】
491
+                                              │
492
+                                    【提交上架】
493
+                                              │
494
+                    ┌─────────────────────────┴─────────────────────────┐
495
+                    │                                                   │
496
+         默认审核 = 开                                         默认审核 = 关
497
+                    │                                                   │
498
+                    ▼                                                   ▼
499
+              【出售中】◄──── 平台审核通过 ────【待审核】──── 平台驳回 ────►【审核失败】
500
+                    │                              ▲                           │
501
+                    │         商家编辑(P14)          │                           │
502
+                    │         仍为待审核             │                           │
503
+                    │                              │                           │
504
+                    └──── 商家/平台:下架 ────►【已下架】◄──────────────────────┘
505
+                                                      │
506
+                                              【编辑 + 提交上架】
507
+```
508
+
509
+| 操作 | 前置状态 | 结果状态 | 执行方 |
510
+|------|----------|----------|--------|
511
+| 保存商品(新建) | — | 未上架 | 商家 |
512
+| 提交上架 | 未上架 / 审核失败 / 已下架 | 待审核 或 出售中 | 商家 |
513
+| 审核通过 | 待审核 | 出售中 | **平台** |
514
+| 审核驳回 | 待审核 | 审核失败 | **平台** |
515
+| 下架 | 出售中 | 已下架 | 商家 / 平台 |
516
+| 编辑保存 | 见 §9.1 | **状态不变** | 商家 |
517
+| 删除 | 未上架 / 审核失败 / 已下架 | 逻辑删除 | 商家 |
518
+
519
+**刚性约束(P17):** 状态 **只能** 通过「提交上架、平台审核、下架」变更;编辑保存 **不得** 直接改为出售中,也 **不得** 改回未上架。
520
+
521
+---
522
+
523
+## 14. 店铺上下文(协作规则,对齐草稿 §6、§7)
524
+
525
+```text
526
+商户经营账号 / 员工 ── 登录商家端
527
+            ↓
528
+    解析当前店铺(会话内记住上次所选店铺)
529
+            ↓
530
+    页头展示当前店铺名称;后续请求携带当前店铺标识
531
+            ↓
532
+    商品列表 / 发品 / 操作 ── 仅作用于当前店铺商品
533
+            ↓
534
+    切换店铺 → 更新当前店铺 → 列表整页刷新
535
+```
536
+
537
+| 规则 | 说明 |
538
+|------|------|
539
+| 员工账号 | 绑定 **单一店铺**,**不可** 切换 |
540
+| 经营账号 | 可管理 **同商户多店**;须 **先选店** 再操作 |
541
+| 默认店铺 | 经营账号登录后默认 **该商户最早创建的店铺** |
542
+| 记住选择 | **同一会话** 内记住上次所选店铺;刷新后 **仍为所选店** |
543
+| 未选店铺 | **不可** 操作商品列表(须先完成店铺上下文初始化) |
544
+
545
+---
546
+
547
+## 15. 与关联模块的协作流程
548
+
549
+### 15.1 发品完整链路
550
+
551
+```text
552
+【平台】配置商品服务目录(可选,建议先发品前完成)
553
+【平台】维护平台商品分类树;商家维护本店二级「商品分类」
554
+【商家】维护「店铺商品分类」(可选)
555
+            ↓
556
+【商家】商品列表 → 添加商品 → 保存(未上架)
557
+            ↓
558
+【商家】提交上架
559
+            ↓
560
+【平台】商品审核(待审核时)→ 通过/驳回
561
+            ↓
562
+【C 端】出售中且满足可购条件 → 展示商品与服务快照
563
+```
564
+
565
+### 15.2 删店与商品
566
+
567
+| 条件 | 说明 |
568
+|------|------|
569
+| 阻塞删店 | 存在 **出售中** 或 **待审核** 商品(关联分析 §7.2) |
570
+| 不阻塞 | **未上架、已下架、审核失败** 可不挡删店 |
571
+| 对本模块 | 商家须先 **下架/处理待审** 后再由平台删店 |
572
+
573
+### 15.3 店铺停业
574
+
575
+| 项 | 行为 |
576
+|----|------|
577
+| 商家端 | **仍可** 维护商品、提交上架 |
578
+| C 端 | 该店 **禁止下单**;商品状态 **不变** |
579
+
580
+---
581
+
582
+## 16. 业务规则汇总
583
+
584
+| 编号 | 规则 |
585
+|------|------|
586
+| **GL1** | 列表与全部操作范围 = **当前店铺** 下未删除商品 |
587
+| **GL2** | 商品 **五态**:未上架、待审核、出售中、审核失败、已下架;与平台 **同源** |
588
+| **GL3** | 新建保存 → **未上架**;**提交上架** 方进入审核/出售流程 |
589
+| **GL4** | 提交上架:仅 **未上架 / 审核失败 / 已下架**;批量含非法状态 → **整批失败** |
590
+| **GL5** | 店铺「默认审核通过」= **开** → 提交后直接 **出售中**;= **关** → **待审核** |
591
+| **GL6** | **待审核** 期间允许 **编辑**,保存后 **仍为待审核**(P14) |
592
+| **GL7** | **出售中** 允许 **编辑** 资料,状态 **不变** |
593
+| **GL8** | 下架:仅 **出售中**;草稿要求 **无未完成订单**(O10)方可下架 |
594
+| **GL9** | 删除:仅 **未上架 / 审核失败 / 已下架**;**待审核、出售中不可删** |
595
+| **GL10** | 批量提交上架 / 下架 / 删除:**整批失败** 策略与平台一致 |
596
+| **GL11** | 商品 **仅挂本店二级商品分类**;**店铺商品分类** 为并列字段,**仅挂本店店铺商品二级** |
597
+| **GL12** | 保存商品时写入 **服务展示快照**;改平台目录 **不追溯** |
598
+| **GL13** | 状态 **仅** 经提交上架、平台审核、下架变更(P17) |
599
+| **GL14** | 商户/店铺/分类/服务目录变更 **不自动** 改商品状态 |
600
+| **GL15** | 须携带 **当前店铺上下文**;切换店铺后数据范围随之变化 |
601
+| **GL16** | 商品创建后 **不可换店** |
602
+| **GL17** | **任意状态** 均可 **查看详情**;审核失败须展示 **驳回原因** |
603
+
604
+---
605
+
606
+## 17. 页面与交互要点
607
+
608
+| 场景 | 要求 |
609
+|------|------|
610
+| 页头 | 固定展示 **当前店铺名称**;经营账号可 **切换店铺** |
611
+| 状态 Tab | 建议 Tab:全部 / 未上架 / 待审核 / 出售中 / 审核失败 / 已下架 |
612
+| 待审核角标 | 可选展示待审数量 |
613
+| 批量操作栏 | 勾选后按状态启用「批量提交上架」「批量下架」「批量删除」 |
614
+| 提交上架 | 与「保存」区分按钮;成功提示目标状态(待审核/出售中) |
615
+| 下架确认 | 二次确认;若有未完成订单则 **明确提示** |
616
+| 删除确认 | 二次确认 |
617
+| 驳回原因 | 审核失败详情 **醒目展示** |
618
+| 空态 | 无商品时引导「添加商品」 |
619
+| 权限 | 无菜单权限 **不可** 见入口 |
620
+
621
+---
622
+
623
+## 18. 非本期范围
624
+
625
+| 项 | 说明 |
626
+|----|------|
627
+| 属性模版 **维护** | 仅 **选用**;模版 CRUD 单独立项 |
628
+| 运费模版 **维护** | 假定平台或它模块已提供可选模版 |
629
+| 多规格 SKU 完整能力 | 草稿含多规格字段;复杂 SKU 以商品管理全模块为准 |
630
+| 平台代商家改价/改库存 | 平台侧能力 |
631
+| 会员价、营销活动 | 全项目不考虑会员体系 |
632
+| 评价管理 | 见 **评价管理**(待建设) |
633
+| 异常返回 code/msg/data | 实现层 |
634
+| 技术栈 | 实现层 |
635
+
636
+---
637
+
638
+## 19. 草稿对照与修订说明
639
+
640
+| 草稿条目 | 本文档处理 |
641
+|----------|------------|
642
+| §1 列表五字段 | §5.1;补 **状态** 列 |
643
+| §2 添加商品大表单 | §8 结构化;服务/分类/快照协作见 §2 |
644
+| §3 检索三项 | §6 |
645
+| §4 五状态 | §3、§12、§13;「待上架」→ **未上架** |
646
+| §5(1) 查看详情 | §7 |
647
+| §5(2) 上下架与审核 | §10、§11;**待审核可编辑** 依 P14 修正草稿 |
648
+| §5(3) 下架订单约束 | §11.2 |
649
+| §5(4) 编辑范围 | §9;**扩展出售中可编辑** |
650
+| §5(5) 删除范围 | §12;**补充待审核/出售中不可删** |
651
+| §6~§7 店铺范围与上下文 | §5.2、§13、§14 |
652
+| §8~§9 | **不纳入** |
653
+| 未写:平台免审、服务快照、分类边界 | §2、§8、§10 |
654
+| 未写:与商品审核分工 | §1、§2.2、§12 |
655
+
656
+---
657
+
658
+## 20. 修订记录
659
+
660
+| 版本 | 说明 |
661
+|------|------|
662
+| **v1.0** | 首版定稿:店铺商品列表/检索/发品/状态流转;对齐平台五态与关联分析;补店铺上下文与服务/分类协作 |
663
+| **v1.1** | 对齐《店铺商品分类功能需求》v1.1:店铺商品分类为 **两级**,发品 **仅挂二级** |
664
+
665
+---
666
+
667
+*文档版本:v1.1 · 关联《关联需求分析.md》v1.5、《商品审核功能需求.md》v1.0、《商品分类功能需求.md》v1.4、《商品服务管理功能需求.md》v1.0.1、《店铺商品分类功能需求.md》v1.1 · 草稿《商品列表功能需求-草稿.md》保持不变。*

+ 515 - 0
doc/店铺后台/商品管理/商品列表/店铺商品列表技术方案.md

@@ -0,0 +1,515 @@
1
+# 店铺商品列表 — 技术方案
2
+
3
+> **依据:** 《商品列表功能需求.md》v1.0  
4
+> **关联:** 《关联需求分析.md》v1.5;平台《商品审核技术方案》v1.0、《商品分类技术方案》v1.2、《商品服务管理技术方案》v1.0.1;商家《店铺商品分类技术方案》(`biz_goods_category` 本店二级)  
5
+> **范围:** 商家端 **当前店铺** 商品列表、检索、发品、编辑、提交上架、下架、删除;**复用** 平台商品主表与状态机,**不另建** 商家商品表。  
6
+> **原则:** `goods_status` 仅经 submit / audit / offShelf 变更(P17);`X-Shop-Id` 店铺上下文;批量含非法状态 **整批失败**。
7
+
8
+---
9
+
10
+## 1. 技术架构
11
+
12
+| 项 | 选型 |
13
+|----|------|
14
+| 基础框架 | RuoYi **v3.9.2**(`springboot2` 分支) |
15
+| 数据库 | **MySQL 5.7.39** |
16
+| ORM / 权限 | MyBatis;`@PreAuthorize`;`AjaxResult` / `TableDataInfo` |
17
+| 店铺上下文 | `SellerShopContextInterceptor` + 请求头 **`X-Shop-Id`**;会话内记住所选店铺(Redis token) |
18
+| 编号 | Redis 自增 `agri:goods:sn:{yyyyMMdd}` |
19
+| 日志 | 增删改、提交上架、下架 `@Log` |
20
+
21
+### 1.1 与平台侧边界
22
+
23
+| 维度 | 平台 · 商品审核/管理 | 本模块 · 商家商品列表 |
24
+|------|----------------------|----------------------|
25
+| 表 | **`biz_goods` 同源** | 同表,`shop_id` 限定当前店 |
26
+| 状态机 | `IGoodsService.auditGoods` / `offShelfPlatform` | `submitGoods` / `offShelfSeller` |
27
+| 列表范围 | `goods_status <> '0'` | **含未上架(0)** 五态全展示 |
28
+| 路径 | `/agri/goods` | **`/agri/seller/goods`** |
29
+| 权限前缀 | `agri:goods:*` | **`agri:seller:goods:*`** |
30
+
31
+> **定稿:** 商家端与平台 **同一套** `IGoodsService` 实现,避免双轨状态逻辑(对齐《商品审核技术方案》§1)。
32
+
33
+### 1.2 业务链
34
+
35
+```text
36
+GET /agri/seller/context          → 前端缓存 shopId(X-Shop-Id)
37
+        ↓
38
+biz_shop_global_config.default_audit_pass
39
+        ↓
40
+biz_goods(shop_id = 当前店铺)
41
+        ├── 保存 POST/PUT           → status=0 未上架
42
+        ├── 提交上架 PUT .../submit → status=1 或 2
43
+        ├── 平台 audit(/agri/goods/audit)→ 1→2|3
44
+        └── 下架 PUT .../offShelf     → 2→4
45
+        ↓
46
+biz_goods_service_snapshot(保存商品时写快照)
47
+        ↓
48
+biz_goods_category
49
+        ├── category_id      → shop_id IS NULL 的二级(平台「商品分类」)
50
+        └── shop_category_id → shop_id = 当前店 的二级(「店铺商品分类」)
51
+```
52
+
53
+| 关联模块 | 协作 |
54
+|----------|------|
55
+| **商品审核** | 商家 submit 后进入平台待审队列;驳回原因商家详情可读 |
56
+| **商品分类** | `category_id` ← `ICategoryFacade.listPlatformLevel2Options()` |
57
+| **店铺商品分类** | `shop_category_id` ← `IShopGoodsCategoryFacade.listOptionsByShopId()` |
58
+| **商品服务** | 发品多选 ← `IGoodsServiceFacade`;保存写快照 |
59
+| **店铺设置** | `IShopGlobalConfigFacade.getDefaultAuditPass()` 决定 submit 目标态 |
60
+| **订单管理** | 下架前校验 **O10 未完成订单**(待实现,`IOrderFacade`) |
61
+| **店铺管理** | `IGoodsFacade.hasBlockingGoodsForShopDelete` 删店前置 |
62
+
63
+### 1.3 模块落位
64
+
65
+```text
66
+baqing-shop/src/main/java/com/ruoyi/web/modules/goods/
67
+├── controller/SellerGoodsController.java      # /agri/seller/goods(本方案)
68
+├── controller/GoodsController.java            # 平台监管(已实现)
69
+├── controller/GoodsAuditController.java       # 平台审核菜单(可选薄封装)
70
+├── service/IGoodsService.java
71
+├── service/impl/GoodsServiceImpl.java
72
+├── domain/BizGoods.java
73
+├── dto/GoodsSaveDTO.java
74
+├── dto/GoodsSubmitBatchDTO.java               # 待实现 · 批量提交
75
+├── dto/GoodsOffShelfDTO.java                  # 复用 · 批量下架
76
+├── dto/GoodsDeleteDTO.java                    # 待实现 · 批量删除
77
+├── mapper/BizGoodsMapper.java
78
+├── support/GoodsSnGenerator.java
79
+├── support/GoodsStatusUtils.java
80
+├── facade/IGoodsFacade.java                   # 删店/分类删校验
81
+└── constant/GoodsConstants.java
82
+
83
+resources/mapper/goods/BizGoodsMapper.xml
84
+sql/biz_goods.sql
85
+sql/biz_goods_service_snapshot.sql
86
+sql/biz_goods_shop_category_id.sql             # shop_category_id 增量 DDL
87
+sql/agri_seller_goods_menu.sql                 # 商家菜单
88
+```
89
+
90
+**店铺上下文(已有):** `com.ruoyi.web.modules.store` → `SellerShopContextController`(`/agri/seller/context`)。
91
+
92
+---
93
+
94
+## 2. 数据库设计
95
+
96
+### 2.1 表复用与分工
97
+
98
+| 表名 | 本模块用途 |
99
+|------|------------|
100
+| **`biz_goods`** | 商品主表;商家 CRUD + 状态字段 |
101
+| **`biz_goods_service_snapshot`** | 发品勾选服务的 **展示快照** |
102
+| `biz_goods_category` | join 分类路径;**不** 由本模块维护 |
103
+| `biz_shop` | 店铺上下文、删店 join |
104
+| `biz_shop_global_config` | 全局默认审核开关 |
105
+
106
+**无商家独立商品表。**
107
+
108
+### 2.2 `biz_goods` 字段(本模块相关)
109
+
110
+| 字段 | 类型 | 说明 |
111
+|------|------|------|
112
+| goods_id | bigint PK | |
113
+| shop_id | bigint NOT NULL | **创建时写入当前店铺**;不可 UPDATE 换店 |
114
+| category_id | bigint NOT NULL | **平台二级分类**(`biz_goods_category`,`shop_id IS NULL`) |
115
+| shop_category_id | bigint NULL | **店铺商品分类**(`biz_goods_category` 本店二级);可空 |
116
+| goods_sn | varchar(32) UK | Redis 生成,全平台唯一 |
117
+| goods_name | varchar(200) | |
118
+| main_pic | varchar(512) | 主图 URL |
119
+| detail_content | text | 详情(首期 JSON/HTML 字符串) |
120
+| sale_price | decimal(10,2) | **首期单规格** 售价 |
121
+| stock | int | **首期单规格** 库存 |
122
+| sales_count | int DEFAULT 0 | 销量(订单模块回写,本模块只读) |
123
+| goods_status | char(1) | **0** 未上架 **1** 待审核 **2** 出售中 **3** 审核失败 **4** 已下架 |
124
+| reject_reason | varchar(500) | 平台驳回原因 |
125
+| submit_time | datetime | 首次 submit 时间 |
126
+| audit_time | datetime | 审核时间 |
127
+| off_shelf_time | datetime | 下架时间 |
128
+| del_flag | char(1) | 0 存在 2 逻辑删除 |
129
+| create_by / create_time / update_by / update_time | | 审计 |
130
+
131
+**首期未落库、后续扩展(需求 §8 完整表单):** 多图、重量、条码、关键词、简述、多规格 SKU、运费模版、属性项等 → 见 §2.5,**不阻塞 v1.0 列表/单规格发品**。
132
+
133
+### 2.3 增量 DDL
134
+
135
+```sql
136
+-- sql/biz_goods_shop_category_id.sql
137
+ALTER TABLE `biz_goods`
138
+  ADD COLUMN `shop_category_id` bigint(20) DEFAULT NULL COMMENT '店铺商品分类ID(本店二级 biz_goods_category)' AFTER `category_id`,
139
+  ADD KEY `idx_shop_category_id` (`shop_category_id`, `del_flag`);
140
+```
141
+
142
+完整建表见 `sql/biz_goods.sql`。
143
+
144
+### 2.4 `biz_goods_service_snapshot`
145
+
146
+| 字段 | 说明 |
147
+|------|------|
148
+| goods_id | FK 逻辑 |
149
+| service_id | 来源 `biz_goods_service` |
150
+| service_name / service_intro / service_icon | **快照** |
151
+| sort_no | 展示顺序 |
152
+
153
+保存商品时 **先删后插** 该商品全部快照行。
154
+
155
+### 2.5 扩展表(非 v1.0 · 概要)
156
+
157
+| 表(规划) | 用途 |
158
+|------------|------|
159
+| `biz_goods_pic` | 多图 gallery |
160
+| `biz_goods_sku` | 多规格 SKU(市场价、库存) |
161
+| `biz_goods_freight` | 固定运费 / 运费模版 ID |
162
+| `biz_goods_attr` | 属性项/规格项键值 |
163
+
164
+v1.0 **仅** 使用主表 `sale_price`/`stock`/`main_pic`/`detail_content`。
165
+
166
+### 2.6 索引
167
+
168
+| 索引 | 字段 | 用途 |
169
+|------|------|------|
170
+| uk_goods_sn | goods_sn | 编号唯一 |
171
+| idx_shop_status | shop_id, goods_status, del_flag | 商家列表 + 状态 Tab |
172
+| idx_category_id | category_id, del_flag | 分类检索 |
173
+| idx_shop_category_id | shop_category_id, del_flag | 店铺分类删校验 |
174
+| idx_submit_time | submit_time | 待审核排序(平台侧) |
175
+
176
+### 2.7 商家列表 SQL 约定
177
+
178
+```sql
179
+WHERE g.del_flag = '0'
180
+  AND g.shop_id = #{shopId}          -- 强制当前店铺(GL1)
181
+  -- 含 goods_status='0',与平台列表不同
182
+```
183
+
184
+### 2.8 字典
185
+
186
+| dict_type | 说明 |
187
+|-----------|------|
188
+| goods_status | 0~4 状态展示 |
189
+
190
+---
191
+
192
+## 3. 状态机(Service)
193
+
194
+> 与《商品审核技术方案》§3、《关联需求分析》§5.4 **同源**。
195
+
196
+| 操作 | 方法 | 执行方 | 前置 status | 结果 status |
197
+|------|------|--------|-------------|-------------|
198
+| 保存(新建) | `insertSellerGoods` | 商家 | — | **0** |
199
+| 保存(编辑) | `updateSellerGoods` | 商家 | 0/1/2/3/4 | **不变** |
200
+| 提交上架 | `submitGoods` | 商家 | 0/3/4 | **1** 或 **2**¹ |
201
+| 审核通过 | `auditGoods` | 平台 | 1 | 2 |
202
+| 审核驳回 | `auditGoods` | 平台 | 1 | 3 |
203
+| 下架 | `offShelfSeller` / `offShelfPlatform` | 商家/平台 | 2 | 4 |
204
+| 删除 | `deleteSellerGoods`² | 商家 | 0/3/4 | del_flag=2 |
205
+
206
+¹ `default_audit_pass='1'` → **2**,否则 **1**。  
207
+² **待实现**;出售中/待审核 **阻断**。
208
+
209
+**禁止:** 请求体携带 `goodsStatus` 直接改态(`rejectGoodsStatusInBody`)。
210
+
211
+**批量策略:** `submit` / `offShelf` / `delete` 均 **先全量校验** → 任一失败 `GoodsBatchOperationException`,**零行** 更新。
212
+
213
+---
214
+
215
+## 4. 跨模块 Facade
216
+
217
+| 接口 | 提供方 | 本模块用法 |
218
+|------|--------|------------|
219
+| `ICategoryFacade` | 分类 | `listPlatformLevel2Options()` — 发品「商品分类」 |
220
+| `IShopGoodsCategoryFacade` | 店铺商品分类 | `listOptionsByShopId(shopId, visibleOnly)` — 「店铺商品分类」 |
221
+| `IGoodsServiceFacade` | 商品服务 | `listAllEnabled` / `listDefaultShow`;删服务前 `existsByServiceId` |
222
+| `IShopGlobalConfigFacade` | 店铺设置 | `getDefaultAuditPass()` |
223
+| `IShopFacade` | 店铺 | 删店时 `assertShopMaintable` |
224
+| `IGoodsFacade` | 商品 | `hasBlockingGoodsForShopDelete`;`existsByShopCategoryId` |
225
+| `IOrderFacade`³ | 订单 | `hasUnfinishedOrderByGoodsId(goodsId)` — 下架前置 |
226
+
227
+³ 订单模块 Facade,下架 O10 校验 **待对接**。
228
+
229
+---
230
+
231
+## 5. 接口设计
232
+
233
+**公共约定**
234
+
235
+| 项 | 说明 |
236
+|----|------|
237
+| 基路径 | `/agri/seller/goods` |
238
+| 请求头 | **`X-Shop-Id`**:当前店铺 ID(除 `/agri/seller/context` 外 `/agri/seller/**` 必传) |
239
+| 分页 | `pageNum` / `pageSize` → `TableDataInfo` |
240
+| 权限 | `@PreAuthorize("@ss.hasPermi('agri:seller:goods:…')")` |
241
+| 批量失败 | `code!=200`,`data.reasons[]` 明细 |
242
+
243
+---
244
+
245
+### 5.1 商品列表 `GET /agri/seller/goods/list`
246
+
247
+| 项 | 说明 |
248
+|----|------|
249
+| 权限 | `agri:seller:goods:list` |
250
+| 店铺 | `SellerShopContext.getShopId()`,与 header 一致 |
251
+
252
+**Query:**
253
+
254
+| 参数 | 说明 |
255
+|------|------|
256
+| goodsSn | 编号模糊 |
257
+| goodsName | 名称模糊 |
258
+| categoryId | **平台** 二级分类 ID |
259
+| goodsStatusQuery | 0/1/2/3/4;不传查全部 |
260
+| keyword | 可选;sn+name 组合模糊 |
261
+
262
+**`rows`(GoodsListVO):**
263
+
264
+| 字段 | 说明 |
265
+|------|------|
266
+| goodsId, goodsSn, goodsName, mainPic | |
267
+| salePrice, salesCount | 售价、销量 |
268
+| stock | 可选列 |
269
+| goodsStatus, goodsStatusLabel | 字典 goods_status |
270
+| categoryPath | 一级 > 二级(平台分类) |
271
+| shopCategoryName | 可选;店铺商品分类名 |
272
+
273
+**排序:** 默认 `create_time DESC`(待审核 Tab 可前端传参或扩展 `orderBy=submitTime`)。
274
+
275
+---
276
+
277
+### 5.2 商品详情 `GET /agri/seller/goods/{goodsId}`
278
+
279
+| 项 | 说明 |
280
+|----|------|
281
+| 权限 | `agri:seller:goods:query` |
282
+| 校验 | `goods_id` 须属 **当前 shop_id** |
283
+
284
+**`data`(GoodsDetailVO):**
285
+
286
+| 字段 | 说明 |
287
+|------|------|
288
+| 列表字段 | 同 §5.1 |
289
+| shopId, categoryId, shopCategoryId | |
290
+| detailContent, stock | |
291
+| rejectReason, submitTime, auditTime, offShelfTime | |
292
+| services[] | 服务快照列表 |
293
+| canSubmit, canOffShelf, canDelete, canEdit | 前端按钮态(可选) |
294
+
295
+---
296
+
297
+### 5.3 添加商品 `POST /agri/seller/goods`
298
+
299
+| 项 | 说明 |
300
+|----|------|
301
+| 权限 | `agri:seller:goods:add` |
302
+| 日志 | title=商家商品 |
303
+
304
+**Body(GoodsSaveDTO · v1.0):**
305
+
306
+```json
307
+{
308
+  "categoryId": 1002,
309
+  "shopCategoryId": 2005,
310
+  "goodsName": "复合肥 50kg",
311
+  "mainPic": "/profile/upload/2026/05/01/a.jpg",
312
+  "detailContent": "<p>详情</p>",
313
+  "salePrice": 128.00,
314
+  "stock": 500,
315
+  "serviceIds": [1, 3]
316
+}
317
+```
318
+
319
+| 校验 | 说明 |
320
+|------|------|
321
+| categoryId | 须为 **平台二级** 有效分类 |
322
+| shopCategoryId | 若传,须属 **当前店** 二级分类 |
323
+| serviceIds | 须全部存在于未删除服务目录 |
324
+| goodsStatus | **禁止** 传入 |
325
+
326
+**响应:** `{ "goodsId": 10001 }`;落库 `goods_status='0'`,生成 `goods_sn`。
327
+
328
+---
329
+
330
+### 5.4 编辑商品 `PUT /agri/seller/goods`
331
+
332
+| 项 | 说明 |
333
+|----|------|
334
+| 权限 | `agri:seller:goods:edit` |
335
+| Body | 同 §5.3 + **goodsId** 必填 |
336
+
337
+- **不修改** `goods_status`、`shop_id`、`goods_sn`。  
338
+- 各状态均可编辑(P14);保存后刷新服务快照。
339
+
340
+---
341
+
342
+### 5.5 提交上架
343
+
344
+#### 5.5.1 单独 `PUT /agri/seller/goods/{goodsId}/submit`
345
+
346
+| 项 | 说明 |
347
+|----|------|
348
+| 权限 | `agri:seller:goods:edit` |
349
+| 前置 | status ∈ {0, 3, 4} |
350
+
351
+**响应 data:**
352
+
353
+```json
354
+{
355
+  "goodsId": 10001,
356
+  "goodsStatus": "1",
357
+  "goodsStatusLabel": "待审核"
358
+}
359
+```
360
+
361
+#### 5.5.2 批量 `PUT /agri/seller/goods/submit`(待实现)
362
+
363
+**Body:** `{ "goodsIds": [10001, 10002] }`  
364
+规则:含非 {0,3,4} → **整批失败**。
365
+
366
+---
367
+
368
+### 5.6 下架
369
+
370
+#### 5.6.1 单独 `PUT /agri/seller/goods/{goodsId}/offShelf`
371
+
372
+| 项 | 说明 |
373
+|----|------|
374
+| 权限 | `agri:seller:goods:offshelf` |
375
+| 前置 | status=2;**无 O10 未完成订单**(待实现) |
376
+
377
+#### 5.6.2 批量 `PUT /agri/seller/goods/offShelf`
378
+
379
+| 项 | 说明 |
380
+|----|------|
381
+| 权限 | `agri:seller:goods:offshelf` |
382
+| Body | 复用 `GoodsOffShelfDTO`:`{ "goodsIds": [10001] }` |
383
+
384
+失败:`GoodsBatchOperationException` → `{ "reasons": ["仅出售中商品可下架:G20260501001"] }`。
385
+
386
+---
387
+
388
+### 5.7 删除
389
+
390
+#### 5.7.1 单独 `DELETE /agri/seller/goods/{goodsId}`(待实现)
391
+
392
+| 项 | 说明 |
393
+|----|------|
394
+| 权限 | `agri:seller:goods:remove` |
395
+| 前置 | status ∈ {0, 3, 4} |
396
+
397
+逻辑删除:`del_flag='2'`;同步删快照(可选保留历史)。
398
+
399
+#### 5.7.2 批量 `DELETE /agri/seller/goods/{goodsIds}`(待实现)
400
+
401
+路径:`goodsIds=1,2,3`;含不可删状态 → **整批失败**。
402
+
403
+---
404
+
405
+### 5.8 发品辅助下拉
406
+
407
+| 方法 | 路径 | 权限 | 说明 |
408
+|------|------|------|------|
409
+| GET | `/agri/seller/goods/categoryOptions` | `list` | 平台二级「商品分类」`ICategoryFacade.listPlatformLevel2Options()` |
410
+| GET | `/agri/seller/goods/shopCategoryOptions` | `list` | 本店二级「店铺商品分类」`IShopGoodsCategoryFacade.listOptionsByShopId(shopId, false)` **待加** |
411
+| GET | `/agri/seller/goods/serviceOptions` | `list` | `{ all: [], defaultShow: [] }` |
412
+
413
+---
414
+
415
+### 5.9 与平台接口对照
416
+
417
+| 能力 | 商家(本方案) | 平台 |
418
+|------|----------------|------|
419
+| 列表 | `GET /agri/seller/goods/list`(含 status=0) | `GET /agri/goods/list`(status≠0) |
420
+| 详情 | `GET /agri/seller/goods/{id}` | `GET /agri/goods/{id}` |
421
+| 保存 | POST/PUT `/agri/seller/goods` | — |
422
+| 提交上架 | PUT `.../submit` | — |
423
+| 审核 | — | PUT `/agri/goods/audit` |
424
+| 下架 | PUT `.../offShelf` | PUT `/agri/goods/offShelf` |
425
+| 删除 | DELETE `.../{id}` | — |
426
+
427
+---
428
+
429
+## 6. Service 核心逻辑摘要
430
+
431
+```text
432
+insertSellerGoods
433
+  → requireShopId
434
+  → validateSaveFields + assertPlatformCategoryLevel2(categoryId)
435
+  → assertShopCategoryIfPresent(shopCategoryId)
436
+  → goodsSn = GoodsSnGenerator.next()
437
+  → insert status=0
438
+  → saveServiceSnapshots
439
+
440
+submitGoods
441
+  → status in (0,3,4)
442
+  → target = defaultAuditPass ? 2 : 1
443
+  → updateSubmitStatus(首次写 submit_time)
444
+
445
+offShelfSeller
446
+  → offShelfBatch(shopId 限定)
447
+  → [待] orderFacade 校验 O10
448
+  → status 2 → 4,写 off_shelf_time
449
+
450
+deleteSellerGoods [待]
451
+  → status in (0,3,4)
452
+  → logic delete
453
+```
454
+
455
+**分类校验口径:**
456
+
457
+| 字段 | SQL 条件 |
458
+|------|----------|
459
+| category_id | `biz_goods_category.category_id`,`shop_id IS NULL`,`parent_id > 0` |
460
+| shop_category_id | `biz_goods_category.category_id`,`shop_id = #{shopId}`,`parent_id > 0` |
461
+
462
+---
463
+
464
+## 7. 权限与菜单
465
+
466
+| 权限标识 | 说明 |
467
+|----------|------|
468
+| agri:seller:goods:list | 列表、下拉 |
469
+| agri:seller:goods:query | 详情 |
470
+| agri:seller:goods:add | 新增 |
471
+| agri:seller:goods:edit | 编辑、提交上架 |
472
+| agri:seller:goods:offshelf | 下架 |
473
+| agri:seller:goods:remove | 删除 |
474
+
475
+**菜单 SQL:** `sql/agri_seller_goods_menu.sql`  
476
+**组件路径:** `agri/seller/goods/index`(发品/编辑可 `goods/form`)。
477
+
478
+---
479
+
480
+## 8. 实现分期
481
+
482
+| 阶段 | 内容 | 状态 |
483
+|------|------|------|
484
+| **v1.0** | 列表/详情/单规格 CRUD/单独 submit·offShelf/服务快照/平台分类与服务下拉 | **已实现** |
485
+| **v1.0 补全** | `shop_category_id` 字段 + 店铺分类下拉 + 删除 + 批量 submit/offShelf/delete + 下架 O10 校验 | **待实现** |
486
+| **v1.x** | 多图、多规格 SKU、运费、属性模版引用、关键词检索扩展 | 规划 |
487
+
488
+---
489
+
490
+## 9. 测试要点
491
+
492
+| 编号 | 场景 |
493
+|------|------|
494
+| T1 | 未传 `X-Shop-Id` → 业务失败 |
495
+| T2 | 列表仅返回当前店商品 |
496
+| T3 | 保存 → status=0;body 带 goodsStatus → 拒收 |
497
+| T4 | submit:免审关→1,免审开→2 |
498
+| T5 | 待审核/出售中 edit 保存 → 状态不变 |
499
+| T6 | 批量 submit 含 status=2 → 整批失败 |
500
+| T7 | 下架非出售中 → 失败 |
501
+| T8 | 删除出售中 → 失败 |
502
+| T9 | 跨店 goodsId → MSG_NOT_OWNER |
503
+| T10 | 服务快照:保存后详情与目录变更隔离 |
504
+
505
+---
506
+
507
+## 10. 修订记录
508
+
509
+| 版本 | 说明 |
510
+|------|------|
511
+| **v1.0** | 首版:商家商品列表技术方案;复用 biz_goods 与平台状态机;接口/DDL 与实现对齐并标注待办 |
512
+
513
+---
514
+
515
+*文档版本:v1.0 · 关联《商品列表功能需求.md》v1.1、《商品审核技术方案.md》、《商品分类技术方案.md》v1.2、《商品服务管理技术方案.md》v1.0.1、《店铺商品分类技术方案.md》v1.1 · 技术栈 RuoYi v3.9.2-springboot2 + MySQL 5.7.39。*

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1042 - 0
doc/店铺后台/商品管理/商品列表/店铺商品列表测试用例.md