pcm-agents 0.3.0 → 0.3.2

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 (146) hide show
  1. package/LICENSE +21 -21
  2. package/dist/cjs/index-BFPEnLbS.js +195 -0
  3. package/dist/cjs/index-BFPEnLbS.js.map +1 -0
  4. package/dist/cjs/index.cjs.js +1 -1
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/my-component.cjs.entry.js +2 -2
  7. package/dist/cjs/my-component.cjs.entry.js.map +1 -1
  8. package/dist/cjs/my-component.entry.cjs.js.map +1 -1
  9. package/dist/cjs/pcm-agents.cjs.js +1 -1
  10. package/dist/cjs/pcm-app-chat-modal.pcm-chat-message.pcm-hr-chat-modal.pcm-jlpx-modal.pcm-mnms-modal.pcm-video-chat-modal.pcm-zygh-modal.entry.cjs.js.map +1 -0
  11. package/dist/cjs/pcm-app-chat-modal_7.cjs.entry.js +6560 -0
  12. package/dist/cjs/pcm-app-chat-modal_7.cjs.entry.js.map +1 -0
  13. package/dist/cjs/pcm-chat-modal.cjs.entry.js +17 -32
  14. package/dist/cjs/pcm-chat-modal.cjs.entry.js.map +1 -1
  15. package/dist/cjs/pcm-chat-modal.entry.cjs.js.map +1 -1
  16. package/dist/collection/collection-manifest.json +2 -0
  17. package/dist/collection/components/my-component/my-component.css +3 -3
  18. package/dist/collection/components/my-component/my-component.js +1 -1
  19. package/dist/collection/components/my-component/my-component.js.map +1 -1
  20. package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.css +2 -1
  21. package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.js +137 -159
  22. package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.js.map +1 -1
  23. package/dist/collection/components/pcm-chat-message/pcm-chat-message.css +66 -12
  24. package/dist/collection/components/pcm-chat-message/pcm-chat-message.js +106 -13
  25. package/dist/collection/components/pcm-chat-message/pcm-chat-message.js.map +1 -1
  26. package/dist/collection/components/pcm-chat-modal/pcm-chat-modal.js +39 -34
  27. package/dist/collection/components/pcm-chat-modal/pcm-chat-modal.js.map +1 -1
  28. package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.js +76 -105
  29. package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.js.map +1 -1
  30. package/dist/collection/components/pcm-jlpx-modal/pcm-jlpx-modal.css +162 -0
  31. package/dist/collection/components/pcm-jlpx-modal/pcm-jlpx-modal.js +616 -0
  32. package/dist/collection/components/pcm-jlpx-modal/pcm-jlpx-modal.js.map +1 -0
  33. package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.css +0 -79
  34. package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.js +133 -81
  35. package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.js.map +1 -1
  36. package/dist/collection/components/pcm-video-chat-modal/pcm-video-chat-modal.js +77 -101
  37. package/dist/collection/components/pcm-video-chat-modal/pcm-video-chat-modal.js.map +1 -1
  38. package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.css +273 -0
  39. package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.js +613 -0
  40. package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.js.map +1 -0
  41. package/dist/collection/global/global.css +324 -0
  42. package/dist/collection/index.js.map +1 -1
  43. package/dist/collection/interfaces/chat.js.map +1 -1
  44. package/dist/collection/utils/utils.js +54 -113
  45. package/dist/collection/utils/utils.js.map +1 -1
  46. package/dist/components/index.js +1298 -11280
  47. package/dist/components/index.js.map +1 -1
  48. package/dist/components/my-component.js +2 -3
  49. package/dist/components/my-component.js.map +1 -1
  50. package/dist/components/{p-C4l_DOnx.js → p-BctfuDvG.js} +106 -147
  51. package/dist/components/p-BctfuDvG.js.map +1 -0
  52. package/dist/components/{p-D0s1Q-3O.js → p-LkDC0SN2.js} +343 -16
  53. package/dist/components/p-LkDC0SN2.js.map +1 -0
  54. package/dist/components/pcm-app-chat-modal.js +1 -1
  55. package/dist/components/pcm-chat-message.js +1 -1
  56. package/dist/components/pcm-chat-modal.js +19 -34
  57. package/dist/components/pcm-chat-modal.js.map +1 -1
  58. package/dist/components/pcm-hr-chat-modal.js +70 -100
  59. package/dist/components/pcm-hr-chat-modal.js.map +1 -1
  60. package/dist/components/pcm-jlpx-modal.d.ts +11 -0
  61. package/dist/components/pcm-jlpx-modal.js +339 -0
  62. package/dist/components/pcm-jlpx-modal.js.map +1 -0
  63. package/dist/components/pcm-mnms-modal.js +109 -57
  64. package/dist/components/pcm-mnms-modal.js.map +1 -1
  65. package/dist/components/pcm-video-chat-modal.js +74 -99
  66. package/dist/components/pcm-video-chat-modal.js.map +1 -1
  67. package/dist/components/pcm-zygh-modal.d.ts +11 -0
  68. package/dist/components/pcm-zygh-modal.js +330 -0
  69. package/dist/components/pcm-zygh-modal.js.map +1 -0
  70. package/dist/esm/index-nVjZGfA8.js +189 -0
  71. package/dist/esm/index-nVjZGfA8.js.map +1 -0
  72. package/dist/esm/index.js +1 -1
  73. package/dist/esm/loader.js +1 -1
  74. package/dist/esm/my-component.entry.js +2 -2
  75. package/dist/esm/my-component.entry.js.map +1 -1
  76. package/dist/esm/pcm-agents.js +1 -1
  77. package/dist/esm/pcm-app-chat-modal.pcm-chat-message.pcm-hr-chat-modal.pcm-jlpx-modal.pcm-mnms-modal.pcm-video-chat-modal.pcm-zygh-modal.entry.js.map +1 -0
  78. package/dist/esm/pcm-app-chat-modal_7.entry.js +6552 -0
  79. package/dist/esm/pcm-app-chat-modal_7.entry.js.map +1 -0
  80. package/dist/esm/pcm-chat-modal.entry.js +17 -32
  81. package/dist/esm/pcm-chat-modal.entry.js.map +1 -1
  82. package/dist/pcm-agents/index.esm.js +1 -1
  83. package/dist/pcm-agents/my-component.entry.esm.js.map +1 -1
  84. package/dist/pcm-agents/p-55417392.entry.js +2 -0
  85. package/dist/pcm-agents/p-55417392.entry.js.map +1 -0
  86. package/dist/pcm-agents/p-a698b59f.entry.js +2 -0
  87. package/dist/pcm-agents/p-a698b59f.entry.js.map +1 -0
  88. package/dist/pcm-agents/p-f3ca99b4.entry.js +2 -0
  89. package/dist/pcm-agents/p-f3ca99b4.entry.js.map +1 -0
  90. package/dist/pcm-agents/p-nVjZGfA8.js +2 -0
  91. package/dist/pcm-agents/p-nVjZGfA8.js.map +1 -0
  92. package/dist/pcm-agents/pcm-agents.esm.js +1 -1
  93. package/dist/pcm-agents/pcm-app-chat-modal.pcm-chat-message.pcm-hr-chat-modal.pcm-jlpx-modal.pcm-mnms-modal.pcm-video-chat-modal.pcm-zygh-modal.entry.esm.js.map +1 -0
  94. package/dist/pcm-agents/pcm-chat-modal.entry.esm.js.map +1 -1
  95. package/dist/types/components/pcm-app-chat-modal/pcm-app-chat-modal.d.ts +13 -8
  96. package/dist/types/components/pcm-chat-message/pcm-chat-message.d.ts +5 -0
  97. package/dist/types/components/pcm-chat-modal/pcm-chat-modal.d.ts +8 -8
  98. package/dist/types/components/pcm-hr-chat-modal/pcm-hr-chat-modal.d.ts +6 -12
  99. package/dist/types/components/pcm-jlpx-modal/pcm-jlpx-modal.d.ts +113 -0
  100. package/dist/types/components/pcm-mnms-modal/pcm-mnms-modal.d.ts +19 -20
  101. package/dist/types/components/pcm-video-chat-modal/pcm-video-chat-modal.d.ts +4 -4
  102. package/dist/types/components/pcm-zygh-modal/pcm-zygh-modal.d.ts +117 -0
  103. package/dist/types/components.d.ts +429 -80
  104. package/dist/types/interfaces/chat.d.ts +0 -4
  105. package/dist/types/utils/utils.d.ts +29 -83
  106. package/package.json +61 -60
  107. package/readme.md +307 -307
  108. package/dist/cjs/index-DfIUl99H.js +0 -11413
  109. package/dist/cjs/index-DfIUl99H.js.map +0 -1
  110. package/dist/cjs/pcm-app-chat-modal.pcm-chat-message.pcm-mnms-modal.entry.cjs.js.map +0 -1
  111. package/dist/cjs/pcm-app-chat-modal_3.cjs.entry.js +0 -3734
  112. package/dist/cjs/pcm-app-chat-modal_3.cjs.entry.js.map +0 -1
  113. package/dist/cjs/pcm-hr-chat-modal.cjs.entry.js +0 -1078
  114. package/dist/cjs/pcm-hr-chat-modal.cjs.entry.js.map +0 -1
  115. package/dist/cjs/pcm-hr-chat-modal.entry.cjs.js.map +0 -1
  116. package/dist/cjs/pcm-video-chat-modal.cjs.entry.js +0 -927
  117. package/dist/cjs/pcm-video-chat-modal.cjs.entry.js.map +0 -1
  118. package/dist/cjs/pcm-video-chat-modal.entry.cjs.js.map +0 -1
  119. package/dist/components/p-C4l_DOnx.js.map +0 -1
  120. package/dist/components/p-CgDy4pJp.js +0 -1244
  121. package/dist/components/p-CgDy4pJp.js.map +0 -1
  122. package/dist/components/p-D0s1Q-3O.js.map +0 -1
  123. package/dist/esm/index-B2EtEi7v.js +0 -11409
  124. package/dist/esm/index-B2EtEi7v.js.map +0 -1
  125. package/dist/esm/pcm-app-chat-modal.pcm-chat-message.pcm-mnms-modal.entry.js.map +0 -1
  126. package/dist/esm/pcm-app-chat-modal_3.entry.js +0 -3730
  127. package/dist/esm/pcm-app-chat-modal_3.entry.js.map +0 -1
  128. package/dist/esm/pcm-hr-chat-modal.entry.js +0 -1076
  129. package/dist/esm/pcm-hr-chat-modal.entry.js.map +0 -1
  130. package/dist/esm/pcm-video-chat-modal.entry.js +0 -925
  131. package/dist/esm/pcm-video-chat-modal.entry.js.map +0 -1
  132. package/dist/pcm-agents/p-0ddd5c47.entry.js +0 -2
  133. package/dist/pcm-agents/p-0ddd5c47.entry.js.map +0 -1
  134. package/dist/pcm-agents/p-5f624943.entry.js +0 -2
  135. package/dist/pcm-agents/p-5f624943.entry.js.map +0 -1
  136. package/dist/pcm-agents/p-6c07f155.entry.js +0 -2
  137. package/dist/pcm-agents/p-6c07f155.entry.js.map +0 -1
  138. package/dist/pcm-agents/p-9a1fb6ca.entry.js +0 -2
  139. package/dist/pcm-agents/p-9a1fb6ca.entry.js.map +0 -1
  140. package/dist/pcm-agents/p-B2EtEi7v.js +0 -146
  141. package/dist/pcm-agents/p-B2EtEi7v.js.map +0 -1
  142. package/dist/pcm-agents/p-e21bc169.entry.js +0 -2
  143. package/dist/pcm-agents/p-e21bc169.entry.js.map +0 -1
  144. package/dist/pcm-agents/pcm-app-chat-modal.pcm-chat-message.pcm-mnms-modal.entry.esm.js.map +0 -1
  145. package/dist/pcm-agents/pcm-hr-chat-modal.entry.esm.js.map +0 -1
  146. package/dist/pcm-agents/pcm-video-chat-modal.entry.esm.js.map +0 -1
@@ -0,0 +1,324 @@
1
+ /* 模态框基础样式 */
2
+ .modal-overlay {
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ right: 0;
7
+ bottom: 0;
8
+ background-color: rgba(0, 0, 0, 0.5);
9
+ display: flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ z-index: 1000;
13
+ overflow-y: auto;
14
+ padding: 20px;
15
+ }
16
+
17
+ /* 全屏模式下取消 padding */
18
+ .fullscreen-overlay {
19
+ padding: 0;
20
+ background-color: rgba(0, 0, 0, 0.7);
21
+ }
22
+
23
+ .modal-container {
24
+ background-color: #fff;
25
+ border-radius: 8px;
26
+ width: 100%;
27
+ display: flex;
28
+ flex-direction: column;
29
+ position: relative;
30
+ margin: auto;
31
+ transition: all 0.3s ease-out;
32
+ overflow: hidden;
33
+ }
34
+
35
+ /* 全屏模式样式 */
36
+ .modal-container.fullscreen {
37
+ width: 100vw;
38
+ max-width: none;
39
+ height: 100%;
40
+ border-radius: 0;
41
+ margin: 0;
42
+ display: flex;
43
+ flex-direction: column;
44
+ height: 100vh;
45
+ max-height: 100vh;
46
+ }
47
+
48
+ /* PC端布局 */
49
+ .pc-layout {
50
+ width: 80%;
51
+ max-width: 500px;
52
+ min-width: 320px;
53
+ }
54
+
55
+ /* 移动端布局 */
56
+ .mobile-layout {
57
+ width: 100%;
58
+ height: 100%;
59
+ border-radius: 0;
60
+ }
61
+
62
+ /* 响应式布局 */
63
+ @media screen and (max-width: 768px) {
64
+ .pc-layout {
65
+ width: 95%;
66
+ }
67
+
68
+ .modal-overlay {
69
+ padding: 0;
70
+ }
71
+
72
+ .modal-container.fullscreen {
73
+ /* 支持 iOS Safari */
74
+ height: -webkit-fill-available;
75
+ max-height: -webkit-fill-available;
76
+ /* 确保内容不会被顶部状态栏和底部工具栏遮挡 */
77
+ padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
78
+ margin-top: 40px;
79
+ height: calc(100% - 40px);
80
+ max-height: calc(100% - 40px);
81
+ border-radius: 16px 16px 0 0;
82
+ }
83
+
84
+ .modal-container.mobile-layout {
85
+ width: 100%;
86
+ height: 100vh;
87
+ max-height: 100vh;
88
+ min-height: 100vh;
89
+ border-radius: 0;
90
+ margin: 0;
91
+ display: flex;
92
+ flex-direction: column;
93
+ }
94
+ }
95
+
96
+ /* 模态框头部样式 */
97
+ .modal-header {
98
+ display: flex;
99
+ justify-content: space-between;
100
+ align-items: center;
101
+ padding: 4px 16px;
102
+ height: 50px;
103
+ border-bottom: 1px solid #e8e8e8;
104
+ flex-shrink: 0;
105
+ }
106
+
107
+ .header-left {
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 8px;
111
+ }
112
+
113
+ .header-icon {
114
+ width: 24px;
115
+ height: 24px;
116
+ }
117
+
118
+ .close-button {
119
+ background: transparent;
120
+ border: none;
121
+ cursor: pointer;
122
+ padding: 8px;
123
+ display: flex;
124
+ align-items: center;
125
+ justify-content: center;
126
+ width: 32px;
127
+ height: 32px;
128
+ border-radius: 4px;
129
+ }
130
+
131
+ .close-button:hover {
132
+ background-color: rgba(0, 0, 0, 0.04);
133
+ }
134
+
135
+ .close-button span {
136
+ font-size: 24px;
137
+ line-height: 1;
138
+ color: #999;
139
+ }
140
+
141
+ .close-button:hover span {
142
+ color: #666;
143
+ }
144
+
145
+
146
+ /* 文件上传区域通用样式 */
147
+ .upload-area {
148
+ border: 2px dashed #ddd;
149
+ border-radius: 8px;
150
+ cursor: pointer;
151
+ transition: all 0.3s ease;
152
+ margin-bottom: 20px;
153
+ width: 100%;
154
+ }
155
+
156
+ .upload-area:hover {
157
+ border-color: #1890ff;
158
+ background-color: rgba(24, 144, 255, 0.05);
159
+ }
160
+
161
+
162
+ .upload-placeholder {
163
+ display: flex;
164
+ flex-direction: column;
165
+ align-items: center;
166
+ color: #666;
167
+ }
168
+
169
+ .upload-placeholder svg {
170
+ color: #1890ff;
171
+ margin-bottom: 8px;
172
+ }
173
+
174
+ .upload-placeholder p {
175
+ margin: 4px 0;
176
+ }
177
+
178
+ .upload-hint {
179
+ font-size: 0.8rem;
180
+ color: #999;
181
+ margin-top: 0.5rem;
182
+ }
183
+
184
+ .file-info {
185
+ display: flex;
186
+ align-items: center;
187
+ justify-content: space-between;
188
+ padding: 8px;
189
+ background: #f9f9f9;
190
+ border: 1px solid #e8e8e8;
191
+ border-radius: 4px;
192
+ }
193
+
194
+ .file-info span {
195
+ overflow: hidden;
196
+ text-overflow: ellipsis;
197
+ white-space: nowrap;
198
+ max-width: calc(100% - 30px);
199
+ }
200
+
201
+ .remove-file {
202
+ background: transparent;
203
+ border: none;
204
+ color: #999;
205
+ cursor: pointer;
206
+ padding: 4px 8px;
207
+ font-size: 16px;
208
+ line-height: 1;
209
+ border-radius: 4px;
210
+ transition: all 0.2s;
211
+ }
212
+
213
+ .remove-file:hover {
214
+ background-color: #f0f0f0;
215
+ color: #666;
216
+ }
217
+
218
+ .file-input {
219
+ display: none;
220
+ }
221
+
222
+
223
+
224
+ /* 输入容器样式 */
225
+ .input-container {
226
+ padding: 20px;
227
+ display: flex;
228
+ flex-direction: column;
229
+ height: calc(100% - 50px);
230
+ /* 减去header高度 */
231
+ overflow-y: auto;
232
+ }
233
+
234
+ .input-container h3 {
235
+ margin-top: 0;
236
+ margin-bottom: 20px;
237
+ font-size: 18px;
238
+ color: #333;
239
+ text-align: center;
240
+ }
241
+
242
+ /* JD输入区域样式 */
243
+ .jd-input-section {
244
+ margin-bottom: 20px;
245
+ }
246
+
247
+ .jd-input-section label {
248
+ display: block;
249
+ margin-bottom: 8px;
250
+ font-weight: 500;
251
+ color: #333;
252
+ }
253
+
254
+ .job-description-textarea {
255
+ width: 100%;
256
+ border: 1px solid #ddd;
257
+ border-radius: 4px;
258
+ resize: vertical;
259
+ font-family: inherit;
260
+ font-size: 14px;
261
+ line-height: 1.5;
262
+ transition: border-color 0.3s;
263
+ }
264
+
265
+ .job-description-textarea:focus {
266
+ outline: none;
267
+ border-color: #1890ff;
268
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
269
+ }
270
+
271
+ /* 简历上传区域样式 */
272
+ .resume-upload-section {
273
+ margin-bottom: 20px;
274
+ width: 100%;
275
+ display: flex;
276
+ flex-direction: column;
277
+ align-items: center;
278
+ }
279
+
280
+ .resume-upload-section label {
281
+ display: block;
282
+ margin-bottom: 8px;
283
+ font-weight: 500;
284
+ color: #333;
285
+ align-self: flex-start;
286
+ }
287
+
288
+
289
+ /* 提交按钮通用样式 */
290
+ .submit-button {
291
+ margin-top: 10px;
292
+ padding: 10px 30px;
293
+ background: #1890ff;
294
+ color: white;
295
+ border: none;
296
+ border-radius: 4px;
297
+ font-size: 16px;
298
+ cursor: pointer;
299
+ transition: all 0.3s ease;
300
+ width: 100%;
301
+ max-width: 400px;
302
+ align-self: center;
303
+ /* 确保按钮居中 */
304
+ }
305
+
306
+ .submit-button:disabled {
307
+ background: #ccc;
308
+ cursor: not-allowed;
309
+ }
310
+
311
+ .submit-button:hover:not(:disabled) {
312
+ background: #40a9ff;
313
+ }
314
+
315
+ /* 聊天模态框容器 */
316
+ .chat-modal-container {
317
+ position: absolute;
318
+ top: 0;
319
+ left: 0;
320
+ right: 0;
321
+ bottom: 0;
322
+ display: flex;
323
+ flex-direction: column;
324
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC","sourcesContent":["/**\n * @fileoverview entry point for your component library\n *\n * This is the entry point for your component library. Use this file to export utilities,\n * constants or data structure that accompany your components.\n *\n * DO NOT use this file to export your components. Instead, use the recommended approaches\n * to consume components of this package as outlined in the `README.md`.\n */\nexport { format } from './utils/utils';\nexport type * from './components.d.ts';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC","sourcesContent":["/**\r\n * @fileoverview entry point for your component library\r\n *\r\n * This is the entry point for your component library. Use this file to export utilities,\r\n * constants or data structure that accompany your components.\r\n *\r\n * DO NOT use this file to export your components. Instead, use the recommended approaches\r\n * to consume components of this package as outlined in the `README.md`.\r\n */\r\nexport { format } from './utils/utils';\r\nexport type * from './components.d.ts';\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/interfaces/chat.ts"],"names":[],"mappings":"","sourcesContent":["export interface ChatMessage {\r\n /**\r\n * 消息唯一标识\r\n */\r\n id: string;\r\n \r\n /**\r\n * 用户输入的消息内容\r\n */\r\n query?: string;\r\n \r\n /**\r\n * AI助手的回复内容\r\n */\r\n answer?: string;\r\n \r\n /**\r\n * 消息时间,格式为 \"HH:mm\"\r\n */\r\n time: string;\r\n \r\n /**\r\n * 会话ID\r\n */\r\n conversation_id?: string;\r\n \r\n /**\r\n * 是否正在流式输出\r\n */\r\n isStreaming?: boolean;\r\n \r\n /**\r\n * 机器人ID\r\n */\r\n bot_id?: string;\r\n \r\n /**\r\n * 输入参数\r\n */\r\n inputs?: Record<string, any>;\r\n \r\n /**\r\n * 消息状态\r\n */\r\n status?: 'normal' | 'error';\r\n \r\n /**\r\n * 错误信息\r\n */\r\n error?: any;\r\n} "]}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/interfaces/chat.ts"],"names":[],"mappings":"","sourcesContent":["export interface ChatMessage {\r\n /**\r\n * 消息唯一标识\r\n */\r\n id: string;\r\n \r\n /**\r\n * 用户输入的消息内容\r\n */\r\n query?: string;\r\n \r\n /**\r\n * AI助手的回复内容\r\n */\r\n answer?: string;\r\n \r\n /**\r\n * 消息时间,格式为 \"HH:mm\"\r\n */\r\n time: string;\r\n \r\n /**\r\n * 会话ID\r\n */\r\n conversation_id?: string;\r\n \r\n /**\r\n * 是否正在流式输出\r\n */\r\n isStreaming?: boolean;\r\n \r\n /**\r\n * 输入参数\r\n */\r\n inputs?: Record<string, any>;\r\n \r\n /**\r\n * 消息状态\r\n */\r\n status?: 'normal' | 'error';\r\n \r\n /**\r\n * 错误信息\r\n */\r\n error?: any;\r\n} "]}
@@ -1,4 +1,8 @@
1
- import COS from "cos-js-sdk-v5";
1
+ /**
2
+ * API域名配置
3
+ */
4
+ // export const API_DOMAIN = 'http://192.168.17.194:8000';
5
+ export const API_DOMAIN = 'https://pcm_api.ylzhaopin.com';
2
6
  export function format(first, middle, last) {
3
7
  return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');
4
8
  }
@@ -32,7 +36,9 @@ export const convertWorkflowStreamNodeToMessageRound = (message_event, inputMess
32
36
  export const sendSSERequest = async (config) => {
33
37
  const { url, method, headers = {}, data, onMessage, onError, onComplete } = config;
34
38
  try {
35
- const response = await fetch(url, {
39
+ // 使用 API_DOMAIN 拼接完整的请求URL
40
+ const requestUrl = `${API_DOMAIN}${url}`;
41
+ const response = await fetch(requestUrl, {
36
42
  method,
37
43
  headers: {
38
44
  'Accept': 'text/event-stream',
@@ -85,7 +91,7 @@ export const sendSSERequest = async (config) => {
85
91
  * @returns Promise<HttpResponse>
86
92
  */
87
93
  export const sendHttpRequest = async (config) => {
88
- const { url, method = 'GET', headers = {}, params = {}, data, onMessage } = config;
94
+ const { url, method = 'GET', headers = {}, params = {}, data, formData, onMessage } = config;
89
95
  try {
90
96
  // 构建URL和查询参数
91
97
  const queryParams = new URLSearchParams();
@@ -94,17 +100,23 @@ export const sendHttpRequest = async (config) => {
94
100
  queryParams.append(key, String(value));
95
101
  }
96
102
  });
97
- let requestUrl = `${url}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
103
+ // 使用 API_DOMAIN 拼接完整的请求URL
104
+ let requestUrl = `${API_DOMAIN}${url}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
98
105
  // 创建请求配置对象
99
106
  const requestConfig = {
100
107
  method,
101
- headers: {
108
+ headers: formData ? { ...headers } : {
102
109
  'Content-Type': 'application/json',
103
110
  ...headers
104
111
  }
105
112
  };
106
- // 只有在非 GET/HEAD 请求时才添加 body
107
- if (method !== 'GET' && method !== 'HEAD' && data) {
113
+ // 处理请求体
114
+ if (formData) {
115
+ // 如果提供了FormData,直接使用
116
+ requestConfig.body = formData;
117
+ }
118
+ else if (method !== 'GET' && method !== 'HEAD' && data) {
119
+ // 否则,如果是非GET/HEAD请求且有data,将其JSON序列化
108
120
  requestConfig.body = JSON.stringify(data);
109
121
  }
110
122
  // 如果是 GET 方法且有 data,将其作为查询参数添加到 URL
@@ -118,17 +130,33 @@ export const sendHttpRequest = async (config) => {
118
130
  requestUrl += (queryParams.toString() ? '&' : '?') + dataParams.toString();
119
131
  }
120
132
  const response = await fetch(requestUrl, requestConfig);
121
- if (!response.ok) {
122
- throw new Error(`HTTP error! status: ${response.status}`);
123
- }
124
133
  const responseData = await response.json();
125
134
  // 调用 onMessage 回调
126
135
  if (onMessage) {
127
136
  onMessage(responseData);
128
137
  }
138
+ // 检查响应状态
139
+ if (!response.ok) {
140
+ console.error(`HTTP错误: ${response.status} ${response.statusText}`);
141
+ return {
142
+ success: false,
143
+ message: responseData.message || `HTTP错误: ${response.status}`,
144
+ error: responseData
145
+ };
146
+ }
147
+ // 检查业务状态码
148
+ if (responseData.code !== 0) {
149
+ console.error(`API错误: ${responseData.message}`);
150
+ return {
151
+ success: false,
152
+ message: responseData.message,
153
+ error: responseData
154
+ };
155
+ }
156
+ // 直接返回data
129
157
  return {
130
- isOk: true,
131
- data: responseData
158
+ success: true,
159
+ data: responseData.data
132
160
  };
133
161
  }
134
162
  catch (error) {
@@ -137,8 +165,9 @@ export const sendHttpRequest = async (config) => {
137
165
  config.onError(error);
138
166
  }
139
167
  return {
140
- isOk: false,
141
- error
168
+ success: false,
169
+ error,
170
+ message: error instanceof Error ? error.message : '未知错误'
142
171
  };
143
172
  }
144
173
  finally {
@@ -147,116 +176,28 @@ export const sendHttpRequest = async (config) => {
147
176
  }
148
177
  }
149
178
  };
150
- /**
151
- * COS文件上传工具函数
152
- * @param config 上传配置
153
- * @returns Promise<COSUploadResult>
154
- */
155
- export const uploadToCOS = (config) => {
156
- const cos = new COS({
157
- SecretId: config.SecretId,
158
- SecretKey: config.SecretKey,
159
- SecurityToken: config.SecurityToken,
160
- StartTime: config.StartTime,
161
- ExpiredTime: config.ExpiredTime,
162
- });
163
- return new Promise((resolve, reject) => {
164
- cos.uploadFile({
165
- Bucket: config.Bucket,
166
- Region: config.Region,
167
- Key: config.Key,
168
- Body: config.file,
169
- SliceSize: 1024 * 1024 * 5, // 分片上传,每片5MB
170
- onProgress: (progressData) => {
171
- const percent = Math.floor((progressData.loaded / progressData.total) * 100);
172
- config.onProgress?.(percent);
173
- },
174
- }, (err, data) => {
175
- if (err) {
176
- config.onError?.(err);
177
- reject(err);
178
- }
179
- else {
180
- const result = {
181
- Location: data.Location,
182
- Bucket: config.Bucket,
183
- Key: config.Key,
184
- ETag: data.ETag,
185
- FileSize: config.file.size,
186
- RequestId: data.RequestId,
187
- };
188
- config.onSuccess?.(result);
189
- resolve(result);
190
- }
191
- });
192
- });
193
- };
194
- /**
195
- * 简单的文件类型检查工具
196
- * @param file 文件对象
197
- * @param allowedTypes 允许的文件类型数组
198
- * @returns boolean
199
- */
200
- export const checkFileType = (file, allowedTypes) => {
201
- const fileType = file.type.toLowerCase();
202
- return allowedTypes.some(type => fileType.includes(type));
203
- };
204
- /**
205
- * 文件大小检查工具
206
- * @param file 文件对象
207
- * @param maxSize 最大文件大小(单位:MB)
208
- * @returns boolean
209
- */
210
- export const checkFileSize = (file, maxSize) => {
211
- const fileSize = file.size / 1024 / 1024; // 转换为MB
212
- return fileSize <= maxSize;
213
- };
214
- /**
215
- * 获取COS上传认证信息
216
- * @param file 文件对象
217
- * @param tags 可选的标签数组
218
- * @returns Promise<COSAuthInfo>
219
- */
220
- export const getCosAuthInfo = async (file, tags) => {
221
- const data = {
222
- filename: file.name,
223
- filesize: file.size,
224
- filetype: file.type,
225
- tags,
226
- };
227
- const res = await sendHttpRequest({
228
- url: '/resource/get-cos-authkey',
229
- method: 'POST',
230
- data,
231
- });
232
- return res?.data ?? {};
233
- };
234
179
  /**
235
180
  * 通过后端API上传文件
236
181
  * @param file 要上传的文件
182
+ * @param headers 可选的请求头
237
183
  * @returns Promise 包含上传结果
238
184
  */
239
- export const uploadFileToBackend = async (file) => {
185
+ export const uploadFileToBackend = async (file, headers) => {
240
186
  const formData = new FormData();
241
187
  formData.append('file', file);
242
188
  try {
243
- const response = await fetch('https://pcm_api.ylzhaopin.com/external/v1/files/upload', {
189
+ const response = await sendHttpRequest({
190
+ url: '/sdk/v1/files/upload',
244
191
  method: 'POST',
245
- body: formData
192
+ headers: {
193
+ ...headers
194
+ },
195
+ formData
246
196
  });
247
- if (!response.ok) {
248
- throw new Error(`上传失败: ${response.status} ${response.statusText}`);
249
- }
250
- const result = await response.json();
251
- if (result.code !== 0 || !result.data) {
252
- throw new Error(result.message || '文件上传失败');
197
+ if (!response.success || !response.data) {
198
+ throw new Error(response.message || '文件上传失败');
253
199
  }
254
- return {
255
- id: result.data.id,
256
- name: result.data.name || file.name,
257
- size: result.data.size || file.size,
258
- type: result.data.type || file.type
259
- };
200
+ return response.data;
260
201
  }
261
202
  catch (error) {
262
203
  console.error('文件上传错误:', error);
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import COS from 'cos-js-sdk-v5';\n\nexport function format(first?: string, middle?: string, last?: string): string {\n return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');\n}\n\n// 添加类型定义\nexport interface UserInputMessageType {\n message: string;\n [key: string]: any;\n}\n\nexport interface WorkFlowNode {\n message_id?: string;\n conversation_id?: string;\n created_at?: string;\n event?: string;\n answer?: string;\n data?: {\n outputs?: {\n answer?: string;\n };\n status?: string;\n error?: any;\n };\n}\n\nexport interface MessageRound extends UserInputMessageType {\n id?: string;\n conversation_id?: string;\n created_at?: string;\n answer?: string;\n status?: string;\n error?: any;\n}\n\n/**\n * 将工作流节点转换为消息轮次\n * @param message_event 消息事件类型\n * @param inputMessage 用户输入消息\n * @param streamNode 工作流节点\n * @returns 消息轮次\n */\nexport const convertWorkflowStreamNodeToMessageRound = (\n message_event: string,\n inputMessage: UserInputMessageType,\n streamNode: WorkFlowNode,\n): MessageRound => {\n const messageRound: MessageRound = {\n ...inputMessage,\n };\n if (message_event === 'workflow_finished') messageRound.answer = streamNode.data?.outputs?.answer;\n if (message_event === 'agent_message' || message_event === 'message') messageRound.answer = streamNode?.answer;\n messageRound.id = streamNode.message_id;\n messageRound.conversation_id = streamNode.conversation_id;\n messageRound.created_at = streamNode.created_at;\n messageRound.status = streamNode.data?.status;\n messageRound.error = streamNode.data?.error;\n return messageRound;\n};\n\n/**\n * SSE 流式请求配置接口\n */\nexport interface SSERequestConfig {\n url: string;\n method: string;\n headers?: Record<string, string>;\n data?: any;\n onMessage?: (data: any) => void;\n onError?: (error: any) => void;\n onComplete?: () => void;\n}\n\n/**\n * 发送 SSE 流式请求\n * @param config 请求配置\n * @returns Promise<void>\n */\nexport const sendSSERequest = async (config: SSERequestConfig): Promise<void> => {\n const { url, method, headers = {}, data, onMessage, onError, onComplete } = config;\n \n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Accept': 'text/event-stream',\n 'Content-Type': 'application/json',\n ...headers\n },\n body: data ? JSON.stringify(data) : undefined\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n \n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n // 处理缓冲区中的完整消息\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // 保留最后一个不完整的行\n\n for (const line of lines) {\n if (line.startsWith('data:')) {\n try {\n const jsonStr = line.substring(5).trim();\n if (!jsonStr) continue;\n \n const data = JSON.parse(jsonStr);\n onMessage?.(data);\n } catch (e) {\n console.error('解析 SSE 数据错误:', e, '原始数据:', line);\n }\n }\n }\n }\n \n onComplete?.();\n } catch (error) {\n console.error('SSE 请求错误:', error);\n onError?.(error);\n }\n};\n\n/**\n * HTTP请求配置接口\n */\nexport interface HttpRequestConfig {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n params?: Record<string, any>;\n data?: any;\n onMessage?: (data: any) => void;\n onError?: (error: any) => void;\n onComplete?: () => void;\n}\n\n/**\n * HTTP响应接口\n */\nexport interface HttpResponse<T = any> {\n isOk: boolean;\n data?: T;\n error?: any;\n}\n\n/**\n * 发送HTTP请求\n * @param config 请求配置\n * @returns Promise<HttpResponse>\n */\nexport const sendHttpRequest = async <T = any>(config: HttpRequestConfig): Promise<HttpResponse<T>> => {\n const { url, method = 'GET', headers = {}, params = {}, data, onMessage } = config;\n \n try {\n // 构建URL和查询参数\n const queryParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n queryParams.append(key, String(value));\n }\n });\n \n let requestUrl = `${url}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n \n // 创建请求配置对象\n const requestConfig: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers\n }\n };\n\n // 只有在非 GET/HEAD 请求时才添加 body\n if (method !== 'GET' && method !== 'HEAD' && data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n // 如果是 GET 方法且有 data,将其作为查询参数添加到 URL\n if (method === 'GET' && data) {\n const dataParams = new URLSearchParams();\n Object.entries(data).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n dataParams.append(key, String(value));\n }\n });\n requestUrl += (queryParams.toString() ? '&' : '?') + dataParams.toString();\n }\n\n const response = await fetch(requestUrl, requestConfig);\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const responseData = await response.json();\n \n // 调用 onMessage 回调\n if (onMessage) {\n onMessage(responseData);\n }\n \n return {\n isOk: true,\n data: responseData\n };\n } catch (error) {\n console.error('HTTP请求错误:', error);\n if (config.onError) {\n config.onError(error);\n }\n return {\n isOk: false,\n error\n };\n } finally {\n if (config.onComplete) {\n config.onComplete();\n }\n }\n};\n\n/**\n * COS上传配置接口\n */\nexport interface COSUploadConfig {\n SecretId: string;\n SecretKey: string;\n SecurityToken?: string;\n StartTime?: number;\n ExpiredTime?: number;\n Bucket: string;\n Region: string;\n Key: string;\n file: File;\n onProgress?: (progress: number) => void;\n onSuccess?: (result: COSUploadResult) => void;\n onError?: (error: any) => void;\n}\n\n/**\n * COS上传结果接口\n */\nexport interface COSUploadResult {\n Location: string;\n Bucket: string;\n Key: string;\n ETag: string;\n FileSize: number;\n RequestId: string;\n}\n\n/**\n * COS文件上传工具函数\n * @param config 上传配置\n * @returns Promise<COSUploadResult>\n */\nexport const uploadToCOS = (config: COSUploadConfig): Promise<COSUploadResult> => {\n const cos = new COS({\n SecretId: config.SecretId,\n SecretKey: config.SecretKey,\n SecurityToken: config.SecurityToken,\n StartTime: config.StartTime,\n ExpiredTime: config.ExpiredTime,\n });\n\n return new Promise((resolve, reject) => {\n cos.uploadFile({\n Bucket: config.Bucket,\n Region: config.Region,\n Key: config.Key,\n Body: config.file,\n SliceSize: 1024 * 1024 * 5, // 分片上传,每片5MB\n onProgress: (progressData) => {\n const percent = Math.floor((progressData.loaded / progressData.total) * 100);\n config.onProgress?.(percent);\n },\n }, (err, data) => {\n if (err) {\n config.onError?.(err);\n reject(err);\n } else {\n const result = {\n Location: data.Location,\n Bucket: config.Bucket,\n Key: config.Key,\n ETag: data.ETag,\n FileSize: config.file.size,\n RequestId: data.RequestId,\n };\n config.onSuccess?.(result);\n resolve(result);\n }\n });\n });\n};\n\n/**\n * 简单的文件类型检查工具\n * @param file 文件对象\n * @param allowedTypes 允许的文件类型数组\n * @returns boolean\n */\nexport const checkFileType = (file: File, allowedTypes: string[]): boolean => {\n const fileType = file.type.toLowerCase();\n return allowedTypes.some(type => fileType.includes(type));\n};\n\n/**\n * 文件大小检查工具\n * @param file 文件对象\n * @param maxSize 最大文件大小(单位:MB)\n * @returns boolean\n */\nexport const checkFileSize = (file: File, maxSize: number): boolean => {\n const fileSize = file.size / 1024 / 1024; // 转换为MB\n return fileSize <= maxSize;\n};\n\n/**\n * COS认证信息接口\n */\nexport interface COSAuthInfo {\n filename?: string;\n filetype?: string;\n filesize?: number;\n cos?: {\n region?: string;\n bucket?: string;\n cos_key?: string;\n };\n auth?: {\n expiredTime?: number;\n expiration?: string;\n requestId?: string;\n startTime?: number;\n credentials?: {\n sessionToken?: string;\n tmpSecretId?: string;\n tmpSecretKey?: string;\n };\n };\n}\n\n/**\n * 获取COS上传认证信息\n * @param file 文件对象\n * @param tags 可选的标签数组\n * @returns Promise<COSAuthInfo>\n */\nexport const getCosAuthInfo = async (file: File, tags?: string[]): Promise<COSAuthInfo> => {\n const data = {\n filename: file.name,\n filesize: file.size,\n filetype: file.type,\n tags,\n };\n\n const res = await sendHttpRequest<COSAuthInfo>({\n url: '/resource/get-cos-authkey',\n method: 'POST',\n data,\n });\n\n return res?.data ?? {};\n};\n\n\n/**\n * 通过后端API上传文件\n * @param file 要上传的文件\n * @returns Promise 包含上传结果\n */\nexport const uploadFileToBackend = async (file: File): Promise<{id: string, name: string, size: number, type: string}> => {\n const formData = new FormData();\n formData.append('file', file);\n \n try {\n const response = await fetch('https://pcm_api.ylzhaopin.com/external/v1/files/upload', {\n method: 'POST',\n body: formData\n });\n \n if (!response.ok) {\n throw new Error(`上传失败: ${response.status} ${response.statusText}`);\n }\n \n const result = await response.json();\n if (result.code !== 0 || !result.data) {\n throw new Error(result.message || '文件上传失败');\n }\n \n return {\n id: result.data.id,\n name: result.data.name || file.name,\n size: result.data.size || file.size,\n type: result.data.type || file.type\n };\n } catch (error) {\n console.error('文件上传错误:', error);\n throw error;\n }\n};\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * API域名配置\r\n */\r\n// export const API_DOMAIN = 'http://192.168.17.194:8000';\r\nexport const API_DOMAIN = 'https://pcm_api.ylzhaopin.com';\r\n\r\n\r\nexport function format(first?: string, middle?: string, last?: string): string {\r\n return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');\r\n}\r\n\r\n// 添加类型定义\r\nexport interface UserInputMessageType {\r\n message: string;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface WorkFlowNode {\r\n message_id?: string;\r\n conversation_id?: string;\r\n created_at?: string;\r\n event?: string;\r\n answer?: string;\r\n data?: {\r\n outputs?: {\r\n answer?: string;\r\n };\r\n status?: string;\r\n error?: any;\r\n };\r\n}\r\n\r\nexport interface MessageRound extends UserInputMessageType {\r\n id?: string;\r\n conversation_id?: string;\r\n created_at?: string;\r\n answer?: string;\r\n status?: string;\r\n error?: any;\r\n}\r\n\r\n/**\r\n * 将工作流节点转换为消息轮次\r\n * @param message_event 消息事件类型\r\n * @param inputMessage 用户输入消息\r\n * @param streamNode 工作流节点\r\n * @returns 消息轮次\r\n */\r\nexport const convertWorkflowStreamNodeToMessageRound = (\r\n message_event: string,\r\n inputMessage: UserInputMessageType,\r\n streamNode: WorkFlowNode,\r\n): MessageRound => {\r\n const messageRound: MessageRound = {\r\n ...inputMessage,\r\n };\r\n if (message_event === 'workflow_finished') messageRound.answer = streamNode.data?.outputs?.answer;\r\n if (message_event === 'agent_message' || message_event === 'message') messageRound.answer = streamNode?.answer;\r\n messageRound.id = streamNode.message_id;\r\n messageRound.conversation_id = streamNode.conversation_id;\r\n messageRound.created_at = streamNode.created_at;\r\n messageRound.status = streamNode.data?.status;\r\n messageRound.error = streamNode.data?.error;\r\n return messageRound;\r\n};\r\n\r\n/**\r\n * SSE 流式请求配置接口\r\n */\r\nexport interface SSERequestConfig {\r\n url: string;\r\n method: string;\r\n headers?: Record<string, string>;\r\n data?: any;\r\n onMessage?: (data: any) => void;\r\n onError?: (error: any) => void;\r\n onComplete?: () => void;\r\n}\r\n\r\n/**\r\n * 发送 SSE 流式请求\r\n * @param config 请求配置\r\n * @returns Promise<void>\r\n */\r\nexport const sendSSERequest = async (config: SSERequestConfig): Promise<void> => {\r\n const { url, method, headers = {}, data, onMessage, onError, onComplete } = config;\r\n \r\n try {\r\n // 使用 API_DOMAIN 拼接完整的请求URL\r\n const requestUrl = `${API_DOMAIN}${url}`;\r\n \r\n const response = await fetch(requestUrl, {\r\n method,\r\n headers: {\r\n 'Accept': 'text/event-stream',\r\n 'Content-Type': 'application/json',\r\n ...headers\r\n },\r\n body: data ? JSON.stringify(data) : undefined\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) throw new Error('No reader available');\r\n \r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n // 处理缓冲区中的完整消息\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || ''; // 保留最后一个不完整的行\r\n\r\n for (const line of lines) {\r\n if (line.startsWith('data:')) {\r\n try {\r\n const jsonStr = line.substring(5).trim();\r\n if (!jsonStr) continue;\r\n \r\n const data = JSON.parse(jsonStr);\r\n onMessage?.(data);\r\n } catch (e) {\r\n console.error('解析 SSE 数据错误:', e, '原始数据:', line);\r\n }\r\n }\r\n }\r\n }\r\n \r\n onComplete?.();\r\n } catch (error) {\r\n console.error('SSE 请求错误:', error);\r\n onError?.(error);\r\n }\r\n};\r\n\r\n/**\r\n * HTTP请求配置接口\r\n */\r\nexport interface HttpRequestConfig {\r\n url: string;\r\n method?: string;\r\n headers?: Record<string, string>;\r\n params?: Record<string, any>;\r\n data?: any;\r\n formData?: FormData; // 添加FormData支持\r\n onMessage?: (data: any) => void;\r\n onError?: (error: any) => void;\r\n onComplete?: () => void;\r\n}\r\n\r\n/**\r\n * 统一的API响应接口\r\n */\r\nexport interface ApiResponse<T = any> {\r\n code: number;\r\n message: string;\r\n data?: T;\r\n}\r\n\r\n/**\r\n * HTTP响应接口\r\n */\r\nexport interface HttpResponse<T = any> {\r\n success: boolean;\r\n data?: T;\r\n error?: any;\r\n message?: string;\r\n}\r\n\r\n/**\r\n * 发送HTTP请求\r\n * @param config 请求配置\r\n * @returns Promise<HttpResponse>\r\n */\r\nexport const sendHttpRequest = async <T = any>(config: HttpRequestConfig): Promise<HttpResponse<T>> => {\r\n const { url, method = 'GET', headers = {}, params = {}, data, formData, onMessage } = config;\r\n \r\n try {\r\n // 构建URL和查询参数\r\n const queryParams = new URLSearchParams();\r\n Object.entries(params).forEach(([key, value]) => {\r\n if (value !== undefined && value !== null) {\r\n queryParams.append(key, String(value));\r\n }\r\n });\r\n \r\n // 使用 API_DOMAIN 拼接完整的请求URL\r\n let requestUrl = `${API_DOMAIN}${url}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\r\n \r\n // 创建请求配置对象\r\n const requestConfig: RequestInit = {\r\n method,\r\n headers: formData ? { ...headers } : {\r\n 'Content-Type': 'application/json',\r\n ...headers\r\n }\r\n };\r\n\r\n // 处理请求体\r\n if (formData) {\r\n // 如果提供了FormData,直接使用\r\n requestConfig.body = formData;\r\n } else if (method !== 'GET' && method !== 'HEAD' && data) {\r\n // 否则,如果是非GET/HEAD请求且有data,将其JSON序列化\r\n requestConfig.body = JSON.stringify(data);\r\n }\r\n\r\n // 如果是 GET 方法且有 data,将其作为查询参数添加到 URL\r\n if (method === 'GET' && data) {\r\n const dataParams = new URLSearchParams();\r\n Object.entries(data).forEach(([key, value]) => {\r\n if (value !== undefined && value !== null) {\r\n dataParams.append(key, String(value));\r\n }\r\n });\r\n requestUrl += (queryParams.toString() ? '&' : '?') + dataParams.toString();\r\n }\r\n\r\n const response = await fetch(requestUrl, requestConfig);\r\n const responseData: ApiResponse<T> = await response.json();\r\n \r\n // 调用 onMessage 回调\r\n if (onMessage) {\r\n onMessage(responseData);\r\n }\r\n \r\n // 检查响应状态\r\n if (!response.ok) {\r\n console.error(`HTTP错误: ${response.status} ${response.statusText}`);\r\n return {\r\n success: false,\r\n message: responseData.message || `HTTP错误: ${response.status}`,\r\n error: responseData\r\n };\r\n }\r\n \r\n // 检查业务状态码\r\n if (responseData.code !== 0) {\r\n console.error(`API错误: ${responseData.message}`);\r\n return {\r\n success: false,\r\n message: responseData.message,\r\n error: responseData\r\n };\r\n }\r\n \r\n // 直接返回data\r\n return {\r\n success: true,\r\n data: responseData.data\r\n };\r\n } catch (error) {\r\n console.error('HTTP请求错误:', error);\r\n if (config.onError) {\r\n config.onError(error);\r\n }\r\n return {\r\n success: false,\r\n error,\r\n message: error instanceof Error ? error.message : '未知错误'\r\n };\r\n } finally {\r\n if (config.onComplete) {\r\n config.onComplete();\r\n }\r\n }\r\n};\r\n\r\n\r\n\r\n/**\r\n * 文件上传响应数据接口\r\n */\r\nexport interface FileUploadResponse {\r\n /** 文件在对象存储中的唯一标识符 */\r\n cos_key: string;\r\n /** 文件名称 */\r\n file_name: string;\r\n /** 文件大小(带单位的字符串,如 \"1.5MB\") */\r\n file_size: string;\r\n /** 文件的预签名URL */\r\n presigned_url: string;\r\n /** 文件扩展名 */\r\n ext: string;\r\n}\r\n\r\n/**\r\n * 通过后端API上传文件\r\n * @param file 要上传的文件\r\n * @param headers 可选的请求头\r\n * @returns Promise 包含上传结果\r\n */\r\nexport const uploadFileToBackend = async (\r\n file: File,\r\n headers?: Record<string, string>\r\n): Promise<FileUploadResponse> => {\r\n const formData = new FormData();\r\n formData.append('file', file);\r\n \r\n try {\r\n const response = await sendHttpRequest<{cos_key: string, file_name: string, file_size: string,presigned_url: string, ext: string}>({\r\n url: '/sdk/v1/files/upload',\r\n method: 'POST',\r\n headers: {\r\n ...headers\r\n },\r\n formData\r\n });\r\n \r\n if (!response.success || !response.data) {\r\n throw new Error(response.message || '文件上传失败');\r\n }\r\n \r\n return response.data;\r\n } catch (error) {\r\n console.error('文件上传错误:', error);\r\n throw error;\r\n }\r\n};\r\n"]}