import { ApiProperty } from '@midwayjs/swagger'; import { Rule, RuleType } from '@midwayjs/validate'; /** * 属性输入DTO */ export class AttributeInputDTO { @ApiProperty({ description: '属性字典标识', example: 'brand' }) @Rule(RuleType.string()) dictName?: string; @ApiProperty({ description: '属性值', example: 'ZYN' }) @Rule(RuleType.string()) value?: string; @ApiProperty({ description: '属性ID', example: 1 }) @Rule(RuleType.number()) id?: number; @ApiProperty({ description: '属性名称', example: 'ZYN' }) @Rule(RuleType.string()) name?: string; @ApiProperty({ description: '属性显示名称', example: 'ZYN' }) @Rule(RuleType.string()) title?: string; } /** * DTO 用于创建产品 */ export class CreateProductDTO { @ApiProperty({ example: 'ZYN 6MG WINTERGREEN', description: '产品名称', required: true, }) @Rule(RuleType.string().required().empty({ message: '产品名称不能为空' })) name: string; @ApiProperty({ description: '产品中文名称', required: false }) @Rule(RuleType.string().allow('').optional()) nameCn?: string; @ApiProperty({ example: '产品描述', description: '产品描述' }) @Rule(RuleType.string()) description: string; @ApiProperty({ example: '产品简短描述', description: '产品简短描述' }) @Rule(RuleType.string().optional()) shortDescription?: string; @ApiProperty({ description: '产品 SKU', required: false }) @Rule(RuleType.string()) sku?: string; @ApiProperty({ description: '分类ID (DictItem ID)', required: false }) @Rule(RuleType.number()) categoryId?: number; @ApiProperty({ description: '站点 SKU 列表', type: 'array', required: false }) @Rule(RuleType.array().items(RuleType.string()).optional()) siteSkus?: string[]; // 通用属性输入(通过 attributes 统一提交品牌/口味/强度/尺寸/干湿等) @ApiProperty({ description: '属性列表', type: 'array' }) @Rule(RuleType.array().required()) attributes: AttributeInputDTO[]; // 商品价格 @ApiProperty({ description: '价格', example: 99.99, required: false }) @Rule(RuleType.number()) price?: number; // 促销价格 @ApiProperty({ description: '促销价格', example: 99.99, required: false }) @Rule(RuleType.number()) promotionPrice?: number; // 商品类型(默认 single; bundle 需手动设置组成) @ApiProperty({ description: '商品类型', enum: ['single', 'bundle'], default: 'single', required: false }) @Rule(RuleType.string().valid('single', 'bundle').default('single')) type?: string; // 仅当 type 为 'bundle' 时,才需要提供 components @ApiProperty({ description: '产品组成', type: 'array', required: false }) @Rule( RuleType.array() .items( RuleType.object({ sku: RuleType.string().required(), quantity: RuleType.number().required(), }) ) .when('type', { is: 'bundle', then: RuleType.array().required(), }) ) components?: { sku: string; quantity: number }[]; } /** * DTO 用于更新产品 */ export class UpdateProductDTO { @ApiProperty({ example: 'ZYN 6MG WINTERGREEN', description: '产品名称' }) @Rule(RuleType.string()) name?: string; @ApiProperty({ description: '产品中文名称', required: false }) @Rule(RuleType.string().allow('').optional()) nameCn?: string; @ApiProperty({ example: '产品描述', description: '产品描述' }) @Rule(RuleType.string()) description?: string; @ApiProperty({ example: '产品简短描述', description: '产品简短描述' }) @Rule(RuleType.string().optional()) shortDescription?: string; @ApiProperty({ description: '产品 SKU', required: false }) @Rule(RuleType.string()) sku?: string; @ApiProperty({ description: '分类ID (DictItem ID)', required: false }) @Rule(RuleType.number()) categoryId?: number; @ApiProperty({ description: '站点 SKU 列表', type: 'array', required: false }) @Rule(RuleType.array().items(RuleType.string()).optional()) siteSkus?: string[]; // 商品价格 @ApiProperty({ description: '价格', example: 99.99, required: false }) @Rule(RuleType.number()) price?: number; // 促销价格 @ApiProperty({ description: '促销价格', example: 99.99, required: false }) @Rule(RuleType.number()) promotionPrice?: number; // 属性更新(可选, 支持增量替换指定字典的属性项) @ApiProperty({ description: '属性列表', type: 'array', required: false }) @Rule(RuleType.array()) attributes?: AttributeInputDTO[]; // 商品类型(single 或 bundle) @ApiProperty({ description: '商品类型', enum: ['single', 'bundle'], required: false }) @Rule(RuleType.string().valid('single', 'bundle')) type?: string; // 仅当 type 为 'bundle' 时,才需要提供 components @ApiProperty({ description: '产品组成', type: 'array', required: false }) @Rule( RuleType.array() .items( RuleType.object({ sku: RuleType.string().required(), quantity: RuleType.number().required(), }) ) .when('type', { is: 'bundle', then: RuleType.array().optional(), }) ) components?: { sku: string; quantity: number }[]; } /** * DTO 用于批量更新产品属性 */ export class BatchUpdateProductDTO { @ApiProperty({ description: '产品ID列表', type: 'array', required: true }) @Rule(RuleType.array().items(RuleType.number()).required().min(1)) ids: number[]; @ApiProperty({ example: 'ZYN 6MG WINTERGREEN', description: '产品名称', required: false }) @Rule(RuleType.string().optional()) name?: string; @ApiProperty({ description: '产品中文名称', required: false }) @Rule(RuleType.string().allow('').optional()) nameCn?: string; @ApiProperty({ example: '产品描述', description: '产品描述', required: false }) @Rule(RuleType.string().optional()) description?: string; @ApiProperty({ example: '产品简短描述', description: '产品简短描述', required: false }) @Rule(RuleType.string().optional()) shortDescription?: string; @ApiProperty({ description: '产品 SKU', required: false }) @Rule(RuleType.string().optional()) sku?: string; @ApiProperty({ description: '分类ID (DictItem ID)', required: false }) @Rule(RuleType.number().optional()) categoryId?: number; @ApiProperty({ description: '站点 SKU 列表', type: 'array', required: false }) @Rule(RuleType.array().items(RuleType.string()).optional()) siteSkus?: string[]; @ApiProperty({ description: '价格', example: 99.99, required: false }) @Rule(RuleType.number().optional()) price?: number; @ApiProperty({ description: '促销价格', example: 99.99, required: false }) @Rule(RuleType.number().optional()) promotionPrice?: number; @ApiProperty({ description: '属性列表', type: 'array', required: false }) @Rule(RuleType.array().optional()) attributes?: AttributeInputDTO[]; @ApiProperty({ description: '商品类型', enum: ['single', 'bundle'], required: false }) @Rule(RuleType.string().valid('single', 'bundle').optional()) type?: string; } /** * DTO 用于批量删除产品 */ export class BatchDeleteProductDTO { @ApiProperty({ description: '产品ID列表', type: 'array', required: true }) @Rule(RuleType.array().items(RuleType.number()).required().min(1)) ids: number[]; } /** * DTO 用于创建分类属性绑定 */ export class CreateCategoryAttributeDTO { @ApiProperty({ description: '分类字典项ID', example: 1 }) @Rule(RuleType.number().required()) categoryItemId: number; @ApiProperty({ description: '属性字典ID列表', example: [2, 3] }) @Rule(RuleType.array().items(RuleType.number()).required()) attributeDictIds: number[]; } /** * DTO 用于分页查询产品 */ export class QueryProductDTO { @ApiProperty({ description: '当前页', example: 1 }) @Rule(RuleType.number().default(1)) current: number; @ApiProperty({ description: '每页数量', example: 10 }) @Rule(RuleType.number().default(10)) pageSize: number; @ApiProperty({ description: '搜索关键字', required: false }) @Rule(RuleType.string()) name?: string; @ApiProperty({ description: '分类ID', required: false }) @Rule(RuleType.number()) categoryId?: number; @ApiProperty({ description: '品牌ID', required: false }) @Rule(RuleType.number()) brandId?: number; @ApiProperty({ description: '排序字段', required: false }) @Rule(RuleType.string()) sortField?: string; @ApiProperty({ description: '排序方式', required: false }) @Rule(RuleType.string().valid('ascend', 'descend')) sortOrder?: string; }