Files
dukang/杜康好客-v3.4.18-门店体验与登录态优化.md
T
jacy 18147e157f
CI / verify (push) Has been cancelled
fix(mini-user): 门店套餐图片自适应完整显示,不再裁剪
- ProductCarousel 新增 imageFit="adaptive"(widthFix + 动态高度)
- 门店套餐详情按图片真实比例自适应高度,完整显示不裁剪
- 补充 v3.4.18 文档 F 项

Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
2026-08-17 21:48:06 +08:00

113 lines
10 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.
# 杜康好客 · v3.4.18 门店体验与登录态优化
> **2026-08-17** · mini-user `3.4.18` / h5-partner / h5-shop / API
> 目标:用户小程序端门店电话与套餐图体验优化;城市合伙人「暂停」账号禁止登录;门店端结算页留白对齐与「休息中能否开张核销」交互。
## 范围
| 项 | 交付 |
|----|------|
| A. mini-user 门店座机电话脱敏 | `maskPhone` 统一「中间四位隐藏」;门店详情已调用 |
| B. mini-user 套餐详情图 1/5 + 自动轮播 | `ProductCarousel` detail 变体 autoplay + 右下角 `1/5` 计数 |
| C. 合伙人账号暂停禁止登录 | 非 `ACTIVE` → 登录/发码均拒,提示「该账号已暂停使用,请联系客服人员」 |
| D. 门店端 申请提现 / 筛选栏留白对齐 | `WithdrawPage` 左右内边距统一 `--space-page` |
| E. 门店端 休息中核销 → 是否开启营业 | 核销页拦截时弹「是否开启营业?」,确认即开张后继续核销 |
| F. mini-user 门店套餐图片自适应完整显示 | `ProductCarousel` 新增 `imageFit="adaptive"`(widthFix + 动态高度),门店套餐详情不再裁剪 |
## A. mini-user 门店座机电话脱敏(中间四位隐藏)
门店对外电话 `store.phone`= `contactPhone ?? loginPhone`,见 `server/.../common/compat/v31-compat.ts``resolveStoreContactPhone`)在门店详情以「电话: {maskPhone(...)}」展示(`apps/mini-user/src/pages/store-detail/index.tsx` ~L393-402)。
- 脱敏规则(座机):`区号 + 本地号前 2 位 + **** + 本地号后 2 位`,隐藏本地号中间四位。
- `0379-12345678``0379-12****78`
- `010-87654321``010-87****21`
- 无分机同理;手机号仍按 `138****8000` 不变。
- 实现点:`apps/mini-user/src/lib/phone.ts``maskPhone` 座机分支(当前保留末 2~4 位)→ 改为保留首 2 + 末 2、中间以 `****` 替代。
- 拨号仍走 `toDialablePhone`(明文),不受脱敏影响。
- 无 Prisma / API 变更;仅前端 `maskPhone` 规则调整。
## B. mini-user 套餐详情图 1/5 计数 + 自动轮播
入口:`apps/mini-user/src/pages/store-package-detail/index.tsx` 渲染
`<ProductCarousel images={imageUrls} variant="detail" previewable />`,图片来自 `GET /stores/:id``packages[index].imageUrls`(最多 20 张,由 `normalizeStorePackageImageUrls` 归一化)。
- 组件:`apps/mini-user/src/components/ProductCarousel.tsx`
- `variant='detail'` 时给 `<Swiper>` 增加 `autoplay` + `interval`(建议 3500ms),仅 `slides.length > 1` 时生效(现有 `circular` 已满足)。
- 右下角叠加分页计数:`${activeIndex + 1}/${slides.length}`(白底圆角胶囊,绝对定位于 `.detail-carousel-wrap` 右下角);保留原居中圆点(dots)或改为以右下计数为主。
- 单图(`slides.length === 1`)不展示计数、不开轮播。
- 图片容器 `.store-package-detail-gallery` 预留右下角定位锚点(如需)。
- 无 API / schema 变更。
## C. 合伙人账号暂停禁止登录
- 后端 `POST /partner/auth/login/sms``server/.../modules/iam/auth.service.ts``loginPartner` ~L1063、`assertPartnerAccountByPhone` ~L307):账号 `status !== 'ACTIVE'` 时当前抛「合伙人账号已停用」。
- 改为抛出:`该账号已暂停使用,请联系客服人员`
- 同时覆盖发码预检 `assertSmsSendAllowed`PARTNER_LOGIN 场景 ~L341)与 `checkPartnerPhone`,使「暂停」账号无法获取短信验证码。
- 前端 `apps/h5-partner/src/pages/LoginPage.tsx`
- `formatPartnerError`(~L69):命中「已暂停 / 已停用」分支时返回 `该账号已暂停使用,请联系客服人员`
- `formatWechatError`(~L80):同上,覆盖微信登录路径。
- 枚举现状:`AccountStatus``ACTIVE` / `DISABLED``schema.prisma` ~L244)。本次**复用 `DISABLED` 即视为暂停**,不新增枚举,避免迁移;若后续需区分「暂停(可恢复)」与「停用(永久)」,再评估新增 `SUSPENDED`
- 统一文案:`该账号已暂停使用,请联系客服人员`
## D. 门店端 申请提现 / 筛选栏左右留白对齐
页面:`apps/h5-shop/src/pages/WithdrawPage.tsx`(门店管理 / 结算提现)。
- 申请提现按钮 `.shop-withdraw-btn`~L135):当前 `width:100%; margin-top:12px`,置于 `.shop-records-main`(无左右 padding)内,贴边满宽。
- 下方筛选栏 `.shop-records-filters`~L147`position: sticky; top:0`)与 `.shop-records-status-chips`:当前左右 `padding:0`chips 贴屏幕边缘。
- 同页 `.shop-records-summary` / `.shop-records-list` / `.shop-records-list-head` 均使用页面级 token `var(--space-page)` 左右内缩。
- 改动:`.shop-records-filters` 增加 `padding: 0 var(--space-page)`(sticky 背景保留);申请提现按钮区域同样左右内缩 `var(--space-page)`(或其父容器加 `padding: 0 var(--space-page)`),使其与上下组件留白一致。仅样式调整,无逻辑 / API 变更。
## E. 门店端 休息中核销 → 是否开启营业
现状:`PhoneRedeemPage.tsx` / `RedeemConfirmPage.tsx` 拉取 `GET /shop/store``status !== 'OPEN'``storeClosed=true`,核销前拦截并报「门店未营业,无法核销」(服务端 `server/.../modules/redeem/redeem.service.ts``loadOpenStoreAccount` ~L117 亦硬校验「门店未营业」)。
- 新交互:当 `storeClosed`(门店 PAUSED / 休息中)且用户尝试核销时,**不再仅提示无法核销**,而是弹确认框「是否开启营业?」:
- 确认 → 调用 `PUT /shop/store/status { status: 'OPEN' }`(复用 `StatusPage.tsx``requestToggle`/`confirmToggle` 调用方式),成功后 `setStoreClosed(false)`,放开核销、继续原流程(重新拉取或直接使用已输入金额 / 券码)。
- 取消 → 维持 `storeClosed`,不放开。
- 边界:门店 `auditStatus !== 'APPROVED'``updateShopStatus` 会拒绝开张(抛「门店尚在总部审核中 / 审核未通过」),前端需捕获并提示该错误,不进入误开启。
- 适用页:`PhoneRedeemPage`(手机号核销)、`RedeemConfirmPage`(扫码核销确认);`HomePage` 扫码入口本身不判状态,保持现状。
- 后端无需改动(开张接口与硬校验已存在)。
## 关键接口 / 文件
| 位置 | 说明 |
|------|------|
| `apps/mini-user/src/lib/phone.ts` `maskPhone` | 座机脱敏规则改为「中间四位隐藏」 |
| `apps/mini-user/src/pages/store-detail/index.tsx` | 门店详情电话展示(已用 maskPhone) |
| `apps/mini-user/src/components/ProductCarousel.tsx` | detail 变体 autoplay + 右下 `1/5` 计数 |
| `apps/mini-user/src/pages/store-package-detail/index.tsx` | 套餐详情图渲染 |
| `GET /stores/:id` | 门店 / 套餐数据(无变更) |
| `server/.../modules/iam/auth.service.ts` `loginPartner` / `assertPartnerAccountByPhone` / `assertSmsSendAllowed` | 合伙人登录 / 发码非 ACTIVE 抛「该账号已暂停使用,请联系客服人员」 |
| `apps/h5-partner/src/pages/LoginPage.tsx` `formatPartnerError` / `formatWechatError` | 暂停文案 |
| `apps/h5-shop/src/pages/WithdrawPage.tsx` + `styles.css` `.shop-records-filters` / `.shop-records-status-chips` / `.shop-withdraw-btn` | 左右留白对齐 `--space-page` |
| `apps/h5-shop/src/pages/PhoneRedeemPage.tsx` / `RedeemConfirmPage.tsx` | 休息中弹「是否开启营业?」 |
| `apps/h5-shop/src/pages/StatusPage.tsx` `requestToggle` / `confirmToggle` | 复用开张调用 |
| `PUT /shop/store/status` `GET /shop/store` | 切换营业 / 读取门店(已存在) |
## F. mini-user 门店套餐图片自适应完整显示(不裁剪)
门店套餐详情(`apps/mini-user/src/pages/store-package-detail/index.tsx`)的 `ProductCarousel` 此前用 `variant="detail"` 默认 `imageFit="cover"`= `aspectFill`),配合 `.detail-carousel-wrap` 的固定 `aspect-ratio: 1``overflow:hidden`,非正方形图片被裁切 → 用户反馈「图片没显示全」。
- 新增 `imageFit="adaptive"` 模式(仅作用于门店套餐详情):
- `Image` 改用 `mode="widthFix"`,按图片真实比例缩放、完整显示、不裁剪。
- 组件挂载时实测容器宽度(`Taro.createSelectorQuery().select('.detail-carousel-wrap--adaptive').boundingClientRect`),图片 `onLoad` 拿到自然宽高后按 `容器宽 × (自然高/自然宽)` 计算每张幻灯片渲染高度,赋给 `<Swiper>` 内联 `height`,实现轮播高度自适应(多图比例不一也能逐张适配,带 0.2s 过渡)。
- 未加载前兜底高度为 `容器宽 × 0.75`(约 3:4)。
- 样式:`product-detail.css` 增加 `.detail-carousel-wrap--adaptive`,覆盖基类固定 `aspect-ratio:1``overflow:hidden``aspect-ratio:auto; overflow:visible`),并令 `.detail-carousel-image` 高度为 `auto`
- `autoplay`3.5s/ `1/5` 计数(feature B)在 adaptive 下保持不变。
- 仅门店套餐详情传 `imageFit="adaptive"`;门店头图(`variant="store"``contain`)、商品详情(`cover`)不受影响。
## 验收
- [ ] 门店详情座机显示形如 `0379-12****78`(中间四位隐藏),手机号仍 `138****8000`;拨打为明文。
- [ ] 套餐详情图多张时右下角显示 `1/5` 分页计数,并自动轮播(约 3.5s 切换);单图不计数、不轮播;点击仍可预览。
- [ ] 合伙人账号处于非 ACTIVE(暂停 / 停用)时:短信登录与微信登录均被拦截,提示「该账号已暂停使用,请联系客服人员」,无法进入。
- [ ] 门店管理(结算提现)页:申请提现按钮与筛选栏左右留白与其他区块一致(统一 `--space-page`),不再贴边。
- [ ] 门店休息中时进入核销:弹「是否开启营业?」;确认开张后可继续核销;取消则维持拦截;未过审门店开张被拒时给出对应提示。
- [ ] 门店套餐详情图片按真实比例完整显示、不再被裁切(轮播高度随图自适应);自动轮播与 `1/5` 计数仍正常。
- [ ] A 仅 `maskPhone` 规则、C/D/E 仅前端样式 / 交互;均无需 Prisma 迁移(C 复用 `DISABLED`)。
## HQ 开发计划
创建版本 `v3.4.18` 并关联本迭代任务;发版前再合并发布(mini-user 升 `3.4.18`)。