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