Compare commits

...

3 Commits

@ -13,6 +13,7 @@ onMounted(() => {
designWidth: 1920,
renderDom: "#app",
resize: true,
ignore:['div[id*="el-popper-container"]',".el-select__popper"]
},
false
); //

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

@ -6,6 +6,7 @@
@import './btn.scss';
@import './ruoyi.scss';
@import './font.css';
@import './map.scss';
body {
height: 100%;

@ -0,0 +1,155 @@
.map-marker {
width: 200px;
position: relative;
}
.marker-icon {
height: 50px;
width: 41px;
}
.marker-type {
position: absolute;
z-index: -1;
left: 23px;
padding: 0 10px 0 23px;
top: 3px;
width: fit-content;
height: 37px;
font-size: 14px;
color: #ffffff;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
font-family: "Aboreto-Bold";
}
.type-color1 {
background: linear-gradient(
270deg,
rgba(11, 170, 55, 0) 0%,
rgba(11, 170, 55, 0.7) 42%,
rgba(11, 170, 55, 0) 100%
);
}
.type-color2 {
background: linear-gradient(
270deg,
rgba(177, 173, 57, 0) 0%,
#b1ad39 42%,
rgba(177, 173, 57, 0) 100%
);
}
.type-color3 {
background: linear-gradient(
270deg,
rgba(107, 57, 177, 0) 0%,
#6b39b1 42%,
rgba(107, 57, 177, 0) 100%
);
}
//
.map-marker-popup {
position: relative;
width: 276px;
background: url("../images/visualization/popup-bg.png");
background-size: 100% 100%;
.marker-popup-close {
cursor: pointer;
position: absolute;
right: 20px;
top: 15px;
height: 10px;
width: 10px;
background: url("../images/visualization/popup-close.png");
background-size: 100% 100%;
}
.marker-popup-title {
height: 43px;
width: 100%;
font-size: 16px;
letter-spacing: 4px;
background: linear-gradient(180deg, #ffffff 0%, #74bbff 50%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
font-family: "Aboreto-Bold";
font-weight: bold;
padding: 0 25px;
line-height: 43px;
border-bottom: 2px solid #3da2fa;
}
.popup-row {
display: flex;
flex-direction: column;
gap: 16px;
padding: 15px 25px;
.row-item {
display: flex;
align-items: center;
.row-name {
width: 90px;
font-size: 14px;
font-weight: 400;
color: rgba(255, 255, 255, 0.7);
}
.row-value {
flex: 1;
font-size: 14px;
color: #ffffff;
font-weight: 400;
display: flex;
align-items: center;
}
}
}
.popup-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
padding-bottom: 15px;
& > div {
cursor: pointer;
padding: 6px 11px;
background: #0e4e87;
border-radius: 4px;
font-size: 14px;
color: #ffffff;
font-weight: 400;
}
& > div:hover {
box-shadow: inset 0px 0px 12px 0px #00d9ff;
}
}
}
//-
.map-dialog {
padding: 0;
// background: url("../images/visualization/popup-bg.png");
// background-size: cover;
border: 1px solid red;
.el-dialog__header {
padding: 0;
}
.map-dialog-title {
font-size: 16px;
letter-spacing: 4px;
background: linear-gradient(180deg, #ffffff 0%, #74bbff 50%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
font-family: "Aboreto-Bold";
font-weight: bold;
padding: 0 25px;
line-height: 43px;
border-bottom: 2px solid #3da2fa;
}
.video-container {
height: 342px;
}
}

@ -4,11 +4,12 @@
<template v-if="values.includes(item.value)">
<!-- && (item.elTagClass == '' || item.elTagClass == null) -->
<span
v-if="(item.elTagType == 'default' || item.elTagType == '') "
v-if="item.elTagType == 'default' || item.elTagType == ''"
:key="item.value"
:index="index"
:class="item.elTagClass"
>{{ item.label + " " }}</span>
>{{ filterseparator(item.label, index) }}
</span>
<el-tag
v-else
:disable-transitions="true"
@ -16,18 +17,20 @@
:index="index"
:type="item.elTagType"
:class="item.elTagClass"
>{{ item.label + " " }}</el-tag>
>{{ item.label + " " }}</el-tag
>
</template>
</template>
<template v-if="unmatch && showValue">
{{ unmatchArray | handleArray }}
</template>
<template v-if="value !==0 && !value "></template>
</div>
</template>
<script setup>
//
const unmatchArray = ref([])
const unmatchArray = ref([]);
const props = defineProps({
//
@ -45,34 +48,61 @@ const props = defineProps({
separator: {
type: String,
default: ",",
},
});
const filterseparator = (label, index) => {
if (typeof props.value == "string" && props.value.includes(",")) {
if (index == values.value.length) {
return label;
}
return label + props.separator;
} else {
return label;
}
})
};
const values = computed(() => {
if (props.value === null || typeof props.value === 'undefined' || props.value === '') return []
return Array.isArray(props.value) ? props.value.map(item => '' + item) : String(props.value).split(props.separator)
})
if (
props.value === null ||
typeof props.value === "undefined" ||
props.value === ""
)
return [];
return Array.isArray(props.value)
? props.value.map((item) => "" + item)
: String(props.value).split(props.separator);
});
const unmatch = computed(() => {
unmatchArray.value = []
unmatchArray.value = [];
// value
if (props.value === null || typeof props.value === 'undefined' || props.value === '' || !Array.isArray(props.options) || props.options.length === 0) return false
if (
props.value === null ||
typeof props.value === "undefined" ||
props.value === "" ||
!Array.isArray(props.options) ||
props.options.length === 0
) {
return false;
}
//
let unmatch = false //
values.value.forEach(item => {
if (!props.options.some(v => v.value === item)) {
unmatchArray.value.push(item)
unmatch = true // true
let unmatch = false; //
values.value.forEach((item) => {
if (!props.options.some((v) => v.value === item)) {
unmatchArray.value.push(item);
unmatch = true; // true
}
})
return unmatch //
})
});
return unmatch; //
});
function handleArray(array) {
if (array.length === 0) return ""
if (array.length === 0) return "";
return array.reduce((pre, cur) => {
return pre + " " + cur
})
return pre + " " + cur;
});
}
</script>
@ -81,10 +111,9 @@ function handleArray(array) {
margin-left: 10px;
}
.el-tag {
font-size: 14px;
/* color: #FFFFFF; */
padding:0 12px;
font-weight: 500;
font-size: 14px;
/* color: #FFFFFF; */
padding: 0 12px;
font-weight: 500;
}
</style>

@ -86,8 +86,8 @@ export function selectDictLabel(datas, value) {
// 回显数据字典(字符串、数组)
export function selectDictLabels(datas, value, separator) {
if (value === undefined || value.length ===0) {
return ""
if (value === undefined ||value === null || value.length ===0) {
return "暂无"
}
if (Array.isArray(value)) {
value = value.join(",")

@ -8,10 +8,12 @@
label-width="68px"
class="search-form"
>
<el-form-item label="处置部门" prop="address">
<el-input
v-model="queryParams.address"
placeholder="请输入"
<el-form-item label="处置部门" prop="parentId">
<el-cascader
v-model="parentIdList"
:options="detpList"
:props="cascaderProps"
@change="parentIdChange"
clearable
/>
</el-form-item>
@ -29,11 +31,14 @@
/>
</el-select>
</el-form-item>
<el-form-item label="影响类型" prop="gdLevel">
<el-form-item label="影响类型" prop="yxlx">
<el-select
v-model="queryParams.gdLevel"
v-model="yxlxList"
placeholder="请选择"
clearable
multiple
collapse-tags
@change="multipleChange"
>
<el-option
v-for="dict in yxlx"
@ -57,7 +62,7 @@
/>
</el-select>
</el-form-item>
<el-form-item label="录入时间" prop="userName">
<el-form-item label="录入时间">
<el-date-picker
v-model="datePicker"
type="datetimerange"
@ -108,6 +113,7 @@
prop="address"
show-overflow-tooltip
/>
<el-table-column
label="工单类型"
align="center"
@ -119,6 +125,17 @@
</template>
</el-table-column>
<el-table-column
label="影响类型 "
align="center"
key="yxlx"
prop="yxlx"
>
<template #default="scope">
<dict-tag :options="yxlx" :value="scope.row.yxlx" />
</template>
</el-table-column>
<el-table-column
label="录入时间"
align="center"
@ -147,31 +164,6 @@
>
<template #default="scope">
<div class="table-operation-row">
<!-- <section v-show="scope.row.status == 0">
<el-button
link
type="primary"
icon="FolderAdd"
@click="handlerEdit(scope.row, 1)"
>勘察录入</el-button
>
<el-button
link
type="primary"
icon="FolderRemove"
@click="handlerRetreat(scope.row)"
>退单</el-button
>
</section> -->
<!-- <section v-show="scope.row.status == 1">
<el-button
link
type="primary"
icon="Edit"
@click="handlerEdit(scope.row)"
>编辑</el-button
>
</section> -->
<section v-show="scope.row.status == 0">
<el-button
link
@ -226,23 +218,21 @@
gdlx,
deptList,
yxlx,
xdsqm
xdsqm,
}"
v-model="open"
:id="workId"
:title="title"
@confirm="getList()"
></operation>
<!-- 派发 -->
<distriBute
:id="workId"
v-model="distributeView"
:deptList="deptList"
@confirm="getList()"
></distriBute>
</tablePage>
</template>
@ -255,12 +245,20 @@ import useUserStore from "@/store/modules/user";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const deptList = ref([]);
const { gdlx, gd_status, yxlx,xdsqm } = proxy.useDict(
const { gdlx, gd_status, yxlx, xdsqm } = proxy.useDict(
"gdlx",
"gd_status",
"yxlx","xdsqm"
"yxlx",
"xdsqm"
);
const yxlxList = ref([]);
const parentIdList = ref([]);
const datePicker = ref([]);
const detpList = ref([]);
const cascaderProps = {
value: "deptId",
label: "deptName",
};
const workId = ref(null);
const loading = ref(false);
const list = ref([]);
@ -268,16 +266,15 @@ const open = ref(false);
const distributeView = ref(false);
const title = ref("");
const total = ref(0);
const router = useRouter();
const data = reactive({
form: {},
queryParams: {
address: undefined,
parentId: undefined,
gdType: undefined,
gdLevel: undefined,
yxlx: undefined,
status: undefined,
begainTime: undefined,
endTime: undefined,
@ -292,13 +289,39 @@ const { queryParams, form, rules } = toRefs(data);
onMounted(() => {
getList();
getDeptTree();
getDeptTree(0);
});
const parentIdChange = (e)=>{
if(e && e.length>0){
queryParams.value.parentId = e[e.length -1];
}else{
queryParams.value.parentId = undefined
}
}
/**
* 影响类型
* @param e
*/
const multipleChange = (e) => {
if (e && e.length > 0) {
queryParams.value.yxlx = e.toString();
}else{
queryParams.value.yxlx = undefined
}
};
//
const changeDatepicker = (e) => {
if (e) {
queryParams.value.begainTime = e[0];
queryParams.value.endTime = e[1];
}else{
queryParams.value.begainTime = undefined;
queryParams.value.endTime = undefined;
}
};
@ -316,11 +339,16 @@ const getList = async () => {
/**
* 获取系统组织架构
*/
const getDeptTree = async () => {
const getDeptTree = async (isParent) => {
const res = await getDetListById({
deptId: userStore.deptId,
isParent: isParent,
});
deptList.value = res;
if (isParent === 0) {
detpList.value = res;
} else {
deptList.value = res;
}
};
/**
@ -337,13 +365,15 @@ const handleQuery = () => {
const resetQuery = () => {
proxy.resetForm("queryRef");
datePicker.value = [];
yxlxList.value = [];
parentIdList.value = [];
queryParams.value.yxlx = undefined;
queryParams.value.begainTime = undefined;
queryParams.value.endTime = undefined;
handleQuery();
};
/**
* 派发
*/
@ -352,8 +382,6 @@ const handlerDistriBute = (row, text) => {
distributeView.value = true;
};
/**
*
* 勘察录入
@ -361,7 +389,7 @@ const handlerDistriBute = (row, text) => {
*/
const handlerEdit = (row) => {
workId.value = row.id;
title.value = "工单处理反馈" ;
title.value = "工单处理反馈";
open.value = true;
};

@ -19,8 +19,8 @@
<div class="form-item">
<div class="form-label">影响类型</div>
<div class="form-value">
<dict-tag :options="yxlx" :value="form.yxlx" v-if="form.yxlx" />
<span v-else></span>
<dict-tag :options="yxlx" :value="form.yxlx" />
</div>
</div>

@ -13,10 +13,57 @@
map-key="emergency"
@onload="marsOnload"
/>
<el-checkbox-group
v-model="checkList"
class="maplayer-select"
@change="mapLayerChange"
>
<section class="checkIcon">
<div class="icon-box">
<img :src="bzIcon" alt="" class="check-img" />
<div class="type-name">
<el-checkbox value="1" label="班组" />
</div>
</div>
</section>
<section class="checkIcon">
<div class="icon-box">
<img :src="clIcon" alt="" class="check-img" />
<div class="type-name type2">
<el-checkbox value="2" label="车辆" />
</div>
</div>
</section>
<section class="checkIcon">
<div class="icon-box">
<img :src="gdIcon" alt="" class="check-img" />
<div class="type-name type3">
<el-checkbox value="3" label="工单" />
</div>
</div>
</section>
</el-checkbox-group>
<!-- 现场视频 -->
<el-dialog
v-model="dialogVisible"
width="568"
class="map-dialog"
append-to-body
>
<template #header>
<div class="map-dialog-title">{{ title }}</div>
</template>
<div class="video-container"></div>
</el-dialog>
</div>
</template>
<script setup>
import bzIcon from "@/assets/images/visualization/bz.png";
import clIcon from "@/assets/images/visualization/cl.png";
import gdIcon from "@/assets/images/visualization/gd.png";
import MarsMap from "@/components/mars-work/mars-map.vue";
import mapOptions from "../mapOptions";
import { onUnmounted } from "vue";
@ -26,7 +73,13 @@ import { panelBlock } from "@/views/visualization/components/index";
import containerLeft from "./components/containerLeft.vue";
import containerRight from "./components/containerRight.vue";
import containerBottom from "./components/containerBottom.vue";
import { getyjList, getyjById } from "@/api/emergency";
const { proxy } = getCurrentInstance();
const { gdlx, xdsqm, yxlx } = proxy.useDict("gdlx", "xdsqm", "yxlx");
const checkList = ref([]);
const dialogVisible = ref(false);
const title = ref("现场视频");
//
const configUrl = "lib/config/config.json";
let mapData = null;
@ -44,6 +97,158 @@ const initAreaCover = async () => {
});
};
/**
* 地图图层变化
* @param e
*/
const mapLayerChange = (e) => {
const list = ["1", "2", "3"];
if (e.length > 0) {
e.map((item) => {
if (list.includes(item)) {
//
getMapLayerData(item);
} else {
//
mapLayer.gdLayer?.clear();
}
});
} else {
mapLayer.gdLayer?.clear();
}
};
/**
* 获取未处理工单
*/
const getMapLayerData = async (type) => {
let list = [];
if (type == 3) {
const res = await getyjList({ status: 0 }); //
list = res.data.records;
}
nextTick(() => {
list.map((item) => {
initBillboardEntity(item, type);
});
});
};
//
const initBillboardEntity = (item, iconType = 1) => {
const gdTypeName = proxy.selectDictLabel(gdlx.value, item.gdType); //
const xdsqmName = proxy.selectDictLabel(xdsqm.value, item.xdsqm);
const image = iconType == 1 ? bzIcon : iconType == 2 ? clIcon : gdIcon;
const graphic = new mars3d.graphic.DivGraphic({
id: `marker${item.id}`,
position: new mars3d.LngLatPoint(
parseFloat(item.lat),
parseFloat(item.lon),
0
),
style: {
html: `
<div class="map-marker">
<img class="marker-icon" src="${image}" />
<div class="marker-type type-color${iconType}">
<span>${gdTypeName}</span>
<span style="display:${
xdsqmName ? "block" : "none"
}">-${xdsqmName}</span>
</div>
</div>
`,
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
clampToGround: true,
offsetX: -20,
},
attr: item,
});
graphic.on(mars3d.EventType.click, (e) => {
const attr = e.target.attr;
//
bindPopupByGd(attr.id);
});
// graphic.on(mars3d.EventType.popupOpen, (e) => {
// document.getElementById("videoLook").addEventListener("click", () => {
// dialogVisible.value = true
// });
// });
mapLayer.gdLayer.addGraphic(graphic);
};
/**
* 绑定弹窗
*/
const bindPopupByGd = async (id) => {
const info = await getInfo(id);
const gdTypeName = proxy.selectDictLabel(gdlx.value, info.gdType); //
const yxlxName = proxy.selectDictLabels(yxlx.value, info.yxlx);
const xdsqmName = proxy.selectDictLabel(xdsqm.value, info.xdsqm);
const markerItem = mapLayer.gdLayer.getGraphicById(`marker${id}`);
markerItem.bindPopup("占位", {
template: `<div class="marker-popup">
<div class="marker-popup-close closeButton"></div>
<div class="marker-popup-title">
工单信息
</div>
<div class="popup-row">
<div class="row-item">
<div class="row-name">工单类型</div>
<div class="row-value">
<span>${gdTypeName} </span>
<spam style="display:${
xdsqmName ? "block" : "none"
}">-${xdsqmName}</spam> </div>
</div>
<div class="row-item">
<div class="row-name">影响类型</div>
<div class="row-value">${yxlxName}</div>
</div>
<div class="row-item">
<div class="row-name">处理班组</div>
<div class="row-value">${info.parentName}</div>
</div>
<div class="row-item">
<div class="row-name">工单描述</div>
<div class="row-value">${info.clms}</div>
</div>
</div>
</div>`,
className: "map-marker-popup",
offsetX: 276,
offsetY: -41,
// <div class="popup-btn">
// <div id="videoLook"></div>
// <div></div>
// </div>
});
nextTick(() => {
markerItem.openPopup();
});
};
/**
* 获取工单详情
* @param id
*/
const getInfo = async (id) => {
const res = await getyjById(id);
return res.data;
};
const inintEntity = (data, fill = false, height) => {
const polylineGraphic = new mars3d.graphic.PolygonEntity({
positions: data.positions,
@ -67,27 +272,6 @@ const inintEntity = (data, fill = false, height) => {
});
mapLayer.arealayer.addGraphic(polylineGraphic);
};
/**
*
* @param positions
*/
const inintEntityWall = (positions) => {
const wall = new mars3d.graphic.WallPrimitive({
positions: positions,
style: {
setHeight: -2500,
diffHeight: 2500, //
width: 100,
materialType: mars3d.MaterialType.Image2,
materialOptions: {
image: wallImg,
color: "#144C8F",
},
},
});
mapLayer.arealayer.addGraphic(wall);
};
/**
* 风貌区
@ -116,9 +300,10 @@ const marsOnload = (map) => {
*/
const createMapLayer = () => {
mapLayer.arealayer = new mars3d.layer.GraphicLayer();
mapLayer.styleFeatures = new mars3d.layer.GraphicLayer();
mapData.addLayer(mapLayer.arealayer);
mapData.addLayer(mapLayer.styleFeatures);
mapLayer.gdLayer = new mars3d.layer.GraphicLayer();
mapData.addLayer(mapLayer.gdLayer);
};
/**
@ -130,7 +315,8 @@ onUnmounted(() => {
mapData = null;
}
mapLayer.arealayer?.clear();
mapLayer.styleFeatures?.clear();
mapLayer.gdLayer?.clear();
mapLayer = null;
});
</script>
@ -167,5 +353,88 @@ onUnmounted(() => {
width: 55%;
padding-bottom: 34px;
}
::v-deep .maplayer-select {
position: absolute;
top: 125px;
left: 22%;
z-index: 10;
display: flex;
flex-direction: column;
gap: 20px;
.el-checkbox__label {
font-size: 14px;
color: #ffffff;
font-weight: bold;
}
.el-checkbox {
display: flex;
align-items: center;
flex-direction: row-reverse;
gap: 10px;
}
.el-checkbox__inner {
height: 18px;
width: 18px;
border-color: #58f4ff;
background-color: #071c3b;
}
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #58f4ff;
}
.el-checkbox__input.is-checked .el-checkbox__inner::after {
border-color: #071c3b; /* 替换为你想要的颜色 */
transform: scale(1.5) rotate(45deg);
}
.el-checkbox__inner:after {
left: 6px;
top: 3px;
}
}
.checkIcon {
display: flex;
align-items: center;
gap: 80px;
.icon-box {
position: relative;
}
.check-img {
width: 41px;
height: 50px;
}
.type-name {
position: absolute;
top: 3px;
display: flex;
align-items: center;
justify-content: center;
left: 30px;
width: 100px;
height: 40px;
background: linear-gradient(
270deg,
rgba(11, 170, 55, 0) 0%,
rgba(11, 170, 55, 0.7) 42%,
rgba(11, 170, 55, 0) 100%
);
}
.type2 {
background: linear-gradient(
270deg,
rgba(177, 173, 57, 0) 0%,
#b1ad39 42%,
rgba(177, 173, 57, 0) 100%
);
}
.type3 {
background: linear-gradient(
270deg,
rgba(107, 57, 177, 0) 0%,
#6b39b1 42%,
rgba(107, 57, 177, 0) 100%
);
}
}
}
</style>

Loading…
Cancel
Save