update tag title
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
import markBsPng from "@/assets/images/mark_bs.png";
|
||||
|
||||
// 初始化地图
|
||||
export const loadAMap = async (plugins) => {
|
||||
@ -27,3 +28,44 @@ export const loadAMap = async (plugins) => {
|
||||
throw new Error("地图创建失败");
|
||||
}
|
||||
};
|
||||
|
||||
export const searchPlace = ({ AMap, map, searchPlugin, keyword, events }) => {
|
||||
if (events.beforeSearch) {
|
||||
events.beforeSearch();
|
||||
}
|
||||
searchPlugin.search(keyword, (status, result) => {
|
||||
if (status === "complete") {
|
||||
const searchResultMarkers = result.poiList.pois.map((el, index) => {
|
||||
const marker = new AMap.Marker({
|
||||
map,
|
||||
position: el.location,
|
||||
anchor: "bottom-center",
|
||||
extData: el,
|
||||
content: `
|
||||
<div
|
||||
style="
|
||||
background-image: url(${markBsPng});
|
||||
width: 19px;
|
||||
height: 31px;
|
||||
background-size: cover;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
padding-top: 3px;
|
||||
"
|
||||
>
|
||||
${index + 1}
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
// marker.on("mouseover", handleResultHover);
|
||||
// marker.on("click", handleResultClick);
|
||||
// marker.on("mouseout", (ev) => {
|
||||
// resultInfoWindow.value.close();
|
||||
// });
|
||||
return marker;
|
||||
});
|
||||
map.setFitView(searchResultMarkers);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -257,6 +257,8 @@ function submitForm() {
|
||||
onMounted(async () => {
|
||||
reset();
|
||||
if (route.query.carId && route.query.uuid) {
|
||||
const routerObj = Object.assign({}, route, { title: "车辆修改" });
|
||||
tab.updatePage(routerObj);
|
||||
const resp = await getInfo(route.query.carId, route.query.uuid);
|
||||
form.value = {
|
||||
...resp.data,
|
||||
|
@ -212,6 +212,8 @@ function back() {
|
||||
onMounted(async () => {
|
||||
reset();
|
||||
if (route.query.driverId && route.query.uuid) {
|
||||
const routerObj = Object.assign({}, route, { title: "司机修改" });
|
||||
tab.updatePage(routerObj);
|
||||
const { data } = await getInfo(route.query.driverId, route.query.uuid);
|
||||
form.value = data;
|
||||
}
|
||||
|
@ -31,7 +31,13 @@
|
||||
>搜索</el-button
|
||||
>
|
||||
<!-- </el-col> -->
|
||||
<el-button type="primary" plain size="small">卫星模式</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
@click="switchMapLayer"
|
||||
>{{ isSatelliteMode ? "标准模式" : "卫星模式" }}</el-button
|
||||
>
|
||||
</el-row>
|
||||
</div>
|
||||
<div id="map-container"></div>
|
||||
@ -125,11 +131,10 @@
|
||||
import tab from "@/plugins/tab";
|
||||
import { onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
// import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
import { addFence, updateFence, getFence } from "@/api/fence";
|
||||
import { loadAMap } from "@/utils/map";
|
||||
import markBsPng from "@/assets/images/mark_bs.png";
|
||||
import mapPinPng from "@/assets/images/map-pin.png";
|
||||
import { loadAMap } from "@/utils/map";
|
||||
import { addFence, updateFence, getFence } from "@/api/fence";
|
||||
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance();
|
||||
@ -137,9 +142,12 @@ const AMap = shallowRef(null);
|
||||
const map = shallowRef(null);
|
||||
const placeSearch = shallowRef(null);
|
||||
const searchResultMarkers = shallowRef([]); // 搜索结果表笔列表
|
||||
const satelliteLayer = shallowRef(null);
|
||||
const isSatelliteMode = ref(false);
|
||||
const turningPointMarker = shallowRef([]);
|
||||
const resultInfoWindow = shallowRef(null);
|
||||
const fencePolygon = shallowRef(null);
|
||||
|
||||
const searchKeyword = ref("");
|
||||
const data = reactive({
|
||||
form: {},
|
||||
@ -163,17 +171,15 @@ const data = reactive({
|
||||
|
||||
const { form, rules } = toRefs(data);
|
||||
|
||||
const handleMapClick = (ev) => {
|
||||
const addFencePath = (lnglat) => {
|
||||
if (map.value.getAllOverlays("polygon").length === 0) {
|
||||
map.value.add(fencePolygon.value);
|
||||
}
|
||||
|
||||
form.value.fencePath.push(ev.lnglat);
|
||||
|
||||
form.value.fencePath.push(lnglat);
|
||||
turningPointMarker.value.push(
|
||||
new AMap.value.Marker({
|
||||
map: map.value,
|
||||
position: ev.lnglat,
|
||||
position: lnglat,
|
||||
content: `
|
||||
<div
|
||||
style="
|
||||
@ -201,14 +207,24 @@ const handleMapClick = (ev) => {
|
||||
el.show();
|
||||
});
|
||||
}
|
||||
fencePolygon.value.setPath(
|
||||
// AMap.value.GeometryUtil.makesureClockwise(
|
||||
// form.value.fencePath.map((el) => new AMap.value.LngLat(el.lng, el.lat))
|
||||
form.value.fencePath
|
||||
// )
|
||||
);
|
||||
fencePolygon.value.setPath(form.value.fencePath);
|
||||
};
|
||||
const handleResultClick = (ev) => {
|
||||
const handleMapClick = (ev) => {
|
||||
addFencePath(ev.lnglat);
|
||||
};
|
||||
|
||||
const switchMapLayer = () => {
|
||||
if (isSatelliteMode.value) {
|
||||
map.value.remove(satelliteLayer.value);
|
||||
isSatelliteMode.value = false;
|
||||
} else {
|
||||
map.value.add([satelliteLayer.value]);
|
||||
isSatelliteMode.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
// 鼠标悬停搜索结果标记
|
||||
const handleResultHover = (ev) => {
|
||||
resultInfoWindow.value.setContent(`
|
||||
<div>
|
||||
${ev.target.getExtData().name}</div>
|
||||
@ -221,13 +237,13 @@ const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
form.value.fencePath = [];
|
||||
|
||||
placeSearch.value.search(searchKeyword.value, (status, result) => {
|
||||
console.log(status, result);
|
||||
// TODO: 添加搜索结果标记
|
||||
if (status === "complete") {
|
||||
searchResultMarkers.value = result.poiList.pois.map((el, index) => {
|
||||
const marker = new AMap.value.Marker({
|
||||
map: map.value,
|
||||
position: new AMap.value.LngLat(el.location.lng, el.location.lat),
|
||||
position: el.location,
|
||||
anchor: "bottom-center",
|
||||
extData: el,
|
||||
content: `
|
||||
<div
|
||||
@ -246,8 +262,8 @@ const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
marker.on("mouseover", handleResultClick);
|
||||
marker.on("click", handleMapClick);
|
||||
marker.on("mouseover", handleResultHover);
|
||||
marker.on("click", handleResultClick);
|
||||
marker.on("mouseout", (ev) => {
|
||||
resultInfoWindow.value.close();
|
||||
});
|
||||
@ -257,6 +273,16 @@ const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 搜索结果点击
|
||||
const handleResultClick = async (ev) => {
|
||||
map.value.clearMap();
|
||||
searchResultMarkers.value = [];
|
||||
const lnglat = ev.target.getExtData()?.location;
|
||||
if (!lnglat) return ElMessage.error("获取经纬度失败");
|
||||
addFencePath(lnglat);
|
||||
};
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
proxy.$refs["fenceRef"].validate((valid) => {
|
||||
@ -281,6 +307,7 @@ function submitForm() {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
function reset() {
|
||||
form.value = {
|
||||
@ -310,9 +337,11 @@ onMounted(() => {
|
||||
map.value = new AMap.value.Map("map-container", {
|
||||
zoom: 16, // 缩放级别
|
||||
center: [117.290345, 31.797813], // 中心点
|
||||
city: "合肥",
|
||||
// city: "合肥",
|
||||
});
|
||||
|
||||
map.value.on("click", handleMapClick);
|
||||
satelliteLayer.value = new AMap.value.TileLayer.Satellite();
|
||||
// 地点搜索插件
|
||||
placeSearch.value = new AMap.value.PlaceSearch({
|
||||
// map: map.value,
|
||||
@ -320,11 +349,14 @@ onMounted(() => {
|
||||
});
|
||||
resultInfoWindow.value = new AMap.value.InfoWindow({
|
||||
anchor: "bottom-center",
|
||||
offset: new AMap.value.Pixel(0, -31),
|
||||
});
|
||||
fencePolygon.value = new AMap.value.Polygon({});
|
||||
map.value.add(fencePolygon.value);
|
||||
map.value.addControl(new AMap.value.Scale());
|
||||
if (route.query.fenceId && route.query.uuid) {
|
||||
const routerObj = Object.assign({}, route, { title: "修改电子围栏" });
|
||||
tab.updatePage(routerObj);
|
||||
getFence(route.query.fenceId, route.query.uuid).then((resp) => {
|
||||
form.value = {
|
||||
...resp.data,
|
||||
@ -359,3 +391,8 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.amap-info {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -144,6 +144,7 @@ const handleRouteClick = (data, index) => {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.icon {
|
||||
flex-shrink: 0;
|
||||
margin-right: 8px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<div class="wrap">
|
||||
<div class="form-drawer" v-show="drawerOpen">
|
||||
<el-button
|
||||
id="drawer-switch"
|
||||
type="primary"
|
||||
plain
|
||||
circle
|
||||
:icon="drawerOpen ? 'ArrowLeftBold' : 'ArrowRightBold'"
|
||||
@click="switchDrawer"
|
||||
></el-button>
|
||||
<div id="form-drawer">
|
||||
<el-scrollbar class="form-container">
|
||||
<div
|
||||
:style="{
|
||||
@ -13,6 +21,7 @@
|
||||
id="route-form"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
size="small"
|
||||
>
|
||||
<el-row justify="center">
|
||||
<el-form-item prop="carType">
|
||||
@ -36,86 +45,32 @@
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-form-item prop="startAddress">
|
||||
<el-popover
|
||||
:width="300"
|
||||
:visible="showStartSuggestion && !!formData.startAddress"
|
||||
title="搜索建议"
|
||||
>
|
||||
<div
|
||||
v-for="item in searchTips"
|
||||
:key="item.id"
|
||||
class="suggestion-item"
|
||||
@click="searchPoint(item.name, 'start')"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<template #reference>
|
||||
<!-- TODO: @input="handleInput('start', $event)" -->
|
||||
<el-input
|
||||
v-model="formData.startAddress"
|
||||
size="small"
|
||||
@keydown.enter="
|
||||
searchPoint(formData.startAddress, 'start')
|
||||
"
|
||||
@focus="
|
||||
nowSearch = 'start';
|
||||
showStartSuggestion = true;
|
||||
"
|
||||
@blur="
|
||||
showStartSuggestion = false;
|
||||
nowSearch = '';
|
||||
"
|
||||
@keydown.enter="searchPoint(formData.startAddress, 'start')"
|
||||
@focus="nowSearch = 'start'"
|
||||
@blur="nowSearch = ''"
|
||||
:suffix-icon="
|
||||
formData?.startLngLat?.length
|
||||
? `circle-check-filled`
|
||||
: null
|
||||
formData?.startLngLat ? `circle-check-filled` : null
|
||||
"
|
||||
>
|
||||
<template #prepend>起</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
<el-form-item prop="endAddress">
|
||||
<el-popover
|
||||
:width="300"
|
||||
:visible="showEndSuggestion && !!formData.endAddress"
|
||||
title="搜索建议"
|
||||
>
|
||||
<div
|
||||
v-for="item in searchTips"
|
||||
:key="item.id"
|
||||
class="suggestion-item"
|
||||
@click="searchPoint(item.name, 'end')"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<template #reference>
|
||||
<!--TODO: @input="getAutoComplete" -->
|
||||
<el-input
|
||||
v-model="formData.endAddress"
|
||||
size="small"
|
||||
@keydown.enter="searchPoint(formData.endAddress, 'end')"
|
||||
@focus="
|
||||
nowSearch = 'end';
|
||||
// map.clearMap();
|
||||
showEndSuggestion = true;
|
||||
"
|
||||
@blur="
|
||||
showEndSuggestion = false;
|
||||
nowSearch = '';
|
||||
// searchTips = [];
|
||||
"
|
||||
@focus="nowSearch = 'end'"
|
||||
@blur="nowSearch = ''"
|
||||
:suffix-icon="
|
||||
formData?.endLngLat?.length
|
||||
? `circle-check-filled`
|
||||
: null
|
||||
formData?.endLngLat ? `circle-check-filled` : null
|
||||
"
|
||||
>
|
||||
<template #prepend>终</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
@ -130,6 +85,64 @@
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="formData.carType === '1'" justify="center">
|
||||
<el-col :span="20">
|
||||
<div class="divider"></div>
|
||||
<el-form-item>
|
||||
<el-select class="select-car-size">
|
||||
<template #prefix>车型大小</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="15">
|
||||
<el-form-item>
|
||||
<el-input class="input-width">
|
||||
<template #prepend>宽/高(米)</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="9">
|
||||
<el-form-item>
|
||||
<el-input class="input-height"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="17">
|
||||
<el-form-item>
|
||||
<el-input class="input-width">
|
||||
<template #prepend>车重/载重(吨)</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item>
|
||||
<el-input class="input-height"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="17">
|
||||
<el-form-item>
|
||||
<el-input class="input-width">
|
||||
<template #prepend>车轴(数)/类型</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item>
|
||||
<el-input class="input-height"> </el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item>
|
||||
<el-input placeholder="车牌号码(可判断限行)">
|
||||
<template #prepend>车牌号码</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
justify="space-between"
|
||||
:style="{
|
||||
@ -150,30 +163,48 @@
|
||||
type="border-card"
|
||||
v-if="showStepPane"
|
||||
v-model="formData.lineType"
|
||||
@tab-change="handleTabChange"
|
||||
@tab-change="searchRoute"
|
||||
>
|
||||
<el-tab-pane name="0" label="费用最低">
|
||||
<route-step-list
|
||||
:route-data="formData.lineJson"
|
||||
@step-click="handleRouteClick"
|
||||
@start-click="map.setFitView([startMarker])"
|
||||
@end-click="map.setFitView([endMarker])"
|
||||
@start-click="
|
||||
map.setFitView([startMarker]);
|
||||
stepPolylineActiveIndex = -1;
|
||||
"
|
||||
@end-click="
|
||||
map.setFitView([endMarker]);
|
||||
stepPolylineActiveIndex = -1;
|
||||
"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="1" label="时间最短">
|
||||
<route-step-list
|
||||
:route-data="formData.lineJson"
|
||||
@step-click="handleRouteClick"
|
||||
@start-click="map.setFitView([startMarker])"
|
||||
@end-click="map.setFitView([endMarker])"
|
||||
@start-click="
|
||||
map.setFitView([startMarker]);
|
||||
stepPolylineActiveIndex = -1;
|
||||
"
|
||||
@end-click="
|
||||
map.setFitView([endMarker]);
|
||||
stepPolylineActiveIndex = -1;
|
||||
"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="2" label="距离最短">
|
||||
<route-step-list
|
||||
:route-data="formData.lineJson"
|
||||
@step-click="handleRouteClick"
|
||||
@start-click="map.setFitView([startMarker])"
|
||||
@end-click="map.setFitView([endMarker])"
|
||||
@start-click="
|
||||
map.setFitView([startMarker]);
|
||||
stepPolylineActiveIndex = -1;
|
||||
"
|
||||
@end-click="
|
||||
map.setFitView([endMarker]);
|
||||
stepPolylineActiveIndex = -1;
|
||||
"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@ -215,26 +246,20 @@
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<el-button
|
||||
id="drawer-switch"
|
||||
type="primary"
|
||||
plain
|
||||
circle
|
||||
:icon="drawerOpen ? 'ArrowLeftBold' : 'ArrowRightBold'"
|
||||
@click="switchDrawer"
|
||||
></el-button>
|
||||
|
||||
<div id="map-container"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="AddLine">
|
||||
import tab from "@/plugins/tab";
|
||||
import { onMounted } from "vue";
|
||||
import { onMounted, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { loadAMap } from "@/utils/map";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ElMessage, ElMessageBox, ElOption, ElSelect } from "element-plus";
|
||||
import endPng from "@/assets/images/end.png";
|
||||
import RouteStepList from "./RouteStepList.vue";
|
||||
import startPng from "@/assets/images/start.png";
|
||||
import markBsPng from "@/assets/images/mark_bs.png";
|
||||
import { addLine, getLine, updateLine } from "@/api/line/line";
|
||||
|
||||
const route = useRoute();
|
||||
@ -250,7 +275,7 @@ const endMarker = shallowRef(null); // 终点标记
|
||||
const resultInfoWindow = shallowRef(null);
|
||||
const searchResultMarkers = ref([]); // 搜索结果表笔列表
|
||||
const stepsPolylines = ref([]); // 路线步骤标记列表
|
||||
const stepsList = ref([]);
|
||||
const stepPolylineActiveIndex = ref(-1);
|
||||
const drawerOpen = ref(true);
|
||||
const routeFormRef = ref(null);
|
||||
const searchTips = ref([]);
|
||||
@ -261,8 +286,8 @@ const activeTabName = ref("LEAST_FEE");
|
||||
|
||||
const showStepPane = computed(
|
||||
() =>
|
||||
formData.value?.startLngLat?.length === 2 &&
|
||||
formData.value?.endLngLat?.length === 2 &&
|
||||
formData.value?.startLngLat &&
|
||||
formData.value?.endLngLat &&
|
||||
formData.value.lineJson
|
||||
);
|
||||
|
||||
@ -302,34 +327,34 @@ const data = reactive({
|
||||
},
|
||||
});
|
||||
const { formData, rules } = toRefs(data);
|
||||
|
||||
// 切换左侧面板显示隐藏
|
||||
const switchDrawer = () => {
|
||||
drawerOpen.value = !drawerOpen.value;
|
||||
if (drawerOpen.value) {
|
||||
document.querySelector("#drawer-switch").style.left = "25%";
|
||||
document.querySelector("#drawer-switch").style.transform =
|
||||
document.getElementById("form-drawer").style.left = "0";
|
||||
document.getElementById("drawer-switch").style.left = "25%";
|
||||
document.getElementById("drawer-switch").style.transform =
|
||||
"translate(-50%, -50%)";
|
||||
} else {
|
||||
document.querySelector("#drawer-switch").style.left = "0";
|
||||
document.querySelector("#drawer-switch").style.transform =
|
||||
document.getElementById("form-drawer").style.left = "-100%";
|
||||
document.getElementById("drawer-switch").style.left = "0";
|
||||
document.getElementById("drawer-switch").style.transform =
|
||||
"translate(0, -50%)";
|
||||
}
|
||||
};
|
||||
|
||||
// 地图点击
|
||||
const handleMapClick = (ev) => {
|
||||
// ev.preventDefault();
|
||||
// 起点输入框 focus 时
|
||||
if (nowSearch.value === "start") {
|
||||
map.value.clearMap();
|
||||
if (formData.value?.endLngLat?.length === 2) {
|
||||
if (formData.value?.endLngLat) {
|
||||
map.value.add(endMarker.value);
|
||||
}
|
||||
startMarker.value.setPosition(
|
||||
new AMap.value.LngLat(ev.lnglat.lng, ev.lnglat.lat)
|
||||
);
|
||||
startMarker.value.setPosition(ev.lnglat);
|
||||
map.value.add(startMarker.value);
|
||||
regeoCode([ev.lnglat.lng, ev.lnglat.lat])
|
||||
regeoCode(ev.lnglat)
|
||||
.then((address) => {
|
||||
formData.value.startAddress = address;
|
||||
})
|
||||
@ -342,12 +367,10 @@ const handleMapClick = (ev) => {
|
||||
// 终点输入框 focus 时
|
||||
else if (nowSearch.value === "end") {
|
||||
map.value.clearMap();
|
||||
if (formData.value?.startLngLat?.length === 2) {
|
||||
if (formData.value?.startLngLat) {
|
||||
map.value.add(startMarker.value);
|
||||
}
|
||||
endMarker.value.setPosition(
|
||||
new AMap.value.LngLat(ev.lnglat.lng, ev.lnglat.lat)
|
||||
);
|
||||
endMarker.value.setPosition(ev.lnglat);
|
||||
map.value.add(endMarker.value);
|
||||
regeoCode([ev.lnglat.lng, ev.lnglat.lat])
|
||||
.then((address) => {
|
||||
@ -375,6 +398,121 @@ const regeoCode = (lnglat /** [lng, lat] */) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 根据名称搜索地图标点
|
||||
const searchPoint = (val, type) => {
|
||||
if (!val) return;
|
||||
|
||||
map.value.clearMap();
|
||||
if (type === "start" && formData.value.endLngLat) {
|
||||
map.value.add(endMarker.value);
|
||||
} else if (type === "end" && formData.value.startLngLat) {
|
||||
map.value.add(startMarker.value);
|
||||
}
|
||||
|
||||
placeSearch.value.search(val, (status, result) => {
|
||||
// 添加搜索结果标记
|
||||
if (status === "complete") {
|
||||
if (result.info === "OK") {
|
||||
searchResultMarkers.value = result.poiList.pois.map((el, index) => {
|
||||
const marker = new AMap.value.Marker({
|
||||
map: map.value,
|
||||
position: el.location,
|
||||
extData: el,
|
||||
anchor: "bottom-center",
|
||||
content: `
|
||||
<div
|
||||
style="
|
||||
background-image: url(${markBsPng});
|
||||
width: 19px;
|
||||
height: 31px;
|
||||
background-size: cover;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
padding-top: 3px;
|
||||
pointer-events: none;
|
||||
"
|
||||
>
|
||||
${index + 1}
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
marker.on("click", handleResultClick);
|
||||
marker.on("mouseover", (ev) => {
|
||||
resultInfoWindow.value.setContent(`
|
||||
<div>
|
||||
${ev.target.getExtData().name}</div>
|
||||
`);
|
||||
resultInfoWindow.value.open(map.value, [
|
||||
ev.lnglat.lng,
|
||||
ev.lnglat.lat,
|
||||
]);
|
||||
});
|
||||
marker.on("mouseout", (ev) => {
|
||||
resultInfoWindow.value.close();
|
||||
});
|
||||
return marker;
|
||||
});
|
||||
map.value.setFitView(searchResultMarkers.value);
|
||||
} else if (result.info === "TIP_CITIES") {
|
||||
// 多个城市有此地名时,选择城市
|
||||
ElMessageBox({
|
||||
title: "请选择城市",
|
||||
showCancelButton: true,
|
||||
message: () =>
|
||||
h(
|
||||
ElSelect,
|
||||
{
|
||||
onChange: (val) => {
|
||||
console.log(val);
|
||||
},
|
||||
},
|
||||
() => result.cityList.map((el) => h(ElOption, { value: el.name }))
|
||||
),
|
||||
})
|
||||
.then(() => {})
|
||||
.catch(() => {});
|
||||
} else {
|
||||
throw new Error(result.info);
|
||||
}
|
||||
} else {
|
||||
console.log(status);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 搜索结果点击
|
||||
const handleResultClick = async (ev) => {
|
||||
const lnglat = ev.target.getExtData()?.location;
|
||||
if (!lnglat) return ElMessage.error("获取经纬度失败");
|
||||
let address;
|
||||
try {
|
||||
address = ev.target.getExtData()?.name ?? (await regeoCode(lnglat));
|
||||
} catch (error) {
|
||||
address = `${lnglat.lng},${lnglat.lat}`;
|
||||
}
|
||||
if (nowSearch.value === "start") {
|
||||
map.value.clearMap();
|
||||
if (formData.value?.endLngLat) {
|
||||
map.value.add(endMarker.value);
|
||||
}
|
||||
startMarker.value.setPosition(lnglat);
|
||||
formData.value.startAddress = address;
|
||||
formData.value.startLngLat = lnglat;
|
||||
startMarker.value.setPosition(lnglat);
|
||||
map.value.add(startMarker.value);
|
||||
} else if (nowSearch.value === "end") {
|
||||
map.value.clearMap();
|
||||
if (formData.value?.startLngLat) {
|
||||
map.value.add(startMarker.value);
|
||||
}
|
||||
formData.value.endAddress = address;
|
||||
formData.value.endLngLat = lnglat;
|
||||
endMarker.value.setPosition(lnglat);
|
||||
map.value.add(endMarker.value);
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索路线
|
||||
const searchRoute = () => {
|
||||
if (!driving.value) return;
|
||||
@ -386,15 +524,12 @@ const searchRoute = () => {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
console.log("123");
|
||||
const startLngLat = formData.value.startLngLat;
|
||||
const endLngLat = formData.value.endLngLat;
|
||||
driving.value.search(startLngLat, endLngLat, (status, result) => {
|
||||
// 未出错时,result即是对应的路线规划方案
|
||||
if (status === "complete") {
|
||||
console.log(result);
|
||||
formData.value.lineJson = result;
|
||||
stepsList.value = result.routes[0].steps;
|
||||
drawRoute(result);
|
||||
resolve(result);
|
||||
} else {
|
||||
@ -423,11 +558,11 @@ const drawRoute = (result) => {
|
||||
strokeOpacity: 1,
|
||||
strokeColor: "#808080",
|
||||
strokeStyle: "dashed",
|
||||
path: [
|
||||
new AMap.value.LngLat(...startLngLat),
|
||||
result.routes[0].steps[0].start_location,
|
||||
],
|
||||
lineJoin: "round",
|
||||
lineCap: "round",
|
||||
path: [startLngLat, result.routes[0].steps[0].start_location],
|
||||
});
|
||||
|
||||
// 结束驾驶地点到终点距离以虚直线表示
|
||||
new AMap.value.Polyline({
|
||||
map: map.value,
|
||||
@ -435,11 +570,14 @@ const drawRoute = (result) => {
|
||||
strokeOpacity: 1,
|
||||
strokeColor: "#808080",
|
||||
strokeStyle: "dashed",
|
||||
lineJoin: "round",
|
||||
lineCap: "round",
|
||||
path: [
|
||||
result.routes[0].steps[result.routes[0].steps.length - 1].end_location,
|
||||
new AMap.value.LngLat(...endLngLat),
|
||||
endLngLat,
|
||||
],
|
||||
});
|
||||
|
||||
// 在地图上绘制路线标记,并添加到数组中
|
||||
stepsPolylines.value = result.routes[0].steps.map((el) => {
|
||||
return new AMap.value.Polyline({
|
||||
@ -447,19 +585,53 @@ const drawRoute = (result) => {
|
||||
strokeWeight: 8,
|
||||
strokeOpacity: 1,
|
||||
strokeColor: "#1bac2e",
|
||||
lineJoin: "round",
|
||||
lineCap: "round",
|
||||
showDir: true,
|
||||
path: el.path,
|
||||
});
|
||||
});
|
||||
|
||||
// 绘制step之间的连接线
|
||||
result.routes[0].steps.forEach((el, index, arr) => {
|
||||
if (index >= arr.length - 1) return;
|
||||
const cur = el.end_location;
|
||||
const next = arr[index + 1].start_location;
|
||||
console.log(cur.lng === next.lng && cur.lat === next.lat);
|
||||
// if (cur.lng === next.lng && cur.lat === next.lat) return;
|
||||
new AMap.value.Polyline({
|
||||
map: map.value,
|
||||
strokeWeight: 8,
|
||||
strokeOpacity: 1,
|
||||
strokeColor: "#1bac2e",
|
||||
showDir: true,
|
||||
lineJoin: "round",
|
||||
lineCap: "round",
|
||||
path: [cur, next],
|
||||
});
|
||||
});
|
||||
|
||||
map.value.setFitView(stepsPolylines.value);
|
||||
};
|
||||
|
||||
// 点击步骤列表
|
||||
const handleRouteClick = (data, index) => {
|
||||
console.log(data, index);
|
||||
map.value.setFitView([stepsPolylines.value[index]]);
|
||||
stepPolylineActiveIndex.value = index;
|
||||
};
|
||||
|
||||
// 监听激活的路线index,改变其颜色,恢复上一次点击的颜色
|
||||
watch(stepPolylineActiveIndex, (val, oldVal) => {
|
||||
val != -1 &&
|
||||
stepsPolylines.value[val].setOptions({
|
||||
strokeColor: "#d12209",
|
||||
});
|
||||
oldVal != -1 &&
|
||||
stepsPolylines.value[oldVal].setOptions({
|
||||
strokeColor: "#1bac2e",
|
||||
});
|
||||
});
|
||||
|
||||
// 清除路线,reset form
|
||||
const clearRoute = () => {
|
||||
formData.value.lineJson = null;
|
||||
@ -467,38 +639,41 @@ const clearRoute = () => {
|
||||
formData.value.endAddress = "";
|
||||
formData.value.startLngLat = null;
|
||||
formData.value.endLngLat = null;
|
||||
stepsList.value = [];
|
||||
map.value.clearMap();
|
||||
};
|
||||
|
||||
// tab点击事件
|
||||
const handleTabChange = (tab) => {
|
||||
if (formData.value.startLngLat.length && formData.value.endLngLat.length) {
|
||||
searchRoute();
|
||||
} else {
|
||||
// ElMessage.error("err");
|
||||
}
|
||||
};
|
||||
// const handleTabChange = (tab) => {
|
||||
// if (formData.value.startLngLat && formData.value.endLngLat) {
|
||||
// searchRoute();
|
||||
// } else {
|
||||
// // ElMessage.error("err");
|
||||
// }
|
||||
// };
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
routeFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
const lineJson = formData.value.lineJson
|
||||
? JSON.stringify(formData.value.lineJson)
|
||||
: null;
|
||||
if (!lineJson) return ElMessage.error("未选择路线");
|
||||
if (formData.value.lineId != null) {
|
||||
updateLine({
|
||||
...formData.value,
|
||||
lineJson: JSON.stringify(formData.value.lineJson),
|
||||
lineJson,
|
||||
reportType: formData.value.reportType.join(","),
|
||||
}).then((response) => {
|
||||
}).then(() => {
|
||||
ElMessage.success("修改成功");
|
||||
back();
|
||||
});
|
||||
} else {
|
||||
addLine({
|
||||
...formData.value,
|
||||
lineJson: JSON.stringify(formData.value.lineJson),
|
||||
lineJson,
|
||||
reportType: formData.value.reportType.join(","),
|
||||
}).then((response) => {
|
||||
}).then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
back();
|
||||
});
|
||||
@ -507,9 +682,9 @@ function submitForm() {
|
||||
});
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const reset = () => {
|
||||
formData.value = {
|
||||
// lineId: null,
|
||||
lineName: null,
|
||||
carType: "0",
|
||||
lineType: "0",
|
||||
@ -517,16 +692,14 @@ const reset = () => {
|
||||
endAddress: null,
|
||||
reportType: [],
|
||||
lineJson: null,
|
||||
// linePath: null,
|
||||
// createBy: null,
|
||||
// createTime: null,
|
||||
// uuid: null,
|
||||
// tenantId: null,
|
||||
};
|
||||
routeFormRef.value && routeFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const getFormData = async () => {
|
||||
if (route.query.lineId && route.query.uuid) {
|
||||
const routerObj = Object.assign({}, route, { title: "修改路径" });
|
||||
tab.updatePage(routerObj);
|
||||
getLine(route.query.lineId, route.query.uuid).then((resp) => {
|
||||
let lineJson;
|
||||
try {
|
||||
@ -574,9 +747,9 @@ onMounted(async () => {
|
||||
map.value = new AMap.value.Map("map-container", {
|
||||
zoom: 16, // 缩放级别
|
||||
center: [117.290345, 31.797813], // 中心点
|
||||
city: "合肥",
|
||||
// city: "合肥",
|
||||
});
|
||||
|
||||
window.mapinstance = map.value;
|
||||
/** 加载插件 */
|
||||
// 驾车路线规划插件
|
||||
driving.value = new AMap.value.Driving();
|
||||
@ -586,7 +759,7 @@ onMounted(async () => {
|
||||
// 地点搜索插件
|
||||
placeSearch.value = new AMap.value.PlaceSearch({
|
||||
// map: map.value,
|
||||
city: "0551",
|
||||
city: "全国",
|
||||
});
|
||||
geocoder.value = new AMap.value.Geocoder();
|
||||
// 搜索建议插件
|
||||
@ -600,6 +773,10 @@ onMounted(async () => {
|
||||
icon: endPng,
|
||||
anchor: "bottom-center",
|
||||
});
|
||||
resultInfoWindow.value = new AMap.value.InfoWindow({
|
||||
anchor: "bottom-center",
|
||||
offset: new AMap.value.Pixel(0, -31),
|
||||
});
|
||||
map.value.on("click", handleMapClick);
|
||||
|
||||
// 当修改时,从返回数据中读取路线数据绘制
|
||||
@ -616,14 +793,14 @@ onMounted(async () => {
|
||||
width: 100%;
|
||||
height: calc(100vh - 84px);
|
||||
}
|
||||
.form-drawer {
|
||||
#form-drawer {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 99;
|
||||
z-index: 999;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
@ -648,19 +825,70 @@ onMounted(async () => {
|
||||
padding-left: 3px;
|
||||
}
|
||||
}
|
||||
:deep(.el-input-group__prepend) {
|
||||
padding: 0 8px;
|
||||
}
|
||||
:deep(.select-car-size) {
|
||||
.el-input__wrapper {
|
||||
padding-left: 0;
|
||||
// overflow: hidden;
|
||||
.el-input__prefix {
|
||||
// box-shadow: rgb(220, 223, 230) 1px 0px 0px 0px inset,
|
||||
// rgb(220, 223, 230) 0px 1px 0px 0px inset,
|
||||
// rgb(220, 223, 230) 0px -1px 0px 0px inset;
|
||||
.el-input__prefix-inner {
|
||||
& > div {
|
||||
box-sizing: border-box;
|
||||
border-radius: 20px 0 0 20px;
|
||||
background-color: #f5f7fa;
|
||||
padding: 0 8px;
|
||||
margin-right: 0;
|
||||
border-right: 1px solid #c0c4cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-input__inner {
|
||||
padding-left: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.input-width) {
|
||||
.el-input__wrapper {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
:deep(.input-height) {
|
||||
.el-input__wrapper {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
:deep(.submit-bar) {
|
||||
width: 100%;
|
||||
.el-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.divider {
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
margin: 6px 0;
|
||||
border-top: 1px solid #dcdfe6;
|
||||
}
|
||||
}
|
||||
:deep(#drawer-switch) {
|
||||
position: absolute;
|
||||
left: 25%;
|
||||
top: 50%;
|
||||
z-index: 100;
|
||||
z-index: 1000;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.amap-info {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
</style>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<el-row class="search-bar" :gutter="10">
|
||||
<el-col :span="18">
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
size="small"
|
||||
placeholder="请输入地名或点击地图选点"
|
||||
@keypress.enter="searchPoint"
|
||||
@ -90,13 +91,15 @@ import { useRoute } from "vue-router";
|
||||
import { loadAMap } from "@/utils/map";
|
||||
import { listSiteGroup } from "@/api/site/group";
|
||||
import CitySelect from "@/components/CitySelect";
|
||||
import markBsPng from "@/assets/images/mark_bs.png";
|
||||
import { addSite, getSite, updateSite } from "@/api/site/site";
|
||||
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance();
|
||||
const geocoder = shallowRef(null); // 经纬度转地址插件
|
||||
const placeSearch = shallowRef(null);
|
||||
const searchResultMarkers = shallowRef([]); // 搜索结果表笔列表
|
||||
const resultInfoWindow = shallowRef(null);
|
||||
const siteMarker = shallowRef(null);
|
||||
const searchKeyword = ref("");
|
||||
const AMap = shallowRef(null);
|
||||
const map = shallowRef(null);
|
||||
@ -157,7 +160,6 @@ const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
form.value.fencePath = [];
|
||||
|
||||
placeSearch.value.search(searchKeyword.value, (status, result) => {
|
||||
console.log(status, result);
|
||||
// TODO: 添加搜索结果标记
|
||||
if (status === "complete") {
|
||||
searchResultMarkers.value = result.poiList.pois.map((el, index) => {
|
||||
@ -165,6 +167,7 @@ const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
map: map.value,
|
||||
position: new AMap.value.LngLat(el.location.lng, el.location.lat),
|
||||
extData: el,
|
||||
anchor: "bottom-center",
|
||||
content: `
|
||||
<div
|
||||
style="
|
||||
@ -182,7 +185,7 @@ const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
marker.on("mouseover", handleResultClick);
|
||||
marker.on("mouseover", () => {});
|
||||
marker.on("click", handleMapClick);
|
||||
marker.on("mouseout", (ev) => {
|
||||
resultInfoWindow.value.close();
|
||||
@ -218,7 +221,27 @@ function reset() {
|
||||
proxy.resetForm("siteRef");
|
||||
}
|
||||
|
||||
onMounted(async () => {});
|
||||
|
||||
listSiteGroup().then((resp) => {
|
||||
siteGroupList.value = resp.rows;
|
||||
});
|
||||
|
||||
reset();
|
||||
onMounted(async () => {
|
||||
// load form
|
||||
if (route.query.siteId && route.query.uuid) {
|
||||
const routerObj = Object.assign({}, route, { title: "站点修改" });
|
||||
tab.updatePage(routerObj);
|
||||
const resp = await getSite(route.query.siteId, route.query.uuid);
|
||||
form.value = resp.data;
|
||||
open.value = true;
|
||||
title.value = "修改站点";
|
||||
} else {
|
||||
open.value = true;
|
||||
title.value = "添加站点";
|
||||
}
|
||||
// 加载地图
|
||||
const _AMap = await loadAMap([
|
||||
"AMap.Scale",
|
||||
"AMap.Geocoder",
|
||||
@ -229,32 +252,28 @@ onMounted(async () => {
|
||||
zoom: 16, // 缩放级别
|
||||
center: [117.290345, 31.797813], // 中心点
|
||||
});
|
||||
resultInfoWindow.value = new AMap.value.InfoWindow({
|
||||
anchor: "bottom-center",
|
||||
offset: new AMap.value.Pixel(0, -31),
|
||||
});
|
||||
siteMarker.value = new AMap.value.Marker();
|
||||
// 地点搜索插件
|
||||
placeSearch.value = new AMap.value.PlaceSearch({
|
||||
// map: map.value,
|
||||
city: "0551",
|
||||
});
|
||||
geocoder.value = new AMap.value.Geocoder();
|
||||
map.value.on("click", handleMapClick);
|
||||
map.value.addControl(new AMap.value.Scale());
|
||||
});
|
||||
|
||||
listSiteGroup().then((resp) => {
|
||||
siteGroupList.value = resp.rows;
|
||||
});
|
||||
|
||||
reset();
|
||||
|
||||
if (route.query.siteId && route.query.uuid) {
|
||||
getSite(route.query.siteId, route.query.uuid).then((resp) => {
|
||||
form.value = resp.data;
|
||||
open.value = true;
|
||||
title.value = "修改站点";
|
||||
});
|
||||
} else {
|
||||
open.value = true;
|
||||
title.value = "添加站点";
|
||||
// TODO:
|
||||
if (form.value.coordinate) {
|
||||
siteMarker.value.setPosition(
|
||||
new AMap.value.LngLat(...form.value.coordinate.split(","))
|
||||
);
|
||||
map.value.add(siteMarker.value);
|
||||
map.value.setFitView([siteMarker.value]);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -96,7 +96,12 @@
|
||||
<el-table-column label="省" align="center" prop="province" />
|
||||
<el-table-column label="市" align="center" prop="city" />
|
||||
<el-table-column label="区" align="center" prop="area" /> -->
|
||||
<el-table-column label="详细地址" align="center" prop="address" />
|
||||
<el-table-column
|
||||
label="详细地址"
|
||||
align="center"
|
||||
prop="address"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column
|
||||
label="经纬度"
|
||||
align="center"
|
||||
|
Reference in New Issue
Block a user