uniapp map地图导航/地图路线

vue3

*创建nvue页面

javascript 复制代码
// html
<!-- 地图区域 -->
<view class="map-section">
	<map class="map" :latitude="dqLat" :longitude="dqLon" 
		:scale="scale" :show-location="true" 
		:markers="markers" :polyline="polyline" :enable-zoom="true" 
		:enable-scroll="true" :enable-rotate="false" :enable-traffic="true"></map>
</view>
// 样式
/* 地图区域 */
.map-section {
	width: 750rpx;
	flex: 1;
	background-color: #E5E5E5;
	
	/* #ifndef APP  */
	min-height: 800rpx;
	/* #endif */
}

.map {
	width: 750rpx;
	flex: 1;
	/* #ifndef APP  */
	min-height: 800rpx;
	/* #endif */
}	

js

javascript 复制代码
// 获取两个经纬度中间点
	getCenterPoint(point1, point2) {
		// console.log(point1, point2);
		// 角度转弧度(JS 数学函数用弧度计算)
		const rad = Math.PI / 180;
		const lat1 = Number(point1.lat) * rad;
		const lng1 = Number(point1.lng) * rad;
		const lat2 = Number(point2.lat) * rad;
		const lng2 = Number(point2.lng) * rad;
		// 球面中点计算公式
		const Bx = Math.cos(lat2) * Math.cos(lng2 - lng1);
		const By = Math.cos(lat2) * Math.sin(lng2 - lng1);
		const latMid = Math.atan2(
		    Math.sin(lat1) + Math.sin(lat2),
		    Math.sqrt((Math.cos(lat1) + Bx) ** 2 + By ** 2)
		);
		const lngMid = lng1 + Math.atan2(By, Math.cos(lat1) + Bx);
		
		// 弧度转回角度
		return {
		    lat: Number((latMid / rad).toFixed(6)),
		    lng: Number((lngMid / rad).toFixed(6))
		};
	},
// 轮询改变当前定位,更新路线
	const rollPoling = () =>{
	// api接口
		accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
			//司机到起点
			var startRoute = [];
			// 接口返回的字符串路线信息
			if(res.data.directionDrivingResult.steps){
				var start_steps = JSON.parse(res.data.directionDrivingResult.steps)
				for (let i = 0; i < start_steps.length; i++) {
					const poLen1 = start_steps[i].polyline.split(";");
					for (let j = 0; j < poLen1.length; j++) {
						console.log();
						startRoute.push({
							longitude: parseFloat(poLen1[j].split(",")[0]),
							latitude: parseFloat(poLen1[j].split(",")[1])
						});
					}
				}
				console.log(start_steps);
			}
			// console.log(startRoute);
			// 起点到终点
			let datad = res.data.order
			var points = [];
			var steps = JSON.parse(datad.steps)
			for (let i = 0; i < steps.length; i++) {
				const poLen = steps[i].polyline.split(";");
				for (let j = 0; j < poLen.length; j++) {
					points.push({
						longitude: parseFloat(poLen[j].split(",")[0]),
						latitude: parseFloat(poLen[j].split(",")[1])
					});
				}
			}
			
			if([4,5,6].indexOf(res.data.order.orderStatus) > -1){
				scale.value = 17.5
				dqLat.value = res.data.order.driverLatitude
				dqLon.value = res.data.order.driverLongitude
				polyline.value = [ {
					points: startRoute,
					color: '#104FB9',
					width: 10,
					arrowLine: true,
				}]
				markers.value = [
					{
						id: 1,
						longitude: Number(datad.departLongitude),
						latitude: Number(datad.departLatitude),
						iconPath: '/static/index/start.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '起点-'+(datad.departAddressDetails || datad.departAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
					{
						id: 2,
						longitude: Number(datad.arriveLongitude),
						latitude: Number(datad.arriveLatitude),
						iconPath: '/static/index/end.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
					{
						id: 3,
						longitude: Number(datad.driverLongitude),
						latitude: Number(datad.driverLatitude),
						iconPath: '/static/driverIcon.png',
						width: 40,
						height: 40,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: res.data.directionDrivingResult.distance+'km',
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
				]
			}else{
				// 完成的路线
				let endRote = []
				if(res.data.order.orderStatus == 7){
					accountServiceOrder_serviceOrderRouteLonLat({orderId: orderId.value}).then(res=>{
						const poLen2 = res.data.split(";");
						for (let j = 0; j < poLen2.length; j++) {
							endRote.push({
								longitude: parseFloat(poLen2[j].split(",")[0]),
								latitude: parseFloat(poLen2[j].split(",")[1])
							});
						}
						console.log(endRote);
						polyline.value = [{
							points: endRote,
							color: '#FF6B35',
							width: 10,
							arrowLine: true,
						}]
					})
				}else{
					polyline.value = [{
						points: points,
						color: '#FF6B35',
						width: 10,
						arrowLine: true,
					}]
				}
				
				markers.value = [
					{
						id: 1,
						longitude: Number(datad.departLongitude),
						latitude: Number(datad.departLatitude),
						iconPath: '/static/index/start.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '起点-'+(datad.departAddressDetails || datad.departAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
					{
						id: 2,
						longitude: Number(datad.arriveLongitude),
						latitude: Number(datad.arriveLatitude),
						iconPath: '/static/index/end.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
				]
			}
			
			if(res.data.routeAddressList.length > 0){
				res.data.routeAddressList.forEach((el,index) =>{
					markers.value.push({
						id: 10 * index,
						longitude: Number(el.routeAddressLon),
						latitude: Number(el.routeAddressLat),
						iconPath: '/static/index/tujingdian.png',
						width: 12,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '途经点-'+el.routeAddress,
							color: '#333333',
							fontSize: 10,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					})
				})
			}
		})
	}
	let pageData = reactive({
		detail:{}
	})
		let totalPrice = ref(0)
	let dqLon = ref(null)
	let dqLat = ref(null)
	let scale = ref(13.5)
	let time = ref(null)
	const getdata = () =>{
	
		accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
			// console.log(res.data.order);
			pageData.detail = res.data.order
			totalPrice.value = ((res.data.order.payPrice || 0) + (res.data.order.backPaymentMoney || 0)).toFixed(2)
				
			let center = getCenterPoint(
				{lat: res.data.order.arriveLatitude, lng: res.data.order.arriveLongitude}, //起点经纬度
				{lat: res.data.order.departLatitude, lng: res.data.order.departLongitude} //终点经纬度
			)
			let radiusNum = Math.abs((res.data.order.arriveLatitude - center.lat) * 100000)
			// 动态改变视图缩放
			if(radiusNum < 3000){
				scale.value = 14
			}else if(radiusNum >= 3000 && radiusNum < 6000){
				scale.value = 13
			}else if(radiusNum >= 6000 && radiusNum < 9000){
				scale.value = 12
			}else if(radiusNum >= 9000 && radiusNum < 12000){
				scale.value = 11
			}else if(radiusNum >= 12000){
				scale.value = 10
			}
			dqLat.value = center.lat
			dqLon.value = center.lng
			rollPoling()
			
			if([3,4,5,6].indexOf(res.data.order.orderStatus) > -1){
				time.value = setInterval(()=>{
					rollPoling()
				},5000)
				butShow.value = true
			}if(res.data.order.orderStatus == 7){
				let newTime = new Date().getTime()
				let nobutTime = new Date(res.data.order.finishLimitTime).getTime()
				butShow.value = nobutTime > newTime ? true : false
			}else{
				clearInterval(time.value)
			}
			
		})
	}

实例Demo

里面的api更换为自己的,公共方法"com."去掉,不用的功能删掉,使用了uview-plus

javascript 复制代码
<template>
	<view class="order-page">
		<!-- 顶部导航栏 -->
		<up-navbar safeAreaInsetTop autoBack left-text="返回" bgColor="transparent">
		</up-navbar>
		<!-- 地图区域 -->
		<view class="map-section">
			<map class="map" :latitude="dqLat" :longitude="dqLon" 
				:scale="scale" :show-location="true" 
				:markers="markers" :polyline="polyline" :enable-zoom="true" 
				:enable-scroll="true" :enable-rotate="false" :enable-traffic="true"></map>
		</view>
		<view class="contPart">
			<!-- 红色提示横幅 -->
			<view class="warning-banner">
				<text class="warning-title">温馨提示</text>
				<text class="warning-text"> 价格以最终订单结束为准</text>
				<view class="radiuDiv"></view>
			</view>
			<!-- 订单状态卡片 -->
			<view class="order-status-card" v-if="[1,2].indexOf(pageData.detail.orderStatus) > -1">
				<view class="order-status-left" v-if="pageData.detail.orderStatus == 1">
					<text class="order-title">待支付 合计:{{pageData.detail.payPrice}}元</text>
					<view class="u-flex-row">
						<text class="col999 font28 mar-r10">目的地</text>
						<text class="font28 col333"> {{ pageData.detail.arriveAddress || pageData.detail.arriveAddressDetails}}</text>
					</view>
				</view>
				<view class="order-status-left" v-if="pageData.detail.orderStatus == 2">
					<text class="order-title">正在寻找司机,请耐心等待</text>
					<view class="u-flex-row">
						<text class="col999 font28 mar-r10">目的地</text>
						<text class="font28 col333"> {{ pageData.detail.arriveAddress || pageData.detail.arriveAddressDetails}}</text>
					</view>
				</view>
				<view class="height-60"></view>
			</view>
			<view class="order-status-card" v-if="[3,4,5,6,7].indexOf(pageData.detail.orderStatus) > -1">
				<view class="dengdai mar-t10" v-if="pageData.detail.orderStatus == 4">
					<text class="font40 fontbold">司机正在赶来</text>
				</view>
				<view class="dengdai mar-t10" v-if="pageData.detail.orderStatus == 5">
					<text class="font40 fontbold">司机已到约定上车点</text>
					<!-- <text class="font26 mar-t10 colED5858">司机可免费等5分钟,超过五分钟需收取额外等待费用</text> -->
				</view>
				<view class="dengdai mar-t10 " v-if="pageData.detail.orderStatus == 6">
					<text class="font40 fontbold">您已上车,预计{{timeFormat(pageData.detail.appointmentEndTime,'hh:MM')}}到达</text>
					<view class="u-flex-row mar-t10">
						<text class="col999 font28 mar-r10">正在前往目的地 </text>
						<text class="font28 colED5858"> {{pageData.detail.arriveAddressDetails}} </text>
					</view> 
				</view>
				<view class="dengdai mar-t10 " v-if="pageData.detail.orderStatus == 7">
					<view class="u-flex-row flexbetween">
						<text class="font40 fontbold">行程已顺利结束</text>
						<view class="u-flex-row" style="align-items: center;" @click="priceShow = !priceShow">
							<text class="font32">合计</text>
							<text class="font48 priceCol fontbold"> {{totalPrice}} </text>
							<text class="font32">元</text>
							<u-icon :name="!priceShow ?'arrow-down-fill':'arrow-up-fill'" size="12"></u-icon>
						</view>
					</view>
					<text class="col999 font28 mar-t10">{{pageData.detail.finishTime}}送达 </text>
					
					<view class="bgF7 u-p-20 mar-t20 radiu16" v-if="priceShow">
						<view class="u-flex-row flexbetween">
							<text class="font32 ">最终订单价</text>
							<text class="font32">{{totalPrice}}元</text>
						</view>
						<text class="col999 font28 mar-t10">总里程{{pageData.detail.kilometreDistance}}公里</text>
						<view class="u-flex-row flexbetween mar-t15">
							<text class="font32 ">支付金额</text>
							<text class="font32">{{pageData.detail.payPrice}}元</text>
						</view>
						<view class="u-flex-row flexbetween mar-t15" v-if="pageData.detail.backPaymentMoney">
							<text class="font32 ">补交金额</text>
							<text class="font32">{{pageData.detail.backPaymentMoney}}元</text>
						</view>
						<view class="u-flex-row flexbetween mar-t15" v-if="pageData.detail.tipPrice">
							<text class="font32 ">红包打赏</text>
							<text class="font32">{{pageData.detail.tipPrice || 0}}元</text>
						</view>
						<!-- <text class="col999 font28 mar-t10">2025-10-15  16:10:30 </text> -->
					</view>
				</view>
				<view class=""> 
					<view class="order-status-content">
						<view class="">
							<text class="font52 fontbold"> {{pageData.detail.licencePlateNumber}} </text>
							<text class="col999 font28 mar-t10">
								{{ pageData.detail.vehicleColour }} · {{ pageData.detail.vehicleBrand }} | {{ pageData.detail.vehicleSaddleTypeLabel }} · {{ pageData.detail.vehicleTypeName }}
							</text>
						</view>
						<image class="car-image" :src="pageData.detail.vehicleTypeThumb" mode="aspectFit"></image>
					</view>
					<view class="userPerson flexbetween flexa u-flex-row">
						<view class="flexalign u-flex-row">
							<u-avatar :src="pageData.detail.driverHead"></u-avatar>
							<view class="mar-l15">
								<text class="font34 col333 u-m-b-6">{{ pageData.detail.driverName}}</text>
								<u-rate :count="5" v-model="pageData.detail.driverStar" 
									size="15" gutter="1" disabled></u-rate>
							</view>
						</view>
						<view class="flexalign u-flex-row">
							<view class="options" @click="collect">
								<!-- #A8BDE0 -->
								<u-icon name="star" :color="'#104FB9'" size="18" v-if="collTag == 0"></u-icon>
								<u-icon name="star-fill" :color="'#104FB9'" size="18" v-if="collTag == 1"></u-icon>
							</view>
							<view class="options mar-l30" @click="goPhone(pageData.detail.driverPhone)"
								v-if="butShow">
								<!-- #A8BDE0 -->
								<u-icon name="phone-fill" color="#104FB9" size="18"></u-icon>
							</view>
						</view>
					</view>
					<view class="opts flexbetween mar-t30 u-flex-row">
						<view class="optsIts" @click="help">
							<image class="optsIts-img" src="/static/index/order1.png" mode="aspectFill"></image>
							<text class="font28 col666 mar-t20">需要帮助</text>
						</view>
						<view class="optsIts" @click="complainCli">
							<image class="optsIts-img" src="/static/index/order2.png" mode="aspectFill"></image>
							<text class="font28 col666 mar-t20">{{complaintTag == 0?'投诉司机':'已投诉'}}</text>
						</view>
						<view class="optsIts" @click="shareRoute">
							<image class="optsIts-img2" src="/static/index/order3.png" mode="aspectFill"></image>
							<text class="font28 col666 mar-t20">行程分享</text>
						</view>
						<view class="optsIts" @click="redPackCli">
							<image class="optsIts-img" src="/static/index/order4.png" mode="aspectFill"></image>
							<text class="font28 col666 mar-t20">红包打赏</text>
						</view>
					</view>
				</view>
			</view>
			<view class="order-status-card" v-if="[8,9].indexOf(pageData.detail.orderStatus) > -1">
				<view class="order-status-left">
					<text class="order-title">订单已取消</text>
					<!-- <view class="u-flex-row">
						<text class="col999 font28 mar-r10">目的地</text>
						<text class="font28 col333"> {{pageData.detail.arriveAddressDetails}}</text>
					</view> -->
				</view>
				<!-- <view class="order-status-content">
					<view class="">
						<text class="waiting-time">已等待15秒</text>
						<text class="col999 font28">预计一分钟派给司机</text>
					</view>
					<image class="car-image" src="/static/index/car1.png" mode="aspectFit"></image>
				</view> -->
			</view>
			<!-- 底部按钮区域 -->
			<view class="bgfff height-30"></view>
			<view class="bottom-actions" v-if="pageData.detail.orderStatus == 1">
				<button class="cancel-btn" hover-class="cancel-btn-hover" @click="noOrderCancel">
					<text class="butText">取消订单</text>
				</button>
				<button class="rebook-btn mar-l20" hover-class="rebook-btn-hover"
					@click="twoPayCli" >
					<text class="butText colfff">立即支付</text>
				</button>
			</view>
			<view class="bottom-actions" v-if="[2,3,4,5].indexOf(pageData.detail.orderStatus) > -1">
				<button class="cancel-btn" hover-class="cancel-btn-hover" @click="cancel">
					<text class="butText">取消订单</text>
				</button>
			</view>
			<view class="bottom-actions" v-if="pageData.detail.orderStatus == 6 && bujiao == 2">
				<button class="rebook-btn" hover-class="rebook-btn-hover" @click="makeUpFor">
					<text class="butText colfff">补交费用{{ bujiaoData.payStatus == 1 ? '(已支付)' : '' }}</text>
				</button>
			</view>
			<view class="bottom-actions" v-if="[7].indexOf(pageData.detail.orderStatus) > -1">
				<!-- <button class="cancel-btn" hover-class="cancel-btn-hover" @click="delOrder">
					<text class="butText">删除订单</text>
				</button> -->
				<button class="rebook-btn " hover-class="rebook-btn-hover" 
					@click="route('/pagesIndex/carMap/evaluate',{orderId: orderId})" 
					v-if="pageData.detail.evaluateStatus == 0">
					<text class="butText colfff">立即评价</text>
				</button>
				<button class="rebook-btn " hover-class="rebook-btn-hover"
					@click="route('/pagesIndex/carMap/evaluateLook',{orderId: orderId})" 
					v-if="pageData.detail.evaluateStatus == 1">
					<text class="butText colfff">查看评价</text>
				</button>
			</view>
		</view>
		<!-- 投诉内容 -->
		<bottom-popup ref="complainPop" type="none" title="投诉信息" >
			<!-- <template #title>
				<text class="font36 colOrigin fontbold "
					v-if="complainData.complaintStatus == 0">审核中</text>
				<text class="font36 colGreen fontbold "
					v-if="complainData.complaintStatus == 1">已通过</text>
				<text class="font36 priceCol fontbold "
					v-if="complainData.complaintStatus == 2">已拒绝</text>	
			</template> -->
			<view class=" mar-t20 mar-l30 ">
				<text class=" font28 col666">投诉原因</text>
				<text class=" font28 mar-t10 mar-l30">{{complainData.complaintReason}}</text>
			</view>
			<view class=" mar-t20 mar-l30 ">
				<text class=" font28 col666 mar-b10">具体情况</text>
				<textarea class="textYuStyle font28 col333 " v-model="complainData.complaintContent" 
					placeholder-class="font28 col999" :maxlength="500" disabled></textarea>
			</view>
			<view class=" mar-t20 mar-l30 ">
				<text class=" font28 col666">图片</text>
				<view class="flexwrap flexrow">
					<image class=" mar-r15 mar-t15 radiu12" style="width: 150rpx;height: 150rpx;"
						v-for="(it,ind) in complainData.complaintPicture.split(',')" :src="it" mode="aspectFill"
						@click="com.lookImg(complainData.complaintPicture.split(','),ind)"></image>
				</view>
			</view>
			<view class="height-60"></view>
		</bottom-popup>
		<!-- 二次支付 -->
		<bottom-popup ref="twoPay" type="none" title="支付" >
			<template #title>
				<text class="font36 priceCol fontbold mar-l20">{{pageData.detail.payPrice}}元</text>
			</template>
			<payType ref="payTypeRef" @radioChange="e => payTypeVal = e" ></payType>
			<view class="bottom-actions">
				<button class="rebook-btn " hover-class="rebook-btn-hover" 
					@click="yesTwoPayment" >
					<text class="butText colfff">确认支付</text>
				</button>
			</view>
		</bottom-popup>
		<!-- 联系客服 -->
		<bottom-popup ref="phonePop" type="none" title="请选择您要联系的客服">
			<template #title>
				<!-- <text class="col999 font28 mar-t10">我们根据选择为您提供服务</text> -->
			</template>
			<view class="width-750">
				<view class="goPhoneIts u-flex-row " 
					@click="goPhone(serviceData.platformServePhone);phonePop.close()">
					<image class="helpImg mar-r30" src="/static/index/help2.png" mode=""></image>
					<view class="">
						<text class="font44">{{serviceData.platformServePhone}}</text>
						<text class="font28 col666">官方客服</text>
					</view>
				</view>
				<view class="goPhoneIts u-flex-row " 
					@click="goPhone(serviceData.motorcadeServePhone);phonePop.close()"
					v-if="serviceData.motorcadeServePhone">
					<image class="helpImg mar-r30" src="/static/index/help1.png" mode=""></image>
					<view class="">
						<text class="font44">{{serviceData.motorcadeServePhone}}</text>
						<text class="font28 col666">车队服务电话</text>
					</view>
				</view>
			</view>
			<view class="height-60"></view>
		</bottom-popup>
		<!-- 分享 -->
		<sharePop ref="sharePopup" title="我正在使用舒客畅游打车" :url="`/pagesIndex/carMap/carMapOrderShare?orderId=${orderId}`"></sharePop>
		<!-- 红包	 -->
		<redPack ref="redPackRef" :id="orderId"></redPack>
		<!-- 取消订单 -->
		<bottom-popup ref="cancelPop" type="none" title="取消订单">
			<view style="padding: 20rpx;">
				<scroll-view :scroll-y="true" style="height: 400rpx">
					<u-radio-group v-model="radiovalue1" placement="column" @change="groupChange"
						borderBottom>
						<u-radio :customStyle="{margin: '10rpx'}" 
							v-for="(item, index) in radiolist1" :key="index"
							:label="item.dictLabel" :name="item.dictLabel" >
						</u-radio>
					</u-radio-group>
				</scroll-view>
				<view class="bgF7 radiu8 mar-t20" style="padding: 20rpx;" v-if="radiovalue1.includes('其他')">
					<textarea class="textYuStyle font28 col333 " v-model="cancelReason" placeholder="补充更详细的取消说明" :maxlength="500"
						placeholder-class="font28 col999" ></textarea>
					<view class="char-count">
						<text class="font22 col999">{{ cancelReason.length }}/500</text>
					</view>
				</view>
			</view>
			<view class="bottom-actions">
				<button class="cancel-btn" hover-class="cancel-btn-hover" @click="cancelPop.close()">
					<text class="butText">不取消了</text>
				</button>
				<view class="width-30"></view>
				<button class="rebook-btn mar-l20" hover-class="rebook-btn-hover" 
					@click="cancelOrder" >
					<text class="butText colfff">确认</text>
				</button>
			</view>
		</bottom-popup>
		<!-- 违约金 -->
		<bottom-popup ref="payPop" type="none" title="爽约费" >
			<template #title>
				<text class="font36 priceCol fontbold mar-l20">{{cancelData.appointmentMoney}}元</text>
			</template>
			<view class="mar-t30 page30">
				<text class="font28 col999" v-if="cancelData.appointmentMoney">
					司机已达上车点,因平台规定您需要支付爽约费
				</text>
				<text class="font28 col999" v-else>
					本次取消无需支付爽约费
				</text>
			</view>
			<view class="flexrow mar-t-b20 flexRight">
				<text class="font36 mar-r20">退款金额</text>
				<text class="font36 priceCol fontbold mar-r30">{{cancelData.refundPrice}} 元</text>
			</view>
			<!-- <payType ref="payTypeRef" @radioChange="e => pageData.payType = e" ></payType> -->
			<view class="bottom-actions">
				<button class="cancel-btn" hover-class="cancel-btn-hover" @click="payPop.close()">
					<text class="butText">不取消了</text>
				</button>
				<view class="width-30"></view>
				<button class="rebook-btn mar-l20" hover-class="rebook-btn-hover" 
					@click="yesCancel" >
					<text class="butText colfff">确认取消</text>
				</button>
			</view>
		</bottom-popup>
		<!-- 补交费用 -->
		<bottom-popup ref="buJiaoPop" type="none" title="补交费用:" >
			<template #title>
				<text class="font36 priceCol fontbold">
					{{bujiaoData.payPrice}}元
					{{ bujiaoData.payStatus == 1 ? '(已支付)' : '' }}
				</text>
			</template>
			<view class="mar-t30 page30">
				<text class="font28 " v-if="bujiaoData.backPaymentType == 1">
					补交类型:更换行程
				</text>
				<text class="font28 " v-if="bujiaoData.backPaymentType == 2">
					补交类型:包车超时
				</text>
			</view>
			<view class="mar-t30 page30"v-if="bujiaoData.backPaymentType == 1">
				<view class="flexrow">
					<text class="font28 col999">出发地:</text>
					<text class="font28 " >
						{{bujiaoData.departAddressDetails}}
					</text>
					<text class="font26 col999">({{bujiaoData.departAddress}})</text>
				</view>
				<view class="flexrow mar-t20">
					<text class="font28 col999">目的地:</text>
					<text class="font28 " >
						{{bujiaoData.arriveAddressDetails}}
					</text>
					<text class="font26 col999">({{bujiaoData.arriveAddress}})</text>
				</view>
			</view>
			<view class="height-80" v-if="bujiaoData.payStatus == 1"></view>
			<payType ref="payTypeRef" @radioChange="e => payTypeVal = e" v-if="bujiaoData.payStatus == 0"
				:balance="bujiaoConfirm.balance" :credit="bujiaoConfirm.creditLimit"></payType>
			<view class="bottom-actions" v-if="bujiaoData.payStatus == 0">
				<button class="rebook-btn " hover-class="rebook-btn-hover" 
					@click="yesBujiao" >
					<text class="butText colfff">确认支付</text>
				</button>
			</view>
		</bottom-popup>
	</view>
</template>

<script setup>
	import { reactive, ref , onUnmounted } from 'vue'
	import { onLoad , onReady , onBackPress } from '@dcloudio/uni-app'
	import com from '@/utils/common'
	import { route , timeFormat } from '@/uni_modules/uview-plus';
	
	import {
		accountServiceOrder_detail , dictDataByType,
		accountCollection_collectionOrCancelCollection,
		accountServiceOrder_orderCancel , accountServiceOrder_noPayCancel,
		appointmentOrderCancel  , travelVehicleOrderCancel,
		accountServiceOrder_againToPay , accountServiceOrder_checkPhone,
		serviceOrderComplaint_check , accountServiceOrder_payBackFee,
		accountServiceOrder_payBackFeeConfirm , payBackFeePaySub,
		accountServiceOrder_serviceOrderRouteLonLat
	} from "@/api/nvueAPI.js"
	
	import payment from "@/utils/payment.js"
	
	let priceShow = ref(false)//金额明细
	// 取消订单
	let radiolist1 = ref([ ])
	function cancelCause (){
		dictDataByType({dictType: 'user_cancel_order'}).then(res=>{
			radiolist1.value = res.data
		})
	}
	let cancelReason = ref('') //传值
	let radiovalue1 = ref('') //radio默认
	const groupChange = (val) => {
		cancelReason.value = val.includes('其他') ? '' : val
		radiovalue1.value = val
	}
	//未支付取消订单
	const noOrderCancel = () => {
		accountServiceOrder_noPayCancel({ orderId: orderId.value }).then(res=>{
			getdata()
			if(reloadList.value){
				uni.$emit('orderList',{tit:'已取消订单',it: pageData.detail})
			}
		})
	}
	// 取消弹窗
	let cancelPop = ref(null)
	let payPop = ref(null)
	let cancelData = ref({})
	const cancel = () => {
		accountServiceOrder_orderCancel({orderId: orderId.value}).then(res=>{
			cancelData.value = res.data
			if(res.data.appointmentMoney == 0){
				cancelPop.value.showDiv()
			}else{
				payPop.value.showDiv()
			}
		})
	}
	// 确定取消
	const yesCancel = () =>{
		payPop.value.close()
		cancelPop.value.showDiv()
	}
	// 取消订单
	const cancelOrder = () => {
		if(pageData.detail.orderType == 1){ //已支付的订单 取消订单(此接口只适用约车的订单 orderType == 1 && (orderStatus == 2 || orderStatus == 3 || orderStatus == 4 || orderStatus == 5))
			appointmentOrderCancel({
				orderId: orderId.value,cancelReason: cancelReason.value
			}).then(res=>{
				getdata()
				cancelPop.value.close()
				if(reloadList.value){
					uni.$emit('orderList',{tit:'已取消订单',it: pageData.detail})
				}
			})
		}else if(pageData.detail.orderType == 3){ //已支付的订单 取消订单(此接口只适用约车的订单 orderType == 1 && (orderStatus == 2 || orderStatus == 3 || orderStatus == 4 || orderStatus == 5))
			travelVehicleOrderCancel({
				orderId: orderId.value,cancelReason: cancelReason.value
			}).then(res=>{
				getdata()
				cancelPop.value.close()
				if(reloadList.value){
					uni.$emit('orderList',{tit:'已取消订单',it: pageData.detail})
				}
			})
		}
	}

	let orderId = ref('')
	let pageData = reactive({
		detail:{}
	})
	// 地图标记点
	const markers = ref([])
	// 路线
	const polyline = ref([])
	// 收藏
	let collTag = ref(0)
	let complaintTag = ref(0)
	// 轮询
	const rollPoling = () =>{
		accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
			collTag.value = res.data.collTag
			complaintTag.value = res.data.complaintTag
			//司机到起点
			var startRoute = [];
			if(res.data.directionDrivingResult.steps){
				var start_steps = JSON.parse(res.data.directionDrivingResult.steps)
				for (let i = 0; i < start_steps.length; i++) {
					const poLen1 = start_steps[i].polyline.split(";");
					for (let j = 0; j < poLen1.length; j++) {
						console.log();
						startRoute.push({
							longitude: parseFloat(poLen1[j].split(",")[0]),
							latitude: parseFloat(poLen1[j].split(",")[1])
						});
					}
				}
				console.log(start_steps);
			}
			// console.log(startRoute);
			// 起点到终点
			let datad = res.data.order
			var points = [];
			var steps = JSON.parse(datad.steps)
			for (let i = 0; i < steps.length; i++) {
				const poLen = steps[i].polyline.split(";");
				for (let j = 0; j < poLen.length; j++) {
					points.push({
						longitude: parseFloat(poLen[j].split(",")[0]),
						latitude: parseFloat(poLen[j].split(",")[1])
					});
				}
			}
			
			if([4,5,6].indexOf(res.data.order.orderStatus) > -1){
				scale.value = 17.5
				dqLat.value = res.data.order.driverLatitude
				dqLon.value = res.data.order.driverLongitude
				polyline.value = [ {
					points: startRoute,
					color: '#104FB9',
					width: 10,
					arrowLine: true,
				}]
				markers.value = [
					{
						id: 1,
						longitude: Number(datad.departLongitude),
						latitude: Number(datad.departLatitude),
						iconPath: '/static/index/start.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '起点-'+(datad.departAddressDetails || datad.departAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
					{
						id: 2,
						longitude: Number(datad.arriveLongitude),
						latitude: Number(datad.arriveLatitude),
						iconPath: '/static/index/end.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
					{
						id: 3,
						longitude: Number(datad.driverLongitude),
						latitude: Number(datad.driverLatitude),
						iconPath: '/static/driverIcon.png',
						width: 40,
						height: 40,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: res.data.directionDrivingResult.distance+'km',
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
				]
			}else{
				// 完成的路线
				let endRote = []
				if(res.data.order.orderStatus == 7){
					accountServiceOrder_serviceOrderRouteLonLat({orderId: orderId.value}).then(res=>{
						const poLen2 = res.data.split(";");
						for (let j = 0; j < poLen2.length; j++) {
							endRote.push({
								longitude: parseFloat(poLen2[j].split(",")[0]),
								latitude: parseFloat(poLen2[j].split(",")[1])
							});
						}
						console.log(endRote);
						polyline.value = [{
							points: endRote,
							color: '#FF6B35',
							width: 10,
							arrowLine: true,
						}]
					})
				}else{
					polyline.value = [{
						points: points,
						color: '#FF6B35',
						width: 10,
						arrowLine: true,
					}]
				}
				
				markers.value = [
					{
						id: 1,
						longitude: Number(datad.departLongitude),
						latitude: Number(datad.departLatitude),
						iconPath: '/static/index/start.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '起点-'+(datad.departAddressDetails || datad.departAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
					{
						id: 2,
						longitude: Number(datad.arriveLongitude),
						latitude: Number(datad.arriveLatitude),
						iconPath: '/static/index/end.png',
						width: 30,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '终点-'+(datad.arriveAddressDetails || datad.arriveAddress),
							color: '#333333',
							fontSize: 12,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					},
				]
			}
			
			if(res.data.routeAddressList.length > 0){
				res.data.routeAddressList.forEach((el,index) =>{
					markers.value.push({
						id: 10 * index,
						longitude: Number(el.routeAddressLon),
						latitude: Number(el.routeAddressLat),
						iconPath: '/static/index/tujingdian.png',
						width: 12,
						height: 30,
						anchor: {
							x: 0.5,
							y: 1
						},
						callout: {
							content: '途经点-'+el.routeAddress,
							color: '#333333',
							fontSize: 10,
							borderRadius: 8,
							bgColor: '#FFFFFF',
							padding: 10,
							display: 'ALWAYS',
							textAlign: 'left',
							borderWidth: 1,
							borderColor: '#E5E5E5'
						}
					})
				})
			}
		})
	}
	let totalPrice = ref(0)
	let dqLon = ref(null)
	let dqLat = ref(null)
	let scale = ref(13.5)
	let time = ref(null)
	let butShow = ref(false)
	
	let bujiao = ref(0)
	let bujiaoData = ref({})
	
	const getdata = () =>{
		// 补交费
		accountServiceOrder_payBackFee({orderId: orderId.value}).then(res=>{
			bujiao.value = res.code
			bujiaoData.value = res.data
		})
		accountServiceOrder_detail({orderId: orderId.value}).then(res=>{
			// console.log(res.data.order);
			pageData.detail = res.data.order
			totalPrice.value = ((res.data.order.payPrice || 0) + (res.data.order.backPaymentMoney || 0)).toFixed(2)
				
			let center = com.getCenterPoint(
				{lat: res.data.order.arriveLatitude, lng: res.data.order.arriveLongitude}, 
				{lat: res.data.order.departLatitude, lng: res.data.order.departLongitude} 
			)
			let radiusNum = Math.abs((res.data.order.arriveLatitude - center.lat) * 100000)
			console.log(radiusNum);
			if(radiusNum < 3000){
				scale.value = 14
			}else if(radiusNum >= 3000 && radiusNum < 6000){
				scale.value = 13
			}else if(radiusNum >= 6000 && radiusNum < 9000){
				scale.value = 12
			}else if(radiusNum >= 9000 && radiusNum < 12000){
				scale.value = 11
			}else if(radiusNum >= 12000){
				scale.value = 10
			}
			dqLat.value = center.lat
			dqLon.value = center.lng
			rollPoling()
			
			if([3,4,5,6].indexOf(res.data.order.orderStatus) > -1){
				time.value = setInterval(()=>{
					rollPoling()
				},5000)
				butShow.value = true
			}if(res.data.order.orderStatus == 7){
				let newTime = new Date().getTime()
				let nobutTime = new Date(res.data.order.finishLimitTime).getTime()
				butShow.value = nobutTime > newTime ? true : false
			}else{
				clearInterval(time.value)
			}
			
		})
	}
	let serviceData = ref({})

	let reloadList = ref(false)
	onLoad((op) => {
		if(op.reload){
			reloadList.value = true
		}
		orderId.value = op.orderId
		getdata()
		cancelCause() //取消原因
		
		uni.$on('payRedPack',data=>{
			getdata()
		})
		// 客服
		accountServiceOrder_checkPhone({orderId: orderId.value}).then(res=>{
			serviceData.value = res.data
		})
		
	})
	onUnmounted(()=>{
		uni.$off('payRedPack')
		clearInterval(time.value)
	})
	onBackPress(()=>{
		clearInterval(time.value)
	})
	const goPhone = (e) => {
		com.goPhone(e)
	}

	// 需要帮助
	let phonePop = ref(null)
	const help = () => {
		phonePop.value.showDiv()
	}
	// 分享行程
	let sharePopup = ref(null)
	const shareRoute = () => {
		sharePopup.value.open()
		// uni.shareWithSystem({
		//   summary: '',
		//   href: 'https://uniapp.dcloud.io',
		//   success(){
		//     // 分享完成,请注意此时不一定是成功分享
		//   },
		//   fail(){
		//     // 分享失败
		//   }
		// })
	}
	// 打赏红包
	let redPackRef = ref(null)
	const redPackCli = () => {
		redPackRef.value.open()
	}
	
	const delOrder = () =>{
		uni.showModal({
			title:'确认删除此订单',
			content: '删除后将无法在订单列表中查询订单,请谨慎操作',
			success: (mod) => {
				if(mod.confirm){
					
				}
			}
		})
	}
	
	// 收藏
	const collect = () => {
		accountCollection_collectionOrCancelCollection({
			driverId: pageData.detail.driverId
		}).then(res=>{
			rollPoling()
		})
	}

	//二次支付
	let twoPay = ref(null)
	function twoPayCli () {
		twoPay.value.showDiv()
	}
	let payTypeVal = ref('')
	function yesTwoPayment(){
		accountServiceOrder_againToPay({
			orderId: orderId.value,
			payType: payTypeVal.value
		}).then(res=>{
			if (('APP JSAPI').includes(payTypeVal.value)) {
				payment.weixin(res.data, '约车二次支付',res.data.orderId)
			} else if (('alipay_app').includes(payTypeVal.value)) {
				payment.alipay(res.data, '约车二次支付',res.data.orderId)
			}
		})
	}
	// 投诉
	let complainPop = ref(null)
	let complainData = ref({})
	function complainCli (){
		if(complaintTag.value == 0){
			uni.$u.route('/pagesIndex/carMap/complaint',{orderId: orderId.value})
		}else{
			serviceOrderComplaint_check({orderId: orderId.value}).then(res=>{
				complainData.value = res.data
				complainPop.value.showDiv()
			})
		}
	}
	
	// 补交费用
	let buJiaoPop = ref(null)
	let payTypeRef = ref(null)
	let bujiaoConfirm = ref({})
	function makeUpFor () {
		if(bujiaoData.value.payStatus == 1){
			buJiaoPop.value.showDiv()
			return
		}
		accountServiceOrder_payBackFeeConfirm({
			serviceOrderBackPaymentId: bujiaoData.value.serviceOrderBackPaymentId
		}).then(res=>{
			bujiaoConfirm.value = res.data
			buJiaoPop.value.showDiv()
			setTimeout(()=>{
				if(res.data.creditLimit == 0){
					payTypeRef.value.showList(0)
				}else{
					payTypeRef.value.showList(1)
				}
			},100)
		})
	}
	function yesBujiao () {
		payBackFeePaySub({
			serviceOrderBackPaymentId: bujiaoData.value.serviceOrderBackPaymentId,
			payType: payTypeVal.value
		}).then(res=>{
			if(res.code == 14){
				buJiaoPop.value.close()
				uni.$u.toast('支付成功')
				getdata()
				return
			}
			if (('APP JSAPI').includes(params.payType)) {
				payment.weixin(res.data, '约车补交费用',res.data.orderId)
			} else if (('alipay_app').includes(params.payType)) {
				payment.alipay(res.data, '约车补交费用',res.data.orderId)
			}
		})
	}
</script>

<!-- <style>
	page {
		background-color: #F5F5F5;
	}
</style> -->

<style scoped>
	@import "@/utils/nvueCommon.css";
	.textYuStyle{
		height: 200rpx; width: 690rpx;padding: 10rpx;
		background-color: #f5f5f5;
		border-radius: 12rpx;
	}
	.order-page {
		width: 750rpx;
		flex: 1;
		flex-direction: column;
		background-color: #F5F5F5;
	}

	/* 地图区域 */
	.map-section {
		width: 750rpx;
		flex: 1;
		background-color: #E5E5E5;
		
		/* #ifndef APP  */
		min-height: 800rpx;
		/* #endif */
	}

	.map {
		width: 750rpx;
		flex: 1;
		/* #ifndef APP  */
		min-height: 800rpx;
		/* #endif */
	}

	.contPart {
		/* position: fixed; bottom: 0; left: 0; right: 0; */
		z-index: 100;
	}

	/* 红色提示横幅 */
	.warning-banner {
		width: 750rpx;
		padding-top: 20rpx;
		padding-left: 30rpx;
		padding-right: 30rpx;
		padding-bottom: 40rpx;
		background: #FF3300;
		border-top-left-radius: 20rpx;
		border-top-right-radius: 20rpx;
		position: relative;
		flex-direction: row;
		align-items: center;
	}

	.warning-title {
		font-weight: bold;
		margin-right: 10rpx;
		color: #FFFFFF;
		font-size: 28rpx;
	}

	.warning-text {
		font-size: 26rpx;
		color: #FFFFFF;
	}

	.radiuDiv {
		width: 750rpx;
		height: 20rpx;
		position: absolute;
		left: 0;
		bottom: 0;
		border-top-left-radius: 20rpx;
		border-top-right-radius: 20rpx;
		background-color: #FFFFFF;
	}

	/* 订单状态卡片 */
	.order-status-card {
		width: 750rpx;
		padding: 0 30rpx;
		background-color: #FFFFFF;
	}

	.order-status-content {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}

	.userPerson {
		padding: 30rpx;
		background-color: #F7F7F7;
		border-radius: 16rpx;
	}

	.options {
		width: 68rpx;
		height: 68rpx;
		border-radius: 20rpx;
		background: #DCE6F7;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.order-status-left {
		flex: 1;
		flex-direction: column;
	}

	.order-title {
		font-size: 44rpx;
		font-weight: bold;
		color: #000000;
		margin-bottom: 20rpx;
	}

	.waiting-time {
		font-size: 40rpx;
		color: #FE5E10;
		margin-bottom: 16rpx;
		font-weight: 600;
	}

	.car-image {
		width: 220rpx;
		height: 160rpx;
		margin-left: 30rpx;
		flex-shrink: 0;
	}

	/* 底部按钮区域 */
	.bottom-actions {
		width: 750rpx;
		flex-direction: row;
		padding-top: 20rpx;
		padding-bottom: 20rpx;
		padding-left: 30rpx;
		padding-right: 30rpx;
		background-color: #FFFFFF;
	}

	.cancel-btn {
		flex: 1;
		height: 88rpx;
		line-height: 88rpx;
		text-align: center;
		background-color: #F5F5F5;
		border-width: 0;
		padding: 0;
	}
	.cancel-btn {
		width: 300rpx;
		height: 88rpx;
		line-height: 88rpx;
		text-align: center;
		background-color: #F5F5F5;
		border-width: 0;
		padding: 0;
	}
	
	.rebook-btn {
		flex: 1;
		height: 88rpx;
		line-height: 88rpx;
		text-align: center;
		background-color: #104FB9;
		border-width: 0;
		padding: 0;
	}

	.butText {
		font-size: 32rpx;
		font-weight: bold;
	}

	.cancel-btn-hover {
		opacity: 0.8;
		background-color: #E5E5E5;
	}

	.rebook-btn-hover {
		opacity: 0.7;
	}

	.opts {
		width: 690rpx;
	}

	.optsIts {
		width: 160rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.optsIts-img {
		width: 48rpx;
		height: 48rpx;
	}

	.optsIts-img2 {
		width: 44rpx;
		height: 44rpx;
		margin-bottom: 4rpx;
	}

	.goPhoneIts {
		width: 690rpx;
		margin: 30rpx;
		padding: 30rpx;
		background: #FFFFFF;
		border: 1px solid #eee;
	}

	.helpImg {
		width: 96rpx;
		height: 96rpx;
	}

	.dengdai {
		border-bottom: 1px dashed #E0E0E0;
		padding-bottom: 30rpx;
	}
</style>

nvueCommon.css

javascript 复制代码
.noRow{ white-space: nowrap; }
/* // 外边距 */
.mar-t4{ margin-top: 4rpx;}
.mar-t10{ margin-top: 10rpx;}
.mar-b10{margin-bottom: 10rpx;}
.mar-l10{margin-left: 10rpx;}
.mar-r10{margin-right: 10rpx;}
.mar-t-b10{margin: 10rpx 0;}
.mar-l-r10{margin: 0 10rpx;}
.margin10{margin: 10rpx;}

.mar-t15{margin-top: 15rpx;}
.mar-b15{margin-bottom: 15rpx;}
.mar-l15{margin-left: 15rpx;}
.mar-r15{margin-right: 15rpx;}
.mar-t-b15{margin: 15rpx 0;}
.mar-l-r15{margin: 0 15rpx;}
.margin15{margin: 15rpx;}

.mar-t20{margin-top: 20rpx;}
.mar-b20{margin-bottom: 20rpx;}
.mar-l20{margin-left: 20rpx;}
.mar-r20{margin-right: 20rpx;}
.mar-t-b20{margin: 20rpx 0;}
.mar-l-r20{margin: 0 20rpx;}
.margin20{margin: 20rpx;}

.mar-t30{margin-top: 30rpx;}
.mar-b30{margin-bottom: 30rpx;}
.mar-l30{margin-left: 30rpx;}
.mar-r30{margin-right: 30rpx;}
.mar-t-b30{margin: 30rpx 0;}
.mar-l-r30{margin: 0 30rpx;}
.margin30{margin: 30rpx;}

/* // 弹性盒子 */
.flex1{
	flex: 1;
}
/* .flexShrink{
	flex-shrink: 0;
} */
.flex{ display: flex; 
}
.flexcolumn{ flex-direction: column; 
}
.flexrow{ flex-direction: row; 
}
.flexwrap{ display: flex; flex-wrap: wrap; 
}
.flexbetween{ display: flex;justify-content: space-between; 
}
.flexaround{ display: flex;justify-content: space-around;
}
.flexbetali{ display: flex;justify-content: space-between;align-items: center;
}
.flexRight{ display: flex;justify-content: flex-end;
}
.flexbottom{ display: flex;align-items: flex-end;
}
.flexalign{ display: flex;align-items: center;
}
.flexcenter{ display: flex;align-items: center;justify-content: center;
}
.textAline{
	text-align: center;
}
.fontbold{font-weight: bold;}

.butStyle{
	/* width: 100%; */
	background: #104FB9;
	color:#fff;
	border-radius: 20rpx;
}
.butStyleQian{
	/* width: 100%; */
	background: #FBC787;
	color:#fff;
	border-radius: 20rpx;
}
.buthovers{
	opacity: 0.6;
}
.butsty {
	background-color: #104FB9;
	justify-content: center;
	align-items: center;
	gap: 24rpx;
	flex: 1 0 0;
	color: var(---white, #FFF);
	/* 点文本-常规/16pt regular */
	font-family: PingFang-SC-Medium;
	border-radius: 5rpx;
}

/* // 背景色 */
.bgfff{background-color: #FFFFFF;}
.bgF7 {background-color: #F7F7F7;}
.bgA9C0E8{background: #A9C0E8;}
.bg44BD4A {background: #44BD4A;}
.bgFF3300 {background: #FF3300;}
.motifBgCol{ background-color: #104FB9; }
/* // 文字颜色 */
.motifCol{ color: #104FB9; }
.priceCol { color: #FC1E1E; }
.colOrigin{ color: #FF963B; }
.colGreen { color: #2BC250; }
.colED5858 { color: #ED5858; }
.col104FB9 { color: #104FB9; }
.colDE9D43 { color: #DE9D43; }
.col807870 { color: #807870;}

.colfff{ color: #fff; }
.col000{ color: #000; }
.col222{ color: #222; }
.col333{ color: #333; }
.col444{ color: #444; }
.col555{ color: #555; }
.col666{ color: #666; }
.col777{ color: #777; }
.col888{ color: #888; }
.col999{ color: #999;  }
.colRed{ color: red; }

/* // 文字对其方式 */
.textAlign{
	text-align: center;
}
.textLeft{
	text-align: left;
}
.textRight{
	text-align: right;
}

/* 文字粗细和斜体 */
.font-weight-light {
	font-weight: 300;
}
/*细*/
.font-weight-lighter {
	font-weight: 100;
}
/*更细*/
.font-weight-normal {
	font-weight: 400;
}
/*正常*/
.font-weight-bold {
	font-weight: 700;
}
/*更粗*/
.font-italic {
	font-style: italic;
}
.font20{ font-size: 20rpx; }
.font22{ font-size: 22rpx; }
.font24{ font-size: 24rpx; }
.font26{ font-size: 26rpx; }
.font28{ font-size: 28rpx; }
.font30{ font-size: 30rpx; }
.font32{ font-size: 32rpx; }
.font34{ font-size: 34rpx; }
.font36{ font-size: 36rpx; }
.font38{ font-size: 38rpx; }
.font40{ font-size: 40rpx; }
.font42{ font-size: 42rpx; }
.font44{ font-size: 44rpx; }

.height-30{ height: 30rpx; }
.height-60{ height: 60rpx; }
.height-80{ height: 80rpx; }
相关推荐
星栈1 小时前
LiveView 页面越写越卡,我最后抓到的凶手不是数据库,是我自己乱塞 `assigns`
前端·前端框架·elixir
没落英雄2 小时前
6. 从零搭建一个 AI Agent —— 构建 Web 前端,让用户能和 agent 实时交互
前端·人工智能·架构
爱勇宝2 小时前
《道德经》第4章,老子写得很像在描述一个“底层系统”。
前端·后端·程序员
snow@li3 小时前
Java:Java 服务器(Web 容器 / Servlet 容器)完整工作清单
java·服务器·前端
洋子3 小时前
Yank Note 系列 14 - 我和 AI 怎么一起写文章
前端·markdown
卓怡学长3 小时前
w263基于springboot + vue 健康饮食管理系统
java·数据库·vue.js·spring boot·spring·intellij-idea
江华森4 小时前
前端构建工具 Webpack 速览
前端·webpack·node.js
谙忆10244 小时前
HTTP 图片缓存实战:Cache-Control、ETag、内容哈希文件名与 CDN 回源到底怎么配
前端