622 lines
16 KiB
Vue
622 lines
16 KiB
Vue
<template>
|
||
<div class="main-content">
|
||
<div class="main-content-title">
|
||
<span>设备添加</span>
|
||
<el-icon size="16" color="#fff" @click="closeDiv"><Close /></el-icon>
|
||
</div>
|
||
<div class="operate-btn">
|
||
<div :class="operateIndex == 0 ? 'active-btn' : ''" @click="getRelativeData(0)">基础配置</div>
|
||
<div :class="operateIndex == 1 ? 'active-btn' : ''" @click="getRelativeData(1)">设备列表</div>
|
||
</div>
|
||
<div class="basic-config" v-show="operateIndex == 0">
|
||
<!-- <div class="switch-content">
|
||
<div>
|
||
<span>是否启用:</span>
|
||
<el-switch v-model="formData.enable" />
|
||
</div>
|
||
</div> -->
|
||
<div class="popup-style">
|
||
<span>弹窗样式:</span>
|
||
<CodeMirror
|
||
v-model:code="code"
|
||
dark
|
||
:codeStyle="{ width: '100%', height: '200px', fontSize: '16px' }"
|
||
:disabled="false"
|
||
:extensions="extensions"
|
||
@ready="onReady"
|
||
@change="onChange"
|
||
@focus="onFocus"
|
||
@blur="onBlur"
|
||
/>
|
||
</div>
|
||
<div class="btn-style">
|
||
<el-button type="primary" @click="saveStyle">保存</el-button>
|
||
</div>
|
||
<!-- <codemirror
|
||
v-model="code"
|
||
placeholder="Code goes here..."
|
||
:style="{ height: '400px' }"
|
||
:autofocus="true"
|
||
:indent-with-tab="true"
|
||
:tab-size="2"
|
||
:extensions="extensions"
|
||
@ready="onReady"
|
||
@change="onChange"
|
||
@focus="onFocus"
|
||
@blur="onBlur"
|
||
/>
|
||
<component :is="previewComp"></component> -->
|
||
</div>
|
||
<div class="equip-list" v-show="operateIndex == 1">
|
||
<div class="type-select">
|
||
<span>选择类型:</span>
|
||
<el-radio-group v-model="formData.showType">
|
||
<el-radio :label="1">类型1</el-radio>
|
||
<el-radio :label="2">类型2</el-radio>
|
||
</el-radio-group>
|
||
</div>
|
||
<el-table
|
||
:data="tableData"
|
||
rowKey="id"
|
||
:header-cell-style="{ backgroundColor: '#3359B5', color: '#fff', borderColor: '#3F5C8E' }"
|
||
>
|
||
<el-table-column prop="name" align="center" label="名称">
|
||
<template #default="{ row }">
|
||
<el-input v-model="row.name" v-if="row.isEdit" />
|
||
<span v-else>{{ row.name }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" label="操作">
|
||
<template #default="scope">
|
||
<span class="primaryBtn" v-if="scope.row.isEdit" @click="saveEdit(scope.row)">保存</span>
|
||
<span class="primaryBtn" v-if="!scope.row.isEdit" @click="scope.row.isEdit = true">编辑</span>
|
||
<span class="deleteBtn" @click="handleDeleteItem(scope.row, scope.$index)">删除</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="btn-style">
|
||
<el-button type="primary" @click="newPoint">新增(图上选点)</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
//引入cesium基础库
|
||
import "mars3d-cesium/Build/Cesium/Widgets/widgets.css";
|
||
import * as Cesium from "mars3d-cesium";
|
||
//导入mars3d主库
|
||
import "mars3d/dist/mars3d.css";
|
||
import * as mars3d from "mars3d";
|
||
import { defineAsyncComponent, ref, shallowRef, watch, onMounted, onUnmounted } from "vue";
|
||
import * as Vue from "vue";
|
||
// import { Codemirror } from "vue-codemirror";
|
||
import { javascript } from "@codemirror/lang-javascript";
|
||
import { vue } from "@codemirror/lang-vue";
|
||
import { oneDark } from "@codemirror/theme-one-dark";
|
||
import { loadModule } from "vue3-sfc-loader";
|
||
import { initVue3Popup } from "@/utils/file-util";
|
||
import QueryPopup from "./query-popup.vue";
|
||
import { ElMessage } from "element-plus";
|
||
import {
|
||
equipmentStyleGet,
|
||
equipmentStyleEdit,
|
||
equipmentList,
|
||
equipmentAdd,
|
||
equipmentEdit,
|
||
equipmentDelete
|
||
} from "@/api/modules/mapCommon";
|
||
const basicConfig = ref({} as any);
|
||
const tableData = ref<any>([]);
|
||
const baseUrl = import.meta.env.VITE_API_URL;
|
||
const formData = ref({
|
||
enable: false,
|
||
showType: 1
|
||
});
|
||
const operateIndex = ref(0);
|
||
const code = ref();
|
||
const previewComp = shallowRef();
|
||
const extensions = [vue(), oneDark];
|
||
import CodeMirror from "@/components/CodeMirror/index.vue";
|
||
const props = defineProps(["mapInstance", "graphicInstance", "equipTypeDictLabel"]);
|
||
const emits = defineEmits(["hiddenConfim"]);
|
||
let map: any = props.mapInstance;
|
||
let graphicLayer: any;
|
||
let parentGraphicLayer = props.graphicInstance;
|
||
// 获取相关tab数据
|
||
const getRelativeData = (index: any) => {
|
||
operateIndex.value = index;
|
||
if (index == 0) {
|
||
getStyle();
|
||
} else if (index == 1) {
|
||
getEquipList();
|
||
}
|
||
};
|
||
// 获取设备列表
|
||
const getEquipList = async () => {
|
||
const res = await equipmentList({ category: props.equipTypeDictLabel });
|
||
if (res.result && res.result.length > 0) {
|
||
tableData.value = res.result;
|
||
}
|
||
console.log(res);
|
||
};
|
||
// 保存基础配置
|
||
const saveStyle = async () => {
|
||
let requestData: any = {
|
||
style: code.value,
|
||
category: props.equipTypeDictLabel
|
||
};
|
||
if (basicConfig.value.id) {
|
||
requestData.id = basicConfig.value.id;
|
||
}
|
||
const res = await equipmentStyleEdit(requestData);
|
||
if (res) {
|
||
ElMessage.success("保存成功");
|
||
}
|
||
};
|
||
// 获取基础配置
|
||
const getStyle = async () => {
|
||
const res = await equipmentStyleGet({ category: props.equipTypeDictLabel }); // 获取设备样式
|
||
if (res.result) {
|
||
basicConfig.value = { ...res.result };
|
||
code.value = res.result.style;
|
||
onBlur();
|
||
}
|
||
};
|
||
// 保存编辑信息
|
||
const saveEdit = async (row: any) => {
|
||
let requestData = {
|
||
name: row.name,
|
||
monitorId: row.monitorId,
|
||
category: props.equipTypeDictLabel
|
||
};
|
||
const res = await equipmentEdit(requestData);
|
||
if (res && res.code == 200) {
|
||
let graphic = graphicLayer.getGraphicById(row.monitorId);
|
||
console.log(graphic, "子图像");
|
||
if (!graphic) {
|
||
graphic = parentGraphicLayer.getGraphicById(row.monitorId);
|
||
}
|
||
console.log(graphic, "父图像");
|
||
graphic.setStyle({
|
||
html: ` <div class="mars3d-camera-content ${getTypeStyle(1)}">
|
||
<span class="mars3d-camera-text">${row.name}</span>
|
||
</div>
|
||
<div class="mars3d-camera-line ${getTypeStyle(2)}" ></div>
|
||
<div class="mars3d-camera-point ${getTypeStyle(3)}"></div>
|
||
`
|
||
});
|
||
}
|
||
row.isEdit = false;
|
||
};
|
||
// 删除用户信息
|
||
const handleDeleteItem = async (row: any, index: any) => {
|
||
let requestData = {
|
||
monitorId: row.monitorId
|
||
};
|
||
const res = await equipmentDelete(requestData);
|
||
if (res && res.code == 200) {
|
||
let graphic = graphicLayer.getGraphicById(row.monitorId);
|
||
if (!graphic) {
|
||
graphic = parentGraphicLayer.getGraphicById(row.monitorId);
|
||
}
|
||
graphic && graphic.remove(true);
|
||
// await useHandleData(deleteBigItem, { id: params.id }, `删除【${params.name}】`);
|
||
tableData.value.splice(index, 1);
|
||
}
|
||
};
|
||
// 图上新增点
|
||
const newPoint = () => {
|
||
graphicLayer.startDraw({
|
||
id: "point-tip",
|
||
type: "point",
|
||
style: {
|
||
visibleDepth: false // 是否被遮挡
|
||
}
|
||
});
|
||
};
|
||
// 根据不同类型获取图片
|
||
const getTypeImage = () => {
|
||
let img: any;
|
||
if (formData.value.showType == 1) {
|
||
img = new URL("@/assets/images/Mars3DImg/icon/camera.svg", import.meta.url).href;
|
||
} else if (formData.value.showType == 2) {
|
||
img = new URL("@/assets/images/Mars3DImg/icon/fire.png", import.meta.url).href;
|
||
}
|
||
return img;
|
||
};
|
||
// 根据不同类型设置样式
|
||
const getTypeStyle = (num: any) => {
|
||
let borderSty: any;
|
||
let borderLeftSty: any;
|
||
let bgSty: any;
|
||
if (formData.value.showType == 1) {
|
||
borderSty = "mars3d-camera-style1";
|
||
borderLeftSty = "mars3d-borderLeft1";
|
||
bgSty = "mars3d-bg1";
|
||
} else if (formData.value.showType == 2) {
|
||
borderSty = "mars3d-camera-style2";
|
||
borderLeftSty = "mars3d-borderLeft2";
|
||
bgSty = "mars3d-bg2";
|
||
}
|
||
if (num == 1) {
|
||
return borderSty;
|
||
} else if (num == 2) {
|
||
return borderLeftSty;
|
||
} else if (num == 3) {
|
||
return bgSty;
|
||
}
|
||
};
|
||
// <img class="mars3d-camera-img" src="${getTypeImage()}" >
|
||
const addRandomGraphicByCount = async (point: any) => {
|
||
const graphicImg = new mars3d.graphic.DivGraphic({
|
||
position: [point.lng, point.lat, point.alt],
|
||
style: {
|
||
html: ` <div class="mars3d-camera-content ${getTypeStyle(1)}">
|
||
<span class="mars3d-camera-text"></span>
|
||
</div>
|
||
<div class="mars3d-camera-line ${getTypeStyle(2)}" ></div>
|
||
<div class="mars3d-camera-point ${getTypeStyle(3)}"></div>
|
||
`,
|
||
offsetX: -51,
|
||
offsetY: 4,
|
||
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 100000)
|
||
}
|
||
// popup: `${code.value}`,
|
||
// popupOptions: {
|
||
// offsetY: -170, // 显示Popup的偏移值,是DivGraphic本身的像素高度值
|
||
// template: `<div class="marsBlackPanel animation-spaceInDown">
|
||
// <div class="marsBlackPanel-text">{content}</div>
|
||
// <span class="mars3d-popup-close-button closeButton" >×</span>
|
||
// </div>`,
|
||
// horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||
// verticalOrigin: Cesium.VerticalOrigin.CENTER
|
||
// }
|
||
});
|
||
// const comp = () => import("http://jxjzw.zhgdyun.com:9001/wisdomsitezw/655c756d12b3a489008940c9.vue");
|
||
// console.log(comp);
|
||
// graphicImg.bindPopup("all");
|
||
graphicImg.bindPopup(
|
||
(event: any) => {
|
||
const attr = event.graphic.attr || {};
|
||
if (!attr) {
|
||
return;
|
||
}
|
||
const dom = initVue3Popup(previewComp.value, { name: "你好啊" });
|
||
// return mars3d.Util.getTemplateHtml({ title: "矢量图层", template: dom, attr: attr });
|
||
return dom;
|
||
},
|
||
{ offsetY: -170, offsetX: 50 }
|
||
);
|
||
graphicLayer.addGraphic(graphicImg);
|
||
console.log(graphicImg);
|
||
const obj = {
|
||
monitorId: graphicImg.id,
|
||
name: graphicImg.name,
|
||
type: formData.value.showType,
|
||
lng: point.lng,
|
||
lat: point.lat,
|
||
alt: point.alt,
|
||
isEdit: false
|
||
};
|
||
let requestData = {
|
||
name: obj.name,
|
||
monitorId: obj.monitorId,
|
||
category: props.equipTypeDictLabel,
|
||
type: formData.value.showType,
|
||
lng: point.lng,
|
||
lat: point.lat,
|
||
alt: point.alt
|
||
};
|
||
const res = await equipmentAdd(requestData);
|
||
if (res && res.code == 200) {
|
||
tableData.value.unshift(obj);
|
||
} else {
|
||
let htmlGraphic = graphicLayer.getGraphicById(graphicImg.id);
|
||
if (!htmlGraphic) {
|
||
htmlGraphic = parentGraphicLayer.getGraphicById(graphicImg.id);
|
||
}
|
||
htmlGraphic && htmlGraphic.remove(true);
|
||
}
|
||
console.log(graphicLayer);
|
||
const pointGraphic = graphicLayer.getGraphicById("point-tip");
|
||
pointGraphic && pointGraphic.remove(true);
|
||
};
|
||
const closeDiv = () => {
|
||
emits("hiddenConfim");
|
||
};
|
||
const onReady = (payload: any) => {
|
||
console.log("ready:", payload);
|
||
};
|
||
const onChange = (value: string, viewUpdate: any) => {
|
||
console.log("change:", value);
|
||
console.log("change:", viewUpdate);
|
||
};
|
||
const onFocus = (viewUpdate: any) => {
|
||
console.log("focus:", viewUpdate);
|
||
};
|
||
const onBlur = () => {
|
||
console.log(code.value, "6666666666777777777");
|
||
try {
|
||
const options = {
|
||
moduleCache: {
|
||
vue: Vue
|
||
},
|
||
async getFile() {
|
||
return code.value;
|
||
},
|
||
addStyle(textContent) {
|
||
const style = Object.assign(document.createElement("style"), {
|
||
textContent
|
||
});
|
||
const ref = document.head.getElementsByTagName("style")[0] || null;
|
||
document.head.insertBefore(style, ref);
|
||
}
|
||
};
|
||
const comp = defineAsyncComponent(() => loadModule("textPopup.vue", options));
|
||
console.log(comp);
|
||
previewComp.value = comp;
|
||
} catch (err) {
|
||
console.error(err);
|
||
}
|
||
};
|
||
onMounted(async () => {
|
||
console.log(map, "66666");
|
||
console.log(QueryPopup, "777888");
|
||
map.scene.globe.depthTestAgainstTerrain = false; // 不加无法投射到地形上
|
||
map.onlyPickModelPosition = true; // 是否仅在模型上标绘
|
||
graphicLayer = new mars3d.layer.GraphicLayer();
|
||
map.addLayer(graphicLayer);
|
||
graphicLayer.on(mars3d.EventType.drawCreated, function (e) {
|
||
console.log("创建完成", e);
|
||
addRandomGraphicByCount(e.graphic.point);
|
||
});
|
||
await getStyle();
|
||
});
|
||
onUnmounted(() => {
|
||
map = null;
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
@mixin flex {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
// 菜单弹框出现动画
|
||
@keyframes fadeIn {
|
||
0% {
|
||
opacity: 0;
|
||
transform: translate3d(100%, 0, 0);
|
||
}
|
||
100% {
|
||
opacity: 1;
|
||
transform: none;
|
||
}
|
||
}
|
||
.main-content {
|
||
position: absolute;
|
||
top: 60px;
|
||
right: 10px;
|
||
padding: 0 !important;
|
||
background-image: none !important;
|
||
border: 1px solid #008aff70;
|
||
border-radius: 2px !important;
|
||
background-color: rgba(23, 49, 71, 0.8);
|
||
width: 500px;
|
||
height: max-content;
|
||
box-shadow: 0 4px 15px 1px #02213bb3;
|
||
animation: fadeIn 1s;
|
||
&-title {
|
||
@include flex;
|
||
width: 100%;
|
||
height: 40px;
|
||
padding: 0 5px 0 10px;
|
||
background-image: url("@/assets/images/Mars3DIcon/subClassTitle.png");
|
||
background-size: 100% 100%;
|
||
background-repeat: no-repeat;
|
||
span {
|
||
font-size: 16px;
|
||
color: #0089fe;
|
||
margin-right: auto;
|
||
}
|
||
:deep() {
|
||
.el-icon {
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
}
|
||
.operate-btn {
|
||
@include flex;
|
||
justify-content: center;
|
||
margin: 0 15px;
|
||
margin-top: 10px;
|
||
border-bottom: 1px solid #50a4e4;
|
||
div {
|
||
font-size: 16px;
|
||
color: white;
|
||
padding-bottom: 10px;
|
||
border-bottom: 2px solid transparent;
|
||
cursor: pointer;
|
||
}
|
||
div:nth-child(1) {
|
||
margin-right: 40px;
|
||
}
|
||
.active-btn {
|
||
color: #4f88e5;
|
||
border-color: #4f88e5;
|
||
}
|
||
}
|
||
.basic-config {
|
||
width: 100%;
|
||
height: 100%;
|
||
padding: 15px 20px;
|
||
.switch-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
margin: 0 5px;
|
||
> div {
|
||
@include flex;
|
||
span {
|
||
color: white;
|
||
font-size: 14px;
|
||
}
|
||
span:last-child {
|
||
margin-left: 5px;
|
||
}
|
||
}
|
||
}
|
||
.popup-style {
|
||
display: flex;
|
||
flex-direction: column;
|
||
margin: 0 5px;
|
||
margin-top: 10px;
|
||
> span {
|
||
font-size: 14px;
|
||
color: white;
|
||
margin-bottom: 10px;
|
||
}
|
||
}
|
||
.btn-style {
|
||
@include flex;
|
||
margin: 0 5px;
|
||
margin-top: 15px;
|
||
:deep() {
|
||
.el-button {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.equip-list {
|
||
width: 100%;
|
||
height: 100%;
|
||
padding: 15px 25px;
|
||
.type-select {
|
||
@include flex;
|
||
color: white;
|
||
margin-bottom: 5px;
|
||
:deep() {
|
||
.el-checkbox__inner,
|
||
.el-radio__inner {
|
||
background-color: transparent;
|
||
}
|
||
.el-checkbox__label,
|
||
.el-radio__label {
|
||
color: white;
|
||
}
|
||
}
|
||
}
|
||
.primaryBtn {
|
||
color: #61aefe;
|
||
margin-right: 10px;
|
||
cursor: pointer;
|
||
}
|
||
.deleteBtn {
|
||
color: #f57272;
|
||
margin-right: 10px;
|
||
cursor: pointer;
|
||
}
|
||
.btn-style {
|
||
@include flex;
|
||
margin-top: 15px;
|
||
:deep() {
|
||
.el-button {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// element 组件样式
|
||
:deep() {
|
||
.el-input__wrapper {
|
||
background-color: transparent;
|
||
}
|
||
.el-input__inner {
|
||
color: white;
|
||
}
|
||
.el-button {
|
||
background: rgba(51, 89, 181, 0.6);
|
||
border-radius: 6px;
|
||
border: 0;
|
||
}
|
||
.el-table {
|
||
background-color: transparent;
|
||
tr {
|
||
background-color: transparent;
|
||
}
|
||
}
|
||
.el-table__border-left-patch {
|
||
background-color: #3f5c8e;
|
||
}
|
||
.el-table--border .el-table__inner-wrapper::after {
|
||
background-color: #3f5c8e;
|
||
}
|
||
.el-table--border::after {
|
||
background-color: #3f5c8e;
|
||
}
|
||
.el-table__inner-wrapper::before {
|
||
background-color: #3f5c8e;
|
||
}
|
||
.el-table td.el-table__cell {
|
||
border-color: #3f5c8e;
|
||
}
|
||
.el-table--border .el-table__cell {
|
||
border-color: #3f5c8e;
|
||
}
|
||
.cell {
|
||
color: white;
|
||
}
|
||
.el-table__row:hover {
|
||
background-color: transparent;
|
||
}
|
||
.el-table__body tr:hover > td {
|
||
// background-color: #008bff !important;
|
||
background-color: transparent !important;
|
||
}
|
||
.el-select,
|
||
.el-input,
|
||
.el-input__inner {
|
||
border-radius: 10px;
|
||
color: #fff;
|
||
//border: 1px solid green;
|
||
border-radius: 0px;
|
||
border-color: green;
|
||
text-align: center;
|
||
}
|
||
|
||
//修改总体选项的样式 最外层
|
||
.el-select__popper.el-popper {
|
||
border: 0;
|
||
background-color: transparent;
|
||
box-shadow: none;
|
||
}
|
||
.el-select-dropdown {
|
||
background: rgba(11, 22, 51, 0.7);
|
||
box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
|
||
opacity: 1;
|
||
border: 1px solid #3b60a7;
|
||
border-radius: 0px;
|
||
}
|
||
|
||
//修改单个的选项的样式
|
||
|
||
.el-select-dropdown__item {
|
||
background-color: transparent;
|
||
color: #fff;
|
||
}
|
||
|
||
//item选项的hover样式
|
||
|
||
.el-select-dropdown__item.hover,
|
||
.el-select-dropdown__item:hover {
|
||
color: white;
|
||
background: linear-gradient(90deg, rgba(49, 96, 179, 0) 0%, #3160b3 51%, rgba(49, 96, 179, 0) 100%);
|
||
}
|
||
.el-popper__arrow::before {
|
||
display: none;
|
||
}
|
||
}
|
||
</style>
|