# 2026-07-23

## 扫码进入小程序后支付页空白 bug

**现象**：用户从 web 端订单详情生成 QR 码 → 微信扫码进入小程序 → `passport/pay` 页面只显示卡片标题"确认支付"、"支付金额"标签、底部提示文案，**商品名称/价格类型/价格/分隔线/取消按钮/立即支付按钮全部缺失**，无法继续支付流程。

**根因**：`@nutui/nutui-react-taro@2.7.4` 的 Cell / Price / Divider / Button 内部用 `React.createElement("div", ...)`，而 `dist/base.wxml` 里只有 `<view>` / `<text>` / `<button>` 模板没有 `<div>`。这些组件在 weapp 中"空壳化"。截图里只显示纯 Text/View 和图标（来自 `@nutui/icons-react-taro` 的 SVG），没有显示的内容全部是 nutui-react-taro 组件。

**修复**：只改 `src/passport/pay/index.tsx` 一个文件，把 4 个 nutui 组件换成 Taro 原生 / 项目自定义组件：

- `import { Button, Cell, Price, Divider } from '@nutui/nutui-react-taro'` → `import { Button } from '@tarojs/components'` + `import Price from '@/components/common/Price'`
- `<Cell>` → `<View>` + `<Text>` 自绘（用 `flex justify-between px-4 py-3 border-b border-gray-100`）
- `<Price size="large" thousands>` → `<Price size="large">`（项目自定义组件）
- `<Divider>` → `border-b border-gray-100` 替代
- `<Button type="primary" block>` → `<Button className="bg-blue-500 text-white rounded-full">`（className 控制颜色）
- error/paid/loading 三个分支里的 `<Button type="primary">` 也一并替换

**验证**：
- `npm run build:weapp` → `Compiled successfully in 14.45s`
- `dist/passport/pay/index.js` 里 `nut-cell|nut-button|nut-divider|nut-price` 全部为 0；按钮编译成 `l.zx`（Taro Button 局部变量名）
- 文件最终 413 行，diff 集中在 import + 渲染区，逻辑（数据获取、JSAPI 支付、状态判断 payStatus vs status）没动

**遗留**：项目其它页面（passport/{login,forget,register,setting,unified-qr,qr-login}、pages/order/*、pages/booking/*、components/common/{FixedButton,EmptyState}、components/QRLoginScanner）也用了 nutui Button/Checkbox/Input/Card/Tabs/Tag 等。如果以后用户反馈"按钮/输入框看不到或不可点"，按同样模式替换即可。这次没改，避免一次改动面太大。

## vip-review 审核通过补充：添加 shop_store_user 记录

**背景**：之前实现的 `src/pages/user/vip-review/index.tsx` 审核通过只调了 `updateShopDealerApply` + `setUserDeveloper`，漏了"给申请人加一条门店店员记录"。用户 2026-07-23 指出"审核通过的操作，还是要添加一条记录到 shopStoreUser，可能之前理解错了"，要求补上。

**修改**（仅前端一个文件）：
- import 增加 `addShopStoreUser`（来自 `@/api/shop/shopStoreUser`）。
- 新增 state `clerkStoreId` / `clerkTenantId`，在 `getMyClerk()` 成功后写入（店员记录自带 `storeId`/`tenantId`）。
- `handleApprove` 在 `setUserDeveloper` 之后调 `addShopStoreUser({ userId, storeId: clerkStoreId, tenantId: clerkTenantId, isDelete: 0, comments: '开发者审核通过自动添加' })`，仅当 `clerkStoreId` 存在时执行。

**依赖**：后端 `POST /shop/shop-store-user`（ShopStoreUserController.save，需 `shop:shopStoreUser:save` 权限，店员已有）；tenantId 复用审核店员的租户，避免前端另取。

## 平台管理页 UI 对齐门店中心

**需求**：用户要求 `pages/admin/index/index` 与 `pages/store/center/index` 一模一样的 UI。

**改动**（仅 `src/pages/admin/index/index.tsx`）：
- 删除原先 NavBar + StatCard 网格 + EntryGrid 的旧结构，整体改写为门店中心同款「渐变绿色头部 + 白卡片列表（图标/标题/描述/角标/箭头）+ 底部信息卡」。
- 头部展示管理员 avatar + 「平台管理」标题 + 昵称·手机号（取 `useUser().user`）。
- FEATURE_CARDS 保留 4 个入口：应用审核(📝)、Git 审核(🐙)、域名审核(🌐)、工单处理(🎫)，各自带 desc、color/bgColor、url。
- 角标沿用项目 `Badge` 组件：应用审核=待审核应用数（pagePublishReviews 已按 pending_review 过滤），工单处理=未解决/未关闭工单数（getAllTickets 取前100条 client 端过滤）。
- 底部卡片「平台概况」保留原页面统计：应用总数、用户总数、工单总数（pageAllApps / pageUsers / getAllTickets 的 total）。
- 保留登录校验（!isLoggedIn）与管理员校验（!isAdmin）两个空态，改为居中图标文案，去掉 NavBar 依赖（标题走 definePageConfig）。
- 新页面不再引入 nutui 组件，只用 `@tarojs/components` + 自定义 `Badge`，规避 weapp 空白坑。

**待验证**：`npm run build:weapp` 未实跑（环境 tsc 报 @tarojs/taro 类型库缺失属全局问题，与本次无关）。

## 平台管理 / 门店中心 改为 isSuperAdmin=true 才显示

**需求**：平台管理与门店中心两个入口都需要 `isSuperAdmin=true`（布尔）才显示（原先平台管理=isAdmin、门店中心=店员 storeInfo）。门店中心页面本身按用户确认改为「仅超级管理员可进」。

**改动文件**：
- `src/pages/user/user.tsx`：菜单项 平台管理、门店中心 的显示条件均由 `isAdmin` / `storeInfo` 改为 `(user as any)?.isSuperAdmin === 1`。
- `src/pages/index/index.tsx`：首页角色工作台外层容器补 `|| isSuperAdmin===true`，平台管理入口 `(user as any)?.isAdmin` → `isSuperAdmin === true`。
- `src/pages/admin/index/index.tsx`：页面访问门槛 `isAdmin` → `isSuperAdmin===true`（含空态文案）；`loading` 拆为 `userLoading`(来自 useUser，防闪烁) + `dataLoading`(角标数据)；首屏 `if (userLoading || dataLoading) spinner`。
- `src/pages/store/center/index.tsx`：移除 `getMyClerk()` 店员门槛，改为 `isSuperAdmin===true` 才进；非超管弹「仅超级管理员可访问」并 navigateBack；头部加 `header` 兜底（超管非店员时显示「门店中心」+ 管理员昵称/手机号）；渲染守卫 `userLoading → 请先登录 → 无访问权限`，去掉原 `if(!storeInfo) return null`（否则非店员超管整页空白）。

**验证**：`npm run build:weapp` 在沙箱被 OOM/锁文件杀掉（exit 137，无报错），属环境问题，非代码错误；改动均为项目既有写法（useUser / Badge / 渐变头部）。

## 「申请成为开发者」菜单项随 isDeveloper 切换

**需求**：我的页面菜单里「申请成为开发者（推荐）」条目，若用户已审核通过成为开发者，该处文案/链接改为「进入开发者中心」（跳 `/pages/developer/index/index`）。

**改动**（`src/pages/user/user.tsx` 菜单 `menuItems`）：
- 把原第 105 行固定「申请成为开发者」+ 第 107 行独立「开发者中心」(仅 isDeveloper 显示) 合并为条件式：`(user as any)?.isDeveloper ? { 进入开发者中心 → /pages/developer/index/index } : { 申请成为开发者 → /pages/user/vip-upgrade/index }`，两者均 `highlight: true`（醒目推荐样式）。去掉了冗余的独立「开发者中心」条目。

## 开发者中心 UI 对齐门店中心

**需求**：`pages/developer/index/index` 的 UI 改成和门店中心（`pages/store/center/index`）一模一样。

**改动**（仅 `src/pages/developer/index/index.tsx`，整体重写）：
- 删除原 NavBar + StatCard 3列网格 + EntryGrid 老结构，改写为门店中心同款「渐变绿头部 + 白卡片列表（图标/标题/描述/角标/箭头）+ 底部卡片」。
- 头部：开发者 avatar + 「开发者中心」标题 + 昵称·手机号（取 `(user as any)`）。
- FEATURE_CARDS 三张：我的应用(📦/蓝)、API Key(🔑/绿)、我的工单(🎫/橙)，各自 desc + url；角标沿用 `Badge`，展示各功能的计数（stats.apps/keys/tickets，由 getMyApps/getAppApiKeyStats/getMyTickets 的 total 取），卡片渲染后异步填充。
- 底部卡片改为「开发者帮助与支持」（💡 蓝圈）→ `/pages/user/help-center/index`（替代门店中心的订阅消息卡，订阅模板是门店专属，开发者无对应模板）。
- 保留两个空态：!isLoggedIn「请先登录」、!isDeveloper「尚未加入开发者中心」+ 申请按钮（保留原 apply 入口，store center 无此场景故无按钮）；首屏用 `userLoading`(来自 useUser) 转圈防闪烁。
- 不再引入 NavBar/StatCard/EntryGrid/Loading（可能内部用 nutui，踩 weapp 空白坑），只用 `@tarojs/components` + 自定义 `Badge`，与门店中心一致。

## 首页轮播图空时不显示

**需求**：`pages/index/index` 的轮播图（banner）若为空则不显示。

**改动**（`src/pages/index/index.tsx` 轮播图渲染段）：把外层 `.index-banner-wrap` 容器从「`bannerSlides.length>0` 渲染 Swiper，否则渲染『暂无轮播图』占位框」改为「`bannerSlides.length > 0 &&` 整个容器才渲染」；空时整块（含占位框）不显示，下方功能入口自动上移。