chore: 使用@woocommerce/woocommerce-rest-api获取

This commit is contained in:
tikkhun 2025-11-17 16:10:56 +08:00
parent e94ea5ed58
commit 4ce5cb8bb0
1 changed files with 68 additions and 45 deletions

View File

@ -1,5 +1,6 @@
import { Config, Provide } from '@midwayjs/core'; import { Config, Provide } from '@midwayjs/core';
import axios, { AxiosRequestConfig } from 'axios'; import axios, { AxiosRequestConfig } from 'axios';
import WooCommerceRestApi, { WooCommerceRestApiVersion } from '@woocommerce/woocommerce-rest-api';
import { WpSite } from '../interface'; import { WpSite } from '../interface';
import { WpProduct } from '../entity/wp_product.entity'; import { WpProduct } from '../entity/wp_product.entity';
import { Variation } from '../entity/variation.entity'; import { Variation } from '../entity/variation.entity';
@ -29,6 +30,46 @@ export class WPService {
return joined.replace(/([^:])\/{2,}/g, '$1/'); return joined.replace(/([^:])\/{2,}/g, '$1/');
} }
/**
* WooCommerce SDK
* @param site
* @param namespace API wc/v3 wcs/v1
*/
private createApi(site: WpSite, namespace: WooCommerceRestApiVersion = 'wc/v3') {
return new WooCommerceRestApi({
url: site.wpApiUrl,
consumerKey: site.consumerKey,
consumerSecret: site.consumerSecret,
// SDK 的版本字段有联合类型限制,这里兼容插件命名空间(例如 wcs/v1
version: namespace,
});
}
/**
* SDK totalPages
*/
private async sdkGetPage<T>(api: any, resource: string, params: Record<string, any> = {}) {
const page = params.page ?? 1;
const per_page = params.per_page ?? 100;
const res = await api.get(resource.replace(/^\/+/, ''), { ...params, page, per_page });
const data = res.data as T[];
const totalPages = Number(res.headers?.['x-wp-totalpages'] ?? 1);
return { items: data, totalPages, page, per_page };
}
/**
* SDK
*/
private async sdkGetAll<T>(api: any, resource: string, params: Record<string, any> = {}, maxPages: number = 50): Promise<T[]> {
const result: T[] = [];
for (let page = 1; page <= maxPages; page++) {
const { items, totalPages } = await this.sdkGetPage<T>(api, resource, { ...params, page });
result.push(...items);
if (page >= totalPages) break;
}
return result;
}
/** /**
* WordPress * WordPress
* @param wpApiUrl WordPress REST API * @param wpApiUrl WordPress REST API
@ -79,6 +120,7 @@ export class WPService {
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString( const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString(
'base64' 'base64'
); );
console.log(`!!!wpApiUrl, consumerKey, consumerSecret, auth`,wpApiUrl, consumerKey, consumerSecret, auth)
let hasMore = true; let hasMore = true;
while (hasMore) { while (hasMore) {
const config: AxiosRequestConfig = { const config: AxiosRequestConfig = {
@ -115,14 +157,13 @@ export class WPService {
} }
async getProducts(site: WpSite): Promise<WpProduct[]> { async getProducts(site: WpSite): Promise<WpProduct[]> {
return await this.fetchPagedData<WpProduct>('/wc/v3/products', site); const api = this.createApi(site, 'wc/v3');
return await this.sdkGetAll<WpProduct>(api, 'products');
} }
async getVariations(site: WpSite, productId: number): Promise<Variation[]> { async getVariations(site: WpSite, productId: number): Promise<Variation[]> {
return await this.fetchPagedData<Variation>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/products/${productId}/variations`, return await this.sdkGetAll<Variation>(api, `products/${productId}/variations`);
site
);
} }
async getVariation( async getVariation(
@ -130,10 +171,9 @@ export class WPService {
productId: number, productId: number,
variationId: number variationId: number
): Promise<Variation> { ): Promise<Variation> {
return await this.fetchData<Variation>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/products/${productId}/variations/${variationId}`, const res = await api.get(`products/${productId}/variations/${variationId}`);
site return res.data as Variation;
);
} }
async getOrder( async getOrder(
@ -141,17 +181,14 @@ export class WPService {
orderId: string orderId: string
): Promise<Record<string, any>> { ): Promise<Record<string, any>> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
return await this.fetchData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/orders/${orderId}`, const res = await api.get(`orders/${orderId}`);
site return res.data as Record<string, any>;
);
} }
async getOrders(siteId: string): Promise<Record<string, any>[]> { async getOrders(siteId: string): Promise<Record<string, any>[]> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
return await this.fetchPagedData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
'/wc/v3/orders', return await this.sdkGetAll<Record<string, any>>(api, 'orders');
site
);
} }
/** /**
@ -161,18 +198,10 @@ export class WPService {
*/ */
async getSubscriptions(siteId: string): Promise<Record<string, any>[]> { async getSubscriptions(siteId: string): Promise<Record<string, any>[]> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
try { // 优先使用 Subscriptions 命名空间 wcs/v1失败回退 wc/v3
return await this.fetchPagedData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
'/wc/v1/subscriptions', return await this.sdkGetAll<Record<string, any>>(api, 'subscriptions');
site
);
} catch (e) {
// fallback
return await this.fetchPagedData<Record<string, any>>(
'/wc/v3/subscriptions',
site
);
}
} }
async getOrderRefund( async getOrderRefund(
@ -181,10 +210,9 @@ export class WPService {
refundId: number refundId: number
): Promise<Record<string, any>> { ): Promise<Record<string, any>> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
return await this.fetchData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/orders/${orderId}/refunds/${refundId}`, const res = await api.get(`orders/${orderId}/refunds/${refundId}`);
site return res.data as Record<string, any>;
);
} }
async getOrderRefunds( async getOrderRefunds(
@ -192,10 +220,8 @@ export class WPService {
orderId: number orderId: number
): Promise<Record<string, any>[]> { ): Promise<Record<string, any>[]> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
return await this.fetchPagedData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/orders/${orderId}/refunds`, return await this.sdkGetAll<Record<string, any>>(api, `orders/${orderId}/refunds`);
site
);
} }
async getOrderNote( async getOrderNote(
@ -204,10 +230,9 @@ export class WPService {
noteId: number noteId: number
): Promise<Record<string, any>> { ): Promise<Record<string, any>> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
return await this.fetchData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/orders/${orderId}/notes/${noteId}`, const res = await api.get(`orders/${orderId}/notes/${noteId}`);
site return res.data as Record<string, any>;
);
} }
async getOrderNotes( async getOrderNotes(
@ -215,10 +240,8 @@ export class WPService {
orderId: number orderId: number
): Promise<Record<string, any>[]> { ): Promise<Record<string, any>[]> {
const site = this.geSite(siteId); const site = this.geSite(siteId);
return await this.fetchPagedData<Record<string, any>>( const api = this.createApi(site, 'wc/v3');
`/wc/v3/orders/${orderId}/notes`, return await this.sdkGetAll<Record<string, any>>(api, `orders/${orderId}/notes`);
site
);
} }
async updateData<T>( async updateData<T>(