瀏覽代碼

历史病案导出

lighter 1 年之前
父節點
當前提交
eace51ded8

+ 16 - 16
src/api/case-front-sheet/index.js

@@ -228,14 +228,6 @@ export function huoQuHuanZheZhuYaoZhenDuan(patNo, times) {
     })
 }
 
-export function fetchSheets(month) {
-    return request({
-        url: '/frontSheetExport/fetchSheets',
-        method: 'get',
-        params: {month},
-    })
-}
-
 export function analyzeQualityControl(data) {
     return request({
         url: '/caseFrontSheet/analyzeQualityControl',
@@ -322,14 +314,6 @@ export function returnLendOutSheet(id) {
     })
 }
 
-export function getExportableDclData(data) {
-    return request({
-        url: '/frontSheetExport/getExportableDclData',
-        method: 'post',
-        data
-    })
-}
-
 export function submitQualityVerification(data) {
     return request({
         url: '/caseFrontSheet/submitQualityVerification',
@@ -391,4 +375,20 @@ export function fetchExportData(data) {
         method: 'post',
         data
     })
+}
+
+export function fetchSheets(month) {
+    return request({
+        url: '/frontSheetExport/fetchSheets',
+        method: 'get',
+        params: {month},
+    })
+}
+
+export function getExportableDclData(data) {
+    return request({
+        url: '/frontSheetExport/getExportableDclData',
+        method: 'post',
+        data
+    })
 }

+ 46 - 48
src/utils/excel.js

@@ -1,65 +1,63 @@
 import axios from 'axios'
 import XLSX from 'xlsx'
-import { startLoading, endLoading } from './loading'
-import { ElMessage } from 'element-plus'
+import {startLoading, endLoading} from './loading'
+import {ElMessage} from 'element-plus'
 import {useProgressBarStore} from "@/pinia/progress-bar-store";
-import {useUserStore} from "@/pinia/user-store";
 
 const apiUrl = import.meta.env.VITE_BASE_URL
 
 export function writeExcelFile(workSheet, fileName) {
-  const workBook = XLSX.utils.book_new()
-  XLSX.utils.book_append_sheet(workBook, workSheet, 'sheet1')
-  XLSX.writeFile(workBook, fileName)
-  endLoading()
+    const workBook = XLSX.utils.book_new()
+    XLSX.utils.book_append_sheet(workBook, workSheet, 'sheet1')
+    XLSX.writeFile(workBook, fileName)
+    endLoading()
 }
 
 export function createWorkSheet(data, fields, titles) {
-  const workSheet = XLSX.utils.json_to_sheet(data, { header: fields })
-  const range = XLSX.utils.decode_range(workSheet['!ref'])
-  for (let c = range.s.c; c <= range.e.c; c++) {
-    const header = XLSX.utils.encode_col(c) + '1'
-    workSheet[header].v = titles[workSheet[header].v]
-  }
-  return workSheet
+    const workSheet = XLSX.utils.json_to_sheet(data, {header: fields})
+    const range = XLSX.utils.decode_range(workSheet['!ref'])
+    for (let c = range.s.c; c <= range.e.c; c++) {
+        const header = XLSX.utils.encode_col(c) + '1'
+        workSheet[header].v = titles[workSheet[header].v]
+    }
+    return workSheet
 }
 
 const progressBarStore = useProgressBarStore()
+
 export function downloadExcel(data) {
-  if (data.jdt) {
-    progressBarStore.initialize({
-        title: '正在导出 Excel',
-        isOpen: true,
-        closeButton: false
-    })
-  } else {
-    startLoading()
-  }
-  axios({
-    method: data.method || 'post',
-    url: apiUrl + data.url,
-    data: data.param,
-    responseType: 'blob',
-    headers: {
-      token: localStorage.token,
-    },
-  })
-    .then((res) => {
-      const link = document.createElement('a')
-      let blob = new Blob([res.data], { type: 'application/vnd.ms-excel' })
-      link.style.display = 'none'
-      link.href = URL.createObjectURL(blob)
-      link.download = data.fileName //下载的文件名
-      document.body.appendChild(link)
-      link.click()
-      document.body.removeChild(link)
-      endLoading()
-      progressBarStore.closeProgressBar()
-    })
-    .catch((error) => {
-      ElMessage.error('网络连接错误', '错误')
-      console.error(error)
-      endLoading()
+    if (data.jdt) {
+        progressBarStore.initialize({
+            title: '正在导出 Excel',
+            isOpen: true,
+            closeButton: false
+        })
+    } else {
+        startLoading()
+    }
+    axios({
+        method: data.method || 'post',
+        url: apiUrl + data.url,
+        data: data.param,
+        responseType: 'blob',
+        headers: {
+            token: localStorage.token,
+        },
+    }).then((res) => {
+        const link = document.createElement('a')
+        let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'})
+        link.style.display = 'none'
+        link.href = URL.createObjectURL(blob)
+        link.download = data.fileName //下载的文件名
+        document.body.appendChild(link)
+        link.click()
+        document.body.removeChild(link)
+        endLoading()
+        progressBarStore.closeProgressBar()
+    }).catch((error) => {
+        ElMessage.error('网络连接错误', '错误')
+        console.error(error)
+        endLoading()
         progressBarStore.closeProgressBar()
     })
 }

+ 11 - 4
src/views/hospitalization/case-front-sheet/FillCaseFrontSheet.vue

@@ -4,10 +4,10 @@
       <el-select v-model="currentWard" @change="handleWardChange" style="width: 120px" filterable>
         <el-option v-for="item in userWards" :key="item.code" :value="item.code" :label="item.name"></el-option>
       </el-select>
-      <el-select v-model="inOutStatus" style="width: 80px" @change="changeInOutStatus">
+      <el-select v-model="inOutStatus" style="width: 80px;margin-right: 8px" @change="changeInOutStatus">
         <el-option v-for="item in inOutOptions" :key="item.code" :value="item.code" :label="item.name"></el-option>
       </el-select>
-      <el-button type="primary" icon="Date" v-show="inOutStatus === 2" @click="showSelectDateRange = true"> 日期范围
+      <el-button type="primary" icon="Clock" v-show="inOutStatus === 2" @click="showSelectDateRange = true"> 日期范围
       </el-button>
       <el-divider direction="vertical"></el-divider>
       <el-input v-model="inpatientNo" style="width: 110px" placeholder="住院号" clearable></el-input>
@@ -16,7 +16,7 @@
       <el-button type="primary" icon="Edit" @click="openYbDiag" v-if="inOutStatus === 1">医保诊断</el-button>
       <el-button type="primary" icon="Upload" @click="saveVerify(1)">保存首页</el-button>
       <el-dropdown trigger="click" type="primary" @command="sheetQualityVerification" style="margin: 0 8px">
-        <el-button type="primary">病案质控<i class="el-icon-arrow-down el-icon--right"></i></el-button>
+        <el-button icon="DataLine" type="primary">病案质控<i class="el-icon-arrow-down el-icon--right"></i></el-button>
         <template #dropdown>
           <el-dropdown-menu>
             <el-dropdown-item command="applyVerification">申请审核</el-dropdown-item>
@@ -26,8 +26,10 @@
       </el-dropdown>
       <el-button type="success" icon="Printer" @click="beforePrint(1)">打印正面</el-button>
       <el-button type="success" icon="Printer" @click="beforePrint(2)">打印反面</el-button>
-      <el-button type="primary" icon="PieChart" @click="setlUplaodClick" v-if="inOutStatus === 2">结算清单质控
+      <el-button type="primary" icon="PieChart" @click="setlUplaodClick" v-if="inOutStatus === 2">
+        结算清单质控
       </el-button>
+      <el-button type="danger" icon="Download" @click="showExportPanel">历史病案导出</el-button>
     </header>
     <div class="layout_main layout_container layout-horizontal">
       <aside class="layout_el-table">
@@ -1124,6 +1126,7 @@ import {xcMessage} from "@/utils/xiaochan-element-plus";
 import useDialogToJs from "@/components/js-dialog-comp/useDialogToJs";
 import AuditHistory from "@/components/inpatient/frontsheet-printpage/AuditHistory.vue";
 import {useUserStore} from "@/pinia/user-store";
+import HistorySheetExport from "@/views/hospitalization/case-front-sheet/component/HistorySheetExport.vue";
 
 const userWards = ref([])
 const currentWard = ref('')
@@ -1975,6 +1978,10 @@ onActivated(async () => {
   }
 })
 
+function showExportPanel() {
+  useDialogToJs(HistorySheetExport, {})
+}
+
 onMounted(() => {
   scrollWrapper.value = document.getElementById('scrollWrapper')
   initLodop()

+ 38 - 0
src/views/hospitalization/case-front-sheet/common.js

@@ -79,3 +79,41 @@ export function clone(obj) {
   }
   return ret
 }
+
+export const fieldMap= {
+  bah: '住院号',
+  admissTimes: '住院次数',
+  name: '姓名',
+  sex: '性别',
+  birthDate: '出生日期',
+  socialNo: '证件号码',
+  phone: '联系方式',
+  zyAdmissWay: '入院方式',
+  medType: '医疗类别',
+  admissDate: '入院时间',
+  admissDept: '入院科室',
+  dismissDate: '出院时间',
+  dismissDept: '出院科室',
+  admissDays: '住院天数',
+  clinicDiagCode: '门(急)诊诊断编码',
+  clinicDiagStr: '门(急)诊诊断名称',
+  hurtReasonCode: '意外伤害编码',
+  hurtReasonName: '意外伤害名称',
+  pathologicDiagCode: '病理诊断编码',
+  pathologicDiagStr: '病理诊断名称',
+  blh: '病理号',
+  leaderDoctorName: '主任(副主任)医师',
+  mainDoctorName: '主治医师',
+  admissDoctorName: '住院医师',
+  dutyNurseName: '责任护士',
+  qualityControlLevel: '病案质量',
+  qualityControlDoctorName: '质控医师',
+  qualityControlNurseName: '质控护士',
+  qualityControlDate: '质控日期',
+  zyDismissWay: '离院方式',
+  totalCost: '总费用',
+  tumorLevelT: '肿瘤分期(T)',
+  tumorLevelN: '肿瘤分期(N)',
+  tumorLevelM: '肿瘤分期(M)',
+  tumorLevel: '肿瘤分期',
+}

+ 188 - 0
src/views/hospitalization/case-front-sheet/component/HistorySheetExport.vue

@@ -0,0 +1,188 @@
+<template>
+  <CyDialog
+    title="历史病案导出"
+    confirm-text="导出"
+    body-width="600px"
+    :confirm-click="executeExport"
+  >
+    <div class="layout_container history-sheet-export">
+      <div class="flex-line">
+        <div class="label">文件名</div>
+        <div class="value">
+          {{ fileName }}
+        </div>
+      </div>
+      <div class="flex-line">
+        <div class="label">出院日期</div>
+        <div class="value">
+          <CyDateRange style="width: 320px"/>
+        </div>
+      </div>
+      <div class="flex-line">
+        <div class="label">导出诊断</div>
+        <div class="value">
+          <el-radio-group v-model="inquiry.needAllDiagnoses">
+            <el-radio :value="true">导出全部诊断</el-radio>
+            <el-radio :value="false">只导出主诊断</el-radio>
+          </el-radio-group>
+        </div>
+      </div>
+      <div class="flex-line">
+        <div class="label">导出手术</div>
+        <div class="value">
+          <el-radio-group v-model="inquiry.needAllSurgeries">
+            <el-radio :value="true" >导出全部手术</el-radio>
+            <el-radio :value="false" >只导出主手术</el-radio>
+          </el-radio-group>
+        </div>
+      </div>
+      <div class="flex-line">
+        <div class="label">选择表头</div>
+        <div class="value">
+          <div class="with-border">
+            <div class="check-all">
+              <el-checkbox
+                  v-model="checkAll"
+                  :indeterminate="isIndeterminate"
+                  @change="handleCheckAllChange"
+              >
+                选择全部
+              </el-checkbox>
+            </div>
+            <div class="field-check">
+              <el-checkbox-group
+                  v-model="checkedFields"
+                  @change="handleCheckedFieldsChange"
+              >
+                <div v-for="code in fieldCodeList" class="check-single">
+                  <el-checkbox
+                      :key="code"
+                      :value="code"
+                  >
+                    {{fieldMap[code]}}
+                  </el-checkbox>
+                </div>
+              </el-checkbox-group>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </CyDialog>
+</template>
+<script setup lang="ts">
+import CyDialog from "@/components/cy/dialog/src/CyDialog.vue";
+import useDateRange from "@/utils/cy-use/useDateRange";
+import {fieldMap} from "@/views/hospitalization/case-front-sheet/common";
+import {downloadExcel} from "@/utils/excel";
+
+const {CyDateRange, dateRange} = useDateRange({shortcutsIndex: 5, clearable: false})
+
+const fileName = computed(() => {
+  return `病案历史记录(${dateRange.value.start.split(' ')[0]}
+   至 ${dateRange.value.end.split(' ')[0]}).xlsx`
+})
+
+const inquiry = reactive({
+  needAllDiagnoses: true,
+  needAllSurgeries: true,
+  start: '',
+  end: ''
+})
+
+const checkAll = ref(false)
+const isIndeterminate = ref(true)
+const fieldCodeList = ref([])
+const checkedFields = ref([])
+
+function handleCheckAllChange(val) {
+  checkedFields.value = val ? fieldCodeList.value : []
+  isIndeterminate.value = false
+}
+
+function handleCheckedFieldsChange(val) {
+  const checkedCount = val.length
+  checkAll.value = checkedCount === fieldCodeList.value.length
+  isIndeterminate.value = checkedCount > 0 && checkedCount < fieldCodeList.value.length
+}
+
+function executeExport() {
+  inquiry.start = dateRange.value.start.split(" ")[0]
+  inquiry.end = dateRange.value.end.split(" ")[0]
+  inquiry.field = generateFields()
+  downloadExcel({
+    param: inquiry,
+    url: '/frontSheetExport/getHistorySheets',
+    fileName: fileName.value
+  })
+}
+
+function generateFields() {
+  let temp = []
+  checkedFields.value.forEach(item => {
+    temp.push({code:item, name: fieldMap[item]})
+  })
+  return temp;
+}
+
+onMounted(() => {
+  inquiry.start = dateRange.value.start.split(" ")[0]
+  inquiry.end = dateRange.value.end.split(" ")[0]
+  for (let key in fieldMap) {
+    fieldCodeList.value.push(key)
+  }
+  checkedFields.value = ['bah','admissTimes',"name"]
+})
+</script>
+
+<style lang="scss">
+.history-sheet-export {
+  .flex-line {
+    display: flex;
+    width: 100%;
+    align-items: center;
+    margin-bottom: 12px;
+    > .label {
+      flex: 1;
+      font-size: 14px;
+      font-weight: bold;
+      text-align: right;
+      padding-right: 20px;
+    }
+    > .value {
+      flex: 3;
+      text-align: left;
+      .el-radio {
+        margin-right: 20px;
+      }
+      .field-check {
+        height: 260px;
+        overflow-y: scroll;
+      }
+      > div {
+        width: 320px;
+      }
+      .check-all {
+        background-color: #ededed;
+        padding: 2px 12px;
+        .el-checkbox__label {
+          font-weight: bold;
+          color: #353535;
+        }
+      }
+      .check-single {
+        padding: 0 12px;
+        .el-checkbox__label {
+          color: #353535;
+        }
+      }
+      .el-checkbox__inner {
+        border-radius: 0;
+      }
+    }
+    .with-border {
+      border: 1px solid #dfdfdf;
+    }
+  }
+}
+</style>