Prechádzať zdrojové kódy

草药添加药单号显示,以及优化终末质控和环节质控

xiaochan 2 rokov pred
rodič
commit
9b80f3f326

+ 3 - 1
.env.dev

@@ -2,4 +2,6 @@ ENV = 'dev'
 
 VITE_BASE_URL = 'http://172.16.30.61:9201'
 VITE_SOCKET_URL = 'ws://172.16.30.61:9201/websocket/'
-VITE_EMR_CONTROL_URL = 'http://172.16.30.61:9227'
+
+VITE_EMR_CONTROL_URL = '172.16.30.61:9227'
+

+ 1 - 1
.env.production

@@ -2,4 +2,4 @@ ENV = 'production'
 
 VITE_BASE_URL = 'http://172.16.32.160:8706'
 VITE_SOCKET_URL = 'ws://172.16.32.160:8706/websocket/'
-VITE_EMR_CONTROL_URL = 'http://172.16.30.160:9227'
+VITE_EMR_CONTROL_URL = '172.16.30.61:9227'

+ 0 - 25
src/api/emr-control/connotation-quality-control.js

@@ -1,25 +0,0 @@
-import service from "./request";
-
-export function save(data) {
-    return service({
-        url: '/save',
-        method: 'post',
-        data
-    })
-}
-
-export function createAnEdit(data) {
-    return service({
-        url: '/timeLimitConfig/createAnEdit',
-        method: 'post',
-        data
-    })
-}
-
-export function reqUnlock(data) {
-    return service({
-        url: '/timeLimitConfig/reqUnlock',
-        method: 'post',
-        data
-    })
-}

+ 17 - 0
src/api/emr-control/emr-control.ts

@@ -0,0 +1,17 @@
+import request from "./request";
+
+export function linkQualityControl(startDate, endDate, sid) {
+    return request({
+        url: '/emrQualityControl/linkControl',
+        method: 'get',
+        params: {startDate, endDate, sid}
+    })
+}
+
+export function finalControl(data: any) {
+    return request({
+        url: '/emrQualityControl/finalControl',
+        method: 'post',
+        data
+    })
+}

+ 1 - 1
src/api/emr-control/request.ts

@@ -7,7 +7,7 @@ import store from '@/store'
 
 const service = axios.create({
     // @ts-ignore
-    baseURL: import.meta.env.VITE_EMR_CONTROL_URL,
+    baseURL: "http://" + import.meta.env.VITE_EMR_CONTROL_URL,
     withCredentials: true,
     timeout: 0,
 })

+ 0 - 17
src/api/zhu-yuan-yi-sheng/emr-control-rule.js

@@ -2,23 +2,6 @@ import request from "@/utils/request";
 
 let url = '/emrControlRule'
 
-export function addRule(data) {
-    return request({
-        url: url + '/addRule',
-        method: 'post',
-        data
-    })
-}
-
-export function getAvailableObjects() {
-    return request({
-        url: url + '/getAvailableObjects',
-        method: 'get',
-    })
-}
-
-
-
 export function myPatientQualityControl() {
     return request({
         url: url + '/myPatientQualityControl',

+ 1 - 1
src/components/zhu-yuan-yi-sheng/emr/EmrSidebar.vue

@@ -75,7 +75,7 @@ import {ElIcon, ElMessageBox} from "element-plus";
 import {Folder, Document, Open, Sort, View} from "@element-plus/icons-vue";
 import {isDev} from "@/utils/public";
 import XEUtils from "xe-utils";
-import {reqUnlock} from "@/api/emr-control/connotation-quality-control";
+import {reqUnlock} from "@/api/emr-control/emr-control";
 
 const props = defineProps({
   maxHeight: {

+ 29 - 0
src/utils/date.js

@@ -1,6 +1,13 @@
 import {stringIsBlank} from '@/utils/blank-utils'
 import moment from 'moment'
 import {getServerDateApi} from "@/api/public-api";
+import XEUtils from 'xe-utils'
+
+export const DATEFORMAT = {
+    DATE: 'YYYY-MM-DD',
+    DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
+    TIME: 'HH:mm:ss',
+}
 
 export function getDate() {
     const date = new Date()
@@ -248,3 +255,25 @@ export const currentAndAFewDaysAgo = async (day = 7, format = 'YYYY-MM-DD') => {
     let start = moment(new Date(date)).subtract(day, 'day')
     return [moment(start).format(format), now]
 }
+
+export const dateRangeAddTime = (val) => {
+    if (XEUtils.isEmpty(val)) {
+        return {
+            start: '',
+            end: ''
+        }
+    }
+    if (val.length === 2) {
+        let start = moment(val[0]).format(DATEFORMAT.DATE)
+        let end = moment(val[1]).format(DATEFORMAT.DATE)
+        return {
+            start: start + ' 00:00:00',
+            end: end + ' 23:59:59'
+        }
+    }
+
+    return {
+        start: '',
+        end: ''
+    }
+}

+ 8 - 11
src/utils/websocket.js

@@ -5,6 +5,7 @@ import store from '@/store'
 
 const socketUrl = import.meta.env.VITE_SOCKET_URL
 
+
 let webSocket = null
 let globalCallback = new Map()
 
@@ -17,25 +18,22 @@ export function closeWebSocket() {
 }
 
 export function setCallback(messageName, callback) {
-    if (globalCallback.has(messageName)) {
-        globalCallback.get(messageName).push(callback)
-    } else {
-        globalCallback.set(messageName, [callback])
-    }
-    console.log(`websocket 监听通道 ${messageName},已监听 ${globalCallback.get(messageName).length} 个`)
+    globalCallback.set(messageName, callback)
 }
 
 export function delCallback(messageName) {
     globalCallback.delete(messageName)
-    console.log(`websocket 监听通道关闭 ${messageName}`)
 }
 
 
 export function sendAMessage(name, data) {
     if (globalCallback.has(name)) {
-        globalCallback.get(name).forEach(item => {
-            item(data)
-        })
+        try {
+            globalCallback.get(name)(data)
+        } catch {
+
+        }
+
     }
 }
 
@@ -55,7 +53,6 @@ export function initWebSocket(sid, force) {
     webSocket.onopen = function () {
         socketErrDialog.value = false
         store.commit('user/sidChange', sid)
-        console.log('WebSocket连接成功', sid)
     }
 
     webSocket.onmessage = function (e) {

+ 1 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/cao-yao-yi-zhu/ChaXunChaoYaoYiZhu.vue

@@ -24,6 +24,7 @@
       <el-tab-pane :name="0" label="历史信息">
         <el-table :data="caoYaoShuJu.data" :height="yzSize.h / 1.2">
           <el-table-column label="名称" prop="orderName"></el-table-column>
+          <el-table-column label="药单号" prop="pageNo"></el-table-column>
           <el-table-column label="开单时间" prop="inputDate" show-overflow-tooltip></el-table-column>
           <el-table-column label="医生" prop="doctorCodeName"></el-table-column>
           <el-table-column label="状态" prop="statusFlag">

+ 1 - 1
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/EmrMain.vue

@@ -310,7 +310,7 @@ import EmrAudit
   from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/EmrAudit.vue";
 import EmrConnotation
   from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/components/EmrConnotation.vue";
-import {createAnEdit, reqUnlock, save} from "@/api/emr-control/connotation-quality-control";
+import {createAnEdit, reqUnlock, save} from "@/api/emr-control/emr-control";
 import XEUtils from 'xe-utils'
 import {
   EmrEditCreateLimit

+ 35 - 0
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-socket.ts

@@ -0,0 +1,35 @@
+import {userInfoStore} from "../../../../../utils/store-public";
+import {uuid} from '../../../../../utils/getUuid'
+import {sendAMessage} from '../../../../../utils/websocket'
+
+export const sid: string = userInfoStore.value.code + '_' + uuid(8, 62);
+
+// @ts-ignore
+const emrServer: string = "ws://" + import.meta.env.VITE_EMR_CONTROL_URL + "/websocket/"
+
+let socket = null
+
+export const openSocket = (): void => {
+    let url: string = emrServer + sid;
+
+    if ('WebSocket' in window) {
+        socket = new WebSocket(url)
+    } else {
+        alert('该浏览器不支持websocket!')
+        socket = null
+    }
+
+    if (socket == null) return
+
+    socket.onmessage = function (e): void {
+        let data = JSON.parse(e.data)
+        sendAMessage(data.name, data.message)
+    }
+
+    socket.onclose = function (): void {
+        setTimeout((): void => {
+            openSocket()
+        }, 3000)
+    }
+
+}

+ 75 - 25
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/EmrControlRule.vue

@@ -7,17 +7,30 @@
           style="width: 220px"
           type="daterange"
           v-model="intervalPatients"/>
-      <el-button type="primary" @click="queryQualityControlData">查询质控数据</el-button>
+      <el-button type="primary"
+                 :loading="load"
+                 @click="queryQualityControlData">查询质控数据
+      </el-button>
     </template>
 
     <template #main>
+      <el-progress :percentage="percentage"/>
       <el-tabs v-model="tabsModel">
         <el-tab-pane label="质控数量" name="质控数量">
-          <rule-total/>
+          <div ref="divRef"></div>
+          <xc-table :localData="numberToArray" :finalHeight="getWindowSize.h / 1.2">
+            <el-table-column prop="name" label="质控名称"/>
+            <el-table-column prop="total" label="总数"/>
+            <el-table-column label="操作">
+              <template #default="{row}">
+                <el-button text @click="detailClick(row)" plain type="primary">详情</el-button>
+              </template>
+            </el-table-column>
+          </xc-table>
         </el-tab-pane>
 
         <el-tab-pane label="详情" name="详情">
-          <rule-sift :data="ruleReturnData.details"/>
+          <rule-sift :data="ruleReturnData.patient"/>
         </el-tab-pane>
 
         <template v-for="(val, key) in siftData">
@@ -31,49 +44,86 @@
 
 </template>
 
-<script setup name='EmrControlRule'>
-import {onMounted} from "vue";
-import {
-  specifyAdmissionQualityControl
-} from '@/api/zhu-yuan-yi-sheng/emr-control-rule'
+<script setup>
+import {onMounted, ref} from "vue";
 import {getDateRangeFormatDate} from "@/utils/date";
 import PageLayer from "@/layout/PageLayer.vue";
 import {shortcuts} from "@/data/shortcuts";
-import RuleTotal
-  from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/RuleTotal.vue";
-import {
-  numberToArray,
-  ruleReturnData, siftData, tabsModel
-} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/rule-store";
 import RuleSift
   from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/RuleSift.vue";
+import {uuid} from "@/utils/getUuid";
+import {setCallback} from "@/utils/websocket";
+import {userInfoStore} from "@/utils/store-public";
+import {linkQualityControl} from "@/api/emr-control/emr-control";
+import {makePercentage} from "@/components/progress/progUtils";
+import {getWindowSize} from "@/utils/window-size";
+import {BizException, ExceptionEnum} from "@/utils/BizException";
+import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
+import {openSocket} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-socket";
 
 const intervalPatients = ref([])
-const dialog = ref(false)
+const load = ref(false)
+
+const sid = userInfoStore.value.code + '_' + uuid(8, 62);
+const percentage = ref(0)
+const numberToArray = ref([])
+const tabsModel = ref('质控数量')
+const ruleReturnData = ref({
+  count: {},
+  patient: []
+})
 
-const queryQualityControlData = () => {
-  let {startTime, endTime} = getDateRangeFormatDate(intervalPatients.value)
+const siftData = ref({})
 
-  specifyAdmissionQualityControl(startTime, endTime).then(res => {
-    siftData.value = {}
-    ruleReturnData.value = res
-    numberToArrayFunc()
-    dialog.value = false
-  })
+const queryQualityControlData = async () => {
+  let {startTime, endTime} = getDateRangeFormatDate(intervalPatients.value)
+  load.value = true
+  percentage.value = 0
+  siftData.value = {}
+  let res = await linkQualityControl(startTime, endTime, sid)
+  ruleReturnData.value = res
+  numberToArrayFunc()
+  load.value = false
 }
 
 const numberToArrayFunc = () => {
   numberToArray.value = []
-  for (let key in ruleReturnData.value.numberOfQuestions) {
+  for (let key in ruleReturnData.value.count) {
     numberToArray.value.push({
       name: key,
-      total: ruleReturnData.value.numberOfQuestions[key]
+      total: ruleReturnData.value.count[key]
     })
   }
 }
 
+const detailClick = ({name, total}) => {
+  if (total === 0) {
+    BizException(ExceptionEnum.MESSAGE_ERROR, "没有指定的病历。")
+  }
+
+  let data = [];
+  for (let i = 0, len = ruleReturnData.value.patient.length; i < len; i++) {
+    let item = JSON.parse(JSON.stringify(ruleReturnData.value.patient[i]))
+    if (item.mapMessage && item.mapMessage[name]) {
+      for (let key in item.mapMessage) {
+        if (key !== name) {
+          delete item.mapMessage[key]
+        }
+      }
+      item.message = JSON.stringify(item.mapMessage[name])
+      data.push(item)
+    }
+  }
+  siftData.value[name] = data;
+  tabsModel.value = name;
+}
+
 onMounted(() => {
   intervalPatients.value = shortcuts[2].value
+  openSocket()
+  setCallback('LINK_CONTROL', (data) => {
+    percentage.value = makePercentage(data.current, data.total)
+  })
 })
 
 </script>

+ 4 - 1
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/RuleSift.vue

@@ -41,7 +41,6 @@
 <script setup name='RuleSift'>
 import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
 import {getWindowSize} from "@/utils/window-size";
-import {mapToStr} from "./rule-store";
 import {Export} from "@/utils/ExportExcel";
 
 const props = defineProps({
@@ -74,6 +73,10 @@ const exportExcel = () => {
   Export(props.data, title, "质控数据")
 }
 
+const mapToStr = (row) => {
+  return JSON.stringify(row.mapMessage)
+}
+
 </script>
 
 <style scoped lang="scss">

+ 0 - 51
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/RuleTotal.vue

@@ -1,51 +0,0 @@
-<template>
-  <xc-table :local-data="numberToArray"
-            :final-height="getWindowSize.h / 1.2">
-    <el-table-column prop="name" label="质控名称"/>
-    <el-table-column prop="total" label="总数"/>
-    <el-table-column label="操作">
-      <template #default="{row}">
-        <el-button @click="detailClick(row)" text plain type="primary">详情</el-button>
-      </template>
-    </el-table-column>
-  </xc-table>
-</template>
-
-<script setup name='RuleTotal'>
-import {
-  numberToArray,
-  ruleReturnData,
-  siftData,
-  tabsModel,
-} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/rule-store";
-import {getWindowSize} from "@/utils/window-size";
-import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
-import {BizException, ExceptionEnum} from "@/utils/BizException";
-
-const detailClick = ({name, total}) => {
-  if (total === 0) {
-    BizException(ExceptionEnum.MESSAGE_ERROR, "没有指定的病历。")
-  }
-  let data = [];
-  for (let i = 0, len = ruleReturnData.value.details.length; i < len; i++) {
-    let item = JSON.parse(JSON.stringify(ruleReturnData.value.details[i]))
-    if (item.mapMessage && item.mapMessage[name]) {
-      for (let key in item.mapMessage) {
-        if (key !== name) {
-          delete item.mapMessage[key]
-        }
-      }
-      item.message = JSON.stringify(item.mapMessage[name])
-      data.push(item)
-    }
-  }
-  siftData.value[name] = data;
-  tabsModel.value = name;
-}
-
-</script>
-
-<style scoped lang="scss">
-
-
-</style>

+ 0 - 20
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr_control_rule/rule-store.ts

@@ -1,20 +0,0 @@
-import {Ref, ref} from "vue";
-
-export const numberToArray = ref([])
-
-export const siftData = ref({})
-
-export const tabsModel = ref('质控数量')
-
-
-export const mapToStr = (row) => {
-    return JSON.stringify(row.mapMessage)
-}
-export const ruleReturnData: Ref<{
-    numberOfQuestions: object,
-    details: Array<any>
-}> = ref({
-        numberOfQuestions: {},
-        details: [],
-    }
-)

+ 99 - 168
src/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/final-quality-control/FinalQualityControl.vue

@@ -1,136 +1,35 @@
-<template>
-  <page-layer>
-    <template #header>
-      质控时间:
-      <el-date-picker style="width: 180px" v-model="queryParam.date" type="daterange" format="YYYY-MM-DD"
-                      value-format="YYYY-MM-DD"/>
-      科室:
-      <el-select style="width: 200px"
-                 v-model="queryParam.deptCode"
-                 clearable
-                 collapse-tags
-                 filterable
-                 multiple
-                 remote>
-        <el-option v-for="item in deptList" :key="item.code" :label="item.name" :value="item.code">
-          <span style="color: #8492a6; font-size: 12px">{{ item.code }}</span>
-          <el-divider direction="vertical"></el-divider>
-          <span>{{ item.name }}</span>
-        </el-option>
-      </el-select>
-      管床医生:
-      <SelectStaffCode style="width: 120px" v-model="queryParam" :name="['tubeBedDoctor', 'tubeBedDoctorName']"/>
-
-      <el-button @click="queryClick">查询</el-button>
-
-      <el-button @click="excelClick">导出excel</el-button>
-    </template>
-
-    <template #main>
-      <xc-table :local-data="data" :final-height="getWindowSize.h / 1.2">
-        <el-table-column type="expand">
-          <template #default="{row}">
-            <JsonViewer :value="row.mapMessage"
-                        copyable
-                        :expandDepth="3"/>
-            <JsonViewer :value="row.qualityControlOpinions"
-                        copyable
-                        :expandDepth="3"/>
-          </template>
-        </el-table-column>
-        <el-table-column prop="inpatientNo" label="住院号" width="120"/>
-        <el-table-column prop="admissTimes" label="次数" width="40"/>
-        <el-table-column prop="name" label="姓名" width="220"/>
-        <el-table-column prop="gradingScale" label="病历评级"/>
-        <el-table-column prop="age" label="年龄"/>
-        <el-table-column prop="clinicDiagStr" label="门(急)诊诊断"/>
-        <el-table-column prop="admissDiag" label="入院诊断"/>
-        <el-table-column prop="admissDate" label="入院时间" width="220"/>
-        <el-table-column prop="deptName" label="入院科室" width="220"/>
-        <el-table-column prop="zkListName" label="转科"/>
-        <el-table-column prop="disDate" label="出院时间"/>
-        <el-table-column prop="admissDay" label="住院天数"/>
-        <el-table-column prop="totalCharge" label="住院费用"/>
-        <el-table-column prop="disDeptName" label="出院科室"/>
-        <el-table-column prop="disDiag" label="出院主诊断"/>
-        <el-table-column prop="typing" label="病历分型"/>
-        <el-table-column prop="deptDirectorName" label="主任医生"/>
-        <el-table-column prop="consultPhysicianName" label="主治医生"/>
-        <el-table-column prop="tubeBedDoctorName" label="管床医生" width="220"/>
-        <el-table-column prop="deathName" label="是否死亡"/>
-        <el-table-column prop="fdcrb" label="法定传染病"/>
-        <el-table-column prop="ssbm" label="手术编码"/>
-        <el-table-column prop="ssmc" label="手术名称"/>
-        <el-table-column prop="operatorName" label="术者"/>
-        <el-table-column prop="level" label="手术级别"/>
-        <el-table-column prop="anaesthesiaName" label="麻醉方式"/>
-        <el-table-column prop="qjcs" label="抢救次数"/>
-        <el-table-column prop="cutName" label="切口分类"/>
-        <el-table-column prop="pathologicDiagStr" label="病理诊断"/>
-        <el-table-column prop="allergicMedicine" label="药物过敏"/>
-        <el-table-column prop="kssName" label="抗生素使用"/>
-        <el-table-column prop="xjpyName" label="细菌培养送检"/>
-
-      </xc-table>
-    </template>
-  </page-layer>
-</template>
-
-<script setup name='FinalQualityControl'>
-import PageLayer from "@/layout/PageLayer.vue";
-import {ref} from "vue";
-import {getDept} from "@/api/public-api";
-import SelectStaffCode from "@/components/SelectStaffCode.vue";
-import {getDateRangeFormatDate} from "@/utils/date";
+<script setup>
+import {onMounted, ref} from "vue";
+import {currentAndAFewDaysAgo, dateRangeAddTime} from "@/utils/date";
+import {finalControl} from "@/api/emr-control/emr-control";
 import XcTable from "@/components/xiao-chan/xc-table/XcTable.vue";
-import {getWindowSize} from "@/utils/window-size";
-import {isDev} from "@/utils/public";
-import {ExcelName} from "@/utils/ExportExcel";
-import {terminalPatients} from "@/api/zhu-yuan-yi-sheng/emr-control-rule";
-import {qieKouName} from "@/components/si-sheet-upload/jieSuanDanXiuGai";
-import {uuid} from "@/utils/getUuid";
-import {sendAMessage} from "@/utils/websocket";
-
-const socketUrl = import.meta.env.VITE_SOCKET_URL
-let id = 'final_emr_rule' + uuid(10, 10)
+import {setCallback} from "@/utils/websocket";
+import {Export} from "@/utils/ExportExcel";
+import {makePercentage} from "@/components/progress/progUtils";
+import {openSocket, sid} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-socket";
 
-const queryParam = ref({
-  date: '',
-  deptCode: '',
-  tubeBedDoctor: '',
-  startDate: '',
-  endDate: '',
-  socketId: ''
-})
-
-const deptList = ref([])
+const dateRange = ref([])
 const data = ref([])
-
+const progressBar = ref({
+  current: 0,
+  total: 0,
+  progress: 0,
+})
 const queryClick = () => {
-
-  let {startTime, endTime} = getDateRangeFormatDate(queryParam.value.date)
-  queryParam.value.startDate = startTime
-  queryParam.value.endDate = endTime
-  queryParam.value.socketId = id
-
-  terminalPatients(queryParam.value).then((res) => {
-    data.value = res
-    console.log(res)
-    setTheName(data.value)
-  })
-}
-
-
-const setTheName = (val) => {
-  val.forEach(item => {
-    item.cutName = qieKouName(item.cut, item.heal)
-    item.kssName = yesOrNo(item.kss)
-    item.xjpyName = yesOrNo(item.xjpy)
+  progressBar.value.progress = 0
+  let {start, end} = dateRangeAddTime(dateRange.value)
+  let temp = {
+    startDate: start,
+    endDate: end,
+    socketId: sid
+  }
+  finalControl(temp).then((res) => {
+    let {patient} = res
+    data.value = patient
   })
 }
 
-
-const excelClick = () => {
+const exportExcelClick = () => {
   let title = {
     inpatientNo: '住院号',
     admissTimes: '次数',
@@ -167,55 +66,87 @@ const excelClick = () => {
     message: '详情',
     opinion: '指控意见'
   }
-  ExcelName(data.value, title)
-}
-
-
-const yesOrNo = (val) => {
-  if (val == 1) {
-    return "是";
-  }
-  if (val == 2) {
-    return "否";
-  }
-  return "";
-};
-
-let socket = null
-
-const webSocket = () => {
-  if (socket != null) return
-  socket = new WebSocket(socketUrl + id);
-
-  socket.onopen = () => {
-    console.log('临时websocket', socketUrl + id)
-  }
-
-  socket.onmessage = (e) => {
-    let data = JSON.parse(e.data)
-    sendAMessage(data.name, data.message)
-  }
+  Export(data.value, title, `${dateRange.value[0]} - ${dateRange.value[1]} 终末质控`)
 }
 
-onDeactivated(() => {
-  socket.close()
-  socket = null
-})
+onMounted(async () => {
+  dateRange.value = await currentAndAFewDaysAgo()
+  openSocket()
+  setCallback('FINAL_CONTROL', (data) => {
+    progressBar.value = data
+    progressBar.value.progress = makePercentage(progressBar.value.current, progressBar.value.total)
+  })
 
-onActivated(() => {
-  webSocket()
 })
 
-onMounted(() => {
-  if (isDev) {
-    queryParam.value.date = ['2023-05-10', '2023-05-10']
-  }
-  getDept().then((res) => {
-    deptList.value = res
-  });
-})
 </script>
 
+<template>
+  <el-container>
+    <el-header style="height: max-content">
+      质控时间:
+      <el-date-picker style="width: 180px" v-model="dateRange" type="daterange" format="YYYY-MM-DD"
+                      value-format="YYYY-MM-DD"/>
+      <el-divider direction="vertical"/>
+      <el-button @click="queryClick">查询</el-button>
+      <el-button @click="exportExcelClick">导出Excel</el-button>
+    </el-header>
+    <el-main>
+      <el-auto-resizer>
+        <template #default="{ height, width }">
+          <el-progress :percentage="progressBar.progress"/>
+          <xc-table :local-data="data"
+                    :final-height="height - 33 - 15"
+                    :default-expand-all="false">
+            <el-table-column type="expand">
+              <template #default="{row}">
+                <JsonViewer :value="row.mapMessage"
+                            copyable
+                            :expandDepth="3"/>
+                <JsonViewer :value="row.qualityControlOpinions"
+                            copyable
+                            :expandDepth="3"/>
+              </template>
+            </el-table-column>
+            <el-table-column prop="inpatientNo" label="住院号" width="120"/>
+            <el-table-column prop="admissTimes" label="次数" width="40"/>
+            <el-table-column prop="name" label="姓名" width="220"/>
+            <el-table-column prop="gradingScale" label="病历评级"/>
+            <el-table-column prop="age" label="年龄"/>
+            <el-table-column prop="clinicDiagStr" label="门(急)诊诊断"/>
+            <el-table-column prop="admissDiag" label="入院诊断"/>
+            <el-table-column prop="admissDate" label="入院时间" width="220"/>
+            <el-table-column prop="deptName" label="入院科室" width="220"/>
+            <el-table-column prop="zkListName" label="转科"/>
+            <el-table-column prop="disDate" label="出院时间"/>
+            <el-table-column prop="admissDay" label="住院天数"/>
+            <el-table-column prop="totalCharge" label="住院费用"/>
+            <el-table-column prop="disDeptName" label="出院科室"/>
+            <el-table-column prop="disDiag" label="出院主诊断"/>
+            <el-table-column prop="typing" label="病历分型"/>
+            <el-table-column prop="deptDirectorName" label="主任医生"/>
+            <el-table-column prop="consultPhysicianName" label="主治医生"/>
+            <el-table-column prop="tubeBedDoctorName" label="管床医生" width="220"/>
+            <el-table-column prop="deathName" label="是否死亡"/>
+            <el-table-column prop="fdcrb" label="法定传染病"/>
+            <el-table-column prop="ssbm" label="手术编码"/>
+            <el-table-column prop="ssmc" label="手术名称"/>
+            <el-table-column prop="operatorName" label="术者"/>
+            <el-table-column prop="level" label="手术级别"/>
+            <el-table-column prop="anaesthesiaName" label="麻醉方式"/>
+            <el-table-column prop="qjcs" label="抢救次数"/>
+            <el-table-column prop="cutName" label="切口分类"/>
+            <el-table-column prop="pathologicDiagStr" label="病理诊断"/>
+            <el-table-column prop="allergicMedicine" label="药物过敏"/>
+            <el-table-column prop="kssName" label="抗生素使用"/>
+            <el-table-column prop="xjpyName" label="细菌培养送检"/>
+          </xc-table>
+        </template>
+      </el-auto-resizer>
+    </el-main>
+  </el-container>
+</template>
+
 <style scoped lang="scss">
 
 </style>