diff --git a/apps/server/src/models/sys-logs/systemLog.router.ts b/apps/server/src/models/sys-logs/systemLog.router.ts index 218d5ec..3eda41d 100644 --- a/apps/server/src/models/sys-logs/systemLog.router.ts +++ b/apps/server/src/models/sys-logs/systemLog.router.ts @@ -193,91 +193,5 @@ export class SystemLogRouter { } }); }), - - // 高级搜索日志 - searchLogs: this.trpc.procedure - .input(z.object({ - page: z.number().default(1), - pageSize: z.number().default(20), - level: z.enum(['info', 'warning', 'error', 'debug']).optional(), - module: z.string().optional(), - action: z.string().optional(), - operatorId: z.string().optional(), - targetId: z.string().optional(), - targetType: z.string().optional(), - status: z.enum(['success', 'failure']).optional(), - startTime: z.string().optional(), - endTime: z.string().optional(), - keyword: z.string().optional(), - departmentId: z.string().optional(), - })) - .query(async ({ input }) => { - // 构建查询条件 - const where: Prisma.SystemLogWhereInput = {}; - - if (input.level) where.level = input.level; - if (input.module) where.module = input.module; - if (input.action) where.action = input.action; - if (input.operatorId) where.operatorId = input.operatorId; - if (input.targetId) where.targetId = input.targetId; - if (input.targetType) where.targetType = input.targetType; - if (input.status) where.status = input.status; - if (input.departmentId) where.departmentId = input.departmentId; - - // 时间范围查询 - if (input.startTime || input.endTime) { - where.timestamp = {}; - if (input.startTime) where.timestamp.gte = new Date(input.startTime); - if (input.endTime) where.timestamp.lte = new Date(input.endTime); - } - - // 关键词搜索 - if (input.keyword) { - where.OR = [ - { targetName: { contains: input.keyword } }, - { action: { contains: input.keyword } }, - { module: { contains: input.keyword } }, - { errorMessage: { contains: input.keyword } }, - ]; - } - - // 使用select代替include - return this.systemLogService.findManyWithPagination({ - page: input.page, - pageSize: input.pageSize, - where, - select: { - id: true, - level: true, - module: true, - action: true, - timestamp: true, - operatorId: true, - ipAddress: true, - targetId: true, - targetType: true, - targetName: true, - details: true, - beforeData: true, - afterData: true, - status: true, - errorMessage: true, - departmentId: true, - operator: { - select: { - id: true, - username: true, - showname: true, - } - }, - department: { - select: { - id: true, - name: true, - } - } - } - }); - }), }) } \ No newline at end of file diff --git a/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx b/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx index 0bd1667..9b8fe79 100644 --- a/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx +++ b/apps/web/src/app/main/staffinfo_write/staffinfo_write.page.tsx @@ -47,7 +47,7 @@ const StaffInfoWrite = () => { // 按分组组织字段 const fieldGroups = useMemo(() => { if (!fields) return {}; - return fields.reduce((groups: any, field: any) => { + return (fields as any[]).reduce((groups: any, field: any) => { const group = field.group || '其他信息'; if (!groups[group]) { groups[group] = []; @@ -157,28 +157,38 @@ const StaffInfoWrite = () => { } }; - const onFinish = async (values: any) => { + const onFinish = async (e, values: any) => { + // values.preventDefault(); + e.preventDefault() + console.log(values) try { setLoading(true); // 创建基础员工记录 + if (!values.username) { + message.error("用户名不能为空"); + return; + } + + // 创建基础员工记录 + console.log('准备创建用户,数据:', { username: values.username }); const staff = await create.mutateAsync({ data: { username: values.username, password: '123456' } }); - + console.log('创建员工记录:', staff); // 过滤有效字段并转换值 const validEntries = Object.entries(values) - .filter(([_, value]) => value !== undefined && value !== null && value !== '') + .filter(([key, value]) => key !== 'username' && value !== undefined && value !== null && value !== '') .map(([fieldName, value]) => { - const field = fields?.find((f: any) => f.name === fieldName); + const field = fields && Array.isArray(fields) ? fields.find((f: any) => f.name === fieldName) : undefined; let processedValue = value; // 处理特殊字段类型 - if (field?.type === 'date' && value instanceof moment) { - processedValue = value.format('YYYY-MM-DD'); + if (field?.type === 'date') { + processedValue = value.toString(); } else if (field?.type === 'cascader' && Array.isArray(value)) { processedValue = value.join('/'); } @@ -197,8 +207,10 @@ const StaffInfoWrite = () => { }) ) ); + console.log('自定义字段提交成功',staff.username); message.success("信息提交成功"); + form.resetFields(); } catch (error) { console.error('提交出错:', error); message.error("提交失败,请重试"); @@ -218,7 +230,6 @@ const StaffInfoWrite = () => {
{ if ('hasTrain' in changedValues) { setHasTrain(!!changedValues.hasTrain); @@ -268,6 +279,7 @@ const StaffInfoWrite = () => { - - - - -
- - - - `共 ${total} 条日志` - }} - loading={isLoading} - onChange={handleTableChange} - /> - - - ); + + // 处理表单查询 + const handleSearch = (values: any) => { + const { timeRange, keyword, level, module, status, ...rest } = values; + + // 构建 where 条件 + const where: any = {}; + + if (level) where.level = level; + if (module) where.module = { contains: module }; + if (status) where.status = status; + + // 处理时间范围 + if (timeRange && timeRange.length === 2) { + where.timestamp = { + gte: timeRange[0].startOf('day').toISOString(), + lte: timeRange[1].endOf('day').toISOString() + }; + } + + // 处理关键词搜索 + if (keyword) { + where.OR = [ + { module: { contains: keyword } }, + { action: { contains: keyword } }, + { targetName: { contains: keyword } } + ]; + } + + // 处理其他条件 + if (rest.operatorId) where.operatorId = rest.operatorId; + if (rest.targetId) where.targetId = rest.targetId; + + console.log('查询参数:', { where }); + setQueryParams({ + ...queryParams, + page: 1, // 重置到第一页 + where + }); + }; + + // 格式化时间显示 + const formatTime = (timeStr: string) => { + return dayjs(timeStr).format('YYYY-MM-DD HH:mm:ss'); + }; + + // 表格列定义 + const columns = [ + { + title: '操作时间', + dataIndex: 'timestamp', + key: 'timestamp', + render: (text: string) => formatTime(text), + sorter: true + }, + { + title: '级别', + dataIndex: 'level', + key: 'level', + render: (text: string) => ( + + {text.toUpperCase()} + + ), + filters: [ + { text: '信息', value: 'info' }, + { text: '警告', value: 'warning' }, + { text: '错误', value: 'error' }, + { text: '调试', value: 'debug' } + ] + }, + { + title: '模块', + dataIndex: 'module', + key: 'module', + }, + { + title: '操作', + dataIndex: 'action', + key: 'action', + }, + { + title: '操作人', + key: 'operator', + render: (_, record: ILog) => ( + record.operator ? record.operator.showname || record.operator.username : '-' + ) + }, + { + title: 'IP地址', + dataIndex: 'ipAddress', + key: 'ipAddress', + render: (text: string) => text || '-' + }, + { + title: '操作对象', + dataIndex: 'targetName', + key: 'targetName', + render: (text: string) => text || '-' + }, + { + title: '状态', + dataIndex: 'status', + key: 'status', + render: (text: string) => ( + + {text === 'success' ? '成功' : '失败'} + + ), + filters: [ + { text: '成功', value: 'success' }, + { text: '失败', value: 'failure' } + ] + }, + { + title: '操作', + key: 'operation', + render: (_, record: ILog) => ( + + ) + } + ]; + + // 显示日志详情的函数 + const showLogDetail = (record: ILog) => { + Modal.info({ + title: '日志详情', + width: 800, + content: ( +
+
+
ID: {record.id}
+
时间: {formatTime(record.timestamp)}
+
模块: {record.module}
+
操作: {record.action}
+
操作人: {record.operator ? (record.operator.showname || record.operator.username) : '-'}
+
IP地址: {record.ipAddress || '-'}
+
操作对象: {record.targetName || '-'}
+
对象类型: {record.targetType || '-'}
+
状态: {record.status === 'success' ? '成功' : '失败'}
+ {record.errorMessage &&
错误信息: {record.errorMessage}
} +
+ + {(record.beforeData || record.afterData) && ( +
+

数据变更

+
+ {record.beforeData && ( +
+
变更前
+
+                                            {JSON.stringify(record.beforeData, null, 2)}
+                                        
+
+ )} + {record.afterData && ( +
+
变更后
+
+                                            {JSON.stringify(record.afterData, null, 2)}
+                                        
+
+ )} +
+
+ )} + + {record.details && ( +
+

详细信息

+
+                                {JSON.stringify(record.details, null, 2)}
+                            
+
+ )} +
+ ), + onOk() {} + }); + }; + + return ( +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + +
`共 ${total} 条日志` + }} + loading={isLoading} + onChange={handleTableChange} + scroll={{ x: 'max-content' }} + /> + + + ); }; export default SystemLogPage; \ No newline at end of file diff --git a/packages/client/src/api/hooks/useStaff.ts b/packages/client/src/api/hooks/useStaff.ts index 4c70184..7729d98 100755 --- a/packages/client/src/api/hooks/useStaff.ts +++ b/packages/client/src/api/hooks/useStaff.ts @@ -1,3 +1,4 @@ + //@ts-nocheck import { getQueryKey } from "@trpc/react-query"; import { api } from "../trpc"; // Adjust path as necessary import { useQueryClient } from "@tanstack/react-query"; @@ -5,6 +6,7 @@ import { ObjectType, Staff } from "@nice/common"; import { findQueryData } from "../utils"; import { CrudOperation, emitDataChange } from "../../event"; + export interface CustomField { name: string; label?: string;