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,
|
UnifiedWebhookPaginationDTO,
|
||||||
CreateWebhookDTO,
|
CreateWebhookDTO,
|
||||||
UpdateWebhookDTO,
|
UpdateWebhookDTO,
|
||||||
|
UnifiedShippingLineDTO,
|
||||||
} from '../dto/site-api.dto';
|
} from '../dto/site-api.dto';
|
||||||
import {
|
import {
|
||||||
ShopyyCustomer,
|
ShopyyCustomer,
|
||||||
|
|
@ -179,6 +180,7 @@ export class ShopyyAdapter implements ISiteAdapter {
|
||||||
city: shipping.city || item.shipping_city || '',
|
city: shipping.city || item.shipping_city || '',
|
||||||
state: shipping.province || item.shipping_zone || '',
|
state: shipping.province || item.shipping_zone || '',
|
||||||
postcode: shipping.zip || item.shipping_postcode || '',
|
postcode: shipping.zip || item.shipping_postcode || '',
|
||||||
|
method_title: item.payment_method || '',
|
||||||
country:
|
country:
|
||||||
shipping.country_name ||
|
shipping.country_name ||
|
||||||
shipping.country_code ||
|
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) => {
|
const formatAddress = (addr: UnifiedAddressDTO) => {
|
||||||
return [
|
return [
|
||||||
|
|
@ -242,6 +257,7 @@ export class ShopyyAdapter implements ISiteAdapter {
|
||||||
customer_name:
|
customer_name:
|
||||||
item.customer_name || `${item.firstname} ${item.lastname}`.trim(),
|
item.customer_name || `${item.firstname} ${item.lastname}`.trim(),
|
||||||
email: item.customer_email || item.email,
|
email: item.customer_email || item.email,
|
||||||
|
customer_email: item.customer_email || item.email,
|
||||||
line_items: lineItems,
|
line_items: lineItems,
|
||||||
sales: lineItems, // 兼容前端
|
sales: lineItems, // 兼容前端
|
||||||
billing: billingObj,
|
billing: billingObj,
|
||||||
|
|
@ -249,9 +265,13 @@ export class ShopyyAdapter implements ISiteAdapter {
|
||||||
billing_full_address: formatAddress(billingObj),
|
billing_full_address: formatAddress(billingObj),
|
||||||
shipping_full_address: formatAddress(shippingObj),
|
shipping_full_address: formatAddress(shippingObj),
|
||||||
payment_method: item.payment_method,
|
payment_method: item.payment_method,
|
||||||
shipping_lines: item.fulfillments || [],
|
shipping_lines: shipping_lines || [],
|
||||||
fee_lines: item.fee_lines || [],
|
fee_lines: item.fee_lines || [],
|
||||||
coupon_lines: item.coupon_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'
|
date_paid: typeof item.pay_at === 'number'
|
||||||
? item.pay_at === 0 ? null : new Date(item.pay_at * 1000).toISOString()
|
? item.pay_at === 0 ? null : new Date(item.pay_at * 1000).toISOString()
|
||||||
: null,
|
: null,
|
||||||
|
|
|
||||||
|
|
@ -420,10 +420,17 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
||||||
shipping_lines: item.shipping_lines,
|
shipping_lines: item.shipping_lines,
|
||||||
fee_lines: item.fee_lines,
|
fee_lines: item.fee_lines,
|
||||||
coupon_lines: item.coupon_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,
|
raw: item,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private mapSubscription(item: WooSubscription): UnifiedSubscriptionDTO {
|
private mapSubscription(item: WooSubscription): UnifiedSubscriptionDTO {
|
||||||
// 将 WooCommerce 订阅数据映射为统一订阅DTO
|
// 将 WooCommerce 订阅数据映射为统一订阅DTO
|
||||||
// 若缺少创建时间则回退为开始时间
|
// 若缺少创建时间则回退为开始时间
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export interface ShopyyOrder {
|
||||||
total_amount?: string | number;
|
total_amount?: string | number;
|
||||||
current_total_price?: string | number;
|
current_total_price?: string | number;
|
||||||
current_subtotal_price?: string | number;
|
current_subtotal_price?: string | number;
|
||||||
current_shipping_price?: string | number;
|
current_shipping_price?: number;
|
||||||
current_tax_price?: string | number;
|
current_tax_price?: string | number;
|
||||||
current_coupon_price?: string | number;
|
current_coupon_price?: string | number;
|
||||||
current_payment_price?: string | number;
|
current_payment_price?: string | number;
|
||||||
|
|
@ -247,7 +247,9 @@ export interface ShopyyOrder {
|
||||||
date_updated?: string;
|
date_updated?: string;
|
||||||
last_modified?: string;
|
last_modified?: string;
|
||||||
// 支付时间
|
// 支付时间
|
||||||
pay_at?: number ;
|
pay_at?: number | null;
|
||||||
|
ip?: string;
|
||||||
|
utm_source?: string;
|
||||||
// 配送方式
|
// 配送方式
|
||||||
shipping_lines?: Array<ShopyyShippingLineDTO>;
|
shipping_lines?: Array<ShopyyShippingLineDTO>;
|
||||||
// 费用项
|
// 费用项
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,9 @@ export class UnifiedAddressDTO {
|
||||||
|
|
||||||
@ApiProperty({ description: '电话', required: false })
|
@ApiProperty({ description: '电话', required: false })
|
||||||
phone?: string;
|
phone?: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '配送方式', required: false })
|
||||||
|
method_title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UnifiedOrderLineItemDTO {
|
export class UnifiedOrderLineItemDTO {
|
||||||
|
|
@ -279,6 +282,9 @@ export class UnifiedOrderDTO {
|
||||||
@ApiProperty({ description: '客户邮箱' })
|
@ApiProperty({ description: '客户邮箱' })
|
||||||
email: string;
|
email: string;
|
||||||
|
|
||||||
|
@ApiProperty({ description: '客户邮箱' })
|
||||||
|
customer_email: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '订单项(具体的商品)', type: () => [UnifiedOrderLineItemDTO] })
|
@ApiProperty({ description: '订单项(具体的商品)', type: () => [UnifiedOrderLineItemDTO] })
|
||||||
line_items: UnifiedOrderLineItemDTO[];
|
line_items: UnifiedOrderLineItemDTO[];
|
||||||
|
|
||||||
|
|
@ -323,7 +329,19 @@ export class UnifiedOrderDTO {
|
||||||
coupon_lines?: UnifiedCouponLineDTO[];
|
coupon_lines?: UnifiedCouponLineDTO[];
|
||||||
|
|
||||||
@ApiProperty({ description: '支付时间', required: false })
|
@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 {
|
export class UnifiedShippingLineDTO {
|
||||||
|
|
@ -350,7 +368,6 @@ export class UnifiedShippingLineDTO {
|
||||||
meta_data?: any[];
|
meta_data?: any[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UnifiedFeeLineDTO {
|
export class UnifiedFeeLineDTO {
|
||||||
// 费用项DTO用于承载统一费用项数据
|
// 费用项DTO用于承载统一费用项数据
|
||||||
@ApiProperty({ description: '费用项ID' })
|
@ApiProperty({ description: '费用项ID' })
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ export class OrderShipping {
|
||||||
method_id: string;
|
method_id: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@Column()
|
@Column({ nullable: true })
|
||||||
@Expose()
|
@Expose()
|
||||||
instance_id: string;
|
instance_id?: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@Column('decimal', { precision: 10, scale: 2 })
|
@Column('decimal', { precision: 10, scale: 2 })
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import { SiteApiService } from './site-api.service';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
import { UnifiedOrderDTO } from '../dto/site-api.dto';
|
||||||
@Provide()
|
@Provide()
|
||||||
export class OrderService {
|
export class OrderService {
|
||||||
|
|
||||||
|
|
@ -137,7 +138,10 @@ export class OrderService {
|
||||||
async syncOrderById(siteId: number, orderId: string) {
|
async syncOrderById(siteId: number, orderId: string) {
|
||||||
try {
|
try {
|
||||||
// 调用 WooCommerce API 获取订单
|
// 调用 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);
|
await this.syncSingleOrder(siteId, order, true);
|
||||||
return { success: true, message: '同步成功' };
|
return { success: true, message: '同步成功' };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -220,6 +224,7 @@ export class OrderService {
|
||||||
externalOrderId,
|
externalOrderId,
|
||||||
orderItems: line_items,
|
orderItems: line_items,
|
||||||
});
|
});
|
||||||
|
console.log('同步进单个订单1')
|
||||||
await this.saveOrderRefunds({
|
await this.saveOrderRefunds({
|
||||||
siteId,
|
siteId,
|
||||||
orderId,
|
orderId,
|
||||||
|
|
@ -238,6 +243,7 @@ export class OrderService {
|
||||||
externalOrderId,
|
externalOrderId,
|
||||||
coupon_lines,
|
coupon_lines,
|
||||||
});
|
});
|
||||||
|
console.log('同步进单个订单2')
|
||||||
await this.saveOrderShipping({
|
await this.saveOrderShipping({
|
||||||
siteId,
|
siteId,
|
||||||
orderId,
|
orderId,
|
||||||
|
|
@ -273,27 +279,14 @@ export class OrderService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveOrder(siteId: number, order: Order): Promise<Order> {
|
async saveOrder(siteId: number, order: UnifiedOrderDTO): Promise<Order> {
|
||||||
order.externalOrderId = String(order.id);
|
const externalOrderId = String(order.id)
|
||||||
order.siteId = siteId;
|
delete order.id
|
||||||
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;
|
|
||||||
// order.billing_phone = order?.billing?.phone || order?.shipping?.phone;
|
// 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({
|
const existingOrder = await this.orderModel.findOne({
|
||||||
where: { externalOrderId: order.externalOrderId, siteId: siteId },
|
where: { externalOrderId, siteId: siteId },
|
||||||
});
|
});
|
||||||
if (existingOrder) {
|
if (existingOrder) {
|
||||||
if (this.canUpdateErpStatus(existingOrder.orderStatus)) {
|
if (this.canUpdateErpStatus(existingOrder.orderStatus)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue