mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-05 17:27:47 +00:00
refactor: 完成多租户架构移除与系统模块重构
1. 移除所有租户相关逻辑:删除租户ID查询参数、租户字段、租户存储相关代码 2. 重构菜单系统:合并platform/system菜单模块,调整菜单作用域为web/app 3. 修复导出接口:统一post请求使用body传参,替换get导出为post 4. 优化权限标识:更新权限路由前缀为module_system 5. 简化菜单过滤逻辑:移除工作区模式判断,直接展示所有菜单 6. 移除租户切换、代签入等无关功能组件与状态 7. 新增用户注册功能与工单导出接口
This commit is contained in:
@@ -81,7 +81,7 @@ const DemoAPI = {
|
||||
|
||||
export default DemoAPI;
|
||||
|
||||
export interface DemoPageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
export interface DemoPageQuery extends PageQuery, UserByQueryParams {
|
||||
name?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
@@ -13,12 +13,10 @@ export interface RecentLoginItem {
|
||||
export interface DashboardStats {
|
||||
online_users: number;
|
||||
total_users: number;
|
||||
total_tenants: number;
|
||||
total_orders: number;
|
||||
today_login_count: number;
|
||||
today_unique_users: number;
|
||||
week_user_created: number;
|
||||
week_tenant_created: number;
|
||||
paid_orders: number;
|
||||
recent_logins: RecentLoginItem[];
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ const OnlineAPI = {
|
||||
|
||||
export default OnlineAPI;
|
||||
|
||||
export interface OnlineUserPageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
export interface OnlineUserPageQuery extends PageQuery, UserByQueryParams {
|
||||
ipaddr?: string;
|
||||
name?: string;
|
||||
login_location?: string;
|
||||
@@ -41,7 +41,6 @@ export interface OnlineUserPageQuery extends PageQuery, UserByQueryParams, Tenan
|
||||
export interface OnlineUserTable {
|
||||
session_id: string;
|
||||
user_id: number;
|
||||
tenant_id?: number;
|
||||
is_superuser?: boolean;
|
||||
name: string;
|
||||
user_name: string;
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { request } from "@utils";
|
||||
|
||||
const API_PATH = "/platform/invoice";
|
||||
|
||||
const InvoiceAPI = {
|
||||
// ─── 租户端 ───
|
||||
tenantListInvoices(query?: InvoicePageQuery) {
|
||||
return request<ApiResponse<{ list: InvoiceTable[]; total: number }>>({
|
||||
url: `${API_PATH}/mine/list`,
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
applyInvoice(body: InvoiceApplyForm) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/apply`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
downloadInvoice(invoiceId: number) {
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/${invoiceId}/download`,
|
||||
method: "get",
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default InvoiceAPI;
|
||||
|
||||
export interface InvoicePageQuery extends PageQuery, TenantByQueryParams {
|
||||
invoice_type?: string;
|
||||
}
|
||||
|
||||
export interface InvoiceTable {
|
||||
id: number;
|
||||
tenant_id: number;
|
||||
order_id: number;
|
||||
invoice_no: string;
|
||||
invoice_type: string;
|
||||
title: string;
|
||||
tax_no?: string;
|
||||
amount: number;
|
||||
tax_amount: number;
|
||||
status: number;
|
||||
bank_info?: string;
|
||||
address_info?: string;
|
||||
pdf_url?: string;
|
||||
description?: string;
|
||||
created_time?: string;
|
||||
}
|
||||
|
||||
export interface InvoiceApplyForm {
|
||||
order_id: number;
|
||||
invoice_type: string;
|
||||
title: string;
|
||||
tax_no?: string;
|
||||
address_info?: string;
|
||||
bank_info?: string;
|
||||
description?: string;
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
import { request } from "@utils";
|
||||
|
||||
// ─── 平台订单 ──────────────────────────────────────────
|
||||
const API_PATH = "/platform/order";
|
||||
|
||||
const OrderAPI = {
|
||||
// ─── 订单管理 ───
|
||||
listOrders(query?: OrderPageQuery) {
|
||||
return request<ApiResponse<{ items: OrderTable[]; total: number }>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
detailOrder(orderId: number) {
|
||||
return request<ApiResponse<OrderTable>>({
|
||||
url: `${API_PATH}/detail/${orderId}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
createOrder(body: OrderCreateForm) {
|
||||
return request<ApiResponse<{ id: number; order_no: string }>>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
cancelOrder(orderId: number) {
|
||||
return request<ApiResponse<{ message: string }>>({
|
||||
url: `${API_PATH}/cancel/${orderId}`,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
// ─── 支付操作 ───
|
||||
payOrder(orderId: number, method?: string) {
|
||||
return request<
|
||||
ApiResponse<{ order_no: string; amount: number; qr_code_url?: string; pay_url?: string }>
|
||||
>({
|
||||
url: `${API_PATH}/pay/${orderId}`,
|
||||
method: "post",
|
||||
params: method ? { method } : undefined,
|
||||
});
|
||||
},
|
||||
|
||||
queryPaymentStatus(orderId: number) {
|
||||
return request<ApiResponse<{ paid: boolean; order_no?: string; amount?: number }>>({
|
||||
url: `${API_PATH}/status/${orderId}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
mockPaymentCallback(orderId: number) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/mock/callback`,
|
||||
method: "post",
|
||||
data: { order_id: orderId },
|
||||
});
|
||||
},
|
||||
|
||||
// ─── 退款管理 ───
|
||||
listRefunds(query?: RefundPageQuery) {
|
||||
return request<ApiResponse<{ items: OrderTable[]; total: number }>>({
|
||||
url: `${API_PATH}/refund/list`,
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
approveRefund(refundId: number) {
|
||||
return request<ApiResponse<{ message: string }>>({
|
||||
url: `${API_PATH}/approve/${refundId}`,
|
||||
method: "put",
|
||||
});
|
||||
},
|
||||
|
||||
rejectRefund(refundId: number, body: { reject_reason?: string }) {
|
||||
return request<ApiResponse<{ message: string }>>({
|
||||
url: `${API_PATH}/reject/${refundId}`,
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
// ─── 租户端 ───
|
||||
tenantCreateOrder(body: {
|
||||
tenant_id: number;
|
||||
package_id?: number;
|
||||
order_type: string;
|
||||
pay_method?: string;
|
||||
}) {
|
||||
return request<ApiResponse<{ id: number; order_no: string }>>({
|
||||
url: `${API_PATH}/tenant/create`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
tenantApplyRefund(orderId: number, body: { reason: string }) {
|
||||
return request<ApiResponse<{ id: number }>>({
|
||||
url: `${API_PATH}/tenant/refund/apply/${orderId}`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default OrderAPI;
|
||||
|
||||
// ─── Order 类型 ──────────────────────────────────────────
|
||||
|
||||
export interface OrderPageQuery extends PageQuery, TenantByQueryParams {
|
||||
order_type?: string;
|
||||
status?: number;
|
||||
refund_status?: number;
|
||||
}
|
||||
|
||||
export interface OrderTable {
|
||||
id: number;
|
||||
order_no: string;
|
||||
tenant_id: number;
|
||||
package_id?: number;
|
||||
order_type: string;
|
||||
amount: number;
|
||||
period_count: number;
|
||||
status: number;
|
||||
pay_method?: string;
|
||||
pay_time?: string;
|
||||
expire_time: string;
|
||||
created_time?: string;
|
||||
|
||||
// 支付信息
|
||||
transaction_id?: string;
|
||||
raw_response?: string;
|
||||
|
||||
// 退款信息
|
||||
refund_no?: string;
|
||||
refund_amount?: number;
|
||||
refund_reason?: string;
|
||||
refund_transaction_id?: string;
|
||||
reviewer_id?: number;
|
||||
review_time?: string;
|
||||
reject_reason?: string;
|
||||
refund_status?: number;
|
||||
}
|
||||
|
||||
export interface OrderCreateForm {
|
||||
tenant_id: number;
|
||||
package_id?: number;
|
||||
order_type: "new" | "renew" | "upgrade" | "downgrade";
|
||||
pay_method?: string;
|
||||
}
|
||||
|
||||
// ─── Refund 类型(复用 OrderTable 的退款字段)─────────────
|
||||
|
||||
export interface RefundPageQuery extends PageQuery {
|
||||
status?: number;
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
import { request } from "@utils";
|
||||
|
||||
const API_PATH = "/platform/package";
|
||||
|
||||
const PackageAPI = {
|
||||
listPackage(query?: PackagePageQuery) {
|
||||
return request<ApiResponse<PageResult<PackageTable>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
detailPackage(id: number) {
|
||||
return request<ApiResponse<PackageTable>>({
|
||||
url: `${API_PATH}/detail/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
createPackage(body: PackageCreateForm) {
|
||||
return request<ApiResponse<PackageTable>>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
updatePackage(id: number, body: PackageUpdateForm) {
|
||||
return request<ApiResponse<PackageTable>>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
deletePackage(body: number[]) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
batchPackageStatus(body: { ids: number[]; status: number }) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/status/batch`,
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
getPackageMenus(packageId: number) {
|
||||
return request<ApiResponse<number[]>>({
|
||||
url: `${API_PATH}/menus/${packageId}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
setPackageMenus(packageId: number, menuIds: number[]) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/menus/${packageId}/set`,
|
||||
method: "post",
|
||||
data: { menu_ids: menuIds },
|
||||
});
|
||||
},
|
||||
|
||||
getPackageOptions() {
|
||||
return request<ApiResponse<OptionType[]>>({
|
||||
url: `${API_PATH}/options`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default PackageAPI;
|
||||
|
||||
export interface PackagePageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
name?: string;
|
||||
code?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export interface PackageTable extends BaseType {
|
||||
name: string;
|
||||
code: string;
|
||||
sort: number;
|
||||
price: number;
|
||||
period: string;
|
||||
trial_days: number;
|
||||
max_users: number;
|
||||
max_roles: number;
|
||||
max_depts: number;
|
||||
max_storage_mb: number;
|
||||
rate_limit: number;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface PackageForm extends BaseFormType {
|
||||
name?: string;
|
||||
code?: string;
|
||||
sort?: number;
|
||||
price?: number;
|
||||
period?: string;
|
||||
trial_days?: number;
|
||||
max_users?: number;
|
||||
max_roles?: number;
|
||||
max_depts?: number;
|
||||
max_storage_mb?: number;
|
||||
rate_limit?: number;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface PackageCreateForm {
|
||||
name: string;
|
||||
code: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
description?: string;
|
||||
price?: number;
|
||||
period?: string;
|
||||
trial_days?: number;
|
||||
max_users?: number;
|
||||
max_roles?: number;
|
||||
max_depts?: number;
|
||||
max_storage_mb?: number;
|
||||
rate_limit?: number;
|
||||
}
|
||||
|
||||
export interface PackageUpdateForm {
|
||||
name?: string;
|
||||
code?: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
description?: string;
|
||||
price?: number;
|
||||
period?: string;
|
||||
trial_days?: number;
|
||||
max_users?: number;
|
||||
max_roles?: number;
|
||||
max_depts?: number;
|
||||
max_storage_mb?: number;
|
||||
rate_limit?: number;
|
||||
}
|
||||
@@ -1,335 +0,0 @@
|
||||
import { request, NO_AUTH_FLAG } from "@utils";
|
||||
|
||||
const API_PATH = "/platform/tenant";
|
||||
|
||||
const TenantAPI = {
|
||||
listTenant(query?: TenantPageQuery) {
|
||||
return request<ApiResponse<PageResult<TenantTable>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
detailTenant(id: number) {
|
||||
return request<ApiResponse<TenantTable>>({
|
||||
url: `${API_PATH}/detail/${id}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
createTenant(body: TenantCreateForm) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/create`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
updateTenant(id: number, body: TenantUpdateForm) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/update/${id}`,
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
deleteTenant(body: number[]) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/delete`,
|
||||
method: "delete",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/** 批量修改租户状态 */
|
||||
batchTenantStatus(body: BatchType) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/status/batch`,
|
||||
method: "patch",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/** 切换单个租户启用/禁用状态 */
|
||||
toggleTenantStatus(id: number) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/status/${id}`,
|
||||
method: "put",
|
||||
});
|
||||
},
|
||||
|
||||
/** 租户续期 */
|
||||
renewTenant(id: number, body: { end_time: string }) {
|
||||
return request<ApiResponse<TenantTable>>({
|
||||
url: `${API_PATH}/renew/${id}`,
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/** 套餐变更预览 */
|
||||
previewPackageChange(packageId: number) {
|
||||
return request<ApiResponse<PackageChangePreview>>({
|
||||
url: `${API_PATH}/package/preview`,
|
||||
method: "get",
|
||||
params: { target_package_id: packageId },
|
||||
});
|
||||
},
|
||||
|
||||
/** 可选购的套餐列表 */
|
||||
getAvailablePackages() {
|
||||
return request<ApiResponse<{ packages: AvailablePackage[] }>>({
|
||||
url: `${API_PATH}/package/available`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/** 公开接口:无需登录即可获取租户配置(用于登录页等场景) */
|
||||
getTenantConfigInfo(tenantId: number) {
|
||||
return request<ApiResponse<TenantConfigItem[]>>({
|
||||
url: `${API_PATH}/${tenantId}/config/info`,
|
||||
method: "get",
|
||||
headers: {
|
||||
Authorization: NO_AUTH_FLAG,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/** 创建自助订单 */
|
||||
createOrder(body: SelfServiceOrderForm) {
|
||||
return request<ApiResponse<{ order_id: number; amount: number }>>({
|
||||
url: `${API_PATH}/order/create`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/** 我的订单列表 */
|
||||
listMyOrders(query?: PageQuery) {
|
||||
return request<ApiResponse<PageResult<SelfServiceOrderItem>>>({
|
||||
url: `${API_PATH}/order/list`,
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
},
|
||||
|
||||
/** 订单详情 */
|
||||
detailMyOrder(orderId: number) {
|
||||
return request<ApiResponse<SelfServiceOrderItem>>({
|
||||
url: `${API_PATH}/order/detail/${orderId}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/** 租户工作台概览 */
|
||||
getWorkspace() {
|
||||
return request<ApiResponse<WorkspaceData>>({
|
||||
url: `${API_PATH}/workspace`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default TenantAPI;
|
||||
|
||||
export interface TenantPageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
name?: string;
|
||||
code?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export interface TenantTable extends BaseType {
|
||||
name: string;
|
||||
code: string;
|
||||
package_id?: number;
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
contact_name?: string;
|
||||
contact_phone?: string;
|
||||
contact_email?: string;
|
||||
address?: string;
|
||||
domain?: string;
|
||||
logo_url?: string;
|
||||
sort?: number;
|
||||
version?: string;
|
||||
favicon?: string;
|
||||
login_bg?: string;
|
||||
copyright?: string;
|
||||
keep_record?: string;
|
||||
help_doc?: string;
|
||||
privacy?: string;
|
||||
clause?: string;
|
||||
git_code?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface TenantForm extends BaseFormType {
|
||||
name?: string;
|
||||
code?: string;
|
||||
package_id?: number;
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
contact_name?: string;
|
||||
contact_phone?: string;
|
||||
contact_email?: string;
|
||||
address?: string;
|
||||
domain?: string;
|
||||
logo_url?: string;
|
||||
sort?: number;
|
||||
version?: string;
|
||||
favicon?: string;
|
||||
login_bg?: string;
|
||||
copyright?: string;
|
||||
keep_record?: string;
|
||||
help_doc?: string;
|
||||
privacy?: string;
|
||||
clause?: string;
|
||||
git_code?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface TenantCreateForm extends BaseFormType {
|
||||
name: string;
|
||||
code: string;
|
||||
package_id?: number;
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
contact_name?: string;
|
||||
contact_phone?: string;
|
||||
contact_email?: string;
|
||||
address?: string;
|
||||
domain?: string;
|
||||
logo_url?: string;
|
||||
sort?: number;
|
||||
version?: string;
|
||||
favicon?: string;
|
||||
login_bg?: string;
|
||||
copyright?: string;
|
||||
keep_record?: string;
|
||||
help_doc?: string;
|
||||
privacy?: string;
|
||||
clause?: string;
|
||||
git_code?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface TenantUpdateForm extends BaseFormType {
|
||||
name?: string;
|
||||
code?: string;
|
||||
package_id?: number;
|
||||
start_time?: string;
|
||||
end_time?: string;
|
||||
contact_name?: string;
|
||||
contact_phone?: string;
|
||||
contact_email?: string;
|
||||
address?: string;
|
||||
domain?: string;
|
||||
logo_url?: string;
|
||||
sort?: number;
|
||||
version?: string;
|
||||
favicon?: string;
|
||||
login_bg?: string;
|
||||
copyright?: string;
|
||||
keep_record?: string;
|
||||
help_doc?: string;
|
||||
privacy?: string;
|
||||
clause?: string;
|
||||
git_code?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface AvailablePackage {
|
||||
id: number;
|
||||
name: string;
|
||||
price: number;
|
||||
period: string;
|
||||
trial_days: number;
|
||||
max_users: number;
|
||||
max_roles: number;
|
||||
max_depts: number;
|
||||
max_storage_mb: number;
|
||||
description: string | null;
|
||||
is_current: boolean;
|
||||
available_actions: string[];
|
||||
}
|
||||
|
||||
/** 租户配置项 */
|
||||
export interface TenantConfigItem {
|
||||
config_key: string;
|
||||
config_value: string | null;
|
||||
}
|
||||
|
||||
export interface PackageChangePreview {
|
||||
current_package: string;
|
||||
target_package: string;
|
||||
action: string;
|
||||
amount: number;
|
||||
period: string;
|
||||
gained_menus: { id: number; name: string; path: string }[];
|
||||
lost_menus: { id: number; name: string; path: string }[];
|
||||
affected_roles: Record<string, unknown>[];
|
||||
affected_users: number;
|
||||
}
|
||||
|
||||
export interface SelfServiceOrderForm {
|
||||
package_id: number;
|
||||
order_type: "buy" | "renew" | "upgrade" | "downgrade";
|
||||
pay_method?: string;
|
||||
}
|
||||
|
||||
export interface SelfServiceOrderItem {
|
||||
id: number;
|
||||
order_no: string;
|
||||
package_name: string;
|
||||
order_type: string;
|
||||
amount: number;
|
||||
status: number;
|
||||
pay_method?: string;
|
||||
pay_time?: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface WorkspaceData {
|
||||
tenant: {
|
||||
id: number;
|
||||
name: string;
|
||||
code: string;
|
||||
status: number;
|
||||
status_label: string;
|
||||
start_time: string | null;
|
||||
end_time: string | null;
|
||||
days_remaining: number;
|
||||
};
|
||||
package: {
|
||||
id: number;
|
||||
name: string;
|
||||
price: number;
|
||||
period: string;
|
||||
} | null;
|
||||
quota: {
|
||||
max_users: number;
|
||||
max_roles: number;
|
||||
max_depts: number;
|
||||
current_users: number;
|
||||
current_roles: number;
|
||||
current_depts: number;
|
||||
usage_percent: {
|
||||
users: number;
|
||||
roles: number;
|
||||
depts: number;
|
||||
};
|
||||
};
|
||||
recent_orders: {
|
||||
id: number;
|
||||
order_no: string;
|
||||
amount: number;
|
||||
order_type: string;
|
||||
status: number;
|
||||
created_at: string | null;
|
||||
}[];
|
||||
}
|
||||
@@ -75,14 +75,16 @@ export interface ApiTokenPageQuery extends PageQuery {
|
||||
export interface ApiTokenTable extends BaseType {
|
||||
name?: string;
|
||||
token_prefix?: string;
|
||||
scopes?: string[];
|
||||
token_mask?: string;
|
||||
owner_user_id?: number;
|
||||
scopes?: string;
|
||||
expires_at?: string;
|
||||
rate_limit?: number;
|
||||
status?: number;
|
||||
last_used_at?: string;
|
||||
last_used_ip?: string;
|
||||
used_count?: number;
|
||||
description?: string;
|
||||
tenant_id?: number;
|
||||
}
|
||||
|
||||
export interface ApiTokenCreateForm extends BaseFormType {
|
||||
|
||||
@@ -45,83 +45,6 @@ const AuthAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
/** 获取当前用户的可选租户列表 */
|
||||
getTenants() {
|
||||
return request<ApiResponse<TenantOption[]>>({
|
||||
url: `${API_PATH}/tenants`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/** 选择租户,返回含 tenant_id 的新 JWT */
|
||||
selectTenant(tenantId: number) {
|
||||
return request<ApiResponse<SelectTenantResult>>({
|
||||
url: `${API_PATH}/select-tenant`,
|
||||
method: "post",
|
||||
data: { tenant_id: tenantId },
|
||||
});
|
||||
},
|
||||
|
||||
/** 返回平台管理模式,清除 tenant_id 返回平台作用域 JWT */
|
||||
enterPlatform() {
|
||||
return request<ApiResponse<SelectTenantResult>>({
|
||||
url: `${API_PATH}/enter-platform`,
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
|
||||
/** 平台管理员代签入(以指定租户身份登录) */
|
||||
impersonate(tenantId: number) {
|
||||
return request<ApiResponse<ImpersonateResult>>({
|
||||
url: `${API_PATH}/impersonate`,
|
||||
method: "post",
|
||||
data: { tenant_id: tenantId },
|
||||
});
|
||||
},
|
||||
|
||||
/** 租户自助注册(PRD §4.5) */
|
||||
tenantRegister(body: TenantRegisterForm) {
|
||||
return request<ApiResponse<TenantRegisterResult>>({
|
||||
url: `${API_PATH}/tenant/register`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
/** 根据编码查询租户 */
|
||||
lookupTenant(code: string) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/tenant/${encodeURIComponent(code)}`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/** 根据域名查询租户 */
|
||||
lookupTenantByDomain(domain: string) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/tenant-by-domain`,
|
||||
method: "get",
|
||||
params: { domain },
|
||||
});
|
||||
},
|
||||
|
||||
/** 搜索租户(根据关键字模糊搜索编码或名称) */
|
||||
tenantSearch(q: string) {
|
||||
return request<ApiResponse<TenantOption[]>>({
|
||||
url: `${API_PATH}/tenant-search`,
|
||||
method: "get",
|
||||
params: { q },
|
||||
});
|
||||
},
|
||||
|
||||
/** 获取所有活跃租户选项,用于登录页下拉选择 */
|
||||
getTenantOptions() {
|
||||
return request<ApiResponse<TenantOption[]>>({
|
||||
url: `${API_PATH}/tenant-options`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/** 滑块验证完成后端标记 */
|
||||
sliderComplete(captchaKey: string) {
|
||||
return request<ApiResponse<{ captcha_key: string; verified: boolean }>>({
|
||||
@@ -134,24 +57,6 @@ const AuthAPI = {
|
||||
|
||||
export default AuthAPI;
|
||||
|
||||
export interface TenantRegisterForm {
|
||||
username: string;
|
||||
password: string;
|
||||
email: string;
|
||||
tenant_name?: string;
|
||||
}
|
||||
|
||||
export interface TenantRegisterResult {
|
||||
user_id: number;
|
||||
username: string;
|
||||
tenant_id: number;
|
||||
tenant_name: string;
|
||||
tenant_code: string;
|
||||
package: string | null;
|
||||
trial_end: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
// ─── Auth 类型定义 ───
|
||||
|
||||
/** 登录表单 */
|
||||
@@ -172,39 +77,13 @@ export interface JWTOut {
|
||||
}
|
||||
|
||||
/** 登录成功返回 */
|
||||
export interface LoginResult extends JWTOut {
|
||||
tenants?: TenantOption[];
|
||||
}
|
||||
export type LoginResult = JWTOut;
|
||||
|
||||
/** 退出登录请求体 */
|
||||
export interface LogoutBody {
|
||||
token: string;
|
||||
}
|
||||
|
||||
/** 租户选项 */
|
||||
export interface TenantOption {
|
||||
id: number;
|
||||
name: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
/** 选择租户返回 (SelectTenantOutSchema) */
|
||||
export interface SelectTenantResult {
|
||||
access_token: string;
|
||||
token_type: string;
|
||||
expires_in: number;
|
||||
}
|
||||
|
||||
/** 平台管理员代签入返回 (ImpersonateOutSchema) */
|
||||
export interface ImpersonateResult {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
token_type: string;
|
||||
expires_in: number;
|
||||
tenant_id: number;
|
||||
tenant_name: string;
|
||||
}
|
||||
|
||||
/** 验证码信息 */
|
||||
export interface CaptchaInfo {
|
||||
enable: boolean;
|
||||
|
||||
@@ -53,7 +53,7 @@ const DeptAPI = {
|
||||
|
||||
export default DeptAPI;
|
||||
|
||||
export interface DeptPageQuery extends UserByQueryParams, TenantByQueryParams {
|
||||
export interface DeptPageQuery extends UserByQueryParams {
|
||||
name?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
@@ -113,11 +113,11 @@ const DictAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
exportDictData(body: DictDataPageQuery) {
|
||||
exportDictData(query: DictDataPageQuery) {
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/data/export`,
|
||||
method: "post",
|
||||
data: body,
|
||||
data: query,
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -40,16 +40,15 @@ const OperationLogAPI = {
|
||||
|
||||
export default OperationLogAPI;
|
||||
|
||||
export interface OperationLogPageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
export interface OperationLogPageQuery extends PageQuery, UserByQueryParams {
|
||||
request_path?: string;
|
||||
creator_name?: string;
|
||||
username?: string;
|
||||
status?: number;
|
||||
request_ip?: string;
|
||||
}
|
||||
|
||||
export interface OperationLogTable {
|
||||
id: number;
|
||||
tenant_id: number;
|
||||
request_path?: string;
|
||||
request_method?: string;
|
||||
request_payload?: Record<string, unknown> | string;
|
||||
@@ -89,7 +88,7 @@ export const LoginLogAPI = {
|
||||
},
|
||||
};
|
||||
|
||||
export interface LoginLogPageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
export interface LoginLogPageQuery extends PageQuery, UserByQueryParams {
|
||||
username?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
+4
-7
@@ -1,6 +1,6 @@
|
||||
import { request } from "@utils";
|
||||
|
||||
const API_PATH = "/platform/menu";
|
||||
const API_PATH = "/system/menu";
|
||||
|
||||
const MenuAPI = {
|
||||
listMenu(query?: MenuPageQuery) {
|
||||
@@ -55,14 +55,13 @@ export default MenuAPI;
|
||||
|
||||
export interface MenuPageQuery extends BaseQueryParams {
|
||||
name?: string;
|
||||
menu_client?: "pc" | "app";
|
||||
status?: number;
|
||||
type?: number;
|
||||
permission?: string;
|
||||
route_path?: string;
|
||||
component_path?: string;
|
||||
description?: string;
|
||||
scope?: "platform" | "tenant";
|
||||
scope?: "web" | "app";
|
||||
}
|
||||
|
||||
export interface MenuTable extends BaseType {
|
||||
@@ -84,14 +83,13 @@ export interface MenuTable extends BaseType {
|
||||
params?: { key: string; value: string }[];
|
||||
affix?: boolean;
|
||||
children?: MenuTable[];
|
||||
client?: "pc" | "app";
|
||||
link?: string;
|
||||
is_iframe?: boolean;
|
||||
is_hide_tab?: boolean;
|
||||
active_path?: string;
|
||||
show_badge?: boolean;
|
||||
show_text_badge?: string;
|
||||
scope?: "platform" | "tenant";
|
||||
scope?: "web" | "app";
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
@@ -113,14 +111,13 @@ export interface MenuForm extends BaseFormType {
|
||||
title?: string;
|
||||
params?: KeyValue[];
|
||||
affix?: boolean;
|
||||
client?: "pc" | "app";
|
||||
link?: string;
|
||||
is_iframe?: boolean;
|
||||
is_hide_tab?: boolean;
|
||||
active_path?: string;
|
||||
show_badge?: boolean;
|
||||
show_text_badge?: string;
|
||||
scope?: "platform" | "tenant";
|
||||
scope?: "web" | "app";
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
@@ -70,11 +70,11 @@ const ParamsAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
exportParams(body: ConfigPageQuery) {
|
||||
exportParams(query: ConfigPageQuery) {
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: "post",
|
||||
data: body,
|
||||
data: query,
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -50,11 +50,11 @@ const PositionAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
exportPosition(body: PositionPageQuery) {
|
||||
exportPosition(query: PositionPageQuery) {
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: "post",
|
||||
data: body,
|
||||
data: query,
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -58,11 +58,11 @@ const RoleAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
exportRole(body: TablePageQuery) {
|
||||
exportRole(query: TablePageQuery) {
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: "post",
|
||||
data: body,
|
||||
data: query,
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
@@ -79,6 +79,8 @@ export default RoleAPI;
|
||||
|
||||
export interface TablePageQuery extends PageQuery, UserByQueryParams {
|
||||
name?: string;
|
||||
code?: string;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export interface RoleTable extends BaseType {
|
||||
|
||||
@@ -25,8 +25,8 @@ const TicketAPI = {
|
||||
exportTicket(query?: TicketPageQuery) {
|
||||
return request<ApiResponse<Blob>>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: "get",
|
||||
params: query,
|
||||
method: "post",
|
||||
data: query,
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { request } from "@utils";
|
||||
import { MenuTable, MenuForm } from "@/api/module_platform/menu";
|
||||
import { MenuTable, MenuForm } from "@/api/module_system/menu";
|
||||
|
||||
const API_PATH = "/system/user";
|
||||
|
||||
@@ -30,7 +30,7 @@ export const UserAPI = {
|
||||
|
||||
changeCurrentUserPassword(body: PasswordFormState) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/current/password/change`,
|
||||
url: `${API_PATH}/password/change`,
|
||||
method: "put",
|
||||
data: body,
|
||||
});
|
||||
@@ -52,6 +52,14 @@ export const UserAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
register(body: RegisterForm) {
|
||||
return request<ApiResponse>({
|
||||
url: `${API_PATH}/register`,
|
||||
method: "post",
|
||||
data: body,
|
||||
});
|
||||
},
|
||||
|
||||
listUser(query: UserPageQuery) {
|
||||
return request<ApiResponse<PageResult<UserInfo>>>({
|
||||
url: `${API_PATH}/list`,
|
||||
@@ -102,8 +110,8 @@ export const UserAPI = {
|
||||
exportUser(query: UserPageQuery) {
|
||||
return request<Blob>({
|
||||
url: `${API_PATH}/export`,
|
||||
method: "get",
|
||||
params: query,
|
||||
method: "post",
|
||||
data: query,
|
||||
responseType: "blob",
|
||||
});
|
||||
},
|
||||
@@ -131,7 +139,6 @@ export const UserAPI = {
|
||||
export default UserAPI;
|
||||
|
||||
export interface ForgetPasswordForm {
|
||||
tenant_name: string;
|
||||
username: string;
|
||||
new_password: string;
|
||||
mobile?: string;
|
||||
@@ -139,19 +146,19 @@ export interface ForgetPasswordForm {
|
||||
}
|
||||
|
||||
export interface RegisterForm {
|
||||
tenant_name: string;
|
||||
username: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
email?: string;
|
||||
}
|
||||
|
||||
export interface UserPageQuery extends PageQuery, UserByQueryParams, TenantByQueryParams {
|
||||
export interface UserPageQuery extends PageQuery, UserByQueryParams {
|
||||
username?: string;
|
||||
name?: string;
|
||||
mobile?: string;
|
||||
email?: string;
|
||||
dept_id?: number;
|
||||
status?: number;
|
||||
}
|
||||
|
||||
export interface searchSelectDataType {
|
||||
@@ -183,7 +190,6 @@ export interface UserInfo extends BaseType {
|
||||
created_by?: CommonType;
|
||||
updated_by?: CommonType;
|
||||
deleted_by?: CommonType;
|
||||
tenant_by?: CommonType;
|
||||
gitee_login?: string;
|
||||
github_login?: string;
|
||||
wx_login?: string;
|
||||
@@ -231,7 +237,6 @@ export interface InfoFormState {
|
||||
updated_time?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
tenant_by?: CommonType;
|
||||
gitee_login?: string;
|
||||
github_login?: string;
|
||||
wx_login?: string;
|
||||
@@ -263,7 +268,6 @@ export interface UserForm extends BaseFormType {
|
||||
mobile?: string;
|
||||
is_superuser?: boolean;
|
||||
avatar?: string;
|
||||
tenant_id?: number;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user