Package Exports
- @gt6/sdk
Readme
@gt6/sdk
GT6 SDK 是一个用于管理文章、分类和标签的JavaScript/TypeScript库,专门为GT6平台设计。
安装
npm install @gt6/sdk快速开始
基本使用
import { GT6SDK } from '@gt6/sdk';
// 初始化SDK
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492',
rootCategoryId: '671920', // 可选,默认为671920
tagAlias: '001' // 可选,默认为001
});
// 获取文章详情
const article = await sdk.getArticle(921546067);
console.log(article.title);
// 获取分类列表
const categories = await sdk.getCategories();
console.log('分类列表:', categories.map(cat => cat.categoryName));
// 获取标签列表
const tags = await sdk.getTags();
console.log('标签列表:', tags.map(tag => tag.tagName));
// 根据分类获取文章
const categoryArticles = await sdk.getArticlesByCategory(782714);
console.log(`分类文章总数: ${categoryArticles.total}`);
// 根据标签获取文章
const tagArticles = await sdk.getArticlesByTag(136424);
console.log(`标签文章总数: ${tagArticles.total}`);
// 获取分类层级路径
const categoryPath = await sdk.getCategoryPath(782714);
console.log('面包屑路径:', categoryPath.breadcrumbs.map(crumb => crumb.categoryName).join(' > '));
// 获取子分类
const subCategories = await sdk.getSubCategories(671920);
console.log(`子分类数量: ${subCategories.total}`);高级功能
// 按分类获取文章
const categoryArticles = await sdk.getArticlesByCategory(782714);
// 按标签获取文章
const tagArticles = await sdk.getArticlesByTag(136424);
// 获取分类层级路径(用于面包屑导航)
const categoryPath = await sdk.getCategoryPath(782714);
// 获取子分类
const subCategories = await sdk.getSubCategories(671920);
// 获取已发布的文章
const publishedArticles = await sdk.articles.getPublishedArticles();
// 搜索文章
const searchResults = await sdk.articles.searchArticles('CRM');
// 获取文章统计信息
const stats = await sdk.articles.getArticleStats();
console.log(`总文章数: ${stats.total}`);
console.log(`已发布: ${stats.published}`);
console.log(`草稿: ${stats.draft}`);
// 获取推荐文章
const recommended = await sdk.articles.getRecommendedArticles(921546067, 5);在Astro项目中使用
// [id].astro
---
import { GT6SDK } from '@gt6/sdk';
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492'
});
const { id } = Astro.params;
const article = await sdk.getArticle(id);
const recommended = await sdk.articles.getRecommendedArticles(Number(id), 3);
---
<html>
<head>
<title>{article.title}</title>
</head>
<body>
<h1>{article.title}</h1>
<div set:html={article.content}></div>
<h2>推荐文章</h2>
<ul>
{recommended.map(rec => (
<li><a href={`/articles/${rec.articleId}`}>{rec.title}</a></li>
))}
</ul>
</body>
</html>面包屑导航使用示例
基本面包屑导航
// 获取分类层级路径
const categoryPath = await sdk.getCategoryPath(782714);
// 输出面包屑数据
console.log('当前分类:', categoryPath.currentCategory?.categoryName);
console.log('完整路径:', categoryPath.path.map(cat => cat.categoryName).join(' > '));
// 前端面包屑导航使用
categoryPath.breadcrumbs.forEach((crumb, index) => {
if (index < categoryPath.breadcrumbs.length - 1) {
console.log(`<a href="/category/${crumb.categoryId}">${crumb.categoryName}</a> >`);
} else {
console.log(`<span>${crumb.categoryName}</span>`);
}
});在Astro中使用面包屑导航
---
// [categoryId]-[pageId].astro
import { GT6SDK } from '@gt6/sdk';
const { categoryId, pageId } = Astro.params;
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492'
});
// 获取分类层级路径
const categoryPath = await sdk.getCategoryPath(parseInt(categoryId));
const currentCategory = categoryPath.currentCategory;
---
<html>
<head>
<title>{currentCategory?.categoryName} - GT6TRADE</title>
</head>
<body>
<!-- 面包屑导航 -->
<nav aria-label="面包屑导航" class="mb-3">
<ol class="breadcrumb justify-content-center">
<li class="breadcrumb-item">
<a href="/" class="text-decoration-none">首页</a>
</li>
{categoryPath.breadcrumbs.map((crumb, index) => (
<li class={`breadcrumb-item ${index === categoryPath.breadcrumbs.length - 1 ? 'active' : ''}`}>
{index === categoryPath.breadcrumbs.length - 1 ? (
<span>{crumb.categoryName}</span>
) : (
<a href={`/postlist/${crumb.categoryId}-1`} class="text-decoration-none">
{crumb.categoryName}
</a>
)}
</li>
))}
</ol>
</nav>
<h1>{currentCategory?.categoryName}</h1>
<!-- 其他内容 -->
</body>
</html>面包屑导航组件
---
// Breadcrumb.astro
export interface Props {
categoryId: number;
currentPage?: number;
}
const { categoryId, currentPage = 1 } = Astro.props;
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492'
});
const categoryPath = await sdk.getCategoryPath(categoryId);
---
<nav aria-label="面包屑导航" class="mb-3">
<ol class="breadcrumb justify-content-center">
<li class="breadcrumb-item">
<a href="/" class="text-decoration-none">
<i class="bi bi-house"></i> 首页
</a>
</li>
{categoryPath.breadcrumbs.map((crumb, index) => (
<li class={`breadcrumb-item ${index === categoryPath.breadcrumbs.length - 1 ? 'active' : ''}`}>
{index === categoryPath.breadcrumbs.length - 1 ? (
<span>{crumb.categoryName}</span>
) : (
<a href={`/postlist/${crumb.categoryId}-1`} class="text-decoration-none">
{crumb.categoryName}
</a>
)}
</li>
))}
{currentPage > 1 && (
<li class="breadcrumb-item active">
<span>第 {currentPage} 页</span>
</li>
)}
</ol>
</nav>
<style>
.breadcrumb {
background: transparent;
padding: 0.5rem 0;
}
.breadcrumb-item + .breadcrumb-item::before {
content: ">";
color: #6c757d;
}
.breadcrumb-item.active span {
color: #495057;
font-weight: 500;
}
</style>标签面包屑导航组件
---
// TagBreadcrumb.astro
export interface Props {
tagId: number;
currentPage?: number;
baseUrl?: string;
platformId?: string | number;
rootCategoryId?: string | number;
}
const {
tagId,
currentPage = 1,
baseUrl = 'https://data.shopasb.io',
platformId = '1747558688',
rootCategoryId = '969287034'
} = Astro.props;
const sdk = new GT6SDK({
baseUrl,
platformId,
rootCategoryId
});
const tags = await sdk.getTags();
const currentTag = tags.find(tag => tag.tagId === tagId);
---
<nav aria-label="面包屑导航" class="mb-3">
<ol class="breadcrumb justify-content-center">
<li class="breadcrumb-item">
<a href="/" class="text-decoration-none">
<i class="bi bi-house"></i> 首页
</a>
</li>
<li class="breadcrumb-item">
<a href="/tags" class="text-decoration-none">标签</a>
</li>
<li class="breadcrumb-item active">
<span>{currentTag?.tagName || `标签 ${tagId}`}</span>
</li>
{currentPage > 1 && (
<li class="breadcrumb-item active">
<span>第 {currentPage} 页</span>
</li>
)}
</ol>
</nav>
<style>
.breadcrumb {
background: transparent;
padding: 0.5rem 0;
margin-bottom: 0;
}
.breadcrumb-item + .breadcrumb-item::before {
content: ">";
color: #6c757d;
margin: 0 0.5rem;
}
.breadcrumb-item.active span {
color: #495057;
font-weight: 500;
}
.breadcrumb-item a {
color: #6c757d;
text-decoration: none;
}
.breadcrumb-item a:hover {
color: #495057;
text-decoration: underline;
}
.breadcrumb-item i {
margin-right: 0.25rem;
}
</style>在文章详情页使用面包屑导航
---
// [articleId].astro
import { GT6SDK } from '@gt6/sdk';
import Breadcrumb from '../components/Breadcrumb.astro';
const { articleId } = Astro.params;
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492'
});
const article = await sdk.getArticle(articleId);
// 假设文章属于第一个分类
const firstCategoryId = article.categories?.[0]?.categoryId;
const categoryPath = firstCategoryId ? await sdk.getCategoryPath(firstCategoryId) : null;
---
<html>
<head>
<title>{article.title} - GT6TRADE</title>
</head>
<body>
{categoryPath && (
<Breadcrumb categoryId={firstCategoryId} />
)}
<article>
<h1>{article.title}</h1>
<div set:html={article.content}></div>
</article>
</body>
</html>在标签列表页使用面包屑导航
---
// [tagId]-[pageId].astro
import { GT6SDK } from '@gt6/sdk';
import TagBreadcrumb from '../components/TagBreadcrumb.astro';
const { tagId, pageId } = Astro.params;
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492'
});
const currentPage = parseInt(pageId);
const tagArticles = await sdk.getArticlesByTag(parseInt(tagId), {
page: currentPage,
limit: 9,
status: 'published'
});
---
<html>
<head>
<title>标签文章 - GT6TRADE</title>
</head>
<body>
<TagBreadcrumb
tagId={parseInt(tagId)}
currentPage={currentPage}
/>
<section>
<h1>标签文章列表</h1>
<div class="articles">
{tagArticles.articles.map(article => (
<article>
<h2><a href={`/post/${article.articleId}`}>{article.title}</a></h2>
<p>{article.content.substring(0, 200)}...</p>
</article>
))}
</div>
</section>
</body>
</html>新方法使用示例
根据分类获取文章
// 获取单个分类的文章
const result = await sdk.getArticlesByCategory(782714);
console.log(`分类文章总数: ${result.total}`);
console.log(`返回文章数: ${result.articles.length}`);
// 获取多个分类的文章(去重)
const multiResult = await sdk.getArticlesByCategory([782714, 821172]);
console.log(`多分类文章总数: ${multiResult.total}`);
// 使用分页和状态过滤
const paginatedResult = await sdk.getArticlesByCategory(782714, {
offset: 0,
limit: 10,
status: 'published'
});根据标签获取文章
// 获取单个标签的文章
const result = await sdk.getArticlesByTag(136424);
console.log(`标签文章总数: ${result.total}`);
// 获取多个标签的文章(去重)
const multiResult = await sdk.getArticlesByTag([136424, 136425]);
console.log(`多标签文章总数: ${multiResult.total}`);
// 使用分页和状态过滤
const paginatedResult = await sdk.getArticlesByTag(136424, {
offset: 0,
limit: 10,
status: 'published'
});
// 指定标签别名获取文章
const customTagResult = await sdk.getArticlesByTag(136424, {
tagAlias: 'custom', // 使用自定义标签别名
limit: 10,
status: 'published'
});获取分类层级路径(面包屑导航)
// 获取分类的完整层级路径
const pathResult = await sdk.getCategoryPath(821172);
// 输出面包屑导航数据
console.log('当前分类:', pathResult.currentCategory?.categoryName);
console.log('完整路径:', pathResult.path.map(cat => cat.categoryName).join(' > '));
// 前端面包屑导航使用
pathResult.breadcrumbs.forEach((crumb, index) => {
if (index < pathResult.breadcrumbs.length - 1) {
console.log(`<a href="/category/${crumb.categoryId}">${crumb.categoryName}</a> >`);
} else {
console.log(`<span>${crumb.categoryName}</span>`);
}
});获取子分类
// 获取直接子分类
const result = await sdk.getSubCategories(671920);
console.log(`子分类数量: ${result.total}`);
console.log(`递归深度: ${result.depth}`);
// 递归获取所有层级的子分类
const recursiveResult = await sdk.getSubCategories(671920, {
recursive: true
});
console.log(`所有子分类数量: ${recursiveResult.total}`);
// 包含当前分类
const includeCurrentResult = await sdk.getSubCategories(671920, {
includeCurrent: true
});
console.log(`包含当前分类的总数量: ${includeCurrentResult.total}`);
// 限制递归深度
const limitedResult = await sdk.getSubCategories(671920, {
recursive: true,
maxDepth: 2
});
console.log(`限制深度后的子分类数量: ${limitedResult.total}`);在Astro中使用面包屑导航
---
// Breadcrumb.astro
import { GT6SDK } from '@gt6/sdk';
const { categoryId } = Astro.props;
const sdk = new GT6SDK({ baseUrl: 'https://data.shopasb.io', platformId: '1750838492' });
const pathResult = await sdk.articles.getCategoryPath(categoryId);
---
<nav class="breadcrumb">
<ol>
<li><a href="/">首页</a></li>
{pathResult.breadcrumbs.map((crumb, index) => (
<li>
{index === pathResult.breadcrumbs.length - 1 ? (
<span>{crumb.categoryName}</span>
) : (
<a href={`/category/${crumb.categoryId}`}>{crumb.categoryName}</a>
)}
{index < pathResult.breadcrumbs.length - 1 && <span> > </span>}
</li>
))}
</ol>
</nav>在Astro中使用分类树导航
---
// CategoryTree.astro
import { GT6SDK } from '@gt6/sdk';
const { categoryId, recursive = false, maxDepth = 3 } = Astro.props;
const sdk = new GT6SDK({ baseUrl: 'https://data.shopasb.io', platformId: '1750838492' });
const result = await sdk.articles.getSubCategories(categoryId, { recursive, maxDepth });
---
<div class="category-tree">
<h3>{result.currentCategory?.categoryName}</h3>
<ul>
{result.subCategories.map(category => (
<li>
<a href={`/category/${category.categoryId}`}>
{category.categoryName} ({category.articleIds.length})
</a>
</li>
))}
</ul>
</div>API 参考
GT6SDK 类
构造函数
new GT6SDK(config: GT6Config)配置参数:
baseUrl(string): API基础URLplatformId(string | number): 平台IDrootCategoryId(string | number, 可选): 根分类ID,默认为'671920'tagAlias(string, 可选): 标签别名,默认为'001'timeout(number, 可选): 请求超时时间,默认为10000mscache(object, 可选): 缓存配置enabled(boolean): 是否启用缓存,默认为truettl(number): 缓存时间,默认为300000ms (5分钟)
方法
便捷方法
getArticle(articleId: number | string): Promise<Article>getCategories(rootCategoryId?: number | string): Promise<Category[]>getTags(tagAlias?: string): Promise<Tag[]>getArticlesByCategory(categoryId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; categoryIds: number[] }>getArticlesByTag(tagId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; tagIds: number[] }>getCategoryPath(categoryId: number): Promise<{ path: Category[]; currentCategory: Category | null; breadcrumbs: Array<{ categoryId: number; categoryName: string; level: number }> }>getSubCategories(categoryId: number, options?: { recursive?: boolean; includeCurrent?: boolean; maxDepth?: number }): Promise<{ subCategories: Category[]; currentCategory: Category | null; total: number; depth: number }>
缓存管理
clearCache(): void- 清除所有缓存getCacheStats()- 获取缓存统计信息
ArticlesAPI 类
文章相关方法
getArticle(articleId: number | string): Promise<Article>getArticles(params?: ArticleQueryParams): Promise<Article[]>getArticleList(params?: ArticleQueryParams): Promise<ArticleListItem[]>getArticlesByCategory(categoryId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; categoryIds: number[] }>getArticlesByTag(tagId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; tagIds: number[] }>getCategoryPath(categoryId: number): Promise<{ path: Category[]; currentCategory: Category | null; breadcrumbs: Array<{ categoryId: number; categoryName: string; level: number }> }>getSubCategories(categoryId: number, options?: { recursive?: boolean; includeCurrent?: boolean; maxDepth?: number }): Promise<{ subCategories: Category[]; currentCategory: Category | null; total: number; depth: number }>getPublishedArticles(params?: Omit<ArticleQueryParams, 'status'>): Promise<Article[]>searchArticles(query: string, params?: ArticleQueryParams): Promise<Article[]>getRecommendedArticles(articleId: number, limit?: number): Promise<Article[]>
分类和标签方法
getCategories(rootCategoryId?: number | string): Promise<Category[]>getTags(tagAlias?: string): Promise<Tag[]>
统计方法
getArticleStats(): Promise<ArticleStats>
数据类型
Article (文章)
interface Article {
articleId: number;
title: string;
content: string;
status: 'published' | 'draft' | 'archived';
publishedAt: string;
templateId: number;
aiId: number;
platformId: number;
isVisible: boolean;
displayTemplate: string;
createdAt: any;
updatedAt: any;
categories: Category[];
tags: Tag[];
metaData: ArticleMetaData[];
images: ArticleImage[];
generatedAt: string;
}Category (分类)
interface Category {
categoryId: number;
categoryName: string;
categoryDescription: string;
metaKeywords: string;
status: number;
parentId: number;
sortOrder: number;
createdAt: any;
updatedAt: any;
platformId: number;
articleIds: number[];
children: Category[];
}Tag (标签)
interface Tag {
tagId: number;
tagName: string;
type: number;
platformId: number;
aliases: string;
createdAt: any;
articleIds: number[];
}错误处理
SDK使用自定义的 GT6Error 类来处理错误:
import { GT6Error } from '@gt6/sdk';
try {
const article = await sdk.getArticle(999999);
} catch (error) {
if (error instanceof GT6Error) {
console.error(`错误: ${error.message}`);
console.error(`状态码: ${error.status}`);
}
}缓存机制
SDK内置缓存机制,默认缓存5分钟:
const sdk = new GT6SDK({
baseUrl: 'https://data.shopasb.io',
platformId: '1750838492',
cache: {
enabled: true,
ttl: 300000 // 5分钟
}
});
// 清除缓存
sdk.clearCache();
// 获取缓存统计
const stats = sdk.getCacheStats();
console.log(`缓存条目数: ${stats.size}`);开发
安装依赖
npm install构建
npm run build测试
npm test类型检查
npm run type-check许可证
MIT