Files
his/openhis-ui-vue3/src/views/inpatientNurse/InpatientBilling/components/FeeDialog.vue
2025-12-27 15:30:25 +08:00

1088 lines
34 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>
<<<<<<< HEAD
<el-dialog v-model="dialogVisible" title="补费" width="90%" :close-on-click-modal="false">
<!-- 弹窗内容 - 左右布局 -->
<div style="display: flex; gap: 20px; height: 70vh">
<!-- 左侧收费组套列表 - 卡片式布局 -->
=======
<el-dialog v-model="dialogVisible" title="补费" width="80%" :close-on-click-modal="false">
<div style="font-size: 16px; font-weight: bold; margin-bottom: 10px">
患者信息{{
props.patientInfo.patientName +
' ' +
props.patientInfo.genderEnum_enumText +
' ' +
props.patientInfo.age
}}
| 住院号{{ props.patientInfo.busNo }} | 科室{{ props.patientInfo.organizationName }} |
病区{{ props.patientInfo.wardName }} | 病房{{ props.patientInfo.houseName }} | 床号{{
props.patientInfo.bedName
}}
</div>
<div style="margin-bottom: 15px; display: flex; align-items: center; gap: 15px">
<el-select
v-model="adviceType"
placeholder="医嘱类型"
style="width: 200px"
@change="getAdviceBaseInfos"
>
<el-option
v-for="item in adviceTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<div>
<el-input
style="width: 400px"
v-model="searchText"
placeholder="输入项目名称"
@keydown.enter="getAdviceBaseInfos"
clearable
>
<template #append>
<el-button icon="Search" @click="getAdviceBaseInfos"></el-button>
</template>
</el-input>
</div>
<el-button type="primary">划价组套</el-button>
</div>
<!-- 弹窗内容 - 左右布局 -->
<div style="display: flex; gap: 20px; height: 70vh">
>>>>>>> v1.3
<div
style="
width: 250px;
border: 1px solid #e4e7ed;
border-radius: 4px;
display: flex;
flex-direction: column;
"
>
<<<<<<< HEAD
<!-- 搜索框 -->
<div style="padding: 10px; border-bottom: 1px solid #e4e7ed">
<el-input v-model="groupSearchText" placeholder="输入组套名称" clearable />
</div>
<!-- 收费组套列表 - 卡片式布局 -->
<div style="flex: 1; overflow-y: auto; padding: 10px">
<div
v-for="group in chargeGroups"
:key="group.id"
class="group-card"
@click="selectChargeGroup(group)"
>
<div class="group-status">
<span class="status-dot"></span>
{{ getGroupType(group.name) }}
</div>
<div class="group-name">{{ group.name }}</div>
<div class="group-info">
{{ getGroupInfo(group.id) }}
=======
<!-- 诊疗耗材 -->
<div
style="flex: 1; overflow-y: auto; padding: 10px; min-height: 200px"
v-loading="adviceLoading"
element-loading-text="正在努力加载..."
element-loading-background="rgba(255, 255, 255, 0.8)"
>
<div
v-for="item in AdviceBaseInfoList"
:key="item.id"
class="item-card"
@click="selectChange(item)"
>
<div class="item-status">
<span class="status-dot"></span>
{{ getItemType_Text(item.adviceType) }}
</div>
<div class="item-name">{{ item.adviceName }}</div>
<div class="item-name">
{{
item.priceList && item.priceList.length > 0
? (item.priceList[0].price / item.partPercent).toFixed(2) +
'元' +
'/' +
item.minUnitCode_dictText
: ''
}}
</div>
<div class="item-name" v-if="item.adviceType === 2">
库存数量
{{ handleQuantity(item) }}
>>>>>>> v1.3
</div>
</div>
<!-- 只显示暂无数据文本 -->
<div
<<<<<<< HEAD
v-if="chargeGroups.length === 0"
=======
v-if="AdviceBaseInfoList.length === 0"
>>>>>>> v1.3
style="text-align: center; color: #909399; padding: 20px"
>
暂无数据
</div>
</div>
</div>
<!-- 右侧费用项目和信息 -->
<div style="flex: 1; display: flex; flex-direction: column">
<!-- 费用项目表格 -->
<el-table :data="feeItemsList" border style="width: 100%; flex: 1">
<el-table-column label="收费项目" prop="itemName" min-width="200">
<<<<<<< HEAD
<template #default="scope">
<el-input
v-model="scope.row.itemName"
placeholder="请输入收费项目"
style="width: 100%"
/>
</template>
</el-table-column>
<el-table-column label="单价" prop="unitPrice" width="100" align="center">
=======
<!-- <template #default="scope">
<el-input
v-model="scope.row.adviceName"
placeholder="请输入收费项目"
style="width: 100%"
/>
</template> -->
<template #default="scope">
{{ scope.row.adviceName }}
{{
scope.row.volume === '-' || !scope.row.volume ? '' : '[' + scope.row.volume + ']'
}}
</template>
</el-table-column>
<!-- 单价 - 简化版 -->
<el-table-column label="单价" width="200" align="center">
>>>>>>> v1.3
<template #default="scope">
<el-input-number
v-model="scope.row.unitPrice"
:min="0"
:step="0.01"
<<<<<<< HEAD
precision="2"
style="width: 100px"
@change="calculateTotalAmount"
/>
</template>
</el-table-column>
<el-table-column label="计费数量" prop="quantity" width="100" align="center">
=======
precision="6"
style="width: 150px"
/>
</template>
</el-table-column>
<el-table-column label="计费数量" prop="quantity" width="150" align="center">
>>>>>>> v1.3
<template #default="scope">
<el-input-number
v-model="scope.row.quantity"
:min="1"
:step="1"
style="width: 100px"
<<<<<<< HEAD
@change="calculateTotalAmount"
/>
</template>
</el-table-column>
<el-table-column label="金额" prop="amount" width="100" align="center" />
<el-table-column label="医保类型" prop="insuranceType" width="100" align="center">
<template #default="scope">
<el-input
v-model="scope.row.insuranceType"
placeholder="医保类型"
style="width: 100px"
/>
</template>
</el-table-column>
<el-table-column label="特限符合" prop="special" width="100" align="center">
<template #default="scope">
<el-switch v-model="scope.row.special" />
=======
/>
</template>
</el-table-column>
<!-- <el-table-column label="最小单位" prop="minUnitCode_dictText" width="100" align="center">
<template #default="scope">
{{ scope.row.minUnitCode_dictText }}
</template>
</el-table-column> -->
<el-table-column label="单位" width="140" align="center">
<template #default="scope">
<el-select
v-model="scope.row.selectUnitCode"
placeholder="单位"
style="width: 100px"
@change="unitCodeChange(scope.row)"
>
<el-option
v-for="unit in scope.row.uniqueUnitCodes"
:key="unit.code"
:label="unit.codeText"
:value="unit.code"
/>
</el-select>
</template>
</el-table-column>
<!-- 优化后的金额列 -->
<el-table-column label="金额" width="100" align="center">
<template #default="scope">
{{ (scope.row.unitPrice * scope.row.quantity).toFixed(6) }}
</template>
</el-table-column>
<el-table-column label="执行科室/位置" prop="dept" width="250" align="center">
<template #default="scope">
<el-select
v-if="scope.row.adviceType == 3"
clearable
filterable
v-model="scope.row.positionId"
placeholder="选择科室"
style="width: 220px"
>
<el-option
v-for="dept in departmentOptions"
:key="dept.id"
:label="dept.name"
:value="dept.id"
/>
</el-select>
<el-select
v-if="scope.row.adviceType == 2"
clearable
filterable
v-model="scope.row.positionId"
placeholder="选择药房/耗材房"
style="width: 220px"
>
<el-option
v-for="dept in locationOptions"
:key="dept.value"
:label="dept.label"
:value="dept.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="医保等级" prop="chrgitmLv_dictText" width="150" align="center">
<template #default="scope">
{{ scope.row.chrgitmLv_dictText }}
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template #default="scope">
<el-button type="text" size="small" @click="feeItemsList.splice(scope.$index, 1)">
删除
</el-button>
>>>>>>> v1.3
</template>
</el-table-column>
</el-table>
<<<<<<< HEAD
<!-- 添加项目按钮 - 移到右侧费用项目表格下方 -->
<div
style="
margin-top: 10px;
padding: 15px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
text-align: center;
cursor: pointer;
color: #409eff;
transition: all 0.3s;
"
@click="addEmptyItem"
>
+ 添加项目
</div>
=======
>>>>>>> v1.3
<!-- 底部信息区域 -->
<div style="margin-top: 20px; display: flex; flex-wrap: wrap; gap: 15px">
<div style="display: flex; align-items: center">
<span style="margin-right: 8px">执行时间</span>
<el-date-picker
v-model="executeTime"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择日期时间"
style="width: 200px"
/>
</div>
<<<<<<< HEAD
<div style="display: flex; align-items: center">
<span style="margin-right: 8px">执行科室</span>
<el-select v-model="selectedDept" placeholder="选择科室" style="width: 150px">
<el-option
v-for="dept in departmentOptions"
:key="dept.value"
:label="dept.label"
:value="dept.value"
/>
</el-select>
</div>
<div style="display: flex; align-items: center">
<span style="margin-right: 8px">开方医生</span>
<el-select v-model="selectedDoctor" placeholder="选择医生" style="width: 150px">
<el-option label="内科医生" value="doctor1" />
<el-option label="外科医生" value="doctor2" />
<el-option label="儿科医生" value="doctor3" />
</el-select>
</div>
<div style="display: flex; align-items: center">
<span style="margin-right: 8px">执行人</span>
<el-select v-model="executor" placeholder="选择执行人" style="width: 150px">
<el-option label="系统管理员" value="admin" />
<el-option label="护士甲" value="nurse1" />
<el-option label="护士乙" value="nurse2" />
</el-select>
</div>
</div>
=======
</div>
>>>>>>> v1.3
<!-- 总金额和操作按钮 -->
<div
style="
margin-top: 20px;
display: flex;
justify-content: space-between;
align-items: center;
"
>
<div style="font-size: 14px; font-weight: bold; text-align: right">
<<<<<<< HEAD
本次补费总金额<span style="color: #ff4d4f">{{ totalAmount.toFixed(2) }}</span>
=======
本次补费总金额<span style="color: #ff4d4f">{{ totalAmount.toFixed(6) }}</span>
>>>>>>> v1.3
</div>
<div>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</div>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
<<<<<<< HEAD
import { ref, computed, onMounted, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { formatDateStr } from '@/utils/index';
=======
import { ref, computed, onMounted, watch, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { formatDateStr } from '@/utils/index';
import { getAdviceBaseInfo, getOrgList, getDiseaseTreatmentInitLoc } from './api.js';
import useUserStore from '@/store/modules/user';
import { get } from 'lodash';
import { lo } from 'element-plus/es/locales.mjs';
>>>>>>> v1.3
// Props定义
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
initialData: {
type: Array,
default: () => [],
},
patientInfo: {
<<<<<<< HEAD
type: String,
default: '',
=======
type: Object, // 通常这类信息是对象,这里假设你已经修正了类型
default: () => ({}),
>>>>>>> v1.3
},
});
// Emits定义
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
// 响应式数据
const dialogVisible = computed({
get: () => props.visible,
set: (value) => emit('update:visible', value),
});
<<<<<<< HEAD
const searchItemText = ref('');
const selectedItemName = ref('');
const feeTabs = ref('chargeItems');
const feeItemsList = ref([]);
const executeTime = ref('');
const selectedDept = ref('');
const selectedDoctor = ref('');
const executor = ref('');
const departmentOptions = ref([]);
// 收费组套相关数据
const chargeGroups = ref([]);
const groupSearchText = ref('');
// 计算总金额
const totalAmount = computed(() => {
return feeItemsList.value.reduce((sum, item) => {
return sum + (item.unitPrice || 0) * (item.quantity || 0);
=======
const adviceTypeList = ref([
{ label: '耗材', value: 2 },
{ label: '诊疗', value: 3 },
{ label: '全部', value: '' },
]);
const adviceType = ref('');
const feeItemsList = ref([]);
const executeTime = ref('');
const departmentOptions = ref([]);
const AdviceBaseInfoList = ref([]);
const locationOptions = ref([]);
const searchText = ref('');
const userId = ref('');
const orgId = ref('');
const queryParams = ref({
pageSize: 100,
pageNum: 1,
adviceTypes: '2,3',
});
/**
* 医嘱提交数据模型
* @type {object}
* @property {number} organizationId - 提交机构ID
* @property {string} startTime - 开始时间 (ISO格式字符串如 '2023-10-27T10:00:00')
* @property {string} authoredTime - 开立时间
* @property {Array<RegAdviceItem>} regAdviceSaveList - 医嘱项目列表
*/
const submitData = reactive({
organizationId: 0,
startTime: '',
authoredTime: '',
regAdviceSaveList: [
{
dbOpType: '1', // '1':新增, '2': 修改, '3': 删除 (签发操作时传1)
adviceType: 0, // 1:药品 , 2: 耗材 , 3:项目
requestId: 0, // 请求ID
chargeItemId: 0, // 费用项id
contentJson: '',
categoryCode: '', // 医嘱详细分类代码,来自数据字典
positionId: 0, // 物理位置id | 可能是 发药药房id,耗材房id,执行科室id
pharmacologyCategoryCode: '', // 药理分类代码
partPercent: 0.0, // 拆零比
partAttributeEnum: 0, // 拆分属性-门诊
executeNum: 0, // 执行次数
prescriptionNo: '', // 处方号
quantity: 0.0, // 数量
dispensePerDuration: 0, // 每次发药供应天数
unitCode: '', // 包装单位
unitPrice: 0.0, // 单价
totalPrice: 0.0, // 总价
definitionId: 0, // 费用定价主表ID
definitionDetailId: 0, // 费用定价子表ID
lotNumber: '', // 默认产品批号
statusEnum: 0, // 请求状态
categoryEnum: 0, // 请求类型枚举 (与categoryCode的区别这是程序内部使用的数字枚举用于逻辑判断)
adviceDefinitionId: 0, // 医嘱定义ID
adviceTableName: '', // 医嘱定义对应表名
adviceName: '', // 医嘱名称
minUnitQuantity: 0.0, // 请求小单位数量
patientId: 0, // 患者ID
practitionerId: 0, // 开方医生ID
locationId: 0, // 请求发起的位置ID
performLocation: 0, // 发放/执行位置ID
founderOrgId: 0, // 开方人科室ID
encounterId: 0, // 就诊ID
accountId: 0, // 账户ID
conditionId: 0, // 诊断ID
encounterDiagnosisId: 0, // 就诊诊断ID
conditionDefinitionId: 0, // 诊断定义ID | 分方使用
therapyEnum: 0, // 治疗类型
methodCode: '', // 用法代码
rateCode: '', // 使用频次代码
dose: 0.0, // 单次剂量
firstDose: 0.0, // 首次用量
doseUnitCode: '', // 剂量单位代码
skinTestFlag: 0, // 是否皮试标识
injectFlag: 0, // 是否为注射药物
groupId: 0, // 分组id, 一组药品共用一个id
packageId: 0, // 组套id
activityId: 0, // 活动(项目)定义id
ybClassEnum: 0, // 类别医保编码
chineseHerbsDoseQuantity: 0.0, // 中药付数
sufferingFlag: 0, // 代煎标识 | 0:否 , 1:是
dosageInstruction: '', // 用药说明
sortNumber: 0, // 排序号
basedOnId: 0, // 请求基于什么的ID
},
],
});
const adviceLoading = ref(false);
// 【优化核心】计算总金额 - 使用计算属性实现实时更新
const totalAmount = computed(() => {
return feeItemsList.value.reduce((sum, item) => {
const price = Number(item.unitPrice) || 0;
const quantity = Number(item.quantity) || 0;
return sum + price * quantity;
>>>>>>> v1.3
}, 0);
});
// 初始化
onMounted(() => {
<<<<<<< HEAD
// 加载科室选项
loadDepartmentOptions();
// 加载收费组套数据
loadChargeGroups();
});
// 监听初始数据变化
watch(
() => props.initialData,
(newData) => {
if (newData && newData.length > 0) {
initFeeDialogData(newData);
}
},
{ deep: true }
);
=======
const userStore = useUserStore();
userId.value = userStore.id;
orgId.value = userStore.orgId;
console.log(props.patientInfo, 'patientInfo in FeeDialog');
console.log('initialData in FeeDialog');
loadDepartmentOptions();
getAdviceBaseInfos();
getDiseaseInitLoc();
});
>>>>>>> v1.3
// 监听弹窗显示状态
watch(
() => props.visible,
(visible) => {
if (visible) {
<<<<<<< HEAD
// 设置默认执行时间为当前时间
executeTime.value = formatDateStr(new Date(), 'YYYY-MM-DD HH:mm:ss');
} else {
// 弹窗关闭时重置数据
=======
executeTime.value = formatDateStr(new Date(), 'YYYY-MM-DD HH:mm:ss');
} else {
>>>>>>> v1.3
resetData();
}
}
);
// 加载科室选项
function loadDepartmentOptions() {
<<<<<<< HEAD
// 模拟科室数据
departmentOptions.value = [
{ label: '内科', value: 'internal' },
{ label: '外科', value: 'surgery' },
{ label: '儿科', value: 'pediatrics' },
{ label: '妇产科', value: 'obstetrics' },
{ label: '其他科室', value: 'others' },
];
}
// 加载收费组套数据
function loadChargeGroups() {
// 模拟收费组套数据
chargeGroups.value = [
{ id: '1', name: '血常规检查组套' },
{ id: '2', name: '生化检查组套' },
{ id: '3', name: '心电图检查组套' },
{ id: '4', name: 'CT检查组套' },
{ id: '5', name: '输液治疗组套' },
];
}
// 获取组套类型
function getGroupType(name) {
if (name.includes('检查')) return '检查';
if (name.includes('治疗')) return '治疗';
return '常规';
}
// 获取组套信息
function getGroupInfo(id) {
const infoMap = {
1: '检验科/基础检查',
2: '检验科/生化项目',
3: '心电图室/常规检查',
4: '影像科/影像学检查',
5: '内科/治疗项目',
};
return infoMap[id] || '标准收费项目';
}
// 初始化费用数据
function initFeeDialogData(selectedRows) {
// 将选中的项目转换为弹窗中的费用项目格式
feeItemsList.value = selectedRows.map((row) => ({
itemName: row.chargeItem,
unitPrice: row.unitPrice,
quantity: row.quantity,
amount: row.unitPrice * row.quantity,
dept: '内科',
special: false,
insuranceType: '',
}));
}
// 选择收费组套
function selectChargeGroup(group) {
// 模拟根据选中的组套添加对应的费用项目
const groupItems = {
1: [
{
itemName: '红细胞计数',
unitPrice: 15.0,
quantity: 1,
dept: '检验科',
special: false,
insuranceType: '甲类',
},
],
2: [
{
itemName: '肝功能检查',
unitPrice: 80.0,
quantity: 1,
dept: '检验科',
special: false,
insuranceType: '甲类',
},
],
3: [
{
itemName: '心电图检查',
unitPrice: 45.0,
quantity: 1,
dept: '心电图室',
special: false,
insuranceType: '甲类',
},
],
4: [
{
itemName: 'CT扫描',
unitPrice: 300.0,
quantity: 1,
dept: '影像科',
special: false,
insuranceType: '乙类',
},
],
5: [
{
itemName: '静脉输液',
unitPrice: 20.0,
quantity: 1,
dept: '内科',
special: false,
insuranceType: '甲类',
},
],
};
const items = groupItems[group.id] || [];
// 计算金额
items.forEach((item) => {
item.amount = item.unitPrice * item.quantity;
});
// 添加到费用项目列表
feeItemsList.value = [...feeItemsList.value, ...items];
}
// 添加空白项目
function addEmptyItem() {
const newItem = {
itemName: '', // 空白项目名称
unitPrice: 0, // 默认单价为0
quantity: 1, // 默认数量为1
amount: 0, // 默认金额为0
dept: '内科', // 默认科室
special: false, // 默认特限不符合
insuranceType: '', // 空白医保类型
};
// 添加到费用项目列表
feeItemsList.value.push(newItem);
// 显示提示信息
ElMessage.success('已添加空白项目,请填写相关信息');
}
// 计算总金额(当数量变化时调用)
function calculateTotalAmount() {
// 更新每个项目的金额
feeItemsList.value.forEach((item) => {
item.amount = (item.unitPrice || 0) * (item.quantity || 0);
=======
getOrgList().then((res) => {
if (res.data && res.data.records && res.data.records.length > 0) {
departmentOptions.value = res.data.records[0].children || [];
}
});
}
// 加载收费组套数据
function getAdviceBaseInfos() {
adviceLoading.value = true;
queryParams.value.searchKey = searchText.value;
queryParams.value.adviceType = adviceType.value;
queryParams.value.organizationId = orgId.value;
queryParams.value.pricingFlag = 1; // 划价标记
getAdviceBaseInfo(queryParams.value)
.then((res) => {
AdviceBaseInfoList.value = res.data?.records || [];
})
.finally(() => {
adviceLoading.value = false;
});
}
function getDiseaseInitLoc() {
getDiseaseTreatmentInitLoc(16).then((response) => {
console.log('Disease Treatment Init Loc:', response);
locationOptions.value = response.data.locationOptions;
});
}
// 获取组套类型文本
function getItemType_Text(type) {
const map = { 2: '耗材', 3: '诊疗' };
return map[type] || '其他';
}
function getUnitCodeOptions(row) {
const unitCodes = [
{ code: row.unitCode, codeText: row.unitCode_dictText },
{ code: row.minUnitCode, codeText: row.minUnitCode_dictText },
];
// 使用 Set 来跟踪已经存在的 code
const seenCodes = new Set();
const uniqueUnitCodes = unitCodes.filter((item) => {
// 如果 Set 中没有这个 code就保留它并把它加入 Set
if (!seenCodes.has(item.code)) {
seenCodes.add(item.code);
return true;
}
// 如果已经存在,就过滤掉
return false;
});
return uniqueUnitCodes;
}
// 单位变更处理
function unitCodeChange(row) {
// 获取价格
const price = row.priceList?.[0]?.price || 0;
// 根据选择的单位调整单价
if (row.selectUnitCode === row.unitCode) {
// 如果选择的是大单位 (如 "盒")
row.unitPrice = price.toFixed(6); // 单价就是原价
} else if (row.selectUnitCode === row.minUnitCode) {
// 如果选择的是小单位 (如 "个")
row.unitPrice = (price / (row.partPercent || 1)).toFixed(6); // 单价 = 原价 / 拆零比
}
}
function handleQuantity(row) {
if (row.inventoryList && row.inventoryList.length > 0) {
const totalQuantity = row.inventoryList.reduce((sum, item) => sum + (item.quantity || 0), 0);
return totalQuantity.toString() + row.minUnitCode_dictText;
}
return 0;
}
// 选择收费项目 - 添加到费用列表
function selectChange(row) {
console.log('Added item:', row, props.patientInfo);
if (row == null) {
return;
}
// 校验库存
if (row.adviceType === 2) {
if (!row.inventoryList || row.inventoryList.length === 0) {
ElMessage.warning(`"${row.adviceName}" 库存信息不可用,无法添加`);
return;
}
const totalQuantity = row.inventoryList.reduce((sum, item) => sum + (item.quantity || 0), 0);
if (totalQuantity <= 0) {
ElMessage.warning(`"${row.adviceName}" 库存不足,无法添加`);
return;
}
}
// 检查是否已存在
const exists = feeItemsList.value.some(
(existing) => existing.adviceDefinitionId === row.adviceDefinitionId
);
if (exists) {
ElMessage.warning(`"${row.adviceName}" 已存在于费用列表中`);
return;
}
//获取价格
const price = row.priceList?.[0]?.price || 0;
//获取大小单位
const uniqueUnitCodes = getUnitCodeOptions(row);
//插入费用列表
feeItemsList.value.push({
...row,
uniqueUnitCodes: uniqueUnitCodes,
unitPrice: (price / (row.partPercent || 1)).toFixed(6), // 根据拆零比计算单价
quantity: 1,
// positionId: row.positionId === null || row.positionId === undefined ? orgId : row.positionId, // 默认执行科室
selectUnitCode: row.minUnitCode, // 默认选择小单位
>>>>>>> v1.3
});
}
// 取消操作
function handleCancel() {
emit('cancel');
dialogVisible.value = false;
}
// 确认操作
function handleConfirm() {
<<<<<<< HEAD
// 构建提交数据
const submitData = {
feeItems: feeItemsList.value,
executeTime: executeTime.value,
department: selectedDept.value,
doctor: selectedDoctor.value,
executor: executor.value,
totalAmount: totalAmount.value,
};
// 发送确认事件
emit('confirm', submitData);
dialogVisible.value = false;
}
// 重置数据
function resetData() {
feeItemsList.value = [];
executeTime.value = '';
selectedDept.value = '';
selectedDoctor.value = '';
executor.value = '';
=======
if (feeItemsList.value.length === 0) {
ElMessage.warning('请至少添加一项费用项目');
return;
}
if (!executeTime.value) {
ElMessage.warning('请选择执行时间');
return;
}
//验证数据的完整性
if (feeItemsList.value.some((item) => !item.positionId)) {
ElMessage.warning('请为所有费用项目选择执行科室/位置');
return;
}
convertDataManually();
emit('confirm', submitData);
dialogVisible.value = false;
}
// 手动转换数据
function convertDataManually() {
// 从 feeItemsList.value 中提取机构ID
const organizationId = props.patientInfo.organizationId;
const encounterId = props.patientInfo.encounterId;
const patientId = props.patientInfo.patientId;
const accountId = props.patientInfo.accountId;
console.log('Submitting data for patientId:', props.patientInfo);
if (!organizationId || !encounterId || !patientId || !accountId) {
ElMessage.error('患者信息不完整,无法提交费用项目');
return;
}
// 设置提交数据的机构ID和时间
submitData.organizationId = organizationId;
submitData.startTime = executeTime.value;
submitData.authoredTime = executeTime.value;
// 清空并重新填充 regAdviceSaveList
submitData.regAdviceSaveList = feeItemsList.value.map((item) => {
// ... (这里是和上面computed中完全相同的映射逻辑)
const mappedItem = {
dbOpType: '1', // 默认为新增操作
adviceType: item.adviceType, // 1:药品 , 2: 耗材 , 3:项目
requestId: null, // 新增项ID为0
chargeItemId: null, // feeItemsList中没有直接对应的chargeItemId可能需要从chargeItemDefinitionId映射或设为0
contentJson: feeItemsList.value.length > 0 ? JSON.stringify(feeItemsList.value) : '',
categoryCode: item.categoryCode, //医嘱详细分类代码,来自数据字典
positionId: item.positionId, // 物理位置id | 可能是 发药药房id,耗材房id,执行科室id
pharmacologyCategoryCode: item.pharmacologyCategoryCode || '', //药品性质 | 分方使用
partPercent: item.partPercent || 1.0, // 默认拆零比为1
partAttributeEnum: item.partAttributeEnum, //拆分属性-门诊
executeNum: 1, // 默认执行次数为1
prescriptionNo: '', // 处方号
quantity: item.quantity || 0.0, // 数量
// dispensePerDuration: 0, //每次发药供应天数
unitCode: item.unitCode || '',
unitPrice: item.unitPrice.toFixed(6) || 0.0, // 单价
totalPrice: ((item.quantity || 0) * (item.unitPrice || 0)).toFixed(6), // 计算总价
definitionId: item.chargeItemDefinitionId || 0,
definitionDetailId: 0,
lotNumber: item.defaultLotNumber || '',
// statusEnum: 1, // 假设默认为“待执行”状态
categoryEnum: item.categoryCode, // 简单映射项目类型枚举值可能与adviceType相同
adviceDefinitionId: item.adviceDefinitionId || '',
adviceTableName: item.adviceTableName || '',
adviceName: item.adviceName || '',
minUnitQuantity: item.quantity || 0.0, // 假设最小单位数量等于请求数量
patientId: patientId, // 需要从外部获取
practitionerId: userId.value, // 需要从外部获取
locationId: item.adviceType === 2 ? item.positionId : null, // 请求发起的位置ID
performLocation: item.adviceType === 2 ? item.positionId : null, // 发放位置ID
founderOrgId: organizationId, // 开方科室ID可能与机构ID相同
encounterId: encounterId, // 需要从外部获取
accountId: accountId, // 需要从外部获取
// conditionId: null, // 需要从外部获取
// encounterDiagnosisId: null, // 需要从外部获取
// conditionDefinitionId: null, // 需要从外部获取
therapyEnum: 2, // 默认治疗类型 1 长期 2 临时
methodCode: item.methodCode || '',
rateCode: item.rateCode || '',
dose: item.dose || null,
// firstDose: null, // 默认无首次用量
doseUnitCode: item.doseUnitCode || '',
skinTestFlag: item.skinTestFlag,
injectFlag: item.injectFlag, //注射药物 1:是 , 0:否
// groupId: null, // 默认不分组
// packageId: null, // 默认不是组套
activityId: item.adviceType === 3 ? item.adviceDefinitionId : null, // 如果是项目类型activityId可能等于adviceDefinitionId
// ybClassEnum: 0, // 默认医保类别
// chineseHerbsDoseQuantity: null, // 默认为0非中药
// sufferingFlag: null, // 默认不代煎
dosageInstruction: item.dosageInstruction || '', //用药说明
// sortNumber: 0, // 默认排序号
basedOnId: null, // 默认无基于ID
};
return mappedItem;
});
}
// 重置数据
function resetData() {
feeItemsList.value = [];
adviceType.value = '';
searchText.value = '';
executeTime.value = '';
>>>>>>> v1.3
}
</script>
<style scoped>
:deep(.el-dialog__body) {
padding: 20px;
}
<<<<<<< HEAD
/* 添加项目按钮样式 */
:deep(
.el-dialog div[style*='flex: 1; display: flex; flex-direction: column'] > div:nth-child(2):hover
) {
background-color: #ecf5ff;
}
/* 收费组套卡片样式 */
.group-card {
=======
.item-card {
>>>>>>> v1.3
background: #ffffff;
border: 1px solid #e4e7ed;
border-radius: 6px;
padding: 12px;
margin-bottom: 12px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
<<<<<<< HEAD
.group-card:hover {
=======
.item-card:hover {
>>>>>>> v1.3
border-color: #409eff;
background-color: #ecf5ff;
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
}
<<<<<<< HEAD
.group-status {
=======
.item-status {
>>>>>>> v1.3
display: flex;
align-items: center;
margin-bottom: 8px;
font-size: 14px;
font-weight: 500;
color: #606266;
}
<<<<<<< HEAD
=======
>>>>>>> v1.3
.status-dot {
width: 8px;
height: 8px;
background-color: #67c23a;
border-radius: 50%;
margin-right: 6px;
}
<<<<<<< HEAD
.group-name {
=======
.item-name {
>>>>>>> v1.3
font-size: 16px;
font-weight: 600;
color: #303133;
margin-bottom: 8px;
word-break: break-word;
}
<<<<<<< HEAD
.group-info {
font-size: 12px;
color: #909399;
border-top: 1px dashed #ebeef5;
padding-top: 8px;
margin-top: 4px;
}
</style>
=======
</style>
>>>>>>> v1.3