Bladeren bron

商品模块

hmp 4 jaren geleden
bovenliggende
commit
2af20b9740
45 gewijzigde bestanden met toevoegingen van 6217 en 180 verwijderingen
  1. 4 0
      .hbuilderx/launch.json
  2. 1 1
      App.vue
  3. 62 3
      assets/colorui/app.scss
  4. 13 1
      assets/http/api.js
  5. 10 1
      assets/http/global.js
  6. 2 1
      assets/http/service.js
  7. 23 1
      main.js
  8. 229 168
      pages.json
  9. 6 2
      pages/consume/comps/card2.vue
  10. 1 1
      pages/consume/detail/comps/shop-info.vue
  11. 6 0
      pages/consume/detail/shop-detail.vue
  12. 447 0
      pages/test/test.vue
  13. 561 0
      pagesD/comps/h-time-alert.vue
  14. 133 0
      pagesD/comps/list-cell/list-cell.vue
  15. 297 0
      pagesD/comps/login.vue
  16. 98 0
      pagesD/comps/modal-checked.vue
  17. 393 0
      pagesD/comps/modal/modal.vue
  18. 155 0
      pagesD/comps/popup-layer/popup-layer.vue
  19. 231 0
      pagesD/comps/u-city-select.vue
  20. 337 0
      pagesD/pages/address/add.vue
  21. 184 0
      pagesD/pages/address/address.vue
  22. 1504 0
      pagesD/pages/menu/menu.vue
  23. 349 0
      pagesD/pages/pay/pay.vue
  24. 283 0
      pagesD/pages/pay/pay1.vue
  25. 81 0
      pagesD/pages/pay/remark.vue
  26. 39 0
      pagesD/pages/test.vue
  27. BIN
      pagesD/static/icon/cart1.png
  28. BIN
      pagesD/static/icon/checked.png
  29. BIN
      pagesD/static/icon/close.png
  30. BIN
      pagesD/static/icon/delivery.png
  31. BIN
      pagesD/static/icon/delivery1.png
  32. BIN
      pagesD/static/icon/delivery2.png
  33. BIN
      pagesD/static/icon/location1.png
  34. BIN
      pagesD/static/icon/order.png
  35. BIN
      pagesD/static/icon/pickup.png
  36. BIN
      pagesD/static/icon/shop.png
  37. BIN
      pagesD/static/icon/shop2.png
  38. 486 0
      pagesD/static/style/app.scss
  39. BIN
      static/icon/goOrder.png
  40. BIN
      static/icon/home.png
  41. 196 0
      static/iconfont/iconfont.scss
  42. 4 1
      store/index.js
  43. 64 0
      uni.scss
  44. 5 0
      utils/dateTime.js
  45. 13 0
      utils/mpi.js

+ 4 - 0
.hbuilderx/launch.json

@@ -6,6 +6,10 @@
      	{
      		"launchtype" : "local"
      	},
+     	"h5" : 
+     	{
+     		"launchtype" : "local"
+     	},
      	"mp-weixin" : 
      	{
      		"launchtype" : "local"

+ 1 - 1
App.vue

@@ -52,5 +52,5 @@
 	@import "uview-ui/index.scss";
 	 @import "assets/colorui/main.css";
 	 @import "assets/colorui/icon.css";
-	 @import "assets/colorui/app.css"; /* 你的项目css */
+	 @import "assets/colorui/app.scss"; /* 你的项目css */
 </style>

+ 62 - 3
assets/colorui/app.css → assets/colorui/app.scss

@@ -23,7 +23,7 @@
 
 .btn-line-color{
 	border: 1rpx solid #FF9447;
-	color: #DA3F33;
+	color: #FF9447;
 }
 
 .text-base{
@@ -47,7 +47,7 @@
 
 
 .bg-base{
-	background-color: #dc311c;
+	background-color: #FF9447;
 	color: #FFFFFF;
 }
 
@@ -257,4 +257,63 @@
 	flex-direction: row;
 	justify-content: center;
 	padding: 30rpx;
-}
+}
+
+button {
+	margin: 0;
+
+	&[type='primary'] {
+		background-color: $color-primary;
+		color: #ffffff;
+		font-size: $font-size-base;
+		
+		&[disabled] {
+			background-color: rgba(255, 148, 71,.4);
+		}
+		
+		&[plain] {
+			color: $color-primary;
+			border: 1rpx solid $color-primary;
+			
+			&.button-hover {
+				color: rgba($color: $color-primary, $alpha: 0.5);
+				border: 1rpx solid rgba($color: $color-primary, $alpha: 0.5);
+			}
+		}
+		
+		&.button-hover {
+			background-color:rgba(255, 148, 71,.7);
+		}
+		
+		&::after {
+			border: 0;
+		}
+	}
+
+	&[type='default'] {
+		&[plain] {
+			color: $text-color-assist;
+			border: 1rpx solid $text-color-assist;
+			
+			&.button-hover {
+				color: rgba($color: $text-color-assist, $alpha: 0.5);
+				border: 1rpx solid rgba($color: $text-color-assist, $alpha: 0.5);
+			}
+		}
+	}
+}
+
+	.homeBtn {
+		width: 128upx;
+		height: 70upx;
+		border-radius: 50upx 0 0 50upx;
+		position: fixed;
+		bottom: 45%;
+		right: 0;
+		z-index: 999;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		background: #ffffff;
+		box-shadow: -4upx -4upx 30upx #888888;
+	}

+ 13 - 1
assets/http/api.js

@@ -143,6 +143,16 @@ const withdraw={
 	list:p => http.get("ldt_bills/withdrawrec/list", {params:p}),
 }
 
+const goods={
+	menu:p => http.get("goods/getGoodsMenuList", {params:p}),
+}
+
+const address={
+	list:p => http.get("client/useraddress/list", {params:p}),
+	detail:p => http.get("ldt_user_address/useraddress/detail", {params:p}),
+	submit:p => http.post('client/useraddress/submit', p),
+}
+
 
 
 export const api={
@@ -166,5 +176,7 @@ export const api={
 	webSocket,
 	joinRecord,
 	statistics,
-	withdraw
+	withdraw,
+	goods,
+	address
 }

+ 10 - 1
assets/http/global.js

@@ -6,7 +6,7 @@ let global = {}
 global.baseUrl = 'http://192.168.1.168:2366/'
 
 // global.WebSocketUrl='wss://ldt.guosen-fumao.cn/websocket/'
-global.WebSocketUrl = 'ws://192.168.1.168:2366/websocket/'
+global.WebSocketUrl = 'ws://192.168.1.8:2366/websocket/'
 
 global.tokenUrl = global.baseUrl +
 	'blade-auth/oauth/token?tenantId=000000&password=21232f297a57a5a743894a0e4a801fc3&username=admin'
@@ -15,6 +15,8 @@ global.socket_prefix = 'USER:'
 
 global.socket_prefix_SHOP = 'SHOP:'
 
+global.cart_prefix = 'cart:'
+
 global.platform={
 	SHOP:"SHOP",
 	MALL:"MALL"
@@ -47,6 +49,13 @@ global.orderType = {
 	MALL_CHARGE: 'MALL_CHARGE'
 }
 
+global.takeType = {
+	dine_in: '店内堂食',
+	package: '到店自取',
+	delivery:'商家配送'
+}
+global.takeTypeList = ['店内堂食','到店自取','商家配送']
+
 global.payStatus = {
 	IS_WAIT: '0',
 	IS_PAY: '1',

+ 2 - 1
assets/http/service.js

@@ -39,13 +39,14 @@ let requests = []
 http.interceptors.response.use(async (response) => {
 	/* 请求之后拦截器。可以使用async await 做异步操作  */
 	//toekn过期处理 
-
+		console.log(response);
 	//200 返回数据成功 0
 	if (response.data.code != 200 && response.data.code !=400) {
 		return Promise.reject(response)
 	}
 	return response.data
 }, async (err) => { // 请求错误做点什么
+		console.log(err,"////");
 	if (err.data.code == 401) {
 		let {
 			config

+ 23 - 1
main.js

@@ -103,7 +103,29 @@ Vue.prototype.$isEmpty=function(value){
 	return false;
 }
 
-
+Vue.prototype.$isNotEmpty=function(value){
+	switch (typeof value) {
+		case 'undefined':
+			return false;
+		case 'string':
+			if(value=='undefined') return false
+			if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return false;
+			break;
+		case 'boolean':
+			if (!value) return false;
+			break;
+		case 'number':
+			if (0 === value || isNaN(value)) return false;
+			break;
+		case 'object':
+			if (null === value || value.length === 0) return false;
+			for (var i in value) {
+				return true;
+			}
+			return false;
+	}
+	return true;
+}
 Vue.config.productionTip = false
 
 App.mpType = 'app'

+ 229 - 168
pages.json

@@ -5,6 +5,8 @@
 	 * pagesB ==> agente 代理分包
 	 * 
 	 * pagesC ==> pay 支付交易的分包
+	 * 
+	 * pagesD ==> goods 商店点餐分包
 	 */
 	"easycom": {
 		"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
@@ -86,230 +88,285 @@
 
 		}
 
-	],
+	    ,{
+            "path" : "pages/test/test",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+    ],
 	"subPackages": [{
-			//tarbar下mine的分包
-			"root": "pagesA",
-			"pages": [{
-				"path": "pages/my-balance/statistics",
+		//tarbar下mine的分包
+		"root": "pagesA",
+		"pages": [{
+			"path": "pages/my-balance/statistics",
+			"style": {
+				"navigationBarTitleText": "账单统计"
+			}
+		}, {
+			"path": "pages/my-balance/my-balance",
+			"style": {
+				"navigationBarTitleText": "积分余额",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/setting/pay-setting",
+			"style": {
+				"navigationBarTitleText": "支付设置",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/setting/question",
+			"style": {
+				"navigationBarTitleText": "问题反馈",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/setting/setting",
+			"style": {
+				"navigationBarTitleText": "设置",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/myInfo",
+			"style": {
+				"navigationBarTitleText": "我的资料",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/my-points/accredit",
+			"style": {
+				"navigationBarTextStyle": "white",
+				"navigationBarBackgroundColor": "#FF9447",
+				"navigationBarTitleText": "积分授权",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/my-points/my-points",
+			"style": {
+				"navigationBarTitleText": "积分资产",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/my-points/exchange",
+			"style": {
+				"navigationBarTitleText": "积分通兑",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/bill/bill-detail",
+			"style": {
+				"navigationBarTitleText": "账单详情",
+				"enablePullDownRefresh": false
+			}
+
+		}]
+	}, {
+		//tarbar下gain 代理的分包
+		"root": "pagesB",
+		"pages": [{
+				"path": "pages/agent/agent",
 				"style": {
-					"navigationBarTitleText": "账单统计"
+					"navigationBarTitleText": "填写资料"
 				}
+
 			}, {
-				"path": "pages/my-balance/my-balance",
+				"path": "pages/agent/pay",
 				"style": {
-					"navigationBarTitleText": "积分余额",
-					"enablePullDownRefresh": false
+					"navigationBarTitleText": "支付页面"
 				}
 
 			}, {
-				"path": "pages/setting/pay-setting",
+				"path": "pages/agent/promote",
 				"style": {
-					"navigationBarTitleText": "支付设置",
-					"enablePullDownRefresh": false
+					"navigationBarTitleText": "去推广"
 				}
 
 			}, {
-				"path": "pages/setting/question",
+				"path": "pages/agent/myPromote",
 				"style": {
-					"navigationBarTitleText": "问题反馈",
-					"enablePullDownRefresh": false
+					"navigationBarTitleText": "我的推广"
 				}
+
 			}, {
-				"path": "pages/setting/setting",
+				"path": "pages/agent/myIncome/myIncome",
 				"style": {
-					"navigationBarTitleText": "设置",
-					"enablePullDownRefresh": false
+					"navigationBarTitleText": "我的收益"
 				}
 
 			}, {
-				"path": "pages/myInfo",
+				"path": "pages/agent/myIncome/todayIncome",
 				"style": {
-					"navigationBarTitleText": "我的资料",
-					"enablePullDownRefresh": false
+					"navigationBarTitleText": "今日收益"
 				}
 
 			}, {
-				"path": "pages/my-points/accredit",
+				"path": "pages/agent/myIncome/detail",
 				"style": {
-					"navigationBarTextStyle": "white",
-					"navigationBarBackgroundColor": "#FF9447",
-					"navigationBarTitleText": "积分授权",
-					"enablePullDownRefresh": false
+					"navigationBarTitleText": "收益详情"
 				}
 
 			}, {
-				"path": "pages/my-points/my-points",
+				"path": "pages/agent/agentDetail",
 				"style": {
-					"navigationBarTitleText": "积分资产",
-					"enablePullDownRefresh": false
+					"navigationStyle": "custom",
+					"navigationBarTitleText": ""
 				}
 
-			}, {
-				"path": "pages/my-points/exchange",
+			},
+			{
+				"path": "pages/agent/draw-poster",
 				"style": {
-					"navigationBarTitleText": "积分通兑",
+					"navigationBarTitleText": "推广",
 					"enablePullDownRefresh": false
 				}
+
 			}, {
-				"path": "pages/bill/bill-detail",
+				"path": "pages/shop-detail",
 				"style": {
-					"navigationBarTitleText": "账单详情",
+					"navigationBarTitleText": "商户详情",
 					"enablePullDownRefresh": false
 				}
 
-			}]
-		}, {
-			//tarbar下gain 代理的分包
-			"root": "pagesB",
-			"pages": [{
-					"path": "pages/agent/agent",
-					"style": {
-						"navigationBarTitleText": "填写资料"
-					}
-
-				}, {
-					"path": "pages/agent/pay",
-					"style": {
-						"navigationBarTitleText": "支付页面"
-					}
-
-				}, {
-					"path": "pages/agent/promote",
-					"style": {
-						"navigationBarTitleText": "去推广"
-					}
-
-				}, {
-					"path": "pages/agent/myPromote",
-					"style": {
-						"navigationBarTitleText": "我的推广"
-					}
-
-				}, {
-					"path": "pages/agent/myIncome/myIncome",
-					"style": {
-						"navigationBarTitleText": "我的收益"
-					}
-
-				}, {
-					"path": "pages/agent/myIncome/todayIncome",
-					"style": {
-						"navigationBarTitleText": "今日收益"
-					}
-
-				}, {
-					"path": "pages/agent/myIncome/detail",
-					"style": {
-						"navigationBarTitleText": "收益详情"
-					}
-
-				}, {
-					"path": "pages/agent/agentDetail",
-					"style": {
-						"navigationStyle": "custom",
-						"navigationBarTitleText": ""
-					}
-
-				},
-				{
-					"path": "pages/agent/draw-poster",
-					"style": {
-						"navigationBarTitleText": "推广",
-						"enablePullDownRefresh": false
-					}
-
-				}, {
-					"path": "pages/shop-detail",
-					"style": {
-						"navigationBarTitleText": "商户详情",
-						"enablePullDownRefresh": false
-					}
-
-				},
-				{
-					"path": "pages/withdraw/select-bank",
-					"style": {
-						"navigationBarTitleText": "选择银行卡",
-						"enablePullDownRefresh": false
-					}
-				},
-				{
-					"path": "pages/withdraw/withdraw",
-					"style": {
-						"navigationBarTitleText": "提现",
-						"enablePullDownRefresh": false
-					}
-				},
-				{
-					"path": "pages/userBank/userBank",
-					"style": {
-						"navigationBarTitleText": "我的银行卡",
-						"enablePullDownRefresh": false
-					}
-				},
-				{
-					"path": "pages/userBank/add",
-					"style": {
-						"navigationBarTitleText": "我的银行卡",
-						"enablePullDownRefresh": false
-					}
-				}, {
-					"path": "pages/withdraw/records",
-					"style": {
-						"navigationBarTitleText": "提现记录",
-						"enablePullDownRefresh": false
-					}
-
-				}
-			]
-		}, {
-			//支付特定包,扫码支付,付款码支付
-			"root": "pagesC/",
-			"pages": [{
-				"path": "pages/checkstand/index",
+			},
+			{
+				"path": "pages/withdraw/select-bank",
 				"style": {
-					"navigationStyle": "custom",
-					"navigationBarTitleText": "收银台",
+					"navigationBarTitleText": "选择银行卡",
 					"enablePullDownRefresh": false
 				}
-
-			}, {
-				"path": "pages/checkstand/order-res",
+			},
+			{
+				"path": "pages/withdraw/withdraw",
 				"style": {
-					"navigationBarTitleText": "支付结果",
+					"navigationBarTitleText": "提现",
 					"enablePullDownRefresh": false
 				}
-
-			}, {
-				"path": "pages/checkstand/pay-qrcode",
+			},
+			{
+				"path": "pages/userBank/userBank",
 				"style": {
-					"navigationBarTitleText": "付款码",
-					"navigationBarTextStyle": "white",
-					"navigationBarBackgroundColor": "#18b566",
+					"navigationBarTitleText": "我的银行卡",
 					"enablePullDownRefresh": false
 				}
-			}, {
-				"path": "pages/checkstand/pay-result",
+			},
+			{
+				"path": "pages/userBank/add",
 				"style": {
-					"navigationStyle": "custom",
-					"navigationBarTitleText": "支付结果",
+					"navigationBarTitleText": "我的银行卡",
 					"enablePullDownRefresh": false
 				}
-
 			}, {
-				"path": "pages/checkstand/pay-qrcode1",
+				"path": "pages/withdraw/records",
 				"style": {
-					"navigationBarTitleText": "付款码",
-					"navigationBarTextStyle": "white",
-					"navigationBarBackgroundColor": "#18b566",
+					"navigationBarTitleText": "提现记录",
 					"enablePullDownRefresh": false
 				}
 
-			}]
-		}
+			}
+		]
+	}, {
+		//支付特定包,扫码支付,付款码支付
+		"root": "pagesC/",
+		"pages": [{
+			"path": "pages/checkstand/index",
+			"style": {
+				"navigationStyle": "custom",
+				"navigationBarTitleText": "收银台",
+				"enablePullDownRefresh": false
+			}
 
-	],
+		}, {
+			"path": "pages/checkstand/order-res",
+			"style": {
+				"navigationBarTitleText": "支付结果",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/checkstand/pay-qrcode",
+			"style": {
+				"navigationBarTitleText": "付款码",
+				"navigationBarTextStyle": "white",
+				"navigationBarBackgroundColor": "#18b566",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/checkstand/pay-result",
+			"style": {
+				"navigationStyle": "custom",
+				"navigationBarTitleText": "支付结果",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/checkstand/pay-qrcode1",
+			"style": {
+				"navigationBarTitleText": "付款码",
+				"navigationBarTextStyle": "white",
+				"navigationBarBackgroundColor": "#18b566",
+				"enablePullDownRefresh": false
+			}
+
+		}]
+	}, {
+		//商品点餐包
+		"root": "pagesD/",
+		"pages": [{
+			"path": "pages/menu/menu",
+			"style": {
+				"navigationBarTitleText": "菜单",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/address/address",
+			"style": {
+				"navigationBarTitleText": "地址",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/address/add",
+			"style": {
+				"navigationBarTitleText": "添加地址",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/pay/pay",
+			"style": {
+				"navigationBarTitleText": "付款",
+				"enablePullDownRefresh": false
+			}
+
+		}
+		, {
+			"path": "pages/pay/remark",
+			"style": {
+				"navigationBarTitleText": "备注",
+				"enablePullDownRefresh": false
+			}
+		
+		}, {
+			"path": "pages/test",
+			"style": {
+				"navigationBarTitleText": "测试",
+				"enablePullDownRefresh": false
+			}
+		
+		}
+		]
+	}],
 	"preloadRule": {
 		"pages/gain/gain": {
 			"network": "all",
@@ -318,6 +375,10 @@
 		"pages/mine/mine": {
 			"network": "all",
 			"packages": ["pagesA", "pagesC"]
+		},
+		"pages/consume/consume": {
+			"network": "all",
+			"packages": ["pagesD"]
 		}
 	},
 	"tabBar": {

+ 6 - 2
pages/consume/comps/card2.vue

@@ -15,7 +15,7 @@
 					<view class="bottom">
 						<view class="">
 							<image src="@/static/icon/map1.png" mode=""></image>
-							<text>距离 {{distance(item.latitude,item.longitude)}} 米</text>
+							<text>距离 {{distance(item.address)}} 米</text>
 						</view>
 						<view class="" @click.stop="checkLine(item)">
 							<image style="width: 40rpx;height: 40rpx;" src="@/static/icon/lx.png" mode=""></image>
@@ -44,7 +44,11 @@
 		},
 		computed:{
 			distance() {
-				return (lat1,lng1) => {
+				return (address) => {
+					let location= address.split(",")
+					let lat1=location[1]
+					let lng1=location[0]
+					
 					if (this.vuex_location!=null) {
 						let distance=this.$util.calculateDistance(lat1,lng1,this.vuex_location.latitude,this.vuex_location.longitude)
 						console.log(distance);

+ 1 - 1
pages/consume/detail/comps/shop-info.vue

@@ -88,7 +88,7 @@
 			},
 			fetchAudit() {
 				this.$api.audit.detail({
-					shopId: this.shopId
+					entityId: this.shopId
 				}).then(res => {
 					this.audit = res.data
 				})

+ 6 - 0
pages/consume/detail/shop-detail.vue

@@ -24,6 +24,12 @@
 				</swiper-item>
 			</swiper>
 		</view>
+		<navigator hover-class="none" :url="'/pagesD/pages/menu/menu?shopId='+id" class="homeBtn">
+			<view class="flex">
+				<image src="/static/icon/goOrder.png" style="width: 36upx;height: 36upx;" />
+				<text class="margin-left-10">点餐</text>
+			</view>
+		</navigator>
 	</view>
 </template>
 <script>

+ 447 - 0
pages/test/test.vue

@@ -0,0 +1,447 @@
+<template>
+	<view style="" style="margin: 20rpx;">
+		<text v-if="demo==$TEST">123</text>
+		<!-- 配送方式tab-->
+		<view class="express-type .page_box">
+			<view class="express-type__head head-box u-flex u-col-center">
+				<view class="express-type__head-nav u-flex u-col-center u-row-center"
+					v-for="(nav, index) in expressType" :key="nav.id" @tap="changeExpressType(nav.value)">
+					<text class="head-nav__title"
+						:class="{ 'head-nav__title--active': expressTypeCur === nav.value }">{{ nav.title }}</text>
+					<view :class="expressClass" v-show="expressTypeCur === nav.value"></view>
+				</view>
+			</view>
+			<view class="express-type__content content_box">
+				<!-- 地址 -->
+				<view class="express-address" v-if="expressTypeCur == 'express'">
+					<text>cur1</text>
+				</view>
+				<!-- 自提  -->
+				<view class="express-address" v-if="expressTypeCur == 'selfetch'">
+					<text>自提</text>
+				</view>
+			</view>
+			<view class="express-type__bottom u-flex u-row-between u-p-b-20">
+				<button class="u-reset-button cancel-btn">取消</button>
+				<button class="u-reset-button save-btn">确定</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				demo:'测试',
+				expressTypeCur: 'express',
+				expressType: [
+					//配送方式
+					{
+						id: 'e1',
+						title: '物流快递',
+						value: 'express'
+					},
+					{
+						id: 'e2',
+						title: '到店/自提',
+						value: 'selfetch'
+					}
+				],
+			}
+		},
+		computed: {
+			expressClass() {
+				let cl = 'head-nav--active';
+				const {
+					expressType,
+					expressTypeCur
+				} = this;
+				if (expressTypeCur === 0) {
+					cl = 'head-nav__left--active';
+				}
+				if (expressTypeCur === expressType.length - 1) {
+					cl = 'head-nav__right--active';
+				}
+				return cl;
+			},
+		},
+		onLoad() {
+			console.log(this.$TEST);
+		},
+		methods: {
+			// 选择快递方式
+			changeExpressType(cur) {
+				this.expressTypeCur = cur;
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.page_box {
+		height: 100%;
+		width: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		overflow-x: hidden;
+		background: #FF9447;
+	}
+
+	// 弹窗之配送方式
+	// 配送方式
+	.express-type {
+		width: 100%;
+		background-color: #fff;
+		border-radius: 20rpx 20rpx 0 0;
+		height: 700rpx;
+		overflow: hidden;
+
+		.express-type__head {
+			width: 100%;
+			height: 80rpx;
+			background: #f8e3bd;
+			border-radius: 20rpx 20rpx 0 0;
+
+			&-nav {
+				width: (750rpx/4);
+				position: relative;
+				height: 100%;
+			}
+
+			.head-nav--active {
+				position: absolute;
+				left: 50%;
+				transform: translateX(-50%);
+				bottom: 0;
+				background: #fff;
+				width: 100%;
+				height: 80rpx;
+				background-color: #fff;
+				border-radius: 20rpx 20rpx 0px 0px;
+
+				&::after {
+					content: '';
+					display: block;
+					width: 40rpx;
+					height: 80rpx;
+					position: absolute;
+					transform: skewX(20deg);
+					background: #fff;
+					border-top-right-radius: 20rpx;
+					top: 0;
+					right: -15rpx;
+				}
+
+				&::before {
+					content: '';
+					display: block;
+					width: 40rpx;
+					height: 80rpx;
+					position: absolute;
+					transform: skewX(-20deg);
+					background: #fff;
+					border-top-left-radius: 20rpx;
+					top: 0;
+					left: -15rpx;
+				}
+			}
+
+			.head-nav__left--active {
+				position: absolute;
+				left: 50%;
+				transform: translateX(-50%);
+				bottom: 0;
+				background: #fff;
+				width: 100%;
+				height: 74rpx;
+				background-color: #fff;
+				border-radius: 20rpx 20rpx 0px 0px;
+
+				&::after {
+					content: '';
+					display: block;
+					width: 40rpx;
+					height: 74rpx;
+					position: absolute;
+					transform: skewX(20deg);
+					background: #fff;
+					border-top-right-radius: 20rpx;
+					top: 0;
+					right: -15rpx;
+				}
+			}
+
+			.head-nav__right--active {
+				position: absolute;
+				left: 50%;
+				transform: translateX(-50%);
+				bottom: 0;
+				background: #fff;
+				width: 100%;
+				height: 74rpx;
+				background-color: #fff;
+				border-radius: 20rpx 20rpx 0px 0px;
+
+				&::before {
+					content: '';
+					display: block;
+					width: 40rpx;
+					height: 74rpx;
+					position: absolute;
+					transform: skewX(-20deg);
+					background: #fff;
+					border-top-left-radius: 20rpx;
+					top: 0;
+					left: -15rpx;
+				}
+			}
+
+			.head-nav__title {
+				font-size: 24rpx;
+				font-weight: 500;
+				color: #666;
+				position: relative;
+				z-index: 6;
+			}
+
+			.head-nav__title--active {
+				color: #a8700d;
+				font-size: 26rpx;
+			}
+		}
+
+		.express-type__content {
+			.empty-address {
+				height: 120rpx;
+				padding: 0 25rpx;
+				font-size: 28rpx;
+
+				font-weight: 400;
+				color: rgba(153, 153, 153, 1);
+			}
+
+			// 无定位
+			.location-box {
+				height: 500rpx;
+				justify-content: center;
+
+				.nolocation-img {
+					width: 74rpx;
+					height: 90rpx;
+					margin-bottom: 40rpx;
+				}
+
+				.location-title {
+					font-size: 35rpx;
+
+					font-weight: bold;
+					color: rgba(70, 53, 27, 1);
+					margin-bottom: 20rpx;
+				}
+
+				.location-tip {
+					font-size: 28rpx;
+
+					font-weight: 400;
+					color: rgba(153, 153, 153, 1);
+					margin-bottom: 40rpx;
+				}
+
+				.open-location {
+					width: 492rpx;
+					line-height: 70rpx;
+					background: linear-gradient(90deg, rgba(233, 180, 97, 1), rgba(238, 204, 137, 1));
+					box-shadow: 0px 7rpx 6rpx 0px rgba(229, 138, 0, 0.22);
+					border-radius: 35rpx;
+					font-size: 28rpx;
+
+					font-weight: 500;
+					color: rgba(255, 255, 255, 1);
+				}
+			}
+
+			// 快递
+			.express-address {
+				position: relative;
+				padding: 30rpx 25rpx;
+				background: url('http://file.shopro.top/imgs/order/address_bg.png') no-repeat;
+				background-size: 430rpx 300rpx;
+				background-position: top right;
+
+				.express-top {
+					margin-bottom: 20rpx;
+					width: 550rpx;
+					text-align: left;
+
+					.address {
+						font-size: 28rpx;
+						font-weight: 500;
+						color: rgba(51, 51, 51, 1);
+						line-height: 40rpx;
+						text-align: left;
+					}
+
+					.dispatch-notice {
+						font-size: 28rpx;
+
+						font-weight: 500;
+						color: rgba(51, 51, 51, 1);
+						line-height: 40rpx;
+						text-align: left;
+					}
+
+					.address-location {
+						position: absolute;
+						right: 60rpx;
+						top: 30rpx;
+
+						.location-img {
+							width: 80rpx;
+							height: 90rpx;
+						}
+
+						.location-text {
+							font-size: 18rpx;
+
+							font-weight: 500;
+							color: rgba(51, 51, 51, 1);
+						}
+					}
+
+					.tag {
+						background: rgba(233, 191, 113, 0.2);
+						border-radius: 6rpx;
+						padding: 0 16rpx;
+						line-height: 38rpx;
+						color: #a8700d;
+						font-size: 22rpx;
+						margin-right: 20rpx;
+					}
+
+					.tag1 {
+						background: rgba(53, 190, 105, 0.2);
+						border-radius: 6rpx;
+						padding: 0 16rpx;
+						line-height: 38rpx;
+						color: #1bbc50;
+						font-size: 22rpx;
+						margin-right: 20rpx;
+					}
+
+					.address-guide {
+						position: absolute;
+						right: 25rpx;
+						top: 40rpx;
+						color: #999999;
+					}
+				}
+
+				.express-content {
+					margin-bottom: 20rpx;
+
+					.box-line {
+						width: 1rpx;
+						height: 61rpx;
+						border-left: 1rpx solid rgba(238, 238, 238, 1);
+						margin: 0 40rpx;
+					}
+
+					.phone-box1 {
+
+						.name,
+						.phone {
+							font-size: 26rpx;
+
+							font-weight: 400;
+							color: rgba(102, 102, 102, 1);
+						}
+
+						.phone {
+							margin-left: 20rpx;
+						}
+					}
+
+					.time-box,
+					.phone-box {
+						text-align: left;
+						min-height: 120rpx;
+
+						.box-title {
+							font-size: 24rpx;
+
+							font-weight: 400;
+							color: #666;
+							padding-bottom: 10rpx;
+						}
+
+						.box-text {
+							font-size: 24rpx;
+
+							font-weight: 500;
+							color: #333;
+						}
+
+						.edit-phone {
+							width: 160rpx;
+							font-size: 24rpx;
+
+							font-weight: 500;
+							color: #333;
+						}
+
+						.box-icon {
+							font-size: 28rpx;
+							color: #999;
+							display: inline-block;
+							width: 40rpx;
+							text-align: center;
+							line-height: 40rpx;
+						}
+					}
+				}
+
+				.express-bottom {
+					.protocol {
+						font-size: 24rpx;
+
+						font-weight: 400;
+						color: rgba(102, 102, 102, 1);
+
+						.protocol-text {
+							color: #6487a4;
+						}
+					}
+				}
+			}
+		}
+
+		.express-type__bottom {
+			height: 90rpx;
+			padding: 0 30rpx;
+
+			.cancel-btn {
+				width: 335rpx;
+				line-height: 74rpx;
+				background: rgba(238, 238, 238, 1);
+				border-radius: 37rpx;
+				font-size: 28rpx;
+
+				font-weight: 400;
+				color: rgba(51, 51, 51, 1);
+			}
+
+			.save-btn {
+				width: 335rpx;
+				line-height: 74rpx;
+				background: linear-gradient(90deg, rgba(233, 180, 97, 1), rgba(238, 204, 137, 1));
+				border-radius: 37rpx;
+				font-size: 28rpx;
+
+				font-weight: 400;
+				color: rgba(255, 255, 255, 1);
+			}
+		}
+	}
+</style>

+ 561 - 0
pagesD/comps/h-time-alert.vue

@@ -0,0 +1,561 @@
+<template>
+	<view :class="{ appintAlertMask: true, aMShow: isShow }" @click="_maskClose">
+		<view :class="{ appintAlertContent: true, aCShow: isShow }" @click.stop="_stopFunc">
+			<view class="closeBtn" v-if="closeBtn" @click="_closeBtnClose">×</view>
+			<view class="alertTtitle">
+				<view>{{ title }}</view>
+				<view>{{ subhead }}</view>
+			</view>
+			<view class="alertChangetab"></view>
+			<view class="alertTimebox">
+				<view class="left_box">
+					<view v-if="item.timeArr.length > 0" @click="_changeDay(index)" :class="{ active: item.checked }" v-for="(item, index) in timeList" :key="item.dateStr">
+						{{ item.name }}
+					</view>
+				</view>
+				<view class="right_box">
+					<view @click="_changeTime(index)" :class="{ active: item.checked }" v-for="(item, index) in activeTimeArr" :key="item.time">
+						{{ item.time }}{{ rangeType ? '-' + item.endtime : '' }}
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	props: {
+		title: {
+			type: String,
+			default: '请选择预约时间'
+		},
+		subhead: {
+			type: String,
+			default: ''
+		},
+		rangeType: {
+			type: Boolean,
+			default: false
+		},
+		isShow: {
+			type: Boolean,
+			default: false
+		},
+		maskHide: {
+			type: Boolean,
+			default: true
+		},
+		closeBtn: {
+			type: Boolean,
+			default: true
+		},
+		rangeDay: {
+			type: [Number, String],
+			default: 2
+		},
+		rangeStartTime: {
+			type: String,
+			default: '10:00:00'
+		},
+		rangeEndTime: {
+			type: String,
+			default: '22:00:00'
+		},
+		defaultTime: {
+			type: String,
+			default: ''
+		},
+		isRoundingTime: {
+			type: Boolean,
+			default: true
+		},
+		intervalTime: {
+			//间隔时间
+			type: [Number, String],
+			default: 30
+		},
+		isNow:{
+			type: Boolean,
+			default: false
+		},
+		dayStartIntTime: {
+			//每天开始间隔时间
+			type: [Number, String],
+			default: 0
+		},
+		disabled: {
+			type: [String, Array],
+			default: () => []
+		}
+	},
+	data() {
+		return {
+			timeList: [],
+			selectDateStr: '',
+			select_dateStr: '',
+			selectTime: '',
+			selectEndime: '',
+			activeTimeArr: []
+		};
+	},
+	beforeMount() {
+		this._initDay();
+	},
+	watch: {
+		isShow: function(val, oldVal) {
+			val && this.timeList.length <= 0 && this._initDay();
+		}
+	},
+	methods: {
+		_stopFunc() {},
+
+		_maskClose() {
+			let { maskHide } = this;
+			maskHide && this._closeAlert();
+		},
+		_closeBtnClose() {
+			let { closeBtn } = this;
+			closeBtn && this._closeAlert();
+		},
+		_closeAlert(data = '') {
+			this.$emit('closeAlert', data);
+		},
+		_changeDay(e) {
+			let _ind = e - 0;
+			let { timeList } = this;
+			timeList.forEach(ele => {
+				ele.checked = false;
+			});
+			timeList[_ind].checked = true;
+			this.timeList = timeList;
+			this.selectDateStr = timeList[_ind].dateStr;
+			this.select_dateStr = timeList[_ind]._dateStr;
+			this.activeTimeArr = timeList[_ind].timeArr;
+		},
+		_changeTime(e) {
+			let _ind = e - 0;
+			let { activeTimeArr } = this;
+			let timeArr = JSON.parse(JSON.stringify(activeTimeArr));
+			timeArr.forEach(ele => {
+				ele.checked = false;
+			});
+			timeArr[_ind].checked = true;
+			this.selectTime = timeArr[_ind].time;
+			this.selectEndime = timeArr[_ind].endtime;
+			this.activeTimeArr = timeArr;
+			let _data = this._handleData();
+			this._closeAlert(_data);
+		},
+		_handleData() {
+			let _data = {};
+			let { selectDateStr, select_dateStr, selectTime, selectEndime } = this;
+			_data.date = selectDateStr + ' ' + selectTime;
+			_data._date = select_dateStr + ' ' + selectTime;
+			_data.dateRange = selectDateStr + ' ' + selectTime + '-' + selectEndime;
+			_data._dateRange = select_dateStr + ' ' + selectTime + '-' + selectEndime;
+			_data.timeStamp = new Date(selectDateStr + ' ' + selectTime).getTime();
+			return _data;
+		},
+		_initDay() {
+			let _timeList = [];
+			let { rangeDay, defaultTime } = this;
+			for (let index = 0; index < rangeDay; index++) {
+				let _item = {
+					...this._getDate(index)
+				};
+				_item.timeArr = this._initTime(index);
+				_timeList.push(_item);
+			}
+
+			if (defaultTime) {
+				//存在默认时间
+				let _day = defaultTime.split(' ')[0].replace(/-/g, '/');
+				let _time = defaultTime.split(' ')[1];
+				let _flag = true;
+				for (let index = 0; index < _timeList.length; index++) {
+					const element = _timeList[index];
+					element.checked = false;
+					if (element.timeArr.length > 0 && element.dateStr === _day) {
+						element.checked = true;
+						_flag = false;
+						element.timeArr.forEach(item => {
+							if (this._timeRange(item.time + ':00', item.endtime + ':00', _time)) {
+								item.checked = true;
+								this.time = item.time;
+								this.endtime = item.endtime;
+							}
+						});
+
+						this.selectDateStr = element.dateStr;
+						this.select_dateStr = element._dateStr;
+						this.activeTimeArr = element.timeArr;
+					}
+				}
+				if (_flag) {
+					this._setDefaultTime(_timeList);
+				}
+			} else {
+				this._setDefaultTime(_timeList);
+			}
+
+			this.timeList = _timeList;
+		},
+		_setDefaultTime(list) {
+			for (let index = 0; index < list.length; index++) {
+				const element = list[index];
+				if (element.timeArr.length > 0) {
+					element.checked = true;
+					//是否默认选择时间
+					// element.timeArr[0].checked = true;
+					this.selectDateStr = element.dateStr;
+					this.select_dateStr = element._dateStr;
+					this.activeTimeArr = element.timeArr;
+					break;
+				}
+			}
+		},
+		_initTime(num) {
+			let _item = [];
+			let { disabled, rangeStartTime, rangeEndTime, intervalTime } = this;
+			if(intervalTime<=0){
+				intervalTime = 1
+			}
+			if (typeof disabled === 'string') {
+				disabled = disabled ? disabled.split(',') : [];
+			} else if (Array.isArray(disabled)) {
+				disabled = disabled.map(ele => {
+					return ele + '';
+				});
+			}
+			if (num === 0 && !disabled.includes('0')) {
+				//今天
+				let _nowTime = this._roundingTime();
+				if (this._timeRange(rangeStartTime, rangeEndTime, _nowTime)) {
+					//当前时间在营业时间内
+					return this._forTime(_nowTime, rangeEndTime, intervalTime, _nowTime);
+				} else if (this._toTimeStr(_nowTime) < this._toTimeStr(rangeStartTime)) {
+					//早于今天开始时间
+					return this._forTime(rangeStartTime, rangeEndTime, intervalTime, _nowTime);
+				} else {
+					return [];
+				}
+			} else {
+				//其他日期
+
+				if (disabled.includes(num + '')) {
+					//禁止当前日期了
+					return [];
+				}
+
+				return this._forTime(rangeStartTime, rangeEndTime, intervalTime);
+			}
+		},
+		_getDate(num) {
+			let date = new Date();
+			let date1 = new Date(date);
+			let weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+			date1.setDate(date.getDate() + num);
+			let name = '',
+				dateStr = '';
+			name = date1.getMonth() - 0 + 1 + '月' + date1.getDate() + '日(' + weekday[date1.getDay()] + ')';
+			dateStr = date1.getFullYear() + '/' + (date1.getMonth() - 0 + 1) + '/' + date1.getDate();
+			if (num == 0) {
+				name = '今天(' + weekday[date1.getDay()] + ')';
+			} else if (num == 1) {
+				name = '明天(' + weekday[date1.getDay()] + ')';
+			}
+			return {
+				name: name,
+				dateStr: dateStr,
+				_dateStr: dateStr.replace(/\//g, '-')
+			};
+		},
+		_addZero(num) {
+			num = num + '';
+			if (num.length === 1) {
+				return '0' + num;
+			}
+			return num;
+		},
+		_roundingTime() {
+			let _now = new Date();
+			let _h = _now.getHours() - 0;
+			let _m = _now.getMinutes() - 0;
+			if (_m > 30) {
+				_m = '00';
+				_h += 1;
+			}else if (_m - 0 > 0&&_m - 0<30) {
+				_m = 30;
+			}
+			if (this.isRoundingTime&&!this.isNow) {
+				return _h + ':' + _m + ':00';
+			}
+			return new Date().getHours() + ':' + new Date().getMinutes() + ':00';
+		},
+		_forTime(st, et, it, dt = 0) {
+			let { dayStartIntTime } = this;
+			let _dayStartIntTime = dayStartIntTime * 1000 * 60;
+			let _st = this._toTimeStr(st);
+			let _et = this._toTimeStr(et);
+			let _it = it * 1000 * 60;
+			let _list = [];
+			if (_st < _et) {
+				for (let i = _st + _dayStartIntTime; i < _et; i += _it) {
+					_list.push({
+						time: this._toLocalTime(i),
+						endtime: this._toLocalTime(i + _it > _et ? _et : i + _it),
+						checked: false
+					});
+				}
+			} else {
+				//跨天了
+				for (let i = dt; i < _et; i += _it) {
+					_list.push({
+						time: this._toLocalTime(i),
+						endtime: this._toLocalTime(i + _it > _et ? _et : i + _it),
+						checked: false
+					});
+				}
+				for (let i = _st  + _dayStartIntTime; i < this._toTimeStr('23:59:59'); i += _it) {
+					_list.push({
+						time: this._toLocalTime(i),
+						endtime: this._toLocalTime(i + _it),
+						checked: false
+					});
+				}
+			}
+			return _list;
+		},
+		_toTimeStr(time = '') {
+			let newTime = time;
+			let itemStr = 0;
+			let timeArr = newTime.split(':');
+			let h = timeArr[0] * 1000 * 60 * 60;
+			let m = timeArr[1] * 1000 * 60;
+			let s = timeArr[2] * 1000;
+			itemStr = h + m + s;
+			return itemStr;
+		},
+		_toLocalTime(v, type = 0) {
+			let h = parseInt((v / 1000 / 60 / 60) % 24);
+			let m = parseInt((v / 1000 / 60) % 60);
+			let s = parseInt((v / 1000) % 60);
+			v = type === 0 ? `${this._addZero(h)}:${this._addZero(m)}` : `${this._addZero(h)}:${this._addZero(m)}:${this._addZero(s)}`;
+			return v;
+		},
+		_timeRange(beginTime, endTime, nowTime) {
+			let strb = beginTime.split(':');
+			if (strb.length != 3) {
+				return false;
+			}
+
+			let stre = endTime.split(':');
+			if (stre.length != 3) {
+				return false;
+			}
+
+			let strn = nowTime.split(':');
+			if (stre.length != 3) {
+				return false;
+			}
+			let b = new Date();
+			let e = new Date();
+			let n = new Date();
+
+			b.setHours(strb[0]);
+			b.setMinutes(strb[1]);
+			e.setHours(stre[0]);
+			e.setMinutes(stre[1]);
+			n.setHours(strn[0]);
+			n.setMinutes(strn[1]);
+
+			let _b = b.getTime();
+			let _e = e.getTime();
+			let _n = n.getTime();
+
+			if (_b > _e) {
+				if (_n - _e >= 0 && _n - _b < 0) {
+					return false;
+				} else {
+					return true;
+				}
+			} else {
+				if (_n - _b >= 0 && _n - _e < 0) {
+					return true;
+				} else {
+					return false;
+				}
+			}
+		}
+	}
+};
+</script>
+
+<style>
+.appintAlertMask {
+	position: fixed;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: 0;
+	background-color: rgba(0, 0, 0, 0.5);
+	z-index: -9999;
+	opacity: 0;
+	transition: opacity 0.3s;
+}
+.aMShow {
+	z-index: 999;
+	opacity: 1;
+}
+.appintAlertMask view {
+	box-sizing: border-box;
+}
+.appintAlertContent {
+	height: 0rpx;
+	background-color: #fff;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	padding: 40rpx 0 10rpx;
+	transition: height 0.5s;
+}
+.aCShow {
+	height: auto;
+}
+.alertTtitle {
+	text-align: center;
+	font-size: 32rpx;
+	color: #222222;
+	font-weight: 600;
+	position: relative;
+}
+
+.closeBtn {
+	position: absolute;
+	width: 80rpx;
+	line-height: 80rpx;
+	text-align: center;
+	right: 0rpx;
+	padding-right: 15rpx;
+	top: 0;
+	color: #999999;
+	z-index: 99;
+	font-size: 44rpx;
+}
+.alertTtitle > view:nth-child(2) {
+	font-size: 22rpx;
+	color: #919191;
+	margin-top: 10rpx;
+}
+.alertChangetab {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 25rpx 60rpx;
+	position: relative;
+}
+.alertChangetab::after {
+	content: ' ';
+	width: 690rpx;
+	position: absolute;
+	left: 20rpx;
+	bottom: 0;
+	height: 1rpx;
+	background-color: #f4f4f4;
+}
+.alertChangetab > view {
+	width: 282rpx;
+	height: 110rpx;
+	border: 1rpx solid rgba(145, 145, 145, 1);
+	border-radius: 20rpx;
+	font-size: 36rpx;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	transition: background-color 0.3s;
+}
+.alertChangetab > view image {
+	width: 82rpx;
+	height: 82rpx;
+	margin-right: 25rpx;
+	background-color: #dd0000;
+}
+.alertChangetab > view > view {
+	text-align: center;
+}
+.alertChangetab > view > view:nth-child(2) {
+	font-size: 20px;
+}
+.alertChangetab > .active {
+	background-color: #dcb477;
+	color: #fff;
+	border: 1px solid #dcb477;
+}
+
+.alertTimebox {
+	background-color: #fbf8fb;
+	height: 660rpx;
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+}
+.alertTimebox > view {
+	height: 100%;
+	overflow-y: auto;
+	-webkit-overflow-scrolling: touch;
+	font-size: 28rpx;
+}
+.alertTimebox .left_box {
+	color: #919191;
+	width: 45%;
+}
+.alertTimebox .left_box view,
+.alertTimebox .right_box view {
+	text-align: center;
+	line-height: 90rpx;
+	position: relative;
+}
+
+.alertTimebox .right_box view::before {
+	content: ' ';
+	width: 80%;
+	position: absolute;
+	left: 10%;
+	bottom: 0;
+	border: 1px dashed #f4f4f4;
+}
+.alertTimebox .right_box view:last-child::before {
+	border: none;
+}
+
+.alertTimebox .right_box {
+	color: #222222;
+	width: 55%;
+	flex: 1;
+	background-color: #fff;
+	text-align: center;
+}
+.alertTimebox .right_box .active {
+	position: relative;
+	color: #dcb477;
+}
+.alertTimebox .left_box .active {
+	background-color: #fff;
+	color: #222222;
+}
+.alertTimebox .right_box .active::after {
+	content: ' ';
+	position: absolute;
+	top: 50%;
+	margin-top: -16rpx;
+	right: 50rpx;
+	width: 10rpx;
+	height: 20rpx;
+	border-color: #dcb477;
+	border-style: solid;
+	border-width: 0 3rpx 5rpx 0;
+	transform: rotate(45deg);
+}
+</style>

+ 133 - 0
pagesD/comps/list-cell/list-cell.vue

@@ -0,0 +1,133 @@
+<template>
+	<view
+		class="tui-cell-class tui-list-cell"
+		:class="{ 'tui-cell-arrow': arrow, 'tui-cell-last': last, 'tui-line-left': lineLeft, 'tui-line-right': lineRight, 'tui-radius': radius }"
+		:hover-class="hover ? 'tui-cell-hover' : ''"
+		:style="{ background: bgcolor, fontSize: size + 'rpx', color: color, padding: padding}"
+		:hover-stay-time="150"
+		@tap="handleClick"
+	>
+		<slot></slot>
+		<image src="/static/images/navigator-1.png" class="arrow" v-if="arrow"></image>
+		<!-- <view class="iconfont iconarrow-right arrow" v-if="arrow"></view> -->
+	</view>
+</template>
+
+<script>
+export default {
+	name: "ListCell",
+	props: {
+		 //是否有箭头
+		arrow: {
+			type: Boolean,
+			default: false
+		},
+		//是否有点击效果
+		hover: {
+			type: Boolean,
+			default: true
+		},
+		//left 30rpx
+		lineLeft:{
+			type: Boolean,
+			default: false
+		},
+		//right 30rpx
+		lineRight:{
+			type: Boolean,
+			default: false
+		},
+		padding:{
+			type:String,
+			default:"26rpx 30rpx"
+		},
+		last: {
+			type: Boolean,
+			default: false //最后一条数据隐藏线条
+		},
+		radius:{
+			type:Boolean,
+			default:false
+		},
+		bgcolor: {
+			type: String,
+			default: "#fff" //背景颜色
+		},
+		size: {
+			type: Number,
+			default: 28 //字体大小
+		},
+		color: {
+			type: String,
+			default: "#5A5B5C" //字体颜色
+		},
+		index: {
+			type: Number,
+			default: 0
+		}
+	},
+	methods: {
+		handleClick() {
+			this.$emit('click', {
+				index: this.index
+			});
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.tui-list-cell {
+	position: relative;
+	width: 100%;
+	box-sizing: border-box;
+	overflow: hidden;
+	display: flex;
+	align-items: center;
+}
+.tui-radius {
+	border-radius: 12rpx;
+	overflow: hidden;
+}
+
+.tui-cell-hover {
+	background: #f7f7f9 !important;
+}
+
+.tui-list-cell::after {
+	content: '';
+	position: absolute;
+	border-bottom: 2rpx solid #eee;
+	-webkit-transform: scaleY(0.8);
+	transform: scaleY(0.8);
+	bottom: 0;
+	right: 0;
+	left: 0;
+}
+.tui-line-left::after {
+	left: 30rpx !important;
+}
+
+.tui-line-right::after {
+	right: 30rpx !important;
+}
+
+.tui-cell-last::after {
+	border-bottom: 0 !important;
+}
+
+// .arrow {
+// 	font-size: 44rpx;
+// 	line-height: 100%;
+// 	color: $text-color-grey;
+// 	position: relative;
+// 	margin-right: -12rpx;
+// }
+.arrow {
+	width: 50rpx;
+	height: 50rpx;
+	position: relative;
+	margin-right: -10rpx;
+	flex-shrink: 0;
+}
+</style>

+ 297 - 0
pagesD/comps/login.vue

@@ -0,0 +1,297 @@
+<template>
+	<view class="">
+		<!-- 获取手机号 -->
+		<u-modal v-model="phoneShow" content="请授权获取手机号">
+			<button class="cu-btn btn-bg-color round" style="width: 80%;height: 70rpx;margin-bottom: 20rpx;" slot="confirm-button"
+				open-type="getPhoneNumber" @getphonenumber="getphonenumber">
+				去授权
+			</button>
+		</u-modal>
+
+		<!-- 获取头像昵称 -->
+		<view @touchmove.stop.prevent="clear" v-show="dialogShow">
+			<view class="popup_mask" @touchmove.stop.prevent="clear"></view>
+			<view class="">
+				<view class="dt-login-wrap">
+					<view class="title">请先登录</view>
+					<view class="content">
+						<view class="userinfo-avatar">
+							<open-data type="userAvatarUrl"></open-data>
+						</view>
+						<open-data type="userNickName"></open-data>
+						<text class="subtitle">申请获取您的公开信息(昵称,头像)</text>
+					</view>
+					<view class="btn-content setBtnCss" >
+						<button @click="hide" style="padding: 10rpx 0;">暂不登录</button>
+						<button @click="getUserProfile" style="padding: 10rpx 0;">立即登录</button>
+						<!-- <button v-else open-type="getUserInfo" @getuserinfo="getuserinfo">立即登录</button> -->
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				canIUseGetUserProfile: false,
+				//保存时间七天
+				cacheTime: 1 * 24 * 60 * 60 * 7,
+				dialogShow: false,
+				jscode: '',
+				//邀请码
+				inviteCode: '',
+				userInfo: '',
+				sessionKey: '',
+
+				//获取手机号
+				phoneShow: false
+			};
+		},
+		beforeDestroy() {
+			if (this.timer) {
+				clearTimeout(this.timer)
+				this.timer = null
+			}
+		},
+		created() {
+			if (uni.getUserProfile) {
+				this.canIUseGetUserProfile = false
+			}
+		},
+		methods: {
+			show() {
+				//获取邀请码
+				this.inviteCode = this.$cache.get('inviteCode')
+				this.dialogShow = true
+				this.$mpi.wxLogin().then(res => {
+					this.jscode = res.code
+				})
+				this.setTimer()
+			},
+			hide() {
+				if (this.timer) {
+					clearTimeout(this.timer)
+					this.timer = null
+				}
+				this.dialogShow = false;
+				this.$emit('hide')
+			},
+			async setTimer() {
+				let respWx = await this.$mpi.wxLogin()
+				this.jscode = respWx.code
+				// 每隔4分钟重新请求 jscode
+				this.timer = setTimeout(() => {
+					this.setTimer()
+				}, 240000)
+			},
+			getUserProfile(e) {
+				uni.getUserProfile({
+					desc: '用于获取头像和昵称',
+					success: (res) => {
+						this.userInfo = res.userInfo
+						console.log("getUserProfile获取用户信息", this.userInfo);
+						this.doLogin()
+					}
+				})
+			},
+			getuserinfo(e) {
+				console.log("getuserinfo获取用户信息", e);
+				if (e.detail.errMsg != 'getUserInfo:ok') {
+					return
+				}
+				this.userInfo = e.detail.userInfo
+				this.doLogin()
+			},
+			async doLogin() {
+				this.dialogShow = false
+				try {
+					this.respLogin = await this.$api.wxApp.getOpenId({
+						code: this.jscode
+					})
+					let openId = this.respLogin.data.openid
+					let unionid = this.respLogin.data.unionid || ''
+					this.sessionKey = this.respLogin.data.session_key
+					//通过openid查询数据库中该用户是否存在
+					let params = {
+						nickName: this.userInfo.nickName,
+						avatar: this.userInfo.avatarUrl,
+						gender: this.userInfo.gender,
+						unionid,
+						openid: openId,
+						province: this.userInfo.province,
+						city: this.userInfo.city
+					}
+					//将openid
+					let resp = await this.$api.loginUser.login(params)
+					if (resp.success) {
+						//登录成功
+						let obj = {
+							openId,
+							sessionKey: this.sessionKey,
+							userId: resp.data.id,
+							phone: resp.data.phone
+						}
+						//将openid和sessionkey存进缓存中,有效时间为七天
+						this.$cache.put("userInfo", obj)
+						this.$u.vuex('vuex_userId', resp.data.id)
+						if (resp.data.phone) {
+							this.$u.vuex('vuex_phone', resp.data.phone)
+						}
+						//移除邀请码
+						this.$cache.remove('inviteCode')
+						this.dialogShow = false
+						this.$emit('signIn', resp)
+					} else {
+						uni.showToast({
+							icon: "none",
+							title: "登录失败"
+						})
+					}
+
+				} catch (e) {
+					console.log(e);
+					uni.showToast({
+						icon: "none",
+						title: "登录失败"
+					})
+				} finally {
+					if (this.timer) {
+						clearTimeout(this.timer)
+						this.setTimer()
+					}
+				}
+			},
+			clear() {
+				return
+			},
+			//获取手机号
+			showPhoneModal() {
+				this.phoneShow = true
+			},
+			async getphonenumber(e) {
+				this.$emit('getphonenumber')
+				if (this.$isEmpty(this.sessionKey)) {
+					this.sessionKey =this.$cache.get('userInfo').sessionKey
+				}
+				let params = {
+					sessionKey: this.sessionKey,
+					encryptedData: e.detail.encryptedData,
+					iv: e.detail.iv
+				}
+				this.$api.wxApp.getOpenData(params).then(res => {
+					if (res.success) {
+						let obj = JSON.parse(res.data)
+						let phone = obj.phoneNumber
+						this.cachePhone(phone)
+					}
+				})
+			},
+			cachePhone(phone) {
+				let userInfo = this.$cache.get('userInfo')
+				let params = {
+					id: userInfo.userId,
+					phone
+				}
+				this.$api.loginUser.submit(params).then(res => {
+					if (res.success) {
+						userInfo.phone = phone
+						this.$cache.put('userInfo', userInfo)
+						this.$u.vuex('vuex_phone', phone)
+					}
+				})
+			}
+
+		}
+	};
+</script>
+
+<style lang="scss">
+	.popup_mask {
+		position: fixed;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+		background-color: rgba(0, 0, 0, 0.4);
+		opacity: 1;
+		z-index: 9999;
+
+	}
+
+	.dt-login-wrap {
+		position: fixed;
+		border-radius: 16rpx;
+		background: #ffffff;
+		width: 560rpx;
+		z-index: 99999;
+		bottom: 30%;
+		left: 50%;
+		margin-left: -280rpx;
+		right: 0;
+		text-align: center;
+
+		.title {
+			padding-top: 40upx;
+			font-size: 34upx;
+			font-weight: bold;
+		}
+
+		.content {
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			flex-direction: column;
+			padding-top: 30rpx;
+			padding-bottom: 150rpx;
+
+			.userinfo-avatar {
+				overflow: hidden;
+				display: block;
+				width: 140rpx;
+				height: 140rpx;
+				margin: 20rpx 20rpx 40rpx;
+				border-radius: 50%;
+				border: 2px solid #fff;
+			}
+		}
+
+		.subtitle {
+			color: #7e7e7e;
+			font-size: 26upx;
+			margin-top: 30rpx;
+		}
+
+		.btn-content {
+			display: flex;
+			width: 100%;
+			border-radius: 0;
+			border-top: 1upx solid #ebebeb;
+
+			button {
+				border: none;
+				width: 50%;
+				font-size: 30rpx;
+				background-color: #FFFFFF;
+				color: #66656a;
+			}
+
+			button:first-child {
+				border-right: 1rpx solid #ebebeb;
+				border-radius: 0 0 0 18rpx;
+			}
+
+			button:last-child {
+				color: #2f7ff5;
+				border-radius: 0 0 18rpx 0;
+			}
+
+		}
+
+		.btn-content button::after {
+			border: none;
+		}
+	}
+</style>

+ 98 - 0
pagesD/comps/modal-checked.vue

@@ -0,0 +1,98 @@
+<template>
+	<view class="">
+		<u-modal @confirm="confirm"  v-model="show" title="请选择服务方式" confirm-color="#EF9944">
+			<view class="modal-content">
+				<view v-for="(item,index) in list" :key="index"
+				 @click="activeIndex=index" class="item" :class="{'active':activeIndex==index}">
+					<view class="flex">
+						<image class="img1" :src="item.icon" mode="widthFix"></image>
+						<text class="center">{{item.name}}</text>
+					</view>
+					<view class="">
+						<image v-if="activeIndex==index" class="img2 center" src="/pagesD/static/icon/checked.png" mode=""></image>
+					</view>
+				</view>
+			</view>
+		</u-modal>
+	</view>
+</template>
+
+<script>
+export default {
+	props:{
+		list:Array
+	},
+	data() {
+		return {
+			show:false,
+			activeIndex:0
+		};
+	},
+	onLoad() {
+		
+	},
+	methods:{
+		showModal(){
+			this.show=true
+		},
+		hideModal(){
+			this.show=false
+		},
+		confirm(){
+			this.$emit('confirm',this.activeIndex)
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+	.modal-content{
+		padding:70rpx 30rpx;
+		
+		.img1{
+			width: 40rpx;
+			height: 40rpx;
+			margin-right: 20rpx;
+			margin-left: 20rpx;
+		}
+		.img2{
+			width: 36rpx;
+			height: 36rpx;
+			margin-right: 20rpx;
+		}
+		.img3{
+			width: 42rpx;
+			height: 42rpx;
+			margin-right: 20rpx;
+			margin-left: 20rpx;
+		}
+		
+		 .item{
+			display: flex;
+			justify-content: space-between;
+			background-color: #f7f7f7;
+			border-radius: 50rpx;
+			padding: 20rpx;
+			margin-bottom: 30rpx;
+			font-size: 26rpx;
+			font-weight: 400;
+			color: #696969;
+			
+		}
+		
+		.active {
+			color: #0b0100;
+			// background-color:rgba(255, 148, 71,.3);
+			background-color: #fef6e1;
+			
+			
+			image{
+				transform: scale(1.3);
+			}
+			
+			text{
+				transform: scale(1.1);
+			}
+		}
+	}
+</style>

+ 393 - 0
pagesD/comps/modal/modal.vue

@@ -0,0 +1,393 @@
+<template>
+	<view @touchmove.stop.prevent>
+		<view class="modal-box" :style="{width:width,padding:padding,borderRadius:radius}" :class="[(fadein || show)?'modal-normal':'modal-scale',show?'modal-show':'']">
+			<view v-if="custom">
+				<slot></slot>
+			</view>
+			<view v-else>
+				<view class="modal-title" v-if="title">{{title}}</view>
+				<view class="modal-content" :class="[title?'':'mtop']" :style="{color:color,fontSize:size+'rpx'}">
+					<slot></slot>
+				</view>
+				<view class="modalBtn-box" :class="[button.length!=2?'flex-column':'']">
+					<block v-for="(item,index) in button" :key="index">
+						<button class="modal-btn" 
+								:class="[
+										''+(item.type || 'primary')+(item.plain?'-outline':''),
+										button.length!=2?'btn-width':'',
+										button.length>2?'mbtm':'',
+										shape=='circle'?'circle-btn':'',
+										'btn-' + (item.size || 'default'),										
+									]"
+								:hover-class="''+(item.plain?'outline':(item.type || 'primary'))+'-hover'" :data-index="index" @tap="handleClick">{{item.text || "确定"}}</button>
+					</block>
+				</view>
+			</view>
+		</view>
+		<view class="modal-mask" :class="[show?'mask-show':'']" @tap="handleClickCancel"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "Modal",
+		props: {
+			//是否显示
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//自定义modal体
+			custom: {
+				type: Boolean,
+				default: false
+			},
+			width: {
+				type: String,
+				default: "84%"
+			},
+			padding: {
+				type: String,
+				default: "40rpx"
+			},
+			radius: {
+				type: String,
+				default: "24rpx"
+			},
+			//标题
+			title: {
+				type: String,
+				default: ""
+			},
+			//内容
+			content: {
+				type: String,
+				default: ""
+			},
+			//内容字体颜色
+			color: {
+				type: String,
+				default: "#999"
+			},
+			//内容字体大小 rpx
+			size: {
+				type: Number,
+				default: 28
+			},
+			//形状 circle, square
+			shape: {
+				type: String,
+				default: 'square'
+			},
+			button: {
+				type: Array,
+				default: function() {
+					return [{
+						text: "取消",
+						type: "red",
+						plain: true //是否空心
+					}, {
+						text: "确定",
+						type: "red",
+						plain: false
+					}]
+				}
+			},
+			//点击遮罩 是否可关闭
+			maskClosable: {
+				type: Boolean,
+				default: true
+			},
+			//淡入效果,自定义弹框插入input输入框时传true
+			fadein: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			handleClick(e) {
+				if (!this.show) return;
+				const dataset = e.currentTarget.dataset;
+				this.$emit('click', {
+					index: Number(dataset.index)
+				});
+			},
+			handleClickCancel() {
+				if (!this.maskClosable) return;
+				this.$emit('cancel');
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.modal-box {
+		position: fixed;
+		left: 50%;
+		top: 50%;
+		margin: auto;
+		background: #fff;
+		z-index: 9999998;
+		transition: all 0.3s ease-in-out;
+		opacity: 0;
+		box-sizing: border-box;
+		visibility: hidden;
+	}
+
+	.modal-scale {
+		transform: translate(-50%, -50%) scale(0);
+	}
+
+	.modal-normal {
+		transform: translate(-50%, -50%) scale(1);
+	}
+
+	.modal-show {
+		opacity: 1;
+		visibility: visible;
+	}
+
+	.modal-mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 9999996;
+		transition: all 0.3s ease-in-out;
+		opacity: 0;
+		visibility: hidden;
+	}
+
+	.mask-show {
+		visibility: visible;
+		opacity: 1;
+	}
+
+	.modal-title {
+		text-align: center;
+		font-size: 34rpx;
+		color: #333;
+		padding-top: 20rpx;
+		font-weight: bold;
+	}
+
+	.modal-content {
+		color: #999;
+		font-size: 28rpx;
+		padding-top: 20rpx;
+		padding-bottom: 60rpx;
+	}
+
+	.mtop {
+		margin-top: 30rpx;
+	}
+
+	.mbtm {
+		margin-bottom: 30rpx;
+	}
+
+	.modalBtn-box {
+		width: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: space-between
+	}
+
+	.flex-column {
+		flex-direction: column;
+	}
+
+	.modal-btn {
+		width: 46%;
+		height: 68rpx;
+		line-height: 68rpx;
+		position: relative;
+		border-radius: 60rpx;
+		font-size: 28rpx;
+		overflow: visible;
+		margin-left: 0;
+		margin-right: 0;
+		
+		&.btn-default {
+			font-size: 28rpx;
+		}
+		
+		&.btn-lg {
+			font-size: 32rpx;
+		}
+		
+		&.btn-sm {
+			font-size: 24rpx;
+		}
+	}
+
+	.modal-btn::after {
+		content: "";
+		position: absolute;
+		width: 200%;
+		height: 200%;
+		-webkit-transform-origin: 0 0;
+		transform-origin: 0 0;
+		-webkit-transform: scale(0.5, 0.5);
+		transform: scale(0.5, 0.5);
+		left: 0;
+		top: 0;
+		border-radius: 60rpx;
+	}
+
+	.btn-width {
+		width: 80% !important;
+	}
+
+	.primary {
+		background: #97AF13;
+		color: #fff;
+	}
+
+	.primary-hover {
+		background: #97AF13;
+		color: #e5e5e5;
+	}
+
+	.primary-outline {
+		color: #97AF13;
+		background: none;
+	}
+
+	.primary-outline::after {
+		border: 1px solid #97AF13;
+	}
+
+	.danger {
+		background: #ed3f14;
+		color: #fff;
+	}
+
+	.danger-hover {
+		background: #d53912;
+		color: #e5e5e5;
+	}
+
+	.danger-outline {
+		color: #ed3f14;
+		background: none;
+	}
+
+	.danger-outline::after {
+		border: 1px solid #ed3f14;
+	}
+
+	.red {
+		background: #e41f19;
+		color: #fff;
+	}
+
+	.red-hover {
+		background: #c51a15;
+		color: #e5e5e5;
+	}
+
+	.red-outline {
+		color: #e41f19;
+		background: none;
+	}
+
+	.red-outline::after {
+		border: 1px solid #e41f19;
+	}
+
+	.warning {
+		background: #ff7900;
+		color: #fff;
+	}
+
+	.warning-hover {
+		background: #e56d00;
+		color: #e5e5e5;
+	}
+
+	.warning-outline {
+		color: #ff7900;
+		background: none;
+	}
+
+	.warning-outline::after {
+		border: 1px solid #ff7900;
+	}
+
+	.green {
+		background: #19be6b;
+		color: #fff;
+	}
+
+	.green-hover {
+		background: #16ab60;
+		color: #e5e5e5;
+	}
+
+	.green-outline {
+		color: #19be6b;
+		background: none;
+	}
+
+	.green-outline::after {
+		border: 1px solid #19be6b;
+	}
+
+	.white {
+		background: #fff;
+		color: #333;
+	}
+
+	.white-hover {
+		background: #f7f7f9;
+		color: #666;
+	}
+
+	.white-outline {
+		color: #333;
+		background: none;
+	}
+
+	.white-outline::after {
+		border: 1px solid #333;
+	}
+
+	.gray {
+		background: #ededed;
+		color: #999;
+	}
+
+	.gray-hover {
+		background: #d5d5d5;
+		color: #898989;
+	}
+
+	.gray-outline {
+		color: #999;
+		background: none;
+	}
+
+	.gray-outline::after {
+		border: 1px solid #999;
+	}
+
+	.outline-hover {
+		opacity: 0.6;
+	}
+
+	.circle-btn {
+		border-radius: 40rpx !important;
+	}
+
+	.circle-btn::after {
+		border-radius: 80rpx !important;
+	}
+</style>

+ 155 - 0
pagesD/comps/popup-layer/popup-layer.vue

@@ -0,0 +1,155 @@
+<template>
+	<view>
+		<view v-show="ifshow" @tap="ableClose" @touchmove.stop.prevent class="popup-layer" >
+		</view>
+		<view class="popup-content" @tap.stop="stopEvent" :style="_location">
+			<slot name="content"></slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'popup-layer',
+		model: {
+			prop: "showPop",
+			event: "change"
+		},
+		props: {
+			showPop:{
+				type:Boolean,
+				default:false,
+			},
+			direction: {
+				type: String,
+				default: 'top', // 方向  top,bottom,left,right 
+			},
+			autoClose: {
+				type: Boolean,
+				default: true,
+			}
+		},
+		data() {
+			return {
+				ifshow: false, // 是否展示,
+				//#ifdef H5
+				translateValue: -150, // 位移距离
+				//#endif
+				//#ifndef H5
+				translateValue: -100, // 位移距离
+				//#endif
+				timer: null,
+				iftoggle: false,
+
+			};
+		},
+		computed: {
+			_translate() {
+				const transformObj = {
+					'top': `transform:translateY(${-this.translateValue}%)`,
+					'bottom': `transform:translateY(${this.translateValue}%)`,
+					'left': `transform:translateX(${-this.translateValue}%)`,
+					'right': `transform:translateX(${this.translateValue}%)`
+				};
+				return transformObj[this.direction]
+			},
+			_location() {
+				const positionValue = {
+					//#ifndef H5
+					'top': 'bottom:0px;width:100%;',
+					//#endif
+					 //#ifdef H5
+					'top': 'bottom:50px;width:100%;',
+					 //#endif
+					'bottom': 'top:0px;width:100%;',
+					'left': 'right:0px;height:100%;',
+					'right': 'left:0px;height:100%;',
+				};
+				return positionValue[this.direction] + this._translate;
+			}
+		},
+		mounted(){
+			if(this.showPop){
+				// console.log(222);
+				this.show();
+			}
+		},
+		watch:{
+			showPop(value){
+				console.log(value)
+				if(value){
+					this.show();
+				}else{
+					this.close();
+				}
+			}	
+		},
+		methods: {
+			stopMove(event){
+				console.log(11);
+				console.log(event);
+				return;
+			},
+			show(events) {
+				this.ifshow = true;
+				let _open = setTimeout(() => {
+					this.translateValue = 0;
+					_open = null;
+				}, 100)
+				let _toggle = setTimeout(() => {
+					this.iftoggle = true;
+					_toggle = null;
+				}, 300);
+			},
+			close() {
+				if (this.timer !== null || !this.iftoggle) {
+					return;
+				}
+				this.translateValue = -100;
+				//#ifdef H5
+				this.translateValue = -150
+				//#endif
+				this.timer = setTimeout(() => {
+					this.ifshow = false;
+					this.timer = null;
+					this.iftoggle = false;
+					this.$emit('closeCallBack', null);
+					this.$emit('change',false)
+				}, 300);
+			},
+			ableClose() {
+				if (this.autoClose) {
+					this.close();
+				}
+			},
+			stopEvent(event) {},
+			doSome(){
+				console.log(111222111111111);
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.popup-layer {
+		position: fixed;
+		z-index: 9990;
+		background: rgba(0, 0, 0, .3);
+		height: 100%;
+		width: 100%;
+		top: 0px;
+		left: 0px;
+		overflow: hidden;
+	}
+
+	.popup-content {
+		position: fixed;
+		z-index: 9991;
+		background: #FFFFFF;
+		transition: all .3s ease;
+		overflow: hidden;
+		box-sizing: border-box;
+		// border:1px solid red;
+	}
+</style>

+ 231 - 0
pagesD/comps/u-city-select.vue

@@ -0,0 +1,231 @@
+<template>
+	<u-popup v-model="value" mode="bottom" :popup="false" :mask="true" :closeable="true" :safe-area-inset-bottom="true"
+	 close-icon-color="#ffffff" :z-index="uZIndex" :maskCloseAble="maskCloseAble" @close="close">
+		<u-tabs v-if="value" :list="genTabsList" :is-scroll="true" :current="tabsIndex" @change="tabsChange" ref="tabs"></u-tabs>
+		<view class="area-box">
+			<view class="u-flex" :class="{ 'change':isChange }">
+				<view class="area-item">
+					<view class="u-padding-10 u-bg-gray" style="height: 100%;">
+						<scroll-view :scroll-y="true" style="height: 100%">
+							<u-cell-group>
+								<u-cell-item v-for="(item,index) in provinces" :title="item.label" :arrow="false" :index="index" :key="index"
+								 @click="provinceChange">
+									<u-icon v-if="isChooseP&&province===index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
+								</u-cell-item>
+							</u-cell-group>
+						</scroll-view>
+					</view>
+				</view>
+				<view class="area-item">
+					<view class="u-padding-10 u-bg-gray" style="height: 100%;">
+						<scroll-view :scroll-y="true" style="height: 100%">
+							<u-cell-group v-if="isChooseP">
+								<u-cell-item v-for="(item,index) in citys" :title="item.label" :arrow="false" :index="index" :key="index"
+								 @click="cityChange">
+									<u-icon v-if="isChooseC&&city===index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
+								</u-cell-item>
+							</u-cell-group>
+						</scroll-view>
+					</view>
+				</view>
+
+				<view class="area-item">
+					<view class="u-padding-10 u-bg-gray" style="height: 100%;">
+						<scroll-view :scroll-y="true" style="height: 100%">
+							<u-cell-group v-if="isChooseC">
+								<u-cell-item v-for="(item,index) in areas" :title="item.label" :arrow="false" :index="index" :key="index"
+								 @click="areaChange">
+									<u-icon v-if="isChooseA&&area===index" slot="right-icon" size="34" name="checkbox-mark"></u-icon>
+								</u-cell-item>
+							</u-cell-group>
+						</scroll-view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</u-popup>
+</template>
+
+<script>
+	import provinces from "uview-ui/libs/util/province.js";
+	import citys from "uview-ui/libs/util/city.js";
+	import areas from "uview-ui/libs/util/area.js";
+	/**
+	 * city-select 省市区级联选择器
+	 * @property {String Number} z-index 弹出时的z-index值(默认1075)
+	 * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
+	 * @property {String} default-region 默认选中的地区,中文形式
+	 * @property {String} default-code 默认选中的地区,编号形式
+	 */
+	export default {
+		name: 'u-city-select',
+		props: {
+			// 通过双向绑定控制组件的弹出与收起
+			value: {
+				type: Boolean,
+				default: false
+			},
+			// 默认显示的地区,可传类似["河北省", "秦皇岛市", "北戴河区"]
+			defaultRegion: {
+				type: Array,
+				default () {
+					return [];
+				}
+			},
+			// 默认显示地区的编码,defaultRegion和areaCode同时存在,areaCode优先,可传类似["13", "1303", "130304"]
+			areaCode: {
+				type: Array,
+				default () {
+					return [];
+				}
+			},
+			// 是否允许通过点击遮罩关闭Picker
+			maskCloseAble: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出的z-index值
+			zIndex: {
+				type: [String, Number],
+				default: 0
+			}
+		},
+		data() {
+			return {
+				cityValue: "",
+				isChooseP: false, //是否已经选择了省
+				province: 0, //省级下标
+				provinces: provinces,
+				isChooseC: false, //是否已经选择了市
+				city: 0, //市级下标
+				citys: citys[0],
+				isChooseA: false, //是否已经选择了区
+				area: 0, //区级下标
+				areas: areas[0][0],
+				tabsIndex: 0,
+			}
+		},
+		mounted() {
+			this.init();
+		},
+		computed: {
+			isChange() {
+				return this.tabsIndex > 1;
+			},
+			genTabsList() {
+				let tabsList = [{
+					name: "请选择"
+				}];
+				if (this.isChooseP) {
+					tabsList[0]['name'] = this.provinces[this.province]['label'];
+					tabsList[1] = {
+						name: "请选择"
+					};
+				}
+				if (this.isChooseC) {
+					tabsList[1]['name'] = this.citys[this.city]['label'];
+					tabsList[2] = {
+						name: "请选择"
+					};
+				}
+				if (this.isChooseA) {
+					tabsList[2]['name'] = this.areas[this.area]['label'];
+				}
+				return tabsList;
+			},
+			uZIndex() {
+				// 如果用户有传递z-index值,优先使用
+				return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
+			}
+		},
+		methods: {
+			init() {
+				if (this.areaCode.length == 3) {
+					this.setProvince("", this.areaCode[0]);
+					this.setCity("", this.areaCode[1]);
+					this.setArea("", this.areaCode[2]);
+				} else if (this.defaultRegion.length == 3) {
+					this.setProvince(this.defaultRegion[0], "");
+					this.setCity(this.defaultRegion[1], "");
+					this.setArea(this.defaultRegion[2], "");
+				};
+			},
+			setProvince(label = "", value = "") {
+				this.provinces.map((v, k) => {
+					if (value ? v.value == value : v.label == label) {
+						this.provinceChange(k);
+					}
+				})
+			},
+			setCity(label = "", value = "") {
+				this.citys.map((v, k) => {
+					if (value ? v.value == value : v.label == label) {
+						this.cityChange(k);
+					}
+				})
+			},
+			setArea(label = "", value = "") {
+				this.areas.map((v, k) => {
+					if (value ? v.value == value : v.label == label) {
+						this.isChooseA = true;
+						this.area = k;
+					}
+				})
+			},
+			close() {
+				this.$emit('input', false);
+			},
+			tabsChange(index) {
+				this.tabsIndex = index;
+			},
+			provinceChange(index) {
+				this.isChooseP = true;
+				this.isChooseC = false;
+				this.isChooseA = false;
+				this.province = index;
+				this.citys = citys[index];
+				this.tabsIndex = 1;
+			},
+			cityChange(index) {
+				this.isChooseC = true;
+				this.isChooseA = false;
+				this.city = index;
+				this.areas = areas[this.province][index];
+				this.tabsIndex = 2;
+			},
+			areaChange(index) {
+				this.isChooseA = true;
+				this.area = index;
+				let result = {};
+				result.province = this.provinces[this.province];
+				result.city = this.citys[this.city];
+				result.area = this.areas[this.area];
+				this.$emit('city-change', result);
+				this.close();
+			}
+		}
+
+	}
+</script>
+<style lang="scss">
+	.area-box {
+		width: 100%;
+		overflow: hidden;
+		height: 800rpx;
+
+		>view {
+			width: 150%;
+			transition: transform 0.3s ease-in-out 0s;
+			transform: translateX(0);
+
+			&.change {
+				transform: translateX(-33.3333333%);
+			}
+		}
+
+		.area-item {
+			width: 33.3333333%;
+			height: 800rpx;
+		}
+	}
+</style>

+ 337 - 0
pagesD/pages/address/add.vue

@@ -0,0 +1,337 @@
+<!-- 添加修改地址 -->
+<template>
+	<view class="address-wrap">
+		<u-form :model="model" :rules="rules" ref="uForm" :errorType="errorType">
+			<!-- 地址定位 -->
+			<view class="location-item u-flex u-row-between u-p-20 u-m-b-20" @tap="chooseLocation">
+				<view class="u-flex">
+					<u-icon name="map-fill" color="#ff9447"></u-icon>
+					<text style="color: #ff9447;">{{ chooseAddress }}</text>
+				</view>
+				<text class="u-iconfont uicon-arrow-right" style="color: #666"></text>
+			</view>
+
+			<view class="address-box">
+				<!-- 地址表单 -->
+				<u-form-item :labelStyle="labelStyle"   label-width="150" label-position="left" label="收货人:"
+					prop="consignee">
+					<u-input placeholder="请填写收货人姓名" v-model="model.consignee" type="text"></u-input>
+				</u-form-item>
+				<u-form-item :labelStyle="labelStyle"   label-width="150" label-position="left" label="手机号:"
+					prop="phone">
+					<u-input placeholder="请输入收货人手机号" v-model="model.phone" type="number"></u-input>
+				</u-form-item>
+				<u-form-item :labelStyle="labelStyle" label-width="150" label-position="left" label="所在地区:"
+					prop="area_text">
+					<u-input type="select" v-model="model.area_text" :select-open="showSelect" placeholder="请选择地区"
+						@click="showSelect = true"></u-input>
+				</u-form-item>
+				<u-form-item :labelStyle="labelStyle" label-position="top" label-width="150" label="详细地址:"
+					prop="address">
+					<u-input border borderColor="#eee" height="150" type="textarea" v-model="model.address"
+						placeholder="如道路、门牌号、小区、楼栋号、单元室等" />
+				</u-form-item>
+			</view>
+
+			<!-- 设置默认 -->
+			<view class="default-box u-flex u-row-between">
+				<text class="title">设为默认地址</text>
+				<u-switch v-model="model.isDefault" activeColor="#ff9447" size="40"></u-switch>
+			</view>
+
+		</u-form>
+
+		<block v-if="!showSelect">
+			<view class="" style="height: 90rpx;"></view>
+			<view :style="{paddingBottom:safeAreaBottom}" class="footer-fixed center" style="bottom: 10%;">
+				<view @click="submit" class="cu-btn df btn-bg-color  round " style="width: 90%;height: 80rpx;">
+					<text>保存收货地址</text>
+				</view>
+			</view>
+		</block>
+
+		<!-- 省市区选择器 -->
+		<city-select v-model="showSelect" @city-change="getRegion"></city-select>
+	</view>
+</template>
+
+<script>
+	import citySelect from '../../comps/u-city-select.vue';
+	export default {
+		components: {
+			citySelect
+		},
+		data() {
+			return {
+				showSelect: false, //省市区
+				addressAreaList: [],
+				addressId: 0, //收货地址ID
+				labelStyle: {
+					'font-size': '28rpx',
+					'font-weight': '600',
+					color: '#595959'
+				},
+				model: {
+					id: '',
+					userId:'',
+					consignee: '',
+					phone: '',
+					area_text: '',
+					address: '',
+					isDefault: false,
+					latitude: '',
+					longitude: ''
+				},
+				rules: {
+					phone: [{
+							required: true,
+							message: '请输入收货人手机号',
+							trigger: ['change', 'blur']
+						},
+						{
+							validator: (rule, value, callback) => {
+								return this.$u.test.mobile(value);
+							},
+							message: '手机号码不正确',
+							trigger: ['change', 'blur']
+						}
+					],
+					consignee: [{
+						required: true,
+						message: '请填写收货人姓名',
+						trigger: ['change', 'blur']
+					}],
+					area_text: [{
+						required: true,
+						message: '请选择地区',
+						trigger: ['change', 'blur']
+					}],
+					address: [{
+						required: true,
+						message: '请输入详细地址',
+						trigger: ['change', 'blur']
+					}]
+				},
+				errorType: ['message'],
+				chooseAddress: '点击选择地理位置'
+			};
+		},
+		computed: {},
+		onReady() {
+			this.$refs.uForm.setRules(this.rules);
+		},
+		onLoad(options) {
+			this.addressId = options.addressId
+			this.model.phone=this.vuex_phone
+			this.model.userId=this.vuex_userId
+			uni.setNavigationBarTitle({
+				title: this.addressId ? '编辑收货地址' : '添加收货地址'
+			});
+			
+			if (this.$isNotEmpty(this.addressId)) {
+				//编辑
+				this.fetchAddress()
+				return
+			}
+			console.log("1111");
+			//新增
+			if (options.wxAddress) {
+				// 微信导入
+				this.wxAddressInit(options)
+			}else{
+				//定位获取
+				this.getLocation()
+			}
+		},
+		methods: {
+			fetchAddress(){
+				this.$api.address.detail({id:this.addressId}).then(res=>{
+					if (this.$isNotEmpty(res.data)) {
+						this.chooseAddress=res.data.address
+						this.model=res.data
+						this.model.area_text = res.data.provinceName + '-' + res.data.cityName + '-' + res.data.areaName
+					}
+				})
+			},
+			async analyseLocation(data, type = 0) {
+				let params = {
+					longitude: data.longitude,
+					latitude: data.latitude
+				}
+				let res = await this.$api.activity.getLocation(params)
+				let result = res.data.result
+				this.model.area_text = result.address_component.province + '-' +
+					result.address_component.city + '-' +
+					result.address_component.district
+				if (type == 1) {
+					this.chooseAddress = result.formatted_addresses.recommend
+					this.model.address= result.formatted_addresses.recommend
+				}else{
+					this.chooseAddress = data.name
+					this.model.address= data.name
+				}
+			},
+			async chooseLocation() {
+				let res = await this.$mpi.chooseLocation()
+				if (res.errMsg != 'chooseLocation:ok') {
+					this.$u.toast('选择地址失败')
+					return
+				}
+				this.analyseLocation(res)
+			},
+			async getLocation() {
+				let res = await this.$mpi.getLocation()
+				if (res.errMsg != 'getLocation:ok') {
+					return
+				}
+				this.analyseLocation(res, 1)
+			},
+			getRegion(data) {
+				console.log(data)
+				this.model.area_text = data.province.label + '-' + data.city.label + '-' + data.area.label
+			},
+			// 微信导入数据格式
+			wxAddressInit(options) {
+				let wxAddress = JSON.parse(options.wxAddress); //微信导入
+				console.log(wxAddress);
+				this.model.consignee = wxAddress.userName;
+				this.model.phone = wxAddress.telNumber;
+				this.model.area_text = `${wxAddress.provinceName}-${wxAddress.cityName}-${wxAddress.countyName}`;
+				this.model.address = wxAddress.detailInfo.replace(/%20/g, '');
+				this.model.isDefault = false;
+				
+				this.chooseAddress=this.model.address
+			},
+
+			// 提交
+			submit() {
+				this.$refs.uForm.validate(valid => {
+					valid ? this.editAddress() : console.log('验证失败');
+				});
+			},
+			// 编辑添加地址
+			editAddress() {
+				let that = this;
+				let area= this.model.area_text.split("-")
+				let data=this.$u.deepClone(this.model)
+				data.provinceName=area[0]
+				data.cityName=area[1]
+				data.areaName=area[2]
+				this.$api.address.submit(data).then(res=>{
+					if (res.success) {
+						this.$dialog.showModalAndBack('操作成功')
+					}
+				})
+			},
+			// 删除收货地址
+			deleteAddress() {
+				const that = this;
+				that.$http(
+					'address.del', {
+						id: that.addressId
+					},
+					'删除中...'
+				).then(res => {
+					if (res.code === 1) {
+						that.$Router.back();
+					}
+				});
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	// 点击定位
+	.location-item {
+		font-size: 28rpx;
+		font-weight: 500;
+		background-color: #fff;
+		color: rgba(167, 111, 13, 1);
+	}
+
+	// 表单
+	.address-box {
+		background-color: #fff;
+		padding: 0 30rpx;
+	}
+
+	.address-item {
+		height: 96rpx;
+		background: #fff;
+		border-bottom: 1rpx solid rgba(#dfdfdf, 0.5);
+		padding: 0 25rpx;
+
+		.item-title {
+			color: #333;
+			font-size: 28rpx;
+			white-space: nowrap;
+		}
+
+		.inp {
+			color: #333;
+			font-size: 28rpx;
+		}
+	}
+
+	.area-box {
+		min-height: 120rpx;
+		padding-bottom: 60rpx;
+		background: #fff;
+		padding: 30rpx 25rpx;
+
+		.item-title {
+			font-size: 28rpx;
+			line-height: 28rpx;
+			vertical-align: middle;
+			white-space: nowrap;
+		}
+
+		.area-inp {
+			color: #333;
+			font-size: 28rpx;
+			vertical-align: middle;
+			margin-top: 8rpx;
+			width: 550rpx;
+		}
+	}
+
+	.default-box {
+		height: 100rpx;
+		padding: 0 25rpx;
+		background: #fff;
+		margin-top: 20rpx;
+
+		.title {
+			font-size: 28rpx;
+		}
+
+		.switch {
+			transform: scale(0.8);
+		}
+	}
+
+	// 底部按钮
+	.foot_box {
+		.delete-btn {
+			line-height: 70rpx;
+			background: linear-gradient(93deg, rgba(208, 19, 37, 1), rgba(237, 60, 48, 1));
+			box-shadow: 0px 7rpx 6rpx 0px rgba(#ed3c30, 0.22);
+			font-size: 28rpx;
+
+			font-weight: 500;
+			color: rgba(255, 255, 255, 1);
+			border-radius: 35rpx;
+			padding: 0;
+			margin-right: 20rpx;
+		}
+
+		.save-btn {
+			line-height: 70rpx;
+			background: linear-gradient(90deg, rgba(233, 180, 97, 1), rgba(238, 204, 137, 1));
+			border: 1rpx solid rgba(238, 238, 238, 1);
+			border-radius: 40rpx;
+			color: rgba(#fff, 0.9);
+		}
+	}
+</style>

+ 184 - 0
pagesD/pages/address/address.vue

@@ -0,0 +1,184 @@
+<!-- 地址列表 -->
+<template>
+	<view class="address-wrap">
+		<view v-if="addressList" class="address-list" v-for="address in addressList" :key="address.id" @tap="useAddress(address)">
+			<view class="top u-flex">
+				<text class="name">{{ address.consignee }}</text>
+				<text class="phone ">{{ address.phone }}</text>
+				<text class="tag" v-if="address.isDefault">默认</text>
+			</view>
+			<view class="detail">{{ address.provinceName }}{{ address.cityName }}{{ address.areaName }}{{ address.address }}</view>
+			<button class="u-reset-button set-btn" @tap.stop="edit(address.id)">编辑</button>
+		</view>
+		
+		<view class="empty" v-else>
+			<image src="@/static/icon/empty5.png" mode="widthFix"></image>
+			<text>暂无地址</text>
+		</view>
+
+		<view class="foot_box-wrap safe-area-inset-bottom">
+			<view class="foot_box u-flex u-row-between safe-area-inset-bottom">
+				<!-- 微信小程序和微信H5 -->
+				<button
+					class="u-reset-button sync-wxaddress u-m-20 u-flex u-row-center u-col-center"
+					@tap="getWXaddress">
+					<text class="u-iconfont uicon-weixin-fill u-p-r-10" style="color:#09bb07;font-size: 40rpx;"></text>
+
+					导入微信地址
+				</button>
+				<button class="u-reset-button add-btn u-m-20" @tap="$jump('/pagesD/pages/address/add')">添加新的收货地址</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+let _this;
+export default {
+	components: {},
+	data() {
+		return {
+			addressList: [],
+		};
+	},
+	computed: {},
+	onLoad() {
+		_this=this
+	},
+	onShow() {
+		this.getAddressList();
+	},
+	methods: {
+		// 选中
+		useAddress(addressData) {
+			let params={
+				addressData
+			}
+			this.$util.backWithParams(params)
+			
+			uni.$emit('ADDRESS',addressData)
+		},
+		//编辑
+		edit(id){
+			uni.navigateTo({
+				url:"./add?addressId="+id
+			})
+		},
+		// 微信导入
+		getWXaddress() {
+			uni.chooseAddress({
+				success: res => {
+					_this.$jump('/pagesD/pages/address/add?wxAddress='+JSON.stringify(res))
+				},
+				fail: err => {
+					console.log('%cuni.chooseAddress,调用失败', 'color:green;background:yellow');
+				}
+			});
+		},
+		getAddressList() {
+			let params={
+				userId:this.vuex_userId
+			}
+			this.$api.address.list(params).then(res=>{
+				this.addressList=res.data.records
+			})
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.empty{
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	margin-top: 360rpx;
+	flex-direction: column;
+	
+	image{
+		width: 220rpx;
+		height: 170rpx;
+	}
+	
+	text{
+		margin-top: 20rpx;
+		font-size: 28rpx;
+		color: #c1c1c1;
+	}
+}	
+
+.address-list {
+	padding: 40rpx;
+	position: relative;
+	background: #fff;
+	margin-bottom: 20rpx;
+
+	.name {
+		font-size: 30rpx;
+		font-weight: 600;
+		margin-bottom: 10rpx;
+	}
+
+	.phone {
+		font-size: 30rpx;
+		margin: 0 20rpx;
+	}
+
+	.tag {
+		background: rgba(233, 191, 113, 0.2);
+		border-radius: 6rpx;
+		padding: 0 16rpx;
+		line-height: 38rpx;
+		color: $base-color;
+		font-size: 22rpx;
+	}
+
+	.detail {
+		margin-top: 25rpx;
+		width: 543rpx;
+		font-size: 26rpx;
+
+		font-weight: 400;
+		color: rgba(153, 153, 153, 1);
+		line-height: 40rpx;
+	}
+
+	.set-btn {
+		background: none;
+		position: absolute;
+		font-size: 26rpx;
+		color: $base-color;
+		top: 40rpx;
+		right: 40rpx;
+	}
+}
+
+// 底部按钮
+.foot_box-wrap {
+	height: 140rpx;
+	width: 100%;
+}
+.foot_box {
+	padding:10rpx 20rpx;
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	width: 100%;
+	background-color: #fff;
+	border-top: 1rpx solid rgba(#ccc, 0.2);
+	.sync-wxaddress {
+		flex: 1;
+		line-height: 80rpx;
+		background: rgba(255, 255, 255, 1);
+		border-radius: 40rpx;
+		box-shadow: 0 0 1rpx 6rpx rgba(#ccc, 0.2);
+	}
+	.add-btn {
+		line-height: 80rpx;
+		flex: 1;
+		background: #ff9447;
+		border-radius: 40rpx;
+		color: rgba(#fff, 0.9);
+	}
+}
+</style>

+ 1504 - 0
pagesD/pages/menu/menu.vue

@@ -0,0 +1,1504 @@
+<template>
+	<view class="u-wrap">
+		<login ref="login"  @signIn="signIn"></login>
+		<view class="u-search-box">
+			<view class="nav" >
+				<view class="header">
+					<view class="left overflow-hidden">
+						<view class="flex align-center overflow-hidden" v-if="takeType == takeTypeGlobal.delivery">
+							<image src="/pagesD/static/icon/location1.png" style="width: 30rpx; height: 30rpx;"
+								class="margin-right-10">
+							</image>
+							<text v-if="$isEmpty(vuex_userId)" @tap="showLogin">去登录</text>
+							<view class="" v-else @click="$jump('/pagesD/pages/address/address')">
+								<text  v-if="$isEmpty(address)">请完善地址信息</text>
+								<view style="margin-right: 20rpx;"  v-else  >
+									<text class="text-cut-1">{{address.address}}</text>
+								</view>
+							</view>
+						</view>
+						<view class="flex align-center overflow-hidden" v-else>
+							<image src="/pagesD/static/icon/shop2.png" style="width: 30rpx; height: 30rpx;"
+								class="margin-right-10">
+							</image>
+							<text style="font-size: 36rpx;font-weight: 800;">杨国福麻辣烫</text>
+						</view>
+					</view>
+					<view @click="modalCheckedShow" class="cu-btn round bg-red sm" style="font-size: 24rpx;">
+						<text class="center">{{takeType.substring(2,4)}}</text>
+						<text class="cuIcon-order center text-bold" style="transform: rotate(90deg);margin-left: 6rpx;"></text>
+					</view>
+				</view>
+				<view class="bg-white">
+					<u-notice-bar mode="horizontal" :list="appProperties.shopNotice"></u-notice-bar>
+				</view>
+			</view>
+		</view>
+		<view class="u-menu-wrap">
+			<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop"
+				:scroll-into-view="itemId">
+				<view  v-for="(item,index) in goods" :key="index" class="u-tab-item"
+					:class="[current == index ? 'u-tab-item-active' : '']" @tap.stop="swichMenu(index)">
+					<text class="u-line-1">{{item.goodsCategoryName}}</text>
+				</view>
+			</scroll-view>
+			<scroll-view :scroll-top="scrollRightTop" scroll-y scroll-with-animation class="right-box"
+				@scroll="rightScroll">
+				<view class="page-view">
+					<view  class="class-item" :id="'item' + index" v-for="(item , index) in goods" :key="index">
+						<view class="item-title" >
+							<text>{{item.goodsCategoryName}}</text>
+						</view>
+						<view class="item-container" >
+							<view class="thumb-box" v-for="(goods, index1) in item.goodsList" :key="index1">
+								<image class="item-menu-image" :src="goods.image" mode=""></image>
+								<view class="item-content" >
+									<view class="name">{{goods.name}}</view>
+									<view class="tips">
+										{{ goods.description && goods.description != '' ? goods.description : goods.name }}
+									</view>
+									<view class="price_and_action">
+										<text class="price">¥{{ goods.defaultPrice / 100 }}</text>
+										<!-- 商品没有下架 -->
+										<view v-if="goods.isSell">
+											<!-- 要选商品规格详细信息 -->
+											<view class="btn-group"
+												v-if="goods.goodsPropertyVos && goods.goodsPropertyVos.length">
+												<button type="primary" class="btn property_btn" hover-class="none"
+													size="mini" @tap="showGoodDetailModal(goods)">
+													选规格
+												</button>
+												<view class="dot" v-show="goodsCartNum(goods.id)">
+													{{ goodsCartNum(goods.id) }}
+												</view>
+											</view>
+											<!-- 可以直接添加,不用选择商品属性 -->
+											<view class="btn-group" v-else>
+												<button type="default" v-show="goodsCartNum(goods.id)" plain
+													class="btn reduce_btn" size="mini" hover-class="none"
+													@tap="handleReduceFromCart(goods)">
+													<view class="iconfont iconsami-select"></view>
+												</button>
+												<view class="number" v-show="goodsCartNum(goods.id)">
+													{{ goodsCartNum(goods.id) }}
+												</view>
+												<button type="primary" class="btn add_btn" size="min" hover-class="none"
+													@tap="handleAddToCart(goods)">
+													<view class="iconfont iconadd-select"></view>
+												</button>
+											</view>
+										</view>
+										<!-- 已经下架了 -->
+										<view v-else>
+											<view class="btn-group">
+												<button type="primary" disabled class="btn property_btn"
+													style="text-decoration: line-through;background-color: rgba(255, 148, 71,.6);" size="mini">
+													已售空
+												</button>
+											</view>
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+		
+		
+		<view class="">
+			<!-- 购物车栏 begin -->
+			<view class="cart-box" v-if="cart && cart.length">
+				<view class="mark" @tap="cartPopupVisible = !cartPopupVisible">
+					<image src="/pagesD/static/icon/cart1.png" class="cart-img"></image>
+					<view class="tag">{{ getCartGoodsNumber }}</view>
+				</view>
+				<view class="price" @tap="cartPopupVisible = !cartPopupVisible">¥{{ getCartGoodsPrice / 100 }}</view>
+				<view v-if="!appProperties.shopStatus"><button type="primary" class="pay-btn" disabled>商家休息中</button>
+				</view>
+				<view v-else-if="isBusinessTime">
+					<button :style="!disabledPay?'background-color: #FF9447;':''"  type="primary" class="pay-btn" @tap="toPay()"
+						:disabled="disabledPay">{{ disabledPay ? `差${spread / 100}元起送` : '去结算' }}</button>
+				</view>
+				<view v-else><button type="primary" class="pay-btn" disabled>未在营业时段</button></view>
+			</view>
+			<!-- 购物车栏 end -->
+			
+			<!-- 商品详情模态框 begin -->
+			<modal :show="goodDetailModalVisible" class="good-detail-modal" color="#5A5B5C" width="90%" custom
+				padding="0rpx" radius="12rpx">
+				<view class="cover">
+					<image v-if="currentGoods.image" :src="currentGoods.image" class="image"></image>
+					<view class="btn-group">
+						<image src="/pagesD/static/icon/close.png" @tap="closeGoodDetailModal"></image>
+					</view>
+				</view>
+				<scroll-view class="detail" scroll-y style="padding-bottom: 100px;">
+					<view class="wrapper">
+						<view class="basic">
+							<view class="name">{{ currentGoods.name }}</view>
+							<view class="tips">{{ currentGoods.description }}</view>
+						</view>
+						<!-- 商品的额外属性 -->
+						<view class="properties"
+							v-if="currentGoods.goodsPropertyVos && currentGoods.goodsPropertyVos.length">
+							<view class="property" v-for="(goodsPropertyVo, index) in currentGoods.goodsPropertyVos"
+								:key="index">
+								<view class="title">
+									<text class="name">
+										<text v-if="goodsPropertyVo.required" style="color: red">*</text>
+										{{ goodsPropertyVo.category }}
+									</text>
+								</view>
+								<view class="values">
+									<view class="value" v-for="(property, index2) in goodsPropertyVo.propertyList"
+										:key="index2" :class="{ default: property.isDefault }"
+										@tap="changePropertyDefault(index, index2)">
+										{{ property.propertyOption }}
+										{{ property.rebasePrice && property.rebasePrice >=0 ? '¥' + property.rebasePrice / 100 : property.extraPrice / 100 ? '¥' + property.extraPrice / 100 : '' }}
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+				<view class="action">
+					<!-- 价格和属性 -->
+					<view class="left">
+						<view class="price">¥{{ currentGoods.realPrice / 100 }}</view>
+						<view class="props" v-if="getGoodSelectedProps(currentGoods)">
+							{{ getGoodSelectedProps(currentGoods) }}
+						</view>
+					</view>
+					<!-- 模态窗里面增减商品 -->
+					<view class="btn-group">
+						<button type="default" plain class="btn" size="mini" hover-class="none"
+							@tap="changeCurrentGoodsNumber(-1)">
+							<view class="iconfont iconsami-select"></view>
+						</button>
+						<view class="number">{{ currentGoods.number }}</view>
+						<button type="primary" class="btn" size="min" hover-class="none" @tap="changeCurrentGoodsNumber(1)">
+							<view class="iconfont iconadd-select"></view>
+						</button>
+					</view>
+				</view>
+				<view class="add-to-cart-btn" @tap="addCurrentGoodsToCart()">
+					<view>确认</view>
+				</view>
+			</modal>
+			<!-- 商品详情模态框 end -->
+			
+			<!-- 购物车详情popup -->
+			
+			<u-popup z-index="99" v-model="cartPopupVisible" mode="bottom">
+				<view class="cart-popup">
+					<view class="top"><text @tap="handleCartClear">清空</text></view>
+					<scroll-view class="cart-list" scroll-y>
+						<view class="wrapper">
+							<view class="item" v-for="(goods, index) in cart" :key="index">
+								<view class="left">
+									<view class="name">{{ goods.name }}</view>
+									<view class="props">{{ getGoodSelectedProps(goods) }}</view>
+								</view>
+								<view class="center">
+									<text>¥{{ goods.realPrice / 100 }}</text>
+								</view>
+								<view class="right">
+									<!-- 购物车里添加数量 -->
+									<button type="default" plain size="mini" class="btn" hover-class="none"
+										@tap="handleCartItemReduce(index)">
+										<view class="iconfont iconsami-select"></view>
+									</button>
+									<view class="number">{{ goods.number }}</view>
+									<!-- 购物车里减少数量 -->
+									<button type="primary" class="btn" size="min" hover-class="none"
+										@tap="handleCartItemAdd(index)">
+										<view class="iconfont iconadd-select"></view>
+									</button>
+								</view>
+							</view>
+							<view class="item" v-if="takeType == takeTypeGlobal.package">
+								<view class="left">
+									<view class="name">包装费</view>
+								</view>
+								<view class="center">
+									<text>¥{{ appProperties.packingPrice / 100 }}</text>
+								</view>
+							</view>
+							<view class="item" v-if="takeType == takeTypeGlobal.delivery">
+								<view class="left">
+									<view class="name">包装费</view>
+								</view>
+								<view class="center">
+									<text>¥{{ appProperties.packingPrice / 100 }}</text>
+								</view>
+								<view class="left">
+									<view class="name">配送费</view>
+								</view>
+								<view class="center">
+									<text>¥{{ appProperties.sendingPrice / 100 }}</text>
+								</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</u-popup>
+			<!-- 购物车详情popup -->
+			
+			<modal-checked @confirm="modalConfirm" ref="modalChecked" :list="checkList"></modal-checked>
+			<login ref="login"  @signIn="signIn"></login>
+		</view>
+		</view>
+	</view>
+</template>
+<script>
+	import login from "../../comps/login.vue"
+	import modal from '../../comps/modal/modal.vue';
+	import modalChecked from "../../comps/modal-checked.vue"
+	import popupLayer from '../../comps/popup-layer/popup-layer.vue';
+	import global from "@/assets/http/global.js"
+	let _this = this
+	export default {
+		components: {
+			modal,
+			popupLayer,
+			login,
+			modalChecked
+		},
+		data() {
+			return {
+				shopId:'',
+				address: {},
+				cart: [],
+				takeType: "店内堂食",
+				takeTypeGlobal:global.takeType,
+				appProperties: {
+					"shopName": "杨国福麻辣烫",
+					"sendingPrice": 100, // 商家配送费
+					"packingPrice": 100, // 包装费
+					"sendingNeedLeastPrice": 2000, // 起送需要的最低价格
+					"businessStartTime": '09:00:00', // 营业开始时间, 开始的点必须在结束之前
+					"businessEndTime": '22:00:00', // 营业结束时间
+					"shopStatus": true, // 商家营业状态
+					"shopNotice": ['10点到22点可以送餐~'], // 公告
+				},
+				goods: {},
+				currentCategoryName: '', // 默认分类
+				goodDetailModalVisible: false, //是否饮品详情模态框
+				currentGoods: {}, // 当前商品
+				selectedPropertyList: [], // 当前商品的属性
+				cartPopupVisible: false,
+				
+				/**
+				 * uview菜单begin
+				 */
+				scrollTop: 0, //tab标题的滚动条位置
+				oldScrollTop: 0,
+				current: 0, // 预设当前项的值
+				menuHeight: 0, // 左边菜单的高度
+				menuItemHeight: 0, // 左边菜单item的高度
+				itemId: '', // 栏目右边scroll-view用于滚动的id
+				goods: [],
+				menuItemPos: [],
+				arr: [],
+				scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
+				timer: null, // 定时器
+				/**
+				 * u-view菜单end
+				 */
+				checkList:[
+					{
+						name:global.takeType.dine_in,
+						icon:"/pagesD/static/icon/order.png",
+					},
+					{
+						name:global.takeType.package,
+						icon:"/pagesD/static/icon/pickup.png",
+					},
+					{
+						name:global.takeType.delivery,
+						icon:"/pagesD/static/icon/delivery2.png",
+					}
+				]
+			}
+		},
+		onLoad(options) {
+			_this = this
+			if (!options.shopId) {
+				this.$dialog.showModalAndBack('系统错误')
+				return
+			}
+			this.shopId=options.shopId
+			this.init()
+			
+		},
+		onShow() {
+			this.address = this.$util.getBackParams('addressData')
+			if (this.$isEmpty(this.address)) {
+				this.fetchAddress()
+			}
+		},
+		onReady() {
+			this.getMenuItemTop()
+		},
+		computed: {
+			isBusinessTime:{
+				get(){
+					return this.timeRange(this.appProperties.businessStartTime,this.appProperties.businessEndTime)
+				}
+			},
+			// 计算单个饮品添加到购物车的数量
+			goodsCartNum() {
+				return id =>
+					this.cart.reduce((acc, cur) => {
+						if (cur.id === id) {
+							return (acc += cur.number);
+						}
+						return acc;
+					}, 0);
+			},
+			// 计算该类商品的购买总数
+			menuCartNum() {
+				return goodsCategoryName =>
+					this.cart.reduce((acc, cur) => {
+						if (cur.goodsCategoryName === goodsCategoryName) {
+							return (acc += cur.number);
+						}
+						return acc;
+					}, 0);
+			},
+			// 计算购物车总数
+			getCartGoodsNumber() {
+				return this.cart.reduce((acc, cur) => acc + cur.number, 0);
+			},
+			// 计算购物车总价,
+			getCartGoodsPrice() {
+				let totalPrice = 0;
+				this.cart.forEach(goods => {
+					totalPrice += goods.realPrice * goods.number;
+				});
+				//如果是到店自取,要计算包装费
+				if (this.takeType == this.takeTypeGlobal.package) {
+					totalPrice += this.appProperties.packingPrice
+				}
+				//如果是商家配送,要计算配送费和包装费
+				if (this.takeType == this.takeTypeGlobal.delivery) {
+					totalPrice += this.appProperties.packingPrice + this.appProperties.sendingPrice;
+				}
+				return totalPrice;
+			}, // 是否达到起送价
+			disabledPay() {
+				return this.takeType == this.takeTypeGlobal.delivery && this.getCartGoodsPrice < this.appProperties
+					.sendingNeedLeastPrice ? true : false;
+			}, // 差多少元起送
+			spread() {
+				if (this.takeType != this.takeTypeGlobal.delivery) return;
+				return this.appProperties.sendingNeedLeastPrice - this.getCartGoodsPrice;
+			}
+		},
+		watch: {
+			cart: {
+				handler: (newV, oldV) => {
+					_this.putCart()
+				},
+				deep: true,
+			}
+		},
+		methods: {
+			modalCheckedShow(){
+				this.$refs.modalChecked.showModal()
+			},
+			timeRange(beginTime, endTime) {//判断是否在缴费查询时间
+			  var strb = beginTime.split (":");
+			  if (strb.length != 3) {
+			    return false;
+			  }
+			 
+			  var stre = endTime.split (":");
+			  if (stre.length != 3) {
+			    return false;
+			  }
+			 
+			  var b = new Date ();
+			  var e = new Date ();
+			  var n = new Date ();
+			  
+			  if (parseInt(strb[0])>=parseInt(stre[0])) {
+				  b.setDate(b.getDate() - 1)
+			  }
+			  
+			  console.log(b,",,,");
+			  console.log(e,",,,");
+			  console.log(n,",,,");
+			 
+			  b.setHours (strb[0]);
+			  b.setMinutes (strb[1]);
+			 b.setSeconds(strb[2]);
+			  e.setHours (stre[0]);
+			  e.setMinutes (stre[1]);
+			  e.setSeconds(stre[2]);
+			  
+			  if (n.getTime () - b.getTime () > 0 && n.getTime () - e.getTime () < 0) {
+			    return true;
+			  } else {
+			    return false;
+			  }
+			},
+
+			//页面初始化
+			async init() {
+				this.initMenu()
+				this.initCart()
+			},
+			initMenu(){
+				this.$api.goods.menu({
+					shopId: this.shopId
+				}).then(res => {
+					this.goods = res.data;
+				})
+			},
+			//初始化购物车
+			initCart() {
+				this.cartKey = this.$global.cart_prefix + this.shopId
+			
+				if (!this.$isEmpty(this.$cache.get(this.cartKey))) {
+					this.cart = this.$cache.get(this.cartKey)
+				}
+			},
+			putCart() {
+				this.$cache.put(this.cartKey, this.cart)
+			},
+			modalConfirm(index){
+				this.takeType=this.checkList[index].name
+				if (this.takeType==this.takeTypeGlobal.delivery) {
+					this.takeout()
+				}
+			},
+			// 选择商家配送的方式下单
+			takeout() {
+				if (this.$isEmpty(this.vuex_userId)) {
+					this.showLogin()
+					return
+				}
+				if (this.$isEmpty(this.address) && this.$isNotEmpty(this.vuex_userId)) {
+					uni.navigateTo({
+						url:"../address/address"
+					})
+				}
+			},
+			// 显示当前商品的详情信息
+			showGoodDetailModal(currentGoods) {
+				currentGoods.number = 1;
+				currentGoods.realPrice = this.getGoodsRealPrice(currentGoods);
+				currentGoods.propertyStr = this.getGoodSelectedProps(currentGoods);
+				this.currentGoods = JSON.parse(JSON.stringify(currentGoods)); // 深拷贝
+			
+				this.goodDetailModalVisible = true;
+				this.selectedPropertyList = [];
+				console.log('显示当前商品的详情信息', this.currentGoods);
+			},
+			// 获取商品具体价格,如大杯商品,小杯商品价格不同
+			getGoodsRealPrice(goods) {
+				console.log(goods);
+				let realPrice = goods.realPrice;
+				if (goods.goodsPropertyVos && goods.goodsPropertyVos.length) {
+					let vos = goods.goodsPropertyVos;
+					for (let i = 0; i < vos.length; i++) {
+						let propertyList = vos[i].propertyList;
+						for (let j = 0; j < propertyList.length; j++) {
+							if (propertyList[j].isDefault && propertyList[j].realPrice) {
+								realPrice = propertyList[j].realPrice;
+								break;
+							}
+						}
+					}
+				}
+				return realPrice;
+			},
+			// 显示当前商品的详情信息
+			showGoodDetailModal(currentGoods) {
+				currentGoods.number = 1;
+				currentGoods.realPrice = this.getGoodsRealPrice(currentGoods);
+				currentGoods.propertyStr = this.getGoodSelectedProps(currentGoods);
+				this.currentGoods = JSON.parse(JSON.stringify(currentGoods)); // 深拷贝
+			
+				this.goodDetailModalVisible = true;
+				this.selectedPropertyList = [];
+				console.log('显示当前商品的详情信息', this.currentGoods);
+			},
+			closeGoodDetailModal() {
+				// 关闭饮品详情模态框
+				this.goodDetailModalVisible = false;
+			},
+			// 改变商品的某个默认属性值 要区分必选和多选的属性
+			changePropertyDefault(categoryIndex, propertyIndex) {
+				let propertyCategory = this.currentGoods.goodsPropertyVos[categoryIndex].category;
+				let propertyList = this.currentGoods.goodsPropertyVos[categoryIndex].propertyList;
+				if (propertyCategory != '加料') {
+					// 必须选一个
+					propertyList.forEach(property => (property.isDefault = false)); // 重置所有默认选择状态重新选择
+					propertyList[propertyIndex].isDefault = true;
+					if (propertyCategory == '大小') {
+						this.currentGoods.realPrice = this.currentGoods.realPrice - this.currentGoods.defaultPrice +
+							propertyList[propertyIndex].rebasePrice;
+						this.currentGoods.defaultPrice = propertyList[propertyIndex].rebasePrice;
+						this.currentGoods.number = 1;
+						this.currentGoods.propertyStr = this.getGoodSelectedProps(this.currentGoods);
+					}
+				} else {
+					// 可选项  加料或减料
+					if (propertyList[propertyIndex].isDefault) {
+						this.currentGoods.realPrice -= propertyList[propertyIndex].extraPrice;
+						propertyList[propertyIndex].isDefault = false;
+					} else {
+						this.currentGoods.realPrice += propertyList[propertyIndex].extraPrice;
+						propertyList[propertyIndex].isDefault = true;
+					}
+				}
+			},
+			// 计算当前饮品所选属性,空格隔开
+			getGoodSelectedProps(goods) {
+				if (goods.goodsPropertyVos) {
+					let propertyStr = '';
+					goods.goodsPropertyVos.forEach(goodsPropertyVo => {
+						goodsPropertyVo.propertyList.forEach(property => {
+							if (property.isDefault) {
+								propertyStr += property.propertyOption + ' ';
+							}
+						});
+					});
+					return propertyStr;
+				}
+				return '';
+			},
+			// 改变当前商品数量
+			changeCurrentGoodsNumber(number) {
+				this.currentGoods.number += number;
+				if (this.currentGoods.number < 0) {
+					this.currentGoods.number = 0;
+				} else if (this.currentGoods.number >= 100) {
+					this.currentGoods.number = 100;
+				}
+			},
+			// 将当前商品加入到购物车
+			addCurrentGoodsToCart() {
+				if (this.currentGoods && this.currentGoods.number) {
+					this.handleAddToCart(this.currentGoods);
+				}
+				this.closeGoodDetailModal();
+			},
+			// 减少购物车里的商品数量, goodsId和propertyStr去比较
+			handleReduceFromCart(goods) {
+				let propertyStr = this.getGoodSelectedProps(goods);
+				let cart = this.cart;
+				for (let i = cart.length - 1; i >= 0; i--) {
+					if (cart[i].id == goods.id && cart[i].propertyStr == propertyStr) {
+						if (cart[i].number <= 1) cart.splice(i, 1);
+						else cart[i].number -= 1;
+			
+						return;
+					}
+				}
+			},
+			// 添加到购物车
+			handleAddToCart(goods) {
+				let propertyStr = this.getGoodSelectedProps(goods);
+				goods.propertyStr = propertyStr;
+				let cart = this.cart;
+				for (let i = cart.length - 1; i >= 0; i--) {
+					if (cart[i].id == goods.id && cart[i].propertyStr == propertyStr) {
+						cart[i].number++;
+			
+						return;
+					}
+				}
+			
+				// 购物车里不存在
+				if (!goods.number) goods.number = 1;
+				this.cart.push(JSON.parse(JSON.stringify(goods)));
+			},
+			// 清空购物车
+			handleCartClear() {
+				let that = this;
+				uni.showModal({
+					title: '提示',
+					content: '确定清空购物车么',
+					success: ({
+						confirm
+					}) => {
+						if (confirm) {
+							that.cartPopupVisible = false;
+							this.cart = []
+						}
+					}
+				});
+			},
+			// 在购物车里操作商品数量
+			handleCartItemAdd(index) {
+				this.cart[index].number += 1;
+			
+			},
+			handleCartItemReduce(index) {
+				if (this.cart[index].number === 1) {
+					this.cart.splice(index, 1);
+				} else {
+					this.cart[index].number -= 1;
+				}
+				if (!this.cart.length) {
+					this.cartPopupVisible = false;
+				}
+			},
+			toPay() {
+				this.cartPopupVisible = false;
+				if (this.$isEmpty(this.vuex_userId)) {
+					this.showLogin()
+					return
+				}
+				let orderInfo={
+					shopId:this.shopId,
+					cart:this.cart,
+					cartKey:this.cartKey,
+					takeType:this.takeType,
+					address:this.address,
+					store:this.appProperties,
+					address:this.address
+				}
+				this.$u.vuex('vuex_orderInfo',orderInfo)
+				uni.navigateTo({
+					url: '../pay/pay'
+				})
+			},
+			fetchAddress(){
+				if (this.$isEmpty(this.vuex_userId)) {
+					return
+				}
+				let params={
+					userId:this.vuex_userId,
+					isDefault:true
+				}
+				this.$api.address.list(params).then(res=>{
+					this.address=res.data.records[0]
+				})
+			},
+			// 登录 begin
+			showLogin(){
+				this.$refs.login.show()
+			},
+			showPhoneModal(){
+				this.$refs.login.showPhoneModal()
+			},
+			signIn(resp){
+				//获取手机号
+				if (this.$isEmpty(this.vuex_phone)) {
+					this.showPhoneModal()
+				}
+				this.$u.toast('登录成功')
+				
+				this.fetchAddress()
+			},
+			async login(e){
+				if (this.$isEmpty(this.vuex_userId)) {
+					this.showLogin()
+					return
+				}else{
+					this.userInfo=this.$cache.get('userInfo')
+				}
+				
+				//获取手机号
+				if (this.$isEmpty(this.vuex_phone)) {
+					this.showPhoneModal()
+				}
+			},
+			// 登录 end
+			
+			
+			/**
+			 * u-view 菜单栏 begin
+			 *
+			 */
+			async swichMenu(index) {
+				if (this.arr.length == 0) {
+					await this.getMenuItemTop();
+				}
+				if (index == this.current) return;
+				this.scrollRightTop = this.oldScrollTop;
+				this.$nextTick(function() {
+					this.scrollRightTop = this.arr[index];
+					this.current = index;
+					this.leftMenuStatus(index);
+				})
+			},
+			// 获取一个目标元素的高度
+			getElRect(elClass, dataVal) {
+				new Promise((resolve, reject) => {
+					const query = uni.createSelectorQuery().in(this);
+					query.select('.' + elClass).fields({
+						size: true
+					}, res => {
+						// 如果节点尚未生成,res值为null,循环调用执行
+						if (!res) {
+							setTimeout(() => {
+								this.getElRect(elClass);
+							}, 10);
+							return;
+						}
+						this[dataVal] = res.height;
+						resolve();
+					}).exec();
+				})
+			},
+			// 观测元素相交状态
+			async observer() {
+				this.goods.map((val, index) => {
+					let observer = uni.createIntersectionObserver(this);
+					// 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
+					// 如果跟.right-box底部相交,就动态设置左边栏目的活动状态
+					observer.relativeTo('.right-box', {
+						top: 0
+					}).observe('#item' + index, res => {
+						if (res.intersectionRatio > 0) {
+							let id = res.id.substring(4);
+							this.leftMenuStatus(id);
+						}
+					})
+				})
+			},
+			// 设置左边菜单的滚动状态
+			async leftMenuStatus(index) {
+				this.current = index;
+				// 如果为0,意味着尚未初始化
+				if (this.menuHeight == 0 || this.menuItemHeight == 0) {
+					await this.getElRect('menu-scroll-view', 'menuHeight');
+					await this.getElRect('u-tab-item', 'menuItemHeight');
+				}
+				// 将菜单活动item垂直居中
+				this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
+			},
+			// 获取右边菜单每个item到顶部的距离
+			getMenuItemTop() {
+				new Promise(resolve => {
+					let selectorQuery = uni.createSelectorQuery();
+					selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
+						// 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
+						if (!rects.length) {
+							setTimeout(() => {
+								this.getMenuItemTop();
+							}, 10);
+							return;
+						}
+						rects.forEach((rect) => {
+							// 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
+							this.arr.push(rect.top - rects[0].top);
+							resolve();
+						})
+					}).exec()
+				})
+			},
+			// 右边菜单滚动
+			async rightScroll(e) {
+				this.oldScrollTop = e.detail.scrollTop;
+				if (this.arr.length == 0) {
+					await this.getMenuItemTop();
+				}
+				if (this.timer) return;
+				if (!this.menuHeight) {
+					await this.getElRect('menu-scroll-view', 'menuHeight');
+				}
+				setTimeout(() => { // 节流
+					this.timer = null;
+					// scrollHeight为右边菜单垂直中点位置
+					let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
+					for (let i = 0; i < this.arr.length; i++) {
+						let height1 = this.arr[i];
+						let height2 = this.arr[i + 1];
+						// 如果不存在height2,意味着数据循环已经到了最后一个,设置左边菜单为最后一项即可
+						if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
+							this.leftMenuStatus(i);
+							return;
+						}
+					}
+				}, 10)
+			},
+			/**
+			 * u-view 菜单栏 end
+			 */
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.nav {
+		width: 100%;
+		flex-shrink: 0;
+		display: flex;
+		flex-direction: column;
+	
+		.header {
+			width: 100%;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			padding: 20rpx;
+			background-color: #ffffff;
+			height: 100rpx;
+	
+			.left {
+				flex: 1;
+				display: flex;
+				flex-direction: column;
+	
+				.store-name {
+					display: flex;
+					justify-content: flex-start;
+					align-items: center;
+					font-size: $font-size-lg;
+					margin-bottom: 10rpx;
+	
+					.iconfont {
+						margin-left: 10rpx;
+						line-height: 100%;
+					}
+				}
+	
+				.store-location {
+					display: flex;
+					justify-content: flex-start;
+					align-items: center;
+					color: $text-color-assist;
+					font-size: $font-size-sm;
+	
+					.iconfont {
+						vertical-align: middle;
+						display: table-cell;
+						color: $color-primary;
+						line-height: 100%;
+					}
+				}
+			}
+	
+			.right {
+				background-color: $bg-color-grey;
+				border-radius: 38rpx;
+				display: flex;
+				align-items: center;
+				font-size: $font-size-sm;
+				padding: 0 38rpx;
+				color: $text-color-assist;
+	
+				.dinein,
+				.takeout {
+					position: relative;
+					display: flex;
+					align-items: center;
+	
+					&.active {
+						padding: 14rpx 38rpx;
+						color: #ffffff;
+						background-color: $color-primary;
+						border-radius: 38rpx;
+					}
+				}
+	
+				.takeout {
+					margin-left: 20rpx;
+					height: 100%;
+					flex: 1;
+					padding: 14rpx 0;
+				}
+	
+				.dinein.active {
+					margin-left: -38rpx;
+				}
+	
+				.takeout.active {
+					margin-right: -38rpx;
+				}
+			}
+		}
+	
+		.coupon {
+			flex: 1;
+			width: 100%;
+			font-size: $font-size-base;
+			color: $color-primary;
+			padding: 0 20rpx;
+			display: flex;
+			align-items: center;
+			overflow: hidden;
+	
+			.title {
+				flex: 1;
+				margin-left: 10rpx;
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
+			}
+	
+			.iconfont {
+				line-height: 100%;
+			}
+		}
+	}
+	.item-container {
+		display: flex;
+		flex-wrap: wrap;
+		
+		.thumb-box {
+			width: 100%;
+			display: flex;
+			padding: 20rpx 0;
+			border-bottom: 1rpx solid #EEEEEE;
+		
+			.item-menu-image {
+				width: 160rpx;
+				height: 160rpx;
+				margin-right: 20rpx;
+				border-radius: 8rpx;
+			}
+			
+			.item-content{
+				width: calc(100% - 180rpx);
+			}
+		
+		
+			.name {
+				font-size: $font-size-base;
+				margin-bottom: 10rpx;
+			}
+		
+			.tips {
+				width: 100%;
+				height: 40rpx;
+				line-height: 40rpx;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				white-space: nowrap;
+				font-size: $font-size-sm;
+				color: $text-color-assist;
+				margin-bottom: 10rpx;
+			}
+		
+			.price_and_action {
+				width: 100%;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				margin-top: 30rpx;
+		
+				.price {
+					font-size: $font-size-base;
+					font-weight: 600;
+				}
+		
+				.btn-group {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					position: relative;
+		
+					.btn {
+						background-color: $base-color;
+						padding: 0 20rpx;
+						box-sizing: border-box;
+						font-size: $font-size-sm;
+						height: 44rpx;
+						line-height: 44rpx;
+		
+						&.property_btn {
+							border-radius: 24rpx;
+						}
+		
+						&.add_btn,
+						&.reduce_btn {
+							color: #FFFFFF;
+							border: $base-color;
+							padding: 0;
+							width: 44rpx;
+							border-radius: 44rpx;
+						}
+					}
+		
+					.dot {
+						position: absolute;
+						background-color: #ffffff;
+						border: 1px solid $color-primary;
+						color: $color-primary;
+						font-size: $font-size-sm;
+						width: 36rpx;
+						height: 36rpx;
+						line-height: 36rpx;
+						text-align: center;
+						border-radius: 100%;
+						right: -12rpx;
+						top: -10rpx;
+					}
+		
+					.number {
+						width: 44rpx;
+						height: 44rpx;
+						line-height: 44rpx;
+						text-align: center;
+					}
+				}
+			}
+		}
+		
+		.thumb-box:last-child {
+			border: none;
+		}
+	}
+	
+	.good-detail-modal {
+		width: 100%;
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+	
+		.cover {
+			height: 320rpx;
+			padding: 30rpx 0;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			position: relative;
+	
+			.image {
+				width: 260rpx;
+				height: 260rpx;
+			}
+	
+			.btn-group {
+				position: absolute;
+				right: 10rpx;
+				top: 30rpx;
+				display: flex;
+				align-items: center;
+				justify-content: space-around;
+	
+				image {
+					width: 80rpx;
+					height: 80rpx;
+				}
+			}
+		}
+	
+		.detail {
+			width: 100%;
+			min-height: 1vh;
+			max-height: calc(90vh - 320rpx - 80rpx - 330rpx);
+	
+			.wrapper {
+				width: 100%;
+				height: 100%;
+				overflow: hidden;
+	
+				.basic {
+					padding: 0 20rpx 30rpx;
+					display: flex;
+					flex-direction: column;
+	
+					.name {
+						font-size: $font-size-base;
+						color: $text-color-base;
+						margin-bottom: 10rpx;
+					}
+	
+					.tips {
+						font-size: $font-size-sm;
+						color: $text-color-grey;
+					}
+				}
+	
+				.properties {
+					width: 100%;
+					border-top: 2rpx solid $bg-color-grey;
+					padding: 10rpx 30rpx 0;
+					display: flex;
+					flex-direction: column;
+	
+					.property {
+						width: 100%;
+						display: flex;
+						flex-direction: column;
+						margin-bottom: 20rpx;
+						padding-bottom: -16rpx;
+	
+						.title {
+							width: 100%;
+							display: flex;
+							justify-content: flex-start;
+							align-items: center;
+							margin-bottom: 20rpx;
+	
+							.name {
+								font-size: 26rpx;
+								color: $text-color-base;
+								margin-right: 20rpx;
+							}
+	
+							.desc {
+								flex: 1;
+								font-size: $font-size-sm;
+								color: $color-primary;
+								overflow: hidden;
+								text-overflow: ellipsis;
+								white-space: nowrap;
+							}
+						}
+	
+						.values {
+							width: 100%;
+							display: flex;
+							flex-wrap: wrap;
+	
+							.value {
+								border-radius: 8rpx;
+								background-color: $bg-color-grey;
+								padding: 16rpx 30rpx;
+								font-size: 26rpx;
+								color: $text-color-assist;
+								margin-right: 16rpx;
+								margin-bottom: 16rpx;
+	
+								&.default {
+									background-color: $color-primary;
+									color: $text-color-white;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	
+		.action {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			background-color: $bg-color-grey;
+			height: 120rpx;
+			padding: 0 26rpx;
+	
+			.left {
+				flex: 1;
+				display: flex;
+				flex-direction: column;
+				justify-content: center;
+				margin-right: 20rpx;
+				overflow: hidden;
+	
+				.price {
+					font-size: $font-size-lg;
+					color: $text-color-base;
+				}
+	
+				.props {
+					color: $text-color-assist;
+					font-size: 24rpx;
+					width: 100%;
+					overflow: hidden;
+					text-overflow: ellipsis;
+					white-space: nowrap;
+				}
+			}
+	
+			.btn-group {
+				display: flex;
+				align-items: center;
+				justify-content: space-around;
+	
+				.number {
+					font-size: $font-size-base;
+					width: 44rpx;
+					height: 44rpx;
+					line-height: 44rpx;
+					text-align: center;
+				}
+	
+				.btn {
+					padding: 0;
+					font-size: $font-size-base;
+					width: 44rpx;
+					height: 44rpx;
+					line-height: 44rpx;
+					border-radius: 100%;
+				}
+			}
+		}
+	
+		.add-to-cart-btn {
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			background-color: $color-primary;
+			color: $text-color-white;
+			font-size: $font-size-base;
+			height: 80rpx;
+			border-radius: 0 0 12rpx 12rpx;
+		}
+	}
+	
+	.cart-popup {
+		.top {
+			background-color: #f3ede3;
+			color: #ff9447;
+			padding: 10rpx 30rpx;
+			font-size: 24rpx;
+			text-align: right;
+		}
+	
+		.cart-list {
+			background-color: #FFFFFF;
+			width: 100%;
+			overflow: hidden;
+			min-height: 30vh;
+			max-height: 70vh;
+			margin-bottom: 30rpx;
+	
+			.wrapper {
+				height: 100%;
+				display: flex;
+				flex-direction: column;
+				padding: 0 30rpx;
+				margin-bottom: 156rpx;
+	
+				.item {
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					padding: 30rpx 0;
+					position: relative;
+	
+					&::after {
+						content: ' ';
+						position: absolute;
+						bottom: 0;
+						left: 0;
+						width: 100%;
+						background-color: $border-color;
+						height: 2rpx;
+						transform: scaleY(.6);
+					}
+	
+					.left {
+						flex: 1;
+						display: flex;
+						flex-direction: column;
+						overflow: hidden;
+						margin-right: 30rpx;
+	
+						.name {
+							font-size: $font-size-sm;
+							color: $text-color-base;
+						}
+	
+						.props {
+							color: $text-color-assist;
+							font-size: 24rpx;
+							overflow: hidden;
+							text-overflow: ellipsis;
+							white-space: nowrap;
+						}
+					}
+	
+					.center {
+						margin-right: 120rpx;
+						font-size: $font-size-base;
+					}
+	
+					.right {
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+	
+						.btn {
+							width: 46rpx;
+							height: 46rpx;
+							border-radius: 100%;
+							padding: 0;
+							text-align: center;
+							line-height: 46rpx;
+						}
+	
+						.number {
+							font-size: $font-size-base;
+							width: 46rpx;
+							height: 46rpx;
+							text-align: center;
+							line-height: 46rpx;
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	
+	
+	.cart-box {
+		position: fixed;
+		bottom: 30rpx;
+		left: 30rpx;
+		right: 30rpx;
+		height: 96rpx;
+		border-radius: 48rpx;
+		box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.2);
+		background-color: #FFFFFF;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		z-index: 999;
+	
+		.cart-img {
+			width: 96rpx;
+			height: 96rpx;
+			position: relative;
+			margin-top: -48rpx;
+		}
+	
+		.pay-btn {
+			height: 100%;
+			padding: 0 30rpx;
+			color: #FFFFFF;
+			border-radius: 0 50rpx 50rpx 0;
+			display: flex;
+			align-items: center;
+		    background-color: rgba(255, 148, 71,.6);
+			font-size: $font-size-base;
+		}
+	
+		.mark {
+			padding-left: 46rpx;
+			margin-right: 30rpx;
+			position: relative;
+	
+			.tag {
+				background-color: #FFFFFF;
+				color: $base-color;
+				border: 1rpx solid $base-color;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				font-size: $font-size-sm;
+				position: absolute;
+				right: -10rpx;
+				top: -50rpx;
+				border-radius: 100%;
+				padding: 4rpx;
+				width: 40rpx;
+				height: 40rpx;
+				opacity: .9;
+			}
+		}
+	
+		.price {
+			flex: 1;
+			color: $text-color-base;
+		}
+	}
+	
+
+	.u-wrap {
+		height: calc(100vh);
+		/* #ifdef H5 */
+		height: calc(100vh - var(--window-top));
+		/* #endif */
+		display: flex;
+		flex-direction: column;
+		width: 100%;
+	}
+
+	.u-search-box {
+		background-color: #FFFFFF;
+	}
+
+	.u-menu-wrap {
+		width: 100%;
+		flex: 1;
+		display: flex;
+		overflow: hidden;
+	}
+
+	.u-search-inner {
+		background-color: rgb(234, 234, 234);
+		border-radius: 100rpx;
+		display: flex;
+		align-items: center;
+		padding: 10rpx 16rpx;
+	}
+
+	.u-search-text {
+		font-size: 26rpx;
+		color: $u-tips-color;
+		margin-left: 10rpx;
+	}
+
+	.u-tab-view {
+		width: 200rpx;
+		height: 100%;
+	}
+
+	.u-tab-item {
+		height: 110rpx;
+		background: #f6f6f6;
+		box-sizing: border-box;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		font-size: 26rpx;
+		color: #444;
+		font-weight: 400;
+		line-height: 1;
+	}
+
+	.u-tab-item-active {
+		position: relative;
+		color: #000;
+		font-size: 30rpx;
+		font-weight: 600;
+		background: #fff;
+	}
+
+	.u-tab-item-active::before {
+		content: "";
+		position: absolute;
+		border-left: 4px solid $base-color;
+		height: 32rpx;
+		left: 0;
+		top: 39rpx;
+	}
+
+	.u-tab-view {
+		height: 100%;
+	}
+
+	.right-box {
+		background-color: rgb(250, 250, 250);
+	}
+
+	.page-view {
+		margin-bottom: 150rpx;
+		background-color: #FFFFFF;
+		padding: 16rpx;
+	}
+
+	.class-item {
+		margin-bottom: 30rpx;
+		background-color: #fff;
+		border-radius: 8rpx;
+	}
+	.class-item:first-child{
+		margin-bottom: 0rpx;
+	}
+
+	.class-item:last-child {
+		min-height: 100vh;
+	}
+
+	.item-title {
+		padding: 20rpx;
+		font-size: 26rpx;
+		color: $u-main-color;
+		font-weight: bold;
+	}
+</style>

+ 349 - 0
pagesD/pages/pay/pay.vue

@@ -0,0 +1,349 @@
+<template>
+	<view class="content">
+		<view class="">
+			<view>
+				<!-- 地址栏 -->
+				<view v-if="takeType==tykeTypeGloabl.delivery" class="bg-white" @click="$jump('/pagesD/pages/address/address')">
+					<view class="add-address-box u-flex u-flex-1" v-if="$isEmpty(address)">
+						<view class="box-bg u-p-30 u-flex-1 u-flex u-row-between">
+							<text class="select-notice">请选择收货地址</text>
+							<text class="cuIcon-right" style="color: #bfbfbf;"></text>
+						</view>
+					</view>
+					<view class="add-address-box u-p-20" v-else>
+						<view class="flex">
+							<view class="center  margin-right-20">
+								<view class="cuIcon cu-btn round bg-base xl " style="width: 80rpx;height: 80rpx;">
+									<text>{{ address.consignee.substring(0,1)}}</text>
+								</view>
+							</view>
+							
+							<view class="" style="width: 90%;">
+								<view class="top u-flex">
+									<text class="name">{{ address.consignee }}</text>
+									<text class="phone">{{ address.phone }}</text>
+									<text class="tag" v-show="address.isDefault == 1">默认</text>
+								</view>
+								<view class="detail u-flex u-row-between" style="width: 100%;">
+									<view class="address text-cut-1" style="width: 90%;">
+										{{ address.provinceName }}{{ address.cityName }}{{ address.areaName }}{{ address.address }}
+									</view>
+									<text class="cuIcon-right margin-left-20" style="color: #bfbfbf;"></text>
+								</view>
+							</view>
+						</view>
+						
+					</view>
+				</view>
+				
+				<view class="card" style="justify-content: flex-start;">
+					<text class="cuIcon-shop center text-base" style="font-size: 34rpx;"></text>
+					<text class="text-lg margin-left-10">{{vuex_orderInfo.store.shopName}}</text>
+				</view>
+				<view class="card text-df" @click="takeTypeShow=true">
+					<text class="text-gray">取餐方式</text>
+					<view class="">
+						<text >{{takeType}}</text>
+						<text class="cuIcon-right"></text>
+					</view>
+				</view>
+				<view v-if="takeType==tykeTypeGloabl.dine_in" class="card text-df">
+					<text class="text-gray">取餐时间</text>
+					<view class="">
+						<text >立即用餐</text>
+						<text class="cuIcon-right"></text>
+					</view>
+				</view>
+				<view v-if="takeType==tykeTypeGloabl.package" class="card text-df" @click="timeShow=true">
+					<view class="">
+						<text class="text-gray">自取时间</text>
+						<view class='cu-tag light sm round margin-left-10 bg-orange'>可预约</view>
+					</view>
+					<view class="">
+						<text >请选择自取时间</text>
+						<text class="cuIcon-right"></text>
+					</view>
+				</view>
+				<view class="card text-df" style="border: none;">
+					<text class="text-gray">联系电话</text>
+					<view class="">
+						<text >{{vuex_phone}}</text>
+						<text class="cuIcon-right"></text>
+					</view>
+				</view>
+			</view>
+			
+			<view style="margin-top: 20rpx;">
+				<view v-for="(item,index) in cart" :key="index" class="cart">
+					<view class="flex" style="width: 70%;">
+						<image :src="item.image" mode=""></image>
+						<view class="item-content">
+							<text class="text-cut-1">{{item.name}}</text>
+							<text class="text-cut-1">{{item.propertyStr ? item.propertyStr : item.name}}</text>
+						</view>
+					</view>
+					<view class="item-data">
+						<view class="">
+							<text class="text-sm">x</text>
+							<text class="text-lg" style="margin-left: 6rpx;">{{item.number}}</text>
+						</view>
+						<text class="text-price text-lg">{{item.realPrice / 100}}</text>
+					</view>
+				</view>
+				<!-- 商家配送 -->
+				<block v-if="takeType==tykeTypeGloabl.delivery">
+					<view class="card text-df">
+						<text class="text-gray">包装费</text>
+						<text class="text-price">1</text>
+					</view>
+					<view class="card text-df">
+						<text class="text-gray">配送费</text>
+						<text class="text-price">1</text>
+					</view>
+				</block>
+				<!-- 到店自取 -->
+				<block v-if="takeType==tykeTypeGloabl.package">
+					<view class="card text-df">
+						<text class="text-gray">包装费</text>
+						<text class="text-price">1</text>
+					</view>
+				</block>
+				
+				<view class="card" style="justify-content: flex-end;flex-direction: column;text-align: right;">
+					<view class="">
+						<text>总计:</text>
+						<text class="text-price text-bold text-xl">{{total / 100}}</text>
+					</view>
+					<view class="text-base text-sm margin-top-20">
+						* 以实际付款为准
+					</view>
+				</view>
+			</view>
+			
+			<view class="card margin-top-20">
+				<text>备注</text>
+				<view style="width: 80%;" class="flex justify-end" @click="goRemark">
+					<text class="text-gray" v-if="!remark">点击填写备注</text>
+					<text v-else class="text-cut-1 text-gray">{{remark}}</text>
+					<text class="cuIcon-right margin-left-10 center"></text>
+				</view>
+			</view>
+		</view>
+		
+		<!-- 付款栏 begin -->
+		<view class="" style="height: 140rpx;"></view>
+		<view class="footer-fixed pay-bar" style="z-index: 99;">
+			<view class="center" style="justify-content: flex-start;margin-left: 40rpx;">
+				<text>总计:</text>
+				<text class="text-price text-bold text-xl">{{total / 100}}</text>
+			</view>
+			<view class="bg-base center text-lg" style="width: 25%;">
+				付款
+			</view>
+		</view>
+		<!-- 付款栏 end -->
+		
+		<!-- 取餐方式 -->
+		<u-picker @confirm="pickConfirm" confirm-color="#FF9447" mode="selector" v-model="takeTypeShow"  :range="takeTypeList"></u-picker>
+		<!-- 自取时间 -->
+		<h-time-alert
+			title="自取时间" 
+			:rangeStartTime="vuex_orderInfo.store.businessStartTime" 
+			:rangeEndTime="vuex_orderInfo.store.businessEndTime"
+			intervalTime="30" 
+			dayStartIntTime="15" 
+			rangeDay="1"
+			:isNow="true"
+			:isShow="timeShow" 
+			@closeAlert="handelClose">
+		</h-time-alert>
+	</view>
+</template>
+
+<script>
+import global from "@/assets/http/global.js"
+import hTimeAlert from "../../comps/h-time-alert.vue"
+export default {
+	components:{
+		hTimeAlert
+	},
+	data() {
+		return {
+			shopId:'',
+			cartKey:'',
+			cart:[],
+			remark:'',
+			//取餐方式
+			takeType:'',
+			tykeTypeGloabl:global.takeType,
+			takeTypeList:[],
+			takeTypeShow:false,
+			//自取时间
+			timeShow:false,
+			//配送地址
+			address:{}
+		};
+	},
+	onLoad() {
+		this.init()
+		uni.$on('REMARK',(remark)=>{
+			this.remark=remark
+		})
+		
+		uni.$on('ADDRESS',(address)=>{
+			console.log(address);
+			this.address=address
+		})
+	},
+	computed:{
+		total() {
+			const sum = this.cart.reduce((pre, item) => {
+			    return pre + item.number * item.realPrice
+			}, 0)
+			//商家配送
+			if (this.takeType==this.$global.takeType.delivery) {
+				return sum + (this.vuex_orderInfo.store.packingPrice)
+				 + (this.vuex_orderInfo.store.sendingPrice)
+			}
+			//到店自取
+			if (this.takeType==this.$global.takeType.package) {
+				return sum + (this.vuex_orderInfo.store.packingPrice)
+			}
+			return sum
+		},
+	},
+	methods:{
+		init(){
+			this.address=this.vuex_orderInfo.address
+			this.takeType=this.vuex_orderInfo.takeType
+			this.takeTypeList=this.$global.takeTypeList
+			this.cart = this.vuex_orderInfo.cart
+			this.shopId=this.vuex_orderInfo.shopId
+			this.cartKey=this.$global.cart_prefix + this.vuex_shopId
+		},
+		goRemark(){
+			uni.navigateTo({
+				url:"remark?data="+this.remark
+			})
+		},
+		pickConfirm(e){
+			let index=e[0]
+			this.takeType=this.takeTypeList[index]
+		},
+		handelClose(data) {
+			this.timeShow = false;
+			console.log(data); 
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+	.content{
+		margin: 20rpx;
+	}
+	
+	.card{
+		padding: 30rpx;
+		background-color: #FFFFFF;
+		border-bottom: 1rpx solid #f1f1f1;
+		display: flex;
+		justify-content: space-between;
+	}
+	
+	.cart{
+		border-bottom: 1rpx solid #f1f1f1;
+		display: flex;
+		background-color: #FFFFFF;
+		padding: 15rpx;
+		
+		image{
+			width: 120rpx;
+			height: 120rpx;
+		}
+		
+		.item-content{
+			width: calc(100% - 120rpx  - 15rpx);
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+			margin-left: 15rpx;
+			
+			text:first-child{
+				font-size: 32rpx;
+				padding-top: 10rpx;
+			}
+			text:last-child{
+				font-size: 26rpx;
+				color: #999;
+				font-weight: 400;
+				padding-bottom: 10rpx;
+			}
+		}
+		
+		.item-data{
+			display: flex;
+			align-items: center;
+			width: 30%;
+			justify-content: space-between;
+			margin-right: 20rpx;
+			
+		}
+	}
+	
+	.cart:last-child{
+		border: none;
+	}
+	
+	.pay-bar{
+		height: 110rpx;
+		background-color: #FFFFFF;
+		display: flex;
+		justify-content: space-between;
+	}
+	
+	
+	.add-address-box {
+		min-height: 100rpx;
+		background: url('http://file.shopro.top/imgs/order/order_address_line.png') no-repeat;
+		background-size: 100% auto;
+		background-position: bottom center;
+	
+		.select-notice {
+			font-weight: 400;
+			color: rgba(153, 153, 153, 1);
+			line-height: 40rpx;
+		}
+	
+		.name,
+		.phone {
+			font-size: 30rpx;
+			font-weight: 500;
+		}
+	
+		.phone {
+			margin: 0 20rpx;
+		}
+	
+		.tag {
+			background: rgba(233, 191, 113, 0.2);
+			border-radius: 6rpx;
+			padding: 0 16rpx;
+			line-height: 38rpx;
+			color: #a8700d;
+			font-size: 22rpx;
+		}
+	
+		.detail {
+			.address {
+				margin-top: 25rpx;
+				width: 543rpx;
+				font-size: 26rpx;
+	
+				font-weight: 400;
+				color: rgba(153, 153, 153, 1);
+				line-height: 40rpx;
+			}
+		}
+	}
+</style>

+ 283 - 0
pagesD/pages/pay/pay1.vue

@@ -0,0 +1,283 @@
+<template>
+	<view class="container position-relative">
+		<view style="margin-bottom: 130rpx;">
+			<view class="section-1">
+				<template v-if="vuex_orderInfo.takeType == '到店自取'">
+					<list-cell class="location">
+						<view class="flex-fill d-flex justify-content-between align-items-center">
+							<view class="store-name flex-fill">
+								{{ vuex_orderInfo.store.shopName }}
+							</view>
+							<image src="/static/images/navigator-1.png" class="arrow"></image>
+						</view>
+					</list-cell>
+				</template>
+				<template v-else>
+					<list-cell @click="chooseAddress">
+						<view class="w-100 d-flex flex-column">
+							<view class="d-flex align-items-center justify-content-between mb-10">
+								<view class="font-size-extra-lg text-color-base">{{ vuex_orderInfo.address.street }}</view>
+								<image src="/static/images/navigator-1.png" class="arrow"></image>
+							</view>
+							<view class="d-flex text-color-assist font-size-sm align-items-center">
+								<view class="mr-10">{{ vuex_orderInfo.address.accept_name }}</view>
+								<view class="mr-10">{{ !vuex_orderInfo.address.sex ? '先生' : '女士' }}</view>
+								<view>{{ vuex_orderInfo.address.mobile }}</view>
+							</view>
+						</view>
+					</list-cell>
+				</template>
+				<template v-if="vuex_orderInfo.takeType == '到店自取'">
+					<list-cell arrow class="meal-time">
+						<view class="flex-fill d-flex justify-content-between align-items-center">
+							<view class="title">取餐时间</view>
+							<view class="time">立即用餐</view>
+						</view>
+					</list-cell>
+					<list-cell class="contact" last :hover="false">
+						<view class="flex-fill d-flex justify-content-between align-items-center">
+							<view class="title flex-fill">联系电话</view>
+							<view class="time">
+								<input class="text-right" placeholder="请输入手机号码" :value="vuex_orderInfo.store.contactPhone"/>
+							</view>
+							<view class="contact-tip font-size-sm">自动填写</view>
+						</view>
+					</list-cell>
+				</template>
+				<template v-else>
+					<list-cell>
+						<view class="w-100 d-flex flex-column">
+							<view class="d-flex align-items-center font-size-base text-color-base">
+								<view class="flex-fill">预计送达时间</view>
+								<view class="mr-10">15:18</view>
+								<image src="/static/images/navigator-1.png" class="arrow"></image>
+							</view>
+							<view class="font-size-base text-color-primary">
+								特殊时期减少接触,请修改下方订单备注
+							</view>
+						</view>
+					</list-cell>
+				</template>
+			</view>
+			<!-- 购物车列表 begin -->
+			<view class="section-2">
+				<view class="cart d-flex flex-column">
+					<list-cell last v-for="(item, index) in vuex_orderInfo.cart" :key="index">
+						<view class="w-100 d-flex flex-column">
+							<view class="d-flex align-items-center mb-10">
+								<view class="name-and-props overflow-hidden">
+									<view class="text-color-base font-size-lg">
+										{{ item.name }}
+									</view>
+								</view>
+								<view class="d-flex flex-fill justify-content-between align-items-center text-color-base font-size-lg">
+									<view>x{{ item.number }}</view>
+									<view>¥{{ item.price }}</view>
+								</view>
+							</view>
+							<view class="text-truncate font-size-base text-color-assist">
+								{{ item.props_text }}
+							</view>
+						</view>
+					</list-cell>
+					<template v-if="vuex_orderInfo.takeType == '商家配送'">
+						<list-cell last v-if="vuex_orderInfo.store.packingPrice > 0">
+							<view class="w-100 d-flex font-size-base align-items-center justify-content-between">
+								<view>包装费</view>
+								<view>¥{{ parseFloat(store.packing_fee / 100) }}</view>
+							</view>
+						</list-cell>
+						<list-cell last v-if="vuex_orderInfo.store.sendingPrice > 0">
+							<view class="w-100 d-flex font-size-base align-items-center justify-content-between">
+								<view>配送费</view>
+								<view>¥{{ parseFloat(vuex_orderInfo.store.sendingPrice / 100) }}</view>
+							</view>
+						</list-cell>
+					</template>
+				</view>
+				<list-cell last>
+					<view class="flex-fill d-flex justify-content-end align-items-center">
+						<view>总计¥{{ total }},实付</view>
+						<view class="font-size-extra-lg font-weight-bold">¥{{ amount }}</view>
+					</view>
+				</list-cell>
+			</view>
+			<!-- 购物车列表 end -->
+			<view class="d-flex align-items-center justify-content-start font-size-sm text-color-warning" 
+				style="padding: 20rpx 0;">
+				<view class="iconfont iconhelp line-height-100"></view>
+				<view>优惠券不与满赠、满减活动共享</view>
+			</view>
+			<!-- 备注 begin -->
+			<list-cell arrow last @click="goToRemark">
+				<view class="d-flex flex-fill align-items-center justify-content-between overflow-hidden">
+					<view class="flex-shrink-0 mr-20">备注</view>
+					<view class="text-color-primary flex-fill text-truncate text-right">{{ form.remark || '点击填写备注' }}</view>
+				</view>
+			</list-cell>
+			<!-- 备注 end -->
+		</view>
+		<!-- 付款栏 begin -->
+		<view class="w-100 pay-box position-fixed fixed-bottom d-flex align-items-center justify-content-between bg-white">
+			<view class="font-size-sm" style="margin-left: 20rpx;">合计:</view>
+			<view class="font-size-lg flex-fill">¥{{ amount }}</view>
+			<view class="bg-primary h-100 d-flex align-items-center just-content-center text-color-white font-size-base"
+				style="padding: 0 60rpx;" @tap="submit">
+				付款
+			</view>
+		</view>
+		<!-- 付款栏 end -->
+		<modal :show="ensureAddressModalVisible" custom :mask-closable="false" :radius="0" width="90%">
+			<view class="modal-content">
+				<view class="d-flex justify-content-end">
+					<image src="/static/images/pay/close.png" style="width: 40rpx; height: 40rpx;" @tap="ensureAddressModalVisible=false"></image>
+				</view>
+				<view class="d-flex just-content-center align-items-center" style="margin-bottom: 40px;">
+					<view class="font-size-extra-lg text-color-base">请再次确认下单地址</view>
+				</view>
+				<view class="d-flex font-size-base text-color-base font-weight-bold align-items-center justify-content-between mb-20">
+					<view>{{ vuex_orderInfo.address.accept_name }} {{ vuex_orderInfo.address.sex ? '女士' : '先生' }}</view>
+					<view>{{ vuex_orderInfo.address.mobile }}</view>
+				</view>
+				<view class="d-flex font-size-sm text-color-assist align-items-center justify-content-between mb-40">
+					<view>{{ vuex_orderInfo.address.street + vuex_orderInfo.address.door_number }}</view>
+					<button type="primary" size="mini" plain class="change-address-btn">修改地址</button>
+				</view>
+				<button type="primary" class="pay_btn" @tap="pay">确认并付款</button>
+			</view>
+		</modal>
+	</view>
+</template>
+
+<script>
+	import listCell from '../../comps/list-cell/list-cell.vue'
+	import modal from '../../comps/modal/modal.vue'
+	
+	export default {
+		components: {
+			listCell,
+			modal
+		},
+		data() {
+			return {
+				cartKey:'',
+				cart:[],
+				form: {
+					remark: ''
+				},
+				ensureAddressModalVisible: false
+			}
+		},
+		computed: {
+			total() {
+				return this.cart.reduce((acc, cur) => acc + cur.number * cur.price, 0)
+			},
+			amount() {
+				return this.cart.reduce((acc, cur) => acc + cur.number * cur.price, 0)
+			}
+		},
+		onLoad(options) {
+			const {remark} = options
+			if (!this.vuex_shopId) {
+				this.$dialog.showModalAndBack('商户id不能为空')
+				return
+			}
+			this.cartKey=this.$global.cart_prefix + this.vuex_shopId
+			this.cart = this.vuex_orderInfo.cart
+			remark && this.$set(this.form, 'remark', remark)
+		},
+		methods: {
+			goToRemark() {
+				uni.navigateTo({
+					url: '/pages/remark/remark?remark=' + this.form.remark
+				})
+			},
+			chooseAddress() {
+				uni.navigateTo({
+					url: '/pages/address/address?is_choose=true&scene=pay'
+				})
+			},
+			submit() {
+				if(this.vuex_orderInfo.takeType == '到店自取') {
+					this.ensureAddressModalVisible = true
+				} else {
+					this.pay()
+				}
+			},
+			pay() {
+				uni.showLoading({title: '加载中'})
+				//测试订单
+				let order = this.vuex_orderInfo.takeType == '到店自取' ? orders[0] : orders[1]
+				order = Object.assign(order, {status: 1})
+				uni.removeStorageSync(this.cartKey)
+				uni.reLaunch({
+					url: '/pages/take-foods/take-foods'
+				})
+				uni.hideLoading()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$color-primary: #FF9447;
+	
+	.container {
+		padding: 30rpx;
+	}
+	
+	.arrow {
+		width: 50rpx; 
+		height: 50rpx;
+		position: relative;
+		margin-right: -10rpx;
+	}
+	
+	.location {
+		.store-name {
+			font-size: 32rpx;
+		}
+		
+		.iconfont {
+			font-size: 50rpx;
+			line-height: 100%;
+			color: $color-primary;
+		}
+	}
+	
+	.section-1 {
+		margin-bottom: 30rpx;
+		.contact {
+			.contact-tip {
+				margin-left: 10rpx;
+				border: 2rpx solid $color-primary;
+				padding: 6rpx 10rpx;
+				color: $color-primary;
+			}
+		}
+	}
+	
+	.section-2 {
+		.name-and-props {
+			width: 65%;
+		}
+	}
+
+	
+	.pay-box {
+		box-shadow: 0 0 20rpx rgba(0, 0, 0, .1);
+		height: 100rpx;
+	}
+	
+	.modal-content {
+		.change-address-btn {
+			line-height: 2;
+			padding: 0 1em;
+		}
+		.pay_btn {
+			width: 100%;
+			border-radius: 50rem !important;
+			line-height: 3;
+		}
+	}
+</style>

+ 81 - 0
pagesD/pages/pay/remark.vue

@@ -0,0 +1,81 @@
+<template>
+	<view class="">
+		<view class="content">
+			<u-input maxlength="50"  height="250" v-model="remark" type="textarea" :border="border" />
+			<view class="text-length">
+				<text style="color: #bfbfbf;">{{remark.length}}</text>
+				<text style="color: #333333;margin-left: 10rpx;">/ 50</text>
+			</view>
+		</view>
+		<view class="tag-content">
+			<text>推荐标签</text>
+			<view class="padding-top-30 flex flex-wrap">
+				<view class="margin-right-20 margin-bottom-20" v-for="(item,index) in tagList" :key="index">
+					<u-tag :index="item" @click="tagClick" color="#FF9447" border-color="#FF9447" mode="plain" :text="item" type="info" />
+				</view>
+			</view>
+		</view>
+		
+		<view class="center footer-fixed" style="margin-top: 120rpx;bottom: 10%;" >
+			<view @click="confirm" class="cu-btn  flex  text-lg btn-bg-color radius" style="padding: 42rpx 0;width: 90%;">
+				确认
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: '',
+	data() {
+		return {
+			remark:'',
+			tagList:[
+				'不吃辣',
+				'少放辣',
+				'多放辣',
+				'不吃蒜',
+				'不吃葱',
+				'不吃香菜',
+			]
+		};
+	},
+	onLoad(options) {
+		this.remark=options.data || ''
+	},
+	methods:{
+		tagClick(item){
+			this.remark=this.remark + item +","
+		},
+		confirm(){
+			uni.$emit('REMARK',this.remark)
+			this.$back()
+		}
+	}
+};
+</script>
+
+<style >
+	
+	page{
+		background-color: #FFFFFF;
+	}
+	.content{
+		padding: 20rpx;
+		margin: 20rpx;
+		background-color: #F1F1F1;
+		border-radius: 4rpx;
+	}
+	
+	.text-length{
+		text-align: right;
+		color: #DDDDDD;
+	}
+	
+	.tag-content{
+		color: #9c9c9c;
+		padding: 20rpx;
+	}
+	
+
+</style>

+ 39 - 0
pagesD/pages/test.vue

@@ -0,0 +1,39 @@
+<template>
+	<view class="">
+		<hTimeAlert 
+			title="自取时间" 
+			rangeStartTime="8:00:00" 
+			rangeEndTime="22:00:00"
+			intervalTime="30" 
+			dayStartIntTime="15" 
+			rangeDay="1"
+			:isNow="true"
+			:isShow="isShow" 
+			@closeAlert="handelClose">
+		</hTimeAlert>
+	</view>
+</template>
+
+<script>
+	import hTimeAlert from "../comps/h-time-alert.vue"
+	export default {
+		components: {
+			hTimeAlert
+		},
+		data() {
+			return {
+				isShow: true,
+			};
+		},
+		methods:{
+			handelClose(data) {
+				this.isShow = false;
+				console.log(data); 
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+
+</style>

BIN
pagesD/static/icon/cart1.png


BIN
pagesD/static/icon/checked.png


BIN
pagesD/static/icon/close.png


BIN
pagesD/static/icon/delivery.png


BIN
pagesD/static/icon/delivery1.png


BIN
pagesD/static/icon/delivery2.png


BIN
pagesD/static/icon/location1.png


BIN
pagesD/static/icon/order.png


BIN
pagesD/static/icon/pickup.png


BIN
pagesD/static/icon/shop.png


BIN
pagesD/static/icon/shop2.png


+ 486 - 0
pagesD/static/style/app.scss

@@ -0,0 +1,486 @@
+@import '~@/uni.scss';
+
+page,
+view,
+scroll-view,
+text,
+image,
+textarea,
+button,
+input {
+	box-sizing: border-box;
+}
+
+page {
+	background-color: #F1F8FA;
+	height: 100%;
+}
+
+.container {
+	width: 100%;
+	height: 100%;
+}
+
+button {
+	margin: 0;
+
+	&[type='primary'] {
+		background-color: $color-primary;
+		color: #ffffff;
+		font-size: $font-size-base;
+		
+		&[disabled] {
+			background-color: #D1D78C;
+		}
+		
+		&[plain] {
+			color: $color-primary;
+			border: 1rpx solid $color-primary;
+			
+			&.button-hover {
+				color: rgba($color: $color-primary, $alpha: 0.5);
+				border: 1rpx solid rgba($color: $color-primary, $alpha: 0.5);
+			}
+		}
+		
+		&.button-hover {
+			background-color: #d5da91;
+		}
+		
+		&::after {
+			border: 0;
+		}
+	}
+
+	&[type='default'] {
+		&[plain] {
+			color: $text-color-assist;
+			border: 1rpx solid $text-color-assist;
+			
+			&.button-hover {
+				color: rgba($color: $text-color-assist, $alpha: 0.5);
+				border: 1rpx solid rgba($color: $text-color-assist, $alpha: 0.5);
+			}
+		}
+	}
+}
+
+uni-toast {
+	z-index: 10002;
+}
+
+.uni-mask {
+	z-index: 10000;
+}
+
+uni-modal, uni-modal .uni-modal {
+	z-index: 10001;
+}
+
+.uni-picker-container .uni-picker {
+	z-index: 10002;
+}
+
+.bg-base {
+	background-color: $bg-color;
+}
+
+.bg-white {
+	background-color: #ffffff;
+}
+
+.bg-transparent {
+  background-color: transparent !important;
+}
+
+.bg-primary {
+	background-color: $color-primary;
+}
+
+.bg-warning {
+	background-color: $color-warning;
+}
+
+.d-flex {
+	display: flex;
+}
+
+.d-none {
+	display: none !important;
+}
+
+.invisible {
+  visibility: hidden !important;
+}
+
+.d-inline {
+	display: inline !important;
+}
+
+.d-inline-block {
+	display: inline-block !important;
+}
+
+.d-block {
+	display: block !important;
+}
+
+.flex-column {
+	-ms-flex-direction: column !important;
+	flex-direction: column !important;
+}
+
+.justify-content-start {
+	justify-content: flex-start;
+}
+
+.justify-content-end {
+	justify-content: flex-end;
+}
+
+.justify-content-between {
+	justify-content: space-between;
+}
+
+.just-content-center {
+	justify-content: center;
+}
+
+.justify-content-evenly {
+	justify-content: space-evenly !important;
+}
+
+.just-content-around {
+	justify-content: space-around;
+}
+
+.align-items-start {
+	align-items: flex-start;
+}
+
+.align-items-end {
+	align-items: flex-end;
+}
+
+.align-items-center {
+	align-items: center;
+}
+
+.align-items-between {
+	align-items: space-between;
+}
+
+.align-items-around {
+	align-items: space-around;
+}
+
+.align-items-stretch {
+	align-items: stretch;
+}
+
+.align-items-baseline {
+	-ms-flex-align: baseline !important;
+	align-items: baseline !important;
+}
+
+.flex-fill {
+	-ms-flex: 1 1 auto !important;
+	flex: 1 1 auto !important;
+}
+
+.flex-wrap {
+	-ms-flex-wrap: wrap !important;
+	flex-wrap: wrap !important;
+}
+
+.flex-nowrap {
+	-ms-flex-wrap: nowrap !important;
+	flex-wrap: nowrap !important;
+}
+
+.flex-shrink-0 {
+	-ms-flex-negative: 0 !important;
+	flex-shrink: 0 !important;
+}
+
+.font-size-base {
+	font-size: 28rpx;
+}
+
+.font-size-sm {
+	font-size: 24rpx;
+}
+
+.font-size-medium {
+	font-size: 26rpx;
+}
+
+.font-size-lg {
+	font-size: 32rpx;
+}
+
+.font-size-extra-lg {
+	font-size: 40rpx;
+}
+
+.text-color-base {
+	color: $text-color-base;
+}
+
+.text-color-assist {
+	color: $text-color-assist;
+}
+
+.text-color-primary {
+	color: $color-primary;
+}
+
+.text-color-danger {
+	color: $color-error;
+}
+
+.text-color-white {
+	color: #ffffff;
+}
+
+.text-color-warning {
+	color: $color-warning;
+}
+
+.text-truncate {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.font-weight-bold {
+	font-weight: 700 !important;
+}
+
+.font-weight-light {
+	font-weight: 300 !important;
+}
+
+.font-weight-lighter {
+	font-weight: lighter !important;
+}
+
+.font-weight-normal {
+	font-weight: 400 !important;
+}
+
+.overflow-auto {
+	overflow: auto !important;
+}
+
+.overflow-hidden {
+	overflow: hidden !important;
+}
+
+.position-relative {
+	position: relative !important;
+}
+
+.position-absolute {
+	position: absolute !important;
+}
+
+.position-fixed {
+	position: fixed !important;
+}
+
+.fixed-top {
+	position: fixed;
+	top: 0;
+	right: 0;
+	left: 0;
+	z-index: 1030;
+}
+
+.fixed-bottom {
+	position: fixed;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 1030;
+}
+
+.line-height-100 {
+	line-height: 100%;
+}
+
+.line-height-2 {
+	line-height: 2rem !important;
+}
+
+.line-height-50 {
+	line-height: 50rem !important;
+}
+
+.w-25 {
+	width: 25% !important;
+}
+
+.w-50 {
+	width: 50% !important;
+}
+
+.w-75 {
+	width: 75% !important;
+}
+
+.w-80 {
+	width: 80% !important;
+}
+
+.w-90 {
+	width: 90% !important;
+}
+
+.w-100 {
+	width: 100% !important;
+}
+
+.h-100 {
+	height: 100% !important;
+}
+
+.h-auto {
+	height: auto !important;
+}
+
+.text-left {
+	text-align: left !important;
+}
+
+.text-right {
+	text-align: right !important;
+}
+
+.text-center {
+	text-align: center !important;
+}
+
+.border-box {
+	box-sizing: border-box;
+}
+
+.rounded-circle {
+	border-radius: 50% !important;
+}
+
+.rounded-pill {
+	border-radius: 50rem !important;
+}
+
+.border-radius-base {
+	border-radius: $border-radius-base;
+}
+
+.pre-line {
+	white-space: pre-line;
+}
+
+.align-top {
+	vertical-align: top !important;
+}
+
+.align-middle {
+	vertical-align: middle !important;
+}
+
+.align-bottom {
+	vertical-align: bottom !important;
+}
+
+.align-text-bottom {
+	vertical-align: text-bottom !important;
+}
+
+.align-text-top {
+	vertical-align: text-top !important;
+}
+
+.w-60 {
+	width: 60%;
+}
+
+.w-40 {
+	width: 40%;
+}
+
+.mb-10 {
+	margin-bottom: 10rpx;
+}
+
+.mb-20 {
+	margin-bottom: 20rpx;
+}
+
+.mb-30 {
+	margin-bottom: 30rpx;
+}
+
+.mb-40 {
+	margin-bottom: 40rpx;
+}
+
+.mb-50 {
+	margin-bottom: 50rpx;
+}
+
+.mt-30 {
+	margin-top: 30rpx;
+}
+
+.mt-40 {
+	margin-top: 40rpx;
+}
+
+.ml-10 {
+	margin-left: 10rpx;
+}
+
+.ml-20 {
+	margin-left: 20rpx;
+}
+
+.ml-30 {
+	margin-left: 30rpx;
+}
+
+.mr-10 {
+	margin-right: 10rpx;
+}
+
+.mr-20 {
+	margin-right: 20rpx;
+}
+
+.mr-30 {
+	margin-right: 30rpx;
+}
+
+.mr-40 {
+	margin-right: 40rpx;
+}
+
+.pl-20 {
+	padding-left: 20rpx;
+}
+
+.pl-30 {
+	padding-left: 30rpx;
+}
+
+.pr-20 {
+	padding-right: 20rpx;
+}
+
+.p-30 {
+	padding: 30rpx;
+}
+
+.p-10 {
+	padding: 10rpx;
+}

BIN
static/icon/goOrder.png


BIN
static/icon/home.png


+ 196 - 0
static/iconfont/iconfont.scss

@@ -0,0 +1,196 @@
+@font-face {
+  font-family: "iconfont";
+  src: url('//at.alicdn.com/t/font_1789197_z1gzlwq7idq.ttf?t=1589441233693') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.iconshoucang:before {
+  content: "\e667";
+}
+
+.iconshoucangfill:before {
+  content: "\e6c9";
+}
+
+.iconjifen:before {
+  content: "\e642";
+}
+
+.iconradio-button-off:before {
+  content: "\e688";
+}
+
+.iconradio-button-on:before {
+  content: "\e689";
+}
+
+.iconhelp:before {
+  content: "\e752";
+}
+
+.iconwxpay:before {
+  content: "\e611";
+}
+
+.iconbalance:before {
+  content: "\e619";
+}
+
+.iconadd-select:before {
+  content: "\e7b0";
+}
+
+.iconsami-select:before {
+  content: "\e7b1";
+}
+
+.iconmap:before {
+  content: "\e758";
+}
+
+.iconsuccess:before {
+  content: "\e767";
+}
+
+.iconsuccess-fill:before {
+  content: "\e78d";
+}
+
+.iconiconset0136:before {
+  content: "\e623";
+}
+
+.iconzan:before {
+  content: "\e640";
+}
+
+.iconjifenqiandao:before {
+  content: "\e6a6";
+}
+
+.iconshouyeshouye:before {
+  content: "\e606";
+}
+
+.icondaohang:before {
+  content: "\e641";
+}
+
+.iconwodelianxikefu:before {
+  content: "\e671";
+}
+
+.iconwodexinyuan:before {
+  content: "\e675";
+}
+
+.iconphone:before {
+  content: "\e6dd";
+}
+
+.icondingdan:before {
+  content: "\e645";
+}
+
+.iconliwu:before {
+  content: "\e61c";
+}
+
+.iconyinpinyinliao:before {
+  content: "\e60d";
+}
+
+.iconyinpin:before {
+  content: "\e70b";
+}
+
+.iconwaimaixinxi:before {
+  content: "\e685";
+}
+
+.iconico:before {
+  content: "\e646";
+}
+
+.iconwode:before {
+  content: "\e616";
+}
+
+.icongengduofuwu:before {
+  content: "\e607";
+}
+
+.iconqucan:before {
+  content: "\e625";
+}
+
+.iconyou:before {
+  content: "\e618";
+}
+
+.iconshouhuodizhi:before {
+  content: "\e666";
+}
+
+.iconshangcheng:before {
+  content: "\e63b";
+}
+
+.iconadd:before {
+  content: "\e742";
+}
+
+.iconarrow-right:before {
+  content: "\e743";
+}
+
+.iconarrow-lift:before {
+  content: "\e744";
+}
+
+.iconarrow-up:before {
+  content: "\e745";
+}
+
+.iconclose:before {
+  content: "\e747";
+}
+
+.iconleftbutton:before {
+  content: "\e755";
+}
+
+.iconreduce:before {
+  content: "\e75e";
+}
+
+.iconseleted:before {
+  content: "\e763";
+}
+
+.iconRightbutton:before {
+  content: "\e765";
+}
+
+.iconleftbutton-fill:before {
+  content: "\e782";
+}
+
+.iconRightbutton-fill:before {
+  content: "\e78a";
+}
+
+.iconarrow-down:before {
+  content: "\e7b2";
+}
+
+.iconaixin1:before {
+  content: "\e63c";
+}

+ 4 - 1
store/index.js

@@ -1,5 +1,6 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
+
 Vue.use(Vuex)
 
 let lifeData = {};
@@ -12,7 +13,7 @@ try{
 }
 
 // 需要永久存储,且下次APP启动需要取出的,在state中的变量名
-let saveStateKeys = ['vuex_audit','vuex_userId','vuex_phone'];
+let saveStateKeys = ['vuex_audit','vuex_userId','vuex_phone','vuex_orderInfo'];
 
 // 保存变量到本地存储中
 const saveLifeData = function(key, value){
@@ -41,6 +42,8 @@ const store = new Vuex.Store({
 		vuex_phone: lifeData.vuex_phone ? lifeData.vuex_phone : null,
 		//地址
 		vuex_location: lifeData.vuex_location ? lifeData.vuex_location : null,
+		//订单信息
+		vuex_orderInfo: lifeData.vuex_orderInfo ? lifeData.vuex_orderInfo : null,
 	},
 	mutations: {
 		$uStore(state, payload) {

+ 64 - 0
uni.scss

@@ -6,4 +6,68 @@ $uni-color-success: #4cd964;
 $uni-color-warning: #f0ad4e;
 $uni-color-error: #dd524d;
 
+/* 颜色变量 */
+/* 行为相关颜色 */
+$color-primary: #FF9447;
+$color-success: #4cd964;
+$color-warning: #FAB714;
+$color-error: #D12E32;
+
+/* 文字基本颜色 */
+$text-color-base: #5A5B5C; //基本色
+$text-color-assist: #919293; //辅助色
+$text-color-black: #3B3C3E; //黑
+$text-color-grey: #878889; //灰
+$text-color-white: #ffffff; //白
+
+/* 背景颜色 */
+$bg-color: #F1F8FA;
+$bg-color-grey: #F5F5F5;
+$bg-color-primary: #E8EACF;
+
+/* 边框颜色 */
+$border-color:#e2e2e2;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$font-size-sm:24rpx;
+$font-size-base:28rpx;
+$font-size-lg:32rpx;
+
+/* 图片尺寸 */
+$img-size-sm:40rpx;
+$img-size-base:52rpx;
+$img-size-lg:80rpx;
+
+/* Border Radius */
+$border-radius-sm: 4rpx;
+$border-radius-base: 6rpx;
+$border-radius-lg: 12rpx;
+$border-radius-circle: 50%;
+
+/* 水平间距 */
+$spacing-row-sm: 10px;
+$spacing-row-base: 20rpx;
+$spacing-row-lg: 30rpx;
+
+/* 垂直间距 */
+$spacing-col-sm: 8rpx;
+$spacing-col-base: 16rpx;
+$spacing-col-lg: 24rpx;
+
+/* 透明度 */
+$opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$color-title: #2C405A; // 文章标题颜色
+$font-size-title:40rpx;
+$color-subtitle: #555555; // 二级标题颜色
+$font-size-subtitle:36rpx;
+$color-paragraph: #3F536E; // 文章段落颜色
+$font-size-paragraph:30rpx;
+
+$box-shadow: 0 20rpx 20rpx -20rpx rgba($color: #333, $alpha: 0.1);
+
+@import '~@/static/iconfont/iconfont.scss';
 

+ 5 - 0
utils/dateTime.js

@@ -32,6 +32,11 @@ dateTime.format=(date= new Date(),fmt="YYYY-mm-dd HH:MM:SS")=> {
 dateTime.createDate = (value)=>{
   let date = typeof (value) == 'string' ? value.replace(/\-/g, '/') : value
   return new Date(date)
+}
+
+dateTime.getTime = (value)=>{
+  let date = typeof (value) == 'string' ? value.replace(/\-/g, '/') : value
+  return new Date(date).getTime()
 } 
 
 //默认五分钟

+ 13 - 0
utils/mpi.js

@@ -118,6 +118,19 @@ mpi.getLocation = () => {
 	})
 }
 
+mpi.chooseLocation = () => {
+	return new Promise((resolve, reject) => {
+		uni.chooseLocation({
+			success: function(res) {
+				resolve(res)
+			},
+			fail: function(err) {
+				reject(err)
+			}
+		});
+	})
+}
+
 mpi.getConnectedWifi = () => {
 	return new Promise((resolve, reject) => {
 		uni.startWifi({