Files
his/openhis-ui-vue3/src/views/charge/clinicrefund/components/refundDialog.vue

509 lines
12 KiB
Vue
Executable File
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>
<el-dialog
v-model="props.open"
title="确认退费"
width="700px"
append-to-body
destroy-on-close
@close="close"
>
<div>
<el-text
size="large"
style="display: block; margin-bottom: 15px"
>
退费日期{{ currentDate }}
</el-text>
<el-text size="large">
费用性质{{ getFeeTypeText }}
</el-text>
<div class="amount-row">
<el-text size="large">
应退金额
</el-text>
<el-text
size="large"
type="primary"
class="amount"
>
{{ props.totalAmount.toFixed(2) + ' 元' }}
</el-text>
</div>
<!-- 自费支付 -->
<div class="payment-container">
<div
v-for="(item, index) in formData.selfPay"
:key="index"
class="payment-item"
>
<span>退费方式</span>
<el-select
v-model="item.payEnum"
placeholder="选择退费方式"
style="width: 160px"
@change="clearAmount(index)"
>
<el-option
v-for="payEnum in selfPayMethods"
:key="payEnum.value"
:label="payEnum.label"
:value="payEnum.value"
:disabled="isMethodDisabled(payEnum.value)"
/>
</el-select>
<span>退费金额</span>
<div class="suffix-wrapper">
<el-input-number
v-model="item.amount"
:precision="2"
:min="0"
:max="getMax(index)"
:controls="false"
placeholder="金额"
class="amount-input"
@change="handleAmountChange"
/>
<span class="suffix-text"></span>
</div>
<el-button
v-if="index > 0"
type="danger"
circle
:icon="Delete"
@click="removePayment(index)"
/>
</div>
<div
class="payment-container"
style="position: relative"
>
<span style="position: absolute; top: 5px">退费原因</span>
<el-input
v-model="reason"
type="textarea"
:rows="2"
placeholder="退费原因"
class="reason-textarea"
@change="handleAmountChange"
/>
</div>
<div class="add-payment">
<el-button
type="primary"
plain
:disabled="formData.selfPay.length >= 4 || remainingAmount <= 0"
@click="addPayment"
>
添加退费方式
</el-button>
<el-text
v-if="remainingAmount <= 0"
type="danger"
class="tip"
>
金额已满足应退不可继续添加
</el-text>
</div>
</div>
<div>
<vxe-table
:data="props.details"
max-height="200"
border
>
<vxe-column
field="payEnum_dictText"
title="支付类型"
align="center"
/>
<vxe-column
field="amount"
title="金额"
header-align="center"
align="right"
width="200"
>
<template #default="scope">
{{ scope.row.amount ? scope.row.amount + ' 元' : '-' }}
</template>
</vxe-column>
</vxe-table>
</div>
<!-- 金额汇总 -->
<div class="summary">
<el-space :size="30">
<div class="summary-item">
<el-text type="info">
实退合计
</el-text>
<el-text type="success">
{{ displayAmount + ' 元' }}
</el-text>
</div>
<!-- <div class="summary-item">
<el-text type="info">应找零</el-text>
<el-text type="warning">{{ returnedAmount + ' 元' }}</el-text>
</div> -->
</el-space>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button
type="primary"
@click="submit"
>
</el-button>
<el-button @click="close">
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import {getReturnMedicineList, refund, renturnDispenseMedical} from './api';
import {computed, getCurrentInstance, reactive, ref, watch} from 'vue';
import {Delete} from '@element-plus/icons-vue';
import useUserStore from '@/store/modules/user';
const props = defineProps({
open: {
type: Boolean,
default: false,
},
totalAmount: {
type: Number,
default: 0.0,
},
category: {
type: String,
},
paymentId: {
type: String,
},
patientInfo: {
type: Object,
default: undefined,
},
chargeItemIds: {
type: [],
default: [],
},
medicineReturnList: {
type: [],
default: [],
},
details: {
type: Object,
default: undefined,
},
medfee_paymtd_code: {
type: Array,
default: () => [],
},
feeType: {
type: String,
default: '',
},
});
const { proxy } = getCurrentInstance();
const reason = ref('');
const userStore = useUserStore();
const formData = reactive({
totalAmount: 0,
selfPay: [{ payEnum: 220100, amount: 0.0, payLevelEnum: 2 }],
medicalInsurance: {
account: '',
poolPay: 0,
personalPay: 0,
},
});
watch(
() => props.totalAmount,
(newValue) => {
formData.totalAmount = newValue;
formData.selfPay[0].amount = newValue;
}
);
const emit = defineEmits(['close']);
function submit() {
console.log(props.chargeItemIds);
console.log(
displayAmount.value,
parseFloat(displayAmount.value),
formData.totalAmount,
formData,
'feeRefund'
);
//比较时,将金额都转换为两位小数的字符串再转换为浮点数,避免浮点数精度问题
if (parseFloat(displayAmount.value) < parseFloat(formData.totalAmount.toFixed(2))) {
proxy.$modal.msgError('请输入正确的金额');
return;
}
if (userStore.fixmedinsCode == '1123123') {
getReturnMedicineList({ encounterId: props.patientInfo.encounterId, refundStatus: 11 }).then(
(res) => {
let returnMedicineList = [];
returnMedicineList = res.data
.filter((item) => {
return item.serviceTable == 'wor_device_request';
})
.map((item) => {
return {
requestId: item.requestId,
dispenseId: item.dispenseId,
tableName: 'wor_device_request',
};
});
renturnDispenseMedical(returnMedicineList).then((res) => {
if (res.code == 200) {
refund({
paymentEnum: 0,
kindEnum: 1,
patientId: props.patientInfo.patientId,
id: props.paymentId,
encounterId: props.patientInfo.encounterId,
chargeItemIds: props.chargeItemIds,
paymentDetails: formData.selfPay,
reason: reason.value,
ybFlag: '0',
eleFlag: '0',
// returnedAmount: parseFloat(returnedAmount.value),
}).then((res) => {
if (res.code == 200) {
emit('close', 'success');
}
});
}
});
}
);
} else {
refund({
paymentEnum: 0,
kindEnum: 1,
patientId: props.patientInfo.patientId,
id: props.paymentId,
encounterId: props.patientInfo.encounterId,
chargeItemIds: props.chargeItemIds,
paymentDetails: formData.selfPay,
reason: reason.value,
ybFlag: '0',
eleFlag: '0',
// returnedAmount: parseFloat(returnedAmount.value),
}).then((res) => {
if (res.code == 200) {
// 长春市朝阳区中医院自动退耗材
emit('close', 'success');
}
});
}
}
const currentDate = ref(new Date().toLocaleString());
const selfPayMethods = [
{ label: '现金', value: 220400 },
{ label: '微信', value: 220100 },
{ label: '支付宝', value: 220200 },
{ label: '银联', value: 220300 },
];
// 计算剩余可输入金额
const remainingAmount = computed(() => {
return (
formData.totalAmount - formData.selfPay.reduce((sum, item) => sum + Number(item.amount), 0)
);
});
// 获取单个支付方式的最大可输入金额
const getMax = (index) => {
const otherSum = formData.selfPay.reduce(
(sum, item, i) => (i !== index ? sum + Number(item.amount) : sum),
0
);
if (formData.selfPay[index].payEnum == 220400) {
return formData.totalAmount + 100 - otherSum;
}
return formData.totalAmount - otherSum;
};
// 检查支付方式是否已使用
const isMethodDisabled = (payEnum) => {
return formData.selfPay.some((item) => item.payEnum === payEnum);
};
const handleAmountChange = () => {
// 不需要在这里直接设置 returnedAmount依赖 computed 属性
};
const addPayment = () => {
if (remainingAmount.value <= 0) {
return;
}
formData.selfPay.push({ payEnum: '', amount: remainingAmount.value });
};
const removePayment = (index) => {
formData.selfPay.splice(index, 1);
};
const clearAmount = (index) => {
// formData.selfPay[index].amount = 0;
};
// 计算属性
const displayAmount = computed(() => {
return formData.selfPay.reduce((sum, item) => sum + (Number(item.amount) || 0), 0).toFixed(2);
});
const returnedAmount = computed(() => {
const display = parseFloat(displayAmount.value);
if (isNaN(display) || display <= 0) {
return '0.00';
}
const returned = display - formData.totalAmount;
return returned >= 0 ? returned.toFixed(2) : '0.00';
});
function close() {
emit('close');
}
// 获取费用性质文本
const getFeeTypeText = computed(() => {
if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) {
return '自费';
}
// 如果有feeType根据feeType查找对应的文本
if (props.feeType) {
const dict = props.medfee_paymtd_code.find(item => item.value === props.feeType);
return dict ? dict.label : '自费';
}
// 如果只有一个选项,直接返回第一个选项的文本
if (props.medfee_paymtd_code.length === 1) {
return props.medfee_paymtd_code[0].label || '自费';
}
return '自费';
});
</script>
<style lang="scss" scoped>
:deep(.pagination-container .el-pagination) {
right: 20px !important;
}
.charge-container {
max-width: 600px;
margin: 20px auto;
padding: 20px 30px;
}
.header {
margin-bottom: 10px;
}
.amount-row {
display: flex;
align-items: center;
gap: 15px;
margin: 15px 0;
}
.amount {
font-size: 20px;
font-weight: bold;
}
.payment-type {
margin: 15px 0;
}
.payment-container {
margin: 15px 0;
}
.payment-item {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 12px;
}
.amount-input {
width: 140px;
}
.reason-textarea {
margin-left: 80px;
width: 59%;
}
.add-payment {
margin-top: 10px;
display: flex;
align-items: center;
gap: 10px;
}
.tip {
font-size: 12px;
}
.summary {
margin: 25px 0;
padding: 15px;
background-color: #f8f9fa;
border-radius: 4px;
}
.summary-item {
display: flex;
align-items: center;
gap: 10px;
}
.action-buttons {
text-align: center;
margin-top: 25px;
}
.el-text.el-text--success {
font-size: 18px !important;
font-weight: 500;
}
.el-text.el-text--warning {
font-size: 18px !important;
font-weight: 500;
}
.suffix-wrapper {
position: relative;
display: inline-block;
}
.suffix-text {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: #999;
pointer-events: none; /* 避免点击干扰 */
}
/* 调整输入框内边距 */
.amount-input .el-input__inner {
padding-right: 30px !important;
}
</style>