<template>
|
<view class="pages-map">
|
|
<view class="view-content">
|
<uni-nav-bar :fixed="true" status-bar right-text="" left-text="" :leftWidth="24" :rightWidth="28"
|
:title="navigationBarTitle">
|
<view class="uni-navbar-container-inner">
|
<text class="uni-nav-bar-text">{{navigationBarTitle }}</text>
|
<image class="icon" v-if="sceneList.length > 1 && !mapOperationType" src="/images/Vector.svg"
|
alt="SVG 图片" @click="clickShowMenu" />
|
</view>
|
<template v-slot:left>
|
<view>
|
<uni-icons type="left" size="24" @click="clickBack"></uni-icons>
|
</view>
|
|
</template>
|
<template v-slot:right>
|
<view v-if="sceneList.length > 0 && !mapOperationType">
|
<a @click="clickMore">
|
<uni-icons class="uni-panel-bar-icon" type="more-filled" size="24"></uni-icons>
|
</a>
|
</view>
|
|
</template>
|
</uni-nav-bar>
|
<view class="no-content" v-if="unlinked">
|
<image class="img" src="/images/image 25.png" alt=" 图片" mode="aspectFit" />
|
<view class="title">车辆连接失败</view>
|
<view class="space">请检查你的网络设置或重新加载</view>
|
</view>
|
<!-- <SceneCreateInfo v-else-if="mapOperationType =='scene_create'" class="map-content" :ip="vehicleIp"
|
v-model:opSceneType="opSceneType" @create-ok="onCreateSceneOk"></SceneCreateInfo> -->
|
<view class="map-content" v-show="mapOperationType !='scene_create'">
|
<view class="content">
|
<view class="fabric" :message="ctxDataStr" :change:message="ctx.receiveMsg" id="canvasMap"></view>
|
<view class="loading-overlay" v-if="bgLoading">
|
<view class="loading-content">
|
<view class="loading-spinner"></view>
|
<text>加载中... {{ bgProgressPercent }}%</text>
|
</view>
|
</view>
|
<view class="position-site" v-if="mapOperationStatus =='pos' " @click="clickPositionStation">
|
<text class="ico my-location-rounded"></text>
|
|
获取搬运车位置和朝向
|
</view>
|
<view class="position" v-else @click="clickVehiclePosition">
|
<text class="ico my-location-rounded"></text>
|
<!-- <image class="img" src="/images/material-symbols_my-location-rounded.svg" alt="SVG 图片" /> -->
|
</view>
|
<view v-if="this.mapOperationType ==''" class="teaching-path-show"
|
:class="showTeachingPathFlag?'selected':''" @click="clickShowTeachingPath">
|
<text class="ico layer"></text>
|
|
</view>
|
<view class="station-info"
|
:style="{'left':(stationViewPos.x - 120)+ 'px','top':(stationViewPos.y + stationViewPos.height/2 + 10)+'px'}"
|
v-if="mapOperationType =='edit_station'">
|
|
<view class=" left">
|
<view class="line">站点名称:
|
</view>
|
<view class="line"> 坐标(x,y):
|
</view>
|
<view class="line">朝向:
|
</view>
|
|
</view>
|
<view class="right">
|
<view class="line"> {{stationEdit.name}}
|
</view>
|
<view class="line">
|
{{ Math.floor( stationEdit.x*1000)/1000}},{{ Math.floor( stationEdit.y*1000)/1000}}
|
</view>
|
<view class="line"> {{ Math.floor(180* stationEdit.angle/Math.PI)}}°
|
</view>
|
|
</view>
|
</view>
|
|
</view>
|
</view>
|
</view>
|
<view class="bottom">
|
<view class="bottom-content" v-if="mapOperationType =='edit_scene_name'">
|
<view class="tip">请输入场景名称</view>
|
<view class="name-input">
|
<input ref="refInputName" :focus="true" placeholder="请输入场景名称" :value="sceneInputName"
|
@input="onInputName"></input>
|
<uni-icons class="clear" color="#ccc" type="clear" size="20" v-if="sceneInputName"
|
@click="clickClearName"></uni-icons>
|
</view>
|
<view class="text-button-group">
|
<a-button type="primary" class="button" :disabled="loading || sceneInputName.trim() == ''"
|
@click="clickNameOK">确认</a-button>
|
<a-button type="ghost" class="button" :disabled="loading" @click="clickNameCancel">取消</a-button>
|
</view>
|
</view>
|
|
<template
|
v-else-if="mapOperationType =='teaching_add_station' || mapOperationType =='add_station' || mapOperationType =='edit_station'">
|
<view class="bottom-content" v-if="mapOperationStatus =='pos' ">
|
<view class="tip">调节位置</view>
|
<view class="row-group">
|
<view class="coordinate">
|
<text class="name">横坐标:</text>
|
<input ref="refInputX" class="number-input" type="number" :value="stationEdit.x"
|
@input="onInputStationX" :maxlength="4"></input>
|
<uni-icons class="clear" color="#ccc" type="clear" size="20"
|
v-if="stationEdit.x && stationEdit.x!='0'" @click="clickClearStationX"></uni-icons>
|
</view>
|
<view class="coordinate">
|
<text class="name">竖坐标:</text>
|
<input ref="refInputX" class="number-input" type="number" :value="stationEdit.y"
|
@input="onInputStationY" :maxlength="4"></input>
|
<uni-icons class="clear" color="#ccc" type="clear" size="20"
|
v-if="stationEdit.y&& stationEdit.y!='0'" @click="clickClearStationY"></uni-icons>
|
</view>
|
</view>
|
|
<view class="tip">调节朝向</view>
|
<view class="angle-group">
|
<image class="img-angle" :src="angleSvg" alt="SVG 图片" />
|
<image class="img-angle-pos" src="/images/Frame 153.svg" alt="SVG 图片"
|
@touchstart="handleAngleTouchStart" @touchmove="handleAngleTouchMove" />
|
</view>
|
</view>
|
<view class="bottom-content" v-else>
|
<view class="tip">请输入站点名称</view>
|
<view class="name-input">
|
<input ref="refInputName" :focus="true" placeholder="输入站点名称" :value="stationEdit.name"
|
@input="onInputStationName"></input>
|
<uni-icons class="clear" color="#ccc" type="clear" size="20" v-if="stationEdit.name"
|
@click="clickClearStationName"></uni-icons>
|
</view>
|
<view class="text-button-group">
|
<a-button class="button" :disabled="loading" @click="clickStationNameCancel">取消</a-button>
|
<a-button type="primary" class="button" :disabled="loading || stationEdit.name.trim() == ''"
|
@click="clickStationNameOK">确定</a-button>
|
</view>
|
</view>
|
|
</template>
|
<view class="bottom-content" v-else-if="mapOperationType =='regiona_planning'">
|
<view class="img-button-group">
|
<view fill="none" class="button" @click="clickManualPlan">
|
<text class="ico conversion-path"></text>
|
<view class="text">人工规划</view>
|
</view>
|
|
<view type="text" class="button " @click="clickVehicleTrajectoryPlan">
|
<text class="ico conversion-path"></text>
|
<view class="text ">车辆轨迹规划</view>
|
</view>
|
</view>
|
</view>
|
<view class="bottom-content" v-else-if="mapOperationType =='vehicle_trajectory_planning'">
|
<template v-if="mapOperationStatus=='feasible_region' || mapOperationStatus=='prohibition_region'">
|
<view class="tip">区域规划</view>
|
<view>可按住各端点调整虚拟墙位置,按【+】按钮可添加顶点,区域需为闭合图形</view>
|
</template>
|
<view class="img-button-group" v-else>
|
<view fill="none" class="button" @click="clickPlanFeasibleRegion">
|
<!-- <text class="ico conversion-path"></text> -->
|
<uni-icons class="img" type="checkmarkempty" size="36" color="#1890FF"></uni-icons>
|
<view class="text">可行区</view>
|
</view>
|
|
<view type="text" class="button " @click="clickPlanProhibitionRegion">
|
<text class="ico placeholder-bold"></text>
|
<view class="text ">禁行区</view>
|
</view>
|
</view>
|
</view>
|
|
<view class="bottom-content" v-else-if="mapOperationType =='manual_planning'">
|
<template v-if="mapOperationStatus=='feasible_region' || mapOperationStatus=='prohibition_region'">
|
<view class="tip">区域规划</view>
|
<view>可按住各端点调整虚拟墙位置,按【+】按钮可添加顶点,区域需为闭合图形</view>
|
</template>
|
<template v-else-if="mapOperationStatus=='virtual_wall'">
|
<view class="tip">区域规划</view>
|
<view>可按住两端点调整虚拟墙位置</view>
|
|
</template>
|
<view class="img-button-group" v-else>
|
<view fill="none" class="button" @click="clickPlanFeasibleRegion">
|
<!-- <text class="ico conversion-path"></text> -->
|
<uni-icons class="img" type="checkmarkempty" size="36" color="#1890FF"></uni-icons>
|
<view class="text">可行区</view>
|
</view>
|
|
<view type="text" class="button " @click="clickPlanProhibitionRegion">
|
<text class="ico placeholder-bold"></text>
|
|
<view class="text ">禁行区</view>
|
</view>
|
<view type="text" class="button " @click="clickPlanVirtualWall">
|
<text class="dashed-line"></text>
|
<view class="text ">虚拟墙</view>
|
</view>
|
</view>
|
|
|
</view>
|
<view class="bottom-content" v-else-if="mapOperationType =='scene_create'"></view>
|
<template v-else-if="mapOperationType =='public_teaching' ">
|
<view class="bottom-content" v-if="mapOperationStatus =='teaching'">
|
<view class="tip">路径记录中...</view>
|
<view v-if="mapOperationType =='public_teaching'">
|
<view>正在记录搬运车行进路径,可随时切换主路/支路示教,完成后点按钮以结束示教。在示教过程中可以添加站点。</view>
|
<view class="switch-type">
|
<view class="switch-button-group">
|
<view class="switch-button"
|
:class="teachingModeCur.main_road ==1?'switch-button-checked':''"
|
@click="onTeachingModeMainRoad(1)">主路示教</view>
|
<view class="switch-button "
|
:class="teachingModeCur.main_road ==0?'switch-button-checked':''"
|
@click="onTeachingModeMainRoad(0)">支路示教</view>
|
</view>
|
</view>
|
</view>
|
|
<view v-else>
|
正在记录搬运车行进路径,完成后点按钮以结束示教
|
</view>
|
<view class="text-button-group">
|
<a-button v-if="mapOperationType =='public_teaching'" type="ghost" class="button"
|
@click="clickAddStation">添加站点</a-button>
|
<a-button type="primary" class="button" @click="clickTeachingEnd">结束记录</a-button>
|
</view>
|
</view>
|
<view class="bottom-content" v-else-if="mapOperationStatus =='end'">
|
<view class="tip">路径记录完成</view>
|
<view>
|
要将该段路径保存为示教路径吗?
|
</view>
|
<view class="text-button-group">
|
<a-button type="primary" class="button" :disabled="loading"
|
@click="clickTeachingSave">保存为示教路径</a-button>
|
<a-button type="ghost" class="button" :disabled="loading"
|
@click="clickTeachingReset">重新记录</a-button>
|
</view>
|
</view>
|
<view class="bottom-content" v-else-if="mapOperationStatus =='save'">
|
<view class="tip">示教完成</view>
|
<view>
|
已将路径保存为示教路径
|
</view>
|
<view class="text-button-group">
|
<a-button type="primary" class="button" :disabled="loading"
|
@click="clickTeachingFinish">完成</a-button>
|
</view>
|
</view>
|
<view class="bottom-content" v-else>
|
<view class="tip">即将开始公共示教</view>
|
<view>
|
请选择要进行主路还是支路示教,点【开始记录】后将记录搬运车的行进路线作为公共示教路线。开始记录后可随时切换主路/支路示教。
|
</view>
|
<view class="text-button-group">
|
<view class="switch-type">
|
<view class="switch-button-group">
|
<view class="switch-button"
|
:class="teachingModeCur.main_road ==1?'switch-button-checked':''"
|
@click="onTeachingModeMainRoad(1)">主路示教</view>
|
<view class="switch-button "
|
:class="teachingModeCur.main_road ==0?'switch-button-checked':''"
|
@click="onTeachingModeMainRoad(0)">支路示教</view>
|
</view>
|
</view>
|
<a-button type="primary" class="button" :disabled="loading"
|
@click="clickTeachingStart">开始记录</a-button>
|
</view>
|
</view>
|
|
</template>
|
<view class="bottom-content" v-else-if="mapOperationType =='edit_map'">
|
<view class="img-button-group">
|
<view fill="none" class="button" @click="clickRename">
|
<text class="ico rename"></text>
|
<view class="text">重命名</view>
|
</view>
|
|
<view type="text" class="button " @click="clickRegionaPlan">
|
<text class="ico zone"></text>
|
<view class="text">区域规划</view>
|
</view>
|
<view fill="none" class="button" @click="clickExtendMap">
|
<text class="ico expand"></text>
|
<view class="text">扩展地图</view>
|
</view>
|
<!-- <view type="text" class="button" @click="clickMapEdit">
|
<text class="ico edit-line"></text>
|
<view class="text"> 编辑地图</view>
|
</view> -->
|
<view type="text" class="button" @click="clickDelete">
|
<text class="ico delete-outline"></text>
|
<view class="text">删除场景</view>
|
</view>
|
</view>
|
|
</view>
|
<view class="bottom-content" v-else>
|
<view class="img-button-group">
|
<view fill="none" class="button" @click="clickMapStation">
|
<text class="ico location1"></text>
|
<view class="text">添加站点</view>
|
</view>
|
<view fill="none" class="button" @click="clickTeaching">
|
<text class="ico teach"></text>
|
<view class="text">路径示教</view>
|
</view>
|
<!-- <view type="text" class="button " @click="clickRegionaPlan">
|
<text class="ico layer"></text>
|
<view class="text">区域规划</view>
|
</view> -->
|
<view type="text" class="button" @click="clickMapEdit">
|
<text class="ico edit-line"></text>
|
<view class="text"> 编辑地图</view>
|
</view>
|
<view type="text" class="button" @click="clickMapTask">
|
<text class="ico task-list"></text>
|
<view class="text">任务设置</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
<view>
|
<uni-popup ref="refPopupMenu" background-color="transparent" maskBackgroundColor="rgba(0, 0, 0, 0.2)">
|
<view class="popup-content">
|
<view class="popup-content-menu "
|
:style="{'margin-top':menuPopup.top+'rpx','margin-left':menuPopup.left+'rpx'}">
|
<view class="popup-content-menu-item" v-for="(item,index) in menuPopup.list" :key="index"
|
@click="menuItemChange(item,menuPopup.type)">
|
{{item}}
|
</view>
|
</view>
|
</view>
|
</uni-popup>
|
<uni-popup ref="refPopupOperateStation" background-color="transparent"
|
maskBackgroundColor="rgba(0, 0, 0, 0.2)" @click="closePopuBtn">
|
<view class="popup-content">
|
<view class="popup-content-btn">
|
<view class="img-button-group">
|
<view fill="none" class="button" @click.stop="clickStationDelete">
|
<text class="ico delete-outline"></text>
|
<view class="text"> 删除站点</view>
|
</view>
|
<view type="text" class="button" @click.stop="clickStationPostion">
|
<text class="ico edit-line"></text>
|
<view class="text">调整位置朝向</view>
|
</view>
|
<view type="text" class="button" @click.stop="clickStationRename">
|
<text class="ico rename"></text>
|
<view class="text">重命名</view>
|
|
</view>
|
</view>
|
</view>
|
|
</view>
|
</uni-popup>
|
<uni-popup ref="refPopupOperateTeaching" background-color="transparent"
|
maskBackgroundColor="rgba(0, 0, 0, 0.2)">
|
<view class="popup-content">
|
<view class="popup-content-btn">
|
<view class="img-button-group">
|
|
<view fill="none" class="button" @click.stop="clickTeachingEdit">
|
<text class="ico edit-line"></text>
|
<view class="text">编辑</view>
|
</view>
|
<view fill="none" class="button" @click.stop="clickTeachingDelete">
|
<text class="ico red delete-outline "></text>
|
<view class="text">删除</view>
|
</view>
|
|
</view>
|
</view>
|
|
</view>
|
</uni-popup>
|
|
</view>
|
</view>
|
</template>
|
<script src="./js/ctx.js" module="ctx" lang="renderjs"></script>
|
|
|
<script>
|
import {
|
showToast,
|
showModal,
|
session,
|
} from "@/comm/utils.js"
|
// import OIFabric from "@/components/oi-fabric/index.vue"
|
import {
|
Button
|
} from 'antd-mobile-vue-next'
|
import SceneCreateInfo from './infos/scene-create.vue'
|
|
|
import {
|
getAllScene,
|
getMapUrl,
|
handoffScene,
|
updateScene,
|
delScene,
|
stations,
|
getAgvState,
|
addStation,
|
updateStation,
|
delStation,
|
getTeachingMode,
|
teachingModeFlag,
|
getCurrentTeachingData,
|
delTeachingMode,
|
delTeachingModeData,
|
checkAgvLocationDistanceError,
|
} from "@/api/vehicle.js"
|
export default {
|
name: "PagesMap",
|
components: {
|
'a-button': Button,
|
SceneCreateInfo
|
},
|
data() {
|
return {
|
loading: false,
|
navigationBarTitle: "",
|
opSceneType: "",
|
vehicleIp: "",
|
sceneId: "",
|
mapShowAgv: false,
|
menuPopup: {
|
type: "",
|
list: []
|
},
|
sceneList: [],
|
ctxDataStr: "[]",
|
mapOperationType: "",
|
mapOperationStatus: "",
|
mapOperationStatus: "",
|
teachingMode: {},
|
teachingModeCur: {},
|
|
stationViewPos: {
|
x: 0,
|
y: 0,
|
width: 0,
|
height: 0
|
},
|
stationEdit: {
|
stationID: "",
|
name: "",
|
x: 0,
|
y: 0,
|
angle: 0
|
},
|
sceneInputName: "",
|
showClearName: false,
|
stationList: [],
|
angleSvg: "/static/images/angle0.svg",
|
windowWidth: 375,
|
bgProgressPercent: 0,
|
bgLoading: false,
|
isMapEdit: false,
|
wallList: [],
|
regionList: [],
|
unlinked: false,
|
showTeachingPathFlag: false,
|
curMapInfo: {
|
proportion: 1,
|
img_proportion: 1,
|
max_x: 1,
|
max_y: 1,
|
min_x: 0,
|
min_y: 0,
|
img_x: 1,
|
img_y: 1
|
},
|
}
|
},
|
computed: {
|
|
getMaxStationNo() {
|
let num = 0
|
this.stationList.forEach((item) => {
|
if (num < item.stationID) {
|
num = item.stationID
|
}
|
})
|
return num
|
},
|
},
|
watch: {
|
mapOperationType(val) {
|
let name = this.sceneId || "地图"
|
if (val == "add_station" || val == "teaching_add_station") {
|
name = "添加站点"
|
} else if (val == "edit_station") {
|
name = "编辑站点"
|
} else if (val == "scene_create") {
|
name = "构建场景"
|
} else if (val == "edit_map") {
|
name = "编辑地图"
|
} else if (val == "manual_planning") {
|
name = "人工规划"
|
} else if (val == "vehicle_trajectory_planning") {
|
name = "车辆轨迹规划"
|
} else if (val == "public_teaching") {
|
name = "路径示教"
|
}
|
this.setData({
|
navigationBarTitle: name
|
})
|
}
|
},
|
onLoad(option) {
|
const _this = this
|
console.log(option)
|
this.vehicleIp = option.ip || ""
|
this.isPageVisible = true
|
uni.getSystemInfo({
|
success(e) {
|
_this.windowWidth = e.windowWidth
|
},
|
|
})
|
this.loadData()
|
|
},
|
onShow() {
|
this.isPageVisible = true
|
},
|
onHide() {
|
this.isPageVisible = false
|
},
|
onUnload() {
|
this.isPageVisible = false
|
},
|
methods: {
|
setData(obj) {
|
let that = this;
|
let keys = [];
|
let val, data;
|
|
Object.keys(obj).forEach(function(key) {
|
keys = key.split(".");
|
val = obj[key];
|
data = that.$data;
|
keys.forEach(function(key2, index) {
|
if (index + 1 == keys.length) {
|
that.$set(data, key2, val);
|
} else {
|
if (!data[key2]) {
|
that.$set(data, key2, {});
|
}
|
}
|
data = data[key2];
|
});
|
});
|
},
|
async loadData() {
|
try {
|
await this.loadSceneList()
|
if (this.sceneList.length > 0) {
|
this.mapOperationType = ''
|
const scene = this.sceneList[0]
|
this.changeMap(scene)
|
}
|
this.refreshAgvPosition()
|
} catch (ex) {
|
this.setData({
|
unlinked: true
|
})
|
this.showError(ex)
|
}
|
},
|
|
clickShowMenu() {
|
this.menuPopup = {
|
type: "scene",
|
list: this.sceneList,
|
left: 225,
|
top: 140
|
}
|
this.$refs.refPopupMenu.open("top")
|
},
|
clickMore() {
|
this.menuPopup = {
|
type: "menu",
|
list: ["构建场景", "地图扩展", "重命名", "删除"],
|
left: 450,
|
top: 140
|
}
|
this.$refs.refPopupMenu.open("top")
|
},
|
|
async clickBack() {
|
if (this.mapOperationType == "scene_create") {
|
if (this.opSceneType == "scan") {
|
showModal("已构建场景将会被删除", "是否中断场景构建?").then((res) => {
|
if (res) {
|
if (this.sceneList.length == 0) {
|
const eventChannel = this.getOpenerEventChannel();
|
eventChannel.emit('check_connect', !this.unlinked);
|
uni.navigateBack({
|
delta: 1
|
})
|
} else {
|
this.opSceneType = ""
|
this.mapOperationType = ""
|
}
|
|
}
|
})
|
} else {
|
if (this.opSceneType != "") {
|
await this.loadSceneList()
|
if (this.sceneList.length == 0) {
|
|
const eventChannel = this.getOpenerEventChannel();
|
eventChannel.emit('check_connect', !this.unlinked);
|
uni.navigateBack({
|
delta: 1
|
})
|
}
|
} else {
|
const eventChannel = this.getOpenerEventChannel();
|
eventChannel.emit('check_connect', !this.unlinked);
|
uni.navigateBack({
|
delta: 1
|
})
|
}
|
}
|
} else if (this.mapOperationType == "edit_map") {
|
this.mapOperationType = ""
|
} else if (this.mapOperationType == "regiona_planning") {
|
this.mapOperationType = "edit_map"
|
} else if (this.mapOperationType == "vehicle_trajectory_planning") {
|
if (this.mapOperationStatus == "feasible_region" || this.mapOperationStatus ==
|
"prohibition_region") {
|
|
showModal("正在进行区域规划。", "是否要退出区域规划?").then((res) => {
|
if (res) {
|
this.mapOperationStatus = ""
|
}
|
})
|
|
} else {
|
this.mapOperationType = "regiona_planning"
|
}
|
return
|
} else if (this.mapOperationType == "manual_planning") {
|
if (this.mapOperationStatus == "virtual_wall" ||
|
this.mapOperationStatus == "feasible_region" ||
|
this.mapOperationStatus == "prohibition_region") {
|
showModal("正在进行区域规划。", "是否要退出区域规划?").then((res) => {
|
if (res) {
|
if (this.mapOperationStatus == "virtual_wall") {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_wall",
|
param: [this.wallEdit]
|
}])
|
this.wallEdit = {}
|
} else {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_region",
|
param: [this.regionEdit]
|
}])
|
this.regionEdit = {}
|
}
|
this.mapOperationStatus = ""
|
}
|
})
|
} else {
|
this.mapOperationType = "regiona_planning"
|
}
|
return
|
} else if (this.mapOperationType == "edit_station") {
|
this.mapOperationType = ""
|
if (this.mapOperationStatus == "pos") {
|
this.ctxDataStr = JSON.stringify([{
|
method: "edit_station_pos",
|
param: undefined
|
}])
|
}
|
this.$refs.refPopupOperateStation.open("bottom")
|
} else if (this.mapOperationType == "add_station") {
|
this.mapOperationType = ""
|
if (this.stationEdit.stationID) {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_station",
|
param: [this.stationEdit]
|
}, {
|
method: "set_selectable",
|
param: true
|
}])
|
}
|
|
|
} else if (this.mapOperationType == "teaching_add_station") {
|
this.mapOperationType = "public_teaching"
|
this.mapOperationStatus = "teaching"
|
if (this.stationEdit.stationID) {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_station",
|
param: [this.stationEdit]
|
}])
|
}
|
|
|
} else if (this.mapOperationType == "public_teaching") {
|
|
|
if (this.mapOperationStatus) {
|
|
showModal("已记录的路径将会被删除。", "是否要退出示教?").then(async (res) => {
|
if (res) {
|
if (mapOperationStatus == 'end' || mapOperationStatus == 'save') {
|
try {
|
await delTeachingMode(this.vehicleIp, [_this.teachingModeCur])
|
} catch (ex) {
|
this.showError(ex)
|
}
|
|
}
|
this.ctxDataStr = JSON.stringify([{
|
method: "teaching_finish",
|
}])
|
|
this.mapOperationType = ""
|
}
|
})
|
} else {
|
this.ctxDataStr = JSON.stringify([{
|
method: "teaching_finish",
|
}])
|
|
this.mapOperationType = ""
|
}
|
|
} else {
|
// const eventChannel = this.getOpenerEventChannel();
|
// eventChannel.emit('udapte_station', this.unlinked);
|
// uni.navigateBack({
|
// delta: 1
|
// })
|
const eventChannel = this.getOpenerEventChannel();
|
eventChannel.emit('check_connect', !this.unlinked);
|
uni.navigateBack({
|
delta: 1
|
})
|
}
|
|
},
|
async onCreateSceneOk(name) {
|
this.opSceneType = ""
|
this.mapOperationType = ""
|
await this.loadSceneList()
|
if (this.sceneList.length == 1) {
|
this.changeMap(this.sceneList[0])
|
} else if (this.sceneList.length > 1) {
|
this.changeMap(name)
|
}
|
},
|
clickStartConstructScene() {
|
|
},
|
clickDownloadScene() {
|
|
},
|
menuItemChange(item, type) {
|
const _this = this
|
this.$refs.refPopupMenu.close()
|
if (type == "scene") {
|
this.changeMap(item)
|
} else if (type == "menu") {
|
if (item == "构建场景") {
|
// this.mapOperationType = 'scene_create'
|
// this.opSceneType = 'add_name'
|
uni.navigateTo({
|
url: `/pages/map/scene?ip=${this.vehicleIp}`,
|
events: {
|
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
|
create_finish: function(data) {
|
_this.onCreateSceneOk(data)
|
},
|
}
|
})
|
} else if (item == "地图扩展") {
|
this.clickExtendMap()
|
} else if (item == "重命名") {
|
this.clickRename()
|
} else if (item == "删除") {
|
this.clickDelete()
|
}
|
}
|
|
|
},
|
async loadAgvState() {
|
try {
|
const info = await getAgvState(this.vehicleIp)
|
return info
|
} catch (ex) {
|
this.showError(ex)
|
return {}
|
}
|
},
|
async loadCurrentTeachingData() {
|
try {
|
const paths = await getCurrentTeachingData(this.vehicleIp) || []
|
return paths
|
} catch (ex) {
|
this.showError(ex)
|
return []
|
}
|
},
|
|
async loadStations() {
|
try {
|
const info = await stations(this.vehicleIp)
|
return info.station_list || []
|
} catch (ex) {
|
this.showError(ex)
|
return []
|
}
|
},
|
async loadMapInfo(id) {
|
try {
|
const info = await getMapUrl(this.vehicleIp, id)
|
return info
|
} catch (ex) {
|
this.showError(ex)
|
return {}
|
}
|
},
|
async changeMap(id) {
|
|
this.mapShowAgv = false
|
this.setData({
|
sceneId: id,
|
navigationBarTitle: id || "地图"
|
})
|
try {
|
uni.showLoading({
|
title: "切换场景中"
|
})
|
this.setData({
|
unlinked: false
|
})
|
await handoffScene(this.vehicleIp, "", id)
|
} catch (ex) {
|
this.setData({
|
unlinked: true
|
})
|
return
|
} finally {
|
uni.hideLoading()
|
}
|
try {
|
this.setData({
|
bgProgressPercent: 0,
|
})
|
const infoAgv = await this.loadAgvState()
|
const stationLst = await this.loadStations()
|
|
const infoMap = await this.loadMapInfo(id)
|
this.curMapInfo = {
|
proportion: infoMap.proportion || 1,
|
img_proportion: infoMap.img_proportion || 1,
|
max_x: infoMap.max_x || 1,
|
max_y: infoMap.max_y || 1,
|
min_x: infoMap.min_x || 0,
|
min_y: infoMap.min_y || 0,
|
img_x: infoMap.img_x || 1,
|
img_y: infoMap.img_y || 1
|
}
|
// getApp().globalData.curScene = infoMap
|
this.setData({
|
bgProgressPercent: 30,
|
bgLoading: infoMap.filedata ? true : false
|
})
|
this.stationList = stationLst
|
this.teachingMode = await this.loadTeachingMode()
|
this.ctxDataStr = JSON.stringify([{
|
method: "init",
|
param: {
|
editMode: true
|
}
|
}, {
|
method: "background",
|
param: infoMap
|
},
|
{
|
method: "update_agv_state",
|
param: infoAgv
|
},
|
{
|
method: "add_station",
|
param: stationLst
|
},
|
{
|
method: "public_teaching_path",
|
param: this.teachingMode.Public || []
|
|
},
|
{
|
method: "station_teaching_path",
|
param: this.teachingMode.Stations || []
|
|
},
|
{
|
method: "move_canvas",
|
param: {
|
x: infoAgv.x,
|
y: infoAgv.y
|
}
|
}
|
])
|
this.mapShowAgv = true
|
} catch (ex) {
|
this.setData({
|
bgProgressPercent: 0,
|
bgLoading: false
|
})
|
this.showError(ex)
|
}
|
},
|
|
receiveRenderData(param) {
|
console.log('接收到视图层的数据:', param);
|
if (param.method == "set_backgroud_progress") {
|
if (param.type == "start") {
|
this.setData({
|
bgProgressPercent: 50,
|
bgLoading: true
|
})
|
} else if (param.type == "progress") {
|
this.setData({
|
bgProgressPercent: 50 + (param.percent || 0) / 2
|
})
|
} else if (param.type == "end") {
|
this.setData({
|
bgProgressPercent: 100,
|
bgLoading: true
|
})
|
setTimeout(() => {
|
this.setData({
|
bgLoading: false
|
})
|
}, 500)
|
|
} else if (param.type == "error") {
|
this.setData({
|
bgProgressPercent: 0,
|
bgLoading: false
|
})
|
}
|
|
} else if (param.method == "edit_station") {
|
this.stationEdit = param.station
|
this.stationViewPos = {
|
x: param.view?.x || 0,
|
y: param.view?.y || 0,
|
width: param.view?.width || 0,
|
height: param.view?.height || 0,
|
}
|
this.mapOperationType = ""
|
|
this.$refs.refPopupOperateStation.open("bottom")
|
|
} else if (param.method == "update_station") {
|
this.stationEdit.stationID = param.station?.stationID
|
this.stationEdit.angle = param.station.angle
|
this.stationEdit.x = param.station.x
|
this.stationEdit.y = param.station.y
|
this.stationViewPos.x = param.view?.x || 0
|
this.stationViewPos.y = param.view?.y || 0
|
} else if (param.method == "edit_finish") {
|
|
if (param.cmd == "ok") {
|
|
if (param.type == "station") {
|
this.mapOperationStatus = ""
|
this.stationEdit.stationID = param.data?.stationID
|
this.stationEdit.name = param.data?.name
|
this.stationEdit.angle = param.data?.angle
|
this.stationEdit.x = param.data?.x
|
this.stationEdit.y = param.data?.y
|
|
const angle = this.getStantardAngle(this.stationEdit.angle * 180 / Math.PI)
|
|
this.angleSvg = `/static/images/angle${angle}.svg`
|
this.clickStationPositonOk()
|
} else if (param.type == "edit_teaching") {
|
// console.log(param.type,JSON.stringify(param.data))
|
this.removeTeachingModeData(param.data)
|
this.ctxDataStr = JSON.stringify([])
|
this.mapOperationType = ""
|
} else if (param.type == "virtual_wall") {
|
this.wallEdit = param.data
|
this.wallList.push(param.data)
|
this.mapOperationStatus = ""
|
|
} else if (param.type == "region") {
|
this.regionEdit = param.data
|
this.regionList.push(param.data)
|
this.mapOperationStatus = ""
|
}
|
|
} else if (param.cmd == "cancel") {
|
|
if (param.type == "edit_teaching") {
|
this.ctxDataStr = JSON.stringify([])
|
this.mapOperationType = ""
|
} else if (this.mapOperationType == "manual_planning") {
|
if (this.mapOperationStatus == "virtual_wall") {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_wall",
|
param: [this.wallEdit]
|
}])
|
this.wallEdit = {}
|
} else {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_region",
|
param: [this.regionEdit]
|
}])
|
this.regionEdit = {}
|
}
|
this.mapOperationStatus = ""
|
} else if (this.mapOperationType == "teaching_add_station") {
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_station",
|
param: [{
|
stationID: this.stationEdit.stationID
|
}],
|
}])
|
this.stationEdit.stationID = ""
|
this.mapOperationType = "public_teaching"
|
this.mapOperationStatus = "teaching"
|
|
} else if (this.mapOperationType == "edit_station") {
|
this.mapOperationType = ""
|
this.mapOperationStatus = ""
|
if (this.mapOperationStatus == "pos") {
|
this.ctxDataStr = JSON.stringify([{
|
method: "edit_station_pos",
|
param: undefined
|
}])
|
}
|
this.$refs.refPopupOperateStation.open("bottom")
|
} else if (this.mapOperationType == "add_station") {
|
this.mapOperationType = ""
|
this.mapOperationStatus = ""
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_station",
|
param: [this.stationEdit]
|
}, {
|
method: "set_selectable",
|
param: true
|
}])
|
}
|
|
}
|
} else if (param.method == "select_teaching_path") {
|
console.log("point", param.point)
|
if (param.type == "station") {
|
|
this.selectTeachingMode = {
|
mode: "Stations",
|
name: param.data?.name || "",
|
src_dst: param.data?.src_dst || "",
|
point: param.point
|
}
|
|
} else if (param.type == "public") {
|
this.selectTeachingMode = {
|
mode: "Public",
|
name: param.data?.name || "",
|
point: param.point
|
}
|
}
|
|
this.$refs.refPopupOperateTeaching.open("bottom")
|
}
|
|
},
|
clickMapStation() {
|
this.stationEdit = {
|
stationID: "",
|
name: "",
|
x: 0,
|
y: 0,
|
angle: 0,
|
}
|
this.mapOperationType = "add_station"
|
this.mapOperationStatus = ""
|
},
|
clickAddStation() {
|
this.stationEdit = {
|
stationID: "",
|
name: "",
|
x: 0,
|
y: 0,
|
angle: 0,
|
}
|
this.mapOperationType = "teaching_add_station"
|
this.mapOperationStatus = ""
|
},
|
clickMapEdit() {
|
|
this.mapOperationType = "edit_map"
|
},
|
clickExtendMap() {
|
uni.navigateTo({
|
url: `/pages/map/scene?ip=${this.vehicleIp}&opType=extend&sceneId=${this.sceneId}`,
|
events: {
|
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
|
create_finish: function(data) {
|
_this.onCreateSceneOk(data)
|
},
|
}
|
})
|
},
|
clickMapTask() {
|
|
uni.navigateTo({
|
url: `/pages/task/list?ip=${this.vehicleIp}`
|
})
|
},
|
clickTeaching() {
|
this.mapOperationStatus = ""
|
this.teachingModeCur = {
|
mode: "Public",
|
main_road: 1,
|
}
|
this.mapOperationType = "public_teaching"
|
this.ctxDataStr = JSON.stringify([{
|
method: "set_selectable",
|
param: false,
|
}, {
|
method: "public_teaching",
|
}])
|
|
// uni.navigateTo({
|
// url: `/pages/map/teaching?ip=${this.vehicleIp}&sceneId=${this.sceneId}&list=${JSON.stringify(this.sceneList)}`
|
// })
|
},
|
clickRegionaPlan() {
|
this.mapOperationType = "regiona_planning"
|
},
|
clickRename() {
|
this.sceneInputName = this.sceneId
|
this.mapOperationType = 'edit_scene_name'
|
},
|
async loadSceneList() {
|
try {
|
uni.showLoading({
|
title: "加载场景中"
|
})
|
const _this = this
|
const res = await getAllScene(this.vehicleIp) || []
|
const list = res?.sceneList || []
|
this.setData({
|
unlinked: false
|
})
|
getApp().globalData.sceneList = list
|
this.sceneList = list
|
if (list.length === 0) {
|
this.opSceneType = ''
|
// this.mapOperationType = 'scene_create'
|
// this.setData({
|
// sceneId: "",
|
// navigationBarTitle: "地图"
|
// })
|
uni.navigateTo({
|
url: `/pages/map/scene?ip=${this.vehicleIp}&opType=create`,
|
events: {
|
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
|
create_finish: function(data) {
|
_this.onCreateSceneOk(data)
|
},
|
}
|
})
|
return
|
}
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
clickDelete() {
|
showModal(`删除场景[${this.sceneId}]会把场景对应的地图任务信息都会删除,是否确认删除?`, "删除场景").then(async (res) => {
|
if (res) {
|
try {
|
uni.showLoading({
|
title: "删除场景中"
|
})
|
this.mapShowAgv = false
|
await delScene(this.vehicleIp, this.sceneId)
|
await this.loadSceneList()
|
if (this.sceneList.length > 0)
|
this.changeMap(this.sceneList[0])
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
}
|
}
|
|
|
|
})
|
},
|
clickManualPlan() {
|
this.mapOperationType = "manual_planning"
|
this.mapOperationStatus = ""
|
},
|
clickVehicleTrajectoryPlan() {
|
this.mapOperationType = "vehicle_trajectory_planning"
|
this.mapOperationStatus = ""
|
},
|
async clickPlanFeasibleRegion() {
|
try {
|
this.mapOperationStatus = "feasible_region"
|
if (this.mapOperationType == "manual_planning") {
|
const agv = await this.loadAgvState()
|
|
const offset = 0.1 * this.curMapInfo.img_proportion
|
this.regionEdit = {
|
|
id: `region_${new Date().getTime()}`,
|
color: "#71d13c",
|
type: "feasible_region",
|
path: [{
|
x: agv.x - offset,
|
y: agv.y - offset
|
}, {
|
x: agv.x - offset,
|
y: agv.y + offset
|
}, {
|
x: agv.x + offset,
|
y: agv.y + offset
|
},
|
{
|
x: agv.x + offset,
|
y: agv.y - offset
|
}
|
]
|
|
}
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_agv_state",
|
param: agv
|
}, {
|
method: "add_region",
|
param: [this.regionEdit]
|
},
|
{
|
method: "move_canvas",
|
param: {
|
x: agv.x,
|
y: agv.y
|
}
|
}
|
])
|
}
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
async clickPlanProhibitionRegion() {
|
try {
|
this.mapOperationStatus = "prohibition_region"
|
if (this.mapOperationType == "manual_planning") {
|
const agv = await this.loadAgvState()
|
const offset = 0.1 * this.curMapInfo.img_proportion
|
this.regionEdit = {
|
id: `region_${new Date().getTime()}`,
|
color: "#ff4d4f",
|
type: "prohibition_region",
|
path: [{
|
x: agv.x - offset,
|
y: agv.y - offset
|
}, {
|
x: agv.x - offset,
|
y: agv.y + offset
|
}, {
|
x: agv.x + offset,
|
y: agv.y + offset
|
},
|
{
|
x: agv.x + offset,
|
y: agv.y - offset
|
}
|
]
|
}
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_agv_state",
|
param: agv
|
}, {
|
method: "add_region",
|
param: [this.regionEdit]
|
},
|
{
|
method: "move_canvas",
|
param: {
|
x: agv.x,
|
y: agv.y
|
}
|
}
|
])
|
}
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
|
async clickPlanVirtualWall() {
|
try {
|
const agv = await this.loadAgvState()
|
const offset = 0.1 * this.curMapInfo.img_proportion
|
|
this.mapOperationStatus = "virtual_wall"
|
this.wallEdit = {
|
id: `wall_${new Date().getTime()}`,
|
color: "#ff4d4f",
|
type: "virtual_wall",
|
path: [{
|
x: agv.x,
|
y: agv.y - offset
|
},
|
{
|
x: agv.x + offset,
|
y: agv.y + offset
|
}
|
]
|
}
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_agv_state",
|
param: agv
|
}, {
|
method: "add_wall",
|
param: [this.wallEdit]
|
},
|
{
|
method: "move_canvas",
|
param: {
|
x: agv.x,
|
y: agv.y
|
}
|
}
|
])
|
} catch (ex) {
|
this.showError(ex)
|
}
|
|
},
|
clickNameCancel() {
|
this.mapOperationType = ''
|
},
|
async clickNameOK() {
|
try {
|
uni.showLoading({
|
title: "更新场景名称"
|
})
|
this.loading = true
|
const name = this.sceneInputName.trim()
|
if (!name) {
|
showToast("场景名称不能为空!")
|
return
|
}
|
console.log(name, this.sceneId)
|
if (name == this.sceneId) {
|
showToast("场景名称未变化!")
|
return
|
}
|
this.mapOperationType = ""
|
await updateScene(this.vehicleIp, this.sceneId, name)
|
this.sceneId = name
|
showToast("场景重命名成功!")
|
} catch (ex) {
|
this.mapOperationType = "edit_scene_name"
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
this.loading = false
|
}
|
|
},
|
|
clickClearName() {
|
this.showClearName = false
|
this.sceneInputName = ""
|
},
|
onInputName(event) {
|
this.sceneInputName = event.detail.value.trim();
|
if (this.sceneInputName)
|
this.showClearName = true
|
else
|
this.showClearName = false
|
},
|
|
closePopuBtn() {
|
|
this.ctxDataStr = JSON.stringify([{
|
method: "set_selectable",
|
param: true
|
}])
|
this.mapOperationType = ""
|
},
|
clickStationDelete() {
|
const _this = this
|
showModal("该站点已绑定任务,删除站点后绑定的任务会停止并删除", "是否确认删除?").then((res) => {
|
if (res) {
|
this.stationDelete(this.stationEdit)
|
}
|
})
|
},
|
async stationAdd(item) {
|
try {
|
uni.showLoading({
|
title: "正在新建站点"
|
})
|
await addStation(this.vehicleIp, item)
|
await updateStation(this.vehicleIp, item)
|
this.stationList.push({
|
stationID: item.stationID,
|
name: item.name,
|
angle: item.angle,
|
x: item.y,
|
y: item.x
|
})
|
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
async stationUpdate(item) {
|
try {
|
uni.showLoading({
|
title: "正在更新站点"
|
})
|
await updateStation(this.vehicleIp, item)
|
const curIndex = this.stationList.findIndex((a) => a.stationID ==
|
item
|
.stationID)
|
if (curIndex > -1) {
|
const station = this.stationList[curIndex]
|
station.name = item.name
|
station.angle = item.angle
|
station.x = item.y
|
station.y = item.x
|
}
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
async clickStationPositonOk() {
|
try {
|
|
if (this.mapOperationType == "add_station") {
|
this.stationAdd(this.stationEdit)
|
} else if (this.mapOperationType == "teaching_add_station") {
|
this.stationAdd(this.stationEdit)
|
this.mapOperationType = "public_teaching"
|
this.mapOperationStatus = "teaching"
|
return
|
} else if (this.mapOperationType == "edit_station") {
|
this.stationUpdate(this.stationEdit)
|
}
|
this.ctxDataStr = JSON.stringify([{
|
method: "set_selectable",
|
param: true
|
}])
|
this.mapOperationType = ''
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
async stationDelete(item) {
|
try {
|
uni.showLoading({
|
title: "正在删除站点"
|
})
|
this.$refs.refPopupOperateStation.close()
|
await delStation(this.vehicleIp, [item.stationID])
|
|
const curIndex = this.stationList.findIndex((a) => a
|
.stationID == item.stationID)
|
if (curIndex > -1) {
|
this.stationList.splice(curIndex, 1)
|
}
|
|
this.mapOperationType = ""
|
this.ctxDataStr = JSON.stringify([{
|
method: "remove_station",
|
param: [item]
|
}, {
|
method: "set_selectable",
|
param: true
|
}])
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
clickStationPostion() {
|
this.mapOperationType = "edit_station"
|
this.mapOperationStatus = "pos"
|
|
|
this.$refs.refPopupOperateStation.close()
|
this.ctxDataStr = JSON.stringify([{
|
method: "edit_station_pos",
|
param: this.stationEdit
|
}])
|
},
|
clickStationRename() {
|
this.mapOperationType = "edit_station"
|
this.mapOperationStatus = ""
|
this.$refs.refPopupOperateStation.close()
|
},
|
clickStationNameCancel() {
|
|
if (this.mapOperationType == "edit_station") {
|
this.ctxDataStr = JSON.stringify([{
|
method: "set_selectable",
|
param: true
|
}])
|
this.mapOperationType = ""
|
this.$refs.refPopupOperateStation.open("bottom")
|
} else if (this.mapOperationType == "add_station") {
|
this.mapOperationType = ""
|
this.ctxDataStr = JSON.stringify([{
|
method: "set_selectable",
|
param: true
|
}])
|
|
} else if (this.mapOperationType == "teaching_add_station") {
|
this.mapOperationType = "public_teaching"
|
this.mapOperationStatus = "teaching"
|
}
|
|
},
|
async clickStationNameOK() {
|
try {
|
this.loading = true
|
const name = this.stationEdit.name.trim()
|
if (!name) {
|
showToast("站点名称还未输入")
|
return
|
}
|
if (this.mapOperationType == 'add_station' || this
|
.mapOperationType == "teaching_add_station") {
|
const agv = await this.loadAgvState()
|
this.stationEdit = {
|
stationID: this.getMaxStationNo + 1,
|
name: name,
|
x: agv.x || 0,
|
y: agv.y || 0,
|
angle: agv.angle || 0,
|
}
|
const angle = this.getStantardAngle(this
|
.stationEdit.angle * 180 / Math.PI)
|
|
this.angleSvg = `/static/images/angle${angle}.svg`
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_agv_state",
|
param: agv
|
}, {
|
method: "update_station",
|
param: [this.stationEdit]
|
}, {
|
method: "edit_station_pos",
|
param: this.stationEdit
|
}, {
|
method: "move_canvas",
|
param: {
|
x: agv.x,
|
y: agv.y
|
}
|
}])
|
this.mapOperationStatus = "pos"
|
} else if (this.mapOperationType ==
|
'edit_station') {
|
this.stationEdit.name = name
|
await updateStation(this.vehicleIp, this
|
.stationEdit)
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_station",
|
param: [this.stationEdit]
|
}, {
|
method: "set_selectable",
|
param: true
|
}])
|
this.mapOperationStatus = "pos"
|
this.$refs.refPopupOperateStation.open("bottom")
|
}
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
this.loading = false
|
}
|
|
},
|
|
clickClearStationName() {
|
this.stationEdit.name = ""
|
this.showClearName = false
|
},
|
onInputStationName(event) {
|
this.stationEdit.name = event.detail.value.trim();
|
if (this.stationEdit.name)
|
this.showClearName = true
|
else
|
this.showClearName = false
|
},
|
onInputStationX(event) {
|
console.log(event)
|
this.stationEdit.x = Number(event.detail.value);
|
console.log(this.stationEdit.x)
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_station",
|
param: [this.stationEdit]
|
}, {
|
method: "move_canvas",
|
param: {
|
x: this.stationEdit.x,
|
y: this.stationEdit.y
|
}
|
}])
|
},
|
|
onInputStationY(event) {
|
this.stationEdit.y = Number(event.detail.value);
|
console.log(this.stationEdit.y)
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_station",
|
param: [this.stationEdit]
|
}, {
|
method: "move_canvas",
|
param: {
|
x: this.stationEdit.x,
|
y: this.stationEdit.y
|
}
|
}])
|
},
|
clickClearStationX() {
|
this.stationEdit.x = 0
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_station",
|
param: [this.stationEdit]
|
}, {
|
method: "move_canvas",
|
param: {
|
x: this.stationEdit.x,
|
y: this.stationEdit.y
|
}
|
}])
|
},
|
clickClearStationY() {
|
this.stationEdit.y = 0
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_station",
|
param: [this.stationEdit]
|
}, {
|
method: "move_canvas",
|
param: {
|
x: this.stationEdit.x,
|
y: this.stationEdit.y
|
}
|
}])
|
},
|
getStantardAngle(angle) {
|
let resAngle = 0
|
if (angle < -157.5) {
|
resAngle = 180
|
} else if (angle < -112.5) {
|
resAngle = -135
|
} else if (angle < -67.5) {
|
resAngle = -90
|
} else if (angle < -22.5) {
|
resAngle = -45
|
} else if (angle < 22.5) {
|
resAngle = 0
|
} else if (angle < 67.5) {
|
resAngle = 45
|
} else if (angle < 112.5) {
|
resAngle = 90
|
} else if (angle < 157.5) {
|
resAngle = 135
|
} else if (angle <= 180) {
|
resAngle = 180
|
} else {
|
resAngle = 0
|
}
|
return resAngle
|
|
},
|
|
touchAngleChange(e) {
|
let angle = 0
|
|
const ptX = e.touches[0].clientX
|
|
const offX = ptX // ptX - e.target.offsetLeft
|
const offW = 300 / 16
|
const centerPt = this.windowWidth / 2
|
if (offX < centerPt - 8 * offW) {
|
return
|
} else if (offX < centerPt - 7 * offW) {
|
angle = 180
|
} else if (offX < centerPt - 5 * offW) {
|
angle = -135
|
} else if (offX < centerPt - 3 * offW) {
|
angle = -90
|
} else if (offX <= centerPt - offW) {
|
angle = -45
|
} else if (offX < centerPt + offW) {
|
angle = 0
|
} else if (offX < centerPt + 3 * offW) {
|
angle = 45
|
} else if (offX < centerPt + 5 * offW) {
|
angle = 90
|
} else if (offX < centerPt + 7 * offW) {
|
angle = 135
|
} else if (offX <= centerPt + 8 * offW) {
|
angle = 180
|
} else {
|
return
|
}
|
this.stationEdit.angle = angle * Math.PI / 180
|
|
|
this.angleSvg = `/static/images/angle${angle}.svg`
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_station",
|
param: [this.stationEdit]
|
}])
|
},
|
handleAngleTouchStart(e) {
|
// console.log("handleAngleTouchStart", e)
|
this.touchAngleChange(e)
|
|
},
|
handleAngleTouchMove(e) {
|
// console.log("handleAngleTouchMove", e)
|
this.touchAngleChange(e)
|
},
|
|
async clickVehiclePosition() {
|
try {
|
const infoAgv = await this.loadAgvState()
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_agv_state",
|
param: infoAgv
|
}, {
|
method: "move_canvas",
|
param: {
|
x: infoAgv.x,
|
y: infoAgv.y
|
}
|
}])
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
async clickPositionStation() {
|
try {
|
const infoAgv = await this.loadAgvState()
|
this.stationEdit.x = infoAgv.x
|
this.stationEdit.y = infoAgv.y
|
this.stationEdit.angle = infoAgv.angle
|
const angle = this.getStantardAngle(this
|
.stationEdit.angle * 180 / Math.PI)
|
console.log(this.stationEdit.angle, angle, this
|
.angleSvg)
|
this.angleSvg =
|
`/static/images/angle${angle}.svg`
|
this.ctxDataStr = JSON.stringify([{
|
method: "update_agv_state",
|
param: infoAgv
|
}, {
|
method: "update_station",
|
param: [this.stationEdit]
|
},
|
{
|
method: "move_canvas",
|
param: {
|
x: infoAgv.x,
|
y: infoAgv.y
|
}
|
}
|
|
|
])
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
async loadTeachingMode() {
|
try {
|
const {
|
data
|
} = await getTeachingMode(this.vehicleIp)
|
return data || {
|
Public: [],
|
Stations: []
|
}
|
|
} catch (ex) {
|
this.showError(ex)
|
return {
|
Public: [],
|
Stations: []
|
}
|
}
|
},
|
async reloadTeachingMode() {
|
try {
|
this.teachingMode = await this.loadTeachingMode()
|
this.ctxDataStr = JSON.stringify([{
|
method: "public_teaching_path",
|
param: this.teachingMode.Public || []
|
},
|
{
|
method: "station_teaching_path",
|
param: this.teachingMode.Stations || []
|
}, {
|
method: "show_teaching_path",
|
param: {
|
show: this.showTeachingPathFlag
|
}
|
}
|
])
|
|
} catch (ex) {
|
this.showError(ex)
|
|
}
|
},
|
|
async clickShowTeachingPath() {
|
try {
|
if (this.showTeachingPathFlag) {
|
this.ctxDataStr = JSON.stringify([{
|
method: "show_teaching_path",
|
param: {
|
show: false
|
}
|
}])
|
this.showTeachingPathFlag = false
|
return
|
}
|
this.showTeachingPathFlag = true
|
//this.teachingMode = await this.loadTeachingMode()
|
this.ctxDataStr = JSON.stringify([
|
// {
|
// method: "clear_teaching_path",
|
|
// },
|
// {
|
// method: "public_teaching_path",
|
// param: this.teachingMode
|
// .Public || []
|
// },
|
// {
|
// method: "station_teaching_path",
|
// param: this.teachingMode
|
// .Stations || []
|
// },
|
{
|
method: "show_teaching_path",
|
param: {
|
show: true
|
}
|
}
|
])
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
async refreshAgvPosition() {
|
try {
|
if (this.isPageVisible && this.mapShowAgv) {
|
const agv = await this.loadAgvState()
|
|
const listCtrData = [{
|
method: "update_agv_state",
|
param: agv
|
}]
|
|
if (this.mapOperationType === "public_teaching" && this.mapOperationStatus ===
|
"teaching") {
|
const list = await this.loadCurrentTeachingData()
|
listCtrData.push({
|
method: "update_current_teaching",
|
param: {
|
main_road: this.teachingModeCur.main_road,
|
pos_list: list
|
}
|
})
|
}
|
this.ctxDataStr = JSON.stringify(listCtrData)
|
}
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
// 无论成功失败,1 秒后再来
|
setTimeout(this.refreshAgvPosition, 1000);
|
}
|
|
},
|
|
askTeachingBiDirection(teachingMode) {
|
showModal("选择当前示教路线类型?", "示教结束", true, "双向路线",
|
"单向路线").then((res) => {
|
if (res) {
|
teachingMode.bidirection = "1"
|
} else {
|
teachingMode.bidirection = "0"
|
}
|
teachingMode.teaching_flag = 0
|
this.finishTeaching(teachingMode)
|
})
|
|
},
|
async finishTeaching(teachingMode) {
|
try {
|
uni.showLoading({
|
title: "示教结束"
|
})
|
await teachingModeFlag(this.vehicleIp,
|
teachingMode)
|
|
this.mapOperationStatus = "end"
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
|
async clickTeachingStart() {
|
|
const _this = this
|
try {
|
uni.showLoading({
|
title: "示教开始"
|
})
|
this.loading = false
|
this.mapOperationStatus = "teaching"
|
await _this.teachingStart("Public")
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
this.loading = false
|
uni.hideLoading()
|
}
|
},
|
clickTeachingEnd() {
|
if (this.mapOperationType ==
|
"station_teaching") {
|
this.teachingEnd("Stations")
|
} else {
|
|
this.teachingEnd("Public")
|
}
|
|
},
|
clickTeachingReset() {
|
const _this = this
|
showModal("已记录的路径将会被删除。", "是否要重新记录?")
|
.then(async (res) => {
|
if (res) {
|
try {
|
this.loading = true
|
await delTeachingMode(_this.vehicleIp, [_this.teachingModeCur])
|
_this.mapOperationStatus = ""
|
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
this.loading = false
|
}
|
} else {
|
|
_this.mapOperationStatus =
|
"save"
|
|
}
|
})
|
|
},
|
async clickTeachingSave() {
|
|
this.mapOperationStatus = "save"
|
try {} catch (ex) {
|
this.showError(ex)
|
}
|
|
},
|
clickTeachingFinish() {
|
this.mapOperationType = ""
|
this.ctxDataStr = JSON.stringify([{
|
method: "teaching_finish",
|
}])
|
this.reloadTeachingMode()
|
|
},
|
async teachingStart(mode) {
|
try {
|
/*if (mode == "Stations") {
|
const res = await checkAgvLocationDistanceError(this.vehicleIp, this.startStationID)
|
if (res?.error) {
|
this.calibratioStationType = "start"
|
this.$refs.refPopupCalibration.open()
|
} else {
|
// const name =
|
// `${ this.stationName(this.startStationID)}_${ this.stationName(this.endStationID)}`
|
|
this.teachingModeCur = {
|
mode: "Stations",
|
src_dst: `${this.startStationID}_${this.endStationID}`,
|
name: "",
|
teaching_flag: 1,
|
}
|
this.ctxDataStr = JSON.stringify([{
|
method: "set_selectable",
|
param: false,
|
}])
|
const res2 = await teachingModeFlag(this.vehicleIp, this.teachingModeCur)
|
if (res2?.name)
|
this.teachingModeCur.name = res2.name
|
}
|
} else {*/
|
|
const main_road = this
|
.teachingModeCur
|
.main_road
|
this.teachingModeCur = {
|
mode: "Public",
|
src_dst: ``,
|
name: "",
|
teaching_flag: 1,
|
main_road
|
}
|
const res2 =
|
await teachingModeFlag(
|
this.vehicleIp,
|
this.teachingModeCur)
|
if (res2?.name) {
|
this.teachingModeCur.name = res2.name
|
}
|
|
} catch (ex) {
|
this.showError(ex)
|
}
|
|
},
|
async teachingEnd(mode) {
|
try {
|
this.loading = true
|
// if (mode == "Stations") {
|
// const res = await checkAgvLocationDistanceError(this.vehicleIp, this.endStationID)
|
// if (res.error) {
|
// this.calibratioStationType = "end"
|
// this.$refs.refPopupCalibration.open()
|
// } else {
|
// this.askTeachingBiDirection(this.teachingModeCur)
|
// }
|
// } else {
|
// this.askTeachingBiDirection(this.teachingModeCur)
|
// }
|
this.askTeachingBiDirection(
|
this
|
.teachingModeCur
|
)
|
} catch (ex) {
|
this.showError(ex)
|
} finally {
|
this.loading = false
|
}
|
|
},
|
async onTeachingModeMainRoad(
|
val) {
|
try {
|
if (this
|
.mapOperationStatus
|
) {
|
|
if (this
|
.teachingModeCur
|
.main_road ==
|
val) {
|
return
|
}
|
this.teachingModeCur
|
.main_road =
|
val
|
this.teachingModeCur
|
.teaching_flag =
|
1
|
this.teachingModeCur
|
.mode =
|
"Public"
|
const res =
|
await teachingModeFlag(
|
this
|
.vehicleIp,
|
this
|
.teachingModeCur
|
)
|
if (val == 0)
|
showToast(
|
"已将该路段路径保存为主路示教路线"
|
)
|
else
|
showToast(
|
"已将该路段路径保存为支路示教路线"
|
)
|
if (res?.name)
|
this
|
.teachingModeCur
|
.name = res
|
.name
|
} else {
|
this.teachingModeCur
|
.main_road =
|
val
|
}
|
|
} catch (ex) {
|
this.showError(ex)
|
}
|
},
|
clickTeachingDelete() {
|
this.$refs
|
.refPopupOperateTeaching
|
.close()
|
this.removeTeachingMode(
|
this
|
.selectTeachingMode
|
)
|
},
|
|
clickTeachingEdit() {
|
this.$refs
|
.refPopupOperateTeaching
|
.close()
|
this.mapOperationType =
|
"edit_teaching"
|
this.ctxDataStr = JSON
|
.stringify([{
|
method: "edit_teaching",
|
param: this.selectTeachingMode,
|
}])
|
},
|
|
async removeTeachingMode(item) {
|
try {
|
uni.showLoading({
|
title: "删除场景中"
|
})
|
await delTeachingMode(this.vehicleIp, [item])
|
this.ctxDataStr =
|
JSON.stringify(
|
[{
|
method: "remove_teaching_path",
|
param: item,
|
}])
|
} catch (ex) {
|
this.showError(
|
ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
async removeTeachingModeData(data) {
|
try {
|
uni.showLoading({
|
title: "删除场景数据中"
|
})
|
await delTeachingModeData(this.vehicleIp, data)
|
this.reloadTeachingMode()
|
} catch (ex) {
|
this.showError(
|
ex)
|
} finally {
|
uni.hideLoading()
|
}
|
},
|
|
showError(ex) {
|
let exStr = JSON.stringify(ex)
|
if (exStr == "{}")
|
exStr = ex
|
let tip = typeof ex.msg == "string" ? ex.msg : typeof ex.errMsg == "string" ? ex.errMsg : exStr
|
showModal(tip,
|
"错误",
|
false,
|
"确定")
|
},
|
|
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.pages-map {
|
display: flex;
|
width: 750rpx;
|
height: 100vh;
|
background-color: #fff;
|
position: relative;
|
|
.uni-navbar-container-inner {
|
display: flex;
|
flex: 1;
|
flex-direction: row;
|
align-items: center;
|
justify-content: center;
|
font-size: 40rpx;
|
overflow: hidden;
|
font-weight: 700;
|
color: #333;
|
|
.icon {
|
width: 30rpx;
|
height: 16rpx;
|
}
|
}
|
|
.uni-nav-bar-text {
|
overflow: hidden;
|
white-space: nowrap;
|
text-overflow: ellipsis;
|
}
|
|
.view-content {
|
position: absolute;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background-color: #ddd;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.map-content {
|
width: 100%;
|
display: flex;
|
flex: 1;
|
margin: auto;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
|
.loading-overlay {
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background-color: rgba(0, 0, 0, 0.5);
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
z-index: 999;
|
|
.loading-content {
|
background-color: #fff;
|
padding: 60rpx 100rpx;
|
border-radius: 20rpx;
|
text-align: center;
|
}
|
|
.loading-spinner {
|
width: 120rpx;
|
height: 120rpx;
|
border: 20rpx solid #f3f3f3;
|
border-top: 20rpx solid #1890FF;
|
border-radius: 50%;
|
animation: spin 1s linear infinite;
|
margin: 0 auto 40rpx;
|
}
|
|
@keyframes spin {
|
0% {
|
transform: rotate(0deg);
|
}
|
|
100% {
|
transform: rotate(360deg);
|
}
|
}
|
|
}
|
|
|
.content {
|
overflow: auto;
|
position: absolute;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
top: 0;
|
|
.fabric {
|
width: 100%;
|
height: 100%;
|
background-color: #fff;
|
}
|
}
|
|
.position {
|
position: absolute;
|
right: 50rpx;
|
bottom: 500rpx;
|
|
.img {
|
width: 65rpx;
|
height: 65rpx;
|
}
|
|
.ico {
|
font-size: 65rpx;
|
color: #1890FF;
|
}
|
}
|
|
.position-site {
|
display: flex;
|
position: absolute;
|
margin: 2rpx;
|
right: 40rpx;
|
bottom: 500rpx;
|
flex-direction: row;
|
padding: 10rpx;
|
border-radius: 10rpx;
|
background-color: #fff;
|
border: 2rpx solid #1890FF;
|
justify-content: center;
|
align-items: center;
|
color: #1890FF;
|
font-size: 32rpx;
|
|
.img {
|
width: 40rpx;
|
height: 40rpx;
|
margin: 0 10rpx;
|
}
|
|
.ico {
|
font-size: 40rpx;
|
color: #1890FF;
|
}
|
}
|
|
.station-info {
|
display: flex;
|
position: absolute;
|
flex-direction: row;
|
border-radius: 10rpx;
|
background-color: #fff;
|
border: 1px solid #1890FF;
|
font-size: 15px;
|
|
.left {
|
display: flex;
|
flex-direction: column;
|
width: 180rpx;
|
color: #aaa;
|
|
.line {
|
padding: 15rpx 5rpx 15rpx 10rpx;
|
}
|
}
|
|
.right {
|
display: flex;
|
flex-direction: column;
|
|
.line {
|
padding: 15rpx 10rpx 15rpx 5rpx;
|
text-align: right;
|
}
|
}
|
}
|
|
.teaching-path-show {
|
position: absolute;
|
right: 50rpx;
|
top: 200rpx;
|
padding: 12rpx;
|
border: 1px solid #1890FF;
|
border-radius: 36rpx;
|
width: 72rpx;
|
height: 72rpx;
|
background-color: #fff;
|
|
.ico {
|
font-size: 40rpx;
|
color: #1890FF;
|
}
|
}
|
|
.selected {
|
background-color: #1890FF20;
|
}
|
|
.station-edit-cancel {
|
position: absolute;
|
color: #F5222D;
|
font-size: 60rpx;
|
}
|
|
.station-edit-ok {
|
position: absolute;
|
color: #52C41A;
|
font-size: 60rpx;
|
}
|
|
.text-button-group {
|
display: flex;
|
width: 100%;
|
justify-content: center;
|
align-items: center;
|
flex-direction: column;
|
font-size: 30rpx !important;
|
|
.button {
|
margin-top: 20rpx;
|
width: 375rpx;
|
}
|
}
|
|
}
|
|
.no-content {
|
margin-top: 50px;
|
padding: 20rpx 40rpx;
|
align-items: center;
|
text-align: center;
|
display: flex;
|
flex-direction: column;
|
font-size: 30rpx;
|
font-weight: 400;
|
background-color: #000fff;
|
|
.title {
|
font-size: 40rpx;
|
margin-bottom: 10rpx;
|
}
|
|
|
}
|
|
.bottom {
|
position: fixed;
|
left: 50rpx;
|
right: 50rpx;
|
bottom: 20rpx;
|
display: flex;
|
|
.bottom-content {
|
display: flex;
|
flex-direction: column;
|
width: 100%;
|
// justify-content: center;
|
// align-items: center;
|
padding: 0 10rpx;
|
padding-bottom: 10rpx;
|
background-color: #fff;
|
border-radius: 10rpx;
|
|
|
.title {
|
font-size: 40rpx;
|
margin-bottom: 10rpx;
|
}
|
|
.tip {
|
color: #888;
|
margin: 10rpx;
|
text-align: left;
|
}
|
|
.row-group {
|
display: flex;
|
flex-direction: row;
|
margin: 10rpx 0;
|
|
}
|
|
.angle-group {
|
padding: 10rpx;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
|
.img-angle {
|
width: 128rpx;
|
height: 42rpx;
|
margin-bottom: 10rpx;
|
}
|
|
.img-angle-pos {
|
width: 300px;
|
height: 64rpx;
|
margin: 10rpx;
|
}
|
|
}
|
|
.coordinate {
|
flex: 1;
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
// .name{
|
// padding: 10rpx 0;
|
|
// }
|
}
|
|
.number-input {
|
flex: 1;
|
background-color: #fff;
|
padding: 10rpx;
|
border-radius: 8rpx;
|
color: #1890FF;
|
}
|
|
|
.name-input {
|
width: calc(100% - 20rpx);
|
margin-bottom: 10rpx;
|
background-color: #fff;
|
padding: 10rpx;
|
border-radius: 8rpx;
|
display: flex;
|
flex-direction: row;
|
color: #1890FF;
|
|
input {
|
flex: 1;
|
}
|
}
|
}
|
|
.img-button-group {
|
display: flex;
|
//width: 100%;
|
flex-direction: row;
|
border-radius: 10px;
|
border: 1px solid #fff;
|
font-size: 30rpx !important;
|
justify-content: space-around;
|
|
.button {
|
margin: 10rpx 10rpx;
|
|
height: 144rpx !important;
|
border: 0;
|
display: flex;
|
flex-direction: column;
|
background-color: #00000000;
|
|
.img {
|
margin: auto;
|
width: 72rpx;
|
height: 72rpx;
|
|
}
|
|
.dashed-line {
|
width: 72rpx;
|
height: 72rpx;
|
border-left: 8rpx dashed #1890FF;
|
/* 设置左侧边框为虚线 */
|
transform: rotate(45deg);
|
/* 旋转45度 */
|
transform-origin: bottom left;
|
/* 设置旋转的基点 */
|
}
|
|
.ico {
|
margin: auto;
|
font-size: 72rpx;
|
color: #1890FF;
|
}
|
|
.text {
|
margin: auto;
|
|
}
|
}
|
|
}
|
|
.text-button-group {
|
display: flex;
|
width: 100%;
|
justify-content: center;
|
align-items: center;
|
flex-direction: column;
|
font-size: 30rpx !important;
|
|
.button {
|
margin: auto;
|
margin-top: 20rpx;
|
width: calc(100% - 10rpx);
|
}
|
}
|
|
.switch-type {
|
width: 100%;
|
align-items: center;
|
vertical-align: middle;
|
|
.switch-button-group {
|
width: 96%;
|
height: 32px;
|
border: 1px solid #dfdfdf;
|
border-radius: 16px;
|
background-color: #dfdfdf;
|
display: flex;
|
flex: row;
|
|
.switch-button {
|
flex: 1;
|
border-radius: 16px;
|
color: #000000A5;
|
height: 32px;
|
line-height: 32px;
|
text-align: center;
|
}
|
|
.switch-button-checked {
|
box-shadow: 0px 2px 8px 0px #0000000C;
|
background-color: #fff;
|
color: #262626;
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.red {
|
color: red !important;
|
}
|
|
.popup-content {
|
display: flex;
|
justify-content: center;
|
flex-direction: column;
|
background-color: transparent;
|
}
|
|
.popup-content-menu {
|
margin-top: 140rpx;
|
margin-left: 225rpx;
|
width: 300rpx;
|
align-items: center;
|
justify-content: center;
|
flex-direction: column;
|
background-color: #fff;
|
border-radius: 5px;
|
border: 1px solid #aaa;
|
}
|
|
.popup-content-menu-item {
|
display: flex;
|
flex-wrap: nowrap;
|
flex-direction: row !important;
|
align-items: center;
|
padding: 8px;
|
font-size: 16px;
|
border-bottom: 1px solid #aaa;
|
|
}
|
|
.popup-content-menu-item:last-child {
|
border-bottom: 0;
|
}
|
|
.popup-content-menu-item:hover {
|
background-color: #eee;
|
}
|
|
.popup-content-btn {
|
margin-bottom: 20rpx;
|
margin-left: 50rpx;
|
width: 600rpx;
|
background-color: #fff;
|
border-radius: 5px;
|
display: flex;
|
|
.img-button-group {
|
display: flex;
|
//width: 100%;
|
flex-direction: row;
|
border-radius: 10px;
|
border: 1px solid #fff;
|
font-size: 30rpx !important;
|
|
margin: auto;
|
|
.button {
|
margin: 10rpx 20rpx;
|
|
height: 144rpx !important;
|
border: 0;
|
display: flex;
|
flex-direction: column;
|
background-color: #00000000;
|
|
.img {
|
margin: auto;
|
width: 72rpx;
|
height: 72rpx;
|
|
}
|
|
.ico {
|
margin: auto;
|
font-size: 72rpx;
|
color: #1890FF;
|
}
|
|
.text {
|
margin: auto;
|
|
}
|
}
|
|
}
|
|
}
|
|
|
}
|
</style>
|