refactor(api): 规范前端API接口地址并统一路径前缀
- 修正开发者、小程序和企业相关API的基础URL,避免重复添加/api前缀 - 统一调整developer、enterprise、invite等模块接口路径,保持与后端Controller一致 - 新增权限申请及消息通知相关API,并完善相关函数实现 - 规范请求参数传递,移除多余包装,改用直接传递对象方式 - 新增API Key重置、版本发布/回滚等接口支持 feat(invite): 重构邀请登录流程支持未注册快速加入 - 完整重写invite页,分离已注册用户和未注册用户的按钮显示和交互 - 实现未注册用户微信手机号授权后自动注册登录及自动加入应用 - 已注册用户直接确认加入应用,无需手机号授权弹窗 - 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错 - 前端配合后端改造,支持已登录用户可直接通过Authorization头加入应用 fix(developer): 修复开发者中心应用加载问题 - 修复只查询创建的应用导致邀请加入的应用不显示的问题 - 同时请求创建应用和参与应用接口,合并并去重应用列表 - 新增pageJoinedApp接口调用及合并逻辑,提高应用列表完整性和体验
This commit is contained in:
@@ -439,3 +439,177 @@ src/enterprise/
|
||||
### 项目状态
|
||||
- ✅ 编译成功
|
||||
- ✅ 开发服务器运行中 (端口: 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` 方法
|
||||
|
||||
@@ -33,3 +33,45 @@
|
||||
- 文件:application-prod.yml
|
||||
- accessKeyId: LTAI4GKGZ9Z2Z8JZ77c3GNZP
|
||||
- 备注:与 OSS 使用同一个 AccessKey
|
||||
|
||||
## 3. 前端接口地址修正
|
||||
**目的**:修正小程序端开发者相关 API 接口地址,与后端 Controller 路径保持一致
|
||||
|
||||
**问题发现**:`BaseUrl` 配置已包含 `/api` 后缀 (`https://websopy-api.websoft.top/api`),前端代码中不应再重复添加 `/api` 前缀,否则会导致 `/api/api/` 路径错误。
|
||||
|
||||
**修正文件**:
|
||||
- `src/api/developer/enterprise.ts`:
|
||||
- 企业信息:`/system/tenant/info`, `/system/tenant`
|
||||
- 企业成员:`/system/user/page`, `/system/user`
|
||||
- 订单:`/system/order/page`, `/system/order`
|
||||
- 账单:`/sys/recharge-order/page`
|
||||
- 企业应用:`/app/product/page`
|
||||
- 邀请:`/app/developer/invite`
|
||||
|
||||
- `src/api/developer/developer.ts`:
|
||||
- 项目/应用:`/app/product/*` (create, update, delete, detail, page, my/page, joined/page)
|
||||
- API Key:`/app/app-credential/*`
|
||||
- 版本发布:`/app/app-version/*`
|
||||
- 开发者信息:`/app/developer/git-account`, `/app/developer/gitea-info`
|
||||
- 通知:`/app/notification/*`
|
||||
- 权限申请:`/app/developer/permission-requests/*`
|
||||
|
||||
- `src/api/invite/index.ts`:
|
||||
- 所有接口移除 `/api` 前缀
|
||||
|
||||
**后端 Controller 对应关系**:
|
||||
| 前端 API | 后端 Controller | 路径前缀 |
|
||||
|---------|----------------|---------|
|
||||
| enterprise.ts | TenantController | /api/system/tenant |
|
||||
| enterprise.ts | UserController | /api/system/user |
|
||||
| enterprise.ts | OrderController | /api/system/order |
|
||||
| enterprise.ts | RechargeOrderController | /api/sys/recharge-order |
|
||||
| developer.ts | AppProductController | /api/app/product |
|
||||
| developer.ts | AppCredentialController | /api/app/app-credential |
|
||||
| developer.ts | AppVersionController | /api/app/app-version |
|
||||
| developer.ts | GitAccountController | /api/app/developer |
|
||||
| developer.ts | AppNotificationController | /api/app/notification |
|
||||
| developer.ts | AppPermissionRequestController | /api/app/developer/permission-requests |
|
||||
| invite/index.ts | - | /api/invite/* |
|
||||
|
||||
**重要配置**:`config/env.ts` 中 `API_BASE_URL` 已包含 `/api` 后缀,前端代码路径不应再以 `/api` 开头。
|
||||
|
||||
Reference in New Issue
Block a user