feat(admin-frontend): 补齐用户节点与订单运营工作台

新增用户高级筛选、批量操作与更多行级动作,支持邮件、
CSV、封禁恢复、订单分配、邀请查看、流量记录与重置流量

增强节点管理页的分页、父子筛选、跨页勾选、批量修改与
单节点置顶,并补齐后端批量更新 host、group_ids、rate

修复订单佣金状态误判问题,新增真实佣金筛选与行级确认,
同时优化仪表盘排行悬浮详情展示

补充 admin-frontend 独立 Dockerfile、Caddy 配置与 GHCR
发布工作流,支持通过独立镜像部署管理前端
This commit is contained in:
yinjianm
2026-04-24 23:15:48 +08:00
parent e393b11b61
commit d4168720ac
65 changed files with 4114 additions and 438 deletions
+31
View File
@@ -24,6 +24,7 @@ import type {
AdminNoticeItem,
AdminNoticeSavePayload,
AdminNodeItem,
AdminNodeBatchUpdatePayload,
AdminNodeSavePayload,
AdminNodeRouteItem,
AdminNodeRouteSavePayload,
@@ -45,6 +46,9 @@ import type {
AdminTicketFetchParams,
AdminTicketListItem,
AdminTrafficLogResult,
AdminUserBulkBanPayload,
AdminUserBulkMailPayload,
AdminUserBulkScopePayload,
AdminUserFetchParams,
AdminUserGeneratePayload,
AdminUserListItem,
@@ -506,6 +510,10 @@ export function updateNode(payload: AdminNodeUpdatePayload): Promise<ApiResponse
return unwrapPost<boolean>('/server/manage/update', payload as unknown as Record<string, unknown>)
}
export function batchUpdateNodes(payload: AdminNodeBatchUpdatePayload): Promise<ApiResponse<boolean>> {
return unwrapPost<boolean>('/server/manage/batchUpdate', payload as unknown as Record<string, unknown>)
}
export function saveNode(payload: AdminNodeSavePayload): Promise<ApiResponse<boolean>> {
return unwrapPost<boolean>('/server/manage/save', payload as unknown as Record<string, unknown>)
}
@@ -554,6 +562,29 @@ export function deleteUser(id: number): Promise<ApiResponse<boolean>> {
return unwrapPost<boolean>('/user/destroy', { id })
}
export function exportUsersCsv(payload: AdminUserBulkScopePayload): Promise<Blob> {
return adminClient
.post<Blob>('/user/dumpCSV', payload as unknown as Record<string, unknown>, {
responseType: 'blob',
})
.then((res) => res.data)
}
export function sendUsersMail(payload: AdminUserBulkMailPayload): Promise<ApiResponse<boolean>> {
return unwrapPost<boolean>('/user/sendMail', payload as unknown as Record<string, unknown>)
}
export function batchUpdateUserBan(payload: AdminUserBulkBanPayload): Promise<ApiResponse<boolean>> {
return unwrapPost<boolean>('/user/ban', payload as unknown as Record<string, unknown>)
}
export function resetUserTraffic(userId: number, reason?: string): Promise<ApiResponse<Record<string, unknown>>> {
return unwrapPost<Record<string, unknown>>('/traffic-reset/reset-user', {
user_id: userId,
reason,
})
}
export function fetchTickets(params: AdminTicketFetchParams): Promise<AdminPaginationResult<AdminTicketListItem>> {
return adminClient
.get<AdminPaginationResult<AdminTicketListItem>>('/ticket/fetch', { params })