<template>
<div class="bim-card-emer-plan-management">
<!-- 封装的对话框组件:用于新建、编辑和查看应急预案 -->
<emergency-plan-dialog
:dialog-visible="dialogVisible"
:dialog-mode="dialogMode"
:emergency-event-type-options="emergencyEventTypeOptions"
:current-form="currentForm"
@update:dialogVisible="val => (dialogVisible = val)"
@update:currentForm="val => (currentForm = val)"
@dialog-closed="handleDialogClosed"
@submit="handleSubmit"
:bridge-unit-map="bridgeUnitMap"
:bridge-options="bridgeOptions" />
<!-- 主内容卡片 -->
<el-card>
<div class="box">
<!-- 头部搜索区域 -->
<div class="box__header">
<el-row :gutter="10" type="flex" justify="end">
<!-- 桥梁选择器 -->
<el-col :span="5" :offset="8">
<bridge-cascader v-model="selectBridge" :bridge-options="bridgeOptions"
@change="handleSearchBridgeChange" :current-bridge-code="storageKey"
:show-all-levels="false" />
</el-col>
<!-- 预案类型选择器 -->
<el-col :span="5">
<el-select v-model="selectAccident" placeholder="请选择预案类型" clearable size="medium"
@clear="handleSearch" class="emergencyTypeClass">
<el-option v-for="item in emergencyEventTypeOptions" :key="item.value"
:label="item.label" :value="item.value" filterable />
</el-select>
</el-col>
<!-- 搜索输入框 -->
<el-col :span="6">
<el-input placeholder="请输入预案名称/描述" v-model="emergencyName" clearable size="medium"
@clear="handleSearch" />
</el-col>
<!-- 搜索按钮 -->
<el-col :span="1.5">
<el-button type="primary" icon="el-icon-search" @click="handleSearch" size="medium">
搜索
</el-button>
</el-col>
<!-- 新建按钮 -->
<el-col :span="1.5">
<el-button type="success" icon="el-icon-circle-plus" @click="openCreateDialog"
size="medium">
新建
</el-button>
</el-col>
</el-row>
</div>
<!-- 主体表格区域 -->
<div class="box__content">
<el-table :data="tableData" style="width: 100%; " :cell-style="{ textAlign: 'center' }"
:header-cell-style="{ textAlign: 'center' }" class="full-height-table">
<el-table-column prop="bridgeName" label="桥梁名称" width="150"></el-table-column>
<el-table-column prop="bridgeCode" label="桥梁编号" width="200"></el-table-column>
<el-table-column prop="emergencyPlanUnit" label="运营单位" width="250"></el-table-column>
<el-table-column prop="emergencyPlanName" label="应急预案名称" width="250"></el-table-column>
<el-table-column prop="emergencyPlanType" label="应急预案类型" width="300"></el-table-column>
<el-table-column prop="emergencyPlanDesc" label="应急预案说明" width="300"></el-table-column>
<el-table-column prop="emergencyPlanRemark" label="应急预案备注" width="300"></el-table-column>
<!-- 操作列 -->
<el-table-column fixed="right" label="操作" width="300">
<template slot-scope="scope">
<el-button-group>
<!-- 修改按钮 -->
<el-button type="primary" icon="el-icon-edit" size="mini"
@click="handleEdit(scope.row)">
修改
</el-button>
<!-- 查看按钮 -->
<el-button type="success" icon="el-icon-view" size="mini"
@click="handleView(scope.row)">
查看
</el-button>
<!-- 删除按钮 -->
<el-button type="danger" icon="el-icon-delete" size="mini"
@click="handleDelete(scope.row)">
删除
</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页区域 -->
<div class="box__footer">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="pagination.pageNo" :page-sizes="[15, 20, 25, 50]"
:page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="total" />
</div>
</div>
</el-card>
</div>
</template>
<script>
// 引入自动高度混入
import autoHeight from "@/mixin/autoHeight";
// 引入字典配置工具
import { mapCfg } from "@/utils";
// 引入应急预案管理API
import {
getEmergencyPlanPageList,
addEmergencyPlan,
deleteEmergencyPlan,
getEmergencyPlanInfo,
updateEmergencyPlan
} from "@/api/emergency-plan-maint-controller.js";
// 引入桥梁级联选择器组件
import BridgeCascader from "./BridgeCascader.vue";
// 引入应急预案对话框组件
import EmergencyPlanDialog from "./EmergencyPlanDialog.vue";
export default {
name: "emergencyPlanManagementTable",
// 使用自动高度混入
mixins: [autoHeight],
components: { BridgeCascader, EmergencyPlanDialog },
data() {
return {
// 默认选中的桥梁编码
storageKey: "G76431026R0310",
// 当前选中的桥梁
selectBridge: "",
// 桥梁与单位的映射关系
bridgeUnitMap: {},
// 桥梁选项数据
bridgeOptions: [],
// 对话框是否可见
dialogVisible: false,
// 对话框模式:create(创建)/edit(编辑)/view(查看)
dialogMode: "create",
// 数据总数
total: 0,
// 分页参数
pagination: {
pageSize: 15,
pageNo: 1
},
// 搜索条件表单
filterForm: {},
// 选中的预案类型
selectAccident: "",
// 搜索关键字(预案名称/描述)
emergencyName: "",
// 表格数据
tableData: [],
// 预案类型选项
emergencyEventTypeOptions: [],
// 当前表单数据
currentForm: {
bridgeCode: "",
emergencyPlanName: "",
emergencyPlanType: "",
emergencyContacts: "",
emergencyTel: "",
emergencyPlanDesc: "",
emergencyPlanRemark: "",
emergencyPlanUnit: "",
fileList: [],
createDate: "",
creator: "",
isDelete: 0,
isLast: 1
}
};
},
// 组件创建时的生命周期钩子
async created() {
// 获取预案类型选项
await this.getEmergencyEventTypeOptins();
// 加载第一页数据
await this.loadListData();
},
methods: {
/**
* 处理桥梁选择变化
* @param {Object} payload - 选择的桥梁数据
*/
handleSearchBridgeChange(payload) {
const bridgeCode = payload ? payload.bridgeCode : "";
this.selectBridge = bridgeCode;
// 触发搜索
this.handleSearch();
},
/**
* 处理搜索操作
*/
handleSearch() {
// 设置搜索条件
this.filterForm = {
bridgeCode: this.selectBridge,
planType: this.selectAccident,
searchKey: this.emergencyName
};
// 重置到第一页
this.pagination.pageNo = 1;
// 重新加载数据
this.loadListData();
},
/**
* 处理每页条数变化
* @param {number} val - 新的每页条数
*/
handleSizeChange(val) {
this.pagination.pageSize = val;
this.pagination.pageNo = 1;
this.loadListData();
},
/**
* 处理当前页码变化
* @param {number} val - 新的页码
*/
handleCurrentChange(val) {
this.pagination.pageNo = val;
this.loadListData();
},
/**
* 获取预案类型选项
*/
async getEmergencyEventTypeOptins() {
try {
// 从字典配置中获取预案类型
const dictList = await mapCfg("EmergencyEventType")();
// 转换为组件需要的格式
this.emergencyEventTypeOptions = dictList.map(item => ({
value: item.key,
label: item.value
}));
} catch (error) {
console.error("获取失败", error);
}
},
/**
* 加载表格数据
*/
async loadListData() {
try {
// 设置请求参数
const params = {
pageSize: this.pagination.pageSize,
pageNo: this.pagination.pageNo,
bridgeCode: this.selectBridge,
planType: this.filterForm.planType,
searchKey: this.filterForm.searchKey
};
// 调用API获取数据
const res = await getEmergencyPlanPageList(params);
// 处理数据:将预案类型值转换为标签
this.tableData = res.entities.map(item => {
const typeOption = this.emergencyEventTypeOptions.find(
opt => opt.value === item.emergencyPlanType
);
return {
...item,
emergencyPlanType: typeOption ? typeOption.label : item.emergencyPlanType
};
});
// 设置数据总数
this.total = res.entityCount;
} catch (error) {
console.error("获取数据失败:", error);
this.$message.error("获取数据失败");
}
},
/**
* 打开创建对话框
*/
openCreateDialog() {
this.dialogMode = "create";
this.dialogVisible = true;
const now = new Date();
// 初始化表单数据
this.currentForm = {
bridgeCode: "",
emergencyPlanName: "",
emergencyPlanType: "",
emergencyContacts: "",
emergencyTel: "",
emergencyPlanDesc: "",
emergencyPlanRemark: "",
emergencyPlanUnit: "",
fileList: [],
// 设置创建日期
createDate: now.toISOString(),
// 设置创建人
creator: this.$store.state.user.userInfo?.username || "系统用户",
isDelete: 0,
isLast: 1
};
},
/**
* 处理对话框关闭事件
*/
handleDialogClosed() {
// 重置表单数据
this.currentForm = {
bridgeCode: "",
emergencyPlanName: "",
emergencyPlanType: "",
emergencyContacts: "",
emergencyTel: "",
emergencyPlanDesc: "",
emergencyPlanRemark: "",
emergencyPlanUnit: "",
fileList: []
};
},
/**
* 处理表单提交
* @param {Object} formData - 提交的表单数据
*/
handleSubmit(formData) {
this.submitForm(formData);
},
/**
* 提交表单数据
* @param {Object} formData - 表单数据
*/
async submitForm(formData) {
try {
// 移除不需要的字段
const { emergencyPlanUnit, ...params } = formData;
if (this.dialogMode === "create") {
// 创建操作
await addEmergencyPlan(params);
this.$message.success("创建成功");
} else if (this.dialogMode === "edit") {
// 编辑操作
params.id = this.currentForm.id;
await updateEmergencyPlan(params);
this.$message.success("修改成功");
}
// 关闭对话框
this.dialogVisible = false;
// 重置到第一页并刷新数据
this.pagination.pageNo = 1;
this.loadListData();
} catch (error) {
console.error("操作失败:", error);
this.$message.error(this.dialogMode === "create" ? "创建失败" : "修改失败");
}
},
/**
* 处理删除操作
* @param {Object} row - 要删除的行数据
*/
handleDelete(row) {
// 确认对话框
this.$confirm("确认删除这条应急预案吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
// 调用删除API
deleteEmergencyPlan({ emergencyPlanId: row.id })
.then(res => {
if (res) {
this.$message.success("删除成功");
// 刷新数据
this.loadListData();
this.pagination.pageNo = 1;
} else {
this.$message.error("删除失败");
}
})
.catch(error => {
this.$message.error("删除请求失败");
console.error(error);
});
})
.catch(action => {
if (action === "cancel") {
this.$message.info("已取消删除");
}
});
},
/**
* 处理编辑操作
* @param {Object} row - 要编辑的行数据
*/
handleEdit(row) {
this.dialogMode = "edit";
this.handleList(row);
},
/**
* 处理查看操作
* @param {Object} row - 要查看的行数据
*/
handleView(row) {
this.dialogMode = "view";
this.handleList(row);
},
/**
* 加载应急预案详情
* @param {Object} row - 行数据
*/
// 在handleList方法中,添加桥梁名称到currentForm
async handleList(row) {
try {
const id = row.id;
const res = await getEmergencyPlanInfo({ emergencyPlanId: id });
// 添加桥梁名称到表单数据
const bridgeOption = this.bridgeOptions.flatMap(company =>
company.children).find(b => b.value === res.bridgeCode);
this.dialogVisible = true;
this.currentForm = {
...res,
bridgeName: bridgeOption ? bridgeOption.bridgeName : "", // 添加桥梁名称
fileList: res.fileList || [],
// ...其他字段
};
} catch (error) {
console.error("获取详情失败:", error);
this.$message.error("获取详情失败");
}
}
}
};
</script>
<style scoped>
/* 主容器样式 */
.bim-card-emer-plan-management {
height: 100%;
display: flex;
flex-direction: column;
}
/* 卡片样式 */
.el-card {
height: 100%;
display: flex;
flex-direction: column;
}
/* 卡片体样式 */
.el-card ::v-deep .el-card__body {
flex: 1;
display: flex;
flex-direction: column;
padding: 0;
height: 100%;
}
/* 内部容器布局 */
.box {
display: flex;
flex-direction: column;
height: 100%;
padding: 0 15px 15px 15px;
}
/* 头部区域样式 */
.box__header {
flex-shrink: 0;
/* 防止压缩 */
padding: 10px 0;
margin-bottom: 0;
}
/* 内容区域样式 */
.box__content {
flex: 1;
/* 占据剩余空间 */
display: flex;
flex-direction: column;
min-height: 300px;
/* 最小高度 */
height: 0;
/* 允许内容区域伸缩 */
}
/* 底部区域样式 */
.box__footer {
flex-shrink: 0;
/* 防止压缩 */
padding: 15px 0 5px;
display: flex;
justify-content: left;
/* 左对齐 */
}
/* 全高表格样式 */
.full-height-table {
flex: 1;
height: auto !important;
display: flex;
flex-direction: column;
}
/* 行间距 */
.el-row {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
/* 预案类型选择器样式 */
.emergencyTypeClass {
width: 100%;
/* 宽度100% */
}
/* 表格内部样式调整 */
.full-height-table ::v-deep .el-table {
height: 100% !important;
}
/* 表格体包装器样式 */
.full-height-table ::v-deep .el-table__body-wrapper {
height: calc(100% - 40px) !important;
/* 减去表头高度 */
overflow-y: auto !important;
/* 允许垂直滚动 */
flex: 1;
}
</style> 修复table内操作列不能随表格垂直滚动的问题 不要移除fixed="right" 发我修改好的完整代码