feat(adapter): 添加getAll方法支持批量获取数据
实现WooCommerceAdapter中的getAllProducts、getAllOrders等方法 添加ISiteAdapter接口中的对应方法定义 更新customer.service使用getAllCustomers方法
This commit is contained in:
parent
8e7ec2372d
commit
8f7f35c538
|
|
@ -16,6 +16,6 @@ yarn.lock
|
|||
**/config.local.ts
|
||||
container
|
||||
scripts
|
||||
ai
|
||||
tmp_uploads/
|
||||
.trae
|
||||
.trae
|
||||
docs
|
||||
|
|
@ -321,6 +321,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllProducts(params?: UnifiedSearchParamsDTO): Promise<UnifiedProductDTO[]> {
|
||||
// Shopyy getAllProducts 暂未实现
|
||||
throw new Error('Shopyy getAllProducts 暂未实现');
|
||||
}
|
||||
|
||||
async getProduct(id: string | number): Promise<UnifiedProductDTO> {
|
||||
// 使用ShopyyService获取单个产品
|
||||
const product = await this.shopyyService.getProduct(this.site, id);
|
||||
|
|
@ -385,6 +390,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllOrders(params?: UnifiedSearchParamsDTO): Promise<UnifiedOrderDTO[]> {
|
||||
// Shopyy getAllOrders 暂未实现
|
||||
throw new Error('Shopyy getAllOrders 暂未实现');
|
||||
}
|
||||
|
||||
async getOrder(id: string | number): Promise<UnifiedOrderDTO> {
|
||||
const data = await this.shopyyService.getOrder(String(this.site.id), String(id));
|
||||
return this.mapOrder(data);
|
||||
|
|
@ -478,6 +488,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
throw new Error('Shopyy does not support subscriptions.');
|
||||
}
|
||||
|
||||
async getAllSubscriptions(params?: UnifiedSearchParamsDTO): Promise<UnifiedSubscriptionDTO[]> {
|
||||
// Shopyy getAllSubscriptions 暂未实现
|
||||
throw new Error('Shopyy getAllSubscriptions 暂未实现');
|
||||
}
|
||||
|
||||
async getMedia(
|
||||
params: UnifiedSearchParamsDTO
|
||||
): Promise<UnifiedPaginationDTO<UnifiedMediaDTO>> {
|
||||
|
|
@ -488,7 +503,7 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
requestParams
|
||||
);
|
||||
return {
|
||||
items: items.map(this.mapMedia),
|
||||
items: items.map(this.mapMedia.bind(this)),
|
||||
total,
|
||||
totalPages,
|
||||
page,
|
||||
|
|
@ -496,6 +511,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllMedia(params?: UnifiedSearchParamsDTO): Promise<UnifiedMediaDTO[]> {
|
||||
// Shopyy getAllMedia 暂未实现
|
||||
throw new Error('Shopyy getAllMedia 暂未实现');
|
||||
}
|
||||
|
||||
async createMedia(file: any): Promise<UnifiedMediaDTO> {
|
||||
const createdMedia = await this.shopyyService.createMedia(this.site, file);
|
||||
return this.mapMedia(createdMedia);
|
||||
|
|
@ -527,6 +547,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllReviews(params?: UnifiedSearchParamsDTO): Promise<UnifiedReviewDTO[]> {
|
||||
// Shopyy getAllReviews 暂未实现
|
||||
throw new Error('Shopyy getAllReviews 暂未实现');
|
||||
}
|
||||
|
||||
async getReview(id: string | number): Promise<UnifiedReviewDTO> {
|
||||
const review = await this.shopyyService.getReview(this.site, id);
|
||||
return this.mapReview(review);
|
||||
|
|
@ -607,6 +632,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllWebhooks(params?: UnifiedSearchParamsDTO): Promise<UnifiedWebhookDTO[]> {
|
||||
// Shopyy getAllWebhooks 暂未实现
|
||||
throw new Error('Shopyy getAllWebhooks 暂未实现');
|
||||
}
|
||||
|
||||
async getWebhook(id: string | number): Promise<UnifiedWebhookDTO> {
|
||||
const webhook = await this.shopyyService.getWebhook(this.site, id);
|
||||
return this.mapWebhook(webhook);
|
||||
|
|
@ -657,6 +687,11 @@ export class ShopyyAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllCustomers(params?: UnifiedSearchParamsDTO): Promise<UnifiedCustomerDTO[]> {
|
||||
// Shopyy getAllCustomers 暂未实现
|
||||
throw new Error('Shopyy getAllCustomers 暂未实现');
|
||||
}
|
||||
|
||||
async getCustomer(id: string | number): Promise<UnifiedCustomerDTO> {
|
||||
const customer = await this.shopyyService.getCustomer(this.site, id);
|
||||
return this.mapCustomer(customer);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { ISiteAdapter } from '../interface/site-adapter.interface';
|
||||
import { IPlatformService } from '../interface/platform.interface';
|
||||
import {
|
||||
UnifiedMediaDTO,
|
||||
UnifiedOrderDTO,
|
||||
|
|
@ -26,10 +25,11 @@ import {
|
|||
WooProductSearchParams,
|
||||
} from '../dto/woocommerce.dto';
|
||||
import { Site } from '../entity/site.entity';
|
||||
import { WPService } from '../service/wp.service';
|
||||
|
||||
export class WooCommerceAdapter implements ISiteAdapter {
|
||||
// 构造函数接收站点配置与服务实例
|
||||
constructor(private site: Site, private wpService: IPlatformService) {
|
||||
constructor(private site: Site, private wpService: WPService) {
|
||||
this.mapProduct = this.mapProduct.bind(this);
|
||||
this.mapReview = this.mapReview.bind(this);
|
||||
this.mapCustomer = this.mapCustomer.bind(this);
|
||||
|
|
@ -71,6 +71,17 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
// 获取所有webhooks
|
||||
async getAllWebhooks(params?: UnifiedSearchParamsDTO): Promise<UnifiedWebhookDTO[]> {
|
||||
try {
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const webhooks = await this.wpService.sdkGetAll(api, 'webhooks', params);
|
||||
return webhooks.map((webhook: any) => this.mapWebhook(webhook));
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get all webhooks: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取单个 webhook 详情
|
||||
async getWebhook(id: string | number): Promise<UnifiedWebhookDTO> {
|
||||
try {
|
||||
|
|
@ -466,6 +477,13 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllProducts(params?: UnifiedSearchParamsDTO): Promise<UnifiedProductDTO[]> {
|
||||
// 使用sdkGetAll获取所有产品数据,不受分页限制
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const products = await this.wpService.sdkGetAll(api, 'products', params);
|
||||
return products.map((product: any) => this.mapProduct(product));
|
||||
}
|
||||
|
||||
async getProduct(id: string | number): Promise<UnifiedProductDTO> {
|
||||
// 获取单个产品详情并映射为统一产品DTO
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
|
|
@ -546,6 +564,13 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
return this.mapOrder(res.data);
|
||||
}
|
||||
|
||||
async getAllOrders(params?: UnifiedSearchParamsDTO): Promise<UnifiedOrderDTO[]> {
|
||||
// 使用sdkGetAll获取所有订单数据,不受分页限制
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const orders = await this.wpService.sdkGetAll(api, 'orders', params);
|
||||
return orders.map((order: any) => this.mapOrder(order));
|
||||
}
|
||||
|
||||
async createOrder(data: Partial<UnifiedOrderDTO>): Promise<UnifiedOrderDTO> {
|
||||
// 创建订单并返回统一订单DTO
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
|
|
@ -649,6 +674,13 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllSubscriptions(params?: UnifiedSearchParamsDTO): Promise<UnifiedSubscriptionDTO[]> {
|
||||
// 使用sdkGetAll获取所有订阅数据,不受分页限制
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const subscriptions = await this.wpService.sdkGetAll(api, 'subscriptions', params);
|
||||
return subscriptions.map((subscription: any) => this.mapSubscription(subscription));
|
||||
}
|
||||
|
||||
async getMedia(
|
||||
params: UnifiedSearchParamsDTO
|
||||
): Promise<UnifiedPaginationDTO<UnifiedMediaDTO>> {
|
||||
|
|
@ -666,6 +698,13 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllMedia(params?: UnifiedSearchParamsDTO): Promise<UnifiedMediaDTO[]> {
|
||||
// 使用sdkGetAll获取所有媒体数据,不受分页限制
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const media = await this.wpService.sdkGetAll(api, 'media', params);
|
||||
return media.map((mediaItem: any) => this.mapMedia(mediaItem));
|
||||
}
|
||||
|
||||
private mapReview(item: any): UnifiedReviewDTO & {raw: any} {
|
||||
// 将 WooCommerce 评论数据映射为统一评论DTO
|
||||
return {
|
||||
|
|
@ -701,6 +740,13 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllReviews(params?: UnifiedSearchParamsDTO): Promise<UnifiedReviewDTO[]> {
|
||||
// 使用sdkGetAll获取所有评论数据,不受分页限制
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const reviews = await this.wpService.sdkGetAll(api, 'products/reviews', params);
|
||||
return reviews.map((review: any) => this.mapReview(review));
|
||||
}
|
||||
|
||||
async createReview(data: any): Promise<UnifiedReviewDTO> {
|
||||
const res = await this.wpService.createReview(this.site, data);
|
||||
return this.mapReview(res);
|
||||
|
|
@ -769,6 +815,13 @@ export class WooCommerceAdapter implements ISiteAdapter {
|
|||
};
|
||||
}
|
||||
|
||||
async getAllCustomers(params?: UnifiedSearchParamsDTO): Promise<UnifiedCustomerDTO[]> {
|
||||
// 使用sdkGetAll获取所有客户数据,不受分页限制
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const customers = await this.wpService.sdkGetAll(api, 'customers', params);
|
||||
return customers.map((customer: any) => this.mapCustomer(customer));
|
||||
}
|
||||
|
||||
async getCustomer(id: string | number): Promise<UnifiedCustomerDTO> {
|
||||
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
|
||||
const res = await api.get(`customers/${id}`);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ export interface ISiteAdapter {
|
|||
*/
|
||||
getProducts(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedProductDTO>>;
|
||||
|
||||
/**
|
||||
* 获取所有产品
|
||||
*/
|
||||
getAllProducts(params?: UnifiedSearchParamsDTO): Promise<UnifiedProductDTO[]>;
|
||||
|
||||
/**
|
||||
* 获取单个产品
|
||||
*/
|
||||
|
|
@ -32,6 +37,11 @@ export interface ISiteAdapter {
|
|||
*/
|
||||
getOrders(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedOrderDTO>>;
|
||||
|
||||
/**
|
||||
* 获取所有订单
|
||||
*/
|
||||
getAllOrders(params?: UnifiedSearchParamsDTO): Promise<UnifiedOrderDTO[]>;
|
||||
|
||||
/**
|
||||
* 获取单个订单
|
||||
*/
|
||||
|
|
@ -42,11 +52,21 @@ export interface ISiteAdapter {
|
|||
*/
|
||||
getSubscriptions(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedSubscriptionDTO>>;
|
||||
|
||||
/**
|
||||
* 获取所有订阅
|
||||
*/
|
||||
getAllSubscriptions(params?: UnifiedSearchParamsDTO): Promise<UnifiedSubscriptionDTO[]>;
|
||||
|
||||
/**
|
||||
* 获取媒体列表
|
||||
*/
|
||||
getMedia(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedMediaDTO>>;
|
||||
|
||||
/**
|
||||
* 获取所有媒体
|
||||
*/
|
||||
getAllMedia(params?: UnifiedSearchParamsDTO): Promise<UnifiedMediaDTO[]>;
|
||||
|
||||
/**
|
||||
* 创建媒体
|
||||
*/
|
||||
|
|
@ -57,6 +77,11 @@ export interface ISiteAdapter {
|
|||
*/
|
||||
getReviews(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedReviewDTO>>;
|
||||
|
||||
/**
|
||||
* 获取所有评论
|
||||
*/
|
||||
getAllReviews(params?: UnifiedSearchParamsDTO): Promise<UnifiedReviewDTO[]>;
|
||||
|
||||
/**
|
||||
* 创建评论
|
||||
*/
|
||||
|
|
@ -111,6 +136,7 @@ export interface ISiteAdapter {
|
|||
batchProcessOrders?(data: BatchOperationDTO): Promise<BatchOperationResultDTO>;
|
||||
|
||||
getCustomers(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedCustomerDTO>>;
|
||||
getAllCustomers(params?: UnifiedSearchParamsDTO): Promise<UnifiedCustomerDTO[]>;
|
||||
getCustomer(id: string | number): Promise<UnifiedCustomerDTO>;
|
||||
createCustomer(data: Partial<UnifiedCustomerDTO>): Promise<UnifiedCustomerDTO>;
|
||||
updateCustomer(id: string | number, data: Partial<UnifiedCustomerDTO>): Promise<UnifiedCustomerDTO>;
|
||||
|
|
@ -123,6 +149,11 @@ export interface ISiteAdapter {
|
|||
*/
|
||||
getWebhooks(params: UnifiedSearchParamsDTO): Promise<UnifiedWebhookPaginationDTO>;
|
||||
|
||||
/**
|
||||
* 获取所有webhooks
|
||||
*/
|
||||
getAllWebhooks(params?: UnifiedSearchParamsDTO): Promise<UnifiedWebhookDTO[]>;
|
||||
|
||||
/**
|
||||
* 获取单个webhook
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -171,17 +171,17 @@ export class CustomerService {
|
|||
try {
|
||||
// 第一步:获取适配器并从站点获取客户数据
|
||||
const adapter = await this.siteApiService.getAdapter(siteId);
|
||||
const siteCustomersResult = await adapter.getCustomers(params || {});
|
||||
const siteCustomers = await adapter.getAllCustomers(params || {});
|
||||
|
||||
// 第二步:将站点客户数据转换为客户实体数据
|
||||
const customersData = siteCustomersResult.items.map(siteCustomer => {
|
||||
const customersData = siteCustomers.map(siteCustomer => {
|
||||
return this.mapSiteCustomerToCustomer(siteCustomer, siteId);
|
||||
});
|
||||
|
||||
// 第三步:批量upsert客户数据
|
||||
const upsertResult = await this.upsertManyCustomers(customersData);
|
||||
return {
|
||||
total: siteCustomersResult.total,
|
||||
total: siteCustomers.length,
|
||||
processed: upsertResult.customers.length,
|
||||
synced: upsertResult.customers.length,
|
||||
updated: upsertResult.updated,
|
||||
|
|
|
|||
|
|
@ -16,12 +16,13 @@ import * as fs from 'fs';
|
|||
const MAX_PAGE_SIZE = 100;
|
||||
@Provide()
|
||||
export class WPService implements IPlatformService {
|
||||
getCustomer(site: any, id: number): Promise<any> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
@Inject()
|
||||
private readonly siteService: SiteService;
|
||||
|
||||
getCustomer(site: any, id: number): Promise<any> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
/**
|
||||
* 构建 URL,自动规范各段的斜杠,避免出现多 / 或少 / 导致请求失败
|
||||
* 使用示例:this.buildURL(wpApiUrl, '/wp-json', 'wc/v3/products', productId)
|
||||
|
|
@ -83,7 +84,7 @@ export class WPService implements IPlatformService {
|
|||
* 使用并发方式获取所有分页数据,提高性能
|
||||
* 默认按 date_created 倒序排列,确保获取最新的数据
|
||||
*/
|
||||
private async sdkGetAll<T>(api: WooCommerceRestApi, resource: string, params: Record<string, any> = {}, maxPages: number = MAX_PAGE_SIZE): Promise<T[]> {
|
||||
async sdkGetAll<T>(api: WooCommerceRestApi, resource: string, params: Record<string, any> = {}, maxPages: number = MAX_PAGE_SIZE): Promise<T[]> {
|
||||
return this.sdkGetAllConcurrent<T>(api, resource, params, maxPages);
|
||||
}
|
||||
|
||||
|
|
@ -101,8 +102,7 @@ export class WPService implements IPlatformService {
|
|||
): Promise<T[]> {
|
||||
// 设置默认排序为 date_created 倒序,确保获取最新数据
|
||||
const defaultParams = {
|
||||
orderby: 'date_created',
|
||||
order: 'desc',
|
||||
order: 'desc', // 倒序,优先获取最新数据
|
||||
per_page: MAX_PAGE_SIZE,
|
||||
...params
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue