Compare commits
No commits in common. "8fc26396d3cf16e5bfa247356c277b1aba0a81ab" and "fbbb86ae37913fbbb18e5ef4daa687f91df37eed" have entirely different histories.
8fc26396d3
...
fbbb86ae37
|
|
@ -750,31 +750,4 @@ export class ProductController {
|
||||||
return errorResponse(error?.message || error);
|
return errorResponse(error?.message || error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有产品,支持按品牌过滤
|
|
||||||
@ApiOkResponse({ description: '获取所有产品', type: ProductListRes })
|
|
||||||
@Get('/all')
|
|
||||||
async getAllProducts(@Query('brand') brand?: string) {
|
|
||||||
try {
|
|
||||||
const data = await this.productService.getAllProducts(brand);
|
|
||||||
return successResponse(data);
|
|
||||||
} catch (error) {
|
|
||||||
return errorResponse(error?.message || error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取按属性分组的产品,默认按强度划分
|
|
||||||
@ApiOkResponse({ description: '获取按属性分组的产品' })
|
|
||||||
@Get('/grouped')
|
|
||||||
async getGroupedProducts(
|
|
||||||
@Query('brand') brand?: string,
|
|
||||||
@Query('attribute') attribute: string = 'strength'
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const data = await this.productService.getProductsGroupedByAttribute(brand, attribute);
|
|
||||||
return successResponse(data);
|
|
||||||
} catch (error) {
|
|
||||||
return errorResponse(error?.message || error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,8 +311,6 @@ export interface ProductWhereFilter {
|
||||||
updatedAtStart?: string;
|
updatedAtStart?: string;
|
||||||
// 更新时间范围结束
|
// 更新时间范围结束
|
||||||
updatedAtEnd?: string;
|
updatedAtEnd?: string;
|
||||||
// TODO 使用 attributes 过滤
|
|
||||||
attributes?: Record<string, string>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ export class ProductService {
|
||||||
|
|
||||||
// 处理SKU过滤
|
// 处理SKU过滤
|
||||||
if (query.where?.sku) {
|
if (query.where?.sku) {
|
||||||
qb.andWhere('product.sku LIKE :sku', { sku: `%${query.where.sku}%` });
|
qb.andWhere('product.sku = :sku', { sku: query.where.sku });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理SKU列表过滤
|
// 处理SKU列表过滤
|
||||||
|
|
@ -296,6 +296,10 @@ export class ProductService {
|
||||||
qb.andWhere('product.sku IN (:...skus)', { skus: query.where.skus });
|
qb.andWhere('product.sku IN (:...skus)', { skus: query.where.skus });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理where对象中的sku过滤
|
||||||
|
if (query.where?.sku) {
|
||||||
|
qb.andWhere('product.sku = :whereSku', { whereSku: query.where.sku });
|
||||||
|
}
|
||||||
|
|
||||||
// 处理where对象中的skus过滤
|
// 处理where对象中的skus过滤
|
||||||
if (query.where?.skus && query.where.skus.length > 0) {
|
if (query.where?.skus && query.where.skus.length > 0) {
|
||||||
|
|
@ -389,41 +393,6 @@ export class ProductService {
|
||||||
qb.andWhere('product.updatedAt <= :whereUpdatedAtEnd', { whereUpdatedAtEnd: new Date(query.where.updatedAtEnd) });
|
qb.andWhere('product.updatedAt <= :whereUpdatedAtEnd', { whereUpdatedAtEnd: new Date(query.where.updatedAtEnd) });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理属性过滤
|
|
||||||
const attributeFilters = query.where?.attributes || {};
|
|
||||||
Object.entries(attributeFilters).forEach(([attributeName, value], index) => {
|
|
||||||
if (value === 'hasValue') {
|
|
||||||
// 如果值为'hasValue',则过滤出具有该属性的产品
|
|
||||||
qb.andWhere(qb => {
|
|
||||||
const subQuery = qb
|
|
||||||
.subQuery()
|
|
||||||
.select('product_attributes_dict_item.productId')
|
|
||||||
.from('product_attributes_dict_item', 'product_attributes_dict_item')
|
|
||||||
.innerJoin('dict_item', 'dict_item', 'product_attributes_dict_item.dictItemId = dict_item.id')
|
|
||||||
.innerJoin('dict', 'dict', 'dict_item.dictId = dict.id')
|
|
||||||
.where('dict.name = :attributeName', {
|
|
||||||
attributeName,
|
|
||||||
})
|
|
||||||
.getQuery();
|
|
||||||
return 'product.id IN ' + subQuery;
|
|
||||||
});
|
|
||||||
} else if (typeof value === 'number' || !isNaN(Number(value))) {
|
|
||||||
// 如果值是数字,则过滤出该属性等于该值的产品
|
|
||||||
const attributeValueId = Number(value);
|
|
||||||
qb.andWhere(qb => {
|
|
||||||
const subQuery = qb
|
|
||||||
.subQuery()
|
|
||||||
.select('product_attributes_dict_item.productId')
|
|
||||||
.from('product_attributes_dict_item', 'product_attributes_dict_item')
|
|
||||||
.where('product_attributes_dict_item.dictItemId = :attributeValueId', {
|
|
||||||
attributeValueId,
|
|
||||||
})
|
|
||||||
.getQuery();
|
|
||||||
return 'product.id IN ' + subQuery;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 品牌过滤(向后兼容)
|
// 品牌过滤(向后兼容)
|
||||||
if (brandId) {
|
if (brandId) {
|
||||||
qb.andWhere(qb => {
|
qb.andWhere(qb => {
|
||||||
|
|
@ -2107,111 +2076,4 @@ export class ProductService {
|
||||||
|
|
||||||
return unifiedProduct;
|
return unifiedProduct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有产品,支持按品牌过滤
|
|
||||||
* @param brand 品牌名称
|
|
||||||
* @returns 所有符合条件的产品
|
|
||||||
*/
|
|
||||||
async getAllProducts(brand?: string): Promise<{ items: Product[], total: number }> {
|
|
||||||
const qb = this.productModel
|
|
||||||
.createQueryBuilder('product')
|
|
||||||
.leftJoinAndSelect('product.attributes', 'attribute')
|
|
||||||
.leftJoinAndSelect('attribute.dict', 'dict')
|
|
||||||
.leftJoinAndSelect('product.category', 'category');
|
|
||||||
|
|
||||||
// 按品牌过滤
|
|
||||||
if (brand) {
|
|
||||||
// 先获取品牌对应的字典项
|
|
||||||
const brandDict = await this.dictModel.findOne({ where: { name: 'brand' } });
|
|
||||||
if (brandDict) {
|
|
||||||
// 查找品牌名称对应的字典项(支持标题和名称匹配)
|
|
||||||
const brandItem = await this.dictItemModel.findOne({
|
|
||||||
where: [
|
|
||||||
{
|
|
||||||
title: brand,
|
|
||||||
dict: { id: brandDict.id }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: brand,
|
|
||||||
dict: { id: brandDict.id }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
if (brandItem) {
|
|
||||||
qb.andWhere(qb => {
|
|
||||||
const subQuery = qb
|
|
||||||
.subQuery()
|
|
||||||
.select('product_attributes_dict_item.productId')
|
|
||||||
.from('product_attributes_dict_item', 'product_attributes_dict_item')
|
|
||||||
.where('product_attributes_dict_item.dictItemId = :brandId', {
|
|
||||||
brandId: brandItem.id,
|
|
||||||
})
|
|
||||||
.getQuery();
|
|
||||||
return 'product.id IN ' + subQuery;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据类型填充组成信息
|
|
||||||
const items = await qb.getMany();
|
|
||||||
for (const product of items) {
|
|
||||||
if (product.type === 'single') {
|
|
||||||
// 单品不持久化组成,这里仅返回一个基于 SKU 的虚拟组成
|
|
||||||
const component = new ProductStockComponent();
|
|
||||||
component.productId = product.id;
|
|
||||||
component.sku = product.sku;
|
|
||||||
component.quantity = 1;
|
|
||||||
product.components = [component];
|
|
||||||
} else {
|
|
||||||
// 混装商品返回持久化的 SKU 组成
|
|
||||||
product.components = await this.productStockComponentModel.find({
|
|
||||||
where: { productId: product.id },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确保属性按强度正确划分,只保留强度相关的属性
|
|
||||||
// 这里根据需求,如果需要可以进一步过滤或重组属性
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
items,
|
|
||||||
total: items.length
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取产品按属性值分组,支持按强度划分
|
|
||||||
* @param brand 品牌名称
|
|
||||||
* @returns 按属性值分组的产品
|
|
||||||
*/
|
|
||||||
async getProductsGroupedByAttribute(brand?: string, attributeName: string = 'strength'): Promise<{ [key: string]: Product[] }> {
|
|
||||||
// 首先获取所有产品
|
|
||||||
const { items } = await this.getAllProducts(brand);
|
|
||||||
|
|
||||||
// 按指定属性分组
|
|
||||||
const groupedProducts: { [key: string]: Product[] } = {};
|
|
||||||
|
|
||||||
items.forEach(product => {
|
|
||||||
// 获取产品的指定属性值
|
|
||||||
const attribute = product.attributes.find(attr => attr.dict.name === attributeName);
|
|
||||||
if (attribute) {
|
|
||||||
const attributeValue = attribute.title || attribute.name;
|
|
||||||
if (!groupedProducts[attributeValue]) {
|
|
||||||
groupedProducts[attributeValue] = [];
|
|
||||||
}
|
|
||||||
groupedProducts[attributeValue].push(product);
|
|
||||||
} else {
|
|
||||||
// 如果没有该属性,放入未分组
|
|
||||||
if (!groupedProducts['未分组']) {
|
|
||||||
groupedProducts['未分组'] = [];
|
|
||||||
}
|
|
||||||
groupedProducts['未分组'].push(product);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return groupedProducts;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue