hookehuyr

refactor(api): 简化 API 参数结构并更新配置

- 移除 API 中的 `t` 参数和 `client_name` 参数,简化 URL 构建
- 更新生产/开发环境域名为 manulife.onwall.cn
- 启用授权模式(ENABLE_AUTH_MODE = true)
- 将废弃的 substr 替换为 substring
- 添加认证调试指南文档(docs/auth-debug-guide.md)
- 更新 API 文档状态(testing/developing)
- 优化登录和退出登录的 JSDoc 注释

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -125,7 +125,7 @@ paths: ...@@ -125,7 +125,7 @@ paths:
125 x-apifox-ordering: 0 125 x-apifox-ordering: 0
126 security: [] 126 security: []
127 x-apifox-folder: 意见反馈 127 x-apifox-folder: 意见反馈
128 - x-apifox-status: released 128 + x-apifox-status: developing
129 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906670-run 129 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906670-run
130 components: 130 components:
131 schemas: {} 131 schemas: {}
......
...@@ -99,7 +99,7 @@ paths: ...@@ -99,7 +99,7 @@ paths:
99 x-apifox-ordering: 0 99 x-apifox-ordering: 0
100 security: [] 100 security: []
101 x-apifox-folder: 意见反馈 101 x-apifox-folder: 意见反馈
102 - x-apifox-status: released 102 + x-apifox-status: developing
103 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906671-run 103 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906671-run
104 components: 104 components:
105 schemas: {} 105 schemas: {}
......
...@@ -96,7 +96,7 @@ paths: ...@@ -96,7 +96,7 @@ paths:
96 x-apifox-ordering: 0 96 x-apifox-ordering: 0
97 security: [] 97 security: []
98 x-apifox-folder: 消息 98 x-apifox-folder: 消息
99 - x-apifox-status: released 99 + x-apifox-status: developing
100 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906673-run 100 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906673-run
101 components: 101 components:
102 schemas: {} 102 schemas: {}
......
...@@ -103,7 +103,7 @@ paths: ...@@ -103,7 +103,7 @@ paths:
103 x-apifox-ordering: 0 103 x-apifox-ordering: 0
104 security: [] 104 security: []
105 x-apifox-folder: 消息 105 x-apifox-folder: 消息
106 - x-apifox-status: released 106 + x-apifox-status: developing
107 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906672-run 107 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906672-run
108 components: 108 components:
109 schemas: {} 109 schemas: {}
......
...@@ -90,7 +90,7 @@ paths: ...@@ -90,7 +90,7 @@ paths:
90 x-apifox-ordering: 0 90 x-apifox-ordering: 0
91 security: [] 91 security: []
92 x-apifox-folder: 用户 92 x-apifox-folder: 用户
93 - x-apifox-status: released 93 + x-apifox-status: testing
94 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906668-run 94 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906668-run
95 components: 95 components:
96 schemas: {} 96 schemas: {}
......
...@@ -49,10 +49,6 @@ paths: ...@@ -49,10 +49,6 @@ paths:
49 password: 49 password:
50 example: '000000' 50 example: '000000'
51 type: string 51 type: string
52 - openid:
53 - description: 要绑定的小程序openid
54 - example: ''
55 - type: string
56 required: 52 required:
57 - uuid 53 - uuid
58 - password 54 - password
...@@ -81,7 +77,7 @@ paths: ...@@ -81,7 +77,7 @@ paths:
81 x-apifox-ordering: 0 77 x-apifox-ordering: 0
82 security: [] 78 security: []
83 x-apifox-folder: 用户 79 x-apifox-folder: 用户
84 - x-apifox-status: released 80 + x-apifox-status: testing
85 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906666-run 81 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906666-run
86 components: 82 components:
87 schemas: {} 83 schemas: {}
......
1 -# 退出登录 1 +# 退出登录并解绑openid
2 2
3 ## OpenAPI Specification 3 ## OpenAPI Specification
4 4
...@@ -10,7 +10,7 @@ info: ...@@ -10,7 +10,7 @@ info:
10 paths: 10 paths:
11 /srv/: 11 /srv/:
12 post: 12 post:
13 - summary: 退出登录 13 + summary: 退出登录并解绑openid
14 deprecated: false 14 deprecated: false
15 description: '' 15 description: ''
16 tags: 16 tags:
...@@ -68,7 +68,7 @@ paths: ...@@ -68,7 +68,7 @@ paths:
68 x-apifox-ordering: 0 68 x-apifox-ordering: 0
69 security: [] 69 security: []
70 x-apifox-folder: 用户 70 x-apifox-folder: 用户
71 - x-apifox-status: released 71 + x-apifox-status: testing
72 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906667-run 72 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906667-run
73 components: 73 components:
74 schemas: {} 74 schemas: {}
......
...@@ -75,7 +75,7 @@ paths: ...@@ -75,7 +75,7 @@ paths:
75 x-apifox-ordering: 0 75 x-apifox-ordering: 0
76 security: [] 76 security: []
77 x-apifox-folder: 用户 77 x-apifox-folder: 用户
78 - x-apifox-status: released 78 + x-apifox-status: developing
79 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906669-run 79 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906669-run
80 components: 80 components:
81 schemas: {} 81 schemas: {}
......
...@@ -29,18 +29,11 @@ paths: ...@@ -29,18 +29,11 @@ paths:
29 type: string 29 type: string
30 - name: a 30 - name: a
31 in: query 31 in: query
32 - description: 文件夹名称 32 + description: ''
33 required: true 33 required: true
34 example: openid 34 example: openid
35 schema: 35 schema:
36 type: string 36 type: string
37 - - name: t
38 - in: query
39 - description: 接口的具体功能
40 - required: true
41 - example: wxapp
42 - schema:
43 - type: string
44 - name: code 37 - name: code
45 in: query 38 in: query
46 description: '' 39 description: ''
...@@ -109,7 +102,7 @@ paths: ...@@ -109,7 +102,7 @@ paths:
109 x-apifox-ordering: 0 102 x-apifox-ordering: 0
110 security: [] 103 security: []
111 x-apifox-folder: 微信 104 x-apifox-folder: 微信
112 - x-apifox-status: released 105 + x-apifox-status: testing
113 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906665-run 106 x-run-in-apifox: https://app.apifox.com/web/project/7792797/apis/api-413906665-run
114 components: 107 components:
115 schemas: {} 108 schemas: {}
......
1 +# MiniProgramAuth 接口联调指南
2 +
3 +## 📋 配置完成情况
4 +
5 +### ✅ 已完成的配置
6 +
7 +1. **域名配置**
8 + - 开发环境:`https://oa-dev.onwall.cn`
9 + - 生产环境:`https://manulife.onwall.cn`
10 +
11 +2. **接口路径统一**
12 + - 统一使用 `a=openid` 参数
13 + - 完整接口:`https://oa-dev.onwall.cn/srv/?a=openid&f=manulife`
14 +
15 +3. **授权模式**
16 + - 已启用:`ENABLE_AUTH_MODE = true`
17 +
18 +4. **请求参数**
19 + - 移除了 `client_name` 参数
20 + - 保留 `f=manulife` 业务模块标识
21 +
22 +## 🧪 测试步骤
23 +
24 +### 步骤 1: 启动项目
25 +
26 +```bash
27 +# 开发环境(默认使用 oa-dev.onwall.cn)
28 +pnpm dev:weapp
29 +```
30 +
31 +### 步骤 2: 微信开发者工具配置
32 +
33 +1. 打开微信开发者工具
34 +2. 导入项目(选择项目根目录)
35 +3. **不勾选**"不校验合法域名"(测试真实接口)
36 +4. 确保已登录微信开发者账号
37 +
38 +### 步骤 3: 测试授权流程
39 +
40 +#### 测试点 1: 首次授权(无 sessionid)
41 +
42 +**操作**
43 +1. 清除小程序缓存(微信开发者工具 → 清除缓存 → 清除全部)
44 +2. 刷新小程序
45 +3. 观察控制台日志
46 +
47 +**预期结果**
48 +```
49 +✅ 应该看到以下流程:
50 +1. app.js 启动时调用 silentAuth()
51 +2. Taro.login() 获取微信 code
52 +3. 调用接口: POST https://oa-dev.onwall.cn/srv/?a=openid&f=manulife
53 +4. 请求体: { code: "xxx" }
54 +5. 接口返回: { code: 1, data: { user: {...} } }
55 +6. 提取 cookie 并写入 localStorage.sessionid
56 +```
57 +
58 +**检查点**
59 +- [ ] 控制台无错误
60 +- [ ] `localStorage.sessionid` 有值
61 +- [ ] 接口返回 `code: 1`
62 +
63 +#### 测试点 2: 已授权用户(有 sessionid)
64 +
65 +**操作**
66 +1. 关闭小程序
67 +2. 重新打开(不清除缓存)
68 +3. 观察控制台日志
69 +
70 +**预期结果**
71 +```
72 +✅ 应该看到以下流程:
73 +1. hasAuth() 返回 true(检测到 sessionid)
74 +2. 跳过授权流程
75 +3. 直接进入首页
76 +```
77 +
78 +**检查点**
79 +- [ ] 不会重复调用授权接口
80 +- [ ] 直接显示首页内容
81 +
82 +#### 测试点 3: 401 自动刷新
83 +
84 +**操作**
85 +1. 手动删除 `localStorage.sessionid`
86 +2. 访问任何需要登录的接口
87 +3. 观察自动刷新流程
88 +
89 +**预期结果**
90 +```
91 +✅ 应该看到以下流程:
92 +1. 接口返回 401
93 +2. request.js 拦截器捕获 401
94 +3. 调用 refreshSession()
95 +4. Taro.login() 获取新 code
96 +5. 重新调用授权接口
97 +6. 重放原始请求
98 +```
99 +
100 +**检查点**
101 +- [ ] 用户无感知(静默刷新)
102 +- [ ] 原始请求自动重放成功
103 +- [ ] 新的 sessionid 已保存
104 +
105 +#### 测试点 4: 授权页跳转(降级方案)
106 +
107 +**操作**
108 +1. 模拟授权失败(修改接口返回错误)
109 +2. 观察是否跳转到授权页
110 +
111 +**预期结果**
112 +```
113 +✅ 应该看到以下流程:
114 +1. 授权失败
115 +2. 保存当前页面路径
116 +3. 跳转到 /pages/auth/index
117 +4. 授权成功后回跳原页面
118 +```
119 +
120 +**检查点**
121 +- [ ] 正确跳转到授权页
122 +- [ ] 授权成功后回跳正确
123 +- [ ] 路径参数不丢失
124 +
125 +## 📊 接口说明
126 +
127 +### 请求格式
128 +
129 +```http
130 +POST https://oa-dev.onwall.cn/srv/?a=openid&f=manulife
131 +Content-Type: application/json
132 +
133 +{
134 + "code": "微信登录code"
135 +}
136 +```
137 +
138 +### 响应格式
139 +
140 +**成功响应**
141 +```json
142 +{
143 + "code": 1,
144 + "msg": "success",
145 + "data": {
146 + "user": {
147 + "id": 123,
148 + "avatar_url": "https://...",
149 + "name": "用户姓名"
150 + }
151 + }
152 +}
153 +```
154 +
155 +**Cookie 处理**
156 +- 后端通过 `Set-Cookie` 头返回 sessionid
157 +- 小程序端从 `response.cookies[0]` 读取
158 +- H5 端从 `response.header['set-cookie']` 读取
159 +
160 +## 🐛 常见问题排查
161 +
162 +### 问题 1: 接口返回 404
163 +
164 +**原因**:接口路径错误
165 +
166 +**检查**
167 +```javascript
168 +// 确认 buildApiUrl 构建的 URL
169 +console.log(buildApiUrl('openid'))
170 +// 应该输出: https://oa-dev.onwall.cn/srv/?a=openid&f=manulife
171 +```
172 +
173 +**解决**:确认后端接口参数为 `a=openid`
174 +
175 +### 问题 2: 接口返回 403
176 +
177 +**原因**:域名未白名单
178 +
179 +**检查**
180 +- 微信开发者工具 → 详情 → 本地设置
181 +- 确认是否勾选了"不校验合法域名"
182 +
183 +**解决**
184 +1. 开发阶段:勾选"不校验合法域名"
185 +2. 生产环境:在微信公众平台配置服务器域名白名单
186 +
187 +### 问题 3: Cookie 未保存
188 +
189 +**原因**:后端未返回 Set-Cookie
190 +
191 +**检查**
192 +```javascript
193 +// 在 refreshSession 中添加日志
194 +const response = await Taro.request({...})
195 +console.log('响应头:', response.header)
196 +console.log('Cookie:', response.cookies)
197 +```
198 +
199 +**解决**
200 +- 确认后端返回了 `Set-Cookie`
201 +- 小程序端确保返回格式正确
202 +
203 +### 问题 4: 授权后仍然跳转登录页
204 +
205 +**原因**:sessionid 未正确保存
206 +
207 +**检查**
208 +```javascript
209 +// 在控制台执行
210 +console.log(Taro.getStorageSync('sessionid'))
211 +```
212 +
213 +**解决**
214 +- 确认 `extractCookie()` 函数正确提取了 cookie
215 +- 确认 `Taro.setStorageSync('sessionid', cookie)` 成功执行
216 +
217 +## 🔍 调试技巧
218 +
219 +### 1. 开启详细日志
220 +
221 +`src/utils/request.js` 拦截器中添加日志:
222 +
223 +```javascript
224 +// 请求拦截器
225 +config => {
226 + console.log('🔵 请求:', config.url, config.data)
227 + return config
228 +}
229 +
230 +// 响应拦截器
231 +response => {
232 + console.log('🟢 响应:', response.config.url, response.data)
233 + return response
234 +}
235 +
236 +// 错误拦截器
237 +error => {
238 + console.error('🔴 错误:', error.config?.url, error.response?.status)
239 + return Promise.reject(error)
240 +}
241 +```
242 +
243 +### 2. 监控网络请求
244 +
245 +微信开发者工具 → Network 面板:
246 +- 查看 `openid` 接口请求
247 +- 确认请求参数和响应格式
248 +- 检查 Cookie 是否正确返回
249 +
250 +### 3. 查看 Storage
251 +
252 +微信开发者工具 → Storage 面板:
253 +- 确认 `sessionid` 存在
254 +- 查看值是否正确
255 +
256 +## ✅ 验收标准
257 +
258 +联调通过的标准:
259 +
260 +- [ ] 首次授权能成功获取 sessionid
261 +- [ ] 已授权用户能直接进入首页
262 +- [ ] 401 时能自动刷新 sessionid
263 +- [ ] 授权失败时能跳转到授权页
264 +- [ ] 授权成功后能正确回跳
265 +- [ ] 所有接口请求都能带上 sessionid
266 +
267 +## 📝 后续优化建议
268 +
269 +1. **添加加载提示**:授权时显示 loading
270 +2. **错误提示优化**:友好的错误文案
271 +3. **重试机制**:授权失败时的重试策略
272 +4. **埋点统计**:授权成功率统计
273 +
274 +## 📞 联系方式
275 +
276 +如有问题,请联系开发团队。
...@@ -31,7 +31,6 @@ export const getProfileAPI = (params) => fn(fetch.get(Api.GetProfile, params)); ...@@ -31,7 +31,6 @@ export const getProfileAPI = (params) => fn(fetch.get(Api.GetProfile, params));
31 * @param {Object} params 请求参数 31 * @param {Object} params 请求参数
32 * @param {string} params.uuid 32 * @param {string} params.uuid
33 * @param {string} params.password 33 * @param {string} params.password
34 - * @param {string} params.openid (可选) 要绑定的小程序openid
35 * @returns {Promise<{ 34 * @returns {Promise<{
36 * code: number; // 状态码 35 * code: number; // 状态码
37 * msg: string; // 消息 36 * msg: string; // 消息
...@@ -41,7 +40,7 @@ export const getProfileAPI = (params) => fn(fetch.get(Api.GetProfile, params)); ...@@ -41,7 +40,7 @@ export const getProfileAPI = (params) => fn(fetch.get(Api.GetProfile, params));
41 export const loginAPI = (params) => fn(fetch.post(Api.Login, params)); 40 export const loginAPI = (params) => fn(fetch.post(Api.Login, params));
42 41
43 /** 42 /**
44 - * @description 退出登录 43 + * @description 退出登录并解绑openid
45 * @remark 44 * @remark
46 * @param {Object} params 请求参数 45 * @param {Object} params 请求参数
47 * @returns {Promise<{ 46 * @returns {Promise<{
......
1 import { fn, fetch } from '@/api/fn'; 1 import { fn, fetch } from '@/api/fn';
2 2
3 const Api = { 3 const Api = {
4 - MiniProgramAuth: '/srv/?a=openid&t=wxapp', 4 + MiniProgramAuth: '/srv/?a=openid',
5 } 5 }
6 6
7 /** 7 /**
......
...@@ -134,7 +134,7 @@ export const refreshSession = async (options) => { ...@@ -134,7 +134,7 @@ export const refreshSession = async (options) => {
134 134
135 // 换取后端会话(服务端通过 Set-Cookie 返回会话信息) 135 // 换取后端会话(服务端通过 Set-Cookie 返回会话信息)
136 const response = await Taro.request({ 136 const response = await Taro.request({
137 - url: buildApiUrl('openid_wxapp'), 137 + url: buildApiUrl('openid'),
138 method: 'POST', 138 method: 'POST',
139 data: request_data, 139 data: request_data,
140 }) 140 })
......
1 /* 1 /*
2 * @Date: 2026-01-29 10:48:35 2 * @Date: 2026-01-29 10:48:35
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-02-02 15:28:09 4 + * @LastEditTime: 2026-02-02 16:43:52
5 * @FilePath: /manulife-weapp/src/utils/config.js 5 * @FilePath: /manulife-weapp/src/utils/config.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -17,18 +17,17 @@ ...@@ -17,18 +17,17 @@
17 * @type {string} 17 * @type {string}
18 */ 18 */
19 const BASE_URL = process.env.NODE_ENV === 'production' 19 const BASE_URL = process.env.NODE_ENV === 'production'
20 - ? 'https://your-production-domain.com' // 🔧 修改为生产环境域名 20 + ? 'https://manulife.onwall.cn' // 生产环境域名
21 - : 'https://your-dev-domain.com' // 🔧 修改为开发环境域名 21 + : 'https://manulife.onwall.cn' // 开发环境域名
22 + // : 'https://oa-dev.onwall.cn' // 开发环境域名
22 23
23 /** 24 /**
24 * 接口默认公共参数(避免在多个文件里硬编码) 25 * 接口默认公共参数(避免在多个文件里硬编码)
25 - * - f:业务模块标识(请修改为您的业务模块) 26 + * - f:业务模块标识
26 - * - client_name:客户端标识(请修改为您的应用名称) 27 + * - a: 接口功能参数
27 - * - a: 文件夹名称
28 - * - t :接口的具体功能
29 */ 28 */
30 export const REQUEST_DEFAULT_PARAMS = { 29 export const REQUEST_DEFAULT_PARAMS = {
31 - f: 'manulife', // 🔧 修改为业务模块标识 30 + f: 'manulife', // 业务模块标识
32 } 31 }
33 32
34 /** 33 /**
...@@ -36,6 +35,6 @@ export const REQUEST_DEFAULT_PARAMS = { ...@@ -36,6 +35,6 @@ export const REQUEST_DEFAULT_PARAMS = {
36 * - true: 启用授权检查、自动跳转登录、401自动续期 35 * - true: 启用授权检查、自动跳转登录、401自动续期
37 * - false: 禁用所有授权相关功能(所有授权检查直接通过,不跳转登录页) 36 * - false: 禁用所有授权相关功能(所有授权检查直接通过,不跳转登录页)
38 */ 37 */
39 -export const ENABLE_AUTH_MODE = false 38 +export const ENABLE_AUTH_MODE = true // 启用授权模式
40 39
41 export default BASE_URL 40 export default BASE_URL
......
...@@ -42,7 +42,7 @@ const wxInfo = () => { ...@@ -42,7 +42,7 @@ const wxInfo = () => {
42 const parseQueryString = url => { 42 const parseQueryString = url => {
43 if (!url) return {}; 43 if (!url) return {};
44 var json = {}; 44 var json = {};
45 - var arr = url.indexOf('?') >= 0 ? url.substr(url.indexOf('?') + 1).split('&') : []; 45 + var arr = url.indexOf('?') >= 0 ? url.substring(url.indexOf('?') + 1).split('&') : [];
46 arr.forEach(item => { 46 arr.forEach(item => {
47 var tmp = item.split('='); 47 var tmp = item.split('=');
48 json[tmp[0]] = tmp[1]; 48 json[tmp[0]] = tmp[1];
...@@ -184,15 +184,14 @@ const get_bill_status_text = (status) => { ...@@ -184,15 +184,14 @@ const get_bill_status_text = (status) => {
184 184
185 /** 185 /**
186 * @description 构建 API 请求 URL(带默认公共参数) 186 * @description 构建 API 请求 URL(带默认公共参数)
187 - * @param {string} action 接口动作名称(例如:openid_wxapp 187 + * @param {string} action 接口动作名称(例如:openid)
188 * @param {Object} [params={}] 额外 query 参数 188 * @param {Object} [params={}] 额外 query 参数
189 - * @returns {string} 完整请求 URL(BASE_URL + /srv/?a=...&f=...&client_name=... 189 + * @returns {string} 完整请求 URL(BASE_URL + /srv/?a=...&f=...)
190 */ 190 */
191 const buildApiUrl = (action, params = {}) => { 191 const buildApiUrl = (action, params = {}) => {
192 const queryParams = new URLSearchParams({ 192 const queryParams = new URLSearchParams({
193 a: action, 193 a: action,
194 f: REQUEST_DEFAULT_PARAMS.f, 194 f: REQUEST_DEFAULT_PARAMS.f,
195 - client_name: REQUEST_DEFAULT_PARAMS.client_name,
196 ...params, 195 ...params,
197 }) 196 })
198 return `${BASE_URL}/srv/?${queryParams.toString()}` 197 return `${BASE_URL}/srv/?${queryParams.toString()}`
......