chore: 初始化平台管理端
This commit is contained in:
254
src/api/announcement.ts
Normal file
254
src/api/announcement.ts
Normal file
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
* 文件用途:公告模块 API 封装
|
||||
* 说明:统一对接平台/租户/应用端公告接口
|
||||
* 日期:2025-12-20
|
||||
*/
|
||||
|
||||
import request from '@/utils/http'
|
||||
import type {
|
||||
AnnouncementCommand,
|
||||
AnnouncementFormData,
|
||||
AnnouncementQueryParams,
|
||||
TenantAnnouncementDto
|
||||
} from '@/types/announcement'
|
||||
import type { PagedResult } from '@/types/common/response'
|
||||
|
||||
/** 发布/撤销命令体(仅包含 RowVersion) */
|
||||
type RowVersionCommand = Pick<AnnouncementCommand, 'rowVersion'>
|
||||
|
||||
const withTenantHeader = (tenantId: string) => ({
|
||||
headers: {
|
||||
'X-Tenant-Id': tenantId
|
||||
}
|
||||
})
|
||||
|
||||
const normalizeQueryParams = (params: AnnouncementQueryParams) => {
|
||||
const { dateFrom, dateTo, ...rest } = params
|
||||
return {
|
||||
...rest,
|
||||
effectiveFrom: params.effectiveFrom ?? dateFrom,
|
||||
effectiveTo: params.effectiveTo ?? dateTo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台公告 API
|
||||
* 路由前缀:/api/platform/announcements
|
||||
*/
|
||||
export const platformAnnouncementApi = {
|
||||
/**
|
||||
* 创建平台公告
|
||||
* @param data 创建参数
|
||||
*/
|
||||
create: (data: AnnouncementFormData) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: '/api/platform/announcements',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 查询平台公告列表
|
||||
* @param params 查询参数
|
||||
*/
|
||||
list: (params: AnnouncementQueryParams) => {
|
||||
return request.get<PagedResult<TenantAnnouncementDto>>({
|
||||
url: '/api/platform/announcements',
|
||||
params: normalizeQueryParams(params)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取平台公告详情
|
||||
* @param announcementId 公告ID
|
||||
*/
|
||||
detail: (announcementId: string) => {
|
||||
return request.get<TenantAnnouncementDto>({
|
||||
url: `/api/platform/announcements/${announcementId}`
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新平台公告(仅草稿)
|
||||
* @param announcementId 公告ID
|
||||
* @param data 更新参数
|
||||
*/
|
||||
update: (announcementId: string, data: AnnouncementFormData) => {
|
||||
return request.put<TenantAnnouncementDto>({
|
||||
url: `/api/platform/announcements/${announcementId}`,
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 发布平台公告
|
||||
* @param announcementId 公告ID
|
||||
* @param command 命令体(包含 rowVersion)
|
||||
*/
|
||||
publish: (announcementId: string, command: RowVersionCommand) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/platform/announcements/${announcementId}/publish`,
|
||||
data: command
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 撤销平台公告
|
||||
* @param announcementId 公告ID
|
||||
* @param command 命令体(包含 rowVersion)
|
||||
*/
|
||||
revoke: (announcementId: string, command: RowVersionCommand) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/platform/announcements/${announcementId}/revoke`,
|
||||
data: command
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户公告 API
|
||||
* 路由前缀:/api/admin/v1/tenants/{tenantId}/announcements
|
||||
*/
|
||||
export const tenantAnnouncementApi = {
|
||||
/**
|
||||
* 分页查询租户公告
|
||||
* @param tenantId 租户ID
|
||||
* @param params 查询参数
|
||||
*/
|
||||
list: (tenantId: string, params: AnnouncementQueryParams) => {
|
||||
return request.get<PagedResult<TenantAnnouncementDto>>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements`,
|
||||
params: normalizeQueryParams(params),
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取租户公告详情
|
||||
* @param tenantId 租户ID
|
||||
* @param announcementId 公告ID
|
||||
*/
|
||||
detail: (tenantId: string, announcementId: string) => {
|
||||
return request.get<TenantAnnouncementDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements/${announcementId}`,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建租户公告
|
||||
* @param tenantId 租户ID
|
||||
* @param data 创建参数
|
||||
*/
|
||||
create: (tenantId: string, data: AnnouncementFormData) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements`,
|
||||
data,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新租户公告(仅草稿)
|
||||
* @param tenantId 租户ID
|
||||
* @param announcementId 公告ID
|
||||
* @param data 更新参数
|
||||
*/
|
||||
update: (tenantId: string, announcementId: string, data: AnnouncementFormData) => {
|
||||
return request.put<TenantAnnouncementDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements/${announcementId}`,
|
||||
data,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 发布租户公告
|
||||
* @param tenantId 租户ID
|
||||
* @param announcementId 公告ID
|
||||
* @param command 命令体(包含 rowVersion)
|
||||
*/
|
||||
publish: (tenantId: string, announcementId: string, command: RowVersionCommand) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements/${announcementId}/publish`,
|
||||
data: command,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 撤销租户公告
|
||||
* @param tenantId 租户ID
|
||||
* @param announcementId 公告ID
|
||||
* @param command 命令体(包含 rowVersion)
|
||||
*/
|
||||
revoke: (tenantId: string, announcementId: string, command: RowVersionCommand) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements/${announcementId}/revoke`,
|
||||
data: command,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除租户公告
|
||||
* @param tenantId 租户ID
|
||||
* @param announcementId 公告ID
|
||||
*/
|
||||
delete: (tenantId: string, announcementId: string) => {
|
||||
return request.del<boolean>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements/${announcementId}`,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 标记公告已读(兼容旧路径)
|
||||
* @param tenantId 租户ID
|
||||
* @param announcementId 公告ID
|
||||
*/
|
||||
markRead: (tenantId: string, announcementId: string) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/announcements/${announcementId}/read`,
|
||||
...withTenantHeader(tenantId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用端公告 API
|
||||
* 路由前缀:/api/app/announcements
|
||||
*/
|
||||
export const appAnnouncementApi = {
|
||||
/**
|
||||
* 获取可见公告列表(已发布且有效期内)
|
||||
* @param params 查询参数
|
||||
*/
|
||||
list: (params: AnnouncementQueryParams) => {
|
||||
return request.get<PagedResult<TenantAnnouncementDto>>({
|
||||
url: '/api/app/announcements',
|
||||
params: normalizeQueryParams(params)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取未读公告列表
|
||||
* @param params 查询参数
|
||||
*/
|
||||
unread: (params: AnnouncementQueryParams) => {
|
||||
return request.get<PagedResult<TenantAnnouncementDto>>({
|
||||
url: '/api/app/announcements/unread',
|
||||
params: normalizeQueryParams(params)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 标记公告已读
|
||||
* @param announcementId 公告ID
|
||||
*/
|
||||
markRead: (announcementId: string) => {
|
||||
return request.post<TenantAnnouncementDto>({
|
||||
url: `/api/app/announcements/${announcementId}/mark-read`
|
||||
})
|
||||
}
|
||||
}
|
||||
71
src/api/auth.ts
Normal file
71
src/api/auth.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param params 登录参数
|
||||
* @returns 登录响应
|
||||
*/
|
||||
export function fetchLogin(params: Api.Auth.LoginParams) {
|
||||
return request.post<Api.Auth.LoginResponse>({
|
||||
url: '/api/admin/v1/auth/login',
|
||||
params
|
||||
// showSuccessMessage: true // 显示成功消息
|
||||
// showErrorMessage: false // 不显示错误消息
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 免租户号登录(仅账号+密码)
|
||||
*/
|
||||
export function fetchLoginSimple(params: Api.Auth.LoginParams) {
|
||||
return request.post<Api.Auth.LoginResponse>({
|
||||
url: '/api/admin/v1/auth/login/simple',
|
||||
params,
|
||||
skipTenantHeader: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @returns 用户信息
|
||||
*/
|
||||
export function fetchGetUserInfo() {
|
||||
return request.get<Api.Auth.UserInfo>({
|
||||
url: '/api/admin/v1/auth/profile'
|
||||
// 自定义请求头
|
||||
// headers: {
|
||||
// 'X-Custom-Header': 'your-custom-value'
|
||||
// }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户菜单
|
||||
* @returns 菜单列表
|
||||
*/
|
||||
export function fetchGetMenu() {
|
||||
return request.get<Api.Auth.MenuListResponse>({
|
||||
url: '/api/admin/v1/auth/menu'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户权限
|
||||
* @param userId 用户ID
|
||||
* @returns 用户权限信息
|
||||
*/
|
||||
export function fetchGetUserPermissions(userId: string) {
|
||||
return request.get<Api.Auth.UserPermissionsResponse>({
|
||||
url: `/api/admin/v1/auth/permissions/${userId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过重置链接令牌重置管理员密码
|
||||
*/
|
||||
export function fetchResetAdminPassword(data: Api.Auth.ResetAdminPasswordRequest) {
|
||||
return request.post<void>({
|
||||
url: '/api/admin/v1/auth/reset-password',
|
||||
data
|
||||
})
|
||||
}
|
||||
222
src/api/billing.ts
Normal file
222
src/api/billing.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 账单接口基础路径
|
||||
*
|
||||
* 说明:后端路由为 /api/admin/v1/billings。
|
||||
*/
|
||||
const BILLING_BASE_URL = '/api/admin/v1/billings'
|
||||
|
||||
// ==================== 查询类 API ====================
|
||||
|
||||
/**
|
||||
* 获取账单列表
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchBillingList(params?: Partial<Api.Billing.BillingListParams>) {
|
||||
return request.get<Api.Billing.BillingListResponse>({
|
||||
url: BILLING_BASE_URL,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账单列表(导出用:自动分页拉取)
|
||||
* @param params 查询参数(不含分页也可)
|
||||
* @param options 导出拉取选项
|
||||
*/
|
||||
export async function fetchBillingListForExport(
|
||||
params?: Partial<Api.Billing.BillingListParams>,
|
||||
options?: {
|
||||
/** 单页拉取条数(越大越快,但后端可能有限制) */
|
||||
pageSize?: number
|
||||
/** 最大导出条数(防止一次性导出过大) */
|
||||
maxRows?: number
|
||||
}
|
||||
) {
|
||||
// 1. 兜底配置
|
||||
const pageSize = Math.min(Math.max(options?.pageSize ?? 200, 50), 2000)
|
||||
const maxRows = Math.min(Math.max(options?.maxRows ?? 10000, 1), 100000)
|
||||
|
||||
// 2. 循环分页拉取(直到 totalPages 或达到 maxRows)
|
||||
const result: Api.Billing.BillingListDto[] = []
|
||||
let pageNumber = 1
|
||||
let totalPages = 1
|
||||
|
||||
while (pageNumber <= totalPages && result.length < maxRows) {
|
||||
const res = await fetchBillingList({
|
||||
...params,
|
||||
PageNumber: pageNumber,
|
||||
PageSize: pageSize
|
||||
})
|
||||
|
||||
const items = res.items || []
|
||||
result.push(...items)
|
||||
|
||||
totalPages = res.totalPages || 1
|
||||
if (items.length === 0) break
|
||||
pageNumber += 1
|
||||
}
|
||||
|
||||
// 3. 截断到 maxRows,避免极端情况内存爆炸
|
||||
return result.slice(0, maxRows)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账单详情
|
||||
* @param id 账单 ID
|
||||
*/
|
||||
export function fetchBillingDetail(id: string) {
|
||||
return request.get<Api.Billing.BillingDetailDto>({
|
||||
url: `${BILLING_BASE_URL}/${id}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账单支付记录
|
||||
* @param billingId 账单 ID
|
||||
*/
|
||||
export function fetchBillingPayments(billingId: string) {
|
||||
return request.get<Api.Billing.PaymentRecordListResponse>({
|
||||
url: `${BILLING_BASE_URL}/${billingId}/payments`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账单统计数据
|
||||
* @param params 统计查询参数
|
||||
*/
|
||||
export function fetchBillingStatistics(params: Api.Billing.BillingStatisticsParams) {
|
||||
return request.get<Api.Billing.BillingStatisticsDto>({
|
||||
url: `${BILLING_BASE_URL}/statistics`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取逾期账单列表
|
||||
* @param params 分页参数
|
||||
*/
|
||||
export function fetchOverdueBillings(params?: Partial<Api.Billing.BillingListParams>) {
|
||||
return request.get<Api.Billing.BillingListResponse>({
|
||||
url: `${BILLING_BASE_URL}/overdue`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 命令类 API ====================
|
||||
|
||||
/**
|
||||
* 创建账单
|
||||
* @param data 创建账单数据
|
||||
*/
|
||||
export function createBilling(data: Api.Billing.CreateBillingCommand) {
|
||||
return request.post<Api.Billing.BillingDetailDto>({
|
||||
url: BILLING_BASE_URL,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新账单状态
|
||||
* @param id 账单 ID
|
||||
* @param data 更新状态数据
|
||||
*/
|
||||
export function updateBillingStatus(id: string, data: Api.Billing.UpdateStatusCommand) {
|
||||
return request.put<Api.Billing.BillingDetailDto>({
|
||||
url: `${BILLING_BASE_URL}/${id}/status`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消账单
|
||||
* @param id 账单 ID
|
||||
* @param data 取消原因
|
||||
*/
|
||||
export function cancelBilling(id: string, data: Api.Billing.CancelBillingCommand) {
|
||||
return request.del<void>({
|
||||
url: `${BILLING_BASE_URL}/${id}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录支付(仅创建待审核支付记录,不会立即更新账单状态)
|
||||
* @param billingId 账单 ID
|
||||
* @param data 支付记录数据
|
||||
*/
|
||||
export function recordPayment(billingId: string, data: Api.Billing.RecordPaymentCommand) {
|
||||
return request.post<Api.Billing.PaymentRecordDto>({
|
||||
url: `${BILLING_BASE_URL}/${billingId}/payments`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键确认收款(记录支付 + 立即审核通过 + 同步更新账单状态)
|
||||
* @param billingId 账单 ID
|
||||
* @param data 支付记录数据
|
||||
*/
|
||||
export function confirmPayment(billingId: string, data: Api.Billing.RecordPaymentCommand) {
|
||||
return request.post<Api.Billing.PaymentRecordDto>({
|
||||
url: `${BILLING_BASE_URL}/${billingId}/payments/confirm`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核支付记录
|
||||
* @param paymentId 支付记录 ID
|
||||
* @param data 审核数据
|
||||
*/
|
||||
export function verifyPayment(paymentId: string, data: Api.Billing.VerifyPaymentCommand) {
|
||||
return request.put<Api.Billing.PaymentRecordDto>({
|
||||
url: `${BILLING_BASE_URL}/payments/${paymentId}/verify`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新账单状态
|
||||
* @param data 批量更新数据
|
||||
*/
|
||||
export function batchUpdateStatus(data: Api.Billing.BatchUpdateStatusCommand) {
|
||||
return request.post<void>({
|
||||
url: `${BILLING_BASE_URL}/batch/status`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出账单
|
||||
* @param data 导出参数
|
||||
* @returns Blob 对象(用于下载)
|
||||
*/
|
||||
export function exportBillings(data: Api.Billing.ExportParams) {
|
||||
return request.post<Blob>({
|
||||
url: `${BILLING_BASE_URL}/export`,
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 兼容导出(适配现有页面命名) ====================
|
||||
|
||||
/** 获取账单列表(兼容旧命名) */
|
||||
export const fetchGetBillList = fetchBillingList
|
||||
|
||||
/** 获取账单详情(兼容旧命名) */
|
||||
export const fetchGetBillDetail = fetchBillingDetail
|
||||
|
||||
/** 获取账单列表(导出用,兼容旧命名) */
|
||||
export const fetchGetBillListForExport = fetchBillingListForExport
|
||||
|
||||
/** 创建账单(兼容旧命名) */
|
||||
export const fetchCreateBill = createBilling
|
||||
|
||||
/** 更新账单状态(兼容旧命名) */
|
||||
export const fetchUpdateBillStatus = updateBillingStatus
|
||||
|
||||
/** 记录支付(兼容旧命名) */
|
||||
export const fetchRecordPayment = recordPayment
|
||||
70
src/api/dictionary/group.ts
Normal file
70
src/api/dictionary/group.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const GROUP_BASE_URL = '/api/admin/v1/dictionary/groups'
|
||||
|
||||
export function getGroups(params?: Api.Dictionary.DictionaryGroupQueryParams) {
|
||||
return request.get<Api.Common.PageResult<Api.Dictionary.DictionaryGroupDto>>({
|
||||
url: GROUP_BASE_URL,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function getGroupById(groupId: string) {
|
||||
return request.get<Api.Dictionary.DictionaryGroupDto>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}`
|
||||
})
|
||||
}
|
||||
|
||||
export function createGroup(data: Api.Dictionary.CreateDictionaryGroupRequest) {
|
||||
return request.post<Api.Dictionary.DictionaryGroupDto>({
|
||||
url: GROUP_BASE_URL,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateGroup(groupId: string, data: Api.Dictionary.UpdateDictionaryGroupRequest) {
|
||||
return request.put<Api.Dictionary.DictionaryGroupDto>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteGroup(groupId: string) {
|
||||
return request.del<void>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}`
|
||||
})
|
||||
}
|
||||
|
||||
export function exportGroup(
|
||||
groupId: string,
|
||||
format: Api.Dictionary.DictionaryExportRequest['format']
|
||||
) {
|
||||
return request.post<Blob>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}/export`,
|
||||
data: { format },
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export function importGroup(
|
||||
groupId: string,
|
||||
payload: {
|
||||
file: File
|
||||
conflictMode?: Api.Dictionary.ConflictResolutionMode | string
|
||||
format?: 'csv' | 'json'
|
||||
}
|
||||
) {
|
||||
const formData = new FormData()
|
||||
formData.append('File', payload.file)
|
||||
if (payload.conflictMode) {
|
||||
formData.append('ConflictMode', String(payload.conflictMode))
|
||||
}
|
||||
if (payload.format) {
|
||||
formData.append('Format', payload.format)
|
||||
}
|
||||
|
||||
return request.post<Api.Dictionary.DictionaryImportResultDto>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}/import`,
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
33
src/api/dictionary/item.ts
Normal file
33
src/api/dictionary/item.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const GROUP_BASE_URL = '/api/admin/v1/dictionary/groups'
|
||||
|
||||
export function getItems(groupId: string) {
|
||||
return request.get<Api.Dictionary.DictionaryItemDto[]>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}/items`
|
||||
})
|
||||
}
|
||||
|
||||
export function createItem(groupId: string, data: Api.Dictionary.CreateDictionaryItemRequest) {
|
||||
return request.post<Api.Dictionary.DictionaryItemDto>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}/items`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateItem(
|
||||
groupId: string,
|
||||
itemId: string,
|
||||
data: Api.Dictionary.UpdateDictionaryItemRequest
|
||||
) {
|
||||
return request.put<Api.Dictionary.DictionaryItemDto>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}/items/${itemId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteItem(groupId: string, itemId: string) {
|
||||
return request.del<void>({
|
||||
url: `${GROUP_BASE_URL}/${groupId}/items/${itemId}`
|
||||
})
|
||||
}
|
||||
70
src/api/dictionary/labelOverride.ts
Normal file
70
src/api/dictionary/labelOverride.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const LABEL_OVERRIDE_BASE_URL = '/api/admin/v1/dictionary/label-overrides'
|
||||
|
||||
// ==================== 租户端 API ====================
|
||||
|
||||
/**
|
||||
* 获取当前租户的标签覆盖列表
|
||||
*/
|
||||
export function getTenantLabelOverrides() {
|
||||
return request.get<Api.Dictionary.LabelOverrideDto[]>({
|
||||
url: `${LABEL_OVERRIDE_BASE_URL}/tenant`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户创建/更新标签覆盖
|
||||
*/
|
||||
export function upsertTenantLabelOverride(data: Api.Dictionary.UpsertLabelOverrideRequest) {
|
||||
return request.post<Api.Dictionary.LabelOverrideDto>({
|
||||
url: `${LABEL_OVERRIDE_BASE_URL}/tenant`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户删除标签覆盖
|
||||
*/
|
||||
export function deleteTenantLabelOverride(dictionaryItemId: string) {
|
||||
return request.del<void>({
|
||||
url: `${LABEL_OVERRIDE_BASE_URL}/tenant/${dictionaryItemId}`
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 平台端 API ====================
|
||||
|
||||
/**
|
||||
* 获取指定租户的所有标签覆盖(平台管理员用)
|
||||
*/
|
||||
export function getPlatformLabelOverrides(
|
||||
targetTenantId: string,
|
||||
overrideType?: Api.Dictionary.OverrideType
|
||||
) {
|
||||
return request.get<Api.Dictionary.LabelOverrideDto[]>({
|
||||
url: `${LABEL_OVERRIDE_BASE_URL}/platform/${targetTenantId}`,
|
||||
params: { overrideType }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台强制覆盖租户字典项的标签
|
||||
*/
|
||||
export function upsertPlatformLabelOverride(
|
||||
targetTenantId: string,
|
||||
data: Api.Dictionary.UpsertLabelOverrideRequest
|
||||
) {
|
||||
return request.post<Api.Dictionary.LabelOverrideDto>({
|
||||
url: `${LABEL_OVERRIDE_BASE_URL}/platform/${targetTenantId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台删除对租户的强制覆盖
|
||||
*/
|
||||
export function deletePlatformLabelOverride(targetTenantId: string, dictionaryItemId: string) {
|
||||
return request.del<void>({
|
||||
url: `${LABEL_OVERRIDE_BASE_URL}/platform/${targetTenantId}/${dictionaryItemId}`
|
||||
})
|
||||
}
|
||||
35
src/api/dictionary/metrics.ts
Normal file
35
src/api/dictionary/metrics.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const METRICS_BASE_URL = '/api/admin/v1/dictionary/metrics'
|
||||
|
||||
export function getCacheStats(timeRange: '1h' | '24h' | '7d' = '1h') {
|
||||
return request.get<{
|
||||
totalHits: number
|
||||
totalMisses: number
|
||||
hitRatio: number
|
||||
hitsByLevel: { l1: number; l2: number }
|
||||
missesByLevel: { l1: number; l2: number }
|
||||
averageQueryDurationMs: number
|
||||
topQueriedDictionaries: Array<{ code: string; queryCount: number }>
|
||||
}>({
|
||||
url: `${METRICS_BASE_URL}/cache-stats`,
|
||||
params: { timeRange }
|
||||
})
|
||||
}
|
||||
|
||||
export function getInvalidationEvents(params: {
|
||||
page: number
|
||||
pageSize: number
|
||||
startDate?: string
|
||||
endDate?: string
|
||||
}) {
|
||||
return request.get<Api.Common.PageResult<Api.Dictionary.CacheInvalidationLogDto>>({
|
||||
url: `${METRICS_BASE_URL}/invalidation-events`,
|
||||
params: {
|
||||
page: params.page,
|
||||
pageSize: params.pageSize,
|
||||
startDate: params.startDate,
|
||||
endDate: params.endDate
|
||||
}
|
||||
})
|
||||
}
|
||||
49
src/api/dictionary/override.ts
Normal file
49
src/api/dictionary/override.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const OVERRIDE_BASE_URL = '/api/admin/v1/dictionary/overrides'
|
||||
|
||||
export function getOverrides() {
|
||||
return request.get<Api.Dictionary.OverrideConfigDto[]>({
|
||||
url: OVERRIDE_BASE_URL
|
||||
})
|
||||
}
|
||||
|
||||
export function getOverride(groupCode: string) {
|
||||
return request.get<Api.Dictionary.OverrideConfigDto>({
|
||||
url: `${OVERRIDE_BASE_URL}/${groupCode}`
|
||||
})
|
||||
}
|
||||
|
||||
export function enableOverride(groupCode: string) {
|
||||
return request.post<Api.Dictionary.OverrideConfigDto>({
|
||||
url: `${OVERRIDE_BASE_URL}/${groupCode}/enable`,
|
||||
data: {}
|
||||
})
|
||||
}
|
||||
|
||||
export function disableOverride(groupCode: string) {
|
||||
return request.post<void>({
|
||||
url: `${OVERRIDE_BASE_URL}/${groupCode}/disable`,
|
||||
data: {}
|
||||
})
|
||||
}
|
||||
|
||||
export function updateHiddenItems(
|
||||
groupCode: string,
|
||||
hiddenItemIds: Api.Dictionary.DictionaryOverrideHiddenItemsRequest['hiddenItemIds']
|
||||
) {
|
||||
return request.put<Api.Dictionary.OverrideConfigDto>({
|
||||
url: `${OVERRIDE_BASE_URL}/${groupCode}/hidden-items`,
|
||||
data: { hiddenItemIds }
|
||||
})
|
||||
}
|
||||
|
||||
export function updateSortOrder(
|
||||
groupCode: string,
|
||||
sortOrder: Api.Dictionary.DictionaryOverrideSortOrderRequest['sortOrder']
|
||||
) {
|
||||
return request.put<Api.Dictionary.OverrideConfigDto>({
|
||||
url: `${OVERRIDE_BASE_URL}/${groupCode}/sort-order`,
|
||||
data: { sortOrder }
|
||||
})
|
||||
}
|
||||
27
src/api/dictionary/query.ts
Normal file
27
src/api/dictionary/query.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
const QUERY_BASE_URL = '/api/admin/v1/dictionaries'
|
||||
|
||||
const normalizeCode = (code: string) => code.trim().toLowerCase()
|
||||
|
||||
export async function getDictionary(code: string) {
|
||||
const result = await batchGetDictionaries([code])
|
||||
return result[code] ?? []
|
||||
}
|
||||
|
||||
export async function batchGetDictionaries(codes: string[]) {
|
||||
if (!codes.length) return {}
|
||||
|
||||
const result = await request.post<Record<string, Api.Dictionary.DictionaryItemDto[]>>({
|
||||
url: `${QUERY_BASE_URL}/batch`,
|
||||
data: { codes }
|
||||
})
|
||||
|
||||
const mapped: Record<string, Api.Dictionary.DictionaryItemDto[]> = {}
|
||||
codes.forEach((code) => {
|
||||
const key = normalizeCode(code)
|
||||
mapped[code] = result[key] ?? result[code] ?? []
|
||||
})
|
||||
|
||||
return mapped
|
||||
}
|
||||
22
src/api/files.ts
Normal file
22
src/api/files.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 文件上传 API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 上传图片或文件(Admin)
|
||||
* @param file 上传的文件
|
||||
* @param type 上传类型(可选)
|
||||
*/
|
||||
export function fetchUploadFile(file: File, type: Api.Files.UploadFileType = 'other') {
|
||||
const formData = new FormData()
|
||||
formData.append('File', file)
|
||||
formData.append('Type', type)
|
||||
|
||||
return request.post<Api.Files.FileUploadResponse>({
|
||||
url: '/api/admin/v1/files/upload',
|
||||
// 重要:不要手动设置 Content-Type,让浏览器自动带 boundary
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
126
src/api/merchant.ts
Normal file
126
src/api/merchant.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import api from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 获取商户列表
|
||||
*/
|
||||
export function fetchMerchantList(params?: Partial<Api.Merchant.MerchantListParams>) {
|
||||
return api.get<Api.Merchant.MerchantListResponse>({
|
||||
url: '/api/admin/v1/merchants',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商户详情
|
||||
*/
|
||||
export function fetchMerchantDetail(merchantId: string, options?: { showErrorMessage?: boolean }) {
|
||||
return api.get<Api.Merchant.MerchantDetail>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}`,
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商户信息
|
||||
*/
|
||||
export function fetchUpdateMerchant(
|
||||
merchantId: string,
|
||||
data: Api.Merchant.UpdateMerchantRequest,
|
||||
options?: { showErrorMessage?: boolean }
|
||||
) {
|
||||
return api.put<Api.Merchant.UpdateMerchantResult>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}`,
|
||||
data,
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商户审核历史
|
||||
*/
|
||||
export function fetchMerchantAuditHistory(merchantId: string) {
|
||||
return api.get<Api.Merchant.MerchantAuditRecord[]>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/audit-history`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取商户变更历史
|
||||
*/
|
||||
export function fetchMerchantChangeLogs(merchantId: string, params?: { fieldName?: string }) {
|
||||
return api.get<Api.Merchant.MerchantChangeLogRecord[]>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/change-history`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待审核商户列表
|
||||
*/
|
||||
export function fetchPendingReviewList(params?: Partial<Api.Merchant.MerchantListParams>) {
|
||||
return api.get<Api.Merchant.MerchantReviewListResponse>({
|
||||
url: '/api/admin/v1/merchants/pending-review',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取审核领取信息
|
||||
*/
|
||||
export function fetchMerchantReviewClaim(merchantId: string) {
|
||||
return api.get<Api.Merchant.ClaimInfo | null>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/review/claim`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 领取审核
|
||||
*/
|
||||
export function fetchClaimMerchantReview(merchantId: string) {
|
||||
return api.post<Api.Merchant.ClaimInfo>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/review/claim`,
|
||||
data: {}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放审核
|
||||
*/
|
||||
export function fetchReleaseMerchantReview(merchantId: string) {
|
||||
return api.del<Api.Merchant.ClaimInfo | null>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/review/claim`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行审核
|
||||
*/
|
||||
export function fetchReviewMerchant(merchantId: string, data: Api.Merchant.ReviewMerchantRequest) {
|
||||
return api.post<void>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/review`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销审核
|
||||
*/
|
||||
export function fetchRevokeMerchantReview(
|
||||
merchantId: string,
|
||||
data: Api.Merchant.RevokeMerchantRequest
|
||||
) {
|
||||
return api.post<void>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/review/revoke`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出商户 PDF
|
||||
*/
|
||||
export function fetchExportMerchantPdf(merchantId: string) {
|
||||
return api.get<Blob>({
|
||||
url: `/api/admin/v1/merchants/${merchantId}/export-pdf`,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
21
src/api/permission.ts
Normal file
21
src/api/permission.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 获取权限列表(分页)
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchGetPermissions(params?: Api.Permission.PermissionQueryParams) {
|
||||
return request.get<Api.Permission.PermissionPageResult>({
|
||||
url: '/api/admin/v1/permissions',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权限树
|
||||
*/
|
||||
export function fetchGetPermissionTree() {
|
||||
return request.get<Api.Permission.PermissionDto[]>({
|
||||
url: '/api/admin/v1/permissions/tree'
|
||||
})
|
||||
}
|
||||
100
src/api/quotaPackage.ts
Normal file
100
src/api/quotaPackage.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 配额包管理 API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取配额包列表
|
||||
*/
|
||||
export function fetchQuotaPackageList(params?: {
|
||||
quotaType?: number
|
||||
isActive?: boolean
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}) {
|
||||
return request.get<Api.Common.PageResult<Api.QuotaPackage.QuotaPackageListDto>>({
|
||||
url: '/api/admin/v1/quota-packages',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建配额包
|
||||
*/
|
||||
export function fetchCreateQuotaPackage(data: Api.QuotaPackage.CreateQuotaPackageCommand) {
|
||||
return request.post<Api.QuotaPackage.QuotaPackageDto>({
|
||||
url: '/api/admin/v1/quota-packages',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配额包
|
||||
*/
|
||||
export function fetchUpdateQuotaPackage(
|
||||
quotaPackageId: string,
|
||||
data: Api.QuotaPackage.UpdateQuotaPackageCommand
|
||||
) {
|
||||
return request.put<Api.QuotaPackage.QuotaPackageDto>({
|
||||
url: `/api/admin/v1/quota-packages/${quotaPackageId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配额包(软删)
|
||||
*/
|
||||
export function fetchDeleteQuotaPackage(quotaPackageId: string) {
|
||||
return request.del<boolean>({
|
||||
url: `/api/admin/v1/quota-packages/${quotaPackageId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配额包状态(上架/下架)
|
||||
*/
|
||||
export function fetchUpdateQuotaPackageStatus(quotaPackageId: string, isActive: boolean) {
|
||||
return request.put<boolean>({
|
||||
url: `/api/admin/v1/quota-packages/${quotaPackageId}/status`,
|
||||
data: {
|
||||
isActive
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 为租户购买配额包
|
||||
*/
|
||||
export function fetchPurchaseQuotaPackage(
|
||||
tenantId: string,
|
||||
data: Api.QuotaPackage.PurchaseQuotaPackageCommand
|
||||
) {
|
||||
return request.post<Api.QuotaPackage.TenantQuotaPurchaseDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/quota-packages`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户配额使用情况
|
||||
*/
|
||||
export function fetchTenantQuotaUsage(tenantId: string, params?: { quotaType?: number }) {
|
||||
return request.get<Api.QuotaPackage.TenantQuotaUsageDto[]>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/quota-usage`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户配额购买记录
|
||||
*/
|
||||
export function fetchTenantQuotaPurchases(
|
||||
tenantId: string,
|
||||
params?: { page?: number; pageSize?: number }
|
||||
) {
|
||||
return request.get<Api.Common.PageResult<Api.QuotaPackage.TenantQuotaPurchaseDto>>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/quota-purchases`,
|
||||
params
|
||||
})
|
||||
}
|
||||
94
src/api/role-template.ts
Normal file
94
src/api/role-template.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 获取角色模板列表
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchGetRoleTemplates(params?: any) {
|
||||
return request.get<Api.RoleTemplate.RoleTemplateDto[]>({
|
||||
url: '/api/admin/v1/role-templates',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色模板详情
|
||||
* @param templateCode 模板编码
|
||||
*/
|
||||
export function fetchGetRoleTemplateDetail(templateCode: string) {
|
||||
return request.get<Api.RoleTemplate.RoleTemplateDto>({
|
||||
url: `/api/admin/v1/role-templates/${templateCode}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建角色模板
|
||||
* @param data 创建参数
|
||||
*/
|
||||
export function fetchCreateRoleTemplate(data: Api.RoleTemplate.CreateRoleTemplateCommand) {
|
||||
return request.post<Api.RoleTemplate.RoleTemplateDto>({
|
||||
url: '/api/admin/v1/role-templates',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新角色模板
|
||||
* @param templateCode 模板编码
|
||||
* @param data 更新参数
|
||||
*/
|
||||
export function fetchUpdateRoleTemplate(
|
||||
templateCode: string,
|
||||
data: Api.RoleTemplate.UpdateRoleTemplateCommand
|
||||
) {
|
||||
return request.put<Api.RoleTemplate.RoleTemplateDto>({
|
||||
url: `/api/admin/v1/role-templates/${templateCode}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色模板
|
||||
* @param templateCode 模板编码
|
||||
*/
|
||||
export function fetchDeleteRoleTemplate(templateCode: string) {
|
||||
return request.del<boolean>({
|
||||
url: `/api/admin/v1/role-templates/${templateCode}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆角色模板
|
||||
* @param templateCode 源模板编码
|
||||
* @param data 克隆参数
|
||||
*/
|
||||
export function fetchCloneRoleTemplate(
|
||||
templateCode: string,
|
||||
data: Api.RoleTemplate.CloneRoleTemplateCommand
|
||||
) {
|
||||
return request.post<Api.RoleTemplate.RoleTemplateDto>({
|
||||
url: `/api/admin/v1/role-templates/${templateCode}/clone`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化角色模板
|
||||
* @param templateCodes 模板编码列表
|
||||
*/
|
||||
export function fetchInitRoleTemplates(templateCodes: string[]) {
|
||||
return request.post<any>({
|
||||
url: '/api/admin/v1/role-templates/init',
|
||||
data: { templateCodes }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色模板权限列表
|
||||
* @param templateCode 模板编码
|
||||
*/
|
||||
export function fetchGetRoleTemplatePermissions(templateCode: string) {
|
||||
return request.get<Api.RoleTemplate.PermissionTemplateDto[]>({
|
||||
url: `/api/admin/v1/role-templates/${templateCode}/permissions`
|
||||
})
|
||||
}
|
||||
47
src/api/statistics.ts
Normal file
47
src/api/statistics.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 统计分析 API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取订阅概览统计
|
||||
*/
|
||||
export function fetchSubscriptionOverview() {
|
||||
return request.get<Api.Statistics.SubscriptionOverview>({
|
||||
url: '/api/admin/v1/statistics/subscriptions/overview'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配额使用排行
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchQuotaUsageRanking(params?: Api.Statistics.QuotaUsageRankingParams) {
|
||||
return request.get<Api.Statistics.QuotaUsageRankingResponse>({
|
||||
url: '/api/admin/v1/statistics/quota/ranking',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收入统计
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchRevenueStatistics(params?: Api.Statistics.RevenueStatisticsParams) {
|
||||
return request.get<Api.Statistics.RevenueStatisticsResponse>({
|
||||
url: '/api/admin/v1/statistics/revenue',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取即将到期订阅列表
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchExpiringSubscriptions(params?: Api.Statistics.ExpiringSubscriptionsParams) {
|
||||
return request.get<Api.Statistics.ExpiringSubscriptionsResponse>({
|
||||
url: '/api/admin/v1/statistics/subscriptions/expiring',
|
||||
params
|
||||
})
|
||||
}
|
||||
309
src/api/store.ts
Normal file
309
src/api/store.ts
Normal file
@@ -0,0 +1,309 @@
|
||||
import api from '@/utils/http'
|
||||
|
||||
interface StoreRequestOptions {
|
||||
tenantId?: string
|
||||
}
|
||||
|
||||
const buildTenantHeader = (options?: StoreRequestOptions) => {
|
||||
// 1. 未提供租户ID时返回空配置
|
||||
if (!options?.tenantId) {
|
||||
return {}
|
||||
}
|
||||
|
||||
// 2. 返回携带租户头的请求配置
|
||||
return {
|
||||
headers: {
|
||||
'X-Tenant-Id': String(options.tenantId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店列表
|
||||
*/
|
||||
export function fetchStoreList(params?: Partial<Api.Store.StoreListParams>) {
|
||||
return api.get<Api.Store.StoreListResponse>({
|
||||
url: '/api/admin/v1/stores',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店详情
|
||||
*/
|
||||
export function fetchStoreDetail(storeId: string, options?: { showErrorMessage?: boolean }) {
|
||||
return api.get<Api.Store.StoreDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}`,
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建门店
|
||||
*/
|
||||
export function fetchCreateStore(data: Api.Store.CreateStoreRequest) {
|
||||
return api.post<Api.Store.StoreDto>({
|
||||
url: '/api/admin/v1/stores',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新门店
|
||||
*/
|
||||
export function fetchUpdateStore(storeId: string, data: Api.Store.UpdateStoreRequest) {
|
||||
return api.put<Api.Store.StoreDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除门店
|
||||
*/
|
||||
export function fetchDeleteStore(storeId: string) {
|
||||
return api.del<void>({
|
||||
url: `/api/admin/v1/stores/${storeId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交门店审核
|
||||
*/
|
||||
export function fetchSubmitStoreAudit(storeId: string) {
|
||||
return api.post<boolean>({
|
||||
url: `/api/admin/v1/stores/${storeId}/submit`,
|
||||
data: {}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换门店经营状态
|
||||
*/
|
||||
export function fetchToggleBusinessStatus(
|
||||
storeId: string,
|
||||
data: Api.Store.ToggleBusinessStatusRequest
|
||||
) {
|
||||
return api.post<Api.Store.StoreDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/business-status`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店资质列表
|
||||
*/
|
||||
export function fetchStoreQualifications(storeId: string, options?: StoreRequestOptions) {
|
||||
return api.get<Api.Store.StoreQualificationDto[]>({
|
||||
url: `/api/admin/v1/stores/${storeId}/qualifications`,
|
||||
...buildTenantHeader(options)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查门店资质完整性
|
||||
*/
|
||||
export function fetchCheckStoreQualifications(storeId: string, options?: StoreRequestOptions) {
|
||||
return api.get<Api.Store.StoreQualificationCheckResultDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/qualifications/check`,
|
||||
...buildTenantHeader(options)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建门店资质
|
||||
*/
|
||||
export function fetchCreateStoreQualification(
|
||||
storeId: string,
|
||||
data: Api.Store.CreateStoreQualificationRequest,
|
||||
options?: StoreRequestOptions
|
||||
) {
|
||||
return api.post<Api.Store.StoreQualificationDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/qualifications`,
|
||||
data,
|
||||
...buildTenantHeader(options)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新门店资质
|
||||
*/
|
||||
export function fetchUpdateStoreQualification(
|
||||
storeId: string,
|
||||
qualificationId: string,
|
||||
data: Api.Store.UpdateStoreQualificationRequest,
|
||||
options?: StoreRequestOptions
|
||||
) {
|
||||
return api.put<Api.Store.StoreQualificationDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/qualifications/${qualificationId}`,
|
||||
data,
|
||||
...buildTenantHeader(options)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除门店资质
|
||||
*/
|
||||
export function fetchDeleteStoreQualification(
|
||||
storeId: string,
|
||||
qualificationId: string,
|
||||
options?: StoreRequestOptions
|
||||
) {
|
||||
return api.del<boolean>({
|
||||
url: `/api/admin/v1/stores/${storeId}/qualifications/${qualificationId}`,
|
||||
...buildTenantHeader(options)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店营业时段
|
||||
*/
|
||||
export function fetchStoreBusinessHours(storeId: string) {
|
||||
return api.get<Api.Store.StoreBusinessHourDto[]>({
|
||||
url: `/api/admin/v1/stores/${storeId}/business-hours`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新门店营业时段
|
||||
*/
|
||||
export function fetchBatchUpdateBusinessHours(
|
||||
storeId: string,
|
||||
data: Api.Store.BatchUpdateBusinessHoursRequest
|
||||
) {
|
||||
return api.put<Api.Store.StoreBusinessHourDto[]>({
|
||||
url: `/api/admin/v1/stores/${storeId}/business-hours/batch`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配送区域
|
||||
*/
|
||||
export function fetchStoreDeliveryZones(storeId: string) {
|
||||
return api.get<Api.Store.StoreDeliveryZoneDto[]>({
|
||||
url: `/api/admin/v1/stores/${storeId}/delivery-zones`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建配送区域
|
||||
*/
|
||||
export function fetchCreateStoreDeliveryZone(
|
||||
storeId: string,
|
||||
data: Api.Store.CreateStoreDeliveryZoneRequest
|
||||
) {
|
||||
return api.post<Api.Store.StoreDeliveryZoneDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/delivery-zones`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配送区域
|
||||
*/
|
||||
export function fetchUpdateStoreDeliveryZone(
|
||||
storeId: string,
|
||||
deliveryZoneId: string,
|
||||
data: Api.Store.UpdateStoreDeliveryZoneRequest
|
||||
) {
|
||||
return api.put<Api.Store.StoreDeliveryZoneDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/delivery-zones/${deliveryZoneId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配送区域
|
||||
*/
|
||||
export function fetchDeleteStoreDeliveryZone(storeId: string, deliveryZoneId: string) {
|
||||
return api.del<void>({
|
||||
url: `/api/admin/v1/stores/${storeId}/delivery-zones/${deliveryZoneId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送范围检测
|
||||
*/
|
||||
export function fetchDeliveryZoneCheck(storeId: string, data: Api.Store.StoreDeliveryCheckRequest) {
|
||||
return api.post<Api.Store.StoreDeliveryCheckResultDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/delivery-check`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店费用配置
|
||||
*/
|
||||
export function fetchStoreFee(storeId: string) {
|
||||
return api.get<Api.Store.StoreFeeDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/fee`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新门店费用配置
|
||||
*/
|
||||
export function fetchUpdateStoreFee(storeId: string, data: Api.Store.UpdateStoreFeeRequest) {
|
||||
return api.put<Api.Store.StoreFeeDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/fee`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 门店费用预览
|
||||
*/
|
||||
export function fetchCalculateStoreFee(storeId: string, data: Api.Store.CalculateStoreFeeRequest) {
|
||||
return api.post<Api.Store.StoreFeeCalculationResultDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/fee/calculate`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 临时时段 API ====================
|
||||
|
||||
/**
|
||||
* 获取门店临时时段列表
|
||||
*/
|
||||
export function fetchStoreHolidays(storeId: string) {
|
||||
return api.get<Api.Store.StoreHolidayDto[]>({
|
||||
url: `/api/admin/v1/stores/${storeId}/holidays`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时时段
|
||||
*/
|
||||
export function fetchCreateStoreHoliday(
|
||||
storeId: string,
|
||||
data: Api.Store.CreateStoreHolidayRequest
|
||||
) {
|
||||
return api.post<Api.Store.StoreHolidayDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/holidays`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新临时时段
|
||||
*/
|
||||
export function fetchUpdateStoreHoliday(
|
||||
storeId: string,
|
||||
holidayId: string,
|
||||
data: Api.Store.UpdateStoreHolidayRequest
|
||||
) {
|
||||
return api.put<Api.Store.StoreHolidayDto>({
|
||||
url: `/api/admin/v1/stores/${storeId}/holidays/${holidayId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除临时时段
|
||||
*/
|
||||
export function fetchDeleteStoreHoliday(storeId: string, holidayId: string) {
|
||||
return api.del<boolean>({
|
||||
url: `/api/admin/v1/stores/${storeId}/holidays/${holidayId}`
|
||||
})
|
||||
}
|
||||
103
src/api/storeAudit.ts
Normal file
103
src/api/storeAudit.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import api from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 获取待审核门店列表
|
||||
*/
|
||||
export function fetchPendingStoreAudits(
|
||||
params?: Partial<Api.StoreAudit.ListPendingStoreAuditsParams>
|
||||
) {
|
||||
return api.get<Api.StoreAudit.PendingStoreAuditResponse>({
|
||||
url: '/api/admin/v1/platform/store-audits/pending',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取审核统计
|
||||
*/
|
||||
export function fetchStoreAuditStatistics(params?: Api.StoreAudit.StoreAuditStatisticsParams) {
|
||||
return api.get<Api.StoreAudit.StoreAuditStatisticsDto>({
|
||||
url: '/api/admin/v1/platform/store-audits/statistics',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店审核详情
|
||||
*/
|
||||
export function fetchStoreAuditDetail(storeId: string) {
|
||||
return api.get<Api.StoreAudit.StoreAuditDetailDto>({
|
||||
url: `/api/admin/v1/platform/store-audits/${storeId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取审核记录
|
||||
*/
|
||||
export function fetchStoreAuditRecords(
|
||||
storeId: string,
|
||||
params?: Api.StoreAudit.ListStoreAuditRecordsParams
|
||||
) {
|
||||
return api.get<Api.Common.PageResult<Api.StoreAudit.StoreAuditRecordDto>>({
|
||||
url: `/api/admin/v1/platform/store-audits/${storeId}/records`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核通过
|
||||
*/
|
||||
export function fetchApproveStoreAudit(
|
||||
storeId: string,
|
||||
data: Api.StoreAudit.ApproveStoreAuditRequest
|
||||
) {
|
||||
return api.post<Api.StoreAudit.StoreAuditActionResultDto>({
|
||||
url: `/api/admin/v1/platform/store-audits/${storeId}/approve`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核驳回
|
||||
*/
|
||||
export function fetchRejectStoreAudit(
|
||||
storeId: string,
|
||||
data: Api.StoreAudit.RejectStoreAuditRequest
|
||||
) {
|
||||
return api.post<Api.StoreAudit.StoreAuditActionResultDto>({
|
||||
url: `/api/admin/v1/platform/store-audits/${storeId}/reject`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制关闭门店
|
||||
*/
|
||||
export function fetchForceCloseStore(storeId: string, data: Api.StoreAudit.ForceCloseStoreRequest) {
|
||||
return api.post<Api.StoreAudit.StoreAuditActionResultDto>({
|
||||
url: `/api/admin/v1/platform/store-audits/${storeId}/force-close`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除强制关闭
|
||||
*/
|
||||
export function fetchReopenStore(storeId: string, data: Api.StoreAudit.ReopenStoreRequest) {
|
||||
return api.post<Api.StoreAudit.StoreAuditActionResultDto>({
|
||||
url: `/api/admin/v1/platform/store-audits/${storeId}/reopen`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取资质预警列表(平台)
|
||||
*/
|
||||
export function fetchQualificationAlerts(
|
||||
params?: Partial<Api.Store.StoreQualificationAlertQueryParams>
|
||||
) {
|
||||
return api.get<Api.Store.StoreQualificationAlertResultDto>({
|
||||
url: '/api/admin/v1/platform/store-qualifications/expiring',
|
||||
params
|
||||
})
|
||||
}
|
||||
134
src/api/subscription.ts
Normal file
134
src/api/subscription.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 订阅管理 API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取订阅列表
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function getSubscriptionList(params?: Api.Subscription.SubscriptionListParams) {
|
||||
return request.get<Api.Subscription.SubscriptionListResponse>({
|
||||
url: '/api/admin/v1/subscriptions',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订阅详情
|
||||
* @param id 订阅ID
|
||||
*/
|
||||
export function getSubscriptionDetail(id: string) {
|
||||
return request.get<Api.Subscription.SubscriptionDetailDto>({
|
||||
url: `/api/admin/v1/subscriptions/${id}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订阅
|
||||
* @param id 订阅ID
|
||||
* @param data 更新数据
|
||||
*/
|
||||
export function updateSubscription(
|
||||
id: string,
|
||||
data: Omit<Api.Subscription.UpdateSubscriptionCommand, 'subscriptionId'>
|
||||
) {
|
||||
return request.put<Api.Subscription.SubscriptionDto>({
|
||||
url: `/api/admin/v1/subscriptions/${id}`,
|
||||
data: {
|
||||
...data,
|
||||
subscriptionId: id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 延期订阅
|
||||
* @param id 订阅ID
|
||||
* @param data 延期数据
|
||||
*/
|
||||
export function extendSubscription(
|
||||
id: string,
|
||||
data: Omit<Api.Subscription.ExtendSubscriptionCommand, 'subscriptionId'>
|
||||
) {
|
||||
return request.post<Api.Subscription.SubscriptionDto>({
|
||||
url: `/api/admin/v1/subscriptions/${id}/extend`,
|
||||
data: {
|
||||
...data,
|
||||
subscriptionId: id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更套餐
|
||||
* @param id 订阅ID
|
||||
* @param data 变更数据
|
||||
*/
|
||||
export function changeSubscriptionPlan(
|
||||
id: string,
|
||||
data: Omit<Api.Subscription.ChangePlanCommand, 'subscriptionId'>
|
||||
) {
|
||||
return request.post<Api.Subscription.SubscriptionDto>({
|
||||
url: `/api/admin/v1/subscriptions/${id}/change-plan`,
|
||||
data: {
|
||||
...data,
|
||||
subscriptionId: id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更订阅状态
|
||||
* @param id 订阅ID
|
||||
* @param data 状态数据
|
||||
*/
|
||||
export function updateSubscriptionStatus(
|
||||
id: string,
|
||||
data: Omit<Api.Subscription.UpdateStatusCommand, 'subscriptionId'>
|
||||
) {
|
||||
return request.post<Api.Subscription.SubscriptionDto>({
|
||||
url: `/api/admin/v1/subscriptions/${id}/status`,
|
||||
data: {
|
||||
...data,
|
||||
subscriptionId: id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量延期订阅
|
||||
* @param data 批量延期数据
|
||||
*/
|
||||
export function batchExtendSubscriptions(data: {
|
||||
subscriptionIds: string[]
|
||||
durationDays: number
|
||||
notes?: string
|
||||
}) {
|
||||
return request.post<{
|
||||
successCount: number
|
||||
failureCount: number
|
||||
failures: Array<{ subscriptionId: string; reason: string }>
|
||||
}>({
|
||||
url: '/api/admin/v1/subscriptions/batch-extend',
|
||||
data,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量发送提醒
|
||||
* @param data 批量提醒数据
|
||||
*/
|
||||
export function batchSendReminders(data: { subscriptionIds: string[]; reminderContent: string }) {
|
||||
return request.post<{
|
||||
successCount: number
|
||||
failureCount: number
|
||||
failures: Array<{ subscriptionId: string; reason: string }>
|
||||
}>({
|
||||
url: '/api/admin/v1/subscriptions/batch-remind',
|
||||
data,
|
||||
showSuccessMessage: true
|
||||
})
|
||||
}
|
||||
86
src/api/system-manage.ts
Normal file
86
src/api/system-manage.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import api from '@/utils/http'
|
||||
import type { AppRouteRecord } from '@/types/router'
|
||||
|
||||
// 1. 获取用户列表
|
||||
export function fetchGetUserList(params: Api.SystemManage.UserSearchParams) {
|
||||
return api.get<Api.SystemManage.UserListResponse>({
|
||||
url: '/api/admin/v1/users',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 2. 获取用户详情
|
||||
export function fetchGetUserDetail(userId: string, includeDeleted?: boolean) {
|
||||
return api.get<Api.SystemManage.UserDetailDto>({
|
||||
url: `/api/admin/v1/users/${userId}`,
|
||||
params: includeDeleted ? { includeDeleted } : undefined
|
||||
})
|
||||
}
|
||||
|
||||
// 3. 创建用户
|
||||
export function fetchCreateUser(command: Api.SystemManage.CreateIdentityUserCommand) {
|
||||
return api.post<Api.SystemManage.UserDetailDto>({
|
||||
url: '/api/admin/v1/users',
|
||||
data: command
|
||||
})
|
||||
}
|
||||
|
||||
// 4. 更新用户
|
||||
export function fetchUpdateUser(
|
||||
userId: string,
|
||||
command: Api.SystemManage.UpdateIdentityUserCommand
|
||||
) {
|
||||
return api.put<Api.SystemManage.UserDetailDto>({
|
||||
url: `/api/admin/v1/users/${userId}`,
|
||||
data: command
|
||||
})
|
||||
}
|
||||
|
||||
// 5. 删除用户
|
||||
export function fetchDeleteUser(userId: string) {
|
||||
return api.del<boolean>({
|
||||
url: `/api/admin/v1/users/${userId}`
|
||||
})
|
||||
}
|
||||
|
||||
// 6. 恢复用户
|
||||
export function fetchRestoreUser(userId: string) {
|
||||
return api.post<boolean>({
|
||||
url: `/api/admin/v1/users/${userId}/restore`
|
||||
})
|
||||
}
|
||||
|
||||
// 7. 更新用户状态
|
||||
export function fetchChangeUserStatus(
|
||||
userId: string,
|
||||
command: Api.SystemManage.ChangeIdentityUserStatusCommand
|
||||
) {
|
||||
return api.put<boolean>({
|
||||
url: `/api/admin/v1/users/${userId}/status`,
|
||||
data: command
|
||||
})
|
||||
}
|
||||
|
||||
// 8. 重置用户密码
|
||||
export function fetchResetUserPassword(userId: string) {
|
||||
return api.post<Api.SystemManage.ResetIdentityUserPasswordResult>({
|
||||
url: `/api/admin/v1/users/${userId}/password-reset`
|
||||
})
|
||||
}
|
||||
|
||||
// 9. 批量用户操作
|
||||
export function fetchBatchUserOperation(
|
||||
command: Api.SystemManage.BatchIdentityUserOperationCommand
|
||||
) {
|
||||
return api.post<Api.SystemManage.BatchIdentityUserOperationResult>({
|
||||
url: '/api/admin/v1/users/batch',
|
||||
data: command
|
||||
})
|
||||
}
|
||||
|
||||
// 10. 获取菜单列表
|
||||
export function fetchGetMenuList() {
|
||||
return api.get<AppRouteRecord[]>({
|
||||
url: '/api/v3/system/menus/simple'
|
||||
})
|
||||
}
|
||||
99
src/api/tenant-onboarding.ts
Normal file
99
src/api/tenant-onboarding.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 自助注册租户
|
||||
* @param data 自助注册参数
|
||||
*/
|
||||
export function fetchSelfRegisterTenant(data: Api.Tenant.SelfRegisterTenantCommand) {
|
||||
return request.post<Api.Tenant.SelfRegisterResult>({
|
||||
url: '/api/public/v1/tenants/self-register',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询租户入驻进度
|
||||
* @param tenantId 租户ID
|
||||
*/
|
||||
export function fetchTenantProgress(tenantId: string) {
|
||||
return request.get<Api.Tenant.TenantProgress>({
|
||||
url: `/api/public/v1/tenants/${tenantId}/status`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交或更新租户实名信息
|
||||
* @param tenantId 租户ID
|
||||
* @param data 实名资料
|
||||
*/
|
||||
export function submitTenantVerification(
|
||||
tenantId: string,
|
||||
data: Api.Tenant.SubmitTenantVerificationCommand
|
||||
) {
|
||||
return request.post<Api.Tenant.TenantVerificationDto>({
|
||||
url: `/api/public/v1/tenants/${tenantId}/verification`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交或更新租户实名信息(管理端)
|
||||
* @param tenantId 租户ID
|
||||
* @param data 实名资料
|
||||
*/
|
||||
export function submitTenantVerificationAdmin(
|
||||
tenantId: string,
|
||||
data: Api.Tenant.SubmitTenantVerificationCommand
|
||||
) {
|
||||
return request.post<Api.Tenant.TenantVerificationDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/verification`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建租户订阅
|
||||
* @param tenantId 租户ID
|
||||
* @param data 订阅参数
|
||||
*/
|
||||
export function createTenantSubscription(
|
||||
tenantId: string,
|
||||
data: Api.Tenant.CreateTenantSubscriptionCommand
|
||||
) {
|
||||
return request.post<Api.Tenant.TenantSubscriptionDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/subscriptions`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初次绑定租户订阅(自助入驻)
|
||||
* @param tenantId 租户ID
|
||||
* @param data 初次绑定参数
|
||||
*/
|
||||
export function bindInitialTenantSubscription(
|
||||
tenantId: string,
|
||||
data: Api.Tenant.BindInitialTenantSubscriptionCommand
|
||||
) {
|
||||
return request.post<Api.Tenant.TenantSubscriptionDto>({
|
||||
url: `/api/public/v1/tenants/${tenantId}/subscriptions/initial`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 升降配租户套餐
|
||||
* @param tenantId 租户ID
|
||||
* @param subscriptionId 订阅ID
|
||||
* @param data 升降配参数
|
||||
*/
|
||||
export function changeTenantSubscriptionPlan(
|
||||
tenantId: string,
|
||||
subscriptionId: string,
|
||||
data: Api.Tenant.ChangeTenantSubscriptionPlanCommand
|
||||
) {
|
||||
return request.put<Api.Tenant.TenantSubscriptionDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/subscriptions/${subscriptionId}/plan`,
|
||||
data: { ...data, tenantId, tenantSubscriptionId: subscriptionId }
|
||||
})
|
||||
}
|
||||
103
src/api/tenant-package.ts
Normal file
103
src/api/tenant-package.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 租户套餐管理 API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 获取租户套餐分页列表
|
||||
*/
|
||||
export function fetchTenantPackageList(params?: Api.Tenant.TenantPackageQueryParams) {
|
||||
return request.get<Api.Tenant.TenantPackageListResponse>({
|
||||
url: '/api/admin/v1/tenant-packages',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 公共租户套餐列表(匿名可访问)
|
||||
*/
|
||||
export function fetchPublicTenantPackageList(params?: Api.Tenant.TenantPackageQueryParams) {
|
||||
return request.get<Api.Tenant.PublicTenantPackageListResponse>({
|
||||
url: '/api/public/v1/tenant-packages',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户套餐详情
|
||||
*/
|
||||
export function fetchTenantPackageDetail(tenantPackageId: string) {
|
||||
return request.get<Api.Tenant.TenantPackageDto>({
|
||||
url: `/api/admin/v1/tenant-packages/${tenantPackageId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建租户套餐
|
||||
*/
|
||||
export function fetchCreateTenantPackage(data: Api.Tenant.CreateTenantPackageCommand) {
|
||||
return request.post<Api.Tenant.TenantPackageDto>({
|
||||
url: '/api/admin/v1/tenant-packages',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新租户套餐
|
||||
*/
|
||||
export function fetchUpdateTenantPackage(
|
||||
tenantPackageId: string,
|
||||
data: Api.Tenant.UpdateTenantPackageCommand
|
||||
) {
|
||||
return request.put<Api.Tenant.TenantPackageDto>({
|
||||
url: `/api/admin/v1/tenant-packages/${tenantPackageId}`,
|
||||
data: {
|
||||
...data,
|
||||
tenantPackageId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除租户套餐(软删)
|
||||
*/
|
||||
export function fetchDeleteTenantPackage(tenantPackageId: string) {
|
||||
return request.del<boolean>({
|
||||
url: `/api/admin/v1/tenant-packages/${tenantPackageId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询套餐使用统计(订阅关联数量、使用租户数量)
|
||||
*/
|
||||
export function fetchTenantPackageUsages(tenantPackageIds?: string[]) {
|
||||
const params = new URLSearchParams()
|
||||
if (tenantPackageIds?.length) {
|
||||
tenantPackageIds.forEach((id) => params.append('tenantPackageIds', id))
|
||||
}
|
||||
|
||||
return request.get<Api.Tenant.TenantPackageUsageDto[]>({
|
||||
url: '/api/admin/v1/tenant-packages/usages',
|
||||
params,
|
||||
showErrorMessage: false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询套餐当前使用租户列表(按有效订阅口径)
|
||||
*/
|
||||
export function fetchTenantPackageTenants(
|
||||
tenantPackageId: string,
|
||||
params: { keyword?: string; page?: number; pageSize?: number; expiringWithinDays?: number } = {}
|
||||
) {
|
||||
return request.get<Api.Common.PageResult<Api.Tenant.TenantPackageTenantDto>>({
|
||||
url: `/api/admin/v1/tenant-packages/${tenantPackageId}/tenants`,
|
||||
params: {
|
||||
keyword: params.keyword || undefined,
|
||||
expiringWithinDays: params.expiringWithinDays ?? undefined,
|
||||
page: params.page ?? 1,
|
||||
pageSize: params.pageSize ?? 20
|
||||
}
|
||||
})
|
||||
}
|
||||
98
src/api/tenant-role.ts
Normal file
98
src/api/tenant-role.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 获取租户角色列表
|
||||
* @param tenantId 租户ID
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export function fetchGetTenantRoles(
|
||||
tenantId: number | string,
|
||||
params?: Api.TenantRole.RoleQueryParams
|
||||
) {
|
||||
return request.get<Api.TenantRole.RoleDtoPagedResult>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户角色详情
|
||||
* @param tenantId 租户ID
|
||||
* @param roleId 角色ID
|
||||
*/
|
||||
export function fetchGetTenantRoleDetail(tenantId: number | string, roleId: number | string) {
|
||||
return request.get<Api.TenantRole.RoleDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles/${roleId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建租户角色
|
||||
* @param tenantId 租户ID
|
||||
* @param data 创建参数
|
||||
*/
|
||||
export function fetchCreateTenantRole(
|
||||
tenantId: number | string,
|
||||
data: Api.TenantRole.CreateRoleCommand
|
||||
) {
|
||||
return request.post<Api.TenantRole.RoleDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新租户角色
|
||||
* @param tenantId 租户ID
|
||||
* @param roleId 角色ID
|
||||
* @param data 更新参数
|
||||
*/
|
||||
export function fetchUpdateTenantRole(
|
||||
tenantId: number | string,
|
||||
roleId: number | string,
|
||||
data: Api.TenantRole.UpdateRoleCommand
|
||||
) {
|
||||
return request.put<Api.TenantRole.RoleDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles/${roleId}`,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除租户角色
|
||||
* @param tenantId 租户ID
|
||||
* @param roleId 角色ID
|
||||
*/
|
||||
export function fetchDeleteTenantRole(tenantId: number | string, roleId: number | string) {
|
||||
return request.del<boolean>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles/${roleId}`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户角色权限
|
||||
* @param tenantId 租户ID
|
||||
* @param roleId 角色ID
|
||||
*/
|
||||
export function fetchGetTenantRolePermissions(tenantId: number | string, roleId: number | string) {
|
||||
return request.get<string[]>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles/${roleId}/permissions`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新租户角色权限
|
||||
* @param tenantId 租户ID
|
||||
* @param roleId 角色ID
|
||||
* @param permissions 权限代码列表
|
||||
*/
|
||||
export function fetchUpdateTenantRolePermissions(
|
||||
tenantId: number | string,
|
||||
roleId: number | string,
|
||||
permissionIds: string[]
|
||||
) {
|
||||
return request.put<boolean>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/roles/${roleId}/permissions`,
|
||||
data: { permissionIds }
|
||||
})
|
||||
}
|
||||
263
src/api/tenant.ts
Normal file
263
src/api/tenant.ts
Normal file
@@ -0,0 +1,263 @@
|
||||
import api from '@/utils/http'
|
||||
import { fetchTenantPackageList } from './tenant-package'
|
||||
import type { QuotaUsageHistoryDto, UpdateTenantCommand } from '@/types/tenant'
|
||||
|
||||
/**
|
||||
* 获取租户列表
|
||||
* @param params 搜索参数
|
||||
*/
|
||||
export function fetchGetTenantList(params?: Partial<Api.Tenant.TenantListParams>) {
|
||||
return api.get<Api.Tenant.TenantListResponse>({
|
||||
url: '/api/admin/v1/tenants',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册租户
|
||||
*/
|
||||
export function fetchRegisterTenant(data: Api.Tenant.RegisterTenantCommand) {
|
||||
return api.post<Api.Tenant.TenantDto>({
|
||||
url: '/api/admin/v1/tenants',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台手动新增租户并直接入驻(创建租户 + 认证 + 订阅 + 管理员账号)
|
||||
*/
|
||||
export function fetchCreateTenantManually(data: Api.Tenant.CreateTenantManuallyCommand) {
|
||||
return api.post<Api.Tenant.TenantDetailDto>({
|
||||
url: '/api/admin/v1/tenants/manual',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户详情(包含认证信息、订阅信息)
|
||||
*/
|
||||
export function fetchGetTenantDetail(tenantId: string, options?: { showErrorMessage?: boolean }) {
|
||||
return api.get<Api.Tenant.TenantDetailDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}`,
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户配额使用情况
|
||||
*/
|
||||
export function fetchGetTenantQuotaUsage(
|
||||
tenantId: string,
|
||||
options?: { showErrorMessage?: boolean }
|
||||
) {
|
||||
return api.get<Api.QuotaPackage.TenantQuotaUsageDto[]>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/quota-usage`,
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户配额使用历史
|
||||
* @param tenantId 租户ID
|
||||
* @param params 分页参数
|
||||
*/
|
||||
export function fetchGetTenantQuotaUsageHistory(
|
||||
tenantId: string,
|
||||
params?: { Page?: number; PageSize?: number }
|
||||
) {
|
||||
return api.get<Api.Common.PageResult<QuotaUsageHistoryDto>>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/quota-usage-history`,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订阅信息(注意:该接口为 POST)
|
||||
*/
|
||||
export function fetchGetTenantSubscriptions(
|
||||
tenantId: string,
|
||||
options?: { showErrorMessage?: boolean }
|
||||
) {
|
||||
return api.post<Api.Tenant.TenantSubscriptionDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/subscriptions`,
|
||||
data: {},
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账单信息(分页,最近10条可传 Page=1 PageSize=10)
|
||||
*/
|
||||
export function fetchGetTenantBillings(
|
||||
tenantId: string,
|
||||
params: { Page?: number; PageSize?: number } = {},
|
||||
options?: { showErrorMessage?: boolean }
|
||||
) {
|
||||
return api.get<Api.Common.PageResult<Api.Billing.BillingListDto>>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/billings`,
|
||||
params,
|
||||
showErrorMessage: options?.showErrorMessage
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新租户信息(TD-001:待后端接口补充)
|
||||
* @param tenantId 租户ID(Snowflake long → string)
|
||||
* @param data 更新数据(tenantId 会以入参为准覆盖)
|
||||
* @returns void(后端 BaseResponse<void> 的 data 字段)
|
||||
*
|
||||
* 后端接口:PUT /api/admin/v1/tenants/{tenantId}
|
||||
* 预期响应:BaseResponse<void>
|
||||
* 预期错误码:400(参数错误)、404(租户不存在)、409(code 冲突)
|
||||
* TODO(TD-001): Swagger 中缺失该端点(当前可能返回 404/405),待后端补充后再联调验证
|
||||
*/
|
||||
export function fetchUpdateTenant(tenantId: string, data: UpdateTenantCommand) {
|
||||
return api.put<void>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}`,
|
||||
data: { ...data, tenantId },
|
||||
showErrorMessage: false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户套餐列表(兼容旧调用)
|
||||
*/
|
||||
export const fetchGetTenantPackages = fetchTenantPackageList
|
||||
|
||||
/**
|
||||
* 审核租户
|
||||
*/
|
||||
export function fetchReviewTenant(
|
||||
tenantId: string,
|
||||
data: Omit<Api.Tenant.ReviewTenantCommand, 'tenantId'>
|
||||
) {
|
||||
return api.post<Api.Tenant.TenantDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/review`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户审核领取信息(未领取返回 null)
|
||||
*/
|
||||
export function fetchGetTenantReviewClaim(tenantId: string) {
|
||||
return api.get<Api.Tenant.TenantReviewClaimDto | null>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/review/claim`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 领取租户审核
|
||||
*/
|
||||
export function fetchClaimTenantReview(tenantId: string) {
|
||||
return api.post<Api.Tenant.TenantReviewClaimDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/review/claim`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制接管租户审核(仅超级管理员)
|
||||
*/
|
||||
export function fetchForceClaimTenantReview(tenantId: string) {
|
||||
return api.post<Api.Tenant.TenantReviewClaimDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/review/force-claim`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放租户审核领取(仅领取人)
|
||||
*/
|
||||
export function fetchReleaseTenantReviewClaim(tenantId: string) {
|
||||
return api.post<Api.Tenant.TenantReviewClaimDto | null>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/review/release`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询租户审核日志
|
||||
*/
|
||||
export function fetchGetTenantAuditLogs(
|
||||
tenantId: string,
|
||||
params: { page?: number; pageSize?: number } = {}
|
||||
) {
|
||||
return api.get<Api.Tenant.TenantAuditLogListResponse>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/audits`,
|
||||
params: {
|
||||
page: params.page ?? 1,
|
||||
pageSize: params.pageSize ?? 20
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 冻结租户(暂停服务)
|
||||
*/
|
||||
export function fetchFreezeTenant(
|
||||
tenantId: string,
|
||||
data: Omit<Api.Tenant.FreezeTenantCommand, 'tenantId'>
|
||||
) {
|
||||
return api.post<Api.Tenant.TenantDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/freeze`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 解冻租户(恢复服务)
|
||||
*/
|
||||
export function fetchUnfreezeTenant(
|
||||
tenantId: string,
|
||||
data: Omit<Api.Tenant.UnfreezeTenantCommand, 'tenantId'> = {}
|
||||
) {
|
||||
return api.post<Api.Tenant.TenantDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/unfreeze`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 延期/赠送租户订阅时长(按当前订阅套餐续费)
|
||||
*/
|
||||
export function fetchExtendTenantSubscription(
|
||||
tenantId: string,
|
||||
data: Omit<Api.Tenant.ExtendTenantSubscriptionCommand, 'tenantId'>
|
||||
) {
|
||||
return api.post<Api.Tenant.TenantSubscriptionDto>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/subscriptions/extend`,
|
||||
data: { ...data, tenantId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 伪装登录租户(返回租户主管理员的 Token)
|
||||
*/
|
||||
export function fetchImpersonateTenant(tenantId: string) {
|
||||
return api.post<Api.Auth.TokenResponse>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/impersonate`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成租户主管理员重置密码链接(仅展示一次)
|
||||
*/
|
||||
export function fetchCreateTenantAdminResetLink(tenantId: string) {
|
||||
return api.post<string>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/admin/reset-link`
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户配额购买记录(分页)
|
||||
*/
|
||||
export function fetchGetTenantQuotaPurchases(
|
||||
tenantId: string,
|
||||
params: { Page?: number; PageSize?: number } = {}
|
||||
) {
|
||||
return api.get<Api.Common.PageResult<Api.QuotaPackage.TenantQuotaPurchaseDto>>({
|
||||
url: `/api/admin/v1/tenants/${tenantId}/quota-purchases`,
|
||||
params: {
|
||||
Page: params.Page ?? 1,
|
||||
PageSize: params.PageSize ?? 10
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user