<!--
 * @Author: Devin
 * @Date: 2021-07-29 11:57:53
 * @LastEditTime: 2021-07-30 17:05:49
 * @LastEditors: Devin
 * @Description: 系统参数管理页面
 * email: das.devin@outlook.com
-->
<template>
  <div class="apaas-custom-model-detail custom-page">
    <div class="page-header">
      <div class="header-left">
        <el-button
          type="text"
          icon="el-icon-arrow-left"
          class="back-button"
          @click.stop="handleBack"
        >
        </el-button>
        <div class="header-item">
          <span class="label">{{ isApprovalMode ? '发起审批' : '模板名称' }}:</span>
          <span v-if="!isApprovalMode" class="value top-value">{{
            isApprovalMode ? '系统参数模板' : displayTemplateName || '系统参数'
          }}</span>
        </div>
        <div v-if="!isApprovalMode" class="header-item version-select-item">
          <span class="label">版本:</span>
          <el-select
            v-model="internalTemplateVersion"
            placeholder="请选择版本"
            class="version-select"
            @change="handleVersionChange"
          >
            <el-option
              v-for="version in versionOptions"
              :key="getVersionKey(version)"
              :label="'V' + getVersionName(version)"
              :value="getVersionName(version)"
            />
          </el-select>
        </div>
      </div>
      <div class="header-right">
        <template v-if="!isMaintainMode && !isApprovalMode">
          <el-button v-if="shouldShowButtons" class="right-button" @click="handleImport">
            导入
          </el-button>
          <el-button v-if="hasTemplateManagementPermission()" class="right-button" @click="handleDownloadTemplate">
            下载导入模板
          </el-button>
          <el-button
            v-if="shouldShowButtons"
            class="right-button"
            @click="handleMaintainParams"
          >
            维护参数
          </el-button>
          <el-button
            v-if="shouldShowButtonsNew && !fromTodo "
            class="right-button-primary"
            type="primary"
            @click="handleInitiateApproval"
          >
            发起审批
          </el-button>
          <el-button
            v-if="shouldShowButtonsNew && fromTodo "
            class="right-button-primary"
            type="primary"
            @click="handleRestartApproval"
          >
            直送
          </el-button>
          <el-button
            v-if="shouldShowButtonsNew && fromTodo "
            class="right-button-primary"
            type="primary"
            @click="handleResendApproval"
          >
            发起
          </el-button>
        </template>
        <template v-else-if="isMaintainMode">
          <el-button
            :disabled="selectedRows.length === 0"
            class="right-button"
            @click="handleBatchDelete"
          >
            批量删除
          </el-button>
          <el-button
            :disabled="selectedRows.length === 0"
            class="right-button"
            @click="handleBatchModifyDepartment"
          >
            批量修改部门
          </el-button>
          <el-button class="right-button-primary" type="primary" @click="handleAddParam">
            新增参数
          </el-button>
        </template>
      </div>
    </div>

    <div v-if="!isMaintainMode && !isApprovalMode" class="page-search-panel">
      <div class="search-fields">
        <div class="search-row">
          <div class="search-field">
            <span class="field-label">类型</span>
            <el-input v-model="searchPanelValue.parameterType" placeholder="请输入" />
          </div>
          <div class="search-field">
            <span class="field-label">零部件名称</span>
            <el-input v-model="searchPanelValue.partsName" placeholder="请输入" />
          </div>
          <div class="search-field">
            <span class="field-label">参数名称</span>
            <el-input v-model="searchPanelValue.parameterName" placeholder="请输入" />
          </div>
          <div class="search-actions">
            <el-button type="primary" @click="handleSearch">
              查询
            </el-button>
            <el-button @click="resetSearch">
              重置
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <div v-if="!isApprovalMode" class="page-data-list" :class="{ 'has-footer': isMaintainMode }">
      <el-table
        ref="vxeTable"
        :key="'table-' + isMaintainMode"
        :data="tableData"
        border
        :row-class-name="getRowClassName"
        :row-key="getRowKey"
        :max-height="tableMaxHeight"
        class="block-table search-table"
        @row-click="rowClickEvent"
        @selection-change="selectDataChange"
      >
        <!-- 选择列（仅在维护模式下显示） -->
        <el-table-column
          v-if="isMaintainMode"
          type="selection"
          width="55"
          fixed="left"
          :selectable="checkRowMethod"
        />
        <!-- 数据列 -->
        <el-table-column
          v-for="col in tableConfig.colConfigs"
          :key="col.prop"
          :prop="col.prop"
          :label="col.label"
          :width="col.width"
          :min-width="col.minWidth"
          :align="col.align || 'center'"
          :fixed="col.fixed"
          :show-overflow-tooltip="col.showOverflowTooltip"
        >
          <template slot-scope="scope">
            <template v-if="col.customSlot === 'options' && isMaintainMode">
              <div class="operation-links">
                <template v-if="scope.row.operation === 'delete'">
                  <span class="deleted-text">已删除</span>
                </template>
                <template v-else>
                  <template v-if="canEditOrDeleteRow(scope.row)">
                    <a
                      href="javascript:void(0)"
                      class="el-link el-link--primary"
                      @click.stop="handleRowEdit(scope.row)"
                    >
                      修改
                    </a>
                    <span class="link-separator"></span>
                    <a
                      href="javascript:void(0)"
                      class="el-link el-link--primary"
                      @click.stop="handleRowDelete(scope.row, scope.$index)"
                    >
                      删除
                    </a>
                  </template>
                </template>
              </div>
            </template>
            <template v-else-if="col.formatter">
              {{ col.formatter({ cellValue: scope.row[col.prop], row: scope.row, rowIndex: scope.$index }) }}
            </template>
            <template v-else>
              {{ scope.row[col.prop] }}
            </template>
          </template>
        </el-table-column>
        <template slot="empty">
          <div class="table-empty">
            <x-empty-page></x-empty-page>
          </div>
        </template>
      </el-table>
      <!-- 分页（仅在非维护模式下显示） -->
      <el-pagination
        v-if="!isMaintainMode"
        :current-page="pagination.currentPage"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="pagination.pageSize"
        :total="pagination.total"
        layout="total, prev, pager, next, sizes, jumper"
        style="margin-top: 10px; text-align: right;"
        @size-change="pageSizeChange"
        @current-change="currentChange"
      />

      <!-- 审批流程 -->
      <div v-if="!isMaintainMode && !isApprovalMode && detail && detail.flowId" class="approval-progress-section">
        <div class="section-title">
          审批流程
        </div>
        <div v-if="timelineNodes && timelineNodes.length > 0" class="approval-timeline">
          <el-timeline>
            <el-timeline-item
              v-for="(node, index) in timelineNodes"
              :key="index"
              :color="getTimelineColor(node.result || node.status, index, timelineNodes.length)"
            >
              <div class="timeline-item-content">
                <div class="node-title">
                  {{ node.title }}
                </div>
                <div class="node-content">
                  <div class="node-info">
                    <div class="node-user">
                      {{ node.userName || '--' }}
                      <span class="node-time">
                        {{ formatTime(node.operateTime) }}
                      </span>
                    </div>
                  </div>
                  <div class="node-status" :class="getStatusClass(node.result || node.status)">
                    {{ setStatusText(node.result || node.status) }}
                  </div>
                  <div v-if="node.opinion" class="node-opinion">
                    审批意见：{{ node.opinion }}
                  </div>
                </div>
              </div>
            </el-timeline-item>
          </el-timeline>
        </div>
        <div v-else class="empty-progress">
          <span class="empty-text">暂无审批流程数据</span>
        </div>
      </div>
    </div>

    <!-- 审批内容区域 -->
    <div
      v-if="isApprovalMode"
      class="page-approval-content"
      :class="{ 'has-footer': isApprovalMode }"
    >
      <div class="approval-content">
        <!-- 流程主题 -->
        <div class="approval-process-title">
          <div class="description-label">
            流程主题 <span class="required-mark">*</span>
          </div>
          <el-input
            v-model="approvalFormData.processTitle"
            maxlength="100"
            show-word-limit
            placeholder="请输入流程主题"
          />
        </div>

        <!-- 参数表格 -->
        <div class="approval-table-section">
          <el-table
            :data="tableData"
            border
            :max-height="approvalTableMaxHeight"
            class="approval-table"
          >
            <el-table-column
              v-for="col in approvalTableConfig.colConfigs"
              :key="col.prop"
              :prop="col.prop"
              :label="col.label"
              :width="col.width"
              :min-width="col.minWidth"
              :align="col.align || 'center'"
              :show-overflow-tooltip="col.showOverflowTooltip"
            >
              <template slot-scope="scope">
                <template v-if="col.formatter">
                  {{ col.formatter({ cellValue: scope.row[col.prop], row: scope.row, rowIndex: scope.$index }) }}
                </template>
                <template v-else>
                  {{ scope.row[col.prop] }}
                </template>
              </template>
            </el-table-column>
          </el-table>
          <!-- 分页 -->
          <el-pagination
            :current-page="pagination.currentPage"
            :page-sizes="[10, 20, 50, 100]"
            :page-size="pagination.pageSize"
            :total="pagination.total"
            layout="total, prev, pager, next, sizes, jumper"
            style="margin-top: 20px; text-align: right;"
            @size-change="approvalPageSizeChange"
            @current-change="approvalCurrentPageChange"
          />
        </div>

        <!-- 说明 -->
        <div class="approval-description">
          <div class="description-label">
            说明
          </div>
          <el-input
            v-model="approvalFormData.description"
            type="textarea"
            :rows="2"
            placeholder="请输入"
          />
        </div>

        <!-- 审批环节 -->
        <div class="approval-workflow">
          <div class="workflow-title">
            审批环节
          </div>
          <div class="workflow-table">
            <table class="workflow-table-content">
              <thead>
                <tr>
                  <th class="step-name-col">
                    环节名称
                  </th>
                  <th class="handler-col">
                    处理人
                  </th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="(step, index) in approvalWorkflowSteps"
                  :key="index"
                  class="workflow-row"
                >
                  <td class="step-name-cell">
                    <span class="step-name">
                      {{ step.name }}
                      <span v-if="step.required" class="required-mark">*</span>
                    </span>
                  </td>
                  <td class="handler-cell">
                    <el-select
                      v-model="step.handlers"
                      multiple
                      filterable
                      remote
                      placeholder="请选择"
                      :remote-method="(query) => handleRemoteSearch(query, index)"
                      :loading="step.loading"
                      class="handler-select"
                      @change="(value) => handleHandlerChange(index, value)"
                    >
                      <el-option
                        v-for="person in step.options"
                        :key="person.userId || person.userNumber"
                        :value="person.userId"
                        :label="person.username"
                      >
                        <span class="username-text">{{ person.username }}</span>
                        <span class="user-id-text">{{ person.userNumber }}</span>
                      </el-option>
                    </el-select>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <!-- 底部操作按钮 -->
    <div v-if="isMaintainMode" class="page-footer">
      <div class="footer-buttons">
        <el-button @click="handleBackFromMaintain">
          返回
        </el-button>
        <!-- <el-button @click="handleReset">
          重置
        </el-button> -->
        <el-button type="primary"  @click="handleSubmit">
          保存
        </el-button>
      </div>
    </div>

    <!-- 审批底部操作按钮 -->
    <div v-if="isApprovalMode" class="page-footer">
      <div class="footer-buttons">
        <el-button @click="handleApprovalCancel">
          取消
        </el-button>
        <el-button
          type="primary"
          :loading="approvalSubmitting"
          :disabled="!approvalFormData.processTitle || !approvalFormData.processTitle.trim()"
          @click="handleApprovalFormSubmit"
        >
          确定
        </el-button>
      </div>
    </div>

    <!-- 参数编辑弹窗 -->
    <el-dialog
      :title="paramModalTitle"
      :visible.sync="paramModalVisible"
      width="800px"
      :close-on-click-modal="false"
      append-to-body
      :modal="true"
      :modal-append-to-body="true"
      custom-class="param-edit-dialog"
      @close="handleParamModalClose"
    >
      <el-form ref="paramForm" :model="paramFormData" :rules="paramFormRules" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="子系统:" prop="subsystemName">
              <el-input v-model="paramFormData.subsystemName" placeholder="请输入子系统" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="类型:" prop="parameterType">
              <el-input v-model="paramFormData.parameterType" placeholder="请输入类型" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="零部件名称:" prop="partsName">
              <el-input v-model="paramFormData.partsName" placeholder="请输入零部件名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="参数名称:" prop="parameterName">
              <el-input v-model="paramFormData.parameterName" placeholder="请输入参数名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="paramFormData.unit" placeholder="请输入单位" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="参数计划来源:" prop="parameterSource">
              <el-select v-model="paramFormData.parameterSource" placeholder="请选择参数计划来源">
                <el-option value="公式计算" label="公式计算"></el-option>
                <el-option value="数据平台手工录入" label="数据平台手工录入"></el-option>
                <el-option value="TC分类表" label="TC分类表"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="填写部门:" prop="department">
          <el-input
            v-model="paramFormData.departmentName"
            placeholder="请选择填写部门"
            readonly
            style="width: 100%"
            @click.native="handleOpenDepartmentDialog"
          >
            <i
              slot="suffix"
              class="el-input__icon el-icon-search"
              style="cursor: pointer;"
              @click.stop="handleOpenDepartmentDialog"
            ></i>
          </el-input>
        </el-form-item>

        <el-form-item label="分类编号/公式:" prop="numberOrFormula">
          <el-input
            v-model="paramFormData.numberOrFormula"
            type="textarea"
            :rows="2"
            placeholder="请输入分类编号或公式"
          />
        </el-form-item>
        <el-form-item label="备注:" prop="remarks">
          <el-input
            v-model="paramFormData.remarks"
            type="textarea"
            :rows="2"
            placeholder="请输入备注"
          />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="paramModalVisible = false">
          取消
        </el-button>
        <el-button type="primary" :loading="paramSubmitting" @click="handleParamFormSubmit">
          确定
        </el-button>
      </div>
    </el-dialog>

    <!-- 部门选择弹窗 -->
    <el-dialog
      :title="batchModifyDepartmentMode ? '批量修改部门' : '选择填写部门'"
      :visible.sync="departmentDialogVisible"
      width="500px"
      append-to-body
      custom-class="department-select-dialog"
      @close="handleDepartmentDialogClose"
    >
      <div class="department-dialog-content">
        <el-input
          v-model="departmentSearchText"
          placeholder="请输入部门名称进行搜索"
          clearable
          prefix-icon="el-icon-search"
          class="department-search-input"
        />
        <div class="department-tree-wrapper">
          <el-tree
            ref="departmentTree"
            :data="departmentTreeData"
            :props="{ children: 'children', label: 'name' }"
            node-key="id"
            :filter-node-method="filterDepartmentNode"
            highlight-current
            :current-node-key="currentDepartmentNodeKey"
            :expand-on-click-node="false"
            @node-click="handleDepartmentTreeNodeClick"
          />
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleDepartmentDialogClose">取消</el-button>
        <el-button type="primary" @click="handleConfirmDepartment">确定</el-button>
      </span>
    </el-dialog>

    <!-- 导入弹窗 -->
    <el-dialog
      title="导入参数"
      :visible.sync="importDialogVisible"
      width="400px"
      append-to-body
      @close="handleImportDialogClose"
    >
      <el-upload
        class="import-uploader"
        drag
        :auto-upload="false"
        :limit="1"
        accept=".xls,.xlsx,.csv"
        :file-list="importFileList"
        :on-change="handleImportFileChange"
        :on-remove="handleImportFileRemove"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <div slot="tip" class="el-upload__tip">
          仅支持Excel或CSV模板文件
        </div>
      </el-upload>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleImportDialogClose">取消</el-button>
        <el-button type="primary" :loading="importing" @click="handleImportConfirm">
          开始导入
        </el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import api from '@/api'
import { getUserId } from '@/utils'
export default {
  name: 'ApaasCustomModelDetail',
  props: {
    templateId: {
      type: String,
      default: ''
    },
    templateName: {
      type: String,
      default: ''
    },
    templateVersion: {
      type: String,
      default: ''
    },
    versionList: {
      type: Array,
      default: () => []
    },
    flowId: {
      type: String,
      default: ''
    },
    changeId: {
      type: String,
      default: ''
    },
    detail: {
      type: Object,
      default: () => ({})
    },
    templateManagementPermissions: {
      type: Array,
      default: () => []
    },
    fromTodo: {
      type: Boolean,
      default: false
    }
  },
  data: function() {
    return {
      departmentList: [],
      internalTemplateVersion: '', // 内部版本值，用于 v-model
      internalTemplateId: '',
      internalTemplateName: '',
      internalChangeId: '', // 内部变更ID，用于版本切换
      currentStatus: '', // 当前版本的状态
      searchPanelValue: {
        parameterType: '',
        partsName: '',
        parameterName: ''
      },
      tableData: [],
      originalTableData: [], // 进入维护模式前的原始数据快照
      originalTableDataForApproval: [], // 进入审批模式前的原始数据快照
      originalPaginationForApproval: null, // 进入审批模式前的分页信息快照
      pagination: { currentPage: 1, pageSize: 10, total: 0 },
      isMaintainMode: false, // 维护参数模式状态
      isApprovalMode: false, // 发起审批模式状态
      paramModalVisible: false, // 参数编辑弹窗显示状态
      paramModalMode: 'add', // 'add' 或 'edit'
      paramCurrentRow: null, // 当前编辑的行
      paramCurrentRowIndex: -1,
      paramFormData: {
        subsystemName: '',
        parameterType: '',
        partsName: '',
        parameterName: '',
        department: '',
        departmentName: '', // 部门名称（用于显示）
        departmentId: '', // 部门ID（用于存储）
        parameterSource: '',
        numberOrFormula: '',
        fillDepartment: '',
        remarks: ''
      },
      departmentDialogVisible: false, // 部门选择弹窗显示状态
      departmentTreeData: [], // 部门树数据（用于 el-tree）
      selectedDepartmentNode: null, // 选中的部门节点
      departmentSearchText: '', // 部门搜索文本
      batchModifyDepartmentMode: false, // 是否为批量修改部门模式
      currentDepartmentNodeKey: null, // 当前选中的部门节点 key（用于反显）
      paramSubmitting: false,
      submitting: false, // 提交按钮loading状态
      importing: false,
      importDialogVisible: false,
      importFileList: [],
      selectedImportFile: null,
      approvalFormData: {
        processTitle: '',
        description: ''
      },
      approvalSubmitting: false, // 审批提交loading状态
      resending: false, // 直送提交loading状态
      isResendMode: false, // 是否为重新发起模式
      isResendModeFilled: false, // 重新发起模式且已填充数据（用于控制编辑状态）
      resendApprovalData: null, // 重新发起时保存的审批流程数据
      resendFlowId: null, // 重新发起时的流程ID（从 resendApprovalData 中提取）
      isProcessTitleEditing: false, // 流程主题是否处于编辑状态
      originalProcessTitle: '', // 流程主题原始数据备份
      approvalWorkflowSteps: [
        {
          name: '校对',
          required: true,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false, // 是否处于编辑状态
          originalData: null // 原始数据备份（用于取消编辑时恢复）
        },
        {
          name: '审核',
          required: true,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        },
        {
          name: '会签',
          required: false,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        },
        {
          name: '批准',
          required: true,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        }
      ],
      nextLocalId: 1,
      // 部门级联选择器相关
      departmentCascaderProps: {
        value: 'id',
        label: 'name',
        children: 'children',
        checkStrictly: true, // 允许选择任意一级（单选）
        emitPath: false, // 只返回最后一级的值（单选时只返回选中的id）
        multiple: false // 明确指定为单选
      },
      // 审批流程相关
      flowNodes: [], // 审批流程节点数据
      progressDetail: {}, // 审批流程详情数据
      selectedRows: [] // 选中的行数据（用于批量删除）
    }
  },
  computed: {
    displayTemplateName() {
      return this.templateName || this.internalTemplateName || ''
    },
    versionOptions() {
      // 返回版本列表，如果没有则返回空数组
      return this.versionList || []
    },
    shouldShowButtonsNew() {
      // 首先检查是否有参数模板管理的权限
      if (!this.hasTemplateManagementPermission()) {
        return false
      }
      // 如果是从 todo 进入且有 flowId，显示重新发起按钮
      if (this.fromTodo && this.flowId) {
        return true
      }
      // 根据 GET_MODEL_DETAIL 接口返回的 status 控制发起审批按钮
      const status = this.currentStatus || ''
      return status === 'DRAFT' && this.isLatestVersion
    },
    // 检查是否应该显示按钮（维护参数、导入）
    shouldShowButtons() {
      // 首先检查是否有参数模板管理的权限
      if (!this.hasTemplateManagementPermission()) {
        return false
      }
      // 根据 GET_MODEL_DETAIL 接口返回的 status 控制维护参数和导入按钮
      // 检查状态是否为 DRAFT 或 COMPLETE，且当前版本是最新版本
      const status = this.currentStatus || ''
      return (status === 'DRAFT' || status === 'COMPLETE')
    },
    // 检查是否应该显示维护参数按钮（在 DRAFT 或 COMPLETE 状态下都显示，且当前版本是最新版本）
    shouldShowMaintainButton() {
      // 根据 GET_MODEL_DETAIL 接口返回的 status 控制维护参数按钮
      const status = this.currentStatus || ''
      const baseCondition = (status === 'DRAFT' || status === 'COMPLETE') && this.isLatestVersion
      if (!baseCondition) {
        return false
      }
      // 检查是否有对应子系统的权限
      const templateName = this.displayTemplateName
      if (!templateName || !this.templateManagementPermissions || this.templateManagementPermissions.length === 0) {
        return false
      }
      // 查找是否有匹配的子系统权限
      const hasSubsystemPermission = this.templateManagementPermissions.some((perm) => {
        return perm.subsystem === templateName
      })
      return hasSubsystemPermission
    },
    // 判断当前版本是否是最新版本
    isLatestVersion() {
      if (!this.versionList || this.versionList.length === 0) {
        return false
      }
      const currentVersion = this.internalTemplateVersion || this.templateVersion
      if (!currentVersion) {
        return false
      }
      // 获取所有版本号，转换为数字进行比较
      const versions = this.versionList.map(v => {
        const versionName = this.getVersionName(v)
        // 尝试将版本号转换为数字（例如 "1" -> 1, "2" -> 2）
        const versionNum = parseInt(versionName, 10)
        return {
          version: versionName,
          versionNum: isNaN(versionNum) ? 0 : versionNum,
          original: v
        }
      })
      // 找到版本号最大的版本（最新版本）
      const latestVersion = versions.reduce((max, v) => {
        return v.versionNum > max.versionNum ? v : max
      }, versions[0])
      // 判断当前版本是否是最新版本
      return latestVersion && latestVersion.version === currentVersion
    },
    // 计算表格最大高度
    tableMaxHeight() {
      // 视口高度
      const viewportHeight = window.innerHeight || document.documentElement.clientHeight
      // 头部高度
      const headerHeight = 56
      // 搜索面板高度（如果显示）
      const searchPanelHeight = this.isApprovalMode || this.isMaintainMode ? 0 : 80
      // 分页器高度（如果显示）
      const paginationHeight = this.isMaintainMode ? 0 : 50
      // 底部按钮高度（维护模式下）
      const footerHeight = this.isMaintainMode ? 80 : 0
      // 页面内边距（.page-data-list 的 padding 上下各 20px，共 40px）
      const padding = 40
      // 表格周围的间距（上下各约 10px）
      const tableMargin = 20
      // 计算可用高度
      const availableHeight = viewportHeight - headerHeight - searchPanelHeight - paginationHeight - footerHeight - padding - tableMargin
      // 返回计算后的高度，最小为 400px
      return Math.max(availableHeight, 400)
    },
    // 计算审批模式表格最大高度
    approvalTableMaxHeight() {
      // 视口高度
      const viewportHeight = window.innerHeight || document.documentElement.clientHeight
      // 头部高度
      const headerHeight = 56
      // 说明区域高度（约100px）
      const descriptionHeight = 100
      // 流程主题高度（约60px）
      const processTitleHeight = 60
      // 审批环节表格高度（约200px）
      const workflowHeight = 200
      // 分页器高度
      const paginationHeight = 50
      // 底部按钮高度
      const footerHeight = 80
      // 页面内边距和间距
      const padding = 100
      // 计算可用高度
      const availableHeight = viewportHeight - headerHeight - descriptionHeight - processTitleHeight - workflowHeight - paginationHeight - footerHeight - padding
      // 返回计算后的高度，最小为 300px
      return Math.max(availableHeight, 300)
    },
    tableConfig() {
      const baseColConfigs = []

      // 维护模式下，在第一列添加序号列（第二列显示序号，第一列是选择列）
      if (this.isMaintainMode) {
        // baseColConfigs.push({
        //   prop: '_index',
        //   label: '序号',
        //   width: 60,
        //   align: 'center',
        //   fixed: 'left',
        //   customSlot: 'index',
        //   formatter: ({ rowIndex }) => {
        //     return rowIndex + 1
        //   }
        // })
      }

      // 添加数据列
      baseColConfigs.push(
        {
          prop: 'subsystemName',
          label: '子系统',
          showOverflowTooltip: true,
          minWidth: '120',
          align: 'center'
        },
        {
          prop: 'parameterType',
          label: '类型',
          showOverflowTooltip: true,
          minWidth: '120',
          align: 'center'
        },
        {
          prop: 'partsName',
          label: '零部件名称',
          showOverflowTooltip: true,
          minWidth: '150',
          align: 'center'
        },
        {
          prop: 'parameterName',
          label: '参数名称',
          showOverflowTooltip: true,
          minWidth: '150',
          align: 'center'
        },
        {
          prop: 'unit',
          label: '单位',
          showOverflowTooltip: true,
          width: '100',
          align: 'center'
        },
        {
          prop: 'parameterSource',
          label: '参数计划来源',
          showOverflowTooltip: true,
          minWidth: '150',
          align: 'center'
        },
        // {
        //   prop: 'numberOrFormula',
        //   label: '当前可适用的分类属性表编号(需要修订)或公式',
        //   showOverflowTooltip: true,
        //   minWidth: '300',
        //   align: 'center'
        // },
        {
          prop: 'department',
          label: '填写部门',
          showOverflowTooltip: true,
          minWidth: '120',
          align: 'center',
          formatter: ({ cellValue }) => {
            return this.formatDepartmentDisplay(cellValue)
          }
        },
        {
          prop: 'remarks',
          label: '备注',
          showOverflowTooltip: true,
          minWidth: '100',
          align: 'center'
        }
      )

      // 添加操作列（仅在维护模式下显示）
      if (this.isMaintainMode) {
        baseColConfigs.push({
          prop: 'options',
          label: '操作',
          customSlot: 'options',
          align: 'center',
          width: '120',
          fixed: 'right'
        })
      }

      return {
        colConfigs: baseColConfigs
      }
    },
    paramModalTitle() {
      return this.paramModalMode === 'add' ? '添加参数' : '修改参数'
    },
    paramFormRules() {
      return {
        subsystemName: [{ required: true, message: '请输入子系统', trigger: 'blur' }],
        parameterType: [{ required: true, message: '请输入类型', trigger: 'blur' }],
        parameterName: [{ required: true, message: '请输入参数名称', trigger: 'blur' }]
      }
    },
    approvalTableConfig() {
      return {
        colConfigs: [
          {
            prop: 'subsystemName',
            label: '子系统',
            showOverflowTooltip: true,
            minWidth: '120',
            align: 'center'
          },
          {
            prop: 'parameterType',
            label: '类型',
            showOverflowTooltip: true,
            minWidth: '120',
            align: 'center'
          },
          {
            prop: 'partsName',
            label: '零部件名称',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          },
          {
            prop: 'parameterName',
            label: '参数名称',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          },
          {
            prop: 'unit',
            label: '单位',
            showOverflowTooltip: true,
            width: '100',
            align: 'center'
          },
          {
            prop: 'parameterSource',
            label: '参数计划来源',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          },
          // {
          //   prop: 'numberOrFormula',
          //   label: '当前可适用的分类属性表编号(需要修订)或公式',
          //   showOverflowTooltip: true,
          //   minWidth: '300',
          //   align: 'center'
          // },
          {
            prop: 'department',
            label: '填写部门',
            showOverflowTooltip: true,
            minWidth: '120',
            align: 'center',
            formatter: ({ cellValue }) => {
              return this.formatDepartmentDisplay(cellValue)
            }
          },
          {
            prop: 'remarks',
            label: '备注',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          },
          {
            prop: 'modifyDetails',
            label: '变动说明',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          }
        ]
      }
    },
    approvalFormRules() {
      return {
        name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
        model: [{ required: true, message: '请输入型号', trigger: 'blur' }],
        value: [{ required: true, message: '请输入数值', trigger: 'blur' }]
      }
    },
    // 发起审批节点
    initiateNode() {
      if (!this.detail || !this.detail.createBy) {
        return null
      }
      return {
        userName: this.detail.createBy,
        createTime: this.detail.createdTime || this.detail.createTime,
        status: 'INITIATE',
        result: 'INITIATE'
      }
    },
    // 审批流程时间线节点（完全按照 approvalProgressDetail.vue 的逻辑）
    timelineNodes() {
      const nodes = []
      // 使用 flowNodes 数据构建审批流程节点
      if (this.flowNodes && this.flowNodes.length > 0) {
        // 按照接口返回的顺序，不进行排序
        const processedNodes = [...this.flowNodes]

        // 找到第一个"待审批"节点，将其改为"审批中"（跟是否有REJECT没关系）
        const stayIndex = processedNodes.findIndex((node) => node.result === '待审批')
        if (stayIndex !== -1) {
          processedNodes[stayIndex] = {
            ...processedNodes[stayIndex],
            result: 'APPROVING'
          }
        }

        // 转换为时间线节点格式
        processedNodes.forEach((node) => {
          let result = 'APPROVING'
          let status = 'APPROVING'

          if (node.result) {
            if (node.result === 'MSG') {
              result = 'PASS'
              status = 'PASS'
            } else if (node.result === 'REJECT') {
              result = 'REJECT'
              status = 'REJECT'
            } else if (node.result === 'RETURN') {
              result = 'RETURN'
              status = 'RETURN'
            } else if (node.result === 'APPROVING') {
              result = 'APPROVING'
              status = 'APPROVING'
            } else if (node.result === 'PASS') {
              result = 'PASS'
              status = 'PASS'
            } else if (node.result === '待审批') {
              result = '待审批'
              status = '待审批'
            }
          }

          // 处理审批意见：如果有 opinions 数组，取第一个；否则为空
          const opinion = node.opinions && Array.isArray(node.opinions) && node.opinions.length > 0
            ? node.opinions[0]
            : null

          // 处理用户名：优先使用 todoUserName（已处理人），如果没有则使用 undoUserName（待处理人）
          const userName = node.todoUserName || node.undoUserName || '--'

          nodes.push({
            title: node.node || '审批节点',
            userName: userName,
            operateTime: node.approvalTime || '',
            result: result,
            status: status,
            opinion: opinion
          })
        })
      } else if (this.progress && this.progress.length > 0) {
        // 兼容旧逻辑：如果没有 flowNodes，则使用原来的 progress 数据
        this.progress.forEach((stage) => {
          if (stage.steps && stage.steps.length > 0) {
            stage.steps.forEach((step) => {
              nodes.push({
                title: stage.title || '审批节点',
                userName: step.userName,
                operateTime: step.approvalTime || step.handleTime || step.createTime,
                result: step.result || step.status,
                status: step.result || step.status,
                opinion: step.opinion || step.remark || step.comment || null
              })
            })
          }
        })
      }

      return nodes
    }
  },
  watch: {
    departmentSearchText(val) {
      if (this.$refs.departmentTree) {
        this.$refs.departmentTree.filter(val)
        // 如果有搜索文本，展开所有节点
        if (val && val.trim() !== '') {
          this.$nextTick(() => {
            // 获取所有节点的 key 并展开
            const allKeys = this.getAllDepartmentNodeKeys(this.departmentTreeData)
            if (this.$refs.departmentTree && allKeys.length > 0) {
              // 使用 setExpandedKeys 方法展开所有节点
              try {
                this.$refs.departmentTree.setExpandedKeys(allKeys)
              } catch (err) {
                // 如果 setExpandedKeys 不存在，使用递归方式展开
                this.expandAllNodesRecursive(this.departmentTreeData)
              }
            }
          })
        } else {
          // 清空搜索时，收起所有节点
          if (this.$refs.departmentTree) {
            try {
              this.$refs.departmentTree.setExpandedKeys([])
            } catch (err) {
              // 忽略错误
            }
          }
        }
      }
    },
    templateId: {
      handler(newId) {
        if (newId) {
          this.internalTemplateId = newId
          this.loadTemplateInfo()
        }
      },
      immediate: true
    },
    templateName: {
      handler(newName) {
        if (newName) {
          this.internalTemplateName = newName
        }
      },
      immediate: true
    },
    '$route.query.id': {
      handler(newId) {
        // 兼容路由方式，如果通过 props 传入则不使用路由
        if (newId && !this.templateId) {
          this.internalTemplateId = newId
          this.loadTemplateInfo()
        }
      },
      immediate: true
    },
    '$route.query.name': {
      handler(newName) {
        // 兼容路由方式，如果通过 props 传入则不使用路由
        if (newName && !this.templateName) {
          this.internalTemplateName = newName
        }
      },
      immediate: true
    },
    templateVersion: {
      handler(newVersion) {
        // 如果传入了版本，使用传入的版本；否则使用最新版本
        if (newVersion) {
          this.internalTemplateVersion = newVersion
        } else {
          // 如果没有传入版本，尝试从模板信息中获取最新版本，或使用默认值
          this.loadLatestVersion()
        }
      },
      immediate: true
    },
    changeId: {
      handler(newChangeId) {
        // 如果传入了 changeId，初始化内部 changeId
        if (newChangeId) {
          this.internalChangeId = newChangeId
        }
      },
      immediate: true
    },
    versionList: {
      handler(newList) {
        // 当版本列表更新时，如果当前版本不在列表中，则选择第一个版本
        if (newList && newList.length > 0) {
          const currentVersion = this.internalTemplateVersion || this.templateVersion
          const versionExists = newList.some((v) => this.getVersionName(v) === currentVersion)
          if (!versionExists) {
            // 如果当前版本不在列表中，优先使用传入的 templateVersion，否则选择第一个版本
            if (
              this.templateVersion &&
              newList.some((v) => this.getVersionName(v) === this.templateVersion)
            ) {
              this.internalTemplateVersion = this.templateVersion
            } else {
              // 如果没有当前版本或当前版本不在列表中，选择第一个版本
              this.internalTemplateVersion = this.getVersionName(newList[0])
            }
            // 更新当前版本的状态
            this.updateCurrentStatus()
            // 重新加载数据
            this.$nextTick(() => {
              this.loadData()
            })
          } else {
            // 如果当前版本在列表中，更新状态和 changeId
            this.updateCurrentStatus()
            // 同步更新 changeId
            const currentVersionItem = newList.find((v) => this.getVersionName(v) === currentVersion)
            if (currentVersionItem && currentVersionItem.id) {
              this.internalChangeId = currentVersionItem.id
            }
          }
        }
      },
      immediate: true
    },
    detail: {
      handler(newDetail) {
        // 当 detail prop 更新时，更新当前状态
        if (newDetail && newDetail.status) {
          this.currentStatus = newDetail.status
        } else {
          // 如果 detail 中没有状态，从 versionList 中获取
          this.updateCurrentStatus()
        }
        // 如果 detail 中有 changeId，更新内部 changeId
        if (newDetail && newDetail.changeId && !this.internalChangeId) {
          this.internalChangeId = newDetail.changeId
        }
        // 如果有 flowId，获取审批流程数据
        if (newDetail && newDetail.flowId) {
          this.$nextTick(() => {
            this.getApprovalSpet()
          })
        }
      },
      immediate: true,
      deep: true
    }
  },
  created() {
     this.loadUserSelfRole()
    // 优先使用 props，如果没有则使用路由参数
    if (this.templateId) {
      this.internalTemplateId = this.templateId
      this.loadTemplateInfo()
    } else if (this.$route.query.id) {
      this.internalTemplateId = this.$route.query.id
      this.loadTemplateInfo()
    }
    if (this.templateName) {
      this.internalTemplateName = this.templateName
    } else if (this.$route.query.name) {
      this.internalTemplateName = this.$route.query.name
    }
    // 初始化 changeId
    if (this.changeId) {
      this.internalChangeId = this.changeId
    } else if (this.detail && this.detail.changeId) {
      this.internalChangeId = this.detail.changeId
    }
    // 初始化版本信息
    if (this.templateVersion) {
      this.internalTemplateVersion = this.templateVersion
      // 根据当前版本设置 changeId
      if (this.versionList && this.versionList.length > 0) {
        const versionItem = this.versionList.find((v) => this.getVersionName(v) === this.templateVersion)
        if (versionItem && versionItem.id) {
          this.internalChangeId = versionItem.id
        }
      }
    } else {
      this.loadLatestVersion()
    }
    // 初始化当前版本的状态
    this.updateCurrentStatus()
    this.loadData()
  },
  mounted() {
    this.loadDepartmentList()
    // 如果有 flowId，获取审批流程数据
    if (this.detail && this.detail.flowId) {
      this.getApprovalSpet()
    }
  },
  methods: {
    // 加载用户自身角色权限
    loadUserSelfRole() {
      const request = {
        ...api.GET_USER_SELF_ROLE,
        params: {
          userOrDepID: getUserId()
        },
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          if (resp && resp.data) {
            // 将权限数据存储到 localStorage
            try {
              localStorage.setItem('user_self_role', JSON.stringify(resp.data))
            } catch (err) {
              console.error('存储权限数据到 localStorage 失败:', err)
            }
          }
        })
        .asyncErrorCatch((err) => {
          console.error('获取用户自身角色失败:', err)
        })
    },
    // 检查权限
    // menuPath: 模块路径，如 "数据录入/模板管理"
    // subsystem: 子系统名称（可选，如果提供则检查该子系统的权限）
    // permissionType: 权限类型，"查看" 或 "编辑"
    checkPermission(menuPath, subsystem = null, permissionType = '查看') {
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }

        // 查找匹配的权限
        const matchedPermissions = permissionData.filter((perm) => {
          // 检查 menuPath 是否匹配（支持包含关系）
          const menuMatch =
            perm.menuPath &&
            menuPath &&
            (perm.menuPath.includes(menuPath) || menuPath.includes(perm.menuPath))
          if (!menuMatch) {
            return false
          }

          // 如果提供了 subsystem，检查是否匹配
          if (subsystem) {
            if (perm.subsystem !== subsystem) {
              return false
            }
          }

          // 检查权限类型是否匹配
          return perm.parameterPer === permissionType
        })

        return matchedPermissions.length > 0
      } catch (err) {
        console.error('检查权限失败:', err)
        return false
      }
    },
    handleResendApproval() {
      // 重新发起：先进入审批模式（和发起审批一样），然后获取之前保存的审批流程信息
      // 保存当前表格数据和分页信息（用于退出审批时还原）
      this.originalTableDataForApproval = JSON.parse(JSON.stringify(this.tableData))
      this.originalPaginationForApproval = JSON.parse(JSON.stringify(this.pagination))

      // 校验 changeId
      const changeId = this.getChangeId()
      if (!changeId) {
        this.$message.error('缺少变更ID，无法重新发起审批')
        return
      }

      // 设置重新发起模式标志
      this.isResendMode = true

      // 先调用 GET_RETURN_APPROVAL 获取之前保存的审批流程信息
      const request = {
        ...api.GET_RETURN_APPROVAL,
        params: {
          templateId: changeId
        },
        disableSuccessMsg: true
      }

      this.$request(request)
        .asyncThen((resp) => {
          console.log('获取审批流程信息:', resp)
          // 保存整个响应对象，fillResendApprovalData 会从中提取节点列表、流程主题和说明
          this.resendApprovalData = resp
          // 调用 getApprovalChange 进入审批模式（在获取审批流程信息成功后）
          this.getApprovalChange()
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批流程信息失败:', err)
          // 如果获取失败，仍然调用 getApprovalChange 进入审批模式，但不填充人员信息
          this.isResendMode = false
          this.resendApprovalData = null
          this.getApprovalChange()
          this.$message.warning('获取原审批流程信息失败，将使用空的人员列表')
        })
    },
    // 检查是否有查看权限（用于模板管理页面，根据templateName匹配subsystem）
    hasViewPermission(subsystem = null) {
      // 如果没有提供subsystem，使用templateName
      const checkSubsystem = subsystem || this.displayTemplateName
      return this.checkPermission('模板管理', checkSubsystem, '查看')
    },
    // 检查是否有编辑权限（用于模板管理页面，根据templateName匹配subsystem）
    hasEditPermission(subsystem = null) {
      // 如果没有提供subsystem，使用templateName
      const checkSubsystem = subsystem || this.displayTemplateName
      return this.checkPermission('模板管理', checkSubsystem, '编辑')
    },
    // 检查是否是管理员（isAdmin === 1）
    isAdmin() {
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }
        // 检查是否有 isAdmin === 1 的记录
        return permissionData.some((perm) => perm.isAdmin === 1 || perm.isAdmin === '1')
      } catch (err) {
        console.error('检查管理员权限失败:', err)
        return false
      }
    },
    // 检查是否有全局编辑权限（permissionPath 是"参数模板管理"且 parameterPer 是"编辑"）
    hasGlobalEditPermission() {
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }
        // 检查是否有 permissionPath 为 "参数模板管理" 且 parameterPer 为 "编辑" 的权限
        return permissionData.some((perm) => {
          const permissionPath = perm.permissionPath || ''
          const parameterPer = perm.parameterPer || ''
          // 检查 permissionPath 是否等于 "参数模板管理"（不包含模板名称）
          return permissionPath === '参数模板管理' && parameterPer === '编辑'
        })
      } catch (err) {
        console.error('检查全局编辑权限失败:', err)
        return false
      }
    },
    // 检查是否有参数模板管理的权限（根据 permissionPath: "参数模板管理/模板名称"）
    hasTemplateManagementPermission() {
      // 如果是管理员，拥有全部权限
      if (this.isAdmin()) {
        return true
      }
      // 如果有全局编辑权限，拥有全部权限
      if (this.hasGlobalEditPermission()) {
        return true
      }
      const templateName = this.displayTemplateName
      if (!templateName) {
        return false
      }
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }
        // 检查是否有 permissionPath 为 "参数模板管理/模板名称" 的权限
        const expectedPath = `参数模板管理/${templateName}`
        return permissionData.some((perm) => {
          const permissionPath = perm.permissionPath || ''
          return permissionPath === expectedPath
        })
      } catch (err) {
        console.error('检查参数模板管理权限失败:', err)
        return false
      }
    },
    // 检查参数是否有编辑权限（根据subsystem和partsName匹配）
    hasParameterEditPermission(subsystem, partsName) {
      // 如果是管理员，拥有全部权限
      if (this.isAdmin()) {
        return true
      }
      // 如果有全局编辑权限，拥有全部权限
      if (this.hasGlobalEditPermission()) {
        return true
      }
      if (!subsystem || !partsName) {
        return false
      }
      // 优先使用传入的权限数组
      if (this.templateManagementPermissions && this.templateManagementPermissions.length > 0) {
        const matchedPermissions = this.templateManagementPermissions.filter((perm) => {
          // 检查 subsystem 是否匹配
          if (perm.subsystem !== subsystem) {
            return false
          }

          // 检查 partsName 是否匹配
          if (perm.partsName !== partsName) {
            return false
          }

          // 检查权限类型是否为"编辑"
          return perm.parameterPer === '编辑'
        })

        return matchedPermissions.length > 0
      }
      // 如果没有传入权限数组，从 localStorage 读取 user_self_role
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }

        // 查找匹配的权限：subsystem匹配，partsName匹配，且parameterPer为"编辑"
        const matchedPermissions = permissionData.filter((perm) => {
          // 如果 menuPath 存在，检查是否包含"模板管理"（可选检查）
          if (perm.menuPath && perm.menuPath.trim() !== '' && !perm.menuPath.includes('模板管理')) {
            return false
          }

          // 检查 subsystem 是否匹配
          if (!perm.subsystem || perm.subsystem !== subsystem) {
            return false
          }

          // 检查 partsName 是否匹配
          if (!perm.partsName || perm.partsName !== partsName) {
            return false
          }

          // 检查权限类型是否为"编辑"
          return perm.parameterPer === '编辑'
        })

        return matchedPermissions.length > 0
      } catch (err) {
        console.error('检查参数权限失败:', err)
        return false
      }
    },
    // 检查是否可以编辑或删除某一行
    canEditOrDeleteRow(row) {
      if (!row) {
        return false
      }
      // 如果是管理员，拥有全部权限，可以直接编辑/删除
      if (this.isAdmin()) {
        return true
      }
      // 如果有全局编辑权限，拥有全部权限，可以直接编辑/删除
      if (this.hasGlobalEditPermission()) {
        return true
      }
      // 如果该行的 createdBy 等于当前用户ID，可以编辑/删除
      if (row.createdBy === getUserId()) {
        return true
      }
      // 根据子系统和零部件名称检查是否有编辑权限
      const subsystem = row.subsystemName || row.subsystem || ''
      const partsName = row.partsName || ''
      if (subsystem && partsName && this.hasParameterEditPermission(subsystem, partsName)) {
        return true
      }
      return false
    },
    loadDepartmentList() {
      const request = {
        ...api.GET_DEPT_OF_USER,
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          // 处理返回的数据，确保格式为 { id, name, children }
          console.log('resp2222', resp)
          let result = []
          if (resp && resp.data) {
            result = resp.data || []
          }
          // 格式化数据为级联选择器需要的格式
          this.departmentList = this.formatDepartmentTreeData(result)
          // 同时生成树形数据（用于 el-tree）
          this.departmentTreeData = this.formatDepartmentTreeData(result)
        })
        .asyncErrorCatch((err) => {
          console.error('加载部门列表失败:', err)
          this.departmentList = []
          this.departmentTreeData = []
        })
    },
    // 格式化部门树数据为级联选择器格式
    formatDepartmentTreeData(data) {
      if (!Array.isArray(data)) {
        return []
      }

      // 递归格式化数据，确保每个节点都有 id 和 name 字段
      const formatNode = (node) => {
        const formatted = {
          id: node.id,
          name: node.name || node.label || '',
          children: undefined
        }

        // 如果有子节点，递归格式化
        if (node.children && Array.isArray(node.children) && node.children.length > 0) {
          formatted.children = node.children.map((child) => formatNode(child))
        }

        return formatted
      }

      return data.map((node) => formatNode(node))
    },
    // 打开部门选择弹窗
    handleOpenDepartmentDialog() {
      this.batchModifyDepartmentMode = false
      this.departmentDialogVisible = true
      this.departmentSearchText = '' // 重置搜索文本
      this.selectedDepartmentNode = null // 重置选中的节点
      // 如果已有选中的部门，在树中高亮显示
      if (this.paramFormData.departmentId) {
        this.currentDepartmentNodeKey = this.paramFormData.departmentId
        // 查找对应的节点数据
        this.$nextTick(() => {
          const node = this.findDepartmentNodeById(this.departmentTreeData, this.paramFormData.departmentId)
          if (node) {
            this.selectedDepartmentNode = node
          }
          // 设置当前选中的节点
          if (this.$refs.departmentTree) {
            try {
              this.$refs.departmentTree.setCurrentKey(this.paramFormData.departmentId)
            } catch (err) {
              console.warn('设置当前节点失败:', err)
            }
          }
        })
      } else {
        this.currentDepartmentNodeKey = null
      }
    },
    // 关闭部门选择弹窗
    handleDepartmentDialogClose() {
      this.departmentDialogVisible = false
      this.selectedDepartmentNode = null
      this.departmentSearchText = '' // 清空搜索文本
      this.batchModifyDepartmentMode = false // 重置批量修改模式
      this.currentDepartmentNodeKey = null // 清空当前选中的节点 key
    },
    // 过滤部门树节点
    filterDepartmentNode(value, data) {
      if (!value) return true
      return (data.name || '').toLowerCase().includes(value.toLowerCase())
    },
    // 递归获取所有部门节点的 key
    getAllDepartmentNodeKeys(nodes) {
      let keys = []
      if (!Array.isArray(nodes)) {
        return keys
      }
      nodes.forEach(node => {
        if (node.id) {
          keys.push(node.id)
        }
        if (node.children && Array.isArray(node.children) && node.children.length > 0) {
          keys = keys.concat(this.getAllDepartmentNodeKeys(node.children))
        }
      })
      return keys
    },
    // 递归展开所有节点（备用方法）
    expandAllNodesRecursive(nodes) {
      if (!Array.isArray(nodes) || !this.$refs.departmentTree) {
        return
      }
      nodes.forEach(node => {
        if (node.id) {
          try {
            this.$refs.departmentTree.store.setExpanded(node.id, true)
          } catch (err) {
            // 忽略错误
          }
        }
        if (node.children && Array.isArray(node.children) && node.children.length > 0) {
          this.expandAllNodesRecursive(node.children)
        }
      })
    },
    // 根据 ID 查找部门节点
    findDepartmentNodeById(nodes, targetId) {
      if (!Array.isArray(nodes) || !targetId) {
        return null
      }
      for (const node of nodes) {
        if (node.id === targetId) {
          return node
        }
        if (node.children && Array.isArray(node.children) && node.children.length > 0) {
          const found = this.findDepartmentNodeById(node.children, targetId)
          if (found) {
            return found
          }
        }
      }
      return null
    },
    // 处理树节点点击
    handleDepartmentTreeNodeClick(data) {
      console.log('节点被点击:', data)
      this.selectedDepartmentNode = data
      this.currentDepartmentNodeKey = data.id || null
    },
    // 统一处理确定按钮点击
    handleConfirmDepartment() {
      console.log('handleConfirmDepartment 被调用, batchModifyDepartmentMode:', this.batchModifyDepartmentMode)
      if (this.batchModifyDepartmentMode) {
        this.handleConfirmBatchModifyDepartment()
      } else {
        this.handleConfirmDepartmentSelect()
      }
    },
    // 确认选择部门
    handleConfirmDepartmentSelect() {
      console.log('handleConfirmDepartmentSelect')
      // 如果没有选中的节点，尝试从 el-tree 获取当前选中的节点
      if (!this.selectedDepartmentNode && this.$refs.departmentTree) {
        try {
          const currentKey = this.$refs.departmentTree.getCurrentKey()
          if (currentKey) {
            const node = this.findDepartmentNodeById(this.departmentTreeData, currentKey)
            if (node) {
              this.selectedDepartmentNode = node
            }
          }
        } catch (err) {
          console.warn('获取当前选中节点失败:', err)
        }
      }
      if (!this.selectedDepartmentNode) {
        this.$message.warning('请选择一个部门')
        return
      }
      // 获取部门路径名称
      const departmentPath = this.getDepartmentPathName(this.selectedDepartmentNode.id)
      // 设置部门信息
      this.paramFormData.departmentId = this.selectedDepartmentNode.id
      this.paramFormData.departmentName = departmentPath || this.selectedDepartmentNode.name
      this.paramFormData.department = departmentPath || this.selectedDepartmentNode.name
      // 关闭弹窗
      this.handleDepartmentDialogClose()
    },
    // 获取部门路径名称（从根到当前节点的完整路径）
    getDepartmentPathName(departmentId) {
      if (!departmentId || !this.departmentList || this.departmentList.length === 0) {
        return ''
      }
      // 递归查找部门路径
      const findPath = (nodes, targetId, path = []) => {
        for (const node of nodes) {
          const currentPath = [...path, node.name]
          if (node.id === targetId) {
            return currentPath.join('-')
          }
          if (node.children && node.children.length > 0) {
            const result = findPath(node.children, targetId, currentPath)
            if (result) {
              return result
            }
          }
        }
        return null
      }
      return findPath(this.departmentList, departmentId) || ''
    },
    // 格式化部门显示：只显示最后一个节点
    formatDepartmentDisplay(department) {
      if (!department) {
        return '平台部'
      }
      // 将 · 替换为 -
      const normalizedDept = department.replace(/·/g, '-')
      // 按 - 分割
      const parts = normalizedDept.split('-').filter(part => part.trim() !== '')
      // 只显示最后一个节点
      if (parts.length > 0) {
        return parts[parts.length - 1]
      }
      // 否则显示全部
      return normalizedDept
    },
    handleBack() {
      // 如果在审批模式下，取消审批而不是返回
      if (this.isApprovalMode) {
        this.handleApprovalCancel()
        return
      }
      // 如果在维护模式下，执行结束维护参数功能
      if (this.isMaintainMode) {
        this.$confirm('确定要返回吗？未保存的修改将丢失。', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            // 退出维护模式时，清空选中状态
            this.selectedRows = []
            // 清空表格的选中状态
            if (this.$refs.vxeTable && this.$refs.vxeTable.clearSelection) {
              this.$refs.vxeTable.clearSelection()
            }
            // 退出维护模式时，恢复原始数据
            if (this.originalTableData && this.originalTableData.length > 0) {
              this.tableData = JSON.parse(JSON.stringify(this.originalTableData))
            }
            this.originalTableData = []
            this.isMaintainMode = false
            console.log('已退出维护参数模式')
            // 重新加载数据（恢复分页）
            this.loadData()
          })
          .catch(() => {
            // 取消操作
          })
      } else {
        // 非维护模式下，执行原来的返回功能
        console.log('handleBack called')
        this.$emit('back')
      }
    },
    pageSizeChange(size) {
      this.$set(this.pagination, 'pageSize', size)
      this.loadData()
    },
    rowClickEvent(row) {
      console.warn(row)
    },
    currentChange(currentPage) {
      this.$set(this.pagination, 'currentPage', currentPage)
      this.loadData()
    },
    approvalPageSizeChange(size) {
      this.$set(this.pagination, 'pageSize', size)
      this.getApprovalChange()
    },
    approvalCurrentPageChange(currentPage) {
      this.$set(this.pagination, 'currentPage', currentPage)
      this.getApprovalChange()
    },
    selectDataChange(data) {
      // 维护模式下，更新选中的行数据，过滤掉已删除的行
      if (this.isMaintainMode) {
        // 过滤掉已标记为删除的行
        const filteredRows = (data || []).filter((row) => row.operation !== 'delete')
        // 使用 Vue.set 确保响应式更新
        this.$set(this, 'selectedRows', filteredRows)
        console.log('选中的行:', this.selectedRows.length)
      } else {
        this.$emit('select-data-change', data)
      }
    },
    resetSearch() {
      this.searchPanelValue = {
        parameterType: '',
        partsName: '',
        parameterName: ''
      }
      this.handleSearch()
    },
    handleSearch() {
      this.$set(this.pagination, 'currentPage', 1)
      this.loadData()
    },
    handleImport() {
      if (this.importing) {
        return
      }
      this.importDialogVisible = true
    },
    handleImportFileChange(uploadFile, uploadFiles) {
      // 允许的文件类型
      const allowedTypes = ['.xls', '.xlsx', '.csv']
      const allowedMimeTypes = [
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'text/csv',
        'application/vnd.ms-excel.sheet.macroEnabled.12'
      ]

      if (uploadFile && uploadFile.raw) {
        const file = uploadFile.raw
        const fileName = file.name || ''
        const fileExtension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase()
        const fileType = file.type || ''

        // 验证文件扩展名
        const isValidExtension = allowedTypes.some((type) => fileExtension === type)
        // 验证 MIME 类型
        const isValidMimeType =
          !fileType || allowedMimeTypes.some((type) => fileType.includes(type))

        if (!isValidExtension && !isValidMimeType) {
          this.$message.error(`文件类型不支持，仅支持 ${allowedTypes.join('、')} 格式的文件`)
          // 清空不符合要求的文件
          this.selectedImportFile = null
          this.importFileList = []
          return false
        }

        this.selectedImportFile = file
        this.importFileList = uploadFiles.slice(-1)
      } else {
        this.selectedImportFile = null
        this.importFileList = uploadFiles.slice(-1)
      }
    },
    handleImportFileRemove() {
      this.selectedImportFile = null
      this.importFileList = []
    },
    handleImportDialogClose() {
      if (this.importing) {
        return
      }
      this.importDialogVisible = false
      this.selectedImportFile = null
      this.importFileList = []
    },
    handleImportConfirm() {
      if (this.importing || !this.selectedImportFile) {
        if (!this.selectedImportFile) {
          this.$message.warning('请先选择要导入的文件')
        }
        return
      }
      const templateId = this.getDetailTemplateId()
      if (!templateId) {
        this.$message.error('缺少模板ID，无法导入')
        return
      }
      const file = this.selectedImportFile
      // 再次验证文件类型（双重保险）
      const allowedTypes = ['.xls', '.xlsx', '.csv']
      const fileName = file.name || ''
      const fileExtension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase()

      if (!allowedTypes.includes(fileExtension)) {
        this.$message.error(`文件类型不支持，仅支持 ${allowedTypes.join('、')} 格式的文件`)
        this.selectedImportFile = null
        this.importFileList = []
        return
      }
      const resetState = () => {
        this.importing = false
        this.importDialogVisible = false
        this.selectedImportFile = null
        this.importFileList = []
      }
      const formData = new FormData()
      formData.append('file', file)
      formData.append('userId', getUserId())
      formData.append('createBy', getUserId())

      formData.append('templateRowId', templateId)
      const request = {
        ...api.IMPORT_MODEL,
        params: formData
      }
      this.importing = true
      // 显示全屏 loading 提示
      const loadingInstance = this.$loading({
        lock: true,
        text: '正在导入参数，请稍候...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      this.$upload(request, null, false)
        .asyncThen(() => {
          loadingInstance.close()
          resetState()
          if (this.tableData.length === 0) {
            this.loadData()
          } else {
            this.handleBack()
          }
        })
        .asyncErrorCatch((err) => {
          console.error('导入失败:', err)
          let errorMessage = '导入失败'
          if (err.data && err.data.error) {
            errorMessage = Array.isArray(err.data.error) ? err.data.error.join(', ') : err.data.error
          }
          this.$message({
            type: 'error',
            message: errorMessage
          })
          loadingInstance.close()
          resetState()
        })
        .finally(() => {
          // 确保 loading 在所有情况下都能关闭
          if (loadingInstance) {
            loadingInstance.close()
          }
          this.importing = false
        })
      this.importDialogVisible = false
    },
    handleDownloadTemplate() {
      const templateRowId = this.getDetailTemplateId()
      if (!templateRowId) {
        console.log('未找到模板ID，无法下载')
        return
      }
      if (this.downloadingRowId === templateRowId) {
        return
      }
      const { url, method = 'get', headers = {} } = api.DOWNLODE_MODEL || {}
      const requestConfig = {
        url,
        method,
        params: {
          templateRowId,
          templateEmpty: true
        },
        responseType: 'blob',
        headers
      }
      if (!requestConfig.url) {
        console.log('未配置下载地址')
        return
      }
      if ((requestConfig.method || '').toLowerCase() === 'post') {
        requestConfig.data = requestConfig.params
        delete requestConfig.params
      }
      this.downloadingRowId = templateRowId
      this.$axios(requestConfig)
        .then((response) => {
          const blobData = response.data
          if (!blobData) {
            console.log('下载失败，文件内容为空')
            return
          }
          const contentType =
            response.headers &&
            (response.headers['content-type'] || response.headers['Content-Type'])
          if (contentType && contentType.includes('application/json')) {
            try {
              const reader = new FileReader()
              reader.onload = () => {
                console.log(`下载失败: ${reader.result}`)
              }
              reader.readAsText(blobData)
            } catch (err) {
              console.error('解析下载失败响应异常:', err)
            }
            return
          }
          const disposition =
            response.headers &&
            (response.headers['content-disposition'] || response.headers['Content-Disposition'])
          let filename = '导入模板.xlsx'
          if (disposition) {
            const filenameMatch = /filename\*=UTF-8''([^;]+)|filename="?([^";]+)"?/i.exec(
              disposition
            )
            const matchedName = filenameMatch ? filenameMatch[1] || filenameMatch[2] : ''
            if (matchedName) {
              try {
                filename = decodeURIComponent(matchedName)
              } catch (err) {
                filename = matchedName
              }
            }
          }
          const downloadUrl = window.URL.createObjectURL(blobData)
          const link = document.createElement('a')
          link.href = downloadUrl
          link.download = filename
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          window.URL.revokeObjectURL(downloadUrl)
          console.log('下载开始，请查看浏览器下载列表')
        })
        .catch((err) => {
          console.error('下载失败:', err)
          console.log('下载失败，请稍后重试')
        })
        .finally(() => {
          this.downloadingRowId = ''
        })
    },
    getApprovalChange() {
      // 保存当前表格数据和分页信息（用于退出审批时还原）
      this.originalTableDataForApproval = JSON.parse(JSON.stringify(this.tableData))
      this.originalPaginationForApproval = JSON.parse(JSON.stringify(this.pagination))

      const request = {
        ...api.GET_APPROVAL_CHANGE,
        params: {
          templateId: this.getChangeId(),
          pageNumber: this.pagination.currentPage,
          pageSize: this.pagination.pageSize
        },
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          console.log('GET_APPROVAL_CHANGE 接口返回数据:', resp)
          const result = (resp && resp.data && resp.data.result) || []
          // 获取总数，确保是数字类型
          const total =
            resp && resp.data ? resp.data.count || resp.data.total || resp.data.totalCount || 0 : 0
          const totalNumber = typeof total === 'number' ? total : parseInt(total, 10) || 0

          // 处理返回的数据，更新部门字段（根据接口返回的 department 值）
          const processedData = result.map((item, index) => {
            const processedItem = {
              ...item,
              parameterType: item.parameterType || item.type || '',
              number:
                item.number ||
                (this.pagination.currentPage - 1) * this.pagination.pageSize + index + 1
            }
            // department 保持原值，不进行格式化
            return processedItem
          })

          // 更新表格数据和分页信息
          this.tableData = processedData
          this.$set(this.pagination, 'total', totalNumber)

          // 切换到发起审批模式
          this.isApprovalMode = true
          // 重置表单数据，设置流程主题默认值
          const templateName = this.displayTemplateName || '模板'
          this.approvalFormData = {
            processTitle: `${templateName}审批流程`,
            description: ''
          }
          // 重置审批环节
          this.approvalWorkflowSteps = [
            {
              name: '校对',
              required: true,
              handlers: [],
              options: [],
              loading: false,
              isEditing: false,
              originalData: null
            },
            {
              name: '审核',
              required: true,
              handlers: [],
              options: [],
              loading: false,
              isEditing: false,
              originalData: null
            },
            {
              name: '会签',
              required: false,
              handlers: [],
              options: [],
              loading: false,
              isEditing: false,
              originalData: null
            },
            {
              name: '批准',
              required: true,
              handlers: [],
              options: [],
              loading: false,
              isEditing: false,
              originalData: null
            }
          ]

          // 如果是重新发起模式，填充之前获取的审批流程数据
          if (this.isResendMode && this.resendApprovalData) {
            // 使用 $nextTick 确保 DOM 更新后再填充数据
            this.$nextTick(() => {
              this.fillResendApprovalData(this.resendApprovalData)
              // 重置标志
              this.isResendMode = false
              this.resendApprovalData = null
            })
          }
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批变更数据失败:', err)
          // 如果接口调用失败，不进入审批模式，保持原有数据
        })
    },
    handleInitiateApproval() {
      this.getApprovalChange()
    },
    handleRestartApproval() {
      // 直送：直接调用直送接口
      const templateId = this.getDetailTemplateId()
      if (!templateId) {
        this.$message.error('缺少模板ID，无法执行直送操作')
        return
      }

      this.$confirm('确定要执行直送操作吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.resending = true
        const request = {
          ...api.RESTART_MODEL_APPROVAL,
          params: {
            templateId: this.getChangeId(),
            userId: getUserId()
          },
          disableSuccessMsg: true
        }

        this.$request(request)
          .asyncThen((resp) => {
            this.$message({
              message: '直送成功',
              type: 'success'
            })
            // 刷新数据
            this.loadData()
            // 如果有 flowId，重新获取审批流程数据
            if (this.detail && this.detail.flowId) {
              this.getApprovalSpet()
            }
            // 通知父组件刷新数据
            this.$emit('refresh')
            this.resending = false
          })
          .asyncErrorCatch((err) => {
            console.error('直送失败:', err)
            this.$message({
              message: err.message || '直送失败，请重试',
              type: 'error'
            })
            this.resending = false
          })
          .finally(() => {
            this.resending = false
          })
      }).catch(() => {
        // 取消操作
      })
    },
    // 填充重新发起的审批流程数据
    fillResendApprovalData(data) {
      console.log('fillResendApprovalData 接收到的数据:', data)
      // 提取节点列表 - 参考 fillApprovalUsersData 的逻辑
      let nodeList = []
      let processedData = null

      // 第一步：提取数据对象（支持多种数据结构）
      if (Array.isArray(data?.data)) {
        processedData = data.data
      } else if (Array.isArray(data?.data?.data)) {
        processedData = data.data.data
      } else if (Array.isArray(data?.data?.result)) {
        processedData = data.data.result
      } else if (Array.isArray(data)) {
        processedData = data
      } else if (data?.data && !Array.isArray(data.data)) {
        processedData = data.data
      } else {
        processedData = data
      }

      // 第二步：从 processedData 中提取节点列表
      if (Array.isArray(processedData)) {
        nodeList = processedData
      } else if (processedData && Array.isArray(processedData.data)) {
        nodeList = processedData.data
      } else if (processedData && Array.isArray(processedData.result)) {
        nodeList = processedData.result
      } else if (processedData && Array.isArray(processedData.nodeList)) {
        nodeList = processedData.nodeList
      } else if (processedData && Array.isArray(processedData.flowNodes)) {
        nodeList = processedData.flowNodes
      }

      console.log('提取的节点列表:', nodeList)
      console.log('处理后的数据对象:', processedData)

      // 确定用于提取流程主题和说明的数据对象
      const dataObj = (data && data.data && !Array.isArray(data.data) && typeof data.data === 'object') ? data.data : (processedData && !Array.isArray(processedData) ? processedData : data)

      // 如果接口返回了流程主题和说明，填充到表单
      if (dataObj && !Array.isArray(dataObj)) {
        if (dataObj.progressTitle || dataObj.processTitle) {
          this.approvalFormData.processTitle = dataObj.progressTitle || dataObj.processTitle || ''
          console.log('填充流程主题:', this.approvalFormData.processTitle)
        } else {
          // 如果接口没有返回流程主题，使用默认值
          const templateName = this.displayTemplateName || '模板'
          this.approvalFormData.processTitle = `${templateName}审批流程`
        }
        if (dataObj.explanation || dataObj.description) {
          this.approvalFormData.description = dataObj.explanation || dataObj.description || ''
        }
      } else {
        // 如果接口没有返回数据，使用默认值
        const templateName = this.displayTemplateName || '模板'
        this.approvalFormData.processTitle = `${templateName}审批流程`
      }

      // 遍历节点列表，根据 nodeName 匹配到对应的审批环节并填充人员信息
      if (nodeList && nodeList.length > 0) {
        console.log('开始填充节点人员信息，节点数量:', nodeList.length)
        nodeList.forEach((nodeItem) => {
          const nodeName = nodeItem.nodeName || nodeItem.node || ''
          console.log('处理节点:', nodeName, nodeItem)
          if (!nodeName) {
            console.log('节点名称为空，跳过')
            return
          }

          // 找到对应的审批环节
          const step = this.approvalWorkflowSteps.find(s => s.name === nodeName)
          if (!step) {
            console.log('未找到对应的审批环节:', nodeName)
            return
          }

          // 获取 assignees 数组
          const assignees = nodeItem.assignees || []
          console.log('节点 assignees:', assignees)
          if (!Array.isArray(assignees) || assignees.length === 0) {
            console.log('assignees 为空或不是数组，跳过')
            return
          }

          // 从 assignees 中提取人员信息（将 id 统一转换为 userId）
          const handlerInfos = assignees.map(assignee => {
            // 提取需要的字段：username、userNumber，并将 id 转换为 userId
            // 确保 userId 字段统一使用（优先使用 userId，如果没有则使用 id）
            const userId = assignee.userId || assignee.id || ''
            return {
              userId: userId,
              username: assignee.username || assignee.name || '',
              userNumber: assignee.userNumber || assignee.account || assignee.userId || assignee.id || ''
            }
          }).filter(item => item.userId) // 过滤掉没有 userId 的项

          console.log('提取的人员信息:', handlerInfos)

          // 如果有处理人信息，设置到 handlers 中（handlers 存储 userId 数组）
          if (handlerInfos.length > 0) {
            step.handlers = handlerInfos.map(h => h.userId).filter(Boolean)
            // 设置 options，确保已选择的人员信息在选项中（用于下拉框显示）
            // 统一使用 userId 字段，不使用 id 字段
            step.options = handlerInfos.map(h => ({
              userId: h.userId, // 统一使用 userId，不使用 id
              username: h.username || '',
              userNumber: h.userNumber || ''
            })).filter(opt => opt.userId)
            console.log('填充后的 step:', step.name, 'handlers:', step.handlers, 'options:', step.options)
          }
        })
      } else {
        console.log('节点列表为空，无法填充人员信息')
      }

      // 提取并保存 flowId（从 dataObj 中提取）
      if (dataObj && !Array.isArray(dataObj)) {
        this.resendFlowId = dataObj.flowId || dataObj.id || null
        console.log('提取的 flowId:', this.resendFlowId)
      }

      // 填充完数据后，设置重新发起模式已填充标志，并备份原始数据
      this.isResendModeFilled = true
      // 备份流程主题
      this.originalProcessTitle = this.approvalFormData.processTitle || ''
      // 备份每个环节的原始数据
      this.approvalWorkflowSteps.forEach((step) => {
        step.originalData = {
          handlers: JSON.parse(JSON.stringify(step.handlers || [])),
          options: JSON.parse(JSON.stringify(step.options || []))
        }
        step.isEditing = false
      })
    },
    handleApprovalCancel() {
      // 取消审批，退出审批模式
      this.isApprovalMode = false
      this.isResendMode = false
      this.resendApprovalData = null
      // 还原原始表格数据和分页信息
      if (this.originalTableDataForApproval && this.originalTableDataForApproval.length > 0) {
        this.tableData = JSON.parse(JSON.stringify(this.originalTableDataForApproval))
      }
      if (this.originalPaginationForApproval) {
        this.$set(this.pagination, 'currentPage', this.originalPaginationForApproval.currentPage)
        this.$set(this.pagination, 'pageSize', this.originalPaginationForApproval.pageSize)
        this.$set(this.pagination, 'total', this.originalPaginationForApproval.total)
      }
      // 清空保存的数据
      this.originalTableDataForApproval = []
      this.originalPaginationForApproval = null
      // 重置表单数据
      this.approvalFormData = {
        processTitle: '',
        description: ''
      }
      // 重置审批环节
      this.approvalWorkflowSteps = [
        {
          name: '校对',
          required: true,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        },
        {
          name: '审核',
          required: true,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        },
        {
          name: '会签',
          required: false,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        },
        {
          name: '批准',
          required: true,
          handlers: [],
          options: [],
          loading: false,
          isEditing: false,
          originalData: null
        }
      ]
      // 重置重新发起模式相关状态
      this.isResendModeFilled = false
      this.resendFlowId = null
      this.isProcessTitleEditing = false
      this.originalProcessTitle = ''
    },
    // 编辑审批环节
    handleEditStep(stepIndex) {
      const step = this.approvalWorkflowSteps[stepIndex]
      if (!step) {
        return
      }
      // 备份当前数据
      step.originalData = {
        handlers: JSON.parse(JSON.stringify(step.handlers || [])),
        options: JSON.parse(JSON.stringify(step.options || []))
      }
      // 设置为编辑状态
      step.isEditing = true
    },
    // 保存审批环节编辑
    handleSaveStep(stepIndex) {
      const step = this.approvalWorkflowSteps[stepIndex]
      if (!step) {
        return
      }
      const userIds = (step.handlers || []).filter(Boolean)
      if (userIds.length === 0) {
        this.$message.warning('请至少选择一位处理人')
        return
      }
      // 获取 flowId：优先从 detail 中获取，如果没有则从 resendFlowId 中获取
      let flowId = null
      if (this.detail && this.detail.flowId) {
        flowId = this.detail.flowId
      } else if (this.resendFlowId) {
        flowId = this.resendFlowId
      }
      if (!flowId) {
        this.$message.error('缺少流程ID，无法保存')
        return
      }
      const request = {
        ...api.EDIT_APPROVAL_PROCESS,
        params: {
          flowId: flowId,
          nodeName: step.name,
          userIds
        },
        disableSuccessMsg: true
      }
      step.loading = true
      this.$request(request)
        .asyncThen(() => {
          // 更新原始数据备份
          step.originalData = {
            handlers: JSON.parse(JSON.stringify(step.handlers || [])),
            options: JSON.parse(JSON.stringify(step.options || []))
          }
          // 退出编辑状态
          step.isEditing = false
          this.$message({
            type: 'success',
            message: '保存成功'
          })
        })
        .asyncErrorCatch((err) => {
          console.error('保存环节编辑失败:', err)
          this.$message({
            type: 'error',
            message: err?.message || '保存失败，请重试'
          })
        })
        .finally(() => {
          step.loading = false
        })
    },
    // 取消审批环节编辑
    handleCancelEditStep(stepIndex) {
      const step = this.approvalWorkflowSteps[stepIndex]
      if (!step || !step.originalData) {
        return
      }
      // 恢复原始数据
      step.handlers = JSON.parse(JSON.stringify(step.originalData.handlers || []))
      step.options = JSON.parse(JSON.stringify(step.originalData.options || []))
      // 退出编辑状态
      step.isEditing = false
    },
    // 继续审批流程
    continueApprovalProcess() {
      // 从 resendFlowId 中获取 flowId
      const flowId = this.resendFlowId
      if (!flowId) {
        this.$message.error('缺少流程ID，无法继续审批')
        this.approvalSubmitting = false
        return Promise.reject(new Error('缺少流程ID'))
      }

      const request = {
        ...api.CONTINUE_APPROVAL_PROCESS,
        params: {
          flowId: flowId,
          userId: getUserId()
        },
        disableSuccessMsg: true
      }

      this.approvalSubmitting = true
      return new Promise((resolve, reject) => {
        this.$request(request)
          .asyncThen((resp) => {
            console.log('审批提交成功')
            this.$message({
              type: 'success',
              message: '审批提交成功'
            })
            this.isApprovalMode = false
            this.isResendModeFilled = false
            this.resendFlowId = null
            this.approvalSubmitting = false
            // 清空保存的审批模式前的数据（因为审批已提交，不需要还原）
            this.originalTableDataForApproval = []
            this.originalPaginationForApproval = null
            this.handleBack()
            resolve(resp)
          })
          .asyncErrorCatch((err) => {
            console.error('审批提交失败:', err)
            this.$message({
              type: 'error',
              message: err?.message || '审批提交失败，请重试'
            })
            this.approvalSubmitting = false
            reject(err)
          })
      })
    },
    // 检查审批流程是否有变化
    checkApprovalDataChanged() {
      // 检查流程主题是否有变化
      const currentTitle = (this.approvalFormData.processTitle || '').trim()
      const originalTitle = (this.originalProcessTitle || '').trim()
      if (currentTitle !== originalTitle) {
        return true
      }

      // 检查审批环节是否有变化
      for (let i = 0; i < this.approvalWorkflowSteps.length; i++) {
        const step = this.approvalWorkflowSteps[i]
        const originalHandlers = (step.originalData && step.originalData.handlers) || []
        const currentHandlers = (step.handlers || []).slice().sort()
        const originalHandlersSorted = originalHandlers.slice().sort()

        // 比较数组是否相同
        if (currentHandlers.length !== originalHandlersSorted.length) {
          return true
        }
        for (let j = 0; j < currentHandlers.length; j++) {
          if (currentHandlers[j] !== originalHandlersSorted[j]) {
            return true
          }
        }
      }

      return false
    },
    // 保存审批流程变更（返回 Promise）
    saveApprovalChanges() {
      return new Promise((resolve, reject) => {
        const newTitle = (this.approvalFormData.processTitle || '').trim()
        if (!newTitle) {
          reject(new Error('流程主题不能为空'))
          return
        }

        // 获取 flowId：优先从 detail 中获取，如果没有则从 resendFlowId 中获取
        let flowId = null
        if (this.detail && this.detail.flowId) {
          flowId = this.detail.flowId
        } else if (this.resendFlowId) {
          flowId = this.resendFlowId
        }

        if (!flowId) {
          reject(new Error('缺少流程ID，无法保存'))
          return
        }

        // 构建 nodeList：从审批环节中提取（和发起审批一样）
        const nodeList = this.approvalWorkflowSteps.map((step, index) => ({
          nodeName: step.name,
          assignees: step.handlers,
          nodeOrder: index + 1
        }))

        // 调用编辑审批流程接口，传参：nodeList, flowId, title, userId
        const request = {
          ...api.EDIT_APPROVAL_PROCESS,
          params: {
            nodeList: nodeList,
            flowId: flowId,
            title: newTitle,
            userId: getUserId()
          },
          disableSuccessMsg: true
        }

        this.$request(request)
          .asyncThen(() => {
            // 更新原始数据备份
            this.originalProcessTitle = newTitle
            // 更新所有环节的原始数据备份
            this.approvalWorkflowSteps.forEach((step) => {
              step.originalData = {
                handlers: JSON.parse(JSON.stringify(step.handlers || [])),
                options: JSON.parse(JSON.stringify(step.options || []))
              }
            })
            resolve()
          })
          .asyncErrorCatch((err) => {
            console.error('保存失败:', err)
            reject(err)
          })
      })
    },
    // 编辑流程主题（统一控制所有环节的编辑状态）
    handleEditProcessTitle() {
      // 备份当前流程主题
      this.originalProcessTitle = this.approvalFormData.processTitle || ''
      // 备份所有环节的原始数据
      this.approvalWorkflowSteps.forEach((step) => {
        step.originalData = {
          handlers: JSON.parse(JSON.stringify(step.handlers || [])),
          options: JSON.parse(JSON.stringify(step.options || []))
        }
      })
      // 设置为编辑状态（统一控制所有环节）
      this.isProcessTitleEditing = true
    },
    // 保存流程主题编辑（统一保存流程主题和所有环节）
    handleSaveProcessTitle() {
      const newTitle = (this.approvalFormData.processTitle || '').trim()
      if (!newTitle) {
        this.$message.warning('流程主题不能为空')
        return
      }
      // 获取 flowId：优先从 detail 中获取，如果没有则从 resendFlowId 中获取
      let flowId = null
      if (this.detail && this.detail.flowId) {
        flowId = this.detail.flowId
      } else if (this.resendFlowId) {
        flowId = this.resendFlowId
      }

      if (!flowId) {
        this.$message.error('缺少流程ID，无法保存')
        return
      }

      // 构建 nodeList：从审批环节中提取（和发起审批一样）
      const nodeList = this.approvalWorkflowSteps.map((step, index) => ({
        nodeName: step.name,
        assignees: step.handlers,
        nodeOrder: index + 1
      }))

      // 调用编辑审批流程接口，传参：nodeList, flowId, title, userId
      const request = {
        ...api.EDIT_APPROVAL_PROCESS,
        params: {
          nodeList: nodeList,
          flowId: flowId,
          title: newTitle,
          userId: getUserId()
        },
        disableSuccessMsg: true
      }

      this.$request(request)
        .asyncThen(() => {
          // 更新原始数据备份
          this.originalProcessTitle = newTitle
          // 更新所有环节的原始数据备份
          this.approvalWorkflowSteps.forEach((step) => {
            step.originalData = {
              handlers: JSON.parse(JSON.stringify(step.handlers || [])),
              options: JSON.parse(JSON.stringify(step.options || []))
            }
          })
          // 退出编辑状态
          this.isProcessTitleEditing = false
          this.$message({
            type: 'success',
            message: '保存成功'
          })
          // 重新拉取流程节点，保持数据同步
          if (flowId) {
            // 如果 detail 中没有 flowId，更新它
            if (!this.detail) {
              this.detail = {}
            }
            if (!this.detail.flowId) {
              this.detail.flowId = flowId
            }
            this.getApprovalSpet()
          }
        })
        .asyncErrorCatch((err) => {
          console.error('保存失败:', err)
          this.$message({
            type: 'error',
            message: err?.message || '保存失败，请重试'
          })
        })
    },
    // 取消流程主题编辑（统一恢复流程主题和所有环节）
    handleCancelEditProcessTitle() {
      // 恢复原始流程主题
      this.approvalFormData.processTitle = this.originalProcessTitle || ''
      // 恢复所有环节的原始数据
      this.approvalWorkflowSteps.forEach((step) => {
        if (step.originalData) {
          step.handlers = JSON.parse(JSON.stringify(step.originalData.handlers || []))
          step.options = JSON.parse(JSON.stringify(step.originalData.options || []))
        }
      })
      // 退出编辑状态
      this.isProcessTitleEditing = false
    },
    handleApprovalFormSubmit() {
      const processTitle = (this.approvalFormData.processTitle || '').trim()
      if (!processTitle) {
        this.$message.warning('请填写流程主题')
        return
      }
      // 统一使用去除首尾空格的值
      this.approvalFormData.processTitle = processTitle
      // 判断是否是重新发起状态
      if (this.isResendModeFilled) {
        // 重新发起状态：先检查是否有变化
        const hasChanged = this.checkApprovalDataChanged()
        console.log('hasChanged', hasChanged);
        
        if (hasChanged) {
          // 有变化，先保存变更
          this.approvalSubmitting = true
          this.saveApprovalChanges()
            .then(() => {
              // 保存成功后，继续审批流程
              return this.continueApprovalProcess()
            })
            .catch((err) => {
              console.error('保存变更失败:', err)
              this.$message({
                type: 'error',
                message: err?.message || '保存变更失败，请重试'
              })
              this.approvalSubmitting = false
            })
        } else {
          // 没有变化，直接继续审批流程
          this.continueApprovalProcess()
        }
      } else {
        // 正常发起审批：调用 START_APPROVAL 接口
        // 获取模板ID
        const templateRowId = this.getDetailTemplateId()
        if (!templateRowId) {
          this.$message.error('缺少模板ID，无法发起审批')
          return
        }
        const processTitle = (this.approvalFormData.processTitle || '').trim()
        // 构建 nodeList：从审批环节中提取（按照 engineDetail.vue 的方式）
        const nodeList = this.approvalWorkflowSteps.map((step, index) => ({
          nodeName: step.name,
          assignees: step.handlers,
          nodeOrder: index + 1
        }))
        const submitData = {
          templateRowId: templateRowId,
          nodeList: nodeList,
          processTitle: processTitle,
          createBy: getUserId(),
          userId: getUserId()
        }

        // 调用发起审批接口
        const request = {
          ...api.START_APPROVAL,
          params: submitData,
          disableSuccessMsg: true
        }

        this.approvalSubmitting = true
        this.$request(request)
          .asyncThen((resp) => {
            console.log('审批提交成功')
            this.$message({
              type: 'success',
              message: '审批提交成功'
            })
            this.isApprovalMode = false
            this.approvalSubmitting = false
            // 清空保存的审批模式前的数据（因为审批已提交，不需要还原）
            this.originalTableDataForApproval = []
            this.originalPaginationForApproval = null
            this.handleBack()
          })
          .asyncErrorCatch((err) => {
            console.error('审批提交失败:', err)
            this.$message({
              type: 'error',
              message: '审批提交失败，请重试'
            })
          })
          .finally(() => {
            this.approvalSubmitting = false
          })
      }
    },
    handleRemoteSearch(query, stepIndex) {
      const step = this.approvalWorkflowSteps[stepIndex]
      if (!query || query.trim() === '') {
        // 空查询时，只保留已选择的人员在选项中
        // step.handlers 现在是 userId 数组（因为 el-option 的 value 是 userId）
        if (step.handlers && step.handlers.length > 0) {
          // 从现有 options 中查找已选择的人员信息（匹配 userId）
          const selectedOptions = step.options.filter(
            (opt) => opt.userId && step.handlers.includes(opt.userId)
          )
          // 检查是否有已选择的人员不在 options 中
          const missingIds = step.handlers.filter(
            (id) => !selectedOptions.some((opt) => opt.userId === id)
          )
          if (missingIds.length > 0) {
            // 如果有缺失的人员信息，尝试通过搜索获取（搜索空字符串可能返回所有用户或最近使用的用户）
            // 这里先保留已找到的，缺失的会在用户下次搜索时自动补充
            step.options = selectedOptions
          } else {
            step.options = selectedOptions
          }
        } else {
          step.options = []
        }
        return
      }

      step.loading = true
      const trimmedQuery = query.trim()
      let request = null
      request = {
        ...api.GET_ALLUSERS,
        params: {
          name: trimmedQuery
        },
        disableSuccessMsg: true
      }

      this.$request(request)
        .asyncThen((resp) => {
          const respData = resp && resp.data
          let result = []
          if (Array.isArray(respData)) {
            result = respData
          } else if (respData && Array.isArray(respData.result)) {
            result = respData.result
          } else if (respData && respData.data && Array.isArray(respData.data)) {
            result = respData.data
          }
          // 转换为选项格式：{userId: user.userId, username: user.username, userNumber: user.userNumber}
          const users = result
            .map((user) => ({
              userId: user.userId || user.id,
              username: user.username || user.name,
              userNumber: user.userNumber || user.userId || user.id
            }))
            .filter((user) => user.userId && user.userNumber) // 过滤掉没有 userId 或 userNumber 的数据
          // step.handlers 现在是 userId 数组（因为 el-option 的 value 是 userId）
          const existingIds = new Set(step.handlers || [])
          // 过滤掉已选择的人员
          const filteredUsers = users.filter((user) => !existingIds.has(user.userId))
          // 合并：已选择的人员信息（从现有 options 中获取）+ 新的搜索结果
          const selectedOptions = (step.options || []).filter(
            (opt) => opt.userId && step.handlers && step.handlers.includes(opt.userId)
          )
          // 去重：使用 Map 确保每个 userId 只出现一次
          const optionsMap = new Map()
          // 先添加已选择的选项
          selectedOptions.forEach((opt) => {
            if (opt.userId) {
              optionsMap.set(opt.userId, opt)
            }
          })
          // 再添加新的搜索结果
          filteredUsers.forEach((user) => {
            if (user.userId && !optionsMap.has(user.userId)) {
              optionsMap.set(user.userId, user)
            }
          })
          step.options = Array.from(optionsMap.values())
          step.loading = false
        })
        .asyncErrorCatch((err) => {
          console.error('搜索人员失败:', err)
          // 搜索失败时，保留已选择的人员信息
          if (step.handlers && step.handlers.length > 0) {
            const selectedOptions = step.options.filter(
              (opt) => opt.userId && step.handlers.includes(opt.userId)
            )
            step.options = selectedOptions
          } else {
            step.options = []
          }
          step.loading = false
        })
    },
    handleHandlerChange(stepIndex, selectedIds) {
      // 处理人员选择变化
      // selectedIds 是选中的 id 数组，格式: ['id1', 'id2', ...]
      // v-model 已经自动更新了 step.handlers 为 id 数组
      // 由于用户选择的人员通常是从搜索结果中选择的，信息应该已经在 options 中
      // 如果不在，等用户下次搜索时会自动补充
      // 确保已选择的人员信息在选项中，以便正确显示 username
    },
    handleMaintainParams() {
      // 切换维护参数模式
      this.isMaintainMode = !this.isMaintainMode
      if (this.isMaintainMode) {
        // 进入维护模式时，清空选中状态
        this.selectedRows = []
        // 重置到第一页
        this.$set(this.pagination, 'currentPage', 1)
        // 先加载所有数据（不分页）
        this.loadAllData().then(() => {
          // 保存当前数据的深拷贝作为原始数据快照
          this.originalTableData = JSON.parse(JSON.stringify(this.tableData))
          console.log('已进入维护参数模式')
        })
      } else {
        // 退出维护模式时，清空选中状态
        this.selectedRows = []
        // 清空表格的选中状态
        if (this.$refs.vxeTable && this.$refs.vxeTable.clearSelection) {
          this.$refs.vxeTable.clearSelection()
        }
        // 退出维护模式时，恢复原始数据
        this.tableData = JSON.parse(JSON.stringify(this.originalTableData))
        this.originalTableData = []
        // 重置到第一页
        this.$set(this.pagination, 'currentPage', 1)
        console.log('已退出维护参数模式')
        // 重新加载数据（恢复分页）
        this.loadData()
      }
    },
    handleCancel() {
      // 取消维护，退出维护模式
      this.$confirm('确定要取消维护吗？未保存的修改将丢失。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.isMaintainMode = false
          this.loadData()
          console.log('已取消维护')
        })
        .catch(() => {
          // 取消操作
        })
    },
    handleBackFromMaintain() {
      // 返回，退出维护模式，恢复原始数据
      this.$confirm('确定要返回吗？未保存的修改将丢失。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 退出维护模式时，清空选中状态
          this.selectedRows = []
          // 清空表格的选中状态
          if (this.$refs.vxeTable && this.$refs.vxeTable.clearSelection) {
            this.$refs.vxeTable.clearSelection()
          }
          // 退出维护模式时，恢复原始数据
          if (this.originalTableData && this.originalTableData.length > 0) {
            this.tableData = JSON.parse(JSON.stringify(this.originalTableData))
          }
          this.originalTableData = []
          this.isMaintainMode = false
          console.log('已退出维护参数模式')
          // 重新加载数据（恢复分页）
          this.loadData()
        })
        .catch(() => {
          // 取消操作
        })
    },
    handleReset() {
      // 重置为进入维护模式前的数据
      this.$confirm('确定要重置吗？所有未提交的修改将丢失。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 恢复原始数据（清除所有操作标记）
          this.tableData = JSON.parse(JSON.stringify(this.originalTableData))
          // 重新计算序号
          const startIndex = (this.pagination.currentPage - 1) * this.pagination.pageSize
          this.tableData = this.tableData.map((item, index) => {
            const newItem = { ...item }
            // 清除操作标记
            delete newItem.operation
            delete newItem._rowClassName
            return {
              ...newItem,
              number: startIndex + index + 1
            }
          })
          // 强制更新表格
          this.$forceUpdate()
          console.log('已重置为原始数据')
        })
        .catch(() => {
          // 取消操作
        })
    },
    handleSubmit() {
      // 提交修改
      this.$confirm('确定要提交修改吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const templateRowId = this.getDetailTemplateId()
        if (!templateRowId) {
          console.log('缺少模板ID，无法提交')
          return
        }
        let sendTableData = this.tableData.map((item) => {
          return {
            ...item,
            parameterId: item.id
          }
        })

        // 构建提交数据，包含所有当前表格数据（包括已删除标记的数据）
        const submitData = {
          templateRowId,
          createBy: getUserId(),
          userId: getUserId(),
          parameterForms: sendTableData
        }
        this.submitting = true
        const request = {
          ...api.EDIT_MODEL_PARAM,
          params: submitData,
          disableSuccessMsg: true
        }

        this.$request(request)
          .asyncThen((res) => {
            this.submitting = false
            console.log('提交成功')
            // 提交成功后退出维护模式并重新加载数据
            this.isMaintainMode = false
            this.originalTableData = []
            this.submitting = false
            const newTemplateId = res.data && (res.data.templateId || res.data.templateRowId)
            this.setDetailTemplateId(newTemplateId)
            this.internalTemplateVersion = res.data.version
            this.templateVersion = res.data.version
            console.log(this.templateId, res.data.templateRowId)
            if (!this.versionList.some((v) => v.version === res.data.version)) {
              this.versionList.push({
                version: res.data.version,
                status: 'DRAFT',
                rowId: newTemplateId,
                id: res.data.templateId
              })
            } else {
              const versionItem = this.versionList.find((v) => v.version === res.data.version)
              versionItem.status = 'DRAFT'
              versionItem.rowId = newTemplateId
              versionItem.id = res.data.templateId
            }
            this.loadData()
          })
          .asyncErrorCatch((err) => {
            this.submitting = false
            console.error('提交失败:', err)
          })
      }).catch(() => {
        // 取消操作
        this.submitting = false
      })
    },
    handleAddParam() {
      // 打开添加参数弹窗
      this.paramModalMode = 'add'
      this.paramCurrentRow = null
      this.paramCurrentRowIndex = -1
      this.paramFormData = {
        subsystemName: '',
        parameterType: '',
        partsName: '',
        parameterName: '',
        department: '',
        departmentName: '',
        departmentId: '',
        parameterSource: '',
        numberOrFormula: '',
        fillDepartment: '',
        remarks: ''
      }
      this.paramModalVisible = true
      // 清除表单验证
      this.$nextTick(() => {
        if (this.$refs.paramForm) {
          this.$refs.paramForm.clearValidate()
        }
      })
    },
    handleRowEdit(row) {
      // 打开修改参数弹窗
      this.paramModalMode = 'edit'
      this.paramCurrentRow = row
      this.paramCurrentRowIndex = this.tableData.findIndex((item) => item === row)
      // 尝试从部门名称查找部门ID
      const departmentId = this.findDepartmentIdByName(row.department || '')
      this.paramFormData = {
        subsystemName: row.subsystemName || '',
        parameterType: row.parameterType || '',
        partsName: row.partsName || '',
        parameterName: row.parameterName || '',
        unit: row.unit || '',
        operation: 'update',
        department: row.department || '',
        departmentName: row.department || '',
        departmentId: departmentId || '',
        parameterSource: row.parameterSource || '',
        numberOrFormula: row.numberOrFormula || '',
        fillDepartment: row.fillDepartment || '',
        remarks: row.remarks || ''
      }
      this.paramModalVisible = true
      // 清除表单验证
      this.$nextTick(() => {
        if (this.$refs.paramForm) {
          this.$refs.paramForm.clearValidate()
        }
      })
    },
    handleRowDelete(row, rowIndex) {
      this.$confirm('确定要删除该参数吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          if (this.isMaintainMode) {
            // 维护模式下，标记为删除而不是真正删除
            this.markRowAsDeleted(row)
          }
        })
        .catch(() => {
          // 取消删除
        })
    },
    // 标记行为已删除（抽取为独立方法，供单个删除和批量删除使用）
    markRowAsDeleted(row) {
      if (!row) {
        return false
      }
      const index = this.tableData.findIndex(
        (item) =>
          item.rowId === row.rowId ||
          item.id === row.id ||
          (row._localId && item._localId === row._localId) ||
          item === row
      )
      if (index !== -1) {
        const targetRow = this.tableData[index]
        // 如果已经是删除状态，跳过
        if (targetRow.operation === 'delete') {
          return false
        }
        // 标记为删除，保留数据但设置删除标记与样式
        const updatedRow = {
          ...targetRow,
          operation: 'delete',
          _rowClassName: 'row-deleted'
        }
        this.$set(this.tableData, index, updatedRow)
        // 从选中列表中移除已删除的行
        this.selectedRows = this.selectedRows.filter(
          (selectedRow) =>
            !(
              (selectedRow.rowId && selectedRow.rowId === row.rowId) ||
              (selectedRow.id && selectedRow.id === row.id) ||
              (row._localId && selectedRow._localId && selectedRow._localId === row._localId) ||
              selectedRow === row
            )
        )
        // 更新表格的选中状态（移除已删除行的选中）
        this.$nextTick(() => {
          if (this.$refs.vxeTable && this.$refs.vxeTable.toggleRowSelection) {
            this.$refs.vxeTable.toggleRowSelection(updatedRow, false)
          }
        })
        console.log('已标记为删除')
        return true
      }
      return false
    },
    // 批量删除
    handleBatchDelete() {
      if (!this.selectedRows || this.selectedRows.length === 0) {
        this.$message.warning('请先选择要删除的参数')
        return
      }
      // 过滤掉已标记为删除的行
      const validSelectedRows = this.selectedRows.filter((row) => row.operation !== 'delete')
      if (validSelectedRows.length === 0) {
        this.$message.warning('选中的参数中已包含已删除的项，请重新选择')
        return
      }
      this.$confirm(`确定要删除选中的 ${validSelectedRows.length} 个参数吗?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 批量执行删除操作（标记为删除）
          let deleteCount = 0
          validSelectedRows.forEach((row) => {
            if (this.markRowAsDeleted(row)) {
              deleteCount++
            }
          })
          // 清空选中状态
          this.selectedRows = []
          // 清空表格的选中状态
          if (this.$refs.vxeTable && this.$refs.vxeTable.clearSelection) {
            this.$refs.vxeTable.clearSelection()
          }
          if (deleteCount > 0) {
            this.$message.success(`已标记 ${deleteCount} 个参数为删除`)
          }
        })
        .catch(() => {
          // 取消删除
        })
    },
    // 批量修改部门
    handleBatchModifyDepartment() {
      if (!this.selectedRows || this.selectedRows.length === 0) {
        this.$message.warning('请先选择要修改部门的参数')
        return
      }
      // 过滤掉已标记为删除的行
      const validSelectedRows = this.selectedRows.filter((row) => row.operation !== 'delete')
      if (validSelectedRows.length === 0) {
        this.$message.warning('选中的参数中已包含已删除的项，请重新选择')
        return
      }
      // 打开部门选择弹窗（批量修改模式）
      this.batchModifyDepartmentMode = true
      this.departmentDialogVisible = true
      this.departmentSearchText = '' // 重置搜索文本
      this.selectedDepartmentNode = null // 重置选中的部门节点
      this.currentDepartmentNodeKey = null // 重置当前选中的节点 key
      // 清空树节点的选中状态
      this.$nextTick(() => {
        if (this.$refs.departmentTree) {
          try {
            // 清空当前选中的节点
            this.$refs.departmentTree.setCurrentKey(null)
          } catch (err) {
            console.warn('清空树节点选中状态失败:', err)
          }
        }
      })
    },
    // 确认批量修改部门
    handleConfirmBatchModifyDepartment() {
      console.log('selectedDepartmentNode', this.selectedDepartmentNode)

      // 如果没有选中的节点，尝试从 el-tree 获取当前选中的节点
      if (!this.selectedDepartmentNode && this.$refs.departmentTree) {
        try {
          const currentKey = this.$refs.departmentTree.getCurrentKey()
          if (currentKey) {
            const node = this.findDepartmentNodeById(this.departmentTreeData, currentKey)
            if (node) {
              this.selectedDepartmentNode = node
            }
          }
        } catch (err) {
          console.warn('获取当前选中节点失败:', err)
        }
      }
      if (!this.selectedDepartmentNode) {
        this.$message.warning('请选择一个部门')
        return
      }
      // 过滤掉已标记为删除的行
      const validSelectedRows = this.selectedRows.filter((row) => row.operation !== 'delete')
      if (validSelectedRows.length === 0) {
        this.$message.warning('选中的参数中已包含已删除的项，请重新选择')
        this.handleDepartmentDialogClose()
        return
      }
      // 获取部门路径名称
      const departmentPath = this.getDepartmentPathName(this.selectedDepartmentNode.id)
      const departmentName = departmentPath || this.selectedDepartmentNode.name
      const departmentId = this.selectedDepartmentNode.id
      // 批量更新选中行的部门信息
      let updateCount = 0
      validSelectedRows.forEach((row) => {
        const index = this.tableData.findIndex(
          (item) =>
            (item.rowId && row.rowId && item.rowId === row.rowId) ||
            (item.id && row.id && item.id === row.id) ||
            (row._localId && item._localId && item._localId === row._localId) ||
            item === row
        )
        if (index !== -1) {
          const targetRow = this.tableData[index]
          // 如果该行已经是删除状态，跳过
          if (targetRow.operation === 'delete') {
            return
          }
          // 更新部门信息
          const updatedRow = {
            ...targetRow,
            department: departmentName,
            departmentId: departmentId,
            operation: targetRow.operation || 'update' // 如果是新增的数据，保持 insert，否则设置为 update
          }
          this.$set(this.tableData, index, updatedRow)
          updateCount++
        }
      })
      // 关闭弹窗
      this.handleDepartmentDialogClose()
      if (updateCount > 0) {
        this.$message.success(`已批量修改 ${updateCount} 个参数的部门`)
      } else {
        this.$message.warning('没有可修改的参数')
      }
    },
    getRowClassName({ row }) {
      // 为标记为删除的行添加红色背景样式
      if (
        this.isMaintainMode &&
        (row.operation === 'delete' || row._rowClassName === 'row-deleted')
      ) {
        return 'row-deleted'
      }
      return ''
    },
    // 获取行的唯一标识（用于 row-key）
    getRowKey(row) {
      // 优先使用 rowId，其次使用 id，最后使用 _localId
      return row.rowId || row.id || row._localId || null
    },
    // 控制哪些行可以被选中（用于 el-table 的 selectable 属性）
    checkRowMethod(row, index) {
      // 已删除的行不能被选中
      if (row.operation === 'delete' || row._rowClassName === 'row-deleted') {
        return false
      }
      return true
    },
    handleParamFormSubmit() {
      // 表单验证
      this.$refs.paramForm.validate((valid) => {
        if (valid) {
          if (this.isMaintainMode) {
            // 维护模式下，只更新本地表格数据，不调用接口
            if (this.paramModalMode === 'add') {
              // 新增：添加到表格数据
              const startIndex = (this.pagination.currentPage - 1) * this.pagination.pageSize
              const newRow = {
                id: null, // 新增的数据没有ID
                rowId: null,
                subsystemName: this.paramFormData.subsystemName,
                parameterType: this.paramFormData.parameterType,
                partsName: this.paramFormData.partsName,
                parameterName: this.paramFormData.parameterName,
                department: this.paramFormData.department,
                parameterSource: this.paramFormData.parameterSource,
                numberOrFormula: this.paramFormData.numberOrFormula,
                unit: this.paramFormData.unit,
                remarks: this.paramFormData.remarks,
                number:
                  this.tableData.length > 0
                    ? Math.max(...this.tableData.map((item) => item.number || 0)) + 1
                    : startIndex + this.tableData.length + 1,
                operation: 'insert', // 标记为新增数据
                _localId: this.nextLocalId++
              }
              this.tableData.push(newRow)
              // 更新总数，使用 $set 确保响应式更新
              this.$set(this.pagination, 'total', this.tableData.length)
            } else {
              // 修改：更新表格中对应的行
              let rowIndex = this.tableData.findIndex(
                (item) =>
                  (this.paramCurrentRow &&
                    item.rowId &&
                    this.paramCurrentRow.rowId &&
                    item.rowId === this.paramCurrentRow.rowId) ||
                  (this.paramCurrentRow &&
                    item.id &&
                    this.paramCurrentRow.id &&
                    item.id === this.paramCurrentRow.id)
              )
              if (rowIndex === -1 && this.paramCurrentRow && this.paramCurrentRow._localId) {
                rowIndex = this.tableData.findIndex(
                  (item) => item._localId && item._localId === this.paramCurrentRow._localId
                )
              }
              if (rowIndex === -1 && this.paramCurrentRowIndex > -1) {
                rowIndex = this.paramCurrentRowIndex
              }
              if (rowIndex === -1) {
                console.warn('未找到需要更新的行')
                return
              }
              this.$set(this.tableData, rowIndex, {
                ...this.tableData[rowIndex],
                subsystemName: this.paramFormData.subsystemName,
                parameterType: this.paramFormData.parameterType,
                partsName: this.paramFormData.partsName,
                parameterName: this.paramFormData.parameterName,
                department: this.paramFormData.department,
                parameterSource: this.paramFormData.parameterSource,
                numberOrFormula: this.paramFormData.numberOrFormula,
                unit: this.paramFormData.unit,
                remarks: this.paramFormData.remarks,
                operation: 'update'
              })
            }

            this.paramModalVisible = false
            console.log(this.paramModalMode === 'add' ? '已添加到表格' : '已更新表格数据')
            this.$message({
              type: 'success',
              message: '保存成功'
            })
          }
        }
      })
    },
    handleParamModalClose() {
      // 重置表单数据
      this.paramFormData = {
        subsystemName: '',
        parameterType: '',
        partsName: '',
        parameterName: '',
        department: '',
        departmentName: '',
        departmentId: '',
        parameterSource: '',
        numberOrFormula: '',
        fillDepartment: '',
        remarks: ''
      }
      this.paramCurrentRow = null
      this.paramCurrentRowIndex = -1
      this.paramSubmitting = false
      this.selectedDepartmentNode = null
      // 清除表单验证
      if (this.$refs.paramForm) {
        this.$refs.paramForm.clearValidate()
      }
    },
    // 根据部门名称查找部门ID
    findDepartmentIdByName(departmentName) {
      if (!departmentName || !this.departmentList || this.departmentList.length === 0) {
        return ''
      }
      // 递归查找部门ID
      const findId = (nodes, targetName) => {
        for (const node of nodes) {
          // 检查完整路径或节点名称是否匹配
          const pathName = this.getDepartmentPathName(node.id)
          if (pathName === targetName || node.name === targetName) {
            return node.id
          }
          if (node.children && node.children.length > 0) {
            const result = findId(node.children, targetName)
            if (result) {
              return result
            }
          }
        }
        return null
      }
      return findId(this.departmentList, departmentName) || ''
    },
    extractParameterId(row) {
      if (!row) {
        return null
      }
      return (
        row.id ||
        row.parameterId ||
        row.parameterID ||
        row.parameterid ||
        row.parameterCode ||
        row.code ||
        null
      )
    },
    buildParamPayload(templateId) {
      const version = this.internalTemplateVersion || this.templateVersion
      return {
        templateRowId: templateId,
        version,
        subsystemName: this.paramFormData.subsystemName,
        parameterType: this.paramFormData.parameterType,
        partsName: this.paramFormData.partsName,
        parameterName: this.paramFormData.parameterName,
        parameterSource: this.paramFormData.parameterSource,
        numberOrFormula: this.paramFormData.numberOrFormula,
        department: this.paramFormData.department,
        fillDepartment: this.paramFormData.fillDepartment,
        remarks: this.paramFormData.remarks
      }
    },
    loadTemplateInfo() {
      // 根据模板ID加载模板信息
      // 这里可以根据实际需求从API获取模板详情
      const id = this.getDetailTemplateId()
      if (id) {
        // TODO: 调用API获取模板详情
        // this.$request(...).then(res => {
        //   this.internalTemplateVersion = res.version || res.latestVersion
        // })
      }
    },
    loadLatestVersion() {
      // 加载最新版本信息
      // 如果没有传入版本，尝试从模板信息中获取最新版本
      const id = this.getDetailTemplateId()
      if (id && !this.internalTemplateVersion) {
        // TODO: 调用API获取最新版本
        // this.$request(...).then(res => {
        //   this.internalTemplateVersion = res.latestVersion || 'v1.0.0'
        // })
        // 暂时使用默认值，实际应该从API获取
        // 如果模板信息中已经有版本信息，可以在这里设置
      }
      // 如果仍然没有版本，可以设置一个默认值
      if (!this.internalTemplateVersion) {
        // 可以根据实际需求设置默认值，这里暂时留空
        // this.internalTemplateVersion = 'v1.0.0'
      }
    },
    loadAllData() {
      // 加载所有数据（不分页），用于维护模式
      const templateId = this.getDetailTemplateId()
      if (!templateId) {
        this.tableData = []
        this.$set(this.pagination, 'total', 0)
        return Promise.resolve()
      }
      const version = this.internalTemplateVersion || this.templateVersion
      const params = {
        templateRowId: templateId,
        version,
        pageNumber: 1,
        pageSize: 999999 // 设置一个很大的值以获取所有数据
      }
      if (this.searchPanelValue.parameterType) {
        params.parameterType = this.searchPanelValue.parameterType
      }
      if (this.searchPanelValue.partsName) {
        params.partsName = this.searchPanelValue.partsName
      }
      if (this.searchPanelValue.parameterName) {
        params.parameterName = this.searchPanelValue.parameterName
      }
      const request = {
        ...api.GET_MODEL_DETAIL,
        params,
        disableSuccessMsg: true
      }
      return this.$request(request)
        .asyncThen((resp) => {
          const result = (resp && resp.data && resp.data.result) || []
          // 获取总数，确保是数字类型
          const total =
            resp && resp.data ? resp.data.count || resp.data.total || resp.data.totalCount || 0 : 0
          const totalNumber = typeof total === 'number' ? total : parseInt(total, 10) || 0
          this.tableData = result.map((item, index) => {
            return {
              ...item,
              parameterType: item.parameterType || item.type || '',
              number: item.number || index + 1
              // department 保持原值，不进行格式化
            }
          })
          // 从接口返回的数据中获取状态（优先从 resp.data 中获取，其次从 result 中获取）
          const statusFromData = resp && resp.data ? (resp.data.status || resp.data.state || '') : ''
          const statusFromResult = result && result.length > 0 ? (result[0].status || result[0].state || '') : ''
          this.currentStatus = statusFromData || statusFromResult || ''
          // 使用 Vue.set 确保响应式更新，使用计算好的 totalNumber
          this.$set(this.pagination, 'total', totalNumber)
        })
        .asyncErrorCatch((err) => {
          console.error('查询失败:', err)
          this.tableData = []
          this.$set(this.pagination, 'total', 0)
        })
    },
    // 获取审批流程数据
    getApprovalSpet() {
      if (!this.detail || !this.detail.flowId) {
        return
      }
      const templateId = this.getDetailTemplateId()
      if (!templateId) {
        return
      }
      const request = {
        ...api.GET_PPROVAL_ALL,
        params: {
          flowId: this.detail.flowId,
          templateId: templateId
        },
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          console.log('审批流程数据:', resp)
          const data = resp.data || resp
          // 保存流程详情
          this.progressDetail = {
            explanation: data.explanation || '',
            flowStatus: data.flowStatus || '',
            progressTitle: data.progressTitle || '',
            templateVersion: data.templateVersion || '',
            contentName: data.contentName || ''
          }
          // 保存流程节点
          this.flowNodes = data.flowNodes || []
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批流程数据失败:', err)
          this.flowNodes = []
          this.progressDetail = {}
        })
    },
    // 设置状态文本
    setStatusText(result) {
      const statusMap = {
        PASS: '通过',
        REJECT: '拒绝',
        REFUSE: '驳回',
        APPROVE: '批准',
        APPROVING: '审批中',
        PENDING: '待处理',
        WAITING: '待处理',
        STAY: '待审批',
        INITIATE: '发起审批',
        RETURN: '退回'
      }
      return statusMap[result] || result || '待处理'
    },
    // 格式化时间
    formatTime(time) {
      if (!time) return '--'
      // 如果是时间戳，转换为日期格式
      if (typeof time === 'number') {
        const date = new Date(time)
        return date.toLocaleString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit'
        })
      }
      // 如果已经是字符串格式，直接返回
      return time
    },
    // 获取时间线颜色
    getTimelineColor(result, stepIndex, totalSteps) {
      // 根据审批结果设置颜色
      if (result === 'PASS' || result === 'APPROVE') {
        return '#67C23A' // 绿色 - 通过
      } else if (result === 'REJECT' || result === 'REFUSE') {
        return '#F56C6C' // 红色 - 驳回
      } else if (result === 'APPROVING' || result === 'PENDING' || result === 'WAITING') {
        return '#E6A23C' // 橙色 - 审批中
      } else if (result === 'STAY') {
        return '#909399' // 灰色 - 待审批
      } else if (result === 'INITIATE' || result === 'RETURN') {
        return '#409EFF' // 蓝色 - 发起审批/退回
      }
      // 默认颜色
      return '#409EFF' // 默认蓝色
    },
    // 获取状态样式类
    getStatusClass(result) {
      const classMap = {
        PASS: 'status-pass',
        APPROVE: 'status-approve',
        REJECT: 'status-reject',
        REFUSE: 'status-reject',
        APPROVING: 'status-approving',
        PENDING: 'status-pending',
        WAITING: 'status-pending',
        STAY: 'status-default',
        INITIATE: 'status-initiate',
        RETURN: 'status-return'
      }
      return classMap[result] || 'status-default'
    },
    getVersionName(version) {
      // 获取版本名称
      return version.version || version.name || ''
    },
    getVersionKey(version) {
      // 获取版本的唯一标识
      return version.version || version.name || version.rowId || ''
    },
    // 统一获取当前详情使用的 templateId（优先内部保存的最新值）
    getDetailTemplateId() {
      return this.internalTemplateId || this.templateId || ''
    },
    // 统一更新当前详情使用的 templateId，确保后续接口都使用最新值
    setDetailTemplateId(newTemplateId) {
      if (!newTemplateId) return
      this.internalTemplateId = newTemplateId
      this.templateId = newTemplateId
    },
    // 统一获取当前详情使用的 changeId（优先内部保存的最新值）
    getChangeId() {
      return this.internalChangeId || this.changeId || (this.detail && this.detail.changeId) || ''
    },
    handleVersionChange(versionName) {
      // 版本切换时，更新内部版本值并重新加载数据
      this.internalTemplateVersion = versionName
      const versionItem = this.versionList.find((v) => v.version === versionName)
      if (versionItem) {
        // 更新 changeId（使用版本的 id）
        this.internalChangeId = versionItem.id || ''
        // 更新 templateId
        const newTemplateId = versionItem.id || versionItem.rowId || ''
        this.setDetailTemplateId(newTemplateId)
      } else {
        this.internalChangeId = ''
      }
      // 重置分页到第一页
      this.$set(this.pagination, 'currentPage', 1)
      // 重新加载数据（使用新的版本号）
      this.loadData()
      // 更新当前版本的状态
      this.updateCurrentStatus()
    },
    // 更新当前版本的状态
    updateCurrentStatus() {
      // 优先从 detail prop 获取状态
      if (this.detail && this.detail.status) {
        this.currentStatus = this.detail.status
        return
      }
      // 从 versionList 中根据当前版本获取状态
      const currentVersion = this.internalTemplateVersion || this.templateVersion
      if (currentVersion && this.versionList && this.versionList.length > 0) {
        const versionItem = this.versionList.find((v) => {
          const versionName = this.getVersionName(v)
          return versionName === currentVersion
        })
        if (versionItem && versionItem.status) {
          this.currentStatus = versionItem.status
        } else {
          // 如果找不到对应版本的状态，使用 detail 中的状态或清空
          this.currentStatus = (this.detail && this.detail.status) || ''
        }
      } else {
        // 如果没有版本列表，使用 detail 中的状态或清空
        this.currentStatus = (this.detail && this.detail.status) || ''
      }
    },
    loadData() {
      const templateId = this.getDetailTemplateId()
      if (!templateId) {
        this.tableData = []
        this.$set(this.pagination, 'total', 0)
        return
      }
      const version = this.internalTemplateVersion || this.templateVersion
      const params = {
        templateRowId: templateId,
        version,
        pageNumber: this.pagination.currentPage,
        pageSize: this.pagination.pageSize
      }
      if (this.searchPanelValue.parameterType) {
        params.parameterType = this.searchPanelValue.parameterType
      }
      if (this.searchPanelValue.partsName) {
        params.partsName = this.searchPanelValue.partsName
      }
      if (this.searchPanelValue.parameterName) {
        params.parameterName = this.searchPanelValue.parameterName
      }
      const request = {
        ...api.GET_MODEL_DETAIL,
        params,
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          console.log('GET_MODEL_DETAIL 接口返回数据:', resp)
          const result = (resp && resp.data && resp.data.result) || []
          // 获取总数，支持多种可能的字段名，确保是数字类型
          const total =
            resp && resp.data ? resp.data.count || resp.data.total || resp.data.totalCount || 0 : 0
          const totalNumber = typeof total === 'number' ? total : parseInt(total, 10) || 0
          console.log('获取到的总数:', total, '转换后的数字:', totalNumber)
          const startIndex = (this.pagination.currentPage - 1) * this.pagination.pageSize
          this.tableData = result.map((item, index) => {
            return {
              ...item,
              parameterType: item.parameterType || item.type || '',
              number: item.number || startIndex + index + 1
              // department 保持原值，不进行格式化
            }
          })
          // 从 GET_MODEL_DETAIL 接口返回的数据中获取状态（优先从 resp.data 中获取，其次从 result 中获取）
          const statusFromData = resp && resp.data ? (resp.data.status || resp.data.state || '') : ''
          const statusFromResult = result && result.length > 0 ? (result[0].status || result[0].state || '') : ''
          // 更新 currentStatus，用于控制维护参数和发起审批按钮的显示
          this.currentStatus = statusFromData || statusFromResult || ''
          console.log('从 GET_MODEL_DETAIL 接口获取到的状态:', this.currentStatus)

          // 使用 Vue.set 确保响应式更新，使用计算好的 totalNumber
          this.$set(this.pagination, 'total', totalNumber)
          console.log('设置后的 pagination.total:', this.pagination.total)
        })
        .asyncErrorCatch((err) => {
          console.error('查询失败:', err)
          this.tableData = []
          this.$set(this.pagination, 'total', 0)
        })
    }
  }
}
</script>

<style lang="scss">
.back-button {
  padding: 0 !important;
}
.header-item {
  .label {
    font-size: 14px !important;
    font-weight: 500 !important;
    color: #303133 !important;
  }
  .value {
    font-size: 14px !important;
    font-weight: 300 !important;
  }
}
// 级联选择器样式修复
::v-deep .el-cascader {
  width: 100%;

  .el-cascader__tags {
    flex-wrap: wrap;
    max-width: 100%;
  }

  .el-input__inner {
    height: 32px;
    line-height: 32px;
  }
}

// 级联选择器下拉面板样式
::v-deep .el-cascader__dropdown {
  min-width: 200px !important;
  max-width: 500px;
  z-index: 3000 !important;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  overflow: visible;

  .el-cascader__suggestion-list {
    min-width: 200px !important;
    max-width: 500px;
    padding: 6px 0;
  }

  .el-cascader-menu {
    min-width: 180px;
    max-width: 300px;
    border-right: 1px solid #e4e7ed;

    &:last-child {
      border-right: none;
    }
  }

  .el-cascader-menu__wrap {
    max-height: 300px;
    overflow-y: auto;
    overflow-x: hidden;
  }

  .el-scrollbar {
    .el-scrollbar__wrap {
      overflow-x: hidden !important;
      overflow-y: auto !important;
      max-height: 300px;
    }

    .el-scrollbar__bar {
      &.is-vertical {
        right: 0;
        width: 6px;

        .el-scrollbar__thumb {
          background-color: rgba(144, 147, 153, 0.3);
          border-radius: 3px;

          &:hover {
            background-color: rgba(144, 147, 153, 0.5);
          }
        }
      }
    }
  }

  // 级联面板样式
  .el-cascader-panel {
    display: flex;
    border-radius: 4px;
    overflow: hidden;
  }

  // 级联菜单项样式
  .el-cascader-menu__item {
    height: 34px;
    line-height: 34px;
    padding: 0 20px;
    font-size: 14px;
    color: #606266;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background-color 0.25s;

    &:hover {
      background-color: #f5f7fa;
    }

    &.is-active {
      color: #409eff;
      font-weight: 500;
      background-color: #ecf5ff;
    }

    &.is-disabled {
      color: #c0c4cc;
      cursor: not-allowed;
      background-color: #fff;
    }
  }
}
.custom-page {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 56px;
    position: relative;
    width: 100%;
    min-height: 56px;
    background: #fff;
    border-bottom: 1px solid #ebeef5;
    padding: 0 20px;
    flex-shrink: 0;
    z-index: 10;

    .header-left {
      display: flex;
      align-items: center;
      gap: 10px;

      .back-button {
        padding: 0;
        margin-right: 8px;
        font-size: 14px;
        color: #000;
        cursor: pointer;
        pointer-events: auto;

        &:hover {
          color: #000;
        }

        i {
          margin-right: 4px;
        }
      }

      .header-item {
        display: flex;
        align-items: center;
        gap: 8px;

        .label {
          color: #303133;
          font-size: 16px !important;
        }

        .value {
          color: #303133;
          font-size: 16px !important;
          font-weight: 500 !important;
          max-width: 180px !important;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }

      .version-select-item {
        .label {
          width: 50px !important;
        }
        .version-select {
          width: 150px;
          margin-left: 8px;

          :deep(.el-input__inner) {
            height: 32px;
            line-height: 32px;
            font-size: 14px;
          }
        }
      }
    }

    .header-right {
      display: flex;
      gap: 8px;
    }
  }

  .page-search-panel {
    background: #fff;
    padding: 16px 24px;
    border-bottom: 1px solid #ebeef5;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 16px;

    .search-fields {
      display: flex;
      flex-direction: column;
      gap: 12px;
      width: 100%;
    }

    .search-row {
      display: flex;
      align-items: flex-end;
      gap: 40px;
      width: 100%;
    }

    .search-field {
      display: flex;
      align-items: center;
      gap: 12px;

      .field-label {
        font-size: 14px;
        font-weight: 600;
        color: #303133;
        white-space: nowrap;
        min-width: 64px;
        text-align: right;
      }

      .el-input,
      .el-select {
        width: 160px;
      }

      :deep(.el-input__inner),
      :deep(.el-select .el-input__inner) {
        height: 32px;
        line-height: 32px;
      }
    }

    .search-actions {
      display: flex;
      align-items: center;
      gap: 12px;
      margin-left: auto;

      :deep(.el-button) {
        padding: 0 16px;
        font-size: 14px;
        border-radius: 4px;
        height: 32px;
        line-height: 32px;
      }
    }
  }

  .page-data-list {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    padding: 10px !important;
    overflow: auto;

    &.has-footer {
      /* 维护模式下为底部按钮预留空间 */
      padding-bottom: 80px;
    }

    .x-empty-page {
      top: 0;
    }
  }

  .page-approval-content {
    display: flex;
    flex: 1;
    min-height: 0;
    padding: 20px;
    overflow-y: auto;
    overflow-x: hidden;
    background: #fff;

    &.has-footer {
      /* 审批模式下为底部按钮预留空间 */
      padding-bottom: 80px;
    }
  }

  .operation-links {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;

    .el-link {
      font-size: 14px;
    }

    .link-separator {
      width: 4px;
      display: inline-block;
    }

    .deleted-text {
      color: #f56c6c;
      font-size: 14px;
      font-weight: 500;
    }
  }

  .page-footer {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 16px 20px;
    background: #fff;
    border-top: 1px solid #ebeef5;
    flex-shrink: 0;
    position: relative;
    /* 确保在分页器之上，与头部按钮同一层级 */
    z-index: 10;

    .footer-buttons {
      display: flex;
      gap: 12px;
    }
  }
}

// 确保弹窗可以正常交互
::v-deep .el-dialog__wrapper {
  z-index: 2000 !important;

  .v-modal {
    z-index: 2000 !important;
  }
}

::v-deep .el-dialog {
  position: relative;
  z-index: 2001 !important;
  pointer-events: auto !important;
}

::v-deep .el-dialog__body {
  position: relative;
  z-index: 2002 !important;
  pointer-events: auto !important;
}

// 参数编辑弹窗样式
::v-deep .param-edit-dialog {
  .el-dialog__body {
    height: 450px;
    overflow-y: auto;
    padding: 20px;
  }

  .el-form {
    .el-row {
      margin-bottom: 0;
    }

    .el-form-item {
      margin-bottom: 18px;
    }

    .el-col {
      .el-form-item {
        margin-bottom: 18px;
      }
    }

    // 弹窗中的级联选择器样式
    .el-cascader {
      width: 100%;

      .el-input__inner {
        height: 32px;
        line-height: 32px;
      }
    }
  }
}

// 弹窗中的级联选择器下拉面板需要更高的z-index
::v-deep .el-dialog__wrapper {
  .el-cascader__dropdown {
    z-index: 3000 !important;
  }
}

.right-button {
  border: 1px solid #027aff !important;
  color: #027aff !important;
}
.right-button--primary {
  background: #027aff !important;
  color: #fff !important;
}

.search-table {
  min-height: 380px !important;
}
// 已删除行的红色背景样式
:deep(.block-table) {
  .row-deleted {
    background-color: #fef0f0 !important;

    td {
      background-color: #fef0f0 !important;
    }
  }
}
.required-mark{color:#f56c6c;margin-left:4px}
// 审批内容样式
.approval-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;

  .approval-table-section {
    // max-height 通过 :max-height 属性动态设置
    display: block;
  }

  .approval-description {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 10px;

    .description-label {
      font-size: 16px;
      line-height: 24px;
      font-weight: bolder;
      margin-bottom: 8px !important;
      color: #303133;
    }
  }

  .approval-process-title {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 20px;

    .description-label {
      font-size: 16px;
      line-height: 24px;
      font-weight: bolder;
      margin-bottom: 8px !important;
      color: #303133;
      gap: 12px;

      .step-actions {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-shrink: 0;

        .edit-step-btn,
        .save-step-btn,
        .cancel-step-btn {
          padding: 0;
          font-size: 12px;
          color: #409eff;

          &:hover {
            color: #66b1ff;
          }
        }

        .cancel-step-btn {
          color: #909399;

          &:hover {
            color: #a6a9ad;
          }
        }
      }
    }
  }

  .approval-workflow {
    display: flex;
    flex-direction: column;
    gap: 16px;

    .workflow-title {
      font-size: 14px;
      font-weight: 600;
      color: #303133;
    }

    .workflow-table {
      width: 100%;

      .workflow-table-content {
        width: 100%;
        border-collapse: collapse;
        border: 1px solid #ebeef5;

        thead {
          background: #f5f7fa;

          th {
            padding: 12px 16px;
            text-align: left;
            font-size: 14px;
            font-weight: 600;
            color: #303133;
            border-bottom: 1px solid #ebeef5;

            &.step-name-col {
              width: 120px;
            }

            &.handler-col {
              width: auto;
            }
          }
        }

        tbody {
          .workflow-row {
            &:not(:last-child) {
              border-bottom: 1px solid #ebeef5;
            }

            .step-name-cell {
              padding: 12px 16px;
              vertical-align: middle;

              .step-name {
                font-size: 14px;
                color: #303133;

                .required-mark {
                  color: #f56c6c;
                  margin-left: 4px;
                }
              }
            }

            .handler-cell {
              padding: 12px 16px;
              vertical-align: middle;

              .handler-select {
                width: 100%;
                min-width: 200px;

                :deep(.el-input__inner) {
                  height: 32px;
                  line-height: 32px;
                }

                :deep(.el-tag) {
                  margin: 2px 4px 2px 0;
                }
              }
            }
          }
        }
      }
    }
  }
}
.el-select-dropdown__item {
  display: flex !important;
  justify-content: space-between !important;
  padding-right: 20px !important;
}
.username-text {
  color: #303133 !important;
  display: inline-block;
  text-align: right !important;
}
.user-id-text {
  color: #909399 !important;
  display: inline-block;
  margin-left: 20px;
  margin-right: 30px;
  text-align: right !important;
}

// 部门选择弹窗样式
::v-deep .department-select-dialog {
  .el-dialog {
    height: 500px;
    display: flex;
    flex-direction: column;
  }

  .el-dialog__body {
    flex: 1;
    padding: 20px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
}

.department-dialog-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;

  .department-search-input {
    margin-bottom: 16px;
    flex-shrink: 0;
  }

  .department-tree-wrapper {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    border: 1px solid #ebeef5;
    border-radius: 4px;
    padding: 8px;
    max-height: 400px;
  }
}

// 审批流程样式
.approval-progress-section {
  margin-top: 20px;
  padding: 20px;
  background: #fff;
  border-radius: 4px;

  .section-title {
    font-size: 16px;
    font-weight: 600;
    color: #303133;
    margin-bottom: 16px;
  }

  .approval-timeline {
    padding: 20px 5px;
    max-height: 450px;
    overflow-y: auto;
  }

  .timeline-item-content {
    .node-title {
      font-size: 14px;
      font-weight: 500;
      color: #303133;
      margin-bottom: 8px;
    }

    .node-content {
      .node-info {
        margin-bottom: 8px;

        .node-user {
          font-size: 14px;
          color: #606266;
          display: flex;
          align-items: center;
          gap: 12px;

          .node-time {
            font-size: 12px;
            color: #909399;
          }
        }
      }

      .node-status {
        display: inline-block;
        padding: 2px 8px;
        border-radius: 2px;
        font-size: 12px;
        margin-bottom: 8px;

        &.status-pass,
        &.status-approve {
          background-color: #f0f9ff;
          color: #67c23a;
        }

        &.status-reject {
          background-color: #fef0f0;
          color: #f56c6c;
        }

        &.status-approving {
          background-color: #fdf6ec;
          color: #e6a23c;
        }

        &.status-pending {
          background-color: #f4f4f5;
          color: #909399;
        }

        &.status-default {
          background-color: #f4f4f5;
          color: #909399;
        }

        &.status-initiate,
        &.status-return {
          background-color: #ecf5ff;
          color: #409eff;
        }
      }

      .node-opinion {
        font-size: 13px;
        color: #606266;
        margin-top: 8px;
        padding: 8px;
        background-color: #f5f7fa;
        border-radius: 4px;
      }
    }
  }

  .empty-progress {
    padding: 40px 0;
    text-align: center;

    .empty-text {
      font-size: 14px;
      color: #909399;
    }
  }
}
::v-deep .el-button {
  line-height: 0.85 !important;
}
</style>
