zksu
/
API
forked from yoone/API
1
0
Fork 0
API/src/dto/product.dto.ts

446 lines
13 KiB
TypeScript

import { ApiProperty } from '@midwayjs/swagger';
import { Rule, RuleType } from '@midwayjs/validate';
import { UnifiedSearchParamsDTO } from './api.dto';
/**
* 属性输入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: '分类名称', required: false })
@Rule(RuleType.string().optional())
categoryName?: string;
@ApiProperty({ description: '站点 SKU 列表', type: 'array', required: false })
@Rule(RuleType.array().items(RuleType.string()).optional())
siteSkus?: string[];
// 通用属性输入(通过 attributes 统一提交品牌/口味/强度/尺寸/干湿等)
// 当 type 为 'single' 时必填,当 type 为 'bundle' 时可选
@ApiProperty({ description: '属性列表', type: 'array', required: false })
@Rule(
RuleType.array()
.when('type', {
is: 'single',
then: RuleType.array().required(),
otherwise: RuleType.array().optional()
})
)
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;
// 产品图片URL
@ApiProperty({ description: '产品图片URL', example: 'https://example.com/image.jpg', required: false })
@Rule(RuleType.string().optional())
image?: string;
// 商品类型(默认 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: '分类名称', required: false })
@Rule(RuleType.string().optional())
categoryName?: string;
@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;
// 产品图片URL
@ApiProperty({ description: '产品图片URL', example: 'https://example.com/image.jpg', required: false })
@Rule(RuleType.string().optional())
image?: string;
// 属性更新(可选, 支持增量替换指定字典的属性项)
@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: '产品图片URL', example: 'https://example.com/image.jpg', required: false })
@Rule(RuleType.string().optional())
image?: string;
@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[];
}
/**
* 产品查询过滤条件接口
*/
export interface ProductWhereFilter {
// 产品ID
id?: number;
// 产品ID列表
ids?: number[];
// SKU
sku?: string;
// SKU列表
skus?: string[];
// 产品名称
name?: string;
// 产品中文名称
nameCn?: string;
// 分类ID
categoryId?: number;
// 分类ID列表
categoryIds?: number[];
// 品牌ID
brandId?: number;
// 品牌ID列表
brandIds?: number[];
// 产品类型
type?: string;
// 价格最小值
minPrice?: number;
// 价格最大值
maxPrice?: number;
// 促销价格最小值
minPromotionPrice?: number;
// 促销价格最大值
maxPromotionPrice?: number;
// 创建时间范围开始
createdAtStart?: string;
// 创建时间范围结束
createdAtEnd?: string;
// 更新时间范围开始
updatedAtStart?: string;
// 更新时间范围结束
updatedAtEnd?: string;
// TODO 使用 attributes 过滤
attributes?: Record<string, string>;
}
/**
* 产品查询过滤条件DTO
*/
export class ProductWhereFilterDTO {
@ApiProperty({ description: '产品ID', example: 1 })
id?: number;
@ApiProperty({ description: '产品ID列表', example: [1, 2, 3] })
ids?: number[];
@ApiProperty({ description: 'SKU', example: 'ZYN-6MG-WINTERGREEN' })
sku?: string;
@ApiProperty({ description: 'SKU列表', example: ['ZYN-6MG-WINTERGREEN', 'ZYN-3MG-WINTERGREEN'] })
skus?: string[];
@ApiProperty({ description: '产品名称', example: 'ZYN 6MG WINTERGREEN' })
name?: string;
@ApiProperty({ description: '产品中文名称', example: 'ZYN 6毫克 冬清味' })
nameCn?: string;
@ApiProperty({ description: '分类ID', example: 1 })
categoryId?: number;
@ApiProperty({ description: '分类ID列表', example: [1, 2, 3] })
categoryIds?: number[];
@ApiProperty({ description: '品牌ID', example: 1 })
brandId?: number;
@ApiProperty({ description: '品牌ID列表', example: [1, 2, 3] })
brandIds?: number[];
@ApiProperty({ description: '产品类型', example: 'single', enum: ['single', 'bundle'] })
type?: string;
@ApiProperty({ description: '价格最小值', example: 99.99 })
minPrice?: number;
@ApiProperty({ description: '价格最大值', example: 199.99 })
maxPrice?: number;
@ApiProperty({ description: '促销价格最小值', example: 89.99 })
minPromotionPrice?: number;
@ApiProperty({ description: '促销价格最大值', example: 179.99 })
maxPromotionPrice?: number;
@ApiProperty({ description: '创建时间范围开始', example: '2023-01-01 00:00:00' })
createdAtStart?: string;
@ApiProperty({ description: '创建时间范围结束', example: '2023-12-31 23:59:59' })
createdAtEnd?: string;
@ApiProperty({ description: '更新时间范围开始', example: '2023-01-01 00:00:00' })
updatedAtStart?: string;
@ApiProperty({ description: '更新时间范围结束', example: '2023-12-31 23:59:59' })
updatedAtEnd?: string;
}
/**
* DTO 用于分页查询产品
* 支持灵活的where条件、分页和排序
*/
export class QueryProductDTO extends UnifiedSearchParamsDTO<ProductWhereFilter> {
}
/**
* DTO 用于创建分类
*/
export class CreateCategoryDTO {
@ApiProperty({ description: '分类显示名称', required: true })
@Rule(RuleType.string().required())
title: string;
@ApiProperty({ description: '分类中文名称', required: false })
@Rule(RuleType.string().allow('').optional())
titleCN?: string;
@ApiProperty({ description: '分类唯一标识', required: true })
@Rule(RuleType.string().required())
name: string;
@ApiProperty({ description: '分类短名称,用于生成SKU', required: false })
@Rule(RuleType.string().allow('').optional())
shortName?: string;
@ApiProperty({ description: '排序', required: false })
@Rule(RuleType.number().optional())
sort?: number;
}
/**
* DTO 用于更新分类
*/
export class UpdateCategoryDTO {
@ApiProperty({ description: '分类显示名称', required: false })
@Rule(RuleType.string().optional())
title?: string;
@ApiProperty({ description: '分类中文名称', required: false })
@Rule(RuleType.string().allow('').optional())
titleCN?: string;
@ApiProperty({ description: '分类唯一标识', required: false })
@Rule(RuleType.string().optional())
name?: string;
@ApiProperty({ description: '分类短名称,用于生成SKU', required: false })
@Rule(RuleType.string().allow('').optional())
shortName?: string;
@ApiProperty({ description: '排序', required: false })
@Rule(RuleType.number().optional())
sort?: number;
}