Merge branch 'master' of http://bore.pub:10439/r/ERP_override
12个文件已添加
22个文件已修改
1 文件已重命名
| | |
| | | /north-glass-erp/.idea/uiDesigner.xml |
| | | /north-glass-erp/.idea/vcs.xml |
| | | /north-glass-erp/northglass-erp/public/*.apk |
| | | /north-glass-erp/.idea |
| | | /north-glass-erp/src/.idea |
| | | /north-glass-erp/src/main/main.iml |
| | |
| | | } |
| | | }, |
| | | "node_modules/@babel/runtime": { |
| | | "version": "7.25.0", |
| | | "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.25.0.tgz", |
| | | "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", |
| | | "version": "7.26.10", |
| | | "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.10.tgz", |
| | | "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", |
| | | "dependencies": { |
| | | "regenerator-runtime": "^0.14.0" |
| | | }, |
| | |
| | | "integrity": "sha512-FKWIhiU96bi3xpP9ewRMgANsoVmMUBnMnmpCT6dPMZOunVYJQmJhSRruoI0XSPoHeIif3kyEuiHbFrOJwEJaEA==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/dompurify": { |
| | | "version": "2.5.6", |
| | | "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.6.tgz", |
| | | "integrity": "sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ==", |
| | | "optional": true |
| | | }, |
| | | "node_modules/element-plus": { |
| | | "version": "2.9.3", |
| | | "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.3.tgz", |
| | |
| | | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" |
| | | }, |
| | | "node_modules/fflate": { |
| | | "version": "0.4.8", |
| | | "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.4.8.tgz", |
| | | "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" |
| | | "version": "0.8.2", |
| | | "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.8.2.tgz", |
| | | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" |
| | | }, |
| | | "node_modules/file-saver": { |
| | | "version": "2.0.5", |
| | |
| | | "version": "3.11.6", |
| | | "resolved": "https://registry.npmmirror.com/jsbarcode/-/jsbarcode-3.11.6.tgz", |
| | | "integrity": "sha512-G5TKGyKY1zJo0ZQKFM1IIMfy0nF2rs92BLlCz+cU4/TazIc4ZH+X1GYeDRt7TKjrYqmPfTjwTBkU/QnQlsYiuA==" |
| | | }, |
| | | "node_modules/jspdf": { |
| | | "version": "2.5.1", |
| | | "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.1.tgz", |
| | | "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==", |
| | | "dependencies": { |
| | | "@babel/runtime": "^7.14.0", |
| | | "atob": "^2.1.2", |
| | | "btoa": "^1.2.1", |
| | | "fflate": "^0.4.8" |
| | | }, |
| | | "optionalDependencies": { |
| | | "canvg": "^3.0.6", |
| | | "core-js": "^3.6.0", |
| | | "dompurify": "^2.2.0", |
| | | "html2canvas": "^1.0.0-rc.5" |
| | | } |
| | | }, |
| | | "node_modules/local-pkg": { |
| | | "version": "0.4.3", |
| | |
| | | "socket.io-client": "^4.5.1" |
| | | } |
| | | }, |
| | | "node_modules/vue-plugin-hiprint/node_modules/dompurify": { |
| | | "version": "2.5.8", |
| | | "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.8.tgz", |
| | | "integrity": "sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==", |
| | | "optional": true |
| | | }, |
| | | "node_modules/vue-plugin-hiprint/node_modules/jspdf": { |
| | | "version": "2.5.2", |
| | | "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.2.tgz", |
| | | "integrity": "sha512-myeX9c+p7znDWPk0eTrujCzNjT+CXdXyk7YmJq5nD5V7uLLKmSXnlQ/Jn/kuo3X09Op70Apm0rQSnFWyGK8uEQ==", |
| | | "dependencies": { |
| | | "@babel/runtime": "^7.23.2", |
| | | "atob": "^2.1.2", |
| | | "btoa": "^1.2.1", |
| | | "fflate": "^0.8.1" |
| | | }, |
| | | "optionalDependencies": { |
| | | "canvg": "^3.0.6", |
| | | "core-js": "^3.6.0", |
| | | "dompurify": "^2.5.4", |
| | | "html2canvas": "^1.0.0-rc.5" |
| | | } |
| | | }, |
| | | "node_modules/vue-router": { |
| | | "version": "4.2.5", |
| | | "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz", |
| | |
| | | "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" |
| | | }, |
| | | "@babel/runtime": { |
| | | "version": "7.25.0", |
| | | "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.25.0.tgz", |
| | | "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", |
| | | "version": "7.26.10", |
| | | "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.10.tgz", |
| | | "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", |
| | | "requires": { |
| | | "regenerator-runtime": "^0.14.0" |
| | | }, |
| | |
| | | "resolved": "https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.6.tgz", |
| | | "integrity": "sha512-FKWIhiU96bi3xpP9ewRMgANsoVmMUBnMnmpCT6dPMZOunVYJQmJhSRruoI0XSPoHeIif3kyEuiHbFrOJwEJaEA==" |
| | | }, |
| | | "dompurify": { |
| | | "version": "2.5.6", |
| | | "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.6.tgz", |
| | | "integrity": "sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ==", |
| | | "optional": true |
| | | }, |
| | | "element-plus": { |
| | | "version": "2.9.3", |
| | | "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.3.tgz", |
| | |
| | | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" |
| | | }, |
| | | "fflate": { |
| | | "version": "0.4.8", |
| | | "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.4.8.tgz", |
| | | "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" |
| | | "version": "0.8.2", |
| | | "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.8.2.tgz", |
| | | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" |
| | | }, |
| | | "file-saver": { |
| | | "version": "2.0.5", |
| | |
| | | "version": "3.11.6", |
| | | "resolved": "https://registry.npmmirror.com/jsbarcode/-/jsbarcode-3.11.6.tgz", |
| | | "integrity": "sha512-G5TKGyKY1zJo0ZQKFM1IIMfy0nF2rs92BLlCz+cU4/TazIc4ZH+X1GYeDRt7TKjrYqmPfTjwTBkU/QnQlsYiuA==" |
| | | }, |
| | | "jspdf": { |
| | | "version": "2.5.1", |
| | | "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.1.tgz", |
| | | "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.14.0", |
| | | "atob": "^2.1.2", |
| | | "btoa": "^1.2.1", |
| | | "canvg": "^3.0.6", |
| | | "core-js": "^3.6.0", |
| | | "dompurify": "^2.2.0", |
| | | "fflate": "^0.4.8", |
| | | "html2canvas": "^1.0.0-rc.5" |
| | | } |
| | | }, |
| | | "local-pkg": { |
| | | "version": "0.4.3", |
| | |
| | | "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" |
| | | }, |
| | | "@babel/runtime": { |
| | | "version": "7.25.0", |
| | | "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.25.0.tgz", |
| | | "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", |
| | | "version": "7.26.10", |
| | | "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.10.tgz", |
| | | "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", |
| | | "requires": { |
| | | "regenerator-runtime": "^0.14.0" |
| | | }, |
| | |
| | | "resolved": "https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.6.tgz", |
| | | "integrity": "sha512-FKWIhiU96bi3xpP9ewRMgANsoVmMUBnMnmpCT6dPMZOunVYJQmJhSRruoI0XSPoHeIif3kyEuiHbFrOJwEJaEA==" |
| | | }, |
| | | "dompurify": { |
| | | "version": "2.5.6", |
| | | "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.6.tgz", |
| | | "integrity": "sha512-zUTaUBO8pY4+iJMPE1B9XlO2tXVYIcEA4SNGtvDELzTSCQO7RzH+j7S180BmhmJId78lqGU2z19vgVx2Sxs/PQ==", |
| | | "optional": true |
| | | }, |
| | | "element-plus": { |
| | | "version": "2.9.3", |
| | | "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.3.tgz", |
| | |
| | | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" |
| | | }, |
| | | "fflate": { |
| | | "version": "0.4.8", |
| | | "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.4.8.tgz", |
| | | "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" |
| | | "version": "0.8.2", |
| | | "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.8.2.tgz", |
| | | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" |
| | | }, |
| | | "file-saver": { |
| | | "version": "2.0.5", |
| | |
| | | "version": "3.11.6", |
| | | "resolved": "https://registry.npmmirror.com/jsbarcode/-/jsbarcode-3.11.6.tgz", |
| | | "integrity": "sha512-G5TKGyKY1zJo0ZQKFM1IIMfy0nF2rs92BLlCz+cU4/TazIc4ZH+X1GYeDRt7TKjrYqmPfTjwTBkU/QnQlsYiuA==" |
| | | }, |
| | | "jspdf": { |
| | | "version": "2.5.1", |
| | | "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.1.tgz", |
| | | "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.14.0", |
| | | "atob": "^2.1.2", |
| | | "btoa": "^1.2.1", |
| | | "canvg": "^3.0.6", |
| | | "core-js": "^3.6.0", |
| | | "dompurify": "^2.2.0", |
| | | "fflate": "^0.4.8", |
| | | "html2canvas": "^1.0.0-rc.5" |
| | | } |
| | | }, |
| | | "local-pkg": { |
| | | "version": "0.4.3", |
| | |
| | | "jspdf": "^2.5.1", |
| | | "nzh": "^1.0.8", |
| | | "socket.io-client": "^4.5.1" |
| | | }, |
| | | "dependencies": { |
| | | "dompurify": { |
| | | "version": "2.5.8", |
| | | "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.8.tgz", |
| | | "integrity": "sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==", |
| | | "optional": true |
| | | }, |
| | | "jspdf": { |
| | | "version": "2.5.2", |
| | | "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.2.tgz", |
| | | "integrity": "sha512-myeX9c+p7znDWPk0eTrujCzNjT+CXdXyk7YmJq5nD5V7uLLKmSXnlQ/Jn/kuo3X09Op70Apm0rQSnFWyGK8uEQ==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.23.2", |
| | | "atob": "^2.1.2", |
| | | "btoa": "^1.2.1", |
| | | "canvg": "^3.0.6", |
| | | "core-js": "^3.6.0", |
| | | "dompurify": "^2.5.4", |
| | | "fflate": "^0.8.1", |
| | | "html2canvas": "^1.0.0-rc.5" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "vue-router": { |
| | |
| | | "jspdf": "^2.5.1", |
| | | "nzh": "^1.0.8", |
| | | "socket.io-client": "^4.5.1" |
| | | }, |
| | | "dependencies": { |
| | | "dompurify": { |
| | | "version": "2.5.8", |
| | | "resolved": "https://registry.npmmirror.com/dompurify/-/dompurify-2.5.8.tgz", |
| | | "integrity": "sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==", |
| | | "optional": true |
| | | }, |
| | | "jspdf": { |
| | | "version": "2.5.2", |
| | | "resolved": "https://registry.npmmirror.com/jspdf/-/jspdf-2.5.2.tgz", |
| | | "integrity": "sha512-myeX9c+p7znDWPk0eTrujCzNjT+CXdXyk7YmJq5nD5V7uLLKmSXnlQ/Jn/kuo3X09Op70Apm0rQSnFWyGK8uEQ==", |
| | | "requires": { |
| | | "@babel/runtime": "^7.23.2", |
| | | "atob": "^2.1.2", |
| | | "btoa": "^1.2.1", |
| | | "canvg": "^3.0.6", |
| | | "core-js": "^3.6.0", |
| | | "dompurify": "^2.5.4", |
| | | "fflate": "^0.8.1", |
| | | "html2canvas": "^1.0.0-rc.5" |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | "vue-router": { |
| | |
| | | // MockData.js
|
| | | const mockLayoutData = {
|
| | | result: "ok",
|
| | | data: {
|
| | | |
| | | Layouts: [
|
| | | {
|
| | | mnumber: 9,
|
| | |
| | | }
|
| | | ],
|
| | | method: "getResult"
|
| | | }
|
| | | |
| | | };
|
| | |
|
| | | export default mockLayoutData;
|
| New file |
| | |
| | | {
|
| | | "optimization": {
|
| | | "yShapeJoinOptimization": "1",
|
| | | "autoMiddleEmptyPairing": "1",
|
| | | "smallPieceRotationProhibited": "1",
|
| | | "maxFramesOnSite": "10",
|
| | | "bendEdgeDistance": "5",
|
| | | "positiveTolerance": "0",
|
| | | "negativeTolerance": "0",
|
| | | "cutterOriginPosition": "topLeft",
|
| | | "uniformShapeEdgeTrimAmount": "5",
|
| | | "edgeTrimMode": "intelligent",
|
| | | "parallelOptimizationChannels": "2",
|
| | | "optimizationIterations": "1",
|
| | | "finishedProductGrindingAmount": "0",
|
| | | "rawPieceEdgeTrimAmount": "0",
|
| | | "finishedSinglePieceBelowGrindingAmount": "500"
|
| | | },
|
| | | "display": {
|
| | | "themeColor": "#ffffff",
|
| | | "includeProductEdge": true,
|
| | | "includeIrregularEdge": true,
|
| | | "mergeByFrameNumber": true,
|
| | | "frameNumber": true,
|
| | | "orderNumber": true,
|
| | | "productName": true,
|
| | | "processingInfo": true,
|
| | | "remarks": true,
|
| | | "floorNumber": true,
|
| | | "edgeLength": true,
|
| | | "manufacturingProcess": true,
|
| | | "identifier": true
|
| | | },
|
| | | "cutting": {
|
| | | "cutting_direction": true,
|
| | | "show_cutting_path": true,
|
| | | "force_continuous_cutting": true,
|
| | | "min_radius": 5,
|
| | | "min_parallel_offset": 0.1,
|
| | | "t_shaped_recess": 2,
|
| | | "down_cut_spacing": 0.5,
|
| | | "lift_retract": 1
|
| | | },
|
| | | "server": {
|
| | | "output_format": "json",
|
| | | "save_location": "local",
|
| | | "auto_save": true,
|
| | | "save_interval": 60,
|
| | | "engineering_file_save_path": "",
|
| | | "cutting_code_save_path": "",
|
| | | "open_folder_after_save": "",
|
| | | "g_code_file_format": "",
|
| | | "trf_file_save_path": "",
|
| | | "btl_file_save_path": "",
|
| | | "optima_file_save_path": "",
|
| | | "optimization_depth_limit_enable": "",
|
| | | "original_sheet_material_calculation": ""
|
| | | },
|
| | | "tempering": {
|
| | | "tempering_temp": 600,
|
| | | "cooling_rate": 50,
|
| | | "annealing_time": 3600,
|
| | | "furnaceLength": 0,
|
| | | "furnaceWidth": 0,
|
| | | "maxLoadingRate": 100,
|
| | | "chaosLevel": 0,
|
| | | "temperingTime": 1200,
|
| | | "defaultTemperingMode": "auto",
|
| | | "maxArea": 100,
|
| | | "maxPieceCount": 100,
|
| | | "xAxisInterval": 10,
|
| | | "yAxisInterval": 10
|
| | | }
|
| | | }
|
| | |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/main/glassOptimize/MoveManage', |
| | | component: () => import('@/views/pp/glassOptimize/MoveManage.vue') |
| | | }, |
| | | { |
| | | path:'userPassWord', |
| | | name: 'userPassWord', |
| | |
| | | component: () => import('../views/pp/glassOptimize/OptimizePrint.vue'), |
| | | }, |
| | | { |
| | | path: 'optimizeMove', |
| | | name: 'optimizeMove', |
| | | component: () => import('../views/pp/glassOptimize/OptimizeMove.vue'), |
| | | path: 'OptimizationRectPrint', |
| | | name: 'OptimizationRectPrint', |
| | | component: () => import('../views/pp/glassOptimize/OptimizationRectPrint.vue'), |
| | | }, |
| | | { |
| | | path: 'OptimizeControl', |
| | | name: 'OptimizeControl', |
| | | component: () => import('../views/pp/glassOptimize/OptimizeControl.vue'), |
| | | }, |
| | | { |
| | | path: 'Optimization', |
| | | name: 'Optimization', |
| | | component: () => import('../views/pp/glassOptimize/Optimization.vue'), |
| | | }, |
| | | { |
| | | path: 'optimizeparms', |
| | | name: 'optimizeparms', |
| | | component: () => import('../views/pp/glassOptimize/OptimizeParms.vue'), |
| | | }, |
| | | { |
| | | path: '/optimizeProject/:projectNo/:thickNess/:model', |
| New file |
| | |
| | | <template>
|
| | | <div>
|
| | | <RectRenderer |
| | | :layoutData="layoutData" |
| | | :gw="1150" |
| | | :gh="850" |
| | | style="width: 1000px; height: 800px; position: relative;"
|
| | | />
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script setup>
|
| | | import { ref,onMounted } from 'vue';
|
| | | import RectRenderer from './page/OptimizationRect.vue';
|
| | | import mockLayoutData from '../../../components/pp/MockData';
|
| | | import request from "@/utils/request";
|
| | | import { useI18n } from "vue-i18n";
|
| | | import { ElMessage } from "element-plus";
|
| | |
|
| | | const { t } = useI18n();
|
| | | //const layoutData = ref(mockLayoutData);
|
| | | // const processId = "P25030309";
|
| | | const savedProjectNo = localStorage.getItem('projectNo');
|
| | | const processId = savedProjectNo;
|
| | | console.log(processId)
|
| | | const layoutData = ref(null);
|
| | |
|
| | | const selectLayout = () => {
|
| | | request.post(`/glassOptimize/selectOptimizeResult/${processId}`)
|
| | | .then((res) => {
|
| | | if (res.code == 200) {
|
| | | try {
|
| | | // 将字符串数据转换为对象
|
| | | // console.log("原始数据:", res.data.data[0].Layouts);
|
| | |
|
| | | const parsedData = JSON.parse(res.data.data[0].Layouts);
|
| | | layoutData.value = parsedData;
|
| | | // console.log("解析后的数据:", layoutData.value);
|
| | | // console.log("数据类型:", typeof parsedData);
|
| | | ElMessage.success("打开版图成功")
|
| | | } catch (error) {
|
| | | ElMessage.error("解析数据时出错:", error);
|
| | | |
| | | }
|
| | | } else {
|
| | |
|
| | | }
|
| | | })
|
| | | .catch((error) => {
|
| | | console.error("请求失败:", error);
|
| | | ElMessage.error(t('basicData.msg.requestFailed'));
|
| | | });
|
| | | }
|
| | |
|
| | | onMounted(() => {
|
| | | selectLayout();
|
| | |
|
| | | });
|
| | | </script>
|
| New file |
| | |
| | | <template> |
| | | <div> |
| | | |
| | | <el-button id="button" type="primary" @click="handlePrint">打印版图</el-button> |
| | | <RectRenderer |
| | | ref="rectRenderer" |
| | | :layoutData="layoutData" |
| | | :gw="1400" |
| | | :gh="1100" |
| | | style="width: 100%; height: 800px; position: relative;" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref,onMounted } from 'vue'; |
| | | import RectRenderer from './page/RectRenderer.vue'; |
| | | import mockLayoutData from '../../../components/pp/MockData'; |
| | | 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'); |
| | | iframe.style.position = 'fixed'; |
| | | iframe.style.top = '-100vh'; |
| | | iframe.style.left = '-100vw'; |
| | | iframe.style.width = '200%'; |
| | | iframe.style.height = '200%'; |
| | | document.body.appendChild(iframe); |
| | | |
| | | // 将RectRenderer的内容加载到iframe中 |
| | | const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; |
| | | iframeDoc.open(); |
| | | iframeDoc.write(` |
| | | <html> |
| | | <head> |
| | | <title>Print Layout</title> |
| | | <style> |
| | | @page { |
| | | size: A4 landscape; |
| | | margin: 20mm; |
| | | } |
| | | body { |
| | | margin: 0; |
| | | padding: 0; |
| | | } |
| | | .layout-wrapper { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | .layout-container { |
| | | page-break-inside: avoid; |
| | | break-inside: avoid; |
| | | page-break-after: auto; |
| | | margin-bottom: 20mm; |
| | | } |
| | | .layout-item { |
| | | page-break-inside: avoid; |
| | | break-inside: avoid; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div class="layout-wrapper"> |
| | | ${rectRenderer.value.$el.outerHTML} |
| | | </div> |
| | | </body> |
| | | </html> |
| | | `); |
| | | iframeDoc.close(); |
| | | |
| | | // 设置打印样式 |
| | | const printStyle = iframeDoc.createElement('style'); |
| | | printStyle.type = 'text/css'; |
| | | printStyle.innerHTML = ` |
| | | @page { |
| | | size: A4 landscape; |
| | | margin: 20mm; |
| | | } |
| | | body { |
| | | -webkit-print-color-adjust: exact; |
| | | } |
| | | .layout-wrapper { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | .layout-container { |
| | | page-break-inside: avoid; |
| | | break-inside: avoid; |
| | | page-break-after: auto; |
| | | margin-bottom: 20mm; |
| | | } |
| | | .layout-item { |
| | | page-break-inside: avoid; |
| | | break-inside: avoid; |
| | | } |
| | | `; |
| | | iframeDoc.head.appendChild(printStyle); |
| | | |
| | | // 调整iframe大小以适应内容 |
| | | const contentWidth = rectRenderer.value.$el.offsetWidth; |
| | | const contentHeight = rectRenderer.value.$el.offsetHeight; |
| | | iframe.width = contentWidth + 'px'; |
| | | iframe.height = contentHeight + 'px'; |
| | | |
| | | // 执行打印 |
| | | iframe.contentWindow.print(); |
| | | |
| | | // 清理 |
| | | setTimeout(() => { |
| | | document.body.removeChild(iframe); |
| | | }, 100); |
| | | }; |
| | | </script> |
| | |
| | | <el-breadcrumb :separator-icon="ArrowRight"> |
| | | <el-breadcrumb-item @click="changeRouter(1)" :class="indexFlag===1?'indexTag':''" :to="{ path: '/main/glassOptimize/optimizeProject' }">{{'工程信息'}}</el-breadcrumb-item> |
| | | <el-breadcrumb-item v-show="false" @click="changeRouter(2)" :class="indexFlag===2?'indexTag':''" :to="{ path: '/main/order/createOrder' }">{{$t('order.page.createOrder')}}</el-breadcrumb-item> |
| | | <el-breadcrumb-item @click="changeRouter(3)" :class="indexFlag===3?'indexTag':''" :to="{ path: '/main/glassOptimize/optimizePrint' }">打印 |
| | | <el-breadcrumb-item @click="changeRouter(3)" :class="indexFlag===3?'indexTag':''" :to="{ path: '/main/glassOptimize/OptimizationRectPrint' }">打印 |
| | | </el-breadcrumb-item> |
| | | <el-breadcrumb-item @click="changeRouter(4)" :class="indexFlag===4?'indexTag':''" :to="{ path: '/main/glassOptimize/optimizeMove' }">调整 |
| | | <el-breadcrumb-item @click="changeRouter(4)" :class="indexFlag===4?'indexTag':''" :to="{ path: '/main/glassOptimize/Optimization' }">调整 |
| | | </el-breadcrumb-item> |
| | | <el-breadcrumb-item @click="changeRouter(5)" :class="indexFlag===5?'indexTag':''" :to="{ path: '/main/glassOptimize/optimizeMove' }">数控 |
| | | <el-breadcrumb-item @click="changeRouter(5)" :class="indexFlag===5?'indexTag':''" :to="{ path: '/main/glassOptimize/OptimizeControl' }">数控 |
| | | </el-breadcrumb-item> |
| | | <el-breadcrumb-item @click="changeRouter(6)" :class="indexFlag===6?'indexTag':''" :to="{ path: '/main/glassOptimize/optimizeMove' }">设置 |
| | | <el-breadcrumb-item @click="changeRouter(6)" :class="indexFlag===6?'indexTag':''" :to="{ path: '/main/glassOptimize/optimizeparms' }">设置 |
| | | </el-breadcrumb-item> |
| | | <el-breadcrumb-item></el-breadcrumb-item> |
| | | </el-breadcrumb> |
| New file |
| | |
| | | <template>
|
| | | <div >
|
| | | <RectRenderer |
| | | :layoutData="layoutData" |
| | | :gw="1400" |
| | | :gh="1100" |
| | | style="width: 1500px; height: 800px; position: relative;"
|
| | | />
|
| | | |
| | | |
| | | </div>
|
| | | <button @click="submitLayouts" style="position: fixed; bottom: 20px; right: 20px; padding: 10px; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer;">
|
| | | 保存OPT
|
| | | </button>
|
| | | </template>
|
| | | |
| | | <script setup>
|
| | | import { ref,onMounted } from 'vue';
|
| | | import RectRenderer from './page/RectRenderer.vue';
|
| | | import mockLayoutData from '../../../components/pp/MockData';
|
| | | import request from "@/utils/request";
|
| | | import { useI18n } from "vue-i18n";
|
| | | import { ElMessage } from "element-plus";
|
| | |
|
| | | const { t } = useI18n();
|
| | | // 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 {
|
| | | const response = await request.post('/glassOptimize/generateOpt', {
|
| | | Layouts: layoutData.value.Layouts |
| | | }, {
|
| | | headers: {
|
| | | 'Content-Type': 'application/json'
|
| | | },
|
| | | responseType: 'blob' // 以 blob 形式接收响应
|
| | | });
|
| | |
|
| | | // 处理下载
|
| | | const downloadUrl = window.URL.createObjectURL(response);
|
| | | const a = document.createElement('a');
|
| | | a.href = downloadUrl;
|
| | | a.download = 'output.opt';
|
| | | document.body.appendChild(a);
|
| | | a.click();
|
| | | document.body.removeChild(a);
|
| | | window.URL.revokeObjectURL(downloadUrl);
|
| | | ElMessage.success('OPT文件下载成功,请选择文件路径');
|
| | | } catch (error) {
|
| | | console.error('下载失败:', error);
|
| | | // 显示错误消息给用户
|
| | | ElMessage.error('下载失败,请稍后再试');
|
| | | }
|
| | | };
|
| | |
|
| | |
|
| | |
|
| | | </script>
|
| | | |
| | |
| | | <template>
|
| | | <div style="width:100%;height:2000px;">
|
| | | <div class="layoutJSON">
|
| | | Displayed as <code>[x, y, w, h]</code>:
|
| | | <div class="columns">
|
| | | <div v-for="item in layout" :key="item.i">
|
| | | <div >
|
| | | <RectRenderer |
| | | :layoutData="layoutData" |
| | | :gw="1400" |
| | | :gh="1100" |
| | | style="width: 1500px; height: 800px; position: relative;"
|
| | | />
|
| | |
|
| | | <b>{{item.i}}</b>: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}]
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | <hr/>
|
| | | <input type="checkbox" v-model="draggable"/> Draggable
|
| | | <input type="checkbox" v-model="resizable"/> Resizable
|
| | | <input type="checkbox" v-model="responsive"/> Responsive
|
| | | <br/>
|
| | | <div style="width:100%;margin-top: 10px;height:100%;">
|
| | | <grid-layout v-model:layout="layout"
|
| | | :col-num="12"
|
| | | :row-height="30"
|
| | | :is-draggable="draggable"
|
| | | :is-resizable="resizable"
|
| | | :vertical-compact="true"
|
| | | :use-css-transforms="true"
|
| | | >
|
| | |
|
| | | <grid-item v-for="item in layout"
|
| | | :key="item.i" |
| | | :static="item.static"
|
| | | :x="item.x"
|
| | | :y="item.y"
|
| | | :w="item.w"
|
| | | :h="item.h"
|
| | | :i="item.i"
|
| | | >
|
| | | <span class="text">{{item.i}}</span>
|
| | | </grid-item>
|
| | | |
| | | </grid-layout>
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | import { GridLayout, GridItem } from 'vue3-grid-layout';
|
| | | <script setup>
|
| | | import { ref } from 'vue';
|
| | | import RectRenderer from './page/RectRenderer.vue';
|
| | | import mockLayoutData from '../../../components/pp/MockData';
|
| | |
|
| | | export default {
|
| | | components: {
|
| | | GridLayout,
|
| | | GridItem,
|
| | | },
|
| | | data() {
|
| | | return {
|
| | | layout: [
|
| | | {"x":0,"y":0,"w":2,"h":2,"i":"0666*343"},
|
| | | {"x":2,"y":0,"w":2,"h":4,"i":"1"},
|
| | | {"x":4,"y":0,"w":2,"h":5,"i":"2"},
|
| | | {"x":6,"y":0,"w":2,"h":3,"i":"3"},
|
| | | {"x":8,"y":0,"w":2,"h":3,"i":"4"},
|
| | | {"x":10,"y":0,"w":2,"h":3,"i":"5"},
|
| | | {"x":0,"y":5,"w":2,"h":5,"i":"6"},
|
| | | {"x":2,"y":5,"w":2,"h":5,"i":"7"},
|
| | | {"x":4,"y":5,"w":2,"h":5,"i":"8"},
|
| | | {"x":6,"y":4,"w":2,"h":4,"i":"9"},
|
| | | {"x":8,"y":4,"w":2,"h":4,"i":"10"},
|
| | | {"x":10,"y":4,"w":2,"h":4,"i":"11"},
|
| | | {"x":0,"y":10,"w":2,"h":5,"i":"12"},
|
| | | {"x":2,"y":10,"w":2,"h":5,"i":"13"},
|
| | | {"x":4,"y":8,"w":2,"h":4,"i":"14"},
|
| | | {"x":6,"y":8,"w":2,"h":4,"i":"15"},
|
| | | {"x":8,"y":10,"w":2,"h":5,"i":"16"},
|
| | | {"x":10,"y":4,"w":2,"h":2,"i":"17"},
|
| | | {"x":0,"y":9,"w":2,"h":3,"i":"18"},
|
| | | {"x":2,"y":6,"w":2,"h":2,"i":"19"}
|
| | | ],
|
| | | draggable: true,
|
| | | resizable: true,
|
| | | responsive: true,
|
| | | index: 0
|
| | | }
|
| | | },
|
| | | methods: {
|
| | | }
|
| | | }
|
| | | const layoutData = ref(mockLayoutData);
|
| | | |
| | | |
| | | </script>
|
| | | |
| | | <style scoped>
|
| | | .vue-grid-layout {
|
| | | background: #eee;
|
| | | }
|
| | | |
| | | .vue-grid-item:not(.vue-grid-placeholder) {
|
| | | background: #ccc;
|
| | | border: 1px solid black;
|
| | | }
|
| | | |
| | | .vue-grid-item .resizing {
|
| | | opacity: 0.9;
|
| | | }
|
| | | |
| | | .vue-grid-item .static {
|
| | | background: #cce;
|
| | | }
|
| | | |
| | | .vue-grid-item .text {
|
| | | font-size: 24px;
|
| | | text-align: center;
|
| | | position: absolute;
|
| | | top: 0;
|
| | | bottom: 0;
|
| | | left: 0;
|
| | | right: 0;
|
| | | margin: auto;
|
| | | height: 100%;
|
| | | width: 100%;
|
| | | }
|
| | | |
| | | .vue-grid-item .no-drag {
|
| | | height: 100%;
|
| | | width: 100%;
|
| | | }
|
| | | |
| | | .vue-grid-item .minMax {
|
| | | font-size: 12px;
|
| | | }
|
| | | |
| | | .vue-grid-item .add {
|
| | | cursor: pointer;
|
| | | }
|
| | | |
| | | .vue-draggable-handle {
|
| | | position: absolute;
|
| | | width: 20px;
|
| | | height: 20px;
|
| | | top: 0;
|
| | | left: 0;
|
| | | background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>") no-repeat;
|
| | | background-position: bottom right;
|
| | | padding: 0 8px 8px 0;
|
| | | background-repeat: no-repeat;
|
| | | background-origin: content-box;
|
| | | box-sizing: border-box;
|
| | | cursor: pointer;
|
| | | }
|
| | | |
| | | .layoutJSON {
|
| | | background: #ddd;
|
| | | border: 1px solid black;
|
| | | margin-top: 10px;
|
| | | padding: 10px;
|
| | | }
|
| | | |
| | | .columns {
|
| | | -moz-columns: 120px;
|
| | | -webkit-columns: 120px;
|
| | | columns: 120px;
|
| | | }
|
| | | |
| | | </style> |
| | | |
| New file |
| | |
| | | <script setup>
|
| | | import { ref, reactive, onMounted, watch } from 'vue';
|
| | | import { useI18n } from "vue-i18n";
|
| | | import { ElMessage } from "element-plus";
|
| | | import request from "@/utils/request";
|
| | | import useUserInfoStore from "@/stores/userInfo";
|
| | |
|
| | | const { t } = useI18n();
|
| | | const userStore = useUserInfoStore()
|
| | | const username = userStore.user.userName
|
| | |
|
| | | const currentComponent = ref('optimization');
|
| | |
|
| | | const settings = reactive({
|
| | | optimization: {},
|
| | | display: {},
|
| | | cutting: {},
|
| | | server: {},
|
| | | tempering: {}
|
| | | });
|
| | |
|
| | | const selectComponent = (component) => {
|
| | | currentComponent.value = component;
|
| | | };
|
| | |
|
| | | const saveToDatabase = () => {
|
| | | request.post(`/glassOptimize/optimizeParms`, settings).then((res) => {
|
| | | if (res.code == 200 && res.data === true) {
|
| | | ElMessage.success(t('basicData.msg.saveSuccess'))
|
| | | } else {
|
| | | ElMessage.warning(res.msg)
|
| | | }
|
| | | });
|
| | | };
|
| | |
|
| | | 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);
|
| | | Object.assign(settings, parsedData);
|
| | | console.log('设置已更新:', settings);
|
| | | } else {
|
| | | console.error('请求失败,状态码:', response.code);
|
| | | }
|
| | | } catch (error) {
|
| | | console.error('请求发生错误:', error);
|
| | | }
|
| | | };
|
| | |
|
| | | onMounted(() => {
|
| | | fetchSettings(username);
|
| | | });
|
| | |
|
| | | // 参数映射表,用于将英文参数名映射为中文名称和类型
|
| | | const paramMapping = {
|
| | | yShapeJoinOptimization: { name: '异形拼接优化', type: 'checkbox' },
|
| | | autoMiddleEmptyPairing: { name: '自动中空配对', type: 'checkbox' },
|
| | | smallPieceRotationProhibited: { name: '小片禁止旋转', type: 'checkbox' },
|
| | | maxFramesOnSite: { name: '现场最大可放架子数量', type: 'text' },
|
| | | bendEdgeDistance: { name: '掰边距(mm)', type: 'text' },
|
| | | positiveTolerance: { name: '正公差(mm)', type: 'text' },
|
| | | negativeTolerance: { name: '负公差(mm)', type: 'text' },
|
| | | cutterOriginPosition: { name: '切割机原点位置', type: 'select' },
|
| | | uniformShapeEdgeTrimAmount: { name: '统一设置异形修边量', type: 'text' },
|
| | | edgeTrimMode: { name: '修边模式', type: 'select' },
|
| | | parallelOptimizationChannels: { name: '并行优化的通道数量', type: 'text' },
|
| | | optimizationIterations: { name: '重复优化次数', type: 'text' },
|
| | | finishedProductGrindingAmount: { name: '成品默认磨量', type: 'text' },
|
| | | rawPieceEdgeTrimAmount: { name: '原片默认修边量', type: 'text' },
|
| | | finishedSinglePieceBelowGrindingAmount: { name: '成品单片小于多少时磨量为', type: 'text' }
|
| | | };
|
| | |
|
| | | // 动态生成参数列表
|
| | | const parameterList = ref(Object.keys(paramMapping).map(key => ({
|
| | | key,
|
| | | ...paramMapping[key]
|
| | | })));
|
| | | </script>
|
| | |
|
| | | <template>
|
| | | <div class="settings-container">
|
| | | <div class="sidebar">
|
| | | <div
|
| | | @click="selectComponent('optimization')"
|
| | | :class="{ active: currentComponent === 'optimization' }"
|
| | | class="sidebar-item"
|
| | | >
|
| | | <div class="sidebar-header">优化参数</div>
|
| | | <div class="sidebar-content">优化参数设置</div>
|
| | | </div>
|
| | |
|
| | | <div
|
| | | @click="selectComponent('display')"
|
| | | :class="{ active: currentComponent === 'display' }"
|
| | | class="sidebar-item"
|
| | | >
|
| | | <div class="sidebar-header">版图显示</div>
|
| | | <div class="sidebar-content">版图显示设置</div>
|
| | | </div>
|
| | |
|
| | | <div
|
| | | @click="selectComponent('cutting')"
|
| | | :class="{ active: currentComponent === 'cutting' }"
|
| | | class="sidebar-item"
|
| | | >
|
| | | <div class="sidebar-header">刀路</div>
|
| | | <div class="sidebar-content">刀路设置</div>
|
| | | </div>
|
| | |
|
| | | <div
|
| | | @click="selectComponent('server')"
|
| | | :class="{ active: currentComponent === 'server' }"
|
| | | class="sidebar-item"
|
| | | >
|
| | | <div class="sidebar-header">输出</div>
|
| | | <div class="sidebar-content">结果输出设置</div>
|
| | | </div>
|
| | |
|
| | | <div
|
| | | @click="selectComponent('tempering')"
|
| | | :class="{ active: currentComponent === 'tempering' }"
|
| | | class="sidebar-item"
|
| | | >
|
| | | <div class="sidebar-header">钢化</div>
|
| | | <div class="sidebar-content">钢化设置</div>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <div class="main-content">
|
| | | <template v-if="currentComponent === 'display'">
|
| | | <div class="display-settings">
|
| | | <h2>版图显示设置</h2>
|
| | | <div class="form-group">
|
| | | <label>矩形成品显示颜色</label>
|
| | | <input type="color" v-model="settings.display.themeColor" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>成品尺寸包含磨边量</label>
|
| | | <input type="checkbox" v-model="settings.display.includeProductEdge" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>异形尺寸包含磨边量</label>
|
| | | <input type="checkbox" v-model="settings.display.includeIrregularEdge" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>按架号合并版图</label>
|
| | | <input type="checkbox" v-model="settings.display.mergeByFrameNumber" />
|
| | | </div>
|
| | | <div style="border: 1px solid #d2d0d0; margin-top: 20px;">
|
| | | <div style="background-color: #D5EAFF;">小片信息</div>
|
| | | <div class="form-group">
|
| | | <label>架号</label>
|
| | | <input type="checkbox" v-model="settings.display.frameNumber" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>订单编号</label>
|
| | | <input type="checkbox" v-model="settings.display.orderNumber" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>产品名称</label>
|
| | | <input type="checkbox" v-model="settings.display.productName" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>加工信息</label>
|
| | | <input type="checkbox" v-model="settings.display.processingInfo" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>备注</label>
|
| | | <input type="checkbox" v-model="settings.display.remarks" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>楼层编号</label>
|
| | | <input type="checkbox" v-model="settings.display.floorNumber" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>边长</label>
|
| | | <input type="checkbox" v-model="settings.display.edgeLength" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>工艺</label>
|
| | | <input type="checkbox" v-model="settings.display.manufacturingProcess" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>ID</label>
|
| | | <input type="checkbox" v-model="settings.display.identifier" />
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <template v-else-if="currentComponent === 'cutting'">
|
| | | <div class="display-settings">
|
| | | <h2>刀路设置</h2>
|
| | | <div class="form-group">
|
| | | <label>正向切割</label>
|
| | | <input type="checkbox" v-model="settings.cutting.cutting_direction" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>显示切割方向</label>
|
| | | <input type="checkbox" v-model="settings.cutting.show_cutting_path" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>强制弧线和直线连续切割</label>
|
| | | <input type="checkbox" v-model="settings.cutting.force_continuous_cutting" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>孔洞最小切割半径</label>
|
| | | <input type="number" v-model="settings.cutting.min_radius" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>两条平行线最小间隔</label>
|
| | | <input type="number" v-model="settings.cutting.min_parallel_offset" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>T型退缩</label>
|
| | | <input type="number" v-model="settings.cutting.t_shaped_recess" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>下刀间距</label>
|
| | | <input type="number" v-model="settings.cutting.down_cut_spacing" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>抬刀退缩</label>
|
| | | <input type="number" v-model="settings.cutting.lift_retract" />
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <template v-else-if="currentComponent === 'server'">
|
| | | <div class="display-settings">
|
| | | <h2>结果输出设置</h2>
|
| | | <div class="form-group">
|
| | | <label>工程文件保存路径</label>
|
| | | <input type="text" v-model="settings.server.output_format" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>切割代码保存路径</label>
|
| | | <input type="text" v-model="settings.server.cutting_code_save_path" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>保存文件后打开所在文件夹</label>
|
| | | <input type="text" v-model="settings.server.open_folder_after_save" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>G代码文件格式</label>
|
| | | <input type="text" v-model="settings.server.g_code_file_format" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>TRF文件保存路径</label>
|
| | | <input type="text" v-model="settings.server.trf_file_save_path" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>保特罗文件保存路径</label>
|
| | | <input type="text" v-model="settings.server.btl_file_save_path" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>OPTIMA文件保存路径</label>
|
| | | <input type="text" v-model="settings.server.optima_file_save_path" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>优化深度限制启用</label>
|
| | | <input type="text" v-model="settings.server.optimization_depth_limit_enable" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>原片切材率计算</label>
|
| | | <input type="text" v-model="settings.server.original_sheet_material_calculation" />
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <template v-else-if="currentComponent === 'tempering'">
|
| | | <div class="display-settings">
|
| | | <h2>钢化设置</h2>
|
| | | <div class="form-group">
|
| | | <label>炉长(mm)</label>
|
| | | <input type="number" v-model="settings.tempering.furnaceLength" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>炉宽(mm)</label>
|
| | | <input type="number" v-model="settings.tempering.furnaceWidth" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>最大装载率(%)</label>
|
| | | <input type="number" v-model="settings.tempering.maxLoadingRate" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>混乱程度(%)</label>
|
| | | <input type="number" v-model="settings.tempering.chaosLevel" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>钢化加热时间(秒)</label>
|
| | | <input type="number" v-model="settings.tempering.temperingTime" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>默认钢化推荐模式</label>
|
| | | <select v-model="settings.tempering.defaultTemperingMode">
|
| | | <option value="auto">自动推荐</option>
|
| | | <option value="manual">手动选择</option>
|
| | | </select>
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>最大面积设置(㎡)</label>
|
| | | <input type="number" v-model="settings.tempering.maxArea" step="0.1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>最大片数设置(片)</label>
|
| | | <input type="number" v-model="settings.tempering.maxPieceCount" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>X轴默认间隔(mm)</label>
|
| | | <input type="number" v-model="settings.tempering.xAxisInterval" step="1" />
|
| | | </div>
|
| | | <div class="form-group">
|
| | | <label>Y轴默认间隔(mm)</label>
|
| | | <input type="number" v-model="settings.tempering.yAxisInterval" step="1" />
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <template v-else>
|
| | | <div class="display-settings">
|
| | | <h2>优化参数设置</h2>
|
| | | <div class="parameter-list">
|
| | | <div |
| | | class="form-group" |
| | | v-for="(param, index) in parameterList" |
| | | :key="index"
|
| | | >
|
| | | <label class="parameter-name">{{ param.name }}</label>
|
| | | <div class="parameter-control">
|
| | | <input |
| | | v-if="param.type === 'checkbox'" |
| | | type="checkbox" |
| | | :checked="settings.optimization[param.key] === '1'"
|
| | | @click="() => { settings.optimization[param.key] = settings.optimization[param.key] === '1' ? '0' : '1' }"
|
| | | >
|
| | | <select |
| | | v-else-if="param.type === 'select'" |
| | | :name="param.key" |
| | | class="cs"
|
| | | >
|
| | | <option |
| | | v-for="option in getOptions(param.key)" |
| | | :key="option.value" |
| | | :selected="option.value === settings.optimization[param.key]"
|
| | | >
|
| | | {{ option.label }}
|
| | | </option>
|
| | | </select>
|
| | | <input |
| | | v-else |
| | | :type="param.type || 'text'" |
| | | :name="param.key" |
| | | class="cs" |
| | | v-model="settings.optimization[param.key]"
|
| | | >
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | | </div>
|
| | |
|
| | | <button class="button" @click="saveToDatabase">保存</button>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <style>
|
| | | .settings-container {
|
| | | display: flex;
|
| | | gap: 20px;
|
| | | padding: 20px;
|
| | | background-color: #f0f2f5;
|
| | | }
|
| | |
|
| | | .sidebar {
|
| | | width: 300px;
|
| | | background-color: white;
|
| | | padding: 15px;
|
| | | border-radius: 8px;
|
| | | box-shadow: 0 2px 4 rgba(0, 0, 0, 0.1);
|
| | | }
|
| | |
|
| | | .sidebar-item {
|
| | | cursor: pointer;
|
| | | padding: 10px;
|
| | | margin-bottom: 5px;
|
| | | border-radius: 6px;
|
| | | transition: all 0.3s ease;
|
| | | }
|
| | |
|
| | | .sidebar-item.active {
|
| | | background-color: #f8f9fa;
|
| | | transform: translateX(5px);
|
| | | }
|
| | |
|
| | | .sidebar-header {
|
| | | font-size: 12px;
|
| | | color: #666;
|
| | | margin-bottom: 5px;
|
| | | }
|
| | |
|
| | | .sidebar-content {
|
| | | font-size: 14px;
|
| | | color:#333;
|
| | | }
|
| | |
|
| | | .main-content {
|
| | | flex-grow: 1;
|
| | | padding: 20px;
|
| | | }
|
| | |
|
| | | button {
|
| | | padding: 10px 20px;
|
| | | background-color: #5cadfe;
|
| | | color: white;
|
| | | border: none;
|
| | | border-radius: 4px;
|
| | | cursor: pointer;
|
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
| | | }
|
| | |
|
| | | @media (max-width: 768px) {
|
| | | .settings-container {
|
| | | flex-direction: column;
|
| | | }
|
| | |
|
| | | .sidebar {
|
| | | order: -1;
|
| | | }
|
| | |
|
| | | .main-content {
|
| | | margin-top: 20px;
|
| | | }
|
| | | }
|
| | |
|
| | | .form-group {
|
| | | margin-bottom: 15px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | gap: 10px;
|
| | | }
|
| | |
|
| | | .form-group label {
|
| | | font-weight: normal;
|
| | | min-width: 120px;
|
| | | }
|
| | |
|
| | | .form-group input,
|
| | | .form-group select {
|
| | | flex: 1;
|
| | | padding: 5px;
|
| | | border: 1px solid #ddd;
|
| | | border-radius: 4px;
|
| | | }
|
| | |
|
| | | .form-group select {
|
| | | cursor: pointer;
|
| | | }
|
| | |
|
| | | .display-settings {
|
| | | background-color: white;
|
| | | padding: 20px;
|
| | | border-radius: 8px;
|
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
| | | }
|
| | |
|
| | | .parameter-list {
|
| | | display: flex;
|
| | | flex-direction: column;
|
| | | gap: 0px;
|
| | | }
|
| | |
|
| | | .parameter-item {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | gap: 0px;
|
| | | }
|
| | |
|
| | | .parameter-name {
|
| | | font-weight: normal;
|
| | | min-width: 120px;
|
| | | }
|
| | |
|
| | | .parameter-control {
|
| | | flex: 1;
|
| | | }
|
| | |
|
| | | .button {
|
| | | text-align: center;
|
| | | width: 70px;
|
| | | height: 28px;
|
| | | border: none;
|
| | | background-color: #5CADFE;
|
| | | box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0), 0 6px 5px 0 rgba(0, 0, 0, 0.19);
|
| | | margin-left: 500px;
|
| | | }
|
| | | </style>
|
| | |
|
| | | <script>
|
| | | // 辅助函数,根据参数键获取选项
|
| | | function getOptions(key) {
|
| | | const optionsMapping = {
|
| | | cutterOriginPosition: [
|
| | | { value: 'topLeft', label: '左上角' },
|
| | | { value: 'bottomLeft', label: '左下角' },
|
| | | { value: 'topRight', label: '右上角' },
|
| | | { value: 'bottomRight', label: '右下角' }
|
| | | ],
|
| | | edgeTrimMode: [
|
| | | { value: 'intelligent', label: '智能修边' },
|
| | | { value: 'complete', label: '完全修边' }
|
| | | ]
|
| | | };
|
| | | return optionsMapping[key] || [];
|
| | | }
|
| | | </script>
|
| New file |
| | |
| | | <template>
|
| | | <div style="display: flex; height: 100vh;">
|
| | | <!-- Sidebar -->
|
| | | <div class="sidebar" style="width: 200px; background: #f4f4f4; padding: 10px;">
|
| | | <div
|
| | | v-for="(layout, layoutIndex) in layouts"
|
| | | :key="layoutIndex"
|
| | | class="sidebar-item"
|
| | | @click="selectLayout(layoutIndex)"
|
| | | :class="{ 'selected': selectedLayoutIndex === layoutIndex }"
|
| | | >
|
| | | {{ layout.width }} × {{ layout.height }} × {{ layout.SameCount }}
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <!-- Main Layout Panel -->
|
| | | <div ref="layoutPanel" :class="panelClass" :style="panelStyle">
|
| | | <div
|
| | | v-for="(layout, layoutIndex) in layouts"
|
| | | :key="layoutIndex"
|
| | | class="layout-wrapper"
|
| | | :style="{ display: selectedLayoutIndex === layoutIndex ? 'block' : 'none', top: '-150px' }"
|
| | | >
|
| | | <!-- Layout Info Label -->
|
| | | <div class="layout-info" :style="layoutInfoStyle(layoutIndex)">
|
| | | {{ getCurrentRectInfo(layoutIndex) }}
|
| | | </div>
|
| | |
|
| | | <!-- Layout Container -->
|
| | | <div class="layout-container" :style="layoutContainerStyle(layoutIndex)">
|
| | | <!-- 灰色矩形 -->
|
| | | <div
|
| | | v-for="(rect, rectIndex) in layout.rects.filter(r => r.isRemain)"
|
| | | :key="`gray-${rectIndex}`"
|
| | | :ref="(el) => { if (el) rectsElements[layoutIndex + '-' + rectIndex] = el }"
|
| | | class="layout-rect"
|
| | | :style="rectStyle(rect, layoutIndex)"
|
| | | @contextmenu.prevent="handleGrayRectRightClick(layoutIndex, rectIndex)"
|
| | | />
|
| | |
|
| | | <!-- 蓝色矩形 -->
|
| | | <div
|
| | | v-for="(rect, rectIndex) in layout.rects.filter(r => !r.isRemain)"
|
| | | :key="`blue-${rectIndex}`"
|
| | | :ref="(el) => { if (el) rectsElements[layoutIndex + '-' + rectIndex] = el }"
|
| | | class="layout-rect"
|
| | | :style="rectStyle(rect, layoutIndex)"
|
| | | @contextmenu.prevent="handleRectRightClick(layoutIndex, rectIndex)"
|
| | | @mousedown="handleRectDragStart(layoutIndex, rectIndex)"
|
| | | @mousemove="handleRectDragging"
|
| | | @mouseup="handleRectDragEnd"
|
| | | @mouseleave="handleRectDragEnd"
|
| | | >
|
| | | <div class="rect-content">
|
| | | <div class="size">{{ rect.w }}×{{ rect.h }}</div>
|
| | | <div v-if="showJiaHao" class="jia-hao">{{ rect.JiaHao }}</div>
|
| | | <div v-if="showProcessId" class="liuchengka">{{ rect.liuchengka }}</div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | | <!-- 提交按钮 -->
|
| | | <button @click="submitLayouts" style="position: fixed; bottom: 20px; right: 20px; padding: 10px; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer;">
|
| | | 保存调整
|
| | | </button>
|
| | | </div>
|
| | | </template>
|
| | |
|
| | | <script setup>
|
| | | import { ref, reactive, onMounted, onUnmounted } from 'vue';
|
| | | 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 },
|
| | | gh: { type: Number, default: 1000 },
|
| | | style: { type: String, default: 'width:1000px;height:600px;display:block;background:gray' }
|
| | | });
|
| | |
|
| | | const emit = defineEmits(['rectClicked']);
|
| | | const layoutPanel = ref(null);
|
| | | const rectsElements = ref({});
|
| | | const focusIndex = ref(null);
|
| | | const layouts = ref([]);
|
| | | const panelClass = ref('');
|
| | | const panelStyle = ref(props.style);
|
| | | const rectClass = ref('layout-rect');
|
| | | const selectedLayoutIndex = ref(0);
|
| | | const currentRect = ref(null);
|
| | | 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 => {
|
| | | layout.rects.forEach(rect => {
|
| | | rect.x = Math.round(rect.x);
|
| | | rect.y = Math.round(rect.y);
|
| | | rect.w = Math.round(rect.w);
|
| | | rect.h = Math.round(rect.h);
|
| | | });
|
| | | });
|
| | | const savedProjectNo = localStorage.getItem('projectNo');
|
| | | const processId = savedProjectNo;
|
| | | const Layouts = layouts.value;
|
| | | request.post(`/glassOptimize/updateOptimizeResult/${processId}`, JSON.stringify({ Layouts }), {
|
| | | headers: {
|
| | | 'Content-Type': 'application/json'
|
| | | }
|
| | | }).then((res) => {
|
| | | if (res.code == 200 && res.data === true) {
|
| | | ElMessage.success(t('basicData.msg.saveSuccess'));
|
| | | } else {
|
| | | ElMessage.warning(res.msg);
|
| | | }
|
| | | });
|
| | | };
|
| | |
|
| | |
|
| | | //获取优化设置
|
| | | 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('请输入成品的宽度和高度', '添加成品', {
|
| | | inputType: 'text',
|
| | | inputValidator: (value) => {
|
| | | const values = value.split(',').map(v => v.trim());
|
| | | if (values.length !== 2) {
|
| | | return '请输入两个数字,用逗号分隔';
|
| | | }
|
| | | const [width, height] = values;
|
| | | if (isNaN(width) || isNaN(height)) {
|
| | | return '请输入有效的数字';
|
| | | }
|
| | | if (width <= 0 || height <= 0) {
|
| | | return '宽度和高度必须大于0';
|
| | | }
|
| | | return true;
|
| | | },
|
| | | inputErrorMessage: '输入格式不正确'
|
| | | })
|
| | | .then(({ value }) => {
|
| | | const values = value.split(',').map(v => parseFloat(v.trim()));
|
| | | const newRect = {
|
| | | x: 0,
|
| | | y: 0,
|
| | | w: values[0],
|
| | | h: values[1],
|
| | | isRemain: false
|
| | | |
| | | };
|
| | | addNewRect(layoutIndex, newRect);
|
| | | })
|
| | | .catch(() => {
|
| | | // 用户取消
|
| | | });
|
| | | };
|
| | |
|
| | | const addNewRect = (layoutIndex, newRect) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | layout.rects.push(newRect);
|
| | | adjustGrayRectangles(layoutIndex);
|
| | | };
|
| | |
|
| | | const layoutContainerStyle = (layoutIndex) => {
|
| | | const containerWidth = (props.gw - 210) / 2;
|
| | | const containerHeight = (props.gh - 100) / 3;
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const scale = Math.min(
|
| | | (props.gw - 100) / layout.width,
|
| | | (props.gh - 100) / layout.height
|
| | | );
|
| | | return {
|
| | | position: 'absolute',
|
| | | left: `${(props.gw - layout.width * scale) / 2}px`,
|
| | | top: `${(props.gh - layout.height * scale) / 2}px`,
|
| | | width: `${layout.width * scale}px`,
|
| | | height: `${layout.height * scale}px`,
|
| | | overflow: 'visible',
|
| | | border: '1px solid #ccc',
|
| | | background: '#fff'
|
| | | };
|
| | | };
|
| | |
|
| | | const layoutInfoStyle = (layoutIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const scale = Math.min(
|
| | | (props.gw - 100) / layout.width,
|
| | | (props.gh - 100) / layout.height
|
| | | );
|
| | | return {
|
| | | position: 'absolute',
|
| | | left: `${(props.gw - layout.width * scale) / 2}px`,
|
| | | top: `${(props.gh - layout.height * scale) / 2 - 45}px`,
|
| | | background: 'none',
|
| | | textAlign: 'center',
|
| | | zIndex: 1000
|
| | | };
|
| | | };
|
| | |
|
| | | const rectStyle = (rect, layoutIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const scale = Math.min(
|
| | | (props.gw - 100) / layout.width,
|
| | | (props.gh - 100) / layout.height
|
| | | );
|
| | | return {
|
| | | position: 'absolute',
|
| | | left: `${rect.x * scale}px`,
|
| | | top: `${rect.y * scale}px`,
|
| | | width: `${rect.w * scale}px`,
|
| | | height: `${rect.h * scale}px`,
|
| | | backgroundColor: rect.isRemain ? '#f0f0f0' : themeColor.value,
|
| | | border: '1px solid #000',
|
| | | cursor: 'pointer',
|
| | | draggable: !rect.isRemain,
|
| | | zIndex: rect.isRemain ? 1 : 2
|
| | | };
|
| | | };
|
| | |
|
| | | const handleRectClick = (layoutIndex, rectIndex) => {
|
| | | focusIndex.value = { layoutIndex, rectIndex };
|
| | | emit('rectClicked', layoutIndex, rectIndex);
|
| | | };
|
| | |
|
| | | const handleRectRightClick = (layoutIndex, rectIndex) => {
|
| | | const rect = layouts.value[layoutIndex].rects[rectIndex];
|
| | | if (rect.isRemain) return;
|
| | |
|
| | | const contextMenu = document.createElement('div');
|
| | | contextMenu.className = 'context-menu';
|
| | | contextMenu.style.position = 'absolute';
|
| | | contextMenu.style.left = `${event.clientX}px`;
|
| | | contextMenu.style.top = `${event.clientY}px`;
|
| | | contextMenu.style.backgroundColor = '#fff';
|
| | | contextMenu.style.border = '1px solid #ccc';
|
| | | contextMenu.style.padding = '5px';
|
| | | contextMenu.style.zIndex = 1001;
|
| | |
|
| | | const rotateItem = document.createElement('div');
|
| | | rotateItem.textContent = '旋转';
|
| | | rotateItem.style.cursor = 'pointer';
|
| | | rotateItem.addEventListener('click', () => {
|
| | | rotateRect(layoutIndex, rectIndex);
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveUpAndRotateItem = document.createElement('div');
|
| | | moveUpAndRotateItem.textContent = '向上移动并旋转';
|
| | | moveUpAndRotateItem.style.cursor = 'pointer';
|
| | | moveUpAndRotateItem.addEventListener('click', () => {
|
| | | moveRectAndRotate(layoutIndex, rectIndex, 'up');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveDownAndRotateItem = document.createElement('div');
|
| | | moveDownAndRotateItem.textContent = '向下移动并旋转';
|
| | | moveDownAndRotateItem.style.cursor = 'pointer';
|
| | | moveDownAndRotateItem.addEventListener('click', () => {
|
| | | moveRectAndRotate(layoutIndex, rectIndex, 'down');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveLeftAndRotateItem = document.createElement('div');
|
| | | moveLeftAndRotateItem.textContent = '向左移动并旋转';
|
| | | moveLeftAndRotateItem.style.cursor = 'pointer';
|
| | | moveLeftAndRotateItem.addEventListener('click', () => {
|
| | | moveRectAndRotate(layoutIndex, rectIndex, 'left');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveRightAndRotateItem = document.createElement('div');
|
| | | moveRightAndRotateItem.textContent = '向右移动并旋转';
|
| | | moveRightAndRotateItem.style.cursor = 'pointer';
|
| | | moveRightAndRotateItem.addEventListener('click', () => {
|
| | | moveRectAndRotate(layoutIndex, rectIndex, 'right');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveUpItem = document.createElement('div');
|
| | | moveUpItem.textContent = '向上移动';
|
| | | moveUpItem.style.cursor = 'pointer';
|
| | | moveUpItem.addEventListener('click', () => {
|
| | | moveRect(layoutIndex, rectIndex, 'up');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveDownItem = document.createElement('div');
|
| | | moveDownItem.textContent = '向下移动';
|
| | | moveDownItem.style.cursor = 'pointer';
|
| | | moveDownItem.addEventListener('click', () => {
|
| | | moveRect(layoutIndex, rectIndex, 'down');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveLeftItem = document.createElement('div');
|
| | | moveLeftItem.textContent = '向左移动';
|
| | | moveLeftItem.style.cursor = 'pointer';
|
| | | moveLeftItem.addEventListener('click', () => {
|
| | | moveRect(layoutIndex, rectIndex, 'left');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const moveRightItem = document.createElement('div');
|
| | | moveRightItem.textContent = '向右移动';
|
| | | moveRightItem.style.cursor = 'pointer';
|
| | | moveRightItem.addEventListener('click', () => {
|
| | | moveRect(layoutIndex, rectIndex, 'right');
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const deleteItem = document.createElement('div');
|
| | | deleteItem.textContent = '删除';
|
| | | deleteItem.style.cursor = 'pointer';
|
| | | deleteItem.addEventListener('click', () => {
|
| | | deleteRect(layoutIndex, rectIndex);
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | const addItem = document.createElement('div');
|
| | | addItem.textContent = '添加成品';
|
| | | addItem.style.cursor = 'pointer';
|
| | | addItem.addEventListener('click', () => {
|
| | | showAddDialog(layoutIndex, rectIndex);
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | contextMenu.appendChild(rotateItem);
|
| | | contextMenu.appendChild(moveUpAndRotateItem);
|
| | | contextMenu.appendChild(moveDownAndRotateItem);
|
| | | contextMenu.appendChild(moveLeftAndRotateItem);
|
| | | contextMenu.appendChild(moveRightAndRotateItem);
|
| | | contextMenu.appendChild(moveUpItem);
|
| | | contextMenu.appendChild(moveDownItem);
|
| | | contextMenu.appendChild(moveLeftItem);
|
| | | contextMenu.appendChild(moveRightItem);
|
| | | contextMenu.appendChild(deleteItem);
|
| | | contextMenu.appendChild(addItem);
|
| | |
|
| | | document.body.appendChild(contextMenu);
|
| | | };
|
| | |
|
| | | const handleGrayRectRightClick = (layoutIndex, rectIndex) => {
|
| | | const rect = layouts.value[layoutIndex].rects[rectIndex];
|
| | | if (!rect.isRemain) return;
|
| | |
|
| | | const contextMenu = document.createElement('div');
|
| | | contextMenu.className = 'context-menu';
|
| | | contextMenu.style.position = 'absolute';
|
| | | contextMenu.style.left = `${event.clientX}px`;
|
| | | contextMenu.style.top = `${event.clientY}px`;
|
| | | contextMenu.style.backgroundColor = '#fff';
|
| | | contextMenu.style.border = '1px solid #ccc';
|
| | | contextMenu.style.padding = '5px';
|
| | | contextMenu.style.zIndex = 1001;
|
| | |
|
| | | const addItem = document.createElement('div');
|
| | | addItem.textContent = '添加成品';
|
| | | addItem.style.cursor = 'pointer';
|
| | | addItem.addEventListener('click', () => {
|
| | | showAddDialog(layoutIndex, rectIndex);
|
| | | document.body.removeChild(contextMenu);
|
| | | });
|
| | |
|
| | | contextMenu.appendChild(addItem);
|
| | |
|
| | | document.body.appendChild(contextMenu);
|
| | | };
|
| | |
|
| | | const handleRectDragStart = (layoutIndex, rectIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[rectIndex];
|
| | | if (rect.isRemain) return;
|
| | |
|
| | | dragging.value = true;
|
| | | dragRect.value = { layoutIndex, rectIndex };
|
| | | dragStartPos.value = {
|
| | | x: event.clientX,
|
| | | y: event.clientY
|
| | | };
|
| | | };
|
| | |
|
| | | const handleRectDragging = (event) => {
|
| | | if (!dragging.value || !dragRect.value) return;
|
| | |
|
| | | const layoutIndex = dragRect.value.layoutIndex;
|
| | | const rectIndex = dragRect.value.rectIndex;
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[rectIndex];
|
| | | const scale = Math.min(
|
| | | (props.gw - 100) / layout.width,
|
| | | (props.gh - 100) / layout.height
|
| | | );
|
| | |
|
| | | const deltaX = event.clientX - dragStartPos.value.x;
|
| | | const deltaY = event.clientY - dragStartPos.value.y;
|
| | |
|
| | | // 只调整位置,不调整大小
|
| | | const newRect = { ...rect };
|
| | | newRect.x += deltaX / scale;
|
| | | newRect.y += deltaY / scale;
|
| | |
|
| | | // 检查是否与其他蓝色矩形重叠
|
| | | const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
|
| | | let isValidMove = true;
|
| | | |
| | | otherRects.forEach(otherRect => {
|
| | | if (checkOverlap(newRect, otherRect)) {
|
| | | isValidMove = false;
|
| | | }
|
| | | });
|
| | |
|
| | | // 检查是否超出布局边界
|
| | | if (newRect.x < 0 || newRect.y < 0 ||
|
| | | newRect.x + newRect.w > layout.width ||
|
| | | newRect.y + newRect.h > layout.height) {
|
| | | isValidMove = false;
|
| | | }
|
| | |
|
| | | if (isValidMove) {
|
| | | rect.x = newRect.x;
|
| | | rect.y = newRect.y;
|
| | | dragStartPos.value = {
|
| | | x: event.clientX,
|
| | | y: event.clientY
|
| | | };
|
| | | adjustGrayRectangles(layoutIndex);
|
| | | }
|
| | | };
|
| | |
|
| | | const handleRectDragEnd = () => {
|
| | | if (dragRect.value) {
|
| | | const layoutIndex = dragRect.value.layoutIndex;
|
| | | const rectIndex = dragRect.value.rectIndex;
|
| | | const rect = layouts.value[layoutIndex].rects[rectIndex];
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const scale = Math.min(
|
| | | (props.gw - 100) / layout.width,
|
| | | (props.gh - 100) / layout.height
|
| | | );
|
| | |
|
| | | // 拖动结束后自动对齐到最近的整数位置
|
| | | rect.x = Math.round(rect.x);
|
| | | rect.y = Math.round(rect.y);
|
| | |
|
| | | // 只调整位置对齐,不调整大小
|
| | | adjustAlignmentPosition(layoutIndex, rectIndex);
|
| | |
|
| | | // 调整灰色矩形
|
| | | adjustGrayRectangles(layoutIndex);
|
| | | }
|
| | |
|
| | | dragging.value = false;
|
| | | dragRect.value = null;
|
| | | };
|
| | |
|
| | | const adjustAlignmentPosition = (layoutIndex, rectIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[rectIndex];
|
| | | const otherRects = layout.rects.filter((r, i) => i !== rectIndex);
|
| | |
|
| | | const threshold = Math.max(rect.w, rect.h) * 0.1;
|
| | |
|
| | | otherRects.forEach(otherRect => {
|
| | | if (Math.abs(rect.x - otherRect.x) < threshold) {
|
| | | rect.x = Math.round((rect.x + otherRect.x) / 2);
|
| | | }
|
| | | if (Math.abs((rect.x + rect.w) - (otherRect.x + otherRect.w)) < threshold) {
|
| | | // 不调整宽度
|
| | | }
|
| | | if (Math.abs(rect.y - otherRect.y) < threshold) {
|
| | | rect.y = Math.round((rect.y + otherRect.y) / 2);
|
| | | }
|
| | | if (Math.abs((rect.y + rect.h) - (otherRect.y + otherRect.h)) < threshold) {
|
| | | // 不调整高度
|
| | | }
|
| | | });
|
| | | };
|
| | |
|
| | | const mergeAdjacentGrayRects = (rects) => {
|
| | | const grayRects = rects.filter(r => r.isRemain);
|
| | | let merged = [];
|
| | | |
| | | grayRects.sort((a, b) => {
|
| | | if (a.x !== b.x) return a.x - b.x;
|
| | | return a.y - b.y;
|
| | | });
|
| | |
|
| | | if (grayRects.length === 0) return;
|
| | |
|
| | | merged.push({ ...grayRects[0] });
|
| | |
|
| | | for (let i = 1; i < grayRects.length; i++) {
|
| | | const last = merged[merged.length - 1];
|
| | | const current = grayRects[i];
|
| | |
|
| | | if (current.x === last.x + last.w && |
| | | current.y === last.y && |
| | | current.h === last.h) {
|
| | | last.w += current.w;
|
| | | last.x = Math.round(last.x);
|
| | | last.y = Math.round(last.y);
|
| | | last.w = Math.round(last.w);
|
| | | last.h = Math.round(last.h);
|
| | | } else if (current.y === last.y + last.h && |
| | | current.x === last.x && |
| | | current.w === last.w) {
|
| | | last.h += current.h;
|
| | | last.x = Math.round(last.x);
|
| | | last.y = Math.round(last.y);
|
| | | last.w = Math.round(last.w);
|
| | | last.h = Math.round(last.h);
|
| | | } else {
|
| | | merged.push({ |
| | | x: Math.round(current.x),
|
| | | y: Math.round(current.y),
|
| | | w: Math.round(current.w),
|
| | | h: Math.round(current.h),
|
| | | isRemain: true
|
| | | });
|
| | | }
|
| | | }
|
| | |
|
| | | const nonGray = rects.filter(r => !r.isRemain);
|
| | | rects.splice(0, rects.length, ...nonGray, ...merged);
|
| | | };
|
| | |
|
| | | const adjustGrayRectangles = (layoutIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rects = layout.rects;
|
| | | const nonGrayRects = rects.filter(rect => !rect.isRemain);
|
| | |
|
| | | const remainingAreas = calculateRemainingAreas(layout.width, layout.height, nonGrayRects);
|
| | |
|
| | | const currentGrayRects = rects.filter(r => r.isRemain);
|
| | | currentGrayRects.forEach((_, index) => {
|
| | | if (index >= remainingAreas.length) {
|
| | | rects.splice(index, 1);
|
| | | }
|
| | | });
|
| | |
|
| | | remainingAreas.forEach((area, index) => {
|
| | | if (index < currentGrayRects.length) {
|
| | | currentGrayRects[index].x = Math.round(area.x);
|
| | | currentGrayRects[index].y = Math.round(area.y);
|
| | | currentGrayRects[index].w = Math.round(area.w);
|
| | | currentGrayRects[index].h = Math.round(area.h);
|
| | | } else {
|
| | | rects.push({
|
| | | x: Math.round(area.x),
|
| | | y: Math.round(area.y),
|
| | | w: Math.round(area.w),
|
| | | h: Math.round(area.h),
|
| | | isRemain: true
|
| | | });
|
| | | }
|
| | | });
|
| | |
|
| | | mergeAdjacentGrayRects(rects);
|
| | | };
|
| | |
|
| | | const rotateRect = (layoutIndex, rectIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[rectIndex];
|
| | | const originalState = { ...rect };
|
| | |
|
| | | // 旋转矩形
|
| | | const temp = rect.w;
|
| | | rect.w = rect.h;
|
| | | rect.h = temp;
|
| | |
|
| | | // 检查旋转后是否与其他蓝色矩形重叠
|
| | | const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
|
| | | let isValidRotation = true;
|
| | |
|
| | | otherRects.forEach(otherRect => {
|
| | | if (checkOverlap(rect, otherRect)) {
|
| | | isValidRotation = false;
|
| | | }
|
| | | });
|
| | |
|
| | | // 检查是否超出布局边界
|
| | | if (rect.x + rect.w > layout.width || rect.y + rect.h > layout.height) {
|
| | | isValidRotation = false;
|
| | | }
|
| | |
|
| | | if (isValidRotation) {
|
| | | adjustGrayRectangles(layoutIndex);
|
| | | } else {
|
| | | // 恢复原状
|
| | | rect.w = originalState.w;
|
| | | rect.h = originalState.h;
|
| | | ElMessage.warning('无法旋转,存在重叠或超出边界');
|
| | | }
|
| | | };
|
| | |
|
| | | const moveRectAndRotate = (layoutIndex, rectIndex, direction) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[rectIndex];
|
| | | const grayRects = layout.rects.filter(r => r.isRemain);
|
| | |
|
| | | // 旋转矩形
|
| | | const temp = rect.w;
|
| | | rect.w = rect.h;
|
| | | rect.h = temp;
|
| | |
|
| | | // 检查旋转后的矩形是否可以放置在某个灰色矩形的位置
|
| | | const canPlace = grayRects.some(grayRect => {
|
| | | return grayRect.w >= rect.w && grayRect.h >= rect.h;
|
| | | });
|
| | |
|
| | | if (!canPlace) {
|
| | | // 如果不能放置,恢复原状
|
| | | const temp = rect.w;
|
| | | rect.w = rect.h;
|
| | | rect.h = temp;
|
| | | ElMessage.warning('无法旋转,没有足够的空间');
|
| | | return;
|
| | | }
|
| | |
|
| | | // 调整灰色矩形
|
| | | adjustGrayRectangles(layoutIndex);
|
| | |
|
| | | // 移动矩形
|
| | | moveRect(layoutIndex, rectIndex, direction);
|
| | | };
|
| | |
|
| | | const moveRect = (layoutIndex, rectIndex, direction) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[rectIndex];
|
| | | const originalState = { ...rect };
|
| | |
|
| | | // 计算剩余空间
|
| | | const remainingAreas = calculateRemainingAreas(layout.width, layout.height, layout.rects.filter(r => !r.isRemain));
|
| | | |
| | | // 根据方向计算可移动的最大步长
|
| | | let maxStep = 0;
|
| | | switch (direction) {
|
| | | case 'up':
|
| | | maxStep = rect.y;
|
| | | break;
|
| | | case 'down':
|
| | | maxStep = layout.height - (rect.y + rect.h);
|
| | | break;
|
| | | case 'left':
|
| | | maxStep = rect.x;
|
| | | break;
|
| | | case 'right':
|
| | | maxStep = layout.width - (rect.x + rect.w);
|
| | | break;
|
| | | }
|
| | |
|
| | | // 移动步长,根据剩余空间动态调整
|
| | | const stepSize = maxStep;
|
| | | const actualStep = Math.min(maxStep, stepSize);
|
| | |
|
| | | // 移动矩形
|
| | | switch (direction) {
|
| | | case 'up':
|
| | | rect.y -= actualStep;
|
| | | break;
|
| | | case 'down':
|
| | | rect.y += actualStep;
|
| | | break;
|
| | | case 'left':
|
| | | rect.x -= actualStep;
|
| | | break;
|
| | | case 'right':
|
| | | rect.x +=actualStep;
|
| | | break;
|
| | | }
|
| | |
|
| | | // 检查是否与其他蓝色矩形重叠
|
| | | const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
|
| | | let isValidMove = true;
|
| | |
|
| | | otherRects.forEach(otherRect => {
|
| | | if (checkOverlap(rect, otherRect)) {
|
| | | isValidMove = false;
|
| | | }
|
| | | });
|
| | |
|
| | | // 检查是否超出布局边界
|
| | | if (rect.x < 0 || rect.y < 0 ||
|
| | | rect.x + rect.w > layout.width ||
|
| | | rect.y + rect.h > layout.height) {
|
| | | isValidMove = false;
|
| | | }
|
| | |
|
| | | if (isValidMove) {
|
| | | adjustGrayRectangles(layoutIndex);
|
| | | } else {
|
| | | // 恢复原状
|
| | | rect.x = originalState.x;
|
| | | rect.y = originalState.y;
|
| | | ElMessage.warning('无法移动,存在重叠或超出边界');
|
| | | }
|
| | | };
|
| | |
|
| | | const deleteRect = (layoutIndex, rectIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | layout.rects.splice(rectIndex, 1);
|
| | | adjustGrayRectangles(layoutIndex);
|
| | | };
|
| | |
|
| | | const checkOverlap = (rect1, rect2) => {
|
| | | return !(rect1.x + rect1.w <= rect2.x ||
|
| | | rect1.x >= rect2.x + rect2.w ||
|
| | | rect1.y + rect1.h <= rect2.y ||
|
| | | rect1.y >= rect2.y + rect2.h);
|
| | | };
|
| | |
|
| | | const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
|
| | | let remaining = [{ x: 0, y: 0, w: totalWidth, h: totalHeight }];
|
| | | obstacles.forEach(rect => {
|
| | | remaining = cutRemainingAreas(remaining, rect);
|
| | | });
|
| | | return remaining;
|
| | | };
|
| | |
|
| | | const cutRemainingAreas = (remainingAreas, obstacle) => {
|
| | | const newRemaining = [];
|
| | | remainingAreas.forEach(area => {
|
| | | if (checkOverlap(area, obstacle)) {
|
| | | if (obstacle.x > area.x) {
|
| | | newRemaining.push({
|
| | | x: area.x,
|
| | | y: area.y,
|
| | | w: obstacle.x - area.x,
|
| | | h: area.h
|
| | | });
|
| | | }
|
| | | if (obstacle.x + obstacle.w < area.x + area.w) {
|
| | | newRemaining.push({
|
| | | x: obstacle.x + obstacle.w,
|
| | | y: area.y,
|
| | | w: area.w - (obstacle.x + obstacle.w - area.x),
|
| | | h: area.h
|
| | | });
|
| | | }
|
| | | if (obstacle.y > area.y) {
|
| | | newRemaining.push({
|
| | | x: area.x,
|
| | | y: area.y,
|
| | | w: area.w,
|
| | | h: obstacle.y - area.y
|
| | | });
|
| | | }
|
| | | if (obstacle.y + obstacle.h < area.y + area.h) {
|
| | | newRemaining.push({
|
| | | x: area.x,
|
| | | y: obstacle.y + obstacle.h,
|
| | | w: area.w,
|
| | | h: area.h - (obstacle.y + obstacle.h - area.y)
|
| | | });
|
| | | }
|
| | | } else {
|
| | | newRemaining.push(area);
|
| | | }
|
| | | });
|
| | | return newRemaining;
|
| | | };
|
| | |
|
| | | const getCurrentRectInfo = (layoutIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[focusIndex.value?.rectIndex || 0];
|
| | | if (!rect) return '';
|
| | | const totalRects = layouts.value.length;
|
| | | const currentRectIndex = layoutIndex + 1;
|
| | | const width = layout.width;
|
| | | const height = layout.height;
|
| | | const percentage = ((rect.w / layout.width) * 100).toFixed(1) + '%';
|
| | | return `${currentRectIndex}/${totalRects} ${width}×${height} ×1 ${percentage}`;
|
| | | };
|
| | |
|
| | | const selectLayout = (layoutIndex) => {
|
| | | selectedLayoutIndex.value = layoutIndex;
|
| | | };
|
| | |
|
| | | const updateLayout = () => {
|
| | | if (!layoutPanel.value) return;
|
| | | layouts.value = props.layoutData.Layouts;
|
| | | };
|
| | |
|
| | |
|
| | | let clickEventListener = null;
|
| | | onMounted(() => {
|
| | | 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>
|
| | |
|
| | | <style scoped>
|
| | | .layout-wrapper {
|
| | | position: relative;
|
| | | margin-top: 50px;
|
| | | }
|
| | |
|
| | | .layout-rect {
|
| | | user-select: none;
|
| | | }
|
| | |
|
| | | .layout-container {
|
| | | position: relative;
|
| | | overflow: visible;
|
| | | }
|
| | |
|
| | | .layout-info {
|
| | | color: #444;
|
| | | font-size: 12px;
|
| | | background-color: #ffffff;
|
| | | padding: 5px 10px;
|
| | | border-radius: 3px;
|
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
| | | font-weight: bold;
|
| | | }
|
| | |
|
| | | .rect-content {
|
| | | display: grid;
|
| | | grid-template-columns: 1fr;
|
| | | grid-template-rows: 1fr;
|
| | | padding: 5px;
|
| | | }
|
| | |
|
| | | .size {
|
| | | grid-row: 1;
|
| | | grid-column: 1;
|
| | | color: #444;
|
| | | font-size: 12px;
|
| | | }
|
| | |
|
| | | .jia-hao .liuchengka {
|
| | | grid-row: 2;
|
| | | grid-column: 1;
|
| | | margin: auto;
|
| | | font-size: 14px;
|
| | | font-weight: bold;
|
| | | }
|
| | |
|
| | | .sidebar-item {
|
| | | padding: 10px;
|
| | | cursor: pointer;
|
| | | }
|
| | |
|
| | | .sidebar-item.selected {
|
| | | background: #ddd;
|
| | | }
|
| | |
|
| | | .context-menu {
|
| | | position: absolute;
|
| | | background-color: #fff;
|
| | | border: 1px solid #ccc;
|
| | | padding: 5px;
|
| | | z-index: 1001;
|
| | | }
|
| | |
|
| | | .context-menu div {
|
| | | padding: 5px;
|
| | | cursor: pointer;
|
| | | }
|
| | |
|
| | | .context-menu div:hover {
|
| | | background-color: #f0f0f0;
|
| | | }
|
| | | </style>
|
| | |
| | | <script setup> |
| | | import {nextTick, onMounted, reactive, ref, watch} from "vue"; |
| | | import {nextTick, onMounted, reactive, ref, watch,onBeforeUnmount } from "vue"; |
| | | import {useI18n} from "vue-i18n"; |
| | | import {Folder, Plus, Setting, Operation,} from "@element-plus/icons-vue"; |
| | | import OptimizeCompute from "@/views/pp/glassOptimize/page/OptimizeCompute.vue"; |
| | |
| | | //工程号 |
| | | const projectNo = ref(route.params.projectNo); |
| | | const projectName = ref(''); |
| | | onBeforeUnmount(() => { |
| | | localStorage.setItem('projectNo', projectNo.value); |
| | | }); |
| | | |
| | | const fetchData = () => { |
| | | request.post(`/glassOptimize/projectInfo/${projectNo.value}`).then((res) => { |
| File was renamed from north-glass-erp/northglass-erp/src/views/pp/glassOptimize/RectRenderer.vue |
| | |
| | | <template>
|
| | | <div ref="layoutPanel" :class="panelClass" :style="panelStyle">
|
| | | <div v-for="(layout, layoutIndex) in layouts" :key="layoutIndex" |
| | | class="layout-wrapper">
|
| | | |
| | | <div v-for="(layout, layoutIndex) in layouts" :key="layoutIndex" class="layout-wrapper">
|
| | | <!-- 布局信息标签 -->
|
| | | <div class="layout-info" :style="layoutInfoStyle(layoutIndex)">
|
| | | 布局{{ layoutIndex + 1 }}
|
| | | {{ getCurrentRectInfo(layoutIndex) }}
|
| | | </div>
|
| | |
|
| | | <!-- 布局容器 -->
|
| | | <div class="layout-container"
|
| | | :style="layoutContainerStyle(layoutIndex)">
|
| | | |
| | | <div v-for="(rect, rectIndex) in layout.rects" :key="rectIndex" |
| | | <div class="layout-container" :style="layoutContainerStyle(layoutIndex)">
|
| | | <div v-for="(rect, rectIndex) in layout.rects" :key="rectIndex"
|
| | | :ref="(el) => { if (el) rectsElements[layoutIndex + '-' + rectIndex] = el }"
|
| | | :class="rectClass"
|
| | | :style="rectStyle(rect, layoutIndex)"
|
| | |
| | | import { ref, reactive, onMounted, onUnmounted } from 'vue';
|
| | |
|
| | | const props = defineProps({
|
| | | layoutData: {
|
| | | type: Object,
|
| | | required: true
|
| | | },
|
| | | gw: {
|
| | | type: Number,
|
| | | default: 1000
|
| | | },
|
| | | gh: {
|
| | | type: Number,
|
| | | default: 1000
|
| | | },
|
| | | style: {
|
| | | type: String,
|
| | | default: 'width:1000px;height:600px;display:block;background:gray'
|
| | | }
|
| | | layoutData: { type: Object, required: true },
|
| | | gw: { type: Number, default: 1000 },
|
| | | gh: { type: Number, default: 1000 },
|
| | | style: { type: String, default: 'width:1000px;height:600px;display:block;background:gray' }
|
| | | });
|
| | |
|
| | | const emit = defineEmits(['rectClicked']);
|
| | |
|
| | | const layoutPanel = ref(null);
|
| | | const rectsElements = ref({});
|
| | | const focusIndex = ref(null);
|
| | | const layouts = ref([]);
|
| | |
|
| | | const panelClass = ref('');
|
| | | const panelStyle = ref(props.style);
|
| | |
|
| | | const rectClass = ref('layout-rect');
|
| | |
|
| | | const layoutContainerStyle = (layoutIndex) => {
|
| | | const containerWidth = (props.gw - 210) / 2; // 两列,每列宽度为gw的一半,减去右边距
|
| | | const containerHeight = (props.gh - 100) / 3; // 三行,每行高度为gh的三分之一,减去下边距
|
| | | const x = (layoutIndex % 2) * (containerWidth + 50); // 横向排列,加上50px间距
|
| | | const y = Math.floor(layoutIndex / 2) * (containerHeight + 50); // 纵向排列,加上50px间距
|
| | | const containerWidth = (props.gw - 210) / 2;
|
| | | const containerHeight = (props.gh - 100) / 3;
|
| | | const x = (layoutIndex % 2) * (containerWidth + 50);
|
| | | const y = Math.floor(layoutIndex / 2) * (containerHeight + 50);
|
| | | return {
|
| | | position: 'absolute',
|
| | | left: `${x}px`,
|
| | |
| | | return {
|
| | | position: 'absolute',
|
| | | left: `${x}px`,
|
| | | top: `${y - 45}px`, // 将标签放在版图容器的上方
|
| | | top: `${y - 45}px`,
|
| | | background: 'none',
|
| | | textAlign: 'center',
|
| | | zIndex: 1000
|
| | |
| | | containerWidth / layout.width,
|
| | | containerHeight / layout.height
|
| | | );
|
| | | |
| | | return {
|
| | | position: 'absolute',
|
| | | left: `${rect.x * scale}px`,
|
| | |
| | | emit('rectClicked', layoutIndex, rectIndex);
|
| | | };
|
| | |
|
| | | const getCurrentRectInfo = (layoutIndex) => {
|
| | | const layout = layouts.value[layoutIndex];
|
| | | const rect = layout.rects[focusIndex.value?.rectIndex || 0];
|
| | | if (!rect) return '';
|
| | | const totalRects = layouts.value.length;
|
| | | const currentRectIndex = layoutIndex+1;
|
| | | const width = layout.width;
|
| | | const height = layout.height;
|
| | | const percentage = ((rect.w / layout.width) * 100).toFixed(1) + '%';
|
| | | return `${currentRectIndex}/${totalRects} ${width}×${height} ×1 ${percentage}`;
|
| | | };
|
| | |
|
| | | const updateLayout = () => {
|
| | | if (!layoutPanel.value) return;
|
| | |
|
| | | layouts.value = props.layoutData.data.Layouts;
|
| | | layouts.value = props.layoutData.Layouts;
|
| | | };
|
| | |
|
| | | onMounted(() => {
|
| | | updateLayout();
|
| | | setTimeout(updateLayout, 500);
|
| | | });
|
| | |
|
| | | onUnmounted(() => {
|
| | | rectsElements.value = {};
|
| | | });
|
| | |
|
| | |
|
| | | </script>
|
| | |
|
| | | <style scoped>
|
| | | .layout-wrapper {
|
| | | position: relative;
|
| | | margin-top:50px;
|
| | | margin-top: 50px;
|
| | | }
|
| | |
|
| | | .layout-container {
|
| | |
| | | border-radius: 3px;
|
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
| | | font-weight: bold;
|
| | |
|
| | | }
|
| | |
|
| | | .rect-content {
|
| New file |
| | |
| | | package com.example.erp.config; |
| | | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | @Configuration |
| | | public class AppConfig { |
| | | @Bean |
| | | public RestTemplate restTemplate() { |
| | | return new RestTemplate(); |
| | | } |
| | | } |
| | |
| | | import cn.dev33.satoken.annotation.SaCheckPermission; |
| | | import com.example.erp.common.Constants; |
| | | import com.example.erp.common.Result; |
| | | import com.example.erp.entity.pp.LayoutsData; |
| | | import com.example.erp.entity.pp.OptimizeProjectMange; |
| | | import com.example.erp.exception.ServiceException; |
| | | import com.example.erp.service.pp.GlassOptimizeService; |
| | | import com.example.erp.service.pp.JsonToOptConverter; |
| | | import com.example.erp.service.userInfo.UserService; |
| | | import com.fasterxml.jackson.core.JsonProcessingException; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.sql.Date; |
| | | import java.util.Map; |
| | | |
| | |
| | | public class GlassOptimizeController { |
| | | @Autowired |
| | | GlassOptimizeService glassOptimizeService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | | //工程信息 |
| | | @ApiOperation("工程信息接口") |
| | | @PostMapping ("/projectInfo/{projectNo}") |
| | |
| | | } |
| | | } |
| | | |
| | | @ApiOperation("优化设置保存") |
| | | @PostMapping("/optimizeParms") |
| | | public Result optimizeParmsSave(@RequestBody Map<String, Object> object) { |
| | | try { |
| | | return Result.seccess(glassOptimizeService.optimizeParmsSave(object)); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return Result.error(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @PostMapping("/selectOptimizeParms/{username}") |
| | | public Result getOptimizeParms(@PathVariable String username) { |
| | | return Result.seccess(userService.getOptimizeParms(username)); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | return Result.error(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | @RequestBody Map<String,Object> object){ |
| | | return Result.seccess(glassOptimizeService.addProjectSv(optionVal,projectId,projectNmae,object)); |
| | | } |
| | | |
| | | |
| | | @ApiOperation("保存优化结果接口") |
| | | @PostMapping("/saveOptimizeResult") |
| | | public Result saveOptimizeResult( |
| | | @RequestBody Map<String,Object> object){ |
| | | return Result.seccess(glassOptimizeService.saveOptimizeResult(object)); |
| | | } |
| | | |
| | | |
| | | @ApiOperation("查询优化结果接口") |
| | | @PostMapping("/selectOptimizeResult/{processId}") |
| | | public Result selectOptimizeResult( |
| | | @PathVariable String processId){ |
| | | return Result.seccess(glassOptimizeService.selectOptimizeResult(processId)); |
| | | } |
| | | |
| | | @ApiOperation("更新优化结果接口") |
| | | @PostMapping("/updateOptimizeResult/{processId}") |
| | | public Result updateOptimizeResult( |
| | | @PathVariable String processId,@RequestBody Map<String,Object> object){ |
| | | |
| | | return Result.seccess(glassOptimizeService.updateOptimizeResult(object,processId)); |
| | | } |
| | | @ApiOperation("OPT文件下载接口") |
| | | @PostMapping("/generateOpt") |
| | | public ResponseEntity<byte[]> generateOptFile(@RequestBody LayoutsData layoutsData) throws IOException { |
| | | // 确保 layoutsData 包含 Layouts 数组 |
| | | if (layoutsData == null || layoutsData.getLayouts() == null) { |
| | | throw new IllegalArgumentException("Layouts 数据不能为空"); |
| | | } |
| | | |
| | | // 生成 OPT 文件内容 |
| | | String optContent = JsonToOptConverter.generateOptContent(layoutsData); |
| | | |
| | | // 创建响应头 |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.setContentType(org.springframework.http.MediaType.TEXT_PLAIN); |
| | | headers.setContentDispositionFormData("attachment", "output.opt"); |
| | | |
| | | // 返回文件内容 |
| | | return new ResponseEntity<>(optContent.getBytes(), headers, HttpStatus.OK); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | return Result.seccess(reportingWorkService.SaveReportingWorkSv(reportingWork)); |
| | | } |
| | | |
| | | @ApiOperation("报工转移") |
| | | @PostMapping ("/reportingWorkTransfer") |
| | | public Result reportingWorkTransfer(@RequestBody Map<String,String> reportingWork) { |
| | | return Result.seccess(reportingWorkService.reportingWorkTransferSv(reportingWork)); |
| | | } |
| | | |
| | | } |
| | |
| | | @ApiOperation("手机扫码玻璃信息") |
| | | @PostMapping("/scannerGlassInfo/{projectNo}") |
| | | public Result scannerGlassInfo(@PathVariable String projectNo) { |
| | | System.out.println("123123"); |
| | | return Result.seccess(orderService.scannerGlassInfo(projectNo)); |
| | | } |
| | | |
| | | @PostMapping("/test") |
| | | public Result scannerGlassInfo() { |
| | | System.out.println("123123"); |
| | | return Result.seccess(null); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | public Result updateUserName(@RequestBody Map<String,Object> object){ |
| | | return Result.seccess( userService.updateUserName(object)); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.example.erp.dto.pp; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 订单序号报工转换变更传输类 |
| | | */ |
| | | |
| | | @Data |
| | | public class OrderNumberTransferDTO { |
| | | /** |
| | | * 旧流程卡号 |
| | | */ |
| | | private String oldProcessId; |
| | | |
| | | /** |
| | | * 旧序号 |
| | | */ |
| | | private String oldOrderNumber; |
| | | |
| | | /** |
| | | * 旧层号 |
| | | */ |
| | | private Integer oldTechnologyNumber; |
| | | |
| | | /** |
| | | * 信流程卡号 |
| | | */ |
| | | private String newProcessId; |
| | | |
| | | /** |
| | | * 新序号 |
| | | */ |
| | | private String newOrderNumber; |
| | | |
| | | /** |
| | | * 新层号 |
| | | */ |
| | | private Integer newTechnologyNumber; |
| | | |
| | | /** |
| | | * 变更数量 |
| | | */ |
| | | private Integer changeNumber; |
| | | } |
| | |
| | | private Integer sort; |
| | | //架号 |
| | | private String rack; |
| | | //订单转移导入数量 |
| | | private Integer importNumber; |
| | | //订单转移导出数量 |
| | | private Integer exportNumber; |
| | | //建立时间 |
| | | private LocalDate createTime; |
| | | //修改时间 |
| New file |
| | |
| | | package com.example.erp.entity.pp;
|
| | |
|
| | | import com.fasterxml.jackson.annotation.JsonProperty;
|
| | | import java.util.List;
|
| | |
|
| | | public class LayoutsData {
|
| | | @JsonProperty("Layouts")
|
| | | private List<Layout> layouts;
|
| | |
|
| | | public List<Layout> getLayouts() {
|
| | | return layouts;
|
| | | }
|
| | |
|
| | |
|
| | | public static class Layout {
|
| | | @JsonProperty("mnumber")
|
| | | private int mNumber;
|
| | | @JsonProperty("width")
|
| | | private int width;
|
| | | @JsonProperty("rects")
|
| | | private List<Rect> rects;
|
| | | @JsonProperty("wuliao")
|
| | | private String material;
|
| | | @JsonProperty("SameCount")
|
| | | private int sameCount;
|
| | | @JsonProperty("height")
|
| | | private int height;
|
| | |
|
| | | public int getWidth() {
|
| | | return width;
|
| | | }
|
| | | public int getSameCount() {
|
| | | return sameCount;
|
| | | }
|
| | | public String getWuliao() {
|
| | | return material;
|
| | | }
|
| | |
|
| | | public int getHeight() {
|
| | | return height;
|
| | | }
|
| | |
|
| | | public List<Rect> getRects() {
|
| | | return rects;
|
| | | }
|
| | | }
|
| | |
|
| | | public static class Rect {
|
| | | @JsonProperty("isRemain")
|
| | | private boolean isRemain;
|
| | | @JsonProperty("h")
|
| | | private int h;
|
| | | @JsonProperty("DM2")
|
| | | private int dm2;
|
| | | @JsonProperty("xuhao")
|
| | | private String serialNumber;
|
| | | @JsonProperty("DM1")
|
| | | private int dm1;
|
| | | @JsonProperty("liuchengka")
|
| | | private String processCard;
|
| | | @JsonProperty("JiaHao")
|
| | | private String jiaHao;
|
| | | @JsonProperty("LM2")
|
| | | private int lm2;
|
| | | @JsonProperty("LM1")
|
| | | private int lm1;
|
| | | @JsonProperty("w")
|
| | | private int W;
|
| | | @JsonProperty("x")
|
| | | private int x;
|
| | | @JsonProperty("y")
|
| | | private int y;
|
| | | @JsonProperty("rownumber")
|
| | | private int rowNumber;
|
| | |
|
| | | public int getWidth() {
|
| | | return W;
|
| | | }
|
| | |
|
| | | public int getHeight() {
|
| | | 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;
|
| | | }
|
| | | }
|
| | | } |
| New file |
| | |
| | | package com.example.erp.entity.pp; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDate; |
| | | |
| | | @Data |
| | | public class ReportingWorkTransfer { |
| | | @TableId(type = IdType.AUTO) |
| | | private Long id; |
| | | //被转移订单号 |
| | | private String oldOrder; |
| | | //被转移序号 |
| | | private Integer oldOrderNumber; |
| | | //被转移内容(sd报工流程表) |
| | | private String oldReportContent; |
| | | |
| | | //新订单 |
| | | private String newOrder; |
| | | //新订单序号 |
| | | private Integer newOrderNumber; |
| | | //新转移内容 |
| | | private String newReportContent; |
| | | //建立时间 |
| | | private LocalDate createTime; |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.example.erp.entity.mm.FinishedGoodsInventory; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | @TableName("sd.`order_detail`") |
| | | public class OrderDetail { |
| | | @TableId(type = IdType.AUTO) |
| | | private Long id; |
| | |
| | | private String createTime; |
| | | private String updateTime; |
| | | private Integer state; |
| | | private String optimizeParms; |
| | | @TableField(select = false,exist = false) |
| | | private List<UserRole> userRoleList; |
| | | |
| | |
| | | void addratioResult(Map<String, Object> object); |
| | | //模拟计算保存 工程信息 |
| | | void addratioProjectResult(Map<String, Object> object); |
| | | //优化设置保存 |
| | | void optimizeParmsSave(String jsonString); |
| | | |
| | | //优化结果保存 |
| | | void optimizeResultSave(String jsonString); |
| | | //优化结果查询 |
| | | List<Map<String, Object>> selectOptimizeResult(String processId); |
| | | //优化结果调整 |
| | | void updateOptimizeResult(String jsonString,String processId); |
| | | |
| | | List<Map<String, Object>> getProcessCardDetailmMp(String processId, Integer technologyNumber); |
| | | |
| New file |
| | |
| | | package com.example.erp.mapper.pp; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.example.erp.entity.pp.ReportingWorkTransfer; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | @Mapper |
| | | public interface ReportingWorkTransferMapper extends BaseMapper<ReportingWorkTransfer> { |
| | | } |
| | |
| | | Boolean updateProcessMp(Integer id, String process); |
| | | |
| | | List<User> findByAddress(String userName); |
| | | |
| | | String selectOptimizeParmsById(@Param("username") String username); |
| | | } |
| | |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | //优化设置保存 |
| | | public Boolean optimizeParmsSave(Map<String, Object> object) { |
| | | try { |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | String jsonString = mapper.writeValueAsString(object); |
| | | |
| | | glassOptimizeMapper.optimizeParmsSave(jsonString); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | //优化调整结果保存 |
| | | public Boolean saveOptimizeResult(Map<String, Object> object) { |
| | | try { |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | String jsonString = mapper.writeValueAsString(object); |
| | | glassOptimizeMapper.optimizeResultSave(jsonString); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | public Boolean updateOptimizeResult(Map<String, Object> object,String processId){ |
| | | try { |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | String jsonString = mapper.writeValueAsString(object); |
| | | glassOptimizeMapper.updateOptimizeResult(jsonString,processId); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | //优化调整结果查询 |
| | | public Map<String, Object> selectOptimizeResult(String processId) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("data", glassOptimizeMapper.selectOptimizeResult(processId)); |
| | | return map; |
| | | } |
| | | |
| | | //工程信息 |
| | | public Map<String, Object> projectInfoSv(String projectNo) { |
| | | Map<String, Object> map = new HashMap<>(); |
| New file |
| | |
| | | package com.example.erp.service.pp;
|
| | |
|
| | | import com.example.erp.entity.pp.LayoutsData;
|
| | | 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 {
|
| | | ObjectMapper objectMapper = new ObjectMapper();
|
| | | return objectMapper.writeValueAsString(layoutsData);
|
| | | }
|
| | |
|
| | | public static String generateOptContent(LayoutsData layoutsData) {
|
| | | StringBuilder optContent = new StringBuilder();
|
| | | 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=5.0\n");
|
| | | optContent.append("Dimension=mm\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) {
|
| | | optContent.append("[OPT_Signature]\n");
|
| | | optContent.append("Creator=OPTIMA S.r.l.\n\n");
|
| | | }
|
| | |
|
| | | 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()) {
|
| | | 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 infoId = 1;
|
| | | for (Layout layout : layoutsData.getLayouts()) {
|
| | | for (Rect rect : layout.getRects()) {
|
| | | 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++;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.example.erp.common.Constants; |
| | | import com.example.erp.entity.pp.DamageDetails; |
| | | import com.example.erp.entity.pp.FlowCard; |
| | | import com.example.erp.entity.pp.ReportingWork; |
| | | import com.example.erp.entity.pp.ReportingWorkDetail; |
| | | import com.example.erp.dto.pp.OrderNumberTransferDTO; |
| | | import com.example.erp.entity.pp.*; |
| | | import com.example.erp.entity.sd.Order; |
| | | import com.example.erp.entity.sd.OrderDetail; |
| | | import com.example.erp.entity.sd.OrderProcessDetail; |
| | | import com.example.erp.entity.userInfo.Log; |
| | | import com.example.erp.entity.userInfo.SysError; |
| | | import com.example.erp.exception.ServiceException; |
| | | import com.example.erp.mapper.mm.FinishedOperateLogMapper; |
| | | import com.example.erp.mapper.pp.*; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.example.erp.mapper.sd.OrderDetailMapper; |
| | | import com.example.erp.mapper.sd.OrderGlassDetailMapper; |
| | | import com.example.erp.mapper.sd.OrderMapper; |
| | | import com.example.erp.mapper.sd.OrderProcessDetailMapper; |
| | |
| | | import com.example.erp.service.userInfo.LogService; |
| | | import com.example.erp.service.userInfo.SysErrorService; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.http.HttpEntity; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | |
| | | |
| | | @Service |
| | | @DS("pp") |
| | | @RequiredArgsConstructor |
| | | public class ReportingWorkService { |
| | | final |
| | | ReportingWorkMapper reportingWorkMapper; |
| | | final |
| | | BasicDateProduceMapper basicDateProduceMapper; |
| | | final |
| | | DamageDetailsMapper damageDetailsMapper; |
| | | final |
| | | OrderProcessDetailMapper orderProcessDetailMapper; |
| | | final |
| | | ReportingWorkDetailMapper |
| | | reportingWorkDetailMapper; |
| | | final OrderMapper |
| | | orderMapper; |
| | | private final ReportingWorkTransferMapper reportingWorkTransferMapper; |
| | | private final ReportingWorkMapper reportingWorkMapper; |
| | | private final BasicDateProduceMapper basicDateProduceMapper; |
| | | private final DamageDetailsMapper damageDetailsMapper; |
| | | private final OrderProcessDetailMapper orderProcessDetailMapper; |
| | | private final ReportingWorkDetailMapper reportingWorkDetailMapper; |
| | | private final OrderMapper orderMapper; |
| | | private final OrderDetailMapper orderDetailMapper; |
| | | |
| | | final |
| | | FlowCardMapper flowCardMapper; |
| | | private final FlowCardMapper flowCardMapper; |
| | | |
| | | final |
| | | OrderProcessDetailService orderProcessDetailService; |
| | | private final OrderProcessDetailService orderProcessDetailService; |
| | | |
| | | final |
| | | LogService logService; |
| | | private final LogService logService; |
| | | |
| | | final LogMapper logMapper; |
| | | private final LogMapper logMapper; |
| | | private final OrderGlassDetailMapper orderGlassDetailMapper; |
| | | private final SysErrorService sysErrorService; |
| | | private final FinishedOperateLogMapper finishedOperateLogMapper; |
| | | private final RestTemplate restTemplate; |
| | | |
| | | |
| | | public ReportingWorkService(ReportingWorkMapper reportingWorkMapper, BasicDateProduceMapper basicDateProduceMapper, DamageDetailsMapper damageDetailsMapper, ReportingWorkDetailMapper reportingWorkDetailMapper, OrderProcessDetailMapper orderProcessDetailMapper, OrderProcessDetailService orderProcessDetailService, OrderMapper orderMapper, FlowCardMapper flowCardMapper, LogService logService, LogMapper logMapper, OrderGlassDetailMapper orderGlassDetailMapper, SysErrorService sysErrorService) { |
| | | /*public ReportingWorkService(ReportingWorkMapper reportingWorkMapper, BasicDateProduceMapper basicDateProduceMapper, DamageDetailsMapper damageDetailsMapper, ReportingWorkDetailMapper reportingWorkDetailMapper, OrderProcessDetailMapper orderProcessDetailMapper, OrderProcessDetailService orderProcessDetailService, OrderMapper orderMapper, FlowCardMapper flowCardMapper, LogService logService, LogMapper logMapper, OrderGlassDetailMapper orderGlassDetailMapper, SysErrorService sysErrorService, OrderDetailMapper orderDetailMapper, FinishedOperateLogMapper finishedOperateLogMapper, ReportingWorkTransferMapper reportingWorkTransferMapper) { |
| | | this.reportingWorkMapper = reportingWorkMapper; |
| | | this.basicDateProduceMapper = basicDateProduceMapper; |
| | | this.damageDetailsMapper = damageDetailsMapper; |
| | |
| | | this.logMapper = logMapper; |
| | | this.orderGlassDetailMapper = orderGlassDetailMapper; |
| | | this.sysErrorService = sysErrorService; |
| | | } |
| | | this.orderDetailMapper = orderDetailMapper; |
| | | this.finishedOperateLogMapper = finishedOperateLogMapper; |
| | | this.reportingWorkTransferMapper = reportingWorkTransferMapper; |
| | | }*/ |
| | | |
| | | public Map<String, Object> AddSelectLastWorkSv(String processIdStr, String technologyStr, String process, String reportType) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | |
| | | |
| | | } |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Object reportingWorkTransferSv(Map<String, String> reportingWork) { |
| | | Order oldOrder = orderMapper.selectOrderId(reportingWork.get("oldOrderId")); |
| | | OrderDetail oldOrderDetail = orderDetailMapper.selectOne( |
| | | new QueryWrapper<OrderDetail>() |
| | | .eq("order_id", reportingWork.get("oldOrderId")) |
| | | .eq("order_number", reportingWork.get("oldOrderNumber")) |
| | | ); |
| | | |
| | | Order newOrder = orderMapper.selectOrderId(reportingWork.get("newOrderId")); |
| | | OrderDetail newOrderDetail = orderDetailMapper.selectOne( |
| | | new QueryWrapper<OrderDetail>() |
| | | .eq("order_id", reportingWork.get("newOrderId")) |
| | | .eq("order_number", reportingWork.get("newOrderNumber")) |
| | | ); |
| | | if(!Objects.equals(oldOrder.getCustomerId(), newOrder.getCustomerId())){ |
| | | return "新旧订单客户不一致"; |
| | | } |
| | | if(!Objects.equals(oldOrderDetail.getProductId(), newOrderDetail.getProductId())){ |
| | | return "新旧订单产品不一致"; |
| | | } |
| | | if (!Objects.equals(oldOrderDetail.getWidth(), newOrderDetail.getWidth()) |
| | | || !Objects.equals(oldOrderDetail.getHeight(), newOrderDetail.getHeight())){ |
| | | return "新旧订单尺寸不一致"; |
| | | } |
| | | |
| | | |
| | | //获取旧订单是否流程卡是否存在 |
| | | List<OrderProcessDetail> oldOrderProcessDetailList = orderProcessDetailMapper |
| | | .selectList(new QueryWrapper<OrderProcessDetail>() |
| | | .eq("order_id", reportingWork.get("oldOrderId")) |
| | | .eq("order_number", reportingWork.get("oldOrderNumber")) |
| | | ); |
| | | if(oldOrderProcessDetailList.isEmpty()){ |
| | | return "旧订单未分流程卡"; |
| | | } |
| | | //获取新订单是否流程卡是否存在 |
| | | List<OrderProcessDetail> newOrderProcessDetailList = orderProcessDetailMapper |
| | | .selectList(new QueryWrapper<OrderProcessDetail>() |
| | | .eq("order_id", reportingWork.get("newOrderId")) |
| | | .eq("order_number", reportingWork.get("newOrderNumber")) |
| | | ); |
| | | if(newOrderProcessDetailList.isEmpty()){ |
| | | return "新订单未分流程卡"; |
| | | } |
| | | //新订单是否存在已经排版序号 |
| | | List<FlowCard> newFlowCardLayoutStatus = flowCardMapper.selectList(new QueryWrapper<FlowCard>() |
| | | .eq("order_id", reportingWork.get("newOrderId")) |
| | | .eq("order_number", reportingWork.get("newOrderNumber")) |
| | | .gt("layout_status",0) |
| | | ); |
| | | if(!newFlowCardLayoutStatus.isEmpty()){ |
| | | return "新订单此序号存在排版"; |
| | | } |
| | | //获取旧订单报工数据汇总 |
| | | List<OrderProcessDetail> oldOrderProcessDetailForReport = orderProcessDetailMapper |
| | | .selectList(new QueryWrapper<OrderProcessDetail>() |
| | | .eq( "order_id", reportingWork.get("oldOrderId")) |
| | | .eq("order_number", reportingWork.get("oldOrderNumber")) |
| | | .gt("reporting_work_num",0) |
| | | ); |
| | | |
| | | Map<String,Object> log = new HashMap<>(); |
| | | log.put("oldOrderBeforeChange",oldOrderProcessDetailForReport); |
| | | |
| | | Map<String,Object> newOrderLog = new HashMap<>(); |
| | | newOrderLog.put("newOrderBeforeChange",newOrderProcessDetailList); |
| | | |
| | | //传给mes流程卡数量集合 |
| | | List<OrderNumberTransferDTO> orderNumberTransferList = new ArrayList<>(); |
| | | |
| | | oldOrderProcessDetailForReport.forEach(oldOrderProcessDetail -> { |
| | | int maxNum = 0; |
| | | for(OrderProcessDetail newOrderProcessDetail : newOrderProcessDetailList){ |
| | | if(oldOrderProcessDetail.getReportingWorkNum() == 0){ |
| | | break; |
| | | } |
| | | //判断小片是否一致,工序是否一致 |
| | | if(newOrderProcessDetail.getProcess().equals(oldOrderProcessDetail.getProcess()) && |
| | | Objects.equals(newOrderProcessDetail.getTechnologyNumber(), oldOrderProcessDetail.getTechnologyNumber())){ |
| | | //判断是否为第一道工序,给可转移最大值赋值 |
| | | if(oldOrderProcessDetail.getProcess().equals("切割")){ |
| | | FlowCard thisFlowCard = flowCardMapper.selectOne(new QueryWrapper<FlowCard>() |
| | | .eq("process_id", newOrderProcessDetail.getProcessId()) |
| | | .eq("order_number", newOrderProcessDetail.getOrderNumber()) |
| | | .eq("technology_number",newOrderProcessDetail.getTechnologyNumber()) |
| | | ); |
| | | maxNum = thisFlowCard.getQuantity(); |
| | | }else{ |
| | | //当不是第一道工序则,拿上一道工序作为最大值 |
| | | maxNum = orderProcessDetailMapper.selectById(newOrderProcessDetail.getId()-1).getReportingWorkNum(); |
| | | } |
| | | //判断被转移的数量是否大于可转移的数量最大值 |
| | | int transferNum = 0; |
| | | if(oldOrderProcessDetail.getReportingWorkNum() > maxNum){ |
| | | transferNum = maxNum; |
| | | oldOrderProcessDetail.setReportingWorkNum(oldOrderProcessDetail.getReportingWorkNum()-maxNum); |
| | | oldOrderProcessDetail.setReportingWorkNumCount(oldOrderProcessDetail.getReportingWorkNumCount()-maxNum); |
| | | }else{ |
| | | transferNum = oldOrderProcessDetail.getReportingWorkNum(); |
| | | oldOrderProcessDetail.setReportingWorkNum(0); |
| | | oldOrderProcessDetail.setReportingWorkNumCount(0); |
| | | } |
| | | //更新旧订单小片流程表的报工数量 |
| | | orderProcessDetailMapper.update(null,new UpdateWrapper<OrderProcessDetail>() |
| | | .set("reporting_work_num",oldOrderProcessDetail.getReportingWorkNum()) |
| | | .set("reporting_work_num_count",oldOrderProcessDetail.getReportingWorkNumCount()) |
| | | .eq("id",oldOrderProcessDetail.getId()) |
| | | ); |
| | | //更新新订单小片流程表的报工数量 |
| | | orderProcessDetailMapper.update(null,new UpdateWrapper<OrderProcessDetail>() |
| | | .set("reporting_work_num",transferNum) |
| | | .set("reporting_work_num_count",transferNum) |
| | | .eq("id",newOrderProcessDetail.getId()) |
| | | ); |
| | | if(oldOrderProcessDetail.getProcess().equals("切割")){ |
| | | //更新旧订单流程卡转出数量 |
| | | flowCardMapper.update(null,new UpdateWrapper<FlowCard>() |
| | | .setSql("export_number = export_number + "+transferNum) |
| | | .eq("process_id", oldOrderProcessDetail.getProcessId()) |
| | | .eq("order_number", oldOrderProcessDetail.getOrderNumber()) |
| | | .eq("technology_number",oldOrderProcessDetail.getTechnologyNumber()) |
| | | ); |
| | | //更新新订单流程卡转出数量 |
| | | flowCardMapper.update(null,new UpdateWrapper<FlowCard>() |
| | | .setSql("import_number = import_number + "+transferNum) |
| | | .eq("process_id", newOrderProcessDetail.getProcessId()) |
| | | .eq("order_number", newOrderProcessDetail.getOrderNumber()) |
| | | .eq("technology_number",newOrderProcessDetail.getTechnologyNumber()) |
| | | ); |
| | | |
| | | //传给mes数据赋值 |
| | | OrderNumberTransferDTO orderNumberTransfer = new OrderNumberTransferDTO(); |
| | | orderNumberTransfer.setChangeNumber(transferNum); |
| | | orderNumberTransfer.setOldProcessId(oldOrderProcessDetail.getProcessId()); |
| | | orderNumberTransfer.setNewProcessId(newOrderProcessDetail.getProcessId()); |
| | | orderNumberTransfer.setOldOrderNumber(oldOrderProcessDetail.getOrderNumber()); |
| | | orderNumberTransfer.setNewOrderNumber(newOrderProcessDetail.getOrderNumber()); |
| | | orderNumberTransfer.setOldTechnologyNumber(oldOrderProcessDetail.getTechnologyNumber()); |
| | | orderNumberTransfer.setNewTechnologyNumber(newOrderProcessDetail.getTechnologyNumber()); |
| | | orderNumberTransferList.add(orderNumberTransfer); |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | }); |
| | | |
| | | |
| | | //把旧订单数据和新订单数据传到日志表当中 |
| | | log.put("oldOrderChange",JSON.toJSONString(oldOrderProcessDetailForReport)); |
| | | |
| | | newOrderLog.put("newOrderChange",orderProcessDetailMapper |
| | | .selectList(new QueryWrapper<OrderProcessDetail>() |
| | | .eq("order_id", reportingWork.get("newOrderId")) |
| | | .eq("order_number", reportingWork.get("newOrderNumber")) |
| | | )); |
| | | //旧订单信息传入日志 |
| | | ReportingWorkTransfer reportingWorkTransfer = new ReportingWorkTransfer(); |
| | | reportingWorkTransfer.setOldOrder(reportingWork.get("oldOrderId")); |
| | | reportingWorkTransfer.setOldOrderNumber(Integer.valueOf(reportingWork.get("oldOrderNumber"))); |
| | | reportingWorkTransfer.setOldReportContent(JSON.toJSONString(log)); |
| | | |
| | | //新订单信息传入日志 |
| | | reportingWorkTransfer.setNewOrder(reportingWork.get("newOrderId")); |
| | | reportingWorkTransfer.setNewOrderNumber(Integer.valueOf(reportingWork.get("newOrderNumber"))); |
| | | reportingWorkTransfer.setNewReportContent(JSON.toJSONString(newOrderLog)); |
| | | reportingWorkTransferMapper.insert(reportingWorkTransfer); |
| | | //restTemplate.postForObject("http://localhost:8086/order/test",orderNumberTransferList,String.class); |
| | | |
| | | //向mes发送http请求 |
| | | ResponseEntity<String> response =restTemplate.exchange( |
| | | "http://localhost:88/api/loadGlass/order/order/orderChange", |
| | | HttpMethod.POST, |
| | | new HttpEntity<>(orderNumberTransferList), |
| | | String.class); |
| | | |
| | | if(response.getStatusCode() == HttpStatus.OK){ |
| | | return true; |
| | | }else{ |
| | | return "mes响应超时"; |
| | | } |
| | | } |
| | | } |
| | |
| | | map.put("users", Collections.singletonList(userList)); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | //查询用户优化参数 |
| | | public String getOptimizeParms(String username) { |
| | | // 获取当前登录用户 |
| | | |
| | | return userMapper.selectOptimizeParmsById(username); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | LEFT JOIN pp.damage_details dal ON dal.order_number = g.order_number AND dal.technology_number = g.technology_number and f.process_id=dal.process_id |
| | | LEFT JOIN pp.flow_card fl ON fl.order_id = g.order_id AND fl.order_number = g.order_number AND fl.technology_number = g.technology_number |
| | | WHERE |
| | | p.state IN (1, 2) and |
| | | f.process_id = #{processId} |
| | | </select> |
| | | |
| | |
| | | ); |
| | | </foreach> |
| | | </insert> |
| | | |
| | | <!--模拟计算结果保存--> |
| | | <insert id="addratioResult" parameterType="map"> |
| | | <foreach collection="projectdetail.data[0].ratioResult" item="glass"> |
| | | INSERT INTO pp.optimize_heat_layout ( |
| | |
| | | </foreach> |
| | | </insert> |
| | | |
| | | |
| | | <!--模拟计算工程更新--> |
| | | <update id="addratioProjectResult" parameterType="map"> |
| | | UPDATE pp.optimize_project |
| | | SET |
| | |
| | | project_no = #{inputValues.project_no} |
| | | |
| | | </update> |
| | | <!--优化设置保存--> |
| | | <update id="optimizeParmsSave"> |
| | | update erp_user_info.user as u |
| | | set u.optimize_parms = #{jsonString} |
| | | </update> |
| | | |
| | | <update id="updateOptimizeResult"> |
| | | update pp.optimize_project_file as u |
| | | set u.content = #{jsonString} |
| | | where u.project_no=#{processId} and type='优化结果' |
| | | </update> |
| | | |
| | | |
| | | |
| | | <select id="selectOptimizeResult"> |
| | | SELECT content as Layouts |
| | | FROM pp.optimize_project_file |
| | | WHERE project_no=#{processId} and type='优化结果'; |
| | | </select> |
| | | </mapper> |
| | |
| | | ogd.child_width, |
| | | ogd.child_height, |
| | | if(od.shape=1,'普形',if(od.shape=2,'异形','')) as shape, |
| | | fc.quantity + ifnull(patch.patch_num,0) -odpd.reporting_work_num -odpd.broken_num as quantity, |
| | | fc.quantity + ifnull(patch.patch_num,0) -odpd.reporting_work_num -odpd.broken_num as completedQuantity, |
| | | fc.quantity -fc.export_number + ifnull(patch.patch_num,0) -odpd.reporting_work_num -odpd.broken_num as quantity, |
| | | fc.quantity -fc.export_number + ifnull(patch.patch_num,0) -odpd.reporting_work_num -odpd.broken_num as completedQuantity, |
| | | odpd.reporting_work_num as completed, |
| | | odpd.broken_num as onceBroken, |
| | | if(fc.quantity -odpd.reporting_work_num = 0 ,true,false) as saveFlag, -- 判断是否已经完成,已经完成不序号和同序号数量相同才能提交 |
| | |
| | | set address=#{process},update_time=now() |
| | | where id=#{id} |
| | | </update> |
| | | |
| | | |
| | | <select id="selectOptimizeParmsById" resultType="String"> |
| | | SELECT optimize_parms FROM erp_user_info.user WHERE user_name = #{username} |
| | | </select> |
| | | |
| | | |
| | | </mapper> |