Browse Source

慢病管理调查问卷填写

hsh 1 year ago
parent
commit
be94f646ae

+ 32 - 0
src/api/chronic-disease/chronic-disease-questionnaire.js

@@ -0,0 +1,32 @@
+import request from '../../utils/request'
+
+export function getCrmEmrModel() {
+    return request({
+        url: '/chronicDisease/getCrmEmrModel',
+        method: 'get',
+    })
+}
+
+export function queryCrmEmrTree(data) {
+    return request({
+        url: '/chronicDisease/queryCrmEmrTree',
+        method: 'post',
+        data,
+    })
+}
+
+export function queryCrmPatientInfoByCode(code) {
+    return request({
+        url: '/chronicDisease/queryCrmPatientInfoByCode',
+        method: 'get',
+        params: { code },
+    })
+}
+
+export function saveCrmEmrModel(data) {
+    return request({
+        url: '/chronicDisease/saveCrmEmrModel',
+        method: 'post',
+        data,
+    })
+}

+ 5 - 0
src/router/modules/dashboard.js

@@ -777,6 +777,11 @@ const route = [
                 component: createNameComponent(() => import('@/views/clinic/chronicDisease/ChronicDiseaseRegister.vue')),
                 meta: {title: '慢特病信息登记'},
             },
+            {
+                path: 'chronicDisease/chronicDiseaseQuestionnaire',
+                component: createNameComponent(() => import('@/views/clinic/chronicDisease/ChronicDiseaseQuestionnaire.vue')),
+                meta: {title: '慢特病调查问卷'},
+            },
         ],
     },
     {

+ 380 - 0
src/views/clinic/chronicDisease/ChronicDiseaseQuestionnaire.vue

@@ -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>

+ 53 - 32
src/views/clinic/chronicDisease/ChronicDiseaseRegister.vue

@@ -4,7 +4,7 @@
             <el-input v-model="keyCode" placeholder="请输入证件号/门诊号/住院号/体检号" style="width: 320px;">
                 <template #prepend>关键字</template>
             </el-input>
-            <el-button type="primary" icon="Search" @click="queryCmr()" style="margin-left: 10px">查询
+            <el-button type="primary" icon="Search" @click="queryCmr" style="margin-left: 10px">查询
             </el-button>
             <el-button type="primary" icon="Plus" @click="addForm(ruleFormRef)" style="margin-left: 10px">新增
             </el-button>
@@ -103,13 +103,10 @@
                                 </el-col> -->
                                 <el-col :span="8">
                                     <el-form-item label="病人来源" prop="pType">
-                                        <el-select v-model="ruleForm.pType" placeholder="请选择病人来源" style="width: 100%">
-                                            <el-option label="" value="" hidden />
-                                            <el-option label="门诊" value="1" />
-                                            <el-option label="住院" value="2" />
-                                            <el-option label="健康体检" value="3" />
-                                            <el-option label="慢病中心" value="4" />
-                                            <el-option label="医联体" value="5" />
+                                        <el-select v-model="ruleForm.pType" placeholder="请选择病人来源" clearable
+                                            style="width: 100%">
+                                            <el-option v-for="item in dics.getAdmissWay" :key="item.code"
+                                                :label="item.name" :value="item.code" />
                                         </el-select>
                                     </el-form-item>
                                 </el-col>
@@ -363,7 +360,8 @@
                             <el-row>
                                 <el-col :span="6">
                                     <el-form-item label="病人等级" prop="importLevel">
-                                        <el-select v-model="ruleForm.importLevel" placeholder="请选择病人等级" style="width: 100%">
+                                        <el-select v-model="ruleForm.importLevel" placeholder="请选择病人等级" clearable
+                                            style="width: 100%">
                                             <el-option label="未住院患者" value="1" />
                                             <el-option label="住院一次患者" value="2" />
                                             <el-option label="住院两次及以上" value="3" />
@@ -373,7 +371,7 @@
                                 <el-col :span="6">
                                     <el-form-item label="省" prop="provinceCode">
                                         <el-select v-model="ruleForm.provinceCode" placeholder="请选择省" style="width: 100%"
-                                            filterable @change="provinceCharge">
+                                            filterable @change="provinceCharge" clearable>
                                             <el-option v-for="item in dics.getProvince" :key="item.code" :label="item.name"
                                                 :value="item.code" />
                                         </el-select>
@@ -382,7 +380,7 @@
                                 <el-col :span="6">
                                     <el-form-item label="市" prop="cityCode">
                                         <el-select v-model="ruleForm.cityCode" placeholder="请选择市" style="width: 100%"
-                                            filterable @change="cityCharge">
+                                            filterable @change="cityCharge" clearable>
                                             <el-option v-for="item in dics.getCity" :key="item.code" :label="item.name"
                                                 :value="item.code" />
                                         </el-select>
@@ -391,7 +389,7 @@
                                 <el-col :span="6">
                                     <el-form-item label="区" prop="areaCode">
                                         <el-select v-model="ruleForm.areaCode" placeholder="请选择区" style="width: 100%"
-                                            filterable>
+                                            filterable clearable>
                                             <el-option v-for="item in dics.getArea" :key="item.code" :label="item.name"
                                                 :value="item.code" />
                                         </el-select>
@@ -411,32 +409,29 @@
                             <el-row>
                                 <el-col :span="6">
                                     <el-form-item label="身高" prop="height">
-                                        <el-input v-model="ruleForm.height" type="number" maxlength="12" show-word-limit
-                                            placeholder="请填写身高">
+                                        <el-input v-model="ruleForm.height" type="number" placeholder="请填写身高">
                                             <template #append>cm</template>
                                         </el-input>
                                     </el-form-item>
                                 </el-col>
                                 <el-col :span="6">
                                     <el-form-item label="体重" prop="weight">
-                                        <el-input v-model="ruleForm.weight" type="number" maxlength="12" show-word-limit
-                                            placeholder="请填写体重">
+                                        <el-input v-model="ruleForm.weight" type="number" placeholder="请填写体重">
                                             <template #append>kg</template>
                                         </el-input>
                                     </el-form-item>
                                 </el-col>
                                 <el-col :span="6">
                                     <el-form-item label="体温" prop="temperature">
-                                        <el-input v-model="ruleForm.temperature" type="number" maxlength="12"
-                                            show-word-limit placeholder="请填写体温">
+                                        <el-input v-model="ruleForm.temperature" type="number" placeholder="请填写体温">
                                             <template #append>°C</template>
                                         </el-input>
                                     </el-form-item>
                                 </el-col>
                                 <el-col :span="6">
                                     <el-form-item label="心率" prop="heartRate">
-                                        <el-input v-model="ruleForm.heartRate" maxlength="12" show-word-limit
-                                            placeholder="请填写心率" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
+                                        <el-input v-model="ruleForm.heartRate" placeholder="请填写心率"
+                                            oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
                                             <template #append>次</template>
                                         </el-input>
                                     </el-form-item>
@@ -444,33 +439,31 @@
                             </el-row>
                             <el-row>
                                 <el-col :span="6">
-                                    <el-form-item label="舒张血压" prop="bloodPressureLow">
-                                        <el-input v-model.number="ruleForm.bloodPressureLow" maxlength="12" show-word-limit
-                                            placeholder="请填写舒张血压" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
+                                    <el-form-item label="收缩压" prop="bloodPressureHigh">
+                                        <el-input v-model="ruleForm.bloodPressureHigh" placeholder="请填写收缩压"
+                                            oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
                                             <template #append>mmHg</template>
                                         </el-input>
                                     </el-form-item>
                                 </el-col>
                                 <el-col :span="6">
-                                    <el-form-item label="收缩血压" prop="bloodPressureHigh">
-                                        <el-input v-model.number="ruleForm.bloodPressureHigh" maxlength="12" show-word-limit
-                                            placeholder="请填写收缩血压" oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
+                                    <el-form-item label="舒张压" prop="bloodPressureLow">
+                                        <el-input v-model="ruleForm.bloodPressureLow" placeholder="请填写舒张压"
+                                            oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
                                             <template #append>mmHg</template>
                                         </el-input>
                                     </el-form-item>
                                 </el-col>
                                 <el-col :span="6">
                                     <el-form-item label="血糖" prop="bloodSugar">
-                                        <el-input v-model="ruleForm.bloodSugar" type="number" maxlength="12" show-word-limit
-                                            placeholder="请填写血糖">
+                                        <el-input v-model="ruleForm.bloodSugar" type="number" placeholder="请填写血糖">
                                             <template #append>mmol/L</template>
                                         </el-input>
                                     </el-form-item>
                                 </el-col>
                                 <el-col :span="6">
                                     <el-form-item label="血氧" prop="bloodOxygen">
-                                        <el-input v-model="ruleForm.bloodOxygen" maxlength="12" show-word-limit
-                                            placeholder="请填写血氧">
+                                        <el-input v-model="ruleForm.bloodOxygen" placeholder="请填写血氧">
                                             <template #append>%</template>
                                         </el-input>
                                     </el-form-item>
@@ -681,7 +674,7 @@ const ruleForm = ref<RuleForm>({
     detailAdress: '',
     referPhysician: '',
     referPhysicianName: '',
-    visitTimes: 1,
+    visitTimes: 0,
     visitDate: '',
     age: '',
     areaCode: '',
@@ -748,6 +741,27 @@ const rulesAll = reactive<FormRules<RuleForm>>({
     visitDate: [
         { required: true, message: '请选择下次随访时间', trigger: 'change' },
     ],
+    height: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
+    weight: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
+    temperature: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
+    bloodSugar: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
+    heartRate: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
+    bloodPressureLow: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
+    bloodPressureHigh: [
+        { min: 0, max: 10, message: '不超过10个字符', trigger: 'blur' },
+    ],
 })
 
 const queryCmr = async () => {
@@ -761,8 +775,15 @@ const queryCmr = async () => {
         });
         return
     }
-    ruleForm.value = await selectCrmPatientMiByCode(code)
     isEditForm.value = true
+    try {
+        await selectCrmPatientMiByCode(code).then((res: any) => {
+            ruleForm.value = res
+        })
+    } catch (error) {
+        console.log(error)
+    }
+
 }
 
 const addForm = (formEl: FormInstance | undefined) => {

+ 1 - 1
src/views/examination/TjReportInfo.vue

@@ -54,7 +54,7 @@
             </el-row>
             <el-row :gutter="6" style="margin-bottom: 160px">
               <el-col :span="6"></el-col>
-              <el-col :span="6">体检日期:{{ filterDate(tjReportDetail.reportHeader.登记日期) }}</el-col>
+              <el-col :span="6">体检日期:{{ tjReportDetail.reportHeader.登记日期 }}</el-col>
               <el-col :span="6">电&emsp;&emsp;话:{{ tjReportDetail.reportHeader.手机 }}</el-col>
               <el-col :span="6"></el-col>
             </el-row>