sa2kit 1.6.52 → 1.6.58

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 (195) hide show
  1. package/dist/AliyunOSSProvider-KSYW2IOG.js +15 -0
  2. package/dist/{AliyunOSSProvider-2FARPAQD.js.map → AliyunOSSProvider-KSYW2IOG.js.map} +1 -1
  3. package/dist/AliyunOSSProvider-TBK3G7YK.mjs +6 -0
  4. package/dist/{AliyunOSSProvider-UMVGVBDJ.mjs.map → AliyunOSSProvider-TBK3G7YK.mjs.map} +1 -1
  5. package/dist/LocalStorageProvider-2DGYRQAB.mjs +6 -0
  6. package/dist/{LocalStorageProvider-PYOHETJV.mjs.map → LocalStorageProvider-2DGYRQAB.mjs.map} +1 -1
  7. package/dist/LocalStorageProvider-SSRW3ZJW.js +15 -0
  8. package/dist/{LocalStorageProvider-JQF5WK5H.js.map → LocalStorageProvider-SSRW3ZJW.js.map} +1 -1
  9. package/dist/UniversalFileService-336GFY6N.mjs +6 -0
  10. package/dist/{UniversalFileService-TNYKO6JN.mjs.map → UniversalFileService-336GFY6N.mjs.map} +1 -1
  11. package/dist/UniversalFileService-J6ET6KZK.js +15 -0
  12. package/dist/{UniversalFileService-RBV6EN5J.js.map → UniversalFileService-J6ET6KZK.js.map} +1 -1
  13. package/dist/booking-BXtkG2ns.d.mts +386 -0
  14. package/dist/booking-BXtkG2ns.d.ts +386 -0
  15. package/dist/bookingAdminService-B2QDjSHJ.d.ts +193 -0
  16. package/dist/bookingAdminService-Dmg7dC6V.d.mts +193 -0
  17. package/dist/calendar/index.js +11 -11
  18. package/dist/calendar/index.mjs +4 -4
  19. package/dist/cart-CcZ7rQyG.d.mts +176 -0
  20. package/dist/cart-D3o67Q3H.d.ts +176 -0
  21. package/dist/chunk-25OFOKNF.js +171 -0
  22. package/dist/chunk-25OFOKNF.js.map +1 -0
  23. package/dist/chunk-3DXPQ4YV.mjs +165 -0
  24. package/dist/chunk-3DXPQ4YV.mjs.map +1 -0
  25. package/dist/{chunk-4VJQZSPU.mjs → chunk-3NHAT7D4.mjs} +3 -4
  26. package/dist/chunk-3NHAT7D4.mjs.map +1 -0
  27. package/dist/{chunk-3JW4X3AC.mjs → chunk-622Y6LTH.mjs} +3 -3
  28. package/dist/{chunk-3JW4X3AC.mjs.map → chunk-622Y6LTH.mjs.map} +1 -1
  29. package/dist/chunk-ANKVXRPY.mjs +30 -0
  30. package/dist/chunk-ANKVXRPY.mjs.map +1 -0
  31. package/dist/chunk-CIVO4R6N.mjs +37 -0
  32. package/dist/chunk-CIVO4R6N.mjs.map +1 -0
  33. package/dist/{chunk-IZOIVYOW.js → chunk-DENROXAE.js} +2 -2
  34. package/dist/{chunk-IZOIVYOW.js.map → chunk-DENROXAE.js.map} +1 -1
  35. package/dist/{chunk-6BJ76BYC.mjs → chunk-EGJPS7OL.mjs} +3 -3
  36. package/dist/{chunk-6BJ76BYC.mjs.map → chunk-EGJPS7OL.mjs.map} +1 -1
  37. package/dist/chunk-EKIOJEJK.js +2719 -0
  38. package/dist/chunk-EKIOJEJK.js.map +1 -0
  39. package/dist/chunk-EOWTOG7Y.js +119 -0
  40. package/dist/chunk-EOWTOG7Y.js.map +1 -0
  41. package/dist/chunk-HDMIOOZY.mjs +546 -0
  42. package/dist/chunk-HDMIOOZY.mjs.map +1 -0
  43. package/dist/{chunk-MZKATHB7.js → chunk-HHVDOIPV.js} +4 -4
  44. package/dist/{chunk-MZKATHB7.js.map → chunk-HHVDOIPV.js.map} +1 -1
  45. package/dist/chunk-HJ6MH7J7.js +552 -0
  46. package/dist/chunk-HJ6MH7J7.js.map +1 -0
  47. package/dist/chunk-KH6RQ4J5.js +28 -0
  48. package/dist/chunk-KH6RQ4J5.js.map +1 -0
  49. package/dist/{chunk-GFVAIT6Y.mjs → chunk-MFG2Y6UR.mjs} +2 -2
  50. package/dist/{chunk-GFVAIT6Y.mjs.map → chunk-MFG2Y6UR.mjs.map} +1 -1
  51. package/dist/{chunk-35CXIK5Y.js → chunk-NCOXT7SK.js} +11 -11
  52. package/dist/{chunk-35CXIK5Y.js.map → chunk-NCOXT7SK.js.map} +1 -1
  53. package/dist/chunk-NZZZUMMX.mjs +784 -0
  54. package/dist/chunk-NZZZUMMX.mjs.map +1 -0
  55. package/dist/{chunk-OBIPI4GU.mjs → chunk-OFYBMMWT.mjs} +4 -4
  56. package/dist/{chunk-OBIPI4GU.mjs.map → chunk-OFYBMMWT.mjs.map} +1 -1
  57. package/dist/chunk-PVLLRDUT.js +6944 -0
  58. package/dist/chunk-PVLLRDUT.js.map +1 -0
  59. package/dist/chunk-Q5EDCKQA.js +336 -0
  60. package/dist/chunk-Q5EDCKQA.js.map +1 -0
  61. package/dist/{chunk-SHY424RZ.mjs → chunk-SNBILYSH.mjs} +6 -6
  62. package/dist/{chunk-SHY424RZ.mjs.map → chunk-SNBILYSH.mjs.map} +1 -1
  63. package/dist/chunk-TJZDPOO7.js +34 -0
  64. package/dist/chunk-TJZDPOO7.js.map +1 -0
  65. package/dist/{chunk-7JN25DJB.js → chunk-UVHPCLP6.js} +14 -14
  66. package/dist/{chunk-7JN25DJB.js.map → chunk-UVHPCLP6.js.map} +1 -1
  67. package/dist/chunk-WGD2NBVR.mjs +6904 -0
  68. package/dist/chunk-WGD2NBVR.mjs.map +1 -0
  69. package/dist/chunk-WS3QZYBI.mjs +2701 -0
  70. package/dist/chunk-WS3QZYBI.mjs.map +1 -0
  71. package/dist/chunk-XLR6QUDR.mjs +113 -0
  72. package/dist/chunk-XLR6QUDR.mjs.map +1 -0
  73. package/dist/chunk-YMS6BPXS.js +807 -0
  74. package/dist/chunk-YMS6BPXS.js.map +1 -0
  75. package/dist/chunk-YOTQG4NP.mjs +314 -0
  76. package/dist/chunk-YOTQG4NP.mjs.map +1 -0
  77. package/dist/chunk-ZGVB35L2.mjs +25 -0
  78. package/dist/chunk-ZGVB35L2.mjs.map +1 -0
  79. package/dist/chunk-ZRAW3HXA.js +43 -0
  80. package/dist/chunk-ZRAW3HXA.js.map +1 -0
  81. package/dist/{chunk-4XXIBWCO.js → chunk-ZRWED7Q6.js} +66 -66
  82. package/dist/{chunk-4XXIBWCO.js.map → chunk-ZRWED7Q6.js.map} +1 -1
  83. package/dist/{chunk-DVENFCQY.js → chunk-ZWQJSZEY.js} +4 -5
  84. package/dist/chunk-ZWQJSZEY.js.map +1 -0
  85. package/dist/components/index.js +104 -104
  86. package/dist/components/index.mjs +4 -4
  87. package/dist/index.js +146 -148
  88. package/dist/index.js.map +1 -1
  89. package/dist/index.mjs +8 -11
  90. package/dist/index.mjs.map +1 -1
  91. package/dist/logger/index.js +7 -7
  92. package/dist/logger/index.mjs +1 -4
  93. package/dist/mikuFusionGame/index.js +4 -4
  94. package/dist/mikuFusionGame/index.mjs +3 -3
  95. package/dist/portfolio/index.js +10 -10
  96. package/dist/portfolio/index.mjs +5 -5
  97. package/dist/showmasterpiece/db/index.d.mts +3028 -0
  98. package/dist/showmasterpiece/db/index.d.ts +3028 -0
  99. package/dist/showmasterpiece/db/index.js +179 -0
  100. package/dist/showmasterpiece/db/index.js.map +1 -0
  101. package/dist/showmasterpiece/db/index.mjs +6 -0
  102. package/dist/showmasterpiece/db/index.mjs.map +1 -0
  103. package/dist/showmasterpiece/index.d.mts +10 -1729
  104. package/dist/showmasterpiece/index.d.ts +10 -1729
  105. package/dist/showmasterpiece/index.js +439 -9659
  106. package/dist/showmasterpiece/index.js.map +1 -1
  107. package/dist/showmasterpiece/index.mjs +12 -9633
  108. package/dist/showmasterpiece/index.mjs.map +1 -1
  109. package/dist/showmasterpiece/logic/index.d.mts +372 -0
  110. package/dist/showmasterpiece/logic/index.d.ts +372 -0
  111. package/dist/showmasterpiece/logic/index.js +91 -0
  112. package/dist/showmasterpiece/logic/index.js.map +1 -0
  113. package/dist/showmasterpiece/logic/index.mjs +6 -0
  114. package/dist/showmasterpiece/logic/index.mjs.map +1 -0
  115. package/dist/showmasterpiece/server/index.d.mts +3 -2704
  116. package/dist/showmasterpiece/server/index.d.ts +3 -2704
  117. package/dist/showmasterpiece/server/index.js +43 -43
  118. package/dist/showmasterpiece/server/index.mjs +2 -2
  119. package/dist/showmasterpiece/ui/miniapp/index.d.mts +86 -0
  120. package/dist/showmasterpiece/ui/miniapp/index.d.ts +86 -0
  121. package/dist/showmasterpiece/ui/miniapp/index.js +196 -0
  122. package/dist/showmasterpiece/ui/miniapp/index.js.map +1 -0
  123. package/dist/showmasterpiece/ui/miniapp/index.mjs +183 -0
  124. package/dist/showmasterpiece/ui/miniapp/index.mjs.map +1 -0
  125. package/dist/showmasterpiece/ui/web/index.d.mts +600 -0
  126. package/dist/showmasterpiece/ui/web/index.d.ts +600 -0
  127. package/dist/showmasterpiece/ui/web/index.js +131 -0
  128. package/dist/showmasterpiece/ui/web/index.js.map +1 -0
  129. package/dist/showmasterpiece/ui/web/index.mjs +14 -0
  130. package/dist/showmasterpiece/ui/web/index.mjs.map +1 -0
  131. package/dist/universalExport/server/index.js +2 -4
  132. package/dist/universalExport/server/index.js.map +1 -1
  133. package/dist/universalExport/server/index.mjs +1 -3
  134. package/dist/universalExport/server/index.mjs.map +1 -1
  135. package/dist/universalFile/index.js +6 -9
  136. package/dist/universalFile/index.js.map +1 -1
  137. package/dist/universalFile/index.mjs +1 -5
  138. package/dist/universalFile/index.mjs.map +1 -1
  139. package/dist/universalFile/server/index.js +5852 -291
  140. package/dist/universalFile/server/index.js.map +1 -1
  141. package/dist/universalFile/server/index.mjs +5764 -8
  142. package/dist/universalFile/server/index.mjs.map +1 -1
  143. package/dist/utils/index.js +11 -11
  144. package/dist/utils/index.mjs +2 -2
  145. package/package.json +26 -1
  146. package/dist/AliyunOSSProvider-2FARPAQD.js +0 -15
  147. package/dist/AliyunOSSProvider-UMVGVBDJ.mjs +0 -9
  148. package/dist/LocalStorageProvider-JQF5WK5H.js +0 -15
  149. package/dist/LocalStorageProvider-PYOHETJV.mjs +0 -9
  150. package/dist/UniversalFileService-RBV6EN5J.js +0 -15
  151. package/dist/UniversalFileService-TNYKO6JN.mjs +0 -9
  152. package/dist/chunk-4NFOSCM6.js +0 -34
  153. package/dist/chunk-4NFOSCM6.js.map +0 -1
  154. package/dist/chunk-4VJQZSPU.mjs.map +0 -1
  155. package/dist/chunk-6AHYPPUP.js +0 -344
  156. package/dist/chunk-6AHYPPUP.js.map +0 -1
  157. package/dist/chunk-76V7EKBX.mjs +0 -796
  158. package/dist/chunk-76V7EKBX.mjs.map +0 -1
  159. package/dist/chunk-ACLOJXXE.js +0 -195
  160. package/dist/chunk-ACLOJXXE.js.map +0 -1
  161. package/dist/chunk-AEXPAH7Z.mjs +0 -32
  162. package/dist/chunk-AEXPAH7Z.mjs.map +0 -1
  163. package/dist/chunk-CFGX3EKK.js +0 -560
  164. package/dist/chunk-CFGX3EKK.js.map +0 -1
  165. package/dist/chunk-D2HXMGXS.js +0 -46
  166. package/dist/chunk-D2HXMGXS.js.map +0 -1
  167. package/dist/chunk-DVENFCQY.js.map +0 -1
  168. package/dist/chunk-K7WNCB4V.mjs +0 -554
  169. package/dist/chunk-K7WNCB4V.mjs.map +0 -1
  170. package/dist/chunk-L4ZYBFB2.mjs +0 -44
  171. package/dist/chunk-L4ZYBFB2.mjs.map +0 -1
  172. package/dist/chunk-M4HGHTIC.js +0 -820
  173. package/dist/chunk-M4HGHTIC.js.map +0 -1
  174. package/dist/chunk-PKKIDPXE.mjs +0 -5797
  175. package/dist/chunk-PKKIDPXE.mjs.map +0 -1
  176. package/dist/chunk-PXWDQFWV.mjs +0 -192
  177. package/dist/chunk-PXWDQFWV.mjs.map +0 -1
  178. package/dist/chunk-TSTBLX6B.js +0 -5888
  179. package/dist/chunk-TSTBLX6B.js.map +0 -1
  180. package/dist/chunk-VTGPHE4Z.mjs +0 -322
  181. package/dist/chunk-VTGPHE4Z.mjs.map +0 -1
  182. package/dist/popupConfig-BznThU1O.d.mts +0 -330
  183. package/dist/popupConfig-BznThU1O.d.ts +0 -330
  184. package/dist/showmasterpiece/migration/index.d.mts +0 -120
  185. package/dist/showmasterpiece/migration/index.d.ts +0 -120
  186. package/dist/showmasterpiece/migration/index.js +0 -595
  187. package/dist/showmasterpiece/migration/index.js.map +0 -1
  188. package/dist/showmasterpiece/migration/index.mjs +0 -589
  189. package/dist/showmasterpiece/migration/index.mjs.map +0 -1
  190. package/dist/showmasterpiece/scripts/index.d.mts +0 -28
  191. package/dist/showmasterpiece/scripts/index.d.ts +0 -28
  192. package/dist/showmasterpiece/scripts/index.js +0 -327
  193. package/dist/showmasterpiece/scripts/index.js.map +0 -1
  194. package/dist/showmasterpiece/scripts/index.mjs +0 -325
  195. package/dist/showmasterpiece/scripts/index.mjs.map +0 -1
@@ -0,0 +1,2701 @@
1
+ import { __esm, __export, __toCommonJS } from './chunk-WMJKH4XE.mjs';
2
+ import React, { createContext, useState, useCallback, useEffect, useContext } from 'react';
3
+
4
+ // src/showmasterpiece/services/masterpiecesService.ts
5
+ var getMasterpieces, MasterpiecesService;
6
+ var init_masterpiecesService = __esm({
7
+ "src/showmasterpiece/services/masterpiecesService.ts"() {
8
+ getMasterpieces = async () => {
9
+ const response = await fetch("/api/showmasterpiece/collections");
10
+ if (!response.ok) {
11
+ throw new Error("\u83B7\u53D6\u753B\u96C6\u5931\u8D25");
12
+ }
13
+ return await response.json();
14
+ };
15
+ MasterpiecesService = class {
16
+ /**
17
+ * 获取所有画集
18
+ *
19
+ * 从后端API获取所有可用的画集数据。
20
+ * 返回的数据包含完整的画集信息和作品页面。
21
+ *
22
+ * @returns Promise<ArtCollection[]> 所有画集的数组
23
+ * @throws {Error} 当API请求失败时抛出错误
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * try {
28
+ * const collections = await MasterpiecesService.getAllCollections();
29
+ * console.log(`共加载了 ${collections.length} 个画集`);
30
+ * } catch (error) {
31
+ * console.error('加载失败:', error.message);
32
+ * }
33
+ * ```
34
+ */
35
+ static async getAllCollections() {
36
+ const response = await fetch("/api/showmasterpiece/collections");
37
+ if (!response.ok) {
38
+ throw new Error("\u83B7\u53D6\u753B\u96C6\u5931\u8D25");
39
+ }
40
+ const payload = await response.json();
41
+ const collections = Array.isArray(payload) ? payload : payload?.collections ?? payload?.data ?? [];
42
+ if (!Array.isArray(collections)) {
43
+ throw new Error("\u753B\u96C6\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E");
44
+ }
45
+ return collections;
46
+ }
47
+ /**
48
+ * 根据ID获取特定画集
49
+ *
50
+ * 通过画集ID获取单个画集的详细信息。
51
+ * 内部实现是先获取所有画集,然后筛选出指定ID的画集。
52
+ *
53
+ * @param id - 画集的唯一标识符
54
+ * @returns Promise<ArtCollection | null> 找到的画集对象,如果不存在则返回null
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const collection = await MasterpiecesService.getCollectionById(1);
59
+ * if (collection) {
60
+ * console.log(`找到画集: ${collection.title}`);
61
+ * } else {
62
+ * console.log('画集不存在');
63
+ * }
64
+ * ```
65
+ */
66
+ static async getCollectionById(id) {
67
+ const collections = await this.getAllCollections();
68
+ return collections.find((c) => c.id === id) || null;
69
+ }
70
+ /**
71
+ * 搜索画集
72
+ *
73
+ * 根据关键词在画集的多个字段中进行搜索,包括:
74
+ * - 画集标题
75
+ * - 艺术家姓名
76
+ * - 画集描述
77
+ * - 画集分类
78
+ * - 画集标签
79
+ *
80
+ * 搜索是大小写不敏感的,支持部分匹配。
81
+ *
82
+ * @param query - 搜索关键词
83
+ * @returns Promise<ArtCollection[]> 匹配的画集数组
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * // 搜索包含"山水"的画集
88
+ * const results = await MasterpiecesService.searchCollections('山水');
89
+ * console.log(`找到 ${results.length} 个相关画集`);
90
+ * ```
91
+ */
92
+ static async searchCollections(query) {
93
+ const collections = await this.getAllCollections();
94
+ const searchTerm = query.toLowerCase();
95
+ return collections.filter(
96
+ (collection) => collection.title.toLowerCase().includes(searchTerm) || collection.number.toLowerCase().includes(searchTerm) || collection.description.toLowerCase().includes(searchTerm) || collection.category && collection.category.toLowerCase().includes(searchTerm) || collection.tags && collection.tags.some((tag) => tag.toLowerCase().includes(searchTerm))
97
+ );
98
+ }
99
+ /**
100
+ * 根据分类获取画集
101
+ *
102
+ * 获取属于指定分类的所有画集。
103
+ * 支持特殊值 'all' 来获取所有画集。
104
+ *
105
+ * @param category - 分类名称,或 'all' 表示所有分类
106
+ * @returns Promise<ArtCollection[]> 该分类下的画集数组
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // 获取油画分类的画集
111
+ * const paintings = await MasterpiecesService.getCollectionsByCategory('油画');
112
+ *
113
+ * // 获取所有画集
114
+ * const allCollections = await MasterpiecesService.getCollectionsByCategory('all');
115
+ * ```
116
+ */
117
+ static async getCollectionsByCategory(category) {
118
+ const collections = await this.getAllCollections();
119
+ if (category === "all") {
120
+ return collections;
121
+ }
122
+ return collections.filter((collection) => collection.category === category);
123
+ }
124
+ /**
125
+ * 获取推荐画集
126
+ *
127
+ * 基于简单的推荐算法获取推荐的画集。
128
+ * 当前算法:优先选择已发布的画集,按作品数量降序排列。
129
+ *
130
+ * @param limit - 返回的推荐画集数量,默认为3个
131
+ * @returns Promise<ArtCollection[]> 推荐的画集数组
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * // 获取3个推荐画集
136
+ * const recommended = await MasterpiecesService.getRecommendedCollections();
137
+ *
138
+ * // 获取5个推荐画集
139
+ * const moreRecommended = await MasterpiecesService.getRecommendedCollections(5);
140
+ * ```
141
+ */
142
+ static async getRecommendedCollections(limit = 3) {
143
+ const collections = await this.getAllCollections();
144
+ return collections.filter((collection) => collection.isPublished !== false).sort((a, b) => b.pages.length - a.pages.length).slice(0, limit);
145
+ }
146
+ /**
147
+ * 获取所有可用分类
148
+ *
149
+ * 从后端API获取所有已定义的画集分类列表。
150
+ * 用于构建分类筛选器和下拉菜单。
151
+ *
152
+ * @returns Promise<Array<{ name: string; description?: string | null }>> 分类名称数组
153
+ * @throws {Error} 当API请求失败时抛出错误
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * const categories = await MasterpiecesService.getCategories();
158
+ * console.log('可用分类:', categories);
159
+ * ```
160
+ */
161
+ static async getCategories() {
162
+ const response = await fetch("/api/showmasterpiece/categories");
163
+ if (!response.ok) {
164
+ throw new Error("\u83B7\u53D6\u5206\u7C7B\u5931\u8D25");
165
+ }
166
+ const payload = await response.json();
167
+ return Array.isArray(payload) ? payload : payload?.data ?? [];
168
+ }
169
+ /**
170
+ * 获取所有可用标签
171
+ *
172
+ * 从后端API获取所有已定义的画集标签列表。
173
+ * 用于构建标签筛选器和标签云。
174
+ *
175
+ * @returns Promise<string[]> 标签名称数组
176
+ * @throws {Error} 当API请求失败时抛出错误
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const tags = await MasterpiecesService.getTags();
181
+ * console.log('可用标签:', tags);
182
+ * ```
183
+ */
184
+ static async getTags() {
185
+ const response = await fetch("/api/showmasterpiece/tags");
186
+ if (!response.ok) {
187
+ throw new Error("\u83B7\u53D6\u6807\u7B7E\u5931\u8D25");
188
+ }
189
+ return await response.json();
190
+ }
191
+ };
192
+ }
193
+ });
194
+ var collectionsCache, collectionsCacheTime, COLLECTIONS_CACHE_DURATION, useMasterpieces;
195
+ var init_useMasterpieces = __esm({
196
+ "src/showmasterpiece/logic/hooks/useMasterpieces.ts"() {
197
+ init_masterpiecesService();
198
+ collectionsCache = null;
199
+ collectionsCacheTime = 0;
200
+ COLLECTIONS_CACHE_DURATION = 3 * 60 * 1e3;
201
+ useMasterpieces = () => {
202
+ const [collections, setCollections] = useState([]);
203
+ const [selectedCollection, setSelectedCollection] = useState(null);
204
+ const [currentPage, setCurrentPage] = useState(0);
205
+ const [loading, setLoading] = useState(false);
206
+ const [error, setError] = useState(null);
207
+ const loadCollections = useCallback(async (forceRefresh = false) => {
208
+ try {
209
+ const now = Date.now();
210
+ if (!forceRefresh && collectionsCache && now - collectionsCacheTime < COLLECTIONS_CACHE_DURATION) {
211
+ setCollections(collectionsCache);
212
+ return;
213
+ }
214
+ setLoading(true);
215
+ setError(null);
216
+ const data = await MasterpiecesService.getAllCollections();
217
+ collectionsCache = data;
218
+ collectionsCacheTime = now;
219
+ setCollections(data);
220
+ } catch (err) {
221
+ setError("\u52A0\u8F7D\u753B\u96C6\u5931\u8D25");
222
+ console.error("Error loading collections:", err);
223
+ } finally {
224
+ setLoading(false);
225
+ }
226
+ }, []);
227
+ const selectCollection = useCallback((collection) => {
228
+ setSelectedCollection(collection);
229
+ setCurrentPage(0);
230
+ }, []);
231
+ const nextPage = useCallback(() => {
232
+ if (selectedCollection && currentPage < selectedCollection.pages.length - 1) {
233
+ setCurrentPage((prev) => prev + 1);
234
+ }
235
+ }, [selectedCollection, currentPage]);
236
+ const prevPage = useCallback(() => {
237
+ if (currentPage > 0) {
238
+ setCurrentPage((prev) => prev - 1);
239
+ }
240
+ }, [currentPage]);
241
+ const goToPage = useCallback((pageIndex) => {
242
+ if (selectedCollection && pageIndex >= 0 && pageIndex < selectedCollection.pages.length) {
243
+ setCurrentPage(pageIndex);
244
+ }
245
+ }, [selectedCollection]);
246
+ const backToGallery = useCallback(() => {
247
+ setSelectedCollection(null);
248
+ setCurrentPage(0);
249
+ }, []);
250
+ const searchCollections = useCallback(async (query) => {
251
+ try {
252
+ setLoading(true);
253
+ setError(null);
254
+ const data = await MasterpiecesService.searchCollections(query);
255
+ setCollections(data);
256
+ } catch (err) {
257
+ setError("\u641C\u7D22\u5931\u8D25");
258
+ console.error("Error searching collections:", err);
259
+ } finally {
260
+ setLoading(false);
261
+ }
262
+ }, []);
263
+ const getCurrentArtwork = useCallback(() => {
264
+ if (!selectedCollection || !selectedCollection.pages[currentPage]) {
265
+ return null;
266
+ }
267
+ return selectedCollection.pages[currentPage];
268
+ }, [selectedCollection, currentPage]);
269
+ const canGoNext = selectedCollection ? currentPage < selectedCollection.pages.length - 1 : false;
270
+ const canGoPrev = currentPage > 0;
271
+ useEffect(() => {
272
+ loadCollections();
273
+ }, [loadCollections]);
274
+ return {
275
+ // === 状态数据 ===
276
+ /** 所有画集数据 */
277
+ collections,
278
+ /** 当前选中的画集 */
279
+ selectedCollection,
280
+ /** 当前页面索引 */
281
+ currentPage,
282
+ /** 加载状态 */
283
+ loading,
284
+ /** 错误信息 */
285
+ error,
286
+ // === 计算属性 ===
287
+ /** 获取当前作品的方法 */
288
+ getCurrentArtwork,
289
+ /** 是否可以下一页 */
290
+ canGoNext,
291
+ /** 是否可以上一页 */
292
+ canGoPrev,
293
+ // === 操作方法 ===
294
+ /** 选择画集 */
295
+ selectCollection,
296
+ /** 下一页 */
297
+ nextPage,
298
+ /** 上一页 */
299
+ prevPage,
300
+ /** 跳转到指定页 */
301
+ goToPage,
302
+ /** 返回画集列表 */
303
+ backToGallery,
304
+ /** 搜索画集 */
305
+ searchCollections,
306
+ /** 加载画集数据 */
307
+ loadCollections
308
+ };
309
+ };
310
+ }
311
+ });
312
+
313
+ // src/showmasterpiece/services/masterpiecesConfigService.ts
314
+ async function getCollectionsOverview() {
315
+ const response = await fetch("/api/showmasterpiece/collections?overview=true");
316
+ if (!response.ok) {
317
+ throw new Error("\u83B7\u53D6\u753B\u96C6\u6982\u89C8\u5931\u8D25");
318
+ }
319
+ return response.json();
320
+ }
321
+ var configCache, configCacheTime, CONFIG_CACHE_DURATION, getConfig, updateConfig, resetConfig, getAllCollections, createCollection, updateCollection, deleteCollection, updateCollectionOrder, moveCollection, moveCollectionUp, moveCollectionDown, addArtworkToCollection, updateArtwork, deleteArtwork, getArtworksByCollection, updateArtworkOrder, moveArtwork, moveArtworkUp, moveArtworkDown, getCategories, createCategory, getTags;
322
+ var init_masterpiecesConfigService = __esm({
323
+ "src/showmasterpiece/services/masterpiecesConfigService.ts"() {
324
+ configCache = null;
325
+ configCacheTime = 0;
326
+ CONFIG_CACHE_DURATION = 5 * 60 * 1e3;
327
+ getConfig = async () => {
328
+ const now = Date.now();
329
+ if (configCache && now - configCacheTime < CONFIG_CACHE_DURATION) {
330
+ return configCache;
331
+ }
332
+ const response = await fetch("/api/showmasterpiece/config");
333
+ if (!response.ok) {
334
+ throw new Error("\u83B7\u53D6\u914D\u7F6E\u5931\u8D25");
335
+ }
336
+ const config = await response.json();
337
+ configCache = config;
338
+ configCacheTime = now;
339
+ return config;
340
+ };
341
+ updateConfig = async (configData) => {
342
+ const response = await fetch("/api/showmasterpiece/config", {
343
+ method: "PUT",
344
+ headers: {
345
+ "Content-Type": "application/json"
346
+ },
347
+ body: JSON.stringify(configData)
348
+ });
349
+ if (!response.ok) {
350
+ throw new Error("\u66F4\u65B0\u914D\u7F6E\u5931\u8D25");
351
+ }
352
+ const updatedConfig = await response.json();
353
+ configCache = updatedConfig;
354
+ configCacheTime = Date.now();
355
+ return updatedConfig;
356
+ };
357
+ resetConfig = async () => {
358
+ const response = await fetch("/api/showmasterpiece/config", {
359
+ method: "DELETE"
360
+ });
361
+ if (!response.ok) {
362
+ throw new Error("\u91CD\u7F6E\u914D\u7F6E\u5931\u8D25");
363
+ }
364
+ const resetConfigData = await response.json();
365
+ configCache = resetConfigData;
366
+ configCacheTime = Date.now();
367
+ return resetConfigData;
368
+ };
369
+ getAllCollections = async () => {
370
+ console.log("\u{1F4E1} [\u670D\u52A1] \u5F00\u59CB\u83B7\u53D6\u6240\u6709\u753B\u96C6...");
371
+ try {
372
+ const timestamp = (/* @__PURE__ */ new Date()).getTime();
373
+ const response = await fetch(`/api/showmasterpiece/collections?_t=${timestamp}`, {
374
+ method: "GET",
375
+ headers: {
376
+ "Cache-Control": "no-cache",
377
+ "Pragma": "no-cache"
378
+ }
379
+ });
380
+ console.log("\u{1F4E1} [\u670D\u52A1] \u753B\u96C6\u8BF7\u6C42\u54CD\u5E94\u72B6\u6001:", response.status);
381
+ if (!response.ok) {
382
+ const errorText = await response.text();
383
+ console.error("\u274C [\u670D\u52A1] \u83B7\u53D6\u753B\u96C6\u5931\u8D25:", {
384
+ status: response.status,
385
+ statusText: response.statusText,
386
+ error: errorText
387
+ });
388
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
389
+ }
390
+ const payload = await response.json();
391
+ const collections = Array.isArray(payload) ? payload : payload?.collections ?? payload?.data ?? [];
392
+ if (!Array.isArray(collections)) {
393
+ throw new Error("\u753B\u96C6\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E");
394
+ }
395
+ console.log("\u2705 [\u670D\u52A1] \u753B\u96C6\u6570\u636E\u83B7\u53D6\u6210\u529F:", {
396
+ count: collections.length,
397
+ titles: collections.map((c) => c.title)
398
+ });
399
+ return collections;
400
+ } catch (error) {
401
+ console.error("\u274C [\u670D\u52A1] \u83B7\u53D6\u753B\u96C6\u6570\u636E\u5931\u8D25:", error);
402
+ throw error;
403
+ }
404
+ };
405
+ createCollection = async (collectionData) => {
406
+ const requestBody = collectionData;
407
+ const response = await fetch("/api/showmasterpiece/collections", {
408
+ method: "POST",
409
+ headers: {
410
+ "Content-Type": "application/json"
411
+ },
412
+ body: JSON.stringify(requestBody)
413
+ });
414
+ if (!response.ok) {
415
+ if (response.status === 413) {
416
+ throw new Error("\u56FE\u7247\u6587\u4EF6\u592A\u5927\uFF0C\u8BF7\u9009\u62E9\u66F4\u5C0F\u7684\u56FE\u7247\u6216\u7B49\u5F85\u56FE\u7247\u538B\u7F29\u5B8C\u6210\u540E\u91CD\u8BD5");
417
+ }
418
+ throw new Error("\u521B\u5EFA\u753B\u96C6\u5931\u8D25");
419
+ }
420
+ return await response.json();
421
+ };
422
+ updateCollection = async (id, collectionData) => {
423
+ const response = await fetch(`/api/showmasterpiece/collections/${id}`, {
424
+ method: "PUT",
425
+ headers: {
426
+ "Content-Type": "application/json"
427
+ },
428
+ body: JSON.stringify(collectionData)
429
+ });
430
+ if (!response.ok) {
431
+ if (response.status === 413) {
432
+ throw new Error("\u56FE\u7247\u6587\u4EF6\u592A\u5927\uFF0C\u8BF7\u9009\u62E9\u66F4\u5C0F\u7684\u56FE\u7247\u6216\u7B49\u5F85\u56FE\u7247\u538B\u7F29\u5B8C\u6210\u540E\u91CD\u8BD5");
433
+ }
434
+ throw new Error("\u66F4\u65B0\u753B\u96C6\u5931\u8D25");
435
+ }
436
+ return await response.json();
437
+ };
438
+ deleteCollection = async (id) => {
439
+ const url = new URL(`/api/showmasterpiece/collections/${id}`, window.location.origin);
440
+ const response = await fetch(url.toString(), {
441
+ method: "DELETE"
442
+ });
443
+ if (!response.ok) {
444
+ const errorData = await response.json().catch(() => ({}));
445
+ throw new Error(errorData.error || "\u5220\u9664\u753B\u96C6\u5931\u8D25");
446
+ }
447
+ };
448
+ updateCollectionOrder = async (collectionOrders) => {
449
+ const response = await fetch("/api/showmasterpiece/collections?action=reorder", {
450
+ method: "PATCH",
451
+ headers: {
452
+ "Content-Type": "application/json"
453
+ },
454
+ body: JSON.stringify({ collectionOrders })
455
+ });
456
+ if (!response.ok) {
457
+ const error = await response.json();
458
+ throw new Error(error.error || "\u66F4\u65B0\u753B\u96C6\u987A\u5E8F\u5931\u8D25");
459
+ }
460
+ };
461
+ moveCollection = async (collectionId, targetOrder) => {
462
+ const response = await fetch("/api/showmasterpiece/collections?action=move", {
463
+ method: "PATCH",
464
+ headers: {
465
+ "Content-Type": "application/json"
466
+ },
467
+ body: JSON.stringify({ collectionId, targetOrder })
468
+ });
469
+ if (!response.ok) {
470
+ const error = await response.json();
471
+ throw new Error(error.error || "\u79FB\u52A8\u753B\u96C6\u5931\u8D25");
472
+ }
473
+ };
474
+ moveCollectionUp = async (collectionId) => {
475
+ const response = await fetch("/api/showmasterpiece/collections?action=up", {
476
+ method: "PATCH",
477
+ headers: {
478
+ "Content-Type": "application/json"
479
+ },
480
+ body: JSON.stringify({ collectionId })
481
+ });
482
+ if (!response.ok) {
483
+ const error = await response.json();
484
+ throw new Error(error.error || "\u4E0A\u79FB\u753B\u96C6\u5931\u8D25");
485
+ }
486
+ };
487
+ moveCollectionDown = async (collectionId) => {
488
+ const response = await fetch("/api/showmasterpiece/collections?action=down", {
489
+ method: "PATCH",
490
+ headers: {
491
+ "Content-Type": "application/json"
492
+ },
493
+ body: JSON.stringify({ collectionId })
494
+ });
495
+ if (!response.ok) {
496
+ const error = await response.json();
497
+ throw new Error(error.error || "\u4E0B\u79FB\u753B\u96C6\u5931\u8D25");
498
+ }
499
+ };
500
+ addArtworkToCollection = async (collectionId, artworkData) => {
501
+ console.log("\u{1F310} [\u670D\u52A1] \u5F00\u59CB\u53D1\u9001\u4F5C\u54C1\u521B\u5EFA\u8BF7\u6C42:", {
502
+ collectionId,
503
+ title: artworkData.title,
504
+ number: artworkData.number,
505
+ imageSize: artworkData.image ? `${artworkData.image.length} chars` : "null"
506
+ });
507
+ const requestBody = JSON.stringify(artworkData);
508
+ console.log("\u{1F4E6} [\u670D\u52A1] \u8BF7\u6C42\u4F53\u5927\u5C0F:", `${requestBody.length} chars (${(requestBody.length / 1024).toFixed(1)} KB)`);
509
+ try {
510
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks`, {
511
+ method: "POST",
512
+ headers: {
513
+ "Content-Type": "application/json"
514
+ },
515
+ body: requestBody
516
+ });
517
+ console.log("\u{1F4E1} [\u670D\u52A1] \u6536\u5230HTTP\u54CD\u5E94:", {
518
+ status: response.status,
519
+ statusText: response.statusText,
520
+ contentLength: response.headers.get("content-length"),
521
+ contentType: response.headers.get("content-type")
522
+ });
523
+ if (!response.ok) {
524
+ const errorText = await response.text();
525
+ console.error("\u274C [\u670D\u52A1] HTTP\u8BF7\u6C42\u5931\u8D25:", {
526
+ status: response.status,
527
+ statusText: response.statusText,
528
+ errorText: errorText.substring(0, 200)
529
+ });
530
+ if (response.status === 413) {
531
+ throw new Error("\u56FE\u7247\u6587\u4EF6\u592A\u5927\uFF0C\u8BF7\u9009\u62E9\u66F4\u5C0F\u7684\u56FE\u7247\u6216\u7B49\u5F85\u56FE\u7247\u538B\u7F29\u5B8C\u6210\u540E\u91CD\u8BD5");
532
+ }
533
+ throw new Error(`\u6DFB\u52A0\u4F5C\u54C1\u5931\u8D25: ${response.status} ${response.statusText}`);
534
+ }
535
+ const result = await response.json();
536
+ console.log("\u2705 [\u670D\u52A1] \u4F5C\u54C1\u521B\u5EFA\u6210\u529F:", {
537
+ id: result.id,
538
+ title: result.title,
539
+ number: result.number
540
+ });
541
+ return result;
542
+ } catch (error) {
543
+ console.error("\u274C [\u670D\u52A1] \u8BF7\u6C42\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:", error);
544
+ if (error instanceof TypeError && error.message.includes("fetch")) {
545
+ throw new Error("\u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u540E\u91CD\u8BD5");
546
+ }
547
+ throw error;
548
+ }
549
+ };
550
+ updateArtwork = async (collectionId, artworkId, artworkData) => {
551
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks/${artworkId}`, {
552
+ method: "PUT",
553
+ headers: {
554
+ "Content-Type": "application/json"
555
+ },
556
+ body: JSON.stringify(artworkData)
557
+ });
558
+ if (!response.ok) {
559
+ if (response.status === 413) {
560
+ throw new Error("\u56FE\u7247\u6587\u4EF6\u592A\u5927\uFF0C\u8BF7\u9009\u62E9\u66F4\u5C0F\u7684\u56FE\u7247\u6216\u7B49\u5F85\u56FE\u7247\u538B\u7F29\u5B8C\u6210\u540E\u91CD\u8BD5");
561
+ }
562
+ throw new Error("\u66F4\u65B0\u4F5C\u54C1\u5931\u8D25");
563
+ }
564
+ return await response.json();
565
+ };
566
+ deleteArtwork = async (collectionId, artworkId) => {
567
+ const url = new URL(`/api/showmasterpiece/collections/${collectionId}/artworks/${artworkId}`, window.location.origin);
568
+ const response = await fetch(url.toString(), {
569
+ method: "DELETE"
570
+ });
571
+ if (!response.ok) {
572
+ const errorData = await response.json().catch(() => ({}));
573
+ throw new Error(errorData.error || "\u5220\u9664\u4F5C\u54C1\u5931\u8D25");
574
+ }
575
+ };
576
+ getArtworksByCollection = async (collectionId) => {
577
+ const timestamp = (/* @__PURE__ */ new Date()).getTime();
578
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks?_t=${timestamp}`, {
579
+ headers: {
580
+ "Cache-Control": "no-cache",
581
+ "Pragma": "no-cache"
582
+ }
583
+ });
584
+ if (!response.ok) {
585
+ throw new Error("\u83B7\u53D6\u4F5C\u54C1\u5217\u8868\u5931\u8D25");
586
+ }
587
+ return await response.json();
588
+ };
589
+ updateArtworkOrder = async (collectionId, artworkOrders) => {
590
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks?action=reorder`, {
591
+ method: "PATCH",
592
+ headers: {
593
+ "Content-Type": "application/json"
594
+ },
595
+ body: JSON.stringify({ artworkOrders })
596
+ });
597
+ if (!response.ok) {
598
+ const error = await response.json();
599
+ throw new Error(error.error || "\u66F4\u65B0\u4F5C\u54C1\u987A\u5E8F\u5931\u8D25");
600
+ }
601
+ };
602
+ moveArtwork = async (collectionId, artworkId, targetOrder) => {
603
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks?action=move`, {
604
+ method: "PATCH",
605
+ headers: {
606
+ "Content-Type": "application/json"
607
+ },
608
+ body: JSON.stringify({ artworkId, targetOrder })
609
+ });
610
+ if (!response.ok) {
611
+ const error = await response.json();
612
+ throw new Error(error.error || "\u79FB\u52A8\u4F5C\u54C1\u5931\u8D25");
613
+ }
614
+ };
615
+ moveArtworkUp = async (collectionId, artworkId) => {
616
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks?action=up`, {
617
+ method: "PATCH",
618
+ headers: {
619
+ "Content-Type": "application/json"
620
+ },
621
+ body: JSON.stringify({ artworkId })
622
+ });
623
+ if (!response.ok) {
624
+ const error = await response.json();
625
+ throw new Error(error.error || "\u4E0A\u79FB\u4F5C\u54C1\u5931\u8D25");
626
+ }
627
+ };
628
+ moveArtworkDown = async (collectionId, artworkId) => {
629
+ const response = await fetch(`/api/showmasterpiece/collections/${collectionId}/artworks?action=down`, {
630
+ method: "PATCH",
631
+ headers: {
632
+ "Content-Type": "application/json"
633
+ },
634
+ body: JSON.stringify({ artworkId })
635
+ });
636
+ if (!response.ok) {
637
+ const error = await response.json();
638
+ throw new Error(error.error || "\u4E0B\u79FB\u4F5C\u54C1\u5931\u8D25");
639
+ }
640
+ };
641
+ getCategories = async () => {
642
+ const response = await fetch("/api/showmasterpiece/categories");
643
+ if (!response.ok) {
644
+ throw new Error("\u83B7\u53D6\u5206\u7C7B\u5931\u8D25");
645
+ }
646
+ const payload = await response.json();
647
+ const categories = Array.isArray(payload) ? payload : payload?.data ?? [];
648
+ if (!Array.isArray(categories)) {
649
+ throw new Error("\u5206\u7C7B\u6570\u636E\u683C\u5F0F\u4E0D\u6B63\u786E");
650
+ }
651
+ return categories;
652
+ };
653
+ createCategory = async (name, description) => {
654
+ const response = await fetch("/api/showmasterpiece/categories", {
655
+ method: "POST",
656
+ headers: {
657
+ "Content-Type": "application/json"
658
+ },
659
+ body: JSON.stringify({ name, description })
660
+ });
661
+ if (!response.ok) {
662
+ const error = await response.json().catch(() => ({}));
663
+ throw new Error(error.error || "\u521B\u5EFA\u5206\u7C7B\u5931\u8D25");
664
+ }
665
+ };
666
+ getTags = async () => {
667
+ const response = await fetch("/api/showmasterpiece/tags");
668
+ if (!response.ok) {
669
+ throw new Error("\u83B7\u53D6\u6807\u7B7E\u5931\u8D25");
670
+ }
671
+ return await response.json();
672
+ };
673
+ }
674
+ });
675
+ var useMasterpiecesConfig;
676
+ var init_useMasterpiecesConfig = __esm({
677
+ "src/showmasterpiece/logic/hooks/useMasterpiecesConfig.ts"() {
678
+ init_masterpiecesConfigService();
679
+ useMasterpiecesConfig = () => {
680
+ const [config, setConfig] = useState(null);
681
+ const [collections, setCollections] = useState([]);
682
+ const [categories, setCategories] = useState([]);
683
+ const [tags, setTags] = useState([]);
684
+ const [loading, setLoading] = useState(true);
685
+ const [error, setError] = useState(null);
686
+ const [refreshCounter, setRefreshCounter] = useState(0);
687
+ useEffect(() => {
688
+ loadData();
689
+ }, []);
690
+ const loadData = async () => {
691
+ console.log("\u{1F504} [Hook] \u5F00\u59CB\u52A0\u8F7D\u6570\u636E...");
692
+ try {
693
+ setLoading(true);
694
+ setError(null);
695
+ console.log("\u{1F4E1} [Hook] \u5E76\u884C\u8BF7\u6C42\u6240\u6709\u6570\u636E...");
696
+ const timestamp = Date.now();
697
+ const [configData, collectionsResponse, categoriesData, tagsData] = await Promise.all([
698
+ getConfig(),
699
+ fetch(`/api/showmasterpiece/collections?_t=${timestamp}&nocache=true&includeImages=true`, {
700
+ headers: {
701
+ "Cache-Control": "no-cache",
702
+ "Pragma": "no-cache"
703
+ }
704
+ }).then((r) => r.json()),
705
+ getCategories(),
706
+ getTags()
707
+ ]);
708
+ const collectionsData = collectionsResponse.data || [];
709
+ console.log("\u2705 [Hook] \u6570\u636E\u52A0\u8F7D\u5B8C\u6210:", {
710
+ \u914D\u7F6E: configData ? "\u5DF2\u52A0\u8F7D" : "\u672A\u52A0\u8F7D",
711
+ \u753B\u96C6\u6570\u91CF: collectionsData.length,
712
+ \u5206\u7C7B\u6570\u91CF: categoriesData.length,
713
+ \u6807\u7B7E\u6570\u91CF: tagsData.length
714
+ });
715
+ if (collectionsData.length > 0) {
716
+ console.log("\u{1F4DA} [Hook] \u753B\u96C6\u8BE6\u60C5:");
717
+ collectionsData.forEach((collection, index) => {
718
+ console.log(` ${index + 1}. ${collection.title} - \u4F5C\u54C1\u6570\u91CF: ${collection.pages.length}`);
719
+ if (collection.pages.length > 0) {
720
+ collection.pages.forEach((page, pageIndex) => {
721
+ console.log(` ${pageIndex + 1}. ${page.title} (ID: ${page.id})`);
722
+ });
723
+ }
724
+ });
725
+ }
726
+ setConfig(configData);
727
+ setCollections(collectionsData);
728
+ setCategories(categoriesData);
729
+ setTags(tagsData);
730
+ console.log("\u{1F4BE} [Hook] \u72B6\u6001\u66F4\u65B0\u5B8C\u6210");
731
+ return {
732
+ config: configData,
733
+ collections: collectionsData,
734
+ // 这里已经是提取后的数组数据
735
+ categories: categoriesData,
736
+ tags: tagsData
737
+ };
738
+ } catch (err) {
739
+ console.error("\u274C [Hook] \u52A0\u8F7D\u6570\u636E\u5931\u8D25:", err);
740
+ console.error("\u9519\u8BEF\u8BE6\u60C5:", {
741
+ message: err instanceof Error ? err.message : "\u672A\u77E5\u9519\u8BEF",
742
+ stack: err instanceof Error ? err.stack : void 0
743
+ });
744
+ setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u6570\u636E\u5931\u8D25");
745
+ throw err;
746
+ } finally {
747
+ setLoading(false);
748
+ console.log("\u{1F3C1} [Hook] \u6570\u636E\u52A0\u8F7D\u6D41\u7A0B\u7ED3\u675F");
749
+ }
750
+ };
751
+ const handleApiError = (error2, operation) => {
752
+ if (error2 instanceof Error) {
753
+ if (error2.message.includes("413") || error2.message.includes("\u592A\u5927")) {
754
+ throw new Error("\u56FE\u7247\u6587\u4EF6\u8FC7\u5927\uFF0C\u8BF7\u4F7F\u7528\u538B\u7F29\u540E\u7684\u56FE\u7247");
755
+ }
756
+ if (error2.message.includes("401")) {
757
+ throw new Error("\u6CA1\u6709\u6743\u9650\u6267\u884C\u6B64\u64CD\u4F5C\uFF0C\u8BF7\u5148\u767B\u5F55");
758
+ }
759
+ if (error2.message.includes("404") || error2.message.includes("\u753B\u96C6\u4E0D\u5B58\u5728")) {
760
+ throw new Error("\u753B\u96C6\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5");
761
+ }
762
+ if (error2.message.includes("409")) {
763
+ if (error2.message.includes("\u753B\u96C6\u4E0D\u5B58\u5728") || error2.message.includes("\u5DF2\u88AB\u5220\u9664")) {
764
+ throw new Error("\u753B\u96C6\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5");
765
+ }
766
+ throw new Error(error2.message);
767
+ }
768
+ throw new Error(`${operation}\u5931\u8D25\uFF1A${error2.message}`);
769
+ }
770
+ throw new Error(`${operation}\u5931\u8D25\uFF1A\u672A\u77E5\u9519\u8BEF`);
771
+ };
772
+ const handleUpdateConfig = async (configData) => {
773
+ try {
774
+ const updatedConfig = await updateConfig(configData);
775
+ setConfig(updatedConfig);
776
+ } catch (err) {
777
+ handleApiError(err, "\u66F4\u65B0\u914D\u7F6E");
778
+ }
779
+ };
780
+ const handleResetConfig = async () => {
781
+ try {
782
+ const resetConfigData = await resetConfig();
783
+ setConfig(resetConfigData);
784
+ } catch (err) {
785
+ handleApiError(err, "\u91CD\u7F6E\u914D\u7F6E");
786
+ }
787
+ };
788
+ const handleCreateCollection = async (collectionData) => {
789
+ try {
790
+ const newCollection = await createCollection(collectionData);
791
+ await loadData();
792
+ } catch (err) {
793
+ handleApiError(err, "\u521B\u5EFA\u753B\u96C6");
794
+ }
795
+ };
796
+ const handleUpdateCollection = async (id, collectionData) => {
797
+ try {
798
+ const updatedCollection = await updateCollection(id, collectionData);
799
+ await loadData();
800
+ } catch (err) {
801
+ handleApiError(err, "\u66F4\u65B0\u753B\u96C6");
802
+ }
803
+ };
804
+ const handleDeleteCollection = async (id) => {
805
+ try {
806
+ await deleteCollection(id);
807
+ await loadData();
808
+ } catch (err) {
809
+ handleApiError(err, "\u5220\u9664\u753B\u96C6");
810
+ }
811
+ };
812
+ const handleAddArtworkToCollection = async (collectionId, artworkData) => {
813
+ console.log("\u{1F3AF} [Hook] \u5F00\u59CB\u6DFB\u52A0\u4F5C\u54C1\u5230\u753B\u96C6:", {
814
+ collectionId,
815
+ title: artworkData.title,
816
+ number: artworkData.number,
817
+ imageSize: artworkData.image ? `${artworkData.image.length} chars` : "null",
818
+ description: artworkData.description?.substring(0, 50) + (artworkData.description && artworkData.description.length > 50 ? "..." : "")
819
+ });
820
+ try {
821
+ console.log("\u{1F4DE} [Hook] \u8C03\u7528API\u670D\u52A1...");
822
+ const newArtwork = await addArtworkToCollection(collectionId, artworkData);
823
+ console.log("\u2705 [Hook] API\u8C03\u7528\u6210\u529F\uFF0C\u8FD4\u56DE\u4F5C\u54C1:", {
824
+ id: newArtwork.id,
825
+ title: newArtwork.title,
826
+ number: newArtwork.number
827
+ });
828
+ console.log("\u{1F504} [Hook] \u91CD\u65B0\u52A0\u8F7D\u6570\u636E\u4EE5\u786E\u4FDD\u4E0E\u6570\u636E\u5E93\u5B8C\u5168\u540C\u6B65...");
829
+ const reloadedData = await loadData();
830
+ console.log("\u2705 [Hook] \u6570\u636E\u91CD\u65B0\u52A0\u8F7D\u5B8C\u6210");
831
+ await new Promise((resolve) => setTimeout(resolve, 50));
832
+ const targetCollection = reloadedData.collections.find((c) => c.id === collectionId);
833
+ if (targetCollection) {
834
+ const newArtworkInCollection = targetCollection.pages.find((p) => p.id === newArtwork.id);
835
+ if (newArtworkInCollection) {
836
+ console.log("\u2705 [Hook] \u9A8C\u8BC1\u6210\u529F\uFF1A\u65B0\u4F5C\u54C1\u5DF2\u5728\u753B\u96C6\u4E2D", {
837
+ artworkId: newArtwork.id,
838
+ collectionId,
839
+ artworkTitle: newArtworkInCollection.title
840
+ });
841
+ } else {
842
+ console.error("\u274C [Hook] \u9A8C\u8BC1\u5931\u8D25\uFF1A\u65B0\u4F5C\u54C1\u4E0D\u5728\u91CD\u65B0\u52A0\u8F7D\u7684\u6570\u636E\u4E2D", {
843
+ expectedArtworkId: newArtwork.id,
844
+ collectionId,
845
+ currentArtworks: targetCollection.pages.map((p) => ({ id: p.id, title: p.title }))
846
+ });
847
+ console.log("\u{1F504} [Hook] \u518D\u6B21\u5C1D\u8BD5\u91CD\u65B0\u52A0\u8F7D\u6570\u636E...");
848
+ await loadData();
849
+ }
850
+ } else {
851
+ console.error("\u274C [Hook] \u9A8C\u8BC1\u5931\u8D25\uFF1A\u627E\u4E0D\u5230\u76EE\u6807\u753B\u96C6", {
852
+ collectionId,
853
+ availableCollections: reloadedData.collections.map((c) => ({ id: c.id, title: c.title }))
854
+ });
855
+ }
856
+ console.log("\u{1F389} [Hook] \u5F3A\u5236\u66F4\u65B0\u72B6\u6001\u4EE5\u786E\u4FDDUI\u540C\u6B65...");
857
+ setCollections([...reloadedData.collections]);
858
+ setRefreshCounter((prev) => prev + 1);
859
+ console.log("\u{1F525} [Hook] \u89E6\u53D1\u5F3A\u5236\u91CD\u65B0\u6E32\u67D3");
860
+ } catch (err) {
861
+ console.error("\u274C [Hook] \u6DFB\u52A0\u4F5C\u54C1\u5931\u8D25:", err);
862
+ console.error("\u9519\u8BEF\u8BE6\u60C5:", {
863
+ message: err instanceof Error ? err.message : "\u672A\u77E5\u9519\u8BEF",
864
+ collectionId,
865
+ artworkTitle: artworkData.title
866
+ });
867
+ handleApiError(err, "\u6DFB\u52A0\u4F5C\u54C1");
868
+ }
869
+ };
870
+ const handleUpdateArtwork = async (collectionId, artworkId, artworkData) => {
871
+ try {
872
+ const updatedArtwork = await updateArtwork(collectionId, artworkId, artworkData);
873
+ await loadData();
874
+ } catch (err) {
875
+ handleApiError(err, "\u66F4\u65B0\u4F5C\u54C1");
876
+ }
877
+ };
878
+ const handleDeleteArtwork = async (collectionId, artworkId) => {
879
+ try {
880
+ await deleteArtwork(collectionId, artworkId);
881
+ await loadData();
882
+ } catch (err) {
883
+ handleApiError(err, "\u5220\u9664\u4F5C\u54C1");
884
+ }
885
+ };
886
+ const handleMoveArtworkUp = async (collectionId, artworkId) => {
887
+ try {
888
+ await moveArtworkUp(collectionId, artworkId);
889
+ await updateCollectionArtworks(collectionId);
890
+ } catch (err) {
891
+ handleApiError(err, "\u4E0A\u79FB\u4F5C\u54C1");
892
+ }
893
+ };
894
+ const handleMoveArtworkDown = async (collectionId, artworkId) => {
895
+ try {
896
+ await moveArtworkDown(collectionId, artworkId);
897
+ await updateCollectionArtworks(collectionId);
898
+ } catch (err) {
899
+ handleApiError(err, "\u4E0B\u79FB\u4F5C\u54C1");
900
+ }
901
+ };
902
+ const handleUpdateArtworkOrder = async (collectionId, artworkOrders) => {
903
+ try {
904
+ await updateArtworkOrder(collectionId, artworkOrders);
905
+ await updateCollectionArtworks(collectionId);
906
+ } catch (err) {
907
+ handleApiError(err, "\u66F4\u65B0\u4F5C\u54C1\u987A\u5E8F");
908
+ }
909
+ };
910
+ const updateCollectionArtworks = async (collectionId) => {
911
+ try {
912
+ const updatedArtworks = await getArtworksByCollection(collectionId);
913
+ setCollections(
914
+ (prevCollections) => prevCollections.map(
915
+ (collection) => collection.id === collectionId ? { ...collection, pages: updatedArtworks } : collection
916
+ )
917
+ );
918
+ } catch (err) {
919
+ console.error("\u66F4\u65B0\u753B\u96C6\u4F5C\u54C1\u6570\u636E\u5931\u8D25:", err);
920
+ await loadData();
921
+ }
922
+ };
923
+ const handleMoveCollectionUp = async (collectionId) => {
924
+ try {
925
+ await moveCollectionUp(collectionId);
926
+ await updateCollectionsData();
927
+ } catch (err) {
928
+ handleApiError(err, "\u4E0A\u79FB\u753B\u96C6");
929
+ }
930
+ };
931
+ const handleMoveCollectionDown = async (collectionId) => {
932
+ try {
933
+ await moveCollectionDown(collectionId);
934
+ await updateCollectionsData();
935
+ } catch (err) {
936
+ handleApiError(err, "\u4E0B\u79FB\u753B\u96C6");
937
+ }
938
+ };
939
+ const handleUpdateCollectionOrder = async (collectionOrders) => {
940
+ try {
941
+ await updateCollectionOrder(collectionOrders);
942
+ await updateCollectionsData();
943
+ } catch (err) {
944
+ handleApiError(err, "\u66F4\u65B0\u753B\u96C6\u987A\u5E8F");
945
+ }
946
+ };
947
+ const updateCollectionsData = async () => {
948
+ try {
949
+ const updatedCollections = await getAllCollections();
950
+ setCollections(updatedCollections);
951
+ } catch (err) {
952
+ console.error("\u66F4\u65B0\u753B\u96C6\u6570\u636E\u5931\u8D25:", err);
953
+ await loadData();
954
+ }
955
+ };
956
+ return {
957
+ // 数据
958
+ config,
959
+ collections,
960
+ categories,
961
+ tags,
962
+ loading,
963
+ error,
964
+ refreshCounter,
965
+ // 方法
966
+ updateConfig: handleUpdateConfig,
967
+ resetConfig: handleResetConfig,
968
+ createCollection: handleCreateCollection,
969
+ updateCollection: handleUpdateCollection,
970
+ deleteCollection: handleDeleteCollection,
971
+ addArtworkToCollection: handleAddArtworkToCollection,
972
+ updateArtwork: handleUpdateArtwork,
973
+ deleteArtwork: handleDeleteArtwork,
974
+ // 新增:作品排序方法
975
+ moveArtworkUp: handleMoveArtworkUp,
976
+ moveArtworkDown: handleMoveArtworkDown,
977
+ updateArtworkOrder: handleUpdateArtworkOrder,
978
+ // 新增:画集排序方法
979
+ moveCollectionUp: handleMoveCollectionUp,
980
+ moveCollectionDown: handleMoveCollectionDown,
981
+ updateCollectionOrder: handleUpdateCollectionOrder,
982
+ refreshData: loadData
983
+ };
984
+ };
985
+ }
986
+ });
987
+
988
+ // src/showmasterpiece/services/cartHistoryService.ts
989
+ var CART_HISTORY_STORAGE_KEY_BASE, CART_HISTORY_STORAGE_KEY, CartHistoryService, getCartHistory, updateBookingStatus, deleteHistoryRecord, clearUserHistory, getAllHistory, getStatistics, saveCartHistory;
990
+ var init_cartHistoryService = __esm({
991
+ "src/showmasterpiece/services/cartHistoryService.ts"() {
992
+ CART_HISTORY_STORAGE_KEY_BASE = "showmasterpiece_cart_history";
993
+ CART_HISTORY_STORAGE_KEY = CART_HISTORY_STORAGE_KEY_BASE;
994
+ CartHistoryService = class {
995
+ /**
996
+ * 生成唯一ID
997
+ */
998
+ // static generateId(): string {
999
+ // return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1000
+ // }
1001
+ /**
1002
+ * 获取用户购物车历史记录
1003
+ *
1004
+ * @param qqNumber 用户QQ号
1005
+ * @param phoneNumber 用户手机号
1006
+ * @returns 购物车历史记录
1007
+ */
1008
+ static async getCartHistory(qqNumber, phoneNumber) {
1009
+ try {
1010
+ const historyData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1011
+ if (historyData) {
1012
+ const allHistory = JSON.parse(historyData);
1013
+ const userHistory = allHistory.filter(
1014
+ (record) => record.qqNumber === qqNumber && record.phoneNumber === phoneNumber
1015
+ );
1016
+ const processedHistory = userHistory.map((record) => ({
1017
+ ...record,
1018
+ submittedAt: new Date(record.submittedAt),
1019
+ items: record.items.map((item) => ({
1020
+ ...item,
1021
+ addedAt: new Date(item.addedAt)
1022
+ }))
1023
+ }));
1024
+ processedHistory.sort((a, b) => b.submittedAt.getTime() - a.submittedAt.getTime());
1025
+ return {
1026
+ records: processedHistory,
1027
+ totalRecords: processedHistory.length
1028
+ };
1029
+ }
1030
+ } catch (error) {
1031
+ console.error("\u8BFB\u53D6\u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1032
+ }
1033
+ return {
1034
+ records: [],
1035
+ totalRecords: 0
1036
+ };
1037
+ }
1038
+ /**
1039
+ * 保存购物车历史记录
1040
+ *
1041
+ * @param historyItem 历史记录项
1042
+ */
1043
+ static async saveCartHistory(historyItem) {
1044
+ try {
1045
+ const generateId = () => `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1046
+ const newHistoryItem = {
1047
+ ...historyItem,
1048
+ id: generateId(),
1049
+ submittedAt: /* @__PURE__ */ new Date()
1050
+ };
1051
+ const existingData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1052
+ const allHistory = existingData ? JSON.parse(existingData) : [];
1053
+ allHistory.push(newHistoryItem);
1054
+ localStorage.setItem(CART_HISTORY_STORAGE_KEY, JSON.stringify(allHistory));
1055
+ console.log("\u2705 \u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u4FDD\u5B58\u6210\u529F:", {
1056
+ id: newHistoryItem.id,
1057
+ qqNumber: newHistoryItem.qqNumber,
1058
+ itemCount: newHistoryItem.items.length
1059
+ });
1060
+ return newHistoryItem;
1061
+ } catch (error) {
1062
+ console.error("\u4FDD\u5B58\u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1063
+ throw new Error("\u4FDD\u5B58\u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u5931\u8D25");
1064
+ }
1065
+ }
1066
+ /**
1067
+ * 更新预订状态
1068
+ *
1069
+ * @param qqNumber 用户QQ号
1070
+ * @param phoneNumber 用户手机号
1071
+ * @param historyId 历史记录ID
1072
+ * @param status 新状态
1073
+ * @param bookingIds 预订ID列表
1074
+ */
1075
+ static async updateBookingStatus(qqNumber, phoneNumber, historyId, status, bookingIds) {
1076
+ try {
1077
+ const historyData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1078
+ if (historyData) {
1079
+ const allHistory = JSON.parse(historyData);
1080
+ const recordIndex = allHistory.findIndex(
1081
+ (record) => record.id === historyId && record.qqNumber === qqNumber && record.phoneNumber === phoneNumber
1082
+ );
1083
+ if (recordIndex !== -1) {
1084
+ const record = allHistory[recordIndex];
1085
+ if (!record) {
1086
+ return;
1087
+ }
1088
+ record.status = status;
1089
+ if (bookingIds) {
1090
+ record.bookingIds = bookingIds;
1091
+ }
1092
+ localStorage.setItem(CART_HISTORY_STORAGE_KEY, JSON.stringify(allHistory));
1093
+ console.log("\u2705 \u9884\u8BA2\u72B6\u6001\u66F4\u65B0\u6210\u529F:", {
1094
+ historyId,
1095
+ status,
1096
+ bookingIds
1097
+ });
1098
+ }
1099
+ }
1100
+ } catch (error) {
1101
+ console.error("\u66F4\u65B0\u9884\u8BA2\u72B6\u6001\u5931\u8D25:", error);
1102
+ throw new Error("\u66F4\u65B0\u9884\u8BA2\u72B6\u6001\u5931\u8D25");
1103
+ }
1104
+ }
1105
+ /**
1106
+ * 删除历史记录
1107
+ *
1108
+ * @param qqNumber 用户QQ号
1109
+ * @param phoneNumber 用户手机号
1110
+ * @param historyId 历史记录ID
1111
+ */
1112
+ static async deleteHistoryRecord(qqNumber, phoneNumber, historyId) {
1113
+ try {
1114
+ const historyData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1115
+ if (historyData) {
1116
+ const allHistory = JSON.parse(historyData);
1117
+ const filteredHistory = allHistory.filter(
1118
+ (record) => !(record.id === historyId && record.qqNumber === qqNumber && record.phoneNumber === phoneNumber)
1119
+ );
1120
+ localStorage.setItem(CART_HISTORY_STORAGE_KEY, JSON.stringify(filteredHistory));
1121
+ console.log("\u2705 \u5386\u53F2\u8BB0\u5F55\u5220\u9664\u6210\u529F:", { historyId });
1122
+ }
1123
+ } catch (error) {
1124
+ console.error("\u5220\u9664\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1125
+ throw new Error("\u5220\u9664\u5386\u53F2\u8BB0\u5F55\u5931\u8D25");
1126
+ }
1127
+ }
1128
+ /**
1129
+ * 清空用户所有历史记录
1130
+ *
1131
+ * @param qqNumber 用户QQ号
1132
+ * @param phoneNumber 用户手机号
1133
+ */
1134
+ static async clearUserHistory(qqNumber, phoneNumber) {
1135
+ try {
1136
+ const historyData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1137
+ if (historyData) {
1138
+ const allHistory = JSON.parse(historyData);
1139
+ const filteredHistory = allHistory.filter(
1140
+ (record) => !(record.qqNumber === qqNumber && record.phoneNumber === phoneNumber)
1141
+ );
1142
+ localStorage.setItem(CART_HISTORY_STORAGE_KEY, JSON.stringify(filteredHistory));
1143
+ console.log("\u2705 \u7528\u6237\u5386\u53F2\u8BB0\u5F55\u6E05\u7A7A\u6210\u529F:", { qqNumber, phoneNumber });
1144
+ }
1145
+ } catch (error) {
1146
+ console.error("\u6E05\u7A7A\u7528\u6237\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1147
+ throw new Error("\u6E05\u7A7A\u7528\u6237\u5386\u53F2\u8BB0\u5F55\u5931\u8D25");
1148
+ }
1149
+ }
1150
+ /**
1151
+ * 获取所有历史记录(管理员功能)
1152
+ */
1153
+ static async getAllHistory() {
1154
+ try {
1155
+ const historyData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1156
+ if (historyData) {
1157
+ const allHistory = JSON.parse(historyData);
1158
+ return allHistory.map((record) => ({
1159
+ ...record,
1160
+ submittedAt: new Date(record.submittedAt),
1161
+ items: record.items.map((item) => ({
1162
+ ...item,
1163
+ addedAt: new Date(item.addedAt)
1164
+ }))
1165
+ }));
1166
+ }
1167
+ } catch (error) {
1168
+ console.error("\u8BFB\u53D6\u6240\u6709\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1169
+ }
1170
+ return [];
1171
+ }
1172
+ /**
1173
+ * 获取统计数据
1174
+ */
1175
+ static async getStatistics() {
1176
+ try {
1177
+ const allHistory = await this.getAllHistory();
1178
+ const totalRecords = allHistory.length;
1179
+ const uniqueUsers = new Set(
1180
+ allHistory.map((record) => `${record.qqNumber}_${record.phoneNumber}`)
1181
+ );
1182
+ const totalUsers = uniqueUsers.size;
1183
+ let totalItems = 0;
1184
+ let totalRevenue = 0;
1185
+ allHistory.forEach((record) => {
1186
+ totalItems += record.totalQuantity;
1187
+ totalRevenue += record.totalPrice;
1188
+ });
1189
+ return {
1190
+ totalRecords,
1191
+ totalUsers,
1192
+ totalItems,
1193
+ totalRevenue
1194
+ };
1195
+ } catch (error) {
1196
+ console.error("\u83B7\u53D6\u7EDF\u8BA1\u6570\u636E\u5931\u8D25:", error);
1197
+ return {
1198
+ totalRecords: 0,
1199
+ totalUsers: 0,
1200
+ totalItems: 0,
1201
+ totalRevenue: 0
1202
+ };
1203
+ }
1204
+ }
1205
+ };
1206
+ getCartHistory = CartHistoryService.getCartHistory;
1207
+ updateBookingStatus = CartHistoryService.updateBookingStatus;
1208
+ deleteHistoryRecord = CartHistoryService.deleteHistoryRecord;
1209
+ clearUserHistory = CartHistoryService.clearUserHistory;
1210
+ getAllHistory = CartHistoryService.getAllHistory;
1211
+ getStatistics = CartHistoryService.getStatistics;
1212
+ saveCartHistory = async (historyItem) => {
1213
+ try {
1214
+ const generateId = () => `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1215
+ const newHistoryItem = {
1216
+ ...historyItem,
1217
+ id: generateId(),
1218
+ submittedAt: /* @__PURE__ */ new Date()
1219
+ };
1220
+ const existingData = localStorage.getItem(CART_HISTORY_STORAGE_KEY);
1221
+ const allHistory = existingData ? JSON.parse(existingData) : [];
1222
+ allHistory.push(newHistoryItem);
1223
+ localStorage.setItem(CART_HISTORY_STORAGE_KEY, JSON.stringify(allHistory));
1224
+ console.log("\u2705 \u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u4FDD\u5B58\u6210\u529F:", {
1225
+ id: newHistoryItem.id,
1226
+ qqNumber: newHistoryItem.qqNumber,
1227
+ itemCount: newHistoryItem.items.length
1228
+ });
1229
+ return newHistoryItem;
1230
+ } catch (error) {
1231
+ console.error("\u4FDD\u5B58\u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1232
+ throw new Error("\u4FDD\u5B58\u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u5931\u8D25");
1233
+ }
1234
+ };
1235
+ }
1236
+ });
1237
+
1238
+ // src/showmasterpiece/services/cartService.ts
1239
+ var CART_STORAGE_KEY, CartService, getCart, addToCart, updateCartItem, removeFromCart, clearCart, batchBooking;
1240
+ var init_cartService = __esm({
1241
+ "src/showmasterpiece/services/cartService.ts"() {
1242
+ init_cartHistoryService();
1243
+ CART_STORAGE_KEY = "showmasterpiece_cart";
1244
+ CartService = class {
1245
+ /**
1246
+ * 获取购物车数据
1247
+ *
1248
+ * @param userId 用户ID
1249
+ * @returns 购物车数据
1250
+ */
1251
+ static async getCart(userId) {
1252
+ try {
1253
+ const storageKey = `${CART_STORAGE_KEY}_${userId}`;
1254
+ const cartData = localStorage.getItem(storageKey);
1255
+ if (cartData) {
1256
+ const parsed = JSON.parse(cartData);
1257
+ if (parsed.items) {
1258
+ parsed.items = parsed.items.map((item) => ({
1259
+ ...item,
1260
+ addedAt: new Date(item.addedAt)
1261
+ }));
1262
+ }
1263
+ return parsed;
1264
+ }
1265
+ } catch (error) {
1266
+ console.error("\u8BFB\u53D6\u8D2D\u7269\u8F66\u6570\u636E\u5931\u8D25:", error);
1267
+ }
1268
+ return {
1269
+ items: [],
1270
+ totalQuantity: 0,
1271
+ totalPrice: 0
1272
+ };
1273
+ }
1274
+ /**
1275
+ * 保存购物车数据到本地存储
1276
+ *
1277
+ * @param userId 用户ID
1278
+ * @param cart 购物车数据
1279
+ */
1280
+ static saveCart(userId, cart) {
1281
+ try {
1282
+ const storageKey = `${CART_STORAGE_KEY}_${userId}`;
1283
+ localStorage.setItem(storageKey, JSON.stringify(cart));
1284
+ } catch (error) {
1285
+ console.error("\u4FDD\u5B58\u8D2D\u7269\u8F66\u6570\u636E\u5931\u8D25:", error);
1286
+ }
1287
+ }
1288
+ /**
1289
+ * 计算购物车总数量和总价格
1290
+ *
1291
+ * @param items 购物车商品项
1292
+ * @returns 总数量和总价格
1293
+ */
1294
+ static calculateTotals(items) {
1295
+ let totalQuantity = 0;
1296
+ let totalPrice = 0;
1297
+ items.forEach((item) => {
1298
+ totalQuantity += item.quantity;
1299
+ const itemPrice = (item.collection.price || 0) * item.quantity;
1300
+ totalPrice += itemPrice;
1301
+ });
1302
+ return { totalQuantity, totalPrice };
1303
+ }
1304
+ /**
1305
+ * 添加商品到购物车
1306
+ *
1307
+ * @param data 添加商品数据
1308
+ * @returns 更新后的购物车数据
1309
+ */
1310
+ static async addToCart(data) {
1311
+ const { userId, collectionId, quantity, collection } = data;
1312
+ const cart = await this.getCart(userId);
1313
+ const existingItemIndex = cart.items.findIndex((item) => item.collectionId === collectionId);
1314
+ if (existingItemIndex >= 0) {
1315
+ const existingItem = cart.items[existingItemIndex];
1316
+ if (existingItem) {
1317
+ existingItem.quantity += quantity;
1318
+ }
1319
+ } else {
1320
+ if (collection) {
1321
+ cart.items.push({
1322
+ collectionId,
1323
+ collection,
1324
+ quantity,
1325
+ addedAt: /* @__PURE__ */ new Date()
1326
+ });
1327
+ } else {
1328
+ cart.items.push({
1329
+ collectionId,
1330
+ collection: {
1331
+ id: collectionId,
1332
+ title: `\u753B\u96C6${collectionId}`,
1333
+ // 临时标题,实际应该从画集数据中获取
1334
+ number: "\u672A\u77E5\u7F16\u53F7",
1335
+ coverImage: "",
1336
+ description: "",
1337
+ pages: [],
1338
+ category: "\u753B\u96C6",
1339
+ tags: [],
1340
+ isPublished: true,
1341
+ price: 0
1342
+ },
1343
+ quantity,
1344
+ addedAt: /* @__PURE__ */ new Date()
1345
+ });
1346
+ }
1347
+ }
1348
+ const { totalQuantity, totalPrice } = this.calculateTotals(cart.items);
1349
+ cart.totalQuantity = totalQuantity;
1350
+ cart.totalPrice = totalPrice;
1351
+ this.saveCart(userId, cart);
1352
+ return cart;
1353
+ }
1354
+ /**
1355
+ * 更新购物车商品数量
1356
+ *
1357
+ * @param data 更新商品数据
1358
+ * @returns 更新后的购物车数据
1359
+ */
1360
+ static async updateCartItem(data) {
1361
+ const { userId, collectionId, quantity } = data;
1362
+ const cart = await this.getCart(userId);
1363
+ const itemIndex = cart.items.findIndex((item) => item.collectionId === collectionId);
1364
+ if (itemIndex >= 0) {
1365
+ if (quantity <= 0) {
1366
+ cart.items.splice(itemIndex, 1);
1367
+ } else {
1368
+ const item = cart.items[itemIndex];
1369
+ if (item) {
1370
+ item.quantity = quantity;
1371
+ }
1372
+ }
1373
+ const { totalQuantity, totalPrice } = this.calculateTotals(cart.items);
1374
+ cart.totalQuantity = totalQuantity;
1375
+ cart.totalPrice = totalPrice;
1376
+ this.saveCart(userId, cart);
1377
+ }
1378
+ return cart;
1379
+ }
1380
+ /**
1381
+ * 从购物车移除商品
1382
+ *
1383
+ * @param data 移除商品数据
1384
+ * @returns 更新后的购物车数据
1385
+ */
1386
+ static async removeFromCart(data) {
1387
+ const { userId, collectionId } = data;
1388
+ const cart = await this.getCart(userId);
1389
+ cart.items = cart.items.filter((item) => item.collectionId !== collectionId);
1390
+ const { totalQuantity, totalPrice } = this.calculateTotals(cart.items);
1391
+ cart.totalQuantity = totalQuantity;
1392
+ cart.totalPrice = totalPrice;
1393
+ this.saveCart(userId, cart);
1394
+ return cart;
1395
+ }
1396
+ /**
1397
+ * 清空购物车
1398
+ *
1399
+ * @param userId 用户ID
1400
+ * @returns 清空后的购物车数据
1401
+ */
1402
+ static async clearCart(userId) {
1403
+ const emptyCart = {
1404
+ items: [],
1405
+ totalQuantity: 0,
1406
+ totalPrice: 0
1407
+ };
1408
+ this.saveCart(userId, emptyCart);
1409
+ return emptyCart;
1410
+ }
1411
+ /**
1412
+ * 批量预订购物车中的商品
1413
+ *
1414
+ * @param data 批量预订数据
1415
+ * @param cart 当前购物车数据(用于保存历史记录)
1416
+ * @returns 预订结果
1417
+ */
1418
+ static async batchBooking(data, cart) {
1419
+ const requestData = {
1420
+ ...data
1421
+ };
1422
+ console.log("\u{1F6D2} [CartService] \u6279\u91CF\u9884\u8BA2:", { data });
1423
+ const response = await fetch(this.BOOKING_URL, {
1424
+ method: "POST",
1425
+ headers: {
1426
+ "Content-Type": "application/json"
1427
+ },
1428
+ body: JSON.stringify(requestData)
1429
+ });
1430
+ if (!response.ok) {
1431
+ const error = await response.json().catch(() => ({ message: "\u6279\u91CF\u9884\u8BA2\u5931\u8D25" }));
1432
+ throw new Error(error.message || "\u6279\u91CF\u9884\u8BA2\u5931\u8D25");
1433
+ }
1434
+ const result = await response.json();
1435
+ if (result.successCount > 0 && cart) {
1436
+ try {
1437
+ await saveCartHistory({
1438
+ qqNumber: data.qqNumber,
1439
+ phoneNumber: data.phoneNumber,
1440
+ items: cart.items,
1441
+ totalQuantity: cart.totalQuantity,
1442
+ totalPrice: cart.totalPrice,
1443
+ notes: data.notes,
1444
+ pickupMethod: data.pickupMethod,
1445
+ status: "pending",
1446
+ bookingIds: result.bookingIds,
1447
+ submittedAt: /* @__PURE__ */ new Date()
1448
+ });
1449
+ } catch (error) {
1450
+ console.error("\u4FDD\u5B58\u8D2D\u7269\u8F66\u5386\u53F2\u8BB0\u5F55\u5931\u8D25:", error);
1451
+ }
1452
+ }
1453
+ return result;
1454
+ }
1455
+ };
1456
+ CartService.BOOKING_URL = "/api/showmasterpiece/bookings/batch";
1457
+ getCart = (userId) => {
1458
+ return CartService.getCart(userId);
1459
+ };
1460
+ addToCart = (data) => {
1461
+ return CartService.addToCart(data);
1462
+ };
1463
+ updateCartItem = (data) => {
1464
+ return CartService.updateCartItem(data);
1465
+ };
1466
+ removeFromCart = (data) => {
1467
+ return CartService.removeFromCart(data);
1468
+ };
1469
+ clearCart = (userId) => {
1470
+ return CartService.clearCart(userId);
1471
+ };
1472
+ batchBooking = (data, cart) => {
1473
+ return CartService.batchBooking(data, cart);
1474
+ };
1475
+ }
1476
+ });
1477
+ function useCart(userId) {
1478
+ const [state, setState] = useState({
1479
+ cart: {
1480
+ items: [],
1481
+ totalQuantity: 0,
1482
+ totalPrice: 0
1483
+ },
1484
+ loading: false,
1485
+ error: void 0,
1486
+ isCartOpen: false
1487
+ });
1488
+ const loadCart = useCallback(async () => {
1489
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1490
+ try {
1491
+ const cartData = await getCart(userId);
1492
+ setState((prev) => ({
1493
+ ...prev,
1494
+ cart: cartData,
1495
+ loading: false
1496
+ }));
1497
+ } catch (error) {
1498
+ console.error("\u52A0\u8F7D\u8D2D\u7269\u8F66\u5931\u8D25:", error);
1499
+ setState((prev) => ({
1500
+ ...prev,
1501
+ loading: false,
1502
+ error: error instanceof Error ? error.message : "\u52A0\u8F7D\u8D2D\u7269\u8F66\u5931\u8D25"
1503
+ }));
1504
+ }
1505
+ }, [userId]);
1506
+ const addItemToCart = useCallback(async (request) => {
1507
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1508
+ try {
1509
+ const updatedCart = await addToCart(request);
1510
+ setState((prev) => ({
1511
+ ...prev,
1512
+ cart: updatedCart,
1513
+ loading: false
1514
+ }));
1515
+ notifyCartUpdate();
1516
+ } catch (error) {
1517
+ console.error("\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u5931\u8D25:", error);
1518
+ setState((prev) => ({
1519
+ ...prev,
1520
+ loading: false,
1521
+ error: error instanceof Error ? error.message : "\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u5931\u8D25"
1522
+ }));
1523
+ }
1524
+ }, [userId]);
1525
+ const updateItemQuantity = useCallback(async (collectionId, quantity) => {
1526
+ if (quantity <= 0) {
1527
+ await removeItemFromCart(collectionId);
1528
+ return;
1529
+ }
1530
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1531
+ try {
1532
+ const request = {
1533
+ userId,
1534
+ collectionId,
1535
+ quantity
1536
+ };
1537
+ const updatedCart = await updateCartItem(request);
1538
+ setState((prev) => ({
1539
+ ...prev,
1540
+ cart: updatedCart,
1541
+ loading: false
1542
+ }));
1543
+ notifyCartUpdate();
1544
+ } catch (error) {
1545
+ console.error("\u66F4\u65B0\u8D2D\u7269\u8F66\u5931\u8D25:", error);
1546
+ setState((prev) => ({
1547
+ ...prev,
1548
+ loading: false,
1549
+ error: error instanceof Error ? error.message : "\u66F4\u65B0\u8D2D\u7269\u8F66\u5931\u8D25"
1550
+ }));
1551
+ }
1552
+ }, [userId]);
1553
+ const removeItemFromCart = useCallback(async (collectionId) => {
1554
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1555
+ try {
1556
+ const request = {
1557
+ userId,
1558
+ collectionId
1559
+ };
1560
+ const updatedCart = await removeFromCart(request);
1561
+ setState((prev) => ({
1562
+ ...prev,
1563
+ cart: updatedCart,
1564
+ loading: false
1565
+ }));
1566
+ notifyCartUpdate();
1567
+ } catch (error) {
1568
+ console.error("\u4ECE\u8D2D\u7269\u8F66\u79FB\u9664\u5931\u8D25:", error);
1569
+ setState((prev) => ({
1570
+ ...prev,
1571
+ loading: false,
1572
+ error: error instanceof Error ? error.message : "\u4ECE\u8D2D\u7269\u8F66\u79FB\u9664\u5931\u8D25"
1573
+ }));
1574
+ }
1575
+ }, [userId]);
1576
+ const clearCartItems = useCallback(async () => {
1577
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1578
+ try {
1579
+ await clearCart(userId);
1580
+ setState((prev) => ({
1581
+ ...prev,
1582
+ cart: { items: [], totalQuantity: 0, totalPrice: 0 },
1583
+ loading: false
1584
+ }));
1585
+ notifyCartUpdate();
1586
+ } catch (error) {
1587
+ console.error("\u6E05\u7A7A\u8D2D\u7269\u8F66\u5931\u8D25:", error);
1588
+ setState((prev) => ({
1589
+ ...prev,
1590
+ loading: false,
1591
+ error: error instanceof Error ? error.message : "\u6E05\u7A7A\u8D2D\u7269\u8F66\u5931\u8D25"
1592
+ }));
1593
+ }
1594
+ }, [userId]);
1595
+ const checkoutCart = useCallback(async (qqNumber, phoneNumber, notes, pickupMethod = "") => {
1596
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1597
+ try {
1598
+ const request = {
1599
+ qqNumber,
1600
+ phoneNumber,
1601
+ items: state.cart.items.map((item) => ({
1602
+ collectionId: item.collectionId,
1603
+ quantity: item.quantity
1604
+ })),
1605
+ notes,
1606
+ pickupMethod
1607
+ };
1608
+ const result = await batchBooking(request, state.cart);
1609
+ if (result.successCount > 0) {
1610
+ await clearCartItems();
1611
+ }
1612
+ setState((prev) => ({ ...prev, loading: false }));
1613
+ return result;
1614
+ } catch (error) {
1615
+ console.error("\u6279\u91CF\u9884\u8BA2\u5931\u8D25:", error);
1616
+ setState((prev) => ({
1617
+ ...prev,
1618
+ loading: false,
1619
+ error: error instanceof Error ? error.message : "\u6279\u91CF\u9884\u8BA2\u5931\u8D25"
1620
+ }));
1621
+ throw error;
1622
+ }
1623
+ }, [state.cart.items, clearCartItems]);
1624
+ const openCart = useCallback(() => {
1625
+ setState((prev) => ({ ...prev, isCartOpen: true }));
1626
+ }, []);
1627
+ const closeCart = useCallback(() => {
1628
+ setState((prev) => ({ ...prev, isCartOpen: false }));
1629
+ }, []);
1630
+ const clearError = useCallback(() => {
1631
+ setState((prev) => ({ ...prev, error: void 0 }));
1632
+ }, []);
1633
+ useEffect(() => {
1634
+ if (userId) {
1635
+ loadCart();
1636
+ }
1637
+ }, [userId, loadCart]);
1638
+ return {
1639
+ // 状态
1640
+ cart: state.cart,
1641
+ loading: state.loading,
1642
+ error: state.error,
1643
+ isCartOpen: state.isCartOpen,
1644
+ // 操作方法
1645
+ loadCart,
1646
+ addItemToCart,
1647
+ updateItemQuantity,
1648
+ removeItemFromCart,
1649
+ clearCartItems,
1650
+ checkoutCart,
1651
+ openCart,
1652
+ closeCart,
1653
+ clearError
1654
+ };
1655
+ }
1656
+ var cartUpdateEvents, CART_UPDATE_EVENT, notifyCartUpdate;
1657
+ var init_useCart = __esm({
1658
+ "src/showmasterpiece/logic/hooks/useCart.ts"() {
1659
+ init_cartService();
1660
+ cartUpdateEvents = new EventTarget();
1661
+ CART_UPDATE_EVENT = "cart-updated";
1662
+ notifyCartUpdate = () => {
1663
+ cartUpdateEvents.dispatchEvent(new Event(CART_UPDATE_EVENT));
1664
+ };
1665
+ }
1666
+ });
1667
+
1668
+ // src/showmasterpiece/services/bookingService.ts
1669
+ var BookingService, createBooking, getBookings, getBooking, updateBooking, deleteBooking, getBookableCollections;
1670
+ var init_bookingService = __esm({
1671
+ "src/showmasterpiece/services/bookingService.ts"() {
1672
+ BookingService = class {
1673
+ /**
1674
+ * 创建新预订
1675
+ *
1676
+ * @param data 预订数据
1677
+ * @returns 创建的预订信息
1678
+ */
1679
+ static async createBooking(data) {
1680
+ const response = await fetch(this.BASE_URL, {
1681
+ method: "POST",
1682
+ headers: {
1683
+ "Content-Type": "application/json"
1684
+ },
1685
+ body: JSON.stringify(data)
1686
+ });
1687
+ if (!response.ok) {
1688
+ const error = await response.json().catch(() => ({ message: "\u521B\u5EFA\u9884\u8BA2\u5931\u8D25" }));
1689
+ throw new Error(error.message || "\u521B\u5EFA\u9884\u8BA2\u5931\u8D25");
1690
+ }
1691
+ return response.json();
1692
+ }
1693
+ /**
1694
+ * 获取预订列表
1695
+ *
1696
+ * @param params 查询参数
1697
+ * @returns 预订列表和分页信息
1698
+ */
1699
+ static async getBookings(params = {}) {
1700
+ const searchParams = new URLSearchParams();
1701
+ if (params.collectionId) {
1702
+ searchParams.append("collectionId", params.collectionId.toString());
1703
+ }
1704
+ if (params.qqNumber) {
1705
+ searchParams.append("qqNumber", params.qqNumber);
1706
+ }
1707
+ if (params.phoneNumber) {
1708
+ searchParams.append("phoneNumber", params.phoneNumber);
1709
+ }
1710
+ if (params.status) {
1711
+ searchParams.append("status", params.status);
1712
+ }
1713
+ if (params.page) {
1714
+ searchParams.append("page", params.page.toString());
1715
+ }
1716
+ if (params.limit) {
1717
+ searchParams.append("limit", params.limit.toString());
1718
+ }
1719
+ const url = `${this.BASE_URL}?${searchParams.toString()}`;
1720
+ const response = await fetch(url);
1721
+ if (!response.ok) {
1722
+ const error = await response.json().catch(() => ({ message: "\u83B7\u53D6\u9884\u8BA2\u5217\u8868\u5931\u8D25" }));
1723
+ throw new Error(error.message || "\u83B7\u53D6\u9884\u8BA2\u5217\u8868\u5931\u8D25");
1724
+ }
1725
+ return response.json();
1726
+ }
1727
+ /**
1728
+ * 获取单个预订详情
1729
+ *
1730
+ * @param id 预订ID
1731
+ * @returns 预订详情
1732
+ */
1733
+ static async getBooking(id) {
1734
+ const response = await fetch(`${this.BASE_URL}/${id}`);
1735
+ if (!response.ok) {
1736
+ const error = await response.json().catch(() => ({ message: "\u83B7\u53D6\u9884\u8BA2\u8BE6\u60C5\u5931\u8D25" }));
1737
+ throw new Error(error.message || "\u83B7\u53D6\u9884\u8BA2\u8BE6\u60C5\u5931\u8D25");
1738
+ }
1739
+ return response.json();
1740
+ }
1741
+ /**
1742
+ * 更新预订状态
1743
+ *
1744
+ * @param id 预订ID
1745
+ * @param data 更新数据
1746
+ * @returns 更新后的预订信息
1747
+ */
1748
+ static async updateBooking(id, data) {
1749
+ const response = await fetch(`${this.BASE_URL}/${id}`, {
1750
+ method: "PUT",
1751
+ headers: {
1752
+ "Content-Type": "application/json"
1753
+ },
1754
+ body: JSON.stringify(data)
1755
+ });
1756
+ if (!response.ok) {
1757
+ const error = await response.json().catch(() => ({ message: "\u66F4\u65B0\u9884\u8BA2\u5931\u8D25" }));
1758
+ throw new Error(error.message || "\u66F4\u65B0\u9884\u8BA2\u5931\u8D25");
1759
+ }
1760
+ return response.json();
1761
+ }
1762
+ /**
1763
+ * 删除预订
1764
+ *
1765
+ * @param id 预订ID
1766
+ */
1767
+ static async deleteBooking(id) {
1768
+ const response = await fetch(`${this.BASE_URL}/${id}`, {
1769
+ method: "DELETE"
1770
+ });
1771
+ if (!response.ok) {
1772
+ const error = await response.json().catch(() => ({ message: "\u5220\u9664\u9884\u8BA2\u5931\u8D25" }));
1773
+ throw new Error(error.message || "\u5220\u9664\u9884\u8BA2\u5931\u8D25");
1774
+ }
1775
+ }
1776
+ /**
1777
+ * 获取可预订的画集列表
1778
+ *
1779
+ * @returns 画集简略信息列表
1780
+ */
1781
+ static async getBookableCollections() {
1782
+ const url = `${this.BASE_URL}/collections`;
1783
+ console.log("\u{1F4E1} [BookingService] \u83B7\u53D6\u53EF\u9884\u8BA2\u753B\u96C6:", { url });
1784
+ const response = await fetch(url);
1785
+ if (!response.ok) {
1786
+ const error = await response.json().catch(() => ({ message: "\u83B7\u53D6\u753B\u96C6\u5217\u8868\u5931\u8D25" }));
1787
+ throw new Error(error.message || "\u83B7\u53D6\u753B\u96C6\u5217\u8868\u5931\u8D25");
1788
+ }
1789
+ const data = await response.json();
1790
+ if (data.success && Array.isArray(data.data)) {
1791
+ console.log(`\u2705 [BookingService] \u83B7\u53D6\u5230 ${data.data.length} \u4E2A\u53EF\u9884\u8BA2\u753B\u96C6`);
1792
+ return data.data;
1793
+ }
1794
+ if (Array.isArray(data)) {
1795
+ console.log(`\u2705 [BookingService] \u83B7\u53D6\u5230 ${data.length} \u4E2A\u53EF\u9884\u8BA2\u753B\u96C6 (\u517C\u5BB9\u683C\u5F0F)`);
1796
+ return data;
1797
+ }
1798
+ throw new Error("API\u54CD\u5E94\u683C\u5F0F\u9519\u8BEF");
1799
+ }
1800
+ };
1801
+ BookingService.BASE_URL = "/api/showmasterpiece/bookings";
1802
+ createBooking = (data) => {
1803
+ return BookingService.createBooking(data);
1804
+ };
1805
+ getBookings = (params) => {
1806
+ return BookingService.getBookings(params);
1807
+ };
1808
+ getBooking = (id) => {
1809
+ return BookingService.getBooking(id);
1810
+ };
1811
+ updateBooking = (id, data) => {
1812
+ return BookingService.updateBooking(id, data);
1813
+ };
1814
+ deleteBooking = (id) => {
1815
+ return BookingService.deleteBooking(id);
1816
+ };
1817
+ getBookableCollections = () => {
1818
+ return BookingService.getBookableCollections();
1819
+ };
1820
+ }
1821
+ });
1822
+ function useBooking(_props = {}) {
1823
+ const [state, setState] = useState({
1824
+ collections: [],
1825
+ loading: false,
1826
+ error: void 0,
1827
+ submitting: false,
1828
+ submitted: false
1829
+ });
1830
+ const loadCollections = useCallback(async () => {
1831
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
1832
+ try {
1833
+ console.log("\u{1F504} [useBooking] \u52A0\u8F7D\u753B\u96C6\u5217\u8868...");
1834
+ const collections = await getBookableCollections();
1835
+ setState((prev) => ({
1836
+ ...prev,
1837
+ collections,
1838
+ loading: false
1839
+ }));
1840
+ } catch (error) {
1841
+ console.error("\u52A0\u8F7D\u753B\u96C6\u5217\u8868\u5931\u8D25:", error);
1842
+ setState((prev) => ({
1843
+ ...prev,
1844
+ loading: false,
1845
+ error: error instanceof Error ? error.message : "\u52A0\u8F7D\u753B\u96C6\u5217\u8868\u5931\u8D25"
1846
+ }));
1847
+ }
1848
+ }, []);
1849
+ const submitBooking = useCallback(async (formData) => {
1850
+ setState((prev) => ({ ...prev, submitting: true, error: void 0 }));
1851
+ try {
1852
+ const bookingData = {
1853
+ collectionId: formData.collectionId,
1854
+ qqNumber: formData.qqNumber,
1855
+ phoneNumber: formData.phoneNumber.trim(),
1856
+ quantity: formData.quantity,
1857
+ notes: formData.notes || void 0
1858
+ };
1859
+ await createBooking(bookingData);
1860
+ setState((prev) => ({
1861
+ ...prev,
1862
+ submitting: false,
1863
+ submitted: true
1864
+ }));
1865
+ } catch (error) {
1866
+ console.error("\u63D0\u4EA4\u9884\u8BA2\u5931\u8D25:", error);
1867
+ setState((prev) => ({
1868
+ ...prev,
1869
+ submitting: false,
1870
+ error: error instanceof Error ? error.message : "\u63D0\u4EA4\u9884\u8BA2\u5931\u8D25"
1871
+ }));
1872
+ }
1873
+ }, []);
1874
+ const resetSubmission = useCallback(() => {
1875
+ setState((prev) => ({
1876
+ ...prev,
1877
+ submitted: false,
1878
+ error: void 0
1879
+ }));
1880
+ }, []);
1881
+ const clearError = useCallback(() => {
1882
+ setState((prev) => ({ ...prev, error: void 0 }));
1883
+ }, []);
1884
+ useEffect(() => {
1885
+ loadCollections();
1886
+ }, [loadCollections]);
1887
+ return {
1888
+ // 状态
1889
+ collections: state.collections,
1890
+ loading: state.loading,
1891
+ error: state.error,
1892
+ submitting: state.submitting,
1893
+ submitted: state.submitted,
1894
+ // 操作方法
1895
+ loadCollections,
1896
+ submitBooking,
1897
+ resetSubmission,
1898
+ clearError
1899
+ };
1900
+ }
1901
+ function useBookingForm() {
1902
+ const [formData, setFormData] = useState({
1903
+ collectionId: 0,
1904
+ qqNumber: "",
1905
+ phoneNumber: "",
1906
+ quantity: 1,
1907
+ notes: ""
1908
+ });
1909
+ const [errors, setErrors] = useState({});
1910
+ const updateField = useCallback((field, value) => {
1911
+ setFormData((prev) => ({ ...prev, [field]: value }));
1912
+ if (errors[field]) {
1913
+ setErrors((prev) => ({ ...prev, [field]: void 0 }));
1914
+ }
1915
+ }, [errors]);
1916
+ const validateForm = useCallback(() => {
1917
+ const newErrors = {};
1918
+ if (!formData.collectionId) {
1919
+ newErrors.collectionId = "\u8BF7\u9009\u62E9\u8981\u9884\u8BA2\u7684\u753B\u96C6";
1920
+ }
1921
+ if (!formData.qqNumber.trim()) {
1922
+ newErrors.qqNumber = "\u8BF7\u8F93\u5165QQ\u53F7";
1923
+ } else if (!/^\d{5,11}$/.test(formData.qqNumber.trim())) {
1924
+ newErrors.qqNumber = "QQ\u53F7\u683C\u5F0F\u4E0D\u6B63\u786E";
1925
+ }
1926
+ if (formData.phoneNumber.trim()) {
1927
+ const phoneRegex = /^1[3-9]\d{9}$/;
1928
+ if (!phoneRegex.test(formData.phoneNumber.trim())) {
1929
+ newErrors.phoneNumber = "\u624B\u673A\u53F7\u683C\u5F0F\u4E0D\u6B63\u786E";
1930
+ }
1931
+ }
1932
+ if (!formData.quantity || formData.quantity < 1) {
1933
+ newErrors.quantity = "\u9884\u8BA2\u6570\u91CF\u5FC5\u987B\u5927\u4E8E0";
1934
+ }
1935
+ setErrors(newErrors);
1936
+ return Object.keys(newErrors).length === 0;
1937
+ }, [formData]);
1938
+ const resetForm = useCallback(() => {
1939
+ setFormData({
1940
+ collectionId: 0,
1941
+ qqNumber: "",
1942
+ phoneNumber: "",
1943
+ quantity: 1,
1944
+ notes: ""
1945
+ });
1946
+ setErrors({});
1947
+ }, []);
1948
+ return {
1949
+ formData,
1950
+ errors,
1951
+ updateField,
1952
+ validateForm,
1953
+ resetForm
1954
+ };
1955
+ }
1956
+ var init_useBooking = __esm({
1957
+ "src/showmasterpiece/logic/hooks/useBooking.ts"() {
1958
+ init_bookingService();
1959
+ }
1960
+ });
1961
+
1962
+ // src/showmasterpiece/services/bookingAdminService.ts
1963
+ var BookingAdminService, getAllBookings, getBookingStats, forceRefreshAllBookings, forceRefreshBookingStats, updateBookingStatus2, deleteBooking2, exportBookings;
1964
+ var init_bookingAdminService = __esm({
1965
+ "src/showmasterpiece/services/bookingAdminService.ts"() {
1966
+ BookingAdminService = class {
1967
+ /**
1968
+ * 获取所有预订数据
1969
+ */
1970
+ static async getAllBookings(params) {
1971
+ try {
1972
+ const timestamp = Date.now();
1973
+ const randomId = Math.random().toString(36).substring(7);
1974
+ const searchParams = new URLSearchParams();
1975
+ searchParams.append("t", timestamp.toString());
1976
+ searchParams.append("forceRefresh", randomId);
1977
+ if (params?.qqNumber) {
1978
+ searchParams.append("qqNumber", params.qqNumber);
1979
+ }
1980
+ if (params?.phoneNumber) {
1981
+ searchParams.append("phoneNumber", params.phoneNumber);
1982
+ }
1983
+ if (params?.status && params.status !== "all") {
1984
+ searchParams.append("status", params.status);
1985
+ }
1986
+ const response = await fetch(`/api/showmasterpiece/bookings/admin?${searchParams.toString()}`, {
1987
+ method: "GET",
1988
+ cache: "no-store",
1989
+ headers: {
1990
+ "Cache-Control": "no-cache, no-store, must-revalidate",
1991
+ "Pragma": "no-cache",
1992
+ "Expires": "0",
1993
+ "X-Requested-With": "XMLHttpRequest"
1994
+ }
1995
+ });
1996
+ if (!response.ok) {
1997
+ throw new Error("\u83B7\u53D6\u9884\u8BA2\u6570\u636E\u5931\u8D25");
1998
+ }
1999
+ const data = await response.json();
2000
+ return data.bookings || [];
2001
+ } catch (error) {
2002
+ console.error("\u83B7\u53D6\u9884\u8BA2\u6570\u636E\u5931\u8D25:", error);
2003
+ throw error;
2004
+ }
2005
+ }
2006
+ /**
2007
+ * 强制刷新获取所有预订数据(绕过所有缓存)
2008
+ */
2009
+ static async forceRefreshAllBookings(params) {
2010
+ try {
2011
+ console.log("\u{1F504} \u4F7F\u7528\u5F3A\u5236\u5237\u65B0API\u83B7\u53D6\u9884\u8BA2\u6570\u636E...");
2012
+ const timestamp = Date.now();
2013
+ const randomId = Math.random().toString(36).substring(7);
2014
+ const searchParams = new URLSearchParams();
2015
+ searchParams.append("t", timestamp.toString());
2016
+ searchParams.append("forceRefresh", randomId);
2017
+ if (params?.qqNumber) {
2018
+ searchParams.append("qqNumber", params.qqNumber);
2019
+ }
2020
+ if (params?.phoneNumber) {
2021
+ searchParams.append("phoneNumber", params.phoneNumber);
2022
+ }
2023
+ if (params?.status && params.status !== "all") {
2024
+ searchParams.append("status", params.status);
2025
+ }
2026
+ const response = await fetch(`/api/showmasterpiece/bookings/admin/refresh?${searchParams.toString()}`, {
2027
+ method: "GET",
2028
+ cache: "no-store",
2029
+ headers: {
2030
+ "Cache-Control": "no-cache, no-store, must-revalidate",
2031
+ "Pragma": "no-cache",
2032
+ "Expires": "0",
2033
+ "X-Requested-With": "XMLHttpRequest",
2034
+ "X-Force-Refresh": "true"
2035
+ }
2036
+ });
2037
+ if (!response.ok) {
2038
+ throw new Error("\u5F3A\u5236\u5237\u65B0\u83B7\u53D6\u9884\u8BA2\u6570\u636E\u5931\u8D25");
2039
+ }
2040
+ const data = await response.json();
2041
+ console.log("\u{1F504} \u5F3A\u5236\u5237\u65B0API\u54CD\u5E94:", {
2042
+ bookingsCount: data.bookings?.length || 0,
2043
+ timestamp: data._timestamp,
2044
+ refreshType: data._refreshType
2045
+ });
2046
+ return data.bookings || [];
2047
+ } catch (error) {
2048
+ console.error("\u5F3A\u5236\u5237\u65B0\u83B7\u53D6\u9884\u8BA2\u6570\u636E\u5931\u8D25:", error);
2049
+ throw error;
2050
+ }
2051
+ }
2052
+ /**
2053
+ * 获取预订统计信息
2054
+ */
2055
+ static async getBookingStats(params) {
2056
+ try {
2057
+ const timestamp = Date.now();
2058
+ const randomId = Math.random().toString(36).substring(7);
2059
+ const searchParams = new URLSearchParams();
2060
+ searchParams.append("t", timestamp.toString());
2061
+ searchParams.append("forceRefresh", randomId);
2062
+ if (params?.qqNumber) {
2063
+ searchParams.append("qqNumber", params.qqNumber);
2064
+ }
2065
+ if (params?.phoneNumber) {
2066
+ searchParams.append("phoneNumber", params.phoneNumber);
2067
+ }
2068
+ if (params?.status && params.status !== "all") {
2069
+ searchParams.append("status", params.status);
2070
+ }
2071
+ const response = await fetch(`/api/showmasterpiece/bookings/admin?${searchParams.toString()}`, {
2072
+ method: "GET",
2073
+ cache: "no-store",
2074
+ headers: {
2075
+ "Cache-Control": "no-cache, no-store, must-revalidate",
2076
+ "Pragma": "no-cache",
2077
+ "Expires": "0",
2078
+ "X-Requested-With": "XMLHttpRequest"
2079
+ }
2080
+ });
2081
+ if (!response.ok) {
2082
+ throw new Error("\u83B7\u53D6\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25");
2083
+ }
2084
+ const data = await response.json();
2085
+ return data.stats || {
2086
+ totalBookings: 0,
2087
+ pendingBookings: 0,
2088
+ confirmedBookings: 0,
2089
+ completedBookings: 0,
2090
+ cancelledBookings: 0,
2091
+ totalQuantity: 0,
2092
+ totalRevenue: 0,
2093
+ totalAmount: 0,
2094
+ todayBookings: 0,
2095
+ weekBookings: 0
2096
+ };
2097
+ } catch (error) {
2098
+ console.error("\u83B7\u53D6\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:", error);
2099
+ throw error;
2100
+ }
2101
+ }
2102
+ /**
2103
+ * 强制刷新获取预订统计信息(绕过所有缓存)
2104
+ */
2105
+ static async forceRefreshBookingStats(params) {
2106
+ try {
2107
+ console.log("\u{1F504} \u4F7F\u7528\u5F3A\u5236\u5237\u65B0API\u83B7\u53D6\u7EDF\u8BA1\u4FE1\u606F...");
2108
+ const timestamp = Date.now();
2109
+ const randomId = Math.random().toString(36).substring(7);
2110
+ const searchParams = new URLSearchParams();
2111
+ searchParams.append("t", timestamp.toString());
2112
+ searchParams.append("forceRefresh", randomId);
2113
+ if (params?.qqNumber) {
2114
+ searchParams.append("qqNumber", params.qqNumber);
2115
+ }
2116
+ if (params?.phoneNumber) {
2117
+ searchParams.append("phoneNumber", params.phoneNumber);
2118
+ }
2119
+ if (params?.status && params.status !== "all") {
2120
+ searchParams.append("status", params.status);
2121
+ }
2122
+ const response = await fetch(`/api/showmasterpiece/bookings/admin/refresh?${searchParams.toString()}`, {
2123
+ method: "GET",
2124
+ cache: "no-store",
2125
+ headers: {
2126
+ "Cache-Control": "no-cache, no-store, must-revalidate",
2127
+ "Pragma": "no-cache",
2128
+ "Expires": "0",
2129
+ "X-Requested-With": "XMLHttpRequest",
2130
+ "X-Force-Refresh": "true"
2131
+ }
2132
+ });
2133
+ if (!response.ok) {
2134
+ throw new Error("\u5F3A\u5236\u5237\u65B0\u83B7\u53D6\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25");
2135
+ }
2136
+ const data = await response.json();
2137
+ console.log("\u{1F504} \u5F3A\u5236\u5237\u65B0\u7EDF\u8BA1\u4FE1\u606F\u54CD\u5E94:", {
2138
+ stats: data.stats,
2139
+ timestamp: data._timestamp,
2140
+ refreshType: data._refreshType
2141
+ });
2142
+ return data.stats || {
2143
+ totalBookings: 0,
2144
+ pendingBookings: 0,
2145
+ confirmedBookings: 0,
2146
+ completedBookings: 0,
2147
+ cancelledBookings: 0,
2148
+ totalQuantity: 0,
2149
+ totalRevenue: 0,
2150
+ totalAmount: 0,
2151
+ todayBookings: 0,
2152
+ weekBookings: 0
2153
+ };
2154
+ } catch (error) {
2155
+ console.error("\u5F3A\u5236\u5237\u65B0\u83B7\u53D6\u7EDF\u8BA1\u4FE1\u606F\u5931\u8D25:", error);
2156
+ throw error;
2157
+ }
2158
+ }
2159
+ /**
2160
+ * 更新预订状态
2161
+ */
2162
+ static async updateBookingStatus(bookingId, status, adminNotes) {
2163
+ try {
2164
+ const response = await fetch(`/api/showmasterpiece/bookings/admin/${bookingId}/status`, {
2165
+ method: "PUT",
2166
+ headers: {
2167
+ "Content-Type": "application/json"
2168
+ },
2169
+ body: JSON.stringify({ status, adminNotes })
2170
+ });
2171
+ if (!response.ok) {
2172
+ throw new Error("\u66F4\u65B0\u9884\u8BA2\u72B6\u6001\u5931\u8D25");
2173
+ }
2174
+ } catch (error) {
2175
+ console.error("\u66F4\u65B0\u9884\u8BA2\u72B6\u6001\u5931\u8D25:", error);
2176
+ throw error;
2177
+ }
2178
+ }
2179
+ /**
2180
+ * 删除预订
2181
+ */
2182
+ static async deleteBooking(bookingId) {
2183
+ try {
2184
+ const response = await fetch(`/api/showmasterpiece/bookings/admin/${bookingId}`, {
2185
+ method: "DELETE",
2186
+ headers: {
2187
+ "Content-Type": "application/json"
2188
+ }
2189
+ });
2190
+ if (!response.ok) {
2191
+ const errorData = await response.json().catch(() => ({}));
2192
+ throw new Error(errorData.message || "\u5220\u9664\u9884\u8BA2\u5931\u8D25");
2193
+ }
2194
+ console.log("\u2705 \u9884\u8BA2\u5220\u9664\u6210\u529F:", { bookingId });
2195
+ } catch (error) {
2196
+ console.error("\u5220\u9664\u9884\u8BA2\u5931\u8D25:", error);
2197
+ throw error;
2198
+ }
2199
+ }
2200
+ /**
2201
+ * 导出预订数据
2202
+ */
2203
+ static async exportBookings(format = "csv") {
2204
+ try {
2205
+ const response = await fetch(`/api/showmasterpiece/bookings/admin/export?format=${format}`);
2206
+ if (!response.ok) {
2207
+ throw new Error("\u5BFC\u51FA\u9884\u8BA2\u6570\u636E\u5931\u8D25");
2208
+ }
2209
+ return await response.blob();
2210
+ } catch (error) {
2211
+ console.error("\u5BFC\u51FA\u9884\u8BA2\u6570\u636E\u5931\u8D25:", error);
2212
+ throw error;
2213
+ }
2214
+ }
2215
+ };
2216
+ getAllBookings = BookingAdminService.getAllBookings;
2217
+ getBookingStats = BookingAdminService.getBookingStats;
2218
+ forceRefreshAllBookings = BookingAdminService.forceRefreshAllBookings;
2219
+ forceRefreshBookingStats = BookingAdminService.forceRefreshBookingStats;
2220
+ updateBookingStatus2 = BookingAdminService.updateBookingStatus;
2221
+ deleteBooking2 = BookingAdminService.deleteBooking;
2222
+ exportBookings = BookingAdminService.exportBookings;
2223
+ }
2224
+ });
2225
+ var useBookingAdmin;
2226
+ var init_useBookingAdmin = __esm({
2227
+ "src/showmasterpiece/logic/hooks/useBookingAdmin.ts"() {
2228
+ init_bookingAdminService();
2229
+ useBookingAdmin = () => {
2230
+ const [bookings, setBookings] = useState([]);
2231
+ const [stats, setStats] = useState({
2232
+ totalBookings: 0,
2233
+ pendingBookings: 0,
2234
+ confirmedBookings: 0,
2235
+ completedBookings: 0,
2236
+ cancelledBookings: 0,
2237
+ totalQuantity: 0,
2238
+ totalRevenue: 0,
2239
+ totalAmount: 0,
2240
+ todayBookings: 0,
2241
+ weekBookings: 0
2242
+ });
2243
+ const [loading, setLoading] = useState(true);
2244
+ const [error, setError] = useState(void 0);
2245
+ const [searchParams, setSearchParams] = useState({});
2246
+ const fetchBookings = useCallback(async (params) => {
2247
+ try {
2248
+ setLoading(true);
2249
+ setError(void 0);
2250
+ const queryParams = params || searchParams;
2251
+ console.log("\u{1F504} \u5F00\u59CB\u83B7\u53D6\u9884\u8BA2\u6570\u636E...", {
2252
+ searchParams: queryParams
2253
+ });
2254
+ const [bookingsData, statsData] = await Promise.all([
2255
+ getAllBookings(queryParams),
2256
+ getBookingStats(queryParams)
2257
+ ]);
2258
+ console.log("\u2705 \u83B7\u53D6\u5230\u9884\u8BA2\u6570\u636E:", {
2259
+ bookingsCount: bookingsData.length,
2260
+ stats: statsData,
2261
+ searchParams: queryParams,
2262
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2263
+ });
2264
+ setBookings(bookingsData);
2265
+ setStats(statsData);
2266
+ } catch (err) {
2267
+ const errorMessage = err instanceof Error ? err.message : "\u83B7\u53D6\u9884\u8BA2\u6570\u636E\u5931\u8D25";
2268
+ setError(errorMessage);
2269
+ console.error("\u274C \u83B7\u53D6\u9884\u8BA2\u6570\u636E\u5931\u8D25:", err);
2270
+ } finally {
2271
+ setLoading(false);
2272
+ }
2273
+ }, [searchParams]);
2274
+ const searchBookings = useCallback(async (params) => {
2275
+ setSearchParams(params);
2276
+ await fetchBookings(params);
2277
+ }, [fetchBookings]);
2278
+ const clearSearch = useCallback(async () => {
2279
+ const emptyParams = {};
2280
+ setSearchParams(emptyParams);
2281
+ await fetchBookings(emptyParams);
2282
+ }, [fetchBookings]);
2283
+ const updateBookingStatus3 = useCallback(async (id, status, adminNotes) => {
2284
+ try {
2285
+ setError(void 0);
2286
+ console.log("\u5F00\u59CB\u66F4\u65B0\u9884\u8BA2\u72B6\u6001:", { id, status, adminNotes });
2287
+ await updateBookingStatus2(id, status, adminNotes);
2288
+ console.log("\u9884\u8BA2\u72B6\u6001\u66F4\u65B0\u6210\u529F");
2289
+ await fetchBookings();
2290
+ } catch (err) {
2291
+ const errorMessage = err instanceof Error ? err.message : "\u66F4\u65B0\u9884\u8BA2\u72B6\u6001\u5931\u8D25";
2292
+ setError(errorMessage);
2293
+ console.error("\u66F4\u65B0\u9884\u8BA2\u72B6\u6001\u5931\u8D25:", err);
2294
+ throw err;
2295
+ }
2296
+ }, [fetchBookings]);
2297
+ const deleteBooking3 = useCallback(async (id) => {
2298
+ try {
2299
+ setError(void 0);
2300
+ console.log("\u5F00\u59CB\u5220\u9664\u9884\u8BA2:", { id });
2301
+ await deleteBooking2(id);
2302
+ console.log("\u9884\u8BA2\u5220\u9664\u6210\u529F");
2303
+ await fetchBookings();
2304
+ } catch (err) {
2305
+ const errorMessage = err instanceof Error ? err.message : "\u5220\u9664\u9884\u8BA2\u5931\u8D25";
2306
+ setError(errorMessage);
2307
+ console.error("\u5220\u9664\u9884\u8BA2\u5931\u8D25:", err);
2308
+ throw err;
2309
+ }
2310
+ }, [fetchBookings]);
2311
+ const exportBookings2 = useCallback(async (format = "csv") => {
2312
+ try {
2313
+ setError(void 0);
2314
+ console.log("\u5F00\u59CB\u5BFC\u51FA\u9884\u8BA2\u6570\u636E:", { format });
2315
+ const blob = await exportBookings(format);
2316
+ const url = window.URL.createObjectURL(blob);
2317
+ const link = document.createElement("a");
2318
+ link.href = url;
2319
+ link.download = `\u9884\u8BA2\u4FE1\u606F_${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${format}`;
2320
+ document.body.appendChild(link);
2321
+ link.click();
2322
+ document.body.removeChild(link);
2323
+ window.URL.revokeObjectURL(url);
2324
+ console.log("\u9884\u8BA2\u6570\u636E\u5BFC\u51FA\u6210\u529F");
2325
+ } catch (err) {
2326
+ const errorMessage = err instanceof Error ? err.message : "\u5BFC\u51FA\u9884\u8BA2\u6570\u636E\u5931\u8D25";
2327
+ setError(errorMessage);
2328
+ console.error("\u5BFC\u51FA\u9884\u8BA2\u6570\u636E\u5931\u8D25:", err);
2329
+ throw err;
2330
+ }
2331
+ }, []);
2332
+ const refreshData = useCallback(async () => {
2333
+ await fetchBookings();
2334
+ }, [fetchBookings]);
2335
+ const clearError = useCallback(() => {
2336
+ setError(void 0);
2337
+ }, []);
2338
+ useEffect(() => {
2339
+ fetchBookings();
2340
+ }, []);
2341
+ return {
2342
+ bookings,
2343
+ stats,
2344
+ loading,
2345
+ error,
2346
+ searchParams,
2347
+ refreshData,
2348
+ searchBookings,
2349
+ clearSearch,
2350
+ updateBookingStatus: updateBookingStatus3,
2351
+ deleteBooking: deleteBooking3,
2352
+ exportBookings: exportBookings2,
2353
+ clearError
2354
+ };
2355
+ };
2356
+ }
2357
+ });
2358
+ function useDeadlinePopup(businessModule = "showmasterpiece", businessScene = "cart_checkout") {
2359
+ const [state, setState] = useState({
2360
+ configs: [],
2361
+ loading: false,
2362
+ error: null,
2363
+ hasPopup: false
2364
+ });
2365
+ const [dismissedPopups, setDismissedPopups] = useState(/* @__PURE__ */ new Set());
2366
+ const checkPopups = useCallback(async (currentTime) => {
2367
+ setState((prev) => ({ ...prev, loading: true, error: null }));
2368
+ try {
2369
+ const response = await fetch("/api/showmasterpiece/popup-configs/check", {
2370
+ method: "POST",
2371
+ headers: {
2372
+ "Content-Type": "application/json"
2373
+ },
2374
+ body: JSON.stringify({
2375
+ businessModule,
2376
+ businessScene,
2377
+ currentTime: (currentTime || /* @__PURE__ */ new Date()).toISOString()
2378
+ })
2379
+ });
2380
+ if (!response.ok) {
2381
+ throw new Error("\u68C0\u67E5\u5F39\u7A97\u914D\u7F6E\u5931\u8D25");
2382
+ }
2383
+ const result = await response.json();
2384
+ const configs = result.configs || [];
2385
+ const activeConfigs = configs.filter((config) => !dismissedPopups.has(config.id));
2386
+ setState((prev) => ({
2387
+ ...prev,
2388
+ configs: activeConfigs,
2389
+ loading: false,
2390
+ hasPopup: activeConfigs.length > 0
2391
+ }));
2392
+ console.log(`\u{1F514} [useDeadlinePopup] \u68C0\u67E5\u5230 ${activeConfigs.length} \u4E2A\u9700\u8981\u663E\u793A\u7684\u5F39\u7A97`);
2393
+ return activeConfigs;
2394
+ } catch (error) {
2395
+ console.error("\u274C [useDeadlinePopup] \u68C0\u67E5\u5F39\u7A97\u5931\u8D25:", error);
2396
+ setState((prev) => ({
2397
+ ...prev,
2398
+ loading: false,
2399
+ error: error instanceof Error ? error.message : "\u68C0\u67E5\u5F39\u7A97\u5931\u8D25",
2400
+ configs: [],
2401
+ hasPopup: false
2402
+ }));
2403
+ return [];
2404
+ }
2405
+ }, [businessModule, businessScene, dismissedPopups]);
2406
+ const closePopup = useCallback((configId) => {
2407
+ setDismissedPopups((prev) => /* @__PURE__ */ new Set([...prev, configId]));
2408
+ setState((prev) => {
2409
+ const remainingConfigs = prev.configs.filter((config) => config.id !== configId);
2410
+ return {
2411
+ ...prev,
2412
+ configs: remainingConfigs,
2413
+ hasPopup: remainingConfigs.length > 0
2414
+ };
2415
+ });
2416
+ console.log(`\u2705 [useDeadlinePopup] \u5F39\u7A97\u5DF2\u5173\u95ED:`, configId);
2417
+ }, []);
2418
+ const confirmPopup = useCallback((configId) => {
2419
+ console.log(`\u2705 [useDeadlinePopup] \u5F39\u7A97\u5DF2\u786E\u8BA4:`, configId);
2420
+ closePopup(configId);
2421
+ }, [closePopup]);
2422
+ const cancelPopup = useCallback((configId) => {
2423
+ console.log(`\u274C [useDeadlinePopup] \u5F39\u7A97\u5DF2\u53D6\u6D88:`, configId);
2424
+ closePopup(configId);
2425
+ }, [closePopup]);
2426
+ const temporaryClosePopup = useCallback((configId) => {
2427
+ setState((prev) => {
2428
+ const remainingConfigs = prev.configs.filter((config) => config.id !== configId);
2429
+ return {
2430
+ ...prev,
2431
+ configs: remainingConfigs,
2432
+ hasPopup: remainingConfigs.length > 0
2433
+ };
2434
+ });
2435
+ console.log(`\u23F8\uFE0F [useDeadlinePopup] \u5F39\u7A97\u4E34\u65F6\u5173\u95ED:`, configId);
2436
+ }, []);
2437
+ const resetDismissedPopups = useCallback(() => {
2438
+ setDismissedPopups(/* @__PURE__ */ new Set());
2439
+ console.log("\u{1F504} [useDeadlinePopup] \u5DF2\u91CD\u7F6E\u5F39\u7A97\u5173\u95ED\u8BB0\u5F55");
2440
+ }, []);
2441
+ const triggerCheck = useCallback(async (currentTime) => {
2442
+ setState((prev) => ({ ...prev, loading: true, error: null }));
2443
+ try {
2444
+ const response = await fetch("/api/showmasterpiece/popup-configs/check", {
2445
+ method: "POST",
2446
+ headers: {
2447
+ "Content-Type": "application/json"
2448
+ },
2449
+ body: JSON.stringify({
2450
+ businessModule,
2451
+ businessScene,
2452
+ currentTime: (currentTime || /* @__PURE__ */ new Date()).toISOString()
2453
+ })
2454
+ });
2455
+ if (!response.ok) {
2456
+ throw new Error("\u68C0\u67E5\u5F39\u7A97\u914D\u7F6E\u5931\u8D25");
2457
+ }
2458
+ const result = await response.json();
2459
+ const configs = result.configs || [];
2460
+ const activeConfigs = configs.filter((config) => {
2461
+ if (config.blockProcess) {
2462
+ return true;
2463
+ } else {
2464
+ return !dismissedPopups.has(config.id);
2465
+ }
2466
+ });
2467
+ setState((prev) => ({
2468
+ ...prev,
2469
+ configs: activeConfigs,
2470
+ loading: false,
2471
+ hasPopup: activeConfigs.length > 0
2472
+ }));
2473
+ console.log(`\u{1F514} [useDeadlinePopup] \u624B\u52A8\u68C0\u67E5\u5230 ${activeConfigs.length} \u4E2A\u9700\u8981\u663E\u793A\u7684\u5F39\u7A97\uFF08\u963B\u65AD\u5F39\u7A97\u4E0D\u53D7dismissedPopups\u9650\u5236\uFF09`);
2474
+ return activeConfigs;
2475
+ } catch (error) {
2476
+ console.error("\u274C [useDeadlinePopup] \u624B\u52A8\u68C0\u67E5\u5F39\u7A97\u5931\u8D25:", error);
2477
+ setState((prev) => ({
2478
+ ...prev,
2479
+ loading: false,
2480
+ error: error instanceof Error ? error.message : "\u68C0\u67E5\u5F39\u7A97\u5931\u8D25",
2481
+ configs: [],
2482
+ hasPopup: false
2483
+ }));
2484
+ return [];
2485
+ }
2486
+ }, [businessModule, businessScene, dismissedPopups]);
2487
+ return {
2488
+ ...state,
2489
+ checkPopups,
2490
+ closePopup,
2491
+ confirmPopup,
2492
+ cancelPopup,
2493
+ temporaryClosePopup,
2494
+ resetDismissedPopups,
2495
+ triggerCheck
2496
+ };
2497
+ }
2498
+ var init_useDeadlinePopup = __esm({
2499
+ "src/showmasterpiece/logic/hooks/useDeadlinePopup.ts"() {
2500
+ "use client";
2501
+ }
2502
+ });
2503
+ var useCartContext;
2504
+ var init_useCartContext = __esm({
2505
+ "src/showmasterpiece/logic/hooks/useCartContext.ts"() {
2506
+ "use client";
2507
+ useCartContext = () => {
2508
+ let CartContext2;
2509
+ try {
2510
+ const contextModule = (init_CartContext(), __toCommonJS(CartContext_exports));
2511
+ CartContext2 = contextModule.CartContext;
2512
+ } catch (error) {
2513
+ throw new Error("Failed to load CartContext. Make sure CartProvider is properly set up.");
2514
+ }
2515
+ const context = useContext(CartContext2);
2516
+ if (context === void 0) {
2517
+ throw new Error("useCartContext must be used within a CartProvider");
2518
+ }
2519
+ return context;
2520
+ };
2521
+ }
2522
+ });
2523
+
2524
+ // src/showmasterpiece/logic/hooks/index.ts
2525
+ var init_hooks = __esm({
2526
+ "src/showmasterpiece/logic/hooks/index.ts"() {
2527
+ init_useMasterpieces();
2528
+ init_useMasterpiecesConfig();
2529
+ init_useCart();
2530
+ init_useBooking();
2531
+ init_useBookingAdmin();
2532
+ init_useDeadlinePopup();
2533
+ init_useCartContext();
2534
+ init_useDeadlinePopup();
2535
+ }
2536
+ });
2537
+
2538
+ // src/showmasterpiece/logic/contexts/CartContext.tsx
2539
+ var CartContext_exports = {};
2540
+ __export(CartContext_exports, {
2541
+ CartContext: () => CartContext,
2542
+ CartProvider: () => CartProvider
2543
+ });
2544
+ var CartContext, CartProvider;
2545
+ var init_CartContext = __esm({
2546
+ "src/showmasterpiece/logic/contexts/CartContext.tsx"() {
2547
+ "use client";
2548
+ init_cartService();
2549
+ init_hooks();
2550
+ CartContext = createContext(void 0);
2551
+ CartProvider = ({ children, userId }) => {
2552
+ const [state, setState] = useState({
2553
+ cart: {
2554
+ items: [],
2555
+ totalQuantity: 0,
2556
+ totalPrice: 0
2557
+ },
2558
+ loading: false,
2559
+ error: void 0,
2560
+ refreshCart: async () => {
2561
+ },
2562
+ addToCart: async () => {
2563
+ },
2564
+ updateCartItem: async () => {
2565
+ },
2566
+ removeFromCart: async () => {
2567
+ },
2568
+ batchBooking: async () => ({ successCount: 0, failCount: 0, bookingIds: [], failures: [] }),
2569
+ clearCart: async () => {
2570
+ }
2571
+ });
2572
+ const refreshCart = useCallback(async () => {
2573
+ if (!userId) return;
2574
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
2575
+ try {
2576
+ const cartData = await getCart(userId);
2577
+ setState((prev) => ({
2578
+ ...prev,
2579
+ cart: cartData,
2580
+ loading: false
2581
+ }));
2582
+ } catch (error) {
2583
+ console.error("\u5237\u65B0\u8D2D\u7269\u8F66\u5931\u8D25:", error);
2584
+ setState((prev) => ({
2585
+ ...prev,
2586
+ loading: false,
2587
+ error: error instanceof Error ? error.message : "\u5237\u65B0\u8D2D\u7269\u8F66\u5931\u8D25"
2588
+ }));
2589
+ }
2590
+ }, [userId]);
2591
+ const addToCartWithEvent = useCallback(async (request) => {
2592
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
2593
+ try {
2594
+ console.log("\u{1F6D2} [CartContext] \u6DFB\u52A0\u5230\u8D2D\u7269\u8F66:", { request, userId });
2595
+ await addToCart({ ...request, userId });
2596
+ await refreshCart();
2597
+ setState((prev) => ({ ...prev, loading: false }));
2598
+ } catch (error) {
2599
+ console.error("\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u5931\u8D25:", error);
2600
+ setState((prev) => ({
2601
+ ...prev,
2602
+ loading: false,
2603
+ error: error instanceof Error ? error.message : "\u6DFB\u52A0\u5230\u8D2D\u7269\u8F66\u5931\u8D25"
2604
+ }));
2605
+ }
2606
+ }, [refreshCart, userId]);
2607
+ const updateCartItemWithEvent = useCallback(async (request) => {
2608
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
2609
+ try {
2610
+ console.log("\u{1F522} [CartContext] \u66F4\u65B0\u8D2D\u7269\u8F66\u6570\u91CF:", { request, userId });
2611
+ await updateCartItem({ ...request, userId });
2612
+ await refreshCart();
2613
+ setState((prev) => ({ ...prev, loading: false }));
2614
+ } catch (error) {
2615
+ console.error("\u66F4\u65B0\u8D2D\u7269\u8F66\u6570\u91CF\u5931\u8D25:", error);
2616
+ setState((prev) => ({
2617
+ ...prev,
2618
+ loading: false,
2619
+ error: error instanceof Error ? error.message : "\u66F4\u65B0\u8D2D\u7269\u8F66\u6570\u91CF\u5931\u8D25"
2620
+ }));
2621
+ }
2622
+ }, [refreshCart, userId]);
2623
+ const removeFromCartWithEvent = useCallback(async (request) => {
2624
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
2625
+ try {
2626
+ console.log("\u{1F5D1}\uFE0F [CartContext] \u79FB\u9664\u5546\u54C1:", { request, userId });
2627
+ await removeFromCart({ ...request, userId });
2628
+ await refreshCart();
2629
+ setState((prev) => ({ ...prev, loading: false }));
2630
+ } catch (error) {
2631
+ console.error("\u79FB\u9664\u5546\u54C1\u5931\u8D25:", error);
2632
+ setState((prev) => ({
2633
+ ...prev,
2634
+ loading: false,
2635
+ error: error instanceof Error ? error.message : "\u79FB\u9664\u5546\u54C1\u5931\u8D25"
2636
+ }));
2637
+ }
2638
+ }, [refreshCart, userId]);
2639
+ const batchBookingWithEvent = useCallback(async (request) => {
2640
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
2641
+ try {
2642
+ console.log("\u{1F4CB} [CartContext] \u6279\u91CF\u9884\u8BA2:", { request, userId });
2643
+ const result = await batchBooking(request, state.cart);
2644
+ await refreshCart();
2645
+ setState((prev) => ({ ...prev, loading: false }));
2646
+ return result;
2647
+ } catch (error) {
2648
+ console.error("\u6279\u91CF\u9884\u8BA2\u5931\u8D25:", error);
2649
+ setState((prev) => ({
2650
+ ...prev,
2651
+ loading: false,
2652
+ error: error instanceof Error ? error.message : "\u6279\u91CF\u9884\u8BA2\u5931\u8D25"
2653
+ }));
2654
+ throw error;
2655
+ }
2656
+ }, [refreshCart, userId, state.cart]);
2657
+ const clearCartWithEvent = useCallback(async () => {
2658
+ setState((prev) => ({ ...prev, loading: true, error: void 0 }));
2659
+ try {
2660
+ console.log("\u{1F5D1}\uFE0F [CartContext] \u6E05\u7A7A\u8D2D\u7269\u8F66:", { userId });
2661
+ await clearCart(userId);
2662
+ await refreshCart();
2663
+ setState((prev) => ({ ...prev, loading: false }));
2664
+ } catch (error) {
2665
+ console.error("\u6E05\u7A7A\u8D2D\u7269\u8F66\u5931\u8D25:", error);
2666
+ setState((prev) => ({
2667
+ ...prev,
2668
+ loading: false,
2669
+ error: error instanceof Error ? error.message : "\u6E05\u7A7A\u8D2D\u7269\u8F66\u5931\u8D25"
2670
+ }));
2671
+ }
2672
+ }, [refreshCart, userId]);
2673
+ useEffect(() => {
2674
+ refreshCart();
2675
+ }, [refreshCart]);
2676
+ useEffect(() => {
2677
+ const handleCartUpdate = () => {
2678
+ refreshCart();
2679
+ };
2680
+ cartUpdateEvents.addEventListener(CART_UPDATE_EVENT, handleCartUpdate);
2681
+ return () => {
2682
+ cartUpdateEvents.removeEventListener(CART_UPDATE_EVENT, handleCartUpdate);
2683
+ };
2684
+ }, [refreshCart]);
2685
+ const contextValue = {
2686
+ ...state,
2687
+ refreshCart,
2688
+ addToCart: addToCartWithEvent,
2689
+ updateCartItem: updateCartItemWithEvent,
2690
+ removeFromCart: removeFromCartWithEvent,
2691
+ batchBooking: batchBookingWithEvent,
2692
+ clearCart: clearCartWithEvent
2693
+ };
2694
+ return /* @__PURE__ */ React.createElement(CartContext.Provider, { value: contextValue }, children);
2695
+ };
2696
+ }
2697
+ });
2698
+
2699
+ export { BookingAdminService, BookingService, CART_UPDATE_EVENT, CartHistoryService, CartProvider, CartService, MasterpiecesService, addArtworkToCollection, addToCart, batchBooking, cartUpdateEvents, clearCart, clearUserHistory, createBooking, createCategory, createCollection, deleteArtwork, deleteBooking, deleteBooking2, deleteCollection, deleteHistoryRecord, exportBookings, forceRefreshAllBookings, forceRefreshBookingStats, getAllBookings, getAllCollections, getAllHistory, getArtworksByCollection, getBookableCollections, getBooking, getBookingStats, getBookings, getCart, getCartHistory, getCategories, getCollectionsOverview, getConfig, getMasterpieces, getStatistics, getTags, init_CartContext, init_bookingAdminService, init_bookingService, init_cartHistoryService, init_cartService, init_hooks, init_masterpiecesConfigService, init_masterpiecesService, moveArtwork, moveArtworkDown, moveArtworkUp, moveCollection, moveCollectionDown, moveCollectionUp, notifyCartUpdate, removeFromCart, resetConfig, saveCartHistory, updateArtwork, updateArtworkOrder, updateBooking, updateBookingStatus, updateBookingStatus2, updateCartItem, updateCollection, updateCollectionOrder, updateConfig, useBooking, useBookingAdmin, useBookingForm, useCart, useCartContext, useDeadlinePopup, useMasterpieces, useMasterpiecesConfig };
2700
+ //# sourceMappingURL=chunk-WS3QZYBI.mjs.map
2701
+ //# sourceMappingURL=chunk-WS3QZYBI.mjs.map