ec-nest/src/prisma/prisma.service.ts
liuyun 766d8c7218 feat(c2): plan/plan_item/order/elder_svc 数据模型
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 22:08:40 +08:00

51 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { getRequestContext } from '../common/context/request-context.js';
/** 不带 tenantCode 的模型(租户表自身)。 */
const TENANT_FREE = new Set(['Tenant', 'Agency', 'SvcNational', 'SvcLocal', 'SvcMapping', 'LocConfig']);
/** 软删模型:读操作统一注入 deletedAt IS NULL。 */
const SOFT_DELETE = new Set(['User', 'Role', 'Resource', 'Org', 'DictType', 'DictItem', 'Config', 'Notice', 'Staff', 'SvcOrg', 'Elder', 'Plan', 'Order', 'ElderSvc']);
const READ_OPS = new Set(['findMany', 'findFirst', 'findUnique', 'count', 'aggregate', 'groupBy']);
/** 没有 where 子句的操作(create 的租户由 service 在 data 里显式写入)。 */
const NO_WHERE_OPS = new Set(['create', 'createMany']);
/**
* Prisma 客户端封装:统一注入多租户过滤(tenantCode)与软删过滤(deletedAt)。
* 通过 `this.prisma.client` 访问扩展后的客户端。
*/
@Injectable()
export class PrismaService implements OnModuleInit, OnModuleDestroy {
readonly client: PrismaClient;
/** 未扩展的裸客户端(无租户/软删注入),供 seed/租户模板等跨租户初始化使用。 */
readonly raw: PrismaClient;
constructor() {
this.raw = new PrismaClient();
this.client = this.raw.$extends({
query: {
$allModels: {
async $allOperations({ model, operation, args, query }: any) {
const ctx = getRequestContext();
if (ctx && !TENANT_FREE.has(model) && !NO_WHERE_OPS.has(operation)) {
args.where = { ...(args.where ?? {}), tenantCode: ctx.tenantCode };
}
if (SOFT_DELETE.has(model) && READ_OPS.has(operation)) {
args.where = { ...(args.where ?? {}), deletedAt: null };
}
return query(args);
},
},
},
}) as unknown as PrismaClient;
}
async onModuleInit(): Promise<void> {
await this.client.$connect();
}
async onModuleDestroy(): Promise<void> {
await this.client.$disconnect();
}
}