huminmin
6 天以前 5eea45a45c48e44e2d6b2fc6818332cd62aef7f5
src/views/productionManagement/processRoute/ItemsForm.vue
@@ -85,31 +85,28 @@
        </el-table-column>
      </el-table>
      <!-- 简化容器结构,直接给el-steps加ref -->
      <el-steps
      <!-- 使用普通div替代el-steps -->
      <div
          v-else
          ref="stepsContainer"
          class="mb5 custom-steps"
          :active="routeItems.length"
          align-center
          style="padding: 10px 0;"
          style="padding: 10px 0; display: flex; flex-wrap: nowrap; gap: 20px; align-items: flex-start;"
      >
        <!-- 关键:给el-step添加data-id,而非内部卡片 -->
        <el-step
        <div
            v-for="(item, index) in routeItems"
            :key="item.id"
            class="custom-step draggable-step"
            :data-id="item.id"
            style="cursor: move;"
            style="cursor: move; flex: 0 0 auto; min-width: 220px;"
        >
          <template #title>
            <div class="step-content">
              <div class="step-number">{{ index + 1 }}</div>
              <el-card
                  :header="item.productName"
                  class="step-card"
                  style="cursor: move;"
              >
          <div class="step-content">
            <div class="step-number">{{ index + 1 }}</div>
            <el-card
                :header="item.productName"
                class="step-card"
                style="cursor: move;"
            >
              <div class="step-card-content">
                <p>{{ item.model }}</p>
                <p>{{ item.unit }}</p>
                <el-select
@@ -124,14 +121,16 @@
                      :value="process.id"
                  />
                </el-select>
                <template #footer>
              </div>
              <template #footer>
                <div class="step-card-footer">
                  <el-button type="danger" link size="small" @click.stop="removeItemByID(item.id)">删除</el-button>
                </template>
              </el-card>
            </div>
          </template>
        </el-step>
      </el-steps>
                </div>
              </template>
            </el-card>
          </div>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
@@ -244,8 +243,10 @@
    processId: undefined
  }));
  console.log('选择产品前数组:', routeItems.value);
  routeItems.value.push(...newData);
  routeItems.value = [...routeItems.value];
  console.log('选择产品后数组:', routeItems.value);
  // 延迟初始化,确保DOM完全渲染
  nextTick(() => {
@@ -359,34 +360,31 @@
  } else {
    if (!stepsContainer.value) return;
    // 关键修复1:精准定位步骤条列表容器(兼容Element Plus不同版本)
    const stepsList = stepsContainer.value.$el.querySelector('.el-steps__items') ||
        stepsContainer.value.$el ||
        stepsContainer.value;
    // 修改:直接使用stepsContainer.value作为拖拽容器
    const stepsList = stepsContainer.value;
    if (!stepsList) {
      console.warn('未找到步骤条拖拽容器');
      return;
    }
    // 关键修复2:放宽拖拽触发条件,恢复拖拽功能
    // 修改:简化拖拽配置
    stepsSortable = new Sortable(stepsList, {
      animation: 150,
      ghostClass: 'sortable-ghost',
      draggable: '.draggable-step', // 可拖拽元素:el-step
      handle: '.draggable-step, .step-card', // 拖拽手柄:step本身 + 卡片(扩大触发区域)
      filter: '.el-button, .el-select, .el-input', // 过滤按钮/选择器,避免误触发
      forceFallback: true, // 强制使用fallback模式,避免原生拖拽冲突
      draggable: '.draggable-step', // 可拖拽元素
      handle: '.draggable-step, .step-card', // 拖拽手柄
      filter: '.el-button, .el-select, .el-input', // 过滤按钮/选择器
      forceFallback: true,
      fallbackClass: 'sortable-fallback',
      preventOnFilter: true, // 过滤元素阻止拖拽
      preventOnFilter: true,
      scroll: true,
      scrollSensitivity: 30,
      scrollSpeed: 10,
      bubbleScroll: true,
      // 统一使用数组 splice 方法重新排序,与表格模式保持一致
      onEnd: (evt) => {
        if (evt.oldIndex === evt.newIndex || !routeItems.value[evt.oldIndex]) return;
        // 使用数组 splice 方法重新排序,与表格模式保持一致
        // 使用数组 splice 方法重新排序
        const moveItem = routeItems.value.splice(evt.oldIndex, 1)[0];
        routeItems.value.splice(evt.newIndex, 0, moveItem);
        routeItems.value = [...routeItems.value];
@@ -447,32 +445,33 @@
  justify-content: space-between;
}
/* 关键修复:优化步骤条拖拽样式,确保可点击区域 */
:deep(.el-steps__items) {
/* 修改:自定义步骤条容器样式 */
.custom-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 20px;
  min-height: 100px; /* 确保容器有高度 */
  min-height: 100px;
}
:deep(.draggable-step) {
  cursor: move !important; /* 强制显示拖拽光标 */
/* 修改:自定义步骤项样式 */
.custom-step {
  cursor: move !important;
  padding: 8px;
  position: relative;
  transition: all 0.2s ease;
  flex: 0 0 auto;
  min-width: 220px;
  touch-action: none; /* 禁用触摸动作,避免移动端冲突 */
  touch-action: none;
}
/* 拖拽悬浮样式,提示可拖拽 */
:deep(.draggable-step:hover) {
.custom-step:hover {
  background-color: rgba(64, 158, 255, 0.05);
  transform: translateY(-2px);
}
:deep(.sortable-ghost) {
.sortable-ghost {
  opacity: 0.4;
  background-color: #f5f7fa !important;
  border: 2px dashed #409eff;
@@ -480,7 +479,7 @@
  transform: scale(1.02);
}
:deep(.sortable-fallback) {
.sortable-fallback {
  opacity: 0.9;
  background-color: #f5f7fa;
  border: 1px solid #409eff;
@@ -489,17 +488,17 @@
  margin: 10px;
}
:deep(.step-card) {
.step-card {
  cursor: move !important;
  transition: box-shadow 0.2s ease;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: auto; /* 确保卡片可触发鼠标事件 */
  pointer-events: auto;
  margin: 10px;
  height: 300px;
  height: 240px;
}
:deep(.step-card:hover) {
.step-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
@@ -508,14 +507,17 @@
  user-select: none;
}
/* 禁用步骤条默认的头部样式干扰 */
:deep(.el-step__head) {
  display: none; /* 隐藏默认的步骤圆圈和序号 */
.step-card-content {
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* 隐藏Element Plus自动生成的连接线 */
:deep(.el-step__main::before) {
  display: none; /* 隐藏连接线 */
.step-card-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 10px;
}
/* 自定义序号样式优化 */
@@ -531,5 +533,4 @@
  border-radius: 50%;
  font-size: 14px;
}
</style>
</style>