Compare commits

..

1 Commits

Author SHA1 Message Date
tikkhun 6f35d5d9c9 feat(订单): 添加获取订单总数功能
实现订单总数统计接口,包括:
1. 在ISiteAdapter接口添加countOrders方法
2. 在WooCommerce和Shopyy适配器中实现该方法
3. 添加控制器端点暴露该功能
4. 优化订单查询参数映射逻辑

refactor(Shopyy): 重构搜索参数映射逻辑

将通用的搜索参数映射逻辑提取为独立方法,提高代码复用性

refactor(interface): 重构站点适配器接口,按功能模块组织方法

重构 ISiteAdapter 接口,将相关方法按功能模块(客户、媒体、订单、产品等)分组
移除废弃的 fulfillOrder 方法
新增多个数据映射方法以支持统一数据格式转换

refactor(api): 统一接口参数为对象形式并支持多条件查询

重构所有接口方法,将直接传递id参数改为接受where条件对象
支持通过id、sku、email等多条件查询实体
优化产品服务逻辑,支持通过sku直接查询产品
统一各适配器实现,确保接口一致性

feat(订单): 添加获取订单总数功能

实现订单总数统计接口,包括:
1. 在ISiteAdapter接口添加countOrders方法
2. 在WooCommerce和Shopyy适配器中实现该方法
3. 添加控制器端点暴露该功能
4. 优化订单查询参数映射逻辑

refactor(Shopyy): 重构搜索参数映射逻辑

将通用的搜索参数映射逻辑提取为独立方法,提高代码复用性

refactor(interface): 重构站点适配器接口,按功能模块组织方法

重构 ISiteAdapter 接口,将相关方法按功能模块(客户、媒体、订单、产品等)分组
移除废弃的 fulfillOrder 方法
新增多个数据映射方法以支持统一数据格式转换

Test

refactor(api): 统一接口参数为对象形式并支持多条件查询

重构所有接口方法,将直接传递id参数改为接受where条件对象
支持通过id、sku、email等多条件查询实体
优化产品服务逻辑,支持通过sku直接查询产品
统一各适配器实现,确保接口一致性

feat(shopyy): 实现全量商品查询功能并优化产品相关逻辑

- 新增ShopyyAllProductQuery类支持全量商品查询参数
- 实现getAllProducts方法支持带条件查询
- 优化getProductBySku方法使用新查询接口
- 公开request方法便于子类调用
- 增加错误日志记录产品查找失败情况
- 修复产品permalink生成逻辑

docs: 统一中文括号格式为全角括号

将代码中的中文括号格式从半角"()"统一修改为全角"()",并删除测试文档文件test-site-sku-methods.md

chore: config.local 还原

docs(dto): 修正注释中的中文括号格式

docs(dto): 修正注释中的括号格式

docs: 修正中文标点符号和注释格式

统一将中文注释和文档中的全角括号和冒号改为半角格式
修正部分TODO注释的标点符号
统一接口文档中的描述符号格式
2026-01-08 20:21:33 +08:00
3 changed files with 53 additions and 46 deletions

View File

@ -403,6 +403,9 @@ export class ShopyyAdapter implements ISiteAdapter {
mapCreateOrderParams(data: Partial<UnifiedOrderDTO>): any {
return data
}
mapProductQuery(query: UnifiedSearchParamsDTO): ShopyyProductQuery {
return this.mapSearchParams(query)
}
mapUpdateOrderParams(data: Partial<UnifiedOrderDTO>): any {
// 构建 ShopYY 订单更新参数(仅包含传入的字段)
@ -977,6 +980,18 @@ export class ShopyyAdapter implements ISiteAdapter {
return product
}
// 通过sku获取产品详情的私有方法
private async getProductBySku(sku: string): Promise<UnifiedProductDTO> {
// 使用Shopyy API的搜索功能通过sku查询产品
const response = await this.getAllProducts({ where: {sku} });
console.log('getProductBySku', response)
const product = response?.[0]
if (!product) {
throw new Error(`未找到sku为${sku}的产品`);
}
return product
}
async batchProcessProducts(
data: { create?: any[]; update?: any[]; delete?: Array<string | number> }
): Promise<any> {
@ -1179,7 +1194,10 @@ export class ShopyyAdapter implements ISiteAdapter {
}
// ========== Webhook映射方法 ==========
<<<<<<< HEAD
=======
>>>>>>> 89d7d78 (refactor(api): )
mapUnifiedToPlatformWebhook(data: Partial<UnifiedWebhookDTO>) {
return data

View File

@ -55,6 +55,15 @@ export class WooCommerceAdapter implements ISiteAdapter {
mapUpdateVariationParams(data: UpdateVariationDTO) {
throw new Error('Method not implemented.');
}
batchProcessProducts?(data: BatchOperationDTO): Promise<BatchOperationResultDTO> {
throw new Error('Method not implemented.');
}
mapCreateVariationParams(data: CreateVariationDTO) {
throw new Error('Method not implemented.');
}
mapUpdateVariationParams(data: UpdateVariationDTO) {
throw new Error('Method not implemented.');
}
// ========== 客户映射方法 ==========
@ -394,53 +403,30 @@ export class WooCommerceAdapter implements ISiteAdapter {
// 将 WooCommerce 订单数据映射为统一订单DTO
// 包含账单地址与收货地址以及创建与更新时间
// 映射物流追踪信息,将后端格式转换为前端期望的格式
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 || [],
}));
// 产品操作方法
async getProduct(id: string | number): Promise<UnifiedProductDTO> {
// 获取单个产品详情并映射为统一产品DTO
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.get(`products/${id}`);
const product = res.data;
return {
id: item.id,
number: item.number,
status: item.status,
currency: item.currency,
total: item.total,
customer_id: item.customer_id,
customer_email: item.billing?.email || '', // TODO 与 email 重复 保留一个即可
email: item.billing?.email || '',
customer_name: `${item.billing?.first_name || ''} ${item.billing?.last_name || ''}`.trim(),
refunds: item.refunds?.map?.(refund => ({
id: refund.id,
reason: refund.reason,
total: refund.total,
})),
line_items: (item.line_items as any[]).map(li => ({
...li,
productId: li.product_id,
})),
customer_ip_address: item.customer_ip_address ?? '',
date_paid: item.date_paid ?? '',
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 || '',
source_type: item?.meta_data?.find(el => el.key === '_wc_order_attribution_source_type')?.value || '',
billing: item.billing,
shipping: item.shipping,
billing_full_address: this.buildFullAddress(item.billing),
shipping_full_address: this.buildFullAddress(item.shipping),
payment_method: item.payment_method_title,
date_created: item.date_created,
date_modified: item.date_modified,
shipping_lines: item.shipping_lines,
fee_lines: item.fee_lines,
coupon_lines: item.coupon_lines,
fulfillments,
raw: item,
};
// 如果产品类型是 variable 且有变体 ID 列表,则加载完整的变体数据
if (product.type === 'variable' && product.variations && Array.isArray(product.variations) && product.variations.length > 0) {
try {
// 批量获取该产品的所有变体数据
const variations = await this.wpService.sdkGetAll(
api,
`products/${product.id}/variations`
);
// 将完整的变体数据添加到产品对象中
product.variations = variations;
} catch (error) {
// 如果获取变体失败,保持原有的 ID 数组
console.error(`获取产品 ${product.id} 的变体数据失败:`, error);
}
}
return this.mapProduct(product);
}
// 订单操作方法

View File

@ -36,11 +36,13 @@ export interface ISiteAdapter {
mapUnifiedToPlatformCustomer(data: Partial<UnifiedCustomerDTO>): any;
/**
*
*
*/
getCustomer(where: Partial<Pick<UnifiedCustomerDTO, 'id' | 'email' | 'phone'>>): Promise<UnifiedCustomerDTO>;
/**
*
*
*/
getCustomers(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedCustomerDTO>>;
@ -68,6 +70,7 @@ export interface ISiteAdapter {
/**
*
*/
batchProcessCustomers?(data: BatchOperationDTO): Promise<BatchOperationResultDTO>;
// ========== 媒体映射方法 ==========