chenlu
2025-08-06 5f112c3f56e5205e137f36208b3736c72a6c22ec
Merge branch 'master' of http://10.153.19.25:10105/r/ERP_override
8个文件已修改
756 ■■■■ 已修改文件
north-glass-erp/northglass-erp/src/components/sd/order/UpdateAlienEditor.vue 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/ProjectDetail.vue 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/sd/order/UpdateOrderCraft.vue 374 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/controller/pp/GlassOptimizeController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/mapper/pp/GlassOptimizeMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/service/mm/MaterialInventoryService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/service/pp/GlassOptimizeService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/resources/mapper/pp/GlassOptimize.xml 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/components/sd/order/UpdateAlienEditor.vue
@@ -219,6 +219,7 @@
  }
  leafer = new Leafer({ view: 'canvas' });
  try {
    let type=0;
    let minX = Infinity, minY = Infinity;
    let maxX = -Infinity, maxY = -Infinity;
    dxfData.value.entities.forEach(entity => {
@@ -231,6 +232,7 @@
        })
      }
      if (entity.type === 'ARC') {
        type=1
        const center = {x: entity.center.x, y: entity.center.y};
        const radius = entity.radius;
        const startAngle = entity.startAngle * (180 / Math.PI);
@@ -252,6 +254,13 @@
          maxX = Math.max(maxX, p.x);
          maxY = Math.max(maxY, p.y);
        });
      }
      if (entity.type === 'CIRCLE') {
        type=1
        minX = Math.min(minX, entity.center.x-entity.radius);
        minY = Math.min(minY, entity.center.y-entity.radius);
        maxX = Math.max(maxX, entity.center.x+entity.radius);
        maxY = Math.max(maxY, entity.center.y+entity.radius);
      }
    });
    if ((maxX - minX) / 400 > (maxY - minY) / 250) {
@@ -295,26 +304,46 @@
          if(entity.vertices.length==4){
            isQuadrilateral(maxY,minY,maxX,minX,point)
          }
          if(type==1){
            const polygon = new Polygon({
              points: point,
              stroke: '#f00'
            })
            setTimeout(() => {
              leafer.add(polygon);
            }, 30);
          }else{
            const polygon = new Polygon({
              points: point,
              fill: "#32cd79"
            })
            setTimeout(() => {
              leafer.add(polygon);
            }, 30);
          }
          const polygon = new Polygon({
            points: point,
            fill: '#32cd79',
          })
          setTimeout(() => {
            leafer.add(polygon);
          }, 30);
          break;
        case 'CIRCLE':
          big = (entity.radius * 2) / 400
          main.style.width = entity.radius * 2 / big + "px"
          main.style.height = entity.radius * 2 / big + "px"
          width.innerHTML = round(entity.radius * 2, 2)
          height.innerHTML = round(entity.radius * 2, 2)
            let CIRCLEX=(entity.center.x-minX-entity.radius)/big
            let CIRCLEY=((maxY - minY)-(entity.center.y-minY+entity.radius))/big
            if(big<(entity.radius * 2) / 400){
              big = (entity.radius * 2) / 400
              main.style.width = entity.radius * 2 / big + "px"
              main.style.height = entity.radius * 2 / big + "px"
              width.innerHTML = round(entity.radius * 2, 2)
              height.innerHTML = round(entity.radius * 2, 2)
              CIRCLEX=0
              CIRCLEY=0
            }
          const ellipse = new Ellipse({
            x:CIRCLEX,
            y:CIRCLEY,
            width: entity.radius * 2 / big,
            height: entity.radius * 2 / big,
            fill: "#32cd79"
            //fill: "#32cd79"
            stroke: '#f00',
          })
          setTimeout(() => {
            leafer.add(ellipse);
@@ -413,7 +442,10 @@
})
const save =  () => {
  emits('getUploadPicture', fileName.value,fileDate.value)
  if(fileName.value!=null&&fileDate.value!=null){
    emits('getUploadPicture', fileName.value,fileDate.value)
  }
}
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/ProjectDetail.vue
@@ -459,49 +459,99 @@
    }
    emit('getSmallPieceData', 1);
    optimizeData.value.glassDetails = [];
    xGrid.value.getTableData().fullData.forEach(items=>{
      let rackNoValue = 0;
      if (items.rackNo !== undefined && items.rackNo !== null && items.rackNo !== '') {
        rackNoValue = items.rackNo;
      }
      const detail={
        width :null,
        height :null,
        processId :null,
        layer :null,
        totalLayer :null,
        orderSort :null,
        markIcon :null,
        quantity:null,
        patchState :null,
        upGrind :null,
        downGrind :null,
        leftGrind:null,
        rightGrind :null,
        rackNo: rackNoValue
      }
      detail.width=items.width
      detail.height=items.height
      detail.processId=items.process_ids
      detail.layer=items.layer
      detail.totalLayer=items.total_layer
      detail.orderSort=items.order_number
      detail.markIcon=items.icon
      detail.patchState=items.patch_state
      detail.quantity=items.quantity
      detail.upGrind=items.longGrind1
      detail.downGrind=items.longGrind2
      detail.leftGrind=items.shortGrind1
      detail.rightGrind=items.shortGrind2
      detail.rackNo=items.rackNo
    // 从后端接口获取 glassDetail 数据,而不是从表格中读取
    fetchGlassDetailData();
      optimizeData.value.glassDetails .push(detail)
    })
    // xGrid.value.getTableData().fullData.forEach(items=>{
    //   let rackNoValue = 0;
    //   if (items.rackNo !== undefined && items.rackNo !== null && items.rackNo !== '') {
    //     rackNoValue = items.rackNo;
    //   }
    //   const detail={
    //     width :null,
    //     height :null,
    //     processId :null,
    //     layer :null,
    //     totalLayer :null,
    //     orderSort :null,
    //     markIcon :null,
    //     quantity:null,
    //     patchState :null,
    //     upGrind :null,
    //     downGrind :null,
    //     leftGrind:null,
    //     rightGrind :null,
    //     rackNo: rackNoValue
    //   }
    //   detail.width=items.width
    //   detail.height=items.height
    //   detail.processId=items.process_ids
    //   detail.layer=items.layer
    //   detail.totalLayer=items.total_layer
    //   detail.orderSort=items.order_number
    //   detail.markIcon=items.icon
    //   detail.patchState=items.patch_state
    //   detail.quantity=items.quantity
    //   detail.upGrind=items.longGrind1
    //   detail.downGrind=items.longGrind2
    //   detail.leftGrind=items.shortGrind1
    //   detail.rightGrind=items.shortGrind2
    //   detail.rackNo=items.rackNo
    //
    //   optimizeData.value.glassDetails .push(detail)
    // })
  }else{
    dialogVisible.value[index] = true;
  }
};
const fetchGlassDetailData = async () => {
  try {
    const res = await request.post(`/glassOptimize/optimizeInfo/${projectNo.value}/${username}`);
    console.log(res);
    if (res.code === "200" && res.data && res.data.data) {
      // 处理从后端获取的数据
      const glassDetailData = res.data.data.map(item => {
        let rackNoValue = 0;
        if (item.rackNo !== undefined && item.rackNo !== null && item.rackNo !== '') {
          rackNoValue = item.rackNo;
        }
        return {
          width: item.width,
          height: item.height,
          processId: item.processId,
          layer: item.layer,
          totalLayer: item.totalLayer,
          orderSort: item.order_number,
          markIcon: item.markIcon,
          quantity: item.quantity,
          patchState: item.patchState,
          upGrind: item.upGrind,
          downGrind: item.downGrind,
          leftGrind: item.leftGrind,
          rightGrind:item.rightGrind,
          layoutId:item.layoutId,
          rackNo: rackNoValue
        };
      });
      // 更新 optimizeData 中的 glassDetails
      optimizeData.value.glassDetails = glassDetailData;
      // 打开优化对话框
      dialogVisible.value[4] = true;
      console.log('获取到的 glassDetail 数据:', glassDetailData);
    } else {
      ElMessage.error('获取玻璃详情数据失败');
    }
  } catch (error) {
    console.error('获取 glassDetail 数据出错:', error);
    ElMessage.error('获取玻璃详情数据时发生错误');
  }
};
//关闭弹窗
const closeDialog = (index) => {
  dialogVisible.value[index] = false;
north-glass-erp/northglass-erp/src/views/sd/order/UpdateOrderCraft.vue
@@ -662,185 +662,213 @@
    leafer.clear()
  }
  leafer = new Leafer({ view: 'canvas' });
      try {
        let minX = Infinity, minY = Infinity;
        let maxX = -Infinity, maxY = -Infinity;
        dxfData.value.entities.forEach(entity => {
          if (entity.type === 'LINE' || entity.type === 'LWPOLYLINE') {
            entity.vertices.forEach(vertices => {
              minX = Math.min(vertices.x, minX);
              minY = Math.min(vertices.y, minY);
              maxX = Math.max(vertices.x, maxX);
              maxY = Math.max(vertices.y, maxY);
            })
          }
          if (entity.type === 'ARC') {
            const center = {x: entity.center.x, y: entity.center.y};
            const radius = entity.radius;
            const startAngle = entity.startAngle * (180 / Math.PI);
            const endAngle = entity.endAngle * (180 / Math.PI);
  try {
    let type=0;
    let minX = Infinity, minY = Infinity;
    let maxX = -Infinity, maxY = -Infinity;
    dxfData.value.entities.forEach(entity => {
      if (entity.type === 'LINE' || entity.type === 'LWPOLYLINE') {
        entity.vertices.forEach(vertices => {
          minX = Math.min(vertices.x, minX);
          minY = Math.min(vertices.y, minY);
          maxX = Math.max(vertices.x, maxX);
          maxY = Math.max(vertices.y, maxY);
        })
      }
      if (entity.type === 'ARC') {
        type=1
        const center = {x: entity.center.x, y: entity.center.y};
        const radius = entity.radius;
        const startAngle = entity.startAngle * (180 / Math.PI);
        const endAngle = entity.endAngle * (180 / Math.PI);
            const points = [];
            const steps = 32;
            for (let i = 0; i <= steps; i++) {
              const angle = startAngle + (endAngle - startAngle) * (i / steps);
              const x = center.x + radius * Math.cos(angle * Math.PI / 180);
              const y = center.y + radius * Math.sin(angle * Math.PI / 180);
              points.push({x, y});
            }
            points.forEach(p => {
              minX = Math.min(minX, p.x);
              minY = Math.min(minY, p.y);
              maxX = Math.max(maxX, p.x);
              maxY = Math.max(maxY, p.y);
            });
          }
        });
        if ((maxX - minX) / 400 > (maxY - minY) / 250) {
          big = (maxX - minX) / 400
        } else {
          big = (maxY - minY) / 250
        const points = [];
        const steps = 32;
        for (let i = 0; i <= steps; i++) {
          const angle = startAngle + (endAngle - startAngle) * (i / steps);
          const x = center.x + radius * Math.cos(angle * Math.PI / 180);
          const y = center.y + radius * Math.sin(angle * Math.PI / 180);
          points.push({x, y});
        }
        Object.values(dxfData.value.entities).forEach(entity => {
          switch (entity.type) {
            case 'LINE':
              main.style.width = (maxX - minX) / big + "px"
              main.style.height = (maxY - minY) / big + "px"
              main.style.backgroundColor = "#8d9095"
              width.innerHTML = round(maxX - minX, 2)
              height.innerHTML = round(maxY - minY, 2)
              const line = new Line({
                points: [(entity.vertices[0].x - minX) / big, ((maxY - minY) - (entity.vertices[0].y- minY)) / big,
                  (entity.vertices[1].x - minX) / big, ((maxY - minY) - (entity.vertices[1].y - minY)) / big],
                stroke: '#f00',
                strokeWidth: 1
              })
              setTimeout(() => {
                leafer.add(line);
              }, 30);
              break;
            case 'LWPOLYLINE':
              main.style.width = (maxX - minX) / big + "px"
              main.style.height = (maxY - minY) / big + "px"
              main.style.backgroundColor = "#8d9095"
              width.innerHTML = round(maxX - minX, 2)
              height.innerHTML = round(maxY - minY, 2)
              let point = entity.vertices.map(v => [
                (v.x - minX) / big,
                toBottomOrigin((v.y - minY) / big, (maxY - minY) / big),
              ]).flat()
              if(entity.vertices.length==4){
                isQuadrilateral(maxY,minY,maxX,minX,point)
              }
              const polygon = new Polygon({
                points: point,
                fill: '#32cd79',
              })
              setTimeout(() => {
                leafer.add(polygon);
              }, 30);
              break;
            case 'CIRCLE':
              big = (entity.radius * 2) / 400
              main.style.width = entity.radius * 2 / big + "px"
              main.style.height = entity.radius * 2 / big + "px"
              width.innerHTML = round(entity.radius * 2, 2)
              height.innerHTML = round(entity.radius * 2, 2)
              const ellipse = new Ellipse({
                width: entity.radius * 2 / big,
                height: entity.radius * 2 / big,
                fill: "#32cd79"
              })
              setTimeout(() => {
                leafer.add(ellipse);
              }, 30);
              break;
            case 'ELLIPSE':
              console.log(entity)
              const {majorAxisEndPoint, axisRatio} = entity;
              const dx = majorAxisEndPoint.x;
              const dy = majorAxisEndPoint.y;
              const a = Math.sqrt(dx ** 2 + dy ** 2);
              const c = a * axisRatio;
              const θ = Math.atan2(dy, dx);
              const l = axisRatio * (180 / Math.PI);
              if ((a * 2) / 400 > (c * 2) / 250) {
                big = (a * 2) / 400
              } else {
                big = (c * 2) / 250
              }
              main.style.width = a * 2 / big + "px"
              main.style.height = c * 2 / big + "px"
              width.innerHTML = round(a * 2, 2)
              height.innerHTML = round(c * 2, 2)
              const ellipse2 = new Ellipse({
                width: a * 2 / big,
                height: c * 2 / big,
                fill: "#32cd79",
              })
              setTimeout(() => {
                leafer.add(ellipse2);
              }, 30);
              break;
            case 'ARC':
              const center = {x: entity.center.x, y: entity.center.y};
              const radius = entity.radius;
              const startAngle = entity.startAngle * (180 / Math.PI);
              const endAngle = entity.endAngle * (180 / Math.PI);
              if ((maxX - minX) / 400 > (maxY - minY) / 250) {
                big = (maxX - minX) / 400
              } else {
                big = (maxY - minY) / 250
              }
              // 计算圆弧的起点和终点
              const startX = (center.x + radius * Math.cos(entity.startAngle) - minX);
              const startY = (maxY - minY) - ((center.y + radius * Math.sin(entity.startAngle)) - minY);
              const endX = (center.x + radius * Math.cos(entity.endAngle) - minX);
              const endY = (maxY - minY) - ((center.y + radius * Math.sin(entity.endAngle)) - minY);
              // 创建圆弧路径
              const path = new Path({
                path: `M ${startX / big} ${startY / big} A ${radius / big} ${radius / big} 0 ${endAngle - startAngle > 180 ? 1 : 0} 0 ${endX / big} ${endY / big}`,
                stroke: '#f00',
                strokeWidth: 1,
              });
              setTimeout(() => {
                leafer.add(path);
              }, 30);
              break;
          }
        })
        trademarkAttr.value.xMargin=trademarkAttr.value.xMargin+1
        trademarkAttr.value.xMargin=trademarkAttr.value.xMargin-1
        trademarkAttr.value.location = t('craft.lowLeft')
      } catch (error) {
        console.error('解析DXF文件时出错:', error);
        points.forEach(p => {
          minX = Math.min(minX, p.x);
          minY = Math.min(minY, p.y);
          maxX = Math.max(maxX, p.x);
          maxY = Math.max(maxY, p.y);
        });
      }
      if (entity.type === 'CIRCLE') {
        type=1
        minX = Math.min(minX, entity.center.x-entity.radius);
        minY = Math.min(minY, entity.center.y-entity.radius);
        maxX = Math.max(maxX, entity.center.x+entity.radius);
        maxY = Math.max(maxY, entity.center.y+entity.radius);
      }
    });
    if ((maxX - minX) / 400 > (maxY - minY) / 250) {
      big = (maxX - minX) / 400
    } else {
      big = (maxY - minY) / 250
    }
    Object.values(dxfData.value.entities).forEach(entity => {
      switch (entity.type) {
        case 'LINE':
          main.style.width = (maxX - minX) / big + "px"
          main.style.height = (maxY - minY) / big + "px"
          main.style.backgroundColor = "#8d9095"
          width.innerHTML = round(maxX - minX, 2)
          height.innerHTML = round(maxY - minY, 2)
          const line = new Line({
            points: [(entity.vertices[0].x - minX) / big, ((maxY - minY) - (entity.vertices[0].y- minY)) / big,
              (entity.vertices[1].x - minX) / big, ((maxY - minY) - (entity.vertices[1].y - minY)) / big],
            stroke: '#f00',
            strokeWidth: 1
          })
          setTimeout(() => {
            leafer.add(line);
          }, 30);
          break;
        case 'LWPOLYLINE':
          main.style.width = (maxX - minX) / big + "px"
          main.style.height = (maxY - minY) / big + "px"
          main.style.backgroundColor = "#8d9095"
          width.innerHTML = round(maxX - minX, 2)
          height.innerHTML = round(maxY - minY, 2)
          let point = entity.vertices.map(v => [
            (v.x - minX) / big,
            toBottomOrigin((v.y - minY) / big, (maxY - minY) / big),
          ]).flat()
          if(entity.vertices.length==4){
            isQuadrilateral(maxY,minY,maxX,minX,point)
          }
          if(type==1){
            const polygon = new Polygon({
              points: point,
              stroke: '#f00'
            })
            setTimeout(() => {
              leafer.add(polygon);
            }, 30);
          }else{
            const polygon = new Polygon({
              points: point,
              fill: "#32cd79"
            })
            setTimeout(() => {
              leafer.add(polygon);
            }, 30);
          }
          break;
        case 'CIRCLE':
          let CIRCLEX=(entity.center.x-minX-entity.radius)/big
          let CIRCLEY=((maxY - minY)-(entity.center.y-minY+entity.radius))/big
          if(big<(entity.radius * 2) / 400){
            big = (entity.radius * 2) / 400
            main.style.width = entity.radius * 2 / big + "px"
            main.style.height = entity.radius * 2 / big + "px"
            width.innerHTML = round(entity.radius * 2, 2)
            height.innerHTML = round(entity.radius * 2, 2)
            CIRCLEX=0
            CIRCLEY=0
          }
          const ellipse = new Ellipse({
            x:CIRCLEX,
            y:CIRCLEY,
            width: entity.radius * 2 / big,
            height: entity.radius * 2 / big,
            //fill: "#32cd79"
            stroke: '#f00',
          })
          setTimeout(() => {
            leafer.add(ellipse);
          }, 30);
          break;
        case 'ELLIPSE':
          console.log(entity)
          const {majorAxisEndPoint, axisRatio} = entity;
          const dx = majorAxisEndPoint.x;
          const dy = majorAxisEndPoint.y;
          const a = Math.sqrt(dx ** 2 + dy ** 2);
          const c = a * axisRatio;
          const θ = Math.atan2(dy, dx);
          const l = axisRatio * (180 / Math.PI);
          if ((a * 2) / 400 > (c * 2) / 250) {
            big = (a * 2) / 400
          } else {
            big = (c * 2) / 250
          }
          main.style.width = a * 2 / big + "px"
          main.style.height = c * 2 / big + "px"
          width.innerHTML = round(a * 2, 2)
          height.innerHTML = round(c * 2, 2)
          const ellipse2 = new Ellipse({
            width: a * 2 / big,
            height: c * 2 / big,
            fill: "#32cd79",
          })
          setTimeout(() => {
            leafer.add(ellipse2);
          }, 30);
          break;
        case 'ARC':
          const center = {x: entity.center.x, y: entity.center.y};
          const radius = entity.radius;
          const startAngle = entity.startAngle * (180 / Math.PI);
          const endAngle = entity.endAngle * (180 / Math.PI);
          if ((maxX - minX) / 400 > (maxY - minY) / 250) {
            big = (maxX - minX) / 400
          } else {
            big = (maxY - minY) / 250
          }
          // 计算圆弧的起点和终点
          const startX = (center.x + radius * Math.cos(entity.startAngle) - minX);
          const startY = (maxY - minY) - ((center.y + radius * Math.sin(entity.startAngle)) - minY);
          const endX = (center.x + radius * Math.cos(entity.endAngle) - minX);
          const endY = (maxY - minY) - ((center.y + radius * Math.sin(entity.endAngle)) - minY);
          // 创建圆弧路径
          const path = new Path({
            path: `M ${startX / big} ${startY / big} A ${radius / big} ${radius / big} 0 ${endAngle - startAngle > 180 ? 1 : 0} 0 ${endX / big} ${endY / big}`,
            stroke: '#f00',
            strokeWidth: 1,
          });
          setTimeout(() => {
            leafer.add(path);
          }, 30);
          break;
      }
    })
    trademarkAttr.value.xMargin=trademarkAttr.value.xMargin+1
    trademarkAttr.value.xMargin=trademarkAttr.value.xMargin-1
    trademarkAttr.value.location = t('craft.lowLeft')
  } catch (error) {
    console.error('解析DXF文件时出错:', error);
  }
};
const handleClosed = () => {
north-glass-erp/src/main/java/com/example/erp/controller/pp/GlassOptimizeController.java
@@ -39,6 +39,14 @@
        return Result.seccess(glassOptimizeService.projectInfoSv(projectNo,username));
    }
    // 优化信息传入
    @ApiOperation("优化传入信息接口")
    @PostMapping  ("/optimizeInfo/{projectNo}/{username}")
    public Result optimizeInfo(@PathVariable String projectNo,@PathVariable String username){
        return Result.seccess(glassOptimizeService.optimizeInfoSv(projectNo,username));
    }
    //工程信息流程卡
    @ApiOperation("工程信息流程卡接口")
    @PostMapping  ("/getProcessCard/{projectNo}")
north-glass-erp/src/main/java/com/example/erp/mapper/pp/GlassOptimizeMapper.java
@@ -17,7 +17,12 @@
    List<Map<String, Object>> firstOptimization(String projectNo);
    List<Map<String, Object>> directOptimization(String projectNo);
    List<Map<String, Object>> analogComputationOptimization(String projectNo);
    List<Map<String, Object>> computeAndOptimization(String projectNo);
    List<Map<String, Object>> getOptimizeDetail(String projectNo);
@@ -152,6 +157,8 @@
    List<Map<String, Object>> getGrindingTrimming(String username);
    List<Map<String, Object>> getGrindingOptimize(String username);
    List<Map<String, Object>> getEdgeTrimming(String username);
    Boolean updateOptimizeConfig(String json,Integer type,String username);
@@ -177,4 +184,6 @@
    List<Map<String, Object>> getProcessCardMpThirdParty(String projectNo);
    List<Map<String, Object>> getProjectByProjectNoSv(String projectNo);
    void updateFlowCardRack(String processId, String technologyNumber, int rackValue);
}
north-glass-erp/src/main/java/com/example/erp/service/mm/MaterialInventoryService.java
@@ -1000,6 +1000,8 @@
                }
                materialInventoryMapper.updateMaterialInventoryAvailableInventoryOutMes(Long.valueOf(optimizeUses.getRawStockCode()),quantity);
                materialInventoryMapper.updateOptimizeUsesMes(optimizeUses.getId(),quantity);
            }else{
                return false;
            }
            //保存日志
north-glass-erp/src/main/java/com/example/erp/service/pp/GlassOptimizeService.java
@@ -336,6 +336,40 @@
    }
    public Object optimizeInfoSv(String projectNo, String username) {
        Map<String, Object> stringObjectMap = glassOptimizeMapper.selectProjectCount(projectNo);
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> dataList = null;
        if (Integer.parseInt(stringObjectMap.get("tempering_state").toString())==1){
            dataList = glassOptimizeMapper.computeAndOptimization(projectNo);
        } else {
            dataList = glassOptimizeMapper.directOptimization(projectNo);
        }
        // 获取磨量配置数据
        List<Map<String, Object>> grindingTrimmingList = glassOptimizeMapper.getGrindingOptimize(username);
        // 将磨量配置数据拼接到每条主数据后面
        if (dataList != null && !dataList.isEmpty() && grindingTrimmingList != null && !grindingTrimmingList.isEmpty()) {
            // 获取第一条磨量配置数据(通常只有一条记录)
            Map<String, Object> grindingConfig = grindingTrimmingList.get(0);
            // 将磨量配置添加到每条主数据中
            for (Map<String, Object> dataItem : dataList) {
                // 将磨量配置的字段添加到每条数据中
                for (Map.Entry<String, Object> entry : grindingConfig.entrySet()) {
                    // 避免覆盖原有字段
                    if (!dataItem.containsKey(entry.getKey())) {
                        dataItem.put(entry.getKey(), entry.getValue());
                    }
                }
            }
        }
        map.put("data", dataList);
        return map;
    }
    //工程信息流程卡
    public Map<String, Object> getProcessCardSv(String projectNo) {
        Map<String, Object> map = new HashMap<>();
@@ -556,11 +590,25 @@
                if(projectType.equals("2")){
                    deleteProject(projectId,2);
                }
                // 创建一个映射来存储 (processId-technologyNumber) 组合到 rack 编号的映射
                Map<String, Integer> rackMap = new HashMap<>();
                int rackCounter = 1;
                for (FlowCard flowCard : flowCardList) {
                    // 为每个唯一的 processId-technologyNumber 组合分配 rack 编号
                    String key = flowCard.getProcessId() + "-" + flowCard.getTechnologyNumber();
                    if (!rackMap.containsKey(key)) {
                        rackMap.put(key, rackCounter++);
                    }
                    int rackValue = rackMap.get(key);
                    if(flowCard.getPatchState().equals(0)){
                        state1=1;
                        //给流程卡表添加对应的工程号
                        Boolean a=glassOptimizeMapper.updateFlowCardProject(flowCard.getProcessId(),flowCard.getTechnologyNumber(),projectId);
                        Boolean a = glassOptimizeMapper.updateFlowCardProject(flowCard.getProcessId(),flowCard.getTechnologyNumber(),projectId);
                        // 更新流程卡的rack字段
                        glassOptimizeMapper.updateFlowCardRack(flowCard.getProcessId(), flowCard.getTechnologyNumber(), rackValue);
                        area = glassOptimizeMapper.getSelectArea(flowCard.getProcessId(),flowCard.getTechnologyNumber()).doubleValue();
                        sumArea = sumArea.add(BigDecimal.valueOf(area));
                        sumQuantity +=flowCard.getQuantity();
@@ -843,4 +891,5 @@
        map.put("data", glassOptimizeMapper.getProjectByProjectNoSv(projectNo));
        return map;
    }
}
north-glass-erp/src/main/resources/mapper/pp/GlassOptimize.xml
@@ -179,6 +179,73 @@
    </select>
    <select id="directOptimization">
        (SELECT
             c.project_no,
             d.child_width as 'width',
             d.child_height as 'height',
             c.quantity,
             concat( c.process_id, '-', c.technology_number ) AS 'process_id',
             c.process_id AS processId,
             c.technology_number as layer,
             c.layers_number as totalLayer,
             round( d.area * c.quantity, 4 ) as 'area',
             c.order_number,
             d.icon  AS markIcon,
             op.project_name,
             0 as patchState,
             c.rack AS rackNo,
             0 as layoutId
         FROM
             pp.flow_card c
                 LEFT JOIN sd.order_glass_detail d ON c.order_id = d.order_id
                 AND c.order_number = d.order_number
                 AND c.technology_number = d.technology_number
                 INNER JOIN pp.optimize_project AS op ON op.project_no = c.project_no
         WHERE
             c.project_no IS NOT NULL
           and c.project_no = #{projectNo}
         ORDER BY
             c.process_id,
             c.order_number
        ) union
        (
            SELECT
                c.project_no,
                d.child_width as 'width',
                d.child_height as 'height',
                c.patch_num as quantity,
                concat( c.process_id, '-', c.technology_number ) AS 'process_id',
                c.process_id AS 'process_ids',
                c.technology_number as layer,
                fc.layers_number as total_layer,
                round( d.area * c.patch_num, 4 ) as 'area',
                c.order_sort as order_number,
                d.icon,
                op.project_name,
                1 as patch_state,
                a.id as rackNo,
                0 as layoutId
            FROM
                pp.patch_log c
                    LEFT JOIN sd.order_glass_detail d ON c.order_id = d.order_id
                    AND c.order_sort = d.order_number
                    AND c.technology_number = d.technology_number
                    INNER JOIN pp.optimize_project AS op ON op.project_no = c.project_no
                    LEFT JOIN pp.flow_card fc ON c.process_id = fc.process_id and fc.technology_number=c.technology_number
                    left join
                (select (@row_number := @row_number + 1) as id,process_id as process_id,technology_number as technology_number from (select process_id,technology_number from pp.flow_card tt where project_no =#{projectNo} group by process_id,technology_number) tt,(select @row_number := 0) as t) a
                on a.process_id=c.process_id and a.technology_number=c.technology_number
            WHERE
                c.project_no IS NOT NULL
              and c.project_no = #{projectNo}
            ORDER BY
                a.id,
                c.process_id,
                c.order_sort)
    </select>
    <!--优化查询-->
    <select id="analogComputationOptimization">
        SELECT
@@ -238,6 +305,52 @@
            LENGTH( h.layout_id ),
            h.layout_id;
    </select>
    <!--优化查询-->
    <select id="computeAndOptimization">
        SELECT
            c.rack AS rackNo,
            h.layout_id as layoutId,
            h.width AS width,
            h.height AS height,
            count( 1 ) AS quantity,
            concat( h.process_id, '-', h.layer ) AS processId,
            h.process_id as process_ids,
            h.layer,
            c.layers_number as totalLayer,
            round( d.area * count( 1 ), 4 ) AS 'area',
            c.order_number,
            h.order_sort AS orderSort,
            d.icon AS markIcon,
            h.patch_state  AS patchState
        from
            pp.`optimize_heat_detail` h
                LEFT JOIN pp.flow_card c ON h.process_id = c.process_id
                AND h.layer = c.technology_number
                AND h.order_sort = c.order_number
                LEFT JOIN sd.order_glass_detail d ON c.order_id = d.order_id
                AND c.order_number = d.order_number
                AND c.technology_number = d.technology_number
        WHERE
            h.project_no = #{projectNo}
        GROUP BY
            h.layout_id,
            h.width,
            h.height,
            h.process_id,
            h.layer,
            d.area,
            c.quantity,
            d.child_width,
            d.child_height,
            c.order_number,
            d.icon
        ORDER BY
            LENGTH( h.layout_id ),
            h.layout_id;
    </select>
    <select id="getOptimizeDetail">
@@ -1309,10 +1422,25 @@
        from  pp.optimize_config oc where config_type=4 and creater=#{username}
    </select>
    <select id="getGrindingOptimize">
        select
            CAST(REPLACE(JSON_EXTRACT( oc.config_detail, '$.left_edge' ), '"', '') AS DECIMAL(10,2)) as leftGrind,
            CAST(REPLACE(JSON_EXTRACT( oc.config_detail, '$.up_edge' ), '"', '') AS DECIMAL(10,2)) as upGrind,
            CAST(REPLACE(JSON_EXTRACT( oc.config_detail, '$.right_edge' ), '"', '') AS DECIMAL(10,2)) as rightGrind,
            CAST(REPLACE(JSON_EXTRACT( oc.config_detail, '$.down_edge' ), '"', '') AS DECIMAL(10,2)) as downGrind
        from  pp.optimize_config oc where config_type=4 and creater=#{username}
    </select>
    <update id="updateOptimizeConfig">
        UPDATE pp.optimize_config set config_detail=#{json},create_time=now()
        where config_type=#{type} and creater=#{username}
    </update>
    <update id="updateFlowCardRack">
        UPDATE pp.flow_card
        SET rack = #{rackValue}
        WHERE process_id = #{processId} AND technology_number = #{technologyNumber}
    </update>
    <select id="simulatedTypesettingUsingOpt">
        SELECT