240 lines
6.8 KiB
Vue
Raw Normal View History

2025-05-20 16:34:38 +08:00
<template>
<div class="compact-form">
<el-table
:data="tableData"
border
stripe
highlight-current-row
@selection-change="handleSelectionChange"
class="custom-table-container"
height="640px"
style="width: 100%; --table-row-height: 32px;"
:header-cell-style="{ backgroundColor: '#f5f7fa' }"
>
<el-table-column
type="index" prop="id" label="" width="45" :index="getRowIndex" >
</el-table-column>
<el-table-column type="selection" width="30"></el-table-column>
<el-table-column prop="jyrq" label="检验日期" v-if="false"></el-table-column>
<el-table-column prop="yq" label="仪器" v-if="false"></el-table-column>
<el-table-column prop="ybh" label="样本号" v-if="false"></el-table-column>
<el-table-column prop="xmdh" label="项目" width="60" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="xmmc" label="名称" width="100" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="csjg" label="结果" width="100" >
<template #default="scope">
<el-input v-model="scope.row.csjg" size="small" class="full-width-input"></el-input>
</template>
</el-table-column>
<el-table-column prop="od" label="OD" width="60" v-if="false">
<template #default="scope">
<el-input v-model="scope.row.od" size="small" class="full-width-input"></el-input>
</template>
</el-table-column>
<el-table-column prop="cutoff" label="SCO" width="60" v-if="false">
<template #default="scope">
<el-input v-model="scope.row.od" size="small" class="full-width-input"></el-input>
</template>
</el-table-column>
<el-table-column prop="refs" label="参考值" width="100" show-overflow-tooltip>
</el-table-column>
<el-table-column prop="dw" label="单位" width="100" show-overflow-tooltip >
</el-table-column>
</el-table>
</div>
</template>
<script setup>
//import {ref, reactive, watch, toRefs, nextTick} from 'vue';
import {deleteresult, queryLabResults} from "@/api/liswork/work/LisWork.js";
import {delType} from "@/api/system/dict/type.js";
import {ElMessageBox} from "element-plus";
const { proxy } = getCurrentInstance();
const props = defineProps({
// 表格数据
tableData: {type: Array,default: () => []},
//主键
tableKey:{type: Array, default: () => []},
// 部门选项
// departments: {
// type: Array,
// default: () => []
// },
// 是否只读
readonly: {type: Boolean, default: false}
});
const { tableData, tableKey, readonly,undeleteflag,hasChanges } = toRefs(props);
const emits = defineEmits([
'add', // 新增行
'save', // 保存数据
'delete', // 删除行
'batch-delete', // 批量删除
'fetchLabResults' //刷新数据
]);
// 选中的行
const selectedRows = ref([]);
const filteredList = ref([]);
// 原始数据副本,用于检测变化
const originalData = ref(JSON.parse(JSON.stringify(props.tableData)));
// 处理选择变化
const handleSelectionChange = (val) => {
selectedRows.value = val;
if (val.length === 0) {
emits('delfalg', true);
}else{
emits('delfalg', false);
}
};
// 新增行
const handleAdd = () => {
// emits('add');
// 创建新行数据
const newRow = {
jyrq: tableKey.jyrq,
yq: tableKey.yq,
ybh: tableKey.ybh
};
// 添加到表格数据
tableData.value.push(newRow);
// 动画结束后移除标记
// 可选:滚动到表格底部并聚焦到第一个输入框
nextTick(() => {
const tableData = document.querySelector('.el-table__body-wrapper');
if (tableData) {
tableData.scrollTop = tableData.scrollHeight;
}
// 聚焦到新行的第一个输入框
const inputs = document.querySelectorAll('.el-input__inner');
if (inputs.length > 0) {
inputs[4].focus(); // 通常最后一个是操作列的按钮,所以取倒数第二个
}
})
};
// 保存数据
const handleSave = () => {
if (hasChanges.value) {
emits('save', props.tableData);
// 保存后更新原始数据
// originalData.value = JSON.parse(JSON.stringify(props.tableData));
hasChanges.value = false;
}
};
// 删除行
const handleDelete = (row) => {
emits('delete', row);
tableData.value = tableData.value.filter(item => item.id !== row.id);
};
// 批量删除(调用API)
const handleBatchDelete = async () => {
try {
if (selectedRows.length === 0) {
return;
}
// 确认删除
await ElMessageBox.confirm(
`确定要删除选中的 ${selectedRows.value.length} 条记录吗?`,
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
);
await deleteresult(selectedRows.value);
fetchLabResults();
} catch (error) {
// 错误已经在拦截器中处理,这里可以不做处理或添加额外逻辑
console.error('删除失败:', error);
}
}
// 重置表格的修改状态
const resetChange = () => {
// 原始数据副本,用于检测变化
originalData.value = JSON.parse(JSON.stringify(props.tableData));
hasChanges.value = false;
};
const fetchLabResults = () => {
emits('fetchLabResults');
}
// 监听数据变化
watch(() => props.tableData, (newVal, oldVal) => {
// 简单比较数据是否有变化
//hasChanges.value = JSON.stringify(newVal) !== JSON.stringify(originalData.value);
}, { deep: true });
// 获取行号(支持分页时显示正确行号)
const getRowIndex = (index) => {
// 如果有分页,可以根据当前页码计算真实行号
// return (currentPage - 1) * pageSize + index + 1;
// 无分页时直接返回索引+1
return index + 1;
};
// 暴露方法给父组件
defineExpose({
handleAdd,
handleDelete,
handleSave,
handleBatchDelete
});
</script>
<style scoped>
/* 移除单元格内边距 */
.custom-table-container /deep/ .el-table__cell {
padding: 0 !important;
}
/* 表格行高 */
.custom-table-container /deep/ .el-table__row {
height: var(--table-row-height) !important;
}
/* 输入框占满单元格 */
.full-width-input /deep/ .el-input__inner {
width: 100%;
height: calc(var(--table-row-height) - 2px); /* 减去上下边框 */
padding: 0 0px; /* 减小内边距 */
border: 0px solid #dcdfe6;
border-radius: 0;
box-sizing: border-box;
background-color: transparent; /* 可选:透明背景 */
}
/* 输入框聚焦效果 */
.full-width-input /deep/ .el-input__inner:focus {
border-color: #409eff;
box-shadow: 0 0 0 0px rgba(64, 158, 255, 0.2);
outline: none;
}
/* 新增行动画 */
.el-table__body-wrapper {
overflow: visible !important; /* 确保动画不被裁剪 */
}
.new-row-enter-active {
animation: fadeIn 0.5s ease;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>