Files
websopy-mp/.workbuddy/memory/2026-04-12.md
赵忠林 611b488af3 refactor(api): 规范前端API接口地址并统一路径前缀
- 修正开发者、小程序和企业相关API的基础URL,避免重复添加/api前缀
- 统一调整developer、enterprise、invite等模块接口路径,保持与后端Controller一致
- 新增权限申请及消息通知相关API,并完善相关函数实现
- 规范请求参数传递,移除多余包装,改用直接传递对象方式
- 新增API Key重置、版本发布/回滚等接口支持

feat(invite): 重构邀请登录流程支持未注册快速加入

- 完整重写invite页,分离已注册用户和未注册用户的按钮显示和交互
- 实现未注册用户微信手机号授权后自动注册登录及自动加入应用
- 已注册用户直接确认加入应用,无需手机号授权弹窗
- 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错
- 前端配合后端改造,支持已登录用户可直接通过Authorization头加入应用

fix(developer): 修复开发者中心应用加载问题

- 修复只查询创建的应用导致邀请加入的应用不显示的问题
- 同时请求创建应用和参与应用接口,合并并去重应用列表
- 新增pageJoinedApp接口调用及合并逻辑,提高应用列表完整性和体验
2026-04-13 15:30:32 +08:00

616 lines
20 KiB
Markdown
Raw Permalink 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-04-12 工作日志
## 项目:小程序改造规划
### 背景
用户需要为 websopy-mp 小程序增加:
- 🛠️ **开发者中心** - 面向开发者,围绕项目展开
- 🏢 **企业控制台** - 面向企业客户
### 关键决策
1. **用户角色分两类**
- 开发者 (Developer):独立于企业存在,申请审核制
- 企业客户 (Enterprise):属于企业组织,购买产品开通
2. **开发模式**:独立开发,不复用现有模块(商城/分销/用户订单)
3. **核心围绕"项目"展开**
- 项目类型:基础/专业/企业
- 项目成员、API Key、应用关联
### Phase 1 开发完成 ✅
已完成以下功能开发:
#### 新增目录结构
```
src/
├── developer/ # 🛠️ 开发者模块
│ ├── index.tsx # 开发者工作台
│ ├── project/ # 项目管理
│ │ ├── index.tsx # 项目列表
│ │ ├── create.tsx # 创建项目
│ │ └── [id]/ # 项目详情
│ ├── app/ # 应用管理
│ │ ├── index.tsx # 应用列表
│ │ ├── create.tsx # 创建应用
│ │ ├── [id]/ # 应用详情
│ │ └── api-keys/ # API Key 管理
│ └── docs/ # 开发者文档
├── enterprise/ # 🏢 企业模块
│ ├── index.tsx # 企业工作台
│ ├── apps/ # 企业应用
│ │ ├── index.tsx # 应用列表
│ │ ├── [id]/ # 应用详情
│ │ └── purchase/ # 购买应用
│ ├── members/ # 成员管理
│ │ ├── index.tsx # 成员列表
│ │ └── invite/ # 邀请成员
│ ├── orders/ # 订单账单
│ │ ├── index.tsx # 订单列表
│ │ └── detail/ # 订单详情
│ ├── billing/ # 费用中心
│ └── settings/ # 企业设置
├── api/developer/ # API 模块
│ ├── index.ts
│ ├── developer.ts # 开发者 API
│ └── enterprise.ts # 企业 API
└── types/developer.ts # 类型定义
```
#### 新增页面
- 首页角色入口卡片(开发者中心/企业控制台)
- 开发者工作台 + 统计卡片 + 快捷操作
- 项目列表/创建/详情
- 应用列表/创建/详情
- 企业工作台 + 统计卡片 + 快捷操作
- 企业应用列表/购买/详情
- 成员列表/邀请
- 订单列表/详情(占位)
- 费用中心/企业设置(占位)
#### 新增 API
- 项目管理 API
- 应用管理 API
- API Key 管理 API
- 企业成员 API
- 订单账单 API
### 待确认
- 后端 API 接口地址是否正确
- 是否需要权限验证
- 微信小程序码支持
---
## Phase 2 开发完成 ✅ (2026-04-12 19:49)
### 新增功能模块
#### 1. API Key 完整管理
- 列表展示(名称/类型/状态/创建时间)
- 创建 Key名称/类型/备注)
- 复制 AppId/AppSecret
- 删除 Key
- 状态筛选
#### 2. 项目成员管理
- 成员列表展示(头像/名称/角色)
- 角色统计(所有者/管理员/开发者/查看者)
- 邀请成员(用户名/角色选择)
- 修改成员角色
- 移除成员
#### 3. 应用版本发布
- 版本列表(版本号/状态/环境)
- 环境 Tab 筛选(全部/开发/预发布/生产)
- 发布新版本(名称/版本号/环境/更新日志)
- 状态标签(构建中/已发布/已回滚/构建失败)
#### 4. 消息通知中心
- 通知列表(类型/标题/内容/时间)
- 类型筛选(全部/系统/应用/成员/订单)
- 未读数量徽标
- 标记已读/全部已读
- 删除通知
- 点击跳转详情
#### 5. 开发者申请
- 申请表单(姓名/手机/邮箱/公司/职位/经验)
- 申请记录列表
- 状态筛选(待审核/已通过/已拒绝)
- 审核备注展示
#### 6. 权限审批
- 申请列表(申请人/类型/目标/状态)
- Tab 筛选(待审核/已通过/已拒绝/全部)
- 待审核数量徽标
- 通过/拒绝操作
- 审核备注展示
### 新增/扩展的页面
```
src/developer/
├── project/[id]/
│ ├── members.tsx # 项目成员管理 ✅
│ ├── members.scss
│ ├── api-keys.tsx # 项目级 API Key
│ ├── api-keys.scss
│ ├── api-keys.config.ts
│ ├── settings.tsx # 项目设置
│ └── settings.scss
├── app/[id]/
│ ├── version.tsx # 版本管理 ✅
│ ├── version.scss
│ ├── config.tsx # 应用配置
│ ├── publish.tsx # 发布管理
│ └── *.config.ts
├── notification/ # 消息通知 ✅
│ ├── index.tsx
│ └── index.scss
├── developer/
│ ├── apply.tsx # 开发者申请 ✅
│ ├── apply.scss
│ └── profile.tsx # 开发者资料
├── docs/
│ ├── quickstart.tsx # 快速开始
│ └── api-docs.tsx # API 文档
└── market/ # 开发者市场
└── index.tsx
src/enterprise/
├── apps/[id]/
│ ├── monitor.tsx # 运营监控
│ ├── analytics.tsx # 数据分析
│ └── settings.tsx # 应用设置
├── members/
│ ├── roles.tsx # 角色权限
│ └── audit.tsx # 权限审批 ✅
├── orders/
│ ├── invoice.tsx # 发票管理
│ └── bills.tsx # 账单明细
├── billing/
│ ├── consumption.tsx # 消费明细
│ ├── recharge.tsx # 充值中心
│ └── coupons.tsx # 优惠券
├── settings/
│ ├── info.tsx # 企业信息
│ ├── domain.tsx # 域名配置
│ └── security.tsx # 安全设置
└── developer/
├── index.tsx # 开发者入口
└── apply.tsx # 申请开发者
```
### 扩展的类型定义
```typescript
// 消息通知
interface Notification {
id, type, title, content, data, isRead, readTime, createTime
}
// 权限申请
interface Apply {
id, type, applicantId, applicantName, applicantAvatar,
targetId, targetName, reason, status, reviewerId,
reviewerName, reviewTime, reviewRemark, createTime
}
```
### 扩展的 API
```typescript
// 通知相关
pageNotification, getUnreadCount, markAsRead, markAllAsRead, deleteNotification
// 申请相关
pageApply, pageMyApply, createApply, reviewApply
```
### 路由配置更新
新增 20+ 个页面路由
---
## Phase 3 开发完成 ✅ (2026-04-12 20:15)
### 新增功能模块
#### 1. CI/CD 流水线
- **构建任务列表**:状态筛选/触发构建/取消构建/查看详情
- **构建详情**:构建信息/Git 信息/构建日志/构建产物
- **部署列表**:环境筛选/部署统计/触发部署/回滚操作
- **部署详情**:部署进度/日志/回滚功能
- **流水线配置**:启用/禁用、自动部署、分支规则、环境变量、Webhook
#### 2. 运营监控/数据分析
- **实时数据看板**UV/PV/API 调用/错误数/Live 指示器
- **今日概览**UV/PV/API 调用统计卡片
- **数据趋势**:图表占位(可集成 ECharts
- **性能指标**:核心指标展示/趋势标签/错误统计
- **用户分析**:活跃用户/新增用户/留存率/地域分布/流量来源
- **页面排行**PV/UV 排行
#### 3. 发票管理
- **发票列表**:状态筛选/发票详情/取消申请
- **可开票金额**:实时金额展示
- **申请发票**:抬头选择/金额输入/提交申请
- **发票抬头管理**:增删改查/默认设置
- **发票统计**:申请总数/已开票数量
#### 4. SSO 单点登录
- **SSO 配置**OIDC/SAML/CAS/LDAP/OAuth2 提供商支持
- **连接配置**Issuer/Client ID/Client Secret/授权 URL 等
- **用户同步**:同步开关/自动创建/默认角色
- **服务提供商信息**Entity ID/ACS URL可复制
- **操作日志**:登录/登出/错误记录
### 新增类型定义
```
src/types/
├── index.ts # 统一导出
├── cicd.ts # CI/CD 流水线类型
├── analytics.ts # 数据分析类型
├── invoice.ts # 发票管理类型
└── sso.ts # SSO 单点登录类型
```
### 新增 API
```
src/api/
├── cicd.ts # CI/CD 流水线 API
├── analytics.ts # 数据分析 API
├── invoice.ts # 发票管理 API
└── sso.ts # SSO 单点登录 API
```
### 新增页面
```
src/developer/app/[id]/
├── builds.tsx # 构建列表
├── builds.scss
├── build/[id].tsx # 构建详情
├── build/[id].scss
├── deploys.tsx # 部署列表
├── deploys.scss
├── deploy/[id].tsx # 部署详情
├── deploy/[id].scss
├── pipeline.tsx # 流水线配置
├── pipeline.scss
├── analytics.tsx # 运营监控
└── analytics.scss
src/enterprise/
├── orders/
│ ├── invoice.tsx # 发票管理
│ └── invoice.scss
└── settings/
├── sso.tsx # SSO 配置
└── sso.scss
```
### Phase 3 完成的功能
| 功能 | 页面 | 状态 |
|------|------|------|
| **CI/CD 构建** | 构建列表/详情 | ✅ 完整 |
| **CI/CD 部署** | 部署列表/详情/回滚 | ✅ 完整 |
| **流水线配置** | 流水线设置 | ✅ 完整 |
| **运营监控** | 数据看板/趋势 | ✅ 完整 |
| **发票管理** | 发票列表/申请/抬头 | ✅ 完整 |
| **SSO 单点登录** | SSO 配置/日志 | ✅ 完整 |
---
### 待开发 (Phase 4)
| 功能 | 说明 |
|------|------|
| SDK 下载 | 各语言 SDK 下载页面 |
| 工单系统 | 客服工单/技术支持 |
| 账单导出 | 账单 Excel 导出 |
| 数据导入 | 企业数据批量导入 |
---
## Phase 4 开发完成 ✅ (2026-04-12 20:25)
### 新增功能模块
#### 1. SDK 下载中心
- **SDK 分类浏览**Web/移动/服务端/小程序
- **SDK 列表展示**:图标/版本/下载量/Star
- **搜索功能**:按名称/描述搜索
- **SDK 详情弹窗**:版本/依赖/更新日志
- **一键安装**NPM 命令复制/直接下载
#### 2. 工单系统
- **工单列表**:状态/类型/优先级筛选
- **工单统计**:总数/待处理/处理中/已解决
- **创建工单**:类型/优先级/标题/内容
- **工单详情**:沟通记录/解决方案/回复
- **工单评价**:满意度评分/反馈
#### 3. FAQ 常见问题
- **分类浏览**API/账单/账户/SDK 等分类
- **搜索功能**:关键词搜索
- **展开查看**:问题详情/回答
- **有帮助/没帮助**:用户反馈
#### 4. 数据导入
- **导入记录列表**:状态/进度/错误统计
- **模板下载**:各类数据导入模板
- **字段说明**:必填/类型/示例
- **错误详情**:行号/字段/错误原因/建议
#### 5. 账单导出
- **导出记录**:任务列表/状态/文件信息
- **新建导出**:类型/格式/时间范围
- **下载管理**:文件下载/过期提醒
- **格式支持**Excel/CSV/PDF
### 新增类型定义
```
src/types/
├── sdk.ts # SDK 下载类型
├── ticket.ts # 工单系统类型
└── import.ts # 导入导出类型
```
### 新增 API
```
src/api/
├── sdk.ts # SDK 下载 API
├── ticket.ts # 工单系统 API
└── import.ts # 导入导出 API
```
### 新增页面
```
src/developer/
├── sdk/
│ └── index.tsx # SDK 下载中心
├── ticket/
│ ├── index.tsx # 工单中心
│ ├── detail.tsx # 工单详情
│ └── faq.tsx # FAQ 常见问题
src/enterprise/
├── settings/
│ └── import.tsx # 数据导入
└── orders/
└── bills.tsx # 账单导出
```
### Phase 4 完成的功能
| 功能 | 页面 | 状态 |
|------|------|------|
| **SDK 下载中心** | 列表/详情/下载 | ✅ 完整 |
| **工单系统** | 列表/创建/详情/评价 | ✅ 完整 |
| **FAQ 常见问题** | 分类/搜索/反馈 | ✅ 完整 |
| **数据导入** | 导入记录/模板下载 | ✅ 完整 |
| **账单导出** | 导出记录/新建导出 | ✅ 完整 |
---
## 📊 四个 Phase 累计完成
| Phase | 功能数 | 页面数 | API 数 |
|-------|--------|--------|--------|
| Phase 1 | 基础框架 | 15+ | 10+ |
| Phase 2 | API Key/成员/通知等 | 20+ | 15+ |
| Phase 3 | CI-CD/监控/发票/SSO | 10+ | 20+ |
| Phase 4 | SDK/工单/导入/导出 | 10+ | 15+ |
| **合计** | - | **55+** | **60+** |
---
## Bug 修复 (2026-04-12 21:00)
### 已修复的问题
#### 1. JSX 语法错误
- 修复 8 个被截断的 `.tsx` 文件appCredential、appEvent、appUser、appVersion
- 修复 `user/apps/index.tsx` 中的 `>` token 问题
#### 2. API 导入问题
- 修复 `analytics.ts``cicd.ts``invoice.ts``sso.ts` 的 request 导入
- 添加缺失的 `ImportType` 导入
- 修复 `sdk.ts` 未使用的导入
#### 3. Config 文件错误
- 修复所有 `defineComponentConfig``definePageConfig`
- 涉及 12 个 config 文件
#### 4. 组件命名错误
- 修复 `PullRefresh``PullToRefresh`nutui 组件)
- 涉及 4 个文件
#### 5. taro-ui 依赖问题
-`taro-ui` 替换为 `nutui-react-taro`
- 重写 `invoice.tsx``sso.tsx` 页面
#### 6. SCSS 导入问题
- 修复 `notification/index.tsx` 的 scss 导入路径
#### 7. 类型定义
- 创建 `src/types/developer.ts` 缺失类型文件
- 修复 `RequestConfig` 缺少 `params` 属性
### 项目状态
- ✅ 编译成功
- ✅ 开发服务器运行中 (端口: dist)
---
## 任务:改造 invite/index.tsx 登录流程
### 需求
- `loginByOpenId` 已注册 → 显示**「确认加入」**按钮
- `loginByOpenId` 未注册 → 显示**「微信手机号快速加入」**按钮(走授权流程)
### 关键逻辑
1. `checkLoginStatus`:调用 `loginByOpenId` 检查用户是否已注册
2. 已注册:`isLoggedIn = true`,显示「确认加入」按钮
3. 未注册:`isLoggedIn = false`,显示「微信手机号授权」按钮
4. 授权成功 → 调用 `loginByMpWxPhone` 完成注册/登录 → 自动执行加入应用
### 文件修改
- `src/passport/invite/index.tsx` - 完整重写,区分已登录/未注册两种按钮状态
---
## 任务:未注册用户在邀请页内完成授权注册,不跳登录页
### 需求
- loginByOpenId 未注册 → 在页面内显示「微信手机号授权」按钮
- 授权成功 → 调用 `loginByMpWxPhone` 注册/登录 → 自动执行加入应用
- 不再跳转 passport/login 页面
### 关键逻辑
1. `checkLoginStatus`:已注册 isLoggedIn=true未注册 isLoggedIn=false**两种情况都显示邀请页**
2. 未注册按钮:`open-type="getPhoneNumber"``handleGetPhoneNumber`
- 授权码调 `SERVER_API_URL/wx-login/loginByMpWxPhone` 完成注册登录
- 保存 token → isLoggedIn=true → 立即调 `doJoinApp`
3. 已注册按钮:普通 `onClick``handleConfirmJoin``doJoinApp(access_token)`
4. `doJoinApp`:统一加入接口,请求头带 `Authorization: Bearer {access_token}`
### 文件修改
- `src/passport/invite/index.tsx` - 完整重写(彻底移除跳登录页逻辑)
---
## 修复:「授权码不能为空」报错
### 问题
后端 `/api/_app/developer/invite/accept` 接口强制要求传 `code`(微信授权码),不传就报「授权码不能为空」。
### 解决
统一用一个 `getPhoneNumber` 按钮处理两种场景:
- **已注册**:文字「确认加入」→ 触发 getPhoneNumber → `doJoinApp(code, accessToken)`
- **未注册**:文字「微信手机号快速加入」→ 触发 getPhoneNumber → 先 `loginByMpWxPhone` 注册 → 再 `wx.login()` 获 code → `doJoinApp(newCode, access_token)`
### doJoinApp 参数
```ts
doJoinApp(wxCode: string, accessToken: string)
// 请求体带 code请求头带 Authorization: Bearer xxx
```
---
## 优化:已登录用户不弹手机号授权
### 改动
- 已登录按钮:普通 `onClick`,文字「确认加入」
- 未注册按钮:`getPhoneNumber` 授权,文字「微信手机号快速加入」
### 逻辑差异
| 用户状态 | 按钮类型 | 获取 code 方式 |
|------|------|------|
| 已登录 | 普通 onClick | `wx.login()` |
| 未注册 | getPhoneNumber | 授权回调的 `code` |
### 文件修改
- `src/passport/invite/index.tsx` - 按钮区分两种类型,已登录用普通 onClick
---
## 优化:已登录用户不强制勾选协议
### 改动
- 已登录用户点击「确认加入」时,不再检查 `agreementChecked`
- 未注册用户仍需勾选协议后才能授权手机号
### 文件修改
- `src/passport/invite/index.tsx` - `handleConfirmJoin` 移除协议检查
---
## 修复:后端需要手机号授权码
### 问题
后端 `invite/accept` 接口只接受 `getPhoneNumber` 获取的手机号授权码,用 `wx.login()` 的 code 会报「获取手机号失败」。
### 解决
两种用户状态都走 `getPhoneNumber` 按钮:
- 已登录:文字「确认加入」,回调 `handleConfirmJoinGetPhoneNumber`
- 未注册:文字「微信手机号快速加入」,回调 `handleGetPhoneNumber`
### 差异
| 用户状态 | 回调 | 行为 |
|------|------|------|
| 已登录 | `handleConfirmJoinGetPhoneNumber` | 直接用 `code + access_token` 调加入接口 |
| 未注册 | `handleGetPhoneNumber` | 先 `loginByMpWxPhone` 注册登录,再调加入接口 |
### 文件修改
- `src/passport/invite/index.tsx` - 两种状态都用 getPhoneNumber 按钮
---
## 任务:后端改造支持已登录用户直接加入
### 问题
后端 `/api/_app/developer/invite/accept` 接口强制要求传 `code`(手机号授权码),导致已登录用户也需要弹手机号授权。
### 后端改造方案
修改 `AppMpInviteController.acceptInvite` 方法:
#### 1. 参数校验调整
- `code` 改为可选参数
- 不传 `code` 时,从 `Authorization` 头获取当前登录用户
#### 2. 双模式支持
```java
if (StrUtil.isBlank(code)) {
// 模式一:已登录用户(通过 Authorization 头识别)
userId = getCurrentUserId();
} else {
// 模式二:未注册用户(通过手机号授权码获取手机号,创建用户)
String phone = getPhoneByCode(code);
userId = getOrCreateUserByPhone(phone);
}
```
#### 3. getCurrentUserId 方法
- 尝试从 Spring Security Context 获取
- 如果获取不到(免登录接口),手动解析 `Authorization` 头的 JWT Token
### 前端配合改造
- 已登录用户:普通 `onClick` 按钮 → `handleConfirmJoin``doJoinAppForLoggedInUser`(不传 `code`
- 未注册用户:`getPhoneNumber` 按钮 → `handleGetPhoneNumber``doJoinAppForNewUser`(传 `code`
### 文件修改
**后端:**
- `/Users/gxwebsoft/JAVA/websopy-java/src/main/java/com/gxwebsoft/app/controller/AppMpInviteController.java`
- `acceptInvite` 方法支持 `code` 可选
- 使用 `BaseController.getLoginUserId()` 获取当前登录用户(无需额外方法)
**前端:**
- `/Users/gxwebsoft/VUE/websopy-mp/src/passport/invite/index.tsx`
- 已登录按钮改为普通 `onClick`
- 新增 `handleConfirmJoin` 方法
- 拆分 `doJoinApp``doJoinAppForLoggedInUser``doJoinAppForNewUser`
---
## 修复:开发者中心加载不到应用
### 问题
用户通过邀请加入应用后,开发者中心显示「加载中...」,无法显示应用列表。
### 原因
- 前端 `developer/index.tsx` 只调用了 `pageMyApp` 接口(查询用户**创建**的应用)
- 用户通过邀请加入的应用属于**参与**的应用,不是创建的应用
- 后端 `loginByOpenId` 返回了应用列表,但前端没有使用这个数据
### 解决
1. **前端改造**`loadData` 同时调用两个接口:
- `pageMyApp` - 查询创建的应用
- `pageJoinedApp` - 查询参与的应用(新增 API
- 合并两个列表,根据 `productId` 去重
2. **新增 API**`src/api/developer/developer.ts` 添加 `pageJoinedApp` 方法
### 文件修改
- `src/developer/index.tsx` - `loadData` 同时查询创建和参与的应用
- `src/api/developer/developer.ts` - 新增 `pageJoinedApp` 方法