<template>
  <transition name="report-detail-fade">
    <div v-if="visible" class="report-detail">
      <div class="detail-panel">
        <div class="detail-header">
          <div class="header-left">
            <el-button
              type="text"
              icon="el-icon-arrow-left"
              class="back-button"
              @click="handleBack"
            >
            </el-button>
            <div class="header-info">
              <div class="title">
                报告详情
              </div>
            </div>
          </div>
          <div class="header-right">
            <!-- 草稿状态：显示发起和修改按钮 -->
            <template v-if="reportDetail.status === 'DRAFT' && !isEditMode">
              <el-button
                v-if="canResend"
                @click="handleResend"
              >
                直送
              </el-button>
              <el-button @click="handleLaunch">
                发起
              </el-button>
              <el-button v-if="hasOperationPermission()" type="primary" @click="handleEdit">
                修改
              </el-button>
            </template>
            <!-- 已拒绝状态：显示重新发起和修改按钮 -->
            <template v-if="reportDetail.status === 'REJECTED' && !isEditMode">
              <el-button
                :loading="resending"
                @click="handleResend"
              >
                直送
              </el-button>
              <el-button @click="handleResendApproval">
                发起
              </el-button>
              <el-button v-if="hasOperationPermission()" type="primary" @click="handleEdit">
                修改
              </el-button>
            </template>
            <!-- 编辑模式：显示保存和返回按钮 -->
            <template v-if="isEditMode">
              <el-button @click="handleCancelEdit">
                返回
              </el-button>
              <el-button type="primary" :loading="saving" @click="handleSave">
                保存
              </el-button>
            </template>
            <!-- 审批中状态：仅从待办页面进入时显示退回、直送和提交/重新发起按钮 -->
            <template v-if="reportDetail.status === 'APPROVING' && !isEditMode && fromTodo">
              <el-button
                @click="handleReturn"
              >
                退回
              </el-button>
              <el-button
                v-if="canResend"
                :loading="resending"
                @click="handleResend"
              >
                直送
              </el-button>
              <el-button
                type="primary"
                @click="handleSubmit"
              >
                提交
              </el-button>
            </template>
          </div>
        </div>
        <div class="detail-content">
          <!-- 报告详情信息 -->
          <section class="block-section">
            <div class="section-title">
              基础信息
            </div>
            <div class="info-grid">
              <!-- 流程主题单独一行 -->
              <div class="info-item-full">
                <span class="label">流程主题</span>
                <div v-if="!isEditMode && !isEditingProcessTitle" class="value process-title-value-wrapper">
                  {{ showTopDetail.processTitle || detail.processTitle || reportDetail.processTitle || '--' }}
                  <i
                    class="el-icon-edit process-title-edit-icon"
                    @click="handleEditProcessTitle"
                  ></i>
                </div>
                <div v-else-if="!isEditMode && isEditingProcessTitle" class="process-title-input-wrapper">
                  <el-input
                    v-model="editingProcessTitle"
                    placeholder="请输入流程主题"
                    maxlength="100"
                    show-word-limit
                    class="process-title-input"
                  >
                    <template slot="suffix">
                      <i class="el-icon-check process-title-icon" @click="handleSaveProcessTitle"></i>
                      <i class="el-icon-close process-title-icon" @click="handleCancelProcessTitle"></i>
                    </template>
                  </el-input>
                </div>
                <el-input
                  v-else
                  v-model="editFormData.processTitle"
                  maxlength="100"
                  show-word-limit
                  placeholder="请输入流程主题"
                />
              </div>
              <!-- 其他信息一行两个 -->
              <div class="info-row">
                <div class="info-item">
                  <span class="label">创建人</span>
                  <span class="value">{{ showTopDetail.createBy || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">创建时间</span>
                  <span class="value">{{ showTopDetail.createTime || '--' }}</span>
                </div>
              </div>
              <div class="info-row">
                <div class="info-item">
                  <span class="label">当前环节</span>
                  <span class="value">{{ showTopDetail.currentNode || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">当前处理人</span>
                  <span class="value">{{ showTopDetail.currentProcessor || '--' }}</span>
                </div>
              </div>
            </div>
          </section>

          <!-- 报告详情信息 -->
          <section class="block-section">
            <div class="section-title">
              报告信息
            </div>
            <!-- 只读模式 -->
            <template v-if="!isEditMode">
              <div class="info-grid">
                <div class="info-item">
                  <span class="label">标题名称</span>
                  <span class="value">{{ reportDetail.title || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">厂家名称（全称）</span>
                  <span class="value">{{ reportDetail.manufacturerName || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">产品型号（全称）</span>
                  <span class="value">{{ reportDetail.modelName || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">厂家简称</span>
                  <span class="value">{{ reportDetail.manufacturerAbbreviation || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">产品型号简称</span>
                  <span class="value">{{ reportDetail.modelAbbreviation || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">产品编号</span>
                  <span class="value">{{ reportDetail.productNumber || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">领域/模块</span>
                  <span class="value">{{ reportDetail.module || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">板块</span>
                  <span class="value">{{ reportDetail.plate || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">平台</span>
                  <span class="value">{{ reportDetail.platform || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">系列</span>
                  <span class="value">{{ reportDetail.series || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">细分市场</span>
                  <span class="value">{{ reportDetail.marketSegment || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">项目名称</span>
                  <span class="value">{{ reportDetail.projectName || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">项目编号</span>
                  <span class="value">{{ reportDetail.projectNumber || '--' }}</span>
                </div>
                <div class="info-item">
                  <span class="label">文件</span>
                  <span class="value">
                    <a v-if="reportDetail.filePath" href="javascript:void(0)" class="el-link el-link--primary" @click.stop="handleDownload(reportDetail)">{{ reportDetail.fileName }}</a>
                  </span>
                </div>
              </div>
              <div v-if="reportDetail.explanation" class="description-block">
                <span class="label">说明：</span>
                <span class="value">{{ reportDetail.explanation }}</span>
              </div>
            </template>
            <!-- 编辑模式 -->
            <template v-else>
              <el-form ref="editForm" :model="editFormData" label-width="150px">
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="标题名称" prop="title">
                      <el-input v-model="editFormData.title" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="厂家名称（全称）" prop="manufacturerName">
                      <el-input v-model="editFormData.manufacturerName" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="产品型号（全称）" prop="modelName">
                      <el-input v-model="editFormData.modelName" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="厂家简称" prop="manufacturerAbbreviation">
                      <el-input v-model="editFormData.manufacturerAbbreviation" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="产品型号简称" prop="modelAbbreviation">
                      <el-input v-model="editFormData.modelAbbreviation" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="产品编号" prop="productNumber">
                      <el-input v-model="editFormData.productNumber" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="领域/模块" prop="module">
                      <el-input v-model="editFormData.module" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="板块" prop="plate">
                      <el-input v-model="editFormData.plate" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="平台" prop="platform">
                      <el-input v-model="editFormData.platform" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="系列" prop="series">
                      <el-input v-model="editFormData.series" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="细分市场" prop="marketSegment">
                      <el-input v-model="editFormData.marketSegment" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="项目名称" prop="projectName">
                      <el-input v-model="editFormData.projectName" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="项目编号" prop="projectNumber">
                      <el-input v-model="editFormData.projectNumber" placeholder="请输入" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-form-item label="附件上传" prop="attachments">
                  <el-upload
                    ref="upload"
                    :auto-upload="false"
                    :on-change="handleFileChange"
                    :on-remove="handleFileRemove"
                    :file-list="fileList"
                    :limit="1"
                    accept=".doc,.pdf,.xls,.xlsx,.ppt,.pptx"
                  >
                    <el-button type="primary" icon="el-icon-upload">
                      选择文件
                    </el-button>
                    <div slot="tip" class="el-upload__tip">
                      支持扩展名: .doc .pdf .xls .xlsx .ppt .pptx，仅支持上传一个文件
                    </div>
                  </el-upload>
                </el-form-item>
                <el-form-item label="说明" prop="explanation">
                  <el-input
                    v-model="editFormData.explanation"
                    type="textarea"
                    :rows="4"
                    placeholder="请输入"
                  />
                </el-form-item>
              </el-form>
            </template>
          </section>

          <!-- 审批环节（草稿状态下显示） -->
          <section v-if="reportDetail.status === 'DRAFT' || reportDetail.status === 'REJECTED'" class="block-section">
            <div class="section-title">
              审批环节
            </div>
            <div class="approval-workflow">
              <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">
                        <!-- 只读模式：显示已选择的人员 -->
                        <template v-if="!isEditMode">
                          <div v-if="step.handlers && step.handlers.length > 0" class="handler-display">
                            <span
                              v-for="(handlerId, idx) in step.handlers"
                              :key="idx"
                              class="handler-tag"
                            >
                              {{ getHandlerName(handlerId, step.options) }}
                            </span>
                          </div>
                          <span v-else class="handler-empty">--</span>
                        </template>
                        <!-- 编辑模式：可编辑的下拉框 -->
                        <el-select
                          v-else
                          v-model="step.handlers"
                          multiple
                          filterable
                          remote
                          placeholder="请选择"
                          :remote-method="(query) => handleRemoteSearch(query, index)"
                          :loading="step.loading"
                          class="handler-select"
                          @change="(value) => handleHandlerChange(index, value)"
                        >
                          <el-option
                            v-for="person in step.options"
                            :key="person.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>
          </section>

          <!-- 审批流程 -->
          <section v-if="reportDetail.status && reportDetail.status !== 'DRAFT' && detail.flowId && !isEditMode" class="block-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>
          </section>
        </div>
      </div>

      <!-- 审批弹窗 -->
      <el-dialog
        title="提交"
        :visible.sync="approvalDialogVisible"
        width="500px"
        :close-on-click-modal="false"
        append-to-body
        @close="handleApprovalDialogClose"
      >
        <el-form
          ref="approvalForm"
          :model="approvalFormData"
          :rules="approvalFormRules"
          label-width="100px"
        >
          <el-form-item label="提交意见:">
            <el-input
              v-model="approvalFormData.opinion"
              type="textarea"
              :rows="4"
              placeholder="请输入提交意见（可选）"
            />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="handleApprovalDialogClose">
            取消
          </el-button>
          <el-button type="primary" :loading="approvalSubmitting" @click="handleApprovalSubmit">
            确定
          </el-button>
        </div>
      </el-dialog>

      <!-- 退回节点选择弹窗 -->
      <el-dialog
        title="选择退回节点"
        :visible.sync="returnNodeDialogVisible"
        width="500px"
        :close-on-click-modal="false"
        append-to-body
        @close="handleReturnNodeDialogClose"
      >
        <div class="return-node-dialog-content">
          <el-radio-group
            v-model="selectedReturnNode"
            @change="handleReturnNodeChange"
          >
            <el-radio
              v-for="node in returnableNodes"
              :key="node"
              :label="node"
            >
            </el-radio>
          </el-radio-group>
          <!-- 当选择"编制"节点时，显示意见输入框 -->
          <div v-if="selectedReturnNode === '编制'" class="return-opinion-section">
            <div class="opinion-label">
              退回意见:
            </div>
            <el-input
              v-model="returnOpinion"
              type="textarea"
              :rows="3"
              placeholder="请输入退回意见"
            />
          </div>
        </div>
        <div slot="footer" class="dialog-footer">
          <el-button @click="handleReturnNodeDialogClose">
            取消
          </el-button>
          <el-button
            type="primary"
            :loading="returnSubmitting"
            :disabled="!selectedReturnNode"
            @click="handleReturnSubmit"
          >
            确定
          </el-button>
        </div>
      </el-dialog>
    </div>
  </transition>
</template>

<script>
import api from '@/api'
import { getUserId } from '@/utils'
export default {
  name: 'ReportDetail',
  props: {
    detail: {
      type: Object,
      default: () => ({})
    },
    visible: {
      type: Boolean,
      default: true
    },
    fromTodo: {
      type: Boolean,
      default: false
    },
    canResend: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      reportDetail: {},
      showTopDetail: {
        processTitle: '',
        createBy: '',
        createTime: '',
        currentNode: '',
        currentProcessor: ''
      },
      progress: [], // 保留用于兼容
      flowNodes: [], // 审批流程节点数据
      progressDetail: {}, // 审批流程详情数据
      approvalDialogVisible: false,
      approvalFormData: {
        result: '',
        opinion: ''
      },
      approvalSubmitting: false,
      resending: false, // 直送提交loading状态
      approvalFormRules: {
        // 意见改为非必填
      },
      // 退回节点选择相关
      returnNodeDialogVisible: false,
      returnableNodes: [],
      selectedReturnNode: '',
      returnSubmitting: false,
      returnOpinion: '', // 退回意见（仅在选择编制节点时使用）
      isEditMode: false, // 编辑模式
      editFormData: {
        title: '',
        manufacturerName: '',
        modelName: '',
        manufacturerAbbreviation: '',
        modelAbbreviation: '',
        productNumber: '',
        module: '',
        plate: '',
        platform: '',
        series: '',
        marketSegment: '',
        projectName: '',
        projectNumber: '',
        explanation: '',
        fileUrl: '',
        fileName: '',
        processTitle: ''
      },
      originalReportDetail: {}, // 保存原始数据，用于取消编辑时恢复
      selectedFile: null, // 选中的文件
      fileList: [], // 文件列表
      uploading: false, // 上传中状态
      saving: false, // 保存中状态
      isEditingProcessTitle: false, // 是否正在编辑流程主题
      editingProcessTitle: '', // 正在编辑的流程主题值
      approvalFlowIdFromUsers: '', // 从审批人员接口获取的流程ID
      approvalCanSend: false, // 审批人员接口返回的是否可继续发起标识
      // 保存时对比快照（不依赖watch/change）
      originalEditSnapshot: null, // 进入编辑态并完成回填后的快照
      approvalWorkflowSteps: [
        {
          name: '校对',
          required: true,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '审核',
          required: true,
          handlers: [],
          options: [],
          loading: false
        },
        {
          name: '批准',
          required: true,
          handlers: [],
          options: [],
          loading: false
        }
      ],
      launching: false // 发起中状态
    }
  },
  computed: {
    // 发起审批节点
    initiateNode() {
      if (!this.reportDetail || !this.reportDetail.createBy) {
        return null
      }
      return {
        userName: this.reportDetail.createBy,
        createTime: this.reportDetail.createTime,
        status: 'INITIATE',
        result: 'INITIATE'
      }
    },
    // 合并所有节点为时间线数据
    timelineNodes() {
      const nodes = []

      // 添加发起审批节点
      if (this.initiateNode) {
      }

      // 使用 flowNodes 数据构建审批流程节点（按照返回的顺序直接渲染，不排序）
      if (this.flowNodes && this.flowNodes.length > 0) {
        // 查找是否有 REJECT 节点
        const rejectIndex = this.flowNodes.findIndex((node) => node.result === 'REJECT')

        let processedNodes = this.flowNodes
        if (rejectIndex !== -1) {
          // 如果有 REJECT 节点，删除该节点后面的所有节点
          // processedNodes = this.flowNodes.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 === 'MSG') {
              result = 'MSG'
              status = 'MSG'
            } else if (node.result === 'RETURN') {
              result = 'PASS'
              status = 'PASS'
            } else if (node.result === 'APPROVING') {
              result = 'APPROVING'
              status = 'APPROVING'
            } else if (node.result === 'PASS') {
              result = 'PASS'
              status = 'PASS'
            } else if (node.result === '待审批') {
              result = '待审批'
              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
    },
    // 当前环节
    currentNode() {
      // 如果是草稿状态，返回"草稿"
      if (this.reportDetail.status === 'DRAFT') {
        return '草稿'
      }
      if (this.flowNodes && this.flowNodes.length > 0) {
        // 找到第一个"待审批"或"审批中"的节点
        const approvingNode = this.flowNodes.find((node) =>
          node.result === '待审批' || node.result === 'APPROVING'
        )
        if (approvingNode) {
          return approvingNode.node || '--'
        }
        // 如果都已完成，返回最后一个节点
        const lastNode = this.flowNodes[this.flowNodes.length - 1]
        return lastNode ? (lastNode.node || '--') : '--'
      }
      return '--'
    },
    // 当前处理人
    currentProcessor() {
      if (this.flowNodes && this.flowNodes.length > 0) {
        // 找到第一个"待审批"或"审批中"的节点
        const approvingNode = this.flowNodes.find((node) =>
          node.result === '待审批' || node.result === 'APPROVING'
        )
        if (approvingNode) {
          // 优先使用待处理人，如果没有则使用已处理人
          return approvingNode.undoUserName || approvingNode.todoUserName || '--'
        }
      }
      return '--'
    }
  },
  watch: {
    detail: {
      handler(newVal) {
        if (newVal && newVal.reportId) {
          // 如果有 reportId，调用接口获取详情
          this.loadReportDetailFromApi(newVal.reportId, newVal.flowId)
          if (newVal.flowId) {
            this.getApprovalSpet(newVal.flowId)
          }
        }
      },
      immediate: true,
      deep: true
    }
  },
  mounted() {
    // this.getReportDetailProcess()
    // 加载用户权限
    this.loadUserSelfRole()
  },
  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)
        })
    },
    // 检查是否是管理员（isAdmin === 1）
    isAdmin() {
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }
        // 检查是否有 isAdmin === 1 的记录
        return permissionData.some((perm) => perm.isAdmin === 1 || perm.isAdmin === '1')
      } catch (err) {
        console.error('检查管理员权限失败:', err)
        return false
      }
    },
    // 检查是否有全局编辑权限（permissionPath 是"对标报告"且 parameterPer 是"编辑"）
    hasGlobalEditPermission() {
      try {
        const permissionDataStr = localStorage.getItem('user_self_role')
        if (!permissionDataStr) {
          return false
        }
        const permissionData = JSON.parse(permissionDataStr)
        if (!Array.isArray(permissionData)) {
          return false
        }
        // 检查是否有 permissionPath 为 "对标报告" 且 parameterPer 为 "编辑" 的权限
        return permissionData.some((perm) => {
          const permissionPath = perm.permissionPath || ''
          const parameterPer = perm.parameterPer || ''
          // 检查 permissionPath 是否等于 "对标报告"（不包含其他路径）
          return permissionPath === '对标报告' && parameterPer === '编辑'
        })
      } catch (err) {
        console.error('检查全局编辑权限失败:', err)
        return false
      }
    },
    // 检查是否有操作权限（管理员或全局编辑权限）
    hasOperationPermission() {
      // 如果是管理员，拥有全部权限
      if (this.isAdmin()) {
        return true
      }
      // 如果有全局编辑权限，拥有全部权限
      if (this.hasGlobalEditPermission()) {
        return true
      }
      return false
    },
    setStatusText(result) {
      const statusMap = {
        'PASS': '通过',
        'REJECT': '驳回',
        'REFUSE': '驳回',
        'APPROVE': '批准',
        'APPROVING': '审批中',
        'PENDING': '待处理',
        'WAITING': '待处理',
        'INITIATE': '发起审批',
        'MSG': '通过'
      }
      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 === 'INITIATE' || result === 'MSG') {
        return '#409EFF' // 蓝色 - 发起审批/MSG
      }
      // 默认颜色
      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',
        'INITIATE': 'status-initiate',
        'MSG': 'status-msg'
      }
      return classMap[result] || 'status-default'
    },
    loadReportDetail() {
      // 如果已经有详情数据，直接使用
      if (this.detail && Object.keys(this.detail).length > 0) {
        if (this.detail.reportId) {
          // 如果有 reportId，调用接口获取详情
          this.loadReportDetailFromApi(this.detail.reportId)
        } else {
          // 如果已经有完整的详情数据，直接使用
          this.reportDetail = this.detail
          // 如果flowId存在且状态不是草稿，加载审批流程
          if (this.detail.flowId && this.reportDetail.status && this.reportDetail.status !== 'DRAFT') {
            this.getApprovalSpet(this.detail.flowId)
          }
        }
      }
    },
    loadReportDetailFromApi(reportId, flowId) {
      console.log(reportId, flowId, 'reportId, flowId')

      if (!reportId) {
        return
      }
      const request = {
        ...api.GET_REPORT_DETAIL,
        params: {
          reportId: reportId
        },
        disableSuccessMsg: true
      }

      this.$request(request)
        .asyncThen((resp) => {
          this.reportDetail = resp.data || resp
          // 保存原始数据（用于编辑模式取消时恢复）
          this.originalReportDetail = JSON.parse(JSON.stringify(this.reportDetail))
          // 如果是草稿状态，获取审批人员（默认只读显示）
          if (this.reportDetail.status === 'DRAFT') {
            const currentFlowId = flowId || this.detail.flowId || this.reportDetail.flowId
            if (currentFlowId) {
              // 重置审批环节
              this.approvalWorkflowSteps = [
                {
                  name: '校对',
                  required: true,
                  handlers: [],
                  options: [],
                  loading: false
                },
                {
                  name: '审核',
                  required: true,
                  handlers: [],
                  options: [],
                  loading: false
                },
                {
                  name: '批准',
                  required: true,
                  handlers: [],
                  options: [],
                  loading: false
                }
              ]
              // 获取审批人员
              this.loadApprovalUsers(currentFlowId)
            }
          } else if (flowId && this.reportDetail.status && this.reportDetail.status !== 'DRAFT') {
            // 如果flowId存在且状态不是草稿，加载审批流程
            this.getApprovalSpet(flowId)
          }
        })
        .asyncErrorCatch((err) => {
          console.error('获取报告详情失败:', err)
          this.$message.error('获取报告详情失败，请重试')
        })
    },
    getApprovalSpet(flowId) {
      if (!flowId) {
        return
      }
      const reportId = this.reportDetail.reportId || this.reportDetail.id || this.detail.reportId || this.detail.id
      if (!reportId) {
        return
      }
      const request = {
        ...api.GET_REPORT_DETAIL_PROCESS,
        params: {
          flowId: flowId// 报告ID作为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.reportDetail.processTitle = data.progressTitle
          // 如果 flowStatus 是 REJECTED，强制设置当前环节为"草稿"，当前处理人为创建人
          const flowStatus = data.flowStatus || ''
          const createBy = data.createBy || ''
          if (flowStatus) {
            // 将报告状态与流程状态保持一致
            this.$set(this.reportDetail, 'status', flowStatus)
          }
          this.showTopDetail = {
            processTitle: data.progressTitle,
            createBy: createBy,
            createTime: data.createTime || '',
            currentNode: flowStatus === 'REJECTED' ? '编制' : (data.currentNode || ''),
            currentProcessor: flowStatus === 'REJECTED' ? createBy : (data.processor || '')
          }
          // 保存流程节点
          this.flowNodes = data.flowNodes || []
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批流程数据失败:', err)
          this.flowNodes = []
          this.progressDetail = {}
        })
    },
    handleBack() {
      this.$emit('close')
    },
    handleDownload(reportDetail) {
      const link = document.createElement('a')
      link.href = reportDetail.filePath
      link.style.display = 'none'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    },
    // 处理退回按钮点击
    handleReturn() {
      if (!this.detail || !this.detail.flowId) {
        this.$message.error('缺少审批信息')
        return
      }

      const request = {
        ...api.GET_CAN_RETURN_NODE,
        params: {
          flowId: this.detail.flowId
        },
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          console.log(resp)
          // 在列表最前面添加"编制"节点作为默认选项
          const nodes = Array.isArray(resp.data) ? resp.data : []
          this.returnableNodes = ['编制', ...nodes]
        })
        .asyncErrorCatch((err) => {
          console.error('获取退回节点失败:', err)
          // 即使获取失败，也添加"编制"节点
          this.returnableNodes = ['编制']
        })
      this.selectedReturnNode = ''
      this.returnOpinion = ''
      this.returnNodeDialogVisible = true
    },
    // 关闭退回节点选择弹窗
    handleReturnNodeDialogClose() {
      this.returnNodeDialogVisible = false
      this.selectedReturnNode = ''
      this.returnOpinion = ''
    },
    // 处理退回节点选择变化
    handleReturnNodeChange() {
      // 如果不是"编制"节点，清空意见
      if (this.selectedReturnNode !== '编制') {
        this.returnOpinion = ''
      }
    },
    // 提交退回操作
    handleReturnSubmit() {
      if (!this.selectedReturnNode) {
        this.$message.warning('请选择要退回的节点')
        return
      }

      if (!this.detail || !this.detail.flowId) {
        this.$message.error('缺少审批信息')
        return
      }

      this.returnSubmitting = true

      // 如果选择的是"编制"节点，调用拒绝接口
      if (this.selectedReturnNode === '编制') {
        const submitData = {
          flowId: this.detail.flowId,
          userId: getUserId(),
          result: 'REJECT',
          opinion: this.returnOpinion || '' // 意见非必填，可以为空
        }

        const request = {
          ...api.START_REPORT_APPROVAL,
          params: submitData,
          disableSuccessMsg: true
        }

        this.$request(request)
          .asyncThen((resp) => {
            this.handleReturnNodeDialogClose()
            // 重新加载审批流程数据
            if (this.detail.flowId) {
              this.getApprovalSpet(this.detail.flowId)
            }
            // 通知父组件刷新数据
            this.$message({
              message: '拒绝成功',
              type: 'success'
            })
            this.$emit('refresh')
            this.returnSubmitting = false
            // 执行返回按钮的点击
            this.handleBack()
          })
          .asyncErrorCatch((err) => {
            console.error('拒绝失败:', err)
            this.$message({
              message: err.message || '拒绝失败，请重试',
              type: 'error'
            })
            this.returnSubmitting = false
          })
          .finally(() => {
            this.returnSubmitting = false
          })
      } else {
        // 其他节点，调用退回接口
        // 获取流程发起人
        const createUserId = this.reportDetail.createdById || this.detail.createdById || ''
        if (!createUserId) {
          this.$message.error('无法获取流程发起人信息')
          this.returnSubmitting = false
          return
        }

        // 获取当前处理人
        const processUserId = getUserId()

        // 构建提交数据
        const submitData = {
          flowId: this.detail.flowId,
          nodeName: this.selectedReturnNode,
          createUserId: createUserId,
          processUserId: processUserId
        }

        const request = {
          ...api.RETURN_REPORT_TODO,
          params: submitData,
          disableSuccessMsg: true
        }

        this.$request(request)
          .asyncThen((resp) => {
            this.handleReturnNodeDialogClose()
            // 重新加载审批流程数据
            if (this.detail.flowId) {
              this.getApprovalSpet(this.detail.flowId)
            }
            // 通知父组件刷新数据
            this.$message({
              message: '退回成功',
              type: 'success'
            })
            this.$emit('refresh')
            this.returnSubmitting = false
            // 执行返回按钮的点击
            this.handleBack()
          })
          .asyncErrorCatch((err) => {
            console.error('退回失败:', err)
            this.$message({
              message: err.message || '退回失败，请重试',
              type: 'error'
            })
            this.returnSubmitting = false
          })
          .finally(() => {
            this.returnSubmitting = false
          })
      }
    },
    // 处理直送按钮点击
    handleResend() {
      const reportId = this.reportDetail.reportId || this.reportDetail.id || this.detail.reportId || this.detail.id
      if (!reportId) {
        this.$message.error('缺少报告ID，无法执行直送操作')
        return
      }

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

          this.$request(request)
            .asyncThen((resp) => {
              // 重新加载审批流程数据
              if (this.detail.flowId) {
                this.getApprovalSpet(this.detail.flowId)
              }
              // 通知父组件刷新数据
              this.$message({
                message: '直送成功',
                type: 'success'
              })
              this.$emit('refresh')
              this.resending = false
              // 执行返回按钮的点击
              this.handleBack()
            })
            .asyncErrorCatch((err) => {
              console.error('直送失败:', err)
              this.$message({
                message: err.message || '直送失败，请重试',
                type: 'error'
              })
              this.resending = false
            })
            .finally(() => {
              this.resending = false
            })
        })
        .catch(() => {
          // 取消操作
        })
    },
    // 处理提交按钮点击
    handleSubmit() {
      this.approvalFormData = {
        result: 'PASS',
        opinion: '同意' // 默认值为"同意"
      }
      this.approvalDialogVisible = true
      // 清除表单验证
      this.$nextTick(() => {
        if (this.$refs.approvalForm) {
          this.$refs.approvalForm.clearValidate()
        }
      })
    },
    handleApprovalDialogClose() {
      this.approvalDialogVisible = false
      this.approvalFormData = {
        result: '',
        opinion: ''
      }
      // 清除表单验证
      if (this.$refs.approvalForm) {
        this.$refs.approvalForm.clearValidate()
      }
    },
    handleApprovalSubmit() {
      // 表单验证
      this.$refs.approvalForm.validate((valid) => {
        if (!valid) {
          return false
        }

        if (!this.detail || !this.detail.flowId) {
          this.$message.error('缺少审批信息')
          return
        }

        // 构建提交数据
        const submitData = {
          flowId: this.detail.flowId,
          userId: getUserId(),
          result: this.approvalFormData.result, // 'PASS'
          opinion: this.approvalFormData.opinion || ''
        }

        this.approvalSubmitting = true
        const request = {
          ...api.START_REPORT_APPROVAL,
          params: submitData,
          disableSuccessMsg: true
        }

        this.$request(request)
          .asyncThen((resp) => {
            this.handleApprovalDialogClose()
            // 重新加载审批流程数据
            if (this.detail.flowId) {
              this.getApprovalSpet(this.detail.flowId)
            }
            // 通知父组件刷新数据
            this.$message({
              message: '审批提交成功',
              type: 'success'
            })
            this.$emit('refresh')
            this.approvalSubmitting = false
            // 执行返回按钮的点击
            this.handleBack()
          })
          .asyncErrorCatch((err) => {
            console.error('审批提交失败:', err)
            this.$message({
              message: '审批提交失败，请重试',
              type: 'error'
            })
            this.approvalSubmitting = false
          })
          .finally(() => {
            this.approvalSubmitting = false
          })
      })
    },
    // 对steps数组进行去重，优先保留有approvalTime的记录
    deduplicateSteps(steps) {
      if (!Array.isArray(steps) || steps.length === 0) {
        return []
      }

      // 使用Map来存储已见过的唯一标识和对应的记录
      const seen = new Map()
      const result = []

      steps.forEach(step => {
        // 生成唯一标识：优先使用id，如果没有id则使用多个字段组合
        let uniqueKey = null

        if (step.id) {
          // 如果有id，使用id作为唯一标识
          uniqueKey = `id_${step.id}`
        } else {
          // 如果没有id，使用多个字段组合作为唯一标识
          const userName = step.userName || step.operator || step.username || step.handlerName || step.handler || ''
          const approvalTime = step.approvalTime || step.handleTime || step.createTime || ''
          const stepResult = step.result || step.status || ''
          uniqueKey = `combo_${userName}_${approvalTime}_${stepResult}`
        }

        if (!uniqueKey) {
          return // 跳过无法生成唯一标识的记录
        }

        // 检查是否已存在相同唯一标识的记录
        if (seen.has(uniqueKey)) {
          // 如果已存在，比较两条记录，优先保留有approvalTime的记录
          const existingIndex = seen.get(uniqueKey)
          const existingStep = result[existingIndex]

          const currentHasTime = !!(step.approvalTime || step.handleTime || step.createTime)
          const existingHasTime = !!(existingStep.approvalTime || existingStep.handleTime || existingStep.createTime)

          // 如果当前记录有approvalTime而已存在的没有，则替换
          if (currentHasTime && !existingHasTime) {
            result[existingIndex] = step
          }
          // 如果两条都有或都没有，保留已存在的（第一条）
        } else {
          // 如果这个唯一标识还没有出现过，添加到结果中
          seen.set(uniqueKey, result.length)
          result.push(step)
        }
      })

      // 对所有记录的approvalTime进行格式化
      return result.map(step => {
        const formattedStep = { ...step }
        if (formattedStep.approvalTime) {
          formattedStep.approvalTime = this.formatTime(formattedStep.approvalTime)
        }
        if (formattedStep.handleTime) {
          formattedStep.handleTime = this.formatTime(formattedStep.handleTime)
        }
        if (formattedStep.createTime) {
          formattedStep.createTime = this.formatTime(formattedStep.createTime)
        }
        return formattedStep
      })
    },
    // 发起功能：直接调用发起接口（按照report.vue的方式）
    handleLaunch() {
      const reportId = this.reportDetail.reportId || this.reportDetail.id || this.detail.reportId || this.detail.id
      const flowId = this.approvalFlowIdFromUsers || this.detail.flowId || this.reportDetail.flowId
      const canSend = this.canResend

      if (!reportId) {
        this.$message.error('缺少报告ID，无法发起审批')
        return
      }

      if (!flowId) {
        this.$message.error('缺少流程ID，无法发起审批')
        return
      }

      this.$confirm('确定发起审批吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          let request = null
          if (canSend) {
            // 可继续发起时，调用继续审批接口，使用审批人员接口返回的 flowId
            const continueFlowId = this.approvalFlowIdFromUsers || flowId
            if (!continueFlowId) {
              this.$message.error('缺少流程ID，无法继续发起审批')
              return
            }
            request = {
              ...api.CONTINUE_REPORT_APPROVAL,
              params: {
                flowId: continueFlowId,
                userId: getUserId()
              },
              disableSuccessMsg: true
            }
          } else {
            const submitData = {
              reportId: reportId,
              flowId: flowId,
              userId: getUserId()
            }
            request = {
              ...api.ADD_REPORT,
              params: submitData,
              disableSuccessMsg: true
            }
          }

          this.launching = true
          this.$request(request)
            .asyncThen((resp) => {
              this.launching = false
              // 重新加载详情
              this.loadReportDetailFromApi(reportId, flowId)
              this.$message({
                type: 'success',
                message: '发起成功'
              })
              // 触发刷新事件
              this.$emit('refresh')
            })
            .asyncErrorCatch((err) => {
              console.error('发起失败:', err)
              this.launching = false
              this.$message({
                type: 'error',
                message: '发起失败，请重试'
              })
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '取消发起审批'
          })
        })
    },
    handleResatrtLaunch() {
      const reportId = this.reportDetail.reportId || this.reportDetail.id || this.detail.reportId || this.detail.id

      if (!reportId) {
        this.$message.error('缺少报告ID，无法发起审批')
        return
      }
      this.$confirm('确定重新发起吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 按照保存时的格式转换 nodeList
          const nodeList = this.approvalWorkflowSteps.map((step, index) => ({
            nodeName: step.name,
            assignees: step.handlers,
            nodeOrder: index + 1
          }))
          const submitData = {
            reportId: reportId,
            ...this.editFormData,
            flowId: '',
            title: this.editingProcessTitle || '',
            processTitle: this.editFormData.processTitle || '',
            explanation: '',
            nodeList: nodeList,
            userId: getUserId()
          }
          const request = {
            ...api.RESTART_REPORT_APPROVAL,
            params: submitData,
            disableSuccessMsg: true
          }

          this.launching = true
          this.$request(request)
            .asyncThen((resp) => {
              this.launching = false
              // 重新加载详情
              const currentFlowId = this.detail.flowId || this.reportDetail.flowId
              this.loadReportDetailFromApi(reportId, currentFlowId)
              this.$message({
                type: 'success',
                message: '发起成功'
              })
              // 触发刷新事件
              this.$emit('refresh')
            })
            .asyncErrorCatch((err) => {
              console.error('发起失败:', err)
              this.launching = false
              this.$message({
                type: 'error',
                message: '发起失败，请重试'
              })
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '取消发起审批'
          })
        })
    },
    // 加载审批人（用于草稿状态显示和编辑模式）
    loadApprovalUsers(flowId) {
      if (!flowId) {
        return Promise.resolve()
      }
      const request = {
        ...api.GET_REPORT_APPROVAL_USERS,
        params: {
          flowId: flowId
        },
        disableSuccessMsg: true
      }
      return this.$request(request)
        .asyncThen((resp) => {
          console.log('获取审批流程信息:', resp)
          // 记录可继续发起的标识及流程ID
          const meta = this.parseApprovalUsersMeta(resp)
          this.approvalCanSend = !!meta.canSend
          this.approvalFlowIdFromUsers = meta.flowId || flowId || ''
          // 同步流程主题（接口返回为准）
          if (meta.title) {
            this.reportDetail.processTitle = meta.title
            this.showTopDetail.processTitle = meta.title
            // 编辑态下也同步到表单，避免保存后显示旧值
            if (this.isEditMode) {
              this.editFormData.processTitle = meta.title
            }
          }
          this.fillApprovalUsersData(resp, this.approvalWorkflowSteps)
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批流程信息失败:', err)
          throw err
        })
    },
    // 提取审批人员接口返回的流程ID/流程主题与可发起标识
    parseApprovalUsersMeta(resp) {
      const meta = { flowId: '', canSend: false, title: '' }
      const candidate = resp?.data ?? resp
      const pickFrom = (obj) => {
        if (!obj || Array.isArray(obj)) return
        meta.flowId = meta.flowId || obj.flowId || obj.id || obj.flowid || ''
        meta.canSend = meta.canSend || obj.canSend || obj.canResend || false
        meta.title = meta.title || obj.progressTitle || obj.processTitle || obj.title || ''
      }
      if (candidate && !Array.isArray(candidate)) {
        pickFrom(candidate)
        if (candidate.data && !Array.isArray(candidate.data)) {
          pickFrom(candidate.data)
        }
      }
      return meta
    },
    // 填充审批人数据（按照report.vue的逻辑）
    fillApprovalUsersData(resp, workflowSteps) {
      // 提取节点列表
      let nodeList = []
      let data = null
      if (Array.isArray(resp.data)) {
        data = resp.data
      } else if (Array.isArray(resp.data?.data)) {
        data = resp.data.data
      } else if (Array.isArray(resp.data?.result)) {
        data = resp.data.result
      } else if (Array.isArray(resp)) {
        data = resp
      } else if (resp.data && !Array.isArray(resp.data)) {
        data = resp.data
      }

      if (Array.isArray(data)) {
        nodeList = data
      } else if (data && Array.isArray(data.data)) {
        nodeList = data.data
      } else if (data && Array.isArray(data.result)) {
        nodeList = data.result
      } else if (data && Array.isArray(data.nodeList)) {
        nodeList = data.nodeList
      } else if (data && Array.isArray(data.flowNodes)) {
        nodeList = data.flowNodes
      }

      // 遍历节点列表，根据 nodeName 匹配到对应的审批环节并填充人员信息
      if (nodeList && nodeList.length > 0) {
        nodeList.forEach((nodeItem) => {
          const nodeName = nodeItem.nodeName || nodeItem.node || ''
          if (!nodeName) {
            return
          }

          // 找到对应的审批环节
          const step = workflowSteps.find(s => s.name === nodeName)
          if (!step) {
            return
          }

          // 获取 assignees 数组
          const assignees = nodeItem.assignees || []
          if (!Array.isArray(assignees) || assignees.length === 0) {
            return
          }

          // 从 assignees 中提取人员信息（将 id 统一转换为 userId）
          const handlerInfos = assignees.map(assignee => {
            const userId = assignee.userId || assignee.id || ''
            return {
              userId: userId,
              username: assignee.username || '',
              userNumber: assignee.userNumber || assignee.account || ''
            }
          }).filter(item => item.userId)

          // 如果有处理人信息，设置到 handlers 中（handlers 存储 userId 数组）
          if (handlerInfos.length > 0) {
            step.handlers = handlerInfos.map(h => h.userId).filter(Boolean)
            // 设置 options，确保已选择的人员信息在选项中（用于下拉框显示）
            step.options = handlerInfos.map(h => ({
              userId: h.userId,
              username: h.username || '',
              userNumber: h.userNumber || ''
            })).filter(opt => opt.userId)
          }
        })
      }
    },
    // 获取处理人名称（用于只读显示）
    getHandlerName(handlerId, options) {
      const handler = options.find(opt => opt.userId === handlerId)
      return handler ? handler.username : handlerId
    },
    // 远程搜索人员（用于编辑模式）
    handleRemoteSearch(query, stepIndex) {
      const step = this.approvalWorkflowSteps[stepIndex]
      if (!query || query.trim() === '') {
        // 空查询时，只保留已选择的人员在选项中
        if (step.handlers && step.handlers.length > 0) {
          const selectedOptions = step.options.filter((opt) => step.handlers.includes(opt.userId))
          step.options = selectedOptions
        } else {
          step.options = []
        }
        return
      }

      step.loading = true
      const trimmedQuery = query.trim()
      const 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
          }
          // 转换为选项格式
          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)
          const existingIds = new Set(step.handlers || [])
          const filteredUsers = users.filter((user) => !existingIds.has(user.userId))
          const selectedOptions = (step.options || []).filter(
            (opt) => opt.userId && step.handlers && step.handlers.includes(opt.userId)
          )
          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) => step.handlers.includes(opt.userId))
            step.options = selectedOptions
          } else {
            step.options = []
          }
          step.loading = false
        })
    },
    // 处理人员选择变化（用于编辑模式）
    handleHandlerChange(stepIndex, selectedIds) {
      // 提交时通过快照对比判断是否变化
    },
    // 处理重新发起按钮点击（已拒绝状态）
    handleResendApproval() {
      // 直接调用重新发起接口（
      this.handleResatrtLaunch()
    },
    handleProcessTitleChange() {
      // 提交时通过快照对比判断是否变化
    },
    // 加载审批人（用于发起弹窗，草稿和已拒绝状态）
    loadLaunchApprovalUsers(flowId) {
      if (!flowId) {
        console.error('缺少流程ID，无法获取审批人员信息')
        return
      }
      const request = {
        ...api.GET_REPORT_APPROVAL_USERS,
        params: {
          flowId: flowId
        },
        disableSuccessMsg: true
      }
      this.$request(request)
        .asyncThen((resp) => {
          console.log('获取审批流程信息:', resp)
          // 使用 fillResendApprovalData 填充数据（它会处理流程主题和审批人）
          this.fillResendApprovalData(resp)
        })
        .asyncErrorCatch((err) => {
          console.error('获取审批流程信息失败:', err)
        })
    },
    // 修改功能：进入编辑模式
    async handleEdit() {
      // 保存原始数据
      this.originalReportDetail = JSON.parse(JSON.stringify(this.reportDetail))
      // 填充表单数据
      this.editFormData = {
        title: this.reportDetail.title || '',
        manufacturerName: this.reportDetail.manufacturerName || '',
        modelName: this.reportDetail.modelName || '',
        manufacturerAbbreviation: this.reportDetail.manufacturerAbbreviation || '',
        modelAbbreviation: this.reportDetail.modelAbbreviation || '',
        productNumber: this.reportDetail.productNumber || '',
        module: this.reportDetail.module || '',
        plate: this.reportDetail.plate || '',
        platform: this.reportDetail.platform || '',
        series: this.reportDetail.series || '',
        marketSegment: this.reportDetail.marketSegment || '',
        projectName: this.reportDetail.projectName || '',
        projectNumber: this.reportDetail.projectNumber || '',
        explanation: this.reportDetail.explanation || '',
        fileUrl: this.reportDetail.fileUrl || this.reportDetail.filePath || '',
        fileName: this.reportDetail.fileName || '',
        processTitle: this.reportDetail.processTitle || this.showTopDetail.processTitle || ''
      }
      // 如果有文件路径，显示在文件列表中
      if (this.reportDetail.fileUrl || this.reportDetail.filePath) {
        this.fileList = [
          {
            name: this.reportDetail.fileName || '文件',
            url: this.reportDetail.fileUrl || this.reportDetail.filePath
          }
        ]
      } else {
        this.fileList = []
      }
      this.selectedFile = null
      this.isEditMode = true
      // 如果是草稿状态，确保审批人员/流程主题已回填后再记录快照（避免回填触发“误判修改”）
      if (this.reportDetail.status === 'DRAFT') {
        const flowId = this.detail.flowId || this.reportDetail.flowId
        if (flowId) {
          try {
            await this.loadApprovalUsers(flowId)
          } catch (e) {
            // ignore
          }
        }
      }
      this.originalEditSnapshot = this.buildEditSnapshot()
    },
    // 取消编辑：恢复只读状态
    handleCancelEdit() {
      // 恢复原始数据
      this.reportDetail = JSON.parse(JSON.stringify(this.originalReportDetail))
      // 清空表单数据
      this.editFormData = {
        title: '',
        manufacturerName: '',
        modelName: '',
        manufacturerAbbreviation: '',
        modelAbbreviation: '',
        productNumber: '',
        module: '',
        plate: '',
        platform: '',
        series: '',
        marketSegment: '',
        projectName: '',
        projectNumber: '',
        explanation: '',
        fileUrl: '',
        fileName: '',
        processTitle: ''
      }
      this.fileList = []
      this.selectedFile = null
      this.originalEditSnapshot = null
      this.isEditMode = false
      // 清除表单验证
      if (this.$refs.editForm) {
        this.$refs.editForm.clearValidate()
      }
    },
    // 文件变化
    handleFileChange(file, fileList) {
      const allowedTypes = ['.doc', '.pdf', '.xls', '.xlsx', '.ppt', '.pptx']
      const fileName = file.name.toLowerCase()
      const isValidType = allowedTypes.some((type) => fileName.endsWith(type))

      if (!isValidType) {
        this.$message.error('不支持的文件类型，仅支持 .doc .pdf .xls .xlsx .ppt .pptx')
        this.$refs.upload.handleRemove(file)
        return false
      }

      this.selectedFile = file && file.raw ? file.raw : null
      this.fileList = fileList.slice(-1)
    },
    // 文件移除
    handleFileRemove(file, fileList) {
      this.selectedFile = null
      this.fileList = []
    },
    // 文件上传
    handleFileUpload() {
      if (this.uploading || !this.selectedFile) {
        if (!this.selectedFile) {
          return Promise.resolve(null)
        }
        return Promise.resolve(null)
      }

      const file = this.selectedFile
      const formData = new FormData()
      formData.append('file', file)
      formData.append('createBy', getUserId())

      const request = {
        ...api.TEST_FILE_UPLOAD,
        params: formData,
        disableSuccessMsg: true
      }

      this.uploading = true
      const loadingInstance = this.$loading({
        lock: true,
        text: '正在上传文件，请稍候...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      return this.$upload(request, null, false)
        .then((resp) => {
          console.log('文件上传成功:', resp)
          loadingInstance.close()
          let fileUrl = ''
          if (resp.data && resp) {
            const url = resp.data
            fileUrl = url
            this.editFormData.fileUrl = fileUrl
          }
          return fileUrl
        })
        .catch((err) => {
          console.error('文件上传失败:', err)
          loadingInstance.close()
          this.$message.error('文件上传失败，请重试')
          throw err
        })
        .finally(() => {
          if (loadingInstance) {
            loadingInstance.close()
          }
          this.uploading = false
        })
    },
    // 保存功能
    handleSave() {
      // 表单验证
      if (this.$refs.editForm) {
        this.$refs.editForm.validate((valid) => {
          if (!valid) {
            return false
          }
          this.submitEdit()
        })
      } else {
        this.submitEdit()
      }
    },
    buildEditSnapshot() {
      const normalize = (v) => (v == null ? '' : v)
      const normalizeSteps = (steps) =>
        (steps || []).map((s) => ({
          name: s.name,
          handlers: (s.handlers || []).filter(Boolean).slice().sort()
        }))
      // 仅用于对比的字段集合
      return {
        form: {
          title: normalize(this.editFormData?.title),
          manufacturerName: normalize(this.editFormData?.manufacturerName),
          modelName: normalize(this.editFormData?.modelName),
          manufacturerAbbreviation: normalize(this.editFormData?.manufacturerAbbreviation),
          modelAbbreviation: normalize(this.editFormData?.modelAbbreviation),
          productNumber: normalize(this.editFormData?.productNumber),
          module: normalize(this.editFormData?.module),
          plate: normalize(this.editFormData?.plate),
          platform: normalize(this.editFormData?.platform),
          series: normalize(this.editFormData?.series),
          marketSegment: normalize(this.editFormData?.marketSegment),
          projectName: normalize(this.editFormData?.projectName),
          projectNumber: normalize(this.editFormData?.projectNumber),
          explanation: normalize(this.editFormData?.explanation),
          fileUrl: normalize(this.editFormData?.fileUrl),
          fileName: normalize(this.editFormData?.fileName)
        },
        processTitle: (this.editFormData?.processTitle || '').trim(),
        steps: normalizeSteps(this.approvalWorkflowSteps)
      }
    },
    diffEditSnapshot(original, current) {
      const isSame = (a, b) => JSON.stringify(a) === JSON.stringify(b)
      const baseChanged =
        !original ||
        !isSame(original.form, current.form) ||
        !!this.selectedFile // 新选中文件一定算基础变更
      const approvalChanged =
        !original ||
        original.processTitle !== current.processTitle ||
        !isSame(original.steps, current.steps)
      return { baseChanged, approvalChanged }
    },
    hasAnyEditChange() {
      const current = this.buildEditSnapshot()
      const { baseChanged, approvalChanged } = this.diffEditSnapshot(this.originalEditSnapshot, current)
      return baseChanged || approvalChanged
    },
    // 提交编辑
    submitEdit() {
      const submitData = async () => {
        try {
          // 没有任何修改时，不调用接口
          if (!this.hasAnyEditChange()) {
            this.isEditMode = false
            this.$message({
              type: 'info',
              message: '未修改，无需保存'
            })
            return
          }

          // 如果有新文件，先上传文件获取文件路径
          if (this.selectedFile) {
            const fileUrl = await this.handleFileUpload()
            this.editFormData.fileUrl = fileUrl || ''
            this.editFormData.fileName = this.selectedFile.name
          }

          const reportId = this.reportDetail.reportId || this.reportDetail.id
          if (!reportId) {
            this.$message.error('缺少报告ID')
            return
          }

          const includeApprovalInSave = !this.canResend
          const shouldUpdateApprovalProcess = this.canResend

          const { processTitle, ...restForm } = this.editFormData
          const params = {
            reportId: reportId,
            flowId: this.detail.flowId,
            ...restForm,
            createBy: getUserId(),
            userId: getUserId()
          }

          if (includeApprovalInSave) {
            params.processTitle = processTitle || ''
            params.nodeList = this.approvalWorkflowSteps.map((step, index) => ({
              nodeName: step.name,
              assignees: step.handlers,
              nodeOrder: index + 1
            }))
          }

          this.saving = true
          // 提交时对比快照判断是否有变化（不依赖watch/change）
          const currentSnap = this.buildEditSnapshot()
          const { baseChanged, approvalChanged } = this.diffEditSnapshot(this.originalEditSnapshot, currentSnap)
          // 当 canResend 为 true 时（shouldUpdateApprovalProcess 为 true），审批环节和流程主题的修改应该走 updateApprovalProcess
          // 当 canResend 为 false 时（includeApprovalInSave 为 true），审批环节和流程主题的修改应该包含在 EDIT_REPORT 中
          const needUpdateApprovalProcess =
            shouldUpdateApprovalProcess && approvalChanged
          // 判断是否需要调用 EDIT_REPORT：
          // 1. 如果有基础变化（文件或表单字段），需要调用 EDIT_REPORT
          // 2. 如果 includeApprovalInSave 为 true 且有审批变化，需要调用 EDIT_REPORT（将审批数据包含在保存中）
          // 3. 如果 shouldUpdateApprovalProcess 为 true 且只有审批变化（没有基础变化），不应该调用 EDIT_REPORT
          const shouldOnlyUpdateApprovalProcess = shouldUpdateApprovalProcess && approvalChanged && !baseChanged
          const needUpdateReportBase =
            !shouldOnlyUpdateApprovalProcess && (
              baseChanged ||
              (includeApprovalInSave && approvalChanged)
            )
          
          // 如果是草稿状态（includeApprovalInSave 为 true）且流程主题被修改，先调用 EDIT_APPROVAL_PROCESS_TITLE
          if (includeApprovalInSave && approvalChanged && this.detail.flowId) {
            const originalProcessTitle = (this.originalEditSnapshot?.processTitle || '').trim()
            const currentProcessTitle = (currentSnap.processTitle || '').trim()
            if (originalProcessTitle !== currentProcessTitle) {
              const updateTitleRequest = {
                ...api.EDIT_APPROVAL_PROCESS_TITLE,
                params: {
                  flowId: this.detail.flowId,
                  title: currentProcessTitle
                },
                disableSuccessMsg: true
              }
              // 先调用更新流程主题接口，成功后再调用编辑报告接口
              await this.$request(updateTitleRequest)
                .asyncThen(() => {
                  console.log('流程主题更新成功')
                })
                .asyncErrorCatch((err) => {
                  console.error('更新流程主题失败:', err)
                  this.$message.error('更新流程主题失败，请重试')
                  throw err
                })
            }
          }
          
          if (needUpdateReportBase) {
            console.log('needUpdateReportBase', needUpdateReportBase)
            const request = {
              ...api.EDIT_REPORT,
              params: params,
              disableSuccessMsg: true
            }
            await this.$request(request).asyncThen(() => {})
          }

          if (needUpdateApprovalProcess) {
            console.log('needUpdateApprovalProcess', needUpdateApprovalProcess)
            await this.updateApprovalProcess()
          }

          this.isEditMode = false
          // 重新加载详情 + 草稿时刷新审批环节/流程主题（对齐 handleResatrtLaunch 的“重新获取”效果）
          const currentFlowId = this.detail.flowId || this.reportDetail.flowId
          this.loadReportDetailFromApi(reportId, currentFlowId)
          if (this.reportDetail.status === 'DRAFT' && currentFlowId) {
            // 重新获取审批环节与流程主题
            this.loadApprovalUsers(currentFlowId)
          }
          // 更新快照（保存后以当前值为基准）
          this.originalEditSnapshot = this.buildEditSnapshot()
          this.$message({
            type: 'success',
            message: '保存成功'
          })
          // 触发刷新事件（保存后不返回上一级）
          this.$emit('refresh', { keepOpen: true })
        } catch (err) {
          console.error('保存失败:', err)
          this.$message.error(err?.message || '保存失败，请重试')
        } finally {
          this.saving = false
        }
      }

      submitData()
    },
    // 更新审批环节（直送模式下单独调用流程修改接口）
    updateApprovalProcess() {
      const flowId = this.detail.flowId || this.reportDetail.flowId
      if (!flowId) {
        this.$message.error('缺少流程ID，无法保存审批环节')
        return Promise.reject(new Error('缺少流程ID'))
      }

      const nodeList = this.approvalWorkflowSteps.map((step, index) => ({
        nodeName: step.name,
        assignees: step.handlers,
        nodeOrder: index + 1
      }))

      const request = {
        ...api.EDIT_APPROVAL_PROCESS,
        params: {
          nodeList: nodeList,
          flowId: flowId,
          title: this.editFormData.processTitle || '',
          userId: getUserId()
        },
        disableSuccessMsg: true
      }

      return this.$request(request)
        .asyncThen(() => {})
        .asyncErrorCatch((err) => {
          console.error('更新审批环节失败:', err)
          this.$message.error(err?.message || '更新审批环节失败，请重试')
          throw err
        })
    },
    // 开始编辑流程主题
    handleEditProcessTitle() {
      this.isEditingProcessTitle = true
      this.editingProcessTitle = this.showTopDetail.processTitle || this.detail.processTitle || this.reportDetail.processTitle || ''
    },
    // 取消编辑流程主题
    handleCancelProcessTitle() {
      this.isEditingProcessTitle = false
      this.editingProcessTitle = ''
    },
    // 保存流程主题
    handleSaveProcessTitle() {
      if (!this.detail || !this.detail.flowId) {
        this.$message.error('缺少流程ID，无法保存')
        return
      }

      const newTitle = (this.editingProcessTitle || '').trim()
      if (!newTitle) {
        this.$message.warning('流程主题不能为空')
        return
      }

      this.$confirm(`确认修改主题为${newTitle}吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          const request = {
            ...api.EDIT_APPROVAL_PROCESS_TITLE,
            params: {
              flowId: this.detail.flowId,
              title: newTitle
            },
            disableSuccessMsg: true
          }

          this.$request(request)
            .asyncThen((resp) => {
              this.showTopDetail.processTitle = newTitle
              this.isEditingProcessTitle = false
              this.editingProcessTitle = ''
              this.$message({
                message: '修改成功',
                type: 'success'
              })
              // 重新加载详情
              if (this.detail.flowId) {
                this.getApprovalSpet(this.detail.flowId)
              }
            })
            .asyncErrorCatch((err) => {
              console.error('修改流程主题失败:', err)
              this.$message({
                message: err.message || '修改失败，请重试',
                type: 'error'
              })
            })
        })
        .catch(() => {
          // 取消操作
        })
    }
  }
}
</script>

<style lang="scss" scoped>
.report-detail {
  width: 100%;
  height: 100%;
  background: #fff;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  padding: 0;
  box-sizing: border-box;
  overflow-y: auto;

  .detail-panel {
    width: 100%;
    // max-width: 1200px;
    background: #ffffff;
    border-radius: 12px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  .detail-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 24px 32px 16px 32px;
    border-bottom: 1px solid #ebeef5;

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

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

    .back-button {
      display: flex;
      align-items: center;
      font-size: 14px;
      color: #606266;

      ::v-deep .el-icon-arrow-left {
        font-size: 16px;
      }
    }

    .header-info {
      display: flex;
      flex-direction: column;
      gap: 4px;

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

      .subtitle {
        font-size: 14px;
        color: #909399;
      }
    }
  }

  .detail-content {
    padding: 24px 32px 40px 32px;
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: auto;
    gap: 24px;

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

  .block-section {
    border-radius: 8px;
    padding: 24px 24px 16px 24px;

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

  .info-grid {
    // 基础样式
    .label {
      font-size: 16px;
      color: #909399;
    }

    .value {
      font-size: 16px;
      color: #303133;
      font-weight: 500;
    }

    // Flex 布局样式（用于基础信息部分：.info-item-full 和 .info-row）
    .info-item-full {
      display: flex;
      gap: 16px 24px;
      margin-bottom: 16px;
      .label {
        min-width: 100px;
      }
      .value {
        flex: 1;
      }

      .process-title-value-wrapper {
        display: flex;
        align-items: center;
        gap: 8px;

        .process-title-edit-icon {
          cursor: pointer;
          color: #909399;
          font-size: 14px;
          transition: color 0.3s;
          flex-shrink: 0;

          &:hover {
            color: #409eff;
          }
        }
      }

      .process-title-input-wrapper {
        flex: 1;

        .process-title-input {
          ::v-deep .el-input__suffix {
            display: flex;
            align-items: center;
            gap: 8px;
            padding-right: 8px;

            .process-title-icon {
              cursor: pointer;
              font-size: 16px;
              transition: color 0.3s;

              &.el-icon-check {
                color: #67c23a;

                &:hover {
                  color: #529b2e;
                }
              }

              &.el-icon-close {
                color: #909399;

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

    .info-row {
      display: flex;
      gap: 16px 24px;
      margin-bottom: 16px;

      .info-item {
        flex: 1;
        display: flex;
        gap: 16px 24px;
        .label {
          min-width: 100px;
        }
      }
    }
  }

  // 网格布局样式（用于报告信息部分：当 .info-grid 的第一个直接子元素是 .info-item 时）
  // 通过检查第一个子元素是否为 .info-item（而不是 .info-item-full 或 .info-row）来判断
  // 由于 CSS 限制，使用 :has() 选择器，如果不支持则通过 JavaScript 动态添加类名
  .info-grid:not(:has(.info-item-full)):not(:has(.info-row)) {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    border: 1px solid #ebeef5;
    border-radius: 4px;
    overflow: hidden;

    > .info-item {
      display: flex;
      flex-direction: row;
      border-right: 1px solid #ebeef5;
      border-bottom: 1px solid #ebeef5;

      &:nth-child(2n) {
        border-right: none;
      }

      &:nth-last-child(-n + 2) {
        border-bottom: none;
      }

      .label {
        font-size: 16px;
        color: #303133;
        background: #f5f7fa;
        padding: 12px 16px;
        min-width: 140px;
        width: 140px;
        text-align: right;
        border-right: 1px solid #ebeef5;
        font-weight: 500;
        flex-shrink: 0;
      }

      .value {
        font-size: 14px;
        color: #303133;
        padding: 12px 16px;
        flex: 1;
        word-break: break-word;
      }
    }
  }

  .description-block {
    display: flex;
    gap: 8px;
    font-size: 14px;
    color: #606266;
    margin-top: 16px;

    .label {
      color: #909399;
    }

    .value {
      flex: 1;
      white-space: pre-line;
      word-break: break-word;
    }
  }

  .approval-timeline {
    padding: 20px 0;

    ::v-deep .el-timeline {
      padding-left: 0;

      .el-timeline-item {
        padding-bottom: 24px;

        &:last-child {
          padding-bottom: 0;
        }

        .el-timeline-item__node {
          width: 12px;
          height: 12px;
          left: 0;
          top: 4px;
          border: 2px solid #fff;
          box-shadow: 0 0 0 2px #409eff;
        }

        .el-timeline-item__wrapper {
          top: 0;
          padding-left: 28px;

          .el-timeline-item__content {
            padding-top: 0;
          }
        }
      }
    }
  }

  .timeline-item-content {
    display: flex;
    flex-direction: column;
    gap: 0;

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

    .node-content {
      background: #f4f7fc;
      border-radius: 4px;
      padding: 12px;
      display: flex;
      flex-direction: column;
      gap: 8px;
    }

    .node-info {
      display: flex;
      flex-direction: column;
      gap: 4px;
      font-size: 13px;
      color: #606266;
    }

    .node-user {
      color: #303133;
      font-weight: 500;
    }

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

    .node-status {
      display: inline-block;
      font-size: 13px;
      font-weight: 500;
      border-radius: 2px;
      width: fit-content;

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

      &.status-msg {
        color: #409eff;
        background: transparent;
      }

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

      &.status-approving,
      &.status-pending {
        color: #e6a23c;
        background: transparent;
      }

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

    .node-opinion {
      font-size: 13px;
      color: #000;
      line-height: 1.6;
    }
  }

  .empty-progress {
    text-align: center;
    padding: 40px 20px;
    color: #909399;
    font-size: 14px;

    .empty-text {
      display: inline-block;
    }
  }
}

.report-detail-fade-enter-active,
.report-detail-fade-leave-active {
  transition: opacity 0.2s ease;
}

.report-detail-fade-enter,
.report-detail-fade-leave-to {
  opacity: 0;
}

::v-deep .el-timeline-item__tail {
  left: 7px;
  top: 3px;
}

.dialog-body-wrapper {
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 10px;
}

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

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

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

              ::v-deep .el-tag {
                margin: 2px 4px 2px 0;
              }
            }

            .handler-display {
              display: flex;
              flex-wrap: wrap;
              gap: 8px;

              .handler-tag {
                display: inline-block;
                padding: 4px 12px;
                background: #f0f2f5;
                border: 1px solid #e4e7ed;
                border-radius: 4px;
                font-size: 14px;
                color: #606266;
              }
            }

            .handler-empty {
              color: #909399;
              font-size: 14px;
            }
          }
        }
      }
    }
  }
}

.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;
  text-align: right !important;
}

::v-deep .el-upload-dragger {
  width: 100%;
  height: 180px;
}

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

.launch-section {
  margin-top: 24px;
}

.launch-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.page-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 16px 32px;
  background: #fff;
  border-top: 1px solid #ebeef5;
  flex-shrink: 0;
  position: relative;
  z-index: 10;

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

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

.return-node-dialog-content {
  padding: 10px 0;

  .empty-hint {
    text-align: center;
    padding: 40px 0;
    color: #909399;
    font-size: 14px;
  }

  .return-node-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: 300px;
    overflow-y: auto;
    margin-bottom: 16px;

    .return-node-item {
      display: flex;
      align-items: center;
      padding: 12px;
      border: 1px solid #ebeef5;
      border-radius: 4px;
      transition: all 0.3s;

      &:hover {
        border-color: #409eff;
        background: #ecf5ff;
      }

      .node-info {
        display: flex;
        flex-direction: column;
        gap: 4px;
        margin-left: 8px;

        .node-title {
          font-size: 14px;
          font-weight: 500;
          color: #303133;
        }

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

  .return-opinion-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid #ebeef5;

    .opinion-label {
      margin-bottom: 8px;
      font-size: 14px;
      color: #606266;
      font-weight: 500;
    }
  }
}
::v-deep .el-button {
  line-height: 0.85 !important;
}
</style>
