wuyouming666
2025-03-25 b8a452ae67c99a4279b9450d1aa7158a29bc45c9
版图调整、打印
6个文件已修改
448 ■■■■■ 已修改文件
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/OptimizationRectPrint.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/OptimizeControl.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue 169 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/RectRenderer.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/entity/pp/LayoutsData.java 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/service/pp/JsonToOptConverter.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/OptimizationRectPrint.vue
@@ -1,6 +1,7 @@
<template>
  <div>
    <button @click="handlePrint"  style="position: fixed; bottom: 20px; right: 20px; padding: 10px; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer;">打印版图</button>
    <el-button id="button" type="primary" @click="handlePrint">打印版图</el-button>
    <RectRenderer 
      ref="rectRenderer"
      :layoutData="layoutData" 
@@ -12,13 +13,47 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref,onMounted } from 'vue';
import RectRenderer from './page/RectRenderer.vue';
import mockLayoutData from '../../../components/pp/MockData';
const layoutData = ref(mockLayoutData);
import request from "@/utils/request";
import { useI18n } from "vue-i18n";
//const layoutData = ref(mockLayoutData);
const rectRenderer = ref(null);
const savedProjectNo = localStorage.getItem('projectNo');
const processId = savedProjectNo;
const layoutData = ref(null);
const selectLayout = () => {
request.post(`/glassOptimize/selectOptimizeResult/${processId}`)
.then((res) => {
  if (res.code == 200) {
    try {
      const parsedData = JSON.parse(res.data.data[0].Layouts);
      layoutData.value = parsedData;
    } catch (error) {
    }
  } else {
  }
})
.catch((error) => {
  console.error("请求失败:", error);
  ElMessage.error(t('basicData.msg.requestFailed'));
});
}
onMounted(() => {
  selectLayout();
});
const handlePrint = () => {
  // 创建一个隐藏的iframe
  const iframe = document.createElement('iframe');
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/OptimizeControl.vue
@@ -15,7 +15,7 @@
  </template>
  
  <script setup>
  import { ref } from 'vue';
  import { ref,onMounted } from 'vue';
  import RectRenderer from './page/RectRenderer.vue';
  import mockLayoutData from '../../../components/pp/MockData';
  import request from "@/utils/request";
@@ -23,7 +23,52 @@
import { ElMessage } from "element-plus";
const { t } = useI18n();
  const layoutData = ref(mockLayoutData);
 // const layoutData = ref(mockLayoutData);
  const savedProjectNo = localStorage.getItem('projectNo');
const processId = savedProjectNo;
const layoutData = ref(null);
const selectLayout = () => {
request.post(`/glassOptimize/selectOptimizeResult/${processId}`)
.then((res) => {
  if (res.code == 200) {
    try {
      const parsedData = JSON.parse(res.data.data[0].Layouts);
      layoutData.value = parsedData;
    } catch (error) {
    }
  } else {
  }
})
.catch((error) => {
  console.error("请求失败:", error);
  ElMessage.error(t('basicData.msg.requestFailed'));
});
}
onMounted(() => {
  selectLayout();
});
  
  const submitLayouts = async () => {
  try {
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
@@ -53,7 +53,8 @@
          >
            <div class="rect-content">
              <div class="size">{{ rect.w }}×{{ rect.h }}</div>
              <div class="jia-hao">{{ rect.JiaHao }}</div>
              <div v-if="showJiaHao" class="jia-hao">{{ rect.JiaHao }}</div>
              <div v-if="showProcessId" class="liuchengka">{{ rect.liuchengka }}</div>
            </div>
          </div>
        </div>
@@ -72,7 +73,13 @@
import request from "@/utils/request";
import { useI18n } from "vue-i18n";
import { ElMessage, ElMessageBox } from "element-plus";
import useUserInfoStore from "@/stores/userInfo";
const { t } = useI18n();
const userStore = useUserInfoStore()
const username = userStore.user.userName
const props = defineProps({
  layoutData: { type: Object, required: true },
  gw: { type: Number, default: 1000 },
@@ -93,7 +100,9 @@
const dragging = ref(false);
const dragStartPos = ref({ x: 0, y: 0 });
const dragRect = ref(null);
const showJiaHao = ref(false); // 新增:控制jia-hao的显示状态
const showProcessId= ref(false);
const themeColor=ref(null)
// 提交布局数据到后端
const submitLayouts = async () => {
  layouts.value.forEach(layout => {
@@ -119,6 +128,44 @@
    }
  });
};
//获取优化设置
const fetchSettings = async (username) => {
  try {
    const response = await request.post(`/glassOptimize/selectOptimizeParms/${username}`);
    if (response.code == 200) {
      if (!response.data) {
        console.error('响应数据为空');
        return;
      }
      const parsedData = JSON.parse(response.data);
      console.log(parsedData.display.frameNumber)
      if (parsedData.display && parsedData.display.frameNumber) {
        showJiaHao.value = parsedData.display.frameNumber;
      }
      if (parsedData.display && parsedData.display.orderNumber) {
        showProcessId.value = parsedData.display.orderNumber;
      }
      if (parsedData.display ) {
        themeColor.value = parsedData.display.themeColor;
      }
      console.log( parsedData);
    } else {
      console.error('请求失败,状态码:', response.code);
    }
  } catch (error) {
    console.error('请求发生错误:', error);
  }
};
const showAddDialog = (layoutIndex, rectIndex) => {
  ElMessageBox.prompt('请输入成品的宽度和高度', '添加成品', {
@@ -146,8 +193,8 @@
      y: 0,
      w: values[0],
      h: values[1],
      isRemain: false,
      JiaHao: `新成品`
      isRemain: false
    };
    addNewRect(layoutIndex, newRect);
  })
@@ -210,7 +257,7 @@
    top: `${rect.y * scale}px`,
    width: `${rect.w * scale}px`,
    height: `${rect.h * scale}px`,
    backgroundColor: rect.isRemain ? '#f0f0f0' : '#a0d8ef',
    backgroundColor: rect.isRemain ? '#f0f0f0' : themeColor.value,
    border: '1px solid #000',
    cursor: 'pointer',
    draggable: !rect.isRemain,
@@ -354,38 +401,6 @@
  contextMenu.style.padding = '5px';
  contextMenu.style.zIndex = 1001;
  const mergeLeftItem = document.createElement('div');
  mergeLeftItem.textContent = '向左合并';
  mergeLeftItem.style.cursor = 'pointer';
  mergeLeftItem.addEventListener('click', () => {
    mergeGrayRects(layoutIndex, rectIndex, 'left');
    document.body.removeChild(contextMenu);
  });
  const mergeRightItem = document.createElement('div');
  mergeRightItem.textContent = '向右合并';
  mergeRightItem.style.cursor = 'pointer';
  mergeRightItem.addEventListener('click', () => {
    mergeGrayRects(layoutIndex, rectIndex, 'right');
    document.body.removeChild(contextMenu);
  });
  const mergeUpItem = document.createElement('div');
  mergeUpItem.textContent = '向上合并';
  mergeUpItem.style.cursor = 'pointer';
  mergeUpItem.addEventListener('click', () => {
    mergeGrayRects(layoutIndex, rectIndex, 'up');
    document.body.removeChild(contextMenu);
  });
  const mergeDownItem = document.createElement('div');
  mergeDownItem.textContent = '向下合并';
  mergeDownItem.style.cursor = 'pointer';
  mergeDownItem.addEventListener('click', () => {
    mergeGrayRects(layoutIndex, rectIndex, 'down');
    document.body.removeChild(contextMenu);
  });
  const addItem = document.createElement('div');
  addItem.textContent = '添加成品';
  addItem.style.cursor = 'pointer';
@@ -394,10 +409,6 @@
    document.body.removeChild(contextMenu);
  });
  contextMenu.appendChild(mergeLeftItem);
  contextMenu.appendChild(mergeRightItem);
  contextMenu.appendChild(mergeUpItem);
  contextMenu.appendChild(mergeDownItem);
  contextMenu.appendChild(addItem);
  document.body.appendChild(contextMenu);
@@ -480,7 +491,7 @@
    rect.y = Math.round(rect.y);
    // 只调整位置对齐,不调整大小
    //adjustAlignmentPosition(layoutIndex, rectIndex);
    adjustAlignmentPosition(layoutIndex, rectIndex);
    // 调整灰色矩形
    adjustGrayRectangles(layoutIndex);
@@ -513,49 +524,6 @@
  });
};
const mergeGrayRects = (layoutIndex, rectIndex, direction) => {
  const layout = layouts.value[layoutIndex];
  const rect = layout.rects[rectIndex];
  const grayRects = layout.rects.filter(r => r.isRemain);
  let targetRect = null;
  switch (direction) {
    case 'left':
      targetRect = grayRects.find(r => r.x + r.w === rect.x && r.y === rect.y && r.h === rect.h);
      break;
    case 'right':
      targetRect = grayRects.find(r => r.x === rect.x + rect.w && r.y === rect.y && r.h === rect.h);
      break;
    case 'up':
      targetRect = grayRects.find(r => r.y + r.h === rect.y && r.x === rect.x && r.w === rect.w);
      break;
    case 'down':
      targetRect = grayRects.find(r => r.y === rect.y + rect.h && r.x === rect.x && r.w === rect.w);
      break;
  }
  if (targetRect) {
    const mergedRect = {
      x: Math.min(rect.x, targetRect.x),
      y: Math.min(rect.y, targetRect.y),
      w: Math.max(rect.x + rect.w, targetRect.x + targetRect.w) - Math.min(rect.x, targetRect.x),
      h: Math.max(rect.y + rect.h, targetRect.y + targetRect.h) - Math.min(rect.y, targetRect.y),
      isRemain: true
    };
    const index = layout.rects.indexOf(rect);
    layout.rects.splice(index, 1);
    const targetIndex = layout.rects.indexOf(targetRect);
    layout.rects.splice(targetIndex, 1);
    layout.rects.push(mergedRect);
    adjustGrayRectangles(layoutIndex);
  } else {
    ElMessage.warning('无法合并,没有相邻的灰色矩形');
  }
};
const mergeAdjacentGrayRects = (rects) => {
  const grayRects = rects.filter(r => r.isRemain);
  let merged = [];
@@ -585,7 +553,7 @@
               current.x === last.x && 
               current.w === last.w) {
      last.h += current.h;
      last.x = Math.round(last);
      last.x = Math.round(last.x);
      last.y = Math.round(last.y);
      last.w = Math.round(last.w);
      last.h = Math.round(last.h);
@@ -745,7 +713,7 @@
      rect.x -= actualStep;
      break;
    case 'right':
      rect.x += actualStep;
      rect.x +=actualStep;
      break;
  }
@@ -861,14 +829,33 @@
  layouts.value = props.layoutData.Layouts;
};
let clickEventListener = null;
onMounted(() => {
  setTimeout(updateLayout, 1000);
  fetchSettings(username);
  setTimeout(updateLayout, 500);
  selectedLayoutIndex.value = 0;
   // 添加全局点击事件监听器
   clickEventListener = (event) => {
    // 检查是否存在右键菜单
    const contextMenus = document.querySelectorAll('.context-menu');
    if (contextMenus.length > 0) {
      // 移除所有右键菜单
      contextMenus.forEach(menu => menu.remove());
    }
  };
  document.addEventListener('click', clickEventListener);
});
onUnmounted(() => {
  rectsElements.value = {};
   // 移除全局点击事件监听器
   if (clickEventListener) {
    document.removeEventListener('click', clickEventListener);
  }
});
</script>
@@ -876,6 +863,10 @@
.layout-wrapper {
  position: relative;
  margin-top: 50px;
}
.layout-rect {
  user-select: none;
}
.layout-container {
@@ -907,7 +898,7 @@
  font-size: 12px;
}
.jia-hao {
.jia-hao .liuchengka {
  grid-row: 2;
  grid-column: 1;
  margin: auto;
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/RectRenderer.vue
@@ -117,7 +117,7 @@
};
onMounted(() => {
  updateLayout();
  setTimeout(updateLayout, 500);
});
onUnmounted(() => {
north-glass-erp/src/main/java/com/example/erp/entity/pp/LayoutsData.java
@@ -29,6 +29,12 @@
    public int getWidth() {
        return width;
    }
    public int getSameCount() {
        return sameCount;
    }
    public String getWuliao() {
        return material;
    }
    public int getHeight() {
        return height;
@@ -43,7 +49,7 @@
    @JsonProperty("isRemain")
    private boolean isRemain;
    @JsonProperty("h")
    private int height;
    private int h;
    @JsonProperty("DM2")
    private int dm2;
    @JsonProperty("xuhao")
@@ -59,7 +65,7 @@
    @JsonProperty("LM1")
    private int lm1;
    @JsonProperty("w")
    private int width;
    private int W;
    @JsonProperty("x")
    private int x;
    @JsonProperty("y")
@@ -68,15 +74,40 @@
    private int rowNumber;
    public int getWidth() {
        return width;
        return W;
    }
    public int getHeight() {
        return height;
        return h;
    }
    public String getProcessCard() {
        return processCard;
    }
    public int getW() {
        return W;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public String getJiaHao() {
        return jiaHao;
    }
    public int getH() {
        return h;
    }
    public boolean isRemain() {
        return isRemain;
    }
}
}
north-glass-erp/src/main/java/com/example/erp/service/pp/JsonToOptConverter.java
@@ -4,8 +4,13 @@
import com.example.erp.entity.pp.LayoutsData.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
 * @author SNG-012
 */
public class JsonToOptConverter {
    public static String convertToJson(LayoutsData layoutsData) throws IOException {
@@ -18,15 +23,20 @@
        addHeader(optContent);
        addSignatures(optContent);
        addPatterns(optContent, layoutsData);
        addCuttings(optContent, layoutsData);
        addShapes(optContent, layoutsData);
        addInfos(optContent, layoutsData);
        return optContent.toString();
    }
    private static void addHeader(StringBuilder optContent) {
        optContent.append("[OPT_Header]\n");
        optContent.append("OPTCutVersion=4.0\n");
        optContent.append("OPTCutVersion=5.0\n");
        optContent.append("Dimension=mm\n");
        optContent.append("Date=2025/2/25\n\n");
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");
        String formattedDate = sdf.format(currentDate);
        optContent.append("Date=" + formattedDate + "\n\n");
    }
    private static void addSignatures(StringBuilder optContent) {
@@ -36,70 +46,92 @@
    private static void addPatterns(StringBuilder optContent, LayoutsData layoutsData) {
        optContent.append("[OPT_Pattern]\n");
        optContent.append("GlassID=FL4\n");
        optContent.append("GlassThickness=4.00\n");
        optContent.append("GlassCoated=0\n");
        optContent.append("GlassType=0\n");
        optContent.append("Pieces=" + layoutsData.getLayouts().size() + "\n");
        optContent.append("Width=" + layoutsData.getLayouts().get(0).getWidth() + ".0\n");
        optContent.append("Height=" + layoutsData.getLayouts().get(0).getHeight() + ".0\n");
        optContent.append("TrimLeft=0.0\n");
        optContent.append("TrimBottom=0.0\n");
        optContent.append("LoaderRack=\n\n");
    }
    private static void addCuttings(StringBuilder optContent, LayoutsData layoutsData) {
        optContent.append("[Cuttings]\n");
        for (Layout layout : layoutsData.getLayouts()) {
            optContent.append("GlassID=32\n");
            optContent.append("GlassDescription=32\n");
            optContent.append("GlassType=0\n");
            optContent.append("GlassThickness=5\n");
            optContent.append("Pieces=100\n");
            optContent.append("Width=").append(layout.getWidth()).append("\n");
            optContent.append("Height=").append(layout.getHeight()).append("\n");
            optContent.append("TrimLeft=15\n");
            optContent.append("TrimBottom=0\n");
            optContent.append("TrimRight=0\n");
            optContent.append("TrimTop=0\n");
            optContent.append("MinCutDistance=10\n");
            optContent.append("Priority=0\n");
            optContent.append("TravType=XY\n\n");
            for (Rect rect : layout.getRects()) {
                if (!rect.isRemain()) {
                    optContent.append("x=" + rect.getX() + ".00 y=" + rect.getY() + ".00 ");
                    optContent.append("X=" + (rect.getX() + rect.getW()) + ".00 Y=" + rect.getY() + ".00 ");
                    optContent.append("x=" + (rect.getX() + rect.getW()) + ".00 y=" + (rect.getY() + rect.getH()) + ".00 ");
                    optContent.append("X=" + rect.getX() + ".00 Y=" + (rect.getY() + rect.getH()) + ".00 ");
                    optContent.append("x=" + rect.getX() + ".00 y=" + rect.getY() + ".00\n");
                }
            }
        }
        optContent.append("\n");
    }
    private static void addShapes(StringBuilder optContent, LayoutsData layoutsData) {
        int shapeId = 1;
        for (Layout layout : layoutsData.getLayouts()) {
            for (Rect rect : layout.getRects()) {
                if (!rect.isRemain()) {
                    optContent.append("[Shape]\n");
                    optContent.append("Id=" + shapeId + "\n");
                    optContent.append("Description=" + rect.getJiaHao() + " ShapeName=" + rect.getJiaHao() + "\n");
                    optContent.append("x=" + rect.getW() + ".0 y=" + rect.getH() + ".0\n");
                    optContent.append("X=0.0 Y=0.0 C=1\n");
                    shapeId++;
                }
            }
        }
        optContent.append("\n");
    }
    private static void addInfos(StringBuilder optContent, LayoutsData layoutsData) {
        int id = 1;
        int infoId = 1;
        for (Layout layout : layoutsData.getLayouts()) {
            for (Rect rect : layout.getRects()) {
                optContent.append("[Info]\n");
                optContent.append("Id=").append(id++).append("\n");
                optContent.append("SecondGlassReference=\n");
                optContent.append("RackNo=0\n");
                optContent.append("SheetWidth=").append(rect.getWidth()).append("\n");
                optContent.append("SheetHeight=").append(rect.getHeight()).append("\n");
                optContent.append("Customer=\n");
                optContent.append("PosNo=\n");
                optContent.append("OrderNo=").append(rect.getProcessCard()).append("-1-").append(id - 1).append("\n");
                optContent.append("RackCode=0\n");
                optContent.append("PieceStandardPz=\n");
                optContent.append("UMPz=\n");
                optContent.append("IDPz=\n");
                optContent.append("RealDimXPz=").append(rect.getWidth()).append(".00\n");
                optContent.append("RealDimYPz=").append(rect.getHeight()).append(".00\n");
                optContent.append("GrindingPz=\n");
                optContent.append("GrindingPzX1=0\n");
                optContent.append("GrindingPzY1=0\n");
                optContent.append("GrindingPzX2=0\n");
                optContent.append("GrindingPzY2=0\n");
                optContent.append("BendingPz=\n");
                optContent.append("QuantityPz=77\n");
                optContent.append("LabelsPz=\n");
                optContent.append("LabelsPzCounter=\n");
                optContent.append("RotationAllowed=1\n");
                optContent.append("PreferencePz=\n");
                optContent.append("DescMatCompPz=\n");
                optContent.append("DeliveryDatePz=\n");
                optContent.append("PzNOTE=3C.orzx\n");
                optContent.append("PzNOTE1=\n");
                optContent.append("PzNOTE2=").append(rect.getWidth()).append("\n");
                optContent.append("PzNOTE3=").append(rect.getHeight()).append("\n");
                optContent.append("PzNOTE4=右下-30-30\n");
                optContent.append("PzNOTE5=false-true-false\n");
                optContent.append("PzNOTE6=true-true\n");
                optContent.append("PzNOTE7=").append(rect.getProcessCard()).append("-1-").append(id - 1).append("\n");
                for (int i = 8; i <= 20; i++) {
                    optContent.append("PzNOTE").append(i).append("=\n");
                if (!rect.isRemain()) {
                    optContent.append("[Info]\n");
                    optContent.append("Id=" + infoId + "\n");
                    optContent.append("SecondGlassReference=FL4\n");
                    optContent.append("RackNo=0\n");
                    optContent.append("SheetWidth=" + rect.getW() + ".0\n");
                    optContent.append("SheetHeight=" + rect.getH() + ".0\n");
                    optContent.append("Customer=\n");
                    optContent.append("PosNo=" + infoId + "\n");
                    optContent.append("OrderNo=\n");
                    optContent.append("RackCode=\n");
                    optContent.append("PieceStandardPz=0\n");
                    optContent.append("UMPz=mm\n");
                    optContent.append("IDPz=\n");
                    optContent.append("RealDimXPz=" + rect.getW() + ".0\n");
                    optContent.append("RealDimYPz=" + rect.getH() + ".0\n");
                    optContent.append("GrindingPz=0.0\n");
                    optContent.append("GrindingPzX1=0.0\n");
                    optContent.append("GrindingPzY1=0.0\n");
                    optContent.append("GrindingPzX2=0.0\n");
                    optContent.append("GrindingPzY2=0.0\n");
                    optContent.append("BendingPz=0.0\n");
                    optContent.append("QuantityPz=1\n");
                    optContent.append("PriorityPz=0\n");
                    optContent.append("LabelsPz=0\n");
                    optContent.append("LabelsPzCounter=0\n");
                    optContent.append("RotationAllowed=1\n");
                    optContent.append("PreferencePz=0\n");
                    optContent.append("DescMatCompPz=\n");
                    optContent.append("DeliveryDatePz=" + new SimpleDateFormat("dd-MM-yyyy").format(new Date()) + "\n");
                    optContent.append("PzNOTE=\n");
                    for (int i = 1; i <= 20; i++) {
                        optContent.append("PzNOTE" + i + "=\n");
                    }
                    infoId++;
                }
                optContent.append("\n");
            }
        }
    }
}