vue2-client 1.22.7 → 1.22.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.env.his +19 -19
  2. package/.idea/CopilotChatHistory.xml +39 -0
  3. package/.idea/MarsCodeWorkspaceAppSettings.xml +8 -0
  4. package/.idea/af-vue2-client.iml +7 -4
  5. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  6. package/.idea/migrateChatHistory.xml +10 -0
  7. package/package.json +1 -1
  8. package/src/base-client/components/common/HIS/HForm/HForm.vue +1186 -1186
  9. package/src/base-client/components/common/XFormTable/demo.vue +134 -53
  10. package/src/base-client/components/common/XInspectionDetailDrawer/components/InspectionSummary.vue +8 -0
  11. package/src/base-client/components/common/XInspectionDetailDrawer/services/inspectionService.js +6 -1
  12. package/src/base-client/components/common/XMarkdownViewer/demo.vue +102 -102
  13. package/src/base-client/components/his/XTransfer/index.md +327 -327
  14. package/src/pages/WorkflowDetail/WorkFlowDemo4.vue +127 -0
  15. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowBaseInformation.vue +417 -417
  16. package/.history/.eslintrc_20260521171150.js +0 -74
  17. package/.history/.eslintrc_20260521171213.js +0 -74
  18. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154443.vue +0 -726
  19. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154700.vue +0 -478
  20. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175435.vue +0 -706
  21. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175450.vue +0 -694
  22. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260611152602.vue +0 -755
  23. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513145941.vue +0 -524
  24. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513153133.vue +0 -731
  25. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513160316.vue +0 -525
  26. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260601144150.vue +0 -1046
  27. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310142713.vue +0 -512
  28. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310145118.vue +0 -511
  29. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260311094834.vue +0 -696
  30. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260320143028.vue +0 -693
  31. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260409101450.vue +0 -677
  32. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164645.vue +0 -758
  33. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164714.vue +0 -693
  34. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508171651.vue +0 -716
  35. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509133717.vue +0 -695
  36. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509171115.vue +0 -664
  37. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140637.vue +0 -1455
  38. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140935.vue +0 -1441
  39. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513150818.vue +0 -1441
  40. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153119.vue +0 -1442
  41. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153126.vue +0 -1486
  42. package/.history/src/base-client/components/common/XForm/XFormItem_20260513140854.vue +0 -1607
  43. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140403.vue +0 -643
  44. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140829.vue +0 -628
  45. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519142824.vue +0 -104
  46. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519143155.vue +0 -102
  47. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171231.vue +0 -1241
  48. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171441.vue +0 -1223
  49. package/.history/src/base-client/components/his/HAi/HAi_20260612174826.vue +0 -472
  50. package/.history/src/base-client/components/his/HAi/HAi_20260612175839.vue +0 -538
  51. package/.history/src/base-client/components/his/HAi/HAi_20260615103331.vue +0 -650
  52. package/.history/src/base-client/components/his/XHDescriptions/XHDescriptions_20260424134504.vue +0 -1469
  53. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171133.vue +0 -788
  54. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171151.vue +0 -780
  55. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511170841.vue +0 -585
  56. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511171138.vue +0 -787
  57. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260512141830.vue +0 -739
  58. package/.history/src/components/STable/index_20260409155138.js +0 -806
  59. package/.history/src/components/STable/index_20260409155218.js +0 -814
  60. package/.history/src/expression/core/Expression_20260305164427.js +0 -1371
  61. package/.history/src/expression/core/Expression_20260305170258.js +0 -1358
  62. package/.history/src/expression/core/Program_20260305111830.js +0 -944
  63. package/.history/src/expression/core/Program_20260305112041.js +0 -931
  64. package/.history/src/logic/LogicRunner_20260304154306.js +0 -170
  65. package/.history/src/logic/LogicRunner_20260304155553.js +0 -112
  66. package/.history/src/logic/LogicRunner_20260305105834.js +0 -112
  67. package/.history/src/logic/LogicRunner_20260305112718.js +0 -129
  68. package/.history/src/logic/LogicRunner_20260305182436.js +0 -133
  69. package/.history/src/logic/LogicRunner_20260306151301.js +0 -213
  70. package/.history/src/logic/LogicRunner_20260306152419.js +0 -213
  71. package/.history/src/logic/plugins/common/DateTools_20260305154159.js +0 -61
  72. package/.history/src/logic/plugins/common/DateTools_20260305154217.js +0 -44
  73. package/.history/src/logic/plugins/common/DateTools_20260305161014.js +0 -44
  74. package/.history/src/logic/plugins/common/HttpTools_20260305164352.js +0 -80
  75. package/.history/src/logic/plugins/common/HttpTools_20260305170258.js +0 -75
  76. package/.history/src/logic/plugins/common/HttpTools_20260305171634.js +0 -75
  77. package/.history/src/logic/plugins/common/HttpTools_20260306152419.js +0 -72
  78. package/.history/src/services/api/restTools_20260427142149.js +0 -245
  79. package/.history/src/services/api/restTools_20260427142853.js +0 -230
  80. package/.history/src/services/api/restTools_20260519135558.js +0 -230
  81. package/.history/src/services/api/restTools_20260519140825.js +0 -230
  82. package/.history/src/services/api/restTools_20260519151223.js +0 -230
  83. package/.history/src/utils/indexedDB_20260306150918.js +0 -593
  84. package/.history/src/utils/indexedDB_20260306151301.js +0 -586
  85. package/.idea/codeStyles/Project.xml +0 -62
  86. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  87. package/.idea/misc.xml +0 -6
  88. package/preview-input-box.html +0 -180
@@ -1,538 +0,0 @@
1
- <template>
2
- <div class="ai-consultation-outer">
3
- <div class="ai-consultation-container">
4
- <div class="chat-area">
5
- <!-- 对话区域 -->
6
- <div class="dialog-area">
7
- <div
8
- v-for="(message, index) in dialogMessages"
9
- :key="index"
10
- :class="['dialog-message', message.type]"
11
- >
12
- <div class="message-text" v-html="renderMd(message.content)" />
13
- <span v-if="message.type === 'ai' && isAiStreaming && index === dialogMessages.length - 1" class="typing-cursor">▍</span>
14
- </div>
15
- </div>
16
- </div>
17
-
18
- <div class="bottom-input-wrapper">
19
- <div class="input-container">
20
- <div class="input-textarea-area">
21
- <a-textarea
22
- ref="consultTextarea"
23
- v-model="doctorInputText"
24
- placeholder="医生补充信息或提问..."
25
- class="bottom-input"
26
- :rows="1"
27
- resize="none"
28
- @input="handleInput"
29
- @keydown="handleKeydown"
30
- ></a-textarea>
31
- </div>
32
-
33
- <input
34
- ref="uploadInput"
35
- type="file"
36
- style="display: none"
37
- @change="handleFileChange"
38
- multiple
39
- accept="image/*,.pdf,.doc,.docx"
40
- />
41
-
42
- <div class="input-controls">
43
- <div class="input-controls-left">
44
- <a-button class="upload-btn" @click="triggerUpload">
45
- <a-icon type="plus" class="upload-icon" />
46
- <span class="upload-text">上传(报告、图片)</span>
47
- </a-button>
48
- </div>
49
-
50
- <div class="input-controls-right">
51
- <span class="enter-tip">Enter</span>
52
- <a-button
53
- type="primary"
54
- shape="circle"
55
- class="send-btn"
56
- @click="handleSendMessage"
57
- :disabled="!doctorInputText.trim()"
58
- >
59
- <span class="send-icon">↑</span>
60
- </a-button>
61
- </div>
62
- </div>
63
- </div>
64
- </div>
65
- </div>
66
- </div>
67
- </template>
68
-
69
- <script>
70
- import { startEventStreamPOST } from '@vue2-client/services/api/restTools'
71
- import { marked } from 'marked'
72
- import moment from 'moment/moment'
73
- import { mapState } from 'vuex'
74
-
75
- export default {
76
- name: 'AIConsultation',
77
- data() {
78
- return {
79
- currentDialogId: null,
80
- doctorInputText: '',
81
- isPlaying: false,
82
- isRecording: false,
83
- patientComplaint: '',
84
- doctorQuestions: [],
85
- examinationOrder: null,
86
- aiDiagnosis: null,
87
- dialogMessages: [],
88
- currentStreamConnection: null,
89
- isAiStreaming: false,
90
- resizeTimeout: null
91
- }
92
- },
93
- computed: {
94
- ...mapState('account', {currUser: 'user'})
95
- },
96
- mounted() {
97
- this.$nextTick(() => {
98
- this.autoResizeTextarea()
99
- })
100
- },
101
- beforeDestroy() {
102
- // 组件销毁时关闭流式连接
103
- if (this.currentStreamConnection) {
104
- this.currentStreamConnection()
105
- this.currentStreamConnection = null
106
- }
107
- if (this.resizeTimeout) {
108
- clearTimeout(this.resizeTimeout)
109
- }
110
- },
111
- methods: {
112
- autoResizeTextarea() {
113
- this.$nextTick(() => {
114
- const textarea = this.$refs.consultTextarea?.$el || this.$refs.consultTextarea
115
- if (!textarea) return
116
-
117
- textarea.style.height = 'auto'
118
- const scrollHeight = textarea.scrollHeight
119
- textarea.style.height = `${Math.min(Math.max(scrollHeight, 120), 250)}px`
120
- })
121
- },
122
-
123
- handleInput() {
124
- if (this.resizeTimeout) clearTimeout(this.resizeTimeout)
125
- this.resizeTimeout = setTimeout(() => {
126
- this.autoResizeTextarea()
127
- }, 16)
128
- },
129
-
130
- renderMd(text) {
131
- if (!text) return ''
132
- try {
133
- return marked.parse(text, { breaks: true, gfm: true, headerIds: false, mangle: false })
134
- } catch {
135
- return text
136
- }
137
- },
138
-
139
- handleKeydown(event) {
140
- if (event.key === 'Enter' && !event.shiftKey) {
141
- event.preventDefault()
142
- this.handleSendMessage()
143
- }
144
- },
145
-
146
- initDialog() {
147
- if (!this.currentDialogId) {
148
- this.currentDialogId = moment().format('YYYYMMDDHHmmss')
149
- }
150
- },
151
-
152
- clearDialog() {
153
- this.currentDialogId = moment().format('YYYYMMDDHHmmss')
154
- this.dialogMessages = []
155
- },
156
-
157
- handleSendMessage() {
158
- if (!this.doctorInputText.trim()) return
159
-
160
- // 确保有dialogId
161
- if (!this.currentDialogId) {
162
- this.initDialog()
163
- }
164
-
165
- const messageContent = this.doctorInputText.trim()
166
- const doctorMessage = {
167
- type: 'user',
168
- content: messageContent,
169
- time: new Date().toLocaleTimeString(),
170
- timestamp: Date.now()
171
- }
172
- this.dialogMessages.push(doctorMessage)
173
- this.scrollToBottom()
174
-
175
- this.doctorInputText = ''
176
- this.autoResizeTextarea()
177
-
178
- const chatId = this.currentDialogId
179
- let aiContent = ''
180
- const aiMsgIndex = this.dialogMessages.length
181
- this.dialogMessages.push({
182
- type: 'ai',
183
- content: '',
184
- time: new Date().toLocaleTimeString(),
185
- timestamp: Date.now()
186
- })
187
- this.scrollToBottom()
188
-
189
- this.isAiStreaming = true
190
-
191
- this.currentStreamConnection = startEventStreamPOST(
192
- '/his-web/api/af-his/ai/chat/stream',
193
- { userMessage: messageContent, chatId, model: '', prompt: '', useContext: true, user: this.currUser.operInfo },
194
- {'Content-Type': 'application/json'},
195
- (data, type) => {
196
- if (type === 'additionalInfo' || type === 'sourceInfo') return
197
-
198
- let textChunk = ''
199
- if (typeof data === 'object' && data !== null) {
200
- const choices = data.choices
201
- if (Array.isArray(choices) && choices.length > 0) {
202
- const delta = choices[0].delta
203
-
204
- // 优先取 delta.content(标准 OpenAI 格式)
205
- if (delta && typeof delta.content === 'string' && delta.content) {
206
- textChunk = delta.content
207
- }
208
-
209
- // 兼容百川模型的 thinking 字段
210
- if (!textChunk && delta && delta.thinking) {
211
- const thinking = delta.thinking
212
- // 取 summary 描述
213
- if (thinking.summary && typeof thinking.summary === 'string') {
214
- textChunk = `[思考中] ${thinking.summary}`
215
- }
216
- // 取 reasoning steps
217
- if (Array.isArray(thinking.steps)) {
218
- const activeStep = thinking.steps.find(s => s.status === 'in_progress')
219
- if (activeStep && activeStep.label) {
220
- textChunk = `[思考中] ${activeStep.label}`
221
- }
222
- }
223
- }
224
-
225
- // 检测模型拒答
226
- const finishReason = choices[0].finish_reason
227
- if (finishReason === 'refuse_answer') {
228
- const refuseTip = '\n\n> ⚠️ 很抱歉,当前问题我无法回答,请尝试调整提问方式或联系管理员。'
229
- if (!this.dialogMessages[aiMsgIndex].content.includes('无法回答')) {
230
- this.dialogMessages[aiMsgIndex].content += refuseTip
231
- this.isAiStreaming = false
232
- this.scrollToBottom()
233
- }
234
- }
235
- }
236
- } else if (typeof data === 'string') {
237
- textChunk = data
238
- }
239
-
240
- if (textChunk) {
241
- aiContent += textChunk
242
- this.dialogMessages[aiMsgIndex].content = aiContent
243
- this.scrollToBottom()
244
- }
245
- },
246
- (error) => {
247
- this.isAiStreaming = false
248
- this.dialogMessages[aiMsgIndex].content += `\n\n[错误: ${error.message || '请求失败'}]`
249
- this.scrollToBottom()
250
- },
251
- () => {
252
- this.isAiStreaming = false
253
- this.scrollToBottom()
254
- }
255
- )
256
- },
257
-
258
- setPatientComplaint(complaint) {
259
- this.patientComplaint = complaint
260
- },
261
-
262
- scrollToBottom(delay = 0) {
263
- this.$nextTick(() => {
264
- setTimeout(() => {
265
- const chatArea = document.querySelector('.chat-area')
266
- if (chatArea) {
267
- chatArea.scrollTop = chatArea.scrollHeight
268
- }
269
- }, delay)
270
- })
271
- },
272
-
273
- reset() {
274
- if (this.currentStreamConnection) {
275
- this.currentStreamConnection()
276
- this.currentStreamConnection = null
277
- }
278
- this.isAiStreaming = false
279
- this.patientComplaint = ''
280
- this.doctorQuestions = []
281
- this.examinationOrder = null
282
- this.aiDiagnosis = null
283
- this.doctorInputText = ''
284
- this.isPlaying = false
285
- this.isRecording = false
286
- this.dialogMessages = []
287
- this.$nextTick(() => {
288
- this.autoResizeTextarea()
289
- const chatArea = document.querySelector('.chat-area')
290
- if (chatArea) {
291
- chatArea.scrollTop = 0
292
- }
293
- })
294
- },
295
-
296
- triggerUpload() {
297
- this.$refs.uploadInput.click()
298
- },
299
-
300
- handleFileChange(event) {
301
- const files = Array.from(event.target.files || [])
302
- if (!files.length) return
303
-
304
- this.dialogMessages.push({
305
- type: 'user',
306
- content: `已上传文件:${files.map(f => f.name).join('、')}`,
307
- time: new Date().toLocaleTimeString(),
308
- timestamp: Date.now()
309
- })
310
- this.scrollToBottom()
311
- event.target.value = ''
312
- }
313
- }
314
- }
315
- </script>
316
-
317
- <style scoped>
318
- .ai-consultation-outer {
319
- box-sizing: border-box;
320
- margin: 0;
321
- padding: 0;
322
- width: 100%;
323
- height: 860px;
324
- }
325
-
326
- .ai-consultation-container {
327
- width: 100%;
328
- height: 100%;
329
- display: flex;
330
- flex-direction: column;
331
- background: #FFFFFF;
332
- border: 1px solid #E5E9F0;
333
- }
334
-
335
- .chat-area {
336
- flex: 1;
337
- overflow-y: auto;
338
- padding: 16px;
339
- background: #fff;
340
- min-height: 690px;
341
- }
342
-
343
- .dialog-area {
344
- display: flex;
345
- flex-direction: column;
346
- }
347
-
348
- /* 底部输入框区域 */
349
- .bottom-input-wrapper {
350
- flex-shrink: 0;
351
- padding: 12px 16px;
352
- background: #fff;
353
- }
354
-
355
- .input-container {
356
- position: relative;
357
- width: 782px;
358
- height: 249px;
359
- margin: 0 auto;
360
- padding: 15px 0 0 11px;
361
- display: flex;
362
- flex-direction: column;
363
- }
364
-
365
- .input-textarea-area {
366
- flex: 1 1 auto;
367
- min-height: 0;
368
- }
369
-
370
- .bottom-input {
371
- width: 100%;
372
- height: 100%;
373
- border-radius: 6px;
374
- opacity: 1;
375
- background: #FFFFFF;
376
- box-sizing: border-box;
377
- border: 1px solid #E5E9F0;
378
- padding: 12px 60px 12px 16px;
379
- font-family: 'Source Han Sans', 'Microsoft YaHei', sans-serif;
380
- font-size: 16px;
381
- color: #313131;
382
- resize: none;
383
- outline: none;
384
- }
385
-
386
- .bottom-input:focus {
387
- border-color: #1890ff;
388
- box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
389
- }
390
-
391
- .bottom-input::placeholder {
392
- color: #999;
393
- }
394
-
395
- .input-controls-left {
396
- position: absolute;
397
- left: 5px;
398
- bottom: 5px;
399
- z-index: 2;
400
- }
401
-
402
- .upload-btn {
403
- width: 173px;
404
- height: 32px;
405
- border-radius: 6px;
406
- background: #FFFFFF;
407
- box-sizing: border-box;
408
- border: 1px solid #9499A0;
409
- color: #313131;
410
- font-family: Source Han Sans;
411
- font-size: 16px;
412
- font-weight: normal;
413
- line-height: normal;
414
- letter-spacing: 0em;
415
- display: flex;
416
- align-items: center;
417
- justify-content: center;
418
- gap: 6px;
419
- cursor: pointer;
420
- padding: 0;
421
- }
422
-
423
- .upload-btn > .anticon + span,
424
- .upload-btn > span + .anticon {
425
- margin-left: 0;
426
- }
427
-
428
- .upload-icon {
429
- font-size: 21px;
430
- margin-left: 8px;
431
- color: #94979E;
432
- display: inline-flex;
433
- align-items: center;
434
- justify-content: center;
435
- }
436
-
437
- .upload-text {
438
- height: 23px;
439
- opacity: 1;
440
- font-family: Source Han Sans;
441
- font-size: 16px;
442
- font-weight: normal;
443
- line-height: normal;
444
- letter-spacing: 0em;
445
- color: #313131;
446
- }
447
-
448
- .input-controls-right {
449
- position: absolute;
450
- right: 7px;
451
- bottom: 7px;
452
- display: flex;
453
- align-items: center;
454
- gap: 8px;
455
- z-index: 2;
456
- }
457
-
458
- .enter-tip {
459
- font-family: 'Inter', sans-serif;
460
- font-size: 14px;
461
- font-weight: 500;
462
- color: #9E9E9E;
463
- padding: 4px 8px;
464
- }
465
-
466
- .send-btn {
467
- width: 30px;
468
- height: 30px;
469
- background: #0057FE;
470
- border: none;
471
- border-radius: 50%;
472
- color: #fff;
473
- font-size: 14px;
474
- cursor: pointer;
475
- display: flex;
476
- align-items: center;
477
- justify-content: center;
478
- padding: 0;
479
- }
480
-
481
- .send-btn:hover {
482
- background: #0040cc;
483
- }
484
-
485
- .send-icon {
486
- font-size: 14px;
487
- font-weight: bold;
488
- }
489
-
490
- /* 对话区域样式 */
491
- .dialog-message {
492
- display: flex;
493
- margin-bottom: 16px;
494
- align-items: flex-start;
495
- }
496
-
497
- .dialog-message:last-child {
498
- margin-bottom: 0;
499
- }
500
-
501
- .dialog-message.ai {
502
- flex-direction: row;
503
- }
504
-
505
- .dialog-message.user {
506
- flex-direction: row-reverse;
507
- }
508
-
509
- .dialog-message.user .message-text {
510
- text-align: right;
511
- }
512
-
513
- .message-text {
514
- opacity: 1;
515
- font-family: Source Han Sans;
516
- font-size: 16px;
517
- font-weight: normal;
518
- line-height: normal;
519
- text-align: justify;
520
- letter-spacing: 0em;
521
- font-feature-settings: "kern" on;
522
- max-width: 100%;
523
- color: #313131;
524
- }
525
-
526
- .typing-cursor {
527
- display: inline-block;
528
- margin-left: 2px;
529
- color: #0057FE;
530
- font-size: 18px;
531
- animation: blink 1s step-end infinite;
532
- }
533
-
534
- @keyframes blink {
535
- 0%, 100% { opacity: 1; }
536
- 50% { opacity: 0; }
537
- }
538
- </style>