| | |
| | | <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> |
| | |
| | | <swiper v-if="pageList.length > 0" circular indicator-dots class="swiper" :current="currentPage" |
| | | @change="changeSwiper"> |
| | | <swiper-item v-for="(page,index) in pageList" class="swiper-item"> |
| | | |
| | | <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-soc" :style="{width:(page.soc*0.4)+'rpx'}" |
| | | src="/images/bx_battery4.svg" alt="SVG 图片" /> |
| | | |
| | | </view> |
| | | <view v-else> |
| | | <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> |
| | | <view class="status-text">{{getAgvStateText(page)}}</view> |
| | | </template> |
| | | <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-soc" :style="{width:(page.soc*0.4)+'rpx'}" |
| | | src="/images/bx_battery4.svg" alt="SVG" /> |
| | | |
| | | |
| | | <view v-else class="gray-text">已离线</view> |
| | | </view> |
| | | <view v-else> |
| | | <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> |
| | | <view class="status-text">{{getAgvStateText(page)}}</view> |
| | | </template> |
| | | |
| | | |
| | | <view v-else class="gray-text">{{translate('offline')}}</view> |
| | | </view> |
| | | <image class="vehicle-img " :class="page.link_status ?'':'gray-image'" mode="aspectFit" |
| | | src="/images/che.png" alt="图片" /> |
| | | <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> |
| | | </view> |
| | | <image class="vehicle-img " :class="page.link_status ?'':'gray-image'" mode="aspectFit" |
| | | 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>{{translate('scenes')}}</text> |
| | | |
| | | </view> |
| | | <view type="primary" class="img-text-button" @click="clickToTask(page)"> |
| | | </view> |
| | | <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> |
| | | </view> |
| | | <view v-else class="unlink-content"> |
| | | <view class="content2" v-if="page.conntecting"> |
| | | <view class="auto-circle"></view> |
| | | </navigator> |
| | | |
| | | <view class="text">连接中...</view> |
| | | </view> |
| | | <view class="content2" v-else> |
| | | <view class="text"> 车辆已离线,请重新连接</view> |
| | | <a-button type="primary" class="button" @click="clickRelink">重新连接 |
| | | </a-button> |
| | | </view> |
| | | |
| | | </view> |
| | | <view v-else class="unlink-content"> |
| | | <view class="content2" v-if="page.conntecting"> |
| | | <view class="auto-circle"></view> |
| | | |
| | | <view class="text">{{translate('connecting')}}...</view> |
| | | </view> |
| | | |
| | | <view class="content2" v-else> |
| | | <view class="text">{{translate('vehicle_offline_to_reconnect')}}</view> |
| | | <a-button type="primary" class="button" @click="clickRelink">{{translate('reconnect')}} |
| | | </a-button> |
| | | </view> |
| | | |
| | | </view> |
| | | |
| | | </swiper-item> |
| | | <swiper-item class="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" |
| | |
| | | <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> |
| | |
| | | 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: { |
| | |
| | | timerBatteryId: 0, |
| | | inputPopupValue: "", |
| | | menuList: [{ |
| | | ico: "edit-line", |
| | | text: "编辑", |
| | | color: "black" |
| | | }, { |
| | | ico: "update", |
| | | text: "更新", |
| | | color: "black" |
| | | }, { |
| | | ico: "book", |
| | | text: "教程", |
| | | color: "black" |
| | | }, { |
| | | ico: "share", |
| | | text: "共享", |
| | | color: "black" |
| | | }, { |
| | | ico: "copy", |
| | | text: "备份", |
| | | color: "black" |
| | | }, { |
| | | ico: "delete-outline", |
| | | text: "删除", |
| | | color: "red" |
| | | }] |
| | | id: "edit", |
| | | ico: "edit-line", |
| | | text: this.translate('edit'), |
| | | color: "black" |
| | | }, |
| | | { |
| | | id: "update", |
| | | ico: "update", |
| | | text: this.translate('update'), |
| | | 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: this.translate('backup'), |
| | | color: "black" |
| | | }, |
| | | { |
| | | id: "remove", |
| | | ico: "delete-outline", |
| | | text: this.translate('remove'), |
| | | color: "red" |
| | | } |
| | | ] |
| | | |
| | | } |
| | | }, |
| | |
| | | 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: { |
| | |
| | | async loadData(ip) { |
| | | |
| | | try { |
| | | |
| | | this.loadCarSaveVersion() |
| | | let list = session.getValue("vehicles") || [] |
| | | |
| | | list.forEach((page) => { |
| | |
| | | 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) |
| | |
| | | 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 |
| | | }) |
| | |
| | | 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 |
| | | } |
| | |
| | | } |
| | | } catch (ex) { |
| | | |
| | | showError(ex) |
| | | showError(ex, this.translate('error')) |
| | | } |
| | | }, |
| | | |
| | |
| | | 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 { |
| | |
| | | // this.pageList = [...list] |
| | | |
| | | } catch (ex) { |
| | | // showError(ex) |
| | | // showError(ex,this.translate('error')) |
| | | showToast(ex) |
| | | } |
| | | |
| | |
| | | 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 |
| | | }, |
| | |
| | | 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 |
| | | } |
| | |
| | | currentPage: index |
| | | }) |
| | | if (this.pageList.length == this.currentPage) |
| | | this.navigationBarTitle = "添加设备" |
| | | this.navigationBarTitle = "" |
| | | else |
| | | this.navigationBarTitle = this.pageList[this.currentPage].name |
| | | this.loadVehicleBattery() |
| | |
| | | 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) { |
| | |
| | | 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 |
| | | }) |
| | | } |
| | | }, |
| | | }) |
| | |
| | | }, |
| | | 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() |
| | | }, |
| | | |
| | |
| | | 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) |
| | |
| | | // else |
| | | // that.navigationBarTitle = "添加设备" |
| | | uni.reLaunch({ |
| | | url:"/pages/indde/index" |
| | | url: "/pages/indde/index" |
| | | }) |
| | | }, |
| | | update_vehicle: function(data) { |
| | |
| | | }, |
| | | async clickToMap(index, page) { |
| | | try { |
| | | console.log("clicktomap") |
| | | console.log("clicktomap") |
| | | const _this = this |
| | | const res = await getAllScene(page.ip) || [] |
| | | const list = res?.sceneList || [] |
| | |
| | | } |
| | | }) |
| | | } catch (ex) { |
| | | showError(ex) |
| | | showError(ex, this.translate('error')) |
| | | } |
| | | |
| | | }, |
| | | clickToTask(page) { |
| | | |
| | | uni.navigateTo({ |
| | | url: `/pages/task/log-list?ip=${page.ip}` |
| | | }) |
| | | |
| | | }, |
| | | isValidIP(ip) { |
| | |
| | | |
| | | 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 |
| | | } |
| | |
| | | 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 |
| | | } |
| | | |
| | |
| | | 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 |
| | |
| | | |
| | | } |
| | | }) |
| | | } 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> |
| | |
| | | .button { |
| | | margin: auto; |
| | | margin-top: 20rpx; |
| | | width: 320rpx !important; |
| | | width: 400rpx !important; |
| | | border-radius: 4rpx; |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | } |
| | | |