|
@@ -0,0 +1,380 @@
|
|
|
+<template>
|
|
|
+ <el-row :gutter="5" style="height: 100%;">
|
|
|
+ <el-col :span="8" style="height: auto;">
|
|
|
+ <PageLayer>
|
|
|
+ <template #main class="hd-cl">
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-descriptions :column="2" border style="width:100%;">
|
|
|
+ <el-descriptions-item label="门诊号" width="15%">
|
|
|
+ {{ crmEmrPatientVo.hisMzNo }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="住院号" width="15%">
|
|
|
+ {{ crmEmrPatientVo.hisZyNo }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-descriptions :column="1" border style="width:100%;">
|
|
|
+ <el-descriptions-item label="证件号" width="30%">
|
|
|
+ {{ crmEmrPatientVo.socialNo }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-descriptions :column="2" border style="width:100%;">
|
|
|
+ <el-descriptions-item label="姓名" width="15%">
|
|
|
+ {{ crmEmrPatientVo.pName }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="病人来源" width="15%">
|
|
|
+ {{ crmEmrPatientVo.ptName }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-descriptions :column="2" border style="width:100%;">
|
|
|
+ <el-descriptions-item label="性别" width="15%">
|
|
|
+ {{ crmEmrPatientVo.sexValue }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="年龄" width="15%">
|
|
|
+ {{ crmEmrPatientVo.age === null ? '' : crmEmrPatientVo.age + '岁' }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="5" style="padding-top: 5px;">
|
|
|
+ <el-tabs type="border-card" v-model="tabType" @tab-click="queryCrmEmdrData" style="width:100%;">
|
|
|
+ <el-tab-pane label="慢病模板" name="0">
|
|
|
+ <el-table :data="emrTemplateData" @row-click="rowClick">
|
|
|
+ <el-table-column type="index" label="序号" width="50"></el-table-column>
|
|
|
+ <el-table-column label="名称" prop="name"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="历史模板" name="3">
|
|
|
+ <el-input v-model="filterText" placeholder="搜索" style="width: 100%;">
|
|
|
+ <template #prepend>关键字</template>
|
|
|
+ </el-input>
|
|
|
+ <el-tree style="width: 100%;" ref="treeRef" class="filter-tree" :data="treeData"
|
|
|
+ :props="defaultProps" @node-click="handleNodeClick" node-key="id" highlight-current
|
|
|
+ default-expand-all :filter-node-method="filterNode" />
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ </PageLayer>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16" style="height: auto;">
|
|
|
+ <PageLayer>
|
|
|
+ <template #header class="hd-cl">
|
|
|
+ <el-input v-model="textCode" placeholder="请输入证件号/门诊号/住院号" style="width: 320px;">
|
|
|
+ <template #prepend>关键字</template>
|
|
|
+ </el-input>
|
|
|
+ <el-button type="primary" icon="Search" @click="selectCrmPatientMiByCode" style="margin-left: 10px">查询
|
|
|
+ </el-button>
|
|
|
+ <el-button type="success" @click="saveData">保存</el-button>
|
|
|
+ <el-button icon="Printer" type="primary" @click="handlePrint"> 打印</el-button>
|
|
|
+ </template>
|
|
|
+ <template #main>
|
|
|
+ <div ref="emrDivRef" style="width: 100% ; height: 100%">
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </PageLayer>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+</template>
|
|
|
+<script setup lang="ts" name="ChronicDiseaseQuestionnaire">
|
|
|
+import { onMounted, ref, nextTick, watch } from "vue";
|
|
|
+import PageLayer from '@/layout/PageLayer.vue'
|
|
|
+import { useEmrInit, UseEmrInitReturn } from "@/utils/emr/emr-init-v2";
|
|
|
+import { getCrmEmrModel, queryCrmEmrTree, queryCrmPatientInfoByCode, saveCrmEmrModel } from "@/api/chronic-disease/chronic-disease-questionnaire";
|
|
|
+import { userInfoStore } from "@/utils/store-public";
|
|
|
+import { ElMessageBox, ElTree, ElMessage } from 'element-plus'
|
|
|
+import { stringIsBlank } from "@/utils/blank-utils";
|
|
|
+import { getServerDateApi, getUuid } from "@/api/public-api";
|
|
|
+
|
|
|
+const textCode = ref('')
|
|
|
+const tabType = ref('0')
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+
|
|
|
+ await nextTick(() => {
|
|
|
+ useEmrInit(emrDivRef.value, {
|
|
|
+ appContext: appContext
|
|
|
+ }).then((res: any) => {
|
|
|
+ editor = res
|
|
|
+ })
|
|
|
+
|
|
|
+ queryCrmEmdrData(null, null)
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+export interface Property {
|
|
|
+ editorVersion?: string;
|
|
|
+ creator?: string;
|
|
|
+ modifyTime?: string;
|
|
|
+ createTime?: string;
|
|
|
+ modifier?: string;
|
|
|
+ reviewer?: string;
|
|
|
+ reviewTime?: string;
|
|
|
+}
|
|
|
+
|
|
|
+export interface Version {
|
|
|
+ name?: string;
|
|
|
+ properties?: Property;
|
|
|
+}
|
|
|
+
|
|
|
+export interface emrTemplateType {
|
|
|
+ documentId?: string,
|
|
|
+ parent?: string;
|
|
|
+ code?: string;
|
|
|
+ versions?: Version[];
|
|
|
+ sortNumber?: number;
|
|
|
+ name?: string;
|
|
|
+ description?: string;
|
|
|
+ _id?: string;
|
|
|
+ type?: string;
|
|
|
+ labels?: string[];
|
|
|
+}
|
|
|
+
|
|
|
+const emrTemplateData = ref<emrTemplateType[]>()
|
|
|
+const emrDivRef = ref<HTMLDivElement>()
|
|
|
+let editor: UseEmrInitReturn;
|
|
|
+const selectionStatus = ref(false)
|
|
|
+const categoryCode = ref<string>('')
|
|
|
+const mzEmrName = ref<string>('')
|
|
|
+const parent = ref<string>('')
|
|
|
+
|
|
|
+const rowClick = (row: emrTemplateType) => {
|
|
|
+ selectionStatus.value = true
|
|
|
+ editor.editor.setEditorMode('free')
|
|
|
+ categoryCode.value = row.code as string
|
|
|
+ mzEmrName.value = row.name as string
|
|
|
+ parent.value = row.parent as string
|
|
|
+ if (tabType.value == '0') {
|
|
|
+ editor.loadAndSetDocument({
|
|
|
+ categoryId: row._id,
|
|
|
+ categoryCode: row.code,
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ editor.loadAndSetDocument({
|
|
|
+ documentId: row.documentId
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+const saveData = () => {
|
|
|
+ if (!((tabType.value == '0' || tabType.value == '2') && selectionStatus.value)) {
|
|
|
+ return ElMessage.error('请选择数据,只有慢病模板才能保存!')
|
|
|
+ }
|
|
|
+ ElMessageBox.confirm('请确认是否保存', {
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ clickSaveData()
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const clickSaveData = async () => {
|
|
|
+ // 解析 id
|
|
|
+ let id = await analysisIframeSrcSearch()
|
|
|
+ let data: any = {
|
|
|
+ pId: crmEmrPatientVo.value.pId,
|
|
|
+ pType: crmEmrPatientVo.value.pType,
|
|
|
+ emrDocumentId: id,
|
|
|
+ emrCategoryCode: categoryCode.value,
|
|
|
+ visitTimes: crmEmrPatientVo.value.visitTimes,
|
|
|
+ emrName: mzEmrName.value,
|
|
|
+ name: mzEmrName.value,
|
|
|
+ parent: parent.value,
|
|
|
+ inputId: crmEmrPatientVo.value.userIdCode,
|
|
|
+ inputDept: crmEmrPatientVo.value.deptCode,
|
|
|
+ documentData: null
|
|
|
+ }
|
|
|
+ let newDate = await getServerDateApi();
|
|
|
+ const document = editor.editor.getDocument();
|
|
|
+
|
|
|
+ document.properties.categoryCode = data.emrCategoryCode
|
|
|
+ document.properties.patientId = data.pId + "-" + data.visitTimes;
|
|
|
+ document._id = data.emrDocumentId
|
|
|
+ data.documentData = document
|
|
|
+
|
|
|
+ if (document.properties.creator) {
|
|
|
+ document.properties.modifier = crmEmrPatientVo.value.userIdCode
|
|
|
+ document.properties.modifierId = crmEmrPatientVo.value.userName
|
|
|
+ document.properties.modifyTime = newDate
|
|
|
+ } else {
|
|
|
+ document.properties.creator = crmEmrPatientVo.value.userIdCode
|
|
|
+ document.properties.creatorId = crmEmrPatientVo.value.userName
|
|
|
+ document.properties.createTime = newDate
|
|
|
+ }
|
|
|
+ saveCrmEmrModel(data).then((res: any) => {
|
|
|
+ selectCrmPatientMiByCode()
|
|
|
+ queryCrmEmdrData(null, null)
|
|
|
+ })
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+const analysisIframeSrcSearch = async () => {
|
|
|
+ let id = getId()
|
|
|
+ let temp: string
|
|
|
+ if (stringIsBlank(id)) {
|
|
|
+ // 这个是 唯一 id 调用服务的雪花算法
|
|
|
+ temp = await getUuid()
|
|
|
+ } else {
|
|
|
+ temp = id
|
|
|
+ }
|
|
|
+ return temp
|
|
|
+}
|
|
|
+
|
|
|
+const getId = () => {
|
|
|
+ if (editor) {
|
|
|
+ return editor.editor.documentData._id
|
|
|
+ }
|
|
|
+ return null
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const appContext = () => {
|
|
|
+ return {
|
|
|
+ endpoints: {
|
|
|
+ app: "/bdp/dataservice/api",
|
|
|
+ his: import.meta.env.VITE_BASE_URL,
|
|
|
+ },
|
|
|
+ input: {
|
|
|
+ user: userInfoStore.value.code,
|
|
|
+ name: userInfoStore.value.name
|
|
|
+ },
|
|
|
+ login: {
|
|
|
+ token: userInfoStore.value.token,
|
|
|
+ user: {
|
|
|
+ id: userInfoStore.value.code,
|
|
|
+ name: userInfoStore.value.name
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ // '患者姓名': crmEmrPatientVo.value.pName,
|
|
|
+ // '性别名称': crmEmrPatientVo.value.sexValue,
|
|
|
+ // '患者年龄': crmEmrPatientVo.value.age,
|
|
|
+ // '门/急诊号': crmEmrPatientVo.value.hisMzNo,
|
|
|
+ // '接诊科室门诊': crmEmrPatientVo.value.deptName,
|
|
|
+ // '编辑者': [{ code: crmEmrPatientVo.value.userIdCode, name: crmEmrPatientVo.value.userName }]
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handlePrint = () => {
|
|
|
+ editor.editor.execute("print", {
|
|
|
+ value: {
|
|
|
+ showPreview: false,
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const crmEmrPatientVo = ref<any>({
|
|
|
+ pId: '',
|
|
|
+ pType: '',
|
|
|
+ hisMzNo: '',
|
|
|
+ hisZyNo: '',
|
|
|
+ visitTimes: null,
|
|
|
+ userIdCode: '',
|
|
|
+ userName: '',
|
|
|
+ deptCode: '',
|
|
|
+ deptName: '',
|
|
|
+ pName: '',
|
|
|
+ sex: '',
|
|
|
+ sexValue: '',
|
|
|
+ age: null,
|
|
|
+ ptName: '',
|
|
|
+ type: null,
|
|
|
+})
|
|
|
+
|
|
|
+const treeData = ref<Tree[]>()
|
|
|
+
|
|
|
+const selectCrmPatientMiByCode = () => {
|
|
|
+ queryCrmPatientInfoByCode(textCode.value).then((res: any) => {
|
|
|
+ crmEmrPatientVo.value = res
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const queryCrmEmdrData = async (tab: any, event: any) => {
|
|
|
+ tabType.value = tab === null ? '0' : tab.props.name
|
|
|
+ let type = Number.parseInt(tabType.value)
|
|
|
+ selectionStatus.value = false
|
|
|
+ if (type == 0) {
|
|
|
+ await getCrmEmrModel().then((res: any) => {
|
|
|
+ let tem = [] as Array<emrTemplateType>
|
|
|
+ if (res) {
|
|
|
+ for (let i = 0; i < res.length; i++) {
|
|
|
+ if (res[i].parent != null) {
|
|
|
+ tem.push(res[i])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ emrTemplateData.value = tem
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ crmEmrPatientVo.value['type'] = type
|
|
|
+ queryCrmEmrTree(crmEmrPatientVo.value).then((res: any) => {
|
|
|
+ if (type == 2) {
|
|
|
+ let tempData = [] as any
|
|
|
+ if (res) {
|
|
|
+ for (let i = 0; i < res.length; i++) {
|
|
|
+ let te = {
|
|
|
+ _id: '',
|
|
|
+ categoryCode: '',
|
|
|
+ documentId: '',
|
|
|
+ name: '',
|
|
|
+ cade: '',
|
|
|
+ parent: '',
|
|
|
+ }
|
|
|
+ te.cade = res[i].emrCategoryCode
|
|
|
+ te.parent = res[i].parent
|
|
|
+ te.categoryCode = res[i].emrCategoryCode
|
|
|
+ te.documentId = res[i].emrDocumentId
|
|
|
+ te.name = res[i].name
|
|
|
+ tempData.push(te)
|
|
|
+ }
|
|
|
+ emrTemplateData.value = tempData
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ treeData.value = res
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+interface Tree {
|
|
|
+ [key: string]: any
|
|
|
+}
|
|
|
+
|
|
|
+const filterText = ref('')
|
|
|
+const treeRef = ref<InstanceType<typeof ElTree>>()
|
|
|
+
|
|
|
+const defaultProps = {
|
|
|
+ children: 'children',
|
|
|
+ label: 'name',
|
|
|
+}
|
|
|
+
|
|
|
+watch(filterText, (val) => {
|
|
|
+ treeRef.value!.filter(val)
|
|
|
+})
|
|
|
+
|
|
|
+const filterNode = (value: string, data: Tree) => {
|
|
|
+ if (!value) return true
|
|
|
+ return data.name.includes(value)
|
|
|
+}
|
|
|
+
|
|
|
+const handleNodeClick = (node: any, object: any, event: any) => {
|
|
|
+ selectionStatus.value = true
|
|
|
+ editor.editor.setEditorMode('readonly')
|
|
|
+ editor.loadAndSetDocument({
|
|
|
+ documentId: node.emrDocumentId
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+</script>
|