19124812874 před 5 roky
revize
ac80566335
100 změnil soubory, kde provedl 31100 přidání a 0 odebrání
  1. 538 0
      App.vue
  2. 22 0
      assets/css/app.css
  3. 71 0
      assets/css/app.scss
  4. 36 0
      assets/css/icon.css
  5. 4124 0
      assets/css/main.css
  6. 367 0
      assets/js/DoormasterSDK-V1.4.js
  7. 123 0
      comps/dt_custom_bar.vue
  8. 157 0
      comps/dt_empty.vue
  9. 228 0
      comps/dt_goods_list_h.vue
  10. 250 0
      comps/dt_goods_list_home.vue
  11. 212 0
      comps/dt_goods_list_home02.vue
  12. 305 0
      comps/dt_login.vue
  13. 33 0
      comps/dt_service.vue
  14. 104 0
      comps/dt_unit_head_v2.vue
  15. 208 0
      comps/foot_dialog.vue
  16. 160 0
      comps/goods/goods.vue
  17. 95 0
      comps/grid/grid.vue
  18. 69 0
      comps/hot-consult/hot-consult.vue
  19. 46 0
      comps/loading/loaders/rotate-plane.vue
  20. 127 0
      comps/loading/loading.vue
  21. 30 0
      comps/mescroll-uni/mescroll-uni-option.js
  22. 223 0
      comps/mescroll-uni/mescroll-uni.css
  23. 747 0
      comps/mescroll-uni/mescroll-uni.js
  24. 306 0
      comps/mescroll-uni/mescroll-uni.vue
  25. 435 0
      comps/mosowe-swiper.vue
  26. 65 0
      comps/mp-time/date.js
  27. 379 0
      comps/mp-time/index.vue
  28. 114 0
      comps/scroll_menu.vue
  29. 69 0
      comps/uploadimg/uploadImg.vue
  30. 92 0
      main.js
  31. 919 0
      pages.json
  32. 228 0
      pages/auth/auth.vue
  33. 426 0
      pages/authorize_record/authorize_record.vue
  34. 524 0
      pages/authorize_record/openPass/openPass.vue
  35. 263 0
      pages/bluetooth/bluetooth.vue
  36. 296 0
      pages/choosePlot/choosePlot.vue
  37. 145 0
      pages/choosePlot/chooseRoom/chooseRoom.vue
  38. 150 0
      pages/choosePlot/chooseUnit/chooseUnit.vue
  39. 643 0
      pages/choosePlot/householdCert/householdCert.vue
  40. 486 0
      pages/community/community.vue
  41. 130 0
      pages/demo/demo1.vue
  42. 65 0
      pages/demo/demo2.vue
  43. 255 0
      pages/demo/demo4.vue
  44. 24 0
      pages/demo/demo5.vue
  45. 129 0
      pages/demo/demo6.vue
  46. 46 0
      pages/demo/myfamily.vue
  47. 257 0
      pages/device/device.vue
  48. 44 0
      pages/empty/empty.vue
  49. 30 0
      pages/empty/goauth.vue
  50. 22 0
      pages/guest/guest.vue
  51. 98 0
      pages/guest/open_door.vue
  52. 105 0
      pages/guide/guide.vue
  53. 126 0
      pages/guide/guide_old.vue
  54. 872 0
      pages/index/index.vue
  55. 1234 0
      pages/life/life.vue
  56. 1237 0
      pages/life/life1.vue
  57. 194 0
      pages/my-camera/my-camera.vue
  58. 214 0
      pages/myFamily/activateFace/activateFace.vue
  59. 637 0
      pages/myFamily/add/add.vue
  60. 693 0
      pages/myFamily/addFamily/addFamily.vue
  61. 837 0
      pages/myFamily/editApplyFamily/editApplyFamily.vue
  62. 670 0
      pages/myFamily/editFamily/editFamily.vue
  63. 833 0
      pages/myFamily/myFamily.vue
  64. 83 0
      pages/myPassword/myPassword.vue
  65. 204 0
      pages/myhome/familyList.vue
  66. 177 0
      pages/myhome/myhome.vue
  67. 50 0
      pages/notice/detail.vue
  68. 194 0
      pages/notice/notice.vue
  69. 164 0
      pages/oneButton/oneButton.vue
  70. 554 0
      pages/poster/poster.vue
  71. 160 0
      pages/record/record.vue
  72. 367 0
      pages/register/register.vue
  73. 148 0
      pages/services/delivery/delivery.vue
  74. 254 0
      pages/services/demand/detail.vue
  75. 142 0
      pages/services/demand/list.vue
  76. 108 0
      pages/services/demand/publish.vue
  77. 69 0
      pages/services/property/comment.vue
  78. 111 0
      pages/services/property/detail.vue
  79. 144 0
      pages/services/property/list/card.vue
  80. 160 0
      pages/services/property/list/item.vue
  81. 118 0
      pages/services/property/list/list.vue
  82. 338 0
      pages/services/property/property.vue
  83. 575 0
      pages/switchcity/switchcity.vue
  84. 114 0
      pages/tool-list/epidemic-pass/detail.vue
  85. 121 0
      pages/tool-list/epidemic-pass/epidemic-pass.vue
  86. 106 0
      pages/tool-list/tool-list.vue
  87. 432 0
      pages/uploadFace/uploadFace.vue
  88. 64 0
      pages/webview/webview.vue
  89. 84 0
      pages/wode/direction/direction.vue
  90. 266 0
      pages/wode/feedback/feedback.vue
  91. 131 0
      pages/wode/myInfo/myInfo.vue
  92. 125 0
      pages/wode/news/news.vue
  93. 55 0
      pages/wode/password/password.vue
  94. 805 0
      pages/wode/wode.vue
  95. 735 0
      pages/wode/wode2.vue
  96. 559 0
      pagesM/comps/canvas/index.vue
  97. 112 0
      pagesM/comps/canvas/poster.vue
  98. 68 0
      pagesM/comps/dt_accumulator.vue
  99. 312 0
      pagesM/comps/dt_category_goods_list.vue
  100. 324 0
      pagesM/comps/dt_category_goods_list_new.vue

+ 538 - 0
App.vue

@@ -0,0 +1,538 @@
+<script>
+	import StringUtil from '@/utils/StringUtil.js'
+	var md5 = require("./utils/md5.js");
+	export default {
+		data() {
+			return {
+				param: null
+			};
+		},
+		onLaunch: function(e) {
+			this.downloadGuideImg()
+			this.param = e;
+			this.execParam();
+			this.globalData.checkIsIPhoneX();
+		},
+		onShow: function(e) {
+			this.param = e;
+			this.execParam();
+		},
+		onHide: function() {
+			console.log('App Hide')
+		},
+		methods: {
+			/**
+			 * 进入小程序就下载引导图,防止进入引导页时加载图片时空白
+			 */
+			downloadGuideImg(){
+				let that=this
+				uni.downloadFile({
+				    url: 'http://139.9.103.171:1888/miniofile/app/guide.png', //仅为示例,并非真实的资源
+				    success: (res) => {
+						uni.saveFile({
+							 tempFilePath: res.tempFilePath,
+							 success: function (res) {
+							   var savedFilePath = res.savedFilePath;
+							   uni.setStorageSync("guideImg",savedFilePath)
+							 }
+						});
+				    }
+				});
+			},
+			execParam() {
+				if (this.param == null || this.param.referrerInfo == null) return;
+				let path = this.param.path;
+				if (StringUtil.startEqualsIgnoreCase(path, 'pages/pages/')) {
+					path = StringUtil.replace(path, 'pages/pages/', 'pages/');
+					if (StringUtil.eqlObjIgnoreCase(path, '/pagesM/pages/goods_des')) {
+						let query = this.param.query;
+						if (query == null || query.id == null || parseInt(query.id) == null || parseInt(query.id) <= 0) {
+							path = `pages/life`;
+						} else {
+							path = `pages/life?type=share&id=${query.id}&path=${path}`;
+						}
+					}
+					this.param.path = path;
+					uni.reLaunch({ url: path });
+					return;
+				}
+				this.param.path = path;
+				let reqParam = this.param.referrerInfo.extraData;
+				wx.setStorageSync('reqParam', reqParam);
+				this.param.referrerInfo = null;
+			}
+		},
+		globalData: {
+			//机构id
+			org_id: "1",
+			token: "j2qctr89u1xfmbjkp69hegfmqhwquycw",
+			//对接后台的api地址
+			//远程的
+			apiurl: "http://139.9.103.171:9082/app/",
+			//德系本地的
+			// apiurl: "http://192.168.2.162:9082/app/",
+			member: null,
+			//用户信息--后台
+			userInfo: null,
+			//小程序用户信息,
+			room_list: null,
+			//会员的房屋列表 
+			own_room_list: null,
+			//业主身份的房子
+			device_list: null,
+			//会员的授权设备列表
+			anyHousePass: false, //判断是否是第二次认证,
+			//封装request请求
+			/**
+			 * params 参数
+			 * operation 操作
+			 * callBack 回调函数
+			 */
+			postRequest: function (params, operation, callBack) {
+			  let that = this; //公共参数
+			  params['org_id'] = that.org_id;
+			  params['token'] = that.token; 
+			  uni.showLoading({
+			    mask: true
+			  }); //Object转json
+			
+			  let jsonStr = JSON.stringify(params); //数据md5签名
+			
+			  let dataSign = md5.hex_md5(jsonStr);
+			  uni.request({
+			    url: that.apiurl + operation,
+			    method: 'POST',
+			    header: {
+			      'content-type': 'application/json',
+			      'data-sign': dataSign
+			    },
+			    data: jsonStr,
+			    success: function (res) {
+			      // console.info(res.header['data-sign']);
+			      // console.info(md5.hex_md5(JSON.stringify(res.data)));
+			      uni.hideLoading(); //回调函数
+			
+			      callBack(res);
+			    },
+			    fail: function (res) {
+			      uni.hideLoading();
+			      uni.showModal({
+			        title: '警告',
+			        content: '网络异常' + res.errMsg,
+			        showCancel: false,
+			        confirmText: '确认'
+			      });
+			    }
+			  });
+			},
+			//上传文件
+			uploadBase64: function (base_64_str, is_need_md5, callback) {
+			  let that = this;
+			  let params = {};
+			  params['base_64_str'] = base_64_str;
+			  params['is_need_md5'] = is_need_md5; //公共参数
+			
+			  params['org_id'] = that.org_id;
+			  params['token'] = that.token;
+			  let operation = 'applyUser/uploadBase64File';
+			  that.postRequest(params, operation, function (res) {
+			    if (res.data.result_code == 1) {
+			      callback(res);
+			    } else {
+			      that.autoFailHint(res.data.result_msg);
+			    }
+			  });
+			},
+			
+			/**
+			 * 失败提示方法方法--单按钮--手动点击关闭
+			 */
+			oneFailHint: function (result_msg, callBack) {
+			  uni.showModal({
+			    content: result_msg,
+			    showCancel: false,
+			    confirmText: '确认',
+			    success: function (res) {
+			      if (res.confirm) {
+			        if (callBack) {
+			          callBack();
+			        }
+			      }
+			    }
+			  });
+			},
+			
+			/**
+			 * 失败提示方法方法--双按钮--手动点击关闭
+			 */
+			twoFailHint: function (result_msg, callBack) {
+			  uni.showModal({
+			    content: result_msg,
+			    confirmText: '确认',
+			    success: function (res) {
+			      if (res.confirm) {
+			        if (callBack) {
+			          callBack();
+			        }
+			      }
+			    }
+			  });
+			},
+			
+			/**
+			  * 失败提示方法方法--自动关闭
+			  */
+			autoFailHint: function (result_msg, callBack) {
+			  uni.showToast({
+			    title: result_msg,
+			    icon: 'none',
+			    duration: 2000,
+			    success: function () {
+			      if (callBack) {
+			        callBack();
+			      }
+			    }
+			  });
+			},
+			
+			/**
+			* 提示用户身份注册
+			*/
+			footaddmore: function () {
+			  uni.showModal({
+			    title: '提示',
+			    content: ' 请先完成注册',
+			    //cancelText:'去绑定',
+			    cancelText: '取消',
+			    confirmText: '去注册',
+			    success: function (res) {
+			      if (res.confirm) {
+			        //跳转到认证页面
+			        uni.navigateTo({
+			        	url:"/pages/register/register"
+			        })
+			      } else {//res.cancel
+			        //绑定界面--暂时不用
+			        // wx.navigateTo({
+			        //   url: '/pages/binding/binding',
+			        // })
+			      }
+			    }
+			  });
+			},
+			//房屋信息完善
+			choosePlot: function () {
+			  uni.showModal({
+			    title: '提示',
+			    content: ' 未获取到房屋信息,是否去完善',
+			    //cancelText:'去绑定',
+			    cancelText: '取消',
+			    confirmText: '去完善',
+			    success: function (res) {
+			      if (res.confirm) {
+			        console.log('用户点击了确认-去完善'); //跳转到认证页面
+					if(!this.$isEmpty(this.globalData.totalStep)){
+						this.globalData.totalStep=2
+					}
+			        uni.navigateTo({
+			          url: "/pages/auth/auth"
+			        });
+			      }
+			    }
+			  });
+			},
+			//检测是否是iphonex以上的机型
+			checkIsIPhoneX: function () {
+			  const self = this;
+			  uni.getSystemInfo({
+			    success: function (res) {
+			      // 根据 model 进行判断
+			      if (res.model.search('iPhone X') != -1) {
+			        //self.isIPX = true
+			        uni.setStorageSync("isIPX", true);
+			      } else {
+			        uni.setStorageSync("isIPX", false);
+			      }
+			    }
+			  });
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	// 引入样式
+	@import  '@/assets/css/app.scss';
+	@import "uview-ui/index.scss";
+	@import "@/assets/css/main.css";
+	@import "@/assets/css/icon.css";
+	@import "@/assets/css/app.css";
+	
+	
+	// 社区样式 begin
+	navigator-hover {
+	  background-color: rgba(0, 0, 0, 0.1);
+	  opacity: 0.7;
+	}
+	
+	input {
+	  font-family: "PingFang SC",
+	                 "Hiragino Sans GB",
+	                 "Heiti SC",
+	                 "Microsoft YaHei",
+	                 "WenQuanYi Micro Hei",
+	                 sans-serif;
+	}
+	
+	.fix_nav_wp-IPX {
+	padding-bottom:68rpx;
+	
+	}
+	
+	.mt20 {
+	  margin-top: 20rpx;
+	}
+	
+	.submit_btn {
+	  position: fixed;
+	  bottom: 0;
+	  left: 0;
+	  padding: 0rpx 0rpx;
+	  width: 100%;
+	  box-sizing: border-box;
+	  background: #fff;
+	}
+	
+	.ar_btn {
+	  background: $base-btn-color;
+	  font-size: 32rpx;
+	  color: #fff;
+	  // border-radius: 10rpx;
+	  margin: 0rpx 0rpx;
+	  padding: 0rpx 60rpx;
+	  height: 100rpx;
+	  line-height: 100rpx;
+	}
+	/* 小图标 */
+	@font-face {
+	  font-family: 'iconfont';  /* project id 930679 */
+	  src: url('//at.alicdn.com/t/font_930679_y7aw8dju2ha.eot');
+	  src: url('//at.alicdn.com/t/font_930679_y7aw8dju2ha.eot?#iefix') format('embedded-opentype'),
+	  url('//at.alicdn.com/t/font_930679_y7aw8dju2ha.woff') format('woff'),
+	  url('//at.alicdn.com/t/font_930679_y7aw8dju2ha.ttf') format('truetype'),
+	  url('//at.alicdn.com/t/font_930679_y7aw8dju2ha.svg#iconfont') format('svg');
+	}
+	
+	.iconfont {
+	  font-family: "iconfont" !important;
+	  font-size: 16px;
+	  font-style: normal;
+	  -webkit-font-smoothing: antialiased;
+	  -moz-osx-font-smoothing: grayscale;
+	}
+	.icon-lianxigray:before { content: "\e61b"; }
+	
+	.icon-dispirited:before { content: "\e650"; }
+	
+	.icon-cha:before { content: "\e601"; }
+	
+	.icon-arrow-left:before { content: "\e604"; }
+	
+	.icon-mima:before { content: "\e603"; }
+	
+	.icon-xiaoxi:before { content: "\e633"; }
+	
+	.icon-shuoming:before { content: "\e605"; }
+	
+	.icon-icon-test:before { content: "\e626"; }
+	
+	.icon-shiming:before { content: "\e6d4"; }
+	
+	.icon-dingwei:before { content: "\e822"; }
+	
+	.icon-yemian:before { content: "\e659"; }
+	
+	.icon-icon-test1:before { content: "\e600"; }
+	
+	.icon-user:before { content: "\e602"; }
+	
+	.flex {
+	  display: -webkit-flex;
+	  display: flex;
+	  width: 100%;
+	}
+	
+	/*  底部悬浮导航  */
+	
+	.fix_nav_wp {
+	  margin-top: 110rpx;
+	  height: 110rpx;
+	  position: fixed;
+	  left: 0;
+	  bottom: 0;
+	  background: #fff;
+	  z-index: 10;
+	}
+	
+	.fix_nav_wp .nav_link {
+	  flex: 1;
+	}
+	
+	.fix_nav_wp button {
+	  height: 110rpx;
+	  display: flex;
+	  justify-content: space-between;
+	  align-items: center;
+	  padding: 0;
+	  font-size: 22rpx;
+	  flex-direction: column;
+	  color: #999;
+	  position: relative;
+	}
+	
+	.fix_nav_wp .tip_tip {
+	  position: absolute;
+	  right: 25rpx;
+	  top: 5rpx;
+	  min-width: 28rpx;
+	  line-height: 32rpx;
+	  height: 32rpx;
+	  padding: 0 8rpx;
+	  color: #fff;
+	  background: #f00;
+	  border-radius: 50em;
+	  border: 1rpx solid #fff;
+	}
+	
+	.fix_nav_wp .nav_link .iconfont {
+	  height: 60rpx;
+	  font-size: 48rpx;
+	  line-height: 80rpx;
+	  color: #c4c8cc;
+	}
+	
+	.fix_nav_wp .nav_link .plus_wp {
+	  width: 120rpx;
+	  height: 120rpx;
+	  margin-top: -60rpx;
+	}
+	
+	.fix_nav_wp .nav_link  image {
+	  width: 120rpx;
+	  height: 120rpx;
+	}
+	
+	.fix_nav_wp .nav_link .txt {
+	  height: 70rpx;
+	  line-height: 60rpx;
+	  color: #444;
+	  font-size: 28rpx;
+	}
+	
+	.fix_nav_wp .nav_link .iconfont {
+	  color: #444;
+	}
+	
+	
+	
+	.fix_nav_wp .nav_link .del_ico {
+	  display: block;
+	}
+	
+	.fix_nav_wp .nav_link .cur_ico {
+	  display: none;
+	}
+	
+	.fix_nav_wp .nav_link.current .del_ico {
+	  display: none;
+	}
+	
+	.fix_nav_wp .nav_link.current .cur_ico {
+	  display: block;
+	  color: $base-btn-color;
+	}
+	
+	.fix_nav_wp .nav_link .txt_fb {
+	  line-height: 60rpx;
+	}
+	
+	.fix_nav_wp .nav_link .mp_ico {
+	  font-size: 50rpx;
+	  line-height: 80rpx;
+	}
+	
+	.fix_nav_wp .nav_link .xiaox_ico {
+	  font-size: 64rpx;
+	  line-height: 70rpx;
+	}
+	
+	.fix_nav_wp .nav_link .my_ico {
+	  font-size: 56rpx;
+	}
+	
+	.fix_nav_wp .on_cor .del_ico, .fix_nav_wp .on_cor .txt {
+	  color: $base-btn-color;
+	}
+	
+	/* 清楚按钮的默认样式  */
+	
+	.defalut_btn {
+	  background: transparent;
+	  border: none;
+	  overflow: visible;
+	  padding-left: 0;
+	  padding-right: 0;
+	  margin-left: 0;
+	  margin-right: 0;
+	  border-radius: 0;
+	}
+	
+	.defalut_btn:after {
+	  display: none;
+	}
+	
+	.text-primary {
+	  color: $base-btn-color;
+	}
+	
+	.submit_btn1 {
+	  margin: 60rpx 0 20rpx;
+	  padding: 0rpx 80rpx;
+	  width: 100%;
+	  box-sizing: border-box;
+	}
+	//社区样式 end
+	
+	// 商城
+	::-webkit-scrollbar {
+		display: none;
+		width: 0 !important;
+		height: 0 !important;
+		-webkit-appearance: none;
+		background: transparent;
+	}
+	
+	.pageBg {
+		background: #f2f2f2;
+		height: auto;
+		min-height: 100vh;
+	}
+	.one_line_ellipsis {
+		display: -webkit-box;
+		overflow: hidden;
+		-webkit-line-clamp: 1;
+		-webkit-box-orient: vertical;
+	}
+	.two_line_ellipsis {
+		display: -webkit-box;
+		overflow: hidden;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+	.three_line_ellipsis {
+		display: -webkit-box;
+		overflow: hidden;
+		-webkit-line-clamp: 3;
+		-webkit-box-orient: vertical;
+	}
+</style>

+ 22 - 0
assets/css/app.css

@@ -0,0 +1,22 @@
+.base-color{
+	color: #2f7ff5;
+}
+.base-bg-color{
+	color: #FFFFFF;
+	background-color: #2f7ff5;
+}
+.text-red-btn{
+	color: #2f7ff5;
+}
+.bg-red-btn{
+	color: #FFFFFF;
+	background-color: #2f7ff5;
+}
+
+
+.line-btn{color: #2f7ff5;}
+
+.bg-btn{
+	color: #FFFFFF;
+	background-color: #2f7ff5;
+}

+ 71 - 0
assets/css/app.scss

@@ -0,0 +1,71 @@
+.dt-page {
+  position: relative;
+  font-size: $dt-font-size-base;
+  font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;
+  background: $dt-bg-color-grey;
+  color: $dt-text-color;
+}
+
+.dt-color-primary {
+  color: $dt-color-primary;
+}
+
+.dt-color-success {
+  color: $dt-color-success;
+}
+
+.dt-color-warning {
+  color: $dt-color-warning;
+}
+
+.dt-color-error {
+  color: $dt-color-error;
+}
+
+.dt-text-row-one {
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 1;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.dt-text-row-two {
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 2;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+button {
+  padding: 0;
+  text-align: center;
+  border-color: $dt-color-primary;
+  color: #fff;  
+  font-size: 32upx;
+  background-color:transparent;
+}
+
+button:after {
+  display: none;
+  content: '';
+}
+.button-hover{
+  color:#ccc;
+  background-color:#f8f8f8;
+}
+.button-hover-scale{
+  transform: scale(0.98);
+  color:#ccc;
+}
+input,textarea{
+  font-size:$dt-font-size-base;
+}
+.input-placeholder,
+.textarea-placeholder{
+  color: $dt-text-color-placeholder;
+}
+.bg-linear-gradient{
+	background:linear-gradient(90deg,rgba(110,160,234,1) 0%,rgba(55,120,248,1) 100%);
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 36 - 0
assets/css/icon.css


+ 4124 - 0
assets/css/main.css

@@ -0,0 +1,4124 @@
+/* ==================
+        初始化
+ ==================== */
+body {
+	background-color: #f1f1f1;
+	font-size: 28upx;
+	color: #333333;
+	font-family: Helvetica Neue, Helvetica, sans-serif;
+}
+
+/* view,
+scroll-view,
+swiper,
+button,
+input,
+textarea,
+label,
+navigator,
+image {
+	box-sizing: border-box;
+} */
+
+.round {
+	border-radius: 5000upx;
+}
+
+.radius {
+	border-radius: 6upx;
+}
+
+/* ==================
+          图片
+ ==================== */
+
+/* image {
+	max-width: 100%;
+	display: inline-block;
+	position: relative;
+	z-index: 0;
+} */
+
+image.loading::before {
+	content: "";
+	background-color: #f5f5f5;
+	display: block;
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	z-index: -2;
+}
+
+image.loading::after {
+	content: "\e7f1";
+	font-family: "cuIcon";
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 32upx;
+	height: 32upx;
+	line-height: 32upx;
+	right: 0;
+	bottom: 0;
+	z-index: -1;
+	font-size: 32upx;
+	margin: auto;
+	color: #ccc;
+	-webkit-animation: cuIcon-spin 2s infinite linear;
+	animation: cuIcon-spin 2s infinite linear;
+	display: block;
+}
+
+.response {
+	width: 100%;
+}
+
+/* ==================
+         开关
+ ==================== */
+
+switch,
+checkbox,
+radio {
+	position: relative;
+}
+
+switch::after,
+switch::before {
+	font-family: "cuIcon";
+	content: "\e645";
+	position: absolute;
+	color: #ffffff !important;
+	top: 0%;
+	left: 0upx;
+	font-size: 26upx;
+	line-height: 26px;
+	width: 50%;
+	text-align: center;
+	pointer-events: none;
+	transform: scale(0, 0);
+	transition: all 0.3s ease-in-out 0s;
+	z-index: 9;
+	bottom: 0;
+	height: 26px;
+	margin: auto;
+}
+
+switch::before {
+	content: "\e646";
+	right: 0;
+	transform: scale(1, 1);
+	left: auto;
+}
+
+switch[checked]::after,
+switch.checked::after {
+	transform: scale(1, 1);
+}
+
+switch[checked]::before,
+switch.checked::before {
+	transform: scale(0, 0);
+}
+
+/* #ifndef MP-ALIPAY */
+radio::before,
+checkbox::before {
+	font-family: "cuIcon";
+	content: "\e645";
+	position: absolute;
+	color: #ffffff !important;
+	top: 50%;
+	margin-top: -8px;
+	right: 5px;
+	font-size: 32upx;
+	line-height: 16px;
+	pointer-events: none;
+	transform: scale(1, 1);
+	transition: all 0.3s ease-in-out 0s;
+	z-index: 9;
+}
+
+radio .wx-radio-input,
+checkbox .wx-checkbox-input,
+radio .uni-radio-input,
+checkbox .uni-checkbox-input {
+	margin: 0;
+	width: 24px;
+	height: 24px;
+}
+
+checkbox.round .wx-checkbox-input,
+checkbox.round .uni-checkbox-input {
+	border-radius: 100upx;
+}
+
+/* #endif */
+
+switch[checked]::before {
+	transform: scale(0, 0);
+}
+
+switch .wx-switch-input,
+switch .uni-switch-input {
+	border: none;
+	padding: 0 24px;
+	width: 48px;
+	height: 26px;
+	margin: 0;
+	border-radius: 100upx;
+}
+
+switch .wx-switch-input:not([class*="bg-"]),
+switch .uni-switch-input:not([class*="bg-"]) {
+	background: #8799a3 !important;
+}
+
+switch .wx-switch-input::after,
+switch .uni-switch-input::after {
+	margin: auto;
+	width: 26px;
+	height: 26px;
+	border-radius: 100upx;
+	left: 0upx;
+	top: 0upx;
+	bottom: 0upx;
+	position: absolute;
+	transform: scale(0.9, 0.9);
+	transition: all 0.1s ease-in-out 0s;
+}
+
+switch .wx-switch-input.wx-switch-input-checked::after,
+switch .uni-switch-input.uni-switch-input-checked::after {
+	margin: auto;
+	left: 22px;
+	box-shadow: none;
+	transform: scale(0.9, 0.9);
+}
+
+radio-group {
+	display: inline-block;
+}
+
+
+
+switch.radius .wx-switch-input::after,
+switch.radius .wx-switch-input,
+switch.radius .wx-switch-input::before,
+switch.radius .uni-switch-input::after,
+switch.radius .uni-switch-input,
+switch.radius .uni-switch-input::before {
+	border-radius: 10upx;
+}
+
+switch .wx-switch-input::before,
+radio.radio::before,
+checkbox .wx-checkbox-input::before,
+radio .wx-radio-input::before,
+switch .uni-switch-input::before,
+radio.radio::before,
+checkbox .uni-checkbox-input::before,
+radio .uni-radio-input::before {
+	display: none;
+}
+
+radio.radio[checked]::after,
+radio.radio .uni-radio-input-checked::after {
+	content: "";
+	background-color: transparent;
+	display: block;
+	position: absolute;
+	width: 8px;
+	height: 8px;
+	z-index: 999;
+	top: 0upx;
+	left: 0upx;
+	right: 0;
+	bottom: 0;
+	margin: auto;
+	border-radius: 200upx;
+	/* #ifndef MP */
+	border: 7px solid #ffffff !important;
+	/* #endif */
+
+	/* #ifdef MP */
+	border: 8px solid #ffffff !important;
+	/* #endif */
+}
+
+.switch-sex::after {
+	content: "\e71c";
+}
+
+.switch-sex::before {
+	content: "\e71a";
+}
+
+.switch-sex .wx-switch-input,
+.switch-sex .uni-switch-input {
+	background: #e54d42 !important;
+	border-color: #e54d42 !important;
+}
+
+.switch-sex[checked] .wx-switch-input,
+.switch-sex.checked .uni-switch-input {
+	background: #0081ff !important;
+	border-color: #0081ff !important;
+}
+
+switch.red[checked] .wx-switch-input.wx-switch-input-checked,
+checkbox.red[checked] .wx-checkbox-input,
+radio.red[checked] .wx-radio-input,
+switch.red.checked .uni-switch-input.uni-switch-input-checked,
+checkbox.red.checked .uni-checkbox-input,
+radio.red.checked .uni-radio-input {
+	background-color: #e54d42 !important;
+	border-color: #e54d42 !important;
+	color: #ffffff !important;
+}
+
+switch.orange[checked] .wx-switch-input,
+checkbox.orange[checked] .wx-checkbox-input,
+radio.orange[checked] .wx-radio-input,
+switch.orange.checked .uni-switch-input,
+checkbox.orange.checked .uni-checkbox-input,
+radio.orange.checked .uni-radio-input {
+	background-color: #f37b1d !important;
+	border-color: #f37b1d !important;
+	color: #ffffff !important;
+}
+
+switch.yellow[checked] .wx-switch-input,
+checkbox.yellow[checked] .wx-checkbox-input,
+radio.yellow[checked] .wx-radio-input,
+switch.yellow.checked .uni-switch-input,
+checkbox.yellow.checked .uni-checkbox-input,
+radio.yellow.checked .uni-radio-input {
+	background-color: #fbbd08 !important;
+	border-color: #fbbd08 !important;
+	color: #333333 !important;
+}
+
+switch.olive[checked] .wx-switch-input,
+checkbox.olive[checked] .wx-checkbox-input,
+radio.olive[checked] .wx-radio-input,
+switch.olive.checked .uni-switch-input,
+checkbox.olive.checked .uni-checkbox-input,
+radio.olive.checked .uni-radio-input {
+	background-color: #8dc63f !important;
+	border-color: #8dc63f !important;
+	color: #ffffff !important;
+}
+
+switch.green[checked] .wx-switch-input,
+switch[checked] .wx-switch-input,
+checkbox.green[checked] .wx-checkbox-input,
+checkbox[checked] .wx-checkbox-input,
+radio.green[checked] .wx-radio-input,
+radio[checked] .wx-radio-input,
+switch.green.checked .uni-switch-input,
+switch.checked .uni-switch-input,
+checkbox.green.checked .uni-checkbox-input,
+checkbox.checked .uni-checkbox-input,
+radio.green.checked .uni-radio-input,
+radio.checked .uni-radio-input {
+	background-color: #39b54a !important;
+	border-color: #39b54a !important;
+	color: #ffffff !important;
+	border-color: #39B54A !important;
+}
+
+switch.cyan[checked] .wx-switch-input,
+checkbox.cyan[checked] .wx-checkbox-input,
+radio.cyan[checked] .wx-radio-input,
+switch.cyan.checked .uni-switch-input,
+checkbox.cyan.checked .uni-checkbox-input,
+radio.cyan.checked .uni-radio-input {
+	background-color: #1cbbb4 !important;
+	border-color: #1cbbb4 !important;
+	color: #ffffff !important;
+}
+
+switch.blue[checked] .wx-switch-input,
+checkbox.blue[checked] .wx-checkbox-input,
+radio.blue[checked] .wx-radio-input,
+switch.blue.checked .uni-switch-input,
+checkbox.blue.checked .uni-checkbox-input,
+radio.blue.checked .uni-radio-input {
+	background-color: #0081ff !important;
+	border-color: #0081ff !important;
+	color: #ffffff !important;
+}
+
+switch.purple[checked] .wx-switch-input,
+checkbox.purple[checked] .wx-checkbox-input,
+radio.purple[checked] .wx-radio-input,
+switch.purple.checked .uni-switch-input,
+checkbox.purple.checked .uni-checkbox-input,
+radio.purple.checked .uni-radio-input {
+	background-color: #6739b6 !important;
+	border-color: #6739b6 !important;
+	color: #ffffff !important;
+}
+
+switch.mauve[checked] .wx-switch-input,
+checkbox.mauve[checked] .wx-checkbox-input,
+radio.mauve[checked] .wx-radio-input,
+switch.mauve.checked .uni-switch-input,
+checkbox.mauve.checked .uni-checkbox-input,
+radio.mauve.checked .uni-radio-input {
+	background-color: #9c26b0 !important;
+	border-color: #9c26b0 !important;
+	color: #ffffff !important;
+}
+
+switch.pink[checked] .wx-switch-input,
+checkbox.pink[checked] .wx-checkbox-input,
+radio.pink[checked] .wx-radio-input,
+switch.pink.checked .uni-switch-input,
+checkbox.pink.checked .uni-checkbox-input,
+radio.pink.checked .uni-radio-input {
+	background-color: #e03997 !important;
+	border-color: #e03997 !important;
+	color: #ffffff !important;
+}
+
+switch.brown[checked] .wx-switch-input,
+checkbox.brown[checked] .wx-checkbox-input,
+radio.brown[checked] .wx-radio-input,
+switch.brown.checked .uni-switch-input,
+checkbox.brown.checked .uni-checkbox-input,
+radio.brown.checked .uni-radio-input {
+	background-color: #a5673f !important;
+	border-color: #a5673f !important;
+	color: #ffffff !important;
+}
+
+switch.grey[checked] .wx-switch-input,
+checkbox.grey[checked] .wx-checkbox-input,
+radio.grey[checked] .wx-radio-input,
+switch.grey.checked .uni-switch-input,
+checkbox.grey.checked .uni-checkbox-input,
+radio.grey.checked .uni-radio-input {
+	background-color: #8799a3 !important;
+	border-color: #8799a3 !important;
+	color: #ffffff !important;
+}
+
+switch.gray[checked] .wx-switch-input,
+checkbox.gray[checked] .wx-checkbox-input,
+radio.gray[checked] .wx-radio-input,
+switch.gray.checked .uni-switch-input,
+checkbox.gray.checked .uni-checkbox-input,
+radio.gray.checked .uni-radio-input {
+	background-color: #f0f0f0 !important;
+	border-color: #f0f0f0 !important;
+	color: #333333 !important;
+}
+
+switch.black[checked] .wx-switch-input,
+checkbox.black[checked] .wx-checkbox-input,
+radio.black[checked] .wx-radio-input,
+switch.black.checked .uni-switch-input,
+checkbox.black.checked .uni-checkbox-input,
+radio.black.checked .uni-radio-input {
+	background-color: #333333 !important;
+	border-color: #333333 !important;
+	color: #ffffff !important;
+}
+
+switch.white[checked] .wx-switch-input,
+checkbox.white[checked] .wx-checkbox-input,
+radio.white[checked] .wx-radio-input,
+switch.white.checked .uni-switch-input,
+checkbox.white.checked .uni-checkbox-input,
+radio.white.checked .uni-radio-input {
+	background-color: #ffffff !important;
+	border-color: #ffffff !important;
+	color: #333333 !important;
+}
+
+/* ==================
+          边框
+ ==================== */
+
+/* -- 实线 -- */
+
+.solid,
+.solid-top,
+.solid-right,
+.solid-bottom,
+.solid-left,
+.solids,
+.solids-top,
+.solids-right,
+.solids-bottom,
+.solids-left,
+.dashed,
+.dashed-top,
+.dashed-right,
+.dashed-bottom,
+.dashed-left {
+	position: relative;
+}
+
+.solid::after,
+.solid-top::after,
+.solid-right::after,
+.solid-bottom::after,
+.solid-left::after,
+.solids::after,
+.solids-top::after,
+.solids-right::after,
+.solids-bottom::after,
+.solids-left::after,
+.dashed::after,
+.dashed-top::after,
+.dashed-right::after,
+.dashed-bottom::after,
+.dashed-left::after {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border-radius: inherit;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	pointer-events: none;
+	box-sizing: border-box;
+}
+
+.solid::after {
+	border: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-top::after {
+	border-top: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-right::after {
+	border-right: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-bottom::after {
+	border-bottom: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solid-left::after {
+	border-left: 1upx solid rgba(0, 0, 0, 0.1);
+}
+
+.solids::after {
+	border: 8upx solid #eee;
+}
+
+.solids-top::after {
+	border-top: 8upx solid #eee;
+}
+
+.solids-right::after {
+	border-right: 8upx solid #eee;
+}
+
+.solids-bottom::after {
+	border-bottom: 8upx solid #eee;
+}
+
+.solids-left::after {
+	border-left: 8upx solid #eee;
+}
+
+/* -- 虚线 -- */
+
+.dashed::after {
+	border: 1upx dashed #ddd;
+}
+
+.dashed-top::after {
+	border-top: 1upx dashed #ddd;
+}
+
+.dashed-right::after {
+	border-right: 1upx dashed #ddd;
+}
+
+.dashed-bottom::after {
+	border-bottom: 1upx dashed #ddd;
+}
+
+.dashed-left::after {
+	border-left: 1upx dashed #ddd;
+}
+
+/* -- 阴影 -- */
+
+.shadow[class*='white'] {
+	--ShadowSize: 0 1upx 6upx;
+}
+
+.shadow-lg {
+	--ShadowSize: 0upx 40upx 100upx 0upx;
+}
+
+.shadow-warp {
+	position: relative;
+	box-shadow: 0 0 10upx rgba(0, 0, 0, 0.1);
+}
+
+.shadow-warp:before,
+.shadow-warp:after {
+	position: absolute;
+	content: "";
+	top: 20upx;
+	bottom: 30upx;
+	left: 20upx;
+	width: 50%;
+	box-shadow: 0 30upx 20upx rgba(0, 0, 0, 0.2);
+	transform: rotate(-3deg);
+	z-index: -1;
+}
+
+.shadow-warp:after {
+	right: 20upx;
+	left: auto;
+	transform: rotate(3deg);
+}
+
+.shadow-blur {
+	position: relative;
+}
+
+.shadow-blur::before {
+	content: "";
+	display: block;
+	background: inherit;
+	filter: blur(10upx);
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	top: 10upx;
+	left: 10upx;
+	z-index: -1;
+	opacity: 0.4;
+	transform-origin: 0 0;
+	border-radius: inherit;
+	transform: scale(1, 1);
+}
+
+/* ==================
+          按钮
+ ==================== */
+
+.cu-btn {
+	position: relative;
+	border: 0upx;
+	display: inline-flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+	padding: 0 30upx;
+	font-size: 28upx;
+	height: 64upx;
+	line-height: 1;
+	text-align: center;
+	text-decoration: none;
+	overflow: visible;
+	margin-left: initial;
+	transform: translate(0upx, 0upx);
+	margin-right: initial;
+}
+
+.cu-btn::after {
+	display: none;
+}
+
+.cu-btn:not([class*="bg-"]) {
+	background-color: #f0f0f0;
+}
+
+.cu-btn[class*="line"] {
+	background-color: transparent;
+}
+
+.cu-btn[class*="line"]::after {
+	content: " ";
+	display: block;
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border: 1upx solid currentColor;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	box-sizing: border-box;
+	border-radius: 12upx;
+	z-index: 1;
+	pointer-events: none;
+}
+
+.cu-btn.round[class*="line"]::after {
+	border-radius: 1000upx;
+}
+
+.cu-btn[class*="lines"]::after {
+	border: 6upx solid currentColor;
+}
+
+.cu-btn[class*="bg-"]::after {
+	display: none;
+}
+
+.cu-btn.sm {
+	padding: 0 20upx;
+	font-size: 20upx;
+	height: 48upx;
+}
+
+.cu-btn.df {
+	padding: 0 24upx;
+	font-size: 24upx;
+	height: 52upx;
+}
+
+.cu-btn.lg {
+	padding: 0 40upx;
+	font-size: 32upx;
+	height: 80upx;
+}
+
+.cu-btn.cuIcon.sm {
+	width: 48upx;
+	height: 48upx;
+}
+
+.cu-btn.cuIcon {
+	width: 64upx;
+	height: 64upx;
+	border-radius: 500upx;
+	padding: 0;
+}
+
+button.cuIcon.lg {
+	width: 80upx;
+	height: 80upx;
+}
+
+.cu-btn.shadow-blur::before {
+	top: 4upx;
+	left: 4upx;
+	filter: blur(6upx);
+	opacity: 0.6;
+}
+
+.cu-btn.button-hover {
+	transform: translate(1upx, 1upx);
+}
+
+.block {
+	display: block;
+}
+
+.cu-btn.block {
+	display: flex;
+}
+
+.cu-btn[disabled] {
+	opacity: 0.6;
+	color: #ffffff;
+}
+
+/* ==================
+          徽章
+ ==================== */
+
+.cu-tag {
+	font-size: 24upx;
+	vertical-align: middle;
+	position: relative;
+	display: inline-flex;
+	align-items: center;
+	justify-content: center;
+	box-sizing: border-box;
+	padding: 0upx 16upx;
+	height: 48upx;
+	font-family: Helvetica Neue, Helvetica, sans-serif;
+	white-space: nowrap;
+}
+
+.cu-tag:not([class*="bg"]):not([class*="line"]) {
+	background-color: #f1f1f1;
+}
+
+.cu-tag[class*="line-"]::after {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border: 1upx solid currentColor;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	box-sizing: border-box;
+	border-radius: inherit;
+	z-index: 1;
+	pointer-events: none;
+}
+
+.cu-tag.radius[class*="line"]::after {
+	border-radius: 12upx;
+}
+
+.cu-tag.round[class*="line"]::after {
+	border-radius: 1000upx;
+}
+
+.cu-tag[class*="line-"]::after {
+	border-radius: 0;
+}
+
+.cu-tag+.cu-tag {
+	margin-left: 10upx;
+}
+
+.cu-tag.sm {
+	font-size: 20upx;
+	padding: 0upx 12upx;
+	height: 32upx;
+}
+
+.cu-capsule {
+	display: inline-flex;
+	vertical-align: middle;
+}
+
+.cu-capsule+.cu-capsule {
+	margin-left: 10upx;
+}
+
+.cu-capsule .cu-tag {
+	margin: 0;
+}
+
+.cu-capsule .cu-tag[class*="line-"]:last-child::after {
+	border-left: 0upx solid transparent;
+}
+
+.cu-capsule .cu-tag[class*="line-"]:first-child::after {
+	border-right: 0upx solid transparent;
+}
+
+.cu-capsule.radius .cu-tag:first-child {
+	border-top-left-radius: 6upx;
+	border-bottom-left-radius: 6upx;
+}
+
+.cu-capsule.radius .cu-tag:last-child::after,
+.cu-capsule.radius .cu-tag[class*="line-"] {
+	border-top-right-radius: 12upx;
+	border-bottom-right-radius: 12upx;
+}
+
+.cu-capsule.round .cu-tag:first-child {
+	border-top-left-radius: 200upx;
+	border-bottom-left-radius: 200upx;
+	text-indent: 4upx;
+}
+
+.cu-capsule.round .cu-tag:last-child::after,
+.cu-capsule.round .cu-tag:last-child {
+	border-top-right-radius: 200upx;
+	border-bottom-right-radius: 200upx;
+	text-indent: -4upx;
+}
+
+.cu-tag.badge {
+	border-radius: 200upx;
+	position: absolute;
+	top:4upx;
+	right: -10upx;
+	font-size: 20upx;
+	padding: 0upx 10upx;
+	height: 28upx;
+	color: #ffffff;
+}
+
+.cu-tag.badge:not([class*="bg-"]) {
+	background-color: #dd514c;
+}
+
+.cu-tag:empty:not([class*="cuIcon-"]) {
+	padding: 0upx;
+	width: 16upx;
+	height: 16upx;
+	top: -4upx;
+	right: -4upx;
+}
+
+.cu-tag[class*="cuIcon-"] {
+	width: 32upx;
+	height: 32upx;
+	top: -4upx;
+	right: -4upx;
+}
+
+/* ==================
+          头像
+ ==================== */
+
+.cu-avatar {
+	font-variant: small-caps;
+	margin: 0;
+	padding: 0;
+	display: inline-flex;
+	text-align: center;
+	justify-content: center;
+	align-items: center;
+	background-color: #ccc;
+	color: #ffffff;
+	white-space: nowrap;
+	position: relative;
+	width: 64upx;
+	height: 64upx;
+	background-size: cover;
+	background-position: center;
+	vertical-align: middle;
+	font-size: 1.5em;
+}
+
+.cu-avatar.sm {
+	width: 48upx;
+	height: 48upx;
+	font-size: 1em;
+}
+
+.cu-avatar.lg {
+	width: 96upx;
+	height: 96upx;
+	font-size: 2em;
+}
+
+.cu-avatar.xl {
+	width: 128upx;
+	height: 128upx;
+	font-size: 2.5em;
+}
+
+.cu-avatar .avatar-text {
+	font-size: 0.4em;
+}
+
+.cu-avatar-group {
+	direction: rtl;
+	unicode-bidi: bidi-override;
+	padding: 0 10upx 0 40upx;
+	display: inline-block;
+}
+
+.cu-avatar-group .cu-avatar {
+	margin-left: -30upx;
+	border: 4upx solid #f1f1f1;
+	vertical-align: middle;
+}
+
+.cu-avatar-group .cu-avatar.sm {
+	margin-left: -20upx;
+	border: 1upx solid #f1f1f1;
+}
+
+/* ==================
+         进度条
+ ==================== */
+
+.cu-progress {
+	overflow: hidden;
+	height: 28upx;
+	background-color: #ebeef5;
+	display: inline-flex;
+	align-items: center;
+	width: 100%;
+}
+
+.cu-progress+view,
+.cu-progress+text {
+	line-height: 1;
+}
+
+.cu-progress.xs {
+	height: 10upx;
+}
+
+.cu-progress.sm {
+	height: 20upx;
+}
+
+.cu-progress view {
+	width: 0;
+	height: 100%;
+	align-items: center;
+	display: flex;
+	justify-items: flex-end;
+	justify-content: space-around;
+	font-size: 20upx;
+	color: #ffffff;
+	transition: width 0.6s ease;
+}
+
+.cu-progress text {
+	align-items: center;
+	display: flex;
+	font-size: 20upx;
+	color: #333333;
+	text-indent: 10upx;
+}
+
+.cu-progress.text-progress {
+	padding-right: 60upx;
+}
+
+.cu-progress.striped view {
+	background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+	background-size: 72upx 72upx;
+}
+
+.cu-progress.active view {
+	animation: progress-stripes 2s linear infinite;
+}
+
+@keyframes progress-stripes {
+	from {
+		background-position: 72upx 0;
+	}
+
+	to {
+		background-position: 0 0;
+	}
+}
+
+/* ==================
+          加载
+ ==================== */
+
+.cu-load {
+	display: block;
+	line-height: 3em;
+	text-align: center;
+}
+
+.cu-load::before {
+	font-family: "cuIcon";
+	display: inline-block;
+	margin-right: 6upx;
+}
+
+.cu-load.loading::before {
+	content: "\e67a";
+	animation: cuIcon-spin 2s infinite linear;
+}
+
+.cu-load.loading::after {
+	content: "加载中...";
+}
+
+.cu-load.over::before {
+	content: "\e64a";
+}
+
+.cu-load.over::after {
+	content: "没有更多了";
+}
+
+.cu-load.erro::before {
+	content: "\e658";
+}
+
+.cu-load.erro::after {
+	content: "加载失败";
+}
+
+.cu-load.load-cuIcon::before {
+	font-size: 32upx;
+}
+
+.cu-load.load-cuIcon::after {
+	display: none;
+}
+
+.cu-load.load-cuIcon.over {
+	display: none;
+}
+
+.cu-load.load-modal {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 140upx;
+	left: 0;
+	margin: auto;
+	width: 260upx;
+	height: 260upx;
+	background-color: #ffffff;
+	border-radius: 10upx;
+	box-shadow: 0 0 0upx 2000upx rgba(0, 0, 0, 0.5);
+	display: flex;
+	align-items: center;
+	flex-direction: column;
+	justify-content: center;
+	font-size: 28upx;
+	z-index: 9999;
+	line-height: 2.4em;
+}
+
+.cu-load.load-modal [class*="cuIcon-"] {
+	font-size: 60upx;
+}
+
+.cu-load.load-modal image {
+	width: 70upx;
+	height: 70upx;
+}
+
+.cu-load.load-modal::after {
+	content: "";
+	position: absolute;
+	background-color: #ffffff;
+	border-radius: 50%;
+	width: 200upx;
+	height: 200upx;
+	font-size: 10px;
+	border-top: 6upx solid rgba(0, 0, 0, 0.05);
+	border-right: 6upx solid rgba(0, 0, 0, 0.05);
+	border-bottom: 6upx solid rgba(0, 0, 0, 0.05);
+	border-left: 6upx solid #f37b1d;
+	animation: cuIcon-spin 1s infinite linear;
+	z-index: -1;
+}
+
+.load-progress {
+	pointer-events: none;
+	top: 0;
+	position: fixed;
+	width: 100%;
+	left: 0;
+	z-index: 2000;
+}
+
+.load-progress.hide {
+	display: none;
+}
+
+.load-progress .load-progress-bar {
+	position: relative;
+	width: 100%;
+	height: 4upx;
+	overflow: hidden;
+	transition: all 200ms ease 0s;
+}
+
+.load-progress .load-progress-spinner {
+	position: absolute;
+	top: 10upx;
+	right: 10upx;
+	z-index: 2000;
+	display: block;
+}
+
+.load-progress .load-progress-spinner::after {
+	content: "";
+	display: block;
+	width: 24upx;
+	height: 24upx;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	border: solid 4upx transparent;
+	border-top-color: inherit;
+	border-left-color: inherit;
+	border-radius: 50%;
+	-webkit-animation: load-progress-spinner 0.4s linear infinite;
+	animation: load-progress-spinner 0.4s linear infinite;
+}
+
+@-webkit-keyframes load-progress-spinner {
+	0% {
+		-webkit-transform: rotate(0);
+		transform: rotate(0);
+	}
+
+	100% {
+		-webkit-transform: rotate(360deg);
+		transform: rotate(360deg);
+	}
+}
+
+@keyframes load-progress-spinner {
+	0% {
+		-webkit-transform: rotate(0);
+		transform: rotate(0);
+	}
+
+	100% {
+		-webkit-transform: rotate(360deg);
+		transform: rotate(360deg);
+	}
+}
+
+/* ==================
+          列表
+ ==================== */
+.grayscale {
+	filter: grayscale(1);
+}
+
+.cu-list+.cu-list {
+	margin-top: 30upx
+}
+
+.cu-list>.cu-item {
+	transition: all .6s ease-in-out 0s;
+	transform: translateX(0upx)
+}
+
+.cu-list>.cu-item.move-cur {
+	transform: translateX(-260upx)
+}
+
+.cu-list>.cu-item .move {
+	position: absolute;
+	right: 0;
+	display: flex;
+	width: 260upx;
+	height: 100%;
+	transform: translateX(100%)
+}
+
+.cu-list>.cu-item .move view {
+	display: flex;
+	flex: 1;
+	justify-content: center;
+	align-items: center
+}
+
+.cu-list.menu-avatar {
+	overflow: hidden;
+}
+
+.cu-list.menu-avatar>.cu-item {
+	position: relative;
+	display: flex;
+	padding-right: 10upx;
+	height: 140upx;
+	background-color: #ffffff;
+	justify-content: flex-end;
+	align-items: center
+}
+
+.cu-list.menu-avatar>.cu-item>.cu-avatar {
+	position: absolute;
+	left: 30upx
+}
+
+.cu-list.menu-avatar>.cu-item .flex .text-cut {
+	max-width: 510upx
+}
+
+.cu-list.menu-avatar>.cu-item .content {
+	position: absolute;
+	left: 146upx;
+	width: calc(100% - 96upx - 60upx - 120upx - 20upx);
+	line-height: 1.6em;
+}
+
+.cu-list.menu-avatar>.cu-item .content.flex-sub {
+	width: calc(100% - 96upx - 60upx - 20upx);
+}
+
+.cu-list.menu-avatar>.cu-item .content>view:first-child {
+	font-size: 30upx;
+	display: flex;
+	align-items: center
+}
+
+.cu-list.menu-avatar>.cu-item .content .cu-tag.sm {
+	display: inline-block;
+	margin-left: 10upx;
+	height: 28upx;
+	font-size: 16upx;
+	line-height: 32upx
+}
+
+.cu-list.menu-avatar>.cu-item .action {
+	width: 100upx;
+	text-align: center
+}
+
+.cu-list.menu-avatar>.cu-item .action view+view {
+	margin-top: 10upx
+}
+
+.cu-list.menu-avatar.comment>.cu-item .content {
+	position: relative;
+	left: 0;
+	width: auto;
+	flex: 1;
+}
+
+.cu-list.menu-avatar.comment>.cu-item {
+	padding: 30upx 30upx 30upx 120upx;
+	height: auto
+}
+
+.cu-list.menu-avatar.comment .cu-avatar {
+	align-self: flex-start
+}
+
+.cu-list.menu>.cu-item {
+	position: relative;
+	display: flex;
+	padding: 0 30upx;
+	min-height: 100upx;
+	background-color: #ffffff;
+	justify-content: space-between;
+	align-items: center
+}
+
+.cu-list.menu>.cu-item:last-child:after {
+	border: none
+}
+
+.cu-list.menu-avatar>.cu-item:after,
+.cu-list.menu>.cu-item:after {
+	position: absolute;
+	top: 0;
+	left: 0;
+	box-sizing: border-box;
+	width: 200%;
+	height: 200%;
+	border-bottom: 1upx solid #ddd;
+	border-radius: inherit;
+	content: " ";
+	transform: scale(.5);
+	transform-origin: 0 0;
+	pointer-events: none
+}
+
+.cu-list.menu>.cu-item.grayscale {
+	background-color: #f5f5f5
+}
+
+.cu-list.menu>.cu-item.cur {
+	background-color: #fcf7e9
+}
+
+.cu-list.menu>.cu-item.arrow {
+	padding-right: 90upx
+}
+
+.cu-list.menu>.cu-item.arrow:before {
+	position: absolute;
+	top: 0;
+	right: 30upx;
+	bottom: 0;
+	display: block;
+	margin: auto;
+	width: 30upx;
+	height: 30upx;
+	color: #8799a3;
+	content: "\e6a3";
+	text-align: center;
+	font-size: 34upx;
+	font-family: cuIcon;
+	line-height: 30upx
+}
+
+.cu-list.menu>.cu-item button.content {
+	padding: 0;
+	background-color: transparent;
+	justify-content: flex-start
+}
+
+.cu-list.menu>.cu-item button.content:after {
+	display: none
+}
+
+.cu-list.menu>.cu-item .cu-avatar-group .cu-avatar {
+	border-color: #ffffff
+}
+
+.cu-list.menu>.cu-item .content>view:first-child {
+	display: flex;
+	align-items: center
+}
+
+.cu-list.menu>.cu-item .content>text[class*=cuIcon] {
+	display: inline-block;
+	margin-right: 10upx;
+	width: 1.6em;
+	text-align: center
+}
+
+.cu-list.menu>.cu-item .content>image {
+	display: inline-block;
+	margin-right: 10upx;
+	width: 1.6em;
+	height: 1.6em;
+	vertical-align: middle
+}
+
+.cu-list.menu>.cu-item .content {
+	font-size: 30upx;
+	line-height: 1.6em;
+	flex: 1
+}
+
+.cu-list.menu>.cu-item .content .cu-tag.sm {
+	display: inline-block;
+	margin-left: 10upx;
+	height: 28upx;
+	font-size: 16upx;
+	line-height: 32upx
+}
+
+.cu-list.menu>.cu-item .action .cu-tag:empty {
+	right: 10upx
+}
+
+.cu-list.menu {
+	display: block;
+	overflow: hidden
+}
+
+.cu-list.menu.sm-border>.cu-item:after {
+	left: 30upx;
+	width: calc(200% - 120upx)
+}
+
+.cu-list.grid>.cu-item {
+	position: relative;
+	display: flex;
+	padding: 20upx 0 30upx;
+	transition-duration: 0s;
+	flex-direction: column
+}
+
+.cu-list.grid>.cu-item:after {
+	position: absolute;
+	top: 0;
+	left: 0;
+	box-sizing: border-box;
+	width: 200%;
+	height: 200%;
+	border-right: 1px solid rgba(0, 0, 0, .1);
+	border-bottom: 1px solid rgba(0, 0, 0, .1);
+	border-radius: inherit;
+	content: " ";
+	transform: scale(.5);
+	transform-origin: 0 0;
+	pointer-events: none
+}
+
+.cu-list.grid>.cu-item text {
+	display: block;
+	margin-top: 10upx;
+	color: #888;
+	font-size: 26upx;
+	line-height: 40upx
+}
+
+.cu-list.grid>.cu-item [class*=cuIcon] {
+	position: relative;
+	display: block;
+	margin-top: 20upx;
+	width: 100%;
+	font-size: 48upx
+}
+
+.cu-list.grid>.cu-item .cu-tag {
+	right: auto;
+	left: 50%;
+	margin-left: 20upx
+}
+
+.cu-list.grid {
+	background-color: #ffffff;
+	text-align: center
+}
+
+.cu-list.grid.no-border>.cu-item {
+	padding-top: 10upx;
+	padding-bottom: 20upx
+}
+
+.cu-list.grid.no-border>.cu-item:after {
+	border: none
+}
+
+.cu-list.grid.no-border {
+	padding: 20upx 10upx
+}
+
+.cu-list.grid.col-3>.cu-item:nth-child(3n):after,
+.cu-list.grid.col-4>.cu-item:nth-child(4n):after,
+.cu-list.grid.col-5>.cu-item:nth-child(5n):after {
+	border-right-width: 0
+}
+
+.cu-list.card-menu {
+	overflow: hidden;
+	margin-right: 30upx;
+	margin-left: 30upx;
+	border-radius: 20upx
+}
+
+
+/* ==================
+          操作条
+ ==================== */
+
+.cu-bar {
+	display: flex;
+	position: relative;
+	align-items: center;
+	min-height: 100upx;
+	justify-content: space-between;
+}
+
+.cu-bar .action {
+	display: flex;
+	align-items: center;
+	height: 100%;
+	justify-content: center;
+	max-width: 100%;
+}
+
+.cu-bar .action.border-title {
+	position: relative;
+	top: -10upx;
+}
+
+.cu-bar .action.border-title text[class*="bg-"]:last-child {
+	position: absolute;
+	bottom: -0.5rem;
+	min-width: 2rem;
+	height: 6upx;
+	left: 0;
+}
+
+.cu-bar .action.sub-title {
+	position: relative;
+	top: -0.2rem;
+}
+
+.cu-bar .action.sub-title text {
+	position: relative;
+	z-index: 1;
+}
+
+.cu-bar .action.sub-title text[class*="bg-"]:last-child {
+	position: absolute;
+	display: inline-block;
+	bottom: -0.2rem;
+	border-radius: 6upx;
+	width: 100%;
+	height: 0.6rem;
+	left: 0.6rem;
+	opacity: 0.3;
+	z-index: 0;
+}
+
+.cu-bar .action.sub-title text[class*="text-"]:last-child {
+	position: absolute;
+	display: inline-block;
+	bottom: -0.7rem;
+	left: 0.5rem;
+	opacity: 0.2;
+	z-index: 0;
+	text-align: right;
+	font-weight: 900;
+	font-size: 36upx;
+}
+
+.cu-bar.justify-center .action.border-title text:last-child,
+.cu-bar.justify-center .action.sub-title text:last-child {
+	left: 0;
+	right: 0;
+	margin: auto;
+	text-align: center;
+}
+
+.cu-bar .action:first-child {
+	margin-left: 30upx;
+	font-size: 30upx;
+}
+
+.cu-bar .action text.text-cut {
+	text-align: left;
+	width: 100%;
+}
+
+.cu-bar .cu-avatar:first-child {
+	margin-left: 20upx;
+}
+
+.cu-bar .action:first-child>text[class*="cuIcon-"] {
+	margin-left: -0.3em;
+	margin-right: 0.3em;
+}
+
+.cu-bar .action:last-child {
+	margin-right: 30upx;
+}
+
+.cu-bar .action>text[class*="cuIcon-"],
+.cu-bar .action>view[class*="cuIcon-"] {
+	font-size: 36upx;
+}
+
+.cu-bar .action>text[class*="cuIcon-"]+text[class*="cuIcon-"] {
+	margin-left: 0.5em;
+}
+
+.cu-bar .content {
+	position: absolute;
+	text-align: center;
+	width: calc(100% - 340upx);
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: 0;
+	margin: auto;
+	height: 60upx;
+	font-size: 32upx;
+	line-height: 60upx;
+	cursor: none;
+	pointer-events: none;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+}
+
+.cu-bar.ios .content {
+	bottom: 7px;
+	height: 30px;
+	font-size: 32upx;
+	line-height: 30px;
+}
+
+.cu-bar.btn-group {
+	justify-content: space-around;
+}
+
+.cu-bar.btn-group button {
+	padding: 20upx 32upx;
+}
+
+.cu-bar.btn-group button {
+	flex: 1;
+	margin: 0 20upx;
+	max-width: 50%;
+}
+
+.cu-bar .search-form {
+	background-color: #f5f5f5;
+	line-height: 64upx;
+	height: 64upx;
+	font-size: 24upx;
+	color: #333333;
+	flex: 1;
+	display: flex;
+	align-items: center;
+	margin: 0 30upx;
+}
+
+.cu-bar .search-form+.action {
+	margin-right: 30upx;
+}
+
+.cu-bar .search-form input {
+	flex: 1;
+	padding-right: 30upx;
+	height: 64upx;
+	line-height: 64upx;
+	font-size: 26upx;
+	background-color: transparent;
+}
+
+.cu-bar .search-form [class*="cuIcon-"] {
+	margin: 0 0.5em 0 0.8em;
+}
+
+.cu-bar .search-form [class*="cuIcon-"]::before {
+	top: 0upx;
+}
+
+.cu-bar.fixed,
+.nav.fixed {
+	position: fixed;
+	width: 100%;
+	top: 0;
+	z-index: 1024;
+	box-shadow: 0 1upx 6upx rgba(0, 0, 0, 0.1);
+}
+
+.cu-bar.foot {
+	position: fixed;
+	width: 100%;
+	bottom: 0;
+	z-index: 1024;
+	box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
+}
+
+.cu-bar.tabbar {
+	padding: 0;
+	height: calc(100upx + env(safe-area-inset-bottom) / 2);
+	padding-bottom: calc(env(safe-area-inset-bottom) / 2);
+}
+
+.cu-tabbar-height {
+	min-height: 100upx;
+	height: calc(100upx + env(safe-area-inset-bottom) / 2);
+}
+
+.cu-bar.tabbar.shadow {
+	box-shadow: 0 -1upx 6upx rgba(0, 0, 0, 0.1);
+}
+
+.cu-bar.tabbar .action {
+	font-size: 22upx;
+	position: relative;
+	flex: 1;
+	text-align: center;
+	padding: 0;
+	display: block;
+	height: auto;
+	line-height: 1;
+	margin: 0;
+	background-color: inherit;
+	overflow: initial;
+}
+
+.cu-bar.tabbar.shop .action {
+	width: 140upx;
+	flex: initial;
+}
+
+.cu-bar.tabbar .action.add-action {
+	position: relative;
+	z-index: 2;
+	padding-top: 50upx;
+}
+
+.cu-bar.tabbar .action.add-action [class*="cuIcon-"] {
+	position: absolute;
+	width: 70upx;
+	z-index: 2;
+	height: 70upx;
+	border-radius: 50%;
+	line-height: 70upx;
+	font-size: 50upx;
+	top: -35upx;
+	left: 0;
+	right: 0;
+	margin: auto;
+	padding: 0;
+}
+
+.cu-bar.tabbar .action.add-action::after {
+	content: "";
+	position: absolute;
+	width: 100upx;
+	height: 100upx;
+	top: -50upx;
+	left: 0;
+	right: 0;
+	margin: auto;
+	box-shadow: 0 -3upx 8upx rgba(0, 0, 0, 0.08);
+	border-radius: 50upx;
+	background-color: inherit;
+	z-index: 0;
+}
+
+.cu-bar.tabbar .action.add-action::before {
+	content: "";
+	position: absolute;
+	width: 100upx;
+	height: 30upx;
+	bottom: 30upx;
+	left: 0;
+	right: 0;
+	margin: auto;
+	background-color: inherit;
+	z-index: 1;
+}
+
+.cu-bar.tabbar .btn-group {
+	flex: 1;
+	display: flex;
+	justify-content: space-around;
+	align-items: center;
+	padding: 0 10upx;
+}
+
+.cu-bar.tabbar button.action::after {
+	border: 0;
+}
+
+.cu-bar.tabbar .action [class*="cuIcon-"] {
+	width: 100upx;
+	position: relative;
+	display: block;
+	height: auto;
+	margin: 0 auto 10upx;
+	text-align: center;
+	font-size: 40upx;
+}
+
+.cu-bar.tabbar .action .cuIcon-cu-image {
+	margin: 0 auto;
+}
+
+.cu-bar.tabbar .action .cuIcon-cu-image image {
+	width: 50upx;
+	height: 50upx;
+	display: inline-block;
+}
+
+.cu-bar.tabbar .submit {
+	align-items: center;
+	display: flex;
+	justify-content: center;
+	text-align: center;
+	position: relative;
+	flex: 2;
+	align-self: stretch;
+}
+
+.cu-bar.tabbar .submit:last-child {
+	flex: 2.6;
+}
+
+.cu-bar.tabbar .submit+.submit {
+	flex: 2;
+}
+
+.cu-bar.tabbar.border .action::before {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	border-right: 1upx solid rgba(0, 0, 0, 0.1);
+	z-index: 3;
+}
+
+.cu-bar.tabbar.border .action:last-child:before {
+	display: none;
+}
+
+.cu-bar.input {
+	padding-right: 20upx;
+	background-color: #ffffff;
+}
+
+.cu-bar.input input {
+	overflow: initial;
+	line-height: 64upx;
+	height: 64upx;
+	min-height: 64upx;
+	flex: 1;
+	font-size: 30upx;
+	margin: 0 20upx;
+}
+
+.cu-bar.input .action {
+	margin-left: 20upx;
+}
+
+.cu-bar.input .action [class*="cuIcon-"] {
+	font-size: 48upx;
+}
+
+.cu-bar.input input+.action {
+	margin-right: 20upx;
+	margin-left: 0upx;
+}
+
+.cu-bar.input .action:first-child [class*="cuIcon-"] {
+	margin-left: 0upx;
+}
+
+.cu-custom {
+	display: block;
+	position: relative;
+}
+
+.cu-custom .cu-bar .content {
+	width: calc(100% - 440upx);
+}
+
+/* #ifdef MP-ALIPAY */
+.cu-custom .cu-bar .action .cuIcon-back {
+	opacity: 0;
+}
+
+/* #endif */
+
+.cu-custom .cu-bar .content image {
+	height: 60upx;
+	width: 240upx;
+}
+
+.cu-custom .cu-bar {
+	min-height: 0px;
+	/* #ifdef MP-WEIXIN */
+	padding-right: 220upx;
+	/* #endif */
+	/* #ifdef MP-ALIPAY */
+	padding-right: 150upx;
+	/* #endif */
+	box-shadow: 0upx 0upx 0upx;
+	z-index: 9999;
+}
+
+.cu-custom .cu-bar .border-custom {
+	position: relative;
+	background: rgba(0, 0, 0, 0.15);
+	border-radius: 1000upx;
+	height: 30px;
+}
+
+.cu-custom .cu-bar .border-custom::after {
+	content: " ";
+	width: 200%;
+	height: 200%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border-radius: inherit;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	pointer-events: none;
+	box-sizing: border-box;
+	border: 1upx solid #ffffff;
+	opacity: 0.5;
+}
+
+.cu-custom .cu-bar .border-custom::before {
+	content: " ";
+	width: 1upx;
+	height: 110%;
+	position: absolute;
+	top: 22.5%;
+	left: 0;
+	right: 0;
+	margin: auto;
+	transform: scale(0.5);
+	transform-origin: 0 0;
+	pointer-events: none;
+	box-sizing: border-box;
+	opacity: 0.6;
+	background-color: #ffffff;
+}
+
+.cu-custom .cu-bar .border-custom text {
+	display: block;
+	flex: 1;
+	margin: auto !important;
+	text-align: center;
+	font-size: 34upx;
+}
+
+/* ==================
+         导航栏
+ ==================== */
+
+.nav {
+	white-space: nowrap;
+}
+
+::-webkit-scrollbar {
+	display: none;
+}
+
+.nav .cu-item {
+	height: 90upx;
+	display: inline-block;
+	line-height: 90upx;
+	margin: 0 10upx;
+	padding: 0 20upx;
+}
+
+.nav .cu-item.cur {
+	border-bottom: 4upx solid;
+}
+
+/* ==================
+         时间轴
+ ==================== */
+
+.cu-timeline {
+	display: block;
+	background-color: #ffffff;
+}
+
+.cu-timeline .cu-time {
+	width: 120upx;
+	text-align: center;
+	padding: 20upx 0;
+	font-size: 26upx;
+	color: #888;
+	display: block;
+}
+
+.cu-timeline>.cu-item {
+	padding: 30upx 30upx 30upx 120upx;
+	position: relative;
+	display: block;
+	z-index: 0;
+}
+
+.cu-timeline>.cu-item:not([class*="text-"]) {
+	color: #ccc;
+}
+
+.cu-timeline>.cu-item::after {
+	content: "";
+	display: block;
+	position: absolute;
+	width: 1upx;
+	background-color: #ddd;
+	left: 60upx;
+	height: 100%;
+	top: 0;
+	z-index: 8;
+}
+
+.cu-timeline>.cu-item::before {
+	font-family: "cuIcon";
+	display: block;
+	position: absolute;
+	top: 36upx;
+	z-index: 9;
+	background-color: #ffffff;
+	width: 50upx;
+	height: 50upx;
+	text-align: center;
+	border: none;
+	line-height: 50upx;
+	left: 36upx;
+}
+
+.cu-timeline>.cu-item:not([class*="cuIcon-"])::before {
+	content: "\e763";
+}
+
+.cu-timeline>.cu-item[class*="cuIcon-"]::before {
+	background-color: #ffffff;
+	width: 50upx;
+	height: 50upx;
+	text-align: center;
+	border: none;
+	line-height: 50upx;
+	left: 36upx;
+}
+
+.cu-timeline>.cu-item>.content {
+	padding: 30upx;
+	border-radius: 6upx;
+	display: block;
+	line-height: 1.6;
+}
+
+.cu-timeline>.cu-item>.content:not([class*="bg-"]) {
+	background-color: #f1f1f1;
+	color: #333333;
+}
+
+.cu-timeline>.cu-item>.content+.content {
+	margin-top: 20upx;
+}
+
+/* ==================
+         聊天
+ ==================== */
+
+.cu-chat {
+	display: flex;
+	flex-direction: column;
+}
+
+.cu-chat .cu-item {
+	display: flex;
+	padding: 30upx 30upx 70upx;
+	position: relative;
+}
+
+.cu-chat .cu-item>.cu-avatar {
+	width: 80upx;
+	height: 80upx;
+}
+
+.cu-chat .cu-item>.main {
+	max-width: calc(100% - 260upx);
+	margin: 0 40upx;
+	display: flex;
+	align-items: center;
+}
+
+.cu-chat .cu-item>image {
+	height: 320upx;
+}
+
+.cu-chat .cu-item>.main .content {
+	padding: 20upx;
+	border-radius: 6upx;
+	display: inline-flex;
+	max-width: 100%;
+	align-items: center;
+	font-size: 30upx;
+	position: relative;
+	min-height: 80upx;
+	line-height: 40upx;
+	text-align: left;
+}
+
+.cu-chat .cu-item>.main .content:not([class*="bg-"]) {
+	background-color: #ffffff;
+	color: #333333;
+}
+
+.cu-chat .cu-item .date {
+	position: absolute;
+	font-size: 24upx;
+	color: #8799a3;
+	width: calc(100% - 320upx);
+	bottom: 20upx;
+	left: 160upx;
+}
+
+.cu-chat .cu-item .action {
+	padding: 0 30upx;
+	display: flex;
+	align-items: center;
+}
+
+.cu-chat .cu-item>.main .content::after {
+	content: "";
+	top: 27upx;
+	transform: rotate(45deg);
+	position: absolute;
+	z-index: 100;
+	display: inline-block;
+	overflow: hidden;
+	width: 24upx;
+	height: 24upx;
+	left: -12upx;
+	right: initial;
+	background-color: inherit;
+}
+
+.cu-chat .cu-item.self>.main .content::after {
+	left: auto;
+	right: -12upx;
+}
+
+.cu-chat .cu-item>.main .content::before {
+	content: "";
+	top: 30upx;
+	transform: rotate(45deg);
+	position: absolute;
+	z-index: -1;
+	display: inline-block;
+	overflow: hidden;
+	width: 24upx;
+	height: 24upx;
+	left: -12upx;
+	right: initial;
+	background-color: inherit;
+	filter: blur(5upx);
+	opacity: 0.3;
+}
+
+.cu-chat .cu-item>.main .content:not([class*="bg-"])::before {
+	background-color: #333333;
+	opacity: 0.1;
+}
+
+.cu-chat .cu-item.self>.main .content::before {
+	left: auto;
+	right: -12upx;
+}
+
+.cu-chat .cu-item.self {
+	justify-content: flex-end;
+	text-align: right;
+}
+
+.cu-chat .cu-info {
+	display: inline-block;
+	margin: 20upx auto;
+	font-size: 24upx;
+	padding: 8upx 12upx;
+	background-color: rgba(0, 0, 0, 0.2);
+	border-radius: 6upx;
+	color: #ffffff;
+	max-width: 400upx;
+	line-height: 1.4;
+}
+
+/* ==================
+         卡片
+ ==================== */
+
+.cu-card {
+	display: block;
+	overflow: hidden;
+}
+
+.cu-card>.cu-item {
+	display: block;
+	background-color: #ffffff;
+	overflow: hidden;
+	border-radius: 10upx;
+	margin: 30upx;
+}
+
+.cu-card>.cu-item.shadow-blur {
+	overflow: initial;
+}
+
+.cu-card.no-card>.cu-item {
+	margin: 0upx;
+	border-radius: 0upx;
+}
+
+.cu-card .grid.grid-square {
+	margin-bottom: -20upx;
+}
+
+.cu-card.case .image {
+	position: relative;
+}
+
+.cu-card.case .image image {
+	width: 100%;
+}
+
+.cu-card.case .image .cu-tag {
+	position: absolute;
+	right: 0;
+	top: 0;
+}
+
+.cu-card.case .image .cu-bar {
+	position: absolute;
+	bottom: 0;
+	width: 100%;
+	background-color: transparent;
+	padding: 0upx 30upx;
+}
+
+.cu-card.case.no-card .image {
+	margin: 30upx 30upx 0;
+	overflow: hidden;
+	border-radius: 10upx;
+}
+
+.cu-card.dynamic {
+	display: block;
+}
+
+.cu-card.dynamic>.cu-item {
+	display: block;
+	background-color: #ffffff;
+	overflow: hidden;
+}
+
+.cu-card.dynamic>.cu-item>.text-content {
+	padding: 0 30upx 0;
+	max-height: 6.4em;
+	overflow: hidden;
+	font-size: 30upx;
+	margin-bottom: 20upx;
+}
+
+.cu-card.dynamic>.cu-item .square-img {
+	width: 100%;
+	height: 200upx;
+	border-radius: 6upx;
+}
+
+.cu-card.dynamic>.cu-item .only-img {
+	width: 100%;
+	height: 320upx;
+	border-radius: 6upx;
+}
+
+/* card.dynamic>.cu-item .comment {
+  padding: 20upx;
+  background-color: #f1f1f1;
+  margin: 0 30upx 30upx;
+  border-radius: 6upx;
+} */
+
+.cu-card.article {
+	display: block;
+}
+
+.cu-card.article>.cu-item {
+	padding-bottom: 30upx;
+}
+
+.cu-card.article>.cu-item .title {
+	font-size: 30upx;
+	font-weight: 900;
+	color: #333333;
+	line-height: 100upx;
+	padding: 0 30upx;
+}
+
+.cu-card.article>.cu-item .content {
+	display: flex;
+	padding: 0 30upx;
+}
+
+.cu-card.article>.cu-item .content>image {
+	width: 240upx;
+	height: 6.4em;
+	margin-right: 20upx;
+	border-radius: 6upx;
+}
+
+.cu-card.article>.cu-item .content .desc {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+}
+
+.cu-card.article>.cu-item .content .text-content {
+	font-size: 28upx;
+	color: #888;
+	height: 4.8em;
+	overflow: hidden;
+}
+
+/* ==================
+         表单
+ ==================== */
+
+.cu-form-group {
+	background-color: #ffffff;
+	padding: 1upx 30upx;
+	display: flex;
+	align-items: center;
+	min-height: 100upx;
+	justify-content: space-between;
+}
+
+.cu-form-group+.cu-form-group {
+	border-top: 1upx solid #eee;
+}
+
+.cu-form-group .title {
+	text-align: justify;
+	padding-right: 30upx;
+	font-size: 30upx;
+	position: relative;
+	height: 60upx;
+	line-height: 60upx;
+}
+
+.cu-form-group input {
+	flex: 1;
+	font-size: 30upx;
+	color: #555;
+	padding-right: 20upx;
+}
+
+.cu-form-group>text[class*="cuIcon-"] {
+	font-size: 36upx;
+	padding: 0;
+	box-sizing: border-box;
+}
+
+.cu-form-group textarea {
+	margin: 32upx 0 30upx;
+	height: 4.6em;
+	width: 100%;
+	line-height: 1.2em;
+	flex: 1;
+	font-size: 28upx;
+	padding: 0;
+}
+
+.cu-form-group.align-start .title {
+	height: 1em;
+	margin-top: 32upx;
+	line-height: 1em;
+}
+
+.cu-form-group picker {
+	flex: 1;
+	padding-right: 40upx;
+	overflow: hidden;
+	position: relative;
+}
+
+.cu-form-group picker .picker {
+	line-height: 100upx;
+	font-size: 28upx;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+	width: 100%;
+	text-align: right;
+}
+
+.cu-form-group picker::after {
+	font-family: cuIcon;
+	display: block;
+	content: "\e6a3";
+	position: absolute;
+	font-size: 34upx;
+	color: #8799a3;
+	line-height: 100upx;
+	width: 60upx;
+	text-align: center;
+	top: 0;
+	bottom: 0;
+	right: -20upx;
+	margin: auto;
+}
+
+.cu-form-group textarea[disabled],
+.cu-form-group textarea[disabled] .placeholder {
+	color: transparent;
+}
+
+/* ==================
+         模态窗口
+ ==================== */
+
+.cu-modal {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 1110;
+	opacity: 0;
+	outline: 0;
+	text-align: center;
+	-ms-transform: scale(1.185);
+	transform: scale(1.185);
+	backface-visibility: hidden;
+	perspective: 2000upx;
+	background: rgba(0, 0, 0, 0.6);
+	transition: all 0.3s ease-in-out 0s;
+	pointer-events: none;
+}
+
+.cu-modal::before {
+	content: "\200B";
+	display: inline-block;
+	height: 100%;
+	vertical-align: middle;
+}
+
+.cu-modal.show {
+	opacity: 1;
+	transition-duration: 0.3s;
+	-ms-transform: scale(1);
+	transform: scale(1);
+	overflow-x: hidden;
+	overflow-y: auto;
+	pointer-events: auto;
+}
+
+.cu-dialog {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+	margin-left: auto;
+	margin-right: auto;
+	width: 680upx;
+	max-width: 100%;
+	background-color: #f8f8f8;
+	border-radius: 10upx;
+	overflow: hidden;
+}
+
+.cu-modal.bottom-modal::before {
+	vertical-align: bottom;
+}
+
+.cu-modal.bottom-modal .cu-dialog {
+	width: 100%;
+	border-radius: 0;
+}
+
+.cu-modal.bottom-modal {
+	margin-bottom: -1000upx;
+}
+
+.cu-modal.bottom-modal.show {
+	margin-bottom: 0;
+}
+
+.cu-modal.drawer-modal {
+	transform: scale(1);
+	display: flex;
+}
+
+.cu-modal.drawer-modal .cu-dialog {
+	height: 100%;
+	min-width: 200upx;
+	border-radius: 0;
+	margin: initial;
+	transition-duration: 0.3s;
+}
+
+.cu-modal.drawer-modal.justify-start .cu-dialog {
+	transform: translateX(-100%);
+}
+
+.cu-modal.drawer-modal.justify-end .cu-dialog {
+	transform: translateX(100%);
+}
+
+.cu-modal.drawer-modal.show .cu-dialog {
+	transform: translateX(0%);
+}
+.cu-modal .cu-dialog>.cu-bar:first-child .action{
+  min-width: 100rpx;
+  margin-right: 0;
+  min-height: 100rpx;
+}
+/* ==================
+         轮播
+ ==================== */
+swiper .a-swiper-dot {
+	display: inline-block;
+	width: 16upx;
+	height: 16upx;
+	background: rgba(0, 0, 0, .3);
+	border-radius: 50%;
+	vertical-align: middle;
+}
+
+swiper[class*="-dot"] .wx-swiper-dots,
+swiper[class*="-dot"] .a-swiper-dots,
+swiper[class*="-dot"] .uni-swiper-dots {
+	display: flex;
+	align-items: center;
+	width: 100%;
+	justify-content: center;
+}
+
+swiper.square-dot .wx-swiper-dot,
+swiper.square-dot .a-swiper-dot,
+swiper.square-dot .uni-swiper-dot {
+	background-color: #ffffff;
+	opacity: 0.4;
+	width: 10upx;
+	height: 10upx;
+	border-radius: 20upx;
+	margin: 0 8upx !important;
+}
+
+swiper.square-dot .wx-swiper-dot.wx-swiper-dot-active,
+swiper.square-dot .a-swiper-dot.a-swiper-dot-active,
+swiper.square-dot .uni-swiper-dot.uni-swiper-dot-active {
+	opacity: 1;
+	width: 30upx;
+}
+
+swiper.round-dot .wx-swiper-dot,
+swiper.round-dot .a-swiper-dot,
+swiper.round-dot .uni-swiper-dot {
+	width: 10upx;
+	height: 10upx;
+	position: relative;
+	margin: 4upx 8upx !important;
+}
+
+swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active::after,
+swiper.round-dot .a-swiper-dot.a-swiper-dot-active::after,
+swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active::after {
+	content: "";
+	position: absolute;
+	width: 10upx;
+	height: 10upx;
+	top: 0upx;
+	left: 0upx;
+	right: 0;
+	bottom: 0;
+	margin: auto;
+	background-color: #ffffff;
+	border-radius: 20upx;
+}
+
+swiper.round-dot .wx-swiper-dot.wx-swiper-dot-active,
+swiper.round-dot .a-swiper-dot.a-swiper-dot-active,
+swiper.round-dot .uni-swiper-dot.uni-swiper-dot-active {
+	width: 18upx;
+	height: 18upx;
+}
+
+.screen-swiper {
+	min-height: 375upx;
+}
+
+.screen-swiper image,
+.screen-swiper video,
+.swiper-item image,
+.swiper-item video {
+	width: 100%;
+	display: block;
+	height: 100%;
+	margin: 0;
+	pointer-events: none;
+}
+
+.card-swiper {
+	height: 420upx !important;
+}
+
+.card-swiper swiper-item {
+	width: 610upx !important;
+	left: 70upx;
+	box-sizing: border-box;
+	padding: 40upx 0upx 70upx;
+	overflow: initial;
+}
+
+.card-swiper swiper-item .swiper-item {
+	width: 100%;
+	display: block;
+	height: 100%;
+	border-radius: 10upx;
+	transform: scale(0.9);
+	transition: all 0.2s ease-in 0s;
+	overflow: hidden;
+}
+
+.card-swiper swiper-item.cur .swiper-item {
+	transform: none;
+	transition: all 0.2s ease-in 0s;
+}
+
+
+.tower-swiper {
+	height: 420upx;
+	position: relative;
+	max-width: 750upx;
+	overflow: hidden;
+}
+
+.tower-swiper .tower-item {
+	position: absolute;
+	width: 300upx;
+	height: 380upx;
+	top: 0;
+	bottom: 0;
+	left: 50%;
+	margin: auto;
+	transition: all 0.2s ease-in 0s;
+	opacity: 1;
+}
+
+.tower-swiper .tower-item.none {
+	opacity: 0;
+}
+
+.tower-swiper .tower-item .swiper-item {
+	width: 100%;
+	height: 100%;
+	border-radius: 6upx;
+	overflow: hidden;
+}
+
+/* ==================
+          步骤条
+ ==================== */
+
+.cu-steps {
+	display: flex;
+}
+
+scroll-view.cu-steps {
+	display: block;
+	white-space: nowrap;
+}
+
+scroll-view.cu-steps .cu-item {
+	display: inline-block;
+}
+
+.cu-steps .cu-item {
+	flex: 1;
+	text-align: center;
+	position: relative;
+	min-width: 100upx;
+}
+
+.cu-steps .cu-item:not([class*="text-"]) {
+	color: #8799a3;
+}
+
+.cu-steps .cu-item [class*="cuIcon-"],
+.cu-steps .cu-item .num {
+	display: block;
+	font-size: 40upx;
+	line-height: 80upx;
+}
+
+.cu-steps .cu-item::before,
+.cu-steps .cu-item::after,
+.cu-steps.steps-arrow .cu-item::before,
+.cu-steps.steps-arrow .cu-item::after {
+	content: "";
+	display: block;
+	position: absolute;
+	height: 0px;
+	width: calc(100% - 80upx);
+	border-bottom: 1px solid #ccc;
+	left: calc(0px - (100% - 80upx) / 2);
+	top: 40upx;
+	z-index: 0;
+}
+
+.cu-steps.steps-arrow .cu-item::before,
+.cu-steps.steps-arrow .cu-item::after {
+	content: "\e6a3";
+	font-family: 'cuIcon';
+	height: 30upx;
+	border-bottom-width: 0px;
+	line-height: 30upx;
+	top: 0;
+	bottom: 0;
+	margin: auto;
+	color: #ccc;
+}
+
+.cu-steps.steps-bottom .cu-item::before,
+.cu-steps.steps-bottom .cu-item::after {
+	bottom: 40upx;
+	top: initial;
+}
+
+.cu-steps .cu-item::after {
+	border-bottom: 1px solid currentColor;
+	width: 0px;
+	transition: all 0.3s ease-in-out 0s;
+}
+
+.cu-steps .cu-item[class*="text-"]::after {
+	width: calc(100% - 80upx);
+	color: currentColor;
+}
+
+.cu-steps .cu-item:first-child::before,
+.cu-steps .cu-item:first-child::after {
+	display: none;
+}
+
+.cu-steps .cu-item .num {
+	width: 40upx;
+	height: 40upx;
+	border-radius: 50%;
+	line-height: 40upx;
+	margin: 20upx auto;
+	font-size: 24upx;
+	border: 1px solid currentColor;
+	position: relative;
+	overflow: hidden;
+}
+
+.cu-steps .cu-item[class*="text-"] .num {
+	background-color: currentColor;
+}
+
+.cu-steps .cu-item .num::before,
+.cu-steps .cu-item .num::after {
+	content: attr(data-index);
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	margin: auto;
+	transition: all 0.3s ease-in-out 0s;
+	transform: translateY(0upx);
+}
+
+.cu-steps .cu-item[class*="text-"] .num::before {
+	transform: translateY(-40upx);
+	color: #ffffff;
+}
+
+.cu-steps .cu-item .num::after {
+	transform: translateY(40upx);
+	color: #ffffff;
+	transition: all 0.3s ease-in-out 0s;
+}
+
+.cu-steps .cu-item[class*="text-"] .num::after {
+	content: "\e645";
+	font-family: 'cuIcon';
+	color: #ffffff;
+	transform: translateY(0upx);
+}
+
+.cu-steps .cu-item[class*="text-"] .num.err::after {
+	content: "\e646";
+}
+
+/* ==================
+          布局
+ ==================== */
+
+/*  -- flex弹性布局 -- */
+
+.flex {
+	display: flex;
+}
+
+.basis-xs {
+	flex-basis: 20%;
+}
+
+.basis-sm {
+	flex-basis: 40%;
+}
+
+.basis-df {
+	flex-basis: 50%;
+}
+
+.basis-lg {
+	flex-basis: 60%;
+}
+
+.basis-xl {
+	flex-basis: 80%;
+}
+
+.flex-sub {
+	flex: 1;
+}
+
+.flex-twice {
+	flex: 2;
+}
+
+.flex-treble {
+	flex: 3;
+}
+
+.flex-direction {
+	flex-direction: column;
+}
+
+.flex-wrap {
+	flex-wrap: wrap;
+}
+
+.align-start {
+	align-items: flex-start;
+}
+
+.align-end {
+	align-items: flex-end;
+}
+
+.align-center {
+	align-items: center;
+}
+
+.align-stretch {
+	align-items: stretch;
+}
+
+.self-start {
+	align-self: flex-start;
+}
+
+.self-center {
+	align-self: flex-center;
+}
+
+.self-end {
+	align-self: flex-end;
+}
+
+.self-stretch {
+	align-self: stretch;
+}
+
+.align-stretch {
+	align-items: stretch;
+}
+
+.justify-start {
+	justify-content: flex-start;
+}
+
+.justify-end {
+	justify-content: flex-end;
+}
+
+.justify-center {
+	justify-content: center;
+}
+
+.justify-between {
+	justify-content: space-between;
+}
+
+.justify-around {
+	justify-content: space-around;
+}
+
+/* grid布局 */
+
+.grid {
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.grid.grid-square {
+	overflow: hidden;
+}
+
+.grid.grid-square .cu-tag {
+	position: absolute;
+	right: 0;
+	top: 0;
+	border-bottom-left-radius: 6upx;
+	padding: 6upx 12upx;
+	height: auto;
+	background-color: rgba(0, 0, 0, 0.5);
+}
+
+.grid.grid-square>view>text[class*="cuIcon-"] {
+	font-size: 52upx;
+	position: absolute;
+	color: #8799a3;
+	margin: auto;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	flex-direction: column;
+}
+
+.grid.grid-square>view {
+	margin-right: 20upx;
+	margin-bottom: 20upx;
+	border-radius: 6upx;
+	position: relative;
+	overflow: hidden;
+}
+.grid.grid-square>view.bg-img image {
+	width: 100%;
+	height: 100%;
+	position: absolute;
+}
+.grid.col-1.grid-square>view {
+	padding-bottom: 100%;
+	height: 0;
+	margin-right: 0;
+}
+
+.grid.col-2.grid-square>view {
+	padding-bottom: calc((100% - 20upx)/2);
+	height: 0;
+	width: calc((100% - 20upx)/2);
+}
+
+.grid.col-3.grid-square>view {
+	padding-bottom: calc((100% - 40upx)/3);
+	height: 0;
+	width: calc((100% - 40upx)/3);
+}
+
+.grid.col-4.grid-square>view {
+	padding-bottom: calc((100% - 60upx)/4);
+	height: 0;
+	width: calc((100% - 60upx)/4);
+}
+
+.grid.col-5.grid-square>view {
+	padding-bottom: calc((100% - 80upx)/5);
+	height: 0;
+	width: calc((100% - 80upx)/5);
+}
+
+.grid.col-2.grid-square>view:nth-child(2n),
+.grid.col-3.grid-square>view:nth-child(3n),
+.grid.col-4.grid-square>view:nth-child(4n),
+.grid.col-5.grid-square>view:nth-child(5n) {
+	margin-right: 0;
+}
+
+.grid.col-1>view {
+	width: 100%;
+}
+
+.grid.col-2>view {
+	width: 50%;
+}
+
+.grid.col-3>view {
+	width: 33.33%;
+}
+
+.grid.col-4>view {
+	width: 25%;
+}
+
+.grid.col-5>view {
+	width: 20%;
+}
+
+/*  -- 内外边距 -- */
+
+.margin-0 {
+	margin: 0;
+}
+
+.margin-xs {
+	margin: 10upx;
+}
+
+.margin-sm {
+	margin: 20upx;
+}
+
+.margin {
+	margin: 30upx;
+}
+
+.margin-lg {
+	margin: 40upx;
+}
+
+.margin-xl {
+	margin: 50upx;
+}
+
+.margin-top-xs {
+	margin-top: 10upx;
+}
+
+.margin-top-sm {
+	margin-top: 20upx;
+}
+
+.margin-top {
+	margin-top: 30upx;
+}
+
+.margin-top-lg {
+	margin-top: 40upx;
+}
+
+.margin-top-xl {
+	margin-top: 50upx;
+}
+
+.margin-right-xs {
+	margin-right: 10upx;
+}
+
+.margin-right-sm {
+	margin-right: 20upx;
+}
+
+.margin-right {
+	margin-right: 30upx;
+}
+
+.margin-right-lg {
+	margin-right: 40upx;
+}
+
+.margin-right-xl {
+	margin-right: 50upx;
+}
+
+.margin-bottom-xs {
+	margin-bottom: 10upx;
+}
+
+.margin-bottom-sm {
+	margin-bottom: 20upx;
+}
+
+.margin-bottom {
+	margin-bottom: 30upx;
+}
+
+.margin-bottom-lg {
+	margin-bottom: 40upx;
+}
+
+.margin-bottom-xl {
+	margin-bottom: 50upx;
+}
+
+.margin-left-xs {
+	margin-left: 10upx;
+}
+
+.margin-left-sm {
+	margin-left: 20upx;
+}
+
+.margin-left {
+	margin-left: 30upx;
+}
+
+.margin-left-lg {
+	margin-left: 40upx;
+}
+
+.margin-left-xl {
+	margin-left: 50upx;
+}
+
+.margin-lr-xs {
+	margin-left: 10upx;
+	margin-right: 10upx;
+}
+
+.margin-lr-sm {
+	margin-left: 20upx;
+	margin-right: 20upx;
+}
+
+.margin-lr {
+	margin-left: 30upx;
+	margin-right: 30upx;
+}
+
+.margin-lr-lg {
+	margin-left: 40upx;
+	margin-right: 40upx;
+}
+
+.margin-lr-xl {
+	margin-left: 50upx;
+	margin-right: 50upx;
+}
+
+.margin-tb-xs {
+	margin-top: 10upx;
+	margin-bottom: 10upx;
+}
+
+.margin-tb-sm {
+	margin-top: 20upx;
+	margin-bottom: 20upx;
+}
+
+.margin-tb {
+	margin-top: 30upx;
+	margin-bottom: 30upx;
+}
+
+.margin-tb-lg {
+	margin-top: 40upx;
+	margin-bottom: 40upx;
+}
+
+.margin-tb-xl {
+	margin-top: 50upx;
+	margin-bottom: 50upx;
+}
+
+.padding-0 {
+	padding: 0;
+}
+
+.padding-xs {
+	padding: 10upx;
+}
+
+.padding-sm {
+	padding: 20upx;
+}
+
+.padding {
+	padding: 30upx;
+}
+
+.padding-lg {
+	padding: 40upx;
+}
+
+.padding-xl {
+	padding: 50upx;
+}
+
+.padding-top-xs {
+	padding-top: 10upx;
+}
+
+.padding-top-sm {
+	padding-top: 20upx;
+}
+
+.padding-top {
+	padding-top: 30upx;
+}
+
+.padding-top-lg {
+	padding-top: 40upx;
+}
+
+.padding-top-xl {
+	padding-top: 50upx;
+}
+
+.padding-right-xs {
+	padding-right: 10upx;
+}
+
+.padding-right-sm {
+	padding-right: 20upx;
+}
+
+.padding-right {
+	padding-right: 30upx;
+}
+
+.padding-right-lg {
+	padding-right: 40upx;
+}
+
+.padding-right-xl {
+	padding-right: 50upx;
+}
+
+.padding-bottom-xs {
+	padding-bottom: 10upx;
+}
+
+.padding-bottom-sm {
+	padding-bottom: 20upx;
+}
+
+.padding-bottom {
+	padding-bottom: 30upx;
+}
+
+.padding-bottom-lg {
+	padding-bottom: 40upx;
+}
+
+.padding-bottom-xl {
+	padding-bottom: 50upx;
+}
+
+.padding-left-xs {
+	padding-left: 10upx;
+}
+
+.padding-left-sm {
+	padding-left: 20upx;
+}
+
+.padding-left {
+	padding-left: 30upx;
+}
+
+.padding-left-lg {
+	padding-left: 40upx;
+}
+
+.padding-left-xl {
+	padding-left: 50upx;
+}
+
+.padding-lr-xs {
+	padding-left: 10upx;
+	padding-right: 10upx;
+}
+
+.padding-lr-sm {
+	padding-left: 20upx;
+	padding-right: 20upx;
+}
+
+.padding-lr {
+	padding-left: 30upx;
+	padding-right: 30upx;
+}
+
+.padding-lr-lg {
+	padding-left: 40upx;
+	padding-right: 40upx;
+}
+
+.padding-lr-xl {
+	padding-left: 50upx;
+	padding-right: 50upx;
+}
+
+.padding-tb-xs {
+	padding-top: 10upx;
+	padding-bottom: 10upx;
+}
+
+.padding-tb-sm {
+	padding-top: 20upx;
+	padding-bottom: 20upx;
+}
+
+.padding-tb {
+	padding-top: 30upx;
+	padding-bottom: 30upx;
+}
+
+.padding-tb-lg {
+	padding-top: 40upx;
+	padding-bottom: 40upx;
+}
+
+.padding-tb-xl {
+	padding-top: 50upx;
+	padding-bottom: 50upx;
+}
+
+/* -- 浮动 --  */
+
+.cf::after,
+.cf::before {
+	content: " ";
+	display: table;
+}
+
+.cf::after {
+	clear: both;
+}
+
+.fl {
+	float: left;
+}
+
+.fr {
+	float: right;
+}
+
+/* ==================
+          背景
+ ==================== */
+
+.line-red::after,
+.lines-red::after {
+	border-color: #e54d42;
+}
+
+.line-orange::after,
+.lines-orange::after {
+	border-color: #f37b1d;
+}
+
+.line-yellow::after,
+.lines-yellow::after {
+	border-color: #fbbd08;
+}
+
+.line-olive::after,
+.lines-olive::after {
+	border-color: #8dc63f;
+}
+
+.line-green::after,
+.lines-green::after {
+	border-color: #39b54a;
+}
+
+.line-cyan::after,
+.lines-cyan::after {
+	border-color: #1cbbb4;
+}
+
+.line-blue::after,
+.lines-blue::after {
+	border-color: #0081ff;
+}
+
+.line-purple::after,
+.lines-purple::after {
+	border-color: #6739b6;
+}
+
+.line-mauve::after,
+.lines-mauve::after {
+	border-color: #9c26b0;
+}
+
+.line-pink::after,
+.lines-pink::after {
+	border-color: #e03997;
+}
+
+.line-brown::after,
+.lines-brown::after {
+	border-color: #a5673f;
+}
+
+.line-grey::after,
+.lines-grey::after {
+	border-color: #8799a3;
+}
+
+.line-gray::after,
+.lines-gray::after {
+	border-color: #aaaaaa;
+}
+
+.line-black::after,
+.lines-black::after {
+	border-color: #333333;
+}
+
+.line-white::after,
+.lines-white::after {
+	border-color: #ffffff;
+}
+
+.bg-red {
+	background-color: #e54d42;
+	color: #ffffff;
+}
+
+.bg-orange {
+	background-color: #f37b1d;
+	color: #ffffff;
+}
+
+.bg-yellow {
+	background-color: #fbbd08;
+	color: #333333;
+}
+
+.bg-olive {
+	background-color: #8dc63f;
+	color: #ffffff;
+}
+
+.bg-green {
+	background-color: #39b54a;
+	color: #ffffff;
+}
+
+.bg-cyan {
+	background-color: #1cbbb4;
+	color: #ffffff;
+}
+
+.bg-blue {
+	background-color: #0081ff;
+	color: #ffffff;
+}
+
+.bg-purple {
+	background-color: #6739b6;
+	color: #ffffff;
+}
+
+.bg-mauve {
+	background-color: #9c26b0;
+	color: #ffffff;
+}
+
+.bg-pink {
+	background-color: #e03997;
+	color: #ffffff;
+}
+
+.bg-brown {
+	background-color: #a5673f;
+	color: #ffffff;
+}
+
+.bg-grey {
+	background-color: #8799a3;
+	color: #ffffff;
+}
+
+.bg-gray {
+	background-color: #f0f0f0;
+	color: #333333;
+}
+
+.bg-black {
+	background-color: #333333;
+	color: #ffffff;
+}
+
+.bg-white {
+	background-color: #ffffff;
+	color: #666666;
+}
+
+.bg-shadeTop {
+	background-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.01));
+	color: #ffffff;
+}
+
+.bg-shadeBottom {
+	background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 1));
+	color: #ffffff;
+}
+
+.bg-red.light {
+	color: #e54d42;
+	background-color: #fadbd9;
+}
+
+.bg-orange.light {
+	color: #f37b1d;
+	background-color: #fde6d2;
+}
+
+.bg-yellow.light {
+	color: #fbbd08;
+	background-color: #fef2ced2;
+}
+
+.bg-olive.light {
+	color: #8dc63f;
+	background-color: #e8f4d9;
+}
+
+.bg-green.light {
+	color: #39b54a;
+	background-color: #d7f0dbff;
+}
+
+.bg-cyan.light {
+	color: #1cbbb4;
+	background-color: #d2f1f0;
+}
+
+.bg-blue.light {
+	color: #0081ff;
+	background-color: #cce6ff;
+}
+
+.bg-purple.light {
+	color: #6739b6;
+	background-color: #e1d7f0;
+}
+
+.bg-mauve.light {
+	color: #9c26b0;
+	background-color: #ebd4ef;
+}
+
+.bg-pink.light {
+	color: #e03997;
+	background-color: #f9d7ea;
+}
+
+.bg-brown.light {
+	color: #a5673f;
+	background-color: #ede1d9;
+}
+
+.bg-grey.light {
+	color: #8799a3;
+	background-color: #e7ebed;
+}
+
+.bg-gradual-red {
+	background-image: linear-gradient(45deg, #f43f3b, #ec008c);
+	color: #ffffff;
+}
+
+.bg-gradual-black {
+	background-image: linear-gradient(45deg, #26272f, #414244);
+	color: #f7ebd2;
+}
+
+.bg-gradual-orange {
+	background-image: linear-gradient(45deg, #ff9700, #ed1c24);
+	color: #ffffff;
+}
+
+.bg-gradual-green {
+	background-image: linear-gradient(45deg, #39b54a, #8dc63f);
+	color: #ffffff;
+}
+
+.bg-gradual-purple {
+	background-image: linear-gradient(45deg, #9000ff, #5e00ff);
+	color: #ffffff;
+}
+
+.bg-gradual-pink {
+	background-image: linear-gradient(45deg, #ec008c, #6739b6);
+	color: #ffffff;
+}
+
+.bg-gradual-blue {
+	background-image: linear-gradient(45deg, #0081ff, #1cbbb4);
+	color: #ffffff;
+}
+
+.shadow[class*="-red"] {
+	box-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2);
+}
+
+.shadow[class*="-orange"] {
+	box-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2);
+}
+
+.shadow[class*="-yellow"] {
+	box-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2);
+}
+
+.shadow[class*="-olive"] {
+	box-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2);
+}
+
+.shadow[class*="-green"] {
+	box-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2);
+}
+
+.shadow[class*="-cyan"] {
+	box-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2);
+}
+
+.shadow[class*="-blue"] {
+	box-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2);
+}
+
+.shadow[class*="-purple"] {
+	box-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2);
+}
+
+.shadow[class*="-mauve"] {
+	box-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2);
+}
+
+.shadow[class*="-pink"] {
+	box-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2);
+}
+
+.shadow[class*="-brown"] {
+	box-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2);
+}
+
+.shadow[class*="-grey"] {
+	box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.shadow[class*="-gray"] {
+	box-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.shadow[class*="-black"] {
+	box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
+}
+
+.shadow[class*="-white"] {
+	box-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
+}
+
+.text-shadow[class*="-red"] {
+	text-shadow: 6upx 6upx 8upx rgba(204, 69, 59, 0.2);
+}
+
+.text-shadow[class*="-orange"] {
+	text-shadow: 6upx 6upx 8upx rgba(217, 109, 26, 0.2);
+}
+
+.text-shadow[class*="-yellow"] {
+	text-shadow: 6upx 6upx 8upx rgba(224, 170, 7, 0.2);
+}
+
+.text-shadow[class*="-olive"] {
+	text-shadow: 6upx 6upx 8upx rgba(124, 173, 55, 0.2);
+}
+
+.text-shadow[class*="-green"] {
+	text-shadow: 6upx 6upx 8upx rgba(48, 156, 63, 0.2);
+}
+
+.text-shadow[class*="-cyan"] {
+	text-shadow: 6upx 6upx 8upx rgba(28, 187, 180, 0.2);
+}
+
+.text-shadow[class*="-blue"] {
+	text-shadow: 6upx 6upx 8upx rgba(0, 102, 204, 0.2);
+}
+
+.text-shadow[class*="-purple"] {
+	text-shadow: 6upx 6upx 8upx rgba(88, 48, 156, 0.2);
+}
+
+.text-shadow[class*="-mauve"] {
+	text-shadow: 6upx 6upx 8upx rgba(133, 33, 150, 0.2);
+}
+
+.text-shadow[class*="-pink"] {
+	text-shadow: 6upx 6upx 8upx rgba(199, 50, 134, 0.2);
+}
+
+.text-shadow[class*="-brown"] {
+	text-shadow: 6upx 6upx 8upx rgba(140, 88, 53, 0.2);
+}
+
+.text-shadow[class*="-grey"] {
+	text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.text-shadow[class*="-gray"] {
+	text-shadow: 6upx 6upx 8upx rgba(114, 130, 138, 0.2);
+}
+
+.text-shadow[class*="-black"] {
+	text-shadow: 6upx 6upx 8upx rgba(26, 26, 26, 0.2);
+}
+
+.bg-img {
+	background-size: cover;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+
+.bg-mask {
+	background-color: #333333;
+	position: relative;
+}
+
+.bg-mask::after {
+	content: "";
+	border-radius: inherit;
+	width: 100%;
+	height: 100%;
+	display: block;
+	background-color: rgba(0, 0, 0, 0.4);
+	position: absolute;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: 0;
+}
+
+.bg-mask view,
+.bg-mask cover-view {
+	z-index: 5;
+	position: relative;
+}
+
+.bg-video {
+	position: relative;
+}
+
+.bg-video video {
+	display: block;
+	height: 100%;
+	width: 100%;
+	-o-object-fit: cover;
+	object-fit: cover;
+	position: absolute;
+	top: 0;
+	z-index: 0;
+	pointer-events: none;
+}
+
+/* ==================
+          文本
+ ==================== */
+
+.text-xs {
+	font-size: 20upx;
+}
+
+.text-sm {
+	font-size: 24upx;
+}
+
+.text-df {
+	font-size: 28upx;
+}
+
+.text-lg {
+	font-size: 32upx;
+}
+
+.text-xl {
+	font-size: 36upx;
+}
+
+.text-xxl {
+	font-size: 44upx;
+}
+
+.text-sl {
+	font-size: 80upx;
+}
+
+.text-xsl {
+	font-size: 120upx;
+}
+
+.text-Abc {
+	text-transform: Capitalize;
+}
+
+.text-ABC {
+	text-transform: Uppercase;
+}
+
+.text-abc {
+	text-transform: Lowercase;
+}
+
+.text-price::before {
+	content: "¥";
+	font-size: 80%;
+	margin-right: 4upx;
+}
+
+.text-cut {
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+}
+
+.text-bold {
+	font-weight: bold;
+}
+
+.text-center {
+	text-align: center;
+}
+
+.text-content {
+	line-height: 1.6;
+}
+
+.text-left {
+	text-align: left;
+}
+
+.text-right {
+	text-align: right;
+}
+
+.text-red,
+.line-red,
+.lines-red {
+	color: #e54d42;
+}
+
+.text-orange,
+.line-orange,
+.lines-orange {
+	color: #f37b1d;
+}
+
+.text-yellow,
+.line-yellow,
+.lines-yellow {
+	color: #fbbd08;
+}
+
+.text-olive,
+.line-olive,
+.lines-olive {
+	color: #8dc63f;
+}
+
+.text-green,
+.line-green,
+.lines-green {
+	color: #39b54a;
+}
+
+.text-cyan,
+.line-cyan,
+.lines-cyan {
+	color: #1cbbb4;
+}
+
+.text-blue,
+.line-blue,
+.lines-blue {
+	color: #0081ff;
+}
+
+.text-purple,
+.line-purple,
+.lines-purple {
+	color: #6739b6;
+}
+
+.text-mauve,
+.line-mauve,
+.lines-mauve {
+	color: #9c26b0;
+}
+
+.text-pink,
+.line-pink,
+.lines-pink {
+	color: #e03997;
+}
+
+.text-brown,
+.line-brown,
+.lines-brown {
+	color: #a5673f;
+}
+
+.text-grey,
+.line-grey,
+.lines-grey {
+	color: #8799a3;
+}
+
+.text-gray,
+.line-gray,
+.lines-gray {
+	color: #aaaaaa;
+}
+
+.text-black,
+.line-black,
+.lines-black {
+	color: #333333;
+}
+
+.text-white,
+.line-white,
+.lines-white {
+	color: #ffffff;
+}
+
+/* custom */
+/* ===========padding=========== */
+.text-line-through{
+	text-decoration: line-through;
+}
+
+
+.padding-10,.padding-sm{
+	padding: 10rpx;
+}
+.padding-20,.padding-df{
+	padding: 20rpx;
+}
+.padding-30,.padding-lg{
+	padding: 30rpx;
+}
+.padding-40{
+	padding: 40rpx;
+}
+.padding-50{
+	padding: 50rpx;
+}
+.padding-left-10,.padding-left-sm{
+	padding-left: 10rpx;
+}
+.padding-left-20,.padding-left-df{
+	padding-left: 20rpx;
+}
+.padding-left-30,.padding-left-lg{
+	padding-left: 30rpx;
+}
+.padding-left-40{
+	padding-left: 40rpx;
+}
+.padding-left-50{
+	padding-left: 50rpx;
+}
+
+.padding-right-10,.padding-right-sm{
+	padding-right: 10rpx;
+}
+.padding-right-20,.padding-right-df{
+	padding-right: 20rpx;
+}
+.padding-right-30,.padding-right-lg{
+	padding-right: 30rpx;
+}
+.padding-right-40{
+	padding-right: 40rpx;
+}
+.padding-right-50{
+	padding-right: 50rpx;
+}
+
+.padding-top-10,.padding-top-sm{
+	padding-top: 10rpx;
+}
+.padding-top-20,.padding-top-df{
+	padding-top: 20rpx;
+}
+.padding-top-30,.padding-top-lg{
+	padding-top: 30rpx;
+}
+.padding-top-40{
+	padding-top: 40rpx;
+}
+.padding-top-50{
+	padding-top: 50rpx;
+}
+
+.padding-bottom-10,.padding-bottom-sm{
+	padding-bottom: 10rpx;
+}
+.padding-bottom-20,.padding-bottom-df{
+	padding-bottom: 20rpx;
+}
+.padding-bottom-30,.padding-bottom-lg{
+	padding-bottom: 30rpx;
+}
+.padding-bottom-40{
+	padding-bottom: 40rpx;
+}
+.padding-bottom-50{
+	padding-bottom: 50rpx;
+}
+
+/* ===========margin=========== */
+.margin-10,.margin-sm{
+	margin: 10rpx;
+}
+.margin-20,.margin-df{
+	margin: 20rpx;
+}
+.margin-30,.margin-lg{
+	margin: 30rpx;
+}
+.margin-40{
+	margin: 40rpx;
+}
+.margin-50{
+	margin: 50rpx;
+}
+.margin-left-10,.margin-left-sm{
+	margin-left: 10rpx;
+}
+.margin-left-20,.margin-left-df{
+	margin-left: 20rpx;
+}
+.margin-left-30,.margin-left-lg{
+	margin-left: 30rpx;
+}
+.margin-left-40{
+	margin-left: 40rpx;
+}
+.margin-left-50{
+	margin-left: 50rpx;
+}
+
+.margin-right-10,.margin-right-sm{
+	margin-right: 10rpx;
+}
+.margin-right-20,.margin-right-df{
+	margin-right: 20rpx;
+}
+.margin-right-30,.margin-right-lg{
+	margin-right: 30rpx;
+}
+.margin-right-40{
+	margin-right: 40rpx;
+}
+.margin-right-50{
+	margin-right: 50rpx;
+}
+
+.margin-top-10,.margin-top-sm{
+	margin-top: 10rpx;
+}
+.margin-top-20,.margin-top-df{
+	margin-top: 20rpx;
+}
+.margin-top-30,.margin-top-lg{
+	margin-top: 30rpx;
+}
+.margin-top-40{
+	margin-top: 40rpx;
+}
+.margin-top-50{
+	margin-top: 50rpx;
+}
+
+.margin-bottom-10,.margin-bottom-sm{
+	margin-bottom: 10rpx;
+}
+.margin-bottom-20,.margin-bottom-df{
+	margin-bottom: 20rpx;
+}
+.margin-bottom-30,.margin-bottom-lg{
+	margin-bottom: 30rpx;
+}
+.margin-bottom-40{
+	margin-bottom: 40rpx;
+}
+.margin-bottom-50{
+	margin-bottom: 50rpx;
+}
+
+.solid-bottom-plus{
+	border-bottom: 1rpx solid #e2e2e2;
+}
+
+/* ==========text-cut=========== */
+
+
+
+.text-cut-1 {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+
+.text-cut-2 {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+.text-cut {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		display: block;
+}
+
+.bg-gradual-black {
+	background-image: linear-gradient(45deg, #26272f, #414244);
+	color: #f7ebd2;
+}
+
+.footer-fixed {
+	position: fixed;
+	z-index: 99999;
+	width: 100%;
+	bottom: 0;
+	left: 0;
+}

+ 367 - 0
assets/js/DoormasterSDK-V1.4.js

@@ -0,0 +1,367 @@
+/**
+ * 1. 获取本机蓝牙适配器状态 wx.getBluetoothAdapterState
+ * 2. 初始化蓝牙适配器 wx.openBluetoothAdapter()
+ * 3. 启动蓝牙发现 wx.wx.startBluetoothDevicesDiscovery()
+ * 4. 获取扫描到的所有设备 wx.getBluetoothDevices()
+ * 
+ * 
+ * 参数:
+ * @callback function 回调函数,用于接收返回值
+ * 
+ * 返回值:
+ * ret:{isBluetoothAvailable:true, isBluetoothSearching:true, scanList:[]}
+ * isBluetoothAvailable boolean 蓝牙适配器状态,true表示初始化蓝牙适配器成功
+ * isBluetoothSearching boolean 蓝牙搜索状态,true表示开启蓝牙发现成功
+ * scanList array 搜索的设备列表
+ */
+function scanDevices(callback) {
+  if (typeof callback != "function") {
+    // console.log('Parameter callback is not a function');
+    return;
+  }
+
+  ; //scanList格式如下:
+  //[{RSSI:-xx, advertisServiceUUIDs:[], deviceId:'', name:''},{...}]
+  //注意:Android系统的deviceId是设备的mac地址,iOS系统的deviceId是设备的UUID
+
+  var ret = {
+    isBluetoothAvailable: false,
+    isBluetoothSearching: false,
+    scanList: []
+  };
+  /**
+   * 获取蓝牙适配器状态
+   * 
+   */
+
+  uni.getBluetoothAdapterState({
+    success: function (res) {
+      // console.log("---getBluetoothAdapterState--success:", res)
+      ret.isBluetoothAvailable = res.available;
+      ret.isBluetoothSearching = res.discovering;
+    },
+    fail: function (res) {
+      console.log("---getBluetoothAdapterState--fail:", res);
+    },
+    complete: function (res) {
+      /**
+       * 初始化蓝牙
+       */
+      if (!ret.isBluetoothAvailable) {
+        uni.openBluetoothAdapter({
+          success: function (res) {
+            // console.log("---openBluetoothAdapter--success:", res);
+            ret.isBluetoothAvailable = true;
+            startBluetoothDiscoveryAndScanDevice(ret, callback);
+          },
+          fail: function (res) {
+            // console.log("---openBluetoothAdapter--fail:", res);
+            callback(ret); //蓝牙初始化失败,直接返回,不进行后续搜索操作
+
+            return;
+          }
+        });
+      } else {
+        startBluetoothDiscoveryAndScanDevice(ret, callback);
+      }
+    }
+  });
+}
+
+function startBluetoothDiscoveryAndScanDevice(ret, callback) {
+  /**
+   * 开启蓝牙发现
+   */
+  if (!ret.isBluetoothSearching) {
+    uni.startBluetoothDevicesDiscovery({
+      services: [],
+      allowDuplicatesKey: true,
+      success: function (res) {
+        // console.log("---startBluetoothDevicesDiscovery--success: ", res);
+        ret.isBluetoothSearching = res.isDiscovering;
+      },
+      fail: function (res) {// console.log('---startBluetoothDevicesDiscovery--fail:', res);
+        // 刷新页面后,开启蓝牙发现失败,暂时忽略10008错误
+        // if (res.errCode != 10008) {
+        //   callback(ret);
+        // }
+      },
+      complete: function (res) {
+        // console.log('---startBluetoothDevicesDiscovery--complete:', res)
+        if (res.errCode === 0 || res.errCode === 10008) {
+          scanBluetoothDevice(ret, callback);
+        } else {
+          callback(ret);
+        }
+      }
+    });
+  } else {
+    scanBluetoothDevice(ret, callback);
+  }
+}
+
+function scanBluetoothDevice(ret, callback) {
+  /**
+  * 获取扫描到的所有设备
+  */
+  setTimeout(function () {
+    uni.getBluetoothDevices({
+      success: function (res) {
+        //{devices: Array[11], errMsg: "getBluetoothDevices:ok"}
+        // console.log('---getBluetoothDevices--success:', res);
+        console.log('---getBluetoothDevices--success:', res.devices);
+        var devArr = []; //根据广播UUID进行设备列表筛选
+
+        for (var i = 0; i < res.devices.length; i++) {
+          if (!('advertisServiceUUIDs' in res.devices[i])) {
+            delete res.devices[i];
+            continue;
+          }
+
+          for (let j = 0; j < res.devices[i].advertisServiceUUIDs.length; j++) {
+            if (res.devices[i].advertisServiceUUIDs[j].toUpperCase().indexOf('FEF5') != -1) {
+              var devSn = res.devices[i].name; // console.log("devSn:", devSn);
+
+              if (devSn.indexOf("-") >= 0) {
+                devArr.push({
+                  "deviceId": res.devices[i].deviceId,
+                  "name": devSn.split("-")[1],
+                  "RSSI": res.devices[i].RSSI
+                });
+              }
+            }
+          }
+        }
+
+        ret.scanList = devArr;
+        callback(ret);
+      },
+      fail: function (res) {
+        console.log('---getBluetoothDevices--fail:', res);
+        callback(ret);
+      }
+    });
+  }, 3000);
+}
+/**
+ * 
+ * 参数:
+ * @deviceid String 参考scanDevices方法
+ * @sendData String 发送到设备的开门指令
+ * @callback function 回调函数,用于处理返回值
+ * 
+ * 返回值:
+ * ret{errCode:'', errMsg:'', receiveData:''}
+ * errCode: 错误码, 0表示开门成功
+ * errMsg: 错误信息,Ok表示开门成功
+ * receiveData: 接收的设备消息,消息内容为ac1c8表示开门成功
+ */
+
+
+function openDoor(deviceid, sendData, callback) {
+  var ret = {
+    errCode: 0,
+    errMsg: 'Ok',
+    receiveData: ''
+  };
+
+  if (typeof callback != "function") {
+    ret.errCode = 6;
+    ret.errMsg = 'parameter callback is not a function';
+    callback(ret);
+    return;
+  } else if (typeof deviceid != "string" || deviceid === '') {
+    ret.errCode = 4;
+    ret.errMsg = 'deviceId is not a string type or is empty';
+    callback(ret);
+    return;
+  } else if (typeof sendData != "string" || sendData === '') {
+    ret.errCode = 5;
+    ret.errMsg = 'sendData is not a string type or is empty';
+    callback(ret);
+    return;
+  }
+
+  var serviceId = '';
+  var characteristics = [];
+  var notifyCharacter = '';
+  var writeCharacter = '';
+  var readCharacter = '';
+  var deviceId = deviceid.toUpperCase(); //BLE蓝牙连接
+
+  uni.createBLEConnection({
+    deviceId: deviceId,
+    success: function (res) {
+      // console.log('---createBLEConnection--success:', res);
+
+      /**
+       * 监听特定BLE设备连接状态变化
+       */
+      uni.onBLEConnectionStateChange(function (res) {// 该方法回调中可以用于处理连接意外断开等异常情况
+        // console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`);
+      }); //获取指定设备的所有服务
+
+      uni.getBLEDeviceServices({
+        deviceId: deviceId,
+        success: function (res) {
+          //筛选指定的服务UUID
+          for (var i = 0; i < res.services.length; i++) {
+            if (res.services[i].uuid.toLowerCase().indexOf('0886') != -1 || res.services[i].uuid.toLowerCase().indexOf('ffe0') != -1) {
+              serviceId = res.services[i].uuid;
+              break;
+            }
+          }
+          /**
+           * 获取指定服务下的所有特征值
+           */
+
+
+          uni.getBLEDeviceCharacteristics({
+            deviceId: deviceId,
+            serviceId: serviceId,
+            success: function (res) {
+              for (var i = 0; i < res.characteristics.length; i++) {
+                if (res.characteristics[i].uuid.toLowerCase().indexOf('878b') != -1) {
+                  notifyCharacter = res.characteristics[i].uuid;
+                } else if (res.characteristics[i].uuid.toLowerCase().indexOf('878c') != -1) {
+                  writeCharacter = res.characteristics[i].uuid;
+                  readCharacter = res.characteristics[i].uuid;
+                }
+              }
+              /**
+               * 启用低功耗蓝牙设备特征值变化时的 notify 功能
+               */
+
+
+              uni.notifyBLECharacteristicValueChange({
+                deviceId: deviceId,
+                serviceId: serviceId,
+                characteristicId: notifyCharacter,
+                state: true,
+                success: function (res) {// console.log('---notifyBLECharacteristicValueChange--success:', res.errMsg);
+                }
+              });
+              /**
+               * 监听低功耗蓝牙设备的特征值变化
+               */
+
+              uni.onBLECharacteristicValueChange(function (res) {
+                // console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`);
+                let buffer = res.value;
+                let dataView = new DataView(buffer);
+                let receiveData = '';
+
+                for (let i = 0; i < buffer.byteLength; i++) {
+                  receiveData += dataView.getUint8(i).toString(16);
+                }
+
+                if (sendData.length <= 20) {
+                  // 向蓝牙设备发送20字节16进制数据,如果不超过20字节数据,监听低功耗蓝牙设备的特征值变化,如果超过,就不监听
+                  if (receiveData != 'ac1c8') {
+                    ret.errCode = 7;
+                    ret.errMsg = "paramater 'sendData' is incorrect.";
+                  }
+
+                  ret.receiveData = receiveData;
+                  callback(ret);
+                }
+              }); //向蓝牙设备发送20字节16进制数据,超过20字节数据,分包续传
+
+              var data = sendData;
+              var buffer_size = data.length > 20 ? data.length / 2 : 20;
+              var buffer = new ArrayBuffer(buffer_size);
+              var dataView = new DataView(buffer);
+
+              for (let i = 0; i < data.length / 2; i++) {
+                var subData = data.slice(2 * i, 2 * i + 2);
+                dataView.setUint8(i, parseInt('0x' + subData));
+              }
+              /**
+               * 写入特征值下的二进制数据
+               * 
+               */
+
+
+              setTimeout(function () {
+                var count = 0;
+
+                if (buffer_size == 20) {
+                  count = 1;
+                } else {
+                  count = 2;
+                }
+
+                var send_data_array = new Array();
+
+                for (let i = 0; i < count; i++) {
+                  var start_buffer = i * 20;
+                  var end_buffer = (i + 1) * 20;
+
+                  if (end_buffer > buffer.byteLength) {
+                    end_buffer = buffer.byteLength;
+                  }
+
+                  var buffer_content = buffer.slice(start_buffer, end_buffer);
+
+                  if (buffer_content.byteLength > 0) {
+                    send_data_array.push(buffer_content);
+                  }
+                }
+
+                var send_index = 0;
+                send_bledata_device(send_index, send_data_array);
+
+                function send_bledata_device(send_index, send_data_array) {
+                  // console.log("----deviceId=" + deviceId + "--serviceId=" + serviceId + "--send_index=" + send_index);                 
+                  uni.writeBLECharacteristicValue({
+                    deviceId: deviceId,
+                    serviceId: serviceId,
+                    characteristicId: writeCharacter,
+                    value: send_data_array[send_index],
+                    success: function (res) {
+                      console.log('++++++++writeBLECharacteristicValue-success:', res);
+
+                      if (send_index < send_data_array.length - 1) {
+                        setTimeout(function () {
+                          send_index += 1;
+                          send_bledata_device(send_index, send_data_array);
+                        }, 250);
+                      } else {
+                        ret.errCode = 0;
+                        callback(ret);
+                      }
+                    },
+                    fail: function (res) {
+                      ret.errCode = res.errCode; //3
+
+                      ret.errMsg = 'writeBLECharacteristicValue fail';
+                      console.log('++++++++writeBLECharacteristicValue-fail-errorCode:', ret.errCode);
+                      callback(ret);
+                    }
+                  });
+                }
+              }, 500);
+            },
+            fail: function (res) {
+              ret.errCode = res.errCode; //2
+
+              ret.errMsg = 'getBLEDeviceCharacteristics fail';
+              callback(ret);
+            }
+          });
+        }
+      });
+    },
+    fail: function (res) {
+      ret.errCode = res.errCode; //1
+
+      ret.errMsg = 'createBLEConnection fail';
+      callback(ret);
+    }
+  });
+}
+
+module.exports = {
+  scanDevices: scanDevices,
+  openDoor: openDoor
+};

+ 123 - 0
comps/dt_custom_bar.vue

@@ -0,0 +1,123 @@
+<template>
+  <view>
+    <view :style="{ background: background }" class="custom-header-container">
+      <view :style="{height:getStausBarHeight + 'px'}" class="custom-header-status-bar"></view>
+      <view :class="{'ios-center': isIos }" class="custom-header-top-container">
+        <view :style="{color: color}" :class="{isIos: isIos}" class="custom-back-btn iconfont" v-if="showBack" @tap="backTap">
+			<image v-if="color!='#ffffff'" src="http://139.9.103.171:1888/img/image/ic_back_black.png" mode="widthFix" style="width: 20px;"></image>
+			<image v-if="color=='#ffffff'" src="http://139.9.103.171:1888/img/image/ic_back_white.png" mode="widthFix" style="width: 20px;"></image>
+		</view>
+        <view :style="{color: color}" :class="[{'ios-center': isIos },{'android-left-30':!isIos&&!showBack},{'android-left-80':!isIos&&showBack}]" class="custom-header-title" >{{ title }}</view></view>
+    </view>
+    <view :style="{ height: getStausBarHeight + (isIos ? 45 : 48) + 'px' }" class="custom-header-height"></view>
+  </view>
+</template>
+<script>
+export default {
+    props: {
+      title:{
+        type:String,
+		default:''
+	  },
+      background: {
+        type: String,
+		default:'transparent'
+      },
+      color: {
+        type: String,
+		default:'#ffffff'
+      },
+      showBack: {
+        type: Boolean,
+		default:false
+      },
+    },
+    computed: {
+      getStausBarHeight() {
+        try {
+          const res = uni.getSystemInfoSync();
+          return res.statusBarHeight;
+        } catch(e) {}
+      },
+      isIos() {
+        return uni.getSystemInfoSync().system.indexOf('iOS') > -1
+      }
+    },
+    methods: {
+      backTap() {
+		uni.navigateBack({
+			delta:1
+		})
+      }
+    }
+  }
+</script>
+<style scoped lang="scss">
+	.custom-header-top-container {
+		display:flex;
+		flex-flow:row nowrap;
+		justify-content:flex-start;
+		width:100%;
+		align-items:center;
+		&.ios-center {
+		 justify-content:center;
+	  }
+	}
+	.custom-header-container {
+		z-index:9;
+		width:750upx;
+		display:flex;
+		flex-direction:column;
+		align-items:center;
+		position:fixed;
+		top:0;
+	}
+	.custom-back-btn {
+		height:48px;
+		line-height:48px;
+		width:40px;
+		margin:0;
+		padding:0;
+		border-radius:0 !important;
+		display:flex;
+		align-items:center;
+		justify-content:center;
+		position:absolute;
+		left:0upx;
+		font-size:18px;
+		border-radius:5px;
+		font-weight:500;
+		color:#FFFFFF;
+		&:active {
+		 background:#0D72DF;
+	   }
+	  &.isIos {
+		line-height:45px;
+		height:45px;
+	 }
+	}
+	.custom-header-status-bar {
+		width:100%;
+		top:0;
+		position:sticky;
+		z-index:100;
+	}
+	.custom-header-title {
+		height:48px;
+		line-height:48px;
+		font-size:16px;
+		color:#FFFFFF;
+		&.ios-center {
+			margin-left: 0;
+			line-height:45px;
+			height:45px;
+		}
+		&.android-left-30{
+			margin-left: 30upx;
+		}
+		&.android-left-80{
+			margin-left: 80upx;
+		}
+			
+	}
+</style>

+ 157 - 0
comps/dt_empty.vue

@@ -0,0 +1,157 @@
+<template>
+  <view class="empty-wrap" v-if="type != 0" :style="{'height':wrapHeight,'backgroundColor':wrapBgColor}">
+    <view class="load-content" :style="{'background-color':_config.bgColor,'z-index':zIndex,'paddingTop':loadingPaddingTop}">
+      <view class="load-error" :style="_errorStyle">
+        <template v-if="type === 1">
+          <image :src="_config.dt_nodata" mode="widthFix"></image>
+        </template>
+        <template v-if="type === 2">
+          <image :src="_config.dt_error" mode="widthFix"></image>
+        </template>
+      </view>
+      <view class="load-tips">
+        <text>{{ tips }}</text>
+        <slot></slot>
+      </view>
+    </view>
+
+    <view
+      class="load-empty"
+      v-if="type == -1"
+      :style="{ top: _config.blankTop + 'px' }"
+    ></view>
+  </view>
+</template>
+<script>
+export default {
+	data(){
+		return{
+			config: {
+			  width:'160',  // 图片宽度 upx
+			  blankTop:'0',  // 空白距离顶部位置 px
+			  icon_nodata: 'http://139.9.103.171:1888/img/image/noData.png',
+			  icon_error: 'http://139.9.103.171:1888/img/image/noData.png',
+			  is_opt: false
+			}	
+		}
+	},
+  props: {
+    type: {
+      type: Number,
+      default: 0 // -1初始化,0无,1空,2错误
+    },
+    tips: {
+      type: String,
+      default: '暂无数据'
+    },
+	wrapHeight:{
+		type: String,
+		default: '100%'
+	},
+	wrapBgColor:{
+		type:String,
+		default: '#f2f2f2'
+	},
+	loadingPaddingTop:{
+		type: String,
+		default: '40%'
+	},
+    // config:{
+    //   type: Object,
+    //   default: {
+    //     width:'160',  // 图片宽度 upx
+    //     blankTop:'0',  // 空白距离顶部位置 px
+    //     icon_nodata: 'http://139.9.103.171:1888/img/image/noData.png',
+    //     icon_error: 'http://139.9.103.171:1888/img/image/noData.png',
+    //     is_opt: false
+    //   }
+    // },
+    zIndex:{
+      type: [String,Number],
+      default: '500'
+    },
+  },
+  computed:{
+    _config(){
+      let _config = this.config || {}
+      _config = Object.assign(_config,{
+        bgColor:'transparent', // 背景色
+        width:'160',  // 图片宽度 upx
+        blankTop:'0',  // 空白距离顶部位置 px
+        dt_nodata: 'http://139.9.103.171:1888/img/image/noData.png',
+        dt_error: 'http://139.9.103.171:1888/img/image/noData.png',
+        is_opt: false
+      })
+      return _config
+    },
+    _errorStyle(){
+      return 'max-width:'+uni.upx2px(this._config.width)+'px;'
+    }
+  },
+  methods:{
+    // init(config){
+    //   let _config = config || {}
+    //   _config = Object.assign(_config,{
+    //     zIndex:'500', // 图标层级
+    //     bgColor:'transparent', // 背景色
+    //     width:'160',  // 图片宽度 upx
+    //     blankTop:'0',  // 空白距离顶部位置 px
+    //     dt_nodata: 'http://139.9.103.171:1888/img/image/comps/dt_nodata.png',
+    //     dt_error: 'http://139.9.103.171:1888/img/image/comps/dt_nodata.png',
+    //     is_opt: false
+    //   })
+    //   this.errorStyle = 'max-width:'+uni.upx2px(_config.width)+'px'
+    //   this.contentStyle = `
+    //     background-color:${relConfig.bgColor};
+    //     z-index:${relConfig.zIndex};
+    //   `;
+    //   this.relConfig = _config
+    // },
+    // onPageLoad(){
+    //   this.init(this.config)
+    // }
+  }
+}
+</script>
+<style lang="scss">
+.empty-wrap {
+  width: 100%;
+  .load-content {
+    position: relative;
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: center;
+    z-index: 500;
+  }
+
+  .load-error {
+    max-width: 200upx;
+    max-height: 204upx;
+
+    image {
+      max-width: 100%;
+      max-height: 100%;
+    }
+  }
+  .load-tips {
+    width: 100%;
+    text-align: center;
+    color: #999999;
+    font-size: 24upx;
+    word-break: break-all;
+    padding: 30upx;
+    color: #666;
+  }
+}
+
+.load-empty {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background: $dt-bg-color-grey;
+  z-index: 1000;
+}
+</style>

+ 228 - 0
comps/dt_goods_list_h.vue

@@ -0,0 +1,228 @@
+<template>
+  <view class="content" :style="{backgroundImage: 'url('+(dataItem.path1?dataItem.path1:'')+')'}" @tap="tapMore">
+	  <view class="banner">
+		  <!-- <view class="name">111</view>
+		  <view class="explain">111</view>
+		  <view class="gotosee">去看看</view> -->
+	  </view>
+	  <scroll-view v-if="dataList.length>0" class="scroll-view" scroll-x="true" >
+	    <view class="goods_list">
+	  		<view class="goods_item" v-for="(item,index) in dataList" :key="index" @tap="jumpGoodsDes(item.id)">
+	  		  <view class="goods_img">
+	  		    <image :src="item.thumbnail|| 'http://139.9.103.171:1888/img/image/goods_def.png'"></image>
+	  		    <view class="goods_sell_out_tip" v-if="false">补货中</view>
+	  		  </view>
+	  		  <!-- <view class="goods_info">
+	  			 <view class="goods_name dt-text-row-two">
+	  				<view class="type">自营</view>
+	  				{{item.name}}
+	  			</view>
+	  			  <view class="goods_bottom">
+	  					  <view class="goods_price">{{item.price}}</view>
+	  					  <image v-if="!share" src="http://139.9.103.171:1888/img/image/shopCar2.png" class="goods_buy_icon"></image>
+	  					  <image v-if="share" src="http://139.9.103.171:1888/img/image/share_team_goods.png" class="goods_buy_icon"></image>
+	  			  </view> 
+	  		  </view> -->
+	  		 <!-- <view class="goods_info">
+	  		    <view class="goods_top">
+	  		      <view class="goods_time" v-if="false">10分钟</view>
+	  		      <view class="goods_title dt-text-row-two">{{item.name}}</view>
+	  		    </view>
+	  		    <view class="goods_des">{{item.caption}}</view>
+	  		    <view class="goods_active" >
+	  		    </view>
+	  		    <view class="goods_bottom">
+	  		      <view class="sell_info">
+	  		        <view class="sell_price">
+	  		          <text>¥{{item.price}}</text>
+	  		          <text>{{item.marketPrice?"¥"+item.marketPrice:''}}</text>
+	  		        </view>
+	  		        <view class="sell_count">销量{{item.sales?item.sales:0}}笔</view>
+	  		      </view>
+	  		      <view class="buy">购买</view>
+	  		    </view>
+	  		  </view> -->
+				 <view class="dt-text-row-one" style="font-size:30upx;font-weight:bold;color:rgba(51,51,51,1);text-align: center;">
+					{{item.name}}
+				</view>
+				<view class="dt-text-row-two" style="font-size:24upx;color:rgba(51,51,51,1);text-align: center;margin-top: 16upx;">
+					{{item.caption?item.caption:''}}
+				</view>
+	  		</view>
+	  		<view class="goods_item"  @tap="tapMore">
+	  			<view style="width: 232upx;height:100%;display: flex;align-items: center;justify-content: center;">
+	  				<view class="text">查看更多</view>
+	  			</view>
+	  		</view>
+	  	</view>
+	  </scroll-view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    dataList: {
+      type: Array,
+      default: []
+    },
+	share: {
+		type:Boolean,
+		default: false
+	},
+	dataItem: {
+		type:Object,
+		default:{}
+	}
+  },
+  data() {
+    return {};
+  },
+  methods: {
+	  tapMore() {
+	    this.$emit("more");
+	  },
+    jumpGoodsDes(id) {
+      console.log(id);
+      uni.navigateTo({
+        url: "/pagesM/pages/goods_des?id=" + id
+      })
+    }
+  },
+  created() { }
+};
+</script>
+
+<style lang="scss">
+	.content{
+		// border-radius: 20upx;
+		background-repeat: no-repeat;
+		background-size: 100% 100%;
+		margin: 0 20upx;
+	}
+	.banner{
+		height:229upx;
+		background-color: transparent;
+		// border-radius:10upx 10upx 0px 0px;
+		// padding-left: 53upx;
+		// padding-top: 29upx;
+		.name{
+			font-size:42upx;
+			height: 42upx;
+			font-family:PingFang SC;
+			font-weight:800;
+			color:rgba(255,255,255,1);
+		}
+		.explain{
+			margin-top: 18upx;
+			height:53upx;
+			font-size:24upx;
+			font-family:PingFang SC;
+			font-weight:400;
+			color:rgba(255,255,255,1);
+		}
+		.gotosee{
+			margin-top: 21upx;
+			border-radius: 25upx;
+			height:50upx;
+			width:100upx;
+			font-size: 24upx;
+			text-align: center;
+			line-height: 50upx;
+			background-color: $dt-color-primary;
+			color:#fff
+		}
+	}
+	.scroll-view{
+		background-color: transparent;
+		height: 468upx;
+	}
+.goods_list {
+	display: flex;
+  .goods_item {
+	// margin: 5.1upx;
+	margin: 0 32upx;
+	margin-bottom: 12upx;
+	width: 176upx;
+	display: flex;
+	flex-direction: column;
+    .goods_img {
+      position: relative;
+      width:176upx;
+      height:225upx;
+	  margin-top: 25upx;
+      image {
+        width:176upx;
+        height:176upx;
+		position: absolute;
+		top: 50%;
+		transform: translateY(-50%);
+      }
+      .goods_sell_out_tip {
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translate(-50%, -50%);
+        width: 98upx;
+        height: 98upx;
+        background: rgba(0, 0, 0, 1);
+        opacity: 0.6;
+        border-radius: 50%;
+        font-size: 22upx;
+        color: #fff;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: center;
+      }
+    }
+	.goods_info{
+		margin: 17upx 0;
+		.type{
+			display: inline-block;
+			background-color: red;
+			color: #fff;
+			font-size: 20upx;
+			border-radius: 6upx;
+			line-height: 20upx;
+			padding: 5upx;
+		}
+		.goods_name{
+			height:63upx;
+			font-size:23upx;
+			font-weight:400;
+			color:rgba(51,51,51,1);
+			line-height:31upx;
+		}
+		.goods_bottom{
+			display: flex;
+			justify-content: space-between;
+			margin-top: 25upx;
+			.goods_price_icon{
+				display: inline-block;
+				font-size:24upx;
+				color:$dt-color-primary;
+				line-height:31upx;
+			}
+			.goods_price{
+				font-size:24upx;
+				font-weight:bold;
+				color:$dt-color-primary;
+				line-height:31upx;
+			}
+			.goods_buy_icon{
+				width:30upx;
+				height:30upx;
+			}
+		}
+	}
+    
+	
+  }
+  .text {
+    font-size:24upx;
+    font-weight:400;
+    color:rgba(102,102,102,1);
+  }
+}
+</style>

+ 250 - 0
comps/dt_goods_list_home.vue

@@ -0,0 +1,250 @@
+<template>
+  <view class="goods_list">
+    <view class="goods_item" v-for="(item,index) in dataList" :key="index" @tap="jumpGoodsDes(item.id)">
+        <scroll-view scroll-x="true">
+        	<view class="goods_img">
+				<view v-for="(imgsItem,imgsIndex) in  item.productImages" :key="imgsIndex">
+					<image :src="imgsItem.large||'http://139.9.103.171:1888/img/image/goods_def.png'" mode="widthFix"></image>
+				</view>
+			</view>
+        </scroll-view>
+      <view class="goods_info">
+        <view class="mid-wrap">
+          <view class="goods_top">
+            <view class="goods_time" v-if="false">10分钟</view>
+            <view class="goods_title dt-text-row-two">{{item.name}}</view>
+          </view>
+          <view class="goods_des one_line_ellipsis">{{item.caption}}</view>
+        </view>
+        <view class="goods_active" v-if="false">
+          <view class="active_item">特价抢购</view>
+          <view class="active_item">1元换购</view>
+          <view class="active_item">包邮</view>
+        </view>
+		<scroll-view scroll-x="true" style="width: 100%;margin: 20upx 0 12upx;">
+			<view v-if="item.promotion" style="display: flex;white-space: nowrap;">
+				<view v-if="item.promotion.coupon" style="
+				padding: 4rpx 8rpx;
+				font-size: 20upx;
+				color: #DB4444;
+				background:rgba(219,68,68,0.1);
+				margin-right: 5upx;
+				border-radius: 25px;">
+				{{item.promotion.coupon.name}}
+				</view>
+				<view v-if="item.promotion.freeShipping" style="
+				padding: 4rpx 8rpx;
+				font-size: 20upx;
+				color: #DB4444;
+				background:rgba(219,68,68,0.1);
+				margin-right: 5upx;
+				border-radius: 25px;">
+				{{item.promotion.freeShipping.name}}
+				</view>
+				<view v-if="item.promotion.gifts.length>0" 
+				v-for="(giftsItem,giftsIndex) in item.promotion.gifts"
+				:key="giftsIndex"
+				style="
+				padding: 4rpx 8rpx;
+				font-size: 20upx;
+				color: #DB4444;
+				background:rgba(219,68,68,0.1);
+				margin-right: 5upx;
+				border-radius: 25px;">
+				{{giftsItem.name}}
+				</view>
+				<view v-if="item.promotion.moneyOffs.length>0" 
+				v-for="(moneyOffs,moneyOffsIndex) in item.promotion.moneyOffs"
+				:key="moneyOffsIndex"
+				style="
+				padding: 4rpx 8rpx;
+				font-size: 20upx;
+				color: #444FDB;
+				background:rgba(68,79,219,0.1);
+				margin-right: 5upx;
+				border-radius: 25px;">
+				{{moneyOffs.name}}
+				</view>
+			</view>
+		</scroll-view>
+        <view class="goods_bottom">
+          <view class="sell_info">
+            <view class="sell_price">
+				<text style="font-size: 20upx;margin-top: 10upx;color: #ee1515;">¥</text>
+              <text class="price">{{item.price}}</text>
+			  <text>{{item.marketPrice?"¥"+item.marketPrice:''}}</text>
+            </view>
+            <!-- <view class="sell_count">销量{{item.sales}}笔</view> -->
+          </view>
+          <!-- <image src="/static/image/shop_car_icon.png" class="buy"></image> -->
+		  <view style="font-weight: 500;font-size:32upx;color: #fff;line-height: 60upx;padding: 0 20upx;background-color: #DB4444;border-radius: 25px;">立即购买</view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    height:{
+      type:[String,Number],
+      default:70
+    },
+    dataList: {
+      type: Array,
+      default: []
+    }
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    midStyle(){
+      return 'height:'+uni.upx2px(this.height)+'px'
+    },
+  },
+  methods: {
+    jumpGoodsDes(id) {
+      console.log(id);
+      uni.navigateTo({
+        url: "/pagesM/pages/goods_des?id=" + id
+      })
+    }
+  },
+  created() { }
+};
+</script>
+
+<style lang="scss">
+.goods_list {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  // background: #F2F2F2;
+  background: transparent;
+  width: 100%;
+  .goods_item {
+    border-radius: 10upx;
+    background: #fff;
+    overflow: hidden;
+	padding: 30upx;
+	margin: 0 20upx 20upx;
+	width: 100%;
+    .goods_img {
+		width: 100%;
+      display: flex;
+      align-items: center;
+	  
+      image {
+		  display: block;
+		border-radius: 10upx;
+        width: 210upx;
+        height: 210upx;
+		margin-right: 12upx;
+      }
+    }
+    .goods_info {
+		margin-top: 20upx;
+      box-sizing: border-box;
+      .mid-wrap{
+        .goods_top {
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          .goods_time {
+            font-size: 18upx;
+            border-radius: 4upx;
+            background: $dt-color-primary;
+            padding: 5upx 10upx;
+            color: #fff;
+            margin-right: 10upx;
+          }
+          .goods_title {
+            flex: 1;
+            color: #3A3A3A;
+            font-size: 28upx;
+			font-weight: bold;
+            letter-spacing: 1upx;
+          }
+        }
+        .goods_des {
+          font-size: 24upx;
+          color: #C1C1C1;
+          margin-top: 10upx;
+        }
+      }
+      .goods_active {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        flex-wrap: wrap;
+        margin-top: 10upx;
+        .active_item {
+          // border-radius: 4upx;
+          padding: 5upx 10upx;
+          color: #ee1515;
+          font-size: 18upx;
+          margin-right: 10upx;
+          position: relative;
+          margin-bottom: 10upx;
+          //  border: 2upx solid #ee1515;
+        }
+        .active_item::after {
+          display: flex;
+          box-sizing: border-box;
+          align-items: center;
+          content: "";
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 200%;
+          height: 200%;
+          transform: scale(0.5);
+          transform-origin: 0 0;
+          border: 1upx solid #ee1515;
+          border-radius: 4upx;
+          pointer-events: none;
+        }
+      }
+      .goods_bottom {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        align-items: center;
+		padding: 0 10upx 10upx;
+        .sell_info {
+          display: flex;
+          flex-direction: column;
+          .sell_price {
+            display: flex;
+            flex-direction: row;
+            align-items: center;
+            .price{
+              font-size: 36upx;
+			  font-weight:800;
+              color: #DB4444;
+            }
+			text:last-child {
+			  color: #888888;
+			  font-size: 22upx;
+			  text-decoration: line-through;
+			  margin-left: 20upx;
+			  margin-top: 10upx;
+			}
+          }
+          .sell_count {
+            margin-top: 10upx;
+            font-size: 22upx;
+            color: #888888;
+          }
+        }
+        .buy {
+          width: 40upx;
+          height: 40upx;
+        }
+      }
+    }
+  }
+}
+</style>

+ 212 - 0
comps/dt_goods_list_home02.vue

@@ -0,0 +1,212 @@
+<template>
+	<view class="goods_list">
+	    <view class="goods_item" v-for="(item,index) in dataList" :key="index" @tap="jumpGoodsDes(item.id)">
+	      <view class="goods_img">
+			  <view v-if="imgsIndex==0" v-for="(imgsItem,imgsIndex) in  item.productImages" :key="imgsIndex">
+			  	<image :src="imgsItem.large||'http://139.9.103.171:1888/img/image/goods_def.png'" mode="widthFix"></image>
+			  </view>
+	        <view class="goods_sell_out_tip" v-if="false">补货中</view>
+	      </view>
+	      <view class="goods_info">
+				<view class="goods_top">
+				  <view class="goods_time" v-if="false">10分钟</view>
+				  <view class="goods_title dt-text-row-one">{{item.name}}</view>
+				</view>
+				<view class="goods_des dt-text-row-one">{{item.caption?item.caption:''}}</view>
+				<view style="position: relative;margin: 0 auto;">
+					<image src="http://139.9.103.171:1888/img/image/ic_boom.png"  style="width: 230upx;height: 128rpx;"></image>
+					<!-- <view style="position: absolute;top: 40upx;left:-12upx;text-decoration: line-through;font-size: 22upx;color: #999;">
+						{{item.marketPrice?"¥"+item.marketPrice:''}}
+					</view> -->
+				</view>
+				<view style="position: relative;width: 350upx;display: flex;flex-direction: column;align-items: center;">
+					<image src="http://139.9.103.171:1888/img/image/price_bg.png"  style="width: 350upx;height: 60rpx;"></image>
+					<view style="position: absolute;left: 20upx;right:20upx;top:0;bottom:0;display: flex;justify-content: space-between;align-items: center;">
+						<view style="display: flex;color: #fff;font-weight: bold;">
+							<view style="margin-top: 10upx;font-size: 24upx;">¥</view>
+							<view style="margin-top: 10upx;">{{item.price}}</view>
+							<view style="text-decoration: line-through;font-size: 20upx;margin-top: 14upx;margin-left: 10upx;color: #f7f7f7;font-weight: 100;">{{item.marketPrice?"¥"+item.marketPrice:''}}</view>
+						</view>
+						<view style="color:#f92325;font-size: 26upx;font-weight: bold;">立即加购</view>
+					</view>
+				</view>
+	      </view>
+	    </view>
+	  </view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			};
+		},
+		props: {
+			dataList: {
+			  type: Array,
+			  default: []
+			},
+			bgColor:{
+					type: String,
+					default:'#f2f2f2'
+				},
+		},
+		
+		methods: {
+		  jumpGoodsDes(id) {
+		    console.log(id);
+		    uni.navigateTo({
+		      url: "/pagesM/pages/goods_des?id=" + id
+		    })
+		  }
+		},
+	}
+</script>
+
+<style lang="scss">
+	.goods_list {
+		
+	  .goods_item {
+		  border-radius: 20upx;
+		  background-color: #fff;
+		  margin-bottom: 10upx;
+	    display: flex;
+	    flex-direction: row;
+	    padding: 20upx;
+	    .goods_img {
+	      position: relative;
+	      width: 290upx;
+	      height: 300upx;
+	      image {
+	        width: 290upx;
+	        height: 300upx;
+	      }
+	      .goods_sell_out_tip {
+	        position: absolute;
+	        left: 50%;
+	        top: 50%;
+	        transform: translate(-50%, -50%);
+	        width: 98upx;
+	        height: 98upx;
+	        background: rgba(0, 0, 0, 1);
+	        opacity: 0.6;
+	        border-radius: 50%;
+	        font-size: 22upx;
+	        color: #fff;
+	        display: flex;
+	        flex-direction: row;
+	        align-items: center;
+	        justify-content: center;
+	      }
+	    }
+	    .goods_info {
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+	      padding-left: 26upx;
+	      flex: 1;
+	      // .mid-wrap{
+	      //   height:150rpx;
+	        .goods_top {
+	          display: flex;
+	          flex-direction: row;
+	          align-items: center;
+	          .goods_time {
+	            font-size: 18upx;
+	            border-radius: 4upx;
+	            background: $dt-color-primary;
+	            padding: 5upx 10upx;
+	            color: #fff;
+	          }
+	          .goods_title {
+	            flex: 1;
+	            color: #3A3A3A;
+				font-weight:bold;
+	            font-size: 28upx;
+	            letter-spacing: 1upx;
+	          }
+	        }
+	        .goods_des {
+	          font-size: 24upx;
+			  margin: 10upx 0;
+	          color: #999;
+			  font-weight: 500;
+	        }
+	      // }
+	      .goods_active {
+	        display: flex;
+	        flex-direction: row;
+	        align-items: center;
+	        flex-wrap: wrap;
+	        .active_item {
+	          // border: 1upx solid #ee1515;
+	          // border-radius: 4upx;
+	          padding: 5upx 10upx;
+	          color: #ee1515;
+	          font-size: 18upx;
+	          margin-right: 20upx;
+	          position: relative;
+	          margin-bottom: 10upx;
+	        }
+	        .active_item::after {
+	          display: flex;
+	          box-sizing: border-box;
+	          align-items: center;
+	          content: "";
+	          position: absolute;
+	          top: 0;
+	          left: 0;
+	          width: 200%;
+	          height: 200%;
+	          transform: scale(0.5);
+	          transform-origin: 0 0;
+	          border: 1upx solid #ee1515;
+	          border-radius: 4upx;
+	          pointer-events: none;
+	        }
+	      }
+	      .goods_bottom {
+	        display: flex;
+	        flex-direction: row;
+	        justify-content: space-between;
+	        align-items: center;
+	        .sell_info {
+	          display: flex;
+	          flex-direction: column;
+	          .sell_price {
+	            display: flex;
+	            flex-direction: row;
+	            align-items: center;
+	            text{
+	              font-size: 36upx;
+	              color: #DB4444;
+	            }
+	            text:last-child {
+	              color: #888888;
+	              font-size: 22upx;
+	              text-decoration: line-through;
+	              margin-left: 20upx;
+	            }
+	          }
+	          .sell_count {
+	            margin-top: 10upx;
+	            font-size: 22upx;
+	            color: #888888;
+	          }
+	        }
+	        .buy {
+	          width: 100upx;
+	          height: 50upx;
+	          line-height: 50upx;
+	          background: $dt-color-primary;
+	          border-radius: 25upx;
+	          font-size: 0.8rem;
+	          text-align: center;
+	          color: #fff;
+	        }
+	      }
+	    }
+	  }
+	}
+</style>

+ 305 - 0
comps/dt_login.vue

@@ -0,0 +1,305 @@
+<template>
+  <FootDialog direction="center" :config="config" :isTitle="false" :isRadius="false" :visible.sync="dialogShow" @close="$emit('close')">
+	 <!-- #ifdef MP-WEIXIN -->
+		<template slot="main">
+		  <view class="dt-login-wrap">
+		    <view class="title">您还没登录</view>
+		    <view class="subtitle">请先登录再进行操作</view>
+		    <image class="login-icon" src="/static/login1.png" ></image>
+			
+		    <view class="btn-wrap">
+		      <button class="btn-base" 
+		        hover-class="button-hover"
+		        @tap="hide">暂不登录</button>
+		      <button class=" btn-base "
+			   style="color: #2f7ff5;"
+		        hover-class="button-hover"
+		        open-type="getPhoneNumber" 
+		        @getphonenumber="tapGetPhoneNumber">立即登录</button>
+		    </view>
+		  </view>
+		</template>
+	<!-- #endif -->
+    <!-- #ifdef APP-PLUS -->
+		<template slot="main">
+			<view class="dt-login-wrap">
+			  <view class="title">登 录</view>
+			  <view>
+				  <view>
+				  	<text>账号:</text>
+				  	<input v-model="formData.account" type="number" placeholder="请输入账号"/>
+				  </view> 
+				  <view class="line"></view>
+				  <view>
+				  	<text>密码:</text>
+				  	<input v-model="formData.passwd"  placeholder="请输入密码" />
+				  </view> 
+			  </view>
+			  <view class="btn-wrap">
+			    <button class="btn-base dt-color-primary" 
+			      hover-class="button-hover"
+			      @tap="touristLogin">登 录</button>
+			  </view>
+			</view>
+		</template>		
+    <!-- #endif -->
+	
+  </FootDialog>
+</template>
+<script>
+import FootDialog from './foot_dialog.vue'
+import { setTimeout } from 'timers';
+
+export default {
+  components: {
+    FootDialog
+  },
+  data () {
+    return {
+      config: {
+        mainBgColor: 'transparent'
+      },
+      dialogShow: false,
+      respWx:{},
+      respWx2:{},
+      respLogin:{},
+      timer:null,
+	  inviteCode:null,
+	  formData:{
+	  	account:'',
+	  	passwd:''
+	  },
+	  formRules:{
+			account:[{
+			  required:true,
+			  message:'请输入账号'
+			},{
+			  type:'mobile',
+			  message:'手机号码有误!'
+			}],
+			passwd:[{
+			  required:true,
+			  message:'请输入密码'
+			}]
+		}
+    }
+  },
+  methods: {
+    show () {
+		console.log("show");
+		let that=this
+		this.inviteCode = this.$auth.getInviteCode() 
+		console.log("inviteCode",this.inviteCode);
+      this.dialogShow=true;
+      this.$mpi.wxLogin().then(res => {
+        this.respWx = res
+		console.log("res",res);
+      })
+      this.setTimer()
+    },
+    hide () {
+		console.log("hide");
+      if(this.timer){
+        clearTimeout(this.timer)
+        this.timer = null
+        console.log('clearTimeout')
+      }
+      this.dialogShow=false;
+    },
+
+    async setTimer(){
+		console.log("setTimer");
+      this.respWx = await this.$mpi.wxLogin()
+      this.timer = setTimeout(()=>{
+        this.setTimer()
+      },240000) // 每隔4分钟重新请求 jscode
+    },
+    
+    async login(detail){
+	  console.log("2:login",detail);
+      try{
+        this.$dialog.showLoading()
+        if(!this.respLogin.sessionKey){
+          this.respLogin = await this.$api.loginByCode({
+            _isReject:true,
+            code:this.respWx.code
+          })
+          
+        }
+		console.log(this.respLogin);
+        let resp = await this.$api.loginByWxapp({
+          _isReject:true,
+          openId: this.respLogin.openId,
+          sessionKey: this.respLogin.sessionKey,
+          encryptedData: detail.encryptedData,
+          iv: detail.iv,
+		  inviteCode: this.inviteCode
+        })
+        console.log(56,resp)
+        resp.openId = this.respLogin.openId
+        resp.sessionKey = this.respLogin.sessionKey
+        let userType = this.$global.userType.member
+        this.$auth.login(userType, resp.sessionId, resp.userId, resp)
+        this.hide()
+        this.$util.refreshPage(['/pagesM/pages/category','/pagesM/pages/shop_car'])
+		// this.$auth.setInviteCode(null);
+		this.$auth.removeInviteCode();
+		let a = this.$auth.getInviteCode();
+		if(this.inviteCode){
+			this.$emit('getDistributorCoupon')
+		}else{
+			this.$emit('signIn', resp)
+		}
+		
+      }catch(err){
+        // console.log(72,err)
+        this.$dialog.alert({
+          content: err.errmsg || '服务繁忙~'
+        })
+      }finally{
+        this.$dialog.hideLoading()
+        if(this.timer){
+          clearTimeout(this.timer)
+          this.setTimer()
+        }
+      }
+    },
+	/**
+	 * app 登陆逻辑
+	 */
+	async touristLogin() {
+		console.log("");
+		if(!this.validate(this.formRules,this.formData)){
+		  return
+		}
+		try{
+			this.$dialog.showLoading()
+			if(!this.respLogin.sessionKey){
+			  this.respLogin = await this.$api.loginByCode({
+			    _isReject:true,
+			    code:this.respWx.code
+			  })
+			}
+			let resp = await this.$api.touristLogin({
+				account:this.formData.account,
+				passwd:this.formData.passwd
+			})
+			console.log(resp)
+			let userType = this.$global.userType.member
+			resp.openId = this.respLogin.openId
+			resp.sessionKey = this.respLogin.sessionKey
+			this.$auth.login(userType, resp.sessionId, resp.userId, resp)
+			this.hide()
+			this.$util.refreshPage(['pages/index','pages/category','pages/shop_car'])
+			this.$auth.removeInviteCode();
+			let a = this.$auth.getInviteCode();
+			if(this.inviteCode){
+				this.$emit('getDistributorCoupon')
+			}else{
+				this.$emit('signIn', resp)
+			}
+		  }catch(err){
+			// console.log(72,err)
+			this.$dialog.alert({
+			  content: err.errmsg || '服务繁忙~'
+			})
+		  }finally{
+			this.$dialog.hideLoading()
+			if(this.timer){
+			  clearTimeout(this.timer)
+			  this.setTimer()
+			}
+		  }
+
+	},
+	/**1 :点击登陆
+	 * @param {Object} e
+	 */
+    async tapGetPhoneNumber (e) {
+		console.log(1,"点击登陆")
+      // console.log(48,e.detail)
+
+      if(e.detail.errMsg != 'getPhoneNumber:ok') {
+        return
+      }
+
+      // let authSetting = await this.$mpi.wxGetSetting()
+      // if(authSetting['scope.userInfo']) {
+      //   let userInfo = await this.$mpi.wxGetUserInfo()
+      //   console.log(56,userInfo)
+      // }
+      // console.log(55,authSetting)
+	  this.login(e.detail)
+    },
+
+  },
+  beforeDestroy() {
+    if(this.timer){
+      clearTimeout(this.timer)
+      this.timer = null
+      console.log('clearTimeout')
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+button{
+	font-size: 28rpx;
+}
+
+.dt-login-wrap {
+  margin: 0 auto;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 560upx;
+  background-color: #fff;
+  border-radius: 16upx;
+
+  .title {
+    padding-top:60upx;
+    padding-bottom:28upx;
+    font-size: 32upx;
+    font-weight: bold;
+  }
+  .subtitle {
+	color: #7e7e7e;
+    font-size: 26upx;
+  }
+  .login-icon {
+    margin: 25upx auto 52upx;
+    width: 320upx;
+    height: 340upx;
+  }
+  .btn-wrap {
+    display: flex;
+    width: 100%;
+    line-height: 80upx;
+	padding:8rpx 0rpx;
+	font-size: 24rpx;
+    border-top:1upx solid #f2f2f2;
+    .btn-base {
+	  padding: 0 60rpx;
+      flex: 1;
+      text-align: center;
+      color:#66656a;
+      border-radius:0;
+    }
+    .btn-base:before {
+      position: absolute;
+      top: 0;
+      right: 1upx;
+      width: 100%;
+      height: 100%;
+      border-right:1upx solid #ebebeb;
+      content: "";
+    }
+    .btn-base:last-child:before {
+      display: none;
+      content: "";
+    }
+  }
+  
+}
+</style>

+ 33 - 0
comps/dt_service.vue

@@ -0,0 +1,33 @@
+<template>
+  <button
+    class="customer-service"
+    open-type="contact"
+    session-from="weapp">
+    <image class="customer-service-icon" src="http://139.9.103.171:1888/img/image/service.png" mode="widthFix"></image>
+  </button>
+</template>
+<script>
+export default {
+  data(){
+    return {}
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+// 客服按钮
+.customer-service{
+  position: fixed;
+  bottom: 60upx;
+  right: 40upx;
+  background-color:transparent;
+  border:0;
+  .customer-service-icon{
+    width:80upx;
+    height:80upx;
+    border-radius:50%;
+	background-color: #2f7ff5;
+    // background-color:$dt-color-primary;
+  }
+}
+</style>

+ 104 - 0
comps/dt_unit_head_v2.vue

@@ -0,0 +1,104 @@
+<template>
+  <view class="comp-goods-wrap">
+	  <view class="titleContent">
+		  <view class="title">{{ titleLeft }}</view>
+		  <view class="dian"></view>
+		  <view class="strongTitle">{{titleRight}}</view>
+	  </view>
+    <view v-if="isShowMore" class="goods-text-title">
+      <view class="text">{{memo}}</view>
+      <view class="mode" @tap="tapMore">
+        <text class="text">查看更多</text>
+        <image src="http://139.9.103.171:1888/img/image/arrow.png" class="more-arrow-img"></image>
+      </view>
+    </view>
+  </view>
+</template>
+<script>
+export default {
+	data(){
+		return{
+			titleLeft:'',
+			titleRight:''
+		}
+	},
+  props: {
+    title: {
+      type: String,
+      default: ""
+    },
+	memo:{
+		type:String,
+		default:""
+	},
+	isShowMore:{
+      type: Boolean,
+      default: true
+	}
+  },
+  created(){
+	  let titLen = this.title.length;
+	  this.titleLeft = this.title.substring(0,titLen-2)
+	  this.titleRight = this.title.substring(titLen-2,titLen)
+	  // console.log(this.titleLeft)
+  },
+  methods: {
+    tapMore() {
+      this.$emit("more");
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+	.comp-goods-wrap{
+		margin:0 20upx;
+		margin-top: 60upx;
+	}
+	
+	.titleContent{
+		display: flex;
+		align-items: center;
+		.title{
+			font-size:42upx;
+			font-weight:800;
+			color:rgba(0,0,0,1);
+			line-height:42upx;
+		}
+		.dian{
+			width:8upx;
+			height:8upx;
+			background:$dt-color-primary;
+			border-radius:50%;
+			margin: 0 6upx;
+		}
+		.strongTitle{	
+			font-size:42upx;
+			font-weight:800;
+			color:$dt-color-primary;
+		}
+	}
+.goods-text-title {
+  display: flex;
+  justify-content: space-between;
+  height: 70upx;
+  align-items: center;
+  .mode{
+	  display: flex;
+	  justify-content: space-between;
+	  height: 24upx;
+	  align-items: center;
+	  .more-arrow-img{
+	  	margin-left: 10upx;
+	  	width: 12upx;
+	  	height:12upx;
+	  }
+  }
+  .text {
+    font-size:24upx;
+    font-weight:400;
+    color:rgba(102,102,102,1);
+  }
+}
+
+</style>

+ 208 - 0
comps/foot_dialog.vue

@@ -0,0 +1,208 @@
+<template>
+  <!-- 人数拼座 -->
+  <view class="dialog-wrap" :style="'z-index:'+zIndex">
+    <!-- 遮罩 -->
+    <view class="mask" :class="{ show: visible }" @tap="tapDialogShow"></view>
+
+    <view class="content-mn" 
+      :class="{
+        bottom:direction=='bottom',
+        top:direction=='top', 
+        right:direction=='right',
+        left:direction=='left',
+        center:direction=='center',
+        show: visible, 
+        isRadius:isRadius
+      }"
+      :style="{'background-color':conf.mainBgColor,'padding-bottom':safeAreaBottom+'px'}">
+      <view v-if="isTitle" class="head-wrap">
+        <view :class="'title ' + titleClass">{{ title }}</view>
+        <image
+          v-if="isCloseBtn"
+          @tap="tapDialogShow"
+          class="close"
+          src="http://139.9.103.171:1888/img/image/close.png"
+          mode="widthFix"
+        ></image>
+      </view>
+      <view class="main-wrap">
+        <slot name="main"></slot>
+      </view>
+    </view>
+  </view>
+</template>
+<script>
+export default {
+  props: {
+    direction:{
+      type:String,
+      default:'bottom' // top
+    },
+    isTitle: {
+      type: Boolean,
+      default: true
+    },
+    isCloseBtn: {
+      type: Boolean,
+      default: true
+    },
+    isRadius:{
+      type: Boolean,
+      default: true
+    },
+    titleClass: {
+      type: String,
+      default: ""
+    },
+    title: {
+      type: String,
+      default: "标题"
+    },
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    zIndex:{
+      type: [Number,String],
+      default: 100
+    },
+    config:{
+      type:Object,
+      default: ()=>{
+        return {}
+      }
+    }
+  },
+  watch:{
+    config:{
+      deep:true,
+      handler:(n,o)=>{
+        console.log(79,n)
+        if(n){
+          this.conf = Object.assign({},n)
+        }
+      }
+    }
+  },
+  data(){
+    return {
+      conf:{}
+    }
+  },
+  methods: {
+    tapDialogShow() {
+      this.$emit("update:visible", false);
+      this.$emit("close")
+    }
+  },
+  created(){
+    console.log(99,'safeAreaBottom',this.safeAreaBottom)
+    console.log(93,this.conf, this.config)
+    this.conf = Object.assign({},this.config)
+  },
+};
+</script>
+<style lang="scss">
+// 弹窗 选择人数拼车
+.dialog-wrap {
+  position: relative;
+  width: 100%;
+  z-index: 100;
+
+  .mask.show {
+    visibility: visible;
+    opacity: 1;
+  }
+  .mask {
+    position: fixed;
+    top: 0;
+    width: 100vw;
+    height: 100vh;
+    background-color: rgba(0, 0, 0, 0.3);
+    transition: all 0.3s ease;
+    visibility: hidden;
+    opacity: 0;
+  }
+  .isRadius{
+    border-radius:14upx 14upx 0upx 0upx;
+  }
+  
+  .content-mn {
+    position: fixed;
+    left: 0;
+    width: 100%;
+    background-color: #fff;
+    // padding-bottom: 1upx;
+    transition: all 0.3s ease;
+    z-index: 102;
+
+    .head-wrap {
+      position: relative;
+      display: flex;
+      align-items: center;
+      padding: 0 30upx;
+      min-height: 90upx;
+      font-size: 28upx;
+      .title {
+        width: 100%;
+        font-size:30upx;
+      }
+      .title-center {
+        text-align: center;
+      }
+      .close {
+        position: absolute;
+        right: 0;
+        top: 50%;
+        transform: translateY(-50%);
+        padding: 30upx;
+        width: 22upx;
+        height: 22upx;
+      }
+    }
+    .main-wrap {
+      width: 100%;
+    }
+  }
+  
+  .center{
+    top:50%;
+    left:50%;
+    transform: translate(-50%,-50%) scale(0.5);
+    opacity: 0;
+    visibility:hidden;
+  }
+  .top{
+    top: 0;
+    transform: translateY(-100%);
+  }
+  .right{
+    top:0;
+    right:0;
+    transform: translateX(100%);
+  }
+  .bottom{
+    bottom: 0;
+    transform: translateY(100%);
+  }
+  .left{
+    top:0;
+    left:0;
+    transform: translateX(-100%);
+  }
+  
+  .center.show{
+    transform: translate(-50%,-50%) scale(1);
+    opacity:1;
+    visibility:visible;
+  }
+  .top.show,
+  .bottom.show {
+    transform: translateY(0);
+  }
+  .right.show,
+  .left.show{
+    transform: translateX(0);
+  }
+}
+</style>

+ 160 - 0
comps/goods/goods.vue

@@ -0,0 +1,160 @@
+<template>
+	<view >
+		<view class="recommend-info" style="background-image: -webkit-gradient(linear, 0 0, 0 bottom, from(#ffffff), to(#f1f1f1))">
+		  <view class="goods-list">
+		    <navigator :url="'/pagesM/pages/goods_des?id='+item.id" class="list" v-for="(item,index) in goodsList" :key="index">
+		      <view class="pictrue">
+		        <image :src="item.productImages[0].medium" mode="heightFix"></image>
+		      </view>
+		      <view class="title-tag">
+		        <view class="tag">
+		          <!-- <text v-if="item.is_goods === 1">特价</text> -->
+		          {{item.name}}
+		        </view>
+		      </view>
+<!-- 			  <view class="padding-top-10 padding-left-20">
+			  	<view class="cu-tag sm text-gray radius" style="background-color: #ebebeb;">
+			  		销量{{item.salfNum}}
+			  	</view>
+			  </view> -->
+		      <view class="price-info">
+		        <view class="user-price">
+		          <text class="min">¥</text>
+		          <text class="max">{{item.price}}</text>
+		        </view>
+		        <view class="vip-price">
+		          <text>¥{{item.marketPrice}}</text>
+		        </view>
+		      </view>
+		    </navigator>
+		  </view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:{
+			goodsList: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			}
+		},
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+		
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	/* 为你推荐 */
+	.recommend-info{
+	  width: 100%;
+	  .recommend-title{
+	    display: flex;
+	    align-items: center;
+	    justify-content: center;
+	    width: 100%;
+	    height: 100rpx;
+	    .title{
+	      display: flex;
+	      align-items: center;
+	      image{
+	        width: 416rpx;
+	        height: 40rpx;
+	      }
+	    }
+	  }
+	  .goods-list{
+	    display: flex;
+	    flex-wrap: wrap;
+	    justify-content: space-between;
+	    padding: 0 30rpx;
+	    .list{
+	      width: 49%;
+	      height: 490rpx;
+	      margin-bottom: 20rpx;
+	      background-color: #FFFFFF;
+	      border-radius: 10rpx;
+	      overflow: hidden;
+	      .pictrue{
+	        display: flex;
+	        justify-content: center;
+	        width: 100%;
+	        image{
+	          height: 320rpx;
+	        }
+	      }
+	      .title-tag{
+	        // display: flex;
+	        height: 70rpx;
+	        padding: 20rpx;
+	        .tag{
+	          float: left;
+	          margin-right: 10rpx;
+	          overflow: hidden;
+	          text-overflow: ellipsis;
+	          display: -webkit-box;
+	          -webkit-line-clamp: 2;
+	          -webkit-box-orient: vertical;
+	          white-space: normal;
+	          font-size: 26rpx;
+	          line-height: 40rpx;
+	          text{
+	            font-size: 24rpx;
+	            color: #FFFFFF;
+	            padding: 4rpx 16rpx;
+	            background: #fe3f11;
+	            border-radius: 6rpx;
+	            margin-right: 10rpx;
+	          }
+	        }
+	      }
+	      .price-info{
+	        display: flex;
+	        flex-wrap: wrap;
+	        align-items: center;
+	        justify-content: start;
+	        padding: 0 20rpx;
+	        height: 50rpx;
+	        .user-price{
+	          display: flex;
+	          align-items: center;
+	          text{
+	            color: #ff587f;
+	          }
+	          .min{
+	            font-size: 24rpx;
+	          }
+	          .max{
+	            font-size: 32rpx;
+	          }
+	        }
+	        .vip-price{
+			  padding-left: 20rpx;
+	          display: flex;
+	          align-items: center;
+	          image{
+	            width: 26rpx;
+	            height: 26rpx;
+	            margin-right: 10rpx;
+	          }
+	          text{
+				text-decoration: line-through;
+	            color: #8c8c8c;
+	            font-size: 24rpx;
+	          }
+	        }
+	      }
+	    }
+	  }
+	}
+
+</style>

+ 95 - 0
comps/grid/grid.vue

@@ -0,0 +1,95 @@
+<template>
+<view class="page">
+	<view class="grid-wrap" v-for="(list, i) in gridList" :key="i">
+		<view class="grid-title">{{list.title}}</view>
+		<view class="grid-item-box"  >
+			<view class="grid-item"
+				v-for="(item, index) in list.subList" 
+				:key="index" hover-class="hover" 
+				:style="'width:calc(100% / '+column+')'"
+				:class="{'no-border-right':(index+1)%column==0,'no-border-top':index+1>column, 'no-border-bottom':noBorderBottom(i,index), 'no-border':!border}"
+				@tap="jump(item.url, index, item)"
+			>
+				<image style="padding-bottom: 16rpx;" :src="item.src" ></image>
+				<view class="name" style="font-size: 26rpx;">{{item.name}}</view>
+			</view>
+		</view>
+	</view>
+</view>
+</template>
+
+<script>
+
+export default {
+	props:{
+		gridList :{
+			type: Array
+		},
+		column:{
+			type: Number,
+			default: 4
+		},
+		border:{
+			type: Boolean,
+			default:true
+		}
+	},
+	data () {
+		return {}
+	},
+	methods : {
+		//最后一行-取消底部边框
+		noBorderBottom ( i, index ) {
+			let len = this.gridList[i].subList.length
+			let row = parseInt(len/this.column)
+			if(len % this.column === 0){
+				return index+1 > (row-1) * this.column
+			}
+			return index+1 > row * this.column
+		},
+		//跳转
+		jump( url, index, item ) {
+			//如果是点击类型的,那么就直接返回当前点击的数据以及索引回去
+			if(item.type === 'click'){
+				const obj = {
+					item,index
+				}
+				this.$emit('tapGrid', obj)
+				return
+			}else if(item.type === 'switchTab'){
+				uni.switchTab({
+					url
+				})
+				return
+			}
+			uni.navigateTo({
+				url
+			})
+		}
+	}
+	
+};
+</script>
+<style scoped lang="scss">
+.grid-wrap{
+	width: 96%;margin-left: 2%;background: #fff;border-radius: 20upx;box-shadow: 0 0 5upx 2upx #efefef;margin-top: 15upx;font-size: 28upx;
+	.grid-title{
+		color: #666;padding: 15upx 2%;font-size: 30upx;width: 96%;margin-left: 20rpx;font-weight: 800;
+	}
+	
+	.grid-item-box{
+		display: flex;align-items: center;flex-wrap: wrap;
+		.grid-item{
+			text-align: center;padding: 20upx 0;width: calc(100% / 3);box-sizing: border-box;
+			border-right: .5upx solid #ccc;border-top: .5upx solid #ccc;border-bottom: .5upx solid #ccc;
+			image{width:48upx;height: 48upx;}
+		}
+		.hover{background: #efefef;}
+		.no-border-right{border-right: none;}
+		.no-border-bottom{border-bottom:none}
+		.no-border-top{border-top:none}
+		.no-border{border:none !important}
+	}
+}
+</style>
+

+ 69 - 0
comps/hot-consult/hot-consult.vue

@@ -0,0 +1,69 @@
+<template>
+	<view>
+		<view class="container">
+			<view class="flex justify-between" >
+				<block>
+					<view class="cu-avatar text-font"  style="background-image:url(http://139.9.103.171:8888/group1/M00/00/01/iwlnq1-_2IiAFB-HAAAQn95tidI930.png);"></view>
+					<view class="margin-top-xs" style="width: 680rpx">
+						<swiper :circular="true" class="swiper" autoplay="true" vertical="true" interval="5000" next-margin="46rpx">
+							<swiper-item v-for="(item, index) in swiperTexts" :key="index" @click="detailTap(item.id)">
+								<view class="swiper-item" > 
+									<text class="text-orange cuIcon-title padding-right-sm"></text>
+									<text>{{item.title}}</text>
+								</view>
+							</swiper-item>
+						</swiper>
+					</view>
+				</block>
+				<view class="flex align-center justify-center" style="width: 100rpx;" @click="onTap">
+					<text class="cuIcon-right"></text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			swiperTexts: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+		},
+		methods: {
+			onTap() {
+				this.$emit('onTap');
+			},
+			detailTap(id) {
+				this.$emit('detailTap',id);
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.container {
+	background-color: #ffffff;
+	height: 110rpx;
+}
+.swiper {
+	height: 90rpx;
+}
+.swiper-item {
+	font-size: 24rpx;
+	color: #323232;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	overflow: hidden;
+	height: 40rpx; 
+	margin: 6rpx 0rpx;
+}
+.text-font {
+	width: 100rpx;
+	height: 100rpx;
+	margin: 10rpx 10rpx 10rpx 20rpx;
+}
+</style>

+ 46 - 0
comps/loading/loaders/rotate-plane.vue

@@ -0,0 +1,46 @@
+<template>
+  <view>
+    <view :style="{
+      backgroundColor: color,
+      width: size+20+'px',
+      height: size+20+'px' }" class="spinner-inside"></view>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'rotatePlane',
+  props: {
+    color: String,
+    size: Number
+  }
+}
+</script>
+
+<style scoped>
+.spinner-inside {
+  margin: 25px auto;
+ 
+  -webkit-animation: rotateplane 1.2s infinite ease-in-out;
+  animation: rotateplane 1.2s infinite ease-in-out;
+}
+ 
+@-webkit-keyframes rotateplane {
+  0% { -webkit-transform: perspective(120px) }
+  50% { -webkit-transform: perspective(120px) rotateY(180deg) }
+  100% { -webkit-transform: perspective(120px) rotateY(180deg)  rotateX(180deg) }
+}
+ 
+@keyframes rotateplane {
+  0% {
+    transform: perspective(120px) rotateX(0deg) rotateY(0deg);
+    -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
+  } 50% {
+    transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
+    -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
+  } 100% {
+    transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+    -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+  }
+}
+</style>

+ 127 - 0
comps/loading/loading.vue

@@ -0,0 +1,127 @@
+<template>
+  <transition name="fade">
+   <view
+			class="mask"
+      v-show="isActive"
+      :class="{ 'full-screen': isFullScreen }"
+      :style="{ backgroundColor }"
+    >
+      <view class="spinner" :style="{ transform:`translate(-50%, -${translateY}%)`}">
+        <slot>
+					<!--  ==========在这里改成选择的那一个========== -->
+					<rotatePlane :color="color" :size="size"/>
+					<!--  ==========在这里改成选择的那一个========== -->
+        </slot>
+        <view
+          v-if="text.length"
+          :style="{ color:textColor }">
+          {{ text }}
+        </view>
+      </view>
+    </view>
+  </transition>
+</template>
+
+<script>
+// ==========在这里选一个你要的其他去掉也行==========
+// import loop from './loaders/loop.vue'
+// import bounce from './loaders/bounce.vue'
+// import doubleBounce from './loaders/double-bounce.vue'
+// import doubleCube from './loaders/double-cube.vue'
+// import doubleDot from './loaders/double-dot.vue'
+import rotatePlane from './loaders/rotate-plane.vue'
+// import scaleOut from './loaders/scale-out.vue'
+// import shrinkRect from './loaders/shrink-rect.vue'
+// ==========在这里选一个你要的其他去掉也行==========
+
+export default {
+  name: 'ourLoading',
+  components: { 
+		// ==========在这里选择一个==========
+			// loop,
+			// bounce,
+			// doubleBounce,
+			// doubleCube,
+			// doubleDot,
+			rotatePlane,
+			// scaleOut,
+			// shrinkRect
+		// ==========在这里选择一个==========
+	},
+  props: {
+    active: Boolean,
+		translateY: {
+			type: Number,
+			default: 150
+		},
+    text: {
+      type: String,
+      default: ''
+    },
+    color: {
+      type: String,
+      default: '#333'
+    },
+		textColor: {
+			type: String,
+			default: '#333'
+		},
+    isFullScreen: {
+      type: Boolean,
+      default: false
+    },
+    backgroundColor: {
+      type: String,
+      default: 'rgba(255, 255, 255, .6)'
+    },
+    size: {
+      type: Number,
+      default: 40
+    }
+  },
+  data () {
+    return {
+      isActive: this.active || false
+    }
+  },
+  watch: {
+    active (value) {
+      this.isActive = value
+    }
+  }
+}
+</script>
+
+<style scoped>
+.mask {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: 3000;
+	transition: opacity .3s linear;
+}
+
+.full-screen {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+}
+
+.spinner {
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	text-align: center;
+}
+
+.fade-enter-active, .fade-leave-active {
+  transition: opacity .3s;
+}
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+</style>

+ 30 - 0
comps/mescroll-uni/mescroll-uni-option.js

@@ -0,0 +1,30 @@
+// mescroll 全局配置
+const GlobalOption = {
+	down: {
+		// 其他down的配置参数也可以写,这里只展示了常用的配置:
+		textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
+		textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
+		textLoading: '加载中 ...', // 加载中的提示文本
+		offset: 80 // 在列表顶部,下拉大于80upx,松手即可触发下拉刷新的回调
+	},
+	up: {
+		// 其他up的配置参数也可以写,这里只展示了常用的配置:
+		textLoading: '加载中 ...', // 加载中的提示文本
+		textNoMore: '到底啦', // 没有更多数据的提示文本
+		offset: 80, // 距底部多远时,触发upCallback
+		isBounce: false, // 默认禁止橡皮筋的回弹效果, 必读事项: http://www.mescroll.com/qa.html?v=190725#q25
+		toTop: {
+			// 回到顶部按钮,需配置src才显示
+			src: "http://www.mescroll.com/img/mescroll-totop.png?v=1", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png )
+			offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000
+			duration: 300, // 回到顶部的动画时长,默认300ms
+		},
+		empty: {
+			use: true, // 是否显示空布局
+			icon: "/static/empty1.png", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
+			tip: '数据为空' // 提示
+		}
+	}
+}
+
+export default GlobalOption

+ 223 - 0
comps/mescroll-uni/mescroll-uni.css

@@ -0,0 +1,223 @@
+/* mescroll-uni
+ * version 1.1.8
+ * 2019-11-01 wenju
+ * http://www.mescroll.com
+ */
+
+page {
+	height: 100%;
+	box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
+	-webkit-overflow-scrolling: touch; /*使iOS列表滑动流畅*/
+}
+
+.mescroll-uni-warp{
+	height: 100%;
+}
+
+.mescroll-uni {
+	position: relative;
+	width: 100%;
+	height: 100%;
+	min-height: 200upx;
+	overflow-y: auto;
+	box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
+}
+
+/* 定位的方式固定高度 */
+.mescroll-uni-fixed{
+	z-index: 1;
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	width: auto; /* 使right生效 */
+	height: auto; /* 使bottom生效 */
+}
+
+/* 下拉刷新区域 */
+.mescroll-downwarp {
+	position: absolute;
+	top: -100%;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	text-align: center;
+}
+
+/* 下拉刷新--内容区,定位于区域底部 */
+.mescroll-downwarp .downwarp-content {
+	position: absolute;
+	left: 0;
+	bottom: 0;
+	width: 100%;
+	min-height: 60upx;
+	padding: 20upx 0;
+	text-align: center;
+}
+
+/* 上拉加载区域 */
+.mescroll-upwarp {
+	min-height: 60upx;
+	text-align: center;
+	clear: both;
+}
+
+/* 下拉刷新,上拉加载--提示文本 */
+.mescroll-downwarp .downwarp-tip,
+.mescroll-upwarp .upwarp-tip,
+.mescroll-upwarp .upwarp-nodata {
+	display: inline-block;
+	font-size: 28upx;
+	color: gray;
+	vertical-align: middle;
+}
+
+.mescroll-downwarp .downwarp-tip,
+.mescroll-upwarp .upwarp-tip {
+	margin-left: 16upx;
+}
+
+/* 下拉刷新,上拉加载--旋转进度条 */
+.mescroll-downwarp .downwarp-progress,
+.mescroll-upwarp .upwarp-progress {
+	display: inline-block;
+	width: 32upx;
+	height: 32upx;
+	border-radius: 50%;
+	border: 2upx solid gray;
+	border-bottom-color: transparent;
+	vertical-align: middle;
+}
+
+/* 旋转动画 */
+.mescroll-rotate {
+	-webkit-animation: mescrollRotate 0.6s linear infinite;
+	animation: mescrollRotate 0.6s linear infinite;
+}
+
+@-webkit-keyframes mescrollRotate {
+	0% {
+		-webkit-transform: rotate(0deg);
+	}
+
+	100% {
+		-webkit-transform: rotate(360deg);
+	}
+}
+
+@keyframes mescrollRotate {
+	0% {
+		transform: rotate(0deg);
+	}
+
+	100% {
+		transform: rotate(360deg);
+	}
+}
+
+/* 无任何数据的空布局 */
+.mescroll-empty {
+	box-sizing: border-box;
+	width: 100%;
+	padding: 40upx;
+	text-align: center;
+}
+
+.mescroll-empty.empty-fixed {
+	z-index: 99;
+	position: fixed; /*transform会使fixed失效,最终会降级为absolute */
+	top: 20%;
+	left: 0;
+}
+
+.mescroll-empty .empty-icon {
+	width: 45%;
+}
+
+.mescroll-empty .empty-tip {
+	margin-top: 20upx;
+	font-size: 24upx;
+	color: gray;
+}
+
+.mescroll-empty .empty-btn {
+	display: inline-block;
+	margin-top: 40upx;
+	min-width: 200upx;
+	padding: 18upx;
+	font-size: 28upx;
+	border: 1upx solid #E04B28;
+	border-radius: 60upx;
+	color: #E04B28;
+}
+
+.mescroll-empty .empty-btn:active {
+	opacity: .75;
+}
+
+/* 回到顶部的按钮 */
+.mescroll-totop {
+	z-index: 9990;
+	position: fixed !important; /* 避免编译到H5,在多mescroll中定位失效 */
+	right: 20upx;
+	bottom: 120upx;
+	width: 72upx;
+	height: 72upx;
+	border-radius: 50%;
+	opacity: 0;
+}
+
+/* 显示动画--淡入 */
+.mescroll-lazy-in,
+.mescroll-fade-in {
+	-webkit-animation: mescrollFadeIn .3s linear forwards;
+	animation: mescrollFadeIn .3s linear forwards;
+}
+
+@-webkit-keyframes mescrollFadeIn {
+	0% {
+		opacity: 0;
+	}
+
+	100% {
+		opacity: 1;
+	}
+}
+
+@keyframes mescrollFadeIn {
+	0% {
+		opacity: 0;
+	}
+
+	100% {
+		opacity: 1;
+	}
+}
+
+/* 隐藏动画--淡出 */
+.mescroll-fade-out {
+	pointer-events: none;
+	-webkit-animation: mescrollFadeOut .5s linear forwards;
+	animation: mescrollFadeOut .5s linear forwards;
+}
+
+@-webkit-keyframes mescrollFadeOut {
+	0% {
+		opacity: 1;
+	}
+
+	100% {
+		opacity: 0;
+	}
+}
+
+@keyframes mescrollFadeOut {
+	0% {
+		opacity: 1;
+	}
+
+	100% {
+		opacity: 0;
+	}
+}

+ 747 - 0
comps/mescroll-uni/mescroll-uni.js

@@ -0,0 +1,747 @@
+/* mescroll-uni
+ * version 1.1.8
+ * 2019-11-01 wenju
+ * http://www.mescroll.com
+ */
+
+export default function MeScroll(options) {
+	let me = this;
+	me.version = '1.1.8'; // mescroll版本号
+	me.options = options || {}; // 配置
+
+	me.isDownScrolling = false; // 是否在执行下拉刷新的回调
+	me.isUpScrolling = false; // 是否在执行上拉加载的回调
+	let hasDownCallback = me.options.down && me.options.down.callback; // 是否配置了down的callback
+
+	// 初始化下拉刷新
+	me.initDownScroll();
+	// 初始化上拉加载,则初始化
+	me.initUpScroll();
+
+	// 自动加载
+	setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
+		// 自动触发下拉刷新 (只有配置了down的callback才自动触发下拉刷新)
+		if (me.optDown.use && me.optDown.auto && hasDownCallback) {
+			if (me.optDown.autoShowLoading) {
+				me.triggerDownScroll(); // 显示下拉进度,执行下拉回调
+			} else {
+				me.optDown.callback && me.optDown.callback(me); // 不显示下拉进度,直接执行下拉回调
+			}
+		}
+		// 自动触发上拉加载
+		me.optUp.use && me.optUp.auto && !me.isUpAutoLoad && me.triggerUpScroll();
+	}, 30); // 需让me.optDown.inited和me.optUp.inited先执行
+}
+
+/* 配置参数:下拉刷新 */
+MeScroll.prototype.extendDownScroll = function(optDown) {
+	// 下拉刷新的配置
+	MeScroll.extend(optDown, {
+		use: true, // 是否启用下拉刷新; 默认true
+		auto: true, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true
+		autoShowLoading: false, // 如果设置auto=true(在初始化完毕之后自动执行下拉刷新的回调),那么是否显示下拉刷新的进度; 默认false
+		isLock: false, // 是否锁定下拉刷新,默认false;
+		offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
+		startTop: 100, // scroll-view滚动到顶部时,此时的scroll-top不一定为0, 此值用于控制最大的误差
+		fps: 40, // 下拉节流 (值越大每秒刷新频率越高)
+		inOffsetRate: 1, // 在列表顶部,下拉的距离小于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
+		outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
+		bottomOffset: 20, // 当手指touchmove位置在距离body底部20px范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行
+		minAngle: 45, // 向下滑动最少偏移的角度,取值区间  [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突;
+		textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
+		textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
+		textLoading: '加载中 ...', // 加载中的提示文本
+		inited: null, // 下拉刷新初始化完毕的回调
+		inOffset: null, // 下拉的距离进入offset范围内那一刻的回调
+		outOffset: null, // 下拉的距离大于offset那一刻的回调
+		onMoving: null, // 下拉过程中的回调,滑动过程一直在执行; rate下拉区域当前高度与指定距离的比值(inOffset: rate<1; outOffset: rate>=1); downHight当前下拉区域的高度
+		beforeLoading: null, // 准备触发下拉刷新的回调: 如果return true,将不触发showLoading和callback回调; 常用来完全自定义下拉刷新, 参考案例【淘宝 v6.8.0】
+		showLoading: null, // 显示下拉刷新进度的回调
+		afterLoading: null, // 准备结束下拉的回调. 返回结束下拉的延时执行时间,默认0ms; 常用于结束下拉之前再显示另外一小段动画,才去隐藏下拉刷新的场景, 参考案例【dotJump】
+		endDownScroll: null, // 结束下拉刷新的回调
+		callback: function(mescroll) {
+			// 下拉刷新的回调;默认重置上拉加载列表为第一页
+			mescroll.resetUpScroll();
+		}
+	})
+}
+
+/* 配置参数:上拉加载 */
+MeScroll.prototype.extendUpScroll = function(optUp) {
+	// 上拉加载的配置
+	MeScroll.extend(optUp, {
+		use: true, // 是否启用上拉加载; 默认true
+		auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true
+		isLock: false, // 是否锁定上拉加载,默认false;
+		isBoth: true, // 上拉加载时,如果滑动到列表顶部是否可以同时触发下拉刷新;默认true,两者可同时触发;
+		isBounce: false, // 默认禁止橡皮筋的回弹效果, 必读事项: http://www.mescroll.com/qa.html?v=190725#q25
+		callback: null, // 上拉加载的回调;function(page,mescroll){ }
+		page: {
+			num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+			size: 10, // 每页数据的数量
+			time: null // 加载第一页数据服务器返回的时间; 防止用户翻页时,后台新增了数据从而导致下一页数据重复;
+		},
+		noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看
+		offset: 80, // 距底部多远时,触发upCallback
+		textLoading: '加载中 ...', // 加载中的提示文本
+		textNoMore: '-- END --', // 没有更多数据的提示文本
+		inited: null, // 初始化完毕的回调
+		showLoading: null, // 显示加载中的回调
+		showNoMore: null, // 显示无更多数据的回调
+		hideUpScroll: null, // 隐藏上拉加载的回调
+		toTop: {
+			// 回到顶部按钮,需配置src才显示
+			src: null, // 图片路径,默认null (建议写成网络图,不必考虑相对路径)
+			offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000
+			duration: 300, // 回到顶部的动画时长,默认300ms
+			btnClick: null, // 点击按钮的回调
+			onShow: null // 是否显示的回调
+		},
+		empty: {
+			use: true, // 是否显示空布局
+			icon: null, // 图标路径
+			tip: '~ 暂无相关数据 ~', // 提示
+			btnText: '', // 按钮
+			btnClick: null, // 点击按钮的回调
+			onShow: null // 是否显示的回调
+		},
+		onScroll: false // 是否监听滚动事件
+	})
+}
+
+/* 配置参数 */
+MeScroll.extend = function(userOption, defaultOption) {
+	if (!userOption) return defaultOption;
+	for (let key in defaultOption) {
+		if (userOption[key] == null) {
+			let def = defaultOption[key];
+			if (def != null && typeof def === 'object') {
+				userOption[key] = MeScroll.extend({}, def); // 深度匹配
+			} else {
+				userOption[key] = def;
+			}
+		} else if (typeof userOption[key] === 'object') {
+			MeScroll.extend(userOption[key], defaultOption[key]); // 深度匹配
+		}
+	}
+	return userOption;
+}
+
+/* -------初始化下拉刷新------- */
+MeScroll.prototype.initDownScroll = function() {
+	let me = this;
+	// 配置参数
+	me.optDown = me.options.down || {};
+	me.extendDownScroll(me.optDown);
+
+	me.downHight = 0; // 下拉区域的高度
+
+	// 在页面中加入下拉布局
+	if (me.optDown.use && me.optDown.inited) {
+		// 初始化完毕的回调
+		setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
+			me.optDown.inited(me);
+		}, 0)
+	}
+}
+
+/* 列表touchstart事件 */
+MeScroll.prototype.touchstartEvent = function(e) {
+	if (!this.optDown.use) return;
+
+	this.startPoint = this.getPoint(e); // 记录起点
+	this.startTop = this.getScrollTop(); // 记录此时的滚动条位置
+	this.lastPoint = this.startPoint; // 重置上次move的点
+	this.maxTouchmoveY = this.getBodyHeight() - this.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
+	this.inTouchend = false; // 标记不是touchend
+}
+
+/* 列表touchmove事件 */
+MeScroll.prototype.touchmoveEvent = function(e) {
+	if (!this.optDown.use) return;
+	if (!this.startPoint) return;
+	let me = this;
+
+	// 节流
+	let t = new Date().getTime();
+	if (me.moveTime && t - me.moveTime < me.moveTimeDiff) { // 小于节流时间,则不处理
+		return;
+	} else {
+		me.moveTime = t
+		me.moveTimeDiff = 1000 / me.optDown.fps
+	}
+
+	let scrollTop = me.getScrollTop(); // 当前滚动条的距离
+	let curPoint = me.getPoint(e); // 当前点
+
+	let moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+
+	// (向下拉&&在顶部) scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
+	// scroll-view滚动到顶部时,scrollTop不一定为0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
+	if (moveY > 0 && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop))) {
+		// 可下拉的条件
+		if (me.optDown.use && !me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
+				me.optUp.isBoth))) {
+
+			// 下拉的角度是否在配置的范围内
+			let x = Math.abs(me.lastPoint.x - curPoint.x);
+			let y = Math.abs(me.lastPoint.y - curPoint.y);
+			let z = Math.sqrt(x * x + y * y);
+			if (z !== 0) {
+				let angle = Math.asin(y / z) / Math.PI * 180; // 两点之间的角度,区间 [0,90]
+				if (angle < me.optDown.minAngle) return; // 如果小于配置的角度,则不往下执行下拉刷新
+			}
+
+			// 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
+			if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
+				me.inTouchend = true; // 标记执行touchend
+				me.touchendEvent(); // 提前触发touchend
+				return;
+			}
+
+			me.preventDefault(e); // 阻止默认事件
+
+			let diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
+
+			// 下拉距离  < 指定距离
+			if (me.downHight < me.optDown.offset) {
+				if (me.movetype !== 1) {
+					me.movetype = 1; // 加入标记,保证只执行一次
+					me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
+					me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
+				}
+				me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
+
+				// 指定距离  <= 下拉距离
+			} else {
+				if (me.movetype !== 2) {
+					me.movetype = 2; // 加入标记,保证只执行一次
+					me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
+					me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
+				}
+				if (diff > 0) { // 向下拉
+					me.downHight += Math.round(diff * me.optDown.outOffsetRate); // 越往下,高度变化越小
+				} else { // 向上收
+					me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
+				}
+			}
+
+			let rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
+			me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
+		}
+	}
+
+	me.lastPoint = curPoint; // 记录本次移动的点
+}
+
+/* 列表touchend事件 */
+MeScroll.prototype.touchendEvent = function(e) {
+	if (!this.optDown.use) return;
+	// 如果下拉区域高度已改变,则需重置回来
+	if (this.isMoveDown) {
+		if (this.downHight >= this.optDown.offset) {
+			// 符合触发刷新的条件
+			this.triggerDownScroll();
+		} else {
+			// 不符合的话 则重置
+			this.downHight = 0;
+			this.optDown.endDownScroll && this.optDown.endDownScroll(this);
+		}
+		this.movetype = 0;
+		this.isMoveDown = false;
+	} else if (this.getScrollTop() === this.startTop) { // 到顶/左/右/底的滑动事件
+		let isScrollUp = this.getPoint(e).y - this.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+		// 上滑 && 检查并触发上拉
+		isScrollUp && this.triggerUpScroll(true);
+	}
+}
+
+/* 根据点击滑动事件获取第一个手指的坐标 */
+MeScroll.prototype.getPoint = function(e) {
+	if (!e) {
+		return {
+			x: 0,
+			y: 0
+		}
+	}
+	if (e.touches && e.touches[0]) {
+		return {
+			x: e.touches[0].pageX,
+			y: e.touches[0].pageY
+		}
+	} else if (e.changedTouches && e.changedTouches[0]) {
+		return {
+			x: e.changedTouches[0].pageX,
+			y: e.changedTouches[0].pageY
+		}
+	} else {
+		return {
+			x: e.clientX,
+			y: e.clientY
+		}
+	}
+}
+
+/* 触发下拉刷新 */
+MeScroll.prototype.triggerDownScroll = function() {
+	if (this.optDown.beforeLoading && this.optDown.beforeLoading(this)) {
+		//return true则处于完全自定义状态
+	} else {
+		this.showDownScroll(); // 下拉刷新中...
+		this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
+	}
+}
+
+/* 显示下拉进度布局 */
+MeScroll.prototype.showDownScroll = function() {
+	this.isDownScrolling = true; // 标记下拉中
+	this.downHight = this.optDown.offset; // 更新下拉区域高度
+	this.optDown.showLoading(this, this.downHight); // 下拉刷新中...
+}
+
+/* 结束下拉刷新 */
+MeScroll.prototype.endDownScroll = function() {
+	let me = this;
+	// 结束下拉刷新的方法
+	let endScroll = function() {
+		me.downHight = 0;
+		me.isDownScrolling = false;
+		me.optDown.endDownScroll && me.optDown.endDownScroll(me);
+		me.setScrollHeight(0) // 重置滚动区域,使数据不满屏时仍可检查触发翻页
+	}
+	// 结束下拉刷新时的回调
+	let delay = 0;
+	if (me.optDown.afterLoading) delay = me.optDown.afterLoading(me); // 结束下拉刷新的延时,单位ms
+	if (typeof delay === 'number' && delay > 0) {
+		setTimeout(endScroll, delay);
+	} else {
+		endScroll();
+	}
+}
+
+/* 锁定下拉刷新:isLock=ture,null锁定;isLock=false解锁 */
+MeScroll.prototype.lockDownScroll = function(isLock) {
+	if (isLock == null) isLock = true;
+	this.optDown.isLock = isLock;
+}
+
+/* -------初始化上拉加载------- */
+MeScroll.prototype.initUpScroll = function() {
+	let me = this;
+	// 配置参数
+	me.optUp = me.options.up || {
+		use: false
+	};
+	me.extendUpScroll(me.optUp);
+
+	if (!me.optUp.isBounce) me.setBounce(false); // 不允许bounce时,需禁止window的touchmove事件
+
+	if (me.optUp.use === false) return; // 配置不使用上拉加载时,则不初始化上拉布局
+	me.optUp.hasNext = true; // 如果使用上拉,则默认有下一页
+	me.startNum = me.optUp.page.num + 1; // 记录page开始的页码
+
+	// 初始化完毕的回调
+	if (me.optUp.inited) {
+		setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
+			me.optUp.inited(me);
+		}, 0)
+	}
+}
+
+/*列表滚动事件*/
+MeScroll.prototype.scroll = function(e, onScroll) {
+	// 更新滚动条的位置
+	this.setScrollTop(e.scrollTop);
+	// 更新滚动内容高度
+	this.setScrollHeight(e.scrollHeight);
+
+	// 向上滑还是向下滑动
+	if (this.preScrollY == null) this.preScrollY = 0;
+	this.isScrollUp = e.scrollTop - this.preScrollY > 0;
+	this.preScrollY = e.scrollTop;
+
+	// 上滑 && 检查并触发上拉
+	this.isScrollUp && this.triggerUpScroll(true);
+
+	// 顶部按钮的显示隐藏
+	if (e.scrollTop >= this.optUp.toTop.offset) {
+		this.showTopBtn();
+	} else {
+		this.hideTopBtn();
+	}
+
+	// 滑动监听
+	this.optUp.onScroll && onScroll && onScroll()
+}
+
+/* 触发上拉加载 */
+MeScroll.prototype.triggerUpScroll = function(isCheck) {
+	if (!this.isUpScrolling && this.optUp.use && this.optUp.callback) {
+		// 是否校验在底部; 默认不校验
+		if (isCheck === true) {
+			let canUp = false;
+			// 还有下一页 && 没有锁定 && 不在下拉中
+			if (this.optUp.hasNext && !this.optUp.isLock && !this.isDownScrolling) {
+				if (this.getScrollBottom() <= this.optUp.offset) { // 到底部
+					canUp = true; // 标记可上拉
+				}
+			}
+			if (canUp === false) return;
+		}
+		this.showUpScroll(); // 上拉加载中...
+		this.optUp.page.num++; // 预先加一页,如果失败则减回
+		this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
+		this.num = this.optUp.page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
+		this.size = this.optUp.page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
+		this.time = this.optUp.page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
+		this.optUp.callback(this); // 执行回调,联网加载数据
+	}
+}
+
+/* 显示上拉加载中 */
+MeScroll.prototype.showUpScroll = function() {
+	this.isUpScrolling = true; // 标记上拉加载中
+	this.optUp.showLoading && this.optUp.showLoading(this); // 回调
+}
+
+/* 显示上拉无更多数据 */
+MeScroll.prototype.showNoMore = function() {
+	this.optUp.hasNext = false; // 标记无更多数据
+	this.optUp.showNoMore && this.optUp.showNoMore(this); // 回调
+}
+
+/* 隐藏上拉区域**/
+MeScroll.prototype.hideUpScroll = function() {
+	this.optUp.hideUpScroll && this.optUp.hideUpScroll(this); // 回调
+}
+
+/* 结束上拉加载 */
+MeScroll.prototype.endUpScroll = function(isShowNoMore) {
+	if (isShowNoMore != null) { // isShowNoMore=null,不处理下拉状态,下拉刷新的时候调用
+		if (isShowNoMore) {
+			this.showNoMore(); // isShowNoMore=true,显示无更多数据
+		} else {
+			this.hideUpScroll(); // isShowNoMore=false,隐藏上拉加载
+		}
+	}
+	this.isUpScrolling = false; // 标记结束上拉加载
+}
+
+/* 重置上拉加载列表为第一页
+ *isShowLoading 是否显示进度布局;
+ * 1.默认null,不传参,则显示上拉加载的进度布局
+ * 2.传参true, 则显示下拉刷新的进度布局
+ * 3.传参false,则不显示上拉和下拉的进度 (常用于静默更新列表数据)
+ */
+MeScroll.prototype.resetUpScroll = function(isShowLoading) {
+	if (this.optUp && this.optUp.use) {
+		let page = this.optUp.page;
+		this.prePageNum = page.num; // 缓存重置前的页码,加载失败可退回
+		this.prePageTime = page.time; // 缓存重置前的时间,加载失败可退回
+		page.num = this.startNum; // 重置为第一页
+		page.time = null; // 重置时间为空
+		if (!this.isDownScrolling && isShowLoading !== false) { // 如果不是下拉刷新触发的resetUpScroll并且不配置列表静默更新,则显示进度;
+			if (isShowLoading == null) {
+				this.removeEmpty(); // 移除空布局
+				this.showUpScroll(); // 不传参,默认显示上拉加载的进度布局
+			} else {
+				this.showDownScroll(); // 传true,显示下拉刷新的进度布局,不清空列表
+			}
+		}
+		this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
+		this.num = page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
+		this.size = page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
+		this.time = page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
+		this.optUp.callback && this.optUp.callback(this); // 执行上拉回调
+	}
+}
+
+/* 设置page.num的值 */
+MeScroll.prototype.setPageNum = function(num) {
+	this.optUp.page.num = num - 1;
+}
+
+/* 设置page.size的值 */
+MeScroll.prototype.setPageSize = function(size) {
+	this.optUp.page.size = size;
+}
+
+/* 联网回调成功,结束下拉刷新和上拉加载
+ * dataSize: 当前页的数据量(必传)
+ * totalPage: 总页数(必传)
+ * systime: 服务器时间 (可空)
+ */
+MeScroll.prototype.endByPage = function(dataSize, totalPage, systime) {
+	let hasNext;
+	if (this.optUp.use && totalPage != null) hasNext = this.optUp.page.num < totalPage; // 是否还有下一页
+	this.endSuccess(dataSize, hasNext, systime);
+}
+
+/* 联网回调成功,结束下拉刷新和上拉加载
+ * dataSize: 当前页的数据量(必传)
+ * totalSize: 列表所有数据总数量(必传)
+ * systime: 服务器时间 (可空)
+ */
+MeScroll.prototype.endBySize = function(dataSize, totalSize, systime) {
+	let hasNext;
+	if (this.optUp.use && totalSize != null) {
+		let loadSize = (this.optUp.page.num - 1) * this.optUp.page.size + dataSize; // 已加载的数据总数
+		hasNext = loadSize < totalSize; // 是否还有下一页
+	}
+	this.endSuccess(dataSize, hasNext, systime);
+}
+
+/* 联网回调成功,结束下拉刷新和上拉加载
+ * dataSize: 当前页的数据个数(不是所有页的数据总和),用于上拉加载判断是否还有下一页.如果不传,则会判断还有下一页
+ * hasNext: 是否还有下一页,布尔类型;用来解决这个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据dataSize判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
+ * systime: 服务器时间(可空);用来解决这个小问题:当准备翻下一页时,数据库新增了几条记录,此时翻下一页,前面的几条数据会和上一页的重复;这里传入了systime,那么upCallback的page.time就会有值,把page.time传给服务器,让后台过滤新加入的那几条记录
+ */
+MeScroll.prototype.endSuccess = function(dataSize, hasNext, systime) {
+	let me = this;
+	// 结束下拉刷新
+	if (me.isDownScrolling) me.endDownScroll();
+
+	// 结束上拉加载
+	if (me.optUp.use) {
+		let isShowNoMore; // 是否已无更多数据
+		if (dataSize != null) {
+			let pageNum = me.optUp.page.num; // 当前页码
+			let pageSize = me.optUp.page.size; // 每页长度
+			// 如果是第一页
+			if (pageNum === 1) {
+				if (systime) me.optUp.page.time = systime; // 设置加载列表数据第一页的时间
+			}
+			if (dataSize < pageSize || hasNext === false) {
+				// 返回的数据不满一页时,则说明已无更多数据
+				me.optUp.hasNext = false;
+				if (dataSize === 0 && pageNum === 1) {
+					// 如果第一页无任何数据且配置了空布局
+					isShowNoMore = false;
+					me.showEmpty();
+				} else {
+					// 总列表数少于配置的数量,则不显示无更多数据
+					let allDataSize = (pageNum - 1) * pageSize + dataSize;
+					if (allDataSize < me.optUp.noMoreSize) {
+						isShowNoMore = false;
+					} else {
+						isShowNoMore = true;
+					}
+					me.removeEmpty(); // 移除空布局
+				}
+			} else {
+				// 还有下一页
+				isShowNoMore = false;
+				me.optUp.hasNext = true;
+				me.removeEmpty(); // 移除空布局
+			}
+		}
+
+		// 隐藏上拉
+		me.endUpScroll(isShowNoMore);
+	}
+}
+
+/* 回调失败,结束下拉刷新和上拉加载 */
+MeScroll.prototype.endErr = function() {
+	// 结束下拉,回调失败重置回原来的页码和时间
+	if (this.isDownScrolling) {
+		let page = this.optUp.page;
+		if (page && this.prePageNum) {
+			page.num = this.prePageNum;
+			page.time = this.prePageTime;
+		}
+		this.endDownScroll();
+	}
+	// 结束上拉,回调失败重置回原来的页码
+	if (this.isUpScrolling) {
+		this.optUp.page.num--;
+		this.endUpScroll(false);
+	}
+}
+
+/* 显示空布局 */
+MeScroll.prototype.showEmpty = function() {
+	this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(true)
+}
+
+/* 移除空布局 */
+MeScroll.prototype.removeEmpty = function() {
+	this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(false)
+}
+
+/* 显示回到顶部的按钮 */
+MeScroll.prototype.showTopBtn = function() {
+	if (!this.topBtnShow) {
+		this.topBtnShow = true;
+		this.optUp.toTop.onShow && this.optUp.toTop.onShow(true);
+	}
+}
+
+/* 隐藏回到顶部的按钮 */
+MeScroll.prototype.hideTopBtn = function() {
+	if (this.topBtnShow) {
+		this.topBtnShow = false;
+		this.optUp.toTop.onShow && this.optUp.toTop.onShow(false);
+	}
+}
+
+/* 获取滚动条的位置 */
+MeScroll.prototype.getScrollTop = function() {
+	return this.scrollTop || 0
+}
+
+/* 记录滚动条的位置 */
+MeScroll.prototype.setScrollTop = function(y) {
+	this.scrollTop = y;
+}
+
+/* 滚动到指定位置 */
+MeScroll.prototype.scrollTo = function(y, t) {
+	this.myScrollTo && this.myScrollTo(y, t) // scrollview需自定义回到顶部方法
+}
+
+/* 自定义scrollTo */
+MeScroll.prototype.resetScrollTo = function(myScrollTo) {
+	this.myScrollTo = myScrollTo
+}
+
+/* 滚动条到底部的距离 */
+MeScroll.prototype.getScrollBottom = function() {
+	return this.getScrollHeight() - this.getClientHeight() - this.getScrollTop()
+}
+
+/* 计步器
+ star: 开始值
+ end: 结束值
+ callback(step,timer): 回调step值,计步器timer,可自行通过window.clearInterval(timer)结束计步器;
+ t: 计步时长,传0则直接回调end值;不传则默认300ms
+ rate: 周期;不传则默认30ms计步一次
+ * */
+MeScroll.prototype.getStep = function(star, end, callback, t, rate) {
+	let diff = end - star; // 差值
+	if (t === 0 || diff === 0) {
+		callback && callback(end);
+		return;
+	}
+	t = t || 300; // 时长 300ms
+	rate = rate || 30; // 周期 30ms
+	let count = t / rate; // 次数
+	let step = diff / count; // 步长
+	let i = 0; // 计数
+	let timer = setInterval(function() {
+		if (i < count - 1) {
+			star += step;
+			callback && callback(star, timer);
+			i++;
+		} else {
+			callback && callback(end, timer); // 最后一次直接设置end,避免计算误差
+			clearInterval(timer);
+		}
+	}, rate);
+}
+
+/* 滚动容器的高度 */
+MeScroll.prototype.getClientHeight = function(isReal) {
+	let h = this.clientHeight || 0
+	if (h === 0 && isReal !== true) { // 未获取到容器的高度,可临时取body的高度 (可能会有误差)
+		h = this.getBodyHeight()
+	}
+	return h
+}
+MeScroll.prototype.setClientHeight = function(h) {
+	this.clientHeight = h;
+}
+
+/* 滚动内容的高度 */
+MeScroll.prototype.getScrollHeight = function() {
+	return this.scrollHeight || 0;
+}
+MeScroll.prototype.setScrollHeight = function(h) {
+	this.scrollHeight = h;
+}
+
+/* body的高度 */
+MeScroll.prototype.getBodyHeight = function() {
+	return this.bodyHeight || 0;
+}
+MeScroll.prototype.setBodyHeight = function(h) {
+	this.bodyHeight = h;
+}
+
+/* 阻止浏览器默认滚动事件 */
+MeScroll.prototype.preventDefault = function(e) {
+	// 小程序不支持e.preventDefault
+	// app的bounce只能通过配置pages.json的style.app-plus.bounce为"none"来禁止
+	// cancelable:是否可以被禁用; defaultPrevented:是否已经被禁用
+	if (e && e.cancelable && !e.defaultPrevented) e.preventDefault()
+}
+
+/* 是否允许下拉回弹(橡皮筋效果); true或null为允许; false禁止bounce */
+MeScroll.prototype.setBounce = function(isBounce) {
+	// #ifdef H5
+	if (isBounce === false) {
+		this.optUp.isBounce = false; // 禁止
+		// 标记当前页使用了mescroll (需延时,确保page已切换)
+		setTimeout(function() {
+			let uniPageDom = document.getElementsByTagName('uni-page')[0];
+			uniPageDom && uniPageDom.setAttribute('use_mescroll', true)
+		}, 30);
+		// 避免重复添加事件
+		if (window.isSetBounce) return;
+		window.isSetBounce = true;
+		// 需禁止window的touchmove事件才能有效的阻止bounce
+		window.bounceTouchmove = function(e) {
+			let el = e.target;
+			// 当前touch的元素及父元素是否要拦截touchmove事件
+			let isPrevent = true;
+			while (el !== document.body && el !== document) {
+				if (el.tagName === 'UNI-PAGE') { // 只扫描当前页
+					if (!el.getAttribute('use_mescroll')) {
+						isPrevent = false; // 如果当前页没有使用mescroll,则不阻止
+					}
+					break;
+				}
+				let cls = el.classList;
+				if (cls) {
+					if (cls.contains('mescroll-touch')) { // 采用scroll-view 此处不能过滤mescroll-uni,否则下拉仍然有回弹
+						isPrevent = false; // mescroll-touch无需拦截touchmove事件
+						break;
+					} else if (cls.contains('mescroll-touch-x') || cls.contains('mescroll-touch-y')) {
+						// 如果配置了水平或者垂直滑动
+						let curX = e.touches ? e.touches[0].pageX : e.clientX; // 当前第一个手指距离列表顶部的距离x
+						let curY = e.touches ? e.touches[0].pageY : e.clientY; // 当前第一个手指距离列表顶部的距离y
+						if (!this.preWinX) this.preWinX = curX; // 设置上次移动的距离x
+						if (!this.preWinY) this.preWinY = curY; // 设置上次移动的距离y
+						// 计算两点之间的角度
+						let x = Math.abs(this.preWinX - curX);
+						let y = Math.abs(this.preWinY - curY);
+						let z = Math.sqrt(x * x + y * y);
+						this.preWinX = curX; // 记录本次curX的值
+						this.preWinY = curY; // 记录本次curY的值
+						if (z !== 0) {
+							let angle = Math.asin(y / z) / Math.PI * 180; // 角度区间 [0,90]
+							if ((angle <= 45 && cls.contains('mescroll-touch-x')) || (angle > 45 && cls.contains('mescroll-touch-y'))) {
+								isPrevent = false; // 水平滑动或者垂直滑动,不拦截touchmove事件
+								break;
+							}
+						}
+					}
+				}
+				el = el.parentNode; // 继续检查其父元素
+			}
+			// 拦截touchmove事件:是否可以被禁用&&是否已经被禁用 (这里不使用me.preventDefault(e)的方法,因为某些情况下会报找不到方法的异常)
+			if (isPrevent && e.cancelable && !e.defaultPrevented && typeof e.preventDefault === "function") e.preventDefault();
+		}
+		window.addEventListener('touchmove', window.bounceTouchmove, {
+			passive: false
+		});
+	} else {
+		this.optUp.isBounce = true; // 允许
+		if (window.bounceTouchmove) {
+			window.removeEventListener('touchmove', window.bounceTouchmove);
+			window.bounceTouchmove = null;
+			window.isSetBounce = false;
+		}
+	}
+	// #endif
+}

+ 306 - 0
comps/mescroll-uni/mescroll-uni.vue

@@ -0,0 +1,306 @@
+<template>
+	<view class="mescroll-uni-warp">
+		<scroll-view :id="viewId" class="mescroll-uni" :class="{'mescroll-uni-fixed':fixed}" :style="{'padding-top':padTop,'padding-bottom':padBottom,'top':fixedTop,'bottom':fixedBottom}" :scroll-top="scrollTop" :scroll-with-animation="scrollAnim" @scroll="scroll" @touchstart="touchstartEvent" @touchmove="touchmoveEvent" @touchend="touchendEvent" @touchcancel="touchendEvent" :scroll-y='scrollAble' :throttle="mescroll.optUp.onScroll==null" :enable-back-to-top="true">
+			<view :style="{'transform': translateY, 'transition': transition}">
+				<!-- 下拉加载区域-->
+				<view v-if="mescroll.optDown.use" class="mescroll-downwarp">
+					<view class="downwarp-content">
+						<view class="downwarp-progress" :class="{'mescroll-rotate':isDownLoading}" :style="{'transform':downRotate}"></view>
+						<view class="downwarp-tip">{{downText}}</view>
+					</view>
+				</view>
+
+				<!-- 列表内容 -->
+				<slot></slot>
+
+				<!-- 空布局 -->
+				<view v-if="isShowEmpty" style="padding-top: 200rpx;" class="mescroll-empty" :class="{'empty-fixed':optEmpty.fixed}" :style="{'z-index':optEmpty.zIndex,'top':optEmpty.top}">
+					<image v-if="optEmpty.icon" style="width: 160rpx;" class="empty-icon" :src="optEmpty.icon" mode="widthFix" />
+					<view v-if="optEmpty.tip" class="empty-tip">{{optEmpty.tip}}</view>
+					<view v-if="optEmpty.btnText" class="empty-btn" @click="emptyClick">{{optEmpty.btnText}}</view>
+				</view>
+
+				<!-- 上拉加载区域 -->
+				<view v-if="mescroll.optUp.use" class="mescroll-upwarp" :class="isLivePage?'padding-tb10':'padding-tb30'" >
+					<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
+					<view v-show="isUpLoading">
+						<view class="upwarp-progress mescroll-rotate"></view>
+						<view class="upwarp-tip">{{mescroll.optUp.textLoading}}</view>
+					</view>
+					<!-- 无数据 -->
+					<view v-if="!isDownLoading && isUpNoMore" class="upwarp-nodata">{{mescroll.optUp.textNoMore}}</view>
+				</view>
+			</view>
+		</scroll-view>
+
+		<!-- 回到顶部按钮 (fixed元素,需写在scroll-view外面,防止滚动的时候抖动)-->
+		<image v-if="mescroll.optUp.toTop.src" class="mescroll-totop" :class="{'mescroll-fade-in':isShowToTop}" :src="mescroll.optUp.toTop.src" mode="widthFix" @click="toTopClick" />
+	</view>
+</template>
+
+<script>
+	// 引入mescroll-uni.js,处理核心逻辑
+	import MeScroll from './mescroll-uni.js';
+	// 引入全局配置
+	import GlobalOption from './mescroll-uni-option.js';
+
+	export default {
+		data() {
+			return {
+				mescroll: null, // mescroll实例
+				viewId: 'id_' + Math.random().toString(36).substr(2), // 随机生成mescroll的id(不能数字开头,否则找不到元素)
+				downHight: 0, //下拉刷新: 容器高度
+				downRotate: 0, //下拉刷新: 圆形进度条旋转的角度
+				downText: '', //下拉刷新: 提示的文本
+				isDownReset: false, //下拉刷新: 是否显示重置的过渡动画
+				isDownLoading: false, //下拉刷新: 是否显示加载中
+				isUpLoading: false, // 上拉加载: 是否显示 "加载中..."
+				isUpNoMore: false, // 上拉加载: 是否显示 "-- END --"
+				isShowEmpty: false, // 是否显示空布局
+				isShowToTop: false, // 是否显示回到顶部按钮
+				scrollAble: true, // 是否禁止下滑 (下拉时禁止,避免抖动)
+				scrollTop: 0, // 滚动条的位置
+				scrollAnim: false, // 是否开启滚动动画
+				windowTop: 0, // 可使用窗口的顶部位置
+				windowBottom: 0 // 可使用窗口的底部位置
+			}
+		},
+		props: {
+			isLivePage:{
+				type:Boolean,
+				default:false
+			},
+			down: Object, // 下拉刷新的参数配置
+			up: Object, // 上拉加载的参数配置
+			top: [String, Number], // 下拉布局往下偏移的数值, 已默认单位为upx.
+			bottom: [String, Number], // 上拉布局往上偏移的数值, 已默认单位为upx.
+			fixed: { // 是否通过fixed固定mescroll的高度, 默认true
+				type: Boolean,
+				default () {
+					return true
+				}
+			}
+		},
+		computed: {
+			// top数值,单位upx,需转成px. 目的是使下拉布局往下偏移
+			numTop() {
+				return uni.upx2px(Number(this.top || 0))
+			},
+			fixedTop() {
+				return this.fixed ? (this.numTop + this.windowTop) + 'px' : 0
+			},
+			padTop() {
+				return !this.fixed ? this.numTop + 'px' : 0
+			},
+			// bottom数值,单位upx,需转成px 目的是使上拉布局往上偏移
+			numBottom() {
+				return uni.upx2px(Number(this.bottom || 0))
+			},
+			fixedBottom() {
+				return this.fixed ? (this.numBottom + this.windowBottom) + 'px' : 0
+			},
+			padBottom() {
+				return !this.fixed ? this.numBottom + 'px' : 0
+			},
+			// 空布局的配置
+			optEmpty() {
+				return this.mescroll.optUp.empty
+			},
+			// 过渡
+			transition() {
+				return this.isDownReset ? 'transform 300ms' : ''
+			},
+			translateY() {
+				return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : '' // transform会使fixed失效,需注意把fixed元素写在mescroll之外
+			}
+		},
+		methods: {
+			//注册列表滚动事件,用于下拉刷新
+			scroll(e) {
+				this.mescroll.scroll(e.detail, () => {
+					this.$emit('scroll', this.mescroll) // 此时可直接通过 this.mescroll.scrollTop获取滚动条位置; this.mescroll.isScrollUp获取是否向上滑动
+				})
+			},
+			//注册列表touchstart事件,用于下拉刷新
+			touchstartEvent(e) {
+				this.mescroll.touchstartEvent(e);
+			},
+			//注册列表touchmove事件,用于下拉刷新
+			touchmoveEvent(e) {
+				this.mescroll.touchmoveEvent(e);
+			},
+			//注册列表touchend事件,用于下拉刷新
+			touchendEvent(e) {
+				this.mescroll.touchendEvent(e);
+			},
+			// 点击空布局的按钮回调
+			emptyClick() {
+				this.$emit('emptyclick', this.mescroll)
+			},
+			// 点击回到顶部的按钮回调
+			toTopClick() {
+				this.isShowToTop = false; // 回到顶部按钮需要先隐藏,再执行回到顶部,避免闪动
+				this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部
+				this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调
+			},
+			// 更新滚动区域的高度 (使内容不满屏和到底,都可继续翻页)
+			setClientHeight() {
+				if (this.mescroll.getClientHeight(true) === 0 && !this.isExec) {
+					this.isExec = true; // 避免多次获取
+					this.$nextTick(() => { // 确保dom已渲染
+						let view = uni.createSelectorQuery().in(this).select('#' + this.viewId);
+						view.boundingClientRect(data => {
+							this.isExec = false;
+							if (data) {
+								this.mescroll.setClientHeight(data.height);
+							} else if (this.clientNum != 3) { // 极少部分情况,可能dom还未渲染完毕,递归获取,最多重试3次
+								this.clientNum = this.clientNum == null ? 1 : this.clientNum + 1;
+								setTimeout(() => {
+									this.setClientHeight()
+								}, this.clientNum * 100)
+							}
+						}).exec();
+					})
+				}
+			}
+		},
+		// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效
+		created() {
+			let vm = this;
+
+			let diyOption = {
+				// 下拉刷新的配置
+				down: {
+					inOffset(mescroll) {
+						// 下拉的距离进入offset范围内那一刻的回调
+						vm.scrollAble = false; // 禁止下拉,避免抖动 (自定义mescroll组件时,此行不可删)
+						vm.isDownReset = false; // 不重置高度 (自定义mescroll组件时,此行不可删)
+						vm.isDownLoading = false; // 不显示加载中
+						vm.downText = mescroll.optDown.textInOffset; // 设置文本
+					},
+					outOffset(mescroll) {
+						// 下拉的距离大于offset那一刻的回调
+						vm.scrollAble = false; // 禁止下拉,避免抖动 (自定义mescroll组件时,此行不可删)
+						vm.isDownReset = false; // 不重置高度 (自定义mescroll组件时,此行不可删)
+						vm.isDownLoading = false; // 不显示加载中
+						vm.downText = mescroll.optDown.textOutOffset; // 设置文本
+					},
+					onMoving(mescroll, rate, downHight) {
+						// 下拉过程中的回调,滑动过程一直在执行; rate下拉区域当前高度与指定距离的比值(inOffset: rate<1; outOffset: rate>=1); downHight当前下拉区域的高度
+						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
+						vm.downRotate = 'rotate(' + 360 * rate + 'deg)'; // 设置旋转角度
+					},
+					showLoading(mescroll, downHight) {
+						// 显示下拉刷新进度的回调
+						vm.scrollAble = true; // 开启下拉 (自定义mescroll组件时,此行不可删)
+						vm.isDownReset = true; // 重置高度 (自定义mescroll组件时,此行不可删)
+						vm.isDownLoading = true; // 显示加载中
+						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
+						vm.downText = mescroll.optDown.textLoading; // 设置文本
+					},
+					endDownScroll(mescroll) {
+						vm.scrollAble = true; // 开启下拉 (自定义mescroll组件时,此行不可删)
+						vm.isDownReset = true; // 重置高度 (自定义mescroll组件时,此行不可删)
+						vm.isDownLoading = false; // 不显示加载中
+						vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
+					},
+					// 派发下拉刷新的回调
+					callback: function(mescroll) {
+						vm.$emit('down', mescroll)
+					}
+				},
+				// 上拉加载的配置
+				up: {
+					// 显示加载中的回调
+					showLoading() {
+						vm.isUpLoading = true;
+						vm.isUpNoMore = false;
+					},
+					// 显示无更多数据的回调
+					showNoMore() {
+						vm.isUpLoading = false;
+						vm.isUpNoMore = true;
+					},
+					// 隐藏上拉加载的回调
+					hideUpScroll() {
+						vm.isUpLoading = false;
+						vm.isUpNoMore = false;
+					},
+					// 空布局
+					empty: {
+						onShow(isShow) { // 显示隐藏的回调
+							vm.isShowEmpty = isShow;
+						}
+					},
+					// 回到顶部
+					toTop: {
+						onShow(isShow) { // 显示隐藏的回调
+							vm.isShowToTop = isShow;
+						}
+					},
+					// 派发上拉加载的回调
+					callback: function(mescroll) {
+						vm.$emit('up', mescroll);
+						// 更新容器的高度 (多mescroll的情况)
+						vm.setClientHeight()
+					}
+				}
+			}
+
+			MeScroll.extend(diyOption, GlobalOption); // 混入全局的配置
+			let myOption = JSON.parse(JSON.stringify({
+				'down': vm.down,
+				'up': vm.up
+			})) // 深拷贝,避免对props的影响
+			MeScroll.extend(myOption, diyOption); // 混入具体界面的配置
+
+			// 初始化MeScroll对象
+			vm.mescroll = new MeScroll(myOption);
+			vm.mescroll.viewId = vm.viewId; // 附带id
+			// init回调mescroll对象
+			vm.$emit('init', vm.mescroll);
+
+			// 设置高度
+			uni.getSystemInfo({
+				success(res) {
+					if (res.windowTop) vm.windowTop = res.windowTop; // 修正app和H5的top值
+					if (res.windowBottom) vm.windowBottom = res.windowBottom; // 修正app和H5的bottom值
+					vm.mescroll.setBodyHeight(res.windowHeight); // 使down的bottomOffset生效
+				}
+			});
+
+			// 因为使用的是scrollview,这里需自定义scrollTo
+			vm.mescroll.resetScrollTo((y, t) => {
+				let curY = vm.mescroll.getScrollTop()
+				if (t === 0) {
+					vm.scrollAnim = false;
+					vm.scrollTop = curY;
+					vm.$nextTick(function() {
+						vm.scrollTop = y
+					})
+				} else {
+					vm.scrollAnim = true;
+					vm.mescroll.getStep(curY, y, step => { // 此写法可支持配置t
+						vm.scrollTop = step
+					}, t)
+				}
+			})
+		},
+		mounted() {
+			// 设置容器的高度
+			this.setClientHeight()
+		}
+	}
+</script>
+
+<style>
+	@import "./mescroll-uni.css";
+	
+	.padding-tb10{
+		padding: 10rpx 0;
+	}
+	
+	.padding-tb30{
+		padding: 30rpx 0;
+	}
+</style>

+ 435 - 0
comps/mosowe-swiper.vue

@@ -0,0 +1,435 @@
+<template>
+	<view  class="mosowe-swiper" :style="'height:'+height+'rpx'">
+		<swiper
+			class="uni-swiper"
+			:indicator-dots="false"
+			:indicator-color="indicatorColor"
+			:indicator-active-color="indicatorActiveColor"
+			:autoplay="autoplay"
+			:current="active"
+			:interval="interval"
+			:duration="duration"
+			:vertical="vertical"
+			:disable-touch="touchable"
+			:previous-margin="canPyramid ? pyramidMargin : ''"
+			:next-margin="canPyramid ? pyramidMargin : ''"
+			:display-multiple-items="canPyramid ? 1 : itemNums"
+			circular
+			@change="bannerChange"
+			>
+		<!-- 非微信小程序 -->
+		<!-- #ifndef MP-WEIXIN -->
+				<swiper-item
+					class="item" 
+					v-for="(item,index) of lists" 
+					:key="index"
+					:class="canPyramid && active !== index ? 'swiper-pyramid' : canPyramid && active === index ? 'swiper-active' : ''"
+					@click="bannerClick({item,index})"
+					>
+					<!-- 仅图片展示 -->
+					<image :src="imageKey ? item[imageKey] : item" class="image" v-if="swiperType === 'image'"></image>
+					<!-- 仅文字展示 -->
+					<text  class="text" v-if="swiperType === 'text'">{{textKey ? item[textKey] : item}}</text>
+					<!-- 图文左右轮播 -->
+					<view class="imageTextLine"  v-if="swiperType === 'imageTextLine'">
+						<image class="avatar" :src="item[imageKey]" />
+						<text class="content">{{item[textKey]}}</text>
+					</view>
+					<view  style="display: flex;flex-wrap: wrap;">
+					  <view v-for="(child,idx) in item.tagGroups" :key="idx" @tap.stop="onCategory(child)" style="width: 142upx;display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: 20upx;">
+						  <image :src="child.path1" mode="aspectFit" style="width: 100upx;height: 100upx;"></image>
+						  <view style="font-size: 24upx;margin-top: 20upx;">{{child.name}}</view>
+					  </view>
+					</view>
+				</swiper-item>
+		<!-- #endif -->
+		
+		
+		<!-- 微信小程序内 -->
+		<!-- #ifdef MP-WEIXIN -->
+			<!-- 可手动滑动 -->
+			<block v-if="!touchable">
+				<swiper-item 
+					class="item" 
+					v-for="(item,index) of lists" 
+					:key="index"
+					:class="canPyramid && active !== index ? 'swiper-pyramid' : canPyramid && active === index ? 'swiper-active' : ''"
+					@click="bannerClick({item,index})"
+					>
+					<!-- 仅图片展示 -->
+					<image :src="imageKey ? item[imageKey] : item" class="image" v-if="swiperType === 'image'"></image>
+					<!-- 仅文字展示 -->
+					<text  class="text" v-if="swiperType === 'text'">{{textKey ? item[textKey] : item}}</text>
+					<!-- 图文左右轮播 -->
+					<view class="imageTextLine"  v-if="swiperType === 'imageTextLine'">
+						<image class="avatar" :src="item[imageKey]" />
+						<text class="content">{{item[textKey]}}</text>
+					</view>
+					<view  style="display: flex;flex-wrap: wrap;">
+					  <view v-for="(child,idx) in item.tagGroups" :key="idx" @tap.stop="onCategory(child)" style="width: 142upx;display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: 20upx;">
+						  <image :src="child.path1" mode="aspectFit" style="width: 100upx;height: 100upx;"></image>
+						  <view style="font-size: 24upx;margin-top: 20upx;">{{child.name}}</view>
+					  </view>
+					</view>
+				</swiper-item>				
+			</block>
+			<!-- 禁用手动滑动 -->
+			<block v-if="touchable">
+				<swiper-item
+					class="item" 
+					v-for="(item,index) of lists" 
+					:key="index"
+					:class="canPyramid && active !== index ? 'swiper-pyramid' : canPyramid && active === index ? 'swiper-active' : ''"
+					@touchstart.stop="WXAPP_bannerTouch"
+					@touchend="WXAPP_bannerTouchEnd({item,index})"
+					>
+					<!-- 仅图片展示 -->
+					<image :src="imageKey ? item[imageKey] : item" class="image" v-if="swiperType === 'image'" />
+					<!-- 仅文字展示 -->
+					<view  class="text" v-if="swiperType === 'text'"><text>{{textKey ? item[textKey] : item}}</text></view>
+					<!-- 图文左右轮播 -->
+					<view class="imageTextLine"  v-if="swiperType === 'imageTextLine'">
+						<image class="avatar" :src="item[imageKey]" />
+						<text class="content">{{item[textKey]}}</text>
+					</view>
+					<view  style="display: flex;flex-wrap: wrap;">
+					  <view v-for="(child,idx) in item.tagGroups" :key="idx" @tap.stop="onCategory(child)" style="width: 142upx;display: flex;flex-direction: column;align-items: center;justify-content: center;margin-top: 20upx;">
+						  <image :src="child.path1" mode="aspectFit" style="width: 100upx;height: 100upx;"></image>
+						  <view style="font-size: 24upx;margin-top: 20upx;">{{child.name}}</view>
+					  </view>
+					</view>
+				</swiper-item>				
+			</block>
+		<!-- #endif -->
+		</swiper>
+		
+		
+		<!-- 数字指示 -->
+		<view class="custom-indicator" v-if="indicator === 'number'">
+			{{ active + 1 }}/{{lists.length}}
+		</view>
+		<view class="custom-rectangle" v-if="indicator === 'rectangle'&&lists.length>1">  
+			<view class="content">
+				<view v-for="(item,index) in lists" :index="index" :key="index" :class="{'rectangleActive':  index == active}" class="rectangle"></view>  
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+  name: 'mosowe-swiper',
+  components: {},
+  props: {
+		current: { // 当前展示的索引
+			type:Number,
+			default: 0
+		},
+		autoplay: { // 是否自动切换
+			type: Boolean,
+			default: true
+		},
+		interval: { // 自动切换时间间隔
+			type: Number,
+			default: 3000
+		},
+		duration: { // 切换动画时长
+			type: Number,
+			default: 500
+		},
+		vertical: { // 滑动方向是否为纵向
+			type: Boolean,
+			default: false
+		},
+		indicator: { // 指示点样式:dots点,number数字右下角,空则不会显示
+			type: String,
+			default: 'rectangle'
+		},
+		indicatorColor: { // dot点样式:默认颜色
+			type: String,
+			default: '#C1C1C1'
+		},
+		indicatorActiveColor: { // dot点选中样式:高亮颜色
+			type: String,
+			default: '#C1C1C1'
+		},
+		scene: { // 场景值
+			type: String,
+			default: ''
+		},
+		touchable: { // 是否禁用手动滑动
+			type: Boolean,
+			default: false
+		},
+		lists: { // 轮播列表
+			type: Array,
+			default: () => {
+				return [];
+			} 
+		},
+		swiperType: { // 轮播类型:image图片轮播,imageTextLine图文一行轮播,text文本轮播
+			type: String,
+			default: 'image'
+		},
+		previewImage: { // 开启图片预览
+			type: Boolean,
+			default: false
+		},
+		imageKey: { // 图片的key值,重复使用的组件可能遇到不同的key,此处传图片的key
+			type: String,
+			default: ''
+		},
+		textKey: { // 文本的key值,重复使用的组件可能遇到不同的key,此处传文本的key
+			type: String,
+			default: ''
+		},
+		height: { // 轮播区的高度,单位rpx
+			type: Number,
+			default: 300
+		},
+		pyramid: { // 金字塔式,横向且纯图模式有效,开启金字塔模式时,active初始化最少为1,最大为this.lists.length -2
+			type: Boolean,
+			default: false
+		},
+		pyramidMargin: { // 金字塔式,前后露出的距离,单位rpx,px
+			type: String,
+			default: '30rpx'
+		},
+		itemNums: { // 同时展示个数,开启金字塔模式时, itemNums = 1
+			type: String,
+			default: '1'
+		}
+	},
+  data () {
+    return {
+			active: 0,
+			activePrev: -1,
+			activeNext: -1,
+			canPyramid: false,
+			touchStartTime:0, // 微信小程序端:触摸事件判断点击或滑动
+    };
+  },
+	created () {
+		this.active = this.current
+		if (this.pyramid && this.swiperType === 'image' && !this.vertical) {
+			this.canPyramid = true
+			if (this.active === 0 || this.active < 0 || this.active > this.lists.length - 1) {
+				this.active = 1
+			} else if (this.active === this.lists.length - 1) {
+				this.active = this.lists.length -2
+			}
+		}
+	},
+
+  methods: {
+	  onCategory(item){
+		  if(item.id){
+		
+			  uni.setStorage({
+			  			key: 'categoryId',
+			  			data: item.id,
+			  			success: function() {
+							uni.navigateTo({
+								url:"/pagesM/pages/category"
+							})
+			  			}
+			  		})
+		  }
+		  
+		  
+	  },
+	  onMore(item) {
+	    let params = item.param;
+	    uni.navigateTo({
+	      url: "/pagesM/pages/category?params=" + JSON.stringify(params)
+	    })
+	  },
+		// 微信小程序:banner触摸时,禁止手动滑动的时候触发
+		WXAPP_bannerTouch () {
+			if(this.previewImage) {
+				this.touchStartTime = new Date().getTime()
+			}
+		},
+		// 微信小程序:触摸完
+		WXAPP_bannerTouchEnd (item) {
+			let t = new Date().getTime()
+			if (t-this.touchStartTime <= 200) { // 点击
+				this.bannerClick(item)
+			} else {
+				if (this.touchable) {
+					return false
+				}
+			}
+		},
+		// banner轮播时
+		bannerChange (e) {
+			this.active = e.detail.current;
+			this.$emit('change', e.detail.current);
+		},
+		// banner点击时
+		bannerClick (item) {
+			console.log(item);
+			if (this.swiperType === 'image' && this.previewImage) { // 纯图片模式下,开启预览模式
+				let urls = [];
+				if (this.imageKey) {
+					for (let image of this.lists) {
+						urls.push(image[this.imageKey]);
+					}					
+				} else {
+					urls = this.lists;
+				}
+				console.log(urls)
+				uni.previewImage({
+					current: item.index,
+					urls: urls
+				});				
+			}
+			this.$emit('bclick', item);
+		},
+		
+  }
+};
+</script>
+
+<style lang="scss">
+	
+.mosowe-swiper{
+	position: relative;
+	.uni-swiper {
+		height: inherit;
+		.uni-swiper-dot{
+			width: 20px !important;
+			height: 8px !important;
+			border-radius: 4px;
+		}
+		.item {
+			box-sizing: border-box;
+			.image{
+				width: 100%;
+				height: 100%;
+			}
+			// 支付宝
+			/* #ifdef MP-ALIPAY */
+			&.swiper-pyramid{
+				padding: 0 30rpx;
+			}
+			/* #endif */
+			
+			// 非支付宝
+			/* #ifndef MP-ALIPAY */
+			&.swiper-pyramid{
+				padding: 30rpx;
+			}
+			&.swiper-prev {
+				animation: prev .5s forwards;
+			}
+			&.swiper-next {
+				animation: next .5s forwards;
+			}
+			&.swiper-active {
+				animation: actives .5s forwards;
+			}
+			/* #endif */
+		}
+	}
+	// 纯图
+	.image{
+		width: 100%;
+		height: 100%;
+	}
+	// 纯文
+	.text{
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		width: 100%;
+		display: block;
+	}
+	// 图文一行
+	.imageTextLine {
+		overflow: hidden;
+		width: 100%;
+		display: flex;
+		align-items: center;
+		.avatar{
+			flex: 0 0 50rpx;
+			height: 50rpx;
+			border-radius: 50%;
+			margin-right: 10rpx;
+		}
+		.content{
+			flex: 1;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+			overflow: hidden;
+		}
+	}
+	.custom-indicator{
+		position: absolute;
+		right: 30rpx;
+		bottom: 30rpx;
+		background: rgba(0, 0, 0, 0.2);
+		width: 80rpx;
+		height: 40rpx;
+		line-height: 40rpx;
+		font-size: 24rpx;
+		color: #fff;
+		border-radius: 30rpx;
+		text-align: center;
+	}
+	.custom-rectangle{
+		position: absolute;
+		left: 0;
+		right: 0;
+		bottom: 20upx;
+		display: flex;
+		justify-content: center;
+		.content{
+			width: auto;
+			background-color: #C1C1C1;
+			display: flex;
+			border-radius: 4upx;
+			overflow: hidden;
+			.rectangle{
+				width: 44upx;
+				height: 6upx;
+				border-radius: 4upx;
+				background-color: #C1C1C1;
+				opacity:0.35;
+			}
+			.rectangleActive{
+				width: 44upx;
+				height: 6upx;
+				border-radius: 4upx;
+				background-color: #DB4444;
+				opacity:1;
+			}
+		}
+		
+	}
+}
+@keyframes prev {
+	0%{
+		padding: 0;
+	}
+	100% {
+		padding: 30rpx;
+	}
+}
+@keyframes next {
+	0%{
+		padding: 0;
+	}
+	100% {
+		padding: 30rpx;
+	}
+}
+@keyframes actives {
+	0%{
+		padding: 30rpx;
+	}
+	100% {
+		padding: 0;
+	}
+}
+</style>

+ 65 - 0
comps/mp-time/date.js

@@ -0,0 +1,65 @@
+//字符串拼接
+function strFormat(str) {
+	return str < 10 ? `0${str}` : str
+}
+//时间戳转日期
+export function timeStamp(time) {
+	const dates = new Date(time)
+	const year = dates.getFullYear()
+	const month = dates.getMonth() + 1
+	const date = dates.getDate()
+	const day = dates.getDay()
+	const hour = dates.getHours()
+	const min = dates.getMinutes()
+	const days = ['日', '一', '二', '三', '四', '五', '六']
+	return {
+		allDate: `${year}/${strFormat(month)}/${strFormat(date)}`,//注:此处ios系统如"-"分割无法显示,只能用"/"分割符
+		date: `${strFormat(month)}-${strFormat(date)}`, //返回的日期 07-01
+		day: `星期${days[day]}`, //返回的礼拜天数  星期一
+		hour: strFormat(hour) + ':' + strFormat(min) //返回的时钟 08:00
+	}
+}
+//获取最近7天的日期和礼拜天数
+export function dateData() {
+	const time = []
+	const date = new Date()
+	const now = date.getTime() //获取当前日期的时间戳
+	let timeStr = 3600 * 24 * 1000 //一天的时间戳
+	for (let i = 0; i < 7; i++) {
+		const timeObj = {}
+		timeObj.date = timeStamp(now + timeStr * i).date //保存日期
+		timeObj.timeStamp = now + timeStr * i //保存时间戳
+		if (i == 0) {
+			timeObj.week = '今天'
+		} else if (i == 1) {
+			timeObj.week = '明天'
+		} else if (i == 2) {
+			timeObj.week = '后天'
+		} else {
+			timeObj.week = timeStamp(now + timeStr * i).day
+		}
+		time.push(timeObj)
+	}
+	return time
+}
+//时间数组
+export function timeData(startTime = '08:00', endTime = '18:30', timeInterval = 0.5) {
+	const time = []
+	const date = timeStamp(Date.now()).allDate
+	const startDate = `${date} ${startTime}`
+	const endDate = `${date} ${endTime}`
+	const startTimeStamp = new Date(startDate).getTime()
+	const endTimeStamp = new Date(endDate).getTime()
+	const timeStr = 3600 * 1000 * timeInterval
+	let count = 0
+	for (let i = startTimeStamp; i <= endTimeStamp; i = i + timeStr) {
+		const timeObj = {}
+		timeObj.time = timeStamp(i).hour
+		timeObj.disable = 1
+		timeObj.index = count
+		time.push(timeObj)
+		count ++
+	}
+	return time
+}
+

+ 379 - 0
comps/mp-time/index.vue

@@ -0,0 +1,379 @@
+<template>
+	<view class="container">
+			<view class="flex justify-center " style="padding: 20rpx 0 50rpx 0;">
+				<text class="text-center text-lg text-bold">请选择预约时间</text>
+			</view>
+			<!-- tab栏 -->
+			<scroll-view class="scroll-view_H b-t b-b" scroll-x>
+				<block v-for="(item, index) in dateArr" :key="index">
+					<div class="flex-box" @click="selectDateEvent(index, item)" :style="{ 'box-shadow': index == dateActive ? 'inset 0 -2px 0 0 ' + selectedTabColor : '' }">
+						<view class="date-box">
+							<text class="days" :style="{ color: index == dateActive ? selectedTabColor : '#333' }">{{ item.week }}</text>
+							<text class="date" :style="{ color: index == dateActive ? selectedTabColor : '#333' }">{{ item.date }}</text>
+						</view>
+					</div>
+				</block>
+			</scroll-view>
+			<!-- 时间选项 -->
+			<view class="time-box" style="margin-top: 20rpx;">
+				<view v-if="mode==0" class="flex justify-center">
+					<view  class="box margin-right-20" @click="changeActive(0)" :class="active==0?'active':'unactive'">
+						<text class="text-center">{{firstTime}}-{{centerTime}}</text>
+					</view>
+					<view class="box margin-left-20" @click="changeActive(1)" :class="active==1?'active':'unactive'">
+						<text class="text-center">{{centerTime}}-{{lastTime}}</text>
+					</view>
+				</view>
+				<block v-else v-for="(item, _index) in timeArr" :key="_index">
+					<view class="item">
+						<view
+							class="item-box line-blue"
+							:class="{ disable: item.disable, 
+							active: timeActive.indexOf(_index) >= 0 }"
+							:style="{
+								filter: _index < timeActive[1] && _index > timeActive[0] ? 'opacity(0.6)' : ''
+							}"
+							@click="selectTimeEvent(_index, item)"
+						>
+							<text>{{ item.time }}</text>
+							<text class="all" v-if="item.disable">{{ disableText }}</text>
+							<text class="all" v-if="_index == timeActive[0] && !item.disable" style="font-size: 20upx;">开始时间</text>
+							<text class="all" v-if="_index == timeActive[1] && !item.disable" style="font-size: 20upx;">结束时间</text>
+						</view>
+					</view>
+				</block>
+				<view v-if="mode==0" class="flex justify-center margin-top-50">
+					<view class="">
+						{{dateTime.beginTime}}
+						<text style="padding: 0 20rpx;">至</text>
+						{{dateTime.endTime}}
+					</view>
+				</view>
+			</view>
+			<view @click="confirm" class="cu-btn bg-red-btn round flex footer-fixed" style="margin:10rpx 0;padding: 40rpx;">
+				确认
+			</view>
+	</view>
+</template>
+
+<script>
+import { dateData, timeData, timeStamp } from './date.js';
+let maxIndex;
+export default {
+	props: {
+		//0 双项模式 1 多项模式
+		mode:{
+			type:Number,
+			default:0
+		},
+		//开始时间选项
+		startTime: {
+			type: String,
+			default: '09:00'
+		},
+		//结束时间选项
+		endTime: {
+			type: String,
+			default: '18:00'
+		},
+		// 提前预约的时间
+		advanceTime: {
+			type: Number,
+			default: 1
+		},
+		// 默认选择的时间段间隔
+		timeSlot: {
+			type: Number,
+			default: 2
+		},
+		//时间间隔
+		timeInterval: {
+			type: [Number, String],
+			default: 1 //半小时
+		},
+		//选中的tab颜色
+		selectedTabColor: {
+			type: String,
+			default: '#59a5f0'
+		},
+		//选中的时间颜色
+		selectedItemColor: {
+			type: String,
+			default: '#59a5f0'
+		},
+
+		//禁用显示的文本
+		disableText: {
+			type: String,
+			default: ''
+		}
+	},
+	data() {
+		return {
+			firstTime:'9:00',
+			centerTime:'13:00',
+			lastTime:'19:00',
+			active:0,
+			dateTime:{},
+			
+			dateArr: [], //日期数据
+			timeArr: [], //时间数据
+			dateActive: 0, //选中的日期索引
+			timeActive: [], //选中的时间索引
+			oldTimeActive: [], //保存用户筛选的时间
+			selectDate: '', //选择的日期数据
+			selectTime: [], //选择的时间
+			oldSelectTime: '',
+			currentTimeStamp: '',
+			currentTime: '',
+			tabs: 0
+		};
+	},
+	created() {
+		//获取日期tab数据
+		this.dateArr = dateData();
+		//获取时间数据
+		this.timeArr = timeData(this.startTime, this.endTime, this.timeInterval);
+		maxIndex = this.timeArr[this.timeArr.length - 1]['index'];
+		//当前时间戳
+		this.currentTimeStamp = Date.now() + this.advanceTime * 3600 * 1000;
+		this.currentTime = timeStamp(this.currentTimeStamp).hour;
+		this.timeArr.map(item => {
+			if (item.time > this.currentTime) {
+				return (item.disable = 0); //判断当前时间大于时间选项则禁用
+			} else {
+				return (item.disable = 1);
+			}
+		});
+		//默认选中的日期
+		// this.selectDate = `${this.dateArr[0]['date']}(${this.dateArr[0]['week']})`;
+		this.selectDate=new Date().getFullYear()+'-'+this.dateArr[0]['date']
+		if (this.active==0) {
+			let beginTime=this.selectDate+" "+this.firstTime+':00'
+			let endTime=this.selectDate+" "+this.centerTime+':00'
+			this.dateTime.beginTime=beginTime
+			this.dateTime.endTime=endTime
+		}else{
+			let beginTime=this.selectDate+" "+this.centerTime+':00'
+			let endTime=this.selectDate+" "+this.lastTime+':00'
+			this.dateTime.beginTime=beginTime
+			this.dateTime.endTime=endTime
+		}
+		
+		this.timeArr.some((item, index) => {
+			// 默认选中的时间段
+			const endIndex = this.timeSlot / this.timeInterval + index > maxIndex ? maxIndex : this.timeSlot / this.timeInterval + index;
+			this.selectTime = [this.timeArr[index]['time'], this.timeArr[endIndex]['time']]; //默认选中的时间
+			this.oldSelectTime = this.selectTime; //存储选中的时间
+			this.timeActive = [index, endIndex]; //选中的时间索引
+			this.oldTimeActive = [index, endIndex];
+			return !item.disable;
+		});
+	},
+	methods: {
+		confirm(){
+			if (this.mode!=0) {
+				if (this.dateTime.beginTime==undefined||this.dateTime.endTime==undefined) {
+					this.dateTime.beginTime=this.selectDate+" "+this.selectTime[0]+":00"
+					this.dateTime.endTime=this.selectDate+" "+this.selectTime[1]+":00"
+				}
+				this.$emit('getDateTime',this.dateTime)
+				return	
+			}
+			if (this.selectDate==''||this.selectDate.length==0) {
+				let now=new Date().toLocaleDateString().replace(new RegExp('/','g'),'-')
+				this.selectDate=now
+			}
+			this.$emit('getDateTime',this.dateTime)
+			
+		},
+		changeActive(active){
+			this.active=active
+			this.getModeZeroDateTime()
+		},
+		getModeZeroDateTime(){
+			if (this.active==0) {
+				let beginTime=this.selectDate+" "+this.firstTime+':00'
+				let endTime=this.selectDate+" "+this.centerTime+':00'
+				this.dateTime.beginTime=beginTime
+				this.dateTime.endTime=endTime
+			}else{
+				let beginTime=this.selectDate+" "+this.centerTime+':00'
+				let endTime=this.selectDate+" "+this.lastTime+':00'
+				this.dateTime.beginTime=beginTime
+				this.dateTime.endTime=endTime
+			}
+		},
+		selectDateEvent(index, item) {
+			this.tabs = 0;
+			if (this.currentTimeStamp < item.timeStamp) {
+				const endIndex = this.timeSlot / this.timeInterval;
+				this.timeActive = [0, endIndex];
+				this.selectTime = [this.timeArr[0]['time'], this.timeArr[endIndex]['time']];
+				this.timeArr.map(item => {
+					return (item.disable = 0);
+				});
+			} else {
+				this.timeActive = this.oldTimeActive;
+				this.selectTime = this.oldSelectTime;
+				this.timeArr.map(item => {
+					if (item.time > this.currentTime) {
+						return (item.disable = 0);
+					} else {
+						return (item.disable = 1);
+					}
+				});
+			}
+			this.dateActive = index;
+			// this.selectDate = `${this.dateArr[index]['date']}(${this.dateArr[index]['week']})`;
+			let tmp=this.dateArr[index]['date']
+			this.selectDate=new Date().getFullYear()+'-'+this.dateArr[index]['date']
+			if (this.mode==0) {
+				this.getModeZeroDateTime()
+			}else{
+				let beginTime=new Date().getFullYear()+'-'+tmp+" "+this.selectTime[0]+':00'
+				let endTime=new Date().getFullYear()+'-'+tmp+" "+this.selectTime[1]+':00'
+				this.dateTime.beginTime=beginTime
+				this.dateTime.endTime=endTime
+			}
+			// this.$emit('selectTime', `${this.selectDate}${this.selectTime.join('-')}`);
+		},
+		selectTimeEvent(index, item) {
+			if (item.disable || this.timeActive.indexOf(index) > -1) return;
+			this.tabs++;
+			if (this.tabs % 2 == 0) {
+				this.$set(this.timeActive, 1, index);
+				this.selectTime[1] = this.timeArr[index]['time'];
+			} else {
+				this.$set(this.timeActive, 0, index);
+				this.selectTime[0] = this.timeArr[index]['time'];
+			}
+			// 判断用户选择的时间是否大于第一次选择的时间
+			if (this.timeActive[0] > this.timeActive[1]) {
+				const tempTime = this.selectTime[0];
+				const tempIndex = this.timeActive[0];
+				this.selectTime[0] = this.selectTime[1];
+				this.selectTime[1] = tempTime;
+				this.$set(this.timeActive, 0, this.timeActive[1]);
+				this.$set(this.timeActive, 1, tempIndex);
+			}
+			let beginTime=this.selectDate+" "+this.selectTime[0]+':00'
+			let endTime=this.selectDate+" "+this.selectTime[1]+':00'
+			this.dateTime.beginTime=beginTime
+			this.dateTime.endTime=endTime
+			// this.$emit('selectTime', `${this.selectDate}${this.selectTime.join('-')}`);
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+
+.box{
+	
+	margin-top: 20rpx;
+	font-size: 30rpx;
+	padding: 50rpx 80rpx;
+	border-radius: 12rpx;
+}
+.unactive{
+	color: #8a8a8a;
+	background-color: #ecedf0;
+}
+.active{
+	border: 1rpx solid #5ca6ef;
+	background-color: rgba(92, 166, 239,.3);
+	color: #5ca6ef;
+}
+
+	
+.container{
+	view,text,image{
+		box-sizing: border-box;
+	}
+	scroll-view{
+		width: 100%;
+		white-space: nowrap;
+		height: 104upx;
+		position: relative;
+		&::after{
+			background: #e5e5e5;
+			content: '';
+			display:block;
+			width: 100%;
+			height: 1px;
+			position: absolute;
+			bottom: 0;
+			left: 0;
+			transform:scaleY(0.5) 
+		}
+		.flex-box{
+			display: inline-block;
+			height: 100%;
+			padding:0 30upx;
+			box-sizing: border-box;
+			&.active{
+				.date-box{
+					.days{
+						color: #0092D5;
+					}
+					.date{
+						color: #0092D5;
+					}
+				}
+			}
+			.date-box{	
+				display: flex;
+				height: 100%;
+				flex-direction: column;
+				align-items: center;
+				justify-content: space-around;
+				font-size: 30upx;
+				color: #333333;
+				.date{
+					color: #999;
+					font-size: 24upx;
+					// margin-top: 10upx;
+				}
+			}
+		}
+		
+	}
+	.time-box{
+		padding:28upx 12upx 26upx;
+		display: flex;
+		flex-wrap: wrap;
+		.item{
+			width: 25%;
+			padding: 0 9upx;
+			margin-bottom: 18upx;
+			&-box{
+				width: 100%;
+				height: 80upx;
+				background: #F1F3F6;
+				color: #333;
+				font-size: 28upx;
+				border-radius: 10upx;
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				justify-content: center;
+				&.disable{
+					background: #F1F3F6 !important;
+					color: #999 !important;
+				}
+				&.active{
+					border: 1rpx solid #5ca6ef;
+					background-color: rgba(92, 166, 239,.1);
+					color: #5ca6ef;
+					font-weight: bold;
+				}
+				.all{
+					font-size: 22upx;
+				}
+			}
+		}
+	}
+	
+}
+</style>

+ 114 - 0
comps/scroll_menu.vue

@@ -0,0 +1,114 @@
+<template>
+	<view class="scroll_memu">
+	  <!-- <scroll-view scroll-x="true" class="scroll">
+	    <view class="memu_list">
+	      <view v-if="tabList.length>0" class="item" v-for="(item,idx) in tabList" :key="idx" hover-class="item-hover" @tap="jumpGoodsDes(item)">{{item.keyword}}</view>
+	    </view>
+	  </scroll-view> -->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				tabList:[]
+			};
+		},
+		created() {
+			// this.getProductCategorys();
+			this.getExporeHotWord()
+		},
+		methods:{
+			async getExporeHotWord(){
+				let resp = await this.$api.getExporeHotWord({
+					type:2, // type:0:默认, 1:商品搜索, 2:商品详情
+					num: '10'
+				})
+				this.tabList = resp;
+			},
+			async getProductCategorys() {
+			  let resp = await this.$api.getProductCategorys();
+			  if (resp) {
+			    let plen = resp.length
+			    if (plen <= 2 && plen > 0) {
+			      if (resp[0] && resp[0].childrens && resp[0].childrens.children) {
+			        let list = resp[0].childrens.children
+			        this.tabList = Array.isArray(list) ? list : []
+			      }
+			    } else if (plen > 2) {
+			      this.tabList = resp;
+			    } else {
+			      this.tabList = [];
+			    }
+			  } else {
+			    this.tabList = [];
+			  }
+			  return resp
+			},
+			jumpGoodsDes(item) {
+			  uni.navigateTo({
+			    url: "/pagesM/pages/goods_des?id=" + item.extendData
+			  })
+			},
+			// 跳转搜索
+			jumpSearch(item) {
+			  if (!item) {
+			    uni.navigateTo({
+			      url: "/pagesM/pages/search"
+			    })
+			  } else {
+			    let params = {
+			      keyword: item.name,
+			      productCategoryId: item.id
+			    }
+			    uni.navigateTo({
+			      url: "/pagesM/pages/search?" + this.$util.serialize(params)
+			    })
+			  }
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.scroll_memu {
+	  // height: 90upx;
+	  margin: 20upx 0 20upx 0;
+	  width: 100%;
+	  .scroll {
+	    white-space: nowrap;
+	    width: 100%;
+	    height: 100%;
+	    .memu_list {
+	      height: 100%;
+	      display: flex;
+	      flex-direction: row;
+	      align-items: center;
+	      font-size: 20upx;
+	      color: #fff;
+	      .item {
+			  // background-image: url(http://139.9.103.171:1888/img/image/home_yezi.png);
+			  // background-size: auto 100% ;
+			  // background-position-x: center;
+			  // background-repeat: no-repeat;
+				background: rgba($color: #FFFFFF, $alpha: 0.3);
+				border-radius: 25px;
+				height: 40upx;
+				line-height: 40upx;
+				padding: 0 20upx;
+				margin-right: 20upx;
+				text-align: center;
+	      }
+	
+	      .item-hover {
+	        opacity: 0.5;
+	      }
+	
+	      .space {
+	        padding-right: 30rpx;
+	      }
+	    }
+	  }
+	}
+</style>

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 69 - 0
comps/uploadimg/uploadImg.vue


+ 92 - 0
main.js

@@ -0,0 +1,92 @@
+import Vue from 'vue'
+import App from './App'
+//商城 begin
+import Server from './utils/server'
+import Storage from './utils/storage'
+import ApiEx from './utils/api'
+import Mixin from './utils/mixin'
+import Global from './utils/global'
+import Auth from './utils/auth'
+import Cache from './utils/cache'
+import Util from './utils/util2'
+import Dialog from './utils/dialog'
+import Filter from './utils/filter'
+import Mpi from './utils/mpi'
+//商城 end
+
+//uview
+import uView from 'uview-ui';
+Vue.use(uView);
+
+Vue.config.productionTip = false
+
+App.mpType = 'app'
+
+//封装判空函数
+Vue.prototype.$isEmpty=function(value){
+	switch (typeof value) {
+		case 'undefined':
+			return true;
+		case 'string':
+			if(value=='undefined') return true
+			if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
+			break;
+		case 'boolean':
+			if (!value) return true;
+			break;
+		case 'number':
+			if (0 === value || isNaN(value)) return true;
+			break;
+		case 'object':
+			if (null === value || value.length === 0) return true;
+			for (var i in value) {
+				return false;
+			}
+			return true;
+	}
+	return false;
+}
+
+// 商城 begin
+// 设置服务器
+Global.server = Server
+// 版本
+Cache.preKey = Server.version
+// 全局注入
+Vue.mixin(Mixin)
+// 全局筛选器
+Object.keys(Filter).forEach(key => {
+  Vue.filter(key, Filter[key])
+})
+// 全局属性 接口
+Vue.prototype.$api = Object.assign({}, ApiEx)
+
+// 全局属性 全局变量
+Vue.prototype.$global = Global
+
+// 全局缓存
+Vue.prototype.$storage = Storage
+
+// 同意授权
+Vue.prototype.$auth = Auth
+
+// 全局属性 工具函数
+Vue.prototype.$util = Util
+
+// 微信函数封装
+Vue.prototype.$mpi = Mpi
+
+// 全局属性 对话框函数
+Dialog.config = Object.assign(Dialog.config,{
+  cancelColor:'#333',
+  confirmColor:'#333',
+  title:'温馨提示'
+})
+Vue.prototype.$dialog = Dialog
+// 商城 end
+
+
+const app = new Vue({
+    ...App
+})
+app.$mount()

+ 919 - 0
pages.json

@@ -0,0 +1,919 @@
+{
+	"easycom": {
+		"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
+	},
+	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+		{
+			"path" : "pages/guide/guide",
+			"style":                                                                                   
+			{
+				"navigationStyle":"custom",
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false
+			}
+			
+		},
+		{
+			"path": "pages/index/index",
+			"style" :
+			{
+			    "enablePullDownRefresh": false,
+				"navigationStyle":"custom"
+			}
+		}
+	    ,{
+            "path" : "pages/myhome/myhome",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我家",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/life/life",
+            "style" :                                                                                    
+            {
+				"navigationStyle":"custom",
+                "navigationBarTitleText": "周边",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/poster/poster",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        },
+		{
+			"path": "pages/authorize_record/authorize_record",
+			"style": {
+				"navigationBarTitleText": "授权记录"
+			}
+		},
+		{
+			"path": "pages/authorize_record/openPass/openPass",
+			"style": {
+				"navigationBarTitleText": "访客授权"
+			}
+		}
+        ,{
+            "path" : "pages/webview/webview",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/register/register",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/wode/direction/direction",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "使用帮助",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/wode/myInfo/myInfo",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/wode/news/news",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我的消息",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/wode/password/password",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        },
+		{
+			"path": "pages/myFamily/myFamily",
+			"style": {
+				"navigationBarTitleText": "家人管理"
+			}
+		},
+		{
+			"path": "pages/myFamily/addFamily/addFamily",
+			"style": {
+				"navigationBarTitleText": "添加家人"
+			}
+		},
+		{
+			"path": "pages/myFamily/editFamily/editFamily",
+			"style": {
+				"navigationBarTitleText": "编辑家人"
+			}
+		},
+		{
+			"path": "pages/myFamily/editApplyFamily/editApplyFamily",
+			"style": {
+				"navigationBarTitleText": "编辑申请"
+			}
+		},
+		{
+			"path": "pages/myFamily/activateFace/activateFace",
+			"style": {
+				"navigationBarTitleText": "人脸激活"
+			}
+		},
+		{
+			"path": "pages/bluetooth/bluetooth",
+			"style": {
+				"navigationBarTitleText": "蓝牙开门"
+			}
+		},
+		{
+			"path": "pages/choosePlot/choosePlot",
+			"style": {
+				"navigationBarTitleText": "选择小区"
+			}
+		},
+		{
+			"path": "pages/choosePlot/chooseUnit/chooseUnit",
+			"style": {
+				"navigationBarTitleText": "选择楼栋"
+			}
+		},
+		{
+			"path": "pages/choosePlot/chooseRoom/chooseRoom",
+			"style": {
+				"navigationBarTitleText": "选择房间"
+			}
+		},
+		{
+			"path": "pages/choosePlot/householdCert/householdCert",
+			"style": {
+				"navigationBarTitleText": "用户认证"
+			}
+		},
+		{
+			"path": "pages/myPassword/myPassword",
+			"style": {
+				"navigationBarTitleText": "访客密码"
+			}
+		},{
+			"path": "pages/oneButton/oneButton",
+			"style": {
+				"navigationBarTitleText": "一键开门"
+			}
+		},{
+			"path": "pages/record/record",
+			"style": {
+				"navigationBarTitleText": "访客记录"
+			}
+		},{
+			"path": "pages/switchcity/switchcity",
+			"style": {
+				"navigationBarTitleText": "选择城市"
+			}
+		},
+		{
+			"path": "pages/uploadFace/uploadFace",
+			"style": {
+				"navigationBarTitleText": "人脸录入"
+			}
+		}
+        ,{
+            "path" : "pages/demo/myfamily",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/demo/demo1",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "添加家人",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/myhome/familyList",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我的家人",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/demo/demo2",
+            "style" :                                                                                    
+            {
+				"navigationStyle":"custom",
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/auth/auth",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "房屋认证",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/device/device",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我家",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/wode/wode",
+            "style" :                                                                                    
+            {
+				"navigationStyle":"custom",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/empty/empty",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "用户注册",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/empty/goauth",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "审核状态",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/myFamily/add/add",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/my-camera/my-camera",
+            "style" :                                                                                    
+            {
+				// "navigationBarTextStyle": "white",
+				// "navigationBarBackgroundColor": "#000",
+				"navigationBarTitleText": "相片拍摄"
+            }
+            
+        }
+        ,{
+            "path" : "pages/demo/demo4",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/demand/list",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "需求大厅",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/demand/detail",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "需求详情",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/demand/publish",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我的需求信息",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/delivery/delivery",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "代领快递",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/community/community",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "社区",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+		,{
+		    "path" : "pages/wode/feedback/feedback",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": "用户反馈",
+		        "enablePullDownRefresh": false
+		    }
+		    
+		}
+        ,{
+            "path" : "pages/notice/notice",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "通知公告"
+            }
+            
+        }
+        ,{
+            "path" : "pages/notice/detail",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "公告详情",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+  
+        ,{
+            "path" : "pages/tool-list/epidemic-pass/epidemic-pass",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "出入信息填写",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/tool-list/epidemic-pass/detail",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "出入通行证",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/tool-list/tool-list",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "功能列表",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/demo/demo5",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "访客开门",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/property/property",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "物业报修",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/wode/wode2",
+            "style" :                                                                                    
+            {
+				"navigationStyle":"custom",
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/property/detail",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "物业报修",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/property/list/list",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我的报修",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/guide/guide_old",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/services/property/comment",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "物业评价",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/guest/guest",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "访客授权",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/guest/open_door",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "访客开门",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/demo/demo6",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "会员登陆",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+    ],
+	 "subPackages": [{
+	 	"root": "pagesM/",
+	 	"pages": [
+				{
+				    "path" : "pages/goods_des",
+				    "style" : {
+				        "navigationBarTitleText" : "商品详情",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+					"path" : "pages/search",
+					"style" : {
+						"navigationBarTitleText" : "搜索商品",
+						"backgroundColor" : "#F2F2F2"
+					}
+				},
+				
+				{
+				    "path" : "pages/category",
+				    "style" : {
+				        "navigationBarTitleText" : "分类",
+				        "navigationBarTextStyle" : "#FFFFFF",
+				        "navigationBarBackgroundColor" : "#E42F2F"
+				    }
+				},
+				{
+				    "path" : "pages/shop_car",
+				    "style" : {
+				        "navigationBarTitleText" : "购物车"
+				    }
+				},
+				{
+				    "path" : "pages/mine",
+				    "style" : {
+				        // "navigationBarTitleText": "我的",
+				        // "navigationBarTextStyle": "white",
+				        // "navigationBarBackgroundColor": "#E42F2F",
+				        // "backgroundColorTop":"#E42F2F",
+				        "enablePullDownRefresh" : true,
+				        "navigationStyle" : "custom"
+				    }
+				},
+				{
+				    "path" : "pages/mine_income",
+				    "style" : {
+				        "navigationBarTitleText" : "团长收益"
+				    }
+				},
+				{
+				    "path" : "pages/applyToPromotion",
+				    "style" : {
+				        "navigationBarTitleText" : "团长申请"
+				    }
+				},
+				{
+				    "path" : "pages/mine_collection",
+				    "style" : {
+				        "navigationBarTitleText" : "我的收藏"
+				    }
+				},
+				{
+				    "path" : "pages/address_list",
+				    "style" : {
+				        "navigationBarTitleText" : "我的地址"
+				    }
+				},
+				{
+				    "path" : "pages/address_edit",
+				    "style" : {
+				        "navigationBarTitleText" : "编辑地址"
+				    }
+				},
+				{
+				    "path" : "pages/coupon_list",
+				    "style" : {
+				        "navigationBarTitleText" : "我的优惠券"
+				    }
+				},
+				{
+				    "path" : "pages/coupon_select",
+				    "style" : {
+				        "navigationBarTitleText" : "选择优惠券"
+				    }
+				},
+				{
+				    "path" : "pages/coupon_center",
+				    "style" : {
+				        "navigationBarTitleText" : "领券中心"
+				    }
+				},
+				{
+				    "path" : "pages/integral",
+				    "style" : {
+				        "navigationBarTitleText" : "我的积分"
+				    }
+				},
+				{
+				    "path" : "pages/integral_list",
+				    "style" : {
+				        "navigationBarTitleText" : "积分明细"
+				    }
+				},
+				{
+				    "path" : "pages/integral_exchange",
+				    "style" : {
+				        "navigationBarTitleText" : "兑换详情"
+				    }
+				},
+				{
+				    "path" : "pages/mine_setting",
+				    "style" : {
+				        "navigationBarTitleText" : "系统设置"
+				    }
+				},
+				{
+				    "path" : "pages/mine_protocal",
+				    "style" : {
+				        "navigationBarTitleText" : "用户协议"
+				    }
+				},
+				{
+				    "path" : "pages/mine_info",
+				    "style" : {
+				        "navigationBarTitleText" : "个人信息"
+				    }
+				},
+				{
+				    "path" : "pages/mine_interest",
+				    "style" : {
+				        "navigationBarTitleText" : "会员权益"
+				    }
+				},
+				{
+				    "path" : "pages/mine_order_list",
+				    "style" : {
+				        "navigationBarTitleText" : "我的订单",
+				        "enablePullDownRefresh" : true
+				    }
+				},
+				{
+				    "path" : "pages/mine_sale_list",
+				    "style" : {
+				        "navigationBarTitleText" : "我的售后"
+				    }
+				},
+				{
+				    "path" : "pages/after_sale_choose",
+				    "style" : {
+				        "navigationBarTitleText" : "选择申请售后货物"
+				    }
+				},
+				{
+				    "path" : "pages/after_sale_apply",
+				    "style" : {
+				        "navigationBarTitleText" : "申请售后"
+				    }
+				},
+				{
+				    "path" : "pages/after_sale_submit",
+				    "style" : {
+				        "navigationBarTitleText" : "申请售后"
+				    }
+				},
+				{
+				    "path" : "pages/goods_manual",
+				    "style" : {
+				        "navigationBarTitleText" : "说明书",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+				    "path" : "pages/goods_comment_list",
+				    "style" : {
+				        "navigationBarTitleText" : "全部评价",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+				    "path" : "pages/goods_list",
+				    "style" : {
+				        "navigationBarTitleText" : "商品列表",
+				        "navigationBarBackgroundColor" : "#FFFFFF",
+						"navigationStyle" : "custom"
+				    }
+				},
+				{
+				    "path" : "pages/order_confirm",
+				    "style" : {
+				        "navigationBarTitleText" : "确认下单",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+				    "path" : "pages/order_pay",
+				    "style" : {
+				        "navigationBarTitleText" : "在线支付",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+				    "path" : "pages/pay_success",
+				    "style" : {
+				        "navigationBarTitleText" : "支付成功",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+				    "path" : "pages/mention_store_list",
+				    "style" : {
+				        "navigationBarTitleText" : "选择提货门店",
+				        "backgroundColor" : "#F2F2F2"
+				    }
+				},
+				{
+				    "path" : "pages/order_appraise",
+				    "style" : {
+				        "navigationBarTitleText" : "填写评价"
+				    }
+				},
+				{
+				    "path" : "pages/order_detail",
+				    "style" : {
+				        "navigationBarTitleText" : "订单详情",
+				        "navigationBarTextStyle" : "white",
+				        "navigationBarBackgroundColor" : "#E42F2F"
+				    }
+				},
+				{
+				    "path" : "pages/order_sale_detail",
+				    "style" : {
+				        "navigationBarTitleText" : "售后详情",
+				        "navigationBarTextStyle" : "white",
+				        "navigationBarBackgroundColor" : "#E42F2F"
+				    }
+				},
+				{
+				    "path" : "pages/common/webview",
+				    "style" : {}
+				},
+				{
+				    "path" : "pages/my_integral",
+				    "style" : {
+				        "navigationBarTitleText" : "我的积分"
+				    }
+				},
+				{
+				    "path" : "pages/share_team",
+				    "style" : {
+				        "navigationBarTitleText" : "我的分享团队"
+				    }
+				},
+				{
+				    "path" : "pages/my_earnings",
+				    "style" : {
+				        "navigationBarTitleText" : "我的分享团队"
+				    }
+				},
+				{
+				    "path" : "pages/share_team_goods",
+				    "style" : {
+				        "navigationBarTitleText" : "我的分享团队"
+				    }
+				},
+				{
+				    "path" : "pages/earn_records",
+				    "style" : {
+				        "navigationBarTitleText" : "收益记录"
+				    }
+				},
+				{
+				    "path" : "pages/earn_details",
+				    "style" : {
+				        "navigationBarTitleText" : "收益详情"
+				    }
+				},
+				{
+				    "path" : "pages/balance_records",
+				    "style" : {
+				        "navigationBarTitleText" : "结算记录"
+				    }
+				},
+				{
+				    "path" : "pages/my_invite",
+				    "style" : {
+				        "navigationBarTitleText" : "我邀请的人"
+				    }
+				},
+				{
+				    "path" : "pages/user_invite",
+				    "style" : {
+				        "navigationBarTitleText" : ""
+				    }
+				},
+				{
+				    "path" : "pages/discounts_goods",
+				    "style" : {
+				        "navigationBarTitleText" : "分销商品"
+				    }
+				},
+				{
+				    "path" : "pages/common/ad_textView",
+				    "style" : {}
+				},
+				{
+				    "path" : "comps/tki_qrcode",
+				    "style" : {}
+				},
+				{
+				    "path" : "pages/nearby_team",
+				    "style" : {
+				        "navigationBarTitleText" : "附近团长"
+				    }
+				},
+				{
+				    "path" : "comps/promotion_detail",
+				    "style" : {}
+				},
+				{
+				    "path" : "pages/claim_goods",
+				    "style" : {
+				        "navigationBarTitleText" : "快速取货"
+				    }
+				},
+				{
+				    "path" : "pages/nearby_team_map",
+				    "style" : {
+				        "navigationBarTitleText" : "附近团长"
+				    }
+				},
+				{
+				    "path" : "pages/about_us",
+				    "style" : {
+				        "navigationBarTitleText" : "关于新邻"
+				    }
+				},
+				{
+				    "path" : "pages/ad_apply_organ",
+				    "style" : {
+				        "navigationBarTitleText" : "申请团长"
+				    }
+				},
+				{
+				    "path" : "pages/browse_records",
+				    "style" : {
+				        "navigationBarTitleText" : "浏览记录"
+				    }
+				},
+				{
+				    "path" : "comps/dt_goods_list_home",
+				    "style" : {}
+				}
+				,{
+				    "path" : "comps/dt_special",
+				    "style" : {}
+				}
+            ]
+	  }],
+	  "preloadRule":{
+		  "pages/life/life": {
+		    "network": "all",
+		    "packages": ["pagesM"]
+		  },
+		  "pages/index/index": {
+		    "network": "all",
+		    "packages": ["pagesM"]
+		  }
+	  },
+	 "tabBar": {
+		  "color":"#8a8a8a",
+		  "backgroundColor":"#FFFFFF",
+		  "borderStyle":"white",
+		  "selectedColor":"#59a5f0",
+		  "list": [
+			{
+			  "pagePath": "pages/index/index",
+			  "text": "小区",
+			  "selectedIconPath":"static/tarbar/blue/home.png",
+			  "iconPath":"static/tarbar/blue/home0.png"
+			},
+			{
+			  "pagePath": "pages/community/community",
+			  "text": "社区",
+			  "selectedIconPath":"static/tarbar/blue/shequ.png",
+			  "iconPath":"static/tarbar/blue/shequ0.png"
+			},
+			{
+			  "pagePath": "pages/device/device",
+			  "text": "我家",
+			  "selectedIconPath":"static/tarbar/blue/zhijia.png",
+			  "iconPath":"static/tarbar/blue/zhijia0.png"
+			},
+			{
+			  "pagePath": "pages/life/life",
+			  "text": "周边",
+			  "selectedIconPath":"static/tarbar/blue/shop.png",
+			  "iconPath":"static/tarbar/blue/shop0.png"  
+			},
+			{
+			  "pagePath": "pages/wode/wode",
+			  "text": "我的",
+			  "selectedIconPath":"static/tarbar/blue/my.png",
+			  "iconPath":"static/tarbar/blue/my0.png"
+			}
+		  ]
+	  },
+	"globalStyle": {
+		"navigationBarTitleText": "新邻社区",
+		"backgroundColor": "#FFFFFF",
+		"navigationBarBackgroundColor":"#FFFFFF",
+		"navigationBarTextStyle":"black"
+	},
+	"navigateToMiniProgramAppIdList" : [ "wx90680ffd54c3b96c" ]
+}

+ 228 - 0
pages/auth/auth.vue

@@ -0,0 +1,228 @@
+<template>
+	<view style="background-color: #FFFFFF;min-height: 100vh;">
+		<view class="flex justify-between " style="padding: 30rpx;box-sizing: border-box;">
+			<view class="" style="font-size: 38rpx;">
+				<text class="text-bold text-black">您要申请的小区</text>
+			</view>
+			<view class="text-red"  style="padding-top: 12rpx;">
+				<text style="font-size: 38rpx;">{{totalStep-1}}</text>
+				<text class="text-df">/{{totalStep}}</text>
+			</view>
+		</view>
+		<view class="padding-top-30  cu-list menu">
+			
+			<view @click="jump(0)" class="cu-item arrow" >
+				<view class="content">
+					<image style="width: 50rpx; height: 50rpx;margin: 0 20rpx 4rpx 0;" 
+					src="/static/icon/city2.png" class="png" mode="aspectFit"></image>
+					<text class="text-black text-bold">城市</text>
+				</view>
+				<view class="action">
+					<text class="text-grey text-df">
+						{{$isEmpty(city_county_name)?'请选择城市':city_county_name}}
+					</text>
+				</view>
+			</view>
+			<view @click="jump(1)" class="cu-item arrow" >
+				<view class="content">
+					<image style="width: 50rpx; height: 50rpx;margin: 0 20rpx 0rpx 0;" 
+					src="/static/icon/xiaoqu.png" class="png" mode="aspectFit"></image>
+					<text class="text-black text-bold">小区</text>
+				</view>
+				<view class="action">
+					<text class="text-grey text-df">
+						{{$isEmpty(data.residential_name)?'请选择小区':data.residential_name}}
+					</text>
+				</view>
+			</view>
+			<view @click="jump(2)" class="cu-item arrow" >
+				<view class="content">
+					<image style="width: 50rpx; height: 50rpx;margin: 0 20rpx 10rpx 0;" 
+					src="/static/icon/loudong.png" class="png" mode="aspectFit"></image>
+					<text class="text-black text-bold">楼栋</text>
+				</view>
+				<view class="action">
+					<text class="text-grey text-df">
+						{{$isEmpty(data.unit_name)?'请选择楼栋':data.unit_name}}
+					</text>
+				</view>
+			</view>
+			<view @click="jump(3)" class="cu-item arrow" >
+				<view class="content">
+					<image style="width: 50rpx; height: 50rpx;margin: 0 20rpx 10rpx 0;" 
+					src="/static/icon/fangjian.png" class="png" mode="aspectFit"></image>
+					<text class="text-black text-bold">门牌号</text>
+				</view>
+				<view class="action">
+					<text class="text-grey text-df">
+						{{$isEmpty(data.room_name)?'请选择门牌号':data.room_name}}
+					</text>
+				</view>
+			</view>
+		</view>
+		<view  class="footer-fixed" @click="next" >
+			<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+				下一步
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	var app=getApp()
+	export default {
+		data() {
+			return {
+				totalStep:3,
+				numList: [{
+					name: '注册账号'
+				}, {
+					name: '选择小区'
+				}, {
+					name: '填写信息'
+				}],
+				//小区id
+				residential_id:'',
+				//楼栋id
+				unit_id:'',
+				data:{
+					//小区
+					residential_name:"",
+					//楼栋
+					unit_name:"",
+					//房间名
+					room_name:"",
+					//房间id
+					room_id:"",
+				},
+				//城市
+				city_county_name:''
+			}
+		},
+		onShow() {
+			if(this.$isEmpty(app.globalData.totalStep)){
+				this.totalStep=2
+			}else{
+				this.totalStep=app.globalData.totalStep
+			}
+			this.residential_id=app.globalData.residentialId || ''
+			this.unit_id=app.globalData.unitId || ''
+		},
+		onLoad(options){
+			if(!this.$isEmpty(options)){
+				//页面数据
+				this.city_county_name=app.globalData.city+app.globalData.county
+				this.data.room_id=options.room_id
+				this.data.room_name=options.room_name
+				this.data.residential_name=options.residential_name
+				this.data.unit_name=options.unit_name
+			}
+		},
+		methods: {
+			jump(type){
+				let that=this
+				if(type==0){
+					//选择城市
+					uni.navigateTo({
+						url:"../choosePlot/choosePlot?city="+app.globalData.city+"&county="+app.globalData.county+"&currentCityCode="+app.globalData.currentCityCode
+					})
+				}
+				//未选择城市
+				if(this.$isEmpty(this.city_county_name)){
+					uni.showToast({
+						title:"请选择城市",
+						icon:"none"
+					})
+					return
+				}
+				if(type==1){
+					//选择小区
+					uni.navigateTo({
+						url:"../choosePlot/choosePlot?city="+app.globalData.city+"&county="+app.globalData.county+"&currentCityCode="+app.globalData.currentCityCode
+					})
+					return
+				}
+				//未选择小区
+				if(this.$isEmpty(this.data.residential_name)){
+					uni.showToast({
+						title:"请选择小区",
+						icon:"none"
+					})
+					return
+				}
+				if(type==2){
+					//选择楼栋
+					uni.navigateTo({
+						url: '/pages/choosePlot/chooseUnit/chooseUnit?residential_id=' + this.residential_id + '&residential_name=' + this.data.residential_name,
+					})
+					return
+				}
+				//未选择楼栋
+				if(this.$isEmpty(this.data.unit_name)){
+					uni.showToast({
+						title:"请选择楼栋",
+						icon:"none"
+					})
+					return
+				}
+				if(type==3){
+					let url="/pages/choosePlot/chooseRoom/chooseRoom?unit_id=" + this.unit_id + "&unit_name=" + this.data.unit_name + "&residential_name=" + this.data.residential_name
+					console.log(url)
+					//选择房间
+					uni.navigateTo({
+						url:url
+					})
+				}
+			},
+			next(){
+				if(this.$isEmpty(this.city_county_name)){
+					uni.showToast({
+						title:"请选择城市",
+						icon:"none"
+					})
+					return
+				}
+				if(this.$isEmpty(this.data.residential_name)){
+					uni.showToast({
+						title:"请选择小区",
+						icon:"none"
+					})
+					return
+				}
+				
+				if(this.$isEmpty(this.data.unit_name)){
+					uni.showToast({
+						title:"请选择楼栋",
+						icon:"none"
+					})
+					return
+				}
+				if(this.$isEmpty(this.data.room_id)||this.$isEmpty(this.data.room_name)){
+					uni.showToast({
+						title:"请选择门牌号",
+						icon:"none"
+					})
+					return
+				}
+				uni.navigateTo({
+					url:"../choosePlot/householdCert/householdCert"+this.$u.queryParams(this.data)
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+view,
+button{
+    box-sizing: border-box;
+}
+.cu-list.menu>.cu-item.arrow {
+    padding-right: 36px;
+}
+
+.bg-gray{
+	background-color: #a1a1a1;
+	color: #FFFFFF;
+}
+</style>

+ 426 - 0
pages/authorize_record/authorize_record.vue

@@ -0,0 +1,426 @@
+<template>
+<view :class="$isEmpty(list)?'empty-wrap':''">
+<view class="bg-white padding-20 flex justify-between" style="box-sizing: border-box;">
+	<view class="text-sm text-gray padding-top-10">
+		<text>只显示最近一个月内的授权记录</text>
+	</view>
+	<navigator url="../record/record" class="cu-btn line-btn sm round">
+		<text class="cuIcon-footprint padding-right-sm"></text>
+		访客记录
+	</navigator>
+</view>
+<view class="container" v-if="list.length>0">
+  <view class="record_content">
+	   <view class="data" v-for="(item, index) in list" :key="index"  style="border-bottom: 1rpx solid #b6b6b6;">
+	   	<view class="top">
+	   		<view class="left">
+	   			<u-icon name="account" :size="30" color="rgb(94,94,94)"></u-icon>
+				<view class="padding-left-sm" v-if="item.guestType==0">访客授权: 朋友</view>
+				<view class="padding-left-sm" v-if="item.guestType==1">访客授权: 外卖</view>
+				<view class="padding-left-sm" v-if="item.guestType==2">访客授权: 快递</view>
+				<view class="padding-left-sm" v-if="item.guestType==3">访客授权: 其他</view>
+	   		</view>
+	   	</view>
+	   	<view class="item">
+	   		<view class="left">
+	   			<view class="content" >
+	   				<view >授权时间:{{item.beginDate}}</view>
+	   				<view >失效时间:{{item.endDate}}</view>
+	   			</view>
+	   		</view>
+	   	</view>
+	   	<view class="bottom" >
+	   		<view  class="cu-btn line-btn sm round margin-right-sm" @tap.stop="showModalFun" :data-password="item.password" :data-begin_date="item. beginDate" :data-end_date="item.endDate" :data-valid_count="item.validCount">
+	   			查看密码
+	   		</view>
+	   		<view @tap.stop="backout" :data-id="item.id" class="cu-btn bg-btn sm round">
+	   			撤销
+	   		</view>
+	   	</view>
+	   </view>
+  </view>
+</view>
+<view v-show="!showModal" @tap="addOpenPassword" class=" footer-fixed" >
+	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+		申请密码
+	</view>
+</view>
+<!--弹窗-->
+<view class="modal-mask" @tap="closeModal" catchtouchmove="preventTouchMove" v-if="showModal"></view>
+<!--  -->
+<view class="modal-dialog" v-if="showModal">
+  <view class="modal-title">开门密码</view>
+    <view class="modal-content">
+      <view class="modal-input">
+        <text class="password">{{password}}</text>
+      </view>
+    </view>
+    <view class="modal-footer">
+      <button class="btn-cancel" open-type="share" data-status="cancel">转发</button>
+      <button class="btn-confirm" @tap="copy" data-status="confirm">复制</button>
+    </view>
+</view>
+
+<view class="default"  v-if="$isEmpty(list)">
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有获取到相关记录</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+var util = require("../../utils/util.js"); //获取app实例
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      list: null,
+      //密码记录
+      showModal: false,
+      password: "",
+      begin_date: "",
+      end_date: "",
+      valid_count: ""
+    };
+  },
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    this.getRecord();
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {
+    //回退的时候刷新
+    let isFlush = uni.getStorageSync("isFlush");
+
+    if (isFlush) {
+      this.getRecord();
+      uni.setStorageSync("isFlush", false);
+    }
+  },
+  //转发
+  onShareAppMessage: function (ops) {
+    let title = "访客密码:" + this.password + ",有效次数:" + this.valid_count + "次,有效期" + this.begin_date + " 到 " + this.end_date;
+    return {
+      title: title,
+      path: '/pages/myPassword/myPassword?valid_count=' + this.valid_count + "&password=" + this.password + "&end_date=" + this.end_date,
+      imageUrl: "http://139.9.103.171:1888/img/image/ps_bg.png"
+    };
+  },
+  methods: {
+    //查看密码
+    showModalFun: function (event) {
+      this.setData({
+        showModal: true,
+        password: event.currentTarget.dataset.password,
+        begin_date: event.currentTarget.dataset.begin_date,
+        //获取记录的时候已经转换了一次
+        end_date: event.currentTarget.dataset.end_date,
+        valid_count: event.currentTarget.dataset.valid_count
+      });
+    },
+    //关闭弹窗
+    closeModal: function () {
+      this.setData({
+        showModal: false
+      });
+    },
+    //复制密码
+    copy: function (e) {
+      var that = this; //获取app.js里面定义的全局变量
+
+      if (uni.setClipboardData) {
+        //微信版本兼容处理
+        let title = "访客密码:" + this.password + ",有效次数:" + this.valid_count + "次,有效期" + this.begin_date + " 到 " + this.end_date;
+        uni.setClipboardData({
+          data: title,
+
+          success(res) {
+            uni.getClipboardData({
+              success(res) {
+				  that.closeModal()
+			  }
+            });
+          }
+
+        });
+      } else {//用户微信版本过低,不支持使用该功能
+      }
+    },
+
+    /**新增 */
+    addOpenPassword: function () {
+      uni.navigateTo({
+        url: '/pages/authorize_record/openPass/openPass'
+      });
+    },
+    //获取密码授权记录
+    getRecord: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      ;
+      let operation = 'guestAuthorize/getListByMemberId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取数据结构" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          let list = res.data.list;
+
+          for (let i in list) {
+            list[i].beginDate = util.formatTime(list[i].beginDate);
+            list[i].endDate = util.formatTime(list[i].endDate);
+          }
+
+          that.setData({
+            list: list
+          });
+        }
+      });
+    },
+    //撤销密码
+    backout: function (event) {
+      let id = event.currentTarget.dataset.id;
+      let that = this;
+      let params = {};
+      params['guest_authorize_id'] = id;
+      params['member_id'] = app.globalData.member.id;
+      ;
+      let operation = 'guestAuthorize/cancel';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取数据结构" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          app.globalData.oneFailHint(res.data.result_msg, function () {
+            that.getRecord();
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+
+.data {
+	background-color: #FFFFFF;
+	width: 720rpx;
+	margin:10rpx auto;
+	border-radius: 6rpx;
+	box-sizing: border-box;
+	padding: 20rpx;
+	font-size: 28rpx;
+	.top {
+		display: flex;
+		justify-content: space-between;
+		.left {
+			display: flex;
+			align-items: center;
+			.title {
+				margin: 0 10rpx;
+				font-size: 32rpx;
+				font-weight: bold;
+			}
+		}
+	}
+	.item {
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		margin: 40rpx 0 20rpx 0;
+		.left {
+			display: flex;
+			.content {
+				padding-left: 30rpx;
+				view{
+					padding-bottom: 16rpx;
+				}
+			}
+		}
+	}
+	.bottom {
+		display: flex;
+		margin-top: 20rpx;
+		justify-content: flex-end;
+		align-items: center;
+	}
+}
+	
+page{
+  overflow-y: scroll;
+}
+
+
+.container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+}
+
+.nav {
+  height: 80rpx;
+  line-height: 80rpx;
+  text-align: center;
+  border-bottom: 1rpx solid #c7c7c9;
+  background: #fff;
+  color: #c7c7c9;
+  font-size: 24rpx;
+}
+
+.record_content{
+  padding-bottom: 110rpx;
+}
+.list-item {
+	border-bottom: 1rpx solid #dddddd;
+  line-height: 60rpx;
+  padding: 20rpx;
+  color: #333;
+  position: relative;
+  box-sizing: border-box;
+  margin-top: 20rpx;
+  background: #fff;
+}
+
+.list-item .btn {
+  position: absolute;
+  right: 20rpx;
+  top: 50%;
+  transform: translate(0, -50%);
+}
+
+.list-item .btn .check_password, .list-item .btn .withdrawn {
+  width: 120rpx;
+  border-radius: 5000rpx;
+  padding: 0 24rpx;
+  height: 56rpx;
+  text-align: center;
+  margin: 14rpx;
+  color: $base-btn-color;
+  border:2rpx solid $base-btn-color;
+}
+.list-item .btn .check_password, .list-item .btn .states {
+
+  color: #999;
+  border:none;
+}
+
+.list-item .btn .withdrawn.state {
+  border: none;
+  color: #999;
+}
+.default {
+  text-align: center;
+  position: fixed;
+  left: 50%;
+  top: 40%;
+  transform: translate(-50%, -50%);
+}
+.default text{
+	color: #AAAAAA;
+}
+.default image {
+  height: 280rpx;
+  display: inline-block;
+}
+.empty-wrap{
+	background-color: #FFFFFF;
+	min-height: 100vh;
+}
+
+/* 查看密码弹窗 */
+.modal-mask {
+  width: 100%;
+  height: 100%;
+  position: fixed;
+  top: 0;
+  left: 0;
+  background: #000;
+  opacity: 0.5;
+  overflow: hidden;
+  z-index: 9000;
+  color: #fff;
+}
+.modal-dialog {
+  width: 540rpx;
+  overflow: hidden;
+  position: fixed;
+  top: 50%;
+  left: 0;
+  z-index: 9999;
+  background: #f9f9f9;
+  margin: -180rpx 105rpx;
+  border-radius: 36rpx;
+}
+
+.modal-title {
+  padding-top: 50rpx;
+  font-size: 36rpx;
+  color: #030303;
+  text-align: center;
+}
+
+.modal-content {
+  padding: 50rpx 32rpx;
+}
+
+.modal-input {
+  display: flex;
+  font-size: 40rpx;
+}
+
+.password {
+  width: 100%;
+  height: 80rpx;
+  font-size: 40rpx;
+  line-height: 80rpx;
+  padding: 0 20rpx;
+  box-sizing: border-box;
+  color: #ec5300;
+  text-align: center;
+}
+
+input-holder {
+  color: #666;
+  font-size: 28rpx;
+}
+
+.modal-footer {
+  display: flex;
+  flex-direction: row;
+  height: 86rpx;
+  border-top: 1px solid #dedede;
+  font-size: 34rpx;
+  line-height: 86rpx;
+}
+.modal-footer button::after{
+   border: none;
+  
+}
+.modal-footer .btn-cancel {
+  width: 50%;
+  color: #666;
+  text-align: center;
+  border-right: 1px solid #dedede;
+ border-radius: 0;
+}
+
+.modal-footer .btn-confirm {
+  width: 50%;
+  color: #ec5300;
+  text-align: center;
+}
+</style>

+ 524 - 0
pages/authorize_record/openPass/openPass.vue

@@ -0,0 +1,524 @@
+<template>
+<view style="background-color: #FFFFFF;height: 100vh;">
+<!--pages/openPass/openPass.wxml-->
+<view class="container edit_wrap" >
+  <view class="form_group">
+    <text class="type">选择房间:</text>
+   <view class="ar_picker " style="background:#fff;border-bottom: 1rpx solid #ddd;" @click="roomSelectShow=true">
+      <view class="ar_picker_wrap">
+        <text>{{selectRoomName?selectRoomName:room_list[0].name}}</text>
+      </view>
+    </view>
+  </view>
+   <view class="form_group" >
+
+    <view class="tui-picker-content">
+      <text class="type">访客类型:</text>
+      <view class="flex between itemBox">
+        <view v-for="(item, index) in guestTypeArray" :key="index" :class="guestTypeIndex == index ? 'active':''" @tap="guestTypethis" :data-thisindex="index">
+          <text>{{item}}</text>
+        </view>
+      </view>
+
+    </view>
+
+  </view>
+  <view class="form_group" >
+
+    <view class="tui-picker-content">
+      <text class="type">密码有效时间:</text>
+      <view class="flex between itemBox">
+        <view v-for="(item, index) in numArray" :key="index" :class="activeIndex == index ? 'active':''" @tap="activethis" :data-thisindex="index">
+          <text>{{item}}小时</text>
+        </view>
+      </view>
+
+    </view>
+
+  </view>
+  <view class="form_group">
+
+    <text class="type">有效次数:</text>
+    <view class="stepper">
+      <text :class="minusStatus" type="number" @tap="bindMinus">-</text>
+      <input @input="bindManual" :value="valid_count"></input>
+      <text @tap="bindPlus">+</text>
+    </view>
+
+  </view>
+<!-- <view class="submit_btn">
+ <button class="ar_btn" @tap="getGuestAuthorize">获取开门密码</button>
+</view> -->
+<view @tap="getGuestAuthorize" class=" footer-fixed" >
+	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+		获取开门密码
+	</view>
+</view>
+
+</view>
+<!--弹窗-->
+<view class="modal-mask" @tap="closeModal" catchtouchmove="preventTouchMove" v-if="showModal"></view>
+<!--  -->
+<view class="modal-dialog" v-if="showModal">
+  <view class="modal-title">开门密码</view>
+    <view class="modal-content">
+      <view class="modal-input">
+        <text class="password">{{password}}</text>
+      </view>
+    </view>
+    <view class="modal-footer">
+      <button class="btn-cancel" open-type="share" data-status="cancel">转发</button>
+      <button class="btn-confirm" @tap="copy" data-status="confirm">复制</button>
+    </view>
+</view>
+<u-select z-index="9999999"  mode="single-column"  value-name="id" label-name="name" v-model="roomSelectShow" :list="room_list" @confirm="roomChange"></u-select>
+</view>
+</template>
+
+<script>
+// 访客授权
+//获取app实例
+var app = getApp();
+var util = require("../../../utils/util.js");
+
+export default {
+  data() {
+    return {
+	  roomSelectShow:false,
+	  selectRoomName:'',
+	  selectRoomId:0,
+		
+      room_list: null,
+      //有效次数
+      valid_count: 1,
+      minusStatus: 'disable',
+      //获取开门密码
+      showModal: false,
+      //开门密码
+      password: null,
+      //访客类型
+      guestTypeIndex: 0,
+      //默认选中第一个
+      guestTypeArray: ['朋友', '外卖', '快递', '其他'],
+      //密码有效期
+      activeIndex: 0,
+      //默认选中第一个
+      numArray: [1, 2, 5, 8, 24, 48],
+      begin_date: "",
+      end_date: ""
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 监听页面加载
+   */
+  onLoad() {
+    //禁用头部分享
+    uni.hideShareMenu({});
+    let room_list = app.globalData.room_list;
+
+    if (room_list) {
+      this.setData({
+        room_list: room_list
+      });
+    } else {
+      //获取房屋信息
+      this.geRoomByMemberId();
+    }
+  },
+
+  onShareAppMessage: function (ops) {
+    let title = "访客密码:" + this.password + ",有效次数:" + this.valid_count + "次,有效期" + this.begin_date + " 到 " + this.end_date;
+    return {
+      title: title,
+      path: '/pages/myPassword/myPassword?valid_count=' + this.valid_count + "&password=" + this.password + "&end_date=" + this.end_date,
+      imageUrl: "http://139.9.103.171:1888/img/image/ps_bg.png"
+    };
+  },
+  methods: {
+    //选择房间
+    roomChange: function (e) {
+		this.selectRoomId=e[0].value
+		this.selectRoomName=e[0].label
+    },
+    //事件处理函数
+
+    /*点击减号*/
+    bindMinus: function () {
+      var valid_count = this.valid_count;
+
+      if (valid_count > 1) {
+        valid_count--;
+      }
+
+      var minusStatus = valid_count > 1 ? 'normal' : 'disable';
+      this.setData({
+        valid_count: valid_count,
+        minusStatus: minusStatus
+      });
+    },
+
+    /*点击加号*/
+    bindPlus: function () {
+      var valid_count = this.valid_count;
+
+      if (valid_count >= 10) {
+        uni.showToast({
+          title: '密码最大次数不能超过10次',
+          icon: 'none',
+          duration: 2000
+        });
+      } else {
+        valid_count++;
+        var minusStatus = valid_count > 1 ? 'normal' : 'disable';
+        this.setData({
+          valid_count: valid_count,
+          minusStatus: minusStatus
+        });
+      }
+    },
+
+    /*输入框事件*/
+    bindManual: function (e) {
+      var valid_count = e.detail.value;
+      var minusStatus = valid_count > 1 ? 'normal' : 'disable';
+      this.setData({
+        valid_count: valid_count,
+        minusStatus: minusStatus
+      });
+    },
+    //访客类型
+    guestTypethis: function (event) {
+      //点击选中事件
+      var thisindex = event.currentTarget.dataset.thisindex; //当前index
+
+      this.setData({
+        guestTypeIndex: thisindex
+      });
+    },
+    //密码有效时间
+    activethis: function (event) {
+      //点击选中事件
+      var thisindex = event.currentTarget.dataset.thisindex; //当前index
+
+      this.setData({
+        activeIndex: thisindex
+      });
+    },
+    //复制密码
+    copy: function (e) {
+      var that = this; //获取app.js里面定义的全局变量
+
+      if (uni.setClipboardData) {
+        //微信版本兼容处理
+        let title = "访客密码:" + this.password + ",有效次数:" + this.valid_count + "次,有效期" + this.begin_date + " 到 " + this.end_date;
+        uni.setClipboardData({
+          data: title,
+
+          success(res) {
+            uni.getClipboardData({
+              success(res) {
+				  that.closeModal()
+			  }
+
+            });
+          }
+
+        });
+      } else {//用户微信版本过低,不支持使用该功能
+      }
+    },
+    //关闭弹窗
+    closeModal: function () {
+      this.setData({
+        showModal: false
+      });
+    },
+    //获取开门密码
+    getGuestAuthorize: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      params['room_id'] = that.selectRoomId;
+      params['guest_type'] = that.guestTypeIndex;
+      params['valid_count'] = that.valid_count; //选择有效时间数字
+
+      let avalid_num = that.numArray[that.activeIndex]; //有效开始时间
+
+      let begin_date = new Date(); //提前30分钟
+
+      begin_date.setMinutes(begin_date.getMinutes() - 30);
+      params['begin_date'] = util.getTimestamp(begin_date); //有效结束时间
+
+      let end_date = new Date(); //小时累加
+
+      end_date.setHours(end_date.getHours() + avalid_num);
+      params['end_date'] = util.getTimestamp(end_date); //有效次数
+
+      params['valid_count'] = that.valid_count;
+      let operation = 'guestAuthorize/getGuestAuthorize';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("接口返回结果:" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          uni.setStorageSync("isFlush", true);
+          that.setData({
+            //显示复制密码弹窗
+            showModal: true,
+            password: res.data.guestAuthorize.password,
+            begin_date: util.formatTime(res.data.guestAuthorize.beginDate),
+            end_date: util.formatTime(res.data.guestAuthorize.endDate)
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    },
+    //根据会员id获取我的房屋列表
+    geRoomByMemberId: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      ;
+      let operation = 'estate/getRoomByMemberId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取成功" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          that.setData({
+            room_list: res.data.list
+          });
+          app.globalData.room_list = res.data.list;
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+/* pages/openPass/openPass.wxss */
+
+.edit_wrap {
+  font-size: 30rpx;
+  color: #333;
+}
+
+.form_group {
+  margin:0 20rpx;
+  line-height: 60rpx;
+  background: #fff;
+  border-radius: 10rpx;
+  padding: 20rpx;
+}
+
+.form_group input, .form_group picker {
+  width: 100%;
+  border-bottom: 1px solid #ddd;
+   color: $base-btn-color;
+  height: 60rpx;
+  line-height: 60rpx;
+  padding: 0rpx 20rpx;
+}
+
+.ar_picker_wrap picker {
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.tui-picker-content picker {
+  width: 260rpx;
+  display: inline-block;
+  padding: 0 10rpx;
+}
+
+.tui-picker-content .time_text {
+  margin: 0 20rpx;
+}
+
+/*主容器*/
+
+.stepper {
+  width: 214rpx;
+  height: 60rpx;
+  border: 2rpx solid #ddd;
+  border-radius: 10rpx;
+  background: #fff;
+  margin-top: 10rpx;
+}
+
+/*加号和减号*/
+
+.stepper text {
+  float: left;
+  width: 70rpx;
+  line-height: 52rpx;
+  text-align: center;
+}
+
+/*数值*/
+
+.stepper input {
+  width: 70rpx;
+  height: 60rpx;
+  float: left;
+  margin: 0 auto;
+  text-align: center;
+  font-size: 12px;
+  border: none;
+  border-left: 1px solid #ddd;
+  border-right: 1px solid #ddd;
+  padding: 0;
+  border-radius: 0;
+  color: $base-btn-color;
+}
+
+/*普通样式*/
+
+.stepper .normal {
+  color: black;
+}
+
+/*禁用样式*/
+
+.stepper .disable {
+  color: #ccc;
+}
+
+.get_code {
+  padding: 0rpx 60rpx;
+  position: fixed;
+  bottom: 20rpx;
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.ar_book {
+  background: $base-btn-color;
+  font-size: 28rpx;
+  color: #fff;
+  border-radius: 10rpx;
+  margin: 40rpx 0rpx 10rpx;
+  padding: 0rpx 60rpx;
+}
+
+.show-btn {
+  margin-top: 100rpx;
+  color: #2c2;
+}
+
+.modal-mask {
+  width: 100%;
+  height: 100%;
+  position: fixed;
+  top: 0;
+  left: 0;
+  background: #000;
+  opacity: 0.5;
+  overflow: hidden;
+  z-index: 9000;
+  color: #fff;
+}
+
+.modal-dialog {
+  width: 540rpx;
+  overflow: hidden;
+  position: fixed;
+  top: 50%;
+  left: 0;
+  z-index: 9999;
+  background: #f9f9f9;
+  margin: -180rpx 105rpx;
+  border-radius: 36rpx;
+}
+
+.modal-title {
+  padding-top: 50rpx;
+  font-size: 36rpx;
+  color: #030303;
+  text-align: center;
+}
+
+.modal-content {
+  padding: 50rpx 32rpx;
+}
+
+.modal-input {
+  display: flex;
+  font-size: 40rpx;
+}
+
+.password {
+  width: 100%;
+  height: 80rpx;
+  font-size: 40rpx;
+  line-height: 80rpx;
+  padding: 0 20rpx;
+  box-sizing: border-box;
+  color: #ec5300;
+  text-align: center;
+}
+
+input-holder {
+  color: #666;
+  font-size: 28rpx;
+}
+
+.modal-footer {
+  display: flex;
+  flex-direction: row;
+  height: 86rpx;
+  border-top: 1px solid #dedede;
+  font-size: 34rpx;
+  line-height: 86rpx;
+}
+.modal-footer button::after{
+   border: none;
+  
+}
+.modal-footer .btn-cancel {
+  width: 50%;
+  color: #666;
+  text-align: center;
+  border-right: 1px solid #dedede;
+ border-radius: 0;
+}
+
+.modal-footer .btn-confirm {
+  width: 50%;
+  color: #ec5300;
+  text-align: center;
+}
+
+/* 密码有效期 */
+
+.itemBox {
+  flex-flow: wrap;
+}
+
+.itemBox view {
+  width: 30%;
+  box-sizing: border-box;
+  margin: 10rpx;
+}
+
+.itemBox view.active text{
+  background: $base-btn-color;
+  color: #fff;
+}
+
+.itemBox view text {
+  text-align: center;
+  width: 100%;
+  background: #fff;
+  color: $base-btn-color;
+  font-size: 28rpx;
+  display: inline-block;
+  border: 2rpx solid $base-btn-color;
+  border-radius: 40rpx;
+}
+
+
+</style>

+ 263 - 0
pages/bluetooth/bluetooth.vue

@@ -0,0 +1,263 @@
+<template>
+<view :class="$isEmpty(scanList)?'empty-wrap':''">
+<view class="container" v-if="scanList.length>0">
+  <scroll-view scroll-y :style="'height:' + list_height + 'rpx'">
+    <block v-for="(item, index) in scanList" :key="index">
+      <view class="list-item">
+        <view style="display:flex;flex-direction:column;width:80%">
+          <text style="font-size:medium;word-break:break-all">设备名称: {{item.name}}</text>
+          <text style="font-size:x-small;color:gray;word-break:break-all">设备ID: {{item.deviceId}}</text>
+          <text style="font-size:x-small;color:gray;word-break:break-all">信号强度RSSI: {{item.RSSI}}</text>
+        </view>
+        <view class="openBtn" :data-deviceId="item.deviceId" :data-wxapp_ekey="item.wxapp_ekey" @tap="openDoor">开门</view>
+      </view>
+    </block>
+  </scroll-view>
+</view>
+<view class="default" v-if="scanList==null || scanList.length==0">
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有扫描到设备</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+//西墨sdk对象
+var tmsdk = require("assets/js/DoormasterSDK-V1.4.js");
+const app = getApp();
+export default {
+  data() {
+    return {
+      scanList: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+  * 生命周期函数--监听页面加载
+  */
+  onLoad: function (options) {
+    //监听蓝牙适配器状态变化
+    uni.onBluetoothAdapterStateChange(function (res) {//console.log(`----adapterState changed, now is`, res)
+    }); //扫描附近设备
+
+    this.scanDevices();
+  },
+
+  /**
+  * 页面相关事件处理函数--监听用户下拉动作
+  */
+  onPullDownRefresh: function () {
+    uni.stopPullDownRefresh(); //注意!下拉刷新,Android系统设备应执行一次停止蓝牙发现接口
+
+    if (app.globalData.platform == 'android') {
+      uni.stopBluetoothDevicesDiscovery({
+        success: function (res) {// console.log('----stopBluetoothDevicesDiscovery', res)
+        }
+      });
+    } //重新扫描蓝牙设备
+
+
+    this.scanDevices();
+  },
+  onUnload: function () {
+    uni.stopBluetoothDevicesDiscovery({
+      success: function (res) {// console.log('---stopBluetoothDevicesDiscovery--success',res);
+      }
+    });
+    uni.closeBluetoothAdapter({
+      success: function (res) {// console.log('---closeBluetoothAdapter--success', res);
+      }
+    });
+  },
+  methods: {
+    //扫描蓝牙设备
+    scanDevices: function () {
+      uni.showLoading({
+        title: '扫描中...',
+        mask: true
+      });
+      var that = this;
+      tmsdk.scanDevices(function (res) {
+        if (!res.isBluetoothAvailable) {
+          uni.hideLoading();
+          uni.showModal({
+            content: '请打开蓝牙',
+            showCancel: false,
+            success: function (res) {
+              if (res.confirm) {
+                uni.navigateBack({
+                  delta: 1 // 返回上一级页面。
+
+                }); //跳转到首页
+                // wx.redirectTo({
+                //   url: '/pages/index/index'
+                // })
+              }
+            }
+          });
+          return;
+        } //筛选后的西墨设备列表
+
+
+        var scanList = res.scanList; //未获取的设备
+
+        if (scanList.length == 0) {
+          uni.hideLoading();
+          uni.showModal({
+            content: '未获取到设备信息,请靠近设备再试',
+            showCancel: false,
+            success: function (res) {
+              if (res.confirm) {
+                uni.navigateBack({
+                  delta: 1 // 返回上一级页面。
+
+                }); //跳转到首页
+                // wx.redirectTo({
+                //   url: '/pages/index/index'
+                // })
+              }
+            }
+          });
+          return;
+        } else {
+          uni.hideLoading(); //过滤设备-z
+
+          let scanList_new = new Array();
+          let device_list = app.globalData.device_list;
+
+          for (let i = 0; i < scanList.length; i++) {
+            for (let x = 0; x < device_list.length; x++) {
+              if (scanList[i].name == device_list[x].dev_sn) {
+                scanList[i]['name'] = device_list[x].dev_name; //用户私钥
+
+                scanList[i]['wxapp_ekey'] = device_list[x].wxapp_ekey;
+                scanList_new.push(scanList[i]);
+              }
+            }
+          }
+
+          if (scanList_new.length == 0) {
+            uni.hideLoading();
+            uni.showModal({
+              content: '未获取到授权设备',
+              showCancel: false,
+              success: function (res) {
+                if (res.confirm) {
+                  uni.navigateBack({
+                    delta: 1 // 返回上一级页面。
+
+                  }); //跳转到首页
+                  // wx.redirectTo({
+                  //   url: '/pages/index/index'
+                  // })
+                }
+              }
+            });
+            return;
+          }
+
+          that.setData({
+            scanList: scanList_new
+          });
+        }
+      });
+    },
+    // 执行开门操作
+    openDoor: function (event) {
+      uni.showLoading({
+        title: '开门中...',
+        mask: true
+      });
+      var deviceId = event.currentTarget.dataset.deviceid;
+      var wxapp_ekey = event.currentTarget.dataset.wxapp_ekey;
+      console.info(deviceId + "=" + wxapp_ekey);
+      tmsdk.openDoor(deviceId, wxapp_ekey, function (res) {
+        uni.hideLoading();
+        console.log("----res.errCode:", res.errCode); // 暂时忽略10008错误码,这是其余所有系统上报的异常
+
+        if (res.errCode === 0 || res.errCode === 10008) {
+          uni.showToast({
+            title: '开门成功',
+            icon: "success"
+          });
+        } else {
+          uni.showToast({
+            title: '开门失败,' + '错误码:' + res.errCode
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+.container {
+  align-items: center;
+}
+
+.list-item {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+  border-radius: 10rpx;
+  padding: 30rpx;
+  box-sizing: border-box;
+  background: #fff;
+  margin: 30rpx;
+  position: relative;
+  line-height:40rpx;
+}
+
+.list-item:last-child {
+  border-style: none;
+}
+
+.button {
+  position: fixed;
+  width: 690rpx;
+  bottom: 30rpx;
+}
+
+.openBtn {
+  float: right;
+}
+
+.openBtn {
+  position: absolute;
+  right: 20rpx;
+  top: 50%;
+  transform: translate(0, -50%);
+  border: 1px solid $base-btn-color;
+  height: 40rpx;
+  line-height: 40rpx;
+  padding: 0 20rpx;
+  border-radius: 6rpx;
+  color: #fff;
+  background: $base-btn-color;
+}
+.default {
+  text-align: center;
+  position: fixed;
+  left: 50%;
+  top: 40%;
+  transform: translate(-50%, -50%);
+}
+.default text{
+	color: #AAAAAA;
+}
+.default image {
+  height: 280rpx;
+  display: inline-block;
+}
+.empty-wrap{
+	background-color: #FFFFFF;
+	min-height: 100vh;
+}
+
+</style>

+ 296 - 0
pages/choosePlot/choosePlot.vue

@@ -0,0 +1,296 @@
+<template>
+<view>
+	<view class="cu-bar bg-white search " >
+		<view class="search-form round">
+			<text class="cuIcon-search"></text>
+			<input @input="nameInputSearch"  placeholder="输入小区名称" placeholder-style="font-size: 28rpx"></input>
+		</view>
+	</view>
+	
+	<view class="bg-gray" style="padding: 12rpx 30rpx;">
+		<text >当前选择城市:</text>
+	</view>
+	<view  style="padding:30rpx 30rpx 20rpx 30rpx;border-bottom: 1rpx solid #efefef;display: flex;justify-content: space-between;">
+		<view class="text-blue">
+			<text class="cuIcon-location padding-right-10"></text>
+			<text class="">{{city}}{{county}}</text>
+		</view>
+		<view class="cu-btn line-blue sm round" @tap="switchCity">
+			<text class="cuIcon-refresh padding-right-10"></text>
+			<text>切换城市</text>
+		</view>
+	</view>
+	<view class="bg-gray" style="padding: 12rpx 30rpx;">
+		<text >选择小区:</text>
+	</view>
+<view class="nav_section" v-if="residential_list.length>0">
+  <view v-for="(item, index) in residential_list" :key="index" @tap="jump" :data-id="item.id" :data-name="item.name">
+    <view class="nav_section_items">
+      <view class="section_cont">
+        <view class="section_cont_tel">
+          <text class="info">{{item.name}}</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</view>
+<view class="default" v-if="residential_list==null || residential_list.length==0">
+  <image src="http://139.9.103.171:1888/img/image/default_icon.png"></image>
+  <view>
+    <text>没有获取到小区信息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+const config = require("../../utils/config.js");
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      //location: app.defaultCity,
+      //county: app.defaultCounty,
+	  //市的名字
+      city: '',
+	  //区的名字
+      county: '',
+      currentCityCode: null,
+      //选择的当前城市所在的区编号,
+      residential_list: null,
+      //小区数据列表
+      sign: false
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+	  console.log(options)
+	if(!this.$isEmpty(options.city)&&!this.$isEmpty(options.county)&&!this.$isEmpty(options.currentCityCode)){
+		this.currentCityCode=options.currentCityCode
+		this.city=options.city
+		this.county=options.county
+		this.getCommunity();
+	}else{
+		uni.showLoading({
+		  mask: true,
+		  title: '定位中'
+		});
+		this.getLocation();
+	}
+    if (options.from_index == 'index') {
+      this.setData({
+        sign: true
+      });
+    } else {
+      this.setData({
+        sign: false
+      });
+    }
+  },
+  onShow() {
+  	
+  },
+  methods: {
+    jump(e) {
+	  let that=this
+      let id = e.currentTarget.dataset.id;
+	  app.globalData.residentialId=id
+      let name = e.currentTarget.dataset.name;
+
+      if (this.sign) {
+        //清空全局list
+        app.globalData.room_list = null;
+        app.globalData.device_list = null;
+        uni.setStorageSync('plotName', name);
+        uni.navigateTo({
+          url: '/pages/index/index?residential_id=' + id + '&residential_name=' + name
+        });
+      } else {
+		 console.log("1111")
+        uni.navigateTo({
+          url: '/pages/choosePlot/chooseUnit/chooseUnit?residential_id=' + id + '&residential_name=' + name,
+          success: function (res) {
+			  
+		  },
+          fail: function (res) {
+			  console.log(res)
+		  },
+          complete: function (res) {}
+        });
+      }
+    },
+
+    //切换城市
+    switchCity: function () {
+      //兼容地图插件
+      app.globalData.city = this.city;
+      app.globalData.currentCityCode = this.currentCityCode;
+      app.globalData.county = this.county;
+      uni.navigateTo({
+        url: '/pages/switchcity/switchcity'
+      });
+    },
+    getLocation: function () {
+      //console.log("正在定位城市");
+      this.setData({
+        county: ''
+      });
+      const that = this;
+      uni.getLocation({
+        type: 'wgs84',
+        success: function (res) {
+          let latitude = res.latitude;
+          let longitude = res.longitude;
+          uni.request({
+            url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${config.key}`,
+            success: res => {
+              uni.hideLoading(); // console.log(res)
+
+              console.log(res.data.result.ad_info.city + res.data.result.ad_info.adcode);
+              that.setData({
+                city: res.data.result.ad_info.city,
+                currentCityCode: res.data.result.ad_info.adcode,
+                //区code  如,越秀区--440104
+                county: res.data.result.ad_info.district
+              }); //兼容地图插件
+
+              app.globalData.city = res.data.result.ad_info.city;
+              app.globalData.currentCityCode = res.data.result.ad_info.adcode;
+              app.globalData.county = res.data.result.ad_info.district; //拉取小区信息
+
+              that.getCommunity();
+            }
+          });
+        }
+      });
+    },
+    //根据区编号获取小区列表
+    getCommunity: function (residential_name) {
+      let that = this;
+      let params = {};
+      params['region_area'] = this.currentCityCode;
+      params['residential_name'] = residential_name;
+      let operation = 'estate/getByRegionArea';
+      app.globalData.postRequest(params, operation, function (res) {
+        //获取成功
+        if (res.data.result_code == 1) {
+          that.setData({
+            residential_list: res.data.list
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    },
+    //输入小区名字联想搜索
+    nameInputSearch: function (e) {
+      let residential_name = e.detail.value;
+      this.getCommunity(residential_name);
+    } // //小程序 点击搜索 按钮时  事件
+    // inputSearch(e) {
+    //   console.info("11111111");
+    //   debugger
+    // },
+
+  }
+};
+</script>
+<style>
+page{
+  overflow-y: scroll;
+  background-color:#FFFFFF
+}
+input {
+  text-align: center;
+  font-size: 32rpx;
+  padding: 5px;
+  border-radius:10rpx;
+  background-color: #fff;
+}
+.input {
+  padding: 16rpx;
+  border-bottom: 1rpx solid #e2e2e2;    
+}
+
+
+/* pages/myHome/myHome.wxss */
+
+.nav_section {
+  width: 100%;
+  background-color: #FFFFFF;
+}
+
+.nav_section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  border-bottom: 2rpx solid #efefef;
+  position: relative;
+}
+
+.nav_section_items:active {
+  background: #ddd;
+}
+
+
+
+.nav_section_items .section_cont view {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+}
+.nav_section_items .section_cont .section_cont_sub {
+  font-size: 30rpx;
+  line-height: 50rpx;
+  color: #000;
+  margin-bottom: 10rpx;
+}
+.section_cont_tel .info{
+  width: 500rpx;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  display: inline-block;
+}
+.local_city{
+    padding: 30rpx;
+    position:relative;
+    background: #fff;
+}
+.local_city .changeCity{
+    padding: 30rpx;
+    position: absolute;
+    right: 0rpx;
+    top: 0;
+}
+.local_city .icon{
+    padding: 20rpx;
+    position: absolute;
+    left: -36rpx;
+    top: 50%;
+    transform: translate(0,-50%);
+    font-size: 40rpx;
+}
+.default {
+  text-align: center;
+  position: fixed;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+}
+
+.default image {
+  width: 128rpx;
+  height: 128rpx;
+  display: inline-block;
+}
+</style>

+ 145 - 0
pages/choosePlot/chooseRoom/chooseRoom.vue

@@ -0,0 +1,145 @@
+<template>
+<view :class="$isEmpty(room_list)?'empty-wrap':''">
+<view class="bg-gray" style="padding: 16rpx 30rpx;">
+	<text >当前选择楼栋:</text>
+</view>
+<view class="bg-white" style="padding:30rpx 30rpx 20rpx 30rpx;border-bottom: 1rpx solid #efefef;display: flex;justify-content: space-between;">
+	<view class="text-blue">
+		<text class="">{{unit_name}}</text>
+	</view>
+	<view class="cu-btn line-blue sm round" @tap="change">
+		<text class="cuIcon-refresh padding-right-10"></text>
+		<text>切换楼栋</text>
+	</view>
+</view>
+	<view class="bg-gray" style="padding: 12rpx 30rpx;">
+		<text >选择房间:</text>
+	</view>
+<view class="nav_section" v-if="room_list.length>0">
+  <navigator open-type="redirect" v-for="(item, index) in room_list" :key="index" :url="'../../auth/auth?room_id=' + item.id + '&room_name=' + item.name + '&residential_name=' + residential_name + '&unit_name=' + unit_name">
+    <view class="nav_section_items">
+      <view class="section_cont">
+        <view class="section_cont_tel">
+          <text class="info">{{item.name}}</text>
+        </view>
+      </view>
+    </view>
+  </navigator>
+</view>
+<view class="default" v-if="$isEmpty(room_list)">
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有获取到房间信息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+var app = getApp();
+
+export default {
+  data() {
+    return {
+	  city_county_name:"",
+	  //房间号
+      room_list: null,
+	  //小区名字
+      residential_name: null,
+	  //楼栋名字
+      unit_name: null 
+
+    };
+  },
+  components: {},
+  props: {},
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+	  this.city_county_name=uni.getStorageSync("cityCountyName")
+    //小区名字
+    var residential_name = options.residential_name; //楼栋名字
+    var unit_name = options.unit_name;
+    this.setData({
+      residential_name: residential_name,
+      unit_name: unit_name
+    });
+    var unit_id = options.unit_id;
+    this.getRoom(unit_id);
+  },
+  methods: {
+	  change(){
+		uni.navigateBack({
+			delta:1
+		})  
+	  },
+    //根据楼栋信息查询房间
+    getRoom: function (unit_id) {
+      let that = this;
+      let params = {};
+      params['unit_id'] = unit_id;
+      let operation = 'estate/getByUnitId';
+      app.globalData.postRequest(params, operation, function (res) {
+        //获取成功
+        if (res.data.result_code == 1) {
+          that.setData({
+            room_list: res.data.list
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style>
+/* pages/choosePlot/chooseUnit/chooseUnit.wxss */
+page{
+  overflow-y: scroll
+}
+.nav_section {
+  width: 100%;
+  background:#fff;
+}
+
+.nav_section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  border-bottom: 2rpx solid #ddd;
+  position: relative;
+}
+
+.nav_section_items:active {
+  background: #ddd;
+}
+
+
+
+.nav_section_items .section_cont view {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+}
+.nav_section_items .section_cont .section_cont_sub {
+  font-size: 30rpx;
+  line-height: 50rpx;
+  color: #000;
+  margin-bottom: 10rpx;
+}
+.section_cont_tel .info{
+  width: 500rpx;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  display: inline-block;
+}
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
+.default text{
+	color: #AAAAAA;
+}
.default image {
  height: 250rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+</style>

+ 150 - 0
pages/choosePlot/chooseUnit/chooseUnit.vue

@@ -0,0 +1,150 @@
+<template>
+<view :class="$isEmpty(unit_list)?'empty-wrap':''">
+	<view class="bg-gray" style="padding: 16rpx 30rpx;">
+		<text >当前选择小区:</text>
+	</view>
+	<view class="bg-white" style="padding:30rpx 30rpx 20rpx 30rpx;border-bottom: 1rpx solid #efefef;display: flex;justify-content: space-between;">
+		<view class="text-blue">
+			<text class="">{{residential_name}}</text>
+		</view>
+		<view class="cu-btn line-blue sm round" @tap="change">
+			<text class="cuIcon-refresh padding-right-10"></text>
+			<text>切换小区</text>
+		</view>
+	</view>
+	<view class="bg-gray" style="padding: 12rpx 30rpx;">
+		<text >选择楼栋:</text>
+	</view>
+<view class="nav_section" v-if="unit_list.length>0">
+  <view @click="jump(item)" v-for="(item, index) in unit_list" :key="index" >
+    <view class="nav_section_items">
+      <view class="section_cont">
+        <view class="section_cont_tel">
+          <text class="info">{{item.name}}</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</view>
+<view class="default" v-if="$isEmpty(unit_list)">
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text >没有获取到楼栋信息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      unit_list: null,
+      //小区集合
+      residential_name: null //小区名字
+
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+	  console.log(app.defaultCity,)
+    //小区名字
+    var residential_name = options.residential_name;
+    this.setData({
+      residential_name: residential_name
+    }); //小区id
+
+    var residential_id = options.residential_id;
+    this.getUnit(residential_id);
+  },
+  methods: {
+	  change(){
+		uni.navigateBack({
+			delta:1
+		})  
+	  },
+	  jump(item){
+		  app.globalData.unitId=item.id
+		  uni.navigateTo({
+		  	 url:"/pages/choosePlot/chooseRoom/chooseRoom?unit_id=" + item.id + "&unit_name=" + item.name + "&residential_name=" + this.residential_name
+		  })
+	  },
+    //根据小区id获取楼栋信息
+    getUnit: function (residential_id) {
+      let that = this;
+      let params = {};
+      params['residential_id'] = residential_id;
+      let operation = 'estate/getByResidentialId';
+      app.globalData.postRequest(params, operation, function (res) {
+        //获取成功
+        if (res.data.result_code == 1) {
+          that.setData({
+            unit_list: res.data.list
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style>
+/* pages/choosePlot/chooseUnit/chooseUnit.wxss */
+page{
+  overflow-y: scroll
+}
+.nav_section {
+  width: 100%;
+  background:#fff;
+
+}
+
+.nav_section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  border-bottom: 2rpx solid #ddd;
+  position: relative;
+}
+
+.nav_section_items:active {
+  background: #ddd;
+}
+
+
+
+.nav_section_items .section_cont view {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+}
+.nav_section_items .section_cont .section_cont_sub {
+  font-size: 30rpx;
+  line-height: 50rpx;
+  color: #000;
+  margin-bottom: 10rpx;
+}
+.section_cont_tel .info{
+  width: 500rpx;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  display: inline-block;
+}
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
+.default text{
+	color: #AAAAAA;
+}
+
.default image {
  height: 250rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+</style>

+ 643 - 0
pages/choosePlot/householdCert/householdCert.vue

@@ -0,0 +1,643 @@
+<template>
+	<view class="bg-white">
+		<view class="flex justify-between " style="padding: 30rpx;box-sizing: border-box;">
+			<view class="" style="font-size: 38rpx;">
+				<text class="text-bold text-black">您的申请信息</text>
+			</view>
+			<view class="text-red"  style="padding-top: 12rpx;">
+				<text style="font-size: 38rpx;">{{totalStep}}</text>
+				<text class="text-df">/{{totalStep}}</text>
+			</view>
+		</view>
+		<view class="">
+			<view style="padding: 50rpx 0 20rpx 48rpx;">
+				<text class="cuIcon-location padding-right-sm"></text>
+				<text class="local_city_info">{{residential_name}} {{unit_name}} {{room_name}}</text>
+			</view>
+		</view>
+		<view class="form">
+				<u-form :border="true" ref="uForm" >
+					<u-form-item :required="true"  label="住户姓名:" prop="name" label-width="150">
+						<u-input :border="true"  placeholder="住户姓名,必填" v-model="name" type="text"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="住户类型:" prop="type" label-width="150">
+						<u-input :border="true"  type="select" :select-open="typeShow" v-model="typeLabel" placeholder="请选择住户类型" @click="typeShow = true"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="国籍:" prop="nationality" label-width="150">
+						<u-input :border="true" type="select" :select-open="nationalityShow" v-model="nationalityLabel"  @click="nationalityShow = true"></u-input>
+					</u-form-item>
+					<u-form-item   label="证件类型:" prop="nationalityName" label-width="150">
+						<u-input :disabled="true" :border="true" type="text" v-model="nationalityName"></u-input>
+					</u-form-item>
+					<u-form-item :required="type==0?true:false"  label="证件号码" prop="id_card" label-width="150">
+						<u-input :border="true" placeholder="住户类型是业主时,必填" :trim="true"  maxlength="18" v-model="id_card" type="number"></u-input>
+					</u-form-item>
+					<u-form-item :required="true" label="性别" prop="sex" label-width="150">
+						<u-radio-group v-model="sex" >
+							<u-radio shape="circle"  name="1">男</u-radio>
+							<u-radio shape="circle"  name="2">女</u-radio>
+						</u-radio-group>
+					</u-form-item>
+				</u-form>
+		</view>
+		<view v-if="nationality==3" style="background-color: #FFFFFF;">
+		  <view class="form_group mb0" style="padding-left: 60rpx;">
+		    <view>
+		      <text class="sex">护照图片:</text>
+		      <text class="tips">(基本身份信息页)</text>
+		    </view>
+		  </view>
+		  <view @click="show=true;operaType=1" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+		    <upload-img
+		  	  :width="$isEmpty(show_passport_img_uri)?bgWidth:imgWidth"
+		  	  :height="$isEmpty(show_passport_img_uri)?bgHeight:imgHeight"
+		  	  :currentImage="show_passport_img_uri"
+		  	  :bgsrc="bgsrc"
+		  	  >
+		    </upload-img>
+		    <view class="" style="color: #59a5f0;">
+		  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+		  	 <text v-if="$isEmpty(show_passport_img_uri)">点击上传护照</text>
+		  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+		    </view>
+		  </view>
+		</view>
+		
+		<view v-if="nationality==3" style="background-color: #FFFFFF;">
+		  <view class="form_group mb0" style="padding-left: 60rpx;">
+		    <view>
+		      <text class="sex">入境证明:</text>
+		      <text class="tips">(入镜盖章页)</text>
+		    </view>
+		  </view>
+		  <view  @click="show=true;operaType=2" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+		    <upload-img
+		  	  :width="$isEmpty(show_entry_img_uri)?bgWidth:imgWidth"
+		  	  :height="$isEmpty(show_entry_img_uri)?bgHeight:imgHeight"
+		  	  :currentImage="show_entry_img_uri"
+		  	  :bgsrc="bgsrc"
+		  	  >
+		    </upload-img>
+		    <view class="" style="color: #59a5f0;">
+		  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+		  	 <text v-if="$isEmpty(show_entry_img_uri)">点击上传入境证明</text>
+		  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+		    </view>
+		  </view>
+		</view>
+		
+		<view style="background-color: #FFFFFF;">
+					<view class="form_group mb0" style="padding-left: 60rpx;">
+						 <view>
+							<text class="sex">人脸:</text>
+							<text class="tips">(人脸用于开门,请上传正脸图片)</text>
+						  </view>
+					</view>
+					<view @click="show=true;operaType=3" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+					  <upload-img
+						  :width="$isEmpty(show_image_uri)?bgWidth:imgWidth"
+						  :height="$isEmpty(show_image_uri)?bgHeight:imgHeight"
+						  :currentImage="show_image_uri"
+						  :bgsrc="bgsrc"
+						  >
+					  </upload-img>
+					  <view class="" style="color: #59a5f0;">
+						 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+						 <text v-if="$isEmpty(show_image_uri)">点击上传人面</text>
+						 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+					  </view>
+					</view>
+					<view class="category" style="padding-bottom: 140rpx;">
+						<view v-for="(item, index) in iconArray" :key="index" class="category_item">
+						  <view class="category_item_wrap" @tap="top" :data-index="item.index">
+							<view class="icon_wrap">
+							  <image :src="item.iconUrl" class="index_icon"></image>
+							</view>
+							<view class="category_item_text">
+							  <text>{{item.iconText}}</text>
+							</view>
+						  </view>
+					</view>
+			</view>
+		</view>
+	  <u-action-sheet @click="photoChecked"  z-index="999999" :list="list" v-model="show"></u-action-sheet>
+	  <u-select z-index="999999" mode="single-column" :list="typeArry" v-model="typeShow" @confirm="typeConfirm"></u-select>
+	  <u-select z-index="999999" mode="single-column" :list="nationalityArry" v-model="nationalityShow" @confirm="nationalityConfirm"></u-select>
+	  <view  @click="showDialogBtn"  class=" footer-fixed" >
+	  	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+	  		提交认证
+	  	</view>
+	  </view>
+	</view>
+ </view>
+</template>
+
+<script>
+import uploadImg from '@/comps/uploadimg/uploadImg.vue'
+//获取app实例
+var app = getApp();
+export default {
+	components:{
+		uploadImg
+	},
+	data() {
+		return {
+			//默认点击弹出拍照模态框的是人面上传操作,1:护照,2:入境,3:人面
+			operaType:3,
+			//人面上传模态框,上传照片或拍照
+			list: [{
+				text: '相册上传',
+			}, {
+				text: '拍照上传'
+			}],
+			show: false,
+			
+			//背景图
+			bgsrc:'http://139.9.103.171:1888/img/image/camera1.png',
+			bgWidth:350,
+			bgHeight:320,
+			//显示图
+			imgWidth:540,
+			imgHeight:400,
+			
+			//总步骤数
+			totalStep:2,
+			sex: "1",
+			//住户类型
+			typeLabel:'业主',
+			typeShow: false,
+			type: 0,
+			typeArry: [
+				{
+					value: '0',
+					label: '业主'
+				},
+				{
+					value: '1',
+					label: '成员'
+				},
+				{
+					value: '2',
+					label: '租户'
+				}
+			],
+			
+			//国籍
+			nationalityLabel:'中国大陆',
+			nationalityShow: false,
+			nationality: 0,
+			nationalityName:'身份证',
+			nationalityArry: [
+				{
+					value: '0',
+					label: '中国大陆'
+				},
+				{
+					value: '1',
+					label: '中国香港/澳门'
+				},
+				{
+					value: '2',
+					label: '中国台湾'
+				},
+				{
+					value: '3',
+					label: '海外'
+				}
+			],
+			
+			//住户名字
+			name: '',
+			residential_name: "",
+			//小区名字
+			community_name: '',
+			//楼栋名字
+			unit_name: '',
+			//房间名字
+			room_name: '',
+			//房间id
+			room_id: '',
+			
+			//护照照片
+			passport_img_uri: null,
+			//护照照片回显
+			show_passport_img_uri: null,
+			//入境证明
+			entry_img_uri: null,
+			//入境证明回显
+			show_entry_img_uri: null,
+			//人脸图片地址
+			image_uri: null,
+			//人脸回显
+			show_image_uri: null,
+			//图片的md5
+			face_code: null,
+			
+			//身份证
+			id_card: null,
+			iconArray: [{
+			  "iconUrl": "http://139.9.103.171:1888/img/image/zd.png",
+			  "iconText": '不要遮挡',
+			  "index": 1
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/mj.png",
+			  "iconText": '不戴墨镜',
+			  "index": 2
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/zl.png",
+			  "iconText": '不能仰头俯拍',
+			  "index": 3
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/cz.png",
+			  "iconText": '光线充足',
+			  "index": 4
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/bg.png",
+			  "iconText": '浅色背景',
+			  "index": 5
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/sh.png",
+			  "iconText": '物业审核生效',
+			  "index": 6
+			}],
+			
+		};
+	},
+	onLoad: function (options) {
+		  //显示用户选择的小区+楼栋+房间名字
+		  this.residential_name = options.residential_name;
+		  this.unit_name = options.unit_name;
+		  this.room_name = options.room_name;
+		  this.room_id = options.room_id;
+		  this.name=app.globalData.member.name
+	},
+	onShow() {
+		//总步骤数
+		//注册的流程总步骤数是3,其他流程总步骤数是2
+		if(this.$isEmpty(app.globalData.totalStep)){
+			this.totalStep=2
+		}else{
+			this.totalStep=app.globalData.totalStep
+		}
+		
+		//获取当前页面的对象,获取拍照回显照片
+		let currPage=this.$util.getPageCtx()
+		if(!this.$isEmpty(currPage.data.image)){
+			this.uploadImage(currPage.data.image)
+		} 
+		
+		
+	},
+	computed: {
+		
+	},
+	methods: {
+		//点击模态框选项触发
+		photoChecked(index){
+			if (index==0) {
+				//图片上传
+				this.chooseImage()
+			} else if(index==1){
+				if(this.operaType==3){
+					//拍照上传,拍照人面
+					uni.navigateTo({
+						url:"../../my-camera/my-camera?type=0"
+					})
+				}else{
+					//拍照上传,拍照证件
+					uni.navigateTo({
+						url:"../../my-camera/my-camera?type=1"
+					})
+				}
+			}
+		},
+		
+		
+		typeConfirm(e) {
+			this.type = 0;
+			e.map((val, index) => {
+				this.type=val.value
+				this.typeLabel=val.label
+			})
+		},
+		nationalityConfirm(e) {
+			this.nationality = 0;
+			e.map((val, index) => {
+				this.nationality=val.value
+				this.nationalityLabel=val.label
+				
+				if (this.nationality == 0) {
+				  this.nationalityName = '身份证';
+				} else if (this.nationality == 1) {
+				  this.nationalityName = '港澳居民往来内地通行证';
+				} else if (this.nationality == 2) {
+				  this.nationalityName = '台湾居民往来大陆通行证';
+				} else if (this.nationality == 3) {
+				  this.nationalityName = '护照';
+				}
+			})
+		},
+		//点击上传图片事件
+		chooseImage: function () {
+		  var that = this;
+		  uni.chooseImage({
+		    count: 1,
+		    //最多可以选择的图片张数,默认9
+		    sourceType: ['album', 'camera'],
+		    sizeType: ['compressed'],
+		    //可选择原图或压缩后的图片
+		    success: res => {
+		      let tempFilePaths = res.tempFilePaths;
+			  that.uploadImage(tempFilePaths[0])
+		    }
+		  });
+		},
+		/**上传图片
+		 * @param {Object} imgUrl 图片url
+		 */
+		uploadImage(imgUrl){
+			console.log("operatype: ",this.operaType);
+			console.log("imgUrl",imgUrl)
+			var that = this;
+			//是否需要md5加密上传人面照
+			let is_need_md5 = false;
+			if (this.operaType == 3) {
+			  is_need_md5 = true;
+			}
+			uni.getFileSystemManager().readFile({
+			  filePath: imgUrl,
+			  //选择图片返回的相对路径
+			  encoding: 'base64',
+			  //编码格式
+			  success: res => {
+			    //成功的回调
+			    app.globalData.uploadBase64('data:image/jpeg;base64,' + res.data, is_need_md5, function (result) {
+			      if (that.operaType == 1) {
+			        that.setData({
+			          passport_img_uri: result.data.uri,
+			          show_passport_img_uri: imgUrl
+			        });
+			      } else if (that.operaType == 2) {
+			        that.setData({
+			          entry_img_uri: result.data.uri,
+			          show_entry_img_uri: imgUrl
+			        });
+			      } else if (that.operaType == 3) {
+			        that.setData({
+			          image_uri: result.data.uri,
+			          show_image_uri: imgUrl,
+			          face_code: result.data.md5Hex
+			        });
+			      }
+			    });
+			  }
+			});
+		},
+		//提交认证
+		showDialogBtn: function () {
+		  let params = {};
+		  let that = this;
+		
+		  if (that.name == "") {
+		    app.globalData.autoFailHint("请填写住户姓名");
+		    return;
+		  } 
+		  //用户类型
+		  let type = that.type; //['业主','成员','租户'],
+		  params['type'] = type; //0 中国大陆 1 中国香港/澳门 2 中国台湾 3 海外
+		  //国籍
+		  let nationality = that.nationality;
+		  params['nationality'] = nationality;
+		  //身份证
+		  var id_card = this.id_card;
+		  params['id_card'] = id_card; //业主身份证必填
+		
+		  if (type == 0 && !id_card) {
+		    app.globalData.autoFailHint("住户类型是业主时,证件号码必填");
+		    return;
+		  }
+		
+		  let passport_img_uri = that.passport_img_uri;
+		  let entry_img_uri = that.entry_img_uri;
+		
+		  if (nationality == 3) {
+		    params['passport_img_uri'] = that.passport_img_uri;
+		    params['entry_img_uri'] = that.entry_img_uri;
+		
+		    if (type == 0) {
+		      if (!passport_img_uri) {
+		        app.globalData.autoFailHint("请上传护照图片");
+		        return;
+		      }
+		      if (!entry_img_uri) {
+		        app.globalData.autoFailHint("请上传入境证明");
+		        return;
+		      }
+		    }
+		  }
+		  console.log(that.image_uri);
+		  let image_uri = that.image_uri;
+		  params['image_uri'] = that.image_uri;
+		  let face_code = that.face_code;
+		  params['face_code'] = that.face_code; //性别
+		  params['sex'] = that.sex;
+		  params['name'] = that.name;
+		  params['tel'] = app.globalData.member.tel;
+		  params['room_id'] = that.room_id; //申请来源0-小程序添加 1-后台添加  2-后台导入 3-app添加
+		  params['create_type'] = '0'; //申请的记录类型 0--认证类型 1--新增类型 2--编辑类型
+		  params['record_type'] = '0'; //会员id
+		  params['member_id'] = app.globalData.member.id;
+	
+		  let operation = 'member/authentication';
+			app.globalData.postRequest(params, operation, function (res) {
+		    //提交成功
+		    if (res.data.result_code == 1) {
+		      app.globalData.oneFailHint(res.data.result_msg, function () {
+		        //跳转到首页
+		        uni.reLaunch({
+		          url: '/pages/index/index?isFlush=true'
+		        });
+		      });
+		    } else {
+		      app.globalData.oneFailHint(res.data.result_msg);
+		    }
+		  });
+		}
+		
+	}
+};
+</script>
+
+<style scoped lang="scss">
+.form {
+	padding:0 60rpx;
+	background-color: #FFFFFF;
+}
+
+.local_city{
+    padding: 30rpx 0;
+    position:relative;
+    background: #fff;
+}
+.local_city .changeCity{
+    padding: 20rpx;
+    position: absolute;
+    right: 0rpx;
+    top: 0;
+}
+.local_city .icon{
+    padding: 20rpx;
+    position: absolute;
+    left: -0;
+    top: 50%;
+    transform: translate(0,-50%);
+    font-size: 40rpx;
+}
+.local_city .local_city_info{
+    padding-left: 40rpx;
+    display:inline-block;
+}
+
+.form_group .upload {
+  padding: 0 28rpx;
+  font-size: 26rpx;
+  background: $base-btn-color;
+  color: #fff;
+  border: none;
+}
+
+.upload_tips {
+  font-size: 24rpx;
+}
+
+.upload_bg {
+  position: relative;
+  text-align: center;
+}
+
+.mb0 {
+  padding-top: 40rpx;
+  font-size: 28rpx;
+  margin-bottom: 0;
+}
+
+.form_group .tips {
+  margin-left: 50rpx;
+}
+
+.upload_bg .upload_bgImg {
+  width: 540rpx;
+  height: 400rpx;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, 0);
+  color: $base-btn-color;
+}
+
+upload_bg {
+  position: relative;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 40%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 55%;
+  width: 100%;
+  color: $base-btn-color;
+}
+
+.img_content {
+  margin-top: 20rpx;
+  position: relative;
+  text-align: center;
+}
+
+.img_content .upload_bgImg {
+  width: 560rpx;
+  height: 420rpx;
+  max-height: 1;
+  display: inline-block;
+  border-radius: 20rpx;
+}
+
+.reUpload {
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: right;
+  color: #333;
+  padding-right: 100rpx;
+  font-size: 26rpx;
+}
+
+.img_content .img_icon {
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 6rpx;
+  border-radius: 20rpx;
+}
+
+.category {
+  padding:20px 20rpx 0;
+  overflow: auto;
+  background-color: #FFF;
+text-align:center;
+
+}
+.category_item {
+  width: 33.3%;
+  float: left;
+  margin-bottom: 40rpx;
+}
+.icon_wrap {
+  width: 120rpx;
+  margin: 0 auto;
+  margin-bottom: 5px;
+}
+.index_icon {
+  width: 60rpx;
+  height: 60rpx;
+}
+.category_item_text {
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+}
+
+</style>
+
+			
+		

+ 486 - 0
pages/community/community.vue

@@ -0,0 +1,486 @@
+<template>
+	<view class="container">
+		<view class="tabs">
+			<u-subsection height="90" active-color="#2f7ff5"  :list="subsectionList" :animation="false" :current="subsectionCurrent" @change="subsectionChange"></u-subsection>
+			<view class="" style="height: 20rpx;"></view>
+		</view>
+		<view style="height: 100%;">
+			<swiper style="height: 100%;" :current="subsectionCurrent"  @change="swiperChange"
+				@animationfinish="animationfinish">
+				<swiper-item >
+					<scroll-view scroll-y style="height: 100%;">
+						<view class="bg-white " >
+							<view style="margin: 0 0rpx 40rpx;">
+								<image style="width: 100%;" mode="widthFix" src="http://139.9.103.171:8888/group1/M00/00/01/iwlnq1-_4mqAf_t4AAKPnq9axkQ981.png" ></image>
+							</view>
+							<view class="bg-white padding-top-20" style="position: relative;top:-20rpx;">
+								<view class="text-bold text-lg margin-left-30 margin-bottom-sm">
+									<text class="cuIcon-titles text-blue margin-right-10 "></text>
+									<text>通用服务</text>
+								</view>
+								<view class="cu-list grid col-4 no-border " style="border-radius: 50rpx;">
+									<view class="cu-item" @click="goDetail(item)" v-for="(item,index) in commonList" :key="index">
+										<view class="grid-icon ">
+											<image  :src="item.icon" mode="widthFix"/>
+										</view>
+										<view class="cu-tag bg-orange badge" v-if="item.badge>0">{{item.badge}}</view>
+										<text class="text-sm ">{{item.title}}</text>
+									</view>
+								</view>
+							</view>
+							
+							<view class="text-bold text-lg margin-left-30 margin-bottom-sm ">
+								<text class="cuIcon-titles text-blue margin-right-10 "></text>
+								<text>手机服务</text>
+							</view>
+							<view class="cu-list grid col-4 no-border " style="border-radius: 50rpx;">
+								<view class="cu-item" @click="goDetail(item)" v-for="(item,index) in mobileList" :key="index">
+									<view class="grid-icon ">
+										<image  :src="item.icon" mode="widthFix"/>
+									</view>
+									<view class="cu-tag bg-orange badge" v-if="item.badge>0">{{item.badge}}</view>
+									<text class="text-sm ">{{item.title}}</text>
+								</view>
+							</view>
+						</view>
+						<view class="bg-white padding-top-20" style="position: relative;top:-10rpx;">
+							<view class="text-bold text-lg margin-left-30 margin-bottom-sm">
+								<text class="cuIcon-titles text-blue margin-right-10 "></text>
+								<text>宽带服务</text>
+							</view>
+							<view class="cu-list grid col-4 no-border " style="border-radius: 50rpx;">
+								<view class="cu-item" @click="goDetail(item)" v-for="(item,index) in broadbandList" :key="index">
+									<view class="grid-icon ">
+										<image   :src="item.icon" mode="widthFix"/>
+									</view>
+									<view class="cu-tag bg-orange badge" v-if="item.badge>0">{{item.badge}}</view>
+									<text class="text-sm ">{{item.title}}</text>
+								</view>
+							</view>
+						</view>
+						<view style="height: 80rpx;">
+							<u-divider bgColor="#f1f1f1;"  height="80">到底了</u-divider>
+						</view>
+					</scroll-view>
+				</swiper-item>
+				<swiper-item >
+					<scroll-view scroll-y style="height: 100%;background-color: #F1F1F1;">
+						<view style="height: 20rpx;"></view>
+						<view style="margin: 0 20rpx;">
+							<u-waterfall v-model="oldManList" ref="uWaterfall">
+								<template v-slot:left="{leftList}">
+									<view class="demo-warter"  v-for="(item, index) in leftList" :key="index">
+										<image :src="item.image"  class="demo-image" ></image>
+										<view class="time">
+											<text class="padding-bottom-10">抓拍时间:</text>
+											<text>{{item.time}}</text>
+										</view>
+										<view class="flex justify-center margin-bottom-50">
+											<view class="cu-btn line-blue round df" style="width: 70%;">
+												查看详情
+											</view>
+										</view>
+									</view>
+								</template>
+								<template v-slot:right="{rightList}">
+									<view class="demo-warter" v-for="(item, index) in rightList" :key="index">
+										<image :src="item.image"  class="demo-image" ></image>
+										<view class="time">
+											<text class="padding-bottom-10">抓拍时间:</text>
+											<text>{{item.time}}</text>
+										</view>
+										<view class="flex justify-center margin-bottom-50">
+											<view class="cu-btn line-blue round df" style="width: 70%;">
+												查看详情
+											</view>
+										</view>
+									</view>
+									
+								</template>
+							</u-waterfall>
+						</view>
+						<!-- <oldMan></oldMan> -->
+					</scroll-view>
+				</swiper-item>
+				<swiper-item >
+					<scroll-view scroll-y style="height: 100%;background-color: #F1F1F1;">
+						<view style="height: 20rpx;"></view>
+						<view style="margin: 0 20rpx;">
+							<u-waterfall v-model="carList" ref="uWaterfall">
+								<template v-slot:left="{leftList}">
+									<view class="demo-warter" v-for="(item, index) in leftList" :key="index">
+										<image :src="item.image"  class="demo-image" ></image>
+										<view class="time">
+											<text class="padding-bottom-10">抓拍时间:</text>
+											<text>{{item.time}}</text>
+										</view>
+										<view class="flex justify-center margin-bottom-50">
+											<view class="cu-btn line-blue round df" style="width: 70%;">
+												查看详情
+											</view>
+										</view>
+									</view>
+								</template>
+								<template v-slot:right="{rightList}">
+									<view class="demo-warter" v-for="(item, index) in rightList" :key="index">
+										<image :src="item.image"  class="demo-image" ></image>
+										<view class="time">
+											<text class="padding-bottom-10">抓拍时间:</text>
+											<text>{{item.time}}</text>
+										</view>
+										<view class="flex justify-center margin-bottom-50">
+											<view class="cu-btn line-blue round df" style="width: 70%;">
+												查看详情
+											</view>
+										</view>
+									</view>
+									
+								</template>
+							</u-waterfall>
+						</view>
+					</scroll-view>
+				</swiper-item>
+			</swiper>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	export default {
+		components:{
+		},
+		data() {
+			return {
+				oldManList:[
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/old1.jpg',
+						time:'2020-11-02 15:31:22'
+					},
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/c3a3a7d714e74b749a88ecefabfd86d.jpg',
+						time:'2020-11-22 09:51:56'
+					}
+				],
+				carList:[
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/1606682778(1).jpg',
+						time:'2020-11-04 12:38:26'
+					},
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/1606682866(1).jpg',
+						time:'2020-11-13 19:42:52'
+					}
+				],
+				
+				tanList: [ {
+					name: '老人关爱'
+				}, {
+					name: '车辆关爱'
+				}],
+				tabCurrent:0,
+				subsectionCurrent: 0,
+				subsectionList: [
+					{
+						name: '通讯服务'
+					}, 
+					{
+						name: '老人关爱'
+					},
+					{
+						name: '车辆关爱'
+					},
+				],
+				// 卡片列表
+				cardList:[
+					{
+						title:'热门活动',
+						subTiltle:'优惠多多',
+						type:'url',
+						target:'https://yx.nx.189.cn/u/public/index.php/index/index/rmhd.html'
+					},
+					{
+						title:'充值交费',
+						subTiltle:'用于充值交费',
+						type:'url',
+						target:'https://mp.weixin.qq.com/s/oGB5l9lZCQHHJJuXT0umRw'
+					},
+					{
+						title:'宽带预约',
+						subTiltle:'用于宽带预约',
+						type:'url',
+						target:'https://wap.nx.189.cn/pages/market/html/market.html'
+					},
+					{
+						title:'充30减2',
+						subTiltle:'手机充值满减活动',
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/dyq/index'
+					},
+					{
+						title:'抽话费',
+						subTiltle:'用于抽话费',
+						type:'url',
+						target:'https://pms.189.cn/cljy-web/static/chfchf/chfchf_zc_index.html?shopid=2000118600000002&cmpid=dp-002&number=undefined'
+					},
+					{
+						title:'流量超市',
+						subTiltle:'用于充值流量',
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/flowcs/index'
+					},
+					
+					
+					
+				],
+				commonList:[
+					// {
+					// 	icon:'../../static/test/icon3.png',
+					// 	title:"话费账单",
+					// 	badge:0,
+					// 	type:'url',
+					// 	target:'https://yx.nx.189.cn/u/public/index.php/index/index/historyold'
+					// },
+					{
+						icon:'../../static/test/paihao.png',
+						title:"营业厅排号",
+						badge:0,
+						type:'url',
+						target:'https://pdweb.360sides.com/?qudao=ningxia'
+					},
+					{
+						icon:'../../static/test/xiaohu.png',
+						title:"销户服务",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/hd2020zzyw/kuandai'
+					},
+					{
+						icon:'../../static/test/tuiding-zengzhi.png',
+						title:"增值服务退订",
+						badge:0,
+						type:'url',
+						target:'http://im.189.cn/cw/index.html?cf=1&cid=6400'
+					},
+					{
+						icon:'../../static/test/tuiding1.png',
+						title:"应用功能退订",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/hd2020zzyw/yy'
+					}
+				],
+				mobileList:[
+					{
+						icon:'../../static/test/chongzhi.png',
+						title:"话费充值",
+						badge:0,
+						type:'applet',
+						target:'wxd4daf5a66b681275'
+					},
+					{
+						icon:'../../static/test/liuliang.png',
+						title:"流量充值",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/flowcs/index'
+					},
+					{
+						icon:'../../static/test/icon21.png',
+						title:"号卡精选",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/hkcs/index'
+					},
+					{
+						icon:'../../static/test/xiehao.png',
+						title:"携号转网",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/m_lx2020xhzw/login_xhzw.do'
+					},
+					{
+						icon:'../../static/test/icon25.png',
+						title:"手机挂失",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/hd2020zzyw/guashi.html'
+					},
+					{
+						icon:'../../static/test/icon26.png',
+						title:"手机补换卡",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/hd2020zzyw/buhuanka'
+					},
+					{
+						icon:'../../static/test/icon24.png',
+						title:"彩铃功能",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/t/public/index.php/hd2020zzyw/cailing'
+					},
+				],
+				
+				broadbandList:[
+					{
+						icon:'../../static/test/icon31.png',
+						title:"宽带订单查询",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/x/kd_yj/order.php'
+					},
+					{
+						icon:'../../static/test/icon32.png',
+						title:"宽带自助排障",
+						badge:0,
+						type:'url',
+						target:'https://x.189.cn/tykf-services/sso?channel=NX_WEIXIN_Soo&reqMode=5&reqParam=hK8dQ%2F1J63ieVlPpE55UzGkn6hYdnMN25CW93bWD%2FTnwiQ2lOVtZ3E3higHv+%2BXd4tUIpuOnSY%2BVYTLziitWtYd2sArB68J422bltp46KFKLbr%2Fpx6l2JOKRI+a6OaIxCk'
+					},
+					{
+						icon:'../../static/test/icon33.png',
+						title:"宽带升级",
+						badge:0,
+						type:'url',
+						target:'http://hd.nxeb.cc/pages/market/html/modify.html?client=0'
+					},
+					{
+						icon:'../../static/test/icon34.png',
+						title:"宽带移机",
+						badge:0,
+						type:'url',
+						target:'https://yx.nx.189.cn/x/kd_yj/'
+					},
+					{
+						icon:'../../static/test/icon35.png',
+						title:"宽带超市",
+						badge:0,
+						type:'url',
+						target:'http://hd.nxeb.cc/pages/market/html/market.html?rand=1535419737668&client=0'
+					}
+				]
+			}
+		},
+		methods: {
+			subsectionChange(index) {
+				this.subsectionCurrent = index
+			},
+			tabChange(index){
+				this.tabCurrent=index
+			},
+			swiperChange(e) {
+			  this.subsectionCurrent = e.detail.current
+			},
+			animationfinish({detail: { current }}) {
+				this.swiperCurrent = current;
+				this.subsectionCurrent = current;
+			},
+			goDetail(item){
+				if (this.$isEmpty(item.type)) {
+					uni.showToast({
+						title:"即将推出",
+						icon:"none"
+					})
+					return
+				}
+				if (item.type=='applet') {
+					//小程序跳转
+					uni.navigateToMiniProgram({
+					  appId: item.target,
+					  path: 'pages/index/index'
+					})
+				}else{
+					//h5跳转
+					uni.navigateTo({
+						url:"../webview/webview?url="+item.target
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		height: 100%;
+		width: 100%;
+	}
+	.container {
+		  height: calc(100vh);
+		  background-color: #F6F6F6;
+		  padding: 90rpx 0rpx 0rpx;
+		 .tabs {
+			 height: 90rpx;
+		    position: fixed;
+		    top: 0rpx;
+			left: 0;
+			right: 0;
+			width: 100%;
+			z-index: 3;
+		  }
+	}
+	view{
+		box-sizing: border-box;
+	}
+	
+	.top1{
+		border-radius: 40rpx 40rpx 0 0;
+		position: relative;
+		top: -30rpx;
+		.card{
+			border-radius: 20rpx;
+		}
+	}
+	
+	.grid-icon{
+		image{
+			width: 56rpx;height: 56rpx;
+		}
+	}
+	
+	.scroll-view {
+		height: 150rpx;
+		white-space: nowrap;
+		width: 100%;
+		position: relative;
+		top: -30rpx;
+	}
+	.scroll-view-item {
+		color: #FFFFFF;
+		background-image: linear-gradient(to right, #2f7ff5, #2f7ff5);
+		display: inline-block;
+		text-align: left;
+		padding: 20rpx 40rpx;
+		margin:0 8rpx;
+		width:24%;
+		border-radius: 12rpx;
+	}
+	.scroll-view-item:first-child{
+		margin-left: 30rpx;
+	}
+	.scroll-view-item:last-child{
+		margin-right: 30rpx;
+	}
+	
+		.demo-warter {
+			height: 580rpx;
+			margin: 20rpx 8rpx;
+			background-color: #ffffff;
+			position: relative;
+			border-top-right-radius: 12rpx;
+			border-top-left-radius: 12rpx;
+			.time{
+				display: flex;flex-direction: column;
+				padding-left: 20rpx;
+				padding-bottom: 40rpx;
+			}
+		}
+		
+		.demo-image {
+			border-top-right-radius: 12rpx;
+			border-top-left-radius: 12rpx;
+			height: 360rpx;
+			padding-bottom: 10rpx;
+			width: 100%;
+		}
+</style>

+ 130 - 0
pages/demo/demo1.vue

@@ -0,0 +1,130 @@
+<template>
+	<view>
+		<view class="data" v-for="(item,index) in 6" :key="index" >
+			<view class="top">
+				<view class="left">
+					<u-icon name="hourglass-half-fill" :size="28" top="4" color="rgb(94,94,94)"></u-icon>
+					<view class="title text-cut-1">标题:<text >代拿一个滑板到二楼,代拿一个滑板到二楼</text></view>
+				</view>
+				<view class="right">
+					2020-10-27
+				</view>
+			</view>
+			<view class="item">
+				<view class="left">
+					<image src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg" mode="aspectFill"></image>
+					<view class="desc">
+						<text>宁夏冬美小区</text>
+						<text>发布人:19124812874</text>
+						<text>价格:4元</text>
+					</view>
+				</view>
+				<view @click="goDetail(item)" class="right">
+					<view  class="cu-btn bg-btn sm round">
+						查看详情
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		
+		<view class="cu-btn cuIcon round lg bg-red-btn" style="position: fixed;bottom: 20%;right: 4%;">
+			<text class="cuIcon-add" style="font-size: 50rpx;"></text>
+		</view>
+		<u-divider height="80"  bg-color="#f1f1f1">没有更多了</u-divider>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			goDetail(item){
+				console.log("111")
+				uni.navigateTo({
+					url:"./demo4"
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.data {
+		border-bottom: 1rpx solid #b6b6b6;
+		background-color: #FFFFFF;
+		width: 700rpx;
+		margin:10rpx auto;
+		border-radius: 10rpx;
+		box-sizing: border-box;
+		padding: 20rpx;
+		font-size: 28rpx;
+		.top {
+			display: flex;
+			justify-content: space-between;
+			padding-bottom: 20rpx;
+			border-bottom: 1rpx solid #e2e2e2;
+			.left {
+				flex: 3;
+				display: flex;
+				align-items: center;
+				.title {
+					margin: 0 10rpx;
+					font-size: 28rpx;
+					font-weight: bold;
+					text{
+						font-weight: 500;
+					}
+				}
+			}
+			.right{
+				flex: 1;
+				text-align: right;
+				margin-top: 6rpx;
+				font-size: 28rpx;
+				color: #a1a1a1;
+			}
+		}
+		.item {
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			margin: 30rpx 0 20rpx 0;
+			.left{
+				display: flex;
+				image{
+					margin: 10rpx 24rpx 10rpx 30rpx ;
+					width: 116rpx;
+					height: 116rpx;
+					border-radius: 10rpx;
+				}
+				.desc{
+					 display: flex;
+					 flex-direction: column;
+					 text{
+						 font-size: 26rpx;
+						 color: #a1a1a1;
+						 margin-bottom: 10rpx;
+					 }
+					 text:first-child{
+						 font-size: 30rpx;
+						 color: #333;
+						 font-weight: 800;
+					 }
+				}
+			}
+			.right {
+				display: flex;
+				flex-direction: column;
+				justify-content: center;
+			}
+			
+		}
+
+	}
+</style>

+ 65 - 0
pages/demo/demo2.vue

@@ -0,0 +1,65 @@
+<template>
+	<view style="min-height: 100vh;">
+		<view class="" >
+			<view class="flex  justify-center" style="position: relative;bottom: -80rpx;">
+				<view  class="cu-btn cuIcon  bg-gradual-blue" style="width: 160rpx;height: 160rpx;">
+					<view class="flex " style="flex-direction: column;">
+						<view class="cuIcon-unlock text-white" style="font-size: 60rpx;"></view>
+						<view class="text-sm margin-top-20">
+							点我开门
+						</view>
+					</view>
+				</view>
+			</view>
+			<view style="padding: 40rpx 10rpx 0rpx;" class="cu-list grid col-5 no-border" >
+				<view  class="cu-item"  v-for="(item,index) in gridList" :key="index">
+					<block >
+						<view class="grid-icon" >
+							<image style="width: 45rpx;height: 45rpx;"  :src="item.icon"/>
+						</view>
+						<view class="cu-tag bg-orange badge" v-if="item.badge>0">{{item.badge}}</view>
+						<text  style="color: #333333;font-size: 26rpx;">{{item.title}}</text>
+					</block>
+				</view>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+export default {
+	name: '',
+	data() {
+		return {
+			gridList:[
+				{
+					icon:'../../static/grid1/kaisuo.png',
+					title:"A区",
+					badge:0,
+					index:1
+				},
+				{
+					icon:'../../static/grid1/kaisuo.png',
+					title:"D区",
+					badge:0,
+					index:1
+				},
+			],
+		};
+	},
+	onLoad() {
+		
+	},
+	methods:{
+		
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+	.bg-gradual-blue {
+		background-image: linear-gradient(45deg, rgba(31, 117, 203, 0.8), rgba(34, 126, 217, 0.5));
+		color: #ffffff;
+	}
+</style>

+ 255 - 0
pages/demo/demo4.vue

@@ -0,0 +1,255 @@
+<template>
+	<view>
+		<view class="data">
+			<view class="address">
+				<view class="img">
+					<image src="/static/icon/address.png" mode="widthFix"></image>
+				</view>
+				<view class="content">
+					<text>宁夏冬美小区</text>
+					<text>银川市兴庆区解放东路477号</text>
+				</view>
+			</view>
+		</view>
+		
+		<view class="data" >
+			<view class="info">
+				<view class="top">
+					<view class="left">
+						<u-icon name="hourglass-half-fill" :size="30" top="2" color="rgb(94,94,94)"></u-icon>
+						<view class="title">订单号:<text>45217845689442452111</text></view>
+					</view>
+					<view class="copy">
+						<text>复制</text>
+					</view>
+				</view>
+				<view class="item">
+					<view class="content" >
+						<text >标题:</text>
+						<text >代拿滑板到二楼</text>
+					</view>
+					<view class="content" >
+						<text >发布时间:</text>
+						<text >2020-10-27 17:00:22</text>
+					</view>
+					<view class="content" >
+						<text >联系人:</text>
+						<text >黄明潘</text>
+					</view>
+					<view class="content" >
+						<text >联系微信:</text>
+						<text >hmp1049127947</text>
+					</view>
+					<view class="content" >
+						<view class="alignCenter">
+							<text >联系电话:</text>
+						</view>
+						<view class="phone">
+							<text class="alignCenter">19124812874</text>
+							<image src="http://139.9.185.150/upload/bf61acb4-22fc-4812-9f80-2f59a4cd949f-phone.png" mode="widthFix"></image>
+						</view>
+					</view>
+					<view class="content" >
+						<text >价格:</text>
+						<text class="price">¥4.00</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="data" >
+			<view class="account">
+				<view class="top">
+					<u-icon name="account" :size="30" top="2" color="rgb(94,94,94)"></u-icon>
+					<text>会员信息</text>
+				</view>
+				<view class="item">
+					<u-avatar :show-sex ="true" size="110" src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg"></u-avatar>
+					<view class="alignCenter name" >
+						plsteins
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="data">
+			<view class="cu-card dynamic no-card " style="margin: 10rpx 0;">
+				<view class="cu-item shadow">
+					<!-- 1张图片 -->
+					<view class=" grid flex-sub   col-1" style="height: 300rpx;"  v-if="dataDetail.picArray.length==1">
+						<view class="bg-img only-img" :style="{backgroundImage: 'url(' + dataDetail.picArray[0] + ')'}">
+						</view>
+					</view>
+					<!-- 多张图片 -->
+					<view class=" grid flex-sub  col-4 grid-square" v-else>
+						<view class="bg-img" :style="{backgroundImage: 'url(' + item1 + ')'}"
+						   v-for="(item1,index1) in dataDetail.picArray" :key="index1">
+						</view>
+					</view>
+				</view>
+				
+				<view class="need-desc">
+					<text>需求内容:</text>
+					<text class="content">
+						小熊USB小风扇迷你超静音手持电风扇便携式随身小型电动充电宿舍【全新包邮】原价40闲置30到手+微信请备注
+					</text>
+				</view>
+			</view>
+		</view>
+		
+		<u-divider height="80"  bg-color="#f1f1f1">没有更多了</u-divider>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				dataDetail:{
+					picArray:[
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg'
+					]
+				}
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.alignCenter{
+		display: flex;flex-direction: column;justify-content: center;
+	}
+	
+	.data {
+		background-color: #FFFFFF;
+		width: 700rpx;
+		margin:20rpx auto;
+		border-radius: 14rpx;
+		box-sizing: border-box;
+		padding: 16rpx;
+		font-size: 28rpx;
+		border-bottom: 1rpx solid #b6b6b6;
+	}
+	// 地址
+	.address{
+		margin: 20rpx auto;
+		display: flex;
+		.img{
+			margin: 20rpx;
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			align-items: center;
+			image{
+				width: 42rpx;
+			}
+		}
+		.content{
+			display: flex;
+			flex-direction: column;
+			margin: 10rpx 0;
+			text{
+				color: #a1a1a1;
+				font-size: 28rpx;
+			}
+			text:first-child{
+				margin-bottom: 20rpx;
+				color: #333;
+				font-weight: 800;
+				font-size: 30rpx;
+			}
+		}
+	}
+	
+	//基本信息
+	.info{
+		.top {
+			display: flex;
+			justify-content: space-between;
+			padding: 20rpx 0;
+			border-bottom: 1rpx solid #e2e2e2;
+			.left {
+				font-size: 28rpx;
+				display: flex;
+				justify-content: space-between;
+				.title {
+					margin: 0 10rpx;
+					font-weight: bold;
+					text{
+						font-weight: 500;
+					}
+				}
+			}
+			.copy{
+				padding-right: 20rpx;
+				color: $base-btn-color;
+				text-decoration: underline;
+			}
+		}
+		.item {
+			margin: 30rpx;
+			display: flex;
+			flex-direction: column;
+			.content{
+				padding: 16rpx 0;
+				display: flex;
+				justify-content: space-between;
+				.price{
+					color: #e54d42;
+					font-size: 32rpx;
+					font-weight: 700;
+				}
+				.phone{
+					display: flex;
+					text{
+						margin-right: 10rpx;
+					}
+					image{
+						width: 50rpx;
+					}
+				}
+			}
+		}
+	}
+	
+	//会员信息
+	.account{
+		.top{
+			padding: 20rpx 0;
+			display: flex;
+			border-bottom: 1rpx solid #e2e2e2;
+			font-weight: 800;
+			
+			text{
+				padding-left: 10rpx;
+			}
+		}
+		.item{
+			padding: 20rpx;
+			display: flex;
+			
+			.name{
+				padding-left: 40rpx;
+				font-size: 32rpx;
+			}
+		}
+	}
+	
+	.need-desc{
+		padding-top: 20rpx;
+		font-weight: 600;
+		line-height: 48rpx;
+		.content{
+			font-weight: 500;
+		}
+	}
+	
+	
+</style>

+ 24 - 0
pages/demo/demo5.vue

@@ -0,0 +1,24 @@
+<template>
+	
+</template>
+
+<script>
+export default {
+	name: '',
+	data() {
+		return {
+			
+		};
+	},
+	onLoad() {
+		
+	},
+	methods:{
+		
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+	
+</style>

+ 129 - 0
pages/demo/demo6.vue

@@ -0,0 +1,129 @@
+<template>
+	<view style="background-color: #FFFFFF;min-height: 100vh;">
+		<!-- solt begin -->
+		<view class="flex  flex-direction  align-center " style="padding-top: 160rpx;">
+			<u-avatar  size="130" src="http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg"></u-avatar>
+			<text  style="margin:30rpx 0 100rpx 0rpx;color: #333333;font-size: 26rpx;font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;">Hi~登陆玩转社区吧</text>
+			<button class="cu-btn round wx-btn " open-type="getPhoneNumber" @getphonenumber="tapGetPhoneNumber">
+				<view class="text-center"  style="position: relative;left: -100rpx;">
+					<text class="cuIcon-weixin" style="font-size: 40rpx;color: #216a21;"></text>
+				</view>
+				<view style="position: relative;left: -16rpx;">
+					<text class="text-center" style="font-size: 28rpx;">微信立即登陆</text>
+				</view>
+			</button>
+			<view @click="hide" class="cu-btn round line-gray " style="font-size: 26rpx;width: 200rpx;margin-top: 80rpx;">
+				<text style="color: #333333;">暂不登陆</text>
+			</view>
+		</view>
+		<!-- solt end -->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				respWx:{},
+				respLogin:{},
+				timer:null,
+				inviteCode:null,
+			}
+		},
+		beforeDestroy() {
+		  if(this.timer){
+		    clearTimeout(this.timer)
+		    this.timer = null
+		    console.log('clearTimeout')
+		  }
+		},
+		onReady() {
+			this.show()
+		},
+		methods:{
+			hide () {
+			  if(this.timer){
+			    clearTimeout(this.timer)
+			    this.timer = null
+			  }
+			},  
+			show(){
+				  let that=this
+				  this.inviteCode = this.$auth.getInviteCode() 
+				  this.$mpi.wxLogin().then(res => {
+					this.respWx = res
+					console.log("res",res);
+				  })
+				  this.setTimer()
+			},
+			async setTimer(){
+				this.respWx = await this.$mpi.wxLogin()
+				this.timer = setTimeout(()=>{
+					this.setTimer()
+				},240000) // 每隔4分钟重新请求 jscode
+			},
+			async tapGetPhoneNumber (e) {
+			  if(e.detail.errMsg != 'getPhoneNumber:ok') {
+			    return
+			  }
+			  this.login(e.detail)
+			},
+			async login(detail){
+			  console.log("2:login",detail);
+			  try{
+			    this.$dialog.showLoading()
+			    if(!this.respLogin.sessionKey){
+			      this.respLogin = await this.$api.loginByCode({
+			        _isReject:true,
+			        code:this.respWx.code
+			      })
+			    }
+				console.log(this.respLogin);
+			    let resp = await this.$api.loginByWxapp({
+			      _isReject:true,
+			      openId: this.respLogin.openId,
+			      sessionKey: this.respLogin.sessionKey,
+			      encryptedData: detail.encryptedData,
+			      iv: detail.iv,
+				  inviteCode: this.inviteCode
+			    })
+			    console.log(56,resp)
+			    resp.openId = this.respLogin.openId
+			    resp.sessionKey = this.respLogin.sessionKey
+			    let userType = this.$global.userType.member
+			    this.$auth.login(userType, resp.sessionId, resp.userId, resp)
+			    this.hide()
+			    this.$util.refreshPage(['/pagesM/pages/category','/pagesM/pages/shop_car'])
+				// this.$auth.setInviteCode(null);
+				this.$auth.removeInviteCode();
+				let a = this.$auth.getInviteCode();
+				if(this.inviteCode){
+					this.$emit('getDistributorCoupon')
+				}else{
+					this.$emit('signIn', resp)
+				}
+			  }catch(err){
+			    // console.log(72,err)
+			    this.$dialog.alert({
+			      content: err.errmsg || '服务繁忙~'
+			    })
+			  }finally{
+			    this.$dialog.hideLoading()
+			    if(this.timer){
+			      clearTimeout(this.timer)
+			      this.setTimer()
+			    }
+			  }
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+.wx-btn{
+	background-color: #2ba246;
+	color: #FFFFFF;
+	width: 600rpx;
+	padding: 40rpx 0rpx;
+}
+</style>

+ 46 - 0
pages/demo/myfamily.vue

@@ -0,0 +1,46 @@
+<template>
+	<view class="flex bg-white flex-direction justify-center align-center">
+		<u-avatar  size="130" src="http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg"></u-avatar>
+		<text  style="margin:30rpx 0 100rpx 0rpx;color: #333333;font-size: 26rpx;font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;">Hi~登陆玩转社区吧</text>
+		<view class="cu-btn round wx-btn ">
+			<view class="text-center"  style="position: relative;left: -100rpx;">
+				<text class="cuIcon-weixin icon"></text>
+			</view>
+			<view style="position: relative;left: -16rpx;">
+				<text class="text-center text-lg">微信快速登陆</text>
+			</view>
+		</view>
+		<view class="cu-btn round line-gray " style="width: 200rpx;margin-top: 80rpx;">
+			返回
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: '',
+	data() {
+		return {
+			
+		};
+	},
+	onLoad() {
+		
+	},
+	methods:{
+		
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+	.wx-btn{
+		background-color: #2ba246;
+		color: #FFFFFF;
+		padding: 40rpx 180rpx;
+		.icon{
+			color: #216a21;
+			font-size: 42rpx;
+		}
+	}
+</style>

+ 257 - 0
pages/device/device.vue

@@ -0,0 +1,257 @@
+<template>
+	<view class="container">
+		<view class="tabs">
+			<u-subsection height="90" active-color="#2f7ff5"  :list="subsectionList" :animation="false" :current="subsectionCurrent" @change="subsectionChange"></u-subsection>
+			<view class="" style="height: 20rpx;"></view>
+		</view>
+		<view style="height: 100%;">
+			<swiper style="height: 100%;" :current="subsectionCurrent"  @change="swiperChange"
+				@animationfinish="animationfinish">
+				<swiper-item >
+					<scroll-view scroll-y style="height: 100%;">
+						<view class="margin-20  bg-white" style="height: 390rpx;border-radius: 12rpx;padding: 20rpx;">
+							<view @click="addDevice" style="padding:6rpx 10rpx 10rpx;box-sizing: border-box;" class="flex justify-between">
+								<text class="text-bold text-lg">我的设备</text>
+								<view class="cu-btn line-red sm padding-right-40">
+									<text class="cuIcon-add padding-right-10"></text>
+									添加设备
+								</view>
+							</view>
+							<view class="text-left flex justify-around content">
+								<view class="" @click="add">
+									<image src="/static/yangan.jpg"  ></image>
+									<text>智能烟感</text>
+								</view>
+								<view class="" @click="add">
+									<image src="http://139.9.103.171:1888/miniofile/app/baojing.jpg"  ></image>
+									<text>一键报警</text>
+								</view>
+								<view class="" @click="add">
+									<image src="http://139.9.103.171:1888/miniofile/app/ranqi.jpg"  ></image>
+									<text>燃气监控</text>
+								</view>
+							</view>
+						</view>
+					</scroll-view>
+				</swiper-item>
+				<swiper-item >
+					<scroll-view scroll-y style="height: 100%;">
+					<view class="goods-data margin-top-20">
+						<view class="goods-list">
+							<view class="list-li" style="margin-bottom: 4rpx;" v-for="(item,index) in goodsList"  :key="index">
+								<view class="thumb" >
+									<image   :src="item.image" mode="scaleToFill"></image>
+								</view>
+								<view class="item">
+									<view class="name">
+										<text class="text-cut-2">{{item.name}}</text>
+									</view>
+									<view class="intro">
+										<view class="left">
+											<view class="cu-tag sm bg-red radius" v-if="index==0"  >
+												<text >热卖中</text>
+											</view>
+											<view class="study text-red">
+												¥ {{item.price}}元
+											</view>
+										</view>
+										<view @click="add" class="right line-blue cu-btn sm round" style="margin-right: 20rpx;">
+											<text class="cuIcon-add"></text>
+											立即添加
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+						<view style="height: 80rpx;">
+							<u-divider bgColor="#f6f6f6" height="60">没有更多了</u-divider>
+						</view>
+					</view>
+					</scroll-view>
+				</swiper-item>
+			</swiper>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		components:{
+		},
+		data() {
+			return {
+				goodsList:[
+					{
+						image:'/static/yangan.jpg',
+						name:'NB-IOT烟雾报警器家用WIFI无线消防认证感应火灾智能烟感探测器',
+						price:'99'
+					},
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/yanwubaojin.jpg',
+						name:'海康威视独立式烟雾报警器家用厨房商用感应消防专用3c认证探测器',
+						price:'78'
+					},
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/ad3d6aa4bbd5b98bb27395f7220b7de.jpg',
+						name:'涂鸦云版智能WiFi 燃气传感器手机APP远程监控语音报警器家用',
+						price:'86'
+					},
+					{
+						image:'http://139.9.103.171:1888/miniofile/app/f890a65d984b9bb2d84617c25781d32.jpg',
+						name:'老人报警器一键式呼救机远程紧急求救按钮家用无线病人床头呼叫器',
+						price:'128'
+					},
+				],
+				
+				subsectionCurrent:0,
+				swiperCurrent:0,
+				subsectionList:[
+					{
+						name: '设备'
+					},
+					{
+						name: '应用'
+					}
+				]
+				
+			}
+		},
+		methods: {
+			add(){
+				uni.showToast({
+					title:"待开发",
+					icon:"none"
+				})
+			},
+			addDevice(){
+				this.subsectionCurrent=1
+				this.swiperCurrent=1
+			},
+			subsectionChange(index){
+				this.subsectionCurrent=index
+			},
+			swiperChange(e) {
+			  uni.pageScrollTo({
+			      scrollTop: 0,
+			      duration: 0
+			  });
+			  this.subsectionCurrent = e.detail.current
+			},
+			animationfinish({detail: { current }}) {
+				this.swiperCurrent = current;
+				this.subsectionCurrent = current;
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.container {
+		  height: calc(100vh);
+		  background-color: #F6F6F6;
+		  padding: 90rpx 0rpx 0rpx;
+		 .tabs {
+			 height: 90rpx;
+		    position: fixed;
+		    top: 0rpx;
+			left: 0;
+			right: 0;
+			width: 100%;
+			z-index: 3;
+		  }
+	}
+	view{
+		box-sizing: border-box;
+	}
+	.scroll-view {
+		height: 150rpx;
+		white-space: nowrap;
+		width: 100%;
+		position: relative;
+		top: -30rpx;
+	}
+	.scroll-view-item {
+		color: #FFFFFF;
+		background-image: linear-gradient(to right, #2f7ff5, #2f7ff5);
+		display: inline-block;
+		text-align: left;
+		padding: 20rpx 40rpx;
+		margin:0 8rpx;
+		width:24%;
+		border-radius: 12rpx;
+	}
+	.scroll-view-item:first-child{
+		margin-left: 30rpx;
+	}
+	.scroll-view-item:last-child{
+		margin-right: 30rpx;
+	}
+	.content{
+		image{
+			height: 210rpx;
+			width: 210rpx;
+			border-radius: 12rpx;
+			margin: 20rpx 0;
+		}
+	}
+	
+	.goods-data {
+		width: 100%;
+		.goods-list {
+			border-radius: 6rpx;
+			overflow: hidden;
+			// 列表
+			.list-li {
+				display: flex;
+				align-items: center;
+				width: 100%;
+				height: 230rpx;
+				background-color: #ffffff;
+				.thumb {
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					width: 30%;
+					height: 100%;
+					image {
+						width: 178rpx;
+						height: 200rpx;
+						border-radius: 6rpx;
+					}
+				}
+				.item {
+					display: flex;
+					flex-direction: column;
+					justify-content: center;
+					width: 70%;
+					height: 100%;
+					border-bottom: 2rpx solid #f6f6f6;
+					.name {
+						padding:0 20rpx 20rpx 20rpx;
+						text {
+							width: 100%;
+							color: #212121;
+							font-size: 28rpx;
+						}
+					}
+					.intro{
+						display: flex;
+						justify-content: space-between;
+						margin-top: 30rpx;
+						margin-left: 8rpx;
+						.left{
+							font-size: 26rpx;
+							.study{
+								padding-top: 10rpx;
+							}
+						}
+						.right{
+							padding-right: 30rpx;
+						}
+						
+					}
+				}
+			}
+		}
+	}
+</style>

+ 44 - 0
pages/empty/empty.vue

@@ -0,0 +1,44 @@
+<template>
+	<view style="background-color: #fff;min-height: 100vh;">
+		<view class="default" >
+		  <image src="/static/empty.png" mode="heightFix"></image>
+		  <view style="font-size: 26rpx;">
+		    <text style="color: #909090;">{{msg}}</text>
+		  </view>
+		  <navigator :url="url" class="cu-btn round bg-btn margin-top-50" style="padding: 35rpx 65rpx;margin-left: 8rpx;">
+				{{btnName}}
+		  </navigator>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				msg:"您还未完成注册认证",
+				btnName:"去注册认证",
+				url:"../register/register"
+			}
+		},
+		onLoad(options) {
+			if(options.type=='2'){
+				//导航栏标题
+				uni.setNavigationBarTitle({
+					title:"房屋认证"
+				})
+				//去认证
+				this.msg="您还未完成房屋认证"
+				this.btnName="去认证"
+				this.url="../auth/auth"
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}
.default image {
  height: 280rpx;
  display: inline-block;
}
+</style>

+ 30 - 0
pages/empty/goauth.vue

@@ -0,0 +1,30 @@
+<template>
+	<view style="background-color: #fff;min-height: 100vh;">
+		<view class="default" >
+		   <image src="/static/empty.png" mode="heightFix"></image>
+		  <view style="margin-top: 20rpx;">
+		    <text>您的信息正在审核中...</text>
+		  </view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		onLoad() {
+			
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 280rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+</style>

+ 22 - 0
pages/guest/guest.vue

@@ -0,0 +1,22 @@
+<template>
+	<view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 98 - 0
pages/guest/open_door.vue

@@ -0,0 +1,98 @@
+<template>
+	<view class="page" style="position: relative;">
+		<loading  isFullScreen color="#59a5f0" :active="isloading" text="开门中..."></loading>
+		<radio-group class="block" @change="RadioChange">
+			<view class="cu-list menu text-left">
+				<view class="cu-item" v-for="(item,index) in device_list" :key="index">
+					<label class="flex justify-between align-center flex-sub">
+						<view class="flex-sub margin-left-sm">{{item.name}}</view>
+						<radio class="roundn red" :class="doorValue==item.id?'checked':''" :checked="doorValue==item.id?true:false"
+						 :value="item.id"></radio>
+					</label>
+				</view>
+			</view>
+		</radio-group>
+		<view class="bottom">
+			<button @click="open" class="cu-btn cuIcon  round  bg-white shadow1" style="height: 150rpx;width: 150rpx;margin-bottom: 160rpx;border: 1rpx solid #c6c6c6;">
+				<text :class="isopen?'cuIcon-unlock':'cuIcon-lock'" :style="{'color':(isopen?'#55aa7f':'#989898')}" style="font-size: 60rpx;color: #989898;"></text>
+			</button>
+		</view>
+	</view>
+</template>
+
+<script>
+var app=getApp()
+var that;
+import loading from "@/comps/loading/loading.vue"
+export default {
+	components:{
+		loading
+	},
+	data() {
+		return {
+			isopen:false,
+			isloading:false,
+			doorValue:'5678',
+			device_list:[
+				{
+					id:'1234',
+					name:'宁夏冬美小区'
+				},
+				{
+					id:'5678',
+					name:'宁夏冬美小区2'
+				},
+			]
+		};
+	},
+	onLoad() {
+		that=this
+	},
+	methods:{
+		RadioChange(e) {
+			this.doorValue = e.detail.value
+		},
+		open(){
+			//进度条加载
+			this.isloading=true
+			setTimeout(()=>{
+				that.openDoor()
+			},2300)
+		},
+		/**
+		 * 立即开门
+		 */
+		openDoor() {
+			 let device_id=this.doorValue
+			 let params = {};
+			 params['member_id'] = app.globalData.member.id;
+			 params['device_id'] = device_id;
+			 let operation = 'member/openDoor';
+			 app.globalData.postRequest(params, operation, function (res) {
+				 that.isloading=false
+				 that.isopen=true
+			   app.globalData.oneFailHint(res.data.result_msg,function(){
+				   that.isopen=false
+			   });
+			 });
+		},
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+	.bottom{
+		position: fixed;
+		bottom: 0;
+		left: 40%;
+	}
+	.shadow1{
+		box-shadow: 0 0  20rpx #cbcbcb
+		
+	}
+	button:active{
+		 box-shadow: 0 0  10rpx rgba(203, 203, 203, 0.2);
+		 position: relative;
+		 top: 2px;
+	}
+</style>

+ 105 - 0
pages/guide/guide.vue

@@ -0,0 +1,105 @@
+<template>
+	<view class="content">
+		<view v-if="guideShow">
+			<u-image :src="img" :height="guideHeight"></u-image>
+			<u-button :custom-style="customStyle" shape="circle" class="jump-over" @click="handleGo" size="mini">跳过 {{countdown}}</u-button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				customStyle:{
+					color:"#ffffff",
+					backgroundColor: 'rgba(0, 0, 0,0.4)'
+				},
+				guideShow:true,
+				guideHeight:0,
+				img:'http://139.9.103.171:1888/miniofile/app/guide.png',
+				countdown:3,
+				timeout:null,
+				timer:null,
+			}
+		},
+		onLoad() {
+			this.getImg()
+			this.guideHeight = uni.getSystemInfoSync().windowHeight * ( 750 / uni.getSystemInfoSync().windowWidth);
+			this.init();
+		},
+		methods: {
+			getImg(){
+				if(!this.$isEmpty(uni.getStorageSync("guideImg"))){
+					this.img=uni.getStorageSync("guideImg")
+				}
+			},
+			/**
+			 * 下载图片
+			 */
+			downloadFile(){
+				let that=this
+				uni.downloadFile({
+				    url: 'http://139.9.103.171:1888/img/image/guide.png', //仅为示例,并非真实的资源
+				    success: (res) => {
+						uni.saveFile({
+							 tempFilePath: res.tempFilePath,
+							 success: function (res) {
+							   var savedFilePath = res.savedFilePath;
+							   that.img=savedFilePath
+							   uni.setStorage({
+							   	key:"guideImg",
+								data:savedFilePath
+							   })
+							 }
+						});
+				    }
+				});
+			},
+			init() {
+				this.timeout = setTimeout(function () {
+					this.guideShow = false;
+					uni.reLaunch({
+						url:"/pages/index/index?isFlush=true"
+					})
+				},3500)
+				this.timer = setInterval(() =>{
+					this.countdown--;
+					if(this.countdown === 0) {
+						clearInterval(this.timer);
+					}
+				}, 1000);
+			},
+			handleGo(){
+				clearInterval(this.timer);
+				clearTimeout(this.timeout);
+				uni.showLoading({
+				    title: '加载中'
+				});
+				setTimeout(function () {
+				  uni.hideLoading();
+					this.guideShow=false
+					uni.reLaunch({
+						url:"/pages/index/index?isFlush=true"
+					})
+				}, 500);
+			},
+		}
+	}
+</script>
+
+<style>
+	 page,
+	 .content{
+	 	width: 100%;
+		height: 100%;
+	 	background-size: 100% auto ;
+	 	padding: 0;
+	 }
+	 .jump-over{
+	 	position: absolute;
+		right: 30rpx;
+		bottom: 200rpx;
+		z-index: 999;
+	 }
+</style>

+ 126 - 0
pages/guide/guide_old.vue

@@ -0,0 +1,126 @@
+<template>
+<view class="swiper-container">
+  <swiper class="guide_swiper" :autoplay="autoplay" :interval="interval" :duration="duration" @change="swiperChange">
+    <block v-for="(item, index) in imgUrls" :key="index">
+      <swiper-item>
+        <image :src="item" mode="aspectFit" class="slide-image"></image>
+        <button class="button-img" @tap="goto_next" v-if="index == imgUrls.length - 1">立即体验</button>
+      </swiper-item>
+    </block>
+  </swiper>
+
+  <view class="dots">
+    <block v-for="(item, index) in imgUrls" :key="index">
+        <view :class="'dot' + (index == swiperCurrent ? ' active' : '')"></view>
+    </block>
+  </view>
+
+</view>
+</template>
+
+<script>
+var app=getApp()
+export default {
+  data() {
+    return {
+      imgUrls: ["http://139.9.103.171:1888/img/image/guide_rl.png", "http://139.9.103.171:1888/img/image/guide_sq.png", "http://139.9.103.171:1888/img/image/guide_jr.png", "http://139.9.103.171:1888/img/image/guide_km.png"],
+      //广告轮播图
+      autoplay: false,
+      interval: 5000,
+      duration: 300,
+      swiperCurrent: 0
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onReady: function (options) {
+	  console.log("onready");
+    //调用API从本地缓存中获取数据
+    var isFir = uni.getStorageSync('isFirst');
+
+    if (isFir == 'true') {
+		uni.reLaunch({
+			url:"/pages/index/index?isFlush=true"
+		})
+    }
+  },
+ onLoad() {
+ },
+  methods: {
+    goto_next: function (val) {
+      uni.setStorageSync("isFirst", 'true');
+      uni.reLaunch({
+      	url:"/pages/index/index?isFlush=true"
+      })
+    },
+    swiperChange: function (e) {
+        this.swiperCurrent=e.detail.current
+    }
+  }
+};
+</script>
+<style>
+page {
+  background-color: #fff;
+}
+.swiper-container {
+  position: relative;
+}
+.guide_swiper {
+  width: 100%;
+  height: 100vh;
+}
+
+.slide-image {
+  margin: 0 auto;
+  height: 100vh;
+  width: 100%;
+}
+
+.button-img 
+
+ {
+  position: fixed;
+  z-index: 1000;
+  bottom: 220rpx;
+  width: 210rpx;
+  height: 60rpx;
+  line-height: 60rpx;
+  left: 270rpx;
+  font-size: 30rpx;
+  text-align: center;
+  box-sizing: border-box;
+  background-color: #33b6ea;
+  opacity: 0.7;
+  color: #fff;
+  border-radius: 30rpx;
+}
+.dots{
+  position: absolute;
+  left: 50%;
+  transform: translate(-50%,0);
+  right: 0;
+  bottom: 150rpx;
+  display: flex;
+  justify-content: center;
+}
+
+.dot{
+  margin: 0 8rpx;
+  width: 14rpx;
+  height: 14rpx;
+  background: #33b6ea;
+  border-radius: 8rpx;
+  transition: all .6s;
+}
+.dot.active{
+  width: 24rpx;
+  background: #f80;
+}
+
+</style>

+ 872 - 0
pages/index/index.vue

@@ -0,0 +1,872 @@
+<template>
+	<view class="content">
+		<view class="">
+<!-- 			<view  class="cu-modal" :class="modalShow?'show':''"  @tap="modalShow=false">
+				<view  class="cu-dialog" @tap.stop="">
+					<view class="bg-white" style="height: 20rpx;"></view>
+					<radio-group  class="block" @change="RadioChange">
+						<view class="cu-list menu text-left">
+							<view class="cu-item" v-for="(item,index) in device_list" :key="index">
+								<label class="flex justify-between align-center flex-sub">
+									<view class="flex-sub margin-left-sm">{{item.name}}</view>
+									<radio class="roundn blue" :class="doorValue==item.id?'checked':''" :checked="doorValue==item.id?true:false"
+									 :value="item.id"></radio>
+								</label>
+							</view>
+						</view>
+					</radio-group>
+					<view class="bg-white" style="height: 120rpx;"></view>
+				</view>
+			</view> -->
+			<loading  isFullScreen color="#2f7ff5" :active="isloading" text="开门中..."></loading>
+			<u-navbar :is-back="false" title=" ">
+				<view class="slot-wrap">
+					<picker @change="typeChange" :value="plotIndex" :range="plotArray">
+					  <view class="padding-left-20 ">
+					  	<u-icon name="map" size="34"></u-icon>
+					  	<text class="padding-left-sm " style="font-size: 34rpx;">{{plot?plot:'暂无小区信息'}}</text>
+					  </view>
+					</picker>
+				</view>
+			</u-navbar>
+			<!-- 头图 -->
+			<swiper class="screen-swiper square-dot "  :indicator-dots="true" :circular="true"
+			 :autoplay="true" interval="5000" duration="500">
+				<swiper-item v-for="(item,index) in adList" :key="index">
+					<image  v-if="item.videoType==0" :src="item.videoUri" mode="aspectFill" ></image>
+					<video  v-if="item.videoType==1" :src="item.videoUri" autoplay loop muted :show-play-btn="false" :controls="false" objectFit="cover"></video>
+				</swiper-item>
+			</swiper>
+			<view class="">
+				<view class="bg-white" style="height: 10rpx;"></view>
+				<hotConsult  @onTap="jump('../notice/notice')" @detailTap="jump('../notice/detail')" :swiperTexts="swiperTexts"></hotConsult>
+			</view>
+			
+			<view style="background-color: #FFFFFF;">
+				<view  style="padding: 30rpx 30rpx 0 30rpx;">
+					<text class="text-bold text-lg">智慧社区</text>
+				</view>
+				<view style="padding: 40rpx 10rpx 0rpx;" class="cu-list grid col-5 no-border" >
+					<view class="cu-item" :class="item.index==5?'img1-lg':''" @click="top(item.index)" v-for="(item,index) in gridList" :key="index">
+						<block v-if="item.index==5">
+							<view class="grid-icon" >
+								<image  style="width: 100rpx;height: 100rpx;" :src="modalShow?'../../static/grid1/kaisuo1.png':'../../static/grid1/kaisuo0.png'"/>
+							</view>
+							<text  style="color: #333333;font-size: 30rpx;font-weight: 800;" >{{item.title}}</text>
+						</block>
+						<block v-else>
+							<view class="grid-icon" >
+								<image  style="width: 48rpx;height: 48rpx;"  :src="item.icon"/>
+							</view>
+							<text  style="color: #333333;font-size: 26rpx;" >{{item.title}}</text>
+						</block>
+						<view class="cu-tag bg-orange badge" v-if="item.badge>0">{{item.badge}}</view>
+					</view>
+				</view>
+				<view v-if="modalShow==true" class="flex justify-around margin-top-30" >
+					<view @click="open" v-for="(item,index) in device_list" :key="index" style="flex-direction: column;" class="flex justify-center align-center">
+						<image style="width: 60rpx;height: 60rpx;" src="../../static/grid1/kaimen.png"/>
+						<view class="text-center padding-top-20" style="font-size: 24rpx;">
+							{{item.name}}
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="nav-list bg-white padding-top-20" >
+				<view hover-class="none"
+					@click="top(item.index)"
+					class="nav-li light" navigateTo :style="{backgroundColor:item.color}" 
+					v-for="(item,index) in elements" :key="index">
+					<view class="nav-title" style="color: #000000;font-size: 28rpx;">{{item.title}}</view>
+					<view class="" style="padding-top: 10rpx;font-size: 24rpx;color: #acacac;">{{item.name}}</view>
+					<image :src="item.icon" mode=""></image>
+				</view>
+			</view>
+		</view>
+		<view class="bg-white">
+			<image src="/static/banner.png" style="width: 100%;" mode="widthFix"></image>
+		</view>
+		<view >
+			<view class="tj-title">
+				<view class="">
+					<text class="text-lg text-bold">为您推荐</text>
+					<text class="sub-title">有料</text>
+					<text class="sub-title">好物</text>
+					<text class="sub-title">有优惠</text>
+				</view>
+				<view class="sub-title" style="color: #969696;padding-top: 8rpx;font-size: 24rpx;" @click="jump('/pages/life/life','type')">
+					<text >查看更多></text>
+				</view>
+			</view>
+			<view>
+				<goods :goodsList="goodsList"></goods>
+			</view>
+		</view>
+		<view style="height: 80rpx;">
+			<u-divider bgColor="#f1f1f1;"  height="80">到底了</u-divider>
+		</view>
+	
+	</view>
+</template>
+
+<script>
+	import loading from "@/comps/loading/loading.vue"
+	import hotConsult from "@/comps/hot-consult/hot-consult.vue"
+	import goods from "@/comps/goods/goods.vue"
+	var app = getApp();
+	let that;
+	export default {
+		components:{
+			goods,hotConsult,loading
+		},
+		data() {
+			return {
+				isloading:false,
+				modalShow:false,
+				//开门设备列表
+				doorValue:'',
+				device_list: [],
+				
+				background: {
+					backgroundColor: '#e54d42',
+				},
+				swiperTexts:[
+					{
+						title:'疫情期间,出入小区请佩戴好口罩,配合门卫大叔做好测温登记工作。谢谢大家的配合。'
+					},
+					{
+						title:'停水停电通知。市政通水设施突发性故障抢修,本小区供水压力暂受影响,敬请做好储水准备,预约影响时间2020年11月28号22时至11月29号16时,由此给您带来不便,敬请谅解。'
+					},
+					{
+						title:'2020年10月1日-2020年10月8日,中秋 国庆节放假,假期间需注意,祝国庆节玩的开心。'
+					},
+					{
+						title:'疫情期间,出入小区请佩戴好口罩,配合门卫大叔做好测温登记工作。谢谢大家的配合。'
+					}
+				],
+				
+				userInfo:{},
+				jsCode:'',
+				openid:'',
+				sessionKey:'',
+				isFirst:false,
+				
+				goodsList:[],
+				isIPX:false,
+				//广告轮播图
+				swiperIndex: 0,
+				plot: null,
+				plotArray: [],
+				//小区名字
+				plotIndex: 0,
+				residentialIdList: [] ,//小区id
+				adList: [
+					{
+					  'videoType': 0,
+					  'videoUri': "http://139.9.103.171:1888/miniofile/app/abcd.png"
+					},
+				],
+				elements: [{
+					title: '防疫登记',
+					name: '在线防疫登记',
+					color: '#e3f5ff',
+					icon: '../../static/home/fanyi1.png',
+					index:6
+				}, {
+					title: '物业缴费',
+					name: '在线物业缴费',
+					color: '#e9f9f3',
+					icon: '../../static/home/jiaofei.png',
+					index:7
+				},
+				{
+					title: '物业报修',
+					name: '在线物业报修',
+					color: '#ffefef',
+					icon: '../../static/home/baoxiu1.png',
+					index:8
+				}, {
+					title: '更多服务',
+					name: '更多智慧服务',
+					color: '#eeeeee',
+					icon: '../../static/home/more.png',
+					index:99
+				}],
+				gridList2:[
+					{
+						icon:'../../static/grid1/kaisuo.png',
+						title:"A区",
+						badge:0,
+						index:1
+					},
+					{
+						icon:'../../static/grid1/kaisuo.png',
+						title:"D区",
+						badge:0,
+						index:1
+					},
+				],
+				gridList:[
+					{
+						icon:'../../static/grid1/fangwu.png',
+						title:"我的房屋",
+						badge:0,
+						index:1
+					},
+					{
+						icon:'../../static/grid1/renyuan.png',
+						title:"家庭成员",
+						badge:0,
+						index:2
+					},
+					{
+						icon:'../../static/grid1/kaisuo1.png',
+						title:"开门",
+						badge:0,
+						index:5
+					},
+					{
+						icon:'../../static/grid1/cheliang.png',
+						title:"我的车辆",
+						badge:0,
+						index:3
+					},
+					{
+						icon:'../../static/grid1/fangke1.png',
+						title:"访客授权",
+						badge:0,
+						index:4
+					},
+					
+				]
+			}
+		},
+		onShow() {
+			//处理进入小程序的不同场景
+			this.execParam();
+			this.loadData()
+			//每次打开此页面都把商品数组打乱
+			this.$u.randomArray(this.goodsList)
+			if(this.isFirst){
+				this.isFirst=false
+			}else{
+				this.getRoomByMemberId()
+			}
+		},
+		onLoad(options) {
+			that=this
+			//处理进入小程序的场景
+			this.handelShare(options)
+			this.isFirst=true
+			//拉取后台用户信息
+			this.getOpenId();
+			this.isIPX=uni.getStorageSync('isIPX')
+			//获取轮播列表
+			this.getAdList();
+			//获取推荐商品列表
+			this.fetchGoodsList()
+		},
+		methods: {
+			open(){
+				//进度条加载
+				this.isloading=true
+				let that=this
+				setTimeout(()=>{
+					that.openDoor()
+				},2300)
+			},
+			//立即开门
+			openDoor: function (event) {
+				 // let device_id = event.currentTarget.dataset.device_id;
+				 let device_id=this.doorValue
+				 let that = this;
+				 let params = {};
+				 params['member_id'] = app.globalData.member.id;
+				 params['device_id'] = device_id;
+				 let operation = 'member/openDoor';
+				 app.globalData.postRequest(params, operation, function (res) {
+					 that.isloading=false
+				   app.globalData.oneFailHint(res.data.result_msg,function(){
+					   that.modalShow=false
+				   });
+				 });
+			},
+			getAuthDevice: function () {
+			  let that = this;
+			  let params = {};
+			  params['member_id'] = app.globalData.member.id;
+			  let operation = 'member/getAuthDeviceByMemberId';
+			  app.globalData.postRequest(params, operation, function (res) {
+			    console.info("查询结果:" + res.data.result_msg); //获取成功
+			
+			    if (res.data.result_code == 1) {
+			      let list = [];
+			      if (uni.getStorageSync('plotName')) {
+			        res.data.list.map(item => {
+			          if (item.name.indexOf(uni.getStorageSync('plotName')) >= 0) {
+			            list.push(item);
+			          }
+			        });
+			      } else {
+					 console.log(res.data.list)
+			        list = res.data.list;
+			      }
+				 console.log(list)
+				 that.setData({
+					device_list: list
+				  });
+				 console.log(that.device_list)
+				 if(!that.$isEmpty(that.device_list)){
+					 that.doorValue=that.device_list[0].id
+				 }
+			      app.globalData.device_list = list;
+			    }
+			  });
+			},
+			async loadData(options){
+				 //进入小程序时进行游客登陆,
+				 //以免直接进入商品详情时会提示用户未授权
+				await this.$nextTick(function(){
+					 this.touristLogin()
+				})
+			},
+			getParam(e){
+				// 用来保存所有的属性名称和值
+				let param = "";
+				// 开始遍历
+				for(let p in e){
+					// 方法
+					if(typeof(e[p])!="function" && p != 'type'){
+						// p 为属性名称,e[p]为对应属性的值
+						param += (param.length > 1 ? '&' : '') + p + "=" + e[p];
+					}
+				}
+				// 最后显示所有的属性
+				return param;
+			},
+			execParam(){
+				let _this = this;
+				if(this.e != null){
+					setTimeout(function(){
+						if(_this.e == null) return;
+						if(_this.e.type == "share"){
+							let path = _this.e.path == null || _this.e.path.length <= 0 ? 'pagesM/pages/goods_des' : '/' + _this.e.path;
+							let param = _this.getParam(_this.e);
+							let url = `${path}?${param}`;
+							console.error("url = " + url);
+							_this.e = null;
+							uni.navigateTo({url: url});
+						}
+					}, 1000);
+				}
+			},
+			handelShare(e){
+				this.e = e;
+				console.log(12,e)
+				//二维码扫描链接 start
+				if(e != null && e.q != null){
+					let url = decodeURIComponent(e.q);
+					let param = {};
+					// 把参数按&拆分成数组
+					let index = url.indexOf("?");
+					let query = url.substring(index+1,index.length);
+					var param_arr = query.split("&");
+					for (var i = 0; i < param_arr.length; i++) {
+					    var pair = param_arr[i].split("=");
+					    param[pair[0]]=pair[1];
+					}
+					if(param['type'] == "share"){
+						let path = 'pagesM/pages/goods_des';
+						let params = `id=${param['id']}&storeId=${param['storeId']}&inviteCode=${param['inviteCode']}`
+						let url = `${path}?${params}`;
+						console.error("url = " + url);
+						this.e = null;
+						uni.navigateTo({url: url});
+					}
+				}
+				//二维码扫描链接 end
+				
+				//点击转发卡片进入的小程序
+				this.execParam();
+				
+				wx.showShareMenu({
+				  withShareTicket: true
+				})
+			},
+			tab(index){
+				console.log(index);
+			},
+			jump(url,type){
+				if(!this.$isEmpty(type)){
+					uni.switchTab({
+						url:url
+					})
+				}else{
+					uni.navigateTo({
+						url:url
+					})
+				}
+			},
+			async fetchGoodsList(){
+				let indexProduct = await this.$api.storeHomeProducts();
+				this.goodsList=indexProduct[1].products
+				this.$u.randomArray(this.goodsList)
+			},
+			//轮播圆点
+			bindchange(e) {
+			  this.setData({
+			    swiperIndex: e.detail.current
+			  });
+			},
+			//改变小区
+			typeChange: function (e) {
+			  let _this = this;
+			  Promise.all([_this.getRoomByMemberId()]).then(result => {
+			    let value = _this.plotArray[e.detail.value];
+			    let residentialId = _this.residentialIdList[e.detail.value];
+			
+			    uni.removeStorageSync("plotName");
+			    uni.removeStorageSync("residentialId");
+			    uni.setStorageSync("plotName", value);
+			    uni.setStorageSync("residentialId", residentialId);
+				
+				
+			    _this.setData({
+			      plotIndex: e.detail.value,
+			      plot: value
+			    });
+				
+			  }).catch(error => {
+			    console.log(error);
+			  });
+			},
+			//一键开门
+			goOpen: function () {
+			  var that = this;
+			  var member = app.globalData.member;
+			  var anyHousePass = app.globalData.anyHousePass; //会员认证状态:{ 0:未认证,1:待审审核,2:已认证 }
+			  if (member == null) {
+			    //未注册
+			    app.globalData.footaddmore();
+			    return;
+			  } else if (member.state == 0 && !anyHousePass) {
+			    //未认证
+			    app.globalData.choosePlot();
+			    return;
+			  } else if (member.state == 1 && !anyHousePass) {
+			    //待审核
+			    that.pending();
+			    return;
+			  } else if (member.state == 2 || anyHousePass) {
+			    //已认证
+			    uni.navigateTo({
+			      url: '/pages/oneButton/oneButton'
+			    });
+			  }
+			},
+			getAdList: function () {
+			  let that = this;
+			  let params = {};
+			  let operation = 'adPushApp/getList';
+			  app.globalData.postRequest(params, operation, function (res) {
+			    //获取成功
+			    if (res.data.result_code == 1) {
+			      let adList = res.data.list;
+			      if (adList && adList.length > 0) {
+			        that.setData({
+			          adList: adList
+			        });
+			      }
+			    }
+			  });
+			},
+			//获取openid
+			getOpenId: function () {
+			  var openid = uni.getStorageSync("openid");
+			  console.info("缓存中获取的openid=" + openid);
+			  var that = this;
+			  if (openid == null || openid == '') {
+			    uni.login({
+			      success: res => {
+			        let params = {};
+			        params['js_code'] = res.code;
+					that.jsCode=res.code
+			        let operation = 'miniprogram/getOpenid'; //发起请求
+			        app.globalData.postRequest(params, operation, function (res) {
+			          //获取成功
+			          if (res.data.result_code == 1) {
+						  console.log("获取openid成功")
+			            //openid存入缓存
+			            uni.setStorageSync("openid", res.data.openid);
+						that.openid=res.data.openid
+						that.sessionKey=res.data.sessionKey
+			            that.getMemberByOpenid(res.data.openid);
+			          } else {
+			            app.globalData.oneFailHint(res.data.result_msg);
+			          }
+			        });
+			      }
+			    });
+			  } else {
+			    that.getMemberByOpenid(openid);
+			  }
+			},
+			//根据openid获取用户信息
+			getMemberByOpenid: function (openid) {
+			  let _this = this;
+			  let params = {};
+			  params['openid'] = openid;
+			  let operation = 'miniprogram/getMemberByOpenid';
+			  app.globalData.postRequest(params, operation, function (res) {
+			    console.info("getMemberByOpenid==" + res.data.result_msg); //获取成功
+			    if (res.data.result_code == 1) {
+			      app.globalData.member = res.data.member;
+			      app.globalData.anyHousePass = res.data.anyHousePass; //获取房屋列表
+			      _this.getRoomByMemberId();
+				  _this.getAuthDevice()
+			    } else {
+					
+			    }
+			  });
+			},
+			/**
+			 * 游客登陆
+			 */
+			async touristLogin() {
+			  // 检查是否登录
+			  this.isLogin = this.$auth.isAuth
+			  console.log(this.$auth.isAuth);
+			  if (!this.$auth.isAuth) { // 就算是游客,也重新登录
+			    console.log('需要使用游客身份,执行游客登录!')
+			    let resp = await this.$api.touristLogin()
+				console.log("Resp",resp);
+			    let userType = this.$global.userType.tourist
+			    this.$auth.login(userType, resp.sessionId, resp.userId, resp)
+			    console.log('游客登录成功!', resp)
+			  } else {
+			    console.log(`已登录!`)
+			  }
+			},
+			//根据会员id获取我的房屋列表
+			getRoomByMemberId: function () {
+			  let that = this;
+			  let params = {};
+			  params['member_id'] = app.globalData.member.id;
+			  let operation = 'estate/getRoomByMemberId';
+			  app.globalData.postRequest(params, operation, function (res) {
+			    console.info("获取成功" + res.data.result_msg); //获取成功
+			    let list = [];
+				
+			    let residentialIdList = [];
+			    if (res.data.result_code == 1) {
+					app.globalData.userId=res.data.list[0].userId
+			      res.data.list.map(item => {
+			        if (list.indexOf(item.residentialName) == -1) {
+			          list.push(item.residentialName);
+			          residentialIdList.push(item.residentialId);
+			        }
+			      });
+			
+			      if (list.length < 1) {
+			        uni.removeStorageSync("plotName");
+			        uni.removeStorageSync("residentialId");
+			      } else {
+			        //获取本地储存的当前所在小区
+			        let plot = that.plot;
+			        if (uni.getStorageSync('plotName')) {
+			          plot = uni.getStorageSync('plotName');
+			          that.setData({
+			            plot: plot
+			          });
+			        } else {
+			          uni.setStorageSync("plotName", list[0]);
+			          uni.setStorageSync("residentialId", residentialIdList[0]);
+			          that.setData({
+			            plot: list[0]
+			          });
+			        }
+			      }
+				  let residentialList=[]
+				  list.forEach((item,index)=>{
+					  let tmp={}
+					  tmp.residentialName=item
+					  tmp.residentialId=residentialIdList[index]
+					  residentialList.push(tmp)
+				  })
+				  uni.setStorage({
+				  	key:"residentialList",
+					data:residentialList
+				  })
+				  console.log();
+			      that.setData({
+			        plotArray: list,
+			        residentialIdList: residentialIdList
+			      });
+			    }
+			  });
+			},
+			top: function (index) {
+			 if (index==5) {
+				 if (this.$isEmpty(this.device_list)) {
+				 	uni.showToast({
+				 		title:"暂无设备",
+						icon:"none"
+				 	})
+					return
+				 }
+				 this.modalShow=!this.modalShow
+			 	 return
+			 }
+			  if (index==99) {
+				  //查看更多
+				  uni.navigateTo({
+				  	url:"../tool-list/tool-list"
+				  })
+				  return
+			  }
+			  var that = this;
+			    var member = app.globalData.member;
+			    var anyHousePass = app.globalData.anyHousePass; //会员认证状态:{ 0:未认证,1:待审审核,2:已认证 }
+			    if (member == null) {
+			      //去注册
+				  uni.navigateTo({
+				  	url:"../empty/empty"
+				  })
+				  return
+			    } else if (member.state == 0 && !anyHousePass) {
+					//去认证
+			      uni.navigateTo({
+			      	url:"../empty/empty?type=2"
+			      })
+			      return
+			    } else if (member.state == 1 && !anyHousePass) {
+			      //待审核
+			      that.pending();
+			    } else if (member.state == 2 || anyHousePass) {
+			      //已认证
+			      //获取页面传过来的值
+			      var url;
+			      switch (index) {
+			        case 1:
+			          //我的家人  
+					  url='/pages/myhome/myhome';
+			          break;
+			        case 2:
+			          //家庭成员
+			          url = '/pages/myFamily/myFamily';
+			          break;
+			        case 3:
+			          //我的车辆
+			          uni.showToast({
+			          	title:"待开发",
+						icon:"none"
+			          })
+			          break;
+			        case 4:
+			          //访客授权
+			          url = '/pages/authorize_record/authorize_record';
+			          break;
+			        case 5:
+					  //一键开门
+					  uni.switchTab({
+					  	url:"../device/device"
+					  })
+			          break;
+					case 6:
+					  //防疫登记
+					  url = '/pages/tool-list/epidemic-pass/epidemic-pass';
+					  break;
+					case 7:
+					  //物业缴费
+					  uni.showToast({
+					  	title:"待开发",
+						icon:"none"
+					  })
+					  break;
+					case 8:
+					  //物业报修
+					  url = '/pages/services/property/property';
+					  break;
+			        default:
+			          url = "";
+			          break;
+			      }
+			      if (url != '') {
+			        uni.navigateTo({
+			          url: url,
+			          success: function (res) {
+			            that.setData({
+			              firstJump: false
+			            });
+			          }
+			        });
+			      }
+			    }
+			},
+			openBluetoothAdapter: function () {
+			  uni.openBluetoothAdapter({
+			    success: function (res) {
+			      uni.navigateTo({
+			        url: "/pages/bluetooth/bluetooth"
+			      });
+			    },
+			    fail: function (res) {
+			      uni.showModal({
+			        content: '请开启手机蓝牙后再试'
+			      });
+			    }
+			  });
+			},
+			//用户信息待审核中
+			pending: function () {
+			  var openid = uni.getStorageSync("openid");
+			  let params = {};
+			  params['openid'] = openid;
+			  let operation = 'miniprogram/getMemberByOpenid';
+			  app.globalData.postRequest(params, operation, function (res) {
+			    //获取成功
+			    if (res.data.result_code == 1) {
+			      let member = res.data.member; //待审核
+			      if (member.state == 1 && !res.data.anyHousePass) {
+			        app.globalData.oneFailHint('亲,你的信息正在审核,请耐心等待');
+			      } else if (member.state == 2) {
+			        app.globalData.oneFailHint('亲,你的信息已审核通过');
+			      }
+			      app.globalData.member = member;
+			      app.globalData.anyHousePass = res.data.anyHousePass;
+			    } else {
+			      app.globalData.oneFailHint(res.data.result_msg);
+			    }
+			  });
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+
+	
+	.img1-lg{
+		margin-top: -80rpx;
+	}
+	
+	.location_item{
+		background-color: #FFFFFF;
+		display: flex;
+		padding: 30rpx;
+		font-size: 32rpx;
+	}
+	.active {
+	  transform: none;
+	  transition: all 0.2s ease-in 0s;
+	}
+	
+	.tj-title{
+	  display: flex;
+	  justify-content: space-between;
+	  padding: 30rpx;
+	  background-color: #FFFFFF;
+	  font-size: 32rpx;
+	  .sub-title{
+		  font-size: 26rpx;
+		  padding-left: 16rpx;
+		  color: #c7c7c7;
+	  }
+	}
+	
+	.nav-list {
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: center;
+	}
+	.nav-li {
+		padding: 30upx 20rpx;
+		border-radius: 12upx;
+		width: 40%;
+		margin: 20rpx 1% 10upx;
+		// background-image: url(/static/unicorn-base/index/cc3b1807-c684-4b83-8f80-80e5b8a6b975.png);
+		background-size: cover;
+		background-position: center;
+		position: relative;
+		z-index: 1;
+	}
+	
+	.nav-li::after {
+		content: "";
+		position: absolute;
+		z-index: -1;
+		background-color: inherit;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		bottom: -10%;
+		border-radius: 10upx;
+		opacity: 0.2;
+		transform: scale(0.9, 0.9);
+	}
+	
+	.nav-li.cur {
+		color: #fff;
+		background: rgb(94, 185, 94);
+		box-shadow: 4upx 4upx 6upx rgba(94, 185, 94, 0.4);
+	}
+	
+	.nav-title {
+		font-size: 32upx;
+		font-weight: 300;
+	}
+	
+	.nav-title::first-letter {
+		font-size: 40upx;
+		margin-right: 4upx;
+	}
+	
+	.nav-name {
+		font-size: 28upx;
+		text-transform: Capitalize;
+		margin-top: 20upx;
+		position: relative;
+	}
+	
+	.nav-name::before {
+		content: "";
+		position: absolute;
+		display: block;
+		width: 40upx;
+		height: 6upx;
+		background: #fff;
+		bottom: 0;
+		right: 0;
+		opacity: 0.5;
+	}
+	
+	.nav-name::after {
+		content: "";
+		position: absolute;
+		display: block;
+		width: 100upx;
+		height: 1px;
+		background: #fff;
+		bottom: 0;
+		right: 40upx;
+		opacity: 0.3;
+	}
+	
+	.nav-name::first-letter {
+		font-weight: bold;
+		font-size: 36upx;
+		margin-right: 1px;
+	}
+	
+	.nav-li image {
+		position: absolute;
+		right: 30upx;
+		top: 30upx;
+		font-size: 52upx;
+		width: 70upx;
+		height: 70upx;
+		text-align: center;
+		line-height: 60upx;
+	}
+	
+</style>

+ 1234 - 0
pages/life/life.vue

@@ -0,0 +1,1234 @@
+<template>
+<view style="background-color: #f2f2f2;">
+	<u-navbar :is-back="false" title=" ">
+		<view class="slot-wrap">
+			<view class="search-wrap" >
+				<view style="flex: 30%;" class="flex text-bold padding-right-20 justify-center align-center">
+					周边商城
+				</view>
+				<view class="">
+					<u-search  @click="jumpSearch()" disabled  :show-action="false" height="56" ></u-search>
+				</view>
+			</view>
+		</view>
+	</u-navbar>
+  <view :style="{display:show}">
+	  <!-- <ScrollMenu></ScrollMenu> -->
+	  <view class="banner">
+	     <swiper 
+	     class="swiper" 
+	     interval="5000" 
+	     duration="500" 
+	     autoplay="true" 
+	     circular="true"
+	  	:indicator-dots="adsList.length>1"
+	     indicator-color="rgba(153,153,153,1)" 
+	     indicator-active-color="#FFF"
+	     @change="switchColor">
+	  	 <swiper-item v-for="(item,index) in adsList" :key="index">
+	  	   <image class="image" mode="heightFix" :src="item.path" @tap="tapNav(item)"></image>
+	  	 </swiper-item>
+	     </swiper>
+<!-- 		 <view style="width: 100%;position: absolute;top: 10rpx;display: flex;justify-content: center;">
+		   <view style="width: 90%;">
+				<u-search @click="jumpSearch()" disabled input-align="center"  :show-action="false" placeholder="请输入要搜索的商品" ></u-search>
+		   </view>
+		  </view> -->
+	   </view>
+	   <!-- 小区信息 -->
+<!-- 	<view class="head" >
+	  <view style="display: flex;align-items: center;margin-bottom: 20upx;padding-top: 10rpx;">
+		  <image src="/static/icon/location.png" style="width: 38upx;height: 38upx;" mode="widthFix"></image>
+		  <text style="color: #fff;font-size: 30upx;margin-left: 10upx;">{{plotName}}</text>
+	  </view>
+	</view> -->
+   
+	<view style="padding: 10upx 20upx;background-color: #FFFFFF;" >
+		<!-- <view>
+			 <image class="imgs" v-for="(item,index) in topAds" :key="index" :src="item.path" mode="widthFix" style="width: 100%;display: block;margin-top: 30upx;" @tap="jumpPromotion(item,index)"></image>
+		 </view> -->
+			<ls-swiper :lists="headNavList" :swiperType="nav" imgKey="imgUrl" :loop="false" :dots="false" :autoplay='false' :height="380" />
+			<view style="flex:1;position: relative;">
+				<!-- <view style="position: absolute;left: 50%;top: 18upx;transform: translateX(-50%);font-size: 32upx;color: #653C00;font-weight: bold;">每日爆款</view> -->
+				<view v-if="index==0" v-for="(item,index) in indexProduct" :key="index" @tap="onMore(item)" class="everyDay" :style="{backgroundImage: 'url('+(item.path1?item.path1:'')+')'}">
+					<scroll-view scroll-x="true" >
+						<view style="display: flex;width: 100%;margin-left: 20upx;">
+							<view style="display: flex;">
+								<view v-for="(child,idx) in item.products" :key="idx" @tap.stop="jumpGoodsDes(child.id)" style="padding: 6upx 14upx;height: 158upx;border-radius: 20upx;background-color: #fff;margin-right: 8upx;display: flex;flex-direction: column;justify-content: center;align-items: center;">
+									<image :src="child.thumbnail" mode="aspectFit" style="width:136upx;height:136upx;"></image>
+									<view style="min-width: 76upx;font-size: 28upx;font-weight: bold;color:#fff;text-align: center;border-radius: 25px;background-color: #E42F2F;padding: 0 4upx;">
+									<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+								</view>
+								<view style="width: 12upx;"></view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+			<view style="display: flex;border-bottom: 2upx solid #f7f7f7;">
+				<view v-if="index==1||index==2" v-for="(item,index) in indexProduct" :key="index"  @tap="onMore(item,item.name,index)" style="width: 314upx;padding: 40upx 20upx 20upx;background-color: #fff;border-right: 2upx solid #f7f7f7;">
+					<view style="font-size: 28upx;font-weight: bold;">{{item.name}}</view>
+					<view style="font-size: 20upx;color:#999999;margin-top: 10upx;">{{item.memo}}</view>
+					<scroll-view scroll-x="true">
+						<view style="display: flex;width: 100%;">
+							<view  v-for="(child,idx) in item.products" :key="idx" >
+								<image :src="child.thumbnail" style="width:148upx;height:148upx;margin:20upx 0;background-color:#f7f7f7"></image>
+								<view style="font-size: 28upx;font-weight: bold;color:#E42F2F;text-align: center;">
+								<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+<!-- 			<view style="display: flex;border-bottom: 2upx solid #f7f7f7;">
+				<view v-if="index==1||index==2" v-for="(item,index) in indexProduct" :key="index"  @tap="onMore(item,item.name,index)"  style="width: 360upx;padding: 40upx 20upx 20upx;background-color: #fff;border-right: 2upx solid #f7f7f7;">
+					<view style="font-size: 28upx;font-weight: bold;">{{item.name}}</view>
+					<view style="font-size: 20upx;color:#999999;margin-top: 10upx;">{{item.memo}}</view>
+					<scroll-view scroll-x="true">
+						<view style="display: flex;width: 100%;">
+							<view  v-for="(child,idx) in item.products" :key="idx" >
+								<image :src="child.thumbnail" style="width:148upx;height:148upx;margin:20upx 0;background-color:#f7f7f7"></image>
+								<view style="font-size: 28upx;font-weight: bold;color:#E42F2F;text-align: center;">
+								<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view> -->
+			<!-- <view>
+				<view  v-for="(item,index) in centerAd" :key="index" @tap="jumpPromotion(item,index)" style="margin-top: 20upx;">
+					<image :src="item.path" mode="widthFix" style="width: 100%;display: block;"></image>
+				</view>
+				<view style="display: flex;justify-content: space-between;">
+					<view  v-for="(item,index) in twoAds" :key="index" @tap="jumpPromotion(item,index)" style="flex:1">
+						<image :src="item.path" mode="widthFix" style="width: 100%;display: block;"></image>
+					</view>
+				</view>
+			</view> -->
+			<view style="display: block;margin-bottom: 20upx;">
+				<view v-if="index==3" v-for="(item,index) in indexProduct" :key="index" style="background-color: #fff;padding: 40upx 20upx 25upx;border-bottom-left-radius: 20upx;border-bottom-right-radius: 20upx;">
+					<view style="display: flex;justify-content: space-between;">
+						<view>
+							<view style="font-size: 28upx;font-weight: bold;">{{item.name}}</view>
+							<view style="font-size: 20upx;margin-top: 10upx;color: #999;">{{item.memo}}</view>
+						</view>
+						<view @tap="onMore(item)" style="display: flex;align-items: center;height: 35upx;">
+							<view style="font-size: 20upx;">查看更多</view>
+							<image src="http://139.9.103.171:1888/img/image/ic_more.png" mode="aspectFit" style="width: 16upx;height: 16upx;margin-left: 5upx;"></image>
+						</view>
+					</view>
+					<scroll-view scroll-x="true">
+						<view style="width: 100%;display: flex;">
+							<view v-for="(child,idx) in item.products" :key="idx" @tap="jumpGoodsDes(child.id)" style="padding: 0 3upx;height: 232upx;border-radius: 20upx;background-color: #fff;margin-top:20upx;margin-right: 20upx;display: flex;flex-direction: column;justify-content: center;align-items: center;">
+								<view :style="idx==0||idx==1?'backgroundColor:#FFE6E6;border-radius:10upx':'backgroundColor:#FFF3E6;border-radius:10upx'" >
+									<image :src="child.thumbnail" mode="widthFix" style="width:148upx;height:148upx;display: block;"></image>
+								</view>
+								<view v-if="idx==0||idx==1" style="min-width: 76upx;font-size: 28upx;font-weight: bold;color:#fff;text-align: center;margin-top: 20upx;border-radius: 25px;background-color: #E42F2F;padding: 0 4upx;">
+									<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+								<view v-else style="min-width: 76upx;font-size: 28upx;font-weight: bold;color:#fff;text-align: center;margin-top: 20upx;border-radius: 25px;background-color: #FFD062;padding: 0 4upx;">
+								<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+							</view>
+							
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+	</view>
+		<scroll-view id="scrollView" class="menu_scroll" scroll-x="true" :scroll-left="scrollLeft" :style="{top:DtCustomBarHeight+'px'}">
+			<view class="menu_type" >
+				<view  v-for="(item,index) in bottomNavList" :key="index" :class="index==menu_index?'type_item_active':'type_item'"  @tap="tapGoodsList(item,index)" >
+					<view style="font-weight:bold;position: relative">
+						<view 
+						v-if="index==0||index==1"
+						class="bubble bubble-red">自提</view>
+						<view
+						v-if="index==2||index==3"
+						class="bubble bubble-yellow">包邮</view>
+						{{item.name}}
+					</view>
+					<view style="font-size: 20upx;color: #999999;margin-top: 10upx;">{{item.memo}}</view>
+					<!-- <view :class="index==menu_index?'type_item_active_line':''"></view> -->
+				</view>
+			</view>
+		</scroll-view>
+	<!-- <view :style="isTop==1? 'display: block':'display:none'" class="topHeight"></view> -->
+	<swiper  :current="menu_index" duration="300" @change="switchTab" :style="{height:product_unit_height}">
+	   <swiper-item  v-for="(item,index) in bottomNavList" :key="index">
+		   <view class="bottom_goods_list">
+			 <!-- <DtGoodsListHome :dataList="item.products"/> -->
+			 <DtGoodsListHome02 :dataList="item.products"/>
+		   </view>
+	   </swiper-item>
+	 </swiper>
+	
+	<!-- <view class="enIcon">
+	  <view v-for="(item,idx) in navList" :key="idx" class="item">
+		<button v-if="item.funcType == 8" class="customer-service" open-type="contact" session-from="weapp">
+			<image :src="item.path"></image>
+			<text class="enIcon-btn-text">{{item.name}}</text>
+		</button>
+		<view class="item2" v-else  @tap="tapGoodsList(item)">
+			<image :src="item.path"></image>
+			<view class="enIcon-text">{{item.name}}</view>
+		</view>
+	  </view>
+	</view> -->
+	<!-- <view class="ad_banner" v-for="(item,index) in adsList" :key="index">
+		<image mode="widthFix" :src="item.path" @tap="tapNav(item)"></image>
+	</view> -->
+	<!-- <view  v-for="(item,idx) in indexProduct" :key="idx">
+	   <view class="goods_list">
+		 <DtUnitHead :title="item.name" :memo="item.memo" @more="onMore(item)" />
+		 <DtGoodsListH :dataList="item.products" :dataItem="item" @more="onMore(item)"/>
+	   </view>
+	</view>
+	<view  v-for="(item,idx) in navTabsList" :key="idx">
+		<view v-if="item.layout==0" class="goods_list">
+			 <DtUnitHead :title="item.name" :memo="item.memo" @more="onMore(item)" />
+			 <view class="ad_goods_content">
+				  <view v-if="cidx==0"  class="ad_goods_left" v-for="(citem,cidx) in item.tagGroups" :key="cidx" :style="{backgroundImage: 'url('+(citem.path1?citem.path1:'')+')'}" @tap="onMore(citem)">
+				  </view>
+				  <view class="ad_goods_right">
+					  <view v-if="cidx==1||cidx==2" v-for="(citem,cidx) in item.tagGroups" :key="cidx" class="ad_goods_right_item" :style="{backgroundImage: 'url('+(citem.path1?citem.path1:'')+')'}" @tap="onMore(citem)">
+					  </view>
+				  </view>
+			 </view>
+		</view>
+		<view v-if="item.layout==1" class="goods_list">
+			 <DtUnitHead :title="item.name" :memo="item.memo" @more="onMore(item)" />
+			 <DtGoodsListH v-if="item.tagGroups" :dataList="item.tagGroups" :dataItem="item" @more="onMore(item)"/>
+		</view>
+	</view> -->
+	
+	<!-- <view v-if="idx==0" v-for="(item,idx) in indexProduct" :key="idx">
+	   <view class="goods_list">
+		 <DtUnitHead :title="item.name" @more="onMore(item)" />
+		 <view class="ad_goods_content">
+			  <view v-if="cidx==0"  class="ad_goods_left" v-for="(citem,cidx) in item.products" :key="cidx" :style="{backgroundImage: 'url('+citem.thumbnail+')'}" @tap="jumpGoodsDes(citem.id)">
+				 <view class="ad_goods_name">{{citem.name}}</view>
+				 <view class="ad_goods_caption">{{citem.caption}}</view>
+				<view class="gotosee">去看看</view>
+			  </view>
+			  <view class="ad_goods_right">
+				  <view v-if="cidx==1||cidx==2" v-for="(citem,cidx) in item.products" :key="cidx" class="ad_goods_right_item" :style="{backgroundImage: 'url('+citem.thumbnail+')'}" @tap="jumpGoodsDes(citem.id)">
+					  <view class="ad_goods_name">{{citem.name}}</view>
+					  <view class="gotosee">去看看</view>
+				  </view>
+			  </view>
+		 </view>
+	   </view>
+	</view>-->
+	
+	
+   <view v-if="couponList.length>0&&couponShow" class="coupon_mengban">
+	   <view class="coupon"  @tap="tapToCoupon">
+		   <image src="http://139.9.103.171:1888/img/image/coupon_bg.png" mode="widthFix" style="width: 650upx;height: 680upx;" ></image>
+		   <image class="ic_off" src="http://139.9.103.171:1888/img/image/ic_coupon_off.png" mode="widthFix" @tap.stop="close_coupon"></image>
+		  <scroll-view class="scroll" scroll-y="true">
+			<view class="coupon_box">
+				<!-- @tap="tapDrawCoupon(item,index)" -->
+			  <view class="coupon_item" v-if="index<2" v-for="(item,index) in couponList" :key="index">
+				<image class="coupon_img" src="http://139.9.103.171:1888/img/image/coupon_img_white.png"></image>
+				<view class="coupon_info">
+				  <text class="coupon_unit">¥</text>
+				  <text class="coupon_amount">{{item.amt}}</text>
+				</view>
+				<view style="position: absolute;width: 255upx;top: 0;bottom:0;left: 10upx;display: flex;flex-direction: column;justify-content: center;">
+					<view class="coupon_name dt-text-row-one">{{item.name}}</view>
+					<view class="dt-text-row-one" style="font-size: 16upx;color: #999999;">
+						有效日期:{{item.beginDate}}至{{item.endDate}}
+					</view>
+				</view>
+			  </view>
+			 
+			 <!-- <view v-if="couponList.length>2" class="coupon_more" @tap="tapToCoupon">
+				<view class="more_text">查看更多</view>
+				<image src="/static/image/arrow.png"></image>
+			  </view> -->
+			</view>
+		  </scroll-view>
+		</view>
+   </view> 
+	<image
+	 v-if="couponList.length>0"
+	src="http://139.9.103.171:1888/img/image/ic_hongbao.png" 
+	mode="widthFix"
+	 @tap="tapToCoupon"
+	style="position: fixed;right: 0;bottom: 50upx;width: 150upx;"></image>
+	<!-- 商品单元列表 -->
+	<!-- <view v-for="(item,idx) in product" :key="idx"
+	  class="product-unit">
+	  <DtUnitHead :title="item.name" @more="onMore(item)" />
+	  <DtGoodsListH :dataList="item.products" />
+	  <view class="line"></view>
+	</view> -->
+	
+	  
+	<!-- 微信客服 -->
+	<!-- <DtService /> -->
+
+  </view>
+  <DtEmpty :type="emptyType" />
+
+  <DtLogin ref="dialogLogin" @signIn="onSignIn" />
+  <!-- <view style="display: flex;flex-direction: column;align-items: center;justify-content: center;font-size: 16px;height: 100vh;">
+	  <view style="font-weight: bold;margin-bottom: 18rpx;">小程序已迁移</view>
+	  <navigator style="padding: 10rpx 20rpx;background-color: green;border-radius: 6rpx;color: #fff;" target="miniProgram" open-type="navigate" app-id="wx90680ffd54c3b96c" path="/pagesM/pages/home" extra-data="" version="release">点我前往新的小程序</navigator>
+  </view> -->
+  
+ <view  style="height: 80rpx;background-color: #F1F1F1;display: flex;justify-content: center;color: #909399;align-items: center;">
+	 <text>没有更多了</text>
+  </view>
+<!--  <view class="text-center  margin-top-10" style="font-size: 26rpx;color: #909399;background-color: #FFFFFF;padding: 22rpx;" >
+	<text>到底了</text>
+  </view> -->
+  
+</view>
+</template>
+
+<script>
+import ScrollMenu from "@/comps/scroll_menu.vue"
+import DtLogin from '@/comps/dt_login.vue'
+import DtEmpty from '@/comps/dt_empty.vue'
+import DtUnitHead from '@/comps/dt_unit_head_v2.vue'
+import DtGoodsListH from '@/comps/dt_goods_list_h.vue'
+import lsSwiper from '@/comps/mosowe-swiper.vue'
+// import DtService from '@/comps/dt_service.vue'
+import DtGoodsListHome from '@/comps/dt_goods_list_home.vue'
+import DtGoodsListHome02 from '@/comps/dt_goods_list_home02.vue'
+import DtCustomBar from '@/comps/dt_custom_bar.vue'
+export default {
+  components: {
+    DtLogin,
+    DtEmpty,
+    DtUnitHead,
+    // DtService,
+    DtGoodsListH,
+	lsSwiper,
+	DtGoodsListHome,
+	ScrollMenu,
+	DtCustomBar,
+	DtGoodsListHome02
+  },
+  data() {
+    return {
+		keyword:'',
+		
+		plotName:'暂无小区信息',
+		nav:'nav',
+      companyAddress: '',
+
+      adsList: [], //广告动态
+
+      indexProduct:[], // 店铺热卖,店铺推荐....
+      couponList: [],
+
+      navList: [], // 导航列表
+      memberId: '',
+	  navTabsList:[],
+	  menu_index:0, //tab index
+	  scrollLeft:0, 
+	  isTop:0, 
+	  myScroll:0, 
+	  product_unit_height:1000 + 'px',
+	  show:'block',
+	  headNavList:[],
+	  bottomNavList:[],
+	  headColor:'#D43A39',
+	  startSwitchColor:true,
+	  organizationList:{},
+	  twoAds:[], //中部会场(两行一列)
+	  centerAd:[],
+	  topAds:[], //顶部会场
+	  DtCustomBarHeight:0,
+	  couponShow:true
+    }
+  },
+  mounted(){
+	
+  },
+ // 判断是否吸顶
+  onPageScroll:function(e){
+	  this.getSwiperHeight();
+	 //  if(e.scrollTop>=this.myScroll){
+		// this.isTop = 1;
+	 //  }else{
+		// this.isTop = 0;
+	 //  }
+	 
+	 const query = uni.createSelectorQuery().in(this);
+	 query.select('#scrollView').boundingClientRect(data => {
+	   if(data.top==this.DtCustomBarHeight){
+			this.isTop = 1
+	   }else{
+		   this.isTop = 0;
+		   this.myScroll = 0;
+	   }
+	 }).exec();
+	 if(this.isTop==1&&this.myScroll==0){
+		 this.myScroll =  e.scrollTop;
+	 }
+  },
+  methods: {
+	  // 跳转搜索
+	  jumpSearch(item) {
+		  console.log(item)
+	    if (!item) {
+	      uni.navigateTo({
+	        url: "/pagesM/pages/search"
+	      })
+	    } else {
+	      let params = {
+	        keyword: item.name,
+	        productCategoryId: item.id
+	      }
+	      uni.navigateTo({
+	        url: "/pagesM/pages/search?" + this.$util.serialize(params)
+	      })
+	    }
+	  },
+	  switchColor(e){
+		  switch(e.detail.current){
+			  case 0:this.headColor = '#D43A39';
+			  break;
+			  case 1:this.headColor = '#98cb5b';
+			  break;
+			  case 2:this.headColor = '#4f85b2';
+		  }
+	  },
+	  claimGoods(){
+		  uni.navigateTo({
+		    url: "claim_goods"
+		  })
+	  },
+	  
+	  openNearbyTeam(){
+		  uni.navigateTo({
+		    url: "/pagesM/pages/nearby_team"
+		  })
+	  },
+	  jumpGoodsDes(id) {
+	    uni.navigateTo({
+	      url: "/pagesM/pages/goods_des?id=" + id
+	    })
+	  },
+	  //动态设置height
+	  getSwiperHeight(){
+		  const query = uni.createSelectorQuery().in(this);
+		  query.selectAll(".bottom_goods_list").boundingClientRect();
+			query.exec((res) => {
+				this.product_unit_height =res[0][this.menu_index].height+'px'
+			})
+	  },
+	  switchTab(e){
+		 //  //判断吸顶之后才返回到滚动起始位置
+		  if(this.isTop == 1){
+			  uni.pageScrollTo({
+	        duration:0,//过渡时间必须为0,uniapp bug,否则运行到手机会报错
+	        scrollTop:this.myScroll,
+	      })
+		  }
+		 //  if(e.detail.current>4){
+			//   this.scrollLeft = 300
+		 //  }else{
+			//   this.scrollLeft = 0
+		 //  }
+		  this.menu_index = e.detail.current
+		  this.getSwiperHeight();
+	  },
+	  tapNav(item){
+		let type = item.type; //0:文本广告,1:图片广告 2:会场广告
+		if([0,"0"].includes(type)&&item.content){
+			uni.navigateTo({
+			  url: '/pagesM/pages/common/ad_textView?content=' + item.content
+			});
+		}else if([1,"1"].includes(type)&&item.productId){
+			uni.navigateTo({
+			  url: '/pagesM/pages/goods_des?id=' + item.productId
+			});
+		}else if([2,'2'].includes(type)&&item.url){
+			let  url = item.url;
+			if (this.memberId){
+				 url = url + this.memberId;
+				 console.log('banner 链接 = ' + url)
+				 uni.navigateTo({
+				   url: '/pagesM/pages/common/webview?url=' + encodeURIComponent(url)
+				 });
+			}
+		}  
+	 },
+    jumpPromotion(item,specialType){
+		let type = item.type; //0:文本广告,1:图片广告 2:会场广告
+		if([0,"0"].includes(type)&&item.content){
+			uni.navigateTo({
+			  url: '/pagesM/pages/common/ad_textView?content=' + item.content
+			});
+		}else if([1,"1"].includes(type)&&item.productId){
+			uni.navigateTo({
+			  url: '/pagesM/pages/goods_des?id=' + item.productId
+			});
+		}else if([2,'2'].includes(type)&&item.url){
+			// uni.navigateTo({
+			  //   url: "../comps/dt_special?url="+item.url+"&title="+item.title+"&style="+type
+			  // })
+			  uni.navigateTo({
+				url: "/pagesM/comps/promotion_detail?url="+item.url+"&title="+item.title+"&style="+specialType
+			  })
+		}
+    		  
+    },
+	tapTocategory(){
+		uni.navigateTo({
+			url:"/pagseM/pages/category"
+		})
+	},
+    showLogin() {
+      this.$refs.dialogLogin.show()
+    },
+    // 登录成功响应事件
+    onSignIn(resp) {
+      // console.log(143, resp)
+      this.$util.refreshPage(['pages/home', 'pages/shop_car'])
+      this.onPullDownRefreshPage()
+    },
+
+    onMore(item,name,theme) {
+      let params = item.param;
+	  if(name){
+		  uni.navigateTo({
+		    url: "/pagesM/pages/goods_list?params=" + JSON.stringify(params) + '&name=' + name + '&hideTop=true' + '&theme=' + theme + '&path=' + item.path1
+		  })
+	  }else{
+		  uni.navigateTo({
+		    url: "/pagesM/pages/goods_list?params=" + JSON.stringify(params)
+		  })
+	  }
+      
+    },
+
+    
+	close_coupon(){
+		this.couponShow = false;
+	},
+    // 领取优惠券
+    async tapDrawCoupon(item, index) {
+      // 领取优惠券需要登录
+      if (!this.isLogin) {
+        this.showLogin()
+        return
+      }
+      console.log('get Voucher', item)
+      try {
+        let resp = await this.$api.couponExchange({
+          _isShowLoading: true,
+          _isReject: true,
+          memberId: this.memberId,
+          couponId: item.id
+        })
+        if (resp.result) {
+          this.$dialog.success('领取成功')
+          item.isReceive = true
+          this.$set(this.couponList, index, item)
+        } else {
+          this.$dialog.error('领取失败')
+        }
+      } catch (err) {
+        // if(err.sysflag === '4010' && err.errmsg === '您已经领取过了'){
+        //   this.$dialog.success('领取成功')
+        //   item.isReceive = true
+        //   this.$set(this.couponList, index, item)
+        // }else{
+        this.$dialog.alert({
+          content: err.errmsg || '领取失败'
+        })
+        // }
+      }
+		this.close_coupon();
+    },
+    // 跳转优惠券
+    tapToCoupon() {
+      uni.navigateTo({
+        url: "/pagesM/pages/coupon_center"
+      })
+    },
+
+    // 商品列表
+    tapGoodsList(item,idx) {
+		this.menu_index = idx;
+		// var list = [];
+		// for(let i in this.indexProduct){
+		// 	if(item.name==this.indexProduct[i].name){
+		// 		list.push(this.indexProduct[i]);
+		// 	}
+		// }
+		// if(this.product.length>0){
+		// 	this.product.splice(0,this.product.length)
+		// }
+		// if(list){
+		// 	this.product = list.concat()
+		// }
+		
+		// if(item.id == null){
+		// 	if(item.type == "customerService"){
+				
+		// 	}
+		// }else{			
+		//   // let idx =
+		//   // console.log(170,item) 
+		//   let params = ''
+		//   if (item.param) {
+		// 	// console.log(176,[item.param])
+		// 	// params = JSON.stringify([item.param])
+		// 	params = JSON.stringify(item.param);
+		//   }
+		//   uni.navigateTo({
+		// 	url: '/pages/goods_list?params=' + params
+		//   })
+		// }
+    },
+
+   //  async homeNavAds(){
+   //    let resp = await this.$api.homeNavAds();
+	  // // this.homeNavAds = resp;
+	  // return resp
+   //  },
+
+    //获取公司介绍 地址
+    async lookIntroduction() {
+      let company = await this.$api.lookIntroduction();
+      this.companyAddress = company.intelligence.companyAddress;
+      return company
+    },
+   
+    // //查找店铺商品分类
+    // async getStoreProductCategorys() {
+    //   let productCategoryList = await this.$api.getStoreProductCategorys();
+    //   if(productCategoryList){
+    //     let plen = productCategoryList.length
+    //     if(plen<=2 && plen>0){
+    //       this.getProductChildrenCategorys();
+    //     }else if(plen > 2){
+    //       this.tabList = productCategoryList;
+    //     }else{
+    //       this.tabList = [];
+    //     }
+    //   }else{
+    //     this.tabList = [];
+    //   }
+    // },
+    // // 查找子分类
+    // async getProductChildrenCategorys() {
+    //   let data = {};
+    //   data.id = this.tabList[0].id;
+    //   let childrenCategorys = await this.$api.getProductChildrenCategorys(data);
+    //   this.tabList = childrenCategorys || [];
+    // },
+
+    //店铺首页 广告、导航菜单、公司信息
+    async storeHomeNavAds() {
+      let index = await this.$api.storeHomeNavAds();
+      this.adsList = index.carousel;
+      this.navList = index.navigation;
+	  this.twoAds.splice(0,this.twoAds.length);
+	  index.twoAds.map((item,index)=>{
+		  if(index!==0){
+			  this.twoAds.push(item)
+		  }
+	  })
+	  this.centerAd.splice(0,this.centerAd.length);
+	  this.centerAd.push(index.twoAds[0]);
+	  this.topAds.splice(0,this.topAds.length);
+	  this.topAds.push(index.ads[0])
+      return index;
+    },
+
+    // 获取可兑换优惠券,前端隐藏已领取的优惠券
+    async getCouponByStoreId() {
+      let resp = await this.$api.getHasExchangeCoupons({
+        memberId: this.memberId
+      });
+      let list = resp || []
+      list = list.slice(0, 3)
+      if (this.isLogin) {
+        list = list.filter((item) => {
+          return !item.isReceive
+        })
+      } else { // 未登录全部显示未领取
+        list.map((item) => {
+          item.isReceive = false
+          return item
+        })
+      }
+      this.couponList = list
+      return resp
+    },
+	async getStoreHomeNavTags(){
+		let resp  = await this.$api.storeHomeNavTags();
+		// this.navTabsList = resp;
+		if(resp.length>0){
+			this.headNavList.splice(0,this.headNavList.length);
+			  resp.map((item)=>{
+				   if(item.name=="中部导航-社区自取"){
+					   this.headNavList.push(item)
+				   }
+			  })
+			  if(this.headNavList[0].tagGroups.length>9){
+				  let obj = {}
+				  let tagGroups = []
+				  this.headNavList[0].tagGroups.map((item,index)=>{
+					  if(index>9){
+						  tagGroups.push(item)
+					  }
+				  })
+				  obj['tagGroups'] = tagGroups
+				  this.headNavList.push(obj)
+				  this.headNavList[0].tagGroups.length = 11
+			  }
+		}
+		return resp
+	},
+    //首页产品-店铺热卖-店铺推荐
+    async storeHomeProducts() {
+      let indexProduct = await this.$api.storeHomeProducts();
+		if(indexProduct.length>0){
+			 this.indexProduct.splice(0,this.indexProduct.length);
+			this.bottomNavList.splice(0,this.bottomNavList.length);
+			this.indexProduct = indexProduct;
+			this.bottomNavList = indexProduct;
+		}
+		
+      return indexProduct
+    },
+    async touristLogin() {
+      // 检查是否登录
+      this.isLogin = this.$auth.isAuth
+      if (!this.$auth.isAuth) { // 就算是游客,也重新登录
+        console.log('需要使用游客身份,执行游客登录!')
+        let resp = await this.$api.touristLogin()
+        let userType = this.$global.userType.tourist
+        this.$auth.login(userType, resp.sessionId, resp.userId, resp)
+        console.log('游客登录成功!', resp)
+      } else {
+        console.log(`已登录!`)
+        	this.$refs.dialogLogin.hide();
+      }
+    },
+	async getProductCategorys() {
+	  let resp = await this.$api.getProductCategorys();
+	  console.log(resp)
+	  if(resp.length>0){
+	  	this.headNavList.splice(0,this.headNavList.length);
+		let obj = {};	
+		let tagGroups = [];
+	  	  resp.map((item,index)=>{
+			  let childObj = {
+				  path1:item.icon,
+				 name:item.name,
+				 id:item.id
+			  }
+			  tagGroups.push(childObj)
+			  obj['tagGroups'] = tagGroups
+			
+	  	  })
+		  this.headNavList.push(obj)
+	  	  if(this.headNavList[0].tagGroups.length>10){
+	  		  let obj = {}
+	  		  let tagGroups = []
+	  		  this.headNavList[0].tagGroups.map((item,index)=>{
+	  			  if(index>9){
+	  				  tagGroups.push(item)
+	  			  }
+	  		  })
+	  		  obj['tagGroups'] = tagGroups
+	  		  this.headNavList.push(obj)
+	  		  this.headNavList[0].tagGroups.length = 10
+	  	  }
+	  }
+	  console.log(this.headNavList)
+	  return resp;
+	},
+    async loadData() {
+	  // wx.hideShareMenu();
+      this.$dialog.showLoading('加载中...')
+      await this.$nextTick(function(){
+      	 this.touristLogin()
+      })
+      this.memberId = this.$auth.getMemberId();
+	  
+	  console.log(this.memberId)
+	  
+	  //从缓存中获取小区信息
+	  this.plotName=uni.getStorageSync("plotName") || '暂无小区信息'
+	  
+      let list = []
+	  // list.push(this.getOrganizationList());//附近团
+      // list.push(this.homeNavAds()); //广告位
+      list.push(this.lookIntroduction()); // 获取定位地址
+      // list.push(this.getStoreProductCategorys()); // 分类
+      list.push(this.getProductCategorys());//产品分类
+      list.push(this.storeHomeNavAds()); // 轮播广告导航
+      list.push(this.getCouponByStoreId()); // 优惠券
+      list.push(this.storeHomeProducts()); // 产品 
+		// list.push(this.getStoreHomeNavTags()); //店铺首页 导航标签组
+      Promise.race(list).then((resList) => {
+        console.log(255, resList)
+      }).catch(err => {
+        consle.log(err)
+      }).finally(() => {
+        this.emptyType = 0
+		if(this.emptyType==0){
+			this.show = 'block'
+		}else{
+			this.show = 'none'
+		}
+        this.$dialog.hideLoading()
+      })
+    },	
+		getParam(e){
+			// 用来保存所有的属性名称和值
+			let param = "";
+			// 开始遍历
+			for(let p in e){
+				// 方法
+				if(typeof(e[p])!="function" && p != 'type'){
+					// p 为属性名称,e[p]为对应属性的值
+					param += (param.length > 1 ? '&' : '') + p + "=" + e[p];
+				}
+			}
+			// 最后显示所有的属性
+			return param;
+		},
+		execParam(){
+			let _this = this;
+			if(this.e != null){
+				setTimeout(function(){
+					if(_this.e == null) return;
+					if(_this.e.type == "share"){
+						let path = _this.e.path == null || _this.e.path.length <= 0 ? 'pagesM/pages/goods_des' : '/' + _this.e.path;
+						let param = _this.getParam(_this.e);
+						let url = `${path}?${param}`;
+						console.error("url = " + url);
+						_this.e = null;
+						uni.navigateTo({url: url});
+					}
+				}, 1000);
+			}
+		},
+		async getOrganizationList(){
+			let resp = await this.$api.getOrganizationList({
+			  _isPull: this.isPull,
+			  pageNo: 1,
+			  pageSize: 1
+			});
+			this.organizationList = resp[0];
+		},
+	},
+
+	onShow() {
+		this.execParam();
+		this.onShowPage();
+		this.loadData();
+	},
+	onLoad(e) {
+		this.e = e;
+		console.log(e)
+		//二维码扫描链接 start
+		if(e != null && e.q != null){
+			let url = decodeURIComponent(e.q);
+			let param = {};
+			// 把参数按&拆分成数组
+			let index = url.indexOf("?");
+			let query = url.substring(index+1,index.length);
+			var param_arr = query.split("&");
+			for (var i = 0; i < param_arr.length; i++) {
+			    var pair = param_arr[i].split("=");
+			    param[pair[0]]=pair[1];
+			}
+			if(param['type'] == "share"){
+				let path = 'pagesM/pages/goods_des';
+				let params = `id=${param['id']}&storeId=${param['storeId']}&inviteCode=${param['inviteCode']}`
+				let url = `${path}?${params}`;
+				console.error("url = " + url);
+				this.e = null;
+				uni.navigateTo({url: url});
+			}
+		}
+		//二维码扫描链接 end
+		this.execParam();
+		wx.showShareMenu({
+		  withShareTicket: true
+		})
+	},
+}
+</script>
+
+<style lang="scss" scoped>
+	.search-wrap {
+		margin: 0 20rpx;
+		display: flex;
+	}
+	
+	.home{
+		// background-color: #fff;
+		// background-image: url(/static/image/home_bg.jpg);
+		// background-size: contain;
+		// background-repeat-y: repeat;
+	}
+.head {
+	padding: 0 20upx;
+	// height:300upx;
+	height: 250upx;
+	border-bottom-left-radius: 10%;
+	border-bottom-right-radius: 10%;
+	// transition: 0.5s linear all;
+  .address {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding: 24upx 0;
+    image {
+      width: 27upx;
+      height: 35upx;
+      padding-right: 20upx;
+    }
+
+    .address_text {
+      flex: 1;
+      font-size: 28upx;
+      color: #fff;
+      letter-spacing: 2upx;
+    }
+  }
+
+
+  .search{
+    height: 60upx;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+	.icon{
+		width: 32upx;
+		height: 32upx;
+	}
+	.icon_message{
+		width: 40upx;
+		height: 40upx;
+		// background-image: url(/static/image/ic_message.png);
+		background-size: 100%;
+		background-color: transparent;
+	}
+    .search_content{
+		height: 60upx;
+		border-radius: 35upx;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		background: #fff;
+		font-size: 24upx;
+		flex: 1;
+		
+		.search_icon {
+		  width: 24upx;
+		  height: 24upx;
+		  margin: 0 30upx;
+		}
+		.search_input {
+		  flex: 1;
+		  height: 60upx;
+		}
+	}
+	
+  }
+}
+
+
+.banner {
+	height: 380upx;
+	overflow: hidden;
+  .swiper {
+    height: 100%;
+    width: 100%;
+    image {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+.ad_banner{
+	image{
+		width: 100%;
+		display: block;
+		margin-bottom: 34upx;
+	}
+}
+.ad_goods_content{
+	margin: 0 20upx;
+	display: flex;
+	.ad_goods_left{
+		  flex:1;
+		  height:340upx;
+		  margin-right: 20upx;
+		  // background-color:#fff;
+			// border-radius:10px;
+			position: relative;
+			background-repeat: no-repeat;
+			background-size: 100% 100%;
+	}
+	.ad_goods_right{
+		flex:1;
+		height:340upx;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		.ad_goods_right_item{
+			height:160upx;
+			// background-color:#fff;
+			// border-radius:10px;
+			position: relative;
+			background-repeat: no-repeat;
+			background-size: 100% 100%;
+		}
+	}
+	.ad_goods_name{
+		font-size:36upx;
+		font-weight:800;
+		color:rgba(51,51,51,1);
+		position: absolute;
+		top:20upx;
+		left:20upx;
+	}
+	.ad_goods_caption{
+		font-size:22upx;
+		font-weight:400;
+		color:rgba(153,153,153,1);
+		margin-top: 10upx;
+		position: absolute;
+		top:60upx;
+		left:20upx;
+	}
+	.gotosee{
+		border-radius: 25upx;
+		height:50upx;
+		width:100upx;
+		font-size: 24upx;
+		text-align: center;
+		line-height: 50upx;
+		background-color: $dt-color-primary;
+		position: absolute;
+		bottom:20upx;
+		left:20upx;
+		color:#fff
+	}
+}
+
+.enIcon {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  align-items: center;
+  padding: 30upx 0upx;
+
+  .item {
+    width: 25%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 30upx;
+	
+	.item2{
+		display: flex;
+		justify-items: center;
+		align-items: center;
+		flex-direction: column;
+	}
+	// 客服按钮
+	.customer-service{
+		display: flex; 
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	  background-color:transparent;
+	  border:0;
+	}
+	
+    image {
+      width: 80upx;
+      height: 80upx;
+      // border-radius: 50%;
+    }
+	
+	.enIcon-btn-text{
+      font-size: 0.7rem;
+      margin-top: 10upx;
+	  line-height: 40upx;
+      color: #353535;
+	}
+
+    .enIcon-text {
+      margin-top: 10upx;
+      font-size: 0.7rem;
+      color: #353535;
+    }
+  }
+}
+.menu_scroll{
+	position:sticky;
+	z-index:9;
+	white-space: nowrap;
+	background-color: #f2f2f2;
+	width: 100%;
+	.menu_type{
+		display: flex;
+		height:110upx;
+		padding-top: 20upx;
+		align-items: center;
+		.type_item{
+			text-align: center;
+			flex:1;
+			font-size:28upx;
+		}
+		.type_item_active{
+			text-align: center;
+			flex:1;
+			font-size:28upx;
+			color:#DB4444;
+		}
+		.type_item_active_line{
+			width:95upx;
+			height:5upx;
+			background: $dt-color-primary;
+			margin: 0 auto;
+		}
+	}
+}
+
+.coupon_mengban{
+	transition: all 3s ease;
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	right:0;
+	left:0;
+	background-color: rgba(0,0,0,0.7);
+	z-index: 1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	z-index: 9;
+	.coupon {
+		width: 650upx;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	  .scroll {
+		  width: 425upx;
+		  top: 60upx;
+		  bottom: 250upx;
+		  position: absolute;
+	    .coupon_box {
+	      .coupon_item {
+	        position: relative;
+	        height: 120upx;
+			margin-bottom: 5upx;
+	        // padding: 0 15upx;
+	        .coupon_img {
+	          width: 420upx;
+	          height: 120upx;
+	        }
+	
+	        .coupon_info {
+	          position: absolute;
+	          top: 50%;
+	          right: 0upx;
+			  text-align: center;
+	          width: 150upx;
+	          text-align: center;
+	          transform: translate(0, -50%);
+	          color: #d73024;
+				font-weight: bold;		
+	          .coupon_amount {
+	            font-size: 40upx;
+	          }
+	
+	          .coupon_unit {
+	            font-size: 20upx;
+	          }
+	        }
+	
+	        .coupon_name {
+	          color: #d73024;
+	          font-size: 30upx;
+			  font-weight: bold;
+			  margin-bottom: 20upx;
+	        }
+	      }
+	
+	      .coupon_more {
+	        display: flex;
+	        flex-direction: row;
+	        align-items: center;
+	        padding: 0 30upx;
+	
+	        .more_text {
+	          font-size: 22upx;
+	          color: #999;
+	          width: 60upx;
+	          text-align: center;
+	          margin-right: 10upx;
+	        }
+	
+	        image {
+	          width: 10upx;
+	          height: 18upx;
+	        }
+	      }
+	    }
+	  }
+	  .ic_off{
+		  width: 50upx;
+		  height: 50upx;
+		  position: absolute;
+		  bottom: -100upx;
+		  z-index:10
+	  }
+	}
+}
+
+
+.line {
+  width: 100%;
+  height: 20upx;
+  background: #f2f2f2;
+}
+.everyDay{
+	height:210upx;
+	border-radius: 20upx;
+	background-repeat: no-repeat;
+	background-size: 100% 100%;
+	padding-top: 80upx;
+}
+.bubble{
+	position: absolute;
+	top: -28upx;
+	right: 20upx;
+	width: 50upx;
+	height: 28upx;
+	background-size: 100% 100%;
+	background-repeat: no-repeat;
+	color: #fff;
+	font-size: 16upx;
+	text-align: center;
+	line-height: 28upx;
+	float: right;
+}
+
+.bubble-red{
+	background-image: url("http://139.9.103.171:1888/img/image/bubble_red.png");
+}
+.bubble-yellow{
+	background-image: url("http://139.9.103.171:1888/img/image/bubble_yellow.png");
+}
+
+</style>

+ 1237 - 0
pages/life/life1.vue

@@ -0,0 +1,1237 @@
+<template>
+<view style="background-color: #f2f2f2;">
+	<DtCustomBar class="DtCustomBar" title="品质生活" :background="headColor"></DtCustomBar>
+  <view :style="{display:show}">
+	<view class="head" :style="{background:headColor}">
+	  <!-- <view class="address">
+		<image src="/static/image/address_icon.png"></image>
+		<text class="address_text">{{companyAddress}}</text>
+	  </view> -->
+	  <view style="display: flex;align-items: center;margin-bottom: 20upx;padding-top: 10rpx;">
+		  <image src="/static/icon/location.png" style="width: 38upx;height: 38upx;" mode="widthFix"></image>
+		  <text style="color: #fff;font-size: 30upx;margin-left: 10upx;">{{plotName}}</text>
+	  </view>
+	  <view class="search" >
+		<!-- <image class="icon" src="/static/image/ic_type.png" mode="" @tap="tapTocategory"></image> -->
+		<view class="search_content" @tap="jumpSearch()">
+			<image class="search_icon" src="http://139.9.103.171:1888/img/image/search_icon.png" mode="aspectFit"></image>
+			<input class="search_input" placeholder="请输入搜索的商品" placeholder-style="color:#ccc;" disabled />
+		</view>
+		<!-- <view @tap="claimGoods" style="margin-left: 20upx;display: flex;flex-direction: column;justify-content: center;align-items: center;">
+			<image class="icon" src="/static/image/ic_yard.png" mode="aspectFit"></image>
+			<view style="color: #fff;font-size: 20upx;margin-top: 5upx;">快速取货</view>
+		</view> -->
+		<!-- <button class="icon_message" type="default" open-type="contact"></button> -->
+	  </view>
+	  <ScrollMenu></ScrollMenu>
+	</view>
+   
+	<view style="margin: -110upx 20upx 0;">
+		<view class="banner">
+		   <swiper 
+		   class="swiper" 
+		   interval="5000" 
+		   duration="500" 
+		   autoplay="true" 
+		   circular="true"
+			:indicator-dots="adsList.length>1"
+		   indicator-color="rgba(153,153,153,1)" 
+		   indicator-active-color="#FFF"
+		   @change="switchColor">
+			 <swiper-item v-for="(item,index) in adsList" :key="index">
+			   <image class="image" mode="aspectFill" :src="item.path" @tap="tapNav(item)"></image>
+			 </swiper-item>
+		   </swiper>
+		 </view>
+		<view>
+			 <image class="imgs" v-for="(item,index) in topAds" :key="index" :src="item.path" mode="widthFix" style="width: 100%;display: block;margin-top: 30upx;" @tap="jumpPromotion(item,index)"></image>
+		 </view>
+			<ls-swiper :lists="headNavList" :swiperType="nav" imgKey="imgUrl" :loop="false" :dots="false" :autoplay='false' :height="380" />
+			<view style="background-image: linear-gradient(#f2f2f2, #fff);flex:1;position: relative;">
+				<!-- <view style="position: absolute;left: 50%;top: 18upx;transform: translateX(-50%);font-size: 32upx;color: #653C00;font-weight: bold;">每日爆款</view> -->
+				<view v-if="index==0" v-for="(item,index) in indexProduct" :key="index" @tap="onMore(item)" class="everyDay" :style="{backgroundImage: 'url('+(item.path1?item.path1:'')+')'}">
+					<scroll-view scroll-x="true" >
+						<view style="display: flex;width: 100%;margin-left: 20upx;">
+							<view style="display: flex;">
+								<view v-for="(child,idx) in item.products" :key="idx" @tap.stop="jumpGoodsDes(child.id)" style="padding: 6upx 14upx;height: 158upx;border-radius: 20upx;background-color: #fff;margin-right: 8upx;display: flex;flex-direction: column;justify-content: center;align-items: center;">
+									<image :src="child.thumbnail" mode="aspectFit" style="width:136upx;height:136upx;"></image>
+									<view style="min-width: 76upx;font-size: 28upx;font-weight: bold;color:#fff;text-align: center;border-radius: 25px;background-color: #E42F2F;padding: 0 4upx;">
+									<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+								</view>
+								<view style="width: 12upx;"></view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+			<view style="display: flex;border-bottom: 2upx solid #f7f7f7;">
+				<view v-if="index==1||index==2" v-for="(item,index) in indexProduct" :key="index"  @tap="onMore(item,item.name,index)" style="width: 314upx;padding: 40upx 20upx 20upx;background-color: #fff;border-right: 2upx solid #f7f7f7;">
+					<view style="font-size: 28upx;font-weight: bold;">{{item.name}}</view>
+					<view style="font-size: 20upx;color:#999999;margin-top: 10upx;">{{item.memo}}</view>
+					<scroll-view scroll-x="true">
+						<view style="display: flex;width: 100%;">
+							<view  v-for="(child,idx) in item.products" :key="idx" >
+								<image :src="child.thumbnail" style="width:148upx;height:148upx;margin:20upx 0;background-color:#f7f7f7"></image>
+								<view style="font-size: 28upx;font-weight: bold;color:#E42F2F;text-align: center;">
+								<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+<!-- 			<view style="display: flex;border-bottom: 2upx solid #f7f7f7;">
+				<view v-if="index==1||index==2" v-for="(item,index) in indexProduct" :key="index"  @tap="onMore(item,item.name,index)"  style="width: 360upx;padding: 40upx 20upx 20upx;background-color: #fff;border-right: 2upx solid #f7f7f7;">
+					<view style="font-size: 28upx;font-weight: bold;">{{item.name}}</view>
+					<view style="font-size: 20upx;color:#999999;margin-top: 10upx;">{{item.memo}}</view>
+					<scroll-view scroll-x="true">
+						<view style="display: flex;width: 100%;">
+							<view  v-for="(child,idx) in item.products" :key="idx" >
+								<image :src="child.thumbnail" style="width:148upx;height:148upx;margin:20upx 0;background-color:#f7f7f7"></image>
+								<view style="font-size: 28upx;font-weight: bold;color:#E42F2F;text-align: center;">
+								<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view> -->
+			<!-- <view>
+				<view  v-for="(item,index) in centerAd" :key="index" @tap="jumpPromotion(item,index)" style="margin-top: 20upx;">
+					<image :src="item.path" mode="widthFix" style="width: 100%;display: block;"></image>
+				</view>
+				<view style="display: flex;justify-content: space-between;">
+					<view  v-for="(item,index) in twoAds" :key="index" @tap="jumpPromotion(item,index)" style="flex:1">
+						<image :src="item.path" mode="widthFix" style="width: 100%;display: block;"></image>
+					</view>
+				</view>
+			</view> -->
+			<view style="display: block;margin-bottom: 20upx;">
+				<view v-if="index==3" v-for="(item,index) in indexProduct" :key="index" style="background-color: #fff;padding: 40upx 20upx 25upx;border-bottom-left-radius: 20upx;border-bottom-right-radius: 20upx;">
+					<view style="display: flex;justify-content: space-between;">
+						<view>
+							<view style="font-size: 28upx;font-weight: bold;">{{item.name}}</view>
+							<view style="font-size: 20upx;margin-top: 10upx;color: #999;">{{item.memo}}</view>
+						</view>
+						<view @tap="onMore(item)" style="display: flex;align-items: center;height: 35upx;">
+							<view style="font-size: 20upx;">查看更多</view>
+							<image src="http://139.9.103.171:1888/img/image/ic_more.png" mode="aspectFit" style="width: 16upx;height: 16upx;margin-left: 5upx;"></image>
+						</view>
+					</view>
+					<scroll-view scroll-x="true">
+						<view style="width: 100%;display: flex;">
+							<view v-for="(child,idx) in item.products" :key="idx" @tap="jumpGoodsDes(child.id)" style="padding: 0 3upx;height: 232upx;border-radius: 20upx;background-color: #fff;margin-top:20upx;margin-right: 20upx;display: flex;flex-direction: column;justify-content: center;align-items: center;">
+								<view :style="idx==0||idx==1?'backgroundColor:#FFE6E6;border-radius:10upx':'backgroundColor:#FFF3E6;border-radius:10upx'" >
+									<image :src="child.thumbnail" mode="widthFix" style="width:148upx;height:148upx;display: block;"></image>
+								</view>
+								<view v-if="idx==0||idx==1" style="min-width: 76upx;font-size: 28upx;font-weight: bold;color:#fff;text-align: center;margin-top: 20upx;border-radius: 25px;background-color: #E42F2F;padding: 0 4upx;">
+									<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+								<view v-else style="min-width: 76upx;font-size: 28upx;font-weight: bold;color:#fff;text-align: center;margin-top: 20upx;border-radius: 25px;background-color: #FFD062;padding: 0 4upx;">
+								<view style="display: inline-block;font-size: 16upx;margin-top: 8upx;">¥</view>{{child.price}}</view>
+							</view>
+							
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+	</view>
+		<scroll-view id="scrollView" class="menu_scroll" scroll-x="true" :scroll-left="scrollLeft" :style="{top:DtCustomBarHeight+'px'}">
+			<view class="menu_type" >
+				<view  v-for="(item,index) in bottomNavList" :key="index" :class="index==menu_index?'type_item_active':'type_item'"  @tap="tapGoodsList(item,index)" >
+					<view style="font-weight:bold;position: relative">
+						<view 
+						v-if="index==0||index==1"
+						class="bubble bubble-red">自提</view>
+						<view
+						v-if="index==2||index==3"
+						class="bubble bubble-yellow">包邮</view>
+						{{item.name}}
+					</view>
+					<view style="font-size: 20upx;color: #999999;margin-top: 10upx;">{{item.memo}}</view>
+					<!-- <view :class="index==menu_index?'type_item_active_line':''"></view> -->
+				</view>
+			</view>
+		</scroll-view>
+	<!-- <view :style="isTop==1? 'display: block':'display:none'" class="topHeight"></view> -->
+	<swiper  :current="menu_index" duration="300" @change="switchTab" :style="{height:product_unit_height}">
+	   <swiper-item  v-for="(item,index) in bottomNavList" :key="index">
+		   <view class="bottom_goods_list">
+			 <!-- <DtGoodsListHome :dataList="item.products"/> -->
+			 <DtGoodsListHome02 :dataList="item.products"/>
+		   </view>
+	   </swiper-item>
+	 </swiper>
+	
+	<!-- <view class="enIcon">
+	  <view v-for="(item,idx) in navList" :key="idx" class="item">
+		<button v-if="item.funcType == 8" class="customer-service" open-type="contact" session-from="weapp">
+			<image :src="item.path"></image>
+			<text class="enIcon-btn-text">{{item.name}}</text>
+		</button>
+		<view class="item2" v-else  @tap="tapGoodsList(item)">
+			<image :src="item.path"></image>
+			<view class="enIcon-text">{{item.name}}</view>
+		</view>
+	  </view>
+	</view> -->
+	<!-- <view class="ad_banner" v-for="(item,index) in adsList" :key="index">
+		<image mode="widthFix" :src="item.path" @tap="tapNav(item)"></image>
+	</view> -->
+	<!-- <view  v-for="(item,idx) in indexProduct" :key="idx">
+	   <view class="goods_list">
+		 <DtUnitHead :title="item.name" :memo="item.memo" @more="onMore(item)" />
+		 <DtGoodsListH :dataList="item.products" :dataItem="item" @more="onMore(item)"/>
+	   </view>
+	</view>
+	<view  v-for="(item,idx) in navTabsList" :key="idx">
+		<view v-if="item.layout==0" class="goods_list">
+			 <DtUnitHead :title="item.name" :memo="item.memo" @more="onMore(item)" />
+			 <view class="ad_goods_content">
+				  <view v-if="cidx==0"  class="ad_goods_left" v-for="(citem,cidx) in item.tagGroups" :key="cidx" :style="{backgroundImage: 'url('+(citem.path1?citem.path1:'')+')'}" @tap="onMore(citem)">
+				  </view>
+				  <view class="ad_goods_right">
+					  <view v-if="cidx==1||cidx==2" v-for="(citem,cidx) in item.tagGroups" :key="cidx" class="ad_goods_right_item" :style="{backgroundImage: 'url('+(citem.path1?citem.path1:'')+')'}" @tap="onMore(citem)">
+					  </view>
+				  </view>
+			 </view>
+		</view>
+		<view v-if="item.layout==1" class="goods_list">
+			 <DtUnitHead :title="item.name" :memo="item.memo" @more="onMore(item)" />
+			 <DtGoodsListH v-if="item.tagGroups" :dataList="item.tagGroups" :dataItem="item" @more="onMore(item)"/>
+		</view>
+	</view> -->
+	
+	<!-- <view v-if="idx==0" v-for="(item,idx) in indexProduct" :key="idx">
+	   <view class="goods_list">
+		 <DtUnitHead :title="item.name" @more="onMore(item)" />
+		 <view class="ad_goods_content">
+			  <view v-if="cidx==0"  class="ad_goods_left" v-for="(citem,cidx) in item.products" :key="cidx" :style="{backgroundImage: 'url('+citem.thumbnail+')'}" @tap="jumpGoodsDes(citem.id)">
+				 <view class="ad_goods_name">{{citem.name}}</view>
+				 <view class="ad_goods_caption">{{citem.caption}}</view>
+				<view class="gotosee">去看看</view>
+			  </view>
+			  <view class="ad_goods_right">
+				  <view v-if="cidx==1||cidx==2" v-for="(citem,cidx) in item.products" :key="cidx" class="ad_goods_right_item" :style="{backgroundImage: 'url('+citem.thumbnail+')'}" @tap="jumpGoodsDes(citem.id)">
+					  <view class="ad_goods_name">{{citem.name}}</view>
+					  <view class="gotosee">去看看</view>
+				  </view>
+			  </view>
+		 </view>
+	   </view>
+	</view>-->
+	
+	
+   <view v-if="couponList.length>0&&couponShow" class="coupon_mengban">
+	   <view class="coupon"  @tap="tapToCoupon">
+		   <image src="http://139.9.103.171:1888/img/image/coupon_bg.png" mode="widthFix" style="width: 650upx;height: 680upx;" ></image>
+		   <image class="ic_off" src="http://139.9.103.171:1888/img/image/ic_coupon_off.png" mode="widthFix" @tap.stop="close_coupon"></image>
+		  <scroll-view class="scroll" scroll-y="true">
+			<view class="coupon_box">
+				<!-- @tap="tapDrawCoupon(item,index)" -->
+			  <view class="coupon_item" v-if="index<2" v-for="(item,index) in couponList" :key="index">
+				<image class="coupon_img" src="http://139.9.103.171:1888/img/image/coupon_img_white.png"></image>
+				<view class="coupon_info">
+				  <text class="coupon_unit">¥</text>
+				  <text class="coupon_amount">{{item.amt}}</text>
+				</view>
+				<view style="position: absolute;width: 255upx;top: 0;bottom:0;left: 10upx;display: flex;flex-direction: column;justify-content: center;">
+					<view class="coupon_name dt-text-row-one">{{item.name}}</view>
+					<view class="dt-text-row-one" style="font-size: 16upx;color: #999999;">
+						有效日期:{{item.beginDate}}至{{item.endDate}}
+					</view>
+				</view>
+			  </view>
+			 
+			 <!-- <view v-if="couponList.length>2" class="coupon_more" @tap="tapToCoupon">
+				<view class="more_text">查看更多</view>
+				<image src="/static/image/arrow.png"></image>
+			  </view> -->
+			</view>
+		  </scroll-view>
+		</view>
+   </view> 
+	<image
+	 v-if="couponList.length>0"
+	src="http://139.9.103.171:1888/img/image/ic_hongbao.png" 
+	mode="widthFix"
+	 @tap="tapToCoupon"
+	style="position: fixed;right: 0;bottom: 50upx;width: 150upx;"></image>
+	<!-- 商品单元列表 -->
+	<!-- <view v-for="(item,idx) in product" :key="idx"
+	  class="product-unit">
+	  <DtUnitHead :title="item.name" @more="onMore(item)" />
+	  <DtGoodsListH :dataList="item.products" />
+	  <view class="line"></view>
+	</view> -->
+	
+	  
+	<!-- 微信客服 -->
+	<!-- <DtService /> -->
+
+  </view>
+  <DtEmpty :type="emptyType" />
+
+  <DtLogin ref="dialogLogin" @signIn="onSignIn" />
+  <!-- <view style="display: flex;flex-direction: column;align-items: center;justify-content: center;font-size: 16px;height: 100vh;">
+	  <view style="font-weight: bold;margin-bottom: 18rpx;">小程序已迁移</view>
+	  <navigator style="padding: 10rpx 20rpx;background-color: green;border-radius: 6rpx;color: #fff;" target="miniProgram" open-type="navigate" app-id="wx90680ffd54c3b96c" path="/pagesM/pages/home" extra-data="" version="release">点我前往新的小程序</navigator>
+  </view> -->
+  
+ <view  style="height: 80rpx;background-color: #F1F1F1;display: flex;justify-content: center;color: #909399;align-items: center;">
+	 <text>没有更多了</text>
+  </view>
+<!--  <view class="text-center  margin-top-10" style="font-size: 26rpx;color: #909399;background-color: #FFFFFF;padding: 22rpx;" >
+	<text>到底了</text>
+  </view> -->
+  
+</view>
+</template>
+
+<script>
+import ScrollMenu from "@/comps/scroll_menu.vue"
+import DtLogin from '@/comps/dt_login.vue'
+import DtEmpty from '@/comps/dt_empty.vue'
+import DtUnitHead from '@/comps/dt_unit_head_v2.vue'
+import DtGoodsListH from '@/comps/dt_goods_list_h.vue'
+import lsSwiper from '@/comps/mosowe-swiper.vue'
+// import DtService from '@/comps/dt_service.vue'
+import DtGoodsListHome from '@/comps/dt_goods_list_home.vue'
+import DtGoodsListHome02 from '@/comps/dt_goods_list_home02.vue'
+import DtCustomBar from '@/comps/dt_custom_bar.vue'
+export default {
+  components: {
+    DtLogin,
+    DtEmpty,
+    DtUnitHead,
+    // DtService,
+    DtGoodsListH,
+	lsSwiper,
+	DtGoodsListHome,
+	ScrollMenu,
+	DtCustomBar,
+	DtGoodsListHome02
+  },
+  data() {
+    return {
+		plotName:'暂无小区信息',
+		nav:'nav',
+      companyAddress: '',
+
+      adsList: [], //广告动态
+
+      indexProduct:[], // 店铺热卖,店铺推荐....
+      couponList: [],
+
+      navList: [], // 导航列表
+      memberId: '',
+	  navTabsList:[],
+	  menu_index:0, //tab index
+	  scrollLeft:0, 
+	  isTop:0, 
+	  myScroll:0, 
+	  product_unit_height:1000 + 'px',
+	  show:'block',
+	  headNavList:[],
+	  bottomNavList:[],
+	  headColor:'#D43A39',
+	  startSwitchColor:true,
+	  organizationList:{},
+	  twoAds:[], //中部会场(两行一列)
+	  centerAd:[],
+	  topAds:[], //顶部会场
+	  DtCustomBarHeight:0,
+	  couponShow:true
+    }
+  },
+  mounted(){
+	  // 获得初始距离顶部高度
+	this.$nextTick(function(){
+		const query = uni.createSelectorQuery().in(this);
+		query.select('.DtCustomBar').boundingClientRect(data => {
+			  this.DtCustomBarHeight = data.height
+		}).exec();
+	})
+  },
+
+ // 判断是否吸顶
+  onPageScroll:function(e){
+	  this.getSwiperHeight();
+	 //  if(e.scrollTop>=this.myScroll){
+		// this.isTop = 1;
+	 //  }else{
+		// this.isTop = 0;
+	 //  }
+	 
+	 const query = uni.createSelectorQuery().in(this);
+	 query.select('#scrollView').boundingClientRect(data => {
+	   if(data.top==this.DtCustomBarHeight){
+			this.isTop = 1
+	   }else{
+		   this.isTop = 0;
+		   this.myScroll = 0;
+	   }
+	 }).exec();
+	 if(this.isTop==1&&this.myScroll==0){
+		 this.myScroll =  e.scrollTop;
+	 }
+  },
+  methods: {
+	  // 跳转搜索
+	  jumpSearch(item) {
+		  console.log(item)
+	    if (!item) {
+	      uni.navigateTo({
+	        url: "/pagesM/pages/search"
+	      })
+	    } else {
+	      let params = {
+	        keyword: item.name,
+	        productCategoryId: item.id
+	      }
+	      uni.navigateTo({
+	        url: "/pagesM/pages/search?" + this.$util.serialize(params)
+	      })
+	    }
+	  },
+	  switchColor(e){
+		  switch(e.detail.current){
+			  case 0:this.headColor = '#D43A39';
+			  break;
+			  case 1:this.headColor = '#98cb5b';
+			  break;
+			  case 2:this.headColor = '#4f85b2';
+		  }
+	  },
+	  claimGoods(){
+		  uni.navigateTo({
+		    url: "claim_goods"
+		  })
+	  },
+	  
+	  openNearbyTeam(){
+		  uni.navigateTo({
+		    url: "/pagesM/pages/nearby_team"
+		  })
+	  },
+	  jumpGoodsDes(id) {
+	    uni.navigateTo({
+	      url: "/pagesM/pages/goods_des?id=" + id
+	    })
+	  },
+	  //动态设置height
+	  getSwiperHeight(){
+		  const query = uni.createSelectorQuery().in(this);
+		  query.selectAll(".bottom_goods_list").boundingClientRect();
+			query.exec((res) => {
+				this.product_unit_height =res[0][this.menu_index].height+'px'
+			})
+	  },
+	  switchTab(e){
+		 //  //判断吸顶之后才返回到滚动起始位置
+		  if(this.isTop == 1){
+			  uni.pageScrollTo({
+	        duration:0,//过渡时间必须为0,uniapp bug,否则运行到手机会报错
+	        scrollTop:this.myScroll,
+	      })
+		  }
+		 //  if(e.detail.current>4){
+			//   this.scrollLeft = 300
+		 //  }else{
+			//   this.scrollLeft = 0
+		 //  }
+		  this.menu_index = e.detail.current
+		  this.getSwiperHeight();
+	  },
+	  tapNav(item){
+		let type = item.type; //0:文本广告,1:图片广告 2:会场广告
+		if([0,"0"].includes(type)&&item.content){
+			uni.navigateTo({
+			  url: '/pagesM/pages/common/ad_textView?content=' + item.content
+			});
+		}else if([1,"1"].includes(type)&&item.productId){
+			uni.navigateTo({
+			  url: '/pagesM/pages/goods_des?id=' + item.productId
+			});
+		}else if([2,'2'].includes(type)&&item.url){
+			let  url = item.url;
+			if (this.memberId){
+				 url = url + this.memberId;
+				 console.log('banner 链接 = ' + url)
+				 uni.navigateTo({
+				   url: '/pagesM/pages/common/webview?url=' + encodeURIComponent(url)
+				 });
+			}
+		}  
+	 },
+    jumpPromotion(item,specialType){
+		let type = item.type; //0:文本广告,1:图片广告 2:会场广告
+		if([0,"0"].includes(type)&&item.content){
+			uni.navigateTo({
+			  url: '/pagesM/pages/common/ad_textView?content=' + item.content
+			});
+		}else if([1,"1"].includes(type)&&item.productId){
+			uni.navigateTo({
+			  url: '/pagesM/pages/goods_des?id=' + item.productId
+			});
+		}else if([2,'2'].includes(type)&&item.url){
+			// uni.navigateTo({
+			  //   url: "../comps/dt_special?url="+item.url+"&title="+item.title+"&style="+type
+			  // })
+			  uni.navigateTo({
+				url: "/pagesM/comps/promotion_detail?url="+item.url+"&title="+item.title+"&style="+specialType
+			  })
+		}
+    		  
+    },
+	tapTocategory(){
+		uni.navigateTo({
+			url:"/pagseM/pages/category"
+		})
+	},
+    showLogin() {
+      this.$refs.dialogLogin.show()
+    },
+    // 登录成功响应事件
+    onSignIn(resp) {
+      // console.log(143, resp)
+      this.$util.refreshPage(['pages/home', 'pages/shop_car'])
+      this.onPullDownRefreshPage()
+    },
+
+    onMore(item,name,theme) {
+      let params = item.param;
+	  if(name){
+		  uni.navigateTo({
+		    url: "/pagesM/pages/goods_list?params=" + JSON.stringify(params) + '&name=' + name + '&hideTop=true' + '&theme=' + theme + '&path=' + item.path1
+		  })
+	  }else{
+		  uni.navigateTo({
+		    url: "/pagesM/pages/goods_list?params=" + JSON.stringify(params)
+		  })
+	  }
+      
+    },
+
+    
+	close_coupon(){
+		this.couponShow = false;
+	},
+    // 领取优惠券
+    async tapDrawCoupon(item, index) {
+      // 领取优惠券需要登录
+      if (!this.isLogin) {
+        this.showLogin()
+        return
+      }
+      console.log('get Voucher', item)
+      try {
+        let resp = await this.$api.couponExchange({
+          _isShowLoading: true,
+          _isReject: true,
+          memberId: this.memberId,
+          couponId: item.id
+        })
+        if (resp.result) {
+          this.$dialog.success('领取成功')
+          item.isReceive = true
+          this.$set(this.couponList, index, item)
+        } else {
+          this.$dialog.error('领取失败')
+        }
+      } catch (err) {
+        // if(err.sysflag === '4010' && err.errmsg === '您已经领取过了'){
+        //   this.$dialog.success('领取成功')
+        //   item.isReceive = true
+        //   this.$set(this.couponList, index, item)
+        // }else{
+        this.$dialog.alert({
+          content: err.errmsg || '领取失败'
+        })
+        // }
+      }
+		this.close_coupon();
+    },
+    // 跳转优惠券
+    tapToCoupon() {
+      uni.navigateTo({
+        url: "/pagesM/pages/coupon_center"
+      })
+    },
+
+    // 商品列表
+    tapGoodsList(item,idx) {
+		this.menu_index = idx;
+		// var list = [];
+		// for(let i in this.indexProduct){
+		// 	if(item.name==this.indexProduct[i].name){
+		// 		list.push(this.indexProduct[i]);
+		// 	}
+		// }
+		// if(this.product.length>0){
+		// 	this.product.splice(0,this.product.length)
+		// }
+		// if(list){
+		// 	this.product = list.concat()
+		// }
+		
+		// if(item.id == null){
+		// 	if(item.type == "customerService"){
+				
+		// 	}
+		// }else{			
+		//   // let idx =
+		//   // console.log(170,item) 
+		//   let params = ''
+		//   if (item.param) {
+		// 	// console.log(176,[item.param])
+		// 	// params = JSON.stringify([item.param])
+		// 	params = JSON.stringify(item.param);
+		//   }
+		//   uni.navigateTo({
+		// 	url: '/pages/goods_list?params=' + params
+		//   })
+		// }
+    },
+
+   //  async homeNavAds(){
+   //    let resp = await this.$api.homeNavAds();
+	  // // this.homeNavAds = resp;
+	  // return resp
+   //  },
+
+    //获取公司介绍 地址
+    async lookIntroduction() {
+      let company = await this.$api.lookIntroduction();
+      this.companyAddress = company.intelligence.companyAddress;
+      return company
+    },
+   
+    // //查找店铺商品分类
+    // async getStoreProductCategorys() {
+    //   let productCategoryList = await this.$api.getStoreProductCategorys();
+    //   if(productCategoryList){
+    //     let plen = productCategoryList.length
+    //     if(plen<=2 && plen>0){
+    //       this.getProductChildrenCategorys();
+    //     }else if(plen > 2){
+    //       this.tabList = productCategoryList;
+    //     }else{
+    //       this.tabList = [];
+    //     }
+    //   }else{
+    //     this.tabList = [];
+    //   }
+    // },
+    // // 查找子分类
+    // async getProductChildrenCategorys() {
+    //   let data = {};
+    //   data.id = this.tabList[0].id;
+    //   let childrenCategorys = await this.$api.getProductChildrenCategorys(data);
+    //   this.tabList = childrenCategorys || [];
+    // },
+
+    //店铺首页 广告、导航菜单、公司信息
+    async storeHomeNavAds() {
+      let index = await this.$api.storeHomeNavAds();
+      this.adsList = index.carousel;
+      this.navList = index.navigation;
+	  this.twoAds.splice(0,this.twoAds.length);
+	  index.twoAds.map((item,index)=>{
+		  if(index!==0){
+			  this.twoAds.push(item)
+		  }
+	  })
+	  this.centerAd.splice(0,this.centerAd.length);
+	  this.centerAd.push(index.twoAds[0]);
+	  this.topAds.splice(0,this.topAds.length);
+	  this.topAds.push(index.ads[0])
+      return index;
+    },
+
+    // 获取可兑换优惠券,前端隐藏已领取的优惠券
+    async getCouponByStoreId() {
+      let resp = await this.$api.getHasExchangeCoupons({
+        memberId: this.memberId
+      });
+      let list = resp || []
+      list = list.slice(0, 3)
+      if (this.isLogin) {
+        list = list.filter((item) => {
+          return !item.isReceive
+        })
+      } else { // 未登录全部显示未领取
+        list.map((item) => {
+          item.isReceive = false
+          return item
+        })
+      }
+      this.couponList = list
+      return resp
+    },
+	async getStoreHomeNavTags(){
+		let resp  = await this.$api.storeHomeNavTags();
+		// this.navTabsList = resp;
+		if(resp.length>0){
+			this.headNavList.splice(0,this.headNavList.length);
+			  resp.map((item)=>{
+				   if(item.name=="中部导航-社区自取"){
+					   this.headNavList.push(item)
+				   }
+			  })
+			  if(this.headNavList[0].tagGroups.length>9){
+				  let obj = {}
+				  let tagGroups = []
+				  this.headNavList[0].tagGroups.map((item,index)=>{
+					  if(index>9){
+						  tagGroups.push(item)
+					  }
+				  })
+				  obj['tagGroups'] = tagGroups
+				  this.headNavList.push(obj)
+				  this.headNavList[0].tagGroups.length = 11
+			  }
+		}
+		return resp
+	},
+    //首页产品-店铺热卖-店铺推荐
+    async storeHomeProducts() {
+      let indexProduct = await this.$api.storeHomeProducts();
+		if(indexProduct.length>0){
+			 this.indexProduct.splice(0,this.indexProduct.length);
+			this.bottomNavList.splice(0,this.bottomNavList.length);
+			this.indexProduct = indexProduct;
+			this.bottomNavList = indexProduct;
+		}
+		
+      return indexProduct
+    },
+    async touristLogin() {
+      // 检查是否登录
+      this.isLogin = this.$auth.isAuth
+      if (!this.$auth.isAuth) { // 就算是游客,也重新登录
+        console.log('需要使用游客身份,执行游客登录!')
+        let resp = await this.$api.touristLogin()
+        let userType = this.$global.userType.tourist
+        this.$auth.login(userType, resp.sessionId, resp.userId, resp)
+        console.log('游客登录成功!', resp)
+      } else {
+        console.log(`已登录!`)
+        	this.$refs.dialogLogin.hide();
+      }
+    },
+	async getProductCategorys() {
+	  let resp = await this.$api.getProductCategorys();
+	  console.log(resp)
+	  if(resp.length>0){
+	  	this.headNavList.splice(0,this.headNavList.length);
+		let obj = {};	
+		let tagGroups = [];
+	  	  resp.map((item,index)=>{
+			  let childObj = {
+				  path1:item.icon,
+				 name:item.name,
+				 id:item.id
+			  }
+			  tagGroups.push(childObj)
+			  obj['tagGroups'] = tagGroups
+			
+	  	  })
+		  this.headNavList.push(obj)
+	  	  if(this.headNavList[0].tagGroups.length>10){
+	  		  let obj = {}
+	  		  let tagGroups = []
+	  		  this.headNavList[0].tagGroups.map((item,index)=>{
+	  			  if(index>9){
+	  				  tagGroups.push(item)
+	  			  }
+	  		  })
+	  		  obj['tagGroups'] = tagGroups
+	  		  this.headNavList.push(obj)
+	  		  this.headNavList[0].tagGroups.length = 10
+	  	  }
+	  }
+	  console.log(this.headNavList)
+	  return resp;
+	},
+    async loadData() {
+	  // wx.hideShareMenu();
+      this.$dialog.showLoading('加载中...')
+      await this.$nextTick(function(){
+      	 this.touristLogin()
+      })
+      this.memberId = this.$auth.getMemberId();
+	  
+	  console.log(this.memberId)
+	  
+	  //从缓存中获取小区信息
+	  this.plotName=uni.getStorageSync("plotName") || '暂无小区信息'
+	  
+      let list = []
+	  // list.push(this.getOrganizationList());//附近团
+      // list.push(this.homeNavAds()); //广告位
+      list.push(this.lookIntroduction()); // 获取定位地址
+      // list.push(this.getStoreProductCategorys()); // 分类
+      list.push(this.getProductCategorys());//产品分类
+      list.push(this.storeHomeNavAds()); // 轮播广告导航
+      list.push(this.getCouponByStoreId()); // 优惠券
+      list.push(this.storeHomeProducts()); // 产品 
+		// list.push(this.getStoreHomeNavTags()); //店铺首页 导航标签组
+      Promise.race(list).then((resList) => {
+        console.log(255, resList)
+      }).catch(err => {
+        consle.log(err)
+      }).finally(() => {
+        this.emptyType = 0
+		if(this.emptyType==0){
+			this.show = 'block'
+		}else{
+			this.show = 'none'
+		}
+        this.$dialog.hideLoading()
+      })
+    },	
+		getParam(e){
+			// 用来保存所有的属性名称和值
+			let param = "";
+			// 开始遍历
+			for(let p in e){
+				// 方法
+				if(typeof(e[p])!="function" && p != 'type'){
+					// p 为属性名称,e[p]为对应属性的值
+					param += (param.length > 1 ? '&' : '') + p + "=" + e[p];
+				}
+			}
+			// 最后显示所有的属性
+			return param;
+		},
+		execParam(){
+			let _this = this;
+			if(this.e != null){
+				setTimeout(function(){
+					if(_this.e == null) return;
+					if(_this.e.type == "share"){
+						let path = _this.e.path == null || _this.e.path.length <= 0 ? 'pagesM/pages/goods_des' : '/' + _this.e.path;
+						let param = _this.getParam(_this.e);
+						let url = `${path}?${param}`;
+						console.error("url = " + url);
+						_this.e = null;
+						uni.navigateTo({url: url});
+					}
+				}, 1000);
+			}
+		},
+		async getOrganizationList(){
+			let resp = await this.$api.getOrganizationList({
+			  _isPull: this.isPull,
+			  pageNo: 1,
+			  pageSize: 1
+			});
+			this.organizationList = resp[0];
+		},
+	},
+
+	onShow() {
+		this.execParam();
+		this.onShowPage();
+		this.loadData();
+	},
+	onLoad(e) {
+		this.e = e;
+		console.log(e)
+		//二维码扫描链接 start
+		if(e != null && e.q != null){
+			let url = decodeURIComponent(e.q);
+			let param = {};
+			// 把参数按&拆分成数组
+			let index = url.indexOf("?");
+			let query = url.substring(index+1,index.length);
+			var param_arr = query.split("&");
+			for (var i = 0; i < param_arr.length; i++) {
+			    var pair = param_arr[i].split("=");
+			    param[pair[0]]=pair[1];
+			}
+			if(param['type'] == "share"){
+				let path = 'pagesM/pages/goods_des';
+				let params = `id=${param['id']}&storeId=${param['storeId']}&inviteCode=${param['inviteCode']}`
+				let url = `${path}?${params}`;
+				console.error("url = " + url);
+				this.e = null;
+				uni.navigateTo({url: url});
+			}
+		}
+		//二维码扫描链接 end
+		this.execParam();
+		wx.showShareMenu({
+		  withShareTicket: true
+		})
+	},
+}
+</script>
+
+<style lang="scss" scoped>
+	.home{
+		// background-color: #fff;
+		// background-image: url(/static/image/home_bg.jpg);
+		// background-size: contain;
+		// background-repeat-y: repeat;
+	}
+.head {
+	padding: 0 20upx;
+	// height:300upx;
+	height: 250upx;
+	border-bottom-left-radius: 10%;
+	border-bottom-right-radius: 10%;
+	// transition: 0.5s linear all;
+  .address {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding: 24upx 0;
+    image {
+      width: 27upx;
+      height: 35upx;
+      padding-right: 20upx;
+    }
+
+    .address_text {
+      flex: 1;
+      font-size: 28upx;
+      color: #fff;
+      letter-spacing: 2upx;
+    }
+  }
+
+
+  .search{
+    height: 60upx;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+	.icon{
+		width: 32upx;
+		height: 32upx;
+	}
+	.icon_message{
+		width: 40upx;
+		height: 40upx;
+		// background-image: url(/static/image/ic_message.png);
+		background-size: 100%;
+		background-color: transparent;
+	}
+    .search_content{
+		height: 60upx;
+		border-radius: 35upx;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		background: #fff;
+		font-size: 24upx;
+		flex: 1;
+		
+		.search_icon {
+		  width: 24upx;
+		  height: 24upx;
+		  margin: 0 30upx;
+		}
+		.search_input {
+		  flex: 1;
+		  height: 60upx;
+		}
+	}
+	
+  }
+}
+
+
+.banner {
+  height: 308upx;
+	margin-top: 20upx;
+	border-radius: 20upx;
+	overflow: hidden;
+  .swiper {
+    height: 100%;
+    width: 100%;
+    image {
+		border-radius: 20upx;
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+.ad_banner{
+	margin: 0 20upx;
+	image{
+		width: 100%;
+		display: block;
+		margin-bottom: 34upx;
+	}
+}
+.ad_goods_content{
+	margin: 0 20upx;
+	display: flex;
+	.ad_goods_left{
+		  flex:1;
+		  height:340upx;
+		  margin-right: 20upx;
+		  // background-color:#fff;
+			// border-radius:10px;
+			position: relative;
+			background-repeat: no-repeat;
+			background-size: 100% 100%;
+	}
+	.ad_goods_right{
+		flex:1;
+		height:340upx;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		.ad_goods_right_item{
+			height:160upx;
+			// background-color:#fff;
+			// border-radius:10px;
+			position: relative;
+			background-repeat: no-repeat;
+			background-size: 100% 100%;
+		}
+	}
+	.ad_goods_name{
+		font-size:36upx;
+		font-weight:800;
+		color:rgba(51,51,51,1);
+		position: absolute;
+		top:20upx;
+		left:20upx;
+	}
+	.ad_goods_caption{
+		font-size:22upx;
+		font-weight:400;
+		color:rgba(153,153,153,1);
+		margin-top: 10upx;
+		position: absolute;
+		top:60upx;
+		left:20upx;
+	}
+	.gotosee{
+		border-radius: 25upx;
+		height:50upx;
+		width:100upx;
+		font-size: 24upx;
+		text-align: center;
+		line-height: 50upx;
+		background-color: $dt-color-primary;
+		position: absolute;
+		bottom:20upx;
+		left:20upx;
+		color:#fff
+	}
+}
+
+.enIcon {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  align-items: center;
+  padding: 30upx 0upx;
+
+  .item {
+    width: 25%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 30upx;
+	
+	.item2{
+		display: flex;
+		justify-items: center;
+		align-items: center;
+		flex-direction: column;
+	}
+	// 客服按钮
+	.customer-service{
+		display: flex; 
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	  background-color:transparent;
+	  border:0;
+	}
+	
+    image {
+      width: 80upx;
+      height: 80upx;
+      // border-radius: 50%;
+    }
+	
+	.enIcon-btn-text{
+      font-size: 0.7rem;
+      margin-top: 10upx;
+	  line-height: 40upx;
+      color: #353535;
+	}
+
+    .enIcon-text {
+      margin-top: 10upx;
+      font-size: 0.7rem;
+      color: #353535;
+    }
+  }
+}
+.menu_scroll{
+	position:sticky;
+	z-index:9;
+	white-space: nowrap;
+	background-color: #f2f2f2;
+	width: 100%;
+	.menu_type{
+		display: flex;
+		height:110upx;
+		padding-top: 20upx;
+		align-items: center;
+		.type_item{
+			text-align: center;
+			flex:1;
+			font-size:28upx;
+		}
+		.type_item_active{
+			text-align: center;
+			flex:1;
+			font-size:28upx;
+			color:#DB4444;
+		}
+		.type_item_active_line{
+			width:95upx;
+			height:5upx;
+			background: $dt-color-primary;
+			margin: 0 auto;
+		}
+	}
+}
+
+.coupon_mengban{
+	transition: all 3s ease;
+	position: fixed;
+	top: 0;
+	bottom: 0;
+	right:0;
+	left:0;
+	background-color: rgba(0,0,0,0.7);
+	z-index: 1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	z-index: 9;
+	.coupon {
+		width: 650upx;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	  .scroll {
+		  width: 425upx;
+		  top: 60upx;
+		  bottom: 250upx;
+		  position: absolute;
+	    .coupon_box {
+	      .coupon_item {
+	        position: relative;
+	        height: 120upx;
+			margin-bottom: 5upx;
+	        // padding: 0 15upx;
+	        .coupon_img {
+	          width: 420upx;
+	          height: 120upx;
+	        }
+	
+	        .coupon_info {
+	          position: absolute;
+	          top: 50%;
+	          right: 0upx;
+			  text-align: center;
+	          width: 150upx;
+	          text-align: center;
+	          transform: translate(0, -50%);
+	          color: #d73024;
+				font-weight: bold;		
+	          .coupon_amount {
+	            font-size: 40upx;
+	          }
+	
+	          .coupon_unit {
+	            font-size: 20upx;
+	          }
+	        }
+	
+	        .coupon_name {
+	          color: #d73024;
+	          font-size: 30upx;
+			  font-weight: bold;
+			  margin-bottom: 20upx;
+	        }
+	      }
+	
+	      .coupon_more {
+	        display: flex;
+	        flex-direction: row;
+	        align-items: center;
+	        padding: 0 30upx;
+	
+	        .more_text {
+	          font-size: 22upx;
+	          color: #999;
+	          width: 60upx;
+	          text-align: center;
+	          margin-right: 10upx;
+	        }
+	
+	        image {
+	          width: 10upx;
+	          height: 18upx;
+	        }
+	      }
+	    }
+	  }
+	  .ic_off{
+		  width: 50upx;
+		  height: 50upx;
+		  position: absolute;
+		  bottom: -100upx;
+		  z-index:10
+	  }
+	}
+}
+
+
+.line {
+  width: 100%;
+  height: 20upx;
+  background: #f2f2f2;
+}
+.everyDay{
+	height:210upx;
+	border-radius: 20upx;
+	background-repeat: no-repeat;
+	background-size: 100% 100%;
+	padding-top: 80upx;
+}
+.bubble{
+	position: absolute;
+	top: -28upx;
+	right: 20upx;
+	width: 50upx;
+	height: 28upx;
+	background-size: 100% 100%;
+	background-repeat: no-repeat;
+	color: #fff;
+	font-size: 16upx;
+	text-align: center;
+	line-height: 28upx;
+	float: right;
+}
+
+.bubble-red{
+	background-image: url("http://139.9.103.171:1888/img/image/bubble_red.png");
+}
+.bubble-yellow{
+	background-image: url("http://139.9.103.171:1888/img/image/bubble_yellow.png");
+}
+
+</style>

+ 194 - 0
pages/my-camera/my-camera.vue

@@ -0,0 +1,194 @@
+<template>
+	<view class="warp">
+		<view class="center">
+			<image class="content" v-if="src!=null" :src="src" ></image>
+			<camera class="content" v-else :device-position="position" flash="auto" @error="error" >
+				<cover-image :class="type==1?'coverImg-type1':'coverImg-type0'"  :src="type==1?'../../static/camera/card.png':'../../static/camera/face1.jpg'"></cover-image>
+			</camera>
+		</view>
+		<view class="bottom">
+			<!-- 取消拍摄 -->
+			<image class="cancel"  @click="cancel" src="../../static/camera/back.png" ></image>
+			<!-- 确认选择照片 -->
+			<image class="confirm" @click="confirm" v-if="src!=null"  src="../../static/camera/confirm1.png" ></image>
+			<!-- 确认拍摄 -->
+			<image class="confirm" v-else @click="takePhoto" src="../../static/camera/takephoto.png" ></image>
+			<!-- 切换摄像头 -->
+			<image class="change" v-if="src==null"   @click="change" src="../../static/camera/change.png"  ></image>
+			<!-- 重新拍摄 -->
+			<image class="change" v-else  @click="rephoto" src="../../static/camera/rephoto.png"  ></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				//0 人面 1 证件
+				type:0,
+				
+				flash:'off',
+				position:'back',
+				src: null
+			}
+		},
+		onLoad(options) {
+			this.type=options.type || 0
+		},
+		methods: {
+			//确认
+			confirm(){
+				console.log(this.src)
+				/* 返回调用页面并把图片URL传递过去 */
+				let that=this
+				let pages = getCurrentPages();
+				let prevPage = pages[pages.length - 2]; 
+				prevPage.setData({
+					"image":that.src
+				})
+				uni.navigateBack();
+			},
+			//闪光灯切换
+			tapLight(){
+				if (this.src==null) {
+					this.flash=this.flash=='on'?'off':'on'
+				}
+			},
+			//切换镜头
+			change(){
+				if (this.src==null) {
+					this.position=this.position=='back'?'front':'back'
+				}
+			},
+			//重新拍摄
+			rephoto(){
+				let that=this
+				uni.showModal({
+					title:"提示",
+					content:"确定重新拍摄?",
+					success: (res) => {
+						if (res.confirm) {
+							that.src=null
+						}
+					}
+				})
+			},
+			//取消拍照
+			cancel(){
+				uni.showModal({
+					title:"提示",
+					content:"确定取消拍摄?",
+					success: (res) => {
+						if (res.confirm) {
+							uni.navigateBack()
+						}
+					}
+				})
+			},
+			//拍照
+			takePhoto() {
+				let that=this
+				const ctx = uni.createCameraContext();
+				ctx.takePhoto({
+					quality: 'high',
+					success: (res) => {
+						that.src = res.tempImagePath
+					},
+					fail: (err) => {
+						console.log(err)
+					}
+				});
+			},
+			//打印错误日志
+			error(e) {
+				console.log(e.detail);
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.warp{
+		height: 100vh;
+		background-color: #fff;
+	}
+	.top{
+		display: flex;
+		justify-content: space-between;
+		box-sizing: border-box;
+		image{
+			width: 50rpx;
+		}
+		//闪光灯
+		.light{
+			margin-left: 50rpx;
+			padding: 10rpx 0;
+		}
+		.rephoto{
+			margin-right: 30rpx;
+			padding: 6rpx 0;
+		}
+	}
+	
+	.center{
+		.content{
+			height: 80vh;
+			width: 100vw;
+			.coverImg-type0{
+				height: 75vh;
+				margin-top: 20rpx;
+				margin-bottom: 20rpx;
+				opacity: 0.3;
+			}
+			.coverImg-type1{
+				height: 80vh;
+				opacity: 0.6;
+			}
+		}
+	}
+	
+
+	
+	
+	// 底部功能按钮
+	.bottom{
+		height: 19vh;
+		display: flex;
+		justify-content:space-around;
+		align-items: center;
+		//切换镜头
+		.change{
+			height: 88rpx;
+			width: 88rpx;
+			margin-left: 40rpx;
+			opacity: 0.7;
+		}
+		//确认拍摄
+		.confirm{
+			height: 150rpx;
+			width: 150rpx
+		}
+		
+		//取消上传
+		.cancel{
+			height: 88rpx;
+			width: 88rpx;
+			margin-right: 40rpx;
+			opacity: .7;
+		}
+	}
+	
+	//重新拍摄按钮
+	.button {
+		font-size: 20rpx;
+	    background-color: #59a5f0; /* Green */
+	    border: none;
+	    color: white;
+	    padding: 2rpx 32rpx;
+	    text-align: center;
+	    text-decoration: none;
+	    display: inline-block;
+	    cursor: pointer;
+	}
+</style>

+ 214 - 0
pages/myFamily/activateFace/activateFace.vue

@@ -0,0 +1,214 @@
+<template>
+<view style="background-color: #FFFFFF;height: 100vh;">
+<view v-if="faceList!=null && faceList.length!=0">
+	<view class="head">请选择人脸套餐:</view>
+	<view class="content">
+	  <view class="faceList">
+	    <view v-for="(item, index) in faceList" :key="index" class="item" @tap="selectFace" :data-item="item" :data-index="index" :style="'border-color:' + (selectIndex==index?'#1296db':'gray')">
+	      <view class="day">{{item.days}}天</view>
+	      <view class="amount">售价{{item.amount}}元</view>
+	    </view>
+	  </view>
+	</view>
+	<view class="faceDate">
+	  人脸有效期:<text>{{faceEndDate}}</text>
+	</view>
+	<view @click="goPay"  class=" footer-fixed" >
+		<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+			支付
+		</view>
+	</view>
+</view>
+<view v-else>
+	<view class="default" >
+	   <image src="/static/empty.png" mode="heightFix"></image>
+	  <view>
+	    <text>没有相关信息</text>
+	  </view>
+	</view>
+</view>	
+
+</view>	
+
+</template>
+
+<script>
+// pages/myFamily/activateFace/activateFace.js
+let app = getApp();
+
+export default {
+  data() {
+    return {
+      user_id: '',
+      room_id: '',
+      residential_id: '',
+      face_charge_id: '',
+      faceList: [],
+      selectIndex: null,
+      faceEndDate: ''
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    this.user_id = options.user_id;
+    this.room_id = options.room_id;
+
+    if (uni.getStorageSync("residentialId")) {
+      this.residential_id = uni.getStorageSync("residentialId");
+    } else {
+      uni.showToast({
+        title: '请先在首页选择所在小区',
+        icon: 'none'
+      });
+      return;
+    }
+
+    this.getFaceList();
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {},
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {},
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {},
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {},
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {},
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {},
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {},
+  methods: {
+    selectFace(e) {
+      let item = e.currentTarget.dataset.item;
+      let index = e.currentTarget.dataset.index;
+      this.setData({
+        face_charge_id: item.id,
+        selectIndex: index
+      });
+    },
+
+    getFaceList: function () {
+      var that = this;
+      let params = {};
+      params['residential_id'] = this.residential_id;
+      params['user_id'] = this.user_id;
+      let operation = 'userFace/getFaceChargeListByResidentialId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取成功" + res.data.result_msg);
+
+        if (res.data.result_code == 1) {
+          that.setData({
+            faceEndDate: res.data.faceEndDate,
+            faceList: res.data.list
+          });
+        }
+      });
+    },
+    goPay: function () {
+      if (this.face_charge_id == '' || this.face_charge_id == null) {
+        uni.showToast({
+          title: '请先选择人脸套餐',
+          icon: 'none'
+        });
+        return;
+      }
+
+      let params = {};
+      params['residential_id'] = this.residential_id;
+      params['user_id'] = this.user_id;
+      params['face_charge_id'] = this.face_charge_id;
+      params['room_id'] = this.room_id;
+      let operation = 'userFace/activeFace';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取成功" + res.data.result_msg);
+
+        if (res.data.result_code == 1) {
+          uni.showToast({
+            title: '激活成功',
+            icon: 'none'
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+.head{
+  line-height: 100rpx;
+  margin-left: 20rpx
+}
+.content{
+  width: 100%;
+}
+.faceList{
+  margin: 0 10rpx;
+  display: flex;
+  justify-content: space-between;
+  flex-wrap: wrap;
+}
+.item{
+  width:30%;
+  display: flex;
+  flex-direction: column;
+  align-content: center;
+  justify-content: center;
+  text-align: center;
+  border-radius: 10rpx;
+  border-style: solid;
+  border-width: 2rpx;
+  margin: 10rpx
+}
+.day{
+  height:80rpx;
+  line-height: 80rpx;
+  font-size: 35rpx;
+}
+.amount{
+  color:#1296db;
+  height:90rpx;
+}
+.faceDate{
+  position: fixed;
+  bottom: 150rpx;
+  width: 100%;
+  height: 100rpx;
+  line-height: 100rpx;
+  text-align: center;
+}
+.faceDate text{
+  color:#1296db;
+}
+
+
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}
.default image {
  height: 280rpx;
  display: inline-block;
}

+</style>

+ 637 - 0
pages/myFamily/add/add.vue

@@ -0,0 +1,637 @@
+<template>
+	<view class="" style="background-color: #FFFFFF;">
+		<view class="form" style="padding-top: 20rpx;">
+				<u-form :border="true" ref="uForm" >
+					<u-form-item :required="true"  label="姓名:" prop="name" label-width="150">
+						<u-input :border="true"  placeholder="姓名,必填" v-model="name" type="text"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="手机号:" prop="tel" label-width="150">
+						<u-input :border="true" maxlength="11"  placeholder="请输入11位手机号码" v-model="tel" type="number"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="房间号:" prop="roomLabel" label-width="150">
+						<u-input :border="true"  type="select" :select-open="roomShow" v-model="roomLabel" placeholder="请选择房间号" @click="roomShow = true"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="住户类型:" prop="type" label-width="150">
+						<u-input :border="true"  type="select" :select-open="typeShow" v-model="typeLabel" placeholder="请选择住户类型" @click="typeShow = true"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="国籍:" prop="nationality" label-width="150">
+						<u-input :border="true" type="select" :select-open="nationalityShow" v-model="nationalityLabel"  @click="nationalityShow = true"></u-input>
+					</u-form-item>
+					<u-form-item   label="证件类型:" prop="nationalityName" label-width="150">
+						<u-input :disabled="true" :border="true" type="text" v-model="nationalityName"></u-input>
+					</u-form-item>
+					<u-form-item :required="type==0?true:false"  label="证件号码" prop="id_card" label-width="150">
+						<u-input :border="true" placeholder="住户类型是业主时,必填" :trim="true"  maxlength="18" v-model="id_card" type="number"></u-input>
+					</u-form-item>
+					<u-form-item :required="true" label="性别" prop="sex" label-width="150">
+						<u-radio-group v-model="sex" >
+							<u-radio shape="circle"  name="1">男</u-radio>
+							<u-radio shape="circle"  name="2">女</u-radio>
+						</u-radio-group>
+					</u-form-item>
+				</u-form>
+		</view>
+		<view v-if="nationality==3" style="background-color: #FFFFFF;">
+		  <view class="form_group mb0" style="padding-left: 60rpx;">
+		    <view>
+		      <text class="sex">护照图片:</text>
+		      <text class="tips">(基本身份信息页)</text>
+		    </view>
+		  </view>
+		  
+		  <view @click="operaType=1;chooseImage()" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+		    <upload-img
+		  	  :width="$isEmpty(show_passport_img_uri)?bgWidth:imgWidth"
+		  	  :height="$isEmpty(show_passport_img_uri)?bgHeight:imgHeight"
+		  	  :currentImage="show_passport_img_uri"
+		  	  :bgsrc="bgsrc"
+		  	  >
+		    </upload-img>
+		    <view class="" style="color: #59a5f0;">
+		  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+		  	 <text v-if="$isEmpty(show_passport_img_uri)">点击上传护照</text>
+		  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+		    </view>
+		  </view>
+		</view>
+		<view v-if="nationality==3" style="background-color: #FFFFFF;">
+		  <view class="form_group mb0" style="padding-left: 60rpx;">
+		    <view>
+		      <text class="sex">入境证明:</text>
+		      <text class="tips">(入镜盖章页)</text>
+		    </view>
+		  </view>
+		  <view @click="operaType=2;chooseImage()" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+		    <upload-img
+		  	  :width="$isEmpty(show_entry_img_uri)?bgWidth:imgWidth"
+		  	  :height="$isEmpty(show_entry_img_uri)?bgHeight:imgHeight"
+		  	  :currentImage="show_entry_img_uri"
+		  	  :bgsrc="bgsrc"
+		  	  >
+		    </upload-img>
+		    <view class="" style="color: #59a5f0;">
+		  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+		  	 <text v-if="$isEmpty(show_entry_img_uri)">点击上传入境证明</text>
+		  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+		    </view>
+		  </view>
+		</view>
+		
+		<view style="background-color: #FFFFFF;">
+					<view class="form_group mb0" style="padding-left: 60rpx;">
+						 <view>
+							<text class="sex">人脸:</text>
+							<text class="tips">(人脸用于开门,请上传正脸图片)</text>
+						  </view>
+					</view>
+					<view @click="show=true;operaType=3" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+					  <upload-img
+						  :width="$isEmpty(show_image_uri)?bgWidth:imgWidth"
+						  :height="$isEmpty(show_image_uri)?bgHeight:imgHeight"
+						  :currentImage="show_image_uri"
+						  :bgsrc="bgsrc"
+						  >
+					  </upload-img>
+					  <view class="" style="color: #59a5f0;">
+						 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+						 <text v-if="$isEmpty(show_image_uri)">点击上传人面</text>
+						 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+					  </view>
+					</view>
+					<view class="category" style="padding-bottom: 140rpx;">
+						<view v-for="(item, index) in iconArray" :key="index" class="category_item">
+						  <view class="category_item_wrap" @tap="top" :data-index="item.index">
+							<view class="icon_wrap">
+							  <image :src="item.iconUrl" class="index_icon"></image>
+							</view>
+							<view class="category_item_text">
+							  <text>{{item.iconText}}</text>
+							</view>
+						  </view>
+					</view>
+			</view>
+		</view>
+	  <u-action-sheet @click="photoChecked"  z-index="999999" :list="list" v-model="show"></u-action-sheet>
+	  <u-select z-index="999999" mode="single-column" value-name="id" label-name="name" :list="own_room_list" v-model="roomShow" @confirm="roomConfirm"></u-select>
+	  <u-select z-index="999999" mode="single-column" :list="typeArry" v-model="typeShow" @confirm="typeConfirm"></u-select>
+	  <u-select z-index="999999" mode="single-column" :list="nationalityArry" v-model="nationalityShow" @confirm="nationalityConfirm"></u-select>
+	  <view  @click="addApplyUser"  class=" footer-fixed" >
+	  	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+	  		提交添加
+	  	</view>
+	  </view>
+	  
+	</view>
+ </view>
+</template>
+
+<script>
+import uploadImg from '@/comps/uploadimg/uploadImg.vue'
+//获取app实例
+var app = getApp();
+export default {
+	components:{
+		uploadImg
+	},
+	data() {
+		return {
+			//默认点击弹出拍照模态框的是人面上传操作,1:护照,2:入境,3:人面
+			operaType:3,
+			//人面上传模态框,上传照片或拍照
+			list: [{
+				text: '相册上传',
+			}, {
+				text: '拍照上传'
+			}],
+			show: false,
+			
+			//背景图
+			bgsrc:'http://139.9.103.171:1888/img/image/camera1.png',
+			bgWidth:350,
+			bgHeight:320,
+			//显示图
+			imgWidth:540,
+			imgHeight:400,
+			
+			roomLabel:'',
+			roomShow:false,
+			room_id: 0,
+			own_room_list: null,
+			//房间列表下标
+			own_room_list_index: 0,
+			
+			//姓名
+			name: null,
+			//电话号码
+			tel: null,
+			
+			//住户类型
+			typeLabel:'业主',
+			typeShow: false,
+			type: 0,
+			typeArry: [
+				{
+					value: '0',
+					label: '业主'
+				},
+				{
+					value: '1',
+					label: '成员'
+				},
+				{
+					value: '2',
+					label: '租户'
+				}
+			],
+			//国籍
+			nationalityLabel:'中国大陆',
+			nationalityShow: false,
+			nationality: 0,
+			nationalityName:'身份证',
+			nationalityArry: [
+				{
+					value: '0',
+					label: '中国大陆'
+				},
+				{
+					value: '1',
+					label: '中国香港/澳门'
+				},
+				{
+					value: '2',
+					label: '中国台湾'
+				},
+				{
+					value: '3',
+					label: '海外'
+				}
+			],
+			//身份证
+			id_card: null,
+			sex: "1",
+			
+			passport_img_uri: null,
+			//护照照片
+			show_passport_img_uri: null,
+			//护照照片回显
+			entry_img_uri: null,
+			//入境证明
+			show_entry_img_uri: null,
+			//入境证明回显
+			image_uri: null,
+			//人脸图片地址
+			show_image_uri: null,
+			//人脸回显
+			face_code: null,
+			//图片的md5
+			iconArray: [{
+			  "iconUrl": "http://139.9.103.171:1888/img/image/zd.png",
+			  "iconText": '不要遮挡',
+			  "index": 1
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/mj.png",
+			  "iconText": '不戴墨镜',
+			  "index": 2
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/zl.png",
+			  "iconText": '不能仰头俯拍',
+			  "index": 3
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/cz.png",
+			  "iconText": '光线充足',
+			  "index": 4
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/bg.png",
+			  "iconText": '浅色背景',
+			  "index": 5
+			}, {
+			  "iconUrl": "http://139.9.103.171:1888/img/image/sh.png",
+			  "iconText": '物业审核生效',
+			  "index": 6
+			}]
+		};
+	},
+	onLoad: function (options) {
+		var that = this;
+		that.setData({
+		  own_room_list: app.globalData.own_room_list
+		});
+	},
+	onShow() {
+		//获取当前页面的对象
+		let currPage=this.$util.getPageCtx()
+		if(!this.$isEmpty(currPage.data.image)){
+			this.uploadImage(currPage.data.image)
+		} 
+	},
+	methods: {
+		//点击模态框选项触发
+		photoChecked(index){
+			if (index==0) {
+				//图片上传
+				this.chooseImage()
+			} else if(index==1){
+				//拍照上传
+				uni.navigateTo({
+					url:"../../my-camera/my-camera"
+				})
+			}
+		},
+		//点击上传图片事件
+		chooseImage: function () {
+		  var that = this;
+		  uni.chooseImage({
+		    count: 1,
+		    //最多可以选择的图片张数,默认9
+		    sourceType: ['album', 'camera'],
+		    sizeType: ['compressed'],
+		    //可选择原图或压缩后的图片
+		    success: res => {
+		      let tempFilePaths = res.tempFilePaths;
+			  that.uploadImage(tempFilePaths[0])
+		    }
+		  });
+		},
+		/**上传图片
+		 * @param {Object} imgUrl 图片url
+		 */
+		uploadImage(imgUrl){
+			console.log("operatype: ",this.operaType);
+			console.log("imgUrl",imgUrl)
+			var that = this;
+			//是否需要md5加密上传人面照
+			let is_need_md5 = false;
+			if (this.operaType == 3) {
+			  is_need_md5 = true;
+			}
+			uni.getFileSystemManager().readFile({
+			  filePath: imgUrl,
+			  //选择图片返回的相对路径
+			  encoding: 'base64',
+			  //编码格式
+			  success: res => {
+			    //成功的回调
+			    app.globalData.uploadBase64('data:image/jpeg;base64,' + res.data, is_need_md5, function (result) {
+			      if (that.operaType == 1) {
+			        that.setData({
+			          passport_img_uri: result.data.uri,
+			          show_passport_img_uri: imgUrl
+			        });
+			      } else if (that.operaType == 2) {
+			        that.setData({
+			          entry_img_uri: result.data.uri,
+			          show_entry_img_uri: imgUrl
+			        });
+			      } else if (that.operaType == 3) {
+			        that.setData({
+			          image_uri: result.data.uri,
+			          show_image_uri: imgUrl,
+			          face_code: result.data.md5Hex
+			        });
+			      }
+			    });
+			  }
+			});
+		},
+		roomConfirm(e) {
+			this.room_id = 0;
+			e.map((val, index) => {
+				this.room_id=val.value
+				this.roomLabel=val.label
+			})
+		},
+		typeConfirm(e) {
+			this.type = 0;
+			e.map((val, index) => {
+				this.type=val.value
+				this.typeLabel=val.label
+			})
+		},
+		nationalityConfirm(e) {
+			this.nationality = 0;
+			e.map((val, index) => {
+				this.nationality=val.value
+				this.nationalityLabel=val.label
+				
+				if (this.nationality == 0) {
+				  this.nationalityName = '身份证';
+				} else if (this.nationality == 1) {
+				  this.nationalityName = '港澳居民往来内地通行证';
+				} else if (this.nationality == 2) {
+				  this.nationalityName = '台湾居民往来大陆通行证';
+				} else if (this.nationality == 3) {
+				  this.nationalityName = '护照';
+				}
+			})
+		},
+		//添加家人
+		addApplyUser: function () {
+		  let that = this;
+		  let params = {};
+		  let name = that.name;
+		
+		  if (!name) {
+		    app.globalData.autoFailHint("请填写名字");
+		    return;
+		  }
+		
+		  params['name'] = name;
+		  let tel = that.tel;
+		
+		  if (!tel) {
+		    app.globalData.autoFailHint("请填写手机");
+		    return;
+		  } //手机号码正则校验
+		  var telReg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/;
+		
+		  if (!telReg.test(tel)) {
+		    app.globalData.autoFailHint("请填写正确手机号");
+		    return;
+		  }
+		  params['tel'] = tel;
+		  let room_id = that.own_room_list[that.own_room_list_index].id;
+		
+		  if (!room_id) {
+		    app.globalData.autoFailHint("请选择房间号");
+		    return;
+		  }
+		  params['room_id'] = room_id;
+		  let type = that.type;
+		  params['type'] = type;
+		  let id_card = that.id_card;
+		  params['id_card'] = id_card; //业主身份时,身份证必填
+		
+		  if (type == 0 && !id_card) {
+		    app.globalData.autoFailHint("住户类型是业主时,证件号码必填");
+		    return;
+		  } //0 中国大陆 1 中国香港/澳门 2 中国台湾 3 海外
+		
+		
+		  let nationality = that.nationality;
+		  params['nationality'] = nationality;
+		  let passport_img_uri = that.passport_img_uri;
+		  let entry_img_uri = that.entry_img_uri;
+		
+		  if (nationality == 3) {
+		    params['passport_img_uri'] = that.passport_img_uri;
+		    params['entry_img_uri'] = that.entry_img_uri;
+		
+		    if (type == 0) {
+		      if (!passport_img_uri) {
+		        app.globalData.autoFailHint("请上传护照图片");
+		        return;
+		      }
+		
+		      if (!entry_img_uri) {
+		        app.globalData.autoFailHint("请上传入境证明");
+		        return;
+		      }
+		    }
+		  }
+		
+		  let image_uri = that.image_uri;
+		  params['image_uri'] = that.image_uri;
+		  let face_code = that.face_code;
+		  params['face_code'] = that.face_code; //性别
+		
+		  params['sex'] = that.sex;
+		  params['member_id'] = app.globalData.member.id; //申请来源0-小程序添加 1-后台添加  2-后台导入 3-app添加
+		
+		  params['create_type'] = '0'; ///申请的记录类型 0--认证类型 1--新增类型 2--编辑类型
+		
+		  params['record_type'] = '1';
+		  let operation = 'member/authentication';
+		  console.log(params)
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //添加成功
+		    if (res.data.result_code == 1) {
+		      app.globalData.oneFailHint(res.data.result_msg, function () {
+		        uni.navigateBack({
+		          delta: 1 // 返回上一级页面。
+		
+		        });
+		      });
+		    } else {
+		      app.globalData.oneFailHint(res.data.result_msg);
+		    }
+		  });
+		}
+		
+	}
+};
+</script>
+
+<style scoped lang="scss">
+.form {
+	padding:0 60rpx;
+	background-color: #FFFFFF;
+}
+
+.local_city{
+    padding: 30rpx 0;
+    position:relative;
+    background: #fff;
+}
+.local_city .changeCity{
+    padding: 20rpx;
+    position: absolute;
+    right: 0rpx;
+    top: 0;
+}
+.local_city .icon{
+    padding: 20rpx;
+    position: absolute;
+    left: -0;
+    top: 50%;
+    transform: translate(0,-50%);
+    font-size: 40rpx;
+}
+.local_city .local_city_info{
+    padding-left: 40rpx;
+    display:inline-block;
+}
+
+.form_group .upload {
+  padding: 0 28rpx;
+  font-size: 26rpx;
+  background: $base-btn-color;
+  color: #fff;
+  border: none;
+}
+
+.upload_tips {
+  font-size: 24rpx;
+}
+
+.upload_bg {
+  position: relative;
+  text-align: center;
+}
+
+.mb0 {
+  padding-top: 40rpx;
+  font-size: 28rpx;
+  margin-bottom: 0;
+}
+
+.form_group .tips {
+  margin-left: 50rpx;
+}
+
+.upload_bg .upload_bgImg {
+  width: 540rpx;
+  height: 400rpx;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, 0);
+  color: $base-btn-color;
+}
+
+upload_bg {
+  position: relative;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 40%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 55%;
+  width: 100%;
+  color: $base-btn-color;
+}
+
+.img_content {
+  margin-top: 20rpx;
+  position: relative;
+  text-align: center;
+}
+
+.img_content .upload_bgImg {
+  width: 560rpx;
+  height: 420rpx;
+  max-height: 1;
+  display: inline-block;
+  border-radius: 20rpx;
+}
+
+.reUpload {
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: right;
+  color: #333;
+  padding-right: 100rpx;
+  font-size: 26rpx;
+}
+
+.img_content .img_icon {
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 6rpx;
+  border-radius: 20rpx;
+}
+
+.category {
+  padding:20px 20rpx 0;
+  overflow: auto;
+  background-color: #FFF;
+text-align:center;
+
+}
+.category_item {
+  width: 33.3%;
+  float: left;
+  margin-bottom: 40rpx;
+}
+
+.icon_wrap {
+  width: 120rpx;
+  margin: 0 auto;
+  margin-bottom: 5px;
+}
+.index_icon {
+  width: 60rpx;
+  height: 60rpx;
+}
+.category_item_text {
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+}
+
+</style>
+
+			
+		

+ 693 - 0
pages/myFamily/addFamily/addFamily.vue

@@ -0,0 +1,693 @@
+<template>
+<view class="container edit_wrap">
+  <form>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">姓名:</text>
+      <input name="data_name" @input="nameFun" placeholder="请与身份证保持一致" placeholder-class="placeholder_style" type="text" value class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">手机号:</text>
+      <input name="data_name" @input="telFun" placeholder="请输入11位手机号码" placeholder-class="placeholder_style" type="text" value class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">房间号:</text>
+      <view class="ar_picker" style="background:#fff">
+        <view class="ar_picker_wrap">
+          <picker @change="bindRoomIdChange" :value="own_room_list_index" :range="own_room_list" :range-key="'name'">
+            <view>
+              <text>{{own_room_list[own_room_list_index].name}}</text>
+            </view>
+          </picker>
+        </view>
+      </view>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">住户类型:</text>
+      <view class="ar_picker" style="background:#fff">
+        <view class="ar_picker_wrap">
+          <picker @change="typeChange" :value="type" :range="typeArray">
+            <view>
+              <text>{{typeArray[type]}}</text>
+            </view>
+          </picker>
+        </view>
+      </view>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">国籍:</text>
+      <view class="ar_picker" style="background:#fff">
+        <view class="ar_picker_wrap">
+          <picker @change="nationalityChange" :value="nationality" :range="nationalityArray">
+            <view>
+              <text>{{nationalityArray[nationality]}}</text>
+            </view>
+          </picker>
+        </view>
+      </view>
+    </view>
+    <view class="form_group">
+      <text class="sex">证件类型:</text>
+      <input :value="nationalityName" disabled="true" placeholder-class="placeholder_style" type="text" class="placeholder_style">
+      </input>
+    </view>
+     <view class="form_group">
+      <text class="sex">证件号码:</text>
+      <input @input="id_cardFun" name="data_name" placeholder="住户类型是业主时,必填" placeholder-class="placeholder_style" type="text" value class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="sex">性别:</text>
+      <radio-group class="item-right radio-group" @change="sexChange">
+        <label v-for="(item, index) in sexArray" :key="index" class="radio">
+          <radio :value="item.sex" :checked="item.checked"></radio>{{item.name}}
+        </label>
+      </radio-group>
+    </view>
+
+    <view v-if="nationality==3">
+      <view class="form_group mb0">
+        <view>
+          <text class="red">*</text>
+          <text class="sex">护照图片:</text>
+          <text class="tips">(基本身份信息页)</text>
+        </view>
+      </view>
+
+      <view class>
+        <view class="upload_bg img_content">
+          <image :src="show_passport_img_uri==null?'http://139.9.103.171:1888/img/image/face_bg.png':show_passport_img_uri" class="upload_bgImg" mode="aspectFit"></image>
+          <view v-if="show_passport_img_uri==null" @tap="chooseImage" data-index="1">
+            <view class="upload_btn">
+              <image src="http://139.9.103.171:1888/img/image/upload_btn.png"></image>
+            </view>
+            <view class="upload_text">
+              <text>点击上传照片</text>
+            </view>
+          </view>
+          <view v-if="show_passport_img_uri!=null" @tap="chooseImage" class="reUpload" data-index="1">
+            <image src="http://139.9.103.171:1888/img/image/picture.png" class="img_icon"></image>
+            <text>重新上传</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <view v-if="nationality==3">
+      <view class="form_group mb0">
+        <view>
+          <text class="red">*</text>
+          <text class="sex">入境证明:</text>
+          <text class="tips">(入镜盖章页)</text>
+        </view>
+      </view>
+
+      <view class>
+        <view class="upload_bg img_content">
+          <image :src="show_entry_img_uri==null?'../../../image/face_bg.png':show_entry_img_uri" class="upload_bgImg" mode="aspectFit"></image>
+          <view v-if="show_entry_img_uri==null" @tap="chooseImage" data-index="2">
+            <view class="upload_btn">
+              <image src="http://139.9.103.171:1888/img/image/upload_btn.png"></image>
+            </view>
+            <view class="upload_text">
+              <text>点击上传照片</text>
+            </view>
+          </view>
+          <view v-if="show_entry_img_uri!=null" @tap="chooseImage" class="reUpload" data-index="2">
+            <image src="http://139.9.103.171:1888/img/image/picture.png" class="img_icon"></image>
+            <text>重新上传</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <view class="form_group mb0">
+      <view>
+        <text class="red">*</text>
+        <text class="sex">人脸:</text>
+        <text class="tips">(人脸用于开门,请上传正脸图片)</text>
+      </view>
+    </view>
+
+    <view class>
+      <view class="upload_bg img_content">
+        <image :src="show_image_uri==null?'../../../image/face_bg.png':show_image_uri" class="upload_bgImg" mode="aspectFit"></image>
+        <view v-if="show_image_uri==null" @tap="chooseImage" data-index="3">
+          <view class="upload_btn">
+            <image src="http://139.9.103.171:1888/img/image/upload_btn.png"></image>
+          </view>
+          <view class="upload_text">
+            <text>点击上传人脸</text>
+          </view>
+        </view>
+        <view v-if="show_image_uri!=null" @tap="chooseImage" class="reUpload" data-index="3">
+          <image src="http://139.9.103.171:1888/img/image/picture.png" class="img_icon"></image>
+          <text>重新上传</text>
+        </view>
+      </view>
+      <view class="category">
+        <view v-for="(item, index) in iconArray" :key="index" class="category_item">
+          <view class="category_item_wrap" @tap="top" :data-index="item.index">
+            <view class="icon_wrap">
+              <image :src="item.iconUrl" class="index_icon"></image>
+            </view>
+            <view class="category_item_text">
+              <text>{{item.iconText}}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+  </form>
+
+  <view class="submit_btn">
+    <button class="ar_btn" @tap="addApplyUser">提交添加</button>
+  </view>
+
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      name: null,
+      //姓名
+      tel: null,
+      //电话号码
+      own_room_list: null,
+      //房间列表下标
+      own_room_list_index: 0,
+      typeArray: ['业主', '成员', '租户'],
+      type: 0,
+      nationalityArray: ['中国大陆', '中国香港/澳门', '中国台湾', '海外'],
+      nationality: 0,
+      nationalityName: '身份证',
+      id_card: null,
+      //身份证
+      sexArray: [{
+        name: '男',
+        checked: true,
+        sex: "1"
+      }, {
+        name: '女',
+        checked: false,
+        sex: "2"
+      }],
+      sex: "1",
+      passport_img_uri: null,
+      //护照照片
+      show_passport_img_uri: null,
+      //护照照片回显
+      entry_img_uri: null,
+      //入境证明
+      show_entry_img_uri: null,
+      //入境证明回显
+      image_uri: null,
+      //人脸图片地址
+      show_image_uri: null,
+      //人脸回显
+      face_code: null,
+      //图片的md5
+      iconArray: [{
+        "iconUrl": "http://139.9.103.171:1888/img/image/zd.png",
+        "iconText": '不要遮挡',
+        "index": 1
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/mj.png",
+        "iconText": '不戴墨镜',
+        "index": 2
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/zl.png",
+        "iconText": '不能仰头俯拍',
+        "index": 3
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/cz.png",
+        "iconText": '光线充足',
+        "index": 4
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/bg.png",
+        "iconText": '浅色背景',
+        "index": 5
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/sh.png",
+        "iconText": '物业审核生效',
+        "index": 6
+      }]
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    var that = this;
+    that.setData({
+      own_room_list: app.globalData.own_room_list
+    });
+  },
+  methods: {
+    //获取input的标签值
+    nameFun: function (e) {
+      this.setData({
+        name: e.detail.value
+      });
+    },
+    telFun: function (e) {
+      this.setData({
+        tel: e.detail.value
+      });
+    },
+    id_cardFun: function (e) {
+      this.setData({
+        id_card: e.detail.value
+      });
+    },
+    // 住户类型
+    typeChange: function (e) {
+      this.setData({
+        type: e.detail.value
+      });
+    },
+    // 类别选择
+    roomIdChange: function (e) {
+      this.setData({
+        own_room_list_index: e.detail.value
+      });
+    },
+    //性别
+    sexChange: function (enent) {
+      this.setData({
+        sex: enent.detail.value
+      });
+    },
+    // 国籍
+    nationalityChange: function (e) {
+      let nationality = e.detail.value;
+      let nationalityName = '';
+
+      if (nationality == 0) {
+        nationalityName = '身份证';
+      } else if (nationality == 1) {
+        nationalityName = '港澳居民往来内地通行证';
+      } else if (nationality == 2) {
+        nationalityName = '台湾居民往来大陆通行证';
+      } else if (nationality == 3) {
+        nationalityName = '护照';
+      }
+
+      this.setData({
+        nationality: nationality,
+        nationalityName: nationalityName
+      });
+    },
+    //点击上传图片事件
+    chooseImage: function (event) {
+      var that = this;
+      let index = event.currentTarget.dataset.index;
+      let is_need_md5 = false;
+
+      if (index == 3) {
+        is_need_md5 = true;
+      }
+
+      uni.chooseImage({
+        count: 1,
+        //最多可以选择的图片张数,默认9
+        sourceType: ['album', 'camera'],
+        sizeType: ['compressed'],
+        //可选择原图或压缩后的图片
+        success: res => {
+          let tempFilePaths = res.tempFilePaths;
+          uni.getFileSystemManager().readFile({
+            filePath: res.tempFilePaths[0],
+            //选择图片返回的相对路径
+            encoding: 'base64',
+            //编码格式
+            success: res => {
+              //成功的回调
+              app.globalData.uploadBase64('data:image/jpeg;base64,' + res.data, is_need_md5, function (result) {
+                if (index == 1) {
+                  that.setData({
+                    passport_img_uri: result.data.uri,
+                    show_passport_img_uri: tempFilePaths[0]
+                  });
+                } else if (index == 2) {
+                  that.setData({
+                    entry_img_uri: result.data.uri,
+                    show_entry_img_uri: tempFilePaths[0]
+                  });
+                } else if (index == 3) {
+                  that.setData({
+                    image_uri: result.data.uri,
+                    show_image_uri: tempFilePaths[0],
+                    face_code: result.data.md5Hex
+                  });
+                }
+              });
+            }
+          });
+        }
+      });
+    },
+    //添加家人
+    addApplyUser: function () {
+      let that = this;
+      let params = {};
+      let name = that.name;
+
+      if (!name) {
+        app.globalData.autoFailHint("请填写名字");
+        return;
+      }
+
+      params['name'] = name;
+      let tel = that.tel;
+
+      if (!tel) {
+        app.globalData.autoFailHint("请填写手机");
+        return;
+      } //手机号码正则校验
+
+
+      var telReg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/;
+
+      if (!telReg.test(tel)) {
+        app.globalData.autoFailHint("请填写正确手机号");
+        return;
+      }
+
+      params['tel'] = tel;
+      let room_id = that.own_room_list[that.own_room_list_index].id;
+
+      if (!room_id) {
+        app.globalData.autoFailHint("请选择房间号");
+        return;
+      }
+
+      params['room_id'] = room_id;
+      let type = that.type;
+      params['type'] = type;
+      let id_card = that.id_card;
+      params['id_card'] = id_card; //业主身份时,身份证必填
+
+	  console.log(params)
+	  return
+      if (type == 0 && !id_card) {
+        app.globalData.autoFailHint("住户类型是业主时,证件号码必填");
+        return;
+      } //0 中国大陆 1 中国香港/澳门 2 中国台湾 3 海外
+
+
+      let nationality = that.nationality;
+      params['nationality'] = nationality;
+      let passport_img_uri = that.passport_img_uri;
+      let entry_img_uri = that.entry_img_uri;
+
+      if (nationality == 3) {
+        params['passport_img_uri'] = that.passport_img_uri;
+        params['entry_img_uri'] = that.entry_img_uri;
+
+        if (type == 0) {
+          if (!passport_img_uri) {
+            app.globalData.autoFailHint("请上传护照图片");
+            return;
+          }
+
+          if (!entry_img_uri) {
+            app.globalData.autoFailHint("请上传入境证明");
+            return;
+          }
+        }
+      }
+
+      let image_uri = that.image_uri;
+      params['image_uri'] = that.image_uri;
+      let face_code = that.face_code;
+      params['face_code'] = that.face_code; //性别
+
+      params['sex'] = that.sex;
+      params['member_id'] = app.globalData.member.id; //申请来源0-小程序添加 1-后台添加  2-后台导入 3-app添加
+
+      params['create_type'] = '0'; ///申请的记录类型 0--认证类型 1--新增类型 2--编辑类型
+
+      params['record_type'] = '1';
+      let operation = 'member/authentication';
+      app.globalData.postRequest(params, operation, function (res) {
+        //添加成功
+        if (res.data.result_code == 1) {
+          app.globalData.oneFailHint(res.data.result_msg, function () {
+            uni.navigateBack({
+              delta: 1 // 返回上一级页面。
+
+            });
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+page{
+  overflow-y: scroll;
+  background: #fff;
+}
+.edit_wrap {
+  font-size: 30rpx;
+  padding: 0rpx 20rpx 120rpx;
+  color: #333;
+}
+
+.form_group {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  margin: 20rpx 20rpx;
+  line-height: 80rpx;
+  position: relative;
+    font-size: 26rpx;
+}
+
+.form_group .red {
+  color: red;
+  position: absolute;
+  left: 0;
+}
+
+.form_group text.sex {
+  margin-left: 15px;
+  text-align: left;
+}
+
+.form_group .radio-group {
+  text-align: left;
+  width: 500rpx;
+}
+
+.form_group .radio-group .radio {
+  margin-right: 60rpx;
+}
+
+.form_group input, .form_group picker {
+  border: 1px solid #ddd;
+  border-radius: 8rpx;
+  height: 80rpx;
+  line-height: 80rpx;
+  padding: 0rpx 20rpx;
+  color: #333;
+  width: 460rpx;
+}
+
+.form_group button {
+  font-size: 30rpx;
+  height: 80rpx;
+  line-height: 80rpx;
+  border: 1px dotted #fff;
+  background: white;
+  padding: 0rpx;
+  margin: 0rpx;
+  outline: none;
+  color: #000;
+}
+
+.placeholder_style {
+  font-family: '微软雅黑';
+  color: #adadad;
+}
+
+.save_btn {
+  width: 600rpx;
+  background: #d24a58;
+  font-size: 32rpx;
+  color: #fff;
+  border-radius: 0rpx;
+  margin: 40rpx 0rpx 10rpx;
+}
+
+/* 自定义 radio 样式 */
+
+radio {
+  width: 38rpx;
+}
+
+radio .wx-radio-input {
+  border-radius: 50%;
+  width: 28rpx;
+  height: 28rpx;
+}
+
+/* 选中后的样式 (可根据设计稿需求自己修改) */
+
+radio .wx-radio-input.wx-radio-input-checked::before {
+  border-radius: 50%;
+  width: 44rpx;
+  height: 44rpx;
+  line-height: 44rpx;
+  text-align: center;
+  font-size: 26rpx; /* 对勾大小 26rpx */
+  color: #fff; /* 对勾颜色 */
+  background: $base-btn-color;
+  border-color: $base-btn-color;
+}
+
+.form_group .upload {
+  padding: 0 28rpx;
+  font-size: 26rpx;
+  background: $base-btn-color;
+  color: #fff;
+  border: none;
+}
+
+.upload_tips {
+  font-size: 24rpx;
+}
+
+.upload_bg {
+  position: relative;
+  text-align: center;
+}
+
+.mb0 {
+  margin-bottom: 0;
+}
+
+.form_group .tips {
+  margin-left: 50rpx;
+}
+
+.upload_bg .upload_bgImg {
+  width: 540rpx;
+  height: 400rpx;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, 0);
+  color: $base-btn-color;
+}
+.upload_bg{
+  position: relative;
+  text-align: center;
+}
+
+.upload_bg .upload_btn{
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 40%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+
+}
+.upload_bg .upload_btn image{
+  width: 100%;
+  height: 100%;
+}
+.upload_text{
+   position: absolute;
+   top: 55%;
+   width:100%;
+   color:$base-btn-color;
+     
+ 
+}
+
+.img_content .upload_bgImg{
+  
+  display: inline-block;
+}
+.reUpload{
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align:right;
+  color: #333;
+  padding-right: 100rpx;
+}
+.img_content .img_icon{
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 6rpx;
+  border-radius: 20rpx;
+}
+.category {
+  padding:20px 20rpx 0;
+  overflow: auto;
+  background-color: #FFF;
+text-align:center;
+
+}
+.category_item {
+  width: 33.3%;
+  float: left;
+  margin-bottom: 40rpx;
+}
+.icon_wrap {
+  width: 120rpx;
+  margin: 0 auto;
+  margin-bottom: 5px;
+}
+.index_icon {
+  width: 60rpx;
+  height: 60rpx;
+}
+.category_item_text {
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+}
+</style>

+ 837 - 0
pages/myFamily/editApplyFamily/editApplyFamily.vue

@@ -0,0 +1,837 @@
+<template>
+<view class="container edit_wrap">
+  <form :style="'pointer-events:' + (waitAudit?'none':'auto')">
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">姓名:</text>
+      <input disabled="true" placeholder-class="placeholder_style" type="text" :value="name" class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">手机号:</text>
+      <input name="data_name" @input="telFun" placeholder="请输入11位手机号码" placeholder-class="placeholder_style" type="text" :value="tel" class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">房间号:</text>
+      <input disabled="true" name="data_name" placeholder-class="placeholder_style" type="text" :value="room_name" class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">住户类型:</text>
+      <view class="ar_picker" style="background:#fff">
+        <view class="ar_picker_wrap">
+          <picker @change="typeChange" :value="type" :range="typeArray">
+            <view>
+              <text>{{typeArray[type]}}</text>
+            </view>
+          </picker>
+        </view>
+      </view>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">国籍:</text>
+      <view class="ar_picker" style="background:#fff">
+        <view class="ar_picker_wrap">
+          <picker @change="nationalityChange" :value="nationality" :range="nationalityArray">
+            <view>
+              <text>{{nationalityArray[nationality]}}</text>
+            </view>
+          </picker>
+        </view>
+      </view>
+    </view>
+    <view class="form_group">
+      <text class="sex">证件类型:</text>
+      <input :value="nationalityName" disabled="true" placeholder-class="placeholder_style" type="text" class="placeholder_style">
+      </input>
+    </view>
+     <view class="form_group">
+      <text class="sex">证件号码:</text>
+      <input @input="id_cardFun" name="data_name" placeholder="住户类型是业主时,必填" placeholder-class="placeholder_style" type="text" :value="id_card" class="placeholder_style">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="sex">性别:</text>
+<!--     <radio-group class="item-right radio-group" @change="sexChange">
+        <label v-for="(item, index) in sexArray" :key="index" class="radio">
+          <radio :class="item.checked?'red checked':''" color="#2e7eff" :value="item.sex" :checked="item.checked"></radio>{{item.name}}
+        </label>
+      </radio-group> -->
+	  <u-radio-group class="item-right radio-group" v-model="sex" >
+	  	<u-radio shape="circle"  name="1">男</u-radio>
+	  	<u-radio shape="circle"  name="2">女</u-radio>
+	  </u-radio-group>
+    </view>
+    <view v-if="waitAudit" class="form_group" :style="'pointer-events:' + (waitAudit?'auto':'none')">
+      <text class="sex">审核原因:</text>
+      <input @input="checkOpinionFun" placeholder="请填写审核原因" placeholder-class="placeholder_style" type="text" :value="checkOpinion" class="placeholder_style"></input>
+    </view>
+      <view v-if="nationality==3">
+      <view class="form_group mb0">
+        <view>
+          <text class="red">*</text>
+          <text class="sex">护照图片:</text>
+          <text class="tips">(基本身份信息页)</text>
+        </view>
+      </view>
+	  <view @click="operaType=1;chooseImage()" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+	    <upload-img
+	  	  :width="$isEmpty(show_passport_img_uri)?bgWidth:imgWidth"
+	  	  :height="$isEmpty(show_passport_img_uri)?bgHeight:imgHeight"
+	  	  :currentImage="show_passport_img_uri"
+	  	  :bgsrc="bgsrc"
+	  	  >
+	    </upload-img>
+	    <view class="" style="color: #59a5f0;">
+	  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+	  	 <text v-if="$isEmpty(show_passport_img_uri)">点击上传护照</text>
+	  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+	    </view>
+	  </view>
+    </view>
+
+    <view v-if="nationality==3">
+      <view class="form_group mb0">
+        <view>
+          <text class="red">*</text>
+          <text class="sex">入境证明:</text>
+          <text class="tips">(入镜盖章页)</text>
+        </view>
+      </view>
+	  
+	  <view @click="operaType=2;chooseImage()" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+	    <upload-img
+	  	  :width="$isEmpty(show_entry_img_uri)?bgWidth:imgWidth"
+	  	  :height="$isEmpty(show_entry_img_uri)?bgHeight:imgHeight"
+	  	  :currentImage="show_entry_img_uri"
+	  	  :bgsrc="bgsrc"
+	  	  >
+	    </upload-img>
+	    <view class="" style="color: #59a5f0;">
+	  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+	  	 <text v-if="$isEmpty(show_entry_img_uri)">点击上传入境证明</text>
+	  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+	    </view>
+	  </view>
+    </view>
+
+    <view class="form_group mb0">
+      <view>
+        <text class="red">*</text>
+        <text class="sex">人脸:</text>
+        <text class="tips">(人脸用于开门,请上传正脸图片)</text>
+      </view>
+    </view>
+
+    <view >
+	  <view @click="show=true;operaType=3" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+	    <upload-img
+	  	  :width="$isEmpty(show_image_uri)?bgWidth:imgWidth"
+	  	  :height="$isEmpty(show_image_uri)?bgHeight:imgHeight"
+	  	  :currentImage="show_image_uri"
+	  	  :bgsrc="bgsrc"
+	  	  >
+	    </upload-img>
+	    <view class="" style="color: #59a5f0;">
+	  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+	  	 <text v-if="$isEmpty(show_image_uri)">点击上传人面</text>
+	  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+	    </view>
+	  </view>
+      <view class="category">
+        <view v-for="(item, index) in iconArray" :key="index" class="category_item">
+          <view class="category_item_wrap" :data-index="item.index">
+            <view class="icon_wrap">
+              <image :src="item.iconUrl" class="index_icon"></image>
+            </view>
+            <view class="category_item_text">
+              <text>{{item.iconText}}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </form>
+ <view  @click="editApplyUser"  class=" footer-fixed" >
+  	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+  		提交修改
+  	</view>
+  </view>
+  
+  <view  v-if="waitAudit"  class=" footer-fixed" >
+	  <view class="flex">
+	  	<view @tap="auditBtn" data-id="1" class="cu-btn  flex-sub  text-lg bg-red-btn" style="padding: 46rpx 0rpx;">
+	  		审核通过
+	  	</view>
+		<view @tap="auditBtn" data-id="2" class="cu-btn  flex-sub  text-lg" style="padding: 46rpx 0;background-color: #fd9517;color: #FFFFFF;">
+			审核不通过
+		</view>
+	  </view>
+  </view>
+  <u-action-sheet @click="photoChecked"  z-index="999999" :list="list" v-model="show"></u-action-sheet>
+</view>
+</template>
+
+<script>
+import uploadImg from '@/comps/uploadimg/uploadImg.vue'
+//获取app实例
+var app = getApp();
+
+export default {
+	components:{
+		uploadImg
+	},
+  data() {
+    return {
+		//默认点击弹出拍照模态框的是人面上传操作,1:护照,2:入境,3:人面
+		operaType:3,
+		//人面上传模态框,上传照片或拍照
+		list: [{
+			text: '相册上传',
+		}, {
+			text: '拍照上传'
+		}],
+		show: false,
+		
+		//背景图
+		bgsrc:'http://139.9.103.171:1888/img/image/camera1.png',
+		bgWidth:350,
+		bgHeight:320,
+		//显示图
+		imgWidth:540,
+		imgHeight:400,
+		
+      user_id: null,
+      //修改的住户id
+      name: null,
+      //姓名
+      tel: null,
+      //电话号码
+      room_name: null,
+      //房间名字
+      typeArray: ['业主', '成员', '租户'],
+      type: 0,
+      nationalityArray: ['中国大陆', '中国香港/澳门', '中国台湾', '海外'],
+      nationality: 0,
+      nationalityName: '身份证',
+      id_card: null,
+      //身份证
+      sexArray: null,
+      sex: null	,
+      passport_img_uri: null,
+      //护照照片
+      show_passport_img_uri: null,
+      //护照照片回显
+      entry_img_uri: null,
+      //入境证明
+      show_entry_img_uri: null,
+      //入境证明回显
+      image_uri: null,
+      //人脸图片地址
+      show_image_uri: null,
+      //人脸回显
+      face_code: null,
+      iconArray: [{
+        "iconUrl": "http://139.9.103.171:1888/img/image/zd.png",
+        "iconText": '不要遮挡',
+        "index": 1
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/mj.png",
+        "iconText": '不戴墨镜',
+        "index": 2
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/zl.png",
+        "iconText": '不能仰头俯拍',
+        "index": 3
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/cz.png",
+        "iconText": '光线充足',
+        "index": 4
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/bg.png",
+        "iconText": '浅色背景',
+        "index": 5
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/sh.png",
+        "iconText": '物业审核生效',
+        "index": 6
+      }],
+      waitAudit: false,
+      //判断是否从审核跳过来
+      checkOpinion: '' //审核原因
+      ,
+      apply_user_id: "",
+      own_room_list_index: ""
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    let apply_user_id = options.apply_user_id;
+    let name = options.name;
+    let tel = options.tel;
+    let room_name = options.room_name;
+    let type = options.type;
+    let nationality = options.nationality;
+    let nationalityName = '';
+
+    if (nationality == 0) {
+      nationalityName = '身份证';
+    } else if (nationality == 1) {
+      nationalityName = '港澳居民往来内地通行证';
+    } else if (nationality == 2) {
+      nationalityName = '台湾居民往来大陆通行证';
+    } else if (nationality == 3) {
+      nationalityName = '护照';
+    }
+
+    this.setData({
+      nationality: nationality,
+      nationalityName: nationalityName
+    });
+    let id_card = options.id_card;
+    let sex = options.sex;
+    let passport_img_uri = options.passport_img_uri;
+    let entry_img_uri = options.entry_img_uri;
+    let image_uri = options.image_uri; //选中性别
+
+    let sexArray = [{
+      name: '男',
+      checked: false,
+      sex: "1"
+    }, {
+      name: '女',
+      checked: false,
+      sex: "2"
+    }];
+
+    for (let i in sexArray) {
+      if (sexArray[i].sex == sex) {
+        sexArray[i].checked = true;
+      }
+    }
+
+    if (options.waitAudit || options.waitAudit != undefined || options.waitAudit != null) {
+      uni.setNavigationBarTitle({
+        title: '住户审核'
+      });
+      this.setData({
+        waitAudit: options.waitAudit
+      });
+    }
+
+    this.setData({
+      apply_user_id: apply_user_id,
+      name: name,
+      tel: tel,
+      room_name: room_name,
+      type: type,
+      nationality: nationality,
+      id_card: id_card,
+      sex: sex,
+      show_image_uri: image_uri,
+      show_passport_img_uri: passport_img_uri,
+      show_entry_img_uri: entry_img_uri,
+      sexArray: sexArray
+    });
+  },
+  onShow() {
+  	//获取当前页面的对象
+  	let currPage=this.$util.getPageCtx()
+  	if(!this.$isEmpty(currPage.data.image)){
+  		this.uploadImage(currPage.data.image)
+  	} 
+  },
+  methods: {
+	//点击模态框选项触发
+	photoChecked(index){
+		if (index==0) {
+			//图片上传
+			this.chooseImage()
+		} else if(index==1){
+			//拍照上传
+			uni.navigateTo({
+				url:"../../my-camera/my-camera"
+			})
+		}
+	},
+	/**
+	 * 点击上传图片事件
+	 */
+	chooseImage: function () {
+	  var that = this;
+	  uni.chooseImage({
+	    count: 1,
+	    //最多可以选择的图片张数,默认9
+	    sourceType: ['album', 'camera'],
+	    sizeType: ['compressed'],
+	    //可选择原图或压缩后的图片
+	    success: res => {
+	      let tempFilePaths = res.tempFilePaths;
+		  that.uploadImage(tempFilePaths[0])
+	    }
+	  });
+	},
+	/**上传图片
+	 * @param {Object} imgUrl 图片url
+	 */
+	uploadImage(imgUrl){
+		console.log("operatype: ",this.operaType);
+		console.log("imgUrl",imgUrl)
+		var that = this;
+		//是否需要md5加密上传人面照
+		let is_need_md5 = false;
+		if (this.operaType == 3) {
+		  is_need_md5 = true;
+		}
+		uni.getFileSystemManager().readFile({
+		  filePath: imgUrl,
+		  //选择图片返回的相对路径
+		  encoding: 'base64',
+		  //编码格式
+		  success: res => {
+		    //成功的回调
+		    app.globalData.uploadBase64('data:image/jpeg;base64,' + res.data, is_need_md5, function (result) {
+		      if (that.operaType == 1) {
+		        that.setData({
+		          passport_img_uri: result.data.uri,
+		          show_passport_img_uri: imgUrl
+		        });
+		      } else if (that.operaType == 2) {
+		        that.setData({
+		          entry_img_uri: result.data.uri,
+		          show_entry_img_uri: imgUrl
+		        });
+		      } else if (that.operaType == 3) {
+		        that.setData({
+		          image_uri: result.data.uri,
+		          show_image_uri: imgUrl,
+		          face_code: result.data.md5Hex
+		        });
+		      }
+		    });
+		  }
+		});
+	},
+	  
+	  
+    //获取input的标签值
+    nameFun: function (e) {
+      this.setData({
+        name: e.detail.value
+      });
+    },
+    telFun: function (e) {
+      this.setData({
+        tel: e.detail.value
+      });
+    },
+    id_cardFun: function (e) {
+      this.setData({
+        id_card: e.detail.value
+      });
+    },
+    checkOpinionFun: function (e) {
+      this.setData({
+        checkOpinion: e.detail.value
+      });
+    },
+    // 住户类型
+    typeChange: function (e) {
+      this.setData({
+        type: e.detail.value
+      });
+    },
+    // 类别选择
+    roomIdChange: function (e) {
+      this.setData({
+        own_room_list_index: e.detail.value
+      });
+    },
+    //性别
+    sexChange: function (enent) {
+      this.setData({
+        sex: enent.detail.value
+      });
+    },
+    // 国籍
+    nationalityChange: function (e) {
+      let nationality = e.detail.value;
+      let nationalityName = '';
+
+      if (nationality == 0) {
+        nationalityName = '身份证';
+      } else if (nationality == 1) {
+        nationalityName = '港澳居民往来内地通行证';
+      } else if (nationality == 2) {
+        nationalityName = '台湾居民往来大陆通行证';
+      } else if (nationality == 3) {
+        nationalityName = '护照';
+      }
+
+      this.setData({
+        nationality: nationality,
+        nationalityName: nationalityName
+      });
+    },
+    //编辑
+    editApplyUser: function () {
+      let that = this;
+      let params = {};
+      let apply_user_id = that.apply_user_id;
+      params['apply_user_id'] = apply_user_id;
+      let tel = that.tel;
+
+      if (!tel) {
+        app.globalData.autoFailHint("请填写手机");
+        return;
+      } //手机号码正则校验
+
+
+      var telReg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/;
+
+      if (!telReg.test(tel)) {
+        app.globalData.autoFailHint("请填写正确手机号");
+        return;
+      }
+
+      params['tel'] = tel;
+      let type = that.type;
+      params['type'] = type;
+      let id_card = that.id_card;
+      params['id_card'] = id_card; //业主身份时,身份证必填
+
+      if (type == 0 && !id_card) {
+        app.globalData.autoFailHint("住户类型是业主时,身份证必填");
+        return;
+      } //0 中国大陆 1 中国香港/澳门 2 中国台湾 3 海外
+
+
+      let nationality = that.nationality;
+      params['nationality'] = nationality;
+      let passport_img_uri = that.passport_img_uri;
+      let entry_img_uri = that.entry_img_uri;
+
+      if (nationality == 3) {
+        params['passport_img_uri'] = that.passport_img_uri;
+        params['entry_img_uri'] = that.entry_img_uri;
+
+        if (type == 0) {
+          if (!passport_img_uri && !that.show_passport_img_uri) {
+            app.globalData.autoFailHint("请上传护照图片");
+            return;
+          }
+
+          if (!entry_img_uri && !that.show_entry_img_uri) {
+            app.globalData.autoFailHint("请上传入境证明");
+            return;
+          }
+        }
+      }
+
+      let image_uri = that.image_uri;
+      let face_code = that.face_code;
+
+      if (image_uri && face_code) {
+        params['image_uri'] = that.image_uri;
+        params['face_code'] = that.face_code;
+      } //性别
+
+
+      params['sex'] = that.sex; //添加了人脸
+
+      params['member_id'] = app.globalData.member.id; //申请来源0-小程序添加 1-后台添加  2-后台导入 3-app添加
+
+      params['create_type'] = '0';
+      let operation = 'applyUser/editApplyUser';
+      app.globalData.postRequest(params, operation, function (res) {
+        //添加成功
+        if (res.data.result_code == 1) {
+          app.globalData.oneFailHint(res.data.result_msg, function () {
+            uni.navigateBack({
+              delta: 1 // 返回上一级页面。
+
+            });
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    },
+
+    auditBtn(e) {
+      let that = this;
+      let params = {};
+
+      if (e.currentTarget.dataset.id == 2 && that.checkOpinion == '') {
+        app.globalData.autoFailHint("请先填写审核意见");
+        return;
+      }
+
+      params['id'] = that.apply_user_id;
+      params['checkState'] = e.currentTarget.dataset.id;
+      params['checkOpinion'] = that.checkOpinion;
+      let operation = 'applyUser/updateCheckState';
+      app.globalData.postRequest(params, operation, function (res) {
+        //添加成功
+        if (res.data.data) {
+          app.globalData.autoFailHint("审核成功");
+        } else {
+          app.globalData.autoFailHint(res.data.msg);
+        }
+      });
+    }
+
+  }
+};
+</script>
+<style lang="scss">
+page{
+  overflow-y: scroll;
+  background: #fff;
+}
+.edit_wrap {
+  font-size: 30rpx;
+  padding: 0rpx 20rpx 120rpx;
+  color: #333;
+}
+
+.form_group {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  margin: 20rpx 20rpx;
+  line-height: 80rpx;
+  position: relative;
+    font-size: 26rpx;
+}
+
+.form_group .red {
+  color: red;
+  position: absolute;
+  left: 0;
+}
+
+.form_group text.sex {
+  margin-left: 15px;
+  text-align: left;
+}
+
+.form_group .radio-group {
+  text-align: left;
+  width: 500rpx;
+  margin-top: 16rpx;
+}
+
+.form_group .radio-group .radio {
+  margin-right: 60rpx;
+}
+
+.form_group input, .form_group picker {
+  border: 1px solid #ddd;
+  border-radius: 8rpx;
+  height: 80rpx;
+  line-height: 80rpx;
+  padding: 0rpx 20rpx;
+  color: #333;
+  width: 460rpx;
+}
+
+.form_group button {
+  font-size: 30rpx;
+  height: 80rpx;
+  line-height: 80rpx;
+  border: 1px dotted #fff;
+  background: white;
+  padding: 0rpx;
+  margin: 0rpx;
+  outline: none;
+  color: #000;
+}
+
+.placeholder_style {
+  font-family: '微软雅黑';
+  color: #adadad;
+}
+
+.save_btn {
+  width: 600rpx;
+  background: #d24a58;
+  font-size: 32rpx;
+  color: #fff;
+  border-radius: 0rpx;
+  margin: 40rpx 0rpx 10rpx;
+}
+
+/* 自定义 radio 样式 */
+
+radio {
+  width: 38rpx;
+}
+
+radio .wx-radio-input {
+  border-radius: 50%;
+  width: 28rpx;
+  height: 28rpx;
+}
+
+/* 选中后的样式 (可根据设计稿需求自己修改) */
+
+radio .wx-radio-input.wx-radio-input-checked::before {
+  border-radius: 50%;
+  width: 44rpx;
+  height: 44rpx;
+  line-height: 44rpx;
+  text-align: center;
+  font-size: 26rpx; /* 对勾大小 26rpx */
+  color: #fff; /* 对勾颜色 */
+  background: $base-btn-color;
+  border-color: $base-btn-color;
+}
+
+.form_group .upload {
+  padding: 0 28rpx;
+  font-size: 26rpx;
+  background: $base-btn-color;
+  color: #fff;
+  border: none;
+}
+
+.upload_tips {
+  font-size: 24rpx;
+}
+
+.upload_bg {
+  position: relative;
+  text-align: center;
+}
+
+.mb0 {
+  margin-bottom: 0;
+}
+
+.form_group .tips {
+  margin-left: 50rpx;
+}
+
+.upload_bg .upload_bgImg {
+  width: 540rpx;
+  height: 400rpx;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, 0);
+  color: $base-btn-color;
+}
+upload_bg{
+  position: relative;
+text-align: center;
+}
+
+.upload_bg .upload_btn{
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 40%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+
+}
+.upload_bg .upload_btn image{
+  width: 100%;
+  height: 100%;
+}
+.upload_text{
+   position: absolute;
+   top: 55%;
+   width:100%;
+   color:$base-btn-color;
+     
+ 
+}
+
+.img_content .upload_bgImg{
+  
+  display: inline-block;
+}
+.reUpload{
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align:right;
+  color: #333;
+  padding-right: 100rpx;
+}
+.img_content .img_icon{
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 6rpx;
+  border-radius: 20rpx;
+}
+.category {
+  padding:20px 20rpx 0;
+  overflow: auto;
+  background-color: #FFF;
+text-align:center;
+
+}
+.category_item {
+  width: 33.3%;
+  float: left;
+  margin-bottom: 40rpx;
+}
+.icon_wrap {
+  width: 120rpx;
+  margin: 0 auto;
+  margin-bottom: 5px;
+}
+.index_icon {
+  width: 60rpx;
+  height: 60rpx;
+}
+.category_item_text {
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+}
+.bottom_btn{
+  width:100%;
+  background: $base-btn-color;
+  font-size: 32rpx;
+  color: #fff;
+  border-radius: 10rpx;
+  margin: 20rpx 10rpx;
+  height: 100rpx;
+  text-align: center;
+  line-height: 100rpx;
+}
+</style>

+ 670 - 0
pages/myFamily/editFamily/editFamily.vue

@@ -0,0 +1,670 @@
+<template>
+	<view class="" style="background-color: #FFFFFF;">
+		<view class="form" style="padding-top: 20rpx;">
+				<u-form :border="true" ref="uForm" >
+					<u-form-item :required="true"  label="姓名:" prop="name" label-width="150">
+						<u-input :disabled="true" :border="true"  placeholder="姓名,必填" v-model="name" type="text"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="手机号:" prop="tel" label-width="150">
+						<u-input :border="true" maxlength="11"  placeholder="请输入11位手机号码" v-model="tel" type="number"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="房间号:" prop="room_name" label-width="150">
+						<u-input :disabled="true" :border="true"  placeholder="请输入房间号" v-model="room_name" type="text"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"   label="住户类型:" prop="type" label-width="150">
+						<u-input :border="true"  type="select" :select-open="typeShow" v-model="typeLabel" placeholder="请选择住户类型" @click="typeShow = true"></u-input>
+					</u-form-item>
+					<u-form-item :required="true"  label="国籍:" prop="nationality" label-width="150">
+						<u-input :border="true" type="select" :select-open="nationalityShow" v-model="nationalityLabel"  @click="nationalityShow = true"></u-input>
+					</u-form-item>
+					<u-form-item   label="证件类型:" prop="nationalityName" label-width="150">
+						<u-input :disabled="true" :border="true" type="text" v-model="nationalityName"></u-input>
+					</u-form-item>
+					<u-form-item :required="type==0?true:false"  label="证件号码" prop="id_card" label-width="150">
+						<u-input :border="true" placeholder="住户类型是业主时,必填" :trim="true"  maxlength="18" v-model="id_card" type="number"></u-input>
+					</u-form-item>
+					<u-form-item :required="true" label="性别" prop="sex" label-width="150">
+						<u-radio-group v-model="sex" >
+							<u-radio shape="circle"  name="1">男</u-radio>
+							<u-radio shape="circle"  name="2">女</u-radio>
+						</u-radio-group>
+					</u-form-item>
+				</u-form>
+		</view>
+		<view v-if="nationality==3" style="background-color: #FFFFFF;">
+		  <view class="form_group mb0" style="padding-left: 60rpx;">
+		    <view>
+		      <text class="sex">护照图片:</text>
+		      <text class="tips">(基本身份信息页)</text>
+		    </view>
+		  </view>
+		  <view @click="operaType=1;chooseImage()" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+		    <upload-img
+		  	  :width="$isEmpty(show_passport_img_uri)?bgWidth:imgWidth"
+		  	  :height="$isEmpty(show_passport_img_uri)?bgHeight:imgHeight"
+		  	  :currentImage="show_passport_img_uri"
+		  	  :bgsrc="bgsrc"
+		  	  >
+		    </upload-img>
+		    <view class="" style="color: #59a5f0;">
+		  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+		  	 <text v-if="$isEmpty(show_passport_img_uri)">点击上传护照</text>
+		  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+		    </view>
+		  </view>
+		</view>
+		<view v-if="nationality==3" style="background-color: #FFFFFF;">
+		  <view class="form_group mb0" style="padding-left: 60rpx;">
+		    <view>
+		      <text class="sex">入境证明:</text>
+		      <text class="tips">(入镜盖章页)</text>
+		    </view>
+		  </view>
+		  <view @click="operaType=2;chooseImage()" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+		    <upload-img
+		  	  :width="$isEmpty(show_entry_img_uri)?bgWidth:imgWidth"
+		  	  :height="$isEmpty(show_entry_img_uri)?bgHeight:imgHeight"
+		  	  :currentImage="show_entry_img_uri"
+		  	  :bgsrc="bgsrc"
+		  	  >
+		    </upload-img>
+		    <view class="" style="color: #59a5f0;">
+		  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+		  	 <text v-if="$isEmpty(show_entry_img_uri)">点击上传入境证明</text>
+		  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+		    </view>
+		  </view>
+		</view>
+		
+		<view style="background-color: #FFFFFF;">
+					<view class="form_group mb0" style="padding-left: 60rpx;">
+						 <view>
+							<text class="sex">人脸:</text>
+							<text class="tips">(人脸用于开门,请上传正脸图片)</text>
+						  </view>
+					</view>
+					
+					<view @click="show=true;operaType=3" style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+					  <upload-img
+						  :width="$isEmpty(show_image_uri)?bgWidth:imgWidth"
+						  :height="$isEmpty(show_image_uri)?bgHeight:imgHeight"
+						  :currentImage="show_image_uri"
+						  :bgsrc="bgsrc"
+						  >
+					  </upload-img>
+					  <view class="" style="color: #59a5f0;">
+						 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+						 <text v-if="$isEmpty(show_image_uri)">点击上传人面</text>
+						 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+					  </view>
+					</view>
+					<view class="category" style="padding-bottom: 140rpx;">
+						<view v-for="(item, index) in iconArray" :key="index" class="category_item">
+						  <view class="category_item_wrap" @tap="top" :data-index="item.index">
+							<view class="icon_wrap">
+							  <image :src="item.iconUrl" class="index_icon"></image>
+							</view>
+							<view class="category_item_text">
+							  <text>{{item.iconText}}</text>
+							</view>
+						  </view>
+					</view>
+			</view>
+		</view>
+	  <u-action-sheet @click="photoChecked"  z-index="999999" :list="list" v-model="show"></u-action-sheet>
+	  <u-select z-index="999999" mode="single-column" :default-value="defaultType" :list="typeArry" v-model="typeShow" @confirm="typeConfirm"></u-select>
+	  <u-select z-index="999999" mode="single-column" :default-value="nationality" :list="nationalityArry" v-model="nationalityShow" @confirm="nationalityConfirm"></u-select>
+	  <view  @click="editUser" class=" footer-fixed" >
+	  	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+	  		确认修改
+	  	</view>
+	  </view>
+	</view>
+ </view>
+</template>
+
+<script>
+import uploadImg from '@/comps/uploadimg/uploadImg.vue'
+//获取app实例
+var app = getApp();
+export default {
+	components:{
+		uploadImg
+	},
+	data() {
+		return {
+			//默认点击弹出拍照模态框的是人面上传操作,1:护照,2:入境,3:人面
+			operaType:3,
+			//人面上传模态框,上传照片或拍照
+			list: [{
+				text: '相册上传',
+			}, {
+				text: '拍照上传'
+			}],
+			show: false,
+			
+			//背景图
+			bgsrc:'http://139.9.103.171:1888/img/image/camera1.png',
+			bgWidth:350,
+			bgHeight:320,
+			//显示图
+			imgWidth:540,
+			imgHeight:400,
+			
+			//修改的住户id
+			  user_id: null,
+			  //姓名
+			  name: null,
+			  //电话号码
+			  tel: null,
+			  //住户类型
+			  defaultType:[0],
+			  typeLabel:'业主',
+			  typeShow: false,
+			  type: 0,
+			  typeArry: [
+			  	{
+			  		value: '0',
+			  		label: '业主'
+			  	},
+			  	{
+			  		value: '1',
+			  		label: '成员'
+			  	},
+			  	{
+			  		value: '2',
+			  		label: '租户'
+			  	}
+			  ],
+			  //国籍
+			  defaultNationality:[0],
+			  nationalityLabel:'中国大陆',
+			  nationalityShow: false,
+			  nationality: 0,
+			  nationalityName:'身份证',
+			  nationalityArry: [
+			  	{
+			  		value: '0',
+			  		label: '中国大陆'
+			  	},
+			  	{
+			  		value: '1',
+			  		label: '中国香港/澳门'
+			  	},
+			  	{
+			  		value: '2',
+			  		label: '中国台湾'
+			  	},
+			  	{
+			  		value: '3',
+			  		label: '海外'
+			  	}
+			  ],
+			  //身份证
+			  id_card: null,
+			  sex: "1",
+			  
+			  //护照照片
+			  passport_img_uri: null,
+			  //护照照片回显
+			  show_passport_img_uri: null,
+			  //入境证明
+			  entry_img_uri: null,
+			  //入境证明回显
+			  show_entry_img_uri: null,
+			  //人脸图片地址
+			  image_uri: null,
+			  //人脸回显
+			  show_image_uri: null,
+			  //图片的md5
+			  face_code: null,
+
+			  //图片的md5
+			  iconArray: [{
+				"iconUrl": "http://139.9.103.171:1888/img/image/zd.png",
+				"iconText": '不要遮挡',
+				"index": 1
+			  }, {
+				"iconUrl": "http://139.9.103.171:1888/img/image/mj.png",
+				"iconText": '不戴墨镜',
+				"index": 2
+			  }, {
+				"iconUrl": "http://139.9.103.171:1888/img/image/zl.png",
+				"iconText": '不能仰头俯拍',
+				"index": 3
+			  }, {
+				"iconUrl": "http://139.9.103.171:1888/img/image/cz.png",
+				"iconText": '光线充足',
+				"index": 4
+			  }, {
+				"iconUrl": "http://139.9.103.171:1888/img/image/bg.png",
+				"iconText": '浅色背景',
+				"index": 5
+			  }, {
+				"iconUrl": "http://139.9.103.171:1888/img/image/sh.png",
+				"iconText": '物业审核生效',
+				"index": 6
+			  }],
+			  room_name: ""
+		};
+	},
+	onShow() {
+		//获取当前页面的对象
+		let currPage=this.$util.getPageCtx()
+		if(!this.$isEmpty(currPage.data.image)){
+			this.uploadImage(currPage.data.image)
+		} 
+	},
+	onLoad: function (options) {
+		let that=this
+		
+		let user_id = options.user_id;
+		let name = options.name;
+		let tel = options.tel;
+		let room_name = options.room_name;
+		let type = options.type;
+		let nationality = options.nationality;
+		
+		if (!nationality) {
+		  nationality = 0;
+		}
+		
+		let nationalityName = '';
+		
+		if (nationality == 0) {
+		  nationalityName = '身份证';
+		} else if (nationality == 1) {
+		  nationalityName = '港澳居民往来内地通行证';
+		} else if (nationality == 2) {
+		  nationalityName = '台湾居民往来大陆通行证';
+		} else if (nationality == 3) {
+		  nationalityName = '护照';
+		}
+		
+		this.setData({
+		  nationality: nationality,
+		  nationalityName: nationalityName
+		});
+		let id_card = options.id_card;
+		let sex = options.sex;
+		let passport_img_uri = options.passport_img_uri ||null;
+		let entry_img_uri = options.entry_img_uri || null;
+		let image_uri = options.image_uri || null; //选中性别
+		this.setData({
+		  user_id: user_id,
+		  name: name,
+		  tel: tel,
+		  room_name: room_name,
+		  type: type,
+		  nationality: nationality,
+		  id_card: id_card,
+		  sex: sex,
+		  show_image_uri: image_uri,
+		  show_passport_img_uri: passport_img_uri,
+		  show_entry_img_uri: entry_img_uri,
+		 
+		}); 
+		this.defaultType=[]
+		this.defaultType.push(type)
+		this.typeLabel=that.typeArry[type].label,
+		this.defaultNationality=[]
+		this.defaultNationality.push(nationality)
+		this.nationalityLabel=that.nationalityArry[nationality].label
+		
+	},
+	methods: {
+		//点击模态框选项触发
+		photoChecked(index){
+			if (index==0) {
+				//图片上传
+				this.chooseImage()
+			} else if(index==1){
+				//拍照上传
+				uni.navigateTo({
+					url:"../../my-camera/my-camera"
+				})
+			}
+		},
+		typeConfirm(e) {
+			this.type = 0;
+			e.map((val, index) => {
+				this.type=val.value
+				this.typeLabel=val.label
+			})
+		},
+		nationalityConfirm(e) {
+			this.nationality = 0;
+			e.map((val, index) => {
+				this.nationality=val.value
+				this.nationalityLabel=val.label
+				
+				if (this.nationality == 0) {
+				  this.nationalityName = '身份证';
+				} else if (this.nationality == 1) {
+				  this.nationalityName = '港澳居民往来内地通行证';
+				} else if (this.nationality == 2) {
+				  this.nationalityName = '台湾居民往来大陆通行证';
+				} else if (this.nationality == 3) {
+				  this.nationalityName = '护照';
+				}
+			})
+		},
+		//点击上传图片事件
+		chooseImage: function () {
+		  var that = this;
+		  uni.chooseImage({
+		    count: 1,
+		    //最多可以选择的图片张数,默认9
+		    sourceType: ['album', 'camera'],
+		    sizeType: ['compressed'],
+		    //可选择原图或压缩后的图片
+		    success: res => {
+		      let tempFilePaths = res.tempFilePaths;
+			  that.uploadImage(tempFilePaths[0])
+		    }
+		  });
+		},
+		/**上传图片
+		 * @param {Object} imgUrl 图片url
+		 */
+		uploadImage(imgUrl){
+			console.log("operatype: ",this.operaType);
+			console.log("imgUrl",imgUrl)
+			var that = this;
+			//是否需要md5加密上传人面照
+			let is_need_md5 = false;
+			if (this.operaType == 3) {
+			  is_need_md5 = true;
+			}
+			uni.getFileSystemManager().readFile({
+			  filePath: imgUrl,
+			  //选择图片返回的相对路径
+			  encoding: 'base64',
+			  //编码格式
+			  success: res => {
+			    //成功的回调
+			    app.globalData.uploadBase64('data:image/jpeg;base64,' + res.data, is_need_md5, function (result) {
+			      if (that.operaType == 1) {
+			        that.setData({
+			          passport_img_uri: result.data.uri,
+			          show_passport_img_uri: imgUrl
+			        });
+			      } else if (that.operaType == 2) {
+			        that.setData({
+			          entry_img_uri: result.data.uri,
+			          show_entry_img_uri: imgUrl
+			        });
+			      } else if (that.operaType == 3) {
+			        that.setData({
+			          image_uri: result.data.uri,
+			          show_image_uri: imgUrl,
+			          face_code: result.data.md5Hex
+			        });
+			      }
+			    });
+			  }
+			});
+		},
+		//添加家人
+		editUser: function () {
+		  let that = this;
+		  let params = {};
+		  let user_id = that.user_id;
+		  params['user_id'] = user_id;
+		  let tel = that.tel;
+		
+		  if (!tel) {
+		    app.globalData.autoFailHint("请填写手机");
+		    return;
+		  } //手机号码正则校验
+		  var telReg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/;
+		
+		  if (!telReg.test(tel)) {
+		    app.globalData.autoFailHint("请填写正确手机号");
+		    return;
+		  }
+		
+		  params['tel'] = tel;
+		  
+		  let type = that.type;
+		  params['type'] = type;
+		  let id_card = that.id_card;
+		  params['id_card'] = id_card; //业主身份时,身份证必填
+		
+		  if (type == 0 && !id_card) {
+		    app.globalData.autoFailHint("住户类型是业主时,身份证必填");
+		    return;
+		  } //0 中国大陆 1 中国香港/澳门 2 中国台湾 3 海外
+		
+		
+		  let nationality = that.nationality;
+		  params['nationality'] = nationality;
+		  let passport_img_uri = that.passport_img_uri;
+		  let entry_img_uri = that.entry_img_uri;
+		
+		  if (nationality == 3) {
+		    params['passport_img_uri'] = that.passport_img_uri;
+		    params['entry_img_uri'] = that.entry_img_uri;
+		
+		    if (type == 0) {
+		      if (!passport_img_uri && !that.show_passport_img_uri) {
+		        app.globalData.autoFailHint("请上传护照图片");
+		        return;
+		      }
+		
+		      if (!entry_img_uri && !that.show_entry_img_uri) {
+		        app.globalData.autoFailHint("请上传入境证明");
+		        return;
+		      }
+		    }
+		  }
+		
+		  let image_uri = that.image_uri;
+		  let face_code = that.face_code;
+		
+		  if (image_uri && face_code) {
+		    params['image_uri'] = that.image_uri;
+		    params['face_code'] = that.face_code;
+		  } //性别
+		
+		
+		  params['sex'] = that.sex; //添加了人脸
+		
+		  params['member_id'] = app.globalData.member.id; //申请来源0-小程序添加 1-后台添加  2-后台导入 3-app添加
+		
+		  params['create_type'] = '0';
+		  console.log(params)
+		  let operation = 'user/editUser';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //添加成功
+		    if (res.data.result_code == 1) {
+		      app.globalData.oneFailHint(res.data.result_msg, function () {
+		        uni.navigateBack({
+		          delta: 1 // 返回上一级页面。
+		
+		        });
+		      });
+		    } else {
+		      app.globalData.oneFailHint(res.data.result_msg);
+		    }
+		  });
+		}
+		
+	}
+};
+</script>
+
+<style scoped lang="scss">
+.form {
+	padding:0 60rpx;
+	background-color: #FFFFFF;
+}
+
+.local_city{
+    padding: 30rpx 0;
+    position:relative;
+    background: #fff;
+}
+.local_city .changeCity{
+    padding: 20rpx;
+    position: absolute;
+    right: 0rpx;
+    top: 0;
+}
+.local_city .icon{
+    padding: 20rpx;
+    position: absolute;
+    left: -0;
+    top: 50%;
+    transform: translate(0,-50%);
+    font-size: 40rpx;
+}
+.local_city .local_city_info{
+    padding-left: 40rpx;
+    display:inline-block;
+}
+
+.form_group .upload {
+  padding: 0 28rpx;
+  font-size: 26rpx;
+  background: $base-btn-color;
+  color: #fff;
+  border: none;
+}
+
+.upload_tips {
+  font-size: 24rpx;
+}
+
+.upload_bg {
+  position: relative;
+  text-align: center;
+}
+
+.mb0 {
+  padding-top: 40rpx;
+  font-size: 28rpx;
+  margin-bottom: 0;
+}
+
+.form_group .tips {
+  margin-left: 50rpx;
+}
+
+.upload_bg .upload_bgImg {
+  width: 540rpx;
+  height: 400rpx;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 70%;
+  left: 50%;
+  transform: translate(-50%, 0);
+  color: $base-btn-color;
+}
+
+upload_bg {
+  position: relative;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 40%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 55%;
+  width: 100%;
+  color: $base-btn-color;
+}
+
+.img_content {
+  margin-top: 20rpx;
+  position: relative;
+  text-align: center;
+}
+
+.img_content .upload_bgImg {
+  width: 560rpx;
+  height: 420rpx;
+  max-height: 1;
+  display: inline-block;
+  border-radius: 20rpx;
+}
+
+.reUpload {
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: right;
+  color: #333;
+  padding-right: 100rpx;
+  font-size: 26rpx;
+}
+
+.img_content .img_icon {
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 6rpx;
+  border-radius: 20rpx;
+}
+
+.category {
+  padding:20px 20rpx 0;
+  overflow: auto;
+  background-color: #FFF;
+text-align:center;
+
+}
+.category_item {
+  width: 33.3%;
+  float: left;
+  margin-bottom: 40rpx;
+}
+
+.icon_wrap {
+  width: 120rpx;
+  margin: 0 auto;
+  margin-bottom: 5px;
+}
+.index_icon {
+  width: 60rpx;
+  height: 60rpx;
+}
+.category_item_text {
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+}
+
+</style>
+
+			
+		

+ 833 - 0
pages/myFamily/myFamily.vue

@@ -0,0 +1,833 @@
+<template>
+	<view :class="$isEmpty(user_list)||$isEmpty(apply_user_list)||$isEmpty(auditList)?'empty-wrap':''" :style="swiperCurrent==0?'':'background-color: #FFFFFF;'">
+		<view class="wrap">
+			<!-- <u-select v-model="show" :list="list"></u-select> -->
+			<u-sticky>
+				<u-tabs :list="list" font-size="29" active-color="#2f7ff5" inactive-color="#a6a6a6" bar-width="80"  :is-scroll="false" :current="current" @change="change"></u-tabs>
+			</u-sticky>
+			<swiper class="swiper-box" :current="swiperCurrent" @change="swiperChange" >
+				<swiper-item class="swiper-item">
+					<scroll-view v-if="!this.$isEmpty(user_list)" scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom">
+						<view class="cu-list menu" @click="locationShow=true">
+							<view class="cu-item" >
+								<view class="content">
+									<text >我的房屋</text>
+								</view>
+								<view class="action">
+									<text >{{selectLabel?selectLabel:room_list[0].name}}</text>
+									<text class="cuIcon-right padding-left-10"></text>
+								</view>
+							</view>
+						</view>
+						<view class="myFamily" >
+							<view class="data" v-for="(item, index) in user_list" :key="index"  style="border-bottom: 1rpx solid #b6b6b6;">
+								<view class="top">
+									<view class="left">
+										<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
+										<view class="title">{{item.residentialName}}{{item.unitName}}{{item.roomName}}</view>
+									</view>
+								</view>
+								<view class="item">
+									<view class="left">
+										<view  data-aid="undefined">
+										  <image v-if="item.imageUri" mode="aspectFill" :src="item.imageUri">
+										  </image>
+										  <image v-if="item.imageUri==null" mode="aspectFill" src="http://139.9.103.171:1888/img/image/head.png">
+										  </image>
+										</view>
+										
+										<view class="content" data-aid="undefined">
+											<view >姓名:{{item.name}}</view>
+											<view >手机:{{item.tel}}</view>
+											<view >创建时间:{{item.createDate}}</view>
+											<view v-if="item.type==0">身份:业主</view>
+											<view v-if="item.type==1">身份:成员</view>
+											<view v-if="item.type==2">身份:租户</view>
+											<view v-if="item.type==3">身份:访客</view>
+										</view>
+									</view>
+								</view>
+								<view class="bottom" >
+									<navigator :url="'/pages/myFamily/editFamily/editFamily?user_id=' + item.id + '&name=' + item.name + '&tel=' + item.tel + '&room_name=' + item.roomName + '&type=' + item.type + '&id_card=' + (item.idCard==null?'':item.idCard) + '&sex=' + item.sex + '&nationality=' + (item.nationality==null?'':item.nationality) + '&image_uri=' + (item.imageUri==null?'':item.imageUri) + '&passport_img_uri=' + (item.passportImgUri==null?'':item.passportImgUri) + '&entry_img_uri=' + (item.entryImgUri==null?'':item.entryImgUri)" class="cu-btn line-btn round sm margin-right-sm"  @click.stop="">
+										编辑
+									</navigator>
+									<navigator :url="'/pages/myFamily/activateFace/activateFace?room_id=' + item.roomId + '&user_id=' + item.id + '&name=' + item.name + '&tel=' + item.tel + '&room_name=' + item.roomName + '&type=' + item.type + '&id_card=' + (item.idCard==null?'':item.idCard) + '&sex=' + item.sex + '&nationality=' + (item.nationality==null?'':item.nationality) + '&image_uri=' + (item.imageUri==null?'':item.imageUri) + '&passport_img_uri=' + (item.passportImgUri==null?'':item.passportImgUri) + '&entry_img_uri=' + (item.entryImgUri==null?'':item.entryImgUri)" class="cu-btn line-btn round sm margin-right-sm"  @click.stop="">
+										人面激活
+									</navigator>
+									<view v-if="item.isShowDelete"  :data-user_id="item.id" class="cu-btn bg-btn sm round" @click.stop="deleteUserById">
+										删除
+									</view>
+								</view>
+								
+							</view>
+						</view>
+					</scroll-view>
+					<view class="default" v-else>
+					   <image src="/static/empty.png" mode="heightFix"></image>
+					  <view>
+					    <text>没有相关信息</text>
+					  </view>
+					</view>
+				</swiper-item>
+				<swiper-item class="swiper-item">
+					<scroll-view v-if="apply_user_list.length>0" scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom">
+						<view class="myFamily" v-if="apply_user_list.length>0">
+						  <view style="border-bottom: 1rpx solid #b6b6b6;" v-for="(item, index) in apply_user_list" :key="index" class="nav_list" hover-class="none">
+						    <view class="flex">
+								<view class="margin-right-10 " style="margin-top: 2rpx;">
+									<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
+								</view>
+						    	<view class="">
+									<text>{{item.residentialName}}{{item.unitName}}{{item.roomName}}</text>
+						    	</view>
+						    </view>
+						    <view class="myFamily_items">
+						      <view class="section_image" data-aid="undefined">
+						        <image style="border-radius: 50%;" v-if="item.imageUri" mode="aspectFill" :src="item.imageUri">
+						        </image>
+						        <image style="border-radius: 50%;" v-if="item.imageUri==null" mode="aspectFill" src="http://139.9.103.171:1888/img/image/head.png">
+						        </image>
+						      </view>
+						      <view class="section_cont" data-aid="undefined">
+						        <view class="section_cont_sub">
+						          <text>姓名:{{item.name}}</text>
+						          <text class="figure renter" v-if="item.type==0">身份:业主</text>
+						          <text class="figure renter" v-else-if="item.type==1">身份:成员</text>
+						          <text class="figure renter" v-else-if="item.type==2">身份:租客</text>
+						          <text class="figure renter" v-else-if="item.type==2">身份:访客</text>
+						        </view>
+						        <view class="section_cont_tel">
+						          <text>手机:{{item.tel}}</text>
+						        </view>
+						        <view class="section_cont_tel">
+						          <text>申请时间:{{item.createDate}}</text>
+						        </view>
+						        <view class="section_cont_tel">
+						          <view class data-aid="undefined">
+						            <text>状态:</text>
+						            <text v-if="item.checkState==0" class="col_red">待审核</text>
+						            <text v-if="item.checkState==1" class="col_red">审核通过</text>
+						            <text v-if="item.checkState==2" class="col_red">审核不通过</text>
+						          </view>
+						          <view class="section_cont_reason" v-if="item.checkState==2">
+						            <text class="reason">原因:<text class="col_red">{{item.checkOpinion}}</text> </text>
+						          </view>
+						        </view>
+						      </view>
+						      <!--审核不通过时显示 且会员有权限-->
+						      <view class="section_edit" v-if="item.isShow">
+						        <navigator :url="'/pages/myFamily/editApplyFamily/editApplyFamily?apply_user_id=' + item.id + '&name=' + item.name + '&tel=' + item.tel + '&room_name=' + item.roomName + '&type=' + item.type + '&id_card=' + (item.idCard==null?'':item.idCard) + '&sex=' + item.sex + '&nationality=' + item.nationality + '&image_uri=' + (item.imageUri==null?'':item.imageUri) + '&passport_img_uri=' + (item.passportImgUri==null?'':item.passportImgUri) + '&entry_img_uri=' + (item.entryImgUri==null?'':item.entryImgUri)">
+						          <view class="edit_btn">编辑</view>
+						        </navigator>
+						      </view>
+						    </view>
+						  </view>
+						</view>
+					</scroll-view>
+					<view class="default" v-if="apply_user_list==null || apply_user_list.length==0">
+						<image src="/static/empty.png" mode="heightFix"></image>
+					  <view>
+					    <text>没有相关信息</text>
+					  </view>
+					</view>
+				</swiper-item>
+				<swiper-item class="swiper-item">
+					<scroll-view scroll-y style="height: 100%;width: 100%;">
+						<view class="myFamily" v-if="auditList.length>0">
+						  <view style="border-bottom: 1rpx solid #b6b6b6;" v-for="(item, index) in auditList" :key="index" class="nav_list" hover-class="none">
+						    <view class="flex">
+						    	<view style="width: 40rpx;height: 40rpx;padding-right: 10rpx;">
+						    		<image src="http://139.9.103.171:1888/img/image/building.png"></image>
+						    	</view>
+						    	<view class="">
+									<text>{{item.residentialName}}{{item.unitName}}{{item.roomName}}</text>
+						    	</view>
+						    </view>
+						    <view class="myFamily_items">
+						      <view class="section_image" data-aid="undefined">
+						        <image v-if="item.imageUri" mode="aspectFill" :src="item.imageUri">
+						        </image>
+						        <image v-if="item.imageUri==null" mode="aspectFill" src="http://139.9.103.171:1888/img/image/head.png">
+						        </image>
+						      </view>
+						      <view class="section_cont" data-aid="undefined">
+						        <view class="section_cont_sub">
+						          <text>姓名:{{item.name}}</text>
+						          <text class="figure renter" v-if="item.type==0">身份:业主</text>
+						          <text class="figure renter" v-else-if="item.type==1">身份:成员</text>
+						          <text class="figure renter" v-else-if="item.type==2">身份:租客</text>
+						          <text class="figure renter" v-else-if="item.type==2">身份:访客</text>
+						        </view>
+						        <view class="section_cont_tel">
+						          <text>手机:{{item.tel}}</text>
+						        </view>
+						        <view class="section_cont_tel">
+						          <text>申请时间:{{item.createDate}}</text>
+						        </view>
+						        <view class="section_cont_tel">
+						          <view class data-aid="undefined">
+						            <text>状态:</text>
+						            <text v-if="item.checkState==0" class="col_red">待审核</text>
+						            <text v-if="item.checkState==1" class="col_red">审核通过</text>
+						            <text v-if="item.checkState==2" class="col_red">审核不通过</text>
+						          </view>
+						          <view class="section_cont_reason" v-if="item.checkState==2">
+						            <text class="reason">原因:<text class="col_red">{{item.checkOpinion}}</text> </text>
+						          </view>
+						        </view>
+						      </view>
+						      <!--审核不通过时显示 且会员有权限-->
+						      <view class="section_edit">
+						        <navigator :url="'/pages/myFamily/editApplyFamily/editApplyFamily?apply_user_id=' + item.id + '&name=' + item.name + '&tel=' + item.tel + '&room_name=' + item.roomName + '&type=' + item.type + '&id_card=' + (item.idCard==null?'':item.idCard) + '&sex=' + item.sex + '&nationality=' + item.nationality + '&image_uri=' + (item.imageUri==null?'':item.imageUri) + '&passport_img_uri=' + (item.passportImgUri==null?'':item.passportImgUri) + '&entry_img_uri=' + (item.entryImgUri==null?'':item.entryImgUri) + '&waitAudit=true'">
+						          <view class="edit_btn">审核</view>
+						        </navigator>
+						      </view>
+						    </view>
+						  </view>
+						</view>
+					</scroll-view>
+					<view class="default" v-if="auditList==null || auditList.length==0">
+					<image src="/static/empty.png" mode="heightFix"></image>
+					  <view>
+					    <text>没有相关信息</text>
+					  </view>
+					</view>
+				</swiper-item>
+			</swiper>
+		</view>
+		<u-select z-index="9999999"  mode="single-column"  value-name="id" label-name="name" v-model="locationShow" :list="room_list" @confirm="roomChange"></u-select>
+		<view style="height: 10rpx;"></view>
+		<!-- <navigator url="/pages/myFamily/addFamily/addFamily" v-if="own_room_list.length>0" class="bg-white footer-fixed padding-10" >
+			<view class="cu-btn  flex radius text-lg" style="padding: 46rpx 0;background-color: #5db5fe;color: #FFFFFF;">
+				添加家人
+				
+			</view>
+		</navigator> -->
+		<view @click="add" v-if="own_room_list.length>0" class=" footer-fixed" >
+			<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+				添加家人
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+var util = require("../../utils/util.js");
+	
+export default {
+	data() {
+		return {
+			locationShow:false,
+			selectLabel:'',
+	
+			//房屋成员
+			user_list: null,
+			//申请的认证列表
+			apply_user_list: null,
+			//审核列表
+			auditList: [],
+			//房屋id集合(业主)
+			room_ids: [],
+		
+			//当前用户业主身份的房子
+			own_room_list: null,
+			//当前显示住户信息下标
+			room_list_index: 0,
+			//复制一份user_list用于筛选房屋列表
+			user_lists: [] ,
+			room_list: "",
+			
+			list: [
+				{
+					name: '审核通过'
+				},
+				{
+					name: '申请记录'
+				},
+				{
+					name: '住户审核'
+				}
+			],
+			current: 0,
+			swiperCurrent: 0,
+		};
+	},
+	onLoad() {
+		this.initData()
+	},
+	onShow() {
+		this.initData()
+	},
+	methods: {
+		initData(){
+			this.geRoomByMemberId();
+			this.getAllApplyUserByMemberId();
+			this.getAllApplyUserByRoomIds();
+		},
+		add(){
+			uni.navigateTo({
+				url:"./add/add"
+			})
+		},
+		roomChange: function (e) {
+			// 选中的房屋 id
+		  let id=e[0].value
+		  //选中的房屋名字
+		  this.selectLabel=e[0].label
+		  //选中的房屋列表的下标
+		  let index= this.room_list.findIndex(value => value.id===id)
+		  
+		  // let index=e.detail.value
+		  let list = [];
+		  this.user_lists.map(item => {
+		    if (this.room_list[index].name == item.roomName) {
+		      list.push(item);
+		    }
+		  }); //拿到当前选择的房间,判断是否该显示添加家人按钮
+		
+		  let room_list = [];
+		  room_list.push(this.room_list[index]);
+		  this.ownRoomLists(room_list);
+		  this.setData({
+		    room_list_index: index,
+		    user_list: list
+		  });
+		  console.log(index)
+		},
+		//删除我的家人
+		deleteUserById: function (event) {
+		  let that = this;
+		  app.globalData.twoFailHint("确认删除该住户吗?", function () {
+		    //住户id
+		    let user_id = event.target.dataset.user_id;
+		    let params = {};
+		    params['member_id'] = app.globalData.member.id;
+		    params['user_id'] = user_id;
+		    let operation = 'user/deleteUserById';
+		    app.globalData.postRequest(params, operation, function (res) {
+		      console.info("获取成功" + res.data.result_msg); //删除成功
+		
+		      if (res.data.result_code == 1) {
+		        app.globalData.autoFailHint(res.data.result_msg, function () {
+		          //重新获取列表
+		          that.getAllUserByMemberId();
+		        });
+		      } else {
+		        app.globalData.oneFailHint(res.data.result_msg);
+		      }
+		    });
+		  });
+		},
+		//根据会员id获取我的家人列表
+		getAllUserByMemberId: function () {
+		  let that = this;
+		  let params = {
+			  "pageNum":0,
+			  "pageSize":15
+		  };
+		  params['member_id'] = app.globalData.member.id;
+		  let operation = 'user/getAllUserByMemberId';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //获取成功
+		    if (res.data.result_code == 1) {
+		      let user_list = res.data.list; //业主身份的房子
+		      let own_room_list = that.own_room_list;
+		
+		      for (let index in user_list) {
+		        user_list[index].createDate = util.formatTime(user_list[index].createDate);
+		        if (own_room_list.length > 0) {
+		          for (let i in own_room_list) {
+		            //该成员有被会员修改的权限
+		            if (user_list[index].roomId == own_room_list[i].id) {
+		              //显示 编辑
+		              user_list[index]['isShowEdit'] = true; //自己不能删除自己   且业主身份也不能删除
+		
+		              if (user_list[index].type != 0) {
+		                user_list[index]['isShowDelete'] = true;
+		              }
+		            }
+		          }
+		        } else {
+		          if (app.globalData.member.name == user_list[index].name) {
+		            //显示 编辑
+		            user_list[index]['isShowEdit'] = true;
+		          }
+		        }
+		      } //过滤掉其他小区,保留选择小区
+		      let list = [];
+		
+		      if (uni.getStorageSync('plotName')) {
+		        user_list.map(item => {
+		          if (item.residentialName == uni.getStorageSync('plotName')) {
+		            list.push(item);
+		          }
+		        });
+		      } else {
+		        list = user_list;
+		        list = user_lists;
+		      }
+		      that.setData({
+		        user_list: list,
+		        user_lists: list
+		      });
+		    } else {
+		      console.info("获取失败:" + res.data.result_msg);
+		    }
+		  });
+		},
+		//根据会员id获取我的申请列表
+		getAllApplyUserByMemberId: function () {
+		  let that = this;
+		  let params = {
+			  pageSize:200,
+			  pageNum:0
+		  };
+		  params['member_id'] = app.globalData.member.id;
+		  ;
+		  let operation = 'applyUser/getAllApplyUserByMemberId';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //获取成功
+		    if (res.data.result_code == 1) {
+		      //业主身份的房子
+		      let own_room_list = that.own_room_list;
+		      let apply_user_list = res.data.list;
+		      for (let index in apply_user_list) {
+		        //格式化日期
+		        apply_user_list[index].createDate = util.formatTime(apply_user_list[index].createDate);
+		
+		        if (own_room_list.length > 0) {
+		          //有业主身份的房子
+		          for (let i in own_room_list) {
+		            //该成员有被会员修改的权限--审核不通过
+		            if (apply_user_list[index].checkState == 2 && apply_user_list[index].roomId == own_room_list[i].id) {
+		              //显示 编辑
+		              apply_user_list[index]['isShow'] = true;
+		            }
+		          }
+		        } else {
+		          //没有业主身份的房子
+		          if (app.globalData.member.name == apply_user_list[index].name && apply_user_list[index].checkState == 2) {
+		            //显示 编辑
+		            apply_user_list[index]['isShow'] = true;
+		          }
+		        }
+		      } //过滤掉其他小区,保留选择小区
+		
+		
+		      let list = [];
+		
+		      if (uni.getStorageSync('plotName')) {
+		        apply_user_list.map(item => {
+		          if (item.residentialName == uni.getStorageSync('plotName')) {
+		            list.push(item);
+		          }
+		        });
+		      } else {
+		        list = apply_user_list;
+		      }
+		
+		      that.setData({
+		        apply_user_list: list
+		      });
+		    } else {
+		      console.info("获取失败:" + res.data.result_msg);
+		    }
+		  });
+		},
+		//根据会员id获取我的房屋列表
+		geRoomByMemberId() {
+		  let that = this;
+		  let params = {};
+		  params['member_id'] = app.globalData.member.id;
+		  console.log(params)
+		  let operation = 'estate/getRoomByMemberId';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    console.info("获取成功" + res.data.result_msg); //获取成功
+		    // if (res.data.result_code == 1) {
+		    //   that.setData({
+		    //     room_list: res.data.list
+		    //   })
+		    //   app.room_list = res.data.list;
+		    //   that.ownRoomList(res.data.list);
+		    // }
+		
+		    if (res.data.result_code == 1) {
+		      let list = [];
+		      if (uni.getStorageSync('plotName')) {
+		        if (that.room_ids.length > 0) {
+		          that.room_ids.splice(0, that.room_ids.length);
+		        }
+		        res.data.list.map(item => {
+		          if (item.residentialName == uni.getStorageSync('plotName')) {
+		            list.push(item);
+		          }
+		          if (item.residentialName == uni.getStorageSync('plotName') && item.relationshipType == 0) {
+		            that.room_ids.push(item.id);
+		          }
+		        });
+		      } else {
+		        list = res.data.list;
+		      }
+		      that.setData({
+		        room_list: list,
+		        room_ids: that.room_ids //获取我的房屋id集合(业主)
+		
+		      });
+			  
+		      that.getAllApplyUserByRoomIds();
+		      app.globalData.room_list = list;
+		      that.ownRoomList(list);
+		    }
+		  });
+		},
+		//获取审核列表
+		getAllApplyUserByRoomIds: function () {
+		  let that = this;
+		  let params = {};
+		  params['room_ids'] = that.room_ids;
+		  params['check_states'] = "0";
+		  let operation = 'applyUser/getAllApplyUserByRoomIds';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //获取成功
+		    if (res.data.result_code == 1) {
+		      that.setData({
+		        auditList: res.data.list
+		      });
+		    }
+		  });
+		},
+		//业主身份的房子
+		ownRoomList: function (room_list) {
+		  let own_room_list = new Array();
+		
+		  for (let index in room_list) {
+		    //是业主身份的房子
+		    if (room_list[index].relationshipType == 0) {
+		      //业主
+		      own_room_list.push(room_list[index]);
+		    }
+		  }
+		
+		  this.setData({
+		    own_room_list: own_room_list
+		  }); //不常变数据保存到全局变量
+		
+		  app.globalData.own_room_list = own_room_list; //家庭成员
+		
+		  this.getAllUserByMemberId();
+		},
+		ownRoomLists: function (room_list) {
+		  let own_room_list = new Array();
+		
+		  for (let index in room_list) {
+		    //是业主身份的房子
+		    if (room_list[index].relationshipType == 0) {
+		      //业主
+		      own_room_list.push(room_list[index]);
+		    }
+		  }
+		
+		  this.setData({
+		    own_room_list: own_room_list
+		  }); //不常变数据保存到全局变量
+		
+		  app.globalData.own_room_list = own_room_list;
+		},
+		reachBottom() {
+			
+		},
+		// 轮播菜单
+		swiperChange(e){
+			this.swiperCurrent=e.detail.current
+			this.current = e.detail.current
+			// this.fetchData()
+		},
+		change(index){
+			this.swiperCurrent=index
+			this.current = index;
+			// this.fetchData()
+		},
+		fetchData(){
+			let index=this.current
+			if(index==0){
+			  this.geRoomByMemberId();
+			}else if(index==1){
+			  this.getAllApplyUserByMemberId();
+			}else if(index==2){
+				this.getAllApplyUserByRoomIds();
+			}
+		}
+	}
+};
+</script>
+
+
+<style lang="scss" scoped>
+.wrap {
+	display: flex;
+	flex-direction: column;
+	height: calc(100vh - var(--window-top));
+	width: 100%;
+}
+.swiper-box {
+	flex: 1;
+}
+.swiper-item {
+	height: 100%;
+}
+/* pages/myHome/myHome.wxss */
+.container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+}
+
+.nav {
+  display: flex;
+  height: 80rpx;
+  border-bottom: 1rpx solid #c7c7c9;
+  background: #fff;
+}
+
+.nav view {
+  flex: 1;
+  text-align: center;
+  height: 80rpx;
+  line-height: 80rpx;
+  color: #4a586a;
+}
+
+.nav view.active {
+  color: $base-btn-color;
+  border-bottom: 4rpx solid $base-btn-color;
+}
+
+.wrapCity {
+  flex: 1;
+}
+
+.wrapCity swiper {
+  height: 100%;
+}
+
+scroll-view {
+  display: box;
+  height: 100%;
+}
+
+.myFamily {
+  width: 100%;
+  padding-bottom: 100rpx;
+}
+
+.nav_list {
+  padding: 20rpx;
+  border-radius: 10rpx;
+  background: #fff;
+  margin-top: 4rpx;
+}
+
+.myFamily_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  position: relative;
+}
+
+
+.myFamily_items .section_image {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  top: 50%;
+  transform: translate(0, -50%);
+}
+
+.myFamily_items .identity {
+  font-size: 24rpx;
+  color: #d24a58;
+}
+
+.myFamily_items .section_image image {
+  width: 100%;
+  height: 100%;
+}
+
+.myFamily_items .section_cont {
+  font-size: 24rpx;
+  color: #666;
+  margin-left: 140rpx;
+}
+
+.reason{
+ text-overflow: -o-ellipsis-lastline;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+.myFamily_items .section_cont .section_cont_intro {
+  white-space: normal;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+
+.myFamily_items .section_cont .section_cont_sub {
+  font-size: 28rpx;
+  line-height: 50rpx;
+  color: #666;
+  margin-bottom: 10rpx;
+}
+
+.myFamily_items .section_cont .section_cont_tel {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 50rpx;
+  margin-bottom: 10rpx;
+}
+
+.myFamily_items .section_cont .section_cont_state {
+  font-size: 28rpx;
+}
+
+.myFamily_items .section_edit {
+  font-size: 24rpx;
+  position: absolute;
+  top: 50%;
+  right: 20rpx;
+  transform: translate(0, -50%);
+}
+
+.figure {
+  color: #d24a58;
+  border: 1px solid #d24a58;
+  border-radius: 6rpx;
+  font-size: 24rpx;
+  padding: 0 6rpx;
+  margin-left: 10rpx;
+}
+
+.figure.renter {
+  color: $base-btn-color;
+  border: 1px solid $base-btn-color;
+}
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 250rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+.edit_btn{
+ background: $base-btn-color;
+  color: #fff;
+  height: 50rpx;
+  line-height: 50rpx;
+  border-radius: 10rpx;
+  padding:0 16rpx;
+  margin:6rpx;
+  text-align: center;
+}
+.delete_btn{
+ background: #d24a58;
+  color: #fff;
+
+
+}
+.col_red{
+  color: #d24a58;
+}
+
+.form_group {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 0 20rpx;
+  background: #fff;
+  line-height: 100rpx;
+  position: relative;
+  font-size: 26rpx;
+  border-bottom: 2rpx solid #ddd;
+  
+}
+.my-item .iconfont.arrow {
+  position: absolute;
+  right: 0;
+  top: 50%;
+  transform: translate(0, -50%);
+  font-size: 32rpx;
+  vertical-align: top;
+ 
+}
+.my-item {
+  width: 100%;
+  position: relative;
+  background: #fff;
+  font-size: 28rpx;
+  box-sizing: border-box;
+}
+
+.my-item .status {
+  position: absolute;
+  right: 35rpx;
+  top: 50%;
+  transform: translate(0, -50%);
+  font-size: 28rpx;
+}
+
+
+	.cu-btn.sm {
+		padding: 0 24upx;
+		font-size: 24upx;
+		height: 54upx;
+	}
+	
+	.data {
+		background-color: #FFFFFF;
+		width: 720rpx;
+		margin:10rpx auto;
+		border-radius: 6rpx;
+		box-sizing: border-box;
+		padding: 20rpx;
+		font-size: 28rpx;
+		.top {
+			display: flex;
+			justify-content: space-between;
+			.left {
+				display: flex;
+				align-items: center;
+				.title {
+					margin: 0 10rpx;
+					font-size: 32rpx;
+					font-weight: bold;
+				}
+			}
+		}
+		.item {
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			margin: 40rpx 0 20rpx 0;
+			.left {
+				display: flex;
+				image {
+					width: 130rpx;
+					height: 130rpx;
+					border-radius: 50%;
+				}
+				.content {
+					padding-left: 30rpx;
+					view{
+						padding-bottom: 16rpx;
+					}
+				}
+			}
+		}
+		.bottom {
+			display: flex;
+			margin-top: 20rpx;
+			justify-content: flex-end;
+			align-items: center;
+		}
+	}
+</style>

+ 83 - 0
pages/myPassword/myPassword.vue

@@ -0,0 +1,83 @@
+<template>
+<view class="container">
+  <view class="password_top">
+    <image mode="aspectFill" src="http://139.9.103.171:1888/img/image/wechat.png"></image>
+  </view>
+  <view class="password_bg">
+        <view class="tips">请妥善保管!</view>
+      <view class="password"><text class="w200">动态密码:</text><text class="col">{{password}}</text></view>
+      <view class="date"><text class="w200">有效次数:</text><text class="col">{{valid_count}}次</text></view>
+      <view class="time"><text class="w200">有效期至:</text><text class="col">{{end_date}}</text></view>
+  </view>
+</view>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      valid_count: null,
+      password: null,
+      end_date: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    this.setData({
+      valid_count: options.valid_count,
+      password: options.password,
+      end_date: options.end_date
+    });
+  },
+  methods: {}
+};
+</script>
+<style lang="scss" scoped>
+/* pages/myPassword/myPassword.wxss */
+.password_top{
+  text-align: center;
+  height: 300rpx;
+  background: $base-btn-color;
+  padding:80rpx;
+}
+.password_top image{
+  width: 160rpx;
+  height: 160rpx;
+  border-radius: 50%;
+}
+.password_bg{
+  background: #fff;
+  width: 80%;
+  border-radius: 10rpx;
+  position: fixed;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%,-50%);
+  padding:40rpx 20rpx;
+ 
+}
+.password_bg view{
+  line-height: 100rpx;
+ box-shadow:0px 30rpx 20px -30rpx #e2e2e2;
+}
+.password_bg view text.w200{
+  width: 200rpx;
+  text-align: right;
+  display: inline-block;
+}
+.password_bg .tips{
+  text-align: center;
+  color: #d24a58;
+}
+.password_bg .col{
+  font-size: 700;
+  color: $base-btn-color;
+}
+</style>

+ 204 - 0
pages/myhome/familyList.vue

@@ -0,0 +1,204 @@
+<template>
+<view :class="$isEmpty(user_list)?'empty-wrap':''">
+<view class="nav_section" v-if="user_list!=null && user_list.length!=0">
+  <view v-for="(item, index) in user_list" :key="index" class="nav_list">
+    <view class="nav_section_items">
+      <view class="section_image" data-aid="undefined">
+        <image v-if="item.imageUri" mode="aspectFill" :src="item.imageUri">
+        </image>
+        <image v-if="item.imageUri==null" mode="aspectFill" src="http://139.9.103.171:1888/img/image/head.png">
+        </image>
+      </view>
+      <view class="section_cont" data-aid="undefined">
+        <view class="section_cont_sub">
+          <text>姓名:{{item.name}}</text>
+        </view>
+        <view class="section_cont_tel">
+          <text>手机:{{item.tel}}</text>
+        </view>
+        <view class="section_cont_tel">
+          <text v-if="item.type==0">身份:业主</text>
+          <text v-else-if="item.type==1">身份:成员</text>
+          <text v-else-if="item.type==2">身份:租客</text>
+          <text v-else-if="item.type==3">身份:访客</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</view>
+<!-- 1-业主  业主身份才能添加房屋成员 wx:if="{{relationship==1}}" -->
+<!-- <view class='submit_btn'>
+  <navigator url='/pages/myHome/myHomeFamily/addMyHomeFamily/addMyHomeFamily?room_id={{room_id}}&relationship={{relationship}}'>
+    <button class="ar_btn">添加成员</button>
+  </navigator>
+</view> -->
+<view class="default" v-else>
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有获取到房屋成员信息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      user_list: null
+    };
+  },
+  onLoad(options) {
+  	let room_id = options.room_id; //获取房间下的住户
+  	console.log(room_id)
+  	this.getUserByRoomId(room_id);
+  },
+  methods: {	  
+    //获取房间下的住户
+    getUserByRoomId: function (room_id) {
+      let that = this;
+      let params = {
+		  pageSize:200,
+		  pageNum:0,
+		  room_id:room_id
+	  };
+      let operation = 'user/getUserByRoomId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取数据结构" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          that.setData({
+            user_list: res.data.list
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+page {
+  overflow-y: scroll;
+}
+
+.nav_section {
+  width: 100%;
+  padding-bottom: 120rpx;
+}
+.nav_list{
+  margin-top: 2rpx;
+}
+.nav_section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+ 
+  position: relative;
+  background: #fff;
+}
+.nav_section_items .section_image {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  top: 50%;
+  transform: translate(0, -50%);
+}
+
+.nav_section_items .identity {
+  font-size: 24rpx;
+  color: #d24a58;
+}
+
+.nav_section_items .section_image image {
+  width: 100%;
+  height: 100%;
+}
+
+.nav_section_items .section_cont {
+  width: 400rpx;
+  font-size: 24rpx;
+  color: #666;
+  margin-left: 140rpx;
+}
+
+.nav_section_items .section_cont view {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+}
+
+.nav_section_items .section_cont .section_cont_intro {
+  white-space: normal;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+
+.nav_section_items .section_cont .section_cont_sub {
+  font-size: 28rpx;
+  line-height: 50rpx;
+  color: #666;
+  margin-bottom: 10rpx;
+}
+
+.nav_section_items .section_cont .section_cont_tel {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 50rpx;
+  margin-bottom: 10rpx;
+}
+
+.nav_section_items .section_cont .section_cont_state {
+  font-size: 28rpx;
+}
+
+.nav_section_items .section_edit {
+  width: 80rpx;
+  height: 40rpx;
+  font-size: 26rpx;
+  border-radius: 10rpx;
+  background: #d24a58;
+  line-height: 40rpx;
+  color: #fff;
+  text-align: center;
+  position: absolute;
+  top: 50%;
+  right: 20rpx;
+  transform: translate(0, -50%);
+}
+
+.building {
+  height: 80rpx;
+  line-height: 80rpx;
+  background: #fff;
+  padding: 0 20rpx;
+  color: #333;
+  border-bottom: 2rpx solid #ddd;
+}
+
+.building image {
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 10rpx;
+}
+.figure{
+  color: #d24a58;
+  border:1px solid #d24a58;
+  border-radius: 6rpx;
+  font-size: 24rpx;
+  padding: 0 6rpx;
+  margin-left: 10rpx;
+}
+.figure.renter{
+  color: $base-btn-color;
+  border:1px solid $base-btn-color;
+
+}
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 250rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+</style>

+ 177 - 0
pages/myhome/myhome.vue

@@ -0,0 +1,177 @@
+<template>
+<view :class="$isEmpty(room_list)?'empty-wrap':''">
+<view v-if="!$isEmpty(room_list)" style="padding-bottom: 90rpx;">
+	<view class="data" v-for="(item, index) in room_list" :key="index">
+		<view class="top">
+			<view class="left">
+				<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
+				<view class="title">{{item.residentialName}}</view>
+			</view>
+		</view>
+		<view class="item">
+			<view class="left">
+				<view style="padding: 0 30rpx;">
+					<view class="content">
+						<text>楼栋信息:</text>
+						<text >{{item.unitName}}</text>
+					</view>
+					<view class="content">
+						<text>房间信息:</text>
+						<text>{{item.name}}</text>
+					</view>
+					<view class="content">
+						<text>身份:</text>
+						<text  v-if="item.relationshipType==0">业主</text>
+						<text  v-if="item.relationshipType==1">成员</text>
+						<text  v-if="item.relationshipType==2">租户</text>
+						<text  v-if="item.relationshipType==3">访客</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="bottom" >
+			<view class="cu-btn  sm round bg-red-btn"  @click="jump(item.id)">
+				房屋成员
+			</view>
+		</view>
+	</view>
+	<view @tap="choosePlot" class="footer-fixed" >
+		<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+			添加房屋认证
+		</view>
+	</view>
+</view>
+
+<view class="default" v-else>
+	  <image src="/static/empty.png" mode="heightFix"></image>
+	<view>
+    <text>没有获取到我的房屋信息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      room_list: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    //获取房屋信息
+    this.geRoomByMemberId();
+  },
+  methods: {
+	  
+	 jump(id){
+		 uni.navigateTo({
+			 url:"./familyList?room_id="+id
+		 })
+	 },
+    //根据会员id获取我的房屋列表
+    geRoomByMemberId: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+	  params['pageSize'] = 200;
+      let operation = 'estate/getRoomByMemberId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取成功" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          let list = [];
+
+          if (uni.getStorageSync('plotName')) {
+            res.data.list.map(item => {
+              if (item.residentialName == uni.getStorageSync('plotName')) {
+                list.push(item);
+              }
+            });
+          } else {
+            list = res.data.list;
+          }
+
+          that.setData({
+            room_list: list
+          });
+          app.globalData.room_list = list;
+        }
+      });
+    },
+
+    choosePlot() {
+		if(!this.$isEmpty(app.globalData.totalStep)){
+			app.globalData.totalStep=2
+		}
+		  uni.navigateTo({
+			url:"../auth/auth"
+		  })
+    }
+
+  }
+};
+</script>
+<style lang="scss">
+
+view,
+button
+ {
+	box-sizing: border-box;
+}
+
+.cu-btn.sm {
+	padding: 0 24upx;
+	font-size: 24upx;
+	height: 52upx;
+}
+
+.data {
+	width: 710rpx;
+	background-color: #ffffff;
+	margin: 20rpx auto;
+	border-radius: 6rpx;
+	box-sizing: border-box;
+	padding: 20rpx;
+	font-size: 28rpx;
+	.top {
+		display: flex;
+		justify-content: space-between;
+		.left {
+			display: flex;
+			align-items: center;
+			.title {
+				margin: 0 10rpx;
+				font-size: 32rpx;
+				font-weight: bold;
+			}
+		}
+	}
+	.item {
+		margin: 40rpx 0 20rpx 0;
+		.content {
+			border-bottom: 1rpx dashed #DDDDDD;
+			display: flex;
+			justify-content: space-between;
+			padding: 30rpx 0;
+		}
+	}
+	.bottom {
+		display: flex;
+		margin-top: 30rpx;
+		justify-content: flex-end;
+		align-items: center;
+	}
+}
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 250rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+</style>

+ 50 - 0
pages/notice/detail.vue

@@ -0,0 +1,50 @@
+<template>
+	<view>
+		<!--文章标题-->
+		<view class="text-black text-bold text-lg title">停水停电通知。</view>
+		<view class="content-view-box">
+			<view class="font-view">
+				<u-parse :html="content"></u-parse>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		components: {
+		},
+		data() {
+			return {
+				content:'市政通水设施突发性故障抢修,本小区供水压力暂受影响,敬请做好储水准备,预约影响时间2020年11月28号22时至11月29号16时,由此给您带来不便,敬请谅解。'
+			}
+		},
+		onLoad(options) {
+			
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+
+<style lang="scss">
+	page {
+		background: #FFFFFF;
+	}
+	.title {
+		margin: 36.36rpx 27.27rpx;
+	}
+
+	.content-view-box {
+		position: relative;
+		.font-view {
+			padding: 27.27rpx;
+			line-height: 1.7;
+		}
+		image {
+			width: 100%;
+		}
+	}
+</style>

+ 194 - 0
pages/notice/notice.vue

@@ -0,0 +1,194 @@
+<template>
+	<view>
+		<view class="cu-load padding-top-10" :class="ajax.loading?'loading':''" @tap="getHistoryMsg"></view>
+		<navigator :url="'./detail?id='+item.id" class="cart-view-box" v-for="(item,index) in msgList" :key="index" :id="`msg-${item.id}`">
+			<view class="text-gray text-center">{{item.time}}</view>
+			<view class="bg-white margin-top radius card-view">
+				<view class="content-view">
+					<view class="text-black text-bold text-lg text-cut">{{item.title}}</view>
+					<view class=" text-sm text-cut-2 subtitle">{{item.subtitle}}</view>
+					<view class="flex  justify-between padding-top-20" style=" border-top: 1rpx solid #f2f2f2;box-sizing: border-box;">
+						<view class="text-df text-black">
+							<text>查看详情</text>
+						</view>
+						<view style="padding-top: 8rpx;">
+							<text class=" cuIcon-right"></text>
+						</view>
+					</view>
+				</view>
+			</view>
+		</navigator>
+	</view>
+</template>
+
+<script>
+	import DtCustomBar from '@/comps/dt_custom_bar.vue'
+	export default {
+		components:{
+			DtCustomBar
+		},
+		data() {
+			return {
+				msgList:[],
+				ajax:{
+					rows:10,	//每页数量
+					page:1,	//页码
+					flag:true,	// 请求开关
+					loading:true,	// 加载中
+				},
+				content:''
+			}
+		},
+		mounted() {
+			this.$nextTick(()=>{
+				this.getHistoryMsg();
+			});
+		},
+		onPageScroll(e){
+			if(e.scrollTop<5){
+				this.getHistoryMsg();
+			}
+		},
+		onLoad() {
+		},
+		methods: {
+			// 获取历史消息
+			getHistoryMsg(){
+				if(!this.ajax.flag){
+					return; //
+				}
+				// 此处用到 ES7 的 async/await 知识,为使代码更加优美。不懂的请自行学习。
+				let get = async ()=>{
+					this.hideLoadTips();
+					this.ajax.flag = false;
+					let data = await this.joinHistoryMsg();
+					
+					console.log('----- 模拟数据格式,供参考 -----');
+					console.log(data);	// 查看请求返回的数据结构 
+					
+					// 获取待滚动元素选择器,解决插入数据后,滚动条定位时使用
+					let selector = '';
+										
+					if(this.ajax.page>1){
+						// 非第一页,则取历史消息数据的第一条信息元素
+						selector = `#msg-${this.msgList[0].id}`;
+					}else{
+						
+						// 第一页,则取当前消息数据的最后一条信息元素
+						selector = `#msg-${data[data.length-1].id}`;
+					}
+					
+					// 将获取到的消息数据合并到消息数组中
+					this.msgList = [...data,...this.msgList];	
+					
+					// 数据挂载后执行,不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
+					this.$nextTick(()=>{
+						// 设置当前滚动的位置
+						this.setPageScrollTo(selector);
+						
+						this.hideLoadTips(true);
+												
+						if(data.length < this.ajax.rows){
+							// 当前消息数据条数小于请求要求条数时,则无更多消息,不再允许请求。
+							// 可在此处编写无更多消息数据时的逻辑
+						}else{
+							this.ajax.page ++;
+							
+							// 延迟 200ms ,以保证设置窗口滚动已完成
+							setTimeout(()=>{
+								this.ajax.flag = true;
+							},200)
+						}
+						
+					})
+				}
+				get();
+			},
+			// 拼接历史记录消息,正式项目可替换为请求历史记录接口
+			joinHistoryMsg(){
+				let join = ()=>{
+					let arr = [];
+					//通过当前页码及页数,模拟数据内容
+					let startIndex = (this.ajax.page-1) * this.ajax.rows;
+					let endIndex = startIndex + this.ajax.rows;
+					for(let i = startIndex; i < endIndex; i++){
+						arr.push({
+							"id":i,	// 消息的ID
+							"time":'2020年11月18日 11:00:18',
+							"title":`${i+1}放假通知`,	// 消息内容
+							"subtitle":'2020年10月1日-2020年10月8日,中秋 国庆节放假,假期间需注意,祝国庆节玩的开心。'	,
+						})
+					}
+					/*
+						颠倒数组中元素的顺序。将最新的数据排在本次接口返回数据的最后面。
+						后端接口按 消息的时间降序查找出当前页的数据后,再将本页数据按消息时间降序排序返回。
+						这是数据的重点,因为页面滚动条和上拉加载历史的问题。
+					 */
+					arr.reverse();
+					
+					return arr;
+				}
+				
+				// 此处用到 ES6 的 Promise 知识,不懂的请自行学习。
+				return new Promise((done,fail)=>{
+					// 无数据请求接口,由 setTimeout 模拟,正式项目替换为 ajax 即可。
+					setTimeout(()=>{
+						let data = join();
+						done(data);
+					},800);
+				})
+			},
+			// 设置页面滚动位置
+			setPageScrollTo(selector){
+				let view = uni.createSelectorQuery().in(this).select(selector);
+				view.boundingClientRect((res) => {
+					uni.pageScrollTo({
+					    scrollTop:res.top - 30,	// -30 为多显示出大半个消息的高度,示意上面还有信息。
+					    duration: 0
+					});
+				}).exec();
+			},
+			// 隐藏加载提示
+			hideLoadTips(flag){
+				if(flag){
+					console.log("333");
+					setTimeout(()=>{
+						this.ajax.loading = false;
+					},300);
+				}else{
+					this.ajax.loading = true;
+				}
+			},
+		},
+		
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color: #F3F3F3;
+		font-size: 28rpx;
+	}
+	.subtitle{
+		color: #7e7e7e;
+		font-size: 28rpx;
+		margin: 50rpx 0 10rpx 0;
+		line-height: 52rpx;
+	}
+	.cart-view-box {
+		padding: 36.36rpx 27.27rpx;
+		.card-view {
+			background-color: #FFFFFF;
+			position: relative;
+			border-radius: 10rpx;
+			.head-img {
+				width: 100%;
+				height: 236.36rpx;
+				border-radius: 9.09rpx 9.09rpx 0 0;
+			}
+			.content-view {
+				padding: 27.27rpx;
+			}
+		}
+	}
+</style>

+ 164 - 0
pages/oneButton/oneButton.vue

@@ -0,0 +1,164 @@
+<template>
+<view :class="$isEmpty(device_list)?'empty-wrap':''">
+<view class="openButton_contain" v-if="device_list.length>0">
+	<view class="padding-30" v-for="(item, index) in device_list" :key="index"  style="border-bottom: 1rpx solid #EEEEEE;display: flex;justify-content: space-between;">
+		<text style="margin: 8rpx 0 0 6rpx;">{{item.name}}</text>
+		<view :data-device_id="item.id" @tap="openDoor" class="cu-btn bg-red sm round " >
+			立即开门
+		</view>
+	</view>
+  <!-- <view v-for="(item, index) in device_list" :key="index" class="openButton_list">
+      <view class="info">{{item.name}}</view>
+	  <view class="cu-btn round sm bg-red">
+		立即开门
+	  </view>
+      <view class="button" :data-device_id="item.id" @tap="openDoor">立即开门</view>
+  </view> -->
+</view>
+<view class="default" v-if="$isEmpty(device_list)">
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有获取到设备信息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+		isFirst:true,
+      device_list: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    // let device_list = app.device_list;
+    // if (device_list){
+    //   this.setData({
+    //     device_list: device_list
+    //   })
+    // }else{
+    // 如果设备列表为空--则去拉取一次
+    // }
+	this.isFirst=false
+    this.getAuthDevice();
+  },
+  onShow() {
+  	if(!this.isFirst){
+  		this.getAuthDevice();
+  	}
+  },
+  methods: {
+    //立即开门
+    openDoor: function (event) {
+      let device_id = event.currentTarget.dataset.device_id;
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      params['device_id'] = device_id;
+      let operation = 'member/openDoor';
+      app.globalData.postRequest(params, operation, function (res) {
+        app.globalData.oneFailHint(res.data.result_msg);
+      });
+    },
+    //获取用户的授权设备列表
+    getAuthDevice: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      let operation = 'member/getAuthDeviceByMemberId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("查询结果:" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          // let list = res.data.list;
+          // console.log(list)
+          // that.setData({
+          //   device_list: list
+          // })
+          // app.device_list = list;
+          let list = [];
+
+          if (uni.getStorageSync('plotName')) {
+            res.data.list.map(item => {
+              if (item.name.indexOf(uni.getStorageSync('plotName')) >= 0) {
+                list.push(item);
+              }
+            });
+          } else {
+            list = res.data.list;
+          }
+
+          that.setData({
+            device_list: list
+          });
+          app.globalData.device_list = list;
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+view,
+button
+{
+    box-sizing: border-box;
+}
+
+.cu-btn.sm {
+    padding: 0 26rpx;
+    font-size: 24rpx;
+    height: 54rpx;
+}
+	
+	
+page {
+  overflow-y: scroll;
+  background-color: #FFFFFF;
+  height: 100vh;
+}
+
+.openButton_contain {
+  padding-top: 30rpx;
+}
+
+.openButton_list {
+  width: 100%;
+  padding: 0 20rpx;
+  border-bottom: 1px solid #eee;
+  height: 120rpx;
+  line-height: 120rpx;
+  background: #fff;
+  position: relative;
+  box-sizing: border-box;
+}
+
+.openButton_list .button {
+  position: absolute;
+  right: 20rpx;
+  top: 50%;
+  transform: translate(0, -50%);
+  border: 1px solid $base;
+  height: 60rpx;
+  line-height: 60rpx;
+  padding: 0 20rpx;
+  border-radius: 6rpx;
+  color: #fff;
+  background: $base;
+}
+
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 250rpx;
  display: inline-block;
}
.empty-wrap{
	background-color: #FFFFFF;
	min-height: 100vh;
}
+
+</style>

+ 554 - 0
pages/poster/poster.vue

@@ -0,0 +1,554 @@
+<template>
+    <view class="poster_page">
+		<swiper class="poster_swiper" previous-margin="110rpx" circular :current="swiperIndex" next-margin="110rpx" @change="onSwiperChange">
+		    <swiper-item v-for="(item, index) of list" :key="index">
+		        <view class="goods_info_box" :class="{ active: swiperIndex == index }">
+		            <image class="goods_image" :src="item.headImgs" mode="scaleToFill"></image>
+		            <view class="goods_info">
+		                <view class="goods_name">{{item.goodsName}}</view>
+		                <view class="price_box">
+		                    <view class="price">¥{{item.goodsPrice}}</view>
+							<view class="store_price">¥{{item.disCountPrice}}</view>
+		                </view>
+		                <view class="poster_info">
+		                    <view class="info">
+		                        <view>扫描二维码访问</view>
+		                        <text>{{platformName}}</text>
+		                    </view>
+		                    <image class="poster_code_image" :src="recommendCodeGoods" mode="aspectFit"></image>
+		                </view>
+		            </view>
+		        </view>
+		    </swiper-item>
+		</swiper>
+        <canvas canvas-id="poster" class="poster_canvas"></canvas>
+       
+        <view class="share_save_box">
+			<view class="push_button" @click="onSaveImg">
+				<text style="font-size: 28rpx;">保存图片</text>
+			</view>
+        </view>
+    </view>
+</template>
+<script>
+// 文字换行
+function drawtext(text, maxWidth) {
+    let textArr = text.split("");
+    let len = textArr.length;
+    // 上个节点
+    let previousNode = 0;
+    // 记录节点宽度
+    let nodeWidth = 0;
+    // 文本换行数组
+    let rowText = [];
+    // 如果是字母,侧保存长度
+    let letterWidth = 0;
+    // 汉字宽度
+    let chineseWidth = 21;
+    // otherFont宽度
+    let otherWidth = 10.5;
+    for (let i = 0; i < len; i++) {
+        if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) {
+            if(letterWidth > 0){
+                if(nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth){
+                    rowText.push({
+                        type: "text",
+                        content: text.substring(previousNode, i)
+                    });
+                    previousNode = i;
+                    nodeWidth = chineseWidth;
+                    letterWidth = 0;
+                } else {
+                    nodeWidth += chineseWidth + letterWidth * otherWidth;
+                    letterWidth = 0;
+                }
+            } else {
+                if(nodeWidth + chineseWidth > maxWidth){
+                    rowText.push({
+                        type: "text",
+                        content: text.substring(previousNode, i)
+                    });
+                    previousNode = i;
+                    nodeWidth = chineseWidth;
+                }else{
+                    nodeWidth += chineseWidth;
+                }
+            }
+        } else {
+            if(/\n/g.test(textArr[i])){
+                rowText.push({
+                    type: "break",
+                    content: text.substring(previousNode, i)
+                });
+                previousNode = i + 1;
+                nodeWidth = 0;
+                letterWidth = 0;
+            }else if(textArr[i] == "\\" && textArr[i + 1] == "n"){
+                rowText.push({
+                    type: "break",
+                    content: text.substring(previousNode, i)
+                });
+                previousNode = i + 2;
+                nodeWidth = 0;
+                letterWidth = 0;
+            }else if(/[a-zA-Z0-9]/g.test(textArr[i])){
+                letterWidth += 1;
+                if(nodeWidth + letterWidth * otherWidth > maxWidth){
+                    rowText.push({
+                        type: "text",
+                        content: text.substring(previousNode, i + 1 - letterWidth)
+                    });
+                    previousNode = i + 1 - letterWidth;
+                    nodeWidth = letterWidth * otherWidth;
+                    letterWidth = 0;
+                }
+            } else{
+                if(nodeWidth + otherWidth > maxWidth){
+                    rowText.push({
+                        type: "text",
+                        content: text.substring(previousNode, i)
+                    });
+                    previousNode = i;
+                    nodeWidth = otherWidth;
+                }else{
+                    nodeWidth += otherWidth;
+                }
+            }
+        }
+    }
+    if (previousNode < len) {
+        rowText.push({
+            type: "text",
+            content: text.substring(previousNode, len)
+        });
+    }
+    return rowText;
+}
+let settingWritePhotosAlbum = false;
+export default {
+    data() {
+        return {
+			list:[
+				{
+					goodsName:'麦趣尔纯牛奶 早餐奶 新疆全脂牛奶 营养盒装鲜奶',
+					headImgs:'https://cms.gzhylwh.com/visit/hyl/445195a7-5b85-42c0-aa4c-f4bc0ca3d7a0detail.png',
+					goodsPrice:'98',
+					disCountPrice:'89'
+				},
+				{
+					goodsName:'麦趣尔纯牛奶 早餐奶 新疆全脂牛奶 营养盒装鲜奶',
+					headImgs:'https://cms.gzhylwh.com/visit/hyl/445195a7-5b85-42c0-aa4c-f4bc0ca3d7a0detail.png',
+					goodsPrice:'98',
+					disCountPrice:'89'
+				},
+				{
+					goodsName:'麦趣尔纯牛奶 早餐奶 新疆全脂牛奶 营养盒装鲜奶',
+					headImgs:'https://cms.gzhylwh.com/visit/hyl/445195a7-5b85-42c0-aa4c-f4bc0ca3d7a0detail.png',
+					goodsPrice:'98',
+					disCountPrice:'89'
+				},
+				{
+					goodsName:'麦趣尔纯牛奶 早餐奶 新疆全脂牛奶 营养盒装鲜奶',
+					headImgs:'https://cms.gzhylwh.com/visit/hyl/445195a7-5b85-42c0-aa4c-f4bc0ca3d7a0detail.png',
+					goodsPrice:'98',
+					disCountPrice:'89'
+				}
+			],
+			//平台
+			platformName: "新邻社区",
+			recommendCodeGoods: "https://cms.gzhylwh.com/visit/hyl/7f858fb8-bb1c-4289-95f9-23572d96862cad0e591c-489b-4869-b6da-84483a2ac559qrcode.jpg",
+			//二维码
+            swiperIndex: 0,
+            posterImgs: [],
+            h5SaveImg: ""
+        };
+    },
+    //第一次加载
+    onLoad(options) {
+		
+    },
+    computed: {
+    },
+    //方法
+    methods: {
+		
+        // 轮播图变化
+        onSwiperChange(e) {
+            this.swiperIndex = e.detail.current;
+        },
+        // 创建海报
+        createPoster() {
+            return new Promise((resolve, reject) => {
+                uni.showLoading({
+                    title: '海报生成中'
+                });
+                const ctx = uni.createCanvasContext('poster');
+                ctx.fillRect(0, 0, 375, 673);
+                ctx.setFillStyle("#FFF");
+                ctx.fillRect(0, 0, 375, 673);
+                uni.downloadFile({
+                    url: this.list[this.swiperIndex].headImgs,
+                    success: (res) => {
+                        if (res.statusCode === 200) {
+                            ctx.drawImage(res.tempFilePath, 0, 0, 375, 375);
+                            uni.downloadFile({
+                                url: this.recommendCodeGoods,
+                                success: (res2) => {
+                                    if (res.statusCode === 200) {
+                                        // 商品标题
+                                        ctx.setFontSize(16);
+                                        ctx.setFillStyle('#333');
+                                        let drawtextList = drawtext(this.list[this.swiperIndex].goodsName, 420);
+                                        let textTop = 0;
+                                        drawtextList.forEach((item,index) => {
+                                            if(index < 2){
+                                                textTop = 380 + (index + 1) * 28;
+												if(index==0){
+													ctx.fillText(item.content, 22, textTop);
+												}else{
+													if(item.content.length>20){
+														ctx.fillText(item.content+"...", 22, textTop);
+													}else{
+														ctx.fillText(item.content, 22, textTop);
+													}
+												}
+                                            }
+                                        });
+										// 商品价格
+										ctx.setFontSize(22);
+										ctx.setFillStyle('#f00');
+										ctx.fillText('¥'+(this.list[this.swiperIndex].goodsPrice), 17, textTop + 47);
+										// 商品门市价
+										ctx.setFontSize(18);
+										ctx.setFillStyle('#999');
+										let textLeft = 38 + (('¥'+this.list[this.swiperIndex].goodsPrice).length * 13)
+										ctx.fillText('¥'+(this.list[this.swiperIndex].disCountPrice), textLeft, textTop + 45);
+										// 商品门市价横线
+										ctx.beginPath();
+										ctx.setLineWidth(1);
+										ctx.moveTo(textLeft - 1, textTop + 38);
+										ctx.lineTo((textLeft + 18 + (('¥'+this.list[this.swiperIndex].disCountPrice).length * 9)), textTop + 38);
+										ctx.setStrokeStyle('#999');
+										ctx.stroke();
+										// 商品分割线
+										ctx.beginPath();
+										ctx.setLineWidth(1);
+										ctx.moveTo(17, textTop + 70);
+										ctx.lineTo(358, textTop + 70);
+										ctx.setStrokeStyle('#eee');
+										ctx.stroke();
+										
+										
+                                        // 商品价格
+          //                               ctx.setFontSize(20);
+          //                               ctx.setFillStyle('#f00');
+          //                               ctx.fillText(this.list[this.swiperIndex].goodsPrice, 17, textTop + 47);
+										// // 商品门市价
+										// ctx.setFontSize(18);
+										// ctx.setFillStyle('#999');
+										// let textLeft = 38 + (this.list[this.swiperIndex].goodsPrice.length * 13)
+										// ctx.fillText(this.list[this.swiperIndex].disCountPrice, textLeft, textTop + 45);
+										// // 商品门市价横线
+										// ctx.beginPath();
+										// ctx.setLineWidth(1);
+										// ctx.moveTo(textLeft - 1, textTop + 38);
+										// ctx.lineTo((textLeft + 5 + this.list[this.swiperIndex].disCountPrice.length * 9), textTop + 38);
+										// ctx.setStrokeStyle('#999');
+										// ctx.stroke();
+                                        // 商品分割线
+                                        ctx.beginPath();
+                                        ctx.setLineWidth(1);
+                                        ctx.moveTo(17, textTop + 70);
+                                        ctx.lineTo(358, textTop + 70);
+                                        ctx.setStrokeStyle('#eee');
+                                        ctx.stroke();
+                                        // 长按识别二维码访问
+                                        ctx.setFontSize(14);
+                                        ctx.setFillStyle('#333');
+                                        ctx.fillText("扫描二维码访问", 17, textTop + 136);
+                                        // 平台名称
+                                        ctx.setFontSize(12);
+                                        ctx.setFillStyle('#999');
+                                        ctx.fillText(this.platformName, 17, textTop + 170);
+                                        // 二维码
+                                        ctx.drawImage(res2.tempFilePath, 238, textTop + 88, 120, 120);
+                                        ctx.draw(true, () => {
+                                            // canvas画布转成图片并返回图片地址
+                                            uni.canvasToTempFilePath({
+                                                canvasId: 'poster',
+                                                width: 375,
+                                                height: 673,
+                                                success: (res) => {
+                                                    if(this.posterImgs[this.swiperIndex]){
+                                                        this.posterImgs[this.swiperIndex].temporary = res.tempFilePath;
+                                                    }else{
+                                                        this.posterImgs[this.swiperIndex] = {
+                                                            temporary: res.tempFilePath
+                                                        };
+                                                    }
+                                                    console.log("海报制作成功!");
+                                                    resolve(res.tempFilePath);
+                                                },
+                                                fail: () => {
+                                                    uni.hideLoading();
+                                                    reject();
+                                                }
+                                            })
+                                        });
+                                    } else {
+                                        uni.hideLoading();
+                                        uni.showToast({
+                                            title: '海报制作失败,图片下载失败',
+                                            icon: 'none'
+                                        });
+                                    }
+                                },
+                                fail: err => {
+                                    uni.hideLoading();
+                                    uni.showToast({
+                                        title: '海报制作失败,图片下载失败',
+                                        icon: 'none'
+                                    });
+                                }
+                            });
+                        } else {
+                            uni.hideLoading();
+                            uni.showToast({
+                                title: '海报制作失败,图片下载失败',
+                                icon: 'none'
+                            });
+                        }
+                    },
+                    fail: err => {
+                        uni.hideLoading();
+                        uni.showToast({
+                            title: '海报制作失败,图片下载失败',
+                            icon: 'none'
+                        });
+                    }
+                });
+            });
+        },
+        // 保存图片
+        async onSaveImg() {
+            let imgUrl = "";
+            if(this.posterImgs[this.swiperIndex] && this.posterImgs[this.swiperIndex].temporary){
+                imgUrl = await this.posterImgs[this.swiperIndex].temporary;
+            }else{
+                imgUrl = await this.createPoster();
+            }
+            // #ifdef H5
+            this.h5SaveImg = imgUrl;
+            uni.hideLoading();
+            // #endif
+            // #ifdef MP-WEIXIN
+            uni.showLoading({
+                title: '海报下载中'
+            });
+            if (settingWritePhotosAlbum) {
+                uni.getSetting({
+                    success: res => {
+                        if (res.authSetting['scope.writePhotosAlbum']) {
+                            uni.saveImageToPhotosAlbum({
+                                filePath: imgUrl,
+                                success: () => {
+                                    uni.showToast({
+                                        title: '保存成功'
+                                    });
+                                },
+                                complete: () => {
+                                    uni.hideLoading();
+                                }
+                            });
+                        } else {
+                            uni.showModal({
+                                title: '提示',
+                                content: '请先在设置页面打开“保存相册”使用权限',
+                                confirmText: '去设置',
+                                cancelText: '算了',
+                                success: data => {
+                                    if (data.confirm) {
+                                        uni.openSetting();
+                                    }
+                                },
+                                complete: () => {
+                                    uni.hideLoading();
+                                }
+                            });
+                        }
+                    },
+                    complete: () => {
+                        uni.hideLoading();
+                    }
+                });
+            } else {
+                settingWritePhotosAlbum = true;
+                uni.authorize({
+                    scope: 'scope.writePhotosAlbum',
+                    success: () => {
+                        uni.saveImageToPhotosAlbum({
+                            filePath: imgUrl,
+                            success: () => {
+                                uni.showToast({
+                                    title: '保存成功'
+                                });
+                            },
+                            complete: () => {
+                                uni.hideLoading();
+                            }
+                        });
+                    },
+                    complete: () => {
+                        uni.hideLoading();
+                    }
+                });
+            }
+            // #endif
+            // #ifdef APP-PLUS
+            uni.showLoading({
+                title: '海报下载中'
+            });
+            uni.saveImageToPhotosAlbum({
+                filePath: imgUrl,
+                success: () => {
+                    uni.hideLoading();
+                    uni.showToast({
+                        title: '保存成功'
+                    });
+                }
+            });
+            // #endif
+        }
+    }
+};
+</script>
+<style lang="scss" scoped>
+.poster_page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+    display: flex;
+    align-items: center;
+}
+.poster_canvas {
+    width: 750rpx;
+    height: 1324rpx;
+    position: fixed;
+    top: -10000rpx;
+    left: 0rpx;
+}
+.poster_swiper {
+    height: 950rpx;
+    width: 100%;
+    swiper-item {
+        box-sizing: border-box;
+        display: flex;
+        align-items: center;
+        .goods_info_box {
+            width: 100%;
+            height: 100%;
+            transform: scale(0.88);
+            transition: all 0.4s;
+            position: relative;
+            overflow: hidden;
+            background-color: #FFFFFF;
+            &.active {
+                transform: scale(1);
+            }
+            .goods_image {
+                width: 100%;
+                height: calc(100vw - 220rpx);
+            }
+            .goods_info {
+                padding: 24rpx;
+                .goods_name {
+                    color: #333;
+                    font-size: 30rpx;
+					overflow: hidden;
+					text-overflow: ellipsis;
+					display: -webkit-box;
+					-webkit-line-clamp: 2;
+					-webkit-box-orient: vertical;
+                }
+                .price_box {
+                    margin-top: 24rpx;
+                    display: flex;
+                    align-items: center;
+                    .price {
+                        font-size: 38rpx;
+                        color: red;
+                    }
+                    .store_price {
+                        margin-left: 30rpx;
+                        font-size: 26rpx;
+                        color: #999;
+                        text-decoration: line-through;
+                    }
+                }
+                .poster_info {
+                    border-top: 2rpx solid #f1f1f1;
+                    padding-top: 24rpx;
+                    margin-top: 24rpx;
+                    display: flex;
+                    align-items: center;
+                    justify-content: space-between;
+                    .info {
+                        display: flex;
+                        flex-direction: column;
+                        view {
+                            color: #333;
+                            font-size: 28rpx;
+                        }
+                        text {
+                            color: #999;
+                            font-size: 24rpx;
+                            margin-top: 20rpx;
+                        }
+                    }
+                    .poster_code_image {
+                        width: 170rpx;
+                        height: 170rpx;
+                        flex-shrink: 0;
+                    }
+                }
+            }
+        }
+    }
+}
+.push_button{
+	position:relative;
+	color:#FFF;
+	display:block;
+	text-decoration:none;
+	margin:0 auto;
+	border-radius:40rpx;
+	text-align:center;
+	padding:12rpx 80rpx;
+	-webkit-transition: all 0.1s;
+	-moz-transition: all 0.1s;
+	transition: all 0.1s;
+	
+	background-color: rgba(232, 0, 0,.7);
+	-webkit-box-shadow: 2px 4px 2px rgba(232, 0, 0,.5);
+	-moz-box-shadow: 2px 4px 2px rgba(232, 0, 0,.5);
+	box-shadow: 2px 4px 2px rgba(232, 0, 0,.5);
+}
+.push_button:active{
+	-webkit-box-shadow: 0px 2px 0px rgba(232, 0, 0,.5);
+	-moz-box-shadow: 0px 2px 0px rgba(232, 0, 0,.5);
+	box-shadow: 0px 2px 0px rgba(232, 0, 0,.5);
+	position:relative;
+	top:7px;
+}
+
+
+.share_save_box {
+    position: fixed;
+    bottom: calc((100vh - 950rpx - 140rpx) / 4);
+    left: 0;
+    z-index: 6;
+    width: 100%;
+    display: flex;
+}
+</style>
+
+

+ 160 - 0
pages/record/record.vue

@@ -0,0 +1,160 @@
+<template>
+<view style="background-color: #FFFFFF;height: 100vh;">
+<view class="nav_section" v-if="list.length>0">
+  <view>
+    <view v-for="(item, index) in list" :key="index" class="nav_section_items">
+      <view class="section_cont" data-aid="undefined">
+        <view class="section_cont_tel">
+          <text>访客类型:</text>
+          <text class="fr classify" v-if="item.accessUserType==0">朋友</text>
+          <text class="fr classify" v-else-if="item.accessUserType==1">外卖</text>
+          <text class="fr classify" v-else-if="item.accessUserType==2">快递</text>
+          <text class="fr classify" v-else-if="item.accessUserType==3">其他</text>
+          <text class="fr classify" v-else>其他</text>
+        </view>
+       <view class="section_cont_tel">
+          <text>开门密码:</text>
+           <text class="fr">{{item.accessCardNo}}</text>
+        </view>
+        <view class="section_cont_tel"> <text>开门时间:</text> <text class="fr">{{item.accessDate}}</text></view>
+        
+      </view>
+    </view>
+  </view>
+</view>
+<view class="default" v-if="list==null || list.length==0">
+    <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有获取到访客记录</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+var util = require("../../utils/util.js");
+
+export default {
+  data() {
+    return {
+      list: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    this.getPwdOpenRecord();
+  },
+  methods: {
+    //获取访客记录
+    getPwdOpenRecord: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      let operation = 'accessRecords/getListByMemberId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取结果:" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          let list = res.data.list;
+
+          for (let i in list) {
+            list[i].accessDate = util.formatTime(list[i].accessDate);
+          }
+
+          that.setData({
+            list: list
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style>
+/* pages/myHome/myHome.wxss */
+page{
+  overflow-y: scroll;
+}
+.nav_section {
+  width: 100%;
+  overflow-y: scroll;
+}
+
+.nav_section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  border-bottom: 2rpx solid #ddd;
+  position: relative;
+  background: #fff;
+  margin: 30rpx;
+  border-radius: 10rpx;
+}
+
+
+.nav_section_items .section_image {
+  width: 170rpx;
+  height: 158rpx;
+  position: relative;
+}
+
+.nav_section_items .identity {
+  padding: 4rpx;
+  top: 0;
+  right: 0;
+  background: #29afec;
+  color: #fff;
+  font-size: 24rpx;
+  position: absolute;
+}
+
+.nav_section_items .section_image image {
+  width: 100%;
+  height: 100%;
+}
+
+.nav_section_items .section_cont {
+  width: 100%;
+  font-size: 26rpx;
+  color: #a9a9a9;
+}
+
+.nav_section_items .section_cont view {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+}
+
+.nav_section_items .section_cont .section_cont_intro {
+  white-space: normal;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+
+.nav_section_items .section_cont .section_cont_tel {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 80rpx;
+  margin-bottom: 10rpx;
+  width: 100%;
+  border-bottom: 1px dashed #a9a9a9;
+}
+.nav_section_items .section_cont .section_cont_tel .classify{
+  color: #d24a58;
+}
+
+.section_cont_tel .fr {
+  float: right;
+}
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 250rpx;
  display: inline-block;
}
</style>

+ 367 - 0
pages/register/register.vue

@@ -0,0 +1,367 @@
+<template>
+<view class="container edit_wrap">
+<view class="flex justify-between " style="padding: 40rpx 30rpx;;box-sizing: border-box;">
+	<view class="" style="font-size: 38rpx;">
+		<text class="text-bold text-black">注册认证</text>
+	</view>
+	<view class="text-red"  style="padding-top: 12rpx;">
+		<text style="font-size: 38rpx;">1</text>
+		<text class="text-df">/3</text>
+	</view>
+</view>
+ <form>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">姓名:</text>
+      <input placeholder="请与物业登记处保持一致" placeholder-class="placeholder_style" type="text" class="placeholder_style" @input="nameInput">
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">手机:</text>
+      <input placeholder="请与物业登记处保持一致" v-model="tel" placeholder-class="placeholder_style" type="number" maxlength="11" class="placeholder_style" >
+      </input>
+    </view>
+    <view class="form_group">
+      <text class="red">*</text>
+      <text class="sex">验证码:</text>
+      <input type="text" class="sendmsg_input" @input="verifyCodeInput"></input>
+      <button class="right code_btn" @tap="sendMsgButton" :disabled="disabled" :style="'background-color:' + color">{{text}}</button>
+    </view>
+    <view style="display:flex;margin:20rpx 20rpx">
+	  <u-checkbox v-model="isCheck" active-color="blue">
+		  <navigator url="/pages/webview/webview?url=https://openapi.lezhuapp.com/help/app.html"><text style="color:#5db5fe">请阅读并同意用户协议</text></navigator>
+	  </u-checkbox>
+    </view>
+	<view class="tips">
+	  <text style="padding-left: 40rpx;">认证后用户可享受更多权益,随时获取到您所在小区的动态</text>
+	</view>
+	
+	<view @click="showDialogBtn" class=" footer-fixed" >
+		<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+			确认
+		</view>
+	</view>
+  </form>
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      text: '获取验证码',
+      //按钮文字
+      currentTime: 61,
+      //倒计时
+      disabled: false,
+      //按钮是否禁用
+      name: null,
+      //姓名
+      tel: null,
+      //获取到的手机栏中的值
+      verify_code: null,
+      //验证码
+      isCheck: true,
+      color: ""
+    };
+  },
+  onLoad() {
+	this.tel=this.$auth.getMineBase().user.mobile || ''
+  },
+  methods: {
+    //获取姓名栏input中的值
+    nameInput: function (e) {
+      this.setData({
+        name: e.detail.value
+      });
+    },
+    //获取验证码栏input中的值
+    verifyCodeInput: function (e) {
+      this.setData({
+        verify_code: e.detail.value
+      });
+    },
+    //获取验证码按钮
+    sendMsgButton: function () {
+      let that = this;
+      that.setData({
+        disabled: true,
+        //只要点击了按钮就让按钮禁用 (避免正常情况下多次触发定时器事件)
+        color: '#ccc'
+      });
+      let name = that.name;
+      let tel = that.tel; //把手机号跟倒计时值变例成js值
+
+      let currentTime = that.currentTime; //warn为当手机号为空或格式不正确时提示用户的文字,默认为空
+
+      let warn = null;
+
+      if (name == null) {
+        warn = "姓名不能为空";
+      } else if (tel == null) {
+        warn = "手机号码不能为空";
+      } else if (tel.trim().length != 11 || !/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[189])\d{8}$/.test(tel)) {
+        warn = "手机号格式不正确";
+      } else {
+        //发送短信
+        that.sendMessage(); //设置一分钟的倒计时
+
+        let interval = setInterval(function () {
+          currentTime--; //每执行一次让倒计时秒数减一
+
+          that.setData({
+            text: currentTime + 's' //按钮文字变成倒计时对应秒数
+
+          }); //如果当秒数小于等于0时 停止计时器 且按钮文字变成重新发送 且按钮变成可用状态 倒计时的秒数也要恢复成默认秒数 即让获取验证码的按钮恢复到初始化状态只改变按钮文字
+
+          if (currentTime <= 0) {
+            clearInterval(interval);
+            that.setData({
+              text: '重新发送',
+              currentTime: 61,
+              disabled: false,
+              color: '#59a5f0'
+            });
+          }
+        }, 1000);
+      }; //判断 当提示错误信息文字不为空 即手机号输入有问题时提示用户错误信息 并且提示完之后一定要让按钮为可用状态 因为点击按钮时设置了只要点击了按钮就让按钮禁用的情况
+
+      if (warn != null) {
+        //自动关闭提示弹窗
+        app.globalData.autoFailHint(warn);
+        that.setData({
+          disabled: false,
+          color: '#59a5f0'
+        });
+        return;
+      }
+
+      ;
+    },
+    //确认
+    showDialogBtn: function () {
+	  app.globalData.totalStep=3
+      let that = this;
+      let name = that.name;
+      if (name == null) {
+        //自动关闭提示弹窗
+        app.globalData.autoFailHint("请填写姓名");
+        return;
+      }
+      let tel = that.tel;
+	  if (tel == null) {
+	    //自动关闭提示弹窗
+	    app.globalData.autoFailHint("请输入手机号");
+	    return;
+	  }
+      if (tel.trim().length != 11 || !/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/.test(tel)) {
+        //自动关闭提示弹窗
+        app.globalData.autoFailHint("请填写正确的手机号码");
+        return;
+      }
+      let verify_code = that.verify_code;
+
+      if (verify_code == null) {
+        //自动关闭提示弹窗
+        app.globalData.autoFailHint("请填写验证码");
+        return;
+      }
+
+      if (!that.isCheck) {
+        app.globalData.autoFailHint("请同意用户协议");
+        return;
+      } //注册
+      //构建参数
+      let params = {};
+      params['name'] = name;
+      params['tel'] = tel;
+      params['verify_code'] = verify_code; 
+
+      params['create_type'] = 0;
+      params['openid'] = uni.getStorageSync("openid");
+      let operation = 'miniprogram/memberRegister';
+      app.globalData.postRequest(params, operation, function (res) {
+        //注册成功
+        if (res.data.result_code == 1) {
+          app.globalData.oneFailHint(res.data.result_msg, function () {
+            //注册成功之后重新拉取一次会员信息
+            let params = {};
+            params['openid'] = uni.getStorageSync("openid");
+            let operation = 'miniprogram/getMemberByOpenid';
+            app.globalData.postRequest(params, operation, function (res) {
+              console.info("getMemberByOpenid==" + res.data.result_msg); //获取成功
+
+              if (res.data.result_code == 1) {
+                let member = res.data.member;
+                app.globalData.member = member; //未认证状态--提示去认证
+                if (member.state == 0) {
+					uni.redirectTo({
+						url:"../auth/auth"
+					})
+                } else {
+                  uni.reLaunch({
+                    url: '/pages/index/index'
+                  });
+                }
+              } else {
+                app.globalData.oneFailHint(res.data.result_msg);
+              }
+            });
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    },
+    //申请短信验证码
+    sendMessage: function () {
+      //构建参数
+      let params = {};
+      params['tel'] = this.tel;
+	  params['play_type'] = 2;
+      let operation = 'member/getSmsCode';
+      app.globalData.postRequest(params, operation, function (res) {
+        //短信发送成功
+        if (res.data.result_code == 1) {
+          app.globalData.autoFailHint(res.data.result_msg);
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+page {
+  background: #fff;
+}
+
+
+.edit_wrap {
+  font-size: 30rpx;
+  padding: 0rpx 20rpx 20rpx;
+  color: #333;
+}
+
+.form_group {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  margin: 20rpx 20rpx;
+  line-height: 100rpx;
+  position: relative;
+  font-size: 26rpx;
+  border-bottom: 2rpx solid #ddd;
+  
+}
+
+.form_group .item {
+  text-align: right;
+  line-height: 80rpx;
+}
+
+.form_group .red {
+  color: red;
+  position: absolute;
+  left: 0;
+}
+
+.form_group text.sex {
+  margin-left: 15px;
+  text-align: right;
+}
+
+.form_group .radio-group {
+  text-align: left;
+}
+
+.form_group input, .form_group picker {
+  width: 500rpx;
+  border-radius: 8rpx;
+ height: 100rpx;
+  line-height: 100rpx;
+  padding: 0rpx 20rpx;
+  color: #333;
+  box-sizing: border-box;
+  position: relative;
+  z-index: 1;
+}
+
+.form_group button {
+  font-size: 24rpx;
+  background: $base-btn-color;
+  margin:10rpx 0 0 10rpx;
+  color: #fff;
+}
+
+.form_group .sendmsg_input {
+  width: 340rpx;
+  margin-left: 36rpx;
+}
+
+.tips {
+  padding: 0 10rpx;
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+  margin-top: 20rpx;
+}
+
+.placeholder_style {
+  font-family: '微软雅黑';
+  color: #adadad;
+  font-size: 26rpx;
+}
+
+.save_btn {
+  width: 600rpx;
+  background: #d24a58;
+  font-size: 32rpx;
+  color: #fff;
+  border-radius: 0rpx;
+  margin: 40rpx 0rpx 10rpx;
+}
+
+.code_btn {
+  width: 150rpx;
+  background: $base-btn-color;
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: center;
+  border-radius: 10rpx;
+  color: #fff;
+  font-size: 33rpx;
+  padding: 0 10rpx;
+}
+
+.password_contet image {
+  width: 48rpx;
+  height: 48rpx;
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+}
+
+.password_contet {
+  position: absolute;
+  right: 0;
+  top: 50%;
+  transform: translate(0, -50%);
+  width: 80rpx;
+  height: 80rpx;
+  z-index: 999;
+}
+checkbox .wx-checkbox-input {
+  width: 34rpx;
+  height: 34rpx;
+}
+checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
+  color: $base-btn-color;
+}
+</style>

+ 148 - 0
pages/services/delivery/delivery.vue

@@ -0,0 +1,148 @@
+<template>
+	<view>
+		<!-- 地址 -->
+		<view class="cu-list menu card ">
+			<view class="cu-item arrow" >
+				<view class="content " style="padding: 36rpx 0;">
+					<image style="width: 60rpx;" src="/static/publish.png" class="png" mode="widthFix"></image>
+					<text class="text-black text-bold margin-left-10 text-lg" >新增收货地址</text>
+				</view>
+			</view>
+		</view>
+		<!-- 时间 -->
+		<view class="card">
+			<view class="cu-form-group" >
+				<view class="title">时间选择</view>
+				<picker mode="time" :value="time" start="09:01" end="21:01" @change="TimeChange">
+					<view class="picker">
+						{{time}}
+					</view>
+				</picker>
+			</view>
+			<view class="cu-form-group">
+				<view class="title">日期选择</view>
+				<picker mode="date" :value="date" start="2015-09-01" end="2020-09-01" @change="DateChange">
+					<view class="picker">
+						{{date}}
+					</view>
+				</picker>
+			</view>
+		</view>
+		<view class="card" >
+			<view class="text-center desc">
+				<view class="text-df" >
+					<text>物品重量</text>
+				</view>
+				<view class="padding-top-10 text-sm">
+					<text>每单仅限1~2件,超重另外收费!超过2公斤,每公斤加1元</text>
+				</view>
+			</view>
+			<view class="form" style="padding: 40rpx 30rpx;">
+				<view class="basis-sm">
+					<text>选择重量</text>
+				</view>
+				<view class="basis-lg">
+					<input type="digit" placeholder="请选择物体重量" />
+				</view>
+			</view>
+		</view>
+
+		<view class="card padding-10" >
+			<view class="form">
+				<view class="basis-sm">
+					<text>驿站</text>
+				</view>
+				<view class="basis-lg">
+					<input type="text" placeholder="请输入物件所在驿站(必填)" />
+				</view>
+			</view>
+		</view>
+		
+		<view class="card">
+			<view class="cu-form-group margin-top">
+				<textarea maxlength="-1"   placeholder="请输入备注信息"></textarea>
+			</view>
+		</view>
+		<!-- 上传短信截图 -->
+		<view class="card">
+			<view class="text-center padding-20">
+				<text>请提供取件短信截图</text>
+			</view>
+			<view class="margin-bottom-30 margin-top-10">
+				<u-upload :action="action" :file-list="fileList" ></u-upload>
+			</view>
+		</view>
+		
+		<view class="read">
+			<u-checkbox v-model="isCheck" active-color="blue">
+				<text>我已阅读并同意</text>
+				<text class="text-red-btn">《小区代收免责协议》</text>
+			</u-checkbox>
+		</view>
+		
+		<view class="" style="height: 160rpx;">
+			
+		</view>
+		
+		<view  class=" footer-fixed" >
+			<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+				确认下单
+			</view>
+		</view>
+		
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				//日期时间
+				time: '12:01',
+				date: '2018-12-25',
+				//上传
+				action: 'http://www.example.com/upload',
+				fileList: [],
+				//协议
+				isCheck:false
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.card{
+		width: 700rpx;
+		margin:20rpx auto 0rpx auto;
+		border-radius: 10rpx;
+		border-bottom: 1rpx solid #b6b6b6;
+		box-sizing: border-box;
+		background-color: #FFFFFF;
+	}
+	
+	.read{
+		width: 700rpx;
+		margin:30rpx auto 0rpx auto;
+	}
+	
+ 	.card:first-child{
+		margin-top: 30rpx;
+	}
+	.card .form{
+		padding: 30rpx;
+		display: flex;
+		.basis-sm{
+			flex-basis: 30%;
+		}
+		.basis-lg{
+			flex-basis: 70%;
+		}
+	}
+	.desc{
+		background-color: #59a5f0;color: #FFFFFF;margin-top: 20rpx;padding: 20rpx;
+	}
+</style>

+ 254 - 0
pages/services/demand/detail.vue

@@ -0,0 +1,254 @@
+<template>
+	<view>
+		<view class="data">
+			<view class="address">
+				<view class="img">
+					<image src="/static/icon/address.png" mode="widthFix"></image>
+				</view>
+				<view class="content">
+					<text>宁夏冬美小区</text>
+					<text>银川市兴庆区解放东路477号</text>
+				</view>
+			</view>
+		</view>
+		
+		<view class="data" >
+			<view class="info">
+				<view class="top">
+					<view class="left">
+						<u-icon name="hourglass-half-fill" :size="30" top="2" color="rgb(94,94,94)"></u-icon>
+						<view class="title">订单号:<text>45217845689442452111</text></view>
+					</view>
+					<view class="copy">
+						<text>复制</text>
+					</view>
+				</view>
+				<view class="item">
+					<view class="content" >
+						<text >标题:</text>
+						<text >代拿滑板到二楼</text>
+					</view>
+					<view class="content" >
+						<text >发布时间:</text>
+						<text >2020-10-27 17:00:22</text>
+					</view>
+					<view class="content" >
+						<text >联系人:</text>
+						<text >黄明潘</text>
+					</view>
+					<view class="content" >
+						<text >联系微信:</text>
+						<text >hmp1049127947</text>
+					</view>
+					<view class="content" >
+						<view class="alignCenter">
+							<text >联系电话:</text>
+						</view>
+						<view class="phone">
+							<text class="alignCenter">19124812874</text>
+							<image src="http://139.9.185.150/upload/bf61acb4-22fc-4812-9f80-2f59a4cd949f-phone.png" mode="widthFix"></image>
+						</view>
+					</view>
+					<view class="content" >
+						<text >价格:</text>
+						<text class="price">¥4.00</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="data" >
+			<view class="account">
+				<view class="top">
+					<u-icon name="account" :size="30" top="2" color="rgb(94,94,94)"></u-icon>
+					<text>会员信息</text>
+				</view>
+				<view class="item">
+					<u-avatar :show-sex ="true" size="110" src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg"></u-avatar>
+					<view class="alignCenter name" >
+						plsteins
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="data">
+			<view class="cu-card dynamic no-card " style="margin: 10rpx 0;">
+				<view class="cu-item shadow">
+					<!-- 1张图片 -->
+					<view class=" grid flex-sub   col-1" style="height: 300rpx;"  v-if="dataDetail.picArray.length==1">
+						<view class="bg-img only-img" :style="{backgroundImage: 'url(' + dataDetail.picArray[0] + ')'}">
+						</view>
+					</view>
+					<!-- 多张图片 -->
+					<view class=" grid flex-sub  col-3 grid-square" v-else>
+						<view class="bg-img" :style="{backgroundImage: 'url(' + item1 + ')'}"
+						   v-for="(item1,index1) in dataDetail.picArray" :key="index1">
+						</view>
+					</view>
+				</view>
+				
+				<view class="need-desc">
+					<text>需求内容:</text>
+					<text class="content">
+						小熊USB小风扇迷你超静音手持电风扇便携式随身小型电动充电宿舍【全新包邮】原价40闲置30到手+微信请备注
+					</text>
+				</view>
+			</view>
+		</view>
+		
+		<u-divider height="80"  bg-color="#f1f1f1">没有更多了</u-divider>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				dataDetail:{
+					picArray:[
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',
+						'https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',
+					]
+				}
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.alignCenter{
+		display: flex;flex-direction: column;justify-content: center;
+	}
+	
+	.data {
+		background-color: #FFFFFF;
+		width: 700rpx;
+		margin:20rpx auto;
+		border-radius: 14rpx;
+		box-sizing: border-box;
+		padding: 16rpx;
+		font-size: 28rpx;
+		border-bottom: 1rpx solid #b6b6b6;
+	}
+	// 地址
+	.address{
+		margin: 20rpx auto;
+		display: flex;
+		.img{
+			margin: 20rpx;
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			align-items: center;
+			image{
+				width: 42rpx;
+			}
+		}
+		.content{
+			display: flex;
+			flex-direction: column;
+			margin: 10rpx 0;
+			text{
+				color: #a1a1a1;
+				font-size: 28rpx;
+			}
+			text:first-child{
+				margin-bottom: 20rpx;
+				color: #333;
+				font-weight: 800;
+				font-size: 30rpx;
+			}
+		}
+	}
+	
+	//基本信息
+	.info{
+		.top {
+			display: flex;
+			justify-content: space-between;
+			padding: 20rpx 0;
+			border-bottom: 1rpx solid #e2e2e2;
+			.left {
+				font-size: 28rpx;
+				display: flex;
+				justify-content: space-between;
+				.title {
+					margin: 0 10rpx;
+					font-weight: bold;
+					text{
+						font-weight: 500;
+					}
+				}
+			}
+			.copy{
+				padding-right: 20rpx;
+				color: $base-btn-color;
+				text-decoration: underline;
+			}
+		}
+		.item {
+			margin: 30rpx;
+			display: flex;
+			flex-direction: column;
+			.content{
+				padding: 16rpx 0;
+				display: flex;
+				justify-content: space-between;
+				.price{
+					color: #e54d42;
+					font-size: 32rpx;
+					font-weight: 700;
+				}
+				.phone{
+					display: flex;
+					text{
+						margin-right: 10rpx;
+					}
+					image{
+						width: 50rpx;
+					}
+				}
+			}
+		}
+	}
+	
+	//会员信息
+	.account{
+		.top{
+			padding: 20rpx 0;
+			display: flex;
+			border-bottom: 1rpx solid #e2e2e2;
+			font-weight: 800;
+			
+			text{
+				padding-left: 10rpx;
+			}
+		}
+		.item{
+			padding: 20rpx;
+			display: flex;
+			
+			.name{
+				padding-left: 40rpx;
+				font-size: 32rpx;
+			}
+		}
+	}
+	
+	.need-desc{
+		padding-top: 20rpx;
+		font-weight: 600;
+		line-height: 48rpx;
+		.content{
+			font-weight: 500;
+		}
+	}
+	
+	
+</style>

+ 142 - 0
pages/services/demand/list.vue

@@ -0,0 +1,142 @@
+<template>
+	<view>
+		<view class="data" v-for="(item,index) in 6" :key="index" >
+			<view class="top">
+				<view class="left">
+					<u-icon name="hourglass-half-fill" :size="28" top="4" color="rgb(94,94,94)"></u-icon>
+					<view class="title text-cut-1">标题:<text >代拿一个滑板到二楼,代拿一个滑板到二楼</text></view>
+				</view>
+				<view class="right">
+					2020-10-27
+				</view>
+			</view>
+			<view class="item">
+				<view class="left">
+					<image src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg" mode="aspectFill"></image>
+					<view class="desc">
+						<text>宁夏冬美小区</text>
+						<text>发布人:19124812874</text>
+						<text>价格:4元</text>
+					</view>
+				</view>
+				<view @click="goDetail(item)" class="right">
+					<view  class="cu-btn bg-red-btn sm round">
+						查看详情
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		
+		<navigator url="./publish" class="cu-btn cuIcon round lg bg-red-btn add" >
+			<text class="cuIcon-add"></text>
+		</navigator>
+		<u-divider height="80"  bg-color="#f1f1f1">没有更多了</u-divider>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			goDetail(item){
+				console.log("111")
+				uni.navigateTo({
+					url:"./detail"
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.add{
+		position: fixed;
+		bottom: 20%;
+		right: 4%;
+		color: #FFFFFF;
+		text{
+			font-size: 50rpx;
+		}
+	}
+	.data:first-child{
+		margin-top: 20rpx;
+	}
+	.data {
+		border-bottom: 1rpx solid #b6b6b6;
+		background-color: #FFFFFF;
+		width: 700rpx;
+		margin:10rpx auto;
+		border-radius: 10rpx;
+		box-sizing: border-box;
+		padding: 20rpx;
+		font-size: 28rpx;
+		.top {
+			display: flex;
+			justify-content: space-between;
+			padding-bottom: 20rpx;
+			border-bottom: 1rpx solid #e2e2e2;
+			.left {
+				flex: 3;
+				display: flex;
+				align-items: center;
+				.title {
+					margin: 0 10rpx;
+					font-size: 28rpx;
+					font-weight: bold;
+					text{
+						font-weight: 500;
+					}
+				}
+			}
+			.right{
+				flex: 1;
+				text-align: right;
+				margin-top: 6rpx;
+				font-size: 28rpx;
+				color: #a1a1a1;
+			}
+		}
+		.item {
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			margin: 30rpx 0 20rpx 0;
+			.left{
+				display: flex;
+				image{
+					margin: 10rpx 24rpx 10rpx 30rpx ;
+					width: 116rpx;
+					height: 116rpx;
+					border-radius: 50%;
+				}
+				.desc{
+					 display: flex;
+					 flex-direction: column;
+					 text{
+						 font-size: 26rpx;
+						 color: #a1a1a1;
+						 margin-bottom: 10rpx;
+					 }
+					 text:first-child{
+						 font-size: 30rpx;
+						 color: #333;
+						 font-weight: 800;
+					 }
+				}
+			}
+			.right {
+				display: flex;
+				flex-direction: column;
+				justify-content: center;
+			}
+			
+		}
+
+	}
+</style>

+ 108 - 0
pages/services/demand/publish.vue

@@ -0,0 +1,108 @@
+<template>
+	<view>
+		<view class="card" >
+			<view class="form">
+				<view >标题</view>
+				<input  placeholder="请输入标题" ></input>
+			</view>
+			<view class="form">
+				<view >联系人</view>
+				<input placeholder="请输入联系人姓名" ></input>
+			</view>
+			<view class="form">
+				<view class="title">联系电话</view>
+				<input placeholder="电话/微信 可选其一" ></input>
+			</view>
+			<view class="form">
+				<view >联系微信</view>
+				<input placeholder="电话/微信 可选其一" ></input>
+			</view>
+			<view class="form">
+				<view >大概价格</view>
+				<input placeholder="例如:面议,100~200元" ></input>
+			</view>
+			<view class="form">
+				<view >小区</view>
+				<input placeholder="点击选择小区" ></input>
+			</view>
+		</view>
+		
+		<view class="card">
+			<view class="form" style="height: 200rpx;">
+				<textarea maxlength="-1"  placeholder="详细描述你的需求"></textarea>
+			</view>
+		</view>
+		<view class="card">
+			<view class="text-center padding-20">
+				<text>请提供取件短信截图</text>
+			</view>
+			<view style="margin-bottom: 20rpx;">
+				<u-upload :action="action" :file-list="fileList" ></u-upload>
+			</view>
+		</view>
+		
+		<view class="read">
+			<u-checkbox v-model="isCheck" active-color="blue">
+				<text>我已阅读并同意</text>
+				<text class="text-red-btn">《小区需求发布免责协议》</text>
+			</u-checkbox>
+		</view>
+		
+		<view class="" style="height: 160rpx;">
+			
+		</view>
+		
+		<view  class=" footer-fixed" >
+			<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+				确认下单
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				isCheck:false,
+				//上传
+				action: 'http://www.example.com/upload',
+				fileList: [],
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.card{
+		width: 700rpx;
+		margin:20rpx auto 0rpx auto;
+		box-sizing: border-box;
+		border-radius: 12rpx;
+		border-bottom: 1rpx solid #b6b6b6;
+		background-color: #FFFFFF;
+	}
+ 	.card:first-child{
+		margin-top: 30rpx;
+	}
+	.card .form{
+		padding: 30rpx;
+		display: flex;
+		border-bottom: 1rpx solid #e4e4e4;
+		view{
+			flex-basis: 30%;
+		}
+		input{
+			flex-basis: 70%;
+		}
+	}
+	
+	.read{
+		width: 700rpx;
+		margin:30rpx auto 0rpx auto;
+	}
+</style>

+ 69 - 0
pages/services/property/comment.vue

@@ -0,0 +1,69 @@
+<template>
+	<view>
+		<view class="cu-form-group solid-top">
+			<textarea maxlength="120" v-model="comment"  placeholder="请输入您的评价"/>
+			<text class="text-gray font-num-view">{{comment.length}} / 120字</text>
+		</view>
+		<view @click="save" class="cu-btn lg radius flex  base-bg-color footer-fixed">
+			确认保存
+		</view>
+	</view>
+</template>
+<script>
+	var app=getApp()
+	export default {
+		data() {
+			return {
+				comment:'',
+				dataDetail:{}
+			}
+		},
+		onLoad(e) {
+			
+		},
+		onShow() {
+			this.dataDetail=app.globalData.dataDetail
+		},
+		methods: {
+			save(){
+				let that=this
+				if (this.$isEmpty(this.dataDetail)) {
+					app.globalData.oneFailHint("系统异常");
+					return
+				}
+				if (this.comment.length<2) {
+					this.$u.toast('评价内容过短')
+					return
+				}
+				this.dataDetail.comment=this.comment
+				this.dataDetail.estimateStatus=1
+				let operation='estateRepair/addEstateRepair'
+				app.globalData.postRequest(this.dataDetail, operation, function (res) {
+					if (res.data.add_result==true) {
+						app.globalData.oneFailHint("评价成功",function(){
+							app.globalData.dataDetail=that.dataDetail
+							uni.navigateBack({
+								delta:1
+							})
+						});
+					}else{
+						app.globalData.oneFailHint(res.data.add_result);
+					}
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.cu-form-group {
+		textarea {
+			height: 8.6em;
+		}
+		.font-num-view {
+		    position: absolute;
+		    bottom: 9.09rpx;
+		    right: 27.27rpx;	
+		}
+	}
+</style>

+ 111 - 0
pages/services/property/detail.vue

@@ -0,0 +1,111 @@
+<template>
+	<view>
+		<view class="bg-red padding" style="height: 100rpx;">
+			<view class="text-xxl ">
+				<text v-if="dataDetail.handleStatus==-1">已撤销</text>
+				<text v-else-if="dataDetail.handleStatus==0">待处理</text>
+				<text v-else-if="dataDetail.handleStatus==1">已处理</text>
+			</view>
+			<view class="text-df padding-top-xs">
+				<text v-if="dataDetail.handleStatus==-1">当前工单已取消</text>
+				<text v-else-if="dataDetail.handleStatus==0">当前工单待处理,请耐心等待</text>
+				<text v-else-if="dataDetail.handleStatus==1">当前工单已完成</text>
+			</view>
+		</view>
+		
+		<view class="margin-top bg-white padding solid-bottom">
+			<view class="flex justify-between">
+				<view class="text-black">
+					<text>工单编号:{{dataDetail.repairNo}}</text>
+					<text class="text-blue padding-left-sm" @click="copy(dataDetail.repairNo)">复制</text>
+				</view>
+				<view class="text-red">
+					<text v-if="dataDetail.handleStatus==-1">已撤销</text>
+					<text v-else-if="dataDetail.handleStatus==0">待处理</text>
+					<text v-else-if="dataDetail.handleStatus==1">已处理</text>
+				</view>
+			</view>
+		</view>
+		<u-cell-group>
+			<u-cell-item :arrow="false" icon="home" title="所在小区" :value="dataDetail.residentialName"></u-cell-item>
+			<u-cell-item :arrow="false" icon="map" title="维修位置" :value="dataDetail.reportPosition"></u-cell-item>
+			<u-cell-item :arrow="false" icon="clock" title="创建时间" :value="dataDetail.createTime"></u-cell-item>
+			<u-cell-item v-if="dataDetail.handleStatus==1" :arrow="false" icon="clock" title="完成时间" :value="dataDetail.handleTime"></u-cell-item>
+		</u-cell-group>
+		<view class="margin-top-sm margin-bottom-sm padding bg-white flex" style="box-sizing: border-box;">
+			<view class="">
+				<text class="">故障描述:</text>
+			</view>
+			<view class="flex-sub" >
+				<text class="">{{dataDetail.reportDetail}}</text>
+			</view>
+		</view>
+		<view  class="footer-fixed  padding-sm bg-white flex justify-end margin-right-30" style="box-sizing: border-box;z-index: 999;">
+			<!-- 待处理,取消工单 -->
+			<view class="cu-btn line-red round " v-if="dataDetail.handleStatus==0" @click="cancelItem()">
+				取消工单
+			</view>
+			<!-- 已撤销工单,删除工单 -->
+			<view class="cu-btn line-red round " v-if="dataDetail.handleStatus==-1" @click="deleteItem()" >
+				删除工单
+			</view>
+			<!-- v-if="dataDetail.handleStatus==1&&dataDetail.estimateStatus==0" -->
+			<!-- 已处理,待评价 -->
+			<navigator url="./comment" class="cu-btn bg-red round "  >
+				写评价
+			</navigator>
+		</view>
+	</view>
+</template>
+
+<script>
+	var app=getApp()
+	export default {
+		data() {
+			return {
+				content:'',
+				dataDetail:{}
+			}
+		},
+		onShow() {
+			this.dataDetail=getApp().globalData.dataDetail
+		},
+		methods: {
+			cancelItem(){
+				this.dataDetail.handleStatus=-1
+				let operation='estateRepair/addEstateRepair'
+				app.globalData.postRequest(this.dataDetail, operation, function (res) {
+					if (res.data.add_result==true) {
+						app.globalData.dataDetail=
+						app.globalData.oneF-ailHint("取消成功");
+					}else{
+						app.globalData.oneFailHint(res.data.add_result);
+					}
+				});
+			},
+			deleteItem(){
+				let that=this
+				app.globalData.twoFailHint("确定要取消该工单?",function(){
+					//删除状态
+					this.dataDetail.status=-1
+					let operation='estateRepair/addEstateRepair'
+					app.globalData.postRequest(item, operation, function (res) {
+						if (res.data.add_result==true) {
+							app.globalData.twoFailHint("删除成功",function(){
+								uni.navigateBack({
+									delta:"1"
+								})
+							});
+						}else{
+							app.globalData.oneFailHint(res.data.add_result);
+						}
+					});
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 144 - 0
pages/services/property/list/card.vue

@@ -0,0 +1,144 @@
+<template>
+	<view class="">
+		<view @click="goDetail(item)" class="data" v-for="(item, index) in list" :key="index">
+			<view class="top">
+				<view class="left">
+					<view class="title">
+						<text>工单编号:{{item.repairNo}}</text>
+						<text @click.stop="copy(item.repairNo)" class="padding-left-20">复制</text>
+					</view>
+				</view>
+				<view class="right">
+					<text class="text-red" v-if="item.handleStatus==-1">已取消</text>
+					<text class="text-orange" v-if="item.handleStatus==0">待处理</text>
+					<text class="" v-if="item.handleStatus==1">已完成</text>
+					<text class="text-orange" v-if="item.handleStatus==2">待评价</text>
+				</view>
+			</view>
+			<view class="item">
+				<view class="left">
+					<view style="padding: 0 30rpx;">
+						<view class="content">
+							<text class="padding-right-10">所在小区:</text>
+							<text >{{item.residentialName}}</text>
+						</view>
+						<view class="content">
+							<text class="padding-right-10">维修位置:</text>
+							<text>{{item.reportPosition}}</text>
+						</view>
+						<view class="content">
+							<text class="padding-right-10">故障描述:</text>
+							<text style="line-height: 50rpx;">{{item.reportDetail}}</text>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="bottom" >
+				<button @click.stop="" open-type="contact" class="cu-btn  sm round line-black margin-right-20" >
+					联系客服
+				</button>
+				<!-- 待处理,显示取消工单 -->
+				<view v-if="item.handleStatus==0" class="cu-btn  sm round bg-red" @click.stop="cancel(item)">
+					取消工单
+				</view>
+				<!-- 已取消,显示删除订单 -->
+				<view v-if="item.handleStatus==-1" class="cu-btn  sm round bg-red" @click.stop="deleteItem(item)">
+					删除工单
+				</view>
+				<!-- 已完成,显示写评价 -->
+				<view v-if="item.handleStatus==1" class="cu-btn  sm round bg-red" @click.stop="comment(item)">
+					写评价
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'card',
+	props:{
+		list:{
+			type:Array,
+			default:()=>{
+				[]
+			}
+		}
+	},
+	data() {
+		return {
+			
+		};
+	},
+	onLoad() {
+		
+	},
+	methods:{
+		copy(data){
+			uni.setClipboardData({
+				data:data
+			})
+		},
+		goDetail(item){
+			getApp().globalData.dataDetail=item
+			uni.navigateTo({
+				url:"../detail"
+			})
+		},
+		cancel(item){
+			this.$emit('cancel',item)
+		},
+		comment(item){
+			getApp().globalData.dataDetail=item
+			uni.navigateTo({
+				url:"../comment"
+			})
+		},
+		deleteItem(item){
+			this.$emit('deleteItem',item)
+		},
+	}
+};
+</script>
+
+<style lang="scss">
+.data {
+	width: 710rpx;
+	background-color: #ffffff;
+	margin: 20rpx auto;
+	border-radius: 6rpx;
+	box-sizing: border-box;
+	padding: 20rpx;
+	font-size: 28rpx;
+	.top {
+		display: flex;
+		justify-content: space-between;
+		padding-bottom: 20rpx;
+		border-bottom: 1rpx solid $dt-border-color-sm;
+		.left {
+			display: flex;
+			align-items: center;
+			.title {
+				margin: 0 10rpx;
+				font-size: 30rpx;
+			}
+		}
+		.right{
+			margin-right: 10rpx;
+		}
+	}
+	.item {
+		margin: 5rpx 0 20rpx 0;
+		.content {
+			border-bottom: 1rpx dashed #DDDDDD;
+			padding: 30rpx 0;
+		}
+	}
+	.bottom {
+		display: flex;
+		margin-top: 30rpx;
+		justify-content: flex-end;
+		align-items: center;
+	}
+}
+</style>

+ 160 - 0
pages/services/property/list/item.vue

@@ -0,0 +1,160 @@
+<template>
+	<MeScroll  :up="up" :down="down" @up="upFn" :fixed="false" @down="downFn" @init="initMeScroll">
+		<scroll-view :scroll-y="true">
+			<card @deleteItem="deleteItem" :list="list" @cancel="cancel"></card>
+		</scroll-view>
+	</MeScroll>
+</template>
+<script>
+	import MeScroll from '@/comps/mescroll-uni/mescroll-uni.vue'
+	import card from './card.vue'
+	var app=getApp()
+	export default {
+		components:{
+			MeScroll,card
+		},
+		props: {
+			refresh:Boolean,
+			type: Number,
+			i: Number,
+			item:Object
+		},
+		watch:{
+			load() {
+				this.mescroll.resetUpScroll()
+			},
+		},
+		data() {
+			return {
+				isInit: false, // 是否初始化
+				list: [], // 列表数据
+				mescroll: null, // mescroll 对象
+				// 上拉配置参数
+				up: {
+					noMoreSize: 4, 
+					auto: true,
+					page: {
+						page: 0,
+						size: 10
+					}
+				},
+				// 下拉配置参数
+				down: {
+					use: true, 
+					auto: false
+				}
+			}
+		},
+		watch:{
+			type(val) {
+				if(!this.isInit && val === this.i) {
+					this.mescroll.resetUpScroll()
+				}
+			}
+		},
+		mounted() {
+			if(!this.isInit && this.i === 0) {
+				this.mescroll.resetUpScroll()
+			}
+		},
+		methods: {
+			/**
+			 * @param {Object} item 删除订单
+			 */
+			deleteItem(item){
+				let that=this
+				app.globalData.twoFailHint("确定要取消该工单?",function(){
+					//删除状态
+					item.status=-1
+					let operation='estateRepair/addEstateRepair'
+					app.globalData.postRequest(item, operation, function (res) {
+						if (res.data.add_result==true) {
+							app.globalData.oneFailHint("删除成功成功");
+							that.mescroll.resetUpScroll()
+						}else{
+							app.globalData.oneFailHint(res.data.add_result);
+						}
+					});
+				})
+			},
+			/**
+			 * 取消订单
+			 * @param {Object} item 订单实体
+			 */
+			cancel(item){
+				let that=this
+				app.globalData.twoFailHint("确定要取消该工单?",function(){
+					item.handleStatus=-1
+					let operation='estateRepair/addEstateRepair'
+					app.globalData.postRequest(item, operation, function (res) {
+						if (res.data.add_result==true) {
+							app.globalData.oneFailHint("取消成功");
+							that.mescroll.resetUpScroll()
+						}else{
+							app.globalData.oneFailHint(res.data.add_result);
+						}
+					});
+				})
+			},
+			/**
+			 * @param {Object} mescroll 初始化组件
+			 */
+			initMeScroll(mescroll) {
+				this.mescroll = mescroll
+			},
+			/**
+			 * @param {Object} mescroll 上拉回调
+			 */
+			upFn(mescroll) {
+				let that=this
+				let data={
+					"page":{
+						current:mescroll.num,
+						size:mescroll.size
+					},
+					handleStatus:this.item.value
+				}
+				//已处理,待评价
+				if (this.item.value==2) {
+					//已处理
+					data.handleStatus=1
+					//待评价
+					data.estimateStatus=0
+				}
+				let operation='estateRepair/estateRepairList'
+				try{
+					app.globalData.postRequest(data, operation, function (res) {
+						let estateRepairList=res.data.estateRepairList
+						let length=estateRepairList.records.length
+						let data=estateRepairList.records
+						mescroll.endBySize(length, estateRepairList.total);
+						if(mescroll.num == 1) that.list = []; //如果是第一页需手动制空列表
+						that.list=that.list.concat(data); //追加新数据
+					});
+				}catch(e){
+					mescroll.endErr();
+				}
+			},
+			/**
+			 * 下拉回调
+			 * */
+			downFn(mescroll) {
+				setTimeout(()=>{
+					this.list=[]
+					this.mescroll.resetUpScroll()
+					uni.showToast({
+						title:"刷新成功",
+						icon:"none",
+						duration:2000
+					})
+				},1500)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	view{
+		box-sizing: border-box;
+	}
+</style>

+ 118 - 0
pages/services/property/list/list.vue

@@ -0,0 +1,118 @@
+<template>
+	<view class="container">
+		<view class="tabs">
+			<scroll-view scroll-x class="bg-white nav">
+				<view class="flex text-center">
+					<view class="cu-item flex-sub" :class="index==current?'text-red':'text-lg'" v-for="(item,index) in tabs" :key="index" @tap="tabChange(index)" >
+						{{item.name}}
+					</view>
+				</view>
+			</scroll-view>
+		</view>
+		<view style="height: 100%;">
+			<swiper style="height: 100%;" :current="current"  @change="swiperChange"
+				@animationfinish="animationfinish">
+				<swiper-item  v-for="(item, index) in tabs" :key="index">
+					<scroll-view scroll-y style="height: 100%;">
+						<item :refresh="refresh" :i="index" :item="item" :type="current"></item>
+					</scroll-view>
+				</swiper-item>
+			</swiper>
+		</view>
+	</view>
+</template>
+<script>
+	import item from "./item.vue"
+	export default {
+		components: {
+			item
+		},
+		data() {
+			return {
+				//是否第一次进入页面
+				isRefresh:false,
+				//动态让item主动刷新
+				refresh:false,
+				scrollLeft:0,
+				current: 0,
+				swiperCurrent:0,
+				tabs: [
+					//数据库数据状态- 
+					//工单状态 -1 已取消  0:待处理  1:已处理
+					//评价 estimateStatus 待评价0  已评价 1
+					{
+						name: '全部',
+						value:''
+					},
+					{
+						name: '待处理',
+						value:0
+					},
+					{
+						name: '已取消',
+						value:-1
+					},
+					{
+						name:'待评价',
+						value:2
+					},
+					{
+						name:'已完成',
+						value:1
+					}
+				],
+			}
+		},
+		onshow(){
+			if (this.isfirst) {
+				this.isfirst=false
+			}else{
+				console.log("刷新列表");
+				//刷新列表
+				this.refresh=!this.refresh
+			}
+		},
+		onLoad() {
+			this.isfirst=true
+		},
+		methods:{
+			tabChange(index) {
+				this.current = index
+				// this.scrollLeft = (index - 1) * 60
+			},
+			swiperChange(e) {
+			  uni.pageScrollTo({
+			      scrollTop: 0,
+			      duration: 0
+			  });
+			  this.current = e.detail.current
+			  // this.scrollLeft = (this.current - 1) * 60
+			},
+			animationfinish({detail: { current }}) {
+				this.swiperCurrent = current;
+				this.current = current;
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.container {
+	  height: calc(100vh - 88rpx);
+	  background-color: #F6F6F6;
+	  padding: 88rpx 0rpx 0rpx;
+	 .tabs {
+	    position: fixed;
+	    top: -10rpx;
+		left: 0;
+		display: flex;
+		align-items: center;
+		width: 100%;
+		height: 100rpx;
+		box-sizing: border-box;
+		box-shadow: 0px 0px 10rpx rgba(0, 0, 0, 0.1);
+		border-radius: 0px 0px 10rpx 10rpx;
+		z-index: 3;
+	  }
+}
+</style>

+ 338 - 0
pages/services/property/property.vue

@@ -0,0 +1,338 @@
+<template>
+	<view>
+		<view class="card" >
+			<view class="form">
+				<view class="flex">
+					<view class="need" >*</view>
+					<view>请选择小区</view>
+				</view>
+				<view class="bg-gray padding-20 "  @click="residentialShow=true">
+					<input disabled type="text" placeholder="请选择您所在的小区" v-model="data.residentialName" />
+				</view>
+			</view>
+			<view class="form">
+				<view class="flex">
+					<view class="need" >*</view>
+					<view>报修位置</view>
+				</view>
+				<view class="bg-gray padding-20 "  >
+					<input  type="text" placeholder="请输入报修的具体位置" v-model="data.reportPosition" />
+				</view>
+			</view>
+			<view class="form ">
+				<view class="flex">
+					<view class="need" >*</view>
+					<view>联系方式</view>
+				</view>
+				<view class="bg-gray padding-20 " >
+					<input maxlength="11" type="number" placeholder="请输入您的联系方式" v-model="data.phone" />
+				</view>
+			</view>
+			<view class="form">
+				<view class="flex">
+					<view class="need" >*</view>
+					<view>预约时间</view>
+				</view>
+				<view class="bg-gray padding-20" @click="timeShow=true">
+					<input disabled  type="number" placeholder="请选择预约时间" v-model="dateTimeStr" />
+				</view>
+				<!-- <view class="flex" style="box-sizing: border-box;" >
+					<view class="flex-sub  bg-gray padding-20" @click="timeType='start';timeShow=true">
+						<input disabled="" type="text" placeholder="请选择开始时间" v-model="data.beginTime" />
+					</view>
+					<text class="padding-20">—</text>
+					<view class="flex-sub   bg-gray padding-20" @click="timeType='end';timeShow=true">
+						<input disabled="" type="text" placeholder="请选择结束时间" v-model="data.endTime" />
+					</view>
+				</view> -->
+			</view>
+		</view>
+		
+		<view class="card ">
+			<view class="form" style="height: 320rpx;">
+				<view  class="bg-gray padding-10">
+					<textarea @click="showMask"   v-model="data.reportDetail" maxlength="100" style="width: 100%;height: 270rpx;line-height: 50rpx;"  placeholder="请填写故障描述"></textarea>
+					<view  class="text-right text-df text-gray padding-top-10">
+						{{data.reportDetail.length}} / 100
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="card">
+			<view class="text-center padding-20">
+				<text>上传图片(选填,最多四张)</text>
+			</view>
+			<view >
+				<view class="cu-form-group" style="padding: 20rpx 30rpx">
+					<view class="grid col-4 grid-square flex-sub padding-left-10">
+						<view class="bg-img" v-for="(item,index) in imgList" :key="index" @click="viewImage(index)" >
+						 <image :src="imgList[index]" mode="aspectFill"></image>
+							<view class="cu-tag bg-red" @click.stop="DelImg(index)" >
+								<text class='cuIcon-close' style="font-size: 20rpx;"></text>
+							</view>
+						</view>
+						<view class="solids" @click="chooseImage" v-if="imgList.length<4">
+							<text class='cuIcon-add ' style="font-size: 60rpx;color: #c9c9c9;"></text>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="bg-white" style="height: 160rpx;"></view>
+		<view style="z-index: 999;" class=" footer-fixed" @click="submit">
+			<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+				确定提交
+			</view>
+		</view>
+		<u-mask z-index="99999" :show="maskShow" @click="maskShow = false">
+			<view style="margin: 20rpx;" @click.stop="">
+				<textarea  @confirm="confirm" @keyboardheightchange="keyboardheightchange" v-model="data.reportDetail"  value="" style="background-color: #FFFFFF;width: 100%;padding: 20rpx;box-sizing: border-box;" placeholder="请填写故障描述" />
+				<view  class="bg-white text-right text-df text-gray padding-10">
+					{{data.reportDetail.length}} / 100
+				</view>
+			</view>
+		</u-mask>
+		<u-popup v-model="timeShow" mode="bottom" border-radius="20" :closeable="true" height="55%">
+			<time-selector  @getDateTime="timeConfirm"></time-selector>
+		</u-popup>
+		
+		<!-- <u-picker  @confirm="timeConfirm" :params="params" z-index="9999999" v-model="timeShow" mode="time"></u-picker> -->
+		<u-select :default-value="defaultValue" value-name="residentialId" label-name="residentialName" @confirm="residentialConfirm" z-index="9999999" v-model="residentialShow" :list="residentialList"></u-select>
+	</view>
+</template>
+
+<script>
+	import timeSelector from '@/comps/mp-time/index.vue';
+	var app=getApp()
+	var that;
+	export default {
+		components:{
+			timeSelector
+		},
+		data() {
+			return {
+				defaultValue:[],
+				platform:'',
+				maskShow:false,
+				//图片回显
+				imgList:[],
+				data:{
+					//处理状态:待处理
+					handleStatus:0,
+					//报修用户的memberId
+					memberId:'',
+					//userId
+					userId:'',
+					//小区id
+					residentialId:'',
+					//小区名字
+					residentialName:'',
+					//故障位置
+					reportPosition:'',
+					//预约时间区间
+					beginTime:'',
+					endTime:'',
+					//联系方式
+					phone:'',
+					//故障详情描述
+					reportDetail:'',
+					//图片描述
+					pic:''
+				},
+				base64_image:[],
+				residentialShow:false,
+				residentialList:[],
+				timeShow:false,
+				dateTimeStr:''
+			}
+		},
+		onLoad() {
+			this.initData()
+		},
+		methods: {
+			initData(){
+				that=this
+				//判断是ios还是安卓,ios键盘上移会挤压遮挡层
+				this.platform=this.$u.os() || "android"
+				//获取用户的userid
+				this.data.userId=app.globalData.userId
+				//获取用户的memberId
+				try{
+					that.data.memberId=app.globalData.member.id
+				}catch(e){
+					console.log(e);
+				}
+				if (this.$isEmpty(this.data.memberId)) {
+					console.log("系统异常");
+					app.globalData.oneFailHint("系统异常",function(){
+						uni.navigateBack({
+							delta:1
+						})
+					})
+					return
+				}
+				//从缓存中获取房屋列表
+				this.residentialList=uni.getStorageSync("residentialList")
+				//从缓存中获取默认的小区名字和小区id
+				this.data.residentialName=uni.getStorageSync("plotName")
+				this.data.residentialId=uni.getStorageSync("residentialId")
+				//社区选择器的默认值
+				this.residentialList.forEach((item,index)=>{
+					if (item.residentialId===this.data.residentialId) {
+						this.defaultValue.push(index)
+						return
+					}
+				})
+			},
+			submit(){
+				if (this.$isEmpty(this.data.residentialName)) {
+					this.$u.toast("请选择小区")
+					return
+				}
+				if (this.$isEmpty(this.data.reportPosition)) {
+					this.$u.toast("请填写具体位置")
+					return
+				}
+				if (this.$isEmpty(this.data.phone)) {
+					this.$u.toast("请输入联系方式")
+					return
+				}
+				if (!this.$u.test.mobile(this.data.phone)) {
+					this.$u.toast("请输入正确的联系方式")
+					return
+				}
+				if (this.$isEmpty(this.data.beginTime)||this.$isEmpty(this.data.endTime)) {
+					this.$u.toast("请选择预约时间")
+					return
+				}
+				if (this.$util.createDate(this.data.beginTime).getTime()>
+					this.$util.createDate(this.data.endTime).getTime()) {
+					this.$u.toast("开始时间不能小于结束时间")
+					return
+				}
+				if (this.$isEmpty(this.data.reportDetail)) {
+					this.$u.toast("请输入故障描述")
+					return
+				}
+				this.data.pic=JSON.stringify(this.base64_image)
+				let operation='estateRepair/addEstateRepair'
+				console.log(this.data);
+				app.globalData.postRequest(this.data, operation, function (res) {
+					if (res.data.add_result) {
+						app.globalData.oneFailHint("提交成功");
+					}else{
+						app.globalData.oneFailHint("提交失败");
+					}
+				});
+			},
+			showMask(){
+				console.log(this.platform);
+				if (this.platform!='ios') {
+					this.maskShow=true
+				}
+			},
+			confirm(){
+				this.maskShow=false
+			},
+			residentialConfirm(e){
+				this.data.residentialId=e[0].value
+				this.data.residentialName=e[0].label
+			},
+			keyboardheightchange(e){
+				console.log(e.detail.height);
+				console.log(this.maskShow);
+				if (e.detail.height==0) {
+					this.maskShow=false
+				}
+			},
+			timeConfirm(e){
+				this.timeShow=false
+				this.data.beginTime=e.beginTime
+				this.data.endTime=e.endTime
+				this.dateTimeStr=this.data.beginTime+"   至   "+this.data.endTime
+				console.log(this.dateTimeStr);
+				// if (this.timeType=='start') {
+				// 	this.data.beginTime=e.year+'-'+e.month+'-'+e.day+" "+e.hour+':'+e.minute
+				// }else if (this.timeType=='end') {
+				// 	this.data.endTime=e.year+'-'+e.month+'-'+e.day+" "+e.hour+':'+e.minute
+				// }
+			},
+			/**
+			 * 上传问题截图
+			 */
+			chooseImage() {
+				let that=this
+				uni.chooseImage({
+					count: 4-this.imgList.length, 
+					sizeType: ['original', 'compressed'], 
+					sourceType: ['album'],
+					success: (res) => {
+						const tempFilePaths = res.tempFilePaths;
+						for (let index in tempFilePaths) {
+							//图片回显
+							that.imgList.push(tempFilePaths[index])
+							//图片转为base64的图片
+							uni.getFileSystemManager().readFile({
+							  filePath: tempFilePaths[index],
+							  //选择图片返回的相对路径
+							  encoding: 'base64',
+							  //编码格式
+							  success: res => {
+							    //成功的回调
+							    that.base64_image.push('data:image/jpeg;base64,' + res.data)
+							  }
+							});
+						}
+					
+					}
+				});
+			},
+			/*预览图片*/
+			viewImage(index) {
+				uni.previewImage({
+					urls: this.imgList,
+					current: index
+				});
+			},
+			/*删除图片*/
+			DelImg(index) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除这张照片吗?',
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.imgList.splice(index, 1)
+						}
+					}
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.bg-gray{
+		background-color: #f7f7f7;
+	}
+	.card{
+		// width: 700rpx;
+		// margin:20rpx auto 0rpx auto;
+		// border-radius: 12rpx;
+		box-sizing: border-box;
+		background-color: #FFFFFF;
+	}
+ 	.card:first-child{
+		// margin-top: 30rpx;
+	}
+	.card .form{
+		padding: 20rpx 40rpx;
+	}
+	.need{
+		font-size: 38rpx;
+		font-weight: 800;
+		color: #ff0000;
+		padding-right: 10rpx;
+	}
+</style>

+ 575 - 0
pages/switchcity/switchcity.vue

@@ -0,0 +1,575 @@
+<template>
+<view>
+	<view class="">
+		<view class="cu-bar bg-white search " >
+			<view class="search-form round">
+				<text class="cuIcon-search"></text>
+				<input type="text" confirm-type="search" @input="bindKeyInput" @blur="bindBlur" placeholder="输入城市名或拼音查询" placeholder-style="font-size: 28rpx" :value="inputName"></input>
+			</view>
+		</view>
+	</view>
+<view class="container-inner">
+  <view class="searchLetter touchClass">
+    <view class="thishotText" @tap="hotCity">
+      <view style="margin-top:0;">当前</view>
+      <view style="margin-top:0;">热门</view>
+    </view>
+    <view v-for="(item, index) in searchLetter" :key="index" class="text-red-btn" style="font-size:20rpx;" :data-letter="item.name" @click="clickLetter">{{item.name}}</view>
+  </view>
+  <view class="container">
+
+    <block v-if="isShowLetter">
+      <view class="showSlectedLetter">
+        {{toastShowLetter}}
+      </view>
+    </block>
+    <scroll-view scroll-y="true" :style="'height:' + winHeight + 'px'" @scroll="bindScroll" :scroll-into-view="scrollTopId" :scroll-top="scrollTop">
+     <view class="bg-white">
+      	<view class="solid-bottom  li" v-for="(item, index) in completeList" :key="index" @tap="bindCity" :data-city="item.city" :data-code="item.code" >
+			<text class="padding-left-50">{{item.city}}</text>
+      	</view>
+      </view>
+      <view v-if="condition" class="hotcity-common" style="margin-bottom: 10rpx;" >选择区县</view>
+      <view v-if="condition" class="county">
+        <block v-for="(item, index) in countyList" :key="index"  class="hotCity">
+          <view class="weui-grid" style="margin-right: 16rpx;" :data-code="item.id" :data-city="item.fullname" @tap="bindCounty">
+            <view class="weui-grid__label">{{item.fullname}}</view>
+          </view>
+        </block>
+      </view>
+
+      <view class="selectCity">
+        <view class="hotcity-common" @tap="reGetLocation">重新定位城区</view>
+        <view class="thisCityName" :data-city="city" :data-code="currentCityCode">{{city}}{{county}}</view>
+
+        <view class="hotcity-common">热门城市</view>
+        <view class="weui-grids">
+          <view class="weui-grid" data-code="110000" data-city="北京市" @tap="bindCity">
+            <view class="weui-grid__label">北京市</view>
+          </view>
+          <view class="weui-grid" data-code="310000" data-city="上海市" @tap="bindCity">
+            <view class="weui-grid__label">上海市</view>
+          </view>
+          <view class="weui-grid" data-code="440100" data-city="广州市" @tap="bindCity">
+            <view class="weui-grid__label">广州市</view>
+          </view>
+        </view>
+        <view class="weui-grids">
+          <view class="weui-grid" data-code="440300" data-city="深圳市" @tap="bindCity">
+            <view class="weui-grid__label">深圳市</view>
+          </view>
+          <view class="weui-grid" data-code="330100" data-city="杭州市" @tap="bindCity">
+            <view class="weui-grid__label">杭州市</view>
+          </view>
+          <view class="weui-grid" data-code="320100" data-city="南京市" @tap="bindCity">
+            <view class="weui-grid__label">南京市</view>
+          </view>
+        </view>
+        <view class="weui-grids">
+          <view class="weui-grid" data-code="420100" data-city="武汉市" @tap="bindCity">
+            <view class="weui-grid__label">武汉市</view>
+          </view>
+          <view class="weui-grid" data-code="120000" data-city="天津市" @tap="bindCity">
+            <view class="weui-grid__label">天津市</view>
+          </view>
+          <view class="weui-grid" data-code="610100" data-city="西安市" @tap="bindCity">
+            <view class="weui-grid__label">西安市</view>
+          </view>
+        </view>
+      </view>
+      <view v-for="(item, index) in cityList" :key="index" class="selection">
+        <view class="item_letter" :id="item.initial">{{item.initial}}</view>
+        <view v-for="(ct, index2) in item.cityInfo" :key="index2" class="item_city" :data-code="ct.code" :data-city="ct.city" @tap="bindCity">
+          {{ct.city}}
+        </view>
+      </view>
+    </scroll-view>
+
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+var app=getApp()
+const city = require("../../utils/city.js");
+const cityObjs = require("../../utils/city.js");
+const config = require("../../utils/config.js");
+const appInstance = getApp();
+export default {
+  data() {
+    return {
+      searchLetter: [],
+      showLetter: "",
+      winHeight: 0,
+      cityList: [],
+      isShowLetter: false,
+      scrollTop: 0,
+	  oldScrollTop:0,
+      //置顶高度
+      scrollTopId: '',
+      //置顶id
+      city: "定位中...",
+      currentCityCode: '',
+      inputName: '',
+      completeList: [],
+      county: '',
+	  //do
+      condition: false,
+	  
+      itemH: "",
+      toastShowLetter: "",
+      countyList: ""
+    };
+  },
+
+  components: {},
+  props: {},
+  onLoad: function () {
+    // 生命周期函数--监听页面加载
+    const searchLetter = city.searchLetter;
+    const cityList = city.cityList();
+    const sysInfo = uni.getSystemInfoSync();
+    console.log(sysInfo);
+    const winHeight = sysInfo.windowHeight;
+    const itemH = winHeight / searchLetter.length;
+    let tempArr = [];
+    searchLetter.map((item, index) => {
+      // console.log(item);
+      // console.log(index);
+      let temp = {};
+      temp.name = item;
+      temp.tHeight = index * itemH;
+      temp.bHeight = (index + 1) * itemH;
+      tempArr.push(temp);
+    }); // console.log(tempArr);
+
+    this.setData({
+      winHeight: winHeight,
+      itemH: itemH,
+      searchLetter: tempArr,
+      cityList: cityList,
+      //兼容地图插件
+      city: appInstance.globalData.city,
+      currentCityCode: appInstance.globalData.currentCityCode,
+      county: appInstance.globalData.county
+    }); //this.getLocation();
+  },
+  methods: {
+	  goTop (e) {
+		  //视图会发生重新渲染
+		  this.scrollTop = this.oldScrollTop
+		  //当视图渲染结束 重新设置为0
+		  this.$nextTick(() =>{
+			  this.scrollTop = 0
+		  });
+	  },
+    clickLetter: function (e) {
+      // console.log(e);
+      console.log(e.currentTarget.dataset.letter);
+      const showLetter = e.currentTarget.dataset.letter;
+      this.setData({
+        toastShowLetter: showLetter,
+        isShowLetter: true,
+        scrollTopId: showLetter
+      }); // const that = this;
+      // wx.showToast({
+      //   title: showLetter,
+      //   disabled: true,
+      //   duration: 500,
+      //   complete: function() {
+      //     that.setData({
+      //       scrollTopId: showLetter,
+      //     })
+      //   }
+      // })
+
+      const that = this;
+      setTimeout(function () {
+        that.setData({
+          isShowLetter: false
+        });
+      }, 500);
+    },
+    reGetLocation: function () {
+      appInstance.globalData.defaultCity = this.city;
+      appInstance.globalData.defaultCounty = this.county;
+      console.log(appInstance.globalData.defaultCity); //返回首页
+
+      uni.navigateTo({
+        url: "/pages/choosePlot/choosePlot"
+      });
+    },
+    //选择城市
+    bindCity: function (e) {
+	  this.goTop()
+      this.setData({
+        condition: true,
+        city: e.currentTarget.dataset.city,
+        currentCityCode: e.currentTarget.dataset.code,
+        completeList: []
+      });
+      this.selectCounty();
+      appInstance.globalData.defaultCity = this.city;
+      appInstance.globalData.defaultCounty = '';
+      this.setData({
+        county: "",
+        currentCityCode: ""
+      });
+      console.log(appInstance.globalData.defaultCity);
+    },
+    bindCounty: function (e) {
+      console.log(e); //this.setData({ county: e.currentTarget.dataset.city })
+      //appInstance.defaultCounty = this.data.county
+
+      console.info("////" + this.city);
+      let pages = getCurrentPages(); //获取当前页面js里面的pages里的所有信息.
+
+      let prevPage = pages[pages.length - 2].$vm; //prevPage 是获取上一个页面的js里面的pages的所有信息。 -2 是上一个页面,-3是上上个页面以此类推。
+	  
+	  if(!this.$isEmpty(this.city)){
+	  	app.globalData.city=this.city
+	  }
+	  if(!this.$isEmpty(e.currentTarget.dataset.city)){
+	  	app.globalData.county=e.currentTarget.dataset.city
+	  }
+	  if(!this.$isEmpty(e.currentTarget.dataset.code)){
+	  	app.globalData.currentCityCode=e.currentTarget.dataset.code
+	  }
+      prevPage.setData({
+        // 将我们想要传递的参数在这里直接setData。上个页面就会执行这里的操作。
+        city: this.city,
+        //广州市
+        county: e.currentTarget.dataset.city,
+        //页面标签定义的是city--天河区
+        currentCityCode: e.currentTarget.dataset.code //天河区的code
+
+      }); //从新获取楼栋信息
+
+      prevPage.getCommunity(); //上一个页面内执行setData操作,将我们想要的信息保存住。当我们返回去的时候,页面已经处理完毕。
+      //最后就是返回上一个页面。
+
+      uni.navigateBack(); //console.log(appInstance.defaultCounty);
+      // wx.navigateBack({
+      //   url: "/pages/choosePlot/choosePlot",
+      // })
+    },
+    //点击热门城市回到顶部
+    hotCity: function () {
+      console.log("hotCity");
+      this.setData({
+        scrollTop: 0
+      });
+    },
+    bindScroll: function (e) {//  console.log(e.detail)
+		this.oldScrollTop = e.detail.scrollTop
+    },
+    selectCounty: function () {
+      console.log("正在定位区县");
+      let code = this.currentCityCode; // console.log(code);
+
+      const that = this;
+      uni.request({
+        url: `https://apis.map.qq.com/ws/district/v1/getchildren?&id=${code}&key=${config.key}`,
+        success: function (res) {
+          // console.log(res.data)
+          // console.log(res.data.result[0]);
+          that.setData({
+            countyList: res.data.result[0]
+          }); // console.log(that.data.countyList);
+
+          console.log("请求区县成功" + `https://apis.map.qq.com/ws/district/v1/getchildren?&id=${code}&key=${config.key}`); // console.log(res)
+        },
+        fail: function () {
+          console.log("请求区县失败,请重试");
+        }
+      });
+    },
+    getLocation: function () {
+      console.log("正在定位城市");
+      this.setData({
+        county: ''
+      });
+      const that = this;
+      uni.getLocation({
+        type: 'wgs84',
+        success: function (res) {
+          let latitude = res.latitude;
+          let longitude = res.longitude;
+          uni.request({
+            url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${config.key}`,
+            success: res => {
+              // console.log(res)
+              console.log(res.data.result.ad_info.city + res.data.result.ad_info.adcode);
+              that.setData({
+                city: res.data.result.ad_info.city,
+                currentCityCode: res.data.result.ad_info.adcode,
+                county: res.data.result.ad_info.district
+              });
+              that.selectCounty();
+            }
+          });
+        }
+      });
+    },
+    bindBlur: function (e) {
+      this.setData({
+        inputName: ''
+      });
+    },
+    bindKeyInput: function (e) {
+      this.setData({
+        inputName: e.detail.value
+      });
+      this.auto();
+	  
+	  this.goTop()
+    },
+    auto: function () {
+      let inputSd = this.inputName.trim();
+      let sd = inputSd.toLowerCase();
+      let num = sd.length;
+      const cityList = cityObjs.cityObjs; // console.log(cityList.length)
+
+      let finalCityList = [];
+      let temp = cityList.filter(item => {
+        let text = item.short.slice(0, num).toLowerCase();
+        return text && text == sd;
+      }); //在城市数据中,添加简拼到“shorter”属性,就可以实现简拼搜索
+
+      let tempShorter = cityList.filter(itemShorter => {
+        if (itemShorter.shorter) {
+          let textShorter = itemShorter.shorter.slice(0, num).toLowerCase();
+          return textShorter && textShorter == sd;
+        }
+
+        return;
+      });
+      let tempChinese = cityList.filter(itemChinese => {
+        let textChinese = itemChinese.city.slice(0, num);
+        return textChinese && textChinese == sd;
+      });
+
+      if (temp[0]) {
+        temp.map(item => {
+          let testObj = {};
+          testObj.city = item.city;
+          testObj.code = item.code;
+          finalCityList.push(testObj);
+        });
+        this.setData({
+          completeList: finalCityList
+        });
+      } else if (tempShorter[0]) {
+        tempShorter.map(item => {
+          let testObj = {};
+          testObj.city = item.city;
+          testObj.code = item.code;
+          finalCityList.push(testObj);
+        });
+        this.setData({
+          completeList: finalCityList
+        });
+      } else if (tempChinese[0]) {
+        tempChinese.map(item => {
+          let testObj = {};
+          testObj.city = item.city;
+          testObj.code = item.code;
+          finalCityList.push(testObj);
+        });
+        this.setData({
+          completeList: finalCityList
+        });
+      } else {
+        return;
+      }
+    }
+  }
+};
+</script>
+<style lang="scss">
+.container-inner {
+  display: flex;
+  flex-direction: row-reverse;
+}
+
+.container {
+  flex-grow: 1;
+  display: flex;
+  flex-direction: column;
+  padding: 0rpx;
+
+}
+
+input {
+  text-align: center;
+  font-size: 32rpx;
+  padding: 5px;
+}
+
+.searchLetter {
+  flex-shrink: 0;
+  width: 80rpx;
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  color: #666;
+}
+
+.searchLetter view {
+  margin-top: 20rpx;
+}
+
+.touchClass {
+  background-color: #fff;
+  color: #fff;
+  padding-top: 16rpx;
+  padding-bottom: 16rpx;
+}
+
+.showSlectedLetter {
+  background-color: rgba(0, 0, 0, 0.5);
+  color: #fff;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  margin: -100rpx;
+  width: 200rpx;
+  height: 200rpx;
+  border-radius: 20rpx;
+  font-size: 52rpx;
+  z-index: 1;
+}
+
+.selection {
+  display: flex;
+  width: 100%;
+  flex-direction: column;
+  margin-top: 10rpx;
+}
+
+.selectCity {
+  padding: 16rpx;
+  background-color: #FFFFFF;
+  margin-bottom: -10rpx;
+}
+
+.item_letter {
+  color: $base-btn-color;
+  display: flex;
+  background-color: #f5f5f5;
+  height: 40rpx;
+  padding-left: 34rpx;
+  align-items: center;
+  font-size: 24rpx;
+}
+
+.item_city {
+  display: flex;
+  background-color: #fff;
+  height: 100rpx;
+  padding-left: 34rpx;
+  align-items: center;
+  border-bottom: 1rpx solid #ededed;
+  font-size: 24rpx;
+}
+
+.hotcity-common {
+  font-size: 24rpx;
+  color: #666;
+  padding-bottom: 0;
+  margin: 8rpx 0;
+  margin-left: 16rpx;
+}
+
+.hotCity {
+  padding-right: 50rpx;
+  margin: auto;
+}
+
+.thisCityName {
+  display: inline-block;
+  border: 1rpx solid $base-btn-color;
+  border-radius: 8rpx;
+  padding: 16rpx 20rpx;
+  font-size: 24rpx;
+  color: $base-btn-color;
+  text-align: center;
+  min-width: 149.5rpx;
+  margin: 16rpx 0;
+}
+
+.thishotText {
+  color: $base-btn-color;
+  font-size: 20rpx;
+  margin: 0 !important;
+}
+
+.slectCity {
+  border-color: $base-btn-color !important;
+}
+
+.slectCity view {
+  color: $base-btn-color !important;
+}
+
+.weui-grid {
+  padding: 18rpx 0;
+  width: 200rpx;
+  box-sizing: border-box;
+  border: 1rpx solid #c8c8c8;
+  border-radius: 8rpx;
+  background-color: white;
+  margin: 8rpx 0;
+}
+
+.weui-grids {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+}
+
+.weui-grid__label {
+  display: block;
+  text-align: center;
+  color: #333;
+  font-size: 24rpx;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+
+.ul {
+  display: block;
+  color: grey;
+  margin-left: 20rpx;
+}
+
+.li {
+  display: block;
+  font-weight: 100;
+  font-size: 28rpx;
+  padding: 20rpx 0;
+  border-bottom: 1rpx solid #efefef;
+}
+
+input {
+  background-color: #fff;
+}
+
+.input {
+  padding: 16rpx;
+  border-bottom: 1rpx solid #f1f1f1;
+}
+
+.county {
+  padding: 10rpx 0 0 20rpx;
+  background-color: #FFFFFF;
+  display: flex;
+  flex-wrap: wrap;
+}
+
+</style>

+ 114 - 0
pages/tool-list/epidemic-pass/detail.vue

@@ -0,0 +1,114 @@
+<template>
+	<view>
+		<view class="card">
+			<view class="top">
+				<text class="title">宁夏冬美小区</text>
+				<view class="avatar">
+					<u-avatar :sex-icon="userInfo.gender==1?'man':'woman'" show-sex="true" size="110" :src="userInfo.avatarUrl"></u-avatar>
+				</view>
+				<view class="text-center text-bold">
+					<text v-text="userInfo.nickName"></text>
+				</view>
+				<view class="text-center padding-top-50 " style="font-size: 26rpx;">
+					请出示该通行证截图,由保安核检
+				</view>
+			</view>
+			<view class="bottom">
+				<view class="item">
+					<text class="">姓名:</text>
+					<text>黄明潘</text>
+				</view>
+				<view class="item">
+					<text class="">身份类型:</text>
+					<text>访客</text>
+				</view>
+				<view class="item">
+					<text class="">出入原因:</text>
+					<text>去朋友家</text>
+				</view>
+				<view class="item">
+					<text class="">体温是否异常:</text>
+					<text class="text-red text-bold">是</text>
+				</view>
+				<view class="item">
+					<text class="">是否有异常症状:</text>
+					<text>否</text>
+				</view>
+				<view class="item">
+					<text class="">访问日期:</text>
+					<text>2020-11-09 15:56:23</text>
+				</view>
+			</view>
+		</view>
+		<view class="text-center text-sm text-gray">
+			通行证仅当天有效,隔日需要再次登记出入信息
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				userInfo:{}
+			}
+		},
+		onLoad() {
+			this.login()
+		},
+		methods: {
+			login(){
+				let that=this
+				uni.login({
+				  success: function () {
+				    uni.getUserInfo({
+				      success: function (res) {
+				        that.userInfo=res.userInfo
+						console.log(that.userInfo);
+				      }
+				    });
+				  }
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.card{
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		width: 80%;
+		height: 850rpx;
+		border-radius: 18rpx;
+		background-color: #FFFFFF;
+		margin: 50rpx auto;
+		
+		.top{
+			padding-top: 20rpx;
+			margin: 30rpx;
+			.title{
+				font-size: 32rpx;
+				font-weight: 800;
+				display: flex;
+				justify-content: center;
+			}
+		}
+		
+		.bottom{
+			padding-bottom: 50rpx;
+			.item{
+				padding: 10rpx 0 10rpx 50rpx;
+				text:first-child{
+					padding-right: 20rpx;
+				}
+			}
+		}
+		.avatar{
+			padding: 50rpx 0 20rpx 0;
+			display: flex;
+			justify-content: center;
+		}
+	}
+</style>

+ 121 - 0
pages/tool-list/epidemic-pass/epidemic-pass.vue

@@ -0,0 +1,121 @@
+<template>
+	<view class="page">
+		<view class="content">
+			<text class=" text-xl ">出入信息填写</text>
+			<view class="name">
+				<view >
+					<text>*</text>
+					<text>您的姓名</text>
+				</view>
+				<view class="input">
+					<input  type="text" value="" placeholder="请输入您的姓名"/>
+				</view>
+			</view>
+			
+			<view class="cause">
+				<view >
+					<text >*</text>
+					<text>出入原因</text>
+				</view>
+				<view class="input">
+					<input  type="text" value="" placeholder="请填写出入小区的原因"/>
+				</view>
+			</view>
+			
+			<view class="radio1 flex justify-between" >
+				<view >
+					<text >*</text>
+					<text style="line-height: 56rpx;">体温是否异常(高于37.3摄氏度属于异常)</text>
+				</view>
+				<view class="switch">
+					<switch style="transform: scale(.9);" class='blue' @change="switch1Change"  :checked="switch1Check" ></switch>
+				</view>
+			</view>
+			
+			<view class="radio1 flex justify-between" >
+				<view >
+					<text >*</text>
+					<text style="line-height: 56rpx;">是否有咳嗽 / 乏力 / 呼吸困难 / 流鼻涕 / 腹泻等异常症状</text>
+				</view>
+				<view class="switch">
+					<switch style="transform: scale(.9);" class='blue' @change="switch2Change"  :checked="switch2Check" ></switch>
+				</view>
+			</view>
+		</view>
+		<view class=" footer-fixed" @click="submit">
+			<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+				提交信息
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				switch1Check:false,
+				switch2Check:false
+			}
+		},
+		methods: {
+			switch1Change(e){
+				this.switch1Check=e.target.value
+			},
+			switch2Change(e){
+				this.switch2Check=e.target.value
+			},
+			submit(){
+				uni.navigateTo({
+					url:"./detail"
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.page{
+		min-height: 100vh;
+		background-color: #FFFFFF;
+	}
+	
+	.content{
+		padding: 40rpx;
+		.name,.cause,.radio1,.radio2{
+			padding-top: 40rpx;
+			view:nth-child(1){
+				display: flex;
+				// *星号
+				text:nth-child(1){
+					font-weight: 800;
+					font-size: 38rpx;
+					color: #D43A39;
+					padding-right: 10rpx;
+				}
+				//您的姓名
+				text:nth-child(2){
+					font-size: 30rpx;
+				}
+			}
+			.input{
+				padding: 20rpx 0 15rpx 25rpx;
+				border-bottom: 1rpx solid #d6d6d6;
+			}
+		}
+		switch{
+			display: flex;
+		}
+		.radio1,.radio2{
+			padding-bottom: 15rpx;
+			border-bottom: 1rpx solid #d6d6d6;
+			.switch{
+				display: flex;
+				justify-content: center;
+				align-items: center;
+			}
+		}
+	}
+	
+	
+</style>

+ 106 - 0
pages/tool-list/tool-list.vue

@@ -0,0 +1,106 @@
+<template>
+	<view>
+		<grid :column="4" :gridList="gridList" :border="false" @tapGrid="tapGrid"></grid>
+		<u-divider bg-color="#f1f1f1" height="100">到底了</u-divider>
+	</view>
+</template>
+
+<script>
+	import grid from "@/comps/grid/grid.vue"
+	export default {
+		components:{
+			grid
+		},
+		data() {
+			return {
+				//提示:如果点击某项,不进行跳转页面,那么请添加type属性为click
+				gridList:[
+				   {
+				       title:'业主认证',
+				       subList:[
+				           {
+				               src:'/static/grid1/fangwu.png',  name:'我的房屋', url:"/pages/myhome/myhome"
+				           },
+				           {
+				               src:'/static/grid1/luru.png',  name:'人脸录入', url:"/pages/uploadFace/uploadFace"
+				           },
+				           {
+				               src:'/static/grid1/renyuan.png',  name:'家人管理', url:"/pages/myFamily/myFamily"
+				           },
+						   {
+				               src:'/static/grid1/fangwu.png',  name:'家人关爱', url:"/pages/index/index",type:'click'
+				           },
+				           {
+				               src:'/static/grid1/baoxiu.png',  name:'增值订购', url:"/pages/index/index",type:'click'
+				           },
+						   {
+				               src:'/static/grid1/luru.png',  name:'业主投票', url:"/pages/index/index",type:'click'
+				           }
+				       ]
+				   },
+				   {
+				       title:'小区出入',
+				       subList:[
+				           {
+				               src:'/static/grid1/kaimen.png',  name:'一键开门', url:"/pages/device/device",type:'switchTab'
+				           },
+				           {
+				               src:'/static/grid1/fangke1.png',  name:'远程开门', url:"/pages/index/index",type:'click'
+				           },
+				           {
+				               src:'/static/grid1/luru.png',  name:'刷卡开门', url:"/pages/index/index",type:'click'
+				           },{
+				               src:'/static/grid1/fangke1.png',  name:'访客授权', url:"/pages/authorize_record/authorize_record"
+				           },
+				           {
+				               src:'/static/grid1/baoxiu.png',  name:'访客记录', url:"/pages/record/record"
+				           }
+				       ]
+				   },
+				   {
+				       title:'小区应用',
+				       subList:[
+				           {
+				               src:'/static/grid1/luru.png',  name:'物业缴费', url:"/pages/index/index", type:'click'
+				           },
+				           {
+				               src:'/static/grid1/fangke1.png',  name:'扫码充电', url:"/pages/index/index", type:'click'
+				           },
+				           {
+				               src:'/static/grid1/baoxiu.png',  name:'物管报修', url:"/pages/index/index", type:'click'
+				           },{
+				               src:'/static/grid1/gonggao.png',  name:'公告查看', url:"/pages/index/index", type:'click'
+				           }
+				       ]
+				   },
+				   {
+				       title:'社区周边',
+				       subList:[
+				           {
+				               src:'/static/grid1/fangke1.png',  name:'周边商户', url:"/pages/index/index", type:'click'
+				           },
+				           {
+				               src:'/static/grid1/kaimen.png',  name:'送水服务', url:"/pages/index/index", type:'click'
+				           },
+						   {
+				               src:'/static/grid1/renyuan.png',  name:'代收快递', url:"/pages/index/index", type:'click'
+				           }
+				       ]
+				   }
+				]
+			}
+		},
+		methods: {
+			tapGrid ( data ) {
+				uni.showToast({
+					title:"待开发",
+					icon:"none"
+				})
+		   }
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 432 - 0
pages/uploadFace/uploadFace.vue

@@ -0,0 +1,432 @@
+<template>
+<view>
+<!--pages/ uploadFace/uploadFace.wxml-->
+<view>
+<!--  <picker class="cybm_pic_1" :value="index" :range="list" :range-key="'roomName'" @change="roomChange">
+    <view class="picker form_group">
+      <view class="my-item">
+        <text class="info">我的房屋</text>
+        <text class="status">{{list[index].roomName}}</text>
+        <text class="iconfont icon-arrow-left arrow"></text>
+      </view>
+    </view>
+  </picker> -->
+  <view class="cu-list menu" @click="locationShow=true">
+  	<view class="cu-item" >
+  		<view class="content">
+  			<text >我的房屋</text>
+  		</view>
+  		<view class="action">
+  			<text >{{selectLabel?selectLabel:list[0].roomName}}</text>
+  			<text class="cuIcon-right padding-left-10"></text>
+  		</view>
+  	</view>
+  </view>
+</view>
+
+<view class="upload_container">
+  <view>
+	  <view @click="show=true"  style="margin: 30rpx 0 10rpx 0;display: flex;align-items: center;flex-direction: column;">
+	    <upload-img
+	  	  :width="$isEmpty(face_url)?300:560"
+	  	  :height="$isEmpty(face_url)?300:420"
+	  	  :currentImage="face_url"
+		  bgsrc="http://139.9.103.171:1888/img/image/camera1.png"
+	  	  >
+	    </upload-img>
+	    <view class="" style="color: #59a5f0;">
+	  	 <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
+	  	 <text v-if="$isEmpty(face_url)">点击上传人脸</text>
+	  	 <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
+	    </view>
+	  </view>
+  </view>
+</view>
+<view class="category">
+  <view v-for="(item, index) in iconArray" :key="index" class="category_item">
+    <view class="category_item_wrap" @tap="top" :data-index="item.index">
+      <view class="icon_wrap">
+        <image :src="item.iconUrl" class="index_icon"></image>
+      </view>
+      <view class="category_item_text">
+        <text>{{item.iconText}}</text>
+      </view>
+    </view>
+  </view>
+</view>
+<canvas canvas-id="photo_canvas" :style="'width:' + canvasWidth + 'px;height:' + canvasHeight + 'px;position: absolute;left:-300px;top:-300px;'"></canvas>
+<view @tap="uploadFace" class=" footer-fixed" >
+	<view class="cu-btn  flex  text-lg bg-red-btn" style="padding: 46rpx 0;">
+		提交人脸信息
+	</view>
+</view>
+<u-select z-index="9999999"  mode="single-column" value-name="id"  label-name="roomName" v-model="locationShow" :list="list" @confirm="roomChange"></u-select>
+<u-action-sheet @click="photoChecked"  z-index="999999" :list="actionList" v-model="show"></u-action-sheet>
+</view>
+</template>
+
+<script>
+import uploadImg from '@/comps/uploadimg/uploadImg.vue'
+//获取app实例
+var app = getApp();
+
+export default {
+  components:{
+	  uploadImg
+  },
+  data() {
+    return {
+	  //显示模态框
+	  locationShow:false,
+	  selectLabel:'',
+		
+	  //上传人面
+	  actionList: [{
+	  	text: '相册上传',
+	  }, {
+	  	text: '拍照上传'
+	  }],
+	  show: false,
+		
+      face_url: null,
+      //人脸图片地址
+      face_image: null,
+      //人脸图片的base64字符串
+      list: null,
+      //住户信息列表
+      index: null,
+      //当前显示住户信息下标
+      iconArray: [{
+        "iconUrl": "http://139.9.103.171:1888/img/image/zd.png",
+        "iconText": '不要遮挡',
+        "index": 1
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/mj.png",
+        "iconText": '不戴墨镜',
+        "index": 2
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/zl.png",
+        "iconText": '不能仰头俯拍',
+        "index": 3
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/cz.png",
+        "iconText": '光线充足',
+        "index": 4
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/bg.png",
+        "iconText": '浅色背景',
+        "index": 5
+      }, {
+        "iconUrl": "http://139.9.103.171:1888/img/image/sh.png",
+        "iconText": '物业审核生效',
+        "index": 6
+      }]
+
+    };
+  },
+  onShow() {
+  	//获取当前页面的对象
+  	let currPage=this.$util.getPageCtx()
+  	if(!this.$isEmpty(currPage.data.image)){
+  		this.handelImg(currPage.data.image)
+  	} 
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    this.getFaceImg();
+  },
+  methods: {
+	  //点击模态框选项触发
+	  photoChecked(index){
+		if (index==0) {
+			//图片上传
+			this.chooseImage()
+		} else if(index==1){
+			//拍照上传
+			uni.navigateTo({
+				url:"../my-camera/my-camera"
+			})
+		}
+	  },
+    //选择房间
+    roomChange: function (e) {
+	   // 选中的房屋 id
+	   let id=e[0].value
+	   //选中的房屋名字
+	   this.selectLabel=e[0].label
+	   //选中的房屋列表的下标
+	   let index= this.list.findIndex(value => value.id===id)
+      let list = this.list;
+      // let index = e.detail.value;
+      let url = list[index].imageUri;
+      console.log(url);
+      this.setData({
+        index: index,
+        face_url: list[index].imageUri
+      });
+    },
+    //获取住户人脸
+    getFaceImg: function () {
+      let that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id;
+      let operation = 'user/getMyUserByMemberId';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("查询结果:" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          // let list = res.data.list;
+          console.log(res.data.list);
+          let list = [];
+          if (uni.getStorageSync('plotName')) {
+            res.data.list.map(item => {
+              if (item.residentialName == uni.getStorageSync('plotName')) {
+                list.push(item);
+              }
+            });
+          } else {
+            list = res.data.list;
+          }
+
+
+          that.setData({
+            face_url: list[0].imageUri,
+            list: list,
+            index: 0
+          });
+        }
+      });
+    },
+    //点击上传图片事件
+    chooseImage: function () {
+      var that = this;
+      uni.chooseImage({
+        count: 1,
+        //最多可以选择的图片张数,默认9
+        sourceType: ['album', 'camera'],
+        sizeType: ['compressed'],
+        //可选择原图或压缩后的图片
+        success: res => {
+          that.handelImg(res.tempFilePaths[0])
+        }
+      });
+    },
+	//处理照片,拍照上传和相册上传的共同处理方法
+	handelImg(imgUrl){
+		var that = this;
+		that.setData({
+		  //图片回显
+		  face_url: imgUrl
+		});
+		uni.getFileSystemManager().readFile({
+		  filePath: imgUrl,
+		  //选择图片返回的相对路径
+		  encoding: 'base64',
+		  //编码格式
+		  success: res => {
+		    //成功的回调
+		    console.log(res);
+		    that.setData({
+		      //图片的base64字符串
+		      face_image: 'data:image/jpeg;base64,' + res.data
+		    });
+		  }
+		});
+	},
+	
+    //上传用户faceImg
+    uploadFace: function () {
+      let that = this;
+      let params = {};
+      let index = that.index; //let index = 0;
+
+      let user = that.list[index];
+      let user_id = user.id;
+      params['user_id'] = user_id;
+      let tel = user.tel;
+      params['tel'] = tel;
+      let type = user.type;
+      params['type'] = type;
+      let id_card = user.idCard;
+      params['id_card'] = id_card;
+      let sex = user.sex; //性别
+
+      params['sex'] = sex;
+      let nationality = user.nationality;
+      params['nationality'] = nationality;
+      let face_image = this.face_image;
+
+      if (face_image) {
+        params['face_image_base64'] = that.face_image;
+      }else{
+		  if(!this.$isEmpty(this.face_url)){
+			  app.globalData.autoFailHint("请重新上传人脸图片");
+			  return;
+		  }else{
+			  app.globalData.autoFailHint("请上传人脸图片");
+			  return;
+		  }
+	  }
+      params['member_id'] = app.globalData.member.id; //申请来源0-小程序添加 1-后台添加  2-后台导入 3-app添加
+
+      params['create_type'] = '0';
+      let operation = 'user/editUser';
+      app.globalData.postRequest(params, operation, function (res) {
+        if (res.data.result_code == 1) {
+          app.globalData.oneFailHint(res.data.result_msg, function () {
+            uni.redirectTo({
+              url: '/pages/uploadFace/uploadFace'
+            });
+          });
+        } else {
+          app.globalData.oneFailHint(res.data.result_msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss">
+/* pages/ uploadFace/uploadFace.wxss */
+page{
+   background: #fff;
+}
+.upload_container {
+  text-align: center;
+  color: #333;
+  background: #fff;
+  border-radius: 10rpx;
+}
+
+.upload_bg {
+  position: relative;
+}
+
+.upload_bg .upload_btn {
+  width: 120rpx;
+  height: 120rpx;
+  position: absolute;
+  left: 50%;
+  top: 40%;
+  margin-left: -65rpx;
+  margin-top: -60rpx;
+}
+
+.upload_bg .upload_btn image {
+  width: 100%;
+  height: 100%;
+}
+
+.upload_text {
+  position: absolute;
+  top: 55%;
+  width: 100%;
+  color: $base-btn-color;
+}
+
+.img_content {
+  margin-top: 20rpx;
+  position: relative;
+  text-align: center;
+}
+
+.img_content .upload_bgImg {
+  width: 560rpx;
+  height: 420rpx;
+  max-height: 1;
+  display: inline-block;
+  border-radius: 20rpx;
+}
+
+.reUpload {
+display: flex;
+justify-content: flex-end;
+align-items: center;
+  height: 60rpx;
+  line-height: 60rpx;
+  color: #333;
+  padding-right: 40rpx;
+}
+
+.img_content .img_icon {
+  width: 40rpx;
+  height: 40rpx;
+  vertical-align: text-top;
+  margin-right: 6rpx;
+  border-radius: 20rpx;
+}
+.tips{
+  height: 80rpx;
+  line-height: 80rpx;
+  padding-left:30rpx;
+  background-color: #f5f5f5;
+  color:#777;
+}
+.category {
+  padding:20px 20rpx 0;
+  overflow: auto;
+  background-color: #FFF;
+text-align:center;
+
+}
+.category_item {
+  width: 33.3%;
+  float: left;
+  margin-bottom: 40rpx;
+}
+.icon_wrap {
+  width: 120rpx;
+  margin: 0 auto;
+  margin-bottom: 5px;
+}
+.index_icon {
+  width: 60rpx;
+  height: 60rpx;
+}
+.category_item_text {
+  text-align: center;
+  font-size: 24rpx;
+  color: #999;
+}
+.form_group {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  margin: 20rpx 20rpx;
+  line-height: 100rpx;
+  position: relative;
+  font-size: 26rpx;
+  border-bottom: 2rpx solid #ddd;
+  
+}
+.my-item .iconfont.arrow {
+  position: absolute;
+  right: 0;
+  top: 50%;
+  transform: translate(0, -50%);
+  font-size: 32rpx;
+  vertical-align: top;
+ 
+}
+.my-item {
+  width: 100%;
+  position: relative;
+  background: #fff;
+  font-size: 28rpx;
+  box-sizing: border-box;
+}
+
+.my-item .status {
+  position: absolute;
+  right: 35rpx;
+  top: 50%;
+  transform: translate(0, -50%);
+  font-size: 28rpx;
+}
+</style>

+ 64 - 0
pages/webview/webview.vue

@@ -0,0 +1,64 @@
+<template>
+<web-view :src="url"></web-view>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      url: ''
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+	 this.url=options.url || ''
+	 console.log(this.url);
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady: function () {},
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow: function () {},
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide: function () {},
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload: function () {},
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh: function () {},
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom: function () {},
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage: function () {},
+  methods: {}
+};
+</script>
+<style>
+/* template/webview.wxss */
+</style>

+ 84 - 0
pages/wode/direction/direction.vue

@@ -0,0 +1,84 @@
+<template>
+	<view class="warp">
+		<view class="content "  @click="tap(item)" :class="item.open?'':'borderBottom'" v-for="(item,index) in itemList" :key="index">
+			<view class="title">
+				<view >
+					<text>{{index+1}}:</text>
+					<text class="padding-left-20">{{item.head}}</text>
+				</view>
+				<text :class="item.open?'cuIcon-unfold':'cuIcon-right'"></text>
+			</view>
+			<view class="body" v-show="item.open==true">
+				<text>{{item.body}}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				itemList: [{
+					head: "如何注册认证房屋信息?",
+					body: "第一步(注册用户账号):输入姓名,手机号和验证码进行注册。注册成功后进入第二步(房屋认证):选择所在的城市,小区,楼栋和门牌号,点击进入第三步(用户认证):选择住户类型,业主必须填写身份证;点击上传人脸,认证成功进入主页面。",
+					open: false,
+					disabled: true
+				},{
+					head: "如何认证成为业主?",
+					body: "住户认证成功后,可在我的房屋中选择房屋,点击“成为业主”,填写在正确的身份证号,选择关系为“业主”后提交,后台审核通过即可完成业主认证。",
+					open: false,
+				},{
+					head: "如何添加家人?",
+					body: "业主注册认证成功后,可在我的家人中添加家人,添加成功显示在未认证列表,后台审核通过显示已认证列表。",
+					open: false,
+				},{
+					head: "如何给来访客人授权开门?",
+					body: "a)访客授权,点击申请密码,访客类型默认为朋友,密码有效期默认为1小时,访问次数默认为1,可直接点击获取开门密码,生成开门密码;2)获取密码后,可选择直接转发到微信好友,或者复制到微信,QQ,短信。",
+					open: false,
+				},{
+					head: "物业人员审核申请信息不通过怎么处理?",
+					body: "物业超过72效时仍未完成审核,请拨打物业人员的电话,主动要求其尽快完成审核工作;",
+					open: false,
+				},{
+					head: "不在本小区居住后,个人信息怎么清除?",
+					body: "业主注册认证成功后,可在我的家人中添加家人,添加成功显示在未认证列表,后台审核通过显示已认证列表。",
+					open: false,
+				}],
+			}
+		},
+		methods: {
+			tap(item){
+				item.open=item.open?false:true
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color: #FFFFFF;
+	}
+	.warp{
+		.content{
+			padding: 40rpx 0;
+			.title{
+				font-size: 32rpx;
+				display: flex;
+				justify-content: space-between;
+				padding: 0 20rpx;
+				margin-bottom: 20rpx;
+				box-sizing: border-box;
+			}
+			.body{
+				line-height: 48rpx;
+				padding: 10rpx 15rpx 10rpx 30rpx;
+				background-color: #F2F2F2;
+			}
+		}
+	}
+	
+	.borderBottom{
+		border-bottom: 1rpx solid #e8e8e8;
+	}
+</style>

+ 266 - 0
pages/wode/feedback/feedback.vue

@@ -0,0 +1,266 @@
+<template>
+	<view class="page">
+		<view class="content">
+			<view style="padding: 30rpx 0;">
+				<text>请选择您要反馈的问题类型:</text>
+			</view>
+
+			<radio-group  class="block" @change="RadioChange">
+				<view class="radioBox">
+					<view class="radioItem" :class="data.type==item.type?'checkBorder':'defalutBorder'" v-for="(item,index) in typeList" :key="index">
+						<label class="flex" >
+							<view class="">
+								<radio  style="transform: scale(.7);"  class="round blue" :class="data.type===item.type?'checked':''" :checked="data.type==item.type?true:false"
+								 :value="item.type"></radio>
+							</view>
+							<view class="text-left padding-left-20 flex" style="flex-direction: column;justify-content: center;">
+								{{item.title}}
+							</view>
+						</label>
+					</view>
+				</view>
+			</radio-group>
+			<view class="area">
+				<view >
+					<textarea @input="input" :value="data.question"  maxlength="120"  placeholder="请描述您的问题,以便我们尽快为您处理"></textarea>
+					<view  class="text-right text-df text-gray padding-bottom-10">
+						{{data.question.length}} / 120
+					</view>
+				</view>
+				<view class="imgArea">
+					<view class="padding-bottom-20">
+						<text class="">请提供相关问题的截图或照片(最多四张)</text>
+					</view>
+					<view class="cu-form-group" style="padding: 20rpx 0 0 0;">
+						<view class="grid col-3 grid-square flex-sub">
+							<view class="bg-img" v-for="(item,index) in imgList" :key="index" @click="viewImage(index)" >
+							 <image :src="imgList[index]" mode="aspectFill"></image>
+								<view class="cu-tag bg-red" @click.stop="DelImg(index)" >
+									<text class='cuIcon-close'></text>
+								</view>
+							</view>
+							<view class="solids" @click="chooseImage" v-if="imgList.length<4">
+								<text class='cuIcon-add ' style="font-size: 60rpx;color: #c9c9c9;"></text>
+							</view>
+						</view>
+					</view>
+					<!-- <u-upload @on-choose-complete="chooseImage" :auto-upload="false" width="194" height="194" :action="action" max-count="4" :file-list="fileList" ></u-upload> -->
+				</view>
+				
+			</view>
+			<view class="bg-white" style="height: 150rpx;">
+				
+			</view>
+		</view>
+		<view class="bg-white margin-top-20 footer-fixed" @click="sumit">
+			<view class="flex flex-direction padding-sm">
+				<button class="radius cu-btn base-bg-color" style="padding: 45rpx;">提交反馈</button>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	var app = getApp();
+	export default {
+		data() {
+			return {
+				//图片回显
+				imgList:[],
+				data:{
+					member_id:'',
+					question:'',
+					image_base64:[],
+					type:"1",
+				},
+				//选择项列表
+				typeList:[
+					{
+						title:'功能异常:功能故障或不可用',
+						type:'1'
+					},
+					{
+						title:'产品建议:用的不爽,我有建议',
+						type:'2'
+					},
+					{
+						title:'安全密码:密码,故障等',
+						type:'3'
+					},
+					{
+						title:'商户终端异常:无法支付,支付慢等',
+						type:'4'
+					},
+					{
+						title:'其他问题',
+						type:'5'
+					},
+				],
+			}
+		},
+		methods: {
+			//选择反馈类型
+			RadioChange(e){
+				this.data.type=e.detail.value
+			},
+			/**输入问题描述
+			 * @param {Object} e
+			 */
+			input(e){
+				this.data.question=e.detail.value
+			},
+			sumit(){
+				if (this.$isEmpty(this.data.question)) {
+					uni.showToast({
+						title:"问题描述不能为空",
+						icon:"none"
+					})
+					return
+				}
+				if (this.data.question.length<3) {
+					uni.showToast({
+						title:"问题描述不能少于三个字",
+						icon:"none"
+					})
+					return
+				}
+				if (this.$isEmpty(this.data.image_base64)) {
+					uni.showToast({
+						title:"请提供相关截图",
+						icon:"none"
+					})
+					return
+				}
+				this.data.member_id=app.globalData.member.id
+				console.log(this.data)
+				let operation='userFeedback/addFeedback'
+				app.globalData.postRequest(this.data, operation, function (res) {
+				  if (res.data.result_code == 1) {
+				    app.globalData.oneFailHint(res.data.result_msg, function () {
+				      uni.switchTab({
+				      	url:"../wode"
+				      })
+				    });
+				  } else {
+				    app.globalData.oneFailHint(res.data.result_msg);
+				  }
+				});
+			},
+			/**
+			 * 上传问题截图
+			 */
+			chooseImage() {
+				let that=this
+				uni.chooseImage({
+					count: 4-this.imgList.length, 
+					sizeType: ['original', 'compressed'], 
+					sourceType: ['album'],
+					success: (res) => {
+						const tempFilePaths = res.tempFilePaths;
+						for (let index in tempFilePaths) {
+							//图片回显
+							that.imgList.push(tempFilePaths[index])
+							//图片转为base64的图片
+							uni.getFileSystemManager().readFile({
+							  filePath: tempFilePaths[index],
+							  //选择图片返回的相对路径
+							  encoding: 'base64',
+							  //编码格式
+							  success: res => {
+							    //成功的回调
+							    that.data.image_base64.push('data:image/jpeg;base64,' + res.data)
+							  }
+							});
+						}
+					
+					}
+				});
+			},
+			/*预览图片*/
+			viewImage(index) {
+				uni.previewImage({
+					urls: this.imgList,
+					current: index
+				});
+			},
+			/*删除图片*/
+			DelImg(index) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除这张照片吗?',
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.imgList.splice(index, 1)
+						}
+					}
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.page{
+		background-color: #FFFFFF;
+		min-height: 100vh;
+	}
+	view{
+		box-sizing: border-box;
+	}
+	.commit{
+		color: #fff;
+		font-size: 28upx;
+		text-align: center;
+		line-height: 88upx;
+		margin: 0 20upx;
+		width: 690upx;
+		height:88upx;
+		background:#59a5f0;
+		border-radius:25px;
+		margin-bottom: 50upx;
+		position: absolute;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		
+	}
+	.content{
+		margin: 0 26rpx;
+		.radioBox{
+			padding-top: 10rpx;
+			.radioItem{
+				padding: 18rpx;
+				margin-bottom: 15rpx;
+				border-radius: 10rpx;
+			}
+			.defalutBorder{
+				border: 1rpx solid #d1d1d1;
+			}
+			.checkBorder{
+				border: 1rpx solid #59a5f0;
+				color: #59a5f0;
+			}
+			
+		}
+		.area{
+			margin-top: 20rpx;
+			padding: 20rpx;
+			border-radius: 12rpx;
+			border: 1rpx solid #d1d1d1;
+			
+			textarea{
+				width: 100%;
+				line-height: 50rpx;
+			}
+			.imgArea{
+				border-top: 1rpx solid #d1d1d1;
+				padding-top: 30rpx;
+			}
+			
+		}
+	}
+	
+</style>

+ 131 - 0
pages/wode/myInfo/myInfo.vue

@@ -0,0 +1,131 @@
+<template>
+<view class="section">
+
+  <view class="section_items">
+    <view class="section_cont">
+      <view class="section_cont_tel">
+        <text class="left">姓名:</text>
+        <text>{{member.name}}</text>
+      </view>
+    </view>
+  </view>
+  <view class="section_items">
+    <view class="section_cont">
+      <view class="section_cont_tel">
+        <text class="left">手机:</text>
+        <text>{{member.tel}}</text>
+
+      </view>
+    </view>
+  </view>
+  <!-- <view class="section_items">
+    <view class="section_cont">
+      <view class="section_cont_tel">
+        <text class='left'>身份证:</text>
+        <text>{{member.idCard}}</text>
+
+      </view>
+    </view>
+  </view> -->
+
+  <!-- <view class="section_items">
+    <view class="section_cont">
+      <view class="section_cont_tel">
+        <text class='left'>性别:</text>
+        <text wx:if="{{member.sex==1}}">男</text>
+        <text wx:elif="{{member.sex==2}}">女</text>
+        <text wx:else>未定义</text>
+      </view>
+    </view>
+  </view> -->
+</view>
+</template>
+
+<script>
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      member: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function () {
+    this.setData({
+      member: app.globalData.member
+    });
+  },
+  methods: {}
+};
+</script>
+<style>
+/* pages/myHome/myHome.wxss */
+
+.section {
+  /* margin: 10rpx; */
+  box-sizing: border-box;
+  background: #fff;
+  /* border-radius: 10rpx; */
+}
+
+.section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  border-bottom: 2rpx dashed #ddd;
+  position: relative;
+
+}
+.section_items:last-child {
+  border-bottom: none;
+}
+
+.section_items .section_cont view {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+  text-align: left;
+}
+.section_items .section_cont .left {
+  width: 130rpx;
+  text-align: left;
+  display: inline-block;
+}
+.section_items .section_cont .section_cont_sub {
+  font-size: 30rpx;
+  line-height: 50rpx;
+  color: #000;
+  margin-bottom: 10rpx;
+}
+
+.upload_bgImg{
+  vertical-align: top;
+  position: absolute;
+  top: 50rpx;
+  left: 50%;
+  transform: translate(-50%,0);
+}
+.img_content{
+  width:600rpx;
+  height: 376rpx;
+  margin-top: 20rpx;
+
+}
+.img_content image{
+  width: 100%;
+  height: 100%;
+  max-height: 1;
+  display: inline-block;
+}
+
+</style>

+ 125 - 0
pages/wode/news/news.vue

@@ -0,0 +1,125 @@
+<template>
+<view style="background-color: #FFFFFF;min-height: 100vh;">
+<view class="nav_section" v-if="list.length>0">
+  <view v-for="(item, index) in list" :key="index" class="nav_section_items">
+    <view class="section_cont">
+      <view class="section_cont_tel">
+        <text class="title">{{item.noticeTitle}}</text>
+      </view>
+      <view class="section_cont_tel">
+        <text class="content">{{item.noticeContent}}</text>
+      </view>
+      <view class="section_cont_tel">
+        <text class="date">{{item.createDate}}</text>
+      </view>
+  
+      
+    </view>
+  </view>
+</view>
+<view class="default" v-if="list==null || list.length==0">
+  <image src="/static/empty.png" mode="heightFix"></image>
+  <view>
+    <text>没有消息</text>
+  </view>
+</view>
+</view>
+</template>
+
+<script>
+var util = require("../../../utils/util.js"); //获取app实例
+//获取app实例
+var app = getApp();
+
+export default {
+  data() {
+    return {
+      list: null
+    };
+  },
+
+  components: {},
+  props: {},
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad: function (options) {
+    this.getNotice();
+  },
+  methods: {
+    //获取公告消息
+    getNotice: function () {
+      var that = this;
+      let params = {};
+      params['member_id'] = app.globalData.member.id; //发布目标渠道  1-app 2-小程序,
+
+      params['push_target'] = 2;
+      let operation = 'member/getNotices';
+      app.globalData.postRequest(params, operation, function (res) {
+        console.info("获取结果:" + res.data.result_msg); //获取成功
+
+        if (res.data.result_code == 1) {
+          let list = res.data.list;
+
+          for (let i in list) {
+            list[i].createDate = util.formatTime(list[i].createDate);
+          }
+
+          that.setData({
+            list: list
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style>
+/* pages/myHome/myHome.wxss */
+page{
+  overflow-y: scroll;
+}
+.nav_section {
+  width: 100%;
+}
+
+.nav_section_items {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  padding: 30rpx;
+  border-bottom: 2rpx solid #ddd;
+  position: relative;
+  background: #fff;
+}
+
+.nav_section_items:active {
+  background: #ddd;
+}
+
+.nav_section_items .section_cont .section_cont_sub {
+  font-size: 30rpx;
+  line-height: 50rpx;
+  margin-bottom: 10rpx;
+}
+.section_cont_tel .title{
+  font-size: 28rpx;
+  color: #1f1f1f;
+}
+.section_cont_tel{
+  line-height: 60rpx;
+
+}
+.section_cont_tel .content{
+
+  font-size: 32rpx;
+  color: #080808;
+}
+.section_cont_tel .date{
+
+  font-size: 24rpx;
+  color: #868686;
+}
+
+.default {
  text-align: center;
  position: fixed;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
}
.default text{
	color: #AAAAAA;
}

.default image {
  height: 250rpx;
  display: inline-block;
}
</style>

+ 55 - 0
pages/wode/password/password.vue

@@ -0,0 +1,55 @@
+<template>
+<view>
+<view class="form_group">
+    <text>固定开门密码:</text>
+    <view class="code"><input name="data_name" type="text" value="123456" disabled="disabled" class="placeholder_style">
+    </input>
+    </view>
+  </view>
+  <view class="submit_btn">
+    <button class="ar_btn" @tap="changePassword">修改密码</button>
+  </view>
+</view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+
+  components: {},
+  props: {},
+  methods: {
+    changePassword: function () {}
+  }
+};
+</script>
+<style>
+/* pages/wode/password/password.wxss */
+
+.form_group {
+  margin: 30rpx 20rpx;
+  line-height: 60rpx;
+  position: relative;
+}
+
+.form_group text {
+  font-size: 32rpx;
+  color: #333;
+}
+
+.form_group .code {
+  width: 60%;
+  margin: 20rpx auto;
+}
+
+.form_group input {
+  border: 1px solid #e2e2e2;
+  text-align: center;
+  height: 80rpx;
+  background: #f2f2f2;
+  border-radius: 10rpx;
+}
+
+</style>

+ 805 - 0
pages/wode/wode.vue

@@ -0,0 +1,805 @@
+<template>
+<view class="">
+	<view class="pageBg">
+		<view  class="header">
+			<DtCustomBar title="我的"></DtCustomBar>
+			<view @tap="tapToWhich('/pagesM/pages/mine_info')" style="display: flex;align-items: center;margin: 0 30upx;">
+				<view class="member_head_img">
+					<block v-if="isLogin">
+						<image v-if="userInfo.avatarUrl" :src="userInfo.avatarUrl" mode="scaleToFill"></image>
+						<button v-else class="avatar-wrap" open-type="getUserInfo" @getuserinfo="tapGetUserInfo" @tap.stop="() => false">
+							<!-- todo -->
+							<image style="background-color: #FFFFFF;" src="http://139.9.103.171:8888/group1/M00/00/01/iwlnq1_AYZqAb30pAAAQNvkj3Wk302.png"></image>
+						</button>
+					</block>
+					<!-- todo -->
+					<image v-else style="background-color: #FFFFFF;" src="http://139.9.103.171:8888/group1/M00/00/01/iwlnq1_AYZqAb30pAAAQNvkj3Wk302.png"></image>
+				</view>
+				<view v-if="isLogin" class="member_info">
+					<view class="member_name_box" style="margin-bottom: 20rpx;">
+						<view class="member_name">{{ userInfo.nickName }}</view>
+					</view>
+					<view class="member_phone_box" >
+						<view class="member_phone">19124812874</view>
+					</view>
+				</view>
+				<view v-else class="no_login"><button class="no_login_btn">游客(未登录)</button></view>
+				<view style="flex:1"></view>
+			</view>
+			<view style="display: flex;margin: 22upx 64upx 0;justify-content: space-between;">
+				<view  @tap="tapHeadMenu(0)" style="text-align: center;">
+					<view style="font-size: 28upx;color: #fff;">{{dataDetail.couponNum?dataDetail.couponNum:0}}</view>
+					<view style="font-size: 24upx;color: #fff;margin-top: 10upx;">我的优惠券</view>
+				</view>
+				<view  @tap="tapHeadMenu(1)" style="text-align: center;">
+					<view style="font-size: 28upx;color: #fff;">{{dataDetail.favoriteNum?dataDetail.favoriteNum:0}}</view>
+					<view style="font-size: 24upx;color: #fff;margin-top: 10upx;">收藏商品</view>
+				</view>
+				<view  @tap="tapHeadMenu(2)" style="text-align: center;">
+					<view style="font-size: 28upx;color: #fff;">{{dataDetail.browseNum?dataDetail.browseNum:0}}</view>
+					<view style="font-size: 24upx;color: #fff;margin-top: 10upx;">浏览记录</view>
+				</view>
+			</view>
+		</view>
+		<!-- todo -->
+		<view class="mine_order_statue">
+			<view class="cu-list grid col-5 no-border margin-top-sm" >
+				<view class="cu-item" @click="tapToMenu(item.index)" v-for="(item,index) in gridList" :key="index">
+					<view class="grid-icon ">
+						<image style="width: 56rpx;height: 56rpx;"  :src="item.icon"/>
+					</view>
+					<view class="cu-tag bg-orange badge" v-if="item.badge>0">{{item.badge}}</view>
+					<text style="font-size: 22rpx;font-family:Sans-serif">{{item.title}}</text>
+				</view>
+			</view>
+		</view>
+		<view class="item_list" >
+			<view class="item">
+				<text style="font-size: 32rpx;">个人设置</text>
+			</view>
+			<view class="item" v-for="(item, index) in mineItemList" :key="index" @tap="tapToMenu(item.index)">
+				<view class="item_content">
+					<image :src="item.itemIcon"></image>
+					<text>{{ item.itemName }}</text>
+				</view>
+				<view class="">
+					<text v-if="index==0" style="padding-right: 16rpx;font-size: 26rpx;" class="text-red">{{authStatus}}</text>
+					<image src="http://139.9.103.171:1888/img/image/arrow.png"></image>
+				</view>
+			</view>
+		</view>
+		<view class="item_list" >
+			<view class="item">
+				<text style="font-size: 32rpx;">系统设置</text>
+			</view>
+			<view class="item" v-for="(item, index) in systemItemList" :key="index" @tap="tapToMenu(item.index)">
+				<view class="item_content">
+					<image :src="item.itemIcon"></image>
+					<text>{{ item.itemName }}</text>
+				</view>
+				<view class="">
+					<image src="http://139.9.103.171:1888/img/image/arrow.png"></image>
+				</view>
+			</view>
+		</view>
+		<view class="bg-white" style="height: 80rpx;">
+			
+		</view>
+		<!-- 微信客服 -->
+		<DtService />
+	
+		<DtLogin ref="dialogLogin" @signIn="onSignIn" />
+	</view>
+</view>
+</template>
+
+<script>
+var app=getApp()
+import DtLogin from '../../comps/dt_login.vue';
+import DtService from '../../comps/dt_service.vue';
+import DtCustomBar from '../../comps/dt_custom_bar.vue'
+export default {
+	components: {
+		DtLogin,
+		DtService,
+		DtCustomBar
+	},
+	data() {
+		return {
+			//todo
+			gridList:[
+				{
+					icon:'../../static/index/blue/order.png',
+					title:"商城订单",
+					badge:0,
+					index:1
+				},
+				{
+					icon:'../../static/index/blue/cart.png',
+					title:"购物车",
+					badge:0,
+					index:2
+				},
+				{
+					icon:'../../static/index/blue/wuye.png',
+					title:"报修业务",
+					badge:0,
+					index:3
+				},
+				{
+					icon:'../../static/index/blue/contact.png',
+					title:"联系物业",
+					badge:0,
+					index:4
+				},
+				{
+					icon:'../../static/index/blue/msg.png',
+					title:"消息通知",
+					badge:0,
+					index:5
+				},
+				
+			],
+			isFirst:false,
+			//社区 begin
+			userInfo: null,
+			//微信用户信息
+			state: null,
+			anyHousePass: false,
+			//社区end
+			mineItemList: [
+				{
+					itemName: '住户认证',
+					itemIcon: '/static/index/blue/renzheng.png',
+					index:6
+				},
+				{
+					itemName: '通行人脸',
+					itemIcon: '/static/index/blue/face.png',
+					index:7
+				},
+				{
+					itemName: '身份信息',
+					itemIcon: '/static/index/blue/shenfen.png',
+					index:8
+				},
+				{
+					itemName: '收货地址',
+					itemIcon: '/static/index/blue/address.png',
+					index:9
+				},
+			],
+			systemItemList:[
+				{
+					itemName: '问题反馈',
+					itemIcon: '/static/index/blue/fankui.png',
+					index:10
+				},
+				{
+					itemName: '帮助中心',
+					itemIcon: '/static/index/blue/shuoming.png',
+					index:11
+				},
+				{
+					itemName: '设置',
+					itemIcon: '/static/index/blue/setting.png',
+					index:12
+				}
+			],
+			memberId: '',
+			dataDetail: {},
+			orderStatusNum: {},
+			userDetail: {},
+			isLogin: false,
+		};
+	},
+	onShow() {
+		if(this.isFirst){
+			this.isFirst=false
+		}else{
+			this.login()
+		}
+	},
+	computed: {
+		orderState() {
+			return this.$global.orderState;
+		},
+		//社区begin
+		authStatus:{
+			  get(){
+				  if(this.state==0 && this.anyHousePass==false){
+					  return "未认证"
+				  }else if(this.state==1&&this.anyHousePass==false){
+					  return "待审核"
+				  }else if(this.state==2 ||this.anyHousePass==true){
+					  return "已认证"
+				  }else{
+					  return "未注册"
+				  }
+			  }
+		},
+		//社区 end
+	},
+	methods: {
+		async tapGetUserInfo(e) {
+			return
+			console.log(158, e);
+			if (e.detail.errMsg == 'getUserInfo:ok') {
+				let userInfo = e.detail.userInfo;
+				let resp = await this.$api.updateIcon({
+					_isShowLoading: true,
+					userId: this.memberId,
+					avatar: userInfo.avatarUrl
+				});
+				this.userDetail.avatar = userInfo.avatarUrl;
+			}
+		},
+		showLogin() {
+			this.$refs.dialogLogin.show();
+		},
+		// 登录成功响应事件
+		onSignIn(resp) {
+			console.log(143, resp);
+			this.$util.refreshPage(['pages/home', 'pages/shop_car']);
+			this.onPullDownRefreshPage();
+		},
+		tapToWhich(aimUrl) {
+			return
+			if (!this.$auth.isAuth) {
+				this.showLogin();
+				return;
+			}
+			uni.navigateTo({
+				url: aimUrl
+			});
+		},
+		tapToOrder(state) {
+			return
+			if (!this.$auth.isAuth) {
+				this.showLogin();
+				return;
+			}
+			uni.navigateTo({
+				url: '/pagesM/pages/mine_order_list?state=' + state
+			});
+		},
+		onShareAppMessage: function(e) {
+			return {
+				path: '/pagesM/pages/home'
+			}
+		},
+		tapHeadMenu(index){
+			return
+			let url;
+			if(index==0){
+				url = '/pagesM/pages/coupon_list'
+			}else if(index==1){
+				url = '/pagesM/pages/mine_collection'
+			}else if(index==2){
+				url = '/pagesM/pages/browse_records'
+			}
+			uni.navigateTo({
+				url: url
+			}); 
+		},
+		tapToMenu(index) {
+			let url=''
+			switch (index) { 
+				case 1: 
+					//商城订单
+					url="/pagesM/pages/mine_order_list"
+					break; 
+				case 2:
+					//购物车
+					uni.showToast({
+						title:"暂未开发",
+						icon:"none"
+					})
+					break;
+				case 3: 
+					// 报修业务
+					// url="/pages/services/property/list/list"
+					uni.showToast({
+						title:"暂未开发",
+						icon:"none"
+					})
+					break;
+				case 4: 
+					// 联系物业
+					this.makePhoneCall("19124812874");
+					break;
+				case 5: 
+					//消息通知
+					this.buttonMethod(2)
+					break;
+				case 6: 
+					// 住户认证
+					this.buttonMethod(1)
+					break;
+				case 7:
+					// 通行人脸
+					url="/pages/uploadFace/uploadFace"
+					break;
+				case 8:
+					// 身份信息
+					uni.showToast({
+						title:"暂未开发",
+						icon:"none"
+					})
+					break;
+				case 9:
+					// 收货地址
+					url= '/pagesM/pages/address_list'
+					break;
+				case 10:
+					// 问题反馈
+					url="./feedback/feedback"
+					break;
+				case 11:
+					// 帮助中心
+					url="direction/direction"
+					break;
+				case 12:
+					// 设置
+					url="/pagesM/pages/mine_setting"
+					break;
+				default:
+					break;
+			}
+			if (url != '') {
+			  uni.navigateTo({
+			    url: url,
+			  });
+			}
+		},
+		async getMyBaseDatas() {
+			let resp = await this.$api.getMyBaseDatas({
+				_isReject: true,
+				_isPull: this.isPull,
+				memberId: this.memberId
+			});
+			console.log(resp)
+			this.$auth.getMineBase(resp);
+			this.dataDetail = resp;
+			this.orderStatusNum = resp.orderStatusNum || {};
+			this.userDetail = resp.user || {};
+		},
+		onLoadPage() {
+			this.isFirst=true
+			this.login()
+			// this.memberId = this.$auth.getMemberId();
+			// this.getMyBaseDatas();
+		},
+		
+		// 社区 begin
+		login(){
+			var that = this; //从全局变量中获取用户信息
+			if (app.globalData.userInfo == null) {
+			  uni.login({
+			    success: function () {
+			      uni.getUserInfo({
+			        success: function (res) {
+						console.log(res);
+					  that.isLogin=true
+			          app.globalData.userInfo = res.userInfo;
+			          that.setData({
+			            userInfo: res.userInfo
+			          });
+			        }
+			      });
+			    }
+			  });
+			} else {
+				that.isLogin=true
+			  that.setData({
+				userInfo: app.globalData.userInfo
+			  });
+			}
+			if (app.globalData.member) {
+			  that.setData({
+			    state: app.globalData.member.state,
+			    anyHousePass: app.globalData.anyHousePass
+			  });
+			}
+		},
+		//用户认证信息
+		buttonMethod: function (type) {
+			console.log("住户认证");
+		  var that = this; //会员认证状态:{ 0:未认证,1:待审审核,2:已认证 }
+		  var member = app.globalData.member;
+		  var anyHousePass = app.globalData.anyHousePass;
+		
+		  if (member == null) {
+		    //未注册
+			uni.navigateTo({
+				url:"../empty/empty"
+			})
+		    return;
+		  } else if (member.state == 0 && !anyHousePass) {
+		    //2未认证
+		    uni.navigateTo({
+		    	url:"../empty/empty?type=2"
+		    })
+		    return;
+		  } else if (member.state == 1 && !anyHousePass) {
+		    //待审核
+		    that.pending();
+		    return;
+		  } else if (member.state == 2 || anyHousePass) {
+		    //已认证
+		    if (type == 1) {
+		      uni.navigateTo({
+		        url: 'myInfo/myInfo'
+		      });
+		    } else if (type == 2) {
+		      uni.navigateTo({
+		        url: '/pages/wode/news/news'
+		      });
+		    }
+		  }
+		},
+		//提示用户身份注册
+		footaddmore: function () {
+		  uni.showModal({
+		    title: '提示',
+		    content: ' 请先完成注册',
+		    //cancelText:'去绑定',
+		    cancelText: '取消',
+		    confirmText: '去注册',
+		    success: function (res) {
+		      if (res.confirm) {
+		        console.log('用户点击了确认-去认证'); //跳转到认证页面
+		
+		        uni.navigateTo({
+		          url: '../register/register'
+		        });
+		      } else {//res.cancel
+		        //绑定界面--暂时不用
+		        // wx.navigateTo({
+		        //   url: '/pages/binding/binding',
+		        // })
+		      }
+		    }
+		  });
+		},
+		//用户信息待审核中
+		pending: function () {
+		  let that = this;
+		  var openid = uni.getStorageSync("openid");
+		  let params = {};
+		  params['openid'] = openid;
+		  let operation = 'miniprogram/getMemberByOpenid';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //获取成功
+		    if (res.data.result_code == 1) {
+		      let member = res.data.member; //待审核
+		
+		      if (member.state == 1 && !res.data.anyHousePass) {
+		        app.globalData.oneFailHint('亲,你的信息正在审核,请耐心等待');
+		      } else if (member.state == 2) {
+		        app.globalData.oneFailHint('亲,你的信息已审核通过', function () {
+		          that.setData({
+		            state: member.state
+		          });
+		        });
+		      }
+		
+		      app.globalData.member = member;
+		      app.globalData.anyHousePass = res.data.anyHousePass;
+		    } else {
+		      app.globalData.oneFailHint(res.data.result_msg);
+		    }
+		  });
+		},
+		// 社区 end
+	},
+	onLoad() {
+		wx.showShareMenu({
+		  withShareTicket: true
+		})
+	},
+	onReady() {
+		// if (!this.$auth.isAuth) {
+		// 	this.showLogin();
+		// 	return;
+		// } else {
+		// 	this.$refs.dialogLogin.hide();
+		// }
+	},
+	onShow() {
+		this.onShowPage();
+	},
+	onPullDownRefresh() {
+		this.onPullDownRefreshPage();
+	}
+};
+</script>
+<style lang="scss" scoped>
+	//todo
+	.pageBg {
+		background-color: #FFFFFF;
+	}
+button::after {
+	  border: none;
+	}
+.header {
+	// border-bottom-left-radius: 20rpx;
+	border-bottom-right-radius: 60rpx;
+	//todo
+	background-image: url(http://139.9.103.171:1888/miniofile/app/bg.png);
+	height: 480upx;
+	background-repeat: no-repeat;
+	background-size: 100% 100%;
+	.member_head_img {
+		margin-right: 30upx;
+		image {
+			//todo
+			width: 110upx;
+			height:110upx;
+			border-radius: 59rpx;
+		}
+
+		.avatar-wrap {
+			display: inline-flex;
+			border: 0;
+			background-color: transparent;
+		}
+	}
+
+	.no_login {
+		display: flex;
+		flex-direction: column;
+		.no_login_btn {
+			border-radius: 25px;
+			//todo
+			font-size: 32upx;
+			color: #fff;
+			width: fit-content;
+			padding: 0 15upx;
+			height: 60upx;
+			line-height: 60upx;
+			background: transparent;
+		}
+	}
+
+	.member_info {
+		display: flex;
+		flex-direction: column;
+		.member_name_box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			.member_name { 
+				font-size: 40upx;
+				color: #fff;
+				font-weight: bold;
+			}
+			.member_level {
+				background: #ffc600;
+				color: #fff;
+				font-size: 22upx;
+				border-radius: 4upx;
+				padding: 5upx 10upx;
+				margin-left: 10upx;
+			}
+		}
+
+		.member_phone_box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			.member_phone { 
+				font-size: 24upx;
+				color: #FFFFFF;
+			}
+
+			image {
+				width: 19upx;
+				height: 19upx;
+				padding: 20upx;
+			}
+		}
+	}
+
+	.member_benefits {
+		background: #fff;
+		width: 180upx;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		text-align: center;
+		border-radius: 27upx 0px 0px 27upx;
+		height: 54upx;
+		text-align: center;
+		position: absolute;
+		right: 0;
+
+		image {
+			width: 26upx;
+			height: 23upx;
+			padding: 0 10upx 0 30upx;
+		}
+
+		.member_benefits_text {
+			font-size: 24upx;
+			color: $dt-color-primary;
+			letter-spacing: 2upx;
+		}
+	}
+
+	button::after {
+		border: none;
+	}
+}
+
+.coupon_point {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	height: 110upx;
+	background: #fff;
+	justify-content: space-around;
+
+	.item {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		width: 50%;
+
+		.item_box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			letter-spacing: 2upx;
+
+			.item_content {
+				color: $dt-color-primary;
+				font-size: 34upx;
+			}
+
+			.item_unit {
+				color: $dt-color-primary;
+				font-size: 22upx;
+				margin-top: 6upx;
+			}
+		}
+
+		.item_text {
+			color: #333333;
+			font-size: 22upx;
+		}
+	}
+
+	.line {
+		width: 1upx;
+		height: 50upx;
+		background: #e5e5e5;
+	}
+}
+
+.mine_order_statue {
+	//todo
+	box-shadow: 0 10rpx #e7f1fd ;
+	margin: -100upx 20upx 0;
+	background: #fff;
+	padding: 10upx 20upx;
+	border-radius: 20rpx;
+	.order_wrap {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		box-sizing: border-box;
+		.mine_order_text {
+			font-size: 28upx;
+			font-weight: bold;
+			color: #333333;
+		}
+
+		.jump_all_order {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+
+			text {
+				color: #999999;
+				font-size: 22upx;
+				margin-right: 10upx;
+			}
+
+			image {
+				width: 10upx;
+				height: 18upx;
+			}
+		}
+	}
+
+	.order_statue_list {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		.order_statue_item {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			position: relative;
+			margin-top: 32upx;
+			image {
+				width: 40upx;
+				height: 40upx;
+			}
+
+			text {
+				font-size: 24rpx;
+				color: #333333;
+				letter-spacing: 1upx;
+				margin-top: 10upx;
+			}
+
+			.tip_count {
+				position: absolute;
+				right: 0upx;
+				top: -6rpx;
+				width: 24upx;
+				height: 24upx;
+				border-radius: 50%;
+				background-color: #ff3b30;
+				color: #fff;
+				font-size: 18upx;
+				text-align: center;
+				line-height: 24upx;
+			}
+		}
+	}
+}
+
+.item_list {
+	display: flex;
+	flex-direction: column;
+	background: #fff;
+	margin-top: 20upx;
+    margin-left: 20rpx;
+	margin-right: 20rpx;
+	border-radius: 20rpx;
+	.item {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		padding: 0 30upx;
+		height: 90upx;
+		border-bottom: 1upx solid #f1f1f1;
+
+		.item_content {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+
+			image {
+				width: 42upx;
+				height: 42upx;
+			}
+
+			text {
+				font-size: 28upx;
+				color: #333333;
+				margin-left: 20upx;
+			}
+		}
+
+		image {
+			width: 10upx;
+			height: 18upx;
+		}
+	}
+	
+	.item:first-child{
+		border: none;
+	}
+
+	.item:last-child {
+		border: none;
+	}
+}
+</style>

+ 735 - 0
pages/wode/wode2.vue

@@ -0,0 +1,735 @@
+<template>
+<view class="">
+	<view class="pageBg">
+		<view  class="header">
+			<DtCustomBar title="我的"></DtCustomBar>
+			<view @tap="tapToWhich('/pagesM/pages/mine_info')" style="display: flex;align-items: center;margin: 0 30upx;">
+				<view class="member_head_img">
+					<block v-if="isLogin">
+						<image v-if="userDetail.avatar" :src="userDetail.avatar"></image>
+						<button v-else class="avatar-wrap" open-type="getUserInfo" @getuserinfo="tapGetUserInfo" @tap.stop="() => false">
+							<image src="http://139.9.103.171:1888/img/image/avatar.png"></image>
+						</button>
+					</block>
+					<image v-else src="http://139.9.103.171:1888/img/image/avatar.png"></image>
+				</view>
+				<view v-if="isLogin" class="member_info">
+					<view class="member_name_box">
+						<view class="member_name">{{ userDetail.username }}</view>
+					</view>
+					<view class="member_name_box">
+						<view class="member_mobile">{{shopPhone}}</view>
+					</view>
+				</view>
+				<view v-else class="no_login"><button class="no_login_btn">游客(未登录)</button></view>
+				<view style="flex:1"></view>
+				<image src="/static/test/item_setting_icon.png" mode="aspectFit" @tap.stop="tapOther(1)" style="width: 56upx;height: 56upx;"></image>
+			</view>
+			<view style="display: flex;margin: 22upx 64upx 0;justify-content: space-between;">
+				<view  @tap="tapHeadMenu(0)" style="text-align: center;">
+					<view style="font-size: 28upx;color: #fff;">{{dataDetail.couponNum?dataDetail.couponNum:0}}</view>
+					<view style="font-size: 24upx;color: #fff;margin-top: 10upx;">我的优惠券</view>
+				</view>
+				<view  @tap="tapHeadMenu(1)" style="text-align: center;">
+					<view style="font-size: 28upx;color: #fff;">{{dataDetail.favoriteNum?dataDetail.favoriteNum:0}}</view>
+					<view style="font-size: 24upx;color: #fff;margin-top: 10upx;">收藏商品</view>
+				</view>
+				<view  @tap="tapHeadMenu(2)" style="text-align: center;">
+					<view style="font-size: 28upx;color: #fff;">{{dataDetail.browseNum?dataDetail.browseNum:0}}</view>
+					<view style="font-size: 24upx;color: #fff;margin-top: 10upx;">浏览记录</view>
+				</view>
+			</view>
+		</view>
+		<view class="mine_order_statue">
+			<view class="order_wrap">
+				<view class="mine_order_text">我的订单</view>
+				<view @tap="tapToOrder(0)" class="jump_all_order">
+					<text style="color:#C1C1C1;font-size: 24upx;">查看全部</text>
+					<image src="http://139.9.103.171:1888/img/image/arrow.png"></image>
+				</view>
+			</view>
+			<view class="order_statue_list">
+				<view class="order_statue_item" v-for="(item, index) in orderStateList" :key="index" @tap="tapToOrder(item.state)">
+					<image :src="item.icon" mode="aspectFit"></image>
+					<text>{{ item.statueName }}</text>
+					<!-- 待付款数量 -->
+					<view v-if="index == 0 && orderStatusNum.pendingPayment > 0" class="tip_count">{{ orderStatusNum.pendingPayment }}</view>
+					<!-- 待发货数量 -->
+					<view v-if="index == 1 && orderStatusNum.pendingShipment > 0" class="tip_count">{{ orderStatusNum.pendingShipment }}</view>
+					<!-- 待收货数量 -->
+					<view v-if="index == 2 && orderStatusNum.shipped > 0" class="tip_count">{{ orderStatusNum.shipped }}</view>
+					<!-- 待评论数量 -->
+					<view v-if="index == 3 && orderStatusNum.pendingReview > 0" class="tip_count">{{ orderStatusNum.pendingReview }}</view>
+					<!-- 售后数量 -->
+					<view v-if="index == 4 && orderStatusNum.afterSale > 0" class="tip_count">{{ orderStatusNum.afterSale }}</view>
+				</view>
+			</view>
+		</view>
+		<view class="item_list">
+			<view class="item" v-for="(item, index) in mineItemList" :key="index" @tap="tapToMenu(item.index)">
+				<view class="item_content">
+					<image :src="item.itemIcon"></image>
+					<text>{{ item.itemName }}</text>
+				</view>
+				<view class="">
+					<text v-if="item.index==0" style="padding-right: 16rpx;color: #D43A39;font-size: 26rpx;">{{authStatus}}</text>
+					<image src="http://139.9.103.171:1888/img/image/arrow.png"></image>
+				</view>
+			</view>
+		</view>
+		<!-- 微信客服 -->
+		<DtService />
+	
+		<DtLogin ref="dialogLogin" @signIn="onSignIn" />
+	</view>
+</view>
+</template>
+
+<script>
+var app=getApp()
+import DtLogin from '../../comps/dt_login.vue';
+import DtService from '../../comps/dt_service.vue';
+import DtCustomBar from '../../comps/dt_custom_bar.vue'
+export default {
+	components: {
+		DtLogin,
+		DtService,
+		DtCustomBar
+	},
+	data() {
+		return {
+			isFirst:false,
+			//社区 begin
+			state: null,
+			anyHousePass: false,
+			//社区end
+			orderStateList: [
+				{
+					statueName: '待付款',
+					icon: 'http://139.9.103.171:1888/img/image/wait_pay.png',
+					count: 1,
+					state: 1
+				},
+				{
+					statueName: '待发货',
+					icon: 'http://139.9.103.171:1888/img/image/wait_ship.png',
+					count: 2,
+					state: 2
+				},
+				{
+					statueName: '待收货',
+					icon: 'http://139.9.103.171:1888/img/image/wait_receipt.png',
+					count: 2,
+					state: 3
+				},
+				{
+					statueName: '待评价',
+					icon: 'http://139.9.103.171:1888/img/image/wait_comment.png',
+					count: 2,
+					state: 5
+				},
+				{
+					statueName: '退款/售后',
+					icon: 'http://139.9.103.171:1888/img/image/wait_refund.png',
+					count: 2,
+					state: 7
+				}
+			],
+			mineItemList: [
+				{
+					itemName: '住户认证',
+					itemIcon: '/static/icon/renzheng.png',
+					index:0
+				},
+				{
+					itemName: '我的消息',
+					itemIcon: '/static/icon/msg.png',
+					index:1
+				},
+				{
+					itemName: '收货地址',
+					itemIcon: '/static/icon/address.png',
+					index:2
+				},
+				{
+					itemName: '问题反馈',
+					itemIcon: '/static/icon/fankui.png',
+					index:3
+				},
+				{
+					itemName: '客服中心',
+					itemIcon: '/static/icon/kefu.png',
+					index:4
+				},
+				{
+					itemName: '使用说明',
+					itemIcon: '/static/icon/shuoming.png',
+					index:5
+				},
+				
+
+			],
+			//商城绑定的手机号
+			shopPhone:'',
+			memberId: '',
+			dataDetail: {},
+			orderStatusNum: {},
+			userDetail: {},
+			isLogin: false,
+		};
+	},
+	computed: {
+		orderState() {
+			return this.$global.orderState;
+		},
+		//社区begin
+		authStatus:{
+			  get(){
+				  if(this.state==0 && this.anyHousePass==false){
+					  return "未认证"
+				  }else if(this.state==1&&this.anyHousePass==false){
+					  return "待审核"
+				  }else if(this.state==2 ||this.anyHousePass==true){
+					  return "已认证"
+				  }else{
+					  return "未注册"
+				  }
+			  }
+		},
+		//社区 end
+	},
+	methods: {
+		async tapGetUserInfo(e) {
+			console.log(158, e);
+			if (e.detail.errMsg == 'getUserInfo:ok') {
+				let userInfo = e.detail.userInfo;
+				let resp = await this.$api.updateIcon({
+					_isShowLoading: true,
+					userId: this.memberId,
+					avatar: userInfo.avatarUrl
+				});
+				this.userDetail.avatar = userInfo.avatarUrl;
+			}
+		},
+		showLogin() {
+			this.$refs.dialogLogin.show();
+		},
+		// 登录成功响应事件
+		onSignIn(resp) {
+			this.shopPhone=this.$auth.getMineBase().user.mobile || ''
+			console.log(143, resp);
+			this.onPullDownRefreshPage();
+		},
+		tapToWhich(aimUrl) {
+			if (!this.$auth.isAuth) {
+				this.showLogin();
+				return;
+			}
+			uni.navigateTo({
+				url: aimUrl
+			});
+		},
+		tapToOrder(state) {
+			if (!this.$auth.isAuth) {
+				this.showLogin();
+				return;
+			}
+			uni.navigateTo({
+				url: '/pagesM/pages/mine_order_list?state=' + state
+			});
+		},
+		tapOther(key){
+			if(key==1){
+				uni.navigateTo({
+					url: '/pagesM/pages/mine_setting'
+				});
+			}
+		},
+		onShareAppMessage: function(e) {
+			return {
+				path: 'pages/index/index'
+			}
+		},
+		tapHeadMenu(index){
+			let url;
+			if(index==0){
+				url = '/pagesM/pages/coupon_list'
+			}else if(index==1){
+				url = '/pagesM/pages/mine_collection'
+			}else if(index==2){
+				url = '/pagesM/pages/browse_records'
+			}
+			uni.navigateTo({
+				url: url
+			}); 
+		},
+		tapToMenu(idx) {
+			if (idx==0) {
+				//住户认证
+				this.buttonMethod(1)
+				return
+			}else if (idx==1) {
+				//我的消息
+				this.buttonMethod(2)
+				return
+			}else if (idx==5) {
+				//使用教程
+				this.buttonMethod(3)
+				return
+			}
+			if (!this.$auth.isAuth) {
+				this.showLogin();
+				return;
+			}
+			switch (idx) { 
+				case 2: // 收货地址
+					uni.navigateTo({
+						url: '/pagesM/pages/address_list'
+					});
+					break;
+				case 3: // 问题反馈
+					uni.navigateTo({
+						url:"./feedback/feedback"
+					})
+					break;
+				case 4: // 客服中心
+					let phone=this.dataDetail.serviceTel
+					console.log(phone);
+					this.makePhoneCall(phone);
+					break;
+				default:
+					break;
+			}
+		},
+		async getMyBaseDatas() {
+			let resp = await this.$api.getMyBaseDatas({
+				_isReject: true,
+				_isPull: this.isPull,
+				memberId: this.memberId
+			});
+			this.shopPhone=resp.user.mobile
+			console.log(this.shopPhone);
+			this.$auth.getMineBase(resp);
+			this.dataDetail = resp;
+			this.orderStatusNum = resp.orderStatusNum || {};
+			this.userDetail = resp.user || {};
+		},
+		onLoadPage() {
+			wx.hideShareMenu();
+			this.communityInitData()
+			this.isLogin = this.$auth.isAuth;
+			this.memberId = this.$auth.getMemberId();
+			this.getMyBaseDatas();
+		},
+		// 社区 begin
+		communityInitData(){
+			var that = this; //从全局变量中获取用户信息
+			if (app.globalData.member) {
+			  that.setData({
+			    state: app.globalData.member.state,
+			    anyHousePass: app.globalData.anyHousePass
+			  });
+			}
+		},
+		//用户认证信息
+		buttonMethod: function (type) {
+		  if (type == 3) {
+		    uni.navigateTo({
+		      url: 'direction/direction'
+		    });
+		    return;
+		  }
+		  var that = this; //会员认证状态:{ 0:未认证,1:待审审核,2:已认证 }
+		  var member = app.globalData.member;
+		  var anyHousePass = app.globalData.anyHousePass;
+		
+		  if (member == null) {
+		    //未注册
+			uni.navigateTo({
+				url:"../empty/empty"
+			})
+		    return;
+		  } else if (member.state == 0 && !anyHousePass) {
+		    //2未认证
+		    uni.navigateTo({
+		    	url:"../empty/empty?type=2"
+		    })
+		    return;
+		  } else if (member.state == 1 && !anyHousePass) {
+		    //待审核
+		    that.pending();
+		    return;
+		  } else if (member.state == 2 || anyHousePass) {
+		    //已认证
+		    if (type == 1) {
+		      uni.navigateTo({
+		        url: 'myInfo/myInfo'
+		      });
+		    } else if (type == 2) {
+		      uni.navigateTo({
+		        url: '/pages/wode/news/news'
+		      });
+		    }
+		  }
+		},
+		//提示用户身份注册
+		footaddmore: function () {
+		  uni.showModal({
+		    title: '提示',
+		    content: ' 请先完成注册',
+		    //cancelText:'去绑定',
+		    cancelText: '取消',
+		    confirmText: '去注册',
+		    success: function (res) {
+		      if (res.confirm) {
+		        console.log('用户点击了确认-去认证'); //跳转到认证页面
+		
+		        uni.navigateTo({
+		          url: '../register/register'
+		        });
+		      } else {//res.cancel
+		        //绑定界面--暂时不用
+		        // wx.navigateTo({
+		        //   url: '/pages/binding/binding',
+		        // })
+		      }
+		    }
+		  });
+		},
+		//用户信息待审核中
+		pending: function () {
+		  let that = this;
+		  var openid = uni.getStorageSync("openid");
+		  let params = {};
+		  params['openid'] = openid;
+		  let operation = 'miniprogram/getMemberByOpenid';
+		  app.globalData.postRequest(params, operation, function (res) {
+		    //获取成功
+		    if (res.data.result_code == 1) {
+		      let member = res.data.member; //待审核
+		      if (member.state == 1 && !res.data.anyHousePass) {
+		        app.globalData.oneFailHint('亲,你的信息正在审核,请耐心等待');
+		      } else if (member.state == 2) {
+		        app.globalData.oneFailHint('亲,你的信息已审核通过', function () {
+		          that.setData({
+		            state: member.state
+		          });
+		        });
+		      }
+		
+		      app.globalData.member = member;
+		      app.globalData.anyHousePass = res.data.anyHousePass;
+		    } else {
+		      app.globalData.oneFailHint(res.data.result_msg);
+		    }
+		  });
+		},
+		// 社区 end
+	},
+	onLoad() {
+		this.isFirst=true
+	},
+	onReady() {
+		if (!this.$auth.isAuth) {
+			this.showLogin();
+			return;
+		} else {
+			this.$refs.dialogLogin.hide();
+		}
+	},
+	onShow() {
+		if (this.isFirst) {
+			this.isFirst=false
+		}else{
+			this.onShowPage();
+			this.onLoadPage()
+		}
+	},
+	onPullDownRefresh() {
+		this.onPullDownRefreshPage();
+	}
+};
+</script>
+<style lang="scss" scoped>
+	.pageBg {
+		background-color: #F6F4F5;
+	}
+	button::after {
+		  border: none;
+		}
+.header {
+	background-image: url(http://139.9.103.171:1888/img/image/mine_head_bg.png);
+	height: 500upx;
+	background-repeat: no-repeat;
+	background-size: 100% 100%;
+	.member_head_img {
+		margin-right: 30upx;
+		image {
+			width: 110upx;
+			height: 110upx;
+			border-radius: 59rpx;
+		}
+
+		.avatar-wrap {
+			display: inline-flex;
+			border: 0;
+			background-color: transparent;
+		}
+	}
+
+	.no_login {
+		display: flex;
+		flex-direction: column;
+		.no_login_btn {
+			border-radius: 25px;
+			font-size: 26upx;
+			color: #fff;
+			width: fit-content;
+			padding: 0 15upx;
+			height: 60upx;
+			line-height: 60upx;
+			background: transparent;
+		}
+	}
+
+	.member_info {
+		display: flex;
+		flex-direction: column;
+		.member_name_box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			.member_name {
+				padding-bottom: 20rpx;
+				font-size: 32upx;
+				color: #fff;
+				font-weight: bold;
+			}
+			.member_mobile {
+				padding-bottom: 10rpx;
+				font-size: 26upx;
+				color: #fff;
+				font-weight: bold;
+			}
+			.member_level {
+				background: #ffc600;
+				color: #fff;
+				font-size: 22upx;
+				border-radius: 4upx;
+				padding: 5upx 10upx;
+				margin-left: 10upx;
+			}
+		}
+
+		.member_phone_box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			.member_phone { 
+				margin-top: -20rpx;
+				font-size: 24upx;
+				color: #999999;
+			}
+
+			image {
+				width: 19upx;
+				height: 19upx;
+				padding: 20upx;
+			}
+		}
+	}
+
+	.member_benefits {
+		background: #fff;
+		width: 180upx;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		text-align: center;
+		border-radius: 27upx 0px 0px 27upx;
+		height: 54upx;
+		text-align: center;
+		position: absolute;
+		right: 0;
+
+		image {
+			width: 26upx;
+			height: 23upx;
+			padding: 0 10upx 0 30upx;
+		}
+
+		.member_benefits_text {
+			font-size: 24upx;
+			color: $dt-color-primary;
+			letter-spacing: 2upx;
+		}
+	}
+
+	button::after {
+		border: none;
+	}
+}
+
+.coupon_point {
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	height: 110upx;
+	background: #fff;
+	justify-content: space-around;
+
+	.item {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		width: 50%;
+
+		.item_box {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			letter-spacing: 2upx;
+
+			.item_content {
+				color: $dt-color-primary;
+				font-size: 34upx;
+			}
+
+			.item_unit {
+				color: $dt-color-primary;
+				font-size: 22upx;
+				margin-top: 6upx;
+			}
+		}
+
+		.item_text {
+			color: #333333;
+			font-size: 22upx;
+		}
+	}
+
+	.line {
+		width: 1upx;
+		height: 50upx;
+		background: #e5e5e5;
+	}
+}
+
+.mine_order_statue {
+	margin: -100upx 20upx 0;
+	background: #fff;
+	padding: 30upx 40upx;
+	border-radius: 20rpx;
+	.order_wrap {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		box-sizing: border-box;
+		.mine_order_text {
+			font-size: 28upx;
+			font-weight: bold;
+			color: #333333;
+		}
+
+		.jump_all_order {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+
+			text {
+				color: #999999;
+				font-size: 22upx;
+				margin-right: 10upx;
+			}
+
+			image {
+				width: 10upx;
+				height: 18upx;
+			}
+		}
+	}
+
+	.order_statue_list {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		.order_statue_item {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			position: relative;
+			margin-top: 32upx;
+			image {
+				width: 40upx;
+				height: 40upx;
+			}
+
+			text {
+				font-size: 24rpx;
+				color: #333333;
+				letter-spacing: 1upx;
+				margin-top: 10upx;
+			}
+
+			.tip_count {
+				position: absolute;
+				right: 0upx;
+				top: -6rpx;
+				width: 24upx;
+				height: 24upx;
+				border-radius: 50%;
+				background-color: #ff3b30;
+				color: #fff;
+				font-size: 18upx;
+				text-align: center;
+				line-height: 24upx;
+			}
+		}
+	}
+}
+
+.item_list {
+	display: flex;
+	flex-direction: column;
+	background: #fff;
+	margin: 20rpx;
+	border-radius: 20rpx;
+	.item {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+		padding: 0 30upx;
+		height: 90upx;
+		border-bottom: 1upx solid #e5e5e5;
+
+		.item_content {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+
+			image {
+				width: 38upx;
+				height: 38upx;
+			}
+
+			text {
+				font-size: 28upx;
+				color: #333333;
+				margin-left: 20upx;
+			}
+		}
+
+		image {
+			width: 10upx;
+			height: 18upx;
+		}
+	}
+
+	.item:last-child {
+		border: none;
+	}
+}
+</style>

+ 559 - 0
pagesM/comps/canvas/index.vue

@@ -0,0 +1,559 @@
+<template>
+  <view class="container">
+    <canvas canvas-id="canvasid" class="dt-canvas" :class="debug ? 'debug' : 'pro'" :style="'width:'+pxWidth+'px;height:'+pxHeight+'px;'"></canvas>
+  </view>
+</template>
+<script>
+
+export default {
+  data() {
+    return {
+      ctx: {},
+      factor: 0,
+      pxHeight: 0,
+      pxWidth: 0,
+    };
+  },
+
+  methods: {
+    /**
+      * 计算画布的高度
+      * @param {*} config
+      */
+    getHeight(config) {
+      const getTextHeight = text => {
+        let fontHeight = text.lineHeight || text.fontSize;
+        let height = 0;
+        if (text.baseLine === "top") {
+          height = fontHeight;
+        } else if (text.baseLine === "middle") {
+          height = fontHeight / 2;
+        } else {
+          height = 0;
+        }
+        return height;
+      };
+      const heightArr = [];
+      (config.blocks || []).forEach(item => {
+        heightArr.push(item.y + item.height);
+      });
+      (config.texts || []).forEach(item => {
+        let height;
+        if (Object.prototype.toString.call(item.text) === "[object Array]") {
+          item.text.forEach(i => {
+            height = getTextHeight({ ...i, baseLine: item.baseLine });
+            heightArr.push(item.y + height);
+          });
+        } else {
+          height = getTextHeight(item);
+          heightArr.push(item.y + height);
+        }
+      });
+      (config.images || []).forEach(item => {
+        heightArr.push(item.y + item.height);
+      });
+      (config.lines || []).forEach(item => {
+        heightArr.push(item.startY);
+        heightArr.push(item.endY);
+      });
+      const sortRes = heightArr.sort((a, b) => b - a);
+      let canvasHeight = 0;
+      if (sortRes.length > 0) {
+        canvasHeight = sortRes[0];
+      }
+      if (config.height < canvasHeight || !config.height) {
+        return canvasHeight;
+      } else {
+        return config.height;
+      }
+    },
+    create(config) {
+      this.ctx = uni.createCanvasContext("canvasid", this);
+      const height = this.getHeight(config);
+      this.initCanvas(config.width, height, config.debug)
+        .then(() => {
+          // 设置画布底色
+          if (config.backgroundColor) {
+            this.ctx.save();
+            this.ctx.setFillStyle(config.backgroundColor);
+            this.ctx.fillRect(
+              0,
+              0,
+              this.toPx(config.width),
+              this.toPx(height)
+            );
+            this.ctx.restore();
+          }
+          const { texts = [], images = [], blocks = [], lines = [] } = config;
+          const queue = this.drawArr
+            .concat(
+              texts.map(item => {
+                item.type = "text";
+                item.zIndex = item.zIndex || 0;
+                return item;
+              })
+            )
+            .concat(
+              blocks.map(item => {
+                item.type = "block";
+                item.zIndex = item.zIndex || 0;
+                return item;
+              })
+            )
+            .concat(
+              lines.map(item => {
+                item.type = "line";
+                item.zIndex = item.zIndex || 0;
+                return item;
+              })
+            );
+          // 按照顺序排序
+          queue.sort((a, b) => a.zIndex - b.zIndex);
+
+          queue.forEach(item => {
+            if (item.type === "image") {
+              this.drawImage(item);
+            } else if (item.type === "text") {
+              this.drawText(item);
+            } else if (item.type === "block") {
+              this.drawBlock(item);
+            } else if (item.type === "line") {
+              this.drawLine(item);
+            }
+          });
+
+          const res = uni.getSystemInfoSync();
+          const platform = res.platform;
+          let time = 0;
+          if (platform === "android") {
+            // 在安卓平台,经测试发现如果海报过于复杂在转换时需要做延时,要不然样式会错乱
+            time = 300;
+          }
+          this.ctx.draw(false, () => {
+            setTimeout(() => {
+              uni.canvasToTempFilePath(
+                {
+                  canvasId: "canvasid",
+                  success: res => {
+                    this.$emit("success", res.tempFilePath);
+                  },
+                  fail: err => {
+                    this.$emit("fail", err);
+                  }
+                },
+                this
+              );
+            }, time);
+          });
+        })
+        .catch(err => {
+          uni.showToast({ icon: "none", title: err.errMsg || "生成失败" });
+          console.error(err);
+        });
+    },
+
+    /**  
+     * main
+     -----------------------*/
+    /**
+     * 渲染块
+     * @param {Object} params
+     */
+    drawBlock({ text, width = 0, height, x, y, paddingLeft = 0, paddingRight = 0, borderWidth, backgroundColor, borderColor, borderRadius = 0, opacity = 1 }) {
+      // 判断是否块内有文字
+      let blockWidth = 0; // 块的宽度
+      let textX = 0;
+      let textY = 0;
+      if (typeof text !== 'undefined') {
+        // 如果有文字并且块的宽度小于文字宽度,块的宽度为 文字的宽度 + 内边距
+        const textWidth = this._getTextWidth(typeof text.text === 'string' ? text : text.text);
+        blockWidth = textWidth > width ? textWidth : width;
+        blockWidth += paddingLeft + paddingLeft;
+        x=x-blockWidth/2
+        const { textAlign = 'left', text: textCon } = text;
+        textY = height/2+ y; // 文字的y轴坐标在块中线
+        if (textAlign === 'left') {
+          // 如果是右对齐,那x轴在块的最左边
+          textX = x + paddingLeft;
+        } else if (textAlign === 'center') {
+          textX = blockWidth / 2 + x;
+        } else {
+          textX = x + blockWidth - paddingRight;
+        }
+      } else {
+        blockWidth = width;
+      }
+
+      if (backgroundColor) {
+        // 画面
+        this.ctx.save();
+        this.ctx.setGlobalAlpha(opacity);
+        this.ctx.setFillStyle(backgroundColor);
+        if (borderRadius > 0) {
+          // 画圆角矩形
+          this._drawRadiusRect(x, y, blockWidth, height, borderRadius);
+          this.ctx.fill();
+        } else {
+          this.ctx.fillRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height));
+        }
+        this.ctx.restore();
+      }
+      if (borderWidth) {
+        // 画线
+        this.ctx.save();
+        this.ctx.setGlobalAlpha(opacity);
+        this.ctx.setStrokeStyle(borderColor);
+        this.ctx.setLineWidth(this.toPx(borderWidth));
+        if (borderRadius > 0) {
+          // 画圆角矩形边框
+          this._drawRadiusRect(x, y, blockWidth, height, borderRadius);
+          this.ctx.stroke();
+        } else {
+          this.ctx.strokeRect(this.toPx(x), this.toPx(y), this.toPx(blockWidth), this.toPx(height));
+        }
+        this.ctx.restore();
+      }
+
+      if (text) {
+        this.drawText(Object.assign(text, { x: textX, y: textY }))
+      }
+    },
+
+    /**
+     * 渲染文字
+     * @param {Object} params
+     */
+    drawText(params) {
+      const { x, y, fontSize, color, baseLine, textAlign, text, opacity = 1, width, lineNum, lineHeight } = params;
+      if (Object.prototype.toString.call(text) === '[object Array]') {
+        let preText = { x, y, baseLine };
+        text.forEach(item => {
+          preText.x += item.marginLeft || 0;
+          const textWidth = this._drawSingleText(Object.assign(item, {
+            ...preText,
+          }));
+          preText.x += textWidth + (item.marginRight || 0); // 下一段字的x轴为上一段字x + 上一段字宽度
+        })
+      } else {
+        this._drawSingleText(params);
+      }
+    },
+
+    /**
+     * 渲染图片
+     */
+    drawImage(data) {
+      const { imgPath, x, y, w, h, sx, sy, sw, sh, borderRadius = 0, borderWidth = 0, borderColor } = data;
+      this.ctx.save();
+      if (borderRadius > 0) {
+        this.ctx.setFillStyle("#FFF");
+        this._drawRadiusRect(x, y, w, h, borderRadius);
+        this.ctx.fill();
+        this.ctx.clip();
+        this.ctx.drawImage(imgPath, this.toPx(sx), this.toPx(sy), this.toPx(sw), this.toPx(sh), this.toPx(x), this.toPx(y), this.toPx(w), this.toPx(h));
+        if (borderWidth > 0) {
+          this.ctx.setStrokeStyle(borderColor);
+          this.ctx.setLineWidth(this.toPx(borderWidth));
+          this.ctx.stroke();
+        }
+      } else {
+        this.ctx.drawImage(imgPath, this.toPx(sx), this.toPx(sy), this.toPx(sw), this.toPx(sh), this.toPx(x), this.toPx(y), this.toPx(w), this.toPx(h));
+      }
+      this.ctx.restore();
+    },
+    /**
+     * 渲染线
+     * @param {*} param0
+     */
+    drawLine({ startX, startY, endX, endY, color, width }) {
+      this.ctx.save();
+      this.ctx.beginPath();
+      this.ctx.setStrokeStyle(color);
+      this.ctx.setLineWidth(this.toPx(width));
+      this.ctx.moveTo(this.toPx(startX), this.toPx(startY));
+      this.ctx.lineTo(this.toPx(endX), this.toPx(endY));
+      this.ctx.stroke();
+      this.ctx.closePath();
+      this.ctx.restore();
+    },
+    downloadResource(images = []) {
+      const drawList = [];
+      this.drawArr = [];
+      images.forEach((image, index) => drawList.push(this._downloadImageAndInfo(image, index)));
+      return Promise.all(drawList);
+    },
+    initCanvas(w, h, debug) {
+      return new Promise((resolve) => {
+        this.pxWidth = this.toPx(w)
+        this.pxHeight = this.toPx(h)
+        this.debug = debug
+        setTimeout(() => {
+          resolve()
+        }, 0)
+      });
+    },
+
+    /**  
+     * handle
+     -----------------------*/
+    /**
+     * 画圆角矩形
+     */
+    _drawRadiusRect(x, y, w, h, r) {
+      const br = r / 2;
+      this.ctx.beginPath();
+      this.ctx.moveTo(this.toPx(x + br), this.toPx(y));    // 移动到左上角的点
+      this.ctx.lineTo(this.toPx(x + w - br), this.toPx(y));
+      this.ctx.arc(this.toPx(x + w - br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (3 / 4), 2 * Math.PI * (4 / 4))
+      this.ctx.lineTo(this.toPx(x + w), this.toPx(y + h - br));
+      this.ctx.arc(this.toPx(x + w - br), this.toPx(y + h - br), this.toPx(br), 0, 2 * Math.PI * (1 / 4))
+      this.ctx.lineTo(this.toPx(x + br), this.toPx(y + h));
+      this.ctx.arc(this.toPx(x + br), this.toPx(y + h - br), this.toPx(br), 2 * Math.PI * (1 / 4), 2 * Math.PI * (2 / 4))
+      this.ctx.lineTo(this.toPx(x), this.toPx(y + br));
+      this.ctx.arc(this.toPx(x + br), this.toPx(y + br), this.toPx(br), 2 * Math.PI * (2 / 4), 2 * Math.PI * (3 / 4))
+    },
+    /**
+     * 计算文本长度
+     * @param {Array|Object}} text 数组 或者 对象
+     */
+    _getTextWidth(text) {
+      let texts = [];
+      if (Object.prototype.toString.call(text) === '[object Object]') {
+        texts.push(text);
+      } else {
+        texts = text;
+      }
+      let width = 0;
+      texts.forEach(({ fontSize, text, marginLeft = 0, marginRight = 0 }) => {
+        this.ctx.setFontSize(this.toPx(fontSize));
+        width += this.ctx.measureText(text).width + marginLeft + marginRight;
+      })
+
+      return this.toRpx(width);
+    },
+    /**
+     * 渲染一段文字
+     */
+    _drawSingleText({ x, y, fontSize, color, baseLine, textAlign = 'left', text, opacity = 1, textDecoration = 'none',
+      width, lineNum = 1, lineHeight = 0, fontWeight = 'normal', fontStyle = 'normal', fontFamily = "sans-serif" }) {
+      this.ctx.save();
+      this.ctx.beginPath();
+      this.ctx.font = fontStyle + " " + fontWeight + " " + this.toPx(fontSize, true) + "px " + fontFamily
+      this.ctx.setGlobalAlpha(opacity);
+      // this.ctx.setFontSize(this.toPx(fontSize));
+      this.ctx.setFillStyle(color);
+      this.ctx.setTextBaseline(baseLine);
+      this.ctx.setTextAlign(textAlign);
+      let textWidth = this.toRpx(this.ctx.measureText(text).width);
+      const textArr = [];
+      if (textWidth > width) {
+        // 文本宽度 大于 渲染宽度
+        let fillText = '';
+        let line = 1;
+        for (let i = 0; i <= text.length - 1; i++) {  // 将文字转为数组,一行文字一个元素
+          fillText = fillText + text[i];
+          if (this.toRpx(this.ctx.measureText(fillText).width) >= width) {
+            if (line === lineNum) {
+              if (i !== text.length - 1) {
+                fillText = fillText.substring(0, fillText.length - 1) + '...';
+              }
+            }
+            if (line <= lineNum) {
+              textArr.push(fillText);
+            }
+            fillText = '';
+            line++;
+          } else {
+            if (line <= lineNum) {
+              if (i === text.length - 1) {
+                textArr.push(fillText);
+              }
+            }
+          }
+        }
+        textWidth = width;
+      } else {
+        textArr.push(text);
+      }
+
+      textArr.forEach((item, index) => {
+        this.ctx.fillText(item, this.toPx(x), this.toPx(y + (lineHeight || fontSize) * index));
+      })
+
+      this.ctx.restore();
+
+      // textDecoration
+      if (textDecoration !== 'none') {
+        let lineY = y;
+        if (textDecoration === 'line-through') {
+          // 目前只支持贯穿线
+          lineY = y;
+        }
+        this.ctx.save();
+        this.ctx.moveTo(this.toPx(x), this.toPx(lineY));
+        this.ctx.lineTo(this.toPx(x) + this.toPx(textWidth), this.toPx(lineY));
+        this.ctx.setStrokeStyle(color);
+        this.ctx.stroke();
+        this.ctx.restore();
+      }
+
+      return textWidth;
+    },
+
+
+    /**  
+     * helper
+     -----------------------*/
+    /**
+     * 下载图片并获取图片信息
+     */
+    _downloadImageAndInfo(image, index) {
+      return new Promise((resolve, reject) => {
+        const { x, y, url, zIndex, type } = image;
+        const imageUrl = url;
+	
+        // 下载图片
+        this._downImage(imageUrl, index, type)
+          // 获取图片信息
+          .then(imgPath => this._getImageInfo(imgPath, index))
+          .then(({ imgPath, imgInfo }) => {
+            // 根据画布的宽高计算出图片绘制的大小,这里会保证图片绘制不变形
+            let sx;
+            let sy;
+            const borderRadius = image.borderRadius || 0;
+            const setWidth = image.width;
+            const setHeight = image.height;
+            const width = this.toRpx(imgInfo.width);
+            const height = this.toRpx(imgInfo.height);
+            if (width / height <= setWidth / setHeight) {
+              sx = 0;
+              sy = (height - ((width / setWidth) * setHeight)) / 2;
+            } else {
+              sy = 0;
+              sx = (width - ((height / setHeight) * setWidth)) / 2;
+            }
+            this.drawArr.push({
+              type: 'image',
+              borderRadius,
+              borderWidth: image.borderWidth,
+              borderColor: image.borderColor,
+              zIndex: typeof zIndex !== 'undefined' ? zIndex : index,
+              imgPath,
+              sx,
+              sy,
+              sw: (width - (sx * 2)),
+              sh: (height - (sy * 2)),
+              x,
+              y,
+              w: setWidth,
+              h: setHeight,
+            });
+            resolve();
+          })
+          .catch(err => reject(err));
+      });
+    },
+    /**
+     * 下载图片资源
+     * @param {*} imageUrl
+     */
+    _downImage(imageUrl,index,type) {
+      return new Promise((resolve, reject) => {
+        if (/^http/.test(imageUrl) && !new RegExp(wx.env.USER_DATA_PATH).test(imageUrl)&&type!=='qrcode') {
+          wx.downloadFile({
+            url: this._mapHttpToHttps(imageUrl),
+            success: (res) => {
+              if (res.statusCode === 200) {
+                resolve(res.tempFilePath);
+              } else {
+                reject(res.errMsg);
+              }
+            },
+            fail(err) {
+              reject(err);
+            },
+          });
+        } else {
+          // 支持本地地址
+          resolve(imageUrl);
+        }
+      });
+    },
+    /**
+     * 获取图片信息
+     * @param {*} imgPath
+     * @param {*} index
+     */
+    _getImageInfo(imgPath, index) {
+      return new Promise((resolve, reject) => {
+        wx.getImageInfo({
+          src: imgPath,
+          success(res) {
+            resolve({ imgPath, imgInfo: res, index });
+          },
+          fail(err) {
+            reject(err);
+          },
+        });
+      });
+    },
+    toPx(rpx, int) {
+      // console.log('toPx',this.factor)
+      if (int) {
+        return parseInt(rpx * this.factor);
+      }
+      return rpx * this.factor;
+    },
+    toRpx(px, int) {
+      // console.log('toRpx',this.factor)
+
+      if (int) {
+        return parseInt(px / this.factor);
+      }
+      return px / this.factor;
+    },
+    /**
+     * 将http转为https
+     * @param {String}} rawUrl 图片资源url
+     */
+    _mapHttpToHttps(rawUrl) {
+      if (rawUrl.indexOf(':') < 0) {
+        return rawUrl;
+      }
+      const urlComponent = rawUrl.split(':');
+      if (urlComponent.length === 2) {
+        if (urlComponent[0] === 'http') {
+          urlComponent[0] = 'https';
+          return `${urlComponent[0]}:${urlComponent[1]}`;
+        }
+      }
+      return rawUrl;
+    },
+  },
+  created() {
+    const sysInfo = uni.getSystemInfoSync();
+    const screenWidth = sysInfo.screenWidth;
+    this.factor = screenWidth / 750;
+    // console.log('created')
+  },
+};
+</script>
+
+<style lang="scss">
+.dt-canvas {
+  width: 750upx;
+  height: 750upx;
+}
+.dt-canvas.pro {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  transform: translate3d(-9999upx, 0, 0);
+}
+.dt-canvas.debug {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  border: 1upx solid #ccc;
+}
+</style>

+ 112 - 0
pagesM/comps/canvas/poster.vue

@@ -0,0 +1,112 @@
+<template>
+  <view>
+    <view @tap="onCreate">
+      <slot/>
+    </view>
+    <we-canvas ref="poster" @success="onCreateSuccess" @fail="onCreateFail"/>
+  </view>
+</template>
+<script>
+import WeCanvas from "./index.vue";
+export default {
+  components: {
+    WeCanvas
+  },
+  props: {
+    config: {
+      type: Object,
+      default: {}
+    },
+    preload: {
+      // 是否预下载图片资源
+      type: Boolean,
+      default: false
+    },
+    hideLoading: {
+      // 是否隐藏loading
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {
+    trigger(event, data) {
+      if (this.listener && typeof this.listener[event] === "function") {
+        this.listener[event](data);
+      }
+    },
+    once(event, fun) {
+      if (typeof this.listener === "undefined") {
+        this.listener = {};
+      }
+      this.listener[event] = fun;
+    },
+    downloadResource(reset) {
+      return new Promise((resolve, reject) => {
+        if (reset) {
+          this.downloadStatus = null;
+        }
+        const poster = this.$refs.poster
+
+        if (this.downloadStatus && this.downloadStatus !== "fail") {
+          if (this.downloadStatus === "success") {
+            resolve();
+          } else {
+            this.once("downloadSuccess", () => resolve());
+            this.once("downloadFail", e => reject(e));
+          }
+        } else {
+          poster
+            .downloadResource(this.config.images)
+            .then(() => {
+              this.downloadStatus = "success";
+              resolve();
+            })
+            .catch(e => reject(e));
+        }
+      });
+    },
+    onCreate(reset = false) {
+      !this.hideLoading && uni.showLoading({ mask: true, title: "生成中" });
+      return this.downloadResource(typeof reset === "boolean" && reset)
+        .then(() => {
+          !this.hideLoading && uni.hideLoading();
+          const poster = this.$refs.poster;
+          poster.create(this.config);
+        })
+        .catch(err => {
+          !this.hideLoading && uni.hideLoading();
+          uni.showToast({ icon: "none", title: err.errMsg || "生成失败" });
+          console.error(err);
+          this.$emit("fail", err);
+        });
+    },
+    onCreateSuccess(path) {
+      this.$emit("success", path);
+    },
+    onCreateFail(err) {
+      console.error(err);
+      this.$emit("fail", err);
+    },
+    
+  },
+  onReady() {
+    if (this.preload) {
+      const poster = this.$refs.poster;
+      this.downloadStatus = 'doing';
+      poster.downloadResource(this.config.images).then(() => {
+        this.downloadStatus = 'success';
+        this.trigger('downloadSuccess');
+      }).catch((e) => {
+        this.downloadStatus = 'fail';
+        this.trigger('downloadFail', e);
+      });
+    }
+  },
+};
+</script>
+
+<style lang="scss">
+</style>

+ 68 - 0
pagesM/comps/dt_accumulator.vue

@@ -0,0 +1,68 @@
+<template>
+  <view class="dt-accumulator">
+    <view class="plus-btn" @tap="tapPlus(-1)">-</view>
+    <input type="number" :value="val" @input="onInput" @blur="onBlur" class="input-box" />
+    <view class="plus-btn" @tap="tapPlus(1)">+</view>
+  </view>
+</template>
+<script>
+export default {
+  props:{
+    isFocus:{
+      type: Boolean,
+      default: false
+    },
+    val:{
+      type: Number,
+      default: 1
+    }
+  },
+  methods:{
+    onBlur(e){
+      let val = parseInt(e.detail.value)
+      this.$emit('update:isFocus',false)
+      this.$emit('change', val)
+      // this.$emit('update:isFocus',false)
+    },
+    onInput(e){
+      this.$emit('update:isFocus',true)
+    },
+    tapPlus(delta){
+      if(this.isFocus) return 
+
+      let val = parseInt(this.val) + delta
+      this.$emit('change', val)
+    }
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.dt-accumulator{
+  display: flex;
+  align-items: center;
+  width: 200upx;
+  height: 50upx;
+  box-sizing: border-box;
+  border:1upx solid #E5E5E5;
+  border-radius:6upx;
+
+  .plus-btn{
+    width:60upx;
+    height: 100%;
+    box-sizing: border-box;
+    text-align: center;
+    font-size:40upx;
+    line-height: 42rpx;
+  }
+  .input-box{
+    flex:1;
+    height:100%;
+    padding:0 10upx;
+    text-align: center;
+    border-left:1upx solid #e5e5e5;
+    border-right:1upx solid #e5e5e5;
+  }
+}
+
+</style>

+ 312 - 0
pagesM/comps/dt_category_goods_list.vue

@@ -0,0 +1,312 @@
+<template>
+  <view>
+    <view class="goods_list_style1" v-if="showStyle">
+      <view class="goods_item_style1">
+        <view class="goods_img">
+          <image src="https://api.dreamstech.cn/img/ysyl//20191012/1c15b1d8-da65-4219-a8ae-a8e671e297891570847701931.png"></image>
+        </view>
+        <view class="goods_info">
+          <view class="goods_top">
+            <view class="goods_time">10分钟</view>
+            <view class="goods_title">众生丸(薄膜衣 浓缩丸)</view>
+          </view>
+          <view class="goods_des">清热解毒,活血凉血,消炎止痛。用于上呼吸道感染,急、慢性咽喉炎,急性扁桃腺炎等症</view>
+          <view class="goods_active">
+            <view class="active_item">特价抢购</view>
+            <view class="active_item">1元换购</view>
+            <view class="active_item">包邮</view>
+          </view>
+          <view class="goods_bottom">
+            <view class="sell_info">
+              <view class="sell_price">
+                <text>¥110.50</text>
+                <text>¥130.50</text>
+              </view>
+              <view class="sell_count">销量520笔</view>
+            </view>
+            <image src="http://139.9.103.171:1888/img/image/ss="buy"></image>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="goods_list_style2" v-else>
+      <view class="goods_item_style2">
+        <view class="goods_item_box">
+          <view class="goods_img">
+            <image src="https://api.dreamstech.cn/img/ysyl//20191012/1c15b1d8-da65-4219-a8ae-a8e671e297891570847701931.png"></image>
+          </view>
+          <view class="goods_info">
+            <view class="goods_top">
+              <view class="goods_title">众生丸(薄膜衣 浓缩丸)</view>
+            </view>
+            <!-- <view class="goods_des">清热解毒,活血凉血,消炎止痛。用于上呼吸道感染,急、慢性咽喉炎,急性扁桃腺炎等症</view> -->
+            <view class="goods_active">
+              <view class="active_item">特价抢购</view>
+              <view class="active_item">1元换购</view>
+              <view class="active_item">包邮</view>
+            </view>
+            <view class="goods_bottom">
+              <view class="sell_info">
+                <view class="sell_price">
+                  <text>¥110.50</text>
+                  <!-- <text>¥130.50</text> -->
+                </view>
+                <view class="sell_count">销量520笔</view>
+              </view>
+              <image src="http://139.9.103.171:1888/img/image/ss="buy"></image>
+              <!-- <view class="buy">购买</view> -->
+            </view>
+          </view>
+        </view>
+      </view>
+      <view class="goods_item_style2">
+        <view class="goods_item_box">
+          <view class="goods_img">
+            <image src="https://api.dreamstech.cn/img/ysyl//20191012/1c15b1d8-da65-4219-a8ae-a8e671e297891570847701931.png"></image>
+          </view>
+          <view class="goods_info">
+            <view class="goods_top">
+              <view class="goods_title">众生丸(薄膜衣 浓缩丸)</view>
+            </view>
+            <!-- <view class="goods_des">清热解毒,活血凉血,消炎止痛。用于上呼吸道感染,急、慢性咽喉炎,急性扁桃腺炎等症</view> -->
+            <view class="goods_active">
+              <view class="active_item">特价抢购</view>
+              <view class="active_item">1元换购</view>
+              <view class="active_item">包邮</view>
+            </view>
+            <view class="goods_bottom">
+              <view class="sell_info">
+                <view class="sell_price">
+                  <text>¥110.50</text>
+                  <!-- <text>¥130.50</text> -->
+                </view>
+                <view class="sell_count">销量520笔</view>
+              </view>
+               <image src="http://139.9.103.171:1888/img/image/ss="buy"></image>
+            </view>
+           
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+
+</template>
+
+<script>
+export default {
+  props: {
+    dataList: {
+      type: Array,
+      default: []
+    },
+    showStyle: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {
+
+  },
+  created() { }
+};
+</script>
+
+<style lang="scss">
+.goods_list_style1 {
+  .goods_item_style1 {
+    display: flex;
+    flex-direction: row;
+    padding: 20upx;
+    border-top: 1upx solid #f2f2f2;
+    .goods_img {
+      image {
+        width: 115upx;
+        height: 115upx;
+      }
+    }
+    .goods_info {
+      padding-left: 20upx;
+      .goods_top {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        .goods_time {
+          font-size: 18upx;
+          border-radius: 4upx;
+          background: $dt-color-primary;
+          padding: 5upx 10upx;
+          color: #fff;
+        }
+        .goods_title {
+          flex: 1;
+          color: #333333;
+          font-size: 28upx;
+          letter-spacing: 2upx;
+          margin-left: 20upx;
+        }
+      }
+      .goods_des {
+        font-size: 22upx;
+        color: #999;
+        line-height: 38upx;
+        margin-bottom: 10upx;
+      }
+      .goods_active {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-bottom: 10upx;
+        flex-wrap: wrap;
+        .active_item {
+          border: 1upx solid #ee1515;
+          border-radius: 4upx;
+          padding: 5upx;
+          color: #ee1515;
+          font-size: 18upx;
+          margin-right: 10upx;
+        }
+      }
+      .goods_bottom {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        align-items: center;
+        .sell_info {
+          display: flex;
+          flex-direction: column;
+          .sell_price {
+            display: flex;
+            flex-direction: row;
+            align-items: center;
+            text:first-child {
+              font-size: 30upx;
+              color: #ee1515;
+            }
+            text:last-child {
+              color: #888888;
+              font-size: 22upx;
+              text-decoration: line-through;
+              margin-left: 20upx;
+            }
+          }
+          .sell_count {
+            margin-top: 10upx;
+            font-size: 22upx;
+            color: #888888;
+          }
+        }
+        .buy {
+          width: 50upx;
+          height: 50upx;
+        }
+      }
+    }
+  }
+}
+
+.goods_list_style2 {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  .goods_item_style2 {
+    width: 50%;
+    justify-content: flex-start;
+    box-sizing: border-box;
+    border-bottom: 2upx solid rgb(238, 238, 238);
+    border-right: 2upx solid rgb(238, 238, 238);
+    .goods_item_box {
+      display: flex;
+      flex-direction: column;
+      padding: 0 20upx;
+      .goods_img {
+        width: 100%;
+        height: 250upx;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: center;
+        image {
+          width: 218upx;
+          height: 218upx;
+        }
+      }
+      .goods_info {
+        margin-bottom: 10upx;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-around;
+        .goods_top {
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          .goods_title {
+            flex: 1;
+            color: #333333;
+            font-size: 24upx;
+            letter-spacing: 1upx;
+          }
+        }
+        .goods_des {
+          font-size: 22upx;
+          color: #999;
+          line-height: 38upx;
+          margin-bottom: 10upx;
+        }
+        .goods_active {
+          display: flex;
+          flex-direction: row;
+          flex-wrap: wrap;
+          margin-bottom: 10upx;
+          .active_item {
+            border: 1upx solid #ee1515;
+            border-radius: 4upx;
+            padding: 5upx 10upx;
+            color: #ee1515;
+            font-size: 18upx;
+            margin-right: 10upx;
+            margin-top: 10upx;
+          }
+        }
+        .goods_bottom {
+          display: flex;
+          flex-direction: row;
+          justify-content: space-between;
+          align-items: center;
+          .sell_info {
+            display: flex;
+            flex-direction: column;
+            .sell_price {
+              display: flex;
+              flex-direction: row;
+              align-items: center;
+              text:first-child {
+                font-size: 30upx;
+                color: #ee1515;
+              }
+              // text:last-child {
+              //   color: #888888;
+              //   font-size: 22upx;
+              //   text-decoration: line-through;
+              //   margin-left: 20upx;
+              // }
+            }
+            .sell_count {
+              margin-top: 10upx;
+              font-size: 22upx;
+              color: #888888;
+            }
+          }
+          .buy {
+            width: 50upx;
+            height: 50upx;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 324 - 0
pagesM/comps/dt_category_goods_list_new.vue

@@ -0,0 +1,324 @@
+<template>
+  <view style="position: relative;">
+	  
+	  <!-- <view style="height: 66upx;"></view> -->
+		  <scroll-view scroll-y="true" @scrolltolower="onScrolltolower" :style="{height: scrollViewHeight}">
+		  	<view>
+				<view v-if="adsList.length>0"  style="padding: 20upx 20upx 0;">
+				   <swiper 
+				   style="border-radius: 16upx;overflow: hidden;height: 172upx;" 
+				   class="swiper" 
+				   interval="5000" 
+				   duration="500" 
+				   autoplay="true" 
+				   circular="true" 
+				   :indicator-dots="adsList.length>1" 
+				   indicator-color="rgba(153,153,153,1)" 
+				   indicator-active-color="#FFF">
+				     <swiper-item v-for="(item,index) in adsList" :key="index">
+				       <image mode="widthFix" :src="item.path" style="width: 100%;border-radius: 16upx;" @tap="tapNav(item)"></image>
+				     </swiper-item>
+				   </swiper>
+				 </view>
+				<view style="position: sticky;top:0;">
+					<view :class="isTapSelect?'':'twoLabelNo'" style="position: absolute;margin-left: 20upx;display: flex;z-index: 999999;background-color: white;padding-top: 20upx;padding-bottom: 10upx;">
+						<view id="menuLists" style="display: flex;flex-wrap: wrap;width: 566upx;margin: 0 auto;">
+							<view v-for="(item,index) in menuList" :key="index" :class="index==curActive?'activeLabel dt-text-row-one':'twoLabel dt-text-row-one'" @tap="tapActive(index,item)">{{index==0?'全部':item.name}}</view>
+						</view>
+							<view @tap="tapSelect" 
+							 style="height: 46upx;
+							 width: 46upx;
+							 display: flex;
+							 align-items: center;
+							 justify-content: center;
+							 margin-right: 10upx;
+							 position: absolute;
+							 background-color: white;
+							 z-index: 9999999;
+							 right: 0;
+							 top: 20upx;">
+								 <image src="http://139.9.103.171:1888/img/image/ic_select.png" style="width: 16upx;height: 16upx;"></image>
+							 </view>
+					</view>
+				</view>
+				<view style="height: 66upx"></view>
+				<view  class="scroll-view-content" :style="{display:show}">
+					<view v-for="(item,index) in dataList" :key="index" @tap="jumpGoodsDes(item.id||item.productId)">
+					<view style="display: flex;padding: 20upx;align-items: center;">
+						<image :src="item.thumbnail||item.img|| 'http://139.9.103.171:1888/img/image/goods_def.png'" mode="widthFix" style="width: 152upx;height: 152upx;"></image>
+						<view style="margin-left: 24upx;flex:1;">
+							<view class="two_line_ellipsis" style="color: #353535;font-size: 24upx;line-height: 28upx;" >{{item.name}}</view>
+							<view class="one_line_ellipsis" style="height: 26upx;line-height: 26upx;box-sizing: content-box;font-size: 24upx;color: #A3A3A3;margin-top: 10upx;overflow: hidden;">{{item.caption?item.caption:''}}</view>
+							<view style="width: 100%;height: 26upx;margin-top: 16upx;">
+								<view v-if="item.promotion" style="display: flex;white-space: nowrap;">
+									<view v-if="item.promotion.coupon" style="
+									color: #DB4444;
+									background:rgba(219,68,68,0.1);
+									border-radius: 25upx;
+									padding: 4rpx 8rpx;
+									margin-right: 5upx;
+									font-size: 20rpx;">
+									{{item.promotion.coupon.name}}
+									</view>
+									<view v-if="item.promotion.freeShipping" style="
+									color: #DB4444;
+									background:rgba(219,68,68,0.1);
+									border-radius: 25upx;
+									padding: 4rpx 8rpx;
+									margin-right: 5upx;
+									font-size: 20rpx;">
+									{{item.promotion.freeShipping.name}}
+									</view>
+									<view v-if="item.promotion.gifts.length>0" 
+									v-for="(giftsItem,giftsIndex) in item.promotion.gifts"
+									:key="giftsIndex"
+									style="
+									color: #DB4444;
+									background:rgba(219,68,68,0.1);
+									border-radius: 25upx;
+									padding: 4rpx 8rpx;
+									margin-right: 5upx;
+									font-size: 20rpx;">
+									{{giftsItem.name}}
+									</view>
+									<view v-if="item.promotion.moneyOffs.length>0"
+									 v-for="(moneyOffsItem,moneyOffsIndex) in item.promotion.moneyOffs"
+									 :key="moneyOffsIndex"
+									style="
+									color: #444FDB;
+									background:rgba(68,79,219,0.1);
+									border-radius: 25upx;
+									padding: 4rpx 8rpx;
+									margin-right: 5upx;
+									font-size: 20rpx;">
+									{{moneyOffsItem.name}}
+									</view>
+								</view>
+							</view>
+							<view style="
+							margin-bottom: 18upx;
+							border-radius: 4upx;
+							line-height: 16upx;
+							padding: 0 4upx;
+							font-size: 10upx;
+							color: #DB4444;"></view>
+							<view style="display: flex;align-items: center;justify-content: space-between;">
+								<view style="display: flex;align-items: center;">
+									<view style="color: #DB4444;font-size: 14upx;margin-top: 10upx;">¥</view>
+									<view style="color: #DB4444;font-size: 26upx;">{{item.price}}</view>
+									<view style="color: #A3A3A3;font-size: 20upx;margin-left: 20upx;text-decoration: line-through;margin-top: 8upx;">{{item.marketPrice?"¥"+item.marketPrice:''}}</view>
+								</view>
+								<image src="http://139.9.103.171:1888/img/image/shop_car_icon.png" mode="widthFix" style="width: 40upx;height: 40upx;" ></image>
+							</view>
+						</view>
+					</view>
+					<view style="background-color: #f2f2f2;height: 2upx;margin: 0 20upx;"></view>
+				</view>
+				</view>
+				<DtNoMore v-if="isNoMore" />
+				<DtEmpty :type="emptyType" :wrapBgColor="white"/>
+				<view style="height: 25upx;"></view>
+			</view>
+		  </scroll-view>
+      
+  </view>
+</template>
+<script>
+import DtGoodsList from './dt_goods_list.vue'
+import DtEmpty from './dt_empty.vue'
+import DtNoMore from './dt_no_more.vue'
+export default {
+  components: {
+    DtGoodsList,
+    DtEmpty,
+    DtNoMore
+  },
+  data() {
+    return {
+		white:'white',
+      memberId: '',
+      productCategoryId: '',
+      paramsList: [],
+      dataList: [],
+      curActive: 0,
+      typeList: {
+        0: null,
+        1: {
+          k: 'sales',
+          t: 3,
+          v: 1
+        },
+        2: {
+          k: 'price',
+          t: 3,
+          v: 1
+        }
+      },
+	  scrollViewHeight:0,
+	  show:'block',
+	  isTapSelect:false,
+	  rightHeight:0
+    }
+  },
+  props:{
+	  menuList:{
+		  type:Array,
+		  default:[]
+	  },
+	  adsList:{
+		  type:Array,
+		  default:[]
+	  }
+  },
+  created() {
+	  this.memberId = this.$auth.getMemberId();
+  },
+  methods: {
+	  tapNav(item){
+	  		  let type = item.type; //0:文本广告,1:图片广告 2:会场广告
+	  		  if([0,"0"].includes(type)&&item.content){
+	  		  	uni.navigateTo({
+	  		  	  url: '/pagesM/pages/common/ad_textView?content=' + item.content
+	  		  	});
+	  		  }else if([1,"1"].includes(type)&&item.productId){
+	  		  	uni.navigateTo({
+	  		  	  url: '/pagesM/pages/goods_des?id=' + item.productId
+	  		  	});
+	  		  }else if([2,'2'].include(type)&&item.url){
+	  		  	let  url = item.url;
+	  		  	if (this.memberId){
+	  		  		 url = url + this.memberId;
+	  		  		 console.log('banner 链接 = ' + url)
+	  		  		 uni.navigateTo({
+	  		  		   url: '/pagesM/pages/common/webview?url=' + encodeURIComponent(url)
+	  		  		 });
+	  		  	}
+	  		}
+	  }, 
+	  getswipHeight(adsList){
+		  
+		  let res = uni.getSystemInfoSync();
+		  let clientHeight = res.windowHeight;
+		  let clientWidth = res.windowWidth;
+		  let upxR = 750 / clientWidth;
+		  let left = clientHeight * upxR - 105;
+		  let leftHeight = uni.upx2px(left);
+		  let right = clientHeight * upxR;
+		
+		  if(adsList.length>0){
+			   this.rightHeight = uni.upx2px(right)-26
+		  }else{
+				this.rightHeight = uni.upx2px(right)
+		  }
+		  // this.winLeftHeight = leftHeight;
+		  this.scrollViewHeight = this.rightHeight+'px';
+	  },
+	  tapSelect(){
+		this.isTapSelect = !this.isTapSelect  
+	  },
+	  onLoadPage(){
+		  this.queryDataList();
+	  },
+	  jumpGoodsDes(id) {
+	    console.log(id);
+	    uni.navigateTo({
+	      url: "/pagesM/pages/goods_des?id=" + id
+	    })
+	  },
+    tapActive(idx,item) {
+		console.log(item)
+      this.curActive = idx
+      this.productCategoryId = item.id;
+      this.isNoMore = false
+      this.pageIndex = 0
+      this.dataList.length = 0
+      this.queryDataList();
+	  this.isTapSelect = false;
+    },
+
+    getParams() {
+      let param = this.typeList[this.curActive]
+      let paramsList = this.paramsList.slice(0)
+      console.log(96, paramsList)
+      if (this.productCategoryId) {
+        paramsList.unshift({
+          k: 'productCategory.id',
+          t: 1,
+          v: this.productCategoryId
+        })
+      }
+      console.log(104, paramsList, param)
+      if (param) {
+        paramsList.unshift(param)
+      }
+      console.log(108, paramsList)
+      return paramsList
+    },
+    // 搜索
+    async queryDataList() {
+      let params = this.getParams()
+      console.log(112, params)
+      let resp = await this.$api.searchProduct({
+        _isShowLoading: true,
+        pageNo: this.pageIndex,
+        pageSize: this.pageSize,
+        memberId: this.memberId,
+        params: params
+      })
+      let list = this.getDataList(resp)
+      this.dataList = this.dataList.concat(list);
+	  const query = uni.createSelectorQuery().in(this);
+	  query.select('#menuLists').boundingClientRect(data => {
+	    console.log('打印高度',data); 
+	  			let height= this.rightHeight - data.height;
+				 this.scrollViewHeight = height+'px';
+	  }).exec();
+	  
+	  if(this.emptyType==0){
+		  this.show = 'block'
+	  }else{
+		  this.show = 'none'
+	  }
+    },
+	onScrolltolower(){
+		this.onReachBottomPage()
+	}
+  },
+  
+}
+</script>
+
+<style lang="scss" scoped>
+	.activeLabel{
+		width: 120upx;
+		height:46upx;
+		text-align: center;
+		line-height: 46upx;
+		border-radius: 4upx;
+		color: #DB4444;
+		background:rgba(219,68,68,0.24);
+		font-size: 24upx;
+		margin-right: 10upx;
+		margin-bottom: 10upx;
+	}
+	.twoLabel{
+		width: 120upx;
+		height:46upx;
+		text-align: center;
+		line-height: 46upx;
+		border-radius: 4upx;
+		background-color: #EBEBEB;
+		color: #999999;
+		font-size: 24upx;
+		margin-right: 10upx;
+		margin-bottom: 10upx;
+	}
+	.scroll-view-content{
+		flex:1
+	}
+	.twoLabelNo{
+		height: 46upx;
+		overflow: hidden;
+	}
+
+</style>

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů