123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- <template>
- <div>
- <el-button type="success" @click="feeDtle">费用明细</el-button>
- <el-button type="success" @click="preCalculateCost">医保试算</el-button>
- <el-button type="success" @click="uploadFees">费用上传</el-button>
- <el-button type="warning" :disabled="!isAdmin" @click="cancelFees">取消上传</el-button>
- <el-button type="primary" @click="weiGuiTuiFeiFenXiDialogOpen(true)">违规费用分析</el-button>
- <el-popover placement="left" width="730" trigger="click">
- <template #reference>
- <el-button type="warning" icon="CircleClose" plain>错误信息 ({{ errorMessages.length }})</el-button>
- </template>
- <el-tag type="info">错误信息</el-tag>
- <el-divider direction="vertical"></el-divider>
- <el-button type="warning" @click="clearErrorMessages">清除内容</el-button>
- <el-table width="700" max-height="300" class="errTable" :data="errorMessages">
- <el-table-column width="80" property="patNo" label="住院号"></el-table-column>
- <el-table-column width="80" property="patName" label="姓名"></el-table-column>
- <el-table-column width="450" property="message" label="错误详情"></el-table-column>
- </el-table>
- </el-popover>
-
- <el-tag type="info" size="small">
- <span style="color: black">¥ {{ patient.totalCharge }}</span>
- <span style="color: orangered">¥ {{ patient.chargeYb }}</span>
- </el-tag>
- <el-tag>可用余额:{{ patient.balance }}</el-tag>
- </div>
- <div style="margin-top: 4px">
- <el-tag type="info">治疗明细</el-tag>
- <el-tag>合计:¥ {{ xmFeeSum }}</el-tag>
- <el-table :data="xmFeeList" stripe :height="feeTableHeight">
- <el-table-column prop="detailSn" label="流水号" width="80"></el-table-column>
- <el-table-column prop="chargeCodeMx" label="院内码" width="100"></el-table-column>
- <el-table-column prop="chargeAmount" label="数量" sortable width="80"></el-table-column>
- <el-table-column prop="chargeFee" label="金额" width="80"></el-table-column>
- <el-table-column prop="chargeDate" label="收费日期"></el-table-column>
- <el-table-column prop="ybCode" :label="ybCodeLabel"></el-table-column>
- <el-table-column prop="chargeName" label="项目名称"></el-table-column>
- <el-table-column prop="ybSelfFlag" label="报销" width="80"></el-table-column>
- <el-table-column>
- <template #default="scope">
- <el-button circle v-if="!injuryMode && patient.mdtrtId && scope.row.chargeAmount < 0"
- @click="fixNegativeFeeUploadProblem(scope.row, 1)">
- <i class="iconfont icon-tools-hardware" style="font-size: 10px;"></i>
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <el-pagination
- @size-change="handleXmSizeChange"
- @current-change="handleCurrentXmChange"
- :current-page="page.xmPage"
- :page-sizes="[10, 30, 50, 70, 100, 300]"
- :page-size="page.xmPageSize"
- layout="total, sizes, prev, pager, next"
- :total="xmTotalSize"
- >
- </el-pagination>
- <div style="height: 5px"></div>
- <el-tag type="info">药品明细</el-tag>
- <el-tag>合计:¥ {{ ypFeeSum }}</el-tag>
- <el-table :data="ypFeeList" stripe :height="feeTableHeight">
- <el-table-column prop="detailSn" label="流水号" width="80"></el-table-column>
- <el-table-column prop="chargeCodeMx" label="院内码" width="100"></el-table-column>
- <el-table-column prop="chargeAmount" label="数量" sortable width="80"></el-table-column>
- <el-table-column prop="chargeFee" label="金额" width="80"></el-table-column>
- <el-table-column prop="chargeDate" label="收费日期"></el-table-column>
- <el-table-column prop="ybCode" :label="ybCodeLabel"></el-table-column>
- <el-table-column prop="chargeName" label="项目名称"></el-table-column>
- <el-table-column prop="ybSelfFlag" label="报销" width="80"></el-table-column>
- <el-table-column>
- <template #default="scope">
- <el-button circle v-if="!injuryMode && patient.mdtrtId && scope.row.chargeAmount < 0"
- @click="fixNegativeFeeUploadProblem(scope.row, 2)">
- <i class="iconfont icon-tools-hardware" style="font-size: 10px;"></i>
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- <el-pagination
- @size-change="handleYpSizeChange"
- @current-change="handleCurrentYpChange"
- :current-page="page.ypPage"
- :page-sizes="[10, 30, 50, 70, 100, 300]"
- :page-size="page.ypPageSize"
- layout="total, sizes, prev, pager, next"
- :total="ypTotalSize"
- >
- </el-pagination>
- <div class="m-wrapper" v-show="showProgress">
- <div class="dj-center-box-wrapper">
- <div class="el-message-box" style="font-size: 13px">
- <div style="background: #409eff; color: white; padding: 7px 10px; font-weight: bold">
- <i class="el-icon-loading"></i>
- 上传进度
- </div>
- <div style="padding: 10px">
- <div style="margin-bottom: 10px">{{ uploadIndexText }} ...</div>
- <div style="margin-bottom: 10px" v-show="percentage === 100">上传结束,正在进行费用计算 ...</div>
- <el-progress :text-inside="true" :stroke-width="22" :percentage="percentage"
- status="success"></el-progress>
- <div style="height: 5px"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <el-dialog v-model="weiGuiTuiFeiFenXiDialog" title="违规费用分析" :fullscreen="true">
- <wei-gui-fei-yong-fen-xi :init="weiGuiTuiFeiInit" @open="weiGuiTuiFeiOpenDialog" ref="weiGui"
- :patient="weiGuiJiBenXinXi"></wei-gui-fei-yong-fen-xi>
- </el-dialog>
- <MedfeeAnalyse v-if="showFeeDetl" type="unsettled" :mdtrt-id="patient.mdtrtId" @close="showFeeDetl = false"/>
- </template>
- <script>
- import store from '@/store'
- import {computed, onActivated, onDeactivated, onMounted, reactive, ref, watch} from 'vue'
- import {fetchNotUploadedFees, getPatientInfo} from '@/api/inpatient/patient'
- import {ElMessage, ElMessageBox} from 'element-plus'
- import {nullPatient} from '@/utils/validate'
- import {
- hospitalizationPreSettlement,
- multipleUpload,
- pairNegativeFee,
- revokeUploadFees,
- uploadFeeDetail
- } from '@/api/medical-insurance/si-inpatient'
- import {revokeInpatientCost, inpatientSettlement, inpatientCostUpload} from '@/api/medical-insurance/si-injury'
- import {setCallback} from '@/utils/websocket'
- import {getGreatestRole} from '@/utils/permission'
- import {baseinfo, setBaseinfo} from '@/data/inpatient'
- import WeiGuiFeiYongFenXi from '@/components/inpatient/WeiGuiFeiYongFenXi.vue'
- import MedfeeAnalyse from '../../../components/medical-insurance/medfee-analyse/Index.vue'
- import {clone} from "@/utils/clone";
- export default {
- components: {WeiGuiFeiYongFenXi, MedfeeAnalyse},
- setup() {
- const feeTableHeight = (store.state.app.windowSize.h - 200) / 2
- const injuryMode = computed(() => {
- return store.state.ptnt.injuryMode
- })
- const isAdmin = getGreatestRole() < 10
- const patient = computed(() => {
- return baseinfo()
- })
- const xmFeeSum = ref('0.00')
- const ypFeeSum = ref('0.00')
- const xmFeeList = ref([])
- const ypFeeList = ref([])
- const xmTotalSize = ref(0)
- const ypTotalSize = ref(0)
- const ybCodeLabel = computed(() => {
- return injuryMode.value ? '社保三大目录ID' : '国家医保编码'
- })
- const page = initPage()
- const fetchProjectFees = () => {
- const param = {
- patNo: patient.value.inpatientNo,
- times: patient.value.admissTimes,
- currentPage: page.xmPage,
- pageSize: page.xmPageSize,
- zdTable: 'zd_charge_item',
- injuryMode: injuryMode.value,
- }
- fetchNotUploadedFees(param).then((res) => {
- xmFeeList.value = res.list
- xmFeeSum.value = res.sum
- xmTotalSize.value = res.totalSize
- })
- }
- const fetchMedicineFees = () => {
- const param = {
- patNo: patient.value.inpatientNo,
- times: patient.value.admissTimes,
- currentPage: page.ypPage,
- pageSize: page.ypPageSize,
- zdTable: 'yp_zd_dict',
- injuryMode: injuryMode.value,
- }
- fetchNotUploadedFees(param).then((res) => {
- ypFeeList.value = res.list
- ypFeeSum.value = res.sum
- ypTotalSize.value = res.totalSize
- })
- }
- const clearFees = () => {
- xmFeeList.value = []
- ypFeeList.value = []
- xmFeeSum.value = '0.00'
- ypFeeSum.value = '0.00'
- xmTotalSize.value = 0
- ypTotalSize.value = 0
- }
- const activated = ref(false)
- onActivated(() => {
- activated.value = true
- store.commit('app/setCurrentPageName', 'inHospFeeUpload')
- setCallback('medInsFeeUploadProgress', socketCallback)
- })
- onDeactivated(() => {
- activated.value = false
- store.commit('app/setCurrentPageName', '')
- })
- watch(
- () => patient.value.inpatientNo,
- () => {
- if (activated.value) {
- if (patient.value.inpatientNo) {
- fetchProjectFees()
- fetchMedicineFees()
- weiGuiTuiFeiFenXiDialogOpen(false)
- } else {
- clearFees()
- }
- }
- }
- )
- const errorMessages = ref([])
- const clearErrorMessages = () => {
- errorMessages.value = []
- }
- const handleXmSizeChange = (val) => {
- page.xmPageSize = val
- fetchProjectFees()
- }
- const handleCurrentXmChange = (val) => {
- page.xmPage = val
- fetchProjectFees()
- }
- const handleYpSizeChange = (val) => {
- page.ypPageSize = val
- fetchMedicineFees()
- }
- const handleCurrentYpChange = (val) => {
- page.ypPage = val
- fetchMedicineFees()
- }
- const preCalculateCost = () => {
- if (nullPatient()) return
- excutePreCal().then(() => {
- getPatientInfo(patient.value.inpatientNo).then(res => {
- setBaseinfo(res)
- })
- })
- }
- const excutePreCal = () => {
- return new Promise((resolve, reject) => {
- if (injuryMode.value) {
- inpatientSettlement(patient.value).then((res) => {
- patient.value.chargeYb = res.fundPay
- ElMessageBox.alert(res, {
- type: 'success',
- confirmButtonText: '确定',
- }).then(() => {
- resolve()
- })
- })
- } else {
- hospitalizationPreSettlement(patient.value).then((res) => {
- ElMessageBox.alert(res, {
- type: 'success',
- confirmButtonText: '确定',
- }).then(() => {
- resolve()
- })
- })
- }
- })
- }
- const patientIndex = ref(1)
- const showProgress = ref(false)
- const percentage = ref(0)
- const selections = computed(() => {
- return store.state.ptnt.selections
- })
- const uploadFees = () => {
- if (selections.value.length > 0) {
- showProgress.value = true
- doMultipleUpload()
- } else {
- if (nullPatient()) return
- showProgress.value = true
- if (injuryMode.value) {
- doSingleInjuryUpload()
- } else {
- doSingleNormalUpload()
- }
- }
- }
- const doSingleInjuryUpload = () => {
- patient.value.sid = store.getters['user/sid']
- inpatientCostUpload(patient.value).then((res) => {
- fetchProjectFees()
- fetchMedicineFees()
- showProgress.value = false
- percentage.value = 0
- patient.value.chargeYb = res.fundPay
- ElMessageBox.alert(res, '成功', {
- type: 'success',
- confirmButtonText: '确定',
- })
- getPatientInfo(patient.value.inpatientNo).then(res => {
- setBaseinfo(res)
- })
- }).catch(() => {
- showProgress.value = false
- percentage.value = 0
- fetchProjectFees()
- fetchMedicineFees()
- })
- }
- const doSingleNormalUpload = () => {
- const param = {
- inpatientNo: patient.value.inpatientNo,
- admissTimes: patient.value.admissTimes,
- ledgerSn: patient.value.ledgerSn,
- sid: store.getters['user/sid'],
- }
- uploadFeeDetail(param).then((res) => {
- fetchProjectFees()
- fetchMedicineFees()
- showProgress.value = false
- percentage.value = 0
- ElMessageBox.alert(res, '成功', {
- type: 'success',
- confirmButtonText: '确定',
- })
- store.commit('app/closeJdt')
- getPatientInfo(patient.value.inpatientNo).then(res => {
- setBaseinfo(res)
- })
- }).catch(() => {
- fetchProjectFees()
- fetchMedicineFees()
- showProgress.value = false
- percentage.value = 0
- })
- }
- const doMultipleUpload = () => {
- let list = clone(selections.value)
- list.forEach((item) => {
- item.sid = store.getters['user/sid']
- })
- multipleUpload(list).then((res) => {
- ElMessage({
- message: '处理完成。',
- type: 'success',
- duration: 2500,
- showClose: true,
- })
- showProgress.value = false
- percentage.value = 0
- }).catch(() => {
- showProgress.value = false
- percentage.value = 0
- })
- }
- const socketCallback = (data) => {
- if (typeof data === 'string') {
- data = JSON.parse(data)
- }
- switch (data.name) {
- case 'uploadFeeResponse':
- errorMessages.value.push(data)
- break
- case 'updatePatientIndex':
- patientIndex.value = data.patientIndex
- percentage.value = 0
- break
- case 'updateProgress':
- percentage.value = data.percentage
- break
- default:
- break
- }
- }
- const uploadIndexText = computed(() => {
- let total = selections.value.length
- if (total === 0) {
- total = 1
- }
- return '共 ' + total + ' 人,正在处理第 ' + patientIndex.value + ' 人'
- })
- const cancelFees = () => {
- ElMessageBox.confirm('是否确定取消此患者已上传的费用?', '提示', {
- type: 'warning',
- confirmButtonText: '确定',
- cancelButtonText: '放弃',
- })
- .then(() => {
- if (injuryMode.value) {
- revokeInpatientCost(patient.value).then(() => {
- ElMessage({
- message: '操作成功。',
- type: 'success',
- duration: 2500,
- showClose: true,
- })
- fetchProjectFees()
- fetchMedicineFees()
- })
- } else {
- revokeUploadFees(patient.value).then(() => {
- ElMessage({
- message: '操作成功。',
- type: 'success',
- duration: 2500,
- showClose: true,
- })
- fetchProjectFees()
- fetchMedicineFees()
- })
- }
- })
- .catch(() => {
- })
- }
- const showFeeDetl = ref(false)
- const feeDtle = () => {
- if (nullPatient()) {
- return
- }
- showFeeDetl.value = true
- }
- const fixNegativeFeeUploadProblem = (row, flag) => {
- pairNegativeFee(row).then((res) => {
- ElMessage({
- message: res,
- type: 'success',
- duration: 2500,
- showClose: true
- })
- flag === 1 ? fetchProjectFees() : fetchMedicineFees()
- })
- }
- ///////////////////////////////////////////// 违规退费分析 /////////////////////////////////////////////////////////////////////////
- const weiGuiTuiFeiInit = ref(0)
- const weiGuiTuiFeiFenXiDialog = ref(true)
- const weiGuiJiBenXinXi = ref({})
- const weiGui = ref()
- const weiGuiTuiFeiFenXiDialogOpen = (val) => {
- weiGuiTuiFeiInit.value += 1
- weiGuiJiBenXinXi.value.deptCode = ''
- weiGuiJiBenXinXi.value.inpatientNo = typeof patient.value.inpatientNo === 'undefined' ? '' : patient.value.inpatientNo
- weiGuiJiBenXinXi.value.openDialog = val
- }
- const weiGuiTuiFeiOpenDialog = (val) => {
- weiGuiTuiFeiFenXiDialog.value = val
- }
- onMounted(() => {
- if (patient.value.inpatientNo) {
- fetchProjectFees()
- fetchMedicineFees()
- }
- })
- return {
- isAdmin,
- patient,
- injuryMode,
- errorMessages,
- clearErrorMessages,
- page,
- handleXmSizeChange,
- handleCurrentXmChange,
- handleYpSizeChange,
- handleCurrentYpChange,
- preCalculateCost,
- percentage,
- uploadFees,
- showProgress,
- patientIndex,
- uploadIndexText,
- cancelFees,
- feeDtle,
- showFeeDetl,
- feeTableHeight,
- weiGuiTuiFeiFenXiDialog,
- weiGuiTuiFeiFenXiDialogOpen,
- fixNegativeFeeUploadProblem,
- weiGuiJiBenXinXi,
- weiGuiTuiFeiInit,
- weiGuiTuiFeiOpenDialog,
- weiGui,
- xmFeeSum,
- ypFeeSum,
- xmFeeList,
- ypFeeList,
- xmTotalSize,
- ypTotalSize,
- ybCodeLabel
- }
- },
- }
- function initPage() {
- return reactive({
- xmPage: 1,
- xmPageSize: 10,
- ypPage: 1,
- ypPageSize: 10,
- })
- }
- </script>
- <style scoped>
- .m-wrapper {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 8888;
- background-color: rgba(0, 0, 0, 0.6);
- }
- .dj-center-box-wrapper {
- position: fixed;
- inset: 0px;
- text-align: center;
- }
- .dj-center-box-wrapper::after {
- content: '';
- display: inline-block;
- height: 100%;
- width: 0px;
- vertical-align: middle;
- }
- </style>
|