Files
his/openhis-ui-vue3/src/views/inpatientNurse/InpatientBilling/components/billingList.vue
chenqi 4f0cc1a0c4 refactor(ui): 优化按钮样式和数据加载逻辑
- 将多个按钮组件从 type="text" 改为 link 属性,提升界面美观性
- 修复 PatientList 组件中姓名显示的文本截断功能
- 在住院记录模板中添加对 patientInfo 变化的监听,自动更新表单数据
- 优化打印机列表获取逻辑,添加连接状态检查和警告信息
- 移除不必要的防抖和重复请求防护逻辑,简化代码实现
- 修复多处组件中对 patientInfo 属性访问的安全性问题
- 优化病历数据加载时机,移除防抖包装直接调用加载函数
- 改进数据设置逻辑,避免覆盖未传入字段的原有值
- 调整组件属性定义,使 patientInfo 参数变为可选并设置默认值
- 优化患者切换时的组件重置和数据加载流程
2026-01-27 17:32:03 +08:00

920 lines
27 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 style="height: calc(100vh - 126px); display: flex; flex-direction: column">
<!-- 操作工具栏 -->
<div
style="
height: 51px;
border-bottom: 2px solid #e4e7ed;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 15px;
flex-shrink: 0;
"
>
<div style="display: flex; align-items: center">
<!-- 日期选择tabs -->
<el-tabs
v-model="dateRange"
type="card"
class="date-tabs"
@tab-click="handleDateTabClick"
style="margin-right: 20px"
>
<el-tab-pane label="今日" name="today"></el-tab-pane>
<el-tab-pane label="昨日" name="yesterday"></el-tab-pane>
<el-tab-pane label="自定义" name="custom"></el-tab-pane>
</el-tabs>
<!-- 日期选择器 -->
<el-date-picker
v-model="dateRangeValue"
type="daterange"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleDatePickerChange"
:disabled="dateRange !== 'custom'"
style="width: 240px; margin-right: 20px"
/>
<!-- 查询按钮 -->
<el-button type="primary" @click="handleQuery">查询</el-button>
</div>
<div style="display: flex; align-items: center">
<!-- 新增划价 -->
<el-button type="primary" @click="handAddBilling">新增划价</el-button>
</div>
</div>
<!-- 费用列表区域 - Collapse折叠面板+按encounterId分组版 -->
<div
style="flex: 1; display: flex; flex-direction: column; overflow: hidden"
v-loading="loading"
element-loading-text="数据加载中..."
element-loading-spinner="el-icon-loading"
>
<!-- 列表统计信息 -->
<div
style="
padding: 10px 15px;
background-color: #f8f9fa;
border-bottom: 1px solid #e4e7ed;
flex-shrink: 0;
"
>
<div style="display: flex; justify-content: space-between; align-items: center">
<div>
<span class="text-primary font-bold">患者医嘱列表</span>
<span style="margin-left: 15px; color: #666">
<span class="text-danger">{{ groupedPrescriptionList.length }}</span> 位患者
</span>
</div>
<!-- <div>
<el-button size="small" link @click="exportData">
<el-icon><Download /></el-icon> 导出数据
</el-button>
</div> -->
</div>
</div>
<!-- 列表内容容器 -->
<div style="flex: 1; overflow-y: auto; padding: 10px; background-color: #f5f7fa">
<!-- 空状态 -->
<div v-if="groupedPrescriptionList.length === 0 && !loading" class="empty-container">
<el-empty description="暂无患者划价数据,请选择查询条件后点击查询" :image-size="120">
<el-button type="primary" @click="handleQuery">立即查询</el-button>
</el-empty>
</div>
<!-- 患者医嘱折叠面板 -->
<div v-else class="prescription-collapse-container">
<el-collapse
v-model="activeCollapseNames"
accordion
border
style="--el-collapse-border-color: #e4e7ed"
>
<!-- 按encounterId分组渲染患者折叠项 -->
<el-collapse-item
v-for="(patientGroup, index) in groupedPrescriptionList"
:key="`patient-${index}-${safeGet(patientGroup[0], 'encounterId', index)}`"
:name="`patient-${index}`"
class="patient-collapse-item"
>
<!-- 折叠面板头部 - 患者信息 -->
<template #title>
<div class="patient-header">
<div class="patient-basic-info">
<el-avatar :icon="User" size="small" style="margin-right: 10px"></el-avatar>
<div>
<span class="patient-name">{{
safeGet(patientGroup[0], 'patientName', '未知患者')
}}</span>
<span class="patient-info-tag"
>{{ safeGet(patientGroup[0], 'genderEnum_enumText', '未知') }} /
{{ safeGet(patientGroup[0], 'age', '未知') }}</span
>
<span class="patient-info-tag"
>{{ safeGet(patientGroup[0], 'bedName', '无床位') }}{{
safeGet(patientGroup[0], 'busNo', '未知编号')
}}</span
>
</div>
</div>
<div class="patient-ext-info">
<div class="ext-item">
<span class="label">住院医生</span>
<span class="value">{{
safeGet(patientGroup[0], 'admittingDoctorName', '未知')
}}</span>
</div>
<div class="ext-item">
<span class="label">预交金余额</span>
<span class="value amount">{{
formatNumber(safeGet(patientGroup[0], 'balanceAmount', 0), 4)
}}</span>
</div>
<div class="ext-item">
<span class="label">诊断</span>
<span class="value" :title="safeGet(patientGroup[0], 'conditionNames', '无')">
{{ truncateText(safeGet(patientGroup[0], 'conditionNames', '无'), 20) }}
</span>
</div>
<div class="ext-item">
<el-tag size="small">{{
safeGet(patientGroup[0], 'contractName', '未知')
}}</el-tag>
</div>
<div class="patient-amount-preview">
小计<span class="amount">{{ calculatePatientTotal(patientGroup) }}</span>
</div>
</div>
</div>
</template>
<!-- 折叠面板内容 - 医嘱表格 -->
<div class="prescription-table-container">
<el-table
:data="safeArray(patientGroup)"
border
size="small"
:ref="(el) => (tableRef[index] = el)"
@selection-change="(val) => handleTableSelectionChange(index, val)"
:header-cell-style="{ background: '#eef9fd', color: '#333' }"
:row-class-name="
({ row }) => (safeGet(row, 'status') === 'priced' ? 'priced-row' : '')
"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="医嘱类型" prop="therapyEnum_enumText" width="90">
<template #default="scope">
<el-tag
size="small"
:type="safeGet(scope.row, 'therapyEnum') === 1 ? 'warning' : 'primary'"
>
{{ safeGet(scope.row, 'therapyEnum_enumText', '未知') }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="划价内容" min-width="200">
<template #default="scope">
<div class="advice-content">
<span>{{ safeGet(scope.row, 'adviceName', '无') }}</span>
<template v-if="safeGet(scope.row, 'adviceTable') === 'wor_device_request'">
<span class="advice-detail">
规格:{{ safeGet(scope.row, 'volume', '无') }} / 数量:{{
safeGet(scope.row, 'quantity', 0)
}}{{ safeGet(scope.row, 'unitCode_dictText', '') }}
</span>
</template>
</div>
</template>
</el-table-column>
<el-table-column label="数量" prop="quantity" width="60">
<template #default="scope">
{{ formatNumber(safeGet(scope.row, 'quantity', 0), 0) }}
{{ safeGet(scope.row, 'unitCode_dictText', '') }}
</template>
</el-table-column>
<el-table-column label="申请时间" prop="requestTime" width="160" />
<el-table-column label="执行/发放" prop="positionName" width="120" />
<el-table-column label="单价()" width="90">
<template #default="scope">
<!-- 实际项目单价可能需要从收费项目配置中获取这里先显示0.0000 -->
{{ formatNumber(safeGet(scope.row, 'unitPrice', 0), 4) }}
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="scope">
<el-button
size="small"
type="text"
@click="handleSingleDelete(scope.row)"
:disabled="safeGet(scope.row, 'status') === 'priced'"
>
撤销
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 患者级操作栏 -->
<div class="patient-actions">
<el-button
size="small"
type="primary"
plain
@click="selectAllPatientItems(index)"
>
全选
</el-button>
<el-button size="small" type="primary" @click="handleBatchDelete(index)">
批量撤销
</el-button>
<el-button size="small" type="primary" @click="handleCalculate(patientGroup)">
新增划价
</el-button>
<span class="patient-amount">
小计:<span class="amount">{{ calculatePatientTotal(patientGroup) }}</span>
</span>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
</div>
<!-- 计费弹窗 -->
<FeeDialog
v-model:visible="dialogVisible"
:initial-data="selectedFeeItems"
:patient-info="currentPatientInfo"
@confirm="handleFeeDialogConfirm"
@cancel="handleFeeDialogCancel"
/>
</div>
</template>
<script setup>
import {computed, nextTick, onMounted, ref, watch} from 'vue';
import {ElMessage, ElMessageBox} from 'element-plus';
// Element Plus 图标导入
import {User} from '@element-plus/icons-vue';
import {patientInfoList} from '../../components/store/patient.js';
import {formatDateStr} from '@/utils/index';
import FeeDialog from './FeeDialog.vue';
import {addBilling, deleteBilling, queryBilling} from './api.js';
import useUserStore from '@/store/modules/user';
// ========== 核心工具函数 ==========
/**
* 安全获取对象属性,避免空值报错
* @param {Object} obj - 源对象
* @param {String} path - 属性路径
* @param {Any} defaultValue - 默认值
* @returns {Any}
*/
const safeGet = (obj, path, defaultValue = '') => {
// 1. 前置校验:如果源对象不是对象类型,直接返回默认值
if (!obj || typeof obj !== 'object') return defaultValue;
// 2. 拆分路径:把 "info.basic.name" 拆成 ["info", "basic", "name"]
const paths = path.split('.');
// 3. 初始化结果为源对象
let result = obj;
// 4. 循环遍历路径数组,逐层访问属性
for (const p of paths) {
// 5. 关键如果当前层属性不存在undefined/null直接返回默认值
if (result[p] === undefined || result[p] === null) return defaultValue;
// 6. 存在则继续访问下一层
result = result[p];
}
// 7. 所有层级都存在,返回最终属性值
return result;
};
/**
* 安全转换为数组
* @param {Any} data - 待转换数据
* @returns {Array}
*/
const safeArray = (data) => {
return Array.isArray(data) ? data : [];
};
/**
* 格式化数字保留4位小数金额专用
* @param {Number} num - 数字
* @param {Number} decimal - 小数位数默认4位
* @returns {String}
*/
const formatNumber = (num, decimal = 4) => {
if (isNaN(Number(num))) return '0.0000';
// 保留指定小数位不足补0
return Number(num).toFixed(decimal);
};
/**
* 文本截断(超出长度显示省略号)
* @param {String} text - 待处理文本
* @param {Number} length - 最大长度
* @returns {String}
*/
const truncateText = (text, length = 20) => {
if (!text || text.length <= length) return text;
return `${text.slice(0, length)}...`;
};
/**
* 按encounterId分组数据
* @param {Array} data - 原始数据
* @returns {Array} 分组后的数据(二维数组)
*/
const groupByEncounterId = (data) => {
const grouped = {};
safeArray(data).forEach((item) => {
const encounterId = safeGet(item, 'encounterId', 'unknown');
if (!grouped[encounterId]) {
grouped[encounterId] = [];
}
// 为每个项添加默认状态未划价和单价默认0实际应从收费项目中获取
grouped[encounterId].push({
...item,
status: safeGet(item, 'status', 'unpriced'), // 默认未划价
unitPrice: safeGet(item, 'unitPrice', 0), // 单价默认0实际需要对接收费项目
});
});
// 转换为数组格式
return Object.values(grouped);
};
// ========== 响应式数据 ==========
const loading = ref(false);
const dateRange = ref('today');
const dateRangeValue = ref([]);
const tableRef = ref([]);
const rawPrescriptionList = ref([]); // 原始未分组数据
const groupedPrescriptionList = ref([]); // 按encounterId分组后的数据
const activeCollapseNames = ref([]); // Collapse激活状态
const selectedRows = ref({}); // 选中的行数据
const totalItemsCount = ref(0); // 总医嘱项数
const totalAmount = ref(0); // 总金额保留4位小数
const dialogVisible = ref(false);
const selectedFeeItems = ref([]);
const currentPatientInfo = ref(null);
const queryParams = ref({
pageSize: 10000,
pageNo: 1,
});
// 用户信息
const userStore = useUserStore();
const userId = ref(safeGet(userStore, 'id', ''));
const orgId = ref(safeGet(userStore, 'orgId', ''));
// ========== 计算属性 ==========
// 计算总统计信息(总项数、总金额)
const calculateTotalStats = computed(() => {
let itemsCount = 0;
let amount = 0;
safeArray(groupedPrescriptionList.value).forEach((patientGroup) => {
safeArray(patientGroup).forEach((item) => {
itemsCount++;
// 累加单价保留4位小数精度
amount = Math.round((amount + Number(safeGet(item, 'unitPrice', 0))) * 10000) / 10000;
});
});
totalItemsCount.value = itemsCount;
totalAmount.value = amount;
});
// ========== 方法 ==========
/**
* 计算单个患者的总金额保留4位小数
* @param {Array} patientGroup - 患者医嘱列表
* @returns {String} 格式化后的金额字符串
*/
const calculatePatientTotal = (patientGroup) => {
const total = safeArray(patientGroup).reduce((sum, item) => {
return (
Math.round(
(sum + Number(safeGet(item, 'unitPrice', 0) * safeGet(item, 'quantity', 0))) * 10000
) / 10000
);
}, 0);
return formatNumber(total, 4);
};
/**
* 全选单个患者的所有项
* @param {Number} index - 患者索引
*/
const selectAllPatientItems = (index) => {
nextTick(() => {
const table = safeArray(tableRef.value)[index];
if (table && typeof table.toggleAllSelection === 'function') {
table.toggleAllSelection();
}
});
};
/**
* 处理表格选择变化
* @param {Number} index - 患者索引
* @param {Array} val - 选中行
*/
const handleTableSelectionChange = (index, val) => {
selectedRows.value[index] = safeArray(val);
console.log('selectedRows:', selectedRows.value);
// 合并所有选中行
const allSelected = [];
Object.values(selectedRows.value).forEach((rows) => {
allSelected.push(...safeArray(rows));
});
selectedFeeItems.value = allSelected;
console.log('selectedFeeItems:', selectedFeeItems.value);
};
/**
* 日期Tab切换
* @param {Object} tab - 标签页
*/
const handleDateTabClick = (tab) => {
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
const format = (date) => formatDateStr(date, 'YYYY-MM-DD');
switch (safeGet(tab, 'paneName')) {
case 'today':
dateRangeValue.value = [format(today), format(today)];
break;
case 'yesterday':
dateRangeValue.value = [format(yesterday), format(yesterday)];
break;
case 'custom':
if (!dateRangeValue.value.length) {
dateRangeValue.value = [format(today), format(today)];
}
break;
}
};
/**
* 日期选择器变化
* @param {Array} val - 选中日期
*/
const handleDatePickerChange = (val) => {
const dateVal = safeArray(val);
if (dateVal.length === 2) {
dateRange.value = 'custom';
const start = new Date(dateVal[0]);
const end = new Date(dateVal[1]);
if (start > end) {
ElMessage.warning('开始日期不能晚于结束日期');
dateRangeValue.value = [dateVal[1], dateVal[0]];
}
}
};
/**
* 查询数据并按encounterId分组
*/
const handleQuery = async () => {
// 基础校验
const patientList = safeArray(patientInfoList.value);
if (patientList.length === 0) {
ElMessage.warning('请先选择患者');
return;
}
if (safeArray(dateRangeValue.value).length < 2) {
ElMessage.warning('请选择有效的查询日期');
return;
}
loading.value = true;
try {
queryParams.value = {
...queryParams.value,
encounterIds: patientList
.map((p) => safeGet(p, 'encounterId'))
.filter((id) => id)
.join(','),
startTime: `${safeArray(dateRangeValue.value)[0]} 00:00:00`,
endTime: `${safeArray(dateRangeValue.value)[1]} 23:59:59`,
};
const response = await queryBilling(queryParams.value);
const rawData = safeArray(safeGet(response, 'data.records', []));
rawPrescriptionList.value = rawData;
// 核心按encounterId分组数据
groupedPrescriptionList.value = groupByEncounterId(rawData);
// 默认展开第一个患者面板
if (groupedPrescriptionList.value.length > 0 && activeCollapseNames.value.length === 0) {
activeCollapseNames.value = ['patient-0'];
}
// 重置选中状态
selectedRows.value = {};
selectedFeeItems.value = [];
ElMessage.success(`查询成功,共找到 ${groupedPrescriptionList.value.length} 位患者的划价数据`);
} catch (error) {
console.error('查询失败:', error);
ElMessage.error(`查询失败:${safeGet(error, 'message', '网络异常')}`);
rawPrescriptionList.value = [];
groupedPrescriptionList.value = [];
} finally {
loading.value = false;
}
};
/**
* 打开新增弹窗
*/
const handAddBilling = () => {
const patientList = safeArray(patientInfoList.value);
if (patientList.length === 0) {
ElMessage.warning('请先选择患者');
return;
}
if (patientList.length > 1) {
ElMessage.warning('新增划价仅支持单患者操作');
return;
}
currentPatientInfo.value = patientList[0];
dialogVisible.value = true;
};
//新增划价
const handleCalculate = (patientGroup) => {
const patientList = safeArray(patientInfoList.value);
if (patientList.length === 0) {
ElMessage.warning('请先选择患者');
return;
}
if (patientGroup.length === 0) {
ElMessage.warning('该患者暂无医嘱信息,无法新增划价');
return;
}
const currentPatient = patientList.find(
(p) => safeGet(p, 'encounterId') === safeGet(patientGroup[0], 'encounterId')
);
if (!currentPatient) {
ElMessage.warning('无法获取当前患者信息');
return;
}
currentPatientInfo.value = currentPatient;
dialogVisible.value = true;
};
/**
* 弹窗确认
* @param {Object} data - 弹窗数据
*/
const handleFeeDialogConfirm = async (data) => {
try {
if (!data || typeof data !== 'object') {
ElMessage.warning('请填写计费信息');
return;
}
loading.value = true;
await addBilling({
...data,
operatorId: userId.value,
orgId: orgId.value,
});
ElMessage.success('计费新增成功');
dialogVisible.value = false;
await handleQuery();
} catch (error) {
ElMessage.error(`计费失败:${safeGet(error, 'message', '提交异常')}`);
} finally {
loading.value = false;
}
};
/**
* 弹窗取消
*/
const handleFeeDialogCancel = () => {
dialogVisible.value = false;
selectedFeeItems.value = [];
currentPatientInfo.value = null;
};
/**
* 单个患者批量撤销
* @param {Number} index - 患者索引
*/
const handleBatchDelete = (index) => {
const rows = safeArray(selectedRows.value[index]);
if (rows.length === 0) {
ElMessage.warning('请先选择要撤销的划价项目');
return;
}
// 第一步:显示确认弹窗
ElMessageBox.confirm(`确认对选中的 ${rows.length} 项划价内容进行批量撤销?`, '批量撤销', {
type: 'warning',
})
.then(() => {
// 用户确认后执行撤销逻辑
loading.value = true;
// 构造请求参数
const param = rows.map((row) => ({
requestId: safeGet(row, 'requestId'),
adviceType:
safeGet(row, 'adviceTable') === 'wor_device_request'
? 2
: safeGet(row, 'adviceTable') === 'wor_service_request'
? 3
: 1,
}));
// 调用批量撤销接口Promise 链式调用)
return deleteBilling(param);
})
.then(() => {
// 接口调用成功
ElMessage.success('批量撤销成功');
handleQuery(); // 重新查询刷新数据
})
.catch((error) => {
// 异常处理(取消操作/接口失败)
if (error !== 'cancel') {
// 排除用户点击取消的情况
ElMessage.error(`批量撤销失败:${safeGet(error, 'message', '操作异常')}`);
}
})
.finally(() => {
// 无论成功/失败,最终关闭加载状态
loading.value = false;
});
};
const handleSingleDelete = (row) => {
if (!row || row.length === 0) {
ElMessage.warning('请先选择要撤销的划价项目');
return;
}
// 第一步:显示确认弹窗
ElMessageBox.confirm(`确认对选中的 ${row.adviceName} 项划价内容进行批量撤销?`, '批量撤销', {
type: 'warning',
})
.then(() => {
// 用户确认后执行撤销逻辑
loading.value = true;
// 构造请求参数
const rowArr = safeArray([row]);
const param = rowArr.map((row) => ({
requestId: safeGet(row, 'requestId'),
adviceType:
safeGet(row, 'adviceTable') === 'wor_device_request'
? 2
: safeGet(row, 'adviceTable') === 'wor_service_request'
? 3
: 1,
}));
// 调用批量撤销接口Promise 链式调用)
return deleteBilling(param);
})
.then(() => {
// 接口调用成功
ElMessage.success('批量撤销成功');
handleQuery(); // 重新查询刷新数据
})
.catch((error) => {
// 异常处理(取消操作/接口失败)
if (error !== 'cancel') {
// 排除用户点击取消的情况
ElMessage.error(`批量撤销失败:${safeGet(error, 'message', '操作异常')}`);
}
})
.finally(() => {
// 无论成功/失败,最终关闭加载状态
loading.value = false;
});
};
// ========== 初始化 ==========
onMounted(() => {
// 设置默认日期
const today = new Date();
const defaultDate = formatDateStr(today, 'YYYY-MM-DD');
dateRangeValue.value = [defaultDate, defaultDate];
// 监听日期变化自动查询
watch(
[dateRange, dateRangeValue],
([newRange, newVal], [oldRange, oldVal]) => {
if (oldRange !== undefined && safeArray(newVal).length === 2) {
handleQuery();
}
},
{ deep: true }
);
// 初始化统计信息
calculateTotalStats.value;
});
</script>
<style scoped>
/* 基础样式 */
.font-bold {
font-weight: 600;
}
.text-primary {
color: #409eff;
}
.text-danger {
color: #f56c6c;
}
.text-success {
color: #67c23a;
}
/* 空状态容器 */
.empty-container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
/* 折叠面板容器 */
.prescription-collapse-container {
--el-collapse-item-border-radius: 8px;
}
/* 患者折叠项 */
.patient-collapse-item {
margin-bottom: 12px;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}
/* 患者头部 */
.patient-header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 0;
flex-wrap: wrap;
gap: 8px;
}
.patient-basic-info {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
}
.patient-name {
font-weight: 600;
font-size: 15px;
margin-right: 10px;
}
.patient-info-tag {
color: #666;
font-size: 13px;
margin-right: 8px;
}
.patient-ext-info {
display: flex;
align-items: center;
gap: 15px;
flex-wrap: wrap;
}
.ext-item {
display: flex;
align-items: center;
font-size: 13px;
flex-wrap: wrap;
}
.ext-item .label {
color: #999;
margin-right: 4px;
}
.ext-item .amount {
color: #e6a23c;
font-weight: 600;
}
.patient-amount-preview {
font-size: 13px;
color: #333;
margin-left: 10px;
}
.patient-amount-preview .amount {
color: #e6a23c;
font-weight: 600;
}
/* 医嘱表格容器 */
.prescription-table-container {
padding: 10px 0;
}
:deep(.el-table) {
--el-table-header-text-color: #333;
--el-table-row-hover-bg-color: #f8f9fa;
--el-table-border-color: #e4e7ed;
}
.priced-row {
background-color: #f0f9ff !important;
}
.advice-content {
display: flex;
flex-direction: column;
}
.advice-detail {
font-size: 12px;
color: #447c95;
margin-top: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 患者操作栏 */
.patient-actions {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0 0;
margin-top: 8px;
border-top: 1px dashed #e4e7ed;
}
.patient-amount {
font-size: 14px;
color: #333;
}
.patient-amount .amount {
color: #e6a23c;
font-weight: 600;
}
/* 日期Tabs样式 */
.date-tabs :deep(.el-tabs__header) {
margin-bottom: 0;
}
.date-tabs :deep(.el-tabs__content) {
display: none;
}
/* 折叠面板样式优化 */
:deep(.el-collapse-item__header) {
padding: 12px 15px;
background-color: #fff;
}
:deep(.el-collapse-item__content) {
padding: 0 15px 15px;
background-color: #fff;
}
:deep(.el-collapse) {
--el-collapse-header-text-color: #333;
--el-collapse-content-bg-color: #fff;
}
/* 表格单元格溢出处理 */
:deep(.el-table__cell) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>