6/24 统一地图组件入口,规范地图方法,属性。 完成天地图和高德切换

This commit is contained in:
Zy
2026-06-24 16:19:19 +08:00
parent 33d35c8d70
commit 4e2ae414c4
14 changed files with 515 additions and 188 deletions

View File

@@ -5,7 +5,7 @@
<div class="title">
<div>基本信息</div>
</div>
<div class="bodybox">
<div class="bodyBox">
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="right">
<el-form-item label="巡检计划名称" prop="planName">
<el-input v-model="form.planName" placeholder="请输入"></el-input>
@@ -22,7 +22,7 @@
v-for="(item, index) in 7"
:key="index"
>
<div class="iconbox">
<div class="iconBox">
<el-icon v-show="checkoutWeek.includes(item)"><Check /></el-icon>
</div>
<span class="ml-5px">{{ numToWeek(item) }}</span>
@@ -64,7 +64,7 @@
<el-select @change="handleChangeMap" v-model="form.routeIds" placeholder="请选择" style="width: 100%">
<el-option v-for="item in playlist" :key="item.value" :label="item.routeName" :value="item.id" />
</el-select>
<GD ref="GDef" :disabled="true"></GD>
<MapWrapper :disabled="true" ref="MapWrapperRef"></MapWrapper>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">提交</el-button>
@@ -83,7 +83,9 @@ import { numToWeek } from '@/utils/time';
import { ref } from 'vue';
import { addPlan, getPlan, updatePlan } from '@/api/system/InspectionPlan';
import { Check } from '@element-plus/icons-vue';
import GD from '@/components/Map/GD.vue';
import MapWrapper from '@/components/Map/index.vue';
import { PointVO } from '@/api/system/InspectionPoint/type';
import { LngLat } from '@/components/Map/type';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_inspection_remind_tiime } = toRefs<any>(proxy?.useDict('com_inspection_remind_tiime'));
@@ -123,7 +125,7 @@ function checkoutWeekFun(val: number) {
// 提醒时间
// 巡检计划id
const editid = ref(null);
const editId = ref(null);
// 初始化
// 路线列表
@@ -132,8 +134,8 @@ async function init() {
const res = await listRoute();
playlist.value = res.rows;
if (route.query.id) {
editid.value = route.query.id;
getPlan(editid.value).then((res) => {
editId.value = route.query.id;
getPlan(editId.value).then((res) => {
form.value = {
id: res.data.id,
planName: res.data.planName, // 巡检计划名称
@@ -176,21 +178,21 @@ function outback() {
router.back();
}
const GDef = ref(null);
const MapWrapperRef = ref<InstanceType<typeof MapWrapper>>();
function handleChangeMap(val: string) {
if (val) {
GDef.value.clearMapMarker();
MapWrapperRef.value.clearMapMarker();
const find = playlist.value.find((item) => item.id === val);
if (find.points && find.points.length > 0) {
find.points.forEach((item) => {
const angular = item.location.split(',').map(Number).filter(Boolean);
GDef.value.addMarker_more(angular, item.pointNames, item.id);
find.points.forEach((item: PointVO) => {
const angular = item.location.split(',').map(Number).filter(Boolean) as LngLat;
MapWrapperRef.value.addMarker_more(angular, item.pointName, item.id);
});
}
// 巡检路线
if (find.pathPoints) {
GDef.value.renderSavedPath(find.pathPoints);
MapWrapperRef.value.renderSavedPath(find.pathPoints);
}
}
}
@@ -208,7 +210,7 @@ function submit() {
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (editid.value) {
if (editId.value) {
updatePlan(form.value).then(() => {
ElMessage.success('编辑成功');
outback();
@@ -229,7 +231,7 @@ function submit() {
margin-top: 20px;
padding: 30px;
background-color: white;
.bodybox {
.bodyBox {
width: 600px;
margin: 20px auto 0;
}
@@ -264,7 +266,7 @@ function submit() {
color: #44a0ff;
}
}
.deleteaction {
.deleteAction {
margin-left: 10px;
cursor: pointer;
&:hover {
@@ -284,7 +286,7 @@ function submit() {
color: #000;
display: flex;
align-items: center;
.iconbox {
.iconBox {
width: 30px;
height: 30px;
margin-left: 5px;

View File

@@ -9,15 +9,15 @@
<el-input v-model.trim="form.pointName" placeholder="请输入巡检点名称" />
</el-form-item>
<el-form-item label="巡检项目" prop="itemId">
<div class="itembox">
<div class="itemBox">
<div
class="item"
:class="{
disabled: item.status === '1',
active: checkoutPointItemlist.includes(item.id)
active: checkoutPointItemList.includes(item.id)
}"
@click="checkoutItem(item.id)"
v-for="(item, index) in pointItemlist"
v-for="(item, index) in pointItemList"
:key="index"
>
<el-icon><Check /></el-icon>
@@ -25,11 +25,6 @@
</div>
</div>
</el-form-item>
<!-- <el-form-item label="打卡方式" prop="checkMode">
<el-select v-model="form.checkMode" placeholder="请选择打卡方式" clearable>
<el-option v-for="dict in com_inspection_point_checkmode" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item> -->
<el-form-item label="巡检点状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="item in com_inspection_point_status" :value="item.value" :key="item.value" :label="item.value">{{
@@ -38,7 +33,7 @@
</el-radio-group>
</el-form-item>
<el-form-item label="巡检点位置" prop="location">
<GD :click-or-draw="true" ref="GDef" @click-point="handleClickPoint"></GD>
<MapWrapper :click-or-draw="true" ref="MapWrapperRef" @click-point="handleClickMapPoint"></MapWrapper>
<div class="tips">
<span>点击地图选择位置</span>
<span
@@ -46,7 +41,7 @@
v-show="Boolean(marker)"
@click="
() => {
GDef.clearLocation();
MapWrapperRef.clearLocation();
}
"
>清空选择地点</span
@@ -74,7 +69,8 @@ import { listItem } from '@/api/system/InspectionItem';
import { onMounted } from 'vue';
import { Check } from '@element-plus/icons-vue';
import GD from '@/components/Map/GD.vue';
import MapWrapper from '@/components/Map/index.vue';
import { LngLat } from '@/components/Map/type';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_inspection_point_status } = toRefs<any>(proxy?.useDict('com_inspection_point_status'));
@@ -103,17 +99,17 @@ const rules = ref({
// !== 初始化 =============================================================================
const pointId = ref(null);
const pointItemlist = ref([]);
const checkoutPointItemlist = ref([]);
const pointItemList = ref([]);
const checkoutPointItemList = ref([]);
const marker = ref(null);
function checkoutItem(id: string) {
form.value.itemId = ''; // 每次点击都先清空 itemId
if (checkoutPointItemlist.value.includes(id)) {
checkoutPointItemlist.value = checkoutPointItemlist.value.filter((item) => item !== id);
if (checkoutPointItemList.value.includes(id)) {
checkoutPointItemList.value = checkoutPointItemList.value.filter((item) => item !== id);
} else {
checkoutPointItemlist.value.push(id);
checkoutPointItemList.value.push(id);
}
form.value.itemId = checkoutPointItemlist.value.join(','); // 将选中的 id 数组转换为逗号分隔的字符串
form.value.itemId = checkoutPointItemList.value.join(','); // 将选中的 id 数组转换为逗号分隔的字符串
}
function init() {
// 获取巡检项目列表
@@ -122,7 +118,7 @@ function init() {
pageNum: 1,
pageSize: 9999
}).then((res) => {
pointItemlist.value = res.rows;
pointItemList.value = res.rows;
});
if (route.query.id) {
@@ -133,18 +129,15 @@ function init() {
...form.value,
...res.data
};
// 如果有 itemId拆分到 checkoutPointItemlist
// 如果有 itemId拆分到 checkoutPointItemList
if (res.data.itemId) {
checkoutPointItemlist.value = res.data.itemId.split(',');
checkoutPointItemList.value = res.data.itemId.split(',');
}
const location = form.value.location
.split(',')
.map((item) => Number(item))
.filter((item) => !Number.isNaN(item));
const location = form.value.location.split(',').map(Number).filter(Boolean) as LngLat;
if (location.length >= 2) {
setTimeout(() => {
marker.value = GDef.value.addMarker_only(location);
marker.value = MapWrapperRef.value.addMarker_only(location, form.value.pointName);
}, 500);
}
});
@@ -156,7 +149,7 @@ const submitForm = () => {
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 设置 itemId
form.value.itemId = checkoutPointItemlist.value.join(',');
form.value.itemId = checkoutPointItemList.value.join(',');
if (pointId.value) {
updatePoint(form.value).then(() => {
ElMessage.success('编辑成功');
@@ -176,11 +169,11 @@ const cancelForm = () => {
router.back();
};
const GDef = ref();
function handleClickPoint(laglat: number[]) {
const MapWrapperRef = ref<InstanceType<typeof MapWrapper>>();
function handleClickMapPoint(LngLat: LngLat) {
marker.value = null;
form.value.location = `${laglat[0]},${laglat[1]}`;
marker.value = GDef.value.addMarker_only(laglat);
form.value.location = `${LngLat[0]},${LngLat[1]}`;
marker.value = MapWrapperRef.value.addMarker_only(LngLat, form.value.pointName);
}
onMounted(async () => {
@@ -215,7 +208,7 @@ onMounted(async () => {
width: 800px;
margin: 0 auto;
.itembox {
.itemBox {
display: flex;
flex-wrap: wrap;
.item {

View File

@@ -9,23 +9,23 @@
<el-input v-model.trim="form.routeName" placeholder="请输入巡检路线名称" />
</el-form-item>
<el-form-item label="巡检点">
<div class="itembox">
<div class="itemBox">
<div
class="item"
:class="{
active: checkoutPointlist.includes(item.id)
active: checkoutPointList.includes(item.id)
}"
v-for="(item, index) in pointslist"
v-for="(item, index) in pointsList"
@click="checkoutItemPoint(item)"
:key="index"
>
<el-icon v-show="checkoutPointlist.includes(item.id)"><Check /></el-icon>
<el-icon v-show="checkoutPointList.includes(item.id)"><Check /></el-icon>
<div>{{ item.pointName }}</div>
</div>
</div>
</el-form-item>
<el-form-item label="绘制巡检路线">
<GD :small-scroll="true" ref="GDef" :click-or-draw="false"></GD>
<MapWrapper :click-or-draw="false" ref="MapWrapperRef"></MapWrapper>
<div class="tips flex flex-items-center justify-between">
<div>点击地图绘制巡检路线再次点击可继续绘制下一条但只能保留一条</div>
<div>
@@ -33,7 +33,7 @@
class="deleteMarker"
@click="
() => {
GDef.clearAll();
MapWrapperRef.clearAll();
}
"
>清空所有路线</span
@@ -60,7 +60,9 @@ import { onMounted, onUnmounted } from 'vue';
import { addRoute, getRoute, updateRoute } from '@/api/system/InspectionRoute';
import { Check } from '@element-plus/icons-vue';
import GD from '@/components/Map/GD.vue';
import MapWrapper from '@/components/Map/index.vue';
import { LngLat } from '@/components/Map/type';
import { PointVO } from '@/api/system/InspectionPoint/type';
const router = useRouter();
const route = useRoute();
@@ -85,19 +87,19 @@ const rules = ref({
estimatedTime: [{ required: true, message: '请输入预计巡检时长', trigger: 'blur' }]
});
const GDef = ref();
const routeid = ref(null);
const MapWrapperRef = ref<InstanceType<typeof MapWrapper>>();
const routeId = ref(null);
// 巡检点 列表
const pointslist = ref([]);
const pointsList = ref<PointVO[]>([]);
// 选择巡检点列表
const checkoutPointlist = ref([]);
const checkoutPointList = ref([]);
// ! 初始化 =========================================================================
function init() {
if (route.query.id) {
routeid.value = route.query.id;
routeId.value = route.query.id;
// 获取巡检点详情
getRoute(routeid.value).then((res) => {
getRoute(routeId.value).then((res) => {
form.value = {
id: res.data.id,
startLat: res.data.startLat,
@@ -112,29 +114,27 @@ function init() {
totalPoints: res.data.totalPoints // 巡检点
};
nextTick(() => {
if (routeid.value) {
checkoutPointlist.value = res.data.totalPoints ? res.data.totalPoints.split(',') : [];
if (checkoutPointlist.value.length > 0) {
if (routeId.value) {
checkoutPointList.value = res.data.totalPoints ? res.data.totalPoints.split(',') : [];
if (checkoutPointList.value.length > 0) {
// 回显 marker
checkoutPointlist.value.forEach((id) => {
checkoutPointList.value.forEach((id) => {
const find = res.data.points.find((item) => item.id === id);
if (find && find.location) {
// addPointMarker(id, find.location, find.pointName);
const location = find.location
.split(',')
.map((item) => Number(item))
.filter((item) => !Number.isNaN(item));
.filter(Boolean) as LngLat;
if (location.length >= 2) {
GDef.value.addMarker_more(location, find.pointName, find.id);
MapWrapperRef.value.addMarker_more(location, find.pointName, find.id);
}
}
});
}
// 回显路线
if (res.data.pathPoints) {
// renderSavedPath(res.data.pathPoints);
setTimeout(() => {
GDef.value.renderSavedPath(res.data.pathPoints);
MapWrapperRef.value.renderSavedPath(res.data.pathPoints);
}, 800);
}
}
@@ -146,9 +146,9 @@ const map = ref<any>(null);
onMounted(async () => {
// 获取巡检点列表
if (!routeid.value) {
if (!routeId.value) {
listPoint({}).then((res) => {
pointslist.value = res.rows;
pointsList.value = res.rows;
});
}
await nextTick(() => init());
@@ -163,15 +163,15 @@ const submitForm = () => {
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 获取路线经纬度
const path = GDef.value.getAllDrawLines() as [number, number][];
const path = MapWrapperRef.value.getAllDrawLines() as LngLat[];
console.log(path);
if (path.length === 0) {
ElMessage.warning('请绘制巡检路线');
return;
}
// 转成字符串传给后端
const [start_lng, start_lat] = path.at(0) as [number, number];
const [end_lng, end_lat] = path.at(-1) as [number, number];
const [start_lng, start_lat] = path.at(0) as LngLat;
const [end_lng, end_lat] = path.at(-1) as LngLat;
form.value.startLng = `${start_lng}`;
form.value.startLat = `${start_lat}`;
@@ -179,8 +179,8 @@ const submitForm = () => {
form.value.endLat = `${end_lat}`;
form.value.pathPoints = JSON.stringify(path);
form.value.totalPoints = checkoutPointlist.value.join(',');
if (routeid.value) {
form.value.totalPoints = checkoutPointList.value.join(',');
if (routeId.value) {
updateRoute(form.value).then(() => {
ElMessage.success('编辑成功');
cancelForm();
@@ -200,20 +200,19 @@ const cancelForm = () => {
};
// 点击展现 巡检点
function checkoutItemPoint(pop) {
const find = pointslist.value.find((item) => item.id === pop.id);
function checkoutItemPoint(pop: PointVO) {
const find = pointsList.value.find((item) => item.id === pop.id);
if (find && find.location) {
const locations =
find.location
.split(',')
.map((item: string) => Number(item))
.filter(Boolean) ?? [];
const locations = find.location
.split(',')
.map((item: string) => Number(item))
.filter(Boolean) as LngLat;
if (locations.length >= 2) {
GDef.value.addMarker_more(locations, find.pointName, find.id);
if (checkoutPointlist.value.includes(pop.id)) {
checkoutPointlist.value = checkoutPointlist.value.filter((item) => item !== pop.id);
MapWrapperRef.value.addMarker_more(locations, find.pointName, find.id);
if (checkoutPointList.value.includes(pop.id)) {
checkoutPointList.value = checkoutPointList.value.filter((item) => item !== pop.id);
} else {
checkoutPointlist.value.push(pop.id);
checkoutPointList.value.push(pop.id);
}
} else {
ElMessage.error(find.pointName + ' - 巡检点经纬度定位有误');
@@ -252,7 +251,7 @@ onUnmounted(() => {
width: 800px;
margin: 0 auto;
.itembox {
.itemBox {
display: flex;
flex-wrap: wrap;
.item {

View File

@@ -5,7 +5,7 @@
<div class="title">
<div>基本信息</div>
</div>
<div class="bodybox">
<div class="bodyBox">
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="right">
<el-form-item label="任务名称" prop="taskName">
<el-input v-model="form.taskName" placeholder="请输入"></el-input>
@@ -14,7 +14,7 @@
<div class="inspectorIdsBox">
<div v-for="(item, index) in checkoutUserlist" :key="index" class="inspector_items">
<div class="name">{{ item.nickName }}</div>
<i @click="handleDelete(item.userId)" class="deleteaction">
<i @click="handleDelete(item.userId)" class="deleteAction">
<el-icon><Delete /></el-icon>
</i>
</div>
@@ -51,22 +51,17 @@
<el-option v-for="item in com_inspection_remind_tiime" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<!-- <el-form-item label="巡检设置">
<el-checkbox-group @change="handleChagneSetting" v-model="Settinglist">
<el-checkbox v-for="(item, index) in com_inspection_plan_setting" :key="index" :label="item.label" :value="item.value" />
</el-checkbox-group>
</el-form-item> -->
<el-form-item label="关联计划" props="planId">
<el-select @change="handleChangeMap" v-model="form.planId" placeholder="请选择" style="width: 100%">
<el-option v-for="item in planlist" :key="item.id" :label="item.planName" :value="item.id" />
<el-option v-for="item in planList" :key="item.id" :label="item.planName" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="计划路线" props="planId">
<GD v-loading="maploading" ref="GDef" :disabled="true"></GD>
<MapWrapper v-loading="mapLoading" :disabled="true" ref="MapWrapperRef"></MapWrapper>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">提交</el-button>
<el-button @click="routeback">返回</el-button>
<el-button @click="outback">返回</el-button>
</el-form-item>
</el-form>
</div>
@@ -82,8 +77,8 @@ import { ref } from 'vue';
import { listPlan } from '@/api/system/InspectionPlan';
import { addTask, getTask, updateTask } from '@/api/system/InspectionTask';
import { getRoute } from '@/api/system/InspectionRoute';
import GD from '@/components/Map/GD.vue';
import MapWrapper from '@/components/Map/index.vue';
import { LngLat } from '@/components/Map/type';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_inspection_remind_tiime } = toRefs<any>(proxy?.useDict('com_inspection_remind_tiime'));
@@ -106,36 +101,19 @@ const rules = ref({
inspectorId: [{ required: true, message: '请选择巡检人员', trigger: 'blur' }],
planId: [{ required: true, message: '请选择巡检计划', trigger: 'blur' }]
});
// 提醒时间
const remindTimeoptions = ref([
{
value: 10,
label: '任务开始前10分钟'
},
{
value: 15,
label: '任务开始前15分钟'
},
{
value: 20,
label: '任务开始前30分钟'
}
]);
// 巡检计划id
const editid = ref(null);
const editId = ref(null);
// 初始化
// 路线列表
const planlist = ref([]);
const planList = ref([]);
async function init() {
// 获取 路线 列表
const res = await listPlan();
planlist.value = res.rows;
planList.value = res.rows;
if (route.query.id) {
editid.value = route.query.id;
getTask(editid.value).then((res) => {
editId.value = route.query.id;
getTask(editId.value).then((res) => {
form.value = {
id: res.data.id,
taskName: res.data.taskName, // 巡检计划名称
@@ -157,51 +135,51 @@ function handleAddUser() {
RepairUserRef.value.open();
}
const checkoutUserlist = ref([]);
function handleUserChange(val) {
function handleUserChange(val: any[]) {
checkoutUserlist.value = val;
}
function handleDelete(id) {
function handleDelete(id: string) {
checkoutUserlist.value = checkoutUserlist.value.filter((item) => item.userId !== id);
}
// 返回
function routeback() {
function outback() {
router.back();
}
const maploading = ref(false);
const mapLoading = ref(false);
const GDef = ref(null);
const MapWrapperRef = ref<InstanceType<typeof MapWrapper>>();
function handleChangeMap(val: string) {
maploading.value = true;
const find = planlist.value.find((item) => item.id === val);
mapLoading.value = true;
const find = planList.value.find((item) => item.id === val);
if (find) {
const route = find.routeList[find.routeList.length - 1];
if (route) {
getRoute(route.id)
.then((res) => {
if (res) {
GDef.value.clearMapMarker();
MapWrapperRef.value.clearMapMarker();
if (res.data.points && res.data.points.length > 0) {
res.data.points.forEach((item) => {
const angular = item.location.split(',').map(Number).filter(Boolean);
GDef.value.addMarker_more(angular, item.pointName, item.id);
const angular = item.location.split(',').map(Number).filter(Boolean) as LngLat;
MapWrapperRef.value.addMarker_more(angular, item.pointName, item.id);
});
}
// 巡检路线
if (res.data.pathPoints) {
GDef.value.renderSavedPath(res.data.pathPoints);
MapWrapperRef.value.renderSavedPath(res.data.pathPoints);
}
}
})
.finally(() => {
maploading.value = false;
mapLoading.value = false;
});
} else {
maploading.value = false;
mapLoading.value = false;
}
} else {
maploading.value = false;
mapLoading.value = false;
}
}
@@ -219,15 +197,15 @@ function submit() {
form.value.inspectorId = checkoutUserlist.value.map((item) => item.userId).join(',');
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (editid.value) {
if (editId.value) {
updateTask(form.value).then(() => {
ElMessage.success('编辑成功');
routeback();
outback();
});
} else {
addTask(form.value).then(() => {
ElMessage.success('添加成功');
routeback();
outback();
});
}
}
@@ -240,7 +218,7 @@ function submit() {
margin-top: 20px;
padding: 30px;
background-color: white;
.bodybox {
.bodyBox {
width: 600px;
margin: 20px auto 0;
}
@@ -275,7 +253,7 @@ function submit() {
color: #44a0ff;
}
}
.deleteaction {
.deleteAction {
margin-left: 10px;
cursor: pointer;
&:hover {
@@ -295,7 +273,7 @@ function submit() {
color: #000;
display: flex;
align-items: center;
.iconbox {
.iconBox {
width: 30px;
height: 30px;
margin-left: 5px;