From d04841c7afad44fc99d630d03c406dd10fc6bf9c Mon Sep 17 00:00:00 2001 From: zhuotianyuan Date: Mon, 13 Oct 2025 16:49:21 +0800 Subject: [PATCH] =?UTF-8?q?20251013-zty-=E6=8D=A2=E8=B4=A7=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/order.controller.ts | 4 +- src/controller/wp_product.controller.ts | 19 +++- src/entity/order.entity.ts | 9 +- src/service/order.service.ts | 118 +++++++++++++++++++++--- src/service/wp_product.service.ts | 38 ++++++++ 5 files changed, 167 insertions(+), 21 deletions(-) diff --git a/src/controller/order.controller.ts b/src/controller/order.controller.ts index 7f668b9..aa71e46 100644 --- a/src/controller/order.controller.ts +++ b/src/controller/order.controller.ts @@ -115,10 +115,10 @@ export class OrderController { @Post('/updateOrderItems/:orderId') async updateOrderItems( @Param('orderId') orderId: number, - @Body() data: any + @Body() data: any, ) { try { - const res = await this.orderService.updateOrderSales(orderId, data); + const res = await this.orderService.updateExchangeOrder(orderId, data); return successResponse(res); } catch (error) { return errorResponse(error?.message || '更新失败'); diff --git a/src/controller/wp_product.controller.ts b/src/controller/wp_product.controller.ts index dad295d..e99bbaa 100644 --- a/src/controller/wp_product.controller.ts +++ b/src/controller/wp_product.controller.ts @@ -21,7 +21,9 @@ import { } from '../dto/wp_product.dto'; import { WPService } from '../service/wp.service'; import { WpSite } from '../interface'; - +import { + ProductsRes, +} from '../dto/reponse.dto'; @Controller('/wp_product') export class WpProductController { @Inject() @@ -187,4 +189,19 @@ export class WpProductController { return errorResponse(error.message || '产品变体更新失败'); } } + + @ApiOkResponse({ + description: '通过name搜索产品/订单', + type: ProductsRes, + }) + @Get('/search') + async searchProducts(@Query('name') name: string) { + try { + // 调用服务获取产品数据 + const products = await this.wpProductService.findProductsByName(name); + return successResponse(products); + } catch (error) { + return errorResponse(error.message || '获取数据失败'); + } + } } diff --git a/src/entity/order.entity.ts b/src/entity/order.entity.ts index 17b7fbe..fc51dd2 100644 --- a/src/entity/order.entity.ts +++ b/src/entity/order.entity.ts @@ -244,14 +244,15 @@ export class Order { utm_source: string; @ApiProperty() - @Column({ default: '' }) + @Column({ default: false }) @Expose() - is_exchange: string; + is_exchange: boolean; @ApiProperty() - @Column({ default: '' }) + @Column('decimal', { precision: 10, scale: 0, default: 0 }) @Expose() - exchange_frequency: string; + exchange_frequency: number; + @ApiProperty({ example: '2022-12-12 11:11:11', diff --git a/src/service/order.service.ts b/src/service/order.service.ts index 7dd42b7..4b20519 100644 --- a/src/service/order.service.ts +++ b/src/service/order.service.ts @@ -213,7 +213,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 +230,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 +333,7 @@ export class OrderService { } } - async saveOrderItemsG(orderItem: OrderItem) { + async saveOrderItemsG(orderItem: OrderItem) { const existingOrderItem = await this.orderItemModel.findOne({ where: { externalOrderId: orderItem.externalOrderId, @@ -597,7 +597,7 @@ export class OrderService { o.total as total, o.date_created as date_created, o.customer_email as customer_email, - + o.exchange_frequency as exchange_frequency, o.transaction_id as transaction_id, o.orderStatus as orderStatus, o.customer_ip_address as customer_ip_address, @@ -673,7 +673,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 +992,7 @@ export class OrderService { }; } - + async getOrderItems({ siteId, startDate, @@ -1157,19 +1157,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 +1368,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, @@ -1383,7 +1383,97 @@ export class OrderService { }); }; - //await orderRepo.save(); + + }).catch(error => { + transactionError = error; + }); + + if (transactionError !== undefined) { + throw new Error(`更新物流信息错误:${transactionError.message}`); + } + return true; + } catch (error) { + throw new Error(`更新发货产品失败:${error.message}`); + } + } + + //换货确认按钮改成调用这个方法 + //换货功能更新OrderSale和Orderitem数据 + async updateExchangeOrder(orderId: number, data: any) { + try { + const dataSource = this.dataSourceManager.getDataSource('default'); + let transactionError = undefined; + + await dataSource.transaction(async manager => { + const orderRepo = manager.getRepository(Order); + const orderSaleRepo = manager.getRepository(OrderSale); + const orderItemRepo = manager.getRepository(OrderItem); + const OrderItemOriginalRepo = manager.getRepository(OrderItemOriginal); + + const productRepo = manager.getRepository(Product); + const WpProductRepo = manager.getRepository(WpProduct); + + const order = await orderRepo.findOneBy({ id: orderId }); + let product: Product; + let wpProduct: WpProduct; + let wpOrderItemOriginal: OrderItemOriginal; + await orderSaleRepo.delete({ orderId }); + await orderItemRepo.delete({ orderId }); + for (const sale of data['sales']) { + product = await productRepo.findOneBy({ sku: sale['sku'] }); + await orderSaleRepo.save({ + orderId, + siteId: order.siteId, + productId: product.id, + name: product.name, + sku: sale['sku'], + quantity: sale['quantity'], + }); + }; + + for (const item of data['items']) { + wpProduct = await WpProductRepo.findOneBy({ sku: item['sku'] }); + wpOrderItemOriginal = await OrderItemOriginalRepo.findOneBy({ sku: item['sku'] }); + let externalVariationId = wpOrderItemOriginal?.externalVariationId; + let price = wpOrderItemOriginal?.price; + if (wpOrderItemOriginal == null) { + externalVariationId = '0'; + price = 0; + } + await orderItemRepo.save({ + orderId, + siteId: order.siteId, + productId: wpProduct.id, + name: wpProduct.name, + externalOrderId: order.externalOrderId, + externalProductId: wpProduct.externalProductId, + externalVariationId: externalVariationId, + price: price, + sku: item['sku'], + quantity: item['quantity'], + }); + + }; + + //将是否换货状态改为true + await orderRepo.update( + order.id + , { + is_exchange: true + }); + + //查询这个用户换过多少次货 + const counts = await orderRepo.countBy({ + is_editable: true, + customer_email: order.customer_email, + }); + + //批量更新当前用户换货次数 + await orderRepo.update({ + customer_email: order.customer_email + }, { + exchange_frequency: counts + }); }).catch(error => { transactionError = error; diff --git a/src/service/wp_product.service.ts b/src/service/wp_product.service.ts index 92c950e..400a411 100644 --- a/src/service/wp_product.service.ts +++ b/src/service/wp_product.service.ts @@ -507,4 +507,42 @@ const excludeValues = []; //await this.variationModel.delete({ siteId, externalProductId: productId }); //await this.wpProductModel.delete({ siteId, externalProductId: productId }); } + + + + async findProductsByName(name: string): Promise { + const nameFilter = name ? name.split(' ').filter(Boolean) : []; + const query = this.wpProductModel.createQueryBuilder('product'); + + // 保证 sku 不为空 + query.where('product.sku IS NOT NULL AND product.on_delete = false'); + + if (nameFilter.length > 0 || name) { + const params: Record = {}; + const conditions: string[] = []; + + // 英文名关键词全部匹配(AND) + if (nameFilter.length > 0) { + const nameConds = nameFilter.map((word, index) => { + const key = `name${index}`; + params[key] = `%${word}%`; + return `product.name LIKE :${key}`; + }); + conditions.push(`(${nameConds.join(' AND ')})`); + } + + // 中文名模糊匹配 + if (name) { + params['nameCn'] = `%${name}%`; + conditions.push(`product.nameCn LIKE :nameCn`); + } + + // 英文名关键词匹配 OR 中文名匹配 + query.andWhere(`(${conditions.join(' OR ')})`, params); + } + + query.take(50); + + return await query.getMany(); + } }