From 9ca85dc3bd39864daf9528d746f4bc6a0963a4c0 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期四, 17 四月 2025 14:05:44 +0800 Subject: [PATCH] 完成走航融合模块 --- src/model/SatelliteGrid.js | 237 +++++----- src/views/underwaymix/component/UnderwayMixEdit.vue | 197 ++++++++ src/components/search/OptionPollutionDegree.vue | 40 + src/api/gridApi.js | 36 + src/components.d.ts | 1 src/views/underwaymix/component/GridStyleTool.vue | 401 ++++++++++------- src/styles/elementUI.scss | 8 src/constant/pollution-degree.js | 30 + src/views/underwaymix/component/UnderwayMixManage.vue | 214 +++++++++ src/components/monitor/DataTable.vue | 3 src/api/index.js | 2 src/views/underwaymix/UnderwayMixMode.vue | 87 +- src/components/grid/GridSearch.vue | 19 src/constant/device-type.js | 28 - src/stores/fusion-data.js | 60 ++ 15 files changed, 984 insertions(+), 379 deletions(-) diff --git a/src/api/gridApi.js b/src/api/gridApi.js index f9f4dff..4d971b1 100644 --- a/src/api/gridApi.js +++ b/src/api/gridApi.js @@ -46,6 +46,29 @@ .then((res) => res.data); }, + /** + * 鑾峰彇缃戞牸缁勪笅鐨勯仴娴嬫暟鎹� + * @param {*} gridData 缃戞牸鏁版嵁 + * @returns + */ + fetchGridData2(gridData) { + return $http + .post(`air/satellite/grid/data2`, gridData) + .then((res) => res.data); + }, + + /** + * 鍒犻櫎缃戞牸鏁版嵁 + * @param {Number} dataId 鏁版嵁id + */ + deleteGridData(dataId) { + return $http + .delete(`air/satellite/grid/data/delete`, { + params: { dataId } + }) + .then((res) => res.data); + }, + // /** // * 鑾峰彇缃戞牸缁勪笅鐨勯仴娴媋od // * @param {*} groupId @@ -144,10 +167,15 @@ .then((res) => res.data); }, - buildUnderwayProduct(missionCode, groupId) { - return $http.get(`air/satellite/import/grid/aod/download/template`, { - responseType: 'blob' - }); + /** + * 鐢熸垚璧拌埅缃戞牸铻嶅悎璁板綍 + * @param {*} gridData + * @returns + */ + buildUnderwayProduct(gridData) { + return $http + .post(`air/satellite/product/underway/build`, gridData) + .then((res) => res.data); }, mixUnderwayGridData(groupId, dataIdList) { diff --git a/src/api/index.js b/src/api/index.js index 559cc74..11a5208 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -1,7 +1,7 @@ import axios from 'axios'; import { ElMessage } from 'element-plus'; -const debug = true; +const debug = false; let ip1 = 'http://47.100.191.150:9029/'; // console.log(import.meta.env); diff --git a/src/components.d.ts b/src/components.d.ts index 77f6091..12e94ad 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -74,6 +74,7 @@ OptionLocation: typeof import('./components/search/OptionLocation.vue')['default'] OptionLocation2: typeof import('./components/search/OptionLocation2.vue')['default'] OptionMission: typeof import('./components/search/OptionMission.vue')['default'] + OptionPollutionDegree: typeof import('./components/search/OptionPollutionDegree.vue')['default'] OptionTime: typeof import('./components/search/OptionTime.vue')['default'] OptionType: typeof import('./components/search/OptionType.vue')['default'] ProgressLineChart: typeof import('./components/chart/ProgressLineChart.vue')['default'] diff --git a/src/components/grid/GridSearch.vue b/src/components/grid/GridSearch.vue index cbb977a..406818d 100644 --- a/src/components/grid/GridSearch.vue +++ b/src/components/grid/GridSearch.vue @@ -17,10 +17,10 @@ label="缁忕含搴�" :content="data.gridCell.longitude + ', ' + data.gridCell.latitude" /> - <DescriptionsListItem label="鍥涜嚦鑼冨洿" content="/" /> + <!-- <DescriptionsListItem label="鍥涜嚦鑼冨洿" content="/" /> --> </DescriptionsList> - <el-tabs v-model="activeName" > + <el-tabs v-model="activeName"> <el-tab-pane label="缃戞牸鏁版嵁" name="first"> <DescriptionsList> <DescriptionsListItem @@ -134,21 +134,11 @@ const data = computed(() => { if (gridStore.selectedGridCellAndDataDetail) { - // const { gridCell, gridDataDetail } = - // gridStore.selectedGridCellAndDataDetail; - // const res = []; - // // 濡傛灉缃戞牸鏁版嵁涓鸿瀺鍚堟暟鎹紝鍒欓渶瑕佸悓姝ュ睍绀哄嚭鍘熷鏁版嵁 - // if (gridDataDetail.mixData) { - // } return { gridCell: gridStore.selectedGridCellAndDataDetail.gridCell, gridDataDetail: gridStore.selectedGridCellAndDataDetail.gridDataDetail, extData: gridStore.selectedGridCellAndDataDetail.extData }; - // console.log(gridStore.selectedGridCellAndDataDetail); - - // return undefined; - // return gridStore.selectedGridCellAndDataDetail; } else { return undefined; } @@ -158,6 +148,7 @@ () => gridStore.selectedGridCellAndDataDetail, (nv, ov) => { if (nv != ov) { + activeName.value = 'first'; dialogVisible.value = true; } }, @@ -165,10 +156,10 @@ ); </script> <style scoped> -:deep(.el-tabs__item){ +:deep(.el-tabs__item) { color: rgba(221, 221, 221, 0.806); } -:deep(.is-active){ +:deep(.is-active) { color: #f0ff1d; } </style> diff --git a/src/components/monitor/DataTable.vue b/src/components/monitor/DataTable.vue index c918ade..e7ad20d 100644 --- a/src/components/monitor/DataTable.vue +++ b/src/components/monitor/DataTable.vue @@ -268,7 +268,8 @@ <style> .el-table { --el-table-bg-color: transparent; - --el-table-row-hover-bg-color: var(--select_color); + --el-table-row-hover-bg-color: #bffff454; + /* --el-table-row-hover-bg-color: transparent; */ --el-table-current-row-bg-color: var(--select_color); /* --el-table-current-row-bg-color: #7dff5d96; */ --el-table-text-color: var(--font-color); diff --git a/src/components/search/OptionPollutionDegree.vue b/src/components/search/OptionPollutionDegree.vue new file mode 100644 index 0000000..f7a6dac --- /dev/null +++ b/src/components/search/OptionPollutionDegree.vue @@ -0,0 +1,40 @@ +<template> + <el-select + :model-value="modelValue" + @update:model-value="handleChange" + placeholder="姹℃煋鑳屾櫙" + size="small" + class="w-120" + > + <el-option + v-for="(s, i) in pollutionList" + :key="i" + :label="s.label" + :value="s.value" + /> + </el-select> +</template> + +<script> +import { pollutionList } from '@/constant/pollution-degree'; +export default { + props: { + modelValue: String + }, + emits: ['update:modelValue', 'initOver'], + data() { + return { + pollutionList: pollutionList() + }; + }, + methods: { + handleChange(value) { + this.$emit('update:modelValue', value); + } + }, + mounted() { + this.$emit('initOver'); + // this.handleChange(this.pollutionList[0].value); + } +}; +</script> diff --git a/src/constant/device-type.js b/src/constant/device-type.js index 1768fb0..350c85b 100644 --- a/src/constant/device-type.js +++ b/src/constant/device-type.js @@ -39,34 +39,8 @@ } } -// fixeme 2024.8.19 鍚庣画璁惧缂栧彿搴旇浠庢湇鍔″櫒鍔ㄦ�佽幏鍙栵紝鍚屾椂鏈夎澶囧彿鐨勫湪绾跨紪杈戝姛鑳� -function deviceList(type) { - if (import.meta.env.VITE_DATA_MODE == 'jingan') { - return [ - { - label: '杞﹁浇璁惧1鍙�', - value: 'TX105' - } - ]; - } else { - const t = type ? type : '0a'; - const _typeList = typeList(); - const typeStr = _typeList.find((v) => { - return v.value == t; - }); - return [1, 2, 3].map((v) => { - const label = `${typeStr.label}璁惧${v}鍙穈; - const value = `${t}000000000${v}`; - return { - label: label, - value: value - }; - }); - } -} - function typeName(type) { return typeList().find((v) => v.value == type).label; } -export { TYPE0, TYPE1, TYPE2, TYPE3, TYPE4, typeList, typeName, deviceList }; +export { TYPE0, TYPE1, TYPE2, TYPE3, TYPE4, typeList, typeName }; diff --git a/src/constant/pollution-degree.js b/src/constant/pollution-degree.js new file mode 100644 index 0000000..d5d6ead --- /dev/null +++ b/src/constant/pollution-degree.js @@ -0,0 +1,30 @@ +function pollutionList() { + return [ + { + label: '浼�', + value: 1 + }, + { + label: '鑹�', + value: 2 + }, + { + label: '杞诲害姹℃煋', + value: 3 + }, + { + label: '涓害姹℃煋', + value: 4 + }, + { + label: '閲嶅害姹℃煋', + value: 5 + } + ]; +} + +function pollutionName(type) { + return pollutionList().find((v) => v.value == type).label; +} + +export { pollutionList, pollutionName }; diff --git a/src/model/SatelliteGrid.js b/src/model/SatelliteGrid.js index e2ef06d..af3f0f7 100644 --- a/src/model/SatelliteGrid.js +++ b/src/model/SatelliteGrid.js @@ -1,3 +1,4 @@ +import { reactive } from 'vue'; import calculate from '@/utils/map/calculate'; import gridMapUtil from '@/utils/map/grid'; import { map, onMapMounted } from '@/utils/map/index_old'; @@ -18,14 +19,13 @@ // 榛樿鍦板浘缃戞牸鐩稿叧瀵硅薄 mapViews; - + gridState; gridDataDetail; // 鍦板浘缃戞牸瀵硅薄Map缁撴瀯锛屽瓨鍌ㄥ搴攌ey涓嬬殑缃戞牸瀵硅薄銆佺綉鏍煎潗鏍囦俊鎭� mapViewsMap = new Map(); - + // 鍦板浘缃戞牸瀵硅薄鐨勫弬鏁扮姸鎬� gridStateMap = new Map(); - // 缃戞牸鏁版嵁Map缁撴瀯锛屽瓨鍌ㄥ搴攌ey涓嬬殑缃戞牸鐩戞祴鏁版嵁淇℃伅 gridDataDetailMap = new Map(); @@ -273,7 +273,7 @@ map.remove(lastGridViews); } map.add(resGridViews); - // map.setFitView(resGridViews); + map.setFitView(resGridViews); return { resGridViews, pointsRes }; } @@ -288,13 +288,20 @@ // 缁樺埗缃戞牸閬ユ劅鏁版嵁鍊煎拰缃戞牸棰滆壊 drawGrid({ mapViews, + gridState, data, - grid = { useCustomColor: false, style: { opacity: 1, zIndex: 11 } }, + grid = { + useCustomColor: false, + style: { opacity: 1, zIndex: 11, isMixGridHighlight: false } + }, dataTxt = { isShow: false, useCustomColor: false, useColor: false }, rankTxt = { isShow: false } }) { + // 纭畾缁樺埗鐨勭綉鏍肩粍鍙婂叾鍙傛暟瀵硅薄 const _mapViews = mapViews ? mapViews : this.mapViews; - this.gridDataDetail = data; + const _gridState = gridState ? gridState : this.gridState; + + // 鏍规嵁缃戞牸鏁版嵁缁樺埗瀵瑰簲鐨勭綉鏍� const { resGridViews, pointsRes } = this.drawColor({ gridViews: _mapViews.gridViews, points: _mapViews.points, @@ -303,10 +310,17 @@ customColor: grid.useCustomColor, style: grid.style }); + // 淇濆瓨鍦板浘缃戞牸鍥惧舰瀵硅薄鍜岀粡绾害瀵硅薄 _mapViews.lastGridViews = resGridViews; _mapViews.lastPoints = pointsRes; + // 鏇存柊缃戞牸鐘舵�佸弬鏁� + _gridState.showGrid = true; + _gridState.showGridCustomColor = false; + _gridState.gridOpacityValue = grid.style.opacity; + _gridState.gridZIndex = grid.style.zIndex; + _gridState.highlightFusionGrid = grid.style.isMixGridHighlight; - // 鏁版嵁鏍囪 + // 缁樺埗鏁版嵁鏂囨湰 const { textViews: dtv } = this.drawDataText( _mapViews.lastPoints, data, @@ -315,7 +329,12 @@ dataTxt.useColor ); _mapViews.dataTxt = dtv; + // 鏇存柊鏁版嵁鏂囨湰鐘舵�佸弬鏁� + _gridState.showData = dataTxt.isShow; + _gridState.showDataColor = dataTxt.useColor; + _gridState.showDataCustomColor = dataTxt.useCustomColor; + // 缁樺埗鎺掑悕鏂囨湰 const { textViews: rtv } = this.drawRankText( _mapViews.lastPoints, data, @@ -323,6 +342,8 @@ _mapViews.rankLayer ); _mapViews.rankTxt = rtv; + // 鏇存柊鎺掑悕鏂囨湰鐘舵�佸弬鏁� + _gridState.showRank = rankTxt.isShow; if (dataTxt.isShow) { map.add(_mapViews.dataTxt); @@ -350,13 +371,16 @@ if (!this.mapViewsMap.has(tag)) { const newMapViews = this._createNewMapViews({ extData }); const newGridState = this._createNewGridState({ extData }); - this.gridStateMap.set(tag, newGridState); this.mapViewsMap.set(tag, newMapViews); + map.on('zoomend', newMapViews.mapZoomEvent); + this.gridStateMap.set(tag, newGridState); this.gridDataDetailMap.set(tag, data); } const _mapViews = this.mapViewsMap.get(tag); + const _gridState = this.gridStateMap.get(tag); this.drawGrid({ mapViews: _mapViews, + gridState: _gridState, data, grid, dataTxt, @@ -364,6 +388,10 @@ }); } + /** + * 鏍规嵁鏍囩鍒犻櫎瀵瑰簲鐨勭綉鏍硷紝鍚屾椂绉婚櫎鍦板浘缂╂斁浜嬩欢绛� + * @param {*} tags 缃戞牸鏍囩鏁扮粍 + */ deleteTagGrid(tags) { this.changeVisibility({ tags, @@ -372,6 +400,8 @@ showRankTxt: false }); tags.forEach((t) => { + const { mapZoomEvent } = this.mapViewsMap.get(t); + map.off('zoomend', mapZoomEvent); this.mapViewsMap.delete(t); this.gridDataDetailMap.delete(t); this.gridStateMap.delete(t); @@ -380,61 +410,56 @@ // 璋冩暣鍚勭被鍦板浘瑕嗙洊鐗╃殑鍙鎬� changeVisibility({ tags = [], showGridViews, showDataTxt, showRankTxt }) { - let { _mapViewsList } = this._getMapViews(...tags); + let { _mapViewsList, _gridStateList } = this._getMapViews(...tags); if (showGridViews != undefined) { if (showGridViews) { - // map.add(this.mapViews.lastGridViews); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.lastGridViews) { map.add(v.lastGridViews); - v.show = true; + _gridStateList[i].showGrid = true; } }); } else { - // map.remove(this.mapViews.lastGridViews); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.lastGridViews) { map.remove(v.lastGridViews); - v.show = false; + _gridStateList[i].showGrid = false; + _gridStateList[i].showHeatMap = false; } }); } } if (showDataTxt != undefined) { if (showDataTxt) { - // map.add(this.mapViews.dataTxt); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.dataTxt) { map.add(v.dataTxt); - v.showData = true; + _gridStateList[i].showData = true; } }); } else { - // map.remove(this.mapViews.dataTxt); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.dataTxt) { map.remove(v.dataTxt); - v.showData = false; + _gridStateList[i].showData = false; } }); } } if (showRankTxt != undefined) { if (showRankTxt) { - // map.add(this.mapViews.rankTxt); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.rankTxt) { map.add(v.rankTxt); - v.showRank = true; + _gridStateList[i].showRank = true; } }); } else { - // map.remove(this.mapViews.rankTxt); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.rankTxt) { map.remove(v.rankTxt); - v.showRank = false; + _gridStateList[i].showRank = false; } }); } @@ -442,9 +467,11 @@ } changeGridOpacity({ tag, isOpacity, opacityValue }) { - let { _mapViewsList } = tag ? this._getMapViews(tag) : this._getMapViews(); + let { _mapViewsList, _gridStateList } = tag + ? this._getMapViews(tag) + : this._getMapViews(); - _mapViewsList.forEach((v) => { + _mapViewsList.forEach((v, i) => { if (v.lastGridViews) { v.lastGridViews.forEach((e) => { e.setOptions({ @@ -456,6 +483,7 @@ : 0.7 }); }); + _gridStateList[i].gridOpacityValue = opacityValue; } }); } @@ -468,19 +496,26 @@ zIndex, isMixGridHighlight }) { - let { _mapViewsList, _gridDataDetailList } = this._getMapViews(...tags); + let { _mapViewsList, _gridDataDetailList, _gridStateList } = + this._getMapViews(...tags); if (_mapViewsList.length == _gridDataDetailList.length) { _mapViewsList.forEach((v, i) => { if (v.lastGridViews) { - if (useCustomColor != undefined) v.showCustomColor = useCustomColor; const lastGridDataDetail = _gridDataDetailList[i]; - if (v.showCustomColor) { + const _gridState = _gridStateList[i]; + if (useCustomColor != undefined) + _gridState.showGridCustomColor = useCustomColor; + if (useCustomColor) { gridMapUtil.drawGridColorCustom( v.lastGridViews, lastGridDataDetail, factorName ? factorName : this.selectedFactorType.name ); } else { + if (opacity != undefined) _gridState.gridOpacityValue = opacity; + if (zIndex != undefined) _gridState.gridZIndex = zIndex; + if (isMixGridHighlight != undefined) + _gridState.highlightFusionGrid = isMixGridHighlight; gridMapUtil.drawGridColor( v.lastGridViews, lastGridDataDetail, @@ -578,83 +613,6 @@ * 閲嶅彔鐨勭綉鏍艰繘琛岀洃娴嬫暟鎹潎鍊艰绠楀苟閲嶆柊璁$畻瀵瑰簲棰滆壊锛屽舰鎴愭柊鐨勪竴缁勮瀺鍚堢綉鏍� * @param {Array} tags 闇�瑕佽瀺鍚堢殑缃戞牸鏍囩锛屽綋涓虹┖鏃讹紝榛樿铻嶅悎鎵�鏈夌綉鏍� */ - mixGrid({ tags, isMixGridHighlight = true }) { - tags.sort((a, b) => { - return a < b ? -1 : 1; - }); - const mixTag = tags.join('-'); - if (this.mapViewsMap.has(mixTag)) { - this.changeVisibility({ - tags: [mixTag], - showGridViews: true - }); - this.changeGridColor({ tags: [mixTag], isMixGridHighlight }); - } else { - // 鏍规嵁鏍囩tag锛岃幏鍙栧搴斿缁勭綉鏍兼暟鎹� - let { _gridDataDetailList } = this._getMapViews(...tags); - const _dataMap = new Map(); - // 灏嗘瘡缁勬瘡涓綉鏍兼暟鎹寜鐓х綉鏍肩紪鍙疯繘琛屽垎绫伙紝鐩稿悓缃戞牸鐨勬暟缁勫綊闆嗚嚦涓�璧� - _gridDataDetailList.forEach((list) => { - list.forEach((gdd) => { - if (!_dataMap.has(gdd.cellId)) { - _dataMap.set(gdd.cellId, { - source: [], - res: {} - }); - } - _dataMap.get(gdd.cellId).source.push(gdd); - }); - }); - // 璁$畻姣忎釜缃戞牸涓嬬殑鏁版嵁鍧囧�� - const resGridDataDetail = []; - _dataMap.forEach((v, k) => { - let total = 0, - count = v.source.length; - v.source.forEach((s) => { - total += s.pm25; - }); - v.res = { - isMixData: true, - groupId: v.source[0].groupId, - cellId: v.source[0].cellId, - pm25: count == 0 ? null : Math.round((total / count) * 10) / 10, - originData: v.source - }; - // 鏁版嵁閲忚秴杩�1涓椂锛岃〃鏄庤缃戞牸鏁版嵁鏄瀺鍚堢殑锛屽睍绀洪珮浜殑鏍峰紡 - if (count > 1) { - v.res.gridStyle = { - strokeWeight: 2, - strokeColor: '#23dad1' - }; - } - resGridDataDetail.push(v.res); - }); - // 閲嶆柊鎸夌収鐩戞祴鏁版嵁鎺掑簭骞舵爣璁版帓鍚� - resGridDataDetail.sort((a, b) => { - return b.pm25 - a.pm25; - }); - resGridDataDetail.forEach((gdd, i) => { - gdd.rank = i + 1; - }); - - this.drawTagGrid({ - tag: mixTag, - data: resGridDataDetail, - grid: { - style: { - isMixGridHighlight - } - }, - extData: { - name: `璧拌埅铻嶅悎 - ${mixTag}`, - type: 1 - } - }); - } - - return mixTag; - } - mixGrid2({ tags, isMixGridHighlight = true, gridDataDetailList }) { tags.sort((a, b) => { return a < b ? -1 : 1; @@ -696,6 +654,9 @@ drawHeatGrid2(tag, headGridDataDetailList) { const heatTag = `heat-${tag}`; + if (this.gridStateMap.has(tag)) { + this.gridStateMap.get(tag).showHeatMap = true; + } if (this.mapViewsMap.has(heatTag)) { this.changeVisibility({ tags: [heatTag], @@ -834,12 +795,14 @@ _getMapViews(...tags) { let _mapViewsList = [], - _gridDataDetailList = []; + _gridDataDetailList = [], + _gridStateList = []; if (tags.length > 0) { tags.forEach((tag) => { if (this.mapViewsMap.has(tag) && this.gridDataDetailMap.has(tag)) { _mapViewsList.push(this.mapViewsMap.get(tag)); _gridDataDetailList.push(this.gridDataDetailMap.get(tag)); + _gridStateList.push(this.gridStateMap.get(tag)); } }); } else { @@ -849,16 +812,20 @@ this.gridDataDetailMap.forEach((v) => { _gridDataDetailList.push(v); }); - if (this.mapViews && this.gridDataDetail) { + this.gridStateMap.forEach((v) => { + _gridStateList.push(v); + }); + if (this.mapViews && this.gridDataDetail && this.gridState) { _mapViewsList.push(this.mapViews); _gridDataDetailList.push(this.gridDataDetail); + _gridStateList.push(this.gridState); } } - return { _mapViewsList, _gridDataDetailList }; + return { _mapViewsList, _gridDataDetailList, _gridStateList }; } - _createNewMapViews({ extData }) { + _createNewMapViews({ tag, extData }) { return { gridViews: gridMapUtil.drawPolylines({ points: this.mapViews.gridPoints, @@ -867,22 +834,50 @@ gridPoints: JSON.parse(JSON.stringify(this.mapViews.gridPoints)), points: JSON.parse(JSON.stringify(this.mapViews.points)), extData, - show: true + show: true, + mapZoomEvent: () => { + const zoomLevel = map.getZoom(); + if (zoomLevel >= 16.5) { + this.changeGridOpacity({ tag, opacityValue: 0.1 }); + } else { + this.changeGridOpacity({ tag, opacityValue: 1 }); + } + // console.log('mapZoomEvent', map.getZoom()); + } }; } _createNewGridState({ extData }) { return { - type: undefined, - name: '', - showGrid: true, - showRank: false, - showData: false, - showCustomColor: false, + // 缃戞牸鍚嶇О + name: extData.name, + // 缃戞牸绫诲瀷锛�0锛氳蛋鑸綉鏍硷紱1锛氳蛋鑸瀺鍚堢綉鏍硷紱2锛氳蛋鑸儹鍔涘浘 + type: extData.type, + // 缃戞牸鐩稿叧鍙傛暟 + showGrid: true, // 鏄惁鏄剧ず缃戞牸 + showGridCustomColor: false, // 鏄惁鏄剧ず瀵规瘮鑹� + gridOpacityValue: 1, // 缃戞牸閫忔槑搴� + gridZIndex: 11, // 缃戞牸z杞撮珮搴� + + // 鎺掑悕鏂囨湰鐩稿叧鍙傛暟 + showRank: false, // 鎺掑悕鏂囨湰鏄惁鏄剧ず + + // 鏁版嵁鏂囨湰鐩稿叧鍙傛暟 + showData: false, // 鏁版嵁鏂囨湰鏄惁鏄剧ず + showDataColor: false, // 鏁版嵁鏂囨湰鏄惁浣跨敤瀵瑰簲鐩戞祴鍥犲瓙鐨勬爣鍑嗛鑹� + showDataCustomColor: false, // 鏁版嵁鏂囨湰鏄惁浣跨敤瀵瑰簲鐩戞祴鍥犲瓙鐨勫姣旈鑹� + + // 鏄惁鏄剧ず瀵瑰簲鐑姏鍥� showHeatMap: false, + + // 濡傛灉鏄瀺鍚堢綉鏍硷紝鏄惁楂樹寒鏄剧ず閲嶅彔缃戞牸 highlightFusionGrid: false, + + // 濡傛灉鏄櫘閫氱殑璧拌埅缃戞牸锛屾槸鍚︽樉绀哄搴旂殑璧拌埅杞ㄨ抗 showUnderway: false, - opacityValue: 1 + + // 鍙兘鐨勮嚜瀹氫箟棰濆鏁版嵁 + extData }; } } diff --git a/src/stores/fusion-data.js b/src/stores/fusion-data.js new file mode 100644 index 0000000..ac4d502 --- /dev/null +++ b/src/stores/fusion-data.js @@ -0,0 +1,60 @@ +// import { ref } from 'vue'; +// import { defineStore } from 'pinia'; +// import gridApi from '@/api/gridApi'; +// import { useFetchData } from '@/composables/fetchData'; + +// // 璧拌埅浠诲姟 +// export const useMissionStore = defineStore('mission', () => { +// const missionList = ref([]); +// const { loading, fetchData } = useFetchData(1000); + +// function fetchMission(type) { +// return fetchData((page, pageSize) => { +// return missionApi +// .fethchMission({ type: type, page, pageSize }) +// .then((res) => { +// missionList.value = res.data; +// return res; +// }); +// }); +// } + +// function fetchFusionData() { +// return fetchData((page, pageSize) => { +// missionApi +// .fethchMission({ type: type, page, pageSize }) +// .then((res) => { +// missionList.value = res.data; +// return res; +// }); + +// return gridApi +// .fetchGridData(props.groupId, undefined, 3) +// .then((res) => { +// fusionDataList.value = res.data; +// }) +// .finally(() => (fusionLoading.value = false)); +// }); +// } + +// function deleteMission(missionCode) { +// return fetchData(() => { +// return missionApi.deleteMission(missionCode).then((res) => { +// let index = -1; +// for (let i = 0; i < missionList.value.length; i++) { +// const e = missionList.value[i]; +// if (e.missionCode == missionCode) { +// index = i; +// break; +// } +// } +// if (index != -1) { +// missionList.value.splice(index, 1); +// } +// return res; +// }); +// }); +// } + +// return { missionList, loading, fetchMission, deleteMission }; +// }); diff --git a/src/styles/elementUI.scss b/src/styles/elementUI.scss index e1d1401..96cfa18 100644 --- a/src/styles/elementUI.scss +++ b/src/styles/elementUI.scss @@ -20,12 +20,12 @@ } .el-button-custom-light { - --el-button-bg-color: var(--font-color); - --el-button-text-color: var(--bg-color); + --el-button-bg-color: var(--select_color); + // --el-button-text-color: var(--bg-color); // --el-button-hover-text-color: var(--bg-color); // --el-button-hover-bg-color: var(--font-color); - --el-button-hover-bg-color: var(--select_color); - --el-button-border-color: var(--bg-color); + --el-button-hover-bg-color: transparent; + --el-button-border-color: var(--font-color); --el-button-active-border-color: transparent; } diff --git a/src/views/underwaymix/UnderwayMixMode.vue b/src/views/underwaymix/UnderwayMixMode.vue index fed5590..0fae038 100644 --- a/src/views/underwaymix/UnderwayMixMode.vue +++ b/src/views/underwaymix/UnderwayMixMode.vue @@ -158,6 +158,14 @@ > {{ '铻嶅悎鍒嗘瀽' }} </el-button> + <el-button + type="primary" + class="el-button-custom" + size="small" + @click="underwayMixDialogVisible = true" + > + {{ '铻嶅悎绠$悊' }} + </el-button> <!-- <CheckButton active-text="铻嶅悎鍒嗘瀽" :default-value="false" @@ -180,12 +188,21 @@ <!-- </el-row> --> </el-col> </el-row> - <GridStyleTool - :gridCtrls="gridCtrls" - @show-underway="handleUnderwayClick" - @on-delete="handleFusionDelete" - ></GridStyleTool> </el-row> + <GridStyleTool + class="style-tool" + :gridCtrls="gridCtrls" + @show-underway="handleUnderwayClick" + @on-delete="handleFusionDelete" + ></GridStyleTool> + <!-- <el-row class="m-t-2"> + <FactorLegend class="m-t-2" @change="handleLegendTypeChange"></FactorLegend> + </el-row> --> + <UnderwayMixManage + :groupId="groupId" + v-model="underwayMixDialogVisible" + @onUpdated="fetchFusionData" + ></UnderwayMixManage> <!-- </div> --> </template> @@ -194,12 +211,14 @@ import moment from 'moment'; import gridApi from '@/api/gridApi'; import { SatelliteGrid } from '@/model/SatelliteGrid'; -import GridStyleTool from './component/GridStyleTool.vue'; import { useGridStore } from '@/stores/grid-info'; import { TYPE0 } from '@/constant/device-type'; import { defaultOptions } from '@/constant/radio-options'; import { useMessageBox } from '@/composables/messageBox'; import { useCloned } from '@vueuse/core'; + +import GridStyleTool from './component/GridStyleTool.vue'; +import UnderwayMixManage from './component/UnderwayMixManage.vue'; const gridStore = useGridStore(); @@ -210,7 +229,7 @@ const props = defineProps({ groupId: { type: Number, - default: 3 + default: 2 } }); const show = ref(true); @@ -218,14 +237,18 @@ // 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙� const factorType = ref(defaultOptions(TYPE0)); satelliteGrid.setShowFactorType(toRaw(factorType.value)); +// const factor = computed(()=>{ + +// }) function handleFactorTypeChange(e, item) { factorType.value = item; - console.log(toRaw(factorType.value)); + // console.log(toRaw(factorType.value)); satelliteGrid.setShowFactorType(toRaw(factorType.value)); } const mission = ref(undefined); +const underwayMixDialogVisible = ref(false); const gridCellList = ref(undefined); const fusionData = ref(undefined); @@ -393,38 +416,8 @@ .finally(() => (fusionLoading.value = false)); } -// 妫�鏌ヨ蛋鑸暟鎹槸鍚﹀拰100绫崇綉鏍煎凡铻嶅悎 -// function checkUnderwayFusionResult() { -// const time = moment(mission.value.startTime).format('YYYY-MM-DD HH:mm:ss'); -// gridApi.fetchGridData(props.groupId, time, 3).then((res) => { -// if (res.data.length > 0) { -// fusionData.value = res.data[0]; -// } else { -// fusionData.value = undefined; -// } -// }); -// } - function prepareGrid(gridInfo) { - satelliteGrid.gridPrepare(gridInfo, function (polygon) { - // const originOption = polygon.getOptions(); - // //榧犳爣绉诲叆浜嬩欢 - // polygon.on('mouseover', () => { - // polygon.setOptions({ - // //淇敼澶氳竟褰㈠睘鎬х殑鏂规硶 - // strokeWeight: 2, - // strokeColor: 'red' - // }); - // }); - // //榧犳爣绉诲嚭浜嬩欢 - // polygon.on('mouseout', () => { - // // polygon.setOptions({ - // // strokeWeight: originOption.strokeWeight, - // // strokeColor: originOption.strokeColor - // // }); - // polygon.setOptions(originOption); - // }); - }); + satelliteGrid.gridPrepare(gridInfo); } watch( @@ -462,7 +455,7 @@ tag: d.id, data: gdd, extData: { - name: `璧拌埅缃戞牸 - ${d.mixDataId}`, + name: `璧拌埅缃戞牸 - ${d.missionCode}`, type: 0 } }); @@ -523,7 +516,7 @@ } else { const d = fusionDataList.value.find((v) => v.id == dataId); const mission = missionStore.missionList.find((v) => { - return v.missionCode == d.mixDataId; + return v.missionCode == d.missionCode; }); mapLine.hideLine(mission.missionCode); done(); @@ -578,7 +571,7 @@ tag: d.id, data: gdd, extData: { - name: `璧拌埅缃戞牸 - ${d.mixDataId}`, + name: `璧拌埅缃戞牸 - ${d.missionCode}`, type: 0 } }); @@ -602,7 +595,7 @@ tag: d.id, data: gdd, extData: { - name: `璧拌埅缃戞牸 - ${d.mixDataId}`, + name: `璧拌埅缃戞牸 - ${d.missionCode}`, type: 0 } }); @@ -679,7 +672,7 @@ if (isUnmounted.value) return Promise.resolve(); const d = fusionDataList.value.find((v) => v.id == dataId); const mission = missionStore.missionList.find((v) => { - return v.missionCode == d.mixDataId; + return v.missionCode == d.missionCode; }); if (factorDataMap.has(mission.missionCode)) { @@ -707,6 +700,12 @@ } </script> <style scoped> +.style-tool { + position: absolute; + top: 0; + right: 0; +} + :deep(.el-table) { --el-table-bg-color: transparent; --el-table-row-hover-bg-color: var(--select_color); diff --git a/src/views/underwaymix/component/GridStyleTool.vue b/src/views/underwaymix/component/GridStyleTool.vue index 0c5b79d..bfa9951 100644 --- a/src/views/underwaymix/component/GridStyleTool.vue +++ b/src/views/underwaymix/component/GridStyleTool.vue @@ -9,135 +9,142 @@ ></CardButton> </el-row> </el-col> + <el-col span="2"> <BaseCard v-show="show" direction="right" borderless="r"> <template #content> <el-scrollbar class="content-wrap"> - <div v-for="(g, i) in gridCtrlList" :key="i"> - <span>{{ g.name }}</span> - <div v-for="(value, t) in g.views" :key="t"> - <el-row justify="space-between" align="middle"> - <div> - <span v-if="value.extData.type == 0">{{ - value.tag + '.' - }}</span> - {{ value.extData.name }} - </div> - <el-button - class="el-button-custom" - type="primary" - icon="Close" - circle - size="small" - @click="handleCloseClick(i, t, value)" - /> - <!-- <el-icon><Close /></el-icon> --> - </el-row> + <el-tabs + class="grid-ctrl-card" + v-model="activeGridCtrl" + type="border-card" + > + <el-tab-pane + v-for="(g, i) in gridCtrlList" + :key="g.name" + :label="g.name" + :name="i" + > + <el-tabs v-model="activeGrid"> + <el-tab-pane + v-for="(grid, y) in g.views" + :key="y" + :label="grid.name" + :name="y" + > + <div v-for="(value, t) in grid.views" :key="t"> + <el-row justify="space-between" align="middle"> + <div> + <span v-if="value.type == 0">{{ + value.tag + '.' + }}</span> + {{ value.name }} + </div> + <el-button + class="el-button-custom" + type="primary" + icon="Close" + circle + size="small" + @click="handleCloseClick(i, y, t, value)" + /> + </el-row> - <!-- {{ key }} --> - <!-- <el-text>{{ g.name }}</el-text> --> - <!-- <div class="m-t-8">缃戞牸瑕佺礌</div> --> - <el-row class="m-t-8" justify="space-between"> - <!-- <el-button - type="primary" - class="el-button-custom" - size="small" - @click="gridLoading = !gridLoading" - > - {{ '铻嶅悎鍒嗘瀽' }} - </el-button> --> - <CheckButton - :loading="gridLoading" - v-model="value.show" - active-text="鏄剧ず缃戞牸" - inactive-text="闅愯棌缃戞牸" - @change="(e) => handleGridClick(e, i, value)" - > - </CheckButton> - <CheckButton - :loading="rankLoading" - v-model="value.showRank" - active-text="鏄剧ず鎺掑悕" - inactive-text="闅愯棌鎺掑悕" - :default-value="false" - @change="(e) => handleRankClick(e, i, value)" - > - </CheckButton> - <CheckButton - :loading="dataLoading" - v-model="value.showData" - active-text="鏄剧ず鏁版嵁" - inactive-text="闅愯棌鏁版嵁" - :default-value="false" - @change="(e) => handleDataClick(e, i, value)" - > - </CheckButton> - </el-row> - <el-row class="m-t-8" justify="space-between"> - <CheckButton - :loading="colorLoading" - v-model="value.showCustomColor" - active-text="缁樺埗瀵规瘮鑹�" - inactive-text="缁樺埗鏍囧噯鑹�" - :default-value="false" - @change="(e) => handleColorClick(e, i, value)" - > - </CheckButton> - <CheckButton - :loading="heatMapLoading" - v-model="value.showHeatMap" - active-text="椋庨櫓鐑姏鍥�" - inactive-text="椋庨櫓鐑姏鍥�" - :default-value="false" - @change="(e) => handleHeatMapClick(e, i, value)" - > - </CheckButton> - <CheckButton - :loading="underwayLoading" - v-if="value.extData.type == 0" - v-model="value.showUnderway" - active-text="鏄剧ず璧拌埅杞ㄨ抗" - inactive-text="闅愯棌璧拌埅杞ㄨ抗" - :default-value="false" - @change="(e) => handleUnderwayClick(e, i, value)" - > - </CheckButton> - <CheckButton - :loading="highlightLoading" - v-if="value.extData.type == 1" - v-model="value.highlightFusionGrid" - active-text="楂樹寒铻嶅悎缃戞牸" - :default-value="true" - @change="(e) => handleHighlightGridClick(e, i, value)" - > - </CheckButton> - </el-row> - <!-- <el-row class="m-b-8" align="middle"> --> - <el-form-item label="閫忔槑搴�"> - <!-- <div class="m-t-8">缃戞牸閫忔槑搴�</div> --> - <el-slider - v-model="value.opacityValue" - :min="0" - :max="1" - :step="0.1" - show-stops - @change="(e) => handleOpacityChange(e, i, value)" - style="width: 150px" - /> - <el-input-number - class="m-l-16" - size="small" - v-model="value.opacityValue" - :min="0" - :max="1" - :step="0.1" - @change="(e) => handleOpacityChange(e, i, value)" - /> - </el-form-item> - <!-- </el-row> --> - <el-divider /> - </div> - </div> + <el-row class="m-t-8" justify="space-between"> + <CheckButton + :loading="gridLoading" + v-model="value.showGrid" + active-text="鏄剧ず缃戞牸" + inactive-text="闅愯棌缃戞牸" + @change="(e) => handleGridClick(e, i, value)" + > + </CheckButton> + <CheckButton + :loading="rankLoading" + v-if="value.type != 2" + v-model="value.showRank" + active-text="鏄剧ず鎺掑悕" + inactive-text="闅愯棌鎺掑悕" + :default-value="false" + @change="(e) => handleRankClick(e, i, value)" + > + </CheckButton> + <CheckButton + :loading="dataLoading" + v-model="value.showData" + active-text="鏄剧ず鏁版嵁" + inactive-text="闅愯棌鏁版嵁" + :default-value="false" + @change="(e) => handleDataClick(e, i, value)" + > + </CheckButton> + </el-row> + <el-row class="m-t-8" justify="space-between"> + <CheckButton + :loading="colorLoading" + v-model="value.showGridCustomColor" + active-text="缁樺埗瀵规瘮鑹�" + inactive-text="缁樺埗鏍囧噯鑹�" + :default-value="false" + @change="(e) => handleColorClick(e, i, value)" + > + </CheckButton> + <CheckButton + :loading="heatMapLoading" + v-if="value.type != 2" + v-model="value.showHeatMap" + active-text="椋庨櫓鐑姏鍥�" + inactive-text="椋庨櫓鐑姏鍥�" + :default-value="false" + @change="(e) => handleHeatMapClick(e, i, value)" + > + </CheckButton> + <CheckButton + :loading="underwayLoading" + v-if="value.type == 0" + v-model="value.showUnderway" + active-text="鏄剧ず璧拌埅杞ㄨ抗" + inactive-text="闅愯棌璧拌埅杞ㄨ抗" + :default-value="false" + @change="(e) => handleUnderwayClick(e, i, value)" + > + </CheckButton> + <CheckButton + :loading="highlightLoading" + v-if="value.type == 1" + v-model="value.highlightFusionGrid" + active-text="楂樹寒铻嶅悎缃戞牸" + :default-value="true" + @change="(e) => handleHighlightGridClick(e, i, value)" + > + </CheckButton> + </el-row> + <el-form-item label="閫忔槑搴�"> + <el-slider + v-model="value.gridOpacityValue" + :min="0" + :max="1" + :step="0.1" + show-stops + @change="(e) => handleOpacityChange(e, i, value)" + style="width: 150px" + /> + <el-input-number + class="m-l-16" + size="small" + v-model="value.gridOpacityValue" + :min="0" + :max="1" + :step="0.1" + @change="(e) => handleOpacityChange(e, i, value)" + /> + </el-form-item> + <el-divider /> + </div> + </el-tab-pane> + </el-tabs> + </el-tab-pane> + </el-tabs> </el-scrollbar> </template> </BaseCard> @@ -148,7 +155,15 @@ /** * 缃戞牸鏍峰紡鎺у埗宸ュ叿 */ -import { ref, reactive, onMounted, onUnmounted, computed, toRaw } from 'vue'; +import { + ref, + reactive, + onMounted, + onUnmounted, + watch, + computed, + toRaw +} from 'vue'; import gridApi from '@/api/gridApi'; import { useGridStore } from '@/stores/grid-info'; @@ -162,6 +177,9 @@ } }); +const activeGridCtrl = ref(0); +const activeGrid = ref(0); + const gridLoading = ref(false); const rankLoading = ref(false); const dataLoading = ref(false); @@ -172,34 +190,66 @@ const emits = defineEmits(['showUnderway', 'onDelete']); -const gridCtrlList = computed(() => { - return props.gridCtrls.map((g) => { - return reactive({ +const gridCtrlList = ref([]); + +const show = ref(false); + +watch( + () => props.gridCtrls, + (nV, oV) => { + if (nV) { + show.value = true; + refreshValue(); + } + } +); + +function refreshValue() { + gridCtrlList.value = props.gridCtrls.map((g) => { + const _tempMap = new Map(); + if (g.gridState) { + _tempMap.set('鍗槦缃戞牸', [g.gridState]); + } + Array.from(g.gridStateMap).map((v) => { + const key = girdTypeToName(v[1].type); + if (!_tempMap.has(key)) { + _tempMap.set(key, []); + } + _tempMap.get(key).push({ + tag: v[0], + ...v[1] + }); + }); + const res = { name: g.name, - views: Array.from(g.mapViewsMap).map((v) => { + views: Array.from(_tempMap).map((v) => { return { - tag: v[0], - extData: v[1].extData, - show: v[1].show, - showRank: v[1].showRank, - showData: v[1].showData, - showCustomColor: v[1].showCustomColor, - showHeatMap: v[1].showHeatMap, - highlightFusionGrid: true, - // ...v[1], - opacityValue: 1 + name: v[0], + views: reactive(v[1]) }; }) - }); + }; + console.log(res); + + return res; }); -}); +} -const show = ref(true); +function girdTypeToName(type) { + switch (type) { + case 0: + return '璧拌埅缃戞牸'; + case 1: + return '铻嶅悎缃戞牸'; + case 2: + return '鐑姏鍥�'; + } +} -function handleCloseClick(index, t, value) { +function handleCloseClick(index, y, t, value) { const key = value.tag; toRaw(props.gridCtrls[index]).deleteTagGrid([key]); - gridCtrlList.value[index].views.splice(t, 1); + gridCtrlList.value[index].views[y].views.splice(t, 1); emits('onDelete', index, key); } @@ -248,7 +298,7 @@ // value.opacityValue = e; toRaw(props.gridCtrls[index]).changeGridOpacity({ tag: key, - opacityValue: toRaw(value.opacityValue) + opacityValue: toRaw(value.gridOpacityValue) }); } @@ -263,7 +313,7 @@ function handleHighlightGridClick(e, index, value) { highlightLoading.value = true; - toRaw(props.gridCtrls[index]).mixGrid({ + toRaw(props.gridCtrls[index]).mixGrid2({ tags: value.tag.split('-'), isMixGridHighlight: e }); @@ -280,13 +330,6 @@ showDataTxt: false, showRankTxt: false }); - // gridCtrlList.value.forEach((v) => { - // v.views.forEach((view) => { - // view.show = false; - // view.showData = false; - // view.showRank = false; - // }); - // }); if (e) { const data = _satelliteGrid.gridDataDetailMap.get(value.tag); gridApi @@ -298,16 +341,7 @@ .then((res) => { heatTag = _satelliteGrid.drawHeatGrid2(value.tag, res.data); _satelliteGrid.setDefaultGridClickEvent([heatTag]); - // _satelliteGrid.setGridEvent( - // [heatTag], - // 'click', - // (gridCell, gridDataDetail) => { - // gridStore.selectedGridCellAndDataDetail = { - // gridCell, - // gridDataDetail - // }; - // } - // ); + refreshValue(); }) .finally(() => (heatMapLoading.value = false)); } else { @@ -316,6 +350,7 @@ showGridViews: true }); heatMapLoading.value = false; + refreshValue(); } } </script> @@ -331,4 +366,44 @@ :deep(.el-input-number) { width: 80px; } + +:deep(.el-tabs__item) { + color: rgba(221, 221, 221, 0.806); +} +:deep(.el-tabs__nav > .is-active) { + color: #f0ff1d; +} +:deep(.el-tabs--border-card) { + background: transparent; + border: 0px; +} + +:deep(.grid-ctrl-card > .el-tabs__content) { + padding: 0; +} +:deep(.grid-ctrl-card > .el-tabs__header) { + background: transparent; + border-bottom: 0px solid var(--el-border-color-light); +} +:deep( + .grid-ctrl-card + > .el-tabs__header + .el-tabs__nav-wrap + .el-tabs__nav-scroll + .el-tabs__nav + ) { + border: 1px solid var(--el-border-color-light); +} +:deep(.grid-ctrl-card > .el-tabs__header .el-tabs__item.is-active) { + color: var(--font-color); + background-color: transparent; + border-right-color: transparent; + border-left-color: transparent; +} +:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item) { + margin-top: 0px; +} +:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item:first-child) { + margin-left: 0px; +} </style> diff --git a/src/views/underwaymix/component/UnderwayMixEdit.vue b/src/views/underwaymix/component/UnderwayMixEdit.vue new file mode 100644 index 0000000..3867e31 --- /dev/null +++ b/src/views/underwaymix/component/UnderwayMixEdit.vue @@ -0,0 +1,197 @@ +<template> + <CardDialog + :title="dialogTitle" + :close-on-click-modal="!loading" + :model-value="modelValue" + @update:modelValue="(e) => $emit('update:modelValue', e)" + > + <el-form + :inline="false" + :model="formObj" + ref="formRef" + :rules="rules" + label-position="right" + label-width="100px" + > + <el-form-item label="鍖哄幙" prop="location"> + <OptionLocation2 + :disabled="true" + :level="3" + :initValue="false" + :checkStrictly="false" + :allOption="false" + v-model="formObj.location" + ></OptionLocation2> + </el-form-item> + <el-form-item label="浠诲姟缂栧彿" prop="missionCode"> + <el-input + :disabled="true" + size="small" + clearable + v-model="formObj.missionCode" + placeholder="浠诲姟缂栧彿" + class="w-150" + /> + </el-form-item> + <el-form-item label="鍖哄煙" prop="zone"> + <el-input + size="small" + clearable + v-model="formObj.zone" + placeholder="鍖哄煙" + class="w-150" + /> + </el-form-item> + <el-form-item label="姹℃煋鑳屾櫙" prop="pollutionDegreeIndex"> + <OptionPollutionDegree + v-model="formObj.pollutionDegreeIndex" + ></OptionPollutionDegree> + </el-form-item> + <el-form-item> + <el-button + :disabled="!edit" + type="primary" + @click="onSubmit" + :loading="loading" + >鎻愪氦</el-button + > + <el-button @click="onCancel" :disabled="loading">鍙栨秷</el-button> + </el-form-item> + </el-form> + </CardDialog> +</template> +<script setup> +import { ref, onMounted, reactive, computed, watch } from 'vue'; +import { useFormConfirm } from '@/composables/formConfirm'; +import { useFetchData } from '@/composables/fetchData'; +import gridApi from '@/api/gridApi'; +import { pollutionName } from '@/constant/pollution-degree'; + +const props = defineProps({ + modelValue: Boolean, + // 璧拌埅铻嶅悎缂栬緫妯″紡锛屾柊寤烘垨鏇存柊 + mode: { + type: String, + default: 'create' + }, + record: { + type: Object + }, + groupId: { + type: Number, + default: 2 + } +}); +const emits = defineEmits(['update:modelValue', 'onSubmit']); + +const dialogTitle = computed(() => { + return `${props.mode == 'create' ? '鐢熸垚' : '淇敼'}璧拌埅铻嶅悎璁板綍`; +}); + +const { loading, fetchData } = useFetchData(); +const { formObj, formRef, edit, onSubmit, onCancel } = useFormConfirm({ + submit: { + do: submitFusionRecord + }, + cancel: { + do: () => { + emits('update:modelValue', false); + } + } +}); +const rules = reactive({ + location: [ + { + required: true, + message: '鍖哄幙涓嶈兘涓虹┖', + trigger: 'change' + } + ], + missionCode: [ + { + required: true, + message: '浠诲姟缂栧彿涓嶈兘涓虹┖', + trigger: 'blur' + } + ], + zone: [ + { + required: true, + message: '鍖哄煙涓嶈兘涓虹┖', + trigger: 'change' + } + ], + pollutionDegreeIndex: [ + { + required: true, + message: '姹℃煋鑳屾櫙涓嶈兘涓虹┖', + trigger: 'change' + } + ] +}); + +const param = computed(() => { + return { + provinceCode: formObj.value.location.pCode, + provinceName: formObj.value.location.pName, + cityCode: formObj.value.location.cCode, + cityName: formObj.value.location.cName, + districtCode: formObj.value.location.dCode, + districtName: formObj.value.location.dName, + townCode: formObj.value.location.tCode, + townName: formObj.value.location.tName, + missionCode: formObj.value.missionCode, + // Fixme 2025.4.15: 缃戞牸缁刬d闇�瑕侀�氳繃鏈嶅姟鍣ㄥ姩鎬佽幏鍙� + groupId: props.groupId, + zone: formObj.value.zone, + pollutionDegreeIndex: formObj.value.pollutionDegreeIndex, + pollutionDegree: pollutionName(formObj.value.pollutionDegreeIndex) + }; +}); + +function submitFusionRecord() { + fetchData((page, pageSize) => { + return gridApi.buildUnderwayProduct(param.value).then((res) => { + emits('onSubmit', param.value.missionCode); + emits('update:modelValue', false); + }); + }); +} + +// 鐩戝惉浼犲叆鐨勮蛋鑸瀺鍚堜俊鎭紝鍦ㄦ洿鏂版ā寮忎笅锛屽皢铻嶅悎淇℃伅鏄犲皠鍒拌〃鍗曚笂 +watch( + () => props.record, + (nV, oV) => { + if (nV && nV != oV) { + const r = nV; + // 鍏抽棴瀵硅瘽妗嗘椂锛岀洿鎺ヨ繑鍥� + if (!props.modelValue) { + return; + } + formObj.value.location = { + pCode: r.provinceCode, + pName: r.provinceName, + cCode: r.cityCode, + cName: r.cityName, + dCode: r.districtCode, + dName: r.districtName, + tCode: r.townCode, + tName: r.townName + }; + formObj.value.missionCode = r.missionCode; + formObj.value.groupId = props.groupId; + formObj.value.zone = r.districtName; + formObj.value.pollutionDegreeIndex = undefined; + formObj.value.pollutionDegree = undefined; + + if (r.fusionData && props.mode == 'update') { + const f = r.fusionData; + formObj.value.groupId = f.groupId; + formObj.value.zone = f.zone; + formObj.value.pollutionDegreeIndex = f.pollutionDegreeIndex; + formObj.value.pollutionDegree = f.pollutionDegree; + } + } + } +); +</script> diff --git a/src/views/underwaymix/component/UnderwayMixManage.vue b/src/views/underwaymix/component/UnderwayMixManage.vue new file mode 100644 index 0000000..b77c4b8 --- /dev/null +++ b/src/views/underwaymix/component/UnderwayMixManage.vue @@ -0,0 +1,214 @@ +<template> + <CardDialog + v-bind="$attrs" + title="璧拌埅铻嶅悎绠$悊" + :model-value="modelValue" + @update:modelValue="handleDialogChange" + > + <el-row class="mission-table"> + <el-col :span="24"> + <el-table + :data="missionStore.missionList" + table-layout="fixed" + size="small" + :show-overflow-tooltip="true" + border + height="64vh" + row-class-name="t-row-normal" + cell-class-name="t-cell" + header-row-class-name="t-header-row" + header-cell-class-name="t-header-cell" + > + <el-table-column + type="index" + label="搴忓彿" + align="center" + width="50" + /> + <el-table-column prop="missionCode" label="浠诲姟缂栧彿" align="center" /> + <el-table-column + prop="startTime" + label="寮�濮嬫椂闂�" + align="center" + :formatter="timeFormatter" + width="150" + /> + <el-table-column + prop="endTime" + label="缁撴潫鏃堕棿" + align="center" + :formatter="timeFormatter" + width="150" + /> + <el-table-column label="铻嶅悎璁板綍" align="center" width="50"> + <template #default="{ row }"> + {{ row.fusionData ? '鏈�' : '鏃�' }} + </template> + </el-table-column> + <el-table-column label="绠$悊" width="160" align="center"> + <template #default="{ row }"> + <el-button + v-if="row.fusionData" + type="primary" + size="small" + icon="EditPen" + class="el-button-custom-light" + :loading="row.loading" + @click="updateFusionRecord(row)" + >鏇存柊璁板綍</el-button + > + <el-button + v-else + type="primary" + size="small" + icon="Plus" + class="el-button-custom" + :loading="row.loading" + @click="createFusionRecord(row)" + >铻嶅悎鐢熸垚</el-button + > + <el-button + v-if="row.fusionData" + type="primary" + size="small" + icon="Delete" + class="el-button-custom" + :disabled="row.loading" + @click="deleteFusionRecord(row)" + ></el-button> + </template> + </el-table-column> + </el-table> + </el-col> + </el-row> + </CardDialog> + <MessageBox + v-model="msgBoxVisible" + :on-confirm="onConfirm" + title="鍒犻櫎璧拌埅铻嶅悎" + msg="纭鏄惁鍒犻櫎璇ヨ蛋鑸瀺鍚�" + confirmText="鍒犻櫎" + ></MessageBox> + <UnderwayMixEdit + v-model="dialogVisible" + width="30%" + :group-id="groupId" + :mode="editMode" + :record="selectedFusionRecord" + @on-submit="refreshFusionRecord" + ></UnderwayMixEdit> +</template> +<script setup> +import { ref, watch, onMounted } from 'vue'; +import moment from 'moment'; +import gridApi from '@/api/gridApi'; +import { useMissionStore } from '@/stores/mission'; +import { useFetchData } from '@/composables/fetchData'; + +import UnderwayMixEdit from './UnderwayMixEdit.vue'; + +const props = defineProps({ + modelValue: Boolean, + groupId: { + type: Number, + default: 2 + } +}); + +const emits = defineEmits(['update:modelValue', 'onUpdated']); + +const { loading, fetchData } = useFetchData(); +const missionStore = useMissionStore(); + +const isEdited = ref(false); +const editMode = ref('create'); +const selectedFusionRecord = ref(undefined); +const dialogVisible = ref(false); +const msgBoxVisible = ref(false); +const onConfirm = ref(undefined); + +// eslint-disable-next-line no-unused-vars +function timeFormatter(row, col, cellValue, index) { + return moment(cellValue).format('YYYY-MM-DD HH:mm:ss'); +} + +// 鏌ヨ璧拌埅铻嶅悎璁板綍 +function fetchFusionRecord(row) { + row.loading = true; + gridApi + .fetchGridData2({ type: 3, missionCode: row.missionCode }) + .then((res) => { + // 璧拌埅缃戞牸铻嶅悎锛屽崟涓蛋鑸湪鍦ㄥ崟涓綉鏍肩粍涓彧鏈夊敮涓�璁板綍 + if (res.data.length > 0) { + row.fusionData = res.data[0]; + } else { + row.fusionData = undefined; + } + }) + .finally(() => (row.loading = false)); +} + +function createFusionRecord(row) { + editMode.value = 'create'; + selectedFusionRecord.value = row; + dialogVisible.value = true; + // row.loading = true; + // setTimeout(() => { + // row.loading = false; + // }, 1000); +} + +function updateFusionRecord(row) { + editMode.value = 'update'; + selectedFusionRecord.value = row; + dialogVisible.value = true; +} + +function deleteFusionRecord(row) { + this.onConfirm = () => { + gridApi.deleteGridData(row.fusionData.id).then((res) => { + if (res.data) { + refreshFusionRecord(row.missionCode); + } + }); + }; + this.msgBoxVisible = true; +} + +function refreshFusionRecord(missionCode) { + const m = missionStore.missionList.find((v) => v.missionCode == missionCode); + fetchFusionRecord(m); + isEdited.value = true; +} + +function handleDialogChange(e) { + emits('update:modelValue', e); + if (isEdited.value) { + emits('onUpdated'); + } +} + +watch( + () => props.modelValue, + (nV, oV) => { + if (nV) { + isEdited.value = false; + missionStore.missionList.forEach((v) => { + fetchFusionRecord(v); + }); + } + } +); +</script> +<style scoped> +.flex-col { + display: flex; + flex-direction: column; + gap: 4px; + align-items: flex-end; +} + +:deep(.t-row-normal) { + background-color: transparent !important; +} +</style> -- Gitblit v1.9.3