forked from yoone/API
1
0
Fork 0
API/src/service/wp.service.ts

301 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Config, Provide } from '@midwayjs/core';
import axios, { AxiosRequestConfig } from 'axios';
import { WpSite } from '../interface';
import { WpProduct } from '../entity/wp_product.entity';
import { Variation } from '../entity/variation.entity';
import { UpdateVariationDTO, UpdateWpProductDTO } from '../dto/wp_product.dto';
@Provide()
export class WPService {
@Config('wpSite')
sites: WpSite[];
/**
* 获取 WordPress 数据
* @param wpApiUrl WordPress REST API 的基础地址
* @param endpoint API 端点路径(例如 wc/v3/products
* @param consumerKey WooCommerce 的消费者密钥
* @param consumerSecret WooCommerce 的消费者密钥
*/
geSite(id: string): WpSite {
let idx = this.sites.findIndex(item => item.id === id);
return this.sites[idx];
}
async fetchData<T>(
endpoint: string,
site: WpSite,
param: Record<string, any> = {}
): Promise<T> {
try {
const { wpApiUrl, consumerKey, consumerSecret } = site;
const url = `${wpApiUrl}/wp-json${endpoint}`;
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString(
'base64'
);
const response = await axios.request({
url,
headers: {
Authorization: `Basic ${auth}`,
},
method: 'GET',
...param,
});
return response.data;
} catch (error) {
throw error;
}
}
async fetchPagedData<T>(
endpoint: string,
site: WpSite,
page: number = 1,
perPage: number = 100
): Promise<T[]> {
const allData: T[] = [];
const { wpApiUrl, consumerKey, consumerSecret } = site;
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString(
'base64'
);
let hasMore = true;
while (hasMore) {
const config: AxiosRequestConfig = {
method: 'GET',
url: `${wpApiUrl}/wp-json${endpoint}`,
headers: {
Authorization: `Basic ${auth}`,
},
params: {
page,
per_page: perPage,
},
};
try {
const response = await axios.request(config);
// Append the current page data
allData.push(...response.data);
// Check for more pages
const totalPages = parseInt(
response.headers['x-wp-totalpages'] || '1',
10
);
hasMore = page < totalPages;
page += 1;
} catch (error) {
throw error;
}
}
return allData;
}
async getProducts(site: WpSite): Promise<WpProduct[]> {
return await this.fetchPagedData<WpProduct>('/wc/v3/products', site);
}
async getVariations(site: WpSite, productId: number): Promise<Variation[]> {
return await this.fetchPagedData<Variation>(
`/wc/v3/products/${productId}/variations`,
site
);
}
async getVariation(
site: WpSite,
productId: number,
variationId: number
): Promise<Variation> {
return await this.fetchData<Variation>(
`/wc/v3/products/${productId}/variations/${variationId}`,
site
);
}
async getOrder(
siteId: string,
orderId: string
): Promise<Record<string, any>> {
const site = this.geSite(siteId);
return await this.fetchData<Record<string, any>>(
`/wc/v3/orders/${orderId}`,
site
);
}
async getOrders(siteId: string): Promise<Record<string, any>[]> {
const site = this.geSite(siteId);
return await this.fetchPagedData<Record<string, any>>(
'/wc/v3/orders',
site
);
}
async getOrderRefund(
siteId: string,
orderId: string,
refundId: number
): Promise<Record<string, any>> {
const site = this.geSite(siteId);
return await this.fetchData<Record<string, any>>(
`/wc/v3/orders/${orderId}/refunds/${refundId}`,
site
);
}
async getOrderRefunds(
siteId: string,
orderId: number
): Promise<Record<string, any>[]> {
const site = this.geSite(siteId);
return await this.fetchPagedData<Record<string, any>>(
`/wc/v3/orders/${orderId}/refunds`,
site
);
}
async getOrderNote(
siteId: string,
orderId: number,
noteId: number
): Promise<Record<string, any>> {
const site = this.geSite(siteId);
return await this.fetchData<Record<string, any>>(
`/wc/v3/orders/${orderId}/notes/${noteId}`,
site
);
}
async getOrderNotes(
siteId: string,
orderId: number
): Promise<Record<string, any>[]> {
const site = this.geSite(siteId);
return await this.fetchPagedData<Record<string, any>>(
`/wc/v3/orders/${orderId}/notes`,
site
);
}
async updateData<T>(
endpoint: string,
site: WpSite,
data: Record<string, any>
): Promise<Boolean> {
const { wpApiUrl, consumerKey, consumerSecret } = site;
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString(
'base64'
);
const config: AxiosRequestConfig = {
method: 'PUT',
url: `${wpApiUrl}/wp-json${endpoint}`,
headers: {
Authorization: `Basic ${auth}`,
},
data,
};
try {
await axios.request(config);
return true;
} catch (error) {
return false;
}
}
/**
* 更新 WooCommerce 产品
* @param productId 产品 ID
* @param data 更新的数据
*/
async updateProduct(
site: WpSite,
productId: string,
data: UpdateWpProductDTO
): Promise<Boolean> {
const { regular_price, sale_price, ...params } = data;
return await this.updateData(`/wc/v3/products/${productId}`, site, {
...params,
regular_price: regular_price ? regular_price.toString() : null,
sale_price: sale_price ? sale_price.toString() : null,
});
}
/**
* 更新 WooCommerce 产品变体
* @param productId 产品 ID
* @param variationId 变体 ID
* @param data 更新的数据
*/
async updateVariation(
site: WpSite,
productId: string,
variationId: string,
data: UpdateVariationDTO
): Promise<Boolean> {
const { regular_price, sale_price, ...params } = data;
return await this.updateData(
`/wc/v3/products/${productId}/variations/${variationId}`,
site,
{
...params,
regular_price: regular_price ? regular_price.toString() : null,
sale_price: sale_price ? sale_price.toString() : null,
}
);
}
/**
* 更新 Order
*/
async updateOrder(
site: WpSite,
orderId: string,
data: Record<string, any>
): Promise<Boolean> {
return await this.updateData(`/wc/v3/orders/${orderId}`, site, data);
}
async createShipment(
site: WpSite,
orderId: string,
data: Record<string, any>
) {
const { wpApiUrl, consumerKey, consumerSecret } = site;
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString(
'base64'
);
const config: AxiosRequestConfig = {
method: 'POST',
url: `${wpApiUrl}/wp-json/wc-ast/v3/orders/${orderId}/shipment-trackings`,
headers: {
Authorization: `Basic ${auth}`,
},
data,
};
return await axios.request(config);
}
async deleteShipment(
site: WpSite,
orderId: string,
trackingId: string,
): Promise<Boolean> {
const { wpApiUrl, consumerKey, consumerSecret } = site;
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString(
'base64'
);
console.log('del', orderId, trackingId);
// 删除接口: DELETE /wp-json/wc-shipment-tracking/v3/orders/<order_id>/shipment-trackings/<tracking_id>
const config: AxiosRequestConfig = {
method: 'DELETE',
url: `${wpApiUrl}/wp-json/wc-ast/v3/orders/${orderId}/shipment-trackings/${trackingId}`,
headers: {
Authorization: `Basic ${auth}`,
},
};
return await axios.request(config);
}
}