vue2-client 1.12.2 → 1.12.3-9.alpha.1

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 (44) hide show
  1. package/.env.iot +19 -0
  2. package/babel.config.js +4 -1
  3. package/docs//345/207/275/346/225/260/344/275/277/347/224/250/347/233/270/345/205/263.md +175 -174
  4. package/package.json +2 -2
  5. package/src/base-client/components/common/XCardSet/XCardSet.vue +300 -0
  6. package/src/base-client/components/common/XCollapse/XCollapse.vue +154 -0
  7. package/src/base-client/components/common/XConversation/XConversation.vue +87 -2
  8. package/src/base-client/components/common/XConversation/XConversationDemo.vue +28 -28
  9. package/src/base-client/components/common/XDataCard/XDataCard.vue +47 -21
  10. package/src/base-client/components/common/XDatePicker/index.vue +13 -3
  11. package/src/base-client/components/common/XForm/XForm.vue +1 -1
  12. package/src/base-client/components/common/XForm/XFormItem.vue +17 -7
  13. package/src/base-client/components/common/XForm/XTreeSelect.vue +263 -264
  14. package/src/base-client/components/common/XForm/demo.vue +105 -0
  15. package/src/base-client/components/common/XFormTable/demo.vue +11 -3
  16. package/src/base-client/components/common/XPrint/Demo.vue +41 -41
  17. package/src/base-client/components/common/XRate/demo.vue +102 -0
  18. package/src/base-client/components/common/XRate/index.vue +136 -0
  19. package/src/base-client/components/common/XReportGrid/XReport.vue +240 -305
  20. package/src/base-client/components/common/XReportGrid/XReportDemo.vue +0 -2
  21. package/src/base-client/components/common/XReportGrid/XReportDesign.vue +115 -345
  22. package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +100 -723
  23. package/src/base-client/components/common/XTable/XTable.vue +3 -0
  24. package/src/base-client/components/common/XTable/XTableWrapper.vue +7 -3
  25. package/src/base-client/components/his/XHDescriptions/XHDescriptions.vue +172 -0
  26. package/src/base-client/components/his/XHisEditor/XHisEditor.vue +360 -359
  27. package/src/layouts/GridView.vue +43 -45
  28. package/src/logic/plugins/common/DateTools.js +3 -0
  29. package/src/logic/plugins/common/VueTools.js +30 -0
  30. package/src/logic/plugins/index.js +3 -1
  31. package/src/pages/LogicCallExample/index.vue +10 -0
  32. package/src/pages/WorkflowDetail/WorkFlowDemo.vue +47 -32
  33. package/src/pages/WorkflowDetail/WorkflowDetail.vue +5 -0
  34. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowHandle.vue +876 -864
  35. package/src/pages/userInfoDetailManage/index.vue +82 -82
  36. package/src/plugins/HiPrintPlugin.js +164 -124
  37. package/src/router/async/router.map.js +3 -2
  38. package/src/services/v3Api.js +116 -116
  39. package/src/utils/EncryptUtil.js +6 -7
  40. package/src/utils/indexedDB.js +3 -1
  41. package/src/utils/request.js +4 -8
  42. package/src/utils/routerUtil.js +17 -0
  43. package/.babelrc +0 -3
  44. package/src/base-client/components/common/XReportGrid/XReportJsonRender.vue +0 -380
@@ -0,0 +1,300 @@
1
+ <template>
2
+ <div class="card-box" v-if="!configurationParameters.drawerMode">
3
+ <div
4
+ class="section-tab"
5
+ :innerText="configurationParameters"
6
+ contenteditable="true"
7
+ :style="{ backgroundColor: configurationParameters.tabBackgroundColor }">
8
+ <a-icon :type="configurationParameters.icon" style="margin-left: 2%;font-size: medium;"/>
9
+ {{ configurationParameters.tab }}
10
+ </div>
11
+ <div class="patient-overview">
12
+ <div
13
+ class="overview-section"
14
+ v-for="(item,index) in data"
15
+ :key="index"
16
+ :style="{borderBottom: index === data.length - 1 ? 'none' : '1px solid #ddd'}">
17
+ <div class="section-header" :style="{ backgroundColor: item.backgroundColor, color: item.fontColor }">
18
+ {{ item.titleName }}({{ item.messageNumber }})
19
+ </div>
20
+ <div class="patient-list-container">
21
+ <div class="patient-list">
22
+ <div
23
+ v-for="(patient, i) in item.showData"
24
+ :key="i"
25
+ class="patient-item"
26
+ :title="`${patient.room_number} - ${patient.patient_name}`">
27
+ <span class="card_data" :style="{ color: item.fontColor }">{{ patient.room_number }}</span>
28
+ <span class="card_data" >{{ patient.patient_name }}</span>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ <div v-else class="card-box">
36
+ <div
37
+ class="section-tab"
38
+ :innerText="configurationParameters"
39
+ contenteditable="true"
40
+ :style="{ backgroundColor: configurationParameters.tabBackgroundColor }">
41
+ <a-icon :type="configurationParameters.icon" style="margin-left: 2%;font-size: medium;"/>
42
+ {{ configurationParameters.tab }}
43
+ </div>
44
+ <a-collapse accordion class="accordion" :activeKey="activeKey" @change="switchDrawers">
45
+ <a-collapse-panel
46
+ v-for="(time, rowId) in times"
47
+ :header="time"
48
+ :style="{backgroundColor:rowId === rowIndex ? configurationParameters.tabBackgroundColor : '#fff'}"
49
+ :key="rowId" >
50
+ <div class="patient-overview">
51
+ <div
52
+ class="overview-section"
53
+ v-for="(item,index) in data"
54
+ :key="index"
55
+ :style="{borderBottom: index === data.length - 1 ? 'none' : '1px solid #ddd'}">
56
+ <div class="section-header" :style="{ backgroundColor: item.backgroundColor, color: item.fontColor }">
57
+ {{ item.titleName }}({{ item.messageNumber }})
58
+ </div>
59
+ <div class="patient-list-container">
60
+ <div class="patient-list">
61
+ <div
62
+ v-for="(patient, i) in item.showData"
63
+ :key="i"
64
+ class="patient-item"
65
+ :title="`${patient.room_number} - ${patient.patient_name}`">
66
+ <span class="card_data" :style="{ color: item.fontColor }">{{ patient.room_number }}</span>
67
+ <span class="card_data" >{{ patient.patient_name }}</span>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </a-collapse-panel>
74
+ </a-collapse>
75
+ </div>
76
+ </template>
77
+
78
+ <script>
79
+
80
+ import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
81
+
82
+ export default {
83
+ name: 'CardComponent',
84
+ data () {
85
+ return {
86
+ tab: 'container',
87
+ data: [
88
+ { room_number: '', patient_name: '' }
89
+ ],
90
+ activeKey: '0',
91
+ times: [],
92
+ DateTimes: [],
93
+ rowIndex: 0,
94
+ /* 配置参数(titleName:行标题名,dataSource:数据源,parameter:参数,fontColor:文字颜色,backgroundColor:背景颜色,
95
+ pageSize:分页数量,tabBackgroundColor:标签背景颜色,isPrimarySource:是否取mainDataSource中的元素), drawerMode:是否选用抽屉模式
96
+ times:如果选用抽屉 */
97
+ configurationParameters: {
98
+ drawerMode: false,
99
+ tab: '',
100
+ icon: '',
101
+ tabBackgroundColor: '',
102
+ mainDataSource: '',
103
+ serverName: '',
104
+ parameter: { pageSize: 8 },
105
+ times: 4,
106
+ configurationData: [
107
+ {
108
+ titleName: '',
109
+ isPrimarySource: true,
110
+ dataSource: '',
111
+ fontColor: '',
112
+ backgroundColor: ''
113
+ }
114
+ ]
115
+ }
116
+ }
117
+ },
118
+ props: {
119
+ queryParamsName: {
120
+ type: String,
121
+ default: 'nurseStationHomeConfig'
122
+ }
123
+ },
124
+ created () {
125
+ this.getData(this.queryParamsName)
126
+ },
127
+ methods: {
128
+ async getData (data) {
129
+ this.data = []
130
+ getConfigByName(data, 'af-his', res => {
131
+ if (!res.drawerMode) {
132
+ this.renderDeck(res)
133
+ } else { this.renderData(res) }
134
+ })
135
+ },
136
+ // 渲染卡片组数据
137
+ async renderDeck (res, times) {
138
+ this.configurationParameters = await res
139
+ if (res.drawerMode) {
140
+ res.parameter.times = await times
141
+ }
142
+ runLogic(res.mainDataSource, res.parameter).then(result => {
143
+ for (let i = 0; i < res.configurationData.length; i++) {
144
+ const ConfigureDisplayData = {
145
+ titleName: res.configurationData[i].titleName,
146
+ fontColor: res.configurationData[i].fontColor,
147
+ backgroundColor: res.configurationData[i].backgroundColor,
148
+ messageNumber: result[res.configurationData[i].dataSource + 'Total'][0].total,
149
+ showData: []
150
+ }
151
+ this.data.push(ConfigureDisplayData)
152
+ this.data[i].showData = result[res.configurationData[i].dataSource]
153
+ }
154
+ })
155
+ },
156
+ formatTime (date) {
157
+ const year = date.getFullYear()
158
+ const month = String(date.getMonth() + 1).padStart(2, '0')
159
+ const day = String(date.getDate()).padStart(2, '0')
160
+ const hours = String(date.getHours()).padStart(2, '0')
161
+ return `${year}-${month}-${day} ${hours}:00`
162
+ },
163
+ getTimes (n) {
164
+ const times = []
165
+ const now = new Date()
166
+ for (let i = 0; i <= n; i++) {
167
+ const time = new Date(now.getTime() + i * 60 * 60 * 1000)
168
+ times.push(this.formatTime(time))
169
+ }
170
+ return times
171
+ },
172
+ formatTimeToHHMM (timeString) {
173
+ const date = new Date(timeString)
174
+ const hours = String(date.getHours()).padStart(2, '0')
175
+ const minutes = String(date.getMinutes()).padStart(2, '0')
176
+ return `${hours}:${minutes}`
177
+ },
178
+ // 获取数据并渲染数据
179
+ renderData (data) {
180
+ this.times = []
181
+ this.DateTimes = []
182
+ const time = this.getTimes(data.times)
183
+ for (let i = 0; i < data.times; i++) {
184
+ const startTime = this.formatTimeToHHMM(time[i])
185
+ const endTime = this.formatTimeToHHMM(time[i + 1])
186
+ this.times.push(`${startTime} ~ ${endTime}`)
187
+ this.DateTimes.push(`${time[i]} and ${time[i + 1]}`)
188
+ }
189
+ this.renderDeck(data, `${time[0]} and ${time[1]}`)
190
+ },
191
+ // 切换抽屉
192
+ switchDrawers (activeKey) {
193
+ if (activeKey !== undefined) {
194
+ console.log('Active Header:', this.DateTimes[activeKey])
195
+ this.data = []
196
+ this.renderDeck(this.configurationParameters, this.DateTimes[activeKey])
197
+ this.rowIndex = activeKey
198
+ }
199
+ }
200
+ },
201
+ watch: {
202
+ queryParamsName: {
203
+ handler (newValue) {
204
+ this.getData(newValue)
205
+ },
206
+ deep: true
207
+ }
208
+ },
209
+ }
210
+ </script>
211
+
212
+ <style scoped>
213
+ .accordion{
214
+ width: 100%;
215
+ }
216
+ .patient-overview {
217
+ width: 100%;
218
+ padding: 0.5%;
219
+ border: 1px solid #ddd;
220
+ border-radius: 0 5px 5px 5px;
221
+ height: 100%;
222
+ background-color: white;
223
+ overflow: scroll;
224
+ }
225
+ .section-header {
226
+ font-weight: bold;
227
+ display: flex;
228
+ width: 10%;
229
+ align-items: center;
230
+ justify-content: center;
231
+ min-height: 45px;
232
+ border-radius: 5px;
233
+ min-width: 90px;
234
+ }
235
+ .patient-list-container {
236
+ display: flex;
237
+ align-items: center;
238
+ width: 100%;
239
+ padding-left: 1%;
240
+ }
241
+ .overview-section{
242
+ display: flex;
243
+ flex-wrap: nowrap;
244
+ align-items: center;
245
+ margin-top: 1%;
246
+ border-bottom: 1px solid #ddd;
247
+ padding-bottom: 0.7%;
248
+ }
249
+ .patient-list {
250
+ display: flex;
251
+ flex-wrap: wrap;
252
+ gap: 10px;
253
+ width: 100%;
254
+ }
255
+ .patient-item {
256
+ background-color: #fff;
257
+ padding: 0.3%;
258
+ border: 1px solid #ddd;
259
+ width: 4%;
260
+ height: 21%;
261
+ text-align: center;
262
+ font-size: x-small;
263
+ border-radius: 5px;
264
+ min-width: 45px;
265
+ min-height: 45px;
266
+ cursor: pointer;
267
+ }
268
+ .patient-item:hover {
269
+ background-color: #f0f0f0;
270
+ }
271
+ .patient-item span {
272
+ display: block;
273
+ }
274
+ .section-tab {
275
+ width: 2vw;
276
+ height: 22vh;
277
+ display: flex;
278
+ writing-mode: vertical-rl;
279
+ align-items: center;
280
+ justify-content: space-evenly;
281
+ border-radius: 5px 0 0 5px;
282
+ color: white;
283
+ min-width: 27px;
284
+ min-height: 80px;
285
+ max-height: 95px;
286
+ max-width: 30px;
287
+ }
288
+ .card-box {
289
+ display: flex;
290
+ flex-direction: row;
291
+ height: 100%;
292
+ }
293
+ .card_data{
294
+ display: inline-block;
295
+ max-width: 5ch; /* 最多显示 3 个字符 */
296
+ white-space: nowrap;
297
+ overflow: hidden;
298
+ text-overflow: ellipsis;
299
+ }
300
+ </style>
@@ -0,0 +1,154 @@
1
+ <template>
2
+ <div>
3
+ <a-collapse
4
+ :activeKey="activeKey"
5
+ @change="handleChange"
6
+ >
7
+ <a-collapse-panel
8
+ v-for="(panel, panelIndex) in config.showData"
9
+ :key="panelIndex.toString()"
10
+ :show-arrow="false"
11
+ >
12
+ <template #header>
13
+ <div class="header-content">
14
+ <span
15
+ class="header-text"
16
+ :style="config.titleStyle"
17
+ >
18
+ {{ panel.title }}
19
+ </span>
20
+ <span
21
+ v-for="(item, headerIndex) in panel.title2 || []"
22
+ :key="headerIndex"
23
+ class="info-item"
24
+ :style="config.title2Style"
25
+ >
26
+ <span>{{ item.key }}:</span>
27
+ <span>{{ item.value }}</span>
28
+ </span>
29
+ <span
30
+ class="time-item"
31
+ :style="config.title3Style"
32
+ >
33
+ {{ panel.title3 }}
34
+ </span>
35
+ </div>
36
+ </template>
37
+ <!-- 根据类型显示不同内容 -->
38
+ <template v-if="panel.type === 'picture'">
39
+ <img :src="panel.configName" alt="图片" style="width: 100%; max-width: 500px;"/>
40
+ </template>
41
+ <template v-else-if="panel.type === 'cover'">
42
+ <x-report
43
+ :use-oss-for-img="false"
44
+ :config-name="panel.configName"
45
+ server-name="af-his"
46
+ :show-img-in-cell="true"
47
+ :display-only="true"
48
+ :edit-mode="false"
49
+ :show-save-button="false"
50
+ :no-padding="true"
51
+ :dont-format="true">
52
+ </x-report>
53
+ </template>
54
+ </a-collapse-panel>
55
+ </a-collapse>
56
+ </div>
57
+ </template>
58
+
59
+ <script>
60
+ import XReport from '@vue2-client/base-client/components/common/XReportGrid'
61
+ import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
62
+
63
+ export default {
64
+ name: 'XCollapse',
65
+ components: {
66
+ XReport
67
+ },
68
+ inject: ['getConfigByName'],
69
+ data () {
70
+ return {
71
+ activeKey: [],
72
+ config: {}
73
+ }
74
+ },
75
+ props: {
76
+ // json名
77
+ queryParamsName: {
78
+ type: Object,
79
+ default: 'openPrescriptionConfig'
80
+ },
81
+ },
82
+ created () {
83
+ this.getData(this.queryParamsName)
84
+ },
85
+ methods: {
86
+ async getData (config) {
87
+ getConfigByName(config, 'af-his', res => {
88
+ this.config = res
89
+ runLogic(res.mainLogic, {}, 'af-his').then(result => {
90
+ console.log(result)
91
+ this.config.showData = result
92
+ this.activeKey = this.config.showData.map((_, panelIndex) => panelIndex.toString())
93
+ })
94
+ })
95
+ },
96
+ handleChange (keys) {
97
+ this.activeKey = keys
98
+ },
99
+ },
100
+ watch: {
101
+ queryParamsName: {
102
+ handler (newValue) {
103
+ console.log(newValue)
104
+ this.getData(newValue)
105
+ },
106
+ deep: true
107
+ }
108
+ }
109
+ }
110
+ </script>
111
+
112
+ <style scoped>
113
+ .header-content {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 24px;
117
+ }
118
+
119
+ .header-text {
120
+ margin-right: 16px;
121
+ font-size: 16px;
122
+ font-weight: 800; /* 默认加粗 */
123
+ }
124
+
125
+ .info-item {
126
+ display: inline-flex;
127
+ align-items: center;
128
+ gap: 4px;
129
+ font-size: 12px;
130
+ color: #888888;
131
+ }
132
+
133
+ .time-item {
134
+ margin-left: auto;
135
+ text-align: right;
136
+ }
137
+
138
+ /* 覆盖 ant-design-vue 的默认样式 */
139
+ :deep(.ant-collapse-header) {
140
+ align-items: center !important;
141
+ }
142
+
143
+ :deep(.ant-collapse-header-text) {
144
+ flex: 1;
145
+ }
146
+
147
+ :deep(.ant-collapse-content > .ant-collapse-content-box) {
148
+ padding: 0;
149
+ }
150
+
151
+ :deep(.ant-card-body) {
152
+ padding: 8px;
153
+ }
154
+ </style>
@@ -9,7 +9,11 @@
9
9
  :class="['chat-message', message.type]"
10
10
  >
11
11
  <span class="chat-avatar">{{ message.type === 'user' ? '👤' : '🤖' }}</span>
12
- <div class="chat-text" v-if="message.text" v-html="renderMarkdown(message.text)"></div>
12
+ <div
13
+ class="chat-text markdown-body"
14
+ v-if="message.text"
15
+ v-html="renderMarkdown(message.text)"
16
+ ></div>
13
17
  <div class="chat-text" v-else-if="message.state === 'loading'">
14
18
  <a-spin :spinning="true"/>
15
19
  </div>
@@ -166,7 +170,35 @@ export default {
166
170
  question: userMessage,
167
171
  additionalInfo: this.additionalInfo
168
172
  }, this.serviceName)
169
- this.messages.push({ type: 'bot', text: response.value })
173
+
174
+ // 遍历并保存 additionalInfo
175
+ console.log(response)
176
+ if (response.additionalInfo) {
177
+ Object.entries(response.additionalInfo).forEach(([key, value]) => {
178
+ // 如果值是字符串类型,尝试转换为数字
179
+ if (typeof value === 'string' && !isNaN(value)) {
180
+ const numberValue = Number(value)
181
+ // 检查转换后的值是否是有限数字
182
+ if (isFinite(numberValue)) {
183
+ this.additionalInfo[key] = numberValue
184
+ } else {
185
+ this.additionalInfo[key] = value
186
+ }
187
+ } else {
188
+ this.additionalInfo[key] = value
189
+ }
190
+ })
191
+ }
192
+ console.log(this.additionalInfo)
193
+ if (typeof response.value === 'string') {
194
+ try {
195
+ response.value = JSON.parse(response.value)
196
+ } catch (e) {
197
+ console.error('JSON解析失败:', e)
198
+ }
199
+ }
200
+ console.log(response.value.response)
201
+ this.messages.push({ type: 'bot', text: response.value.response })
170
202
  } else if (this.renderConfig.api) {
171
203
  // 通过api获取消息
172
204
  this.messages.push({ type: 'bot', state: 'loading' })
@@ -195,6 +227,18 @@ export default {
195
227
  )
196
228
  }
197
229
  },
230
+ setHistoryMessages (messages) {
231
+ console.log(messages)
232
+ // 清空现有消息
233
+ this.messages = []
234
+ // 添加历史消息
235
+ messages.forEach(msg => {
236
+ this.messages.push({
237
+ type: msg.role === 'user' ? 'user' : 'bot',
238
+ text: msg.content
239
+ })
240
+ })
241
+ }
198
242
  },
199
243
  mounted () {
200
244
  this.setAddtionalInfo(this.getMixinData())
@@ -272,4 +316,45 @@ code {
272
316
  padding: 2px 4px;
273
317
  font-size: 90%;
274
318
  }
319
+
320
+ /* 添加 Markdown 样式 */
321
+ .markdown-body {
322
+ font-size: 14px;
323
+ line-height: 1.6;
324
+ }
325
+
326
+ .markdown-body h1,
327
+ .markdown-body h2,
328
+ .markdown-body h3,
329
+ .markdown-body h4,
330
+ .markdown-body h5,
331
+ .markdown-body h6 {
332
+ margin-top: 16px;
333
+ margin-bottom: 8px;
334
+ font-weight: 600;
335
+ }
336
+
337
+ .markdown-body pre {
338
+ background-color: #f6f8fa;
339
+ border-radius: 6px;
340
+ padding: 16px;
341
+ overflow: auto;
342
+ }
343
+
344
+ .markdown-body code {
345
+ background-color: #f6f8fa;
346
+ border-radius: 3px;
347
+ padding: 0.2em 0.4em;
348
+ font-size: 85%;
349
+ }
350
+
351
+ .markdown-body p {
352
+ margin-bottom: 16px;
353
+ }
354
+
355
+ .markdown-body ul,
356
+ .markdown-body ol {
357
+ padding-left: 2em;
358
+ margin-bottom: 16px;
359
+ }
275
360
  </style>
@@ -1,28 +1,28 @@
1
- <template>
2
- <div>
3
- <h1>对话示例</h1>
4
- <XConversation ref="XConversation"/>
5
- </div>
6
- </template>
7
-
8
- <script>
9
- import XConversation from './XConversation.vue' // 请根据实际路径调整
10
-
11
- export default {
12
- name: 'ConversationDemo',
13
- components: {
14
- XConversation
15
- },
16
- mounted () {
17
- this.$refs.XConversation.init({
18
- logicName: 'submitMessage',
19
- serviceName: 'af-his'
20
- })
21
- this.$refs.XConversation.setAddtionalInfo({ patient_id: 37 })
22
- }
23
- }
24
- </script>
25
-
26
- <style scoped>
27
- /* 这里可以添加你的样式 */
28
- </style>
1
+ <template>
2
+ <div>
3
+ <h1>对话示例</h1>
4
+ <XConversation ref="XConversation"/>
5
+ </div>
6
+ </template>
7
+
8
+ <script>
9
+ import XConversation from './XConversation.vue' // 请根据实际路径调整
10
+
11
+ export default {
12
+ name: 'ConversationDemo',
13
+ components: {
14
+ XConversation
15
+ },
16
+ mounted () {
17
+ this.$refs.XConversation.init({
18
+ logicName: 'ragMessage',
19
+ serviceName: 'af-gpt-apply'
20
+ })
21
+ this.$refs.XConversation.setAddtionalInfo({ patient_id: 37 })
22
+ }
23
+ }
24
+ </script>
25
+
26
+ <style scoped>
27
+ /* 这里可以添加你的样式 */
28
+ </style>