- orgs: 列表按可见部门过滤 - audit-logs/login-logs: 按操作人所属部门过滤(self 按 userId/username) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
||
import { InjectPinoLogger, PinoLogger } from 'nestjs-pino';
|
||
import { BaseCrudService } from '../common/base-crud.service.js';
|
||
import { PrismaService } from '../prisma/prisma.service.js';
|
||
import { getRequestContext } from '../common/context/request-context.js';
|
||
import { ListLoginLogQuery } from './dto.js';
|
||
|
||
export interface LoginLogEntry {
|
||
tenantCode: string;
|
||
username?: string | null;
|
||
ip?: string | null;
|
||
userAgent?: string | null;
|
||
status: string;
|
||
message?: string | null;
|
||
}
|
||
|
||
@Injectable()
|
||
export class LoginLogsService extends BaseCrudService {
|
||
constructor(
|
||
prisma: PrismaService,
|
||
@InjectPinoLogger(LoginLogsService.name) private readonly logger: PinoLogger,
|
||
) {
|
||
super(prisma, 'loginLog');
|
||
}
|
||
|
||
/** 写入一条登录日志;失败仅告警,不抛出。 */
|
||
async record(data: LoginLogEntry): Promise<void> {
|
||
try {
|
||
await this.db().create({ data });
|
||
} catch (err) {
|
||
this.logger.warn({ err }, '登录日志写入失败');
|
||
}
|
||
}
|
||
|
||
async listLoginLogs(q: ListLoginLogQuery) {
|
||
const ctx = getRequestContext();
|
||
const where: Record<string, unknown> = {};
|
||
if (q.username) where.username = { contains: q.username };
|
||
if (q.status) where.status = q.status;
|
||
// 数据权限:仅本人按 username;否则按可见部门内的用户
|
||
if (ctx && ctx.dataScope !== 'all') {
|
||
if (ctx.dataScope === 'self') {
|
||
where.username = ctx.username;
|
||
} else {
|
||
const usernames = ctx.orgCodes.length
|
||
? (
|
||
await this.prisma.client.user.findMany({
|
||
where: { tenantCode: ctx.tenantCode, orgCode: { in: ctx.orgCodes }, deletedAt: null },
|
||
select: { username: true },
|
||
})
|
||
).map((u) => u.username)
|
||
: [];
|
||
where.username = { in: usernames };
|
||
}
|
||
}
|
||
return this.paginate(q.page, q.pageSize, where);
|
||
}
|
||
}
|