Procházet zdrojové kódy

完善结算单上传。

lighter před 3 roky
rodič
revize
6a2c264a2d

+ 3 - 3
src/App.vue

@@ -5,9 +5,9 @@
 </template>
 
 <script>
-import {defineComponent} from 'vue'
+import { defineComponent } from 'vue'
 import locale from 'element-plus/lib/locale/lang/zh-cn'
-import {useStore} from 'vuex'
+import { useStore } from 'vuex'
 
 export default defineComponent({
   name: 'App',
@@ -24,7 +24,7 @@ export default defineComponent({
 function getWindowSize() {
   const w = window.innerWidth
   const h = window.innerHeight - 96
-  return {w, h}
+  return { w, h }
 }
 </script>
 

+ 16 - 0
src/api/medical-insurance/si-manage.js

@@ -39,3 +39,19 @@ export function revokeCatalogueContrast(data) {
     data,
   })
 }
+
+export function upldSetlList(data) {
+  return request({
+    url: '/siManage/upldSetlList',
+    method: 'post',
+    data,
+  })
+}
+
+export function upldSetlListTimes(startTime, endTime, insutype) {
+  return request({
+    url: '/siManage/upldSetlListTimes',
+    method: 'get',
+    params: { startTime, endTime, insutype },
+  })
+}

+ 79 - 77
src/utils/websocket.js

@@ -1,4 +1,4 @@
-import {ElMessageBox, ElNotification} from 'element-plus'
+import { ElMessageBox, ElNotification } from 'element-plus'
 import Cookies from 'js-cookie'
 import router from '@/router'
 import store from '@/store'
@@ -9,93 +9,95 @@ let webSocket = null
 let globalCallback = null
 
 export function closeWebSocket() {
-    Cookies.remove('sid')
-    if (webSocket !== null) {
-        webSocket.close()
-        webSocket = null
-    }
+  Cookies.remove('sid')
+  if (webSocket !== null) {
+    webSocket.close()
+    webSocket = null
+  }
 }
 
 export function setCallback(callback) {
-    if (callback !== null) {
-        globalCallback = callback
-        console.log('global callback settled.')
-    }
+  if (callback !== null) {
+    globalCallback = callback
+    console.log('global callback settled.')
+  }
 }
 
 export function initWebSocket(sid) {
-    if ('WebSocket' in window) {
-        if (webSocket === null) {
-            const url = socketUrl + sid
-            webSocket = new WebSocket(url)
-        }
-    } else {
-        alert('该浏览器不支持websocket!')
-        webSocket = 'unsupport'
+  if ('WebSocket' in window) {
+    if (webSocket === null) {
+      const url = socketUrl + sid
+      webSocket = new WebSocket(url)
     }
+  } else {
+    alert('该浏览器不支持websocket!')
+    webSocket = 'unsupport'
+  }
 
-    webSocket.onopen = function () {
-        console.log('WebSocket连接成功')
-    }
+  webSocket.onopen = function () {
+    console.log('WebSocket连接成功')
+  }
 
-    webSocket.onmessage = function (e) {
-        let data = JSON.parse(e.data)
-        if (data.name === 'refreshToken') {
-            store.commit('user/tokenChange', data.token)
-        } else if (data.name === 'systemNotification') {
-            ElNotification({
-                title: typeof data.title === 'undefined' ? '新消息' : data.title,
-                message: data.message,
-                dangerouslyUseHTMLString: true,
-                type: typeof data.type === 'undefined' ? 'warning' : data.type,
-                duration: 0,
-            })
-            if (data.refreshDelay) {
-                setTimeout(() => {
-                    location.reload()
-                }, data.refreshDelay)
-            }
-            if (null !== globalCallback) {
-                globalCallback(data)
-            }
-        } else if (data.name === 'upldSetlListMessage') {
-            console.log("医保结算单上传的错误信息", data)
-        } else {
-            if (null !== globalCallback) {
-                globalCallback(data)
-            }
-        }
+  webSocket.onmessage = function (e) {
+    let data = JSON.parse(e.data)
+    if (data.name === 'refreshToken') {
+      store.commit('user/tokenChange', data.token)
+    } else if (data.name === 'systemNotification') {
+      ElNotification({
+        title: typeof data.title === 'undefined' ? '新消息' : data.title,
+        message: data.message,
+        dangerouslyUseHTMLString: true,
+        type: typeof data.type === 'undefined' ? 'warning' : data.type,
+        duration: 0,
+      })
+      if (data.refreshDelay) {
+        setTimeout(() => {
+          location.reload()
+        }, data.refreshDelay)
+      }
+      if (null !== globalCallback) {
+        globalCallback(data)
+      }
+    } else if (data.name === 'upldSetlListMessage') {
+      if (null != globalCallback) {
+        globalCallback(data)
+      }
+    } else {
+      if (null !== globalCallback) {
+        globalCallback(data)
+      }
     }
+  }
 
-    webSocket.onclose = function () {
-        webSocket = null
-        let sid
-        if (router.currentRoute.value.path === '/triageRoomScreen') {
-            sid = Cookies.get('room-screen-sid')
-        } else {
-            sid = store.getters['user/sid']
-        }
-        if (!sid) {
-            if (router.currentRoute.value.path === '/login') {
-                return
-            }
-            ElMessageBox.confirm('未检测到WebSocket连接的sid,请重新登录。', '提示', {
-                showCancelButton: false,
-                type: 'warning',
-            }).then(() => {
-                router.push('/login')
-            })
-        } else {
-            if (router.currentRoute.value.path === '/triageFloorScreen') {
-                sid += '-triageFloorScreen'
-            }
-            setTimeout(() => {
-                initWebSocket(sid)
-            }, 3000)
-        }
+  webSocket.onclose = function () {
+    webSocket = null
+    let sid
+    if (router.currentRoute.value.path === '/triageRoomScreen') {
+      sid = Cookies.get('room-screen-sid')
+    } else {
+      sid = store.getters['user/sid']
     }
-
-    webSocket.onerror = function () {
-        console.error('WebSocket连接发生错误')
+    if (!sid) {
+      if (router.currentRoute.value.path === '/login') {
+        return
+      }
+      ElMessageBox.confirm('未检测到WebSocket连接的sid,请重新登录。', '提示', {
+        showCancelButton: false,
+        type: 'warning',
+      }).then(() => {
+        router.push('/login')
+      })
+    } else {
+      if (router.currentRoute.value.path === '/triageFloorScreen') {
+        sid += '-triageFloorScreen'
+      }
+      setTimeout(() => {
+        initWebSocket(sid)
+      }, 3000)
     }
+  }
+
+  webSocket.onerror = function () {
+    console.error('WebSocket连接发生错误')
+  }
 }

+ 187 - 36
src/views/medical-insurance/allpatient/SetlInfo.vue

@@ -1,32 +1,41 @@
 <template>
   <el-container>
     <el-header style="height: 35px; margin-top: 10px">
-      <el-select v-model="slctSetlPrm.clrType" placeholder="结算类别" style="width: 100px">
+      <el-select v-model="slctSetlPrm.clrType" placeholder="结算类别" style="width: 100px" @change="setlinfos = []">
         <el-option v-for="item in clrTypes" :key="item.code" :value="item.code" :label="item.name"></el-option>
       </el-select>
       <el-date-picker
-          v-model="dateRange"
-          type="daterange"
-          :shortcuts="setlShtcuts"
-          range-separator="至"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期"
-          style="width: 220px"
+        v-model="dateRange"
+        type="daterange"
+        :shortcuts="setlShtcuts"
+        range-separator="至"
+        start-placeholder="开始日期"
+        end-placeholder="结束日期"
+        style="width: 220px"
+        @change="setlinfos = []"
       ></el-date-picker>
-      <el-select v-model="slctSetlPrm.insutype" placeholder="险种类型" filterable clearable>
+      <el-select v-model="slctSetlPrm.insutype" placeholder="险种类型" filterable clearable style="width: 120px" @change="currentPage = 1">
         <el-option v-for="item in insutypes" :key="item.code" :value="item.code" :label="item.name"></el-option>
       </el-select>
-      <el-select v-model="slctSetlPrm.clrOptins" placeholder="清算机构" filterable clearable
-                 :disabled="setlinfos.length === 0">
+      <el-select v-model="slctSetlPrm.clrOptins" placeholder="清算机构" filterable clearable :disabled="setlinfos.length === 0" style="width: 120px" @change="currentPage = 1">
         <el-option v-for="item in optins" :key="item.code" :value="item.code" :label="item.name"></el-option>
       </el-select>
       <el-divider direction="vertical"></el-divider>
       <el-button type="primary" icon="el-icon-search" @click="getSetlInfos">检索</el-button>
       <el-button type="primary" icon="el-icon-coin" @click="bfrChkSetl">对总账</el-button>
       <el-button type="primary" icon="el-icon-data-analysis" @click="setlDtlCheck">明细对账</el-button>
+      <el-button type="success" @click="upldAllList">全部上传</el-button>
+      <el-button type="success" @click="upldSelections">上传选中条目</el-button>
     </el-header>
     <el-main>
-      <el-table :data="cptSetlinfos" stripe :height="tableHeight" highlight-current-row>
+      <el-table
+        :data="cptSetlinfos.slice(pageSize * (currentPage - 1), pageSize * currentPage)"
+        stripe
+        :height="tableHeight"
+        highlight-current-row
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="35"></el-table-column>
         <el-table-column type="index" label="序号"></el-table-column>
         <el-table-column prop="patNo" label="住院号/门诊号"></el-table-column>
         <el-table-column prop="times" label="次数"></el-table-column>
@@ -45,6 +54,16 @@
         <el-table-column prop="psnCashPay" label="个人现金支出"></el-table-column>
         <el-table-column prop="clrOptinsName" label="清算机构"></el-table-column>
       </el-table>
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="currentPage"
+        :page-sizes="[15, 30, 45, 60]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="cptSetlinfos.length"
+        style="margin-top: 5px"
+      ></el-pagination>
       <el-dialog v-model="showSetlDtlCheckRslt" title="明细对账结果">
         <el-table :data="setlDtlCheckRslt" stripe :height="300" highlight-current-row>
           <el-table-column type="index" label="序号"></el-table-column>
@@ -58,38 +77,89 @@
         </el-table>
       </el-dialog>
     </el-main>
+    <div style="position: fixed; z-index: 10000">
+      <el-dialog v-model="showUpldRsps" title="结算单上传详情" :close-on-click-modal="false" :close-on-press-escape="false" :before-close="beforeCloseUpldRsps">
+        <el-progress :text-inside="true" title="sd" :stroke-width="22" :percentage="percentage" status="success">
+          <span><i v-show="percentage < 100" class="el-icon-loading"></i> {{ cptUpldRsTxt }}</span>
+        </el-progress>
+        <el-divider></el-divider>
+        <el-table ref="upldRsTbl" :data="upldRsps" height="300" stripe>
+          <el-table-column type="index" label="序号" width="40">
+            <template #default="scope">
+              <span :style="{ color: scope.row.code === 200 ? 'green' : 'red' }"> {{ scope.$index + 1 }} </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="住院号" width="80">
+            <template #default="scope">
+              <span :style="{ color: scope.row.code === 200 ? 'green' : 'red' }">{{ scope.row.patNo }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="次数" width="40">
+            <template #default="scope">
+              <span :style="{ color: scope.row.code === 200 ? 'green' : 'red' }">{{ scope.row.times }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="账页号" width="50">
+            <template #default="scope">
+              <span :style="{ color: scope.row.code === 200 ? 'green' : 'red' }">{{ scope.row.ledgerSn }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="上传结果">
+            <template #default="scope">
+              <span :style="{ color: scope.row.code === 200 ? 'green' : 'red' }">{{ scope.row.message }}</span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-dialog>
+    </div>
   </el-container>
 </template>
 
 <script>
-import {computed, onMounted, reactive, ref} from '@vue/runtime-core'
+import { computed, onActivated, onMounted, reactive, ref } from '@vue/runtime-core'
 import store from '@/store'
-import {getClrTypes, getInsutypes} from '@/api/medical-insurance/si-dict'
-import {setlShtcuts} from '@/data/shortcuts'
-import {ElMessage, ElMessageBox} from 'element-plus'
-import {
-  institutionSettlementDetailCheck,
-  institutionSettlementLedgerCheck,
-  selectSetlinfos
-} from '@/api/medical-insurance/si-manage'
-import {formatDate} from '@/utils/date'
+import { getClrTypes, getInsutypes } from '@/api/medical-insurance/si-dict'
+import { setlShtcuts } from '@/data/shortcuts'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { institutionSettlementDetailCheck, institutionSettlementLedgerCheck, selectSetlinfos, upldSetlList, upldSetlListTimes } from '@/api/medical-insurance/si-manage'
+import { formatDate } from '@/utils/date'
+import { getDateRangeFormatDate } from '../../../utils/date'
+import { setCallback } from '@/utils/websocket'
 
 export default {
   setup() {
     const windowSize = store.state.app.windowSize
-    const tableHeight = windowSize.h - 45
+    const tableHeight = windowSize.h - 100
     const insutypes = ref([])
     const clrTypes = ref([])
     const dateRange = ref(null)
     const setlinfos = ref([])
     const optins = ref([])
+    const showUpldRsps = ref(false)
+    const upldRsps = ref([])
+    const percentage = ref(0)
+    const upldRsTbl = ref(null)
+    const cptUpldRsTxt = computed(() => {
+      if (percentage.value < 100) {
+        return `上传中 ( ${percentage.value}% ) ...`
+      }
+      return '上传完成(100%)'
+    })
     const slctSetlPrm = reactive({
-      insutype: null,
+      insutype: '',
       clrType: null,
       clrOptins: null,
       begndate: null,
       enddate: null,
     })
+    const pageSize = ref(30)
+    const currentPage = ref(1)
+    const handleSizeChange = (val) => {
+      pageSize.value = val
+    }
+    const handleCurrentChange = (val) => {
+      currentPage.value = val
+    }
     const cptSetlinfos = computed(() => {
       return setlinfos.value.filter((item) => {
         if (!slctSetlPrm.insutype && !slctSetlPrm.clrOptins) {
@@ -127,14 +197,14 @@ export default {
       slctSetlPrm.begndate = formatDate(dateRange.value[0])
       slctSetlPrm.enddate = formatDate(dateRange.value[1])
       selectSetlinfos(slctSetlPrm)
-          .then((res) => {
-            setlinfos.value = res.list
-            optins.value = res.optins
-          })
-          .catch(() => {
-            setlinfos.value = []
-            optins.value = []
-          })
+        .then((res) => {
+          setlinfos.value = res.list
+          optins.value = res.optins
+        })
+        .catch(() => {
+          setlinfos.value = []
+          optins.value = []
+        })
     }
 
     const bfrChkSetl = () => {
@@ -229,6 +299,74 @@ export default {
       })
     }
 
+    const upldAllList = () => {
+      if (slctSetlPrm.clrType !== '21') {
+        ElMessage({
+          message: '结算类别请选择为【住院】!',
+          type: 'warning',
+          showClose: true,
+        })
+        return
+      }
+      if (!dateRange.value) {
+        ElMessage({
+          message: '请选择日期范围!',
+          type: 'warning',
+          showClose: true,
+        })
+        return
+      }
+      const dates = getDateRangeFormatDate(dateRange.value)
+      showUpldRsps.value = true
+      upldSetlListTimes(dates.startTime, dates.endTime, slctSetlPrm.insutype).then(() => {
+        ElMessage({
+          message: '上传完成。',
+          type: 'info',
+          duration: 2500,
+          showClose: true,
+        })
+      })
+    }
+
+    const selections = ref([])
+    const handleSelectionChange = (val) => {
+      selections.value = val
+    }
+
+    const upldSelections = () => {
+      showUpldRsps.value = true
+      upldSetlList(selections.value).then(() => {
+        ElMessage({
+          message: '上传完成。',
+          type: 'info',
+          duration: 2500,
+          showClose: true,
+        })
+      })
+    }
+
+    const beforeCloseUpldRsps = (done) => {
+      percentage.value = 0
+      upldRsps.value = []
+      done()
+    }
+
+    const socketCallback = (data) => {
+      switch (data.name) {
+        case 'upldSetlListMessage':
+          upldRsps.value.push(data)
+          percentage.value = data.percentage
+          upldRsTbl.value.$refs.bodyWrapper.scrollTop = upldRsTbl.value.$refs.bodyWrapper.scrollHeight
+          break
+        default:
+          break
+      }
+    }
+
+    onActivated(() => {
+      setCallback(socketCallback)
+    })
+
     onMounted(() => {
       getInsutypes().then((res) => {
         insutypes.value = res
@@ -247,12 +385,25 @@ export default {
       setlShtcuts,
       setlinfos,
       cptSetlinfos,
+      pageSize,
+      currentPage,
+      setlDtlCheckRslt,
+      optins,
+      showSetlDtlCheckRslt,
+      showUpldRsps,
+      upldRsTbl,
+      upldRsps,
+      percentage,
+      cptUpldRsTxt,
+      upldSelections,
+      handleCurrentChange,
+      handleSizeChange,
       getSetlInfos,
       bfrChkSetl,
-      optins,
+      upldAllList,
+      handleSelectionChange,
       setlDtlCheck,
-      setlDtlCheckRslt,
-      showSetlDtlCheckRslt,
+      beforeCloseUpldRsps,
     }
   },
 }
@@ -272,6 +423,6 @@ function calSumamt(list) {
   fundSum = fundSum.toFixed(2)
   acctSum = acctSum.toFixed(2)
   psnCashPay = psnCashPay.toFixed(2)
-  return {medSum, fundSum, acctSum, psnCashPay}
+  return { medSum, fundSum, acctSum, psnCashPay }
 }
 </script>

+ 2 - 2
src/views/medical-insurance/inpatient/InHospFeeUpload.vue

@@ -173,6 +173,7 @@ export default {
     onActivated(() => {
       actived.value = true
       store.commit('app/setCurrentPageName', 'inHospFeeUpload')
+      setCallback(socketCallback)
     })
 
     onDeactivated(() => {
@@ -434,7 +435,6 @@ export default {
     }
 
     onMounted(() => {
-      setCallback(socketCallback)
       if (patient.value.inpatientNo) {
         fetchProjectFees()
         fetchMedicineFees()
@@ -510,7 +510,7 @@ function initPage() {
   left: 0;
   right: 0;
   bottom: 0;
-  z-index: 10000;
+  z-index: 8888;
   background-color: rgba(0, 0, 0, 0.6);
 }
 .dj-center-box-wrapper {