WXL
4 天以前 dc082351978a1e9f75d7a1471a0ca7ebeac552a5
src/views/business/course/index.vue
@@ -6,50 +6,53 @@
        <div class="timeline-section">
          <div class="section-header">
            <h3>捐献进程时间线</h3>
            <el-tag :type="getOverallStatusTag(caseInfo.status)">
              {{ getStatusText(caseInfo.status) }}
            </el-tag>
          </div>
          <div class="timeline-container">
            <div
              v-for="stage in processStages"
              :key="stage.key"
              class="timeline-item"
              :class="{
                'active': activeStage === stage.key,
                'completed': stage.status === 'completed',
                'in-progress': stage.status === 'in_progress',
                'pending': stage.status === 'pending'
              }"
              @click="handleStageClick(stage)"
            >
              <div class="timeline-marker">
                <i v-if="stage.status === 'completed'" class="el-icon-check"></i>
                <i v-else-if="stage.status === 'in_progress'" class="el-icon-loading"></i>
                <i v-else class="el-icon-time"></i>
              </div>
              <div class="timeline-content">
                <div class="stage-header">
                  <span class="stage-name">{{ stage.name }}</span>
                  <el-tag
                    size="small"
                    :type="getStageStatusTag(stage.status)"
                  >
                    {{ getStageStatusText(stage.status) }}
                  </el-tag>
          <div class="timeline-scroll-container">
            <div class="timeline-container">
              <div
                v-for="stage in processStages"
                :key="stage.key"
                class="timeline-item"
                :class="{
                  active: stage.status == 'active',
                  completed: stage.status == 'completed',
                  progress: stage.status == 'progress',
                  pending: stage.status == 'pending'
                }"
                @click="handleStageClick(stage)"
              >
                <div class="timeline-marker">
                  <i
                    v-if="stage.status == 'completed'"
                    class="el-icon-check"
                  ></i>
                  <i
                    v-else-if="stage.status == 'progress'"
                    class="el-icon-loading"
                  ></i>
                  <i v-else class="el-icon-time"></i>
                </div>
                <div class="stage-info">
                  <div v-if="stage.completeTime" class="time-info">
                    <span>完成时间: {{ formatTime(stage.completeTime) }}</span>
                <div class="timeline-content">
                  <div class="stage-header">
                    <span class="stage-name">{{ stage.name }}</span>
                    <dict-tag
                      :options="dict.type[stage.dict]"
                      :value="stage.state"
                    />
                  </div>
                  <div v-if="stage.updateTime" class="time-info">
                    <span>最近更新: {{ formatTime(stage.updateTime) }}</span>
                  </div>
                  <div v-if="stage.operator" class="operator-info">
                    <span>负责人: {{ stage.operator }}</span>
                  <div class="stage-info">
                    <div v-if="stage.createtime" class="time-info">
                      创建时间: {{ formatTime(stage.createtime) }}
                    </div>
                    <div v-if="stage.updateTime" class="time-info">
                      最近更新: {{ formatTime(stage.updateTime) }}
                    </div>
                    <div v-if="stage.operator" class="operator-info">
                      负责人: {{ stage.operator }}
                    </div>
                  </div>
                </div>
              </div>
@@ -57,103 +60,21 @@
          </div>
        </div>
        <!-- 右侧内容区域 -->
        <!-- 右侧内容 -->
        <div class="content-section">
          <!-- 案例基本信息 -->
          <div class="basic-info-section">
            <div class="section-header">
              <h3>案例基本信息</h3>
              <el-button
                type="primary"
                size="small"
                @click="handleEditBasicInfo"
              >
                编辑信息
              </el-button>
            </div>
          <case-basic-info :case-id="caseId" :show-attachment="true" />
            <el-descriptions :column="2" border>
              <el-descriptions-item label="住院号">
                {{ caseInfo.caseNo }}
              </el-descriptions-item>
              <el-descriptions-item label="住院号">
                {{ caseInfo.hospitalNo }}
              </el-descriptions-item>
              <el-descriptions-item label="捐献者姓名">
                {{ caseInfo.donorName }}
              </el-descriptions-item>
              <el-descriptions-item label="性别">
                <dict-tag
                  :options="dict.type.sys_user_sex"
                  :value="parseInt(caseInfo.gender)"
                />
              </el-descriptions-item>
              <el-descriptions-item label="年龄">
                {{ caseInfo.age }} 岁
              </el-descriptions-item>
              <el-descriptions-item label="血型">
                <dict-tag
                  :options="dict.type.sys_BloodType"
                  :value="caseInfo.bloodType"
                />
              </el-descriptions-item>
              <el-descriptions-item label="疾病诊断">
                {{ caseInfo.diagnosis }}
              </el-descriptions-item>
              <el-descriptions-item label="案例状态">
                <el-tag :type="getOverallStatusTag(caseInfo.status)">
                  {{ getStatusText(caseInfo.status) }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="创建时间">
                {{ formatTime(caseInfo.createTime) }}
              </el-descriptions-item>
              <el-descriptions-item label="登记人">
                {{ caseInfo.registrant }}
              </el-descriptions-item>
              <el-descriptions-item label="当前阶段">
                {{ getCurrentStageName() }}
              </el-descriptions-item>
            </el-descriptions>
          </div>
          <!-- 阶段详情内容 -->
          <div class="stage-detail-section">
            <div class="section-header">
              <h3>{{ activeStageName }} - 阶段详情</h3>
              <div class="stage-actions">
                <el-button
                  v-if="activeStageData.status !== 'completed'"
                  type="success"
                  size="small"
                  @click="handleCompleteStage"
                >
                  完成阶段
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  @click="handleViewDetail"
                >
                  查看详情
                </el-button>
                <el-button
                  v-if="activeStageData.status === 'completed'"
                  type="warning"
                  size="small"
                  @click="handleModifyStage"
                >
                  修改信息
                </el-button>
              </div>
            </div>
            <!-- 动态阶段内容 -->
            <div class="stage-content">
            <div class="stage-content-wrapper">
              <component
                :is="getStageComponent()"
                :stageData="activeStageData"
                :caseInfo="caseInfo"
                :infoid="caseId"
              />
            </div>
          </div>
@@ -164,298 +85,200 @@
</template>
<script>
import { getDonationProcessDetail } from './donationProcess';
import DonorMaintenanceStage from './components/DonorMaintenanceStage';
import MedicalAssessmentStage from './components/MedicalAssessmentStage';
import DeathJudgmentStage from './components/DeathJudgmentStage';
import DonationConfirmStage from './components/DonationConfirmStage';
import EthicalReviewStage from './components/EthicalReviewStage';
import OrganAllocationStage from './components/OrganAllocationStage';
import OrganProcurementStage from './components/OrganProcurementStage';
import OrganUtilizationStage from './components/OrganUtilizationStage';
// ===================== 字典 Label → UI 主题 =====================
function mapDictLabelToTheme(label) {
  if (!label) return "pending";
  const l = label.trim();
  // 待 XX
  if (/^待/.test(l)) {
    return "progress";
  }
  // XX中
  if (/中$/.test(l)) {
    return "active";
  }
  // 完成 / 完成XX
  if (/完成/.test(l)) {
    return "completed";
  }
  // 弃用 / 放弃
  if (/弃用|放弃/.test(l)) {
    return "danger";
  }
  return "pending";
}
import { getDonatebaseinfoflow } from "@/api/project/donatebaseinfo";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import DonorMaintenanceStage from "./components/DonorMaintenanceStage";
import DeathJudgmentStage from "./components/DeathJudgmentStage";
import MedicalAssessmentStage from "./components/MedicalAssessmentStage";
import DonationConfirmStage from "./components/DonationConfirmStage";
import EthicalReviewStage from "./components/EthicalReviewStage";
import OrganAllocationStage from "./components/OrganAllocationStage";
import OrganProcurementStage from "./components/OrganProcurementStage";
import OrganUtilizationStage from "./components/OrganUtilizationStage";
import dayjs from "dayjs";
// ============== 字典映射(你后面自己改) ==============
const STAGE_DICT_MAP = {
  donatemaintenance: "maintain_type",
  deathinfo: "decide_type",
  medicalevaluation: "state_Evaluation",
  relativesconfirmation: "affirm_type",
  donateflowcharts: "sys_ethical",
  donateorgansService: "allocation_Status",
  donationwitness: "Obtain_status",
  donatecompletioninfo: "utilize_statue"
};
// state -> 流程状态
const STATE_MAP = {
  0: "pending",
  1: "progress",
  2: "completed",
  3: "terminated"
};
// 阶段配置
const STAGE_CONFIG = [
  { key: "donor_maintenance", name: "供者维护", apiKey: "donatemaintenance" },
  { key: "death_judgment", name: "死亡判定", apiKey: "deathinfo" },
  { key: "medical_assessment", name: "医学评估", apiKey: "medicalevaluation" },
  {
    key: "donation_confirm",
    name: "捐献确认",
    apiKey: "relativesconfirmation"
  },
  { key: "ethical_review", name: "伦理审查", apiKey: "donateflowcharts" },
  { key: "organ_allocation", name: "器官分配", apiKey: "donateorgansService" },
  { key: "organ_procurement", name: "器官获取", apiKey: "donationwitness" },
  { key: "organ_utilization", name: "器官利用", apiKey: "donatecompletioninfo" }
];
export default {
  name: 'DonationProcessDetail',
  name: "DonationProcessDetail",
  components: {
    CaseBasicInfo,
    DonorMaintenanceStage,
    MedicalAssessmentStage,
    DeathJudgmentStage,
    MedicalAssessmentStage,
    DonationConfirmStage,
    EthicalReviewStage,
    OrganAllocationStage,
    OrganProcurementStage,
    OrganUtilizationStage
  },
  dicts: ['sys_user_sex', 'sys_BloodType', 'sys_0_1'],
  dicts: [
    "decide_type",
    "maintain_type",
    "state_Evaluation",
    "affirm_type",
    "sys_ethical",
    "allocation_Status",
    "Obtain_status",
    "utilize_statue"
  ], // 这里只声明一个即可,其余通过 dict.type[xxx] 使用
  data() {
    return {
      caseId: null,
      caseInfo: {
        id: '',
        caseNo: '',
        hospitalNo: '',
        donorName: '',
        gender: '',
        age: '',
        bloodType: '',
        diagnosis: '',
        status: 'in_progress',
        createTime: '',
        registrant: '',
        currentStage: 'donor_maintenance'
      },
      processStages: [
        {
          key: 'donor_maintenance',
          name: '供者维护',
          status: 'completed',
          completeTime: '2025-12-01 10:00:00',
          updateTime: '2025-12-01 10:00:00',
          operator: '张医生'
        },
        {
          key: 'medical_assessment',
          name: '医学评估',
          status: 'completed',
          completeTime: '2025-12-02 14:30:00',
          updateTime: '2025-12-02 14:30:00',
          operator: '李主任'
        },
        {
          key: 'death_judgment',
          name: '死亡判定',
          status: 'completed',
          completeTime: '2025-12-03 09:15:00',
          updateTime: '2025-12-03 09:15:00',
          operator: '王医生'
        },
        {
          key: 'donation_confirm',
          name: '捐献确认',
          status: 'completed',
          completeTime: '2025-12-03 11:00:00',
          updateTime: '2025-12-03 11:00:00',
          operator: '赵协调员'
        },
        {
          key: 'ethical_review',
          name: '伦理审查',
          status: 'completed',
          completeTime: '2025-12-03 15:20:00',
          updateTime: '2025-12-03 15:20:00',
          operator: '伦理委员会'
        },
        {
          key: 'organ_allocation',
          name: '器官分配',
          status: 'in_progress',
          updateTime: '2025-12-04 10:00:00',
          operator: '分配系统'
        },
        {
          key: 'organ_procurement',
          name: '器官获取',
          status: 'pending',
          operator: '待分配'
        },
        {
          key: 'organ_utilization',
          name: '器官利用',
          status: 'pending',
          operator: '待分配'
        }
      ],
      activeStage: 'organ_allocation',
      activeStageName: '器官分配',
      activeStageData: {},
      loading: false
      caseInfo: {},
      processStages: [],
      activeStage: "",
      activeStageName: "",
      activeStageData: {}
    };
  },
  computed: {
  },
  created() {
    this.caseId = this.$route.query.id;
    if (this.caseId) {
      this.getDetail();
    } else {
      this.generateMockData();
    }
    this.setActiveStage(this.activeStage);
  },
  methods: {
       getStageComponent() {
      const componentMap = {
        'donor_maintenance': 'DonorMaintenanceStage',
        'medical_assessment': 'MedicalAssessmentStage',
        'death_judgment': 'DeathJudgmentStage',
        'donation_confirm': 'DonationConfirmStage',
        'ethical_review': 'EthicalReviewStage',
        'organ_allocation': 'OrganAllocationStage',
        'organ_procurement': 'OrganProcurementStage',
        'organ_utilization': 'OrganUtilizationStage'
      };
      return componentMap[this.activeStage];
    },
    // 获取详情数据
    async getDetail() {
      this.loading = true;
      try {
        const response = await getDonationProcessDetail(this.caseId);
        if (response.code === 200) {
          this.caseInfo = response.data.caseInfo;
          this.processStages = response.data.processStages;
          this.setActiveStage(response.data.currentStage);
        }
      } catch (error) {
        console.error('获取捐献进程详情失败:', error);
        this.$message.error('获取详情失败');
      } finally {
        this.loading = false;
      }
    },
    // 生成模拟数据
    generateMockData() {
      this.caseInfo = {
        id: '202512001',
        caseNo: 'C202512001',
        hospitalNo: 'D202512001',
        donorName: '张三',
        gender: '0',
        age: 45,
        bloodType: 'A',
        diagnosis: '脑外伤',
        status: 'in_progress',
        createTime: '2025-12-01 08:00:00',
        registrant: '李协调员',
        currentStage: 'organ_allocation'
      };
    },
    // 设置当前激活阶段
    setActiveStage(stageKey) {
      this.activeStage = stageKey;
      const stage = this.processStages.find(s => s.key === stageKey);
      if (stage) {
        this.activeStageName = stage.name;
        this.activeStageData = stage;
      }
    },
    // 处理阶段点击
    handleStageClick(stage) {
      if (stage.status !== 'pending') {
        this.setActiveStage(stage.key);
      } else {
        this.$message.warning('该阶段尚未开始,无法查看详情');
      }
    },
    // 获取阶段状态标签类型
    getStageStatusTag(status) {
      const map = {
        'completed': 'success',
        'in_progress': 'warning',
        'pending': 'info'
      };
      return map[status] || 'info';
    },
    // 获取阶段状态文本
    getStageStatusText(status) {
      const map = {
        'completed': '已完成',
        'in_progress': '进行中',
        'pending': '未开始'
      };
      return map[status] || '未知';
    },
    // 获取整体状态标签类型
    getOverallStatusTag(status) {
      const map = {
        'completed': 'success',
        'in_progress': 'warning',
        'pending': 'info',
        'terminated': 'danger'
      };
      return map[status] || 'info';
    },
    // 获取整体状态文本
    getStatusText(status) {
      const map = {
        'completed': '已完成',
        'in_progress': '进行中',
        'pending': '未开始',
        'terminated': '已终止'
      };
      return map[status] || '未知';
    },
    // 时间格式化
    formatTime(time) {
      if (!time) return '-';
      return dayjs(time).format('YYYY-MM-DD HH:mm');
    },
        const res = await getDonatebaseinfoflow(this.caseId);
    // 获取当前阶段名称
    getCurrentStageName() {
      const currentStage = this.processStages.find(
        stage => stage.status === 'in_progress'
      );
      return currentStage ? currentStage.name : '已完成';
    },
    // 编辑基本信息
    handleEditBasicInfo() {
      this.$message.info('编辑基本信息功能');
    },
    // 完成阶段
    handleCompleteStage() {
      this.$confirm(`确定要完成【${this.activeStageName}】阶段吗?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 更新当前阶段状态
        const currentIndex = this.processStages.findIndex(
          stage => stage.key === this.activeStage
        );
        const data = res;
        if (currentIndex !== -1) {
          this.processStages[currentIndex].status = 'completed';
          this.processStages[currentIndex].completeTime = new Date().toISOString();
        this.caseInfo = data.donatebaseinfo || {};
          // 激活下一个阶段
          if (currentIndex < this.processStages.length - 1) {
            this.processStages[currentIndex + 1].status = 'in_progress';
            this.setActiveStage(this.processStages[currentIndex + 1].key);
          } else {
            this.caseInfo.status = 'completed';
          }
        this.processStages = STAGE_CONFIG.map(stage => {
          const obj = data[stage.apiKey] || {};
          console.log(stage.apiKey, "stage.apiKey");
          console.log(this.dict?.type?.[STAGE_DICT_MAP[stage.apiKey]]);
          this.$message.success('阶段已完成');
        }
      });
    },
    // 查看详情
    handleViewDetail() {
      const routeMap = {
        'donor_maintenance': '/case/donorMaintenance/detail',
        'medical_assessment': '/case/medicalAssessment/detail',
        'death_judgment': '/case/deathJudgment/detail',
        'donation_confirm': '/case/donationConfirm/detail',
        'ethical_review': '/case/ethicalReview/detail',
        'organ_allocation': '/case/organAllocation/detail',
        'organ_procurement': '/case/organProcurement/detail',
        'organ_utilization': '/case/organUtilization/detail'
      };
          const dictLabel =
            this.dict?.type?.[STAGE_DICT_MAP[stage.apiKey]]?.find(
              d => d.value == obj.state
            )?.label || "";
      const route = routeMap[this.activeStage];
      if (route) {
        this.$router.push({
          path: route,
          query: { id: this.caseId }
          const theme = mapDictLabelToTheme(dictLabel);
          return {
            key: stage.key,
            name: stage.name,
            dict: STAGE_DICT_MAP[stage.apiKey],
            state: obj.state,
            dictLabel,
            status: theme, // ✅ 核心:UI 主题由 dictLabel 决定
            createtime: obj.createtime,
            updateTime: obj.updatetime,
            operator: obj.updateperson || obj.createperson
          };
        });
        const active =
          this.processStages.find(s => s.status == "progress") ||
          [...this.processStages].reverse().find(s => s.status == "completed");
        this.setActiveStage(active?.key || STAGE_CONFIG[0].key);
      } catch (e) {
        console.error(e);
        this.$message.error("获取流程详情失败");
      }
    },
    // 修改阶段信息
    handleModifyStage() {
      this.$message.info(`修改${this.activeStageName}信息功能`);
    setActiveStage(key) {
      const stage = this.processStages.find(s => s.key == key);
      if (!stage) return;
      this.activeStage = key;
      this.activeStageName = stage.name;
      this.activeStageData = stage;
    },
    getStageComponent() {
      const map = {
        donor_maintenance: "DonorMaintenanceStage",
        death_judgment: "DeathJudgmentStage",
        medical_assessment: "MedicalAssessmentStage",
        donation_confirm: "DonationConfirmStage",
        ethical_review: "EthicalReviewStage",
        organ_allocation: "OrganAllocationStage",
        organ_procurement: "OrganProcurementStage",
        organ_utilization: "OrganUtilizationStage"
      };
      return map[this.activeStage];
    },
    handleStageClick(stage) {
      if (stage.status == "pending") {
        this.$message.warning("该阶段尚未开始");
        return;
      }
      this.setActiveStage(stage.key);
    },
    formatTime(time) {
      return time ? dayjs(time).format("YYYY-MM-DD HH:mm") : "-";
    }
  }
};
@@ -466,47 +289,190 @@
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
  box-sizing: border-box;
}
.process-card {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}
.process-container {
  display: flex;
  min-height: 800px;
  min-height: 600px;
  /* 设置一个最小高度 */
  gap: 20px;
  align-items: flex-start;
  /* 顶部对齐 */
}
/* 左侧时间线样式 */
/* 左侧时间线样式 - 固定高度,内部滚动 */
.timeline-section {
  flex: 0 0 300px;
  flex: 0 0 320px;
  /* 固定宽度 */
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 6px;
  padding: 20px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  height: calc(120vh - 120px);
  /* 根据视口高度自适应 */
  max-height: 1200px;
  /* 设置最大高度 */
  position: sticky;
  /* 使用 sticky 定位 */
  top: 20px;
  /* 距离顶部 20px */
}
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #e4e7ed;
.timeline-scroll-container {
  flex: 1;
  overflow-y: auto;
  /* 内部可滚动 */
  margin-top: 20px;
  padding-right: 8px;
  /* 为滚动条留出空间 */
}
.section-header h3 {
  margin: 0;
  color: #303133;
  font-size: 16px;
.timeline-scroll-container::-webkit-scrollbar {
  width: 6px;
}
.timeline-scroll-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}
.timeline-scroll-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}
.timeline-scroll-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
.timeline-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
  padding-bottom: 10px;
}
/* 右侧内容区域样式 - 自适应高度 */
.content-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 0;
  /* 重要:允许flex子项压缩 */
}
.basic-info-section {
  background: white;
  border-radius: 6px;
  padding: 20px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* 重要 */
}
.basic-info-content {
  flex: 1;
  max-height: 300px;
  /* 基本信息区域最大高度 */
  overflow-y: auto;
  /* 基本信息内部可滚动 */
  margin-top: 20px;
  padding-right: 8px;
}
.basic-info-content::-webkit-scrollbar {
  width: 6px;
}
.basic-info-content::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}
.basic-info-content::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}
.basic-info-content::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
.basic-info-content .el-descriptions {
  width: 100%;
}
.stage-detail-section {
  flex: 1;
  /* 占据剩余空间 */
  background: white;
  border-radius: 6px;
  padding: 20px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  min-height: 400px;
  /* 最小高度 */
  max-height: 800px;
  /* 最大高度,可根据需要调整 */
  overflow: hidden;
  /* 隐藏外层溢出 */
}
.stage-content-wrapper {
  flex: 1;
  overflow-y: auto;
  /* 阶段详情内部可滚动 */
  margin-top: 20px;
  padding-right: 8px;
  min-height: 0;
  /* 重要 */
}
.stage-content-wrapper::-webkit-scrollbar {
  width: 6px;
}
.stage-content-wrapper::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}
.stage-content-wrapper::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}
.stage-content-wrapper::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
/* 原有样式保持不变 */
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  /* 防止被压缩 */
}
.section-header h3 {
  margin: 0;
  color: #303133;
  font-size: 16px;
  white-space: nowrap;
}
.timeline-item {
@@ -517,25 +483,34 @@
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid #e4e7ed;
  flex-shrink: 0;
  /* 防止被压缩 */
}
.timeline-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transform: translateY(-1px);
}
.timeline-item.danger {
  border-color: #f56c6c;
  background-color: #fef0f0;
}
.timeline-item.danger .timeline-marker {
  background-color: #f56c6c;
}
.timeline-item.active {
  border-color: #409EFF;
  border-color: #409eff;
  background-color: #f0f9ff;
}
.timeline-item.completed {
  border-color: #67C23A;
  border-color: #67c23a;
  background-color: #f0f9e8;
}
.timeline-item.in-progress {
  border-color: #E6A23C;
.timeline-item.progress {
  border-color: #e6a23c;
  background-color: #fdf6ec;
}
@@ -557,11 +532,14 @@
}
.timeline-item.completed .timeline-marker {
  background-color: #67C23A;
  background-color: #67c23a;
}
.timeline-item.active .timeline-marker {
  background-color: #409eff;
}
.timeline-item.in-progress .timeline-marker {
  background-color: #E6A23C;
.timeline-item.progress .timeline-marker {
  background-color: #e6a23c;
}
.timeline-item.pending .timeline-marker {
@@ -583,6 +561,10 @@
  font-weight: 600;
  color: #303133;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 150px;
}
.stage-info {
@@ -590,33 +572,18 @@
  color: #606266;
}
.time-info, .operator-info {
.time-info,
.operator-info {
  margin-bottom: 4px;
}
/* 右侧内容区域样式 */
.content-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.basic-info-section,
.stage-detail-section {
  background: white;
  border-radius: 6px;
  padding: 20px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stage-actions {
  display: flex;
  gap: 10px;
}
.stage-content {
  margin-top: 20px;
  flex-wrap: wrap;
}
/* 响应式设计 */
@@ -627,7 +594,19 @@
  .timeline-section {
    flex: none;
    margin-bottom: 20px;
    width: 100%;
    height: auto;
    max-height: 300px;
    position: static;
    /* 小屏幕取消 sticky */
  }
  .timeline-scroll-container {
    max-height: 250px;
  }
  .stage-detail-section {
    max-height: 500px;
  }
}
@@ -652,26 +631,17 @@
    gap: 10px;
  }
  .stage-actions {
    flex-wrap: wrap;
  .stage-name {
    max-width: 120px;
  }
}
/* 动画效果 */
.timeline-item {
  transition: all 0.3s ease;
}
  .basic-info-content {
    max-height: 250px;
  }
.timeline-item:hover {
  transform: translateY(-2px);
}
/* 进度条样式优化 */
:deep(.el-progress-bar) {
  padding-right: 0;
}
:deep(.el-progress__text) {
  font-size: 12px;
  .stage-detail-section {
    min-height: 300px;
    max-height: 400px;
  }
}
</style>