origin/apps/server/src/models/sys-logs/systemLog.service.ts

134 lines
4.4 KiB
TypeScript

import { Injectable } from "@nestjs/common";
import { BaseService } from "../base/base.service";
import { db, ObjectType, Prisma } from "@nice/common";
import EventBus, { CrudOperation } from "@server/utils/event-bus";
@Injectable()
export class SystemLogService extends BaseService<Prisma.SystemLogDelegate> {
protected readonly prismaClient: any;
constructor() {
super(db, ObjectType.SYSTEM_LOG, false);
this.prismaClient = db;
}
async create(args: Prisma.SystemLogCreateArgs) {
// 确保消息字段有值
if (args.data && typeof args.data === 'object') {
const { level, module, action, targetName } = args.data as any;
const timestamp = new Date().toLocaleString();
const messagePrefix = level === 'error' ? '错误' : '';
// 添加默认消息格式 - 确保 message 字段存在
if (!args.data.message) {
args.data.message = `[${timestamp}] ${messagePrefix}${module || ''} ${action || ''}: ${targetName || ''}`;
}
}
const result = await super.create(args);
this.emitDataChanged(CrudOperation.CREATED, result);
return result;
}
async findMany(args: Prisma.SystemLogFindManyArgs): Promise<Prisma.SystemLogGetPayload<{}>[]> {
return super.findMany(args); // 放弃分页结构
}
async findManyWithPagination({ page = 1, pageSize = 20, where = {}, ...rest }: any) {
const skip = (page - 1) * pageSize;
try {
const [items, total] = await Promise.all([
this.prismaClient.systemLog.findMany({
where,
skip,
take: pageSize,
orderBy: { timestamp: 'desc' },
...rest
}),
this.prismaClient.systemLog.count({ where })
]);
return {
items,
total,
page,
pageSize,
totalPages: Math.ceil(total / pageSize)
};
} catch (error) {
console.error('Error in findManyWithPagination:', error);
throw error;
}
}
async logStaffAction(
action: string,
operatorId: string | null,
ipAddress: string | null,
targetId: string,
targetName: string,
beforeData: any = null,
afterData: any = null,
status: 'success' | 'failure' = 'success',
errorMessage?: string
) {
// 生成变更详情
const details = beforeData && afterData
? this.generateChangeDetails(beforeData, afterData)
: {};
const timestamp = new Date().toLocaleString();
const messagePrefix = status === 'success' ? '' : '错误: ';
const message = `[${timestamp}] ${messagePrefix}用户 ${targetName}${action}`;
return this.create({
data: {
level: status === 'success' ? 'info' : 'error',
module: '人员管理',
action,
operatorId,
ipAddress,
targetId,
targetType: 'staff',
targetName,
message,
details,
beforeData,
afterData,
status,
errorMessage,
}
});
}
/**
* 生成变更详情
*/
private generateChangeDetails(before: any, after: any) {
if (!before || !after) return {};
const changes: Record<string, { oldValue: any; newValue: any }> = {};
Object.keys(after).forEach(key => {
// 忽略一些不需要记录的字段
if (['password', 'createdAt', 'updatedAt', 'deletedAt'].includes(key)) return;
if (JSON.stringify(before[key]) !== JSON.stringify(after[key])) {
changes[key] = {
oldValue: before[key],
newValue: after[key]
};
}
});
return { changes };
}
private emitDataChanged(operation: CrudOperation, data: any) {
EventBus.emit('dataChanged', {
type: ObjectType.SYSTEM_LOG,
operation,
data,
});
}
}