From d4e7c11e06b643c9353444c839cec40c25945219 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期三, 30 十月 2024 17:37:05 +0800 Subject: [PATCH] 1. 场景报告模块编写(暂存) --- src/views/fysp/data-product/ProdSceneReport.vue | 270 ++++++++++++ src/enum/device/monitorDevice.js | 77 +++ src/model/info | 0 src/views/fysp/scene/CompSceneConstructionInfo.vue | 211 +++++++++ src/model/fysp/device.js | 28 + src/enum/device/productionDevice.js | 67 +++ src/components.d.ts | 11 src/components/SideList.vue | 62 +- src/constants/menu.js | 8 src/views/fysp/data-product/components/CompImgInfo.vue | 80 +++ src/enum/device/device.js | 24 + src/views/fysp/check/components/ArbitraryPhoto.vue | 116 +++-- src/views/fysp/data-product/components/CompProblemTable.vue | 116 +++++ src/components/FYImageSelectDialog.vue | 99 ++++ src/enum/device/treatmentDevice.js | 75 +++ src/api/fysp/deviceApi.js | 12 16 files changed, 1,155 insertions(+), 101 deletions(-) diff --git a/src/api/fysp/deviceApi.js b/src/api/fysp/deviceApi.js index 8dc9dd1..fe67087 100644 --- a/src/api/fysp/deviceApi.js +++ b/src/api/fysp/deviceApi.js @@ -13,11 +13,17 @@ // 鑾峰彇璁惧 async fetchDevices(sceneId, deviceTypeId) { const params = `?sceneId=${sceneId}&deviceTypeId=${deviceTypeId}`; - return await $fysp.get(`device${params}`).then((res) => res).then((res) => res.data); + return await $fysp + .get(`device${params}`) + .then((res) => res) + .then((res) => res.data); }, // 鑾峰彇璁惧鐘舵�佷互鍙婅澶囪鎯� - async fetchDeviceStatus({deviceId, sceneId, deviceTypeId}) { + async fetchDeviceStatus({ deviceId, sceneId, deviceTypeId }) { const params = `?deviceId=${deviceId}&sceneId=${sceneId}&deviceTypeId=${deviceTypeId}`; - return await $fysp.get(`device/status${params}`).then((res) => res).then((res) => res.data); + return await $fysp + .get(`device/status${params}`) + .then((res) => res) + .then((res) => res.data); } }; diff --git a/src/components.d.ts b/src/components.d.ts index 13c1bdc..e7b8095 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -12,17 +12,13 @@ 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'] @@ -41,19 +37,14 @@ 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'] ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] ElOption: typeof import('element-plus/es')['ElOption'] - ElPagination: typeof import('element-plus/es')['ElPagination'] ElPopover: typeof import('element-plus/es')['ElPopover'] - ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] - ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] 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'] @@ -65,7 +56,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'] @@ -74,6 +64,7 @@ FYBgTaskDialog: typeof import('./components/bg-task/FYBgTaskDialog.vue')['default'] FYBgTaskItem: typeof import('./components/bg-task/FYBgTaskItem.vue')['default'] FYForm: typeof import('./components/form/FYForm.vue')['default'] + FYImageSelectDialog: typeof import('./components/FYImageSelectDialog.vue')['default'] FYInfoSearch: typeof import('./components/search-option/FYInfoSearch.vue')['default'] FYList: typeof import('./components/table/FYList.vue')['default'] FYOptionLocation: typeof import('./components/search-option/FYOptionLocation.vue')['default'] diff --git a/src/components/FYImageSelectDialog.vue b/src/components/FYImageSelectDialog.vue new file mode 100644 index 0000000..f9f249c --- /dev/null +++ b/src/components/FYImageSelectDialog.vue @@ -0,0 +1,99 @@ +<template> + <el-dialog + v-model="anyPhotoDialog" + width="66%" + title="浠绘剰鍥剧墖" + destroy-on-close + > + <div class="main"> + <el-row justify="end" class="btns" v-if="!readonly"> + <el-text size="small" type="info" class="m-r-8" + >鏈�澶氶�夋嫨{{ maxSelect }}寮犲浘鐗�</el-text + > + <el-button + size="small" + type="primary" + @click="sendSelectedImg(true)" + :disabled="selectedImgUrlList.length == 0" + >纭畾</el-button + > + <el-button size="small" type="primary" @click="sendSelectedImg(false)" + >鍙栨秷</el-button + > + </el-row> + + <div class="center"> + <el-tabs v-if="typeList.length > 0" v-model="activeId" type="card"> + <el-tab-pane + v-for="item in typeList" + :key="item.typeId" + :label=" + item.typeName + ' (' + typeImgMap.get(activeId).length + ')' + " + :name="item.typeId" + > + </el-tab-pane> + </el-tabs> + <el-empty v-if="isEmpty" description="鏆傛棤璁板綍" /> + <el-scrollbar class="imgs"> + <el-image + v-for="(img, i) in typeImgMap.get(activeId)" + :key="i" + :class="[img.isSelect ? 'selected' : 'noActive', 'image']" + fit="cover" + :src="img.url" + lazy + @click="onSelect(img, i)" + /> + </el-scrollbar> + </div> + </div> + </el-dialog> +</template> +<script setup> +import { ref, watch } from 'vue'; + +const props = defineProps({ + typeList: { + type: Array, + default: () => [] + }, + // 鏄惁浠ュ彧璇荤殑褰㈠紡鏌ョ湅褰撳墠椤甸潰 + readonly: { + type: Boolean, + default: false + }, + defaultFile: { + type: Array, + default: () => [] + }, + // 鍥剧墖鍙�夋暟閲忥紝褰撲紶鍏ユ暟瀛楁椂锛屼唬琛ㄥ浘鐗囨暟閲� + maxSelect: { + type: Number, + default: 3 + } +}); + +const activeId = ref(''); +const typeImgMap = ref(new Map()); +const selectedImgList = ref([]); + +watch(typeImgMap, (newMap, oldMap) => { + if (newMap.get(activeId.value) == undefined) { + return; + } + newMap.get(activeId.value).forEach( + (i) => { + if (i.isSelect == true) { + return; + } + props.defaultFile.forEach((imgItem) => { + if (imgItem.url == i.url) { + i.isSelect = true; + } + }); + }, + { deep: true } + ); +}); +</script> diff --git a/src/components/SideList.vue b/src/components/SideList.vue index 4b440fe..fc8c61f 100644 --- a/src/components/SideList.vue +++ b/src/components/SideList.vue @@ -11,24 +11,26 @@ empty-text="鏆傛棤璁板綍" > <template #default="{ node, data }"> - <div - :class=" - data.selected - ? 'selected-tree-node custom-tree-node' - : 'custom-tree-node' - " - > - <el-icon v-if="data.type == 2" color="var(--el-color-success)" - ><SuccessFilled - /></el-icon> - <el-icon v-else-if="data.type == 1" color="var(--el-color-warning)" - ><WarningFilled - /></el-icon> - <el-icon v-else-if="data.type == 0" color="var(--el-color-danger)" - ><WarningFilled - /></el-icon> - <div>{{ node.label }}</div> - </div> + <slot :node="node" :data="data"> + <div + :class=" + data.selected + ? 'selected-tree-node custom-tree-node' + : 'custom-tree-node' + " + > + <el-icon v-if="data.type == 2" color="var(--el-color-success)" + ><SuccessFilled + /></el-icon> + <el-icon v-else-if="data.type == 1" color="var(--el-color-warning)" + ><WarningFilled + /></el-icon> + <el-icon v-else-if="data.type == 0" color="var(--el-color-danger)" + ><WarningFilled + /></el-icon> + <div>{{ node.label }}</div> + </div> + </slot> </template> </el-tree> </template> @@ -43,20 +45,20 @@ type: 0, title: 'title', categoly: '2022-10-10', - data: {}, - }, - ], + data: {} + } + ] }, - loading: Boolean, + loading: Boolean }, emits: ['itemClick'], data() { return { defaultProps: { children: 'children', - label: 'title', + label: 'title' }, - isLoading: this.loading, + isLoading: this.loading }; }, computed: { @@ -75,7 +77,7 @@ for (const [key, value] of itemMap) { const i = { title: key, - children: [], + children: [] }; value.forEach((v) => { i.children.push(v); @@ -92,11 +94,11 @@ } }); return list; - }, + } }, watch: { loading(nValue) { - this.isLoading = nValue + this.isLoading = nValue; }, //褰撴暟鎹涓�娆℃洿鏂版椂 dataList(nValue) { @@ -117,7 +119,7 @@ } this.isLoading = false; } - }, + } }, methods: { handleNodeClick(data) { @@ -131,8 +133,8 @@ if (data.children == undefined) { this.$emit('itemClick', data); } - }, - }, + } + } }; </script> diff --git a/src/constants/menu.js b/src/constants/menu.js index 9e744ee..6add49c 100644 --- a/src/constants/menu.js +++ b/src/constants/menu.js @@ -37,7 +37,7 @@ }, { icon: 'DataAnalysis', - name: '鏁版嵁浜у搧', + name: '涓棿鏁版嵁浜у搧', children: [ { path: '/fysp/data-product/profollow', @@ -59,6 +59,12 @@ icon: 'Document', name: '鏃ユ姤绠$悊', }, + ], + }, + { + icon: 'DataAnalysis', + name: '鏈�缁堟暟鎹骇鍝�', + children: [ { path: '/fysp/data-product/scenereport', icon: 'Document', diff --git a/src/enum/device/device.js b/src/enum/device/device.js new file mode 100644 index 0000000..842bd36 --- /dev/null +++ b/src/enum/device/device.js @@ -0,0 +1,24 @@ +import monitor from './monitorDevice'; +import treatment from './treatmentDevice'; +import production from './productionDevice'; + +function enumDevice() { + return [ + { value: 0, label: '鐩戞帶璁惧' }, + { value: 1, label: '娌荤悊璁惧' }, + { value: 2, label: '鐢熶骇璁惧' } + ]; +} + +function toLabel(sceneType, deviceType, valueArr) { + switch (deviceType + '') { + case '0': + return monitor.toLabel(sceneType, valueArr); + case '1': + return treatment.toLabel(sceneType, valueArr); + case '2': + return production.toLabel(sceneType, valueArr); + } +} + +export { enumDevice, toLabel }; diff --git a/src/enum/device/monitorDevice.js b/src/enum/device/monitorDevice.js new file mode 100644 index 0000000..987b173 --- /dev/null +++ b/src/enum/device/monitorDevice.js @@ -0,0 +1,77 @@ +const dustDeviceType = [ + { + label: '鎵皹鐩戞祴', + value: '1', + children: [ + { + label: '鎵皹鐩戞祴', + value: '1', + }, + ], + }, +]; + +const fumeDeviceType = [ + { + label: '娌圭儫鐩戞祴', + value: '1', + children: [ + { + label: '娌圭儫鐩戞祴', + value: '1', + }, + ], + }, +]; + +const vocDeviceType = [ + { + label: 'VOC鐩戞祴', + value: '1', + children: [ + { + label: 'VOC鐩戞祴', + value: '1', + }, + ], + }, +]; + +// 鐩戞祴璁惧绫诲瀷 +function monitorDevices(sceneType) { + switch (parseInt(sceneType)) { + // 宸ュ湴,鐮佸ご,鎼呮媽绔�,鍫嗗満 + case 1: + case 2: + case 3: + case 14: + return dustDeviceType; + // 椁愰ギ + case 5: + return fumeDeviceType; + // 宸ヤ笟浼佷笟,姹戒慨 + case 4: + case 6: + return vocDeviceType; + default: + return dustDeviceType; + } +} + +function toLabel(sceneType, valueArr) { + const labelArr = []; + let options = monitorDevices(sceneType); + valueArr.forEach(v => { + if (options) { + const op = options.find(o => { + return (o.value + '') == (v + ''); + }); + labelArr.push(op.label); + options = op.children; + } + }); + + return labelArr; +} + +export default { monitorDevices, toLabel }; diff --git a/src/enum/device/productionDevice.js b/src/enum/device/productionDevice.js new file mode 100644 index 0000000..70ba509 --- /dev/null +++ b/src/enum/device/productionDevice.js @@ -0,0 +1,67 @@ +const dustDeviceType = [ + { + label: '闈為亾', + value: '1', + children: [ + { label: '鎸栨帢鏈�', value: '1' }, + { label: '鍙夎溅', value: '2' }, + { label: '灞ュ甫鍚�', value: '3' }, + { label: '閾茶溅', value: '4' }, + { label: '鍙戝姩鏈�', value: '5' }, + ], + }, +]; + +const fumeDeviceType = [ + { + label: '鍘ㄥ叿', + value: '1', + children: [{ label: '鍘ㄥ叿', value: '1' }], + }, +]; + +const vocDeviceType = [ + { + label: 'VOC', + value: '1', + children: [{ label: 'VOC', value: '1' }], + }, +]; + +// 鐢熶骇璁惧绫诲瀷 +function productionDevices(sceneType) { + switch (parseInt(sceneType)) { + // 宸ュ湴,鐮佸ご,鎼呮媽绔�,鍫嗗満 + case 1: + case 2: + case 3: + case 14: + return dustDeviceType; + // 椁愰ギ + case 5: + return fumeDeviceType; + // 宸ヤ笟浼佷笟,姹戒慨 + case 4: + case 6: + return vocDeviceType; + default: + return dustDeviceType; + } +} + +function toLabel(sceneType, valueArr) { + const labelArr = []; + let options = productionDevices(sceneType); + valueArr.forEach(v => { + if (options) { + const op = options.find(o => { + return (o.value + '') == (v + ''); + }); + labelArr.push(op.label); + options = op.children; + } + }); + return labelArr; +} + +export default { productionDevices, toLabel }; diff --git a/src/enum/device/treatmentDevice.js b/src/enum/device/treatmentDevice.js new file mode 100644 index 0000000..28efcf5 --- /dev/null +++ b/src/enum/device/treatmentDevice.js @@ -0,0 +1,75 @@ +const dustDeviceType = [ + { + label: '鎶�闃�', + value: '1', + children: [ + { label: '鐜繚娲掓按杞︼紙澶у瀷闈炵數鍔級', value: '1' }, + { label: '鐢靛姩闆剧偖杞�', value: '2' }, + { label: '鐢靛姩娲掓按杞︼紙灏忓瀷锛�', value: '3' }, + { label: '闆剧偖杞︼紙鍥哄畾鎴栬疆寮忥級', value: '4' }, + { label: '鑷姩鍐叉礂瑁呯疆锛堝皝闂紡锛�', value: '5' }, + { label: '楂樻晥娲楄疆鏈�', value: '6' }, + { label: '楂樺帇姘存灙', value: '7' }, + { label: '鏅�氭按绠℃垨娑堥槻鏍�', value: '8' }, + { label: '濉斿悐鍠锋穻', value: '9' }, + { label: '鍥村鍠锋穻', value: '10' }, + { label: '鎵皹鐩戞祴涓庡柗娣嬭仈鍔�', value: '11' }, + { label: '鍫嗗満鍠锋穻', value: '12' }, + { label: '鐢熶骇鍖哄柗娣�', value: '13' }, + ], + }, +]; + +const fumeDeviceType = [ + { + label: '鍑�鍖�', + value: '1', + children: [{ label: '娌圭儫鍑�鍖�', value: '1' }], + }, +]; + +const vocDeviceType = [ + { + label: '鍑�鍖�', + value: '1', + children: [{ label: '鍥哄簾鍑�鍖�', value: '1' }], + }, +]; + +// 娌荤悊璁惧绫诲瀷 +function treatmentDevices(sceneType) { + switch (parseInt(sceneType)) { + // 宸ュ湴,鐮佸ご,鎼呮媽绔�,鍫嗗満 + case 1: + case 2: + case 3: + case 14: + return dustDeviceType; + // 椁愰ギ + case 5: + return fumeDeviceType; + // 宸ヤ笟浼佷笟,姹戒慨 + case 4: + case 6: + return vocDeviceType; + default: + return dustDeviceType; + } +} + +function toLabel(sceneType, valueArr) { + const labelArr = []; + let options = treatmentDevices(sceneType); + valueArr.forEach(v => { + if (options) { + const op = options.find(o => { + return (o.value + '') == (v + ''); + }); + labelArr.push(op.label); + options = op.children; + } + }); + return labelArr; +} + +export default { treatmentDevices, toLabel }; diff --git a/src/model/fysp/device.js b/src/model/fysp/device.js new file mode 100644 index 0000000..fb7eb1b --- /dev/null +++ b/src/model/fysp/device.js @@ -0,0 +1,28 @@ +/** + * 鏍囧噯鍖栧睘鎬у悕 + * 灏嗕笁绉嶈澶嘯鐩戞帶璁惧],[娌荤悊璁惧],[鐢熶骇璁惧]瀵硅薄鐨勫睘鎬у悕缁熶竴鏍煎紡鍖� + * @param {*} data + */ +function formatDevice(data) { + // 灏嗕竴涓猨s瀵硅薄涓墍鏈塪i锛寃i锛宲i寮�澶寸殑灞炴�у叏閮ㄦ敼鎴愬幓鎺夎繖浜涘墠缂�骞朵笖閲嶆柊鍙樹负椹煎嘲寮忓懡鍚� + const newObj = {}; + for (const key in data) { + let newKey = key; + if (key.startsWith('di')) { + newKey = key.substring(2); + } else if (key.startsWith('wi')) { + newKey = key.substring(2); + } else if (key.startsWith('pi')) { + newKey = key.substring(2); + } + newKey = newKey.charAt(0).toLowerCase() + newKey.slice(1); + newObj[newKey] = data[key]; + } + return newObj; +} + +function formatDeviceList(dataList) { + return dataList.map((v) => formatDevice(v)); +} + +export { formatDevice, formatDeviceList }; diff --git a/src/model/info b/src/model/info new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/model/info diff --git a/src/views/fysp/check/components/ArbitraryPhoto.vue b/src/views/fysp/check/components/ArbitraryPhoto.vue index 854296c..bd24994 100644 --- a/src/views/fysp/check/components/ArbitraryPhoto.vue +++ b/src/views/fysp/check/components/ArbitraryPhoto.vue @@ -1,49 +1,50 @@ <template> <div class="main"> - <div class="filters" v-if="false"> - <el-select - v-for="(key_select, index_select) of filters.keys()" - :placeholder="key_select.text" + <el-row justify="end" class="btns" v-if="!readonly"> + <el-text size="small" type="info" class="m-r-8" + >鏈�澶氶�夋嫨{{ maxSelect }}寮犲浘鐗�</el-text > - <el-option - v-for="(key_option) in filters.get(key_select.key)" - :key="key_option.key" - :value="key_option.value" - :label="key_option.label" - > - </el-option> - </el-select> - </div> - <div class="btns" v-if="!readonly"> - <el-button size="small" type="primary" @click="sendSelectedImg(true)">纭畾</el-button> - <el-button size="small" type="primary" @click="sendSelectedImg(false)">鍙栨秷</el-button> - </div> + <el-button + size="small" + type="primary" + @click="sendSelectedImg(true)" + :disabled="selectedImgUrlList.length == 0" + >纭畾</el-button + > + <el-button size="small" type="primary" @click="sendSelectedImg(false)" + >鍙栨秷</el-button + > + </el-row> <div class="center"> - <el-descriptions> + <!-- <el-descriptions> <el-descriptions-item label="鎬绘暟"> <span>{{ this.imgUrlList.length }}</span> </el-descriptions-item> - </el-descriptions> + </el-descriptions> --> <el-tabs v-model="activeId" type="card"> <el-tab-pane v-for="item in typeList" - :label="item.businesstype" + :key="item.businesstypeid" + :label=" + item.businesstype + ' (' + typeImgMap.get(activeId).length + ')' + " :name="item.businesstypeid" > </el-tab-pane> </el-tabs> <el-empty v-if="isEmpty" description="鏆傛棤璁板綍" /> - <div class="imgs"> + <el-scrollbar class="imgs"> <el-image v-for="(img, i) in typeImgMap.get(activeId)" + :key="i" :class="[Boolean(img.isSelect) ? 'selected' : 'noActive', 'image']" fit="cover" :src="img.url" lazy @click="onSelect(img, i)" /> - </div> + </el-scrollbar> </div> </div> </template> @@ -70,6 +71,11 @@ defaultFile: { type: Array, default: () => [] + }, + // 鍥剧墖鍙�夋暟閲忥紝褰撲紶鍏ユ暟瀛楁椂锛屼唬琛ㄥ浘鐗囨暟閲� + maxSelect: { + type: Number, + default: 3 } }, data() { @@ -95,10 +101,19 @@ // { businesstypeid: 60, businesstype: '鎵╁睍绫诲崄' } ], typeImgMap: new Map(), - imgUrlList: [] + imgUrlList: [], + selectedImgUrlList: [] }; }, watch: { + subtask: { + handler(nV, oV) { + if (nV != oV && nV) { + this.getAllImgList(); + } + }, + immediate: true + }, defaultFile: { handler(newFileList, oldFileList) { if (this.isClose) { @@ -128,9 +143,9 @@ } }, mounted() { - if (this.subtask) { - this.getAllImgList(); - } + // if (this.subtask) { + // this.getAllImgList(); + // } }, methods: { // 鍒濆鍖栧垰寮�濮嬮�変腑鐨勬爣绛� @@ -139,11 +154,13 @@ this.activeId = this.typeList[0].businesstypeid; } }, - async getAllImgList() { + getAllImgList() { // for(var k of this.typeImgMap.keys()) { // this.typeImgMap.set(k, []) // } - await mediafileApi.getRoutineByStGuid(this.subtask.stGuid).then((res) => { + this.typeImgMap.clear(); + this.typeList = []; + mediafileApi.getRoutineByStGuid(this.subtask.stGuid).then((res) => { this.isEmpty = false; let data = res.data; if (data.length == 0) { @@ -179,7 +196,6 @@ this.imgUrlList.push(e); // TODO imgUrl鍏ㄥ眬閰嶇疆 e.url = $fysp.imgUrl + e.extension1 + e.guid + '.jpg'; - // e.url = "http://47.100.191.150:9005/images/" + e.extension1 + e.guid + '.jpg' e.isSelect = false; } this.initSelectedTab(); @@ -217,20 +233,31 @@ }); }, onSelect(img, i) { - // if (i == 2 && !this.isAll) { - // this.getAllImgList(); - // this.isAll = true; - // } else { - // if (this.readonly) { - // return; - // } - // img.isSelect = !Boolean(img.isSelect); - // } - if (this.readonly) { return; } - img.isSelect = !img.isSelect; + const index = this.selectedImgUrlList.indexOf(img); + if (index == -1) { + if (this.maxSelect == 1) { + img.isSelect = true; + this.selectedImgUrlList.push(img); + if (this.selectedImgUrlList.length > 1) { + this.selectedImgUrlList.splice(0, 1).forEach((e) => { + e.isSelect = false; + }); + } + } else if (this.maxSelect > 1) { + if (this.selectedImgUrlList.length < this.maxSelect) { + img.isSelect = true; + this.selectedImgUrlList.push(img); + } + } + } else { + this.selectedImgUrlList.splice(index, 1); + img.isSelect = false; + } + + // img.isSelect = !img.isSelect; }, sendSelectedImg(isOk) { let result = []; @@ -280,7 +307,7 @@ } */ .imgs { - height: 650px; + height: 50vh; width: 90%; min-height: 100px !important; /* border-style:solid; @@ -295,6 +322,7 @@ } .image { + margin: 5px; height: 210px; width: 200px; border-radius: 4px; @@ -308,10 +336,10 @@ } .selected { - padding: 5px; + margin: 3px; color: #4abe84; box-shadow: 0 2px 7px 0 rgba(85, 110, 97, 0.35); - border: 1px solid rgba(74, 190, 132, 1); + border: 2px solid rgba(74, 190, 132, 1); } .selected:before { @@ -338,7 +366,7 @@ } .noActive { - padding: 5px; + /* padding: 5px; */ } .blurry { diff --git a/src/views/fysp/data-product/ProdSceneReport.vue b/src/views/fysp/data-product/ProdSceneReport.vue index c2d8d05..a6abc18 100644 --- a/src/views/fysp/data-product/ProdSceneReport.vue +++ b/src/views/fysp/data-product/ProdSceneReport.vue @@ -1,3 +1,271 @@ <template> - 鍦烘櫙鎶ュ憡绠$悊 + <BaseContentLayout> + <template #header> + <SearchBar @on-submit="search"> </SearchBar> + </template> + <template #aside> + <SideList + :items="subtasks" + :loading="sideLoading" + @item-click="chooseSubtask" + ></SideList> + </template> + <template #main> + <el-scrollbar class="el-scrollbar" v-loading="mainLoading"> + <CompSceneConstructionInfo + title="A銆佸伐鍦板熀鏈俊鎭�" + :form-info="formSubScene" + /> + <div><el-text type="">闄勫浘鐗囷細</el-text></div> + <CompImgInfo + title="鏂藉伐閾墝" + :img-src="sceneImg.url" + @change="anyPhotoDialog = true" + ></CompImgInfo> + <el-divider /> + <el-text tag="h1">B銆佷富瑕佹薄鏌撻槻娌昏鏂�</el-text> + <el-space wrap> + <CompImgInfo + v-for="(item, i) in deviceList" + :key="i" + down-title + :title="item._deviceTypeName" + :img-src="item._showStatusPic" + @change="showDevicePhotoDialog(item)" + ></CompImgInfo> + </el-space> + <el-divider /> + <el-text tag="h1">C銆佺幇鍦烘薄鏌撻棶棰樹笌鏁存敼鎯呭喌</el-text> + </el-scrollbar> + </template> + </BaseContentLayout> + <el-dialog + v-model="anyPhotoDialog" + width="66%" + title="浠绘剰鍥剧墖" + destroy-on-close + > + <ArbitraryPhoto + :max-select="1" + :readonly="false" + :subtask="curSubtask.data" + @selectByAnyPhonoEvent="handleSelectAnyPhoto" + :defaultFile="[sceneImg]" + > + </ArbitraryPhoto> + </el-dialog> + <el-dialog + title="璁惧鍥剧墖" + width="66%" + v-model="deiveceImgDialog" + destroy-on-close + > + <CompDevicePhono + @selectPhonoEvent="handleSelectDevicePhoto" + :imgPathsDataSource="showDeviceImgList" + > + </CompDevicePhono> + </el-dialog> </template> +<script setup> +import { ref, computed } from 'vue'; + +import { $fysp } from '@/api/index'; +import taskApi from '@/api/fysp/taskApi'; +import sceneApi from '@/api/fysp/sceneApi'; +import deviceApi from '@/api/fysp/deviceApi'; +import { formatDeviceList } from '@/model/fysp/device'; +import { enumDevice, toLabel } from '@/enum/device/device'; + +import CompSceneConstructionInfo from '@/views/fysp/scene/CompSceneConstructionInfo.vue'; +import ArbitraryPhoto from '@/views/fysp/check/components/ArbitraryPhoto.vue'; +import CompDevicePhono from '@/views/fysp/check/components/CompDevicePhono.vue'; +import CompImgInfo from '@/views/fysp/data-product/components/CompImgInfo.vue'; + +/************************* 宸︿晶宸℃煡浠诲姟閫夊崟 **********************************/ +const curSubtask = ref({}); +const subtasks = ref([]); +const sideLoading = ref(false); +const mainLoading = ref(false); +//鑾峰彇浠诲姟闂鐨勫鏍告儏鍐� +function getSubtaskType(s) { + let type = 0; + if (s.proNum == 0) { + type = 2; + } else if (s.proCheckedNum == 0) { + type = 0; + } else if (s.proCheckedNum < s.proNum) { + type = 1; + } else { + type = 2; + } + return type; +} +//鏌ヨ瀛愪换鍔$粺璁′俊鎭� +function search(formSearch) { + // this.topTask = formSearch.topTask; + sideLoading.value = true; + mainLoading.value = true; + // this.curProList = []; + curSubtask.value = {}; + const param = { + topTaskId: formSearch.topTask.tguid, + sceneTypeId: formSearch.sceneTypeId + }; + taskApi.getSubtaskSummary(param).then((res) => { + const list = []; + res.forEach((s) => { + const t = getSubtaskType(s); + list.push({ + type: t, + title: s.stName, + categoly: s.stPlanTime.split('T')[0], + data: s + }); + }); + subtasks.value = list; + if (list.length == 0) { + sideLoading.value = false; + mainLoading.value = false; + } + }); +} +//鐐瑰嚮宸︿晶鑿滃崟浠诲姟浜嬩欢 +function chooseSubtask(s) { + sideLoading.value = false; + mainLoading.value = true; + curSubtask.value = s; + + fetchSceneInfo(s.data.sceneId).finally(() => { + mainLoading.value = false; + }); + fetchDeviceList(s); + fetchProblems(s) +} + +/************************* 鍦烘櫙鍩烘湰淇℃伅 **********************************/ +const formSubScene = ref({}); +function fetchSceneInfo(sceneId) { + return sceneApi.getSceneDetail(sceneId).then((res) => { + //鍦烘櫙 + // if (res.data.scense) formScene = res.data.scense; + formSubScene.value = res.data.subScene ? res.data.subScene : {}; + // if (res.data.sceneDevice) { + // formSceneDevice = res.data.sceneDevice; + // } else { + // formSceneDevice = { + // sGuid: formScene.guid, + // }; + // } + }); +} + +// 浠绘剰鎷嶅浘鐗囬�夋嫨瀵硅瘽妗� +const anyPhotoDialog = ref(false); +const sceneImg = ref({}); +function handleSelectAnyPhoto(data) { + anyPhotoDialog.value = false; + if (data.length > 0) { + sceneImg.value = { url: data[0].url }; + } +} +/************************* 鍦烘櫙璁惧淇℃伅 **********************************/ + +// 璁惧鍥剧墖閫夋嫨瀵硅瘽妗� +const deiveceImgDialog = ref(false); +const showDeviceImg = ref({}); +const showDeviceImgList = ref([]); +// 璁惧鍥剧墖鍒楄〃 +const deviceList = ref([]); + +function showDevicePhotoDialog(device) { + deiveceImgDialog.value = true; + showDeviceImgList.value = []; + let imgList = []; + device._status + .map((s) => s._picUrls) + .forEach((pics) => { + imgList = imgList.concat( + pics.map((p) => { + return { + topTypeId: device.topTypeId, + _picUrl: p + }; + }) + ); + }); + console.log(imgList); + + showDeviceImgList.value = imgList; +} + +function handleSelectDevicePhoto(data) { + deiveceImgDialog.value = false; + if (data.length > 0) { + showDeviceImg.value = { url: data[0].url }; + } +} + +const deviceTopTypes = [ + { id: 0, label: '鐩戞帶璁惧' }, + { id: 1, label: '娌荤悊璁惧' } + // { id: 2, label: '鐢熶骇璁惧' } +]; + +function fetchDeviceList(s) { + deviceList.value = []; + for (const deviceTopTypeElement of deviceTopTypes) { + const topTypeId = deviceTopTypeElement.id; + deviceApi + .fetchDevices(s.data.sceneId, topTypeId) + .then((res) => { + return formatDeviceList(res.data); + }) + .then((result) => { + result.forEach((r) => { + const param = { + deviceId: r.id, + sceneId: r.sceneGuid, + deviceTypeId: topTypeId + }; + deviceApi + .fetchDeviceStatus(param) + .then((res) => { + res.data.forEach((e) => { + if (e.dlPicUrl && e.dlPicUrl.trim() != '') { + e._picUrls = e.dlPicUrl + .split(';') + .map((v) => $fysp.imgUrl + v); + } else { + e._picUrls = []; + } + }); + return res; + }) + .then((res) => { + if (res.data.length > 0 && res.data[0]._picUrls.length > 0) { + r._showStatusPic = res.data[0]._picUrls[0]; + } + r._status = res.data; + r.topTypeId = topTypeId; + r._deviceTypeName = toLabel(r.sceneTypeId, topTypeId, [ + r.typeId, + r.subtypeId + ]).join('-'); + deviceList.value.push(r); + }); + }); + }); + } +} +/************************* 鐜板満宸℃煡鎯呭喌锛堥棶棰樹笌鏁存敼锛� **********************************/ +//褰撳墠浠诲姟鐨勯棶棰樺垪琛� +const curProList = ref([]); + +function fetchProblems(s) { + taskApi.getProBySubtask(s.data.stGuid).then((res) => { + curProList.value = res; + }); +} +/************************* 鎵皹闃叉不寤鸿 **********************************/ +</script> diff --git a/src/views/fysp/data-product/components/CompImgInfo.vue b/src/views/fysp/data-product/components/CompImgInfo.vue new file mode 100644 index 0000000..5fcfd7e --- /dev/null +++ b/src/views/fysp/data-product/components/CompImgInfo.vue @@ -0,0 +1,80 @@ +<template> + <table> + <tbody> + <tr v-if="!downTitle"> + <td> + <el-row justify="space-between" align="middle"> + {{ title }} + <el-button size="small" @click="$emit('change')">{{ + btnName + }}</el-button> + </el-row> + </td> + </tr> + <tr> + <td> + <el-image + class="image" + :src="imgSrc" + :preview-src-list="[imgSrc]" + :initial-index="0" + fit="cover" + lazy + /> + </td> + </tr> + <tr v-if="downTitle"> + <td> + <el-row justify="space-between" align="middle"> + {{ title }} + <el-button size="small" @click="$emit('change')">{{ + btnName + }}</el-button> + </el-row> + </td> + </tr> + </tbody> + </table> +</template> +<script setup> +import { ref } from 'vue'; + +const props = defineProps({ + // 鏍囬鏄惁鍦ㄥ浘鐗囦笅鏂� + downTitle: Boolean, + title: String, + imgSrc: String, + btnName: { + type: String, + default: '淇敼' + } +}); + +const emit = defineEmits(['change']); +</script> +<style scoped> +.image { + width: 200px; + height: 210px; + border-radius: 4px; +} + +table { + color: #333333; + border-color: #666666; + border-collapse: collapse; +} + +tr { + font-size: var(--el-font-size-small); +} + +td { + border: 1px solid black; + padding: 2px 6px; + /* border-width: 1px; + padding: 8px; + border-style: solid; + border-color: #666666; */ +} +</style> diff --git a/src/views/fysp/data-product/components/CompProblemTable.vue b/src/views/fysp/data-product/components/CompProblemTable.vue new file mode 100644 index 0000000..0d3d6df --- /dev/null +++ b/src/views/fysp/data-product/components/CompProblemTable.vue @@ -0,0 +1,116 @@ +<template> + <table> + <tbody> + <tr> + <td>{{ title }}</td> + </tr> + <tr> + <td> + <el-image + class="image" + :src="seletcedProblemPic" + :preview-src-list="[seletcedProblemPic]" + :initial-index="0" + fit="cover" + lazy + /> + </td> + <td> + <el-image + class="image" + :src="seletcedChangePic" + :preview-src-list="[seletcedChangePic]" + :initial-index="0" + fit="cover" + lazy + /> + </td> + </tr> + <tr> + <td> + <el-row justify="space-between" align="middle"> + <div>浣嶇疆锛歿{ problem.location }}</div> + <div>鎻忚堪锛歿{ problem.problemname }}</div> + <el-button size="small" @click="$emit('change')">{{ + btnName + }}</el-button> + </el-row> + </td> + <td> + <el-row justify="space-between" align="middle"> + <div>浣嶇疆锛歿{ problem.location }}</div> + <div>鎻忚堪锛歿{ problem.problemname }}</div> + <el-button size="small" @click="$emit('change')">{{ + btnName + }}</el-button> + </el-row> + </td> + </tr> + </tbody> + </table> +</template> +<script setup> +import { ref, watch } from 'vue'; +import ProCheckProxy from '@/views/check/ProCheckProxy'; + +const props = defineProps({ + problem: { + type: Object, + default: () => { + return {}; + } + } +}); + +const emit = defineEmits(['change']); + +const pics = ref([]); +const seletcedProblemPic = ref(); +const seletcedChangePic = ref(); + +function getPics() { + pics.value = ProCheckProxy.proPics(props.problem); + if (pics.value[0].path.length > 0) { + seletcedProblemPic.value = pics.value[0].path[0]; + } + if (pics.value[1].path.length > 0) { + seletcedChangePic.value = pics.value[1].path[0]; + } +} + +watch( + () => props.problem, + (nV, oV) => { + if (nV != oV) { + getPics(); + } + }, + { immediate: true } +); +</script> +<style scoped> +.image { + width: 200px; + height: 210px; + border-radius: 4px; +} + +table { + color: #333333; + border-color: #666666; + border-collapse: collapse; +} + +tr { + font-size: var(--el-font-size-small); +} + +td { + border: 1px solid black; + padding: 2px 6px; + /* border-width: 1px; + padding: 8px; + border-style: solid; + border-color: #666666; */ +} +</style> diff --git a/src/views/fysp/scene/CompSceneConstructionInfo.vue b/src/views/fysp/scene/CompSceneConstructionInfo.vue index 4ff7cfb..6d2c70f 100644 --- a/src/views/fysp/scene/CompSceneConstructionInfo.vue +++ b/src/views/fysp/scene/CompSceneConstructionInfo.vue @@ -1,6 +1,7 @@ <!-- 宸ュ湴涓撳睘淇℃伅缂栬緫 --> <template> <el-form + v-if="showStyle == 'form'" :inline="false" :model="formObj" ref="formRef" @@ -161,6 +162,183 @@ <el-button :disabled="!edit" @click="onReset">閲嶇疆</el-button> </el-form-item> </el-form> + + <el-descriptions + v-else-if="showStyle == 'descriptions'" + :column="2" + :size="fontSize" + direction="horizontal" + border + > + <template #title> + <el-text tag="h1">{{ title }}</el-text> + </template> + <template #extra> + <el-button + :size="fontSize" + :disabled="!edit" + type="primary" + @click="onSubmit" + :loading="loading" + >鎻愪氦</el-button + > + <el-button :size="fontSize" :disabled="!edit" @click="onReset" + >閲嶇疆</el-button + > + </template> + <el-descriptions-item label="宸ョ▼绫诲瀷" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csProjectType" + placeholder="宸ョ▼绫诲瀷" + /></el-descriptions-item> + <!-- <el-descriptions-item label="寤鸿鐘舵��" + ><el-select + v-model="formObj.csStatus" + placeholder="寤鸿鐘舵��" + > + <el-option + v-for="s in status" + :key="s.value" + :label="s.label" + :value="s.value" + /> </el-select + ></el-descriptions-item> --> + <el-descriptions-item label="鏂藉伐闃舵" + ><el-select + v-model="formObj.siExtension1" + placeholder="鏂藉伐闃舵" + :size="fontSize" + > + <el-option + v-for="s in stage" + :key="s.value" + :label="s.label" + :value="s.value" + /> </el-select + ></el-descriptions-item> + <el-descriptions-item label="鏂藉伐鏃堕棿" + ><el-date-picker + :size="fontSize" + v-model="formObj._timeRange" + type="daterange" + range-separator="鑷�" + start-placeholder="寮�宸ユ椂闂�" + end-placeholder="瀹屽伐鏃堕棿" + /></el-descriptions-item> + <el-descriptions-item label="鍓╀綑宸ユ湡" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csLeftTime" + placeholder="鍓╀綑宸ユ湡锛屼緥濡傚嚑骞淬�佸嚑鏈堛�佸嚑鍛ㄣ�佸嚑澶╃瓑" + /></el-descriptions-item> + <el-descriptions-item label="鏂藉伐鍦板潃" span="2" + ><el-input + clearable + v-model="formObj.location" + placeholder="鏂藉伐鍦板潃" + :size="fontSize" + /></el-descriptions-item> + <el-descriptions-item label="鍗犲湴闈㈢Н" rowspan="2" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csFloorSpace" + placeholder="鍗犲湴闈㈢Н" + > + <template #append>銕�</template> + </el-input></el-descriptions-item + > + <el-descriptions-item label="鏂藉伐闈㈢Н" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csConstructionArea" + placeholder="鏂藉伐闈㈢Н" + > + <template #append>銕�</template> + </el-input></el-descriptions-item + > + <el-descriptions-item label="姣忔湀鏂藉伐闈㈢Н" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csConstructionAreaPerMonth" + placeholder="姣忔湀鏂藉伐闈㈢Н" + > + <template #append>銕�</template> + </el-input></el-descriptions-item + > + <el-descriptions-item label="瀹夊叏鍛�" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csSecurityOfficer" + placeholder="瀹夊叏鍛�" + /></el-descriptions-item> + <el-descriptions-item label="瀹夊叏鍛樼數璇�" + ><el-input + :size="fontSize" + clearable + type="tel" + v-model="formObj.csSecurityOfficerTel" + placeholder="瀹夊叏鍛樼數璇�" + > + <template #prepend> + <el-icon><Iphone /></el-icon> + </template> </el-input + ></el-descriptions-item> + <el-descriptions-item label="鎬诲寘鍗曚綅" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csConstructionUnit" + placeholder="鎬诲寘鍗曚綅" + /></el-descriptions-item> + <!-- <el-descriptions-item label="鏂藉伐鍗曚綅鑱旂郴浜�" + ><el-input + clearable + v-model="formObj.csConstructionContacts" + placeholder="鏂藉伐鍗曚綅鑱旂郴浜�" + /></el-descriptions-item> + <el-descriptions-item label="鏂藉伐鍗曚綅鑱旂郴鐢佃瘽" + ><el-input + clearable + type="tel" + v-model="formObj.csConstructionContactsTel" + placeholder="鏂藉伐鍗曚綅鑱旂郴鐢佃瘽" + > + <template #prepend> + <el-icon><Iphone /></el-icon> + </template> </el-input + ></el-descriptions-item> --> + <el-descriptions-item label="寤鸿鍗曚綅" + ><el-input + :size="fontSize" + clearable + v-model="formObj.csEmployerUnit" + placeholder="寤鸿鍗曚綅" + /></el-descriptions-item> + <!-- <el-descriptions-item label="涓氫富鍗曚綅鑱旂郴浜�" + ><el-input + clearable + v-model="formObj.csEmployerContacts" + placeholder="涓氫富鍗曚綅鑱旂郴浜�" + /></el-descriptions-item> + <el-descriptions-item label="涓氫富鍗曚綅鑱旂郴鐢佃瘽" + ><el-input + clearable + type="tel" + v-model="formObj.csEmployerContactsTel" + placeholder="涓氫富鍗曚綅鑱旂郴鐢佃瘽" + > + <template #prepend> + <el-icon><Iphone /></el-icon> + </template> </el-input + ></el-descriptions-item> --> + </el-descriptions> </template> <script setup> @@ -171,23 +349,32 @@ import { useFormConfirm } from '@/composables/formConfirm'; const props = defineProps({ + scene: Object, //宸ュ湴棰濆淇℃伅 formInfo: Object, //鍦烘櫙绫诲瀷锛氬伐鍦� sceneType: { type: Number, - default: 1, + default: 1 }, + // 灞曠ず鏍峰紡 form锛氳〃鍗曪紱descriptions锛氭弿杩板垪琛� + showStyle: { + type: String, + default: 'descriptions' + // default:'form' + }, + title: String }); +const fontSize = ref('small'); const emit = defineEmits(['onSubmit', 'onCancel']); const { formObj, formRef, edit, onSubmit, onReset } = useFormConfirm({ submit: { - do: submit, + do: submit }, cancel: { - do: cancel, - }, + do: cancel + } }); const loading = ref(false); const status = reactive(enumStatusNA()); @@ -197,23 +384,23 @@ { required: true, message: '宸ョ▼绫诲瀷涓嶈兘涓虹┖', - trigger: 'blur', - }, + trigger: 'blur' + } ], csStatus: [ { required: true, message: '寤鸿鐘舵�佷笉鑳戒负绌�', - trigger: 'change', - }, + trigger: 'change' + } ], siExtension1: [ { required: true, message: '鏂藉伐闃舵涓嶈兘涓虹┖', - trigger: 'change', - }, - ], + trigger: 'change' + } + ] }); // 鍒涘缓鎴栨洿鏂板満鏅鎯� @@ -252,7 +439,7 @@ formObj.value = nValue; formObj.value._timeRange = [ new Date(formObj.value.csStartTime), - new Date(formObj.value.csEndTime), + new Date(formObj.value.csEndTime) ]; } }, -- Gitblit v1.9.3