web/src/views/charge/index.vue

476 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container">
<div class="left">
<chargeQueue @clickItem="clickItem" @getStatus="getStatus" ref="chargeQueueRef"></ChargeQueue>
</div>
<div class="middle">
<el-scrollbar>
<div>
<Panel title="医疗诊断">
<template #default>
<div class="diagnosis-content">
<div>诊断</div>
<div class="diagnosis">
<DiagnosisSearchInput
v-model="diagnosisKeyword"
:request-api="diagnosisSearchApi"
:show-config="diagnosisShowConfig"
@selectedCallBack="diagnosisSelect"
ref="diagnosisSearchRef"
:show-header="false"
:disabled="statusDisabled==1||formData.status==1"
>
</DiagnosisSearchInput>
</div>
<div>医生:</div>
<div class="doctor">
<el-select
v-model="formData.patientRegistration.organizationDoctorId"
@change="handleChange"
clearable
style="width: 100%"
:disabled="statusDisabled==1||formData.status==1"
>
<el-option
v-for="item in doctorList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</div>
</div>
</template>
</Panel>
</div>
<div style="margin-top: 24px">
<ServiceDetail v-model="formData.itemDetail" :status="formData.status == 0"
@totalPriceChange="getOrderTotalPrice" :statusDisabled="statusDisabled==1"></ServiceDetail>
</div>
<div style="margin-top: 24px">
<GoodsDetail v-model="formData.goodsDetail" :status="formData.status == 0"
@totalPriceChange="getOrderTotalPrice" :statusDisabled="statusDisabled==1"></GoodsDetail>
</div>
</el-scrollbar>
<div class="bottom">
<TotalPrice v-model="formData.totalPrice"
@save="charge"
:status="formData.status"
@openSettlement="charge"
@openCheckOut="openCheckoutDetail(formData.goodsDetail,formData.patientRegistration.psnNo)"
@refund="refund"
@print="printReceiptDo"
></TotalPrice>
</div>
</div>
<div class="right">
<div class="top">
<PatientCard ref="patientCardRef"></PatientCard>
</div>
<div class="bottom">
<RecordsLog ref="recordsConsumptionRef"></RecordsLog>
</div>
</div>
</div>
<CheckoutDetail ref="checkoutDetailRef" @confirm="saveAndCharge"></CheckoutDetail>
<Settlement
:disabled="disabled"
ref="settlementRef"
@orderCompleted="orderCompleted"
@orderCanceled="orderCanceled"
></Settlement>
</template>
<script setup lang="ts">
import Panel from "@/components/common/Panel.vue";
import ChargeQueue from "@/components/charge/ChargeQueue.vue";
import {nextTick, onMounted, onUnmounted, ref, watch} from "vue";
import {post} from "@/utils/request.ts";
import ServiceDetail from "@/components/common/service/ServiceDetail.vue";
import GoodsDetail from "@/components/common/goods/GoodsDetail.vue";
import DiagnosisSearchInput from "@/components/outpatient/DiagnosisSearchInput.vue";
import Settlement from "@/components/charge/Settlement.vue";
import TotalPrice from "@/components/charge/TotalPrice.vue";
import psnCertTypes from "@/assets/config/directory/psnCertTypes.json"
import {getKey} from "@/utils/discrotyUtil.ts";
import antys from "@/assets/config/directory/antys.json"
import RecordsLog from "@/components/charge/RecordsLog.vue";
import PatientCard from "@/components/charge/PatientCard.vue";
import {apiConfig} from "@/assets/config/apiConfig.ts";
import CheckoutDetail from "@/components/charge/CheckoutDetail.vue";
import {ElMessage} from "element-plus";
import {medTypeJson} from "@/assets/config/constants.ts";
import {useWsStore} from "@/stores/wsStore.ts";
import type {Request, Response} from "@/utils/ws.ts";
import {API} from "@/assets/config/API.ts";
const formData = ref<any>({
patientInfo: {},
diagnosisMedicalRecord: {},
goodsDetail: [],
itemDetail: [],
patientRegistration: {}
})
const initFormData = () => {
formData.value = {
patientInfo: {},
diagnosisMedicalRecord: {},
goodsDetail: [],
itemDetail: [],
patientRegistration: {}
}
}
const statusDisabled = ref(0)
const diagnosisKeyword = ref("")
const chargeQueueRef = ref()
const delDraft = () => {
nextTick(() => {
chargeQueueRef.value?.delDraft()
})
}
const settlementRef = ref()
const charge = () => {
if (checkTraceCode(formData.value.goodsDetail)) {
//保存订单
saveAndCharge()
} else {
//打开追溯码详情页
openCheckoutDetail(formData.value.goodsDetail, formData.value.patientRegistration.psnNo)
}
}
const checkTraceCode = (goodsList: any[]) => {
for (let i = 0; i < goodsList.length; i++) {
const item = goodsList[i];
if (!item.traceAbilityCodeList || item.shouldNumber != item.traceAbilityCodeList.length) {
ElMessage({
message: `${item.name}的追溯码采集未完成`,
type: 'warning',
})
return false;
}
}
return true;
}
const checkoutDetailRef = ref()
const openCheckoutDetail = (goodsList: any[], psnNo: string) => {
if (!goodsList || goodsList.length == 0) {
ElMessage({
message: '没有商品信息,请先选择需要售卖的商品',
type: 'info',
plain: true,
});
return
}
nextTick(() => {
checkoutDetailRef.value.init(goodsList, psnNo);
})
}
const saveAndCharge = () => {
post('charge/save', {data: {...formData.value, doctorId: doctorId.value}}).then((res: any) => {
formData.value.orderCode = res
nextTick(() => {
settlementRef.value?.init(res, formData.value.patientRegistration.psnNo)
})
})
}
const diagnosisSearchRef = ref()
const diagnosisSearchApi = API.Social.Diagnose.Search
const diagnosisShowConfig = [
{
label: "诊断名称",
prop: "name",
},
{
label: "诊断编码",
prop: "code",
}
]
const diagnosisSelect = (list: any) => {
const diagnosisNames = list.map((item: any) => item.name).join(',')
formData.value.diagnosisMedicalRecord.diagnosisDetail = JSON.stringify(list)
formData.value.diagnosisMedicalRecord.diagnosisSummary = diagnosisNames
}
const recordsConsumptionRef = ref<any>("")
const patientCardRef = ref()
const disabled = ref(false)
const clickItem = async (item: any, status: any) => {
statusDisabled.value = status
formData.value = await post('medical/record/getByDiagnosisCode', {diagnosisCode: item.code})
//添加追溯码应采字段
for (let i = 0; i < formData.value.goodsDetail.length; i++) {
let goodsItem = formData.value.goodsDetail[i]
if (goodsItem.packagingUnit == goodsItem.selectedUnit) {
goodsItem.shouldNumber = goodsItem.selectedNum;
} else {
goodsItem.shouldNumber = Math.ceil(goodsItem.selectedNum / goodsItem.minPackagingNumber);
}
goodsItem.idCode = goodsItem.idCode ? goodsItem.idCode == "" ? null : goodsItem.idCode.split(",") : null
}
disabled.value = formData.value.patientRegistration.type == 2
getOrderTotalPrice()
nextTick(() => {
let list = JSON.parse(formData.value.diagnosisMedicalRecord.diagnosisDetail)
let nList = formData.value.diagnosisMedicalRecord.diagnosisSummary.split(',')
diagnosisSearchRef.value?.init(list, nList);
recordsConsumptionRef.value?.init(formData.value.patientInfo.id);
patientCardRef.value?.init(formData.value.registrationId);
})
}
const dockerList = ref<any[]>([])
const getDockerList = () => {
let query = {
role: 1
}
post('organization/member/search', {query: query}).then((res: any) => {
dockerList.value = res
})
}
const orderCompleted = (printReceipt: any) => {
if (printReceipt) {
//打印小票
printReceiptDo()
}
nextTick(() => {
chargeQueueRef.value?.init()
})
initFormData()
}
type MedTypeKey = keyof typeof medTypeJson;
const wsStore = useWsStore()
const printReceiptDo = async () => {
let chargeOrder: any = await post("charge/getOrderByDiagnosisCode", {
diagnosisCode: formData.value.code,
})
if (!chargeOrder) {
ElMessage.error("该订单不存在")
return
}
const printConfig = {} as any;
post("common/config/getPrintConfig").then((res: any) => {
printConfig.printName = res.printName
printConfig.pageType = res.pageType
if (!printConfig.printName || !printConfig.pageType) {
ElMessage.error("打印机未设置,请先到设置-打印管理中设置")
return;
}
post("charge/getPrintInfoByCode", {code: chargeOrder.code}).then((res: any) => {
res.printerName = printConfig.printName
res.pageType = printConfig.pageType
if (res.chargeSocialPayLog) {
res.chargeSocialPayLog.medTypeStr = medTypeJson[res.chargeSocialPayLog.medType as MedTypeKey];
}
wsStore.sendMessage({
type: "PrintReceipt",
config: null,
data: res
})
})
})
}
let request: Request = {
type: "getPrintList",
config: null,
data: null
}
wsStore.sendMessage(request);
const reciceMessage = (response: Response) => {
}
onMounted(async () => {
wsStore.setMessageCallback(reciceMessage)
})
onUnmounted(() => {
wsStore.removeAllMessageCallback()
})
const orderCanceled = () => {
nextTick(() => {
chargeQueueRef.value?.getOrderList()
})
}
onMounted(() => {
getDockerList()
list()
})
const getOrderTotalPrice = () => {
let totalPrice = 0
formData.value.itemDetail?.forEach((item: any) => {
totalPrice += item.selectedPrice * item.selectedNum
})
formData.value.goodsDetail.forEach((item: any) => {
totalPrice += item.selectedPrice * item.selectedNum
})
formData.value.preTotalPrice = Math.round(totalPrice * 100) / 100
formData.value.totalPrice = Math.round(totalPrice * 100) / 100
}
const props = {
expandTrigger: 'hover' as const,
}
const doctorId = ref<any>('')
const handleChange = (value: any) => {
doctorId.value = value[value.length - 1]
}
const cardTypeList = ref<any>(Object.entries(psnCertTypes).map(([id, name]) => ({id, name})))
const doctorList = ref<any>([])
const sectionDoctorOption = ref<any>('')
const list = () => {
post(API.Charge.Order.List, {query: {role: 1}}).then((res: any) => {
doctorList.value = res
})
}
const getStatus = (status: any) => {
statusDisabled.value = status
initFormData()
nextTick(() => {
patientCardRef.value?.clear()
recordsConsumptionRef.value?.clearList();
})
}
//退费
const refund = async () => {
if (!formData.value.code) {
ElMessage.error("请先选择要退费的订单")
return
}
let chargeOrder: any = await post("charge/getOrderByDiagnosisCode", {
diagnosisCode: formData.value.code,
})
if (!chargeOrder) {
ElMessage.error("该订单不存在")
return
}
await post("charge/refund", {changeOrderCode: chargeOrder.code})
ElMessage.success("退费成功")
initFormData()
nextTick(() => {
chargeQueueRef.value?.init()
})
}
watch(
[() => formData.value.goodsDetail, () => formData.value.itemDetail],
([newGoodsDetail, newItemDetail]) => {
if (newGoodsDetail || newItemDetail) {
getOrderTotalPrice()
}
},
{deep: true}
)
</script>
<style scoped lang="scss">
.container {
padding: 0 24px;
height: 100%;
width: 100%;
display: flex;
.left {
width: 320px;
margin-right: 24px;
}
.middle {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.diagnosis-content {
height: 64px;
padding: 0 24px 24px;
display: flex;
align-items: center;
.diagnosis {
flex: 1;
margin-right: 24px;
}
.doctor {
width: 200px;
}
}
.case {
background: #FFFFFF;
border-radius: 8px;
padding-bottom: 24px;
}
.service-items {
margin-top: 24px;
background: #FFFFFF;
border-radius: 8px;
}
.pharmaceutical-consumables {
margin-top: 24px;
background: #FFFFFF;
border-radius: 8px;
}
.bottom {
margin-top: 24px;
height: 86px;
border-radius: 8px;
}
.el-form-item {
margin-right: 0;
}
}
.right {
width: 400px;
margin-left: 24px;
display: flex;
flex-direction: column;
.top {
height: 240px;
}
.bottom {
flex: 1;
width: 100%;
background: #fff;
margin-top: 24px;
border-radius: 8px;
min-height: 0;
}
}
}
.bottom {
margin-top: 24px;
height: 86px;
background: #FFFFFF;
border-radius: 8px;
}
</style>