108 lines
3.4 KiB
TypeScript
108 lines
3.4 KiB
TypeScript
import { unwrapApiResponse } from '@/utils/api-response'
|
|
import { mockFlags } from '@/utils/mock-flags'
|
|
import { request } from '@/utils/request'
|
|
import type { ApiResponse, PageResult } from '@/types/common'
|
|
|
|
import type {
|
|
AuditLogListResponse,
|
|
AuditLogQuery,
|
|
AuditLogRecord,
|
|
AuditLogResponseDto,
|
|
BackendCollection,
|
|
BackendPage,
|
|
} from './types'
|
|
|
|
const useMockData = mockFlags.audit
|
|
|
|
function formatDateTime(value: string) {
|
|
const date = new Date(value)
|
|
|
|
if (Number.isNaN(date.getTime())) {
|
|
return value
|
|
.replace('T', ' ')
|
|
.replace(/\.\d+Z$/, '')
|
|
.replace(/Z$/, '')
|
|
}
|
|
|
|
const pad = (part: number) => String(part).padStart(2, '0')
|
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(
|
|
date.getHours(),
|
|
)}:${pad(date.getMinutes())}`
|
|
}
|
|
|
|
function mapAuditLog(dto: AuditLogResponseDto): AuditLogRecord {
|
|
return {
|
|
id: dto.id,
|
|
action: dto.action,
|
|
resourceType: dto.resourceType,
|
|
resourceId: dto.resourceId ?? '',
|
|
operatorId: dto.operatorId ?? '',
|
|
operatorName: dto.operatorName ?? (dto.operatorId ? '未知' : '系统'),
|
|
operatorRoles: dto.operatorRoles ?? '—',
|
|
clientIp: dto.clientIp ?? '—',
|
|
userAgent: dto.userAgent ?? '—',
|
|
detailsJson: dto.detailsJson ?? '',
|
|
createdAt: formatDateTime(dto.createdAt),
|
|
}
|
|
}
|
|
|
|
function normalizePage<T>(
|
|
data: BackendPage<T> | T[],
|
|
fallbackPage: number,
|
|
fallbackPageSize: number,
|
|
): PageResult<T> {
|
|
const records = Array.isArray(data) ? data : (data.records ?? data.items ?? data.content ?? [])
|
|
|
|
return {
|
|
records,
|
|
total: Array.isArray(data) ? records.length : (data.total ?? records.length),
|
|
page: Array.isArray(data) ? fallbackPage : (data.page ?? fallbackPage),
|
|
pageSize: Array.isArray(data) ? fallbackPageSize : (data.size ?? fallbackPageSize),
|
|
}
|
|
}
|
|
|
|
export function getAuditLogs(query: AuditLogQuery): Promise<AuditLogListResponse> {
|
|
if (useMockData) {
|
|
return Promise.resolve({ records: [], total: 0, page: query.page, pageSize: query.pageSize })
|
|
}
|
|
|
|
const params: Record<string, string | number> = {
|
|
page: Math.max(query.page, 1),
|
|
size: Math.min(Math.max(query.pageSize, 1), 200),
|
|
}
|
|
|
|
if (query.keyword?.trim()) {
|
|
params.keyword = query.keyword.trim()
|
|
}
|
|
|
|
if (query.createdFrom) params.createdFrom = query.createdFrom
|
|
if (query.createdTo) params.createdTo = query.createdTo
|
|
if (query.operator?.trim()) params.operator = query.operator.trim()
|
|
if (query.module) params.module = query.module
|
|
|
|
return request
|
|
.get<ApiResponse<BackendCollection<AuditLogResponseDto>>>('/v1/audit-logs', { params })
|
|
.then(unwrapApiResponse)
|
|
.then((data) => {
|
|
const page = normalizePage(data, query.page, query.pageSize)
|
|
return { ...page, records: page.records.map(mapAuditLog) }
|
|
})
|
|
}
|
|
|
|
export function exportAuditLogs(query: AuditLogQuery): Promise<Blob> {
|
|
const params: Record<string, string | number> = {
|
|
page: Math.max(query.page, 1),
|
|
size: Math.min(Math.max(query.pageSize, 1), 200),
|
|
}
|
|
if (query.keyword?.trim()) params.keyword = query.keyword.trim()
|
|
if (query.createdFrom) params.createdFrom = query.createdFrom
|
|
if (query.createdTo) params.createdTo = query.createdTo
|
|
if (query.operator?.trim()) params.operator = query.operator.trim()
|
|
if (query.module) params.module = query.module
|
|
|
|
return request.get<Blob>('/v1/audit-logs/export', {
|
|
params,
|
|
responseType: 'blob',
|
|
})
|
|
}
|