<template>
|
<div class="table-box">
|
<div id="mars3dContainer" class="mars3d-container">
|
<Mars3DMap
|
ref="marsMap"
|
v-if="configLoaded"
|
:mapconfig="mapConfigs"
|
@map-loaded="onMapLoaded"
|
:showfence="marsHome.showfence"
|
:showanchor="marsHome.showanchor"
|
:showlayer="marsHome.layer"
|
:mapcolor="marsHome.mapcolor"
|
style="border: none"
|
/>
|
</div>
|
<el-card class="right-card" style="width: 450px">
|
<template #header>
|
<div class="card-header">
|
<b>{{ t("Fence.drawFence") }}</b>
|
<el-button type="primary" plain @click="drawExtentDuoBianXing" style="float: right">
|
<el-icon><Crop /></el-icon> {{ t("Fence.polygon") }}
|
</el-button>
|
</div>
|
</template>
|
<el-form
|
ref="ruleFormRef"
|
label-width="50px"
|
label-suffix=" :"
|
:rules="rules"
|
:model="fences"
|
:hide-required-asterisk="true"
|
>
|
<el-form-item label-width="100" :label="t('Fence.map')" prop="floor">
|
<el-select v-model="fences.floor" :placeholder="t('Fence.selectMap')" @change="handleSelectMap">
|
<el-option :label="t('Fence.baiduMap')" value="百度地图" />
|
<el-option v-for="item in mapList" :key="item.value" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.type')" prop="type">
|
<el-select v-model="fences.type" :placeholder="t('Fence.selectType')">
|
<el-option v-for="item in typeList" :key="item.label" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.department')" prop="bumen">
|
<el-select v-model="fences.bumen" :placeholder="t('Fence.selectDepartment')">
|
<el-option v-for="item in bumenList" :key="item.label" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.company')" prop="company">
|
<el-select v-model="fences.company" :placeholder="t('Fence.selectCompany')">
|
<el-option v-for="item in companys" :key="item.label" :label="item.label" :value="item.value" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.name')" prop="name">
|
<el-input v-model="fences.name" :placeholder="t('Fence.inputName')" clearable></el-input>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.height')" prop="baoliu11">
|
<el-input v-model="fences.baoliu11" :placeholder="t('Fence.inputHeight')" clearable></el-input>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.color')" prop="baoliu14">
|
<el-color-picker v-model="fences.baoliu14" />
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.voice')" prop="baoliu13">
|
<el-input v-model="fences.baoliu13" :placeholder="t('Fence.inputVoice')" clearable></el-input>
|
</el-form-item>
|
<el-form-item label-width="100" :label="t('Fence.coordinates')" prop="baoliu8">
|
<el-input v-model="fences.baoliu8" :autosize="{ minRows: 2, maxRows: 6 }" type="textarea" readonly />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<el-button @click="ResetFrom">{{ t("Config.reset") }}</el-button>
|
<el-button v-show="true" v-if="BUTTONS.add" type="primary" @click="handleSubmit">{{ t("Config.sure") }}</el-button>
|
</template>
|
</el-card>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { onMounted, ref, reactive } from "vue";
|
import * as mars3d from "mars3d";
|
import { ElMessage, FormInstance } from "element-plus";
|
import { useAuthButtons } from "@/hooks/useAuthButtons";
|
import "mars3d-space";
|
import Mars3DMap from "../components/screen/Mars3DMap.vue";
|
import "mars3d-cesium/Build/Cesium/Widgets/widgets.css";
|
import "mars3d/mars3d.css";
|
import { FenceCompanyAutocomplete } from "@/api/modules/hxzk/user/company";
|
import { getThreeMapConfig } from "@/api/modules/hxzk/map/threemap";
|
import { FindUserCompanyMap, FindFloorMap } from "@/api/modules/hxzk/map/twomap";
|
import { DepartmentAutocomplete } from "@/api/modules/hxzk/department/department";
|
import { addFence } from "@/api/modules/hxzk/fence/fence";
|
import { useI18n } from "vue-i18n";
|
|
const { t } = useI18n({ useScope: "global" });
|
const { BUTTONS } = useAuthButtons();
|
|
const rules = reactive({
|
floor: [{ required: true, message: t("Fence.validation.mapRequired") }],
|
type: [{ required: true, message: t("Fence.validation.typeRequired") }],
|
bumen: [{ required: true, message: t("Fence.validation.departmentRequired") }],
|
name: [{ required: true, message: t("Fence.validation.nameRequired") }],
|
baoliu11: [{ required: true, message: t("Fence.validation.heightRequired") }],
|
baoliu14: [{ required: true, message: t("Fence.validation.colorRequired") }],
|
baoliu13: [{ required: true, message: t("Fence.validation.voiceRequired") }],
|
baoliu8: [{ required: true, message: t("Fence.validation.coordinatesRequired") }]
|
});
|
|
// 图层下拉列表
|
const mapList = ref();
|
// 部门下拉列表
|
const bumenList = ref();
|
const fences = ref({
|
floor: "百度地图",
|
type: "",
|
bumen: "",
|
name: "",
|
baoliu11: "10",
|
color: "红色",
|
baoliu13: t("Fence.none"),
|
baoliu14: "#409EFF",
|
baoliu8: "",
|
company: ""
|
});
|
|
// 类型下拉列表
|
const typeList = ref([
|
{
|
value: "进入告警",
|
label: t("warningTypes.enter")
|
},
|
{
|
value: "出去告警",
|
label: t("warningTypes.exit")
|
},
|
{
|
value: "考勤区域",
|
label: t("Fence.attendanceArea")
|
}
|
]);
|
|
const configLoaded = ref(false);
|
let map;
|
let tileLayermap;
|
const marsHome = ref({
|
id: 0,
|
offlinehide: false,
|
voice: false,
|
showfence: false,
|
showanchor: false,
|
threemap: false,
|
layer: false,
|
image: false,
|
jiankong: true,
|
weixing: false,
|
mapcolor: "#409EFF",
|
showmap: false
|
});
|
|
// 地图配置
|
//公司下拉列表
|
const companys = ref();
|
const mapConfigs = ref({});
|
|
onMounted(() => {
|
//公司下拉列表
|
FenceCompanyAutocomplete().then(data => {
|
companys.value = data;
|
});
|
// 初始化地图下拉-部门下拉-类型下拉
|
//地图初始化
|
getThreeMapConfig().then(mapConfig => {
|
mapConfigs.value = mapConfig;
|
marsHome.value.id = mapConfig.id;
|
if (mapConfig.showfence == "1") {
|
marsHome.value.showfence = true;
|
}
|
if (mapConfig.layer == "1") {
|
marsHome.value.layer = true;
|
}
|
if (mapConfig.showanchor == "1") {
|
marsHome.value.showanchor = true;
|
}
|
if (mapConfig.threemap == "1") {
|
marsHome.value.threemap = true;
|
}
|
|
if (mapConfig.voice == "1") {
|
marsHome.value.voice = true;
|
}
|
if (mapConfig.showmap == "1") {
|
marsHome.value.showmap = true;
|
}
|
marsHome.value.mapcolor = mapConfig.mapcolor;
|
configLoaded.value = true;
|
});
|
FindUserCompanyMap().then(mapLists => {
|
mapList.value = mapLists;
|
});
|
const param = {
|
companyid: ""
|
};
|
DepartmentAutocomplete(param).then(bumenLists => {
|
bumenList.value = bumenLists;
|
});
|
});
|
|
const baseUrl = import.meta.env.VITE_IP;
|
|
//地图初始化
|
const onMapLoaded = (mapInstance: any) => {
|
map = mapInstance;
|
map.basemap = 8890;
|
if (marsHome.value.showmap) {
|
map.scene.globe.show = true;
|
}
|
};
|
|
// 选中二维地图
|
const handleSelectMap = value => {
|
const params = {
|
floor: value
|
};
|
FindFloorMap(params).then(maps => {
|
map.removeLayer(tileLayermap);
|
tileLayermap = new mars3d.layer.ImageLayer({
|
name: maps.mapname,
|
url: `${baseUrl}/uploads/map/` + maps.mapname,
|
rectangle: {
|
xmin: maps.baoliu5.split(",")[0],
|
xmax: maps.baoliu6.split(",")[0],
|
ymin: maps.baoliu8.split(",")[1],
|
ymax: maps.baoliu6.split(",")[1]
|
},
|
zIndex: 20
|
});
|
map.addLayer(tileLayermap);
|
map.camera.flyTo({
|
destination: Cesium.Cartesian3.fromDegrees(maps.baoliu5.split(",")[0], maps.baoliu8.split(",")[1], 500),
|
duration: 2
|
});
|
});
|
};
|
|
// 重置
|
const ResetFrom = () => {
|
fences.value.baoliu11 = "";
|
fences.value.bumen = "";
|
fences.value.name = "";
|
fences.value.type = "";
|
fences.value.baoliu13 = "";
|
fences.value.baoliu8 = "";
|
};
|
|
// 提交数据(新增/编辑)
|
const ruleFormRef = ref<FormInstance>();
|
const handleSubmit = () => {
|
ruleFormRef.value!.validate(async valid => {
|
if (!valid) return;
|
try {
|
if (fences.value.bumen === t("Fence.allDepartments")) {
|
fences.value.bumen = t("Fence.systemDefault");
|
}
|
const res = await addFence(fences.value);
|
ElMessage.success({ message: `${res.msg}` });
|
} catch (error) {
|
console.log(error);
|
}
|
});
|
};
|
|
// 开始绘制多边形
|
const drawExtentDuoBianXing = async () => {
|
if (fences.value.name == "") {
|
ElMessage.error(t("Fence.validation.nameFirst"));
|
return;
|
}
|
fences.value.baoliu8 = "";
|
map.graphicLayer.clear();
|
const graphic = await map.graphicLayer.startDraw({
|
type: "polygonP",
|
style: {
|
color: fences.value.baoliu14,
|
opacity: 0.5,
|
label: {
|
text: fences.value.name,
|
font_size: 18,
|
color: "#ffffff",
|
distanceDisplayCondition: true,
|
distanceDisplayCondition_far: 500000,
|
distanceDisplayCondition_near: 0
|
}
|
}
|
});
|
for (let i = 0; i < graphic.toJSON().positions.length; i++) {
|
fences.value.baoliu8 += graphic.toJSON().positions[i][0] + ":" + graphic.toJSON().positions[i][1] + ";";
|
}
|
fences.value.baoliu8 = fences.value.baoliu8.slice(0, -1);
|
};
|
</script>
|
|
<style scoped>
|
.table-box {
|
display: flex;
|
flex-direction: row-reverse;
|
height: 100%;
|
}
|
.mars3dContainer {
|
width: 80%;
|
background-color: #f0f0f0;
|
}
|
.right-card {
|
box-sizing: border-box;
|
width: 20%;
|
}
|
</style>
|