vue2-client 1.14.16 → 1.14.18
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.
- package/package.json +1 -1
- package/src/base-client/components/common/FormGroupEdit/FormGroupEdit.vue +0 -1
- package/src/base-client/components/common/XForm/XFormItem.vue +9 -0
- package/src/base-client/components/common/XFormTable/demo.vue +1 -2
- package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +4 -3
- package/src/base-client/components/his/threeTestOrders/editor.vue +111 -0
- package/src/base-client/components/his/threeTestOrders/textBox.vue +526 -0
- package/src/base-client/components/his/threeTestOrders/threeTestOrders.vue +181 -0
- package/src/pages/userInfoDetailManage/index.vue +2 -2
- package/src/utils/routerUtil.js +6 -1
package/package.json
CHANGED
|
@@ -221,6 +221,7 @@
|
|
|
221
221
|
:label="showLabel?attr.name:undefined"
|
|
222
222
|
:prop="attr.prop ? attr.prop : attr.model">
|
|
223
223
|
<a-select
|
|
224
|
+
class="multiple_select"
|
|
224
225
|
style="width:100%"
|
|
225
226
|
v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
|
|
226
227
|
v-model="form[attr.model]"
|
|
@@ -262,6 +263,7 @@
|
|
|
262
263
|
</a-select>
|
|
263
264
|
<a-select
|
|
264
265
|
v-else
|
|
266
|
+
class="multiple_select"
|
|
265
267
|
v-model="form[attr.model]"
|
|
266
268
|
:disabled="disabled"
|
|
267
269
|
:filter-option="filterOption"
|
|
@@ -1308,4 +1310,11 @@ export default {
|
|
|
1308
1310
|
position: absolute;
|
|
1309
1311
|
z-index: 1050;
|
|
1310
1312
|
}
|
|
1313
|
+
.multiple_select {
|
|
1314
|
+
:deep(.ant-select-selection){
|
|
1315
|
+
max-height: 32px;
|
|
1316
|
+
overflow-y: scroll;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1311
1320
|
</style>
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
<x-form-table
|
|
7
7
|
title="示例表单"
|
|
8
8
|
:queryParamsName="queryParamsName"
|
|
9
|
-
:x-tree-config-name="xTreeConfigName"
|
|
10
9
|
:fixedAddForm="fixedAddForm"
|
|
11
10
|
@action="action"
|
|
12
11
|
@columnClick="columnClick"
|
|
@@ -27,7 +26,7 @@ export default {
|
|
|
27
26
|
data () {
|
|
28
27
|
return {
|
|
29
28
|
// 查询配置文件名
|
|
30
|
-
queryParamsName: '
|
|
29
|
+
queryParamsName: 'ChargeQueryCRUD',
|
|
31
30
|
// 查询配置左侧tree
|
|
32
31
|
xTreeConfigName: 'addressType',
|
|
33
32
|
// 新增表单固定值
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
</template>
|
|
26
26
|
<template v-else-if="cell.type === 'slot'">
|
|
27
27
|
<template
|
|
28
|
-
v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse','x-h-descriptions', 'x-sidebar', 'x-list','x-input','x-time-line', 'x-radio','x-calendar', 'x-time-select' ,'x-checkbox', 'x-title', 'x-select', 'x-tree-rows'].includes(cell.slotType)">
|
|
28
|
+
v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse','x-h-descriptions', 'x-sidebar', 'x-list','x-input','x-time-line', 'x-radio','x-calendar', 'x-time-select' ,'x-checkbox', 'x-title', 'x-select', 'x-tree-rows', 'x-three-test-orders'].includes(cell.slotType)">
|
|
29
29
|
<component
|
|
30
30
|
:is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
|
|
31
31
|
:key="cellIndex"
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
</template>
|
|
64
64
|
<template v-else-if="cell.type === 'slot'">
|
|
65
65
|
<template
|
|
66
|
-
v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse', 'x-h-descriptions', 'x-sidebar', 'x-list','x-input','x-time-line', 'x-radio','x-calendar', 'x-time-select','x-checkbox', 'x-title', 'x-select', 'x-tree-rows'].includes(cell.slotType)">
|
|
66
|
+
v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse', 'x-h-descriptions', 'x-sidebar', 'x-list','x-input','x-time-line', 'x-radio','x-calendar', 'x-time-select','x-checkbox', 'x-title', 'x-select', 'x-tree-rows', 'x-three-test-orders'].includes(cell.slotType)">
|
|
67
67
|
<component
|
|
68
68
|
:is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
|
|
69
69
|
:key="cellIndex"
|
|
@@ -123,7 +123,8 @@ export default {
|
|
|
123
123
|
XCheckbox: () => import('@vue2-client/base-client/components/his/XCheckbox/XCheckbox.vue'),
|
|
124
124
|
XTitle: () => import('@vue2-client/base-client/components/his/XTitle/XTitle.vue'),
|
|
125
125
|
XSelect: () => import('@vue2-client/base-client/components/his/XSelect/XSelect.vue'),
|
|
126
|
-
XTreeRows: () => import('@vue2-client/base-client/components/his/XTreeRows/XTreeRows.vue')
|
|
126
|
+
XTreeRows: () => import('@vue2-client/base-client/components/his/XTreeRows/XTreeRows.vue'),
|
|
127
|
+
XThreeTestOrders: () => import('@vue2-client/base-client/components/his/threeTestOrders/threeTestOrders.vue')
|
|
127
128
|
},
|
|
128
129
|
props: {
|
|
129
130
|
// 每一行的配置
|
|
@@ -0,0 +1,111 @@
|
|
|
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
|
+
startEditorCheck(frameWindow, iframe)
|
|
91
|
+
}
|
|
92
|
+
// 组件销毁前清理
|
|
93
|
+
onBeforeUnmount(() => {
|
|
94
|
+
if (checkEditorTimer.value) {
|
|
95
|
+
clearInterval(checkEditorTimer.value)
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
// 暴露方法给父组件
|
|
99
|
+
defineExpose({ getEditor, createVitalSigns })
|
|
100
|
+
|
|
101
|
+
// 定义事件
|
|
102
|
+
const emit = defineEmits(['editor-ready', 'load'])
|
|
103
|
+
</script>
|
|
104
|
+
|
|
105
|
+
<style scoped>
|
|
106
|
+
iframe {
|
|
107
|
+
border: none;
|
|
108
|
+
width: 100%;
|
|
109
|
+
min-height: 800px;
|
|
110
|
+
}
|
|
111
|
+
</style>
|
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, reactive, watch } from 'vue'
|
|
3
|
+
import { message } from 'ant-design-vue'
|
|
4
|
+
import { runLogic } from '@/services/api/common'
|
|
5
|
+
|
|
6
|
+
// 定义组件属性
|
|
7
|
+
const props = defineProps({
|
|
8
|
+
visible: Boolean,
|
|
9
|
+
id: {
|
|
10
|
+
type: String,
|
|
11
|
+
default: '180'
|
|
12
|
+
},
|
|
13
|
+
modalType: {
|
|
14
|
+
type: String,
|
|
15
|
+
default: 'create',
|
|
16
|
+
validator: (value) => ['create', 'update', 'baby'].includes(value)
|
|
17
|
+
},
|
|
18
|
+
initialId: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: ''
|
|
21
|
+
},
|
|
22
|
+
editorReady: {
|
|
23
|
+
type: Boolean,
|
|
24
|
+
default: false
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
// 定义组件事件
|
|
29
|
+
const emit = defineEmits(['update:visible', 'submit', 'cancel'])
|
|
30
|
+
|
|
31
|
+
// 常量
|
|
32
|
+
const modalTitles = {
|
|
33
|
+
create: '创建体温单',
|
|
34
|
+
update: '更新体温单',
|
|
35
|
+
baby: '新生儿体温单'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 响应式状态
|
|
39
|
+
const submitLoading = ref(false)
|
|
40
|
+
const formErrors = ref({})
|
|
41
|
+
|
|
42
|
+
// 表单数据
|
|
43
|
+
const formData = reactive({
|
|
44
|
+
id: '',
|
|
45
|
+
name: '',
|
|
46
|
+
inDate: '',
|
|
47
|
+
diag: '',
|
|
48
|
+
dept: '',
|
|
49
|
+
bed: '',
|
|
50
|
+
medicalNo: '',
|
|
51
|
+
begin: '',
|
|
52
|
+
operateDate: '',
|
|
53
|
+
notes: '',
|
|
54
|
+
sex: '男',
|
|
55
|
+
weight: '',
|
|
56
|
+
heart: '',
|
|
57
|
+
tempType: '',
|
|
58
|
+
temperature: '',
|
|
59
|
+
breath: '',
|
|
60
|
+
sphygmus: '',
|
|
61
|
+
physicalcool: '',
|
|
62
|
+
labels: '',
|
|
63
|
+
data1: '',
|
|
64
|
+
data2: '',
|
|
65
|
+
data3: '',
|
|
66
|
+
data4: '',
|
|
67
|
+
data5: '',
|
|
68
|
+
data6: '',
|
|
69
|
+
data7: '',
|
|
70
|
+
data8: '',
|
|
71
|
+
data9: '',
|
|
72
|
+
pain: ''
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
// 监听 props 变化初始化表单
|
|
76
|
+
watch(() => props.visible, (newVal, oldVal) => {
|
|
77
|
+
if (newVal) {
|
|
78
|
+
// 如果是从关闭状态变为打开状态,重置表单错误
|
|
79
|
+
formErrors.value = {}
|
|
80
|
+
|
|
81
|
+
// 无论何种模式,都先尝试从服务加载数据
|
|
82
|
+
initFormData()
|
|
83
|
+
} else if (oldVal && !newVal) {
|
|
84
|
+
// 当弹窗关闭时,清空表单数据,为下次打开做准备
|
|
85
|
+
resetForm()
|
|
86
|
+
}
|
|
87
|
+
}, { immediate: true })
|
|
88
|
+
|
|
89
|
+
watch(() => props.modalType, (newVal) => {
|
|
90
|
+
if (props.visible) {
|
|
91
|
+
// 无论何种模式,都先尝试从服务加载数据
|
|
92
|
+
initFormData()
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
watch(() => props.initialId, (newVal) => {
|
|
97
|
+
if (newVal) {
|
|
98
|
+
formData.id = newVal
|
|
99
|
+
}
|
|
100
|
+
}, { immediate: true })
|
|
101
|
+
|
|
102
|
+
// 重置表单为默认值
|
|
103
|
+
const resetForm = () => {
|
|
104
|
+
// 清空表单错误
|
|
105
|
+
formErrors.value = {}
|
|
106
|
+
|
|
107
|
+
const today = new Date().toISOString().split('T')[0]
|
|
108
|
+
const isBaby = props.modalType === 'baby'
|
|
109
|
+
|
|
110
|
+
// 重置所有字段
|
|
111
|
+
formData.id = props.initialId || (isBaby ? `BY${Date.now()}` : `VS${Date.now()}`)
|
|
112
|
+
formData.name = ''
|
|
113
|
+
formData.inDate = today
|
|
114
|
+
formData.diag = ''
|
|
115
|
+
formData.dept = isBaby ? '妇产科' : ''
|
|
116
|
+
formData.bed = ''
|
|
117
|
+
formData.medicalNo = ''
|
|
118
|
+
formData.begin = today
|
|
119
|
+
formData.operateDate = ''
|
|
120
|
+
formData.notes = isBaby ? '出生-十时二十分' : '入院-十时二十分,,转入ICU,,,,,,,手术,,,,,,,,,,,,,,,出院,死亡于×时×分'
|
|
121
|
+
formData.sex = '男'
|
|
122
|
+
formData.weight = isBaby ? '3200,,,,3300,,,,3400,,,,3400,,,,3500,,,,3400,,,,' : ''
|
|
123
|
+
formData.heart = '112,120,118,111,,,,,,,112,120,118,111'
|
|
124
|
+
formData.tempType = isBaby
|
|
125
|
+
? '2,2,2,3,2,1,2,2,2,1,2,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1'
|
|
126
|
+
: '0,1,2,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1'
|
|
127
|
+
formData.temperature = isBaby
|
|
128
|
+
? '37.7,37.9,38.5,37.1,37.5,38.5,,,37.5,38.5,37.4,37.8,,37.5,37.6,37.8,,37.9,37.8,37.5,38.6,37.8,,37.9,37.8'
|
|
129
|
+
: '38.7,38.9,38.5,39.1,38.5,38.5|37.1,38.5,38.5,,,38.5,38.5|36.9,38.4,38.8,,38.5,38.6,38.8,,38.9,38.8,38.5,38.6,38.8,,38.9,38.8,34,34.0'
|
|
130
|
+
formData.physicalcool = isBaby ? ',,,37.6,,,,,,,,37.5,,,,,,,,,37.4,,' : ''
|
|
131
|
+
formData.breath = '30,30,R,,35,35,35,35,35,35,35,35,,R,R,35,35,,R,,,35,35,,R'
|
|
132
|
+
formData.sphygmus = '112,110,109,103,108,85,90,83,90,103,108,85,90,83,90,,90,83,90,103,108,85,90,83,90'
|
|
133
|
+
formData.labels = isBaby
|
|
134
|
+
? '血压(mmHg)|入水量(ml)|出水量(ml)|大便(次)|小便(次)'
|
|
135
|
+
: '血压(mmHg)|入水量(ml)|出水量(ml)|大便(次)|小便(次)|身高(cm)|体重(kg)|过敏药'
|
|
136
|
+
formData.data1 = '120/85,121/84,,110/75,'
|
|
137
|
+
formData.data2 = '1180ml,,,500ml,,40ml'
|
|
138
|
+
formData.data3 = '500ml,,,,500ml,,67ml'
|
|
139
|
+
formData.data4 = '2,4,5,3,3,3,2,,2'
|
|
140
|
+
formData.data5 = '2,4,5,3,3,3,2,,2'
|
|
141
|
+
formData.data6 = '167cm,,,,,,,,,164cm'
|
|
142
|
+
formData.data7 = '95kg,,,,,90kg'
|
|
143
|
+
formData.data8 = '青霉素,'
|
|
144
|
+
formData.data9 = '测试,'
|
|
145
|
+
formData.pain = '2,2,4,5,8,8,9|2,6|3,,,4,4,4'
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 处理JSON字符串数据
|
|
149
|
+
const parseFormData = (data) => {
|
|
150
|
+
if (!data) return null
|
|
151
|
+
try {
|
|
152
|
+
// 如果是字符串,尝试解析为JSON
|
|
153
|
+
if (typeof data === 'string') {
|
|
154
|
+
return JSON.parse(data)
|
|
155
|
+
}
|
|
156
|
+
// 如果已经是对象且有f_data字段,尝试解析f_data
|
|
157
|
+
if (typeof data === 'object' && data.f_data) {
|
|
158
|
+
return JSON.parse(data.f_data)
|
|
159
|
+
}
|
|
160
|
+
// 如果是普通对象,直接返回
|
|
161
|
+
return data
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error('解析数据失败:', error)
|
|
164
|
+
return null
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 初始化表单数据
|
|
169
|
+
const initFormData = async () => {
|
|
170
|
+
try {
|
|
171
|
+
let parsedData = null
|
|
172
|
+
let resultData = null
|
|
173
|
+
try {
|
|
174
|
+
// 尝试从服务器获取数据
|
|
175
|
+
resultData = await runLogic('threeTestOrderDataLOGIC', { id: props.id }, 'af-his')
|
|
176
|
+
console.log('体温单数据 = ', resultData)
|
|
177
|
+
// 处理不同格式的返回数据
|
|
178
|
+
if (resultData) {
|
|
179
|
+
// 如果是数组,取第一项
|
|
180
|
+
if (Array.isArray(resultData) && resultData.length > 0) {
|
|
181
|
+
const firstItem = resultData[0]
|
|
182
|
+
|
|
183
|
+
// 检查是否有f_data字段
|
|
184
|
+
if (firstItem.f_data) {
|
|
185
|
+
parsedData = parseFormData(firstItem.f_data)
|
|
186
|
+
} else {
|
|
187
|
+
// 可能整个对象就是数据
|
|
188
|
+
parsedData = firstItem
|
|
189
|
+
}
|
|
190
|
+
} else if (typeof resultData === 'object') {
|
|
191
|
+
if (resultData.f_data) {
|
|
192
|
+
parsedData = parseFormData(resultData.f_data)
|
|
193
|
+
} else { parsedData = resultData }
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.error('获取数据失败:', error)
|
|
198
|
+
}
|
|
199
|
+
// 如果解析成功且非创建模式,填充表单
|
|
200
|
+
if (parsedData && props.modalType !== 'create') {
|
|
201
|
+
console.log('解析后的数据:', parsedData)
|
|
202
|
+
// 将解析后的数据填充到表单中
|
|
203
|
+
Object.keys(parsedData).forEach(key => {
|
|
204
|
+
if (key in formData) {
|
|
205
|
+
formData[key] = parsedData[key]
|
|
206
|
+
}
|
|
207
|
+
})
|
|
208
|
+
// 确保formData.id是正确设置的
|
|
209
|
+
if (!formData.id && parsedData.id) {
|
|
210
|
+
formData.id = parsedData.id
|
|
211
|
+
}
|
|
212
|
+
return
|
|
213
|
+
} else if (props.modalType === 'create') {
|
|
214
|
+
// 创建模式下重置表单
|
|
215
|
+
resetForm()
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error('初始化表单数据失败:', error)
|
|
220
|
+
message.error('体温单数据加载失败,将使用默认值')
|
|
221
|
+
}
|
|
222
|
+
// 如果没有数据或解析失败,使用默认值
|
|
223
|
+
resetForm()
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 关闭弹窗
|
|
227
|
+
const closeModal = () => {
|
|
228
|
+
// 关闭弹窗前清空表单数据
|
|
229
|
+
resetForm()
|
|
230
|
+
emit('update:visible', false)
|
|
231
|
+
emit('cancel')
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// 验证表单
|
|
235
|
+
const validateForm = () => {
|
|
236
|
+
const isBaby = props.modalType === 'baby'
|
|
237
|
+
const errors = {}
|
|
238
|
+
let hasError = false
|
|
239
|
+
// 通用字段验证
|
|
240
|
+
const requiredFields = [
|
|
241
|
+
{ key: 'id', label: 'ID' },
|
|
242
|
+
{ key: 'name', label: '姓名' },
|
|
243
|
+
{ key: 'inDate', label: '入院日期' },
|
|
244
|
+
{ key: 'dept', label: '科室' },
|
|
245
|
+
{ key: 'bed', label: '床位' },
|
|
246
|
+
{ key: 'medicalNo', label: '病历号' },
|
|
247
|
+
{ key: 'begin', label: '开始日期' },
|
|
248
|
+
{ key: 'notes', label: '备注' },
|
|
249
|
+
{ key: 'heart', label: '心率' },
|
|
250
|
+
{ key: 'tempType', label: '体温类型' },
|
|
251
|
+
{ key: 'temperature', label: '体温' },
|
|
252
|
+
{ key: 'breath', label: '呼吸' },
|
|
253
|
+
{ key: 'labels', label: '标签' },
|
|
254
|
+
{ key: 'data1', label: '血压' },
|
|
255
|
+
{ key: 'data2', label: '入水量' },
|
|
256
|
+
{ key: 'data3', label: '出水量' },
|
|
257
|
+
{ key: 'data4', label: '大便次数' },
|
|
258
|
+
{ key: 'data5', label: '小便次数' }
|
|
259
|
+
]
|
|
260
|
+
// 成人特有字段
|
|
261
|
+
if (!isBaby) {
|
|
262
|
+
requiredFields.push(
|
|
263
|
+
{ key: 'diag', label: '诊断' },
|
|
264
|
+
{ key: 'operateDate', label: '手术日期' },
|
|
265
|
+
{ key: 'sphygmus', label: '脉搏' },
|
|
266
|
+
{ key: 'data6', label: '身高' },
|
|
267
|
+
{ key: 'data7', label: '体重' },
|
|
268
|
+
{ key: 'data8', label: '过敏药' },
|
|
269
|
+
{ key: 'data9', label: '其他数据' }
|
|
270
|
+
)
|
|
271
|
+
} else {
|
|
272
|
+
// 婴儿特有字段
|
|
273
|
+
requiredFields.push(
|
|
274
|
+
{ key: 'weight', label: '体重' },
|
|
275
|
+
{ key: 'physicalcool', label: '物理降温' }
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
// 检查每个必填字段
|
|
279
|
+
requiredFields.forEach(field => {
|
|
280
|
+
// 首先检查字段是否存在
|
|
281
|
+
if (formData[field.key] === undefined || formData[field.key] === null) {
|
|
282
|
+
errors[field.key] = `${field.label}不能为空`
|
|
283
|
+
hasError = true
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
// 将值转换为字符串后再检查是否为空
|
|
287
|
+
const value = String(formData[field.key])
|
|
288
|
+
if (value.trim() === '') {
|
|
289
|
+
errors[field.key] = `${field.label}不能为空`
|
|
290
|
+
hasError = true
|
|
291
|
+
}
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
formErrors.value = errors
|
|
295
|
+
if (hasError) {
|
|
296
|
+
message.error('表单验证失败,请填写所有必填项')
|
|
297
|
+
return false
|
|
298
|
+
}
|
|
299
|
+
return true
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 获取表单数据
|
|
303
|
+
const getFormData = () => {
|
|
304
|
+
const isBaby = props.modalType === 'baby'
|
|
305
|
+
const commonData = {
|
|
306
|
+
id: formData.id || `${isBaby ? 'BY' : 'VS'}${Date.now()}`,
|
|
307
|
+
name: formData.name,
|
|
308
|
+
inDate: formData.inDate,
|
|
309
|
+
dept: formData.dept,
|
|
310
|
+
bed: formData.bed,
|
|
311
|
+
medicalNo: formData.medicalNo,
|
|
312
|
+
begin: formData.begin,
|
|
313
|
+
notes: formData.notes,
|
|
314
|
+
heart: formData.heart,
|
|
315
|
+
tempType: formData.tempType,
|
|
316
|
+
temperature: formData.temperature,
|
|
317
|
+
breath: formData.breath,
|
|
318
|
+
labels: formData.labels,
|
|
319
|
+
data1: formData.data1,
|
|
320
|
+
data2: formData.data2,
|
|
321
|
+
data3: formData.data3,
|
|
322
|
+
data4: formData.data4,
|
|
323
|
+
data5: formData.data5,
|
|
324
|
+
pain: formData.pain
|
|
325
|
+
}
|
|
326
|
+
if (isBaby) {
|
|
327
|
+
return {
|
|
328
|
+
...commonData,
|
|
329
|
+
type: 'baby',
|
|
330
|
+
sex: formData.sex,
|
|
331
|
+
weight: formData.weight,
|
|
332
|
+
physicalcool: formData.physicalcool
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
...commonData,
|
|
337
|
+
diag: formData.diag,
|
|
338
|
+
operateDate: formData.operateDate,
|
|
339
|
+
sphygmus: formData.sphygmus,
|
|
340
|
+
data6: formData.data6,
|
|
341
|
+
data7: formData.data7,
|
|
342
|
+
data8: formData.data8,
|
|
343
|
+
data9: formData.data9
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// 提交表单
|
|
348
|
+
const submitForm = async () => {
|
|
349
|
+
if (!props.editorReady) {
|
|
350
|
+
message.error('体温单编辑器未加载完成,请等待或刷新页面')
|
|
351
|
+
return
|
|
352
|
+
}
|
|
353
|
+
// 首先验证表单
|
|
354
|
+
if (!validateForm()) {
|
|
355
|
+
return
|
|
356
|
+
}
|
|
357
|
+
submitLoading.value = true
|
|
358
|
+
try {
|
|
359
|
+
const data = getFormData()
|
|
360
|
+
emit('submit', data)
|
|
361
|
+
// 关闭弹窗
|
|
362
|
+
closeModal()
|
|
363
|
+
} catch (err) {
|
|
364
|
+
console.error('提交体温单数据出错:', err)
|
|
365
|
+
message.error(`提交体温单数据失败: ${err.message || '未知错误'}`)
|
|
366
|
+
} finally {
|
|
367
|
+
submitLoading.value = false
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
</script>
|
|
371
|
+
|
|
372
|
+
<template>
|
|
373
|
+
<a-modal
|
|
374
|
+
:title="modalTitles[modalType]"
|
|
375
|
+
:visible="visible"
|
|
376
|
+
@cancel="closeModal"
|
|
377
|
+
:width="700"
|
|
378
|
+
:footer="null">
|
|
379
|
+
<a-form :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
380
|
+
<!-- 通用基础信息字段 -->
|
|
381
|
+
<a-form-item label="ID" :validateStatus="formErrors.id ? 'error' : ''" :help="formErrors.id">
|
|
382
|
+
<a-input v-model="formData.id" :placeholder="`请输入ID,如:${modalType === 'baby' ? 'BY' : 'AD'}20230001`" />
|
|
383
|
+
</a-form-item>
|
|
384
|
+
<a-form-item label="姓名" :validateStatus="formErrors.name ? 'error' : ''" :help="formErrors.name">
|
|
385
|
+
<a-input v-model="formData.name" placeholder="请输入姓名,如:张三" />
|
|
386
|
+
</a-form-item>
|
|
387
|
+
<a-form-item label="入院日期" :validateStatus="formErrors.inDate ? 'error' : ''" :help="formErrors.inDate">
|
|
388
|
+
<a-input v-model="formData.inDate" placeholder="请输入日期,如:2023-08-01" />
|
|
389
|
+
</a-form-item>
|
|
390
|
+
<!-- 新生儿特有字段 -->
|
|
391
|
+
<template v-if="modalType === 'baby'">
|
|
392
|
+
<a-form-item label="性别">
|
|
393
|
+
<a-radio-group v-model="formData.sex">
|
|
394
|
+
<a-radio value="男">男</a-radio>
|
|
395
|
+
<a-radio value="女">女</a-radio>
|
|
396
|
+
</a-radio-group>
|
|
397
|
+
</a-form-item>
|
|
398
|
+
</template>
|
|
399
|
+
<!-- 成人特有字段 -->
|
|
400
|
+
<template v-else>
|
|
401
|
+
<a-form-item label="诊断" :validateStatus="formErrors.diag ? 'error' : ''" :help="formErrors.diag">
|
|
402
|
+
<a-input v-model="formData.diag" placeholder="请输入诊断,如:新型冠状病毒肺炎" />
|
|
403
|
+
</a-form-item>
|
|
404
|
+
</template>
|
|
405
|
+
<!-- 通用字段 -->
|
|
406
|
+
<a-form-item label="科室" :validateStatus="formErrors.dept ? 'error' : ''" :help="formErrors.dept">
|
|
407
|
+
<a-input v-model="formData.dept" :placeholder="`请输入科室,如:${modalType === 'baby' ? '妇产科' : '呼吸内科'}`" />
|
|
408
|
+
</a-form-item>
|
|
409
|
+
<a-form-item label="床位" :validateStatus="formErrors.bed ? 'error' : ''" :help="formErrors.bed">
|
|
410
|
+
<a-input v-model="formData.bed" placeholder="请输入床位,如:801" />
|
|
411
|
+
</a-form-item>
|
|
412
|
+
<a-form-item label="病历号" :validateStatus="formErrors.medicalNo ? 'error' : ''" :help="formErrors.medicalNo">
|
|
413
|
+
<a-input v-model="formData.medicalNo" placeholder="请输入病历号,如:202300991" />
|
|
414
|
+
</a-form-item>
|
|
415
|
+
<a-form-item label="开始日期" :validateStatus="formErrors.begin ? 'error' : ''" :help="formErrors.begin">
|
|
416
|
+
<a-input v-model="formData.begin" placeholder="请输入日期,如:2023-08-01" />
|
|
417
|
+
</a-form-item>
|
|
418
|
+
<!-- 成人特有字段 -->
|
|
419
|
+
<template v-if="modalType !== 'baby'">
|
|
420
|
+
<a-form-item label="手术日期" :validateStatus="formErrors.operateDate ? 'error' : ''" :help="formErrors.operateDate">
|
|
421
|
+
<a-input v-model="formData.operateDate" placeholder="请输入日期,如:2023-08-03" />
|
|
422
|
+
</a-form-item>
|
|
423
|
+
</template>
|
|
424
|
+
<!-- 备注字段 -->
|
|
425
|
+
<a-form-item label="备注" :validateStatus="formErrors.notes ? 'error' : ''" :help="formErrors.notes">
|
|
426
|
+
<a-input v-model="formData.notes" :placeholder="`请输入备注,如:${modalType === 'baby' ? '出生-十时二十分' : '入院-十时二十分,,转入ICU,,,,,,,手术'}`" />
|
|
427
|
+
<div class="input-tip">格式:多个值用逗号分隔,对应不同日期</div>
|
|
428
|
+
</a-form-item>
|
|
429
|
+
<!-- 根据表单类型显示不同的数据字段 -->
|
|
430
|
+
<template v-if="modalType !== 'baby'">
|
|
431
|
+
<a-form-item label="脉搏" :validateStatus="formErrors.sphygmus ? 'error' : ''" :help="formErrors.sphygmus">
|
|
432
|
+
<a-input v-model="formData.sphygmus" placeholder="脉搏数据,如:112,110,109,103,108,85" />
|
|
433
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
434
|
+
</a-form-item>
|
|
435
|
+
</template>
|
|
436
|
+
<template v-else>
|
|
437
|
+
<a-form-item label="体重" :validateStatus="formErrors.weight ? 'error' : ''" :help="formErrors.weight">
|
|
438
|
+
<a-input v-model="formData.weight" placeholder="体重数据,多个值用逗号分隔,如:3200,,,,3300,,,,3400" />
|
|
439
|
+
<div class="input-tip">格式:多个值用逗号分隔,每组数据对应一天</div>
|
|
440
|
+
</a-form-item>
|
|
441
|
+
</template>
|
|
442
|
+
<!-- 生命体征数据字段 -->
|
|
443
|
+
<a-form-item label="心率" :validateStatus="formErrors.heart ? 'error' : ''" :help="formErrors.heart">
|
|
444
|
+
<a-input v-model="formData.heart" placeholder="心率数据,多个值用逗号分隔,如:112,120,118,111" />
|
|
445
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
446
|
+
</a-form-item>
|
|
447
|
+
<a-form-item label="体温类型" :validateStatus="formErrors.tempType ? 'error' : ''" :help="formErrors.tempType">
|
|
448
|
+
<a-input v-model="formData.tempType" placeholder="体温类型,如:0,1,2,3,0,1" />
|
|
449
|
+
<div class="input-tip">格式:多个值用逗号分隔,0-3表示不同类型</div>
|
|
450
|
+
</a-form-item>
|
|
451
|
+
<a-form-item label="体温" :validateStatus="formErrors.temperature ? 'error' : ''" :help="formErrors.temperature">
|
|
452
|
+
<a-input v-model="formData.temperature" :placeholder="`体温数据,如:${modalType === 'baby' ? '37.7,37.9,38.5,37.1' : '38.7,38.9,38.5,39.1,38.5,38.5|37.1'}`" />
|
|
453
|
+
<div class="input-tip">格式:多个值用逗号分隔<template v-if="modalType !== 'baby'">,|表示新一行数据</template></div>
|
|
454
|
+
</a-form-item>
|
|
455
|
+
<!-- 新生儿特有字段 -->
|
|
456
|
+
<template v-if="modalType === 'baby'">
|
|
457
|
+
<a-form-item label="物理降温" :validateStatus="formErrors.physicalcool ? 'error' : ''" :help="formErrors.physicalcool">
|
|
458
|
+
<a-input v-model="formData.physicalcool" placeholder="物理降温数据,如:,,,37.6,,,,,,,,37.5" />
|
|
459
|
+
<div class="input-tip">格式:多个值用逗号分隔,空值用逗号表示</div>
|
|
460
|
+
</a-form-item>
|
|
461
|
+
</template>
|
|
462
|
+
<!-- 通用数据字段 -->
|
|
463
|
+
<a-form-item label="呼吸" :validateStatus="formErrors.breath ? 'error' : ''" :help="formErrors.breath">
|
|
464
|
+
<a-input v-model="formData.breath" placeholder="呼吸数据,如:30,30,R,,35,35" />
|
|
465
|
+
<div class="input-tip">格式:多个值用逗号分隔,R表示异常</div>
|
|
466
|
+
</a-form-item>
|
|
467
|
+
<a-form-item label="标签" :validateStatus="formErrors.labels ? 'error' : ''" :help="formErrors.labels">
|
|
468
|
+
<a-input v-model="formData.labels" :placeholder="`标签数据,如:血压(mmHg)|入水量(ml)|出水量(ml)|大便(次)|小便(次)${modalType === 'baby' ? '' : '|身高(cm)|体重(kg)|过敏药'}`" />
|
|
469
|
+
<div class="input-tip">格式:多个标签用|分隔</div>
|
|
470
|
+
</a-form-item>
|
|
471
|
+
<!-- 通用数据字段 -->
|
|
472
|
+
<a-form-item label="血压" :validateStatus="formErrors.data1 ? 'error' : ''" :help="formErrors.data1">
|
|
473
|
+
<a-input v-model="formData.data1" placeholder="血压数据,如:120/85,121/84,,110/75" />
|
|
474
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
475
|
+
</a-form-item>
|
|
476
|
+
<a-form-item label="入水量" :validateStatus="formErrors.data2 ? 'error' : ''" :help="formErrors.data2">
|
|
477
|
+
<a-input v-model="formData.data2" placeholder="入水量数据,如:1180ml,,,500ml,,40ml" />
|
|
478
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
479
|
+
</a-form-item>
|
|
480
|
+
<a-form-item label="出水量" :validateStatus="formErrors.data3 ? 'error' : ''" :help="formErrors.data3">
|
|
481
|
+
<a-input v-model="formData.data3" placeholder="出水量数据,如:500ml,,,,500ml,,67ml" />
|
|
482
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
483
|
+
</a-form-item>
|
|
484
|
+
<a-form-item label="大便次数" :validateStatus="formErrors.data4 ? 'error' : ''" :help="formErrors.data4">
|
|
485
|
+
<a-input v-model="formData.data4" placeholder="大便次数数据,如:2,4,5,3,3,3,2,,2" />
|
|
486
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
487
|
+
</a-form-item>
|
|
488
|
+
<a-form-item label="小便次数" :validateStatus="formErrors.data5 ? 'error' : ''" :help="formErrors.data5">
|
|
489
|
+
<a-input v-model="formData.data5" placeholder="小便次数数据,如:2,4,5,3,3,3,2,,2" />
|
|
490
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
491
|
+
</a-form-item>
|
|
492
|
+
<!-- 成人特有字段 -->
|
|
493
|
+
<template v-if="modalType !== 'baby'">
|
|
494
|
+
<a-form-item label="身高" :validateStatus="formErrors.data6 ? 'error' : ''" :help="formErrors.data6">
|
|
495
|
+
<a-input v-model="formData.data6" placeholder="身高数据,如:167cm,,,,,,,,,164cm" />
|
|
496
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
497
|
+
</a-form-item>
|
|
498
|
+
<a-form-item label="体重" :validateStatus="formErrors.data7 ? 'error' : ''" :help="formErrors.data7">
|
|
499
|
+
<a-input v-model="formData.data7" placeholder="体重数据,如:95kg,,,,,90kg" />
|
|
500
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
501
|
+
</a-form-item>
|
|
502
|
+
<a-form-item label="过敏药" :validateStatus="formErrors.data8 ? 'error' : ''" :help="formErrors.data8">
|
|
503
|
+
<a-input v-model="formData.data8" placeholder="过敏药数据,如:青霉素," />
|
|
504
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
505
|
+
</a-form-item>
|
|
506
|
+
<a-form-item label="其他数据" :validateStatus="formErrors.data9 ? 'error' : ''" :help="formErrors.data9">
|
|
507
|
+
<a-input v-model="formData.data9" placeholder="其他数据,如:测试," />
|
|
508
|
+
<div class="input-tip">格式:多个值用逗号分隔</div>
|
|
509
|
+
</a-form-item>
|
|
510
|
+
</template>
|
|
511
|
+
<!-- 按钮 -->
|
|
512
|
+
<a-form-item :wrapper-col="{ span: 18, offset: 6 }">
|
|
513
|
+
<a-button type="primary" @click="submitForm" :loading="submitLoading" style="margin-right: 10px">确定</a-button>
|
|
514
|
+
<a-button @click="closeModal">取消</a-button>
|
|
515
|
+
</a-form-item>
|
|
516
|
+
</a-form>
|
|
517
|
+
</a-modal>
|
|
518
|
+
</template>
|
|
519
|
+
|
|
520
|
+
<style scoped>
|
|
521
|
+
.input-tip {
|
|
522
|
+
color: #999;
|
|
523
|
+
font-size: 12px;
|
|
524
|
+
margin-top: 4px;
|
|
525
|
+
}
|
|
526
|
+
</style>
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- <Source src="/code/VitalSigns.vue"></Source>-->
|
|
3
|
+
<div>
|
|
4
|
+
<a-row class="box">
|
|
5
|
+
病历号 <a-input v-model="vitalSignsId" style="width: 160px"></a-input>
|
|
6
|
+
<a-button-group style="margin-left: 20px;">
|
|
7
|
+
<a-button plain type="primary" @click="showVitalSignsModal('create')" :loading="loading" :disabled="!editorReady">创建体温单</a-button>
|
|
8
|
+
<a-button plain type="primary" @click="showVitalSignsModal('update')" :loading="loading" :disabled="!editorReady">更新体温单</a-button>
|
|
9
|
+
</a-button-group>
|
|
10
|
+
<a-button-group style="margin: 0 20px;">
|
|
11
|
+
<a-button plain type="primary" @click="showVitalSignsModal('baby')" :loading="loading" :disabled="!editorReady">新生儿体温单</a-button>
|
|
12
|
+
</a-button-group>
|
|
13
|
+
<a-button-group style="margin-left: 20px;">
|
|
14
|
+
<a-button plain type="primary" @click="execCommand('preview')" :loading="loading" :disabled="!editorReady">打印预览</a-button>
|
|
15
|
+
<a-button plain type="primary" @click="execCommand('print')" :loading="loading" :disabled="!editorReady">打印</a-button>
|
|
16
|
+
</a-button-group>
|
|
17
|
+
</a-row>
|
|
18
|
+
<div v-if="!editorReady" style="margin: 10px 0; padding: 10px; background-color: #fffbe6; border: 1px solid #ffe58f;">
|
|
19
|
+
<a-icon type="loading" /> 体温单编辑器加载中...
|
|
20
|
+
</div>
|
|
21
|
+
<Editor @editor-ready="onEditorReady" style="margin: 10px 0;" ref="editorComponent"></Editor>
|
|
22
|
+
|
|
23
|
+
<!-- 使用TextBox组件替代原有弹窗 -->
|
|
24
|
+
<TextBox
|
|
25
|
+
:visible="modalVisible"
|
|
26
|
+
:modalType="modalType"
|
|
27
|
+
:initialId="vitalSignsId"
|
|
28
|
+
:editorReady="editorReady"
|
|
29
|
+
:id="vitalSignsId"
|
|
30
|
+
@submit="handleSubmit"
|
|
31
|
+
@cancel="closeModal"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup>
|
|
37
|
+
import { ref, onMounted } from 'vue'
|
|
38
|
+
import Editor from '@/base-client/components/his/threeTestOrders/editor.vue'
|
|
39
|
+
import TextBox from '@/base-client/components/his/threeTestOrders/textBox.vue'
|
|
40
|
+
import { message } from 'ant-design-vue'
|
|
41
|
+
|
|
42
|
+
// 响应式状态
|
|
43
|
+
const vitalSignsId = ref('')
|
|
44
|
+
const loading = ref(false)
|
|
45
|
+
const editorReady = ref(false)
|
|
46
|
+
const editorComponent = ref(null)
|
|
47
|
+
const modalVisible = ref(false)
|
|
48
|
+
const modalType = ref('create')
|
|
49
|
+
let editor = null
|
|
50
|
+
// 定义组件事件
|
|
51
|
+
const emit = defineEmits(['submit'])
|
|
52
|
+
// 常量
|
|
53
|
+
const modalTitles = {
|
|
54
|
+
create: '创建体温单',
|
|
55
|
+
update: '更新体温单',
|
|
56
|
+
baby: '新生儿体温单'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 显示弹窗
|
|
60
|
+
const showVitalSignsModal = (type) => {
|
|
61
|
+
modalType.value = type
|
|
62
|
+
modalVisible.value = true
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 关闭弹窗
|
|
66
|
+
const closeModal = () => {
|
|
67
|
+
modalVisible.value = false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 编辑器初始化
|
|
71
|
+
const onEditorReady = (editorObj) => {
|
|
72
|
+
try {
|
|
73
|
+
if (!editorObj) {
|
|
74
|
+
throw new Error('传入的editor对象为null或undefined')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 尝试获取编辑器对象
|
|
78
|
+
if (typeof editorObj.createVitalSigns === 'function') {
|
|
79
|
+
editor = editorObj
|
|
80
|
+
} else if (editorObj.getEditor && typeof editorObj.getEditor === 'function') {
|
|
81
|
+
const editorFromComponent = editorObj.getEditor()
|
|
82
|
+
editor = editorFromComponent && typeof editorFromComponent.createVitalSigns === 'function'
|
|
83
|
+
? editorFromComponent
|
|
84
|
+
: (typeof editorObj.createVitalSigns === 'function' ? editorObj : null)
|
|
85
|
+
}
|
|
86
|
+
if (!editor) {
|
|
87
|
+
throw new Error('无法获取有效的editor对象')
|
|
88
|
+
}
|
|
89
|
+
editorReady.value = true
|
|
90
|
+
} catch (err) {
|
|
91
|
+
console.error('设置editor对象失败:', err)
|
|
92
|
+
message.error('体温单编辑器初始化失败,请刷新页面重试')
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 执行命令
|
|
97
|
+
const execCommand = (cmd) => {
|
|
98
|
+
if (!editorReady.value || !editor) return
|
|
99
|
+
loading.value = true
|
|
100
|
+
try {
|
|
101
|
+
editor.execCommand(cmd)
|
|
102
|
+
} catch (err) {
|
|
103
|
+
console.error('执行命令出错:', err)
|
|
104
|
+
message.error(`执行${cmd}命令失败`)
|
|
105
|
+
} finally {
|
|
106
|
+
loading.value = false
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// 处理表单提交
|
|
111
|
+
const handleSubmit = async (formData) => {
|
|
112
|
+
if (!editorReady.value || !editor) {
|
|
113
|
+
message.error('体温单编辑器未加载完成,请等待或刷新页面')
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
loading.value = true
|
|
117
|
+
try {
|
|
118
|
+
// 尝试调用iframe方法创建体温单
|
|
119
|
+
let result
|
|
120
|
+
try {
|
|
121
|
+
const iframe = editorComponent.value.$refs.editorIframe
|
|
122
|
+
if (iframe?.contentWindow) {
|
|
123
|
+
const dataStr = JSON.stringify(formData)
|
|
124
|
+
const script = `try {
|
|
125
|
+
const data = JSON.parse('${dataStr.replace(/'/g, "\\'")}');
|
|
126
|
+
editor.createVitalSigns(data);
|
|
127
|
+
} catch(e) {
|
|
128
|
+
console.error('iframe执行错误:', e);
|
|
129
|
+
null;
|
|
130
|
+
}`
|
|
131
|
+
result = iframe.contentWindow.eval(script)
|
|
132
|
+
} else if (window.iframeEditor) {
|
|
133
|
+
result = window.iframeEditor.createVitalSigns(formData)
|
|
134
|
+
} else {
|
|
135
|
+
throw new Error('无法访问iframe')
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
// 备用方案
|
|
139
|
+
if (editor && typeof editor.createVitalSigns === 'function') {
|
|
140
|
+
result = editor.createVitalSigns(formData)
|
|
141
|
+
} else {
|
|
142
|
+
throw new Error('无法调用createVitalSigns方法')
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
vitalSignsId.value = result || formData.id
|
|
146
|
+
modalVisible.value = false
|
|
147
|
+
message.success(`${modalTitles[modalType.value]}成功`)
|
|
148
|
+
emit('submit', formData)
|
|
149
|
+
} catch (err) {
|
|
150
|
+
console.error('创建体温单出错:', err)
|
|
151
|
+
message.error(`创建体温单失败: ${err.message || '未知错误'}`)
|
|
152
|
+
} finally {
|
|
153
|
+
loading.value = false
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 生命周期钩子
|
|
158
|
+
onMounted(() => {
|
|
159
|
+
window.addEventListener('message', (event) => {
|
|
160
|
+
if (event.data?.type === 'editorReady' && !editorReady.value && editorComponent.value?.getEditor) {
|
|
161
|
+
try {
|
|
162
|
+
const editorFromComponent = editorComponent.value.getEditor()
|
|
163
|
+
if (editorFromComponent && typeof editorFromComponent.createVitalSigns === 'function') {
|
|
164
|
+
editor = editorFromComponent
|
|
165
|
+
editorReady.value = true
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.error('从组件获取editor对象错误:', err)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
<style scoped>
|
|
176
|
+
.box {
|
|
177
|
+
display: flex;
|
|
178
|
+
align-items: center;
|
|
179
|
+
padding: 1%;
|
|
180
|
+
}
|
|
181
|
+
</style>
|
|
@@ -277,8 +277,8 @@ export default {
|
|
|
277
277
|
},
|
|
278
278
|
mounted () {},
|
|
279
279
|
computed: {
|
|
280
|
-
...mapState('account', {currUser: 'user'}),
|
|
281
|
-
...mapState('setting', {isMobile: 'isMobile'})
|
|
280
|
+
...mapState('account', { currUser: 'user' }),
|
|
281
|
+
...mapState('setting', { isMobile: 'isMobile' })
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
</script>
|
package/src/utils/routerUtil.js
CHANGED
|
@@ -82,7 +82,8 @@ function parseRoutes (routesConfig, routerMap) {
|
|
|
82
82
|
}
|
|
83
83
|
// 查看是否是栅格配置页面
|
|
84
84
|
if (item.meta && item.meta.type) {
|
|
85
|
-
|
|
85
|
+
// 新的资源管理有单独字段存储 component
|
|
86
|
+
if (item.meta.type === 'GridView' || item.component === 'GridView') {
|
|
86
87
|
router = routerMap.gridView
|
|
87
88
|
item.path = encodeURI(item.router) || encodeURI(item.name)
|
|
88
89
|
}
|
|
@@ -434,6 +435,7 @@ function parsefunc (func) {
|
|
|
434
435
|
name: row.name
|
|
435
436
|
}
|
|
436
437
|
if (row.link) {
|
|
438
|
+
// 旧的资源管理 link 格式为 {name_space}${link} 所以这么判断
|
|
437
439
|
if (row.link.includes('$')) {
|
|
438
440
|
route.router = row.link.split('$')[1]
|
|
439
441
|
route.params = row.link.split('$')[0]
|
|
@@ -453,6 +455,9 @@ function parsefunc (func) {
|
|
|
453
455
|
}
|
|
454
456
|
} catch (e) {}
|
|
455
457
|
}
|
|
458
|
+
if (row.config_name) {
|
|
459
|
+
route.meta.configName = row.config_name
|
|
460
|
+
}
|
|
456
461
|
}
|
|
457
462
|
if (row.children && row.children.length > 0) {
|
|
458
463
|
route.children = parsefunc(row.children)
|