From d7d7da5c09340eafcd2e2c672e6b2c001a4cc0be Mon Sep 17 00:00:00 2001 From: hcong <1050828145@qq.com> Date: 星期五, 08 十一月 2024 08:38:40 +0800 Subject: [PATCH] 基础数据产品-场景清单,监管清单 --- package-lock.json | 258 ++++ src/views/fysp/data-product/components/CompProdTreatmentDeviceDescription.vue | 61 + src/views/fysp/data-product/components/CompGooderProdStage,.vue | 106 + src/views/fysp/data-product/js/tableCol.js | 21 public/test.docx | 0 src/components.d.ts | 8 src/constants/menu.js | 15 src/api/fysp/taskApi.js | 15 src/views/fysp/data-product/components/CompShowEChart.vue | 211 +++ src/views/fysp/data-product/components/CompPreviewProd.vue | 14 src/views/fysp/data-product/components/DynamicTable.vue | 246 ++++ src/views/fysp/data-product/ProdScenseInfo.vue | 637 ++++++++++ src/views/fysp/data-product/ProdMonitorTaskInfo.vue | 600 ++++++++++ src/views/fysp/data-product/components/TableColumn.vue | 71 + src/router/index.js | 18 src/views/fysp/data-product/components/CompSelectProdStage.vue | 85 + src/views/fysp/data-product/js/htmlTransfer.js | 120 ++ src/views/fysp/data-product/components/MutiableOptionScene.vue | 84 + src/views/fysp/data-product/components/OptionChartProd.vue | 47 src/views/fysp/data-product/js/genChart.js | 123 ++ src/main.js | 9 src/views/fysp/data-product/components/CompChangeHeaderTree.vue | 90 + package.json | 9 src/views/fysp/data-product/components/ComSelectMonitorTaskProdStage.vue | 143 ++ src/views/fysp/data-product/components/CompProdSteps.vue | 9 src/views/fysp/data-product/ProdTreatmentDeviceInfo.vue | 80 + src/views/fysp/data-product/components/CompProdGenMonitorInfoDescription.vue | 109 + src/views/fysp/data-product/components/CompProdGenScenseDescription.vue | 286 ++++ 28 files changed, 3,463 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c46b4e..ae86edd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,13 +13,21 @@ "@element-plus/icons-vue": "^2.0.10", "@vue-office/excel": "^1.7.11", "@vueuse/core": "^9.7.0", + "angular-expressions": "^1.4.0", "axios": "^1.2.1", "dayjs": "^1.11.13", + "docxtemplater": "^3.9.0", + "docxtemplater-image-module-free": "^1.1.1", + "echarts": "^4.8.0", "element-plus": "^2.8.3", "exceljs": "^4.4.0", + "file-saver": "^2.0.5", + "html2canvas": "^1.4.1", "js-base64": "^3.7.5", + "jszip-utils": "^0.1.0", "md5": "^2.3.0", "pinia": "^2.0.26", + "pizzip": "^3.1.7", "vue": "^3.2.45", "vue-demi": "^0.14.6", "vue-i18n": "^9.8.0", @@ -31,6 +39,7 @@ "@babel/core": "^7.20.5", "@babel/eslint-parser": "^7.19.1", "@babel/preset-env": "^7.20.2", + "@types/html-docx-js": "^0.3.4", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", "@vitejs/plugin-vue": "^3.2.0", @@ -2221,6 +2230,16 @@ "license": "MIT", "peer": true }, + "node_modules/@types/html-docx-js": { + "version": "0.3.4", + "resolved": "https://registry.npmmirror.com/@types/html-docx-js/-/html-docx-js-0.3.4.tgz", + "integrity": "sha512-+t/4SxNnEq+0xbSUG7LrOOfG/y12aTXBjYKtOYtigVRIIOCEmK7jh0pSUeW5ATvI934274hkzdBg57t5RDrZow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "dev": true, @@ -2853,6 +2872,12 @@ "ajv": "^6.9.1" } }, + "node_modules/angular-expressions": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/angular-expressions/-/angular-expressions-1.4.0.tgz", + "integrity": "sha512-LmbYpeZMuMhifpk+LmF2li9FzH2kYPwF/ykwHFKSnLrk8zJ8sZUjipcmGjJoHQTPcfj/YhkUoQYVbyZ08jDdYg==", + "license": "Unlicense" + }, "node_modules/ansi-colors": { "version": "4.1.3", "dev": true, @@ -3191,6 +3216,15 @@ "node_modules/balanced-match": { "version": "1.0.2", "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } }, "node_modules/base64-js": { "version": "1.5.1", @@ -3745,6 +3779,15 @@ "node": "*" } }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/cssesc": { "version": "3.0.0", "dev": true, @@ -3933,6 +3976,27 @@ "node": ">=6.0.0" } }, + "node_modules/docxtemplater": { + "version": "3.9.0", + "resolved": "https://registry.npmmirror.com/docxtemplater/-/docxtemplater-3.9.0.tgz", + "integrity": "sha512-l74k7jtT/Ui3Y+KZOxaUr85HxfsHZJ3xaYzYfGmgpHavfsxvtu2pF7rU/AqERGpY59mip0gj0PxqfI5Wfcxw7Q==", + "license": "MIT", + "dependencies": { + "xmldom": "^0.1.27" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/docxtemplater-image-module-free": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/docxtemplater-image-module-free/-/docxtemplater-image-module-free-1.1.1.tgz", + "integrity": "sha512-aWOzVQN7ggDYjfoy3pTTNrcrZ7/CJrQcI9cT+hmyHE6nRLR67nt5yPFPe9hm9VWbfYIED2fi+3itOnF0TE/RWQ==", + "license": "MIT", + "dependencies": { + "xmldom": "^0.1.27" + } + }, "node_modules/domexception": { "version": "4.0.0", "dev": true, @@ -3991,6 +4055,15 @@ "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" + } + }, + "node_modules/echarts": { + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-4.8.0.tgz", + "integrity": "sha512-YwShpug8fWngj/RlgxDaYrLBoD+LsZUArrusjNPHpAF+is+gGe38xx4W848AwWMGoi745t3OXM52JedNrv+F6g==", + "license": "Apache-2.0", + "dependencies": { + "zrender": "4.3.1" } }, "node_modules/electron-to-chromium": { @@ -4692,6 +4765,12 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.0.1", "dev": true, @@ -5037,6 +5116,19 @@ }, "engines": { "node": ">=12" + } + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" } }, "node_modules/http-proxy-agent": { @@ -5566,6 +5658,12 @@ "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } + }, + "node_modules/jszip-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/jszip-utils/-/jszip-utils-0.1.0.tgz", + "integrity": "sha512-tBNe0o3HAf8vo0BrOYnLPnXNo5A3KsRMnkBFYjh20Y3GPYGfgyoclEMgvVchx0nnL+mherPi74yLPIusHUQpZg==", + "license": "(MIT OR GPL-3.0)" }, "node_modules/jszip/node_modules/readable-stream": { "version": "2.3.8", @@ -6431,6 +6529,21 @@ "optional": true } } + }, + "node_modules/pizzip": { + "version": "3.1.7", + "resolved": "https://registry.npmmirror.com/pizzip/-/pizzip-3.1.7.tgz", + "integrity": "sha512-VemVeAQtdIA74AN1Fsd5OmbMbEeS4YOwwlcudgzvmUrOIOPrk1idYC5Tw5FUFq/I0c26ziNOw9z//iPmGfp1jA==", + "license": "(MIT OR GPL-3.0)", + "dependencies": { + "pako": "^2.1.0" + } + }, + "node_modules/pizzip/node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", + "license": "(MIT AND Zlib)" }, "node_modules/postcss": { "version": "8.4.20", @@ -7317,6 +7430,15 @@ "license": "MIT", "peer": true }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/text-table": { "version": "0.2.0", "dev": true, @@ -7798,6 +7920,15 @@ "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT" + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } }, "node_modules/uuid": { "version": "8.3.2", @@ -8290,6 +8421,16 @@ "version": "2.2.0", "license": "MIT" }, + "node_modules/xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmmirror.com/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", + "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0", + "license": "(LGPL-2.0 or MIT)", + "engines": { + "node": ">=0.1" + } + }, "node_modules/yallist": { "version": "4.0.0", "dev": true, @@ -8347,6 +8488,12 @@ "engines": { "node": ">= 10" } + }, + "node_modules/zrender": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-4.3.1.tgz", + "integrity": "sha512-CeH2TpJeCdG0TAGYoPSAcFX2ogdug1K7LIn9UO/q9HWqQ54gWhrMAlDP9AwWYMUDhrPe4VeazQ4DW3msD96nUQ==", + "license": "BSD-3-Clause" } }, "dependencies": { @@ -9727,6 +9874,15 @@ "dev": true, "peer": true }, + "@types/html-docx-js": { + "version": "0.3.4", + "resolved": "https://registry.npmmirror.com/@types/html-docx-js/-/html-docx-js-0.3.4.tgz", + "integrity": "sha512-+t/4SxNnEq+0xbSUG7LrOOfG/y12aTXBjYKtOYtigVRIIOCEmK7jh0pSUeW5ATvI934274hkzdBg57t5RDrZow==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/json-schema": { "version": "7.0.15", "dev": true @@ -10194,6 +10350,11 @@ "peer": true, "requires": {} }, + "angular-expressions": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/angular-expressions/-/angular-expressions-1.4.0.tgz", + "integrity": "sha512-LmbYpeZMuMhifpk+LmF2li9FzH2kYPwF/ykwHFKSnLrk8zJ8sZUjipcmGjJoHQTPcfj/YhkUoQYVbyZ08jDdYg==" + }, "ansi-colors": { "version": "4.1.3", "dev": true @@ -10413,6 +10574,11 @@ }, "balanced-match": { "version": "1.0.2" + }, + "base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" }, "base64-js": { "version": "1.5.1" @@ -10745,6 +10911,14 @@ "resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" }, + "css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "requires": { + "utrie": "^1.0.2" + } + }, "cssesc": { "version": "3.0.0", "dev": true @@ -10879,6 +11053,22 @@ "esutils": "^2.0.2" } }, + "docxtemplater": { + "version": "3.9.0", + "resolved": "https://registry.npmmirror.com/docxtemplater/-/docxtemplater-3.9.0.tgz", + "integrity": "sha512-l74k7jtT/Ui3Y+KZOxaUr85HxfsHZJ3xaYzYfGmgpHavfsxvtu2pF7rU/AqERGpY59mip0gj0PxqfI5Wfcxw7Q==", + "requires": { + "xmldom": "^0.1.27" + } + }, + "docxtemplater-image-module-free": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/docxtemplater-image-module-free/-/docxtemplater-image-module-free-1.1.1.tgz", + "integrity": "sha512-aWOzVQN7ggDYjfoy3pTTNrcrZ7/CJrQcI9cT+hmyHE6nRLR67nt5yPFPe9hm9VWbfYIED2fi+3itOnF0TE/RWQ==", + "requires": { + "xmldom": "^0.1.27" + } + }, "domexception": { "version": "4.0.0", "dev": true, @@ -10933,6 +11123,14 @@ "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" + } + }, + "echarts": { + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-4.8.0.tgz", + "integrity": "sha512-YwShpug8fWngj/RlgxDaYrLBoD+LsZUArrusjNPHpAF+is+gGe38xx4W848AwWMGoi745t3OXM52JedNrv+F6g==", + "requires": { + "zrender": "4.3.1" } }, "electron-to-chromium": { @@ -11406,6 +11604,11 @@ "flat-cache": "^3.0.4" } }, + "file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "fill-range": { "version": "7.0.1", "dev": true, @@ -11626,6 +11829,15 @@ "dev": true, "requires": { "whatwg-encoding": "^2.0.0" + } + }, + "html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "requires": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" } }, "http-proxy-agent": { @@ -11994,6 +12206,11 @@ } } } + }, + "jszip-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/jszip-utils/-/jszip-utils-0.1.0.tgz", + "integrity": "sha512-tBNe0o3HAf8vo0BrOYnLPnXNo5A3KsRMnkBFYjh20Y3GPYGfgyoclEMgvVchx0nnL+mherPi74yLPIusHUQpZg==" }, "klona": { "version": "2.0.5", @@ -12544,6 +12761,21 @@ "vue-demi": "*" } }, + "pizzip": { + "version": "3.1.7", + "resolved": "https://registry.npmmirror.com/pizzip/-/pizzip-3.1.7.tgz", + "integrity": "sha512-VemVeAQtdIA74AN1Fsd5OmbMbEeS4YOwwlcudgzvmUrOIOPrk1idYC5Tw5FUFq/I0c26ziNOw9z//iPmGfp1jA==", + "requires": { + "pako": "^2.1.0" + }, + "dependencies": { + "pako": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + } + } + }, "postcss": { "version": "8.4.20", "requires": { @@ -13085,6 +13317,14 @@ "terser": "^5.14.1" } }, + "text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "requires": { + "utrie": "^1.0.2" + } + }, "text-table": { "version": "0.2.0", "dev": true @@ -13393,6 +13633,14 @@ "util-deprecate": { "version": "1.0.2" }, + "utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "requires": { + "base64-arraybuffer": "^1.0.2" + } + }, "uuid": { "version": "8.3.2" }, @@ -13654,6 +13902,11 @@ "xmlchars": { "version": "2.2.0" }, + "xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmmirror.com/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" + }, "yallist": { "version": "4.0.0", "dev": true @@ -13698,6 +13951,11 @@ } } } + }, + "zrender": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-4.3.1.tgz", + "integrity": "sha512-CeH2TpJeCdG0TAGYoPSAcFX2ogdug1K7LIn9UO/q9HWqQ54gWhrMAlDP9AwWYMUDhrPe4VeazQ4DW3msD96nUQ==" } } } diff --git a/package.json b/package.json index 7308c77..ca7301b 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,21 @@ "@element-plus/icons-vue": "^2.0.10", "@vue-office/excel": "^1.7.11", "@vueuse/core": "^9.7.0", + "angular-expressions": "^1.4.0", "axios": "^1.2.1", "dayjs": "^1.11.13", + "docxtemplater": "^3.9.0", + "docxtemplater-image-module-free": "^1.1.1", + "echarts": "^4.8.0", "element-plus": "^2.8.3", "exceljs": "^4.4.0", + "file-saver": "^2.0.5", + "html2canvas": "^1.4.1", "js-base64": "^3.7.5", + "jszip-utils": "^0.1.0", "md5": "^2.3.0", "pinia": "^2.0.26", + "pizzip": "^3.1.7", "vue": "^3.2.45", "vue-demi": "^0.14.6", "vue-i18n": "^9.8.0", @@ -36,6 +44,7 @@ "@babel/core": "^7.20.5", "@babel/eslint-parser": "^7.19.1", "@babel/preset-env": "^7.20.2", + "@types/html-docx-js": "^0.3.4", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", "@vitejs/plugin-vue": "^3.2.0", diff --git a/public/test.docx b/public/test.docx new file mode 100644 index 0000000..b37c1d1 --- /dev/null +++ b/public/test.docx Binary files differ diff --git a/src/api/fysp/taskApi.js b/src/api/fysp/taskApi.js index d7f918b..98c4c90 100644 --- a/src/api/fysp/taskApi.js +++ b/src/api/fysp/taskApi.js @@ -22,6 +22,13 @@ return $fysp.get('task/alltask/0').then((res) => res.data); }, + /** + * 鑾峰彇椤跺眰浠诲姟鍜屾棩浠诲姟 + */ + getTopTaskWithDayTask() { + return $fysp.get('task/alltask/1').then((res) => res.data); + }, + getLastTopTask(task){ return $fysp.post(`task/lastTask`, task).then((res) => res.data); }, @@ -119,9 +126,11 @@ /** * 閫氳繃鎬讳换鍔d鍜屾椂闂村尯闂磋幏鍙栧瓙浠诲姟鍒楄〃 */ - async getByTopTaskAndDate({startTime, endTime, sceneTypeId, topTaskId}) { - const params = `?startTime=${startTime}&endTime=${endTime}&sceneTypeId=${sceneTypeId}&topTaskId=${topTaskId}`; - return await $fysp.get(`subtask/getSubTask${params}`).then((res) => res.data); + async getByTopTaskAndDate({startTime = null, endTime = null, sceneTypeId = null, topTaskId}) { + // const params = `?startTime=${startTime}&endTime=${endTime}&sceneTypeId=${sceneTypeId}&topTaskId=${topTaskId}`; + return await $fysp.get(`subtask/getSubTask`, { + params: {startTime: startTime, endTime: endTime, sceneTypeId: sceneTypeId, topTaskId: topTaskId} + }).then((res) => res.data); }, /** * 鑾峰彇鏌愪釜鍦烘櫙鐨勫贰鏌ヤ换鍔� diff --git a/src/components.d.ts b/src/components.d.ts index 37e7435..124cacb 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -12,23 +12,18 @@ BasePanelLayout: typeof import('./components/core/BasePanelLayout.vue')['default'] CompQuickSet: typeof import('./components/search-option/CompQuickSet.vue')['default'] Content: typeof import('./components/core/Content.vue')['default'] - ElAffix: typeof import('element-plus/es')['ElAffix'] ElAside: typeof import('element-plus/es')['ElAside'] ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElBadge: typeof import('element-plus/es')['ElBadge'] ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] - ElCalendar: typeof import('element-plus/es')['ElCalendar'] ElCard: typeof import('element-plus/es')['ElCard'] - ElCascader: typeof import('element-plus/es')['ElCascader'] - ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCol: typeof import('element-plus/es')['ElCol'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] ElContainer: typeof import('element-plus/es')['ElContainer'] - ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDescriptions: typeof import('element-plus/es')['ElDescriptions'] ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem'] ElDialog: typeof import('element-plus/es')['ElDialog'] @@ -41,7 +36,6 @@ ElIcon: typeof import('element-plus/es')['ElIcon'] ElImage: typeof import('element-plus/es')['ElImage'] ElInput: typeof import('element-plus/es')['ElInput'] - ElLink: typeof import('element-plus/es')['ElLink'] ElMain: typeof import('element-plus/es')['ElMain'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] @@ -50,7 +44,6 @@ ElPopover: typeof import('element-plus/es')['ElPopover'] ElRow: typeof import('element-plus/es')['ElRow'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] - ElSegmented: typeof import('element-plus/es')['ElSegmented'] ElSelect: typeof import('element-plus/es')['ElSelect'] ElSpace: typeof import('element-plus/es')['ElSpace'] ElStep: typeof import('element-plus/es')['ElStep'] @@ -62,7 +55,6 @@ ElTabs: typeof import('element-plus/es')['ElTabs'] ElTag: typeof import('element-plus/es')['ElTag'] ElText: typeof import('element-plus/es')['ElText'] - ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTree: typeof import('element-plus/es')['ElTree'] ElUpload: typeof import('element-plus/es')['ElUpload'] Footer: typeof import('./components/core/Footer.vue')['default'] diff --git a/src/constants/menu.js b/src/constants/menu.js index 9e744ee..a1637ba 100644 --- a/src/constants/menu.js +++ b/src/constants/menu.js @@ -64,6 +64,21 @@ icon: 'Document', name: '鍦烘櫙鎶ュ憡', }, + { + path: '/fysp/data-product/ProdScenseInfo', + icon: 'Document', + name: '鍦烘櫙娓呭崟', + }, + { + path: '/fysp/data-product/ProdMonitorTaskInfo', + icon: 'Document', + name: '鐩戠娓呭崟', + }, + { + path: '/fysp/data-product/ProdTreatmentDeviceInfo', + icon: 'Document', + name: '闃叉不璁惧娓呭崟', + }, ], }, // { diff --git a/src/main.js b/src/main.js index 511d8bd..95195f2 100644 --- a/src/main.js +++ b/src/main.js @@ -14,6 +14,10 @@ import 'element-plus/theme-chalk/src/message-box.scss'; import 'element-plus/theme-chalk/src/notification.scss'; +// 寮曞叆echarts +// import Echarts from 'vue-echarts' +import * as echarts from 'echarts' + // dayjs plugin import dayjs from 'dayjs'; import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; @@ -29,7 +33,10 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component); } - +// 浣跨敤缁勪欢 +// app.component('e-charts',Echarts) +// 鍏ㄥ眬鎸傝浇 echarts +app.config.globalProperties.$echarts = echarts app .use(pinia) .use(router) diff --git a/src/router/index.js b/src/router/index.js index 41e3ccd..72fa525 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -41,6 +41,24 @@ path: '/fysp/data-product/scenereport', component: () => import('@/views/fysp/data-product/ProdSceneReport.vue') }, + { + // 鍩虹浜у搧-鍦烘櫙娓呭崟 + name: 'ProdScenseInfo', + path: '/fysp/data-product/ProdScenseInfo', + component: () => import('@/views/fysp/data-product/ProdScenseInfo.vue') + }, + { + // 鍩虹浜у搧-鐩戠娓呭崟 + name: 'ProdMonitorTaskInfo', + path: '/fysp/data-product/ProdMonitorTaskInfo', + component: () => import('@/views/fysp/data-product/ProdMonitorTaskInfo.vue') + }, + { + // 鍩虹浜у搧-闃叉不璁惧娓呭崟 + name: 'ProdTreatmentDeviceInfo', + path: '/fysp/data-product/ProdTreatmentDeviceInfo', + component: () => import('@/views/fysp/data-product/ProdTreatmentDeviceInfo.vue') + }, // { // //鍦烘櫙鎶ュ憡-宸ュ湴 // name: 'construction', diff --git a/src/views/fysp/data-product/ProdMonitorTaskInfo.vue b/src/views/fysp/data-product/ProdMonitorTaskInfo.vue new file mode 100644 index 0000000..120f59f --- /dev/null +++ b/src/views/fysp/data-product/ProdMonitorTaskInfo.vue @@ -0,0 +1,600 @@ +<template> + <el-col> + <el-row justify="end" class="fixed-div"> + <!-- 鎸夐挳缁� --> + <div class="btn-group"> + <el-button v-if="this.activeStep.id > 0" @click="beforeStep" + >涓婁竴姝�</el-button + > + <el-button + v-if="this.activeStep.id == 0" + @click="genDialog = true" + type="primary" + >浜у搧鐢熸垚閰嶇疆</el-button + > + <el-button + v-if="this.activeStep.id == 1" + @click="gooderDialog = true" + type="primary" + >浜у搧浼樺寲閰嶇疆</el-button + > + <!-- <el-button type="primary" @click="chartDialog = true" + >鍥捐〃灞曠ず</el-button + > --> + <el-button + v-if="this.activeStep.id == 2" + type="primary" + @click="previewProduct" + >鐢熸垚</el-button + > + </div> + </el-row> + </el-col> + <!-- 姝ラ --> + <el-steps + :active="activeStep.id" + finish-status="success" + style="" + align-center + > + <el-step v-for="(s, i) in steps" :key="s.id" :title="s.name" /> + </el-steps> + <div class="center-div"> + <span class="title-input"> {{ title }} </span><br /> + </div> + <div class="center-div"> + <div + v-show="this.activeStep.id != 0" + class="main" + v-loading="searchLoading" + > + <span class="second-title"> {{ `涓�銆佺洃绠℃鍐礰 }} </span> + <CompProdGenMonitorInfoDescription + id="descriptionComp" + class="product-item-margin" + :table-data="tableData" + :location="formSearch._locations" + ref="prodGenDescriptionRef" + @generated-description="onGeneratedDescription" + > + </CompProdGenMonitorInfoDescription> + <template v-if="showChart"> + <span class="second-title"> {{ `浜屻�佺粺璁¢�忚` }} </span> + <div class="charts product-item-margin"> + <div class="chart-item" v-for="chart in charts" :key="chart.id"> + <div class="chart" ref="myChart" :id="chart.id"></div> + <!-- <el-button + type="danger" + @click="charts = charts.filter((item) => item.id != chart.id)" + >鍒犻櫎</el-button + > --> + </div> + </div> + </template> + <span class="second-title"> {{ `涓夈�佽缁嗘竻鍗昤 }} </span> + <DynamicTable + ref="dynamicTableRef" + v-loading="loading" + :table-header="tableConfig" + @search="onSearch" + :pagination="false" + ></DynamicTable> + </div> + <el-empty + v-show="this.activeStep.id == 0" + style="font-size: large" + description="鏈厤缃骇鍝�" + /> + </div> + + <el-dialog title="浜у搧鐢熸垚閰嶇疆" v-model="genDialog"> + <ComSelectMonitorTaskProdStage + :table-header="tableConfig" + @next="selectProdStageOver" + > + </ComSelectMonitorTaskProdStage> + </el-dialog> + <el-dialog title="浜у搧浼樺寲" v-model="gooderDialog" destroy-on-close> + <CompGooderProdStage + :table-header="tableConfig" + @selected-gooder="onselectedGooder" + > + </CompGooderProdStage> + </el-dialog> + <el-dialog title="鍥捐〃灞曠ず" v-model="chartDialog" destroy-on-close> + <CompShowEChart + @painted-chart="onPaintedChart" + :table-data="tableData" + :table-header="tableConfig" + ref="chartRef" + > + </CompShowEChart> + </el-dialog> +</template> +<script> +import sceneApi from '@/api/fysp/sceneApi'; +import taskApi from '@/api/fysp/taskApi.js'; +import DynamicTable from './components/DynamicTable.vue'; +import { load } from '@amap/amap-jsapi-loader'; +import ComSelectMonitorTaskProdStage from './components/ComSelectMonitorTaskProdStage.vue'; +import CompProdGenMonitorInfoDescription from './components/CompProdGenMonitorInfoDescription.vue'; +import CompShowEChart from './components/CompShowEChart.vue'; +import htmlTransfer from './js/htmlTransfer'; +import dayjs from 'dayjs'; +import CompGooderProdStage from './components/CompGooderProdStage,.vue'; +import genChart from './js/genChart'; +export default { + components: { + DynamicTable, + ComSelectMonitorTaskProdStage, + CompProdGenMonitorInfoDescription, + CompShowEChart, + CompGooderProdStage + }, + computed: { + title() { + return ( + (this.formSearch._locations.tName || + this.formSearch._locations.dName || + this.formSearch._locations.cName || + this.formSearch._locations.pName || + '') + '鐩戠娓呭崟' + ); + } + }, + watch: { + oneValue: { + handler(nv, ov) { + console.log('master', nv); + }, + immediate: true, + deep: true + } + }, + data() { + return { + gooderDialog: false, + activeStep: { + id: 0, + name: '浜у搧閰嶇疆鐢熸垚' + }, + steps: [ + { + id: 0, + name: '浜у搧閰嶇疆鐢熸垚' + }, + { + id: 1, + name: '浜у搧閰嶇疆浼樺寲' + }, + { + id: 2, + name: '鐢熸垚' + } + ], + mainVisible: false, + showChart: false, + chartDialog: false, + genDialog: false, + oneValue: { + _locations: {}, + _scenetype: [] + }, + charts: [], + chart: {}, + loading: false, + tableConfig: [], + tableData: [], + formSearch: { + topTask: '', + _locations: {}, + searchText: '', + _scenetype: {}, + online: {}, + topTasks: [] + }, + topTasks: [] + }; + }, + mounted() { + this.getOptions(); + this.genHeaders(); + }, + methods: { + genWord() { + let imgUrls = this.charts.map((item) => { + return htmlTransfer.chartToImageUrl( + this.$echarts.getInstanceByDom(document.getElementById(item.id)) + ); + }); + const data = { + title: this.title, + description: this.description, + tableData: this.tableData, + imgUrls: imgUrls + }; + const imgSize = { + imgUrl: [200, 200] + }; + htmlTransfer.ExportBriefDataDocx( + '.\\test.docx', // 妯℃澘璺緞 + data, // 鏁版嵁 + this.title, // 鏂囦欢鍚� + imgSize + ); + }, + previewProduct() { + this.genWord(); + }, + onGeneratedDescription(description) { + this.description = description; + }, + onPaintedChart(chartOption) { + this.showChart = true; + let id = `chart${this.charts.length}`; + this.charts.push({ + id: id, + option: chartOption + }); + console.log('chartOption', chartOption); + setTimeout(() => { + const dom = document.getElementById(id); + + const myChart = this.$echarts.init(dom); // 鍒濆鍖杄charts瀹炰緥 + this.chart = myChart; + myChart.setOption(chartOption); + this.chartDialog = false; + }, 100); + }, + // 绗竴闃舵纭畾涔嬪悗鐨勫洖璋� + selectProdStageOver(result) { + this.genDialog = false; + this.nextStep(); + if (result != null) { + this.formSearch._locations = result._locations; + this.formSearch.topTasks = result.topTasks; + + this.$refs.dynamicTableRef.onSearch(); + } + console.log('绗竴闃舵杩斿洖鍊�', result); + }, + onTopTaskChange(value) { + this.$refs.dynamicTableRef.onSearch(); + }, + //鑾峰彇鏌ヨ鏉′欢 + getOptions() { + taskApi.getTopTask().then((res) => { + const list = res.map((r) => { + return { + value: r.tguid, + label: r.name, + data: r + }; + }); + this.topTasks = list; + this.formSearch.topTask = list[0]; + // this.$refs.dynamicTableRef.onSearch(); + }); + }, + addSceneRegion(obj) { + obj.scene._region = + obj.scene.provincename + + obj.scene.cityname + + obj.scene.districtname + + obj.scene.townname + + obj.scene.location; + }, + standardSupervisedNum(obj) { + obj.extension1 = obj.extension1 ? obj.extension1 : 0; + }, + addSupervisedTime(monitorObj) { + console.log('monitorObj', monitorObj); + if (!('_subTasks' in monitorObj) || monitorObj._subTasks.length == 0) { + monitorObj._executionstarttime = '/'; + return; + } + monitorObj._executionstarttime = monitorObj._subTasks + .map((item) => dayjs(item.executionstarttime).format('YYYY-MM-DD')) + .join(','); + }, + + onSearch(page, func) { + this.loading = true; + // 鑾峰彇褰撳墠鐩戠浠诲姟涓嬫墍鏈夊瓙浠诲姟 + const getAllNeedSubTaskPromises = this.formSearch.topTasks.map((item) => { + return taskApi.getByTopTaskAndDate({ topTaskId: item.tguid }); + }); + + const subTaskPromises = this.formSearch.topTasks.map((item) => { + return taskApi.fetchMonitorObjectVersion(item.tguid); + }); + Promise.all(getAllNeedSubTaskPromises) + .then((results) => { + // 灏嗕簩缁存暟缁勫睍骞虫垚涓�缁存暟缁� + const subTasks = results.reduce((acc, val) => acc.concat(val), []); + console.log('subTasks', subTasks); + + return Promise.all(subTasks); + }) + .then((allSubTasks) => { + // 浣跨敤 Promise.all 绛夊緟鎵�鏈夌殑瀛愪换鍔¤姹傚畬鎴� + Promise.all(subTaskPromises) + .then((results) => { + console.log('results', results); + // 灏嗕簩缁存暟缁勫睍骞虫垚涓�缁存暟缁� + const flatResults = results.reduce( + (acc, val) => acc.concat(val), + [] + ); + // 鍐嶆浣跨敤 Promise.all 澶勭悊涓�缁存暟缁勪腑鐨勬瘡涓厓绱� + return Promise.all(flatResults); + }) + .then((moniterRes) => { + // 淇濆瓨鏃ヤ换鍔″垪琛� + taskApi.getTopTaskWithDayTask().then((allTopAndDay) => { + let topWithDyTask = allTopAndDay.filter((item) => { + return ( + this.formSearch.topTasks + .map((top) => top.tguid) + .indexOf(item.tguid) != -1 + ); + }); + + const subTasks = []; + for (const r of moniterRes) { + // 璧嬪�兼�讳换鍔� _topTask.daytaskList 涓烘棩浠诲姟鍒楄〃 + r._topTask = topWithDyTask.filter( + (item) => item.tguid == r.tid + )[0]; + r._topTask.daytaskList.forEach((dayTask) => { + let dayTaskId = dayTask.tguid; + let topTaskId = dayTask.tsguid; + let sceneId = r.sguid; + let subTasks = this.selectSubTaskBySceneIdAndTaskId( + allSubTasks, + sceneId, + topTaskId, + dayTaskId + ); + if (subTasks) { + r._subTasks = subTasks; + } + }); + // 鐢熸垚鍦烘櫙鍖哄煙鍒� + this.addSceneRegion(r); + // 鏍囧噯鍖栧凡鐩戠娆℃暟 + this.standardSupervisedNum(r); + // 鐢熸垚鐩戠鏃堕棿鍒� + this.addSupervisedTime(r); + // r._topTask = this.formSearch.topTask.data; + subTasks.push(r); + } + this.tableData = subTasks; + this.genSomeCharts(); + func({ + data: subTasks + }); + this.loading = false; + }); + }) + .catch((error) => { + this.loading = false; + console.error('Error fetching subtasks:', error); + }); + }); + }, + genSomeCharts() { + console.log("this.ta", this.tableData); + // 娣诲姞鍥捐〃 + this.charts = []; + this.showChart = true; + // 鐢熸垚鍖哄煙涓殑涓嬩竴绾х殑鍥捐〃 + const l = this.formSearch._locations; + console.log(this.tableData); + + let positionProp = ''; + if (l.pName != null) { + positionProp = 'cityname'; + if (l.cName != null) { + positionProp = 'districtname'; + if (l.dName != null) { + positionProp = 'townname'; + if (l.tName != null) { + positionProp = 'townname'; + } + } + } + } + positionProp = 'scene.' + positionProp; + [ + genChart.getChartByDataAndProp(this.tableData, 'sceneType', '绫诲瀷', 'bar'), + genChart.getPieChartByDataAndProp( + this.tableData, + positionProp, + '鎵�灞炲尯鍩�' + ) + ].forEach((item) => { + let id = `chart${this.charts.length}`; + this.charts.push({ + id: id, + option: item + }); + setTimeout(() => { + this.paintChart(id, item); + }, 100); + }); + }, + paintChart(id, chartOption) { + const dom = document.getElementById(id); + var startX, startY, chartWidth, chartHeight; + const myChart = this.$echarts.init(dom); // 鍒濆鍖杄charts瀹炰緥 + // 寮�濮嬫嫋鎷� + myChart.getZr().on('mousedown', function (event) { + if (event.target) { + startX = event.offsetX; + startY = event.offsetY; + chartWidth = myChart.getWidth(); + chartHeight = myChart.getHeight(); + } + }); + + // 鎷栧姩璋冩暣瀹藉害 + myChart.getZr().on('mouseup', function (event) { + if (startX != null || startY != null) { + var deltaX = event.offsetX - startX; + var deltaY = event.offsetY - startY; + myChart.resize({ + width: chartWidth + deltaX, + height: chartHeight + deltaY + }); + } + startX = null; + startY = null; + }); + + this.chart = myChart; + myChart.setOption(chartOption); + this.chartDialog = false; + }, + selectSubTaskBySceneIdAndTaskId(subTasks, sceneId, topTaskId, dayTaskId) { + return subTasks.filter( + (item) => + item.scenseid == sceneId && + item.tguid == topTaskId && + item.tsguid == dayTaskId + ); + }, + beforeStep() { + let currId = this.activeStep.id; + this.activeStep = this.steps.filter((item) => item.id == currId - 1)[0]; + }, + nextStep() { + let currId = this.activeStep.id; + this.activeStep = this.steps.filter( + (item) => item.id == (currId + 1) % this.steps.length + )[0]; + }, + onselectedGooder(result) { + let copy = this.tableConfig.map((item) => item); + result.forEach((item) => { + copy = copy.filter( + (copyItem) => !(copyItem.id == item.id1 || copyItem.id == item.id2) + ); + copy.push(item); + this.tableData.forEach( + (tableItem) => + (tableItem[item.prop] = `${tableItem[item.prop1]},${ + tableItem[item.prop2] + }`) + ); + copy.sort((a, b) => a.id - b.id); + }); + this.tableConfig = copy; + this.gooderDialog = false; + this.nextStep(); + }, + genHeaders() { + this.tableConfig = [ + { + id: 1, + label: '鍦烘櫙鍚嶇О', + prop: 'scene.name', + width: '80' + }, + { + id: 2, + label: '鍦烘櫙鎵�灞炲尯鍩�', + prop: 'scene._region', + width: '80' + }, + { + id: 3, + label: '鍦烘櫙绫诲瀷', + prop: 'scene.type', + width: '20' + }, + { + id: 4, + label: '璁″垝娆℃暟', + prop: 'monitornum', + width: '20' + }, + { + id: 5, + label: '瀹為檯宸茬洃绠℃鏁�', + prop: 'extension1', + width: '20' + }, + { + id: 6, + label: '瀹為檯鎵ц鏃ユ湡', + prop: '_executionstarttime', + width: '20' + } + ]; + } + } +}; +</script> +<style scoped> +.options { + display: flex; + padding: 5px; +} +.title-input { + margin-top: -20px; + border-radius: 6px; + color: #000; + width: 80%; + font-size: 1.5rem; + line-height: 5rem; + text-align: center; + border: none; +} +.center-div { + display: flex; + justify-content: center; +} +.btn-group { + /* background-color: rgb(32, 127, 211); */ + white-space: nowrap; +} +.chart { + margin-top: 5px; + margin-bottom: 2px; + width: 100%; + height: 500px; +} +/* 鍥哄畾瀹氫綅鐨� div */ +.fixed-div { + position: fixed; + top: 7%; + right: 20px; /* 璺濈鍙充晶 20px */ + width: 'auto'; /* div 鐨勫搴� */ + background-color: #f2f2f200; /* 鑳屾櫙棰滆壊 */ + padding: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.11); /* 闃村奖鏁堟灉 */ + z-index: 1000; /* 纭繚 div 鍦ㄩ〉闈㈠叾浠栧唴瀹逛箣涓� */ +} +.charts { + display: flex; + flex-wrap: wrap; +} +.chart-item { + text-align: center; + width: 30%; +} +.product-item-margin { + margin-bottom: 5px; +} +.second-title { + color: var(--el-text-color-primary); + font-size: 16px; + font-weight: bold; + margin-bottom: 16px; +} +.main { + /* text-align: center; */ + width: 95%; +} +</style> diff --git a/src/views/fysp/data-product/ProdScenseInfo.vue b/src/views/fysp/data-product/ProdScenseInfo.vue new file mode 100644 index 0000000..ef36789 --- /dev/null +++ b/src/views/fysp/data-product/ProdScenseInfo.vue @@ -0,0 +1,637 @@ +<template> + <el-col> + <el-row justify="end" class="fixed-div"> + <!-- 鎸夐挳缁� --> + <div class="btn-group"> + <el-button v-if="this.activeStep.id > 0" @click="beforeStep" + >涓婁竴姝�</el-button + > + <el-button + v-if="this.activeStep.id == 0" + @click="genDialog = true" + type="primary" + >浜у搧鐢熸垚閰嶇疆</el-button + > + <el-button + v-if="this.activeStep.id == 1" + @click="gooderDialog = true" + type="primary" + >浜у搧浼樺寲閰嶇疆</el-button + > + <!-- <el-button type="primary" @click="chartDialog = true" + >鍥捐〃灞曠ず</el-button + > --> + <el-button + v-if="this.activeStep.id == 2" + type="primary" + @click="previewProduct" + >鐢熸垚</el-button + > + </div> + </el-row> + </el-col> + <!-- 姝ラ --> + <el-steps + :active="activeStep.id" + finish-status="success" + style="" + align-center + > + <el-step v-for="(s, i) in steps" :key="s.id" :title="s.name" /> + </el-steps> + <div class="center-div"> + <span class="title-input"> {{ title }} </span><br /> + </div> + <div class="center-div"> + <div + v-show="this.activeStep.id != 0" + class="main" + v-loading="searchLoading" + > + <span class="second-title"> {{ `涓�銆佸満鏅鍐礰 }} </span> + <CompProdGenScenseDescription + id="descriptionComp" + class="product-item-margin" + :table-data="tableData" + :location="formSearch._locations" + ref="prodGenDescriptionRef" + @generated-description="onGeneratedDescription" + > + </CompProdGenScenseDescription> + <template v-if="showChart"> + <span class="second-title"> {{ `浜屻�佺粺璁¢�忚` }} </span> + <div class="charts product-item-margin"> + <div class="chart-item" v-for="chart in charts" :key="chart.id"> + <div class="chart" ref="myChart" :id="chart.id"></div> + <!-- <el-button + type="danger" + @click="charts = charts.filter((item) => item.id != chart.id)" + >鍒犻櫎</el-button + > --> + </div> + </div> + </template> + <span class="second-title"> {{ `涓夈�佽缁嗘竻鍗昤 }} </span> + <DynamicTable + class="product-item-margin" + ref="dynamicTableRef" + :table-header="tableConfig" + @search="onSearch" + :pagination="false" + ></DynamicTable> + </div> + <el-empty + v-show="this.activeStep.id == 0" + style="font-size: large" + description="鏈厤缃骇鍝�" + /> + </div> + <el-dialog title="浜у搧鐢熸垚閰嶇疆" v-model="genDialog"> + <CompSelectProdStage + :table-header="tableConfig" + @next="selectProdStageOver" + > + </CompSelectProdStage> + </el-dialog> + <el-dialog title="浜у搧棰勮" v-model="previewDialog" destroy-on-close> + <CompSelectProdStage @next="selectProdStageOver"> </CompSelectProdStage> + </el-dialog> + <el-dialog title="浜у搧浼樺寲" v-model="gooderDialog" destroy-on-close> + <CompGooderProdStage + :table-header="tableConfig" + @selected-gooder="onselectedGooder" + > + </CompGooderProdStage> + </el-dialog> + <el-dialog title="鍥捐〃灞曠ず" v-model="chartDialog" destroy-on-close> + <CompShowEChart + @painted-chart="onPaintedChart" + :table-data="tableData" + :table-header="tableConfig" + ref="chartRef" + > + </CompShowEChart> + </el-dialog> +</template> +<script> +import DynamicTable from './components/DynamicTable.vue'; +import CompSelectProdStage from './components/CompSelectProdStage.vue'; +import sceneApi from '@/api/fysp/sceneApi'; +import taskApi from '@/api/fysp/taskApi.js'; +import CompProdGenScenseDescription from './components/CompProdGenScenseDescription.vue'; +import htmlTransfer from './js/htmlTransfer'; +import CompShowEChart from './components/CompShowEChart.vue'; +import html2canvas from 'html2canvas'; +import CompGooderProdStage from './components/CompGooderProdStage,.vue'; +import dayjs from 'dayjs'; +import genChart from './js/genChart'; +export default { + computed: { + title() { + return ( + (this.formSearch._locations.tName || + this.formSearch._locations.dName || + this.formSearch._locations.cName || + this.formSearch._locations.pName || + '') + '鍦板尯鍦烘櫙娓呭崟' + ); + } + }, + components: { + DynamicTable, + CompSelectProdStage, + CompProdGenScenseDescription, + CompShowEChart, + CompGooderProdStage + }, + data() { + return { + activeStep: { + id: 0, + name: '浜у搧閰嶇疆鐢熸垚' + }, + steps: [ + { + id: 0, + name: '浜у搧閰嶇疆鐢熸垚' + }, + { + id: 1, + name: '浜у搧閰嶇疆浼樺寲' + }, + { + id: 2, + name: '鐢熸垚' + } + ], + gooderDialog: false, + searchLoading: false, + description: '', + showChart: false, + chart: {}, + charts: [], + chartDialog: false, + genDialog: false, + tableConfig: [], + tableData: [], + formSearch: { + _locations: {}, + searchText: '', + _scenetypes: [], + _scenetype: {}, + online: {} + } + }; + }, + mounted() { + this.genHeaders(); + }, + methods: { + beforeStep() { + let currId = this.activeStep.id; + this.activeStep = this.steps.filter((item) => item.id == currId - 1)[0]; + }, + nextStep() { + let currId = this.activeStep.id; + this.activeStep = this.steps.filter( + (item) => item.id == (currId + 1) % this.steps.length + )[0]; + }, + onselectedGooder(result) { + let copy = this.tableConfig.map((item) => item); + result.forEach((item) => { + copy = copy.filter( + (copyItem) => !(copyItem.id == item.id1 || copyItem.id == item.id2) + ); + copy.push(item); + this.tableData.forEach( + (tableItem) => + (tableItem[item.prop] = `${tableItem[item.prop1]},${ + tableItem[item.prop2] + }`) + ); + copy.sort((a, b) => a.id - b.id); + }); + this.tableConfig = copy; + this.gooderDialog = false; + this.nextStep(); + }, + captureScreenshot() { + const element = document.getElementById('descriptionComp'); + + return html2canvas(element).then((canvas) => + canvas.toDataURL('image/png') + ); + }, + onGeneratedDescription(description) { + this.description = description; + }, + paintChart(id, chartOption) { + const dom = document.getElementById(id); + var startX, startY, chartWidth, chartHeight; + const myChart = this.$echarts.init(dom); // 鍒濆鍖杄charts瀹炰緥 + // 寮�濮嬫嫋鎷� + myChart.getZr().on('mousedown', function (event) { + if (event.target) { + startX = event.offsetX; + startY = event.offsetY; + chartWidth = myChart.getWidth(); + chartHeight = myChart.getHeight(); + } + }); + + // 鎷栧姩璋冩暣瀹藉害 + myChart.getZr().on('mouseup', function (event) { + if (startX != null || startY != null) { + var deltaX = event.offsetX - startX; + var deltaY = event.offsetY - startY; + myChart.resize({ + width: chartWidth + deltaX, + height: chartHeight + deltaY + }); + } + startX = null; + startY = null; + }); + + this.chart = myChart; + myChart.setOption(chartOption); + this.chartDialog = false; + }, + onPaintedChart(chartOption) { + this.showChart = true; + let id = `chart${this.charts.length}`; + this.charts.push({ + id: id, + option: chartOption + }); + console.log('chartOption', chartOption); + + setTimeout(() => { + this.paintChart(id, chartOption); + }, 100); + }, + genWord() { + let imgUrls = this.charts.map((item) => { + return htmlTransfer.chartToImageUrl( + this.$echarts.getInstanceByDom(document.getElementById(item.id)) + ); + }); + + this.captureScreenshot().then((item) => { + const month = dayjs(new Date()).month() + 1; + const day = dayjs(new Date()).date(); + const data = { + title: this.title, + month: month, + day: day, + sceneTypeImg: imgUrls[0], + positionImg: imgUrls[1], + description: this.description, + tableData: this.tableData, + imgUrls: imgUrls + }; + const imgSize = { + imgUrl: [300, 350] + }; + htmlTransfer.ExportBriefDataDocx( + '.\\test.docx', // 妯℃澘璺緞 + data, // 鏁版嵁 + this.title, // 鏂囦欢鍚� + imgSize + ); + }); + }, + previewProduct() { + this.genWord(); + }, + // 绗竴闃舵纭畾涔嬪悗鐨勫洖璋� + selectProdStageOver(result) { + this.genDialog = false; + this.nextStep(); + if (result != null) { + this.formSearch._locations = result._locations; + this.formSearch._scenetypes = result._scenetype; + + this.$refs.dynamicTableRef.onSearch(); + } + }, + genSomeCharts() { + // 娣诲姞鍥捐〃 + this.charts = []; + this.showChart = true; + // 鐢熸垚鍖哄煙涓殑涓嬩竴绾х殑鍥捐〃 + const l = this.formSearch._locations; + console.log(this.tableData); + + let positionProp = ''; + if (l.pName != null) { + positionProp = 'cityname'; + if (l.cName != null) { + positionProp = 'districtname'; + if (l.dName != null) { + positionProp = 'townname'; + if (l.tName != null) { + positionProp = 'townname'; + } + } + } + } + [ + genChart.getChartByDataAndProp(this.tableData, 'type', '绫诲瀷', 'bar'), + genChart.getPieChartByDataAndProp( + this.tableData, + positionProp, + '鎵�灞炲尯鍩�' + ) + ].forEach((item) => { + let id = `chart${this.charts.length}`; + this.charts.push({ + id: id, + option: item + }); + setTimeout(() => { + this.paintChart(id, item); + }, 100); + }); + }, + getList(page) { + let promises = []; + if (this.formSearch._scenetypes == undefined) { + let obj = {}; + this.fillPosition(obj); + promises.push( + // sceneApi.searchScene(obj, page.currentPage, page.pageSize) + sceneApi.searchScene(obj, 1, 9999) + ); + this.addOnlineProp(); + this.addExistTopTask(); + return promises; + } else { + for ( + let index = 0; + index < this.formSearch._scenetypes.length; + index++ + ) { + const item = this.formSearch._scenetypes[index]; + let obj = { + // online: true + }; + this.fillPosition(obj); + obj.scensetypeid = item.value; + if (obj.scensetypeid == '0') obj.scensetypeid = null; + promises.push(sceneApi.searchScene(obj, 1, 9999)); + } + this.addOnlineProp(); + this.addExistTopTask(); + return promises; + } + }, + onSearch(page, func) { + this.searchLoading = true; + return Promise.all(this.getList(page)).then((results) => { + this.tableData = []; + + results.forEach((res) => { + if (res.success) { + res.data.forEach((item) => { + this.tableData.push(item); + }); + } + }); + this.addOnlineProp(); + this.addExistTopTask(); + this.genSomeCharts(); + this.searchLoading = false; + func({ + data: this.tableData + }); + }); + }, + fillPosition(area) { + const f = this.formSearch; + // 琛屾斂鍖哄垝 + area.provincecode = f._locations.pCode; + area.citycode = f._locations.cCode; + area.districtcode = f._locations.dCode; + area.towncode = f._locations.tCode; + }, + getArea(area) { + const f = this.formSearch; + // 鍦烘櫙绫诲瀷 + area.scensetypeid = f._scenetype.value; + if (area.scensetypeid == '0') area.scensetypeid = null; + // 涓婁笅绾跨姸鎬� + area.online = f.online.value; + // 鏌ヨ鍏抽敭瀛�(鍦烘櫙鍚嶇О) + area.sceneName = f.searchText; + }, + addOnlineProp() { + this.tableData.forEach( + (item) => (item._isOnline = item.extension1 == 1 ? '鏄�' : '鍚�') + ); + }, + addExistTopTask() { + taskApi.getTopTask().then((res) => { + const topTaskId = res[0].tguid; + taskApi.fetchMonitorObjectVersion(topTaskId).then((subTaskRes) => { + let alreadyExistTopTask = subTaskRes.map((item) => item.sguid); + this.noExistTopTaskNum = 0; + this.existTopTaskNum = 0; + this.tableData.forEach((e) => { + if (alreadyExistTopTask.indexOf(e.guid) == -1) { + e._isExistInTopTask = '涓嶅湪鐩戠璁″垝鍐�'; + } else { + e._isExistInTopTask = '鍦ㄧ洃绠¤鍒掑唴'; + } + }); + }); + }); + }, + genHeaders() { + this.tableConfig = [ + { + id: 1, + label: '缂栧彿', + prop: 'index', + width: '80', + disabled: true + }, + { + id: 2, + label: '鍚嶇О', + prop: 'name', + width: '400', + disabled: true + }, + { + id: 3, + label: '绫诲瀷', + prop: 'type', + width: '130', + sortable: true, + disabled: true + }, + { + id: 4, + label: '鐪�', + prop: 'provincename', + width: '90', + disabled: true + }, + { + id: 5, + label: '甯�', + prop: 'cityname', + width: '90', + disabled: true + }, + { + id: 6, + label: '鍖哄幙', + prop: 'districtname', + width: '90', + disabled: true + }, + { + id: 7, + label: '琛楅亾', + prop: 'townname', + width: '110', + disabled: true + }, + { + id: 8, + label: '鍦板潃', + prop: 'location', + width: '400', + disabled: true + }, + { + id: 9, + label: '缁忓害', + prop: 'longitude', + width: '110', + merge: 10, + title: '缁忕含搴�', + disabled: true + }, + { + id: 10, + label: '绾害', + prop: 'latitude', + width: '110', + merge: 9, + disabled: true + }, + { + id: 11, + label: '鑱旂郴浜�', + prop: 'contacts', + width: '110', + disabled: true + }, + { + id: 12, + label: '鑱旂郴鐢佃瘽', + prop: 'contactst', + width: '110', + disabled: true + }, + { + id: 13, + label: '澶囨敞', + prop: 'remark', + width: '110' + }, + { + id: 14, + label: '杩愯惀涓�', + prop: '_isOnline', + width: '110', + sortable: true, + disabled: true + }, + { + id: 15, + label: '鏄惁瀛樺湪浜庢�讳换鍔′腑', + prop: '_isExistInTopTask', + width: '110', + sortable: true, + disabled: true + } + ]; + } + } +}; +</script> +<style scoped> +.options { + display: flex; + padding: 5px; +} +.title-input { + margin-top: -20px; + border-radius: 6px; + color: #000; + width: 80%; + font-size: 1.5rem; + line-height: 5rem; + text-align: center; + border: none; +} +.center-div { + display: flex; + justify-content: center; +} +.btn-group { + /* background-color: rgb(32, 127, 211); */ + white-space: nowrap; +} +.chart { + margin-top: 5px; + margin-bottom: 2px; + width: 100%; + height: 500px; +} +.fixed-div-steps { + position: fixed; + top: 7%; + width: 100%; /* div 鐨勫搴� */ + background-color: #f2f2f200; /* 鑳屾櫙棰滆壊 */ + padding: 5px; + z-index: 1000; /* 纭繚 div 鍦ㄩ〉闈㈠叾浠栧唴瀹逛箣涓� */ +} +/* 鍥哄畾瀹氫綅鐨� div */ +.fixed-div { + position: fixed; + top: 7%; + right: 20px; /* 璺濈鍙充晶 20px */ + width: 'auto'; /* div 鐨勫搴� */ + background-color: #f2f2f200; /* 鑳屾櫙棰滆壊 */ + padding: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.11); /* 闃村奖鏁堟灉 */ + z-index: 1000; /* 纭繚 div 鍦ㄩ〉闈㈠叾浠栧唴瀹逛箣涓� */ +} +.charts { + display: flex; + flex-wrap: wrap; +} +.chart-item { + text-align: center; + width: 30%; +} +.product-item-margin { + margin-bottom: 5px; +} +.second-title { + color: var(--el-text-color-primary); + font-size: 16px; + font-weight: bold; + margin-bottom: 16px; +} +.main { + text-align: center; + width: 95%; +} +</style> diff --git a/src/views/fysp/data-product/ProdTreatmentDeviceInfo.vue b/src/views/fysp/data-product/ProdTreatmentDeviceInfo.vue new file mode 100644 index 0000000..1fefd21 --- /dev/null +++ b/src/views/fysp/data-product/ProdTreatmentDeviceInfo.vue @@ -0,0 +1,80 @@ +<template> + <el-col> + <el-row justify="end" class="fixed-div"> + <div class="btn-group"> + <el-button @click="genDialog = true" type="primary" + >浜у搧鐢熸垚閰嶇疆</el-button + > + <el-button type="primary" @click="chartDialog = true" + >鍥捐〃灞曠ず</el-button + > + <el-button type="primary" @click="previewProduct">瀵煎嚭</el-button> + </div> + </el-row> + </el-col> +</template> +<script> + +</script> +<style scoped> +.options { + display: flex; + padding: 5px; +} +.title-input { + margin-top: -20px; + border-radius: 6px; + color: #000; + width: 80%; + font-size: 1.5rem; + line-height: 5rem; + text-align: center; + border: none; +} +.center-div { + display: flex; + justify-content: center; +} +.btn-group { + /* background-color: rgb(32, 127, 211); */ + white-space: nowrap; +} +.chart { + margin-top: 5px; + margin-bottom: 2px; + width: 100%; + height: 500px; +} +/* 鍥哄畾瀹氫綅鐨� div */ +.fixed-div { + position: fixed; + top: 7%; + right: 20px; /* 璺濈鍙充晶 20px */ + width: 'auto'; /* div 鐨勫搴� */ + background-color: #f2f2f200; /* 鑳屾櫙棰滆壊 */ + padding: 5px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.11); /* 闃村奖鏁堟灉 */ + z-index: 1000; /* 纭繚 div 鍦ㄩ〉闈㈠叾浠栧唴瀹逛箣涓� */ +} +.charts { + display: flex; + flex-wrap: wrap; +} +.chart-item { + text-align: center; + width: 30%; +} +.product-item-margin { + margin-bottom: 5px; +} +.second-title { + color: var(--el-text-color-primary); + font-size: 16px; + font-weight: bold; + margin-bottom: 16px; +} +.main { + text-align: center; + width: 95%; +} +</style> diff --git a/src/views/fysp/data-product/components/ComSelectMonitorTaskProdStage.vue b/src/views/fysp/data-product/components/ComSelectMonitorTaskProdStage.vue new file mode 100644 index 0000000..de79056 --- /dev/null +++ b/src/views/fysp/data-product/components/ComSelectMonitorTaskProdStage.vue @@ -0,0 +1,143 @@ +<template> + <span class="second-title"> {{ `鍩烘湰淇℃伅` }} </span> + <el-form :inline="true"> + <FYOptionLocation + :allOption="false" + :level="4" + v-model:value="result._locations" + ></FYOptionLocation> + <MutiableOptionScene + :allOption="false" + :type="2" + :multiple="true" + :initValue="false" + v-model:value="result._scenetype" + ></MutiableOptionScene> + <!-- <el-form-item label="鏈堜唤瀵规瘮"> + <el-date-picker + v-model="result.months" + type="monthrange" + range-separator="-" + start-placeholder="Start month" + @change="onSelectedMonthsChange" + end-placeholder="End month" + /> + </el-form-item> --> + <el-form-item label="鎬讳换鍔�"> + <!-- <el-input v-model="formSearch.topTaskId" placeholder="鎬讳换鍔�" /> --> + <el-select + multiple + value-key="value" + v-model="result.topTasks" + placeholder="鎬讳换鍔�" + style="width: 320px; margin-left: 30px" + > + <el-option + v-for="s in topTasks" + :key="s.value" + :label="s.label" + :value="s" + /> + </el-select> + </el-form-item> + </el-form> + <el-divider /> + <span class="second-title"> {{ `閫夋嫨琛ㄦ牸涓渶瑕佸睍绀虹殑鍒椾俊鎭痐 }} </span> + <CompChangeHeaderTree :table-header="tableHeader" ref="changeHeaderRef"> + </CompChangeHeaderTree> + + <div class="center"> + <div> + <el-button type="primary" @click="ok">涓嬩竴姝�</el-button> + <el-button type="primary" @click="cancel">鍙栨秷</el-button> + </div> + </div> +</template> +<script> +import CompChangeHeaderTree from './CompChangeHeaderTree.vue'; +import MutiableOptionScene from './MutiableOptionScene.vue'; +import tableCol from '../js/tableCol'; +import taskApi from '@/api/fysp/taskApi.js'; +import dayjs from 'dayjs'; +export default { + mounted() { + this.getTopTasks(); + }, + props: { + tableHeader: { + type: Array, + default: () => [] + } + }, + components: { + MutiableOptionScene, + CompChangeHeaderTree + }, + data() { + return { + result: { + _locations: {}, + _scenetype: [], + topTasks: [], + months: [] + }, + topTasks: [] + }; + }, + methods: { + onSelectedMonthsChange(val) { + // let m1 = dayjs(val[0]).format("YYYY-MM") + // let m2 = dayjs(val[0]).format("YYYY-MM") + // function + // this.topTasks = this.topTasks.filter(item=>{ + // console.log("dayjs(new Date(item.starttime))", dayjs(item.starttime).format("YYYY-MM")); + // return dayjs(new Date(item.starttime)).format("YYYY-MM") == m1 || dayjs(item.starttime).format("YYYY-MM") == m2 + // }) + }, + getTopTasks() { + taskApi.getTopTask().then((res) => { + const list = res.map((r) => { + return { + value: r.tguid, + label: r.name, + data: r + }; + }); + this.topTasks = list; + // this.$refs.dynamicTableRef.onSearch(); + }); + }, + ok() { + let changedHeaders = this.$refs.changeHeaderRef.getChangedHeaders(); + let copy = this.tableHeader.map((item) => item); + let changedHeadeArray = tableCol.treeToArray(changedHeaders); + tableCol.treeToArray(copy).forEach((item) => { + for (let index = 0; index < changedHeadeArray.length; index++) { + const element = changedHeadeArray[index]; + if (element.id == item.id) { + item.hidden = element.hidden; + changedHeadeArray.splice(index, 1); + } + } + }); + this.result.topTasks = this.result.topTasks.map((item) => item.data); + this.$emit('next', this.result); + }, + cancel() { + this.$emit('next', null); + } + } +}; +</script> +<style scoped> +.center { + display: flex; + justify-content: center; +} +.second-title { + color: var(--el-text-color-primary); + font-size: 16px; + font-weight: bold; + margin-bottom: 16px; +} +</style> diff --git a/src/views/fysp/data-product/components/CompChangeHeaderTree.vue b/src/views/fysp/data-product/components/CompChangeHeaderTree.vue new file mode 100644 index 0000000..0085b2b --- /dev/null +++ b/src/views/fysp/data-product/components/CompChangeHeaderTree.vue @@ -0,0 +1,90 @@ +<template> + <!-- 鍒楀嚭琛ㄥご鐨勬爲鐘剁粨鏋� --> + <el-tree + class="tree" + ref="tree" + :props="headTreeProps" + :data="copyTableHeader" + node-key="id" + show-checkbox + :default-checked-keys="defaultCheckedKeys" + @check="check" + /> +</template> +<script> +import { useCloned } from '@vueuse/core'; +import tableCol from '../js/tableCol'; +export default { + computed: { + defaultCheckedKeys() { + if (this.copyTableHeader.length == 0) { + this.tableHeaderCopy() + } + let result = this.collectLabels(this.copyTableHeader); + console.log("resultsss", result); + + return result + } + }, + mounted() { + this.tableHeaderCopy() + }, + data() { + return { + copyTableHeader: [], + headTreeProps: { + children: 'children', + label: 'label', + disabled: 'disabled' + } + }; + }, + props: { + // 澶氱骇琛ㄥご鐨勬暟鎹� + tableHeader: { + type: Array, + required: true + } + }, + methods: { + getChangedHeaders() { + return this.copyTableHeader + }, + tableHeaderCopy() { + this.copyTableHeader = useCloned(this.tableHeader).cloned.value + }, + collectLabels(nodes) { + let labels = []; + + function traverseNodes(nodes) { + nodes.forEach((node) => { + if (!('hidden' in node) || !node.hidden) { + labels.push(node.id); + } + + // 濡傛灉褰撳墠鑺傜偣鏈夊瓙鑺傜偣锛岄�掑綊璋冪敤閬嶅巻鍑芥暟 + if (node.children && node.children.length > 0) { + traverseNodes(node.children); + } + }); + } + + traverseNodes(nodes); // 寮�濮嬮�掑綊閬嶅巻 + + return labels; // 杩斿洖鏀堕泦鍒扮殑 labels 鏁扮粍 + }, + check(checkedNode, checkedKeys, halfCheckedNodes, halfCheckedKeys) { + checkedNode.hidden = !checkedNode.hidden; + this.$refs.tree.updateKeyChildren(checkedNode.id, checkedNode); + }, + } +}; +</script> +<style scoped> +.tree { + margin-left: -16.5px; + display: flex !important; + width: 100% !important; + flex-flow: row wrap !important; +} +</style> diff --git a/src/views/fysp/data-product/components/CompGooderProdStage,.vue b/src/views/fysp/data-product/components/CompGooderProdStage,.vue new file mode 100644 index 0000000..9aa9c12 --- /dev/null +++ b/src/views/fysp/data-product/components/CompGooderProdStage,.vue @@ -0,0 +1,106 @@ +<template> + <div class="gooderstage-center-div"> + <el-transfer + :titles="['鍙悎骞跺垪', '宸查�変腑']" + v-model="selected" + :props="{ + key: 'id', + label: 'label' + }" + :data="data" + /> + <el-button @click="ok" type="primary" class="ok-style">涓嬩竴姝�</el-button> + </div> +</template> +<script> +export default { + props: { + tableHeader: { + type: Array, + default: () => [] + } + }, + mounted() { + this.initData(); + }, + data() { + return { + data: [], + selected: [] + }; + }, + methods: { + ok() { + this.$emit( + 'selected-gooder', + this.data.filter((item) => this.selected.indexOf(item.id) != -1) + ); + }, + initData() { + let obj = this.processElements(this.tableHeader); + this.selected = obj.mergedElements; + this.data = obj.canMergePairs; + }, + processElements(elements) { + const canMergePairs = []; + const mergedElements = []; + const seenPairs = new Set(); // 鐢ㄤ簬璺熻釜宸插鐞嗙殑 ID 瀵� + + // 鍒涘缓涓�涓敤浜庢煡鎵惧厓绱犵殑鏄犲皠锛屼互渚挎牴鎹� ID 蹇�熻闂� + const elementMap = new Map(elements.map((el) => [el.id, el])); + + for (const element of elements) { + // 妫�鏌ユ槸鍚︽湁 merge 灞炴�� + if (element.merge) { + const targetElement = elementMap.get(element.merge); + if (targetElement) { + // 鎵惧埌鐩爣鍏冪礌锛岀敓鎴愭柊鐨勫悎骞跺 + const id1 = element.id; + const id2 = targetElement.id; + const prop1 = element.prop; + const prop2 = targetElement.prop; + const smallerId = Math.min(id1, id2); + const largerId = Math.max(id1, id2); + const title = element.prop + targetElement.prop; + + // 鍒涘缓涓�涓敮涓�鐨� ID 瀵癸紝纭繚涓嶄細閲嶅 + const pairKey = `${smallerId}-${largerId}`; + if (!seenPairs.has(pairKey)) { + canMergePairs.push({ + id1, + id2, + prop1, + prop2, + id: smallerId, + label: `${element.label}/${targetElement.label}`, + prop: title, + merged: false + // children: [element, targetElement] + }); + seenPairs.add(pairKey); // 鏍囪涓哄凡澶勭悊 + } + } + // 灏嗗綋鍓嶅厓绱犳爣璁颁负宸插悎骞� + if (element.merged) { + mergedElements.push(element); + } + } + } + + return { canMergePairs, mergedElements }; + }, + getSelected() { + return this.selected; + } + } +}; +</script> +<style scoped> +.gooderstage-center-div { + display: block; + text-align: center; +} +.ok-style { + margin-top: 2px; +} +</style> diff --git a/src/views/fysp/data-product/components/CompPreviewProd.vue b/src/views/fysp/data-product/components/CompPreviewProd.vue new file mode 100644 index 0000000..788fc3f --- /dev/null +++ b/src/views/fysp/data-product/components/CompPreviewProd.vue @@ -0,0 +1,14 @@ +<template> + <div></div> +</template> +<script> +import { saveAs } from 'file-saver'; +export default { + methods: { + exportToWord() { + + } + } +}; +</script> +<style scoped></style> diff --git a/src/views/fysp/data-product/components/CompProdGenMonitorInfoDescription.vue b/src/views/fysp/data-product/components/CompProdGenMonitorInfoDescription.vue new file mode 100644 index 0000000..3841fd2 --- /dev/null +++ b/src/views/fysp/data-product/components/CompProdGenMonitorInfoDescription.vue @@ -0,0 +1,109 @@ +<template> + <span class="description"> {{ description }} </span> +</template> +<script> +import dayjs from 'dayjs'; +export default { + watch: { + tableData: { + handler(nv, ov) { + this.buildDescription() + }, + deep: true, + immediate: true + } + }, + methods: { + // 娈甸 + startStr() { + return `${' '}`; + }, + // 娈靛熬 + endStr() { + return '銆�'; + }, + buildMonitorNum() { + let str = ''; + str += this.startStr(); + str += `褰撳墠娓呭崟鍖呮嫭${this.tableData.length}涓洃绠′换鍔; + str += this.endStr(); + return str; + }, + buildTopTaskNum() { + let topNames = Array.from(new Set(this.tableData.map((item) => item._topTask.name))) + let str = ''; + str += this.startStr(); + str += `鏈堝害浠诲姟鏈�${ + topNames.length + }涓紝鍒嗗埆涓�${topNames.join(',')}`; + str += this.endStr(); + return str; + }, + buildScene() { + let scenes = Array.from(new Set(this.tableData.map(item=>item.sceneType))) + let str = ''; + str += this.startStr(); + str += `鎬诲叡${scenes.length}涓満鏅紝`; + str += `鍖呮嫭${scenes.join('锛�')}鍦烘櫙`; + str += this.endStr(); + return str; + }, + buildDescription() { + let result = ''; + // 鐩戠浠诲姟鏁伴噺 + result += this.buildMonitorNum(); + // 娑夊強澶氬皯鎬讳换鍔� + result += this.buildTopTaskNum(); + // 鍦烘櫙涓暟鍜岀被鍨� + result += this.buildScene(); + this.description = result + }, + }, + computed: { + locationStr() { + let result = ''; + if (this.location.pName) { + // result += this.location.pName; + if (this.location.cName) { + result += this.location.cName; + if (this.location.dName) { + result += this.location.dName; + if (this.location.tName) { + result += this.location.tName; + } + } + } + } + if (result == '') { + if (this.location.pName) { + result += this.location.pName; + } + } + return result; + }, + time() { + if (!this.tableData || this.tableData.length == 0) { + return ''; + } else { + return dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'); + } + } + }, + props: { + location: {}, + tableData: [] + }, + data() { + return { + description: '' + }; + } +}; +</script> +<style scoped> +.description { + display: block; + /* white-space: pre-line; */ + width: 100%; +} +</style> diff --git a/src/views/fysp/data-product/components/CompProdGenScenseDescription.vue b/src/views/fysp/data-product/components/CompProdGenScenseDescription.vue new file mode 100644 index 0000000..b9d17cf --- /dev/null +++ b/src/views/fysp/data-product/components/CompProdGenScenseDescription.vue @@ -0,0 +1,286 @@ +<template> + <!-- <el-descriptions :column="2" size="default" border> + <el-descriptions-item label="鍖哄煙"> + {{ locationStr }} + </el-descriptions-item> + <el-descriptions-item label="鏃堕棿"> {{ time }} </el-descriptions-item> + <el-descriptions-item label="鎻忚堪"> + <span class="description"> {{ description }} </span> + </el-descriptions-item> + </el-descriptions> --> + <span class="description"> {{ description }} </span> +</template> +<script> +import taskApi from '@/api/fysp/taskApi.js'; +import dayjs from 'dayjs'; +export default { + watch: { + tableData: { + handler(nv, ov) { + if (nv == null || nv.length == 0) { + this.init() + return; + } + this.countScenseNum(); + this.countTownScenses(); + this.countTown(); + this.countExistTopTask(); + this.countOnline(); + }, + deep: true, + immediate: true + } + }, + props: { + location: {}, + tableData: [] + }, + computed: { + time() { + if (!this.tableData || this.tableData.length == 0) { + return ''; + } else { + return dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'); + } + }, + locationStr() { + let result = ''; + if (this.location.pName) { + // result += this.location.pName; + if (this.location.cName) { + result += this.location.cName; + if (this.location.dName) { + result += this.location.dName; + if (this.location.tName) { + result += this.location.tName; + } + } + } + } + if (result == '') { + if (this.location.pName) { + result += this.location.pName; + } + } + return result; + }, + description() { + let result = ''; + if (!this.tableData || this.tableData.length == 0) { + return result; + } + // result += `${this.startStr()}褰撳墠娓呭崟鍖呮嫭`; + result += this.startStr() + result += `褰撳墠鍦烘櫙娓呭崟鍖呮嫭`; + result += this.scenses.map((item) => item.type).join(',') + '鍦烘櫙绫诲瀷锛�'; + result += `鎬昏${this.scenseNum}绉嶅満鏅痐; + result += this.endStr(); + result += `${ + Array.from(new Set(this.tableData.map((item) => item.townname))).length + }涓閬擄紝`; + // 鍦烘櫙鍒嗗竷 + result = this.buildTownScenses(result); + result = this.buildScenseDistribution(result); + result = this.buildOnline(result); + result = this.buildExistTopTask(result); + this.$emit('generated-description', result); + return result; + } + }, + data() { + return { + scenseNum: 0, + scenses: [], + towns: [ + // { + // name: '', + // scense: 0 + // } + ], + townScenses: [], + existTopTaskNum: 0, + noExistTopTaskNum: 0, + online: 0, + noOnline: 0 + }; + }, + mounted() { + this.countScenseNum(); + this.countTown(); + this.countOnline(); + this.countExistTopTask(); + }, + methods: { + // 娈甸 + startStr() { + return `${' '}`; + }, + // 娈靛熬 + endStr() { + return '銆�'; + }, + init() { + this.scenseNum = 0, + this.scenses = [], + this.towns = [ + // { + // name: '', + // scense: 0 + // } + ], + this.townScenses = [], + this.existTopTaskNum = 0, + this.noExistTopTaskNum = 0, + this.online = 0, + this.noOnline = 0 + }, + countTownScenses() { + this.townScenses = []; + const groupedData = this.tableData.reduce((acc, current) => { + if (!acc[current.townname]) { + acc[current.townname] = { + type: [current.type] + }; + } + if (acc[current.townname].type.indexOf(current.type) == -1) { + acc[current.townname].type.push(current.type); + } + return acc; + }, {}); + for (const prop in groupedData) { + this.townScenses.push({ + name: prop, + types: groupedData[prop].type + }); + } + }, + buildTownScenses(result) { + // result += this.startStr() + for (let index = 0; index < this.townScenses.length; index++) { + const item = this.townScenses[index]; + if (index == 0) { + result += `${item.name}${item.types.length}绉嶅満鏅�(${item.types.join( + '锛�' + )})`; + } else { + result += `锛�${item.name}${item.types.length}绉嶅満鏅�(${item.types.join( + '锛�' + )})`; + } + } + result += this.endStr(); + return result; + }, + getDescription() { + let obj = { + description: this.description, + location: this.locationStr, + time: this.time + }; + return obj; + }, + buildOnline(result) { + // result += this.startStr() + result += + `鍦ㄧ嚎鏁伴噺${this.online}涓紝涓嬬嚎鏁伴噺${this.noOnline}涓猔 + this.endStr(); + return result; + }, + // 鏄惁鍦ㄧ洃绠′换鍔′腑 + buildExistTopTask(result) { + // result += this.startStr() + result += + `鍦ㄧ嚎鐨�${this.online}涓満鏅腑${this.existTopTaskNum}涓満鏅湪鐩戠浠诲姟涓紝${this.noExistTopTaskNum}涓満鏅笉鍦ㄧ洃绠′换鍔′腑` + + this.endStr(); + return result; + }, + // 鍦烘櫙鍒嗗竷 + buildScenseDistribution(result) { + // result += this.startStr() + + result += `${this.tableData.length}涓満鏅紝`; + for (let index = 0; index < this.towns.length; index++) { + const item = this.towns[index]; + if (index == 0) { + result += `${item.name}${item.town}涓猔; + } else { + result += `锛�${item.name}${item.town}涓猔; + } + } + result += this.endStr(); + return result; + }, + // 鏄惁鍦ㄧ嚎 + countOnline() { + this.online = this.tableData.filter( + (item) => item.extension1 == 1 + ).length; + this.noOnline = this.tableData.filter( + (item) => item.extension1 != 1 + ).length; + }, + countExistTopTask() { + taskApi.getTopTask().then((res) => { + const topTaskId = res[0].tguid; + taskApi.fetchMonitorObjectVersion(topTaskId).then((subTaskRes) => { + let alreadyExistTopTask = subTaskRes.map((item) => item.sguid); + this.noExistTopTaskNum = 0; + this.existTopTaskNum = 0; + this.tableData + .filter((item) => item.extension1 == 1) + .forEach((e) => { + if (alreadyExistTopTask.indexOf(e.guid) == -1) { + e._isExistInTopTask = '涓嶅湪鐩戠璁″垝鍐�'; + this.noExistTopTaskNum++; + } else { + e._isExistInTopTask = '鍦ㄧ洃绠¤鍒掑唴'; + this.existTopTaskNum++; + } + }); + }); + }); + }, + countScenseNum() { + this.scenses = []; + let scenseIds = this.scenses.map((item) => item.typeid); + this.tableData.forEach((item) => { + if (scenseIds.indexOf(item.typeid) == -1) { + this.scenses.push(item); + scenseIds.push(item.typeid); + } + }); + this.scenseNum = scenseIds.length; + }, + countTown() { + this.towns = []; + + const groupedData = this.tableData.reduce((acc, current) => { + if (!acc[current.type]) { + acc[current.type] = { + name: current.type, + town: 1 + }; + } + let town = { + name: current.type, + town: acc[current.type].town + 1 + }; + acc[current.type] = town; + return acc; + }, {}); + for (const prop in groupedData) { + this.towns.push({ + name: prop, + town: groupedData[prop].town + }); + } + } + } +}; +</script> +<style scoped> +.description { + display: block; + white-space: pre-wrap; + width: 100%; +} +</style> diff --git a/src/views/fysp/data-product/components/CompProdSteps.vue b/src/views/fysp/data-product/components/CompProdSteps.vue new file mode 100644 index 0000000..e8e319c --- /dev/null +++ b/src/views/fysp/data-product/components/CompProdSteps.vue @@ -0,0 +1,9 @@ +<template> + <div></div> +</template> +<script> + +</script> +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/fysp/data-product/components/CompProdTreatmentDeviceDescription.vue b/src/views/fysp/data-product/components/CompProdTreatmentDeviceDescription.vue new file mode 100644 index 0000000..afb33ba --- /dev/null +++ b/src/views/fysp/data-product/components/CompProdTreatmentDeviceDescription.vue @@ -0,0 +1,61 @@ +<template> + <el-descriptions :column="2" size="default" border> + <el-descriptions-item label="鍖哄煙"> + {{ locationStr }} + </el-descriptions-item> + <el-descriptions-item label="鏃堕棿"> {{ time }} </el-descriptions-item> + <el-descriptions-item label="鎻忚堪"> + <span class="description"> {{ description }} </span> + </el-descriptions-item> + </el-descriptions> + </template> + <script> + import dayjs from 'dayjs'; + export default { + computed: { + description() { + let result = '' + return result + }, + locationStr() { + let result = ''; + if (this.location.pName) { + // result += this.location.pName; + if (this.location.cName) { + result += this.location.cName; + if (this.location.dName) { + result += this.location.dName; + if (this.location.tName) { + result += this.location.tName; + } + } + } + } + if (result == '') { + if (this.location.pName) { + result += this.location.pName; + } + } + return result; + }, + time() { + if (!this.tableData || this.tableData.length == 0) { + return ''; + } else { + return dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'); + } + } + }, + props: { + location: {}, + tableData: [] + }, + data() { + return { + description: '' + }; + } + }; + </script> + <style scoped></style> + \ No newline at end of file diff --git a/src/views/fysp/data-product/components/CompSelectProdStage.vue b/src/views/fysp/data-product/components/CompSelectProdStage.vue new file mode 100644 index 0000000..1c2a50c --- /dev/null +++ b/src/views/fysp/data-product/components/CompSelectProdStage.vue @@ -0,0 +1,85 @@ +<template> + <span class="second-title"> {{ `鍩烘湰淇℃伅` }} </span> + <el-form :inline="true"> + <FYOptionLocation + :allOption="false" + :level="4" + v-model:value="result._locations" + ></FYOptionLocation> + <MutiableOptionScene + :allOption="false" + :type="2" + :multiple="true" + :initValue="false" + v-model:value="result._scenetype" + ></MutiableOptionScene> + </el-form> + <el-divider /> + <span class="second-title"> {{ `閫夋嫨琛ㄦ牸涓渶瑕佸睍绀虹殑鍒椾俊鎭痐 }} </span> + <CompChangeHeaderTree :table-header="tableHeader" ref="changeHeaderRef"> </CompChangeHeaderTree> + + <div class="center"> + <div> + <el-button type="primary" @click="ok">涓嬩竴姝�</el-button> + <el-button type="primary" @click="cancel">鍙栨秷</el-button> + </div> + </div> +</template> +<script> +import CompChangeHeaderTree from './CompChangeHeaderTree.vue'; +import MutiableOptionScene from './MutiableOptionScene.vue'; +import tableCol from '../js/tableCol'; +export default { + mounted() {}, + props: { + tableHeader: { + type: Array, + default: () => [] + } + }, + components: { + MutiableOptionScene, + CompChangeHeaderTree + }, + data() { + return { + result: { + _locations: {}, + _scenetype: [] + } + }; + }, + methods: { + ok() { + let changedHeaders = this.$refs.changeHeaderRef.getChangedHeaders() + let copy = this.tableHeader.map(item=>item) + let changedHeadeArray = tableCol.treeToArray(changedHeaders) + tableCol.treeToArray(copy).forEach(item=>{ + for (let index = 0; index < changedHeadeArray.length; index++) { + const element = changedHeadeArray[index]; + if (element.id == item.id) { + item.hidden = element.hidden + changedHeadeArray.splice(index, 1) + } + } + }) + this.$emit('next', this.result); + }, + cancel() { + this.$emit('next', null); + } + } +}; +</script> +<style scoped> +.center { + display: flex; + justify-content: center; +} +.second-title { + color: var(--el-text-color-primary); + font-size: 16px; + font-weight: bold; + margin-bottom: 16px; +} +</style> diff --git a/src/views/fysp/data-product/components/CompShowEChart.vue b/src/views/fysp/data-product/components/CompShowEChart.vue new file mode 100644 index 0000000..78fa25a --- /dev/null +++ b/src/views/fysp/data-product/components/CompShowEChart.vue @@ -0,0 +1,211 @@ +<template> + <!-- 閫夐」 --> + <div class="options"> + <el-form :inline="true"> + <!-- <el-form-item> + <el-option + v-model="charType" + v-for="type of charTypeOptions" + :key="type" + :value="type" + :label="type" + ></el-option> + </el-form-item> --> + <el-form-item> + <el-select + v-model="charType" + style="width: 150px" + placeholder="璇烽�夋嫨鍥捐〃绫诲瀷" + > + <el-option + v-for="item in charTypeOptions" + :key="item.value" + :value="item.value" + :label="item.label" + ></el-option> + </el-select> + </el-form-item> + <el-form-item> + <el-select + v-model="selectHeader" + style="width: 200px" + @change="onSelectHeaderChange" + value-key="id" + placeholder="璇烽�夋嫨灞曠ず鐨勫垪" + > + <el-option + v-for="item in allHeader" + :key="item.id" + :value="item" + :label="item.label" + ></el-option> + </el-select> + </el-form-item> + </el-form> + </div> + <div ref="myChart" id="myChart" class="chart"></div> + <el-button type="primary" @click="ok()">纭畾</el-button> +</template> +<script> +export default { + props: { + tableHeader: { + type: Array, + required: true + }, + tableData: { + type: Array, + required: true + } + }, + computed: { + allHeader() { + return this.treeToArray(this.tableHeader); + } + }, + data() { + return { + selectHeader: null, + charType: null, + charTypeOptions: [ + { + label: '鐩存柟鍥�', + value: 'bar' + }, + { + label: '鎶樼嚎鍥�', + value: 'line' + }, + { + label: '楗煎浘', + value: 'pie' + } + ], + + charts: [], + chart: {} + }; + }, + mounted() { + // this.setChartOptions('myChart', this.header.prop, this.header.label); + // this.selectHeader = this.tableHeader[0] + }, + methods: { + getChartObj() { + return this.chart; + }, + ok() { + let option = this.setChartOptions( + 'myChart', + this.selectHeader.prop, + this.selectHeader.label + ); + this.$emit('painted-chart', option); + }, + onSelectHeaderChange() { + this.setChartOptions( + 'myChart', + this.selectHeader.prop, + this.selectHeader.label + ); + }, + // 閫掑綊鐨勮幏鍙杘bj涓殑prop灞炴�� + getPropValueLoop(obj, prop) { + if (typeof prop !== 'string') { + return obj; + } + const props = prop.split('.'); + let result = obj; + props.forEach((item) => { + result = result[item]; + }); + return result; + }, + addChart(ref) {}, + setChartOptions(refName, prop, label) { + let series = this.tableData.map((item) => + this.getPropValueLoop(item, prop) + ); + + const dom = this.$refs[refName]; + const myChart = this.$echarts.init(dom); // 鍒濆鍖杄charts瀹炰緥 + this.chart = myChart; + const option = { + title: { + text: label //璁剧疆鎴戜滑鐨勬爣棰� + }, + tooltip: { + trigger: 'item' + }, + legend: { + orient: 'vertical', + left: 'left' + }, + xAxis: { + type: 'category', + data: Array.from(new Set(series)), + axisLabel: { + rotate: 45, // 鏃嬭浆鏍囩锛岄伩鍏嶉噸鍙� + // 鎴栬�� + interval: 0 // 鏄剧ず鎵�鏈夋爣绛撅紝鍙兘瀵艰嚧閲嶅彔锛屾牴鎹渶姹傝皟鏁� + } + }, + yAxis: { + type: 'value' + }, + series: [ + { + data: Array.from(new Set(series)).map((item) => + this.getCount(series, item) + ), + type: this.charType, + smooth: true + } + ] + }; + // 璁剧疆瀹炰緥鍙傛暟 + myChart.setOption(option); + return option; + }, + + getCount(array, element) { + let count = 0; + array.forEach((e) => { + if (e == element) { + count++; + } + }); + return count; + }, + treeToArray(nodes) { + let labels = []; + + function traverseNodes(nodes) { + nodes.forEach((node) => { + labels.push(node); + + // 濡傛灉褰撳墠鑺傜偣鏈夊瓙鑺傜偣锛岄�掑綊璋冪敤閬嶅巻鍑芥暟 + if (node.children && node.children.length > 0) { + traverseNodes(node.children); + } + }); + } + + traverseNodes(nodes); // 寮�濮嬮�掑綊閬嶅巻 + + return labels; // 杩斿洖鏀堕泦鍒扮殑 labels 鏁扮粍 + } + } +}; +</script> +<style scoped> +.options { + display: flex; + margin: 5px; + margin-left: 0px; +} +.chart { + width: 'auto'; + height: 500px; +} +</style> diff --git a/src/views/fysp/data-product/components/DynamicTable.vue b/src/views/fysp/data-product/components/DynamicTable.vue new file mode 100644 index 0000000..601fb71 --- /dev/null +++ b/src/views/fysp/data-product/components/DynamicTable.vue @@ -0,0 +1,246 @@ +<template> + <!-- 淇敼琛ㄥご --> + <el-col> + <el-row justify="end" class="btn-group"> + <el-popover placement="bottom" :width="400" trigger="click"> + <template #reference> + <!-- <el-button type="primary">琛ㄥご淇敼</el-button> --> + </template> + <!-- 鍒楀嚭琛ㄥご鐨勬爲鐘剁粨鏋� --> + <el-tree + ref="tree" + :props="headTreeProps" + :data="tableHeader" + node-key="id" + show-checkbox + :default-checked-keys="defaultCheckedKeys" + @check="check" + /> + </el-popover> + <!-- <el-button type="primary" @click="openChart">鍥捐〃灞曠ず</el-button> --> + </el-row> + </el-col> + + <el-table + :data="tableData" + border + :header-cell-style="headerStyle" + :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" + row-key="id" + lazy + max-height="60vh" + v-loading="loading" + ref="tableRef" + > + <template v-for="item in tableHeader.filter((item) => !item.hidden)"> + <table-column + v-if="item.children && item.children.length" + :key="item.id" + :coloumn-header="item" + ></table-column> + <el-table-column + v-else + :key="item.id + 'else'" + :label="item.label" + :prop="item.prop" + align="center" + :min-width="item.width ? item.width : '200px'" + :sortable="item.sortable == undefined ? false : item.sortable" + > + <!-- <template #header> + {{ item.label }} + <el-button type="primary" @click="hidden(item)">闅愯棌</el-button> + </template> --> + </el-table-column> + </template> + </el-table> + <el-pagination + v-if="pagination" + ref="paginationRef" + class="el-pagination" + v-model:current-page="currentPage" + v-model:page-size="pageSize" + :page-sizes="[10, 20, 50, 100]" + :background="true" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + /> + + <el-dialog title="鍥捐〃灞曠ず" v-model="chartDialog" destroy-on-close> + <CompShowEChart :table-data="tableData" :table-header="tableHeader"> + </CompShowEChart> + </el-dialog> +</template> + +<script> +import CompShowEChart from './CompShowEChart.vue'; +import TableColumn from './TableColumn.vue'; +import tableCol from '../js/tableCol'; +export default { + components: { + TableColumn, + CompShowEChart + }, + mounted() { + // this.onSearch(); + }, + watch: { + currentPage(nValue, oValue) { + if (nValue != oValue) { + this.onSearch(); + } + }, + pageSize(nValue, oValue) { + if (nValue != oValue) { + this.onSearch(); + } + } + }, + computed: { + defaultCheckedKeys() { + return this.collectLabels(this.tableHeader); + } + }, + data() { + return { + total: 0, + currentPage: 1, + pageSize: 20, + tableData: [], + + chartDialog: false, + char1: {}, + headTreeProps: { + children: 'children', + label: 'label', + disabled: 'noncloseable' + } + }; + }, + props: { + // 琛ㄦ牸鐨勬暟鎹� + // tableData: { + // type: Array, + // required: true + // }, + pagination: { + type: Boolean, + default: false + }, + // 澶氱骇琛ㄥご鐨勬暟鎹� + tableHeader: { + type: Array, + required: true + } + }, + methods: { + // @Description: 璁剧疆琛ㄥご鏍峰紡 + headerStyle({ row, rowIndex, columnIndex }) { + if (row[columnIndex].order != '' && row[columnIndex].order != null) { + return { 'background-color': '#F56C6C', 'color': '#000000' }; + } + return {} + }, + // 鏂规硶涓嶈嚜鍔ㄨЕ鍙戯紝鐢辩埗缁勪欢涓诲姩璋冪敤鑾峰彇鍒楄〃鏁版嵁 + onSearch() { + this.loading = true; + this.$emit( + 'search', + { + currentPage: this.currentPage, + pageSize: this.pageSize + }, + (res) => { + this.tableData = res.data; + this.total = res.total ? res.total : 0; + this.loading = false; + // this.doLayout(); + } + ); + }, + doLayout() { + this.$refs.tableRef.doLayout(); + }, + openChart() { + this.chartDialog = true; + }, + check(checkedNode, checkedKeys, halfCheckedNodes, halfCheckedKeys) { + checkedNode.hidden = !checkedNode.hidden; + this.treeToArray(this.tableHeader).map((item) => { + if (item.hidden) { + console.log('闅愯棌', item.id); + this.$refs.tree.setCheckedKeys([item.id], false); + } else { + console.log('鏄剧ず', item.id); + this.$refs.tree.setCheckedKeys([item.id], true); + } + }); + }, + load(tree, treeNode, resolve) { + this.$emit('load', tree, treeNode, resolve); + }, + hidden(header) { + header.hidden = true; + }, + collectLabels(nodes) { + let labels = []; + + function traverseNodes(nodes) { + nodes.forEach((node) => { + if (!('hidden' in node) || !node.hidden) { + labels.push(node.id); + } + + // 濡傛灉褰撳墠鑺傜偣鏈夊瓙鑺傜偣锛岄�掑綊璋冪敤閬嶅巻鍑芥暟 + if (node.children && node.children.length > 0) { + traverseNodes(node.children); + } + }); + } + + traverseNodes(nodes); // 寮�濮嬮�掑綊閬嶅巻 + + return labels; // 杩斿洖鏀堕泦鍒扮殑 labels 鏁扮粍 + }, + treeToArray(nodes) { + let labels = []; + + function traverseNodes(nodes) { + nodes.forEach((node) => { + labels.push(node); + + // 濡傛灉褰撳墠鑺傜偣鏈夊瓙鑺傜偣锛岄�掑綊璋冪敤閬嶅巻鍑芥暟 + if (node.children && node.children.length > 0) { + traverseNodes(node.children); + } + }); + } + + traverseNodes(nodes); // 寮�濮嬮�掑綊閬嶅巻 + + return labels; // 杩斿洖鏀堕泦鍒扮殑 labels 鏁扮粍 + } + } +}; +</script> + +<style scoped> +.btns { + display: flex; + margin: 5px; + margin-left: 0px; +} +.el-pagination { + background-color: var(--el-color-white); + padding-top: 20px; + border-top: 1px solid rgba(0, 0, 0, 0.096); + /* margin-top: 2px; */ +} +.btn-group { + /* background-color: rgb(32, 127, 211); */ + white-space: nowrap; +} +.table-cell-red { + background-color: rgb(196, 23, 23); +} +</style> diff --git a/src/views/fysp/data-product/components/MutiableOptionScene.vue b/src/views/fysp/data-product/components/MutiableOptionScene.vue new file mode 100644 index 0000000..6d3dd8d --- /dev/null +++ b/src/views/fysp/data-product/components/MutiableOptionScene.vue @@ -0,0 +1,84 @@ +<template> + <el-form-item label="鍦烘櫙绫诲瀷" :prop="prop"> + <el-select + :model-value="value" + @change="handleChange" + placeholder="鍦烘櫙绫诲瀷" + style="width: 350px" + :multiple="multiple" + > + <el-option + v-for="s in sceneTypes" + :key="s.value" + :label="s.label" + :value="s" + /> + </el-select> + </el-form-item> +</template> + +<script> +import { enumScene } from '@/enum/scene'; + +export default { + props: { + // 鏄惁鍙互澶氶�� + multiple: { + type: Boolean, + default: false + }, + // 鏄惁鍦ㄩ閫夐」澶勬坊鍔犫�滃叏閮ㄢ�濋�夐」 + allOption: { + type: Boolean, + default: true + }, + // 1:椋炵窘鐜绯荤粺锛�2锛氶缇界洃绠$郴缁燂紱 + type: { + type: Number || String, + default: 1 + }, + // 杩斿洖缁撴灉 + value: Object, + // 鏄惁榛樿杩斿洖鍒濆閫夐」 + initValue: { + type: Boolean, + default: true + }, + // form琛ㄥ崟缁戝畾灞炴�у悕 + prop: { + type: String, + default: '_scenetype' + }, + // 鍒囨崲 type 鍚庯紝褰撳墠閫夐」鏄惁娓呯┖ + sourceInit: { + type: Boolean, + default: true + } + }, + emits: ['update:value'], + data() { + return { + // sceneTypes: enumScene(this.type, this.allOption), + }; + }, + computed: { + sceneTypes() { + if (this.sourceInit) { + // 褰撳洜涓簍ype鎴栬�卆llOption鍙傛暟鍙樺寲寮曡捣閫夐」鍙樻洿鏃讹紝娓呯┖褰撳墠閫夐」 + this.handleChange(); + } + return enumScene(this.type, this.allOption); + } + }, + methods: { + handleChange(value) { + this.$emit('update:value', value); + } + }, + mounted() { + if (this.initValue) { + this.handleChange(this.sceneTypes[0]); + } + } +}; +</script> diff --git a/src/views/fysp/data-product/components/OptionChartProd.vue b/src/views/fysp/data-product/components/OptionChartProd.vue new file mode 100644 index 0000000..a83946e --- /dev/null +++ b/src/views/fysp/data-product/components/OptionChartProd.vue @@ -0,0 +1,47 @@ +<template> + <el-form-item> + <el-select + :model-value="value" + style="width: 150px" + placeholder="璇烽�夋嫨鍥捐〃绫诲瀷" + :multiple="multiple" + > + <el-option + v-for="item in charTypeOptions" + :key="item.value" + :value="item.value" + :label="item.label" + ></el-option> + </el-select> + </el-form-item> +</template> +<script> +export default { + methods: { + }, + props: { + // 缁撴灉杩斿洖 + value: Object, + // 鏄惁澶氶�� + multiple: { + type: Boolean, + default: false + } + }, + data() { + return { + charTypeOptions: [ + { + label: '鐩存柟鍥�', + value: 'bar' + }, + { + label: '鎶樼嚎鍥�', + value: 'line' + } + ] + }; + } +}; +</script> +<style scoped></style> diff --git a/src/views/fysp/data-product/components/TableColumn.vue b/src/views/fysp/data-product/components/TableColumn.vue new file mode 100644 index 0000000..c25bfa7 --- /dev/null +++ b/src/views/fysp/data-product/components/TableColumn.vue @@ -0,0 +1,71 @@ +<template> + <el-table-column + :label="coloumnHeader.label" + :prop="coloumnHeader.label" + show-overflow-tooltip + align="center" + :min-width="coloumnHeader.width ? coloumnHeader.width : '200px'" + :sortable=" + coloumnHeader.sortable == undefined ? false : coloumnHeader.sortable + " + > + <!-- <template #header> + {{ coloumnHeader.label }} + <el-button type="primary" @click="hidden1">闅愯棌</el-button> + </template> --> + <template + v-for="item in coloumnHeader.children.filter((item) => !item.hidden)" + > + <tableColumn + v-if="item.children && item.children.length" + :key="item.id" + :coloumn-header="item" + > + </tableColumn> + <el-table-column + v-else + :key="item.name" + :label="item.label" + :prop="item.prop" + align="center" + :min-width="item.width ? item.width : '200px'" + :sortable="item.sortable == undefined ? false : item.sortable" + > + <!-- <template #header> + {{ item.label }} + <el-button type="primary" @click="hidden2(item)">闅愯棌</el-button> + </template> --> + </el-table-column> + </template> + </el-table-column> +</template> + +<script> +import tableCol from '../js/tableCol'; +export default { + name: 'tableColumn', + props: { + // 琛ㄥご鏁版嵁淇℃伅 + coloumnHeader: { + type: Object, + required: true + } + }, + methods: { + hidden1() { + let header = this.coloumnHeader; + header.hidden = true; + }, + hidden2(header) { + header.hidden = true; + }, + sortChangeFunc(column, prop, order) { + console.log('tableCol', tableCol); + + tableCol.sortChange(column, prop, order); + } + } +}; +</script> + +<style scoped></style> diff --git a/src/views/fysp/data-product/js/genChart.js b/src/views/fysp/data-product/js/genChart.js new file mode 100644 index 0000000..b89f086 --- /dev/null +++ b/src/views/fysp/data-product/js/genChart.js @@ -0,0 +1,123 @@ +// 閫掑綊鐨勮幏鍙杘bj涓殑prop灞炴�� 瑙e喅鏈夋椂闇�瑕佸彇val.obj.prop鐨勬儏鍐� +function getPropValueLoop(obj, prop) { + if (typeof prop !== 'string') { + return obj; + } + const props = prop.split('.'); + let result = obj; + props.forEach((item) => { + result = result[item]; + }); + return result; +} +function getCount(array, element) { + let count = 0; + array.forEach((e) => { + if (e == element) { + count++; + } + }); + return count; +} +export default { + getPieChartByDataAndProp(data, prop, label) { + let chartData = [] + function addNewName(name) { + chartData.push({ + name: name, + value: 1 + }) + } + function addCount(name) { + chartData.map(item=>{ + if (item.name === name) { + item.value++ + } + }) + } + function hasThisName(name) { + for (let index = 0; index < chartData.length; index++) { + const element = chartData[index]; + if (element.name === name) { + return true + } + } + return false + } + + data + .map((item) => { + const name = getPropValueLoop(item, prop) + if (hasThisName(name)) { + addCount(name) + }else { + addNewName(name) + } + }) + + return { + title: { + text: label, + left: 'center' + }, + tooltip: { + trigger: 'item' + }, + legend: { + orient: 'vertical', + left: 'left' + }, + series: [ + { + type: 'pie', + radius: '50%', + data: chartData, + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + } + } + ] + }; + }, + getChartByDataAndProp(data, prop, label, chartType = 'bar') { + let series = data.map((item) => getPropValueLoop(item, prop)); + const option = { + title: { + text: label //璁剧疆鏍囬 + }, + tooltip: { + trigger: 'item' + }, + legend: { + orient: 'vertical', + left: 'left' + }, + xAxis: { + type: 'category', + data: Array.from(new Set(series)), + axisLabel: { + rotate: 45, // 鏃嬭浆鏍囩锛岄伩鍏嶉噸鍙� + // 鎴栬�� + interval: 0 // 鏄剧ず鎵�鏈夋爣绛撅紝鍙兘瀵艰嚧閲嶅彔锛屾牴鎹渶姹傝皟鏁� + } + }, + yAxis: { + type: 'value' + }, + series: [ + { + data: Array.from(new Set(series)).map((item) => + getCount(series, item) + ), + type: chartType, + smooth: true + } + ] + }; + return option; + } +}; diff --git a/src/views/fysp/data-product/js/htmlTransfer.js b/src/views/fysp/data-product/js/htmlTransfer.js new file mode 100644 index 0000000..c6b21fe --- /dev/null +++ b/src/views/fysp/data-product/js/htmlTransfer.js @@ -0,0 +1,120 @@ +import Docxtemplater from 'docxtemplater' +import PizZip from 'pizzip' +import JSZipUtils from 'jszip-utils' +import { saveAs } from 'file-saver' +import ImageModule from 'docxtemplater-image-module-free' +import expressions from 'angular-expressions' +import PizZipUtils from 'pizzip/utils/index.js' +/** + * 灏哹ase64鏍煎紡鐨勬暟鎹浆涓篈rrayBuffer + * @param {Object} dataURL base64鏍煎紡鐨勬暟鎹� + */ +function base64DataURLToArrayBuffer(dataURL) { + const base64Regex = /^data:image\/(png|jpg|jpeg|svg|svg\+xml);base64,/; + if (!base64Regex.test(dataURL)) { + return false; + } + const stringBase64 = dataURL.replace(base64Regex, ""); + let binaryString; + if (typeof window !== "undefined") { + binaryString = window.atob(stringBase64); + } else { + binaryString = Buffer.from(stringBase64, "base64").toString("binary"); + } + const len = binaryString.length; + const bytes = new Uint8Array(len); + for (let i = 0; i < len; i++) { + const ascii = binaryString.charCodeAt(i); + bytes[i] = ascii; + } + return bytes.buffer; +} +export default { + chartToImageUrl(chart) { + const dataURL = chart.getDataURL({ + pixelRatio: 5, // 鎻愰珮鍥剧墖璐ㄩ噺 + backgroundColor: '#FFFFFF', // 璁剧疆鑳屾櫙棰滆壊 + excludeComponents: ['toolbox'], // 鎺掗櫎宸ュ叿绠辩粍浠� + type: 'png' // 杈撳嚭鍥剧墖绫诲瀷涓篜NG + }); + return dataURL; + }, + /** + * 瀵煎嚭word鏂囨。锛堝甫鍥剧墖锛� + * + */ + + +ExportBriefDataDocx(tempDocxPath, data, fileName, imgSize) { + expressions.filters.lower = function(input) { + if (!input) return input + return input.toLowerCase() + } + + JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => { + if (error) { + console.log(error) + } + expressions.filters.size = function(input, width, height) { + return { + data: input, + size: [width, height] + } + } + let opts = {} + opts = { + // 鍥惧儚鏄惁灞呬腑 + centered: false + } + opts.getImage = (chartId) => { + //灏哹ase64鐨勬暟鎹浆涓篈rrayBuffer + return base64DataURLToArrayBuffer(chartId); + } + opts.getSize = function(img, tagValue, tagName) { + console.log("img, tagValue, tagName", img, tagValue, tagName); + + if (imgSize[tagName]) { + console.log("imgSize[tagName]", imgSize[tagName]); + return imgSize[tagName] + } else { + return [300, 300] + } + } + // 鍒涘缓涓�涓狫SZip瀹炰緥锛屽唴瀹逛负妯℃澘鐨勫唴瀹� + + const zip = new PizZip(content) + // 鍒涘缓骞跺姞杞� Docxtemplater 瀹炰緥瀵硅薄 + // 璁剧疆妯℃澘鍙橀噺鐨勫�� + const doc = new Docxtemplater() + doc.attachModule(new ImageModule(opts)) + doc.loadZip(zip) + doc.setOptions({ + nullGetter: function() { // 璁剧疆绌哄�� undefined 涓�'' + return '' + } + }) + doc.setData(data) + try { + // 鍛堢幇鏂囨。锛屼細灏嗗唴閮ㄦ墍鏈夊彉閲忔浛鎹㈡垚鍊硷紝 + doc.render() + } catch (error) { + const e = { + message: error.message, + name: error.name, + stack: error.stack, + properties: error.properties + } + console.log('err', { error: e }) + // 褰撲娇鐢╦son璁板綍鏃讹紝姝ゅ鎶涘嚭閿欒淇℃伅 + throw error + } + // 鐢熸垚涓�涓唬琛―ocxtemplater瀵硅薄鐨剒ip鏂囦欢锛堜笉鏄竴涓湡瀹炵殑鏂囦欢锛岃�屾槸鍦ㄥ唴瀛樹腑鐨勮〃绀猴級 + const out = doc.getZip().generate({ + type: 'blob', + mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + }) + // 灏嗙洰鏍囨枃浠跺璞′繚瀛樹负鐩爣绫诲瀷鐨勬枃浠讹紝骞跺懡鍚� + saveAs(out, fileName) + }) +} +} \ No newline at end of file diff --git a/src/views/fysp/data-product/js/tableCol.js b/src/views/fysp/data-product/js/tableCol.js new file mode 100644 index 0000000..244aa41 --- /dev/null +++ b/src/views/fysp/data-product/js/tableCol.js @@ -0,0 +1,21 @@ + +export default { + treeToArray(nodes) { + let labels = []; + + function traverseNodes(nodes) { + nodes.forEach((node) => { + labels.push(node); + + // 濡傛灉褰撳墠鑺傜偣鏈夊瓙鑺傜偣锛岄�掑綊璋冪敤閬嶅巻鍑芥暟 + if (node.children && node.children.length > 0) { + traverseNodes(node.children); + } + }); + } + + traverseNodes(nodes); // 寮�濮嬮�掑綊閬嶅巻 + + return labels; // 杩斿洖鏀堕泦鍒扮殑 labels 鏁扮粍 + } +} \ No newline at end of file -- Gitblit v1.9.3