Files
Edu/apps/admin-portal/src/hooks/use-audit-logs.ts
SpecialX b3511910d1 feat(admin-portal): 完整实现 admin-portal 管理端微前端
包含 src 全部实现、Dockerfile、配置文件等
2026-07-10 19:09:12 +08:00

90 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 审计日志 Hooks
*
* contract §2.4auditLogs
* 仲裁 ARB-005经 teacher-bff GraphQL 消费(不直连 Kafka
*/
import { useCallback, useState } from "react";
import { useGraphQuery } from "./use-graphql";
import { AUDIT_LOGS_QUERY } from "@/lib/graphql-client";
import type {
AuditLogViewModel,
PaginatedResult,
ListFilter,
} from "@/types/view-models";
interface AuditLogsResponse {
auditLogs: PaginatedResult<AuditLogViewModel>;
}
interface AuditLogFilter extends Partial<ListFilter> {
action?: string;
actorUserId?: string;
startDate?: number;
endDate?: number;
}
export function useAuditLogs(filter: AuditLogFilter) {
const result = useGraphQuery<AuditLogsResponse>(AUDIT_LOGS_QUERY, { filter });
return {
...result,
data: result.data?.auditLogs ?? null,
};
}
export function useAuditLogFilter(initial?: Partial<AuditLogFilter>) {
const [filter, setFilter] = useState<AuditLogFilter>({
page: 1,
pageSize: 20,
...initial,
});
const setPage = useCallback(
(page: number) => setFilter((f) => ({ ...f, page })),
[],
);
const setSearch = useCallback(
(search: string) => setFilter((f) => ({ ...f, search, page: 1 })),
[],
);
const setAction = useCallback(
(action: string) =>
setFilter((f) => ({ ...f, action: action || undefined, page: 1 })),
[],
);
return { filter, setFilter, setPage, setSearch, setAction };
}
/** 审计日志导出 CSV */
export function exportAuditLogsCsv(logs: AuditLogViewModel[]): void {
const headers = [
"时间",
"操作人",
"操作",
"资源类型",
"资源ID",
"IP",
"追踪ID",
];
const rows = logs.map((l) => [
new Date(l.occurredAt).toLocaleString("zh-CN"),
l.actorName,
l.action,
l.resourceType,
l.resourceId,
l.ip,
l.traceId ?? "",
]);
const csv = [headers, ...rows]
.map((row) =>
row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(","),
)
.join("\n");
const blob = new Blob([`\uFEFF${csv}`], { type: "text/csv;charset=utf-8;" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = `audit-logs-${new Date().toISOString().slice(0, 10)}.csv`;
link.click();
URL.revokeObjectURL(url);
}