622 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>