两个字段是否一致
在注册时,我们经常需要判断 密码 和 重复密码 两个是否一致,我们可以使用这个规则
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
export function IsConfirm(validationOptions?: ValidationOptions) {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'IsConfirm',
target: object.constructor,
propertyName,
constraints: [],
options: validationOptions,
validator: {
validate(value: string, args: ValidationArguments) {
return Boolean(value === args.object[`${args.property}_confirm`]);
},
},
});
};
}
是否在数据库中存在
在编辑时,我们需要一些字段的值必须在数据库中存在,我们可以使用这个规则
比如下方的使用示例: 更新用户时,我们需要该用户名必须存在
import { schema, SchemaName } from '@labs/shared';
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
import { eq } from 'drizzle-orm';
import { db } from '@/drizzle/db';
/**
* field is required in table
* @param table drizzle schema name
* @param validationOptions validation message
* @returns {boolean}
*/
export function IsExists(table: SchemaName, validationOptions?: ValidationOptions) {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'IsExists',
target: object.constructor,
propertyName,
constraints: [table],
options: validationOptions,
validator: {
async validate(value: string, args: ValidationArguments) {
if (!args.value)
return false;
const [result] = await db
.select()
.from(schema[table])
.where(eq(schema[table][propertyName], args.value));
return Boolean(result);
},
},
});
};
}
是否在数据库中不存在
在新增时,我们需要指定的字段在数据库中不能重复,我们可以使用这个规则
它在数据库中设置了
unique或者你希望它在数据库中是唯一的
import { schema, SchemaName } from '@labs/shared';
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
import { eq } from 'drizzle-orm';
import { db } from '@/drizzle/db';
/**
* field is required in table
* @param table drizzle schema name
* @param validationOptions validation message
* @returns {boolean}
*/
export function IsNotExists(table: SchemaName, validationOptions?: ValidationOptions) {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'IsNotExists',
target: object.constructor,
propertyName,
constraints: [table],
options: validationOptions,
validator: {
async validate(value: string, args: ValidationArguments) {
if (!args.value)
return false;
console.log(table, 'table');
const [result] = await db
.select()
.from(schema[table])
.where(eq(schema[table][propertyName], args.value));
return !result;
},
},
});
};
}
字段是否唯一
在编辑或者新增时,我们希望这个字段是唯一的。可以使用这个规则
import { schema, SchemaName } from '@labs/shared';
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
import { and, eq, ne } from 'drizzle-orm';
import { db } from '@/drizzle/db';
interface IsUniqueOptions extends ValidationOptions {
excludeField?: string // 编辑时排除当前记录的字段名,默认为 'id'
}
/**
* 检查字段值是否唯一
* @param table drizzle schema name
* @param validationOptions validation options (可选 excludeField 用于编辑场景)
* @returns {boolean}
* @example
* // 新增场景
* @IsUnique('user', { message: '用户名已存在' })
* username: string;
*
* // 编辑场景
* @IsUnique('user', { message: '用户名已存在', excludeField: 'id' })
* username: string;
*/
export function IsUnique(table: SchemaName, validationOptions?: IsUniqueOptions) {
return (object: Record<string, any>, propertyName: string) => {
registerDecorator({
name: 'IsUnique',
target: object.constructor,
propertyName,
constraints: [table],
options: validationOptions,
validator: {
async validate(value: string, args: ValidationArguments) {
if (!value)
return true; // 空值由其他验证器处理
const excludeField = validationOptions?.excludeField || 'id';
const currentObject = args.object as any;
try {
const tableSchema = schema[table];
const column = tableSchema[propertyName];
if (!column) {
console.error(`Column ${propertyName} not found in table ${table}`);
return false;
}
// 构建查询条件
const conditions = [eq(column, value)];
// 如果是编辑操作(存在 excludeField),排除当前记录
if (currentObject?.[excludeField]) {
const excludeColumn = tableSchema[excludeField];
if (excludeColumn) {
conditions.push(ne(excludeColumn, currentObject[excludeField]));
}
}
const [result] = await db
.select()
.from(tableSchema)
.where(conditions.length > 1 ? and(...conditions) : conditions[0])
.limit(1);
// 如果找不到记录,说明值是唯一的
return !result;
}
catch (error) {
console.error('IsUnique validation error:', error);
return false;
}
},
},
});
};
}