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:
@@ -57,5 +57,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lastUpdated": 1776019986045
|
"lastUpdated": 1776023218479
|
||||||
}
|
}
|
||||||
@@ -439,3 +439,177 @@ src/enterprise/
|
|||||||
### 项目状态
|
### 项目状态
|
||||||
- ✅ 编译成功
|
- ✅ 编译成功
|
||||||
- ✅ 开发服务器运行中 (端口: dist)
|
- ✅ 开发服务器运行中 (端口: 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
|
- 文件:application-prod.yml
|
||||||
- accessKeyId: LTAI4GKGZ9Z2Z8JZ77c3GNZP
|
- accessKeyId: LTAI4GKGZ9Z2Z8JZ77c3GNZP
|
||||||
- 备注:与 OSS 使用同一个 AccessKey
|
- 备注:与 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` 开头。
|
||||||
|
|||||||
@@ -18,22 +18,23 @@ import type {
|
|||||||
ApplyParam,
|
ApplyParam,
|
||||||
} from '@/types/developer'
|
} from '@/types/developer'
|
||||||
|
|
||||||
// ==================== 项目相关 ====================
|
// ==================== 项目/应用相关 ====================
|
||||||
|
// 注意:后端使用 AppProduct 作为项目/应用的概念,路径为 /app/product
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取我的项目列表
|
* 获取我的项目列表(我创建的应用)
|
||||||
*/
|
*/
|
||||||
export async function pageMyProject(params?: ProjectParam) {
|
export async function pageMyProject(params?: ProjectParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Project>>>('/project/my/page', { params })
|
const res = await request.get<ApiResult<PageResult<Project>>>('/app/product/my/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目列表
|
* 获取项目列表(分页查询应用列表)
|
||||||
*/
|
*/
|
||||||
export async function pageProject(params?: ProjectParam) {
|
export async function pageProject(params?: ProjectParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Project>>>('/project/page', { params })
|
const res = await request.get<ApiResult<PageResult<Project>>>('/app/product/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -42,7 +43,7 @@ export async function pageProject(params?: ProjectParam) {
|
|||||||
* 获取项目详情
|
* 获取项目详情
|
||||||
*/
|
*/
|
||||||
export async function getProject(id: number) {
|
export async function getProject(id: number) {
|
||||||
const res = await request.get<ApiResult<Project>>(`/project/${id}`)
|
const res = await request.get<ApiResult<Project>>(`/app/product/detail/${id}`)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -51,7 +52,7 @@ export async function getProject(id: number) {
|
|||||||
* 创建项目
|
* 创建项目
|
||||||
*/
|
*/
|
||||||
export async function createProject(data: Partial<Project>) {
|
export async function createProject(data: Partial<Project>) {
|
||||||
const res = await request.post<ApiResult<unknown>>('/project', data)
|
const res = await request.post<ApiResult<unknown>>('/app/product/create', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -60,7 +61,7 @@ export async function createProject(data: Partial<Project>) {
|
|||||||
* 更新项目
|
* 更新项目
|
||||||
*/
|
*/
|
||||||
export async function updateProject(data: Partial<Project>) {
|
export async function updateProject(data: Partial<Project>) {
|
||||||
const res = await request.put<ApiResult<unknown>>(`/project/${data.id}`, data)
|
const res = await request.put<ApiResult<unknown>>('/app/product/update', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -69,16 +70,16 @@ export async function updateProject(data: Partial<Project>) {
|
|||||||
* 删除项目
|
* 删除项目
|
||||||
*/
|
*/
|
||||||
export async function deleteProject(id: number) {
|
export async function deleteProject(id: number) {
|
||||||
const res = await request.del<ApiResult<unknown>>(`/project/${id}`)
|
const res = await request.del<ApiResult<unknown>>(`/app/product/delete/${id}`)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目成员列表
|
* 获取项目成员列表(使用应用用户服务)
|
||||||
*/
|
*/
|
||||||
export async function listProjectMember(projectId: number) {
|
export async function listProjectMember(projectId: number) {
|
||||||
const res = await request.get<ApiResult<ProjectMember[]>>(`/project/${projectId}/members`)
|
const res = await request.get<ApiResult<ProjectMember[]>>(`/app/app-user/page`, { appId: projectId })
|
||||||
if (res.code === 0 && res.data) return res.data
|
if (res.code === 0 && res.data) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -87,7 +88,7 @@ export async function listProjectMember(projectId: number) {
|
|||||||
* 添加项目成员
|
* 添加项目成员
|
||||||
*/
|
*/
|
||||||
export async function addProjectMember(projectId: number, data: Partial<ProjectMember>) {
|
export async function addProjectMember(projectId: number, data: Partial<ProjectMember>) {
|
||||||
const res = await request.post<ApiResult<unknown>>(`/project/${projectId}/members`, data)
|
const res = await request.post<ApiResult<unknown>>(`/app/app-user`, { ...data, appId: projectId })
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -96,18 +97,27 @@ export async function addProjectMember(projectId: number, data: Partial<ProjectM
|
|||||||
* 移除项目成员
|
* 移除项目成员
|
||||||
*/
|
*/
|
||||||
export async function removeProjectMember(projectId: number, memberId: number) {
|
export async function removeProjectMember(projectId: number, memberId: number) {
|
||||||
const res = await request.del<ApiResult<unknown>>(`/project/${projectId}/members/${memberId}`)
|
const res = await request.del<ApiResult<unknown>>(`/app/app-user/${memberId}`)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 应用相关 ====================
|
// ==================== 应用相关(别名,与项目共用)====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询我的应用
|
* 分页查询我的应用(创建的应用)
|
||||||
*/
|
*/
|
||||||
export async function pageMyApp(params?: AppParam) {
|
export async function pageMyApp(params?: AppParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<App>>>('/app/product/my/page', { params })
|
const res = await request.get<ApiResult<PageResult<App>>>('/app/product/my/page', params)
|
||||||
|
if (res.code === 0) return res.data
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询我参与的应用(通过邀请加入的应用)
|
||||||
|
*/
|
||||||
|
export async function pageJoinedApp(params?: AppParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<App>>>('/app/product/joined/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -116,7 +126,7 @@ export async function pageMyApp(params?: AppParam) {
|
|||||||
* 获取应用列表
|
* 获取应用列表
|
||||||
*/
|
*/
|
||||||
export async function pageApp(params?: AppParam) {
|
export async function pageApp(params?: AppParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<App>>>('/app/product/page', { params })
|
const res = await request.get<ApiResult<PageResult<App>>>('/app/product/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -125,7 +135,7 @@ export async function pageApp(params?: AppParam) {
|
|||||||
* 获取应用详情
|
* 获取应用详情
|
||||||
*/
|
*/
|
||||||
export async function getApp(id: number) {
|
export async function getApp(id: number) {
|
||||||
const res = await request.get<ApiResult<App>>(`/app/product/${id}`)
|
const res = await request.get<ApiResult<App>>(`/app/product/detail/${id}`)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -134,7 +144,7 @@ export async function getApp(id: number) {
|
|||||||
* 创建应用
|
* 创建应用
|
||||||
*/
|
*/
|
||||||
export async function createApp(data: Partial<App>) {
|
export async function createApp(data: Partial<App>) {
|
||||||
const res = await request.post<ApiResult<unknown>>('/app/product', data)
|
const res = await request.post<ApiResult<unknown>>('/app/product/create', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -143,7 +153,7 @@ export async function createApp(data: Partial<App>) {
|
|||||||
* 更新应用
|
* 更新应用
|
||||||
*/
|
*/
|
||||||
export async function updateApp(data: Partial<App>) {
|
export async function updateApp(data: Partial<App>) {
|
||||||
const res = await request.put<ApiResult<unknown>>(`/app/product/${data.id}`, data)
|
const res = await request.put<ApiResult<unknown>>('/app/product/update', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -152,18 +162,19 @@ export async function updateApp(data: Partial<App>) {
|
|||||||
* 删除应用
|
* 删除应用
|
||||||
*/
|
*/
|
||||||
export async function deleteApp(id: number) {
|
export async function deleteApp(id: number) {
|
||||||
const res = await request.del<ApiResult<unknown>>(`/app/product/${id}`)
|
const res = await request.del<ApiResult<unknown>>(`/app/product/delete/${id}`)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== API Key 相关 ====================
|
// ==================== API Key 相关 ====================
|
||||||
|
// 对应后端 AppCredentialController,路径为 /app/app-credential
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 API Key 列表
|
* 获取 API Key 列表
|
||||||
*/
|
*/
|
||||||
export async function pageApiKey(params?: ApiKeyParam) {
|
export async function pageApiKey(params?: ApiKeyParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<ApiKey>>>('/app/app-credential/page', { params })
|
const res = await request.get<ApiResult<PageResult<ApiKey>>>('/app/app-credential/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -204,13 +215,23 @@ export async function deleteApiKey(id: number) {
|
|||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置 API Key Secret
|
||||||
|
*/
|
||||||
|
export async function resetApiKeySecret(id: number) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(`/app/app-credential/resetSecret/${id}`)
|
||||||
|
if (res.code === 0) return res.message
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 版本发布相关 ====================
|
// ==================== 版本发布相关 ====================
|
||||||
|
// 对应后端 AppVersionController,路径为 /app/app-version
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取版本列表
|
* 获取版本列表
|
||||||
*/
|
*/
|
||||||
export async function pageVersion(params?: VersionParam) {
|
export async function pageVersion(params?: VersionParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Version>>>('/app/app-version/page', { params })
|
const res = await request.get<ApiResult<PageResult<Version>>>('/app/app-version/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -233,42 +254,80 @@ export async function createVersion(data: Partial<Version>) {
|
|||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 开发者相关 ====================
|
/**
|
||||||
|
* 发布版本
|
||||||
|
*/
|
||||||
|
export async function publishVersion(id: number) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(`/app/app-version/publish/${id}`)
|
||||||
|
if (res.code === 0) return res.message
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取开发者信息
|
* 回滚版本
|
||||||
|
*/
|
||||||
|
export async function rollbackVersion(id: number) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(`/app/app-version/rollback/${id}`)
|
||||||
|
if (res.code === 0) return res.message
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 开发者相关 ====================
|
||||||
|
// 对应后端 GitAccountController,路径为 /app/developer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取开发者信息(Git账号绑定状态)
|
||||||
*/
|
*/
|
||||||
export async function getDeveloperInfo() {
|
export async function getDeveloperInfo() {
|
||||||
const res = await request.get<ApiResult<Developer>>('/developer/info')
|
const res = await request.get<ApiResult<Developer>>('/app/developer/git-account')
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 申请成为开发者
|
* 申请成为开发者(绑定Git账号)
|
||||||
*/
|
*/
|
||||||
export async function applyDeveloper(data: DeveloperApplyParam) {
|
export async function applyDeveloper(data: DeveloperApplyParam) {
|
||||||
const res = await request.post<ApiResult<unknown>>('/developer/apply', data)
|
const res = await request.post<ApiResult<unknown>>('/app/developer/git-account', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新开发者信息
|
* 更新开发者信息(更新Git账号)
|
||||||
*/
|
*/
|
||||||
export async function updateDeveloperInfo(data: Partial<Developer>) {
|
export async function updateDeveloperInfo(data: Partial<Developer>) {
|
||||||
const res = await request.put<ApiResult<unknown>>('/developer/info', data)
|
const res = await request.put<ApiResult<unknown>>('/app/developer/git-account', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Gitea服务器信息
|
||||||
|
*/
|
||||||
|
export async function getGiteaInfo() {
|
||||||
|
const res = await request.get<ApiResult<{ url: string; version: string; registrationEnabled: boolean }>>('/app/developer/gitea-info')
|
||||||
|
if (res.code === 0) return res.data
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 消息通知相关 ====================
|
// ==================== 消息通知相关 ====================
|
||||||
|
// 对应后端 AppNotificationController,路径为 /app/notification
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取通知列表
|
* 获取通知列表
|
||||||
*/
|
*/
|
||||||
export async function pageNotification(params?: NotificationParam) {
|
export async function pageNotification(params?: NotificationParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Notification>>>('/notification/page', { params })
|
const res = await request.get<ApiResult<PageResult<Notification>>>('/app/notification/page', params)
|
||||||
|
if (res.code === 0) return res.data
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取最近通知(铃铛下拉)
|
||||||
|
*/
|
||||||
|
export async function getRecentNotifications(type?: string, limit?: number) {
|
||||||
|
const res = await request.get<ApiResult<Notification[]>>('/app/notification/recent', { type, limit })
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -277,7 +336,7 @@ export async function pageNotification(params?: NotificationParam) {
|
|||||||
* 获取未读通知数量
|
* 获取未读通知数量
|
||||||
*/
|
*/
|
||||||
export async function getUnreadCount() {
|
export async function getUnreadCount() {
|
||||||
const res = await request.get<ApiResult<{ count: number }>>('/notification/unread-count')
|
const res = await request.get<ApiResult<{ count: number }>>('/app/notification/unread-count')
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -286,7 +345,7 @@ export async function getUnreadCount() {
|
|||||||
* 标记通知为已读
|
* 标记通知为已读
|
||||||
*/
|
*/
|
||||||
export async function markAsRead(id: number) {
|
export async function markAsRead(id: number) {
|
||||||
const res = await request.put<ApiResult<unknown>>(`/notification/${id}/read`)
|
const res = await request.put<ApiResult<unknown>>(`/app/notification/read/${id}`)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -294,8 +353,8 @@ export async function markAsRead(id: number) {
|
|||||||
/**
|
/**
|
||||||
* 标记所有通知为已读
|
* 标记所有通知为已读
|
||||||
*/
|
*/
|
||||||
export async function markAllAsRead() {
|
export async function markAllAsRead(type?: string) {
|
||||||
const res = await request.put<ApiResult<unknown>>('/notification/read-all')
|
const res = await request.put<ApiResult<unknown>>('/app/notification/read-all', { type })
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -304,18 +363,28 @@ export async function markAllAsRead() {
|
|||||||
* 删除通知
|
* 删除通知
|
||||||
*/
|
*/
|
||||||
export async function deleteNotification(id: number) {
|
export async function deleteNotification(id: number) {
|
||||||
const res = await request.del<ApiResult<unknown>>(`/notification/${id}`)
|
const res = await request.del<ApiResult<unknown>>(`/app/notification/${id}`)
|
||||||
|
if (res.code === 0) return res.message
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空已读通知
|
||||||
|
*/
|
||||||
|
export async function clearReadNotifications(type?: string) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>('/app/notification/clear-read', { type })
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 权限审批相关 ====================
|
// ==================== 权限审批相关 ====================
|
||||||
|
// 对应后端 AppPermissionRequestController,路径为 /app/developer/permission-requests
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取申请列表
|
* 获取申请列表
|
||||||
*/
|
*/
|
||||||
export async function pageApply(params?: ApplyParam) {
|
export async function pageApply(params?: ApplyParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Apply>>>('/apply/page', { params })
|
const res = await request.get<ApiResult<PageResult<Apply>>>('/app/developer/permission-requests/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -324,7 +393,25 @@ export async function pageApply(params?: ApplyParam) {
|
|||||||
* 获取我的申请列表
|
* 获取我的申请列表
|
||||||
*/
|
*/
|
||||||
export async function pageMyApply(params?: ApplyParam) {
|
export async function pageMyApply(params?: ApplyParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Apply>>>('/apply/my/page', { params })
|
const res = await request.get<ApiResult<PageResult<Apply>>>('/app/developer/permission-requests', params)
|
||||||
|
if (res.code === 0) return res.data
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取权限申请统计
|
||||||
|
*/
|
||||||
|
export async function getApplyStats() {
|
||||||
|
const res = await request.get<ApiResult<{ [key: string]: number }>>('/app/developer/permission-requests/stats')
|
||||||
|
if (res.code === 0) return res.data
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取可申请的仓库列表
|
||||||
|
*/
|
||||||
|
export async function getAvailableRepos() {
|
||||||
|
const res = await request.get<ApiResult<Array<{ name: string; fullName: string }>>>('/app/developer/permission-requests/available-repos')
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -332,17 +419,26 @@ export async function pageMyApply(params?: ApplyParam) {
|
|||||||
/**
|
/**
|
||||||
* 创建申请
|
* 创建申请
|
||||||
*/
|
*/
|
||||||
export async function createApply(data: Partial<Apply>) {
|
export async function createApply(data: { repo: string; reason: string; gitUsername?: string }) {
|
||||||
const res = await request.post<ApiResult<unknown>>('/apply', data)
|
const res = await request.post<ApiResult<unknown>>('/app/developer/permission-requests', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批申请
|
* 审批申请-通过
|
||||||
*/
|
*/
|
||||||
export async function reviewApply(id: number, status: 'approved' | 'rejected', remark?: string) {
|
export async function approveApply(id: number, note?: string) {
|
||||||
const res = await request.put<ApiResult<unknown>>(`/apply/${id}/review`, { status, remark })
|
const res = await request.put<ApiResult<unknown>>(`/app/developer/permission-requests/${id}/approve`, { note })
|
||||||
|
if (res.code === 0) return res.message
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批申请-拒绝
|
||||||
|
*/
|
||||||
|
export async function rejectApply(id: number, reason: string) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(`/app/developer/permission-requests/${id}/reject`, { reason })
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import request from '@/utils/request'
|
|||||||
import type { ApiResult, PageResult } from '@/api'
|
import type { ApiResult, PageResult } from '@/api'
|
||||||
import type { Enterprise, EnterpriseMember, EnterpriseMemberParam, Order, Bill, BillParam, App, AppParam } from '@/types/developer'
|
import type { Enterprise, EnterpriseMember, EnterpriseMemberParam, Order, Bill, BillParam, App, AppParam } from '@/types/developer'
|
||||||
|
|
||||||
// ==================== 企业相关 ====================
|
// ==================== 企业/租户相关 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取企业信息
|
* 获取企业信息
|
||||||
*/
|
*/
|
||||||
export async function getEnterpriseInfo() {
|
export async function getEnterpriseInfo() {
|
||||||
const res = await request.get<ApiResult<Enterprise>>('/enterprise/info')
|
const res = await request.get<ApiResult<Enterprise>>('/system/tenant/info')
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -17,18 +17,18 @@ export async function getEnterpriseInfo() {
|
|||||||
* 更新企业信息
|
* 更新企业信息
|
||||||
*/
|
*/
|
||||||
export async function updateEnterpriseInfo(data: Partial<Enterprise>) {
|
export async function updateEnterpriseInfo(data: Partial<Enterprise>) {
|
||||||
const res = await request.put<ApiResult<unknown>>('/enterprise/info', data)
|
const res = await request.put<ApiResult<unknown>>('/system/tenant', data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 企业成员相关 ====================
|
// ==================== 企业成员/用户相关 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取企业成员列表
|
* 获取企业成员列表
|
||||||
*/
|
*/
|
||||||
export async function pageEnterpriseMember(params?: EnterpriseMemberParam) {
|
export async function pageEnterpriseMember(params?: EnterpriseMemberParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<EnterpriseMember>>>('/enterprise/member/page', { params })
|
const res = await request.get<ApiResult<PageResult<EnterpriseMember>>>('/system/user/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ export async function pageEnterpriseMember(params?: EnterpriseMemberParam) {
|
|||||||
* 获取企业成员列表(不分页)
|
* 获取企业成员列表(不分页)
|
||||||
*/
|
*/
|
||||||
export async function listEnterpriseMember(params?: EnterpriseMemberParam) {
|
export async function listEnterpriseMember(params?: EnterpriseMemberParam) {
|
||||||
const res = await request.get<ApiResult<EnterpriseMember[]>>('/enterprise/member', params)
|
const res = await request.get<ApiResult<EnterpriseMember[]>>('/system/user', params)
|
||||||
if (res.code === 0 && res.data) return res.data
|
if (res.code === 0 && res.data) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ export async function listEnterpriseMember(params?: EnterpriseMemberParam) {
|
|||||||
* 邀请企业成员
|
* 邀请企业成员
|
||||||
*/
|
*/
|
||||||
export async function inviteEnterpriseMember(enterpriseId: number, data: Partial<EnterpriseMember>) {
|
export async function inviteEnterpriseMember(enterpriseId: number, data: Partial<EnterpriseMember>) {
|
||||||
const res = await request.post<ApiResult<unknown>>(`/enterprise/member/${enterpriseId}/invite`, data)
|
const res = await request.post<ApiResult<unknown>>(`/app/developer/invite/${enterpriseId}/invite`, data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ export async function inviteEnterpriseMember(enterpriseId: number, data: Partial
|
|||||||
* 更新企业成员
|
* 更新企业成员
|
||||||
*/
|
*/
|
||||||
export async function updateEnterpriseMember(data: Partial<EnterpriseMember>) {
|
export async function updateEnterpriseMember(data: Partial<EnterpriseMember>) {
|
||||||
const res = await request.put<ApiResult<unknown>>(`/enterprise/member/${data.id}`, data)
|
const res = await request.put<ApiResult<unknown>>(`/system/user`, data)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ export async function updateEnterpriseMember(data: Partial<EnterpriseMember>) {
|
|||||||
* 移除企业成员
|
* 移除企业成员
|
||||||
*/
|
*/
|
||||||
export async function removeEnterpriseMember(memberId: number) {
|
export async function removeEnterpriseMember(memberId: number) {
|
||||||
const res = await request.del<ApiResult<unknown>>(`/enterprise/member/${memberId}`)
|
const res = await request.del<ApiResult<unknown>>(`/system/user/${memberId}`)
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ export async function removeEnterpriseMember(memberId: number) {
|
|||||||
* 获取订单列表
|
* 获取订单列表
|
||||||
*/
|
*/
|
||||||
export async function pageOrder(params?: { page?: number; limit?: number; status?: number }) {
|
export async function pageOrder(params?: { page?: number; limit?: number; status?: number }) {
|
||||||
const res = await request.get<ApiResult<PageResult<Order>>>('/enterprise/order/page', { params })
|
const res = await request.get<ApiResult<PageResult<Order>>>('/system/order/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -84,18 +84,27 @@ export async function pageOrder(params?: { page?: number; limit?: number; status
|
|||||||
* 获取订单详情
|
* 获取订单详情
|
||||||
*/
|
*/
|
||||||
export async function getOrder(id: number) {
|
export async function getOrder(id: number) {
|
||||||
const res = await request.get<ApiResult<Order>>(`/enterprise/order/${id}`)
|
const res = await request.get<ApiResult<Order>>(`/system/order/${id}`)
|
||||||
if (res.code === 0 && res.data) return res.data
|
if (res.code === 0 && res.data) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 账单相关 ====================
|
/**
|
||||||
|
* 创建订单
|
||||||
|
*/
|
||||||
|
export async function createOrder(data: any) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>('/system/order', data)
|
||||||
|
if (res.code === 0) return res.message
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 充值/账单相关 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取账单列表
|
* 获取账单列表
|
||||||
*/
|
*/
|
||||||
export async function pageBill(params?: BillParam) {
|
export async function pageBill(params?: BillParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<Bill>>>('/enterprise/bill/page', { params })
|
const res = await request.get<ApiResult<PageResult<Bill>>>('/sys/recharge-order/page', params)
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -104,7 +113,7 @@ export async function pageBill(params?: BillParam) {
|
|||||||
* 获取账单概览
|
* 获取账单概览
|
||||||
*/
|
*/
|
||||||
export async function getBillOverview() {
|
export async function getBillOverview() {
|
||||||
const res = await request.get<ApiResult<{ balance: number; totalConsume: number; totalRecharge: number }>>('/enterprise/bill/overview')
|
const res = await request.get<ApiResult<{ balance: number; totalConsume: number; totalRecharge: number }>>('/sys/user-balance-log/overview')
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -115,7 +124,7 @@ export async function getBillOverview() {
|
|||||||
* 获取企业应用列表
|
* 获取企业应用列表
|
||||||
*/
|
*/
|
||||||
export async function pageEnterpriseApp(params?: AppParam) {
|
export async function pageEnterpriseApp(params?: AppParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<App>>>('/enterprise/app/page', { params })
|
const res = await request.get<ApiResult<PageResult<App>>>('/app/product/page', { params })
|
||||||
if (res.code === 0) return res.data
|
if (res.code === 0) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -124,7 +133,7 @@ export async function pageEnterpriseApp(params?: AppParam) {
|
|||||||
* 获取企业应用详情
|
* 获取企业应用详情
|
||||||
*/
|
*/
|
||||||
export async function getEnterpriseApp(id: number) {
|
export async function getEnterpriseApp(id: number) {
|
||||||
const res = await request.get<ApiResult<App>>(`/enterprise/app/${id}`)
|
const res = await request.get<ApiResult<App>>(`/app/product/${id}`)
|
||||||
if (res.code === 0 && res.data) return res.data
|
if (res.code === 0 && res.data) return res.data
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
@@ -133,7 +142,7 @@ export async function getEnterpriseApp(id: number) {
|
|||||||
* 购买应用
|
* 购买应用
|
||||||
*/
|
*/
|
||||||
export async function purchaseApp(productId: number) {
|
export async function purchaseApp(productId: number) {
|
||||||
const res = await request.post<ApiResult<unknown>>('/enterprise/app/purchase', { productId })
|
const res = await request.post<ApiResult<unknown>>('/api/system/order/createOrder', { productId })
|
||||||
if (res.code === 0) return res.message
|
if (res.code === 0) return res.message
|
||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { View, Text, ScrollView } from '@tarojs/components'
|
|||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import { Button, Empty } from '@nutui/nutui-react-taro'
|
import { Button, Empty } from '@nutui/nutui-react-taro'
|
||||||
import { useThemeStyles } from '@/hooks/useTheme'
|
import { useThemeStyles } from '@/hooks/useTheme'
|
||||||
import { pageMyApp } from '@/api/developer'
|
import { pageMyApp, pageJoinedApp } from '@/api/developer'
|
||||||
import type { App } from '@/types/developer'
|
import type { App } from '@/types/developer'
|
||||||
import { APP_TYPE_NAME } from '@/types/developer'
|
import { APP_TYPE_NAME } from '@/types/developer'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
@@ -18,19 +18,45 @@ const DeveloperIndex: React.FC = () => {
|
|||||||
totalCalls: 0,
|
totalCalls: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 加载数据
|
// 加载数据 - 同时查询创建的应用和参与的应用
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const result = await pageMyApp({ current: 1, size: 10 })
|
// 同时调用两个接口:创建的应用 + 参与的应用(通过邀请加入)
|
||||||
if (result) {
|
const [myAppsResult, joinedAppsResult] = await Promise.all([
|
||||||
setApps(result.list || [])
|
pageMyApp({ current: 1, size: 10 }),
|
||||||
|
pageJoinedApp({ current: 1, size: 10 }),
|
||||||
|
])
|
||||||
|
|
||||||
|
// 合并两个列表,去重(根据 productId)
|
||||||
|
const myApps = myAppsResult?.records || []
|
||||||
|
const joinedApps = joinedAppsResult?.records || []
|
||||||
|
|
||||||
|
// 使用 Map 去重,优先保留创建的应用(排在前面)
|
||||||
|
const appMap = new Map<number, App>()
|
||||||
|
|
||||||
|
// 先加入创建的应用
|
||||||
|
myApps.forEach((app) => {
|
||||||
|
if (app.productId) {
|
||||||
|
appMap.set(app.productId, { ...app, isOwner: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 再加入参与的应用(如果已存在则跳过)
|
||||||
|
joinedApps.forEach((app) => {
|
||||||
|
if (app.productId && !appMap.has(app.productId)) {
|
||||||
|
appMap.set(app.productId, { ...app, isOwner: false })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mergedApps = Array.from(appMap.values())
|
||||||
|
|
||||||
|
setApps(mergedApps)
|
||||||
setStats({
|
setStats({
|
||||||
totalApps: result.count || 0,
|
totalApps: mergedApps.length,
|
||||||
runningApps: result.list?.filter((a) => a.status === 1).length || 0,
|
runningApps: mergedApps.filter((a) => a.status === 1).length,
|
||||||
totalCalls: 0,
|
totalCalls: 0,
|
||||||
})
|
})
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载数据失败', error)
|
console.error('加载数据失败', error)
|
||||||
Taro.showToast({ title: '加载失败', icon: 'none' })
|
Taro.showToast({ title: '加载失败', icon: 'none' })
|
||||||
|
|||||||
Reference in New Issue
Block a user