From 84167d13f951358315d13609de426ebb318a3c9a Mon Sep 17 00:00:00 2001 From: gerson <1405270578@qq.com> Date: 星期日, 09 二月 2025 23:19:34 +0800 Subject: [PATCH] 面板样式调整 --- src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/panelTool/ThemeControl.vue | 370 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 357 insertions(+), 13 deletions(-) diff --git a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/panelTool/ThemeControl.vue b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/panelTool/ThemeControl.vue index c81f972..635553f 100644 --- a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/panelTool/ThemeControl.vue +++ b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/panelTool/ThemeControl.vue @@ -1,6 +1,6 @@ <template> - <div class="layer-control bg-white"> - <div class="w-[370px] bg-white p-3 rounded"> + <div class="layer-control bg-white flex-col" style="display: flex"> + <div class="bg-white rounded flex-0"> <div class="header flex-items-center pb-1.5" style="border-bottom: 1px solid black"> <div class="flex-items-center"> <span class="ywifont ywicon-guanbi cursor-pointer mr-1.5" @click="closeClick"></span> @@ -8,8 +8,8 @@ </div> </div> </div> - <div class="content rounded-lg max-h-[700px] overflow-y-auto min-h-[600px]"> - <el-tree + <div class="flex-auto content rounded-lg overflow-y-auto"> + <!-- <el-tree class="w-full" :data="themeInfo" :props="defaultProps" @@ -23,16 +23,63 @@ <template #default="{ node, data }"> <span>{{ node.label }}</span> </template> - </el-tree> + </el-tree> --> + <div> + <div class="theme-item" v-for="themeGroup in themeInfo" :key="themeGroup.id"> + <div class="theme-item-title h-fit flex-items-center gap-2 mb-1"> + <div class="w-1 h-4 bg-[#1677ff]"></div> + <span class="font-bold">{{ themeGroup.title }}</span> + </div> + <div> + <el-radio-group v-model="themeGroup.activeTheme" class="w-full" @change="(val) => handleThemeChange(val, themeGroup)"> + <div class="flex w-full" v-for="(children, index) in themeGroup.viewChildren" :key="index"> + <el-radio v-for="item in children" :key="item.id" :label="item.id" class="flex-1">{{ item.title }}</el-radio> + </div> + </el-radio-group> + </div> + </div> + </div> + <!-- <el-checkbox-group v-model="checkList" :max="1"> + <el-checkbox label="Option A" value="Value A" /> + <el-checkbox label="Option B" value="Value B" /> + <el-checkbox label="Option C" value="Value C" /> + <el-checkbox label="disabled" value="Value disabled" disabled /> + <el-checkbox label="selected and disabled" value="Value selected and disabled" disabled /> + </el-checkbox-group> --> + <div class="theme-item" v-for="legend in legendList" :key="legend.title"> + <div class="theme-item-title h-fit flex-items-center gap-2 mb-2"> + <div class="w-1 h-4 bg-[#1677ff]"></div> + <span class="font-bold">{{ legend.title }}</span> + </div> + <div class="theme-item-content"> + <el-row :gutter="0"> + <el-col v-for="item in legend.legend" :key="item.style" :span="12" class="mb20"> + <div class="flex-items-center gap-2"> + <div class="w-4 h-2 bg-[#1677ff]" :style="{ backgroundColor: `#${item.style}` }"></div> + <span>{{ item.label }}</span> + </div> + </el-col> + </el-row> + </div> + </div> </div> </div> </template> <script setup lang="ts" name="ThemeControl"> -import { computed, ref, watch, watchEffect } from 'vue'; +import type { ElTree } from 'element-plus'; +import { chunk } from 'lodash-es'; +import Circle from 'ol/style/Circle'; +import Style from 'ol/style/Style'; +import { computed, ref, watch } from 'vue'; +import { switchMapTheme } from '/@/api/map'; import type { OLMap } from '/@/model/map/OLMap'; -import { ElTree } from 'element-plus'; +import { formatDate } from '/@/utils/formatTime'; import { travelTree } from '/@/utils/util'; +import Fill from 'ol/style/Fill'; +import Stroke from 'ol/style/Stroke'; +import { Text } from 'ol/style'; +import { ElLoadingService } from 'element-plus'; const props = defineProps(['olMap']); const emit = defineEmits(['close']); @@ -45,27 +92,325 @@ emit('close'); }; const checkTreeRef = ref<InstanceType<typeof ElTree>>(); +const parseLegends = (legends) => { + const result = legends.map((item) => { + const isEqual = item.operate === '='; + const result = { + ...item, + legend: item.legend.map((legendItem, index, array) => { + const preItem = array[index - 1]; + let label = ''; + if (isEqual) { + label = legendItem.value; + } else if (preItem) { + label = `>${preItem.value}涓�${item.operate}${legendItem.value}`; + } else { + label = `${item.operate}${legendItem.value}`; + } + return { + ...legendItem, + label: label, + }; + }), + }; + result.legend.push({ + style: item.default, + value: '', + label: result.legend.length == 0 ? '榛樿' : `>${item.legend[item.legend.length - 1].value}`, + }); + return result; + }); + return result; +}; let isHumanCheckTrigger = false; const handleCheck = (data: any, node: any) => { const checkedKeys = node.checkedKeys; isHumanCheckTrigger = true; - travelTree(themeInfo.value, (theme) => { - console.log("馃殌 ~ theme.type:", theme.type) + + // 鍙栨秷鍒嗙粍涓棫鐨勯�夐」 + const excludeKeys = []; + for (const themeGroup of themeInfo.value) { + // 鍘熸潵鏈夊灏戜釜璁剧疆鐨� + const originSet = themeGroup.children.filter((item) => item.isSet); + // 鐜板湪鏈夊灏戜釜璁剧疆鐨� + const newSet = themeGroup.children.filter((item) => checkedKeys.includes(item.id)); + if (originSet.length === 1 && newSet.length === 2) { + originSet[0].isSet = false; + excludeKeys.push(originSet[0].id); + } + } + + const realCheckedKeys = checkedKeys.filter((key) => !excludeKeys.includes(key)); + + travelTree(themeInfo.value, (theme, index, array, parent) => { if (theme.type === 'theme') { const id = theme.id; - if (!checkedKeys.includes(id)) { + if (!realCheckedKeys.includes(id)) { theme.isSet = false; } else { theme.isSet = true; } } }); - console.log('馃殌 ~ human keys:', checkedKeys); + checkTreeRef.value?.setCheckedKeys(realCheckedKeys); }; const handleNodeClick = () => {}; -const themeInfo = computed(() => (props.olMap as OLMap).themeInfo.value); +const themeInfo = computed(() => { + const info = (props.olMap as OLMap).themeInfo.value; + // info.push({ + // id: 'group-娴嬭瘯', + // title: '娴嬭瘯', + // type: 'theme-group', + // children: [ + // { + // id: 'junction_1', + // title: '娴嬭瘯1', + // type: 'theme', + // }, + // { + // id: 'junction_2', + // title: '娴嬭瘯2', + // type: 'theme', + // }, + // { + // id: 'junction_3', + // title: '娴嬭瘯3', + // type: 'theme', + // }, + // { + // id: 'junction_4', + // title: '娴嬭瘯4', + // type: 'theme', + // }, + // { + // id: 'junction_5', + // title: '娴嬭瘯5', + // type: 'theme', + // }, + // { + // id: 'junction_6', + // title: '娴嬭瘯6', + // type: 'theme', + // }, + // ], + // }); + + const result = info.map((item, index) => { + if (item.children) { + // index == 0 && + // item.children.push( + // ...[ + // { + // id: 'junction_1', + // title: '娴嬭瘯1', + // type: 'theme', + // }, + // { + // id: 'junction_2', + // title: '娴嬭瘯2', + // type: 'theme', + // }, + // { + // id: 'junction_3', + // title: '娴嬭瘯3', + // type: 'theme', + // }, + // { + // id: 'junction_4', + // title: '娴嬭瘯4', + // type: 'theme', + // }, + // { + // id: 'junction_5', + // title: '娴嬭瘯5', + // type: 'theme', + // }, + // { + // id: 'junction_6', + // title: '娴嬭瘯6', + // type: 'theme', + // }, + // ] + // ); + item.viewChildren = chunk(item.children, 2); + } + return item; + }); + + return result; +}); + +const styleMap: Record<string, Record<string, Style>> = { + junction: {}, + pipe: {}, + polygon: {}, +}; +const maxResolution = 1; + +const getText = function (feature, resolution) { + const oname = feature.get('oname'); + let text = `first-${oname[0]}`; + if (resolution > maxResolution) { + text = ''; + } + + // else if (type == 'hide') { + // text = ''; + // } else if (type == 'shorten') { + // text = text.trunc(12); + // } else if (type == 'wrap' && (!dom.placement || dom.placement.value != 'line')) { + // text = stringDivider(text, 16, '\n'); + // } + + return text; +}; +const createTextStyle = (feature, resolution) => { + return new Style({ + text: new Text({ + text: getText(feature, resolution), + font: '14px Arial', + fill: new Fill({ color: '#000' }), + stroke: new Stroke({ color: '#fff', width: 2 }), + offsetX: 10, // 鏂囧瓧鐩稿浜庡嚑浣曚腑蹇冪殑姘村钩鍋忕Щ + offsetY: 20, // 鏂囧瓧鐩稿浜庡嚑浣曚腑蹇冪殑鍨傜洿鍋忕Щ + }), + }); +}; + +const legendList = ref([]); +const changeTheme = async (themeId: string) => { + const loadingInstance = ElLoadingService({ + text: '鍔犺浇涓婚涓�...', + target: '.layout-parent', + }); + const res = await switchMapTheme({ + theme_id: themeId, + time: formatDate(new Date()), + }).finally(() => { + loadingInstance.close(); + }); + + // 鍔犲叆涓婚涔嬪悗鐨勬牱寮忓嚱鏁� + const themeLayerStyleFunc = (feature, resolution) => { + const otype = feature.get('otype'); + const oname = feature.get('oname'); + // oname 鏄犲皠鏍峰紡 + const onameStyleMap = res?.[`O_${otype}`] ?? {}; + const themeStyles = res?.styles ?? []; + const styleIndex = onameStyleMap[oname]?.style_id; + const themeStyle = styleIndex == null ? null : themeStyles[styleIndex]; + // if(themeStyle){ + // } + const shape = feature.getGeometry().getType(); + const styles = []; + switch (shape) { + case 'Point': + const pSize = themeStyle?.PSIZE ?? feature.get('psize'); + + const pcolor = themeStyle?.PCOLOR ?? feature.get('pcolor'); + + const pStyle = themeStyle?.PSTYLE ?? feature.get('pstyle'); + + const pointStyle = props.olMap?.getPointStyles({ + size: pSize, + color: pcolor, + style: pStyle, + }); + pointStyle && styles.push(pointStyle); + break; + case 'LineString': + const lSize = themeStyle?.LSIZE ?? feature.get('lsize'); + const lColor = themeStyle?.LCOLOR ?? feature.get('lcolor'); + const lStyle = themeStyle?.LSTYLE ?? feature.get('lstyle'); + + const pSize1 = themeStyle?.PSIZE ?? feature.get('psize'); + const pcolor1 = themeStyle?.PCOLOR ?? feature.get('pcolor'); + const pStyle1 = themeStyle?.PSTYLE ?? feature.get('pstyle'); + + const lineStyle = props.olMap?.getLineStyles({ + lsize: lSize, + lcolor: lColor, + lstyle: lStyle, + psize: pSize1, + pcolor: pcolor1, + pstyle: pStyle1, + }); + lineStyle && styles.push(...lineStyle); + + break; + case 'Polygon': + const pColor = feature.get('pcolor'); + const lSize1 = feature.get('lsize'); + const lColor1 = feature.get('lcolor'); + const lstyle1 = feature.get('lstyle'); + const polygonStyle = props.olMap?.getPolygonStyles({ + pcolor: pColor, + lsize: lSize1, + lcolor: lColor1, + lstyle: lstyle1, + }); + polygonStyle && styles.push(...polygonStyle); + + break; + default: + break; + } + + // switch (otype) { + // case 'WDM_JUNCTIONS': + // const textStyle = createTextStyle(feature, resolution); + // styles.push(textStyle); + + // case 'WDM_PIPES': + // break; + // } + //#region ====================== 娣诲姞鏍囨敞 ====================== + const tString = themeStyle?.TSTRING ?? feature.get('tstring'); + const tStringStyle = props.olMap?.getLabelStyles({ + textContent: tString, + resolution, + }); + tStringStyle && styles.push(tStringStyle); + //#endregion + + return styles; + }; + const allLayers = props.olMap.layerInfo.value.reduce((preVal, curVal) => { + return preVal.concat(curVal.children.map((item) => item)); + }, []); + for (const item of allLayers) { + if (props.olMap?.unsupportedLayers.includes(item.id)) { + continue; + } + item.model.setStyle(themeLayerStyleFunc); + } + return res?.legends ?? []; +}; + +const handleThemeChange = async (val, themeGroup) => { + const allIds = []; + for (const item of themeInfo.value) { + if (item.activeTheme) { + allIds.push(item.activeTheme); + } + } + const ids = allIds.join(','); + + if (!ids) { + const allLayers = props.olMap.layerInfo.value.reduce((preVal, curVal) => { + return preVal.concat(curVal.children.map((item) => item.model)); + }, []); + for (const item of allLayers) { + const originStyle = item.get('originStyle'); + originStyle && item.setStyle(originStyle); + } + return; + } + const legends = await changeTheme(ids); + legendList.value = parseLegends(legends); +}; watch( () => themeInfo.value, @@ -84,7 +429,6 @@ } }); // const keys = layerInfo.value.filter((item) => item.isSet).map((item) => item.id); - console.log('馃殌 ~ watch keys:', keys); checkTreeRef.value?.setCheckedKeys(keys); } ); -- Gitblit v1.9.3