组件
<template>
<!-- https://blog.csdn.net/m0_58953167/article/details/134895241-->
<el-dialog v-model="visible" @close="tableData=[]">
<div class="box">
<el-table :data="tableData" border style="width: 100%;margin: 0 auto;" max-height="250px" >
<el-table-column label="序号" align="center" width="70px">
<template #default="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column v-for="(column, index) in dynamicColumns" :key="index" :prop="column.prop" :label="column.label" align="center" width="auto">
<template #default="scope">
<!-- <el-input v-model="scope.row[column.prop]" size="small"></el-input>-->
<el-form-item >
<el-input :rules="[{ required: true, message: '输入不能为空', trigger: 'blur' }]" v-model="scope.row[column.prop]" size="small"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="70">
<template #default="scope">
<el-button @click="deleteTableData(scope.row)" link icon="Delete" type="primary"></el-button>
</template>
</el-table-column>
</el-table>
</div>
<div style="height: 10px"></div>
<el-row :gutter="20" type="flex" justify="center">
<el-col :span="6">
<el-button type="primary" @click="submitRelateData">提交</el-button>
</el-col>
<el-col :span="6" class="text-right">
<el-button type="primary" @click="addTableData">添加</el-button>
</el-col>
</el-row>
</el-dialog>
</template>
<script setup >
import {ref} from 'vue';
import baseService from "@/service/baseService";
import {ElMessage} from "element-plus";
const tableData = ref([]);
const visible = ref(false);
const dynamicColumns = ref([]);
const rowData = ref({})
//动态加载后端对应后续动态字段
const getTeachClass = async (row)=>{
try {
const res = await baseService.post("/obe/examine/getDynammicField/",row);
if(res.code!==0) {
ElMessage.error("数据初始化失败!");
}
return res.data;
}catch{
ElMessage.error("获取动态字段列表失败!");
return [];
}
}
//后端初始化列数据
const init = async (row) => {
//回显动态字段
const columnsFromBackend = [
//此为固定字段,后端有用到,前后端要统一
{"prop":"作业","label":"作业"},
];
//动态字段加载
const data = await getTeachClass(row);
data.forEach((item)=>{
const newRow = {};
newRow["prop"] = item;
newRow["label"] = item;
columnsFromBackend.push(newRow)
})
//根据后端信息构造动态字段数据 例如:{"prop":"作业","label":"作业"},
dynamicColumns.value = columnsFromBackend;
//后端初始化表格数据
let rows = await tableDataInit(row)
for (let i=0;i<rows.length;i++) {
let newRow={}
dynamicColumns.value.forEach((column) => {
// 后端获取的某列如果不存在则该列的值为0,可以查看对应sql查出来的数据
let value = rows[i][column.prop]==null?
0:(Number.isNaN(Number(rows[i][column.prop]))?
rows[i][column.prop]:Number(rows[i][column.prop]));
newRow[column.prop] = value;
});
tableData.value.push(newRow);
}
};
//回显表格数据
const tableDataInit = async (row)=>{
try {
const res = await baseService.post("/obe/examine/getObjectRelations/",row);
if(res.code!==0) {
ElMessage.error("数据初始化失败!");
}
return res.data;
}catch{
ElMessage.error("数据初始化失败!");
}
}
//提交关联信息列表数据
const submitRelateData = async ()=>{
// console.log("表格关联数据:"+tableData.value);
// console.log("行数据:"+rowData.value);
const submitData= {"tableData":tableData.value,"examineEntity":rowData.value};
let hasInvalidData = false; // 设置标志位,表示是否存在无效数据
for (let i=0;i<tableData.value.length;i++) {
dynamicColumns.value.forEach((item)=>{
//当前只有非空校验
if (tableData.value[i][item.prop]===""||tableData.value[i][item.prop]===undefined) {
ElMessage.error("数据不合法,请重新输入!");
hasInvalidData = true; // 如果发现无效数据,将标志位设为 true
}
})
if (hasInvalidData) {
break; // 如果存在无效数据,跳出外部循环
}
}
if (hasInvalidData) {
return; // 如果存在无效数据,直接return函数
}
//更新提交表格
try {
const res = await baseService.post("/obe/examine/updateTableData/",submitData);
if(res.code!==0) {
ElMessage.error("数据更新失败!");
}
}catch{
ElMessage.error("服务器异常!");
}
tableData.value=[];
visible.value=false;
}
// 新增一行
const addTableData = ()=>{
const newRow = {};
dynamicColumns.value.forEach((column) => {
newRow[column.prop] = null;
});
tableData.value.push(newRow);
}
// 删除
const deleteTableData = (row) =>{
const index = tableData.value.indexOf(row);
if (index !== -1) {
tableData.value.splice(index, 1);
}
}
//获取每条考核信息记录,回显数据初始化函数入口
const setrowData = (row)=>{
init(row);
visible.value = true;
rowData.value = row;
}
defineExpose({
setrowData
});
</script>
<style scoped>
.box{
position: relative;
.icon{
position: absolute;
bottom:10px;
right: 19px;
}
}
.text-right {
text-align: right;
}
</style>
表格示例
后端加载动态字段接口信息示例
回显数据接口示例
数据提交示例