cuiqian2004
4 天以前 2af5f043b60c1f7ac38ecccc8f5bf44743134325
pages/index/index.vue
@@ -1,6 +1,6 @@
<template>
   <view class="pages-main">
      <uni-nav-bar :fixed="true" status-bar right-text="" left-text="" :leftWidth="0" rightWidth="72px"
      <uni-nav-bar :fixed="true" status-bar right-text="" left-text="" :leftWidth="0" rightWidth="150rpx"
         :title="navigationBarTitle">
         <view class="uni-navbar-container-inner">
            <text class="uni-nav-bar-text">{{navigationBarTitle }}</text>
@@ -24,14 +24,14 @@
               <view class="vehicle-header">
                  <view class="link-view">
                     <view v-if="page.link_status">
                        <!-- <image class="img-battery-charging" src="/images/bx_battery3.svg" alt="SVG 图片" /> -->
                        <image class="img-battery-charging" src="/images/bx_battery2.svg" alt="SVG 图片" />
                     <!-- <image class="img-battery-charging" src="/images/bx_battery3.svg" alt="SVG" /> -->
                     <image class="img-battery-charging" src="/images/bx_battery2.svg" alt="SVG" />
                        <image class="img-battery-soc" :style="{width:(page.soc*0.4)+'rpx'}"
                           src="/images/bx_battery4.svg" alt="SVG 图片" />
                        src="/images/bx_battery4.svg" alt="SVG" />
                     </view>
                     <view v-else>
                        <image class="img-battery" src="/images/bx_battery1.svg" alt="SVG 图片" />
                     <image class="img-battery" src="/images/bx_battery1.svg" alt="SVG" />
                     </view>
                     <template v-if="page.link_status">
                        <view class="soc-text">{{page.soc}}%</view>
@@ -39,35 +39,39 @@
                     </template>
                     <view v-else class="gray-text">已离线</view>
                  <view v-else class="gray-text">{{translate('offline')}}</view>
                  </view>
               </view>
               <image class="vehicle-img " :class="page.link_status ?'':'gray-image'" mode="aspectFit"
                  src="/images/che.png" alt="图片" />
               src="/images/che.png" alt="picture" />
               <view v-if="page.link_status" class="img-button-group">
                  <view type="primary" plain="true" class="img-text-button" @click="clickToMap(index,page)">
                     <a-button class="img-button" color='primary'>
                        <text class="ico map" />
                     </a-button>
                     <text>场景构建</text>
                  <text>{{translate('scenes')}}</text>
                  </view>
                  <view type="primary" class="img-text-button" @click="clickToTask(page)">
               <navigator :url="`/pages/task/log-list?ip=${page.ip}`" hover-class="other-navigator-hover">
                  <view type="primary" class="img-text-button">
                     <a-button class="img-button" color='primary'>
                        <text class="ico task-list" />
                     </a-button>
                     <text>任务记录</text>
                     <text>{{translate('tasks')}}</text>
                  </view>
               </navigator>
               </view>
               <view v-else class="unlink-content">
                  <view class="content2" v-if="page.conntecting">
                     <view class="auto-circle"></view>
                     <view class="text">连接中...</view>
                  <view class="text">{{translate('connecting')}}...</view>
                  </view>
                  <view class="content2" v-else>
                     <view class="text"> 车辆已离线,请重新连接</view>
                     <a-button type="primary" class="button" @click="clickRelink">重新连接
                  <view class="text">{{translate('vehicle_offline_to_reconnect')}}</view>
                  <a-button type="primary" class="button" @click="clickRelink">{{translate('reconnect')}}
                     </a-button>
                  </view>
@@ -76,26 +80,31 @@
         </swiper-item>
            <swiper-item class="swiper-item">
            <image class="title-img gray-image" src="/images/image_15.png" alt="图片" />
            <image class="title-img gray-image" src="/images/image_15.png" alt="picture" />
            <view class="button-group">
               <a-button type="primary" class="button" @click="clickScanCode">扫描添加设备</a-button>
               <a-button type="ghost" class="button" @click="clickManualAdd">手动添加设备</a-button>
               <a-button type="primary" class="button"
                  @click="clickScanCode">{{translate('scan_add_device')}}</a-button>
               <a-button type="ghost" class="button"
                  @click="clickManualAdd">{{translate('manual_add_device')}}</a-button>
            </view>
         </swiper-item>
      </swiper>
      <view v-else class="no-page items-center">
         <view class="content ">
            <image class="title-img gray-image" src="/images/image_15.png" alt="图片" />
            <image class="title-img gray-image" src="/images/image_15.png" alt="picture" />
            <view class="button-group">
               <a-button type="primary" class="button" @click="clickScanCode">扫描添加设备</a-button>
               <a-button type="ghost" class="button" @click="clickManualAdd">手动添加设备</a-button>
               <a-button type="primary" class="button"
                  @click="clickScanCode">{{translate('scan_add_device')}}</a-button>
               <a-button type="ghost" class="button"
                  @click="clickManualAdd">{{translate('manual_add_device')}}</a-button>
            </view>
         </view>
      </view>
      <view>
         <uni-popup ref="refPopupInput" type="dialog">
            <uni-popup-dialog mode="input" title="输入车辆IP" :value="inputPopupValue" placeholder="车辆IP"
               :beforeClose="true" @confirm="dialogInputConfirm" @close="dialogInputClose"></uni-popup-dialog>
            <uni-popup-dialog mode="input" :title="translate('connect_device')" :value="inputPopupValue"
               :placeholder="translate('input_vehicle_ip')" :beforeClose="true" @confirm="dialogInputConfirm"
               @close="dialogInputClose"></uni-popup-dialog>
         </uni-popup>
         <!--       <uni-popup ref="refPopupMessage" type="dialog">
            <uni-popup-dialog type="info" title="" :content="inputPopupValue" 
@@ -107,7 +116,9 @@
                  <a-button class="popup-content-menu-item" v-for="(item,index) in menuList" :key="index"
                     @click="menuItemChange(item)" :style="{'color':item.color}">
                     <view class="text">{{item.text}}</view>
                     <text class="ico" :class="item.ico" />
                     <view v-if="item.id=='update' && newCarVersion" class="new" />
                     <view class="ico" :class="item.ico" />
                     <uni-icons :type="item.ico" size="20"></uni-icons>
                  </a-button>
               </view>
            </view>
@@ -125,20 +136,20 @@
      showToast,
      showModal,
      showError,
      showInfo
      showInfo,
   } from "@/comm/utils.js"
   import TaskInit from "@/comm/extend.js"
   import {
      getAllScene,
      mtBattery,
      getAgvState,
      checkIpLinkSuccess,
      getShellVersion
   } from "@/api/vehicle.js"
   import {
      Button
   } from 'antd-mobile-vue-next'
   import {
      async
   } from "rxjs";
   export default {
      name: "PagesMain",
      components: {
@@ -152,30 +163,50 @@
            timerBatteryId: 0,
            inputPopupValue: "",
            menuList: [{
                  id: "edit",
               ico: "edit-line",
               text: "编辑",
                  text: this.translate('edit'),
               color: "black"
            }, {
               },
               {
                  id: "update",
               ico: "update",
               text: "更新",
                  text: this.translate('update'),
               color: "black"
            }, {
               ico: "book",
               text: "教程",
               color: "black"
            }, {
               ico: "share",
               text: "共享",
               color: "black"
            }, {
               },
               {
                  id: "error",
                  ico: "info",
                  text: this.translate('errors'),
                  color: "black",
               },
               // {
               //   id: "tutorial",
               //    ico: "book",
               //    text: this.translate('tutorial'),
               //    color: "black"
               // },
               // {
               //   id: "share",
               //    ico: "share",
               //    text: this.translate('share'),
               //    color: "black"
               // },
               {
                  id: "backup",
               ico: "copy",
               text: "备份",
                  text: this.translate('backup'),
               color: "black"
            }, {
               },
               {
                  id: "remove",
               ico: "delete-outline",
               text: "删除",
                  text: this.translate('remove'),
               color: "red"
            }]
               }
            ]
         }
      },
@@ -201,14 +232,18 @@
      onLoad(option) {
         const ip = option.connectedIp || ""
         this.loadData(ip)
         console.log("hide")
      },
      computed: {
         tabList() {
            return [...this.pageList, {
               ip: ""
            }]
         },
         newCarVersion() {
            const page = this.pageList[this.currentPage]
            return page?.newVer || false
         }
      },
      methods: {
@@ -236,7 +271,7 @@
         async loadData(ip) {
            try {
               this.loadCarSaveVersion()
               let list = session.getValue("vehicles") || []
               list.forEach((page) => {
@@ -252,7 +287,7 @@
                  if (this.pageList.length > 0)
                     this.navigationBarTitle = this.pageList[0].name
                  else
                     this.navigationBarTitle = "添加设备"
                     this.navigationBarTitle = ""
                  for (let i in list) {
                     const page = list[i]
                     const battery = await this.loadMTBattery(page.ip)
@@ -260,6 +295,7 @@
                        page.soc = battery
                        page.status = await this.loadAgvState(page.ip)
                        page.link_status = true
                        page.newVer = await this.checkServerVersion(page.ip)
                        this.setData({
                           currentPage: i
                        })
@@ -280,6 +316,7 @@
                     page.soc = battery
                     page.link_status = true
                     page.status = await this.loadAgvState(page.ip)
                     page.newVer = await this.checkServerVersion(page.ip)
                  } else {
                     page.link_status = false
                  }
@@ -289,7 +326,7 @@
               }
            } catch (ex) {
               showError(ex)
               showError(ex, this.translate('error'))
            }
         },
@@ -303,6 +340,7 @@
                  if (battery > -1) {
                     page.soc = battery
                     page.status = await this.loadAgvState(page.ip)
                     page.newVer = await this.checkServerVersion(page.ip)
                     page.link_status = true
                  } else {
@@ -315,7 +353,7 @@
               // this.pageList = [...list]
            } catch (ex) {
               // showError(ex)
               // showError(ex,this.translate('error'))
               showToast(ex)
            }
@@ -349,13 +387,13 @@
         getAgvStateText(page) {
            let text = ""
            if (page.status == 1) {
               text = "空闲中"
               text = this.translate('idle')
            } else if (page.status == 2) {
               text = "工作中"
               text = this.translate('at_work')
            } else if (page.status == 3) {
               text = "故障"
               text = this.translate('fault')
            } else {
               text = `状态${page.status}`
               text = `${this.translate('state')}:${page.status}`
            }
            return text
         },
@@ -368,6 +406,7 @@
                  page.soc = battery
                  page.link_status = true
                  page.status = await this.loadAgvState(page.ip)
                  page.newVer = await this.checkServerVersion(page.ip)
               } else {
                  page.link_status = false
               }
@@ -385,7 +424,7 @@
               currentPage: index
            })
            if (this.pageList.length == this.currentPage)
               this.navigationBarTitle = "添加设备"
               this.navigationBarTitle = ""
            else
               this.navigationBarTitle = this.pageList[this.currentPage].name
            this.loadVehicleBattery()
@@ -416,13 +455,14 @@
                     page.soc = battery
                     page.link_status = true
                     page.status = await this.loadAgvState(page.ip)
                     page.newVer = await this.checkServerVersion(page.ip)
                     this.setData({
                        pageList: list
                     })
                  }
               }
            } catch (ex) {
               showError(ex)
               showError(ex, this.translate('error'))
            }
         },
         async checkConnectSuccess(ip) {
@@ -445,25 +485,28 @@
                  const result = res.result || ""
                  const arCode = result.split(";")
                  if (arCode.length != 3) {
                     showToast("无效的二维码!")
                     showToast(this.translate("invalid_qr_code"))
                     return
                  }
                  let ip = arCode[0].trim()
                  if (!ip || !arCode[0].trim()) {
                     showToast("无效的二维码!")
                     showToast(this.translate("invalid_qr_code"))
                     return
                  }
                  const curIndex = that.pageList.findIndex((a) => a.ip == ip)
                  if (curIndex < 0) {
                     if (that.pageList.length === 3) {
                        showToast("对多只允许添加3辆车!")
                        showToast(this.translate("only_3_vehicles_to_added"))
                        return
                     }
                     uni.navigateTo({
                        url: `/pages/index/connect?ip=${ ip}&sid=${ arCode[1]}&password=${ arCode[2]}`
                     })
                  } else {
                     showToast("不允许添加相同IP的设备!")
                     showToast(this.translate('vehicle_ip_has_added'))
                     this.setData({
                        currentPage: curIndex
                     })
                  }
               },
            })
@@ -471,6 +514,18 @@
         },
         clickManualAdd() {
            this.inputPopupValue = ""
            // const _this = this
            // uni.showModal({
            //    title: this.translate('connect_device'),
            //    showCancel: true,
            //    editable: true,
            //    placeholderText:this.translate('input_vehicle_ip'),
            //    success: function(res) {
            //       if (res.confirm) {
            //          _this.dialogInputConfirm(res.content)
            //       }
            //    }
            // });
            this.$refs.refPopupInput.open()
         },
@@ -486,7 +541,7 @@
               url: `/pages/index/detail?param=${JSON.stringify(page)}`,
               events: {
                  // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
                  delete_vehicle: function(data) {
                  remove_vehicle: function(data) {
                     const list = that.pageList
                     const index = that.currentPage
                     list.splice(index, 1)
@@ -551,15 +606,8 @@
                  }
               })
            } catch (ex) {
               showError(ex)
               showError(ex, this.translate('error'))
            }
         },
         clickToTask(page) {
            uni.navigateTo({
               url: `/pages/task/log-list?ip=${page.ip}`
            })
         },
         isValidIP(ip) {
@@ -574,12 +622,12 @@
            let text = val.trim()
            if (!text) {
               showToast("请输入车辆IP!")
               showToast(this.translate('input_vehicle_ip'))
               this.$refs.refPopupInput.open()
               return
            }
            if (!this.isValidIP(text)) {
               showToast("IP无效!")
               showToast(this.translate('invalid_ip'))
               this.$refs.refPopupInput.open()
               return
            }
@@ -590,14 +638,17 @@
            const curIndex = this.pageList.findIndex((a) => a.ip == text)
            if (curIndex < 0) {
               if (this.pageList.length === 3) {
                  showToast("对多只允许添加3辆车!")
                  showToast(this.translate('only_3_vehicles_to_added'))
                  return
               }
               uni.navigateTo({
                  url: `/pages/index/connect?ip=${text}`
               })
            } else {
               showToast("不允许添加相同IP的设备!")
               showToast(this.translate('vehicle_ip_has_added'))
               this.setData({
                  currentPage: curIndex
               })
               return
            }
@@ -607,13 +658,18 @@
            this.$refs.refPopupInput.close()
         },
         menuItemChange(item) {
            if (item.text == "编辑") {
            if (item.id == 'edit') {
               const page = this.pageList[this.currentPage]
               this.clickInfo(page)
            } else if (item.text == "删除") {
            } else if (item.id == "remove") {
               const page = this.pageList[this.currentPage]
               showModal(`确定要删除设备“${ page.name}”吗`, "警告", true, "确定", "取消").then((res) => {
               showModal({
                  content: `${this.translate('ask_delete_device')}`,
                  confirmText: this.translate('remove'),
                  cancelText: this.translate("cancel"),
               }).then((res) => {
                  if (res) {
                     const list = this.pageList
                     let curPage = this.currentPage
@@ -635,17 +691,107 @@
                  }
               })
            } else if (item.text == "备份") {
            } else if (item.id == "backup") {
               const page = this.pageList[this.currentPage]
               uni.navigateTo({
                  url: `/pages/index/backup?ip=${page.ip}`
               })
            } else if (item.id == "error") {
               const page = this.pageList[this.currentPage]
               uni.navigateTo({
                  url: `/pages/error/index?ip=${page.ip}`
               })
            } else if (item.id == "update") {
               const page = this.pageList[this.currentPage]
               uni.navigateTo({
                  url: `/pages/version/car-program-upload?ip=${page.ip}`
               })
            }
         },
         async loadCarSaveVersion() {
            try {
               var verName = ""
               var fileList = []
               try {
                  fileList = await TaskInit.fileUtils.listSavedFiles('car_version')
               } catch (ex) {
                  console.log(ex)
               }
               fileList.forEach((ele) => {
                  if (verName) {
                     if (verName < ele.name) {
                        verName = ele.name
                     }
                  } else {
                     verName = ele.name
                  }
               })
               this.localCarVersion = this.getVersionFromFileName(verName)
            } catch (ex) {
               this.localCarVersion = {
                  date: "",
                  ver: ""
               }
            }
         },
         getVersionFromFileName(fileName) {
            if (!fileName.trim()) {
               return {
                  date:"" ,
                  ver: ""
               }
            }
            let versionInfos = fileName.trim().split('_');
            let date = versionInfos[1]
            let version2 = versionInfos[2]
            let versionInfos2 = version2.split('.');
            versionInfos2.pop()
            return {
               date,
               ver: versionInfos2.join(".")
            }
         },
         async checkServerVersion(ip) {
            try {
               if (!this.localCarVersion?.ver) {
                  return false
               }
               const verInfo = await getShellVersion(ip)
               console.log(verInfo)
               if (verInfo?.software_version) {
                  const isVer = `${this.localCarVersion?.date ||""}_${this.localCarVersion?.ver ||""}` > verInfo
                     .software_version
                  return isVer
               }
            } catch (ex) {
               return false
            }
            return false
         },
         closeMenu() {
            this.$refs.refPopupMenu.close()
         }
         },
         translate(t, values) {
            if (typeof this.$t == "function") {
               const message = this.$t(`page.${t}`)
               if (values) {
                  return message.replace(/{(\d+)}/g, (match, index) => {
                     const value = values[index]
                     return value !== undefined ? value : match
                  })
               } else return message
            } else return t;
         },
      }
   }
</script>
@@ -884,7 +1030,7 @@
      .button {
         margin: auto;
         margin-top: 20rpx;
         width: 320rpx !important;
         width: 400rpx !important;
         border-radius: 4rpx;
      }
@@ -913,18 +1059,21 @@
         display: flex;
         flex-wrap: nowrap;
         flex-direction: row !important;
         align-items: center;
         padding: 8rpx 16rpx;
         // align-items: center;
         padding: 10rpx 20rpx;
         font-size: 32rpx;
         .text {
            flex: 1;
            text-align: left;
         }
         .img {
            width: 40rpx;
            height: 40rpx;
            margin: 10rpx;
         .new {
            background-color: red;
            width: 10rpx;
            height: 10rpx;
            margin: 5rpx 10rpx;
            border-radius: 5rpx;
         }
      }