From 25570a9ecd9b10a865fd7ce2614410814aaf52eb Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期五, 28 三月 2025 17:54:40 +0800 Subject: [PATCH] 修复网格样式中删除一组数据后,表格没有联动的问题 --- src/views/underwaymix/UnderwayMixMode.vue | 775 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 772 insertions(+), 3 deletions(-) diff --git a/src/views/underwaymix/UnderwayMixMode.vue b/src/views/underwaymix/UnderwayMixMode.vue index a26096a..8c82db3 100644 --- a/src/views/underwaymix/UnderwayMixMode.vue +++ b/src/views/underwaymix/UnderwayMixMode.vue @@ -1,6 +1,775 @@ <template> - <div class="p-events-none m-t-2"></div> + <!-- <div class="p-events-none m-t-2"> --> + <el-row class="m-t-2"> + <FactorRadio @change="handleFactorTypeChange"></FactorRadio> + </el-row> + <el-row class="m-t-2" justify="space-between"> + <el-row class="wrap"> + <el-col span="2"> + <!-- <el-row> --> + <BaseCard v-show="show" size="medium" direction="left"> + <template #content> + <!-- <el-row> + <el-form :inline="true"> + + </el-form> + </el-row> --> + <el-row justify="space-between"> + <span>铻嶅悎鍒嗘瀽</span> + </el-row> + <el-form :inline="false"> + <el-form-item label="鏃舵绛涢��"> + <el-select + v-model="selectedTimeSection" + multiple + clearable + placeholder="閫夋嫨鏃舵" + size="small" + style="width: 300px" + > + <el-option + v-for="(v, i) in timeSectionList" + :key="i" + :label="v.label" + :value="v.value" + /> + </el-select> + </el-form-item> + <el-form-item label="鍖哄煙绛涢��"> + <el-select + v-model="selectedZone" + multiple + clearable + placeholder="閫夋嫨鍖哄煙" + size="small" + style="width: 300px" + > + <el-option + v-for="(v, i) in zoneList" + :key="i" + :label="v.label" + :value="v.value" + /> + </el-select> + </el-form-item> + <el-form-item label="鑳屾櫙绛涢��"> + <el-select + v-model="selectedPollutionDegree" + multiple + clearable + placeholder="閫夋嫨鑳屾櫙" + size="small" + style="width: 300px" + > + <el-option + v-for="(v, i) in pollutionDegreeList" + :key="i" + :label="v.label" + :value="v.value" + /> + </el-select> + </el-form-item> + </el-form> + <el-space v-if="!gridCellList"> + <el-icon class="is-loading"><Loading /></el-icon> + <el-text type="info">缃戞牸淇℃伅鍔犺浇涓�...</el-text> + </el-space> + <el-table + ref="tableRef" + :data="showFusionDataList" + table-layout="fixed" + size="small" + :show-overflow-tooltip="true" + border + height="45vh" + 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" + :highlight-current-row="false" + @row-click="handleRowClick" + @select="handleSelectionChange" + @select-all="handleSelectionChange" + > + <el-table-column width="40" v-if="!gridCellList"> + <template #default> + <el-icon class="is-loading"><Loading /></el-icon> + </template> + </el-table-column> + <el-table-column + v-else + type="selection" + :selectable="selectable" + width="40" + > + <!-- <template #header> + <span>閫夋嫨</span> + </template> --> + </el-table-column> + <!-- <el-table-column + type="index" + label="搴忓彿" + width="30" + /> --> + <el-table-column + prop="dataTime" + label="鏃堕棿" + align="center" + :formatter="timeFormatter" + width="100" + /> + <el-table-column + prop="missionCode" + label="浠诲姟缂栧彿" + align="center" + width="150" + /> + <el-table-column + prop="zone" + label="鍖哄煙" + align="center" + width="50" + /> + <el-table-column + prop="pollutionDegree" + label="姹℃煋鑳屾櫙" + align="center" + width="70" + /> + </el-table> + + <div class="m-t-8">鎿嶄綔</div> + <el-space class="m-t-8 m-b-8"> + <!-- <el-button + type="primary" + class="el-button-custom" + size="small" + :disabled="!gridCellList || selectedfusionData.length == 0" + @click="handleFusionClick" + > + {{ '鍙犲姞璧拌埅' }} + </el-button> --> + <el-button + type="primary" + class="el-button-custom" + size="small" + @click="handleMixClick" + > + {{ '铻嶅悎鍒嗘瀽' }} + </el-button> + <!-- <CheckButton + active-text="铻嶅悎鍒嗘瀽" + :default-value="false" + @change="handleMixClick" + > + </CheckButton> --> + </el-space> + </template> + <template #footer> </template> + </BaseCard> + <!-- </el-row> --> + </el-col> + <el-col span="2"> + <!-- <el-row> --> + <CardButton + name="璧拌埅铻嶅悎" + direction="right" + @click="() => (show = !show)" + ></CardButton> + <!-- </el-row> --> + </el-col> + </el-row> + <GridStyleTool + :gridCtrls="gridCtrls" + @show-underway="handleUnderwayClick" + @on-delete="handleFusionDelete" + ></GridStyleTool> + </el-row> + <!-- </div> --> </template> -<script setup></script> -<style scoped></style> +<script setup> +import { ref, toRaw, onMounted, onUnmounted, watch, computed } from 'vue'; +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'; + +const gridStore = useGridStore(); + +const satelliteGrid = new SatelliteGrid('璧拌埅铻嶅悎'); +const gridCtrls = ref([satelliteGrid]); + +// 鍊熺敤鍗槦閬ユ祴妯″潡涓殑100绫崇綉鏍� +const props = defineProps({ + groupId: { + type: Number, + default: 3 + } +}); +const show = ref(true); + +// 鐩戞祴鍥犲瓙鐨勭被鍨嬬紪鍙� +const factorType = ref(defaultOptions(TYPE0)); +satelliteGrid.setShowFactorType(toRaw(factorType.value)); + +function handleFactorTypeChange(e, item) { + factorType.value = item; + console.log(toRaw(factorType.value)); + satelliteGrid.setShowFactorType(toRaw(factorType.value)); +} + +const mission = ref(undefined); + +const gridCellList = ref(undefined); +const fusionData = ref(undefined); +// 璧拌埅铻嶅悎鏁版嵁 +const fusionLoading = ref(false); +const fusionDataList = ref([]); + +const lastSelectedfusionData = ref([]); +const selectedfusionData = ref([]); +const tableRef = ref(); +const selectable = (row) => gridCellList.value; + +const gridDataDetailMap = new Map(); + +const selectedTimeSection = ref([]); +const selectedZone = ref([]); +const selectedPollutionDegree = ref([]); + +const timeSectionList = computed(() => { + let res = []; + fusionDataList.value.forEach((e) => { + const hour = moment(e.dayTimePeriodStart).hour(); + const t = e.dayTimePeriod; + const option = { + label: `${t} ${moment(e.dayTimePeriodStart).format('HH:mm')} - ${moment(e.dayTimePeriodEnd).format('HH:mm')}`, + value: t, + index: hour + }; + if (!res.find((v) => v.label == option.label)) { + res.push(option); + } + }); + res.sort((a, b) => { + return a.index - b.index; + }); + + const rMap = new Map(); + showFusionDataList.value.forEach((d) => { + if (!rMap.has(d.dayTimePeriod)) { + rMap.set(d.dayTimePeriod, 0); + } + rMap.set(d.dayTimePeriod, rMap.get(d.dayTimePeriod) + 1); + }); + + res = res.map((v) => { + const count = rMap.get(v.value); + v.label = `${v.label} (${count ? count : 0})`; + return v; + }); + return res; +}); + +const zoneList = computed(() => { + let res = []; + fusionDataList.value.forEach((e) => { + const t = e.zone; + const option = { + label: t, + value: t + }; + if (!res.find((v) => v.label == option.label)) { + res.push(option); + } + }); + const rMap = new Map(); + showFusionDataList.value.forEach((d) => { + if (!rMap.has(d.zone)) { + rMap.set(d.zone, 0); + } + rMap.set(d.zone, rMap.get(d.zone) + 1); + }); + + res = res.map((v) => { + const count = rMap.get(v.value); + v.label = `${v.label} (${count ? count : 0})`; + return v; + }); + return res; +}); + +const pollutionDegreeList = computed(() => { + let res = []; + fusionDataList.value.forEach((e) => { + const t = e.pollutionDegree; + const option = { + label: t, + value: t, + index: e.pollutionDegreeIndex + }; + if (!res.find((v) => v.label == option.label)) { + res.push(option); + } + }); + res.sort((a, b) => { + return a.index - b.index; + }); + const rMap = new Map(); + showFusionDataList.value.forEach((d) => { + if (!rMap.has(d.pollutionDegree)) { + rMap.set(d.pollutionDegree, 0); + } + rMap.set(d.pollutionDegree, rMap.get(d.pollutionDegree) + 1); + }); + + res = res.map((v) => { + const count = rMap.get(v.value); + v.label = `${v.label} (${count ? count : 0})`; + return v; + }); + return res; +}); + +const showFusionDataList = computed(() => { + return fusionDataList.value.filter((v) => { + const b1 = + selectedTimeSection.value.length == 0 || + selectedTimeSection.value.indexOf(v.dayTimePeriod) != -1; + const b2 = + selectedZone.value.length == 0 || + selectedZone.value.indexOf(v.zone) != -1; + const b3 = + selectedPollutionDegree.value.length == 0 || + selectedPollutionDegree.value.indexOf(v.pollutionDegree) != -1; + + return b1 && b2 && b3; + }); +}); +// if ( +// selectedTimeSection.value.length == 0 && +// selectedZone.value.length == 0 && +// selectedPollutionDegree.value.length == 0 +// ) { +// return true; +// } else { +// const b1 = +// selectedTimeSection.value.indexOf( +// moment(v.dataTime).format('YYYY-MM-DD') +// ) != -1; +// const b2 = selectedZone.value.indexOf(v.zone) != -1; +// const b3 = selectedPollutionDegree.value.indexOf(v.pollutionDegree) != -1; + +// return b1 && b2 || b3; +// } + +const mixActive = ref(false); +const heatActive = ref(false); +const gridVisible = ref(true); +const underwayVisible = ref(false); +const rankVisible = ref(false); +const dataVisible = ref(false); +const isStandardColor = ref(true); +const isOpacity = ref(false); + +function timeFormatter(row, col, cellValue, index) { + return moment(cellValue).format('YYYY-MM-DD'); +} + +function fetchFusionData() { + fusionLoading.value = true; + gridApi + .fetchGridData(props.groupId, undefined, 3) + .then((res) => { + fusionDataList.value = res.data; + }) + .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); + // }); + }); +} + +watch( + () => props.groupId, + (nV, oV) => { + if (nV != oV) { + satelliteGrid.gridGroupId = nV; + gridApi.fetchGridCell(nV).then((res) => { + gridCellList.value = res.data; + prepareGrid(gridCellList.value); + }); + fetchFusionData(); + } + }, + { + immediate: true + } +); + +function handleFusionClick() { + // resetButton(); + satelliteGrid.changeVisibility({ showGridViews: false }); + selectedfusionData.value.forEach((i) => { + // const d = fusionDataList.value[i]; + const d = i; + if (gridDataDetailMap.has(d.id)) { + satelliteGrid.changeVisibility({ tags: [d.id], showGridViews: true }); + // gridCtrls.value = Array.from(satelliteGrid.mapViewsMap); + gridCtrls.value = [satelliteGrid]; + } else { + gridApi.fetchGridDataDetail(d.id, d.groupId).then((res) => { + gridDataDetailMap.set(d.id, res.data); + const gdd = res.data; + satelliteGrid.drawTagGrid({ + tag: d.id, + data: gdd, + extData: { + name: `璧拌埅缃戞牸 - ${d.mixDataId}`, + type: 0 + } + }); + satelliteGrid.setDefaultGridClickEvent([d.id]); + // satelliteGrid.setGridEvent( + // [d.id], + // 'click', + // (gridCell, gridDataDetail) => { + // gridStore.selectedGridCellAndDataDetail = { + // gridCell, + // gridDataDetail + // }; + // } + // ); + gridCtrls.value = [satelliteGrid]; + }); + } + }); +} + +let mixTag; +function handleMixClick() { + // mixActive.value = !mixActive.value; + const tags = selectedfusionData.value.map((v) => v.id); + satelliteGrid.changeVisibility({ + showGridViews: false, + showDataTxt: false, + showRankTxt: false + }); + // if (mixActive.value) { + gridApi.mixUnderwayGridData(props.groupId, tags).then((res) => { + mixTag = satelliteGrid.mixGrid2({ tags, gridDataDetailList: res.data }); + satelliteGrid.setDefaultGridClickEvent([mixTag]); + gridCtrls.value = [satelliteGrid]; + }); + + // satelliteGrid.setGridEvent([mixTag], 'click', (gridCell, gridDataDetail) => { + // gridStore.selectedGridCellAndDataDetail = { + // gridCell, + // gridDataDetail + // }; + // }); + // gridCtrls.value = [satelliteGrid]; + // } else { + // satelliteGrid.changeVisibility({ + // tags, + // showGridViews: true + // }); + // } +} + +let heatTag; +const heatMapSearchLength = 4; +function handleHeatMapClick() { + heatActive.value = !heatActive.value; + satelliteGrid.changeVisibility({ + showGridViews: false, + showDataTxt: false, + showRankTxt: false + }); + if (heatActive.value) { + const data = satelliteGrid.gridDataDetailMap.get(mixTag); + gridApi + .buildUnderwayHeatmap(props.groupId, data, heatMapSearchLength) + .then((res) => { + heatTag = satelliteGrid.drawHeatGrid2(mixTag, res.data); + satelliteGrid.setDefaultGridClickEvent([heatTag]); + gridCtrls.value = [satelliteGrid]; + }); + } else { + satelliteGrid.changeVisibility({ + tags: [mixTag], + showGridViews: true + }); + } +} + +function handleHeatMapSearchClick() { + const res = satelliteGrid.search( + { + groupId: 1, + cellId: 2893, + pm25: 50 + }, + 120, + 90, + 10, + 10, + 3 + ); + + console.log(res); +} + +function handleUnderwayClick({ isShow, dataId, done }) { + underwayVisible.value = !underwayVisible.value; + + if (isShow) { + draw(dataId).finally(() => done()); + } else { + const d = fusionDataList.value.find((v) => v.id == dataId); + const mission = missionStore.missionList.find((v) => { + return v.missionCode == d.mixDataId; + }); + mapLine.hideLine(mission.missionCode); + done(); + } +} +function handleFusionDelete(index, tag) { + const f = selectedfusionData.value.find((v) => v.id == tag); + if (f) { + // const i = selectedfusionData.value.indexOf(f); + // selectedfusionData.value.splice(i, 1); + tableRef.value.toggleRowSelection(f, false); + } +} + +function handleSelectionChange(val) { + console.log(val); + + const deleted = lastSelectedfusionData.value.filter((v) => { + return !val.find((t) => t.id == v.id); + }); + const deletedIdList = deleted.map((d) => d.id); + const added = val.filter((v) => { + return !lastSelectedfusionData.value.find((t) => t.id == v.id); + }); + + if (val.length > 4) { + useMessageBox({ + confirmMsg: '鏈�澶氬厑璁稿悓鏃跺睍绀�4娆¤蛋鑸褰�', + confirmTitle: '璧拌埅璁板綍閫夋嫨杩囧璀﹀憡' + }); + added.forEach((a) => { + tableRef.value.toggleRowSelection(a, false); + }); + return; + } + // const addedIdList = added.map(d=>d.id) + + if (deletedIdList.length > 0) { + satelliteGrid.deleteTagGrid(deletedIdList); + gridCtrls.value = [satelliteGrid]; + // satelliteGrid.changeVisibility({ tags: deletedIdList, showGridViews: false }); + } + + added.forEach((i) => { + const d = i; + if (gridDataDetailMap.has(d.id)) { + const gdd = gridDataDetailMap.get(d.id); + satelliteGrid.drawTagGrid({ + tag: d.id, + data: gdd, + extData: { + name: `璧拌埅缃戞牸 - ${d.mixDataId}`, + type: 0 + } + }); + satelliteGrid.setDefaultGridClickEvent([d.id]); + // satelliteGrid.setGridEvent( + // [d.id], + // 'click', + // (gridCell, gridDataDetail) => { + // gridStore.selectedGridCellAndDataDetail = { + // gridCell, + // gridDataDetail + // }; + // } + // ); + gridCtrls.value = [satelliteGrid]; + } else { + gridApi.fetchGridDataDetail(d.id, d.groupId).then((res) => { + gridDataDetailMap.set(d.id, res.data); + const gdd = res.data; + satelliteGrid.drawTagGrid({ + tag: d.id, + data: gdd, + extData: { + name: `璧拌埅缃戞牸 - ${d.mixDataId}`, + type: 0 + } + }); + satelliteGrid.setDefaultGridClickEvent([d.id]); + // satelliteGrid.setGridEvent( + // [d.id], + // 'click', + // (gridCell, gridDataDetail) => { + // gridStore.selectedGridCellAndDataDetail = { + // gridCell, + // gridDataDetail + // }; + // } + // ); + gridCtrls.value = [satelliteGrid]; + }); + } + }); + + lastSelectedfusionData.value = useCloned(val).cloned.value + selectedfusionData.value = val; +} + +/**璧拌埅杞ㄨ抗*******************************************************************/ +import { FactorDatas } from '@/model/FactorDatas'; +import sector from '@/utils/map/sector'; +import mapLine from '@/utils/map/line'; +import mapUtil from '@/utils/map/util'; +import { fetchHistoryData } from '@/utils/factor/data'; +import { useFetchData } from '@/composables/fetchData'; +import { useMissionStore } from '@/stores/mission'; + +onMounted(() => { + isUnmounted.value = false; + fetchMission(); +}); +onUnmounted(() => { + mapUtil.clearMap(); + isUnmounted.value = true; +}); +const { loading, fetchData } = useFetchData(10000); + +const missionStore = useMissionStore(); +const missionLoading = ref(false); + +const isUnmounted = ref(false); + +const drawMode = ref(0); +// 鐩戞祴鏁版嵁 +const factorDataMap = new Map(); + +function fetchMission() { + missionLoading.value = true; + missionStore.fetchMission().finally(() => (missionLoading.value = false)); +} + +function search(option) { + const { deviceType, deviceCode, startTime, endTime } = option; + const _startTime = moment(startTime).format('YYYY-MM-DD HH:mm:ss'); + const _endTime = moment(endTime).format('YYYY-MM-DD HH:mm:ss'); + return fetchData((page, pageSize) => { + return fetchHistoryData({ + deviceType, + deviceCode, + startTime: _startTime, + endTime: _endTime, + page, + perPage: pageSize + }); + }); +} + +function draw(dataId) { + 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; + }); + + if (factorDataMap.has(mission.missionCode)) { + const fd = factorDataMap.get(mission.missionCode); + fd.refreshHeight(factorType.value.value); + return Promise.resolve(drawLine(mission.missionCode, fd)); + } else { + return search(mission).then((res) => { + const fd = new FactorDatas(); + fd.setData(res.data, drawMode.value, () => { + fd.refreshHeight(factorType.value.value); + factorDataMap.set(mission.missionCode, fd); + drawLine(mission.missionCode, fd); + }); + }); + } +} + +function drawLine(missionCode, fd) { + // 鍒锋柊鍥句緥 + const factor = fd.factor[factorType.value.value]; + sector.clearSector(); + fd.refreshHeight(factorType.value.value); + mapLine.drawTagLine(missionCode, fd, factor); +} +</script> +<style scoped> +:deep(.el-table) { + --el-table-bg-color: transparent; + --el-table-row-hover-bg-color: var(--select_color); + --el-table-current-row-bg-color: var(--select_color); + /* --el-table-current-row-bg-color: #7dff5d96; */ + --el-table-text-color: var(--font-color); +} + +:deep(.t-row-normal) { + cursor: pointer; + background-color: transparent !important; +} + +:deep(.t-cell) { + /* background: red !important; */ + /* height: 40px; + border: 1px solid black; */ +} + +:deep(.t-header-row) { +} + +:deep(.t-header-cell) { + background-color: var(--bg-color-2) !important; + /* text-align: center !important; */ + color: white !important; +} +</style> -- Gitblit v1.9.3