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