<template>
	<view class="page-container">
		<u-navbar title="订单详情" :border-bottom="false" :background="{ backgroundColor: '#fff' }" title-color='#333'
			title-size='34' height='44'></u-navbar>
		
		<!-- 地图区域 -->
		<view class="map-wrapper">
			<map class="map" id="map" ref="map" :scale="zoomSize" :latitude="latitude" :longitude="longitude"
				:show-location="true" :markers="markers" :polyline="polyline" :polygons="polygon" :enable-zoom="true"
				:enable-scroll="true">
				<cover-view hover-class="app-tap-hover" class="map-ctrl-btn park-btn" @click="toggleIconAndCallout">
					<cover-image class="img" src="https://lxnapi.ccttiot.com/bike/img/static/uRiYQZQEb3l2LsltEsyW"></cover-image>
				</cover-view>
				<cover-view hover-class="app-tap-hover" class="map-ctrl-btn track-btn" @click="toTrack" v-if="orderxqobj.status != 'CANCELED'">
					<cover-image class="img" src="https://lxnapi.ccttiot.com/bike/img/static/ufaAAtlirJYs1QwJF25P"></cover-image>
				</cover-view>
			</map>
		</view>

		<!-- 订单概览卡片 -->
		<view class="info-card overview-card" style="">
			<view class="card-header">
				<view class="order-no-box" style="display: flex; align-items: center;">
					<text class="value">{{orderxqobj.no}}</text>
					<zhima-no-deposit-badge v-if="orderxqobj.payChannelApiType === ChannelApiType.ZHIMA_DEPOSIT_ONLY.value" style="margin-left: 12rpx;" />
				</view>
				<view class="status-tag" :class="{
					'processing': orderxqobj.status == 'PROCESSING',
					'finished': orderxqobj.status == 'FINISHED',
					'canceled': orderxqobj.status == 'CANCELED'
				}">
					<text v-if="orderxqobj.status == 'PROCESSING'">进行中</text>
					<text v-if="orderxqobj.status == 'FINISHED'">已完成</text>
					<text v-if="orderxqobj.status == 'CANCELED'">已取消</text>
				</view>
			</view>
			
			<view class="data-grid">
				<view class="data-item">
					<view class="data-val price">￥{{orderxqobj.actualReceivedAmount || '0.00'}}</view>
					<view class="data-label">实收金额</view>
				</view>
				<view class="data-item">
					<view class="data-val">{{formattedDuration}}</view>
					<view class="data-label">骑行时长</view>
				</view>
				<view class="data-item">
					<view class="data-val">{{kmDistance}}<text class="unit">km</text></view>
					<view class="data-label">骑行距离</view>
				</view>
			</view>

			<view class="divider"></view>

			<view class="detail-list">
				<view class="list-item">
					<text class="label">开始时间</text>
					<text class="value">{{orderxqobj.startTime || '--'}}</text>
				</view>
				<view class="list-item">
					<text class="label">超时状态</text>
					<text class="value">{{orderxqobj.timeout ? '有超时' : '无超时'}}</text>
				</view>
				<view class="list-item">
					<text class="label">用户信息</text>
					<view class="value-row">
						<text>{{orderxqobj.userName}}</text>
						<text hover-class="app-tap-hover" class="phone-link" @click="checkbtn(1)">{{orderxqobj.userPhone}}</text>
					</view>
				</view>
				<view class="list-item">
					<text class="label">套餐名称</text>
					<text class="value highlight">{{orderxqobj.suitName}}</text>
				</view>
				<view class="list-item">
					<text class="label">支付方式</text>
					<text class="value">{{orderxqobj.payType == 1 ? '押金抵扣' : '用户支付'}}</text>
				</view>
			</view>
		</view>

		<!-- 费用明细卡片 -->
		<view class="info-card">
			<view class="card-title-bar">
				<view class="bar-mark"></view>
				<text class="title-text">费用明细</text>
			</view>
			<view class="fee-list">
				<view class="list-item">
					<text class="label">骑行费</text>
					<text class="value">￥{{orderxqobj.ridingFee}}</text>
				</view>
				<view class="list-item">
					<text class="label">调度费</text>
					<text class="value">￥{{orderxqobj.dispatchFee}}</text>
				</view>
				<view class="list-item">
					<text class="label">管理费</text>
					<text class="value">￥{{orderxqobj.manageFee}}</text>
				</view>
				<view class="list-item" v-if="showOrderInsureFee">
					<text class="label">应收保险费</text>
					<text class="value">￥{{ insureFeeDisplay }}</text>
				</view>
				<view class="list-item border-dashed">
					<text class="label">车损费</text>
					<text class="value">￥{{orderxqobj.deductionFee}}</text>
				</view>
				<view class="damage-display-block" v-if="orderDamageImages.length">
					<text class="damage-display-title">车损图片</text>
					<view class="damage-display-grid">
						<image hover-class="app-tap-hover"
							v-for="(dimg, dix) in orderDamageImages"
							:key="dix"
							:src="dimg"
							mode="aspectFill"
							class="damage-display-thumb"
							@click="previewOrderDamage(dimg)"
						></image>
					</view>
				</view>
				<view class="verify-remark-block" v-if="hasVerifyRemark">
					<text class="verify-remark-title">还车审核备注</text>
					<text class="verify-remark-text">{{ orderxqobj.verifyRemark }}</text>
				</view>
				
				<view class="summary-section">
					<view class="list-item sm">
						<text class="label">结算金额</text>
						<text class="value">￥{{orderxqobj.totalFee}}</text>
					</view>
					<view class="list-item sm">
						<text class="label">优惠</text>
						<text class="value">￥{{orderxqobj.totalDiscountAmount}}</text>
					</view>
					<view class="list-item sm">
						<text class="label">退款</text>
						<text class="value text-red">￥{{orderxqobj.adminRefundAmount}}</text>
					</view>
				</view>

				<view class="total-pay">
					<text class="label">实付金额</text>
					<text class="price">￥{{orderxqobj.actualReceivedAmount}}</text>
				</view>
			</view>
		</view>

		<!-- 车辆信息卡片 -->
		<view class="info-card vehicle-card">
			<view class="card-title-bar">
				<view class="bar-mark"></view>
				<text class="title-text">车辆信息</text>
			</view>
			<view class="vehicle-list">
				<view class="vehicle-item" v-for="(item,index) in processedOrderDeviceList" :key="index">
					<!-- 车辆头部信息 -->
					<view hover-class="app-tap-hover" class="vehicle-header" @click.stop="btntz(item.deviceId)">
						<view class="vehicle-header-left">
							<view class="vehicle-badge" :class="index==0 ? 'badge-primary' : 'badge-secondary'">
								<view class="badge-dot"></view>
								<text class="badge-text">{{index == 0 ? '初始车辆' : '更换车辆'}}</text>
							</view>
							<view class="vehicle-time-info">
								<text class="time-label">开始时间</text>
								<text class="time-value">{{item.startTime || '--'}}</text>
							</view>
						</view>
						<view class="vehicle-arrow">
							<u-icon name="arrow-right" color="#C0C4CC" size="20"></u-icon>
						</view>
					</view>
					
					<!-- 车辆详细信息 -->
					<view hover-class="app-tap-hover" class="vehicle-details" @click.stop="btntz(item.deviceId)">
						<view class="detail-grid">
							<view class="detail-item">
								<text class="detail-label">SN编号</text>
								<text class="detail-value">{{item.deviceSn || '--'}}</text>
							</view>
							<view class="detail-item">
								<text class="detail-label">MAC</text>
								<text class="detail-value">{{item.deviceMac || '--'}}</text>
							</view>
							<view class="detail-item">
								<text class="detail-label">车牌号</text>
								<text class="detail-value highlight">{{item.deviceVehicleNum || '--'}}</text>
							</view>
							<view class="detail-item">
								<text class="detail-label">车型</text>
								<text class="detail-value">{{item.deviceModelName || '--'}}</text>
							</view>
						</view>
						
						<view class="time-info-section">
							<view class="time-item">
								<view class="time-icon start"></view>
								<view class="time-content">
									<text class="time-title">开锁时间</text>
									<text class="time-desc">{{item.startTime || '--'}}</text>
								</view>
							</view>
							<view class="time-item">
								<view class="time-icon end"></view>
								<view class="time-content">
									<text class="time-title">结束时间</text>
									<text class="time-desc">{{item.endTime || '--'}}</text>
								</view>
							</view>
						</view>
					</view>

					<!-- 检查视频/图片区域 -->
					<view class="media-section" v-if="item.checkVideo || item.finishPicture">
						<view class="media-item" v-if="item.checkVideo">
							<view class="media-header">
								<view class="media-icon start-icon"></view>
								<text class="media-title">开始前检查</text>
							</view>
							<view class="media-wrapper">
								<video class="media-video" :src="item.checkVideo" controls></video>
							</view>
						</view>
						<view class="media-item" v-if="item.finishPicture">
							<view class="media-header">
								<view class="media-icon end-icon"></view>
								<text class="media-title">结束前检查</text>
							</view>
							<view class="media-wrapper">
								<video class="media-video" :src="item.finishPicture" controls></video>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>

		<!-- 最后订单信息 -->
		<view class="info-card" v-if="deviceInfos.etOrders && deviceInfos.etOrders[0] && deviceInfos.sn">
			<view class="card-title-bar">
				<view class="bar-mark"></view>
				<text class="title-text">最后订单信息</text>
			</view>
			<view class="detail-list">
				<view class="list-item">
					<text class="label">用户姓名</text>
					<text class="value">{{deviceInfos.etOrders[0].realName || '--'}}</text>
				</view>
				<view class="list-item">
					<text class="label">用户电话</text>
					<text class="value">{{deviceInfos.etOrders[0].phonenumber || '--'}}</text>
				</view>
				<view class="list-item">
					<text class="label">订单编号</text>
					<text class="value">{{deviceInfos.etOrders[0].orderNo || '--'}}</text>
				</view>
				<view class="list-item">
					<text class="label">开始时间</text>
					<text class="value">{{deviceInfos.etOrders[0].createTime || '--'}}</text>
				</view>
				<view class="list-item">
					<text class="label">订单状态</text>
					<text class="value">{{statuss()}}</text>
				</view>
			</view>
		</view>

		<view class="footer-spacer" v-if="showFooterBar"></view>

		<!-- 底部操作栏（含待审核时固定的「通过审核」） -->
		<view class="footer-bar" v-if="showFooterBar">
			<view class="btn-group" :class="{ 'btn-group--audit': orderxqobj.status == 'WAIT_VERIFY' }">
				<view hover-class="app-tap-hover" class="btn btn-audit" v-if="orderxqobj.status == 'WAIT_VERIFY'" @click="unpass">
					<u-icon name="checkmark-circle" color="#fff" size="18" style="margin-right: 8rpx;"></u-icon>
					<text>审核</text>
				</view>
				<view hover-class="app-tap-hover" class="btn btn-outline" v-if="orderxqobj.status == 'FINISHED'" @click="checkbtn(0)">退款</view>
				<view hover-class="app-tap-hover" class="btn btn-primary" v-if="orderxqobj.status == 'RIDE_WAIT_PAY'" @click="btngaijia">改价</view>
				<view hover-class="app-tap-hover" class="btn btn-primary" v-if="orderxqobj.status == 'RIDE_WAIT_PAY'" @click="btnyajin">押金抵扣</view>
				<view hover-class="app-tap-hover" class="btn btn-outline" v-if="orderxqobj.priceChanged == true" @click="btnjilu">改价记录</view>
				<view hover-class="app-tap-hover" class="btn btn-primary" @click="btnhuanbike" v-if="orderxqobj.status=='PROCESSING'">辅助换车</view>
				<view hover-class="app-tap-hover" class="btn btn-primary" @click="btnfuzhu" v-if="orderxqobj.status=='PROCESSING'">辅助还车</view>
			</view>
		</view>

		<!-- 各种弹窗保留原有逻辑 -->
		<u-mask hover-class="app-tap-hover" :show="false" @click="show = false" :z-index='100' />
		<u-mask :show="maskloading" :z-index='100' duration='0' />
		<view class="maskloadpage" v-if="maskloading">
			<view class="maskpage1" v-if="maskepage==4">
				<view class="top_info">
					<image :src="loadimg" mode=""></image>
					<view class="masktxt">
						{{buletxt}}
					</view>
				</view>
				<view class="masktips" style="width: 100%;">
					请确保与车辆的距离小于3米
				</view>
				<view class="tipsimg">
					<image src="https://lxnapi.ccttiot.com/bike/img/static/ugvqmfB3QYujZ6SnfTia" mode=""></image>
				</view>
			</view>
			<!-- 不允许停车点外还车 -->
			<view class="maskpage1" v-if="maskepage==5">
				<view class="top_info">
					<image src="https://lxnapi.ccttiot.com/bike/img/static/uG3cbPgvPDzwlq6IHHxK" mode=""></image>
					<view class="masktxt" v-if="orderinfo.sn">
						蓝牙连接失败
					</view>
				</view>
				<view class="masktips" style="width: 100%;">
					请确保手机蓝牙已经打开
				</view>
				<view class="tipsimg">
					<image src="https://lxnapi.ccttiot.com/bike/img/static/ugvqmfB3QYujZ6SnfTia" mode=""></image>
				</view>
				<view class="btn_box">
					<view hover-class="app-tap-hover" class="btn4" @click="closemask()">
						返回
					</view>
					<view hover-class="app-tap-hover" class="btn3" @click="Binddevice">
						重新连接
					</view>
				</view>
			</view>
		</view>
		<u-mask hover-class="app-tap-hover" :show="showvehicle" @click="closevehicle()" :z-index='100' />
		<view class="tip_box" v-if="showvehicle">
			<view class="top" v-if="showvehicle">
				<view class="tip">
					设备信息修改
				</view>
				<view class="ipt_box">
					<view class="text">
						车牌号
					</view>
					<view class="ipt">
						<input type="text" v-model="vehicleNum" placeholder=" " class="input"
							placeholder-style="color:#C7CDD3">
					</view>
				</view>
			</view>
			<view class="bots">
				<view hover-class="app-tap-hover" class="bot_left" @click="closevehicle()">
					取消
				</view>
				<view hover-class="app-tap-hover" class="bot_right" @click="putvehicle()">
					确定
				</view>
			</view>
		</view>
		<u-mask hover-class="app-tap-hover" :show="showqr" @click="closeQr()" :z-index='100' />
		<view class="tip_box" v-if="showqr">
			<view class="ewm" style="padding-top: 50rpx;">
				<canvas id="qrcode" canvas-id="qrcode" style="width: 350rpx;height:350rpx;margin-left: 164rpx;" />
			</view>
			<view hover-class="app-tap-hover" class="saveQr" @click="saveQrcode()">
				保存二维码
			</view>
		</view>
		<u-mask hover-class="app-tap-hover" :show="showbtntip" @click="closevehicle()" :z-index='100' />
		<view class="tip_box" v-if="showbtntip">
			<view class="top" v-if="showbtntip">
				<view class="tip">
					操作提示
				</view>
				<view class="ipt_box" style="justify-content: center;">
					<view class="text" style="width: 80%;text-align: center;">
						车辆有正在进行中的订单，是否进行该操作
					</view>
				</view>
			</view>
			<view class="bots">
				<view hover-class="app-tap-hover" class="bot_left" @click="closeshowtip() ">
					取消
				</view>
				<view hover-class="app-tap-hover" class="bot_right" @click="btn(btnnum)">
					确定
				</view>
			</view>
		</view>
		<u-select v-model="showModelList" :list="ModelList" title='修改车型' @confirm="confirm"></u-select>

		<view class="zengsongone huanche-verify-modal" v-if="huancheflag">
			<view class="tops">还车审核</view>
			<scroll-view scroll-y class="huanche-verify-scroll">
				<view class="huanche-field-label">车损费</view>
				<input class="huanche-field-input" type="digit" v-model="price" placeholder="请输入车损费" />
				<view class="huanche-field-label">车损图片 <text class="huanche-sub">(最多9张)</text></view>
				<view class="verify-damage-upload-wrap">
					<view hover-class="app-tap-hover"
						class="verify-damage-item"
						v-for="(img, vidx) in damageImageList"
						:key="'done-' + vidx"
						@click="previewVerifyDamage(vidx)"
					>
						<image :src="img" mode="aspectFill"></image>
						<view hover-class="app-tap-hover" class="verify-damage-del" @click.stop="removeVerifyDamage(vidx)">×</view>
					</view>
					<view
						class="verify-damage-item verify-damage-item-uploading"
						v-for="item in damageImageUploadingList"
						:key="'up-' + item.uid"
					>
						<image :src="item.tempPath" mode="aspectFill"></image>
						<view class="verify-damage-upload-mask">
							<u-loading mode="circle" size="28" color="#ffffff"></u-loading>
							<text class="verify-damage-upload-mask-text">上传中</text>
						</view>
					</view>
					<view hover-class="app-tap-hover"
						class="verify-damage-add"
						v-if="damageImageList.length + damageImageUploadingList.length < 9"
						@click="chooseVerifyDamageImages"
					>
						<u-icon name="plus" size="36" color="#999"></u-icon>
						<text>{{ damageImageList.length + damageImageUploadingList.length }}/9</text>
					</view>
				</view>
				<view class="huanche-field-label">备注</view>
				<input class="huanche-field-input" type="text" v-model="beizhu" placeholder="请输入备注" />
			</scroll-view>
			<view class="anniu">
				<view hover-class="app-tap-hover" class="qx" @click="btnqx">取消</view>
				<view hover-class="app-tap-hover"
					class="qd"
					:class="{ 'qd-disabled': damageImageUploadingList.length > 0 }"
					@click="btnqd"
				>确定</view>
			</view>
		</view>
		<view class="maskone" v-if="huancheflag"></view>
		
		<view class="zengsong refund-modal" v-if="tkflag">
			<view class="refund-modal__header">
				<view class="refund-modal__head-text">
					<text class="refund-modal__title">订单退款</text>
					<text class="refund-modal__desc">在右侧填写退款金额，不得超过左侧实收金额</text>
				</view>
			</view>
			<view class="refund-table__head">
				<text class="col-name">费用项目</text>
				<text class="col-refund">退款(元)</text>
			</view>
			<view
				class="refund-table__row"
				:class="{ 'refund-table__row--disabled': isRefundRowDisabled('riding') }"
			>
				<text class="col-name">骑行费</text>
				<text class="col-original">￥{{ formatRefundMoney(getRefundOriginal('riding')) }}</text>
				<input
					v-if="!isRefundRowDisabled('riding')"
					class="col-refund-input"
					type="digit"
					v-model="qxfei"
					placeholder="填退款"
				/>
				<text v-else class="col-refund-placeholder">—</text>
			</view>
			<view
				class="refund-table__row"
				:class="{ 'refund-table__row--disabled': isRefundRowDisabled('dispatch') }"
			>
				<text class="col-name">调度费</text>
				<text class="col-original">￥{{ formatRefundMoney(getRefundOriginal('dispatch')) }}</text>
				<input
					v-if="!isRefundRowDisabled('dispatch')"
					class="col-refund-input"
					type="digit"
					v-model="ddfei"
					placeholder="填退款"
				/>
				<text v-else class="col-refund-placeholder">—</text>
			</view>
			<view
				class="refund-table__row"
				:class="{ 'refund-table__row--disabled': isRefundRowDisabled('manage') }"
			>
				<text class="col-name">管理费</text>
				<text class="col-original">￥{{ formatRefundMoney(getRefundOriginal('manage')) }}</text>
				<input
					v-if="!isRefundRowDisabled('manage')"
					class="col-refund-input"
					type="digit"
					v-model="glfei"
					placeholder="填退款"
				/>
				<text v-else class="col-refund-placeholder">—</text>
			</view>
			<view
				class="refund-table__row"
				:class="{ 'refund-table__row--disabled': isRefundRowDisabled('deduction') }"
			>
				<text class="col-name">车损费</text>
				<text class="col-original">￥{{ formatRefundMoney(getRefundOriginal('deduction')) }}</text>
				<input
					v-if="!isRefundRowDisabled('deduction')"
					class="col-refund-input"
					type="digit"
					v-model="csfei"
					placeholder="填退款"
				/>
				<text v-else class="col-refund-placeholder">—</text>
			</view>
			<view class="refund-reason">
				<text class="refund-reason__label">退款原因</text>
				<input
					class="refund-reason__input"
					type="text"
					v-model="yuanyin"
					placeholder="请填写退款原因（必填）"
				/>
			</view>
			<view class="refund-total">
				<text class="refund-total__label">本次退款合计</text>
				<text class="refund-total__amount">￥{{ totalRefund }}</text>
			</view>
			<view class="anniu">
				<view hover-class="app-tap-hover" class="qx" @click="qxqx">取消</view>
				<view hover-class="app-tap-hover" class="qd refund-modal__confirm" @click="btntuikuan">确认退款</view>
			</view>
		</view>
		<view style="background-color: rgba(0, 0, 0, .5);width: 100%;height: 100vh;position: fixed;top: 0;left: 0;z-index: 11;"	v-if="tkflag"></view>

		<!-- 退款二次确认 -->
		<view class="refund-confirm-mask" v-if="refundConfirmFlag" @click="closeRefundConfirm"></view>
		<view class="refund-confirm-dialog" v-if="refundConfirmFlag">
			<view class="refund-confirm-dialog__title">确认退款</view>
			<view class="refund-confirm-dialog__content">
				<view class="refund-confirm-dialog__line1">
					<text class="refund-confirm-dialog__text">本次将退款</text>
					<text class="refund-confirm-dialog__amount">￥{{ totalRefund }}</text>
				</view>
				<view class="refund-confirm-dialog__line2">确定要执行退款吗？</view>
			</view>
			<view class="refund-confirm-dialog__actions">
				<view hover-class="app-tap-hover" class="refund-confirm-dialog__btn refund-confirm-dialog__btn--cancel" @click="closeRefundConfirm">取消</view>
				<view hover-class="app-tap-hover" class="refund-confirm-dialog__btn refund-confirm-dialog__btn--ok" @click="confirmRefundSubmit">确定</view>
			</view>
		</view>
		
		<!-- 辅助还车是否收取调度费 -->
		<view class="diaodu" v-if="ddflag">
			<view hover-class="app-tap-hover" class="top" @click="btncha">
				×
			</view>
			<view class="cen">
				该车辆未在停车区还车，是否收取调度费{{fuzhuobj.manageFee > 0 ? fuzhuobj.manageFee : fuzhuobj.dispatchFee > 0 ? fuzhuobj.dispatchFee : ''}}元？
			</view>
			<view class="anniu">
				<view hover-class="app-tap-hover" class="bu" @click="btnfuzhus(false)">
					不收取
				</view>
				<view hover-class="app-tap-hover" class="shou" @click="btnfuzhus(true)">
					收取
				</view>
			</view>
		</view>
		<view class="mask" v-if="ddflag">
		</view>

		<!-- 改价弹窗 -->
		<view class="zengsong" v-if="zengsongflag">
			<view class="tops">
				改价
			</view>
			<view class="gai">
				<view class="">
					骑行费
				</view>
				<input type="text" v-model="orderxqobj.ridingFee" :disabled="true" style="background-color: #efefef;"
					placeholder="请输入骑行费" /> >
				<input type="text" v-model="qxfei" placeholder="请输入骑行费" />
			</view>
			<view class="gai">
				<view class="">
					调度费
				</view>
				<input type="text" v-model="orderxqobj.dispatchFee" :disabled="true" style="background-color: #efefef;"
					placeholder="请输入调度费" /> >
				<input type="text" v-model="ddfei" placeholder="请输入调度费" />
			</view>
			<view class="gai">
				<view class="">
					管理费
				</view>
				<input type="text" v-model="orderxqobj.manageFee" :disabled="true" style="background-color: #efefef;"
					placeholder="请输入管理费" /> >
				<input type="text" v-model="glfei" placeholder="请输入管理费" />
			</view>
			<view class="gai">
				<view class="">
					改价原因
				</view>
				<input type="text" style="width:440rpx;" v-model="yuanyin" placeholder="请输入改价原因" />
			</view>
			<view class="anniu">
				<view hover-class="app-tap-hover" class="qx" @click="qxqx">
					取消
				</view>
				<view hover-class="app-tap-hover" class="qd" @click="qdqd">
					确定
				</view>
			</view>
		</view>
		<view style="background-color: rgba(0, 0, 0, .5);width: 100%;height: 100vh;position: fixed;top: 0;left: 0;z-index: 999;"
			v-if="zengsongflag"></view>
			
		<!-- 押金抵扣弹窗 -->
		<view class="yajindikou" style="z-index: 999;" v-if="yajinyajin">
			<view class="tops">
				押金抵扣
			</view>
		    <view class="aaaa">即将进行押金抵扣，请确认</view>
		    <view class="aaaa">抵扣金额：{{ orderxqobj.totalFee == undefined ? '--' : orderxqobj.totalFee}} 元</view>
		    <view class="aaaa">剩余可抵扣押金：{{ orderxqobj.depositDeductRemain == undefined ? '--' : orderxqobj.depositDeductRemain}} 元</view>
		    <view class="aaaa">若押金不足，则收取最大可抵扣金额</view>
			<view class="anniu">
				<view hover-class="app-tap-hover" class="qx" @click="yjqxqx">
					取消
				</view>
				<view hover-class="app-tap-hover" class="qd" @click="yjqdqd">
					确定
				</view>
			</view>
		</view>
		<view style="background-color: rgba(0, 0, 0, .5);width: 100%;height: 100vh;position: fixed;top: 0;left: 0;z-index: 998;"
			v-if="yajinyajin"></view>
			
		<!-- 辅助换车弹窗 -->
		<view class="change-bike-modal" v-if="showChangeBike">
			<view class="modal-header">
				<view class="modal-title">辅助换车</view>
				<view hover-class="app-tap-hover" class="modal-close" @click="closeChangeBike">×</view>
			</view>
			<view class="modal-content">
				<!-- 目标设备信息 -->
				<view class="form-section">
					<view class="form-item">
						<view class="form-label">
							<text class="label-text">设备SN</text>
						</view>
						<view class="input-with-scan">
							<view hover-class="app-tap-hover" class="scan-icon" @click="scanDeviceSn">
								<u-icon name="scan" color="#4C97E7" size="32"></u-icon>
							</view>
							<input 
								class="form-input-with-icon" 
								type="text" 
								v-model="selectedDeviceSn" 
								placeholder="请输入设备SN或点击左侧扫码" 
							/>
						</view>
					</view>
				</view>

				<!-- 换车原因 -->
				<view class="form-section">
					<view class="section-title">换车原因<text class="required">*</text></view>
					<picker 
						mode="selector" 
						:range="reasonOptions" 
						range-key="label" 
						:value="reasonIndex" 
						@change="onReasonChange"
					>
						<view class="picker-item">
							<text :class="['picker-text', !changeReason && 'placeholder']">
								{{ changeReason ? (changeReason === 'LOW_POWER' ? '电量不足' : '车辆损坏') : '请选择换车原因' }}
							</text>
							<u-icon name="arrow-right" color="#C0C4CC" size="18"></u-icon>
						</view>
					</picker>
				</view>

				<!-- 故障信息（仅当选择车辆损坏时显示） -->
				<view class="form-section" v-if="changeReason === 'DEVICE_FAULT'">
					<view class="form-item">
						<view class="form-label">
							<text class="label-text">故障原因</text>
							<text class="label-tip">（可选）</text>
						</view>
						<textarea 
							class="form-textarea" 
							v-model="faultDetail" 
							placeholder="请输入故障原因描述" 
							maxlength="200"
							:auto-height="true"
						></textarea>
					</view>
					<view class="form-item">
						<view class="form-label">
							<text class="label-text">故障图片</text>
							<text class="label-tip">（可选）</text>
						</view>
						<view class="upload-container">
							<view class="upload-preview" v-if="faultPicture">
								<image hover-class="app-tap-hover" 
									class="preview-image" 
									:src="faultPicture" 
									mode="aspectFill"
									@click="previewFaultImage"
								></image>
								<view hover-class="app-tap-hover" class="delete-btn" @click="deleteFaultImage">
									<u-icon name="close" color="#fff" size="14"></u-icon>
								</view>
							</view>
							<view hover-class="app-tap-hover" class="upload-btn" v-else @click="uploadFaultImage">
								<u-icon name="camera" color="#4C97E7" size="32"></u-icon>
								<text class="upload-text">上传图片</text>
							</view>
						</view>
					</view>
				</view>
			</view>
			<view class="modal-footer">
				<view hover-class="app-tap-hover" class="footer-btn cancel-btn" @click="closeChangeBike">取消</view>
				<view hover-class="app-tap-hover" class="footer-btn confirm-btn" @click="confirmChangeBike">确定换车</view>
			</view>
		</view>
		<view style="background-color: rgba(0, 0, 0, .5);width: 100%;height: 100vh;position: fixed;top: 0;left: 0;z-index: 999;"
			v-if="showChangeBike"></view>
		<qiniu-upload-progress />
	</view>
</template>

<script>
	const app = getApp()
	var xBlufi = require("@/components/blufi/xBlufi.js")
	import { ChannelApiType } from '@/common/enums/channel'
	import { normalizeLocationLogList, toPolylinePointList } from '@/common/trackMapUtil.js'
import ZhimaNoDepositBadge from '@/components/zhima-no-deposit-badge/zhima-no-deposit-badge.vue'

	let _this = null
	export default {
		components: { ZhimaNoDepositBadge },
		data() {
			return {
				ChannelApiType,
				tcindex:1,
				yajinyajin:false,
				huancheflag:false,
				beizhu:'',
				qxfei: 0,
				ddfei: 0,
				glfei: 0,
				csfei:0,
				yuanyin: '',
				zengsongflag: false,
				devicesList: [],
				searching: false,
				btnflag: true,
				tishiflag: false,
				option: '',
				bluthlist: [], //蓝牙数组
				statusflag: false,
				Bluetoothmac: '',
				mac: '',
				ishave: false,
				ver_data: null,
				deviceInfoss: {},
				gps: {},
				isband: false,
				deviceIds: '',
				name: '',
				orderinfo: {},
				dl: 0,
				czmoney: true,
				iscz: true,
				bgc: {
					backgroundColor: "#fff",
				},
				show: true,
				showgj: true,
				searchKeyword: '11',
				latitude: '',
				longitude: '',
				isMap: false,
				zoomSize: 15,
				markers: [], // 标记点数组
				polyline: [], // 轨迹折线数组
				polygon: [], // 用于存储区域多边形
				cardId: '001区域',
				sn: '',
				deviceInfos: {},
				carstause: false,

				maskloading: false,
				toploadtxt: "开锁中0%",
				loadimg: 'https://lxnapi.ccttiot.com/bike/img/static/urJQJnOI1DEjWatFqHYh',
				tiptxt: '请定点停放，规范用车',
				maskepage: 0,
				backgps: {},
				buletxt: '',
				flagdiaodu: false,
				buleclose: false,
				buleopen: false,
				bulering: false,
				bulerebort: false,
				getnum: 0,
				showvehicle: false,
				vehicleNum: '',
				showbtntip: false,
				btnnum: null,
				showqr: false,
				canvasWidth: 300,
				deptId: null,
				showModelList: false,
				ModelList: [],
				jytxt: '开',
				orid: '',
				orderxqobj: {
					distance: 0
				},
				tkflag: false,
				refundConfirmFlag: false,
				amount: '',
				orderDeviceList: [],
				suitSeconds: '',

				currentPolyline: [],
				trackPoints: [], // 存储轨迹点数据
				tkje: true,

				ddflag: false,
				fuzhuobj: {},
				price:0,
				youhuiobj:{},
				kstime:'',
				endtime:'',
				// 换车相关
				showChangeBike: false,
				changeDeviceList: [],
				selectedDeviceId: '',
				selectedDeviceSn: '',
				changeReason: '', // LOW_POWER 或 DEVICE_FAULT
				faultDetail: '',
				faultPicture: '',
				reasonOptions: [
					{ label: '电量不足', value: 'LOW_POWER' },
					{ label: '车辆损坏', value: 'DEVICE_FAULT' }
				],
				reasonIndex: -1,
				qiniuToken: '', // 七牛云上传token
				damageImageList: [], // 还车审核弹窗车损图（已上传完成的 URL）
				damageImageUploadingList: [], // 上传中：{ tempPath, uid }
				/** 任一未完成操作时锁住底部与其它并行按钮；仅在解锁后方可新开链路（防抖多重请求 / 多窗） */
				orderActionBusy: false,
				verifyAuditBusy: false,
				/** 改价确定 / 押金抵扣确定：防双击重复提交 */
				priceSubmitting: false,
				deductSubmitting: false,
				changeBikeConfirming: false,
				auxReturnBusy: false
			}
		},
		onLoad(e) {
			if(e.id){
				this.sn = e.id
			}
			this.kstime = e.ksitem
			this.endtime = e.endTime == null ? this.formatCurrentTime() : e.endTime
			console.log(e);
			this.orid = e.orid
			this.getorderxq()
			this.deptId = uni.getStorageSync('deptId')
			this.getyouhui()
		},
		onUnload: function() {
			xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent)
			xBlufi.notifyStartDiscoverBle({
				'isStart': false
			})
		},
		onHide() {
			xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent)
			xBlufi.notifyStartDiscoverBle({
				'isStart': false
			})
		},
		onBeforeUnmount() {
			xBlufi.listenDeviceMsgEvent(false, this.funListenDeviceMsgEvent)
			xBlufi.notifyStartDiscoverBle({
				'isStart': false
			})
		},
		watch: {

		},
		computed: {
			totalRefund() {
				return (
					Number(this.qxfei || 0) +
					Number(this.ddfei || 0) +
					Number(this.glfei || 0) +
					Number(this.csfei || 0)
				).toFixed(2)
			},
			formattedDuration() {
				// 获取开始时间（必须存在）
				const startTime = this.orderxqobj?.startTime ? new Date(this.orderxqobj.startTime) : null;
				if (!startTime || isNaN(startTime.getTime())) return '00:00:00';

				// 获取结束时间（若为null则用当前时间）
				const endTime = this.orderxqobj?.endTime ?
					new Date(this.orderxqobj.endTime) :
					new Date();
				if (isNaN(endTime.getTime())) return '00:00:00';

				// 计算时间差（毫秒）
				const diffMs = endTime - startTime;
				if (diffMs < 0) return '00:00:00'; // 结束时间早于开始时间

				// 转换为秒并格式化
				const diffSeconds = Math.floor(diffMs / 1000);
				return this.formatSecondsToHMS(diffSeconds);
			},
			// 使用计算属性来进行渲染换车
			processedOrderDeviceList() {
				return this.orderDeviceList.map(item => ({
					...item,
					pictures: item.finishPicture ? item.finishPicture.split(',') : []
				}))
			},
			kmDistance() {
				return (this.orderxqobj?.distance / 1000).toFixed(2);
			},
			formattedPayedAmount() {
				// 默认值处理
				const payedAmount = parseFloat(this.orderxqobj?.payedAmount) || 0;
				const payRefunded = parseFloat(this.orderxqobj?.payRefunded) || 0;
				const payRefunding = parseFloat(this.orderxqobj?.payRefunding) || 0;
				// 计算实际金额
				const actualAmount = payedAmount - (payRefunded + payRefunding);
				// 确保是合法数字，并格式化为 ￥XX.XX
				return `￥${isNaN(actualAmount) ? '0.00' : actualAmount.toFixed(2)}`;
			},
			showFooterBar() {
				const o = this.orderxqobj
				if (!o || !o.status) return false
				const s = o.status
				return (
					s === 'WAIT_VERIFY' ||
					s === 'FINISHED' ||
					s === 'RIDE_WAIT_PAY' ||
					s === 'PROCESSING' ||
					o.priceChanged === true
				)
			},
			orderDamageImages() {
				const urls = this.orderxqobj && this.orderxqobj.damageImageUrls
				if (!urls || typeof urls !== 'string') return []
				return urls.split(',').map((x) => x.trim()).filter(Boolean)
			},
			hasVerifyRemark() {
				const r = this.orderxqobj && this.orderxqobj.verifyRemark
				if (r == null) return false
				return String(r).trim().length > 0
			},
			/** 从订单详情接口解析应收保险费（兼容多字段名与字符串） */
			orderInsureFeeParsed() {
				const o = this.orderxqobj
				if (!o) return null
				const keys = [
					'insureFee',
					'actualInsureFee',
					'insuranceFee',
					'expectInsureFee',
					'insure_fee',
					'actual_insure_fee'
				]
				let raw
				for (let i = 0; i < keys.length; i++) {
					const v = o[keys[i]]
					if (v !== undefined && v !== null && v !== '') {
						raw = v
						break
					}
				}
				if (raw === undefined) return null
				if (typeof raw === 'object' && raw !== null) {
					const inner = raw.amount != null ? raw.amount : raw.value
					if (inner !== undefined && inner !== null && inner !== '') raw = inner
					else return null
				}
				let s = String(raw).replace(/,/g, '').trim()
				s = s.replace(/^￥\s*/, '').replace(/\s*元\s*$/, '')
				const n = parseFloat(s)
				return Number.isFinite(n) ? n : null
			},
			/** 有有效金额时展示（非 0） */
			showOrderInsureFee() {
				const n = this.orderInsureFeeParsed
				return n !== null && n !== 0
			},
			insureFeeDisplay() {
				const n = this.orderInsureFeeParsed
				return n !== null ? n.toFixed(2) : '0.00'
			}
		},
		methods: {
			toastIfOrderBusy() {
				if (this.orderActionBusy) {
					uni.showToast({ title: '操作进行中，请稍候', icon: 'none', duration: 1200 })
					return true
				}
				return false
			},

			formatCurrentTimes() {
			  const date = new Date();
			  const year = date.getFullYear();
			  const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始，补0
			  const day = String(date.getDate()).padStart(2, '0');
			  const hours = String(date.getHours()).padStart(2, '0');
			  const minutes = String(date.getMinutes()).padStart(2, '0');
			  const seconds = String(date.getSeconds()).padStart(2, '0');
			  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
			},
			getyouhui(){
				let data = {
					orderId:this.orid,
				}
				this.$u.post(`/app/order/calcRideFee`,data).then(res =>{
					if(res.code == 200){
						this.youhuiobj = res.data
					}
				})
			},
			btnqx() {
				this.huancheflag = false
				this.damageImageList = []
				this.damageImageUploadingList = []
				this.orderActionBusy = false
				this.verifyAuditBusy = false
			},
			previewOrderDamage(current) {
				uni.previewImage({
					current,
					urls: this.orderDamageImages
				})
			},
			async chooseVerifyDamageImages() {
				if (this.damageImageUploadingList.length > 0) {
					uni.showToast({ title: '请等待当前图片上传完成', icon: 'none' })
					return
				}
				const remain = 9 - this.damageImageList.length - this.damageImageUploadingList.length
				if (remain <= 0) return
				uni.chooseImage({
					count: remain,
					sizeType: ['compressed'],
					sourceType: ['album', 'camera'],
					success: async (res) => {
						if (!res.tempFilePaths || !res.tempFilePaths.length) return
						const paths = res.tempFilePaths
						const uids = paths.map(() => String(this.$u.guid(16)))
						paths.forEach((tempPath, i) => {
							this.damageImageUploadingList.push({ tempPath, uid: uids[i] })
						})
						try {
							const valid = []
							for (let i = 0; i < paths.length; i++) {
								const url = await this.uploadVerifyDamageFile(paths[i])
								if (url) valid.push(url)
							}
							this.damageImageUploadingList = this.damageImageUploadingList.filter(
								(x) => !uids.includes(x.uid)
							)
							this.damageImageList = this.damageImageList.concat(valid).slice(0, 9)
							if (valid.length) {
								uni.showToast({ title: '上传成功', icon: 'success' })
							} else if (paths.length) {
								uni.showToast({ title: '图片上传失败，请重试', icon: 'none' })
							}
						} catch (e) {
							this.damageImageUploadingList = this.damageImageUploadingList.filter(
								(x) => !uids.includes(x.uid)
							)
							uni.showToast({ title: '部分图片上传失败', icon: 'none' })
						}
					}
				})
			},
			async uploadVerifyDamageFile(filePath) {
				const math = 'static/' + this.$u.guid(20)
				try {
					return await this.$uploadQiniuFile({
						filePath,
						key: 'bike/img/' + math,
						title: '上传车损图片',
						showProgress: true
					})
				} catch (e) {
					return ''
				}
			},
			removeVerifyDamage(index) {
				this.damageImageList.splice(index, 1)
			},
			previewVerifyDamage(index) {
				uni.previewImage({
					current: this.damageImageList[index],
					urls: this.damageImageList
				})
			},
			// 通过审核
			btnqd(){
				if (this.verifyAuditBusy) {
					return
				}
				if (this.damageImageUploadingList.length > 0) {
					uni.showToast({ title: '请等待图片上传完成', icon: 'none' })
					return
				}
				this.verifyAuditBusy = true
				uni.showLoading({
					title:'加载中...'
				})
				let data = {
					id:this.orderxqobj.id,
					deductionFee:this.price,
					remark:this.beizhu,
					damageImageUrls: this.damageImageList.length ? this.damageImageList.join(',') : ''
				}
				this.$u.put('/bst/order/verify', data).then((res) => {
					if (res.code === 200) {
						uni.showToast({
							title: '审核成功',
							icon: 'success',
							duration: 2000
						})
						this.huancheflag = false
						this.price = 0
						this.beizhu = ''
						this.damageImageList = []
						this.damageImageUploadingList = []
						setTimeout(()=>{
							this.deviceInfo()
							this.getorderxq()
						},1000)
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {}).finally(() => {
					uni.hideLoading()
					this.verifyAuditBusy = false
					this.orderActionBusy = false
				})
			},
			
			
			btntcindex(num){
				this.tcindex = num
			},
			btnjilu(){
				if (this.toastIfOrderBusy()) return
				uni.navigateTo({
					url:'/page_user/gaijiajilu?id=' + this.orid
				})
			},
			// 点击进行押金抵扣
			btnyajin(){
				if (this.toastIfOrderBusy()) return
				this.orderActionBusy = true
				this.yajinyajin = true
			},
			yjqxqx(){
				this.yajinyajin = false
				this.orderActionBusy = false
				this.deductSubmitting = false
			},
			yjqdqd(){
				if (this.deductSubmitting) return
				this.deductSubmitting = true
				let fee = this.youhuiobj
				let data = {
					id:this.orid,
					fee
				}
				this.$u.put('/bst/order/deduct', data).then(res=>{
					if(res.code == 200) {
						uni.showToast({
							title: '抵扣成功',
							icon: 'success',
							duration: 2000
						})
						this.yajinyajin = false
						this.deviceInfo()
						this.getorderxq()
					}else{
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {}).finally(() => {
					this.deductSubmitting = false
					this.orderActionBusy = false
				})
			},
			// 点击进行改价
			btngaijia() {
				if (this.toastIfOrderBusy()) return
				this.orderActionBusy = true
				this.zengsongflag = true
			},
			// 点击确定改价
			qdqd() {
				if (this.priceSubmitting) return
				this.priceSubmitting = true
				let data = {
					id: this.orid,
					ridingFee: this.qxfei == '' ? this.orderxqobj.ridingFee : this.qxfei,
					dispatchFee: this.ddfei == '' ? this.orderxqobj.dispatchFee : this.ddfei,
					manageFee: this.glfei == '' ? this.orderxqobj.manageFee : this.glfei,
					reason: this.yuanyin
				}
				this.$u.put('/bst/order/updatePrice', data).then((res) => {
					if (res.code === 200) {
						this.zengsongflag = false
						uni.showToast({
							title: '改价成功',
							icon: 'success',
							duration: 2000
						})
						this.qxfei = ''
						this.ddfei = ''
						this.glfei = ''
						this.yuanyin = ''
						this.deviceInfo()
						this.getorderxq()
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {}).finally(() => {
					this.priceSubmitting = false
					this.orderActionBusy = false
				})
			},
			qxqx() {
				this.zengsongflag = false
				this.tkflag = false
				this.refundConfirmFlag = false
				this.orderActionBusy = false
				this.priceSubmitting = false
				this.qxfei = ''
				this.ddfei = ''
				this.glfei = ''
				this.csfei = ''
				this.yuanyin = ''
			},
			btntz(id) {
				uni.navigateTo({
					url: '/page_shanghu/guanli/device_detail?id=' + id
				})
			},
			formatSecondsToHMS(seconds) {
				const h = Math.floor(seconds / 3600).toString().padStart(2, '0');
				const m = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0');
				const s = Math.floor(seconds % 60).toString().padStart(2, '0');
				return `${h}:${m}:${s}`;
			},
			formatDatess(startTime, endTime) {
				if (!startTime) return "0秒"; // 如果没有开始时间，返回0

				// 解析时间（无效时间则返回0）
				const start = new Date(startTime);
				const ends = endTime == null ? this.formatCurrentTime() : new Date(endTime);
				const end = new Date(ends)
				console.log(ends, end, '02220');
				if (isNaN(start.getTime()) || isNaN(end.getTime())) return "0秒";

				// 计算时间差（毫秒）
				let diffMs = end - start;
				if (diffMs < 0) return "0秒"; // 结束时间早于开始时间

				// 计算各时间单位
				const diffDays = Math.floor(diffMs / 86400000); // 天
				diffMs %= 86400000;
				const diffHours = Math.floor(diffMs / 3600000); // 小时
				diffMs %= 3600000;
				const diffMinutes = Math.floor(diffMs / 60000); // 分钟
				diffMs %= 60000;
				const diffSeconds = Math.floor(diffMs / 1000); // 秒

				// 智能拼接结果（忽略0值单位，但至少显示"X秒"）
				const parts = [];
				if (diffDays > 0) parts.push(`${diffDays}天`);
				if (diffHours > 0) parts.push(`${diffHours}小时`);
				if (diffMinutes > 0) parts.push(`${diffMinutes}分钟`);
				parts.push(`${diffSeconds}秒`); // 始终显示秒

				return parts.join("");
			},
			formatCurrentTime() {
				const now = new Date();
				const padZero = num => num < 10 ? `0${num}` : num;
				return `${now.getFullYear()}-${padZero(now.getMonth() + 1)}-${padZero(now.getDate())} ${padZero(now.getHours())}:${padZero(now.getMinutes())}:${padZero(now.getSeconds())}`;
			},
			updateTrackData() {
				const formattedStartTime = this.orderxqobj.startTime;
				const formattedEndTime = this.orderxqobj.endTime || this.formatCurrentTime();
				// this.$u.get('/bst/locationLog/listByTime?sn=' + this.sn + '&startTime=' + formattedStartTime + '&endTime=' + formattedEndTime).then((res) => {
				this.$u.get('/bst/locationLog/listAll?orderId=' + this.orid + '&timeRange=' + this.kstime + ',' + this.endtime + '&valid=true').then((res) => {
					if (res.code === 200) {
						if (!res.data || res.data.length === 0) {
							uni.showToast({
								title: '该时间段内无轨迹数据',
								icon: 'none',
								duration: 2000
							});
							return
						}

						// 清空之前的轨迹数据
						this.polyline = []
						this.markers = []

						this.trackPoints = normalizeLocationLogList(res.data, (point) => ({
							status: point.status,
							onlineStatus: point.onlineStatus,
							remainingPower: point.bat || 0,
						}))

						if (!this.trackPoints.length) {
							uni.showToast({
								title: '该时间段内无有效轨迹数据',
								icon: 'none',
								duration: 2000,
							})
							return
						}

						// 添加起点和终点标记
						if (this.trackPoints.length > 0) {
							const startPoint = this.trackPoints[0]
							const endPoint = this.trackPoints[this.trackPoints.length - 1]

							// 添加起点标记
							this.markers.push({
								id: 'start',
								latitude: startPoint.latitude,
								longitude: startPoint.longitude,
								width: 22,
								height: 32,
								iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uoORewceRbnD0jcNHhns'
							})

							// 添加终点标记
							this.markers.push({
								id: 'end',
								latitude: endPoint.latitude,
								longitude: endPoint.longitude,
								width: 22,
								height: 32,
								iconPath: 'https://api.ccttiot.com/smartmeter/img/static/u5HZcdTVcyNGkHDUeT4h'
							})

							// 添加轨迹折线
							this.polyline.push({
								points: toPolylinePointList(this.trackPoints),
								color: '#00AF99',
								width: 4,
								dottedLine: false,
								arrowLine: true,
								borderWidth: 2,
								borderColor: '#ffffff'
							})

							// 更新地图显示范围
							this.latitude = startPoint.latitude
							this.longitude = startPoint.longitude
							this.$nextTick(() => {
								const ctx = uni.createMapContext('map', this)
								if (ctx && typeof ctx.includePoints === 'function') {
									ctx.includePoints({
										points: toPolylinePointList(this.trackPoints),
										padding: [80, 80, 80, 80],
									})
								}
							})
						}
					}
				})
			},


			btnflagxs() {
				this.flagdiaodu = !this.flagdiaodu
			},
			unpass() {
				if (this.toastIfOrderBusy()) return
				this.orderActionBusy = true
				this.damageImageList = []
				this.getQiniuToken()
				this.huancheflag = true
			},
			parsePictures(pictureString) {
				console.log(pictureString, '45454545454');
				if (!pictureString || typeof pictureString !== 'string') {
					return []
				}
				return pictureString.split(',')
			},
			preview(img, pic) {
				uni.previewImage({
					current: img,
					urls: this.parsePictures(pic.finishPicture)
				})
			},

			getRefundOriginal(type) {
				const keyMap = {
					riding: 'actualReceivedRidingFee',
					dispatch: 'actualReceivedDispatchFee',
					manage: 'actualReceivedManageFee',
					deduction: 'actualReceivedDeductionFee'
				}
				const v = Number(this.orderxqobj[keyMap[type]])
				return isNaN(v) ? 0 : v
			},
			isRefundRowDisabled(type) {
				return this.getRefundOriginal(type) <= 0
			},
			formatRefundMoney(val) {
				const n = Number(val)
				return (isNaN(n) ? 0 : n).toFixed(2)
			},
			resetRefundForm() {
				this.qxfei = ''
				this.ddfei = ''
				this.glfei = ''
				this.csfei = ''
				this.yuanyin = ''
			},
			validateRefundForm() {
				const rows = [
					{ type: 'riding', val: this.qxfei, label: '骑行费' },
					{ type: 'dispatch', val: this.ddfei, label: '调度费' },
					{ type: 'manage', val: this.glfei, label: '管理费' },
					{ type: 'deduction', val: this.csfei, label: '车损费' }
				]
				let hasRefund = false
				for (let i = 0; i < rows.length; i++) {
					const row = rows[i]
					const original = this.getRefundOriginal(row.type)
					if (original <= 0) continue
					const amount = Number(row.val || 0)
					if (isNaN(amount) || amount < 0) {
						uni.showToast({ title: row.label + '退款金额不正确', icon: 'none' })
						return false
					}
					if (amount > original) {
						uni.showToast({ title: row.label + '退款不能超过实收', icon: 'none' })
						return false
					}
					if (amount > 0) hasRefund = true
				}
				if (!hasRefund) {
					uni.showToast({ title: '请至少填写一项退款金额', icon: 'none' })
					return false
				}
				return true
			},
			// 点击退款：先校验，再打开自定义确认弹窗
			btntuikuan() {
				if (!this.tkje) return
				if (!this.validateRefundForm()) return
				this.refundConfirmFlag = true
			},
			closeRefundConfirm() {
				this.refundConfirmFlag = false
			},
			confirmRefundSubmit() {
				this.refundConfirmFlag = false
				this.submitRefundOrder()
			},
			submitRefundOrder() {
				if (!this.tkje) return
				this.tkje = false
				uni.showLoading({
					title: '退款中...',
					mask: true
				})
				const data = {
					orderId: this.orid,
					ridingRefund: this.isRefundRowDisabled('riding') ? 0 : (this.qxfei === '' ? 0 : this.qxfei),
					dispatchRefund: this.isRefundRowDisabled('dispatch') ? 0 : (this.ddfei === '' ? 0 : this.ddfei),
					manageRefund: this.isRefundRowDisabled('manage') ? 0 : (this.glfei === '' ? 0 : this.glfei),
					deductionRefund: this.isRefundRowDisabled('deduction') ? 0 : (this.csfei === '' ? 0 : this.csfei),
					reason: this.yuanyin
				}
				this.$u.put(`/bst/order/refund`, data).then(res => {
					if (res.code == 200) {
						uni.showToast({
							title: '退款成功',
							icon: 'success',
							duration: 2000
						})
						this.resetRefundForm()
						this.refundConfirmFlag = false
						this.tkflag = false
						this.deviceInfo()
						this.getorderxq()
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {}).finally(() => {
					uni.hideLoading()
					this.tkje = true
					this.orderActionBusy = false
				})
			},
			btncha() {
				this.ddflag = false
				this.orderActionBusy = false
			},
			// 是否收取调度费
			btnfuzhus(flag) {
				if (this.auxReturnBusy) return
				this.auxReturnBusy = true
				uni.showLoading({
					title: '还车中...',
					mask: true
				})
				let data = {
					orderId: this.orid,
					requiredIot: false
				}
				this.$u.put(`/bst/order/finishDevice`, data).then(res =>{
					if (res.code != 200) {
						uni.showToast({
							title: '错误' + res.msg,
							icon: 'none',
							duration: 2000
						})
						return Promise.reject(res)
					}
					let datas = {
						orderId: this.orid,
						needDispatchFee: flag
					}
					return this.$u.put(`/bst/order/end`, datas)
				}).then((res2) => {
					if (!res2) return
					if (res2.code == 200) {
						uni.showToast({
							title: '辅助还车成功',
							icon: 'success',
							duration: 2000
						})
						this.ddflag = false
						setTimeout(() => {
							this.deviceInfo()
							this.getorderxq()
						}, 1500)
					} else {
						uni.showToast({
							title: res2.msg,
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {}).finally(() => {
					uni.hideLoading()
					this.auxReturnBusy = false
					this.orderActionBusy = false
				})
			},
			// 点击辅助换车
			btnhuanbike() {
				if (this.toastIfOrderBusy()) return
				this.orderActionBusy = true
				uni.showModal({
					title: '提示',
					content: '确定要进行辅助换车操作吗？',
					confirmText: '确定',
					cancelText: '取消',
					success: (res) => {
						if (res.confirm) {
							this.doChangeBike()
						} else {
							this.orderActionBusy = false
						}
					},
					fail: () => {
						this.orderActionBusy = false
					}
				})
			},
			// 执行换车流程
			doChangeBike() {
				uni.showLoading({
					title: '锁车中...',
					mask: true
				})
				let data = {
					orderId:this.orid,
					requiredIot:false
				}
				this.$u.put('/bst/order/finishDevice',data).then((res) => {
					if(res.code == 200){
						uni.hideLoading()
						this.getQiniuToken()
						this.showChangeBike = true
					}else{
						uni.hideLoading()
						uni.showToast({
							title: '错误' + res.msg,
							icon: 'none',
							duration: 5000
						})
						this.orderActionBusy = false
					}
				}).catch((err) => {
					uni.hideLoading()
					this.getQiniuToken()
					this.showChangeBike = true
				})
			},
			// 获取七牛云上传token
			getQiniuToken() {
				this.$u.get('/common/qiniuToken').then((res) => {
					if (res.code == 200) {
						this.qiniuToken = res.data
					}
				}).catch((err) => {
					console.log('获取七牛云token失败', err)
				})
			},
			// 上传故障图片
			uploadFaultImage() {
				const _this = this
				uni.chooseImage({
					count: 1,
					sizeType: ['compressed'],
					sourceType: ['album', 'camera'],
					success(res) {
						const tempFilePaths = res.tempFilePaths[0]
						const math = 'static/' + _this.$u.guid(20)
						// 检查文件大小（5MB）
						uni.getFileInfo({
							filePath: tempFilePaths,
							async success(fileInfo) {
								if (fileInfo.size > 5 * 1024 * 1024) {
									uni.showToast({
										title: '图片大小不能超过5MB',
										icon: 'none',
										duration: 2000
									})
									return
								}
								try {
									const url = await _this.$uploadQiniuFile({
										filePath: tempFilePaths,
										key: 'bike/img/' + math,
										title: '上传故障图片',
										showProgress: true
									})
									_this.faultPicture = url
									uni.showToast({
										title: '上传成功',
										icon: 'success',
										duration: 1500
									})
								} catch (e) {
									uni.showToast({
										title: '上传失败，请重试',
										icon: 'none',
										duration: 2000
									})
								}
							}
						})
					},
					fail(err) {
						uni.showToast({
							title: '未授权访问相册权限，请授权后使用',
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			// 预览故障图片
			previewFaultImage() {
				if (this.faultPicture) {
					uni.previewImage({
						current: this.faultPicture,
						urls: [this.faultPicture]
					})
				}
			},
			// 删除故障图片
			deleteFaultImage() {
				uni.showModal({
					title: '提示',
					content: '确定要删除这张图片吗？',
					success: (res) => {
						if (res.confirm) {
							this.faultPicture = ''
						}
					}
				})
			},
			// 扫码获取设备SN
			scanDeviceSn() {
				uni.scanCode({
					onlyFromCamera: true,
					scanType: ['qrCode'],
					success: (res) => {
						console.log('扫码结果：', res)
						// 从二维码中提取SN
						function getQueryParam(url, paramName) {
							let regex = new RegExp(`[?&]${paramName}=([^&]*)`)
							let results = regex.exec(url)
							return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : null
						}
						let sceneValue = res.result
						let decodedValue = decodeURIComponent(sceneValue)
						let sn = getQueryParam(decodedValue, 's') || getQueryParam(decodedValue, 'sn')
						
						// 如果二维码中不包含参数，尝试直接使用结果
						if (!sn) {
							sn = res.result
						}
						
						if (sn) {
							this.selectedDeviceSn = sn
							uni.showToast({
								title: '扫码成功',
								icon: 'success',
								duration: 1500
							})
						} else {
							uni.showToast({
								title: '未识别到设备SN',
								icon: 'none',
								duration: 2000
							})
						}
					},
					fail: (err) => {
						console.error('扫码失败：', err)
						uni.showToast({
							title: '扫码失败，请重试',
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			// 关闭换车弹窗
			closeChangeBike() {
				this.showChangeBike = false
				this.selectedDeviceSn = ''
				this.changeReason = ''
				this.faultDetail = ''
				this.faultPicture = ''
				this.reasonIndex = -1
				this.changeBikeConfirming = false
				this.orderActionBusy = false
			},
			// 选择换车原因
			onReasonChange(e) {
				const index = e.detail.value
				this.reasonIndex = index
				this.changeReason = this.reasonOptions[index].value
			},
			// 确认换车
			confirmChangeBike() {
				if (this.changeBikeConfirming) return
				if (!this.changeReason) {
					uni.showToast({
						title: '请选择换车原因',
						icon: 'none',
						duration: 2000
					})
					return
				}
				if (!this.selectedDeviceSn) {
					uni.showToast({
						title: '请输入目标设备SN',
						icon: 'none',
						duration: 2000
					})
					return
				}

				this.changeBikeConfirming = true
				uni.showLoading({
					title: '换车中...',
					mask: true
				})

				let data = {
					orderId: this.orid,
					reason: this.changeReason,
					deviceSn: this.selectedDeviceSn
				}

				if (this.changeReason === 'DEVICE_FAULT') {
					if (this.faultDetail) {
						data.faultDetail = this.faultDetail
					}
					if (this.faultPicture) {
						data.faultPicture = this.faultPicture
					}
				}

				this.$u.put('/bst/order/changeDevice', data).then((res) => {
					if (res.code === 200) {
						uni.showToast({
							title: '换车成功',
							icon: 'success',
							duration: 2000
						})
						this.closeChangeBike()
						setTimeout(() => {
							this.getorderxq()
						}, 1500)
					} else {
						uni.showToast({
							title: res.msg || '换车失败',
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {}).finally(() => {
					uni.hideLoading()
					this.changeBikeConfirming = false
					this.orderActionBusy = false
				})
			},
			/** 辅助还车：无调度费争议时，锁车 + 结束订单（与弹窗内「确定」逻辑一致） */
			_finishAuxReturnNoDispatchDialog() {
				uni.showLoading({
					title: '锁车中...',
					mask: true
				})
				const data = {
					orderId: this.orid,
					requiredIot: false
				}
				this.$u.put('/bst/order/finishDevice', data).then((res) => {
					if (res.code != 200) {
						uni.showToast({
							title: '错误' + res.msg,
							icon: 'none',
							duration: 5000
						})
						return Promise.reject(res)
					}
					return this.$u.put(`/bst/order/end`, { orderId: this.orid })
				}).then((res2) => {
					if (!res2) return
					if (res2.code == 200) {
						uni.showToast({
							title: '辅助还车成功',
							icon: 'success',
							duration: 2000
						})
						setTimeout(() => {
							this.deviceInfo()
							this.getorderxq()
						}, 1500)
					} else {
						uni.showModal({
							title: '提示',
							content: res2.msg,
							showCancel: false,
							confirmText: '知道了',
							success: function() {}
						})
					}
				}).catch(() => {}).finally(() => {
					uni.hideLoading()
					this.orderActionBusy = false
				})
			},
			// 点击辅助还车
			btnfuzhu() {
				if (this.toastIfOrderBusy()) return
				this.orderActionBusy = true
				let arr = this.devicesList.map(item => {
				  const name = item.name || ''
				  return name.slice(-12)
				})
				let data = {
					orderId: this.orid,
					checkLocation: false,
					macList:arr
				}
				this.$u.post(`/app/order/calcFee`, data).then(res => {
					if (res.code == 200) {
						this.fuzhuobj = res.data
						let manageFee = res.data.manageFee == null ? 0 : res.data.manageFee
						let dispatchFee = res.data.dispatchFee == null ? 0 : res.data.dispatchFee
						if (manageFee > 0 || dispatchFee > 0) {
							this.ddflag = true
						} else {
							let that = this
							uni.showModal({
								title: '提示',
								content: '您确定要进行辅助还车吗？',
								showCancel: true,
								success(resM) {
									if (resM.confirm) {
										that._finishAuxReturnNoDispatchDialog()
									} else {
										that.orderActionBusy = false
									}
								},
								fail() {
									that.orderActionBusy = false
								}
							})
						}
					} else {
						this.orderActionBusy = false
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				}).catch(() => {
					this.orderActionBusy = false
				})
			},

			// 转换成时分秒
			formatSecondsToHMS(seconds) {
				seconds = seconds || 0 // 处理空值
				const h = Math.floor(seconds / 3600).toString().padStart(2, '0')
				const m = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0')
				const s = Math.floor(seconds % 60).toString().padStart(2, '0')
				return `${h}:${m}:${s}`
			},
			
			checkbtn(num) {
				if (num == 1) { //1为联系客户
					uni.makePhoneCall({
						phoneNumber: this.orderxqobj.userPhone,
						success: function(res) {
							console.log('拨打电话成功', res)
						},
						fail: function(err) {
							console.error('拨打电话失败', err)
						}
					})
				} else { //否则为退款
					if (this.toastIfOrderBusy()) return
					this.orderActionBusy = true
					this.resetRefundForm()
					this.tkflag = true
				}
			},
			// 请求订单详情
			getorderxq() {
				this.$u.get(`/bst/order/${this.orid}?assembleOrderDeviceList=true`).then(res => {
					if (res.code == 200) {
						this.sn = res.data.deviceSn
						this.deviceInfo()
						this.orderxqobj = res.data
						this.updateTrackData()
						this.suitSeconds = res.data.suitSeconds == null ? '--' : Math.ceil(res.data.suitSeconds / 3600)
						this.orderDeviceList = res.data.orderDeviceList
						console.log(this.orderDeviceList, '12212121211124121')
					}else if(res.code == 401){
						this.getlogo()
					}
				})
			},
			// 静默登录
			getlogo(){
				let taht = this
				wx.login({
					success(res) {
						if (res.code) {
							let data = {
								loginCode: res.code,
								appId:taht.$store.state.appid
							}
							taht.$u.post('/wxLogin', data).then(res => {
			                    if (res.code == 200) {
									uni.setStorageSync('token', res.token)
									taht.getorderxq()
									taht.getyouhui()
								}
							})
						}
					},
				})
			},

			// 静音
			btnjingyin() {
				if (this.jytxt == '开') {
					let data = {
						isSound: 0
					}
					this.$u.post(`/appVerify/device/mute/${this.sn}`).then(res => {
						if (res.code == 200) {
							this.jytxt = '关'
							uni.showToast({
								title: '关闭静音成功',
								icon: 'success',
								duration: 2000
							})
						}
					})
				} else {
					let data = {
						isSound: 1
					}
					this.$u.post(`/appVerify/device/mute/${this.sn}`).then(res => {
						if (res.code == 200) {
							this.jytxt = '开'
							uni.showToast({
								title: '开启静音成功',
								icon: 'success',
								duration: 2000
							})
						}
					})
				}
			},
			toTrack() {
				let endTime = this.orderxqobj.endTime || this.formatCurrentTime()
				console.log(endTime, '020202002');
				uni.navigateTo({
					url: '/page_shanghu/guanli/bike_track?id=' + this.deviceInfos.id + '&type=1' + '&qufen=123' +
						'&startTime=' + this.orderxqobj.startTime + '&endTime=' + endTime + '&orid=' + this.orid
				})
			},
			changeShwoList() {
				console.log('diaoyongle')
				this.showModelList = true
			},
			confirm(e) {
				let modelId = e[0].value
				let data = {
					sn: this.sn,
					modelId: modelId
				}
				this.$u.put('/bst/device', data).then((res) => {
					if (res.code == 200) {
						this.showModelList = false
						this.deviceInfo()
						uni.showToast({
							title: '修改成功',
							icon: 'none',
							duration: 2000
						})
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			getModelList() {
				this.$u.get(`/bst/model/list?pageNum=1&pageSize=999`).then((res) => {
					if (res.code == 200) {
						this.ModelList = res.rows.map(item => ({
							value: item.id,
							label: item.name
						}))
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			closeQr() {
				this.showqr = false
			},
			generateQrcode() {
				uni.navigateTo({
					url: '/page_shanghu/guanli/Qrcode?sn=' + this.deviceInfos.sn
				})
			},
			saveQrcode() {
				uni.canvasToTempFilePath({
					canvasId: 'qrcode',
					x: -10, // 裁剪区域的 x
					y: 0, // 裁剪区域的 y
					width: 155, // 裁剪区域的宽度，包含边距
					height: 157 + 15, // 裁剪区域的高度，包含边距
					success: (res) => {
						uni.saveImageToPhotosAlbum({
							filePath: res.tempFilePath,
							success: () => {
								uni.showToast({
									title: '保存成功',
									icon: 'success'
								})
								this.showqr = false
							},
							fail: (err) => {
								uni.showToast({
									title: '保存失败',
									icon: 'none'
								})
							}
						})
					},
					fail: (err) => {
						uni.showToast({
							title: '生成二维码失败',
							icon: 'none'
						})
					}
				})
			},
			closeshowtip() {
				this.showbtntip = false
			},
			// 确定修改车牌号
			putvehicle() {
				let data = {
					sn: this.sn,
					vehicleNum: this.vehicleNum
				}
				this.$u.put('/bst/device', data).then((res) => {
					if (res.code == 200) {
						this.deviceInfo()
						this.showvehicle = false
						uni.showToast({
							title: '修改成功',
							icon: 'none',
							duration: 2000
						})
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			closemask() {
				this.maskloading = false
			},
			statuss() {
				if (this.deviceInfos.sn) {
					if (this.deviceInfos.etOrders[0]) {
						if (this.deviceInfos.etOrders[0].status == 0) {
							return '预约中'
						} else if (this.deviceInfos.etOrders[0].status == 1) {
							return '取消预约'
						} else if (this.deviceInfos.etOrders[0].status == 2) {
							return '骑行中'
						} else if (this.deviceInfos.etOrders[0].status == 3) {
							return '骑行结束'
						} else if (this.deviceInfos.etOrders[0].status == 4) {
							return '订单完成'
						}
					}
				}
			},
			closevehicle() {
				this.showvehicle = false
			},
			bulebtn(num) {
				if (num == 1) {
					if (this.carstause) {
						this.ring()
					} else {
						this.bulering = true
						this.Binddevice()
					}
				} else if (num == 2) {
					if (this.carstause) {
						this.open()
					} else {
						this.buleopen = true
						this.Binddevice()
					}
				} else if (num == 3) {
					if (this.carstause) {
						this.close()
					} else {
						this.buleclose = true
						this.Binddevice()
					}
				} else if (num == 4) {
					if (this.carstause) {
						this.reboot()
					} else {
						this.bulerebort = true
						this.Binddevice()
					}
				}
			},
			btn(num) {
				this.showbtntip = false
				let data = [this.sn]
				if (num == 0) {
					uni.showLoading({
						title: '加载中...'
					})
					console.log('点击了....1');
					this.$u.put('/bst/device/iot/unlock?sn=' + this.sn).then((res) => {
						if (res.code == 200) {
							// 处理接口返回的数据，将边界数据转换为地图组件需要的折线结构
							this.deviceInfo()
							uni.showToast({
								title: '操作成功',
								icon: 'success',
								duration: 2000
							})
						} else {
							uni.hideLoading()
							this.bulebtn(2)
						}
					})
				} else if (num == 1) {
					uni.showLoading({
						title: '加载中...'
					})
					console.log('点击了....2');
					this.$u.put('/bst/device/iot/lock?sn=' + this.sn).then((res) => {
						if (res.code == 200) {
							// 处理接口返回的数据，将边界数据转换为地图组件需要的折线结构
							this.deviceInfo()
							uni.showToast({
								title: '操作成功',
								icon: 'success',
								duration: 2000
							});
						} else {
							uni.hideLoading()
							this.bulebtn(3)
						}
					})
				} else if (num == 2) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/disable', data).then((res) => {
						if (res.code == 200) {
							uni.showToast({
								title: '解禁成功',
								icon: 'success',
								duration: 2000
							});
							// 处理接口返回的数据，将边界数据转换为地图组件需要的折线结构
							this.deviceInfo()
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				} else if (num == 3) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/enable', data).then((res) => {
						if (res.code == 200) {
							// 处理接口返回的数据，将边界数据转换为地图组件需要的折线结构
							uni.showToast({
								title: '解禁成功',
								icon: 'success',
								duration: 2000
							});
							this.deviceInfo()
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				} else if (num == 4) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/iot/ring?sn=' + this.sn).then((res) => {
						if (res.code == 200) {
							uni.hideLoading()
							uni.showToast({
								title: '操作成功',
								icon: 'success',
								duration: 2000
							});
						} else {
							uni.hideLoading()
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							});
							this.bulebtn(1)
						}
					})
				} else if (num == 5) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/in', data).then((res) => {
						if (res.code == 200) {
							uni.showToast({
								title: '回仓成功',
								icon: 'success',
								duration: 2000
							});
							this.deviceInfo()
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				} else if (num == 6) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/out', data).then((res) => {
						if (res.code == 200) {
							this.deviceInfo()
							uni.showToast({
								title: '出仓成功',
								icon: 'success',
								duration: 2000
							})
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				} else if (num == 7) {
					this.showvehicle = true
				} else if (num == 8) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/iot/reboot?sn=' + this.sn).then((res) => {
						if (res.code == 200) {
							this.deviceInfo()
							uni.showToast({
								title: '操作成功',
								icon: 'success',
								duration: 2000
							})
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				} else if (num == 9) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/iot/unlockSeat?sn=' + this.sn).then((res) => {
						if (res.code == 200) {
							this.deviceInfo()
							uni.showToast({
								title: '操作成功',
								icon: 'success',
								duration: 2000
							})
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				} else if (num == 10) {
					uni.showLoading({
						title: '加载中...'
					})
					this.$u.put('/bst/device/iot/refresh?id=' + this.sn).then((res) => {
						if (res.code == 200) {
							this.deviceInfo()
							uni.showToast({
								title: '操作成功',
								icon: 'success',
								duration: 2000
							})
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none',
								duration: 2000
							})
						}
					})
				}
			},
			Binddevice() {
				uni.getBluetoothAdapterState({
					success: function(res) {
						console.log('蓝牙状态：', res.available)
					},
					fail: function(res) {
						console.log('获取蓝牙状态失败')
					}
				})
				this.maskloading = true
				this.devicesList = []
				this.maskepage = 4
				this.buletxt = '蓝牙连接中'
				console.log("xBlufi", xBlufi.XMQTT_SYSTEM)
				xBlufi.listenDeviceMsgEvent(true, this.funListenDeviceMsgEvent)
				xBlufi.notifyStartDiscoverBle({
					'isStart': true
				})
				// 两秒后停止蓝牙搜索
				setTimeout(() => {
					xBlufi.notifyStartDiscoverBle({
						'isStart': false
					})
					setTimeout(() => {
						if (this.devicesList.length == 0) {
							this.maskepage = 5
						} else {
							let uniqueDevicesList = Array.from(new Set(this.devicesList))
							// 将去重后的数组重新赋值给 this.devicesList
							this.devicesList = uniqueDevicesList
							console.log(this.devicesList, 'this.devicesListthis.devicesList')
							let istrue = false
							this.devicesList.forEach(device => {
								// 从设备名称中提取 MAC 地址（假设 MAC 地址是设备名称的后6个字符）
								let macFromName = device.name.substring(device.name.length - 12)
								console.log(macFromName, 'macFromNamemacFromName')
								// 与 this.mac 进行比较
								if (macFromName == this.mac) {
									// 如果相同，则将 this.ishave 设置为 true
									console.log(device)
									this.deviceInfoss = device
									istrue = true
									this.createBLEConnection(device)
									console.log('对比正确1111111111')
								} else {
									console.log('对比错误')
								}
							})
							setTimeout(() => {
								if (!istrue) {
									this.buletxt = '蓝牙连接失败'
									setTimeout(() => {
										this.maskepage = 5
									}, 500)
								}
							}, 500)
						}
					}, 200)
				}, 5000)
			},
			reboot() {
				let vm = this // 将外部的 this 绑定到 vm 上
				uni.getNetworkType({
					success(res) {
						if (res.networkType !== 'none') {
							uni.getConnectedBluetoothDevices({
								success(res) {
									console.log('已连接的蓝牙设备信息：', res)
									xBlufi.notifySendCustomData({
										customData: "11reboot"
									})
									vm.maskloading = false
								},
								fail(err) {
									uni.hideLoading()
									console.error('获取已连接蓝牙设备信息失败：', err)
								}
							})
						} else {
							console.log('手机未连接网络')
						}
					}
				})
			},
			open() {
				let vm = this // 将外部的 this 绑定到 vm 上
				uni.getNetworkType({
					success(res) {
						if (res.networkType !== 'none') {
							uni.getConnectedBluetoothDevices({
								success(res) {
									console.log('已连接的蓝牙设备信息：', res)
									xBlufi.notifySendCustomData({
										customData: "11open"
									})
									vm.maskloading = false
									vm.deviceInfo()
								},
								fail(err) {
									uni.hideLoading()
									console.error('获取已连接蓝牙设备信息失败：', err)
								}
							})
						} else {
							console.log('手机未连接网络')
						}
					}
				})
			},
			close() {
				let vm = this // 将外部的 this 绑定到 vm 上
				uni.getNetworkType({
					success(res) {
						if (res.networkType !== 'none') {
							uni.getConnectedBluetoothDevices({
								success(res) {
									console.log('已连接的蓝牙设备信息：', res)
									xBlufi.notifySendCustomData({
										customData: "11close"
									})
									vm.maskloading = false
									vm.deviceInfo()
								},
								fail(err) {
									uni.hideLoading()
									console.error('获取已连接蓝牙设备信息失败：', err)
								}
							})
						} else {
							console.log('手机未连接网络')
						}
					}
				})
			},
			ring() {
				let vm = this // 将外部的 this 绑定到 vm 上
				uni.getNetworkType({
					success(res) {
						if (res.networkType !== 'none') {
							uni.getConnectedBluetoothDevices({
								success(res) {
									console.log('已连接的蓝牙设备信息：', res)
									xBlufi.notifySendCustomData({
										customData: "11play1@"
									})
									vm.maskloading = false
									vm.deviceInfo()
								},
								fail(err) {
									uni.hideLoading()
									console.error('获取已连接蓝牙设备信息失败：', err)
								}
							})
						} else {
							console.log('手机未连接网络')
						}
					}
				})
			},
			funListenDeviceMsgEvent: function(options) {
				switch (options.type) {
					case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS:
						if (options.result) {
							let devicesarr = options.data
							devicesarr.forEach(device => {
								this.devicesList.push(device)
								let uniqueDevicesList = Array.from(new Set(this.devicesList))
								// 将去重后的数组重新赋值给 this.devicesList
								this.devicesList = uniqueDevicesList
							})
						}
						break;
					case xBlufi.XBLUFI_TYPE.TYPE_CONNECTED:
						console.log("连接回调：" + JSON.stringify(options))
						if (options.result) {
							xBlufi.notifyInitBleEsp32({
								deviceId: options.data.deviceId
							})
							let systemInfo = uni.getSystemInfoSync()
							if (systemInfo.platform === 'android') {
								// 当前设备是 Android  
							} else if (systemInfo.platform === 'ios') {
								// 当前设备是 iOS  
							}
						}
						if (options.result == false) {
							this.carstause = false
							if (this.maskepage == 4) {
								this.buletxt = '设备连接失败'
								setTimeout(() => {
									this.maskepage = 5
								}, 800)
							}
						}
						break;
					case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA:
						if (options.data) {
							this.carstause = true
							if (this.maskloading && this.maskepage == 4) {
								if (this.buleclose == false && this.buleopen == false && this.bulerebort == false &&
									this.bulering == false) {
									if (this.buletxt == '蓝牙连接中') {
										this.buletxt = '蓝牙连接成功!'
									}
								}
								if (this.buleclose) {
									this.buleclose = false
									this.close()
								}
								if (this.buleopen) {
									this.buleopen = false
									this.open()
								}
								if (this.bulerebort) {
									this.buleopen = false
									this.reboot()
								}
								if (this.bulering) {
									this.bulering = false
									this.ring()
								}
							}
						} else {
							this.carstause = false
							if (this.maskepage == 4) {
								this.buletxt = '设备连接失败'
								setTimeout(() => {
									this.maskepage = 5
								}, 800)
							}
						}
						console.log("1收到设备发来的自定义数据结果：", options.data)
						break;
					case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED: {
						console.log('状态', options.result)
						if (options.result == false) {
							this.carstause = false
							if (this.maskepage == 4) {
								this.buletxt = '设备连接失败'
								setTimeout(() => {
									this.maskepage = 5
								}, 800)
							}
						}
					}
					break;
					case xBlufi.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP:
						if (options.result) {
							let uniqueDevicesList = Array.from(new Set(this.devicesList))
							// 过滤出名称字段的前五个字母为 "CTPOW" 的项
							let filteredDevices = uniqueDevicesList.filter(device => device.name.substring(0, 4) ===
								"BBLE")
							// 将过滤后的数组重新赋值给 this.devicesList
							this.devicesList = filteredDevices
						}
						this.searching = false
						break
				}
			},
			btnyc() {
				this.titleflag = false
			},
			// 解析自定义数据
			//4、建立连接
			createBLEConnection(e) {
				console.log('调用了')
				xBlufi.notifyStartDiscoverBle({
					'isStart': false
				});
				console.log(e, '蓝牙信息')
				const deviceId = e.deviceId
				let name = e.name
				console.log('点击了，蓝牙准备连接的deviceId:' + e.deviceId)
				xBlufi.notifyConnectBle({
					isStart: true,
					deviceId: e.deviceId,
					name
				})
			},

			funListenDeviceMsgEvents: function(options) {
				let that = this
				switch (options.type) {
					case xBlufi.XBLUFI_TYPE.TYPE_STATUS_CONNECTED: {
						console.log('状态', options.result)
						if (options.result == false) {
							this.carstause = false
							uni.showToast({
								title: '设备断开链接，请重新点击蓝牙链接',
								icon: 'none'
							})
							uni.hideLoading()
						}
					}
					break;

					case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_MY_DATA:
						this.loadPercent = options.data
						this.loadText = '文件读取中'
						console.log("文件读取中", options.data)
						break;
					case xBlufi.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA:
						console.log("1收到设备发来的自定义数据结果：", options.data)
						if (options.data) {
							this.carstause = true
						}
						break
					case xBlufi.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT:
						uni.hideLoading()
						if (options.result) {
							console.log('初始化成功')
						} else {
							console.log('初始化失败')
						}
						break
				}
			},
			// 点击隐藏没有设备提示
			btnhd() {
				this.tishiflag = false
			},
			status() {
				if (this.deviceInfos.status == 0) {
					return '仓库中'
				} else if (this.deviceInfos.status == 1) {
					return '待租'
				} else if (this.deviceInfos.status == 2) {
					return '预约中'
				} else if (this.deviceInfos.status == 3) {
					return '骑行中'
				} else if (this.deviceInfos.status == 4) {
					return '临时锁车中'
				} else if (this.deviceInfos.status == 6) {
					return '调度中'
				} else if (this.deviceInfos.status == 8) {
					return '下线'
				}
			},
			deviceInfo() {
				this.markers = [];
				this.polygon = []; // 初始化polygon数组
				this.$u.get(`/bst/device?sn=${this.sn}&supportLocation=true`).then((res) => {
					console.log(res, 'rererer');
					if (res.code === 200) {
						this.deviceInfos = res.data;
						if (res.data.isSound == 0) {
							this.jytxt = '关';
						} else {
							this.jytxt = '开';
						}
						this.vehicleNum = res.vehicleNum;
						this.mac = res.data.mac;
						this.getModelList();
						this.latitude = this.deviceInfos.latitude;
						this.longitude = this.deviceInfos.longitude;

						// 确保在获取设备信息后立即获取区域信息
						if (this.deviceInfos.areaId) {
							this.getArea();
						}

						if (this.getnum == 0) {
							this.getArea()
						}
						this.getnum = 1
						if (this.deviceInfos.status == 0) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								// iconPath: 'https://lxnapi.ccttiot.com/bike/img/static/u6jBvj7S50FPgsHaHXai',
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/uQRng4QNKA38Amk8Wgt5' :
									'https://lxnapi.ccttiot.com/bike/img/static/uocjFo8Ar2BJVpzC2G2f',
								callout: {
									content: this.deviceInfos.remainingPower + '%', // 修改为你想要显示的文字内容
									color: '#ffffff', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#000000', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						} else if (this.deviceInfos.status == 1) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/uzhMeExOQJbMcZtrfGUV' :
									'https://lxnapi.ccttiot.com/bike/img/static/uheL17wVZn24BwCwEztT',
								callout: {
									content: this.deviceInfos.remainingPower + '%', // 修改为你想要显示的文字内容
									color: '#2679D1', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#D4ECFF', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						} else if (this.deviceInfos.status == 2) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/uR3DQEssiK62ovhh88y8' :
									'https://lxnapi.ccttiot.com/bike/img/static/u460R1NKWHEpHbt0U4H7',
								callout: {
									content: this.deviceInfos.remainingPower + '%', // 修改为你想要显示的文字内容
									color: '#2679D1', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#D4ECFF', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						} else if (this.deviceInfos.status == 3) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/uG13E7BpUFF44wVYC9no' :
									'https://lxnapi.ccttiot.com/bike/img/static/uHQIdWCTmtUztl49wBKU',
								callout: {
									content: this.deviceInfos.remainingPower + '%', // 修改为你想要显示的文字内容
									color: '#2679D1', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#D4ECFF', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						} else if (this.deviceInfos.status == 4) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								// joinCluster: true,
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/uRod2zf3t9dAOYafWoWt' :
									'https://lxnapi.ccttiot.com/bike/img/static/uZpXq3TBtM5gVgJJeImY',
								callout: {
									content: this.deviceInfos.remainingPower + '%', // 修改为你想要显示的文字内容
									color: '#2679D1', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#D4ECFF', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						} else if (this.deviceInfos.status == 6) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/uhZudZM3nEKj0tYKlho2' :
									'https://lxnapi.ccttiot.com/bike/img/static/ujur6TezvPf4buFAqPHo',
								callout: {
									content: '' + this.deviceInfos.remainingPower + '%',
									color: '#2679D1', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#D4ECFF', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						} else if (this.deviceInfos.status == 8) {
							this.markers.push({
								id: parseFloat(this.deviceInfos.sn),
								latitude: this.deviceInfos.latitude,
								longitude: this.deviceInfos.longitude,
								// title: item.deviceName,
								width: 40,
								height: 47,
								iconPath: this.deviceInfos.onlineStatus == 0 ?
									'https://lxnapi.ccttiot.com/bike/img/static/ucBKG3ebYRAToVweJihu' :
									'https://lxnapi.ccttiot.com/bike/img/static/uyK7Vg4Lu8xb3oNVuG2l',
								callout: {
									content: this.deviceInfos.remainingPower + '%', // 修改为你想要显示的文字内容
									color: '#ffffff', // 修改为文字颜色
									fontSize: 10, // 修改为文字大小
									borderRadius: 10, // 修改为气泡圆角大小
									bgColor: '#000000', // 修改为气泡背景颜色
									padding: 2, // 修改为气泡内边距
									display: 'ALWAYS', // 修改为气泡的显示策略
								}
							})
						}
						this.$forceUpdate()
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			convertBoundaryToPolyline(boundary) {
				if (!boundary) return null;
				try {
					const points = JSON.parse(boundary).map(coord => ({
						latitude: coord[1],
						longitude: coord[0]
					}));
					return {
						points: points,
						color: "#22FF00",
						width: 2,
						dottedLine: false,
						arrowLine: false,
						borderWidth: 2,
						borderColor: "#22FF00"
					};
				} catch (error) {
					console.error("Error converting boundary to polyline:", error);
					return null;
				}
			},
			convertBoundaryToPolylines(boundaries, num) {
				if (!boundaries || !Array.isArray(boundaries)) return [];
				return boundaries.map(boundary => {
					if (!boundary) return null;
					try {
						const coords = JSON.parse(boundary);
						if (!Array.isArray(coords)) return null;
						const points = coords.map(coord => ({
							latitude: coord[1],
							longitude: coord[0]
						}))
						let style = {};
						if (num === 1) {
							style = {
								color: "#3A7EDB",
								width: 2,
								dottedLine: false,
								arrowLine: false,
								borderWidth: 2,
								borderColor: "#3A7EDB"
							};
						} else if (num === 2) {
							style = {
								color: "#FF473E",
								width: 2,
								dottedLine: false,
								arrowLine: false,
								borderWidth: 2,
								borderColor: "#FF473E"
							};
						} else if (num === 3) {
							style = {
								color: "#FFC107",
								width: 2,
								dottedLine: false,
								arrowLine: false,
								borderWidth: 2,
								borderColor: "#FFC107"
							};
						}
						return {
							points: points,
							...style
						};
					} catch (error) {
						console.error("Error converting boundary to polylines:", error);
						return null;
					}
				}).filter(polyline => polyline !== null);
			},
			toggleIconAndCallout() {
				this.showIconAndCallout = !this.showIconAndCallout
				if (this.showIconAndCallout) {
					const newMarkers = []
					this.parkingList.forEach(item => {
						newMarkers.push({
							id: parseFloat(item.id),
							latitude: parseFloat(item.latitude),
							longitude: parseFloat(item.longitude),
							width: 20,
							height: 28.95,
							iconPath: item.type == 1 ?
								'https://lxnapi.ccttiot.com/bike/img/static/up2xXqAgwCX5iER600k3' : item.type == 2 ?
								'https://lxnapi.ccttiot.com/bike/img/static/uDNY5Q4zOiZTCBTA2Jdq' :
								'https://lxnapi.ccttiot.com/bike/img/static/u53BAQcFIX3vxsCzEZ7t',
							callout: {
								content: item.name,
								color: '#ffffff',
								fontSize: 14,
								borderRadius: 10,
								bgColor: item.type == 1 ? '#3A7EDB' : item.type == 2 ? '#FF473E' : '#FFC107',
								padding: 6,
								display: 'ALWAYS'
							},
							isCalloutVisible: true // 添加标记
						})
					})
					this.$set(this, 'markers', [...this.markers, ...newMarkers])
				} else {
					// 过滤掉所有气泡显示的标记
					this.$set(this, 'markers', this.markers.filter(marker => !marker.isCalloutVisible))
				}
			},
			convertBoundaryToPolygon(boundary) {
				if (!boundary) return null;
				try {
					const points = JSON.parse(boundary).map(coord => ({
						latitude: coord[1],
						longitude: coord[0]
					}));
					return {
						points: points,
						fillColor: "#55888840",
						strokeColor: "#22FF0080",
						strokeWidth: 1,
						zIndex: 1
					};
				} catch (error) {
					console.error("Error converting boundary to polygon:", error);
					return null;
				}
			},
			convertBoundaryToPolygons(boundaries, num) {
				if (!boundaries || !boundaries.length) return [];
				const colors = {
					1: {
						fill: "#3A7EDB40",
						stroke: "#3A7EDB"
					},
					2: {
						fill: "#FFF5D640",
						stroke: "#FFC107"
					},
					3: {
						fill: "#FFE0E040",
						stroke: "#FF473E"
					}
				};
				return boundaries.map(boundary => {
					if (!boundary) return null
					try {
						const coords = JSON.parse(boundary)
						if (!Array.isArray(coords)) return null

						const points = coords.map(coord => ({
							latitude: coord[1],
							longitude: coord[0]
						}))
						return {
							points: points,
							fillColor: colors[num].fill,
							strokeColor: colors[num].stroke,
							strokeWidth: 1,
							zIndex: 1
						}
					} catch (error) {
						console.error("Error converting boundary to polygons:", error)
						return null
					}
				}).filter(Boolean)
			},

			getParking() {
				let data = {
					areaId: this.deviceInfos.areaId
				};
				this.$u.get('/bst/areaSub/listByAreaId', data).then((res) => {
					if (res.code === 200) {
						const filteredData = res.data.filter(item => item.status != 1)
						const type1Data = []
						const type2Data = []
						const type3Data = []
						filteredData.forEach(row => {
							if (row.type == 1) type1Data.push(row)
							else if (row.type == 2) type2Data.push(row)
							else if (row.type == 3) type3Data.push(row)
						})
						// 处理 type1 数据
						const validBoundaries = type1Data.map(row => row.boundaryStr).filter(boundary =>
							typeof boundary === 'string' && boundary.trim() !== '')
						const polygons = this.convertBoundaryToPolygons(validBoundaries, 1)
						if (polygons && polygons.length > 0) {
							this.polygon = this.polygon.concat(polygons)
						}
						// 处理 type2 数据
						const validBoundaries1 = type2Data.map(row => row.boundaryStr).filter(boundary =>
							typeof boundary === 'string' && boundary.trim() !== '')
						const polygons1 = this.convertBoundaryToPolygons(validBoundaries1, 2)
						if (polygons1 && polygons1.length > 0) {
							this.polygon = this.polygon.concat(polygons1)
						}
						// 处理 type3 数据
						const validBoundaries2 = type3Data.map(row => row.boundaryStr).filter(boundary =>
							typeof boundary === 'string' && boundary.trim() !== '');
						const polygons2 = this.convertBoundaryToPolygons(validBoundaries2, 3);
						if (polygons2 && polygons2.length > 0) {
							this.polygon = this.polygon.concat(polygons2);
						}

						this.parkingList = filteredData;
						this.$forceUpdate();
					}
				}).catch(error => {
					console.error("Error fetching parking data:", error);
				});
			},

			getArea() {
				let id = this.deviceInfos.areaId;
				if (!id) {
					console.error("Area ID is missing");
					return;
				}

				this.$u.get(`/bst/area/${id}`).then((res) => {
					if (res.code === 200 && res.data && res.data.boundaryStr) {
						const polygon = this.convertBoundaryToPolygon(res.data.boundaryStr);
						if (polygon) {
							this.polygon = [polygon];
							console.log('Area boundary added:', polygon);
							this.getParking();
						}
					}
				}).catch(error => {
					console.error("Error fetching area data:", error);
				});
			},
		}
	}
</script>

<style lang="scss">
	.page-container {
		background-color: #F6F8FB;
		min-height: 100vh;
		padding-bottom: 200rpx;
		box-sizing: border-box;
	}
    .diaodu {
    	position: fixed;
    	width: 560rpx;
    	background-color: #fff;
    	top: 50%;
    	left: 50%;
    	transform: translate(-50%, -50%);
    	border-radius: 24rpx;
    	overflow: hidden;
    	z-index: 999;
    	box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
    
    	.top {
    		width: 100%;
    		height: 80rpx;
    		display: flex;
    		align-items: center;
    		justify-content: flex-end;
    		padding: 0 30rpx;
    		box-sizing: border-box;
    		font-size: 40rpx;
    		color: #999;
    	}
    
    	.cen {
    		font-size: 32rpx;
    		color: #333;
    		padding: 0 40rpx 40rpx;
    		box-sizing: border-box;
    		text-align: center;
    		line-height: 1.5;
    	}
    
    	.anniu {
    		display: flex;
    		height: 100rpx;
    		border-top: 1px solid #f5f5f5;
    
    		view {
    			flex: 1;
    			display: flex;
    			align-items: center;
    			justify-content: center;
    			font-size: 32rpx;
    			font-weight: 500;
    		}
    
    		.bu {
    			color: #666;
    			background: #f8f8f8;
    		}
    
    		.shou {
    			color: #fff;
    			background: #4C97E7;
    		}
    	}
    }
	.map-wrapper {
		width: 100%;
		height: 400rpx;
		position: relative;
		
		.map {
			width: 100%;
			height: 100%;
		}
		
		.map-ctrl-btn {
			position: absolute;
			width: 80rpx;
			height: 80rpx;
			border-radius: 50%;
			// background: #fff;
			box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
			display: flex;
			align-items: center;
			justify-content: center;
			z-index: 10;
			
			.img {
				width: 100%;
				height: 100%;
			}
			
			&.park-btn {
				right: 30rpx;
				bottom: 30rpx;
			}
			&.track-btn {
				left: 30rpx;
				bottom: 30rpx;
			}
		}
	}

	.info-card {
		background: #FFFFFF;
		border-radius: 20rpx;
		margin: 24rpx;
		padding: 30rpx;
		box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.03);
		position: relative;
		overflow: hidden;
		
		&.overview-card {
			// z-index: 20;
		}
	}
	
	.card-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 30rpx;
		
		.order-no-box {
			font-size: 26rpx;
			color: #666;
			
			.value {
				color: #333;
				font-weight: 500;
				margin-left: 10rpx;
			}
		}
		
		.status-tag {
			padding: 4rpx 16rpx;
			border-radius: 8rpx;
			font-size: 24rpx;
			&.processing { background: rgba(58, 126, 219, 0.1); color: #3A7EDB; }
			&.finished { background: rgba(100, 182, 168, 0.1); color: #64B6A8; }
			&.canceled { background: #F3F3F3; color: #999; }
		}
	}

	.data-grid {
		display: flex;
		justify-content: space-around;
		text-align: center;
		margin-bottom: 30rpx;
		
		.data-item {
			display: flex;
			flex-direction: column;
			align-items: center;
			
			.data-val {
				font-size: 32rpx;
				font-weight: 600;
				color: #333;
				margin-bottom: 8rpx;
				
				&.price {
					color: #FF7310;
					font-size: 36rpx;
				}
				
				.unit {
					font-size: 24rpx;
					font-weight: 400;
					margin-left: 4rpx;
				}
			}
			
			.data-label {
				font-size: 24rpx;
				color: #999;
			}
		}
	}
	
	.divider {
		height: 1rpx;
		background: #F3F3F3;
		margin: 20rpx 0;
	}

	.detail-list, .fee-list {
		.list-item {
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 16rpx 0;
			font-size: 28rpx;
			color: #333;
			
			.label {
				color: #909399;
			}
			.value {
				font-weight: 500;
			}
			.highlight {
				color: #3A7EDB;
			}
			.text-red {
				color: #FF4444;
			}
			
			&.border-dashed {
				border-bottom: 1rpx dashed #eee;
				margin-bottom: 10rpx;
			}
			&.sm {
				font-size: 26rpx;
				padding: 8rpx 0;
			}
			
			.value-row {
				display: flex;
				align-items: center;
				
				.phone-link {
					color: #3A7EDB;
					margin-left: 10rpx;
				}
			}
		}
		
		.damage-display-block {
			margin-top: 20rpx;
			padding-top: 20rpx;
			border-top: 1rpx dashed #eee;
		}
		.damage-display-title {
			display: block;
			font-size: 26rpx;
			color: #909399;
			margin-bottom: 16rpx;
		}
		.damage-display-grid {
			display: flex;
			flex-wrap: wrap;
			gap: 16rpx;
		}
		.damage-display-thumb {
			width: 160rpx;
			height: 160rpx;
			border-radius: 12rpx;
			background: #f5f7fa;
		}
		
		.verify-remark-block {
			margin-top: 20rpx;
			padding-top: 20rpx;
			border-top: 1rpx dashed #eee;
		}
		.verify-remark-title {
			display: block;
			font-size: 26rpx;
			color: #909399;
			margin-bottom: 12rpx;
		}
		.verify-remark-text {
			display: block;
			font-size: 28rpx;
			color: #333;
			line-height: 1.6;
			word-break: break-all;
		}
	}

	.card-title-bar {
		display: flex;
		align-items: center;
		margin-bottom: 24rpx;
		
		.bar-mark {
			width: 6rpx;
			height: 30rpx;
			background: #4C97E7;
			border-radius: 4rpx;
			margin-right: 16rpx;
		}
		.title-text {
			font-size: 32rpx;
			font-weight: 600;
			color: #333;
		}
	}
	
	.summary-section {
		background: #FAFAFA;
		padding: 20rpx;
		border-radius: 12rpx;
		margin-top: 10rpx;
	}
	
	.total-pay {
		display: flex;
		justify-content: flex-end;
		align-items: center;
		margin-top: 24rpx;
		font-size: 30rpx;
		
		.label {
			margin-right: 16rpx;
		}
		.price {
			color: #FF7310;
			font-size: 40rpx;
			font-weight: bold;
		}
	}
	
	.vehicle-card {
		.vehicle-list {
			.vehicle-item {
				background: linear-gradient(135deg, #FFFFFF 0%, #F8FAFC 100%);
				border-radius: 16rpx;
				padding: 30rpx;
				margin-bottom: 24rpx;
				border: 1rpx solid #F0F2F5;
				box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.02);
				transition: all 0.3s ease;
				
				&:active {
					transform: scale(0.98);
					box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.05);
				}
				
				&:last-child {
					margin-bottom: 0;
				}
			}
			
			.vehicle-header {
				display: flex;
				justify-content: space-between;
				align-items: center;
				padding-bottom: 24rpx;
				border-bottom: 1rpx solid #F0F2F5;
				margin-bottom: 24rpx;
				
				.vehicle-header-left {
					flex: 1;
					display: flex;
					align-items: center;
					flex-wrap: wrap;
					gap: 20rpx;
				}
				
				.vehicle-badge {
					display: flex;
					align-items: center;
					padding: 8rpx 16rpx;
					border-radius: 20rpx;
					font-size: 24rpx;
					
					.badge-dot {
						width: 8rpx;
						height: 8rpx;
						border-radius: 50%;
						margin-right: 8rpx;
					}
					
					.badge-text {
						font-weight: 500;
					}
					
					&.badge-primary {
						background: linear-gradient(135deg, #E6F3FF 0%, #D4E9FF 100%);
						color: #3A7EDB;
						
						.badge-dot {
							background: #3A7EDB;
						}
					}
					
					&.badge-secondary {
						background: linear-gradient(135deg, #FFF5E6 0%, #FFEED4 100%);
						color: #FF7310;
						
						.badge-dot {
							background: #FF7310;
						}
					}
				}
				
				.vehicle-time-info {
					display: flex;
					flex-direction: column;
					
					.time-label {
						font-size: 22rpx;
						color: #909399;
						margin-bottom: 4rpx;
					}
					
					.time-value {
						font-size: 26rpx;
						color: #333;
						font-weight: 500;
					}
				}
				
				.vehicle-arrow {
					display: flex;
					align-items: center;
					justify-content: center;
					width: 48rpx;
					height: 48rpx;
					border-radius: 50%;
					background: #F5F7FA;
				}
			}
			
			.vehicle-details {
				.detail-grid {
					display: grid;
					grid-template-columns: 1fr 1fr;
					gap: 20rpx;
					margin-bottom: 24rpx;
					
					.detail-item {
						display: flex;
						flex-direction: column;
						padding: 16rpx;
						background: #FAFBFC;
						border-radius: 12rpx;
						border: 1rpx solid #F0F2F5;
						
						.detail-label {
							font-size: 22rpx;
							color: #909399;
							margin-bottom: 8rpx;
						}
						
						.detail-value {
							font-size: 28rpx;
							color: #333;
							font-weight: 500;
							word-break: break-all;
							
							&.highlight {
								color: #3A7EDB;
								font-weight: 600;
							}
						}
					}
				}
				
				.time-info-section {
					display: flex;
					flex-direction: column;
					gap: 16rpx;
					padding: 20rpx;
					background: linear-gradient(135deg, #F8FAFC 0%, #F0F4F8 100%);
					border-radius: 12rpx;
					
					.time-item {
						display: flex;
						align-items: flex-start;
						
						.time-icon {
							width: 40rpx;
							height: 40rpx;
							border-radius: 50%;
							display: flex;
							align-items: center;
							justify-content: center;
							margin-right: 16rpx;
							flex-shrink: 0;
							
							&.start {
								background: linear-gradient(135deg, #E6F3FF 0%, #D4E9FF 100%);
								
								&::before {
									content: '';
									width: 0;
									height: 0;
									border-left: 6rpx solid #3A7EDB;
									border-top: 4rpx solid transparent;
									border-bottom: 4rpx solid transparent;
								}
							}
							
							&.end {
								background: linear-gradient(135deg, #FFE6E6 0%, #FFD4D4 100%);
								
								&::before {
									content: '';
									width: 12rpx;
									height: 12rpx;
									border-radius: 50%;
									background: #FF4444;
								}
							}
						}
						
						.time-content {
							flex: 1;
							
							.time-title {
								display: block;
								font-size: 24rpx;
								color: #909399;
								margin-bottom: 6rpx;
							}
							
							.time-desc {
								display: block;
								font-size: 28rpx;
								color: #333;
								font-weight: 500;
							}
						}
					}
				}
			}
			
			.media-section {
				margin-top: 24rpx;
				display: flex;
				flex-direction: column;
				gap: 20rpx;
				
				.media-item {
					background: #FAFBFC;
					border-radius: 12rpx;
					padding: 20rpx;
					border: 1rpx solid #F0F2F5;
					
					.media-header {
						display: flex;
						align-items: center;
						margin-bottom: 16rpx;
						
						.media-icon {
							width: 32rpx;
							height: 32rpx;
							border-radius: 50%;
							margin-right: 12rpx;
							
							&.start-icon {
								background: linear-gradient(135deg, #E6F3FF 0%, #D4E9FF 100%);
								
								&::before {
									content: '';
									width: 0;
									height: 0;
									border-left: 5rpx solid #3A7EDB;
									border-top: 3rpx solid transparent;
									border-bottom: 3rpx solid transparent;
									display: block;
									margin: 13rpx auto;
								}
							}
							
							&.end-icon {
								background: linear-gradient(135deg, #FFE6E6 0%, #FFD4D4 100%);
								
								&::before {
									content: '';
									width: 10rpx;
									height: 10rpx;
									border-radius: 50%;
									background: #FF4444;
									display: block;
									margin: 11rpx auto;
								}
							}
						}
						
						.media-title {
							font-size: 26rpx;
							color: #333;
							font-weight: 500;
						}
					}
					
					.media-wrapper {
						width: 100%;
						border-radius: 8rpx;
						overflow: hidden;
						background: #000;
						
						.media-video {
							width: 100%;
							height: 400rpx;
							display: block;
						}
					}
				}
			}
		}
	}
	
	.footer-bar {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		background: #fff;
		box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.05);
		padding: 20rpx 30rpx 40rpx; // 适配 iPhone X 底部安全区
		box-sizing: border-box;
		z-index: 100;
		
		.btn-group {
			display: flex;
			flex-wrap: wrap;
			justify-content: flex-end;
			
			&.btn-group--audit {
				justify-content: stretch;
				.btn-audit {
					margin-left: 0;
					flex: 1;
					width: 100%;
				}
			}
			
			.btn {
				margin-left: 20rpx;
				margin-bottom: 10rpx;
				padding: 0 40rpx;
				height: 80rpx;
				line-height: 80rpx;
				border-radius: 40rpx;
				font-size: 30rpx;
				text-align: center;
				
				&.btn-primary {
					background: linear-gradient(90deg, #4C97E7 0%, #3A7EDB 100%);
					color: #fff;
					box-shadow: 0 4rpx 12rpx rgba(58, 126, 219, 0.3);
				}
				
				&.btn-outline {
					background: #fff;
					color: #666;
					border: 1rpx solid #ddd;
				}
				
				&.btn-audit {
					display: flex;
					align-items: center;
					justify-content: center;
					background: linear-gradient(90deg, #4c97e7, #6ab0ff);
					color: #fff;
					box-shadow: 0 4rpx 12rpx rgba(100, 182, 168, 0.3);
				}
			}
		}
	}
	
	/* 弹窗样式保留优化 */
	.tip_box {
		position: fixed;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		width: 600rpx;
		background: #FFFFFF;
		border-radius: 20rpx;
		z-index: 110;
		overflow: hidden;
		
		.top {
			padding: 40rpx;
			text-align: center;
			.tip { font-size: 34rpx; font-weight: 600; margin-bottom: 30rpx; }
			.ipt_box {
				display: flex;
				align-items: center;
				background: #F5F7FA;
				padding: 10rpx 20rpx;
				border-radius: 10rpx;
				.text { width: 120rpx; font-size: 28rpx; }
				.ipt { flex: 1; input { width: 100%; } }
			}
		}
		
		.bots {
			display: flex;
			border-top: 1rpx solid #eee;
			.bot_left, .bot_right {
				flex: 1;
				height: 90rpx;
				line-height: 90rpx;
				text-align: center;
				font-size: 32rpx;
			}
			.bot_left { color: #666; background: #fff; }
			.bot_right { color: #fff; background: #4C97E7; }
		}
	}
	
	.zengsongone, .yajindikou, .zengsong {
		position: fixed;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		width: 650rpx;
		background: #fff;
		border-radius: 20rpx;
		z-index: 200;
		padding: 40rpx;
		box-sizing: border-box;
		z-index: 1000;
		.tops { font-size: 36rpx; font-weight: 600; text-align: center; margin-bottom: 40rpx; }
		input {
			width: 100%;
			height: 80rpx;
			background: #F5F7FA;
			border-radius: 10rpx;
			padding: 0 20rpx;
			margin-bottom: 20rpx;
		}
		
		.gai {
			display: flex;
			align-items: center;
			justify-content: space-between;
			margin-bottom: 20rpx;
			font-size: 28rpx;
			/* 左侧文案（如「退款原因」四字）勿被压窄换行 */
			> view:first-child {
				flex-shrink: 0;
				white-space: nowrap;
				min-width: 140rpx;
				padding-right: 12rpx;
				box-sizing: border-box;
			}
			input.gai-full-input {
				flex: 1;
				min-width: 0;
				width: auto !important;
			}
			input { width: 200rpx; margin-bottom: 0; }
			picker {
				flex: 1;
				.picker-view {
					width: 200rpx;
					height: 80rpx;
					line-height: 80rpx;
					background: #F5F7FA;
					border-radius: 10rpx;
					padding: 0 20rpx;
					text-align: right;
					font-size: 28rpx;
					color: #333;
				}
			}
		}
		
		.anniu {
			display: flex;
			justify-content: space-between;
			margin-top: 40rpx;
			.qx, .qd {
				width: 45%;
				height: 80rpx;
				line-height: 80rpx;
				text-align: center;
				border-radius: 40rpx;
				font-size: 32rpx;
			}
			.qx { background: #F5F7FA; color: #666; }
			.qd { background: #4C97E7; color: #fff; }
		}
	}

	.refund-modal {
		width: 680rpx;
		padding: 36rpx 32rpx 32rpx;
		.tops { display: none; }
		input {
			width: auto;
			height: auto;
			background: transparent;
			border-radius: 0;
			padding: 0;
			margin-bottom: 0;
		}
		.refund-modal__header {
			display: flex;
			align-items: flex-start;
			margin-bottom: 28rpx;
		}
		.refund-modal__badge {
			width: 72rpx;
			height: 72rpx;
			line-height: 72rpx;
			text-align: center;
			border-radius: 16rpx;
			background: linear-gradient(135deg, #ff6b6b, #ff4444);
			color: #fff;
			font-size: 36rpx;
			font-weight: 700;
			flex-shrink: 0;
			margin-right: 20rpx;
		}
		.refund-modal__head-text {
			flex: 1;
			min-width: 0;
		}
		.refund-modal__title {
			display: block;
			font-size: 36rpx;
			font-weight: 700;
			color: #1a1a1a;
			line-height: 1.3;
		}
		.refund-modal__desc {
			display: block;
			margin-top: 8rpx;
			font-size: 24rpx;
			color: #888;
			line-height: 1.5;
		}
		.refund-table__head,
		.refund-table__row {
			display: flex;
			align-items: center;
			padding: 0 16rpx;
			box-sizing: border-box;
		}
		.refund-table__head {
			height: 56rpx;
			background: #f0f4f8;
			border-radius: 10rpx;
			margin-bottom: 12rpx;
			font-size: 22rpx;
			color: #666;
			font-weight: 600;
		}
		.refund-table__row {
			min-height: 88rpx;
			margin-bottom: 12rpx;
			border-radius: 12rpx;
			background: #f8fafc;
			border: 1rpx solid #e8edf2;
		}
		.refund-table__row--disabled {
			background: #ececec;
			border-color: #e0e0e0;
			.col-name,
			.col-original,
			.col-refund-placeholder {
				color: #aaa;
			}
			.col-original {
				// background: #e4e4e4;
			}
		}
		.col-name {
			width: 120rpx;
			flex-shrink: 0;
			font-size: 28rpx;
			color: #333;
			font-weight: 500;
		}
		.col-original {
			width: 140rpx;
			flex-shrink: 0;
			height: 64rpx;
			line-height: 64rpx;
			text-align: center;
			font-size: 28rpx;
			color: #666;
			// background: #eef1f5;
			border-radius: 8rpx;
			margin-right: 100rpx;
		}
		.col-refund {
			flex: 1;
			text-align: right;
		}
		.col-refund-input {
			flex: 1;
			min-width: 0;
			height: 64rpx;
			line-height: 64rpx;
			padding: 0 16rpx;
			font-size: 30rpx;
			font-weight: 600;
			color: #ff4444;
			background: #fff;
			border: 2rpx solid #ffb4b4;
			border-radius: 8rpx;
			box-sizing: border-box;
		}
		.col-refund-placeholder {
			flex: 1;
			text-align: center;
			font-size: 32rpx;
			color: #bbb;
		}
		.refund-reason {
			margin-top: 20rpx;
			padding: 20rpx 16rpx;
			background: #f8fafc;
			border-radius: 12rpx;
			border: 1rpx solid #e8edf2;
		}
		.refund-reason__label {
			display: block;
			font-size: 26rpx;
			color: #666;
			margin-bottom: 12rpx;
		}
		.refund-reason__input {
			width: 100%;
			height: 72rpx;
			padding: 0 20rpx;
			font-size: 28rpx;
			background: #fff;
			border: 1rpx solid #dde3ea;
			border-radius: 8rpx;
			box-sizing: border-box;
		}
		.refund-total {
			display: flex;
			align-items: center;
			justify-content: space-between;
			margin-top: 24rpx;
			padding: 20rpx 24rpx;
			background: #fff5f5;
			border-radius: 12rpx;
			border: 1rpx solid #ffd4d4;
		}
		.refund-total__label {
			font-size: 28rpx;
			color: #666;
		}
		.refund-total__amount {
			font-size: 40rpx;
			font-weight: 700;
			color: #ff4444;
		}
		.refund-modal__confirm {
			background: #ff4444 !important;
		}
		.anniu {
			margin-top: 32rpx;
		}
	}

	.refund-confirm-mask {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100vh;
		background: rgba(0, 0, 0, 0.55);
		z-index: 1100;
	}
	.refund-confirm-dialog {
		position: fixed;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		width: 580rpx;
		background: #fff;
		border-radius: 24rpx;
		z-index: 1101;
		padding: 48rpx 40rpx 36rpx;
		box-sizing: border-box;
		box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.12);
	}
	.refund-confirm-dialog__title {
		font-size: 36rpx;
		font-weight: 700;
		color: #1a1a1a;
		text-align: center;
		margin-bottom: 36rpx;
	}
	.refund-confirm-dialog__content {
		text-align: center;
		margin-bottom: 48rpx;
	}
	.refund-confirm-dialog__line1 {
		display: flex;
		align-items: baseline;
		justify-content: center;
		flex-wrap: wrap;
		line-height: 1.5;
	}
	.refund-confirm-dialog__text {
		font-size: 30rpx;
		color: #333;
	}
	.refund-confirm-dialog__amount {
		font-size: 44rpx;
		font-weight: 700;
		color: #ff4444;
		margin-left: 8rpx;
	}
	.refund-confirm-dialog__line2 {
		display: block;
		margin-top: 20rpx;
		font-size: 28rpx;
		color: #666;
		line-height: 1.5;
	}
	.refund-confirm-dialog__actions {
		display: flex;
		justify-content: space-between;
		gap: 24rpx;
	}
	.refund-confirm-dialog__btn {
		flex: 1;
		height: 84rpx;
		line-height: 84rpx;
		text-align: center;
		border-radius: 42rpx;
		font-size: 32rpx;
	}
	.refund-confirm-dialog__btn--cancel {
		background: #f5f7fa;
		color: #666;
	}
	.refund-confirm-dialog__btn--ok {
		background: #ff4444;
		color: #fff;
		font-weight: 600;
	}
	
	.zengsongone.huanche-verify-modal {
		max-height: 85vh;
		display: flex;
		flex-direction: column;
		padding: 32rpx;
		.tops {
			margin-bottom: 24rpx;
			flex-shrink: 0;
		}
		.huanche-verify-scroll {
			flex: 1;
			min-height: 0;
			max-height: 52vh;
		}
		.huanche-field-label {
			font-size: 28rpx;
			color: #333;
			margin-bottom: 12rpx;
		}
		.huanche-sub {
			font-size: 22rpx;
			color: #999;
		}
		.huanche-field-input {
			width: 100%;
			height: 80rpx;
			background: #f5f7fa;
			border-radius: 10rpx;
			padding: 0 20rpx;
			margin-bottom: 24rpx;
			box-sizing: border-box;
		}
		.verify-damage-upload-wrap {
			display: flex;
			flex-wrap: wrap;
			gap: 16rpx;
			margin-bottom: 24rpx;
		}
		.verify-damage-item,
		.verify-damage-add {
			width: 140rpx;
			height: 140rpx;
			border-radius: 10rpx;
			overflow: hidden;
			position: relative;
		}
		.verify-damage-item {
			image {
				width: 100%;
				height: 100%;
			}
		}
		.verify-damage-item-uploading {
			.verify-damage-upload-mask {
				position: absolute;
				left: 0;
				top: 0;
				right: 0;
				bottom: 0;
				background: rgba(0, 0, 0, 0.45);
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				gap: 8rpx;
			}
			.verify-damage-upload-mask-text {
				font-size: 22rpx;
				color: #fff;
			}
		}
		.verify-damage-del {
			position: absolute;
			right: 0;
			top: 0;
			width: 36rpx;
			height: 36rpx;
			background: rgba(0, 0, 0, 0.55);
			color: #fff;
			font-size: 24rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			border-bottom-left-radius: 8rpx;
		}
		.verify-damage-add {
			background: #f5f7fa;
			border: 1rpx dashed #cdd3dd;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			color: #999;
			font-size: 22rpx;
		}
		.anniu {
			margin-top: 16rpx;
			flex-shrink: 0;
			.qd.qd-disabled {
				opacity: 0.55;
				pointer-events: none;
			}
		}
	}
	
	/* 换车弹窗样式 */
	.change-bike-modal {
		position: fixed;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		width: 680rpx;
		max-height: 90vh;
		background: #FFFFFF;
		border-radius: 24rpx;
		z-index: 1000;
		box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);
		overflow: hidden;
		display: flex;
		flex-direction: column;
		
		.modal-header {
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 32rpx 40rpx;
			border-bottom: 1rpx solid #F0F2F5;
			
			.modal-title {
				font-size: 36rpx;
				font-weight: 600;
				color: #333;
			}
			
			.modal-close {
				width: 48rpx;
				height: 48rpx;
				line-height: 48rpx;
				text-align: center;
				font-size: 48rpx;
				color: #909399;
				border-radius: 50%;
				transition: all 0.3s;
				
				&:active {
					background: #F5F7FA;
					color: #606266;
				}
			}
		}
		
		.modal-content {
			flex: 1;
			padding: 40rpx;
			overflow-y: auto;
			
			.form-section {
				margin-bottom: 40rpx;
				
				&:last-child {
					margin-bottom: 0;
				}
				
				.section-title {
					font-size: 30rpx;
					font-weight: 600;
					color: #333;
					margin-bottom: 24rpx;
					display: flex;
					align-items: center;
					
					.required {
						color: #FF4444;
						margin-left: 4rpx;
					}
				}
				
				.form-item {
					margin-bottom: 32rpx;
					
					&:last-child {
						margin-bottom: 0;
					}
					
					.form-label {
						display: flex;
						align-items: center;
						margin-bottom: 16rpx;
						
						.label-text {
							font-size: 28rpx;
							color: #333;
							font-weight: 500;
						}
						
						.label-tip {
							font-size: 24rpx;
							color: #909399;
							margin-left: 8rpx;
						}
					}
					
					.form-input {
						width: 100%;
						height: 88rpx;
						background: #F5F7FA;
						border-radius: 12rpx;
						padding: 0 24rpx;
						font-size: 28rpx;
						color: #333;
						box-sizing: border-box;
						
						&::placeholder {
							color: #C0C4CC;
						}
					}
					
					.input-with-scan {
						display: flex;
						align-items: center;
						background: #F5F7FA;
						border-radius: 12rpx;
						padding: 0 20rpx;
						box-sizing: border-box;
						
						.scan-icon {
							width: 48rpx;
							height: 48rpx;
							display: flex;
							align-items: center;
							justify-content: center;
							flex-shrink: 0;
							margin-right: 12rpx;
							border-radius: 8rpx;
							transition: all 0.3s;
							
							&:active {
								background: rgba(76, 151, 231, 0.1);
							}
						}
						
						.form-input-with-icon {
							flex: 1;
							height: 88rpx;
							font-size: 28rpx;
							color: #333;
							border: none;
							background: transparent;
							
							&::placeholder {
								color: #C0C4CC;
							}
						}
					}
					
					.form-textarea {
						width: 100%;
						min-height: 160rpx;
						background: #F5F7FA;
						border-radius: 12rpx;
						padding: 20rpx 24rpx;
						font-size: 28rpx;
						color: #333;
						box-sizing: border-box;
						line-height: 1.6;
						
						&::placeholder {
							color: #C0C4CC;
						}
					}
					
					.picker-item {
						display: flex;
						justify-content: space-between;
						align-items: center;
						height: 88rpx;
						background: #F5F7FA;
						border-radius: 12rpx;
						padding: 0 24rpx;
						
						.picker-text {
							font-size: 28rpx;
							color: #333;
							
							&.placeholder {
								color: #C0C4CC;
							}
						}
					}
					
					.upload-container {
						.upload-preview {
							position: relative;
							width: 200rpx;
							height: 200rpx;
							border-radius: 12rpx;
							overflow: hidden;
							
							.preview-image {
								width: 100%;
								height: 100%;
							}
							
							.delete-btn {
								position: absolute;
								top: 8rpx;
								right: 8rpx;
								width: 40rpx;
								height: 40rpx;
								background: rgba(0, 0, 0, 0.6);
								border-radius: 50%;
								display: flex;
								align-items: center;
								justify-content: center;
							}
						}
						
						.upload-btn {
							width: 200rpx;
							height: 200rpx;
							background: #F5F7FA;
							border: 2rpx dashed #C0C4CC;
							border-radius: 12rpx;
							display: flex;
							flex-direction: column;
							align-items: center;
							justify-content: center;
							transition: all 0.3s;
							
							&:active {
								background: #EBEDF0;
								border-color: #4C97E7;
							}
							
							.upload-text {
								margin-top: 12rpx;
								font-size: 24rpx;
								color: #4C97E7;
							}
						}
					}
				}
				
				.form-divider {
					text-align: center;
					color: #909399;
					font-size: 24rpx;
					margin: 16rpx 0;
				}
			}
		}
		
		.modal-footer {
			display: flex;
			padding: 24rpx 40rpx 40rpx;
			gap: 24rpx;
			border-top: 1rpx solid #F0F2F5;
			
			.footer-btn {
				flex: 1;
				height: 88rpx;
				line-height: 88rpx;
				text-align: center;
				border-radius: 44rpx;
				font-size: 32rpx;
				font-weight: 500;
				transition: all 0.3s;
				
				&.cancel-btn {
					background: #F5F7FA;
					color: #666;
					
					&:active {
						background: #EBEDF0;
					}
				}
				
				&.confirm-btn {
					background: linear-gradient(90deg, #4C97E7 0%, #3A7EDB 100%);
					color: #fff;
					box-shadow: 0 4rpx 12rpx rgba(58, 126, 219, 0.3);
					
					&:active {
						transform: scale(0.98);
						box-shadow: 0 2rpx 8rpx rgba(58, 126, 219, 0.2);
					}
				}
			}
		}
	}
	
	.maskone, .mask {
		position: fixed;
		top: 0; left: 0;
		width: 100%; height: 100%;
		background: rgba(0,0,0,0.5);
		z-index: 99;
	}
	
	.maskloadpage {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		background: #fff;
		border-radius: 40rpx 40rpx 0 0;
		padding: 50rpx;
		z-index: 200;
		box-sizing: border-box;
		
		.top_info {
			display: flex;
			align-items: center;
			justify-content: center;
			margin-bottom: 30rpx;
			image { width: 50rpx; height: 50rpx; margin-right: 20rpx; }
			.masktxt { font-size: 40rpx; font-weight: 600; }
		}
		.tipsimg {
			display: flex; justify-content: center; margin: 50rpx 0;
			image { width: 400rpx; height: 200rpx; }
		}
		.btn_box {
			display: flex; justify-content: space-between;
			.btn3, .btn4 {
				width: 45%; height: 90rpx; border-radius: 45rpx;
				display: flex; align-items: center; justify-content: center; font-size: 32rpx;
			}
			.btn3 { background: #4C97E7; color: #fff; }
			.btn4 { border: 1rpx solid #ccc; color: #666; }
		}
	}
</style>