UNPKG

@gt6/sdk

Version:

GT6 SDK for articles management - A comprehensive JavaScript/TypeScript library for managing articles, categories, and tags in GT6 platform

1,412 lines (1,407 loc) 117 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); // 错误类型 class GT6Error extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode; this.name = 'GT6Error'; } } class GT6Client { constructor(config) { this.config = { timeout: 10000, cache: { enabled: true, ttl: 300000 // 5分钟默认缓存 }, ...config }; this.cache = new Map(); } /** * 发起HTTP请求 */ async request(endpoint, options = {}) { const url = `${this.config.baseUrl}${endpoint}`; const cacheKey = `${options.method || 'GET'}:${url}`; // 检查缓存(只对GET请求缓存) if (this.config.cache?.enabled && options.method !== 'POST' && options.method !== 'PUT' && options.method !== 'DELETE') { const cached = this.cache.get(cacheKey); if (cached && Date.now() - cached.timestamp < this.config.cache.ttl) { return cached.data; } } try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.config.timeout); // 对于FormData,不设置Content-Type,让浏览器自动设置 const headers = new Headers(options.headers); if (!(options.body instanceof FormData)) { headers.set('Content-Type', 'application/json'); } const response = await fetch(url, { ...options, headers, signal: controller.signal }); clearTimeout(timeoutId); if (!response.ok) { throw new GT6Error(`HTTP ${response.status}: ${response.statusText}`, response.status); } const data = await response.json(); // 更新缓存(只对GET请求缓存) if (this.config.cache?.enabled && options.method !== 'POST' && options.method !== 'PUT' && options.method !== 'DELETE') { this.cache.set(cacheKey, { data, timestamp: Date.now() }); } return data; } catch (error) { if (error instanceof GT6Error) { throw error; } if (error.name === 'AbortError') { throw new GT6Error('Request timeout', 408); } throw new GT6Error(`Network error: ${error.message}`); } } /** * 获取配置 */ getConfig() { return { ...this.config }; } /** * 清除缓存 */ clearCache() { this.cache.clear(); } /** * 获取缓存统计 */ getCacheStats() { const entries = Array.from(this.cache.entries()).map(([key, value]) => ({ key, age: Date.now() - value.timestamp })); return { size: this.cache.size, entries }; } } class ArticlesAPI { constructor(client) { this.client = client; } /** * 1. 根据文章ID获取文章详情 */ async getArticle(articleId) { return this.client.request(`/articles/${articleId}.json`); } /** * 1.1 根据文章ID获取文章详情(平台使用) */ async getArticle_p(articleId) { return this.client.request(`/parentarticles/${articleId}.json`); } /** * 2. 获取文章分类列表 */ async getCategories(rootCategoryId) { const config = this.client.getConfig(); const categoryId = rootCategoryId || config.rootCategoryId || '671920'; const response = await this.client.request(`/article-categories/platform-${config.platformId}-root-${categoryId}.json`); return response.categories; } /** * 2.1 获取文章分类列表(使用下级平台ID) */ async getCategories_p(rootCategoryId_p) { const config = this.client.getConfig(); const categoryId = rootCategoryId_p || config.rootCategoryId_p || '671920'; const response = await this.client.request(`/article-categories/platform/platform-${config.platformId_p}-root-${categoryId}.json`); return response.categories; } /** * 2.2 获取文章分类列表(使用下级平台ID) */ async getCategories_a(rootCategoryId) { const config = this.client.getConfig(); const categoryId = rootCategoryId || config.rootCategoryId; const response = await this.client.request(`/big-article-categories/platform-${config.platformId}-root-${categoryId}.json`); return response.categories; } /** * 3. 获取文章标签列表 */ async getTags(tagAlias) { const config = this.client.getConfig(); const alias = tagAlias || config.tagAlias || '001'; const response = await this.client.request(`/article-tags/platform-${config.platformId}-${alias}.json`); return response.tags; } /** * 3.1 获取文章标签列表(使用下级平台ID) */ async getTags_p(tagAlias_p) { const config = this.client.getConfig(); const alias = tagAlias_p || config.tagAlias_p || '001'; const response = await this.client.request(`/article-tags/platform-${config.platformId_p}-${alias}.json`); return response.tags; } /** * 3.2. 获取单个平台文章标签列表 */ async getTags_p_single(tagId_p) { const config = this.client.getConfig(); const tagId = tagId_p || config.tagId_p; if (!tagId) { throw new Error('Article tag ID is required'); } const response = await this.client.request(`/article-tags/${tagId}.json`); return response; } /** * 3.3. 获取单个平台文章标签的文章ID列表 */ async getTagArticleIds_p(tagId_p) { const tagData = await this.getTags_p_single(tagId_p); return tagData.articleIds; } /** * 4. 根据分类ID获取文章列表 * 支持单个分类ID或分类ID数组 */ async getArticlesByCategory(categoryId, options) { // 获取分类数据 const categories = await this.getCategories(); // 将单个分类ID转换为数组 const categoryIds = Array.isArray(categoryId) ? categoryId : [categoryId]; // 收集所有指定分类下的文章ID const allArticleIds = []; categoryIds.forEach(id => { const targetCategory = categories.find(cat => cat.categoryId === id); if (targetCategory) { allArticleIds.push(...targetCategory.articleIds); } }); // 去重 const uniqueArticleIds = [...new Set(allArticleIds)]; if (uniqueArticleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = uniqueArticleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: uniqueArticleIds.length, page, limit }; } /** * 4.1 根据分类ID获取文章列表 * 支持单个分类ID或分类ID数组 */ async getArticlesByCategory_p(categoryId, options) { // 获取分类数据 const categories = await this.getCategories_p(); // 将单个分类ID转换为数组 const categoryIds = Array.isArray(categoryId) ? categoryId : [categoryId]; // 收集所有指定分类下的文章ID const allArticleIds = []; categoryIds.forEach(id => { const targetCategory = categories.find(cat => cat.categoryId === id); if (targetCategory) { allArticleIds.push(...targetCategory.articleIds); } }); // 去重 const uniqueArticleIds = [...new Set(allArticleIds)]; if (uniqueArticleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = uniqueArticleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle_p(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: uniqueArticleIds.length, page, limit }; } /** * 4.2 根据分类ID获取文章列表 * 支持单个分类ID或分类ID数组 */ async getArticlesByCategory_t(categoryId, options) { // 获取分类数据 const categories = await this.getCategories(); // 将单个分类ID转换为数组 const categoryIds = Array.isArray(categoryId) ? categoryId : [categoryId]; // 收集所有指定分类下的文章ID const allArticleIds = []; categoryIds.forEach(id => { const targetCategory = categories.find(cat => cat.categoryId === id); if (targetCategory) { allArticleIds.push(...targetCategory.articleIds); } }); // 去重 const uniqueArticleIds = [...new Set(allArticleIds)]; if (uniqueArticleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = uniqueArticleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle_p(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: uniqueArticleIds.length, page, limit }; } /** * 4.3 根据分类ID获取文章列表(使用大型分类静态文件) * 只支持单个分类ID,从大型分类静态文件获取文章ID列表 */ async getArticlesByCategory_a(categoryId, options) { // 从大型分类静态文件获取该分类的文章ID列表 const categoryData = await this.client.request(`/big-article-categories/${categoryId}.json`); if (!categoryData || !categoryData.articleIds || categoryData.articleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = categoryData.articleIds.slice(offset, offset + limit); // 获取文章详情(使用上级平台数据) const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle_p(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: categoryData.articleIds.length, page, limit }; } /** * 5. 根据标签ID获取文章列表 * 支持单个标签ID或标签ID数组 */ async getArticlesByTag(tagId, options) { // 获取标签数据,传递tagAlias参数 const tags = await this.getTags(options?.tagAlias); // 将单个标签ID转换为数组 const tagIds = Array.isArray(tagId) ? tagId : [tagId]; // 收集所有指定标签下的文章ID const allArticleIds = []; tagIds.forEach(id => { const targetTag = tags.find(tag => tag.tagId === id); if (targetTag) { allArticleIds.push(...targetTag.articleIds); } }); // 去重 const uniqueArticleIds = [...new Set(allArticleIds)]; if (uniqueArticleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = uniqueArticleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: uniqueArticleIds.length, page, limit }; } /** * 5.1 根据标签ID获取文章列表 * 支持单个标签ID或标签ID数组 */ async getArticlesByTag_p(tagId, options) { // 获取标签数据,传递tagAlias参数 const tags = await this.getTags_p(options?.tagAlias); // 将单个标签ID转换为数组 const tagIds = Array.isArray(tagId) ? tagId : [tagId]; // 收集所有指定标签下的文章ID const allArticleIds = []; tagIds.forEach(id => { const targetTag = tags.find(tag => tag.tagId === id); if (targetTag) { allArticleIds.push(...targetTag.articleIds); } }); // 去重 const uniqueArticleIds = [...new Set(allArticleIds)]; if (uniqueArticleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = uniqueArticleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle_p(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: uniqueArticleIds.length, page, limit }; } /** * 5.2 根据标签ID获取文章列表 * 支持单个标签ID或标签ID数组 */ async getArticlesByTag_t(tagId, options) { // 获取标签数据,传递tagAlias参数 const tags = await this.getTags(options?.tagAlias); // 将单个标签ID转换为数组 const tagIds = Array.isArray(tagId) ? tagId : [tagId]; // 收集所有指定标签下的文章ID const allArticleIds = []; tagIds.forEach(id => { const targetTag = tags.find(tag => tag.tagId === id); if (targetTag) { allArticleIds.push(...targetTag.articleIds); } }); // 去重 const uniqueArticleIds = [...new Set(allArticleIds)]; if (uniqueArticleIds.length === 0) { return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = uniqueArticleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle_p(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } return { articles: filteredArticles, total: uniqueArticleIds.length, page, limit }; } /** * 5.3. 根据单个标签ID获取平台文章列表 * 使用getTags_p_single获取指定标签数据,然后获取文章详情 * @param tagId 单个标签ID * @param options 查询选项 */ async getArticlesByTag_single(tagId, options) { // 获取指定标签的数据 const tagData = await this.getTags_p_single(tagId); if (!tagData || !tagData.articleIds || tagData.articleIds.length === 0) { // 剔除articleIds字段 const { articleIds, ...tagInfo } = tagData; return { articles: [], total: 0, page: options?.page || 1, limit: options?.limit || 10, tag: tagInfo }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedArticleIds = tagData.articleIds.slice(offset, offset + limit); // 获取文章详情 const articles = await Promise.all(paginatedArticleIds.map(articleId => this.getArticle_p(articleId))); // 应用状态过滤 let filteredArticles = articles; if (options?.status) { filteredArticles = articles.filter(article => article.status === options.status); } // 剔除articleIds字段 const { articleIds, ...tagInfo } = tagData; return { articles: filteredArticles, total: tagData.articleIds.length, page, limit, tag: tagInfo }; } /** * 6. 根据分类ID获取该分类的层级路径 * 用于前端面包屑导航 */ async getCategoryPath(categoryId) { // 获取所有分类数据 const categories = await this.getCategories(); // 查找目标分类 const targetCategory = categories.find(cat => cat.categoryId === categoryId); if (!targetCategory) { return { path: [], currentCategory: null, breadcrumbs: [] }; } // 构建分类路径 const path = []; const breadcrumbs = []; // 递归查找父分类 const buildPath = (currentCategory, level = 0) => { // 将当前分类添加到路径开头(因为我们要从根到叶子构建) path.unshift(currentCategory); breadcrumbs.unshift({ categoryId: currentCategory.categoryId, categoryName: currentCategory.categoryName, level }); // 如果有父分类,继续递归 if (currentCategory.parentId && currentCategory.parentId !== 0) { const parentCategory = categories.find(cat => cat.categoryId === currentCategory.parentId); if (parentCategory) { buildPath(parentCategory, level + 1); } } }; // 从目标分类开始构建路径 buildPath(targetCategory); return { path, currentCategory: targetCategory, breadcrumbs }; } /** * 7. 获取指定分类ID下的子分类 * 支持递归获取所有层级的子分类 */ async getSubCategories(categoryId, options) { // 获取所有分类数据 const categories = await this.getCategories(); // 查找目标分类 const targetCategory = categories.find(cat => cat.categoryId === categoryId); if (!targetCategory) { return { subCategories: [], currentCategory: null, total: 0, depth: 0 }; } const subCategories = []; let maxDepth = options?.maxDepth || Infinity; let actualDepth = 0; // 递归获取子分类的函数 const collectSubCategories = (parentId, currentDepth = 0) => { if (currentDepth >= maxDepth) { return; } // 查找直接子分类 const children = categories.filter(cat => cat.parentId === parentId); children.forEach(child => { subCategories.push(child); // 如果需要递归且未达到最大深度,继续查找子分类 if (options?.recursive && currentDepth < maxDepth - 1) { collectSubCategories(child.categoryId, currentDepth + 1); } }); // 更新实际深度 actualDepth = Math.max(actualDepth, currentDepth); }; // 开始收集子分类 collectSubCategories(categoryId); // 如果需要包含当前分类,添加到结果中 if (options?.includeCurrent) { subCategories.unshift(targetCategory); } return { subCategories, currentCategory: targetCategory, total: subCategories.length, depth: actualDepth }; } } class ProductsAPI { constructor(client) { this.client = client; } /** * 1. 根据产品ID获取产品详情 */ async getProduct(productId) { const product = await this.client.request(`/products/${productId}.json`); // 检查产品是否有销售区域和税费模板 if (product.regions && product.regions.length > 0 && product.taxTemplates && product.taxTemplates.length > 0) { try { // 获取税费信息 const taxInfo = await this.getTaxInfo(); // 为每个税费模板添加规则 product.taxTemplates = product.taxTemplates.map(template => { const matchingTemplate = taxInfo.templates.find(t => t.templateId === template.templateId); if (matchingTemplate) { // 过滤出产品可销售区域的规则 const productRegionIds = product.regions.map(r => r.regionId); const applicableRules = matchingTemplate.rules.filter(rule => productRegionIds.includes(rule.regionId)); return { ...template, rules: applicableRules }; } return template; }); } catch (error) { // 如果获取税费信息失败,不影响产品详情返回 console.warn('Failed to fetch tax info:', error); } } // 检查产品是否有销售区域和运费模板 if (product.regions && product.regions.length > 0 && product.shippingTemplates && product.shippingTemplates.length > 0) { try { // 获取运费信息 const shippingInfo = await this.getShippingInfo(); // 为每个运费模板添加规则 product.shippingTemplates = product.shippingTemplates.map(template => { const matchingTemplate = shippingInfo.templates.find(t => t.templateId === template.templateId); if (matchingTemplate) { // 过滤出产品可销售区域的规则 const productRegionIds = product.regions.map(r => r.regionId); const applicableRules = matchingTemplate.rules.filter(rule => productRegionIds.includes(rule.regionId)); return { ...template, rules: applicableRules }; } return template; }); } catch (error) { // 如果获取运费信息失败,不影响产品详情返回 console.warn('Failed to fetch shipping info:', error); } } return product; } /** * 1.1. 根据产品ID获取父平台产品详情 */ async getProduct_p(productId) { const product = await this.client.request(`/parentproducts/${productId}.json`); // 检查产品是否有销售区域和税费模板 if (product.regions && product.regions.length > 0 && product.taxTemplates && product.taxTemplates.length > 0) { try { // 获取税费信息 const taxInfo = await this.getTaxInfo(); // 为每个税费模板添加规则 product.taxTemplates = product.taxTemplates.map(template => { const matchingTemplate = taxInfo.templates.find(t => t.templateId === template.templateId); if (matchingTemplate) { // 过滤出产品可销售区域的规则 const productRegionIds = product.regions.map(r => r.regionId); const applicableRules = matchingTemplate.rules.filter(rule => productRegionIds.includes(rule.regionId)); return { ...template, rules: applicableRules }; } return template; }); } catch (error) { // 如果获取税费信息失败,不影响产品详情返回 console.warn('Failed to fetch tax info:', error); } } // 检查产品是否有销售区域和运费模板 if (product.regions && product.regions.length > 0 && product.shippingTemplates && product.shippingTemplates.length > 0) { try { // 获取运费信息 const shippingInfo = await this.getShippingInfo(); // 为每个运费模板添加规则 product.shippingTemplates = product.shippingTemplates.map(template => { const matchingTemplate = shippingInfo.templates.find(t => t.templateId === template.templateId); if (matchingTemplate) { // 过滤出产品可销售区域的规则 const productRegionIds = product.regions.map(r => r.regionId); const applicableRules = matchingTemplate.rules.filter(rule => productRegionIds.includes(rule.regionId)); return { ...template, rules: applicableRules }; } return template; }); } catch (error) { // 如果获取运费信息失败,不影响产品详情返回 console.warn('Failed to fetch shipping info:', error); } } return product; } /** * 2. 获取产品分类列表 */ async getCategories(productRootCategoryId) { const config = this.client.getConfig(); const categoryId = productRootCategoryId || config.productRootCategoryId || '277233'; const response = await this.client.request(`/product-categories/platform-${config.platformId}-root-${categoryId}.json`); return response.categories; } /** * 2.1. 获取平台产品分类列表 */ async getCategories_p(productRootCategoryId_p) { const config = this.client.getConfig(); const categoryId = productRootCategoryId_p || config.productRootCategoryId_p; const response = await this.client.request(`/product-categories/platform/platform-${config.platformId_p}-root-${categoryId}.json`); return response.categories; } /** * 2.2. 获取平台产品分类列表 */ async getCategories_b(productRootCategoryId) { const config = this.client.getConfig(); const categoryId = productRootCategoryId || config.productRootCategoryId; const response = await this.client.request(`/big-product-categories/platform-${config.platformId}-root-${categoryId}.json`); return response.categories; } /** * 3. 获取产品标签列表 */ async getTags(productTagAlias) { const config = this.client.getConfig(); const alias = productTagAlias || config.productTagAlias || '01'; const response = await this.client.request(`/product-tags/platform-${config.platformId}-${alias}.json`); return response.tags; } /** * 3.1. 获取平台产品标签列表 */ async getTags_p(productTagAlias_p) { const config = this.client.getConfig(); const alias = productTagAlias_p || config.productTagAlias_p; const response = await this.client.request(`/product-tags/platform-${config.platformId_p}-${alias}.json`); return response.tags; } /** * 3.2. 获取单个平台产品标签列表 */ async getTags_p_single(productTagId_p) { const config = this.client.getConfig(); const productTagId = productTagId_p || config.productTagId_p; if (!productTagId) { throw new Error('Product tag ID is required'); } const response = await this.client.request(`/product-tags/${productTagId}.json`); return response; } /** * 3.3. 获取单个平台产品标签的产品ID列表 */ async getTagProductIds_p(productTagId_p) { const tagData = await this.getTags_p_single(productTagId_p); return tagData.productIds; } /** * 4. 根据分类ID获取产品列表 * 支持单个分类ID或分类ID数组 */ async getProductsByCategory(categoryId, options) { // 获取分类数据 const categories = await this.getCategories(); // 递归查找分类的函数 const findCategoryById = (cats, targetId) => { for (const cat of cats) { if (cat.categoryId === targetId) { return cat; } if (cat.children && cat.children.length > 0) { const found = findCategoryById(cat.children, targetId); if (found) return found; } } return null; }; // 将单个分类ID转换为数组 const categoryIds = Array.isArray(categoryId) ? categoryId : [categoryId]; // 收集所有指定分类下的产品ID const allProductIds = []; categoryIds.forEach(id => { const targetCategory = findCategoryById(categories, id); if (targetCategory) { allProductIds.push(...targetCategory.productIds); } }); // 去重 const uniqueProductIds = [...new Set(allProductIds)]; if (uniqueProductIds.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = uniqueProductIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } return { products: filteredProducts, total: uniqueProductIds.length, page, limit }; } /** * 4.1. 根据分类ID获取平台产品列表 */ async getProductsByCategory_p(categoryId, options) { // 获取分类数据 const categories = await this.getCategories_p(); // 递归查找分类的函数 const findCategoryById = (cats, targetId) => { for (const cat of cats) { if (cat.categoryId === targetId) { return cat; } if (cat.children && cat.children.length > 0) { const found = findCategoryById(cat.children, targetId); if (found) return found; } } return null; }; // 将单个分类ID转换为数组 const categoryIds = Array.isArray(categoryId) ? categoryId : [categoryId]; // 收集所有指定分类下的产品ID const allProductIds = []; categoryIds.forEach(id => { const targetCategory = findCategoryById(categories, id); if (targetCategory) { allProductIds.push(...targetCategory.productIds); } }); // 去重 const uniqueProductIds = [...new Set(allProductIds)]; if (uniqueProductIds.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = uniqueProductIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct_p(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } return { products: filteredProducts, total: uniqueProductIds.length, page, limit }; } /** * 4.2. 根据分类ID获取平台产品列表 */ async getProductsByCategory_t(categoryId, options) { // 获取分类数据 const categories = await this.getCategories(); // 递归查找分类的函数 const findCategoryById = (cats, targetId) => { for (const cat of cats) { if (cat.categoryId === targetId) { return cat; } if (cat.children && cat.children.length > 0) { const found = findCategoryById(cat.children, targetId); if (found) return found; } } return null; }; // 将单个分类ID转换为数组 const categoryIds = Array.isArray(categoryId) ? categoryId : [categoryId]; // 收集所有指定分类下的产品ID const allProductIds = []; categoryIds.forEach(id => { const targetCategory = findCategoryById(categories, id); if (targetCategory) { allProductIds.push(...targetCategory.productIds); } }); // 去重 const uniqueProductIds = [...new Set(allProductIds)]; if (uniqueProductIds.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = uniqueProductIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct_p(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } return { products: filteredProducts, total: uniqueProductIds.length, page, limit }; } /** * 4.3. 根据大分类ID获取平台产品列表 * 适配big-product-categories/${categoryId}.json新结构,支持排序和分页,直接返回数据 * @param categoryId 分类ID * @param options { page, limit, sortBy } * sortBy: 'createdAt-desc' | 'createdAt-asc' | 'price-desc' | 'price-asc' */ async getProductsByCategory_b(categoryId, options) { // 从大型分类静态文件获取该分类的产品信息列表 const categoryData = await this.client.request(`/big-product-categories/${categoryId}.json`); if (!categoryData || !categoryData.productInfos || categoryData.productInfos.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 排序 let sortedProducts = [...categoryData.productInfos]; const sortBy = options?.sortBy || 'createdAt-desc'; if (sortBy === 'createdAt-desc') { sortedProducts.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); } else if (sortBy === 'createdAt-asc') { sortedProducts.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()); } else if (sortBy === 'price-desc') { sortedProducts.sort((a, b) => parseFloat(b.price) - parseFloat(a.price)); } else if (sortBy === 'price-asc') { sortedProducts.sort((a, b) => parseFloat(a.price) - parseFloat(b.price)); } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProducts = sortedProducts.slice(offset, offset + limit); // 应用状态过滤(如果有status字段) let filteredProducts = paginatedProducts; if (options?.status !== undefined) { filteredProducts = paginatedProducts.filter(product => product.status === options.status); } return { products: filteredProducts, total: categoryData.productInfos.length, page, limit }; } /** * 5. 根据标签ID获取产品列表 * 支持单个标签ID或标签ID数组 */ async getProductsByTag(tagId, options) { // 获取标签数据,传递productTagAlias参数 const tags = await this.getTags(options?.productTagAlias); // 将单个标签ID转换为数组 const tagIds = Array.isArray(tagId) ? tagId : [tagId]; // 收集所有指定标签下的产品ID const allProductIds = []; tagIds.forEach(id => { const targetTag = tags.find(tag => tag.tagId === id); if (targetTag) { allProductIds.push(...targetTag.productIds); } }); // 去重 const uniqueProductIds = [...new Set(allProductIds)]; if (uniqueProductIds.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = uniqueProductIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } return { products: filteredProducts, total: uniqueProductIds.length, page, limit }; } /** * 5.1. 根据标签ID获取平台产品列表 */ async getProductsByTag_p(tagId, options) { // 获取标签数据,传递productTagAlias参数 const tags = await this.getTags_p(options?.productTagAlias); // 将单个标签ID转换为数组 const tagIds = Array.isArray(tagId) ? tagId : [tagId]; // 收集所有指定标签下的产品ID const allProductIds = []; tagIds.forEach(id => { const targetTag = tags.find(tag => tag.tagId === id); if (targetTag) { allProductIds.push(...targetTag.productIds); } }); // 去重 const uniqueProductIds = [...new Set(allProductIds)]; if (uniqueProductIds.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = uniqueProductIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct_p(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } return { products: filteredProducts, total: uniqueProductIds.length, page, limit }; } /** * 5.2. 根据标签ID获取平台产品列表 */ async getProductsByTag_t(tagId, options) { // 获取标签数据,传递productTagAlias参数 const tags = await this.getTags(options?.productTagAlias); // 将单个标签ID转换为数组 const tagIds = Array.isArray(tagId) ? tagId : [tagId]; // 收集所有指定标签下的产品ID const allProductIds = []; tagIds.forEach(id => { const targetTag = tags.find(tag => tag.tagId === id); if (targetTag) { allProductIds.push(...targetTag.productIds); } }); // 去重 const uniqueProductIds = [...new Set(allProductIds)]; if (uniqueProductIds.length === 0) { return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10 }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = uniqueProductIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct_p(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } return { products: filteredProducts, total: uniqueProductIds.length, page, limit }; } /** * 5.3. 根据单个标签ID获取平台产品列表 * 使用getTags_p_single获取指定标签数据,然后获取产品详情 * @param tagId 单个标签ID * @param options 查询选项 */ async getProductsByTag_single(tagId, options) { // 获取指定标签的数据 const tagData = await this.getTags_p_single(tagId); if (!tagData || !tagData.productIds || tagData.productIds.length === 0) { // 剔除productIds字段 const { productIds, ...tagInfo } = tagData; return { products: [], total: 0, page: options?.page || 1, limit: options?.limit || 10, tag: tagInfo }; } // 应用分页 const page = options?.page || 1; const limit = options?.limit || 10; const offset = (page - 1) * limit; const paginatedProductIds = tagData.productIds.slice(offset, offset + limit); // 获取产品详情 const products = await Promise.all(paginatedProductIds.map(productId => this.getProduct_p(productId))); // 应用状态过滤 let filteredProducts = products; if (options?.status !== undefined) { filteredProducts = products.filter(product => product.status === options.status); } // 剔除productIds字段 const { productIds, ...tagInfo } = tagData; return { products: filteredProducts, total: tagData.productIds.length, page, limit, tag: tagInfo }; } /** * 6. 根据分类ID获取该分类的层级路径 * 用于前端面包屑导航 */ async getCategoryPath(categoryId) { // 获取所有分类数据 const categories = await this.getCategories(); // 递归查找目标分类的函数 const findCategoryById = (cats, targetId) => { for (const cat of cats) { if (cat.categoryId === targetId) { return cat; } if (cat.children && cat.children.length > 0) { const found = findCategoryById(cat.children, targetId); if (found) return found; } } return null; }; // 查找目标分类(包括子分类) const targetCategory = findCategoryById(categories, categoryId); if (!targetCategory) { return { path: [], currentCategory: null, breadcrumbs: [] }; } // 构建分类路径 const path = []; const breadcrumbs = []; // 递归查找父分类的函数 const buildPath = (currentCategory, level = 0) => { // 将当前分类添加到路径开头(因为我们要从根到叶子构建) path.unshift(currentCategory); breadcrumbs.unshift({ categoryId: currentCategory.categoryId, categoryName: currentCategory.categoryName, level }); // 如果有父分类,继续递归 if (currentCategory.parentId && currentCategory.parentId !== 0) { const parentCategory = findCategoryById(categories, currentCategory.parentId); if (parentCategory) { buildPath(parentCategory, level + 1); } } }; // 从目标分类开始构建路径 buildPath(targetCategory); return { path, currentCategory: targetCategory, breadcrumbs }; } /** * 7. 获取指定分类ID下的子分类 * 支持递归获取所有层级的子分类 */ async getSubCategories(categoryId, options) { // 获取所有分类数据 const categories = await this.getCategories(); // 递归查找分类的函数 const findCategoryById = (cats, targetId) => { for (const cat of cats) { if (cat.categoryId === targetId) { return cat; } if (cat.children && cat.children.length > 0) { const found = findCategoryById(cat.children, targetId); if (found) return found; } } return null; }; // 查找目标分类(包括子分类) const targetCategory = findCategoryById(categories, categoryId); if (!targetCategory) { return { subCategories: [], currentCategory: null, total: 0, depth: 0 }; } const subCategories = []; let maxDepth = options?.maxDepth || Infinity; let actualDepth = 0; // 递归获取子分类的函数 const collectSubCategories = (parentId, currentDepth = 0) => { if (currentDepth >= maxDepth) { return; } // 递归查找直接子分类 const findChildren = (cats, parentId) => { const children = []; for (const cat of cats) { if (cat.parentId === parentId) { children.push(cat); } if (cat.children && cat.children.length > 0) { children.push(...findChildren(cat.children, parentId)); } } return children; }; const children = findChildren(categories, parentId); children.forEach(child => { subCategories.push(child); // 如果需要递归且未达到最大深度,继续查找子分类 if (options?.recursive && currentDepth < maxDepth - 1) { collectSubCategories(child.categoryId, currentDepth + 1); } }); // 更新实际深度 actualDepth = Math.max(actualDepth, currentDepth); }; // 开始收集子分类 collectSubCategories(categoryId); // 如果需要包含当前分类,添加到结果中 if (options?.includeCurrent) { subCategories.unshift(targetCategory); } return { subCategories, currentCategory: targetCategory, total: subCategories.length, depth: actualDepth }; } /** * 8. 获取税费信息 * 获取平台的所有税费模板和规则 */ async getTaxInfo() { const config = this.client.getConfig(); return this.client.request(`/tax/platform-${config.platformId}.json`); } /** * 9. 获取运费信息 * 获取平台的所有运费模板和规则 */ async getShippingInfo() { const config = this.client.getConfig(); return this.client.request(`/shipping/platform-${config.platformId}.json`); } /** * 10. 获取区域信息 * 获取平台的所有区域信息,包括层级结构 */ async getRegions() { const config = this.client.getConfig(); return this.client.request(`/regions/platform-${config.platformId}.json`); } /** * 11. 获取支付方式信息 * 获取平台的所有支付方式,包括API支付和手动支付 * @param paymentAlias 支付方式别名,默认为'01' */ async getPaymentMethods(paymentAlias) { const config = this.client.getConfig(); const alias = paymentAlias || '01'; return this.client.request(`/payment/platform-${config.platformId}-${alias}.json`); } /** * 12. 根据支付方式类型获取支付方式列表 * @param type 支付方式类型:'Api' | 'Manual' | 'Gateway' | 'Crypto' * @param paymentAlias 支付方式别名,默认为'01' */ async getPaymentMethodsByType(type, paymentAlias) { const response = await this.getPaymentMethods(paymentAlias); return response.methods.filter(method => method.type === type); } /** * 13. 根据支付方式ID获取特定支付方式详情 * @param methodId 支付方式ID * @param paymentAlias 支付方式别名,默认为'01' */ async getPaymentMethodById(methodId, paymentAlias) { const response = await this.getPaymentMethods(paymentAlias); return response.methods.find(method => method.id === methodId) || null; } /** * 14. 获取支付方式属性值 * @param methodId 支付方式ID * @param attrName 属性名称 * @param paymentAlias 支付方式别名,默认为'01' */ async getPaymentMethodAtt