Selaa lähdekoodia

配送路线在地图上显示

yang yi 7 kuukautta sitten
vanhempi
sitoutus
83913ffae8

+ 8 - 0
app.json

@@ -15,6 +15,14 @@
     "navigationBarTitleText": "低空药品运输",
     "navigationBarBackgroundColor": "#ffffff"
   },
+  "permission": {
+    "scope.userLocation": {
+      "desc": "您的位置信息将用于显示无人机配送轨迹"
+    }
+  },
+  "requiredPrivateInfos": [
+    "getLocation"
+  ],
   "tabBar": {
     "color": "#7A7E83",
     "selectedColor": "#3cc51f",

BIN
images/drone-marker.png


BIN
images/hospital-marker.png


+ 64 - 1
pages/order-detail/order-detail.js

@@ -1,7 +1,12 @@
 // order-detail.js
 Page({
   data: {
-    order: null
+    order: null,
+    mapCenter: {
+      latitude: 39.9042,
+      longitude: 116.4074
+    },
+    mapScale: 14
   },
 
   onLoad(options) {
@@ -14,6 +19,11 @@ Page({
       this.setData({
         order: order
       })
+
+      // 如果订单有地图数据,设置地图中心点和缩放级别
+      if (order.mapTracking && order.mapTracking.markers) {
+        this.setupMap(order.mapTracking.markers)
+      }
     } else {
       wx.showToast({
         title: '订单不存在',
@@ -25,6 +35,59 @@ Page({
     }
   },
 
+  // 设置地图中心点和缩放级别
+  setupMap(markers) {
+    if (markers.length === 0) return
+
+    // 计算所有标记点的中心点
+    let totalLat = 0
+    let totalLng = 0
+    markers.forEach(marker => {
+      totalLat += marker.latitude
+      totalLng += marker.longitude
+    })
+
+    const centerLat = totalLat / markers.length
+    const centerLng = totalLng / markers.length
+
+    // 计算合适的缩放级别(基于标记点之间的距离)
+    let minLat = Infinity
+    let maxLat = -Infinity
+    let minLng = Infinity
+    let maxLng = -Infinity
+
+    markers.forEach(marker => {
+      minLat = Math.min(minLat, marker.latitude)
+      maxLat = Math.max(maxLat, marker.latitude)
+      minLng = Math.min(minLng, marker.longitude)
+      maxLng = Math.max(maxLng, marker.longitude)
+    })
+
+    const latDiff = maxLat - minLat
+    const lngDiff = maxLng - minLng
+    const maxDiff = Math.max(latDiff, lngDiff)
+
+    // 根据距离设置缩放级别
+    let scale = 14
+    if (maxDiff > 0.01) {
+      scale = 12
+    } else if (maxDiff > 0.005) {
+      scale = 13
+    } else if (maxDiff > 0.002) {
+      scale = 14
+    } else {
+      scale = 15
+    }
+
+    this.setData({
+      mapCenter: {
+        latitude: centerLat,
+        longitude: centerLng
+      },
+      mapScale: scale
+    })
+  },
+
   // 返回上一页
   goBack() {
     wx.navigateBack({

+ 6 - 1
pages/order-detail/order-detail.json

@@ -1,5 +1,10 @@
 {
   "navigationBarTitleText": "订单详情",
   "navigationStyle": "custom",
-  "enablePullDownRefresh": false
+  "enablePullDownRefresh": false,
+  "permission": {
+    "scope.userLocation": {
+      "desc": "您的位置信息将用于显示无人机配送轨迹"
+    }
+  }
 }

+ 38 - 0
pages/order-detail/order-detail.wxml

@@ -109,6 +109,44 @@ module.exports = {
         </view>
       </view>
     </view>
+
+    <!-- 地图显示 -->
+    <view class="map-section" wx:if="{{order.mapTracking}}">
+    1
+      <view class="map-container">
+        <map
+          id="deliveryMap"
+          class="delivery-map"
+          latitude="{{mapCenter.latitude}}"
+          longitude="{{mapCenter.longitude}}"
+          scale="{{mapScale}}"
+          markers="{{order.mapTracking.markers}}"
+          polyline="{{order.mapTracking.polyline}}"
+          show-location="{{true}}"
+          enable-3D="{{true}}"
+          show-compass="{{true}}"
+          enable-overlooking="{{true}}"
+          enable-zoom="{{true}}"
+          enable-scroll="{{true}}"
+          enable-rotate="{{true}}"
+        >
+        </map>
+      </view>
+      <view class="map-legend">
+        <view class="legend-item">
+          <view class="legend-icon hospital"></view>
+          <text class="legend-text">医院位置</text>
+        </view>
+        <view class="legend-item">
+          <view class="legend-icon drone"></view>
+          <text class="legend-text">无人机位置</text>
+        </view>
+        <view class="legend-item">
+          <view class="legend-icon route"></view>
+          <text class="legend-text">配送路线</text>
+        </view>
+      </view>
+    </view>
   </view>
 
   <!-- 操作按钮 -->

+ 62 - 0
pages/order-detail/order-detail.wxss

@@ -265,6 +265,68 @@
   color: #333;
 }
 
+/* 地图样式 */
+.map-section {
+  margin-top: 30rpx;
+}
+
+.map-container {
+  border-radius: 15rpx;
+  overflow: hidden;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
+  background: #f0f0f0;
+  min-height: 400rpx;
+}
+
+.delivery-map {
+  width: 100%;
+  height: 400rpx;
+  display: block;
+}
+
+.map-legend {
+  display: flex;
+  justify-content: space-around;
+  margin-top: 20rpx;
+  padding: 20rpx;
+  background: #f8f8f8;
+  border-radius: 10rpx;
+}
+
+.legend-item {
+  display: flex;
+  align-items: center;
+}
+
+.legend-icon {
+  width: 24rpx;
+  height: 24rpx;
+  border-radius: 50%;
+  margin-right: 10rpx;
+}
+
+.legend-icon.hospital {
+  background: #ff4d4f;
+  border: 2rpx solid #ff4d4f;
+}
+
+.legend-icon.drone {
+  background: #007AFF;
+  border: 2rpx solid #007AFF;
+}
+
+.legend-icon.route {
+  width: 40rpx;
+  height: 4rpx;
+  background: #007AFF;
+  border-radius: 2rpx;
+}
+
+.legend-text {
+  font-size: 24rpx;
+  color: #666;
+}
+
 .action-section {
   background: white;
   padding: 30rpx;

+ 68 - 2
pages/order/order.js

@@ -164,6 +164,10 @@ Page({
       return
     }
 
+    // 根据医院生成地图轨迹数据
+    const hospitalLocation = this.getHospitalLocation(this.data.selectedHospital.name)
+    const mapTracking = this.generateMapTracking(hospitalLocation)
+
     // 创建订单数据
     const order = {
       id: Date.now(),
@@ -175,7 +179,8 @@ Page({
       droneTracking: {
         status: '配送中',
         steps: ['订单确认', '药品准备', '无人机起飞', '配送中', '待送达']
-      }
+      },
+      mapTracking: mapTracking
     }
 
     // 保存订单到全局变量和本地存储
@@ -199,6 +204,62 @@ Page({
     })
   },
 
+  // 获取医院位置
+  getHospitalLocation(hospitalName) {
+    const locations = {
+      '北京协和医院': { latitude: 39.9139, longitude: 116.3917 },
+      '上海瑞金医院': { latitude: 31.2304, longitude: 121.4737 },
+      '广州中山医院': { latitude: 23.1291, longitude: 113.2644 }
+    }
+    return locations[hospitalName] || { latitude: 39.9042, longitude: 116.4074 }
+  },
+
+  // 生成地图轨迹数据
+  generateMapTracking(hospitalLocation) {
+    const points = []
+    const numPoints = 5
+    
+    for (let i = 0; i < numPoints; i++) {
+      const latOffset = (i * 0.004) / numPoints
+      const lngOffset = (i * 0.007) / numPoints
+      points.push({
+        latitude: hospitalLocation.latitude + latOffset,
+        longitude: hospitalLocation.longitude + lngOffset
+      })
+    }
+
+    return {
+      polyline: [
+        {
+          points: points,
+          color: '#007AFF',
+          width: 4,
+          dottedLine: false
+        }
+      ],
+      markers: [
+        {
+          id: 1,
+          latitude: hospitalLocation.latitude,
+          longitude: hospitalLocation.longitude,
+          iconPath: '/images/hospital-marker.png',
+          width: 30,
+          height: 30,
+          title: '医院位置'
+        },
+        {
+          id: 2,
+          latitude: points[points.length - 1].latitude,
+          longitude: points[points.length - 1].longitude,
+          iconPath: '/images/drone-marker.png',
+          width: 30,
+          height: 30,
+          title: '无人机位置'
+        }
+      ]
+    }
+  },
+
   // 选择热门药品
   selectHotMedicine(e) {
     const medicineName = e.currentTarget.dataset.medicine
@@ -223,6 +284,10 @@ Page({
       content: `确认在${priceInfo.hospital}购买${medicineName},价格:¥${priceInfo.price}`,
       success: (res) => {
         if (res.confirm) {
+          // 根据医院生成地图轨迹数据
+          const hospitalLocation = this.getHospitalLocation(priceInfo.hospital)
+          const mapTracking = this.generateMapTracking(hospitalLocation)
+
           // 创建订单数据
           const order = {
             id: Date.now(),
@@ -234,7 +299,8 @@ Page({
             droneTracking: {
               status: '配送中',
               steps: ['订单确认', '药品准备', '无人机起飞', '配送中', '待送达']
-            }
+            },
+            mapTracking: mapTracking
           }
 
           // 保存订单到全局变量和本地存储

+ 71 - 0
utils/mockData.js

@@ -204,6 +204,42 @@ const mockData = {
       droneTracking: {
         status: "已送达",
         steps: ["订单确认", "药品准备", "无人机起飞", "配送中", "已送达"]
+      },
+      mapTracking: {
+        polyline: [
+          {
+            points: [
+              { latitude: 39.9139, longitude: 116.3917 },
+              { latitude: 39.9150, longitude: 116.3930 },
+              { latitude: 39.9160, longitude: 116.3950 },
+              { latitude: 39.9170, longitude: 116.3970 },
+              { latitude: 39.9180, longitude: 116.3990 }
+            ],
+            color: "#007AFF",
+            width: 4,
+            dottedLine: false
+          }
+        ],
+        markers: [
+          {
+            id: 1,
+            latitude: 39.9139,
+            longitude: 116.3917,
+            iconPath: "/images/hospital-marker.png",
+            width: 30,
+            height: 30,
+            title: "北京协和医院"
+          },
+          {
+            id: 2,
+            latitude: 39.9180,
+            longitude: 116.3990,
+            iconPath: "/images/drone-marker.png",
+            width: 30,
+            height: 30,
+            title: "配送位置"
+          }
+        ]
       }
     },
     {
@@ -216,6 +252,41 @@ const mockData = {
       droneTracking: {
         status: "配送中",
         steps: ["订单确认", "药品准备", "无人机起飞", "配送中", "待送达"]
+      },
+      mapTracking: {
+        polyline: [
+          {
+            points: [
+              { latitude: 31.2304, longitude: 121.4737 },
+              { latitude: 31.2320, longitude: 121.4750 },
+              { latitude: 31.2330, longitude: 121.4770 },
+              { latitude: 31.2340, longitude: 121.4790 }
+            ],
+            color: "#007AFF",
+            width: 4,
+            dottedLine: false
+          }
+        ],
+        markers: [
+          {
+            id: 1,
+            latitude: 31.2304,
+            longitude: 121.4737,
+            iconPath: "/images/hospital-marker.png",
+            width: 30,
+            height: 30,
+            title: "上海瑞金医院"
+          },
+          {
+            id: 2,
+            latitude: 31.2340,
+            longitude: 121.4790,
+            iconPath: "/images/drone-marker.png",
+            width: 30,
+            height: 30,
+            title: "无人机位置"
+          }
+        ]
       }
     }
   ],