diff --git a/package-lock.json b/package-lock.json index 405c79b..ae4071c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -523,6 +523,23 @@ "node": ">=18" } }, + "node_modules/@faker-js/faker": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.2.0.tgz", + "integrity": "sha512-rTXwAsIxpCqzUnZvrxVh3L0QA0NzToqWBLAhV+zDV3MIIwiQhAZHMdPCIaj5n/yADu/tyk12wIPgL6YHGXJP+g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0", + "npm": ">=10" + } + }, "node_modules/@hapi/bourne": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/@hapi/bourne/-/bourne-3.0.0.tgz", diff --git a/src/adapter/woocommerce.adapter.ts b/src/adapter/woocommerce.adapter.ts index e3ffcaa..f14d7d3 100644 --- a/src/adapter/woocommerce.adapter.ts +++ b/src/adapter/woocommerce.adapter.ts @@ -17,6 +17,7 @@ import { UnifiedVariationPaginationDTO, CreateReviewDTO, UpdateReviewDTO, + FulfillmentDTO, } from '../dto/site-api.dto'; import { UnifiedPaginationDTO, UnifiedSearchParamsDTO } from '../dto/api.dto'; import { @@ -29,10 +30,12 @@ import { WooOrderSearchParams, WooProductSearchParams, WpMediaGetListParams, + WooFulfillment, } from '../dto/woocommerce.dto'; import { Site } from '../entity/site.entity'; import { WPService } from '../service/wp.service'; import { BatchOperationDTO, BatchOperationResultDTO } from '../dto/batch.dto'; +import { toArray, toNumber } from '../utils/trans.util'; export class WooCommerceAdapter implements ISiteAdapter { // 构造函数接收站点配置与服务实例 @@ -330,22 +333,11 @@ export class WooCommerceAdapter implements ISiteAdapter { // } const mapped: any = { ...(params.search ? { search: params.search } : {}), - // ...(orderBy ? { orderBy } : {}), page, per_page, }; - const toArray = (value: any): any[] => { - if (Array.isArray(value)) return value; - if (value === undefined || value === null) return []; - return String(value).split(',').map(v => v.trim()).filter(Boolean); - }; - const toNumber = (value: any): number | undefined => { - if (value === undefined || value === null || value === '') return undefined; - const n = Number(value); - return Number.isFinite(n) ? n : undefined; - }; // 时间过滤参数 if (where.after ?? where.date_created_after ?? where.created_after) mapped.after = String(where.after ?? where.date_created_after ?? where.created_after); @@ -356,8 +348,7 @@ export class WooCommerceAdapter implements ISiteAdapter { // 集合过滤参数 if (where.exclude) mapped.exclude = toArray(where.exclude); - if (where.include) mapped.include = toArray(where.include); - if (where.ids) mapped.include = toArray(where.ids); + if (where.ids || where.number || where.id || where.include) mapped.include = [...new Set([where.number,where.id,...toArray(where.ids),...toArray(where.include)])].filter(Boolean); if (toNumber(where.offset) !== undefined) mapped.offset = Number(where.offset); if (where.parent ?? where.parentId) mapped.parent = toArray(where.parent ?? where.parentId); if (where.parent_exclude ?? where.parentExclude) mapped.parent_exclude = toArray(where.parent_exclude ?? where.parentExclude); @@ -408,13 +399,11 @@ export class WooCommerceAdapter implements ISiteAdapter { // 包含账单地址与收货地址以及创建与更新时间 // 映射物流追踪信息,将后端格式转换为前端期望的格式 - const fulfillments = (item.fulfillments || []).map((track: any) => ({ - tracking_number: track.tracking_number || '', - shipping_provider: track.shipping_provider || '', - shipping_method: track.shipping_method || '', - status: track.status || '', - date_created: track.date_created || '', - items: track.items || [], + const fulfillments = (item.fulfillments || []).map((track) => ({ + tracking_id: track.tracking_id, + tracking_number: track.tracking_number, + shipping_provider: track.tracking_provider, + date_created: track.data_sipped, })); return { @@ -541,54 +530,25 @@ export class WooCommerceAdapter implements ISiteAdapter { return await this.wpService.getFulfillments(this.site, String(orderId)); } - async createOrderFulfillment(orderId: string | number, data: { - tracking_number: string; - shipping_provider: string; - shipping_method?: string; - status?: string; - date_created?: string; - items?: Array<{ - order_item_id: number; - quantity: number; - }>; - }): Promise { - const shipmentData: any = { - shipping_provider: data.shipping_provider, + async createOrderFulfillment(orderId: string | number, data: FulfillmentDTO): Promise { + const shipmentData: Partial = { + tracking_provider: data.shipping_provider, tracking_number: data.tracking_number, - }; - - if (data.shipping_method) { - shipmentData.shipping_method = data.shipping_method; + data_sipped: data.date_created, + // items: data.items, } - - if (data.status) { - shipmentData.status = data.status; - } - - if (data.date_created) { - shipmentData.date_created = data.date_created; - } - - if (data.items) { - shipmentData.items = data.items; - } - const response = await this.wpService.createFulfillment(this.site, String(orderId), shipmentData); return response.data; } - async updateOrderFulfillment(orderId: string | number, fulfillmentId: string, data: { - tracking_number?: string; - shipping_provider?: string; - shipping_method?: string; - status?: string; - date_created?: string; - items?: Array<{ - order_item_id: number; - quantity: number; - }>; - }): Promise { - return await this.wpService.updateFulfillment(this.site, String(orderId), fulfillmentId, data); + async updateOrderFulfillment(orderId: string | number, fulfillmentId: string, data: FulfillmentDTO): Promise { + const shipmentData: Partial = { + tracking_provider: data.shipping_provider, + tracking_number: data.tracking_number, + data_sipped: data.date_created, + // items: data.items, + } + return await this.wpService.updateFulfillment(this.site, String(orderId), fulfillmentId, shipmentData); } async deleteOrderFulfillment(orderId: string | number, fulfillmentId: string): Promise { diff --git a/src/dto/site-api.dto.ts b/src/dto/site-api.dto.ts index b02cd43..a5b2fc7 100644 --- a/src/dto/site-api.dto.ts +++ b/src/dto/site-api.dto.ts @@ -799,14 +799,16 @@ export class UpdateWebhookDTO { export class FulfillmentItemDTO { - @ApiProperty({ description: '订单项ID' }) + @ApiProperty({ description: '订单项ID' ,required: false}) order_item_id: number; - @ApiProperty({ description: '数量' }) + @ApiProperty({ description: '数量' ,required:false}) quantity: number; } export class FulfillmentDTO { + @ApiProperty({ description: '物流id', required: false }) + tracking_id?: string; @ApiProperty({ description: '物流单号', required: false }) tracking_number?: string; diff --git a/src/dto/woocommerce.dto.ts b/src/dto/woocommerce.dto.ts index f042838..c48b85f 100644 --- a/src/dto/woocommerce.dto.ts +++ b/src/dto/woocommerce.dto.ts @@ -370,17 +370,24 @@ export interface WooOrder { date_modified?: string; date_modified_gmt?: string; // 物流追踪信息 - fulfillments?: Array<{ - tracking_number?: string; - shipping_provider?: string; - shipping_method?: string; - status?: string; - date_created?: string; - items?: Array<{ - order_item_id?: number; - quantity?: number; - }>; - }>; + fulfillments?: WooFulfillment[]; +} +// 这个是一个插件的物流追踪信息 +// 接口: +export interface WooFulfillment { + data_sipped: string; + tracking_id: string; + tracking_link: string; + tracking_number: string; + tracking_provider: string; +} +// https://docs.zorem.com/docs/ast-free/developers/adding-tracking-info-to-orders/ +export interface WooFulfillmentCreateParams { + order_id: string; + tracking_provider: string; + tracking_number: string; + date_shipped?: string; + status_shipped?: string; } export interface WooOrderRefund { id?: number; @@ -552,7 +559,8 @@ export interface WooOrderSearchParams { order: string; orderby: string; parant: string[]; - status: (WooOrderStatusSearchParams)[]; + parent_exclude: string[]; + status: WooOrderStatusSearchParams[]; customer: number; product: number; dp: number; diff --git a/src/utils/trans.util.ts b/src/utils/trans.util.ts new file mode 100644 index 0000000..57063e3 --- /dev/null +++ b/src/utils/trans.util.ts @@ -0,0 +1,11 @@ +export const toArray = (value: any): any[] => { + if (Array.isArray(value)) return value; + if (value === undefined || value === null) return []; + return String(value).split(',').map(v => v.trim()).filter(Boolean); +}; + +export const toNumber = (value: any): number | undefined => { + if (value === undefined || value === null || value === '') return undefined; + const n = Number(value); + return Number.isFinite(n) ? n : undefined; +}; \ No newline at end of file