# 2026-07-22 工作日志

## 开发者登录弹窗 UI 美化
- 文件：`src/pages/user/about/index.tsx`
- 美化了 Input（圆角12px、高度48px、柔和背景色）、Button（蓝色渐变、阴影、圆角14px）、验证码按钮（与输入框等高、倒计时优化）
- 弹窗整体：圆角加大、内边距增加、宽度收窄

## 开发者登录弹窗样式改为红色系
- 文件：`src/pages/user/about/index.tsx`
- Input 边框：`transparent` → `#e53e3e`（红色），背景 `#f7f8fa` → `#fff5f5`（淡红）
- 获取验证码按钮：激活态添加 `backgroundColor: #e53e3e`、`borderColor: #e53e3e`
- 登录按钮：渐变从蓝色 `#4f8cff→#3b6fd4` 改为红色 `#fc5c5c→#e53e3e`，阴影同步改为红色

## 关于我们页面介绍内容改写
- 文件：`src/pages/user/about/index.tsx`
- 公司：南宁市网宿信息科技有限公司，品牌：威数谱软件（websopy）
- 重写品牌故事（三个段落）、核心业务（6项软件相关）、联系我们（公司名称/总部/电话/邮箱/官网）、版权信息
- 头部 Logo 文字「鑫」→「威」，版本号显示 websopy v1.0.0

## VIP 概念替换为「开发者」（文案统一）
- 起因：用户要求把 `pages/user/vip-upgrade/index` 的 VIP 概念换成「开发者」。后台审核页 `vip-review` 已定义 `VIP_ROLE_NAME='开发者'`，概念本就一致。
- 改动文件与要点：
  - `vip-upgrade/index.tsx` + `index.config.ts`：导航栏/分享标题/主副标题/状态说明/温馨提示/权益区块标题及权益项描述，全部「VIP会员」→「开发者」；顶部图标 👑→🔰；表单标签「门店名称/门店地址」→「开发团队/公司地址」（placeholder、toast 同步），底层字段 realName/address 不变。
  - `user.tsx`：用户中心入口「升级VIP会员」👑→「申请开发者」🔰。
  - `store/center/index.tsx`：门店中心入口「VIP会员审核/审核客户VIP会员申请」👑→「开发者审核/审核客户开发者申请」🔰。
  - `vip-review/index.tsx`：导航栏标题、通过/驳回弹窗文案、审核说明、列表字段标签（门店名称/门店地址→开发团队/公司地址）统一为「开发者」。
- 注意：仅改可见文案与图标，**未重命名**页面路由/文件夹（vip-upgrade、vip-review）、变量名（VIP_ROLE_CODE、pendingVipCount 等）及定价逻辑（dealerPrice/VIP 状态判断仍保留原标识符，因对应后端角色与缓存 key）。
- 用户确认方式：先给文案对照表，经 AskUserQuestion 确认表单标签与图标及范围后执行。

## VIP 升级页新增「所在城市」选择
- 文件：`src/pages/user/vip-upgrade/index.tsx`、`src/api/shop/shopDealerApply/model/index.ts`
- 在「办公地址」上方新增「所在城市 *」字段：复用微信原生 `Picker mode='region'`（省市区三级），与 `pages/user/address-edit.tsx` 风格一致。
- 状态：`cityValue: string[]` + 派生 `cityText`（以空格连接）；`Picker` 的 `disabled` 跟随 `isReadonly`（审核中/已通过只读）。
- `ShopDealerApply` 模型新增 `city?: string`（注释：省 市 区，空格分隔）。
- 提交时 `addShopDealerApply` 增加 `city: cityText`；读取历史申请时 `setCityValue(latest.city.split(' '))`；保存校验增加「请选择所在城市」。
- 注意：仅前端扩展字段，后端是否落库 `city` 存疑（模型此前只有 address），需后端 schema 支持才能真正持久化。

## vip-review 审核通过：改为「更新 user 为 developer」（不新增角色）
- 起因：用户要求 `pages/user/vip-review/index` 审核通过时直接把 user 标记为开发者，而不是往 `sys_user_role` 加 developer 角色。
- 后端（仓库 `/Users/gxwebsoft/JAVA/com.gxwebsoft.core`，已 `mvn -o compile` BUILD SUCCESS）：
  - `User.isDeveloper`（`sys_user.is_developer`，Boolean）此前从未被写入，正是开发者标记位。
  - `UserService` 新增 `boolean markAsDeveloper(Integer userId)`；`UserServiceImpl` 用最小实体 `updateById` 置 `isDeveloper=true`，成功后再经 `syncMessageProducer` 同步 websopy（复用 updateUser 的同步范式）。
  - `UserController` 新增 `PUT /api/system/user/developer/{userId}`（`setDeveloper`），权限沿用 `sys:userRole:save`（与原 `addUserRole` 一致，避免店员 403 回归）。
- 前端：
  - `@/api/system/user/index.ts` 新增 `setUserDeveloper(userId)` → `PUT /system/user/developer/{userId}`。
  - `vip-review/index.tsx`：移除 `addUserRole/listUserRole/listRoles/TenantId` 等角色相关 import 与 `VIP_ROLE_*`、`getCurrentTenantId`、`getVipRoleId`、`assignVipRole`、`formatDateTime`；`handleApprove` 中 `await assignVipRole(item.userId)` 替换为 `await setUserDeveloper(item.userId!)`。
- 约定：**开发者身份 = `sys_user.is_developer` 布尔位，不是角色表记录**（已记项目 MEMORY.md）。

## vip-review 审核通过：补回「开发者角色绑定」+ 保留 `isDeveloper=1`
- 起因：上一轮把 `addUserRole` 整段删了（按"不用新增角色"）。本轮用户要求"除了更新角色之外，还要更新 isDeveloper=1"，即两者都要。
- 改动：仅前端 `src/pages/user/vip-review/index.tsx`：
  - 恢复 import：`addUserRole, listUserRole`(@/api/system/userRole)、`listRoles`(@/api/system/role)、`TenantId`(@/config/app)。
  - 恢复常量与函数：`VIP_ROLE_CODE='developer'`、`VIP_ROLE_NAME='开发者'`、`getCurrentTenantId()`、`getVipRoleId()`（按 roleCode+租户查 roleId）、`assignVipRole(userId)`（查已有角色、无则 `addUserRole`）。
  - `handleApprove` 中 `await setUserDeveloper(item.userId!)` 之前新增 `await assignVipRole(item.userId)`：先绑 developer 角色，再置 `is_developer=1`。
- 后端 `markAsDeveloper`（`PUT /system/user/developer/{userId}`）上一轮已落地并编译通过，本次未改；其 `updateById` 置 `isDeveloper=true` 即"更新数据库"的落库动作。
- 结论：审核通过 = 绑定 developer 角色 + 置 isDeveloper=1（两项都做）。已更新项目 MEMORY.md 的"开发者身份表示方式"条目。

## vip-review 审核通过：更正为「替换角色为 developer」+ `is_developer=1`（最终方案）
- 用户纠正上一轮：不是"新增/叠加角色"（那样会留下原角色 + developer 两个角色），而是**把用户角色改成 developer（替换，不并存）**，同时 `sys_user.is_developer=1`。
- 前端 `vip-review/index.tsx`：撤掉上一轮刚加回的 `assignVipRole` 及 `addUserRole/listUserRole/listRoles/TenantId/VIP_ROLE_*`/`getCurrentTenantId`/`getVipRoleId`；`handleApprove` 恢复为只 `await setUserDeveloper(item.userId!)`。前端完全不碰 `sys_user_role`。
- 后端 `UserServiceImpl.markAsDeveloper` 本次新增"替换角色"逻辑：置 `is_developer=1` 后，按 `user.getTenantId()` 调 `roleService.getByRoleCode(roleCode="developer", tenantId)` 找到 developer 角色 → `userRoleService.remove(eq userId)` 删现有角色 → `saveBatch(userId, [developerRoleId])` 只绑 developer（单角色）。整段包 try/catch，角色缺失/失败不影响 is_developer 落库。新增 import：`RoleParam`、`java.util.Collections`。
- 编译：`./mvnw -o compile` → BUILD SUCCESS。前端无残留角色符号。
- 结论（已同步 MEMORY.md）：升级为开发者 = 单角色 developer + isDeveloper 标记位；前端一次 `setUserDeveloper` 调用、后端一处搞定。

## 小程序端新增开发者中心 & 平台管理（入口改造）
- 起因：用户要求小程序端对齐 PC 端 `/developer` 与 `/admin` 功能。方案确认：入口挂「我的」页，分阶段实现 MVP 核心。
- 页面（新增于 `src/pages/developer/*` 与 `src/pages/admin/*`，已注册到 `app.config.ts`）：
  - 开发者中心：`index`(概览) / `apps`(我的应用) / `apikeys`(API Key) / `tickets`(我的工单)
  - 平台管理：`index`(管理首页) / `app-review`(应用审核) / `git-review`(Git/权限审核) / `domain-review`(域名绑定审核) / `tickets`(工单处理)
- API 模块（新增 `src/api/app/`：apikey、appProduct、appDomain、ticket、developer），复刻 PC 端 `/api/app/*` 契约，基址走 `WEBSOPY_API_BASE_URL`。
- 公共组件：新增 `StatCard` / `EntryGrid` / `CellRow`（`src/components/common/`）。
- 入口方式（**本次按用户最新要求改**）：不做工作台卡片，改为「我的」页功能菜单里的链接项，与「门店中心」同款——`开发者中心` 仅当 `(user as any)?.isDeveloper` 时显示、`平台管理` 仅当 `(user as any)?.isAdmin` 时显示，均 `requireAuth`。首页不额外加卡。
- 关键依赖：菜单显示与否取决于登录接口返回的 user 对象是否携带 `isDeveloper/isAdmin` 字段（后端 `setDeveloper` 写的是 `sys_user.is_developer`，但登录态是否回填该字段需联调确认）。
- 编译验证：已 `npm run build:weapp`（后台 IzjQLY 进行中），待确认无报错。
