songzhihui 2 rokov pred
rodič
commit
ed09ae1154
100 zmenil súbory, kde vykonal 13449 pridanie a 0 odobranie
  1. 37 0
      App.vue
  2. 37 0
      api/carWash.js
  3. 107 0
      api/maintain.js
  4. 34 0
      api/myApi.js
  5. 66 0
      api/shop.js
  6. 2 0
      assets/iconfont/iconfont.css
  7. 175 0
      components/ActionSheet/index.vue
  8. 243 0
      components/Card.vue
  9. 191 0
      components/Menu.vue
  10. 139 0
      components/SetMeal/index.vue
  11. 138 0
      components/SetMeal/shopGoods.vue
  12. 3 0
      config/index.js
  13. 20 0
      index.html
  14. 55 0
      main.js
  15. 117 0
      manifest.json
  16. 201 0
      node_modules/miniapp-color-thief/LICENSE
  17. 170 0
      node_modules/miniapp-color-thief/README.md
  18. 79 0
      node_modules/miniapp-color-thief/index.js
  19. 37 0
      node_modules/miniapp-color-thief/package.json
  20. 20 0
      node_modules/quantize/LICENSE
  21. 62 0
      node_modules/quantize/README.md
  22. 35 0
      node_modules/quantize/package.json
  23. 490 0
      node_modules/quantize/quantize.js
  24. 43 0
      package-lock.json
  25. 5 0
      package.json
  26. 392 0
      pages.json
  27. 130 0
      pages/home/components/Banner.vue
  28. 108 0
      pages/home/index.vue
  29. 50 0
      pages/maintenance/agreement/agreement.vue
  30. 31 0
      pages/maintenance/evaluate/history/detail.vue
  31. 183 0
      pages/maintenance/evaluate/history/index.vue
  32. 419 0
      pages/maintenance/evaluate/index.vue
  33. 147 0
      pages/maintenance/expensesList/expensesList.vue
  34. 231 0
      pages/maintenance/index.vue
  35. 558 0
      pages/maintenance/maintainOrder/deliveryOfVehicle/index.vue
  36. 181 0
      pages/maintenance/maintainOrder/flow/index.vue
  37. 416 0
      pages/maintenance/maintainOrder/index.vue
  38. 483 0
      pages/maintenance/maintainOrder/orderDetail/index.vue
  39. 863 0
      pages/maintenance/onlineReservation/index.vue
  40. 814 0
      pages/maintenance/servicesAvailable/index.vue
  41. 255 0
      pages/maintenance/setMeal/buySetMeal/index.vue
  42. 167 0
      pages/maintenance/setMeal/index.vue
  43. 535 0
      pages/maintenance/setMeal/setMealDetail/index.vue
  44. 136 0
      pages/preCarWash/chooseCar/index.vue
  45. 272 0
      pages/preCarWash/chooseShop/index.vue
  46. 304 0
      pages/preCarWash/chooseTime/index.vue
  47. 700 0
      pages/preCarWash/index.vue
  48. 182 0
      pages/preCarWash/setMeal/index.vue
  49. 366 0
      pages/preCarWash/washOrder/index.vue
  50. 405 0
      pages/preCarWash/washOrder/orderDetail/index.vue
  51. 339 0
      pages/preCarWash/washOrder/serviceEvaluation/index.vue
  52. 8 0
      pages/shop/CarsClass/index.vue
  53. 8 0
      pages/shop/LeaseCarClass/index.vue
  54. 8 0
      pages/shop/ShoppingMall/index.vue
  55. 375 0
      pages/shop/cashierDesk/cashierDesk.vue
  56. 95 0
      pages/shop/navigation/navigation.vue
  57. 26 0
      pages/shop/shopDetail/ShopInclude/ShopInclude.vue
  58. 935 0
      pages/shop/shopDetail/index.vue
  59. 113 0
      pages/shop/shopDetail/shopPhotoAlbum/index.vue
  60. 8 0
      pages/user/User/index.vue
  61. 217 0
      pages/userMeal/index.vue
  62. 483 0
      pages/userMeal/userMealDetail/index.vue
  63. BIN
      static/1..png
  64. BIN
      static/2..png
  65. BIN
      static/addVideo.png
  66. BIN
      static/address.png
  67. BIN
      static/alipay.png
  68. BIN
      static/back.png
  69. BIN
      static/backw.png
  70. BIN
      static/banjin.png
  71. BIN
      static/banner.png
  72. BIN
      static/baoyang.png
  73. BIN
      static/bg.png
  74. BIN
      static/car.png
  75. BIN
      static/cardbg.png
  76. BIN
      static/chafen.png
  77. BIN
      static/changgui.png
  78. BIN
      static/che.png
  79. BIN
      static/choose.png
  80. BIN
      static/chooseMenu.png
  81. BIN
      static/daohang.png
  82. BIN
      static/delete.png
  83. BIN
      static/dianhua.png
  84. BIN
      static/dianpu.png
  85. BIN
      static/guanzhu.png
  86. BIN
      static/gujia.png
  87. BIN
      static/guohu.png
  88. BIN
      static/half.png
  89. BIN
      static/icon-cart-hot.png
  90. BIN
      static/icon-cart.png
  91. BIN
      static/icon-class-hot.png
  92. BIN
      static/icon-class.png
  93. BIN
      static/icon-fuwu.png
  94. BIN
      static/icon-home-hot.png
  95. BIN
      static/icon-home.png
  96. BIN
      static/icon-user-hot.png
  97. BIN
      static/icon-user.png
  98. BIN
      static/icon-zhibo-hot.png
  99. BIN
      static/icon-zhibo.png
  100. BIN
      static/jiancha.png

+ 37 - 0
App.vue

@@ -0,0 +1,37 @@
+<script>
+	export default {
+		globalData: {
+			longitude: "",
+			latitude: "",
+			requestToken: ""
+		},
+		onLaunch: function() {
+			let _this = this;
+			uni.getLocation({
+				type: 'wgs84',
+				success: function(res) {
+					console.log(res)
+					_this.globalData.longitude = res.longitude;
+					_this.globalData.latitude = res.latitude;
+				},
+				fail: function() {
+					uni.showToast({
+						title: '获取地址失败,将导致部分功能不可用',
+						icon: 'none'
+					});
+				}
+			});
+		},
+		onShow: function() {
+			console.log('App Show')
+		},
+		onHide: function() {
+			console.log('App Hide')
+		}
+	}
+</script>
+
+<style>
+	/*每个页面公共css */
+	@import './assets/iconfont/iconfont.css';
+</style>

+ 37 - 0
api/carWash.js

@@ -0,0 +1,37 @@
+import request from "@/utils/request";
+/**
+ * 预约洗车-洗车类型
+ */
+export function getByTypeCode(data) {
+  return request.post("/api/common/getByTypeCode", data, { login: true });
+}
+/**
+ * 预约洗车-默认价格
+ */
+export function getDefaultPrice(data) {
+  return request.get("/api/shop/defaultPrice", data, { login: true });
+}
+/**
+ * 预约洗车-可用套餐列表
+ */
+export function getMyPackage(data) {
+  return request.get("/api/userPackage/myPackage", data, { login: true });
+}
+/**
+ * 预约洗车-立即预约
+ */
+export function carwashOrder(data) {
+  return request.post("/api/carwashOrder/washOrder", data, { login: true });
+}
+/**
+ * 预约洗车-订单列表
+ */
+export function carwashOrderList(data) {
+  return request.post("/api/carwashOrder/list", data, { login: true,loading:true });
+}
+/**
+ * 预约洗车-订单详情
+ */
+export function carwashOrderDetail(data) {
+  return request.post("/api/carwashOrder/detail", data, { login: true,loading:true });
+}

+ 107 - 0
api/maintain.js

@@ -0,0 +1,107 @@
+import request from "@/utils/request";
+
+/**
+ * 维修估价-新增
+
+ */
+export function setEvaluationAdd(data) {
+  return request.post("/api/repairEvaluation/add", data, { login: true });
+}
+/**
+ * 维修估价-历史记录
+ */
+export function getEvaluationList(data) {
+  return request.post("/api/repairEvaluation/list", data, { login: true,loading:true });
+}
+/**
+ * 维修估价-详情
+ */
+export function getEvaluationDetail(data) {
+  return request.post("/api/repairEvaluation/detail", data, { login: true });
+}
+/**
+ * 维修估价-获取服务data
+ */
+export function getShopServiceOne(data) {
+  return request.post("/api/shopServiceOne/list", data, { login: true });
+}
+/**
+ * 维修估价-首页服务
+ */
+export function getRepairServiceOne(data) {
+  return request.post("/api/repairServiceOne/list", data, { login: true });
+}
+/**
+ * 维修估价-新增订单
+ */
+export function repairOrderAdd(data) {
+  return request.post("/api/repairOrder/add", data, { login: true });
+}
+/**
+ * 维修估价-订单列表
+ */
+export function repairOrderList(data) {
+  return request.post("/api/repairOrder/list", data, { login: true,loading:true });
+}
+/**
+ * 维修估价-取消维保订单
+ */
+export function cancelOrder(data) {
+  return request.post("/api/repairOrder/cancelOrder", data, { login: true });
+}
+/**
+ * 维修估价-订单评价
+ */
+export function orderEvaluate(data) {
+  return request.post("/api/orderEvaluate/add", data, { login: true });
+}
+/**
+ * 维修估价-提交提车信息
+ */
+export function repairGetCar(data) {
+  return request.post("/api/repairGetCar/add", data, { login: true });
+}
+/**
+ * 维修估价-订单详情
+ */
+export function orderDetail(data) {
+  return request.post("/api/repairOrder/detail", data, { login: true });
+}
+/**
+ * 维修估价-流程明显
+ */
+export function logList(data) {
+  return request.post("/api/repairOrder/logList", data, { login: true });
+}
+/**
+ * 维修估价-套餐列表
+ */
+export function packageList(data) {
+  return request.post("/api/package/list", data, { login: true });
+}
+/**
+ * 维修估价-套餐详情
+ */
+export function packageDetail(data) {
+  return request.post("/api/package/detail", data, { login: true });
+}
+/**
+ * 维修估价-购买套餐
+ */
+export function packageBuy(data) {
+  return request.post("/api/package/buy", data, { login: true });
+}
+
+/**
+ * 维修保养支付
+ */
+export function payOrder(data){
+	return request.post("/api/repairOrder/payOrder",data,{login:true})
+}
+
+/**
+ * 资源详情
+ */
+export function agreement(data){
+	return request.post("/api/resource/detail",data,{login:true})
+}

+ 34 - 0
api/myApi.js

@@ -0,0 +1,34 @@
+import request from "@/utils/request";
+
+/**
+ * 我的套餐-列表
+
+ */
+export function userPackageList(data) {
+  return request.post("/api/userPackage/List", data, { login: true });
+}
+
+export function userPackageDefail(data) {
+	return request.post("/api/userPackage/detail", data, { login: true });
+}
+
+/**
+ * 我的套餐-下单
+ */
+export function buyPackage(data) {
+	return request.post("/api/package/buyPackage",data,{login: true})
+}
+
+/**
+ * 收藏
+ */
+export function saveShop(data) {
+	return request.post("/api/collection/save",data,{login:true})
+}
+
+/**
+ * 获取用户信息
+ */
+export function getUserInfo() {
+	return request.post("/api/user/detail",{}, { login: true })
+}

+ 66 - 0
api/shop.js

@@ -0,0 +1,66 @@
+import request from "@/utils/request";
+
+/**
+ * 门店列表
+ */
+export function getSelectStore(data) {
+  return request.post("/api/shop/selectStore", data, { login: true,loading:true });
+}
+/**
+ * 默认车辆
+ */
+export function getUserCar(data) {
+  return request.get("/api/userCar/defaultCar", data, { login: true });
+}
+/**
+ * 车辆列表
+ */
+export function getUserCarPage(data) {
+  return request.get("/api/userCar/carPage", data, { login: true,loading:true });
+}
+/**
+ * 获取时间
+ */
+export function getTimeList(data) {
+  return request.get("/api/shop/timeList", data, { login: false });
+}
+/**
+ * 获取省市区
+ */
+export function getRegion(data) {
+  return request.post("/api/sysRegion/getRegion", data, { login: false });
+}
+/**
+ * 店铺详情
+ */
+export function shopDetail(data) {
+  return request.post("/api/shop/detail", data, { login: true });
+}
+
+/**
+ * 获取店铺服务
+ */
+export function carwashService(data){
+	return request.get('/api/shop/carwashService',data, { login: true })
+}
+
+/**
+ * 获取店铺评价
+ */
+export function orderEvaluate(data){
+	return request.post('/api/orderEvaluate/list',data, { login: true })
+}
+
+/**
+ * 获取店铺主页商品
+ */
+export function getShopGoods(data){
+	return request.post('/api/package/list',data, { login: true })
+}
+
+/**
+ * 获取店铺介绍
+ */
+export function getInclude(data){
+	return request.post('/api/common/userHFiveUrl',data, { login: true })
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2 - 0
assets/iconfont/iconfont.css


+ 175 - 0
components/ActionSheet/index.vue

@@ -0,0 +1,175 @@
+<template>
+	<view>
+		<view class="actionsheet-class actionsheet" :class="[show?'actionsheet-show':'']">
+			<view class="tips">
+				已选服务
+			</view>
+			<view class="actionsheet-body">
+				<view class="actionsheet-view" v-for="(item, index) in list" :key="index">
+					<view class="actionsheet-left">
+						<view class="title">
+							{{item.chooseName}}
+						</view>
+						<view class="menu" v-if="item.menu">
+							{{item.menu}}
+						</view>
+						<view class="menu" v-else>
+							个人套餐
+						</view>
+					</view>
+					<image class="actionsheet-img" @click="deleteChoose(item)" :src="require('../../static/delete.png')"></image>
+				</view>
+				<view style="height: 200rpx;"></view>
+			</view>
+
+		</view>
+		<view class="actionsheet-mask" :class="[show?'mask-show':'']" @tap="handleClickMask"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "actionsheet",
+		props: {
+			//点击遮罩 是否可关闭
+			maskClosable: {
+				type: Boolean,
+				default: true
+			},
+			//显示操作菜单
+			show: {
+				type: Boolean,
+				default: false
+			},
+			list: {
+				type: Array
+			},
+		},
+		methods: {
+			handleClickMask() {
+				if (!this.maskClosable) return;
+				this.handleClickCancel();
+			},
+			handleClickItem(e) {
+				if (!this.show) return;
+				const dataset = e.currentTarget.dataset;
+				this.$emit('click', {
+					index: dataset.index
+				});
+			},
+			handleClickCancel() {
+				this.$emit('showAction');
+			},
+			deleteChoose(item) {
+				this.$emit('deleted', item);
+			}
+		}
+	}
+</script>
+
+<style>
+	.actionsheet {
+		width: 100%;
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 9997;
+		visibility: hidden;
+		-webkit-transform: translate3d(0, 100%, 0);
+		transform: translate3d(0, 100%, 0);
+		-webkit-transform-origin: center;
+		transform-origin: center;
+		transition: all 0.3s ease-in-out;
+		background: #FFFFFF;
+		min-height: 100rpx;
+	}
+
+	.actionsheet-show {
+		transform: translate3d(0, 0, 0);
+		visibility: visible;
+	}
+
+	.actionsheet-left {
+		float: left;
+	}
+
+	.tips {
+		width: 100%;
+		padding: 41rpx 36rpx;
+		box-sizing: border-box;
+		text-align: center;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		/* justify-content: center; */
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #333333;
+		line-height: 36rpx;
+	}
+
+	.actionsheet-body {
+		overflow-y: auto;
+		height: 917rpx;
+	}
+
+	.actionsheet-view {
+		width: 687rpx;
+		min-height: 154rpx;
+		display: flex;
+		border-bottom: 1px solid #E6E6E6;
+		margin-left: 32rpx;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.title {
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 36rpx;
+		padding: 37rpx 35rpx 0 0;
+	}
+
+	.menu {
+		width: 112rpx;
+		height: 34rpx;
+		background: #FFFFFF;
+		border: 1px solid #FF6600;
+		border-radius: 5rpx;
+		font-size: 22rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FF6600;
+		line-height: 36rpx;
+		text-align: center;
+		margin: 15rpx 0 37rpx 0;
+	}
+
+	.actionsheet-img {
+		width: 32rpx;
+		height: 31rpx;
+		float: right;
+	}
+
+	.actionsheet-mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 9996;
+		transition: all 0.3s ease-in-out;
+		opacity: 0;
+		visibility: hidden;
+	}
+
+	.mask-show {
+		opacity: 1;
+		visibility: visible;
+	}
+</style>

+ 243 - 0
components/Card.vue

@@ -0,0 +1,243 @@
+<template>
+	<view class="card-view">
+		<view class="classHead">
+			<view class="classBorder">
+
+			</view>
+			<view class="classTitle">
+				{{titles}}
+			</view>
+		</view>
+		<view class="classBody" @tap="routerTo(titles)">
+			<view style="display: flex;align-items: center;">
+				<view style="display: flex;align-items: center;" v-if="titles=='附近门店' || titles=='服务门店'">
+					<image v-if="data.logoUrl" class="classImg" :src="baseImagePath + data.logoUrl"></image>
+					<image v-else class="classImg" :src="require('../static/moren-mendian.png')"></image>
+				</view>
+				<view style="display: flex;align-items: center;" v-else>
+					<image v-if="data.brandLogo" class="classImg" :src="baseImagePath+data.brandLogo"></image>
+					<image v-else class="classImg" :src="require('../static/morentu.png')"></image>
+				</view>
+				<view style="padding: 0 0 0 30rpx;display: flex;flex-direction: column;"
+					v-if="titles=='附近门店' || titles=='服务门店'">
+					<view v-if="data.name">
+						<view class="classBodyHead">
+							{{data.name}}
+						</view>
+						<view v-if="titles=='服务门店'" class="classBodyContent"
+							style="display: flex;align-items: baseline;">
+							<image class="location" :src="require('../static/address.png')"></image>
+							<view class="locationNum">
+								据您{{data.distance}}km
+							</view>
+						</view>
+						<view v-else-if="titles=='附近门店'" class="classBodyContent">
+							{{data.contacts}}
+						</view>
+					</view>
+					<view v-else style="height: 100%;display: flex;align-items: center;">
+						<view class="chooseView">
+							请选择门店
+						</view>
+					</view>
+
+
+				</view>
+				<view style="padding: 0 0 0 30rpx;" v-else>
+					<view v-if="data.carNumber!=null">
+						<view class="carBodyHead classBodyHead">
+							<view style="display: flex;justify-content: left;">
+								<image class="carImg" :src="require('../static/car.png')"></image>
+							<span>{{data.carNumber}}</span>
+							</view>
+							
+							<view class="vehicleBorder"></view><span>{{data.carMadelLevel}}</span>
+						</view>
+
+						<view class="classBodyContent">
+							{{data.carModelName}}
+						</view>
+					</view>
+					<view v-else style="height: 100%;display: flex;align-items: center;">
+						<view class="chooseView">
+							请选择车辆
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="viewRight">
+				<image class="classChoose" :src="require('../static/choose.png')">
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		components: {},
+		data() {
+			return {
+				categoryCurrent: 0, //分类轮播下标
+				baseImagePath: this.baseImagePath
+			};
+		},
+		props: {
+			data: {
+				type: Object,
+				default: function() {
+					return {};
+				}
+			},
+			titles: {
+				type: String,
+				default: ""
+			},
+			page: {
+				type: String,
+				default: ''
+			}
+		},
+		methods: {
+			// 路由跳转
+			routerTo(item) {
+				console.log(item);
+				console.log('page', this.page);
+				if (item == "附近门店" || item == "服务门店") {
+					this.$yrouter.push({
+						path: "/pages/preCarWash/chooseShop/index?type=" + this.page
+					});
+				} else if (item == "车辆信息" || item == "预约车辆" || item == "使用车辆") {
+
+					this.$yrouter.push({
+						path: "/pages/preCarWash/chooseCar/index?id=" + this.data.id
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	.location {
+		width: 23rpx;
+		height: 23rpx;
+		padding-right: 10rpx;
+	}
+
+	.locationNum {
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #333333;
+		line-height: 31rpx;
+	}
+
+	.card-view {
+		width: 94%;
+		height: 239rpx;
+		margin-left: 3%;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 28rpx;
+	}
+
+	.classHead {
+		display: flex;
+		padding-top: 28rpx;
+		width: 100%;
+		height: 28rpx;
+	}
+
+	.classBorder {
+		width: 5rpx;
+		height: 28rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 3rpx;
+	}
+
+	.classTitle {
+		height: 25rpx;
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		padding-left: 28rpx;
+		line-height: 28rpx;
+	}
+
+	.classBody {
+		display: flex;
+		justify-content: space-between;
+		padding: 28rpx;
+		padding-top: 0rpx;
+		align-items: center;
+		margin-top: 36rpx;
+	}
+
+	.classImg {
+		width: 120rpx;
+		height: 120rpx;
+		/* background: linear-gradient(135deg, #D10498 0%, #D21728 100%); */
+		border-radius: 8rpx;
+	}
+
+	.classBodyHead {
+		height: 31rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 31rpx;
+	}
+
+	.classBodyContent {
+		width: 370rpx;
+		height: 23rpx;
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 31rpx;
+		padding-top: 22rpx;
+	}
+
+	.viewRight {
+		height: 100%;
+		/* line-height: 183rpx;
+		margin-top: -28rpx;
+		margin-left: 100rpx; */
+	}
+
+	.classChoose {
+		width: 15rpx;
+		height: 23rpx;
+	}
+
+	.carBodyHead {
+		display: flex;
+		justify-content: left;
+		align-items: center;
+	}
+
+	.vehicleBorder {
+		width: 1rpx;
+		height: 20rpx;
+		background: #DBDBDB;
+		margin-left: 15rpx;
+		margin-right: 18rpx;
+	}
+
+	.carImg {
+		width: 33rpx;
+		height: 27rpx;
+		margin-right: 13rpx;
+	}
+
+	.chooseView {
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 42rpx;
+	}
+</style>

+ 191 - 0
components/Menu.vue

@@ -0,0 +1,191 @@
+<template>
+	<!-- 产品分类导航 -->
+	<view class="menu-category-box" v-if="carousel">
+		<!-- mb20 -->
+		<!-- :style="list.length <= menu ? `height:200rpx` : `height:360rpx`" -->
+		<swiper class="menu-swiper-box" :style="list.length <= menu ? `height:160rpx` : `height:320rpx`"
+			@change="onSwiper" circular :autoplay="false" :interval="3000" :duration="1000">
+			<swiper-item class="menu-swiper-item" v-for="(itemList, index) in carousel" :key="index"
+				:style="list.length <= menu ? `height:200rpx` : `height:340rpx`">
+				<view class="menu-tab-box">
+					<view v-for="item in itemList">
+						<view class="tab-list y-f" :style="{ width: 710 / menu + 'rpx' }" :key="item.name"
+							@tap="routerTo(item)">
+							<image class="tab-img Shop-selector-circular"
+								:style="{ width: imgW + 'rpx', height: imgW + 'rpx' }" :src="item.pic"></image>
+							<text class="Shop-selector-rect">{{ item.name }}</text>
+						</view>
+					</view>
+				</view>
+			</swiper-item>
+		</swiper>
+		<view class="menu-category-dots" v-if="carousel.length > 1">
+			<text :class="categoryCurrent === index ? 'category-dot-active' : 'category-dot'"
+				v-for="(dot, index) in carousel.length" :key="index"></text>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		components: {},
+		data() {
+			return {
+				categoryCurrent: 0 //分类轮播下标
+			};
+		},
+		props: {
+			list: {
+				type: Array,
+				default: []
+			},
+			menu: {
+				default: 5
+			},
+			imgW: {
+				type: Number,
+				default: 100
+			}
+		},
+		computed: {
+			carousel() {
+				if (this.list) {
+					let list = this.sortData(this.list, this.menu * 2);
+					return list;
+				}
+			}
+		},
+		created() {},
+		methods: {
+			// 数据分层
+			sortData(oArr, length) {
+				let arr = [];
+				let minArr = [];
+				oArr.forEach(c => {
+					if (minArr.length === length) {
+						minArr = [];
+					}
+					if (minArr.length === 0) {
+						arr.push(minArr);
+					}
+					minArr.push(c);
+				});
+
+				return arr;
+			},
+			// 轮播
+			onSwiper(e) {
+				this.categoryCurrent = e.detail.current;
+			},
+			// 路由跳转
+			routerTo(item) {
+				// const token = "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VySWQiOjE1OTcxNTUzMDAwOTAwODUzNzgsImFjY291bnQiOiIxNTE0MTE1NTQ3NyIsInV1aWQiOiIyYjMxN2MzZC04OGMwLTQxZmEtOTFlNi00YTQ1ZDQxYzUwNGYiLCJyZW1lbWJlck1lIjp0cnVlLCJleHBpcmF0aW9uRGF0ZSI6MTY3ODA5MDE1NDYxMywiY2FUb2tlbiI6bnVsbCwib3RoZXJzIjpudWxsLCJzdWIiOiIxNTk3MTU1MzAwMDkwMDg1Mzc4IiwiaWF0IjoxNjc2MzM3MTIxLCJleHAiOjE2NzgwOTAxNTR9._b6LSaJ6gRKgR0rbwZh61K9F0DKJ4w3OjIo_yb2VfH7ynzX99RPod6MYpFnO0Naehve2AbMHd5vyNKsHkj7Oew"
+
+				if (item.name == "预约洗车") {
+					this.$yrouter.push({ path: "/pages/preCarWash/index" });
+				}else if (item.name == "维修保养") {
+					this.$yrouter.push({ path: "/pages/maintenance/index" });
+					// this.$yrouter.push({ path: "/pages/maintenance/index?token="+token });
+				}else if (item.name == "汽车商城") {
+					this.$yrouter.push({ path: "/pages/preCarWash/washOrder/index" });
+				}else if (item.name == "租车商城") {
+					this.$yrouter.push({ path: "/pages/maintenance/maintainOrder/index" });
+				}else if (item.name == "综合商城") {
+					this.$yrouter.push({ path: "/pages/userMeal/index" });
+				}else if (item.name == "登记过户") {
+					this.$yrouter.push({ path: "/pages/maintenance/onlineReservation/index" });
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	button::after {
+		border: none;
+	}
+
+	button {
+		background-color: #fff;
+	}
+
+	// 产品分类
+	.y-f {
+		display: -webkit-box;
+		display: -webkit-flex;
+		display: flex;
+		-webkit-box-orient: vertical;
+		-webkit-box-direction: normal;
+		-webkit-flex-direction: column;
+		flex-direction: column;
+		-webkit-box-align: center;
+		-webkit-align-items: center;
+		align-items: center;
+	}
+
+	.menu-category-box {
+		// padding: 40rpx 30rpx 0 30rpx;
+		padding: 20rpx 0rpx 0rpx;
+		background: #fff !important;
+		box-sizing: border-box;
+		// border-radius: 10rpx;
+		overflow: hidden;
+	}
+
+	.menu-category-box,
+	.menu-swiper-box {
+		position: relative;
+		background: #fff;
+
+		.menu-swiper-item {
+			background: #fff;
+			height: 100%;
+			width: 100%;
+		}
+
+		.menu-tab-box {
+			display: flex;
+			flex-wrap: wrap;
+			justify-content: space-around;
+
+			.tab-list {
+				font-size: 23rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: rgba(51, 51, 51, 1);
+				padding-bottom: 30rpx;
+				line-height: 30rpx;
+
+				text {
+					width: max-content;
+				}
+
+				.tab-img {
+					border-radius: 25rpx;
+				}
+			}
+		}
+
+		.menu-category-dots {
+			display: flex;
+			position: absolute;
+			left: 50%;
+			transform: translateX(-50%);
+			bottom: 20rpx;
+
+			.category-dot {
+				width: 40rpx;
+				height: 3rpx;
+				background: #eeeeee;
+				margin-right: 10rpx;
+			}
+
+			.category-dot-active {
+				width: 40rpx;
+				height: 3rpx;
+				background: #a8700d;
+				margin-right: 10rpx;
+			}
+		}
+	}
+</style>

+ 139 - 0
components/SetMeal/index.vue

@@ -0,0 +1,139 @@
+<template>
+	<view class="body">
+		<view class="card" v-for="(item, index) in setMealList" :key="index" @tap="routerTo(item)">
+			<image :src="'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/'+item.imgUrl"></image>
+			<view class="title">
+				{{item.name}}
+			</view>
+			<view class="content">
+				{{item.title}}
+			</view>
+			<view class="bottomView">
+				<view class="priceView">
+					<view class="unit">
+						¥
+					</view>
+					<view class="price">
+						{{item.carPrice}}-{{item.truckPrice}}
+					</view>
+				</view>
+				<view class="dprice">
+					已售:{{item.buyNum || 0}}
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		components: {},
+		data() {
+			return {};
+		},
+		props: {
+			setMealList: {
+				type: Array,
+				default: function() {
+					return {};
+				}
+			},
+		},
+		methods: {
+			// 路由跳转
+			routerTo(item) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/setMeal/setMealDetail/index?item=" + JSON.stringify(item)
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.body {
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+		margin-top: 30rpx;
+		// padding-bottom: 30rpx;
+		padding: 0 26rpx 30rpx;
+		.card {
+			width: 338rpx;
+			height: 532rpx;
+			background: #FFFFFF;
+			border: 1px solid #E5E5E5;
+			box-shadow: 0px 0px 14rpx 0px rgba(125, 125, 125, 0.13);
+			border-radius: 10rpx;
+			margin-top: 26rpx;
+			position: relative;
+			image {
+				width: 338rpx;
+				height: 338rpx;
+				box-shadow: 0px 0px 14rpx 0px rgba(125, 125, 125, 0.13);
+				border-radius: 10rpx;
+			}
+
+			.title {
+				height: 27rpx;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 39rpx;
+				padding: 24rpx 0 0 20rpx;
+			}
+
+			.content {
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 28rpx;
+				padding: 16rpx 20rpx 0 20rpx;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				-webkit-line-clamp: 2;
+				line-clamp: 2;
+				-webkit-box-orient: vertical;
+
+			}
+
+			.bottomView {
+				width: calc(100% - 34rpx);
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0rpx 17rpx 0 17rpx;
+				position: absolute;
+				bottom: 10rpx;
+				.priceView {
+					display: flex;
+					align-items: baseline;
+
+					.unit {
+						font-size: 20rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF3C00;
+					}
+
+					.price {
+						font-size: 32rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF3C00;
+					}
+				}
+
+				.dprice {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+				}
+			}
+		}
+	}
+</style>

+ 138 - 0
components/SetMeal/shopGoods.vue

@@ -0,0 +1,138 @@
+<template>
+	<view class="body">
+		<view class="card" v-for="(item, index) in setMealList" :key="index" @tap="routerTo(item)">
+			<image :src="'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/'+item.imgUrl"></image>
+			<view class="title">
+				{{item.name}}
+			</view>
+			<view class="content">
+				{{item.title}}
+			</view>
+			<view class="bottomView">
+				<view class="priceView">
+					<view class="unit">
+						¥
+					</view>
+					<view class="price">
+						{{item.carPrice}}-{{item.truckPrice}}
+					</view>
+				</view>
+				<view class="dprice">
+					已售:{{item.buyNum || 0}}
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		components: {},
+		data() {
+			return {};
+		},
+		props: {
+			setMealList: {
+				type: Array,
+				default: function() {
+					return {};
+				}
+			},
+		},
+		methods: {
+			// 路由跳转
+			routerTo(item) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/setMeal/setMealDetail/index?item=" + JSON.stringify(item)
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	.body {
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+		margin-top: 30rpx;
+		// padding-bottom: 30rpx;
+		padding: 0 2rpx 30rpx;
+		.card {
+			width: 338rpx;
+			height: 532rpx;
+			background: #FFFFFF;
+			border: 1px solid #E5E5E5;
+			box-shadow: 0px 0px 14rpx 0px rgba(125, 125, 125, 0.13);
+			border-radius: 10rpx;
+			margin-top: 26rpx;
+			position: relative;
+			image {
+				width: 338rpx;
+				height: 338rpx;
+				box-shadow: 0px 0px 14rpx 0px rgba(125, 125, 125, 0.13);
+				border-radius: 10rpx;
+			}
+
+			.title {
+				height: 27rpx;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 39rpx;
+				padding: 24rpx 0 0 20rpx;
+			}
+
+			.content {
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 28rpx;
+				padding: 16rpx 20rpx 0 20rpx;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				-webkit-line-clamp: 2;
+				line-clamp: 2;
+				-webkit-box-orient: vertical;
+			}
+
+			.bottomView {
+				width: calc(100% - 34rpx);
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0rpx 17rpx 0 17rpx;
+				position: absolute;
+				bottom: 10rpx;
+				.priceView {
+					display: flex;
+					align-items: baseline;
+
+					.unit {
+						font-size: 20rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF3C00;
+					}
+
+					.price {
+						font-size: 32rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF3C00;
+					}
+				}
+
+				.dprice {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+				}
+			}
+		}
+	}
+</style>

+ 3 - 0
config/index.js

@@ -0,0 +1,3 @@
+export default {
+	baseImagePath : 'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/',
+};

+ 20 - 0
index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <script>
+      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+        CSS.supports('top: constant(a)'))
+      document.write(
+        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+    </script>
+    <title></title>
+    <!--preload-links-->
+    <!--app-context-->
+  </head>
+  <body>
+    <div id="app"><!--app-html--></div>
+    <script type="module" src="/main.js"></script>
+  </body>
+</html>

+ 55 - 0
main.js

@@ -0,0 +1,55 @@
+import App from './App'
+import {
+	_router,
+	parseRoute
+} from '@/utils'
+// #ifndef VUE3
+import Vue from 'vue'
+import __config from 'config/index';
+Vue.config.productionTip = false
+Vue.prototype.$onLaunched = new Promise(resolve => {
+    Vue.prototype.$isResolve = resolve
+})
+Vue.prototype.baseImagePath = __config.baseImagePath;
+App.mpType = 'app'
+const app = new Vue({
+    ...App
+})
+Object.defineProperty(Vue.prototype, '$yrouter', {
+	get() {
+		return _router
+	},
+})
+
+Object.defineProperty(Vue.prototype, '$yroute', {
+	get() {
+		return this._route
+	},
+})
+Vue.mixin({
+	onLoad() {
+		const {
+			$mp
+		} = this.$root
+		this._route = parseRoute($mp)
+	},
+	onShow() {
+		_router.app = this
+		_router.currentRoute = this._route
+	},
+	// 这里为了解决 .vue文件中 template 无法获取 VUE.prototype 绑定的变量
+	computed: {
+	},
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+export function createApp() {
+  const app = createSSRApp(App)
+  return {
+    app
+  }
+}
+// #endif

+ 117 - 0
manifest.json

@@ -0,0 +1,117 @@
+{
+    "name" : "demo",
+    "appid" : "__UNI__E0A6F37",
+    "description" : "",
+    "versionName" : "1.2.0",
+    "versionCode" : 120,
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "compatible" : {
+            "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持 
+        },
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {
+            "Geolocation" : {},
+            "Payment" : {},
+            "VideoPlayer" : {},
+            "Maps" : {},
+            "Camera" : {}
+        },
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ],
+                "minSdkVersion" : 19,
+                "targetSdkVersion" : 21,
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
+            },
+            /* ios打包配置 */
+            "ios" : {
+                "dSYMs" : false
+            },
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "payment" : {
+                    "weixin" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appid" : "wx4e83ee1dac8476e8",
+                        "UniversalLinks" : "https://www.biaodianfuhao.net/"
+                    },
+                    "alipay" : {
+                        "__platform__" : [ "ios", "android" ]
+                    }
+                },
+                "geolocation" : {
+                    "system" : {
+                        "__platform__" : [ "ios", "android" ]
+                    },
+                    "amap" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appkey_ios" : "d9859a9bc8e45c7117c6935658c2ea82",
+                        "appkey_android" : "825fa606c29f4e672c7f32f6345757a7"
+                    }
+                },
+                "ad" : {},
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "d9859a9bc8e45c7117c6935658c2ea82",
+                        "appkey_android" : "825fa606c29f4e672c7f32f6345757a7"
+                    }
+                }
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "vueVersion" : "2"
+}

+ 201 - 0
node_modules/miniapp-color-thief/LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 170 - 0
node_modules/miniapp-color-thief/README.md

@@ -0,0 +1,170 @@
+# Mini App Color Thief
+
+基于小程序的结构,参考 [Color Thief](https://github.com/lokesh/color-thief/) 实现的获取图片主色调,非小程序也可使用,只需是 `Uint8ClampedArray` 类型的图片数据即可
+
+[![npm](https://img.shields.io/npm/v/miniapp-color-thief.svg?style=flat-square)](https://www.npmjs.com/package/miniapp-color-thief)
+[![license](https://img.shields.io/github/license/neobaran/miniapp-color-thief.svg?style=flat-square)](./LICENSE)
+[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
+
+## 快速上手
+
+### 安装
+
+```bash
+npm i --save miniapp-color-thief
+```
+
+### 使用
+
+以小程序中使用为 🌰
+
+```javascript
+import colorThief from "miniapp-color-thief";
+
+wx.canvasGetImageData({
+  canvasId: "myCanvas",
+  x: 0,
+  y: 0,
+  width: 100,
+  height: 100,
+  success: res => {
+    let palette = colorThief(res.data)
+      .palette()
+      .get();
+    console.log(palette); // [[0,0,0],[0,0,0],[0,0,0]...]
+  }
+});
+```
+
+## Demo
+
+[微信小程序代码片段](https://developers.weixin.qq.com/s/HIEMlXmk7w5q)
+
+## API
+
+### 计算
+
+#### Palette
+
+- 参数:
+  - `{Number} count` 返回色板的颜色数量 ( 1 < count < 256 )
+  - `{Number} quality` 计算颜色的精度,默认为 `10`
+- 说明:
+
+  获取图片的色板
+
+```javascript
+colorThief(data)
+  .palette(count, quality)
+  .get(); // [[0,0,0],[0,0,0],[0,0,0]...]
+```
+
+#### Color
+
+- 参数:
+  - `{Number} quality` 计算颜色的精度,默认为 `10`
+- 说明:
+
+  获取图片的主色调
+
+```javascript
+colorThief(data)
+  .color(quality)
+  .get(); // [0,0,0]
+```
+
+### 输出
+
+#### Get
+
+- 输出:
+  - `{Array}`
+- 说明:
+
+  返回颜色的 [R,G,B]
+
+```javascript
+colorThief(data)
+  .palette()
+  .get(); // [[0,0,0],[0,0,0],[0,0,0]...]
+
+colorThief(data)
+  .color()
+  .get(); // [0,0,0]
+```
+
+#### GetHex
+
+- 输出:
+  - `{Array|String}`
+- 说明:
+
+  返回颜色的 16 进制
+
+```javascript
+colorThief(data)
+  .palette()
+  .getHex(); // ['#000000','#000000','#000000'...]
+
+colorThief(data)
+  .color()
+  .getHex(); // '#000000'
+```
+
+#### GetGray
+
+- 输出:
+  - `{Array|Number}`
+- 说明:
+
+  返回颜色灰度 `0 ~ 255`
+
+```javascript
+colorThief(data)
+  .palette()
+  .getGray(); // [0,0,0...]
+
+colorThief(data)
+  .color()
+  .getGray(); // 0
+```
+
+#### IsDark
+
+- 输出:
+  - `{Array|Boolean}`
+- 说明:
+
+  返回颜色是否为深色系
+
+```javascript
+colorThief(data)
+  .palette()
+  .isDark(); // [true,true,false...]
+
+colorThief(data)
+  .color()
+  .isDark(); // true
+```
+
+#### IsLight
+
+- 输出:
+  - `{Array|Boolean}`
+- 说明:
+
+  返回颜色是否为浅色系
+
+```javascript
+colorThief(data)
+  .palette()
+  .isLight(); // [true,true,false...]
+
+colorThief(data)
+  .color()
+  .isLight(); // true
+```
+
+## License
+
+Apache-2.0 @ [NEOBARAN](https://github.com/neobaran)

+ 79 - 0
node_modules/miniapp-color-thief/index.js

@@ -0,0 +1,79 @@
+import quantize from "quantize";
+
+const toString = array =>
+  `#${((1 << 24) + (array[0] << 16) + (array[1] << 8) + array[2])
+    .toString(16)
+    .slice(1)}`;
+
+const proxy = (data, fn) => {
+  if (data.map(item => Array.isArray(item)).includes(true)) {
+    return data.map(item => fn(item));
+  } else {
+    return fn(data);
+  }
+};
+
+const getGray = rgb => (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
+
+const colorThief = pixels => ({
+  palette(count, quality) {
+    if (typeof count === "undefined" || count < 2 || count > 256) {
+      count = 10;
+    }
+    if (typeof quality === "undefined" || quality < 1) {
+      quality = 10;
+    }
+
+    // Store the RGB values in an array format suitable for quantize function
+    let pixelArray = [];
+    for (
+      let i = 0, offset, r, g, b, a;
+      i < pixels.length / 4;
+      i = i + quality
+    ) {
+      offset = i * 4;
+      r = pixels[offset + 0];
+      g = pixels[offset + 1];
+      b = pixels[offset + 2];
+      a = pixels[offset + 3];
+      // If pixel is mostly opaque and not white
+      if (a >= 125) {
+        if (!(r > 250 && g > 250 && b > 250)) {
+          pixelArray.push([r, g, b]);
+        }
+      }
+    }
+    this._data = quantize(pixelArray, count).palette() || null;
+    return this;
+  },
+  color(quality) {
+    let palette = this.palette(5, quality)._data;
+    if (palette) {
+      this._data = palette[0];
+      return this;
+    } else {
+      console.error(
+        "[MiniApp Color Thief] getColor has error: palette length is zero."
+      );
+    }
+  },
+  __proto__: {
+    get() {
+      return this._data;
+    },
+    getHex() {
+      return proxy(this._data, toString);
+    },
+    getGray() {
+      return proxy(this._data, getGray);
+    },
+    isDark() {
+      return proxy(this._data, data => getGray(data) < 127.5);
+    },
+    isLight() {
+      return proxy(this._data, data => getGray(data) >= 127.5);
+    }
+  }
+});
+
+export default colorThief;

+ 37 - 0
node_modules/miniapp-color-thief/package.json

@@ -0,0 +1,37 @@
+{
+  "name": "miniapp-color-thief",
+  "version": "1.0.5",
+  "description": "color thief for mini app (wechat / Alipay / Baidu...)",
+  "main": "index.js",
+  "scripts": {
+    "prod": "npm version patch && npm publish"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/neobaran/miniapp-color-thief.git"
+  },
+  "keywords": [
+    "color",
+    "color thief",
+    "颜色",
+    "miniapp",
+    "小程序",
+    "wechat",
+    "weixin",
+    "微信",
+    "微信小程序",
+    "支付宝小程序",
+    "百度小程序",
+    "头条小程序",
+    "快应用"
+  ],
+  "author": "NEOBARAN",
+  "license": "Apache-2.0",
+  "bugs": {
+    "url": "https://github.com/neobaran/miniapp-color-thief/issues"
+  },
+  "homepage": "https://github.com/neobaran/miniapp-color-thief",
+  "dependencies": {
+    "quantize": "^1.0.2"
+  }
+}

+ 20 - 0
node_modules/quantize/LICENSE

@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Olivier Lesnicki
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 62 - 0
node_modules/quantize/README.md

@@ -0,0 +1,62 @@
+quantize
+========
+
+Node.js module for color quantization, based on Leptonica.
+
+Install
+-------
+
+	npm install quantize
+
+Quick Overview
+--------------
+
+###Usage
+
+`````javascript
+var quantize = require('quantize');
+
+var arrayOfPixels = [[190,197,190], [202,204,200], [207,214,210], [211,214,211], [205,207,207]];
+var maximumColorCount = 4;
+
+var colorMap = quantize(arrayOfPixels, maximumColorCount);
+`````
+
+* `arrayOfPixels` - An array of pixels (represented as [R,G,B arrays]) to quantize
+* `maxiumColorCount` - The maximum number of colours allowed in the reduced palette
+
+#####Reduced Palette
+
+The `.palette()` method returns an array that contains the reduced color palette.
+
+`````javascript
+// Returns the reduced palette
+colorMap.palette(); 
+// [[204, 204, 204], [208,212,212], [188,196,188], [212,204,196]]
+`````
+
+#####Reduced pixel
+
+The `.map(pixel)` method maps an individual pixel to the reduced color palette.
+
+`````javascript
+// Returns the reduced pixel
+colorMap.map(arrayOfPixels[0]);
+// [188,196,188]
+`````
+
+Author
+------
+
+* [Olivier Lesnicki](https://github.com/olivierlesnicki)
+
+Contributors
+------------
+
+* [Nick Rabinowitz](https://github.com/nrabinowitz)
+* [Mike Bostock] (https://github.com/mbostock)
+
+License
+-------
+
+Licensed under the MIT License.

+ 35 - 0
node_modules/quantize/package.json

@@ -0,0 +1,35 @@
+{
+    "name": "quantize",
+    "version": "1.0.2",
+    "description": "A node.js module for color quantization, based on Leptonica.",
+    "homepage": "https://github.com/olivierlesnicki/quantize",
+    "author": "Olivier Lesnicki (https://github.com/olivierlesnicki)",
+    "keywords": [
+        "image",
+        "quantize",
+        "color",
+        "node"
+    ],
+    "contributors": [
+        "Nick Rabinowitz (https://github.com/nrabinowitz)",
+        "Olivier Lesnicki (https://github.com/olivierlesnicki)"
+    ],
+    "bugs": {
+        "url": "http://github.com/olivierlesnicki/quantize/issues"
+    },
+    "license": {
+        "type": "MIT",
+        "url": "http://github.com/olivierlesnicki/quantize/raw/master/LICENSE"
+    },
+    "main": "quantize.js",
+    "repository": {
+        "type": "git",
+        "url": "git://github.com/olivierlesnicki/quantize.git"
+    },
+    "engines": {
+        "node": ">=0.10.21"
+    },
+    "dependencies": {},
+    "devDependencies": {},
+    "scripts": {}
+}

+ 490 - 0
node_modules/quantize/quantize.js

@@ -0,0 +1,490 @@
+/*
+ * quantize.js Copyright 2008 Nick Rabinowitz
+ * Ported to node.js by Olivier Lesnicki
+ * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
+ */
+
+// fill out a couple protovis dependencies
+/*
+ * Block below copied from Protovis: http://mbostock.github.com/protovis/
+ * Copyright 2010 Stanford Visualization Group
+ * Licensed under the BSD License: http://www.opensource.org/licenses/bsd-license.php
+ */
+if (!pv) {
+    var pv = {
+        map: function(array, f) {
+            var o = {};
+            return f ? array.map(function(d, i) {
+                o.index = i;
+                return f.call(o, d);
+            }) : array.slice();
+        },
+        naturalOrder: function(a, b) {
+            return (a < b) ? -1 : ((a > b) ? 1 : 0);
+        },
+        sum: function(array, f) {
+            var o = {};
+            return array.reduce(f ? function(p, d, i) {
+                o.index = i;
+                return p + f.call(o, d);
+            } : function(p, d) {
+                return p + d;
+            }, 0);
+        },
+        max: function(array, f) {
+            return Math.max.apply(null, f ? pv.map(array, f) : array);
+        }
+    }
+}
+
+/**
+ * Basic Javascript port of the MMCQ (modified median cut quantization)
+ * algorithm from the Leptonica library (http://www.leptonica.com/).
+ * Returns a color map you can use to map original pixels to the reduced
+ * palette. Still a work in progress.
+ * 
+ * @author Nick Rabinowitz
+ * @example
+ 
+// array of pixels as [R,G,B] arrays
+var myPixels = [[190,197,190], [202,204,200], [207,214,210], [211,214,211], [205,207,207]
+                // etc
+                ];
+var maxColors = 4;
+ 
+var cmap = MMCQ.quantize(myPixels, maxColors);
+var newPalette = cmap.palette();
+var newPixels = myPixels.map(function(p) { 
+    return cmap.map(p); 
+});
+ 
+ */
+var MMCQ = (function() {
+    // private constants
+    var sigbits = 5,
+        rshift = 8 - sigbits,
+        maxIterations = 1000,
+        fractByPopulations = 0.75;
+
+    // get reduced-space color index for a pixel
+
+    function getColorIndex(r, g, b) {
+        return (r << (2 * sigbits)) + (g << sigbits) + b;
+    }
+
+    // Simple priority queue
+
+    function PQueue(comparator) {
+        var contents = [],
+            sorted = false;
+
+        function sort() {
+            contents.sort(comparator);
+            sorted = true;
+        }
+
+        return {
+            push: function(o) {
+                contents.push(o);
+                sorted = false;
+            },
+            peek: function(index) {
+                if (!sorted) sort();
+                if (index === undefined) index = contents.length - 1;
+                return contents[index];
+            },
+            pop: function() {
+                if (!sorted) sort();
+                return contents.pop();
+            },
+            size: function() {
+                return contents.length;
+            },
+            map: function(f) {
+                return contents.map(f);
+            },
+            debug: function() {
+                if (!sorted) sort();
+                return contents;
+            }
+        };
+    }
+
+    // 3d color space box
+
+    function VBox(r1, r2, g1, g2, b1, b2, histo) {
+        var vbox = this;
+        vbox.r1 = r1;
+        vbox.r2 = r2;
+        vbox.g1 = g1;
+        vbox.g2 = g2;
+        vbox.b1 = b1;
+        vbox.b2 = b2;
+        vbox.histo = histo;
+    }
+    VBox.prototype = {
+        volume: function(force) {
+            var vbox = this;
+            if (!vbox._volume || force) {
+                vbox._volume = ((vbox.r2 - vbox.r1 + 1) * (vbox.g2 - vbox.g1 + 1) * (vbox.b2 - vbox.b1 + 1));
+            }
+            return vbox._volume;
+        },
+        count: function(force) {
+            var vbox = this,
+                histo = vbox.histo;
+            if (!vbox._count_set || force) {
+                var npix = 0,
+                    i, j, k, index;
+                for (i = vbox.r1; i <= vbox.r2; i++) {
+                    for (j = vbox.g1; j <= vbox.g2; j++) {
+                        for (k = vbox.b1; k <= vbox.b2; k++) {
+                            index = getColorIndex(i, j, k);
+                            npix += (histo[index] || 0);
+                        }
+                    }
+                }
+                vbox._count = npix;
+                vbox._count_set = true;
+            }
+            return vbox._count;
+        },
+        copy: function() {
+            var vbox = this;
+            return new VBox(vbox.r1, vbox.r2, vbox.g1, vbox.g2, vbox.b1, vbox.b2, vbox.histo);
+        },
+        avg: function(force) {
+            var vbox = this,
+                histo = vbox.histo;
+            if (!vbox._avg || force) {
+                var ntot = 0,
+                    mult = 1 << (8 - sigbits),
+                    rsum = 0,
+                    gsum = 0,
+                    bsum = 0,
+                    hval,
+                    i, j, k, histoindex;
+                for (i = vbox.r1; i <= vbox.r2; i++) {
+                    for (j = vbox.g1; j <= vbox.g2; j++) {
+                        for (k = vbox.b1; k <= vbox.b2; k++) {
+                            histoindex = getColorIndex(i, j, k);
+                            hval = histo[histoindex] || 0;
+                            ntot += hval;
+                            rsum += (hval * (i + 0.5) * mult);
+                            gsum += (hval * (j + 0.5) * mult);
+                            bsum += (hval * (k + 0.5) * mult);
+                        }
+                    }
+                }
+                if (ntot) {
+                    vbox._avg = [~~(rsum / ntot), ~~ (gsum / ntot), ~~ (bsum / ntot)];
+                } else {
+                    //console.log('empty box');
+                    vbox._avg = [~~(mult * (vbox.r1 + vbox.r2 + 1) / 2), ~~ (mult * (vbox.g1 + vbox.g2 + 1) / 2), ~~ (mult * (vbox.b1 + vbox.b2 + 1) / 2)];
+                }
+            }
+            return vbox._avg;
+        },
+        contains: function(pixel) {
+            var vbox = this,
+                rval = pixel[0] >> rshift;
+            gval = pixel[1] >> rshift;
+            bval = pixel[2] >> rshift;
+            return (rval >= vbox.r1 && rval <= vbox.r2 &&
+                gval >= vbox.g1 && gval <= vbox.g2 &&
+                bval >= vbox.b1 && bval <= vbox.b2);
+        }
+    };
+
+    // Color map
+
+    function CMap() {
+        this.vboxes = new PQueue(function(a, b) {
+            return pv.naturalOrder(
+                a.vbox.count() * a.vbox.volume(),
+                b.vbox.count() * b.vbox.volume()
+            )
+        });;
+    }
+    CMap.prototype = {
+        push: function(vbox) {
+            this.vboxes.push({
+                vbox: vbox,
+                color: vbox.avg()
+            });
+        },
+        palette: function() {
+            return this.vboxes.map(function(vb) {
+                return vb.color
+            });
+        },
+        size: function() {
+            return this.vboxes.size();
+        },
+        map: function(color) {
+            var vboxes = this.vboxes;
+            for (var i = 0; i < vboxes.size(); i++) {
+                if (vboxes.peek(i).vbox.contains(color)) {
+                    return vboxes.peek(i).color;
+                }
+            }
+            return this.nearest(color);
+        },
+        nearest: function(color) {
+            var vboxes = this.vboxes,
+                d1, d2, pColor;
+            for (var i = 0; i < vboxes.size(); i++) {
+                d2 = Math.sqrt(
+                    Math.pow(color[0] - vboxes.peek(i).color[0], 2) +
+                    Math.pow(color[1] - vboxes.peek(i).color[1], 2) +
+                    Math.pow(color[2] - vboxes.peek(i).color[2], 2)
+                );
+                if (d2 < d1 || d1 === undefined) {
+                    d1 = d2;
+                    pColor = vboxes.peek(i).color;
+                }
+            }
+            return pColor;
+        },
+        forcebw: function() {
+            // XXX: won't  work yet
+            var vboxes = this.vboxes;
+            vboxes.sort(function(a, b) {
+                return pv.naturalOrder(pv.sum(a.color), pv.sum(b.color))
+            });
+
+            // force darkest color to black if everything < 5
+            var lowest = vboxes[0].color;
+            if (lowest[0] < 5 && lowest[1] < 5 && lowest[2] < 5)
+                vboxes[0].color = [0, 0, 0];
+
+            // force lightest color to white if everything > 251
+            var idx = vboxes.length - 1,
+                highest = vboxes[idx].color;
+            if (highest[0] > 251 && highest[1] > 251 && highest[2] > 251)
+                vboxes[idx].color = [255, 255, 255];
+        }
+    };
+
+    // histo (1-d array, giving the number of pixels in
+    // each quantized region of color space), or null on error
+
+    function getHisto(pixels) {
+        var histosize = 1 << (3 * sigbits),
+            histo = new Array(histosize),
+            index, rval, gval, bval;
+        pixels.forEach(function(pixel) {
+            rval = pixel[0] >> rshift;
+            gval = pixel[1] >> rshift;
+            bval = pixel[2] >> rshift;
+            index = getColorIndex(rval, gval, bval);
+            histo[index] = (histo[index] || 0) + 1;
+        });
+        return histo;
+    }
+
+    function vboxFromPixels(pixels, histo) {
+        var rmin = 1000000,
+            rmax = 0,
+            gmin = 1000000,
+            gmax = 0,
+            bmin = 1000000,
+            bmax = 0,
+            rval, gval, bval;
+        // find min/max
+        pixels.forEach(function(pixel) {
+            rval = pixel[0] >> rshift;
+            gval = pixel[1] >> rshift;
+            bval = pixel[2] >> rshift;
+            if (rval < rmin) rmin = rval;
+            else if (rval > rmax) rmax = rval;
+            if (gval < gmin) gmin = gval;
+            else if (gval > gmax) gmax = gval;
+            if (bval < bmin) bmin = bval;
+            else if (bval > bmax) bmax = bval;
+        });
+        return new VBox(rmin, rmax, gmin, gmax, bmin, bmax, histo);
+    }
+
+    function medianCutApply(histo, vbox) {
+        if (!vbox.count()) return;
+
+        var rw = vbox.r2 - vbox.r1 + 1,
+            gw = vbox.g2 - vbox.g1 + 1,
+            bw = vbox.b2 - vbox.b1 + 1,
+            maxw = pv.max([rw, gw, bw]);
+        // only one pixel, no split
+        if (vbox.count() == 1) {
+            return [vbox.copy()]
+        }
+        /* Find the partial sum arrays along the selected axis. */
+        var total = 0,
+            partialsum = [],
+            lookaheadsum = [],
+            i, j, k, sum, index;
+        if (maxw == rw) {
+            for (i = vbox.r1; i <= vbox.r2; i++) {
+                sum = 0;
+                for (j = vbox.g1; j <= vbox.g2; j++) {
+                    for (k = vbox.b1; k <= vbox.b2; k++) {
+                        index = getColorIndex(i, j, k);
+                        sum += (histo[index] || 0);
+                    }
+                }
+                total += sum;
+                partialsum[i] = total;
+            }
+        } else if (maxw == gw) {
+            for (i = vbox.g1; i <= vbox.g2; i++) {
+                sum = 0;
+                for (j = vbox.r1; j <= vbox.r2; j++) {
+                    for (k = vbox.b1; k <= vbox.b2; k++) {
+                        index = getColorIndex(j, i, k);
+                        sum += (histo[index] || 0);
+                    }
+                }
+                total += sum;
+                partialsum[i] = total;
+            }
+        } else { /* maxw == bw */
+            for (i = vbox.b1; i <= vbox.b2; i++) {
+                sum = 0;
+                for (j = vbox.r1; j <= vbox.r2; j++) {
+                    for (k = vbox.g1; k <= vbox.g2; k++) {
+                        index = getColorIndex(j, k, i);
+                        sum += (histo[index] || 0);
+                    }
+                }
+                total += sum;
+                partialsum[i] = total;
+            }
+        }
+        partialsum.forEach(function(d, i) {
+            lookaheadsum[i] = total - d
+        });
+
+        function doCut(color) {
+            var dim1 = color + '1',
+                dim2 = color + '2',
+                left, right, vbox1, vbox2, d2, count2 = 0;
+            for (i = vbox[dim1]; i <= vbox[dim2]; i++) {
+                if (partialsum[i] > total / 2) {
+                    vbox1 = vbox.copy();
+                    vbox2 = vbox.copy();
+                    left = i - vbox[dim1];
+                    right = vbox[dim2] - i;
+                    if (left <= right)
+                        d2 = Math.min(vbox[dim2] - 1, ~~ (i + right / 2));
+                    else d2 = Math.max(vbox[dim1], ~~ (i - 1 - left / 2));
+                    // avoid 0-count boxes
+                    while (!partialsum[d2]) d2++;
+                    count2 = lookaheadsum[d2];
+                    while (!count2 && partialsum[d2 - 1]) count2 = lookaheadsum[--d2];
+                    // set dimensions
+                    vbox1[dim2] = d2;
+                    vbox2[dim1] = vbox1[dim2] + 1;
+                    // console.log('vbox counts:', vbox.count(), vbox1.count(), vbox2.count());
+                    return [vbox1, vbox2];
+                }
+            }
+
+        }
+        // determine the cut planes
+        return maxw == rw ? doCut('r') :
+            maxw == gw ? doCut('g') :
+            doCut('b');
+    }
+
+    function quantize(pixels, maxcolors) {
+        // short-circuit
+        if (!pixels.length || maxcolors < 2 || maxcolors > 256) {
+            // console.log('wrong number of maxcolors');
+            return false;
+        }
+
+        // XXX: check color content and convert to grayscale if insufficient
+
+        var histo = getHisto(pixels),
+            histosize = 1 << (3 * sigbits);
+
+        // check that we aren't below maxcolors already
+        var nColors = 0;
+        histo.forEach(function() {
+            nColors++
+        });
+        if (nColors <= maxcolors) {
+            // XXX: generate the new colors from the histo and return
+        }
+
+        // get the beginning vbox from the colors
+        var vbox = vboxFromPixels(pixels, histo),
+            pq = new PQueue(function(a, b) {
+                return pv.naturalOrder(a.count(), b.count())
+            });
+        pq.push(vbox);
+
+        // inner function to do the iteration
+
+        function iter(lh, target) {
+            var ncolors = 1,
+                niters = 0,
+                vbox;
+            while (niters < maxIterations) {
+                vbox = lh.pop();
+                if (!vbox.count()) { /* just put it back */
+                    lh.push(vbox);
+                    niters++;
+                    continue;
+                }
+                // do the cut
+                var vboxes = medianCutApply(histo, vbox),
+                    vbox1 = vboxes[0],
+                    vbox2 = vboxes[1];
+
+                if (!vbox1) {
+                    // console.log("vbox1 not defined; shouldn't happen!");
+                    return;
+                }
+                lh.push(vbox1);
+                if (vbox2) { /* vbox2 can be null */
+                    lh.push(vbox2);
+                    ncolors++;
+                }
+                if (ncolors >= target) return;
+                if (niters++ > maxIterations) {
+                    // console.log("infinite loop; perhaps too few pixels!");
+                    return;
+                }
+            }
+        }
+
+        // first set of colors, sorted by population
+        iter(pq, fractByPopulations * maxcolors);
+        // console.log(pq.size(), pq.debug().length, pq.debug().slice());
+
+        // Re-sort by the product of pixel occupancy times the size in color space.
+        var pq2 = new PQueue(function(a, b) {
+            return pv.naturalOrder(a.count() * a.volume(), b.count() * b.volume())
+        });
+        while (pq.size()) {
+            pq2.push(pq.pop());
+        }
+
+        // next set - generate the median cuts using the (npix * vol) sorting.
+        iter(pq2, maxcolors - pq2.size());
+
+        // calculate the actual colors
+        var cmap = new CMap();
+        while (pq2.size()) {
+            cmap.push(pq2.pop());
+        }
+
+        return cmap;
+    }
+
+    return {
+        quantize: quantize
+    }
+})();
+
+module.exports = MMCQ.quantize

+ 43 - 0
package-lock.json

@@ -0,0 +1,43 @@
+{
+  "name": "U1U5Uni",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "dependencies": {
+        "miniapp-color-thief": "^1.0.5"
+      }
+    },
+    "node_modules/miniapp-color-thief": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/miniapp-color-thief/-/miniapp-color-thief-1.0.5.tgz",
+      "integrity": "sha512-vBfmh8rY1pYeRSFi3RPCkp4ExtFtrdbye/qYs/XTgrt4qpIlIRAC4XynSJRd1KumGFAKi8UUN/spxw2BqcSTBg==",
+      "dependencies": {
+        "quantize": "^1.0.2"
+      }
+    },
+    "node_modules/quantize": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/quantize/-/quantize-1.0.2.tgz",
+      "integrity": "sha512-25P7wI2UoDbIQsQp50ARkt+5pwPsOq7G/BqvT5xAbapnRoNWMN8/p55H9TXd5MuENiJnm5XICB2H2aDZGwts7w==",
+      "engines": {
+        "node": ">=0.10.21"
+      }
+    }
+  },
+  "dependencies": {
+    "miniapp-color-thief": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/miniapp-color-thief/-/miniapp-color-thief-1.0.5.tgz",
+      "integrity": "sha512-vBfmh8rY1pYeRSFi3RPCkp4ExtFtrdbye/qYs/XTgrt4qpIlIRAC4XynSJRd1KumGFAKi8UUN/spxw2BqcSTBg==",
+      "requires": {
+        "quantize": "^1.0.2"
+      }
+    },
+    "quantize": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/quantize/-/quantize-1.0.2.tgz",
+      "integrity": "sha512-25P7wI2UoDbIQsQp50ARkt+5pwPsOq7G/BqvT5xAbapnRoNWMN8/p55H9TXd5MuENiJnm5XICB2H2aDZGwts7w=="
+    }
+  }
+}

+ 5 - 0
package.json

@@ -0,0 +1,5 @@
+{
+  "dependencies": {
+    "miniapp-color-thief": "^1.0.5"
+  }
+}

+ 392 - 0
pages.json

@@ -0,0 +1,392 @@
+{
+	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+		{
+			"path": "pages/home/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "优1优5",
+			    "enablePullDownRefresh": false
+			}
+		},
+		{
+			"path": "pages/shop/CarsClass/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "买车",
+			    "enablePullDownRefresh": false
+			}
+		},
+		{
+			"path": "pages/shop/LeaseCarClass/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "租车",
+			    "enablePullDownRefresh": false
+			}
+		},
+		{
+			"path": "pages/shop/ShoppingMall/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "商城",
+			    "enablePullDownRefresh": false
+			}
+		},
+		{
+			"path": "pages/user/User/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "我的",
+			    "enablePullDownRefresh": false
+			}
+		},
+		{
+			"path": "pages/preCarWash/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "预约洗车",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"disableSwipeBack": true,
+				"app-plus": {
+					"popGesture": "none"
+				}
+			}
+		},
+		{
+			"path": "pages/userMeal/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "我的套餐",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"disableSwipeBack": true,
+				"app-plus": {
+					"popGesture": "none"
+				}
+			}
+		},
+		{
+			"path": "pages/userMeal/userMealDetail/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "我的套餐详情",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "维修保养",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"disableSwipeBack": true,
+				"app-plus": {
+					"popGesture": "none"
+				}
+			}
+		},
+		{
+			"path": "pages/maintenance/maintainOrder/flow/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "流程细明",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/maintainOrder/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "维修保养订单",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"disableSwipeBack": true,
+				"app-plus": {
+					"popGesture": "none"
+				}
+			}
+		},
+		{
+			"path": "pages/maintenance/maintainOrder/orderDetail/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "订单详情",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"navigationBarTextStyle": "white",
+				"navigationStyle":"custom",
+				 "app-plus":{
+				       "titleNView":false
+				       }
+			}
+		},
+		{
+			"path": "pages/maintenance/maintainOrder/deliveryOfVehicle/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "提车确认",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/preCarWash/chooseTime/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "选择预约时间",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/preCarWash/chooseShop/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "选择门店",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/preCarWash/chooseCar/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "选择车辆",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/preCarWash/setMeal/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "选择套餐",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/preCarWash/washOrder/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "洗车订单",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"disableSwipeBack": true,
+				"app-plus": {
+					"popGesture": "none"
+				}
+			}
+		},
+		{
+			"path": "pages/preCarWash/washOrder/serviceEvaluation/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "服务评价",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/preCarWash/washOrder/orderDetail/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "订单详情",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"navigationBarTextStyle": "white",
+				"navigationStyle":"custom",
+				 "app-plus":{
+				       "titleNView":false
+				       }
+			}
+		},
+		{
+			"path": "pages/maintenance/onlineReservation/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "在线预约",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/servicesAvailable/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "服务项目",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/evaluate/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "维修估价",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/evaluate/history/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "历史估价记录",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/evaluate/history/detail",
+			"style" :
+			{
+			    "navigationBarTitleText": "评估详情",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/setMeal/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "套餐服务",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/setMeal/buySetMeal/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "购买套餐",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		},
+		{
+			"path": "pages/maintenance/setMeal/setMealDetail/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "套餐详情",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"disableSwipeBack": true
+			}
+		},
+		{
+			"path": "pages/shop/shopDetail/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "店铺详情",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"navigationBarTextStyle": "white",
+				"navigationStyle":"custom",
+				 "app-plus":{
+				       "titleNView":false
+				       }
+			}
+		},
+		{
+			"path": "pages/shop/shopDetail/shopPhotoAlbum/index",
+			"style" :
+			{
+			    "navigationBarTitleText": "门店相册",
+			    "enablePullDownRefresh": false,
+				"navigationBarBackgroundColor": "#FFFFFF"
+			}
+		}
+        ,{
+            "path" : "pages/maintenance/expensesList/expensesList",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "费用清单",
+                "enablePullDownRefresh": false,
+                "navigationBarBackgroundColor": "#FFFFFF",
+                "app-plus": {
+                	"popGesture": "none"
+                }
+            }
+            
+        }
+        ,{
+            "path" : "pages/shop/shopDetail/ShopInclude/ShopInclude",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "店铺介绍",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/maintenance/agreement/agreement",
+            "style" :                                                                                    
+            {
+                "enablePullDownRefresh": false,
+                "navigationBarBackgroundColor": "#FFFFFF"
+            }
+            
+        }
+        ,{
+            "path" : "pages/shop/navigation/navigation",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "店铺导航",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/shop/cashierDesk/cashierDesk",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "收银台",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+    ],
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "uni-app",
+		"navigationBarBackgroundColor": "#F8F8F8",
+		"backgroundColor": "#F8F8F8",
+		"enablePullDownRefresh":false
+	},
+	"tabBar": {
+		"color": "#666666",
+		"selectedColor": "#333333",
+		"borderStyle": "black",
+		"backgroundColor": "#FFFFFF",
+		"height": "50px",
+		"fontSize": "10px",
+		"iconWidth": "24px",
+		"spacing": "3px",
+		"list": [{
+				"pagePath": "pages/home/index",
+				"text": "首页"
+			},
+			{
+				"pagePath": "pages/shop/CarsClass/index",
+				"text": "买车"
+			},
+			{
+				"pagePath": "pages/shop/LeaseCarClass/index",
+				"text": "租车"
+			},
+			{
+				"pagePath": "pages/shop/ShoppingMall/index",
+				"text": "商城"
+			},
+			{
+				"pagePath": "pages/user/User/index",
+				"text": "我的"
+			}
+		]
+	}
+}

+ 130 - 0
pages/home/components/Banner.vue

@@ -0,0 +1,130 @@
+<template>
+	<view class="banner-swiper-box">
+		<canvas canvas-id="colorThief" class="hide-canvas"></canvas>
+		<swiper class="banner-carousel Shop-selector-rect" circular @change="swiperChange" :autoplay="true">
+			<swiper-item v-for="(item, index) in detail" :key="index" class="carousel-item">
+				<image class="swiper-image" :src="item.pic" mode="heightFix" lazy-load>
+				</image>
+			</swiper-item>
+		</swiper>
+		<view class="banner-swiper-dots">
+			<text :class="swiperCurrent === index ? 'banner-dot-active' : 'banner-dot'" v-for="(dot, index) in detail.length"
+			 :key="index"></text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import colorThief from 'miniapp-color-thief';
+
+	export default {
+		data() {
+			return {
+				swiperCurrent: 0, //轮播下标
+				webviewId: 0,
+			};
+		},
+		props: {
+			detail: {
+				type: Array,
+				default: []
+			}
+		},
+		created: async function() {
+			await this.doColorThief();
+		},
+		computed: {},
+		methods: {
+			doColorThief() {
+				let that = this;
+				// 获取轮播图
+				let item = this.detail[this.swiperCurrent];
+				// 获取轮播图颜色
+				let bgcolor = item.color;
+				// 颜色不存在
+				if (!bgcolor) {
+					that.$set(item, 'bgcolor', '#2A2A2A');
+					that.$emit('getbgcolor', '#2A2A2A');
+				} else {
+					that.$set(item, 'bgcolor', bgcolor);
+					that.$emit('getbgcolor', bgcolor);
+				}
+
+			},
+			swiperChange(e) {
+				this.swiperCurrent = e.detail.current;
+				this.doColorThief();
+				let bgcolor = this.detail[this.swiperCurrent].bgcolor;
+			},
+
+			// 路由跳转
+			goRoll(item) {
+				if (item.uniapp_url) {
+					this.$yrouter.push(item.uniapp_url)
+				}
+			},
+		}
+
+	}
+</script>
+
+<style lang="less">
+	// 轮播
+	.banner-swiper-box {
+		background: #fff;
+	}
+
+	.banner-swiper-box,
+	.banner-carousel {
+		width: 750rpx;
+		height: 380rpx;
+		position: relative;
+
+		.carousel-item {
+			width: 100%;
+			height: 100%;
+			// padding: 0 28upx;
+			overflow: hidden;
+		}
+
+		.swiper-image {
+			width: 100%;
+			height: 100%;
+			// border-radius: 10upx;
+			// background: #ccc;
+		}
+	}
+
+	.banner-swiper-dots {
+		display: flex;
+		position: absolute;
+		left: 50%;
+		transform: translateX(-50%);
+		bottom: 20rpx;
+		z-index: 5;
+
+		.banner-dot {
+			width: 8rpx;
+			height: 8rpx;
+			border-radius: 50%;
+			margin-right: 6rpx;
+			background: rgba(255, 255, 255, 1);
+		}
+
+		.banner-dot-active {
+			width: 30rpx;
+			height: 8rpx;
+			background: #C3102E;
+			border-radius: 4rpx;
+			margin-right: 6rpx;
+		}
+	}
+
+
+	.hide-canvas {
+		position: fixed !important;
+		top: -99999upx;
+		left: -99999upx;
+		z-index: -99999;
+	}
+</style>

+ 108 - 0
pages/home/index.vue

@@ -0,0 +1,108 @@
+<template>
+	<view class="index">
+		<view class="content_box">
+			<!-- <view @click="to">套餐入口</view> -->
+			<!-- 菜单 -->
+			<Menu :list="menus"></Menu>
+		</view>
+	</view>
+</template>
+
+<script>
+	import Banner from './components/Banner'
+	import Menu from '@/components/Menu'
+	export default {
+		name: 'Index',
+		components: {
+			Banner,
+			Menu
+		},
+		props: {},
+		data: function() {
+			return {
+				bgcolor: '',
+				bannerData: [{
+						pic: require("../../static/banner.png")
+					},
+					{
+						pic: "https://qiniu.liangzhuangzhu.com/头图01(1).jpg"
+					},
+				],
+				menus:[
+					{
+						name:"汽车商城",
+						pic:require("../../static/qiche.png")
+					},
+					{
+						name:"租车商城",
+						pic:require("../../static/zuche.png")
+					},
+					{
+						name:"综合商城",
+						pic:require("../../static/shangcheng.png")
+					},
+					{
+						name:"维修保养",
+						pic:require("../../static/weixiu.png")
+					},
+					{
+						name:"登记过户",
+						pic:require("../../static/guohu.png")
+					},
+					{
+						name:"积分兑换",
+						pic:require("../../static/jifen.png")
+					},
+					{
+						name:"车况检测",
+						pic:require("../../static/jiancha.png")
+					},
+					{
+						name:"车辆快评",
+						pic:require("../../static/kuaiping.png")
+					},
+					{
+						name:"预约洗车",
+						pic:require("../../static/xiche.png")
+					},
+					{
+						name:"维修保养",
+						pic:require("../../static/baoyang.png")
+					},
+					{
+						name:"VIN码查车",
+						pic:require("../../static/vin.png")
+					},
+					{
+						name:"违章查询",
+						pic:require("../../static/weizhang.png")
+					},
+					{
+						name:"驾照查分",
+						pic:require("../../static/chafen.png")
+					},
+					{
+						name:"分期计算",
+						pic:require("../../static/jisuan.png")
+					}
+				]
+			}
+		},
+		methods: {
+			to(){
+				uni.navigateTo({
+					url:'/pages/maintenance/maintainOrder/index',
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	.index {
+		background-color: #FFFFFF;
+	}
+	.content_box {
+		background: #FFFFFF;
+	}
+</style>

+ 50 - 0
pages/maintenance/agreement/agreement.vue

@@ -0,0 +1,50 @@
+<template>
+	<view>
+		<view v-html="content" class="myView"></view>
+	</view>
+</template>
+
+<script>
+	import {
+		agreement
+	} from '@/api/maintain.js';
+	export default {
+		data() {
+			return {
+				title : '',
+				identifies : '',
+				content:''
+			}
+		},
+		methods: {
+			getAgreement(){
+				let data = {
+					identifies : this.identifies
+				}
+				agreement(data).then(res=>{
+					this.content = res.data.content
+				})
+			}
+		},
+		onLoad(option) {
+			this.title = option.title
+			this.identifies = option.identifies
+			this.getAgreement()
+		},
+		onReady() {
+			uni.setNavigationBarTitle({
+				title:this.title
+			})
+		}
+	}
+</script>
+
+<style>
+.myView{
+	width: 690rpx;
+	position: relative;
+	left: calc(50% - 345rpx);
+	margin-top: 20rpx;
+	padding-bottom: 150rpx;
+}
+</style>

+ 31 - 0
pages/maintenance/evaluate/history/detail.vue

@@ -0,0 +1,31 @@
+<template>
+	<view class="text" v-html="detail">
+	</view>
+</template>
+
+<script>
+	import {
+		getEvaluationDetail
+	} from "@/api/maintain.js"
+	export default {
+		data: function() {
+			return {
+				detail: ""
+			}
+		},
+		onLoad(options) {
+			let that = this;
+			getEvaluationDetail({
+				id: options.id
+			}).then((res) => {
+				that.detail = res.data.result;
+			})
+		}
+	}
+</script>
+
+<style>
+	.text {
+		padding: 58rpx;
+	}
+</style>

+ 183 - 0
pages/maintenance/evaluate/history/index.vue

@@ -0,0 +1,183 @@
+<template>
+	<view class="history">
+		<view class="history-card" v-for="(item, index) in dataList" :key="index">
+			<view class="header">
+				<image :src="baseImgUrl + item.carLogo" alt="">
+					<view class="title">
+						{{item.carModelName}}
+					</view>
+			</view>
+			<view class="content">
+				{{item.describes}}
+			</view>
+			<view class="history-img" v-if="item.status==1">
+				<view v-for="(items, indexs) in item.imgUrls.split(',')" :key="indexs">
+					<image v-if="items.indexOf('png'||'jpg')!= -1" :src="baseImgUrl+items" alt="">
+				</view>
+				<video v-if="item.videoUrl != ''" :src="baseImgUrl+item.videoUrl"></video>
+			</view>
+			<view class="bottom">
+				<view class="leftView">
+					<view class="history-type" :style="item.status==1?'color: #FF6000;':'color: #005CFF;'">
+						{{item.status==1?'评估中':'已评估'}}
+					</view>
+					<view class="history-time">
+						{{item.time}}
+					</view>
+				</view>
+				<view class="rightView" @click="toDetail(item.id)">
+					估价详情
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getEvaluationList
+	} from "@/api/maintain.js"
+	export default {
+		data: function() {
+			return {
+				baseImgUrl: "https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/",
+				dataList: [],
+				pageNo: 1,
+				pageSize: 20,
+			}
+		},
+		onLoad() {
+			this.getPage()
+		},
+		onReachBottom() {
+			this.getPage()
+		},
+		methods: {
+			getPage() {
+				let that = this;
+				getEvaluationList({
+					pageNo: that.pageNo,
+					pageSize: that.pageSize
+				}).then((res) => {
+					that.dataList = that.dataList.concat(res.data.rows)
+					console.log(that.dataList);
+					that.pageNo++
+				})
+			},
+			toDetail(id) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/evaluate/history/detail?id=" + id
+				});
+			}
+		},
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.history {
+		.history-card {
+			width: 650rpx;
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+			padding: 30rpx;
+
+			.header {
+				display: flex;
+
+				image {
+					width: 130rpx;
+					height: 130rpx;
+					background: #FFFFFF;
+					border: 2rpx solid #F4F4F4;
+					border-radius: 10rpx;
+				}
+
+				.title {
+					width: 455rpx;
+					font-size: 32rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					line-height: 44rpx;
+					padding-left: 32rpx;
+				}
+			}
+
+			.content {
+				height: 162rpx;
+				background: #F5F5F5;
+				border-radius: 10rpx;
+				padding: 25rpx 51rpx 32rpx 29rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 40rpx;
+				margin-top: 18rpx;
+			}
+
+			.history-img {
+				display: flex;
+				overflow-y: auto;
+
+				image {
+					width: 116rpx;
+					height: 116rpx;
+					background: #F9A9A9;
+					border-radius: 8rpx;
+					margin: 18rpx 18rpx 0 0;
+				}
+
+				video {
+					width: 116rpx;
+					height: 116rpx;
+					background: #F9A9A9;
+					border-radius: 8rpx;
+					margin: 18rpx 18rpx 0 0;
+				}
+			}
+
+			.bottom {
+				display: flex;
+				justify-content: space-between;
+
+				margin-top: 28rpx;
+
+
+				.leftView {
+					.history-type {
+						font-size: 28rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+					}
+
+					.history-time {
+						font-size: 26rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 31rpx;
+					}
+				}
+
+				.rightView {
+					width: 180rpx;
+					height: 64rpx;
+					background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+					border-radius: 32rpx;
+					font-size: 28rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FFFFFF;
+					line-height: 64rpx;
+					text-align: center;
+				}
+			}
+		}
+	}
+</style>

+ 419 - 0
pages/maintenance/evaluate/index.vue

@@ -0,0 +1,419 @@
+<template>
+	<view class="eva-body">
+		<!-- 页头step -->
+		<view class="step">
+			<view class="step1">
+				<image :src="require('../../../static/1..png')" alt="">
+					<view class="span">提交车辆故障信息</view>
+			</view>
+			<image :src="require('../../../static/tiaozhuan.png')" alt="">
+				<view class="step2">
+					<image :src="require('../../../static/2..png')" alt="">
+						<view class="span">专业师傅评估报价</view>
+				</view>
+		</view>
+		<!-- 选择车辆 -->
+		<navigator url="/pages/preCarWash/chooseCar/index" class="chooseCar">
+			<view class="carsMsg">
+				<image :src="cardMsg.brandLogo?baseImagePath+cardMsg.brandLogo: carImg" alt="">
+					<view v-if="cardMsg.brandLogo" class="carNa">
+						{{cardMsg.brandName}} {{cardMsg.carSeriesName}}
+					</view>
+					<view v-else class="carNa" style="color: #666666;">
+						{{carTitle}}
+					</view>
+			</view>
+			<image :src="require('../../../static/choose.png')" alt="">
+		</navigator>
+		<!-- 描述详情 -->
+		<view
+			style="background-color: #FFFFFF;width: 710rpx;position: relative;left: calc(50% - 355rpx);border-radius: 8px;">
+			<view class="eva-detail">
+				<textarea class="textarea" :value="textData" @input="textInput" placeholder="请输入车辆遇到的问题/状况描述"
+					placeholder-class="classTextarea" maxlength="-1"></textarea>
+			</view>
+			<!-- 上传图片 -->
+			<view class="uploadFile">
+				<view class="uploadView" v-for="(item, index) in uploadFileList" :key="index">
+					<image @click="del(index)" class="uploadDelete" :src="require('../../../static/uploadDelete.png')"
+						alt="">
+						<image class="uploadImg" :src="item" alt="">
+
+				</view>
+				<view class="uploadView">
+					<image @click="upload" class="uploadImg" :src="require('../../../static/upload-pic.png')" alt="">
+				</view>
+			</view>
+			<!-- 上传视频 -->
+			<view class="uploadFile" style="padding-bottom: 46rpx;">
+				<view class="uploadView">
+					<image v-if="videoFilePath!=''" @click="delvideo()" class="uploadDelete"
+						:src="require('../../../static/uploadDelete.png')" alt="">
+						<image v-if="videoFilePath==''" @click="chooseVideo" class="uploadImg"
+							:src="require('../../../static/upload-video.png')" alt="">
+							<video v-else class="uploadImg" :src="videoFilePath"></video>
+				</view>
+			</view>
+		</view>
+		<!-- 提交 -->
+		<view class="submit" @click="submit()">
+			提交
+		</view>
+		<!-- 历史估价记录 -->
+		<view @click="topath()" class="history">
+			历史估价记录
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getUserCar
+	} from "@/api/shop.js"
+	import {
+		setEvaluationAdd
+	} from "@/api/maintain.js"
+	export default {
+		data: function() {
+			return {
+				carImg: require("../../../static/morentu.png"),
+				carTitle: "请选择车辆",
+				carData: {
+					id: 1,
+					carImg: require("../../../static/qiche.png"),
+					carTitle: "奥迪a6l 2017款 30 fsi  技术型 fsi 技术型"
+				},
+				baseImagePath: this.baseImagePath,
+				textData: "",
+				uploadFileList: [
+
+				],
+				imgUrls: "",
+				videoUrl: "",
+				videoFilePath: "",
+				cardMsg: {}
+			}
+		},
+		onLoad() {
+			this.getUserCar()
+		},
+		onShow: function() { //option为object类型,会序列化上个页面传递的参数
+			let that = this;
+			uni.$on('chooseCar', function(data) {
+				that.cardMsg = data;
+			})
+		},
+		methods: {
+			getUserCar() {
+				console.log('-------------------------------------------------------------');
+				getUserCar().then(res => {
+					console.log(res, '返回');
+					this.cardMsg = res.data;
+				})
+			},
+			textInput(e) {
+				this.textData = e.detail.value;
+			},
+			topath() {
+				this.$yrouter.push({
+					path: "/pages/maintenance/evaluate/history/index"
+				});
+
+			},
+			submit() {
+				if (!this.carData.id) {
+					uni.showToast({
+						icon: "none",
+						title: '请选择您的车辆'
+					})
+				} else if (!this.textData) {
+					uni.showToast({
+						icon: "none",
+						title: '请输入估计内容'
+					})
+				} else if (!this.imgUrls) {
+					uni.showToast({
+						icon: "none",
+						title: '请输至少上传一张图片'
+					})
+				} else {
+					setEvaluationAdd({
+						carId: this.carData.id,
+						describes: this.textData,
+						imgUrls: this.imgUrls,
+						videoUrl: this.videoUrl
+					}).then(res => {
+						if (res.code == "00000") {
+							uni.showToast({
+								title: '预约成功',
+								icon: 'none',
+								duration: 3000
+							});
+							setTimeout(res => {
+								uni.navigateBack({
+									delta: 1 //返回两层页面
+								});
+							}, 3000)
+						}
+					})
+				}
+
+			},
+			upload() {
+				let that = this;
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					loop: true,
+					success: res => {
+						if (res.tempFilePaths.length != 0) {
+							this.uploadFileList.push(res.tempFilePaths[0]);
+						}
+						var tempFilePaths = res.tempFilePaths;
+						var tempFiles = res.tempFiles;
+						uni.uploadFile({
+							url: 'https://api.biaodianfuhao.net/api/common/sysFileInfo/upload',
+							fileType: 'image',
+							filePath: tempFilePaths[0],
+							file: tempFiles[0],
+							name: 'file',
+							success: uploadFileRes => {
+								let uploadRes = JSON.parse(uploadFileRes.data);
+								if (that.imgUrls == "") {
+									that.imgUrls = uploadRes.data;
+								} else {
+									that.imgUrls = that.imgUrls + "," + uploadRes.data
+								}
+
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			},
+			chooseVideo() {
+				let that = this;
+				// 上传视频
+				uni.chooseVideo({
+					maxDuration: 60,
+					count: 1,
+					camera: 'back',
+					sourceType: ['album', 'camera'],
+					success: (responent) => {
+						this.videoFilePath = responent.tempFilePath;
+						let videoFile = responent.tempFile;
+						uni.uploadFile({
+							url: 'https://api.biaodianfuhao.net/api/common/sysFileInfo/upload',
+							fileType: 'video',
+							filePath: this.videoFilePath,
+							file: videoFile,
+							name: 'file',
+							success: uploadFileRes => {
+								let uploadRes = JSON.parse(uploadFileRes.data);
+								that.videoUrl = uploadRes.data;
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						// this.src = responent.tempFilePath;  //头条
+					}
+				})
+			},
+
+			// 删除图片
+			del(index) {
+				this.uploadFileList.splice(index, 1);
+				console.log(this.uploadFileList);
+			},
+			delvideo() {
+				this.videoFilePath = "";
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.history {
+		width: 600rpx;
+		height: 90rpx;
+		background: #FFFFFF;
+		border: 1px solid #0063FF;
+		border-radius: 45rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #0063FF;
+		text-align: center;
+		line-height: 90rpx;
+		margin: 50rpx 75rpx 0 75rpx;
+	}
+
+	.submit {
+		width: 600rpx;
+		height: 90rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 45rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FFFFFF;
+		text-align: center;
+		line-height: 90rpx;
+		margin: 60rpx 75rpx 0 75rpx;
+
+	}
+
+	.uploadFile {
+		width: 630rpx;
+		height: 146rpx;
+		display: flex;
+		background: #ffffff;
+		overflow-x: auto;
+		padding: 0 40rpx 21rpx 40rpx;
+
+		.uploadView {
+			position: relative;
+
+			.uploadImg {
+				width: 146rpx;
+				height: 146rpx;
+				background: #FFFFFF;
+				border-radius: 8px;
+				margin-right: 17rpx;
+				margin-bottom: 21rpx;
+			}
+
+			.uploadDelete {
+				width: 26rpx;
+				height: 26rpx;
+				border-radius: 0 8px 0 0;
+				position: absolute;
+				top: 0;
+				right: 17rpx;
+				z-index: 9;
+			}
+		}
+
+	}
+
+	.eva-body {
+		.step {
+			width: 100%;
+			height: 70rpx;
+			background: #E9F3FF;
+			display: flex;
+			justify-content: space-around;
+			align-items: center;
+
+			.step1 {
+				display: flex;
+				align-items: baseline;
+
+				image {
+					width: 24rpx;
+					height: 27rpx;
+				}
+
+				.span {
+					margin-left: 14rpx;
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #006AFF;
+					line-height: 31rpx;
+				}
+			}
+
+			image {
+				width: 11rpx;
+				height: 19rpx;
+			}
+
+			.step2 {
+				display: flex;
+				align-items: baseline;
+
+				image {
+					width: 24rpx;
+					height: 27rpx;
+				}
+
+				.span {
+					margin-left: 14rpx;
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #006AFF;
+					line-height: 31rpx;
+				}
+			}
+		}
+	}
+
+	.chooseCar {
+		width: 710rpx;
+		height: 170rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 15rpx;
+		margin-left: 20rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+
+		.carsMsg {
+			display: flex;
+			align-items: center;
+
+			image {
+				width: 118rpx;
+				height: 118rpx;
+				padding-left: 26rpx;
+			}
+
+			.carNa {
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 42rpx;
+				padding: 0 33rpx 0 33rpx;
+			}
+		}
+
+		image {
+			width: 15rpx;
+			height: 27rpx;
+			padding-right: 28rpx;
+		}
+	}
+
+	.eva-detail {
+		width: 710rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx 10rpx 0 0;
+		margin: 20rpx 20rpx 0 0rpx;
+
+		.textarea {
+			width: 630rpx;
+			height: 150rpx;
+			padding: 40rpx;
+		}
+	}
+
+	.classTextarea {
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #BFBFBF;
+		line-height: 34rpx
+	}
+</style>

+ 147 - 0
pages/maintenance/expensesList/expensesList.vue

@@ -0,0 +1,147 @@
+<template>
+	<view>
+		<view class="payList">
+			<uni-table border stripe emptyText="暂无更多数据" >
+				<uni-tr>
+					<uni-th align="center" width="80">维修项目/配件</uni-th>
+					<uni-th align="center" width="30">数量</uni-th>
+					<uni-th align="center" width="30">单价</uni-th>
+					<uni-th align="center" width="30">工时费</uni-th>
+					<uni-th align="center" width="30">总计</uni-th>
+					<uni-th align="center" width="30">实收</uni-th>
+				</uni-tr>
+				<uni-tr v-for="(item,index) in tableList" :key="index">
+					<uni-td align="center">{{item.goodsName}}</uni-td>
+					<uni-td align="center">{{item.num}}</uni-td>
+					<uni-td align="center">{{item.unitPrice}}</uni-td>
+					<uni-td align="center">{{item.hourPrice}}</uni-td>
+					<uni-td align="center">{{item.sumPrice}}</uni-td>
+					<uni-td align="center">{{item.payPrice}}</uni-td>
+				</uni-tr>
+			</uni-table>
+			<view class="dataBlock">
+				<view class="payInfo">
+					<view class="payTitle">合计费用</view>
+					<view class="payPrice">¥{{payList.payNum || 0}}</view>
+				</view>
+				<view class="payInfo">
+					<view class="payTitle">优惠费用</view>
+					<view class="payPrice">-¥{{payList.discountPrice || 0}}</view>
+				</view>
+				<view class="payInfo">
+					<view class="payTitle">实际支付</view>
+					<view class="paySure">¥{{payList.payPrice}}</view>
+				</view>
+				<view class="payInfo">
+					<view class="payTitle">支付状态</view>
+					<view class="paySure">{{payList.payStatus==1?'已支付':payList.payStatus==2?'未支付':'已挂账'}}</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="payBtn" @click="toPay()" v-if="payStatus === 4">立即支付</view>
+	</view>
+</template>
+
+<script>
+	import {
+		orderDetail,
+		payOrder
+	} from '../../../api/maintain.js'
+	export default {
+		data() {
+			return {
+				orderId:'',
+				type:1,
+				provider:'',
+				payList:{},
+				tableList:[],
+				payStatus : ''
+			};
+		},
+		onLoad(options){
+			this.orderId = options.id
+			this.getOrderDetail()
+		},
+		methods:{
+			getOrderDetail(){
+				let data = {
+					id : this.orderId
+				}
+				orderDetail(data).then(res=>{
+					this.payList = res.data
+					this.payStatus = res.data.status
+					this.tableList = res.data.repairOrderServicesVO
+					console.log(this.payStatus);
+				})
+			},
+			toPay(){
+				let data = {
+					id:this.orderId,
+					payType:this.type,
+					payMoney:this.payList.payPrice
+				}
+				uni.navigateTo({
+					url:'/pages/shop/cashierDesk/cashierDesk?page=maintenance&params='+JSON.stringify(data)
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background-color: #F5F5F5;
+	}
+.payList{
+	width: 630rpx;
+	padding: 40rpx 30rpx;
+	position: relative;
+	left: calc(50% - 345rpx);
+	background: #FFFFFF;
+	border-radius: 10rpx;
+	margin-top: 30rpx;
+}
+.dataBlock{
+	width: 100%;
+	margin-top: 30rpx;
+	display: flex;
+	flex-direction: column;
+	.payInfo{
+		width: 100%;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-top: 30rpx;
+		.payTitle{
+			font-size: 26rpx;
+			font-weight: 500;
+			color: #666666;
+		}
+		.payPrice{
+			font-size: 26rpx;
+			font-weight: 500;
+			color: #333333;
+		}
+		.paySure{
+			font-size: 26rpx;
+			font-weight: 500;
+			color: #FE5C4A;
+		}
+	}
+}
+.payBtn{
+	width: 690rpx;
+	height: 90rpx;
+	background: linear-gradient(0deg, #0036FF 0%, #008EFF 100%);
+	border-radius: 45rpx;
+	position: relative;
+	left: calc(50% - 345rpx);
+	font-size: 32rpx;
+	font-weight: 500;
+	color: #FFFFFF;
+	line-height: 90rpx;
+	text-align: center;
+	margin-top: 180rpx;
+}
+</style>

+ 231 - 0
pages/maintenance/index.vue

@@ -0,0 +1,231 @@
+<template>
+	<view class="">
+		<!-- header -->
+		<view class="headers">
+			<view class="body" v-for="(item, index) in headerList" :key="index" @tap="routerTo(item)">
+				<image :src="item.url" style="width:103	rpx;height:105rpx">
+					<view class="title">
+						{{item.name}}
+					</view>
+			</view>
+		</view>
+		<!-- 预约服务 -->
+		<view class="serve">
+			<view class="headers">
+				<image :src="require('../../static/left.png')">
+					预约服务
+					<image :src="require('../../static/right.png')">
+			</view>
+			<view class="body">
+				<view class="card" v-for="(item, index) in serveList" :key="index" @click="toServe(item)">
+					<image :src="baseImagePath + item.imgUrl">
+				</view>
+			</view>
+		</view>
+		<!-- 推荐套餐 -->
+		<view class="setMeal">
+			<view class="headers">
+				<image :src="require('../../static/left.png')">
+					推荐套餐
+					<image :src="require('../../static/right.png')">
+			</view>
+			<SetMeal :set-meal-list="setMealList"></SetMeal>
+		</view>
+	</view>
+</template>
+
+<script>
+	import SetMeal from '@/components/SetMeal';
+	import {
+		getRepairServiceOne,
+		packageList
+	} from "@/api/maintain.js"
+	const app = getApp();
+	export default {
+		components: {
+			SetMeal
+		},
+		data() {
+			return {
+				requestData: {},
+				headerLists: "",
+				baseImagePath: this.baseImagePath,
+				// 这里url使用的本地图片,使用require后会造成路由跳转传参失败,所以暂时不使用require
+				setMealList: [],
+				serveList: [],
+				headerList: [{
+						name: "在线预约",
+						url: require("../../static/kefu.png"),
+						path: "/pages/maintenance/onlineReservation/index?page=index"
+					},
+					{
+						name: "附近门店",
+						url: require("../../static/mendian.png"),
+						path: "/pages/preCarWash/chooseShop/index?page=index"
+					},
+					{
+						name: "维修估价",
+						url: require("../../static/gujia.png"),
+						path: "/pages/maintenance/evaluate/index"
+					},
+					{
+						name: "套餐服务",
+						url: require("../../static/taocan.png"),
+						path: "/pages/maintenance/setMeal/index"
+					},
+				],
+				pageNo: 1,
+				pageSize: 10,
+				loadmore: true,
+			};
+		},
+		onBackPress(options) {
+			// 这里可以自定义返回逻辑,比如下面跳转其他页面
+			// #ifdef APP-PLUS
+			if (plus.os.name.toLowerCase() === 'android') {
+				plus.runtime.quit();
+			} else {
+				plus.runtime.quit();
+			}
+			// #endif
+			// return true 表示禁止默认返回
+			return true;
+		},
+		onReachBottom() {
+			if (this.loadmore) {
+				this.packageList();
+			}
+		},
+		onLoad(e) {
+			app.globalData.requestToken = e.token;
+			uni.setStorageSync('token', e.token)
+			let _this = this;
+			this.packageList();
+			getRepairServiceOne().then((res) => {
+				_this.serveList = res.data
+			})
+		},
+		methods: {
+			packageList() {
+				packageList({
+					pageNo: this.pageNo,
+					pageSize: this.pageSize,
+					recommend: 1,
+				}).then((res) => {
+					this.setMealList = res.data.rows;
+					if (this.setMealList.length < this.pageSize) {
+						this.loadmore = false
+					}
+					this.pageNo++
+				})
+			},
+			// 路由跳转
+			routerTo(item) {
+				uni.removeStorageSync('chooseCar')
+				uni.removeStorageSync('chooseShop')
+				if (item.path) {
+					this.$yrouter.push({
+						path: item.path
+					});
+				}
+			},
+			toServe(item) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/servicesAvailable/index?item=" + encodeURIComponent(JSON.stringify(
+						item))
+				});
+			}
+		},
+	}
+</script>
+
+<style lang="less">
+	.headers {
+		width: 750rpx;
+		height: 208rpx;
+		display: flex;
+		justify-content: space-around;
+		align-items: center;
+
+		.body {
+			width: 110rpx;
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+
+			image {
+				width: 103rpx;
+				height: 104rpx;
+			}
+
+			.title {
+				height: 23rpx;
+				font-size: 24rpx;
+				font-weight: 500;
+				color: #333333;
+			}
+		}
+	}
+
+	.serve {
+		width: 100%;
+		height: 354rpx;
+		background-image: url(../../static/yuyue-bg.png);
+		background-size: 100% 100%;
+		padding-top: 36rpx;
+
+		.headers {
+			width: 227rpx;
+			height: 31rpx;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #333333;
+			line-height: 36rpx;
+			margin: auto;
+
+			image {
+				width: 31rpx;
+				height: 31rpx;
+			}
+		}
+
+		.body {
+			display: flex;
+			flex-wrap: wrap;
+			justify-content: space-around;
+			margin-top: 30rpx;
+
+			.card {
+				width: 220rpx;
+				height: 107rpx;
+				margin-top: 16rpx;
+
+				image {
+					width: 100%;
+					height: 100%;
+				}
+			}
+		}
+	}
+
+	.setMeal {
+		padding-top: 36rpx;
+
+		.headers {
+			width: 227rpx;
+			height: 31rpx;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #333333;
+			line-height: 36rpx;
+			margin: auto;
+
+			image {
+				width: 31rpx;
+				height: 31rpx;
+			}
+		}
+	}
+</style>

+ 558 - 0
pages/maintenance/maintainOrder/deliveryOfVehicle/index.vue

@@ -0,0 +1,558 @@
+<template>
+	<view class="deliveryOfVehicle">
+		<view class="contentView">
+			<view class="row">
+				<view class="title">
+					接车人员
+				</view>
+				<view class="content">
+					{{orderData.getName}}
+				</view>
+			</view>
+			<view class="row">
+				<view class="title">
+					联系电话
+				</view>
+				<view class="content">
+					{{orderData.getPhone}}
+				</view>
+			</view>
+		</view>
+		<view class="videoBody">
+			<view class="title">
+				全车视频
+			</view>
+			<image @click="chooseVideo" v-if="videoFilePath==''" :src="require('../../../../static/addVideo.png')"
+				alt="">
+				<view v-else class="videos">
+					<image @click="delvideo()" class="uploadDelete"
+						:src="require('../../../../static/uploadDelete.png')" alt="">
+						<video class="uploadImg" :src="baseImagePath+videoFilePath"></video>
+				</view>
+		</view>
+		<view class="upuploadImage">
+			<view class="imgView" v-for="(item, index) in imgList" :key="index">
+				<image @click="upload(index)" v-if="item.url==''" :src="item.imgBg" alt="">
+					<view v-else class="imgs">
+						<image @click="del(index)" class="uploadDelete"
+							:src="require('../../../../static/uploadDelete.png')" alt="">
+							<image class="uploadImg" :src="baseImagePath+item.url" alt="">
+					</view>
+					<view class="unit">
+						<span>*</span>{{item.title}}
+					</view>
+			</view>
+		</view>
+		<view class="otherImg">
+			<view class="imgView" v-for="(item, index) in otherImg" :key="index">
+				<image @click="uploadOther(index)" v-if="item.url==''" :src="require('../../../../static/other.png')"
+					alt="">
+					<view v-else class="imgs">
+						<image @click="delOther(index)" class="uploadDelete"
+							:src="require('../../../../static/uploadDelete.png')" alt="">
+							<image class="uploadImg" :src="baseImagePath+item.url" alt="">
+					</view>
+					<view class="unit">
+						{{item.title}}
+					</view>
+			</view>
+		</view>
+		<view style="height: 218rpx;">
+
+		</view>
+		<view class="buttom">
+			<view class="buttomBtn" @click="delivery">
+				确认提车
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		repairGetCar
+	} from "@/api/maintain.js"
+	export default {
+		components: {},
+		data() {
+			return {
+				baseImagePath: this.baseImagePath,
+				otherImg: [{
+					url: "",
+					title: "其他1"
+				}],
+				imgList: [{
+						title: "左前方",
+						imgBg: require("../../../../static/zuoqianfang.png"),
+						url: "",
+					},
+					{
+						title: "左后方",
+						imgBg: require("../../../../static/zuohoufang.png"),
+						url: "",
+					},
+					{
+						title: "右前方",
+						imgBg: require("../../../../static/youqian.png"),
+						url: "",
+					},
+					{
+						title: "右后方",
+						imgBg: require("../../../../static/youhou.png"),
+						url: "",
+					},
+					{
+						title: "里程表",
+						imgBg: require("../../../../static/lichengbiao.png"),
+						url: "",
+					},
+					{
+						title: "交强险保单",
+						imgBg: require("../../../../static/jiaoqiangxian.png"),
+						url: "",
+					},
+					{
+						title: "行驶证",
+						imgBg: require("../../../../static/xingshizheng.png"),
+						url: "",
+					},
+				],
+				videoFilePath: "",
+				orderData: {},
+				carVideo: "",
+			}
+		},
+		onLoad(options) {
+			this.orderData = JSON.parse(decodeURIComponent(options.data));
+		},
+		methods: {
+			delivery() {
+				if (this.imgList[0].url == "") {
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传车辆左前方图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}else if(this.imgList[1].url == ""){
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传车辆左后方图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}else if(this.imgList[2].url == ""){
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传车辆右前方图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}else if(this.imgList[3].url == ""){
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传车辆右后方图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}else if(this.imgList[4].url == ""){
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传车辆里程表图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}else if(this.imgList[5].url == ""){
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传交强险保单图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}else if(this.imgList[6].url == ""){
+					uni.showModal({
+						title: '提示',
+						showCancel:false,
+						content: '请上传车辆行驶证图片',
+						success() {},
+						complete() {
+						}
+					});
+					return;
+				}
+				for (let index in this.otherImg) {
+					if (this.carVideo == "") {
+						this.carVideo = this.otherImg[index].url
+					} else {
+						this.carVideo = this.carVideo + "," + this.otherImg[index].url
+					}
+				}
+				let data = {
+					orderId: this.orderData.id,
+					leftAnterior: this.imgList[0].url,
+					leftRear: this.imgList[1].url,
+					rightAnterior: this.imgList[2].url,
+					rightRear: this.imgList[3].url,
+					odometer: this.imgList[4].url,
+					guaranteeSlip: this.imgList[5].url,
+					drivingLicense: this.imgList[6].url,
+					carVideo: this.carVideo,
+					others: this.videoFilePath
+				}
+				repairGetCar(data).then((res) => {
+					if (res.code == "00000") {
+						uni.navigateBack({
+							delta: 1
+						})
+						uni.$emit('deliveryOver', {
+							data: "提车成功"
+						})
+					}
+				})
+			},
+			uploadOther(index) {
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					loop: true,
+					success: res => {
+						console.log(res);
+						var tempFilePaths = res.tempFilePaths;
+						var tempFiles = res.tempFiles;
+						console.log(tempFilePaths);
+						console.log(tempFilePaths[0]);
+						uni.uploadFile({
+							url: 'https://api.biaodianfuhao.net/api/common/sysFileInfo/upload',
+							fileType: 'image',
+							filePath: tempFilePaths[0],
+							file: tempFiles[0],
+							name: 'file',
+							success: uploadFileRes => {
+								console.log('上传图片', JSON.parse(uploadFileRes.data));
+								this.otherImg[index].url = JSON.parse(uploadFileRes.data).data;
+								if (this.otherImg.length < 4) {
+									this.otherImg.push({
+										url: "",
+										title: "其他" + (parseInt(index) + 2)
+									})
+								}
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			},
+			delOther(index) {
+				this.otherImg.splice(index, 1);
+				this.otherImg.forEach((res, index) => {
+					this.otherImg[index].title = "其他" + (index + 1)
+				})
+				if (this.otherImg.length < 4) {
+					this.otherImg.push({
+						url: "",
+						title: "其他" + (this.otherImg.length + 1)
+					})
+				}
+			},
+			upload(index) {
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					loop: true,
+					success: res => {
+						console.log(res);
+						var tempFilePaths = res.tempFilePaths;
+						var tempFiles = res.tempFiles;
+						console.log(tempFilePaths);
+						console.log(tempFilePaths[0]);
+						uni.uploadFile({
+							url: 'https://api.biaodianfuhao.net/api/common/sysFileInfo/upload',
+							fileType: 'image',
+							filePath: tempFilePaths[0],
+							file: tempFiles[0],
+							name: 'file',
+							success: uploadFileRes => {
+								console.log('上传图片', JSON.parse(uploadFileRes.data));
+								this.imgList[index].url = JSON.parse(uploadFileRes.data).data;
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			},
+			del(index) {
+				this.imgList[index].url = "";
+			},
+			chooseVideo() {
+				// 上传视频
+				uni.chooseVideo({
+					maxDuration: 60,
+					count: 1,
+					camera: 'back',
+					sourceType: ['album', 'camera'],
+					success: (responent) => {
+
+						let videoFile = responent.tempFile;
+						uni.uploadFile({
+							url: 'https://api.biaodianfuhao.net/api/common/sysFileInfo/upload',
+							fileType: 'video',
+							filePath: responent.tempFilePath,
+							file: videoFile,
+							name: 'file',
+							success: uploadFileRes => {
+								console.log('上传图片', JSON.parse(uploadFileRes.data));
+								this.videoFilePath = JSON.parse(uploadFileRes.data).data;
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+						// this.src = responent.tempFilePath;  //头条
+					}
+				})
+			},
+			delvideo() {
+				this.videoFilePath = "";
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.buttom {
+		width: 100%;
+		height: 170rpx;
+		background: #FFFFFF;
+		position: fixed;
+		bottom: 0;
+
+		.buttomBtn {
+			width: 690rpx;
+			height: 90rpx;
+			background: linear-gradient(0deg, #008EFF 0%, #0036FF 100%);
+			border-radius: 45rpx;
+			margin: 30rpx;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			line-height: 90rpx;
+			text-align: center;
+		}
+	}
+
+	.otherImg {
+		width: 710rpx;
+		height: 254rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 20rpx;
+		display: flex;
+		align-items: center;
+		overflow-x: auto;
+
+		.imgView {
+			padding-left: 25rpx;
+
+			image {
+				width: 150rpx;
+				height: 150rpx;
+			}
+
+			.imgs {
+				position: relative;
+
+				.uploadImg {
+					width: 150rpx;
+					height: 150rpx;
+					border-radius: 10rpx;
+				}
+
+				.uploadDelete {
+					width: 26rpx;
+					height: 26rpx;
+					border-radius: 0 8px 0 0;
+					position: absolute;
+					top: 0;
+					right: 0;
+					z-index: 9;
+				}
+
+
+			}
+
+			.unit {
+				font-size: 24rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 24rpx;
+				text-align: center;
+			}
+		}
+	}
+
+	.upuploadImage {
+		width: 710rpx;
+		height: 490rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 20rpx;
+		display: flex;
+		flex-wrap: wrap;
+		align-items: center;
+
+		.imgView {
+			padding-left: 25rpx;
+
+			image {
+				width: 150rpx;
+				height: 150rpx;
+			}
+
+			.imgs {
+				position: relative;
+
+				.uploadImg {
+					width: 150rpx;
+					height: 150rpx;
+					border-radius: 10rpx;
+				}
+
+				.uploadDelete {
+					width: 26rpx;
+					height: 26rpx;
+					border-radius: 0 8px 0 0;
+					position: absolute;
+					top: 0;
+					right: 0;
+					z-index: 9;
+				}
+
+
+			}
+
+			.unit {
+				font-size: 24rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 24rpx;
+				text-align: center;
+
+				span {
+					color: #FF5400;
+				}
+			}
+		}
+
+	}
+
+	.contentView {
+		width: 710rpx;
+		height: 210rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 20rpx;
+
+		.row {
+			height: 100rpx;
+			display: flex;
+			align-items: center;
+			margin: 0 30rpx 0 30rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 55rpx;
+			}
+
+			.content {
+				padding-left: 74rpx;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 55rpx;
+			}
+		}
+	}
+
+	.videoBody {
+		margin: 20rpx;
+		width: 710rpx;
+		height: 196rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		display: flex;
+		justify-content: space-between;
+
+		.title {
+			font-size: 28rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #666666;
+			line-height: 31rpx;
+			padding: 30rpx 0 0 28rpx;
+		}
+
+		image {
+			width: 150rpx;
+			height: 150rpx;
+			margin: 23rpx 25rpx 23rpx 0;
+		}
+
+		.videos {
+			position: relative;
+
+			.uploadDelete {
+				width: 26rpx;
+				height: 26rpx;
+				border-radius: 0 8px 0 0;
+				position: absolute;
+				top: -18rpx;
+				right: -6rpx;
+				z-index: 9;
+			}
+
+			.uploadImg {
+				width: 150rpx;
+				height: 150rpx;
+				background: #FFFFFF;
+				border-radius: 8px;
+				margin-right: 17rpx;
+				margin-bottom: 21rpx;
+			}
+		}
+	}
+</style>

+ 181 - 0
pages/maintenance/maintainOrder/flow/index.vue

@@ -0,0 +1,181 @@
+<template>
+	<view>
+		<view class="flow" style="display: flex;" v-for="(item, index) in logListData" :key="index">
+			<view class="steps">
+				<view class="steps_list">
+					<view :class="index==0?'tails':'active-tails'"></view>
+					<view class="node">
+						<view class="active-node">
+
+						</view>
+					</view>
+					<view v-if="(index+1)<logListData.length" class="tail"
+						:class="{'active-tail':parseInt(item.id)-1 == item.index}" :hidden="item.index == 0">
+					</view>
+				</view>
+
+			</view>
+			<view class="wrapper">
+				<view class="title">
+					<text>{{item.name}}</text>
+				</view>
+				<view class="time">
+					<span>{{item.timeMessage}}</span>
+				</view>
+			</view>
+		</view>
+
+	</view>
+
+</template>
+
+<script>
+	/*
+	item:没条记录详情
+	activity: 当前进度条状态
+	wrapperStatus:流程状态对应字段
+	wrapperTitle:详情对应字段
+	index:进度条排列序号 index == 0代表最后一个没有竖立进度条
+	date:时间
+	 */
+	import {
+		logList
+	} from "@/api/maintain.js"
+	export default {
+		data() {
+			return {
+				detail: [{
+						activity: 0,
+						logType: 1,
+						createTime: "2021.07.01 20:00",
+					},
+					{
+						activity: 1,
+						logType: 2,
+						createTime: "2021.07.01 20:00",
+					},
+					{
+						activity: 2,
+						logType: 3,
+						createTime: "2021.07.01 20:00",
+					},
+					{
+						activity: 3,
+						logType: 4,
+						createTime: "2021.07.01 20:00",
+					},
+					{
+						activity: 4,
+						logType: 5,
+						createTime: "2021.07.01 20:00",
+					},
+					{
+						activity: 5,
+						logType: 6,
+						createTime: "2021.07.01 20:00",
+					}
+				],
+				orderData: {},
+				logListData: [],
+			}
+		},
+		onLoad(options) {
+			this.orderData = JSON.parse(decodeURIComponent(options.data));
+			logList({
+				orderId: this.orderData.id
+			}).then((res) => {
+				this.logListData = res.data
+			})
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.flow {
+		background: #F5F5F5;
+	}
+
+	page {
+		height: 100%;
+		background: #F5F5F5;
+	}
+
+	.wrapper {
+		width: 605rpx;
+		height: 138rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 46rpx 46rpx 46rpx 37rpx;
+		padding: 33rpx;
+
+		.title {
+			font-weight: bold;
+			font-size: 26rpx;
+		}
+
+		.time {
+			padding-top: 20rpx;
+			font-size: 26rpx;
+			color: #333;
+		}
+	}
+
+	.steps {
+		display: flex;
+
+		.steps_list {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			// padding: 0 0 0 5px;
+			// padding: 0 0 40rpx;
+			margin-left: 54rpx;
+			// height: 160rpx;
+		}
+
+		.active-tails {
+			height: 118rpx;
+			width: 2rpx;
+			background: #E8E7E7;
+		}
+
+		.tails {
+			height: 118rpx;
+			width: 2rpx;
+		}
+
+		.tail {
+			height: calc(100% - 15rpx);
+			width: 2rpx;
+			background: #E8E7E7;
+		}
+
+		.active-tail {
+			width: 2rpx;
+			background-color: #F87362 !important;
+		}
+
+
+
+		.node {
+			width: 28rpx;
+			height: 28rpx;
+			background: rgba(0, 94, 255, 0.15);
+			border-radius: 50%;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			.active-node {
+				width: 14rpx;
+				height: 14rpx;
+				background: #005EFF;
+				border-radius: 50%;
+
+			}
+		}
+	}
+</style>

+ 416 - 0
pages/maintenance/maintainOrder/index.vue

@@ -0,0 +1,416 @@
+<template>
+	<view class="maintainOrder">
+		<!-- header bar -->
+		<view class="header">
+			<view class="bars">
+				<view :class="orderType == 1?'bar-select':'bar'" style="border-right: 1px solid #E6E6E6;"
+					@click="changeOrderType(1)">
+					进行中
+				</view>
+				<image v-if="orderType==1" :src="require('../../../static/sel.png')" alt="">
+			</view>
+			<view class="bars">
+				<view :class="orderType == 0?'bar-select':'bar'" style="border-right: 1px solid #E6E6E6;"
+					@click="changeOrderType(0)">
+					已取消
+				</view>
+				<image v-if="orderType==0" :src="require('../../../static/sel.png')" alt="">
+			</view>
+
+			<view class="bars">
+				<view :class="orderType == 6?'bar-select':'bar'" @click="changeOrderType(6)">
+					已完成
+				</view>
+				<image v-if="orderType==6" :src="require('../../../static/sel.png')" alt="">
+			</view>
+		</view>
+		<view style="height: 86rpx;"></view>
+		<!-- 搜索 -->
+		<view class="search">
+			<view v-if="!search" @click="search = true">
+				<image :src="require('../../../static/search.png')" class="searchIcon" alt="">
+				<view class="search-text">
+					搜索订单
+				</view>
+			</view>
+			
+			<input type="text" placeholder="请输入" confirm-type="search" v-model="searchTerm" @confirm="getListData(1)" @blur="noSearch()" focus v-else style="width: 80%;"/>
+		</view>
+		<!-- 订单 -->
+		<view class="order" v-for="(item, index) in dataList" :key="index" @click="toPaths(item)">
+			<view class="order-header">
+				<view class="orderId">
+					订单号:{{item.number}}
+				</view>
+				<view class="orderType" :style="item.status==0?'color: #666666':''">
+					{{item.status==1?'待服务':item.status==2?'提车中':item.status==3?'作业中':item.status==4 && item.payStatus==2?'作业完成待支付':item.status==4 && item.payStatus==3?'已完成(已挂帐)':item.status==5?'作业完成已支付':item.status==6?'已完成':'已取消'}}
+					<image :src="require('../../../static/choose.png')" alt="">
+				</view>
+			</view>
+			<view class="carView">
+				<image :src="baseImagePath+item.carLogo" alt="">
+					<view class="carBody">
+						<view class="carTitle">
+							<image :src="require('../../../static/car.png')" alt="">
+								<span>{{item.carNumber}}</span>
+								<view class="border"></view>
+								<span>{{item.carMadelLevel}}</span>
+						</view>
+						<view class="content">
+							{{item.carTypeName}}
+						</view>
+					</view>
+			</view>
+			<view class="buttom">
+				<view class="orderTime">
+					{{item.time}}
+				</view>
+				<view @click.stop="onStatus(item)" class="orderBtn"
+					:style="item.status==1?'background: #FFFFFF;border: 1px solid #ADADAD;color: #999999;':item.status==5?'background: #FFFFFF;color: #005EFF;border: 1px solid #005EFF;':''"
+					v-if="item.status!=0 && item.status!=3 && item.isEvaluate == 2">
+					{{item.status==1?'取消':item.status==2?'提车确认':item.status==3?'作业直播':item.status==4?'支付费用':item.isEvaluate ==2?'评价':''}}
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		repairOrderList,
+		cancelOrder,
+		orderEvaluate
+	} from "@/api/maintain.js"
+	const app = getApp();
+	export default {
+		components: {},
+		data() {
+			return {
+				baseImagePath: this.baseImagePath,
+				orderType: 1,
+				dataList: [],
+				searchTerm: "",
+				pageNo: 1,
+				pageSize: 20,
+				search:false
+			}
+		},
+		onShow: function() { //option为object类型,会序列化上个页面传递的参数
+			this.pageNo = 1
+			this.getListData(1);
+			let that = this
+			uni.$on('maintainEvaluateOver', function(data) {
+				uni.showToast({
+					title: data.data,
+					icon: "none",
+					duration: 1500
+				});
+				console.log(data.data);
+			})
+			uni.$on('deliveryOver', function(data) {
+				uni.showToast({
+					title: data.data,
+					icon: "none",
+					duration: 1500
+				});
+				console.log(data.data);
+			})
+		},
+		onLoad(e) {
+			app.globalData.requestToken = e.token;
+			uni.setStorageSync('token',e.token)
+		},
+		watch: {
+			orderType(val) {
+				this.pageNo = 1;
+				this.getListData(1);
+			}
+		},
+		onReachBottom() {
+			this.pageNo++
+			this.getListData()
+		},
+		onBackPress(options) {
+			console.log('11111');
+			// 这里可以自定义返回逻辑,比如下面跳转其他页面
+			// #ifdef APP-PLUS
+			if (plus.os.name.toLowerCase() === 'android') {
+				plus.runtime.quit();
+			} else {
+				plus.runtime.quit();
+			}
+			// #endif
+			// return true 表示禁止默认返回
+			return true;
+		},
+		methods: {
+			noSearch(){
+				if(!this.searchTerm){
+					this.search = false
+				}
+				this.getListData(1)
+				
+			},
+			changeOrderType(val) {
+				this.orderType = val;
+			},
+			getListData(val) {
+				let that = this;
+				if(!this.searchTerm){
+					this.search = false
+				}
+				console.log(this.orderType);
+				repairOrderList({
+					pageNo: that.pageNo,
+					pageSize: that.pageSize,
+					status: this.orderType,
+					searchTerm: this.searchTerm
+				}).then((res) => {
+					if (val == 1) {
+						that.dataList = [];
+					}
+					that.dataList = that.dataList.concat(res.data.rows)
+					console.log('dataList参数',this.dataList);
+				})
+			},
+			onStatus(item) {
+			
+				
+				let that = this;
+				if (item.status == 2) {
+					this.$yrouter.push({
+						path: "/pages/maintenance/maintainOrder/deliveryOfVehicle/index?data=" +
+							encodeURIComponent(JSON.stringify(item))
+					});
+				} else if (item.status == 1) {
+					cancelOrder({
+						id: item.id
+					}).then((res) => {
+						this.pageNo = 1
+						that.getListData(1)
+					})
+				}else if(item.status == 4){
+					this.$yrouter.push({
+						path: "/pages/maintenance/expensesList/expensesList?id=" + item.id
+					});
+				} else if (item.status == 5 || item.status == 6) {
+					this.$yrouter.push({
+						path: "/pages/preCarWash/washOrder/serviceEvaluation/index?type=" + 1 + "&detailId=" + item
+							.id
+					});
+				}
+			},
+			toPaths(item) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/maintainOrder/orderDetail/index?data=" + encodeURIComponent(JSON
+						.stringify(item))
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.maintainOrder {
+		.header {
+			display: flex;
+			align-items: center;
+			width: 100%;
+			height: 86rpx;
+			background: #FFFFFF;
+			position: fixed;
+			top: 0;
+			z-index: 999;
+			.bars {
+				width: 33%;
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				justify-content: center;
+				background-color: #FFFFFF;
+				
+				image {
+					width: 34rpx;
+					height: 11rpx;
+				}
+
+				.bar-select {
+					width: 100%;
+					height: 30rpx;
+					text-align: center;
+					font-size: 28rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					line-height: 31rpx;
+
+				}
+
+				.bar {
+					width: 100%;
+					height: 30rpx;
+					text-align: center;
+					font-size: 28rpx;
+					font-family: PingFang SC;
+					font-weight: 400;
+					color: #666666;
+					line-height: 31rpx;
+				}
+			}
+
+		}
+
+		.search {
+			width: 690rpx;
+			height: 65rpx;
+			background: #FFFFFF;
+			border-radius: 32rpx;
+			margin: 30rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			view{
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				.searchIcon {
+					width: 25rpx;
+					height: 25rpx;
+				}
+				
+				.search-text {
+					padding-left: 15rpx;
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+				}
+			}
+			
+		}
+
+		.order {
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+			padding: 30rpx;
+
+			.order-header {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				border-bottom: 1px solid #EEEEEE;
+				padding-bottom: 30rpx;
+
+				.orderId {
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+					line-height: 34rpx;
+				}
+
+				.orderType {
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #005BFF;
+					line-height: 34rpx;
+
+					image {
+						width: 11rpx;
+						height: 18rpx;
+						margin-left: 9rpx;
+					}
+				}
+			}
+
+			.carView {
+				display: flex;
+				border-bottom: 1px solid #EEEEEE;
+				align-items: center;
+				justify-content: s;
+				padding: 20rpx 0;
+				image {
+					width: 120rpx;
+					height: 120rpx;
+					background: #FFFFFF;
+					border: 2px solid #F4F4F4;
+					border-radius: 8rpx;
+				}
+
+				.carBody {
+					padding: 32rpx;
+					height: 100%;
+					display: flex;
+					align-items: center;
+					flex-direction: column;
+					.carTitle {
+						display: flex;
+						align-items: center;
+						margin-bottom: 20rpx;
+						image {
+							width: 33rpx;
+							height: 27rpx;
+							margin-top: 0rpx;
+						}
+
+						.border {
+							width: 1px;
+							height: 20rpx;
+							background: #DBDBDB;
+						}
+
+						span {
+							font-size: 30rpx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #333333;
+							padding: 0 15rpx 0 15rpx;
+						}
+					}
+
+					.content {
+						font-size: 26rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						// padding: 20rpx 60rpx 20rpx 0;
+					}
+				}
+			}
+
+			.buttom {
+				padding-top: 30rpx;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+
+				.orderTime {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 34rpx;
+				}
+
+				.orderBtn {
+					width: 156rpx;
+					height: 56rpx;
+					text-align: center;
+					background: linear-gradient(0deg, #008EFF 0%, #0036FF 100%);
+					border-radius: 28rpx;
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FFFFFF;
+					line-height: 56rpx;
+				}
+			}
+		}
+	}
+</style>

+ 483 - 0
pages/maintenance/maintainOrder/orderDetail/index.vue

@@ -0,0 +1,483 @@
+<template>
+	<view class="orderDetail">
+		<view class="orderHeader">
+			<!-- 手机状态栏占位 -->
+			<view class="statusBar" :style="{height:statusBarHeight+'rpx'}"></view>
+			<!-- 导航栏 -->
+			<view class="navigationBar" :style="{height:navigationBarHeight,paddingTop:statusBarHeight+'rpx'}">
+				<view @tap="goBack">
+					<image :src="require('../../../../static/backw.png')" alt="">
+				</view>
+
+				<view class="navigationTitle">
+					订单详情
+				</view>
+			</view>
+			<view class="headerBody" @click="toPath">
+				<view>
+					<view class="serveBody">
+						<image :src="require('../../../../static/che.png')" alt="">
+						<view class="serveTitle">
+							{{orderData.status==1?'待服务':orderData.status==2?'提车中':orderData.status==3?'作业中':orderData.status==4?'作业完成待支付':orderData.status==5?'作业完成已支付':orderData.status==6?'已完成':'已取消'}}
+						</view>
+					</view>
+					<view class="reserve">
+						预约时间:{{orderData.time}}
+					</view>
+				</view>
+				<image class="more" :src="require('../../../../static/more-w.png')" alt="">
+			</view>
+
+		</view>
+		<view class="orderBody">
+			<view class="orderDetail">
+				<view class="carHeader">
+					预约信息
+				</view>
+				<view class="carView">
+					<image :src="baseImagePath+orderData.carLogo" alt="">
+					<view class="carBody">
+						<view class="carTitle">
+							<image :src="require('../../../../static/car.png')" alt="">
+							<span>{{orderData.carNumber}}</span>
+							<view class="border"></view>
+							<span>{{orderData.carMadelLevel}}</span>
+						</view>
+						<view class="content">
+							{{orderData.carTypeName}}
+						</view>
+					</view>
+				</view>
+				<view class="shop">
+					<view>
+						服务门店:{{orderData.shopName}}
+					</view>
+
+				</view>
+				<view class="times">
+					<view>
+						服务方式:{{orderData.serviceType==1?'在店下单':'上门提车'}}
+					</view>
+				</view>
+				<view class="times" v-if="orderData.remarks">
+					<view>
+						预约备注:{{orderData.remarks}}
+					</view>
+				</view>
+			</view>
+			<view class="explain">
+				<view class="serveHeader">
+					服务项目
+				</view>
+				<view class="serveBodys" v-for="(item, index) in orderData.repairOrderServicesVO" :key="index">
+					<view class="leftView">
+						<view class="dian"></view>
+						<view class="title">
+							{{item.goodsName}}
+						</view>
+					</view>
+					<view class="rightView" v-if="item.oneName !== null">
+						{{item.oneName}}
+					</view>
+				</view>
+			</view>
+			<view style="height: 240rpx;"></view>
+		</view>
+
+		<view class="buttomBtn" v-if="orderData.status==4 || orderData.status==5 || orderData.status==6">
+			<view class="inventory" @click="toRouter(orderData.id)">
+				费用清单
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+			orderDetail
+		} from "@/api/maintain.js"
+	export default {
+		components: {},
+		data: function() {
+			return {
+				baseImagePath:this.baseImagePath,
+				serveList: [{
+						name: "常规检查",
+						subTitle: "全车48项检测",
+					},
+					{
+						name: "机械维修",
+						subTitle: "机械维修",
+					},
+					{
+						name: "常规检查",
+						subTitle: "全车48项检测",
+					},
+					{
+						name: "常规检查",
+						subTitle: "机械维修",
+					},
+				],
+				orderData: {},
+				statusBarHeight: "",
+				navigationBarHeight: "",
+				navHeight: ""
+			}
+		},
+		onLoad(options) {
+			console.log(options);
+			this.orderData = JSON.parse(decodeURIComponent(options.data));
+			orderDetail({id:this.orderData.id}).then((res)=>{
+				this.orderData= res.data;
+				console.log(this.orderData);
+			})
+			// 状态栏高度
+			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
+
+			// #ifdef MP-WEIXIN
+			// 获取微信胶囊的位置信息 width,height,top,right,left,bottom
+			const custom = wx.getMenuButtonBoundingClientRect()
+			// console.log(custom)
+			// 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
+			this.navigationBarHeight = custom.height + (custom.top - this.statusBarHeight) * 2
+
+			// console.log("导航栏高度:"+this.globalData.navigationBarHeight)
+
+			// 总体高度 = 状态栏高度 + 导航栏高度
+			this.navHeight = (this.navigationBarHeight + this.statusBarHeight)
+			this.navigationBarHeight = this.navigationBarHeight + 'px'
+			this.statusBarHeight = this.statusBarHeight + 'px'
+			this.navHeight = this.navHeight + 'px'
+
+			// #endif
+		},
+		methods: {
+			
+			goBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			toPath() {
+					this.$yrouter.push({
+						path: "/pages/maintenance/maintainOrder/flow/index?data=" + encodeURIComponent(JSON.stringify(this.orderData))
+					});
+			},
+			toRouter(id){
+				console.log(id);
+				this.$yrouter.push({
+					path:"/pages/maintenance/expensesList/expensesList?id="+id
+				})
+			}
+		},
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.buttomBtn {
+		position: fixed;
+		bottom: 0;
+		width: 750rpx;
+		height: 144rpx;
+		background: #FFFFFF;
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+
+		.deliveryOfVehicle {
+			width: 200rpx;
+			height: 70rpx;
+			background: #FFFFFF;
+			border: 1px solid #005EFF;
+			border-radius: 35rpx;
+			font-size: 28rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #005EFF;
+			line-height: 70rpx;
+			text-align: center;
+			margin-right: 20rpx;
+		}
+
+		.liveStreaming {
+			width: 200rpx;
+			height: 70rpx;
+			background: #FFFFFF;
+			border: 1px solid #005EFF;
+			border-radius: 35rpx;
+			font-size: 28rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #005EFF;
+			line-height: 70rpx;
+			text-align: center;
+			margin-right: 20rpx;
+		}
+
+		.inventory {
+			width: 200rpx;
+			height: 70rpx;
+			background: linear-gradient(0deg, #008EFF 0%, #0036FF 100%);
+			border-radius: 35rpx;
+			font-size: 28rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			line-height: 70rpx;
+			text-align: center;
+			margin-right: 20rpx;
+		}
+	}
+
+	.more {
+		width: 14rpx;
+		height: 23rpx;
+	}
+
+	.serveBodys {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 34rpx 30rpx 0 36rpx;
+
+		.leftView {
+			display: flex;
+			align-items: center;
+
+			.dian {
+				width: 6rpx;
+				height: 6rpx;
+				background: #005EFF;
+				border-radius: 50%;
+			}
+
+			.title {
+				padding-left: 10rpx;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 36rpx;
+			}
+		}
+
+		.rightView {
+			text-align: center;
+			min-width: 94rpx;
+			height: 32rpx;
+			background: #FFFFFF;
+			border: 1px solid #DBDBDB;
+			border-radius: 3rpx;
+			font-size: 18rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #999999;
+			line-height: 32rpx;
+		}
+	}
+
+	.headerBody {
+		display: flex;
+		align-items: center;
+		margin-top: 73rpx;
+		margin-left: 44rpx;
+		justify-content: space-between;
+		margin-right: 41rpx;
+	}
+
+	.orderBody {
+		position: absolute;
+		top: 358rpx;
+
+		// 
+		.orderDetail {
+			width: 710rpx;
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+
+			.carHeader {
+				padding: 38rpx 0 13rpx 31rpx;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 36rpx;
+			}
+
+			.carView {
+				display: flex;
+				padding: 26rpx;
+
+				image {
+					width: 120rpx;
+					height: 120rpx;
+					background: #FFFFFF;
+					border: 2rpx solid #F4F4F4;
+					border-radius: 8rpx;
+					padding-top: 14rpx;
+				}
+
+				.carBody {
+					padding: 14rpx 29rpx 14rpx 29rpx;
+
+					.carTitle {
+						display: flex;
+
+						image {
+							width: 33rpx;
+							height: 27rpx;
+							padding-top: 0rpx;
+						}
+
+						.border {
+							width: 1px;
+							height: 20rpx;
+							background: #DBDBDB;
+						}
+
+						span {
+							font-size: 30rpx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #333333;
+							line-height: 31rpx;
+							padding: 0 15rpx 0 15rpx;
+						}
+					}
+
+					.content {
+						font-size: 26rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 34rpx;
+						padding: 20rpx 60rpx 20rpx 0;
+					}
+				}
+			}
+
+			.shop {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				padding: 15rpx 30rpx 15rpx 30rpx;
+
+				image {
+					width: 30rpx;
+					height: 26rpx;
+				}
+			}
+
+			.times {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				margin-top: 16rpx;
+				padding-bottom: 30rpx;
+				padding: 0rpx 30rpx 15rpx 30rpx;
+
+				image {
+					width: 30rpx;
+					height: 26rpx;
+				}
+			}
+
+			.buttomBtn {
+				height: 33rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				text-align: center;
+				margin: 26rpx 31rpx 0 74%;
+			}
+		}
+
+		.explain {
+			width: 710rpx;
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+			padding-top: 11rpx;
+			padding-bottom: 40rpx;
+
+			.serveHeader {
+				padding: 38rpx 0 13rpx 31rpx;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 36rpx;
+			}
+		}
+	}
+
+	.orderHeader {
+		width: 100%;
+		height: 454rpx;
+		background: linear-gradient(90deg, #005AFF 0%, #0078FF 100%);
+
+		.navigationBar {
+			display: flex;
+			align-items: center;
+			text-align: center;
+
+			image {
+				padding-left: 17rpx;
+				width: 44rpx;
+				height: 44rpx;
+			}
+
+			.navigationTitle {
+				padding-left: 242rpx;
+				font-size: 36rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				line-height: 75rpx;
+			}
+		}
+
+		.serveBody {
+			display: flex;
+			align-items: center;
+
+			image {
+				width: 77rpx;
+				height: 38rpx;
+			}
+
+			.serveTitle {
+				font-size: 36rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				line-height: 75rpx;
+				padding-left: 20rpx;
+			}
+		}
+
+		.reserve {
+			margin-top: 27rpx;
+			font-size: 24rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			line-height: 31rpx;
+		}
+	}
+</style>

+ 863 - 0
pages/maintenance/onlineReservation/index.vue

@@ -0,0 +1,863 @@
+<template>
+	<view style="padding-bottom: 200rpx;">
+		<Card titles="服务门店" page="maintenance" :data="carShop"></Card>
+		<Card titles="预约车辆" :data="cardMsg"></Card>
+		<view class="body">
+			<view class="classHead">
+				<view class="classBorder">
+
+				</view>
+				<view class="classTitle">
+					服务预约
+				</view>
+			</view>
+			<view class="projectBody" @tap="toPage()">
+				<view class="title">
+					服务项目
+				</view>
+				<view :class="projectList.num?'projectTime':'projectNull'">
+					{{projectList.num?'已选'+projectList.num+'项':'未选择'}}
+				</view>
+				<view class="dataRight">
+					<image class="classChoose" :src="require('../../../static/choose.png')">
+				</view>
+			</view>
+			<view class="border"></view>
+			<!-- 服务项目 -->
+			<view class="projectBody">
+				<view class="title">
+					预约时间
+				</view>
+				<picker class="projectTime" :value="defaultValues" mode="multiSelector" :range="dateTimeArray"
+					@change="change" @columnchange="columnchange">
+					<view style="height: 100%;">
+						<input style="height: 100%;width: 300rpx;text-align:left" type="text" disabled="true"
+							:value="customer.time" placeholder="请选择预约时间" placeholder-class="placeholder" />
+					</view>
+				</picker>
+				<view class="dataRight">
+					<image class="classChoose" :src="require('../../../static/choose.png')">
+				</view>
+			</view>
+			<view class="border"></view>
+			<!-- 联系人 -->
+			<view class="projectBody2">
+				<view class="title">
+					联 系 人
+				</view>
+				<input type="text" v-model="customer.contacts" placeholder-class="placeholder" placeholder="请输入联系人">
+			</view>
+			<view class="border"></view>
+			<!-- 联系方式 -->
+			<view class="projectBody2">
+				<view class="title">
+					联系方式
+				</view>
+				<input type="text" v-model="customer.phone" placeholder-class="placeholder" placeholder="请输入联系方式">
+			</view>
+			<view class="border"></view>
+			<!-- </view> -->
+			<!-- 发票 -->
+			<view class="projectBody">
+				<view class="title">
+					需要发票
+				</view>
+				<radio-group @change="invoiceRadioChange">
+					<div class="radioBody">
+						<div class="radio">
+							<radio style="transform:scale(0.7)" color="#0078FF" :value="1"
+								:checked="invoiceRadioType===1" />需要
+						</div>
+						<div class="radio">
+							<radio style="transform:scale(0.7)" color="#0078FF" :value="2"
+								:checked="invoiceRadioType===2" />不需要
+						</div>
+					</div>
+				</radio-group>
+			</view>
+			<!-- 预约备注 -->
+			<view class="projectBody">
+				<view class="title">
+					预约备注
+				</view>
+				<input type="text" :value="remarks" style="margin-left:18rpx;" placeholder="请输入备注"
+					placeholder-class="placeholder" />
+			</view>
+		</view>
+
+		<button class="onLineBtn" @click="onLine">立即预约</button>
+		<view class="annotation">
+			点击立即预约即代表同意优1优5的<view class="agreement" @click="toAgreement('维修保养协议')">维修保养协议</view>
+		</view>
+		<view v-if="showPicker" class="bigMorePicker" @touchmove.stop.prevent="()=>false" @tap="closePicker">
+			<view class="morePickerCent" @tap.stop="()=>false">
+				<view class="morePickerTitle">
+					<view @tap="closePicker" style="color: #333;">取消</view>
+					<view @tap="confirmPicker" style="color:#1aa034">确认</view>
+				</view>
+				<picker-view indicator-style="height: 50px;" :value="defaultValue" @change="bindChange"
+					class="picker-view">
+					<picker-view-column>
+						<view class="item" v-for="(item,index) in oneList" :key="index">{{item.name}}</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="item" v-for="(item,index) in twoList" :key="index">{{item.name}}</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="item" v-for="(item,index) in threeList" :key="index">{{item.name}}</view>
+					</picker-view-column>
+				</picker-view>
+
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import Card from '@/components/Card';
+	import {
+		getSelectStore,
+		getUserCar,
+		getRegion
+	} from "@/api/shop.js"
+	import {
+		repairOrderAdd,
+		getShopServiceOne
+	} from "@/api/maintain.js"
+	const dateTimePicker = require('@/utils/dateTimePicker.js')
+	const app = getApp();
+	export default {
+		components: {
+			Card
+		},
+		data() {
+			return {
+				remarks: "",
+				// 时间选择器
+				dateTimeArray: null,
+				dateTime: null,
+				startYear: 2022,
+				endYear: 2150,
+				defaultValues: [0, 0, 0, 0, 0],
+				defaultValue: [0, 0, 0],
+				oneList: [],
+				twoList: [],
+				threeList: [],
+				showPicker: false,
+				modeRadioType: "0",
+				invoiceRadioType: 2,
+				projectList: {},
+				carShops: [],
+				carShops2: [],
+				carShop: {
+					url: require("../../../static/logo.png"),
+					title: "智来汽车装饰厂",
+					content: "辽宁省大连市中山区友好路236号",
+					location: "8.9km"
+				},
+				cardMsg: {
+					carId: "辽B75684",
+					carType: "辽5座轿车",
+					url: require("../../../static/logo.png"),
+					content: "奥迪a6l 2017款 30 fsi 技术型 fsi 技术型",
+				},
+				customer: {
+					time: "",
+					deliveryLocation: "",
+					detailLocation: "",
+					contacts: "",
+					phone: "",
+
+				},
+				longitude: app.globalData.longitude,
+				latitude: app.globalData.latitude,
+				provCode: "",
+				cityCode: "",
+				areaCode: "",
+				arr: "",
+				token: '',
+				pageType: '',
+				btnStatus: false
+			}
+		},
+		watch: {
+			carShop() {
+				let params = {
+					shopId: this.carShop.id,
+					type: 1,
+					shopSeviceTwoId: []
+				}
+				console.log(params);
+				let chooseList = this.projectList.chooseList
+				console.log(chooseList);
+				for (let item in chooseList) {
+					params.shopSeviceTwoId.push(chooseList[item].id)
+					console.log(params.shopSeviceTwoId);
+				}
+				let status = ''
+				getShopServiceOne(params).then((res) => {
+					console.log('店铺下服务===......7777777777777>', res);
+				}).catch(err => {
+					if (err) {
+						this.projectList.num = 0
+						this.projectList.chooseList = []
+					}
+				})
+			}
+		},
+		onLoad: async function(option) { //option为object类型,会序列化上个页面传递的参数
+			const value1 = uni.getStorageSync('shopData');
+			if (value1) {
+				console.log(value1);
+			}
+			this.carShop = value1
+			console.log('1', this.carShop);
+			console.log(option);
+			if (option.page !== "index") {
+				app.globalData.requestToken = option.token;
+				uni.setStorageSync('token', option.token)
+			}
+			this.pageType = option.type
+			let that = this;
+			this.token = uni.getStorageSync('token')
+			if (option.data) {
+				that.projectList = JSON.parse(option.data);
+			}
+			let date = new Date();
+			let year = date.getFullYear();
+			let month = date.getMonth() + 1;
+			let day = date.getDate();
+			let hour = date.getHours();
+			let minute = date.getMinutes();
+			if (month < 10) {
+				month = "0" + month;
+			}
+			if (day < 10) {
+				day = "0" + day;
+			}
+			if (hour < 10) {
+				hour = "0" + hour;
+			}
+			if (minute < 10) {
+				minute = "0" + minute;
+			}
+			this.defaultValues = [0, parseInt(month) - 1, parseInt(day), parseInt(hour), parseInt(minute)]
+			this.arr = year + '/' + month + '/' + day + ' ' + hour + ':' + minute
+			let obj = dateTimePicker.dateTimePicker(this.startYear, this.endYear, this.arr)
+			this.dateTimeArray = obj.dateTimeArray
+			this.dateTime = obj.dateTime
+			let shop = uni.getStorageSync('chooseShop')
+			console.log(this.carShop);
+			console.log(shop, 'shoopssssssssssssss');
+			if (shop) {
+				this.carShop = shop
+			} else {
+				await getSelectStore({
+					pageNo: 1,
+					pageSize: 20,
+					type: 2,
+					isRepair: 1,
+					longitude: that.longitude,
+					latitude: that.latitude
+				}).then(res => {
+					that.carShops = res.data.rows;
+					console.log(res.data.rows[0]);
+					that.carShops[0] = that.carShop;
+					console.log(that.carShops[0]);
+					let carShop1 = uni.getStorageSync('shopData')
+					console.log(carShop1);
+					if (carShop1 == "") {
+						console.log(1);
+						this.carShops2 = res.data.rows
+						console.log(this.carShops2[1]);
+						this.carShop = this.carShops2[1]
+					}
+					console.log(this.carShops2[1]);
+					// console.log(this.carShop[0]);
+					if (option.type === 'maintenance') {
+
+					} else {
+						uni.removeStorageSync('shopData')
+					}
+				})
+				uni.$on('chooseShop', function(data) {
+					that.carShop = data;
+				})
+			}
+			await getUserCar().then(res => {
+				console.log(res, 'getUserCar');
+				that.cardMsg = res.data;
+				let data = uni.getStorageSync('chooseCar')
+				if (data) {
+					console.log(data, 'car');
+					that.cardMsg = data
+				}
+			})
+			await getRegion().then(res => {
+				that.oneList = res.data;
+			})
+			await getRegion({
+				parentId: 110000
+			}).then(res => {
+				that.twoList = res.data;
+			})
+			await getRegion({
+				parentId: 110100
+			}).then(res => {
+				that.threeList = res.data;
+			})
+
+		},
+		onUnload() {
+			uni.clearStorageSync('shopData')
+		},
+		onBackPress(e) {
+			if (!this.pageType) {
+				uni.navigateTo({
+					url: "/pages/maintenance/index?token=" + this.token
+				})
+				return true
+			}
+		},
+		onShow: function() { //option为object类型,会序列化上个页面传递的参数
+			let that = this;
+			/* uni.$on('chooseShop', function(data) {
+				console.log('getCarShop',data);
+				this.carShop = data
+			}) */
+			let shop = uni.getStorageSync('chooseShop')
+			console.log(shop, 'shoopssssssssssssss');
+			if (shop) {
+				this.carShop = shop
+			}
+			// uni.$on('chooseNum', function(data) {
+			// 	that.projectList = data;
+			// })
+			/* uni.$on('chooseCar', function(data) {
+				that.cardMsg = data;
+			}) */
+
+			let data = uni.getStorageSync('chooseCar')
+			if (data) {
+				console.log(data, 'car');
+				that.cardMsg = data
+			}
+		},
+		methods: {
+			toAgreement(title) {
+				uni.navigateTo({
+					url: '/pages/maintenance/agreement/agreement?title=' + title + '&identifies=maintenance'
+				})
+			},
+			onLine() {
+				console.log('店铺信息=>', this.carShop);
+				if (this.projectList.num === 0) {
+					uni.showToast({
+						icon: 'none',
+						title: '请选择店铺服务'
+					})
+					return;
+				}
+				let serviceId = [];
+				for (let index in this.projectList.chooseList) {
+					let obj = {
+						upsId: '',
+						twoId: '',
+						type: '',
+						typeId: ''
+					}
+					console.log(this.projectList.chooseList);
+					console.log(this.projectList.chooseList[index].typeId);
+					console.log(this.projectList.chooseList[index].type);
+					obj.typeId = this.projectList.chooseList[index].typeId,
+						obj.type = this.projectList.chooseList[index].type,
+						obj.upsId = this.projectList.chooseList[index].upsId
+					serviceId.push(obj)
+					console.log(serviceId);
+					// if (this.projectList.chooseList[index].upsId) {
+					// 	obj.upsId = this.projectList.chooseList[index].upsId,
+					// 		obj.twoId = this.projectList.chooseList[index].id,
+					// 		obj.type = this.projectList.chooseList[index].type
+					// 	console.log(obj);
+					// 	serviceId.push(obj)
+					// } else {
+					// 	obj.upsId = null,
+					// 		obj.twoId = this.projectList.chooseList[index].id
+					// 	obj.type = this.projectList.chooseList[index].type
+					// 	console.log(obj);
+					// 	serviceId.push(obj)
+					// }
+				}
+				/* for (let index in this.projectList.chooseList) {
+					if (serviceId == "") {
+						serviceId = this.projectList.chooseList[index].id
+					} else {
+						serviceId = serviceId + "," + this.projectList.chooseList[index].id
+					}
+
+				}
+				/* const data = {
+					shopId: this.carShop.id,
+					carId: this.cardMsg.id,
+					shopServiceIds: serviceId,
+					serviceType: this.modeRadioType,
+					appoinTime: new Date(this.customer.time).getTime().toFixed(),
+					provCode: this.modeRadioType == 2 ? this.provCode : "",
+					cityCode: this.modeRadioType == 2 ? this.cityCode : "",
+					areaCode: this.modeRadioType == 2 ? this.areaCode : "",
+					addressDetail: this.modeRadioType == 2 ? this.customer.deliveryLocation : "",
+					contacts: this.modeRadioType == 2 ? this.customer.contacts : "aaa",
+					contactsPhone: this.modeRadioType == 2 ? this.customer.phone : "13478431332",
+					isInvoice: this.invoiceRadioType,
+					remarks: this.remarks
+				} */
+				if (!this.customer.phone) {
+					uni.showToast({
+						icon: 'none',
+						title: '请输入联系方式'
+					})
+					return;
+				}
+				if (!this.customer.time) {
+					uni.showToast({
+						icon: 'none',
+						title: '请选择预约时间'
+					})
+					return;
+				}
+				if (!this.customer.contacts) {
+					uni.showToast({
+						icon: 'none',
+						title: '请输入联系人'
+					})
+					return;
+				}
+				if (!this.customer.phone) {
+					uni.showToast({
+						icon: 'none',
+						title: '请输入联系方式'
+					})
+					return;
+				}
+				console.log(this.btnStatus, 'btnStatus');
+				if (this.btnStatus) return;
+				this.btnStatus = true
+				uni.showLoading({
+					title: '加载中'
+				})
+				const data = {
+					shopId: this.carShop.id,
+					carId: this.cardMsg.id,
+					// shopServiceIds: serviceId,
+					serviceType: 1,
+					reserveTime: new Date(this.customer.time).getTime().toFixed(),
+					provCode: this.provCode,
+					cityCode: this.cityCode,
+					areaCode: this.areaCode,
+					addressDetail: this.customer.deliveryLocation,
+					contacts: this.customer.contacts,
+					contactsPhone: this.customer.phone,
+					isInvoice: this.invoiceRadioType,
+					remarks: this.remarks,
+					serviceIds: serviceId
+				}
+				console.log('维保订单预约参数=>', data);
+				if (data.carId == null) {
+					uni.showToast({
+						icon: 'none',
+						title: '请先添加车辆'
+					})
+				} else {
+					repairOrderAdd(data).then((res) => {
+						// uni.hideToast()
+						if (res.code == "00000") {
+							uni.showToast({
+								title: '预约成功',
+								icon: 'none',
+								duration: 2000
+							});
+							setTimeout(function() {
+								uni.removeStorageSync('shopData')
+								uni.navigateBack({})
+							}, 2000);
+						}
+					})
+				}
+
+
+			},
+			back() {
+				uni.navigateBack({
+					delta: 1
+				});
+			},
+			change(e) {
+				let value = []
+				e.detail.value.forEach((val, index) => {
+					value.push(this.dateTimeArray[index][val])
+				})
+				let dateArray = value[0] + "/" + value[1] + "/" + value[2] + " " + value[3] + ":" + value[4]
+				this.customer.time = dateArray
+			},
+			columnchange(e) {
+				let dateArr = this.dateTimeArray
+				let arr = this.dateTime
+				//滑动所在列的数据并对其值进行更新
+				arr[e.detail.column] = e.detail.value
+				//更新展示月份对应的天数(28 or 29 or 30 or 31)
+				dateArr[2] = dateTimePicker.getMonthDay(dateArr[0][arr[0]], dateArr[1][arr[1]])
+				//最后把最新的数值赋值到dateTimeArray
+				this.dateTimeArray = dateArr
+				this.dateTime = arr
+			},
+			showPickerChange() {
+				this.showPicker = true;
+			},
+			//变化
+			async bindChange(e) {
+				let that = this;
+				await getRegion({
+					parentId: this.oneList[e.detail.value[0]].id
+				}).then(async res => {
+					that.twoList = res.data;
+					await getRegion({
+						parentId: that.twoList[e.detail.value[1]].id
+					}).then(res => {
+						that.threeList = res.data;
+					})
+				})
+				this.defaultValue = e.detail.value;
+				console.log(e)
+			},
+			//取消
+			closePicker() {
+				this.showPicker = false;
+				this.defaultValue = [0, 0, 0];
+			},
+			//确认
+			confirmPicker() {
+				this.customer.deliveryLocation = "";
+				this.customer.deliveryLocation = this.oneList[this.defaultValue[0]].name + this.twoList[this.defaultValue[
+					1]].name + this.threeList[this.defaultValue[2]].name;
+				this.showPicker = false;
+				this.provCode = this.oneList[this.defaultValue[0]].id;
+				this.cityCode = this.twoList[this.defaultValue[1]].id;
+				this.areaCode = this.threeList[this.defaultValue[2]].id;
+			},
+			modeRadioChange(e) {
+				this.modeRadioType = 2
+			},
+			invoiceRadioChange(e) {
+				this.invoiceRadioType = e.detail.value
+			},
+			toPage() {
+				this.$yrouter.push({
+					path: "/pages/maintenance/servicesAvailable/index?shopId=" + this.carShop.id +
+						"&projectList=" + JSON.stringify(this.projectList) + '&type=main'
+				});
+				console.log('2', this.carShop);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.projectTime {
+		max-width: 238rpx;
+		height: 100%;
+		display: flex;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 100rpx;
+		padding-left: 28rpx;
+	}
+
+	.projectNull {
+		min-width: 238rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #A9A9A9;
+		line-height: 100rpx;
+		padding-left: 28rpx;
+	}
+
+	.bigMorePicker {
+		position: fixed;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 99;
+	}
+
+	.morePickerCent {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		background-color: #fff;
+
+	}
+
+	.morePickerTitle {
+		width: 100%;
+		height: 70rpx;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding: 20rpx;
+		box-sizing: border-box;
+		font-size: 32rpx;
+		border-bottom: #eee 2rpx solid;
+	}
+
+	.picker-view {
+		width: 100%;
+		height: 500rpx;
+		margin-top: 20rpx;
+	}
+
+	.item {
+		height: 50px;
+		line-height: 50px;
+		align-items: center;
+		justify-content: center;
+		text-align: center;
+	}
+
+	.body {
+		width: 94%;
+		margin-left: 3%;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 28rpx;
+		margin-bottom: 28rpx;
+
+		.classHead {
+			display: flex;
+			padding-top: 28rpx;
+			width: 100%;
+			height: 28rpx;
+
+			.classBorder {
+				width: 5rpx;
+				height: 28rpx;
+				background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+				border-radius: 3rpx;
+			}
+
+			.classTitle {
+				height: 25rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				padding-left: 28rpx;
+				line-height: 28rpx;
+			}
+		}
+
+		.projectBody2 {
+			width: calc(100% - 60rpx);
+			height: 100rpx;
+			display: flex;
+			align-items: center;
+			justify-content: left;
+			padding: 28rpx 30rpx 0;
+
+			.title {
+				min-width: 300rpx;
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 100rpx;
+			}
+		}
+
+		.projectBody {
+			width: calc(100% - 60rpx);
+			height: 100rpx;
+			display: flex;
+			align-items: center;
+			justify-content: left;
+			padding: 28rpx 30rpx 0;
+
+			.title {
+				min-width: 300rpx;
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 100rpx;
+			}
+
+			.projectTime {
+				min-width: 238rpx;
+				height: 100%;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 100rpx;
+				padding-left: 0rpx;
+			}
+
+			.projectNull {
+				min-width: 238rpx;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #A9A9A9;
+				line-height: 100rpx;
+				padding-left: 0rpx;
+			}
+
+			.dataRight {
+				line-height: 100rpx;
+				margin-left: 198rpx;
+
+				image {
+					width: 15rpx;
+					height: 23rpx;
+				}
+			}
+		}
+
+		.border {
+			width: 650rpx;
+			height: 1px;
+			background: #EEEEEE;
+			border-radius: 1px;
+			margin-left: 4%;
+		}
+	}
+
+	.box {
+		width: 660rpx;
+		height: 590rpx;
+		// background-image: url(../../../static/bg.png);
+		background-size: 100% 100%;
+		margin-left: 25rpx;
+		transition: all 0.3;
+
+		.projectBodys {
+			width: 100%;
+			height: 100rpx;
+			padding-top: 18rpx;
+			display: flex;
+
+			.title {
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 100rpx;
+				padding-left: 35rpx;
+				width: 117rpx;
+			}
+
+			.projectTime {
+				width: 300rpx;
+				font-size: 27rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #666666;
+				line-height: 100rpx;
+				padding-left: 54rpx;
+			}
+
+			.projectNull {
+				width: 300rpx;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #A9A9A9;
+				line-height: 100rpx;
+				padding-left: 52rpx;
+			}
+
+			.dataRight {
+				line-height: 100rpx;
+				margin-left: 110rpx;
+
+				image {
+					width: 15rpx;
+					height: 23rpx;
+				}
+			}
+		}
+
+		.border {
+			width: 586rpx;
+			height: 1px;
+			background: #DCECFF;
+			border-radius: 1px;
+			margin-left: 5%;
+		}
+	}
+
+	.radio {
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #333333;
+		line-height: 55rpx;
+		width: 50%;
+	}
+
+	.radioBody {
+		display: flex;
+		padding: 28rpx 0 28rpx 0;
+		width: 400rpx;
+	}
+
+	.placeholder {
+		font-size: 30rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #999999;
+		line-height: 31rpx;
+	}
+
+	.onLineBtn {
+		width: 600rpx;
+		height: 90rpx;
+		margin-left: 75rpx;
+		margin-top: 91rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 45rpx;
+		text-align: center;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FFFFFF;
+		line-height: 90rpx;
+		// position: fixed;
+		// bottom: 50rpx;
+	}
+
+	.annotation {
+		font-size: 22rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #999999;
+		display: flex;
+		justify-content: center;
+		margin-top: 41rpx;
+		margin-bottom: 50rpx;
+
+		.agreement {
+			text-decoration: none;
+			color: #0068FF;
+		}
+	}
+</style>

+ 814 - 0
pages/maintenance/servicesAvailable/index.vue

@@ -0,0 +1,814 @@
+<template>
+	<view class="">
+		<view class="chooseTap">
+			<view class="tap-btn" @click="chooseServer(1)">
+				<view :class="[tar === 1?'line':'noline']">
+					平台服务
+				</view>
+			</view>
+			<view style="width: 1px;height: 40rpx;background-color: #E4E4E4;"></view>
+			<view class="tap-btn" @click="chooseServer(2)">
+				<view :class="[tar === 2?'line':'noline']">
+					个人套餐
+				</view>
+			</view>
+		</view>
+		<view style="height: 80rpx;"></view>
+		<view class="search">
+			<view class="searchCard">
+				<view class="input">
+					<view style="display: flex;align-items: center;">
+						<text class="iconfont icon-sousuo2"></text>
+						<input style="margin-left: 20rpx;" type="text" placeholder="输入关键字搜索" v-model="search"
+							placeholder-class="co" />
+					</view>
+					<view class="bnt" @click="submit">搜索</view>
+				</view>
+			</view>
+		</view>
+		<view class="body" v-if="tar === 1">
+			<view class="menuLeft" :style="{height:swiperHeight+'px'}">
+				<view v-for="(item, index) in dataList" :key="index" :class="menu==index?'chooseMenu':'menu'"
+					@click="chooseMenu(index)">
+					<view style="width: 100%;">
+						<image v-if="menu==index" :src="require('../../../static/chooseMenu.png')">
+							{{item.serviceName}}
+					</view>
+
+					<view v-if="item.num!=0" class="span">{{item.num}}</view>
+				</view>
+				<view style="height: 200rpx;"></view>
+			</view>
+			<view class="bodyRight" :style="{height:swiperHeight+'px'}">
+				<view class="card" v-for="(item, index) in dataList[menu].serviceTwoList" :key="index">
+					<view class="content">
+						<view class="title">
+							{{item.name}}
+						</view>
+						<view class="price">
+							<span>参考价</span>¥{{item.price}}
+						</view>
+					</view>
+					<view class="radios">
+						<radio-group>
+							<radio style="transform:scale(0.7)" color="#0078FF" :checked="item.isSelected == 1"
+								@tap="radioChange(item,index)" />
+						</radio-group>
+					</view>
+				</view>
+				<view style="height: 200rpx;"></view>
+			</view>
+		</view>
+		<view class="body02" v-else>
+			<view class="mainView" v-for="(item,index) in datasList" :key="index">
+				<view class="viewBlock">
+					<view class="goodsInfo">
+						<image :src="imgPath+item.imgUrl" class="goodsImg"></image>
+						<view class="infoBlock">
+							<view style="font-size: 32rpx;font-weight: bold;">{{item.packageName}}</view>
+							<view>
+								<view style="color: #005BFF;font-size: 24rpx;font-weight: 500;">{{item.invalidTime}}前有效
+								</view>
+								<view style="font-size: 24rpx;font-weight: bold;">
+									{{item.num + '/'+item.allNum}}
+									<text style="color: #999999;font-size: 24rpx;font-weight: 500;">个项目可用</text>
+								</view>
+							</view>
+						</view>
+					</view>
+					<view v-for="(datas,count) in item.userPackageSerVOS" :key="count"
+						style="display: flex;align-items: center;justify-content: space-between;margin: 40rpx 0;">
+						<view style="font-size: 26rpx;color: #666666;">{{datas.sstName}}</view>
+						<view style="width: 180rpx;height: 1px;border-top: 1px dashed #CCCCCC;"></view>
+						<view style="font-size: 26rpx;font-weight: 500;color: #666666;">×{{datas.buyNum}}</view>
+						<view style="font-size: 24rpx;font-weight: 500;color: #666666">余
+							<text style="color:#005BFF">{{datas.surplusSum}}</text>
+						</view>
+						<view class="radios">
+							<radio-group>
+								<radio style="transform:scale(0.7)" color="#0078FF" :checked="datas.isSelected == 1"
+									@tap="radioChanges(datas,count,index)" />
+							</radio-group>
+						</view>
+					</view>
+				</view>
+				<view style="width:100%;height:20rpx;margin-top:10rpx;background-color:#F5F5F5"></view>
+			</view>
+		</view>
+		<view class="bottomBtn">
+			<view class="leftView" @click="showAction()">
+				<image class="carImg" :src="require('../../../static/car.png')">
+					<view class="chooseNum">
+						已选<span>{{chooseNum}}</span>项
+					</view>
+					<image class="upImg" :src="require('../../../static/up.png')">
+			</view>
+			<view class="rightView" @tap="goBack(chooseNum)">
+				确定
+			</view>
+		</view>
+		<ActionSheet :show="show" :mask-closable="maskClosable" :list="chooseList" @showAction="showAction"
+			@deleted="deleted"></ActionSheet>
+	</view>
+</template>
+
+<script>
+	import ActionSheet from '@/components/ActionSheet/index.vue'
+	import {
+		getShopServiceOne
+	} from "@/api/maintain.js"
+	export default {
+		components: {
+			ActionSheet
+		},
+		data() {
+			return {
+				// 打开底部弹窗
+				show: false,
+				// 遮罩层是否可以关闭弹窗
+				maskClosable: true,
+				chooseList: [],
+				chooseNum: 0,
+				menu: 0,
+				swiperHeight: "",
+				menuWidth: "",
+				foodWidth: "",
+				dataList: [{
+					serviceTwoList: []
+				}],
+				projectList: {},
+				search: "",
+				tar: 1,
+				item: null,
+				myProjectList: null,
+				imgPath: this.baseImagePath,
+				shopId: '',
+				datasList: [],
+				type: ''
+			}
+		},
+		watch: {
+			chooseList(val) {
+				console.log(val, 'val=========================');
+				console.log(this.chooseList.length);
+				this.chooseNum = this.chooseList.length
+			}
+		},
+		onLoad(options) {
+			console.log(options);
+			let that = this;
+			let datas = {};
+			let item = {};
+			this.item = options.item
+			this.projectList = options.projectList
+			this.shopId = options.shopId
+			this.type = options.type
+			if (options.item != undefined) {
+				datas = {};
+				item = JSON.parse(decodeURIComponent(options.item))
+			} else {
+				if (JSON.parse(options.projectList).chooseList != undefined) {
+					this.chooseList = JSON.parse(options.projectList).chooseList;
+				}
+				datas = {
+					shopId: options.shopId
+				}
+			}
+			datas = Object.assign({
+				type: this.tar
+			}, datas)
+			console.log(datas, '传参');
+			getShopServiceOne(
+				datas
+			).then((res) => {
+				that.dataList = res.data;
+				for (let listIndex in that.dataList) {
+					if (item != "") {
+						if (item.id == that.dataList[listIndex].id) {
+							that.menu = listIndex;
+						}
+					}
+					if (this.chooseList.length == 0) {
+						that.$set(that.dataList[listIndex], 'num', 0);
+						for (let subListIndex in that.dataList[listIndex].serviceTwoList) {
+							that.dataList[listIndex].serviceTwoList[subListIndex].isSelected = 0;
+						}
+					} else {
+						let num = 0;
+						let executeNum = 0;
+						console.log(this.chooseList);
+						for (let index in this.chooseList) {
+							if (this.chooseList[index].menuId == that.dataList[listIndex].id) {
+								for (let subListIndex in that.dataList[listIndex].serviceTwoList) {
+									if (that.dataList[listIndex].serviceTwoList[subListIndex].id == this
+										.chooseList[index]
+										.id) {
+										executeNum++
+										num++
+										that.dataList[listIndex].serviceTwoList[subListIndex].isSelected = 1;
+									} else if (executeNum == 0) {
+										that.dataList[listIndex].serviceTwoList[subListIndex].isSelected = 0;
+									}
+								}
+							}
+						}
+						that.$set(that.dataList[listIndex], 'num', num);
+					}
+					that.chooseNum = that.chooseNum + that.dataList[listIndex].num;
+				}
+			})
+			//初始化页面的组件大小
+			uni.getSystemInfo({
+				success: (res) => {
+					// - uni.upx2px(100) 减去头部的列表
+					let height = res.windowHeight
+					let windowWidth = res.windowWidth
+					this.swiperHeight = height
+					this.menuWidth = windowWidth / 5
+					this.foodWidth = windowWidth * 4 / 5
+				}
+			});
+			// this.chooseData();
+		},
+		methods: {
+			chooseServer(type) {
+				this.tar = type
+				if (this.tar === 2) {
+					getShopServiceOne({
+						type: this.tar,
+					}).then((res) => {
+						this.datasList = res.data
+						console.log(this.datasList);
+						for (let index in this.datasList) {
+							if (this.chooseList.length !== 0) {
+								for (let itemList in this.chooseList) {
+									if (this.chooseList[itemList].oneId === this.datasList[index].id) {
+										console.log(this.chooseList[itemList].oneId);
+										for (let listData in this.datasList[index].userPackageSerVOS) {
+											if (this.chooseList[itemList].id === this.datasList[index]
+												.userPackageSerVOS[listData].sstId) {
+												this.datasList[index].userPackageSerVOS[listData].isSelected = 1
+											}
+										}
+									}
+								}
+							}
+						}
+						console.log(res, 'res');
+					})
+				} else {
+					let that = this
+					let datas = {};
+					let item = {};
+					if (this.item != undefined) {
+						datas = {};
+						item = JSON.parse(decodeURIComponent(this.item))
+					} else {
+						if (JSON.parse(this.projectList).chooseList != undefined) {
+							this.chooseList = JSON.parse(this.projectList).chooseList;
+						}
+						datas = {
+							shopId: this.shopId
+						}
+					}
+					datas = Object.assign({
+						type: this.tar
+					}, datas)
+					console.log(datas, '传参');
+					getShopServiceOne(
+						datas
+					).then((res) => {
+						that.dataList = res.data;
+						console.log(that.dataList);
+						for (let listIndex in that.dataList) {
+							if (item != "") {
+								if (item.id == that.dataList[listIndex].id) {
+									that.menu = listIndex;
+								}
+							}
+							if (this.chooseList.length == 0) {
+								that.$set(that.dataList[listIndex], 'num', 0);
+								for (let subListIndex in that.dataList[listIndex].serviceTwoList) {
+									that.dataList[listIndex].serviceTwoList[subListIndex].isSelected = 0;
+								}
+							} else {
+								let num = 0;
+								let executeNum = 0;
+								for (let index in this.chooseList) {
+									console.log(that.dataList[listIndex], 'that.dataList[listIndex].id');
+									if (this.chooseList[index].menuId == that.dataList[listIndex].id) {
+										for (let subListIndex in that.dataList[listIndex].serviceTwoList) {
+											if (that.dataList[listIndex].serviceTwoList[subListIndex].id == this
+												.chooseList[index].id) {
+												executeNum++
+												num++
+												that.dataList[listIndex].serviceTwoList[subListIndex].isSelected =
+													1;
+											} else if (executeNum == 0) {
+												that.dataList[listIndex].serviceTwoList[subListIndex].isSelected =
+													0;
+											}
+										}
+									}
+								}
+								that.$set(that.dataList[listIndex], 'num', num);
+							}
+							// that.chooseNum = that.chooseNum +that.dataList[listIndex].num;
+						}
+					})
+				}
+
+			},
+			submit() {
+				getShopServiceOne({
+					serviceOneId: this.dataList[this.menu].id,
+					keyword: this.search,
+					type: this.tar,
+					shopId: this.shopId
+				}).then((res) => {
+					console.log(this.chooseList);
+					if (this.chooseList.length == 0) {
+						for (let subListIndex in res.data.serviceTwoList) {
+							res.data.serviceTwoList[subListIndex].isSelected = 0;
+						}
+					} else {
+						let num = 0;
+						let executeNum = 0;
+						for (let index in this.chooseList) {
+							if (this.chooseList[index].menuId == this.dataList[this.menu].id) {
+								for (let subListIndex in res.data.serviceTwoList) {
+									if (res.data.serviceTwoList[subListIndex].id == this.chooseList[index].id) {
+										executeNum++
+										num++
+										res.data.serviceTwoList[subListIndex].isSelected = 1;
+									} else if (executeNum == 0) {
+										res.data.serviceTwoList[subListIndex].isSelected = 0;
+									}
+								}
+							}
+						}
+					}
+					console.log('data=====================================》', res.data)
+					this.dataList[this.menu].serviceTwoList = res.data[this.menu].serviceTwoList;
+				})
+			},
+			goBack(datas) {
+				console.log(datas);
+				if (datas === 0) {
+					uni.showToast({
+						icon: 'none',
+						title: '选择的服务不可以为空'
+					})
+					return
+				}
+				let data = {
+					num: datas,
+					chooseList: this.chooseList,
+
+				}
+				console.log(this.chooseList);
+				console.log('choose==========', data);
+				uni.navigateTo({
+					url: "/pages/maintenance/onlineReservation/index?data=" + JSON.stringify(data) + "&page=index"
+				})
+				// uni.$emit('chooseNum', data);
+
+				// uni.navigateBack({
+				// 	delta: 1
+				// })
+			},
+			deleted(data) {
+				if (data.upsId) {
+					console.log(data, '删除');
+					for (let listIndex in this.datasList) {
+						if (this.datasList[listIndex].id === data.oneId) {
+							for (let twoList in this.datasList[listIndex].userPackageSerVOS) {
+								if (data.id === this.datasList[listIndex].userPackageSerVOS[twoList].sstId) {
+									this.datasList[listIndex].userPackageSerVOS[twoList].isSelected = 0
+									for (let index in this.chooseList) {
+										if (this.chooseList[index].id === data.id) {
+											this.chooseList.splice(index, 1)
+											this.chooseNum = this.chooseList.length
+										}
+									}
+								}
+							}
+						}
+					}
+				} else {
+					for (let listIndex in this.dataList) {
+						if (this.dataList[listIndex].serviceName == data.menu) {
+							for (let subListIndex in this.dataList[listIndex].serviceTwoList) {
+								if (this.dataList[listIndex].serviceTwoList[subListIndex].id == data.id) {
+									this.dataList[listIndex].serviceTwoList[subListIndex].isSelected = 0;
+									this.dataList[listIndex].num--
+								}
+							}
+						}
+					}
+					for (let index in this.chooseList) {
+						if (data.id == this.chooseList[index].id && data.chooseName == this.chooseList[index].chooseName) {
+							this.chooseList.splice(index, 1)
+						}
+					}
+					// this.chooseData();	
+				}
+
+			},
+			showAction() {
+				this.show = !this.show;
+				console.log(this.show, 'show');
+			},
+			chooseData() {
+				let chooseItem = {};
+				this.chooseList = [];
+				// this.chooseNum = 0;
+				for (let listIndex in this.dataList) {
+					// this.chooseNum = this.chooseNum + this.dataList[listIndex].num;
+					for (let subListIndex in this.dataList[listIndex].serviceTwoList) {
+						chooseItem = {};
+						console.log(this.dataList[listIndex].serviceTwoList);
+						if (this.dataList[listIndex].serviceTwoList[subListIndex].isSelected == 1) {
+							chooseItem.id = this.dataList[listIndex].serviceTwoList[subListIndex].id;
+							chooseItem.chooseName = this.dataList[listIndex].serviceTwoList[subListIndex].serviceName;
+							chooseItem.menu = this.dataList[listIndex].serviceName;
+							chooseItem.menuId = this.dataList[listIndex].id;
+							this.chooseList.push(chooseItem);
+							this.chooseNum = this.chooseList.length
+						}
+
+					}
+				}
+			},
+			radioChanges(item, index, val) {
+				this.chooseNum = 0;
+				console.log(item);
+				if (item.isSelected == 0 || item.isSelected == undefined) {
+					this.datasList[val].userPackageSerVOS[index].isSelected = 1;
+					let datasObj = {}
+						datasObj.typeId = this.datasList[val].userPackageSerVOS[index].typeId
+						datasObj.type = this.datasList[val].userPackageSerVOS[index].type
+					// if (this.datasList[val].userPackageSerVOS[index].sstId == null) {
+					// 	datasObj.id = this.datasList[val].userPackageSerVOS[index].goodsId
+					// 	datasObj.type = this.datasList[val].userPackageSerVOS[index].type
+					// } else {
+					// 	datasObj.id = this.datasList[val].userPackageSerVOS[index].sstId
+					// 	datasObj.type = this.datasList[val].userPackageSerVOS[index].type
+					// }
+					// console.log(datasObj.id);
+					datasObj.chooseName = this.datasList[val].userPackageSerVOS[index].sstName
+					datasObj.upsId = this.datasList[val].userPackageSerVOS[index].id,
+						datasObj.oneId = this.datasList[val].id
+					this.chooseList.push(datasObj);
+				} else {
+					for (let count in this.chooseList) {
+						console.log(item.sstId, this.chooseList[count].id, '123456789');
+						if (item.sstId == this.chooseList[count].id) {
+							this.chooseList.splice(index, 1)
+						}
+					}
+					this.datasList[val].userPackageSerVOS[index].isSelected = 0;
+				}
+				console.log('this.chooseList===========>', this.chooseList);
+				this.chooseNum = this.chooseList.length
+
+			},
+			radioChange(item, index) {
+				this.chooseNum = 0;
+				console.log(item, 'item1111111111111');
+				if (item.isSelected == 0 || item.isSelected == undefined) {
+					this.dataList[this.menu].num++;
+					this.dataList[this.menu].serviceTwoList[index].isSelected = 1;
+					let chooseItem = {};
+					chooseItem.id = item.id;
+					chooseItem.type = item.type;
+					chooseItem.typeId = item.typeId;
+					chooseItem.chooseName = item.serviceName;
+					chooseItem.menu = item.serviceName;
+					chooseItem.menuId = this.dataList[this.menu].id;
+					this.chooseList.push(chooseItem);
+					console.log(chooseItem);
+					console.log(this.chooseList);
+				} else {
+					for (let count in this.chooseList) {
+						console.log(item.id, this.chooseList[count].id, 'this.chooseList[count].id');
+						if (item.id == this.chooseList[count].id) {
+							this.chooseList.splice(count, 1)
+						}
+					}
+					this.dataList[this.menu].num--;
+					this.dataList[this.menu].serviceTwoList[index].isSelected = 0;
+				}
+			},
+			chooseMenu(data) {
+				this.menu = data;
+			},
+		},
+	}
+</script>
+
+<style lang="less">
+	.chooseTap {
+		width: 100%;
+		height: 80rpx;
+		background-color: #FFFFFF;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 20rpx;
+		position: fixed;
+		top: 0;
+		z-index: 999;
+		border-bottom: 1px solid #EEEEEE;
+
+		.tap-btn {
+			flex: 1;
+			text-align: center;
+			line-height: 80rpx;
+			background-color: #FFFFFF;
+
+			.line {
+				height: 77rpx;
+				color: #0060FF;
+				display: inline-block;
+				border-bottom: 3px solid #0060FF;
+			}
+
+			.noLine {
+				color: #333333;
+			}
+		}
+	}
+
+	.bottomBtn {
+		width: 690rpx;
+		height: 110rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 8rpx 17rpx 0px rgba(168, 165, 165, 0.26);
+		border-radius: 55rpx;
+		margin-left: 30rpx;
+		position: fixed;
+		bottom: 67rpx;
+		z-index: 9998;
+
+		.leftView {
+			float: left;
+			height: 100%;
+			display: flex;
+			align-items: center;
+
+			.carImg {
+				width: 64rpx;
+				height: 51rpx;
+				margin-left: 41rpx;
+			}
+
+			.chooseNum {
+				margin-left: 25rpx;
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 31rpx;
+
+				span {
+					font-size: 36rpx;
+					color: #0060FF;
+				}
+			}
+
+			.upImg {
+				width: 21rpx;
+				height: 17rpx;
+				margin-left: 12rpx;
+			}
+		}
+
+		.rightView {
+			float: right;
+			width: 210rpx;
+			height: 108rpx;
+			background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+			border-radius: 0 55rpx 55rpx 0;
+			font-size: 34rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FEFEFE;
+			line-height: 108rpx;
+			text-align: center;
+		}
+	}
+
+	.body02 {
+		padding-bottom: 200rpx;
+
+		.mainView {
+			width: 100%;
+			background-color: #FFFFFF;
+
+			.viewBlock {
+				padding: 30rpx;
+
+				.goodsInfo {
+					display: flex;
+
+					.infoBlock {
+						display: flex;
+						flex-direction: column;
+						justify-content: space-between;
+						margin-left: 20rpx;
+					}
+
+					.goodsImg {
+						width: 163rpx;
+						height: 163rpx;
+					}
+				}
+			}
+
+		}
+	}
+
+	.body {
+		display: flex;
+
+		.menuLeft {
+			width: 190rpx;
+			background: #F5F5F5;
+			border-radius: 0px 14rpx 0px 0px;
+			overflow-y: auto;
+
+			.menu {
+				width: 190rpx;
+				height: 90rpx;
+				background: #F5F5F5;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 98rpx;
+				text-align: center;
+
+				.span {
+					width: 34rpx;
+					height: 34rpx;
+					background: #FF3C00;
+					border-radius: 50%;
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FFFFFF;
+					line-height: 36rpx;
+					position: relative;
+					top: -84rpx;
+					left: 74%;
+				}
+			}
+
+			.chooseMenu {
+				width: 190rpx;
+				height: 95rpx;
+				background: #FFFFFF;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 98rpx;
+				text-align: center;
+
+				.span {
+					width: 34rpx;
+					height: 34rpx;
+					background: #FF3C00;
+					border-radius: 50%;
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FFFFFF;
+					line-height: 36rpx;
+					position: relative;
+					top: -84rpx;
+					left: 74%;
+				}
+
+				image {
+					width: 12rpx;
+					height: 38rpx;
+					position: relative;
+					left: -36rpx;
+					top: 10rpx;
+				}
+			}
+		}
+
+		.bodyRight {
+			width: 560rpx;
+			height: 878rpx;
+			background: #FFFFFF;
+			overflow-y: auto;
+
+			.card {
+				width: 500rpx;
+				border-bottom: 1px solid #E6E6E6;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+
+				.content {
+					float: left;
+
+					.title {
+						font-size: 32rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #333333;
+						line-height: 36rpx;
+						padding-top: 41rpx;
+						padding-left: 29rpx;
+
+					}
+
+					.price {
+						font-size: 26rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #005BFF;
+						padding-top: 29rpx;
+						padding-left: 29rpx;
+						padding-bottom: 37rpx;
+
+						span {
+							color: #666666;
+							font-size: 22rpx;
+							font-family: PingFang SC;
+							font-weight: 500;
+						}
+					}
+				}
+
+				.radios {
+					float: right;
+				}
+			}
+		}
+	}
+
+	.search {
+		width: 100%;
+		height: 90rpx;
+		background: #FFFFFF;
+		box-shadow: 0px 1px 0px 0px rgba(55, 55, 55, 0.1);
+	}
+
+	.searchCard {
+		width: 710rpx;
+		height: 70rpx;
+		background: #ECECEC;
+		border: 1px solid #FFFFFF;
+		border-radius: 34rpx;
+		margin-left: 20rpx;
+		margin-top: 21rpx;
+	}
+
+	.iconfont {
+		font-family: "iconfont" !important;
+		font-size: 35rpx;
+		font-style: normal;
+		-webkit-font-smoothing: antialiased;
+		-moz-osx-font-smoothing: grayscale;
+		background: #ECECEC;
+		padding-left: 37rpx;
+		line-height: 70rpx;
+		border-radius: 34rpx;
+	}
+
+	.co {
+		background: #ECECEC;
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #999999;
+	}
+
+	.input {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.bnt {
+		width: 130rpx;
+		height: 58rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 29rpx;
+		line-height: 58rpx;
+		text-align: center;
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FFFFFF;
+		position: relative;
+		right: 8rpx;
+	}
+</style>

+ 255 - 0
pages/maintenance/setMeal/buySetMeal/index.vue

@@ -0,0 +1,255 @@
+<template>
+	<view class="">
+		<view class="card">
+			<view class="classHead">
+				<view class="classBorder">
+
+				</view>
+				<view class="classTitle">
+					套餐详情
+				</view>
+			</view>
+			<view class="body">
+				<image :src="'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/'+setMeal.packages.imgUrl" alt="">
+					<view class="content">
+						<view class="title">
+							{{setMeal.packages.name}}
+						</view>
+						<view class="explain">
+							<a href="##">购买的套餐仅限选择的车辆使用</a>
+						</view>
+					</view>
+			</view>
+		</view>
+		<Card titles="使用车辆" :data="setMeal.userCar"></Card>
+		<view class="bottomBtn">
+			<view class="leftView">
+				<view class="unit">
+					需支付:
+				</view>
+				<view class="chooseNum">
+					<view style="font-size: 26rpx;">
+						¥
+					</view>
+					<view style="font-size: 56rpx;">
+						{{setMeal.price}}
+					</view>
+				</view>
+			</view>
+			<view class="rightView" @click="createOrder(setMeal.packages.id,setMeal.userCar.id,setMeal.price)">
+				确定
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	import {
+		packageBuy
+	} from "@/api/maintain.js"
+	import {
+		buyPackage
+	} from "@/api/myApi.js"
+	import Card from '@/components/Card'
+	export default {
+		components: {
+			Card
+		},
+		data() {
+			return {
+				setMeal: {
+					packages: {},
+					userCar: {},
+					price: null
+				},
+				url: "",
+				name: "",
+				cardMsg: [],
+				provider: '',
+				payType: 1
+			};
+		},
+		onLoad(options) {
+			this.packageBuys(JSON.parse(options.item).id)
+		},
+		methods: {
+			createOrder(packageId, carId, price) {
+				let data = {
+					packageId: packageId,
+					carId: carId,
+					payPrice: price,
+					payType: this.payType
+				}
+				console.log(data);
+				buyPackage(data).then(res => {
+					console.log(res);
+					if (this.payType === 1) {
+						this.provider = 'wxpay'
+					}
+					console.log(res.data.wechatOrder);
+					uni.requestPayment({
+						
+						provider: this.provider,
+						orderInfo: res.data.wechatOrder,
+						success: (res) => {
+							console.log('下单支付===============>', res);
+							uni.showToast({
+								icon: 'none',
+								title: '下单成功'
+							})
+							uni.redirectTo({
+								url: '/pages/preCarWash/washOrder/index'
+							})
+						},
+						fail: (res) => {
+							console.log(res, '支付失败fail');
+							uni.showToast({
+								icon: 'none',
+								title: '支付失败:' + res.errMsg + ',code:' + res.code +
+									',errCode:' + res.errCode
+							})
+						}
+					})
+				})
+			},
+			packageBuys(id) {
+				packageBuy({
+					packageId: id
+				}).then(res => {
+					console.log('获取参数=================>', res);
+					this.setMeal = res.data;
+				})
+			},
+
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #EDEDED;
+	}
+
+	.bottomBtn {
+		width: 690rpx;
+		height: 110rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 8rpx 17rpx 0px rgba(168, 165, 165, 0.26);
+		border-radius: 55rpx;
+		margin-left: 30rpx;
+		position: absolute;
+		bottom: 67rpx;
+		z-index: 9998;
+
+		.leftView {
+			float: left;
+			height: 100%;
+			display: flex;
+			align-items: center;
+
+			.unit {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 31rpx;
+				padding-left: 52rpx;
+			}
+
+			.chooseNum {
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #FF3C00;
+				line-height: 31rpx;
+				display: flex;
+				align-items: baseline;
+			}
+		}
+
+		.rightView {
+			float: right;
+			width: 210rpx;
+			height: 108rpx;
+			background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+			border-radius: 0 55rpx 55rpx 0;
+			font-size: 34rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FEFEFE;
+			line-height: 108rpx;
+			text-align: center;
+		}
+	}
+
+	.card {
+		width: 94%;
+		height: 239rpx;
+		margin-left: 3%;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 28rpx;
+
+		.classHead {
+			display: flex;
+			padding-top: 28rpx;
+			width: 100%;
+			height: 28rpx;
+
+			.classBorder {
+				width: 5rpx;
+				height: 28rpx;
+				background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+				border-radius: 3rpx;
+			}
+
+			.classTitle {
+				height: 25rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				padding-left: 28rpx;
+				line-height: 28rpx;
+			}
+		}
+
+		.body {
+			display: flex;
+			align-items: center;
+			padding: 36rpx 0 0 26rpx;
+
+			image {
+				width: 120rpx;
+				height: 120rpx;
+			}
+
+			.content {
+				padding-left: 30rpx;
+
+				.title {
+					font-size: 32rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					line-height: 31rpx;
+				}
+
+				.explain {
+					margin-top: 23rpx;
+
+					a {
+						font-size: 24rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #005BFF;
+						line-height: 31rpx;
+						text-decoration: none;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 167 - 0
pages/maintenance/setMeal/index.vue

@@ -0,0 +1,167 @@
+<template>
+	<view class="body">
+		<view class="card" v-for="(item, index) in setMealList" :key="index" @tap="routerTo(item)">
+			<image :src="'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/'+item.imgUrl"></image>
+			<view class="title">
+				{{item.name}}
+			</view>
+			<view class="content">
+				{{item.title}}
+			</view>
+			<view class="bottomView">
+				<view class="priceView">
+					<view class="unit">
+						¥
+					</view>
+					<view class="price">
+						{{item.carPrice}}-{{item.truckPrice}}
+					</view>
+				</view>
+				<view class="dprice">
+					已售:{{item.buyNum}}
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import SetMeal from '@/components/SetMeal';
+	import {
+		packageList
+	} from "@/api/maintain.js"
+	export default {
+		components: {
+			SetMeal
+		},
+		data: function() {
+			return {
+				setMealList: [],
+				pageNo: 1,
+				pageSize: 10,
+				loadmore: true
+			}
+		},
+		onLoad() {
+			this.packageList();
+		},
+		onReachBottom() {
+			if (this.loadmore) {
+				this.packageList();
+			}
+		},
+		methods: {
+			// 路由跳转
+			routerTo(item) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/setMeal/setMealDetail/index?item=" + JSON.stringify(item)
+				});
+			},
+			packageList() {
+				packageList({
+					pageNo: this.pageNo,
+					pageSize: this.pageSize,
+				}).then((res) => {
+					this.setMealList = [...this.setMealList,...res.data.rows];
+					if (this.setMealList.length < this.pageSize) {
+						this.loadmore = false
+					}
+					this.pageNo++
+				})
+			},
+		}
+	}
+</script>
+<style>
+	page{
+		background-color: #EDEDED;
+	}
+</style>
+<style lang="less" scoped>
+	.body {
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+		padding-top: 20rpx;
+		padding-bottom: 30rpx;
+		padding-left: 20rpx;
+		padding-right: 20rpx;
+		background-color: #EDEDED;
+		.card {
+			width: 344rpx;
+			height: 532rpx;
+			background: #FFFFFF;
+			border: 1px solid #E5E5E5;
+			box-shadow: 0px 0px 14rpx 0px rgba(125, 125, 125, 0.13);
+			border-radius: 10rpx;
+			margin-top: 18rpx;
+			position: relative;
+			image {
+				width: 344rpx;
+				height: 344rpx;
+				box-shadow: 0px 0px 14rpx 0px rgba(125, 125, 125, 0.13);
+				border-radius: 10rpx;
+			}
+
+			.title {
+				height: 27rpx;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 39rpx;
+				padding: 15rpx 0 0 20rpx;
+			}
+
+			.content {
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 28rpx;
+				padding: 16rpx 20rpx 0 20rpx;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				-webkit-line-clamp: 2;
+				line-clamp: 2;
+				-webkit-box-orient: vertical;
+			}
+
+			.bottomView {
+				width: calc(100% - 34rpx);
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0rpx 17rpx 0 17rpx;
+				position: absolute;
+				bottom: 10rpx;
+				.priceView {
+					display: flex;
+					align-items: baseline;
+
+					.unit {
+						font-size: 20rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF3C00;
+					}
+
+					.price {
+						font-size: 32rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF3C00;
+					}
+				}
+
+				.dprice {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+				}
+			}
+		}
+	}
+</style>

+ 535 - 0
pages/maintenance/setMeal/setMealDetail/index.vue

@@ -0,0 +1,535 @@
+<template>
+	<view class="setMealDetail">
+		<image :src="'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/'+setMeal.imgUrl" alt="">
+			<view class="header-card">
+				<view class="header">
+					{{setMeal.name}}
+				</view>
+				<view class="content">
+					{{setMeal.title}}
+				</view>
+				<view class="bottom">
+					<view class="left">
+						{{setMeal.endTime}}
+					</view>
+					<view class="right">
+						已售{{setMeal.buyNum}}
+					</view>
+				</view>
+			</view>
+			<!-- 套餐项目 -->
+			<view class="servicesAvailable">
+				<view class="header">
+					<view class="title">
+						套餐项目
+					</view>
+					<view class="border"></view>
+				</view>
+				<view class="body" v-for="(item, index) in setMeal.serviceList" :key="index">
+					<view class="title">
+						{{item.serviceName}}
+					</view>
+					<view class="border">
+
+					</view>
+					<view class="length">
+						×{{item.sum||0}}
+					</view>
+				</view>
+			</view>
+			<!-- 可用门店 -->
+			<view class="shop">
+				<view class="header">
+					<view class="title">
+						可用门店
+					</view>
+					<view class="border"></view>
+				</view>
+				<view class="flexView">
+					<view class="body" v-for="(item, index) in setMeal.shopList" :key="index">
+						<image :src="'https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/'+item.logoUrl" alt="">
+							<view class="subbody">
+								<view class="title">
+									{{item.name}}
+								</view>
+								<view class="content">
+									<view class="location">
+										{{item.address}}
+									</view>
+									<view class="right">
+										<image :src="require('../../../../static/address.png')" alt="">
+											<view class="km">
+												{{item.distance}}km
+											</view>
+									</view>
+								</view>
+							</view>
+					</view>
+				</view>
+			</view>
+			<!-- 套餐详情 -->
+			<view class="detail">
+				<view class="header">
+					<view class="title">
+						套餐详情
+					</view>
+					<view class="border"></view>
+				</view>
+				<view class="content">
+					{{setMeal.title}}
+				</view>
+			</view>
+			<view style="height: 200rpx;">
+
+			</view>
+			<!-- 底部按钮 -->
+			<view class="bottomBtn">
+				<view class="leftView">
+					<view class="chooseNum">
+						<view style="font-size: 26rpx;">
+							¥
+						</view>
+						<view style="font-size: 56rpx;">
+							{{price}}
+						</view>
+					</view>
+				</view>
+				<view class="rightView" @click="routerTo()">
+					立即购买
+				</view>
+			</view>
+	</view>
+</template>
+
+<script>
+	const app = getApp();
+	import {
+		packageDetail
+	} from "@/api/maintain.js";
+	import {
+		getUserCar
+	} from "@/api/shop.js"
+	export default {
+		components: {},
+		data() {
+			return {
+				setMeal: {},
+				shopList: [{
+						name: "海通洗车华南店",
+						url: "https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/1539087000475328514.png",
+						location: "大连市甘井子区友好路236号 拷贝 3",
+						km: "8.9km"
+					},
+					{
+						name: "海通洗车华南店",
+						url: "https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/1539087000475328514.png",
+						location: "大连市甘井子区友好路236号 拷贝 3",
+						km: "8.9km"
+					},
+					{
+						name: "海通洗车华南店",
+						url: "https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/1539087000475328514.png",
+						location: "大连市甘井子区友好路236号 拷贝 3",
+						km: "8.9km"
+					},
+					{
+						name: "海通洗车华南店",
+						url: "https://biaodianfuhao.oss-cn-beijing.aliyuncs.com/1539087000475328514.png",
+						location: "大连市甘井子区友好路236号 拷贝 3",
+						km: "8.9km"
+					},
+				],
+				servicesAvailableList: [{
+						name: "普通洗车",
+						list: [{
+								name: "xxxxxxx"
+							},
+							{
+								name: "xxxxxxx"
+							},
+						]
+					},
+					{
+						name: "常规保养",
+						list: [{
+								name: "xxxxxxx"
+							},
+							{
+								name: "xxxxxxx"
+							},
+						]
+					},
+					{
+						name: "二级保养",
+						list: [{
+								name: "xxxxxxx"
+							},
+							{
+								name: "xxxxxxx"
+							},
+						]
+					},
+					{
+						name: "钣金修复",
+						list: [{
+								name: "xxxxxxx"
+							},
+							{
+								name: "xxxxxxx"
+							},
+							{
+								name: "xxxxxxx"
+							},
+						]
+					},
+					{
+						name: "磨泥打蜡",
+						list: [{
+							name: "xxxxxxx"
+						}, ]
+					},
+				],
+				price: "",
+				longitude: app.globalData.longitude,
+				latitude: app.globalData.latitude,
+				userCar:{}
+			};
+		},
+		onLoad(options) {
+			// this.setMeal = JSON.parse(options.item);
+			console.log(options);
+			this.$nextTick(()=> {
+				console.log(options);
+				this.packageDetail(JSON.parse(options.item).id)
+				this.getUserCar();
+			});
+
+
+		},
+		methods: {
+			getUserCar(){
+				getUserCar().then(res=>{
+					this.userCar = res.data;
+				})
+			},
+			packageDetail(id) {
+				console.log(id);
+				packageDetail({
+					longitude: this.longitude || "111",
+					latitude: this.latitude || "111",
+					id: id
+				}).then(res => {
+					console.log(res);
+					this.setMeal = res.data;
+					this.price = this.setMeal.carPrice < this.setMeal.suvPrice ? (this.setMeal.carPrice < this
+						.setMeal.truckPrice ?
+						this.setMeal.carPrice : this.setMeal.truckPrice) : (this.setMeal.suvPrice < this
+						.setMeal.truckPrice ?
+						this.setMeal.suvPrice : this.setMeal.truckPrice)
+						console.log(setMeal.buyNum);
+				})
+			},
+			routerTo(item) {
+				if(this.userCar.id == null){
+					uni.showToast({
+						title: '请添加默认车辆',
+						icon: 'none',
+						duration: 2000
+					});
+				}else{
+					this.$yrouter.push({
+						path: "/pages/maintenance/setMeal/buySetMeal/index?item=" + JSON.stringify(this.setMeal)
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #EDEDED;
+	}
+
+	.bottomBtn {
+		width: 690rpx;
+		height: 110rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 8rpx 17rpx 0px rgba(168, 165, 165, 0.26);
+		border-radius: 55rpx;
+		margin-left: 30rpx;
+		position: fixed;
+		bottom: 67rpx;
+		z-index: 9998;
+
+		.leftView {
+			float: left;
+			height: 100%;
+			display: flex;
+			align-items: center;
+			margin-left: 57rpx;
+
+			.chooseNum {
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #FF3C00;
+				line-height: 31rpx;
+				display: flex;
+				align-items: baseline;
+			}
+		}
+
+		.rightView {
+			float: right;
+			width: 210rpx;
+			height: 108rpx;
+			background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+			border-radius: 0 55rpx 55rpx 0;
+			font-size: 34rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FEFEFE;
+			line-height: 108rpx;
+			text-align: center;
+		}
+	}
+
+	.detail {
+		background: #FFFFFF;
+		border-radius: 10px;
+		margin-top: 20rpx;
+		padding: 36rpx 30rpx;
+
+		.header {
+			padding-bottom: 36rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 106rpx;
+				height: 6rpx;
+				background: linear-gradient(90deg, #005BFF 0%, #FFFFFF 100%);
+				opacity: 0.6;
+			}
+		}
+
+		.content {
+			font-size: 26rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #666666;
+			line-height: 36rpx;
+		}
+	}
+
+	.shop {
+		max-height: 514rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 20rpx;
+		padding: 36rpx 30rpx;
+
+		.header {
+			padding-bottom: 36rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 106rpx;
+				height: 6rpx;
+				background: linear-gradient(90deg, #005BFF 0%, #FFFFFF 100%);
+				opacity: 0.6;
+			}
+		}
+
+		.flexView {
+			max-height: 420rpx;
+			overflow-x: auto;
+			display: flex;
+			flex-wrap: wrap;
+			flex-direction: column;
+
+			.body {
+				width: 655rpx;
+				height: 101rpx;
+				background: #FFFFFF;
+				border-radius: 10rpx;
+				display: flex;
+				align-items: center;
+				padding-bottom: 36rpx;
+
+				image {
+					width: 100rpx;
+					height: 100rpx;
+				}
+
+				.subbody {
+					width: 76%;
+					padding: 11rpx 21rpx 0rpx 21rpx;
+
+					.title {
+						font-size: 32rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #333333;
+						line-height: 31rpx;
+					}
+
+					.content {
+						padding-top: 21rpx;
+
+						.location {
+							width: 350rpx;
+							font-size: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #999999;
+							line-height: 31rpx;
+							float: left;
+						}
+
+						.right {
+							display: flex;
+							align-items: center;
+							float: right;
+
+							image {
+								width: 23rpx;
+								height: 23rpx;
+							}
+
+							.km {
+								font-size: 24rpx;
+								font-family: PingFang SC;
+								font-weight: 500;
+								color: #333333;
+							}
+						}
+					}
+				}
+			}
+		}
+
+	}
+
+	.servicesAvailable {
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 20rpx;
+		padding: 36rpx 30rpx;
+
+		.header {
+			padding-bottom: 36rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 106rpx;
+				height: 6rpx;
+				background: linear-gradient(90deg, #005BFF 0%, #FFFFFF 100%);
+				opacity: 0.6;
+			}
+		}
+
+		.body {
+			display: flex;
+			padding: 19rpx;
+			align-items: center;
+			justify-content: space-around;
+
+			.title {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 437rpx;
+				height: 1rpx;
+				border-bottom: 1px dashed #CCCCCC;
+			}
+
+			.length {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 29rpx;
+			}
+		}
+	}
+
+	.setMealDetail {
+		image {
+			width: 100%;
+			height: 750rpx;
+		}
+
+		.header-card {
+			background: #FFFFFF;
+			border-radius: 0px 0px 16rpx 16rpx;
+			padding: 40rpx 29rpx 35rpx 29rpx;
+
+			.header {
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 31rpx;
+			}
+
+			.content {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 36rpx;
+				padding-top: 25rpx;
+			}
+
+			.bottom {
+				display: flex;
+				justify-content: space-between;
+				padding-top: 37rpx;
+
+				.left {
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #005BFF;
+					line-height: 55rpx;
+				}
+
+				.right {
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+					line-height: 55rpx;
+				}
+			}
+		}
+	}
+</style>

+ 136 - 0
pages/preCarWash/chooseCar/index.vue

@@ -0,0 +1,136 @@
+<template>
+	<view class="chooseCar">
+		<radio-group @change="radioChange">
+			<view class="body" v-for="(item, index) in carList" :key="index" @tap="goBack(item)">
+				<view style="display: flex;align-items: center;">
+					<image :src="baseImagePath+item.brandLogo" alt="">
+						<view class="carView">
+							<view class="carBodyHead">
+								<image class="carImg" :src="require('../../../static/car.png')">
+									<span>{{item.carNumber}}</span>
+									<view class="vehicleBorder"></view><span>{{item.carMadelLevel}}</span>
+							</view>
+							<view class="classBodyContent">
+								{{item.brandName}} {{item.carSeriesName}}
+								</view>
+					</view>
+				</view>
+
+				<view class="radio">
+					<radio style="line-height: 66rpx;" color="#FF5C00" :value="index" :checked="id==item.id" />
+				</view>
+			</view>
+		</radio-group>
+
+	</view>
+</template>
+
+<script>
+	import {
+		getUserCarPage
+	} from "@/api/shop.js";
+	export default {
+		components: {},
+		data: function() {
+			return {
+				baseImagePath: this.baseImagePath,
+				id: "",
+				carList: [],
+				pageSize: 20,
+				pageNo: 1
+			}
+		},
+		onLoad: function(option) { //option为object类型,会序列化上个页面传递的参数
+		this.id = option.id
+			this.getPage()
+		},
+		onReachBottom() {
+			this.getPage()
+		},
+		methods: {
+			getPage(){
+				let _this = this;
+					getUserCarPage({
+						pageSize:  _this.pageSize,
+						pageNo:  _this.pageNo,
+					}).then((res) => {
+						console.log(res,'选择');
+						_this.carList = _this.carList.concat(res.data.rows)
+						_this.pageNo++
+					})
+			},
+			radioChange(e) {
+
+			},
+			goBack(datas) {
+				uni.$emit('chooseCar', datas)
+				uni.setStorageSync('chooseCar',datas)
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.body {
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 20rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 33rpx 24rpx 33rpx 26rpx;
+
+		image {
+			width: 120rpx;
+			height: 120rpx;
+			background: #FFFFFF;
+			border: 2px solid #F4F4F4;
+			border-radius: 8rpx;
+		}
+
+		.carView {
+			padding-left: 29rpx;
+			padding-top: 8rpx;
+
+			.carBodyHead {
+				display: flex;
+
+				.carImg {
+					width: 33rpx;
+					height: 27rpx;
+				}
+
+				.vehicleBorder {
+					width: 1px;
+					height: 20rpx;
+					background: #DBDBDB;
+				}
+
+				span {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					line-height: 31rpx;
+					padding: 0 15rpx 0 15rpx;
+				}
+			}
+
+			.classBodyContent {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 34rpx;
+				padding: 20rpx 45rpx 8rpx 0;
+			}
+		}
+	}
+</style>

+ 272 - 0
pages/preCarWash/chooseShop/index.vue

@@ -0,0 +1,272 @@
+<template>
+	<view class="">
+		<view class="search">
+			<view class="searchCard">
+				<view class="input">
+					<view style="min-width: 120rpx;">
+						<text class="iconfont icon-sousuo2"></text>
+					</view>
+					<!-- <form @submit.prevent="submit"></form> -->
+					<input style="margin-left: -34rpx;" type="text" placeholder="搜索店内服务" v-model="search"
+						placeholder-class="co" />
+					<view class="bnt" @click="submit">搜索</view>
+				</view>
+			</view>
+		</view>
+		<view class="">
+			<view class="shopBody" v-for="(item, index) in shopList" :key="index" @tap="goBack(item)">
+				<view class="classBody" style="margin-left: 30rpx;">
+					<image class="classImg" :src="baseImagePath+item.logoUrl">
+					<view style="padding: 0 0 0 22rpx;display: flex;flex-direction: column;justify-content: center;">
+						<view class="classBodyHead">
+							{{item.name}}
+						</view>
+						<view class="classBodyContent">
+							{{item.address}}
+						</view>
+					</view>
+					<view class="viewRight">
+						<image class="location" :src="require('../../../static/address.png')">
+						<view class="locationNum">
+							{{item.distance}}km
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getSelectStore
+	} from "@/api/shop.js"
+	const app = getApp();
+	export default {
+		data: function() {
+			return {
+				baseImagePath: this.baseImagePath,
+				longitude: app.globalData.longitude,
+				latitude: app.globalData.latitude,
+				shopList: [],
+				pageNo: 1,
+				pageSize: 20,
+				search:"",
+				page:'',
+				pageType : ''
+			}
+		},
+		onLoad: function(option) { //option为object类型,会序列化上个页面传递的参数
+			console.log('option',option);
+			this.page = option.page
+			this.pageType = option.type
+			this.getPage()
+					
+		},
+		onReachBottom() {
+			this.getPage()
+		},
+		methods: {
+			submit(){
+				let that = this;
+				that.pageNo = 1;
+				that.shopList = [];
+				let data = {
+					pageNo: that.pageNo,
+					pageSize: that.pageSize,
+					type : 2,
+					longitude: that.longitude,
+					latitude: that.latitude,
+					name:that.search,
+					isRepair:null,
+					isCarwash:null,
+				}
+				console.log(this.pageType === "washCar",'this.pageType === "washCar"');
+				if(this.pageType === "washCar"){
+					data.isCarwash = 1
+				}else{
+					data.isRepair = 1
+				}
+				getSelectStore(data).then(res => {
+					that.shopList = that.shopList.concat(res.data.rows)
+					that.pageNo++
+				})
+			},
+			getPage(){
+				let that = this;
+				let data = {
+					pageNo: that.pageNo,
+					pageSize: that.pageSize,
+					isRepair:null,
+					isCarwash:null,
+					type : 2,
+					longitude: that.longitude,
+					latitude: that.latitude
+				}
+				console.log(this.pageType === "washCar",'this.pageType === "washCar"');
+				if(this.pageType === "washCar"){
+					data.isCarwash = 1
+				}else{
+					data.isRepair = 1
+				}
+				getSelectStore(data).then(res => {
+					that.shopList = that.shopList.concat(res.data.rows)
+					that.pageNo++
+				})
+			},
+			/* routerTo(item) {
+				this.$yrouter.push({
+					path: "/pages/shop/shopDetail/index?id=" + item.id
+				});
+			} */
+			goBack(datas) {
+				console.log(datas);
+				if(this.page === 'index'){
+					this.$yrouter.push({
+						path: "/pages/shop/shopDetail/index?id=" + datas.id
+					});
+				}else{
+					uni.setStorageSync('chooseShop',datas)
+					uni.$emit('chooseShop',datas)
+					uni.navigateBack({
+						delta: 1
+					})
+				}
+			},
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #EDEDED;
+	}
+
+	.classBodyHead {
+		height: 31rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 31rpx;
+		margin-bottom: 32rpx;
+	}
+
+	.classBodyContent {
+		width: 370rpx;
+		height: 23rpx;
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 31rpx;
+	}
+
+	.viewRight {
+		height: calc(100% - 56rpx);
+		display: flex;
+		align-items: center;
+		position: absolute;
+		right: 30rpx;
+		bottom: 0;
+	}
+
+	.location {
+		width: 23rpx;
+		height: 23rpx;
+	}
+
+	.locationNum {
+		font-size: 24rpx;
+		font-weight: 500;
+		color: #333333;
+		line-height: 31rpx;
+		margin-left: 6rpx;
+	}
+
+	.classImg {
+		width: 120rpx;
+		height: 120rpx;
+		background: linear-gradient(135deg, #D10498 0%, #D21728 100%);
+		border-radius: 8rpx;
+	}
+
+	.classBody {
+		display: flex;
+		align-items: center;
+	}
+
+	.search {
+		width: 100%;
+		height: 90rpx;
+		background: #FFFFFF;
+		box-shadow: 0px 1px 0px 0px rgba(55, 55, 55, 0.1);
+	}
+
+	.searchCard {
+		width: 710rpx;
+		height: 70rpx;
+		background: #ECECEC;
+		border: 1px solid #FFFFFF;
+		border-radius: 34rpx;
+		margin-left: 20rpx;
+	}
+
+	.iconfont {
+		font-family: "iconfont" !important;
+		font-size: 35rpx;
+		font-style: normal;
+		-webkit-font-smoothing: antialiased;
+		-moz-osx-font-smoothing: grayscale;
+		background: #ECECEC;
+		padding-left: 37rpx;
+		line-height: 70rpx;
+		border-radius: 34rpx;
+	}
+
+	.acea-row {
+		display: flex;
+		flex-wrap: wrap;
+	}
+
+	.co {
+		background: #ECECEC;
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #999999;
+	}
+
+	.input {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.bnt {
+		width: 130rpx;
+		height: 58rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 29rpx;
+		line-height: 58rpx;
+		text-align: center;
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FFFFFF;
+		position: relative;
+		right: 8rpx;
+	}
+
+	.shopBody {
+		width: 710rpx;
+		height: 170rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-left: 20rpx;
+		margin-top: 20rpx;
+		position: relative;
+		display: flex;
+		align-items: center;
+	}
+</style>

+ 304 - 0
pages/preCarWash/chooseTime/index.vue

@@ -0,0 +1,304 @@
+<template>
+	<view class="">
+		<view class="classWeeks">
+			<view class="weeks" v-for="(itemList, index) in check" :key="index" @click="chooseDatas(itemList,index)"
+				:style="chooseData==index?'background: linear-gradient(-35deg, #005AFF 0%, #0078FF 100%);box-shadow: 0px 5rpx 8rpx 0px rgba(0, 92, 255, 0.25);':'background: #FFFFFF;'">
+				<view class="week" :style="chooseData==index?'color: #FFFFFF;':'color: #333333;'">
+					{{itemList.week}}
+				</view>
+				<view class="weekData" :style="chooseData==index?'color: #FFFFFF;':'color: #333333;'">
+					{{itemList.date}}
+				</view>
+			</view>
+		</view>
+		<view class="classChooseTime">
+			<view v-for="(item, index) in dataTimeList" :key="index" :class="[item.prohibit?'timeBody':'timeBodyNo']"
+				:style="sectionTime == item.time?'border: 1px solid #005AFF;color: #005AFF;':item.type?'background: #FFFFFF;color: #C3C3C3;border: 1px solid #EEEEEE;':''"
+				@click="chooseTimes(item)" style="text-align: center;position: relative;margin-left: 20rpx;">
+				<span
+					:style="sectionTime == item.time || item.type?'position: relative;z-index: 1;':''">{{item.time}}</span>
+				<image v-if="sectionTime == item.time" class="chooseImg" :src="require('../../../static/select.png')">
+				<image v-if="item.type" class="chooseImg" :src="require('../../../static/mang.png')">
+			</view>
+		</view>
+		<view class="classBottom">
+			<view class="dataView">
+				{{chooseWeeks}} {{sectionTime}}
+			</view>
+			<view @tap="goBack()" class="classbtn">确定预约</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	import {
+		getTimeList
+	} from "@/api/shop.js"
+	export default {
+		data: function() {
+			return {
+				shopId: "",
+				chooseWeeks: "今天",
+				chooseData: null,
+				sectionTime: "",
+				dataTimeList: [],
+				list: [],
+				check: [],
+				startTime:""
+			}
+		},
+		watch: {
+			chooseData(val) {
+				this.dataTimeList = []
+				for (let subIndex in this.list[this.check[val].intTime]) {
+					let startTime = this.dataTime(this.list[this.check[val].intTime][subIndex].startTime);
+					let endTime = this.dataTime(this.list[this.check[val].intTime][subIndex].endTime);
+					console.log(this.list[this.check[val].intTime][subIndex].prohibit,'prohibit');
+					this.dataTimeList.push({
+						time: startTime + "-" + endTime,
+						startTime:this.list[this.check[val].intTime][subIndex].startTime,
+						type: this.list[this.check[val].intTime][subIndex].isBusy,
+						prohibit:this.list[this.check[val].intTime][subIndex].prohibit
+					})
+				}
+			}
+		},
+		onLoad: function(option) { //option为object类型,会序列化上个页面传递的参数
+			this.shopId = option.shopId;
+			let i = 0;
+			this.list = JSON.parse(option.dataTimeList);
+			for (let index in this.list) {
+				i = i + 1;
+				let date = new Date(parseInt(index));
+				let year = date.getFullYear();
+				let month = date.getMonth() + 1;
+				let day = date.getDate();
+				let dt2 = new Date(parseInt(index));
+				let weekDay = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
+				let weekDays = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
+				if (month < 10) {
+					month = "0" + month;
+				}
+				if (day < 10) {
+					day = "0" + day;
+				}
+				// console.log(duty);
+				//把七天的时间和星期添加到数组中
+
+				this.check.push({
+					intTime: index,
+					date: month + "." + day,
+					day: day,
+					weekday: weekDays[dt2.getDay()],
+					week: i === 1 ? "今天" : weekDay[dt2.getDay()],
+					sectionTime: "",
+				});
+			}
+			this.chooseData = 0;
+			let listKey = Object.keys(this.list);
+			this.check.forEach((res,index)=>{
+				if(res.date == option.dataTime.substring(0, option.dataTime.lastIndexOf("日")).replace(/月/g, ".")){
+					this.chooseData = index;
+				}
+			})
+			this.sectionTime = option.dataTime.substring(option.dataTime.lastIndexOf(" ") + 1, option.dataTime.length);
+			console.log(option.dataTime); //打印出上个页面传递的参数。
+			// this.chooseTime(option)
+		},
+		methods: {
+			dataTime(val) {
+				let date = new Date(parseInt(val));
+				let h = date.getHours();
+				h = h < 10 ? ('0' + h) : h; //小时补0
+				let m = date.getMinutes();
+				m = m < 10 ? ('0' + m) : m; //分钟补0
+				return h + ":" + m
+			},
+			goBack() {
+				uni.$emit('chooseData', {data:this.check[this.chooseData].date.replace(".", "月") + "日 " + this.sectionTime,startTime:this.startTime})
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			chooseTimes(data) {
+				if (data.type) return;
+				if(!data.prohibit) return;
+				this.startTime = data.startTime;
+				this.sectionTime = data.time;
+			},
+			chooseDatas(data, index) {
+				this.chooseData = index;
+				this.sectionTime = data.sectionTime;
+				this.chooseWeeks = data.week;
+			},
+			// chooseTime(option) {
+			// 	this.check = [];
+			// 	for (let i = 0; i < 5; i++) {
+			// 		//24 * 3600 * 1000 就是计算一天的时间  
+			// 		var date = new Date(new Date().getTime() + i * 24 * 3600 * 1000);
+			// 		var year = date.getFullYear();
+			// 		var month = date.getMonth() + 1;
+			// 		var day = date.getDate();
+			// 		var dt2 = new Date(new Date().getTime() + i * 24 * 3600 * 1000);
+			// 		var weekDay = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
+			// 		var weekDays = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
+			// 		if (month < 10) {
+			// 			month = "0" + month;
+			// 		}
+			// 		if (day < 10) {
+			// 			day = "0" + day;
+			// 		}
+			// 		// console.log(duty);
+			// 		//把七天的时间和星期添加到数组中
+
+			// 		this.check.push({
+			// 			date: month + "." + day,
+			// 			day: day,
+			// 			weekday: weekDays[dt2.getDay()],
+			// 			week: i === 0 ? "今天" : weekDay[dt2.getDay()],
+			// 			sectionTime: "",
+			// 		});
+			// 		for (let item in this.check) {
+			// 			if (this.check[item].date == option.dataTime.substring(0, option.dataTime.lastIndexOf("日"))
+			// 				.replace(/月/g, ".")) {
+			// 				this.check[item].sectionTime = option.dataTime.substring(option.dataTime.lastIndexOf(" ") + 1,
+			// 					option.dataTime.length);
+			// 				this.chooseWeeks = this.check[item].week;
+			// 			}
+			// 		}
+			// 	}
+			// }
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F5F5F5;
+	}
+
+	.classWeeks {
+		display: flex;
+		height: 130rpx;
+		background: #FFFFFF;
+		border-radius: 0px 0px 16rpx 16rpx;
+		justify-content: space-around;
+		align-items: center;
+		padding: 8rpx 14rpx;
+	}
+
+	.weeks {
+		width: 100rpx;
+		height: 99rpx;
+		border-radius: 6rpx;
+	}
+
+	.week {
+		height: 26rpx;
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		line-height: 40rpx;
+		text-align: center;
+		padding-top: 24rpx;
+	}
+
+	.weekData {
+		height: 19rpx;
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FFFFFF;
+		line-height: 41rpx;
+		text-align: center;
+		padding-top: 12rpx;
+	}
+
+	.timeBody {
+		width: 216rpx;
+		height: 90rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 7rpx 12rpx 0px rgba(167, 167, 167, 0.1);
+		border-radius: 8rpx;
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 90rpx;
+		margin-top: 10rpx;
+		text-align: center;
+	}
+	
+	.timeBodyNo {
+		width: 216rpx;
+		height: 90rpx;
+		background: #999999;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 7rpx 12rpx 0px rgba(167, 167, 167, 0.1);
+		border-radius: 8rpx;
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #eeeeee;
+		line-height: 90rpx;
+		margin-top: 10rpx;
+		text-align: center;
+	}
+
+	.classChooseTime {
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: start;
+		padding: 0 13rpx;
+	}
+
+	.chooseImg {
+		width: 47rpx;
+		height: 47rpx;
+		/* position: relative;
+		top: 36rpx;
+		left: 10rpx; */
+		position: absolute;
+		bottom: 0;
+		right: 0;
+		z-index: 2;
+	}
+
+	.classBottom {
+		width: 690rpx;
+		height: 110rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 8rpx 17rpx 0px rgba(168, 165, 165, 0.09);
+		border-radius: 55rpx;
+		margin-left: 28rpx;
+		position: absolute;
+		bottom: 77rpx;
+	}
+
+	.dataView {
+		font-size: 40rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #005DFF;
+		line-height: 110rpx;
+		float: left;
+		padding-left: 28rpx;
+	}
+
+	.classbtn {
+		width: 240rpx;
+		height: 110rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 0 55rpx 55rpx 0;
+		font-size: 34rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FEFEFE;
+		text-align: center;
+		line-height: 110rpx;
+		float: right;
+	}
+</style>

+ 700 - 0
pages/preCarWash/index.vue

@@ -0,0 +1,700 @@
+<template>
+	<view class="preCarWash" style="padding-bottom: 240rpx;">
+		<Card titles="附近门店" page="washCar" :data="carShopData"></Card>
+		<Card titles="车辆信息" :data="cardMsg"></Card>
+		<view class="card-view">
+			<view class="classHead">
+				<view class="classBorder">
+
+				</view>
+				<view class="classTitle">
+					选择服务
+				</view>
+			</view>
+			<view class="classBody" style="padding: 36rpx 0;">
+				<view v-for="(item, index) in carWashType" :key="index"
+					style="padding-left: 24rpx;margin-bottom: 20rpx;">
+					<button :class="chooseBtn==index?'chooseBtn':'btn'" @click="chooseBtn=index">{{item.name}}</button>
+				</view>
+			</view>
+		</view>
+		<view class="card-view">
+			<view class="classHead">
+				<view class="classBorder">
+
+				</view>
+				<view class="classTitle">
+					服务方式
+				</view>
+			</view>
+			<view class="radioView">
+				<radio-group @change="radioChange">
+					<div class="radioBody">
+						<div class="radio">
+							<radio style="transform:scale(0.7)" color="#0078FF" checked="true" :value="1" />在店洗车
+						</div>
+						<div class="radio">
+							<radio style="transform:scale(0.7)" color="#0078FF" :value="2" />预约洗车
+						</div>
+					</div>
+				</radio-group>
+			</view>
+			<view class="border" v-if="radioValue===2"></view>
+			<view class="dataTimeBody" @tap="routerTo(dataTime)" v-if="radioValue===2">
+				<view :class="dataTime?'dataTime':'dataNull'">
+					{{dataTime || "请选择预约时间"}}
+				</view>
+				<view class="dataRight">
+					<image class="classChoose" :src="require('../../static/choose.png')">
+				</view>
+			</view>
+		</view>
+		<view class="card-view" style="height: 186rpx;">
+			<view class="classHead">
+				<view class="classBorder">
+
+				</view>
+				<view class="classTitle">
+					可用套餐
+				</view>
+			</view>
+			<view class="dataTimeBody" style="padding-top: 28rpx;" @tap="routerTo('套餐')">
+				<view :class="setMeal.name?'dataTime':'dataNull'">
+					{{setMeal.name || "请选择套餐"}}
+				</view>
+				<view class="dataRight">
+					<span v-if="setMeal.name" class="unit">可用</span>
+					<span v-if="setMeal.name" class="num">{{setMeal.surplusSum}}</span>
+					<image class="classChoose" :src="require('../../static/choose.png')">
+				</view>
+			</view>
+		</view>
+		<view class="price">
+			<view class="leftView">
+				<view class="classBottomLeft">
+					<view style="font-size: 26rpx;">
+						¥
+					</view>
+					<view style="font-size: 56rpx;">
+						{{carPrice}}
+					</view>
+				</view>
+				<view class="classBottomRight">
+					<view class="bottomSpan">
+						优惠价
+					</view>
+					<view class="bottomLaset">
+						¥{{carScrib}}
+					</view>
+				</view>
+			</view>
+			<view class="rightView" @click="plOrder">
+				立即预约
+			</view>
+		</view>
+	</view>
+
+
+</template>
+
+<script>
+	import {
+		getSelectStore,
+		getUserCar,
+		getTimeList,
+		carwashService
+	} from "@/api/shop.js"
+	import {
+		getByTypeCode,
+		getDefaultPrice,
+		getMyPackage,
+		carwashOrder
+	} from "@/api/carWash.js"
+	import Card from '@/components/Card'
+	const app = getApp();
+	export default {
+		components: {
+			Card
+		},
+		data: function() {
+			return {
+				requestStatus: false,
+				loading: false,
+				cardMsg: {},
+				chooseBtn: 0,
+				imgurl: require("../../static/logo.png"),
+				dataTime: "",
+				carShop: [],
+				carShopData: {},
+				setMeal: {},
+				carWashType: [],
+				setMealList: [],
+				carPrice: "",
+				carScrib: "",
+				dataTimeList: [],
+				startTime: "",
+				radioValue: "1",
+				carwashCode: "",
+				pageType: '',
+				btnStatus: false
+			}
+		},
+		onBackPress(options) {
+			console.log('11111');
+			// 这里可以自定义返回逻辑,比如下面跳转其他页面
+			if (!this.pageType) {
+				// #ifdef APP-PLUS
+				if (plus.os.name.toLowerCase() === 'android') {
+					plus.runtime.quit();
+				} else {
+					plus.runtime.quit();
+				}
+				// #endif
+				// return true 表示禁止默认返回
+				return true;
+			}
+		},
+		watch: {
+			setMeal(val) {
+				this.carPrice = 0
+			},
+			loading(val) {
+				console.log(22222);
+				if (this.cardMsg != "" && this.carShopData != undefined && this.carWashType != "" && val != undefined) {
+					console.log(
+						'this.cardMsg != "" && this.carShopData != undefined && this.carWashType != "" && val != undefined',
+						this.cardMsg);
+					if (this.cardMsg.id != undefined) {
+						this.getDefaultPrices(this.carWashType[0].name, this.carShopData.id, this.cardMsg.id)
+						this.getMyPackages(this.carWashType[0].name, this.carShopData.id, this.cardMsg.id)
+					}
+				}
+			},
+			chooseBtn(val) {
+				console.log(33333, val);
+				if (this.cardMsg != "" && this.carShopData != undefined && this.carWashType != "" && val != undefined) {
+					if (this.cardMsg.id != undefined) {
+						console.log(this.carWashType[val], 'val');
+						this.carwashCode = this.carWashType[val].id
+						this.getDefaultPrices(this.carWashType[val].name, this.carShopData.id, this.cardMsg.id)
+						this.getMyPackages(this.carWashType[val].name, this.carShopData.id, this.cardMsg.id)
+					}
+				}
+			},
+			cardMsg(val) {
+				if (this.carShopData != undefined && this.carWashType != "" && val.id != undefined) {
+					console.log(44444);
+					console.log('val', val);
+					this.getDefaultPrices(this.carWashType[0].name, this.carShopData.id, val.id)
+					this.getMyPackages(this.carWashType[0].name, this.carShopData.id, val.id)
+				}
+			},
+			carShopData(val) {
+				console.log(55555);
+				console.log('this.cardMsg.id', this.val);
+				console.log(this.carWashType);
+				if (this.cardMsg != "" && this.carWashType != "" && val != undefined) {
+					if (this.cardMsg.id != undefined) {
+						console.log(111);
+						console.log(this.carWashType[0].id, val.id, this.cardMsg.id);
+						// this.getDefaultPrices(this.carWashType[0].id, val.id, this.cardMsg.id)
+						this.getMyPackages(this.carWashType[0].id, val.id, this.cardMsg.id)
+					}
+				}
+			}
+		},
+		onLoad: function(e) { //option为object类型,会序列化上个页面传递的参数
+			console.log('onLoad', e.token);
+			this.pageType = e.type
+			let that = this;
+			app.globalData.requestToken = e.token;
+			uni.setStorageSync('token', e.token)
+			getSelectStore({
+				pageNo: 1,
+				pageSize: 20,
+				type: 2,
+				isCarwash: 1,
+				longitude: app.globalData.longitude,
+				latitude: app.globalData.latitude
+			}).then(res => {
+				that.carShop = res.data.rows;
+				that.carShopData = that.carShop[0];
+				console.log('that.carShop', that.carShop);
+				console.log('that.carShop[0]', that.carShop[0]);
+				console.log('shop====================>', uni.getStorageSync('shopData'));
+				if (that.carShopData != undefined) {
+					console.log(that.carShopData.id, 'that.carShopData.idthat.carShopData.id,');
+					carwashService({
+						id: that.carShopData.id
+					}).then(res => {
+						console.log(res, '参数12345');
+						that.carWashType = res.data;
+						that.carwashCode = that.carWashType[0].id
+						if (that.carShop != "" && that.cardMsg != "" && that.carWashType != "") {
+							that.loading = true;
+
+						}
+					})
+					getTimeList({
+						id: that.carShopData.id
+					}).then(res => { //that.carShopData.id
+						that.dataTimeList = res.data
+					})
+					if (that.carShop != "" && that.cardMsg != "" && that.carWashType != "") {
+						that.loading = true;
+					}
+				} else {
+					that.loading = true;
+				}
+			})
+
+			getUserCar().then(res => {
+				console.log(res);
+
+				that.cardMsg = res.data;
+				if (that.carShop != "" && that.cardMsg != "" && that.carWashType != "") {
+					that.loading = true;
+				}
+			})
+
+			/* getByTypeCode({
+				dictTypeCode: "carWashType",
+				
+			}).then(res => {
+				console.log(res.data,'dict');
+				that.carWashType = res.data;
+				that.carwashCode = that.carWashType[0].code
+				if (that.carShop != "" && that.cardMsg != "" && that.carWashType != "") {
+					that.loading = true;
+				}
+			}) */
+		},
+		onShow: function() { //option为object类型,会序列化上个页面传递的参数
+			console.log('onShow');
+			let that = this
+			uni.$on('chooseData', function(data) {
+				console.log('data===========================>', data);
+				that.dataTime = data.data;
+				that.startTime = data.startTime;
+			})
+			uni.$on('chooseCar', function(data) {
+				that.cardMsg = data;
+			})
+			uni.$on('chooseShop', function(data) {
+				console.log('datadddddd==================================>', data);
+				that.carShopData = data;
+				getTimeList({
+					id: that.carShopData.id
+				}).then(res => {
+					console.log(res, 'resss');
+					that.dataTimeList = res.data
+					carwashService({
+						id: that.carShopData.id
+					}).then(res => {
+						that.chooseBtn = 0
+						console.log(res.data, '参数');
+						that.carWashType = res.data;
+						that.carwashCode = res.data[0].id
+						console.log(that.carWashType[0].name, that.carShopData.id, tidhat
+							.cardMsg
+							.id,
+							'that.carWashType[0].name, that.carShopData.id, that.cardMsg.id'
+						);
+						that.getDefaultPrices(that.carWashType[0].name, that.carShopData.id,
+							that.cardMsg.id)
+						that.getMyPackages(that.carWashType[0].name, that.carShopData.id, that
+							.cardMsg.id)
+						if (that.carShop != "" && that.cardMsg != "" && that.carWashType !=
+							"") {
+							that.loading = true;
+						}
+					})
+				})
+			})
+			uni.$on('setMeal', function(data) {
+				that.setMeal = data;
+				if (that.setMeal) {
+					this.carPrice = 0
+				}
+			})
+		},
+		methods: {
+			/* toPay(){
+				uni.requestPayment({
+					provider:"wxpay",
+					
+				})
+			}, */
+			plOrder() {
+				if (this.requestStatus) {
+					// 利用 return 终止函数继续运行
+					return false;
+				}
+				this.requestStatus = true;
+				setTimeout(() => {
+					// 模拟执行完毕
+					// 改变 requestStatus
+					this.requestStatus = false;
+				}, 1000);
+
+				console.log(1);
+
+				let data = {};
+				if (this.cardMsg == "") {
+					uni.showToast({
+						title: "请选择车辆",
+						icon: 'none',
+						duration: 2000,
+					})
+					return
+				} else {
+					data.userCarId = this.cardMsg.id;
+				}
+				if (this.carShopData == "") {
+					uni.showToast({
+						title: "请选择店铺",
+						icon: 'none',
+						duration: 2000,
+					})
+					return;
+				} else {
+					data.shopId = this.carShopData.id;
+				}
+				if (this.carShopData == "") {
+					uni.showToast({
+						title: "请选择店铺",
+						icon: 'none',
+						duration: 2000,
+					})
+					return;
+				} else {
+					data.shopId = this.carShopData.id;
+				}
+				if (this.carwashCode == "") {
+					uni.showToast({
+						title: "请选择服务",
+						// icon: 'none',
+						duration: 2000,
+					})
+					return
+				} else {
+					data.shopServiceId = this.carwashCode
+				}
+				let type = 2
+				if (data.payMoney == 0) type = 0;
+				console.log(this.setMeal);
+				data.payType = type;
+				data.reserveTime = this.startTime;
+				data.payMoney = this.carPrice;
+				console.log(data.payMoney);
+				data.upsId = this.setMeal.id
+				data.upId = this.setMeal.upId
+				data.serviceType = parseInt(this.radioValue);
+				console.log('传参============>time', data);
+				if (data.userCarId == null) {
+					uni.showToast({
+						icon: 'none',
+						title: '请先添加车辆'
+					})
+				} else {
+					if (data.upsId) {
+						carwashOrder(data).then(() => {
+							uni.showToast({
+								icon: 'none',
+								title: '下单成功'
+							})
+							setTimeout(() => {
+								uni.navigateTo({
+									url: '/pages/preCarWash/washOrder/index?token=' + uni
+										.getStorageSync('token')
+								})
+							}, 1000)
+						})
+					} else {
+						uni.navigateTo({
+							url: '/pages/shop/cashierDesk/cashierDesk?page=carwash&params=' + JSON.stringify(data)
+						})
+					}
+				}
+
+			},
+			getDefaultPrices(carwashCode, id, ucId) {
+				let _this = this;
+				console.log(carwashCode, id, ucId, 'carwashCode, id, ucId');
+				getDefaultPrice({
+					carwashName: carwashCode,
+					id: id,
+					ucId: ucId
+				}).then((res) => {
+					_this.carPrice = res.data.carPrice;
+					_this.carScrib = res.data.carScrib;
+				})
+
+			},
+			getMyPackages(carwashCode, id, ucId) {
+				let _this = this;
+				console.log(carwashCode, '店铺id');
+				getMyPackage({
+					carwashName: carwashCode,
+					shopId: id,
+					carId: ucId
+				}).then((res) => {
+					console.log(res, 'ressssss');
+					_this.setMealList = res.data
+				})
+			},
+			radioChange(e) {
+				this.radioValue = e.detail.value
+			},
+			// 路由跳转
+			routerTo(item) {
+				if (item == "门店") {
+					this.$yrouter.push({
+						path: "/pages/preCarWash/chooseShop/index"
+					});
+				} else if (item == "套餐") {
+					if (this.carShopData.id == null) {
+						uni.showToast({
+							title: "请选择店铺",
+							icon: 'none',
+							duration: 2000,
+						})
+						return;
+					}
+					if (this.cardMsg.id == null) {
+						uni.showToast({
+							title: "请选择车辆",
+							icon: 'none',
+							duration: 2000,
+						})
+						return;
+					}
+					let id = this.setMeal.id != undefined ? this.setMeal.id : "";
+					this.$yrouter.push({
+						path: "/pages/preCarWash/setMeal/index?id=" + id + "&setMealList=" + JSON.stringify(this
+								.setMealList) + "&shopId=" + this.carShopData.id + "&carId=" + this.cardMsg.id +
+							"&carWashType=" + this.carWashType[this.chooseBtn].dictCode
+					});
+				} else {
+					this.$yrouter.push({
+						path: "/pages/preCarWash/chooseTime/index?dataTime=" + item + "&shopId=" + this.carShop
+							.id + "&dataTimeList=" + JSON.stringify(this.dataTimeList)
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F5F5F5;
+	}
+
+	.card-view {
+		width: 94%;
+		margin-left: 3%;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 28rpx;
+	}
+
+	.classHead {
+		display: flex;
+		padding-top: 28rpx;
+		width: 100%;
+		height: 28rpx;
+	}
+
+	.classBorder {
+		width: 5rpx;
+		height: 28rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 3rpx;
+	}
+
+	.classTitle {
+		height: 25rpx;
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		padding-left: 28rpx;
+		line-height: 28rpx;
+	}
+
+	.classBody {
+		display: flex;
+		justify-content: start;
+		flex-wrap: wrap;
+	}
+
+	.classChoose {
+		width: 15rpx;
+		height: 23rpx;
+		margin-left: 10rpx;
+	}
+
+	.chooseBtn {
+		width: 204rpx;
+		height: 86rpx;
+		background: linear-gradient(0deg, #FF4800 0%, #FF9600 100%);
+		border-radius: 10rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #FFFFFF;
+		line-height: 86rpx;
+	}
+
+	.btn {
+		width: 204rpx;
+		height: 86rpx;
+		background: #FFFFFF;
+		border: 1px solid #DBDBDB;
+		border-radius: 10rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 86rpx;
+	}
+
+	.radio {
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #333333;
+		line-height: 55rpx;
+		width: 50%;
+	}
+
+	.radioBody {
+		display: flex;
+		padding: 28rpx;
+	}
+
+	.border {
+		width: 650rpx;
+		height: 1px;
+		background: #EEEEEE;
+		border-radius: 1px;
+		margin-left: 4%;
+	}
+
+	.dataTimeBody {
+		height: 100rpx;
+		width: calc(100% - 56rpx);
+		display: flex;
+		padding: 0 28rpx;
+		justify-content: space-between;
+	}
+
+	.dataTime {
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 100rpx
+	}
+
+	.dataNull {
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #A9A9A9;
+		line-height: 100rpx;
+	}
+
+	.dataRight {
+		/* margin-right: 56rpx; */
+		line-height: 100rpx;
+	}
+
+	.price {
+		width: 690rpx;
+		height: 110rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 8rpx 17rpx 0px rgba(168, 165, 165, 0.09);
+		border-radius: 55rpx;
+		margin: 58rpx 0 58rpx 28rpx;
+		position: fixed;
+		bottom: 0rpx;
+	}
+
+	.leftView {
+		float: left;
+		display: flex;
+		padding: 18rpx;
+	}
+
+	.rightView {
+		float: right;
+		width: 240rpx;
+		height: 110rpx;
+		text-align: center;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 0 55rpx 55rpx 0;
+		font-size: 34rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FEFEFE;
+		line-height: 110rpx
+	}
+
+	.classBottomLeft {
+		display: flex;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #005EFF;
+		align-items: baseline;
+	}
+
+	.bottomLaset {
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		text-decoration: line-through;
+		color: #BCBCBC;
+		line-height: 50rpx;
+	}
+
+	.bottomSpan {
+		width: 78rpx;
+		height: 28rpx;
+		text-align: center;
+		background: rgba(255, 181, 158, 0.4);
+		box-shadow: 0px 3rpx 6rpx 0px rgba(212, 84, 24, 0.2);
+		border-radius: 14rpx 14rpx 13rpx 0px;
+		font-size: 20rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FF3C00;
+		line-height: 31rpx;
+	}
+
+	.classBottomRight {
+		padding-left: 18rpx;
+	}
+
+	.unit {
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 31rpx;
+	}
+
+	.num {
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #007DFF;
+		line-height: 31rpx;
+	}
+
+	button::after {
+		border: none;
+	}
+</style>

+ 182 - 0
pages/preCarWash/setMeal/index.vue

@@ -0,0 +1,182 @@
+<template>
+	<view class="">
+		<radio-group @change="radioChange">
+			<view class="setMeal" v-for="(item, index) in setMealList" :key="index" @tap="goBack(item)">
+				<view class="">
+					<view class="classBody">
+						<view class="">
+							<image class="classImg" :src="baseImagePath +item.imgUrl">
+						</view>
+						<view style="padding: 0 0 0 22rpx;">
+							<view class="classBodyHead">
+								{{item.name}}
+							</view>
+							<view class="classBodyContent">
+								{{item.title}}
+							</view>
+						</view>
+						<view class="viewRight">
+							剩
+							<view style="font-weight: bold;font-size: 26rpx;">
+								{{item.surplusSum}}
+							</view>
+							次
+						</view>
+					</view>
+					<view class="border">
+						<view class="classTime">
+							有效期至{{item.invalidDay}}
+						</view>
+						<radio style="line-height: 66rpx;" color="#0078FF" :value="index" :checked="id==index+1" />
+					</view>
+				</view>
+			</view>
+		</radio-group>
+	</view>
+</template>
+
+<script>
+	import {
+		getMyPackage
+	} from "@/api/carWash.js"
+	export default {
+		data: function() {
+			return {
+				id: 0,
+				baseImagePath: this.baseImagePath,
+				setMealList: [],
+				pageNo:1,
+				pageSize:10,
+				shopId:"",
+				carId:"",
+				carWashType:""
+			}
+		},
+		onLoad: function(option) { //option为object类型,会序列化上个页面传递的参数
+			this.id = parseInt(option.id);
+			this.setMealList = JSON.parse(option.setMealList);
+			this.shopId =option.shopId;
+			this.carId = option.carId;
+			this.carWashType = option.carWashType;
+			this.getMyPackage();
+			for (let index in this.setMealList) {
+				let dateTime = Number(this.setMealList[index].invalidDay)
+				let date = new Date(dateTime);
+				//时间戳为10位需*1000,时间戳为13位的话不需乘1000
+				let y = date.getFullYear();
+				let MM = date.getMonth() + 1;
+				MM = MM < 10 ? ('0' + MM) : MM; //月补0
+				let d = date.getDate();
+				d = d < 10 ? ('0' + d) : d; //天补0
+				this.setMealList[index].invalidDay =  y + '.' + MM + '.' + d
+			}
+		},
+		onReachBottom() {
+			this.getMyPackage()
+		},
+		methods: {
+			radioChange(e) {
+
+			},
+			getMyPackage(){
+				let data = {
+					pageNo: this.pageNo,
+					pageSize: this.pageSize,
+					carwashcode:this.carWashType,
+					shopId:this.shopId,
+					carId:this.carId
+				}
+				let that = this;
+				// debugger
+				getMyPackage(data).then((res) => {
+					this.setMealList = [...this.setMealList,...res.data.data]
+					// that.pageNo++
+				})
+			},
+			goBack(datas) {
+				uni.$emit('setMeal', datas)
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+		},
+	}
+</script>
+
+<style>
+	page {
+		background: #EDEDED;
+	}
+
+	.setMeal {
+		width: 710rpx;
+		height: 232rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-left: 20rpx;
+		margin-top: 20rpx;
+
+	}
+
+	.classBody {
+		width: 100%;
+		display: flex;
+		padding: 28rpx 28rpx 0 28rpx;
+	}
+
+	.classImg {
+		width: 120rpx;
+		height: 120rpx;
+		/* background: linear-gradient(135deg, #D10498 0%, #D21728 100%); */
+		border-radius: 8rpx;
+	}
+
+	.classBodyHead {
+		height: 31rpx;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		line-height: 31rpx;
+	}
+
+	.classBodyContent {
+		width: 370rpx;
+		height: 23rpx;
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 31rpx;
+		padding-top: 22rpx;
+	}
+
+	.viewRight {
+		display: flex;
+		height: 100%;
+		margin-left: 68rpx;
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 31rpx;
+	}
+
+	.border {
+		display: flex;
+		justify-content: space-between;
+		width: 660rpx;
+		height: 84rpx;
+		margin-left: 25rpx;
+		height: 1px;
+		border-top: 1px dashed #D4D4D4;
+	}
+
+	.classTime {
+		font-size: 24rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #0062FF;
+		line-height: 66rpx;
+	}
+</style>

+ 366 - 0
pages/preCarWash/washOrder/index.vue

@@ -0,0 +1,366 @@
+<template>
+	<view class="order">
+		<view class="bars">
+			<view style="display: flex;">
+				<view :class="orderType == ''?'bar-select':'bar'" @click="changeType('')">
+					全部
+					<image v-if="orderType==''" :src="require('../../../static/sel.png')" alt="">
+				</view>
+			</view>
+			<view style="display: flex;">
+				<view :class="orderType == '2'?'bar-select':'bar'" @click="changeType('2')">
+					待服务
+					<image v-if="orderType=='2'" :src="require('../../../static/sel.png')" alt="">
+				</view>
+				<span v-if="orderNum>0">{{orderNum}}</span>
+			</view>
+			<view style="display: flex;">
+				<view :class="orderType == '4'?'bar-select':'bar'" @click="changeType('4')">
+					已取消
+					<image v-if="orderType=='4'" :src="require('../../../static/sel.png')" alt="">
+				</view>
+			</view>
+			<view style="display: flex;">
+				<view :class="orderType == '3'?'bar-select':'bar'" @click="changeType('3')">
+					已完成
+					<image v-if="orderType=='3'" :src="require('../../../static/sel.png')" alt="">
+				</view>
+			</view>
+		</view>
+		<view style="height: 80rpx;"></view>
+		<view class="body" v-for="(item, index) in orderList" :key="index" @click="toPath(item)">
+			<view class="header">
+				<view class="orderId">
+					订单编号:{{item.orderNumber}}
+				</view>
+				<view class="orderType" :style="item.status==1 || item.status==2?'color: #005BFF;':'color: #666666;'">
+					{{item.status==1?'待支付':item.status==2?'待服务':item.status==3?'已完成':item.status==4?'已取消':'进行中'}}
+					<image :src="require('../../../static/choose.png')" alt="">
+				</view>
+			</view>
+			<view class="carView">
+				<image :src="baseImagePath+item.carLogo" alt="">
+					<view class="carBody">
+						<view class="carTitle">
+							<image :src="require('../../../static/car.png')" alt="">
+								<span>{{item.carNumber}}</span>
+								<view class="border"></view>
+								<span>{{item.carMadelLevel}}</span>
+								<view class="border"></view>
+								<span>{{item.carWashType}}</span>
+						</view>
+						<view class="content">
+							{{item.carTypeName}}
+						</view>
+					</view>
+			</view>
+			<view class="shop">
+				<image :src="require('../../../static/shop.png')" alt="">
+					<view style="padding-left: 16rpx;">
+						门店:{{item.shopName}}
+					</view>
+
+			</view>
+			<view class="times" :style="item.orderType==2?'border-bottom: 1px solid #EEEEEE;':''">
+				<image :src="require('../../../static/time.png')" alt="">
+					<view style="padding-left: 16rpx;">
+						时间:{{item.time}}
+					</view>
+			</view>
+			<view v-if="item.status==3 && item.isEvaluate == 2">
+				<view class="buttomBtn" @click.stop="toEvaluation(item.id)">
+					评价
+				</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		carwashOrderList
+	} from "@/api/carWash.js"
+	const app = getApp();
+	export default {
+		components: {},
+		data: function() {
+			return {
+				requestStatus: false,
+				baseImagePath: this.baseImagePath,
+				orderNum: null,
+				orderType: "",
+				orderList: [],
+				pageNo: 1,
+				pageSize: 20,
+			}
+		},
+		onReachBottom() {
+			let that = this
+			that.pageNo++
+			this.getPage()
+		},
+		onLoad(e) {
+			app.globalData.requestToken = e.token;
+			uni.setStorageSync('token', e.token)
+		},
+		onShow() {
+			this.pageNo = 1
+			this.getPage(1)
+		},
+		onBackPress(options) {
+			console.log('11111');
+			// 这里可以自定义返回逻辑,比如下面跳转其他页面
+			// #ifdef APP-PLUS
+			if (plus.os.name.toLowerCase() === 'android') {
+				plus.runtime.quit();
+			} else {
+				plus.runtime.quit();
+			}
+			// #endif
+			// return true 表示禁止默认返回
+			return true;
+		},
+		methods: {
+			changeType(val) {
+				this.orderType = val;
+				this.pageNo = 1;
+				this.getPage(1);
+			},
+			getPage(val) {
+				let data = {
+					status: this.orderType,
+					pageNo: this.pageNo,
+					pageSize: this.pageSize
+				}
+				let that = this;
+				carwashOrderList(data).then((res) => {
+					console.log(res);
+					that.orderNum = res.data.beServiceNum;
+					if (val == 1) {
+						that.orderList = [];
+					}
+					that.orderList = that.orderList.concat(res.data.carWashOrderListVO.rows)
+				})
+			},
+			toPath(item) {
+				console.log('订单详情', item);
+				this.$yrouter.push({
+					path: "/pages/preCarWash/washOrder/orderDetail/index?data=" + encodeURIComponent(JSON
+						.stringify(item))
+				});
+			},
+			toEvaluation(id) {
+				if (this.requestStatus) {
+					// 利用 return 终止函数继续运行
+					return false;
+					console.log(1);
+
+				}
+				this.$yrouter.push({
+					path: "/pages/preCarWash/washOrder/serviceEvaluation/index?type=3&detailId=" + id
+				});
+				console.log('按钮点击函数执行');
+				// 执行函数
+				this.requestStatus = true;
+				setTimeout(() => {
+					// 模拟执行完毕
+					// 改变 requestStatus
+					this.requestStatus = false;
+				}, 1000);
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.order {
+		.bars {
+			width: 100%;
+			height: 80rpx;
+			background: #FFFFFF;
+			box-shadow: 0px 1px 0px 0px rgba(55, 55, 55, 0.1);
+			display: flex;
+			justify-content: space-around;
+			align-items: center;
+			position: fixed;
+			top: 0;
+			z-index: 999;
+
+			.bar {
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				background-color: #FFFFFF;
+			}
+
+			span {
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #005BFF;
+				padding-left: 12rpx;
+			}
+		}
+
+		.bar-select {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			font-size: 28rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #333333;
+
+			image {
+				width: 34rpx;
+				height: 11rpx;
+			}
+		}
+
+		.body {
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+			padding: 30rpx;
+
+			.header {
+				display: flex;
+				justify-content: space-between;
+				border-bottom: 1rpx solid #EEEEEE;
+				padding-bottom: 30rpx;
+
+				.orderId {
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 34rpx;
+				}
+
+				.orderType {
+					display: flex;
+					align-items: center;
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+
+					line-height: 34rpx;
+
+					image {
+						padding-left: 8rpx;
+						width: 11rpx;
+						height: 18rpx;
+					}
+				}
+			}
+
+			.carView {
+				display: flex;
+
+				image {
+					width: 120rpx;
+					height: 120rpx;
+					background: #FFFFFF;
+					border: 2rpx solid #F4F4F4;
+					border-radius: 8rpx;
+					margin-top: 32rpx;
+				}
+
+				.carBody {
+					padding: 32rpx;
+
+					.carTitle {
+						display: flex;
+
+						image {
+							width: 33rpx;
+							height: 27rpx;
+							margin-top: 0rpx;
+						}
+
+						.border {
+							width: 1px;
+							height: 20rpx;
+							background: #DBDBDB;
+						}
+
+						span {
+							font-size: 30rpx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #333333;
+							line-height: 31rpx;
+							padding: 0 15rpx 0 15rpx;
+							white-space: nowrap;
+						}
+					}
+
+					.content {
+						font-size: 26rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 34rpx;
+						padding: 20rpx 60rpx 20rpx 0;
+					}
+				}
+			}
+
+			.shop {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+
+				image {
+					width: 30rpx;
+					height: 26rpx;
+				}
+			}
+
+			.times {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				margin-top: 31rpx;
+				padding-bottom: 30rpx;
+
+				image {
+					width: 30rpx;
+					height: 26rpx;
+				}
+			}
+
+			.buttomBtn {
+				width: 148rpx;
+				height: 56rpx;
+				background: #FFFFFF;
+				border: 1px solid #003EFF;
+				border-radius: 28rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #0051FF;
+				line-height: 56rpx;
+				text-align: center;
+				margin: 26rpx 31rpx 0 74%;
+			}
+		}
+	}
+</style>

+ 405 - 0
pages/preCarWash/washOrder/orderDetail/index.vue

@@ -0,0 +1,405 @@
+<template>
+	<view class="orderDetail">
+		<view class="orderHeader">
+			<!-- 手机状态栏占位 -->
+			<view class="statusBar" :style="{height:statusBarHeight+'rpx'}"></view>
+			<!-- 导航栏 -->
+			<view class="navigationBar" :style="{height:navigationBarHeight,paddingTop:statusBarHeight+'rpx'}">
+				<view @tap="goBack">
+					<image :src="require('../../../../static/backw.png')" alt="">
+				</view>
+
+				<view class="navigationTitle">
+					订单详情
+				</view>
+			</view>
+			<view class="serveBody">
+				<image :src="require('../../../../static/icon-fuwu.png')" alt="">
+					<view class="serveTitle">
+						{{orderData.status==1?'待支付':orderData.status==2?'待服务':orderData.status==3?'已完成':orderData.status==4?'已取消':'进行中'}}
+					</view>
+			</view>
+		</view>
+		<view class="orderBody">
+			<view class="orderDetail">
+				<view class="carView">
+					<image :src="baseImagePath+orderData.carLogo" alt="">
+						<view class="carBody">
+							<view class="carTitle">
+								<image :src="require('../../../../static/car.png')" alt="">
+									<span>{{orderData.carNumber}}</span>
+									<view class="border"></view>
+									<span>{{orderData.carMadelLevel}}</span>
+									<view class="border"></view>
+									<span>{{orderData.upsName}}</span>
+							</view>
+							<view class="content">
+								{{orderData.carTypeName}}
+							</view>
+						</view>
+				</view>
+				<view class="shop">
+					<image :src="require('../../../../static/shop.png')" alt="">
+						<view style="padding-left: 16rpx;">
+							门店:{{orderData.shopName}}
+						</view>
+
+				</view>
+				<view class="times">
+					<image :src="require('../../../../static/time.png')" alt="">
+						<view style="padding-left: 16rpx;">
+							时间:{{orderData.time}}
+						</view>
+				</view>
+				<view>
+					<view class="buttomBtn">
+						<view v-if="orderData.status==1" class="orderBtn" @click="plOrder">
+							立即支付
+						</view>
+						<view style="white-space: nowrap;">
+							实付:<span style="font-size: 26rpx;font-weight: bold;">¥ </span><span
+							style="font-size: 40rpx;font-weight: bold;white-space: nowrap;">{{orderData.payMoney}}</span>
+						</view>
+						
+					</view>
+				</view>
+			</view>
+			<view class="explain">
+				<view class="orders" v-if="orderData.orderNumber">
+					订单编号:{{orderData.orderNumber}}
+					<view class="span" @click="copy(orderData.orderNumber)">复制</view>
+				</view>
+				<view class="orders" v-if="orderData.createTimeStr">
+					下单时间:{{orderData.createTimeStr}}
+				</view>
+				<view class="orders" v-if="orderData.payTimeStr">
+					支付时间:{{orderData.payTimeStr}}
+				</view>
+				<view class="orders" v-if="orderData.startTimeStr">
+					服务时间:{{orderData.startTimeStr}}
+				</view>
+				<view class="orders" v-if="orderData.accomplishTimeStr">
+					完成时间:{{orderData.accomplishTimeStr}}
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	import {
+		getUserCar
+	} from "@/api/shop.js"
+	import {
+		carwashOrderDetail,
+		carwashOrder
+	} from "@/api/carWash.js"
+	export default {
+		components: {},
+		data: function() {
+			return {
+				baseImagePath: this.baseImagePath,
+				orderData: {},
+				usercar:{},
+				statusBarHeight: "",
+				navigationBarHeight: "",
+				navHeight: ""
+			}
+		},
+		onLoad(options) {
+			this.orderData = JSON.parse(decodeURIComponent(options.data));
+
+			carwashOrderDetail({
+				id: this.orderData.id
+			}).then((res) => {
+				console.log(res);
+				this.orderData = res.data;
+			})
+			// 状态栏高度
+			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
+
+			// #ifdef MP-WEIXIN
+			// 获取微信胶囊的位置信息 width,height,top,right,left,bottom
+			const custom = wx.getMenuButtonBoundingClientRect()
+			// console.log(custom)
+			// 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
+			this.navigationBarHeight = custom.height + (custom.top - this.statusBarHeight) * 2
+
+			// console.log("导航栏高度:"+this.globalData.navigationBarHeight)
+
+			// 总体高度 = 状态栏高度 + 导航栏高度
+			this.navHeight = (this.navigationBarHeight + this.statusBarHeight)
+			this.navigationBarHeight = this.navigationBarHeight + 'px'
+			this.statusBarHeight = this.statusBarHeight + 'px'
+			this.navHeight = this.navHeight + 'px'
+
+			// #endif
+			
+		},
+		onShow(){
+			getUserCar().then(res => {
+				console.log(res.data);
+				this.usercar = res.data
+				console.log(this.usercar);
+				console.log(this.usercar.id);
+			})
+		},
+		methods: {
+			plOrder() {
+				let data = {}
+				data.userCarId = this.usercar.id
+				data.shopId = this.orderData.shopId
+				data.shopServiceId = this.orderData.shopServiceId
+				data.payType = this.orderData.payType
+				data.reserveTime = this.orderData.reserveTime
+				data.payMoney = this.orderData.payMoney
+				data.serviceType = this.orderData.serviceType
+				console.log(data);
+				console.log(this.orderData);
+				console.log(this.orderData.payMoney);
+				carwashOrder(data).then(() => {
+					uni.showToast({
+						icon: 'none',
+						title: '正在跳转收银台'
+					})
+					uni.navigateTo({
+						url: '/pages/shop/cashierDesk/cashierDesk?page=carwash&params=' + JSON.stringify(data)
+					})
+				})
+			},
+			goBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			copy(val) {
+				uni.setClipboardData({
+					data: val, // 要复制的文字
+					success: function(res) {
+						uni.getClipboardData({
+							success: function(res) {
+								uni.showToast({
+									title: '复制成功'
+								});
+							}
+						});
+					}
+				});
+			},
+		},
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.orderBody {
+		position: absolute;
+		top: 315rpx;
+
+		// 
+		.orderDetail {
+			width: 710rpx;
+			height: 440rpx;
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+
+			.carView {
+				display: flex;
+				padding: 26rpx;
+
+				image {
+					width: 120rpx;
+					height: 120rpx;
+					background: #FFFFFF;
+					border: 2rpx solid #F4F4F4;
+					border-radius: 8rpx;
+					padding-top: 14rpx;
+				}
+
+				.carBody {
+					padding: 14rpx 29rpx 14rpx 29rpx;
+
+					.carTitle {
+						display: flex;
+
+						image {
+							width: 33rpx;
+							height: 27rpx;
+							padding-top: 0rpx;
+						}
+
+						.border {
+							width: 1px;
+							height: 20rpx;
+							background: #DBDBDB;
+						}
+
+						span {
+							font-size: 30rpx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #333333;
+							line-height: 31rpx;
+							padding: 0 15rpx 0 15rpx;
+						}
+					}
+
+					.content {
+						font-size: 26rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 34rpx;
+						padding: 20rpx 60rpx 20rpx 0;
+					}
+				}
+			}
+
+			.shop {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				padding: 15rpx 30rpx 15rpx 30rpx;
+
+				image {
+					width: 30rpx;
+					height: 26rpx;
+				}
+			}
+
+			.times {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				margin-top: 16rpx;
+				padding-bottom: 30rpx;
+				padding: 0rpx 30rpx 15rpx 30rpx;
+
+				image {
+					width: 30rpx;
+					height: 26rpx;
+				}
+			}
+
+			.buttomBtn {
+				height: 33rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				text-align: center;
+				margin: 26rpx 31rpx 0 74%;
+
+				.orderBtn {
+					width: 156rpx;
+					height: 56rpx;
+					text-align: center;
+					background: linear-gradient(0deg, #008EFF 0%, #0036FF 100%);
+					border-radius: 28rpx;
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FFFFFF;
+					line-height: 56rpx;
+				}
+			}
+		}
+
+		.explain {
+			width: 710rpx;
+			// height: 344rpx;
+			background: #FFFFFF;
+			border-radius: 10rpx;
+			margin: 20rpx;
+			padding-top: 11rpx;
+			padding-bottom: 40rpx;
+
+			.orders {
+				display: flex;
+				align-items: center;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 34rpx;
+				padding: 33rpx 0 0 29rpx;
+
+				.span {
+					text-align: center;
+					margin-left: 16rpx;
+					width: 70rpx;
+					height: 28rpx;
+					border: 1px solid #999999;
+					border-radius: 14rpx;
+					font-size: 18rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+					line-height: 28rpx;
+				}
+			}
+		}
+	}
+
+	.orderHeader {
+		width: 100%;
+		height: 454rpx;
+		background-image: url(../../../../static/cardbg.png);
+		// background-image: url(../../../../static/bgcard.png);
+		background-size: 100% 100%;
+
+		.navigationBar {
+			display: flex;
+			align-items: center;
+			text-align: center;
+
+			image {
+				padding-left: 17rpx;
+				width: 44rpx;
+				height: 44rpx;
+			}
+
+			.navigationTitle {
+				padding-left: 242rpx;
+				font-size: 36rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				line-height: 75rpx;
+			}
+		}
+
+		.serveBody {
+			display: flex;
+			align-items: center;
+			margin-top: 73rpx;
+			margin-left: 38rpx;
+
+			image {
+				width: 37rpx;
+				height: 39rpx;
+			}
+
+			.serveTitle {
+				font-size: 36rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				line-height: 75rpx;
+				padding-left: 20rpx;
+			}
+		}
+	}
+</style>

+ 339 - 0
pages/preCarWash/washOrder/serviceEvaluation/index.vue

@@ -0,0 +1,339 @@
+<template>
+	<view class="serveEva">
+		<view class="card">
+			<view class="title">
+				服务态度
+			</view>
+			<view class="star">
+				<view v-for="(subItem, indexs) in starList" :key="indexs" @click="changemanner(indexs)">
+					<image :src="manner==indexs+0.5?subItem.half:(indexs+1)<=manner?subItem.stary:subItem.starsg"
+						alt="">
+				</view>
+
+			</view>
+		</view>
+		<view class="card">
+			<view class="title">
+				服务质量
+			</view>
+			<view class="star">
+				<view v-for="(subItem, indexs) in starList" :key="indexs" @click="changequality(indexs)">
+					<image :src="quality==indexs+0.5?subItem.half:(indexs+1)<=quality?subItem.stary:subItem.starsg"
+						alt="">
+				</view>
+			</view>
+		</view>
+		<view class="body">
+			<view class="card">
+				<view class="title">
+					综合服务
+				</view>
+				<view class="star">
+					<view v-for="(subItem, indexs) in starList" :key="indexs" @click="changezonghe(indexs)">
+						<image :src="zonghe==indexs+0.5?subItem.half:(indexs+1)<=zonghe?subItem.stary:subItem.starsg"
+							alt="">
+					</view>
+				</view>
+			</view>
+			<view class="content">
+				<!-- 描述详情 -->
+				<textarea class="textarea" placeholder="请输入车辆遇到的问题/状况描述" v-model="content"
+					placeholder-class="classTextarea" maxlength="-1"></textarea>
+				<!-- 上传图片 -->
+				<view class="uploadFile">
+					<view class="uploadView" v-for="(item, index) in uploadFileList" :key="index">
+						<image @click="del(index)" class="uploadDelete"
+							:src="require('../../../../static/uploadDelete.png')" alt="">
+							<image class="uploadImg" :src="item" alt="">
+
+					</view>
+					<view class="uploadView">
+						<image @click="upload" class="uploadImg" :src="require('../../../../static/upload-pic.png')"
+							alt="">
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="buttomBtn" @click="evaluateAdd">
+			立即评价
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		orderEvaluate
+	} from "@/api/maintain.js"
+	export default {
+		components: {},
+		data: function() {
+			return {
+				clickName: false,
+				manner: 0,
+				quality: 0,
+				zonghe: 0,
+				content: "",
+				starList: [{
+						starsg: require('../../../../static/star-s-g.png'),
+						half: require('../../../../static/half.png'),
+						stary: require('../../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../../static/star-s-g.png'),
+						half: require('../../../../static/half.png'),
+						stary: require('../../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../../static/star-s-g.png'),
+						half: require('../../../../static/half.png'),
+						stary: require('../../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../../static/star-s-g.png'),
+						half: require('../../../../static/half.png'),
+						stary: require('../../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../../static/star-s-g.png'),
+						half: require('../../../../static/half.png'),
+						stary: require('../../../../static/star-y.png'),
+					}
+				],
+				uploadFileList: [],
+				type: 0,
+				detailId: "",
+				imgContent: ""
+			}
+		},
+		onLoad(options) {
+			this.type = options.type;
+			this.detailId = options.detailId;
+		},
+		methods: {
+			evaluateAdd() {
+				if (!this.clickName) {
+					// 第一次点击
+					let data = {
+						type: this.type,
+						detailId: this.detailId,
+						serviceScore: this.manner,
+						satisfiedScore: this.quality,
+						sumScore: this.zonghe,
+						content: this.content,
+						imgContent: this.imgContent
+					}
+					orderEvaluate(data).then((res) => {
+						if (res.code == "00000") {
+							if (this.type == 1) {
+								uni.$emit('maintainEvaluateOver', {
+									data: "评价完成"
+								})
+							}
+							uni.navigateBack({
+								delta: 1
+							})
+						}
+					})
+					this.clickName = true;
+					
+				} else {
+					console.log(this.clickName);
+				}
+
+
+
+			},
+			changemanner(index) {
+				if (this.manner == index + 0.5) {
+					this.manner = index + 1;
+				} else if (this.manner >= index + 1) {
+					this.manner = index
+				} else if (this.manner == index + 1) {
+					this.manner--
+				} else {
+					this.manner = index + 0.5;
+				}
+			},
+			changequality(index) {
+				if (this.quality == index + 0.5) {
+					this.quality = index + 1;
+				} else if (this.quality >= index + 1) {
+					this.quality = index
+				} else if (this.quality == index + 1) {
+					this.quality--
+				} else {
+					this.quality = index + 0.5;
+				}
+			},
+			changezonghe(index) {
+				if (this.zonghe == index + 0.5) {
+					this.zonghe = index + 1;
+				} else if (this.zonghe >= index + 1) {
+					this.zonghe = index
+				} else if (this.zonghe == index + 1) {
+					this.zonghe--
+				} else {
+					this.zonghe = index + 0.5;
+				}
+			},
+			// 删除图片
+			del(index) {
+				this.uploadFileList.splice(index, 1);
+				console.log(this.uploadFileList);
+			},
+			upload() {
+				let that = this;
+				uni.chooseImage({
+					count: 9, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					loop: true,
+					success: res => {
+						console.log(res);
+						if (res.tempFilePaths.length != 0) {
+							this.uploadFileList.push(res.tempFilePaths[0]);
+						}
+						console.log(JSON.stringify(res.tempFilePaths));
+						var tempFilePaths = res.tempFilePaths;
+						var tempFiles = res.tempFiles;
+						console.log(tempFilePaths);
+						console.log(tempFilePaths[0]);
+						uni.uploadFile({
+							url: 'https://api.biaodianfuhao.net/api/common/sysFileInfo/upload',
+							fileType: 'image',
+							filePath: tempFilePaths[0],
+							file: tempFiles[0],
+							name: 'file',
+							success: uploadFileRes => {
+								console.log('上传图片', JSON.parse(uploadFileRes.data));
+								if (that.imgContent == "") {
+									that.imgContent = JSON.parse(uploadFileRes.data).data
+								}
+								that.imgContent = that.imgContent + "," + JSON.parse(uploadFileRes
+									.data).data
+							},
+							fail(err) {
+								console.log(err);
+							}
+						});
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.buttomBtn {
+		width: 690rpx;
+		height: 90rpx;
+		background: linear-gradient(0deg, #008EFF 0%, #0036FF 100%);
+		border-radius: 45rpx;
+		margin-left: 30rpx;
+		text-align: center;
+		font-size: 32rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #FFFFFF;
+		line-height: 90rpx;
+		margin-top: 282rpx;
+
+	}
+
+	.body {
+		margin-top: 20rpx;
+		background: #FFFFFF;
+		padding-bottom: 30rpx;
+
+		.content {
+			height: 404rpx;
+			background: #F7F7F7;
+			border-radius: 10rpx;
+			margin: 6rpx 30rpx 30rpx 30rpx;
+
+			.textarea {
+				height: 150rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+				padding-left: 20rpx;
+				padding-top: 40rpx;
+			}
+		}
+
+		.uploadFile {
+			width: 665rpx;
+			height: 146rpx;
+			display: flex;
+			overflow-x: auto;
+			margin-left: 20rpx;
+
+			.uploadView {
+				position: relative;
+
+				.uploadImg {
+					width: 146rpx;
+					height: 146rpx;
+					background: #FFFFFF;
+					border-radius: 8px;
+					margin-right: 17rpx;
+					margin-bottom: 21rpx;
+				}
+
+				.uploadDelete {
+					width: 26rpx;
+					height: 26rpx;
+					border-radius: 0 8px 0 0;
+					position: absolute;
+					top: 0;
+					right: 17rpx;
+					z-index: 9;
+				}
+			}
+
+		}
+	}
+
+	.classTextarea {
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #BFBFBF;
+		line-height: 34rpx;
+	}
+
+	.serveEva {
+		.card {
+			background: #FFFFFF;
+			height: 100rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			padding: 0 31rpx 0 31rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+			}
+
+			.star {
+				display: flex;
+				margin-top: 12rpx;
+
+				image {
+					width: 22rpx;
+					height: 22rpx;
+				}
+			}
+		}
+	}
+</style>

+ 8 - 0
pages/shop/CarsClass/index.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 8 - 0
pages/shop/LeaseCarClass/index.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 8 - 0
pages/shop/ShoppingMall/index.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 375 - 0
pages/shop/cashierDesk/cashierDesk.vue

@@ -0,0 +1,375 @@
+<template>
+	<view>
+		<view class="goback" v-if="this.show == true">
+			<view class="gb-bg">
+				<view class="check">
+					确认要离开收银台吗?
+				</view>
+				<view class="toast">
+					订单已提交成功,超时未支付将会取消订单,请尽快完成支付。
+				</view>
+				<view class="but">
+					<view class="no" @click="no()">
+						取消支付
+					</view>
+					<view class="yes" @click="yes()">
+						继续支付
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="payBlock">
+			<view class="payMoney">
+				<text style="font-size: 32rpx;">¥</text>{{payData.payMoney.toFixed(2)}}
+			</view>
+			<view class="payToast">需支付</view>
+		</view>
+		<view class="payCheck">
+			<view class="typeBlock border-b" @click="type = 2">
+				<view class="payCheckTitle">
+					<image src="../../../static/alipay.png" class="payTypeImage"></image>
+					<view class="payTitle">支付宝支付</view>
+				</view>
+				<image src="../../../static/sel@2x.png" v-if="type === 2" class="checkIcon"></image>
+				<image src="../../../static/unsel.png" v-else class="checkIcon"></image>
+			</view>
+			<view class="typeBlock border-b" @click="type = 1">
+				<view class="payCheckTitle">
+					<image src="../../../static/wechat.png" class="payTypeImage"></image>
+					<view class="payTitle">微信支付</view>
+				</view>
+				<image src="../../../static/sel@2x.png" v-if="type === 1" class="checkIcon"></image>
+				<image src="../../../static/unsel.png" v-else class="checkIcon"></image>
+			</view>
+			<view class="typeBlock" @click="type = 3">
+				<view class="payCheckTitle">
+					<image src="../../../static/yu‘e@2x.png" class="payTypeImage"></image>
+					<view class="payTitle">余额支付</view>
+					<view class="balance">(可用¥{{balance}})</view>
+				</view>
+				<image src="../../../static/sel@2x.png" v-if="type === 3" class="checkIcon"></image>
+				<image src="../../../static/unsel.png" v-else class="checkIcon"></image>
+			</view>
+		</view>
+		<view class="payBtn" @click="toPay()">
+			{{type==1?'微信':type==2?'支付宝':'余额'}}支付¥{{payData.payMoney.toFixed(2)}}
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getUserInfo
+	} from "../../../api/myApi.js"
+	import {
+		carwashOrder
+	} from "@/api/carWash.js"
+	import {
+		payOrder
+	} from '../../../api/maintain.js'
+	export default {
+		data() {
+			return {
+				show: false,
+				payData: {},
+				type: 1,
+				balance: 0,
+				orderInfo: '',
+				page: ''
+			};
+		},
+		onLoad(options) {
+			this.payData = JSON.parse(options.params)
+			this.page = options.page
+			this.getUser()
+			console.log(this.payData);
+		},
+		onBackPress(e) {
+			if (e.from == 'backbutton') {
+				this.show = true
+				return true;
+			} else if (e.from == 'navigateBack') {
+				return false;
+			}
+		},
+		methods: {
+			no() {
+				uni.showToast({
+					icon: "none",
+					title: "顾客取消支付"
+				})
+				setTimeout(()=>{
+					uni.navigateBack({
+						delta: 1
+					})
+				}, 1000)
+
+			},
+			yes() {
+				this.show = false
+			},
+			toPay() {
+				this.payData.payType = this.type
+				if (this.payData.payType === 3) {
+					if (this.payData.payMoney > this.balance) {
+						return uni.showToast({
+							icon: "none",
+							title: "余额不足"
+						})
+					}
+				}
+				if (this.page === 'carwash') {
+					this.carWash()
+				} else if (this.page === 'maintenance') {
+					this.maintenance()
+				}
+			},
+			getUser() {
+				getUserInfo().then(res => {
+					this.balance = res.data.balance
+				})
+			},
+			carWash() {
+				carwashOrder(this.payData).then(res => {
+					if (this.payData.payType === 1 || this.payData.payType === 2) {
+						if (this.payData.payType === 1) {
+							this.orderInfo = res.data.wechatOrder
+						} else if (this.payData.payType === 2) {
+							this.orderInfo = res.data.zfbOrder
+						}
+						this.payment()
+					}
+				})
+			},
+			maintenance() {
+				payOrder(this.payData).then(res => {
+					if (this.payData.payType === 1 || this.payData.payType === 2) {
+						if (this.payData.payType === 1) {
+							this.orderInfo = res.data.wechatOrder
+						} else if (this.payData.payType === 2) {
+							this.orderInfo = res.data.zfbOrder
+						}
+						this.payment()
+					}
+				})
+			},
+			payment() {
+
+				let payType = this.payData.payType === 1 ? 'wxpay' : 'alipay'
+				console.log('订单西悉尼', this.orderInfo);
+				uni.requestPayment({
+					provider: payType,
+					orderInfo: this.orderInfo,
+					success: (res) => {
+						console.log('下单支付===============>', res);
+
+						if (this.page === 'carwash') {
+							uni.redirectTo({
+								url: '/pages/preCarWash/washOrder/index?token=' + uni.getStorageSync(
+									'token')
+							})
+						} else if (this.page === 'maintenance') {
+							uni.redirectTo({
+								url: '/pages/maintenance/maintainOrder/index?token=' + uni
+									.getStorageSync('token')
+							})
+						}
+					},
+					fail: (res) => {
+						console.log(res, '支付失败fail');
+						uni.showToast({
+							icon: 'none',
+							title: '支付失败:' + res.errMsg + ',code:' + res.code + ',errCode:' + res
+								.errCode
+						})
+					}
+				})
+
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #F5F5F5;
+	}
+
+	.goback {
+		width: 100%;
+		height: 100%;
+		background-color: rgba(0, 0, 0, 0.5);
+		position: fixed;
+		z-index: 999999999999999999;
+		top: 0;
+
+		.gb-bg {
+			width: 600rpx;
+			height: 378rpx;
+			background: #FFFFFF;
+			border-radius: 16rpx;
+			box-sizing: border-box;
+			padding: 50rpx 70rpx;
+			margin: 0 auto;
+			margin-top: 50%;
+
+			.check {
+				height: 29rpx;
+				font-size: 30rpx;
+				font-weight: bold;
+				color: #333333;
+				line-height: 40rpx;
+				text-align: center;
+			}
+
+			.toast {
+				width: 467rpx;
+				height: 63rpx;
+				font-size: 26rpx;
+				font-weight: 500;
+				color: #333333;
+				line-height: 36rpx;
+				margin: 56rpx 0;
+			}
+
+			.but {
+				display: flex;
+				justify-content: space-between;
+
+				.no {
+					width: 210rpx;
+					height: 70rpx;
+					background: #FFFFFF;
+					border: 1px solid #0060FF;
+					border-radius: 35rpx;
+					font-size: 28rpx;
+					font-weight: 500;
+					color: #0062FF;
+					line-height: 70rpx;
+					text-align: center;
+				}
+
+				.yes {
+					width: 210rpx;
+					height: 70rpx;
+					background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+					border-radius: 35rpx;
+					font-size: 28rpx;
+					font-weight: 500;
+					color: #FFFFFF;
+					line-height: 70rpx;
+					text-align: center;
+				}
+			}
+
+		}
+	}
+
+	.payBlock {
+		width: 100%;
+		height: 225rpx;
+		background-color: $uni-text-color-inverse;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		border-radius: 0 0 16rpx 16rpx;
+		margin-bottom: 30rpx;
+
+		.payMoney {
+			font: {
+				size: 50rpx;
+				weight: bold;
+			}
+
+			;
+			color: $uni-text-color;
+		}
+
+		.payToast {
+			font: {
+				size: 24rpx;
+				weight: 500;
+			}
+
+			;
+			color: $uni-text-color-grey;
+		}
+	}
+
+	.payCheck {
+		width: calc(100% - 80rpx);
+		padding: 0 40rpx;
+		background-color: $uni-text-color-inverse;
+		border-radius: 16px;
+
+		.typeBlock {
+			width: calc(100% - 10rpx);
+			height: 125rpx;
+			padding-left: 10rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+
+			.payCheckTitle {
+				height: 100%;
+				display: flex;
+				align-items: center;
+
+				.payTypeImage {
+					width: 44rpx;
+					height: 44rpx;
+				}
+
+				.payTitle {
+					font: {
+						size: 30rpx;
+						weight: 500;
+					}
+
+					;
+					color: $uni-text-color;
+					margin-left: 24rpx;
+				}
+
+				.balance {
+					font: {
+						size: 30rpx;
+						weight: 500;
+					}
+
+					;
+					color: $uni-text-color-grey;
+					margin-left: 17rpx;
+				}
+			}
+
+			.checkIcon {
+				width: 36rpx;
+				height: 36rpx;
+			}
+		}
+
+		.border-b {
+			border-bottom: 1px solid #EEEEEE;
+		}
+	}
+
+	.payBtn {
+		width: 600rpx;
+		height: 90rpx;
+		text-align: center;
+		line-height: 90rpx;
+		background: linear-gradient(0deg, #0078FF 0%, #005AFF 100%);
+
+		font: {
+			size: 32rpx;
+			weight: 500;
+		}
+
+		;
+		color: $uni-text-color-inverse;
+		border-radius: 45rpx;
+		margin: 174rpx auto;
+	}
+</style>

+ 95 - 0
pages/shop/navigation/navigation.vue

@@ -0,0 +1,95 @@
+<template>
+	<view>
+		<map class="mapStyle" :markers="markers" :latitude="latitude" :longitude="longitude"></map>
+		<view class="shopInfo">
+			<view>
+				<view class="shopName">{{shopName}}</view>
+				<view class="shopAddress">
+					<view>{{address}}</view>
+					<view>距离{{distance}}km</view>
+				</view>
+			</view>
+			<view class="toNavi" @click="toCall()">去导航</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				latitude: '',
+				longitude:'',
+				markers:[{
+					latitude:'',
+					longitude:'',
+					width:100,
+					height:100,
+					iconPath:'../../../static/dianpu.png',
+				}],
+				shopName:'',
+				address:'',
+				distance:'',
+				phone:''
+			};
+		},
+		onLoad(options) {
+			console.log(options);
+			this.latitude = options.latitude,
+			this.longitude = options.longitude
+			this.markers[0].latitude = options.latitude,
+			this.markers[0].longitude = options.longitude
+			this.shopName = options.shopTitle
+			this.address = options.address
+			this.distance = options.distance
+			this.phone = options.phone
+		},
+		methods:{
+			toCall(){
+				let dst = new plus.maps.Point(this.longitude,this.latitude)
+				let src = new plus.maps.Point(this.longitude,this.latitude)
+				plus.maps.openSysMap(dst,this.shopName,src)
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+.mapStyle{
+	width: 100%;
+	height: 86vh;
+}
+.shopInfo{
+	width: 100%;
+	height: 14vh;
+	position: absolute;
+	bottom: 0;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	.shopName{
+		font-size: 32rpx;
+		font-weight: bold;
+		margin-left: 50rpx
+	}
+	.shopAddress{
+		font-size: 28rpx;
+		font-weight: 500;
+		margin-top: 10rpx;
+		margin-left: 50rpx;
+		color: #999999;
+	}
+	.toNavi{
+		width: 200rpx;
+		height: 80rpx;
+		background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+		border-radius: 40rpx;
+		text-align: center;
+		font-size: 30rpx;
+		font-weight: bold;
+		color: #FFFFFF;
+		line-height: 80rpx;
+		margin-right: 50rpx;
+	}
+}
+</style>

+ 26 - 0
pages/shop/shopDetail/ShopInclude/ShopInclude.vue

@@ -0,0 +1,26 @@
+<template>
+	<view>
+		<web-view :src="url"></web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				url:''
+			}
+		},
+		methods: {
+			
+		},
+		onLoad(options){
+			this.url = options.url
+			console.log(this.url);
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 935 - 0
pages/shop/shopDetail/index.vue

@@ -0,0 +1,935 @@
+<template>
+	<view class="shopDetail" :style="{marginTop:statusBarHeight}">
+		<view class="header">
+			<view class="hdbefore">
+				<image :src="baseImagePath+shopData.logoUrl" alt="" style="width: 100%;height: 100%;">
+			</view>
+			<!-- 手机状态栏占位 -->
+			<view class="statusBar" :style="{height:statusBarHeight+'rpx'}"></view>
+			<!-- 导航栏 -->
+			<view class="navigationBar" :style="{height:navigationBarHeight,paddingTop:statusBarHeight+'rpx'}">
+				<view @click="goBack">
+					<image class="back" :src="require('../../../static/back.png')" alt="">
+				</view>
+
+			</view>
+			<!-- 顶部搜索 -->
+			<view class="search">
+				<view class="icon-search">
+					<image :src="require('../../../static/search.png')" alt="">
+				</view>
+				<input class="input" type="text" confirm-type="search" @confirm="toSearch()" placeholder="输入关键字搜索"
+					v-model="search" placeholder-class="co" />
+			</view>
+			<!-- 视频播放 -->
+			<view class="video" v-if="shopData.video">
+				<image :src="require('../../../static/video.png')" alt="">
+					<view class="title">
+						视频
+					</view>
+
+			</view>
+			<!-- 查看图片 -->
+			<view class="image" v-if="shopData.photo" @click="toShopPhotoAlbum">
+				<image :src="require('../../../static/pic.png')" alt="">
+					<view class="title">
+						图片
+					</view>
+			</view>
+		</view>
+		<view class="body">
+			<!-- 门店基本信息 -->
+			<view class="header-view">
+				<view class="headPortrait">
+					<image :src="baseImagePath+shopData.logoUrl" alt="">
+				</view>
+				<view class="middle">
+					<view class="">
+						<view class="title">
+							{{shopData.name}}
+						</view>
+						<view class="buttom">
+							<view v-if="shopData.attribute==1" class="manage">
+								自营
+							</view>
+							<view class="stars">
+								<view class="unit">
+									评分:
+								</view>
+								<view class="star" v-for="(item, index) in starList" :key="index">
+									<image :src="(index+1)<=shopData.ealuationScore?item.stary:item.starsg" alt="">
+								</view>
+							</view>
+							<view class="num">
+								收藏数{{shopData.collectionNum}}
+							</view>
+						</view>
+					</view>
+
+					<view :class="shopData.isCollection==1?'collect':'uncollect'" @click="toSave(shopData.id)">
+						<image v-if="shopData.isCollection==2" :src="require('../../../static/guanzhu.png')" alt="">
+							{{shopData.isCollection==1?'已收藏':'收藏'}}
+					</view>
+				</view>
+			</view>
+			<!-- 营业时间地址等信息 -->
+			<view class="introduce">
+				<view class="businessHours">
+					营业时间:{{shopData.satrtTime}}-{{shopData.overTime}}
+				</view>
+				<view class="content">
+					<view class="locations">
+						<view class="location">
+							{{shopData.address}}
+						</view>
+						<view class="km">
+							距您{{shopData.distance}}km
+						</view>
+					</view>
+					<view class="btn">
+						<view class="navigation" @click="toGps()">
+							<image :src="require('../../../static/daohang.png')" alt="">
+								<view class="unit">
+									导航
+								</view>
+						</view>
+						<view class="phone" @click="toCall(shopData.phone)">
+							<image :src="require('../../../static/dianhua.png')" alt="">
+								<view class="unit">
+									电话
+								</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<!-- 门店服务 门店评价 门店介绍 -->
+			<view class="shopFunction">
+				<view class="shopHeader">
+					<view :class="shopType == 0?'action':'title'" @click="shopType = 0">
+						门店服务
+						<view class="border"></view>
+					</view>
+					<view :class="shopType == 1?'action':'title'" @click="shopType = 1">
+						门店评价
+						<view class="border"></view>
+					</view>
+					<view :class="shopType == 2?'action':'title'" @click="toInclude(2)">
+						门店介绍
+						<view class="border"></view>
+					</view>
+				</view>
+				<shopGoods v-if="shopType == 0" :set-meal-list="setMealList"></shopGoods>
+				<view v-if="shopType == 1" class="evaluateBody" v-for="(item, index) in pingjia" :key="index">
+					<view class="evaluateHead">
+						<view class="titleBody">
+							<view class="titleImg">
+								<image :src="baseImagePath+item.userImg" alt="">
+							</view>
+							<view class="classTitle">
+								<view class="title">
+									{{item.title}}
+								</view>
+								<view class="star">
+									<image v-for="(subItem, indexs) in starList" :key="indexs"
+										:src="(indexs+1)<=item.sumScore?subItem.stary:subItem.starsg" alt="">
+								</view>
+							</view>
+						</view>
+						<view class="time">
+							{{item.createTime}}
+						</view>
+					</view>
+					<view class="evaluateButtom">
+						<view :style="item.imgContent?'width: 75%;':''" class="evaluateContent">
+							{{item.content}}
+						</view>
+						<view style="position: relative;" @click="previewImage(item.imgContent.split(','))">
+							<image v-if="item.imgContent" :src="baseImagePath+item.imgContent.split(',')[0]" alt="">
+								<view v-if="item.imgContent" class="phoneNum">
+									{{item.imgContent.split(',').length}}张
+								</view>
+						</view>
+
+					</view>
+				</view>
+				<view class="webView" v-if="shopType == 2">
+					<view v-html="shopData.introduce" style="padding: 0rpx 30rpx 30rpx ;"></view>
+				</view>
+			</view>
+
+			<view style="height: 200rpx;">
+			</view>
+		</view>
+		<view class="buttomBtn">
+			<view class="preCarWash" @click="carWash">
+				预约洗车
+			</view>
+			<view class="preMaintain" @click="routerTo">
+				预约维修
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import shopGoods from '@/components/SetMeal/shopGoods.vue'
+	import {
+		getShopGoods,
+		shopDetail,
+		orderEvaluate,
+		getInclude
+	} from "@/api/shop.js"
+	import {
+		saveShop
+	} from "../../../api/myApi.js"
+	const app = getApp();
+	export default {
+		components: {
+			shopGoods,
+		},
+		data: function() {
+			return {
+				baseImagePath: this.baseImagePath,
+				shopType: 0, //0:门店服务 1:门店评价 2:门店介绍
+				pingjia: [],
+				setMealList: [],
+				starList: [{
+						starsg: require('../../../static/star-s-g.png'),
+						stary: require('../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../static/star-s-g.png'),
+						stary: require('../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../static/star-s-g.png'),
+						stary: require('../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../static/star-s-g.png'),
+						stary: require('../../../static/star-y.png'),
+					},
+					{
+						starsg: require('../../../static/star-s-g.png'),
+						stary: require('../../../static/star-y.png'),
+					}
+				],
+				shopData: {
+					headerData: {
+						url: require('../../../static/u1u5bg.png'),
+						name: "优1优5华南广场快修店",
+						manageType: 1,
+						xingxing: 4,
+						type: false,
+						shoucangshu: "35678"
+					}
+				},
+				longitude: app.globalData.longitude,
+				latitude: app.globalData.latitude,
+				statusBarHeight: "",
+				navigationBarHeight: "",
+				navHeight: "",
+				id: "",
+				search: "",
+				pageNo: 1,
+				pageSize: 10,
+				url: ''
+			}
+		},
+		onReachBottom() {
+			switch (this.shopType) {
+				case 0:
+					this.pageNo += 1
+					this.getGoods()
+					break;
+				case 1:
+					this.pageNo += 1
+					this.getEvaluate()
+					break;
+				case 2:
+					break;
+			}
+		},
+		onLoad(options) {
+			// 状态栏高度
+			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
+
+			// #ifdef MP-WEIXIN
+			// 获取微信胶囊的位置信息 width,height,top,right,left,bottom
+			const custom = wx.getMenuButtonBoundingClientRect()
+			// console.log(custom)
+			// 导航栏高度(标题栏高度) = 胶囊高度 + (顶部距离 - 状态栏高度) * 2
+			this.navigationBarHeight = custom.height + (custom.top - this.statusBarHeight) * 2
+
+			// console.log("导航栏高度:"+this.globalData.navigationBarHeight)
+
+			// 总体高度 = 状态栏高度 + 导航栏高度
+			this.navHeight = (this.navigationBarHeight + this.statusBarHeight)
+			this.navigationBarHeight = this.navigationBarHeight + 'px'
+			this.statusBarHeight = this.statusBarHeight + 'px'
+			this.navHeight = this.navHeight + 'px'
+
+			// #endif
+			this.id = options.id
+			shopDetail({
+				id: this.id,
+				longitude: this.longitude,
+				latitude: this.latitude
+			}).then(res => {
+				this.shopData = res.data;
+				console.log('店铺详情=====》', this.shopData);
+			})
+			this.getGoods()
+		},
+		watch: {
+			shopType(val) {
+				console.log(val, '评价');
+				this.pageNo = 1
+				switch (val) {
+					case 0:
+						this.setMealList = []
+						this.getGoods()
+						break;
+					case 1:
+						this.pingjia = []
+						this.getEvaluate()
+						break;
+					case 2:
+						getInclude({
+							id: this.id
+						}).then(res => {
+							for (let item in res.data) {
+								if (res.data[item].type === "15") {
+									// this.url = res.data[item].url+ '?id='+this.id+'&token=eyJ1c2VySWQiOjE1OTcxNTUzMDAwOTAwODUzNzgsImFjY291bnQiOiIxNTE0MTE1NTQ3NyIsInV1aWQiOiIyMGRiNGE3Ny00OTg5LTRmOWUtYWMxNi1mZDc3OGMyMjFmMWQiLCJyZW1lbWJlck1lIjp0cnVlLCJleHBpcmF0aW9uRGF0ZSI6MTY3MTk4NDU1MTUxOCwiY2FUb2tlbiI6bnVsbCwib3RoZXJzIjpudWxsLCJzdWIiOiIxNTk3MTU1MzAwMDkwMDg1Mzc4IiwiaWF0IjoxNjcwMjMxNTE4LCJleHAiOjE2NzE5ODQ1NTF9'
+									this.url = res.data[item].url + '?id=' + this.id
+									console.log(this.url, 'asdfasdfa');
+								}
+							}
+						})
+						break;
+				}
+			}
+		},
+		methods: {
+			toSave(id) {
+				let data = {
+					detailId: id,
+					type: 2
+				}
+				saveShop(data).then(res => {
+					console.log(res);
+					if (res.code === '00000') {
+						shopDetail({
+							id: this.id,
+							longitude: this.longitude,
+							latitude: this.latitude
+						}).then(res => {
+							this.shopData = res.data;
+							console.log('店铺详情=====》', this.shopData);
+						})
+					}
+				})
+			},
+			previewImage(item) {
+				let imgArr = []
+				item.forEach(data => {
+					console.log(data, 'data');
+					imgArr.push(this.baseImagePath + data)
+				})
+				uni.previewImage({
+					urls: imgArr,
+					fail: (res) => {
+						console.log(res);
+					}
+				})
+			},
+			toGps() {
+				console.log(this.shopData);
+				uni.navigateTo({
+					url: '/pages/shop/navigation/navigation?latitude=' + this.shopData.latitude + '&longitude=' +
+						this.shopData.longitude + '&shopTitle=' + this.shopData.name + '&address=' + this.shopData
+						.address + '&distance=' + this.shopData.distance + '&phone=' + this.shopData.phone,
+					fail: (res) => {
+						console.log(res);
+					}
+				})
+			},
+			toCall(tel) {
+				uni.makePhoneCall({
+					phoneNumber: tel,
+					fail: (res) => {
+						uni.showToast({
+							icon: 'none',
+							title: '呼叫拉起失败:' + res
+						})
+					}
+				})
+			},
+			toInclude(item) {
+				this.shopType = 2
+
+			},
+			toSearch() {
+				this.pageNo = 1
+				this.setMealList = []
+				this.getGoods()
+			},
+			toShopPhotoAlbum() {
+				// this.$yrouter.push({ path: "/pages/shop/shopDetail/shopPhotoAlbum/index" });
+				uni.navigateTo({
+					url: '/pages/shop/shopDetail/shopPhotoAlbum/index?photo=' + this.shopData.photo
+				})
+			},
+			routerTo() {
+				// uni.$emit('chooseShop', this.shopData)
+				uni.setStorageSync('shopData', this.shopData)
+				console.log('1', this.shopData);
+				uni.navigateTo({
+					url: "/pages/maintenance/onlineReservation/index?type=maintenance&page=index"
+				})
+			},
+			goBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			carWash() {
+				// uni.$emit('chooseShop', this.shopData)
+				uni.setStorageSync('shopData', this.shopData)
+				uni.navigateTo({
+					url: "/pages/preCarWash/index?type=washCar&token=" + uni.getStorageSync('token')
+				})
+			},
+			getGoods() {
+				let data = {
+					pageNo: this.pageNo,
+					pageSize: this.pageSize,
+					shopId: this.id,
+					name: this.search
+				}
+				getShopGoods(data).then(res => {
+					console.log('服务', res.data);
+					this.setMealList = [...this.setMealList, ...res.data.rows]
+				})
+			},
+			getEvaluate() {
+				let data = {
+					pageNo: this.pageNo,
+					pageSize: this.pageSize,
+					shopId: this.id
+				}
+				orderEvaluate(data).then(res => {
+					// console.log('评论',res.data.rows);
+					this.pingjia = [...this.pingjia, ...res.data.rows]
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+		width: 96vw;
+	}
+
+	.buttomBtn {
+		position: fixed;
+		bottom: 0;
+		width: 100%;
+		height: 150rpx;
+		background: #FFFFFF;
+		display: flex;
+		justify-content: space-around;
+		align-items: center;
+
+		.preCarWash {
+			width: 330rpx;
+			height: 90rpx;
+			background: linear-gradient(180deg, #F98324 0%, #FF5325 100%);
+			border-radius: 45rpx;
+			text-align: center;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #FFFFFF;
+			line-height: 90rpx;
+		}
+
+		.preMaintain {
+			width: 330rpx;
+			height: 90rpx;
+			background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+			border-radius: 45rpx;
+			text-align: center;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #FFFFFF;
+			line-height: 90rpx;
+		}
+
+	}
+
+	.evaluateBody {
+		padding: 20rpx 39rpx 20rpx 29rpx;
+
+		.evaluateHead {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+
+			.titleBody {
+				display: flex;
+
+				.titleImg {
+					image {
+						width: 70rpx;
+						height: 70rpx;
+						border: 1px solid #EEEEEE;
+						background: linear-gradient(135deg, #D10498 0%, #D21728 100%);
+						border-radius: 50%;
+					}
+				}
+
+				.classTitle {
+					margin-left: 24rpx;
+
+					.title {
+						font-size: 24rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #333333;
+						line-height: 31rpx;
+					}
+
+					.star {
+						display: flex;
+						margin-top: 12rpx;
+
+						image {
+							width: 22rpx;
+							height: 22rpx;
+						}
+					}
+				}
+			}
+
+			.time {
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 31rpx;
+			}
+		}
+
+		.evaluateButtom {
+			display: flex;
+
+			.evaluateContent {
+				font-size: 24rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 34rpx;
+			}
+
+			image {
+				width: 130rpx;
+				height: 130rpx;
+				background: #C97E7E;
+				border-radius: 10rpx;
+				margin-left: 33rpx;
+			}
+
+			.phoneNum {
+				width: 66rpx;
+				height: 32rpx;
+				background: rgba(0, 0, 0, 0.3);
+				border: 1px solid rgba(255, 255, 255, 0.3);
+				border-radius: 16rpx;
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #FFFFFF;
+				line-height: 32rpx;
+				text-align: center;
+				position: absolute;
+				right: 8rpx;
+				top: 89rpx;
+				z-index: 2;
+			}
+		}
+
+	}
+
+	.body {
+		position: relative;
+		top: -66rpx;
+	}
+
+	.shopFunction {
+		width: 710rpx;
+		background: #FFFFFF;
+		border-radius: 16rpx;
+		margin: 20rpx;
+
+		.shopHeader {
+			display: flex;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				line-height: 40rpx;
+				padding: 32rpx;
+
+				.border {
+					display: none;
+				}
+			}
+
+			.action {
+				padding: 32rpx;
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 40rpx;
+
+				.border {
+					width: 126rpx;
+					height: 8rpx;
+					background: linear-gradient(-90deg, #005BFF 0%, #00A8FF 100%);
+					box-shadow: 0px 3rpx 10rpx 0px rgba(0, 94, 255, 0.24);
+				}
+			}
+		}
+	}
+
+	.introduce {
+		width: 710rpx;
+		height: 210rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 20rpx;
+
+		.businessHours {
+			font-size: 24rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #333333;
+			line-height: 36rpx;
+			padding: 34rpx 0 0 32rpx;
+		}
+
+		.content {
+			display: flex;
+			padding: 24rpx 32rpx 0 32rpx;
+			justify-content: space-between;
+
+			.locations {
+				margin-top: 20rpx;
+
+				.location {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #333333;
+					line-height: 36rpx;
+				}
+
+				.km {
+					font-size: 20rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #777777;
+					line-height: 40rpx;
+				}
+			}
+
+			.btn {
+				display: flex;
+
+				.navigation {
+					text-align: center;
+
+					image {
+						width: 54rpx;
+						height: 54rpx;
+					}
+
+					.unit {
+						font-size: 22rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #333333;
+						line-height: 20rpx;
+					}
+				}
+
+				.phone {
+					text-align: center;
+					padding-left: 45rpx;
+
+					image {
+						width: 54rpx;
+						height: 54rpx;
+					}
+
+					.unit {
+						font-size: 22rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #333333;
+						line-height: 20rpx;
+					}
+				}
+			}
+		}
+	}
+
+	.buttom {
+		display: flex;
+		align-items: center;
+		margin-top: 22rpx;
+
+		.manage {
+			width: 70rpx;
+			height: 32rpx;
+			background: #FF7200;
+			border-radius: 16rpx;
+			font-size: 20rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			line-height: 32rpx;
+			text-align: center;
+			margin-right: 20rpx;
+		}
+
+		.stars {
+			display: flex;
+			align-items: center;
+
+			.unit {
+				font-size: 22rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 32rpx;
+			}
+
+			.star {
+				image {
+					width: 22rpx;
+					height: 22rpx;
+				}
+			}
+		}
+
+		.num {
+			font-size: 22rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #666666;
+			line-height: 40rpx;
+			padding-left: 25rpx;
+		}
+	}
+
+	.header {
+		width: 100%;
+		height: 605rpx;
+		position: relative;
+
+		.navigationBar {
+			display: flex;
+			align-items: center;
+			max-width: 200rpx;
+			padding-left: 29rpx;
+
+			.back {
+				width: 62rpx;
+				height: 62rpx;
+			}
+		}
+
+		.search {
+			width: 690rpx;
+			height: 64rpx;
+			background: rgba(10, 10, 10, 0.3);
+			border: 1px solid rgba(255, 255, 255, 0.3);
+			border-radius: 31rpx;
+			display: flex;
+			margin: 30rpx;
+
+			.icon-search {
+				padding-left: 35rpx;
+				display: flex;
+				align-items: center;
+
+				image {
+					width: 26rpx;
+					height: 26rpx;
+				}
+			}
+
+			.input {
+				padding-left: 14rpx;
+				height: 64rpx;
+			}
+		}
+
+		.video {
+			width: 110rpx;
+			height: 50rpx;
+			background: rgba(0, 0, 0, 0.3);
+			border: 1rpx solid rgba(255, 255, 255, 0.3);
+			border-radius: 25rpx;
+			position: absolute;
+			bottom: 72rpx;
+			right: 158rpx;
+			font-size: 22rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			line-height: 50rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-evenly;
+
+			image {
+				width: 24rpx;
+				height: 24rpx;
+			}
+		}
+
+		.image {
+			width: 110rpx;
+			height: 50rpx;
+			background: rgba(0, 0, 0, 0.3);
+			border: 1rpx solid rgba(255, 255, 255, 0.3);
+			border-radius: 25rpx;
+			position: absolute;
+			bottom: 72rpx;
+			right: 30rpx;
+			font-size: 22rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			line-height: 50rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-evenly;
+
+			image {
+				width: 24rpx;
+				height: 24rpx;
+			}
+		}
+	}
+
+	.hdbefore {
+		content: '';
+		width: 100%;
+		height: 100%;
+		position: absolute;
+		z-index: -1;
+		background-size: 100% 100%;
+		-webkit-filter: blur(5rpx);
+		filter: blur(5rpx) brightness(100%);
+		-webkit-transform: scale(1.1);
+		transform: scale(1.1);
+	}
+
+	.header-view {
+		width: 710rpx;
+		height: 210rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin: 20rpx;
+		position: relative;
+
+		.headPortrait {
+			position: absolute;
+			bottom: 158rpx;
+			left: 40rpx;
+
+			image {
+				width: 120rpx;
+				height: 120rpx;
+				background: #FF542E;
+				border: 1px solid #FFFFFF;
+				border-radius: 60rpx;
+			}
+		}
+
+		.middle {
+			display: flex;
+			align-items: baseline;
+			justify-content: space-around;
+			padding-top: 64rpx;
+
+			.title {
+				font-size: 34rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 40rpx;
+			}
+
+			.collect {
+				width: 144rpx;
+				height: 58rpx;
+				background: #E6E6E6;
+				border-radius: 29rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 54rpx;
+				text-align: center;
+			}
+
+			.uncollect {
+				width: 144rpx;
+				height: 58rpx;
+				background: #005BFF;
+				border-radius: 29rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #FFFFFF;
+				line-height: 54rpx;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+
+				image {
+					width: 32rpx;
+					height: 27rpx;
+					padding-right: 12rpx;
+				}
+			}
+		}
+	}
+
+	.co {
+		font-size: 26rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		line-height: 64rpx;
+		color: #C4C4C4;
+	}
+
+	.webView {
+		width: 710rpx;
+		border-radius: 0rpx 0rpx 16rpx 16rpx;
+		background-color: #FFFFFF;
+		margin: auto;
+		position: relative;
+	}
+</style>

+ 113 - 0
pages/shop/shopDetail/shopPhotoAlbum/index.vue

@@ -0,0 +1,113 @@
+<!-- html -->
+<template>
+	<view class="container">
+		<view class="left">
+			<image v-for="(item,index) in leftList" :key="index" @tap="previewImage(item.id)" :src="item.url" alt=""
+				mode="widthFix"></image>
+		</view>
+		<view class="right">
+			<image v-for="(item,index) in rightList" :key="index" @tap="previewImage(item.id)" :src="item.url" alt=""
+				mode="widthFix"></image>
+		</view>
+	</view>
+</template>
+
+
+<script>
+	export default {
+		components: {},
+		data: function() {
+			return {
+				setMealList: [],
+				// 初始化左右盒子
+				leftList: [],
+				rightList: [],
+				// 初始化左右盒子高度
+				leftH: 0,
+				rightH: 0,
+				baseImagePath:this.baseImagePath
+			}
+		},
+		onLoad(options) {
+			let data = options.photo.split(',')
+			data.forEach(item=>{
+				let img = {
+					url : this.baseImagePath+item
+				}
+				this.setMealList.push(img)
+			})
+			console.log(data);
+			this.doList()
+		},
+		methods: {
+			async doList() {
+				const that = this
+				for (let index in this.setMealList) {
+					// 获取图片宽高
+					await this.getImageInfo(index).then((res) => {
+						// 计算图片渲染高度
+						let showH = (50 * res.height) / res.width
+						// 判断左右盒子高度
+						if (that.leftH <= that.rightH) {
+							that.leftList.push(this.setMealList[index])
+							that.leftH += showH
+						} else {
+							that.rightList.push(this.setMealList[index])
+							that.rightH += showH
+						}
+					})
+				}
+			},
+			async getImageInfo(index) {
+				return new Promise((resolve, reject) => {
+					uni.getImageInfo({
+						src: this.setMealList[index].url,
+						success: (image) => {
+							resolve(image)
+
+						},
+					})
+				})
+
+			},
+			previewImage(index) {
+				//uniapp预览轮播图
+				uni.previewImage({
+					current: index, //预览图片的下标
+					urls: this.setMealList.map(item => item.url) //预览图片的地址,必须要数组形式,如果不是数组形式就转换成数组形式就可以
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	page{
+		background-color: #F5F5F5; 
+	}
+	.container {
+		padding: 0 30rpx;
+		font-size: 14rpx;
+		line-height: 24rpx;
+		padding-top: 21rpx;
+	}
+
+	.right,
+	.left {
+		display: inline-block;
+		width: 49%;
+		vertical-align: top;
+		border-radius: 10rpx;
+	}
+
+	.left {
+		margin-right: 2%;
+	}
+
+	.left image,
+	.right image {
+		border-radius: 10rpx;
+		width: 100%;
+		margin-bottom: 10rpx;
+	}
+</style>

+ 8 - 0
pages/user/User/index.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 217 - 0
pages/userMeal/index.vue

@@ -0,0 +1,217 @@
+<template>
+	<view class="userMeal">
+		<view class="header">
+			<view style="display: flex;justify-content: center;width: 50%;">
+				<view :class="barType == 1?'bar-select':'bar'" @click="barType=1">
+					生效中
+					<image v-if="barType==1" :src="require('../../static/sel.png')" alt="">
+				</view>
+				<span v-if="barNum>0 && barType==1">{{barNum}}</span>
+			</view>
+			<view style="display: flex;justify-content: center;width: 50%;border-left: 1px solid #E6E6E6;">
+				<view :class="barType == 2?'bar-select':'bar'" @click="barType=2">
+					已失效
+					<image v-if="barType==2" :src="require('../../static/sel.png')" alt="">
+				</view>
+				<span v-if="barNum>0 && barType==2">{{barNum}}</span>
+			</view>
+		</view>
+		<view class="body" v-for="(item, index) in setMealList" :key="index" @click="toPath(item.id)">
+			<image :src="baseImagePath + item.imgUrl" mode=""></image>
+			<view class="cont">
+				<view class="title">
+					{{item.packageName}}
+				</view>
+				<view class="content">
+					<view class="times">
+						{{item.createTime}}
+					</view>
+					<view class="services" v-if="item.status === 1">
+						{{item.num}}/{{item.allNum}}<span>个项目可用</span>
+					</view>
+					<image v-else :src="require('../../static/shixiao.png')" mode=""></image>
+
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		userPackageList
+	} from "@/api/myApi.js"
+	const app = getApp()
+	export default {
+		components: {},
+		data: function() {
+			return {
+				barType: 1,
+				barNum: 0,
+				pageNo:1,
+				pageSize:10,
+				setMealList: [],
+				baseImagePath: this.baseImagePath,
+			}
+		},
+		onLoad(e) {
+			app.globalData.requestToken = e.token;
+			uni.setStorageSync('token',e.token)
+			this.getList()
+		},
+		watch:{
+			barType(){
+				this.setMealList = []
+				this.pageNo = 1
+				this.getList()
+			}
+		},
+		onReachBottom() {
+			this.pageNo += 1
+			this.getList()
+		},
+		onBackPress(options) {
+		    // 这里可以自定义返回逻辑,比如下面跳转其他页面
+		  // #ifdef APP-PLUS
+		  if (plus.os.name.toLowerCase() === 'android') {
+		      plus.runtime.quit();
+		  } else {
+		      plus.runtime.quit();
+		  }
+		  // #endif
+		    // return true 表示禁止默认返回
+		   return true;
+		},
+		methods: {
+			toPath(item){
+				console.log(item);
+				this.$yrouter.push({
+					path: "/pages/userMeal/userMealDetail/index?id="+item + "&type=my"
+				});
+			},
+			getList(){
+				let data = {
+					pageNo:this.pageNo,
+					pageSize:this.pageSize,
+					status:this.barType
+				}
+				userPackageList(data).then(res=>{
+					console.log(res);
+					this.setMealList = [...this.setMealList,...res.data.rows]
+					this.barNum = this.setMealList.length
+				})
+			}
+		},
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #F5F5F5;
+	}
+
+	.body {
+		height: 178rpx;
+		background: #FFFFFF;
+		border-radius: 5rpx;
+		margin: 10rpx;
+		display: flex;
+		padding: 29rpx 23rpx 0 25rpx;
+
+		image {
+			width: 120rpx;
+			height: 120rpx;
+		}
+
+		.cont {
+			width: 76%;
+			padding: 16rpx 0 16rpx 30rpx;
+
+			.title {
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 31rpx;
+			}
+
+			.content {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				margin-top: 33rpx;
+
+				.times {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #005BFF;
+					line-height: 31rpx
+				}
+
+				.services {
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					line-height: 31rpx;
+
+					span {
+						font-size: 24rpx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						line-height: 31rpx;
+					}
+				}
+
+				image {
+					width: 142rpx;
+					height: 107rpx;
+					margin-top: -74rpx;
+				}
+			}
+		}
+	}
+
+	.header {
+		width: 100%;
+		height: 86rpx;
+		background: #FFFFFF;
+		display: flex;
+		align-items: center;
+
+		.bar {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			font-size: 28rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #666666;
+		}
+
+		span {
+			font-size: 22rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #005BFF;
+			padding-left: 12rpx;
+		}
+	}
+
+	.bar-select {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+
+		image {
+			width: 34rpx;
+			height: 11rpx;
+		}
+	}
+</style>

+ 483 - 0
pages/userMeal/userMealDetail/index.vue

@@ -0,0 +1,483 @@
+<template>
+	<view class="setMealDetail">
+		<image :src="baseImagePath + setMeal.imgUrl" alt="">
+			<view class="header-card">
+				<view class="header">
+					{{setMeal.name}}
+				</view>
+				<view class="content">
+					{{setMeal.title}}
+				</view>
+				<view class="bottom" v-if="setMeal.invalidDay">
+					<view class="left">
+						{{setMeal.invalidDay}}前有效
+					</view>
+					<view class="right" v-if="setMeal.status">
+						生效中
+					</view>
+					<view class="right" v-else>
+						已失效
+					</view>
+				</view>
+				<view class="bottom" v-else>
+					<view class="left">
+						购买后{{setMeal.invalidTime}}天内有效
+					</view>
+					<view class="right" v-if="setMeal.status">
+						生效中
+					</view>
+					<view class="right" v-else>
+						已失效
+					</view>
+				</view>
+			</view>
+			<!-- 套餐项目 -->
+			<view class="servicesAvailable">
+				<view class="header">
+					<view class="title">
+						套餐项目
+					</view>
+					<view class="border"></view>
+				</view>
+				<view class="body" v-for="(item, index) in servicesAvailableList" :key="index">
+					<view class="title">
+						{{item.sstName}}
+					</view>
+					<view class="border">
+
+					</view>
+					<view class="length">
+						×{{item.buyNum}}
+					</view>
+					<view class="lengths">
+						余 <span>{{item.surplusSum}}</span>
+					</view>
+				</view>
+			</view>
+			<!-- 可用门店 -->
+			<view class="shop">
+				<view class="header">
+					<view class="title">
+						可用门店
+					</view>
+					<view class="border"></view>
+				</view>
+				<view class="flexView">
+					<view class="body" v-for="(item, index) in shopList" :key="index">
+						<image :src="baseImagePath + item.logoUrl" alt="">
+							<view class="subbody">
+								<view class="title">
+									{{item.name}}
+								</view>
+								<view class="content">
+									<view class="location">
+										{{item.address}}
+									</view>
+									<view class="right">
+										<image :src="require('../../../static/address.png')" alt="" style="margin-right: 10rpx;">
+										<view class="km">
+											{{item.distance}}km
+										</view>
+									</view>
+								</view>
+							</view>
+					</view>
+				</view>
+			</view>
+			<!-- 套餐详情 -->
+			<view class="detail">
+				<view class="header">
+					<view class="title">
+						套餐详情
+					</view>
+					<view class="border"></view>
+				</view>
+				<view class="content" v-html="setMeal.introduce">
+					
+				</view>
+			</view>
+			<view style="height: 200rpx;">
+
+			</view>
+			<!-- 底部按钮 -->
+			<view class="bottomBtn" v-if="type !== 'my'">
+				<view class="leftView">
+					<view class="chooseNum">
+						<view style="font-size: 26rpx;">
+							¥
+						</view>
+						<view style="font-size: 56rpx;">
+							{{setMeal.carPrice}}-{{setMeal.truckPrice}}
+						</view>
+					</view>
+				</view>
+				<view class="rightView" @click="routerTo()">
+					立即购买
+				</view>
+			</view>
+	</view>
+</template>
+
+<script>
+	import {
+		userPackageDefail
+	} from '../../../api/myApi.js'
+	const app = getApp()
+	export default {
+		components: {},
+		data() {
+			return {
+				longitude: app.globalData.longitude,
+				latitude: app.globalData.latitude,
+				baseImagePath:this.baseImagePath,
+				packageId:null,
+				setMeal: {},
+				shopList: [],
+				servicesAvailableList: [],
+				type:''
+			};
+		},
+		onLoad(options) {
+			this.packageId = options.id
+			this.type = options.type
+			this.getInfo()
+		},
+		methods: {
+			routerTo(item) {
+				this.$yrouter.push({
+					path: "/pages/maintenance/setMeal/buySetMeal/index?item=" + JSON.stringify(this.setMeal)
+				});
+			},
+			getInfo(){
+				let data = {
+					longitude: this.longitude,
+					latitude: this.latitude,
+					id:this.packageId
+				}
+				userPackageDefail(data).then(res=>{
+					this.setMeal = res.data.packagesVO
+					console.log(this.setMeal);
+					this.servicesAvailableList = res.data.userPackageSerVOS
+					console.log(this.servicesAvailableList);
+					this.shopList = res.data.shopVOList
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="less">
+	page {
+		background: #EDEDED;
+	}
+
+	.bottomBtn {
+		width: 690rpx;
+		height: 110rpx;
+		background: #FFFFFF;
+		border: 1px solid #EEEEEE;
+		box-shadow: 0px 8rpx 17rpx 0px rgba(168, 165, 165, 0.26);
+		border-radius: 55rpx;
+		margin-left: 30rpx;
+		position: fixed;
+		bottom: 67rpx;
+		z-index: 9998;
+
+		.leftView {
+			float: left;
+			height: 100%;
+			display: flex;
+			align-items: center;
+			margin-left: 57rpx;
+
+			.chooseNum {
+				font-size: 30rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #FF3C00;
+				line-height: 31rpx;
+				display: flex;
+				align-items: baseline;
+			}
+		}
+
+		.rightView {
+			float: right;
+			width: 210rpx;
+			height: 108rpx;
+			background: linear-gradient(0deg, #005AFF 0%, #0078FF 100%);
+			border-radius: 0 55rpx 55rpx 0;
+			font-size: 34rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FEFEFE;
+			line-height: 108rpx;
+			text-align: center;
+		}
+	}
+
+	.detail {
+		background: #FFFFFF;
+		border-radius: 10px;
+		margin-top: 20rpx;
+		padding: 36rpx 30rpx;
+
+		.header {
+			padding-bottom: 36rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 106rpx;
+				height: 6rpx;
+				background: linear-gradient(90deg, #005BFF 0%, #FFFFFF 100%);
+				opacity: 0.6;
+			}
+		}
+
+		.content {
+			font-size: 26rpx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #666666;
+			line-height: 36rpx;
+			padding: 0 30rpx 0 0;
+			overflow: hidden;
+			display: flex;
+		}
+	}
+
+	.shop {
+		max-height: 514rpx;
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 20rpx;
+		padding: 36rpx 30rpx 0;
+
+		.header {
+			padding-bottom: 36rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 106rpx;
+				height: 6rpx;
+				background: linear-gradient(90deg, #005BFF 0%, #FFFFFF 100%);
+				opacity: 0.6;
+			}
+		}
+
+		.flexView {
+			max-height: 420rpx;
+			overflow-x: auto;
+			flex-direction: column;
+			display: flex;
+			flex-wrap: wrap;
+
+			.body {
+				width: 655rpx;
+				height: 101rpx;
+				background: #FFFFFF;
+				border-radius: 10rpx;
+				display: flex;
+				padding-bottom: 36rpx;
+
+				image {
+					width: 100rpx;
+					height: 100rpx;
+				}
+
+				.subbody {
+					width: 76%;
+					padding: 11rpx 21rpx 11rpx 21rpx;
+
+					.title {
+						font-size: 32rpx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #333333;
+						line-height: 31rpx;
+					}
+
+					.content {
+						padding-top: 21rpx;
+
+						.location {
+							width: 350rpx;
+							font-size: 24rpx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #999999;
+							line-height: 31rpx;
+							float: left;
+							overflow: hidden;
+							text-overflow: ellipsis;
+							white-space: nowrap;
+						}
+
+						.right {
+							display: flex;
+							align-items: center;
+							image {
+								width: 23rpx;
+								height: 23rpx;
+							}
+
+							.km {
+								font-size: 24rpx;
+								font-family: PingFang SC;
+								font-weight: 500;
+								color: #333333;
+								line-height: 31rpx;
+							}
+						}
+					}
+				}
+			}
+		}
+
+	}
+
+	.servicesAvailable {
+		background: #FFFFFF;
+		border-radius: 10rpx;
+		margin-top: 20rpx;
+		padding: 36rpx 30rpx;
+
+		.header {
+			padding-bottom: 36rpx;
+
+			.title {
+				font-size: 28rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 106rpx;
+				height: 6rpx;
+				background: linear-gradient(90deg, #005BFF 0%, #FFFFFF 100%);
+				opacity: 0.6;
+			}
+		}
+
+		.body {
+			display: flex;
+			padding: 19rpx;
+			justify-content: space-around;
+			align-items: center;
+
+			.title {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 29rpx;
+			}
+
+			.border {
+				width: 354rpx;
+				height: 1rpx;
+				border-top: 1px dashed #CCCCCC;
+			}
+
+			.length {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 29rpx;
+			}
+
+			.lengths {
+				font-size: 24rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+				line-height: 29rpx;
+
+				span {
+					color: #005BFF;
+				}
+			}
+		}
+	}
+
+	.setMealDetail {
+		image {
+			width: 100%;
+			height: 750rpx;
+		}
+
+		.header-card {
+			background: #FFFFFF;
+			border-radius: 0px 0px 16rpx 16rpx;
+			padding: 40rpx 0 0 29rpx;
+
+			.header {
+				font-size: 32rpx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #333333;
+				line-height: 31rpx;
+				padding-right: 29rpx;
+			}
+
+			.content {
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 36rpx;
+				padding-top: 25rpx;
+				padding-right: 29rpx;
+			}
+
+			.bottom {
+				display: flex;
+				justify-content: space-between;
+				padding-top: 37rpx;
+				position: relative;
+
+				.left {
+					font-size: 26rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #005BFF;
+					line-height: 55rpx;
+					padding-bottom: 22rpx;
+				}
+
+				.right {
+					width: 167rpx;
+					height: 62rpx;
+					background: linear-gradient(-35deg, #FF6000 0%, #FFA800 100%);
+					border-radius: 10rpx 0rpx 10rpx 0rpx;
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FFFFFF;
+					line-height: 62rpx;
+					text-align: center;
+					position: absolute;
+					right: 0;
+					bottom: 0;
+				}
+			}
+		}
+	}
+</style>

BIN
static/1..png


BIN
static/2..png


BIN
static/addVideo.png


BIN
static/address.png


BIN
static/alipay.png


BIN
static/back.png


BIN
static/backw.png


BIN
static/banjin.png


BIN
static/banner.png


BIN
static/baoyang.png


BIN
static/bg.png


BIN
static/car.png


BIN
static/cardbg.png


BIN
static/chafen.png


BIN
static/changgui.png


BIN
static/che.png


BIN
static/choose.png


BIN
static/chooseMenu.png


BIN
static/daohang.png


BIN
static/delete.png


BIN
static/dianhua.png


BIN
static/dianpu.png


BIN
static/guanzhu.png


BIN
static/gujia.png


BIN
static/guohu.png


BIN
static/half.png


BIN
static/icon-cart-hot.png


BIN
static/icon-cart.png


BIN
static/icon-class-hot.png


BIN
static/icon-class.png


BIN
static/icon-fuwu.png


BIN
static/icon-home-hot.png


BIN
static/icon-home.png


BIN
static/icon-user-hot.png


BIN
static/icon-user.png


BIN
static/icon-zhibo-hot.png


BIN
static/icon-zhibo.png


BIN
static/jiancha.png


Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov