@gt6/sdk 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,42 @@ npm install @gt6/sdk
10
10
 
11
11
  ## 快速开始
12
12
 
13
+ ### 基础配置
14
+
15
+ ```typescript
16
+ import { GT6SDK } from '@gt6/sdk';
17
+
18
+ const sdk = new GT6SDK({
19
+ baseUrl: 'https://data.shopasb.io',
20
+ platformId: '1747558688',
21
+ // 文章相关配置
22
+ rootCategoryId: '969287034', // 文章根分类ID
23
+ tagAlias: '002', // 文章标签别名
24
+ // 产品相关配置
25
+ productRootCategoryId: '277233', // 产品根分类ID
26
+ productTagAlias: '01', // 产品标签别名
27
+ // 缓存配置
28
+ cache: {
29
+ enabled: true,
30
+ ttl: 300000 // 5分钟
31
+ }
32
+ });
33
+ ```
34
+
35
+ ### 配置选项
36
+
37
+ | 字段 | 类型 | 必需 | 默认值 | 描述 |
38
+ |------|------|------|--------|------|
39
+ | `baseUrl` | string | ✅ | - | API 基础URL |
40
+ | `platformId` | string \| number | ✅ | - | 平台ID |
41
+ | `rootCategoryId` | string \| number | ❌ | '671920' | 文章根分类ID |
42
+ | `tagAlias` | string | ❌ | '001' | 文章标签别名 |
43
+ | `productRootCategoryId` | string \| number | ❌ | '277233' | 产品根分类ID |
44
+ | `productTagAlias` | string | ❌ | '01' | 产品标签别名 |
45
+ | `timeout` | number | ❌ | 10000 | 请求超时时间(毫秒) |
46
+ | `cache.enabled` | boolean | ❌ | true | 是否启用缓存 |
47
+ | `cache.ttl` | number | ❌ | 300000 | 缓存时间(毫秒) |
48
+
13
49
  ### 基本使用
14
50
 
15
51
  ```typescript
@@ -18,9 +54,15 @@ import { GT6SDK } from '@gt6/sdk';
18
54
  // 初始化SDK
19
55
  const sdk = new GT6SDK({
20
56
  baseUrl: 'https://data.shopasb.io',
21
- platformId: '1750838492',
22
- rootCategoryId: '671920', // 可选,默认为671920
23
- tagAlias: '001' // 可选,默认为001
57
+ platformId: '1747558688',
58
+ rootCategoryId: '969287034', // 可选,默认为671920
59
+ tagAlias: '002', // 可选,默认为001
60
+ productRootCategoryId: '277233',
61
+ productTagAlias: '01',
62
+ cache: {
63
+ enabled: true,
64
+ ttl: 300000
65
+ }
24
66
  });
25
67
 
26
68
  // 获取文章详情
@@ -40,7 +82,7 @@ const categoryArticles = await sdk.getArticlesByCategory(782714);
40
82
  console.log(`分类文章总数: ${categoryArticles.total}`);
41
83
 
42
84
  // 根据标签获取文章
43
- const tagArticles = await sdk.getArticlesByTag(136424);
85
+ const tagArticles = await sdk.getArticlesByTag(236656846);
44
86
  console.log(`标签文章总数: ${tagArticles.total}`);
45
87
 
46
88
  // 获取分类层级路径
@@ -59,7 +101,7 @@ console.log(`子分类数量: ${subCategories.total}`);
59
101
  const categoryArticles = await sdk.getArticlesByCategory(782714);
60
102
 
61
103
  // 按标签获取文章
62
- const tagArticles = await sdk.getArticlesByTag(136424);
104
+ const tagArticles = await sdk.getArticlesByTag(236656846);
63
105
 
64
106
  // 获取分类层级路径(用于面包屑导航)
65
107
  const categoryPath = await sdk.getCategoryPath(782714);
@@ -92,7 +134,15 @@ import { GT6SDK } from '@gt6/sdk';
92
134
 
93
135
  const sdk = new GT6SDK({
94
136
  baseUrl: 'https://data.shopasb.io',
95
- platformId: '1750838492'
137
+ platformId: '1747558688',
138
+ rootCategoryId: '969287034',
139
+ tagAlias: '002',
140
+ productRootCategoryId: '277233',
141
+ productTagAlias: '01',
142
+ cache: {
143
+ enabled: true,
144
+ ttl: 300000
145
+ }
96
146
  });
97
147
 
98
148
  const { id } = Astro.params;
@@ -118,21 +168,127 @@ const recommended = await sdk.articles.getRecommendedArticles(Number(id), 3);
118
168
  </html>
119
169
  ```
120
170
 
121
- ### 面包屑导航使用示例
171
+ ## API 参考
122
172
 
123
- #### 基本面包屑导航
173
+ ### GT6SDK 类
174
+
175
+ #### 构造函数
124
176
 
125
177
  ```typescript
126
- // 获取分类层级路径
127
- const categoryPath = await sdk.getCategoryPath(782714);
178
+ new GT6SDK(config: GT6Config)
179
+ ```
180
+
181
+ **配置参数:**
128
182
 
129
- // 输出面包屑数据
130
- console.log('当前分类:', categoryPath.currentCategory?.categoryName);
131
- console.log('完整路径:', categoryPath.path.map(cat => cat.categoryName).join(' > '));
183
+ - `baseUrl` (string): API基础URL
184
+ - `platformId` (string | number): 平台ID
185
+ - `rootCategoryId` (string | number, 可选): 根分类ID,默认为'671920'
186
+ - `tagAlias` (string, 可选): 标签别名,默认为'001'
187
+ - `timeout` (number, 可选): 请求超时时间,默认为10000ms
188
+ - `cache` (object, 可选): 缓存配置
189
+ - `enabled` (boolean): 是否启用缓存,默认为true
190
+ - `ttl` (number): 缓存时间,默认为300000ms (5分钟)
191
+
192
+ #### 便捷方法
193
+
194
+ - `getArticle(articleId: number | string): Promise<Article>`
195
+ - `getCategories(rootCategoryId?: number | string): Promise<Category[]>`
196
+ - `getTags(tagAlias?: string): Promise<Tag[]>`
197
+ - `getArticlesByCategory(categoryId: number | number[], options?: ArticlesByCategoryOptions): Promise<{ articles: Article[]; total: number; page: number; limit: number }>`
198
+ - `getArticlesByTag(tagId: number | number[], options?: ArticlesByTagOptions): Promise<{ articles: Article[]; total: number; page: number; limit: number }>`
199
+ - `getCategoryPath(categoryId: number): Promise<{ path: Category[]; currentCategory: Category | null; breadcrumbs: Array<{ categoryId: number; categoryName: string; level: number }> }>`
200
+ - `getSubCategories(categoryId: number, options?: { recursive?: boolean; includeCurrent?: boolean; maxDepth?: number }): Promise<{ subCategories: Category[]; currentCategory: Category | null; total: number; depth: number }>`
201
+
202
+ #### 缓存管理
203
+
204
+ - `clearCache(): void` - 清除所有缓存
205
+ - `getCacheStats()` - 获取缓存统计信息
206
+
207
+ ### ArticlesAPI 类
208
+
209
+ #### 文章相关方法
210
+
211
+ - `getArticle(articleId: number | string): Promise<Article>`
212
+ - `getArticles(params?: ArticleQueryParams): Promise<Article[]>`
213
+ - `getArticleList(params?: ArticleQueryParams): Promise<ArticleListItem[]>`
214
+ - `getArticlesByCategory(categoryId: number | number[], options?: ArticlesByCategoryOptions): Promise<{ articles: Article[]; total: number; page: number; limit: number }>`
215
+ - `getArticlesByTag(tagId: number | number[], options?: ArticlesByTagOptions): Promise<{ articles: Article[]; total: number; page: number; limit: number }>`
216
+ - `getCategoryPath(categoryId: number): Promise<{ path: Category[]; currentCategory: Category | null; breadcrumbs: Array<{ categoryId: number; categoryName: string; level: number }> }>`
217
+ - `getSubCategories(categoryId: number, options?: { recursive?: boolean; includeCurrent?: boolean; maxDepth?: number }): Promise<{ subCategories: Category[]; currentCategory: Category | null; total: number; depth: number }>`
218
+ - `getPublishedArticles(params?: Omit<ArticleQueryParams, 'status'>): Promise<Article[]>`
219
+ - `searchArticles(query: string, params?: ArticleQueryParams): Promise<Article[]>`
220
+ - `getRecommendedArticles(articleId: number, limit?: number): Promise<Article[]>`
221
+
222
+ #### 分类和标签方法
223
+
224
+ - `getCategories(rootCategoryId?: number | string): Promise<Category[]>`
225
+ - `getTags(tagAlias?: string): Promise<Tag[]>`
226
+
227
+ #### 统计方法
228
+
229
+ - `getArticleStats(): Promise<ArticleStats>`
230
+
231
+ ## 使用示例
232
+
233
+ ### 根据分类获取文章
234
+
235
+ ```typescript
236
+ // 获取单个分类的文章
237
+ const result = await sdk.getArticlesByCategory(782714);
238
+ console.log(`分类文章总数: ${result.total}`);
239
+ console.log(`返回文章数: ${result.articles.length}`);
240
+
241
+ // 获取多个分类的文章(去重)
242
+ const multiResult = await sdk.getArticlesByCategory([782714, 821172]);
243
+ console.log(`多分类文章总数: ${multiResult.total}`);
244
+
245
+ // 使用分页和状态过滤
246
+ const paginatedResult = await sdk.getArticlesByCategory(782714, {
247
+ page: 1,
248
+ limit: 10,
249
+ status: 'published'
250
+ });
251
+ ```
252
+
253
+ ### 根据标签获取文章
254
+
255
+ ```typescript
256
+ // 获取单个标签的文章
257
+ const result = await sdk.getArticlesByTag(236656846);
258
+ console.log(`标签文章总数: ${result.total}`);
259
+
260
+ // 获取多个标签的文章(去重)
261
+ const multiResult = await sdk.getArticlesByTag([236656846, 497329737]);
262
+ console.log(`多标签文章总数: ${multiResult.total}`);
263
+
264
+ // 使用分页和状态过滤
265
+ const paginatedResult = await sdk.getArticlesByTag(236656846, {
266
+ page: 1,
267
+ limit: 10,
268
+ status: 'published'
269
+ });
270
+
271
+ // 指定标签别名获取文章
272
+ const customTagResult = await sdk.getArticlesByTag(236656846, {
273
+ tagAlias: '002', // 使用自定义标签别名
274
+ limit: 10,
275
+ status: 'published'
276
+ });
277
+ ```
278
+
279
+ ### 获取分类层级路径(面包屑导航)
280
+
281
+ ```typescript
282
+ // 获取分类的完整层级路径
283
+ const pathResult = await sdk.getCategoryPath(821172);
284
+
285
+ // 输出面包屑导航数据
286
+ console.log('当前分类:', pathResult.currentCategory?.categoryName);
287
+ console.log('完整路径:', pathResult.path.map(cat => cat.categoryName).join(' > '));
132
288
 
133
289
  // 前端面包屑导航使用
134
- categoryPath.breadcrumbs.forEach((crumb, index) => {
135
- if (index < categoryPath.breadcrumbs.length - 1) {
290
+ pathResult.breadcrumbs.forEach((crumb, index) => {
291
+ if (index < pathResult.breadcrumbs.length - 1) {
136
292
  console.log(`<a href="/category/${crumb.categoryId}">${crumb.categoryName}</a> >`);
137
293
  } else {
138
294
  console.log(`<span>${crumb.categoryName}</span>`);
@@ -140,56 +296,37 @@ categoryPath.breadcrumbs.forEach((crumb, index) => {
140
296
  });
141
297
  ```
142
298
 
143
- #### 在Astro中使用面包屑导航
299
+ ### 获取子分类
144
300
 
145
- ```astro
146
- ---
147
- // [categoryId]-[pageId].astro
148
- import { GT6SDK } from '@gt6/sdk';
301
+ ```typescript
302
+ // 获取直接子分类
303
+ const result = await sdk.getSubCategories(671920);
304
+ console.log(`子分类数量: ${result.total}`);
305
+ console.log(`递归深度: ${result.depth}`);
149
306
 
150
- const { categoryId, pageId } = Astro.params;
151
- const sdk = new GT6SDK({
152
- baseUrl: 'https://data.shopasb.io',
153
- platformId: '1750838492'
307
+ // 递归获取所有层级的子分类
308
+ const recursiveResult = await sdk.getSubCategories(671920, {
309
+ recursive: true
154
310
  });
311
+ console.log(`所有子分类数量: ${recursiveResult.total}`);
155
312
 
156
- // 获取分类层级路径
157
- const categoryPath = await sdk.getCategoryPath(parseInt(categoryId));
158
- const currentCategory = categoryPath.currentCategory;
159
- ---
313
+ // 包含当前分类
314
+ const includeCurrentResult = await sdk.getSubCategories(671920, {
315
+ includeCurrent: true
316
+ });
317
+ console.log(`包含当前分类的总数量: ${includeCurrentResult.total}`);
160
318
 
161
- <html>
162
- <head>
163
- <title>{currentCategory?.categoryName} - GT6TRADE</title>
164
- </head>
165
- <body>
166
- <!-- 面包屑导航 -->
167
- <nav aria-label="面包屑导航" class="mb-3">
168
- <ol class="breadcrumb justify-content-center">
169
- <li class="breadcrumb-item">
170
- <a href="/" class="text-decoration-none">首页</a>
171
- </li>
172
- {categoryPath.breadcrumbs.map((crumb, index) => (
173
- <li class={`breadcrumb-item ${index === categoryPath.breadcrumbs.length - 1 ? 'active' : ''}`}>
174
- {index === categoryPath.breadcrumbs.length - 1 ? (
175
- <span>{crumb.categoryName}</span>
176
- ) : (
177
- <a href={`/postlist/${crumb.categoryId}-1`} class="text-decoration-none">
178
- {crumb.categoryName}
179
- </a>
180
- )}
181
- </li>
182
- ))}
183
- </ol>
184
- </nav>
185
-
186
- <h1>{currentCategory?.categoryName}</h1>
187
- <!-- 其他内容 -->
188
- </body>
189
- </html>
319
+ // 限制递归深度
320
+ const limitedResult = await sdk.getSubCategories(671920, {
321
+ recursive: true,
322
+ maxDepth: 2
323
+ });
324
+ console.log(`限制深度后的子分类数量: ${limitedResult.total}`);
190
325
  ```
191
326
 
192
- #### 面包屑导航组件
327
+ ## 在Astro中使用
328
+
329
+ ### 面包屑导航组件
193
330
 
194
331
  ```astro
195
332
  ---
@@ -202,7 +339,15 @@ export interface Props {
202
339
  const { categoryId, currentPage = 1 } = Astro.props;
203
340
  const sdk = new GT6SDK({
204
341
  baseUrl: 'https://data.shopasb.io',
205
- platformId: '1750838492'
342
+ platformId: '1747558688',
343
+ rootCategoryId: '969287034',
344
+ tagAlias: '002',
345
+ productRootCategoryId: '277233',
346
+ productTagAlias: '01',
347
+ cache: {
348
+ enabled: true,
349
+ ttl: 300000
350
+ }
206
351
  });
207
352
  const categoryPath = await sdk.getCategoryPath(categoryId);
208
353
  ---
@@ -251,7 +396,7 @@ const categoryPath = await sdk.getCategoryPath(categoryId);
251
396
  </style>
252
397
  ```
253
398
 
254
- #### 标签面包屑导航组件
399
+ ### 标签面包屑导航组件
255
400
 
256
401
  ```astro
257
402
  ---
@@ -269,13 +414,21 @@ const {
269
414
  currentPage = 1,
270
415
  baseUrl = 'https://data.shopasb.io',
271
416
  platformId = '1747558688',
272
- rootCategoryId = '969287034'
417
+ rootCategoryId = '969287034',
418
+ productRootCategoryId = '277233',
419
+ productTagAlias = '01'
273
420
  } = Astro.props;
274
421
 
275
422
  const sdk = new GT6SDK({
276
423
  baseUrl,
277
424
  platformId,
278
- rootCategoryId
425
+ rootCategoryId,
426
+ productRootCategoryId,
427
+ productTagAlias,
428
+ cache: {
429
+ enabled: true,
430
+ ttl: 300000
431
+ }
279
432
  });
280
433
  const tags = await sdk.getTags();
281
434
  const currentTag = tags.find(tag => tag.tagId === tagId);
@@ -336,44 +489,67 @@ const currentTag = tags.find(tag => tag.tagId === tagId);
336
489
  </style>
337
490
  ```
338
491
 
339
- #### 在文章详情页使用面包屑导航
492
+ ### 分类列表页面
340
493
 
341
494
  ```astro
342
495
  ---
343
- // [articleId].astro
496
+ // [categoryId]-[pageId].astro
344
497
  import { GT6SDK } from '@gt6/sdk';
345
498
  import Breadcrumb from '../components/Breadcrumb.astro';
346
499
 
347
- const { articleId } = Astro.params;
500
+ const { categoryId, pageId } = Astro.params;
348
501
  const sdk = new GT6SDK({
349
502
  baseUrl: 'https://data.shopasb.io',
350
- platformId: '1750838492'
503
+ platformId: '1747558688',
504
+ rootCategoryId: '969287034',
505
+ tagAlias: '002',
506
+ productRootCategoryId: '277233',
507
+ productTagAlias: '01',
508
+ cache: {
509
+ enabled: true,
510
+ ttl: 300000
511
+ }
351
512
  });
352
513
 
353
- const article = await sdk.getArticle(articleId);
354
- // 假设文章属于第一个分类
355
- const firstCategoryId = article.categories?.[0]?.categoryId;
356
- const categoryPath = firstCategoryId ? await sdk.getCategoryPath(firstCategoryId) : null;
514
+ const currentPage = parseInt(pageId);
515
+ const categoryArticles = await sdk.getArticlesByCategory(parseInt(categoryId), {
516
+ page: currentPage,
517
+ limit: 9,
518
+ status: 'published'
519
+ });
520
+
521
+ const categoryPath = await sdk.getCategoryPath(parseInt(categoryId));
522
+ const currentCategory = categoryPath.currentCategory;
357
523
  ---
358
524
 
359
525
  <html>
360
526
  <head>
361
- <title>{article.title} - GT6TRADE</title>
527
+ <title>{currentCategory?.categoryName} - GT6TRADE</title>
362
528
  </head>
363
529
  <body>
364
- {categoryPath && (
365
- <Breadcrumb categoryId={firstCategoryId} />
366
- )}
530
+ <Breadcrumb
531
+ categoryId={parseInt(categoryId)}
532
+ currentPage={currentPage}
533
+ />
367
534
 
368
- <article>
369
- <h1>{article.title}</h1>
370
- <div set:html={article.content}></div>
371
- </article>
535
+ <section>
536
+ <h1>{currentCategory?.categoryName}</h1>
537
+ <p>共 {categoryArticles.total} 篇文章</p>
538
+
539
+ <div class="articles">
540
+ {categoryArticles.articles.map(article => (
541
+ <article>
542
+ <h2><a href={`/post/${article.articleId}`}>{article.title}</a></h2>
543
+ <p>{article.content.substring(0, 200)}...</p>
544
+ </article>
545
+ ))}
546
+ </div>
547
+ </section>
372
548
  </body>
373
549
  </html>
374
550
  ```
375
551
 
376
- #### 在标签列表页使用面包屑导航
552
+ ### 标签列表页面
377
553
 
378
554
  ```astro
379
555
  ---
@@ -384,20 +560,32 @@ import TagBreadcrumb from '../components/TagBreadcrumb.astro';
384
560
  const { tagId, pageId } = Astro.params;
385
561
  const sdk = new GT6SDK({
386
562
  baseUrl: 'https://data.shopasb.io',
387
- platformId: '1750838492'
563
+ platformId: '1747558688',
564
+ rootCategoryId: '969287034',
565
+ tagAlias: '002',
566
+ productRootCategoryId: '277233',
567
+ productTagAlias: '01',
568
+ cache: {
569
+ enabled: true,
570
+ ttl: 300000
571
+ }
388
572
  });
389
573
 
390
574
  const currentPage = parseInt(pageId);
391
575
  const tagArticles = await sdk.getArticlesByTag(parseInt(tagId), {
392
576
  page: currentPage,
393
577
  limit: 9,
394
- status: 'published'
578
+ status: 'published',
579
+ tagAlias: '002'
395
580
  });
581
+
582
+ const tags = await sdk.getTags('002');
583
+ const currentTag = tags.find(tag => tag.tagId === parseInt(tagId));
396
584
  ---
397
585
 
398
586
  <html>
399
587
  <head>
400
- <title>标签文章 - GT6TRADE</title>
588
+ <title>{currentTag?.tagName} - GT6TRADE</title>
401
589
  </head>
402
590
  <body>
403
591
  <TagBreadcrumb
@@ -406,7 +594,9 @@ const tagArticles = await sdk.getArticlesByTag(parseInt(tagId), {
406
594
  />
407
595
 
408
596
  <section>
409
- <h1>标签文章列表</h1>
597
+ <h1>{currentTag?.tagName}</h1>
598
+ <p>共 {tagArticles.total} 篇文章</p>
599
+
410
600
  <div class="articles">
411
601
  {tagArticles.articles.map(article => (
412
602
  <article>
@@ -420,219 +610,6 @@ const tagArticles = await sdk.getArticlesByTag(parseInt(tagId), {
420
610
  </html>
421
611
  ```
422
612
 
423
- ### 新方法使用示例
424
-
425
- #### 根据分类获取文章
426
-
427
- ```typescript
428
- // 获取单个分类的文章
429
- const result = await sdk.getArticlesByCategory(782714);
430
- console.log(`分类文章总数: ${result.total}`);
431
- console.log(`返回文章数: ${result.articles.length}`);
432
-
433
- // 获取多个分类的文章(去重)
434
- const multiResult = await sdk.getArticlesByCategory([782714, 821172]);
435
- console.log(`多分类文章总数: ${multiResult.total}`);
436
-
437
- // 使用分页和状态过滤
438
- const paginatedResult = await sdk.getArticlesByCategory(782714, {
439
- offset: 0,
440
- limit: 10,
441
- status: 'published'
442
- });
443
- ```
444
-
445
- #### 根据标签获取文章
446
-
447
- ```typescript
448
- // 获取单个标签的文章
449
- const result = await sdk.getArticlesByTag(136424);
450
- console.log(`标签文章总数: ${result.total}`);
451
-
452
- // 获取多个标签的文章(去重)
453
- const multiResult = await sdk.getArticlesByTag([136424, 136425]);
454
- console.log(`多标签文章总数: ${multiResult.total}`);
455
-
456
- // 使用分页和状态过滤
457
- const paginatedResult = await sdk.getArticlesByTag(136424, {
458
- offset: 0,
459
- limit: 10,
460
- status: 'published'
461
- });
462
-
463
- // 指定标签别名获取文章
464
- const customTagResult = await sdk.getArticlesByTag(136424, {
465
- tagAlias: 'custom', // 使用自定义标签别名
466
- limit: 10,
467
- status: 'published'
468
- });
469
- ```
470
-
471
- #### 获取分类层级路径(面包屑导航)
472
-
473
- ```typescript
474
- // 获取分类的完整层级路径
475
- const pathResult = await sdk.getCategoryPath(821172);
476
-
477
- // 输出面包屑导航数据
478
- console.log('当前分类:', pathResult.currentCategory?.categoryName);
479
- console.log('完整路径:', pathResult.path.map(cat => cat.categoryName).join(' > '));
480
-
481
- // 前端面包屑导航使用
482
- pathResult.breadcrumbs.forEach((crumb, index) => {
483
- if (index < pathResult.breadcrumbs.length - 1) {
484
- console.log(`<a href="/category/${crumb.categoryId}">${crumb.categoryName}</a> >`);
485
- } else {
486
- console.log(`<span>${crumb.categoryName}</span>`);
487
- }
488
- });
489
- ```
490
-
491
- #### 获取子分类
492
-
493
- ```typescript
494
- // 获取直接子分类
495
- const result = await sdk.getSubCategories(671920);
496
- console.log(`子分类数量: ${result.total}`);
497
- console.log(`递归深度: ${result.depth}`);
498
-
499
- // 递归获取所有层级的子分类
500
- const recursiveResult = await sdk.getSubCategories(671920, {
501
- recursive: true
502
- });
503
- console.log(`所有子分类数量: ${recursiveResult.total}`);
504
-
505
- // 包含当前分类
506
- const includeCurrentResult = await sdk.getSubCategories(671920, {
507
- includeCurrent: true
508
- });
509
- console.log(`包含当前分类的总数量: ${includeCurrentResult.total}`);
510
-
511
- // 限制递归深度
512
- const limitedResult = await sdk.getSubCategories(671920, {
513
- recursive: true,
514
- maxDepth: 2
515
- });
516
- console.log(`限制深度后的子分类数量: ${limitedResult.total}`);
517
- ```
518
-
519
- #### 在Astro中使用面包屑导航
520
-
521
- ```astro
522
- ---
523
- // Breadcrumb.astro
524
- import { GT6SDK } from '@gt6/sdk';
525
-
526
- const { categoryId } = Astro.props;
527
- const sdk = new GT6SDK({ baseUrl: 'https://data.shopasb.io', platformId: '1750838492' });
528
- const pathResult = await sdk.articles.getCategoryPath(categoryId);
529
- ---
530
-
531
- <nav class="breadcrumb">
532
- <ol>
533
- <li><a href="/">首页</a></li>
534
- {pathResult.breadcrumbs.map((crumb, index) => (
535
- <li>
536
- {index === pathResult.breadcrumbs.length - 1 ? (
537
- <span>{crumb.categoryName}</span>
538
- ) : (
539
- <a href={`/category/${crumb.categoryId}`}>{crumb.categoryName}</a>
540
- )}
541
- {index < pathResult.breadcrumbs.length - 1 && <span> > </span>}
542
- </li>
543
- ))}
544
- </ol>
545
- </nav>
546
- ```
547
-
548
- #### 在Astro中使用分类树导航
549
-
550
- ```astro
551
- ---
552
- // CategoryTree.astro
553
- import { GT6SDK } from '@gt6/sdk';
554
-
555
- const { categoryId, recursive = false, maxDepth = 3 } = Astro.props;
556
- const sdk = new GT6SDK({ baseUrl: 'https://data.shopasb.io', platformId: '1750838492' });
557
- const result = await sdk.articles.getSubCategories(categoryId, { recursive, maxDepth });
558
- ---
559
-
560
- <div class="category-tree">
561
- <h3>{result.currentCategory?.categoryName}</h3>
562
- <ul>
563
- {result.subCategories.map(category => (
564
- <li>
565
- <a href={`/category/${category.categoryId}`}>
566
- {category.categoryName} ({category.articleIds.length})
567
- </a>
568
- </li>
569
- ))}
570
- </ul>
571
- </div>
572
- ```
573
-
574
- ## API 参考
575
-
576
- ### GT6SDK 类
577
-
578
- #### 构造函数
579
-
580
- ```typescript
581
- new GT6SDK(config: GT6Config)
582
- ```
583
-
584
- **配置参数:**
585
-
586
- - `baseUrl` (string): API基础URL
587
- - `platformId` (string | number): 平台ID
588
- - `rootCategoryId` (string | number, 可选): 根分类ID,默认为'671920'
589
- - `tagAlias` (string, 可选): 标签别名,默认为'001'
590
- - `timeout` (number, 可选): 请求超时时间,默认为10000ms
591
- - `cache` (object, 可选): 缓存配置
592
- - `enabled` (boolean): 是否启用缓存,默认为true
593
- - `ttl` (number): 缓存时间,默认为300000ms (5分钟)
594
-
595
- #### 方法
596
-
597
- ##### 便捷方法
598
-
599
- - `getArticle(articleId: number | string): Promise<Article>`
600
- - `getCategories(rootCategoryId?: number | string): Promise<Category[]>`
601
- - `getTags(tagAlias?: string): Promise<Tag[]>`
602
- - `getArticlesByCategory(categoryId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; categoryIds: number[] }>`
603
- - `getArticlesByTag(tagId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; tagIds: number[] }>`
604
- - `getCategoryPath(categoryId: number): Promise<{ path: Category[]; currentCategory: Category | null; breadcrumbs: Array<{ categoryId: number; categoryName: string; level: number }> }>`
605
- - `getSubCategories(categoryId: number, options?: { recursive?: boolean; includeCurrent?: boolean; maxDepth?: number }): Promise<{ subCategories: Category[]; currentCategory: Category | null; total: number; depth: number }>`
606
-
607
- ##### 缓存管理
608
-
609
- - `clearCache(): void` - 清除所有缓存
610
- - `getCacheStats()` - 获取缓存统计信息
611
-
612
- ### ArticlesAPI 类
613
-
614
- #### 文章相关方法
615
-
616
- - `getArticle(articleId: number | string): Promise<Article>`
617
- - `getArticles(params?: ArticleQueryParams): Promise<Article[]>`
618
- - `getArticleList(params?: ArticleQueryParams): Promise<ArticleListItem[]>`
619
- - `getArticlesByCategory(categoryId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; categoryIds: number[] }>`
620
- - `getArticlesByTag(tagId: number | number[], options?: { offset?: number; limit?: number; status?: string }): Promise<{ articles: Article[]; total: number; tagIds: number[] }>`
621
- - `getCategoryPath(categoryId: number): Promise<{ path: Category[]; currentCategory: Category | null; breadcrumbs: Array<{ categoryId: number; categoryName: string; level: number }> }>`
622
- - `getSubCategories(categoryId: number, options?: { recursive?: boolean; includeCurrent?: boolean; maxDepth?: number }): Promise<{ subCategories: Category[]; currentCategory: Category | null; total: number; depth: number }>`
623
- - `getPublishedArticles(params?: Omit<ArticleQueryParams, 'status'>): Promise<Article[]>`
624
- - `searchArticles(query: string, params?: ArticleQueryParams): Promise<Article[]>`
625
- - `getRecommendedArticles(articleId: number, limit?: number): Promise<Article[]>`
626
-
627
- #### 分类和标签方法
628
-
629
- - `getCategories(rootCategoryId?: number | string): Promise<Category[]>`
630
- - `getTags(tagAlias?: string): Promise<Tag[]>`
631
-
632
- #### 统计方法
633
-
634
- - `getArticleStats(): Promise<ArticleStats>`
635
-
636
613
  ## 数据类型
637
614
 
638
615
  ### Article (文章)
@@ -692,6 +669,53 @@ interface Tag {
692
669
  }
693
670
  ```
694
671
 
672
+ ### 选项类型
673
+
674
+ ```typescript
675
+ interface ArticlesByCategoryOptions {
676
+ page?: number;
677
+ limit?: number;
678
+ status?: 'published' | 'draft' | 'archived';
679
+ }
680
+
681
+ interface ArticlesByTagOptions {
682
+ page?: number;
683
+ limit?: number;
684
+ status?: 'published' | 'draft' | 'archived';
685
+ tagAlias?: string;
686
+ }
687
+
688
+ interface ProductsByCategoryOptions {
689
+ page?: number;
690
+ limit?: number;
691
+ status?: number;
692
+ }
693
+
694
+ interface ProductsByTagOptions {
695
+ page?: number;
696
+ limit?: number;
697
+ status?: number;
698
+ productTagAlias?: string;
699
+ }
700
+ ```
701
+
702
+ ### 产品选项类型
703
+
704
+ ```typescript
705
+ interface ProductsByCategoryOptions {
706
+ page?: number;
707
+ limit?: number;
708
+ status?: number;
709
+ }
710
+
711
+ interface ProductsByTagOptions {
712
+ page?: number;
713
+ limit?: number;
714
+ status?: number;
715
+ productTagAlias?: string;
716
+ }
717
+ ```
718
+
695
719
  ## 错误处理
696
720
 
697
721
  SDK使用自定义的 `GT6Error` 类来处理错误:
@@ -716,7 +740,7 @@ SDK内置缓存机制,默认缓存5分钟:
716
740
  ```typescript
717
741
  const sdk = new GT6SDK({
718
742
  baseUrl: 'https://data.shopasb.io',
719
- platformId: '1750838492',
743
+ platformId: '1747558688',
720
744
  cache: {
721
745
  enabled: true,
722
746
  ttl: 300000 // 5分钟
@@ -759,4 +783,360 @@ npm run type-check
759
783
 
760
784
  ## 许可证
761
785
 
762
- MIT
786
+ MIT
787
+
788
+ ## 产品管理
789
+
790
+ ### 获取产品详情
791
+
792
+ ```typescript
793
+ const product = await sdk.getProduct(424210);
794
+ console.log(product.productName); // "极简不对称设计纯色短袖T恤"
795
+ console.log(product.price); // "30.00"
796
+
797
+ // 检查产品类型
798
+ if (product.productType === 2) {
799
+ // 订阅产品
800
+ console.log(product.subscription?.billingCycleUnit); // "month"
801
+ console.log(product.subscription?.trialDays); // 5
802
+ } else if (product.productType === 3) {
803
+ // 批发产品
804
+ console.log(product.wholesale?.minOrderQuantity); // 最小订购量
805
+ console.log(product.priceTiers?.length); // 价格层级数量
806
+ } else if (product.productType === 4) {
807
+ // 众筹产品
808
+ console.log(product.crowdfunding?.targetAmount); // 目标金额
809
+ console.log(product.crowdfunding?.currentAmount); // 当前金额
810
+ console.log(product.rewards?.length); // 奖励数量
811
+ } else if (product.productType === 5) {
812
+ // 简单理财产品
813
+ console.log(product.simpleFinance?.interestRate); // 年化收益率
814
+ console.log(product.simpleFinance?.minInvestment); // 最小投资金额
815
+ console.log(product.simpleFinance?.investmentPeriod); // 投资期限
816
+ } else {
817
+ // 普通产品
818
+ console.log(product.variants.length); // 变体数量
819
+ }
820
+
821
+ // 税费和运费模板规则自动填充
822
+ // SDK会自动为产品的税费模板和运费模板添加适用的规则
823
+ if (product.taxTemplates && product.taxTemplates.length > 0) {
824
+ product.taxTemplates.forEach(template => {
825
+ console.log(`税费模板: ${template.templateName}`);
826
+ console.log(`默认税率: ${template.defaultTaxRate}%`);
827
+ if (template.rules && template.rules.length > 0) {
828
+ console.log(`适用规则数量: ${template.rules.length}`);
829
+ template.rules.forEach(rule => {
830
+ console.log(` 区域 ${rule.regionId}: ${rule.taxRate}%`);
831
+ });
832
+ }
833
+ });
834
+ }
835
+
836
+ if (product.shippingTemplates && product.shippingTemplates.length > 0) {
837
+ product.shippingTemplates.forEach(template => {
838
+ console.log(`运费模板: ${template.templateName}`);
839
+ console.log(`默认运费: ${template.defaultFee}`);
840
+ if (template.rules && template.rules.length > 0) {
841
+ console.log(`适用规则数量: ${template.rules.length}`);
842
+ template.rules.forEach(rule => {
843
+ console.log(` 区域 ${rule.regionId}: 首${rule.firstUnit}件${rule.firstFee}元,续${rule.additionalUnit}件${rule.additionalFee}元`);
844
+ });
845
+ }
846
+ });
847
+ }
848
+ ```
849
+
850
+ ### 获取产品分类列表
851
+
852
+ ```typescript
853
+ const categories = await sdk.getProductCategories();
854
+ console.log(categories.length); // 分类数量
855
+
856
+ // 或者指定产品根分类ID
857
+ const categories = await sdk.getProductCategories('277233');
858
+ ```
859
+
860
+ ### 获取产品标签列表
861
+
862
+ ```typescript
863
+ const tags = await sdk.getProductTags();
864
+ console.log(tags.length); // 标签数量
865
+
866
+ // 或者指定产品标签别名
867
+ const tags = await sdk.getProductTags('01');
868
+ ```
869
+
870
+ ### 根据分类获取产品列表
871
+
872
+ ```typescript
873
+ const result = await sdk.getProductsByCategory(367704, {
874
+ page: 1,
875
+ limit: 10,
876
+ status: 1
877
+ });
878
+
879
+ console.log(result.products.length); // 产品数量
880
+ console.log(result.total); // 总产品数
881
+ ```
882
+
883
+ ### 根据标签获取产品列表
884
+
885
+ ```typescript
886
+ const result = await sdk.getProductsByTag(567515, {
887
+ page: 1,
888
+ limit: 10,
889
+ status: 1,
890
+ productTagAlias: '01'
891
+ });
892
+
893
+ console.log(result.products.length); // 产品数量
894
+ console.log(result.total); // 总产品数
895
+ ```
896
+
897
+ ### 获取产品分类路径(面包屑导航)
898
+
899
+ ```typescript
900
+ const categoryPath = await sdk.getProductCategoryPath(categoryId);
901
+ console.log(categoryPath.breadcrumbs);
902
+ // [
903
+ // { categoryId: 277233, categoryName: "中文商品", level: 0 },
904
+ // { categoryId: 367704, categoryName: "女装", level: 1 },
905
+ // { categoryId: 907691, categoryName: "T恤", level: 2 }
906
+ // ]
907
+ ```
908
+
909
+ ### 获取产品子分类
910
+
911
+ ```typescript
912
+ const subCategories = await sdk.getProductSubCategories(367704, {
913
+ recursive: true,
914
+ includeCurrent: false,
915
+ maxDepth: 2
916
+ });
917
+
918
+ console.log(subCategories.subCategories.length); // 子分类数量
919
+ ```
920
+
921
+ ### 获取税费信息
922
+
923
+ ```typescript
924
+ const taxInfo = await sdk.getTaxInfo();
925
+ console.log('税费模板数量:', taxInfo.templates.length);
926
+
927
+ taxInfo.templates.forEach(template => {
928
+ console.log(`模板 ${template.templateId}: ${template.templateName}`);
929
+ console.log(` 默认税率: ${template.defaultTaxRate}%`);
930
+ console.log(` 规则数量: ${template.rules.length}`);
931
+
932
+ template.rules.forEach(rule => {
933
+ console.log(` 区域 ${rule.regionId}: ${rule.taxRate}%`);
934
+ });
935
+ });
936
+ ```
937
+
938
+ ### 获取运费信息
939
+
940
+ ```typescript
941
+ const shippingInfo = await sdk.getShippingInfo();
942
+ console.log('运费模板数量:', shippingInfo.templates.length);
943
+
944
+ shippingInfo.templates.forEach(template => {
945
+ console.log(`模板 ${template.templateId}: ${template.templateName}`);
946
+ console.log(` 默认运费: ${template.defaultFee}`);
947
+ console.log(` 免运费门槛: ${template.freeShippingLimit}`);
948
+ console.log(` 规则数量: ${template.rules.length}`);
949
+
950
+ template.rules.forEach(rule => {
951
+ console.log(` 区域 ${rule.regionId}: 首${rule.firstUnit}件${rule.firstFee}元,续${rule.additionalUnit}件${rule.additionalFee}元`);
952
+ });
953
+ });
954
+ ```
955
+
956
+ ### 获取区域信息
957
+
958
+ ```typescript
959
+ const regionInfo = await sdk.getRegions();
960
+ console.log('区域数量:', regionInfo.regions.length);
961
+
962
+ // 递归显示区域层级结构
963
+ const displayRegions = (regions: any[], level: number = 0) => {
964
+ regions.forEach(region => {
965
+ const indent = ' '.repeat(level);
966
+ console.log(`${indent}${region.regionName} (${region.regionCode}) - ${region.regionLevel}`);
967
+
968
+ if (region.children && region.children.length > 0) {
969
+ displayRegions(region.children, level + 1);
970
+ }
971
+ });
972
+ };
973
+
974
+ displayRegions(regionInfo.regions);
975
+ ```
976
+
977
+ ### 税费和运费模板规则自动填充
978
+
979
+ SDK在获取产品详情时会自动为税费模板和运费模板填充适用的规则:
980
+
981
+ **触发条件:**
982
+ - 产品有销售区域(`regions` 不为空)
983
+ - 产品有税费模板(`taxTemplates` 不为空)或运费模板(`shippingTemplates` 不为空)
984
+
985
+ **自动填充逻辑:**
986
+ 1. 获取平台的所有税费/运费模板和规则
987
+ 2. 根据产品的销售区域过滤出适用的规则
988
+ 3. 将适用规则添加到对应的模板中
989
+ 4. 如果获取模板信息失败,不影响产品详情返回
990
+
991
+ **示例:**
992
+ ```typescript
993
+ const product = await sdk.getProduct(424210);
994
+
995
+ // 税费模板会自动包含适用区域的规则
996
+ if (product.taxTemplates) {
997
+ product.taxTemplates.forEach(template => {
998
+ console.log(`模板: ${template.templateName}`);
999
+ console.log(`默认税率: ${template.defaultTaxRate}%`);
1000
+
1001
+ // 自动填充的规则
1002
+ if (template.rules) {
1003
+ template.rules.forEach(rule => {
1004
+ console.log(`区域 ${rule.regionId}: ${rule.taxRate}%`);
1005
+ });
1006
+ }
1007
+ });
1008
+ }
1009
+
1010
+ // 运费模板会自动包含适用区域的规则
1011
+ if (product.shippingTemplates) {
1012
+ product.shippingTemplates.forEach(template => {
1013
+ console.log(`模板: ${template.templateName}`);
1014
+ console.log(`默认运费: ${template.defaultFee}`);
1015
+
1016
+ // 自动填充的规则
1017
+ if (template.rules) {
1018
+ template.rules.forEach(rule => {
1019
+ console.log(`区域 ${rule.regionId}: 首${rule.firstUnit}件${rule.firstFee}元`);
1020
+ });
1021
+ }
1022
+ });
1023
+ }
1024
+ ```
1025
+
1026
+ **注意事项:**
1027
+ - 如果产品没有销售区域或模板,不会进行自动填充
1028
+ - 如果获取模板信息失败,产品详情仍会正常返回,只是模板中没有规则
1029
+ - 自动填充的规则只包含产品可销售区域的规则,确保数据的准确性
1030
+
1031
+ ### 产品类型说明
1032
+
1033
+ - **productType: 1** - 普通产品(包含 variants、options 等)
1034
+ - **productType: 2** - 订阅产品(包含 subscription 信息)
1035
+ - **productType: 3** - 批发产品(包含 wholesale、priceTiers、variantPrices 信息)
1036
+ - **productType: 4** - 众筹产品(包含 crowdfunding、rewards、updates、faqs 信息)
1037
+ - **productType: 5** - 简单理财产品(包含 simpleFinance 信息)
1038
+
1039
+ ### 订阅产品示例
1040
+
1041
+ ```typescript
1042
+ const subscriptionProduct = await sdk.getProduct(305191);
1043
+
1044
+ if (subscriptionProduct.subscription) {
1045
+ console.log('订阅周期:', subscriptionProduct.subscription.billingCycleUnit);
1046
+ console.log('试用天数:', subscriptionProduct.subscription.trialDays);
1047
+ console.log('设置费用:', subscriptionProduct.subscription.setupFee);
1048
+ console.log('续费折扣:', subscriptionProduct.subscription.renewalDiscount);
1049
+ console.log('自动续费:', subscriptionProduct.subscription.autoRenew);
1050
+ }
1051
+ ```
1052
+
1053
+ ### 批发产品示例
1054
+
1055
+ ```typescript
1056
+ const wholesaleProduct = await sdk.getProduct(369374);
1057
+
1058
+ if (wholesaleProduct.wholesale) {
1059
+ console.log('最小订购量:', wholesaleProduct.wholesale.minOrderQuantity);
1060
+ console.log('最大订购量:', wholesaleProduct.wholesale.maxOrderQuantity);
1061
+ console.log('允许混合变体:', wholesaleProduct.wholesale.allowMixedVariants);
1062
+ console.log('显示零售价:', wholesaleProduct.wholesale.showRetailPrice);
1063
+ console.log('批发描述:', wholesaleProduct.wholesale.wholesaleDescription);
1064
+ console.log('付款条件:', wholesaleProduct.wholesale.paymentTerms);
1065
+ console.log('运输条件:', wholesaleProduct.wholesale.shippingTerms);
1066
+
1067
+ // 价格层级
1068
+ console.log('价格层级数量:', wholesaleProduct.priceTiers?.length);
1069
+ wholesaleProduct.priceTiers?.forEach(tier => {
1070
+ console.log(`层级 ${tier.tierId}: ${tier.minQuantity}-${tier.maxQuantity}件, 价格调整: ${tier.priceValue}`);
1071
+ });
1072
+
1073
+ // 变体价格
1074
+ console.log('变体价格数量:', wholesaleProduct.variantPrices?.length);
1075
+ }
1076
+ ```
1077
+
1078
+ ### 众筹产品示例
1079
+
1080
+ ```typescript
1081
+ const crowdfundingProduct = await sdk.getProduct(803421);
1082
+
1083
+ if (crowdfundingProduct.crowdfunding) {
1084
+ console.log('目标金额:', crowdfundingProduct.crowdfunding.targetAmount);
1085
+ console.log('当前金额:', crowdfundingProduct.crowdfunding.currentAmount);
1086
+ console.log('支持者数量:', crowdfundingProduct.crowdfunding.supporterCount);
1087
+ console.log('最小支持金额:', crowdfundingProduct.crowdfunding.minSupportAmount);
1088
+ console.log('允许超额众筹:', crowdfundingProduct.crowdfunding.allowOverFunding);
1089
+ console.log('超额限制:', crowdfundingProduct.crowdfunding.overFundingLimit);
1090
+
1091
+ // 众筹进度
1092
+ const progress = (parseFloat(crowdfundingProduct.crowdfunding.currentAmount) / parseFloat(crowdfundingProduct.crowdfunding.targetAmount)) * 100;
1093
+ console.log(`众筹进度: ${progress.toFixed(2)}%`);
1094
+
1095
+ // 奖励列表
1096
+ console.log('奖励数量:', crowdfundingProduct.rewards?.length);
1097
+ crowdfundingProduct.rewards?.forEach(reward => {
1098
+ console.log(`奖励 ${reward.rewardId}: ${reward.rewardName} - ${reward.rewardAmount}`);
1099
+ console.log(` 已认领: ${reward.rewardClaimed}/${reward.rewardLimit || '无限制'}`);
1100
+ });
1101
+
1102
+ // 项目更新
1103
+ console.log('项目更新数量:', crowdfundingProduct.updates?.length);
1104
+ crowdfundingProduct.updates?.forEach(update => {
1105
+ console.log(`更新 ${update.updateId}: ${update.updateTitle} (${update.isPublic ? '公开' : '私密'})`);
1106
+ });
1107
+
1108
+ // FAQ
1109
+ console.log('FAQ数量:', crowdfundingProduct.faqs?.length);
1110
+ crowdfundingProduct.faqs?.forEach(faq => {
1111
+ console.log(`FAQ ${faq.faqId}: ${faq.question}`);
1112
+ });
1113
+ }
1114
+ ```
1115
+
1116
+ ### 简单理财产品示例
1117
+
1118
+ ```typescript
1119
+ const financeProduct = await sdk.getProduct(249478);
1120
+
1121
+ if (financeProduct.simpleFinance) {
1122
+ console.log('年化收益率:', financeProduct.simpleFinance.interestRate + '%');
1123
+ console.log('最小投资金额:', financeProduct.simpleFinance.minInvestment + ' ' + financeProduct.simpleFinance.minInvestmentUnit);
1124
+ console.log('最大投资金额:', financeProduct.simpleFinance.maxInvestment + ' ' + financeProduct.simpleFinance.maxInvestmentUnit);
1125
+ console.log('投资期限:', financeProduct.simpleFinance.investmentPeriod + ' ' + financeProduct.simpleFinance.investmentPeriodUnit);
1126
+ console.log('计息周期:', financeProduct.simpleFinance.calculationPeriod + ' ' + financeProduct.simpleFinance.calculationPeriodUnit);
1127
+
1128
+ // 计算投资收益示例
1129
+ const investmentAmount = 5000; // 投资金额
1130
+ const interestRate = parseFloat(financeProduct.simpleFinance.interestRate);
1131
+ const investmentPeriod = financeProduct.simpleFinance.investmentPeriod;
1132
+
1133
+ // 简单年化收益计算
1134
+ const annualReturn = (investmentAmount * interestRate / 100);
1135
+ const totalReturn = annualReturn * investmentPeriod;
1136
+
1137
+ console.log(`投资 ${investmentAmount} ${financeProduct.simpleFinance.minInvestmentUnit} 的预期收益:`);
1138
+ console.log(` 年化收益: ${annualReturn.toFixed(2)} ${financeProduct.simpleFinance.minInvestmentUnit}`);
1139
+ console.log(` 总收益: ${totalReturn.toFixed(2)} ${financeProduct.simpleFinance.minInvestmentUnit}`);
1140
+ console.log(` 到期金额: ${(investmentAmount + totalReturn).toFixed(2)} ${financeProduct.simpleFinance.minInvestmentUnit}`);
1141
+ }
1142
+ ```