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( endpoint: string, site: WpSite, param: Record = {} ): Promise { 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( endpoint: string, site: WpSite, page: number = 1, perPage: number = 100 ): Promise { 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 { return await this.fetchPagedData('/wc/v3/products', site); } async getVariations(site: WpSite, productId: number): Promise { return await this.fetchPagedData( `/wc/v3/products/${productId}/variations`, site ); } async getVariation( site: WpSite, productId: number, variationId: number ): Promise { return await this.fetchData( `/wc/v3/products/${productId}/variations/${variationId}`, site ); } async getOrder( siteId: string, orderId: string ): Promise> { const site = this.geSite(siteId); return await this.fetchData>( `/wc/v3/orders/${orderId}`, site ); } async getOrders(siteId: string): Promise[]> { const site = this.geSite(siteId); return await this.fetchPagedData>( '/wc/v3/orders', site ); } async getOrderRefund( siteId: string, orderId: string, refundId: number ): Promise> { const site = this.geSite(siteId); return await this.fetchData>( `/wc/v3/orders/${orderId}/refunds/${refundId}`, site ); } async getOrderRefunds( siteId: string, orderId: number ): Promise[]> { const site = this.geSite(siteId); return await this.fetchPagedData>( `/wc/v3/orders/${orderId}/refunds`, site ); } async getOrderNote( siteId: string, orderId: number, noteId: number ): Promise> { const site = this.geSite(siteId); return await this.fetchData>( `/wc/v3/orders/${orderId}/notes/${noteId}`, site ); } async getOrderNotes( siteId: string, orderId: number ): Promise[]> { const site = this.geSite(siteId); return await this.fetchPagedData>( `/wc/v3/orders/${orderId}/notes`, site ); } async updateData( endpoint: string, site: WpSite, data: Record ): Promise { 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 { 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 { 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 ): Promise { return await this.updateData(`/wc/v3/orders/${orderId}`, site, data); } async createShipment( site: WpSite, orderId: string, data: Record ) { 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 { 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//shipment-trackings/ 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); } }