<template>
  <el-dialog :title="dialogMode === 'create' ? '新建' : dialogMode === 'edit' ? '修改' : '查看'" :visible.sync="dialogVisible"
    :modal-append-to-body="true" append-to-body :close-on-click-modal="false" custom-class="fixed-height-dialog"
    width="60%" top="5vh">
    <el-form label-width="80px" ref="formRef" :model="currentForm"
      style="height: 100%; display: flex; flex-direction: column;" :rules="rules">
      <!-- 项目信息区域 -->
      <div class="formBorder">
        <el-row :gutter="10">
          <el-col :span="6">
            <el-form-item size="mini" label="项目名称" prop="projectName">
              <el-input v-model="currentForm.projectName" clearable style="width:100%" size="mini"
                :disabled="dialogMode === 'view'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item size="mini" label="项目编号" prop="projectCode">
              <el-input v-model="currentForm.projectCode" clearable style="width:100%" size="mini"
                :disabled="dialogMode === 'view'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item size="mini" label="项目周期" prop="projectDate">
              <el-date-picker v-model="projectDate" range-separator="→" start-placeholder="请选择开始日期"
                end-placeholder="请选择结束日期" type="daterange" size="mini" style="width: 100%;" unlink-panels
                :disabled="dialogMode === 'view'">
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="6">
            <el-form-item label="负责人" size="mini" style="width: fit-content;">
              <el-input v-model="currentForm.projectUser" clearable style="width:100%" size="mini"
                :disabled="dialogMode === 'view'"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="项目概述">
              <el-input v-model="currentForm.remark" :rows="2" :disabled="dialogMode === 'view'"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </div>
      <!-- 待检边坡区域 - 使用纯CSS控制高度 -->
      <div class="formBorder2">
        <el-container style="height: 100%;">
          <el-header style="height: auto; flex-shrink: 0; padding-bottom: 10px;">
            <el-row :gutter="10" type="flex" class="searchDialog">
              <el-col :span="5">
                <el-select v-model="filterForm.maintenanceCompanyName" placeholder="请选择管养单位" size="mini" clearable
                  filterable @clear="resetSearch" :disabled="dialogMode === 'view'">
                  <el-option v-for="item in MaintenanceUnitoptions" :key="item.value" :label="item.label"
                    :value="item.value"></el-option>
                </el-select>
              </el-col>
              <el-col :span="5">
                <el-select v-model="filterForm.routeCode" placeholder="请选择路线编号" size="mini" clearable filterable
                  @clear="resetSearch" :disabled="dialogMode === 'view'">
                  <el-option v-for="item in routeCodeOptions" :key="item.value" :label="item.label"
                    :value="item.value"></el-option>
                </el-select>
              </el-col>
              <el-col :span="5">
                <el-input v-model="filterForm.searchKey" placeholder="请输入边坡编号或名称" size="mini" clearable
                  @keyup.enter.native="searchForm" @clear="resetSearch" :disabled="dialogMode === 'view'">
                  <i slot="suffix" class="el-input__icon el-icon-search"></i>
                </el-input>
              </el-col>
              <el-col :span="5">
                <el-select v-model="filterForm.evaluateLevel" placeholder="请选择技术状态等级" size="mini" clearable
                  @clear="resetSearch" :disabled="dialogMode === 'view'">
                  <el-option v-for="item in evaluateLeveloptions" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-select>
              </el-col>
              <el-col :span="2" :offset="4">
                <el-button type="primary" size="mini" style="width:100%" icon="el-icon-search" @click="searchForm"
                  :loading="loading" :disabled="dialogMode === 'view'">搜索</el-button>
              </el-col>
            </el-row>
          </el-header>
          <!-- 边坡表格 - 移除动态高度绑定 -->
          <el-main style="overflow-y: hidden;">
            <el-table ref="scrollTable" v-loading="loading" style="width: 100%;" border :data="formTabledata"
              :row-style="{ height: '36px' }" :cell-style="{ padding: '4px 0', textAlign: 'center' }"
              :header-cell-style="{
                height: '36px',
                padding: '4px 0',
                lineHeight: '36px',
                textAlign: 'center'
              }" @selection-change="handleSelectionChange" :row-key="getRowkey">
              <!-- 选择列(查看模式禁用) -->
              <el-table-column type="selection" width="55" :selectable="isRowSelectable" :reserve-selection="true">
              </el-table-column>
              <!-- 其他数据列 -->
              <el-table-column label="管养单位" prop="maintenanceCompanyName" width="290"
                show-overflow-tooltip></el-table-column>
              <el-table-column label="路线编号" prop="routeCode" width="100"></el-table-column>
              <el-table-column label="边坡编号" prop="sideSlopeCode" width="240" show-overflow-tooltip></el-table-column>
              <el-table-column label="边坡名称" prop="sideSlopeName" width="267" show-overflow-tooltip></el-table-column>
              <el-table-column label="技术状态等级" width="137">
                <template slot-scope="scope">
                  {{ mapEvaluateLevel(scope.row.evaluateLevel) }}
                </template>
              </el-table-column>
            </el-table>
          </el-main>
          <!-- 分页区域 -->
          <el-footer style="flex-shrink: 0; padding-top: 10px;">
            <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
              :current-page="pageParams.pageNo" :page-sizes="[10, 20, 50, 100]" :page-size="pageParams.pageSize"
              layout="total, prev, pager, next" :total="total">
            </el-pagination>
          </el-footer>
        </el-container>
      </div>
    </el-form>
    <!-- 弹窗底部按钮 -->
    <div slot="footer" class="dialog-footer" v-if="dialogMode === 'create' || dialogMode === 'edit'">
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="submitForm">提交</el-button>
    </div>
  </el-dialog>
</template>
<script>
import { mapCfg } from "@/utils";
import {
  getPeriodicInspectionSideSlopePageList,
  addPeriodicInspection,
  modifyPeriodicInspection,
  getSelectedPeriodicInspectionSideSlopeList
} from "../../api/testProject";
import { getMaintenanceCompanyList, getRouteList } from "../../api/basicInformation";
export default {
  name: "SideSlopeDialog",
  props: {
    visible: Boolean, // 控制弹窗显示
    mode: String, // 模式:create/edit/view
    initialForm: Object, // 初始表单数据
  },
  data() {
    return {
      isInitializingSelection: false, // 初始化状态标志
      dialogVisible: this.visible, // 弹窗显示状态
      dialogMode: this.mode, // 当前模式
      currentForm: { ...this.initialForm }, // 当前表单数据
      projectDate: [], // 项目日期范围
      total: 0, // 总数据量
      loading: false, // 加载状态
      pageParams: { // 分页参数
        pageNo: 1,
        pageSize: 10,
      },
      filterForm: { // 搜索条件
        maintenanceCompanyName: "",
        routeCode: "",
        searchKey: "",
        evaluateLevel: "",
      },
      mulitipleSelection: [],
      allSelection: new Map(),
      MaintenanceUnitoptions: [], // 管养单位选项
      routeCodeOptions: [], // 路线编号选项
      formTabledata: [], // 表格数据
      evaluateLeveloptions: [], // 技术状态等级选项
      rules: { // 表单验证规则
        projectName: [
          { required: true, message: "项目名称不能为空", trigger: "blur" },
        ],
        projectCode: [
          { required: true, message: "项目编码不能为空", trigger: "blur" },
        ],
      },
    };
  },
  watch: {
    // 修复1:监听visible变化时确保加载数据
    async visible(val) {
      this.dialogVisible = val;
      if (val) {
        // 打开对话框时重置状态
        this.resetAllData();
        // 关键修复:确保在创建模式外加载数据
        if (this.dialogMode !== 'create' && this.currentForm.id) {
          // 确保在DOM更新后加载数据
          await this.$nextTick();
          await this.LoadListData();
        }
      } else {
        // 关闭对话框时重置数据
        this.resetAllData();
      }
    },
    // 修复2:监听模式变化
    mode(val) {
      this.dialogMode = val;
      // 当模式从创建变为编辑/查看时,确保加载数据
      if (this.dialogVisible && val !== 'create' && this.currentForm.id) {
        this.LoadListData();
      }
    },
    // 修复3:监听初始表单数据变化
    initialForm: {
      deep: true,
      immediate: true,  // 添加立即执行
      async handler(val) {
        this.currentForm = { ...val };
        this.projectDate = [val.projectStartDate, val.projectEndDate];
        // 关键修复:当初始表单有ID时立即加载数据
        if (this.dialogVisible && val.id && this.dialogMode !== 'create') {
          await this.$nextTick();
          await this.LoadListData();
        }
      }
    },
    // 同步弹窗显示状态到父组件
    dialogVisible(val) {
      this.$emit("update:visible", val);
    },
    projectDate: {
      deep: true,
      handler(value) {
        if (value && value.length === 2) {
          this.currentForm.projectStartDate = value[0];
          this.currentForm.projectEndDate = value[1];
        }
      },
    },
  },
  async created() {
    // 初始化数据
    this.getRouteList();
    await this.getEvaluateLevel();
    this.getMaintenanceCompanyList();
  },
  methods: {
    handleSelectionChange(selection) {
      // 跳过初始化阶段的选中状态变更
      if (this.isInitializingSelection) return;
      // 获取当前页选中项的key集合
      const currentPageKeys = new Set(
        selection.map(row => row.sideSlopeUniqueCode)
      );
      // 处理当前页的取消选中操作
      this.formTabledata.forEach(row => {
        const key = row.sideSlopeUniqueCode;
        // 仅当行在全局选中池中但不在当前页选中集合时删除
        if (this.allSelection.has(key) && !currentPageKeys.has(key)) {
          this.allSelection.delete(key);
        }
      });
      // 添加新选中的项到全局池
      selection.forEach(row => {
        const key = row.sideSlopeUniqueCode;
        if (!this.allSelection.has(key)) {
          this.allSelection.set(key, row);
        }
      });
      // 更新当前页选中引用
      this.mulitipleSelection = selection;
    },
    getRowkey(row) {
      return row.sideSlopeUniqueCode;
    },
    // 判断行是否可选(查看模式禁用选择)
    isRowSelectable(row, index) {
      return this.dialogMode !== "view";
    },
    // 获取管养单位列表
    async getMaintenanceCompanyList() {
      const res = await getMaintenanceCompanyList();
      this.MaintenanceUnitoptions = res.map((item) => ({
        value: item,
        label: item,
      }));
    },
    // 获取路线列表
    async getRouteList() {
      const res = await getRouteList();
      this.routeCodeOptions = res.map((item) => ({
        value: item.id,
        label: item.routeCode,
      }));
    },
    // 搜索方法
    searchForm() {
      // this.showSelectedOnly = false,
      this.pageParams.pageNo = 1;
      this.LoadListData();
    },
    // 重置搜索条件
    resetSearch() {
      // this.showSelectedOnly = true,
      this.filterForm = {
        maintenanceCompanyName: "",
        routeCode: "",
        searchKey: "",
        evaluateLevel: "",
      };
      this.pageParams.pageNo = 1;
      this.LoadListData();
    },
    // 重置组件状态
    resetAllData() {
      this.resetSelection();
      this.formTabledata = []; // 清空表格数据
      this.total = 0;          // 重置总条数
      this.pageParams = {      // 重置分页
        pageNo: 1,
        pageSize: 10
      };
      // 重置搜索条件(可选)
      this.filterForm = {
        maintenanceCompanyName: "",
        routeCode: "",
        searchKey: "",
        evaluateLevel: ""
      };
    },
    // 修改原有方法
    resetSelection() {
      this.allSelection.clear();
      this.allSelection = new Map();
      if (this.$refs.scrollTable) {
        this.$refs.scrollTable.clearSelection();
      }
    },
    // 映射技术状态等级
    mapEvaluateLevel(level) {
      const option = this.evaluateLeveloptions.find(
        (item) => item.value === level
      );
      return option.label;
    },
    // 加载表格数据
    async LoadListData() {
      this.loading = true;
      try {
        const params = {
          orgId: this.filterForm.maintenanceCompanyName,
          routeId: this.filterForm.routeCode,
          searchKey: this.filterForm.searchKey,
          evaluateLevel: this.filterForm.evaluateLevel,
          pageSize: this.pageParams.pageSize,
          pageNo: this.pageParams.pageNo,
        };
        // 获取表格数据
        const res = await getPeriodicInspectionSideSlopePageList(params);
        this.formTabledata = res.entities;
        this.total = res.entityCount;
        // 处理非创建模式的数据加载
        if (this.dialogMode !== 'create' && this.currentForm.id) {
          // 首次加载时获取所有选中项
          if (this.pageParams.pageNo === 1) {
            const selected = await getSelectedPeriodicInspectionSideSlopeList({
              periodicId: this.currentForm.id,
              pageSize: 10000, // 获取所有选中项
              pageNo: 1
            });
            
            // 重置全局选中池
            this.allSelection.clear();
            this.mulitipleSelection = selected.entities;
            // 存储全局选中状态
            this.mulitipleSelection.forEach(item => {
              this.allSelection.set(item.sideSlopeUniqueCode, item);
            });
          }
          // 设置当前页选中状态
          this.isInitializingSelection = true;
          this.$nextTick(() => {
            this.formTabledata.forEach(row => {
              if (this.allSelection.has(row.sideSlopeUniqueCode)) {
                this.$refs.scrollTable.toggleRowSelection(row, true);
              }
            });
            this.isInitializingSelection = false;
          });
        }
      } catch (error) {
        console.error("加载数据失败:", error);
        this.$message.error("加载数据失败");
      } finally {
        this.loading = false;
      }
    },
    // 分页大小变化
    handleSizeChange(val) {
      this.pageParams.pageSize = val;
      this.pageParams.pageNo = 1;
      this.LoadListData();
    },
    // 当前页码变化
    handleCurrentChange(val) {
      this.pageParams.pageNo = val;
      this.LoadListData();
    },
    // 获取技术状态等级选项
    async getEvaluateLevel() {
      const levelList = await mapCfg("Inspection.Regular.RegularEvaluateLevel")();
      this.evaluateLeveloptions = levelList.map((item) => ({
        value: item.key,
        label: item.value,
      }));
    },
    // 提交表单
    async submitForm() {
      this.$refs.formRef.validate(async (valid) => {
        if (valid) {
          // 验证是否选择了边坡
          const selectedItems = Array.from(this.allSelection.values());
          if (this.allSelection.size === 0) {
            this.$message.warning("请至少选择一个边坡");
            return;
          }
          // 构造提交参数
          const params = {
            ...this.currentForm,
            sideSlopeDetailList: selectedItems.map(item => ({
              sideSlopeUniqueCode: item.sideSlopeUniqueCode,
              evaluateLevel: item.evaluateLevel,
              evaluateDate: item.evaluateDate || undefined
            })),
          };
          // 根据模式选择操作
          const action = this.dialogMode === "create"
            ? addPeriodicInspection
            : modifyPeriodicInspection;
          // 执行操作
          try {
            const success = await action(params);
            if (success) {
              this.$message.success(
                this.dialogMode === "create" ? "新建成功" : "修改成功"
              );
              this.$refs.scrollTable.clearSelection();
              this.$emit("success");
              this.dialogVisible = false;
            } else {
              this.$message.error("操作失败");
            }
          } catch (error) {
            this.$message.error(error.message || "操作失败");
          }
        }
      });
    }
  },
};
</script>
<style lang="scss" scoped>
/* 修复1:弹性容器最小高度约束 */
:deep(.fixed-height-dialog),
.formBorder2,
.formBorder2 .el-container,
.formBorder2 .el-main {
  min-height: 0 !important;
}
/* 表格行高优化 */
:deep(.el-table) {
  .el-table__row {
    height: 36px !important;
    td {
      padding: 4px 0 !important;
    }
  }
  .el-table__header {
    th {
      padding: 4px 0 !important;
      .cell {
        line-height: 28px !important;
      }
    }
  }
  /* 确保内部滚动 */
  .el-table__body-wrapper {
    overflow-y: auto !important;
    max-height: calc(100vh - 400px) !important;
  }
}
/* 表单区域固定 */
.formBorder {
  position: relative; ///为伪元素提供定位上下文 
  border: thin dotted black !important;
  padding: 10px !important;
  margin-top: 15px !important;
  flex-shrink: 0 !important;
  height: auto !important;
  overflow: visible !important;
  margin-bottom: 15px !important;
  /* 边框的文字 */
  &::before {
    content: "项目信息";
    position: absolute;
    top: -8px; //调整到更合适的位置
    left: 15px; //向右移动避免遮挡
    background-color: #fff; //背景色需与页面背景一致
    padding: 0 8px;
    font-size: 13px;
    color: #606266;
    z-index: 10; //提高层级确保显示
    font-weight: 500; //加粗文字 
    pointer-events: none; //防止点击穿透
  }
}
.formBorder2 {
  position: relative;
  border: thin dotted black;
  padding: 10px;
  flex: 1;
  min-height: 0;
  overflow: hidden; // 保留
  display: flex;
  flex-direction: column;
  margin-top: 15px;
  &::before {
    content: "待检边坡";
    position: absolute;
    top: -8px; //调整到更合适的位置
    left: 15px; //向右移动避免遮挡
    background-color: #fff; //背景色需与页面背景一致
    padding: 0 8px;
    font-size: 13px;
    color: #606266;
    z-index: 10; //提高层级确保显示
    font-weight: 500; //加粗文字 
    pointer-events: none; //防止点击穿透
  }
  .el-container {
    height: auto !important; // 覆盖行内样式
    flex: 1; // 填满剩余空间
    display: flex;
    flex-direction: column;
    min-height: 0;
    .el-header {
      flex-shrink: 0;
      height: auto !important;
      padding-bottom: 10px;
    }
    .el-main {
      flex: 1;
      overflow: hidden;
      position: relative;
      padding: 0;
    }
    .el-footer {
      flex-shrink: 0;
      padding-top: 10px;
    }
  }
}
// 弹窗底部按钮区域
.dialog-footer {
  padding: 10px 20px;
  border-top: 1px solid #ebeef5;
  text-align: center;
}
// 搜索区域样式
.searchDialog {
  margin-top: 5px;
}
// 空数据样式
:deep(.el-table__empty-block) {
  min-height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
}
// 分页样式
:deep(.el-pagination) {
  padding: 5px 0;
}
// 表格高度控制
:deep(.el-table) {
  height: 100% !important;
  .el-table__body-wrapper {
    overflow-y: auto !important;
  }
}
</style>为什么待检边坡有一半被margin-top遮住了
					最新发布