import { z } from 'zod'; import { DisabledStatus } from '@/share/types'; import { AreaLevel } from './area.entity'; // 省市区创建Schema export const createAreaSchema = z.object({ parentId: z.number().int().min(0, '父级ID不能为负数').default(0), name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符'), level: z.nativeEnum(AreaLevel, { message: '层级必须是1(省/直辖市)、2(市)或3(区/县)' }), code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符'), isDisabled: z.nativeEnum(DisabledStatus).default(DisabledStatus.ENABLED), }).refine((data) => { // 验证层级和父级ID的关系 if (data.level === AreaLevel.PROVINCE && data.parentId !== 0) { return false; } if (data.level !== AreaLevel.PROVINCE && data.parentId === 0) { return false; } return true; }, { message: '层级和父级ID关系不正确:省/直辖市(parentId=0),市/区县(parentId>0)', path: ['parentId'], }); // 省市区更新Schema export const updateAreaSchema = z.object({ parentId: z.number().int().min(0, '父级ID不能为负数').optional(), name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符').optional(), level: z.nativeEnum(AreaLevel, { message: '层级必须是1(省/直辖市)、2(市)或3(区/县)' }).optional(), code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符').optional(), isDisabled: z.nativeEnum(DisabledStatus).optional(), }).refine((data) => { // 验证层级和父级ID的关系 if (data.level && data.parentId !== undefined) { if (data.level === AreaLevel.PROVINCE && data.parentId !== 0) { return false; } if (data.level !== AreaLevel.PROVINCE && data.parentId === 0) { return false; } } return true; }, { message: '层级和父级ID关系不正确:省/直辖市(parentId=0),市/区县(parentId>0)', path: ['parentId'], }); // 省市区获取Schema export const getAreaSchema = z.object({ id: z.number().int().positive('ID必须为正整数'), parentId: z.number().int().min(0, '父级ID不能为负数'), name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符'), level: z.nativeEnum(AreaLevel, { message: '层级必须是1(省/直辖市)、2(市)或3(区/县)' }), code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符'), isDisabled: z.nativeEnum(DisabledStatus), isDeleted: z.number().int(), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), createdBy: z.number().int().nullable(), updatedBy: z.number().int().nullable(), }); // 省市区列表查询Schema export const listAreasSchema = z.object({ keyword: z.string().optional(), level: z.nativeEnum(AreaLevel).optional(), parentId: z.coerce.number().int().min(0).optional(), isDisabled: z.coerce.number().int().optional(), page: z.coerce.number().int().min(1).default(1), pageSize: z.coerce.number().int().min(1).max(100).default(20), sortBy: z.enum(['name', 'level', 'code', 'createdAt']).default('createdAt'), sortOrder: z.enum(['ASC', 'DESC']).default('DESC'), }); // 省市区列表返回Schema export const areaListResponseSchema = z.object({ id: z.number().int().positive('ID必须为正整数'), parentId: z.coerce.number().int().min(0, '父级ID不能为负数').nullable(), name: z.string().min(1, '区域名称不能为空').max(100, '区域名称不能超过100个字符'), level: z.nativeEnum(AreaLevel, { message: '层级必须是1(省/直辖市)、2(市)或3(区/县)' }), code: z.string().min(1, '行政区划代码不能为空').max(20, '行政区划代码不能超过20个字符'), isDisabled: z.nativeEnum(DisabledStatus), isDeleted: z.number().int(), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), createdBy: z.number().int().nullable(), updatedBy: z.number().int().nullable(), }); // 省市区删除Schema export const deleteAreaSchema = z.object({ id: z.number().int().positive('ID必须为正整数'), }); // 省市区启用/禁用Schema export const toggleAreaStatusSchema = z.object({ id: z.number().int().positive('ID必须为正整数'), isDisabled: z.nativeEnum(DisabledStatus), }); // 省市区层级查询Schema export const getAreasByLevelSchema = z.object({ level: z.nativeEnum(AreaLevel, { message: '层级必须是1(省/直辖市)、2(市)或3(区/县)' }), }); // 省市区子级查询Schema export const getChildAreasSchema = z.object({ parentId: z.number().int().positive('父级ID必须为正整数'), }); // 省市区路径查询Schema export const getAreaPathSchema = z.object({ id: z.number().int().positive('区域ID必须为正整数'), }); // 导出类型 export type CreateAreaInput = z.infer; export type UpdateAreaInput = z.infer; export type GetAreaInput = z.infer; export type ListAreasInput = z.infer; export type DeleteAreaInput = z.infer; export type ToggleAreaStatusInput = z.infer; export type GetAreasByLevelInput = z.infer; export type GetChildAreasInput = z.infer; export type GetAreaPathInput = z.infer;