@rxdrag/website-lib-core 0.0.7 → 0.0.8

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.
Files changed (71) hide show
  1. package/index.ts +1 -1
  2. package/package.json +10 -6
  3. package/src/component-logic/gsap.d.ts +4 -0
  4. package/src/component-logic/index.ts +8 -0
  5. package/src/component-logic/link-client.ts +33 -0
  6. package/src/component-logic/link.ts +50 -0
  7. package/src/component-logic/modal.ts +36 -0
  8. package/src/component-logic/motion.ts +272 -0
  9. package/src/component-logic/number.ts +45 -0
  10. package/src/component-logic/popover.ts +51 -0
  11. package/src/component-logic/tabs.ts +10 -0
  12. package/src/controller/AnimateController.ts +138 -0
  13. package/src/controller/AosController.ts +240 -0
  14. package/src/controller/FlipController.ts +339 -0
  15. package/src/controller/ModalController.ts +127 -0
  16. package/src/controller/NumberController.ts +161 -0
  17. package/src/controller/PageLoader.ts +163 -0
  18. package/src/controller/PopoverController.ts +116 -0
  19. package/src/controller/TabsController.ts +271 -0
  20. package/src/controller/applyAnimation.ts +86 -0
  21. package/src/controller/applyInitialState.ts +79 -0
  22. package/src/{scripts → controller}/consts.ts +0 -2
  23. package/src/controller/index.ts +9 -0
  24. package/src/controller/popup.ts +346 -0
  25. package/src/controller/utils.ts +48 -0
  26. package/src/entify/Entify.ts +354 -365
  27. package/src/entify/IEntify.ts +91 -0
  28. package/src/entify/index.ts +3 -2
  29. package/src/entify/lib/newQueryProductOptions.ts +2 -3
  30. package/src/entify/lib/newQueryProductsMediaOptions.ts +19 -18
  31. package/src/entify/lib/queryAllProducts.ts +11 -3
  32. package/src/entify/lib/queryFeaturedProducts.ts +3 -3
  33. package/src/entify/lib/queryLatestPosts.ts +2 -2
  34. package/src/entify/lib/queryOneTheme.ts +1 -1
  35. package/src/entify/lib/queryPostCategories.ts +3 -3
  36. package/src/entify/lib/queryPostSlugs.ts +2 -2
  37. package/src/entify/lib/queryPosts.ts +92 -92
  38. package/src/entify/lib/queryProductCategories.ts +3 -3
  39. package/src/entify/lib/queryProducts.ts +69 -69
  40. package/src/entify/lib/queryUserPosts.ts +2 -2
  41. package/src/entify/lib/searchProducts.ts +2 -2
  42. package/src/index.ts +3 -1
  43. package/src/lib/formatDate.ts +15 -0
  44. package/src/lib/index.ts +3 -0
  45. package/src/lib/pagination.ts +114 -0
  46. package/src/lib/utils.ts +119 -0
  47. package/src/motion/consts.ts +428 -598
  48. package/src/motion/convertToGsapVars.ts +102 -0
  49. package/src/motion/index.ts +5 -1
  50. package/src/motion/normalizeAnimation.ts +28 -0
  51. package/src/motion/normalizeAosAnimation.ts +22 -0
  52. package/src/motion/normalizePopupAnimation.ts +24 -0
  53. package/src/motion/types.ts +133 -46
  54. package/src/react/components/AttachmentIcon/index.tsx +53 -0
  55. package/src/react/components/ContactForm/index.tsx +341 -0
  56. package/src/react/components/Icon/index.tsx +10 -0
  57. package/src/react/components/Medias/index.tsx +347 -347
  58. package/src/react/components/ProductCard/ProductCta/index.tsx +7 -5
  59. package/src/react/components/RichTextOutline/index.tsx +76 -76
  60. package/src/react/components/Scroller.tsx +5 -1
  61. package/src/react/components/SearchInput.tsx +36 -34
  62. package/src/react/components/ToTop.tsx +63 -28
  63. package/src/react/components/index.ts +3 -1
  64. package/src/react/hooks/useScroll.ts +16 -10
  65. package/src/react/components/EnquiryForm/index.tsx +0 -334
  66. package/src/scripts/actions.ts +0 -304
  67. package/src/scripts/events.ts +0 -33
  68. package/src/scripts/index.ts +0 -3
  69. /package/src/react/components/{EnquiryForm → ContactForm}/Input.tsx +0 -0
  70. /package/src/react/components/{EnquiryForm → ContactForm}/Submit.tsx +0 -0
  71. /package/src/react/components/{EnquiryForm → ContactForm}/Textarea.tsx +0 -0
@@ -1,365 +1,354 @@
1
- import { EnvVariables, TSize } from "./types";
2
- import { queryOneTheme } from "./lib/queryOneTheme";
3
- import {
4
- ListConditions,
5
- queryEntityList,
6
- queryFeaturedProducts,
7
- queryLangs,
8
- queryLatestPosts,
9
- queryOnePostBySlug,
10
- queryOnePostCategoryBySlug,
11
- queryOneProductBySlug,
12
- queryOneProductCategoryBySlug,
13
- queryOneUser,
14
- queryPostCategories,
15
- queryPosts,
16
- queryProductCategories,
17
- queryProducts,
18
- queryUserPosts,
19
- searchProducts,
20
- } from "./lib";
21
- import { IQueryOptions } from "@rxdrag/entify-hooks";
22
- import { queryAllProducts } from "./lib/queryAllProducts";
23
- import { queryPostSlugs } from "./lib/queryPostSlugs";
24
- import { queryUserIds } from "./lib/queryUserIds";
25
-
26
- export type PostsOptions = {
27
- category?: string;
28
- coverSize?: TSize | undefined;
29
- page: number;
30
- pageSize: number;
31
- };
32
-
33
- export type PostPatinateOptions = {
34
- pageSize: number;
35
- category?: string;
36
- };
37
-
38
- export class Entify {
39
- private static instance: Entify | null = null;
40
-
41
- private constructor(protected envVariables: EnvVariables) {}
42
-
43
- public static getInstance(envVariables: EnvVariables): Entify {
44
- if (!Entify.instance) {
45
- Entify.instance = new Entify(envVariables);
46
- }
47
- return Entify.instance;
48
- }
49
-
50
- public async queryEntityList<
51
- T,
52
- WhereExp = unknown,
53
- OrderBy = unknown,
54
- DistinctExp = unknown
55
- >(options: IQueryOptions<T, WhereExp, OrderBy, DistinctExp>) {
56
- return await queryEntityList<T, WhereExp, OrderBy, DistinctExp>(
57
- options,
58
- this.envVariables
59
- );
60
- }
61
-
62
- public async getTheme() {
63
- return await queryOneTheme(this.envVariables);
64
- }
65
-
66
- public async getLangs() {
67
- return (await queryLangs(this.envVariables))?.items;
68
- }
69
-
70
- public async getFeaturedProducts(count?: number) {
71
- return await queryFeaturedProducts(count, this.envVariables);
72
- }
73
-
74
- public async getLatestPosts(count?: number) {
75
- return await queryLatestPosts(count, this.envVariables);
76
- }
77
-
78
- public async getPosts(options: PostsOptions) {
79
- const { category, coverSize, page, pageSize } = options;
80
- const conditions: ListConditions = { category, page, pageSize };
81
- const result = await queryPosts(conditions, coverSize, this.envVariables);
82
- return result?.items;
83
- }
84
-
85
- public async getPostListPaths(options: PostPatinateOptions) {
86
- const { category, pageSize } = options;
87
- // 获取总文章数据,只需要获取总数
88
- // TODO: 目前数据查询有点重复,后续要结合后端优化
89
- const postsData = await queryPosts(
90
- { category, page: 1, pageSize: 10 },
91
- undefined,
92
- this.envVariables
93
- );
94
-
95
- const totalItems = postsData?.total ?? 0;
96
-
97
- return this.createPagination(totalItems, pageSize);
98
- }
99
-
100
- public async getPostPaths() {
101
- // 获取所有文章的 slug
102
- const slugs = await this.getPostSlugs();
103
-
104
- // 为每个 slug 创建路径
105
- return slugs.map((slug) => ({
106
- params: { slug },
107
- props: { slug },
108
- }));
109
- }
110
-
111
- public async getPostBySlug(slug: string, coverSize: TSize | undefined) {
112
- return await queryOnePostBySlug(slug, coverSize, this.envVariables);
113
- }
114
-
115
- /**
116
- * 获取所有文章的 slug,用于生成静态页面
117
- * 对于大量文章,这个方法会进行优化,只获取 slug 字段
118
- */
119
- public async getPostSlugs() {
120
- // 只获取 slug 字段,减少数据传输量
121
- const result = await queryPostSlugs(this.envVariables);
122
-
123
- return result?.items?.map((post) => post.slug) || [];
124
- }
125
-
126
- public async getPostCategories() {
127
- return (await queryPostCategories(this.envVariables))?.items;
128
- }
129
-
130
- public async getPostCategoryBySlug(slug: string) {
131
- return await queryOnePostCategoryBySlug(slug, this.envVariables);
132
- }
133
-
134
- public async getProuducts(
135
- conditions: ListConditions,
136
- imageSize: TSize | undefined
137
- ) {
138
- return (await queryProducts(conditions, imageSize, this.envVariables))
139
- ?.items;
140
- }
141
-
142
- public async getProductListPaths(options: {
143
- category?: string;
144
- pageSize: number;
145
- }) {
146
- const { category, pageSize } = options;
147
- // 获取总产品数据,只需要获取总数
148
- const productsData = await queryProducts(
149
- { category, page: 1, pageSize: 10 },
150
- undefined,
151
- this.envVariables
152
- );
153
-
154
- const totalItems = productsData?.total ?? 0;
155
-
156
- return this.createPagination(totalItems, pageSize);
157
- }
158
-
159
- public async getCategoredProductListPaths() {
160
- // 获取所有产品分类
161
- const categories = await this.getProductCategories();
162
-
163
- // 为每个分类生成路径
164
- const paths = [];
165
-
166
- // 如果没有分类,至少创建一个默认路径
167
- if (!categories || categories.length === 0) {
168
- paths.push({
169
- params: { slug: "default", page: "1" },
170
- props: {
171
- currentPage: 1,
172
- totalPages: 1,
173
- pageSize: 12,
174
- totalItems: 0,
175
- slug: "default",
176
- },
177
- });
178
- return paths;
179
- }
180
-
181
- for (const category of categories) {
182
- // 跳过没有 slug 的分类
183
- if (!category.slug) continue;
184
-
185
- // 获取该分类下的分页路径
186
- const categoryPaths = await this.getProductListPaths({
187
- pageSize: 12,
188
- category: category.slug,
189
- });
190
-
191
- // 如果该分类没有产品,至少创建一个第一页
192
- if (categoryPaths.length === 0) {
193
- paths.push({
194
- params: { slug: String(category.slug), page: "1" },
195
- props: {
196
- currentPage: 1,
197
- totalPages: 1,
198
- pageSize: 12,
199
- totalItems: 0,
200
- slug: String(category.slug),
201
- },
202
- });
203
- continue;
204
- }
205
-
206
- // 为每个分页路径添加分类 slug
207
- for (const path of categoryPaths) {
208
- paths.push({
209
- params: { ...path.params, slug: String(category.slug) },
210
- props: { ...path.props, slug: String(category.slug) },
211
- });
212
- }
213
- }
214
-
215
- return paths;
216
- }
217
-
218
- /**
219
- * TODO:未调试
220
- * 获取所有文章分类的分页路径
221
- * 用于生成静态页面
222
- * @returns 所有文章分类的分页路径
223
- */
224
- public async getCategoredPostListPaths() {
225
- // 获取所有文章分类
226
- const categories = await this.getPostCategories();
227
-
228
- // 为每个分类生成路径
229
- const paths = [];
230
-
231
- // 如果没有分类,至少创建一个默认路径
232
- if (!categories || categories.length === 0) {
233
- paths.push({
234
- params: { slug: "default", page: "1" },
235
- props: {
236
- currentPage: 1,
237
- totalPages: 1,
238
- pageSize: 10,
239
- totalItems: 0,
240
- slug: "default",
241
- },
242
- });
243
- return paths;
244
- }
245
-
246
- for (const category of categories) {
247
- // 跳过没有 slug 的分类
248
- if (!category.slug) continue;
249
-
250
- // 获取该分类下的分页路径
251
- const categoryPaths = await this.getPostListPaths({
252
- pageSize: 10,
253
- category: category.slug,
254
- });
255
-
256
- // 如果该分类没有文章,至少创建一个第一页
257
- if (categoryPaths.length === 0) {
258
- paths.push({
259
- params: { slug: String(category.slug), page: "1" },
260
- props: {
261
- currentPage: 1,
262
- totalPages: 1,
263
- pageSize: 10,
264
- totalItems: 0,
265
- slug: String(category.slug),
266
- },
267
- });
268
- continue;
269
- }
270
-
271
- // 为每个分页路径添加分类 slug
272
- for (const path of categoryPaths) {
273
- paths.push({
274
- params: { ...path.params, slug: String(category.slug) },
275
- props: { ...path.props, slug: String(category.slug) },
276
- });
277
- }
278
- }
279
-
280
- return paths;
281
- }
282
-
283
- public async getProductBySlug(slug: string, imageSize: TSize | undefined) {
284
- return await queryOneProductBySlug(slug, imageSize, this.envVariables);
285
- }
286
-
287
- public async getProductPaths() {
288
- // 获取所有产品的 slug
289
- const slugs = await this.getProductSlugs();
290
-
291
- // 为每个 slug 创建路径
292
- return slugs.map((slug) => ({
293
- params: { slug },
294
- props: { slug },
295
- }));
296
- }
297
-
298
- /**
299
- * 获取所有产品的 slug,用于生成静态页面
300
- * 对于大量产品,这个方法会进行优化,只获取 slug 字段
301
- */
302
- public async getProductSlugs() {
303
- // 只获取 slug 字段,减少数据传输量
304
- const result = await queryAllProducts(this.envVariables);
305
- return result?.items?.map((product) => product.slug) || [];
306
- }
307
-
308
- public async getProductIds() {
309
- const result = await queryAllProducts(this.envVariables);
310
- return result?.items?.map((product) => product.id) || [];
311
- }
312
-
313
- public async getProductCategories() {
314
- return (await queryProductCategories(this.envVariables))?.items;
315
- }
316
-
317
- public async getProductCategoryBySlug(slug: string) {
318
- return await queryOneProductCategoryBySlug(slug, this.envVariables);
319
- }
320
-
321
- public async getOneUser(id: string) {
322
- return await queryOneUser(id, this.envVariables);
323
- }
324
-
325
- public async getUserPosts(userId: string) {
326
- return (await queryUserPosts({ userId }, this.envVariables))?.items;
327
- }
328
-
329
- public async searchProducts(keyword: string) {
330
- return await searchProducts(keyword, this.envVariables);
331
- }
332
-
333
- public async getUserPaths() {
334
- const result = await queryUserIds(this.envVariables);
335
- return (
336
- result?.items?.map((user) => ({
337
- params: { id: user.id },
338
- props: { id: user.id },
339
- })) || []
340
- );
341
- }
342
-
343
- public createPagination(totalItems: number, pageSize: number) {
344
- const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
345
-
346
- // 为每个页面创建路径和获取对应的文章数据
347
- const paths = [];
348
-
349
- for (let i = 0; i < totalPages; i++) {
350
- const currentPage = i + 1;
351
-
352
- paths.push({
353
- params: { page: String(currentPage) },
354
- props: {
355
- currentPage,
356
- totalPages,
357
- pageSize,
358
- totalItems,
359
- },
360
- });
361
- }
362
-
363
- return paths;
364
- }
365
- }
1
+ import { EnvVariables, TSize } from "./types";
2
+ import { queryOneTheme } from "./lib/queryOneTheme";
3
+ import {
4
+ ListConditions,
5
+ queryEntityList,
6
+ queryFeaturedProducts,
7
+ queryLangs,
8
+ queryLatestPosts,
9
+ queryOnePostBySlug,
10
+ queryOnePostCategoryBySlug,
11
+ queryOneProductBySlug,
12
+ queryOneProductCategoryBySlug,
13
+ queryOneUser,
14
+ queryPostCategories,
15
+ queryPosts,
16
+ queryProductCategories,
17
+ queryProducts,
18
+ queryUserPosts,
19
+ searchProducts,
20
+ } from "./lib";
21
+ import { IQueryOptions } from "@rxdrag/entify-hooks";
22
+ import { queryAllProducts } from "./lib/queryAllProducts";
23
+ import { queryPostSlugs } from "./lib/queryPostSlugs";
24
+ import { queryUserIds } from "./lib/queryUserIds";
25
+ import { IEntify, PostPatinateOptions, PostsOptions } from "./IEntify";
26
+
27
+ export class Entify implements IEntify {
28
+ private static instance: Entify | null = null;
29
+
30
+ private constructor(protected envVariables: EnvVariables) {}
31
+
32
+ public static getInstance(envVariables: EnvVariables): Entify {
33
+ if (!Entify.instance) {
34
+ Entify.instance = new Entify(envVariables);
35
+ }
36
+ return Entify.instance;
37
+ }
38
+
39
+ public async queryEntityList<
40
+ T,
41
+ WhereExp = unknown,
42
+ OrderBy = unknown,
43
+ DistinctExp = unknown
44
+ >(options: IQueryOptions<T, WhereExp, OrderBy, DistinctExp>) {
45
+ return await queryEntityList<T, WhereExp, OrderBy, DistinctExp>(
46
+ options,
47
+ this.envVariables
48
+ );
49
+ }
50
+
51
+ public async getTheme() {
52
+ return await queryOneTheme(this.envVariables);
53
+ }
54
+
55
+ public async getLangs() {
56
+ return (await queryLangs(this.envVariables))?.items;
57
+ }
58
+
59
+ public async getFeaturedProducts(count?: number) {
60
+ return await queryFeaturedProducts(count, this.envVariables);
61
+ }
62
+
63
+ public async getLatestPosts(count?: number) {
64
+ return await queryLatestPosts(count, this.envVariables);
65
+ }
66
+
67
+ public async getPosts(options: PostsOptions) {
68
+ const { category, coverSize, page, pageSize } = options;
69
+ const conditions: ListConditions = { category, page, pageSize };
70
+ const result = await queryPosts(conditions, coverSize, this.envVariables);
71
+ return result?.items;
72
+ }
73
+
74
+ public async getPostListPaths(options: PostPatinateOptions) {
75
+ const { category, pageSize } = options;
76
+ // 获取总文章数据,只需要获取总数
77
+ // TODO: 目前数据查询有点重复,后续要结合后端优化
78
+ const postsData = await queryPosts(
79
+ { category, page: 1, pageSize: 10 },
80
+ undefined,
81
+ this.envVariables
82
+ );
83
+
84
+ const totalItems = postsData?.total ?? 0;
85
+
86
+ return this.createPagination(totalItems, pageSize);
87
+ }
88
+
89
+ public async getPostPaths() {
90
+ // 获取所有文章的 slug
91
+ const slugs = await this.getPostSlugs();
92
+
93
+ // 为每个 slug 创建路径
94
+ return slugs.map((slug) => ({
95
+ params: { slug },
96
+ props: { slug },
97
+ }));
98
+ }
99
+
100
+ public async getPostBySlug(slug: string, coverSize: TSize | undefined) {
101
+ return await queryOnePostBySlug(slug, coverSize, this.envVariables);
102
+ }
103
+
104
+ /**
105
+ * 获取所有文章的 slug,用于生成静态页面
106
+ * 对于大量文章,这个方法会进行优化,只获取 slug 字段
107
+ */
108
+ public async getPostSlugs() {
109
+ // 只获取 slug 字段,减少数据传输量
110
+ const result = await queryPostSlugs(this.envVariables);
111
+
112
+ return result?.items?.map((post) => post.slug) || [];
113
+ }
114
+
115
+ public async getPostCategories() {
116
+ return (await queryPostCategories(this.envVariables))?.items;
117
+ }
118
+
119
+ public async getPostCategoryBySlug(slug: string) {
120
+ return await queryOnePostCategoryBySlug(slug, this.envVariables);
121
+ }
122
+
123
+ public async getProducts(
124
+ conditions: ListConditions,
125
+ imageSize: TSize | undefined
126
+ ) {
127
+ return (await queryProducts(conditions, imageSize, this.envVariables))
128
+ ?.items;
129
+ }
130
+
131
+ public async getProductListPaths(options: {
132
+ category?: string;
133
+ pageSize: number;
134
+ }) {
135
+ const { category, pageSize } = options;
136
+ // 获取总产品数据,只需要获取总数
137
+ const productsData = await queryProducts(
138
+ { category, page: 1, pageSize: 10 },
139
+ undefined,
140
+ this.envVariables
141
+ );
142
+
143
+ const totalItems = productsData?.total ?? 0;
144
+
145
+ return this.createPagination(totalItems, pageSize);
146
+ }
147
+
148
+ public async getCategoredProductListPaths() {
149
+ // 获取所有产品分类
150
+ const categories = await this.getProductCategories();
151
+
152
+ // 为每个分类生成路径
153
+ const paths = [];
154
+
155
+ // 如果没有分类,至少创建一个默认路径
156
+ if (!categories || categories.length === 0) {
157
+ paths.push({
158
+ params: { slug: "default", page: "1" },
159
+ props: {
160
+ currentPage: 1,
161
+ totalPages: 1,
162
+ pageSize: 12,
163
+ totalItems: 0,
164
+ slug: "default",
165
+ },
166
+ });
167
+ return paths;
168
+ }
169
+
170
+ for (const category of categories) {
171
+ // 跳过没有 slug 的分类
172
+ if (!category.slug) continue;
173
+
174
+ // 获取该分类下的分页路径
175
+ const categoryPaths = await this.getProductListPaths({
176
+ pageSize: 12,
177
+ category: category.slug,
178
+ });
179
+
180
+ // 如果该分类没有产品,至少创建一个第一页
181
+ if (categoryPaths.length === 0) {
182
+ paths.push({
183
+ params: { slug: String(category.slug), page: "1" },
184
+ props: {
185
+ currentPage: 1,
186
+ totalPages: 1,
187
+ pageSize: 12,
188
+ totalItems: 0,
189
+ slug: String(category.slug),
190
+ },
191
+ });
192
+ continue;
193
+ }
194
+
195
+ // 为每个分页路径添加分类 slug
196
+ for (const path of categoryPaths) {
197
+ paths.push({
198
+ params: { ...path.params, slug: String(category.slug) },
199
+ props: { ...path.props, slug: String(category.slug) },
200
+ });
201
+ }
202
+ }
203
+
204
+ return paths;
205
+ }
206
+
207
+ /**
208
+ * TODO:未调试
209
+ * 获取所有文章分类的分页路径
210
+ * 用于生成静态页面
211
+ * @returns 所有文章分类的分页路径
212
+ */
213
+ public async getCategoredPostListPaths() {
214
+ // 获取所有文章分类
215
+ const categories = await this.getPostCategories();
216
+
217
+ // 为每个分类生成路径
218
+ const paths = [];
219
+
220
+ // 如果没有分类,至少创建一个默认路径
221
+ if (!categories || categories.length === 0) {
222
+ paths.push({
223
+ params: { slug: "default", page: "1" },
224
+ props: {
225
+ currentPage: 1,
226
+ totalPages: 1,
227
+ pageSize: 10,
228
+ totalItems: 0,
229
+ slug: "default",
230
+ },
231
+ });
232
+ return paths;
233
+ }
234
+
235
+ for (const category of categories) {
236
+ // 跳过没有 slug 的分类
237
+ if (!category.slug) continue;
238
+
239
+ // 获取该分类下的分页路径
240
+ const categoryPaths = await this.getPostListPaths({
241
+ pageSize: 10,
242
+ category: category.slug,
243
+ });
244
+
245
+ // 如果该分类没有文章,至少创建一个第一页
246
+ if (categoryPaths.length === 0) {
247
+ paths.push({
248
+ params: { slug: String(category.slug), page: "1" },
249
+ props: {
250
+ currentPage: 1,
251
+ totalPages: 1,
252
+ pageSize: 10,
253
+ totalItems: 0,
254
+ slug: String(category.slug),
255
+ },
256
+ });
257
+ continue;
258
+ }
259
+
260
+ // 为每个分页路径添加分类 slug
261
+ for (const path of categoryPaths) {
262
+ paths.push({
263
+ params: { ...path.params, slug: String(category.slug) },
264
+ props: { ...path.props, slug: String(category.slug) },
265
+ });
266
+ }
267
+ }
268
+
269
+ return paths;
270
+ }
271
+
272
+ public async getProductBySlug(slug: string, imageSize: TSize | undefined) {
273
+ return await queryOneProductBySlug(slug, imageSize, this.envVariables);
274
+ }
275
+
276
+ public async getProductPaths() {
277
+ // 获取所有产品的 slug
278
+ const slugs = await this.getProductSlugs();
279
+
280
+ // 为每个 slug 创建路径
281
+ return slugs.map((slug) => ({
282
+ params: { slug },
283
+ props: { slug },
284
+ }));
285
+ }
286
+
287
+ /**
288
+ * 获取所有产品的 slug,用于生成静态页面
289
+ * 对于大量产品,这个方法会进行优化,只获取 slug 字段
290
+ */
291
+ public async getProductSlugs() {
292
+ // 只获取 slug 字段,减少数据传输量
293
+ const result = await queryAllProducts(this.envVariables);
294
+ return result?.items?.map((product) => product.slug) || [];
295
+ }
296
+
297
+ public async getProductIds() {
298
+ const result = await queryAllProducts(this.envVariables);
299
+ return result?.items?.map((product) => product.id) || [];
300
+ }
301
+
302
+ public async getProductCategories() {
303
+ return (await queryProductCategories(this.envVariables))?.items;
304
+ }
305
+
306
+ public async getProductCategoryBySlug(slug: string) {
307
+ return await queryOneProductCategoryBySlug(slug, this.envVariables);
308
+ }
309
+
310
+ public async getOneUser(id: string) {
311
+ return await queryOneUser(id, this.envVariables);
312
+ }
313
+
314
+ public async getUserPosts(userId: string) {
315
+ return (await queryUserPosts({ userId }, this.envVariables))?.items;
316
+ }
317
+
318
+ public async searchProducts(keyword: string) {
319
+ return await searchProducts(keyword, this.envVariables);
320
+ }
321
+
322
+ public async getUserPaths() {
323
+ const result = await queryUserIds(this.envVariables);
324
+ return (
325
+ result?.items?.map((user) => ({
326
+ params: { id: user.id },
327
+ props: { id: user.id },
328
+ })) || []
329
+ );
330
+ }
331
+
332
+ public createPagination(totalItems: number, pageSize: number) {
333
+ const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
334
+
335
+ // 为每个页面创建路径和获取对应的文章数据
336
+ const paths = [];
337
+
338
+ for (let i = 0; i < totalPages; i++) {
339
+ const currentPage = i + 1;
340
+
341
+ paths.push({
342
+ params: { page: String(currentPage) },
343
+ props: {
344
+ currentPage,
345
+ totalPages,
346
+ pageSize,
347
+ totalItems,
348
+ },
349
+ });
350
+ }
351
+
352
+ return paths;
353
+ }
354
+ }