286 lines
8.5 KiB
TypeScript
286 lines
8.5 KiB
TypeScript
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;
|
|
}
|
|
|