wwh преди 1 седмица
родител
ревизия
1ee8436278

+ 8 - 0
doc/消费者APP/站内消息/站内消息功能需求-草稿.md

@@ -0,0 +1,8 @@
1
+做一个站内消息模块:
2
+
3
+1. 前提:会员已登录APP
4
+2. 商家入驻成功、商家入驻审核失败等;
5
+3. 红点提醒有未读新消息;
6
+4. 查询当前登录会员的站内消息,从biz_member_message表读取
7
+5. 异常返回:统一格式 code、msg、data。
8
+6. 技术栈:RuoYi v3.9.2-springboot2 分支 + MySQL-5.7.39。

+ 403 - 0
doc/消费者APP/站内消息/站内消息功能需求.md

@@ -0,0 +1,403 @@
1
+# 站内消息 — 功能需求说明(C 端)
2
+
3
+> 本文档在《站内消息功能需求-草稿》基础上整理,并关联 **《关联需求分析.md》** v1.6、平台侧 **《会员管理功能需求》** v1.1、《商户入驻审核功能需求》** v1.1 及 C 端兄弟模块 **《我的服务功能需求》** v1.1、《我的店铺关注功能需求》** v1.0 做边界与流程对齐。  
4
+> 范围:**C 端(消费者 APP / 用户商城)· 站内消息中心** 的 **未读提醒、消息列表、消息详情、已读标记与关联跳转**;**不涉及** 数据库结构、接口定义及技术实现细节。  
5
+> **说明:** 本模块 **只读消费** 系统为当前会员投递的消息;**消息写入** 由平台业务事件(本期主要为 **商户入驻审核**)触发,**不在** C 端维护。  
6
+> **v1.0:** 首版定稿;对齐草稿 §1~§4;补全入驻三类通知、红点规则、与「我的入驻」协作及非本期边界。
7
+
8
+---
9
+
10
+## 1. 模块定位
11
+
12
+### 1.1 业务目标
13
+
14
+为 **已登录的 C 端会员** 提供 **站内消息统一查看** 能力,使其能够:
15
+
16
+- 在 **个人中心或全局入口** 看到 **未读新消息** 的 **红点/角标** 提醒;
17
+- 查看 **当前会员** 收到的 **全部站内消息** 列表(按时间倒序);
18
+- 打开 **消息详情**,阅读完整标题与正文;
19
+- 阅读后 **标记为已读**,红点随之更新;
20
+- 对 **入驻审核类** 消息,**一键跳转** 至 **我的入驻 / 申请详情**,核对进度或驳回原因。
21
+
22
+**不包含(本期或与它模块分工):**
23
+
24
+| 能力 | 说明 |
25
+|------|------|
26
+| **消息产生与投递逻辑** | 由平台 **商户入驻审核** 等业务模块在状态变更时 **系统写入**;C 端 **不创建、不编辑、不删除** 消息 |
27
+| **平台运营查看/群发消息** | 平台后台 **无** 独立「消息管理」工作台;非本期 |
28
+| **短信、邮件、App Push** | 入驻审核 EA14 明确 **本期仅站内消息** |
29
+| **订单状态、物流、售后通知** | 见 **订单管理** / **我的订单**;**可另册** 扩展消息类型 |
30
+| **店铺关注「开业提醒」** | 见 **我的店铺关注**;**可另册** |
31
+| **商家端消息** | 本模块 **仅 C 端买家会员**;经营账号 **不在此** 收件 |
32
+
33
+### 1.2 在业务链中的位置
34
+
35
+```text
36
+【用户链】C 端注册/登录
37
+    ↓
38
+【可选】我的服务 · 商家入驻申请 → 提交
39
+    ↓
40
+【平台】商户入驻审核(待审 → 通过/公示 → 完成入驻 / 驳回)
41
+    ↓
42
+【系统】向申请人会员投递站内消息(EA14)
43
+    ↓
44
+【本模块】消息中心 · 红点 · 列表 · 详情 · 跳转「我的入驻」
45
+
46
+【并行】会员浏览/下单 ── 不依赖是否收到或已读消息
47
+```
48
+
49
+| 关联模块 | 关系 | 边界说明 |
50
+|----------|------|----------|
51
+| **商户入驻审核** v1.1 | **上游写入** | 审核通过→公示、完成公示、审核驳回 **各发一条** 消息;文案见 §7 |
52
+| **我的服务** v1.1 | **兄弟 + 跳转目标** | 入驻进度 **可在** 消息中心 **或** 「我的入驻」查看;消息 UI **本模块** 承担 |
53
+| **会员管理** v1.1 | **用户链** | 禁用会员 **不可登录**,故 **不可** 使用本模块 |
54
+| **会员注册登录** | **前置** | 须有效登录态 |
55
+| **我的店铺关注** v1.0 | **潜在扩展** | 开业提醒类消息 **非本期** |
56
+| **订单管理** v1.0.1 | **潜在扩展** | 订单类通知 **非本期** |
57
+| **关联需求分析** v1.6 §2.1 | **双链** | 用户链消息 **不影响** 供给链发品/经营 |
58
+
59
+### 1.3 与平台《商户入驻审核》的对应
60
+
61
+| 平台事件(EA14) | 申请状态变化 | 本模块应展示的消息类型 |
62
+|------------------|--------------|------------------------|
63
+| 运营 **审核通过** | 待审核 → **公示中** | **入驻审核通过,公示中** |
64
+| **完成公示**(自动或手动) | 公示中 → **已完成入驻** | **入驻完成** |
65
+| 运营 **审核驳回** | 待审核 → **审核未通过** | **入驻审核未通过**(含拒绝原因) |
66
+
67
+> **平台代录入**(路径 B)**不经过** 入驻审核,**不产生** 本模块消息。
68
+
69
+---
70
+
71
+## 2. 关联需求分析
72
+
73
+### 2.1 与平台《会员管理》
74
+
75
+| 项 | C 端本模块 | 平台会员管理 |
76
+|----|------------|--------------|
77
+| 收件人 | **仅当前登录会员** 可见本人消息 | 列表/详情 **不展示** 会员消息箱 |
78
+| 是否启用 | 禁用后 **无法登录** → 本模块不可用 | 禁用须二次确认(M4) |
79
+| 会员注销/换绑手机 | **非本期** | — |
80
+
81
+### 2.2 与《商户入驻审核》《我的服务 · 商家入驻》
82
+
83
+| 项 | 定稿 |
84
+|----|------|
85
+| 通知渠道 | 状态变更 **必须** 发站内消息(EA14);**无** 短信/邮件 |
86
+| 文案一致性 | 消息 **标题、正文要点** 与平台 §8.2、§8.3、§9 及 C 端 **我的入驻** 展示 **不矛盾** |
87
+| 驳回原因 | 消息正文 **须含** 拒绝原因摘要;与申请详情、C 端「我的入驻」 **同源** |
88
+| 公示期 | 「公示中」消息 **须提示** 公示结束/预计完成时间(与平台公示起止一致) |
89
+| 重复申请 | 驳回后 **新申请** 产生 **新消息**;历史消息 **保留** 只读 |
90
+| 查看入口 | C 端可在 **消息中心** 或 **我的入驻** 查看结果(MS §9.8) |
91
+
92
+### 2.3 与《我的店铺关注》(边界)
93
+
94
+| 项 | 定稿 |
95
+|----|------|
96
+| 关注店开业提醒 | 产品曾提及「XX 店开业提醒」;**非本期** 消息类型 |
97
+| 链入 | 若未来从消息跳转店铺主页,须 **带登录态** 与有效 **shopId** |
98
+
99
+### 2.4 消息写入与读取职责
100
+
101
+```text
102
+写入方(系统 · 非 C 端 UI)
103
+├── 商户入驻审核 · 审核通过        → 投递「公示中」
104
+├── 商户入驻审核 · 完成公示        → 投递「入驻完成」
105
+└── 商户入驻审核 · 审核驳回        → 投递「未通过 + 原因」
106
+
107
+读取方(本模块 · C 端)
108
+├── 未读计数 / 红点
109
+├── 消息列表(分页)
110
+├── 消息详情 + 标记已读
111
+└── 按业务类型跳转(本期:入驻申请详情)
112
+```
113
+
114
+---
115
+
116
+## 3. 功能结构
117
+
118
+```text
119
+站内消息(C 端 · 须登录)
120
+├── 全局/个人中心入口(含未读红点)
121
+├── 消息列表
122
+│   ├── 全部消息(时间倒序)
123
+│   ├── 未读/已读标识
124
+│   └── 下拉刷新 / 分页加载
125
+├── 消息详情
126
+│   ├── 标题、正文、接收时间
127
+│   ├── 打开即标记已读(见 §6.3)
128
+│   └── 关联操作(本期:查看入驻申请)
129
+└── (被动)未读数变化驱动入口红点更新
130
+```
131
+
132
+---
133
+
134
+## 4. 业务概念
135
+
136
+| 概念 | 说明 |
137
+|------|------|
138
+| 站内消息 | 系统向 **指定会员** 投递的 **应用内通知**;含标题、正文、业务关联信息 |
139
+| 未读 / 已读 | 会员 **尚未打开详情** 为未读;**已打开详情** 为已读 |
140
+| 未读数 | 当前会员 **未读消息条数**;用于 **红点/数字角标** |
141
+| 消息类型(本期) | **入驻审核**:公示中、入驻完成、审核未通过 |
142
+| 业务关联 | 消息可关联 **入驻申请单**;详情页可 **跳转** 至对应申请 |
143
+| 消息中心 | 本模块列表 + 详情 **统一入口** 的统称 |
144
+
145
+---
146
+
147
+## 5. 访问控制与前置条件
148
+
149
+### 5.1 统一前置(对齐草稿 §1)
150
+
151
+| 规则 | 说明 |
152
+|------|------|
153
+| **MM0** | 使用本模块 **任意能力** 前,须 **已通过 C 端登录** 且 Token 有效 |
154
+| 未登录 | **拦截**,引导 **登录**;登录成功后可 **回跳** 消息中心(若产品支持) |
155
+| 访客 | **不提供** 消息入口,或进入后等同未登录 |
156
+
157
+### 5.2 会员启用状态
158
+
159
+```text
160
+平台禁用会员 → 无法登录 → 本模块不可用
161
+```
162
+
163
+| 规则 | 说明 |
164
+|------|------|
165
+| 历史消息 | 会员 **重新启用** 后,**历史消息仍在**,未读状态 **保持** |
166
+| 数据隔离 | **仅展示** 当前登录 `member_id` 的消息;**不可** 查看他人消息 |
167
+
168
+### 5.3 与草稿对齐的读取范围(草稿 §4 业务化)
169
+
170
+| 规则 | 说明 |
171
+|------|------|
172
+| 数据范围 | 列表与详情 **仅查询当前登录会员** 的站内消息 |
173
+| 排序 | 默认按 **接收时间(创建时间)降序**;**最新在前** |
174
+| 分页 | 列表 **须支持分页**(或等价「加载更多」);避免一次拉取过多 |
175
+
176
+---
177
+
178
+## 6. 未读提醒(对齐草稿 §3)
179
+
180
+### 6.1 入口与展示
181
+
182
+| 入口(建议) | 红点规则 |
183
+|--------------|----------|
184
+| **个人中心 / 我的** 内「消息」或「消息中心」菜单项 | 未读数 **> 0** 时展示 **红点**;可选展示 **未读数字**(如 99+ 封顶) |
185
+| **APP 顶部导航** 消息图标(若产品配置) | 同上 |
186
+| **TabBar / 首页** 快捷入口(若产品配置) | 同上 |
187
+
188
+### 6.2 未读数计算
189
+
190
+| 规则 | 说明 |
191
+|------|------|
192
+| **MM1** | 未读数 = 当前会员 **read_flag = 未读** 的消息 **总条数** |
193
+| 实时性 | 进入个人中心、打开消息列表、从详情返回列表时 **应刷新** 未读数 |
194
+| 无未读 | 未读数 = 0 时 **隐藏** 红点/数字 |
195
+
196
+### 6.3 已读标记
197
+
198
+| 规则 | 说明 |
199
+|------|------|
200
+| **MM2** | 会员 **打开某条消息详情** 后,该条 **标记为已读** |
201
+| 列表态 | 列表页 **滑动浏览** **不** 批量标记已读;**须进入详情**(或产品定义「点击列表行 = 进详情并已读」) |
202
+| 幂等 | 已读消息 **再次打开** **不改变** 状态 |
203
+| 红点更新 | 标记已读后 **立即** 更新未读数与入口红点 |
204
+
205
+---
206
+
207
+## 7. 消息类型与内容(对齐草稿 §2)
208
+
209
+### 7.1 本期支持的消息类型
210
+
211
+| 类型 | 触发时机(平台) | 标题(示例) | 正文要点 |
212
+|------|------------------|--------------|----------|
213
+| **公示中** | 入驻申请 **审核通过**,进入公示 | 入驻审核通过,公示中 | 申请编号;已进入公示期;**预计完成/公示结束时间** |
214
+| **入驻完成** | **完成公示**,商户+首店+经营账号已建档 | 入驻完成 | 申请编号;入驻成功;可 **经营账号登录商家端** |
215
+| **审核未通过** | 入驻申请 **被驳回** | 入驻审核未通过 | 申请编号;**拒绝原因全文或摘要**(与平台驳回原因一致) |
216
+
217
+### 7.2 投递规则
218
+
219
+| 规则 | 说明 |
220
+|------|------|
221
+| **MM3** | 每条平台状态变更 **对应一条新消息**;**不合并** 历史记录 |
222
+| 收件人 | **提交入驻申请的会员**(`member_id`);与平台列表「申请会员名称」一致 |
223
+| 平台代录入 | **不产生** 消息 |
224
+| 重复审核 | 对 **非待审核** 申请的操作被平台 **阻断**;**不会** 重复发同阶段消息 |
225
+
226
+### 7.3 入驻审核消息流程
227
+
228
+```text
229
+会员提交入驻申请(我的服务)
230
+    ↓
231
+【待审核】— 无消息
232
+    ↓
233
+平台审核通过 ──► 消息①「公示中」+ 未读红点
234
+    ↓
235
+公示期满 / 手动完成公示 ──► 消息②「入驻完成」+ 未读红点
236
+    ↓
237
+(或)平台驳回 ──► 消息「审核未通过」+ 原因 + 未读红点
238
+```
239
+
240
+---
241
+
242
+## 8. 消息列表
243
+
244
+### 8.1 列表字段
245
+
246
+| 字段 | 说明 |
247
+|------|------|
248
+| 标题 | 消息标题;**未读** 时可 **加粗** 或 **未读圆点** 区分 |
249
+| 摘要 | 正文 **前几行截断** 或 **单行摘要**(驳回类 **须能辨识** 含原因) |
250
+| 接收时间 | 消息创建/投递时间;格式 **YYYY-MM-DD HH:mm**(或产品统一规范) |
251
+| 已读状态 | 未读 **视觉标识**;已读 **弱化** 样式 |
252
+
253
+### 8.2 列表行为
254
+
255
+| 规则 | 说明 |
256
+|------|------|
257
+| 默认排序 | **接收时间降序** |
258
+| 空态 | 无任何消息时:「暂无消息」+ 简要说明(如「入驻审核结果将在此通知您」) |
259
+| 点击行 | 进入 **消息详情**(§9) |
260
+| 刷新 | 支持下拉刷新或进入页 **自动刷新** |
261
+| 加载失败 | 统一错误态 + **重试** |
262
+
263
+### 8.3 筛选与分类(本期)
264
+
265
+| 项 | 定稿 |
266
+|----|------|
267
+| Tab 分类(全部/未读/系统/订单) | **非本期**;列表 **仅「全部」** |
268
+| 搜索 | **非本期** |
269
+| 删除 / 批量已读 | **非本期**(消息 **不可** 由用户删除) |
270
+
271
+---
272
+
273
+## 9. 消息详情
274
+
275
+### 9.1 展示内容
276
+
277
+| 字段 | 说明 |
278
+|------|------|
279
+| 标题 | 完整标题 |
280
+| 正文 | 完整内容;驳回类 **拒绝原因须完整可读** |
281
+| 接收时间 | 与列表一致 |
282
+| 关联操作 | 见 §9.2 |
283
+
284
+### 9.2 关联跳转(本期)
285
+
286
+| 消息类型 | 跳转目标 | 说明 |
287
+|----------|----------|------|
288
+| 入驻审核类(三种) | **我的服务 · 我的入驻 / 该申请详情** | 携带 **申请单** 上下文;会员可核对状态、公示期、驳回原因 |
289
+| 无法关联(数据异常) | **不跳转** 或提示「关联内容不存在」 | 如申请单已被清理的 **极端情况**;正文仍可读 |
290
+
291
+### 9.3 详情交互
292
+
293
+| 规则 | 说明 |
294
+|------|------|
295
+| 进入详情 | **标记该条已读**(§6.3) |
296
+| 返回列表 | 列表 **刷新** 该条已读样式与 **全局未读数** |
297
+| 长正文 | **可滚动** 阅读;**不截断** |
298
+
299
+---
300
+
301
+## 10. 与「我的入驻」的信息一致性
302
+
303
+| 场景 | 消息中心 | 我的入驻 |
304
+|------|----------|----------|
305
+| 公示中 | 消息① + 预计完成时间 | 展示 **公示起止**、状态「公示中」 |
306
+| 入驻完成 | 消息② + 成功指引 | 状态「已完成入驻」、经营账号说明 |
307
+| 审核未通过 | 消息 + **原因** | **醒目** 展示 **同一拒绝原因**、**重新申请** 入口 |
308
+
309
+| 规则 | 说明 |
310
+|------|------|
311
+| **MM4** | 两处信息 **不得矛盾**;以 **平台审核结果** 为唯一事实来源 |
312
+| 优先入口 | 会员 **可从任一处** 获知结果;消息中心侧重 **主动提醒**,我的入驻侧重 **进度管理** |
313
+
314
+---
315
+
316
+## 11. 异常与边界
317
+
318
+### 11.1 常见边界
319
+
320
+| 场景 | 处理 |
321
+|------|------|
322
+| 未登录打开消息链接 | 引导登录 → 回跳 |
323
+| 登录后会员 A 尝试访问会员 B 的消息 | **不可见**(服务端按会员隔离) |
324
+| 消息已读但用户未读「我的入驻」 | **允许**;两处独立 |
325
+| 连续多条未读 | 红点展示 **总数**;列表 **逐条** 展示 |
326
+| 会员无入驻申请却收到消息 | **不应发生**;若出现则详情跳转 **失败提示** |
327
+
328
+### 11.2 与草稿 §5 的关系
329
+
330
+草稿要求接口异常返回 **code、msg、data** 统一格式;该约定属于 **接口/技术层**,**不纳入** 本功能需求正文;产品层要求:**加载失败可重试、错误提示友好**(见 §8.2、§12)。
331
+
332
+---
333
+
334
+## 12. 页面与交互要点
335
+
336
+| 场景 | 要求 |
337
+|------|------|
338
+| 未读红点 | 未读数变化 **及时**;避免已读后仍长期显示红点 |
339
+| 驳回消息 | 列表摘要与详情中原因 **醒目**(可与我的入驻 **同色系**) |
340
+| 公示中消息 | 详情中 **突出** 公示结束/预计完成 **日期时间** |
341
+| 入驻完成 | 详情提供 **查看入驻结果** / **我的入驻** 按钮 |
342
+| 空态 | 友好文案;**不** 展示虚假未读 |
343
+| 加载中 | 列表 **骨架屏或 Loading** |
344
+| 弱网 | 失败 **Toast** + 重试 |
345
+
346
+---
347
+
348
+## 13. 业务规则汇总
349
+
350
+| 编号 | 规则 |
351
+|------|------|
352
+| **MM0** | 须 **登录且启用** 会员 |
353
+| **MM1** | 未读数 = 当前会员未读消息条数 |
354
+| **MM2** | **打开详情** 标记该条已读 |
355
+| **MM3** | 入驻审核状态变更 **各投递一条** 新消息 |
356
+| **MM4** | 消息与「我的入驻」**信息一致** |
357
+| **MM5** | **仅当前会员** 可读本人消息 |
358
+| **MM6** | 列表 **时间倒序**、**分页** |
359
+| **MM7** | 入驻审核类消息 **可跳转** 申请详情 |
360
+| **MM8** | 用户 **不可** 删除或编辑消息 |
361
+| **MM9** | 平台代录入 **不产生** 消息 |
362
+| **MM10** | 本期 **仅入驻审核** 三类;订单/关注等 **另册** |
363
+
364
+---
365
+
366
+## 14. 非本期范围
367
+
368
+| 项 | 说明 |
369
+|----|------|
370
+| 订单支付、发货、收货、售后 **消息** | 订单模块建设时 **扩展** |
371
+| 店铺关注 **开业提醒** | 见我的店铺关注 |
372
+| 短信、邮件、Push | EA14:**仅站内** |
373
+| 消息 **分类 Tab**、搜索、用户删除 | — |
374
+| **全部标记已读** | 可后续迭代 |
375
+| 平台后台 **消息管理/人工群发** | — |
376
+| 商家端 / 平台运营端 **收件箱** | — |
377
+| 草稿 §5 异常 **code/msg/data**、§6 **技术栈** | **不纳入** 本文 |
378
+
379
+---
380
+
381
+## 15. 草稿对照与修订说明
382
+
383
+| 草稿条目 | 本文档处理 |
384
+|----------|------------|
385
+| §1 会员已登录 APP | §5 |
386
+| §2 入驻成功、审核失败等 | §7(扩展为 **公示中 / 完成 / 驳回** 三类,对齐 EA14) |
387
+| §3 红点提醒未读 | §6 |
388
+| §4 查询当前会员站内消息 | §5.3、§8(**不写表名**) |
389
+| §5 异常 code/msg/data | §11.2 **不纳入** 功能需求 |
390
+| §6 技术栈 | **不纳入** |
391
+| 未写:详情、已读规则、跳转、与我的入驻一致性、平台写入边界 | §2、§9、§10、§14 补充 |
392
+
393
+---
394
+
395
+## 16. 修订记录
396
+
397
+| 版本 | 说明 |
398
+|------|------|
399
+| **v1.0** | 首版定稿:未读红点、列表、详情、已读、入驻三类消息与跳转;关联商户入驻审核、我的服务、会员管理 |
400
+
401
+---
402
+
403
+*文档版本:v1.0(定稿)· 关联《站内消息功能需求-草稿.md》、《关联需求分析.md》v1.6、《商户入驻审核功能需求.md》v1.1、《会员管理功能需求.md》v1.1、《我的服务功能需求.md》v1.1 · 草稿保持不变。*

+ 340 - 0
doc/消费者APP/站内消息/站内消息页技术方案.md

@@ -0,0 +1,340 @@
1
+# 站内消息 — 技术方案(C 端)
2
+
3
+> **依据:** 《站内消息功能需求.md》v1.0  
4
+> **关联:** 平台《商户入驻审核技术方案》v1.1、《商户入驻审核功能需求》v1.1、《会员管理技术方案》v1.3、《关联需求分析.md》v1.6;C 端《我的服务技术方案》v1.0  
5
+> **范围:** C 端 **`/api/member/message/**`** 未读数、分页列表、详情(含 **打开即已读**);**复用** 既有 `biz_member_message` 与入驻审核 **写入** 链路;**不含** 前端页面、平台消息管理、短信/Push。  
6
+> **原则:** **不新建表**;写入 **仅** `entry` 模块 `MemberEntryMessageSupport`;本模块 **只读 + 已读更新**;按 `member_id` **严格隔离**。
7
+
8
+---
9
+
10
+## 1. 技术架构
11
+
12
+| 项 | 选型 |
13
+|----|------|
14
+| 基础框架 | RuoYi **v3.9.2**(`springboot2` 分支) |
15
+| 数据库 | **MySQL 5.7.39** |
16
+| ORM / 响应 | MyBatis;`AjaxResult`(`code`、`msg`、`data`);列表 **`TableDataInfo`**(`rows`、`total`) |
17
+| 鉴权 | **`MemberAuthInterceptor`**(`MemberWebConfig` → `/api/member/**`);**无** `@Anonymous` |
18
+| 分页 | **`PageHelper`** + `startPage()`;Query `pageNum`、`pageSize` |
19
+| 缓存 | **本期不做** Redis |
20
+
21
+### 1.1 模块落位
22
+
23
+```text
24
+baqing-shop/src/main/java/com/ruoyi/web/modules/message/     # 新建 · C 端读
25
+├── controller/MemberMessageAppController.java               # /api/member/message/**
26
+├── service/IMemberMessageAppService.java
27
+├── service/impl/MemberMessageAppServiceImpl.java
28
+├── vo/
29
+│   ├── MemberMessageListItemVO.java                         # 列表行
30
+│   ├── MemberMessageDetailVO.java                           # 详情
31
+│   └── MemberMessageUnreadVO.java                           # 未读数
32
+└── constant/MemberMessageConstants.java                     # 文案/ bizType 常量(读侧)
33
+
34
+entry/(已有 · 写入 · 协作)
35
+├── domain/BizMemberMessage.java
36
+├── mapper/BizMemberMessageMapper.java                       # 扩展 select/count/updateRead
37
+├── support/MemberEntryMessageSupport.java                   # approve/reject/complete 写消息
38
+└── constant/MerchantEntryApplyConstants.java                # BIZ_TYPE_ENTRY_AUDIT、标题常量
39
+
40
+account/(已有 · 鉴权)
41
+├── config/MemberWebConfig.java                              # /api/member/** 已覆盖 message
42
+└── support/MemberContext.java、MemberAuthInterceptor.java
43
+
44
+resources/mapper/entry/BizMemberMessageMapper.xml            # 扩展 SQL
45
+sql/biz_member_message.sql                                   # 权威 DDL(已存在)
46
+```
47
+
48
+### 1.2 协作链
49
+
50
+```text
51
+【写入 · 平台入驻审核 · 已实现】
52
+    PUT /agri/merchantEntryApply/approve/{applyId}
53
+        → MemberEntryMessageSupport.sendPublicity(...)
54
+    PUT /agri/merchantEntryApply/completePublicity/{applyId}
55
+    或 MerchantEntryPublicityTask.processExpiredPublicity()
56
+        → MemberEntryMessageSupport.sendPass(...)
57
+    PUT /agri/merchantEntryApply/reject
58
+        → MemberEntryMessageSupport.sendReject(...)
59
+
60
+【本模块 · C 端读】
61
+    GET  /api/member/message/unread-count     → 红点/角标
62
+    GET  /api/member/message/list             → 分页列表
63
+    GET  /api/member/message/{messageId}      → 详情 + 标记已读
64
+
65
+【前端跳转 · 协作】
66
+    biz_type=ENTRY_AUDIT & biz_id=applyId
67
+        → 我的入驻 GET /api/merchant/entry/my(按 applyId 定位详情页)
68
+```
69
+
70
+| 关联模块 | 协作 |
71
+|----------|------|
72
+| **平台 · 商户入驻审核** | **唯一写入方**(EA14);三类消息标题/正文与 `MemberEntryMessageSupport` **一致** |
73
+| **平台 · 会员管理** | 禁用会员 **无法登录** → 本模块不可用 |
74
+| **C 端 · 我的服务 / 入驻** | 消息详情 **跳转** 至 `/api/merchant/entry/my` 对应申请 |
75
+| **C 端 · 订单/关注** | 订单/开业提醒类消息 **非本期**;`biz_type` 预留扩展 |
76
+
77
+### 1.3 职责边界
78
+
79
+| 层 | 职责 |
80
+|----|------|
81
+| `MemberEntryMessageSupport` | **insert** 消息;**不** 提供 C 端 API |
82
+| `MemberMessageAppService` | 按 `member_id` **查询**、**未读计数**、**详情并 markRead** |
83
+| C 端 Controller | **无** 创建/删除/编辑消息接口(MM8) |
84
+
85
+---
86
+
87
+## 2. 数据库设计
88
+
89
+### 2.1 复用 · 会员站内消息 `biz_member_message`
90
+
91
+> DDL 见 [`sql/biz_member_message.sql`](../../../../sql/biz_member_message.sql);**本期不 ALTER**。
92
+
93
+| 字段 | 类型 | 说明 |
94
+|------|------|------|
95
+| message_id | bigint PK | 自增 |
96
+| member_id | bigint | 收件会员;**列表/详情 WHERE 必带** |
97
+| biz_type | varchar(32) | 业务类型;本期 **`ENTRY_AUDIT`** |
98
+| biz_id | bigint | 业务主键;入驻类 = **`apply_id`** |
99
+| title | varchar(128) | 标题 |
100
+| content | varchar(1000) | 正文(含驳回原因、公示时间等) |
101
+| read_flag | char(1) | **`0`** 未读 / **`1`** 已读;默认 `0` |
102
+| create_time | datetime | 投递时间;列表 **降序** |
103
+
104
+**索引(已有):**
105
+
106
+| 索引 | 用途 |
107
+|------|------|
108
+| `idx_member_time` (member_id, create_time) | 分页列表 |
109
+| PK (message_id) | 详情 |
110
+
111
+**可选优化(非本期必做):** `idx_member_read` (member_id, read_flag) — 未读数大时加速 `COUNT`。
112
+
113
+### 2.2 业务类型枚举(本期)
114
+
115
+| biz_type | 含义 | biz_id | 写入时机 |
116
+|----------|------|--------|----------|
117
+| `ENTRY_AUDIT` | 商户入驻审核 | `apply_id` | 公示中 / 入驻完成 / 审核驳回 |
118
+
119
+**标题常量(与 `MerchantEntryApplyConstants` 对齐):**
120
+
121
+| 场景 | title |
122
+|------|-------|
123
+| 审核通过→公示 | 入驻审核通过,公示中 |
124
+| 完成公示 | 入驻完成 |
125
+| 审核驳回 | 入驻审核未通过 |
126
+
127
+### 2.3 与关联表
128
+
129
+| 表 | 关系 |
130
+|----|------|
131
+| `biz_merchant_entry_apply` | `biz_id` → `apply_id`;跳转前 **可选** 校验申请是否存在 |
132
+| `biz_member` | `member_id` → 收件人;与登录态 **一致** |
133
+
134
+---
135
+
136
+## 3. C 端接口设计
137
+
138
+**基路径:** `/api/member/message`  
139
+**鉴权:** 全部须 **`Authorization: Bearer {token}`**;未登录 → **401**「请先登录」  
140
+**MemberWebConfig:** `/api/member/**` **已拦截**,**无需追加** path。
141
+
142
+### 3.1 接口一览
143
+
144
+| 方法 | 路径 | 说明 |
145
+|------|------|------|
146
+| GET | `/api/member/message/unread-count` | 未读条数(红点) |
147
+| GET | `/api/member/message/list` | 消息分页列表 |
148
+| GET | `/api/member/message/{messageId}` | 消息详情 + **标记已读** |
149
+
150
+**本期不提供:**
151
+
152
+| 项 | 说明 |
153
+|----|------|
154
+| POST/PUT/DELETE 消息 | C 端 **不可** 创建/编辑/删除(MM8) |
155
+| 分类 Tab / 搜索 / 批量已读 | 需求 **非本期** |
156
+| 平台 B 端查会员信箱 | **无** |
157
+
158
+### 3.2 未读数 `GET /api/member/message/unread-count`
159
+
160
+| 项 | 说明 |
161
+|----|------|
162
+| 数据范围 | `member_id = MemberContext.getMemberId()` 且 `read_flag='0'` |
163
+| 响应 | `AjaxResult` → `data` |
164
+
165
+**`data` → `MemberMessageUnreadVO`:**
166
+
167
+| 字段 | 类型 | 说明 |
168
+|------|------|------|
169
+| unreadCount | int | 未读条数;**0** 时前端 **隐藏** 红点 |
170
+
171
+**SQL 要点:** `SELECT COUNT(1) FROM biz_member_message WHERE member_id=? AND read_flag='0'`
172
+
173
+### 3.3 消息列表 `GET /api/member/message/list`
174
+
175
+| 项 | 说明 |
176
+|----|------|
177
+| Query | `pageNum`、`pageSize`(RuoYi 默认) |
178
+| 排序 | `create_time DESC` |
179
+| 响应 | **`TableDataInfo`** |
180
+
181
+**`rows[]` → `MemberMessageListItemVO`:**
182
+
183
+| 字段 | 类型 | 说明 |
184
+|------|------|------|
185
+| messageId | long | |
186
+| title | string | |
187
+| summary | string | `content` **截断**(建议 ≤80 字,Service 层 `StringUtils.abbreviate`) |
188
+| readFlag | string | `0` / `1` |
189
+| createTime | string | `yyyy-MM-dd HH:mm:ss` |
190
+| bizType | string | 如 `ENTRY_AUDIT` |
191
+| bizId | long | 如 `applyId` |
192
+
193
+**空列表:** `rows=[]`,`total=0`;**非异常**。
194
+
195
+### 3.4 消息详情 `GET /api/member/message/{messageId}`
196
+
197
+| 项 | 说明 |
198
+|----|------|
199
+| 数据范围 | `message_id=? AND member_id=当前会员` |
200
+| 副作用 | 若 `read_flag='0'` → **更新为 `1`**(MM2);已读 **幂等** |
201
+| 事务 | `@Transactional`:查询 + 条件更新 **同一事务** |
202
+
203
+**不存在或非本人:** `ServiceException`「消息不存在」(**404** 或业务码,与项目统一)。
204
+
205
+**`data` → `MemberMessageDetailVO`:**
206
+
207
+| 字段 | 类型 | 说明 |
208
+|------|------|------|
209
+| messageId | long | |
210
+| title | string | 完整标题 |
211
+| content | string | 完整正文 |
212
+| readFlag | string | 返回 **`1`**(本次打开后) |
213
+| createTime | string | |
214
+| bizType | string | |
215
+| bizId | long | |
216
+| linkType | string | 跳转类型;`ENTRY_AUDIT` → **`MERCHANT_ENTRY`** |
217
+| linkAvailable | boolean | 关联 `apply_id` **是否存在**;`false` 时前端 **仅展示正文** |
218
+
219
+**跳转约定(前端):**
220
+
221
+| linkType | 行为 |
222
+|----------|------|
223
+| `MERCHANT_ENTRY` | 跳转 **我的入驻** 页,携带 `applyId=bizId`;数据来自 **`GET /api/merchant/entry/my`** |
224
+
225
+### 3.5 错误与响应格式
226
+
227
+| 场景 | code | msg(示例) |
228
+|------|------|-------------|
229
+| 未登录 | 401 | 请先登录 |
230
+| 消息不存在 | 404 或 500 | 消息不存在 |
231
+| 成功 | 200 | 操作成功 |
232
+
233
+统一 **`AjaxResult` / `TableDataInfo`**,与 C 端其它模块一致。
234
+
235
+---
236
+
237
+## 4. Service 要点
238
+
239
+### 4.1 `getUnreadCount(memberId)`
240
+
241
+```text
242
+return mapper.countUnreadByMemberId(memberId)
243
+```
244
+
245
+### 4.2 `listMessages(memberId)`(Controller 内 `startPage()`)
246
+
247
+```text
248
+return mapper.selectListByMemberId(memberId)   # ORDER BY create_time DESC
249
+→ 每行 content → summary 截断
250
+```
251
+
252
+### 4.3 `getDetailAndMarkRead(memberId, messageId)`(@Transactional)
253
+
254
+```text
255
+msg = mapper.selectByIdAndMemberId(messageId, memberId)
256
+if msg == null → throw「消息不存在」
257
+if read_flag == '0' → mapper.updateReadFlag(messageId, memberId, '1')
258
+if biz_type == ENTRY_AUDIT → linkAvailable = applyMapper.selectById(bizId) != null
259
+assemble MemberMessageDetailVO
260
+```
261
+
262
+### 4.4 Mapper 扩展(`BizMemberMessageMapper`)
263
+
264
+| 方法 | 说明 |
265
+|------|------|
266
+| `insert` | **已有** · 写入 |
267
+| `countUnreadByMemberId(Long memberId)` | 未读数 |
268
+| `selectListByMemberId(Long memberId)` | 列表(PageHelper 分页) |
269
+| `selectByIdAndMemberId(messageId, memberId)` | 详情 + 隔离 |
270
+| `updateReadFlag(messageId, memberId, readFlag)` | `WHERE message_id AND member_id` |
271
+
272
+---
273
+
274
+## 5. 与平台入驻审核写入对齐
275
+
276
+| 平台操作 | 消息方法 | title | content 要点 |
277
+|----------|----------|-------|--------------|
278
+| approve | `sendPublicity` | 入驻审核通过,公示中 | 申请编号 + 公示结束时间 |
279
+| completePublicity | `sendPass` | 入驻完成 | 申请编号 + 经营账号登录指引 |
280
+| reject | `sendReject` | 入驻审核未通过 | 申请编号 + **驳回原因** |
281
+
282
+> **本模块不修改** 上述写入逻辑;联调时核对 **标题/正文** 与《站内消息功能需求》§7 **一致** 即可。
283
+
284
+---
285
+
286
+## 6. 业务规则映射(MM)
287
+
288
+| 编号 | 实现要点 |
289
+|------|----------|
290
+| MM0 | `MemberWebConfig` + `MemberContext` |
291
+| MM1 | `unread-count` → `COUNT read_flag=0` |
292
+| MM2 | 详情接口 **同事务** 更新 `read_flag=1` |
293
+| MM3 | 写入在 **entry**;本模块 **只读** |
294
+| MM4 | content 与 `MemberEntryMessageSupport` **同源** |
295
+| MM5 | 所有 SQL **带 member_id** |
296
+| MM6 | 列表 `create_time DESC` + PageHelper |
297
+| MM7 | 详情返回 `linkType` + `bizId` |
298
+| MM8 | **无** 写/删 API |
299
+| MM9 | 代录入 **无** insert → 本模块 **无** 此类消息 |
300
+| MM10 | 仅处理已写入的 `ENTRY_AUDIT` |
301
+
302
+---
303
+
304
+## 7. 测试要点
305
+
306
+| 用例 | 预期 |
307
+|------|------|
308
+| 未登录调 list | 401 |
309
+| 会员 A 读会员 B 的 messageId | 「消息不存在」 |
310
+| 未读详情后再调 unread-count | 计数 **-1** |
311
+| 已读详情再次打开 | `read_flag` 仍为 1 |
312
+| approve 后 list | 新行 `read_flag=0`,title=公示中 |
313
+| reject 后 detail | content **含** rejectReason |
314
+| 空信箱 list | rows=[], total=0 |
315
+
316
+**建议测试类:** `MemberMessageAppServiceTest`、`MemberMessageAppControllerTest`(MockMvc + Token)。
317
+
318
+---
319
+
320
+## 8. 非本期 / 扩展
321
+
322
+| 项 | 说明 |
323
+|----|------|
324
+| 订单类 `biz_type=ORDER_*` | 订单模块建设时 **扩展** insert + linkType |
325
+| 店铺开业 `SHOP_OPEN` | 关注模块 **另册** |
326
+| `PUT .../read-all` 全部已读 | 可迭代 |
327
+| Redis 缓存未读数 | 量大时再考虑 |
328
+| 平台消息管理后台 | **无** |
329
+
330
+---
331
+
332
+## 9. 修订记录
333
+
334
+| 版本 | 说明 |
335
+|------|------|
336
+| **v1.0** | 首版:复用 `biz_member_message`;`/api/member/message` 三接口;与入驻审核写入链协作 |
337
+
338
+---
339
+
340
+*文档版本:v1.0 · 关联《站内消息功能需求.md》v1.0、《商户入驻审核技术方案.md》v1.1、《会员管理技术方案》v1.3 · 草稿保持不变。*