From bcfb05f5e7782ef23e4deb1b38a1ca4b4085181a Mon Sep 17 00:00:00 2001
From: cuiqian2004 <cuiqian2004@163.com>
Date: 星期六, 11 十月 2025 17:09:47 +0800
Subject: [PATCH] test

---
 pages/map/index.vue | 2881 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 2,795 insertions(+), 86 deletions(-)

diff --git a/pages/map/index.vue b/pages/map/index.vue
index 8a606f2..1c35489 100644
--- a/pages/map/index.vue
+++ b/pages/map/index.vue
@@ -1,73 +1,542 @@
 <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 @click="clickBack">
+						<uni-icons type="left" size="24"></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" />
+				<image class="img" src="/images/image_25.png" alt=" 鍥剧墖" mode="aspectFit" />
 				<view class="title">杞﹁締杩炴帴澶辫触</view>
 				<view class="space">璇锋鏌ヤ綘鐨勭綉缁滆缃垨閲嶆柊鍔犺浇</view>
 			</view>
-			<view class="map-content" v-show="!unlinked">
-				<view class="text-button-group">
-					<a-button type="primary" class="button" @click="clickStationList">
-						绔欑偣鍒楄〃
-					</a-button>
-					<a-button type="primary" class="button" @click="clickTeachingList">
-						绀烘暀璺嚎鍒楄〃
-					</a-button>
+			<!-- 	<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 ref="canvasCtx" class="fabric" id="canvasMap" :message="ctxDataStr"
+						:change:message="ctx.receiveMsg">
+					</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" v-if="!unlinked">
+		<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" />
+					<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>
 
-			<view class="bottom-content">
+			<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" />
+							<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" />
+							<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" />
+						<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>姝e湪璁板綍鎼繍杞﹁杩涜矾寰勶紝瀹屾垚鍚庣偣鎸夐挳浠ョ粨鏉熺ず鏁欍�鍦ㄧず鏁欒繃绋嬩腑鍙互娣诲姞绔欑偣銆�/view>
+						<view class="switch-type">鍙殢鏃跺垏鎹㈢ず鏁欐ā寮�+							<view class="switch-button-group">
+								<view class="switch-button"
+									:class="teachingModeCur.mode_type ==0?'switch-button-checked':''"
+									@click="onTeachingModeType(0)">榛樿</view>
+								<view class="switch-button "
+									:class="teachingModeCur.mode_type ==1?'switch-button-checked':''"
+									@click="onTeachingModeType(1)">鍙屽悜</view>
+								<view class="switch-button "
+									:class="teachingModeCur.mode_type ==2?'switch-button-checked':''"
+									@click="onTeachingModeType(2)">鏅鸿兘</view>
+							</view>
+						</view>
+					</view>
+
+					<view v-else>
+						姝e湪璁板綍鎼繍杞﹁杩涜矾寰勶紝瀹屾垚鍚庣偣鎸夐挳浠ョ粨鏉熺ず鏁�+					</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.mode_type ==0?'switch-button-checked':''"
+									@click="onTeachingModeType(0)">榛樿</view>
+								<view class="switch-button "
+									:class="teachingModeCur.mode_type ==1?'switch-button-checked':''"
+									@click="onTeachingModeType(1)">鍙屽悜</view>
+								<view class="switch-button "
+									:class="teachingModeCur.mode_type ==2?'switch-button-checked':''"
+									@click="onTeachingModeType(2)">鏅鸿兘</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 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 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>
+			<uni-popup ref="refPopupTeachingUpdate" type="dialog">
+				<uni-popup-dialog type="info" cancelText="鍙栨秷" confirmText="纭畾" title="绀烘暀鏇存柊"
+					@confirm="dialogTeachingUpdateConfirm" @close="dialogTeachingUpdateClose">
+
+					<view>
+
+						<radio-group @change="radioTeachinMainRoadChange">
+							<label class="radio">
+								<radio :value="1" :checked="selectTeachingMode.main_road == 1" />涓昏矾
+							</label>
+							<label class="radio">
+								<radio :value="0" :checked="selectTeachingMode.main_road != 1" />鏀矾
+							</label>
+						</radio-group>
+
+
+					</view>
+					<view>
+						<radio-group @change="radioTeachinBidirectionChange">
+							<label class="radio">
+								<radio :value="1" :checked="selectTeachingMode.bidirection == 1" />鍙屽悜
+							</label>
+							<label class="radio">
+								<radio :value="0" :checked="selectTeachingMode.bidirection != 1" />鍗曞悜
+							</label>
+						</radio-group>
+
+					</view>
+
+				</uni-popup-dialog>
+			</uni-popup>
+
+
+
+		</view>
 	</view>
 </template>
+<script src="./js/ctx.js" module="ctx" lang="renderjs"></script>
 <script>
 	import {
+		ref
+	} from "vue";
+	import {
 		showToast,
-		showModal
+		showModal,
+		session,
+		showError,
+		showInfo
 	} 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,
+		splitTeachingMode,
+		updateSplitTeachingData,
+		deleteSplitTeachingData
 	} from "@/api/vehicle.js"
 	export default {
 		name: "PagesMap",
 		components: {
-			'a-button': Button
+			'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: [],
-				unlinked: true
+				angleSvg: "/static/images/angle0.svg",
+				windowWidth: 375,
+				bgProgressPercent: 0,
+				bgLoading: false,
+				isMapEdit: false,
+				wallList: [],
+				regionList: [],
+				unlinked: false,
+				showTeachingPathFlag: true,
+				curTeachingPathFlag: 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
+				},
+				positioningAgv: false,
+				isPageVisible: true,
+				destroyFlag: false,
 			}
 		},
 		computed: {
+
 			getMaxStationNo() {
 				let num = 0
 				this.stationList.forEach((item) => {
@@ -79,15 +548,70 @@
 			},
 		},
 		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
+
+		},
+		async onUnload() {
+
+			this.isPageVisible = false
+
+			console.log("onUnload")
+
+
+		},
+		onBackPress() {
+			this.isPageVisible = false
+			if (this.destroyFlag)
+				return false
+			else {
+				this.ctxDataStr = JSON.stringify([{
+					method: "destroy",
+				}])
+				return true
+			}
+
+		},
+
 		methods: {
 			setData(obj) {
 				let that = this;
@@ -112,60 +636,1884 @@
 			},
 			async loadData() {
 				try {
-					const info = await getAgvState(this.vehicleIp)
-					this.setData({
-						unlinked: false
-					})
+					await this.loadSceneList()
+					if (this.sceneList.length > 0) {
+						this.mapOperationType = ''
+						const scene = this.sceneList[0]
+						this.changeMap(scene)
+					} else {
+						uni.navigateBack({
+							delta: 1, //杩斿洖灞傛暟锛�鍒欎笂涓婇〉
+						})
+					}
+					this.refreshAgvPosition()
 				} catch (ex) {
 					this.setData({
 						unlinked: true
 					})
-
+					showError(ex)
 				}
 			},
+
 			clickShowMenu() {
+				// const list = [...this.sceneList]
+				// for(let i =0; i < 20;i++){
+				// 	list.push("test" + i)
+				// }
+				this.menuPopup = {
+					type: "scene",
+					list: this.sceneList,
+					left: 225,
+					top: 140
+				}
 				this.$refs.refPopupMenu.open("top")
 			},
-			clickBack() {
-				uni.navigateBack({
-					delta: 1
-				})
+			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("姝e湪杩涜鍖哄煙瑙勫垝銆�, "鏄惁瑕侀�鍑哄尯鍩熻鍒掞紵").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("姝e湪杩涜鍖哄煙瑙勫垝銆�, "鏄惁瑕侀�鍑哄尯鍩熻鍒掞紵").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) {
+								const listDataStr = []
+								if (this.mapOperationStatus == 'end' || this.mapOperationStatus ==
+									'save') {
+									try {
+										//	await delTeachingMode(this.vehicleIp, [this.teachingModeCur])
+										await deleteSplitTeachingData(this.vehicleIp, this.teachingModeCur
+											.edge_name, this.teachingModeCur.name)
+
+										listDataStr.push({
+											method: "remove_teaching_path",
+											param: {
+												name: this.teachingModeCur.name,
+												mode: "Public"
+											},
+										})
+									} catch (ex) {
+										showError(ex)
+									}
+								}
+								listDataStr.push({
+									method: "teaching_finish",
+								})
+								this.ctxDataStr = JSON.stringify(listDataStr)
+								this.mapOperationType = ""
+							}
+						})
+					} else {
+						this.ctxDataStr = JSON.stringify([{
+							method: "teaching_finish",
+						}])
+
+						this.mapOperationType = ""
+					}
+
+				} else {
+
+					const eventChannel = this.getOpenerEventChannel();
+					eventChannel.emit('check_connect', !this.unlinked);
+					uni.navigateBack({
+						delta: 1
+					})
+				}
 
 			},
-			clickStationList() {
-				uni.navigateTo({
-					url: `/pages/station/index?ip=${this.vehicleIp}`
-				})
+			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)
+				}
 			},
-			clickTeachingList() {
-				uni.navigateTo({
-					url: `/pages/teaching/list?ip=${this.vehicleIp}`
+			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}&opType=create`,
+							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) {
+					showToast(ex)
+					return {}
+				}
+			},
+			async loadCurrentTeachingData() {
+				try {
+					const paths = await getCurrentTeachingData(this.vehicleIp) || []
+					return paths
+				} catch (ex) {
+					showToast(ex)
+					return []
+				}
+			},
+
+			async loadStations() {
+				try {
+					const info = await stations(this.vehicleIp)
+					return info.station_list || []
+				} catch (ex) {
+					showError(ex)
+					return []
+				}
+			},
+			async loadMapInfo(id) {
+				try {
+					const info = await getMapUrl(this.vehicleIp, id)
+					return info
+				} catch (ex) {
+					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,
+						bgLoading: true
+					})
+					const infoAgv = await this.loadAgvState()
+					const stationLst = await this.loadStations()
+
+					const infoMap = await this.loadMapInfo(id)
+					this.curMapInfo = {
+						proportion: parseInt(infoMap.proportion) || 1,
+						img_proportion: parseInt(infoMap.img_proportion) || 1,
+						max_x: parseInt(infoMap.max_x) || 1,
+						max_y: parseInt(infoMap.max_y) || 1,
+						min_x: parseInt(infoMap.min_x) || 0,
+						min_y: parseInt(infoMap.min_y) || 0,
+						img_x: parseInt(infoMap.img_x) || 1,
+						img_y: parseInt(infoMap.img_y) || 1
+					}
+					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: "show_teaching_path",
+							param: {
+								show: this.showTeachingPathFlag
+							}
+						},
+						{
+							method: "public_teaching_path",
+							param: {
+								list: this.teachingMode.Public || [],
+								show: this.showTeachingPathFlag
+							}
+
+						},
+						{
+							method: "station_teaching_path",
+							param: {
+								list: this.teachingMode.Stations || [],
+								show: this.showTeachingPathFlag
+							}
+
+						},
+						{
+							method: "move_pt_center",
+							param: {
+								x: infoAgv.x,
+								y: infoAgv.y
+							}
+						}
+					])
+					this.positioningAgv = true
+					this.mapShowAgv = true
+				} catch (ex) {
+					this.setData({
+						bgProgressPercent: 0,
+						bgLoading: false
+					})
+					showError(ex)
+				}
+			},
+
+			receiveRenderData(param) {
+				console.log('鎺ユ敹鍒拌鍥惧眰鐨勬暟鎹細', param);
+				if (param.method === "destroy_complete") {
+					if (param.param) {
+						this.destroyFlag = true
+						uni.navigateBack({
+							delta: 1
+						})
+					}
+				} else if (param.method == "set_backgroud_progress") {
+					if (param.type == "start") {
+						this.setData({
+							bgProgressPercent: 50,
+							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,
+					}
+					const angle = this.getStantardAngle(this.stationEdit.angle * 180 / Math.PI)
+
+					this.angleSvg = `/static/images/angle${angle}.svg`
+					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`
+							if (this.mapOperationType == "teaching_add_station") {
+								this.positioningAgv = true
+							}
+							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"
+							this.positioningAgv = true
+						} 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",
+							edge_name: param.data?.edge_name || "",
+							name: param.data?.name || "",
+							point: param.point,
+							main_road: param.data?.main_road || 0,
+							bidirection: param.data?.name || 0,
+						}
+					}
+					this.$refs.refPopupOperateTeaching.open("bottom")
+				} else if (param.method == "cancel_positioning_agv") {
+					if (this.mapOperationType == "public_teaching" &&
+						this.mapOperationStatus == "teaching") {
+						this.positioningAgv = true
+					} else
+						this.positioningAgv = false
+				} else if (param.method == "show_log") {
+					const listLog = session.getValue("request_log") || []
+					listLog.unshift(param.data)
+					session.setValue("request_log", listLog)
+				}
 			},
 			clickMapStation() {
-				uni.navigateTo({
-					url: `/pages/station/index?ip=${this.vehicleIp}&isAdd=1`
-				})
+				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() {
+				const _this = this
 				uni.navigateTo({
-					url: `/pages/map/edit?ip=${this.vehicleIp}`
+					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/map/task?ip=${this.vehicleIp}`
+					url: `/pages/task/list?ip=${this.vehicleIp}`
 				})
 			},
+			clickTeaching() {
+				this.mapOperationStatus = ""
+				this.teachingModeCur = {
+					mode: "Public",
+					mode_type: 0,
+				}
+				this.positioningAgv = true
+				this.mapOperationType = "public_teaching"
+				this.ctxDataStr = JSON.stringify([{
+					method: "public_teaching",
+				}])
 
-			showError(ex) {
-				let exStr = JSON.stringify(ex)
-				if (exStr == "{}")
-					exStr = ex
-				let tip = typeof ex.msg == "string" ? ex.msg : exStr
-				showModal(tip, "閿欒", false)
+				// 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 {
+
+
+					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}`,
+						// 	events: {
+						// 		// 涓烘寚瀹氫簨浠舵坊鍔犱竴涓洃鍚櫒锛岃幏鍙栬鎵撳紑椤甸潰浼犻�鍒板綋鍓嶉〉闈㈢殑鏁版嵁
+						// 		create_finish: function(data) {
+						// 			_this.onCreateSceneOk(data)
+						// 		},
+						// 	}
+						// })
+						uni.navigateBack({
+							delta: 1, //杩斿洖灞傛暟锛�鍒欎笂涓婇〉
+						})
+						return
+					}
+
+				} catch (ex) {
+					showError(ex)
+				}
+			},
+			clickDelete() {
+				const _this = this
+				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])
+							// else {
+							// 	_this.mapOperationType = ""
+							// 	setTimeout(() => {
+							// 		uni.navigateBack({
+							// 			delta: 1, //杩斿洖灞傛暟锛�鍒欎笂涓婇〉
+							// 		})
+							// 	}, 500)
+
+							// }
+						} catch (ex) {
+							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_pt_center",
+								param: {
+									x: agv.x,
+									y: agv.y
+								}
+							}
+						])
+					}
+				} catch (ex) {
+					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_pt_center",
+								param: {
+									x: agv.x,
+									y: agv.y
+								}
+							}
+						])
+					}
+				} catch (ex) {
+					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_pt_center",
+							param: {
+								x: agv.x,
+								y: agv.y
+							}
+						}
+					])
+				} catch (ex) {
+					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
+					}
+					const curIndex = this.sceneList.findIndex((param) => param == this.sceneId)
+					this.mapOperationType = ""
+					await updateScene(this.vehicleIp, this.sceneId, name)
+
+
+					this.sceneId = name
+					if (curIndex > -1) {
+						this.sceneList[curIndex] = name
+					}
+					this.setData({
+						navigationBarTitle: name
+					})
+					showToast("鍦烘櫙閲嶅懡鍚嶆垚鍔燂紒")
+				} catch (ex) {
+					this.mapOperationType = "edit_scene_name"
+					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
+				uni.navigateTo({
+					url: `/pages/station/delete?ip=${ this.vehicleIp}`,
+					events: {
+						// 涓烘寚瀹氫簨浠舵坊鍔犱竴涓洃鍚櫒锛岃幏鍙栬鎵撳紑椤甸潰浼犻�鍒板綋鍓嶉〉闈㈢殑鏁版嵁
+						delete_finish: function(data) {
+							console.log(data)
+							const list = data.map((a) => {
+								return {
+									stationID: a
+								}
+
+							})
+							_this.ctxDataStr = JSON.stringify([{
+								method: "remove_station",
+								param: list
+							}])
+						}
+					}
+				})
+				//this.stationDelete(this.stationEdit)
+				// const _this = this
+				// showModal("璇ョ珯鐐瑰凡缁戝畾浠诲姟锛屽垹闄ょ珯鐐瑰悗缁戝畾鐨勪换鍔′細鍋滄骞跺垹闄�, "鏄惁纭鍒犻櫎锛�).then((res) => {
+				// 	if (res) {
+
+				// 	}
+				// })
+			},
+			async stationAdd(item) {
+				try {
+					uni.showLoading({
+						title: "姝e湪鏂板缓绔欑偣"
+					})
+					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) {
+					showError(ex)
+				} finally {
+					uni.hideLoading()
+				}
+			},
+			async stationUpdate(item) {
+				try {
+					uni.showLoading({
+						title: "姝e湪鏇存柊绔欑偣"
+					})
+					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) {
+					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"
+						this.positioningAgv = true
+						return
+					} else if (this.mapOperationType == "edit_station") {
+						this.stationUpdate(this.stationEdit)
+					}
+					this.ctxDataStr = JSON.stringify([{
+						method: "set_selectable",
+						param: true
+					}])
+					this.mapOperationType = ''
+				} catch (ex) {
+					showError(ex)
+				}
+			},
+			async stationDelete(item) {
+				try {
+					uni.showLoading({
+						title: "姝e湪鍒犻櫎绔欑偣"
+					})
+					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) {
+					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 {
+
+					const name = this.stationEdit.name.trim()
+					if (!name) {
+						showToast("绔欑偣鍚嶇О杩樻湭杈撳叆")
+						return
+					}
+					this.loading = true
+					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_pt_center",
+							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) {
+					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_pt_center",
+					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_pt_center",
+					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_pt_center",
+					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_pt_center",
+					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 {
+					this.positioningAgv = true
+					const infoAgv = await this.loadAgvState()
+					this.ctxDataStr = JSON.stringify([{
+						method: "update_agv_state",
+						param: infoAgv
+					}, {
+						method: "move_pt_center",
+						param: {
+							x: infoAgv.x,
+							y: infoAgv.y
+						}
+					}])
+				} catch (ex) {
+					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_pt_center",
+							param: {
+								x: infoAgv.x,
+								y: infoAgv.y
+							}
+						}
+
+
+					])
+				} catch (ex) {
+					showError(ex)
+				}
+			},
+			async loadTeachingMode() {
+				try {
+					const {
+						data
+					} = await splitTeachingMode(this.vehicleIp)
+					return data || {
+						Public: [],
+						Stations: []
+					}
+
+				} catch (ex) {
+					showError(ex)
+					return {
+						Public: [],
+						Stations: []
+					}
+				}
+			},
+			async reloadTeachingMode(finish) {
+				try {
+					this.teachingMode = await this.loadTeachingMode()
+
+					const list = [{
+							method: "clear_teaching_path",
+						},
+						{
+							method: "public_teaching_path",
+							param: {
+								list: this.teachingMode.Public || [],
+								show: this.showTeachingPathFlag
+							}
+						},
+						{
+							method: "station_teaching_path",
+							param: {
+								list: this.teachingMode.Stations || [],
+								show: this.showTeachingPathFlag
+							}
+						}
+
+					]
+					if (finish) {
+						list.push({
+							method: "teaching_finish",
+						})
+					}
+					this.ctxDataStr = JSON.stringify(list)
+
+				} catch (ex) {
+					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) {
+					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: 1, //this.teachingModeCur.main_road,
+								pos_list: list
+							}
+						})
+						if (list.length > 0) {
+							this.curTeachingPathFlag = true
+						} else {
+							if (this.curTeachingPathFlag) {
+								this.curTeachingPathFlag = false
+								const teaching = await this.loadTeachingMode()
+
+								const publicOld = this.teachingMode.Public || []
+								const stationOld = this.teachingMode.Stations || []
+								const publicNew = teaching.Public || []
+								const stationNew = teaching.Stations || []
+								const publicAdd = []
+								const stationAdd = []
+								for (let i in publicNew) {
+									const item = publicNew[i]
+									const curIndex = publicOld.findIndex((a) => a.name == item.name)
+									console.log(curIndex, item)
+									if (curIndex < 0) {
+										publicAdd.push(item)
+										publicOld.push(item)
+									}
+
+								}
+								for (let i in stationNew) {
+									const item = stationNew[i]
+									const curIndex = stationOld.findIndex((a) => a.name == item.name)
+									if (curIndex < 0) {
+										stationAdd.push(item)
+										stationOld.push(item)
+									}
+
+								}
+								this.teachingMode.Public = publicOld
+								this.teachingMode.Stations = stationOld
+
+								if (publicAdd.length > 0) {
+									listCtrData.push({
+										method: "public_teaching_path",
+										param: {
+											list: publicAdd,
+											show: this.showTeachingPathFlag
+										}
+									})
+								}
+								if (stationAdd.length > 0) {
+									listCtrData.push({
+										method: "station_teaching_path",
+										param: {
+											list: stationAdd,
+											show: this.showTeachingPathFlag
+										}
+									})
+								}
+							}
+						}
+
+						// }
+
+						if (this.positioningAgv) {
+							if (this.curTeachingPathFlag) {
+								listCtrData.push({
+									method: "move_pt_center",
+									param: {
+										x: agv.x,
+										y: agv.y,
+									}
+								})
+
+							} else {
+								listCtrData.push({
+									method: "move_pt_visible",
+									param: {
+										x: agv.x,
+										y: agv.y,
+										width: 80,
+										height: 80,
+									}
+								})
+
+							}
+						}
+
+						this.ctxDataStr = JSON.stringify(listCtrData)
+					}
+					//setTimeout(this.refreshAgvPosition, 1000);
+				} catch (ex) {
+					// showError(ex).then((res) => {
+
+					// })
+					showToast(ex)
+				} finally {
+					// 鏃犺鎴愬姛澶辫触锛� 绉掑悗鍐嶆潵
+					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) {
+					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) {
+					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])
+								await deleteSplitTeachingData(_this.vehicleIp, _this.teachingModeCur.edge_name,
+									_this.teachingModeCur.name)
+								_this.mapOperationStatus = ""
+								const listDataStr = []
+								listDataStr.push({
+									method: "remove_teaching_path",
+									param: {
+										name: _this.teachingModeCur.name,
+										mode: "Public"
+									},
+								})
+								_this.ctxDataStr = JSON.stringify(listDataStr)
+
+
+							} catch (ex) {
+								showError(ex)
+							} finally {
+								this.loading = false
+							}
+						} else {
+
+							_this.mapOperationStatus = "save"
+
+						}
+					})
+
+			},
+			async clickTeachingSave() {
+
+				this.mapOperationStatus = "save"
+				try {} catch (ex) {
+					showError(ex)
+				}
+
+			},
+			clickTeachingFinish() {
+				this.mapOperationType = ""
+
+				//this.reloadTeachingMode(true)
+
+			},
+			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 mode_type = this
+						.teachingModeCur
+						.mode_type
+					this.teachingModeCur = {
+						mode: "Public",
+						src_dst: ``,
+						name: "",
+						teaching_flag: 1,
+						mode_type
+					}
+					const res2 =
+						await teachingModeFlag(
+							this.vehicleIp,
+							this.teachingModeCur)
+					if (res2?.name) {
+						this.teachingModeCur.name = res2.name
+					}
+
+				} catch (ex) {
+					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
+					// )
+					this.teachingModeCur.teaching_flag = 0
+					await this.finishTeaching(this.teachingModeCur)
+				} catch (ex) {
+					showError(ex)
+				} finally {
+					this.loading = false
+				}
+
+			},
+			async onTeachingModeType(val) {
+				try {
+					if (this.mapOperationStatus) {
+
+						if (this.teachingModeCur.mode_type == val) {
+							return
+						}
+						this.teachingModeCur.teaching_flag = 0
+						const oldName = this.teachingModeCur.name
+						await teachingModeFlag(this.vehicleIp, this.teachingModeCur)
+						this.teachingModeCur.mode_type = val
+						this.teachingModeCur.teaching_flag = 1
+						this.teachingModeCur.mode = "Public"
+						this.teachingModeCur.name = ""
+						const res = await teachingModeFlag(this.vehicleIp, this.teachingModeCur)
+						if (val == 1)
+							showToast("宸插皢绀烘暀鍒囨崲鎴愬弻鍚戞ā寮�)
+						else if (val == 2)
+							showToast("宸插皢绀烘暀鍒囨崲鎴愭櫤鑳芥ā寮�)
+						else
+							showToast("宸插皢绀烘暀鍒囨崲鎴愰粯璁ゆā寮�)
+						/*if (val == 0)
+							showToast(
+								"宸插皢璇ヨ矾娈佃矾寰勪繚瀛樹负涓昏矾绀烘暀璺嚎"
+							)
+						else
+							showToast(
+								"宸插皢璇ヨ矾娈佃矾寰勪繚瀛樹负鏀矾绀烘暀璺嚎"
+							)
+						if (res?.name)
+							this.teachingModeCur.name = res.name
+
+						const {
+							data
+						} = await splitTeachingMode(this.vehicleIp)
+
+						const publicList = data.Public || []
+						const curIndex = publicList.findIndex((a) => a.name == oldName)
+
+						if (curIndex > -1) {
+							this.ctxDataStr = JSON.stringify([{
+								method: "public_teaching_path",
+								param: {
+									list: [publicList[curIndex]],
+									show: true
+								}
+							}])
+
+						}
+*/
+
+					} else {
+						this.teachingModeCur.mode_type = val
+					}
+
+				} catch (ex) {
+					showError(ex)
+				}
+			},
+			clickTeachingDelete() {
+				this.$refs
+					.refPopupOperateTeaching
+					.close()
+				this.removeTeachingMode(
+					this
+					.selectTeachingMode
+				)
+			},
+
+			clickTeachingEdit() {
+				this.$refs.refPopupOperateTeaching.close()
+				this.$refs.refPopupTeachingUpdate.open("")
+
+				// this.mapOperationType =
+				// 	"edit_teaching"
+				// this.ctxDataStr = JSON
+				// 	.stringify([{
+				// 		method: "edit_teaching",
+				// 		param: this.selectTeachingMode,
+				// 	}])
+			},
+			radioTeachinMainRoadChange(e) {
+				this.selectTeachingMode.main_road = evt.detail.value
+			},
+			radioTeachinBidirectionChange(evt) {
+				this.selectTeachingMode.bidirection = evt.detail.value
+			},
+			async dialogTeachingUpdateConfirm() {
+				try {
+					uni.showLoading({
+						title: "鏇存柊绀烘暀涓�
+					})
+					const item = this.selectTeachingMode
+					await updateSplitTeachingData(this.vehicleIp, item)
+					this.ctxDataStr =
+						JSON.stringify(
+							[{
+								method: "update_teaching",
+								param: item,
+							}])
+					this.selectTeachingMode = {}
+					showToast("鏇存柊绀烘暀鎴愬姛")
+				} catch (ex) {
+					showError(
+						ex)
+				} finally {
+					uni.hideLoading()
+				}
+			},
+			dialogTeachingUpdateClose() {
+				this.$refs.refPopupTeachingUpdate.close()
+
+			},
+
+			async removeTeachingMode(item) {
+				try {
+					uni.showLoading({
+						title: "鍒犻櫎绀烘暀涓�
+					})
+					await deleteSplitTeachingData(this.vehicleIp, item.edge_name, item.name)
+					//await delTeachingMode(this.vehicleIp, [item])
+					this.ctxDataStr =
+						JSON.stringify(
+							[{
+								method: "remove_teaching_path",
+								param: item,
+							}])
+					showToast("鍒犻櫎绀烘暀鎴愬姛")
+				} catch (ex) {
+					showError(
+						ex)
+				} finally {
+					uni.hideLoading()
+				}
+			},
+			async removeTeachingModeData(data) {
+				try {
+					uni.showLoading({
+						title: "鍒犻櫎绀烘暀鏁版嵁涓�
+					})
+					await deleteSplitTeachingData(this.vehicleIp, data.edge_name, data.name)
+					//await delTeachingModeData(this.vehicleIp, data)
+					showToast("鍒犻櫎绀烘暀鎴愬姛")
+					this.reloadTeachingMode()
+				} catch (ex) {
+					showError(ex)
+				} finally {
+					uni.hideLoading()
+				}
+			},
 
 		}
 	}
@@ -208,6 +2556,7 @@
 			left: 0;
 			right: 0;
 			bottom: 0;
+			background-color: #ddd;
 			display: flex;
 			flex-direction: column;
 		}
@@ -217,6 +2566,174 @@
 			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;
@@ -225,14 +2742,12 @@
 				align-items: center;
 				flex-direction: column;
 				font-size: 30rpx !important;
-				background-color: #eee;
 
 				.button {
 					margin-top: 20rpx;
 					width: 375rpx;
 				}
 			}
-
 
 		}
 
@@ -245,6 +2760,7 @@
 			flex-direction: column;
 			font-size: 30rpx;
 			font-weight: 400;
+			background-color: #000fff;
 
 			.title {
 				font-size: 40rpx;
@@ -271,51 +2787,189 @@
 				padding-bottom: 10rpx;
 				background-color: #fff;
 				border-radius: 10rpx;
-			}
 
 
+				.title {
+					font-size: 40rpx;
+					margin-bottom: 10rpx;
+				}
 
-		}
+				.tip {
+					color: #888;
+					margin: 10rpx;
+					text-align: left;
+				}
 
-		.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 20rpx;
-
-				height: 144rpx !important;
-				border: 0;
-				display: flex;
-				flex-direction: column;
-				background-color: #00000000;
-
-				.img {
-					margin: auto;
-					width: 72rpx;
-					height: 72rpx;
+				.row-group {
+					display: flex;
+					flex-direction: row;
+					margin: 10rpx 0;
 
 				}
 
-				.ico {
-					margin: auto;
-					font-size: 72rpx;
+				.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;
 				}
 
-				.text {
+
+				.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: #1890FF;
+
+					}
 
 				}
+
 			}
 
 		}
 
+
+
+		.red {
+			color: red !important;
+		}
 
 		.popup-content {
 			display: flex;
@@ -325,15 +2979,17 @@
 		}
 
 		.popup-content-menu {
-			margin-top: 75px;
-			margin-left: 120px;
-			width: 150px;
+			margin-top: 140rpx;
+			margin-left: 225rpx;
+			width: 300rpx;
+			max-height: 50vh;
+			overflow: auto;
 			align-items: center;
 			justify-content: center;
 			flex-direction: column;
 			background-color: #fff;
 			border-radius: 5px;
-			border: 1px solid gray;
+			border: 1px solid #aaa;
 		}
 
 		.popup-content-menu-item {
@@ -341,16 +2997,69 @@
 			flex-wrap: nowrap;
 			flex-direction: row !important;
 			align-items: center;
-			padding: 4px 8px;
+			padding: 8px;
 			font-size: 16px;
+			border-bottom: 1px solid #aaa;
 
-			.img {
-				width: 20px;
-				height: 20px;
-				margin: 5px;
-			}
 		}
 
+		.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;
+
+					}
+				}
+
+			}
+
+		}
 
 
 	}

--
Gitblit v1.9.1