<!--
 * @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 class="value" v-if="!isApprovalMode">{{
            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 class="right-button" @click="handleDownloadTemplate">
            下载导入模板
          </el-button>
          <el-button
            v-if="shouldShowButtons"
            class="right-button"
            @click="handleMaintainParams"
          >
            维护参数
          </el-button>
          <el-button
            v-if="shouldShowButtonsNew"
            class="right-button-primary"
            type="primary"
            @click="handleInitiateApproval"
          >
            发起审批
          </el-button>
        </template>
        <template v-else-if="isMaintainMode">
          <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 }">
      <x-vxe-table
        ref="vxeTable"
        :key="'table-' + isMaintainMode"
        :border="true"
        :colConfigs="tableConfig.colConfigs"
        :tableData="tableData"
        :rowDraggable="tableConfig.rowDraggable"
        :seqType="tableConfig.seqType"
        :layout="tableConfig.layout"
        :autoSize="tableConfig.autoSize"
        :pageConfig="tableConfig.pageConfig"
        :pagination="pagination"
        :row-class-name="getRowClassName"
        class="block-table"
        @table-row-click="rowClickEvent"
        @size-change="pageSizeChange"
        @current-page-change="currentChange"
        @select-data-change="selectDataChange"
      >
        <template
          v-for="(colConfig, index) in tableConfig.colConfigs"
          v-slot:[colConfig.customSlot]="{ row, rowIndex }"
        >
          <div
            v-if="colConfig.customSlot === 'options' && isMaintainMode"
            :key="index + '' + rowIndex"
            class="operation-links"
          >
            <template v-if="row.operation === 'delete'">
              <span class="deleted-text">已删除</span>
            </template>
            <template v-else>
              <template v-if="canEditOrDeleteRow(row)">
                <a
                  href="javascript:void(0)"
                  class="el-link el-link--primary"
                  @click.stop="handleRowEdit(row)"
                >
                  修改
                </a>
                <span class="link-separator"></span>
                <a
                  href="javascript:void(0)"
                  class="el-link el-link--primary"
                  @click.stop="handleRowDelete(row, rowIndex)"
                >
                  删除
                </a>
              </template>
            </template>
          </div>
        </template>
        <template slot="empty">
          <div class="table-empty">
            <x-empty-page></x-empty-page>
          </div>
        </template>
      </x-vxe-table>

      <!-- 审批流程 -->
      <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-table-section">
          <x-vxe-table
            :border="true"
            :colConfigs="approvalTableConfig.colConfigs"
            :tableData="tableData"
            :seqType="approvalTableConfig.seqType"
            :layout="approvalTableConfig.layout"
            :autoSize="approvalTableConfig.autoSize"
            :pageConfig="approvalTableConfig.pageConfig"
            :pagination="pagination"
            class="approval-table"
            @size-change="approvalPageSizeChange"
            @current-page-change="approvalCurrentPageChange"
          >
          </x-vxe-table>
        </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>
            <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>
          <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
                      reserve-keyword
                      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.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" :loading="submitting" @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" @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="选择填写部门"
      :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"
          @input="handleDepartmentSearch"
        />
        <div class="department-tree-wrapper">
          <el-tree
            ref="departmentTree"
            :data="filteredDepartmentTreeData"
            :props="{ children: 'children', label: 'name' }"
            node-key="id"
            :highlight-current="true"
            :default-expand-all="false"
            @node-click="handleDepartmentTreeNodeClick"
          />
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleDepartmentDialogClose">取消</el-button>
        <el-button type="primary" @click="handleConfirmDepartmentSelect">确定</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: () => []
    },
    changeId: {
      type: String,
      default: ''
    },
    detail: {
      type: Object,
      default: () => ({})
    },
    templateManagementPermissions: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    return {
      departmentList: [],
      internalTemplateVersion: '', // 内部版本值，用于 v-model
      internalTemplateId: '',
      internalTemplateName: '',
      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: '', // 部门搜索文本
      paramSubmitting: false,
      submitting: false, // 提交按钮loading状态
      importing: false,
      importDialogVisible: false,
      importFileList: [],
      selectedImportFile: null,
      approvalFormData: {
        processTitle: '',
        description: ''
      },
      approvalSubmitting: false, // 审批提交loading状态
      approvalWorkflowSteps: [
        {
          name: '校对',
          required: true,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '审核',
          required: true,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '会签',
          required: false,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '批准',
          required: true,
          handlers: [],
          options: [],
          loading: false
        }
      ],
      nextLocalId: 1,
      // 部门级联选择器相关
      departmentCascaderProps: {
        value: 'id',
        label: 'name',
        children: 'children',
        checkStrictly: true, // 允许选择任意一级（单选）
        emitPath: false, // 只返回最后一级的值（单选时只返回选中的id）
        multiple: false // 明确指定为单选
      },
      // 审批流程相关
      flowNodes: [], // 审批流程节点数据
      progressDetail: {} // 审批流程详情数据
    }
  },
  computed: {
    displayTemplateName() {
      return this.templateName || this.internalTemplateName || ''
    },
    versionOptions() {
      // 返回版本列表，如果没有则返回空数组
      return this.versionList || []
    },
    shouldShowButtonsNew() {
      // 根据 GET_MODEL_DETAIL 接口返回的 status 控制发起审批按钮
      const status = this.currentStatus || ''
      return status === 'DRAFT' && this.isLatestVersion
    },
    // 检查是否应该显示按钮（维护参数、导入）
    shouldShowButtons() {
      // 根据 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
    },
    tableConfig() {
      const baseColConfigs = [
        {
          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'
        },
        {
          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 {
        rowDraggable: false,
        colConfigs: baseColConfigs,
        seqType: '',
        layout: this.isMaintainMode ? '' : 'total, prev, pager, next, sizes, jumper',
        pageConfig: this.isMaintainMode
          ? { hidden: true }
          : {
            currentPage: this.pagination.currentPage,
            pageSize: this.pagination.pageSize,
            total: this.pagination.total
          }
      }
    },
    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'
          },
          {
            prop: 'remarks',
            label: '备注',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          },
          {
            prop: 'modifyDetails',
            label: '变动说明',
            showOverflowTooltip: true,
            minWidth: '150',
            align: 'center'
          }
        ],
        seqType: '',
        autoSize: true,
        layout: 'total, prev, pager, next, sizes, jumper',
        pageConfig: {
          currentPage: this.pagination.currentPage,
          pageSize: this.pagination.pageSize,
          total: this.pagination.total
        }
      }
    },
    approvalFormRules() {
      return {
        name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
        model: [{ required: true, message: '请输入型号', trigger: 'blur' }],
        value: [{ required: true, message: '请输入数值', trigger: 'blur' }]
      }
    },
    // 审批流程时间线节点
    timelineNodes() {
      const nodes = []
      if (!this.flowNodes || this.flowNodes.length === 0) {
        return nodes
      }

      // 按照 nodeOrder 排序
      const sortedNodes = [...this.flowNodes].sort((a, b) => {
        const orderA = a.nodeOrder !== undefined && a.nodeOrder !== null ? Number(a.nodeOrder) : 0
        const orderB = b.nodeOrder !== undefined && b.nodeOrder !== null ? Number(b.nodeOrder) : 0
        return orderA - orderB
      })

      // 查找是否有 REJECT 节点
      const rejectIndex = sortedNodes.findIndex((node) => node.result === 'REJECT')

      let processedNodes = sortedNodes
      if (rejectIndex !== -1) {
        // 如果有 REJECT 节点，删除该节点后面的所有节点
        processedNodes = sortedNodes.slice(0, rejectIndex + 1)
      } else {
        // 如果没有 REJECT，将第一个 result 是"待审批"的节点改为 APPROVING
        const stayIndex = processedNodes.findIndex((node) => node.result === '待审批')
        if (stayIndex !== -1) {
          processedNodes = processedNodes.map((node, index) => {
            if (index === stayIndex) {
              return {
                ...node,
                result: 'APPROVING'
              }
            }
            return node
          })
        }
      }

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

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

        // 处理审批意见：如果有 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
        })
      })

      return nodes
    },
    // 过滤后的部门树数据
    filteredDepartmentTreeData() {
      if (!this.departmentSearchText || this.departmentSearchText.trim() === '') {
        return this.departmentTreeData
      }
      // 递归过滤树节点
      const filterTree = (nodes) => {
        const result = []
        for (const node of nodes) {
          const match =
            node.name && node.name.toLowerCase().includes(this.departmentSearchText.toLowerCase())
          const filteredChildren =
            node.children && node.children.length > 0 ? filterTree(node.children) : []
          if (match || filteredChildren.length > 0) {
            result.push({
              ...node,
              children: filteredChildren.length > 0 ? filteredChildren : node.children
            })
          }
        }
        return result
      }
      return filterTree(this.departmentTreeData)
    }
  },
  watch: {
    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
    },
    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 {
            // 如果当前版本在列表中，更新状态
            this.updateCurrentStatus()
          }
        }
      },
      immediate: true
    },
    detail: {
      handler(newDetail) {
        // 当 detail prop 更新时，更新当前状态
        if (newDetail && newDetail.status) {
          this.currentStatus = newDetail.status
        } else {
          // 如果 detail 中没有状态，从 versionList 中获取
          this.updateCurrentStatus()
        }
        // 如果有 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
    }
    // 初始化版本信息
    if (this.templateVersion) {
      this.internalTemplateVersion = this.templateVersion
    } 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
      }
    },
    // 检查是否有查看权限（用于模板管理页面，根据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, '编辑')
    },
    // 检查参数是否有编辑权限（根据subsystem和partsName匹配）
    hasParameterEditPermission(subsystem, partsName) {
      if (!subsystem || !partsName) {
        return false
      }
      // 优先使用传入的权限数组
      if (this.templateManagementPermissions && this.templateManagementPermissions.length > 0) {
        const templateName = this.displayTemplateName
        const matchedPermissions = this.templateManagementPermissions.filter((perm) => {
          // 检查 subsystem 是否匹配 templateName
          if (templateName && perm.subsystem !== templateName) {
            return false
          }

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

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

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

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

        // 查找匹配的权限：menuPath包含"模板管理"，subsystem匹配，partsName匹配，且parameterPer为"编辑"
        const templateName = this.displayTemplateName
        const matchedPermissions = permissionData.filter((perm) => {
          // 检查 menuPath 是否匹配
          const menuMatch = perm.menuPath && perm.menuPath.includes('模板管理')
          if (!menuMatch) {
            return false
          }

          // 检查 subsystem 是否匹配 templateName（如果 templateName 存在）
          if (templateName && perm.subsystem !== templateName) {
            return false
          }

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

          // 检查 partsName 是否匹配
          if (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
      }
      // 如果该行的 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.QUERY_ORG_TREE,
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          // 处理返回的数据，确保格式为 { id, name, children }
          let result = []
          if (resp && resp.data) {
            result = resp.data.result || resp.data.data || 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.departmentDialogVisible = true
      this.departmentSearchText = '' // 重置搜索文本
      // 如果已有选中的部门，在树中高亮显示
      if (this.paramFormData.departmentId && this.$refs.departmentTree) {
        this.$nextTick(() => {
          this.$refs.departmentTree.setCurrentKey(this.paramFormData.departmentId)
        })
      }
    },
    // 关闭部门选择弹窗
    handleDepartmentDialogClose() {
      this.departmentDialogVisible = false
      this.selectedDepartmentNode = null
      this.departmentSearchText = '' // 清空搜索文本
    },
    // 处理部门搜索
    handleDepartmentSearch() {
      // 搜索文本变化时，computed 属性 filteredDepartmentTreeData 会自动更新
      // 无需额外操作
    },
    // 处理树节点点击
    handleDepartmentTreeNodeClick(data) {
      this.selectedDepartmentNode = data
    },
    // 确认选择部门
    handleConfirmDepartmentSelect() {
      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(() => {
            // 退出维护模式时，恢复原始数据
            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) {
      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)
          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.changeId || this.detail.changeId,
          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 字段存在，格式化显示（只显示最后一节）
            if (item.department) {
              processedItem.department = this.formatDepartmentDisplay(item.department)
            }
            return processedItem
          })

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

          // 切换到发起审批模式
          this.isApprovalMode = true
          // 重置表单数据
          this.approvalFormData = {
            processTitle: '',
            description: ''
          }
          // 重置审批环节
          this.approvalWorkflowSteps = [
            {
              name: '校对',
              required: true,
              handlers: [],
              options: [],
              loading: false
            },
            {
              name: '审核',
              required: true,
              handlers: [],
              options: [],
              loading: false
            },
            {
              name: '会签',
              required: false,
              handlers: [],
              options: [],
              loading: false
            },
            {
              name: '批准',
              required: true,
              handlers: [],
              options: [],
              loading: false
            }
          ]
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批变更数据失败:', err)
          // 如果接口调用失败，不进入审批模式，保持原有数据
        })
    },
    handleInitiateApproval() {
      this.getApprovalChange()
    },
    handleApprovalCancel() {
      // 取消审批，退出审批模式
      this.isApprovalMode = false
      // 还原原始表格数据和分页信息
      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
        },
        {
          name: '审核',
          required: true,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '会签',
          required: false,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '批准',
          required: true,
          handlers: [],
          options: [],
          loading: false
        }
      ]
    },
    handleApprovalFormSubmit() {
      // 获取模板ID
      const templateRowId = this.getDetailTemplateId()
      if (!templateRowId) {
        this.$message.error('缺少模板ID，无法发起审批')
        return
      }
      const processTitle = (this.approvalFormData.processTitle || '').trim()
      if (!processTitle) {
        this.$message.warning('请填写流程主题')
        return
      }
      // 构建 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
      }

      this.approvalSubmitting = true
      this.$request(request)
        .asyncThen((resp) => {
          console.log('审批提交成功')
          // this.$message.success('审批提交成功')
          this.isApprovalMode = false
          this.approvalSubmitting = false
          // 清空保存的审批模式前的数据（因为审批已提交，不需要还原）
          this.originalTableDataForApproval = []
          this.originalPaginationForApproval = null
          this.handleBack()
        })
        .asyncErrorCatch((err) => {
          console.error('审批提交失败:', err)
          this.$message.error('审批提交失败，请重试')
        })
        .finally(() => {
          this.approvalSubmitting = false
        })
    },
    handleRemoteSearch(query, stepIndex) {
      const step = this.approvalWorkflowSteps[stepIndex]
      if (!query || query.trim() === '') {
        // 空查询时，只保留已选择的人员在选项中
        // step.handlers 现在是 userNumber 数组
        if (step.handlers && step.handlers.length > 0) {
          // 从现有 options 中查找已选择的人员信息
          const selectedOptions = step.options.filter(
            (opt) => opt.userNumber && step.handlers.includes(opt.userNumber)
          )
          // 检查是否有已选择的人员不在 options 中
          const missingNumbers = step.handlers.filter(
            (num) => !selectedOptions.some((opt) => opt.userNumber === num)
          )
          if (missingNumbers.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 现在是 userNumber 数组
          const existingNumbers = new Set(step.handlers || [])
          // 过滤掉已选择的人员
          const filteredUsers = users.filter((user) => !existingNumbers.has(user.userNumber))
          // 合并：已选择的人员信息（从现有 options 中获取）+ 新的搜索结果
          const selectedOptions = (step.options || []).filter(
            (opt) => opt.userNumber && step.handlers && step.handlers.includes(opt.userNumber)
          )
          // 去重：使用 Map 确保每个 userNumber 只出现一次
          const optionsMap = new Map()
          // 先添加已选择的选项
          selectedOptions.forEach((opt) => {
            if (opt.userNumber) {
              optionsMap.set(opt.userNumber, opt)
            }
          })
          // 再添加新的搜索结果
          filteredUsers.forEach((user) => {
            if (user.userNumber && !optionsMap.has(user.userNumber)) {
              optionsMap.set(user.userNumber, 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.userNumber && step.handlers.includes(opt.userNumber)
            )
            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.$set(this.pagination, 'currentPage', 1)
        // 先加载所有数据（不分页）
        this.loadAllData().then(() => {
          // 保存当前数据的深拷贝作为原始数据快照
          this.originalTableData = JSON.parse(JSON.stringify(this.tableData))
          console.log('已进入维护参数模式')
        })
      } else {
        // 退出维护模式时，恢复原始数据
        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(() => {
          // 退出维护模式时，恢复原始数据
          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: newTemplateId
              })
            } else {
              const versionItem = this.versionList.find((v) => v.version === res.data.version)
              versionItem.status = 'DRAFT'
              versionItem.rowId = newTemplateId
              versionItem.id = newTemplateId
            }
            this.loadData()
          })
          .asyncErrorCatch((err) => {
            this.submitting = false
            console.error('提交失败:', err)
          })
      })
      this.submitting = false.catch(() => {
        // 取消操作
      })
    },
    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) {
            // 维护模式下，标记为删除而不是真正删除
            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]
              // 标记为删除，保留数据但设置删除标记与样式
              const updatedRow = {
                ...targetRow,
                operation: 'delete',
                _rowClassName: 'row-deleted'
              }
              this.$set(this.tableData, index, updatedRow)
              console.log('已标记为删除')
            }
          }
        })
        .catch(() => {
          // 取消删除
        })
    },
    getRowClassName({ row }) {
      // 为标记为删除的行添加红色背景样式
      if (
        this.isMaintainMode &&
        (row.operation === 'delete' || row._rowClassName === 'row-deleted')
      ) {
        return 'row-deleted'
      }
      return ''
    },
    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: item.department ? this.formatDepartmentDisplay(item.department) : (item.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 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') {
        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 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
    },
    handleVersionChange(versionName) {
      // 版本切换时，更新内部版本值并重新加载数据
      this.internalTemplateVersion = versionName
      this.changeId = this.versionList.find((v) => v.version === versionName)?.id || ''
      const versionItem = this.versionList.find((v) => v.version === versionName)
      const newTemplateId = (versionItem && (versionItem.id || versionItem.rowId)) || ''
      this.setDetailTemplateId(newTemplateId)
      // 重置分页到第一页
      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: item.department ? this.formatDepartmentDisplay(item.department) : (item.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;
        }
      }

      .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: 1;
    min-height: 0;
    padding: 20px;
    overflow-y: auto;
    overflow-x: hidden;

    &.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;

    &.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;
}

// 已删除行的红色背景样式
: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 {
    .approval-table {
      max-height: 500px;
    }
  }

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

    .description-label {
      font-size: 14px;
      font-weight: 600;
      color: #303133;
    }
  }

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

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

    .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 0;
  }

  .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 {
          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;
    }
  }
}
</style>
