diff --git a/src/config/config.default.ts b/src/config/config.default.ts index 6fe7ac8..c35e3f2 100644 --- a/src/config/config.default.ts +++ b/src/config/config.default.ts @@ -16,6 +16,7 @@ import { OrderFee } from '../entity/order_fee.entity'; import { OrderRefund } from '../entity/order_refund.entity'; import { OrderRefundItem } from '../entity/order_retund_item.entity'; import { OrderSale } from '../entity/order_sale.entity'; +import { OrderSaleOriginal } from '../entity/order_item_original.entity'; import { OrderShipping } from '../entity/order_shipping.entity'; import { Service } from '../entity/service.entity'; import { ShippingAddress } from '../entity/shipping_address.entity'; @@ -57,6 +58,7 @@ export default { OrderRefund, OrderRefundItem, OrderSale, + OrderSaleOriginal, OrderShipment, ShipmentItem, Shipment, diff --git a/src/controller/logistics.controller.ts b/src/controller/logistics.controller.ts index 41ab6bb..23ef859 100644 --- a/src/controller/logistics.controller.ts +++ b/src/controller/logistics.controller.ts @@ -195,7 +195,7 @@ export class LogisticsController { ) @Post('/getShipmentLabel/:shipmentId') async getShipmentLabel( - @Param('shipmentId') shipmentId: string + @Param('shipmentId') shipmentId: number ) { try { const res = await this.logisticsService.getShipmentLabel(shipmentId); @@ -224,7 +224,7 @@ export class LogisticsController { @ApiOkResponse() @Post('/updateState/:id') async updateShipmentState( - @Param('shipmentId') shipmentId: string + @Param('shipmentId') shipmentId: number ) { try { const data = await this.logisticsService.updateShipmentStateById(shipmentId); @@ -236,7 +236,7 @@ export class LogisticsController { @ApiOkResponse() @Del('/shipment/:id') - async delShipment(@Param('id') id: string, @User() user) { + async delShipment(@Param('id') id: number, @User() user) { try { const data = await this.logisticsService.delShipment(id, user.id); return successResponse(data); @@ -260,7 +260,7 @@ export class LogisticsController { @ApiOkResponse() @Post('/getListByTrackingId') - async getListByTrackingId(@Query('shipment_id') shipment_id: string) { + async getListByTrackingId(@Query('shipment_id') shipment_id: number) { try { return successResponse( await this.logisticsService.getListByTrackingId(shipment_id) diff --git a/src/controller/order.controller.ts b/src/controller/order.controller.ts index 904ae9d..de1b010 100644 --- a/src/controller/order.controller.ts +++ b/src/controller/order.controller.ts @@ -108,6 +108,22 @@ export class OrderController { } } + @ApiOkResponse({ + type: BooleanRes, + }) + @Post('/updateOrderItems/:orderId') + async updateOrderItems( + @Param('orderId') orderId: number, + @Body() data: any + ) { + try { + const res = await this.orderService.updateOrderSales(orderId, data); + return successResponse(res); + } catch (error) { + return errorResponse(error?.message || '更新失败'); + } + } + @ApiOkResponse({ type: BooleanRes, }) diff --git a/src/entity/order.entity.ts b/src/entity/order.entity.ts index 62d15b0..792400f 100644 --- a/src/entity/order.entity.ts +++ b/src/entity/order.entity.ts @@ -50,7 +50,7 @@ export class Order { @ApiProperty() @Column({ name: 'shipment_id', nullable: true }) @Expose() - shipmentId: string; + shipmentId: number; @OneToOne(() => Shipment) @JoinColumn({ name: 'shipment_id' }) diff --git a/src/entity/order_item_original.entity.ts b/src/entity/order_item_original.entity.ts new file mode 100644 index 0000000..195e866 --- /dev/null +++ b/src/entity/order_item_original.entity.ts @@ -0,0 +1,78 @@ +import { ApiProperty } from '@midwayjs/swagger'; +import { Exclude, Expose } from 'class-transformer'; +import { + Column, + CreateDateColumn, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; +import { Order } from './order.entity'; + +@Entity('order_sale_original') +@Exclude() +export class OrderSaleOriginal { + @ApiProperty() + @PrimaryGeneratedColumn() + @Expose() + id?: number; + + @ApiProperty() + @ManyToOne(() => Order) + @JoinColumn({ name: 'order_id' }) + @Expose() + orderId: number; // 订单 ID + + @ApiProperty() + @Column() + @Expose() + siteId: string; // 来源站点唯一标识 + + @ApiProperty() + @Column() + @Expose() + externalOrderItemId: string; // WooCommerce 订单item ID + + @ApiProperty() + @Column() + @Expose() + productId: number; + + @ApiProperty() + @Column() + @Expose() + name: string; + + @ApiProperty({ description: 'sku', type: 'string' }) + @Expose() + @Column() + sku: string; + + @ApiProperty() + @Column() + @Expose() + quantity: number; + + @ApiProperty() + @Column({ default: false }) + @Expose() + isPackage: boolean; + + @ApiProperty({ + example: '2022-12-12 11:11:11', + description: '创建时间', + }) + @CreateDateColumn() + @Expose() + createdAt?: Date; + + @ApiProperty({ + example: '2022-12-12 11:11:11', + description: '更新时间', + }) + @UpdateDateColumn() + @Expose() + updatedAt?: Date; +} diff --git a/src/entity/order_sale.entity.ts b/src/entity/order_sale.entity.ts index dbce840..d8947cf 100644 --- a/src/entity/order_sale.entity.ts +++ b/src/entity/order_sale.entity.ts @@ -27,7 +27,7 @@ export class OrderSale { siteId: string; // 来源站点唯一标识 @ApiProperty() - @Column() + @Column({ nullable: true }) @Expose() externalOrderItemId: string; // WooCommerce 订单item ID diff --git a/src/entity/order_shipment.entity.ts b/src/entity/order_shipment.entity.ts index 7ac348d..ea6774d 100644 --- a/src/entity/order_shipment.entity.ts +++ b/src/entity/order_shipment.entity.ts @@ -13,7 +13,7 @@ export class OrderShipment { @ApiProperty() @Column() - shipment_id: string; + shipment_id: number; @ApiProperty() @Column() diff --git a/src/entity/shipment.entity.ts b/src/entity/shipment.entity.ts index 5d3b4f6..947db07 100644 --- a/src/entity/shipment.entity.ts +++ b/src/entity/shipment.entity.ts @@ -19,7 +19,7 @@ export class Shipment { @ApiProperty() @PrimaryGeneratedColumn() @Expose() - id: string; + id: number; @ApiProperty() @Column({ nullable: true }) diff --git a/src/entity/shipment_item.entity.ts b/src/entity/shipment_item.entity.ts index 3b32e68..b2d244a 100644 --- a/src/entity/shipment_item.entity.ts +++ b/src/entity/shipment_item.entity.ts @@ -4,9 +4,13 @@ import { Column, CreateDateColumn, Entity, + JoinColumn, + ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm'; +import { Shipment } from './shipment.entity'; +import { Order } from './order.entity'; @Entity('shipment_item') @Exclude() @@ -17,17 +21,19 @@ export class ShipmentItem { id: number; @ApiProperty() - @Column() @Expose() - shipment_id: string; + @ManyToOne(() => Shipment) + @JoinColumn({ name: 'shipment_id' }) + shipment_id: number; @ApiProperty() - @Column() @Expose() - productId: number; + @ManyToOne(() => Order) + @JoinColumn({ name: 'order_id' }) + order_id: number; @ApiProperty() - @Column() + @Column({ nullable: true }) @Expose() name: string; diff --git a/src/service/canadaPost.service.ts b/src/service/canadaPost.service.ts index fc38a66..0edee31 100644 --- a/src/service/canadaPost.service.ts +++ b/src/service/canadaPost.service.ts @@ -157,7 +157,7 @@ export class CanadaPostService { } /** 取消运单 */ - async cancelShipment(shipmentId: string) { + async cancelShipment(shipmentId: number) { const url = `${this.url}/rs/${this.customerNumber}/${this.customerNumber}/shipment/${shipmentId}`; const res = await axios.delete(url, { diff --git a/src/service/freightcom.service.ts b/src/service/freightcom.service.ts index 0426c21..6b901fc 100644 --- a/src/service/freightcom.service.ts +++ b/src/service/freightcom.service.ts @@ -98,7 +98,7 @@ export class FreightcomService { } // 查询运单详细信息 - async getShipment(shipment_id: string) { + async getShipment(shipment_id: number) { let { status, data } = await axios.request({ url: `${this.apiUrl}/shipment/${shipment_id}`, method: 'GET', @@ -117,7 +117,7 @@ export class FreightcomService { } // 取消发货 - async cancelShipment(shipment_id: string) { + async cancelShipment(shipment_id: number) { const response = await axios.request({ url: `${this.apiUrl}/shipment/${shipment_id}`, method: 'DELETE', diff --git a/src/service/logistics.service.ts b/src/service/logistics.service.ts index 0252f7b..9bdbc9b 100644 --- a/src/service/logistics.service.ts +++ b/src/service/logistics.service.ts @@ -29,6 +29,7 @@ import { OrderItem } from '../entity/order_item.entity'; import { OrderSale } from '../entity/order_sale.entity'; import { UniExpressService } from './uni_express.service'; import { StockPoint } from '../entity/stock_point.entity'; +import { OrderService } from './order.service'; @Provide() export class LogisticsService { @@ -74,6 +75,9 @@ export class LogisticsService { @Inject() wpService: WPService; + @Inject() + orderService: OrderService; + @Inject() dataSourceManager: TypeORMDataSourceManager; @@ -124,7 +128,6 @@ export class LogisticsService { async updateShipmentState(shipment: Shipment) { try { const data = await this.uniExpressService.getOrderStatus(shipment.return_tracking_number); - // console.log('res', data, data.data[0].state); shipment.state = data.data[0].state; if (shipment.state in [203, 215, 216, 230]) { // todo,写常数 shipment.finished = true; @@ -136,7 +139,7 @@ export class LogisticsService { } } - async updateShipmentStateById(id: string) { + async updateShipmentStateById(id: number) { const shipment:Shipment = await this.shipmentModel.findOneBy({ id : id }); return this.updateShipmentState(shipment); } @@ -224,7 +227,7 @@ export class LogisticsService { } } - async removeShipment(shipmentId) { + async removeShipment(shipmentId: number) { try { const shipment:Shipment = await this.shipmentModel.findOneBy({id: shipmentId}); if (shipment.state !== '190') { // todo,写常数 @@ -292,7 +295,7 @@ export class LogisticsService { shipper_country_code: data.details.origin.address.country, receiver: data.details.destination.contact_name, city: data.details.destination.address.city, - province: data.details.destination.address.region, // todo,待确认 + province: data.details.destination.address.region, country: data.details.destination.address.country, postal_code: data.details.destination.address.postal_code.replace(/\s/g, ''), delivery_address: data.details.destination.address.address_line_1, @@ -316,6 +319,7 @@ export class LogisticsService { async createShipment(orderId: number, data: ShipmentBookDTO, userId: number) { const order = await this.orderModel.findOneBy({ id: orderId }); + const { sales } = data; if (!order) { throw new Error('订单不存在'); } @@ -338,7 +342,7 @@ export class LogisticsService { shipper_country_code: data.details.origin.address.country, receiver: data.details.destination.contact_name, city: data.details.destination.address.city, - province: data.details.destination.address.region, // todo,待确认 + province: data.details.destination.address.region, country: data.details.destination.address.country, postal_code: data.details.destination.address.postal_code.replace(/\s/g, ''), delivery_address: data.details.destination.address.address_line_1, @@ -415,6 +419,9 @@ export class LogisticsService { throw transactionError; } + // 更新产品发货信息 + this.orderService.updateOrderSales(order.id, sales); + return { data: { shipmentId } }; @@ -474,8 +481,8 @@ export class LogisticsService { } } - async getShipment(id: string) { - const orderShipments = await this.orderShipmentModel.find({ + async getShipment(id: number) { + const orderShipments:OrderShipment[] = await this.orderShipmentModel.find({ where: { shipment_id: id }, }); if (!orderShipments || orderShipments.length === 0) return; @@ -507,7 +514,7 @@ export class LogisticsService { } } - async delShipment(id: string, userId: number) { + async delShipment(id: number, userId: number) { const shipment = await this.shipmentModel.findOneBy({ id }); if (!shipment) throw new Error('物流不存在'); @@ -574,7 +581,7 @@ export class LogisticsService { })); } - async getListByTrackingId(id: string) { + async getListByTrackingId(id: number) { const qb = ` SELECT oi.name, diff --git a/src/service/order.service.ts b/src/service/order.service.ts index fd28cab..34bfc1d 100644 --- a/src/service/order.service.ts +++ b/src/service/order.service.ts @@ -29,6 +29,7 @@ import { WpSite } from '../interface'; import { ShipmentItem } from '../entity/shipment_item.entity'; import { UpdateStockDTO } from '../dto/stock.dto'; import { StockService } from './stock.service'; +import { OrderSaleOriginal } from '../entity/order_item_original.entity'; @Provide() export class OrderService { @@ -50,6 +51,9 @@ export class OrderService { @InjectEntityModel(OrderSale) orderSaleModel: Repository; + @InjectEntityModel(OrderSaleOriginal) + orderSaleOriginalModel: Repository; + @InjectEntityModel(WpProduct) wpProductModel: Repository; @@ -214,12 +218,10 @@ export class OrderService { entity.id = existingOrder.id; return entity; } - console.log('/////////////'); entity.orderStatus = this.mapOrderStatus(entity.status); const customer = await this.customerModel.findOne({ where: { email: order.customer_email }, }); - console.log('error? ', this.customerModel); if(!customer) { await this.customerModel.save({ email: order.customer_email, @@ -1182,6 +1184,21 @@ export class OrderService { } } + // update order_sale_origin if not exist + + try { + const order_sale_origin_count = await this.orderSaleOriginalModel.countBy({ orderId: id }); + if (order_sale_origin_count === 0) { + sales.forEach(async sale => { + const { id: saleId, ...saleData } = sale; + await this.orderSaleOriginalModel.save(saleData); + }); + } + + } catch (error) { + console.log('create order sale origin error: ', error.message); + } + return { ...order, siteName: site.siteName, @@ -1297,6 +1314,7 @@ export class OrderService { return dataSource.transaction(async manager => { const orderRepo = manager.getRepository(Order); const orderSaleRepo = manager.getRepository(OrderSale); + const OrderSaleOriginalRepo = manager.getRepository(OrderSaleOriginal); const productRepo = manager.getRepository(Product); const order = await orderRepo.save({ siteId: '-1', @@ -1314,7 +1332,7 @@ export class OrderService { }); for (const sale of sales) { const product = await productRepo.findOne({ where: { sku: sale.sku } }); - await orderSaleRepo.save({ + const saleItem = { orderId: order.id, siteId: '-1', externalOrderItemId: '-1', @@ -1322,7 +1340,9 @@ export class OrderService { name: product.name, sku: sale.sku, quantity: sale.quantity, - }); + }; + await orderSaleRepo.save(saleItem); + await OrderSaleOriginalRepo.save(saleItem); } }); } @@ -1363,4 +1383,42 @@ export class OrderService { pageSize, }; } + + async updateOrderSales(orderId: number, sales: OrderSale[]) { + 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 productRepo = manager.getRepository(Product); + + const order = await orderRepo.findOneBy({ id: orderId }); + let product:Product; + await orderSaleRepo.delete({ orderId }); + for (const sale of 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 + }); + }; + }).catch(error => { + transactionError = error; + }); + + if (transactionError !== undefined) { + throw new Error(`更新物流信息错误:${transactionError.message}`); + } + return true; + } catch (error) { + throw new Error(`更新发货产品失败:${error.message}`); + } + } + }