Compare commits

...

2 Commits

Author SHA1 Message Date
tikkhun 817f368522 feat: 添加产品查询过滤条件DTO并优化Swagger配置
添加 ProductWhereFilterDTO 用于产品查询过滤条件
修改 api.dto.ts 中 where 和 orderBy 的类型为 any 以解决 openapit2ts 问题
配置 Swagger 支持嵌套查询参数
移除 product.service.ts 中的多余空行
2026-01-06 18:49:17 +08:00
tikkhun a22e302c4e refactor(order.service): 简化订单ID验证逻辑并优化查询条件
移除冗余的空值检查,使用可选链操作符简化验证
仅在validIds非空时添加查询条件
2026-01-06 10:54:47 +08:00
6 changed files with 82 additions and 14 deletions

View File

@ -119,6 +119,15 @@ export default {
description: 'Bearer Auth',
addSecurityRequirements: true,
},
// 配置 Swagger 支持嵌套查询参数
options: {
// 设置查询参数风格为 deepObject
// 这会告诉 Swagger 使用 JSON 格式来序列化嵌套的查询参数
query: {
style: 'deepObject',
explode: false
}
}
},
mailer: {
host: 'smtphz.qiye.163.com',

View File

@ -37,12 +37,16 @@ export class UnifiedSearchParamsDTO<Where=Record<string, any>> {
@ApiProperty({ description: '搜索关键词', required: false })
search?: string;
@ApiProperty({ description: '过滤条件对象', type: 'object', required: false })
@ApiProperty({
description: '过滤条件对象',
type: 'any', // FIXME 这里是因为 openapit2ts 会将 where 变成 undefined 所以有嵌套对象时先不指定类型
required: false,
})
where?: Where;
@ApiProperty({
description: '排序对象,例如 { "sku": "desc" }',
type: 'object',
type: 'any', // FIXME 这里是因为 openapit2ts 会将 where 变成 undefined 所以有嵌套对象时先不指定类型
required: false,
})
orderBy?: Record<string, 'asc' | 'desc'> | string;

View File

@ -303,6 +303,68 @@ export interface ProductWhereFilter {
updatedAtEnd?: 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条件

View File

@ -2461,17 +2461,9 @@ export class OrderService {
}
try {
// 空值检查和数据清理
if (!ids || !Array.isArray(ids)) {
throw new Error('订单ID列表不能为空');
}
// 过滤掉NaN和非数字值只保留有效的数字ID
const validIds = ids.filter(id => Number.isFinite(id) && id > 0);
if (validIds.length === 0) {
throw new Error('未提供有效的订单ID');
}
const validIds = ids?.filter?.(id => Number.isFinite(id) && id > 0);
const dataSource = this.dataSourceManager.getDataSource('default');
@ -2479,7 +2471,9 @@ export class OrderService {
return await dataSource.transaction(async manager => {
// 准备查询条件
const whereCondition: any = {};
whereCondition.id = In(validIds);
if(validIds.length > 0){
whereCondition.id = In(validIds);
}
// 获取订单、订单项和物流信息
const orders = await manager.getRepository(Order).find({

View File

@ -235,7 +235,6 @@ export class ProductService {
.leftJoinAndSelect('product.attributes', 'attribute')
.leftJoinAndSelect('attribute.dict', 'dict')
.leftJoinAndSelect('product.category', 'category');
// 处理分页参数(支持新旧两种格式)
const page = query.page || 1;
const pageSize = query.per_page || 10;