# 2026-07-14 工作日志

## 门店订单页商品图片修复
- 文件：`src/pages/store/orders/index.tsx`
- 问题：订单商品图片不显示，字段名与模型不匹配
- 修复：`coverImage` → `image`、`specInfo` → `spec`、`quantity` → `totalNum`（按 `ShopOrderGoods` 模型定义）
- 图片压缩：`getCompressedImageUrl(goods.image, { width: 80 })`，展示尺寸 w-16 h-16（64px），压缩宽度 80 够用

## 门店中心新增用户管理功能
- 新页面：`src/pages/store/users/index.tsx`
- 功能：分页查询用户列表、搜索（昵称/手机号）、Tab 筛选（全部/正常/已禁用）、查看用户详情弹窗、禁用/启用用户
- 使用的 API：`pageUsers`（`/system/user/page`）、`updateUserStatus`（`/system/user/status`，参数 userId + status，0=正常 1=禁用）
- 入口：`src/pages/store/center/index.tsx` FEATURE_CARDS 中，在 VIP会员审核上方加了"用户管理"卡片（蓝色主题 👥 图标）
- 路由注册：`src/app.config.ts` 新增 `pages/store/users/index`

## 禁用用户拦截（防止被禁用用户仍可浏览小程序）
- 新增工具函数：`src/utils/auth.ts` 中 `isUserDisabled(user)` 和 `blockDisabledUser(user)`（清登录态+弹窗+跳转登录页）
- 拦截层级：
  1. **UserContext 启动校验**（`src/contexts/UserContext.tsx`）：init 时先用缓存快速显示，再异步调 `getUserInfo()` 校验 status；若被禁用则 `blockDisabledUser` 拦截
  2. **UserContext refreshUser / syncFromStorage / loginUser**：均加了 `isUserDisabled` 检查
  3. **登录 API**（`src/api/passport/login/index.ts`）：`login()` 和 `loginBySms()` 在 `saveStorageByLoginUser` 前检查 status，被禁用则 reject
  4. **登录页面**：`passport/login.tsx`、`passport/register.tsx`、`pages/store/login/index.tsx` 在保存登录态前检查 status，被禁用则弹窗拦截
- 用户状态约定：`status === 0` 正常，`status === 1` 禁用（通过 `updateUserStatus(userId, status)` 接口控制）

## 微信隐私协议（chooseImage errno:112）修复
- 报错：`MiniProgramError {errMsg:"chooseImage:fail api scope is not declared in the privacy agreement", errno:112}`（基础库 3.16.1+ 强制）
- 影响范围：所有调用 `Taro.chooseImage` 的地方，本轮修复统一入口 `uploadFile`（商品管理页、订单评价、售后申请、门店订单都走这个）
- 修复：
  1. **`src/api/system/file/index.ts`** — `uploadFile` 加 `ensurePrivacyAuthorized()` 预检（`getPrivacySetting` + `requirePrivacyAuthorize`）
  2. **`src/app.tsx`** — `useLaunch` 里注册 `Taro.onNeedPrivacyAuthorization` 回调，弹自定义 showModal 协议弹窗，同意 resolve({event:'agree'}) 拒绝 resolve({event:'disagree'})
  3. **小程序管理后台**（必须手动去配）→ 设置 → 第三方设置 → 用户隐私保护指引 → 添加「开发者收集你的相册/摄像头」声明，否则首次调用仍会触发协议弹窗
- 旧基础库兼容：`typeof wxAny.requirePrivacyAuthorize !== 'function'` 时直接放行
- ⚠️ **易错点：`requiredPrivateInfos` 字段只接受位置类 API 白名单**（chooseAddress/chooseLocation/choosePoi/getFuzzyLocation/getLocation/onLocationChange/startLocationUpdate/startLocationUpdateBackground），不要加 `chooseImage`/`chooseMedia` 等非位置类，会导致 app.json 解析失败
- 后续若别的页面直接调 `Taro.chooseImage`（如 `evaluate/index.tsx`、`after-sale/apply/index.tsx`、`store/orders/index.tsx`），仍要单独加 `ensurePrivacyAuthorized` 预检


