vue2-client 1.16.54 → 1.16.57

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 (32) hide show
  1. package/package.json +112 -112
  2. package/src/assets/img/paymentMethod/icon1.png +0 -0
  3. package/src/assets/img/paymentMethod/icon2.png +0 -0
  4. package/src/assets/img/paymentMethod/icon3.png +0 -0
  5. package/src/assets/img/paymentMethod/icon4.png +0 -0
  6. package/src/assets/img/paymentMethod/icon5.png +0 -0
  7. package/src/assets/img/paymentMethod/icon6.png +0 -0
  8. package/src/assets/svg/female.svg +1 -1
  9. package/src/assets/svg/male.svg +1 -1
  10. package/src/base-client/components/common/HIS/HFormGroup/HFormGroup.vue +120 -120
  11. package/src/base-client/components/common/HIS/HFormGroup/index.js +3 -3
  12. package/src/base-client/components/common/HIS/HFormTable/HFormTable.vue +379 -379
  13. package/src/base-client/components/common/HIS/HTab/HTab.vue +37 -3
  14. package/src/base-client/components/common/HIS/demo.vue +61 -61
  15. package/src/base-client/components/common/XCollapse/XCollapse.vue +461 -461
  16. package/src/base-client/components/common/XInput/XInput.vue +147 -147
  17. package/src/base-client/components/common/XReport/XReportHospitalizationDemo.vue +45 -0
  18. package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +828 -824
  19. package/src/base-client/components/common/XTable/XTable.vue +1610 -1610
  20. package/src/base-client/components/common/XTimeline/XTimeline.vue +454 -454
  21. package/src/base-client/components/his/XCharge/XCharge.vue +245 -93
  22. package/src/base-client/components/his/XCharge/XChargeDemo.vue +99 -3
  23. package/src/base-client/components/his/XCharge/testConfig.js +439 -0
  24. package/src/base-client/components/his/XHisEditor/XHisEditor.vue +705 -705
  25. package/src/base-client/components/his/XList/XList.vue +829 -829
  26. package/src/base-client/components/his/XSidebar/XSidebar.vue +113 -25
  27. package/src/base-client/components/his/XTitle/XTitle.vue +16 -0
  28. package/src/base-client/components/his/threeTestOrders/editor.vue +113 -113
  29. package/src/pages/userInfoDetailManage/ExceptionRecordQuery/index.vue +45 -45
  30. package/src/router/async/router.map.js +132 -129
  31. package/src-base-client/components/his/XCharge/README.md +0 -0
  32. package/src-base-client/components/his/XCharge/XCharge.vue +0 -0
@@ -1,17 +1,19 @@
1
1
  <template>
2
2
  <div
3
3
  class="drawer"
4
- :class="{ 'drawer-collapsed': !isOpen }">
4
+ :class="[{ 'drawer-collapsed': !isOpen }, wrapperClassObject()]"
5
+ :style="drawerStyle">
5
6
  <div
6
7
  v-show="!isFrameConfig"
7
8
  class="drawer-toggle"
8
9
  :class="{ 'toggle-collapsed': !isOpen }"
10
+ :style="toggleStyle"
9
11
  @click="toggleDrawer">
10
12
  <div class="arrow">
11
13
  {{ isOpen ? '›' : '‹' }}
12
14
  </div>
13
15
  </div>
14
- <div class="drawer-content" v-show="isOpen">
16
+ <div class="drawer-content" v-show="isOpen" :style="contentStyle">
15
17
  <x-report
16
18
  ref="x_report"
17
19
  :configName="queryParamsName"
@@ -51,15 +53,39 @@ export default {
51
53
  type: Boolean,
52
54
  default: false
53
55
  },
54
- // 展开时所占宽度百分比(影响父级 ant-col 的 flex 与 max-width)
56
+ // 展开时所占宽度百分比(percent模式使用,影响父级 ant-col 的 flex 与 max-width)
55
57
  expandedWidthPercent: {
56
58
  type: Number,
57
59
  default: 33.3
58
60
  },
59
- // 收缩时所占宽度百分比
61
+ // 收缩时所占宽度百分比(percent模式使用)
60
62
  collapsedWidthPercent: {
61
63
  type: Number,
62
64
  default: 2
65
+ },
66
+ // 展开时所占宽度像素值(px模式使用)
67
+ expandedWidth: {
68
+ type: Number,
69
+ default: 602
70
+ },
71
+ // 收缩时所占宽度像素值(px模式使用)
72
+ collapsedWidth: {
73
+ type: Number,
74
+ default: 26
75
+ },
76
+ // 总宽度像素值(px模式使用)
77
+ totalWidth: {
78
+ type: Number,
79
+ default: 1638
80
+ },
81
+ // 宽度计算模式:'percent' 百分比模式,'px' 像素模式
82
+ // 使用示例:
83
+ // percent模式: <x-sidebar :width-mode="'percent'" :expanded-width-percent="40" :collapsed-width-percent="3" />
84
+ // px模式: <x-sidebar :width-mode="'px'" :expanded-width="500" :collapsed-width="30" />
85
+ widthMode: {
86
+ type: String,
87
+ default: 'percent',
88
+ validator: value => ['percent', 'px'].includes(value)
63
89
  }
64
90
  },
65
91
  data () {
@@ -88,18 +114,29 @@ export default {
88
114
  })
89
115
  }
90
116
  },
117
+ wrapperClassObject () {
118
+ const attrs = this.$attrs || {}
119
+ const classes = {}
120
+ const booleanStyleKeys = ['']
121
+ booleanStyleKeys.forEach(key => {
122
+ const val = attrs[key]
123
+ const truthy = val === true || val === '' || val === 'true'
124
+ if (truthy) classes[`x-sidebar-${key}`] = true
125
+ })
126
+ return classes
127
+ },
91
128
  // 更新card-body的padding
92
129
  updateCardBodyPadding () {
93
130
  this.$nextTick(() => {
94
131
  const cardBody = this.$el.querySelector('.ant-card-body')
95
132
  if (cardBody) {
96
- cardBody.style.padding = '3%'
133
+ cardBody.style.padding = '0px'
97
134
  } else {
98
135
  // 如果找不到元素,可能需要等待XReport完全渲染
99
136
  setTimeout(() => {
100
137
  const cardBody = this.$el.querySelector('.ant-card-body')
101
138
  if (cardBody) {
102
- cardBody.style.padding = '3%'
139
+ cardBody.style.padding = '0px'
103
140
  }
104
141
  }, 500)
105
142
  }
@@ -159,20 +196,37 @@ export default {
159
196
  }
160
197
 
161
198
  if (isOpen) {
162
- // 展开:仅当显式允许时才改变布局百分比;否则恢复默认宽度
199
+ // 展开:仅当显式允许时才改变布局;否则恢复默认宽度
163
200
  if (this.affectLayout) {
164
- const drawerWidth = (this.expandedWidthPercent || 33.3)
165
- currentCol.style.cssText = `
166
- flex: 0 0 ${drawerWidth}% !important;
167
- max-width: ${drawerWidth}% !important;
168
- transition: all 0.3s;`
169
- if (otherCols.length === 1) {
170
- const mainCol = otherCols[0]
171
- const mainWidth = Math.max(0, 100 - drawerWidth)
172
- mainCol.style.cssText = `
173
- flex: 0 0 ${mainWidth}% !important;
174
- max-width: ${mainWidth}% !important;
201
+ if (this.widthMode === 'px') {
202
+ // px模式:使用固定像素宽度
203
+ const drawerWidth = this.expandedWidth || 584
204
+ currentCol.style.cssText = `
205
+ flex: 0 0 ${drawerWidth}px !important;
206
+ max-width: ${drawerWidth}px !important;
207
+ transition: all 0.3s;`
208
+ if (otherCols.length === 1) {
209
+ const mainCol = otherCols[0]
210
+ mainCol.style.cssText = `
211
+ flex: 1 1 auto !important;
212
+ max-width: calc(${this.totalWidth} - ${drawerWidth}px) !important;
213
+ transition: all 0.3s;`
214
+ }
215
+ } else {
216
+ // percent模式:使用百分比宽度(原有逻辑)
217
+ const drawerWidth = (this.expandedWidthPercent || 33.3)
218
+ currentCol.style.cssText = `
219
+ flex: 0 0 ${drawerWidth}% !important;
220
+ max-width: ${drawerWidth}% !important;
175
221
  transition: all 0.3s;`
222
+ if (otherCols.length === 1) {
223
+ const mainCol = otherCols[0]
224
+ const mainWidth = Math.max(0, Math.min(this.totalWidth, 100) - drawerWidth)
225
+ mainCol.style.cssText = `
226
+ flex: 0 0 ${mainWidth}% !important;
227
+ max-width: ${mainWidth}% !important;
228
+ transition: all 0.3s;`
229
+ }
176
230
  }
177
231
  } else {
178
232
  // 恢复默认(移除我们加的内联样式)
@@ -186,16 +240,16 @@ export default {
186
240
  }
187
241
  triggerResize()
188
242
  } else {
189
- // 收缩:为了消除空白,始终把侧栏压到 24px,并让相邻主列占满剩余
243
+ // 收缩:为了消除空白,始终把侧栏压到 26px,并让相邻主列占满剩余
190
244
  currentCol.style.cssText = `
191
- flex: 0 0 24px !important;
192
- max-width: 24px !important;
193
- transition: all 0.3s;`
245
+ flex: 0 0 26px !important;
246
+ max-width: 26px !important;
247
+ transition: all 0.3s;`
194
248
  if (otherCols.length === 1) {
195
249
  const mainCol = otherCols[0]
196
250
  mainCol.style.cssText = `
197
251
  flex: 1 1 auto !important;
198
- max-width: calc(100% - 24px) !important;
252
+ max-width: calc(100% - 26px) !important;
199
253
  transition: all 0.3s;`
200
254
  }
201
255
  triggerResize()
@@ -226,6 +280,39 @@ export default {
226
280
  computed: {
227
281
  isFrameConfig () {
228
282
  return this.queryParamsName?.endsWith('Frame') || false
283
+ },
284
+ drawerStyle () {
285
+ const isPx = this.widthMode === 'px'
286
+ if (!this.isOpen) {
287
+ // collapsed width
288
+ return isPx
289
+ ? { width: `${this.collapsedWidth}px` }
290
+ : { width: `${this.collapsedWidthPercent}%` }
291
+ }
292
+ // expanded width for the whole drawer wrapper
293
+ return isPx
294
+ ? { width: `${this.expandedWidth}px`, display: 'flex', flexDirection: 'row', alignItems: 'stretch' }
295
+ : { width: `${this.expandedWidthPercent}%`, display: 'flex', flexDirection: 'row', alignItems: 'stretch' }
296
+ },
297
+ contentStyle () {
298
+ const isPx = this.widthMode === 'px'
299
+ if (!this.isOpen) return { display: 'none' }
300
+ if (isPx) {
301
+ const contentWidth = Math.max(0, (this.expandedWidth || 0) - (this.collapsedWidth || 0))
302
+ return { width: `${contentWidth}px`, flex: '1 1 auto', overflow: 'hidden' }
303
+ }
304
+ const contentPercent = Math.max(0, (this.expandedWidthPercent || 0) - (this.collapsedWidthPercent || 0))
305
+ return { width: `${contentPercent}%`, flex: '1 1 auto', overflow: 'hidden' }
306
+ },
307
+ toggleStyle () {
308
+ // 在展开时让切换按钮参与flex布局,避免与内容重叠;收起时保持绝对定位
309
+ const isPx = this.widthMode === 'px'
310
+ if (this.isOpen) {
311
+ return isPx
312
+ ? { position: 'relative', left: '0', zIndex: 1, flex: `0 0 ${this.collapsedWidth}px`, width: `${this.collapsedWidth}px` }
313
+ : { position: 'relative', left: '0', zIndex: 1, flex: `0 0 ${this.collapsedWidthPercent}%`, width: `${this.collapsedWidthPercent}%` }
314
+ }
315
+ return { left: '0' }
229
316
  }
230
317
  }
231
318
  }
@@ -243,14 +330,14 @@ export default {
243
330
  }
244
331
 
245
332
  .drawer-collapsed {
246
- width: 24px;
333
+ width: 26px;
247
334
  box-shadow: none;
248
335
  }
249
336
  .drawer-toggle {
250
337
  position: absolute;
251
338
  top: 50%;
252
339
  transform: translateY(-50%);
253
- width: 24px;
340
+ width: 26px;
254
341
  height: 48px;
255
342
  cursor: pointer;
256
343
  background-color: rgba(255, 255, 255, 0) !important;
@@ -279,5 +366,6 @@ export default {
279
366
  }
280
367
  .drawer-content {
281
368
  height: 100%;
369
+ padding-right: 12px;
282
370
  }
283
371
  </style>
@@ -27,6 +27,11 @@ const props = defineProps({
27
27
  queryParamsName: {
28
28
  type: String,
29
29
  default: ''
30
+ },
31
+ // 新增:直接设置标题文本,优先级高于queryParamsName
32
+ title: {
33
+ type: String,
34
+ default: ''
30
35
  }
31
36
  })
32
37
 
@@ -75,6 +80,17 @@ const handleClick = () => {
75
80
  }
76
81
 
77
82
  const parseConfig = (data) => {
83
+ // 如果设置了title属性,直接使用title作为标签
84
+ if (props.title) {
85
+ config.value.label = props.title
86
+ config.value.type = 'title'
87
+ config.value.line = ''
88
+ config.value.color = ''
89
+ config.value.lineLength = ''
90
+ config.value.clickName = ''
91
+ return
92
+ }
93
+
78
94
  if (!data) return
79
95
 
80
96
  const parts = data.includes('-') ? data.split('-') : data === 'line' ? ['', 'title', 'line'] : [data]
@@ -1,113 +1,113 @@
1
- <template>
2
- <!-- 根据实际部署环境修改 editor.html 的路径 -->
3
- <iframe
4
- src="/his/editor/editor.html"
5
- width="100%"
6
- height="800"
7
- frameborder="0"
8
- @load="onIframeLoad"
9
- ref="editorIframe">
10
- </iframe>
11
- </template>
12
-
13
- <script setup>
14
-
15
- import { ref, onBeforeUnmount } from 'vue'
16
-
17
- const editorIframe = ref(null)
18
- const checkEditorTimer = ref(null)
19
- const checkCount = ref(0)
20
- const editor = ref(null)
21
- const iframeWindow = ref(null)
22
- // 对外暴露的获取editor方法
23
- const getEditor = () => {
24
- if (editor.value) {
25
- return editor.value
26
- }
27
- if (iframeWindow.value && iframeWindow.value.editor) {
28
- editor.value = iframeWindow.value.editor
29
- return editor.value
30
- }
31
- if (editorIframe.value && editorIframe.value.contentWindow && editorIframe.value.contentWindow.editor) {
32
- editor.value = editorIframe.value.contentWindow.editor
33
- return editor.value
34
- }
35
- return null
36
- }
37
- // 创建体温单方法
38
- const createVitalSigns = (data) => {
39
- const editorObj = getEditor()
40
- if (!editorObj) {
41
- throw new Error('editor对象未初始化,无法创建体温单')
42
- }
43
- if (typeof editorObj.createVitalSigns === 'function') {
44
- return editorObj.createVitalSigns(data)
45
- } else {
46
- throw new Error('editor对象未包含createVitalSigns方法')
47
- }
48
- }
49
-
50
- // 检查editor对象是否已初始化
51
- const startEditorCheck = (frameWindow, iframe) => {
52
- if (checkEditorTimer.value) {
53
- clearInterval(checkEditorTimer.value)
54
- }
55
- checkCount.value = 0
56
- checkEditorTimer.value = setInterval(() => {
57
- checkCount.value++
58
- try {
59
- const editorObj = frameWindow.editor
60
- if (editorObj && typeof editorObj.createVitalSigns === 'function') {
61
- clearInterval(checkEditorTimer.value)
62
- editor.value = editorObj
63
- // 将editor对象暴露到全局
64
- window.iframeEditor = editorObj
65
- window.iframeWindow = frameWindow
66
- // 触发事件
67
- emit('editor-ready', editorObj)
68
- emit('load', { target: iframe, editor: editorObj })
69
- // 发送消息通知
70
- window.parent.postMessage({ type: 'editorReady' }, '*')
71
- }
72
- } catch (err) {
73
- console.error('检查editor对象时出错:', err)
74
- }
75
- if (checkCount.value >= 20) {
76
- clearInterval(checkEditorTimer.value)
77
- console.error('Editor 对象加载失败')
78
- }
79
- }, 500)
80
- }
81
- // iframe加载完成的处理
82
- const onIframeLoad = (e) => {
83
- const iframe = e.target
84
- const frameWindow = iframe.contentWindow
85
- iframeWindow.value = frameWindow
86
- if (!frameWindow) {
87
- console.error('无法访问 iframe 内容')
88
- return
89
- }
90
- // 关闭文书工具栏
91
- iframe.contentWindow.editor.option.toolbar = false
92
- startEditorCheck(frameWindow, iframe)
93
- }
94
- // 组件销毁前清理
95
- onBeforeUnmount(() => {
96
- if (checkEditorTimer.value) {
97
- clearInterval(checkEditorTimer.value)
98
- }
99
- })
100
- // 暴露方法给父组件
101
- defineExpose({ getEditor, createVitalSigns })
102
-
103
- // 定义事件
104
- const emit = defineEmits(['editor-ready', 'load'])
105
- </script>
106
-
107
- <style scoped>
108
- iframe {
109
- border: none;
110
- width: 100%;
111
- min-height: 800px;
112
- }
113
- </style>
1
+ <template>
2
+ <!-- 根据实际部署环境修改 editor.html 的路径 -->
3
+ <iframe
4
+ src="/his/editor/editor.html"
5
+ width="100%"
6
+ height="800"
7
+ frameborder="0"
8
+ @load="onIframeLoad"
9
+ ref="editorIframe">
10
+ </iframe>
11
+ </template>
12
+
13
+ <script setup>
14
+
15
+ import { ref, onBeforeUnmount } from 'vue'
16
+
17
+ const editorIframe = ref(null)
18
+ const checkEditorTimer = ref(null)
19
+ const checkCount = ref(0)
20
+ const editor = ref(null)
21
+ const iframeWindow = ref(null)
22
+ // 对外暴露的获取editor方法
23
+ const getEditor = () => {
24
+ if (editor.value) {
25
+ return editor.value
26
+ }
27
+ if (iframeWindow.value && iframeWindow.value.editor) {
28
+ editor.value = iframeWindow.value.editor
29
+ return editor.value
30
+ }
31
+ if (editorIframe.value && editorIframe.value.contentWindow && editorIframe.value.contentWindow.editor) {
32
+ editor.value = editorIframe.value.contentWindow.editor
33
+ return editor.value
34
+ }
35
+ return null
36
+ }
37
+ // 创建体温单方法
38
+ const createVitalSigns = (data) => {
39
+ const editorObj = getEditor()
40
+ if (!editorObj) {
41
+ throw new Error('editor对象未初始化,无法创建体温单')
42
+ }
43
+ if (typeof editorObj.createVitalSigns === 'function') {
44
+ return editorObj.createVitalSigns(data)
45
+ } else {
46
+ throw new Error('editor对象未包含createVitalSigns方法')
47
+ }
48
+ }
49
+
50
+ // 检查editor对象是否已初始化
51
+ const startEditorCheck = (frameWindow, iframe) => {
52
+ if (checkEditorTimer.value) {
53
+ clearInterval(checkEditorTimer.value)
54
+ }
55
+ checkCount.value = 0
56
+ checkEditorTimer.value = setInterval(() => {
57
+ checkCount.value++
58
+ try {
59
+ const editorObj = frameWindow.editor
60
+ if (editorObj && typeof editorObj.createVitalSigns === 'function') {
61
+ clearInterval(checkEditorTimer.value)
62
+ editor.value = editorObj
63
+ // 将editor对象暴露到全局
64
+ window.iframeEditor = editorObj
65
+ window.iframeWindow = frameWindow
66
+ // 触发事件
67
+ emit('editor-ready', editorObj)
68
+ emit('load', { target: iframe, editor: editorObj })
69
+ // 发送消息通知
70
+ window.parent.postMessage({ type: 'editorReady' }, '*')
71
+ }
72
+ } catch (err) {
73
+ console.error('检查editor对象时出错:', err)
74
+ }
75
+ if (checkCount.value >= 20) {
76
+ clearInterval(checkEditorTimer.value)
77
+ console.error('Editor 对象加载失败')
78
+ }
79
+ }, 500)
80
+ }
81
+ // iframe加载完成的处理
82
+ const onIframeLoad = (e) => {
83
+ const iframe = e.target
84
+ const frameWindow = iframe.contentWindow
85
+ iframeWindow.value = frameWindow
86
+ if (!frameWindow) {
87
+ console.error('无法访问 iframe 内容')
88
+ return
89
+ }
90
+ // 关闭文书工具栏
91
+ iframe.contentWindow.editor.option.toolbar = false
92
+ startEditorCheck(frameWindow, iframe)
93
+ }
94
+ // 组件销毁前清理
95
+ onBeforeUnmount(() => {
96
+ if (checkEditorTimer.value) {
97
+ clearInterval(checkEditorTimer.value)
98
+ }
99
+ })
100
+ // 暴露方法给父组件
101
+ defineExpose({ getEditor, createVitalSigns })
102
+
103
+ // 定义事件
104
+ const emit = defineEmits(['editor-ready', 'load'])
105
+ </script>
106
+
107
+ <style scoped>
108
+ iframe {
109
+ border: none;
110
+ width: 100%;
111
+ min-height: 800px;
112
+ }
113
+ </style>
@@ -1,45 +1,45 @@
1
- <script>
2
- export default {
3
- name: 'ExceptionQuery',
4
- components: {
5
- XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue')
6
- },
7
- props: {
8
- currUserInfo: {
9
- type: Object,
10
- default: () => undefined
11
- }
12
- },
13
- mounted () {
14
- this.$refs.xFormTable.refresh(true)
15
- },
16
- data () {
17
- return {
18
- // 查询配置名称
19
- queryParamsName: 'ExceptionRecordQueryCRUD',
20
- fixedQueryForm: { ex_f_userfiles_id: this.currUserInfo.f_userfiles_id },
21
- // 新增表单固定值
22
- fixedAddForm: {},
23
- // 是否显示详情抽屉
24
- detailVisible: false,
25
- // 当前记录
26
- record: {}
27
- }
28
- }
29
- }
30
- </script>
31
-
32
- <template>
33
- <a-card :bordered="false">
34
- <x-form-table
35
- title="异常查询"
36
- :queryParamsName="queryParamsName"
37
- :fixedQueryForm="fixedQueryForm"
38
- ref="xFormTable">
39
- </x-form-table>
40
- </a-card>
41
- </template>
42
-
43
- <style scoped>
44
-
45
- </style>
1
+ <script>
2
+ export default {
3
+ name: 'ExceptionQuery',
4
+ components: {
5
+ XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue')
6
+ },
7
+ props: {
8
+ currUserInfo: {
9
+ type: Object,
10
+ default: () => undefined
11
+ }
12
+ },
13
+ mounted () {
14
+ this.$refs.xFormTable.refresh(true)
15
+ },
16
+ data () {
17
+ return {
18
+ // 查询配置名称
19
+ queryParamsName: 'ExceptionRecordQueryCRUD',
20
+ fixedQueryForm: { ex_f_userfiles_id: this.currUserInfo.f_userfiles_id },
21
+ // 新增表单固定值
22
+ fixedAddForm: {},
23
+ // 是否显示详情抽屉
24
+ detailVisible: false,
25
+ // 当前记录
26
+ record: {}
27
+ }
28
+ }
29
+ }
30
+ </script>
31
+
32
+ <template>
33
+ <a-card :bordered="false">
34
+ <x-form-table
35
+ title="异常查询"
36
+ :queryParamsName="queryParamsName"
37
+ :fixedQueryForm="fixedQueryForm"
38
+ ref="xFormTable">
39
+ </x-form-table>
40
+ </a-card>
41
+ </template>
42
+
43
+ <style scoped>
44
+
45
+ </style>