feat(order_shipping): 添加订单配送信息实体和相关接口
- 添加 order_shipping.entity.ts 实体类定义 - 更新 shopyy.adapter.ts 支持订单配送数据处理 - 更新 woocommerce.adapter.ts 支持配送信息适配 - 完善 site-adapter.interface.ts 接口定义 - 优化 order.service.ts 配送相关逻辑 - 更新相关 DTO 类以支持配送信息
This commit is contained in:
parent
2f99e27f0f
commit
84beb1a65e
|
|
@ -17,6 +17,7 @@ import {
|
|||
UnifiedWebhookPaginationDTO,
|
||||
CreateWebhookDTO,
|
||||
UpdateWebhookDTO,
|
||||
UnifiedShippingLineDTO,
|
||||
} from '../dto/site-api.dto';
|
||||
import {
|
||||
ShopyyCustomer,
|
||||
|
|
@ -179,6 +180,7 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
city: shipping.city || item.shipping_city || '',
|
||||
state: shipping.province || item.shipping_zone || '',
|
||||
postcode: shipping.zip || item.shipping_postcode || '',
|
||||
method_title: item.payment_method || '',
|
||||
country:
|
||||
shipping.country_name ||
|
||||
shipping.country_code ||
|
||||
|
|
@ -186,6 +188,19 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
'',
|
||||
};
|
||||
|
||||
// 构建送货地址对象
|
||||
const shipping_lines: UnifiedShippingLineDTO[] = [
|
||||
{
|
||||
id: item.fulfillments?.[0]?.id || 0,
|
||||
method_title: item.payment_method || '',
|
||||
method_id: item.payment_method || '',
|
||||
total: item.current_shipping_price.toExponential(2) || '0.00',
|
||||
total_tax: '0.00',
|
||||
taxes: [],
|
||||
meta_data: [],
|
||||
},
|
||||
];
|
||||
|
||||
// 格式化地址为字符串
|
||||
const formatAddress = (addr: UnifiedAddressDTO) => {
|
||||
return [
|
||||
|
|
@ -242,6 +257,7 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
customer_name:
|
||||
item.customer_name || `${item.firstname} ${item.lastname}`.trim(),
|
||||
email: item.customer_email || item.email,
|
||||
customer_email: item.customer_email || item.email,
|
||||
line_items: lineItems,
|
||||
sales: lineItems, // 兼容前端
|
||||
billing: billingObj,
|
||||
|
|
@ -249,9 +265,13 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
billing_full_address: formatAddress(billingObj),
|
||||
shipping_full_address: formatAddress(shippingObj),
|
||||
payment_method: item.payment_method,
|
||||
shipping_lines: item.fulfillments || [],
|
||||
shipping_lines: shipping_lines || [],
|
||||
fee_lines: item.fee_lines || [],
|
||||
coupon_lines: item.coupon_lines || [],
|
||||
customer_ip_address: item.ip || '',
|
||||
device_type: item.source_device || '',
|
||||
utm_source: item.utm_source || '',
|
||||
source_type: 'shopyy',
|
||||
date_paid: typeof item.pay_at === 'number'
|
||||
? item.pay_at === 0 ? null : new Date(item.pay_at * 1000).toISOString()
|
||||
: null,
|
||||
|
|
|
|||
|
|
@ -420,10 +420,17 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
shipping_lines: item.shipping_lines,
|
||||
fee_lines: item.fee_lines,
|
||||
coupon_lines: item.coupon_lines,
|
||||
utm_source: item?.meta_data?.find(el => el.key === '_wc_order_attribution_utm_source')?.value || '',
|
||||
device_type: item?.meta_data?.find(el => el.key === '_wc_order_attribution_device_type')?.value || '',
|
||||
customer_email: item?.billing?.email || '',
|
||||
source_type: item?.meta_data?.find(el => el.key === '_wc_order_attribution_source_type')?.value || '',
|
||||
raw: item,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private mapSubscription(item: WooSubscription): UnifiedSubscriptionDTO {
|
||||
// 将 WooCommerce 订阅数据映射为统一订阅DTO
|
||||
// 若缺少创建时间则回退为开始时间
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ export interface ShopyyOrder {
|
|||
total_amount?: string | number;
|
||||
current_total_price?: string | number;
|
||||
current_subtotal_price?: string | number;
|
||||
current_shipping_price?: string | number;
|
||||
current_shipping_price?: number;
|
||||
current_tax_price?: string | number;
|
||||
current_coupon_price?: string | number;
|
||||
current_payment_price?: string | number;
|
||||
|
|
@ -247,7 +247,9 @@ export interface ShopyyOrder {
|
|||
date_updated?: string;
|
||||
last_modified?: string;
|
||||
// 支付时间
|
||||
pay_at?: number ;
|
||||
pay_at?: number | null;
|
||||
ip?: string;
|
||||
utm_source?: string;
|
||||
// 配送方式
|
||||
shipping_lines?: Array<ShopyyShippingLineDTO>;
|
||||
// 费用项
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ export class UnifiedAddressDTO {
|
|||
|
||||
@ApiProperty({ description: '电话', required: false })
|
||||
phone?: string;
|
||||
|
||||
@ApiProperty({ description: '配送方式', required: false })
|
||||
method_title?: string;
|
||||
}
|
||||
|
||||
export class UnifiedOrderLineItemDTO {
|
||||
|
|
@ -279,6 +282,9 @@ export class UnifiedOrderDTO {
|
|||
@ApiProperty({ description: '客户邮箱' })
|
||||
email: string;
|
||||
|
||||
@ApiProperty({ description: '客户邮箱' })
|
||||
customer_email: string;
|
||||
|
||||
@ApiProperty({ description: '订单项(具体的商品)', type: () => [UnifiedOrderLineItemDTO] })
|
||||
line_items: UnifiedOrderLineItemDTO[];
|
||||
|
||||
|
|
@ -323,7 +329,19 @@ export class UnifiedOrderDTO {
|
|||
coupon_lines?: UnifiedCouponLineDTO[];
|
||||
|
||||
@ApiProperty({ description: '支付时间', required: false })
|
||||
date_paid?: string ;
|
||||
date_paid?: string | null;
|
||||
|
||||
@ApiProperty({ description: '客户IP地址', required: false })
|
||||
customer_ip_address?: string;
|
||||
|
||||
@ApiProperty({ description: 'UTM来源', required: false })
|
||||
utm_source?: string;
|
||||
|
||||
@ApiProperty({ description: '设备类型', required: false })
|
||||
device_type?: string;
|
||||
|
||||
@ApiProperty({ description: '来源类型', required: false })
|
||||
source_type?: string;
|
||||
}
|
||||
|
||||
export class UnifiedShippingLineDTO {
|
||||
|
|
@ -350,7 +368,6 @@ export class UnifiedShippingLineDTO {
|
|||
meta_data?: any[];
|
||||
|
||||
}
|
||||
|
||||
export class UnifiedFeeLineDTO {
|
||||
// 费用项DTO用于承载统一费用项数据
|
||||
@ApiProperty({ description: '费用项ID' })
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ export class OrderShipping {
|
|||
method_id: string;
|
||||
|
||||
@ApiProperty()
|
||||
@Column()
|
||||
@Column({ nullable: true })
|
||||
@Expose()
|
||||
instance_id: string;
|
||||
instance_id?: string;
|
||||
|
||||
@ApiProperty()
|
||||
@Column('decimal', { precision: 10, scale: 2 })
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import { SiteApiService } from './site-api.service';
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { UnifiedOrderDTO } from '../dto/site-api.dto';
|
||||
@Provide()
|
||||
export class OrderService {
|
||||
|
||||
|
|
@ -137,7 +138,10 @@ export class OrderService {
|
|||
async syncOrderById(siteId: number, orderId: string) {
|
||||
try {
|
||||
// 调用 WooCommerce API 获取订单
|
||||
const order = await this.wpService.getOrder(siteId, orderId);
|
||||
//const order = await this.wpService.getOrder(siteId, orderId);
|
||||
const order = await (await this.siteApiService.getAdapter(siteId)).getOrder(
|
||||
orderId,
|
||||
);
|
||||
await this.syncSingleOrder(siteId, order, true);
|
||||
return { success: true, message: '同步成功' };
|
||||
} catch (error) {
|
||||
|
|
@ -220,6 +224,7 @@ export class OrderService {
|
|||
externalOrderId,
|
||||
orderItems: line_items,
|
||||
});
|
||||
console.log('同步进单个订单1')
|
||||
await this.saveOrderRefunds({
|
||||
siteId,
|
||||
orderId,
|
||||
|
|
@ -238,6 +243,7 @@ export class OrderService {
|
|||
externalOrderId,
|
||||
coupon_lines,
|
||||
});
|
||||
console.log('同步进单个订单2')
|
||||
await this.saveOrderShipping({
|
||||
siteId,
|
||||
orderId,
|
||||
|
|
@ -273,27 +279,14 @@ export class OrderService {
|
|||
}
|
||||
}
|
||||
|
||||
async saveOrder(siteId: number, order: Order): Promise<Order> {
|
||||
order.externalOrderId = String(order.id);
|
||||
order.siteId = siteId;
|
||||
delete order.id;
|
||||
order.device_type =
|
||||
order?.meta_data?.find(
|
||||
el => el.key === '_wc_order_attribution_device_type'
|
||||
)?.value || '';
|
||||
order.source_type =
|
||||
order?.meta_data?.find(
|
||||
el => el.key === '_wc_order_attribution_source_type'
|
||||
)?.value || '';
|
||||
order.utm_source =
|
||||
order?.meta_data?.find(
|
||||
el => el.key === '_wc_order_attribution_utm_source'
|
||||
)?.value || '';
|
||||
order.customer_email = order?.billing?.email || order?.shipping?.email;
|
||||
async saveOrder(siteId: number, order: UnifiedOrderDTO): Promise<Order> {
|
||||
const externalOrderId = String(order.id)
|
||||
delete order.id
|
||||
|
||||
// order.billing_phone = order?.billing?.phone || order?.shipping?.phone;
|
||||
const entity = plainToClass(Order, order);
|
||||
const entity = plainToClass(Order, {...order, externalOrderId, siteId});
|
||||
const existingOrder = await this.orderModel.findOne({
|
||||
where: { externalOrderId: order.externalOrderId, siteId: siteId },
|
||||
where: { externalOrderId, siteId: siteId },
|
||||
});
|
||||
if (existingOrder) {
|
||||
if (this.canUpdateErpStatus(existingOrder.orderStatus)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue