You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

437 lines
9.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<!-- 自定义标题 -->
<uni-nav-bar left-icon="left" left-text="" background-color="#537CF7" color="#ffffff" @clickLeft="goBack">
<text class="navbar-title">{{ status ? '应急抢险工单详情' : '应急抢险工单录入' }}</text>
</uni-nav-bar>
<!-- 地图容器 -->
<view class="map-container" id="map"></view>
<!-- 搜索框 -->
<!-- <view class="top-container">
<image src="/static/images/地图icon.png" mode=""></image>
<view class="search-container">
<uni-easyinput v-model="keyword" placeholder="请在地图上选择点位或手动输入" class="search-input" @confirm="toSearch" @input="handleInput" disabled></uni-easyinput>
<view class="search-results" v-if="searchBox && searchList.length > 0">
<view class="search-item" v-for="(item, index) in searchList" :key="index" @click="centerMap(item)">
<view class="item-name">{{ item.name }}</view>
<view class="item-address">{{ item.address }}</view>
</view>
</view>
</view>
</view> -->
<!-- 表单 -->
<view class="form-container">
<emDetailsform :order-id="orderId" />
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import 'mars2d/mars2d.css';
import * as mars2d from 'mars2d';
import emDetailsform from '/components/emDetailsform';
import { getEmergencyOrderById } from '@/api/emergency/api';
const orderId = ref(null);
const status = ref(null);
const map = ref(null);
const selectedMarker = ref(null);
const pointForm = ref({
name: '',
lat: '',
lng: '',
address: ''
});
const keyword = ref('');
const searchList = ref([]);
const searchBox = ref(false);
const gaodeKey = 'bd665f6310bb41cdaea4494ec86fcbfa';
const searchDebounce = ref(null);
// 返回
function goBack() {
uni.navigateBack();
}
//地图
function initMap() {
map.value = new mars2d.Map('map', {
zoom: 17,
copyright: false,
// 使用默认中心点后续会被API数据覆盖
center: { lng: 121.442442, lat: 31.197245 },
basemaps: [{ name: '高德地图', type: 'gaode', layer: 'vec', show: true }],
graphicLayer: {
id: 'graphicLayer',
isAutoAdd: true
},
chinaCRS: 'GCJ02'
});
map.value.on('load', () => {
selectedMarker.value = new mars2d.graphic.Marker({
latlng: [121.442442, 31.197245],
style: { opacity: 0 }
});
map.value.graphicLayer.addGraphic(selectedMarker.value);
});
}
function addDefaultMarker(latlng) {
selectedMarker.value = new mars2d.graphic.Marker({
latlng: [latlng.lat, latlng.lng],
style: {
image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
width: 20,
height: 30,
draggable: true
}
});
map.value.graphicLayer.addGraphic(selectedMarker.value);
selectedMarker.value.on('dragend', (event) => {
const newLatLng = event.target.getLatLng();
updatePointForm(newLatLng);
reverseGeocode(newLatLng).then(() => {
pointForm.value.name = pointForm.value.address;
keyword.value = pointForm.value.address;
});
});
}
function updatePointForm(latlng) {
pointForm.value.lat = latlng.lat;
pointForm.value.lng = latlng.lng;
}
function submitLocation() {
if (!pointForm.value.address) {
uni.showToast({ title: '请选择一个地址', icon: 'none' });
return;
}
uni.showToast({ title: '提交成功', icon: 'success' });
console.log('提交地址信息:', pointForm.value);
}
function handleInput() {
if (searchDebounce.value) clearTimeout(searchDebounce.value);
searchDebounce.value = setTimeout(() => {
toSearch();
}, 300);
}
function toSearch() {
if (!keyword.value.trim()) {
searchList.value = [];
searchBox.value = false;
return;
}
const url = `https://restapi.amap.com/v3/place/text?key=${gaodeKey}&keywords=${keyword.value}&city=亳州市`;
uni.request({
url,
success: (res) => {
if (res.data.pois && res.data.pois.length > 0) {
searchList.value = res.data.pois.map((poi) => ({
name: poi.name,
address: poi.address,
location: poi.location
}));
searchBox.value = true;
} else {
uni.showToast({ title: '未找到相关地点', icon: 'none' });
}
},
fail: () => {
uni.showToast({ title: '搜索失败,请稍后重试', icon: 'none' });
}
});
}
function centerMap(item) {
const [lng, lat] = item.location.split(',').map(Number);
// 更新地图视图
map.value.flyTo([lat, lng], 17);
// 清除已有标记
if (selectedMarker.value) {
map.value.graphicLayer.removeGraphic(selectedMarker.value);
}
// 添加新标记
selectedMarker.value = new mars2d.graphic.Marker({
latlng: [lat, lng],
style: {
image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
width: 32,
height: 44,
draggable: true
}
});
map.value.graphicLayer.addGraphic(selectedMarker.value);
// 监听拖动事件
selectedMarker.value.on('dragend', (event) => {
const newLatLng = event.target.getLatLng();
updatePointForm(newLatLng);
reverseGeocode(newLatLng).then(() => {
pointForm.value.name = pointForm.value.address;
keyword.value = pointForm.value.address;
});
});
// 设置表单数据
pointForm.value = {
name: item.name,
lat: lat,
lng: lng,
address: item.address
};
// 回写到搜索框
keyword.value = item.name;
// 关闭搜索面板
searchBox.value = false;
// 重新绑定点击事件以确保正常工作
map.value.off('click');
map.value.on('click', (event) => {
selectedMarker.value.setLatLng(event.latlng);
updatePointForm(event.latlng);
reverseGeocode(event.latlng).then(() => {
pointForm.value.name = pointForm.value.address;
keyword.value = pointForm.value.address;
});
});
}
function reverseGeocode(latlng) {
return new Promise((resolve, reject) => {
const url = `https://restapi.amap.com/v3/geocode/regeo?key=${gaodeKey}&location=${latlng.lng},${latlng.lat}`;
uni.request({
url,
success: (res) => {
if (res.data.status === '1') {
pointForm.value.address = res.data.regeocode.formatted_address;
resolve();
} else {
reject();
}
},
fail: () => {
reject();
}
});
});
}
// 初始化地图
// 在onMounted中修改为以下代码
onMounted(async () => {
const route = useRoute();
orderId.value = route.query.orderId;
status.value = route.query.status;
initMap();
if (orderId.value) {
try {
const response = await getEmergencyOrderById(orderId.value);
const orderData = response.data;
const lat = parseFloat(orderData.lat);
const lng = parseFloat(orderData.lon);
// 更新地图中心点和标记
updateMapCenter(lat, lng, orderData.address || '应急工单位置');
} catch (error) {
console.error('获取详情失败:', error);
uni.showToast({ title: '加载工单位置失败', icon: 'none' });
}
}
});
function updateMapCenter(lat, lng, address) {
if (!map.value) return;
// 飞向新位置
map.value.flyTo([lng, lat], 17);
// 清除旧标记
if (selectedMarker.value) {
map.value.graphicLayer.removeGraphic(selectedMarker.value);
}
// 添加新标记
selectedMarker.value = new mars2d.graphic.Marker({
latlng: [lng, lat], // 注意顺序:[经度, 纬度]
style: {
image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
width: 30,
height: 40,
draggable: false
}
});
map.value.graphicLayer.addGraphic(selectedMarker.value);
// 更新表单数据
pointForm.value = {
name: address,
lat: lat,
lng: lng,
address: address
};
keyword.value = address;
}
</script>
<style scoped>
.container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f5f5f5;
}
.navbar-title {
font-family: 'Alimama ShuHeiTi-Bold';
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
color: #fff;
}
.top-container {
width: 100%;
display: flex;
align-items: center;
background-color: #fff;
gap: 20rpx;
padding-left: 30rpx;
padding-right: 20rpx;
}
.top-container image {
width: 45rpx;
height: 45rpx;
}
.search-container {
padding: 20rpx;
flex: 1;
position: relative;
display: flex;
flex-direction: column;
gap: 20rpx;
background-color: #fff;
z-index: 999;
}
.search-input {
width: 100%;
}
.search-results {
position: absolute;
top: 100%;
left: 20rpx;
width: calc(100% - 40rpx);
max-height: 300px;
overflow-y: auto;
background-color: white;
border: 1px solid #ebeef5;
border-radius: 8rpx;
box-shadow: 0 4rpx 24rpx 0 rgba(0, 0, 0, 0.1);
z-index: 1000;
}
.search-item {
padding: 20rpx 30rpx;
cursor: pointer;
border-bottom: 1px solid #ebeef5;
}
.search-item:last-child {
border-bottom: none;
}
.search-item:hover {
background-color: #f5f7fa;
}
.item-name {
font-weight: bold;
margin-bottom: 10rpx;
}
.item-address {
color: #909399;
font-size: 24rpx;
}
.map-container {
width: 100%;
height: 800rpx;
background-color: #e6e6e6;
overflow: hidden;
position: relative;
z-index: 1;
}
.button-container {
padding: 20rpx;
background-color: #fff;
margin-top: 20rpx;
}
.selected-location {
padding: 20rpx;
background-color: #fff;
margin: 20rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.location-item {
margin-bottom: 15rpx;
font-size: 28rpx;
display: flex;
align-items: center;
}
.back-btn {
background-color: #f8f8f8;
color: #333;
position: relative;
}
button[type='primary'] {
margin-left: 20rpx;
}
.label {
font-weight: bold;
width: 120rpx;
color: #666;
}
.form-container {
height: 100%;
padding: 15rpx 20rpx 40rpx 15rpx;
overflow: auto;
background-color: #fff;
}
</style>