|
|
@@ -0,0 +1,96 @@
|
|
|
+# uni.request params 无效修复记录 — user-binding/list-by-patient
|
|
|
+
|
|
|
+## 概要 ✅
|
|
|
+在使用 `uni.request` 向后端请求 `POST /user-binding/list-by-patient` 时,尝试通过 `params` 传递 query 参数无效,问题被定位为 `uni.request` 并不会将 `params` 自动拼接到 url(或该项目的环境未实现该字段),最终采用在 URL 中拼接 Query String(`qs`)并 `encodeURIComponent` 编码后成功解决。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 问题描述 ⚠️
|
|
|
+在 `src/api/userBinding.ts` 中最初写法:
|
|
|
+
|
|
|
+```ts
|
|
|
+const res: any = await uni.request({
|
|
|
+ url: 'https://wx.baiyun.work/user-binding/list-by-patient',
|
|
|
+ method: 'POST',
|
|
|
+ data: query,
|
|
|
+ params: {
|
|
|
+ patientUserId,
|
|
|
+ bindingType
|
|
|
+ },
|
|
|
+ header: {
|
|
|
+ 'content-type': 'application/json',
|
|
|
+ Authorization: `Bearer ${token}`
|
|
|
+ }
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+希望 `params` 被自动拼接到 URL(比如 `?patientUserId=...&bindingType=...`),但实践中该字段没有生效,于是后续改为把 query 直接放到 URL:
|
|
|
+
|
|
|
+```ts
|
|
|
+const qs = `?patientUserId=${encodeURIComponent(String(patientUserId))}&bindingType=${encodeURIComponent(bindingType)}`
|
|
|
+const res: any = await uni.request({
|
|
|
+ url: 'https://wx.baiyun.work/user-binding/list-by-patient' + qs,
|
|
|
+ method: 'POST',
|
|
|
+ data: query,
|
|
|
+ header: { ... }
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+这样一来后端成功收到了查询字符串,接口返回正常。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 为什么会这样?💡
|
|
|
+- `uni.request` 支持的参数与 `axios`/`fetch` 不完全一致。某些平台/版本在 `uni.request` 中并不会自动把 `params` 拼接到 URL(尤其是在 `POST` 请求中,Get请求中可能是生效的),或者该 SDK 在实现上没有 `params` 字段(或仅在特定平台生效)。
|
|
|
+- 后端在 `list-by-patient` 端点可能通过 `@RequestParam`(Spring)、query 参数或路由匹配等方式读取 query,因此必须把参数放到 URL 中。
|
|
|
+- 另外要注意:Snowflake 等 64 位 ID 要用字符串传递以避免 JavaScript Number 精度问题(项目中已有处理)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 建议与最佳实践 🔧
|
|
|
+1. 简单而稳妥的解决方法:在 url 上手动拼接 `qs`。
|
|
|
+ - 使用 `encodeURIComponent` 对参数进行编码,避免空格或特殊字符破坏查询字符串。
|
|
|
+2. 如果你期望 `params` 自动生效:
|
|
|
+ - 查看当前 `uni-app` SDK 版本与平台(H5、小程序、App)文档,确认 `params` 是否被支持和如何使用。某些平台可能不支持把 `params` 自动序列化到 URL。
|
|
|
+3. 后端改造建议(如果可能):
|
|
|
+ - 考虑将 `list`接口改为 `GET` 请求(更语义化),或同时支持从 body 和 query 中读取参数(兼容性更好)。
|
|
|
+4. 推荐封装函数:
|
|
|
+ - 为了避免每次都手写拼接字符串,封装一个通用的构建 URL 的工具:
|
|
|
+
|
|
|
+```ts
|
|
|
+function toQueryString(obj: Record<string, any>) {
|
|
|
+ return Object.entries(obj)
|
|
|
+ .filter(([, v]) => v !== undefined && v !== null)
|
|
|
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
|
|
|
+ .join('&')
|
|
|
+}
|
|
|
+
|
|
|
+// 使用示例
|
|
|
+const qs = toQueryString({ patientUserId, bindingType })
|
|
|
+const res = await uni.request({
|
|
|
+ url: `https://wx.baiyun.work/user-binding/list-by-patient?${qs}`,
|
|
|
+ method: 'POST',
|
|
|
+ data: query,
|
|
|
+ header: {...}
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+5. 记录与测试:
|
|
|
+ - 在改动后,通过前端控制台或后端日志确认实际 hit 的 URL;
|
|
|
+ - 通过单元/集成测试模拟该请求,确保在不同平台(H5/小程序/APP)上行为一致;
|
|
|
+ - 如果使用 CORS,确保后端对 query 参数和 `Authorization` header 的处理没有冲突。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 项目里与此相关的注意点 🧭
|
|
|
+- 在 `src/api/userBinding.ts` 已用字符串处理 Snowflake ID(`String(patientUserId)`) 防止精度丢失;保持该写法即可。
|
|
|
+- 当需要批量拼接多个可选参数时,确保 `toQueryString` 过滤掉 undefined / null 值。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 结论 ✅
|
|
|
+问题的根本在于:`uni.request` 的 `params` 字段在该平台/项目里没有把参数自动拼接到 URL 上。稳妥且简单的修复是:在 URL 中手动拼接 querystring(使用 `encodeURIComponent`),或者改后端接口/规范。该修复已被验证成功。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+如需我把 `toQueryString` 工具函数也写入 `src/utils/` 并替换所有类似拼接,请回复,我可以继续实现并加上对应的单元测试。
|