refactor(api): 移除手动 softDelete 配置,改为基于 schema 自动检测
- 从 CrudServiceOptions 中移除 softDelete 属性 - CrudService 基于 Prisma schema 自动检测模型是否支持软删除 - 新增 supportsSoftDelete getter 用于判断软删除支持 - 更新 findDeleted/restore 方法使用自动检测 - PrismaService 底层已自动处理软删除逻辑 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,14 +14,8 @@ export const CRUD_OPTIONS_KEY = 'crud:options';
|
||||
* class UserService extends CrudService<User, CreateUserDto, UpdateUserDto> {}
|
||||
*
|
||||
* @example
|
||||
* // 启用软删除
|
||||
* @CrudOptions({ softDelete: true })
|
||||
* class UserService extends CrudService<User, CreateUserDto, UpdateUserDto> {}
|
||||
*
|
||||
* @example
|
||||
* // 自定义分页配置
|
||||
* @CrudOptions({
|
||||
* softDelete: true,
|
||||
* defaultPageSize: 10,
|
||||
* maxPageSize: 50,
|
||||
* defaultSortBy: 'name',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { PaginatedResponse } from '@seclusion/shared';
|
||||
|
||||
import { getCrudOptions } from './crud.decorator';
|
||||
@@ -6,6 +7,13 @@ import { CrudServiceOptions, FindAllParams, PrismaDelegate, SoftDeletable } from
|
||||
|
||||
import { PrismaService } from '@/prisma/prisma.service';
|
||||
|
||||
// 自动检测支持软删除的模型(有 deletedAt 字段的模型)
|
||||
const SOFT_DELETE_MODELS = new Set(
|
||||
Prisma.dmmf.datamodel.models
|
||||
.filter((model) => model.fields.some((field) => field.name === 'deletedAt'))
|
||||
.map((model) => model.name.toLowerCase())
|
||||
);
|
||||
|
||||
/**
|
||||
* CRUD 泛型基类
|
||||
*
|
||||
@@ -19,7 +27,6 @@ import { PrismaService } from '@/prisma/prisma.service';
|
||||
* import { User, Prisma } from '@prisma/client';
|
||||
*
|
||||
* @Injectable()
|
||||
* @CrudOptions({ softDelete: true })
|
||||
* export class UserService extends CrudService<
|
||||
* User,
|
||||
* Prisma.UserCreateInput,
|
||||
@@ -40,11 +47,13 @@ export abstract class CrudService<
|
||||
WhereUniqueInput = { id: string },
|
||||
> {
|
||||
protected readonly options: Required<CrudServiceOptions>;
|
||||
protected readonly prisma: PrismaService;
|
||||
|
||||
protected constructor(
|
||||
protected readonly prisma: PrismaService,
|
||||
prisma: PrismaService,
|
||||
protected readonly modelName: string
|
||||
) {
|
||||
this.prisma = prisma;
|
||||
// 从装饰器获取配置,如果没有则使用默认配置
|
||||
this.options = getCrudOptions(this);
|
||||
}
|
||||
@@ -216,18 +225,25 @@ export abstract class CrudService<
|
||||
return { message: this.getDeletedMessage(id) };
|
||||
}
|
||||
|
||||
// ============ 软删除相关方法(仅当 softDelete: true 时可用)============
|
||||
// ============ 软删除相关方法(仅当模型有 deletedAt 字段时可用)============
|
||||
|
||||
/**
|
||||
* 判断当前模型是否支持软删除
|
||||
*/
|
||||
protected get supportsSoftDelete(): boolean {
|
||||
return SOFT_DELETE_MODELS.has(this.modelName.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已删除的记录
|
||||
* 仅当 softDelete: true 时有效
|
||||
* 仅当模型有 deletedAt 字段时有效
|
||||
* pageSize <= 0 时返回所有数据(不分页)
|
||||
*/
|
||||
async findDeleted(
|
||||
params: FindAllParams<WhereInput> = {}
|
||||
): Promise<PaginatedResponse<Entity & SoftDeletable>> {
|
||||
if (!this.options.softDelete) {
|
||||
throw new Error('此服务未启用软删除功能');
|
||||
if (!this.supportsSoftDelete) {
|
||||
throw new Error('此模型不支持软删除功能');
|
||||
}
|
||||
|
||||
const {
|
||||
@@ -288,12 +304,12 @@ export abstract class CrudService<
|
||||
|
||||
/**
|
||||
* 恢复已删除的记录
|
||||
* 仅当 softDelete: true 时有效
|
||||
* 仅当模型有 deletedAt 字段时有效
|
||||
* @throws NotFoundException 当已删除的记录不存在时
|
||||
*/
|
||||
async restore(id: string): Promise<Entity> {
|
||||
if (!this.options.softDelete) {
|
||||
throw new Error('此服务未启用软删除功能');
|
||||
if (!this.supportsSoftDelete) {
|
||||
throw new Error('此模型不支持软删除功能');
|
||||
}
|
||||
|
||||
// 查询已删除的记录
|
||||
|
||||
@@ -4,8 +4,6 @@ import { PaginationParams } from '@seclusion/shared';
|
||||
* CRUD 服务配置选项
|
||||
*/
|
||||
export interface CrudServiceOptions {
|
||||
/** 是否启用软删除(默认 false) */
|
||||
softDelete?: boolean;
|
||||
/** 默认分页大小 */
|
||||
defaultPageSize?: number;
|
||||
/** 最大分页大小 */
|
||||
@@ -22,7 +20,6 @@ export interface CrudServiceOptions {
|
||||
* 默认配置
|
||||
*/
|
||||
export const DEFAULT_CRUD_OPTIONS: Required<CrudServiceOptions> = {
|
||||
softDelete: false,
|
||||
defaultPageSize: 20,
|
||||
maxPageSize: 100,
|
||||
defaultSortBy: 'createdAt',
|
||||
|
||||
Reference in New Issue
Block a user