|
|
@@ -1,9 +1,9 @@
|
|
1
|
1
|
# 会员注册登录 — 前端技术方案(C 端 · shop-app)
|
|
2
|
2
|
|
|
3
|
|
-> **依据:** 《会员注册登录技术方案.md》v1.2
|
|
|
3
|
+> **依据:** 《会员注册登录技术方案.md》v1.3
|
|
4
|
4
|
> **关联:** 《商品详情内页前端技术方案》(加购登录引导)、《搜索页前端技术方案》
|
|
5
|
5
|
> **范围:** 消费者 APP **会员注册、登录、服务协议勾选**;**不** 改后端、**不** 实现短信验证码、忘记密码、资料/地址编辑(另册)。
|
|
6
|
|
-> **实现状态:** 页面与 API 已落地,待与 `/api/member/**` 联调。
|
|
|
6
|
+> **实现状态:** 页面与 API 已落地;登录 Token 解析已对齐 v1.3 根级响应,待联调。
|
|
7
|
7
|
|
|
8
|
8
|
---
|
|
9
|
9
|
|
|
|
@@ -12,9 +12,10 @@
|
|
12
|
12
|
| 项 | 说明 |
|
|
13
|
13
|
|----|------|
|
|
14
|
14
|
| 框架 | uni-app **Vue 3** + **uview-plus** |
|
|
15
|
|
-| 请求 | `@/utils/request`;成功 `code=200`,业务数据在 `data` |
|
|
|
15
|
+| 请求 | `@/utils/request`;成功 `code=200`;业务体在 `data`,**登录例外**见 §4.2 |
|
|
16
|
16
|
| Token | `config` → `TOKEN_KEY = shop-Admin-Token`;请求头 `Authorization: Bearer {token}` |
|
|
17
|
|
-| 登录账号 | **手机号** 或 **会员名称**(`memberCode`,产品所称「会员 ID」) |
|
|
|
17
|
+| 鉴权机制 | 与平台一致:`TokenService` 签发 JWT,Redis 会话;不足 20 分钟自动续期(后端) |
|
|
|
18
|
+| 登录账号 | **手机号** 或 **会员名称**(`memberCode`;产品 **「会员 ID」= 会员名称**,**非** 数字 `memberId`) |
|
|
18
|
19
|
| 注册 | **无短信验证码**;`mobile + password + confirmPassword` |
|
|
19
|
20
|
| 样式 | 登录/注册共用 `styles/auth.scss` |
|
|
20
|
21
|
|
|
|
@@ -44,10 +45,10 @@
|
|
44
|
45
|
|------|------|------|
|
|
45
|
46
|
| 登录页 | `shop-app/pages/login/index.vue` | 账号+密码+协议+记住账号 |
|
|
46
|
47
|
| 注册页 | `shop-app/subpackage/account/register.vue` | 手机号注册表单 |
|
|
47
|
|
-| 协议块 | `shop-app/components/account/AgreementBlock.vue` | 勾选 + 弹窗 **`rich-text`** 渲染(同商品详情) |
|
|
|
48
|
+| 协议块 | `shop-app/components/account/AgreementBlock.vue` | 勾选 + 弹窗 **`rich-text`** 渲染 |
|
|
48
|
49
|
| HTML 预处理 | `shop-app/utils/htmlContent.js` | 实体解码、图片 URL、空 `<p>` 清理 |
|
|
49
|
50
|
| API | `shop-app/api/member.js` | register / login / serviceAgreement / profile |
|
|
50
|
|
-| 状态 | `shop-app/store/user.js` | 登录态、资料缓存 |
|
|
|
51
|
+| 状态 | `shop-app/store/user.js` | 登录态、**根级 token** 解析、资料缓存 |
|
|
51
|
52
|
| 协议加载 | `shop-app/utils/memberAgreement.js` | 初始化协议配置 |
|
|
52
|
53
|
| 校验 | `shop-app/utils/memberValidate.js` | 手机号、密码 |
|
|
53
|
54
|
| 登录引导 | `shop-app/utils/apiAuth.js` | `ensureApiToken` → 登录页 |
|
|
|
@@ -69,6 +70,8 @@
|
|
69
|
70
|
| `getMemberServiceAgreement()` | GET | `/api/member/serviceAgreement` | 匿名 |
|
|
70
|
71
|
| `getMemberProfile()` | GET | `/api/member/profile` | Token |
|
|
71
|
72
|
|
|
|
73
|
+可选(本期未单独封装):`GET /api/member/serviceAgreement/status` — 仅开关;注册/登录页用完整 `serviceAgreement` 即可。
|
|
|
74
|
+
|
|
72
|
75
|
### 4.1 注册 Body
|
|
73
|
76
|
|
|
74
|
77
|
| 字段 | 必填 | 前端 |
|
|
|
@@ -79,15 +82,40 @@
|
|
79
|
82
|
| memberCode | 否 | 会员名称,空则后端自动生成 |
|
|
80
|
83
|
| agreementAccepted | 条件 | 协议 `enabled` 时须勾选 |
|
|
81
|
84
|
|
|
82
|
|
-### 4.2 登录 Body
|
|
|
85
|
+**成功 `data`:** 系统主键 `memberId`(long);**不能** 作为登录账号,注册成功后跳转登录页用 **手机号** 登录。
|
|
|
86
|
+
|
|
|
87
|
+### 4.2 登录 Body 与响应(v1.3)
|
|
83
|
88
|
|
|
84
|
89
|
| 字段 | 必填 | 前端 |
|
|
85
|
90
|
|------|:----:|------|
|
|
86
|
|
-| account | 是 | 手机号或会员名称 |
|
|
|
91
|
+| account | 是 | 手机号或会员名称(产品所称会员 ID) |
|
|
87
|
92
|
| password | 是 | — |
|
|
88
|
93
|
| agreementAccepted | 条件 | `requireAgreementOnLogin` 为 true 时须勾选 |
|
|
89
|
94
|
|
|
90
|
|
-**成功 `data`:** `{ token, memberId }`(`memberId` 为系统主键,**不能**当登录账号)。
|
|
|
95
|
+**成功响应(与平台 `POST /login` 一致,字段在 JSON 根级):**
|
|
|
96
|
+
|
|
|
97
|
+```json
|
|
|
98
|
+{
|
|
|
99
|
+ "code": 200,
|
|
|
100
|
+ "msg": "操作成功",
|
|
|
101
|
+ "token": "eyJhbGciOiJIUzUxMiJ9...",
|
|
|
102
|
+ "memberId": 1001
|
|
|
103
|
+}
|
|
|
104
|
+```
|
|
|
105
|
+
|
|
|
106
|
+| 字段 | 说明 |
|
|
|
107
|
+|------|------|
|
|
|
108
|
+| `token` | 存本地 + 请求头 `Authorization: Bearer {token}` |
|
|
|
109
|
+| `memberId` | **系统主键**,仅资料展示;**不可** 填入登录框 |
|
|
|
110
|
+
|
|
|
111
|
+**`store/user.js` 解析:**
|
|
|
112
|
+
|
|
|
113
|
+```javascript
|
|
|
114
|
+const token = res.token || (res.data && res.data.token)
|
|
|
115
|
+const memberId = res.memberId != null ? res.memberId : (res.data && res.data.memberId)
|
|
|
116
|
+```
|
|
|
117
|
+
|
|
|
118
|
+> **兼容:** 后端若仍传 `mobile` 且 `account` 为空,由服务端等同 `account=mobile`;前端统一传 `account`。
|
|
91
|
119
|
|
|
92
|
120
|
### 4.3 服务协议 `data` 要点
|
|
93
|
121
|
|
|
|
@@ -107,19 +135,20 @@
|
|
107
|
135
|
```text
|
|
108
|
136
|
顶栏品牌区
|
|
109
|
137
|
└── 卡片
|
|
110
|
|
- ├── 账号(手机号或会员名称)
|
|
|
138
|
+ ├── 账号(手机号或会员名称 / 会员 ID)
|
|
111
|
139
|
├── 密码
|
|
112
|
140
|
├── 记住账号(localStorage: shop_login_account)
|
|
113
|
141
|
├── AgreementBlock(协议启用且 requireAgreementOnLogin 时显示)
|
|
114
|
|
- ├── 登录按钮 → memberLogin → fetchUserInfo → switchTab 首页
|
|
|
142
|
+ ├── 登录按钮 → memberLogin → 读根级 token → fetchUserInfo → switchTab 首页
|
|
115
|
143
|
└── 立即注册 → subpackage/account/register
|
|
116
|
144
|
```
|
|
117
|
145
|
|
|
118
|
146
|
| 规则 | 实现 |
|
|
119
|
147
|
|------|------|
|
|
120
|
|
-| RL3 | 单输入框 `account` |
|
|
|
148
|
+| RL3 | 单输入框 `account`;文案标明「会员 ID = 会员名称」 |
|
|
121
|
149
|
| RL4 | 错误文案由后端统一返回,前端 Toast `msg` |
|
|
122
|
150
|
| RL6 | `needAgreement` 计算属性控制勾选 |
|
|
|
151
|
+| RL8 | 不把 `memberId` 当登录账号 |
|
|
123
|
152
|
| 已登录进页 | 有 Token 直接 `switchTab` 首页 |
|
|
124
|
153
|
|
|
125
|
154
|
### 5.2 注册 `subpackage/account/register`
|
|
|
@@ -155,6 +184,7 @@
|
|
155
|
184
|
|
|
156
|
185
|
```text
|
|
157
|
186
|
memberLogin 成功
|
|
|
187
|
+ → 解析 res.token(根级)
|
|
158
|
188
|
→ setToken(token)
|
|
159
|
189
|
→ getMemberProfile() 写入 store
|
|
160
|
190
|
→ 业务请求带 Authorization
|
|
|
@@ -167,7 +197,7 @@ request 401(需登录接口)
|
|
167
|
197
|
→ fedLogOut + reLaunch 登录页
|
|
168
|
198
|
```
|
|
169
|
199
|
|
|
170
|
|
-**退出:** 仅本地 `fedLogOut`(后端无 C 端 logout 接口)。
|
|
|
200
|
+**退出:** 仅本地 `fedLogOut`(C 端无专用 logout 接口;与 v1.3 Token 机制不冲突)。
|
|
171
|
201
|
|
|
172
|
202
|
---
|
|
173
|
203
|
|
|
|
@@ -177,10 +207,10 @@ request 401(需登录接口)
|
|
177
|
207
|
|------|----------|
|
|
178
|
208
|
| RL1 | 注册页无验证码 |
|
|
179
|
209
|
| RL2 | 确认密码前端校验 |
|
|
180
|
|
-| RL3 | 登录 `account` 字段 |
|
|
|
210
|
+| RL3 | 登录 `account` 字段;UI 提示会员 ID = 会员名称 |
|
|
181
|
211
|
| RL4 | 不区分「用户不存在/密码错误」展示 |
|
|
182
|
212
|
| RL6 | `AgreementBlock` + 提交前校验 |
|
|
183
|
|
-| RL8 | UI 提示「会员名称」;`memberId` 仅展示在资料区(若有) |
|
|
|
213
|
+| RL8 | `memberId` 仅 store/资料;登录框不用数字主键 |
|
|
184
|
214
|
|
|
185
|
215
|
---
|
|
186
|
216
|
|
|
|
@@ -188,7 +218,8 @@ request 401(需登录接口)
|
|
188
|
218
|
|
|
189
|
219
|
- [ ] `GET /api/member/serviceAgreement` 返回开关与正文
|
|
190
|
220
|
- [ ] `POST /api/member/register` 成功 → 登录页预填手机号
|
|
191
|
|
-- [ ] `POST /api/member/login` 手机号 / 会员名称均可登录
|
|
|
221
|
+- [ ] `POST /api/member/login` 返回 **根级** `token`、`memberId`;前端能登录并进首页
|
|
|
222
|
+- [ ] 手机号 / 会员名称(会员 ID)均可登录
|
|
192
|
223
|
- [ ] 协议未勾选时注册/登录被后端拒绝且 Toast 文案正确
|
|
193
|
224
|
- [ ] 登录后 `GET /api/member/profile` 我的页展示昵称/手机号
|
|
194
|
225
|
- [ ] 商品详情加购无 Token 跳转登录页
|
|
|
@@ -202,6 +233,7 @@ request 401(需登录接口)
|
|
202
|
233
|
|----|------|
|
|
203
|
234
|
| 短信验证码 | 不做 |
|
|
204
|
235
|
| 忘记密码 / 换绑手机 | 不做 |
|
|
|
236
|
+| 以数字 `member_id` 登录 | 不做 |
|
|
205
|
237
|
| 资料编辑 / 地址管理 | 另册;接口已存在 `/profile`、`/address/**` |
|
|
206
|
238
|
| 微信 OAuth | 不做 |
|
|
207
|
239
|
|
|
|
@@ -212,7 +244,8 @@ request 401(需登录接口)
|
|
212
|
244
|
| 版本 | 说明 |
|
|
213
|
245
|
|------|------|
|
|
214
|
246
|
| **v1.0** | 首版:会员登录改造、注册分包页、协议组件、我的页入口 |
|
|
|
247
|
+| **v1.1** | 对齐后端 v1.3:登录 **根级** `token`/`memberId` 解析;登录文案「会员 ID」;联调清单补充 |
|
|
215
|
248
|
|
|
216
|
249
|
---
|
|
217
|
250
|
|
|
218
|
|
-*文档版本:v1.0 · 关联《会员注册登录技术方案.md》v1.2*
|
|
|
251
|
+*文档版本:v1.1 · 关联《会员注册登录技术方案.md》v1.3*
|