cuiqian2004
2025-10-10 55fb3b56398be972b7e961ccf82970ece8739e64
pages/map/scene.vue
@@ -1,15 +1,18 @@
<template>
   <view class="pages-scene">
      <view class="map-content" v-if="opSceneType =='' ">
         <image class="img" src="/images/image 25.png" alt=" 图片" mode="aspectFit" />
         <view class="space">没有找到符合条件的地图</view>
         <image v-if="opType != 'extend'" class="img" src="/images/image_25.png" alt=" 图片" mode="aspectFit" />
         <image v-else class="img" :src="extendBase64Img" alt=" 图片" mode="aspectFit" />
         <view v-if="opType != 'extend'" class="space">没有找到符合条件的地图</view>
         <!-- <view class="loading-view">{{mapserverIsOk?"构图程序准备就绪":"等待构图程序就绪..."}}
            <view v-if="!mapserverIsOk" class="auto-circle"></view>:disabled="!mapserverIsOk"
         </view> -->
         <view class="text-button-group">
            <a-button type="primary" class="button" @click="clickStartConstructScene">
               开始构建
               {{opType == 'extend'?"开始扩展":'开始构建'}}
            </a-button>
            <a-button type="primary" class="button" :disabled="loading && localSceneList.length == 0"
               @click="clickDownloadScene" disabled>
            <a-button v-if="opType != 'extend'" type="primary" class="button"
               :disabled="loading && localSceneList.length == 0" @click="clickDownloadScene" disabled>
               下载场景
            </a-button>
         </view>
@@ -17,13 +20,16 @@
      </view>
      <view class="content" v-show="opSceneType =='scan'">
         <view class="fabric" :message="ctxDataStr" :change:message="ctx.receiveMsg" id="canvasMap"></view>
         <view class="position" @click="clickVehiclePosition">
            <text class="ico my-location-rounded"></text>
         </view>
      </view>
      <view class="bottom">
         <view class="bottom-content" v-if="opSceneType =='add_name' ">
            <view class="tip">请输入场景名称</view>
            <view class="name-input">
               <input ref="refInputName" :focus="true" placeholder="请输入场景名称" :value="sceneName"
                  @input="onInputName"></input>
                  @input="onInputName" />
               <uni-icons class="clear" color="#ccc" type="clear" size="20" v-if="showClearName"
                  @click="clickClearName"></uni-icons>
            </view>
@@ -45,13 +51,13 @@
            </view>
         </view>
         <view class="bottom-content" v-else-if="opSceneType =='finish'">
            <view class="tip">场景构建完成</view>
            <view>
               已成功构建“{{sceneName}}”
            <view class="tip"> “{{sceneName}}”{{opType == "extend"?"场景扩展完成"+"":"场景构建完成"}}</view>
         <!--    <view> 已成功构建“{{sceneName}}”</view> -->
            <view class="loading-view">{{saveMapIsOk?"构图保存完成":"等待构图保存完成..."}}
               <view v-if="!saveMapIsOk" class="auto-circle"></view>
            </view>
            <view class="text-button-group">
               <a-button type="primary" class="button" :disabled="loading" @click="clickFinish">构建完成</a-button>
               <a-button type="primary" class="button" :disabled=" !saveMapIsOk || loading" @click="clickFinish">{{opType == "extend"?"扩展完成":"构建完成"}}</a-button>
            </view>
         </view>
      </view>
@@ -64,6 +70,8 @@
      showToast,
      showModal,
      session,
      showError,
      showInfo
   } from "@/comm/utils.js"
   import {
      Button
@@ -76,6 +84,11 @@
      //getAgvState,
      getMapLaserData,
      saveDBData,
      checkMapServerIsStart,
      startOrStopMapServer,
      checkMapServerIsOk,
      checkSaveMapIsOk,
      getMapUrl
   } from "@/api/vehicle.js"
   export default {
@@ -94,7 +107,13 @@
            showClearName: false,
            mapId: "",
            ctxDataStr: "[]",
            localSceneList: []
            localSceneList: [],
            positioningAgv: true,
            robotPos: {},
            mapserverIsOk: false,
            extendBase64Img: "",
            saveMapIsOk: false,
            destroyFlag: false,
         }
      },
@@ -105,6 +124,7 @@
      },
      onLoad(option) {
         console.log("scene load")
         const _this = this
         this.ip = option.ip || ""
         uni.getSystemInfo({
@@ -120,7 +140,7 @@
      },
      onUnload() {
         console.log("scene unload")
      },
      onBackPress() {
@@ -130,6 +150,7 @@
               if (res) {
                  this.opSceneType = ""
                  if (this.opType != "") {
                     uni.navigateBack({
                        delta: 1, //返回层数,2则上上页
                     })
@@ -139,8 +160,28 @@
            })
            return true
         } else if (this.opSceneType == "finish") {
            if (this.destroyFlag) {
               const eventChannel = this.getOpenerEventChannel();
               eventChannel.emit('create_finish', this.sceneName);
               return false
            } else {
               this.ctxDataStr = JSON.stringify([{
                  method: "destroy",
               }])
               return true
            }
         } else {
            return false
            if (this.destroyFlag)
               return false
            else {
               this.ctxDataStr = JSON.stringify([{
                  method: "destroy",
               }])
               return true
            }
         }
      },
@@ -169,6 +210,7 @@
         async loadData() {
            try {
               // this.loadMapServerState()
               if (this.opType == "") {
                  this.localSceneList = await this.loadLocalScene()
               } else {
@@ -179,19 +221,103 @@
                     await addMap(this.ip, this.sceneName, "extend")
                     this.opSceneType = 'scan'
                  }
               }
                  // if (this.opType == "extend") {
                  //    // const infoMap = await this.loadMapInfo(this.sceneName)
                  //    // if (infoMap.filedata) {
                  //    //    var base64Image = infoMap.filedata
                  //    //    if (base64Image.indexOf("data:image/png;base64,") < 0) {
                  //    //       base64Image = "data:image/png;base64," + infoMap.filedata
                  //    //    }
                  //    //    this.extendBase64Img = base64Image
                  //    // }
                  // }
               }
               this.refreshMapLaserData()
            } catch (ex) {
               this.showError(ex)
               showError(ex)
            }
         },
         async loadMapInfo(id) {
            try {
               const info = await getMapUrl(this.ip, id)
               return info
            } catch (ex) {
               return {}
            }
         },
         async loadMapServerState() {
            try {
               this.mapserverIsOk = false
               const res = await checkMapServerIsStart(this.ip)
               if (res) {
                  this.mapserverIsOk = true
               } else {
                  this.mapserverIsOk = false
                  const res = await startOrStopMapServer(this.ip, 1)
                  if (res) {
                     this.checkMapServerState()
                  }
               }
            } catch (ex) {
               showError(ex)
            }
         },
         async checkMapServerState() {
            try {
               const res = await checkMapServerIsOk(this.ip)
               if (res) {
                  this.mapserverIsOk = true
               } else {
                  this.mapserverIsOk = false
                  setTimeout(this.checkMapServerState, 1000);
               }
            } catch (ex) {
               showError(ex).then((res) => {
                  setTimeout(this.checkMapServerState, 1000);
               })
            }
         },
         async checkSaveMapState() {
            try {
               const res = await checkSaveMapIsOk(this.ip)
               if (res) {
                  this.saveMapIsOk = true
               } else {
                  this.saveMapIsOk = false
                  setTimeout(this.checkSaveMapState, 1000);
               }
            } catch (ex) {
               showError(ex).then((res) => {
                  setTimeout(this.checkSaveMapState, 1000);
               })
            }
         },
         receiveRenderData(param) {
            console.log('接收到视图层的数据:', param);
            if (param.method == "set_backgroud_progress") {
            if (param.method === "destroy_complete") {
               if (param.param) {
                  this.destroyFlag = true
                  uni.navigateBack({
                     delta: 1
                  })
               }
            } else if (param.method == "set_backgroud_progress") {
               if (param.type == "start") {
                  this.setData({
                     bgProgressPercent: 50,
@@ -213,12 +339,34 @@
                  }, 500)
               } else if (param.type == "error") {
                  console.log("set_backgroud_progress error")
                  this.setData({
                     bgProgressPercent: 0,
                     bgLoading: false
                  })
                  const now = new Date()
                  const date = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`
                  showToast("加载底图失败")
                  const log = {
                     date,
                     method: `POST`,
                     url: "app/log/load_img",
                     param: param.msg,
                     statusCode: 100,
                     data: "加载底图失败"
                  }
                  const listLog = session.getValue("request_log") || []
                  listLog.unshift(log)
                  session.setValue("request_log", listLog)
               }
            } else if (param.method == "cancel_positioning_agv") {
               //this.positioningAgv = false
            } else if (param.method == "show_log") {
               const listLog = session.getValue("request_log") || []
               listLog.unshift(param.data)
               session.setValue("request_log", listLog)
            }
         },
@@ -227,12 +375,22 @@
               const list = session.getValue("scene_db") || []
               return list
            } catch (ex) {
               this.showError(ex)
               showError(ex)
               return []
            }
         },
         clickStartConstructScene() {
            this.opSceneType = "add_name"
         async clickStartConstructScene() {
            try {
               this.mapId = ""
               if (this.opType == "extend") {
                  await addMap(this.ip, this.sceneName, "extend")
                  this.opSceneType = 'scan'
               } else {
                  this.opSceneType = "add_name"
               }
            } catch (ex) {
               showError(ex)
            }
         },
         async clickDownloadScene() {
            try {
@@ -250,7 +408,7 @@
                  delta: 1, //返回层数,2则上上页
               })
            } catch (ex) {
               this.showError(ex)
               showError(ex)
            } finally {
               this.loading = false
               uni.hideLoading()
@@ -282,11 +440,12 @@
               uni.showLoading({
                  title: "开始扫描地图"
               })
               this.mapId = ""
               this.opSceneType = 'scan'
            } catch (ex) {
               this.showError(ex)
               showError(ex)
               this.opSceneType = 'add_name'
            } finally {
               this.loading = false
@@ -315,25 +474,25 @@
               uni.setNavigationBarTitle({
                  title: this.sceneName
               })
               this.saveMapIsOk = false
               await stopMap(this.ip, this.sceneName)
               if (this.opType == "extend") {
                  this.opSceneType = ""
                  const eventChannel = this.getOpenerEventChannel();
                  eventChannel.emit('create_finish', this.sceneName);
                  uni.navigateBack({
                     delta: 1, //返回层数,2则上上页
                  })
               }
               // await startOrStopMapServer(this.ip, 2)
               // this.checkSaveMapState();
               // if (this.opType == "extend") {
               //    this.opSceneType = ""
               //    const eventChannel = this.getOpenerEventChannel();
               //    eventChannel.emit('create_finish', this.sceneName);
               //    uni.navigateBack({
               //       delta: 1, //返回层数,2则上上页
               //    })
               // }
               setTimeout(() => {this.saveMapIsOk = true}, 5000);
            } catch (ex) {
               console.log(ex)
               showModal("请检查车辆连接,并重新开始构建场景", "场景构建失败", false, "确定").then((res) => {
                  this.opSceneType = ''
                  if (this.opType != "") {
                     uni.navigateBack({
                        delta: 1, //返回层数,2则上上页
                     })
                  }
                  // this.loadMapServerState()
               })
            } finally {
               this.loading = false
@@ -349,21 +508,13 @@
                  title: "结束场景构建"
               })
               this.opSceneType = ""
               await createScene(this.ip, this.sceneName, 0)
               const eventChannel = this.getOpenerEventChannel();
               eventChannel.emit('create_finish', this.sceneName);
               uni.navigateBack({
                  delta: 1, //返回层数,2则上上页
               })
            } catch (ex) {
               showModal("请检查车辆连接,并重新开始构建场景", "场景构建失败", false, "确定").then((res) => {
                  this.opSceneType = ''
                  if (this.opType != "") {
                     uni.navigateBack({
                        delta: 1, //返回层数,2则上上页
                     })
                  }
               })
               console.log(ex)
            } finally {
               this.loading = false
               uni.hideLoading()
@@ -376,7 +527,7 @@
               const info = await getMapLaserData(this.ip, this.mapId)
               return info
            } catch (ex) {
               this.showError(ex)
               showToast(ex)
               return {}
            }
         },
@@ -387,66 +538,92 @@
                  const data = await this.loadMapLaserData()
                  const listCtrData = []
                  let newMap = false
                  if (data.base_map?.image_base64) {
                     this.robotPos = {}
                     newMap = true
                     const mapData = data.base_map.image_base64 //this.mapId ?"terdy":
                     this.mapId = data.base_map.map_id
                     listCtrData.push({
                        method: "background",
                        param: {
                           proportion: 1,
                           img_proportion: 1,
                           max_x: data.base_map.width,
                           max_y: data.base_map.height,
                           max_x: data.base_map.width || 100,
                           max_y: data.base_map.height || 100,
                           min_x: 0,
                           min_y: 0,
                           img_x: data.base_map.width,
                           img_y: data.base_map.height,
                           filedata: data.base_map.image_base64
                        }
                     })
                     listCtrData.push({
                        method: "agv_laser",
                        param: data.robot_pose
                     })
                     listCtrData.push({
                        method: "point_cloud",
                        param: data.point_cloud
                     })
                     listCtrData.push({
                        method: "move_canvas",
                        param: {
                           x: data.robot_pose.x,
                           y: data.robot_pose.y
                           img_x: data.base_map.width || 100,
                           img_y: data.base_map.height || 100,
                           filedata: mapData
                        }
                     })
                  } else {
                  }
                  listCtrData.push({
                     method: "point_cloud",
                     param: data.point_cloud
                  })
                  if (data.robot_pose) {
                     listCtrData.push({
                        method: "agv_laser",
                        param: data.robot_pose
                     })
                     listCtrData.push({
                        method: "point_cloud",
                        param: data.point_cloud
                     })
                     if (newMap) {
                        listCtrData.push({
                           method: "move_pt_center",
                           param: {
                              x: data.robot_pose.x,
                              y: data.robot_pose.y,
                           }
                        })
                     } else {
                        if (this.positioningAgv) {
                           listCtrData.push({
                              method: "move_pt_visible",
                              param: {
                                 x: data.robot_pose.x,
                                 y: data.robot_pose.y,
                                 width: 50,
                                 height: 50,
                              }
                           })
                        }
                     }
                  }
                  // console.log("ctxDataStr",listCtrData.length)
                  this.ctxDataStr = JSON.stringify(listCtrData)
                  if (data.robot_pose) {
                     this.robotPos = {
                        x: data.robot_pose.x,
                        y: data.robot_pose.y
                     }
                  }
               }
               setTimeout(this.refreshMapLaserData, 1000);
            } catch (ex) {
               this.showError(ex)
            } finally {
               // 无论成功失败,1 秒后再来
               showToast(ex)
               setTimeout(this.refreshMapLaserData, 1000);
            }
         },
         async clickVehiclePosition() {
            this.positioningAgv = true
         showError(ex) {
            console.log(ex)
            let exStr = JSON.stringify(ex)
            if (exStr == "{}")
               exStr = ex
            let tip = typeof ex.msg == "string" ? ex.msg : exStr
            showModal(tip, "错误", false, "确定")
            if (this.robotPos.x) {
               this.ctxDataStr = JSON.stringify([{
                  method: "move_pt_center",
                  param: {
                     x: this.robotPos.x,
                     y: this.robotPos.y
                  }
               }])
            }
         },
@@ -475,6 +652,16 @@
            background-color: #fff;
         }
         .position {
            position: absolute;
            right: 50rpx;
            bottom: 500rpx;
            .ico {
               font-size: 65rpx;
               color: #1890FF;
            }
         }
      }
@@ -488,6 +675,7 @@
         justify-content: center;
         .text-button-group {
            display: flex;
            width: 100%;
@@ -504,6 +692,32 @@
      }
      .loading-view {
         display: flex;
         flex-direction: row;
         .auto-circle {
            margin-left: 20rpx;
            width: 50rpx;
            height: 50rpx;
            border-radius: 50%;
            border: 10rpx solid #1890FF;
            border-top-color: transparent;
            animation: drawCircle 1s infinite linear;
         }
         @keyframes drawCircle {
            0% {
               transform: rotate(0deg);
            }
            100% {
               transform: rotate(360deg);
            }
         }
      }
      .bottom {
         position: fixed;