Jelajahi Sumber

代驾司机客户端

hxl13994548489 1 bulan lalu
induk
melakukan
d852ebe29c
100 mengubah file dengan 6558 tambahan dan 0 penghapusan
  1. 16 0
      .hbuilderx/launch.json
  2. 176 0
      App.vue
  3. 47 0
      execution/move/move.less
  4. 192 0
      execution/move/move.vue
  5. TEMPAT SAMPAH
      execution/static/move/close-icon.png
  6. TEMPAT SAMPAH
      execution/static/move/driver-icon.png
  7. 71 0
      identity/face_camera/face_camera.less
  8. 118 0
      identity/face_camera/face_camera.vue
  9. 119 0
      identity/filling/filling.less
  10. 441 0
      identity/filling/filling.vue
  11. 42 0
      identity/identity_camera/identity_camera.less
  12. 70 0
      identity/identity_camera/identity_camera.vue
  13. TEMPAT SAMPAH
      identity/static/face_camera/bg.png
  14. TEMPAT SAMPAH
      identity/static/face_camera/face.png
  15. TEMPAT SAMPAH
      identity/static/face_camera/tips.png
  16. TEMPAT SAMPAH
      identity/static/filling/camera.png
  17. TEMPAT SAMPAH
      identity/static/filling/card.png
  18. TEMPAT SAMPAH
      identity/static/filling/credentials-bg.jpg
  19. 14 0
      index.html
  20. 0 0
      lib/qqmap-wx-jssdk.min.js
  21. 397 0
      main.js
  22. 107 0
      manifest.json
  23. 28 0
      order/enter_fee/enter_fee.less
  24. 125 0
      order/enter_fee/enter_fee.vue
  25. 203 0
      order/order/order.less
  26. 338 0
      order/order/order.vue
  27. 110 0
      order/order_bill/order_bill.less
  28. 234 0
      order/order_bill/order_bill.vue
  29. TEMPAT SAMPAH
      order/static/order/icon-1.png
  30. TEMPAT SAMPAH
      order/static/order/icon-2.png
  31. TEMPAT SAMPAH
      order/static/order/icon-3.png
  32. TEMPAT SAMPAH
      order/static/order/icon-4.png
  33. TEMPAT SAMPAH
      order/static/order/icon-5.png
  34. TEMPAT SAMPAH
      order/static/order/money.png
  35. TEMPAT SAMPAH
      order/static/order/rate.png
  36. TEMPAT SAMPAH
      order/static/waiting_payment/payment.png
  37. 70 0
      order/waiting_payment/waiting_payment.less
  38. 119 0
      order/waiting_payment/waiting_payment.vue
  39. 24 0
      package.json
  40. 248 0
      pages.json
  41. 60 0
      pages/heat_chart/heat_chart.vue
  42. 58 0
      pages/login/login.less
  43. 100 0
      pages/login/login.vue
  44. 45 0
      pages/message/message.less
  45. 40 0
      pages/message/message.vue
  46. 56 0
      pages/message_list/message_list.less
  47. 44 0
      pages/message_list/message_list.vue
  48. 210 0
      pages/mine/mine.less
  49. 228 0
      pages/mine/mine.vue
  50. 119 0
      pages/order_list/order_list.less
  51. 138 0
      pages/order_list/order_list.vue
  52. 130 0
      pages/register/register.less
  53. 129 0
      pages/register/register.vue
  54. 542 0
      pages/workbench/workbench.less
  55. 969 0
      pages/workbench/workbench.vue
  56. 83 0
      rule/bill_rule/bill_rule.less
  57. 70 0
      rule/bill_rule/bill_rule.vue
  58. 36 0
      rule/cancel_rule/cancel_rule.less
  59. 40 0
      rule/cancel_rule/cancel_rule.vue
  60. 4 0
      rule/user_guide/user_guide.less
  61. 31 0
      rule/user_guide/user_guide.vue
  62. 29 0
      rule/user_rule/user_rule.less
  63. 88 0
      rule/user_rule/user_rule.vue
  64. TEMPAT SAMPAH
      static/login/top.png
  65. TEMPAT SAMPAH
      static/message_list/email-icon-1.png
  66. TEMPAT SAMPAH
      static/message_list/email-icon-2.png
  67. TEMPAT SAMPAH
      static/mine/icon-1.png
  68. TEMPAT SAMPAH
      static/mine/icon-10.png
  69. TEMPAT SAMPAH
      static/mine/icon-11.png
  70. TEMPAT SAMPAH
      static/mine/icon-2.png
  71. TEMPAT SAMPAH
      static/mine/icon-3.png
  72. TEMPAT SAMPAH
      static/mine/icon-4.png
  73. TEMPAT SAMPAH
      static/mine/icon-5.png
  74. TEMPAT SAMPAH
      static/mine/icon-6.png
  75. TEMPAT SAMPAH
      static/mine/icon-7.png
  76. TEMPAT SAMPAH
      static/mine/icon-8.png
  77. TEMPAT SAMPAH
      static/mine/icon-9.png
  78. TEMPAT SAMPAH
      static/mine/user.jpg
  79. TEMPAT SAMPAH
      static/order_list/calendar-icon.png
  80. TEMPAT SAMPAH
      static/register/location.png
  81. TEMPAT SAMPAH
      static/register/title-bg.png
  82. TEMPAT SAMPAH
      static/register/top.jpg
  83. TEMPAT SAMPAH
      static/tab_bar/message_1.png
  84. TEMPAT SAMPAH
      static/tab_bar/message_2.png
  85. TEMPAT SAMPAH
      static/tab_bar/order_1.png
  86. TEMPAT SAMPAH
      static/tab_bar/order_2.png
  87. TEMPAT SAMPAH
      static/tab_bar/people_1.png
  88. TEMPAT SAMPAH
      static/tab_bar/people_2.png
  89. TEMPAT SAMPAH
      static/tab_bar/workbench_1.png
  90. TEMPAT SAMPAH
      static/tab_bar/workbench_2.png
  91. TEMPAT SAMPAH
      static/voice/voice_1.mp3
  92. TEMPAT SAMPAH
      static/voice/voice_2.mp3
  93. TEMPAT SAMPAH
      static/voice/voice_3.mp3
  94. TEMPAT SAMPAH
      static/voice/voice_4.mp3
  95. TEMPAT SAMPAH
      static/voice/voice_5.mp3
  96. TEMPAT SAMPAH
      static/workbench/alarm-icon.png
  97. TEMPAT SAMPAH
      static/workbench/arrive-start-icon.png
  98. TEMPAT SAMPAH
      static/workbench/btn-icon-1.png
  99. TEMPAT SAMPAH
      static/workbench/btn-icon-2.png
  100. TEMPAT SAMPAH
      static/workbench/call.png

+ 16 - 0
.hbuilderx/launch.json

@@ -0,0 +1,16 @@
+{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+  // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+    "version": "0.0",
+    "configurations": [{
+     	"default" : 
+     	{
+     		"launchtype" : "local"
+     	},
+     	"mp-weixin" : 
+     	{
+     		"launchtype" : "local"
+     	},
+     	"type" : "uniCloud"
+     }
+    ]
+}

+ 176 - 0
App.vue

@@ -0,0 +1,176 @@
+<script>
+export default {
+	onLaunch: function() {
+		let gps = [];
+		wx.setKeepScreenOn({
+			keepScreenOn: true
+		});
+
+		//TODO 每隔3分钟触发自定义事件,接受系统消息
+
+		wx.startLocationUpdate({
+			success(resp) {
+				console.log('开启定位成功');
+			},
+			fail(resp) {
+				console.log('开启定位失败');
+				uni.$emit('updateLocation', null);
+			}
+		});
+
+		wx.onLocationChange(function(resp) {
+			let latitude = resp.latitude;
+			let longitude = resp.longitude;
+			let speed = resp.speed;
+
+			let location = {
+				latitude: latitude,
+				longitude: longitude
+			};
+
+			let workStatus = uni.getStorageSync('workStatus');
+			let baseUrl = 'http://10.114.41.214:8201/hxds-driver';
+			if (workStatus == '开始接单') {
+				// TODO 只在每分钟的前10秒上报定位信息,减小服务器压力
+				// let current = new Date();
+				// if (current.getSeconds() > 10) {
+				// 	return;
+				// }
+				let settings = uni.getStorageSync('settings');
+				settings = {
+					orderDistance: 0,
+					rangeDistance: 5,
+					orientation: ''
+				};
+				let orderDistance = settings.orderDistance;
+				let rangeDistance = settings.rangeDistance;
+				let orientation = settings.orientation;
+				uni.request({
+					url: `${baseUrl}/driver/location/updateLocationCache`,
+					method: 'POST',
+					header: {
+						token: uni.getStorageSync('token')
+					},
+					data: {
+						latitude: latitude,
+						longitude: longitude,
+						orderDistance: orderDistance,
+						rangeDistance: rangeDistance,
+						orientateLongitude: orientation != '' ? orientation.longitude : null,
+						orientateLatitude: orientation != '' ? orientation.latitude : null
+					},
+					success: function(resp) {
+						if (resp.statusCode == 401) {
+							uni.redirectTo({
+								url: 'pages/login/login'
+							});
+						} else if (resp.statusCode == 200 && resp.data.code == 200) {
+							let data = resp.data;
+							if (data.hasOwnProperty('token')) {
+								let token = data.token;
+								uni.setStorageSync('token', token);
+							}
+							console.log('定位更新成功');
+						} else {
+							console.error('更新GPS定位信息失败', resp.data);
+						}
+					},
+					fail: function(error) {
+						console.error('更新GPS定位信息失败', error);
+					}
+				});
+			} 
+			else if(workStatus == '接客户'){
+				let executeOrder = uni.getStorageSync('executeOrder');
+				let orderId=executeOrder.id
+				let data={
+					orderId:orderId,
+					latitude: latitude,
+					longitude: longitude
+				}
+				uni.request({
+					url: `${baseUrl}/driver/location/updateOrderLocationCache`,
+					method:"POST",
+					header:{
+						token:uni.getStorageSync("token")
+					},
+					data:data,
+					success:function(resp){
+						if (resp.statusCode == 401) {
+							uni.redirectTo({
+								url: 'pages/login/login'
+							});
+						} else if (resp.statusCode == 200 && resp.data.code == 200) {
+							let data = resp.data;
+							if (data.hasOwnProperty('token')) {
+								let token = data.token;
+								uni.setStorageSync('token', token);
+							}
+							console.log('订单定位更新成功');
+						} else {
+							console.error('订单定位更新失败', resp.data);
+						}
+					},
+					fail:function(error){
+						console.error('订单定位更新失败', error);
+					}
+				})
+			}
+			else if (workStatus == '开始代驾') {
+				//每凑够20个定位就上传一次,减少服务器的压力
+				let executeOrder=uni.getStorageSync("executeOrder")
+				if(executeOrder!=null){
+					gps.push({
+						orderId: executeOrder.id,
+						customerId: executeOrder.customerId,
+						latitude: latitude,
+						longitude: longitude,
+						speed: speed
+					})
+					if(gps.length==5){
+						uni.request({
+							url:`${baseUrl}/order/gps/insertOrderGps`,
+							method: 'POST',
+							header: {
+							    token: uni.getStorageSync('token')
+							},
+							data: {
+							    list: gps
+							},
+							success: function(resp) {
+								if (resp.statusCode == 401) {
+								    uni.redirectTo({
+								        url: '/pages/login/login'
+								    });
+								}
+								else if (resp.statusCode == 200 && resp.data.code == 200) {
+								    let data = resp.data;
+								    console.log("上传GPS成功");
+								} 
+								else {
+								    console.error('保存GPS定位失败', resp.data);
+								}
+								gps.length = 0;
+							},
+							fail: function(error) {
+							    console.error('保存GPS定位失败', error);
+							}
+						})
+					}
+				}
+			}
+			uni.$emit('updateLocation', location);
+		});
+	},
+	onShow: function() {
+		console.log('App Show');
+	},
+	onHide: function() {
+		console.log('App Hide');
+	}
+};
+</script>
+
+<style lang="scss">
+@import 'uview-ui/index.scss';
+</style>

+ 47 - 0
execution/move/move.less

@@ -0,0 +1,47 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+}
+.map {
+	width: 100%;
+}
+.location {
+	width: 50rpx;
+	height: 50rpx;
+	position: absolute;
+	right: 45rpx;
+	bottom: 60rpx;
+}
+.information-container {
+	display: flex;
+	position: absolute;
+	bottom: 70rpx;
+	width: 90%;
+	left: 5%;
+	background-color: rgba(255, 255, 255, 0.95);
+	border-radius: 8rpx;
+	border: solid 1rpx @bc-1;
+	padding: 0 35rpx;
+	box-sizing: border-box;
+	.close-icon{
+		display: block;
+		width: 30rpx;
+		height: 30rpx;
+		margin-top: 38rpx;
+		margin-right: 30rpx;
+	}
+	.info {
+		display: flex;
+		padding: 30rpx 0;
+		.label {
+			font-size: 34rpx;
+			color: @fc-2;
+		}
+		.value {
+			font-weight: bolder !important;
+			font-size: 34rpx;
+			color: @fc-4;
+			margin: 0 5rpx;
+		}
+	}
+}

+ 192 - 0
execution/move/move.vue

@@ -0,0 +1,192 @@
+<template>
+	<view>
+		<map
+			id="map"
+			scale="15"
+			:longitude="longitude"
+			:latitude="latitude"
+			:enable-poi="true"
+			class="map"
+			:style="mapStyle"
+			:polyline="polyline"
+			:markers="markers"
+			@longpress="showHandle"
+		>
+			<!-- <cover-image class="location" src="../static/workbench/location.png" @tap="returnLocationHandle()" /> -->
+			<cover-view class="information-container" v-show="infoStatus">
+				<cover-image src="../static/move/close-icon.png" class="close-icon" @tap="hideHandle"></cover-image>
+				<cover-view class="info">
+					<cover-view class="label">剩余</cover-view>
+					<cover-view class="value">{{ distance }}公里</cover-view>
+					<cover-view class="label">,预计</cover-view>
+					<cover-view class="value">{{ duration }}分钟</cover-view>
+				</cover-view>
+			</cover-view>
+		</map>
+	</view>
+</template>
+
+<script>
+let QQMapWX = require('../../lib/qqmap-wx-jssdk.min.js');
+let qqmapsdk;
+export default {
+	data() {
+		return {
+			orderId: null,
+			status: null,
+			mode: null,
+			map: null,
+			mapStyle: '',
+			startLatitude: 0,
+			startLongitude: 0,
+			endLatitude: 0,
+			endLongitude: 0,
+			latitude: 0,
+			longitude: 0,
+			targetLatitude: 0,
+			targetLongitude: 0,
+			distance: 0,
+			duration: 0,
+			polyline: [],
+			markers: [],
+			timer: null,
+			infoStatus: true
+		};
+	},
+	methods: {
+		formatPolyline(polyline) {
+			let coors = polyline;
+			let pl = [];
+			//坐标解压(返回的点串坐标,通过前向差分进行压缩)
+			const kr = 1000000;
+			for (let i = 2; i < coors.length; i++) {
+				coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
+			}
+			//将解压后的坐标放入点串数组pl中
+			for (let i = 0; i < coors.length; i += 2) {
+				pl.push({
+					longitude: coors[i + 1],
+					latitude: coors[i]
+				});
+			}
+			return pl;
+		},
+		calculateLine: function(ref) {
+			if (ref.latitude == 0 || ref.longitude == 0) {
+				return;
+			}
+			qqmapsdk.direction({
+				mode: ref.mode,
+				from: {
+					latitude: ref.latitude,
+					longitude: ref.longitude
+				},
+				to: {
+					latitude: ref.targetLatitude,
+					longitude: ref.targetLongitude
+				},
+				success: function(resp) {
+					let route = resp.result.routes[0];
+					let distance = route.distance;
+					let duration = route.duration;
+					let polyline = route.polyline;
+					ref.distance = Math.ceil((distance / 1000) * 10) / 10;
+					ref.duration = duration;
+
+					let points = ref.formatPolyline(polyline);
+
+					ref.polyline = [
+						{
+							points: points,
+							width: 6,
+							color: '#05B473',
+							arrowLine: true
+						}
+					];
+					ref.markers = [
+						{
+							id: 1,
+							latitude: ref.latitude,
+							longitude: ref.longitude,
+							width: 35,
+							height: 35,
+							anchor: {
+								x: 0.5,
+								y: 0.5
+							},
+							iconPath: '../static/move/driver-icon.png'
+						}
+					];
+				},
+				fail: function(error) {
+					console.log(error);
+				}
+			});
+		},
+		hideHandle: function() {
+			this.infoStatus = false;
+		},
+		showHandle: function() {
+			this.infoStatus = true;
+		}
+	},
+	onLoad: function(options) {
+		let that = this;
+		that.orderId = options.orderId;
+		qqmapsdk = new QQMapWX({
+			key: that.tencent.map.key
+		});
+		let windowHeight = uni.getSystemInfoSync().windowHeight;
+		that.mapStyle = `height:${windowHeight}px`;
+	},
+	onShow: function() {
+		let that = this;
+		uni.$on('updateLocation', function(location) {
+			if (location != null) {
+				that.latitude = location.latitude;
+				that.longitude = location.longitude;
+			}
+		});
+
+		let data = {
+			orderId: that.orderId
+		};
+		that.ajax(that.url.searchOrderForMoveById, 'POST', data, function(resp) {
+			let result = resp.data.result;
+
+			let startPlaceLocation = JSON.parse(result.startPlaceLocation);
+			that.startLatitude = startPlaceLocation.latitude;
+			that.startLongitude = startPlaceLocation.longitude;
+
+			let endPlaceLocation = JSON.parse(result.endPlaceLocation);
+			that.endLatitude = endPlaceLocation.latitude;
+			that.endLongitude = endPlaceLocation.longitude;
+
+			let status = result.status;
+			if (status == 2) {
+				that.targetLatitude = that.startLatitude;
+				that.targetLongitude = that.startLongitude;
+				that.mode = 'bicycling';
+			} else if (status == 3 || status == 4) {
+				that.targetLatitude = that.endLatitude;
+				that.targetLongitude = that.endLongitude;
+				that.mode = 'driving';
+			}
+			that.calculateLine(that);
+			that.timer = setInterval(function() {
+				that.calculateLine(that);
+			}, 6000);
+		});
+	},
+	onHide: function() {
+		let that = this;
+		uni.$off('updateLocation');
+		clearInterval(that.timer);
+		that.timer = null;
+	}
+};
+</script>
+
+<style lang="less">
+@import url('move.less');
+</style>

TEMPAT SAMPAH
execution/static/move/close-icon.png


TEMPAT SAMPAH
execution/static/move/driver-icon.png


+ 71 - 0
identity/face_camera/face_camera.less

@@ -0,0 +1,71 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+}
+.face-container {
+	margin-top: 80rpx;
+	position: relative;
+	.camera {
+		display: block;
+		width: 750rpx;
+		height: 750rpx;
+	}
+	.image-container {
+		width: 750rpx;
+		height: 750rpx;
+		.cover {
+			position: absolute;
+			left: 0;
+			top: 0;
+			width: 750rpx;
+			height: 750rpx;
+			background-image: url(../static/face_camera/bg.png);
+			background-size: 750rpx 750rpx;
+		}
+		.photo {
+			width: 750rpx;
+			height: 750rpx;
+		}
+	}
+}
+
+.desc {
+	text-align: center;
+	.tips {
+		display: block;
+		width: 100rpx;
+		margin-left: auto;
+		margin-right: auto;
+		margin-bottom: 25rpx;
+	}
+	.face {
+		display: block;
+		width: 150rpx;
+		margin-left: auto;
+		margin-right: auto;
+		margin-bottom: 25rpx;
+	}
+	text {
+		display: block;
+		font-size: 30rpx;
+		margin-bottom: 12rpx;
+		color: @fc-2;
+	}
+}
+
+.btn {
+	background-color: @btnc-1;
+	color: #fff;
+	width: 70%;
+	margin-top: 200rpx;
+	position: absolute;
+	left: 15%;
+	bottom: 180rpx;
+
+	&::after {
+		border: none;
+	}
+	&:active {
+		background-color: @btnac-1;
+	}
+}

+ 118 - 0
identity/face_camera/face_camera.vue

@@ -0,0 +1,118 @@
+<template>
+	<view>
+		<view class="face-container">
+			<camera device-position="front" flash="off" class="camera" @error="error" v-if="showCamera">
+				<cover-image src="../static/face_camera/bg.png" class="bg"></cover-image>
+			</camera>
+			<view class="image-container" v-if="showImage">
+				<image mode="widthFix" class="photo" :src="photoPath"></image>
+				<view class="cover"></view>
+			</view>
+		</view>
+		<view class="desc">
+			<block v-if="mode == 'verificate'">
+				<image src="../static/face_camera/tips.png" mode="widthFix" class="tips"></image>
+				<text>请把面部放在圆圈内</text>
+				<text>拍摄脸部来确认身份</text>
+			</block>
+			<block v-if="mode == 'create'">
+				<image src="../static/face_camera/face.png" mode="widthFix" class="face"></image>
+				<text>请把完整面部放在圆圈内</text>
+				<text>拍摄脸部来保存身份识别数据</text>
+			</block>
+		</view>
+		<button class="btn" @tap="confirmHandle">{{ mode == 'create' ? '录入面部信息' : '身份核实' }}</button>
+	</view>
+</template>
+
+<script>
+let dayjs = require('dayjs');
+export default {
+	data() {
+		return {
+			mode: 'verificate',
+			photoPath: '',
+			showCamera: true,
+			showImage: false,
+			audio: null
+		};
+	},
+	methods: {
+		confirmHandle:function(){
+			let that=this
+			that.audio.stop()
+			let ctx=uni.createCameraContext()
+			ctx.takePhoto({
+				quality:"high",
+				success:function(resp){
+					that.photoPath=resp.tempImagePath
+					that.showCamera=false
+					that.showImage=true
+					uni.getFileSystemManager().readFile({
+						filePath:that.photoPath,
+						encoding:"base64",
+						success:function(resp){
+							let base64='data:image:/png;base64,'+resp.data
+							let url=null
+							if(that.mode=="create"){
+								//创建司机面部模型档案
+								url = that.url.createDriverFaceModel;
+							}
+							else{
+								//验证司机面部模型
+								url = that.url.verificateDriverFace;
+							}
+							that.ajax(url,"POST",{photo:base64},function(resp){
+								let result=resp.data.result
+								if(that.mode=="create"){
+									if(result!=null&&result.length>0){
+										console.error(result);
+										uni.showToast({
+											icon: 'none',
+											title: '面部录入失败,请重新录入'
+										});
+										setTimeout(function() {
+											that.showCamera = true;
+											that.showImage = false;
+										}, 2000);
+									}
+									else{
+										uni.showToast({
+											title: '面部录入成功'
+										});
+										setTimeout(function() {
+											uni.switchTab({
+												url: '../../pages/workbench/workbench'
+											});
+										}, 2000);
+									}
+								}
+								else{
+									//TODO 判断人脸识别结果
+								}
+							})
+						}
+					})
+				}
+			})
+		}
+	},
+	onLoad: function(options) {
+		let that=this
+		that.mode=options.mode
+		let audio=uni.createInnerAudioContext();
+		that.audio=audio
+		audio.src="/static/voice/voice_5.mp3"
+		audio.play()
+	},
+	onHide: function() {
+		if(this.audio!=null){
+			this.audio.stop()
+		}
+	}
+};
+</script>
+
+<style lang="less">
+@import url('face_camera.less');
+</style>

+ 119 - 0
identity/filling/filling.less

@@ -0,0 +1,119 @@
+@import url("../../style.less");
+page {
+	background-color: #eef0f6;
+	height: 100%;
+	font-family: @ff-1;
+}
+.page {
+	padding-bottom: 70rpx;
+	padding-left: 40rpx;
+	padding-right: 40rpx;
+	padding-top: 120rpx;
+}
+.notice {
+	background-color: @bgc-5;
+	position: fixed;
+	z-index: 999;
+	top: 0;
+	left: 0;
+	width: 100%;
+	padding: 20rpx 30rpx;
+	// display: flex;
+	text {
+		font-size: 26rpx;
+		color: @fc-14;
+		margin-left: 10rpx;
+	}
+}
+.credentials-container {
+	display: flex;
+	justify-content: space-between;
+	flex-wrap: wrap;
+	.credentials {
+		width: 214rpx;
+		height: 150rpx;
+		margin-bottom: 60rpx;
+		position: relative;
+		.bg {
+			width: 214rpx;
+			height: 150rpx;
+			display: block;
+			border-radius: 10rpx;
+		}
+		.cover {
+			position: absolute;
+			left: 0;
+			top: 0;
+			width: 214rpx;
+			height: 150rpx;
+			.card {
+				width: 46rpx;
+				margin-top: 20rpx;
+				margin-left: 25rpx;
+			}
+			.desc {
+				display: block;
+				font-size: 24rpx;
+				color: #fff;
+				margin-left: 25rpx;
+				margin-top: 0rpx;
+				line-height: 1;
+				font-weight: bold;
+			}
+			.camera {
+				border: none;
+				background-color: @btnc-1;
+				width: 70rpx;
+				height: 70rpx;
+				border-radius: 35rpx;
+				margin-left: auto;
+				margin-right: auto;
+				margin-top: 15rpx;
+				background-image: url(../static/filling/camera.png);
+				background-size: 40rpx;
+				background-repeat: no-repeat;
+				background-position: 16rpx 15rpx;
+				&:active {
+					width: 70rpx;
+					height: 70rpx;
+					border-radius: 35rpx;
+					background-color: @btnac-1;
+				}
+			}
+		}
+	}
+}
+.title {
+	font-weight: bold;
+	font-size: 32rpx;
+	color: @fc-1;
+	margin-top: 25rpx;
+	margin-bottom: 25rpx;
+	padding-left: 10rpx;
+}
+.list {
+	border-radius: 20rpx;
+	background-color: #fff;
+	overflow: hidden;
+}
+.btn {
+	background-color: @btnc-1;
+	color: #fff;
+	margin-top: 40rpx;
+	border: none;
+	padding-top: 8rpx;
+	padding-bottom: 8rpx;
+	&::after {
+		border: none;
+	}
+	&:active {
+		background-color: @btnac-1;
+	}
+}
+.remark {
+	color: @fc-3;
+	font-size: 28rpx;
+	margin-top: 30rpx;
+	line-height: 1.7;
+	bottom: 60rpx;
+}

+ 441 - 0
identity/filling/filling.vue

@@ -0,0 +1,441 @@
+<template>
+	<view class="page">
+		<view class="notice">
+			<u-icon name="info-circle-fill" color="#AC9146" size="30" top="3" />
+			<text>准确填写个人信息,可享受每份代驾订单人身意外险</text>
+		</view>
+		<view class="credentials-container">
+			<view class="credentials">
+				<image :src="cardBackground[0]" class="bg"></image>
+				<view class="cover">
+					<image src="../static/filling/card.png" mode="widthFix" class="card"></image>
+					<text class="desc">身份证正面</text>
+					<ocr-navigator @onSuccess="scanIdcardFront" certificateType="idCard" :opposite="false"><button class="camera"></button></ocr-navigator>
+				</view>
+			</view>
+			<view class="credentials">
+				<image :src="cardBackground[1]" class="bg"></image>
+				<view class="cover">
+					<image src="../static/filling/card.png" mode="widthFix" class="card"></image>
+					<text class="desc">身份证背面</text>
+					<ocr-navigator @onSuccess="scanIdcardBack" certificateType="idCard" :opposite="true"><button class="camera"></button></ocr-navigator>
+				</view>
+			</view>
+			<view class="credentials">
+				<image :src="cardBackground[2]" class="bg"></image>
+				<view class="cover">
+					<image src="../static/filling/card.png" mode="widthFix" class="card"></image>
+					<text class="desc">手持身份证</text>
+					<button class="camera" @tap="takePhoto('idcardHolding')"></button>
+				</view>
+			</view>
+			<view class="credentials">
+				<image :src="cardBackground[3]" class="bg"></image>
+				<view class="cover">
+					<image src="../static/filling/card.png" mode="widthFix" class="card"></image>
+					<text class="desc">驾驶证正面</text>
+					<ocr-navigator @onSuccess="scanDrcardFront" certificateType="driverslicense"><button class="camera"></button></ocr-navigator>
+				</view>
+			</view>
+			<view class="credentials">
+				<image :src="cardBackground[4]" class="bg"></image>
+				<view class="cover">
+					<image src="../static/filling/card.png" mode="widthFix" class="card"></image>
+					<text class="desc">驾驶证背面</text>
+					<button class="camera" @tap="takePhoto('drcardBack')"></button>
+				</view>
+			</view>
+			<view class="credentials">
+				<image :src="cardBackground[5]" class="bg"></image>
+				<view class="cover">
+					<image src="../static/filling/card.png" mode="widthFix" class="card"></image>
+					<text class="desc">手持驾驶证</text>
+					<button class="camera" @tap="takePhoto('drcardHolding')"></button>
+				</view>
+			</view>
+		</view>
+
+		<view class="title">个人信息</view>
+		<view class="list">
+			<u-cell-group border="false">
+				<u-cell-item title="真实姓名" :value="idcard.name" :value-style="style" :arrow="false" />
+				<u-cell-item title="性别" :value="idcard.sex" :value-style="style" :arrow="false" />
+				<u-cell-item title="生日" :value="idcard.birthday" :value-style="style" :arrow="false" />
+				<u-cell-item title="身份证号" :value="idcard.pid" :value-style="style" :arrow="false" />
+				<u-cell-item title="身份证地址" 
+							:value="idcard.shortAddress" 
+							:value-style="style" 
+							@click="showAddressContent" />
+				<u-cell-item title="身份证有效期" :value="idcard.expiration" :value-style="style" :arrow="false" />
+			</u-cell-group>
+		</view>
+		<view class="title">联系方式</view>
+		<view class="list">
+			<u-cell-group border="false">
+				<u-cell-item title="手机号码" :value="contact.tel" :value-style="style" @click="enterContent('手机号码', 'tel')" />
+				<u-cell-item title="电子信箱" :value="contact.shortEmail" :value-style="style" @click="enterContent('电子信箱', 'email')" />
+				<u-cell-item title="收信地址" :value="contact.shortMailAddress" :value-style="style" @click="enterContent('收信地址', 'mailAddress')" />
+				<u-cell-item title="紧急联系人" :value="contact.contactName" :value-style="style" @click="enterContent('紧急联系人', 'contactName')" />
+				<u-cell-item title="紧急联系人电话" :value="contact.contactTel" :value-style="style" @click="enterContent('紧急联系人电话', 'contactTel')" />
+			</u-cell-group>
+		</view>
+		<view class="title">驾驶证</view>
+		<view class="list">
+			<u-cell-group border="false">
+				<u-cell-item title="驾驶证类型" :value="drcard.carClass" :value-style="style" :arrow="false" />
+				<u-cell-item title="驾驶证有效期" :value="drcard.validTo" :value-style="style" :arrow="false" />
+				<u-cell-item title="初次领证日期" :value="drcard.issueDate" :value-style="style" :arrow="false" />
+			</u-cell-group>
+		</view>
+
+		<button class="btn" @tap="save" :disabled="realAuth == 3">保存信息</button>
+		<view class="remark">您每次提交实名信息之后,都需要工作人员严格审查,请等候1~3天,这期间您将无法接单,特此声明!</view>
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+let dayjs = require('dayjs');
+export default {
+	data() {
+		return {
+			mode: 'fill',
+			style: {
+				color: '#FF9900'
+			},
+			cardBackground: [
+				'../static/filling/credentials-bg.jpg',
+				'../static/filling/credentials-bg.jpg',
+				'../static/filling/credentials-bg.jpg',
+				'../static/filling/credentials-bg.jpg',
+				'../static/filling/credentials-bg.jpg',
+				'../static/filling/credentials-bg.jpg'
+			],
+			idcard: {
+				pid: '',
+				name: '',
+				sex: '',
+				address: '',
+				shortAddress: '',
+				birthday: '',
+				expiration: '',
+				idcardFront: '',
+				idcardBack: '',
+				idcardHolding: ''
+			},
+			contact: {
+				tel: '',
+				email: '',
+				shortEmail: '',
+				mailAddress: '',
+				shortMailAddress: '',
+				contactName: '',
+				contactTel: ''
+			},
+			drcard: {
+				issueDate: '',
+				carClass: '',
+				validFrom: '',
+				validTo: '',
+				drcardFront: '',
+				drcardBack: '',
+				drcardHolding: ''
+			},
+			cosImg: [],
+			currentImg: {},
+			realAuth: uni.getStorageSync('realAuth')
+		};
+	},
+	methods: {
+		scanIdcardFront: function(resp) {
+			let that = this;
+			let detail = resp.detail;
+			that.idcard.pid = detail.id.text;
+			that.idcard.name = detail.name.text;
+			that.idcard.sex = detail.gender.text;
+			that.idcard.address = detail.address.text;
+			//需要缩略身份证地址,文字太长页面显示不了
+			that.idcard.shortAddress = detail.address.text.substr(0, 15) + '...';
+			that.idcard.birthday = detail.birth.text;
+			//OCR插件拍摄到的身份证正面照片存储地址
+			that.idcard.idcardFront = detail.image_path;
+			//让身份证View标签加载身份证正面照片
+			that.cardBackground[0] = detail.image_path;
+			that.uploadCos(that.url.uploadCosPrivateFile, detail.image_path, 'driverAuth', function(resp) {
+				let data = JSON.parse(resp.data);
+				let path = data.path;
+				that.currentImg['idcardFront'] = path;
+				that.cosImg.push(path);
+			});
+		},
+		scanIdcardBack: function(resp) {
+			let that = this;
+			let detail = resp.detail;
+			//OCR插件拍摄到的身份证背面照片存储地址
+			that.idcard.idcardBack = detail.image_path;
+			//View标签加载身份证背面照片
+			that.cardBackground[1] = detail.image_path;
+			let validDate = detail.valid_date.text.split('-')[1];
+			that.idcard.expiration = dayjs(validDate, 'YYYYMMDD').format('YYYY-MM-DD');
+			that.uploadCos(that.url.uploadCosPrivateFile, detail.image_path, 'driverAuth', function(resp) {
+				let data = JSON.parse(resp.data);
+				let path = data.path;
+				that.currentImg['idcardBack'] = path;
+				that.cosImg.push(path);
+			});
+		},
+		scanDrcardFront: function(resp) {
+			let that = this;
+			let detail = resp.detail;
+			that.drcard.issueDate = detail.issue_date.text; //初次领证日期
+			that.drcard.carClass = detail.car_class.text; //准驾车型
+			that.drcard.validFrom = detail.valid_from.text; //驾驶证起始有效期
+			that.drcard.validTo = detail.valid_to.text; //驾驶证截止有效期
+			that.drcard.drcardFront = detail.image_path;
+			that.cardBackground[3] = detail.image_path;
+			that.uploadCos(that.url.uploadCosPrivateFile, detail.image_path, 'driverAuth', function(resp) {
+				let data = JSON.parse(resp.data);
+				let path = data.path;
+				that.currentImg['drcardFront'] = path;
+				that.cosImg.push(path);
+			});
+		},
+		updatePhoto: function(type, path) {
+			let that = this;
+			that.uploadCos(that.url.uploadCosPrivateFile, path, 'driverAuth', function(resp) {
+				let data = JSON.parse(resp.data);
+				that.cosImg.push(data.path);
+				if (type == 'idcardHolding') {
+					that.cardBackground[2] = path;
+					that.currentImg['idcardHolding'] = data.path;
+					that.idcard.idcardHolding = data.path;
+				} else if (type == 'drcardBack') {
+					that.cardBackground[4] = path;
+					that.currentImg['drcardBack'] = data.path;
+					that.idcard.drcardBack = data.path;
+				} else if (type == 'drcardHolding') {
+					that.cardBackground[5] = path;
+					that.currentImg['drcardHolding'] = data.path;
+					that.idcard.drcardHolding = data.path;
+				}
+			});
+			that.$forceUpdate();
+		},
+		takePhoto: function(type) {
+			uni.navigateTo({
+				url: '../identity_camera/identity_camera?type=' + type
+			});
+		},
+		enterContent: function(title, key) {
+			let that = this;
+			uni.showModal({
+				title: title,
+				editable: true,
+				content: that.contact[key],
+				success: function(resp) {
+					if (resp.confirm) {
+						if (key == 'mailAddress') {
+							that.contact['shortMailAddress'] = resp.content.substr(0, 15) + (resp.content.length > 15 ? '...' : '');
+						} else if (key == 'email') {
+							that.contact['shortEmail'] = resp.content.substr(0, 25) + (resp.content.length > 25 ? '...' : '');
+						}
+						that.contact[key] = resp.content;
+					}
+				}
+			});
+		},
+		save: function() {
+			let that = this;
+			//判断是否设置了6张照片
+			if (Object.keys(that.currentImg).length != 6) {
+				that.$refs.uToast.show({
+					title: '证件上传不完整',
+					type: 'error'
+				});
+			}
+			//执行前端验证
+			else if (
+				that.checkValidTel(that.contact.tel, '手机号码') &&
+				that.checkValidEmail(that.contact.email, '电子信箱') &&
+				that.checkValidAddress(that.contact.mailAddress, '收信地址') &&
+				that.checkValidName(that.contact.contactName, '联系人') &&
+				that.checkValidTel(that.contact.contactTel, '联系人电话')
+			) {
+				uni.showModal({
+					title: '提示信息',
+					content: '确认提交实名资料?',
+					success: function(resp) {
+						if (resp.confirm) {
+							//比较哪些照片需要删除
+							let temp = [];
+							let values = [];
+							//从JSON中获取6张证件照片的云端存储地址
+		 				for (let key in that.currentImg) {
+								let path = that.currentImg[key];
+								values.push(path);
+							}
+							//判断cosImg数组里面哪些图片的云端地址不是6张图片的,这些图片要在云端删除
+							for (let one of that.cosImg) {
+								if (!values.includes(one)) {
+									temp.push(one);
+								}
+							}
+							if (temp.length > 0) {
+								//删除云端文件
+								that.ajax(that.url.deleteCosPrivateFile, 'POST', JSON.stringify({ pathes: temp }), function() {
+									console.log('文件删除成功');
+								});
+							}
+							//需要上传的实名认证数据
+							let data = {
+								pid: that.idcard.pid,
+								name: that.idcard.name,
+								sex: that.idcard.sex,
+								birthday: that.idcard.birthday,
+								tel: that.contact.tel,
+								email: that.contact.email,
+								mailAddress: that.contact.mailAddress,
+								contactName: that.contact.contactName,
+								contactTel: that.contact.contactTel,
+								idcardAddress: that.idcard.address,
+								idcardFront: that.currentImg.idcardFront,
+								idcardBack: that.currentImg.idcardBack,
+								idcardHolding: that.currentImg.idcardHolding,
+								idcardExpiration: that.idcard.expiration,
+								drcardType: that.drcard.carClass,
+								drcardExpiration: that.drcard.validTo,
+								drcardIssueDate: that.drcard.issueDate,
+								drcardFront: that.currentImg.drcardFront,
+								drcardBack: that.currentImg.drcardBack,
+								drcardHolding: that.currentImg.drcardHolding
+							};
+							//提交Ajax请求,上传数据
+							that.ajax(that.url.updateDriverAuth, 'POST', data, function(resp) {
+								console.log('更新成功');
+								that.$refs.uToast.show({
+									title: '资料提交成功',
+									type: 'success',
+									callback: function() {
+										uni.setStorageSync('realAuth', 3); //更新小程序Storage
+										that.realAuth = 3; //更新模型层
+										if (that.mode == 'create') {
+											//提示新注册的司机采集面部数据
+											uni.navigateTo({
+												url:"../face_camera/face_camera?mode=create"
+											})
+										} else {
+											//跳转到工作台页面
+											uni.switchTab({
+												url: '../../pages/workbench/workbench'
+											});
+										}
+									}
+								});
+							});
+						}
+					}
+				});
+			}
+		},
+		showAddressContent: function() {
+			if (this.idcard.address.length > 0) {
+				uni.showModal({
+					title: '身份证地址',
+					content: this.idcard.address,
+					showCancel: false
+				});
+			}
+		}
+	},
+	onLoad: function(options) {
+		// console.log(uni.getStorageSync('token'));
+		let that = this;
+		that.mode = options.mode;
+		if(uni.getStorageSync('realAuth')==1){
+			uni.showModal({
+			    title: '提示信息',
+			    content: '新注册的代驾司机请填写实名认证信息,并且上传相关证件照片',
+			    showCancel: false
+			});
+		}else{
+			that.ajax(that.url.searchDriverAuth,"GET",null,function(resp){
+				let json=resp.data.result
+				// console.log(json)
+				that.idcard.pid=json.pid
+				that.idcard.name = json.name;
+				that.idcard.sex = json.sex;
+				that.idcard.birthday = json.birthday;
+				that.idcard.address = json.idcardAddress;
+				that.idcard.shortAddress = json.idcardAddress.substr(0, 15) + (json.idcardAddress.length > 15 ? '...' : '');
+				that.idcard.expiration = json.idcardExpiration;
+				that.idcard.idcardFront = json.idcardFront;
+				if(json.idcardFrontUrl.length>0){
+					that.cardBackground[0]=json.idcardFrontUrl
+				}
+				that.idcard.idcardBack = json.idcardBack;
+				if (json.idcardBackUrl.length > 0) {
+				    that.cardBackground[1] = json.idcardBackUrl;
+				}
+				that.idcard.idcardHolding = json.idcardHolding;
+				if (json.idcardHoldingUrl.length > 0) {
+				    that.cardBackground[2] = json.idcardHoldingUrl;
+				}
+				
+				that.contact.tel = json.tel;
+				that.contact.email = json.email;
+				that.contact.shortEmail = json.email.substr(0, 25) + (json.email.length > 25 ? '...' : '');
+				that.contact.mailAddress = json.mailAddress;
+				that.contact.shortMailAddress = json.mailAddress.substr(0, 15) + (json.mailAddress.length > 15 ? '...' : '');
+				that.contact.contactName = json.contactName;
+				that.contact.contactTel = json.contactTel;
+				
+				that.drcard.carClass = json.drcardType;
+				that.drcard.validTo = json.drcardExpiration;
+				that.drcard.issueDate = json.drcardIssueDate;
+				that.drcard.drcardFront = json.drcardFront;
+				if (json.drcardFrontUrl.length > 0) {
+				    that.cardBackground[3] = json.drcardFrontUrl;
+				}
+				that.drcard.drcardBack = json.drcardBack;
+				if (json.drcardBackUrl.length > 0) {
+				    that.cardBackground[4] = json.drcardBackUrl;
+				}
+				that.drcard.drcardHolding = json.drcardHolding;
+				if (json.drcardHoldingUrl.length > 0) {
+				    that.cardBackground[5] = json.drcardHoldingUrl;
+				}
+				
+				if(that.idcard.idcardFront.length>0){
+					that.cosImg.push(that.idcard.idcardFront)
+					that.currentImg['idcardFront']=that.idcard.idcardFront
+				}
+				if (that.idcard.idcardBack.length > 0) {
+				    that.cosImg.push(that.idcard.idcardBack);
+				    that.currentImg['idcardBack'] = that.idcard.idcardBack;
+				}
+				if (that.idcard.idcardHolding.length > 0) {
+				    that.cosImg.push(that.idcard.idcardHolding);
+				    that.currentImg['idcardHolding'] = that.idcard.idcardHolding;
+				}
+				if (that.drcard.drcardFront.length > 0) {
+				    that.cosImg.push(that.drcard.drcardFront);
+				    that.currentImg['drcardFront'] = that.drcard.drcardFront;
+				}
+				if (that.drcard.drcardBack.length > 0) {
+				    that.cosImg.push(that.drcard.drcardBack);
+				    that.currentImg['drcardBack'] = that.drcard.drcardBack;
+				}
+				if (that.drcard.drcardHolding.length > 0) {
+				    that.cosImg.push(that.drcard.drcardHolding);
+				    that.currentImg['drcardHolding'] = that.drcard.drcardHolding;
+				}
+				
+			})
+		}
+	}
+};
+</script>
+
+<style lang="less">
+@import url('filling.less');
+</style>

+ 42 - 0
identity/identity_camera/identity_camera.less

@@ -0,0 +1,42 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+}
+
+.camera,
+.image {
+	width: 100%;
+	height: 480rpx;
+}
+.operate-container {
+	display: flex;
+	justify-content: center;
+	margin-top: 50rpx;
+	.btn {
+		width: 40%;
+		margin: 0;
+		&::after {
+			border: none;
+		}
+		&:first-child {
+			margin-right: 30rpx;
+		}
+	}
+}
+
+.notice-container {
+	padding: 40rpx 60rpx;
+	.notice {
+		font-size: 40rpx;
+		color: @fc-1;
+		font-weight: bold;
+		display: block;
+		margin-bottom: 15rpx;
+	}
+	.desc {
+		display: block;
+		font-size: 32rpx;
+		color: @fc-3;
+		line-height: 1.7;
+	}
+}

+ 70 - 0
identity/identity_camera/identity_camera.vue

@@ -0,0 +1,70 @@
+<template>
+	<view>
+		<camera device-position="back" flash="off" class="camera" @error="error" v-if="showCamera"></camera>
+		<image mode="widthFix" class="image" :src="photoPath" v-if="showImage"></image>
+		<view class="operate-container">
+			<button type="primary" class="btn" @tap="clickBtn">{{ btnText }}</button>
+			<button type="warn" class="btn" @tap="afresh">重拍</button>
+		</view>
+		<view class="notice-container">
+			<text class="notice">注意事项</text>
+			<text class="desc">
+				<block v-if="type != 'driverCardBack'">
+					拍照的时候,必须把证件拍摄清晰并完整,否则影响识别结果。持证拍照的时候不许戴帽子、墨镜和面纱等遮挡五官的饰物,只拍摄上半身即可。手持证件,五官与证件必须同时拍摄到照片中。
+				</block>
+				<block v-if="type == 'driverCardBack'">拍照的时候,必须把驾驶证背面拍摄的清晰完整,否则影响认证结果。</block>
+			</text>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			type: null,
+			photoPath: '',
+			btnText: '拍照',
+			showCamera: true,
+			showImage: false
+		};
+	},
+	onLoad: function(options) {
+		this.type = options.type;
+	},
+	methods: {
+		clickBtn:function(){
+			let that=this
+			if(that.btnText=="拍照"){
+				let ctx=uni.createCameraContext()
+				ctx.takePhoto({
+					quality:"high",
+					success:function(resp){
+						that.photoPath= resp.tempImagePath
+						that.showCamera=false
+						that.showImage=true
+						that.btnText="提交"
+					}
+				})
+			}else{
+				let pages=getCurrentPages();
+				let prevPage=pages[pages.length-2]
+				prevPage.$vm.updatePhoto(that.type,that.photoPath)
+				uni.navigateBack({
+					delta:1
+				})
+			}
+		},
+		afresh:function(){
+			let that = this;
+			that.showCamera = true;
+			that.showImage = false;
+			that.btnText = '拍照';
+		}
+	}
+};
+</script>
+
+<style lang="less">
+@import url('identity_camera.less');
+</style>

TEMPAT SAMPAH
identity/static/face_camera/bg.png


TEMPAT SAMPAH
identity/static/face_camera/face.png


TEMPAT SAMPAH
identity/static/face_camera/tips.png


TEMPAT SAMPAH
identity/static/filling/camera.png


TEMPAT SAMPAH
identity/static/filling/card.png


TEMPAT SAMPAH
identity/static/filling/credentials-bg.jpg


+ 14 - 0
index.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
+    <title></title>
+    <!--preload-links-->
+    <!--app-context-->
+  </head>
+  <body>
+    <div id="app"><!--app-html--></div>
+    <script type="module" src="/main.js"></script>
+  </body>
+</html>

File diff ditekan karena terlalu besar
+ 0 - 0
lib/qqmap-wx-jssdk.min.js


+ 397 - 0
main.js

@@ -0,0 +1,397 @@
+import App from './App'
+
+
+// #ifndef VUE3
+import Vue from 'vue'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+    ...App
+})
+
+//注册uView组件
+import uView from 'uview-ui';
+Vue.use(uView);
+
+
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import {
+    createSSRApp
+} from 'vue'
+export function createApp() {
+    const app = createSSRApp(App)
+    return {
+        app
+    }
+}
+// #endif
+
+
+let baseUrl = "http://10.114.41.214:8201/hxds-driver"
+
+Vue.prototype.url = {
+    registerNewDriver: `${baseUrl}/driver/registerNewDriver`,
+    updateDriverAuth: `${baseUrl}/driver/updateDriverAuth`,
+    uploadCosPrivateFile: `${baseUrl}/cos/uploadCosPrivateFile`,
+    deleteCosPrivateFile: `${baseUrl}/cos/deleteCosPrivateFile`,
+    createDriverFaceModel: `${baseUrl}/driver/createDriverFaceModel`,
+    verificateDriverFace: `${baseUrl}/driver/recognition/verificateDriverFace`,
+    login: `${baseUrl}/driver/login`,
+    logout: `${baseUrl}/driver/logout`,
+    searchDriverBaseInfo: `${baseUrl}/driver/searchDriverBaseInfo`,
+    searchWorkbenchData: `${baseUrl}/driver/searchWorkbenchData`,
+    searchDriverAuth: `${baseUrl}/driver/searchDriverAuth`,
+    startWork: `${baseUrl}/driver/startWork`,
+    stopWork: `${baseUrl}/driver/stopWork`,
+    receiveNewOrderMessage: `${baseUrl}/message/order/new/receiveNewOrderMessage`,
+    acceptNewOrder: `${baseUrl}/order/acceptNewOrder`,
+    searchDriverExecuteOrder: `${baseUrl}/order/searchDriverExecuteOrder`,
+    searchDriverCurrentOrder: `${baseUrl}/order/searchDriverCurrentOrder`,
+    searchOrderForMoveById: `${baseUrl}/order/searchOrderForMoveById`,
+    arriveStartPlace: `${baseUrl}/order/arriveStartPlace`,
+    startDriving: `${baseUrl}/order/startDriving`,
+    uploadRecordFile: `${baseUrl}/monitoring/uploadRecordFile`,
+    updateOrderStatus: `${baseUrl}/order/updateOrderStatus`,
+    updateBillFee: `${baseUrl}/order/updateBillFee`,
+    searchReviewDriverOrderBill: `${baseUrl}/order/searchReviewDriverOrderBill`,
+    searchOrderStatus: `${baseUrl}/order/searchOrderStatus`,
+    updateOrderAboutPayment: `${baseUrl}/order/updateOrderAboutPayment`,
+    searchDriverOrderByPage: `${baseUrl}/order/searchDriverOrderByPage`,
+    searchOrderById: `${baseUrl}/order/searchOrderById`,
+    startCommentWorkflow: `${baseUrl}/comment/startCommentWorkflow`,
+}
+
+
+Vue.prototype.tencent = {
+    map: {
+        referer: "华星代驾",
+        key: "4WRBZ-SVM3Z-WKAXG-7SU6N-52ESO-E6BRU"
+    }
+}
+
+
+Vue.prototype.ajax = function(url, method, data, fun, load) {
+    let timer = null
+    if (load == true || load == undefined) {
+        uni.showLoading({
+            title: "执行中"
+        })
+        timer = setTimeout(function() {
+            uni.hideLoading()
+        }, 60 * 1000)
+    }
+
+    uni.request({
+        "url": url,
+        "method": method,
+        "header": {
+            token: uni.getStorageSync("token")
+        },
+        "data": data,
+        success: function(resp) {
+            // console.log(resp)
+            if (load == true || load == undefined) {
+                clearTimeout(timer)
+                uni.hideLoading()
+            }
+            if (resp.statusCode == 401) {
+                uni.redirectTo({
+                    url: "/pages/login/login.vue"
+                })
+            } else if (resp.statusCode == 200 && resp.data.code == 200) {
+                let data = resp.data
+                if (data.hasOwnProperty("token")) {
+                    let token = data.token
+                    uni.setStorageSync("token", token)
+                }
+                fun(resp)
+            } else if (resp.data.error == "该微信无法注册") {
+                uni.showToast({
+                    icon: "none",
+                    title: "该微信无法注册"
+                })
+            } else if (resp.data.error == "当前手机号与注册手机号不一致") {
+                uni.showToast({
+                    icon: "none",
+                    title: "当前手机号与注册手机号不一致"
+                })
+            } else {
+                uni.showToast({
+                    icon: "none",
+                    title: "执行异常"
+                })
+                console.error(resp.data)
+            }
+        },
+        fail: function(error) {
+            if (load == true || load == undefined) {
+                clearTimeout(timer)
+                uni.hideLoading()
+            }
+        }
+    })
+}
+
+
+Vue.prototype.refreshMessage = function(that) {
+    uni.request({
+        "url": that.url.refreshMessage,
+        "method": "POST",
+        "header": {
+            token: uni.getStorageSync("token")
+        },
+        "data": {
+            identity: 'driver'
+        },
+        success: function(resp) {
+
+            if (resp.statusCode == 401) {
+                uni.redirectTo({
+                    url: "/pages/login/login.vue"
+                })
+            } else if (resp.statusCode == 200 && resp.data.code == 200) {
+                uni.$emit("updateMessageService", true)
+                let result = resp.data.result
+                let lastRows = result.lastRows
+                let unreadRows = result.unreadRows
+                if (lastRows > 0) {
+                    uni.$emit("showMessageTip", lastRows)
+                }
+            } else {
+                console.error(resp.data)
+                //在工作台页面触发更新消息服务状态,显示服务可用或者不可用
+                uni.$emit("updateMessageService", false)
+            }
+            console.log("刷新消息")
+        },
+        fail: function(error) {
+            //在工作台页面触发更新消息服务状态,显示服务可用或者不可用
+            uni.$emit("updateMessageService", false)
+        }
+    })
+}
+
+Vue.prototype.uploadCos = function(url, path, module, fun) {
+    uni.uploadFile({
+        url: url,
+        filePath: path,
+        name: "file",
+        header: {
+            token: uni.getStorageSync("token")
+        },
+        formData: {
+            "module": module
+        },
+        success: function(resp) {
+            let data = JSON.parse(resp.data)
+            if (resp.statusCode == 401) {
+                uni.redirectTo({
+                    url: "/pages/login/login.vue"
+                })
+            } else if (resp.statusCode == 200 && data.code == 200) {
+                fun(resp)
+            } else {
+                uni.showToast({
+                    icon: "none",
+                    title: data.error
+                })
+            }
+        }
+    })
+}
+
+Vue.prototype.upload = function(url, path, data, fun) {
+    uni.uploadFile({
+        url: url,
+        filePath: path,
+        name: "file",
+        header: {
+            token: uni.getStorageSync("token")
+        },
+        formData: data,
+        success: function(resp) {
+            let data = JSON.parse(resp.data)
+
+            if (resp.statusCode == 401) {
+                uni.redirectTo({
+                    url: "/pages/login/login.vue"
+                })
+            } else if (resp.statusCode == 200 && data.code == 200) {
+                fun(resp)
+            } else {
+                uni.showToast({
+                    icon: "none",
+                    title: data.error
+                })
+            }
+        },
+        fail: function(error) {
+            console.log(error)
+        }
+    })
+}
+
+Vue.prototype.toPage = function(url) {
+    uni.navigateTo({
+        url: url
+    })
+}
+
+
+Vue.prototype.checkNull = function(data, name) {
+    if (data == null) {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return true
+    }
+    return false
+}
+
+Vue.prototype.checkBlank = function(data, name) {
+    if (data == null || data == "") {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return true
+    }
+    return false
+}
+
+Vue.prototype.checkValidName = function(data, name) {
+    if (data == null || data == "") {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return false
+    } else if (!/^[\u4e00-\u9fa5]{2,15}$/.test(data)) {
+        this.$refs.uToast.show({
+            title: name + "不正确",
+            type: 'error'
+        })
+        return false
+    }
+    return true
+}
+Vue.prototype.checkValidTel = function(data, name) {
+    if (data == null || data == "") {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return false
+    } else if (!/^1[0-9]{10}$/.test(data)) {
+        this.$refs.uToast.show({
+            title: name + "不正确",
+            type: 'error'
+        })
+        return false
+    }
+    return true
+}
+Vue.prototype.checkValidEmail = function(data, name) {
+    if (data == null || data == "") {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return false
+    } else if (!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(data)) {
+        this.$refs.uToast.show({
+            title: name + "不正确",
+            type: 'error'
+        })
+        return false
+    }
+    return true
+}
+
+Vue.prototype.checkValidAddress = function(data, name) {
+
+    if (data == null || data == "") {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return false
+    } else if (!/^[0-9a-zA-Z\u4e00-\u9fa5\-]{6,50}$/.test(data)) {
+        this.$refs.uToast.show({
+            title: name + "不正确",
+            type: 'error'
+        })
+        return false
+    }
+    return true
+}
+
+Vue.prototype.checkValidFee = function(data, name) {
+
+    if (data == null || data == "") {
+        this.$refs.uToast.show({
+            title: name + "不能为空",
+            type: 'error'
+        })
+        return false
+    } else if (!/^[1-9]\d*\.\d{1,2}$|^0\.\d{1,2}$|^[1-9]\d*$/.test(data)) {
+        this.$refs.uToast.show({
+            title: name + "不正确",
+            type: 'error'
+        })
+        return false
+    }
+    return true
+}
+
+
+Vue.prototype.changeNumber = function(value) {
+    let newValue = ['', ''];
+    let fr = 1000;
+    const ad = 1;
+    let num = 3;
+    const fm = 1;
+    while (value / fr >= 1) {
+        fr *= 10;
+        num += 1;
+    }
+    if (num <= 4) {
+        // 千
+        newValue[1] = '千';
+        newValue[0] = parseInt(value / 1000) + '';
+    } else if (num <= 8) {
+        // 万
+        const text1 = parseInt(num - 4) / 3 > 1 ? '千万' : '万';
+        const fm = '万' === text1 ? 10000 : 10000000;
+        newValue[1] = text1;
+        newValue[0] = value / fm + '';
+    } else if (num <= 16) {
+        // 亿
+        let text1 = (num - 8) / 3 > 1 ? '千亿' : '亿';
+        text1 = (num - 8) / 4 > 1 ? '万亿' : text1;
+        text1 = (num - 8) / 7 > 1 ? '千万亿' : text1;
+        // tslint:disable-next-line:no-shadowed-variable
+        let fm = 1;
+        if ('亿' === text1) {
+            fm = 100000000;
+        } else if ('千亿' === text1) {
+            fm = 100000000000;
+        } else if ('万亿' === text1) {
+            fm = 1000000000000;
+        } else if ('千万亿' === text1) {
+            fm = 1000000000000000;
+        }
+        newValue[1] = text1;
+        newValue[0] = parseInt(value / fm) + '';
+    }
+    if (value < 1000) {
+        newValue[1] = '';
+        newValue[0] = value + '';
+    }
+    let temp = Math.floor((newValue[0]) * 100) / 100
+    return temp + newValue[1];
+}

+ 107 - 0
manifest.json

@@ -0,0 +1,107 @@
+{
+	"name": "hxds-driver-wx",
+	"appid": "",
+	"description": "",
+	"versionName": "1.0.0",
+	"versionCode": "100",
+	"transformPx": false,
+	/* 5+App特有相关 */
+	"app-plus": {
+		"usingComponents": true,
+		"nvueStyleCompiler": "uni-app",
+		"compilerVersion": 3,
+		"splashscreen": {
+			"alwaysShowBeforeRender": true,
+			"waiting": true,
+			"autoclose": true,
+			"delay": 0
+		},
+		/* 模块配置 */
+		"modules": {},
+		/* 应用发布信息 */
+		"distribute": {
+			/* android打包配置 */
+			"android": {
+				"permissions": [
+					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
+					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+					"<uses-feature android:name=\"android.hardware.camera\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+				]
+			},
+			/* ios打包配置 */
+			"ios": {},
+			/* SDK配置 */
+			"sdkConfigs": {}
+		}
+	},
+	/* 快应用特有相关 */
+	"quickapp": {},
+	/* 小程序特有相关 */
+	"mp-weixin": {
+		"appid": "wx6f903040d7fed698",
+		"optimization": {
+			"subPackages": true
+		},
+		"setting": {
+			"urlCheck": false,
+			"minified": true
+		},
+		"usingComponents": true,
+		"plugins": {
+			//OCR证件识别
+			"ocr-plugin": {
+				"version": "3.0.6",
+				"provider": "wx4418e3e031e551be"
+			},
+			//文字转语音播报
+			"WechatSI": {
+				"version": "0.3.5",
+				"provider": "wx069ba97219f66d99"
+			},
+			//路线规划
+			"routePlan": {
+				"version": "1.0.18",
+				"provider": "wx50b5593e81dd937a"
+			},
+			//地图选点
+			"chooseLocation": {
+				"version": "1.0.9",
+				"provider": "wx76a9a06e5b4e693e"
+			}
+		},
+		/**
+		 * 挂到后台依然可以使用GPS定位
+		 */
+		"requiredBackgroundModes": ["location"],
+		"permission": {
+			"scope.userLocation": {
+				"desc": "请允许地图服务使用GPS定位"
+			}
+		}
+	},
+	"mp-alipay": {
+		"usingComponents": true
+	},
+	"mp-baidu": {
+		"usingComponents": true
+	},
+	"mp-toutiao": {
+		"usingComponents": true
+	},
+	"uniStatistics": {
+		"enable": false
+	},
+	"vueVersion": "2"
+}

+ 28 - 0
order/enter_fee/enter_fee.less

@@ -0,0 +1,28 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+}
+.step {
+	margin-top: 60rpx;
+}
+.title {
+	font-size: 50rpx;
+	text-align: center;
+	font-weight: bold;
+	margin-top: 65rpx;
+	margin-bottom: 40rpx;
+	color: @fc-1;
+}
+
+.btn {
+	background-color: @btnc-1;
+	color: #fff;
+	margin-top: 80rpx;
+	width: 90%;
+	&::after {
+		border: none;
+	}
+	&:active {
+		background-color: @btnac-1;
+	}
+}

+ 125 - 0
order/enter_fee/enter_fee.vue

@@ -0,0 +1,125 @@
+<template>
+	<view>
+		<u-notice-bar mode="horizontal" :list="notice"></u-notice-bar>
+		<view class="step"><u-steps :list="numList" mode="number" :current="0"></u-steps></view>
+		<view class="title">【 相关费用 】</view>
+		<u-cell-group>
+			<u-cell-item icon="red-packet-fill" title="路桥费" :value="tollFee + '元'" @click="enterFee('toll')"></u-cell-item>
+			<u-cell-item icon="red-packet-fill" title="停车费" :value="parkingFee + '元'" @click="enterFee('parking')"></u-cell-item>
+			<u-cell-item icon="red-packet-fill" title="其他费用" :value="otherFee + '元'" @click="enterFee('other')"></u-cell-item>
+		</u-cell-group>
+		<button class="btn" @tap="submit">输入好了</button>
+		<u-toast ref="uToast" />
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			notice: ['请认真填写相关金额,发送账单之后则不能修改,请慎重填写费用金额,精确到小数点后两位'],
+			numList: [
+				{
+					name: '结束代驾'
+				},
+				{
+					name: '输入费用'
+				},
+				{
+					name: '提交账单'
+				},
+				{
+					name: '用户付款'
+				}
+			],
+			orderId: null,
+			customerId: null,
+			tollFee: '0.00',
+			parkingFee: '0.00',
+			otherFee: '0.00'
+		};
+	},
+	methods: {
+		enterFee: function(type) {
+			let that = this;
+			if (type == 'toll') {
+				uni.showModal({
+					title: '路桥费',
+					content: that.tollFee,
+					editable: true,
+					placeholderText: '输入路桥费',
+					showCancel: false,
+					success: function(resp) {
+						if (that.checkValidFee(resp.content, '路桥费')) {
+							that.tollFee = resp.content;
+						}
+					}
+				});
+			} else if (type == 'parking') {
+				uni.showModal({
+					title: '停车费',
+					content: that.parkingFee,
+					editable: true,
+					placeholderText: '输入停车费',
+					showCancel: false,
+					success: function(resp) {
+						if (that.checkValidFee(resp.content, '停车费')) {
+							that.parkingFee = resp.content;
+						}
+					}
+				});
+			} else if (type == 'other') {
+				uni.showModal({
+					title: '其他费用',
+					content: that.otherFee,
+					editable: true,
+					placeholderText: '输入其他费用',
+					showCancel: false,
+					success: function(resp) {
+						if (that.checkValidFee(resp.content, '其他费用')) {
+							that.otherFee = resp.content;
+						}
+					}
+				});
+			}
+		},
+		submit: function() {
+			let that = this;
+			if (that.checkValidFee(that.tollFee, '路桥费') 
+				&& that.checkValidFee(that.parkingFee, '停车费') 
+				&& that.checkValidFee(that.otherFee, '其他费用')) {
+				uni.showModal({
+					title: '提示消息',
+					content: '您确认要提交以上相关费用?',
+					success: function(resp) {
+						if (resp.confirm) {
+							let data = {
+								tollFee: that.tollFee,
+								parkingFee: that.parkingFee,
+								otherFee: that.otherFee,
+								orderId: that.orderId
+							};
+							that.ajax(that.url.updateBillFee, 'POST', data, function(resp) {
+								uni.navigateTo({
+									url: `/order/order_bill/order_bill?orderId=${that.orderId}&customerId=${that.customerId}`
+								});
+							});
+						}
+					}
+				});
+			}
+		}
+	},
+	onLoad: function(options) {
+		this.orderId = options.orderId;
+		this.customerId = options.customerId;
+	},
+	onShow: function() {},
+	onHide: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('enter_fee.less');
+</style>

+ 203 - 0
order/order/order.less

@@ -0,0 +1,203 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+}
+.customer-container {
+	display: flex;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	padding-top: 50rpx;
+	.info {
+		margin-left: 30rpx;
+		.customer-name {
+			font-size: 36rpx;
+			font-weight: bold;
+			color: @fc-2;
+			margin-bottom: 10rpx;
+		}
+		.customer-tel {
+			font-size: 28rpx;
+			color: @fc-2;
+			margin-bottom: 10rpx;
+			letter-spacing: 1rpx;
+		}
+	}
+}
+.address-container {
+	font-size: 28rpx;
+	color: @fc-2;
+	line-height: 1.6;
+	margin-top: 35rpx;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	.from {
+		display: flex;
+		&::before {
+			display: block;
+			content: '';
+			width: 20rpx;
+			height: 20rpx;
+			border-radius: 10rpx;
+			background-color: @bgc-7;
+			margin-top: 14rpx;
+			margin-right: 17rpx;
+		}
+	}
+	.dashed-line {
+		height: 30rpx;
+		border-left: @bc-5 2rpx dashed;
+		// background-color: red;
+		margin-top: 5rpx;
+		margin-bottom: 5rpx;
+		margin-left: 10rpx;
+	}
+	.to {
+		display: flex;
+		&::before {
+			display: block;
+			content: '';
+			width: 20rpx;
+			height: 20rpx;
+			border-radius: 10rpx;
+			background-color: @bgc-8;
+			margin-top: 14rpx;
+			margin-right: 17rpx;
+		}
+	}
+}
+.order-container {
+	padding: 25rpx 30rpx;
+	margin-top: 30rpx;
+	border-top: solid 1rpx @bc-1;
+	view {
+		line-height: 60rpx;
+		height: 60rpx;
+		color: @fc-2;
+		font-size: 28rpx;
+		display: flex;
+	}
+}
+.setion-title {
+	background-color: @bgc-1;
+	padding: 25rpx 30rpx;
+	display: flex;
+	image {
+		width: 32rpx;
+		height: auto;
+		margin-top: 9rpx;
+		margin-right: 12rpx;
+	}
+	text {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: @fc-2;
+	}
+}
+.section-content {
+	padding: 20rpx 20rpx;
+	.item {
+		display: flex;
+		justify-content: space-between;
+		border-bottom: solid 1rpx @bc-1;
+		padding: 25rpx 20rpx 25rpx 20rpx;
+		&:last-child {
+			border-bottom: none;
+		}
+		.left {
+			border-left: solid 7rpx @bc-8;
+			padding-left: 20rpx;
+			.item-title {
+				display: block;
+				font-size: 28rpx;
+				color: @fc-2;
+				margin-bottom: 15rpx;
+			}
+			.item-desc {
+				display: block;
+				font-size: 26rpx;
+				color: @fc-16;
+			}
+		}
+		.right {
+			color: @fc-2;
+			font-size: 28rpx;
+		}
+	}
+	.content-container {
+		display: flex;
+		justify-content: space-between;
+		padding: 25rpx 20rpx;
+		.content {
+			display: block;
+			font-size: 28rpx;
+			color: @fc-2;
+			margin-bottom: 30rpx;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			text {
+				color: @fc-2;
+				font-weight: bold;
+				margin-right: 3rpx;
+			}
+			.red {
+				color: @fc-19;
+			}
+		}
+		.img {
+			width: 150rpx;
+			height: auto;
+		}
+	}
+	.remark-container {
+		padding: 20rpx;
+		.remark-rate {
+			display: flex;
+			.photo {
+				margin-right: 15rpx;
+			}
+			.rate {
+				flex-grow: 1;
+				margin-top: 8rpx;
+				display: flex;
+				justify-content: space-between;
+				color: @fc-22;
+			}
+		}
+		.remark {
+			color: @fc-1;
+			line-height: 40rpx;
+			margin-top: 20rpx;
+		}
+	}
+}
+.operate-container {
+	background-color: @bgc-1;
+	padding: 45rpx 0 0 0;
+	.operate {
+		text-align: center;
+		font-size: 26rpx;
+		color: @fc-4;
+	}
+}
+.contact-container {
+	background-color: @bgc-1;
+	padding: 45rpx 50rpx 45rpx 50rpx;
+	text-align: center;
+	font-size: 26rpx;
+	color: @fc-13;
+
+	.contact {
+		margin-bottom: 20rpx;
+	}
+}
+
+.appeal-title {
+	color: @fc-20;
+	font-weight: bold;
+	font-size: 40rpx;
+	text-align: center;
+	padding: 45rpx 0 30rpx 0;
+}
+
+

+ 338 - 0
order/order/order.vue

@@ -0,0 +1,338 @@
+<template>
+	<view>
+		<view class="customer-container">
+			<u-avatar :src="photo" mode="square"></u-avatar>
+			<view class="info">
+				<view class="customer-name">代驾客户({{ title }})</view>
+				<view class="customer-tel">Tel:{{ tel }}</view>
+			</view>
+		</view>
+		<view class="address-container">
+			<view class="from">
+				<text>{{ startPlace }}</text>
+			</view>
+			<view class="dashed-line"></view>
+			<view class="to">
+				<text>{{ endPlace }}</text>
+			</view>
+		</view>
+		<view class="order-container">
+			<view>【 订单号码 】 {{ orderId }}</view>
+			<view>【 下单时间 】 {{ createTime }}</view>
+			<view>【 客户红包 】 {{ favourFee }}元</view>
+			<view>【 系统奖励 】 {{ incentiveFee }}元</view>
+			<view>【 代驾车型 】 {{ carType }}</view>
+			<view>【 代驾车牌 】 {{ carPlate }}</view>
+		</view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>基础收费</text>
+			</view>
+			<view class="section-content">
+				<view class="item">
+					<view class="left">
+						<text class="item-title">里程费({{ realMileage }}公里)</text>
+						<text class="item-desc">
+							时段收费({{ baseMileagePrice }}元{{ baseMileage }}公里,超出每公里{{
+								exceedMileagePrice
+							}}元)
+						</text>
+					</view>
+					<view class="right">{{ mileageFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">时长费({{ waitingMinute }}分钟)</text>
+						<text class="item-desc">
+							免费{{ base_minute }}分钟,超出部分每分钟{{ exceedMinutePrice }}元
+						</text>
+					</view>
+					<view class="right">{{ waitingFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">返程费({{ returnMileage }}公里)</text>
+						<text class="item-desc">
+							总里程超过{{ baseReturnMileage }}公里,每公里{{ exceedReturnPrice }}元
+						</text>
+					</view>
+					<view class="right">{{ returnFee }}</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>额外收费</text>
+			</view>
+			<view class="section-content">
+				<view class="item">
+					<view class="left">
+						<text class="item-title">停车费</text>
+						<text class="item-desc">如果代驾司机预付停车费,该费用将计入订单费用</text>
+					</view>
+					<view class="right">{{ parkingFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">路桥费</text>
+						<text class="item-desc">如果代驾司机预付停车费,该费用将计入订单费用</text>
+					</view>
+					<view class="right">{{ tollFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">其他费用</text>
+						<text class="item-desc">代驾过程中产生的其他费用</text>
+					</view>
+					<view class="right">{{ otherFree }}</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>总金额</text>
+			</view>
+			<view class="section-content">
+				<view class="content-container">
+					<view class="left">
+						<view class="content">
+							【汇总合计】
+							<text>¥ {{ total }} 元</text>
+						</view>
+						<view class="content">
+							【减免金额】
+							<text>¥ {{ voucherFee }} 元</text>
+						</view>
+						<view class="content">
+							【实付金额】
+							<text class="red">¥ {{ realPay }} 元</text>
+						</view>
+					</view>
+					<image :src="img" mode="widthFix" class="img"></image>
+				</view>
+			</view>
+		</view>
+		<view class="operate-container" v-if="status == 6">
+			<view class="operate" @tap="enterFeeHandle">输入相关费用</view>
+		</view>
+
+		<view v-if="status >= 7">
+			<view class="setion-title">
+				<image src="../static/order/rate.png" mode="widthFix"></image>
+				<text>客户评价</text>
+			</view>
+			<view class="section-content">
+				<view class="remark-container">
+					<view class="remark-rate">
+						<view class="photo"><u-avatar :src="photo" size="60" /></view>
+						<view class="rate">
+							<u-rate
+								:count="comment.count"
+								v-model="comment.value"
+								disabled="true"
+								active-color="#FFBB2A"
+								size="40"
+							/>
+							<view v-if="comment.value <= 2 && comment.status == 1" @tap="appeal.showAppeal = true">
+								我要申诉
+							</view>
+							<view v-if="comment.value <= 2 && comment.status == 2">申诉中</view>
+						</view>
+					</view>
+					<view class="remark">{{ comment.remark }}</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="contact-container">
+			<view class="contact">
+				<text class="label">客服电话:</text>
+				<text class="tel">0411-87143331</text>
+			</view>
+			<view class="contact">
+				<text class="label">服务监督电话:</text>
+				<text class="tel">0411-87143331</text>
+			</view>
+		</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+		<u-popup v-model="appeal.showAppeal" mode="center" border-radius="14" width="550rpx" height="580rpx">
+			<view class="appeal-title">华夏代驾订单评价申诉</view>
+			<u-input
+				v-model="appeal.reason"
+				type="textarea"
+				:border="false"
+				:clearable="false"
+				placeholder="填写申诉理由"
+				:custom-style="appeal.reasonStyle"
+				height="230"
+			/>
+			<u-button type="success" :custom-style="appeal.btnStyle" @click="insertAppeal">确定</u-button>
+		</u-popup>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			orderId: null,
+			customerId: null,
+			photo: '',
+			title: '',
+			tel: '',
+			startPlace: '',
+			endPlace: '',
+			createTime: '',
+			favourFee: '',
+			incentiveFee: '',
+			carPlate: '',
+			carType: '',
+			status: null,
+			realMileage: '--',
+			mileageFee: '0.00',
+			baseMileagePrice: '',
+			baseMileage: '',
+			exceedMileagePrice: '',
+
+			waitingFee: '0.00',
+			base_minute: '',
+			waitingMinute: '--',
+			exceedMinutePrice: '',
+			returnFee: '0.00',
+			baseReturnMileage: '',
+			exceedReturnPrice: '',
+			returnMileage: '--',
+			parkingFee: '0.00',
+			tollFee: '0.00',
+			otherFree: '0.00',
+			total: '--',
+			voucherFee: '--',
+			realPay: '--',
+			img: '',
+			comment: {
+				count: 5,
+				value: 0,
+				remark: '[ 客户没有评价,系统默认为好评~ ]',
+				status: null
+			},
+			appeal: {
+				showAppeal: false,
+				reason: null,
+				reasonStyle: {
+					'background-color': '#f8f8f8',
+					padding: '20rpx',
+					margin: '0 50rpx'
+				},
+				btnStyle: {
+					margin: '40rpx 50rpx 30rpx 50rpx'
+				}
+			}
+		};
+	},
+	methods: {
+		enterFeeHandle: function() {
+			uni.navigateTo({
+				url: '../enter_fee/enter_fee?orderId=' + this.orderId + '&customerId=' + this.customerId
+			});
+		},
+		insertAppeal: function() {
+			let that = this;
+			if (that.appeal.reason == null || that.appeal.reason.length == 0) {
+				uni.showToast({
+					icon: 'error',
+					title: '申诉原因不能为空'
+				});
+				return;
+			}
+			let data = {
+				orderId: that.orderId,
+				customerId: that.customerId,
+				reason: that.appeal.reason
+			};
+			that.ajax(that.url.startCommentWorkflow, 'POST', data, function(resp) {
+				that.appeal.showAppeal = false;
+				that.comment.status = 2;
+				setTimeout(function() {
+					uni.showToast({
+						icon: 'success',
+					 title: '申诉提交成功'
+					});
+				}, 1000);
+			});
+		}
+	},
+	onLoad: function(options) {
+		let that = this;
+		let orderId = options.orderId;
+		that.orderId = orderId;
+		let data = {
+			orderId: orderId
+		};
+		that.ajax(that.url.searchOrderById, 'POST', data, function(resp) {
+			let result = resp.data.result;
+			that.customerId = result.customerId;
+			that.photo = result.photo;
+			that.title = result.title;
+			that.tel = result.tel;
+			that.startPlace = result.startPlace;
+			that.endPlace = result.endPlace;
+			that.createTime = result.createTime;
+			that.favourFee = result.favourFee;
+			that.incentiveFee = result.incentiveFee;
+			that.carPlate = result.carPlate;
+			that.carType = result.carType;
+			let status = result.status;
+			that.status = status;
+			if ([5, 6, 7, 8].includes(status)) {
+				that.realMileage = result.realMileage;
+				that.mileageFee = result.mileageFee;
+				that.waitingFee = result.waitingFee;
+				that.waitingMinute = result.waitingMinute;
+				that.returnFee = result.returnFee;
+				that.returnMileage = result.returnMileage;
+				that.parkingFee = result.parkingFee;
+				that.tollFee = result.tollFee;
+				that.otherFree = result.otherFree;
+				that.total = result.total;
+				that.voucherFee = result.voucherFee;
+			}
+			that.baseMileagePrice = result.baseMileagePrice;
+			that.baseMileage = result.baseMileage;
+			that.exceedMileagePrice = result.exceedMileagePrice;
+			// that.createTime = result.createTime;
+			that.base_minute = result.baseMinute;
+			that.exceedMinutePrice = result.exceedMinutePrice;
+			that.baseReturnMileage = result.baseReturnMileage;
+			that.exceedReturnPrice = result.exceedReturnPrice;
+			that.realPay = '--';
+			if ([2, 3].includes(status)) {
+				that.img = '../static/order/icon-1.png';
+			} else if ([4].includes(status)) {
+				that.img = '../static/order/icon-2.png';
+			} else if ([5, 6].includes(status)) {
+				that.img = '../static/order/icon-3.png';
+			} else if ([7].includes(status)) {
+				that.img = '../static/order/icon-4.png';
+				that.realPay = result.realPay;
+			} else if ([8, 9, 10, 11, 12].includes(status)) {
+				that.img = '../static/order/icon-5.png';
+				that.realPay = result.realPay;
+			}
+			that.comment.value = result.comment.rate;
+			if (result.comment.hasOwnProperty('remark')) {
+				that.comment.remark = result.comment.remark;
+				that.comment.status = result.comment.status;
+			}
+		});
+	},
+	onShow: function() {},
+	onHide: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('order.less');
+</style>

+ 110 - 0
order/order_bill/order_bill.less

@@ -0,0 +1,110 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+	padding-bottom: 100rpx;
+}
+
+.setion-title {
+	background-color: @bgc-1;
+	padding: 25rpx 30rpx;
+	display: flex;
+	image {
+		width: 32rpx;
+		height: auto;
+		margin-top: 9rpx;
+		margin-right: 12rpx;
+	}
+	text {
+		font-size: 32rpx;
+		font-weight: bold;
+		color: @fc-2;
+	}
+}
+.section-content {
+	padding: 20rpx 20rpx;
+	.item {
+		display: flex;
+		justify-content: space-between;
+		border-bottom: solid 1rpx @bc-1;
+		padding: 25rpx 20rpx 25rpx 20rpx;
+		&:last-child {
+			border-bottom: none;
+		}
+		.left {
+			border-left: solid 7rpx @bc-8;
+			padding-left: 20rpx;
+			.item-title {
+				display: block;
+				font-size: 28rpx;
+				color: @fc-2;
+				margin-bottom: 15rpx;
+			}
+			.item-desc {
+				display: block;
+				font-size: 26rpx;
+				color: @fc-16;
+			}
+		}
+		.right {
+			color: @fc-2;
+			font-size: 28rpx;
+		}
+	}
+	.content-container {
+		display: flex;
+		justify-content: space-between;
+		padding: 25rpx 20rpx;
+		.content {
+			display: block;
+			font-size: 28rpx;
+			color: @fc-2;
+			margin-bottom: 30rpx;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			text {
+				color: @fc-2;
+				font-weight: bold;
+				margin-right: 3rpx;
+			}
+			.red {
+				color: @fc-19;
+			}
+		}
+		.big{
+			font-size: 32rpx;
+		}
+		.img {
+			width: 150rpx;
+			height: auto;
+		}
+	}
+	.desc{
+		padding: 10rpx 35rpx;
+		font-size: 26rpx;
+		color: @fc-16;
+	}
+}
+.contact-container {
+	background-color: @bgc-1;
+	padding: 45rpx 50rpx 45rpx 50rpx;
+	text-align: center;
+	font-size: 26rpx;
+	color: @fc-13;
+
+	.contact {
+		margin-bottom: 20rpx;
+	}
+}
+.btn {
+	background-color: @btnc-1;
+	color: #fff;
+	width: 87%;
+	margin-top: 30rpx;
+	&::after {
+		border: none;
+	}
+	&:active {
+		background-color: @btnac-1;
+	}
+}

+ 234 - 0
order/order_bill/order_bill.vue

@@ -0,0 +1,234 @@
+<template>
+	<view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>基础收费</text>
+			</view>
+			<view class="section-content">
+				<view class="item">
+					<view class="left">
+						<text class="item-title">里程费({{ realMileage }}公里)</text>
+						<text class="item-desc">时段收费({{ baseMileagePrice }}元{{ baseMileage }}公里,超出每公里{{ exceedMileagePrice }}元)</text>
+					</view>
+					<view class="right">{{ mileageFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">时长费({{ waitingMinute }}分钟)</text>
+						<text class="item-desc">免费{{ baseMinute }}分钟,超出部分每分钟{{ exceedMinutePrice }}元</text>
+					</view>
+					<view class="right">{{ waitingFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">返程费({{ returnMileage }}公里)</text>
+						<text class="item-desc">总里程超过{{ baseReturnMileage }}公里,每公里{{ exceedReturnPrice }}元</text>
+					</view>
+					<view class="right">{{ returnFee }}</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>额外收费</text>
+			</view>
+			<view class="section-content">
+				<view class="item">
+					<view class="left">
+						<text class="item-title">停车费</text>
+						<text class="item-desc">如果代驾司机预付停车费,该费用将计入订单费用</text>
+					</view>
+					<view class="right">{{ parkingFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">路桥费</text>
+						<text class="item-desc">如果代驾司机预付停车费,该费用将计入订单费用</text>
+					</view>
+					<view class="right">{{ tollFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">其他费用</text>
+						<text class="item-desc">代驾过程中产生的其他费用</text>
+					</view>
+					<view class="right">{{ otherFee }}</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>奖励费</text>
+			</view>
+			<view class="section-content">
+				<view class="item">
+					<view class="left">
+						<text class="item-title">客户好处费</text>
+						<text class="item-desc">代驾客户赠与的红包奖励</text>
+					</view>
+					<view class="right">{{ favourFee }}</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="item-title">系统奖励费</text>
+						<text class="item-desc">华夏代驾系统激励代驾司机的奖励</text>
+					</view>
+					<view class="right">{{ incentiveFee }}</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<view class="setion-title">
+				<image src="../static/order/money.png" mode="widthFix"></image>
+				<text>总金额</text>
+			</view>
+			<view class="section-content">
+				<view class="content-container">
+					<view class="left">
+						<view class="content big">
+							【汇总合计】
+							<text class="red">¥ {{ total }} 元</text>
+						</view>
+						<view class="content big">
+							【代缴个税】
+							<text class="red">¥ {{ taxFee }} 元</text>
+						</view>
+						<view class="content big">
+							【实际收入】
+							<text class="red">¥ {{ driverIncome }} 元</text>
+						</view>
+					</view>
+					
+					<image :src="img" mode="widthFix" class="img"></image>
+				</view>
+				<view class="desc">
+					代缴个税和实际收入仅供参考,以乘客实际付款金额为准
+				</view>	
+			</view>
+			<button class="btn" @tap="sendOrderBill">发送账单</button>
+		</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			orderId: null,
+			customerId: null,
+			favourFee: '暂无',
+			incentiveFee: '暂无',
+			realMileage: '--',
+			mileageFee: '暂无',
+			baseMileagePrice: '',
+			baseMileage: '',
+			exceedMileagePrice: '',
+			waitingFee: '暂无',
+			baseMinute: '',
+			waitingMinute: '--',
+			exceedMinutePrice: '',
+			returnFee: '暂无',
+			baseReturnMileage: '',
+			exceedReturnPrice: '',
+			returnMileage: '--',
+			parkingFee: '暂无',
+			tollFee: '暂无',
+			otherFee: '暂无',
+			total: '--',
+			taxFee: '--',
+			driverIncome: '--'
+		};
+	},
+	methods: {
+		sendOrderBill: function() {
+			let that = this;
+			uni.showModal({
+				title: '提示消息',
+				content: '是否发送代驾账单给客户?',
+				success: function(resp) {
+					if (resp.confirm) {
+						let data = {
+							orderId: that.orderId,
+							customerId: that.customerId,
+							status: 6
+						};
+						that.ajax(that.url.updateOrderStatus, 'POST', data, function(resp) {
+							that.workStatus = '等待付款';
+							uni.setStorageSync('workStatus', '等待付款');
+							//页面发生跳转
+							uni.navigateTo({
+								url: '../waiting_payment/waiting_payment?orderId=' + that.orderId
+							});
+						});
+					}
+				}
+			});
+		},
+		sendOrderBill: function() {
+			let that = this;
+			uni.showModal({
+				title: '提示消息',
+				content: '是否发送代驾账单给客户?',
+				success: function(resp) {
+					if (resp.confirm) {
+						let data = {
+							orderId: that.orderId,
+							customerId: that.customerId,
+							status: 6
+						};
+						that.ajax(that.url.updateOrderStatus, 'POST', data, function(resp) {
+							that.workStatus = '等待付款';
+							uni.setStorageSync('workStatus', '等待付款');
+							uni.navigateTo({
+								url: '../waiting_payment/waiting_payment?orderId=' + that.orderId
+							});
+						});
+					}
+				}
+			});
+		}
+	},
+	onLoad: function(options) {
+		let that = this;
+		that.orderId = options.orderId;
+		that.customerId = options.customerId;
+		let data = {
+			orderId: that.orderId
+		};
+		that.ajax(that.url.searchReviewDriverOrderBill, 'POST', data, function(resp) {
+			let result = resp.data.result;
+			that.favourFee = result.favourFee;
+			that.incentiveFee = result.incentiveFee;
+			that.realMileage = result.realMileage;
+			that.mileageFee = result.mileageFee;
+			that.baseMileagePrice = result.baseMileagePrice;
+			that.baseMileage = result.baseMileage;
+			that.exceedMileagePrice = result.exceedMileagePrice;
+			that.waitingFee = result.waitingFee;
+			that.baseMinute = result.baseMinute;
+			that.waitingMinute = result.waitingMinute;
+			that.exceedMinutePrice = result.exceedMinutePrice;
+			that.returnFee = result.returnFee;
+			that.baseReturnMileage = result.baseReturnMileage;
+			that.exceedReturnPrice = result.exceedReturnPrice;
+			that.returnMileage = result.returnMileage;
+			that.parkingFee = result.parkingFee;
+			that.tollFee = result.tollFee;
+			that.otherFee = result.otherFee;
+			that.total = result.total;
+			that.driverIncome = result.driverIncome;
+			that.taxFee = result.taxFee;
+		});
+	},
+	onShow: function() {},
+	onHide: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('order_bill.less');
+</style>

TEMPAT SAMPAH
order/static/order/icon-1.png


TEMPAT SAMPAH
order/static/order/icon-2.png


TEMPAT SAMPAH
order/static/order/icon-3.png


TEMPAT SAMPAH
order/static/order/icon-4.png


TEMPAT SAMPAH
order/static/order/icon-5.png


TEMPAT SAMPAH
order/static/order/money.png


TEMPAT SAMPAH
order/static/order/rate.png


TEMPAT SAMPAH
order/static/waiting_payment/payment.png


+ 70 - 0
order/waiting_payment/waiting_payment.less

@@ -0,0 +1,70 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+	background-color: #eef0f6;
+}
+.waiting-container {
+	background-color: #fff;
+	padding-top: 100rpx;
+	padding-bottom: 80rpx;
+	margin-bottom: 25rpx;
+	.payment {
+		display: block;
+		width: 50%;
+		margin-left: auto;
+		margin-right: auto;
+	}
+	.title {
+		font-size: 38rpx;
+		font-weight: bold;
+		color: @fc-1;
+		text-align: center;
+		margin-top: 30rpx;
+	}
+	.second {
+		text-align: center;
+		margin-top: 15rpx;
+		color: @fc-1;
+		font-size: 34rpx;
+	}
+	.btn {
+		background-color: @btnc-1;
+		color: #fff;
+		width: 65%;
+		margin-top: 80rpx;
+		&::after {
+			border: none;
+		}
+		&:active {
+			background-color: @btnac-1;
+		}
+	}
+}
+
+.notice-container {
+	background-color: #fff;
+	padding-left: 20rpx;
+	padding-right: 30rpx;
+	padding-bottom: 80rpx;
+	.notice-title {
+		text-align: center;
+		font-size: 32rpx;
+		padding-top: 50rpx;
+		padding-bottom: 20rpx;
+		text{
+			margin-left: 5rpx;
+		}
+	}
+	.desc {
+		font-size: 28rpx;
+		color: @fc-3;
+		line-height: 1.7;
+		padding-left: 25rpx;
+		padding-top: 10rpx;
+		padding-bottom: 10rpx;
+		display: flex;
+		.num{
+			margin-right: 10rpx;
+		}
+	}
+}

+ 119 - 0
order/waiting_payment/waiting_payment.vue

@@ -0,0 +1,119 @@
+<template>
+	<view>
+		<view class="waiting-container">
+			<image src="../static/waiting_payment/payment.png" mode="widthFix" class="payment"></image>
+			<view class="title">等待顾客付款</view>
+			<view class="second">{{ i }}s</view>
+			<button class="btn" @tap="checkPaymentHandle">未收到付款通知</button>
+		</view>
+
+		<view class="notice-container">
+			<view class="notice-title">
+				<u-icon name="error-circle-fill" top="2" color="#fea802" size="36"></u-icon>
+				<text>注意事项</text>
+			</view>
+			<view class="desc">
+				<text class="num">1.</text>
+				如果顾客已经成功付款,但是司机端未能收到付款成功的通知消息,可以点击“未收到顾客付款通知”的链接。系统将立即向微信支付平台查询顾客的付款结果;
+			</view>
+			<view class="desc">
+				<text class="num">2.</text>
+				如果顾客已经成功付款,并且您的微信上面也收到了分账通知消息,但是本页面并没有接收到用户付款成功的通知消息。您可以点击已经收款按钮,系统将立即确认付款结果;
+			</view>
+			<view class="desc">
+				<text class="num">3.</text>
+				如果顾客已经成功付款,并且本页面也接收到了付款成功的通知,但是您没有收到系统分账的通知。您可以耐心等待,因为本系统将会审核您在代驾中是否存在违规,并且扣除相关罚款,再给您分账。所以在顾客付款成功之后的2小时之内,您会收到本次代驾的分账收入,请您耐心等待,如有技术问题,请拨打400-264166678
+			</view>
+		</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			i: 0,
+			orderId: null,
+			timer: null
+		};
+	},
+	methods: {
+		checkPaymentHandle: function() {
+			let that = this;
+			let data = {
+				orderId: that.orderId
+			};
+			that.ajax(that.url.updateOrderAboutPayment, 'POST', data, function(resp) {
+				let result = resp.data.result;
+				if (result == '付款成功') {
+					uni.showToast({
+						title: '客户已付款'
+					});
+					uni.setStorageSync('workStatus', '停止接单');
+					clearInterval(that.timer);
+					that.i = 0;
+					setTimeout(function() {
+						uni.switchTab({
+							url: '../../pages/workbench/workbench'
+						});
+					}, 2500);
+				} else {
+					uni.showToast({
+						icon: '未检测到成功付款'
+					});
+				}
+			});
+		}
+	},
+	onLoad: function(options) {
+		let that = this;
+		that.orderId = options.orderId;
+		that.timer = setInterval(function() {
+			that.i++;
+			if (that.i % 2 == 0) {
+				let data = {
+					orderId: that.orderId
+				};
+				that.ajax(
+					that.url.searchOrderStatus,
+					'POST',
+					data,
+					function(resp) {
+						if (!resp.data.hasOwnProperty('result')) {
+							uni.showToast({
+						 	icon: 'none',
+								title: '没有找到订单'
+							});
+							clearInterval(that.timer);
+							that.i = 0;
+						} else {
+							let result = resp.data.result;
+							if (result == 7 || result == 8) {
+								uni.showToast({
+									title: '客户已付款'
+								});
+								uni.setStorageSync('workStatus', '停止接单');
+								clearInterval(that.timer);
+								that.i = 0;
+								setTimeout(function() {
+									uni.switchTab({
+										url: '../../pages/workbench/workbench'
+									});
+								}, 2500);
+							}
+						}
+					},
+					false
+				);
+			}
+		}, 1000);
+	},
+	onShow: function() {},
+	onHide: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('waiting_payment.less');
+</style>

+ 24 - 0
package.json

@@ -0,0 +1,24 @@
+{
+  "name": "uView",
+  "version": "1.0.0",
+  "description": "<p align=\"center\">\r     <img alt=\"logo\" src=\"https://uviewui.com/common/logo.png\" width=\"120\" height=\"120\" style=\"margin-bottom: 10px;\">\r </p>\r <h3 align=\"center\" style=\"margin: 30px 0 30px;font-weight: bold;font-size:40px;\">uView</h3>\r <h3 align=\"center\">多平台快速开发的UI框架</h3>",
+  "main": "main.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/YanxinNet/uView.git"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "bugs": {
+    "url": "https://github.com/YanxinNet/uView/issues"
+  },
+  "homepage": "https://github.com/YanxinNet/uView#readme",
+  "dependencies": {
+    "dayjs": "^1.10.7",
+    "vue-i18n": "^8.20.0"
+  }
+}

+ 248 - 0
pages.json

@@ -0,0 +1,248 @@
+{
+	"easycom": {
+		"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
+	},
+	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+		{
+			"path": "pages/login/login",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom",
+				"app-plus": {
+					"bounce": "none"
+				}
+			}
+		}, {
+			"path": "pages/register/register",
+			"style": {
+				"navigationBarTitleText": "新司机注册",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom",
+				"app-plus": {
+					"bounce": "none"
+				},
+				"backgroundColor": "#EEF0F6"
+			}
+		}, {
+			"path": "pages/workbench/workbench",
+			"style": {
+				"navigationBarTitleText": "工作台",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/order_list/order_list",
+			"style": {
+				"navigationBarTitleText": "我的订单",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/message_list/message_list",
+			"style": {
+				"navigationBarTitleText": "系统消息",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/mine/mine",
+			"style": {
+				"navigationBarTitleText": "个人中心",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/message/message",
+			"style": {
+				"navigationBarTitleText": "系统消息",
+				"enablePullDownRefresh": false
+			}
+
+		}
+		, {
+			"path": "pages/heat_chart/heat_chart",
+			"style": {
+				"navigationBarTitleText": "接单热点地区",
+				"enablePullDownRefresh": false
+			}
+
+		}
+	],
+	"tabBar": {
+		"color": "#444",
+		"selectedColor": "#1297DB",
+		"list": [{
+				"text": "工作台",
+				"pagePath": "pages/workbench/workbench",
+				"iconPath": "static/tab_bar/workbench_1.png",
+				"selectedIconPath": "static/tab_bar/workbench_2.png"
+			},
+			{
+				"text": "我的订单",
+				"pagePath": "pages/order_list/order_list",
+				"iconPath": "static/tab_bar/order_1.png",
+				"selectedIconPath": "static/tab_bar/order_2.png"
+			},
+			{
+				"text": "消息中心",
+				"pagePath": "pages/message_list/message_list",
+				"iconPath": "static/tab_bar/message_1.png",
+				"selectedIconPath": "static/tab_bar/message_2.png"
+			},
+			{
+				"text": "个人中心",
+				"pagePath": "pages/mine/mine",
+				"iconPath": "static/tab_bar/people_1.png",
+				"selectedIconPath": "static/tab_bar/people_2.png"
+			}
+		]
+	},
+	"globalStyle": {
+		"navigationBarTextStyle": "white",
+		"navigationBarTitleText": "华夏代驾",
+		"navigationBarBackgroundColor": "#2074FD",
+		"backgroundColor": "#FFFFFF"
+	},
+	"subPackages": [{
+			"root": "identity",
+			"pages": [{
+					"path": "filling/filling",
+					"style": {
+						"navigationBarTitleText": "实名登记",
+						"enablePullDownRefresh": false,
+						"usingComponents": {
+							"ocr-navigator": "plugin://ocr-plugin/ocr-navigator"
+						}
+					}
+				}, {
+					"path": "identity_camera/identity_camera",
+					"style": {
+						"navigationBarTitleText": "证件拍照",
+						"enablePullDownRefresh": false
+					}
+				},
+				{
+					"path": "face_camera/face_camera",
+					"style": {
+						"navigationBarTitleText": "人脸识别",
+						"enablePullDownRefresh": false
+					}
+				}
+			]
+		},
+		{
+			"root": "user",
+			"pages": [{
+				"path": "account/account",
+				"style": {
+					"navigationBarTitleText": "账号与安全",
+					"enablePullDownRefresh": false
+				}
+			}, {
+				"path": "settings/settings",
+				"style": {
+					"navigationBarTitleText": "接单设置",
+					"enablePullDownRefresh": false
+				}
+			}, {
+				"path": "fine_list/fine_list",
+				"style": {
+					"navigationBarTitleText": "罚款列表",
+					"enablePullDownRefresh": false
+				}
+
+			}]
+		},
+		{
+			"root": "rule",
+			"pages": [{
+					"path": "bill_rule/bill_rule",
+					"style": {
+						"navigationBarTitleText": "计费规则",
+						"enablePullDownRefresh": false
+					}
+				}, {
+					"path": "user_rule/user_rule",
+					"style": {
+						"navigationBarTitleText": "用户规则",
+						"enablePullDownRefresh": false
+					}
+				},
+				{
+					"path": "cancel_rule/cancel_rule",
+					"style": {
+						"navigationBarTitleText": "取消规则",
+						"enablePullDownRefresh": false
+					}
+				},
+				{
+					"path": "user_guide/user_guide",
+					"style": {
+						"navigationBarTitleText": "用户指南",
+						"enablePullDownRefresh": false
+					}
+				}
+			]
+		},
+		{
+			"root": "wallet",
+			"pages": [{
+				"path": "recharge/recharge",
+				"style": {
+					"navigationBarTitleText": "钱包充值",
+					"enablePullDownRefresh": false
+				}
+
+			}, {
+				"path": "wallet/wallet",
+				"style": {
+					"navigationBarTitleText": "我的钱包",
+					"enablePullDownRefresh": false
+				}
+
+			}]
+		},
+		{
+			"root": "execution",
+			"pages": [{
+				"path": "move/move",
+				"style": {
+					"navigationBarTitleText": "司乘同显",
+					"enablePullDownRefresh": false
+				}
+
+			}]
+		},
+		{
+			"root": "order",
+			"pages": [{
+				"path": "order/order",
+				"style": {
+					"navigationBarTitleText": "订单详情",
+					"enablePullDownRefresh": false
+				}
+
+			}, {
+				"path": "enter_fee/enter_fee",
+				"style": {
+					"navigationBarTitleText": "输入相关费用",
+					"enablePullDownRefresh": false
+				}
+
+			}, {
+				"path": "order_bill/order_bill",
+				"style": {
+					"navigationBarTitleText": "订单费用",
+					"enablePullDownRefresh": false
+				}
+
+			}, {
+				"path": "waiting_payment/waiting_payment",
+				"style": {
+					"navigationBarTitleText": "等待客户付款",
+					"enablePullDownRefresh": false
+				}
+
+			}]
+		}
+	]
+
+
+}

+ 60 - 0
pages/heat_chart/heat_chart.vue

@@ -0,0 +1,60 @@
+<template>
+	<view>
+		<map id="map" :style="contentStyle" 
+		    subkey="RPJBZ-4223W-ADURO-RMYNV-NDCB2-MLBCB" scale="12" 
+		    :latitude="latitude" :longitude="longitude">
+		</map>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				windowHeight: 0,
+				contentStyle: '',
+				latitude: 39.908823,
+				longitude: 116.39747,
+			}
+		},
+		methods: {
+			
+		},
+		onShow: function() {
+		    let that = this;
+		    uni.$on('updateLocation', function(location) {
+		        if (location != null) {
+		            that.latitude = location.latitude;
+		            that.longitude = location.longitude;
+		        }
+		    });
+		},
+		onHide: function() {
+		    uni.$off('updateLocation');
+		    
+		},
+		onLoad:function(){
+			let that=this
+			let windowHeight=uni.getSystemInfoSync().windowHeight
+			that.windowHeight=windowHeight
+			that.contentStyle = `width: 750rpx;height:${that.windowHeight}px;`;
+			
+			let map = wx.createMapContext('map');
+			map.addVisualLayer({
+				layerId: '88fdf7fdfb12',
+				interval: 5,
+				zIndex: 999,
+				success: function(resp) {
+				    console.log(resp);
+				},
+				fail: function(error) {
+				    console.log(error);
+				}
+			})
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 58 - 0
pages/login/login.less

@@ -0,0 +1,58 @@
+@import url("../../style.less");
+page{
+	font-family: @ff-1;
+}
+.top {
+	width: 100%;
+	display: block;
+}
+.logo {
+	display: block;
+	width: 75%;
+	margin-left: auto;
+	margin-right: auto;
+	margin-top: 50rpx;
+}
+.desc{
+	text-align: center;
+	color: @fc-2;
+	margin-top: 20rpx;
+	.name{
+		font-size: 38rpx;
+	}
+	.version{
+		font-size: 30rpx;
+	}
+}
+.btn{
+	background-color: @btnc-1;
+	color: #fff;
+	width: 70%;
+	margin-top: 50rpx;
+	&::after {
+		border: none;
+	}
+	&:active{
+		background-color: @btnac-1;
+	}
+}
+.register-container{
+	text-align: center;
+	font-size: 30rpx;
+	color: @fc-2;
+	margin-top: 30rpx;
+	.link{
+		color: @fc-4;
+		margin-left: 10rpx;
+	}
+}
+.remark{
+	display: block;
+	color: @fc-3;
+	font-size: 28rpx;
+	margin-left: 50rpx;
+	margin-right: 50rpx;
+	line-height: 1.7;
+	position: absolute;
+	bottom: 60rpx;
+}

+ 100 - 0
pages/login/login.vue

@@ -0,0 +1,100 @@
+<template>
+    <view>
+        <image src="../../static/login/top.png" mode="widthFix" class="top"></image>          
+        <button class="btn" open-type="getPhoneNumber" @getphonenumber="login">立即进入(司机版)</button>
+        <view class="register-container">
+            没有账号?
+            <text class="link" @tap="toRegisterPage()">立即注册</text>
+        </view>
+        
+        <u-toast ref="uToast" />
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {};
+    },
+    methods: {
+        login: function(e) {
+            let that = this;
+            // console.log(e.detail.code)
+            let phoneCode = e.detail.code;
+            uni.login({
+                provider: 'weixin',
+                success: function(resp) {
+                    let code = resp.code;
+                    let data = {
+                        code: code,
+                        phoneCode: phoneCode
+                    };
+                    // console.log(data);
+                    that.ajax(that.url.login, 'POST', data, function(resp) {
+                        if (!resp.data.hasOwnProperty('token')) {
+                            that.$refs.uToast.show({
+                                title: '请先注册',
+                                type: 'error'
+                            });
+                        } else {
+                            let token = resp.data.token;
+                            let realAuth = resp.data.realAuth;
+                            let archive = resp.data.archive;
+                            uni.setStorageSync('token', token);
+                            uni.setStorageSync('realAuth', realAuth);
+                            uni.removeStorageSync('executeOrder');
+                            that.$refs.uToast.show({
+                                title: '登陆成功',
+                                type: 'success',
+                                callback: function() {
+                                    uni.setStorageSync('workStatus', '停止接单');
+                                    //检查用户是否没有填写实名信息
+                                    if (realAuth == 1) {
+                                        uni.redirectTo({
+                                            url: '../../identity/filling/filling?mode=create'
+                                        });
+                                    } else if (archive == false) {
+                                        //检查系统是否存有司机的面部数据
+                                        uni.showModal({
+                                            title: '提示消息',
+                                            content: '您还没有录入用于核实身份的面部特征信息,如果不录入将无法接单',
+                                            confirmText: '录入',
+                                            cancelText: '取消',
+                                            success: function(resp) {
+                                                if (resp.confirm) {
+                                                    //跳转到面部识别页面,采集人脸数据
+                                                    uni.redirectTo({
+                                                        url: '../../identity/face_camera/face_camera?mode=create'
+                                                    });
+                                                } else {
+                                                    uni.switchTab({
+                                                        url: '../workbench/workbench'
+                                                    });
+                                                }
+                                            }
+                                        });
+                                    } else {
+                                        uni.switchTab({
+                                            url: '../workbench/workbench'
+                                        });
+                                    }
+                                }
+                            });
+                        }
+                    });
+                }
+            });
+        },
+        toRegisterPage: function() {
+            uni.navigateTo({
+                url: '../register/register'
+            });
+        }
+    },
+    onLoad: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('login.less');
+</style>

+ 45 - 0
pages/message/message.less

@@ -0,0 +1,45 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+	background-color: #eef0f6;
+}
+.message {
+	margin: 55rpx;
+	.header {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 15rpx;
+		.desc {
+			font-size: 28rpx;
+			color: #999;
+		}
+		.opt {
+			font-size: 28rpx;
+			color: red;
+			padding-right: 10rpx;
+		}
+	}
+	.content {
+		background-color: #fff;
+		padding: 20rpx 45rpx;
+		border-radius: 15rpx;
+		.sender {
+			display: flex;
+			margin-bottom: 15rpx;
+			image {
+				width: 60rpx;
+				margin-right: 20rpx;
+			}
+			text {
+				font-size: 32rpx;
+				color: @fc-1;
+				margin-top: 10rpx;
+			}
+		}
+		.msg {
+			font-size: 30rpx;
+			line-height: 1.8;
+			color: @fc-3;
+		}
+	}
+}

+ 40 - 0
pages/message/message.vue

@@ -0,0 +1,40 @@
+<template>
+	<view>
+		<view class="message">
+			<view class="header">
+				<view class="desc">{{ sendTime }}</view>
+				<view class="opt" @tap="deleteMsg()">删除</view>
+			</view>
+			<view class="content">
+				<view class="sender">
+					<image :src="senderPhoto" mode="widthFix" class="photo" />
+					<text>{{ senderName }}</text>
+				</view>
+				<view class="msg">{{ msg }}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			
+		};
+	},
+	onShow: function() {
+		
+	},
+	onLoad: function(options) {
+		
+	},
+	methods: {
+		
+	}
+};
+</script>
+
+<style lang="less">
+@import url('message.less');
+</style>

+ 56 - 0
pages/message_list/message_list.less

@@ -0,0 +1,56 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+	background-color: #eef0f6;
+	padding-bottom: 10rpx;
+}
+.message-container {
+	background-color: #fff;
+	margin: 40rpx 40rpx;
+	padding: 20rpx 30rpx;
+	border-radius: 10rpx;
+	.top {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 15rpx;
+		.title {
+			display: flex;
+			image {
+				width: 40rpx;
+				margin-top: 4rpx;
+				margin-right: 15rpx;
+			}
+			text {
+				color: @fc-1;
+				font-size: 32rpx;
+			}
+		}
+		.date {
+			font-size: 32rpx;
+			color: @fc-3;
+		}
+	}
+	.content {
+		display: -webkit-box;
+		-webkit-box-orient: vertical;
+		-webkit-line-clamp: 2;
+		overflow: hidden;
+		font-size: 28rpx;
+		line-height: 1.7;
+		color: @fc-3;
+	}
+	.bottom {
+		display: flex;
+		justify-content: space-between;
+		border-top: solid 1rpx @bc-1;
+		margin-top: 20rpx;
+		padding-top: 20rpx;
+		text{
+			font-size: 28rpx;
+			color: @fc-2;
+		}
+	}
+}
+.empty{
+	margin-top: 80rpx;
+}

+ 44 - 0
pages/message_list/message_list.vue

@@ -0,0 +1,44 @@
+<template>
+	<view>
+		<view class="message-container" v-for="one in list" v-if="list.length > 0" @tap="viewMessageHandle(one.id, one.readFlag, one.refId)">
+			<view class="top">
+				<view class="title">
+					<image src="../../static/message_list/email-icon-1.png" mode="widthFix" v-if="!one.readFlag"></image>
+					<image src="../../static/message_list/email-icon-2.png" mode="widthFix" v-if="one.readFlag"></image>
+					<text>{{ one.senderName }}</text>
+				</view>
+				<view class="date">{{ one.sendTime }}</view>
+			</view>
+			<view class="content">{{ one.msg }}</view>
+			<view class="bottom">
+				<text>查看详情</text>
+				<u-icon name="arrow-right" color="#aaa" size="28"></u-icon>
+			</view>
+		</view>
+		<view class="empty" v-if="list.length == 0"><u-empty text="消息列表为空" mode="list"></u-empty></view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			
+		};
+	},
+	methods: {
+		
+	},
+	
+	onShow: function() {
+		
+	},
+	onReachBottom: function() {
+		
+	}
+};
+</script>
+
+<style lang="less">
+@import url('message_list.less');
+</style>

+ 210 - 0
pages/mine/mine.less

@@ -0,0 +1,210 @@
+@import url('../../style.less');
+page {
+	background-color: @bgc-1;
+	font-family: @ff-1;
+}
+.page {
+	padding-bottom: 0rpx;
+}
+.summary-container {
+	background-color: @bgc-2;
+	display: flex;
+	padding: 40rpx 40rpx;
+
+	.photo {
+		width: 120rpx;
+		border-radius: 60rpx;
+	}
+	.summary {
+		margin-left: 30rpx;
+		flex-grow: 1;
+		.row {
+			display: flex;
+			padding-top: 10rpx;
+			.name {
+				font-size: 40rpx;
+				color: @fc-5;
+				font-weight: bold;
+			}
+			.auth-icon {
+				width: 36rpx;
+				margin-top: 13rpx;
+				margin-left: 30rpx;
+			}
+			.auth {
+				color: @fc-6;
+				font-size: 28rpx;
+				margin-top: 12rpx;
+				margin-left: 15rpx;
+			}
+			.unauth {
+				.auth;
+				color: @fc-7;
+			}
+			.attribute {
+				color: @fc-5;
+				font-size: 26rpx;
+				width: 100%;
+				display: flex;
+				margin-top: 5rpx;
+				.item {
+					line-height: 1;
+					&:first-of-type {
+						padding-right: 28rpx;
+						border-right: solid 1rpx @bc-1;
+					}
+					&:nth-of-type(2) {
+						padding-left: 28rpx;
+						padding-right: 28rpx;
+						border-right: solid 1rpx @bc-1;
+					}
+					&:nth-of-type(3) {
+						padding-left: 28rpx;
+					}
+				}
+			}
+		}
+	}
+}
+.notice-container {
+	background-color: @bgc-3;
+	padding: 30rpx 40rpx;
+	.notice-title {
+		display: flex;
+		image {
+			width: 36rpx;
+			margin-top: 8rpx;
+		}
+		text {
+			color: @fc-5;
+			font-size: 32rpx;
+			margin-left: 10rpx;
+			font-weight: bold;
+		}
+	}
+	.desc {
+		color: @fc-5;
+		font-size: 26rpx;
+		margin-top: 10rpx;
+		line-height: 1.6;
+	}
+}
+
+.nav-container {
+	background-color: #fff;
+	padding: 0 40rpx;
+	.row {
+		display: flex;
+		padding: 40rpx 0;
+		&:first-of-type {
+			// border-bottom: solid 2rpx #e0e0e0;
+		}
+		.item {
+			display: flex;
+			width: 334rpx;
+			&:last-child {
+				padding-left: 40rpx;
+			}
+			image {
+				width: 48rpx;
+				margin-top: 4rpx;
+			}
+			.info {
+				margin-left: 20rpx;
+				.title {
+					display: block;
+					font-size: 36rpx;
+				}
+				.desc {
+					display: block;
+					margin-top: 10rpx;
+					font-size: 28rpx;
+					color: @fc-3;
+				}
+			}
+		}
+		.border-column {
+			width: 0;
+			border-left: solid 2rpx @bc-2;
+		}
+	}
+	.border-row {
+		// padding: 0 40rpx;
+		display: flex;
+		justify-content: space-between;
+		&::before {
+			content: '';
+			display: block;
+			height: 0;
+			border-bottom: solid 2rpx @bc-2;
+			width: 300rpx;
+		}
+		&::after {
+			content: '';
+			display: block;
+			height: 0;
+			border-bottom: solid 2rpx @bc-2;
+			width: 300rpx;
+		}
+	}
+}
+.tab-container {
+	display: flex;
+	margin: 20rpx 0;
+	padding: 40rpx;
+	background-color: #fff;
+	justify-content: space-between;
+	.item {
+		.ball {
+			width: 90rpx;
+			height: 90rpx;
+			border-radius: 44rpx;
+			background-color: @bc-3;
+			background-size: 44rpx;
+			background-repeat: no-repeat;
+			margin-left: auto;
+			margin-right: auto;
+		}
+		.ball-1 {
+			background-image: url(../../static/mine/icon-8.png);
+			background-position: 26rpx 24rpx;
+			background-size: 40rpx;
+		}
+		.ball-2 {
+			background-image: url(../../static/mine/icon-9.png);
+			background-position: 24rpx 22rpx;
+		}
+		.ball-3 {
+			background-image: url(../../static/mine/icon-10.png);
+			background-position: 24rpx 22rpx;
+		}
+		.ball-4 {
+			background-image: url(../../static/mine/icon-11.png);
+			background-position: 24rpx 22rpx;
+		}
+		text {
+			font-size: 28rpx;
+			color: @fc-2;
+			display: block;
+			text-align: center;
+			margin-top: 20rpx;
+		}
+	}
+}
+.exit {
+	margin-top: 20rpx;
+	background-color: #fff;
+	padding-bottom: 50rpx;
+	.btn {
+		background-color: @btnc-1;
+		color: #fff;
+		border-radius: 0;
+		padding: 8rpx;
+		&::after {
+			border: none;
+		}
+		&:active {
+			background-color: @btnac-1;
+		}
+	}
+}

+ 228 - 0
pages/mine/mine.vue

@@ -0,0 +1,228 @@
+<template>
+	<view class="page">
+		<view class="summary-container">
+			<image :src="photo" mode="widthFix" class="photo"></image>
+			<view class="summary">
+				<view class="row">
+					<text class="name">{{ name }}</text>
+					<image :src="realAuth ? '../../static/mine/icon-1.png' : '../../static/mine/icon-2.png'" mode="widthFix" class="auth-icon"></image>
+					<text :class="realAuth ? 'auth' : 'unauth'">{{ realAuth ? '已认证' : '未认证' }}</text>
+				</view>
+				<view class="row">
+					<view class="attribute">
+						<view class="item">代驾:{{ years }}年</view>
+						<view class="item">等级:Lv{{ level }}</view>
+						<view class="item">接单:{{ changeNumber(totalOrder) }}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="notice-container">
+			<view class="notice-title">
+				<image src="../../static/mine/icon-3.png" mode="widthFix"></image>
+				<text>{{ levelName }}</text>
+			</view>
+			<view class="desc">升级Lv{{ level + 1 }}等级还需接单{{ 50 - (totalOrder % 50) }}个,并且为顾客提供安全和高质量代驾服务</view>
+		</view>
+		<view class="nav-container">
+			<view class="row">
+				<view class="item" @tap="toPage('../../wallet/recharge/recharge')">
+					<image src="../../static/mine/icon-4.png" mode="widthFix"></image>
+					<view class="info">
+						<text class="title">钱包</text>
+						<text class="desc">总额{{ balance }}元</text>
+					</view>
+				</view>
+				<view class="border-column"></view>
+				<view class="item">
+					<image src="../../static/mine/icon-5.png" mode="widthFix"></image>
+					<view class="info">
+						<text class="title">订单</text>
+						<text class="desc">本周有{{ weekOrder }}单</text>
+					</view>
+				</view>
+			</view>
+			<view class="border-row"></view>
+			<view class="row">
+				<view class="item">
+					<image src="../../static/mine/icon-6.png" mode="widthFix"></image>
+					<view class="info">
+						<text class="title">顾客评价</text>
+						<text class="desc">近期{{ weekComment }}条好评</text>
+					</view>
+				</view>
+				<view class="border-column"></view>
+				<view class="item">
+					<image src="../../static/mine/icon-7.png" mode="widthFix"></image>
+					<view class="info">
+						<text class="title">我的申诉</text>
+						<text class="desc">正在申诉{{ appeal }}件</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="tab-container">
+			<view class="item">
+				<view class="ball ball-1"></view>
+				<text>活动中心</text>
+			</view>
+			<view class="item">
+				<view class="ball ball-2"></view>
+				<text>积分商城</text>
+			</view>
+			<view class="item">
+				<view class="ball ball-3"></view>
+				<text>本月排名</text>
+			</view>
+			<view class="item">
+				<view class="ball ball-4"></view>
+				<text>我的数据</text>
+			</view>
+		</view>
+		<u-cell-group :border="false">
+           
+			<u-cell-item icon="account-fill" :icon-style="icon" title="账号与安全" :border-top="false" @click="this.toPage('../../user/account/account')" />
+            <u-cell-item icon="eye-fill" :icon-style="icon" title="接单热点地区" @click="this.toPage('../heat_chart/heat_chart')" />
+			<u-cell-item icon="server-fill" :icon-style="icon" title="在线客服" @click="serviceHandle" />
+			<u-cell-item icon="trash-fill" :icon-style="icon" title="清理缓存" @click="clearHandle" />
+			<u-cell-item icon="file-text-fill" :icon-style="icon" title="用户指南" :border-bottom="false" @click="this.toPage('../../rule/user_guide/user_guide')" />
+		</u-cell-group>
+		<view class="exit"><button class="btn" @tap="logoutHandle()">退出系统</button></view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+let dayjs = require('dayjs');
+export default {
+	data() {
+		return {
+			icon: {
+				color: '#8A8B8F',
+				'margin-top': '-1rpx'
+			},
+			name: '',
+			photo: '',
+			realAuth: false,
+			years: 0,
+			level: 0,
+			levelName: '',
+			balance: 0,
+			totalOrder: 0,
+			weekOrder: 0,
+			weekComment: 0,
+			appeal: 0
+		};
+	},
+	methods: {
+		logoutHandle: function() {
+			let that = this;
+			uni.vibrateShort({});
+			uni.showModal({
+				title: '提示信息',
+				content: '确认退出系统?',
+				success: function(resp) {
+					if (resp.confirm) {
+						that.ajax(that.url.logout, 'GET', null, function(resp) {
+							uni.removeStorageSync('realAuth');
+							uni.removeStorageSync('token');
+							uni.showToast({
+								title: '已经退出系统',
+								success: function() {
+									setTimeout(function() {
+										uni.redirectTo({
+											url: '../login/login'
+										});
+									}, 1500);
+								}
+							});
+						});
+					}
+				}
+			});
+		},
+		serviceHandle: function() {
+			uni.vibrateShort({});
+			uni.makePhoneCall({
+				phoneNumber: '10086'
+			});
+		},
+		clearHandle: function() {
+			uni.vibrateShort({});
+			uni.showModal({
+				title: '提示消息',
+				content: '清理本地缓存',
+				success: function(resp) {
+					if (resp.confirm) {
+						uni.vibrateShort({});
+						uni.showLoading({
+							title: '执行中'
+						});
+						let cache = uni.getStorageInfoSync();
+						for (let key of cache.keys) {
+							if (key == 'token' || key == 'realAuth') {
+								continue;
+							}
+							uni.removeStorageSync(key);
+							console.log('删除Storage缓存成功');
+						}
+						uni.getSavedFileList({
+							success: function(resp) {
+								for (let one of resp.fileList) {
+									let path = one.filePath;
+									uni.removeSavedFile({
+										filePath: path,
+										success: function() {
+											console.log('缓存文件删除成功');
+										}
+									});
+								}
+							}
+						});
+						setTimeout(function() {
+							uni.hideLoading();
+							uni.showToast({
+								title: '清理完毕'
+							});
+						}, 500);
+					}
+				}
+			});
+		}
+	},
+	onShow: function() {
+		let that = this;
+		that.ajax(that.url.searchDriverBaseInfo, 'POST', null, function(resp) {
+			let result = resp.data.result;
+			that.name = result.name;
+			that.photo = result.photo;
+			that.realAuth = uni.getStorageSync('realAuth') == 1;
+
+			let createTime = dayjs(result.createTime, 'YYYY-MM-DD');
+			let current = dayjs();
+			let years = current.diff(createTime, 'years');
+			that.years = years;
+			that.level = result.summary.level;
+			if (that.level < 10) {
+				that.levelName = '初级代驾';
+			} else if (that.level < 30) {
+				that.levelName = '中级代驾';
+			} else if (that.level < 50) {
+				that.levelName = '高级代驾';
+			} else {
+				that.levelName = '王牌代驾';
+			}
+			that.balance = result.balance;
+			that.totalOrder = result.summary.totalOrder;
+			that.weekOrder = result.summary.weekOrder;
+			that.weekComment = result.summary.weekComment;
+			that.appeal = result.summary.appeal;
+		});
+	},
+	onHide: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('mine.less');
+</style>

+ 119 - 0
pages/order_list/order_list.less

@@ -0,0 +1,119 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+	background-color: #eef0f6;
+}
+.order-list {
+	.month {
+		display: flex;
+		justify-content: space-between;
+		padding: 20rpx 30rpx;
+		text {
+			font-size: 34rpx;
+			font-weight: bold;
+			color: @fc-1;
+		}
+		image {
+			width: 38rpx;
+		}
+	}
+	.order {
+		background-color: #fff;
+		margin-bottom: 20rpx;
+		&:last-child{
+			margin-bottom: 0;
+		}
+		.top {
+			display: flex;
+			justify-content: space-between;
+			padding-top: 20px;
+			.date {
+				background-color: @bgc-10;
+				color: #fff;
+				padding-left: 40rpx;
+				padding-right: 30rpx;
+				padding-top: 13rpx;
+				padding-bottom: 13rpx;
+				border-top-right-radius: 100rpx;
+				border-bottom-right-radius: 100rpx;
+				font-size: 32rpx;
+				font-weight: bold;
+			}
+			.amount-status {
+				padding-right: 30rpx;
+				padding-top: 10rpx;
+				.amount {
+					font-size: 32rpx;
+					font-weight: bold;
+					color: @fc-1;
+					margin-right: 35rpx;
+				}
+				.status {
+					font-size: 30rpx;
+					color: @fc-2;
+					font-weight: bold;
+				}
+				.green{
+					color: @fc-21;
+				}
+				.red{
+					color: @fc-19;
+				}
+				.orange{
+					color: @fc-20;
+				}
+			}
+		}
+		.content {
+			padding-top: 40rpx;
+			padding-bottom: 30rpx;
+			.from {
+				display: flex;
+				margin-bottom: 25rpx;
+				font-size: 30rpx;
+				color: @fc-1;
+				padding: 0 40rpx;
+				&::before {
+					display: block;
+					content: '';
+					width: 20rpx;
+					height: 20rpx;
+					border-radius: 10rpx;
+					background-color: @bgc-7;
+					margin-top: 14rpx;
+					margin-right: 17rpx;
+				}
+			}
+			.to {
+				display: flex;
+				margin-bottom: 25rpx;
+				font-size: 30rpx;
+				color: @fc-1;
+				padding: 0 40rpx;
+				&::before {
+					display: block;
+					content: '';
+					width: 20rpx;
+					height: 20rpx;
+					border-radius: 10rpx;
+					background-color: @bgc-8;
+					margin-top: 14rpx;
+					margin-right: 17rpx;
+				}
+			}
+			.desc{
+				display: flex;
+				justify-content: space-between;
+				padding-left: 40rpx;
+				padding-right: 25rpx;
+				text{
+					font-size: 30rpx;
+					color: @fc-3;
+				}
+				.rate{
+					margin-top: 5rpx;
+				}
+			}
+		}
+	}
+}

+ 138 - 0
pages/order_list/order_list.vue

@@ -0,0 +1,138 @@
+<template>
+	<view>
+		<view class="order-list" v-for="one in monthList">
+			<view class="month">
+				<text>{{ one.month }}</text>
+				<image src="../../static/order_list/calendar-icon.png" mode="widthFix"></image>
+			</view>
+			<view class="order" v-for="order in one.orders" @tap="viewOrderHandle(order.id)">
+				<view class="top">
+					<view class="date">{{ order.acceptTime }}</view>
+					<view class="amount-status">
+						<text class="amount" v-if="order.hasOwnProperty('realFee')">¥{{ order.realFee }}</text>
+						<text :class="order.style">{{ order.status }}</text>
+					</view>
+				</view>
+				<view class="content">
+					<view class="from">
+						<text>{{ order.startPlace }}</text>
+					</view>
+					<view class="to">
+						<text>{{ order.endPlace }}</text>
+					</view>
+					<view class="desc">
+						<text>订单编号:{{ order.id }}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+let dayjs = require('dayjs');
+export default {
+	data() {
+		return {
+			monthList: [],
+			page: 1,
+			length: 50,
+			isLastPage: false
+		};
+	},
+	methods: {
+		loadPageData: function(ref) {
+			let data = {
+				page: ref.page,
+				length: ref.length
+			};
+			let status = {
+				'1': '等待接单',
+				'2': '已接单',
+				'3': '司机已到达',
+				'4': '开始代驾',
+				'5': '结束代驾',
+				'6': '未付款',
+				'7': '已付款',
+				'8': '订单已结束',
+				'9': '顾客撤单',
+				'10': '司机撤单',
+				'11': '事故关闭',
+				'12': '其他'
+			};
+			ref.ajax(ref.url.searchDriverOrderByPage, 'POST', data, function(resp) {
+				let result = resp.data.result;
+				let temp = null;
+				let orderList = [];
+				let monthList = [];
+				if (!result.hasOwnProperty('list') || result.list.length == 0) {
+					ref.isLastPage = true;
+					return;
+				}
+				for (let one of result.list) {
+					if (temp != null && temp != one.month) {
+						monthList.push({ month: temp, orders: orderList });
+						orderList = [];
+					}
+					if (one.status == 6) {
+						one.style = 'status red';
+					} else if (one.status == 7) {
+						one.style = 'status green';
+					} else if ([9, 10].includes(one.status)) {
+						one.style = 'status orange';
+					} else {
+						one.style = 'status';
+					}
+					one.status = status[one.status + ''];
+					one.acceptTime = dayjs(one.acceptTime, 'YYYY-MM-DD HH-mm-ss').format('MM/DD HH:mm');
+					orderList.push(one);
+					temp = one.month;
+				}
+				monthList.push({ month: temp, orders: orderList });
+				if (ref.monthList.length == 0) {
+					ref.monthList = monthList;
+				} else {
+					for (let one of monthList) {
+						let flag = false;
+						for (let temp of ref.monthList) {
+							if (one.month == temp.month) {
+								temp.orders = temp.orders.concat(one.orders);
+								flag = true;
+								break;
+							}
+						}
+						if (!flag) {
+							ref.monthList.push(one);
+						}
+					}
+				}
+			});
+		},
+		viewOrderHandle: function(orderId) {
+			uni.navigateTo({
+				url: '/order/order/order?orderId=' + orderId
+			});
+		}
+	},
+	onLoad: function() {
+		let that = this;
+		that.loadPageData(that);
+	},
+	onReachBottom: function() {
+		let that = this;
+		if (that.isLastPage) {
+			return;
+		}
+		that.page = that.page + 1;
+		that.loadPageData(that);
+	},
+
+	onShow: function() {},
+	onHide: function() {}
+};
+</script>
+
+<style lang="less">
+@import url('order_list.less');
+</style>

+ 130 - 0
pages/register/register.less

@@ -0,0 +1,130 @@
+@import url('../../style.less');
+page {
+	background-color: @bgc-1;
+	height: 100%;
+	font-family: @ff-1;
+}
+.page {
+	padding-bottom: 70rpx;
+}
+.top {
+	width: 100%;
+}
+.location-container {
+	display: flex;
+	justify-content: space-between;
+	background-color: #fff;
+	width: 85%;
+	margin-left: auto;
+	margin-right: auto;
+	// border: #e5e5e5 solid 1rpx;
+	padding: 25rpx 30rpx;
+	border-radius: 10rpx;
+	position: relative;
+	top: -40rpx;
+	box-shadow: @bc-1 0px 2px 8px 0px;
+	margin-bottom: 50rpx;
+	.left {
+		display: flex;
+		font-size: 28rpx;
+		color: @fc-2;
+		.location {
+			width: 30rpx;
+			margin-top: 6rpx;
+			margin-right: 5rpx;
+		}
+	}
+	.right {
+		font-size: 28rpx;
+		color: @fc-2;
+	}
+}
+.info-container {
+	background-color: #fff;
+	border-radius: 10rpx;
+	width: 85%;
+	margin-left: auto;
+	margin-right: auto;
+	padding-bottom: 25rpx;
+	margin-bottom: 80rpx;
+	// box-shadow: #e0e0e0 0px 2px 8px 0px;
+	.title-container {
+		text-align: center;
+		position: relative;
+		margin-bottom: 25rpx;
+		.title-bg {
+			width: 380rpx;
+			margin-top: -29rpx;
+		}
+		.title {
+			color: @fc-1;
+			text-align: center;
+			display: block;
+			width: 100%;
+			position: absolute;
+			top: -14rpx;
+			font-size: 32rpx;
+			font-weight: bold;
+		}
+	}
+	.list {
+		margin: 0 40rpx;
+		font-size: 28rpx;
+		color: @fc-8;
+		line-height: 1.7;
+		.item {
+			margin-bottom: 10rpx;
+			display: flex;
+			text {
+				margin-right: 15rpx;
+			}
+		}
+		.complex-item {
+			display: flex;
+			line-height: 1;
+			border-bottom: solid 1rpx @bc-4;
+			padding-bottom: 35rpx;
+			padding-top: 35rpx;
+			&:first-child {
+				padding-top: 0;
+			}
+			&:last-child {
+				border-bottom: none;
+			}
+			.left {
+				font-size: 90rpx;
+				color: @fc-9;
+				font-weight: bold;
+				margin-right: 25rpx;
+				// margin-top: -20rpx;
+			}
+			.right {
+				.item-title {
+					font-weight: bold;
+					color: @fc-1;
+					display: block;
+					font-size: 34rpx;
+					margin-top: 8rpx;
+					margin-bottom: 14rpx;
+				}
+				.item-desc {
+					color: @fc-8;
+					display: block;
+					font-size: 28rpx;
+				}
+			}
+		}
+	}
+}
+
+.btn {
+	width: 85%;
+	background-color: @btnc-1;
+	color: #fff;
+	&::after {
+		border: none;
+	}
+	&:active {
+		background-color: @btnac-1;
+	}
+}

+ 129 - 0
pages/register/register.vue

@@ -0,0 +1,129 @@
+<template>
+    <view class="page">
+        <image src="../../static/register/top.jpg" mode="widthFix" class="top" />
+        <view class="location-container">
+            <view class="left">
+                <image src="../../static/register/location.png" mode="widthFix" class="location"></image>
+                <text>hxds服务地点</text>
+            </view>
+            <view class="right">xxx.xxx</view>
+        </view>
+        <view class="info-container">
+            <view class="title-container">
+                <image src="../../static/register/title-bg.png" mode="widthFix" class="title-bg"></image>
+                <text class="title">基本要求</text>
+            </view>
+            <view class="list">
+                <view class="item">
+                    <text>1.</text>
+                    三年安全驾驶经验;
+                </view>
+                <view class="item">
+                    <text>2.</text>
+                    年龄23~55周岁;
+                </view>                
+                <view class="item">
+                    <text>4.</text>
+                    有熟练驾车经验;
+                </view>               
+                <view class="item">
+                    <text>6.</text>
+                    需要提供身份证、驾驶证、直系亲属联系方式,并保存前述材料的真实合法性;
+                </view>
+            </view>
+        </view>
+        <view class="info-container">
+            <view class="title-container">
+                <image src="../../static/register/title-bg.png" mode="widthFix" class="title-bg"></image>
+                <text class="title">基本要求</text>
+            </view>
+            <view class="list">
+                <view class="complex-item">
+                    <view class="left">01</view>
+                    <view class="right">
+                        <text class="item-title">在线注册</text>
+                        <text class="item-desc">在小程序上完成注册</text>
+                    </view>
+                </view>
+                <view class="complex-item">
+                    <view class="left">02</view>
+                    <view class="right">
+                        <text class="item-title">基本信息提交</text>
+                        <text class="item-desc">按照流程提交本人身份证、驾驶证</text>
+                    </view>
+                </view>
+                <view class="complex-item">
+                    <view class="left">03</view>
+                    <view class="right">
+                        <text class="item-title">信息审核</text>
+                        <text class="item-desc">对提交信息以及证件进行审核</text>
+                    </view>
+                </view>
+                <view class="complex-item">
+                    <view class="left">04</view>
+                    <view class="right">
+                        <text class="item-title">签署合同</text>
+                        <text class="item-desc">收到邮寄的合同后必须本人签署</text>
+                    </view>
+                </view>
+            </view>
+        </view>
+        <button class="btn" open-type="getUserInfo" @tap="register()">立即注册</button>
+        <u-toast ref="uToast" />
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            code: null
+        };
+    },
+    methods: {
+        register: function() {
+            let that = this;
+            uni.login({
+                provider: 'weixin',
+                success: function(resp) {
+                    let code = resp.code;
+                    that.code = code;
+                }
+            });
+            uni.getUserProfile({
+                desc: '获取用户信息',
+                success: function(resp) {
+                    let nickname = resp.userInfo.nickName;
+                    let avatarUrl = resp.userInfo.avatarUrl;
+                    console.log(nickname);
+                    console.log(avatarUrl);
+                    let data = {
+                        code: that.code,
+                        nickname: nickname,
+                        photo: avatarUrl
+                    };
+                    that.ajax(that.url.registerNewDriver, 'POST', data, function(resp) {
+                        console.log(resp);
+                        let token = resp.data.token;
+                        uni.setStorageSync('token', token);
+                        uni.setStorageSync('realAuth', 1);
+                        that.$refs.uToast.show({
+                            title: '注册成功',
+                            type: 'success',
+                            callback: function() {
+                                uni.redirectTo({
+                                    url: '../../identity/filling/filling?mode=create'
+                                });
+                            }
+                        });
+                    });
+                }
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less">
+@import url('register.less');
+</style>

+ 542 - 0
pages/workbench/workbench.less

@@ -0,0 +1,542 @@
+@import url('../../style.less');
+page {
+	font-family: @ff-1;
+}
+.review-container {
+	image {
+		display: block;
+		width: 70%;
+		margin-left: auto;
+		margin-right: auto;
+		margin-top: 180rpx;
+	}
+	.title {
+		color: @fc-10;
+		font-size: 50rpx;
+		font-weight: bold;
+		text-align: center;
+		margin-top: 50rpx;
+	}
+	.desc {
+		font-size: 28rpx;
+		color: @fc-8;
+		text-align: center;
+		margin-top: 15rpx;
+	}
+}
+
+.top-container {
+	background-color: @bgc-2;
+	padding-top: 40rpx;
+	padding-bottom: 40rpx;
+	height: 200px;
+	.notice {
+		color: @fc-11;
+		font-size: 26rpx;
+		text-align: center;
+		background-color: @bgc-4;
+		width: 60%;
+		margin-left: auto;
+		margin-right: auto;
+		height: 48rpx;
+		line-height: 48rpx;
+		border-radius: 24rpx;
+	}
+	.summary-container {
+		display: flex;
+		justify-content: space-between;
+		margin-top: 40rpx;
+		.item {
+			flex-grow: 1;
+			color: @fc-5;
+			&:nth-child(2) {
+				border-left: solid @bc-1 2rpx;
+				border-right: solid @bc-1 2rpx;
+			}
+			.title {
+				text-align: center;
+				font-size: 30rpx;
+			}
+			.value {
+				text-align: center;
+				margin-top: 15rpx;
+				.number {
+					font-size: 56rpx;
+					font-weight: bold;
+					padding: 0 10rpx;
+				}
+				.unit {
+					font-size: 28rpx;
+					vertical-align: 5rpx;
+				}
+			}
+		}
+	}
+	.service-container {
+		display: flex;
+		padding: 0 30rpx;
+		justify-content: space-between;
+		margin-top: 15rpx;
+		.item {
+			margin-top: 20rpx;
+			color: @fc-12;
+			font-size: 24rpx;
+			background-color: @bgc-4;
+			padding: 10rpx 15rpx;
+			display: flex;
+			border-radius: 10rpx;
+
+			.icon-1 {
+				width: 30rpx;
+				margin-right: 10rpx;
+				margin-top: 3rpx;
+			}
+			.icon-2 {
+				width: 30rpx;
+				margin-right: 10rpx;
+				margin-top: 3rpx;
+			}
+			.icon-3 {
+				width: 33rpx;
+				margin-right: 10rpx;
+				margin-top: 1rpx;
+			}
+			.icon-4 {
+				width: 30rpx;
+				margin-right: 10rpx;
+				margin-top: 3rpx;
+			}
+		}
+	}
+}
+.location {
+	width: 50rpx;
+	height: 50rpx;
+	position: absolute;
+	right: 45rpx;
+	bottom: 60rpx;
+}
+
+.new-order {
+	border-top: solid 25rpx @bc-4;
+	border-bottom: solid 25rpx @bc-4;
+	padding-left: 50rpx;
+	padding-right: 50rpx;
+	padding-top: 50rpx;
+	height: 570rpx;
+	.no-order-img {
+		display: block;
+		margin-left: auto;
+		margin-right: auto;
+		margin-top: 20rpx;
+		width: 50%;
+	}
+	.no-order-title {
+		font-size: 36rpx;
+		// font-weight: bold;
+		text-align: center;
+		margin-top: -30rpx;
+		color: #fea802;
+	}
+	.line-1 {
+		display: flex;
+		justify-content: space-between;
+		.sub-time {
+			color: @fc-16;
+			font-size: 28rpx;
+			margin-bottom: 20rpx;
+			height: 40rpx;
+		}
+		.number {
+			color: @fc-1;
+			font-weight: bold;
+			font-size: 60rpx;
+			margin-right: 8rpx;
+		}
+		.unit {
+			color: @fc-2;
+			font-size: 32rpx;
+		}
+		.tag {
+			color: @fc-18;
+			font-size: 26rpx;
+			margin-bottom: 10rpx;
+			background-color: @bgc-6;
+			height: 50rpx;
+			line-height: 50rpx;
+			padding: 0 20rpx;
+			border-radius: 25rpx;
+			position: relative;
+			top: -10rpx;
+		}
+	}
+	.line-2 {
+		font-size: 28rpx;
+		color: @fc-2;
+		line-height: 1.6;
+		margin-top: 35rpx;
+		.from {
+			display: flex;
+			&::before {
+				display: block;
+				content: '';
+				width: 20rpx;
+				height: 20rpx;
+				border-radius: 10rpx;
+				background-color: @bgc-7;
+				margin-top: 14rpx;
+				margin-right: 17rpx;
+			}
+		}
+		.dashed-line {
+			height: 30rpx;
+			border-left: @bc-5 2rpx dashed;
+			// background-color: red;
+			margin-top: 5rpx;
+			margin-bottom: 5rpx;
+			margin-left: 10rpx;
+		}
+		.to {
+			display: flex;
+			&::before {
+				display: block;
+				content: '';
+				width: 20rpx;
+				height: 20rpx;
+				border-radius: 10rpx;
+				background-color: @bgc-8;
+				margin-top: 14rpx;
+				margin-right: 17rpx;
+			}
+		}
+	}
+	.accept-btn {
+		margin-top: 50rpx;
+		background-color: @btnc-3;
+		color: #fff;
+		line-height: 70rpx;
+		padding: 10rpx 0;
+
+		font-size: 34rpx;
+		font-weight: bold;
+		&::after {
+			border: none;
+		}
+		&:active {
+			background-color: @btnac-3;
+		}
+	}
+	.disabled-btn {
+		background-color: @btnc-4;
+		margin-top: 50rpx;
+		color: #fff;
+		line-height: 70rpx;
+		padding: 10rpx 0;
+		font-size: 34rpx;
+		font-weight: bold;
+		&::after {
+			border: none;
+		}
+	}
+}
+.notice-container {
+	padding: 50rpx;
+	.title {
+		font-size: 32rpx;
+		font-weight: bold;
+		text-align: center;
+		margin-bottom: 15rpx;
+	}
+	.desc {
+		font-size: 28rpx;
+		color: @fc-3;
+		line-height: 1.7;
+		padding-top: 10rpx;
+		padding-bottom: 10rpx;
+		display: flex;
+		.num {
+			margin-right: 10rpx;
+		}
+	}
+}
+.execute-order-container {
+	position: relative;
+	.call {
+		position: absolute;
+		right: 45rpx;
+		margin-top: 60rpx;
+		width: 120rpx;
+		height: 120rpx;
+		border-radius: 60rpx;
+		background-color: @btnc-5;
+		background-image: url(../../static/workbench/call.png);
+		background-size: 60rpx 60rpx;
+		background-position: 26rpx 35rpx;
+		background-repeat: no-repeat;
+		&:active {
+			background-color: @btnac-5;
+		}
+	}
+	.customer-container {
+		border-top: solid 25rpx @bc-4;
+		display: flex;
+		padding-left: 50rpx;
+		padding-right: 50rpx;
+		padding-top: 50rpx;
+		.info {
+			margin-left: 30rpx;
+			.customer-name {
+				font-size: 36rpx;
+				font-weight: bold;
+				color: @fc-2;
+				margin-bottom: 10rpx;
+			}
+			.customer-tel {
+				font-size: 28rpx;
+				color: @fc-2;
+				margin-bottom: 10rpx;
+				letter-spacing: 1rpx;
+			}
+		}
+	}
+	.address-container {
+		font-size: 28rpx;
+		color: @fc-2;
+		line-height: 1.6;
+		margin-top: 35rpx;
+		padding-left: 50rpx;
+		padding-right: 50rpx;
+		.from {
+			display: flex;
+			&::before {
+				display: block;
+				content: '';
+				width: 20rpx;
+				height: 20rpx;
+				border-radius: 10rpx;
+				background-color: @bgc-7;
+				margin-top: 14rpx;
+				margin-right: 17rpx;
+			}
+		}
+		.dashed-line {
+			height: 30rpx;
+			border-left: @bc-5 2rpx dashed;
+			// background-color: red;
+			margin-top: 5rpx;
+			margin-bottom: 5rpx;
+			margin-left: 10rpx;
+		}
+		.to {
+			display: flex;
+			&::before {
+				display: block;
+				content: '';
+				width: 20rpx;
+				height: 20rpx;
+				border-radius: 10rpx;
+				background-color: @bgc-8;
+				margin-top: 14rpx;
+				margin-right: 17rpx;
+			}
+		}
+	}
+	.order-container {
+		padding: 25rpx 50rpx;
+		margin-top: 30rpx;
+		
+		border-top: solid 25rpx @bc-4;
+		view {
+			line-height: 60rpx;
+			height: 60rpx;
+			color: @fc-2;
+			font-size: 28rpx;
+			display: flex;
+		}
+	}
+	.operate-container {
+		padding: 30rpx 40rpx 40rpx 40rpx;
+		display: flex;
+		justify-content: space-around;
+		.item {
+			background-color: @bc-12;
+			padding: 15rpx 30rpx;
+			border-radius: 15rpx;
+			.cancel-icon {
+				width: 60rpx;
+				display: block;
+				margin-top: 10px;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.cancel-text {
+				display: block;
+				text-align: center;
+				color: @fc-20;
+				margin-top: 15rpx;
+				font-size: 28rpx;
+			}
+			.arrive-start-icon {
+				width: 100rpx;
+				display: block;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.arrive-start-text {
+				display: block;
+				text-align: center;
+				color: @fc-21;
+				margin-top: -8rpx;
+				font-size: 28rpx;
+			}
+			.drive-start-icon {
+				width: 70rpx;
+				display: block;
+				margin-top: 15rpx;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.drive-start-text {
+				display: block;
+				text-align: center;
+				color: @fc-22;
+				margin-top: 8rpx;
+				font-size: 28rpx;
+			}
+			.drive-stop-icon {
+				width: 70rpx;
+				display: block;
+				margin-top: 15rpx;
+				margin-left: auto;
+				margin-right: auto;
+
+			}
+			.drive-stop-text {
+				display: block;
+				text-align: center;
+				color: #8B61FD;
+				margin-top: 8rpx;
+				font-size: 28rpx;
+			}
+			.alarm-icon {
+				width: 60rpx;
+				display: block;
+				margin-top: 8px;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.alarm-text {
+				display: block;
+				text-align: center;
+				color: #ff5b5b;
+				margin-top: 18rpx;
+				font-size: 28rpx;
+			}
+		}
+	}
+	.other-container {
+		padding: 30rpx 70rpx;
+		display: flex;
+		justify-content: space-between;
+		border-top: solid 25rpx @bc-4;
+		.item {
+			.location-icon {
+				width: 65rpx;
+				display: block;
+				margin-top: 10px;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.location-text {
+				display: block;
+				text-align: center;
+				color: @fc-13;
+				margin-top: 15rpx;
+				font-size: 28rpx;
+			}
+			.display-icon {
+				width: 65rpx;
+				display: block;
+				margin-top: 10px;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.display-text {
+				display: block;
+				text-align: center;
+				color: @fc-13;
+				margin-top: 15rpx;
+				font-size: 28rpx;
+			}
+			.order-icon {
+				width: 60rpx;
+				display: block;
+				margin-top: 14px;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.order-text {
+				display: block;
+				text-align: center;
+				color: @fc-13;
+				margin-top: 12rpx;
+				font-size: 28rpx;
+			}
+			.service-icon {
+				width: 65rpx;
+				display: block;
+				margin-top: 10px;
+				margin-left: auto;
+				margin-right: auto;
+			}
+			.service-text {
+				display: block;
+				text-align: center;
+				color: @fc-13;
+				margin-top: 15rpx;
+				font-size: 28rpx;
+			}
+		}
+	}
+}
+
+.bottom-container {
+	background-color: #fff;
+	display: flex;
+	justify-content: space-around;
+	margin-top: 10px;
+	.btn {
+		background-color: @btnc-2;
+		color: @fc-13;
+		font-size: 30rpx;
+		padding: 0rpx 40rpx;
+		line-height: 48px;
+		border-radius: 10rpx;
+		border: solid 1rpx @bc-1;
+		display: flex;
+		.btn-icon-1 {
+			width: 38rpx;
+			margin-top: 24rpx;
+			margin-right: 10rpx;
+		}
+		.btn-icon-2 {
+			width: 36rpx;
+			margin-top: 30rpx;
+			margin-right: 10rpx;
+		}
+		&:active {
+			background-color: @btnac-2;
+		}
+	}
+	.primary {
+		background-color: @btnc-1;
+		color: #fff;
+		padding: 0 65rpx;
+		&::after {
+			border: none;
+		}
+		&:active {
+			background-color: @btnac-1;
+		}
+	}
+}

+ 969 - 0
pages/workbench/workbench.vue

@@ -0,0 +1,969 @@
+<template>
+    <view>
+        <view class="review-container" v-show="reviewAuth">
+            <image src="../../static/workbench/review.png" mode="widthFix"></image>
+            <view class="title">您的实名资料正在审核中</view>
+            <view class="desc">这期间您将无法接单,请等待资料审核通过</view>
+        </view>
+        <view v-show="!reviewAuth">
+            <view class="top-container">
+                <view class="notice">今日数据:凌晨00:00 ~ 本日23:59</view>
+                <view class="summary-container">
+                    <view class="item">
+                        <view class="title">代驾时长</view>
+                        <view class="value">
+                            <text class="number">{{ hour }}</text>
+                            <text class="unit">时</text>
+                        </view>
+                    </view>
+                    <view class="item">
+                        <view class="title">今日收入</view>
+                        <view class="value">
+                            <text class="number">{{ income }}</text>
+                            <text class="unit">元</text>
+                        </view>
+                    </view>
+                    <view class="item">
+                        <view class="title">今日成单</view>
+                        <view class="value">
+                            <text class="number">{{ orders }}</text>
+                            <text class="unit">单</text>
+                        </view>
+                    </view>
+                </view>
+                <view class="service-container">
+                    <view class="item" :style="service.locationStyle">
+                        <image :src="service.locationIcon" mode="widthFix" class="icon icon-1"></image>
+                        {{ service.locationText }}
+                    </view>
+                    <view class="item" :style="service.messageStyle">
+                        <image :src="service.messageIcon" mode="widthFix" class="icon icon-2"></image>
+                        {{ service.messageText }}
+                    </view>
+                    <view class="item" :style="service.listenStyle" @tap="listenHandle()">
+                        <image :src="service.listenIcon" mode="widthFix" class="icon icon-3"></image>
+                        {{ service.listenText }}
+                    </view>
+                    <view class="item" :style="service.settingStyle" @tap="settingHandle()">
+                        <image :src="service.settingIcon" mode="widthFix" class="icon icon-4"></image>
+                        {{ service.settingText }}
+                    </view>
+                </view>
+            </view>
+            <view v-show="workStatus == '停止接单'">
+                <map id="map" :longitude="longitude" :latitude="latitude" scale="15" :style="contentStyle" :enable-traffic="true" :show-location="true" :enable-poi="true">
+                    <cover-image class="location" src="../../static/workbench/location.png" @tap="returnLocationHandle()"></cover-image>
+                </map>
+            </view>
+            <scroll-view scroll-y="true" :style="contentStyle" v-show="workStatus == '开始接单'">
+                <view class="new-order">
+                    <view v-if="newOrder == null">
+                        <image src="../../static/workbench/no-order.png" mode="widthFix" class="no-order-img"></image>
+                        <view class="no-order-title">目前暂无订单</view>
+                    </view>
+                    <view v-if="newOrder != null">
+                        <view class="line-1">
+                            <view>
+                                <view class="sub-time">距离您</view>
+                                <view>
+                                    <text class="number">{{ newOrder.distance }}</text>
+                                    <text class="unit">公里</text>
+                                </view>
+                            </view>
+                            <view>
+                                <view class="sub-time">全程</view>
+                                <view>
+                                    <text class="number">{{ newOrder.mileage }}</text>
+                                    <text class="unit">公里</text>
+                                </view>
+                            </view>
+                            <view>
+                                <view class="tag">含加价{{ newOrder.favourFee }}元</view>
+                                <view>
+                                    <text class="number">{{ newOrder.expectsFee }}</text>
+                                    <text class="unit">元</text>
+                                </view>
+                            </view>
+                        </view>
+                        <view class="line-2">
+                            <view class="from">
+                                <text>{{ newOrder.from }}</text>
+                            </view>
+                            <view class="dashed-line"></view>
+                            <view class="to">
+                                <text>{{ newOrder.to }}</text>
+                            </view>
+                        </view>
+                        <button :class="!canAcceptOrder ? 'disabled-btn' : 'accept-btn'" @tap="acceptHandle">立即抢单</button>
+                    </view>
+                </view>
+                <view class="notice-container">
+                    <view class="title">【 抢单说明 】</view>
+                    <view class="desc">
+                        <text class="num">1.</text>
+                        当前地区可能存在多个代驾订单,但是司机端只能显示其中一条订单。这是为了保障代驾乘客订单的接单率,避免代驾司机只挑选优质订单。
+                    </view>
+                    <view class="desc">
+                        <text class="num">2.</text>
+                        某条订单如果10秒钟之内您没有抢单,系统则认定您主动放弃该订单,系统将为你推送新的订单。
+                    </view>
+                </view>
+            </scroll-view>
+            <scroll-view scroll-y="true" :style="contentStyle" class="execute-order-container" v-show="['接客户', '到达代驾点', '开始代驾'].includes(workStatus)">
+                <view class="call" @tap="callCustomerHandle"></view>
+                <view class="customer-container">
+                    <u-avatar :src="executeOrder.photo" mode="square"></u-avatar>
+                    <view class="info">
+                        <view class="customer-name">代驾客户({{ executeOrder.title }})</view>
+                        <view class="customer-tel">Tel:{{ executeOrder.tel }}</view>
+                    </view>
+                </view>
+                <view class="address-container">
+                    <view class="from">
+                        <text>{{ executeOrder.startPlace }}</text>
+                    </view>
+                    <view class="dashed-line"></view>
+                    <view class="to">
+                        <text>{{ executeOrder.endPlace }}</text>
+                    </view>
+                </view>
+                <view class="order-container">
+                    <view>【 订单号码 】 {{ executeOrder.id }}</view>
+                    <view>【 下单时间 】 {{ executeOrder.createTime }}</view>
+                    <view>【 客户红包 】 {{ executeOrder.favourFee }}元</view>
+                    <view>【 代驾车型 】 {{ executeOrder.carType }}</view>
+                    <view>【 代驾车牌 】 {{ executeOrder.carPlate }}</view>
+                </view>
+                <view class="operate-container">
+                    <view class="item" @tap="cancelOrderHandle">
+                        <image src="../../static/workbench/cancel-icon.png" mode="widthFix" class="cancel-icon"></image>
+                        <text class="cancel-text">取消订单</text>
+                    </view>
+                    <view class="vline"></view>
+                    <view class="item" v-show="workStatus == '接客户'" @tap="arriveStartPlaceHandle">
+                        <image src="../../static/workbench/arrive-start-icon.png" mode="widthFix" class="arrive-start-icon"></image>
+                        <text class="arrive-start-text">到达代驾点</text>
+                    </view>
+                    <view class="item" v-show="workStatus == '到达代驾点'" @tap="startDrivingHandle">
+                        <image src="../../static/workbench/drive-start-icon.png" mode="widthFix" class="drive-start-icon"></image>
+                        <text class="drive-start-text">开始代驾</text>
+                    </view>
+                    <view class="item" v-show="workStatus == '开始代驾'" @tap="endDrivingHandle">
+                        <image src="../../static/workbench/drive-stop-icon.png" mode="widthFix" class="drive-stop-icon"></image>
+                        <text class="drive-stop-text">结束代驾</text>
+                    </view>
+                    <view class="vline"></view>
+                    <view class="item">
+                        <image src="../../static/workbench/alarm-icon.png" mode="widthFix" class="alarm-icon"></image>
+                        <text class="alarm-text">立即报警</text>
+                    </view>
+                </view>
+                <view class="other-container">
+                    <view class="item" @tap="showNavigationHandle">
+                        <image src="../../static/workbench/other-icon-1.png" mode="widthFix" class="location-icon"></image>
+                        <text class="location-text">定位导航</text>
+                    </view>
+                    <view class="item" @tap="showMoveHandle">
+                        <image src="../../static/workbench/other-icon-2.png" mode="widthFix" class="display-icon"></image>
+                        <text class="display-text">司乘同显</text>
+                    </view>
+                    <view class="item" @tap="showOrderHandle">
+                        <image src="../../static/workbench/other-icon-3.png" mode="widthFix" class="order-icon"></image>
+                        <text class="order-text">订单详情</text>
+                    </view>
+                    <view class="item" @tap="callServiceHandle">
+                        <image src="../../static/workbench/other-icon-4.png" mode="widthFix" class="service-icon"></image>
+                        <text class="service-text">客服热线</text>
+                    </view>
+                </view>
+            </scroll-view>
+            <view class="bottom-container" v-show="['开始接单', '停止接单'].includes(workStatus)">
+                <view class="btn" @tap="gohomeHandle()">
+                    <image src="../../static/workbench/btn-icon-1.png" mode="widthFix" class="btn-icon-1"></image>
+                    <text>回家</text>
+                </view>
+                <view class="btn primary">
+                    <text v-show="workStatus == '停止接单'" @tap="startWorkHandle()">开始接单</text>
+                    <text v-show="workStatus == '开始接单'" @tap="stopWorkHandle()">停止接单</text>
+                </view>
+                <view class="btn" @tap="rechargeHandle()">
+                    <image src="../../static/workbench/btn-icon-2.png" mode="widthFix" class="btn-icon-2"></image>
+                    <text>充值</text>
+                </view>
+            </view>
+        </view>
+        <u-top-tips ref="uTips"></u-top-tips>
+        <u-toast ref="uToast" />
+        <u-modal
+            v-model="model.cancelConfirm.show"
+            :title="model.cancelConfirm.title"
+            :content="model.cancelConfirm.content"
+            :show-confirm-button="true"
+            :show-cancel-button="true"
+            @confirm="confirmCancelOrder"
+        ></u-modal>
+        <u-modal
+            v-model="model.cancelSuccess.show"
+            :title="model.cancelSuccess.title"
+            :content="model.cancelSuccess.content"
+            :show-confirm-button="true"
+            :show-cancel-button="false"
+        ></u-modal>
+    </view>
+</template>
+
+<script>
+let QQMapWX = require('../../lib/qqmap-wx-jssdk.min.js');
+let qqmapsdk;
+
+let plugin = requirePlugin('WechatSI');
+let dayjs = require('dayjs');
+export default {
+    data() {
+        return {
+            reviewAuth: uni.getStorageSync('realAuth') == 3,
+            hour: 0,
+            income: 0,
+            orders: 0,
+            map: null,
+            windowHeight: 0,
+            contentStyle: '',
+            latitude: 39.908823,
+            longitude: 116.39747,
+            service: {
+                locationIcon: '../../static/workbench/service-icon-1.png',
+                locationText: '定位正常',
+                locationStyle: '',
+                messageIcon: '../../static/workbench/service-icon-2.png',
+                messageText: '推送正常',
+                messageStyle: '',
+                listenIcon: '../../static/workbench/service-icon-3.png',
+                listenText: '收听订单',
+                listenStyle: '',
+                settingIcon: '../../static/workbench/service-icon-4.png',
+                settingText: '接单设置',
+                settingStyle: ''
+            },
+            settings: {
+                listenService: true,
+                autoAccept: false
+            },
+            workStatus: uni.getStorageSync('workStatus'),
+            newOrder: null,
+            newOrderList: [],
+            executeOrder: {
+                id: '',
+                photo: '',
+                title: '',
+                tel: '',
+                customerId: '',
+                startPlace: '',
+                startPlaceLocation: {},
+                endPlace: '',
+                endPlaceLocation: {},
+                favourFee: '',
+                carPlate: '',
+                carType: '',
+                createTime: ''
+            },
+            reciveNewOrderTimer: null,
+            playFlag: false,
+            audio: null,
+            canAcceptOrder: false,
+            accepting: false,
+            showModel: false,
+            modelTitle: '',
+            modelContent: '',
+            model: {
+                cancelConfirm: {
+                    show: false,
+                    title: '提示消息',
+                    content: '如果不满足订单免费取消规则,只能有偿取消订单,并且可能被禁止接单一段时间,您确认要取消当前订单?'
+                },
+                cancelSuccess: {
+                    show: false,
+                    title: '提示消息',
+                    content: ''
+                }
+            },
+            recordNum: 0,
+            recordManager: null,
+            stopRecord: false
+        };
+    },
+    methods: {
+        changeListenService: function(bool) {
+            if (bool) {
+                this.service.listenIcon = '../../static/workbench/service-icon-3.png';
+                this.service.listenStyle = 'color:#46B68F';
+                this.service.listenText = '收听订单';
+            } else {
+                this.service.listenIcon = '../../static/workbench/service-icon-7.png';
+                this.service.listenStyle = 'color:#FF4D4D';
+                this.service.listenText = '不听订单';
+            }
+        },
+        returnLocationHandle: function() {
+            this.map.moveToLocation();
+        },
+        startWorkHandle: function() {
+            let that = this;
+            /*
+             * TODO 检查司机是否可以接单
+             * 1.没有被禁止接单
+             * 2.没有未缴纳的罚款
+             * 3.当天已经做了人脸验证
+             */
+            //设置司机当天通过身份验证
+            uni.setStorageSync('verification', { result: true, date: dayjs().format('YYYY-MM-DD') });
+
+            uni.showModal({
+                title: '提示消息',
+                content: '你要开始接收代驾订单信息?',
+                success: function(resp) {
+                    if (resp.confirm) {
+                        uni.vibrateShort({});
+                        let audio = uni.createInnerAudioContext();
+                        that.audio = audio;
+                        audio.src = '/static/voice/voice_1.mp3';
+                        audio.play();
+                        that.$refs.uToast.show({
+                            title: '开始接单了',
+                            type: 'success',
+                            callback: function() {
+                                that.ajax(that.url.startWork, 'POST', null, function(resp) {});
+                                uni.setStorageSync('workStatus', '开始接单');
+                                that.workStatus = '开始接单';
+                                //初始化新订单和列表变量
+                                that.newOrder = null;
+                                that.newOrderList.length = 0;
+                                that.executeOrder = {};
+                                //创建接收新订单消息的定时器,每隔5秒钟接收一次新订单消息
+                                if (that.reciveNewOrderTimer == null) {
+                                    that.reciveNewOrderTimer = that.createTimer(that);
+                                }
+                            }
+                        });
+                    }
+                }
+            });
+        },
+        stopWorkHandle: function() {
+            let that = this;
+            uni.showModal({
+                title: '提示消息',
+                content: '你要停止接收代驾订单信息?',
+                success: function(resp) {
+                    if (resp.confirm) {
+                        uni.vibrateShort({});
+                        if (that.audio != null) {
+                            that.audio.stop();
+                        }
+                        let audio = uni.createInnerAudioContext();
+                        that.audio = audio;
+                        audio.src = '/static/voice/voice_2.mp3';
+                        audio.play();
+                        that.$refs.uToast.show({
+                            title: '停止接单了',
+                            type: 'default',
+                            callback: function() {
+                                that.ajax(that.url.stopWork, 'POST', null, function(resp) {});
+                                that.workStatus = '停止接单';
+                                uni.setStorageSync('workStatus', '停止接单');
+                                //初始化新订单和列表变量
+                                that.newOrder = null;
+                                that.newOrderList.length = 0;
+                                that.executeOrder = {};
+                                //销毁接收新订单消息的定时器
+                                clearInterval(that.reciveNewOrderTimer);
+                                that.reciveNewOrderTimer = null;
+                                that.playFlag = false;
+                            }
+                        });
+                    }
+                }
+            });
+        },
+        createTimer: function(ref) {
+            let timer = setInterval(function() {
+                ref.ajax(
+                    ref.url.receiveNewOrderMessage,
+                    'POST',
+                    null,
+                    function(resp) {
+                        let result = resp.data.result;
+                        if (result.length > 0) {
+                            // console.log(result);
+                            ref.newOrderList = result.concat(ref.newOrderList);
+                            if (ref.playFlag == false) {
+                                //调用封装函数
+                                ref.showNewOrder(ref);
+                            }
+                        }
+                    },
+                    false
+                );
+            }, 5000);
+            return timer;
+        },
+        showNewOrder: function(ref) {
+            ref.playFlag = true;
+            ref.canAcceptOrder = false;
+            let order = ref.newOrderList.shift();
+            let orderId = order.orderId;
+            let distance = order.distance;
+            let expectsFee = order.expectsFee;
+            let favourFee = order.favourFee;
+            let from = order.from;
+            let to = order.to;
+            let mileage = order.mileage;
+            let minute = order.minute;
+            ref.newOrder = {
+                orderId: orderId,
+                distance: distance,
+                expectsFee: expectsFee,
+                favourFee: favourFee,
+                from: from,
+                to: to,
+                mileage: mileage,
+                minute: minute
+            };
+            if (ref.settings.listenService) {
+                let audio = uni.createInnerAudioContext();
+                ref.audio = audio;
+                plugin.textToSpeech({
+                    lang: 'zh_CN',
+                    tts: true,
+                    content: `即时订单,距离您${distance}公里,从${from},到${to},全程约${mileage}公里,预估代驾费${expectsFee}元`,
+                    success: function(resp) {
+                        audio.src = resp.filename;
+                        audio.play();
+                        audio.onEnded(function() {
+                            ref.canAcceptOrder = true;
+                            let verification = uni.getStorageSync('verification');
+                            /*
+                             * TODO 判断人脸识别凭证是否过期,如果过期就要重新人脸验证。
+                             * 这是以防司机今天开始接单人脸验证通过,但是一直没有停止接单,
+                             * 到了次日依然要重新做人脸验证。
+                             *
+                             */
+                            if (false) {
+                            } else {
+                                if (ref.settings.autoAccept) {
+                                    let data = {
+                                        orderId: orderId
+                                    };
+                                    ref.ajax(
+                                        ref.url.acceptNewOrder,
+                                        'POST',
+                                        data,
+                                        function(resp) {
+                                            let result = resp.data.result;
+                                            if (result == '接单成功') {
+                                                uni.showToast({
+                                                    title: '接单成功'
+                                                });
+                                                audio = uni.createInnerAudioContext();
+                                                ref.audio = audio;
+                                                audio.src = '/static/voice/voice_3.mp3';
+                                                audio.play();
+                                                audio.onEnded(function() {
+                                                    ref.ajax(ref.url.stopWork, 'POST', null, function(resp) {});
+                                                    //初始化新订单和列表变量
+                                                    ref.newOrder = null;
+                                                    ref.newOrderList.length = 0;
+                                                    ref.executeOrder.id = orderId;
+                                                    clearInterval(ref.reciveNewOrderTimer);
+                                                    ref.reciveNewOrderTimer = null;
+                                                    ref.playFlag = false;
+                                                    //隐藏了工作台页面底部操作条之后,需要重新计算订单执行View的高度
+                                                    ref.contentStyle = `width: 750rpx;height:${ref.windowHeight - 200 - 0}px;`;
+                                                    //加载订单执行数据
+                                                    ref.loadExecuteOrder(ref);
+                                                });
+                                            } else {
+                                                //自动抢单失败
+                                                audio = uni.createInnerAudioContext();
+                                                ref.audio = audio;
+                                                audio.src = '/static/voice/voice_4.mp3';
+                                                audio.play();
+                                                audio.onEnded(function() {
+                                                    ref.playFlag = false;
+                                                    if (ref.newOrderList.length > 0) {
+                                                        ref.showNewOrder(ref);
+                                                    } else {
+                                                        ref.newOrder = null;
+                                                    }
+                                                });
+                                            }
+                                        },
+                                        false
+                                    );
+                                } else {
+                                    ref.playFlag = false;
+                                    setTimeout(function() {
+                                        //如果用户不是正在手动抢单中,就播放下一个新订单
+                                        if (!ref.accepting) {
+                                            ref.canAcceptOrder = false;
+                                            if (ref.newOrderList.length > 0) {
+                                                ref.showNewOrder(ref); //递归调用
+                                            } else {
+                                                ref.newOrder = null;
+                                            }
+                                        }
+                                    }, 3000);
+                                }
+                            }
+                        });
+                    },
+                    fail: function(resp) {
+                        console.error('语音订单播报失败', resp);
+                        ref.playFlag = false;
+                        ref.canAcceptOrder = true;
+                        ref.acception = false;
+                    }
+                });
+            }
+        },
+        acceptHandle: function() {
+            let that = this;
+            if (!that.canAcceptOrder || that.accepting) {
+                return;
+            }
+            that.accepting = true;
+            uni.vibrateShort({});
+            that.ajax(that.url.acceptNewOrder, 'POST', { orderId: that.newOrder.orderId }, function(resp) {
+                let audio = uni.createInnerAudioContext();
+                let result = resp.data.result;
+                //手动抢单成功
+                if (result == '接单成功') {
+                    uni.showToast({
+                        title: '接单成功'
+                    });
+                    that.audio = audio;
+                    audio.src = '/static/voice/voice_3.mp3';
+                    audio.play();
+                    audio.onEnded(function() {
+                        //停止接单
+                        that.audio = null;
+                        that.ajax(that.url.stopWork, 'POST', null, function(resp) {});
+                        //初始化新订单和列表变量
+                        that.executeOrder.id = that.newOrder.orderId;
+                        that.newOrder = null;
+                        that.newOrderList.length = 0;
+                        clearInterval(that.reciveNewOrderTimer);
+                        that.reciveNewOrderTimer = null;
+                        that.playFlag = false;
+                        that.accepting = false;
+                        that.canAcceptOrder = false;
+                        //隐藏了工作台页面底部操作条之后,需要重新计算订单执行View的高度
+                        that.contentStyle = `width: 750rpx;height:${that.windowHeight - 200 - 0}px;`;
+                        //加载订单执行数据
+                        that.loadExecuteOrder(that);
+                    });
+                } else {
+                    that.audio = audio;
+                    audio.src = '/static/voice/voice_4.mp3';
+                    audio.play();
+                    that.playFlag = false;
+                    setTimeout(function() {
+                        that.accepting = false;
+                        that.canAcceptOrder = false;
+                        if (that.newOrderList.length > 0) {
+                            that.showNewOrder(that); //递归调用
+                        } else {
+                            that.newOrder = null;
+                        }
+                    }, 3000);
+                }
+            });
+        },
+        loadExecuteOrder: function(ref) {
+            let data = {
+                orderId: ref.executeOrder.id
+            };
+            ref.ajax(ref.url.searchDriverExecuteOrder, 'POST', data, function(resp) {
+                let result = resp.data.result;
+                ref.executeOrder = {
+                    id: ref.executeOrder.id,
+                    photo: result.photo,
+                    title: result.title,
+                    tel: result.tel,
+                    customerId: result.customerId,
+                    startPlace: result.startPlace,
+                    startPlaceLocation: JSON.parse(result.startPlaceLocation),
+                    endPlace: result.endPlace,
+                    endPlaceLocation: JSON.parse(result.endPlaceLocation),
+                    favourFee: result.favourFee,
+                    carPlate: result.carPlate,
+                    carType: result.carType,
+                    createTime: result.createTime
+                };
+                ref.workStatus = '接客户';
+                uni.setStorageSync('workStatus', '接客户');
+                uni.setStorageSync('executeOrder', ref.executeOrder);
+            });
+        },
+        callCustomerHandle: function() {
+            let that = this;
+            uni.makePhoneCall({
+                phoneNumber: that.executeOrder.tel
+            });
+        },
+        callServiceHandle: function() {
+            let that = this;
+            uni.makePhoneCall({
+                phoneNumber: '10086'
+            });
+        },
+        showMoveHandle: function() {
+            let that = this;
+            uni.navigateTo({
+                url: '../../execution/move/move?orderId=' + that.executeOrder.id
+            });
+        },
+        arriveStartPlaceHandle: function() {
+            let that = this;
+            uni.showModal({
+                title: '消息通知',
+                content: '确认已经到达了代驾点?',
+                success: function(resp) {
+                    if (resp.confirm) {
+                        // qqmapsdk.calculateDistance({
+                        //     mode: 'straight',
+                        //     from: {
+                        //         latitude: that.latitude,
+                        //         longitude: that.longitude
+                        //     },
+                        //     to: [
+                        //         {
+                        //             latitude: that.executeOrder.startPlaceLocation.latitude,
+                        //             longitude: that.executeOrder.startPlaceLocation.longitude
+                        //         }
+                        //     ],
+                        //     success: function(resp) {
+                        //         let distance = resp.result.elements[0].distance;
+                        //         if (distance <= 1000) {
+                                    let data = {
+                                        orderId: that.executeOrder.id,
+                                        customerId: that.executeOrder.customerId
+                                    };
+                                    that.ajax(that.url.arriveStartPlace, 'POST', data, function(resp) {
+                                        if (resp.data.rows == 1) {
+                                            uni.showToast({
+                                                icon: 'success',
+                                                title: '订单状态更新成功'
+                                            });
+                                            that.workStatus = '到达代驾点';
+                                            uni.setStorageSync('workStatus', '到达代驾点');
+                                        }
+                                    });
+                        //         } else {
+                        //             uni.showToast({
+                        //                 icon: 'none',
+                        //                 title: '请移动到距离代驾起点1公里以内'
+                        //             });
+                        //         }
+                        //     },
+                        //     fail: function(error) {
+                        //         console.log(error);
+                        //     }
+                        // });
+                    }
+                }
+            });
+        },
+        startDrivingHandle: function() {
+            let that = this;
+            uni.showModal({
+                title: '消息通知',
+                content: '您已经接到客户,现在开始代驾?',
+                success: function(resp) {
+                    if (resp.confirm) {
+                        //设置录音标志位
+                        that.stopRecord = false;
+                        let data = {
+                            orderId: that.executeOrder.id,
+                            customerId: that.executeOrder.customerId
+                        };
+                        that.ajax(that.url.startDriving, 'POST', data, function(resp) {
+                            if (resp.data.rows == 1) {
+                                uni.showToast({
+                                    icon: 'success',
+                                    title: '订单状态更新成功'
+                                });
+                                that.workStatus = '开始代驾';
+                                uni.setStorageSync('workStatus', '开始代驾');
+                                //开始录音
+                                that.recordManager.start({ duration: 20 * 1000, lang: 'zh_CN' });
+                            }
+                        });
+                    }
+                }
+            });
+        },
+        endDrivingHandle: function() {
+            let that = this;
+            uni.showModal({
+                title: '消息通知',
+                content: '已经到达终点,现在结束代驾?',
+                success: function(resp) {
+                    if (resp.confirm) {
+                        // qqmapsdk.calculateDistance({
+                        //     mode: 'straight',
+                        //     from: {
+                        //         latitude: that.latitude,
+                        //         longitude: that.longitude
+                        //     },
+                        //     to: [
+                        //         {
+                        //             latitude: that.executeOrder.endPlaceLocation.latitude,
+                        //             longitude: that.executeOrder.endPlaceLocation.longitude
+                        //         }
+                        //     ],
+                        //     success: function(resp) {
+                        //         let distance = resp.result.elements[0].distance;
+                        //         if (distance <= 2000) {
+                                    let data = {
+                                        orderId: that.executeOrder.id,
+                                        customerId: that.executeOrder.customerId,
+                                        status: 5
+                                    };
+                                    that.ajax(that.url.updateOrderStatus, 'POST', data, function(resp) {
+                                        that.stopRecord = true;
+                                        try {
+                                            that.recordManager.stop();
+                                            that.recordNum = 0;
+                                            that.stopRecord = false;
+                                            that.workStatus = '结束代驾';
+                                            uni.setStorageSync('workStatus', '结束代驾');
+                                            uni.navigateTo({
+                                                url: '../../order/enter_fee/enter_fee?orderId=' + that.executeOrder.id + '&customerId=' + that.executeOrder.customerId
+                                            });
+                                        } catch (e) {
+                                            console.error(e);
+                                        }
+                                    });
+                        //         } else {
+                        //             uni.showToast({
+                        //                 icon: 'none',
+                        //                 title: '请移动到距离代驾终点2公里以内'
+                        //             });
+                        //         }
+                        //     },
+                        //     fail: function(error) {
+                        //         console.log(error);
+                        //     }
+                        // });
+                    }
+                }
+            });
+        },
+        showNavigationHandle: function() {
+            let that = this;
+            let latitude = null;
+            let longitude = null;
+            let destination = null;
+            if (that.workStatus == '接客户') {
+                latitude = Number(that.executeOrder.startPlaceLocation.latitude);
+                longitude = Number(that.executeOrder.startPlaceLocation.longitude);
+                destination = that.executeOrder.startPlace;
+            } else {
+                latitude = Number(that.executeOrder.endPlaceLocation.latitude);
+                longitude = Number(that.executeOrder.endPlaceLocation.longitude);
+                destination = that.executeOrder.endPlace;
+            }
+            //打开手机导航软件
+            that.map.openMapApp({
+                latitude: latitude,
+                longitude: longitude,
+                destination: destination
+            });
+        },
+        showNavigationHandle: function() {
+            let that = this;
+            let latitude = null;
+            let longitude = null;
+            let destination = null;
+            if (that.workStatus == '接客户') {
+                latitude = Number(that.executeOrder.startPlaceLocation.latitude);
+                longitude = Number(that.executeOrder.startPlaceLocation.longitude);
+                destination = that.executeOrder.startPlace;
+            } else {
+                latitude = Number(that.executeOrder.endPlaceLocation.latitude);
+                longitude = Number(that.executeOrder.endPlaceLocation.longitude);
+                destination = that.executeOrder.endPlace;
+            }
+            that.map.openMapApp({
+                latitude: latitude,
+                longitude: longitude,
+                destination: destination
+            });
+        }
+    },
+    onLoad: function() {
+        let that = this;
+        //新添加----------------------------------------------
+        qqmapsdk = new QQMapWX({
+            key: that.tencent.map.key
+        });
+        //---------------------------------------------------
+        if (!that.reviewAuth) {
+            let windowHeight = uni.getSystemInfoSync().windowHeight;
+            that.windowHeight = windowHeight;
+            let recordManager = plugin.getRecordRecognitionManager(); //初始化录音管理器
+
+            recordManager.onStop = function(resp) {
+                if (that.workStatus == '开始代驾' && that.stopRecord == false) {
+                    that.recordManager.start({ duration: 20 * 1000, lang: 'zh_CN' });
+                }
+
+                let tempFilePath = resp.tempFilePath;
+                //上传录音
+                that.recordNum += 1;
+                let data = {
+                    name: `${that.executeOrder.id}-${that.recordNum}.mp3`,
+                    text: resp.result
+                };
+                // console.log(data);
+                that.upload(that.url.uploadRecordFile, tempFilePath, data, function(resp) {
+                    console.log('录音上传成功');
+                });
+            };
+            recordManager.onStart = function(resp) {
+                console.log('成功开始录音识别');
+                if (that.recordNum == 0) {
+                    uni.vibrateLong({
+                        complete: function() {}
+                    });
+                    uni.showToast({
+                        icon: 'none',
+                        title: '请提示客户系上安全带!'
+                    });
+                }
+            };
+            recordManager.onError = function(resp) {
+                console.error('录音识别故障', resp.msg);
+            };
+
+            that.recordManager = recordManager;
+        }
+        //查询正在执行的订单
+        that.ajax(
+            that.url.searchDriverCurrentOrder,
+            'POST',
+            null,
+            function(resp) {
+                if (resp.data.hasOwnProperty('result')) {
+                    let result = resp.data.result;
+                    that.executeOrder = {
+                        id: result.id,
+                        photo: result.photo,
+                        title: result.title,
+                        tel: result.tel,
+                        customerId: result.customerId,
+                        startPlace: result.startPlace,
+                        startPlaceLocation: JSON.parse(result.startPlaceLocation),
+                        endPlace: result.endPlace,
+                        endPlaceLocation: JSON.parse(result.endPlaceLocation),
+                        favourFee: result.favourFee,
+                        carPlate: result.carPlate,
+                        carType: result.carType,
+                        createTime: result.createTime
+                    };
+                    let map = {
+                        '2': '接客户',
+                        '3': '到达代驾点',
+                        '4': '开始代驾'
+                    };
+                    that.contentStyle = `width: 750rpx;height:${that.windowHeight - 200 - 0}px;`;
+                    that.workStatus = map[result.status + ''];
+                    uni.setStorageSync('workStatus', that.workStatus);
+                    uni.setStorageSync('executeOrder', that.executeOrder);
+                    // console.log(that.workStatus);
+                    if (that.workStatus == '开始代驾') {
+                        that.recordManager.start({ duration: 20 * 1000, lang: 'zh_CN' });
+                    }
+                }
+            },
+            false
+        );
+
+        //初始化地图
+        that.map = uni.createMapContext('map');
+    },
+    onShow: function() {
+        let that = this;
+
+        //TODO 定时刷新消息
+
+        //TODO 更新消息服务状态,可用或者不可用
+
+        if (!that.reviewAuth) {
+            //查询控制台数据
+            that.ajax(that.url.searchWorkbenchData, 'POST', null, function(resp) {
+                let result = resp.data.result;
+                that.hour = result.business.duration;
+                that.income = result.business.income;
+                that.orders = result.business.orders;
+
+                let settings = result.settings;
+                uni.setStorageSync('settings', settings);
+                that.settings.listenService = settings.listenService;
+                that.settings.autoAccept = settings.autoAccept;
+                that.changeListenService(that.settings.listenService);
+            });
+
+            //实时获取定位
+            uni.$on('updateLocation', function(location) {
+                // console.log(location)
+                if (location != null) {
+                    that.service.locationIcon = '../../static/workbench/service-icon-1.png';
+                    that.service.locationText = '定位正常';
+                    that.service.locationStyle = 'color:#46B68F';
+                    that.latitude = location.latitude;
+                    that.longitude = location.longitude;
+                } else {
+                    that.service.locationIcon = '../../static/workbench/service-icon-5.png';
+                    that.service.locationText = '定位失败';
+                    that.service.locationStyle = 'color:#FF4D4D';
+                }
+            });
+
+            let workStatus = uni.getStorageSync('workStatus');
+
+            //判断工作状态,是否定时轮询接单
+            if (workStatus == '开始接单') {
+                that.newOrder = null;
+                that.newOrderList.length = 0;
+                that.playFlag = false;
+                //创建接收新订单消息的定时器,每隔5秒钟接收一次新订单消息
+                that.reciveNewOrderTimer = that.createTimer(that);
+            }
+
+            //初始化控件高度
+            if (['接客户', '到达代驾点', '开始代驾'].includes(workStatus)) {
+                that.contentStyle = `width: 750rpx;height:${that.windowHeight - 200 - 0}px;`;
+            } else {
+                that.contentStyle = `width: 750rpx;height:${that.windowHeight - 200 - 70}px;`;
+            }
+        }
+    },
+    onHide: function() {
+        uni.$off('updateLocation');
+        this.newOrder = null;
+        this.newOrderList.length = 0;
+        if (this.audio != null) {
+            this.audio.stop();
+            this.audio = null;
+        }
+        clearInterval(this.reciveNewOrderTimer);
+        this.reciveNewOrderTimer = null;
+        this.playFlag = false;
+    }
+};
+</script>
+
+<style lang="less">
+@import url('workbench.less');
+</style>

+ 83 - 0
rule/bill_rule/bill_rule.less

@@ -0,0 +1,83 @@
+@import url("../../style.less");
+page{
+	font-family: @ff-1;
+}
+.page {
+	padding: 50rpx 40rpx 70rpx 40rpx;
+}
+.title {
+	font-size: 38rpx;
+	color: @fc-1;
+	text-align: center;
+}
+.section {
+	margin-top: 40rpx;
+	.section-title {
+		display: flex;
+		color: @fc-3;
+		font-size: 32rpx;
+		margin-bottom: 30rpx;
+		&::before {
+			content: '';
+			display: block;
+			height: 0;
+			flex-grow: 1;
+			border-bottom: 1rpx solid @bc-5;
+			margin-right: 25rpx;
+			margin-top: 24rpx;
+		}
+		&::after {
+			content: '';
+			display: block;
+			height: 0;
+			flex-grow: 1;
+			border-bottom: 1rpx solid @bc-5;
+			margin-left: 25rpx;
+			margin-top: 24rpx;
+		}
+	}
+	.item {
+		display: flex;
+		font-size: 32rpx;
+		color: @fc-1;
+		line-height: 1;
+		margin-top: 40rpx;
+		margin-bottom: 20rpx;
+		justify-content: space-between;
+		.left {
+			display: flex;
+			&::before {
+				content: '';
+				display: block;
+				width: 10rpx;
+				height: 32rpx;
+				background-color: @fc-13;
+				margin-right: 15rpx;
+				border-radius: 3rpx;
+			}
+		}
+	}
+	.row {
+		display: flex;
+		justify-content: space-between;
+		padding-left: 25rpx;
+		padding-top: 10rpx;
+		padding-bottom: 10rpx;
+		.label {
+			color: @fc-3;
+			font-size: 28rpx;
+		}
+		.value {
+			color: @fc-3;
+			font-size: 28rpx;
+		}
+	}
+	.desc {
+		font-size: 28rpx;
+		color: @fc-3;
+		line-height: 1.7;
+		padding-left: 25rpx;
+		padding-top: 10rpx;
+		padding-bottom: 10rpx;
+	}
+}

+ 70 - 0
rule/bill_rule/bill_rule.vue

@@ -0,0 +1,70 @@
+<template>
+	<view class="page">
+		<view class="title">大连市</view>
+		<view class="section">
+			<view class="section-title">代驾基础费</view>
+			<view class="item"><text class="left">起步价(分时段)</text></view>
+			<view class="row">
+				<text class="label">06:00 ~ 21:59</text>
+				<text class="value">35元/含8公里</text>
+			</view>
+			<view class="row">
+				<text class="label">22:00 ~ 22:59</text>
+				<text class="value">50元/含8公里</text>
+			</view>
+			<view class="row">
+				<text class="label">23:00 ~ 23:59</text>
+				<text class="value">65元/含8公里</text>
+			</view>
+			<view class="row">
+				<text class="label">00:00 ~ 05:59</text>
+				<text class="value">85元/含8公里</text>
+			</view>
+			<view class="item">
+				<text class="left">里程费</text>
+				<text class="right">5元/公里</text>
+			</view>
+			<view class="desc">超过起步里程后开始计算。所有计费单位都按整数计算,如0.1公里记为1公里,1.1分钟记为2分钟。</view>
+			<view class="item">
+				<text class="left">等候费</text>
+				<text class="right">1元/分钟</text>
+			</view>
+			<view class="desc">代驾司机到达后可以免费等待顾客10分钟,超过后每分钟收取1元,代驾司机最多等待顾客190分钟(包含等待时间)。</view>
+		</view>
+		<view class="section">
+			<view class="section-title">计费规则</view>
+			<view class="desc">收取费用 = 起步价 + 里程费 + 等候费 + 动态加价费 + 附加服务费(各项费用按照实际产生收取,不产生不收取)。</view>
+		</view>
+		<view class="section">
+			<view class="section-title">附加计费</view>
+			<view class="item"><text class="left">动态加价</text></view>
+			<view class="desc">
+				当雨雪天气,周围司机较少或需求过旺的情况下,为了促进承担,鼓励司机更快接单,平台会临时对订单起步价、里程费和等候费适当调价,保障您的出行,调价上限为1.50倍。
+			</view>
+			<view class="desc">代驾过程中产生的路桥费、停车费、住宿费等,由车主承担。</view>
+			<view class="desc">若遇到费用过高或者其他异常情况,需按预估价提前支付该笔代驾费用。服务结束后,根据实际费用多退少补。</view>
+			<view class="item"><text class="left">取消费</text></view>
+			<view class="desc">为了保证平台公平性,因您的责任导致订单取消时,您需支付一定的费用,用于补偿司机的空驶成本</view>
+		</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {};
+	},
+	methods: {},
+	onShow: function() {
+		
+	},
+	onHide: function() {
+		
+	}
+};
+</script>
+
+<style lang="less">
+@import url('bill_rule.less');
+</style>

+ 36 - 0
rule/cancel_rule/cancel_rule.less

@@ -0,0 +1,36 @@
+@import url("../../style.less");
+page{
+	font-family: @ff-1;
+}
+.page {
+	padding: 50rpx 40rpx 70rpx 40rpx;
+}
+.item {
+	display: flex;
+	font-size: 32rpx;
+	color: @fc-1;
+	line-height: 1;
+	margin-top: 40rpx;
+	margin-bottom: 20rpx;
+	&::before {
+		content: '';
+		display: block;
+		width: 10rpx;
+		height: 32rpx;
+		background-color: @fc-13;
+		margin-right: 15rpx;
+		border-radius: 3rpx;
+	}
+}
+.desc {
+	font-size: 28rpx;
+	color: @fc-3;
+	line-height: 1.7;
+	padding-left: 25rpx;
+	padding-top: 10rpx;
+	padding-bottom: 10rpx;
+	display: flex;
+	.num{
+		margin-right: 10rpx;
+	}
+}

+ 40 - 0
rule/cancel_rule/cancel_rule.vue

@@ -0,0 +1,40 @@
+<template>
+	<view class="page">
+		<view class="item">华夏代驾取消费规则</view>
+		<view class="desc">
+			为保证平台公平性,顾客发单后需要取消订单的,应自行及时主动取消订单。乘客无正当理由取消订单,诱导、胁迫司机取消订单,或顾客存在下列清醒导致订单取消的,属于顾客有责消单。
+		</view>
+		<view class="item">乘客有责取消费场景</view>
+		<view class="desc"><text class="num">1.</text>临时无代驾需求;</view>
+		<view class="desc"><text class="num">2.</text>下错单(其他业务需求)、发错单(信息错误)等</view>
+		<view class="desc"><text class="num">3.</text>乘车人数超过车内座位数(包括婴儿在内);</view>
+		<view class="desc"><text class="num">4.</text>携带易燃易爆危险物品或者管制器具;</view>
+		<view class="desc"><text class="num">5.</text>要求线下交易或者议价;</view>
+		<view class="desc"><text class="num">6.</text>上车点或目的地无法到达,但乘客要求必须到达;</view>
+		<view class="desc"><text class="num">7.</text>其他乘客个人原因导致的超时取消;</view>
+		<view class="item">乘客无责消单场景</view>
+		<view class="desc"><text class="num">1.</text>代驾司机诱导消单,如直接要求消单,给出错误信息诱导消单、加价议价导致消单等;</view>
+		<view class="desc"><text class="num">2.</text>因代驾司机自身原因无法正常提供代驾服务导致消单;</view>
+		<view class="desc"><text class="num">3.</text>代驾司机没有主动联系顾客,或者顾客联系不上代驾司机导致消单;</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {};
+	},
+	methods: {},
+	onShow: function() {
+		
+	},
+	onHide: function() {
+		
+	}
+};
+</script>
+
+<style lang="less">
+@import url('cancel_rule.less');
+</style>

+ 4 - 0
rule/user_guide/user_guide.less

@@ -0,0 +1,4 @@
+@import url("../../style.less");
+page{
+	font-family: @ff-1;
+}

+ 31 - 0
rule/user_guide/user_guide.vue

@@ -0,0 +1,31 @@
+<template>
+	<view>
+		<u-cell-group :border="false">
+			<u-cell-item icon="rmb-circle-fill" :icon-style="icon" title="计费规则" :border-top="false" @click="this.toPage('../bill_rule/bill_rule')" />
+			<u-cell-item icon="account-fill" :icon-style="icon" title="用户规则" @click="this.toPage('../user_rule/user_rule')" />
+			<u-cell-item icon="error-circle-fill" :icon-style="icon" title="取消规则" @click="this.toPage('../cancel_rule/cancel_rule')" />
+		</u-cell-group>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			
+		};
+	},
+	methods: {},
+	onShow: function() {
+		
+	},
+	onHide: function() {
+		
+	}
+};
+</script>
+
+<style lang="less">
+@import url('user_guide.less');
+</style>

+ 29 - 0
rule/user_rule/user_rule.less

@@ -0,0 +1,29 @@
+@import url("../../style.less");
+page{
+	font-family: @ff-1;
+}
+.page {
+	padding: 0rpx 40rpx 70rpx 40rpx;
+}
+.title{
+	color: @fc-1;
+	text-align: center;
+	font-size: 38rpx;
+	font-weight: bold;
+	margin-top: 50rpx;
+	margin-bottom: 40rpx;
+	
+}
+.section{
+	color: @fc-1;
+	font-weight: bold;
+	font-size: 32rpx;
+	line-height: 1;
+	margin: 30rpx 0;
+}
+.desc{
+	font-size: 28rpx;
+	color: @fc-3;
+	line-height: 1.7;
+	margin-bottom: 20rpx;
+}

+ 88 - 0
rule/user_rule/user_rule.vue

@@ -0,0 +1,88 @@
+<template>
+	<view class="page">
+		<view class="title">总则</view>
+		<view class="section">规则的目的和任务</view>
+		<view class="desc">本规则基于打击恶意乘客, 维护司机人身财产安全及平台运行秩序的目的,结合平台恶意乘客现象及处理经验,进行制定。</view>
+		<view class="section">适用范围</view>
+		<view class="desc">本规则适用于通过华夏代驾APP、华夏代驾小程序等途径使用华夏代驾功能及服务的全部乘客。</view>
+		<view class="section">基本原则</view>
+		<view class="desc">平等原则:对于任何乘客违规,在规则面前一律平等,任何等级、消费记录等因素均不影响规则的判定。</view>
+		<view class="desc">
+			法律原则
+			:对于乘客在使用滴滴代驾的过程中发生了涉嫌违反国家法律、行政法规、部门规章及相关规则性文件的规定行为的,平台有权对该乘客账号进行管控,本规则已有规定的,适用本规则
+			;本规则尚无规定的,平台有权在合法合理的范围内酌情处理。同时将该案件移至公安机关处理 。
+		</view>
+		<view class="section">处罚形式</view>
+		<view class="desc">限制账号使用 :限制违规人使用华夏代驾发单功能的权利,限制过程中该账号仍可登陆查看账号信息,但无法通过华夏代驾发单并享受代驾服务。</view>
+		<view class="desc">溯及力 :在本规则进行变更时,规则对于行为的溯及力遵循“从旧兼从轻”原则 。</view>
+		<view class="title">分则</view>
+		<view class="section">第一章 损害平台管理秩序</view>
+		<view class="desc">
+			第一节 黑单空号
+			<br />
+			无真实代驾需求的乘客故意频繁发单,并最终订单被取消,影响平台派单秩序的,对乘客账号处以限制使用6个月的处罚。手段恶劣、行为密集或多次触犯的永久封禁乘客账号。
+		</view>
+		<view class="desc">
+			第二节 司乘联合刷单
+			<br />
+			滴滴代驾乘客同滴滴代驾司机串通虚构订单事实以进行虚假交易的,对乘客账号处以限制使用6个月的处罚。
+		</view>
+		<view class="desc">
+			第三节 产品推销
+			<br />
+			无真实代驾需求的乘客在滴滴代驾平台进行发单,向滴滴代驾司机进行商品或服务的推销,并最终订单被取消的,对乘客账号处以限制使用6个月的处罚,其中推销平台不认可的第三方软件的,永久封禁乘客账号。
+		</view>
+		<view class="section">第二章 损害司机人身财产</view>
+		<view class="desc">
+			第一节 恶意差评投诉
+			<br />
+			滴滴代驾乘客未公正客观使用订单评价功能,对代驾服务进行大量频繁恶意差评,或议价无果后投诉滴滴代驾司机,影响司机代驾工作的,对乘客账号处以限制使用30天的处罚。恶意捏造事实对司机进行重大投诉,如恶意投诉司机性骚扰、殴打或其他犯罪行为的,对乘客账号处以限制使用6个月的处罚。手段恶劣、后果严重的,永久封禁乘客账号。
+		</view>
+		<view class="desc">
+			第二节 辱骂殴打司机
+			<br />
+			滴滴代驾乘客在享受代驾服务过程中,故意对滴滴代驾司机进行辱骂或殴打,侵害司机人身安全的,对乘客账号处以限制使用的处罚,辱骂的限制使用30天,殴打的限制使用6个月。情节严重的,永久封禁乘客账号。
+		</view>
+		<view class="desc">
+			第三节 强制结束代驾
+			<br />
+			滴滴代驾乘客在享受代驾服务过程中,无正当理由在高速路、快速路及高架等危险路段强制结束代驾,或在普通路段强制结束代驾并造成严重后果的,永久封禁乘客账号。
+		</view>
+		<view class="desc">
+			第四节 威胁胁迫
+			<br />
+			滴滴代驾乘客在使用滴滴代驾的过程中,故意对滴滴代驾司机进行威胁,向司机提出免单、私人优惠或其他不合理要求,侵害司机应得利益的,对乘客账号处以限制使用30天的处罚,并归还司机损失,否则限制账号使用直至其归还。
+		</view>
+		<view class="desc">
+			第五节 性骚扰
+			<br />
+			滴滴代驾乘客在享受代驾服务过程中,对滴滴代驾司机进行性骚扰行为,对司机人身财产或精神造成伤害的,对乘客账号处限制使用的处罚,言语上骚扰的限制6个月,存在肢体触碰性骚扰的限制12个月。情节严重的,永久封禁乘客账号。
+		</view>
+		<view class="desc">性骚扰指为了满足性方面欲望,违背受害人意志,向受害人实施带性暗示的言语动作的行为,特别是肢体碰触受害者性别特征部位。</view>
+		<view class="desc">
+			第六节 抢劫诈骗
+			<br />
+			滴滴代驾乘客在使用代驾服务过程中,通过隐瞒、欺骗或暴力威胁的手段,对滴滴代驾司机进行抢劫诈骗并造成司机财产损失的,永久封禁乘客账号。
+		</view>
+		<u-top-tips ref="uTips"></u-top-tips>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {};
+	},
+	methods: {},
+	onShow: function() {
+		
+	},
+	onHide: function() {
+		
+	}
+};
+</script>
+
+<style lang="less">
+@import url('user_rule.less');
+</style>

TEMPAT SAMPAH
static/login/top.png


TEMPAT SAMPAH
static/message_list/email-icon-1.png


TEMPAT SAMPAH
static/message_list/email-icon-2.png


TEMPAT SAMPAH
static/mine/icon-1.png


TEMPAT SAMPAH
static/mine/icon-10.png


TEMPAT SAMPAH
static/mine/icon-11.png


TEMPAT SAMPAH
static/mine/icon-2.png


TEMPAT SAMPAH
static/mine/icon-3.png


TEMPAT SAMPAH
static/mine/icon-4.png


TEMPAT SAMPAH
static/mine/icon-5.png


TEMPAT SAMPAH
static/mine/icon-6.png


TEMPAT SAMPAH
static/mine/icon-7.png


TEMPAT SAMPAH
static/mine/icon-8.png


TEMPAT SAMPAH
static/mine/icon-9.png


TEMPAT SAMPAH
static/mine/user.jpg


TEMPAT SAMPAH
static/order_list/calendar-icon.png


TEMPAT SAMPAH
static/register/location.png


TEMPAT SAMPAH
static/register/title-bg.png


TEMPAT SAMPAH
static/register/top.jpg


TEMPAT SAMPAH
static/tab_bar/message_1.png


TEMPAT SAMPAH
static/tab_bar/message_2.png


TEMPAT SAMPAH
static/tab_bar/order_1.png


TEMPAT SAMPAH
static/tab_bar/order_2.png


TEMPAT SAMPAH
static/tab_bar/people_1.png


TEMPAT SAMPAH
static/tab_bar/people_2.png


TEMPAT SAMPAH
static/tab_bar/workbench_1.png


TEMPAT SAMPAH
static/tab_bar/workbench_2.png


TEMPAT SAMPAH
static/voice/voice_1.mp3


TEMPAT SAMPAH
static/voice/voice_2.mp3


TEMPAT SAMPAH
static/voice/voice_3.mp3


TEMPAT SAMPAH
static/voice/voice_4.mp3


TEMPAT SAMPAH
static/voice/voice_5.mp3


TEMPAT SAMPAH
static/workbench/alarm-icon.png


TEMPAT SAMPAH
static/workbench/arrive-start-icon.png


TEMPAT SAMPAH
static/workbench/btn-icon-1.png


TEMPAT SAMPAH
static/workbench/btn-icon-2.png


TEMPAT SAMPAH
static/workbench/call.png


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini