- ProductCarousel 新增 imageFit="adaptive"(widthFix + 动态高度) - 门店套餐详情按图片真实比例自适应高度,完整显示不裁剪 - 补充 v3.4.18 文档 F 项 Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
10 KiB
杜康好客 · 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****78010-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.tsxvariant='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均使用页面级 tokenvar(--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)。