Files
xinlong-shop-taro/.workbuddy/memory/2026-07-04.md
赵忠林 5c8acfd19c feat(store): 新增门店新订单提醒功能
- 新增 useNewOrderDetector Hook,实现30秒轮询检测新订单
- 订单管理页集成该 Hook,新增订单时震动+Toast提醒
- “全部”Tab 显示新订单红点,切换Tab清空未读计数
- 门店中心页增加待处理订单角标,统一待审核和待处理显示逻辑
- 底部新增“接收新订单提醒”订阅消息授权入口,调用微信接口申请授权
- 文档中补充订阅消息模板ID及字段说明,待后端配合公众号推送消息
2026-07-04 12:10:02 +08:00

118 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 2026-07-04 工作日志
## VIP会员审核功能开发
### 功能概述
为 xinlong-shop-taro 小程序新增了 VIP 会员审核功能,包含以下三个核心模块:
### 1. VIP会员审核菜单入口user.tsx
- 在"门店中心"下方添加了"VIP会员审核"菜单项
- 仅门店店员身份显示(与门店中心相同的 `storeInfo` 判断条件)
- 点击跳转到 `/pages/user/vip-review/index`
- 同时在页面加载、useDidShow、下拉刷新时调用 `checkAndCacheVipStatus` 更新当前用户的 VIP 状态缓存
### 2. VIP会员审核页面vip-review/index.tsx
- 新建页面 `src/pages/user/vip-review/index.tsx`
- 页面进入时验证当前用户是否为店员(通过 `getMyClerk()`
- 三个 Tab待审核(applyStatus=10)、已通过(20)、已驳回(30)
- 展示申请人的门店名称、门店地址、申请时间
- 店员可"通过"(设 applyStatus=20或"驳回"(设 applyStatus=30附带驳回原因
- 使用 `updateShopDealerApply` API 进行审核操作
- 与 vip-upgrade/index.tsx 配套:用户提交申请 → 店员实地考察 → 审核通过/驳回
### 3. VIP会员价格特权dealerPrice
- 创建了 VIP 状态工具 `src/utils/vip.ts`
- `isVipMember()` - 同步从缓存读取 VIP 状态
- `checkAndCacheVipStatus(userId)` - 异步检查并缓存(查询 ShopDealerApply applyStatus=20
- `getDisplayPrice(product)` - 获取商品对当前用户的实际价格
- 创建了 `src/hooks/useVipStatus.ts` Hook
- 修改了以下页面/组件支持 VIP 显示 dealerPrice
- `ProductCard` - 商品列表卡片价格
- `product-detail.tsx` - 商品详情页价格 + 立即购买传参
- `SkuSelector` - SKU 选择弹窗价格 + 确认时 fakeSku 价格
- `cart.tsx` - 购物车商品价格 + 推荐商品价格
- `CartContext.tsx` - `calcPrice` 计算总价时使用 dealerPrice
- `checkout.tsx` - 结算页金额计算 + 单价显示
### 4. 路由注册
-`app.config.ts` 中注册了 `pages/user/vip-review/index`
### 5. VIP升级页字段来源修正
- 修改 `vip-upgrade/index.tsx`
- 门店名称和门店地址不再从 `user` 对象读取,统一从 `shop-dealer-apply` 表最新记录读取
- 待审核(10) 和 已通过(20) 时只读展示;已驳回(30) 时允许编辑并重新提交
- TypeScript 类型检查通过
### 6. 审核通过时添加 VIP 角色
-`vip-review/index.tsx` 中新增了 `assignVipRole` 辅助函数
- 审核通过applyStatus=20自动调用 `addUserRole` 给申请人添加 `VIP会员` 角色roleId=2032, roleCode=vip
- 先调用 `listUserRole({ userId })` 检查用户是否已有 VIP 角色,避免重复绑定
- TypeScript 类型检查通过
### 7. 门店中心改造为仪表盘
-`store/center/index.tsx` 从订单管理页改造为功能入口仪表盘
- 新建 `store/orders/index.tsx`,将原订单管理逻辑完整搬入
- VIP会员审核入口从 `user.tsx` 独立菜单移除,统一放入门店中心仪表盘
- 门店中心仪表盘功能卡片支持扩展FEATURE_CARDS 数组,新增只需加一项)
- VIP会员审核卡片显示待审核数量角标红底白字
- TypeScript 类型检查通过
### 8. 门店中心顶部显示店员头像和门店名称
- 修改 `store/center/index.tsx` 顶部信息区
- 左侧显示圆形店员头像(读取 `storeInfo.avatar`),无头像时显示默认 👤 图标
- 右侧显示门店名称(`storeInfo.storeName`)和店员姓名 + 手机号(`storeInfo.name``storeInfo.phone`
- TypeScript 类型检查通过
### 涉及文件(补充)
- 修改:`src/pages/store/center/index.tsx`
### 9. 商品详情页价格下方 0 值隐藏
- 修改 `product-detail.tsx` 价格区域
-`dealerPrice``salePrice``memberStorePrice` 增加 `Number(value) > 0` 判断
- 0 或无效值时不再渲染,避免价格下方出现单独的 "0"
- TypeScript 类型检查通过
### 涉及文件(补充)
- 修改:`src/pages/shop/product-detail.tsx`
---
### 10. 新订单提醒功能(前端轮询 + 订阅消息)
#### 10.1 创建 useNewOrderDetector Hook
- 新建 `src/hooks/useNewOrderDetector.ts`
- 封装新订单轮询检测逻辑:
- 首次加载自动建立订单 ID 基准线,不触发提醒
- 后续轮询对比发现新订单后触发 `onNewOrders` 回调
- 页面隐藏时自动暂停轮询,显示时恢复
- 提供 `clearUnread()` 方法清除未读计数
- 导出类型:`NewOrderItem``UseNewOrderDetectorOptions``UseNewOrderDetectorReturn`
- 注册到 `src/hooks/index.ts`
#### 10.2 改造订单管理页(前端轮询)
- 修改 `src/pages/store/orders/index.tsx`
- 集成 `useNewOrderDetector`30 秒轮询,静默检测新订单
- 发现新订单时:震动提醒(`Taro.vibrateShort`+ Toast 提示("您有 N 条新订单"
- "全部" Tab 增加红色角标显示未读新订单数(>99 显示 99+
- 切换 Tab 时自动清除未读计数
#### 10.3 改造门店中心页
- 修改 `src/pages/store/center/index.tsx`
- 订单管理卡片增加待处理订单角标(查询 statusFilter=1 的 total
- VIP 审核角标同步增强,统一使用 `getBadgeCount()` 方法
- 底部新增"接收新订单提醒"卡片:
- 调用 `Taro.requestSubscribeMessage` 请求微信订阅消息授权
- 模板 ID 通过 `SUBSCRIBE_TMPL_IDS` 常量配置(待微信公众平台申请后填入)
- 授权成功后 Toast 提示
#### 待后端配合
- 微信公众平台申请订阅消息模板("新订单通知"类目)
- 将模板 ID 填入 `store/center/index.tsx``SUBSCRIBE_TMPL_IDS` 数组
- 后端在订单创建成功后调用 `subscribeMessage.send` API 向店员推送
#### 涉及文件
- 新建:`src/hooks/useNewOrderDetector.ts`
- 修改:`src/hooks/index.ts`
- 修改:`src/pages/store/orders/index.tsx`
- 修改:`src/pages/store/center/index.tsx`