Compare commits
	
		
			2 Commits
		
	
	
		
			7638096eb6
			...
			19859bbaf0
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
								 | 
						19859bbaf0 | |
| 
							
							
								
								 | 
						aa2b55ac01 | 
| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					import request from '@/utils/request'
 | 
				
			||||||
 | 
					import { parseStrEmpty } from "@/utils/ruoyi";
 | 
				
			||||||
 | 
					import { createUniqueString } from "@/utils/index";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const tempTypeList = [
 | 
				
			||||||
 | 
					  { value: 'point', label: '点' },
 | 
				
			||||||
 | 
						{ value: 'polyline', label: '线' },
 | 
				
			||||||
 | 
					  { value: 'polygon', label: '面' },
 | 
				
			||||||
 | 
					  { value: 'billboard', label: '图标' },
 | 
				
			||||||
 | 
					  { value: 'label', label: '标签' },
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					const tempList = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查询样式类型信息
 | 
				
			||||||
 | 
					export function getStyleType() {
 | 
				
			||||||
 | 
					  return Promise.resolve(tempTypeList)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查询样式列表
 | 
				
			||||||
 | 
					export function listStyle(query) {
 | 
				
			||||||
 | 
						const list = tempList.filter(item => {
 | 
				
			||||||
 | 
					    if(query.styleName && item.styleName.indexOf(query.styleName) === -1) {
 | 
				
			||||||
 | 
					      return false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(query.styleType && item.styleType.indexOf(query.styleType) === -1) {
 | 
				
			||||||
 | 
					      return false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					  return Promise.resolve({
 | 
				
			||||||
 | 
							rows: list,
 | 
				
			||||||
 | 
							total: list.length,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 查询样式详细
 | 
				
			||||||
 | 
					export function getStyle(styleId) {
 | 
				
			||||||
 | 
					  return Promise.resolve({
 | 
				
			||||||
 | 
					    data: tempList.find(item => item.id === parseStrEmpty(styleId))
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 新增样式
 | 
				
			||||||
 | 
					export function addStyle(data) {
 | 
				
			||||||
 | 
						data.id = createUniqueString()
 | 
				
			||||||
 | 
					  tempList.push(data)
 | 
				
			||||||
 | 
					  return Promise.resolve({
 | 
				
			||||||
 | 
					    code: 200,
 | 
				
			||||||
 | 
					    msg: '新增成功',
 | 
				
			||||||
 | 
					    data: data
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 修改样式
 | 
				
			||||||
 | 
					export function updateStyle(data) {
 | 
				
			||||||
 | 
					  for (const v of tempList) {
 | 
				
			||||||
 | 
					    if (v.id === data.id) {
 | 
				
			||||||
 | 
					      v.styleName = data.styleName
 | 
				
			||||||
 | 
					      v.styleType = data.styleType
 | 
				
			||||||
 | 
					      v.style = data.style
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return Promise.resolve({
 | 
				
			||||||
 | 
					    code: 200,
 | 
				
			||||||
 | 
					    msg: '修改成功',
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 删除样式
 | 
				
			||||||
 | 
					export function delStyle(styleId) {
 | 
				
			||||||
 | 
					  let idList = styleId
 | 
				
			||||||
 | 
					  if(typeof styleId === 'string') {
 | 
				
			||||||
 | 
					    idList = [styleId]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  for (let index = tempList.length - 1; index >= 0; index--) {
 | 
				
			||||||
 | 
					    if(idList.includes(tempList[index].id)) {
 | 
				
			||||||
 | 
					      tempList.splice(index, 1)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return Promise.resolve({
 | 
				
			||||||
 | 
					    code: 200,
 | 
				
			||||||
 | 
					    msg: '删除成功',
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.5 KiB  | 
| 
		 After Width: | Height: | Size: 1.6 KiB  | 
| 
		 After Width: | Height: | Size: 1.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.3 KiB  | 
| 
		 After Width: | Height: | Size: 1.4 KiB  | 
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 After Width: | Height: | Size: 1.1 KiB  | 
| 
		 After Width: | Height: | Size: 866 B  | 
| 
						 | 
					@ -16,6 +16,7 @@ const props = defineProps({
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					const emits = defineEmits(['init'])
 | 
				
			||||||
let viewer = null;
 | 
					let viewer = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,6 +93,8 @@ const initMap = async () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // 取消左键双击
 | 
					  // 取消左键双击
 | 
				
			||||||
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
 | 
					  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  emits('init', viewer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					import * as Cesium from "cesium";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getCenterPosition = (positions) => {
 | 
				
			||||||
 | 
					  if(positions.length === 0) {
 | 
				
			||||||
 | 
					    console.warn("positions is empty");
 | 
				
			||||||
 | 
					    return Cesium.Cartesian3.ZERO;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  let maxX = Cesium.Math.toRadians(-180),
 | 
				
			||||||
 | 
					    minX = Cesium.Math.toRadians(180);
 | 
				
			||||||
 | 
					  let maxY = Cesium.Math.toRadians(-90),
 | 
				
			||||||
 | 
					    minY = Cesium.Math.toRadians(90);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (let i = 0; i < positions.length; i++) {
 | 
				
			||||||
 | 
					    const cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
 | 
				
			||||||
 | 
					    if (cartographic.longitude < minX) {
 | 
				
			||||||
 | 
					      minX = cartographic.longitude;
 | 
				
			||||||
 | 
					    } else if (cartographic.longitude > maxX) {
 | 
				
			||||||
 | 
					      maxX = cartographic.longitude;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (cartographic.latitude < minY) {
 | 
				
			||||||
 | 
					      minY = cartographic.latitude;
 | 
				
			||||||
 | 
					    } else if (cartographic.latitude > maxY) {
 | 
				
			||||||
 | 
					      maxY = cartographic.latitude;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return Cesium.Cartesian3.fromRadians((minX + maxX) / 2, (minY + maxY) / 2)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  getCenterPosition
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,167 @@
 | 
				
			||||||
 | 
					import * as Cesium from "cesium";
 | 
				
			||||||
 | 
					import { getCenterPosition } from "./calcFn";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const createFeature = (style, position, text, layer) => {
 | 
				
			||||||
 | 
					  if (!style) {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (style.properties?.type) {
 | 
				
			||||||
 | 
					    case "point":
 | 
				
			||||||
 | 
					    case "billboard":
 | 
				
			||||||
 | 
					    case "label":
 | 
				
			||||||
 | 
					      return createPointFeature(style, position, text, layer);
 | 
				
			||||||
 | 
					    case "polyline":
 | 
				
			||||||
 | 
					      return createPolylineFeature(style, position, text, layer);
 | 
				
			||||||
 | 
					    case "polygon":
 | 
				
			||||||
 | 
					      return createPolygonFeature(style, position, text, layer);
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 生成点要素
 | 
				
			||||||
 | 
					 * 目前图标、标签没有额外操作,故共享该方法
 | 
				
			||||||
 | 
					 * @param {Object} style 处理后的样式对象
 | 
				
			||||||
 | 
					 * @param {Cesium.Cartesian3} position 点位置
 | 
				
			||||||
 | 
					 * @param {String} text 标签文本,可选
 | 
				
			||||||
 | 
					 * @param {Cesium.DataSource} layer 图层
 | 
				
			||||||
 | 
					 * @returns {Cesium.Entity} 点对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPointFeature = (style, position, text, layer) => {
 | 
				
			||||||
 | 
					  if (!position) {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const entity = new Cesium.Entity({
 | 
				
			||||||
 | 
					    position: position,
 | 
				
			||||||
 | 
					    ...cloneStyle(style),
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  // 添加标签文本
 | 
				
			||||||
 | 
					  // if(text !== null && text !== undefined) {
 | 
				
			||||||
 | 
					  //   if(Cesium.defined(entity.label)) {
 | 
				
			||||||
 | 
					  //     entity.label.text = new Cesium.ConstantProperty(text)
 | 
				
			||||||
 | 
					  //   } else {
 | 
				
			||||||
 | 
					  //     entity.label = new Cesium.LabelGraphics({
 | 
				
			||||||
 | 
					  //       text,
 | 
				
			||||||
 | 
					  //       font: '16px sans-serif',
 | 
				
			||||||
 | 
					  //     })
 | 
				
			||||||
 | 
					  //   }
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					  if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
 | 
				
			||||||
 | 
					    entity.label.text = new Cesium.ConstantProperty(text);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 加入图层
 | 
				
			||||||
 | 
					  if (layer) {
 | 
				
			||||||
 | 
					    layer.entities.add(entity);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return entity;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 生成线要素
 | 
				
			||||||
 | 
					 * @param {Object} style 处理后的样式对象
 | 
				
			||||||
 | 
					 * @param {Array<Cesium.Cartesian3>} position 位置数组
 | 
				
			||||||
 | 
					 * @param {String} text 标签文本,可选
 | 
				
			||||||
 | 
					 * @param {Cesium.DataSource} layer 图层
 | 
				
			||||||
 | 
					 * @returns {Cesium.Entity} 线对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPolylineFeature = (style, position, text, layer) => {
 | 
				
			||||||
 | 
					  if (!position || position.length < 2) {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const entity = new Cesium.Entity(cloneStyle(style));
 | 
				
			||||||
 | 
					  // 添加线坐标
 | 
				
			||||||
 | 
					  if (Cesium.defined(style.polyline)) {
 | 
				
			||||||
 | 
					    entity.polyline.positions = new Cesium.ConstantProperty(
 | 
				
			||||||
 | 
					      style.properties.closed ? [...position, position[0]] : position
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    entity.polyline = new Cesium.PolylineGraphics({
 | 
				
			||||||
 | 
					      positions: position,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加标签文本
 | 
				
			||||||
 | 
					  if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
 | 
				
			||||||
 | 
					    entity.label.text = new Cesium.ConstantProperty(text)
 | 
				
			||||||
 | 
					    // 添加label坐标
 | 
				
			||||||
 | 
					    entity.position = getCenterPosition(position)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 加入图层
 | 
				
			||||||
 | 
					  if (layer) {
 | 
				
			||||||
 | 
					    layer.entities.add(entity);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return entity;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 生成面要素
 | 
				
			||||||
 | 
					 * @param {Object} style 处理后的样式对象
 | 
				
			||||||
 | 
					 * @param {Array<Cesium.Cartesian3>} position 位置数组
 | 
				
			||||||
 | 
					 * @param {String} text 标签文本,可选
 | 
				
			||||||
 | 
					 * @param {Cesium.DataSource} layer 图层
 | 
				
			||||||
 | 
					 * @returns {Cesium.Entity} 面对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPolygonFeature = (style, position, text, layer) => {
 | 
				
			||||||
 | 
					  if (!position || position.length < 3) {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const entity = new Cesium.Entity(cloneStyle(style));
 | 
				
			||||||
 | 
					  // 添加面坐标
 | 
				
			||||||
 | 
					  if (Cesium.defined(style.polygon)) {
 | 
				
			||||||
 | 
					    entity.polygon.hierarchy = new Cesium.PolygonHierarchy(position);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    entity.polyline = new Cesium.PolygonGraphics({
 | 
				
			||||||
 | 
					      hierarchy: new Cesium.PolygonHierarchy(position),
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加轮廓线坐标
 | 
				
			||||||
 | 
					  // 这里消极的判断,仅当存在polyline时才添加,且必定是闭合线
 | 
				
			||||||
 | 
					  if (Cesium.defined(style.polyline)) {
 | 
				
			||||||
 | 
					    entity.polyline.positions = new Cesium.ConstantProperty([
 | 
				
			||||||
 | 
					      ...position,
 | 
				
			||||||
 | 
					      position[0],
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加标签文本
 | 
				
			||||||
 | 
					  if (Cesium.defined(entity.label) && text !== null && text !== undefined) {
 | 
				
			||||||
 | 
					    entity.label.text = new Cesium.ConstantProperty(text)
 | 
				
			||||||
 | 
					    // 添加label坐标
 | 
				
			||||||
 | 
					    entity.position = getCenterPosition(position)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 加入图层
 | 
				
			||||||
 | 
					  if (layer) {
 | 
				
			||||||
 | 
					    layer.entities.add(entity)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return entity;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cloneStyle = (style) => {
 | 
				
			||||||
 | 
					  const clone = {};
 | 
				
			||||||
 | 
					  for (let key in style) {
 | 
				
			||||||
 | 
					    console.log(key);
 | 
				
			||||||
 | 
					    if (key === "id") {
 | 
				
			||||||
 | 
					      clone[key] = style[key];
 | 
				
			||||||
 | 
					    } else if (key === "properties") {
 | 
				
			||||||
 | 
					      // 浅拷贝属性
 | 
				
			||||||
 | 
					      clone[key] = {};
 | 
				
			||||||
 | 
					      for (let prop in style[key]) {
 | 
				
			||||||
 | 
					        clone[key][prop] = style[key][prop];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      // 用cesium提供方法拷贝
 | 
				
			||||||
 | 
					      clone[key] = style[key].clone();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return clone;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  createFeature,
 | 
				
			||||||
 | 
					  createPointFeature,
 | 
				
			||||||
 | 
					  createPolylineFeature,
 | 
				
			||||||
 | 
					  createPolygonFeature,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,330 @@
 | 
				
			||||||
 | 
					import * as Cesium from 'cesium';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let _clampToGround = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getStyle = (options) => {
 | 
				
			||||||
 | 
					  // 将配置项转为cesium内部类,提供复用
 | 
				
			||||||
 | 
					  const _options = {}
 | 
				
			||||||
 | 
					  // 判断类型(option提供了则套用,未提供测推断)
 | 
				
			||||||
 | 
					  if(options.type) {
 | 
				
			||||||
 | 
					    _options.type = options.type
 | 
				
			||||||
 | 
					  } else if(options.point) {
 | 
				
			||||||
 | 
					    _options.type = 'point'
 | 
				
			||||||
 | 
					  } else if(options.polygon) {
 | 
				
			||||||
 | 
					    _options.type = 'polygon'
 | 
				
			||||||
 | 
					  } else if(options.polyline) {
 | 
				
			||||||
 | 
					    _options.type = 'polyline'
 | 
				
			||||||
 | 
					  } else if(options.billboard) {
 | 
				
			||||||
 | 
					    _options.type = 'billboard'
 | 
				
			||||||
 | 
					  } else if(options.label) {
 | 
				
			||||||
 | 
					    _options.type = 'label'
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // 什么配置都没提供,则返回空对象
 | 
				
			||||||
 | 
					    return _options
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 转通用配置
 | 
				
			||||||
 | 
					  const common = parseCommonOptions(_options.type, options.common);
 | 
				
			||||||
 | 
					  // 属性配置项
 | 
				
			||||||
 | 
					  const property = options.property || {};
 | 
				
			||||||
 | 
					  property.type = _options.type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (_options.type) {
 | 
				
			||||||
 | 
					    case 'point':
 | 
				
			||||||
 | 
					      return parsePointOptions(options, common, property)
 | 
				
			||||||
 | 
					    case 'polyline':
 | 
				
			||||||
 | 
					      return parsePolylineOptions(options, common, property)
 | 
				
			||||||
 | 
					    case 'polygon':
 | 
				
			||||||
 | 
					      return parsePolygonOptions(options, common, property)
 | 
				
			||||||
 | 
					    case 'billboard':
 | 
				
			||||||
 | 
					      return parseBillboardOptions(options, common, property)
 | 
				
			||||||
 | 
					    case 'label':
 | 
				
			||||||
 | 
					      return parseLabelOptions(options, common, property)
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      console.warn('不支持的样式类型:', _options.type);
 | 
				
			||||||
 | 
					      return {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 解析通用配置
 | 
				
			||||||
 | 
					const parseCommonOptions = (type, options) => {
 | 
				
			||||||
 | 
					  const _options = {}
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return _options
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 贴地
 | 
				
			||||||
 | 
					  if(options.clampToGround) {
 | 
				
			||||||
 | 
					    _clampToGround = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 按视距缩放
 | 
				
			||||||
 | 
					  // 线和面没有按视距缩放
 | 
				
			||||||
 | 
					  if(options.scaleByDistance && type !== 'polyline' && type !== 'polygon') {
 | 
				
			||||||
 | 
					    _options.scaleByDistance = new Cesium.NearFarScalar(
 | 
				
			||||||
 | 
					      options.scaleNear,
 | 
				
			||||||
 | 
					      options.scaleNearValue,
 | 
				
			||||||
 | 
					      options.scaleFar,
 | 
				
			||||||
 | 
					      options.scaleFarValue
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return _options
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析点相关配置为对象
 | 
				
			||||||
 | 
					 * @param {Object} options 总配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @param {Object} property 属性配置对象
 | 
				
			||||||
 | 
					 * @returns 点样式对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const parsePointOptions = (options, common, property) => {
 | 
				
			||||||
 | 
					  const style = {
 | 
				
			||||||
 | 
					    point: createPointByOptions(options.point, common),
 | 
				
			||||||
 | 
					    properties: property || {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加图标、标签
 | 
				
			||||||
 | 
					  if(options.billboard) {
 | 
				
			||||||
 | 
					    style.billboard = createBillboardByOptions(options.billboard, common)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(options.label) {
 | 
				
			||||||
 | 
					    style.label = createLabelByOptions(options.label, common)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return style
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析点配置项
 | 
				
			||||||
 | 
					 * @param {Object} options 点配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @returns cesium点对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPointByOptions = (options, common) => {
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _options = {
 | 
				
			||||||
 | 
					    pixelSize: parseFloat(options.pixelSize) || 10,
 | 
				
			||||||
 | 
					    color: Cesium.Color.fromCssColorString(options.color) || Cesium.Color.WHITE,
 | 
				
			||||||
 | 
					    ...common
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(options.showOutline) {
 | 
				
			||||||
 | 
					    _options.outlineWidth = parseFloat(options.outlineWidth) || 1
 | 
				
			||||||
 | 
					    _options.outlineColor = Cesium.Color.fromCssColorString(options.outlineColor) || Cesium.Color.BLACK
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_clampToGround) {
 | 
				
			||||||
 | 
					    _options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Cesium.PointGraphics(_options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析线相关配置为对象
 | 
				
			||||||
 | 
					 * @param {Object} options 总配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @param {Object} property 属性配置对象
 | 
				
			||||||
 | 
					 * @returns 线样式对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const parsePolylineOptions = (options, common, property) => {
 | 
				
			||||||
 | 
					  const style = {
 | 
				
			||||||
 | 
					    polyline: createPolylineByOptions(options.polyline, common),
 | 
				
			||||||
 | 
					    properties: property || {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加闭合属性
 | 
				
			||||||
 | 
					  if(options.polyline.closed) {
 | 
				
			||||||
 | 
					    property.closed = true
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加标签
 | 
				
			||||||
 | 
					  if(options.label) {
 | 
				
			||||||
 | 
					    style.label = createLabelByOptions(options.label, common)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return style
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析线配置项
 | 
				
			||||||
 | 
					 * @param {Object} options 线配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @param {Object} property 属性配置对象
 | 
				
			||||||
 | 
					 * @returns cesium线对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPolylineByOptions = (options, common) => {
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _options = {
 | 
				
			||||||
 | 
					    width: parseFloat(options.width) || 1,
 | 
				
			||||||
 | 
					    material: Cesium.Color.fromCssColorString(options.color) || Cesium.Color.WHITE,
 | 
				
			||||||
 | 
					    ...common
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_clampToGround) {
 | 
				
			||||||
 | 
					    _options.clampToGround = true
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Cesium.PolylineGraphics(_options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析面相关配置为对象
 | 
				
			||||||
 | 
					 * @param {Object} options 总配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @param {Object} property 属性配置对象
 | 
				
			||||||
 | 
					 * @returns 面样式对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const parsePolygonOptions = (options, common, property) => {
 | 
				
			||||||
 | 
					  const style = {
 | 
				
			||||||
 | 
					    polygon: createPolygonByOptions(options.polygon, common),
 | 
				
			||||||
 | 
					    properties: property || {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加面的轮廓线
 | 
				
			||||||
 | 
					  if(options.polygon.showOutline) {
 | 
				
			||||||
 | 
					    property.closed = true
 | 
				
			||||||
 | 
					    style.polyline = createPolygonOutlineByOptions(options.polygon, common)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加标签
 | 
				
			||||||
 | 
					  if(options.label) {
 | 
				
			||||||
 | 
					    style.label = createLabelByOptions(options.label, common)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return style
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析面的轮廓线配置项
 | 
				
			||||||
 | 
					 * 因面的自带相关属性不支持贴地形,所以生成cesium线对象
 | 
				
			||||||
 | 
					 * @param {Object} options 面配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @returns cesium线对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPolygonOutlineByOptions = (options, common) => {
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _options = {
 | 
				
			||||||
 | 
					    width: parseFloat(options.outlineWidth) ?? 1,
 | 
				
			||||||
 | 
					    material: Cesium.Color.fromCssColorString(options.outlineColor) || Cesium.Color.BLACK,
 | 
				
			||||||
 | 
					    ...common
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_clampToGround) {
 | 
				
			||||||
 | 
					    _options.clampToGround = true
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Cesium.PolylineGraphics(_options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析面配置项
 | 
				
			||||||
 | 
					 * @param {Object} options 面配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @returns cesium面对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createPolygonByOptions = (options, common) => {
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _options = {
 | 
				
			||||||
 | 
					    material: Cesium.Color.fromCssColorString(options.color) || Cesium.Color.WHITE,
 | 
				
			||||||
 | 
					    ...common
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_clampToGround) {
 | 
				
			||||||
 | 
					    _options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Cesium.PolygonGraphics(_options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析图标相关配置为对象
 | 
				
			||||||
 | 
					 * @param {Object} options 总配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @param {Object} property 属性配置对象
 | 
				
			||||||
 | 
					 * @returns 图标样式对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const parseBillboardOptions = (options, common, property) => {
 | 
				
			||||||
 | 
					  const style = {
 | 
				
			||||||
 | 
					    billboard: createBillboardByOptions(options.billboard, common),
 | 
				
			||||||
 | 
					    properties: property || {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 添加标签
 | 
				
			||||||
 | 
					  if(options.label) {
 | 
				
			||||||
 | 
					    style.label = createLabelByOptions(options.label, common)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return style
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析图标配置项
 | 
				
			||||||
 | 
					 * @param {Object} options 图标配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @returns cesium图标对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createBillboardByOptions = (options, common) => {
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _options = {
 | 
				
			||||||
 | 
					    image: options.image,
 | 
				
			||||||
 | 
					    scale: parseFloat(options.scale) ?? 1,
 | 
				
			||||||
 | 
					    rotation: Cesium.Math.toRadians(parseFloat(options.rotation) || 0),
 | 
				
			||||||
 | 
					    horizontalOrigin: parseInt(options.horizontalOrigin) ?? Cesium.HorizontalOrigin.CENTER,
 | 
				
			||||||
 | 
					    verticalOrigin: parseInt(options.verticalOrigin) ?? Cesium.VerticalOrigin.BOTTOM,
 | 
				
			||||||
 | 
					    pixelOffset: new Cesium.Cartesian2(parseFloat(options.horizontalOffset) || 0, parseFloat(options.verticalOffset) || 0),
 | 
				
			||||||
 | 
					    ...common
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_clampToGround) {
 | 
				
			||||||
 | 
					    _options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Cesium.BillboardGraphics(_options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析标签相关配置为对象
 | 
				
			||||||
 | 
					 * @param {Object} options 总配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @param {Object} property 属性配置对象
 | 
				
			||||||
 | 
					 * @returns 标签样式对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const parseLabelOptions = (options, common, property) => { 
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    label: createLabelByOptions(options.label, common),
 | 
				
			||||||
 | 
					    properties: property || {}
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 解析标签配置项
 | 
				
			||||||
 | 
					 * @param {Object} options 标签配置项
 | 
				
			||||||
 | 
					 * @param {Object} common 通用配置对象
 | 
				
			||||||
 | 
					 * @returns cesium标签对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const createLabelByOptions = (options, common) => {
 | 
				
			||||||
 | 
					  if(!options) {
 | 
				
			||||||
 | 
					    return undefined
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const _options = {
 | 
				
			||||||
 | 
					    font: `${options.font ?? 16}px sans-serif`,
 | 
				
			||||||
 | 
					    fillColor: Cesium.Color.fromCssColorString(options.fillColor) || Cesium.Color.WHITE,
 | 
				
			||||||
 | 
					    horizontalOrigin: parseInt(options.horizontalOrigin) ?? Cesium.HorizontalOrigin.CENTER,
 | 
				
			||||||
 | 
					    verticalOrigin: parseInt(options.verticalOrigin) ?? Cesium.VerticalOrigin.BOTTOM,
 | 
				
			||||||
 | 
					    pixelOffset: new Cesium.Cartesian2(parseFloat(options.horizontalOffset) ?? 0, parseFloat(options.verticalOffset) ?? 0),
 | 
				
			||||||
 | 
					    ...common
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(options.showOutline) {
 | 
				
			||||||
 | 
					    _options.style = Cesium.LabelStyle.FILL_AND_OUTLINE
 | 
				
			||||||
 | 
					    _options.outlineWidth = parseFloat(options.outlineWidth) || 1
 | 
				
			||||||
 | 
					    _options.outlineColor = Cesium.Color.fromCssColorString(options.outlineColor) || Cesium.Color.BLACK
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(options.showBackground) {
 | 
				
			||||||
 | 
					    _options.showBackground = true
 | 
				
			||||||
 | 
					    _options.backgroundColor = Cesium.Color.fromCssColorString(options.backgroundColor) || new Cesium.Color(0.165, 0.165, 0.165, 0.8)
 | 
				
			||||||
 | 
					    _options.backgroundPadding = new Cesium.Cartesian2(parseFloat(options.horizontalPadding) ?? 7, parseFloat(options.verticalPadding) ?? 5)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_clampToGround) {
 | 
				
			||||||
 | 
					    _options.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Cesium.LabelGraphics(_options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  getStyle
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,12 @@ export const constantRoutes = [
 | 
				
			||||||
        component: () => import('@/views/gisManagement/configSetting/index.vue'),
 | 
					        component: () => import('@/views/gisManagement/configSetting/index.vue'),
 | 
				
			||||||
        name: 'configSetting',
 | 
					        name: 'configSetting',
 | 
				
			||||||
        meta: { title: '地图配置' }
 | 
					        meta: { title: '地图配置' }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: 'configStyle',
 | 
				
			||||||
 | 
					        component: () => import('@/views/gisManagement/configStyle/index.vue'),
 | 
				
			||||||
 | 
					        name: 'configStyle',
 | 
				
			||||||
 | 
					        meta: { title: '样式配置' }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,170 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-dialog v-model="show" title="选择图标" width="600px">
 | 
				
			||||||
 | 
					    <!-- <el-button type="primary">上传本地图片</el-button> -->
 | 
				
			||||||
 | 
					    <div v-loading="loading">
 | 
				
			||||||
 | 
					      <el-upload action="#" :auto-upload="false" :show-file-list="false" :on-change="handleFileChange"
 | 
				
			||||||
 | 
					        accept="image/*">
 | 
				
			||||||
 | 
					        <el-button type="primary">上传本地图片</el-button>
 | 
				
			||||||
 | 
					      </el-upload>
 | 
				
			||||||
 | 
					      <div class="icon-container">
 | 
				
			||||||
 | 
					        <div :class="{active: icon === selectedItem}" class="icon-item" v-for="(icon, index) in icons" :key="index" @click="selectIcon(icon)">
 | 
				
			||||||
 | 
					          <el-image style="width: 48px; height: 48px" :src="icon" fit="contain" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <template #footer>
 | 
				
			||||||
 | 
					      <span class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button @click="handleCancel">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click="handleConfirm" :disabled="!selectedItem">
 | 
				
			||||||
 | 
					          确定
 | 
				
			||||||
 | 
					        </el-button>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </el-dialog>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import analysisAroundIcon from '@/assets/icons/example/analysis_around.png'
 | 
				
			||||||
 | 
					import analysisCoordinationLocationIcon from '@/assets/icons/example/analysis_coordination_location.png'
 | 
				
			||||||
 | 
					import analysisMapLocationIcon from '@/assets/icons/example/analysis_map_location.png'
 | 
				
			||||||
 | 
					import analysisSandboxIcon from '@/assets/icons/example/analysis_sandbox.png'
 | 
				
			||||||
 | 
					import analysisSpreadIcon from '@/assets/icons/example/analysis_spread.png'
 | 
				
			||||||
 | 
					import checkPointIcon from '@/assets/icons/example/check_point.png'
 | 
				
			||||||
 | 
					import sandboxExplosiveIcon from '@/assets/icons/example/sandbox_explosive.png'
 | 
				
			||||||
 | 
					import sandboxFireIcon from '@/assets/icons/example/sandbox_fire.png'
 | 
				
			||||||
 | 
					import sandboxFirefighterIcon from '@/assets/icons/example/sandbox_firefighter.png'
 | 
				
			||||||
 | 
					import sandboxFirepointIcon from '@/assets/icons/example/sandbox_firepoint.png'
 | 
				
			||||||
 | 
					import sandboxFlameIcon from '@/assets/icons/example/sandbox_flame.png'
 | 
				
			||||||
 | 
					import sandboxTrappedIcon from '@/assets/icons/example/sandbox_trapped.png'
 | 
				
			||||||
 | 
					import sandboxWaterIcon from '@/assets/icons/example/sandbox_water.png'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const show = defineModel()
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  current: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: ''
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const emits = defineEmits(['update:current'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// const icons = ref([
 | 
				
			||||||
 | 
					//   { url: analysisAroundIcon },
 | 
				
			||||||
 | 
					//   { url: analysisCoordinationLocationIcon },
 | 
				
			||||||
 | 
					//   { url: analysisMapLocationIcon },
 | 
				
			||||||
 | 
					//   { url: analysisSandboxIcon },
 | 
				
			||||||
 | 
					//   { url: analysisSpreadIcon },
 | 
				
			||||||
 | 
					//   { url: checkPointIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxExplosiveIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxFireIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxFirefighterIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxFirepointIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxFlameIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxTrappedIcon },
 | 
				
			||||||
 | 
					//   { url: sandboxWaterIcon }
 | 
				
			||||||
 | 
					// ])
 | 
				
			||||||
 | 
					const icons = ref([
 | 
				
			||||||
 | 
					  analysisAroundIcon,
 | 
				
			||||||
 | 
					  analysisCoordinationLocationIcon,
 | 
				
			||||||
 | 
					  analysisMapLocationIcon,
 | 
				
			||||||
 | 
					  analysisSandboxIcon,
 | 
				
			||||||
 | 
					  analysisSpreadIcon,
 | 
				
			||||||
 | 
					  checkPointIcon,
 | 
				
			||||||
 | 
					  sandboxExplosiveIcon,
 | 
				
			||||||
 | 
					  sandboxFireIcon,
 | 
				
			||||||
 | 
					  sandboxFirefighterIcon,
 | 
				
			||||||
 | 
					  sandboxFirepointIcon,
 | 
				
			||||||
 | 
					  sandboxFlameIcon,
 | 
				
			||||||
 | 
					  sandboxTrappedIcon,
 | 
				
			||||||
 | 
					  sandboxWaterIcon
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					const loading = ref(false)
 | 
				
			||||||
 | 
					const selectedItem = ref(props.current)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 上传图片 */
 | 
				
			||||||
 | 
					const handleFileChange = (uploadFile) => {
 | 
				
			||||||
 | 
					  loading.value = true;
 | 
				
			||||||
 | 
					  const file = uploadFile.raw;
 | 
				
			||||||
 | 
					  if (!file) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 检查文件类型
 | 
				
			||||||
 | 
					  if (!file.type.startsWith('image/')) {
 | 
				
			||||||
 | 
					    ElMessage.error('只能上传图片文件!');
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 检查文件大小 (可选)
 | 
				
			||||||
 | 
					  // const isLt2M = file.size / 1024 / 1024 < 2;
 | 
				
			||||||
 | 
					  // if (!isLt2M) {
 | 
				
			||||||
 | 
					  //   ElMessage.error('图片文件大小不能超过 2MB!');
 | 
				
			||||||
 | 
					  //   return;
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const reader = new FileReader();
 | 
				
			||||||
 | 
					  reader.onloadend = () => {
 | 
				
			||||||
 | 
					    const base64String = reader.result;
 | 
				
			||||||
 | 
					    if(icons.value.includes(base64String)) {
 | 
				
			||||||
 | 
					      ElMessage.error('该图片已存在,请选择其他图片!');
 | 
				
			||||||
 | 
					      loading.value = false;
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    icons.value.push(base64String);
 | 
				
			||||||
 | 
					    loading.value = false;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  reader.onerror = () => {
 | 
				
			||||||
 | 
					    ElMessage.error('读取图片时出错!');
 | 
				
			||||||
 | 
					    loading.value = false;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  reader.readAsDataURL(file);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 图片点击 */
 | 
				
			||||||
 | 
					const selectIcon = (icon) => {
 | 
				
			||||||
 | 
					  selectedItem.value = icon
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 确认 */
 | 
				
			||||||
 | 
					const handleConfirm = () => {
 | 
				
			||||||
 | 
					  emits('update:current', selectedItem.value)
 | 
				
			||||||
 | 
					  show.value = false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 取消 */
 | 
				
			||||||
 | 
					const handleCancel = () => {
 | 
				
			||||||
 | 
					  selectedItem.value = props.current
 | 
				
			||||||
 | 
					  show.value = false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.icon-container {
 | 
				
			||||||
 | 
					  margin-top: 20px;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-wrap: wrap;
 | 
				
			||||||
 | 
					  border-left: 1px solid var(--el-border-color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .icon-item {
 | 
				
			||||||
 | 
					    width: 60px;
 | 
				
			||||||
 | 
					    height: 60px;
 | 
				
			||||||
 | 
					    // background-color: #f0f0f0;
 | 
				
			||||||
 | 
					    border-right: 1px solid var(--el-border-color);
 | 
				
			||||||
 | 
					    border-bottom: 1px solid var(--el-border-color);
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:nth-child(-n+10) {
 | 
				
			||||||
 | 
					      border-top: 1px solid var(--el-border-color);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      // background-color: #e0e0e0;
 | 
				
			||||||
 | 
					      background-color: var(--el-border-color-extra-light);
 | 
				
			||||||
 | 
					      color: var(--brand-color-light);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    &.active {
 | 
				
			||||||
 | 
					      background-color: var(--el-color-primary-light-6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,234 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-dialog v-model="dialogVisible" title="选择图标/图片" width="600px" @close="handleCancel">
 | 
				
			||||||
 | 
					    <div class="image-library-content">
 | 
				
			||||||
 | 
					      <!-- 上传本地图片 -->
 | 
				
			||||||
 | 
					      <div class="upload-area">
 | 
				
			||||||
 | 
					        <el-upload action="#" :auto-upload="false" :show-file-list="false" :on-change="handleFileChange"
 | 
				
			||||||
 | 
					          accept="image/*">
 | 
				
			||||||
 | 
					          <el-button type="primary">上传本地图片</el-button>
 | 
				
			||||||
 | 
					        </el-upload>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <!-- 图标/图片列表 -->
 | 
				
			||||||
 | 
					      <div class="item-list">
 | 
				
			||||||
 | 
					        <div v-for="item in items" :key="item.id" :class="['item', { 'is-selected': selectedItem?.id === item.id }]"
 | 
				
			||||||
 | 
					          @click="selectItem(item)">
 | 
				
			||||||
 | 
					          <template v-if="item.type === 'system' && item.component">
 | 
				
			||||||
 | 
					            <!-- Element Plus Icon -->
 | 
				
			||||||
 | 
					            <el-icon :size="30">
 | 
				
			||||||
 | 
					              <component :is="item.component" />
 | 
				
			||||||
 | 
					            </el-icon>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          <template v-else-if="item.type === 'system' && item.display">
 | 
				
			||||||
 | 
					            <!-- System Image URL -->
 | 
				
			||||||
 | 
					            <img :src="item.display" alt="system image" class="item-image" />
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          <template v-else-if="item.type === 'local' && item.display">
 | 
				
			||||||
 | 
					            <!-- Local Base64 Image -->
 | 
				
			||||||
 | 
					            <img :src="item.display" alt="local image" class="item-image" />
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					          <div v-else class="item-placeholder">无预览</div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <template #footer>
 | 
				
			||||||
 | 
					      <span class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button @click="handleCancel">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click="handleConfirm" :disabled="!selectedItem">
 | 
				
			||||||
 | 
					          确定
 | 
				
			||||||
 | 
					        </el-button>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </el-dialog>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import { ref, watch, onMounted } from 'vue';
 | 
				
			||||||
 | 
					import { ElDialog, ElButton, ElUpload, ElIcon, ElMessage } from 'element-plus';
 | 
				
			||||||
 | 
					// 导入 Element Plus Icons (按需导入或全局注册)
 | 
				
			||||||
 | 
					// 如果是全局注册,则不需要在这里导入
 | 
				
			||||||
 | 
					// 如果是按需导入,需要导入你用到的图标组件
 | 
				
			||||||
 | 
					import * as ElementPlusIconsVue from '@element-plus/icons-vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 定义 props
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  visible: {
 | 
				
			||||||
 | 
					    type: Boolean,
 | 
				
			||||||
 | 
					    default: false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  initialValue: {
 | 
				
			||||||
 | 
					    type: String, // 传入的当前选中图片的值 (URL 或 Base64)
 | 
				
			||||||
 | 
					    default: null
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 定义 emits
 | 
				
			||||||
 | 
					const emit = defineEmits(['update:visible', 'confirm']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 弹窗可见性
 | 
				
			||||||
 | 
					const dialogVisible = ref(props.visible);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 图标/图片列表数据
 | 
				
			||||||
 | 
					const items = ref([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 当前选中的项
 | 
				
			||||||
 | 
					const selectedItem = ref(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 默认系统图标和图片
 | 
				
			||||||
 | 
					const defaultSystemItems = [
 | 
				
			||||||
 | 
					  // Element Plus Icons (示例)
 | 
				
			||||||
 | 
					  { id: 'icon-star', type: 'system', display: 'Star', value: 'ElIconStarFilled', component: 'ElIconStarFilled' },
 | 
				
			||||||
 | 
					  { id: 'icon-picture', type: 'system', display: 'Picture', value: 'ElIconPicture', component: 'ElIconPicture' },
 | 
				
			||||||
 | 
					  { id: 'icon-folder', type: 'system', display: 'Folder', value: 'ElIconFolder', component: 'ElIconFolder' },
 | 
				
			||||||
 | 
					  { id: 'icon-setting', type: 'system', display: 'Setting', value: 'ElIconSetting', component: 'ElIconSetting' },
 | 
				
			||||||
 | 
					  { id: 'icon-user', type: 'system', display: 'User', value: 'ElIconUser', component: 'ElIconUser' },
 | 
				
			||||||
 | 
					  // System Images (示例 URLs)
 | 
				
			||||||
 | 
					  { id: 'img-placeholder-1', type: 'system', display: 'https://via.placeholder.com/50x50?text=Img1', value: 'https://via.placeholder.com/50x50?text=Img1' },
 | 
				
			||||||
 | 
					  { id: 'img-placeholder-2', type: 'system', display: 'https://via.placeholder.com/50x50?text=Img2', value: 'https://via.placeholder.com/50x50?text=Img2' },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 加载默认系统项
 | 
				
			||||||
 | 
					// onMounted(() => {
 | 
				
			||||||
 | 
					//   items.value = [...defaultSystemItems];
 | 
				
			||||||
 | 
					// });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 监听 visible prop 变化,同步弹窗状态并处理回显
 | 
				
			||||||
 | 
					// watch(() => props.visible, (newVal) => {
 | 
				
			||||||
 | 
					//   dialogVisible.value = newVal;
 | 
				
			||||||
 | 
					//   if (newVal) {
 | 
				
			||||||
 | 
					//     // 弹窗打开时,根据 initialValue 查找并选中对应的项
 | 
				
			||||||
 | 
					//     selectedItem.value = items.value.find(item => item.value === props.initialValue) || null;
 | 
				
			||||||
 | 
					//   } else {
 | 
				
			||||||
 | 
					//     // 弹窗关闭时,重置选中状态
 | 
				
			||||||
 | 
					//     selectedItem.value = null;
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					// });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 处理文件上传变化
 | 
				
			||||||
 | 
					const handleFileChange = (uploadFile) => {
 | 
				
			||||||
 | 
					  const file = uploadFile.raw;
 | 
				
			||||||
 | 
					  if (!file) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 检查文件类型
 | 
				
			||||||
 | 
					  if (!file.type.startsWith('image/')) {
 | 
				
			||||||
 | 
					    ElMessage.error('只能上传图片文件!');
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 检查文件大小 (可选)
 | 
				
			||||||
 | 
					  // const isLt2M = file.size / 1024 / 1024 < 2;
 | 
				
			||||||
 | 
					  // if (!isLt2M) {
 | 
				
			||||||
 | 
					  //   ElMessage.error('图片文件大小不能超过 2MB!');
 | 
				
			||||||
 | 
					  //   return;
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const reader = new FileReader();
 | 
				
			||||||
 | 
					  reader.onloadend = () => {
 | 
				
			||||||
 | 
					    const base64String = reader.result;
 | 
				
			||||||
 | 
					    const newItem = {
 | 
				
			||||||
 | 
					      id: `local-${Date.now()}-${Math.random().toString(16).slice(2)}`, // 确保唯一ID
 | 
				
			||||||
 | 
					      type: 'local',
 | 
				
			||||||
 | 
					      display: base64String, // Base64 用于显示
 | 
				
			||||||
 | 
					      value: base64String // Base64 用于返回
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    items.value.push(newItem);
 | 
				
			||||||
 | 
					    // 自动选中新上传的图片 (可选)
 | 
				
			||||||
 | 
					    // selectedItem.value = newItem;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  reader.readAsDataURL(file);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 选中一个项
 | 
				
			||||||
 | 
					const selectItem = (item) => {
 | 
				
			||||||
 | 
					  selectedItem.value = item;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 处理确定按钮点击
 | 
				
			||||||
 | 
					const handleConfirm = () => {
 | 
				
			||||||
 | 
					  if (selectedItem.value) {
 | 
				
			||||||
 | 
					    // 返回选中项的 value (URL 或 Base64)
 | 
				
			||||||
 | 
					    emit('confirm', selectedItem.value.value);
 | 
				
			||||||
 | 
					    // 关闭弹窗
 | 
				
			||||||
 | 
					    emit('update:visible', false);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 处理取消按钮点击或弹窗关闭
 | 
				
			||||||
 | 
					const handleCancel = () => {
 | 
				
			||||||
 | 
					  emit('update:visible', false);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 将 Element Plus Icons 暴露给模板使用 (如果按需导入)
 | 
				
			||||||
 | 
					// 如果是全局注册,则不需要这一步
 | 
				
			||||||
 | 
					const icons = ElementPlusIconsVue;
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.image-library-content {
 | 
				
			||||||
 | 
					  padding: 0 20px 20px 20px;
 | 
				
			||||||
 | 
					  /* 调整内边距 */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.upload-area {
 | 
				
			||||||
 | 
					  margin-bottom: 20px;
 | 
				
			||||||
 | 
					  text-align: right;
 | 
				
			||||||
 | 
					  /* 让上传按钮靠右 */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.item-list {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-wrap: wrap;
 | 
				
			||||||
 | 
					  gap: 10px;
 | 
				
			||||||
 | 
					  /* 项之间的间距 */
 | 
				
			||||||
 | 
					  max-height: 300px;
 | 
				
			||||||
 | 
					  /* 限制列表高度并添加滚动条 */
 | 
				
			||||||
 | 
					  overflow-y: auto;
 | 
				
			||||||
 | 
					  padding-right: 10px;
 | 
				
			||||||
 | 
					  /* 为滚动条留出空间 */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.item {
 | 
				
			||||||
 | 
					  width: 60px;
 | 
				
			||||||
 | 
					  /* 项的固定宽度 */
 | 
				
			||||||
 | 
					  height: 60px;
 | 
				
			||||||
 | 
					  /* 项的固定高度 */
 | 
				
			||||||
 | 
					  border: 1px solid #dcdfe6;
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					  transition: border-color 0.3s;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  /* 防止图片溢出 */
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.item:hover {
 | 
				
			||||||
 | 
					  border-color: #409eff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.item.is-selected {
 | 
				
			||||||
 | 
					  border-color: #409eff;
 | 
				
			||||||
 | 
					  box-shadow: 0 0 5px rgba(64, 158, 255, 0.5);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.item-image {
 | 
				
			||||||
 | 
					  max-width: 100%;
 | 
				
			||||||
 | 
					  max-height: 100%;
 | 
				
			||||||
 | 
					  object-fit: contain;
 | 
				
			||||||
 | 
					  /* 保持图片比例 */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.item-placeholder {
 | 
				
			||||||
 | 
					  font-size: 12px;
 | 
				
			||||||
 | 
					  color: #909399;
 | 
				
			||||||
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 调整 Element Plus Icon 的样式 */
 | 
				
			||||||
 | 
					.item .el-icon {
 | 
				
			||||||
 | 
					  font-size: 30px;
 | 
				
			||||||
 | 
					  /* 确保图标大小合适 */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,155 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="app-container">
 | 
				
			||||||
 | 
					    <el-card style="margin-bottom: 12px;" shadow="always" v-show="showSearch">
 | 
				
			||||||
 | 
					      <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="68px">
 | 
				
			||||||
 | 
					        <el-form-item label="样式名称" prop="styleName">
 | 
				
			||||||
 | 
					          <el-input v-model="queryParams.styleName" placeholder="请输入样式名称" clearable></el-input>
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					        <el-form-item label="样式类型" prop="styleType">
 | 
				
			||||||
 | 
					          <el-select clearable v-model="queryParams.styleType" style="width: 200px" placeholder="请选择样式类型">
 | 
				
			||||||
 | 
					            <el-option v-for="type in styleTypeList" :key="type.value" :label="type.label" :value="type.value" />
 | 
				
			||||||
 | 
					          </el-select>
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					        <el-form-item>
 | 
				
			||||||
 | 
					          <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
 | 
				
			||||||
 | 
					          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					      </el-form>
 | 
				
			||||||
 | 
					    </el-card>
 | 
				
			||||||
 | 
					    <el-card shadow="always" class="list-table-section">
 | 
				
			||||||
 | 
					      <template #header>
 | 
				
			||||||
 | 
					        <el-row :gutter="10" class="mb8">
 | 
				
			||||||
 | 
					          <el-col :span="1.5">
 | 
				
			||||||
 | 
					            <el-button type="primary" plain icon="Plus" @click="formDialogRef.show()">新增</el-button>
 | 
				
			||||||
 | 
					          </el-col>
 | 
				
			||||||
 | 
					          <el-col :span="1.5">
 | 
				
			||||||
 | 
					            <el-button type="success" plain icon="Edit" :disabled="single" @click="formDialogRef.show(ids[0])">修改</el-button>
 | 
				
			||||||
 | 
					          </el-col>
 | 
				
			||||||
 | 
					          <el-col :span="1.5">
 | 
				
			||||||
 | 
					            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
 | 
				
			||||||
 | 
					          </el-col>
 | 
				
			||||||
 | 
					          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
 | 
				
			||||||
 | 
					        </el-row>
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					      <el-table v-loading="loading" :data="styleList" @selection-change="handleSelectionChange">
 | 
				
			||||||
 | 
					        <el-table-column type="selection" width="55" align="center" />
 | 
				
			||||||
 | 
					        <el-table-column label="样式名称" align="center" prop="styleName" />
 | 
				
			||||||
 | 
					        <el-table-column label="样式类型" align="center" prop="styleType">
 | 
				
			||||||
 | 
					          <template #default="{ row }">
 | 
				
			||||||
 | 
					            <!-- <el-tag type="primary" v-for="(type, index) in row.type.split(',')" :key="index">
 | 
				
			||||||
 | 
												{{ styleTypeList.find(item => item.id === type) }}
 | 
				
			||||||
 | 
											</el-tag> -->
 | 
				
			||||||
 | 
					            <el-tag v-for="(dict, index) in styleTypeList"
 | 
				
			||||||
 | 
					              v-show="row.styleType === dict.value" :key="index">{{ dict.label }}</el-tag>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					        </el-table-column>
 | 
				
			||||||
 | 
					        <el-table-column label="描述信息" align="center" prop="description" />
 | 
				
			||||||
 | 
					        <el-table-column label="操作" width="300" align="center" class-name="small-padding fixed-width">
 | 
				
			||||||
 | 
					          <template #default="{ row }">
 | 
				
			||||||
 | 
					            <el-tooltip content="修改" placement="top">
 | 
				
			||||||
 | 
					              <el-button link type="primary" icon="Edit" @click="formDialogRef.show(row.id)"></el-button>
 | 
				
			||||||
 | 
					            </el-tooltip>
 | 
				
			||||||
 | 
					            <el-tooltip content="删除" placement="top">
 | 
				
			||||||
 | 
					              <el-button link type="primary" icon="Delete" @click="handleDelete(row)"></el-button>
 | 
				
			||||||
 | 
					            </el-tooltip>
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					        </el-table-column>
 | 
				
			||||||
 | 
					      </el-table>
 | 
				
			||||||
 | 
					    </el-card>
 | 
				
			||||||
 | 
					    <div class="page-wrap">
 | 
				
			||||||
 | 
					      <pagination class="list-page" v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
 | 
				
			||||||
 | 
					        v-model:limit="queryParams.pageSize" @pagination="getList" />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  <style-dialog ref="formDialogRef" @refresh="getList()" />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup name="configStyle">
 | 
				
			||||||
 | 
					import { getStyleType, listStyle, delStyle  } from "@/api/gisManagement/configStyle"
 | 
				
			||||||
 | 
					import styleDialog from "./styleDialog.vue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const { proxy } = getCurrentInstance()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const styleTypeList = ref([])
 | 
				
			||||||
 | 
					const styleList = ref([])
 | 
				
			||||||
 | 
					const loading = ref(true)
 | 
				
			||||||
 | 
					const showSearch = ref(true)
 | 
				
			||||||
 | 
					const ids = ref([])
 | 
				
			||||||
 | 
					const single = ref(true)
 | 
				
			||||||
 | 
					const multiple = ref(true)
 | 
				
			||||||
 | 
					const total = ref(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const formDialogRef = ref()
 | 
				
			||||||
 | 
					const queryParams = ref({
 | 
				
			||||||
 | 
					  pageNum: 1,
 | 
				
			||||||
 | 
					  pageSize: 10,
 | 
				
			||||||
 | 
					  styleName: '',
 | 
				
			||||||
 | 
					  styleType: null
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 初始化 */
 | 
				
			||||||
 | 
					function init() {
 | 
				
			||||||
 | 
					  // 获取样式类型
 | 
				
			||||||
 | 
					  getStyleType().then(response => {
 | 
				
			||||||
 | 
					    styleTypeList.value = response
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 查询用户信息列表 */
 | 
				
			||||||
 | 
					function getList() {
 | 
				
			||||||
 | 
					  loading.value = true
 | 
				
			||||||
 | 
					  listStyle(queryParams.value).then(response => {
 | 
				
			||||||
 | 
					    styleList.value = response.rows
 | 
				
			||||||
 | 
					    total.value = response.total
 | 
				
			||||||
 | 
					    loading.value = false
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 搜索按钮操作 */
 | 
				
			||||||
 | 
					function handleQuery() {
 | 
				
			||||||
 | 
					  queryParams.value.pageNum = 1
 | 
				
			||||||
 | 
					  getList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 重置按钮操作 */
 | 
				
			||||||
 | 
					function resetQuery() {
 | 
				
			||||||
 | 
					  proxy.resetForm("queryRef")
 | 
				
			||||||
 | 
					  handleQuery()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 多选框选中数据
 | 
				
			||||||
 | 
					function handleSelectionChange(selection) {
 | 
				
			||||||
 | 
					  ids.value = selection.map(item => item.id)
 | 
				
			||||||
 | 
					  single.value = selection.length != 1
 | 
				
			||||||
 | 
					  multiple.value = !selection.length
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 删除按钮操作 */
 | 
				
			||||||
 | 
					function handleDelete(row) {
 | 
				
			||||||
 | 
					  const _userIds = row.id || ids.value
 | 
				
			||||||
 | 
					  proxy.$modal.confirm('是否确认删除勾选的数据项?').then(function () {
 | 
				
			||||||
 | 
					    return delStyle(_userIds)
 | 
				
			||||||
 | 
					  }).then(() => {
 | 
				
			||||||
 | 
					    getList()
 | 
				
			||||||
 | 
					    proxy.$modal.msgSuccess("删除成功")
 | 
				
			||||||
 | 
					  }).catch(() => { })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					init()
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.app-container {
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  height: calc(100vh - 84px);
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.list-table-section {
 | 
				
			||||||
 | 
					  flex: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,728 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-dialog v-model="showDialog" :title="title" width="800px" destroy-on-close>
 | 
				
			||||||
 | 
					    <div class="form-wrapper">
 | 
				
			||||||
 | 
					      <div class="base-container">
 | 
				
			||||||
 | 
					        <el-form class="base-info" :model="form" ref="formRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-form-item label="样式名称" prop="styleName">
 | 
				
			||||||
 | 
					            <el-input v-model="form.styleName" placeholder="请输入样式名称" clearable></el-input>
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-form-item label="样式类型" prop="styleType">
 | 
				
			||||||
 | 
					            <el-select clearable v-model="form.styleType" placeholder="请选择样式类型" @change="handleTypeChange">
 | 
				
			||||||
 | 
					              <el-option v-for="type in styleTypeList" :key="type.value" :label="type.label" :value="type.value" />
 | 
				
			||||||
 | 
					            </el-select>
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-form-item label="描述" prop="description">
 | 
				
			||||||
 | 
					            <el-input v-model="form.description" type="textarea" :autosize="{ minRows: 4, maxRows: 4 }" resize="none"
 | 
				
			||||||
 | 
					              placeholder="请输入描述信息"></el-input>
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12" v-if="form.styleType === 'point'">
 | 
				
			||||||
 | 
					              <el-form-item label="显示图标" prop="showBillboard">
 | 
				
			||||||
 | 
					                <el-switch v-model="showBillboard" @change="refreshMap" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12" v-if="['point', 'polyline', 'polygon', 'billboard'].includes(form.styleType)">
 | 
				
			||||||
 | 
					              <el-form-item label="显示标签" prop="showLabel">
 | 
				
			||||||
 | 
					                <el-switch v-model="showLabel" @change="refreshMap" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					        <div class="map-preview">
 | 
				
			||||||
 | 
					          <cesium-map :options="mapOptions" @init="initMap" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="sub-container">
 | 
				
			||||||
 | 
					        <!-- 点样式 -->
 | 
				
			||||||
 | 
					        <el-form v-if="showPoint" :model="formPoint" ref="formPointRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-divider content-position="left" class="style-title">点样式配置</el-divider>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="像素大小" prop="pixelSize">
 | 
				
			||||||
 | 
					                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
 | 
				
			||||||
 | 
					                <el-input-number v-model="formPoint.pixelSize" :min="1" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="color">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formPoint.color" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-form-item label="轮廓线" prop="showOutline">
 | 
				
			||||||
 | 
					            <el-switch v-model="formPoint.showOutline" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-row v-if="formPoint.showOutline" :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="宽度" prop="outlineWidth">
 | 
				
			||||||
 | 
					                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
 | 
				
			||||||
 | 
					                <el-input-number v-model="formPoint.outlineWidth" :min="1" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="outlineColor">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formPoint.outlineColor" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					        <!-- 线样式 -->
 | 
				
			||||||
 | 
					        <el-form v-if="showPolyline" :model="formPolyline" ref="formPolylineRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-divider content-position="left" class="style-title">线样式配置</el-divider>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="宽度" prop="width">
 | 
				
			||||||
 | 
					                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
 | 
				
			||||||
 | 
					                <el-input-number v-model="formPolyline.width" :min="1" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="color">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formPolyline.color" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-form-item label="闭合" prop="closed">
 | 
				
			||||||
 | 
					            <el-switch v-model="formPolyline.closed" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					        <!-- 面样式 -->
 | 
				
			||||||
 | 
					        <el-form v-if="showPolygon" :model="formPolygon" ref="formPolygonRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-divider content-position="left" class="style-title">面样式配置</el-divider>
 | 
				
			||||||
 | 
					          <el-form-item label="填充颜色" prop="color">
 | 
				
			||||||
 | 
					            <el-color-picker v-model="formPolygon.color" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-form-item label="轮廓线" prop="showOutline">
 | 
				
			||||||
 | 
					            <el-switch v-model="formPolygon.showOutline" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-row v-if="formPolygon.showOutline" :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="宽度" prop="outlineWidth">
 | 
				
			||||||
 | 
					                <!-- <el-input v-model="form.styleName" placeholder="请输入像素大小" clearable></el-input> -->
 | 
				
			||||||
 | 
					                <el-input-number v-model="formPolygon.outlineWidth" :min="1" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="outlineColor">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formPolygon.outlineColor" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					        <!-- 图标样式 -->
 | 
				
			||||||
 | 
					        <el-form v-if="showBillboard" :model="formBillboard" ref="formBillboardRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-divider content-position="left" class="style-title">图标样式配置</el-divider>
 | 
				
			||||||
 | 
					          <el-form-item label="图片" prop="image">
 | 
				
			||||||
 | 
					            <el-image class="style-billboard-image" :src="formBillboard.image" fit="contain"
 | 
				
			||||||
 | 
					              @click="handleIconSelect" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="缩放" prop="scale">
 | 
				
			||||||
 | 
					                <el-slider v-model="formBillboard.scale" :max="5" :min="0.1" :step="0.1" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="旋转" prop="rotation">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formBillboard.rotation" :min="0" :max="360" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="横向定位" prop="horizontalOrigin">
 | 
				
			||||||
 | 
					                <el-select v-model="formBillboard.horizontalOrigin" placeholder="请选择横向定位">
 | 
				
			||||||
 | 
					                  <el-option v-for="item in horizontalOriginTypeList" :key="item.value" :label="item.label"
 | 
				
			||||||
 | 
					                    :value="item.value" />
 | 
				
			||||||
 | 
					                </el-select>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="纵向定位" prop="verticalOrigin">
 | 
				
			||||||
 | 
					                <el-select v-model="formBillboard.verticalOrigin" placeholder="请选择纵向定位">
 | 
				
			||||||
 | 
					                  <el-option v-for="item in verticalOriginTypeList" :key="item.value" :label="item.label"
 | 
				
			||||||
 | 
					                    :value="item.value" />
 | 
				
			||||||
 | 
					                </el-select>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="横向偏移" prop="horizontalOffset">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formBillboard.horizontalOffset" style="width: calc(100% - 60px);" />
 | 
				
			||||||
 | 
					                <span style="margin-left: 8px;">(右为正)</span>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="纵向偏移" prop="verticalOffset">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formBillboard.verticalOffset" style="width: calc(100% - 60px);" />
 | 
				
			||||||
 | 
					                <span style="margin-left: 8px;">(下为正)</span>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					        <!-- 标签样式 -->
 | 
				
			||||||
 | 
					        <el-form v-if="showLabel" :model="formLabel" ref="formLabelRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-divider content-position="left" class="style-title">标签样式配置</el-divider>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="字号" prop="font">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formLabel.font" :min="12" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="fillColor">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formLabel.fillColor" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-form-item label="轮廓线" prop="showOutline">
 | 
				
			||||||
 | 
					            <el-switch v-model="formLabel.showOutline" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-row v-if="formLabel.showOutline" :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="宽度" prop="outlineWidth">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formLabel.outlineWidth" :min="1" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="outlineColor">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formLabel.outlineColor" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-form-item label="背景" prop="showBackground">
 | 
				
			||||||
 | 
					            <el-switch v-model="formLabel.showBackground" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <el-row v-if="formLabel.showBackground" :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="横向内边距" prop="horizontalPadding">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formLabel.horizontalPadding" :min="0" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="纵向内边距" prop="verticalPadding">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formLabel.verticalPadding" :min="0" style="width: 100%;" />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="24">
 | 
				
			||||||
 | 
					              <el-form-item label="颜色" prop="backgroundColor">
 | 
				
			||||||
 | 
					                <el-color-picker v-model="formLabel.backgroundColor" show-alpha />
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="横向定位" prop="horizontalOrigin">
 | 
				
			||||||
 | 
					                <el-select v-model="formLabel.horizontalOrigin" placeholder="请选择横向定位">
 | 
				
			||||||
 | 
					                  <el-option v-for="item in horizontalOriginTypeList" :key="item.value" :label="item.label"
 | 
				
			||||||
 | 
					                    :value="item.value" />
 | 
				
			||||||
 | 
					                </el-select>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="纵向定位" prop="verticalOrigin">
 | 
				
			||||||
 | 
					                <el-select v-model="formLabel.verticalOrigin" placeholder="请选择纵向定位">
 | 
				
			||||||
 | 
					                  <el-option v-for="item in verticalOriginTypeList" :key="item.value" :label="item.label"
 | 
				
			||||||
 | 
					                    :value="item.value" />
 | 
				
			||||||
 | 
					                </el-select>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					          <el-row :gutter="20">
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="横向偏移" prop="horizontalOffset">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formLabel.horizontalOffset" style="width: calc(100% - 60px);" />
 | 
				
			||||||
 | 
					                <span style="margin-left: 8px;">(右为正)</span>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					            <el-col :span="12">
 | 
				
			||||||
 | 
					              <el-form-item label="纵向偏移" prop="verticalOffset">
 | 
				
			||||||
 | 
					                <el-input-number v-model="formLabel.verticalOffset" style="width: calc(100% - 60px);" />
 | 
				
			||||||
 | 
					                <span style="margin-left: 8px;">(下为正)</span>
 | 
				
			||||||
 | 
					              </el-form-item>
 | 
				
			||||||
 | 
					            </el-col>
 | 
				
			||||||
 | 
					          </el-row>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					        <!-- 通用样式 -->
 | 
				
			||||||
 | 
					        <el-form :model="formCommon" ref="formCommonRef" :label-width="labelWidth">
 | 
				
			||||||
 | 
					          <el-divider content-position="left" class="style-title">通用样式配置</el-divider>
 | 
				
			||||||
 | 
					          <el-form-item label="贴地" prop="clampToGround">
 | 
				
			||||||
 | 
					            <el-switch v-model="formCommon.clampToGround" />
 | 
				
			||||||
 | 
					          </el-form-item>
 | 
				
			||||||
 | 
					          <div v-if="['point', 'billboard', 'label'].includes(form.styleType)">
 | 
				
			||||||
 | 
					            <el-form-item label="按视距缩放" prop="scaleByDistance">
 | 
				
			||||||
 | 
					              <el-switch v-model="formCommon.scaleByDistance" />
 | 
				
			||||||
 | 
					            </el-form-item>
 | 
				
			||||||
 | 
					            <el-row v-if="formCommon.scaleByDistance" :gutter="20">
 | 
				
			||||||
 | 
					              <el-col :span="12">
 | 
				
			||||||
 | 
					                <el-form-item label="缩放近视距" prop="scaleNear">
 | 
				
			||||||
 | 
					                  <el-input-number v-model="formCommon.scaleNear" :min="0" style="width: 100%;" />
 | 
				
			||||||
 | 
					                </el-form-item>
 | 
				
			||||||
 | 
					              </el-col>
 | 
				
			||||||
 | 
					              <el-col :span="12">
 | 
				
			||||||
 | 
					                <el-form-item label="缩放比例" prop="scaleNearValue">
 | 
				
			||||||
 | 
					                  <el-input-number v-model="formCommon.scaleNearValue" style="width: 100%;" />
 | 
				
			||||||
 | 
					                </el-form-item>
 | 
				
			||||||
 | 
					              </el-col>
 | 
				
			||||||
 | 
					            </el-row>
 | 
				
			||||||
 | 
					            <el-row v-if="formCommon.scaleByDistance" :gutter="20">
 | 
				
			||||||
 | 
					              <el-col :span="12">
 | 
				
			||||||
 | 
					                <el-form-item label="缩放远视距" prop="scaleFar">
 | 
				
			||||||
 | 
					                  <el-input-number v-model="formCommon.scaleFar" :min="1" style="width: 100%;" />
 | 
				
			||||||
 | 
					                </el-form-item>
 | 
				
			||||||
 | 
					              </el-col>
 | 
				
			||||||
 | 
					              <el-col :span="12">
 | 
				
			||||||
 | 
					                <el-form-item label="缩放比例" prop="scaleFarValue">
 | 
				
			||||||
 | 
					                  <el-input-number v-model="formCommon.scaleFarValue" style="width: 100%;" />
 | 
				
			||||||
 | 
					                </el-form-item>
 | 
				
			||||||
 | 
					              </el-col>
 | 
				
			||||||
 | 
					            </el-row>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </el-form>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <icon-dialog ref="iconDialog" v-model:current="formBillboard.image" v-model="showIconDialog" />
 | 
				
			||||||
 | 
					    <template #footer>
 | 
				
			||||||
 | 
					      <div class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button @click="handleCancel">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click="handleConfirm">保存</el-button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </el-dialog>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup name="styleDialog">
 | 
				
			||||||
 | 
					import * as Cesium from 'cesium'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import CesiumMap from '@/components/CesiumMap/index.vue';
 | 
				
			||||||
 | 
					import { getStyle } from "@/components/CesiumMap/utils/styleFn";
 | 
				
			||||||
 | 
					import { createFeature } from "@/components/CesiumMap/utils/layerFn";
 | 
				
			||||||
 | 
					import IconDialog from "./iconDialog.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { getStyleType, getStyle as getStyleApi, addStyle, updateStyle } from "@/api/gisManagement/configStyle"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import checkPointIcon from '@/assets/icons/example/check_point.png'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const emits = defineEmits(['refresh'])
 | 
				
			||||||
 | 
					const { proxy } = getCurrentInstance()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const showDialog = ref(false)
 | 
				
			||||||
 | 
					const title = ref('');
 | 
				
			||||||
 | 
					const labelWidth = '85px'
 | 
				
			||||||
 | 
					let viewer = null
 | 
				
			||||||
 | 
					let entity = null
 | 
				
			||||||
 | 
					const defaultPoint = [102, 25]
 | 
				
			||||||
 | 
					const defaultPosition = Cesium.Cartesian3.fromDegrees(...defaultPoint)
 | 
				
			||||||
 | 
					const defaultPolyline = Cesium.Cartesian3.fromDegreesArray([102.1, 24.9, 102.1, 25.1, 101.9, 24.9, 101.9, 25.2])
 | 
				
			||||||
 | 
					const defaultPolygon = Cesium.Cartesian3.fromDegreesArray([102.1, 24.9, 102.1, 25.1, 101.9, 25.1, 101.9, 24.9])
 | 
				
			||||||
 | 
					const mapOptions = {
 | 
				
			||||||
 | 
					  setView: {
 | 
				
			||||||
 | 
					    x: defaultPoint[0],
 | 
				
			||||||
 | 
					    y: defaultPoint[1],
 | 
				
			||||||
 | 
					    z: 5000,
 | 
				
			||||||
 | 
					    heading: 0,
 | 
				
			||||||
 | 
					    pitch: -90,
 | 
				
			||||||
 | 
					    roll: 0
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					const styleTypeList = ref([])
 | 
				
			||||||
 | 
					const horizontalOriginTypeList = ref([
 | 
				
			||||||
 | 
					  { label: '左', value: 1 },
 | 
				
			||||||
 | 
					  { label: '中', value: 0 },
 | 
				
			||||||
 | 
					  { label: '右', value: -1 }
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					const verticalOriginTypeList = ref([
 | 
				
			||||||
 | 
					  { label: '上', value: -1 },
 | 
				
			||||||
 | 
					  { label: '中', value: 0 },
 | 
				
			||||||
 | 
					  { label: '下', value: 1 }
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					const form = ref({
 | 
				
			||||||
 | 
					  id: null,
 | 
				
			||||||
 | 
					  styleName: '',
 | 
				
			||||||
 | 
					  styleType: [],
 | 
				
			||||||
 | 
					  description: '',
 | 
				
			||||||
 | 
					  config: '',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const showPoint = ref(false)
 | 
				
			||||||
 | 
					const formPoint = ref({
 | 
				
			||||||
 | 
					  pixelSize: 10,
 | 
				
			||||||
 | 
					  color: '#ffffff',
 | 
				
			||||||
 | 
					  showOutline: false,
 | 
				
			||||||
 | 
					  outlineWidth: 1,
 | 
				
			||||||
 | 
					  outlineColor: '#000000',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const showPolyline = ref(false)
 | 
				
			||||||
 | 
					const formPolyline = ref({
 | 
				
			||||||
 | 
					  width: 1,
 | 
				
			||||||
 | 
					  color: '#ffffff',
 | 
				
			||||||
 | 
					  closed: false,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const showPolygon = ref(false)
 | 
				
			||||||
 | 
					const formPolygon = ref({
 | 
				
			||||||
 | 
					  color: '#ffffff',
 | 
				
			||||||
 | 
					  showOutline: false,
 | 
				
			||||||
 | 
					  outlineWidth: 1,
 | 
				
			||||||
 | 
					  outlineColor: '#000000',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const showBillboard = ref(false)
 | 
				
			||||||
 | 
					const formBillboard = ref({
 | 
				
			||||||
 | 
					  image: checkPointIcon,
 | 
				
			||||||
 | 
					  scale: 1,
 | 
				
			||||||
 | 
					  rotation: 0,
 | 
				
			||||||
 | 
					  horizontalOrigin: 0,
 | 
				
			||||||
 | 
					  verticalOrigin: 1,
 | 
				
			||||||
 | 
					  horizontalOffset: 0,
 | 
				
			||||||
 | 
					  verticalOffset: 0,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const showIconDialog = ref(false)
 | 
				
			||||||
 | 
					const showLabel = ref(false)
 | 
				
			||||||
 | 
					const formLabel = ref({
 | 
				
			||||||
 | 
					  font: 12,
 | 
				
			||||||
 | 
					  fillColor: '#ffffff',
 | 
				
			||||||
 | 
					  showOutline: false,
 | 
				
			||||||
 | 
					  outlineWidth: 1,
 | 
				
			||||||
 | 
					  outlineColor: '#000000',
 | 
				
			||||||
 | 
					  showBackground: false,
 | 
				
			||||||
 | 
					  backgroundColor: 'rgba(42, 42, 42, 0.8)',
 | 
				
			||||||
 | 
					  horizontalPadding: 0,
 | 
				
			||||||
 | 
					  verticalPadding: 0,
 | 
				
			||||||
 | 
					  horizontalOrigin: 0,
 | 
				
			||||||
 | 
					  verticalOrigin: 1,
 | 
				
			||||||
 | 
					  horizontalOffset: 0,
 | 
				
			||||||
 | 
					  verticalOffset: 0,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					const formCommon = ref({
 | 
				
			||||||
 | 
					  clampToGround: true,
 | 
				
			||||||
 | 
					  scaleByDistance: false,
 | 
				
			||||||
 | 
					  scaleNear: 0,
 | 
				
			||||||
 | 
					  scaleNearValue: 0,
 | 
				
			||||||
 | 
					  scaleFar: 1,
 | 
				
			||||||
 | 
					  scaleFarValue: 0,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 打开弹窗的方法
 | 
				
			||||||
 | 
					 * @param id 样式id
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const show = async (id) => {
 | 
				
			||||||
 | 
					  reset()
 | 
				
			||||||
 | 
					  if (id) {
 | 
				
			||||||
 | 
					    title.value = '修改样式信息'
 | 
				
			||||||
 | 
					    getStyleApi(id).then(res => {
 | 
				
			||||||
 | 
					      // const data = response.data
 | 
				
			||||||
 | 
					      // form.value.styleName = data.styleName
 | 
				
			||||||
 | 
					      // form.value.styleType = data.styleType
 | 
				
			||||||
 | 
					      // form.value.description = data.description
 | 
				
			||||||
 | 
					      form.value = res.data
 | 
				
			||||||
 | 
					      const config = JSON.parse(form.value.config)
 | 
				
			||||||
 | 
					      if (config.point) {
 | 
				
			||||||
 | 
					        showPoint.value = true
 | 
				
			||||||
 | 
					        formPoint.value = config.point
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (config.polyline) {
 | 
				
			||||||
 | 
					        showPolyline.value = true
 | 
				
			||||||
 | 
					        formPolyline.value = config.polyline
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (config.polygon) {
 | 
				
			||||||
 | 
					        showPolygon.value = true
 | 
				
			||||||
 | 
					        formPolygon.value = config.polygon
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (config.billboard) {
 | 
				
			||||||
 | 
					        showBillboard.value = true
 | 
				
			||||||
 | 
					        formBillboard.value = config.billboard
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (config.label) {
 | 
				
			||||||
 | 
					        showLabel.value = true
 | 
				
			||||||
 | 
					        formLabel.value = config.label
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      formCommon.value = config.common
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    title.value = '新增样式信息'
 | 
				
			||||||
 | 
					    form.value.id = null
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // 获取样式类型
 | 
				
			||||||
 | 
					  getStyleType().then(response => {
 | 
				
			||||||
 | 
					    styleTypeList.value = response
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  showDialog.value = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 初始化地图
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const initMap = (viewerInstance) => {
 | 
				
			||||||
 | 
					  // 初始化地图变量
 | 
				
			||||||
 | 
					  viewer = viewerInstance
 | 
				
			||||||
 | 
					  // entity = viewer.entities.add({
 | 
				
			||||||
 | 
					  //   id: 'stylePreview',
 | 
				
			||||||
 | 
					  //   position: defaultPosition, // 默认位置
 | 
				
			||||||
 | 
					  // })
 | 
				
			||||||
 | 
					  // 设置不能平移
 | 
				
			||||||
 | 
					  viewer.camera.lookAt(
 | 
				
			||||||
 | 
					    defaultPosition, // 设置初始位置
 | 
				
			||||||
 | 
					    new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90), 5000) // 设置初始视角
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  refreshMap()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 样式类型改变, 切换配置项显示
 | 
				
			||||||
 | 
					 * @param {string} val 类型值
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const handleTypeChange = (val) => {
 | 
				
			||||||
 | 
					  if (val === 'point') {
 | 
				
			||||||
 | 
					    showPoint.value = true
 | 
				
			||||||
 | 
					    showPolyline.value = false
 | 
				
			||||||
 | 
					    showPolygon.value = false
 | 
				
			||||||
 | 
					    showBillboard.value = false
 | 
				
			||||||
 | 
					    showLabel.value = false
 | 
				
			||||||
 | 
					  } else if (val === 'polyline') {
 | 
				
			||||||
 | 
					    showPoint.value = false
 | 
				
			||||||
 | 
					    showPolyline.value = true
 | 
				
			||||||
 | 
					    showPolygon.value = false
 | 
				
			||||||
 | 
					    showBillboard.value = false
 | 
				
			||||||
 | 
					    showLabel.value = false
 | 
				
			||||||
 | 
					  } else if (val === 'polygon') {
 | 
				
			||||||
 | 
					    showPoint.value = false
 | 
				
			||||||
 | 
					    showPolyline.value = false
 | 
				
			||||||
 | 
					    showPolygon.value = true
 | 
				
			||||||
 | 
					    showBillboard.value = false
 | 
				
			||||||
 | 
					    showLabel.value = false
 | 
				
			||||||
 | 
					  } else if (val === 'billboard') {
 | 
				
			||||||
 | 
					    showPoint.value = false
 | 
				
			||||||
 | 
					    showPolyline.value = false
 | 
				
			||||||
 | 
					    showPolygon.value = false
 | 
				
			||||||
 | 
					    showBillboard.value = true
 | 
				
			||||||
 | 
					    showLabel.value = false
 | 
				
			||||||
 | 
					  } else if (val === 'label') {
 | 
				
			||||||
 | 
					    showPoint.value = false
 | 
				
			||||||
 | 
					    showPolyline.value = false
 | 
				
			||||||
 | 
					    showPolygon.value = false
 | 
				
			||||||
 | 
					    showBillboard.value = false
 | 
				
			||||||
 | 
					    showLabel.value = true
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // 隐藏所有样式配置项
 | 
				
			||||||
 | 
					    showPoint.value = false
 | 
				
			||||||
 | 
					    showPolyline.value = false
 | 
				
			||||||
 | 
					    showPolygon.value = false
 | 
				
			||||||
 | 
					    showBillboard.value = false
 | 
				
			||||||
 | 
					    showLabel.value = false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 打开图标选择对话框
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const handleIconSelect = () => {
 | 
				
			||||||
 | 
					  showIconDialog.value = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 刷新地图
 | 
				
			||||||
 | 
					 * 更新样式后触发
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const refreshMap = () => {
 | 
				
			||||||
 | 
					  if(!viewer) {
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const options = {
 | 
				
			||||||
 | 
					    type: form.value.styleType,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (showPoint.value) options.point = formPoint.value
 | 
				
			||||||
 | 
					  if (showPolyline.value) options.polyline = formPolyline.value
 | 
				
			||||||
 | 
					  if (showPolygon.value) options.polygon = formPolygon.value
 | 
				
			||||||
 | 
					  if (showBillboard.value) options.billboard = formBillboard.value
 | 
				
			||||||
 | 
					  if (showLabel.value) options.label = formLabel.value
 | 
				
			||||||
 | 
					  options.common = formCommon.value
 | 
				
			||||||
 | 
					  console.log('更新样式配置:', JSON.stringify(options))
 | 
				
			||||||
 | 
					  form.value.config = JSON.stringify(options)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (entity) {
 | 
				
			||||||
 | 
					    viewer.entities.remove(entity)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const style = getStyle(options)
 | 
				
			||||||
 | 
					  style.id = 'stylePreview'
 | 
				
			||||||
 | 
					  let position = defaultPosition
 | 
				
			||||||
 | 
					  if (style.properties?.type === 'polyline') {
 | 
				
			||||||
 | 
					    position = defaultPolyline
 | 
				
			||||||
 | 
					  } else if (style.properties?.type === 'polygon') {
 | 
				
			||||||
 | 
					    position = defaultPolygon
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  entity = createFeature(style, position, '测试')
 | 
				
			||||||
 | 
					  if (entity) {
 | 
				
			||||||
 | 
					    viewer.entities.add(entity)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const reset = () => {
 | 
				
			||||||
 | 
					  viewer = null
 | 
				
			||||||
 | 
					  entity = null
 | 
				
			||||||
 | 
					  form.value = {
 | 
				
			||||||
 | 
					    id: null,
 | 
				
			||||||
 | 
					    styleName: '',
 | 
				
			||||||
 | 
					    styleType: [],
 | 
				
			||||||
 | 
					    description: '',
 | 
				
			||||||
 | 
					    config: '',
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  showPoint.value = false
 | 
				
			||||||
 | 
					  formPoint.value = {
 | 
				
			||||||
 | 
					    pixelSize: 10,
 | 
				
			||||||
 | 
					    color: '#ffffff',
 | 
				
			||||||
 | 
					    showOutline: false,
 | 
				
			||||||
 | 
					    outlineWidth: 1,
 | 
				
			||||||
 | 
					    outlineColor: '#000000',
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  showPolyline.value = false
 | 
				
			||||||
 | 
					  formPolyline.value = {
 | 
				
			||||||
 | 
					    width: 1,
 | 
				
			||||||
 | 
					    color: '#ffffff',
 | 
				
			||||||
 | 
					    closed: false,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  showPolygon.value = false
 | 
				
			||||||
 | 
					  formPolygon.value = {
 | 
				
			||||||
 | 
					    color: '#ffffff',
 | 
				
			||||||
 | 
					    showOutline: false,
 | 
				
			||||||
 | 
					    outlineWidth: 1,
 | 
				
			||||||
 | 
					    outlineColor: '#000000',
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  showBillboard.value = false
 | 
				
			||||||
 | 
					  formBillboard.value = {
 | 
				
			||||||
 | 
					    image: checkPointIcon,
 | 
				
			||||||
 | 
					    scale: 1,
 | 
				
			||||||
 | 
					    rotation: 0,
 | 
				
			||||||
 | 
					    horizontalOrigin: 0,
 | 
				
			||||||
 | 
					    verticalOrigin: 1,
 | 
				
			||||||
 | 
					    horizontalOffset: 0,
 | 
				
			||||||
 | 
					    verticalOffset: 0,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  showLabel.value = false
 | 
				
			||||||
 | 
					  formLabel.value = {
 | 
				
			||||||
 | 
					    font: 12,
 | 
				
			||||||
 | 
					    fillColor: '#ffffff',
 | 
				
			||||||
 | 
					    showOutline: false,
 | 
				
			||||||
 | 
					    outlineWidth: 1,
 | 
				
			||||||
 | 
					    outlineColor: '#000000',
 | 
				
			||||||
 | 
					    showBackground: false,
 | 
				
			||||||
 | 
					    backgroundColor: 'rgba(42, 42, 42, 0.8)',
 | 
				
			||||||
 | 
					    horizontalPadding: 0,
 | 
				
			||||||
 | 
					    verticalPadding: 0,
 | 
				
			||||||
 | 
					    horizontalOrigin: 0,
 | 
				
			||||||
 | 
					    verticalOrigin: 1,
 | 
				
			||||||
 | 
					    horizontalOffset: 0,
 | 
				
			||||||
 | 
					    verticalOffset: 0,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  formCommon.value = {
 | 
				
			||||||
 | 
					    clampToGround: true,
 | 
				
			||||||
 | 
					    scaleByDistance: false,
 | 
				
			||||||
 | 
					    scaleNear: 0,
 | 
				
			||||||
 | 
					    scaleNearValue: 0,
 | 
				
			||||||
 | 
					    scaleFar: 1,
 | 
				
			||||||
 | 
					    scaleFarValue: 0,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 确定
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const handleConfirm = () => {
 | 
				
			||||||
 | 
					  // proxy.$refs["styleRef"].validate(valid => {
 | 
				
			||||||
 | 
					  //   if (valid) {
 | 
				
			||||||
 | 
					  //     if (form.value.userId != null) {
 | 
				
			||||||
 | 
					  //       updateUser(form.value).then(response => {
 | 
				
			||||||
 | 
					  //         proxy.$modal.msgSuccess("修改成功")
 | 
				
			||||||
 | 
					  //         open.value = false
 | 
				
			||||||
 | 
					  //         getList()
 | 
				
			||||||
 | 
					  //       })
 | 
				
			||||||
 | 
					  //     } else {
 | 
				
			||||||
 | 
					  //       addUser(form.value).then(response => {
 | 
				
			||||||
 | 
					  //         proxy.$modal.msgSuccess("新增成功")
 | 
				
			||||||
 | 
					  //         open.value = false
 | 
				
			||||||
 | 
					  //         getList()
 | 
				
			||||||
 | 
					  //       })
 | 
				
			||||||
 | 
					  //     }
 | 
				
			||||||
 | 
					  //   }
 | 
				
			||||||
 | 
					  // })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  proxy.$refs["formRef"].validate(valid => {
 | 
				
			||||||
 | 
					    if (valid) {
 | 
				
			||||||
 | 
					      if (form.value.id) {
 | 
				
			||||||
 | 
					        updateStyle(form.value).then(response => {
 | 
				
			||||||
 | 
					          proxy.$modal.msgSuccess("修改成功")
 | 
				
			||||||
 | 
					          emits('refresh', response)
 | 
				
			||||||
 | 
					          showDialog.value = false
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        addStyle(form.value).then(response => {
 | 
				
			||||||
 | 
					          proxy.$modal.msgSuccess("新增成功")
 | 
				
			||||||
 | 
					          emits('refresh', response)
 | 
				
			||||||
 | 
					          showDialog.value = false
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 取消
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const handleCancel = () => {
 | 
				
			||||||
 | 
					  showDialog.value = false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(form.value.styleType, (val) => {
 | 
				
			||||||
 | 
					  if (val === 'polyline' || val === 'polygon') {
 | 
				
			||||||
 | 
					    formCommon.value.scaleByDistance = false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(() => [form.value.styleType, formPoint, formPolyline, formPolygon, formBillboard, formLabel, formCommon], refreshMap, {
 | 
				
			||||||
 | 
					  deep: true
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineExpose({
 | 
				
			||||||
 | 
					  show
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.base-container {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .base-info {
 | 
				
			||||||
 | 
					    flex: auto;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .map-preview {
 | 
				
			||||||
 | 
					    width: 40%;
 | 
				
			||||||
 | 
					    min-width: 400px;
 | 
				
			||||||
 | 
					    height: 250px;
 | 
				
			||||||
 | 
					    margin-left: 20px;
 | 
				
			||||||
 | 
					    border: 1px solid var(--el-border-color);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sub-container {
 | 
				
			||||||
 | 
					  margin-top: 12px;
 | 
				
			||||||
 | 
					  max-height: calc(70vh - 290px);
 | 
				
			||||||
 | 
					  overflow-x: hidden;
 | 
				
			||||||
 | 
					  overflow-y: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.style-title {
 | 
				
			||||||
 | 
					  margin: 32px 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.style-billboard-image {
 | 
				
			||||||
 | 
					  width: 48px;
 | 
				
			||||||
 | 
					  height: 48px;
 | 
				
			||||||
 | 
					  border: 1px solid var(--el-border-color);
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||