说明:本文件汇总来自
医生首页患者动态(patientActivities)中,用户 ID 精度丢失导致头像请求错误的问题,以及解决过程、关键修改点、测试要点与后续建议。文档以中文撰写。
在页面 src/pages/doctor/index/index.vue 中,患者动态数据原始接口返回如下(示例):
{"id":"1991836353626906625","userId":1988147181088956418,...}
但浏览器/小程序客户端请求头像的 URL 为:
https://wx.baiyun.work/user/avatar/1988147181088956400
可见 userId 发生了数值精度丢失,最后几位被截断或舍入,导致错误的头像 URL 发起请求,无法加载正确头像。
在 API 层/前端解析层把 ID 强制转换为字符串(string)
示例:在 api 的响应处理或 userActivity 的接口方法中,转换记录字段:
// src/api/userActivity.ts (示例)
const resp = response.data as any
if (resp && resp.code === 200 && resp.data) {
const safeRecords = resp.data.records.map((r: any) => ({
...r,
id: r.id === null ? null : String(r.id),
userId: r.userId === null ? null : String(r.userId),
relatedEntityId: r.relatedEntityId === null ? null : String(r.relatedEntityId)
}))
// 继续处理 safeRecords...
}
修改 TypeScript 类型
id, userId, relatedEntityId)类型从 number 改为 string,或使用 string | null。前端组件中使用字符串 ID
getPatientAvatar 和任何缓存键、URL 拼接处确保使用字符串:const idStr = String(userId)(注意这是在 ID 还未丢失的情况下才有效)。userId 等字段转为 string,前端组件直接使用。缓存 key 的统一
把 avatarCache 的 key 统一为字符串,避免使用 Number 当 key:
// avatarCache.set(String(userId), tempFilePath)
// avatarCache.get(String(userId))
避免在 JSON.parse 后直接使用数字
如果从后端一端得到大整数并要使用 JSON.parse,可以用 json-bigint 之类的库或 reviver,将 ID 字段解析为字符串。示例:
// 使用 JSONBig(json-bigint 库)
import JSONbig from 'json-bigint'
const resp = JSONbig.parse(rawResponse)
// JSONbig 能保留大整数字符串或 BigInt,视配置而定。
或者使用 reviver:
const parsed = JSON.parse(raw, (k, v) => {
if (['id', 'userId', 'relatedEntityId'].includes(k)) return v === null ? null : String(v)
return v
})
1) API 层响应转换(Node/TS 或前端 API 出片)
function normalizeIdsInRecord<T extends Record<string, any>>(record: T): T {
return {
...record,
id: record.id === null ? null : String(record.id),
userId: record.userId === null ? null : String(record.userId),
relatedEntityId: record.relatedEntityId === null ? null : String(record.relatedEntityId)
}
}
// 使用:
const safeRecords = resp.data.records.map(normalizeIdsInRecord)
2) 组件层防护(已在 index.vue 中使用,一并保证):
// 在 getPatientAvatar 中
const idStr = String(userId) // 确保传入的是字符串
// 拼接 URL
const url = `https://wx.baiyun.work/user/avatar/${idStr}`
3) Typescript 类型建议(定义):
export interface ActivityRecord {
id: string | null
userId: string | null
relatedEntityId?: string | null
activityType: string
activityDescription?: string
createTime: string
// ... other fields
}
uni.downloadFile 请求 URL,确认使用字符串化的 ID。avatarCache(键为字符串)。avatarCache.get 能成功返回缓存路径。normalizeIdsInRecord 或 API 层 transform 的行为,确保数字和字符串输入都能正确转换为字符串输出。src/api 下所有接口返回中含 id, userId, relatedEntityId 的地方src/pages/** 中对 userId 进行拼接或作为缓存 key 的地方avatarCache 的实现(键类型)uni.getStorageSync('user_info') / fetchUserInfo 中是否把 id 等字段当作 number 使用JSON.parse 直接处理接口原始返回值的地方id、userId 等主键为字符串类型(比如 JSON 的字符串 '123'),避免在前端做相应处理(最高优先级)。normalizeId 或 API 层统一解析方法,确保任何 API 响应里所有 ID 都统一为字符串(中优先级)。api 层与前端数据模型)以使用字符串 ID(中优先级)。id 字段类型是否被误用为 Number(低优先级)。"1988147181088956418")后,前端可以把 id 定义为 string 类型,不需要额外的 String() 转换。avatarCache)