From 5ef88f0ed5a04a75eb48b2eaefaaceede63fdda3 Mon Sep 17 00:00:00 2001 From: tikkhun Date: Tue, 14 Oct 2025 11:02:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=B9=E8=AE=A2=E5=8D=95=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E8=BF=9B=E8=A1=8C=E8=87=AA=E5=8A=A8=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/enums/base.enum.ts | 20 +++++++------ src/service/order.service.ts | 57 ++++++++++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/enums/base.enum.ts b/src/enums/base.enum.ts index bcdf0f9..aab088b 100644 --- a/src/enums/base.enum.ts +++ b/src/enums/base.enum.ts @@ -31,16 +31,18 @@ export enum StockRecordOperationType { IN = 'in', OUT = 'out', } - +// Order status. Options: pending, processing, on-hold, completed, cancelled, refunded, failed and trash. Default is pending. +// 原始订单状态 export enum OrderStatus { - PENDING = 'pending', - PROCESSING = 'processing', - COMPLETED = 'completed', - ON_HOLD = 'on-hold', - CANCEL = 'cancelled', - REFUNDED = 'refunded', - FAILED = 'failed', - DRAFT = 'draft', + PENDING = 'pending', // default // 待付款 + PROCESSING = 'processing', // 正在处理 + ON_HOLD = 'on-hold', // 保留 + COMPLETED = 'completed', // 已完成 + CANCEL = 'cancelled', // 已取消 + REFUNDED = 'refunded', // 已退款 + FAILED = 'failed', // 失败订单 + DRAFT = 'draft', // 草稿 + // TRASH = 'trash', REFUND_REQUESTED = 'refund_requested', // 已申请退款 REFUND_APPROVED = 'refund_approved', // 退款申请已通过 REFUND_CANCELLED = 'refund_cancelled', // 已取消退款 diff --git a/src/service/order.service.ts b/src/service/order.service.ts index 7dd42b7..56c0013 100644 --- a/src/service/order.service.ts +++ b/src/service/order.service.ts @@ -111,7 +111,37 @@ export class OrderService { const order = await this.wPService.getOrder(siteId, orderId); await this.syncSingleOrder(siteId, order, true); } + // 订单状态切换表 + orderAutoNextStatusMap = { + [OrderStatus.REFUND_APPROVED]: OrderStatus.ON_HOLD, // 退款申请已通过转为 on-hold + [OrderStatus.REFUND_CANCELLED]: OrderStatus.REFUNDED // 已取消退款转为 refunded + } + // 由于 wordpress 订单状态和 我们的订单状态 不一致,需要做转换 + async autoUpdateOrderStatus(siteId: string, order: any) { + console.log('更新订单状态', order) + // 其他状态保持不变 + const originStatus = order.status; + // 如果有值就赋值 + if (this.orderAutoNextStatusMap[originStatus]) { + order.status = this.orderAutoNextStatusMap[originStatus]; + } + const shouldSync = originStatus !== order.status; + if (!shouldSync) return; + try { + const site = this.sites.find(v => v.id === siteId); + if (!site) { + throw new Error(`更新订单信息,但失败,原因为 ${siteId} 的站点信息不存在`) + } + // 同步更新回 wordpress 的 order 状态 + await this.wPService.updateOrder(site, order.id, { status: order.status }); + } catch (error) { + console.error('更新订单状态失败,原因为:', error) + // 回滚到原始状态 + order.status = originStatus; + } + } + // wordpress 发来, async syncSingleOrder(siteId: string, order: any, forceUpdate = false) { let { line_items, @@ -121,9 +151,12 @@ export class OrderService { refunds, ...orderData } = order; + console.log('同步进单个订单', order) const existingOrder = await this.orderModel.findOne({ where: { externalOrderId: order.id, siteId: siteId }, }); + // 更新状态 + await this.autoUpdateOrderStatus(siteId, order); const orderId = (await this.saveOrder(siteId, orderData)).id; const externalOrderId = order.id; if ( @@ -213,7 +246,7 @@ export class OrderService { el => el.key === '_wc_order_attribution_utm_source' )?.value || ''; order.customer_email = order?.billing?.email || order?.shipping?.email; - // order.billing_phone = order?.billing?.phone || order?.shipping?.phone; + // order.billing_phone = order?.billing?.phone || order?.shipping?.phone; const entity = plainToClass(Order, order); const existingOrder = await this.orderModel.findOne({ where: { externalOrderId: order.externalOrderId, siteId: siteId }, @@ -230,7 +263,7 @@ export class OrderService { const customer = await this.customerModel.findOne({ where: { email: order.customer_email }, }); - if(!customer) { + if (!customer) { await this.customerModel.save({ email: order.customer_email, rate: 0, @@ -333,7 +366,7 @@ export class OrderService { } } - async saveOrderItemsG(orderItem: OrderItem) { + async saveOrderItemsG(orderItem: OrderItem) { const existingOrderItem = await this.orderItemModel.findOne({ where: { externalOrderId: orderItem.externalOrderId, @@ -673,7 +706,7 @@ export class OrderService { sqlQuery += ` AND o.payment_method like "%${payment_method}%" `; totalQuery += ` AND o.payment_method like "%${payment_method}%" `; } - const user = await this.userModel.findOneBy({id: userId}); + const user = await this.userModel.findOneBy({ id: userId }); if (user?.permissions?.includes('order-10-days')) { sqlQuery += ` AND o.date_created >= ?`; totalQuery += ` AND o.date_created >= ?`; @@ -992,7 +1025,7 @@ export class OrderService { }; } - + async getOrderItems({ siteId, startDate, @@ -1157,19 +1190,19 @@ export class OrderService { }); } - // update order_item_origin if not exist - const order_item_origin_count = await this.orderItemOriginalModel.countBy({ orderId: id }); - if (order_item_origin_count === 0 && items.length!=0) { + // update order_item_origin if not exist + const order_item_origin_count = await this.orderItemOriginalModel.countBy({ orderId: id }); + if (order_item_origin_count === 0 && items.length != 0) { items.forEach(async sale => { const { id: saleId, ...saleData } = sale; await this.orderItemOriginalModel.save(saleData); }); } - + } catch (error) { console.log('create order sale origin error: ', error.message); } - + return { ...order, siteName: site.siteName, @@ -1368,10 +1401,10 @@ export class OrderService { const productRepo = manager.getRepository(Product); const order = await orderRepo.findOneBy({ id: orderId }); - let product:Product; + let product: Product; await orderSaleRepo.delete({ orderId }); for (const sale of sales) { - product = await productRepo.findOneBy({ sku: sale.sku }); + product = await productRepo.findOneBy({ sku: sale.sku }); await orderSaleRepo.save({ orderId, siteId: order.siteId,