zhoushihao
2025-10-27 636bd027a92d4bf669410ee550a5ca6324f72c88
UI-Project/src/views/EngineerScheduling/engineerScheduling.vue
@@ -92,10 +92,16 @@
const fetchTargetKeys = async () => {
  try {
    let type = 1;
    if (activeTab.value === 'cutting2') type = 2;
    else if (activeTab.value === 'tempered') type = 3;
    const response = await request.post('/loadGlass/optimizeProject/engineerScheduling', {type})
    let response;
    if (activeTab.value === 'cutting2') {
      type = 2;
      response = await request.post('/loadGlass/optimizeProject/engineerScheduling', {type})
    } else if (activeTab.value === 'tempered') {
      type = 3;
      response = await request.post('/cacheVerticalGlass/bigStorageCageDetails/queryTemperingOrder')
    } else {
      response = await request.post('/loadGlass/optimizeProject/engineerScheduling', {type})
    }
    if (response.code === 200) {
      // 右侧表格数据
      rightDataSource.value = response.data.map((item: any) => ({
@@ -182,7 +188,7 @@
const resetScheduling = async () => {
  await fetchDataSource()
  await fetchTargetKeys()
  ElMessage.info(t('已取消'))
  ElMessage.info(t('scheduling.cancelled'))
}
// 监听标签页切换,根据不同标签页加载对应的数据
@@ -214,17 +220,24 @@
  return index === rightDataSource.value.length - 1;
};
// 判断上方是否有进行中的行(state=100表示进行中,根据实际状态值调整)
// 判断上方是否有进行中的行(修复:使用正确的状态值1)
const hasInProgressAbove = (row: TransferDataItem) => {
  const index = rightDataSource.value.findIndex(item => item.key === row.key);
  // 查找当前行上方是否有进行中的任务
  return rightDataSource.value.some((item, i) => i < index && item.state === 100);
  return rightDataSource.value.some((item, i) => i < index && item.state === 1);
};
// 向上移动一行
const moveUp = (row: TransferDataItem) => {
  const index = rightDataSource.value.findIndex(item => item.key === row.key);
  if (index > 0) {
    // 检查是否会超过进行中的任务
    const prevItem = rightDataSource.value[index - 1];
    if (prevItem.state === 1) {
      // 直接上方是进行中任务,提示用户不可超过
      ElMessage.warning('操作不可超过进行中的任务');
      return;
    }
    // 交换位置
    [rightDataSource.value[index], rightDataSource.value[index - 1]] =
        [rightDataSource.value[index - 1], rightDataSource.value[index]];
@@ -245,27 +258,77 @@
  }
};
// 置顶(移动到第一个非进行中任务上方)
// 判断是否可以置顶(即是否有可置顶的位置)
const canMoveToTop = (row: TransferDataItem) => {
  // 进行中任务不能置顶
  if (row.state === 1) return false;
  const index = rightDataSource.value.findIndex(item => item.key === row.key);
  // 已经是第一行的不能置顶
  if (index === 0) return false;
  // 查找第一个非进行中任务的位置
  const firstNonProgressIndex = rightDataSource.value.findIndex(item => item.state !== 1);
  // 如果当前行已经在第一个非进行中任务的位置或之前,则不能置顶
  return index > firstNonProgressIndex;
};
// ... existing code (moveUp和moveDown函数保持不变)
// 置顶(移动到所有非进行中任务的最前面)
const moveToTop = (row: TransferDataItem) => {
  const index = rightDataSource.value.findIndex(item => item.key === row.key);
  if (index > 0) {
    // 移除当前行
    const newList = rightDataSource.value.filter(item => item.key !== row.key);
    // 查找第一个进行中任务的位置
    const firstInProgressIndex = newList.findIndex(item => item.state === 100);
    if (firstInProgressIndex === -1) {
      // 无进行中任务,直接添加到开头
      newList.unshift(row);
    // 查找所有非进行中任务的位置
    const nonProgressIndices = newList
        .map((item, i) => ({ item, index: i }))
        .filter(item => item.item.state !== 1)
        .map(item => item.index);
    if (nonProgressIndices.length > 0) {
      // 有非进行中任务,添加到第一个非进行中任务的位置
      newList.splice(nonProgressIndices[0], 0, row);
    } else {
      // 有进行中任务,添加到第一个进行中任务后面
      newList.splice(firstInProgressIndex + 1, 0, row);
      // 全部都是进行中任务,添加到开头
      newList.unshift(row);
    }
    // 更新数据源
    rightDataSource.value = newList;
  }
};
// 创建计算属性,根据标签页返回不同的表头配置
const tableHeaders = computed(() => {
  const baseHeaders = {
    serial: t('scheduling.serial'),
    projectNo: t('scheduling.projectNo'),
    thickness: t('scheduling.thickness'),
    glassType: t('scheduling.glassType'),
    totalCount: t('scheduling.totalCount'),
    totalArea: t('scheduling.totalArea'),
    operate: t('scheduling.operate')
  };
  // 根据不同标签页返回不同的表头配置
  if (activeTab.value === 'tempered') {
    return {
      ...baseHeaders,
      // 更改钢化标签页的特定表头
      totalCount: t('scheduling.totalFireCount'),
      totalArea: t('scheduling.fullFireCount')
    };
  }
  return baseHeaders;
});
// 状态格式化函数
const stateFormatter = (row: any) => {
  return row.state === 1 ? '进行中' : '未开始';
};
</script>
<template>
@@ -279,8 +342,8 @@
    <!-- 表格布局容器 -->
    <div class="table-container">
      <!-- 左侧表格:待排产 -->
      <div class="table-wrapper">
        <h3 class="table-title">{{ '待排产' }} ({{ dataSource.length }})</h3>
      <div class="table-wrapper" v-if="activeTab !== 'tempered'">
        <h3 class="table-title">{{ t('scheduling.unfinished') }} ({{ dataSource.length }})</h3>
        <el-table
            :data="dataSource"
            border
@@ -288,16 +351,16 @@
            height="400"
            row-key="key"
        >
          <el-table-column type="index" label="序号" width="55"/>
          <el-table-column prop="projectNo" label="工程ID" width="180"/>
          <el-table-column prop="glassThickness" label="玻璃厚度(mm)" width="120"/>
          <el-table-column prop="glassType" label="玻璃类型" width="120"/>
          <el-table-column prop="glassTotal" label="总片数" width="90"/>
          <el-table-column prop="glassTotalArea" label="总面积(㎡)" width="120"/>
          <el-table-column label="操作" width="120" align="center">
          <el-table-column type="index" :label="$t('scheduling.serial')" width="55"/>
          <el-table-column prop="projectNo" :label="$t('scheduling.projectNo')" width="150"/>
          <el-table-column prop="glassThickness" :label="$t('scheduling.thickness')" width="120"/>
          <el-table-column prop="glassType" :label="$t('scheduling.glassType')" width="120"/>
          <el-table-column prop="glassTotal" :label="$t('scheduling.totalCount')" width="90"/>
          <el-table-column prop="glassTotalArea" :label="$t('scheduling.totalArea')" width="100"/>
          <el-table-column :label="$t('scheduling.operate')" width="90" align="center">
            <template #default="{ row }">
              <el-button type="primary" @click="moveToRight(row)">
                {{ t('添加') }}
                {{ t('scheduling.add') }}
              </el-button>
            </template>
          </el-table-column>
@@ -317,55 +380,56 @@
            @row-click="(row) => fetchProjectDetail(row.key)"
            highlight-current-row
        >
          <el-table-column type="index" label="序号" width="55"/>
          <el-table-column prop="projectNo" label="工程ID" width="120"/>
          <el-table-column prop="glassThickness" label="玻璃厚度(mm)" width="120"/>
          <el-table-column prop="glassType" label="玻璃类型" width="120"/>
          <el-table-column prop="glassTotal" label="总片数" width="90"/>
          <el-table-column prop="glassTotalArea" label="总面积(㎡)" width="120"/>
          <el-table-column label="操作" width="300" align="center">
          <el-table-column type="index" :label="tableHeaders.serial" width="55"/>
          <el-table-column prop="projectNo" :label="tableHeaders.projectNo" width="120"/>
          <el-table-column prop="glassThickness" :label="tableHeaders.thickness" width="120"/>
          <el-table-column prop="glassType" :label="tableHeaders.glassType" width="120"/>
          <el-table-column prop="glassTotal" :label="tableHeaders.totalCount" width="90"/>
          <el-table-column prop="glassTotalArea" :label="tableHeaders.totalArea" width="120"/>
          <el-table-column
              prop="state"
              :label="t('scheduling.state')"
              width="90"
              :formatter="stateFormatter"
          />
          <el-table-column :label="t('scheduling.operate')" :width="activeTab === 'tempered' ? 200 : 300" :align="center">
            <template #default="{ row }">
              <div style="display: flex; gap: 5px; align-items: center;">
                <el-button
                    v-if="activeTab !== 'tempered'"
                    type="default"
                    size="small"
                    @click="moveToLeft(row)"
                    :disabled="row.state === 1"
                    style="background: #ff4d4f; color: white; border-radius: 8px; min-width: 60px; display: inline-flex; justify-content: center; align-items: center;"
                >
                  去除
                  {{ t('scheduling.remove') }}
                </el-button>
                <!-- 向上按钮 -->
                <el-button
                    type="default"
                    size="small"
                    @click="moveUp(row)"
                    :disabled="isFirstRow(row) || hasInProgressAbove(row)"
                    :disabled="row.state === 1 || isFirstRow(row)"
                    style="background: #E6F4FF; color: #1890FF; border-radius: 8px; min-width: 40px; display: inline-flex; justify-content: center; align-items: center;"
                >
                  ↑
                </el-button>
                <!-- 向下按钮 -->
                <el-button
                    type="default"
                    size="small"
                    @click="moveDown(row)"
                    :disabled="isLastRow(row)"
                    :disabled="row.state === 1 || isLastRow(row)"
                    style="background: #E6F4FF; color: #1890FF; border-radius: 8px; min-width: 40px; display: inline-flex; justify-content: center; align-items: center;"
                >
                  ↓
                </el-button>
                <!-- 置顶按钮 -->
                <el-button
                    type="primary"
                    size="small"
                    @click="moveToTop(row)"
                    :disabled="isFirstRow(row) || hasInProgressAbove(row)"
                    :disabled="row.state === 1 || isFirstRow(row) || !canMoveToTop(row)"
                    style="background: #E6F4FF; color: #1890FF; border-radius: 8px; min-width: 60px; display: inline-flex; justify-content: center; align-items: center;"
                >
                  置顶
                  {{ t('scheduling.top') }}
                </el-button>
              </div>
            </template>
@@ -393,20 +457,19 @@
        class="detail-table"
        height="230"
    >
      <el-table-column prop="engineerId" label="工程号" width="120"/>
      <el-table-column prop="flowCardId" label="流程卡号" width="150"/>
      <el-table-column prop="layer" label="层号" width="80"/>
      <el-table-column prop="glassType" label="订序" width="80"/>
      <el-table-column prop="thickness" label="厚度(mm)" width="100"/>
      <el-table-column prop="filmsid" label="膜系" width="120"/>
      <el-table-column prop="width" label="宽(mm)" width="90"/>
      <el-table-column prop="height" label="高(mm)" width="90"/>
      <el-table-column prop="glassIdCount" label="数量" width="80"/>
      <el-table-column prop="cuttingCount" label="切割" width="80"/>
      <el-table-column prop="edgingCount" label="磨边" width="80"/>
      <el-table-column prop="temperingCount" label="钢化" width="80"/>
      <el-table-column prop="insulatingCount" label="中空" width="80"/>
      <el-table-column prop="engineerId" :label="$t('scheduling.projectNo')" width="120"/>
      <el-table-column prop="flowCardId" :label="$t('scheduling.flowCardId')" width="150"/>
      <el-table-column prop="layer" :label="$t('scheduling.layerCount')" width="80"/>
      <el-table-column prop="glassType" :label="$t('scheduling.serial')" width="80"/>
      <el-table-column prop="thickness" :label="$t('scheduling.thickness')" width="100"/>
      <el-table-column prop="filmsid" :label="$t('scheduling.coatingType')" width="120"/>
      <el-table-column prop="width" :label="$t('scheduling.width')" width="90"/>
      <el-table-column prop="height" :label="$t('scheduling.height')" width="90"/>
      <el-table-column prop="glassIdCount" :label="$t('scheduling.glassCount')" width="80"/>
      <el-table-column prop="cuttingCount" :label="$t('scheduling.cuttingCount')" width="80"/>
      <el-table-column prop="edgingCount" :label="$t('scheduling.edgingCount')" width="80"/>
      <el-table-column prop="temperingCount" :label="$t('scheduling.temperingCount')" width="80"/>
      <el-table-column prop="insulatingCount" :label="$t('scheduling.insulatingCount')" width="80"/>
    </el-table>
  </div>
</template>