197 lines
7.8 KiB
TypeScript
197 lines
7.8 KiB
TypeScript
|
import { Injectable } from "@nestjs/common";
|
||
|
import { TrpcService } from "@server/trpc/trpc.service";
|
||
|
import { SystemLogService } from "./systemLog.service";
|
||
|
import { z, ZodType } from "zod";
|
||
|
import { Prisma } from "@nice/common";
|
||
|
|
||
|
// 定义Zod类型Schema
|
||
|
const SystemLogCreateArgsSchema: ZodType<Prisma.SystemLogCreateArgs> = z.any();
|
||
|
const SystemLogFindManyArgsSchema: ZodType<Prisma.SystemLogFindManyArgs> = z.any();
|
||
|
const SystemLogFindUniqueArgsSchema: ZodType<Prisma.SystemLogFindUniqueArgs> = z.any();
|
||
|
const SystemLogWhereInputSchema: ZodType<Prisma.SystemLogWhereInput> = z.any();
|
||
|
const SystemLogSelectSchema: ZodType<Prisma.SystemLogSelect> = z.any();
|
||
|
|
||
|
@Injectable()
|
||
|
export class SystemLogRouter {
|
||
|
constructor(
|
||
|
private readonly trpc: TrpcService,
|
||
|
private readonly systemLogService: SystemLogService,
|
||
|
) { }
|
||
|
|
||
|
router = this.trpc.router({
|
||
|
// 创建日志
|
||
|
create: this.trpc.procedure
|
||
|
.input(z.object({
|
||
|
level: z.enum(['info', 'warning', 'error', 'debug']).default('info'),
|
||
|
module: z.string(),
|
||
|
action: z.string(),
|
||
|
operatorId: z.string().optional(),
|
||
|
ipAddress: z.string().optional(),
|
||
|
targetId: z.string().optional(),
|
||
|
targetType: z.string().optional(),
|
||
|
targetName: z.string().optional(),
|
||
|
details: z.any().optional(),
|
||
|
beforeData: z.any().optional(),
|
||
|
afterData: z.any().optional(),
|
||
|
status: z.enum(['success', 'failure']).default('success'),
|
||
|
errorMessage: z.string().optional(),
|
||
|
departmentId: z.string().optional(),
|
||
|
}))
|
||
|
.mutation(async ({ input, ctx }) => {
|
||
|
const ctxIpAddress = ctx.ip;
|
||
|
const operatorId = ctx.staff?.id;
|
||
|
|
||
|
return this.systemLogService.create({
|
||
|
data: {
|
||
|
level: input.level,
|
||
|
module: input.module,
|
||
|
action: input.action,
|
||
|
operatorId: input.operatorId || operatorId,
|
||
|
ipAddress: input.ipAddress || ctxIpAddress,
|
||
|
targetId: input.targetId,
|
||
|
targetType: input.targetType,
|
||
|
targetName: input.targetName,
|
||
|
details: input.details,
|
||
|
beforeData: input.beforeData,
|
||
|
afterData: input.afterData,
|
||
|
status: input.status,
|
||
|
errorMessage: input.errorMessage,
|
||
|
departmentId: input.departmentId,
|
||
|
}
|
||
|
});
|
||
|
}),
|
||
|
|
||
|
// 查询日志列表
|
||
|
findMany: this.trpc.procedure
|
||
|
.input(SystemLogFindManyArgsSchema)
|
||
|
.query(async ({ input }) => {
|
||
|
return this.systemLogService.findMany(input);
|
||
|
}),
|
||
|
|
||
|
// 查询日志列表(带分页) - 保留原名
|
||
|
getLogs: this.trpc.procedure
|
||
|
.input(z.object({
|
||
|
page: z.number().default(1),
|
||
|
pageSize: z.number().default(20),
|
||
|
where: SystemLogWhereInputSchema.optional(),
|
||
|
select: SystemLogSelectSchema.optional(),
|
||
|
}))
|
||
|
.query(async ({ input }) => {
|
||
|
try {
|
||
|
const { page, pageSize, where = {}, select } = input;
|
||
|
|
||
|
return await this.systemLogService.findManyWithPagination({
|
||
|
page,
|
||
|
pageSize,
|
||
|
where,
|
||
|
...(select ? { select } : {})
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.error('Error in getLogs:', error);
|
||
|
// 返回空结果,避免崩溃
|
||
|
return {
|
||
|
items: [],
|
||
|
total: 0,
|
||
|
page: input.page,
|
||
|
pageSize: input.pageSize,
|
||
|
totalPages: 0
|
||
|
};
|
||
|
}
|
||
|
}),
|
||
|
|
||
|
// 查询日志列表(带分页) - 新名称
|
||
|
findManyWithPagination: this.trpc.procedure
|
||
|
.input(z.object({
|
||
|
page: z.number().default(1),
|
||
|
pageSize: z.number().default(20),
|
||
|
where: SystemLogWhereInputSchema.optional(),
|
||
|
select: SystemLogSelectSchema.optional(),
|
||
|
}))
|
||
|
.query(async ({ input }) => {
|
||
|
try {
|
||
|
const { page, pageSize, where = {}, select } = input;
|
||
|
|
||
|
return await this.systemLogService.findManyWithPagination({
|
||
|
page,
|
||
|
pageSize,
|
||
|
where,
|
||
|
...(select ? { select } : {})
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.error('Error in findManyWithPagination:', error);
|
||
|
// 返回空结果,避免崩溃
|
||
|
return {
|
||
|
items: [],
|
||
|
total: 0,
|
||
|
page: input.page,
|
||
|
pageSize: input.pageSize,
|
||
|
totalPages: 0
|
||
|
};
|
||
|
}
|
||
|
}),
|
||
|
|
||
|
// 获取单个日志详情
|
||
|
findUnique: this.trpc.procedure
|
||
|
.input(SystemLogFindUniqueArgsSchema)
|
||
|
.query(async ({ input }) => {
|
||
|
return this.systemLogService.findUnique(input);
|
||
|
}),
|
||
|
|
||
|
// 通过ID获取日志详情(简化版)
|
||
|
findById: this.trpc.procedure
|
||
|
.input(z.string())
|
||
|
.query(async ({ input }) => {
|
||
|
return this.systemLogService.findUnique({
|
||
|
where: { id: input },
|
||
|
include: {
|
||
|
operator: {
|
||
|
select: {
|
||
|
id: true,
|
||
|
username: true,
|
||
|
showname: true,
|
||
|
}
|
||
|
},
|
||
|
department: {
|
||
|
select: {
|
||
|
id: true,
|
||
|
name: true,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}),
|
||
|
|
||
|
// 记录人员操作日志的便捷方法
|
||
|
logStaffAction: this.trpc.protectProcedure
|
||
|
.input(z.object({
|
||
|
action: z.string(),
|
||
|
targetId: z.string(),
|
||
|
targetName: z.string(),
|
||
|
beforeData: z.any().optional(),
|
||
|
afterData: z.any().optional(),
|
||
|
status: z.enum(['success', 'failure']).default('success'),
|
||
|
errorMessage: z.string().optional(),
|
||
|
}))
|
||
|
.mutation(async ({ input, ctx }) => {
|
||
|
const ipAddress = ctx.ip;
|
||
|
const operatorId = ctx.staff?.id;
|
||
|
|
||
|
return this.systemLogService.create({
|
||
|
data: {
|
||
|
level: 'info',
|
||
|
module: 'staff',
|
||
|
action: input.action,
|
||
|
operatorId: operatorId,
|
||
|
ipAddress: ipAddress,
|
||
|
targetId: input.targetId,
|
||
|
targetType: 'staff',
|
||
|
targetName: input.targetName,
|
||
|
beforeData: input.beforeData,
|
||
|
afterData: input.afterData,
|
||
|
status: input.status,
|
||
|
errorMessage: input.errorMessage,
|
||
|
}
|
||
|
});
|
||
|
}),
|
||
|
})
|
||
|
}
|