于杰
1 天以前 121ef0e477b9ab0e3a610de08a92f08eb955d556
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizeCompute.vue
@@ -1,8 +1,11 @@
<script setup>
import {ref, computed, watch} from "vue";
import {Connection} from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from 'element-plus';
import {useRoute, useRouter} from "vue-router";
import useOrderInfoStore from "@/stores/sd/order/orderInfo";
import requestOptimize from "@/utils/requestOptimize";
import request from "@/utils/request";
const router = useRouter()
const orderInfo = useOrderInfoStore()
@@ -40,6 +43,8 @@
  const remainingSeconds = seconds.value % 60;
  return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
});
const showCompleteButton = ref(false);
const startTimer = () => {
  if(progress.value>0){
    seconds.value = 0;
@@ -53,239 +58,179 @@
  if(props.optimizeData!=null){
    document.getElementById("start").disabled=true
    document.getElementById("complete").style.display="none"
    showCompleteButton.value = false;
    console.log(props.optimizeData)
    if (!isRunning.value) {
      isRunning.value = true;
      intervalId = setInterval(() => {
        seconds.value++;
        progress.value += 1;
        if (progress.value >= 100) {
          progress.value = 100;
          clearInterval(intervalId);
        // 最大只到99%
        if (progress.value < 99) {
          progress.value += 1;
        }
      }, 1000);
    }
    // 发送请求到真实接口
    requestOptimize.post('/api/optimize', props.optimizeData, {timeout: 300000})
        .then((response) => {
          // 处理响应数据
          if (response.code === 200 && response.data) {
            // 解析接口返回的数据
            const result = response.data;
    mockData.value = {
      code: 200,
      data: [{
        "projectNo":"P25041001",
        "totalQuantity":1,
        "glassTotalQuantity":1,
        "glassTotalArea":1,
        "avgCutRate":1,
        "lastCutRate":1,
        "validCutRate":1,
        "layouts":[
          {
            "stockId":3,
            "usageRate":0.9,
            "width":4500,
            "height":2440,
            "stockCode":11,
            "upTrim":12,
            "downTrim":12,
            "leftTrim":12,
            "rightTrim":12,
            "quantity":1,
            "glassQuantity":6,
            "glassArea":45,
            "materialType":1,
            "mergeID":1,
            "glassDetails":[
              {"isRemain":false,
                "width":2070,
                "height":725,
                "realWidth":2070,
                "realHeight":725,
                "layer":1,
                "totalLayer":2,
                "orderSort":1,
                "processId":"NG22091408A06",
                "stockSort":1,
                "polySort":1,
                "markIcon":"",
                "x":0,
                "y":0,
                "patchState":0,
                "isRotate":0,
                "rackNo":1,
                "glassPoint":{}
              },
              {"isRemain":false,
                "width":2070,
                "height":725,
                "realWidth":2070,
                "realHeight":725,
                "layer":1,
                "totalLayer":2,
                "orderSort":1,
                "processId":"NG22091408A06",
                "stockSort":1,
                "polySort":2,
                "markIcon":"",
                "x":2070,
                "y":0,
                "patchState":0,
                "isRotate":0,
                "rackNo":1,
                "glassPoint":{}
              },
              {"isRemain":false,
                "width":2070,
                "height":725,
                "realWidth":2070,
                "realHeight":725,
                "layer":1,
                "totalLayer":2,
                "orderSort":1,
                "processId":"NG22091408A06",
                "stockSort":1,
                "polySort":3,
                "markIcon":"",
                "x":0,
                "y":725,
                "patchState":0,
                "isRotate":0,
                "rackNo":1,
                "glassPoint":{}
              },
              {"isRemain":false,
                "width":2070,
                "height":725,
                "realWidth":2070,
                "realHeight":725,
                "layer":1,
                "totalLayer":2,
                "orderSort":1,
                "processId":"NG22091408A06",
                "stockSort":1,
                "polySort":4,
                "markIcon":"",
                "x":2070,
                "y":725,
                "patchState":0,
                "isRotate":0,
                "rackNo":1,
                "glassPoint":{}
              },
              {"isRemain":false,
                "width":2070,
                "height":725,
                "realWidth":2070,
                "realHeight":725,
                "layer":1,
                "totalLayer":2,
                "orderSort":1,
                "processId":"NG22091408A06",
                "stockSort":1,
                "polySort":5,
                "markIcon":"",
                "x":0,
                "y":1450,
                "patchState":0,
                "isRotate":0,
                "rackNo":1,
                "glassPoint":{}
              },
              {"isRemain":false,
                "width":2070,
                "height":725,
                "realWidth":2070,
                "realHeight":725,
                "layer":1,
                "totalLayer":2,
                "orderSort":1,
                "processId":"NG22091408A06",
                "stockSort":1,
                "polySort":6,
                "markIcon":"",
                "x":2070,
                "y":1450,
                "patchState":0,
                "isRotate":0,
                "rackNo":1,
                "glassPoint":{}
              },
              {"isRemain":true,
                "width":2070,
                "height":265,
                "x":0,
                "y":2175
              },
              {"isRemain":true,
                "width":2070,
                "height":265,
                "x":2070,
                "y":2175
              },
              {"isRemain":true,
                "width":360,
                "height":2440,
                "x":4140,
                "y":0
              }]
            // 更新 store 数据
            if (result.layouts && result.layouts.length > 0) {
              orderInfo.optimizeData.optimalResults = {
                projectNo: result.projectNo,
                glassThickness: result.glassThickness,
                glassType: result.glassType,
                totalQuantity: result.totalQuantity,
                glassTotalQuantity: result.glassTotalQuantity,
                glassTotalArea: result.glassTotalArea,
                avgCutRate: result.avgCutRate,
                lastCutRate: result.lastCutRate,
                validCutRate: result.validCutRate,
                layouts: result.layouts
              };
            }
            // 在这里就设置 originalFilm 数据
            const newOriginalFilm = [];
            result.layouts.forEach(items => {
              const existingItem = newOriginalFilm.find(
                  item => item.width === items.width && item.height === items.height
              );
              if (existingItem) {
                existingItem.count += 1;
              } else {
                newOriginalFilm.push({
                  width: items.width,
                  height: items.height,
                  upTrim: items.upTrim,
                  downTrim: items.downTrim,
                  leftTrim: items.leftTrim,
                  rightTrim: items.rightTrim,
                  stockCode: items.stockCode,
                  glassArea: items.glassArea,
                  glassQuantity: items.glassQuantity,
                  usageRate: items.usageRate,
                  count: 1
                });
              }
            });
            originalFilm.value = newOriginalFilm;
            orderInfo.optimizeData.originalFilm = newOriginalFilm; // 这一行很重要
            console.log('优化完成后设置 originalFilm:', newOriginalFilm);
            // 更新利用率
            totalUtilizationRate.value = result.avgCutRate;
            tailPieceRate.value = result.lastCutRate;
            // 显示成功提示
            ElMessage.success('优化完成');
          } else {
            // 显示失败提示
            ElMessage.error(response.msg || '优化失败');
          }
        ]}]
    }
        })
        .catch((error) => {
          // 捕获网络错误
          console.error('优化请求失败:', error);
          ElMessage.error('网络异常,请检查接口');
        })
        .finally(() => {
          // 在请求完成时将进度条设为100%
          progress.value = 100;
          // 启用按钮
          document.getElementById("start").disabled = false;
          // 显示完成按钮
          document.getElementById("complete").style.display = "block";
          showCompleteButton.value = true;
          // 停止定时器
          pauseTimer();
        });
    }
};
const pauseTimer = () => {
  if (isRunning.value) {
    clearInterval(intervalId);
    isRunning.value = false;
  }
};
const resetTimer = () => {
  router.push({path: '/main/glassOptimize/Optimization'})
  /*clearInterval(intervalId);
  isRunning.value = false;
  seconds.value = 0;
  progress.value = 0;*/
const isSaving = ref(false);
const saveOptimizeData = async () => {
  // 检查是否有优化数据
  if(orderInfo.optimizeData !== null){
    try {
      isSaving.value = true;
      // 确保 originalFilm 数据已设置
      if (!orderInfo.optimizeData.originalFilm) {
        orderInfo.optimizeData.originalFilm = originalFilm.value;
        console.log('保存前设置 originalFilm:', originalFilm.value);
      }
      // 发送请求保存优化数据
      const res = await request.post(`/glassOptimize/saveOptimizeData/${props.optimizeData.projectNo}`, orderInfo.optimizeData);
      if (Number(res.code) === 200) {
        ElMessage.success("保存成功");
        return true; // 保存成功
      } else {
        ElMessage.warning(res.msg || "保存失败");
        return false; // 保存失败
      }
    } catch (error) {
      ElMessage.error("保存过程中发生错误");
      console.error("保存数据出错:", error);
      return false; // 保存出错
    } finally {
      // 无论成功或失败,都结束保存状态
      isSaving.value = false;
    }
  } else {
    ElMessage.warning("无优化数据可保存");
    return false;
  }
}
const resetTimer = async () => {
  // 先保存数据,保存成功后再跳转
  const isSaved = await saveOptimizeData();
  if (isSaved) {
    // 保存成功后跳转到优化界面
    router.push({path: '/main/glassOptimize/Optimization'});
  } else {
    // 保存失败,给用户选择是否仍要离开
    ElMessageBox.confirm(
        '数据保存失败,是否仍要离开当前页面?',
        '提示',
        {
          confirmButtonText: '确定离开',
          cancelButtonText: '取消',
          type: 'warning'
        }
    ).then(() => {
      // 用户确认离开
      router.push({path: '/main/glassOptimize/Optimization'});
    }).catch(() => {
      // 用户取消,留在当前页面
      ElMessage.info('操作已取消');
    });
  }
};
watch(
    ()=> [progress.value],
    ([newValue])=> {
      if(progress.value===10){
        orderInfo.optimizeData.optimalResults=mockData.value.data[0]
        mockData.value.data[0].layouts.forEach(items=>{
    () => progress.value,
    (newValue) => {
      console.log('优化进度更新:', newValue);
    }
);
          // 根据唯一标识(如 id)查找是否已存在
          const existingItem = originalFilm.value.find(item => item["width"] === items["width"]&&item["height"] === items["height"]);
          if (existingItem) {
            // 存在:数量加1(假设字段为 count)
            existingItem.count += 1;
          } else {
            // 不存在:新增到数组(初始化 count=1)
            const array={
              width:items["width"],
              height:items["height"],
              upTrim:items["upTrim"],
              downTrim:items["downTrim"],
              leftTrim:items["leftTrim"],
              rightTrim:items["rightTrim"],
              stockCode:items["stockCode"],
              count:1
            }
            originalFilm.value.push(array);
          }
        })
        orderInfo.optimizeData.originalFilm=originalFilm.value
        totalUtilizationRate.value=mockData.value.data[0].avgCutRate*100
        tailPieceRate.value=mockData.value.data[0].layouts*100
        pauseTimer()
        document.getElementById("complete").style.display="block"
        document.getElementById("start").disabled=false
      }
    });
</script>
@@ -301,9 +246,26 @@
          <vxe-input class="input" v-model="props.quantity" disabled ></vxe-input>
          <span>优化时长(秒):</span>
          <span class="time-display">{{ formattedTime }}</span>
          <el-button id="start" type="primary" style="margin-left: 20px" @click="startTimer">开始优化</el-button>
<!--          <el-button class="buttons" type="primary" @click="pauseTimer">暂停</el-button>-->
          <el-button id="complete" class="buttons" type="primary" style="display: none" @click="resetTimer">完成</el-button>
          <el-button
              id="start"
              type="primary"              style="margin-left: 20px"
              @click="startTimer"
              :disabled="isRunning || isSaving"
              :class="{ 'disabled-button': isRunning || isSaving }"
          >
            开始优化
          </el-button>
          <el-button
              id="complete"
              class="buttons"
              type="primary"
              :style="{ display: showCompleteButton ? 'inline-block' : 'none' }"
              @click="resetTimer"
              :disabled="isSaving"
              :class="{ 'disabled-button': isSaving }"
          >
            {{ isSaving ? '保存中...' : '完成' }}
          </el-button>
        </div>
        <br>
<!--        <div style="display: flex;margin-top: -10px">
@@ -322,13 +284,14 @@
  <div id="box">
    <span style="font-size: 20px">优化进度</span>
    <div class="progress-bar">
      <el-progress :percentage="progress"
                   :text-inside="true"
                   :stroke-width="20"
                   status="success"
                   striped
                   striped-flow
                   duration="45"/>
      <el-progress  :percentage="progress"
                    :text-inside="true"
                    :stroke-width="20"
                    status="success"
                    :striped="true"
                    :striped-flow="progress < 100"
                    :duration="progress < 100 ? 45 : 0"
      />
    </div>
    <div style="height: 250px; margin-top: 20px;   border: 2px solid #e6e6e6; padding: 10px; border-radius: 5px;">
      <span style="font-weight: bold">当前结果</span><br/>
@@ -381,5 +344,10 @@
  height: 80%;
}
.disabled-button {
  opacity: 0.95 !important;
  cursor: not-allowed !important;
}
</style>