From 68574dbc7a74e0f8130f195eba4a28dd3887c485 Mon Sep 17 00:00:00 2001 From: tikkhun Date: Mon, 12 Jan 2026 15:13:37 +0800 Subject: [PATCH] =?UTF-8?q?refactor(order):=20=E9=87=8D=E6=9E=84=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E7=9B=B8=E5=85=B3=E5=AE=9E=E4=BD=93=E5=92=8C=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构 OrderSale 实体,移除品牌判断标志字段,改为直接存储品牌、口味等属性 修改订单服务和统计服务,使用新的属性字段进行查询和统计 优化产品查询时的关联关系加载 --- src/adapter/shopyy.adapter.ts | 4 +- src/entity/order_sale.entity.ts | 65 +++++++++++++------------------ src/service/order.service.ts | 36 +++++++++-------- src/service/statistics.service.ts | 60 ++++++++++++++-------------- 4 files changed, 78 insertions(+), 87 deletions(-) diff --git a/src/adapter/shopyy.adapter.ts b/src/adapter/shopyy.adapter.ts index c2225a3..e14e6d2 100644 --- a/src/adapter/shopyy.adapter.ts +++ b/src/adapter/shopyy.adapter.ts @@ -227,7 +227,7 @@ export class ShopyyAdapter implements ISiteAdapter { // ========== 订单映射方法 ========== mapPlatformToUnifiedOrder(item: ShopyyOrder): UnifiedOrderDTO { - console.log(item) + // console.log(item) if(!item) throw new Error('订单数据不能为空') // 提取账单和送货地址 如果不存在则为空对象 const billing = (item).bill_address || {}; @@ -315,7 +315,7 @@ export class ShopyyAdapter implements ISiteAdapter { product_id: p.product_id, quantity: p.quantity, total: String(p.price ?? ''), - sku: p.sku || p.sku_code || '', + sku: p.sku_code || '', price: String(p.price ?? ''), }) ); diff --git a/src/entity/order_sale.entity.ts b/src/entity/order_sale.entity.ts index 5ceb758..35b0e0b 100644 --- a/src/entity/order_sale.entity.ts +++ b/src/entity/order_sale.entity.ts @@ -22,22 +22,22 @@ export class OrderSale { @Expose() id?: number; - @ApiProperty() + @ApiProperty({ name:'原始订单ID' }) @Column() @Expose() orderId: number; // 订单 ID - @ApiProperty() - @Column({ nullable: true }) + @ApiProperty({ name:'站点' }) + @Column() @Expose() siteId: number; // 来源站点唯一标识 - @ApiProperty() + @ApiProperty({name: "原始订单 itemId"}) @Column({ nullable: true }) @Expose() externalOrderItemId: string; // WooCommerce 订单item ID - @ApiProperty() + @ApiProperty({name: "产品 ID"}) @Column() @Expose() productId: number; @@ -62,25 +62,35 @@ export class OrderSale { @Expose() isPackage: boolean; - @ApiProperty() - @Column({ default: false }) + @ApiProperty({ description: '品牌', type: 'string',nullable: true}) @Expose() - isYoone: boolean; + @Column({ nullable: true }) + brand?: string; - @ApiProperty() - @Column({ default: false }) + @ApiProperty({ description: '口味', type: 'string', nullable: true }) @Expose() - isZex: boolean; + @Column({ nullable: true }) + flavor?: string; - @ApiProperty({ nullable: true }) - @Column({ type: 'int', nullable: true }) + @ApiProperty({ description: '湿度', type: 'string', nullable: true }) @Expose() - size: number | null; // 其实是 strength + @Column({ nullable: true }) + humidity?: string; - @ApiProperty() - @Column({ default: false }) + @ApiProperty({ description: '尺寸', type: 'string', nullable: true }) @Expose() - isYooneNew: boolean; + @Column({ nullable: true }) + size?: string; + + @ApiProperty({name: '强度', nullable: true }) + @Column({ nullable: true }) + @Expose() + strength: string | null; + + @ApiProperty({ description: '版本', type: 'string', nullable: true }) + @Expose() + @Column({ nullable: true }) + version?: string; @ApiProperty({ example: '2022-12-12 11:11:11', @@ -97,25 +107,4 @@ export class OrderSale { @UpdateDateColumn() @Expose() updatedAt?: Date; - - // // === 自动计算逻辑 === - // @BeforeInsert() - // @BeforeUpdate() - // setFlags() { - // if (!this.name) return; - // const lower = this.name.toLowerCase(); - // this.isYoone = lower.includes('yoone'); - // this.isZex = lower.includes('zex'); - // this.isYooneNew = this.isYoone && lower.includes('new'); - // let size: number | null = null; - // const sizes = [3, 6, 9, 12, 15, 18]; - // for (const s of sizes) { - // if (lower.includes(s.toString())) { - // size = s; - // break; - // } - // } - // this.size = size; - // } - } diff --git a/src/service/order.service.ts b/src/service/order.service.ts index 86a9d50..586dc42 100644 --- a/src/service/order.service.ts +++ b/src/service/order.service.ts @@ -714,7 +714,7 @@ export class OrderService { // 从数据库查询产品,关联查询组件 const product = await this.productModel.findOne({ where: { siteSkus: Like(`%${orderItem.sku}%`) }, - relations: ['components'], + relations: ['components','attributes','attributes.dict'], }); if (!product) return; @@ -722,7 +722,7 @@ export class OrderService { return { product: await this.productModel.findOne({ where: { sku: comp.sku }, - relations: ['components', 'attributes'], + relations: ['components', 'attributes','attributes.dict'], }), quantity: comp.quantity * orderItem.quantity, } @@ -739,26 +739,28 @@ export class OrderService { name: componentDetail.product.name, quantity: componentDetail.quantity * orderItem.quantity, sku: componentDetail.product.sku, + // 理论上直接存 product 的全部数据才是对的,因为这样我的数据才全面。 isPackage: componentDetail.product.type === 'bundle', isYoone: attrsObj?.['brand']?.name === 'yoone', isZyn: attrsObj?.['brand']?.name === 'zyn', isZex: attrsObj?.['brand']?.name === 'zex', isYooneNew: attrsObj?.['brand']?.name === 'yoone' && attrsObj?.['version']?.name === 'new', - size: this.extractNumberFromString(attrsObj?.['strength']?.name) || null, + strength: attrsObj?.['strength']?.name, }); return orderSale }).filter(v => v !== null) - + console.log("orderSales",orderSales) if (orderSales.length > 0) { await this.orderSaleModel.save(orderSales); } } - extractNumberFromString(str: string): number { - if (!str) return 0; + // // extract stren + // extractNumberFromString(str: string): number { + // if (!str) return 0; - const num = parseInt(str, 10); - return isNaN(num) ? 0 : num; - } + // const num = parseInt(str, 10); + // return isNaN(num) ? 0 : num; + // } /** * 保存订单退款信息 @@ -1572,14 +1574,14 @@ export class OrderService { `; let yooneSql = ` SELECT - SUM(CASE WHEN os.isYoone = 1 AND os.size = 3 THEN os.quantity ELSE 0 END) AS yoone3Quantity, - SUM(CASE WHEN os.isYoone = 1 AND os.size = 6 THEN os.quantity ELSE 0 END) AS yoone6Quantity, - SUM(CASE WHEN os.isYoone = 1 AND os.size = 9 THEN os.quantity ELSE 0 END) AS yoone9Quantity, - SUM(CASE WHEN os.isYoone = 1 AND os.size = 12 THEN os.quantity ELSE 0 END) AS yoone12Quantity, - SUM(CASE WHEN os.isYooneNew = 1 AND os.size = 12 THEN os.quantity ELSE 0 END) AS yoone12QuantityNew, - SUM(CASE WHEN os.isYoone = 1 AND os.size = 15 THEN os.quantity ELSE 0 END) AS yoone15Quantity, - SUM(CASE WHEN os.isYoone = 1 AND os.size = 18 THEN os.quantity ELSE 0 END) AS yoone18Quantity, - SUM(CASE WHEN os.isZex = 1 THEN os.quantity ELSE 0 END) AS zexQuantity + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '3mg' THEN os.quantity ELSE 0 END) AS yoone3Quantity, + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '6mg' THEN os.quantity ELSE 0 END) AS yoone6Quantity, + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '9mg' THEN os.quantity ELSE 0 END) AS yoone9Quantity, + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '12mg' THEN os.quantity ELSE 0 END) AS yoone12Quantity, + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '12mg' THEN os.quantity ELSE 0 END) AS yoone12QuantityNew, + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '15mg' THEN os.quantity ELSE 0 END) AS yoone15Quantity, + SUM(CASE WHEN os.brand = 'yoone' AND os.strength = '18mg' THEN os.quantity ELSE 0 END) AS yoone18Quantity, + SUM(CASE WHEN os.brand = 'zex' THEN os.quantity ELSE 0 END) AS zexQuantity FROM order_sale os INNER JOIN \`order\` o ON o.id = os.orderId WHERE o.date_paid BETWEEN ? AND ? diff --git a/src/service/statistics.service.ts b/src/service/statistics.service.ts index fd0f741..ffa557e 100644 --- a/src/service/statistics.service.ts +++ b/src/service/statistics.service.ts @@ -73,16 +73,16 @@ export class StatisticsService { order_sales_summary AS ( SELECT orderId, - SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity, - SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity, - SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity + SUM(CASE WHEN brand = 'zyn' THEN quantity ELSE 0 END) AS zyn_quantity, + SUM(CASE WHEN brand = 'yoone' THEN quantity ELSE 0 END) AS yoone_quantity, + SUM(CASE WHEN brand = 'zex' THEN quantity ELSE 0 END) AS zex_quantity, + SUM(CASE WHEN brand = 'yoone' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, + SUM(CASE WHEN brand = 'yoone' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '3mg' THEN quantity ELSE 0 END) AS yoone_3_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '6mg' THEN quantity ELSE 0 END) AS yoone_6_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '9mg' THEN quantity ELSE 0 END) AS yoone_9_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '12mg' THEN quantity ELSE 0 END) AS yoone_12_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '15mg' THEN quantity ELSE 0 END) AS yoone_15_quantity FROM order_sale GROUP BY orderId ), @@ -269,16 +269,16 @@ export class StatisticsService { order_sales_summary AS ( SELECT orderId, - SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity, - SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity, - SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity + SUM(CASE WHEN brand = 'zyn' THEN quantity ELSE 0 END) AS zyn_quantity, + SUM(CASE WHEN brand = 'yoone' THEN quantity ELSE 0 END) AS yoone_quantity, + SUM(CASE WHEN brand = 'zex' THEN quantity ELSE 0 END) AS zex_quantity, + SUM(CASE WHEN brand = 'yoone' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, + SUM(CASE WHEN brand = 'yoone' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '3mg' THEN quantity ELSE 0 END) AS yoone_3_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '6mg' THEN quantity ELSE 0 END) AS yoone_6_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '9mg' THEN quantity ELSE 0 END) AS yoone_9_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '12mg' THEN quantity ELSE 0 END) AS yoone_12_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '15mg' THEN quantity ELSE 0 END) AS yoone_15_quantity FROM order_sale GROUP BY orderId ), @@ -466,16 +466,16 @@ export class StatisticsService { order_sales_summary AS ( SELECT orderId, - SUM(CASE WHEN name LIKE '%zyn%' THEN quantity ELSE 0 END) AS zyn_quantity, - SUM(CASE WHEN name LIKE '%yoone%' THEN quantity ELSE 0 END) AS yoone_quantity, - SUM(CASE WHEN name LIKE '%zex%' THEN quantity ELSE 0 END) AS zex_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%3%' THEN quantity ELSE 0 END) AS yoone_3_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%6%' THEN quantity ELSE 0 END) AS yoone_6_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%9%' THEN quantity ELSE 0 END) AS yoone_9_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%12%' THEN quantity ELSE 0 END) AS yoone_12_quantity, - SUM(CASE WHEN name LIKE '%yoone%' AND name LIKE '%15%' THEN quantity ELSE 0 END) AS yoone_15_quantity + SUM(CASE WHEN brand = 'zyn' THEN quantity ELSE 0 END) AS zyn_quantity, + SUM(CASE WHEN brand = 'yoone' THEN quantity ELSE 0 END) AS yoone_quantity, + SUM(CASE WHEN brand = 'zex' THEN quantity ELSE 0 END) AS zex_quantity, + SUM(CASE WHEN brand = 'yoone' AND isPackage = 1 THEN quantity ELSE 0 END) AS yoone_G_quantity, + SUM(CASE WHEN brand = 'yoone' AND isPackage = 0 THEN quantity ELSE 0 END) AS yoone_S_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '3mg' THEN quantity ELSE 0 END) AS yoone_3_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '6mg' THEN quantity ELSE 0 END) AS yoone_6_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '9mg' THEN quantity ELSE 0 END) AS yoone_9_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '12mg' THEN quantity ELSE 0 END) AS yoone_12_quantity, + SUM(CASE WHEN brand = 'yoone' AND strength = '15mg' THEN quantity ELSE 0 END) AS yoone_15_quantity FROM order_sale GROUP BY orderId ),