Feat: admin audit (#5068)

* add admin audit (#5041)

* Test audit (#5058)

* feat: operation index

* fix: delete update vector

* perf: Clear invalid data

* perf: index

* perf: cleare invalid data

* index

* perf: audit event

* fix: schema enum

* add audit.svg (#5060)

Co-authored-by: dreamer6680 <146868355@qq.com>

* update package

* perf: audit

* perf: code move

* eslint

* doc

---------

Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com>
Co-authored-by: dreamer6680 <1468683855@qq.com>
Co-authored-by: dreamer6680 <146868355@qq.com>
This commit is contained in:
Archer
2025-06-19 10:35:21 +08:00
committed by GitHub
parent 36fafd2149
commit d44befeff0
53 changed files with 580 additions and 266 deletions
@@ -15,8 +15,8 @@ import { useTranslation } from 'next-i18next';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
import { getOperationLogs } from '@/web/support/user/team/operantionLog/api';
import { operationLogMap } from '@fastgpt/service/support/operationLog/constants';
import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
import { auditLogMap } from '@fastgpt/web/support/user/audit/constants';
import { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
import UserBox from '@fastgpt/web/components/common/UserBox';
import MultipleSelect, {
@@ -27,11 +27,11 @@ import { getTeamMembers } from '@/web/support/user/team/api';
import { specialProcessors } from './processors';
import { defaultMetadataProcessor } from './processors/commonProcessor';
function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
function AuditLog({ Tabs }: { Tabs: React.ReactNode }) {
const { t } = useTranslation();
const [searchParams, setSearchParams] = useState<{
tmbIds?: string[];
events?: OperationLogEventEnum[];
events?: AuditEventEnum[];
}>({});
const { data: members, ScrollData } = useScrollPagination(getTeamMembers, {});
@@ -51,8 +51,8 @@ function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
const eventOptions = useMemo(
() =>
Object.values(OperationLogEventEnum).map((event) => ({
label: t(operationLogMap[event].typeLabel),
Object.values(AuditEventEnum).map((event) => ({
label: t(auditLogMap[event].typeLabel),
value: event
})),
[t]
@@ -61,14 +61,14 @@ function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
const processMetadataByEvent = useCallback(
(event: string, metadata: any) => {
const defaultFormat = defaultMetadataProcessor(metadata, t);
const specialFormat = specialProcessors[event as OperationLogEventEnum]?.(defaultFormat, t);
const specialFormat = specialProcessors[event as AuditEventEnum]?.(defaultFormat, t);
return specialFormat || defaultFormat;
},
[t]
);
const {
data: operationLogs = [],
data: auditLog = [],
isLoading: loadingLogs,
ScrollData: LogScrollData
} = useScrollPagination(getOperationLogs, {
@@ -92,7 +92,7 @@ function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
setValue: setSelectedEvents,
isSelectAll: isSelectAllEvent,
setIsSelectAll: setIsSelectAllEvent
} = useMultipleSelect<OperationLogEventEnum>(
} = useMultipleSelect<AuditEventEnum>(
eventOptions.map((item) => item.value),
true
);
@@ -166,8 +166,8 @@ function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
</Tr>
</Thead>
<Tbody>
{operationLogs?.map((log) => {
const i18nData = operationLogMap[log.event];
{auditLog?.map((log) => {
const i18nData = auditLogMap[log.event];
const metadata = processMetadataByEvent(log.event, { ...log.metadata });
return i18nData ? (
@@ -195,4 +195,4 @@ function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
);
}
export default OperationLogTable;
export default AuditLog;
@@ -1,10 +1,10 @@
import type { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
import type { AuditEventEnum } from '@fastgpt/global/support/user/audit/constants';
import { createTeamProcessors } from './teamProcessors';
import { createAppProcessors } from './appProcessors';
import { createDatasetProcessors } from './datasetProcessors';
export type MetadataProcessor = (metadata: any, t: any) => any;
export const specialProcessors: Partial<Record<OperationLogEventEnum, MetadataProcessor>> = {
export const specialProcessors: Partial<Record<AuditEventEnum, MetadataProcessor>> = {
...createTeamProcessors,
...createAppProcessors,
...createDatasetProcessors