Ver código fonte

填充静态页面内容

achao 3 anos atrás
pai
commit
8b3a08241c
100 arquivos alterados com 6947 adições e 499 exclusões
  1. 16 0
      .hbuilderx/launch.json
  2. 2 1
      App.vue
  3. 21 1
      README.md
  4. 3 3
      api/mock.js
  5. 48 21
      common/helper.js
  6. 0 67
      components/good-list/good-list.vue
  7. 318 0
      components/master-keyboard/master-keyboard.scss
  8. 331 0
      components/master-keyboard/master-keyboard.vue
  9. 205 0
      components/me-tabs/me-tabs.vue
  10. 143 0
      components/ossutil/base64.js
  11. 9 0
      components/ossutil/config.js
  12. 178 0
      components/ossutil/crypto.js
  13. 34 0
      components/ossutil/hmac.js
  14. 79 0
      components/ossutil/sha1.js
  15. 394 0
      components/ossutil/signature.js
  16. 86 0
      components/ossutil/uploadFile.js
  17. 788 0
      components/upload.vue
  18. 1 1
      config/index.js
  19. 103 0
      demo.vue
  20. 2 1
      main.js
  21. 115 110
      pages.json
  22. 0 76
      pages/demo/demo.vue
  23. 38 30
      pages/goodSource/index.vue
  24. 139 0
      pages/goodSource/mescroll-swiper-item.vue
  25. 102 3
      pages/goodSource/shippingDetails.vue
  26. 0 53
      pages/index/index.vue
  27. 213 0
      pages/mine/camera/camera.nvue
  28. 246 0
      pages/mine/camera/idcard/idcard.nvue
  29. 240 0
      pages/mine/camera/idphoto/idphoto.nvue
  30. 214 0
      pages/mine/camera/portrait/portrait.nvue
  31. 228 0
      pages/mine/camera/watermark/watermark.nvue
  32. 519 8
      pages/mine/driverCertification.vue
  33. 329 0
      pages/mine/driverCertificationNext.vue
  34. 18 3
      pages/mine/helpDescription.vue
  35. 78 3
      pages/mine/index.vue
  36. 220 8
      pages/mine/manageBankCards/addBankCard.vue
  37. 20 0
      pages/mine/manageBankCards/editBankCard.vue
  38. 51 4
      pages/mine/manageBankCards/index.vue
  39. 43 6
      pages/mine/manageVehicles/addVehicle.vue
  40. 43 6
      pages/mine/manageVehicles/editVehicle.vue
  41. 80 5
      pages/mine/manageVehicles/index.vue
  42. 244 6
      pages/mine/set.vue
  43. 77 6
      pages/news/index.vue
  44. 146 5
      pages/order/confirmLoading.vue
  45. 147 6
      pages/order/confirmUnloading.vue
  46. 56 61
      pages/order/index.vue
  47. 139 0
      pages/order/mescroll-swiper-item.vue
  48. 119 4
      pages/order/orderDetails.vue
  49. 5 1
      pages/public/login.vue
  50. 208 0
      pages/public/register.vue
  51. 89 0
      static/css/common.scss
  52. 20 0
      static/css/font.css
  53. BIN
      static/icon_delete.png
  54. BIN
      static/icon_down.png
  55. BIN
      static/images/login/bg.png
  56. BIN
      static/images/login/bg@2x.png
  57. BIN
      static/images/login/bg@3x.png
  58. BIN
      static/images/login/bg_slices/bg.png
  59. BIN
      static/images/login/bg_slices/bg@2x.png
  60. BIN
      static/images/login/bg_slices/bg@3x.png
  61. BIN
      static/images/login/duihao2.png
  62. BIN
      static/images/login/duihao2@2x.png
  63. BIN
      static/images/login/duihao2@3x.png
  64. BIN
      static/images/login/guanbi@2x.png
  65. BIN
      static/images/login/logo.png
  66. BIN
      static/images/login/logo@2x.png
  67. BIN
      static/images/login/logo@3x.png
  68. BIN
      static/images/login/select.png
  69. BIN
      static/images/login/select@2x.png
  70. BIN
      static/images/login/select@3x.png
  71. BIN
      static/images/login/selected1.png
  72. BIN
      static/images/login/selected2.png
  73. BIN
      static/images/login/selected3.png
  74. BIN
      static/images/mine/saoma.png
  75. BIN
      static/images/myimg/LiangNong.png
  76. BIN
      static/images/myimg/LiangNong@2x.png
  77. BIN
      static/images/myimg/LiangNong@3x.png
  78. BIN
      static/images/myimg/LiangShang@2x.png
  79. BIN
      static/images/myimg/LiangShang@3x.png
  80. BIN
      static/images/myimg/SiJi.png
  81. BIN
      static/images/myimg/SiJi@2x.png
  82. BIN
      static/images/myimg/SiJi@3x.png
  83. BIN
      static/images/myimg/YongHu.png
  84. BIN
      static/images/myimg/YongHu@2x.png
  85. BIN
      static/images/myimg/YongHu@3x.png
  86. BIN
      static/images/myimg/erp.png
  87. BIN
      static/images/myimg/fabu@3x.png
  88. BIN
      static/images/myimg/gengduo1.png
  89. BIN
      static/images/myimg/gengduo1@2x.png
  90. BIN
      static/images/myimg/gengduo1@3x.png
  91. BIN
      static/images/myimg/liangmai@3x.png
  92. BIN
      static/images/myimg/renzheng@3x.png
  93. BIN
      static/images/myimg/sg.png
  94. BIN
      static/images/xiangji-2.png
  95. BIN
      static/live-camera/back.png
  96. BIN
      static/live-camera/bar.png
  97. BIN
      static/live-camera/flip.png
  98. BIN
      static/live-camera/outline/idcardbadge.png
  99. BIN
      static/live-camera/outline/idcardface.png
  100. BIN
      static/live-camera/outline/idphoto.png

+ 16 - 0
.hbuilderx/launch.json

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

+ 2 - 1
App.vue

@@ -1,6 +1,7 @@
 <style lang="scss">
 	/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
 	@import "@/uni_modules/uview-ui/index.scss";
+	@import 'static/css/common.scss';
 </style>
 <script>
 	import {
@@ -19,7 +20,7 @@
 			let type = uni.getSystemInfoSync().platform
 			console.log(type)
 			if (type == "android") {
-				appUpdate()
+				// appUpdate()
 			}
 			var that = this
 			plus.push.getClientInfoAsync((info) => {

+ 21 - 1
README.md

@@ -2,4 +2,24 @@
 
 #### 介绍
 uni-app项目开发模板,集成了u-view 2.0、基于uni-request封装、token验证、websocket、页面权限、按钮权限、mescoll上拉加载、下拉刷新、热更新、推送
-
+#### 常用u-view组件及方法
+常用view功能在根目录demo页面
+#### 公共样式
+常用css公共变量在 uni.scss和uni_modules\uview-ui目录下的theme.scss, 全局公共样式可以在theme.scss文件配置,也可以在static文件夹common.scss 配置
+全局样式包括但不限于内容布局、文字大小、颜色、公共组件css。
+常用css样式配置在common.scss文件中,常用flex布局、常用对齐方式、常用内边距、外边距
+#### 图片上传和拍照上传
+点击按钮上传文件
+import uploadImage from '@/components/ossutil/uploadFile.js';
+	uni.chooseImage({
+				    count: 1, 
+				    success: function (res) {
+				        console.log(JSON.stringify(res.tempFilePaths));
+						uploadImage(res.tempFilePaths[0], 'appData/',
+							result => {
+								// 上传成功
+								console.log('图片地址', result)
+							}
+						)
+				    }
+				});

+ 3 - 3
api/mock.js

@@ -61,12 +61,12 @@ export function apiGoods(pageNum, pageSize, keyword) {
 				
 				// 符合关键词的记录
 				let keywordList = [];
-				if (!keyword || keyword == "全部") {
+				if (!keyword || keyword == "推荐"||keyword == "全部") {
 					// 搜索全部商品
 					keywordList = goods;
 				}else{
 					// 关键词搜索
-					if(keyword=="母婴") keyword="婴"; // 为这个关键词展示多几条数据
+					if(keyword=="按时间"||keyword=="未发运") keyword="婴"; // 为这个关键词展示多几条数据
 					for (let i = 0; i < goods.length; i++) {
 						let good = goods[i]
 						if (good.goodName.indexOf(keyword) !== -1) {
@@ -166,7 +166,7 @@ export function apiGetTabs() {
 		//延时,模拟联网
 		setTimeout(function() {
 			try {
-				let tabs = ['全部', '奶粉', '面膜', '图书', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'];
+				let tabs = ['推荐', '按时间', '按距离', '运费先付', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'];
 				//模拟接口请求成功
 				resolute(tabs);
 			} catch (e) {

+ 48 - 21
common/helper.js

@@ -1,27 +1,41 @@
 import * as config from '../config'
 const rolesList = []
-const getListByUserId = function() {
-	let baseUrlNew = config.def().baseUrlNew
-	var userInfo = uni.getStorageSync("userInfo")
-	console.log("------",userInfo)
-	if(userInfo){
-		uni.request({
-			url: baseUrlNew + '/roleMenu/query/getListByUserId',
-			data: {
-				userId: userInfo.id?userInfo.id:userInfo.data.id
-			},
-			method: 'GET',
-			success: (res) => {
-				if (res.statusCode === 200) {
-					uni.setStorageSync("jurisdiction", res.data.data)
-					let list = getUserAllRoles(res.data.data);
-					uni.setStorageSync("rolesList", list)
-		
+const ossUploadUrl = 'https://taohaoliang.oss-cn-beijing.aliyuncs.com/';
+const chooseImage = {
+	count: '1',
+	sizeType: ['original', 'compressed'],
+	sourceType: ['album'],
+}
+const imgType = '请选择图片来源'
+const imgTypeList = [{
+			name: '相册',
+		},
+		{
+			name: '拍照',
+		}
+	]
+	const getListByUserId = function() {
+		let baseUrlNew = config.def().baseUrlNew
+		var userInfo = uni.getStorageSync("userInfo")
+		console.log("------", userInfo)
+		if (userInfo) {
+			uni.request({
+				url: baseUrlNew + '/roleMenu/query/getListByUserId',
+				data: {
+					userId: userInfo.id ? userInfo.id : userInfo.data.id
+				},
+				method: 'GET',
+				success: (res) => {
+					if (res.statusCode === 200) {
+						uni.setStorageSync("jurisdiction", res.data.data)
+						let list = getUserAllRoles(res.data.data);
+						uni.setStorageSync("rolesList", list)
+
+					}
 				}
-			}
-		})
+			})
+		}
 	}
-}
 const getUserAllRoles = (item) => {
 	console.log(item)
 
@@ -53,7 +67,20 @@ const setAudit = (item) => {
 	}
 	console.log(item)
 }
+const contactCustomerService = (item) => {
+	console.log(item)
+	console.log("联系客服")
+	uni.makePhoneCall({
+		phoneNumber: '114' //仅为示例
+	});
+
+}
 export default {
 	getListByUserId,
-	setAudit
+	setAudit,
+	ossUploadUrl,
+	contactCustomerService,
+	chooseImage,
+	imgType,
+	imgTypeList
 }

+ 0 - 67
components/good-list/good-list.vue

@@ -1,67 +0,0 @@
-<!-- 商品列表组件 <good-list :list="xx"></good-list> -->
-<template>
-	<view class="good-list">
-		<view :id="'good'+good.id" class="good-li" v-for="good in list" :key="good.id">
-			<image class="good-img" :src="good.goodImg" mode="widthFix"/>
-			<view class="flex-item">
-				<view class="good-name">{{good.goodName}}</view>
-				<text class="good-price">{{good.goodPrice}} 元</text>
-				<text class="good-sold">已售{{good.goodSold}}件</text>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		props:{
-			list: {
-				type: Array,
-				default(){
-					return []
-				}
-			}
-		}
-	}
-</script>
-
-<style lang="scss">
-	.good-list{
-		background-color: #fff;
-		
-		.good-li{
-			display: flex;
-			align-items: center;
-			padding: 20upx;
-			border-bottom: 1upx solid #eee;
-			
-			.good-img{
-				width: 160upx;
-				height: 160upx;
-				margin-right: 20rpx;
-			}
-			
-			.flex-item{
-				flex: 1;
-				
-				.good-name{
-					font-size: 26upx;
-					line-height: 40upx;
-					height: 80upx;
-					margin-bottom: 20upx;
-					overflow: hidden;
-				}
-				.good-price{
-					font-size: 26upx;
-					color: red;
-				}
-				.good-sold{
-					font-size: 24upx;
-					margin-left: 16upx;
-					color: gray;
-				}
-				
-			}
-		}
-	}
-</style>

+ 318 - 0
components/master-keyboard/master-keyboard.scss

@@ -0,0 +1,318 @@
+.master_wrap{
+	width: 100%;
+	background-color: #eee;
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	z-index:10000;
+	padding-top: 10rpx;
+	padding-bottom: 20rpx;
+	.down_wrap{
+		width: 100%;
+		height: 50rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		image{
+			width: 48rpx;
+			height: 48rpx;
+		}
+	}
+	.number_next{
+		width: 100%;
+		height: 80rpx;
+		margin-top: 10rpx;
+		background-color: white;
+		border-radius: 10rpx;
+		text-align: center;
+		line-height: 80rpx;
+		box-sizing: border-box;
+		display: block;
+	}
+	.kerboard_number{
+		width: 100%;
+		display: flex;
+		justify-content: space-evenly;
+		flex-flow: wrap;
+		.number_item{
+			width: 30%;
+			height: 80rpx;
+			margin-top: 10rpx;
+			background-color: white;
+			border-radius: 10rpx;
+			text-align: center;
+			line-height: 80rpx;
+			box-sizing: border-box;
+			display: block;
+		}
+		.number_item_active{
+			width: 30%;
+			height: 80rpx;
+			margin-top: 10rpx;
+			background-color: #888;
+			border-radius: 10rpx;
+			text-align: center;
+			line-height: 80rpx;
+			box-sizing: border-box;
+			display: block;
+			color: white;
+		}
+		.number_empty{
+			background-color: #eeeeee;
+			width: 30%;
+			height: 80rpx;
+			margin-top: 10rpx;
+			border-radius: 10rpx;
+		}
+		.number_empty_active{
+			background-color: #eeeeee;
+		}
+		.number_delete{
+			width: 30%;
+			height: 80rpx;
+			margin-top: 10rpx;
+			background-color: white;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			.delete_img{
+				width: 65rpx;
+				height: 64rpx;
+			}
+		}
+		.number_delete_active{
+			width: 30%;
+			height: 80rpx;
+			margin-top: 10rpx;
+			background-color: #e64d3a;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			border-radius: 10rpx;
+			.delete_img{
+				width: 65rpx;
+				height: 64rpx;
+			}
+		}
+	}
+	
+	.keyboard_car{
+		width: 100%;
+		display: flex;
+		flex-direction: column;
+		position: relative;
+		.car_down{
+			position: absolute;
+			top: 10rpx;
+			left: 15rpx;
+			width: 48rpx;
+			height: 48rpx;
+		}
+		.tab_wrap{
+			height: 65rpx;
+			margin: 0 auto;
+			background-color: white;
+			border-radius: 20rpx;
+			display: flex;
+			padding-left: 25rpx;
+			padding-right: 25rpx;
+			image{
+				width: 48rpx;
+				height: 48rpx;
+			}
+			.tab_item{
+				height: 100%;
+				text-align: center;
+				line-height: 65rpx;
+				font-size: 26rpx;
+				margin: 0 20rpx;
+			}
+			.tab_item_active{
+				height: 100%;
+				text-align: center;
+				line-height: 65rpx;
+				font-size: 26rpx;
+				margin: 0 20rpx;
+				text-decoration: underline;
+				color: #e64d3a;
+			}
+		}
+		
+		.car_content{
+			width: 100%;
+			position: relative;
+			.car_province{
+				width: 100%;
+				display: flex;
+				justify-content: space-evenly;
+				flex-flow: wrap;
+				margin: 0;
+				.province_item{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: white;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+				}
+				.province_item_active{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: #888;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+					color: white;
+				}
+				.province_item_disable{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: #fff;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+					opacity: 0.5;
+				}
+			}
+			.car_province_1{
+				width: 100%;
+				display: flex;
+				margin: 0;
+				.province_item1{
+					margin: 0;
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: white;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+				}
+				.province_item_active{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: #888;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+					color: white;
+				}
+				.province_item_disable{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: #fff;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+					opacity: 0.5;
+				}
+			}
+			.car_latter{
+				width: 100%;
+				display: flex;
+				justify-content: space-evenly;
+				flex-flow: wrap;
+				.latter_item{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: white;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+				}
+				.province_item_active{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: #888;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+					color: white;
+				}
+				.province_item_disable{
+					width: 9.5%;
+					height: 80rpx;
+					margin-top: 10rpx;
+					background-color: #fff;
+					border-radius: 10rpx;
+					text-align: center;
+					line-height: 80rpx;
+					box-sizing: border-box;
+					display: block;
+					font-size: 28rpx;
+					font-weight: 450;
+					opacity: 0.5;
+				}
+			}
+			.car_delete{
+				width: 15%;
+				height: 80rpx;
+				margin-top: 10rpx;
+				background-color: white;
+				border-radius: 10rpx;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				position: absolute;
+				.delete_img{
+					width: 65rpx;
+					height: 64rpx;
+				}
+			}
+			.car_delete_active{
+				width: 15%;
+				height: 80rpx;
+				margin-top: 10rpx;
+				background-color: #e64d3a;
+				border-radius: 10rpx;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				position: absolute;
+				.delete_img{
+					width: 65rpx;
+					height: 64rpx;
+				}
+			}
+		}
+	}
+}

+ 331 - 0
components/master-keyboard/master-keyboard.vue

@@ -0,0 +1,331 @@
+<template>
+	<view class="master_wrap" v-show="show" hover-stop-propagation>
+		<block v-if="keyboardtype == 'number' || keyboardtype == 'digit' || keyboardtype == 'idcard'">
+			<view class="down_wrap">
+				<image src="../../static/icon_down.png" @tap.stop="handleCloseKeyboard(false)"></image>
+			</view>
+			<view class="kerboard_number">
+				<view @tap.stop="handleNumberKeyboardClick(item)" :hover-stay-time="100"
+					:class="item== '-1' ? keyboardtype == 'number' ?  'number_empty' :'number_item' : item=='-2' ? 'number_delete' : 'number_item' "
+					:hover-class="item== '-1' ?  keyboardtype == 'number' ?  'number_empty_active' : 'number_item_active' : item=='-2' ? 'number_delete_active' : 'number_item_active'"
+					v-for="(item,index) in  randomNumberArr" :key="index">
+					<block v-if="item == '-1'">
+						<view v-if="keyboardtype == 'digit'">
+							·
+						</view>
+						<view v-else-if=" keyboardtype ==  'idcard'">
+							X
+						</view>
+					</block>
+					<block v-else-if="item == '-2'">
+						<image class="delete_img" src="../../static/icon_delete.png"></image>
+					</block>
+					<block v-else>
+						{{item}}
+					</block>
+				</view>
+			</view>
+			<view class="next-btn">
+				<view class='number_next' @click="nextBtnClick(0)">上一项</view>
+				<view class='number_next' @click="nextBtnClick(1)">下一项</view>
+			</view>
+		</block>
+		<block v-else-if="keyboardtype == 'car'">
+			<view class="keyboard_car">
+				<image @tap.stop="handleCloseKeyboard(false)" class="car_down" src="../../static/icon_down.png"></image>
+				<view class="tab_wrap">
+					<view @tap.stop="handleCarTabItemClick(index)"
+						:class=" carType === index ?'tab_item_active' : 'tab_item'" hover-class="tab_item_active"
+						v-for="(item,index) in carTabArr" :key="index">
+						{{item}}
+					</view>
+				</view>
+				<view class="car_content">
+					<block v-if="carType === 0">
+						<view class="car_province">
+							<view @tap.stop="handleCarKerboardClick(item)"
+								:class="computedDefaultValueLength ===0 ?  'province_item' :'province_item_disable'"
+								:hover-class="computedDefaultValueLength ===0 ? 'province_item_active' : 'none'"
+								:hover-stay-time="100" v-for="(item,index) in sliceProvinceArr" :key="index">
+								{{item}}
+							</view>
+						</view>
+						<view class="car_province_1">
+							<view @tap.stop="handleCarKerboardClick(item)"
+								:class=" (formatCarProvinceFirst(item) === -1 && computedDefaultValueLength ===0 )  ? 'province_item1' :
+								 ((newCar && computedDefaultValueLength ===7 && formatCarProvinceFirst(item) !== -1) || 
+								 (!newCar && computedDefaultValueLength ===6 && formatCarProvinceFirst(item) !== -1) ) ? 'province_item1' :  'province_item_disable'"
+								:hover-class=" (formatCarProvinceFirst(item) === -1 && computedDefaultValueLength ===0) ? 'province_item_active' : 'none'"
+								:hover-stay-time="100" :style="{'margin-left' : computeItemSpace + '%'}"
+								v-for="(item,index) in sliceSecondProvinceArr" :key="index">
+								{{item}}
+							</view>
+						</view>
+					</block>
+					<block v-else="carType === 1">
+						<view class="car_latter">
+							<view @tap.stop="handleCarKerboardClick(item)"
+								:class=" (computedDefaultValueLength ===1 && formatCarProvinceSecond(item) >-1 || computedDefaultValueLength ===0) ? 'province_item_disable' : 'latter_item'"
+								:hover-class=" (computedDefaultValueLength ===1 && formatCarProvinceSecond(item) >-1 || computedDefaultValueLength ===0) ? 'none' : 'province_item_active'"
+								:hover-stay-time="100" v-for="(item,index) in sliceLatterArr" :key="index">
+								<text>{{item}}</text>
+							</view>
+						</view>
+						<view class="car_province_1">
+							<view @tap.stop="handleCarKerboardClick(item)"
+								:class=" (computedDefaultValueLength ===1 && formatCarProvinceSecond(item) >-1 || computedDefaultValueLength ===0)  ? 'province_item_disable' : 'province_item1'"
+								:hover-class=" (computedDefaultValueLength ===1 && formatCarProvinceSecond(item) >-1 || computedDefaultValueLength ===0) ? 'none' : 'province_item_active'"
+								:hover-stay-time="100" :style="{'margin-left' : computeItemSpace + '%'}"
+								v-for="(item,index) in sliceSecondLatterArr" :key="index">
+								{{item}}
+							</view>
+						</view>
+					</block>
+					<view @tap.stop="handleCarKerboardDeleteClick" class="car_delete" hover-class="car_delete_active"
+						:hover-stay-time="100"
+						:style="{'top':computeDeleteTop + 'rpx','right' :computeItemSpace + '%' }">
+						<image class="delete_img" src="../../static/icon_delete.png"></image>
+					</view>
+				</view>
+			</view>
+		</block>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "master-keyboard",
+		props: {
+		fatherMethod: {
+				type: Function,
+				default: null
+			  },
+			keyboardtype: {
+				type: String,
+				default: 'number' // number=数字键盘 digit=带小数点的数字键盘  idcard=身份证号键盘  car=车牌号键盘
+			},
+			defaultValue: {
+				type: String,
+				default: ''
+			},
+			newCar: {
+				type: Boolean,
+				default: false
+			},
+			randomNumber: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				numberArr: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
+				carProvinceArr: ['京', '津', '渝', '沪', '冀', '晋', '辽', '吉', '黑', '苏', '浙', '皖', '闽', '赣', '鲁', '豫',
+					'鳄', '湘', '粤', '琼', '川', '贵', '云', '陕', '甘', '青', '蒙', '桂', '宁', '新', '藏', '使',
+					'领', '警', '学', '港', '澳'
+				],
+				carLatterArr: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+					'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
+					'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
+				],
+				carTabArr: ['省份', '字母'],
+				carType: 0,
+				show: false,
+			};
+		},
+		computed: {
+			sliceProvinceArr: function() {
+				return this.carProvinceArr.slice(0, 30)
+			},
+			sliceSecondProvinceArr: function() {
+				return this.carProvinceArr.slice(30, this.carProvinceArr.length)
+			},
+			sliceLatterArr: function() {
+				return this.carLatterArr.slice(0, 30)
+			},
+			sliceSecondLatterArr: function() {
+				return this.carLatterArr.slice(30, this.carLatterArr.length)
+			},
+			computeDeleteTop: function() {
+				return 80 * 3 + 10 * 3
+			},
+			computeItemSpace: function() {
+				return (1 - 0.095 * 10) / 11 * 100
+			},
+			computedDefaultValueLength: function() {
+				return this.$props.defaultValue.length
+			},
+			randomNumberArr: function() {
+				if(this.$props.randomNumber){
+					this.numberArr.sort(function() {
+						return 0.5 - Math.random()
+					})
+				}
+				const size = this.numberArr.length
+				this.numberArr.splice(size - 1, 0, "-1")
+				this.numberArr.push("-2")
+				return this.numberArr
+			}
+		},
+		watch: {
+			show: function(value) {
+
+			}
+		},
+		onLoad() {},
+		methods: {
+			nextBtnClick(type){
+				let that = this
+				if (this.fatherMethod) {
+				          this.fatherMethod(type);
+					}
+			},
+			formatCarProvinceFirst(value) {
+				const list = ['使', '领', '警', '学', '港', '澳', ]
+				return list.indexOf(value)
+			},
+			formatCarProvinceSecond(value) {
+				const list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
+				return list.indexOf(value)
+			},
+			handleCloseKeyboard() {
+				this.open(false)
+			},
+			open(value) {
+				this.show = value
+				if(!value&&this.keyboardtype == 'car'){
+					this.carType=0
+				}
+			},
+			//车牌tab点击事件
+			handleCarTabItemClick(index) {
+				this.carType = index
+			},
+			//车牌键盘点击事件
+			handleCarKerboardClick(e) {
+				const keyValue = e
+				let value = this.$props.defaultValue
+				if (/^[\u4e00-\u9fa5]*$/.test(value) && value.length >= 2) {
+					value = ''
+				}
+				var pattern = new RegExp("[\u4E00-\u9FA5]+");
+				var pattern2 = new RegExp("[A-Za-z]+");
+				var pattern3 = new RegExp("[0-9]+");
+
+				if (value.length == 0) {
+					if (!pattern.test(keyValue) || this.formatCarProvinceFirst(keyValue) !== -1) {
+						return
+					}
+					this.carType = 1
+				} else if (value.length == 1) {
+					if (!pattern2.test(keyValue)) {
+						return
+					}
+				} else {
+					if (value.length === (this.$props.newCar ? 7 : 6) && pattern.test(keyValue) && this
+						.formatCarProvinceFirst(keyValue) == -1) {
+						return
+					}
+					if (pattern.test(keyValue) && value.length !== (this.$props.newCar ? 7 : 6)) {
+						return
+					}
+				}
+
+				if (value.length < 7 && !this.$props.newCar) {
+					this.$emit('keyboardClick', {
+						value: value + keyValue
+					})
+				}
+				if (value.length < 8 && this.$props.newCar) {
+					this.$emit('keyboardClick', {
+						value: value + keyValue
+					})
+				}
+			},
+			//车牌键盘删除事件
+			handleCarKerboardDeleteClick() {
+				let deleteValue = this.$props.defaultValue
+				if (deleteValue == '' || (/^[\u4e00-\u9fa5]*$/.test(deleteValue) && deleteValue.length !== 1)) {
+					return
+				}
+				if (deleteValue.length > 0) {
+					let count = deleteValue.length
+					this.$emit('keyboardClick', {
+						value: deleteValue.substr(0, count - 1)
+					})
+				}
+			},
+			//数字键盘点击事件
+			handleNumberKeyboardClick(e) {
+				const keyValue = e
+				if (this.$props.keyboardtype == 'number' || this.$props.keyboardtype == 'digit' || this.$props
+					.keyboardtype == 'idcard') {
+					switch (keyValue) {
+						case '-1':
+							if (this.$props.keyboardtype == 'number' || this.$props.defaultValue == '') {
+								return
+							}
+							let value = this.$props.defaultValue
+							if (/^[\u4e00-\u9fa5]*$/.test(value) || value.indexOf('.') > -1 || value.indexOf('X') > -1) {
+								return
+							}
+							if (this.$props.keyboardtype == 'idcard') {
+								if (value.length === 17) {
+									this.$emit('keyboardClick', {
+										value: value + 'X'
+									})
+								}
+							}
+							if (this.$props.keyboardtype == 'digit') {
+								this.$emit('keyboardClick', {
+									value: value + '.'
+								})
+							}
+							break
+						case '-2':
+							let deleteValue = this.$props.defaultValue
+							if (deleteValue == '' || /^[\u4e00-\u9fa5]*$/.test(deleteValue)) {
+								return
+							}
+							if (deleteValue.length > 0) {
+								let count = deleteValue.length
+								this.$emit('keyboardClick', {
+									value: deleteValue.substr(0, count - 1)
+								})
+							}
+							break
+						default:
+							let initValue = this.$props.defaultValue
+							if (/^[\u4e00-\u9fa5]*$/.test(initValue)) {
+								initValue = ''
+							}
+							if (this.$props.keyboardtype == 'idcard') {
+								if (initValue.length < 18) {
+									this.$emit('keyboardClick', {
+										value: initValue + keyValue
+									})
+								}
+								return
+							}
+							this.$emit('keyboardClick', {
+								value: initValue + keyValue
+							})
+							break
+					}
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	@import './master-keyboard.scss';
+	.next-btn{
+		display: flex;
+		justify-content: space-evenly;
+		.number_next{
+			width: 45%;
+		}
+		
+		}
+</style>

+ 205 - 0
components/me-tabs/me-tabs.vue

@@ -0,0 +1,205 @@
+<!-- tab组件: <me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs> -->
+<template>
+	<view class="me-tabs" :class="{'tabs-fixed': fixed}" :style="{height: tabHeightVal, top:topFixed}">
+		<scroll-view v-if="tabs.length" :id="viewId" :scroll-left="scrollLeft" scroll-x scroll-with-animation :scroll-animation-duration="300">
+			<view class="tabs-item" :class="{'tabs-flex':!isScroll, 'tabs-scroll':isScroll}">
+				<!-- tab -->
+				<view class="tab-item" :style="{height: tabHeightVal, 'line-height':tabHeightVal}" v-for="(tab, i) in tabs" :class="{'active': value===i}" :key="i" @click="tabClick(i)">
+					{{getTabName(tab)}}
+				</view>
+				<!-- 下划线 -->
+				<!-- <view class="tabs-line" :style="{left:lineLeft}"></view> -->
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:{
+			tabs: { // 支持格式: ['全部', '待付款'] 或 [{name:'全部'}, {name:'待付款'}]
+				type: Array,
+				default(){
+					return []
+				}
+			},
+			nameKey: { // 取name的字段
+				type: String,
+				default: 'name'
+			},
+			value: { // 当前显示的下标 (使用v-model语法糖: 1.props需为value; 2.需回调input事件)
+				type: [String, Number],
+				default: 0
+			},
+			fixed: Boolean, // 是否悬浮,默认false
+			tabWidth: Number, // 每个tab的宽度,默认不设置值,为flex平均分配; 如果指定宽度,则不使用flex,每个tab居左,超过则水平滑动(单位默认rpx)
+			height: { // 高度,单位rpx
+				type: Number,
+				default: 64
+			},
+			top: { // 顶部偏移的距离,默认单位rpx (当fixed=true时,已加上windowTop)
+				type: Number,
+				default: 0
+			}
+		},
+		data() {
+			return {
+				viewId: 'id_' + Math.random().toString(36).substr(2,16),
+				scrollLeft: 0,
+				windowWidth: 0,
+				windowTop: 0
+			}
+		},
+		computed: {
+			isScroll(){
+				return this.tabWidth && this.tabs.length // 指定了tabWidth的宽度,则支持水平滑动
+			},
+			tabHeightPx(){
+				return uni.upx2px(this.height)
+			},
+			tabHeightVal(){
+				return this.tabHeightPx+'px'
+			},
+			tabWidthPx(){
+				return uni.upx2px(this.tabWidth)
+			},
+			tabWidthVal(){
+				// return this.isScroll ? this.tabWidthPx+'px' : ''
+			},
+			lineLeft() {
+				if (this.isScroll) {
+					return this.tabWidthPx * this.value + this.tabWidthPx/2 + 'px' // 需转为px (用rpx的话iOS真机显示有误差)
+				} else{
+					return 100/this.tabs.length*(this.value + 1) - 100/(this.tabs.length*2) + '%'
+				}
+			},
+			topFixed(){
+				return this.fixed ? this.windowTop + uni.upx2px(this.top) + 'px' : 0
+			},
+			topMargin(){
+				return this.fixed ? 0 : this.top + 'rpx'
+			}
+		},
+		watch: {
+			tabs() {
+				this.warpWidth = null; // 重新计算容器宽度
+				this.scrollCenter(); // 水平滚动到中间
+			},
+			value() {
+				this.scrollCenter(); // 水平滚动到中间
+			}
+		},
+		created() {
+			let sys = uni.getSystemInfoSync();
+			this.windowWidth = sys.windowWidth
+			this.windowTop = sys.windowTop
+		},
+		mounted() {
+			this.scrollCenter() // 滚动到当前下标
+		},
+		methods: {
+			getTabName(tab){
+				return typeof tab === "object" ? tab[this.nameKey] : tab
+			},
+			tabClick(i){
+				if(this.value!=i){
+					this.$emit("input",i);
+					this.$emit("change",i);
+				}
+			},
+			async scrollCenter(){
+				if(!this.isScroll) return;
+				if(!this.warpWidth){ // tabs容器的宽度
+					let rect = await this.initWarpRect()
+					this.warpWidth = rect ? rect.width : this.windowWidth; // 某些情况下取不到宽度,暂时取屏幕宽度
+				}
+				let tabLeft = this.tabWidthPx * this.value + this.tabWidthPx/2; // 当前tab中心点到左边的距离
+				let diff = tabLeft - this.warpWidth/2 // 如果超过tabs容器的一半,则滚动差值
+				this.scrollLeft = diff;
+				// #ifdef MP-TOUTIAO
+				this.scrollTimer && clearTimeout(this.scrollTimer)
+				this.scrollTimer = setTimeout(()=>{ // 字节跳动小程序,需延时再次设置scrollLeft,否则tab切换跨度较大时不生效
+					this.scrollLeft = Math.ceil(diff)
+				},400)
+				// #endif
+			},
+			initWarpRect(){
+				return new Promise(resolve=>{
+					setTimeout(()=>{ // 延时确保dom已渲染, 不使用$nextclick
+						let query = uni.createSelectorQuery();
+						// #ifndef MP-ALIPAY
+						query = query.in(this) // 支付宝小程序不支持in(this),而字节跳动小程序必须写in(this), 否则都取不到值
+						// #endif
+						query.select('#'+this.viewId).boundingClientRect(data => {
+							resolve(data)
+						}).exec();
+					},20)
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.me-tabs{
+		position: relative;
+		font-size: 24rpx;
+		background-color: #fff;
+		border-bottom: 1rpx solid #eee;
+		box-sizing: border-box;
+		overflow-y: hidden;
+		background-color: #fff;
+		display: flex;
+		justify-content: space-around;
+		&.tabs-fixed{
+			z-index: 990;
+			position: fixed;
+			left: 0;
+			width: 100%;
+		}
+		
+		.tabs-item{
+			position: relative;
+			white-space: nowrap;
+			padding-bottom: 30rpx; // 撑开高度,再配合me-tabs的overflow-y: hidden,以达到隐藏滚动条的目的
+			box-sizing: border-box;
+			.tab-item{
+				position: relative;
+				text-align: center;
+				box-sizing: border-box;
+				width: 25%;
+				&.active{
+					font-weight: bold;
+					color: red;
+				}
+			}
+		}
+		
+		// 平分的方式显示item
+		.tabs-flex{
+			display: flex;
+			.tab-item{
+				flex: 1;
+			}
+		}
+		// 居左显示item,支持水平滑动
+		.tabs-scroll{
+			.tab-item{
+				display: inline-block;
+			}
+		}
+		
+		// 选中tab的线
+		.tabs-line{
+			z-index: 1;
+			position: absolute;
+			bottom: 30rpx; // 至少与.tabs-item的padding-bottom一致,才能保证在底部边缘
+			width: 50rpx;
+			height: 6rpx;
+			transform: translateX(-50%);
+			border-radius: 4rpx;
+			transition: left .3s;
+			background: red;
+		}
+	}
+</style>

+ 143 - 0
components/ossutil/base64.js

@@ -0,0 +1,143 @@
+
+var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var base64DecodeChars = new Array(
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+    -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
+function encode(str) {
+    var out, i, len;
+    var c1, c2, c3;
+    len = str.length;
+    i = 0;
+    out = "";
+    while (i < len) {
+        c1 = str.charCodeAt(i++) & 0xff;
+        if (i == len) {
+            out += base64EncodeChars.charAt(c1 >> 2);
+            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
+            out += "==";
+            break;
+        }
+        c2 = str.charCodeAt(i++);
+        if (i == len) {
+            out += base64EncodeChars.charAt(c1 >> 2);
+            out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
+            out += "=";
+            break;
+        }
+        c3 = str.charCodeAt(i++);
+        out += base64EncodeChars.charAt(c1 >> 2);
+        out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
+        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
+        out += base64EncodeChars.charAt(c3 & 0x3F);
+    }
+    return out;
+}
+function decode(str) {
+    var c1, c2, c3, c4;
+    var i, len, out;
+    len = str.length;
+    i = 0;
+    out = "";
+    while (i < len) {
+        /* c1 */
+        do {
+            c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+        } while (i < len && c1 == -1);
+        if (c1 == -1)
+            break;
+        /* c2 */
+        do {
+            c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+        } while (i < len && c2 == -1);
+        if (c2 == -1)
+            break;
+        out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
+        /* c3 */
+        do {
+            c3 = str.charCodeAt(i++) & 0xff;
+            if (c3 == 61)
+                return out;
+            c3 = base64DecodeChars[c3];
+        } while (i < len && c3 == -1);
+        if (c3 == -1)
+            break;
+        out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
+        /* c4 */
+        do {
+            c4 = str.charCodeAt(i++) & 0xff;
+            if (c4 == 61)
+                return out;
+            c4 = base64DecodeChars[c4];
+        } while (i < len && c4 == -1);
+        if (c4 == -1)
+            break;
+        out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
+    }
+    return out;
+}
+
+
+function utf16to8(str) {
+    var out, i, len, c;
+    out = "";
+    len = str.length;
+    for (i = 0; i < len; i++) {
+        c = str.charCodeAt(i);
+        if ((c >= 0x0001) && (c <= 0x007F)) {
+            out += str.charAt(i);
+        } else if (c > 0x07FF) {
+            out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
+            out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
+            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
+        } else {
+            out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
+            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
+        }
+    }
+    return out;
+}
+function utf8to16(str) {
+    var out, i, len, c;
+    var char2, char3;
+    out = "";
+    len = str.length;
+    i = 0;
+    while (i < len) {
+        c = str.charCodeAt(i++);
+        switch (c >> 4) {
+            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+                // 0xxxxxxx
+                out += str.charAt(i - 1);
+                break;
+            case 12: case 13:
+                // 110x xxxx 10xx xxxx
+                char2 = str.charCodeAt(i++);
+                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
+                break;
+            case 14:
+                // 1110 xxxx 10xx xxxx 10xx xxxx
+                char2 = str.charCodeAt(i++);
+                char3 = str.charCodeAt(i++);
+                out += String.fromCharCode(((c & 0x0F) << 12) |
+                    ((char2 & 0x3F) << 6) |
+                    ((char3 & 0x3F) << 0));
+                break;
+        }
+    }
+    return out;
+}
+
+
+module.exports = {
+    encode: encode,
+    decode: decode,
+    utf16to8: utf16to8,
+    utf8to16: utf8to16
+}

+ 9 - 0
components/ossutil/config.js

@@ -0,0 +1,9 @@
+var fileHost = 'https://taohaoliang.oss-cn-beijing.aliyuncs.com';//你的阿里云地址最后面跟上一个/   在你当前小程序的后台的uploadFile 合法域名也要配上这个域名
+var config = {
+   //aliyun OSS config
+  uploadImageUrl: `${fileHost}`, // 默认存在根目录,可根据需求改
+  AccessKeySecret: 'FpClTp4OVrRRtHEfi3lBOWUoLxKieW',        // AccessKeySecret 去你的阿里云上控制台上找
+  OSSAccessKeyId: 'LTAI4G9c14PgKvM23WZ9zrpc',         // AccessKeyId 去你的阿里云上控制台上找
+   timeout: 87600 //这个是上传文件时Policy的失效时间
+};
+module.exports = config

+ 178 - 0
components/ossutil/crypto.js

@@ -0,0 +1,178 @@
+const Crypto = {};
+
+(function(){
+
+var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+
+// Crypto utilities
+var util = Crypto.util = {
+
+	// Bit-wise rotate left
+	rotl: function (n, b) {
+		return (n << b) | (n >>> (32 - b));
+	},
+
+	// Bit-wise rotate right
+	rotr: function (n, b) {
+		return (n << (32 - b)) | (n >>> b);
+	},
+
+	// Swap big-endian to little-endian and vice versa
+	endian: function (n) {
+
+		// If number given, swap endian
+		if (n.constructor == Number) {
+			return util.rotl(n,  8) & 0x00FF00FF |
+			       util.rotl(n, 24) & 0xFF00FF00;
+		}
+
+		// Else, assume array and swap all items
+		for (var i = 0; i < n.length; i++)
+			n[i] = util.endian(n[i]);
+		return n;
+
+	},
+
+	// Generate an array of any length of random bytes
+	randomBytes: function (n) {
+		for (var bytes = []; n > 0; n--)
+			bytes.push(Math.floor(Math.random() * 256));
+		return bytes;
+	},
+
+	// Convert a string to a byte array
+	stringToBytes: function (str) {
+		var bytes = [];
+		for (var i = 0; i < str.length; i++)
+			bytes.push(str.charCodeAt(i));
+		return bytes;
+	},
+
+	// Convert a byte array to a string
+	bytesToString: function (bytes) {
+		var str = [];
+		for (var i = 0; i < bytes.length; i++)
+			str.push(String.fromCharCode(bytes[i]));
+		return str.join("");
+	},
+
+	// Convert a string to big-endian 32-bit words
+	stringToWords: function (str) {
+		var words = [];
+		for (var c = 0, b = 0; c < str.length; c++, b += 8)
+			words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
+		return words;
+	},
+
+	// Convert a byte array to big-endian 32-bits words
+	bytesToWords: function (bytes) {
+		var words = [];
+		for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
+			words[b >>> 5] |= bytes[i] << (24 - b % 32);
+		return words;
+	},
+
+	// Convert big-endian 32-bit words to a byte array
+	wordsToBytes: function (words) {
+		var bytes = [];
+		for (var b = 0; b < words.length * 32; b += 8)
+			bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
+		return bytes;
+	},
+
+	// Convert a byte array to a hex string
+	bytesToHex: function (bytes) {
+		var hex = [];
+		for (var i = 0; i < bytes.length; i++) {
+			hex.push((bytes[i] >>> 4).toString(16));
+			hex.push((bytes[i] & 0xF).toString(16));
+		}
+		return hex.join("");
+	},
+
+	// Convert a hex string to a byte array
+	hexToBytes: function (hex) {
+		var bytes = [];
+		for (var c = 0; c < hex.length; c += 2)
+			bytes.push(parseInt(hex.substr(c, 2), 16));
+		return bytes;
+	},
+
+	// Convert a byte array to a base-64 string
+	bytesToBase64: function (bytes) {
+
+		// Use browser-native function if it exists
+		// if (typeof btoa == "function") return btoa(util.bytesToString(bytes));
+
+		var base64 = [],
+		    overflow;
+
+		for (var i = 0; i < bytes.length; i++) {
+			switch (i % 3) {
+				case 0:
+					base64.push(base64map.charAt(bytes[i] >>> 2));
+					overflow = (bytes[i] & 0x3) << 4;
+					break;
+				case 1:
+					base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));
+					overflow = (bytes[i] & 0xF) << 2;
+					break;
+				case 2:
+					base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));
+					base64.push(base64map.charAt(bytes[i] & 0x3F));
+					overflow = -1;
+			}
+		}
+
+		// Encode overflow bits, if there are any
+		if (overflow != undefined && overflow != -1)
+			base64.push(base64map.charAt(overflow));
+
+		// Add padding
+		while (base64.length % 4 != 0) base64.push("=");
+
+		return base64.join("");
+
+	},
+
+	// Convert a base-64 string to a byte array
+	base64ToBytes: function (base64) {
+
+		// Use browser-native function if it exists
+		if (typeof atob == "function") return util.stringToBytes(atob(base64));
+
+		// Remove non-base-64 characters
+		base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
+
+		var bytes = [];
+
+		for (var i = 0; i < base64.length; i++) {
+			switch (i % 4) {
+				case 1:
+					bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |
+					           (base64map.indexOf(base64.charAt(i)) >>> 4));
+					break;
+				case 2:
+					bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |
+					           (base64map.indexOf(base64.charAt(i)) >>> 2));
+					break;
+				case 3:
+					bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |
+					           (base64map.indexOf(base64.charAt(i))));
+					break;
+			}
+		}
+
+		return bytes;
+
+	}
+
+};
+
+// Crypto mode namespace
+Crypto.mode = {};
+
+})();
+
+module.exports = Crypto;

+ 34 - 0
components/ossutil/hmac.js

@@ -0,0 +1,34 @@
+const Crypto = require('./crypto.js');
+
+(function(){
+
+// Shortcut
+var util = Crypto.util;
+
+Crypto.HMAC = function (hasher, message, key, options) {
+
+	// Allow arbitrary length keys
+	key = key.length > hasher._blocksize * 4 ?
+	      hasher(key, { asBytes: true }) :
+	      util.stringToBytes(key);
+
+	// XOR keys with pad constants
+	var okey = key,
+	    ikey = key.slice(0);
+	for (var i = 0; i < hasher._blocksize * 4; i++) {
+		okey[i] ^= 0x5C;
+		ikey[i] ^= 0x36;
+	}
+
+	var hmacbytes = hasher(util.bytesToString(okey) +
+	                       hasher(util.bytesToString(ikey) + message, { asString: true }),
+	                       { asBytes: true });
+	return options && options.asBytes ? hmacbytes :
+	       options && options.asString ? util.bytesToString(hmacbytes) :
+	       util.bytesToHex(hmacbytes);
+
+};
+
+})();
+
+module.exports = Crypto;

+ 79 - 0
components/ossutil/sha1.js

@@ -0,0 +1,79 @@
+const Crypto = require('./crypto.js');
+
+(function(){
+
+// Shortcut
+var util = Crypto.util;
+
+// Public API
+var SHA1 = Crypto.SHA1 = function (message, options) {
+	var digestbytes = util.wordsToBytes(SHA1._sha1(message));
+	return options && options.asBytes ? digestbytes :
+	       options && options.asString ? util.bytesToString(digestbytes) :
+	       util.bytesToHex(digestbytes);
+};
+
+// The core
+SHA1._sha1 = function (message) {
+
+	var m  = util.stringToWords(message),
+	    l  = message.length * 8,
+	    w  =  [],
+	    H0 =  1732584193,
+	    H1 = -271733879,
+	    H2 = -1732584194,
+	    H3 =  271733878,
+	    H4 = -1009589776;
+
+	// Padding
+	m[l >> 5] |= 0x80 << (24 - l % 32);
+	m[((l + 64 >>> 9) << 4) + 15] = l;
+
+	for (var i = 0; i < m.length; i += 16) {
+
+		var a = H0,
+		    b = H1,
+		    c = H2,
+		    d = H3,
+		    e = H4;
+
+		for (var j = 0; j < 80; j++) {
+
+			if (j < 16) w[j] = m[i + j];
+			else {
+				var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
+				w[j] = (n << 1) | (n >>> 31);
+			}
+
+			var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
+			         j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
+			         j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
+			         j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
+			                  (H1 ^ H2 ^ H3) - 899497514);
+
+			H4 =  H3;
+			H3 =  H2;
+			H2 = (H1 << 30) | (H1 >>> 2);
+			H1 =  H0;
+			H0 =  t;
+
+		}
+
+		H0 += a;
+		H1 += b;
+		H2 += c;
+		H3 += d;
+		H4 += e;
+
+	}
+
+	return [H0, H1, H2, H3, H4];
+
+};
+
+// Package private blocksize
+SHA1._blocksize = 16;
+
+})();
+
+module.exports = Crypto;

+ 394 - 0
components/ossutil/signature.js

@@ -0,0 +1,394 @@
+class Handwriting {
+  // 内置数据
+  ctx = '';
+  canvasWidth = 300;
+  canvasHeight = 900;
+  linePrack = []; //划线轨迹 ; 生成线条的实际点
+  currentLine = [];
+  transparent = 1; // 透明度
+  pressure = 0.5; // 默认压力
+  smoothness = 100; //顺滑度,用60的距离来计算速度
+  lineSize = 1.5; // 笔记倍数
+  lineMin = 0.5; // 最小笔画半径
+  lineMax = 2; // 最大笔画半径
+  currentPoint = {};
+  firstTouch = true; // 第一次触发
+  radius = 1; //画圆的半径
+  cutArea = {
+    top: 0,
+    right: 0,
+    bottom: 0,
+    left: 0
+  }; //裁剪区域
+  lastPoint = 0;
+  chirography = []; //笔迹
+  startY = 0;
+  deltaY = 0;
+  startValue = 0;
+  constructor(opts) {
+    this.lineColor = opts.lineColor || '#1A1A1A' // 颜色
+    this.slideValue = opts.slideValue || 50
+		this.canvasName = opts.canvasName || 'handWriting'
+    this.init()
+  }
+  init() {
+    this.ctx = uni.createCanvasContext(this.canvasName)
+    var query = uni.createSelectorQuery();
+    query.select('.handCenter').boundingClientRect(rect => {
+      console.log(rect)
+	  if(rect){
+		 this.canvasWidth = rect.width;
+		 this.canvasHeight = rect.height; 
+	  }
+      
+    }).exec();
+    this.selectSlideValue(this.slideValue);
+  }
+
+  // 笔迹开始
+  uploadScaleStart(event) {
+		let e = event.mp
+    if (e.type != 'touchstart') return false;
+    this.ctx.setFillStyle(this.lineColor); // 初始线条设置颜色
+    this.ctx.setGlobalAlpha(this.transparent); // 设置半透明
+    this.currentPoint = {
+      x: e.touches[0].x,
+      y: e.touches[0].y
+    }
+    this.currentLine.unshift({
+      time: new Date().getTime(),
+      dis: 0,
+      x: this.currentPoint.x,
+      y: this.currentPoint.y
+    })
+    if (this.firstTouch) {
+      this.cutArea = {
+        top: this.currentPoint.y,
+        right: this.currentPoint.x,
+        bottom: this.currentPoint.y,
+        left: this.currentPoint.x
+      }
+      this.firstTouch = false
+    }
+    this.pointToLine(this.currentLine);
+  }
+  // 笔迹移动
+  uploadScaleMove(event) {
+		let e = event.mp
+    if (e.type != 'touchmove') return false;
+    if (e.cancelable) {
+      // 判断默认行为是否已经被禁用
+      if (!e.defaultPrevented) {
+        e.preventDefault();
+      }
+    }
+    let point = {
+      x: e.touches[0].x,
+      y: e.touches[0].y
+    }
+    //测试裁剪
+    if (point.y < this.cutArea.top) {
+      this.cutArea.top = point.y;
+    }
+    if (point.y < 0) this.cutArea.top = 0;
+
+    if (point.x > this.cutArea.right) {
+      this.cutArea.right = point.x;
+    }
+    if (this.canvasWidth - point.x <= 0) {
+      this.cutArea.right = this.canvasWidth;
+    }
+    if (point.y > this.cutArea.bottom) {
+      this.cutArea.bottom = point.y;
+    }
+    if (this.canvasHeight - point.y <= 0) {
+      this.cutArea.bottom = this.canvasHeight;
+    }
+    if (point.x < this.cutArea.left) {
+      this.cutArea.left = point.x;
+    }
+    if (point.x < 0) this.cutArea.left = 0;
+
+    this.lastPoint = this.currentPoint;
+    this.currentPoint = point
+    this.currentLine.unshift({
+      time: new Date().getTime(),
+      dis: this.distance(this.currentPoint, this.lastPoint, 'move'),
+      x: point.x,
+      y: point.y
+    })
+    this.pointToLine(this.currentLine);
+  }
+  // 笔迹结束
+  uploadScaleEnd(event) {
+		let e = event.mp
+    if (e.type != 'touchend') return 0;
+    let point = {
+      x: e.changedTouches[0].x,
+      y: e.changedTouches[0].y
+    }
+		
+    this.lastPoint = this.currentPoint;
+    this.currentPoint = point
+    this.currentLine.unshift({
+      time: new Date().getTime(),
+      dis: this.distance(this.currentPoint, this.lastPoint, 'end'),
+      x: point.x,
+      y: point.y
+    })
+    if (this.currentLine.length > 2) {
+      var info = (this.currentLine[0].time - this.currentLine[this.currentLine.length - 1].time) / this.currentLine.length;
+      //$("#info").text(info.toFixed(2));
+    }
+    //一笔结束,保存笔迹的坐标点,清空,当前笔迹
+    //增加判断是否在手写区域;
+    this.pointToLine(this.currentLine);
+    var currentChirography = {
+      lineSize: this.lineSize,
+      lineColor: this.lineColor
+    };
+    this.chirography.unshift(currentChirography);
+    this.linePrack.unshift(this.currentLine);
+    this.currentLine = []
+  }
+  retDraw() {
+    this.ctx.clearRect(0, 0, 700, 730)
+    this.ctx.draw()
+  }
+
+  //画两点之间的线条;参数为:line,会绘制最近的开始的两个点;
+  pointToLine(line) {
+    this.calcBethelLine(line);
+    // this.calcBethelLine1(line);
+    return;
+  }
+  //计算插值的方式;
+  calcBethelLine(line) {
+    if (line.length <= 1) {
+      line[0].r = this.radius;
+      return;
+    }
+    let x0, x1, x2, y0, y1, y2, r0, r1, r2, len, lastRadius, dis = 0,
+      time = 0,
+      curveValue = 0.5;
+    if (line.length <= 2) {
+      x0 = line[1].x
+      y0 = line[1].y
+      x2 = line[1].x + (line[0].x - line[1].x) * curveValue;
+      y2 = line[1].y + (line[0].y - line[1].y) * curveValue;
+      //x2 = line[1].x;
+      //y2 = line[1].y;
+      x1 = x0 + (x2 - x0) * curveValue;
+      y1 = y0 + (y2 - y0) * curveValue;;
+
+    } else {
+      x0 = line[2].x + (line[1].x - line[2].x) * curveValue;
+      y0 = line[2].y + (line[1].y - line[2].y) * curveValue;
+      x1 = line[1].x;
+      y1 = line[1].y;
+      x2 = x1 + (line[0].x - x1) * curveValue;
+      y2 = y1 + (line[0].y - y1) * curveValue;
+    }
+    //从计算公式看,三个点分别是(x0,y0),(x1,y1),(x2,y2) ;(x1,y1)这个是控制点,控制点不会落在曲线上;实际上,这个点还会手写获取的实际点,却落在曲线上
+    len = this.distance({
+      x: x2,
+      y: y2
+    }, {
+      x: x0,
+      y: y0
+    }, 'calc');
+    lastRadius = this.radius;
+    for (let n = 0; n < line.length - 1; n++) {
+      dis += line[n].dis;
+      time += line[n].time - line[n + 1].time;
+      if (dis > this.smoothness) break;
+    }
+    this.radius = Math.min(time / len * this.pressure + this.lineMin, this.lineMax) * this.lineSize
+    line[0].r = this.radius;
+    //计算笔迹半径;
+    if (line.length <= 2) {
+      r0 = (lastRadius + this.radius) / 2;
+      r1 = r0;
+      r2 = r1;
+      //return;
+    } else {
+      r0 = (line[2].r + line[1].r) / 2;
+      r1 = line[1].r;
+      r2 = (line[1].r + line[0].r) / 2;
+    }
+    let n = 5;
+    let point = [];
+    for (let i = 0; i < n; i++) {
+      let t = i / (n - 1);
+      let x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2;
+      let y = (1 - t) * (1 - t) * y0 + 2 * t * (1 - t) * y1 + t * t * y2;
+      let r = lastRadius + (this.radius - lastRadius) / n * i;
+      point.push({
+        x: x,
+        y: y,
+        r: r
+      });
+      if (point.length == 3) {
+        let a = this.ctaCalc(point[0].x, point[0].y, point[0].r, point[1].x, point[1].y, point[1].r, point[2].x, point[2].y, point[2].r);
+        a[0].color = this.lineColor;
+        this.bethelDraw(a, 1);
+        point = [{
+          x: x,
+          y: y,
+          r: r
+        }];
+      }
+    }
+  }
+  //求两点之间距离
+  distance(a, b, type) {
+    let x = b.x - a.x;
+    let y = b.y - a.y;
+    return Math.sqrt(x * x + y * y) * 5;
+  }
+  ctaCalc(x0, y0, r0, x1, y1, r1, x2, y2, r2) {
+    let a = [],
+      vx01, vy01, norm, n_x0, n_y0, vx21, vy21, n_x2, n_y2;
+    vx01 = x1 - x0;
+    vy01 = y1 - y0;
+    norm = Math.sqrt(vx01 * vx01 + vy01 * vy01 + 0.0001) * 2;
+    vx01 = vx01 / norm * r0;
+    vy01 = vy01 / norm * r0;
+    n_x0 = vy01;
+    n_y0 = -vx01;
+    vx21 = x1 - x2;
+    vy21 = y1 - y2;
+    norm = Math.sqrt(vx21 * vx21 + vy21 * vy21 + 0.0001) * 2;
+    vx21 = vx21 / norm * r2;
+    vy21 = vy21 / norm * r2;
+    n_x2 = -vy21;
+    n_y2 = vx21;
+    a.push({
+      mx: x0 + n_x0,
+      my: y0 + n_y0,
+      color: "#1A1A1A"
+    });
+    a.push({
+      c1x: x1 + n_x0,
+      c1y: y1 + n_y0,
+      c2x: x1 + n_x2,
+      c2y: y1 + n_y2,
+      ex: x2 + n_x2,
+      ey: y2 + n_y2
+    });
+    a.push({
+      c1x: x2 + n_x2 - vx21,
+      c1y: y2 + n_y2 - vy21,
+      c2x: x2 - n_x2 - vx21,
+      c2y: y2 - n_y2 - vy21,
+      ex: x2 - n_x2,
+      ey: y2 - n_y2
+    });
+    a.push({
+      c1x: x1 - n_x2,
+      c1y: y1 - n_y2,
+      c2x: x1 - n_x0,
+      c2y: y1 - n_y0,
+      ex: x0 - n_x0,
+      ey: y0 - n_y0
+    });
+    a.push({
+      c1x: x0 - n_x0 - vx01,
+      c1y: y0 - n_y0 - vy01,
+      c2x: x0 + n_x0 - vx01,
+      c2y: y0 + n_y0 - vy01,
+      ex: x0 + n_x0,
+      ey: y0 + n_y0
+    });
+    a[0].mx = a[0].mx.toFixed(1);
+    a[0].mx = parseFloat(a[0].mx);
+    a[0].my = a[0].my.toFixed(1);
+    a[0].my = parseFloat(a[0].my);
+    for (let i = 1; i < a.length; i++) {
+      a[i].c1x = a[i].c1x.toFixed(1);
+      a[i].c1x = parseFloat(a[i].c1x);
+      a[i].c1y = a[i].c1y.toFixed(1);
+      a[i].c1y = parseFloat(a[i].c1y);
+      a[i].c2x = a[i].c2x.toFixed(1);
+      a[i].c2x = parseFloat(a[i].c2x);
+      a[i].c2y = a[i].c2y.toFixed(1);
+      a[i].c2y = parseFloat(a[i].c2y);
+      a[i].ex = a[i].ex.toFixed(1);
+      a[i].ex = parseFloat(a[i].ex);
+      a[i].ey = a[i].ey.toFixed(1);
+      a[i].ey = parseFloat(a[i].ey);
+    }
+    return a;
+  }
+  bethelDraw(point, is_fill, color) {
+    this.ctx.beginPath();
+    this.ctx.moveTo(point[0].mx, point[0].my);
+    if (undefined != color) {
+      this.ctx.setFillStyle(color);
+      this.ctx.setStrokeStyle(color);
+    } else {
+      this.ctx.setFillStyle(point[0].color);
+      this.ctx.setStrokeStyle(point[0].color);
+    }
+    for (let i = 1; i < point.length; i++) {
+      this.ctx.bezierCurveTo(point[i].c1x, point[i].c1y, point[i].c2x, point[i].c2y, point[i].ex, point[i].ey);
+    }
+    this.ctx.stroke();
+    if (undefined != is_fill) {
+      this.ctx.fill(); //填充图形 ( 后绘制的图形会覆盖前面的图形, 绘制时注意先后顺序 )
+    }
+    this.ctx.draw(true)
+  }
+
+  selectColorEvent(lineColor) {
+    this.lineColor = lineColor;
+  }
+
+  selectSlideValue(slideValue) {
+    switch (slideValue) {
+      case 0:
+        this.lineSize = 0.1;
+        this.lineMin = 0.1;
+        this.lineMax = 0.1;
+        break;
+      case 25:
+        this.lineSize = 1;
+        this.lineMin = 0.5;
+        this.lineMax = 2;
+        break;
+      case 50:
+        this.lineSize = 1.5;
+        this.lineMin = 1;
+        this.lineMax = 3;
+        break;
+      case 75:
+        this.lineSize = 1.5;
+        this.lineMin = 2;
+        this.lineMax = 3.5;
+        break;
+      case 100:
+        this.lineSize = 3;
+        this.lineMin = 2;
+        this.lineMax = 3.5;
+        break;
+    }
+  }
+	
+	saveCanvas(){
+		 return new Promise((resolve,rej) => {
+			uni.canvasToTempFilePath({
+				canvasId: this.canvasName,
+				success: function(res) {
+					console.log(res.tempFilePath)
+					resolve(res.tempFilePath);
+				},
+				 fail:function(err){
+					 console.log('图片生成失败:'+err)
+					 rej(err);
+				 }
+			})
+		})	
+	}	
+}
+
+export default Handwriting;

+ 86 - 0
components/ossutil/uploadFile.js

@@ -0,0 +1,86 @@
+const env = require('./config.js'); //配置文件,在这文件里配置你的OSS keyId和KeySecret,timeout:87600;
+
+const base64 = require('./base64.js');//Base64,hmac,sha1,crypto相关算法
+require('./hmac.js');
+require('./sha1.js');
+const Crypto = require('./crypto.js');
+
+/*
+ *上传文件到阿里云oss
+ *@param - filePath :图片的本地资源路径
+ *@param - dir:表示要传到哪个目录下
+ *@param - successc:成功回调
+ *@param - failc:失败回调
+ */ 
+const uploadFile = function (filePath, dir, successc, failc) {debugger
+  if (!filePath || filePath.length < 9) {
+    uni.showModal({
+      title: '图片错误',
+      content: '请重试',
+      showCancel: false,
+    })
+    return;
+  }
+  
+  //图片名字 可以自行定义,     这里是采用当前的时间戳 + 150内的随机数来给图片命名的
+  const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png';
+  
+  const aliyunServerURL = env.uploadImageUrl;//OSS地址,需要https
+  const accessid = env.OSSAccessKeyId;
+  const policyBase64 = getPolicyBase64();
+  const signature = getSignature(policyBase64);//获取签名
+ 
+  uni.uploadFile({
+    url: aliyunServerURL,//开发者服务器 url
+    filePath: filePath,//要上传文件资源的路径
+    name: 'file',//必须填file
+    formData: {
+      'key': aliyunFileKey,
+      'policy': policyBase64,
+      'OSSAccessKeyId': accessid,
+      'signature': signature,
+      'success_action_status': '200',
+    },
+    success: function (res) {
+			console.log(res);
+      if (res.statusCode != 200) {
+        failc(new Error('上传错误:' + JSON.stringify(res)))
+        return;
+      }
+       successc(aliyunServerURL+"/"+aliyunFileKey);
+    },
+    fail: function (err) {
+      err.wxaddinfo = aliyunServerURL;
+      failc(err);
+    },
+  })
+}
+
+const getPolicyBase64 = function () {
+  let date = new Date();
+  date.setHours(date.getHours() + env.timeout);
+  let srcT = date.toISOString();
+  const policyText = {
+    "expiration": srcT, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了 
+    "conditions": [
+      ["content-length-range", 0, 5 * 1024 * 1024] // 设置上传文件的大小限制,5mb
+    ]
+  };
+
+  const policyBase64 = base64.encode(JSON.stringify(policyText));
+	console.log(policyBase64);
+  return policyBase64;
+}
+
+const getSignature = function (policyBase64) {
+  const accesskey = env.AccessKeySecret;
+
+  const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
+    asBytes: true
+  });
+  const signature = Crypto.util.bytesToBase64(bytes);
+console.log(signature);
+  return signature;
+}
+
+module.exports = uploadFile;

+ 788 - 0
components/upload.vue

@@ -0,0 +1,788 @@
+<template>
+	<view class="u-upload" v-if="!disabled">
+		<view v-if="showUploadList" class="u-list-item u-preview-wrap" :class="{'customPreviewStyle':custom}"
+			v-for="(item, index) in lists" :key="index" :style="{
+				width: width + 'rpx',
+				height: width + 'rpx'
+			}">
+			<view v-if="deletable" class="u-delete-icon" @tap.stop="deleteItem(index)" :style="{
+					background: delBgColor,
+				}">
+				<u-icon class="u-icon" :name="delIcon" :size="delIconSize" :color="delColor"></u-icon>
+			</view>
+			<view v-if="showProgress && item.progress > 0 && !item.error" class="u-check-icon" @tap.stop="deleteItem(index)" :style="{
+					background: checkBgColor,
+				}">
+				<u-icon class="u-icon" :name="checkIcon" :size="checkIconSize" :color="checkColor"></u-icon>
+			</view>
+			<!-- <u-line-progress v-if="showProgress && item.progress > 0 && !item.error" :show-percent="false" height="16"
+				class="u-progress" :percent="item.progress"></u-line-progress> -->
+			<view @tap.stop="retry(index)" v-if="item.error" class="u-error-btn">点击重试</view>
+			<image @tap.stop="doPreviewImage(item.url || item.path, index)" class="u-preview-image" v-if="!item.isImage"
+				:src="item.url || item.path" :mode="imageMode"></image>
+		</view>
+		<slot name="file" :file="lists"></slot>
+		<view style="display: inline-block;" :style="{
+			background:custom?customBack:'transparent',
+			border:custom?customBorder:'1px solid transparent'
+		}" :class="custom?'customStyle':'default'"
+			@tap="selectFile" v-if="maxCount > lists.length">
+			<slot name="addBtn"></slot>
+			<img v-if="custom&&options.bgc!=''" :src="options.bgc" alt="" class="imgstyle">
+			<view class="u-list-item u-add-wrap" hover-class="u-add-wrap__hover" hover-stay-time="150" :style="{
+					width: width + 'rpx',
+					height: width + 'rpx'
+				}">
+				<u-icon v-if="custom&&!customBtn" name="camera-fill" class="" size="100" color="#617E8B"></u-icon>
+				<image v-if="custom&&customBtn" :style="{
+				width: customBtnWidth + 'px',
+				height: customBtnHeight + 'px'
+			}" :src="customBtnImage" mode=""></image>
+				<image v-if="!custom" style='width:23px;height:23px;' src="../static/images/xiangji-2.png" mode=""></image>
+				<view v-if="!custom" class="u-add-tips">{{ uploadText }}</view>
+				<view v-if="custom" :style="{
+				color: customBtnColor,
+				'font-size':customBtnFontSize+'px',
+			}" class="u-add-tips">{{ options.text }}</view>
+			</view>
+		</view>
+		<view @click='imgShow=false' v-if="imgShow" class="shade">
+			<image style='position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;' :src="url" mode=""></image>
+		</view>
+		<!-- <view class="custom-style" v-if="custom"
+					:style="{backgroundImage: 'url(' + options.bgc + ')', backgroundSize:'100% 100%'}">
+
+		</view> -->
+	</view>
+</template>
+
+<script>
+	/**
+	 * upload 图片上传
+	 * @description 该组件用于上传图片场景
+	 * @tutorial https://www.uviewui.com/components/upload.html
+	 * @property {String} action 服务器上传地址
+	 * @property {String Number} max-count 最大选择图片的数量(默认99)
+	 * @property {Boolean} custom-btn 如果需要自定义选择图片的按钮,设置为true(默认false)
+	 * @property {Boolean} show-progress 是否显示进度条(默认true)
+	 * @property {Boolean} disabled 是否启用(显示/移仓)组件(默认false)
+	 * @property {String} image-mode 预览图片等显示模式,可选值为uni的image的mode属性值(默认aspectFill)
+	 * @property {String} del-icon 右上角删除图标名称,只能为uView内置图标
+	 * @property {String} del-bg-color 右上角关闭按钮的背景颜色
+	 * @property {String} del-color 右上角关闭按钮图标的颜色
+	 * @property {Object} header 上传携带的头信息,对象形式
+	 * @property {Object} form-data 上传额外携带的参数
+	 * @property {String} name 上传文件的字段名,供后端获取使用(默认file)
+	 * @property {Array<String>} size-type original 原图,compressed 压缩图,默认二者都有(默认['original', 'compressed'])
+	 * @property {Array<String>} source-type 选择图片的来源,album-从相册选图,camera-使用相机,默认二者都有(默认['album', 'camera'])
+	 * @property {Boolean} preview-full-image	是否可以通过uni.previewImage预览已选择的图片(默认true)
+	 * @property {Boolean} multiple	是否开启图片多选,部分安卓机型不支持(默认true)
+	 * @property {Boolean} deletable 是否显示删除图片的按钮(默认true)
+	 * @property {String Number} max-size 选择单个文件的最大大小,单位B(byte),默认不限制(默认Number.MAX_VALUE)
+	 * @property {Array<Object>} file-list 默认显示的图片列表,数组元素为对象,必须提供url属性
+	 * @property {Boolean} upload-text 选择图片按钮的提示文字(默认“选择图片”)
+	 * @property {Boolean} auto-upload 选择完图片是否自动上传,见上方说明(默认true)
+	 * @property {Boolean} show-tips 特殊情况下是否自动提示toast,见上方说明(默认true)
+	 * @property {Boolean} show-upload-list 是否显示组件内部的图片预览(默认true)
+	 * @event {Function} on-oversize 图片大小超出最大允许大小
+	 * @event {Function} on-preview 全屏预览图片时触发
+	 * @event {Function} on-remove 移除图片时触发
+	 * @event {Function} on-success 图片上传成功时触发
+	 * @event {Function} on-change 图片上传后,无论成功或者失败都会触发
+	 * @event {Function} on-error 图片上传失败时触发
+	 * @event {Function} on-progress 图片上传过程中的进度变化过程触发
+	 * @event {Function} on-uploaded 所有图片上传完毕触发
+	 * @event {Function} on-choose-complete 每次选择图片后触发,只是让外部可以得知每次选择后,内部的文件列表
+	 * @example <u-upload :action="action" :file-list="fileList" ></u-upload>
+	 */
+
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	export default {
+		name: 'upload',
+		props: {
+			//是否显示组件自带的图片预览功能
+			showUploadList: {
+				type: Boolean,
+				default: true
+			},
+			// 后端地址
+			action: {
+				type: String,
+				default: ''
+			},
+			// 最大上传数量
+			maxCount: {
+				type: [String, Number],
+				default: 52,
+				},
+			// 删除图标大小
+			delIconSize:{
+				type: String,
+				default: '20'
+			},
+			//  是否显示进度条
+			showProgress: {
+				type: Boolean,
+				default: true
+			},
+			// 是否启用
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			// 预览上传的图片时的裁剪模式,和image组件mode属性一致
+			imageMode: {
+				type: String,
+				default: 'aspectFill'
+			},
+			// 头部信息
+			header: {
+				type: Object,
+				default () {
+					return {};
+				}
+			},
+			// 额外携带的参数
+			formData: {
+				type: Object,
+				default () {
+					return {};
+				}
+			},
+			// 上传的文件字段名
+			name: {
+				type: String,
+				default: 'file'
+			},
+			// 所选的图片的尺寸, 可选值为original compressed
+			sizeType: {
+				type: Array,
+				default () {
+					return ['original', 'compressed'];
+				}
+			},
+			sourceType: {
+				type: Array,
+				default () {
+					return ['album', 'camera'];
+				}
+			},
+			// 成功背景颜色
+			checkBgColor:{
+				type: String,
+				default: '#22C572'
+			},
+			// 成功icon颜色
+			checkColor:{
+				type: String,
+				default: '#fff'
+			},
+			// 成功icon颜色
+			checkIcon:{
+				type: String,
+				default: 'checkbox-mark'
+			},
+			// 成功icon颜色
+			checkIconSize:{
+				type: String,
+				default: '20'
+			},
+			// 是否在点击预览图后展示全屏图片预览
+			previewFullImage: {
+				type: Boolean,
+				default: true
+			},
+			// 是否开启图片多选,部分安卓机型不支持
+			multiple: {
+				type: Boolean,
+				default: true
+			},
+			// 是否展示删除按钮
+			deletable: {
+				type: Boolean,
+				default: true
+			},
+			// 文件大小限制,单位为byte
+			maxSize: {
+				type: [String, Number],
+				default: Number.MAX_VALUE
+			},
+			// 显示已上传的文件列表
+			fileList: {
+				type: Array,
+				default () {
+					return [];
+				}
+			},
+			// 上传区域的提示文字
+			uploadText: {
+				type: String,
+				default: '选择图片'
+			},
+			// 是否自动上传
+			autoUpload: {
+				type: Boolean,
+				default: true
+			},
+			// 是否显示toast消息提示
+			showTips: {
+				type: Boolean,
+				default: true
+			},
+			// 是否通过slot自定义传入选择图标的按钮
+			customBtn: {
+				type: Boolean,
+				default: false
+			},
+			customBtnImage: {
+				type: String,
+				default: ''
+			},
+			customBtnWidth: {
+				type: Number,
+				default: 0
+			},
+			customBtnHeight: {
+				type: Number,
+				default: 0
+			},
+			customBtnColor: {
+				type: String,
+				default: '#617E8B'
+			},
+			customBack:{
+				type: String,
+				default: '#F5F6FA'
+			},
+			customBorder:{
+				type: String,
+				// default: '2px dashed #C6CBCE'
+			},
+			customBtnFontSize:{
+				type: String,
+				default: '18'
+			},
+			// 内部预览图片区域和选择图片按钮的区域宽度,高等于宽
+			width: {
+				type: [String, Number],
+				default: 200
+			},
+			// 右上角关闭按钮的背景颜色
+			delBgColor: {
+				type: String,
+				default: '#fa3534'
+			},
+			// 右上角关闭按钮的叉号图标的颜色
+			delColor: {
+				type: String,
+				default: '#ffffff'
+			},
+			// 右上角删除图标名称,只能为uView内置图标
+			delIcon: {
+				type: String,
+				default: 'close'
+			},
+			// 如果上传后的返回值为json字符串,是否自动转json
+			toJson: {
+				type: Boolean,
+				default: true
+			},
+			// 上传前的钩子,每个文件上传前都会执行
+			beforeUpload: {
+				type: Function,
+				default: null
+			},
+			options: {
+				type: Object,
+				default: null
+			},
+			custom: {
+				type: Boolean,
+				default: false
+			},
+			imgIndex:{
+				type: Number,
+				default: 0
+			}
+		},
+		mounted() {},
+		data() {
+			return {
+				lists: [],
+				isInCount: true,
+				uploading: false,
+				isSelectFile: false,
+				imgShow:false,
+				url:''
+			};
+		},
+		watch: {
+			fileList: {
+				immediate: true,
+				handler(val) {
+					val.map(value => {
+						this.lists.push({
+							url: value.url,
+							error: false,
+							progress: 100
+						});
+					});
+				}
+			}
+		},
+		methods: {
+			// 清除列表
+			clear() {
+				this.lists = [];
+				// 如果是清空形式的话,发出"on-list-change"事件
+				this.$emit('on-list-change', this.lists);
+			},
+			// 重新上传队列中上传失败的所有文件
+			reUpload() {
+				this.uploadFile();
+			},
+			// 选择图片
+			selectFile() {
+				if (this.disabled) return;
+				const {
+					name = '', maxCount, multiple, maxSize, sizeType, lists, camera, compressed, maxDuration, sourceType
+				} = this;
+				let chooseFile = null;
+				const newMaxCount = maxCount - lists.length;
+				// 设置为只选择图片的时候使用 chooseImage 来实现
+				chooseFile = new Promise((resolve, reject) => {
+					uni.chooseImage({
+						count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,
+						sourceType: sourceType,
+						sizeType,
+						success: resolve,
+						fail: reject
+					});
+				});
+				chooseFile
+					.then(res => {
+						let file = null;
+						let listOldLength = this.lists.length;
+						res.tempFiles.map((val, index) => {
+							// 如果是非多选,index大于等于1或者超出最大限制数量时,不处理
+							if (!multiple && index >= 1) return;
+							if (val.size > maxSize) {
+								this.$emit('on-oversize', val, this.lists);
+								this.showToast('超出允许的文件大小');
+							} else {
+								if (maxCount <= lists.length) {
+									this.$emit('on-exceed', val, this.lists);
+									this.showToast('超出最大允许的文件个数');
+									return;
+								}
+								let fileName = '';
+								let fileNameLength = '';
+								let fileFormat = '';
+								//#ifdef H5
+								fileName = val.name.lastIndexOf(".");
+								fileNameLength = val.name.length;
+								fileFormat = val.name.substring(fileName + 1, fileNameLength).toLowerCase();
+								//#endif
+								//#ifndef H5
+								fileName = val.path.lastIndexOf(".");
+								fileNameLength = val.path.length;
+								fileFormat = val.path.substring(fileName + 1, fileNameLength).toLowerCase();
+								//#endif
+								lists.push({
+									url: val.path,
+									fileType: fileFormat,
+									progress: 0,
+									error: false
+								});
+								// 列表发生改变,发出事件,第二个参数为当前发生变化的项的索引
+								this.$emit('on-list-change', this.lists);
+							}
+						});
+						// 每次图片选择完,抛出一个事件,并将当前内部选择的图片数组抛出去
+						this.$emit('on-choose-complete', this.lists);
+						if (this.autoUpload) this.uploadFile(listOldLength);
+					})
+					.catch(error => {
+						this.$emit('on-error', error);
+					});
+			},
+			// 提示用户消息
+			showToast(message, force = false) {
+				if (this.showTips || force) {
+					uni.showToast({
+						title: message,
+						icon: 'none'
+					});
+				}
+			},
+			// 该方法供用户通过ref调用,手动上传
+			upload() {
+				this.uploadFile();
+			},
+			// 对失败的图片重新上传
+			retry(index) {
+				this.lists[index].progress = 0;
+				this.lists[index].error = false;
+				this.lists[index].response = null;
+				uni.showLoading({
+					title: '重新上传'
+				});
+				this.uploadFile(index);
+			},
+			// 上传图片
+			async uploadFile(index = 0) {
+				if (this.disabled) return;
+				if (this.uploading) return;
+				// 全部上传完成
+				if (index >= this.lists.length) {
+					this.isSelectFile = true
+					this.$emit('on-uploaded', this.lists);
+					return;
+				}
+				// 检查上传地址
+				if (!this.action) {
+					this.showToast('请配置上传地址', true);
+					return;
+				}
+				// 检查是否是已上传或者正在上传中
+				if (this.lists[index].progress == 100) {
+					if (this.autoUpload == false) this.uploadFile(index + 1);
+					return;
+				}
+				// 执行before-upload钩子
+				if (this.beforeUpload && typeof(this.beforeUpload) === 'function') {
+					// 执行回调,同时传入索引和文件列表当作参数
+					let beforeResponse = this.beforeUpload(index, this.lists);
+					// 判断是否返回了promise
+					if (!!beforeResponse && typeof beforeResponse.then === 'function') {
+						await beforeResponse.then(res => {
+							// promise返回成功,不进行动作,继续上传
+						}).catch(err => {
+							// 进入catch回调的话,继续下一张
+							return this.uploadFile(index + 1);
+						})
+					} else if (beforeResponse === false) {
+						// 如果返回false,继续下一张图片的上传
+						return this.uploadFile(index + 1);
+					}
+				}
+				this.lists[index].error = false;
+				this.uploading = true;
+				uploadImage(this.lists[index].url, 'appData/',
+					result => {
+						console.log
+						// 上传成功
+						this.lists[index].response = result;
+						this.lists[index].progress = 100;
+						this.lists[index].error = false;
+						let data = result
+						this.$emit('on-success', data, index, this.lists,this.imgIndex);
+						uni.hideLoading();
+						this.uploading = false;
+						this.uploadFile(index + 1);
+						this.$emit('on-change', data, index, this.lists,this.imgIndex);
+					}
+				)
+				// 创建上传对象
+				// const task = uni.uploadFile({
+				// 	url: this.action,
+				// 	filePath: this.lists[index].url,
+				// 	name: this.name,
+				// 	formData: this.formData,
+				// 	header: this.header,
+				// 	success: res => {
+				// 		// 判断是否json字符串,将其转为json格式
+				// 		let data = this.toJson && this.checkIsJSON(res.data) ? JSON.parse(res.data) : res
+				// 			.data;
+				// 		if (![200, 201].includes(res.statusCode)) {
+				// 			this.uploadError(index, data);
+				// 		} else {
+				// 			// 上传成功
+				// 			this.lists[index].response = data;
+				// 			this.lists[index].progress = 100;
+				// 			this.lists[index].error = false;
+				// 			// this.$emit('on-success', data, index, this.lists);
+				// 		}
+				// 	},
+				// 	fail: e => {
+				// 		this.uploadError(index, e);
+				// 	},
+				// 	complete: res => {
+				// 		uni.hideLoading();
+				// 		this.uploading = false;
+				// 		this.uploadFile(index + 1);
+				// 		this.$emit('on-change', res, index, this.lists);
+				// 	}
+				// });
+				// task.onProgressUpdate(res => {
+				// 	if (res.progress > 0) {
+				// 		this.lists[index].progress = res.progress;
+				// 		this.$emit('on-progress', res, index, this.lists);
+				// 	}
+				// });
+			},
+			// 上传失败
+			uploadError(index, err) {
+				this.lists[index].progress = 0;
+				this.lists[index].error = true;
+				this.lists[index].response = null;
+				this.$emit('on-error', err, index, this.lists);
+				this.showToast('上传失败,请重试');
+			},
+			// 删除一个图片
+			deleteItem(index) {
+				uni.showModal({
+					title: '提示',
+					content: '您确定要删除此项吗?',
+					success: res => {
+						if (res.confirm) {
+							this.isSelectFile = false
+							if (this.lists[index].process < 100 && this.lists[index].process > 0) {
+								typeof this.lists[index].uploadTask != 'undefined' && this.lists[index]
+									.uploadTask.abort();
+							}
+							this.lists.splice(index, 1);
+							this.$forceUpdate();
+							this.$emit('on-remove', index, this.lists);
+							this.showToast('移除成功');
+							// 列表发生改变,发出事件
+							this.$emit('on-list-change', this.lists);
+						}
+					}
+				});
+			},
+			// 用户通过ref手动的形式,移除一张图片
+			remove(index) {
+				// 判断索引的合法范围
+				if (index >= 0 && index < this.lists.length) {
+					this.lists.splice(index, 1);
+					this.$emit('on-list-change', this.lists);
+				}
+			},
+			// 预览图片
+			doPreviewImage(url, index) {
+				console.log(this.lists,url,index)
+				if (!this.previewFullImage) return;
+				const images = this.lists.map(item => item.url || item.path);
+				this.url=url
+				this.imgShow=true
+				// 图片预览调用onShow清空数据
+				// uni.previewImage({
+				// 	urls: images,
+				// 	current: url,
+				// 	success: () => {
+				// 		this.$emit('on-preview', url, this.lists);
+				// 	},
+				// 	fail: () => {
+				// 		uni.showToast({
+				// 			title: '预览图片失败',
+				// 			icon: 'none'
+				// 		});
+				// 	}
+				// });
+			},
+			// 判断是否json字符串
+			checkIsJSON(str) {
+				if (typeof str == 'string') {
+					try {
+						var obj = JSON.parse(str);
+						if (typeof obj == 'object' && obj) {
+							return true;
+						} else {
+							return false;
+						}
+					} catch (e) {
+						return false;
+					}
+				}
+				return false;
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	// nvue不能用标签命名样式
+	/* #ifndef APP-NVUE */
+	image {
+		display: inline-block;
+		// 解决图片加载时可能会瞬间变形的问题
+		will-change: transform;
+	}
+
+	view,
+	text {
+		box-sizing: border-box;
+		flex-direction: row;
+	}
+
+	/* #endif */
+	.u-upload {
+		display: flex;
+		flex-wrap: wrap;
+		align-items: center;
+	}
+
+	.u-list-item {
+		width: 200rpx;
+		height: 200rpx;
+		overflow: hidden;
+		// margin: 10rpx;
+		background: rgb(244, 245, 246);
+		position: relative;
+		border-radius: 10rpx;
+		display: inline-flex;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.u-preview-wrap {
+		border: 1px solid rgb(235, 236, 238);
+	}
+
+	.u-add-wrap {
+		flex-direction: column;
+		color: $u-content-color;
+		font-size: 28rpx;
+	}
+
+	.u-add-tips {
+		margin-top: 20rpx;
+	}
+
+	.u-add-wrap__hover {
+		background-color: rgb(235, 236, 238);
+	}
+
+	.u-preview-image {
+		display: block;
+		width: 100%;
+		height: 100%;
+		border-radius: 10rpx;
+	}
+
+	.u-delete-icon {
+		position: absolute;
+		top: 0rpx;
+		right: 0rpx;
+		z-index: 10;
+		background-color: $u-error;
+		border-radius:0 0 0 10rpx;
+		width: 44rpx;
+		height: 44rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.u-icon {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.u-progress {
+		position: absolute;
+		bottom: 10rpx;
+		left: 8rpx;
+		right: 8rpx;
+		z-index: 9;
+		width: auto;
+	}
+
+	.u-error-btn {
+		color: #ffffff;
+		background-color: $u-error;
+		font-size: 20rpx;
+		padding: 4px 0;
+		text-align: center;
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		z-index: 9;
+		line-height: 1;
+	}
+	.customStyleBgc {
+		width: 100% !important;
+		height: 440rpx !important;
+		display: flex !important;
+		justify-content: center;
+		align-items: center;
+		position: relative;
+
+		.u-add-wrap {
+			width: 100% !important;
+			height: 100% !important;
+			background: transparent;
+		}
+
+		.u-add-tips {
+			font-size: 18px;
+			font-weight: 600;
+			color: #617E8B;
+		}
+	}
+
+	.customStyle {
+		width: 712rpx !important;
+		height: 440rpx !important;
+		background: #F5F6FA;
+		border-radius: 20rpx;
+		// border: 2px dashed #C6CBCE;
+		display: flex !important;
+		justify-content: center;
+		align-items: center;
+		position: relative;
+
+		.u-add-wrap {
+			width: 100% !important;
+			height: 100% !important;
+			background: transparent;
+		}
+
+		.u-add-tips {
+			font-size: 18px;
+			font-weight: 600;
+			color: #617E8B;
+		}
+	}
+
+	.customPreviewStyle {
+		width: 100% !important;
+		height: 440rpx !important;
+	}
+
+	.imgstyle {
+		width: 100% !important;
+		height: 440rpx !important;
+		position: absolute;
+	}
+	.default{
+		
+		.u-list-item.u-add-wrap{
+			background:#fff;
+			border:1px dashed #AFB3BF;
+		}
+	}
+	.shade{
+		background:#000;
+		position:fixed;
+		top:0;left:0;
+	   width:100%;height:100%;
+	   z-index:10000;
+	}
+	.u-check-icon{
+		position: absolute;
+		bottom: 0rpx;
+		left: 0rpx;
+		z-index: 10;
+		background-color: $u-error;
+		border-radius:0 0 0 10rpx;
+		width: 44rpx;
+		height: 44rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+</style>

+ 1 - 1
config/index.js

@@ -1,5 +1,5 @@
 const dev = {
-	baseUrlNew: 'http://192.168.1.117:8090',
+	baseUrlNew: 'http://192.168.1.121:8090',
 	h5Appid: 'wxb66b599f7f61b46f',
 	debug: false
 }

+ 103 - 0
demo.vue

@@ -0,0 +1,103 @@
+<template>
+	<view class="content">
+		常用
+		1、延时一定时间进行回调
+		2、获取父组件this
+		3、节流防抖
+		4、对象克隆
+		5、路由跳转
+		6、对象修改为地址栏传参
+		7、常用规则校验
+		8、toast消息提示
+		9、弹框提示
+		10、请求方法
+		11、loading
+	</view>
+</template>
+
+<script>
+	export default {
+		// 此处为页面级,所以name值可选
+		name: 'page',
+		data() {
+			return {
+
+			}
+		},
+		onLoad() {
+
+		},
+		mounted() {
+			// 2、
+			// 将会得到父页面的this实例
+			uni.$u.$parent.call(this, 'page')
+		}
+		methods: {
+			demo() {
+				// 1、
+				// 300ms后触发回调
+				uni.$u.sleep(300).then(() => {
+					console.log('定时结束')
+				})
+				// 3、
+				// <view class="throttle" @tap="$u.throttle(btnAClick, 500)">
+				// uni.$u.throttle(this.toNext, 500)
+				// <view class="debounce" @tap="$u.debounce(btnAClick, 500)">
+				// uni.$u.debounce(this.toNext, 500)
+				// 4、
+				let b = uni.$u.deepClone(a);
+				// 5、
+				// 无参数
+				uni.$u.route('/pages/components/empty/index');
+				// 带参数
+				uni.$u.route('/pages/goodSource/shippingDetails', {
+					id: 1,
+				});
+				// 6、
+				uni.$u.queryParams(this.data)
+				// 7、
+				uni.$u.test.idCard('110101199003070134')
+				// 8、
+				// default/error/success/loading
+				// <u-toast ref="uToast"></u-toast>
+				// let params = {
+				// 		type: 'success',
+				// 		title: '成功主题(带图标)',
+				// 		message: "庄生晓梦迷蝴蝶",
+				// 		iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+				// 	}
+				// this.$refs.uToast.show({
+				// 	...params,
+				// 	complete() {
+				// 		params.url && uni.navigateTo({
+				// 			url: params.url
+				// 		})
+				// 	}
+				// })
+				// uni.$u.toast('倒计时结束后再发送');
+				// 9、
+				// <u-modal :show="isShowAlert" :title="alertTitle" :content='alertContent' :closeOnClickOverlay='true' :showCancelButton='true' confirmColor='#22C572'  @confirm="confirmClick" @close="cancelClick" @cancel="cancelClick"></u-modal>
+				// 10、
+				// that.$request.baseRequest('get', '/commonUser/loginVerifyCode', {
+				// 		phone: that.model1.phone,
+				// 		verifyCode: that.model1.code
+				// 	}).then(res => {
+							
+				
+				// 	})
+				// 	.catch(res => {
+				// 		uni.showToast({
+				// 			title: res.message,
+				// 			icon: 'none',
+				// 			duration: 2000
+				// 		})
+				// 	});
+				// 11、
+				// 	uni.showLoading({
+				// 				title: '登录中',
+				// 				mask: true
+				// 			})
+			}
+		}
+	}
+</script>

+ 2 - 1
main.js

@@ -11,11 +11,12 @@ import baseApi from '@/util/base.js'
 import request from '@/util/request.js'
 import utils from '@/util/util.js'
 import webim from 'webim.js';
+import helper from'@/common/helper.js'
 Vue.prototype.$api = baseApi
 Vue.prototype.$request = request
 Vue.prototype.$utils = utils
+Vue.prototype.$helper = helper
 Vue.prototype.$socket = webim;
-
 Vue.prototype.$store = store
 
 

+ 115 - 110
pages.json

@@ -35,7 +35,7 @@
 		{
 			"path": "pages/goodSource/index",
 			"style": {
-				"navigationBarTitleText": "uni-app"
+				"navigationBarTitleText": "粮运天下"
 			}
 		}, {
 			"path": "pages/order/index",
@@ -69,116 +69,121 @@
 				"enablePullDownRefresh": false
 			}
 
-		}
+		},
+		{
+			"path": "pages/public/register",
+			"style": {
+				"navigationBarTitleText": "注册",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "pages/goodSource/shippingDetails",
+			"style": {
+				"navigationBarTitleText": "发运详情",
+				"enablePullDownRefresh": false
+			}
 
-	    ,{
-            "path" : "pages/goodSource/shippingDetails",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "发运详情",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/order/orderDetails",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "订单详情",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/order/confirmLoading",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "确认装车",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/order/confirmUnloading",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "确认卸车",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/driverCertification",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "司机认证",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/helpDescription",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "帮助说明",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/manageVehicles/index",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "管理车辆",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/manageVehicles/addVehicle",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "添加车辆",
-                "enablePullDownRefresh": false
-            }
-            
-        }   ,{
-            "path" : "pages/mine/manageVehicles/editVehicle",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "修改车辆",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/manageBankCards/index",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "银行卡",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/manageBankCards/addBankCard",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "添加银行卡",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-        ,{
-            "path" : "pages/mine/set",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "设置",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-    ],
+		}, {
+			"path": "pages/order/orderDetails",
+			"style": {
+				"navigationBarTitleText": "订单详情",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/order/confirmLoading",
+			"style": {
+				"navigationBarTitleText": "确认装车",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/order/confirmUnloading",
+			"style": {
+				"navigationBarTitleText": "确认卸车",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/driverCertification",
+			"style": {
+				"navigationBarTitleText": "司机认证",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+		 "path": "pages/mine/driverCertificationNext",
+			"style": {
+				"navigationBarTitleText": "司机认证",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/helpDescription",
+			"style": {
+				"navigationBarTitleText": "操作说明",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/manageVehicles/index",
+			"style": {
+				"navigationBarTitleText": "管理车辆",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/manageVehicles/addVehicle",
+			"style": {
+				"navigationBarTitleText": "添加车辆",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/manageVehicles/editVehicle",
+			"style": {
+				"navigationBarTitleText": "修改车辆",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/manageBankCards/index",
+			"style": {
+				"navigationBarTitleText": "银行卡",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/manageBankCards/addBankCard",
+			"style": {
+				"navigationBarTitleText": "添加银行卡",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/manageBankCards/editBankCard",
+			"style": {
+				"navigationBarTitleText": "修改银行卡",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/mine/set",
+			"style": {
+				"navigationBarTitleText": "设置",
+				"enablePullDownRefresh": false
+			}
+
+		},
+		{
+			"path": "pages/mine/camera/idcard/idcard",
+			"style": {
+				"navigationStyle": "custom",
+				"backgroundColor": "#000000"
+			}
+
+		}
+	],
 	"globalStyle": {
 		"navigationBarTextStyle": "black",
 		"navigationBarTitleText": "uni-app",

+ 0 - 76
pages/demo/demo.vue

@@ -1,76 +0,0 @@
-<template>
-	 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
-		<view class="notice">mescroll的极简示例,大部分情况就是这么用</view>
-		<good-list :list="goods"></good-list>
-	</mescroll-body>
-</template>
-
-<script>
-	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
-	import {apiGoods} from "@/api/mock.js"
-	
-	export default {
-		mixins: [MescrollMixin], // 使用mixin
-		data() {
-			return {
-				goods: [] // 数据列表
-			}
-		},
-		methods: {
-			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
-			upCallback(page) {
-				// 此处可以继续请求其他接口
-				// if(page.num == 1){
-				// 	// 请求其他接口...
-				// }
-				
-				// 如果希望先请求其他接口,再触发upCallback,可参考以下写法
-				// if(!this.isInitxx){
-				// 	apiGetxx().then(res=>{
-				// 		this.isInitxx = true
-				// 		this.mescroll.resetUpScroll() // 重新触发upCallback
-				// 	}).catch(()=>{
-				// 		this.mescroll.endErr()
-				// 	})
-				// 	return // 此处return,先获取xx
-				// }
-				
-				//联网加载数据
-				apiGoods(page.num, page.size).then(res=>{
-					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
-					//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;
-
-					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
-					//this.mescroll.endByPage(res.list.length, totalPage); //必传参数(当前页的数据个数, 总页数)
-
-					//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
-					//this.mescroll.endBySize(res.list.length, totalSize); //必传参数(当前页的数据个数, 总数据量)
-
-					//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
-					//this.mescroll.endSuccess(res.list.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)
-
-					//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据
-					this.mescroll.endSuccess(res.list.length);
-
-					//设置列表数据
-					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
-					this.goods=this.goods.concat(res.list); //追加新数据
-				}).catch(()=>{
-					//联网失败, 结束加载
-					this.mescroll.endErr();
-				})
-			}
-		}
-	}
-</script>
-
-<style>
-	/*说明*/
-	.notice{
-		font-size: 26upx;
-		padding: 40upx 0;
-		border-bottom: 1upx solid #eee;
-		text-align: center;
-		color:#555;
-	}
-</style>

+ 38 - 30
pages/goodSource/index.vue

@@ -1,53 +1,61 @@
 <!-- 货源 -->
 <template>
 	<view class="content">
-		
-		<!-- <u--image :showLoading="true" :src="src" width="80px" height="80px" @click="click"></u--image> -->
-		货源
+		<view class="head flex flex-space-evenly">
+			<view class="flex">
+				<view>装</view>
+				<view @click="changeCity(0)">营口</view>
+				<view>></view>
+			</view>
+			<view>-------></view>
+			<view class="flex">
+				<view>卸</view>
+				<view @click="changeCity(1)">全国</view>
+				<view>></view>
+			</view>
+		</view>
+		<me-tabs v-model="tabIndex" :tabs="tabs" class="m-topr20"></me-tabs>
+		<swiper :style="{height: height}" :current="tabIndex" @change="swiperChange">
+			<swiper-item v-for="(tab,i) in tabs" :key="i">
+				<mescroll-item ref="mescrollItem" :i="i" :index="tabIndex" :tabs="tabs" :height="height">
+				</mescroll-item>
+			</swiper-item>
+		</swiper>
 	</view>
 </template>
 
 <script>
+	import MescrollItem from "./mescroll-swiper-item.vue";
 	export default {
+		components: {
+			MescrollItem
+		},
 		data() {
 			return {
-				src: 'https://cdn.uviewui.com/uview/album/1.jpg'
+				src: 'https://cdn.uviewui.com/uview/album/1.jpg',
+				height: "", // 需要固定swiper的高度
+				tabs: [{name:'推荐'}, {name:'按时间'}, {name:'按距离'}, {name:'运费先付'}],
+				tabIndex: 0 // 当前tab的下标
+
 			}
 		},
 		onLoad() {
 			let _isHave = this.$utils.getRoles('aaa')
 			console.log(_isHave)
+			// 需要固定swiper的高度 (需减去悬浮tabs的高度64rpx)
+			this.height = uni.getSystemInfoSync().windowHeight - uni.upx2px(64) + 'px'
 		},
 		methods: {
-		
+			changeCity(type) {
+				console.log(type)
+			},
+			swiperChange(e) {
+				this.tabIndex = e.detail.current
+			}
 		}
 	}
 </script>
 
-<style>
-	.content {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		justify-content: center;
-	}
+<style scoped lang="scss">
 
-	.logo {
-		height: 200rpx;
-		width: 200rpx;
-		margin-top: 200rpx;
-		margin-left: auto;
-		margin-right: auto;
-		margin-bottom: 50rpx;
-	}
-
-	.text-area {
-		display: flex;
-		justify-content: center;
-	}
-
-	.title {
-		font-size: 36rpx;
-		color: #8f8f94;
-	}
 </style>

+ 139 - 0
pages/goodSource/mescroll-swiper-item.vue

@@ -0,0 +1,139 @@
+<template>
+	<mescroll-uni :ref="'mescrollRef'+i" @init="mescrollInit" :height="height" :down="downOption" @down="downCallback"
+		:up="upOption" @up="upCallback" @emptyclick="emptyClick">
+		<view :id="'good'+good.id" class="good-list paddingr20" v-for="good in goods" :key="good.id" @click="toDetail(good.id)">
+			<view class="flex flex-space-between row">
+				<view class="left flex">
+					<view>辽</view>
+					<view>营口 鲅鱼圈</view>
+					<view>--------></view>
+					<view class="">
+						京
+					</view>
+					<view>背景 通州</view>
+				</view>
+				<view class="right">
+					21:51
+				</view>
+			</view>
+			<view class="flex flex-space-between row">
+				<view class="left flex">
+					<view>货距~10km</view>
+					<view>运距~35km</view>
+				</view>
+				<view class="right">
+					300元/吨
+				</view>
+			</view>
+			<view class="flex">
+				<view>玉米|</view>
+				<view>3.8-5米|</view>
+				<view>厢式/平板/高栏|</view>
+				<view>10吨</view>
+			</view>
+			<view class="flex">
+				<view>运输过程中其他费用,发货方承担。</view>
+			</view>
+			<view class="flex flex-space-between">
+				<view class="left flex">
+					<u--image :showLoading="true" :src="good.goodImg" width="40px" height="40px"></u--image>
+					<view>张颖</view>
+					<view>发运106次</view>
+					<view>好评率99%</view>
+				</view>
+				<view class="right">
+					<view @click.stop="grabOrders(good.id)">抢单</view>
+				</view>
+			</view>
+		</view>
+	</mescroll-uni>
+</template>
+
+<script>
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	import MescrollMoreItemMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js";
+	import {
+		apiGoods
+	} from "@/api/mock.js"
+
+	export default {
+		mixins: [MescrollMixin, MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
+		data() {
+			return {
+				downOption: {
+					auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
+				},
+				upOption: {
+					auto: false, // 不自动加载
+					// page: {
+					// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+					// 	size: 10 // 每页数据的数量
+					// },
+					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
+					empty: {
+						tip: '~ 空空如也 ~', // 提示
+						btnText: '去看看'
+					}
+				},
+				goods: [] //列表数据
+			}
+		},
+		props: {
+			i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
+			index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
+				type: Number,
+				default () {
+					return 0
+				}
+			},
+			tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			height: [Number, String] // mescroll的高度
+		},
+		methods: {
+			/*下拉刷新的回调 */
+			downCallback() {
+				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
+				// loadSwiper();
+				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
+				this.mescroll.resetUpScroll()
+			},
+			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
+			upCallback(page) {
+				//联网加载数据
+				let keyword = this.tabs[this.i].name
+				apiGoods(page.num, page.size, keyword).then(res => {
+					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
+					this.mescroll.endSuccess(res.list.length);
+					//设置列表数据
+					if (page.num == 1) this.goods = []; //如果是第一页需手动制空列表
+					this.goods = this.goods.concat(res.list); //追加新数据
+				}).catch(() => {
+					//联网失败, 结束加载
+					this.mescroll.endErr();
+				})
+			},
+			//点击空布局按钮的回调
+			emptyClick() {
+				uni.showToast({
+					title: '点击了按钮,具体逻辑自行实现'
+				})
+			},
+			// 跳转详情
+			toDetail(id){
+				console.log('点击详情id:',id)
+				uni.$u.route('/pages/goodSource/shippingDetails', {
+					id:id,
+				});
+			},
+			//抢单
+			grabOrders(id){
+				console.log('抢单id:',id)
+			}
+		}
+	}
+</script>

+ 102 - 3
pages/goodSource/shippingDetails.vue

@@ -1,7 +1,103 @@
 <!-- 发运详情 -->
 <template>
-	<view>
-		发运详情
+	<view class="content">
+		<view class="content1">
+			<view class="left">
+				<u--image src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix"></u--image>
+			</view>
+			<view class="right">
+				<view class="flex">
+					<view class="">张三</view>
+					<view class="">联系货主</view>
+					<view>关注</view>
+					<!-- <view>已关注</view> -->
+				</view>
+				<view class="flex">
+					黑龙江中天贸易有限公司
+				</view>
+				<view class="flex">
+					<view class="left">
+						装车
+					</view>
+					<view>辽宁省营口市鲅鱼圈区蝴蝶泉路116号</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						卸车车
+					</view>
+					<view>黑龙江省齐齐哈尔市梅里斯达斡尔族区杜尔门沁达斡尔乡53农场</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						货物
+					</view>
+					<view>玉米|20吨</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						距离
+					</view>
+					<view class="right">
+						<view>运输距离月500公里</view>
+						<view><u--image src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix"></u--image></view>
+					</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						运费
+					</view>
+					<view class="right">
+						100元/吨
+					</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						日期
+					</view>
+					<view class="right">
+						<view class="in-row">
+							<view class="text">
+								发车
+							</view>
+							<view class="time">2022-01-27 15:15:15</view>
+						</view>
+						<view class="in-row">
+							<view class="text">
+								装车
+							</view>
+							<view class="time">2022-01-27~2022-01-30</view>
+						</view>
+					</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						车型
+					</view>
+					<view class="right">
+						10-15米  |  平板/高栏  |  约30吨
+					</view>
+				</view>
+				<view class="flex">
+					<view class="left">
+						描述
+					</view>
+					<view class="right">
+						我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述我是发运任务描述
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="content2">
+			<view class="left">
+				运费¥100元/吨
+			</view>
+			<view class="right">
+				<u-button type="error" text="立即抢单"></u-button>
+			</view>
+			<view class="right">
+				<u-button type="error" text="已抢单" disabled></u-button>
+			</view>
+		</view>
 	</view>
 </template>
 
@@ -9,8 +105,11 @@
 	export default {
 		data() {
 			return {
-				
+				src: 'https://cdn.uviewui.com/uview/album/1.jpg',
 			};
+		},
+		onLoad(options) {
+			console.log(options)
 		}
 	}
 </script>

+ 0 - 53
pages/index/index.vue

@@ -1,53 +0,0 @@
-<template>
-	<view class="content">
-		
-		<!-- <u--image :showLoading="true" :src="src" width="80px" height="80px" @click="click"></u--image> -->
-		我是首页
-	</view>
-</template>
-
-<script>
-	export default {
-		
-		data() {
-			return {
-				src: 'https://cdn.uviewui.com/uview/album/1.jpg'
-			}
-		},
-		onLoad() {
-			let _isHave = this.$utils.getRoles('aaa')
-			console.log(_isHave)
-		},
-		methods: {
-		
-		}
-	}
-</script>
-
-<style>
-	.content {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		justify-content: center;
-	}
-
-	.logo {
-		height: 200rpx;
-		width: 200rpx;
-		margin-top: 200rpx;
-		margin-left: auto;
-		margin-right: auto;
-		margin-bottom: 50rpx;
-	}
-
-	.text-area {
-		display: flex;
-		justify-content: center;
-	}
-
-	.title {
-		font-size: 36rpx;
-		color: #8f8f94;
-	}
-</style>

+ 213 - 0
pages/mine/camera/camera.nvue

@@ -0,0 +1,213 @@
+<template>
+	<view class="live-camera" :style="{ width: windowWidth, height: windowHeight }">
+		<live-pusher
+			id="livePusher"
+			ref="livePusher"
+			class="livePusher"
+			mode="FHD"
+			beauty="0"
+			whiteness="0"
+			:aspect="aspect"
+			min-bitrate="1000"
+			audio-quality="16KHz"
+			device-position="back"
+			:auto-focus="true"
+			:muted="true"
+			:enable-camera="true"
+			:enable-mic="false"
+			:zoom="false"
+			@statechange="statechange"
+			:style="{ width: windowWidth, height: windowHeight }"
+		></live-pusher>
+
+		<view class="menu">
+			<!--底部菜单区域背景-->
+			<cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image>
+
+			<!--返回键-->
+			<cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image>
+
+			<!--快门键-->
+			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image>
+
+			<!--反转键-->
+			<cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image>
+		</view>
+	</view>
+</template>
+
+<script>
+let _this = null;
+export default {
+	data() {
+		return {
+			poenCarmeInterval:null,//打开相机的轮询
+			aspect: '2:3', //比例
+			windowWidth: '', //屏幕可用宽度
+			windowHeight: '', //屏幕可用高度
+			camerastate: false, //相机准备好了
+			livePusher: null, //流视频对象
+			snapshotsrc: null //快照
+		};
+	},
+	onLoad(e) {
+		_this = this;
+		this.initCamera();
+	},
+	onReady() {
+		this.livePusher = uni.createLivePusherContext('livePusher', this);
+		this.startPreview(); //开启预览并设置摄像头
+		this.poenCarme();
+	},
+	methods: {
+		
+		//轮询打开
+		poenCarme(){
+			//#ifdef APP-PLUS
+			if (plus.os.name == 'Android') {
+				this.poenCarmeInterval = setInterval(function() {
+					console.log(_this.camerastate);
+					if (!_this.camerastate) _this.startPreview();
+				}, 2500);
+			}
+			//#endif
+		},
+		//初始化相机
+		initCamera() {
+			uni.getSystemInfo({
+				success: function(res) {
+					_this.windowWidth = res.windowWidth;
+					_this.windowHeight = res.windowHeight;
+					let zcs = _this.aliquot(_this.windowWidth,_this.windowHeight);
+					_this.aspect = (_this.windowWidth/zcs)+':'+(_this.windowHeight/zcs);
+					console.log('画面比例:'+_this.aspect);
+				}
+			});
+		},
+		
+		//整除数计算
+		aliquot(x, y) {
+			if (x % y == 0) return y;
+			return this.aliquot(y, x % y);
+		},
+
+		//开始预览
+		startPreview() {
+			this.livePusher.startPreview({
+				success: a => {
+					console.log(a)
+				}
+			});
+		},
+		
+		//停止预览
+		stopPreview() {
+			this.livePusher.stopPreview({
+				success: a => {
+					_this.camerastate = false; //标记相机未启动
+				}
+			});
+		},
+		
+		//状态
+		statechange(e) {
+			//状态改变
+			console.log(e);
+			if (e.detail.code == 1007) {
+				_this.camerastate = true;
+			} else if (e.detail.code == -1301) {
+				_this.camerastate = false;
+			}
+		},
+		
+
+		//返回
+		back() {
+			uni.navigateBack();
+		},
+
+		//抓拍
+		snapshot() {
+			//震动
+			uni.vibrateShort({
+			    success: function () {
+			        console.log('success');
+			    }
+			});
+			//拍照
+			this.livePusher.snapshot({
+				success: e => {
+					_this.snapshotsrc = e.message.tempImagePath;
+					_this.stopPreview();
+					_this.setImage();
+					uni.navigateBack();
+				}
+			});
+		},
+
+		//反转
+		flip() {
+			this.livePusher.switchCamera();
+		},
+
+		//设置
+		setImage() {
+			let pages = getCurrentPages();
+			let prevPage = pages[pages.length - 2]; //上一个页面
+
+			//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去
+			prevPage.$vm.setImage({ path: _this.snapshotsrc });
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.live-camera {
+	justify-content: center;
+	align-items: center;
+	.menu {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 750rpx;
+		height: 180rpx;
+		z-index: 98;
+		align-items: center;
+		justify-content: center;
+		.menu-mask {
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			width: 750rpx;
+			height: 180rpx;
+			z-index: 98;
+		}
+		.menu-back {
+			position: absolute;
+			left: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+		.menu-snapshot {
+			width: 130rpx;
+			height: 130rpx;
+			z-index: 99;
+		}
+		.menu-flip {
+			position: absolute;
+			right: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+	}
+}
+</style>

+ 246 - 0
pages/mine/camera/idcard/idcard.nvue

@@ -0,0 +1,246 @@
+<template>
+	<view class="live-camera" :style="{ width: windowWidth, height: windowHeight }">
+		<view class="preview" :style="{ width: windowWidth, height: windowHeight - 80 }">
+			<live-pusher
+				id="livePusher"
+				ref="livePusher"
+				class="livePusher"
+				mode="FHD"
+				beauty="0"
+				whiteness="0"
+				:aspect="aspect"
+				min-bitrate="1000"
+				audio-quality="16KHz"
+				device-position="back"
+				:auto-focus="true"
+				:muted="true"
+				:enable-camera="true"
+				:enable-mic="false"
+				:zoom="false"
+				@statechange="statechange"
+				:style="{ width: cameraWidth, height: cameraHeight }"
+			></live-pusher>
+
+			<!--提示语-->
+			<cover-view class="remind">
+				<text class="remind-text" style="">{{ message }}</text>
+			</cover-view>
+
+			<!--辅助线-->
+			<cover-view class="outline-box" :style="{ width: windowWidth, height: windowHeight - 80 }">
+				<cover-image
+					class="outline-img"
+					:src="dotype == 'idcardface' ? '/static/live-camera/outline/idcardface.png' : '/static/live-camera/outline/idcardbadge.png'"
+					style=""
+				></cover-image>
+			</cover-view>
+		</view>
+
+		<view class="menu">
+			<!--底部菜单区域背景-->
+			<cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image>
+
+			<!--返回键-->
+			<cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image>
+
+			<!--快门键-->
+			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image>
+
+			<!--反转键-->
+			<cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image>
+		</view>
+	</view>
+</template>
+
+<script>
+let _this = null;
+export default {
+	data() {
+		return {
+			poenCarmeInterval: null, //打开相机的轮询
+			dotype: 'face', //操作类型
+			message: '', //提示
+			aspect: '2:3', //比例
+			cameraWidth: '', //相机画面宽度
+			cameraHeight: '', //相机画面宽度
+			windowWidth: '', //屏幕可用宽度
+			windowHeight: '', //屏幕可用高度
+			camerastate: false, //相机准备好了
+			livePusher: null, //流视频对象
+			snapshotsrc: null //快照
+		};
+	},
+	onLoad(e) {
+		_this = this;
+		this.dotype = e.dotype;
+		this.initCamera();
+	},
+	onReady() {
+		this.livePusher = uni.createLivePusherContext('livePusher', this);
+		this.startPreview(); //开启预览并设置摄像头
+		this.poenCarme();
+	},
+	methods: {
+		//轮询打开
+		poenCarme() {
+			//#ifdef APP-PLUS
+			if (plus.os.name == 'Android') {
+				this.poenCarmeInterval = setInterval(function() {
+					console.log(_this.camerastate);
+					if (!_this.camerastate) _this.startPreview();
+				}, 2500);
+			}
+			//#endif
+		},
+		//初始化相机
+		initCamera() {
+			//处理安卓手机异步授权问题
+			uni.getSystemInfo({
+				success: function(res) {
+					_this.windowWidth = res.windowWidth;
+					_this.windowHeight = res.windowHeight;
+					_this.cameraWidth = res.windowWidth;
+					_this.cameraHeight = res.windowWidth * 1.5;
+				}
+			});
+		},
+
+		//开始预览
+		startPreview() {
+			this.livePusher.startPreview({
+				success: a => {
+					console.log(a);
+				}
+			});
+		},
+
+		//停止预览
+		stopPreview() {
+			this.livePusher.stopPreview({
+				success: a => {
+					_this.camerastate = false; //标记相机未启动
+				}
+			});
+		},
+
+		//状态
+		statechange(e) {
+			//状态改变
+			console.log(e);
+			if (e.detail.code == 1007) {
+				_this.camerastate = true;
+			} else if (e.detail.code == -1301) {
+				_this.camerastate = false;
+			}
+		},
+
+		//返回
+		back() {
+			uni.navigateBack();
+		},
+
+		//抓拍
+		snapshot() {
+			this.livePusher.snapshot({
+				success: e => {
+					_this.snapshotsrc = e.message.tempImagePath;
+					_this.stopPreview();
+					_this.setImage();
+					uni.navigateBack();
+				}
+			});
+		},
+
+		//反转
+		flip() {
+			this.livePusher.switchCamera();
+		},
+
+		//设置
+		setImage() {
+			let pages = getCurrentPages();
+			let prevPage = pages[pages.length - 2]; //上一个页面
+
+			//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去
+			prevPage.$vm.setImage({ path: _this.snapshotsrc, dotype: this.dotype });
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.live-camera {
+	.preview {
+		justify-content: center;
+		align-items: center;
+		.outline-box {
+			position: absolute;
+			top: 0;
+			left: 0;
+			bottom: 0;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+			.outline-img {
+				width: 750rpx;
+				height: 1125rpx;
+			}
+		}
+		.remind {
+			position: absolute;
+			top: 880rpx;
+			width: 750rpx;
+			z-index: 100;
+			align-items: center;
+			justify-content: center;
+			.remind-text {
+				color: #dddddd;
+				font-weight: bold;
+			}
+		}
+	}
+	.menu {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 750rpx;
+		height: 180rpx;
+		z-index: 98;
+		align-items: center;
+		justify-content: center;
+		.menu-mask {
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			width: 750rpx;
+			height: 180rpx;
+			z-index: 98;
+		}
+		.menu-back {
+			position: absolute;
+			left: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+		.menu-snapshot {
+			width: 130rpx;
+			height: 130rpx;
+			z-index: 99;
+		}
+		.menu-flip {
+			position: absolute;
+			right: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+	}
+}
+</style>

+ 240 - 0
pages/mine/camera/idphoto/idphoto.nvue

@@ -0,0 +1,240 @@
+<template>
+	<view class="live-camera" :style="{ width: windowWidth, height: windowHeight }">
+		<view class="preview" :style="{ width: windowWidth, height: windowHeight - 80 }">
+			<live-pusher
+				id="livePusher"
+				ref="livePusher"
+				class="livePusher"
+				mode="FHD"
+				beauty="1"
+				whiteness="0"
+				:aspect="aspect"
+				min-bitrate="1000"
+				audio-quality="16KHz"
+				device-position="back"
+				:auto-focus="true"
+				:muted="true"
+				:enable-camera="true"
+				:enable-mic="false"
+				:zoom="false"
+				@statechange="statechange"
+				:style="{ width: cameraWidth, height: cameraHeight }"
+			></live-pusher>
+
+			<!--提示语-->
+			<cover-view class="remind">
+				<text class="remind-text" style="">{{ message }}</text>
+			</cover-view>
+
+			<!--辅助线-->
+			<cover-view class="outline-box" :style="{ width: windowWidth, height: windowHeight - 80 }">
+				<cover-image class="outline-img" src="/static/live-camera/outline/idphotoskin.png" style=""></cover-image>
+			</cover-view>
+		</view>
+
+		<view class="menu">
+			<!--底部菜单区域背景-->
+			<cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image>
+
+			<!--返回键-->
+			<cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image>
+
+			<!--快门键-->
+			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image>
+
+			<!--反转键-->
+			<cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image>
+		</view>
+	</view>
+</template>
+
+<script>
+let _this = null;
+export default {
+	data() {
+		return {
+			dotype: 'idphoto', //操作类型
+			message: '', //提示
+			aspect: '2:3', //比例
+			cameraWidth: '', //相机画面宽度
+			cameraHeight: '', //相机画面宽度
+			windowWidth: '', //屏幕可用宽度
+			windowHeight: '', //屏幕可用高度
+			camerastate: false, //相机准备好了
+			livePusher: null, //流视频对象
+			snapshotsrc: null //快照
+		};
+	},
+	onLoad(e) {
+		_this = this;
+		if (e.dotype != undefined) this.dotype = e.dotype;
+		this.initCamera();
+	},
+	onReady() {
+		this.livePusher = uni.createLivePusherContext('livePusher', this);
+		this.startPreview(); //开启预览并设置摄像头
+		this.poenCarme();
+	},
+	methods: {
+		//轮询打开
+		poenCarme() {
+			//#ifdef APP-PLUS
+			if (plus.os.name == 'Android') {
+				this.poenCarmeInterval = setInterval(function() {
+					console.log(_this.camerastate);
+					if (!_this.camerastate) _this.startPreview();
+				}, 2500);
+			}
+			//#endif
+		},
+
+		//初始化相机
+		initCamera() {
+			uni.getSystemInfo({
+				success: function(res) {
+					_this.windowWidth = res.windowWidth;
+					_this.windowHeight = res.windowHeight;
+					_this.cameraWidth = res.windowWidth;
+					_this.cameraHeight = res.windowWidth * 1.5;
+				}
+			});
+		},
+
+		//开始预览
+		startPreview() {
+			this.livePusher.startPreview({
+				success: a => {
+					console.log(a);
+				}
+			});
+		},
+		//停止预览
+		stopPreview() {
+			this.livePusher.stopPreview({
+				success: a => {
+					_this.camerastate = false; //标记相机未启动
+				}
+			});
+		},
+
+		//状态
+		statechange(e) {
+			//状态改变
+			console.log(e);
+			if (e.detail.code == 1007) {
+				_this.camerastate = true;
+			} else if (e.detail.code == -1301) {
+				_this.camerastate = false;
+			}
+		},
+
+		//返回
+		back() {
+			uni.navigateBack();
+		},
+
+		//抓拍
+		snapshot() {
+			this.livePusher.snapshot({
+				success: e => {
+					_this.snapshotsrc = e.message.tempImagePath;
+					_this.stopPreview();
+					_this.setImage();
+					uni.navigateBack();
+				}
+			});
+		},
+
+		//反转
+		flip() {
+			this.livePusher.switchCamera();
+		},
+
+		//设置
+		setImage() {
+			let pages = getCurrentPages();
+			let prevPage = pages[pages.length - 2]; //上一个页面
+
+			//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去
+			prevPage.$vm.setImage({ path: _this.snapshotsrc, dotype: this.dotype });
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.live-camera {
+	.preview {
+		justify-content: center;
+		align-items: center;
+		.outline-box {
+			position: absolute;
+			top: 0;
+			left: 0;
+			bottom: 0;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+			.outline-img {
+				width: 750rpx;
+				height: 1125rpx;
+			}
+		}
+		.remind {
+			position: absolute;
+			top: 880rpx;
+			width: 750rpx;
+			z-index: 100;
+			align-items: center;
+			justify-content: center;
+			.remind-text {
+				color: #dddddd;
+				font-weight: bold;
+			}
+		}
+	}
+	.menu {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 750rpx;
+		height: 180rpx;
+		z-index: 98;
+		align-items: center;
+		justify-content: center;
+		.menu-mask {
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			width: 750rpx;
+			height: 180rpx;
+			z-index: 98;
+		}
+		.menu-back {
+			position: absolute;
+			left: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+		.menu-snapshot {
+			width: 130rpx;
+			height: 130rpx;
+			z-index: 99;
+		}
+		.menu-flip {
+			position: absolute;
+			right: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+	}
+}
+</style>

+ 214 - 0
pages/mine/camera/portrait/portrait.nvue

@@ -0,0 +1,214 @@
+<template>
+	<view class="live-camera" :style="{ width: windowWidth, height: windowHeight }">
+		<live-pusher
+			id="livePusher"
+			ref="livePusher"
+			class="livePusher"
+			mode="FHD"
+			beauty="0"
+			whiteness="0"
+			:aspect="aspect"
+			min-bitrate="1000"
+			audio-quality="16KHz"
+			device-position="back"
+			:auto-focus="true"
+			:muted="true"
+			:enable-camera="true"
+			:enable-mic="false"
+			:zoom="false"
+			:style="{ width: windowWidth, height: windowHeight }"
+		></live-pusher>
+
+		<!--提示语-->
+		<cover-view class="remind">
+			<text class="remind-text" style="">{{ message }}</text>
+		</cover-view>
+
+		<!--辅助线-->
+		<cover-view class="outline">
+			<cover-image class="outline" src="/static/live-camera/outline/portrait.png" style=""></cover-image>
+		</cover-view>
+		
+
+		<view class="menu">
+			<!--底部菜单区域背景-->
+			<cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image>
+
+			<!--返回键-->
+			<cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image>
+
+			<!--快门键-->
+			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image>
+
+			<!--反转键-->
+			<cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image>
+		</view>
+	</view>
+</template>
+
+<script>
+let _this = null;
+export default {
+	data() {
+		return {
+			message:'请拍摄苛学加',//提示
+			aspect: '2:3', //比例
+			windowWidth: '', //屏幕可用宽度
+			windowHeight: '', //屏幕可用高度
+			camerastate: false, //相机准备好了
+			livePusher: null, //流视频对象
+			snapshotsrc: null //快照
+		};
+	},
+	onLoad(e) {
+		_this = this;
+		this.initCamera();
+	},
+	onReady() {
+		this.livePusher = uni.createLivePusherContext('livePusher', this);
+		this.startPreview(); //开启预览并设置摄像头
+	},
+	methods: {
+		//初始化相机
+		initCamera() {
+			uni.getSystemInfo({
+				success: function(res) {
+					_this.windowWidth = res.windowWidth;
+					_this.windowHeight = res.windowHeight;
+					let zcs = _this.aliquot(_this.windowWidth, _this.windowHeight);
+					_this.aspect = _this.windowWidth / zcs + ':' + _this.windowHeight / zcs;
+				}
+			});
+		},
+
+		//整除数计算
+		aliquot(x, y) {
+			if (x % y == 0) return y;
+			return this.aliquot(y, x % y);
+		},
+
+		//开始预览
+		startPreview() {
+			this.livePusher.startPreview({
+				success: a => {
+					if (a.errMsg == 'startPreview:ok' || a.errMsg == 'operateLivePusher:ok') {
+						_this.camerastate = true; //标记相机启动成功
+					}
+				}
+			});
+		},
+		//停止预览
+		stopPreview() {
+			this.livePusher.stopPreview({
+				success: a => {
+					_this.camerastate = false; //标记相机未启动
+				}
+			});
+		},
+
+		//返回
+		back() {
+			uni.navigateBack();
+		},
+
+		//抓拍
+		snapshot() {
+			this.livePusher.snapshot({
+				success: e => {
+					_this.snapshotsrc = e.message.tempImagePath;
+					_this.stopPreview();
+					_this.setImage();
+					uni.navigateBack();
+				}
+			});
+		},
+
+		//反转
+		flip() {
+			this.livePusher.switchCamera();
+		},
+
+		//设置
+		setImage() {
+			let pages = getCurrentPages();
+			let prevPage = pages[pages.length - 2]; //上一个页面
+
+			//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去
+			prevPage.$vm.setImage({ path: _this.snapshotsrc });
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.live-camera {
+	justify-content: center;
+	align-items: center;
+	.outline {
+		position: absolute;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		width: 750rpx;
+		height: 1125rpx;
+		z-index: 99;
+		align-items: center;
+		justify-content: center;
+	}
+	.remind {
+		position: absolute;
+		top: 880rpx;
+		width: 750rpx;
+		z-index: 100;
+		align-items: center;
+		justify-content: center;
+		.remind-text {
+			color: #dddddd;
+			font-weight: bold;
+		}
+	}
+	.menu {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 750rpx;
+		height: 180rpx;
+		z-index: 98;
+		align-items: center;
+		justify-content: center;
+		.menu-mask {
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			width: 750rpx;
+			height: 180rpx;
+			z-index: 98;
+		}
+		.menu-back {
+			position: absolute;
+			left: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+		.menu-snapshot {
+			width: 130rpx;
+			height: 130rpx;
+			z-index: 99;
+		}
+		.menu-flip {
+			position: absolute;
+			right: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+	}
+}
+</style>

+ 228 - 0
pages/mine/camera/watermark/watermark.nvue

@@ -0,0 +1,228 @@
+<template>
+	<view class="live-camera" :style="{ width: windowWidth, height: windowHeight }">
+		<view class="preview" :style="{ width: windowWidth, height: windowHeight}">
+			<live-pusher
+				id="livePusher"
+				ref="livePusher"
+				class="livePusher"
+				mode="FHD"
+				beauty="0"
+				whiteness="0"
+				:aspect="aspect"
+				min-bitrate="1000"
+				audio-quality="16KHz"
+				device-position="back"
+				:auto-focus="true"
+				:muted="true"
+				:enable-camera="true"
+				:enable-mic="false"
+				:zoom="false"
+				@statechange="statechange"
+				:style="{ width: windowWidth, height: windowHeight }"
+			></live-pusher>
+			<!--提示语-->
+			<cover-view class="remind">
+				<text class="remind-text" style="">{{ message }}</text>
+			</cover-view>
+		</view>
+		<view class="menu">
+			<!--底部菜单区域背景-->
+			<cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image>
+
+			<!--返回键-->
+			<cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image>
+
+			<!--快门键-->
+			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image>
+
+			<!--反转键-->
+			<cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image>
+		</view>
+	</view>
+</template>
+
+<script>
+let _this = null;
+export default {
+	data() {
+		return {
+			dotype:'watermark',
+			message:'live-camer',//水印内容
+			poenCarmeInterval: null, //打开相机的轮询
+			aspect: '2:3', //比例
+			windowWidth: '', //屏幕可用宽度
+			windowHeight: '', //屏幕可用高度
+			camerastate: false, //相机准备好了
+			livePusher: null, //流视频对象
+			snapshotsrc: null //快照
+		};
+	},
+	onLoad(e) {
+		_this = this;
+		if (e.dotype != undefined) this.dotype = e.dotype;
+		this.initCamera();
+	},
+	onReady() {
+		this.livePusher = uni.createLivePusherContext('livePusher', this);
+		this.startPreview(); //开启预览并设置摄像头
+		this.poenCarme();
+	},
+	methods: {
+		//轮询打开
+		poenCarme() {
+			//#ifdef APP-PLUS
+			if (plus.os.name == 'Android') {
+				this.poenCarmeInterval = setInterval(function() {
+					console.log(_this.camerastate);
+					if (!_this.camerastate) _this.startPreview();
+				}, 2500);
+			}
+			//#endif
+		},
+		//初始化相机
+		initCamera() {
+			uni.getSystemInfo({
+				success: function(res) {
+					_this.windowWidth = res.windowWidth;
+					_this.windowHeight = res.windowHeight;
+					let zcs = _this.aliquot(_this.windowWidth, _this.windowHeight);
+					_this.aspect = _this.windowWidth / zcs + ':' + _this.windowHeight / zcs;
+					console.log('画面比例:'+_this.aspect);
+				}
+			});
+		},
+
+		//整除数计算
+		aliquot(x, y) {
+			if (x % y == 0) return y;
+			return this.aliquot(y, x % y);
+		},
+
+		//开始预览
+		startPreview() {
+			this.livePusher.startPreview({
+				success: a => {
+					console.log(a);
+				}
+			});
+		},
+
+		//停止预览
+		stopPreview() {
+			this.livePusher.stopPreview({
+				success: a => {
+					_this.camerastate = false; //标记相机未启动
+				}
+			});
+		},
+
+		//状态
+		statechange(e) {
+			//状态改变
+			console.log(e);
+			if (e.detail.code == 1007) {
+				_this.camerastate = true;
+			} else if (e.detail.code == -1301) {
+				_this.camerastate = false;
+			}
+		},
+
+		//返回
+		back() {
+			uni.navigateBack();
+		},
+
+		//抓拍
+		snapshot() {
+			this.livePusher.snapshot({
+				success: e => {
+					_this.snapshotsrc = e.message.tempImagePath;
+					_this.stopPreview();
+					_this.setImage();
+					uni.navigateBack();
+				}
+			});
+		},
+
+		//反转
+		flip() {
+			this.livePusher.switchCamera();
+		},
+
+		//设置
+		setImage() {
+			let pages = getCurrentPages();
+			let prevPage = pages[pages.length - 2]; //上一个页面
+
+			//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去
+			prevPage.$vm.setImage({ path: _this.snapshotsrc , dotype: this.dotype });
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.live-camera {
+	justify-content: center;
+	align-items: center;
+	.preview {
+		justify-content: center;
+		align-items: center;
+		.remind {
+			position: absolute;
+			top: 60rpx;
+			left: 20rpx;
+			width: 130px;
+			z-index: 100;
+			.remind-text {
+				color: #dddddd;
+				font-size: 40rpx;
+				text-shadow: #fff 1px 0 0, #fff 0 1px 0, #fff -1px 0 0, #fff 0 -1px 0;
+			}
+		}
+	}
+	.menu {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 750rpx;
+		height: 180rpx;
+		z-index: 98;
+		align-items: center;
+		justify-content: center;
+		.menu-mask {
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			width: 750rpx;
+			height: 180rpx;
+			z-index: 98;
+		}
+		.menu-back {
+			position: absolute;
+			left: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+		.menu-snapshot {
+			width: 130rpx;
+			height: 130rpx;
+			z-index: 99;
+		}
+		.menu-flip {
+			position: absolute;
+			right: 30rpx;
+			bottom: 50rpx;
+			width: 80rpx;
+			height: 80rpx;
+			z-index: 99;
+			align-items: center;
+			justify-content: center;
+		}
+	}
+}
+</style>

+ 519 - 8
pages/mine/driverCertification.vue

@@ -1,20 +1,531 @@
-<!-- 司机认证 -->
 <template>
-	<view>
-		司机认证
+	<view class="content">
+		<view class="content1 content-other">
+			<view class="flex flex-space-between">
+				<view>姓名</view>
+				<u--input placeholder="请输入内容" inputAlign='right' border="none" v-model="dataDetails.driverName">
+				</u--input>
+			</view>
+			<view class="flex flex-space-between">
+				<view>联系电话</view>
+				<u--input placeholder="请输入联系电话" inputAlign='right' border="none" v-model="dataDetails.driverPhone">
+				</u--input>
+			</view>
+			<view class="flex s-row" v-for="(item,index) in dataDetails.driverCarInfoList" :key='index'>
+				<view class="flex flex-space-between width100">
+					<view class="left">
+						车牌号-{{index+1}}
+					</view>
+					<view class="right flex">
+						<input class="car-uumber" v-model='item.carNumber' @click.stop="handleShowKeyboard(index)"
+							:disabled="true" placeholder="输入7位车牌号" name="input"></input>
+						<!-- <u-input v-model="item1.carNo" placeholder="输入7位车牌号" /> -->
+						<view class="flex">
+							<view @click="addCarNumber(dataDetails.driverCarInfoList)" style="margin-right: 20rpx;">
+								<image class='row4-img'
+									src="https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/jia%402x.png">
+								</image>
+							</view>
+							<view @click="delCarNumber(dataDetails.driverCarInfoList,index)">
+								<image class='row4-img'
+									src="https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/jian%402x.png">
+								</image>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="width100">
+					<view class="">人车合影-{{index+1}}</view>
+					<u-button type="primary" @click="uploadImg(0,item)">上传人车合影</u-button>
+					<image class="preview" :src="item.addressUrl" mode="aspectFit"
+						style="width:710rpx:height:710rpx;margin: 20rpx;">
+						<!-- 		<upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="1"
+						:size-type="['compressed']" @on-success="getImgUrl" @on-error="onError" @on-remove="onRemove"
+						@on-uploaded="isAdd = true" :before-upload="filterFileType" @on-progress="onProgress"></upload> -->
+				</view>
+			</view>
+		</view>
+		<u-divider text="分割线"></u-divider>
+		<view class="content2 content-other">
+			<u-button type="primary" @click="uploadImg(1)">上传身份证人像</u-button>
+			<!-- <upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="1"
+				:size-type="['compressed']" @on-success="getImgUrl1" @on-error="onError" @on-remove="onRemove"
+				@on-uploaded="isAdd = true" :before-upload="filterFileType" :options="uploadOptions1"
+				:custom="uploadCustom1" @on-progress="onProgress"></upload> -->
+			<!-- <navigator class="buttons" url="./camera/idcard/idcard?dotype=face"><button type="primary">打开身份证人像面采集相机</button></navigator> -->
+			<!-- <view>拍摄结果预览图,见下方</view> -->
+			<image class="preview" :src="dataDetails.cardAddressUrl" mode="aspectFit"
+				style="width:710rpx:height:710rpx;margin: 20rpx;">
+			</image>
+			<view class="flex flex-space-between">
+				<view>身份证号</view>
+				<u--input placeholder="请输入身份证号" inputAlign='right' border="none" v-model="dataDetails.numberCard">
+				</u--input>
+			</view>
+			<u-button type="primary" @click="uploadImg(2)">上传身份证国徽页</u-button>
+			<image class="preview" :src="dataDetails.cardBackAddressUrl" mode="aspectFit"
+				style="width:710rpx:height:710rpx;margin: 20rpx;">
+			</image>
+			<view class="flex flex-space-between">
+				<view>身份证截止日期</view>
+				<view class="" @click="selectValidityPeriod">
+					{{dataDetails.cardValidityDate?dataDetails.cardValidityDate:'选择身份证截止日期'}}</view>
+
+			</view>
+			<u-picker :show="isShowcardValidity" ref="uPicker" :columns="validityPeriod"
+				@confirm="confirmValidityPeriod" @change="changeHandler">
+			</u-picker>
+		</view>
+		<u-divider text="分割线"></u-divider>
+		<view class="content3 flex s-row" v-for="(item,index) in dataDetails.bankList" :key='index'>
+			<view class="flex flex-space-between width100">
+				<view class="left">
+					银行卡-{{index+1}}
+				</view>
+				<view class="right flex">
+					<view class="flex">
+						<view @click="addBankNumber(dataDetails.bankList)" style="margin-right: 20rpx;">
+							<image class='row4-img'
+								src="https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/jia%402x.png">
+							</image>
+						</view>
+						<view @click="delBankNumber(dataDetails.bankList,index)">
+							<image class='row4-img'
+								src="https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/jian%402x.png">
+							</image>
+						</view>
+					</view>
+				</view>
+			</view>
+			<!-- 	<view class="width100">
+				<view class="">上传银行卡号面</view>
+				<upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="1"
+					:size-type="['compressed']" @on-success="getImgUrl" @on-remove="onRemove" delIconSize='30'
+					delBgColor='rgba(0,0,0,0.4)' delIcon="trash" @on-uploaded="isAdd = true"
+					:before-upload="filterFileType" :options="uploadOptions3" :custom="uploadCustom3"></upload>
+			</view> -->
+			<u-button type="primary" @click="uploadImg(3)">上传银行卡号页</u-button>
+			<view class="flex flex-space-between width100">
+				<view>银行卡卡号</view>
+				<view class="flex">
+					<u--input placeholder="输入银行卡号码" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+					<u--image src="../../static/images/xiangji-2.png" width="40px" height="40px" @click='photograph'>
+					</u--image>
+				</view>
+			</view>
+			<view class="flex flex-space-between width100">
+				<view>开户行</view>
+				<view class="flex">
+					<u--input placeholder="输入开户行" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+				</view>
+			</view>
+			<view class="flex flex-space-between width100">
+				<view>开户支行</view>
+				<view class="flex">
+					<u--input placeholder="选择开户支行" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+					<view>手动输入</view>
+				</view>
+			</view>
+			<view class="flex flex-space-between width100">
+				<view>收款人</view>
+				<view class="flex">
+					<u--input placeholder="输入收款人姓名" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+				</view>
+			</view>
+		</view>
+		<view class="content4">
+			<u-button type="primary" @click="next()">
+				下一步
+			</u-button>
+		</view>
+		<master-keyboard ref="keyboard" keyboardtype="car" :show="keyShow" :randomNumber="true" :newCar="false"
+			:defaultValue="carNumber" @keyboardClick="handleClick"></master-keyboard>
+		<u-toast ref="uToast"></u-toast>
+		<u-action-sheet :actions="$helper.imgTypeList" :title="$helper.imgType" :show="isShowimgType"
+			@select="imgTypeSelect" :closeOnClickOverlay="true" :closeOnClickAction="true" @close="isShowimgType=false">
+		</u-action-sheet>
 	</view>
 </template>
 
 <script>
+	import keyboard from "@/components/master-keyboard/master-keyboard.vue";
+	import upload from '@/components/upload.vue';
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	var _this;
 	export default {
+		components: {
+			keyboard,
+			upload
+		},
 		data() {
 			return {
-				
+				index:'',
+				validityPeriod: [],
+				isShowcardValidity: false,
+				uploadType: '',
+				isShowimgType: false,
+				// uploadOptions1: {
+				// 	"text": "上传身份证头像页",
+				// 	"bgc": "https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/identityup%282%29.png"
+				// },
+				// uploadOptions2: {
+				// 	"text": "上传身份证国徽页",
+				// 	"bgc": "https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/identitylow%282%29.png"
+				// },
+				// uploadOptions3: {
+				// 	"text": "上传银行卡正面",
+				// 	"bgc": "https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/bankup%282%29.png"
+				// },
+				carInfo: '',
+				dataDetails: {
+					commonId: '',
+					driverName: '',
+					driverPhone: '',
+					cardAddressUrl: '',
+					cardBackAddressUrl: '',
+					cardValidityDate: '',
+					driverType: '',
+					driverLicenseHomePage: '',
+					driverLicenseBackPage: '',
+					driverLicenseValidityDate: '',
+					drivingLicenseHomePage: '',
+					drivingLicenseBackPage: '',
+					drivingLicenseValidityDate: '',
+					trailerLicenseHomePage: '',
+					trailerLicenseBackPage: '',
+					trailerLicenseValidityDate: '',
+					qualificationCertificate: '',
+					qualificationCertificateValidityDate: '',
+					operationCertificate: '',
+					operationCertificateValidityDate: '',
+					trailerOperationCertificate: '',
+					trailerOperationCertificateValidityDate: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					numberCard: '',
+					driverCarInfoList: [{
+						carNumber: '',
+						addressUrl: ''
+					}],
+					driverPayeeInfoList: [{
+						payeeAddressUrl: '',
+						bankCard: '',
+						bankDeposit: '',
+						bankDepositBranch: '',
+						payeeName: ''
+					}],
+				},
+				keyShow: false,
+				carNumber: '',
+				action: this.$helper.ossUploadUrl,
+				maxSize: 50 * 1024 * 1024, //限制文件大小 50M
+				isAdd: true,
+				imagesrc: ''
 			};
-		}
-	}
-</script>
+		},
+		onLoad() {
+			_this = this;
+			this.makeValidityPeriod()
+		},
+		methods: {
+			changeHandler(e) {
+				const {
+					columnIndex,
+					value,
+					values,
+					index,
+					picker = this.$refs.uPicker
+				} = e
+
+				// if (columnIndex === 0) {
+				// 	debugger
+				// 	if (e.index != 0) {
+				// 		picker.setColumnValues(1, this.validityPeriod[1].shift())
+				// 	}
+
+				// } else if (columnIndex === 1) {
+				// 	if (e.index != 0) {
+				// 		picker.setColumnValues(2, this.validityPeriod[2].shift())
+				// 	}
+				// }
+			},
+			// 回调参数为包含columnIndex、value、values
+			confirmValidityPeriod(e) {
+				debugger
+				console.log('confirm', e)
+				if (e.value[0] == '长期') {
+					this.dataDetails.cardValidityDate = e.value[0]
+				} else {
+					this.dataDetails.cardValidityDate = e.value[0] + '-' + e.value[1] + '-' + e.value[2]
+				}
+
+				this.isShowcardValidity = false
+			},
+			makeValidityPeriod() {
+				//获取当前年
+				let nowDate = new Date();
+				let year = nowDate.getFullYear()
+				let _list1 = ['长期']
+				// let _list2 = ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]
+				let _list2 = ['长期', "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]
+				let _list3 = ['长期', "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14",
+					"15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
+					"31"
+				]
+				let _ValidityPeriod = []
+				for (let i = 0; i < 30; i++) {
+					_list1.push(year + i)
+				}
+				this.validityPeriod.push(_list1, _list2, _list3)
+
+			},
+			selectValidityPeriod() {
+				this.isShowcardValidity = true
+			},
+			//设置图片
+			setImage(e) {
+				debugger
+				console.log(e);
+				//显示在页面
+				//this.imagesrc = e.path;
+				if (e.dotype == 'idphoto') {
+					_this.zjzClipper(e.path);
+				} else if (e.dotype == 'watermark') {
+					_this.watermark(e.path);
+				} else {
+					_this.savePhoto(e.path);
+				}
+			},
+			//保存图片到相册,方便核查
+			savePhoto(path) {
+				debugger
+				this.imagesrc = path;
+				uploadImage(path, 'appData/',
+					result => {
+						// 上传成功
+						console.log('图片地址', result)
+					}
+				)
+				//保存到相册
+				// uni.saveImageToPhotosAlbum({
+				// 	filePath: path,
+				// 	success: () => {
+				// 		uni.showToast({
+				// 			title: '已保存至相册',
+				// 			duration: 2000
+				// 		});
+				// 	}
+				// });
+			},
+			uploadImg(type, val) {
+				debugger
+				this.uploadType = type
+				this.isShowimgType = true
+				this.carInfo = val
+			},
+			photograph() {
+				console.log('拍照')
+				let that = this;
+				uni.chooseImage({
+					count: 1,
+					success: function(res) {
+						console.log(JSON.stringify(res.tempFilePaths));
+						uploadImage(res.tempFilePaths[0], 'appData/',
+							result => {
+								// 上传成功
+								console.log('图片地址', result)
+							}
+						)
+					}
+				});
 
-<style lang="scss">
+			},
+			imgTypeSelect(val) {
+				debugger
+				console.log(val)
+				console.log(this.uploadType)
+				if (val.name == '相册') {
+					uni.chooseImage({
+						count: 1,
+						sourceType: this.$helper.chooseImage.sourceType,
+						success: function(res) {
+							console.log(JSON.stringify(res.tempFilePaths));
+							uploadImage(res.tempFilePaths[0], 'appData/',
+								result => {
 
+									// 上传成功
+									console.log('图片地址', result)
+									switch (_this.uploadType) {
+										case 0:
+											//赋值上传图片图片路径
+											for (let i = 0; i < _this.dataDetails.driverCarInfoList
+												.length; i++) {
+												let _item = _this.dataDetails.driverCarInfoList[i]
+												if (_item.carNumber == _this.carInfo.carNumber) {
+													_item.addressUrl = result
+													}
+										}
+										
+											console.log('人车合影')
+											break
+										case 1:
+											console.log('身份正面')
+											break
+										case 2:
+											console.log('身份反面')
+											break
+										case 3:
+											console.log('银行卡')
+											break
+										case 4:
+									}
+								}
+							)
+						}
+					});
+
+				} else {
+					switch (this.uploadType) {
+						case 0:
+							console.log('人车合影')
+							break
+						case 1:
+							uni.$u.route('/pages/mine/camera/idcard/idcard?dotype=face');
+							console.log('身份正面')
+							break
+						case 2:
+							console.log('身份反面')
+							break
+						case 3:
+							console.log('银行卡')
+							break
+						case 4:
+					}
+				}
+
+			},
+			//身份证正面
+			getImgUrl1(src) {
+				// console.log(src)
+				// console.log('------------res-----------')
+				// let that = this;
+				// that.id[0] = src
+				// that.id1 = src
+				// that.certificates = false
+				// that.personImgs.personImg = that.id[0]
+				// that.$api.doRequest('get', '/driverViewInfo/personShibie', that
+				// 	.personImgs).then(res => {
+				// 	if (res.data.data.recPerson != null) {
+				// 		if (res.data.data.recPerson != "") {
+				// 			that.$set(that.DriverViewInfo, 'driverName', res
+				// 				.data.data.recPerson)
+				// 		}
+				// 	}
+				// 	if (res.data.data.recPersonNo != null) {
+				// 		if (res.data.data.recPersonNo != "") {
+				// 			that.$set(that.DriverViewInfo, 'numberCard', res
+				// 				.data.data.recPersonNo)
+				// 		}
+				// 	}
+				// }).catch(res => {
+				// 	uni.showToast({
+				// 		title: res.data.message,
+				// 		icon: 'none',
+				// 		duration: 2000
+				// 	})
+				// })
+			},
+			handleClick(e) {debugger
+				this.carNumber = e.value
+				this.dataDetails.driverCarInfoList[this.index].carNumber = e.value //键盘输入值
+			},
+			handleShowKeyboard(index) {
+				debugger
+				if (this.dataDetails.driverCarInfoList[index].carNumber == '') {
+					this.carNumber = ''
+				} else {
+					this.carNumber = this.dataDetails.driverCarInfoList[index].carNumber
+				}
+				if (this.$refs.keyboard.open) {
+					this.$refs.keyboard.open(false) //true 键盘显示 false 键盘隐藏
+				} else {
+					this.$refs.keyboard[0].open(false)
+				}
+				this.index = index
+				if (this.$refs.keyboard.open) {
+					this.$refs.keyboard.open(true) //true 键盘显示 false 键盘隐藏
+				} else {
+					this.$refs.keyboard[0].open(true)
+				}
+			},
+			addCarNumber(val) {
+				val.push({
+					carNo: ''
+				})
+			},
+			delCarNumber(val, index) {
+				if (val.length > 1) {
+					val.splice(index, 1)
+					this.$forceUpdate()
+				} else {
+					let params = {
+						type: 'error',
+						message: "至少保留一个车牌号!",
+						iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+					}
+					this.$refs.uToast.show({
+						...params
+					})
+				}
+			},
+			addBankNumber(val) {
+				val.push({
+					bankNo: ''
+				})
+			},
+			delBankNumber(val, index) {
+				if (val.length > 1) {
+					val.splice(index, 1)
+					this.$forceUpdate()
+				} else {
+					let params = {
+						type: 'error',
+						message: "至少保留一张银行卡!",
+						iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+					}
+					this.$refs.uToast.show({
+						...params
+					})
+				}
+			},
+			next(val) {
+				console.log(111111111111)
+				uni.$u.route('/pages/mine/driverCertificationNext', {
+					id: 1,
+				});
+			}
+
+		},
+	};
+</script>
+
+<style scoped lang="scss">
+	.row4-img {
+		width: 32rpx;
+		height: 32rpx;
+	}
 </style>

+ 329 - 0
pages/mine/driverCertificationNext.vue

@@ -0,0 +1,329 @@
+<template>
+	<view class="content">
+		<u-radio-group v-model="radiovalue1" iconPlacement="row">
+			<u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in radiolist1" :key="index"
+				:label="item.name" :name="item.name" @change="radioChange">
+			</u-radio>
+		</u-radio-group>
+
+		<view class="level1-title">证件信息</view>
+		<view class="content1">
+			<view class="flex flex-space-between">
+				<view class="left">
+					<view>驾驶证主页</view>
+					<u-button type="primary">上传驾驶证主页</u-button>
+				</view>
+				<view class="left">
+					<view>驾驶证副页</view>
+					<u-button type="primary">上传驾驶证副页</u-button>
+				</view>
+			</view>
+			<view class="flex flex-space-between">
+				<view>驾驶证有效期</view>
+				<view>选择驾驶证有效期</view>
+			</view>
+		</view>
+
+		<u-divider text="分割线"></u-divider>
+		<view class="content2">
+			<view class="flex flex-space-between">
+				<view class="left">
+					<view>行驶证主页</view>
+					<u-button type="primary">上传行驶证主页</u-button>
+				</view>
+				<view class="left">
+					<view>行驶证副页</view>
+					<u-button type="primary">上传行驶证副页</u-button>
+				</view>
+			</view>
+			<view class="flex flex-space-between">
+				<view>行驶证有效期</view>
+				<view>选择行驶证有效期</view>
+			</view>
+		</view>
+		<u-divider text="分割线"></u-divider>
+		<view class="content3">
+			<view class="flex flex-space-between">
+				<view class="left">
+					<view>挂车行驶证主页</view>
+					<u-button type="primary">上传挂车行驶证主页</u-button>
+				</view>
+				<view class="left">
+					<view>挂车行驶证副页</view>
+					<u-button type="primary">上传挂车行驶证副页</u-button>
+				</view>
+			</view>
+			<view class="flex flex-space-between">
+				<view>挂车行驶证有效期</view>
+				<view>选择挂车行驶证有效期</view>
+			</view>
+			<u-divider text="分割线"></u-divider>
+		</view>
+		<view class="content4">
+			<view class="flex s-row">
+				<view class="">从业资格证</view>
+				<u-button type="primary">上传从业资格证</u-button>
+			</view>
+			<view class="flex flex-space-between">
+				<view>从业资格证有效期</view>
+				<view>选择从业资格证有效期</view>
+			</view>
+		</view>
+		<u-divider text="分割线"></u-divider>
+		<view class="content5">
+			<view class="flex s-row">
+				<view class="">运营证</view>
+				<u-button type="primary">上传运营证</u-button>
+			</view>
+			<view class="flex flex-space-between">
+				<view>运营证有效期</view>
+				<view>选择运营证有效期</view>
+			</view>
+		</view>
+		<u-divider text="分割线"></u-divider>
+		<view class="content6">
+			<view class="flex s-row">
+				<view class="">挂车运营证</view>
+				<u-button type="primary">上传挂车运营证</u-button>
+			</view>
+			<view class="flex flex-space-between">
+				<view>挂车运营证有效期</view>
+				<view>选择挂车运营证有效期</view>
+			</view>
+		</view>
+		<u-button type="primary" @click="submit">提交</u-button>
+		<u-toast ref="uToast"></u-toast>
+
+	</view>
+</template>
+
+<script>
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	var _this;
+	export default {
+		components: {},
+		data() {
+			return {
+				radiolist1: [{
+						name: '挂车司机',
+						disabled: false
+					},
+					{
+						name: '非挂车司机',
+						disabled: false
+					}
+				],
+				// u-radio-group的v-model绑定的值如果设置为某个radio的name,就会被默认选中
+				radiovalue1: '挂车司机',
+			};
+		},
+		onLoad(options) {
+			_this = this;
+			console.log(options)
+		},
+		methods: {
+			submit() {
+				// 校验
+				console.log('提交')
+			},
+			radioChange(n) {
+				console.log('radioChange', n);
+			},
+			//设置图片
+			setImage(e) {
+				debugger
+				console.log(e);
+				//显示在页面
+				//this.imagesrc = e.path;
+				if (e.dotype == 'idphoto') {
+					_this.zjzClipper(e.path);
+				} else if (e.dotype == 'watermark') {
+					_this.watermark(e.path);
+				} else {
+					_this.savePhoto(e.path);
+				}
+			},
+			//保存图片到相册,方便核查
+			savePhoto(path) {
+				debugger
+				this.imagesrc = path;
+				uploadImage(path, 'appData/',
+					result => {
+						// 上传成功
+						console.log('图片地址', result)
+					}
+				)
+				//保存到相册
+				// uni.saveImageToPhotosAlbum({
+				// 	filePath: path,
+				// 	success: () => {
+				// 		uni.showToast({
+				// 			title: '已保存至相册',
+				// 			duration: 2000
+				// 		});
+				// 	}
+				// });
+			},
+			uploadImg(type) {
+
+				this.uploadType = type
+				this.isShowimgType = true
+			},
+			photograph() {
+				console.log('拍照')
+				let that = this;
+				uni.chooseImage({
+					count: 1,
+					success: function(res) {
+						console.log(JSON.stringify(res.tempFilePaths));
+						uploadImage(res.tempFilePaths[0], 'appData/',
+							result => {
+								// 上传成功
+								console.log('图片地址', result)
+							}
+						)
+					}
+				});
+
+			},
+			imgTypeSelect(val) {
+				console.log(val)
+				console.log(this.uploadType)
+				if (val.name == '相册') {
+					uni.chooseImage({
+						count: 1,
+						sourceType: this.$helper.chooseImage.sourceType,
+						success: function(res) {
+							console.log(JSON.stringify(res.tempFilePaths));
+							uploadImage(res.tempFilePaths[0], 'appData/',
+								result => {
+									// 上传成功
+									console.log('图片地址', result)
+									switch (this.uploadType) {
+										case 0:
+											console.log('人车合影')
+											break
+										case 1:
+											console.log('身份正面')
+											break
+										case 2:
+											console.log('身份反面')
+											break
+										case 3:
+											console.log('银行卡')
+											break
+										case 4:
+									}
+								}
+							)
+						}
+					});
+
+				} else {
+					debugger
+					switch (this.uploadType) {
+						case 0:
+
+
+							console.log('人车合影')
+
+							break
+						case 1:
+							uni.$u.route('/pages/mine/camera/idcard/idcard?dotype=face');
+							console.log('身份正面')
+							break
+						case 2:
+							console.log('身份反面')
+							break
+						case 3:
+							console.log('银行卡')
+							break
+						case 4:
+					}
+				}
+
+			},
+			// 上传人车合影
+			unloadGroupPhoto() {
+				this.isShowimgType = true
+				// uni.chooseImage({
+				//     count: 1, 
+				//     success: function (res) {
+				//         console.log(JSON.stringify(res.tempFilePaths));
+				// 		uploadImage(res.tempFilePaths[0], 'appData/',
+				// 			result => {
+				// 				// 上传成功
+				// 				console.log('图片地址', result)
+				// 			}
+				// 		)
+				//     }
+				// });
+			},
+			//身份证正面
+			getImgUrl1(src) {
+				// console.log(src)
+				// console.log('------------res-----------')
+				// let that = this;
+				// that.id[0] = src
+				// that.id1 = src
+				// that.certificates = false
+				// that.personImgs.personImg = that.id[0]
+				// that.$api.doRequest('get', '/driverViewInfo/personShibie', that
+				// 	.personImgs).then(res => {
+				// 	if (res.data.data.recPerson != null) {
+				// 		if (res.data.data.recPerson != "") {
+				// 			that.$set(that.DriverViewInfo, 'driverName', res
+				// 				.data.data.recPerson)
+				// 		}
+				// 	}
+				// 	if (res.data.data.recPersonNo != null) {
+				// 		if (res.data.data.recPersonNo != "") {
+				// 			that.$set(that.DriverViewInfo, 'numberCard', res
+				// 				.data.data.recPersonNo)
+				// 		}
+				// 	}
+				// }).catch(res => {
+				// 	uni.showToast({
+				// 		title: res.data.message,
+				// 		icon: 'none',
+				// 		duration: 2000
+				// 	})
+				// })
+			},
+
+			// getImgUrl(res) {
+			// 	// this.detailData.addressUrl = res
+			// 	console.log(res)
+			// 	console.log('------------res-----------')
+			// },
+			// onError(error) {
+			// 	console.log('------------error-----------')
+			// 	console.log(error)
+			// },
+			// onRemove(index) {},
+			// filterFileType(index, lists) {
+			// 	if (lists[index].fileType != 'jpg' && lists[index].fileType != 'png' && lists[index].fileType != 'gif') {
+			// 		lists.splice(index, 1);
+			// 		// 当前文件不支持
+			// 		uni.showModal({
+			// 			title: '暂不支持当前图片类型',
+			// 			showCancel: false
+			// 		});
+			// 	} else {
+			// 		this.isAdd = false;
+			// 	}
+			// },
+			// onProgress(e) {
+			// 	console.log(e)
+			// },
+
+		},
+	};
+</script>
+
+<style scoped lang="scss">
+	.row4-img {
+		width: 32rpx;
+		height: 32rpx;
+	}
+</style>

+ 18 - 3
pages/mine/helpDescription.vue

@@ -1,7 +1,22 @@
 <!-- 帮助说明 -->
 <template>
-	<view>
-		帮助说明
+	<view class="content flex-center">
+		<view> 手机注册</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view>抢单</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view> 货主确认,签订三方合同</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view> 装车反馈,货主确认</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view> 平台支付运费预付款</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view> 卸车反馈,货主确认</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view> 平台支付运费尾款</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
+		<view> 评价订单</view>
+		<u-icon name="arrow-downward" size="28"></u-icon>
 	</view>
 </template>
 
@@ -9,7 +24,7 @@
 	export default {
 		data() {
 			return {
-				
+
 			};
 		}
 	}

+ 78 - 3
pages/mine/index.vue

@@ -1,16 +1,91 @@
 <!-- 我的 -->
 <template>
-	<view>
-		我的
+	<view class="content">
+		<view class="head">
+			<view class="row">
+				<u--image class="flex-end" :showLoading="true" src="../../static/images/mine/saoma.png" width="20px"
+					height="20px"></u--image>
+			</view>
+			<u--image class="flex-end" :showLoading="true" src="https://cdn.uviewui.com/uview/album/1.jpg" width="60px"
+				height="60px"></u--image>
+			<view @click="toLogin" class="information">{{hasLogin? userName : '立即登录' }}</view>
+
+			<view></view>
+		</view>
+		<view class="content1">
+			<view class="flex flex-space-between" @click="goDetailPage('/pages/mine/driverCertification')">
+				<view>身份管理</view>
+				<view>已认证></view>
+			</view>
+			<!-- <view class="flex flex-space-between" @click="goDetailPage('/pages/mine/driverCertification')">
+				<view>货主评价</view>
+				<view> > </view>
+			</view> -->
+			<view class="flex flex-space-between" @click="goDetailPage('/pages/mine/manageBankCards/index')">
+				<view>管理银行卡</view>
+				<view> > </view>
+			</view>
+			<view class="flex flex-space-between" @click="goDetailPage('/pages/mine/manageVehicles/index')">
+				<view>管理车辆</view>
+				<view> > </view>
+			</view>
+			<view class="flex flex-space-between" @click="$helper.contactCustomerService">
+				<view>联系客服</view>
+				<view> > </view>
+			</view>
+			<view class="flex flex-space-between" @click="goDetailPage('/pages/mine/helpDescription')">
+				<view>帮助说明</view>
+				<view> > </view>
+			</view>
+			<view class="flex flex-space-between" @click="goDetailPage('/pages/mine/set')">
+				<view>设置</view>
+				<view> > </view>
+			</view>
+		</view>
 	</view>
 </template>
 
 <script>
+	import {
+		mapState
+	} from 'vuex';
 	export default {
 		data() {
 			return {
-				
+				userName:'',
 			};
+		},
+		onLoad() {
+			debugger
+			this.userName = this.userInfo.userName
+		},
+		computed: {
+			...mapState(['hasLogin', 'userInfo']),
+			// 手机号中间4位加*
+			// starUserphone() {
+			// 	let reg = /^(\d{3})\d{4}(\d{4})$/;
+			// 	if (this.userphone) {
+			// 		return this.userphone.replace(reg, "$1****$2");
+			// 	}
+			// }
+		},
+		methods: {
+			goDetailPage(src) {
+				uni.$u.route(src);
+			},
+			toLogin() {
+				debugger
+				console.log("userInfo", this.userInfo)
+				if (!this.hasLogin || !this.userInfo || this.userName == "立即登录") {
+					uni.$u.route('/pages/public/login');
+				} else {}
+				// else if(!this.userInfo.nickname){
+				// 	this.inputShow = true
+				// 	this.inputStatus = 'inline'
+				// 	this.feild = "nickname"
+				// 	this.inputContent = ''
+				// }
+			},
 		}
 	}
 </script>

+ 220 - 8
pages/mine/manageBankCards/addBankCard.vue

@@ -1,20 +1,232 @@
-<!-- 添加银行卡 -->
 <template>
-	<view>
-		添加银行卡
+	<view class="content">
+		<view class="content3 flex s-row">
+			<view class="flex flex-space-between width100">
+				上传银行卡正面
+			</view>
+
+			<u-button type="primary" @click="uploadImg(3)">上传银行卡号页</u-button>
+			<view class="flex flex-space-between width100">
+				<view>银行卡卡号</view>
+				<view class="flex">
+					<u--input placeholder="输入银行卡号码" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+					<u--image src="../../static/images/xiangji-2.png" width="40px" height="40px" @click='photograph'>
+					</u--image>
+				</view>
+			</view>
+			<view class="flex flex-space-between width100">
+				<view>开户行</view>
+				<view class="flex">
+					<u--input placeholder="输入开户行" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+				</view>
+			</view>
+			<view class="flex flex-space-between width100">
+				<view>开户支行</view>
+				<view class="flex">
+					<u--input placeholder="选择开户支行" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+					<view>手动输入</view>
+				</view>
+			</view>
+			<view class="flex flex-space-between width100">
+				<view>收款人</view>
+				<view class="flex">
+					<u--input placeholder="输入收款人姓名" inputAlign='right' border="none" v-model="dataDetails.name">
+					</u--input>
+				</view>
+			</view>
+		</view>
+		<view class="" @click="submit">提交</view>
+		<u-action-sheet :actions="$helper.imgTypeList" :title="$helper.imgType" :show="isShowimgType"
+			@select="imgTypeSelect" :closeOnClickOverlay="true" :closeOnClickAction="true" @close="isShowimgType=false">
+		</u-action-sheet>
 	</view>
 </template>
 
 <script>
+	import upload from '@/components/upload.vue';
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	var _this;
 	export default {
+		components: {},
 		data() {
 			return {
-				
+				uploadType: '',
+				isShowimgType: false,
+				dataDetails: {
+					name: '阿萨啊',
+					carNumberList: [{
+						kahao: '',
+						addressUrl: ''
+					}],
+					bankList: [{
+						yhk: '',
+						kh: '',
+						khh: '',
+						khzh: '',
+						skr: ''
+					}],
+				},
+				imagesrc: ''
 			};
-		}
-	}
-</script>
+		},
+		onLoad() {
+			_this = this;
+		},
+		methods: {
+			//设置图片
+			setImage(e) {
+				debugger
+				console.log(e);
+				//显示在页面
+				//this.imagesrc = e.path;
+				if (e.dotype == 'idphoto') {
+					_this.zjzClipper(e.path);
+				} else if (e.dotype == 'watermark') {
+					_this.watermark(e.path);
+				} else {
+					_this.savePhoto(e.path);
+				}
+			},
+			//保存图片到相册,方便核查
+			savePhoto(path) {
+				debugger
+				this.imagesrc = path;
+				uploadImage(path, 'appData/',
+					result => {
+						// 上传成功
+						console.log('图片地址', result)
+					}
+				)
+				//保存到相册
+				// uni.saveImageToPhotosAlbum({
+				// 	filePath: path,
+				// 	success: () => {
+				// 		uni.showToast({
+				// 			title: '已保存至相册',
+				// 			duration: 2000
+				// 		});
+				// 	}
+				// });
+			},
+			uploadImg(type) {
+
+				this.uploadType = type
+				this.isShowimgType = true
+			},
+			photograph() {
+				console.log('拍照')
+				let that = this;
+				uni.chooseImage({
+					count: 1,
+					success: function(res) {
+						console.log(JSON.stringify(res.tempFilePaths));
+						uploadImage(res.tempFilePaths[0], 'appData/',
+							result => {
+								// 上传成功
+								console.log('图片地址', result)
+							}
+						)
+					}
+				});
 
-<style lang="scss">
+			},
+			imgTypeSelect(val) {
+				console.log(val)
+				console.log(this.uploadType)
+				if (val.name == '相册') {
+					uni.chooseImage({
+						count: 1,
+						sourceType: this.$helper.chooseImage.sourceType,
+						success: function(res) {
+							console.log(JSON.stringify(res.tempFilePaths));
+							uploadImage(res.tempFilePaths[0], 'appData/',
+								result => {
+									// 上传成功
+									console.log('图片地址', result)
+									switch (this.uploadType) {
+										case 0:
+											console.log('人车合影')
+											break
+										case 1:
+											console.log('身份正面')
+											break
+										case 2:
+											console.log('身份反面')
+											break
+										case 3:
+											console.log('银行卡')
+											break
+										case 4:
+									}
+								}
+							)
+						}
+					});
 
+				} else {
+					switch (this.uploadType) {
+						case 0:
+							console.log('人车合影')
+							break
+						case 1:
+							uni.$u.route('/pages/mine/camera/idcard/idcard?dotype=face');
+							console.log('身份正面')
+							break
+						case 2:
+							console.log('身份反面')
+							break
+						case 3:
+							console.log('银行卡')
+							break
+						case 4:
+					}
+				}
+
+			},
+			//身份证正面
+			getImgUrl1(src) {
+				// console.log(src)
+				// console.log('------------res-----------')
+				// let that = this;
+				// that.id[0] = src
+				// that.id1 = src
+				// that.certificates = false
+				// that.personImgs.personImg = that.id[0]
+				// that.$api.doRequest('get', '/driverViewInfo/personShibie', that
+				// 	.personImgs).then(res => {
+				// 	if (res.data.data.recPerson != null) {
+				// 		if (res.data.data.recPerson != "") {
+				// 			that.$set(that.DriverViewInfo, 'driverName', res
+				// 				.data.data.recPerson)
+				// 		}
+				// 	}
+				// 	if (res.data.data.recPersonNo != null) {
+				// 		if (res.data.data.recPersonNo != "") {
+				// 			that.$set(that.DriverViewInfo, 'numberCard', res
+				// 				.data.data.recPersonNo)
+				// 		}
+				// 	}
+				// }).catch(res => {
+				// 	uni.showToast({
+				// 		title: res.data.message,
+				// 		icon: 'none',
+				// 		duration: 2000
+				// 	})
+				// })
+			},
+			submit(){
+				console.log(' tijia')
+			},
+		},
+	};
+</script>
+
+<style scoped lang="scss">
+	.row4-img {
+		width: 32rpx;
+		height: 32rpx;
+	}
 </style>

+ 20 - 0
pages/mine/manageBankCards/editBankCard.vue

@@ -0,0 +1,20 @@
+<!-- 添加银行卡 -->
+<template>
+	<view>
+		修改银行卡
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss">
+
+</style>

+ 51 - 4
pages/mine/manageBankCards/index.vue

@@ -1,16 +1,63 @@
 <template>
-	<view>
-		
+	<view class="content">
+		<view class="" v-for="(item,index) in 4" :key='index'>
+			<view class="flex">
+				<view class="">中国银行</view>
+				<view>鲅鱼圈支行</view>
+			</view>
+			<view class="flex">收款人:张三</view>
+			<view class="flex flex-end">112 312 312 3123 1231 3123</view>
+			<view>
+				<view>
+					<radio :value="value" />
+					<view>设为默认收款账户</view>
+				</view>
+				<view>
+					<view @click="edit">修改</view>
+					<view>删除</view>
+				</view>
+			</view>
+		</view>
+		<view @click="addBankCard">添加银行卡</view>
+		<u-toast ref="uToast"></u-toast>
 	</view>
 </template>
 
 <script>
+	import {
+		mapState
+	} from 'vuex';
 	export default {
 		data() {
 			return {
-				
+				value: '111'
 			};
-		}
+		},
+		computed: {
+			...mapState(['hasLogin', 'userInfo']),
+		},
+		onLoad() {
+			if (!this.hasLogin) {
+				uni.$u.route('/pages/public/login');
+			}
+		},
+		methods: {
+			addBankCard() {
+				uni.$u.route('/pages/mine/manageBankCards/addBankCard');
+			},
+			edit() {
+				uni.$u.route('/pages/mine/manageBankCards/editBankCard');
+				let params = {
+					type: 'success',
+					message: "修改成功",
+					iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+				}
+				this.$refs.uToast.show({
+					...params
+				})
+			},
+		},
+
 	}
 </script>
 

+ 43 - 6
pages/mine/manageVehicles/addVehicle.vue

@@ -1,20 +1,57 @@
-<!-- 添加车辆 -->
+<!-- 管理车辆 -->
 <template>
-	<view>
-		添加车辆
+	<view class="content">
+		<view class="flex flex-space-between">
+			<view>车牌号</view>
+			<u--input placeholder="输入车牌号" inputAlign='right' border="none" v-model="carNumber"></u--input>
+		</view>
+		<view>上传人车合影(车头车牌号可见)</view>
+		<u-button type="primary" @click="unloadGroupPhoto()">上传人车合影</u-button>
+		<u-button type="primary" @click="submit">提交</u-button>
+		<u-toast ref="uToast"></u-toast>
 	</view>
 </template>
 
 <script>
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	var _this;
 	export default {
 		data() {
 			return {
-				
+				carNumber: '',
 			};
-		}
+		},
+		onLoad(options) {
+			_this = this;
+			console.log(options)
+		},
+		methods: {
+			unloadGroupPhoto() {
+				uni.chooseImage({
+					count: 1,
+					success: function(res) {
+						console.log(JSON.stringify(res.tempFilePaths));
+						uploadImage(res.tempFilePaths[0], 'appData/',
+							result => {
+								// 上传成功
+								console.log('图片地址', result)
+							}
+						)
+					}
+				});
+			},
+			submit(){
+				let params = {
+						type: 'success',
+						message: "提交成功",
+						iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+					}
+				this.$refs.uToast.show({...params})
+			},
+		},
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 
 </style>

+ 43 - 6
pages/mine/manageVehicles/editVehicle.vue

@@ -1,20 +1,57 @@
-修改车辆
+<!-- 管理车辆 -->
 <template>
-	<view>
-		修改车辆
+	<view class="content">
+		<view class="flex flex-space-between">
+			<view>车牌号</view>
+			<u--input placeholder="输入车牌号" inputAlign='right' border="none" v-model="carNumber"></u--input>
+		</view>
+		<view>上传人车合影(车头车牌号可见)</view>
+		<u-button type="primary" @click="unloadGroupPhoto()">上传人车合影</u-button>
+		<u-button type="primary" @click="submit">提交</u-button>
+		<u-toast ref="uToast"></u-toast>
 	</view>
 </template>
 
 <script>
+	import uploadImage from '@/components/ossutil/uploadFile.js';
+	var _this;
 	export default {
 		data() {
 			return {
-				
+				carNumber: '',
 			};
-		}
+		},
+		onLoad(options) {
+			_this = this;
+			console.log(options)
+		},
+		methods: {
+			unloadGroupPhoto() {
+				uni.chooseImage({
+					count: 1,
+					success: function(res) {
+						console.log(JSON.stringify(res.tempFilePaths));
+						uploadImage(res.tempFilePaths[0], 'appData/',
+							result => {
+								// 上传成功
+								console.log('图片地址', result)
+							}
+						)
+					}
+				});
+			},
+			submit(){
+				let params = {
+						type: 'success',
+						message: "修改成功",
+						iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+					}
+				this.$refs.uToast.show({...params})
+			},
+		},
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 
 </style>

+ 80 - 5
pages/mine/manageVehicles/index.vue

@@ -1,20 +1,95 @@
 <!-- 管理车辆 -->
 <template>
-	<view>
-		管理车辆
+	<view class="content">
+		<view class="content1">
+			<view class="content1-item inline-block ">
+				<u--image width='100%' height='100%' src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix">
+				</u--image>
+				<view class="flex flex-space-between">
+					<view>辽H11111</view>
+					<view>审核中</view>
+				</view>
+				<view class="flex">
+					<view>删除</view>
+					<view>修改</view>
+				</view>
+			</view>
+			<view class="content1-item inline-block ">
+				<u--image width='100%' height='100%' src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix">
+				</u--image>
+				<view class="flex flex-space-between">
+					<view>辽H11111</view>
+					<view>审核中</view>
+				</view>
+				<view class="flex">
+					<view>删除</view>
+					<view>修改</view>
+				</view>
+			</view>
+			<view class="content1-item inline-block ">
+				<u--image width='100%' height='100%' src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix">
+				</u--image>
+				<view class="flex flex-space-between">
+					<view>辽H11111</view>
+					<view>审核中</view>
+				</view>
+				<view class="flex">
+					<view>删除</view>
+					<view>修改</view>
+				</view>
+			</view>
+			<view class="content1-item inline-block ">
+				<u--image width='100%' height='100%' src="https://cdn.uviewui.com/uview/album/1.jpg" mode="widthFix">
+				</u--image>
+				<view class="flex flex-space-between">
+					<view>辽H11111</view>
+					<view>审核中</view>
+				</view>
+				<view class="flex">
+					<view @click="del">删除</view>
+					<view @click="edit">修改</view>
+				</view>
+			</view>
+		</view>
+		<u-button type="primary" @click="addCar">添加车辆</u-button>
 	</view>
 </template>
 
 <script>
+	import {
+		mapState
+	} from 'vuex';
+	var _this;
 	export default {
 		data() {
 			return {
-				
+
 			};
-		}
+		},
+		onLoad(options) {
+			_this = this;
+			console.log(options)
+			if (!this.hasLogin) {
+				uni.$u.route('/pages/public/login');
+			}
+		},
+		methods: {
+			addCar() {
+				uni.$u.route('/pages/mine/manageVehicles/addVehicle');
+			},
+			edit() {
+				uni.$u.route('/pages/mine/manageVehicles/editVehicle');
+			}
+		},
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
+	.content1 {
+		width: 100%;
+	}
 
+	.content1-item {
+		width: calc(50% - 0rpx);
+	}
 </style>

+ 244 - 6
pages/mine/set.vue

@@ -1,20 +1,258 @@
-<!-- 设置 -->
 <template>
-	<view>
-		设置
+	<view class="content">
+		<view class="cu-list menu text-left solid-top indexlow">
+			<view class='flex flex-space-between' @click="switchPicture">
+				<view>
+					<text>头像</text>
+				</view>
+				<view style='align-items: center;' class="flex">
+					<view class="pictures">
+						<image :src="headUrl" class="picture"></image>
+					</view>
+					<image src="../../static/images/myimg/gengduo1@3x.png" class="arrow"></image>
+				</view>
+			</view>
+			<view class='flex flex-space-between' @click="nickname(username)">
+				<view>
+					<text>姓名</text>
+				</view>
+				<view style='align-items: center;' class="flex">
+					<view class="username">
+						{{username}}
+					</view>
+					<image src="../../static/images/myimg/gengduo1@3x.png" class="arrow"></image>
+				</view>
+			</view>
+			<view class='flex flex-space-between' @click='UpdataPassword'>
+				<view>
+					<text>修改账号</text>
+				</view>
+				<image src="../../static/images/myimg/gengduo1@3x.png" class="arrow"></image>
+			</view>
+			<view class='flex flex-space-between' @click='UpdataPassword'>
+				<view>
+					<text>修改密码</text>
+				</view>
+				<image src="../../static/images/myimg/gengduo1@3x.png" class="arrow"></image>
+			</view>
+			<view class='flex flex-space-between' @click='fankui'>
+				<view>
+					<text>意见反馈</text>
+				</view>
+				<image src="../../static/images/myimg/gengduo1@3x.png" class="arrow"></image>
+			</view>
+			<view class='flex flex-space-between' @click='clearStorage'>
+				<view>
+					<text>清除缓存</text>
+				</view>
+				<image src="../../static/images/myimg/gengduo1@3x.png" class="arrow"></image>
+			</view>
+		</view>
+		<view class='exitloginwrap'>
+			<button @click='logout()' class='exitlogin'>退出登录</button>
+		</view>
+		<!-- <u-modal v-model="isShowAlert" :title-style="{fontSize: '18px',fontWeight:'500'}"
+			:content-style="{fontSize: '14px',fontWeight:'400'}" confirm-color='#22C572' confirm-text='确定' title='温馨提示'
+			showCancelButton='false' :content="content" @confirm="goOpenService" @cancel="cancelClick"></u-modal> -->
 	</view>
 </template>
 
 <script>
+	import {
+		mapState
+	} from 'vuex';
 	export default {
 		data() {
 			return {
-				
-			};
+				isShowAlert: false,
+				content: '您确定要退出吗?',
+				headUrl: "../../static/images/myimg/YongHu@3x.png",
+				username: "",
+				gridList: [{
+					num: 0,
+					name: '退出登录',
+					// icon:'cuIcon-exit',
+					src: '../../static/images/sign/return@3x.png',
+					tips: 0,
+					url: '',
+					show: true
+				}, ],
+			}
+		},
+		computed: {
+			// ...mapState(['hasLogin', 'userInfo'])
+		},
+		onShow() {
+			this.getList()
+		},
+		onLoad() {},
+		methods: {
+			UpdataPassword() {
+				uni.navigateTo({
+					url: `/pages/public/reset?phone=${this.userInfo.phone}`
+				})
+			},
+			clearStorage() {
+				let that = this
+				uni.clearStorage({
+					success: function(res) {
+						console.log('success');
+						that.goOpenService()
+					}
+				})
+			},
+			cancelClick() {
+				this.isShowAlert = false
+			},
+			goOpenService() {
+				uni.hideTabBarRedDot({
+					index: 3
+				})
+				uni.clearStorageSync();
+				var that = this
+				this.$api.doRequest('post', '/auth/api/logout').then(res => {
+					if (res.data.data) {
+
+					}
+				})
+				this.$store.commit('logout')
+				this.$api.logout()
+				uni.navigateTo({
+					url: `/pages/public/login`
+				})
+			},
+			getList() {
+				this.userInfo = uni.getStorageSync('userInfo')
+				this.headUrl = this.userInfo.avatarUrl
+				if (this.headUrl == null || this.headUrl == "") {
+					this.headUrl = "../../static/images/myimg/YongHu@3x.png"
+				}
+				this.username = this.userInfo.userName
+			},
+			switchPicture() {
+				uni.navigateTo({
+					url: `/pages/user/set_picture`
+				})
+			},
+			nickname(username) {
+				uni.navigateTo({
+					url: `/pages/user/set_nickname?nickname=${username}`
+				})
+			},
+			exitlogin() {
+
+			},
+			fankui() {
+				uni.navigateTo({
+					url: `/pages/user/fankui`
+				})
+			},
+			logout() {
+				// const that = this
+				this.isShowAlert = true
+				// uni.showModal({
+				// 	title: '询问',
+				// 	content: '您确定要退出吗?',
+				// 	cancelText: '取消',
+				// 	confirmText: '确定',
+				// 	success: (e) => {
+				// 		if (e.confirm) {
+				// 			uni.hideTabBarRedDot({
+				// 				index: 3
+				// 			})
+				// 			uni.clearStorageSync();
+				// 			that.$store.commit('logout')
+				// 			that.$api.logout()
+				// 			uni.navigateTo({
+				// 				url: `/pages/public/login`
+				// 			})
+				// 		}
+				// 	}
+				// })
+			},
 		}
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
+	page {
+		background-color: #F5F6FA;
+	}
+
+	.container {
+		padding: 10px 0 0px;
+	}
+
+	.headPortrait {
+		width: 100%;
+		height: 52px;
+		margin-top: 15px;
+		background-color: #FFFFFF;
+		border-radius: 6px;
+		// justify-content: flex-end;
+	}
+
+	.title {
+		font-size: 16px;
+		line-height: 50px;
+		font-weight: 600;
+		margin-left: 10px;
+	}
+
+	.pictures {
+		justify-content: flex-end;
+		width: 35px;
+		height: 35px;
+		background-color: #E0FAF6;
+		border-radius: 18px;
+	}
+
+	.picture {
+		width: 35px;
+		height: 35px;
+	}
+
+	.arrow {
+		margin-left: 15px;
+		width: 8px;
+		height: 12px;
+		// justify-content: flex-end
 
+	}
+
+	.username {
+		line-height: 50px;
+		color: #6D6D72;
+	}
+
+	.sign {
+		width: 18px;
+		height: 18px;
+		top: 4px;
+		margin-right: 6px;
+	}
+
+	.cu-list>.cu-item:after {
+		border: none;
+	}
+
+	.exitloginwrap {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		padding-bottom: 20px;
+	}
+
+	.exitlogin {
+		width: 90%;
+		background: #fff;
+		border-radius: 30px;
+		color: #FB1E1E;
+		font-size: 17px;
+	}
+
+	.exitlogin:after {
+		border: none;
+	}
 </style>

+ 77 - 6
pages/news/index.vue

@@ -1,20 +1,91 @@
-<!-- 消息 -->
 <template>
-	<view>
-		消息
-	</view>
+	 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
+		<view class="content">
+			<view class="info-item" v-for="good in goods" :key="good.id">
+				<view class="flex flex-space-between">
+					<view class="left">
+						<view>系统消息</view>
+						 <u-badge :isDot="true" bgColor='red' :absolute='true' :offset='badgeOffset'></u-badge>
+					</view>
+					<view class="">
+						今天 21:51
+					</view>
+				</view>
+				<view class="flex flex-space-between">
+					您的驾驶证即将到期,请尽快到“我的-身份认证”中更新,逾期将影响运费支付。
+				</view>
+				
+			</view>
+		</view>
+	</mescroll-body>
 </template>
 
 <script>
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	import {apiGoods} from "@/api/mock.js"
+	
 	export default {
+		mixins: [MescrollMixin], // 使用mixin
 		data() {
 			return {
+				value:100,
+				goods: [] ,// 数据列表
+				badgeOffset:[0,-5]
+			}
+		},
+		methods: {
+			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
+			upCallback(page) {
+				// 此处可以继续请求其他接口
+				// if(page.num == 1){
+				// 	// 请求其他接口...
+				// }
+				
+				// 如果希望先请求其他接口,再触发upCallback,可参考以下写法
+				// if(!this.isInitxx){
+				// 	apiGetxx().then(res=>{
+				// 		this.isInitxx = true
+				// 		this.mescroll.resetUpScroll() // 重新触发upCallback
+				// 	}).catch(()=>{
+				// 		this.mescroll.endErr()
+				// 	})
+				// 	return // 此处return,先获取xx
+				// }
 				
-			};
+				//联网加载数据
+				apiGoods(page.num, page.size).then(res=>{
+					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
+					//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;
+
+					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
+					//this.mescroll.endByPage(res.list.length, totalPage); //必传参数(当前页的数据个数, 总页数)
+
+					//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
+					//this.mescroll.endBySize(res.list.length, totalSize); //必传参数(当前页的数据个数, 总数据量)
+
+					//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
+					//this.mescroll.endSuccess(res.list.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)
+
+					//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据
+					this.mescroll.endSuccess(res.list.length);
+
+					//设置列表数据
+					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
+					this.goods=this.goods.concat(res.list); //追加新数据
+				}).catch(()=>{
+					//联网失败, 结束加载
+					this.mescroll.endErr();
+				})
+			}
 		}
 	}
 </script>
 
 <style lang="scss">
-
+.info-item{
+	.left{
+		position: relative;
+	}
+}
 </style>
+

+ 146 - 5
pages/order/confirmLoading.vue

@@ -1,20 +1,161 @@
 <!-- 确认装车 -->
 <template>
-	<view>
-		确认装车
+	<view class="content">
+		<view class="level1-title">
+			任务信息
+		</view>
+		<view class="content1">
+			<view class='row-between'>
+				<view class="">货主</view>
+				<view class="flex">
+					<view>张三</view>
+					<view>del</view>
+				</view>
+				
+			</view>
+			<view class='row-between'>
+				<view class="">货主单位</view>
+				<view>黑龙江中天昊元贸易有限公司</view>
+			</view>
+			<view class='row-between'>
+				<view class="">发货地</view>
+				<view>鲅鱼圈</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸货地</view>
+				<view>黑龙江省齐齐哈尔市梅里斯达斡尔族区杜尔门沁达斡尔乡53农场</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货名</view>
+				<view>玉米</view>
+			</view>
+			<view class='row-between'>
+				<view class="">运费</view>
+				<view>100元/吨</view>
+			</view>
+		</view>
+		<view class="level1-title">
+			装车信息
+		</view>
+		<view class="content2">
+			<view class='row-between'>
+				<view class="">车牌号</view>
+				<view>辽H12345</view>
+			</view>
+			<view class='row-between'>
+				<view class="">装车时间</view>
+				<view>2022-02-10 16:13:15</view>
+			</view>
+			<view class='row-between'>
+				<view class="">装车净重</view>
+			</view>
+			<view class='s-flex'>
+				<view class="">上传装车照片</view>
+				<upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="3"
+					:size-type="['compressed']" @on-success="getImgUrl" @on-error="onError" @on-remove="onRemove"
+					@on-uploaded="isAdd = true" :before-upload="filterFileType" @on-progress="onProgress"></upload>
+			</view>
+			<view class='s-flex'>
+				<view class="">上传装车磅单</view>
+				<upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="1"
+					:size-type="['compressed']" @on-success="getImgUrl" @on-error="onError" @on-remove="onRemove"
+					@on-uploaded="isAdd = true" :before-upload="filterFileType" @on-progress="onProgress"></upload>
+			</view>
+		</view>
+		<view class="content3 flex">
+			<u-button text="暂存" type="primary" @click="submit(0)"></u-button>
+			<u-button text="提交" type="primary" @click="submit(1)"></u-button>
+		</view>
+		<u-toast ref="uToast"></u-toast>
+		<u-modal :show="isShowAlert" :title="alertTitle" :content='alertContent' :closeOnClickOverlay='true' :showCancelButton='true' confirmColor='#22C572'  @confirm="confirmClick" @close="cancelClick" @cancel="cancelClick"></u-modal>
 	</view>
 </template>
 
 <script>
+	import upload from '@/components/upload.vue';
 	export default {
+		components: {
+			upload
+		},
 		data() {
 			return {
-				
+				detailData: {
+					addressUrl: ''
+				},
+				action: this.$helper.ossUploadUrl,
+				maxSize: 50 * 1024 * 1024, //限制文件大小 50M
+				isAdd: true,
+				isShowAlert: false,
+				alertContent: '',
+				alertTitle: '',
 			}
 		},
+		onLoad(options) {
+			console.log(options)
+		},
 		methods: {
-			
-		}
+			alertBtn() {
+				// uni.navigateTo({
+				// 	url: '/pages/public/login'
+				// })
+			},
+			cancelClick() {
+				this.isShowAlert = false
+			},
+			getImgUrl(res) {
+				this.detailData.addressUrl = res
+				console.log(res)
+				console.log('------------res-----------')
+			},
+			onError(error) {
+				alert(error)
+				console.log('------------error-----------')
+				console.log(error)
+			},
+			onRemove(index) {},
+			filterFileType(index, lists) {
+				if (lists[index].fileType != 'jpg' && lists[index].fileType != 'png' && lists[index].fileType != 'gif') {
+					lists.splice(index, 1);
+					// 当前文件不支持
+					uni.showModal({
+						title: '暂不支持当前图片类型',
+						showCancel: false
+					});
+				} else {
+					this.isAdd = false;
+				}
+			},
+			onProgress(e) {
+				console.log(e)
+			},
+			submit(type) {
+				console.log(type)
+				let params = {
+						type: 'success',
+						title: '成功主题(带图标)',
+						message: "庄生晓梦迷蝴蝶",
+						iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+					}
+					if(type==0){
+						
+					}else{
+						this.alertContent='确定提交装车信息?'
+						this.alertTitle='提示'
+						this.isShowAlert = true
+					}
+				// this.$refs.uToast.show({
+				// 	...params,
+				// 	complete() {
+				// 		params.url && uni.navigateTo({
+				// 			url: params.url
+				// 		})
+				// 	}
+				// })
+			},
+			confirmClick(){
+				console.log('提交')
+			}
+		},
 	}
 </script>
 

+ 147 - 6
pages/order/confirmUnloading.vue

@@ -1,20 +1,161 @@
-<!-- 确认车 -->
+<!-- 确认车 -->
 <template>
-	<view>
-		确认卸车
+	<view class="content">
+		<view class="level1-title">
+			任务信息
+		</view>
+		<view class="content1">
+			<view class='row-between'>
+				<view class="">订单编号</view>
+				<view>CY20220210666666</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货主</view>
+				<view>张三</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货主单位</view>
+				<view>黑龙江中天昊元贸易有限公司</view>
+			</view>
+			<view class='row-between'>
+				<view class="">发货地</view>
+				<view>鲅鱼圈</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸货地</view>
+				<view>黑龙江省齐齐哈尔市梅里斯达斡尔族区杜尔门沁达斡尔乡53农场</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货名</view>
+				<view>玉米</view>
+			</view>
+			<view class='row-between'>
+				<view class="">运费</view>
+				<view>100元/吨</view>
+			</view>
+		</view>
+		<view class="level1-title">
+			卸车信息
+		</view>
+		<view class="content2">
+			<view class='row-between'>
+				<view class="">车牌号</view>
+				<view>辽H12345</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸车时间</view>
+				<view>2022-02-10 16:13:15</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸车净重</view>
+			</view>
+			<view class='s-flex'>
+				<view class="">上传卸车照片</view>
+				<upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="3"
+					:size-type="['compressed']" @on-success="getImgUrl" @on-error="onError" @on-remove="onRemove"
+					@on-uploaded="isAdd = true" :before-upload="filterFileType" @on-progress="onProgress"></upload>
+			</view>
+			<view class='s-flex'>
+				<view class="">上传卸车磅单</view>
+				<upload class="upload" ref="upload" :action="action" :max-size="maxSize" :max-count="1"
+					:size-type="['compressed']" @on-success="getImgUrl" @on-error="onError" @on-remove="onRemove"
+					@on-uploaded="isAdd = true" :before-upload="filterFileType" @on-progress="onProgress"></upload>
+			</view>
+		</view>
+		<view class="content3 flex">
+			<u-button text="暂存" type="primary" @click="submit(0)"></u-button>
+			<u-button text="提交" type="primary" @click="submit(1)"></u-button>
+		</view>
+		<u-toast ref="uToast"></u-toast>
+		<u-modal :show="isShowAlert" :title="alertTitle" :content='alertContent' :closeOnClickOverlay='true' :showCancelButton='true' confirmColor='#22C572'  @confirm="confirmClick" @close="cancelClick" @cancel="cancelClick"></u-modal>
 	</view>
 </template>
 
 <script>
+	import upload from '@/components/upload.vue';
 	export default {
+		components: {
+			upload
+		},
 		data() {
 			return {
-				
+				detailData: {
+					addressUrl: ''
+				},
+				action: this.$helper.ossUploadUrl,
+				maxSize: 50 * 1024 * 1024, //限制文件大小 50M
+				isAdd: true,
+				isShowAlert: false,
+				alertContent: '',
+				alertTitle: '',
 			}
 		},
+		onLoad(options) {
+			console.log(options)
+		},
 		methods: {
-			
-		}
+			alertBtn() {
+				// uni.navigateTo({
+				// 	url: '/pages/public/login'
+				// })
+			},
+			cancelClick() {
+				this.isShowAlert = false
+			},
+			getImgUrl(res) {
+				this.detailData.addressUrl = res
+				console.log(res)
+				console.log('------------res-----------')
+			},
+			onError(error) {
+				alert(error)
+				console.log('------------error-----------')
+				console.log(error)
+			},
+			onRemove(index) {},
+			filterFileType(index, lists) {
+				if (lists[index].fileType != 'jpg' && lists[index].fileType != 'png' && lists[index].fileType != 'gif') {
+					lists.splice(index, 1);
+					// 当前文件不支持
+					uni.showModal({
+						title: '暂不支持当前图片类型',
+						showCancel: false
+					});
+				} else {
+					this.isAdd = false;
+				}
+			},
+			onProgress(e) {
+				console.log(e)
+			},
+			submit(type) {
+				console.log(type)
+				let params = {
+						type: 'success',
+						title: '成功主题(带图标)',
+						message: "庄生晓梦迷蝴蝶",
+						iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+					}
+					if(type==0){
+						
+					}else{
+						this.alertContent='确定提交装车信息?'
+						this.alertTitle='提示'
+						this.isShowAlert = true
+					}
+				// this.$refs.uToast.show({
+				// 	...params,
+				// 	complete() {
+				// 		params.url && uni.navigateTo({
+				// 			url: params.url
+				// 		})
+				// 	}
+				// })
+			},
+			confirmClick(){
+				console.log('提交')
+			}
+		},
 	}
 </script>
 

+ 56 - 61
pages/order/index.vue

@@ -1,77 +1,72 @@
-<!-- 订单-->
+<!-- 货源 -->
 <template>
-	 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
-		<view class="notice">mescroll的极简示例,大部分情况就是这么用</view>
-		<good-list :list="goods"></good-list>
-	</mescroll-body>
+	<view class="content">
+		<view class="head flex">
+			<u-search placeholder="日照香炉生紫烟" v-model="keyword"></u-search>
+		</view>
+		<me-tabs v-model="tabIndex" :tabs="tabs" class="m-topr20"></me-tabs>
+		<swiper :style="{height: height}" :current="tabIndex" @change="swiperChange">
+			<swiper-item v-for="(tab,i) in tabs" :key="i">
+				<mescroll-item ref="mescrollItem" :i="i" :index="tabIndex" :tabs="tabs" :height="height">
+				</mescroll-item>
+			</swiper-item>
+		</swiper>
+	</view>
 </template>
 
 <script>
-	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
-	import {apiGoods} from "@/api/mock.js"
-	
+	import MescrollItem from "./mescroll-swiper-item.vue";
 	export default {
-		mixins: [MescrollMixin], // 使用mixin
+		components: {
+			MescrollItem
+		},
 		data() {
 			return {
-				goods: [] // 数据列表
-			}
-		},
-		methods: {
-			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
-			upCallback(page) {
-				// 此处可以继续请求其他接口
-				// if(page.num == 1){
-				// 	// 请求其他接口...
-				// }
+				keyword:'',
+				src: 'https://cdn.uviewui.com/uview/album/1.jpg',
+				height: "", // 需要固定swiper的高度
+				tabs: [{
+					name: '全部'
+				}, {
+					name: '未发运'
+				}, {
+					name: '运输中'
+				}, {
+					name: '代收货'
+				},
+				{
+					name: '评价'
+				},
+				{
+					name: '待结算'
+				},
+				{
+					name: '已完结'
+				},
 				
-				// 如果希望先请求其他接口,再触发upCallback,可参考以下写法
-				// if(!this.isInitxx){
-				// 	apiGetxx().then(res=>{
-				// 		this.isInitxx = true
-				// 		this.mescroll.resetUpScroll() // 重新触发upCallback
-				// 	}).catch(()=>{
-				// 		this.mescroll.endErr()
-				// 	})
-				// 	return // 此处return,先获取xx
-				// }
 				
-				//联网加载数据
-				apiGoods(page.num, page.size).then(res=>{
-					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
-					//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;
-
-					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
-					//this.mescroll.endByPage(res.list.length, totalPage); //必传参数(当前页的数据个数, 总页数)
-
-					//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
-					//this.mescroll.endBySize(res.list.length, totalSize); //必传参数(当前页的数据个数, 总数据量)
-
-					//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
-					//this.mescroll.endSuccess(res.list.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)
+				],
+				tabIndex: 0 // 当前tab的下标
 
-					//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据
-					this.mescroll.endSuccess(res.list.length);
-
-					//设置列表数据
-					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
-					this.goods=this.goods.concat(res.list); //追加新数据
-				}).catch(()=>{
-					//联网失败, 结束加载
-					this.mescroll.endErr();
-				})
+			}
+		},
+		onLoad() {
+			let _isHave = this.$utils.getRoles('aaa')
+			console.log(_isHave)
+			// 需要固定swiper的高度 (需减去悬浮tabs的高度64rpx)
+			this.height = uni.getSystemInfoSync().windowHeight - uni.upx2px(64) + 'px'
+		},
+		methods: {
+			changeCity(type) {
+				console.log(type)
+			},
+			swiperChange(e) {
+				this.tabIndex = e.detail.current
 			}
 		}
 	}
 </script>
 
-<style>
-	/*说明*/
-	.notice{
-		font-size: 26upx;
-		padding: 40upx 0;
-		border-bottom: 1upx solid #eee;
-		text-align: center;
-		color:#555;
-	}
+<style scoped lang="scss">
+
 </style>

+ 139 - 0
pages/order/mescroll-swiper-item.vue

@@ -0,0 +1,139 @@
+<template>
+	<mescroll-uni :ref="'mescrollRef'+i" @init="mescrollInit" :height="height" :down="downOption" @down="downCallback"
+		:up="upOption" @up="upCallback" @emptyclick="emptyClick">
+		<view :id="'good'+good.id" class="good-list paddingr20" v-for="good in goods" :key="good.id" @click="toDetail(good.id)">
+			<view class="flex flex-space-between">
+				<view>CY20220210666666  玉米</view>
+				<view>待签约</view>
+			</view>
+			<view class="flex flex-space-between row">
+				<view class="left flex">
+					<view>辽</view>
+					<view>营口 鲅鱼圈</view>
+					<view>--------></view>
+					<view class="">
+						京
+					</view>
+					<view>背景 通州</view>
+				</view>
+			</view>
+			<view class="flex flex-space-between">
+				<view class="left flex">
+					<view>货主</view>
+					<view>中天贸易有限公司</view>
+					<view>小王</view>
+				</view>
+				<view class="right">
+					提醒货主确认卸车
+				</view>
+			</view>
+			<view class="flex flex-space-between row">
+				<view class="left flex">
+					运距~35km
+				</view>
+				<view class="right">
+					1000元/车
+				</view>
+			</view>
+		
+			<view class="flex flex-space-between">
+				<view class="left flex tiem">
+					2022-02-10 10:08
+				</view>
+				<view class="right flex">
+					<view @click.stop="grabOrders(good.id)">终止</view>
+					<view @click.stop="grabOrders(good.id)">签约</view>
+				</view>
+			</view>
+		</view>
+	</mescroll-uni>
+</template>
+
+<script>
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	import MescrollMoreItemMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js";
+	import {
+		apiGoods
+	} from "@/api/mock.js"
+
+	export default {
+		mixins: [MescrollMixin, MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
+		data() {
+			return {
+				downOption: {
+					auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
+				},
+				upOption: {
+					auto: false, // 不自动加载
+					// page: {
+					// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+					// 	size: 10 // 每页数据的数量
+					// },
+					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
+					empty: {
+						tip: '~ 空空如也 ~', // 提示
+						btnText: '去看看'
+					}
+				},
+				goods: [] //列表数据
+			}
+		},
+		props: {
+			i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
+			index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
+				type: Number,
+				default () {
+					return 0
+				}
+			},
+			tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			height: [Number, String] // mescroll的高度
+		},
+		methods: {
+			/*下拉刷新的回调 */
+			downCallback() {
+				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
+				// loadSwiper();
+				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
+				this.mescroll.resetUpScroll()
+			},
+			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
+			upCallback(page) {
+				//联网加载数据
+				let keyword = this.tabs[this.i].name
+				apiGoods(page.num, page.size, keyword).then(res => {
+					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
+					this.mescroll.endSuccess(res.list.length);
+					//设置列表数据
+					if (page.num == 1) this.goods = []; //如果是第一页需手动制空列表
+					this.goods = this.goods.concat(res.list); //追加新数据
+				}).catch(() => {
+					//联网失败, 结束加载
+					this.mescroll.endErr();
+				})
+			},
+			//点击空布局按钮的回调
+			emptyClick() {
+				uni.showToast({
+					title: '点击了按钮,具体逻辑自行实现'
+				})
+			},
+			// 跳转详情
+			toDetail(id){
+				console.log('点击详情id:',id)
+				uni.$u.route('/pages/order/orderDetails', {
+					id:id,
+				});
+			},
+			//抢单
+			grabOrders(id){
+				console.log('抢单id:',id)
+			}
+		}
+	}
+</script>

+ 119 - 4
pages/order/orderDetails.vue

@@ -1,7 +1,111 @@
 <!-- 订单详情-->
 <template>
-	<view>
-		
+	<view class="content">
+		<u-divider text="基本信息"></u-divider>
+		<view class="content1">
+			<view class='row-between'>
+				<view class="">货主</view>
+				<view>张三</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货主单位</view>
+				<view>黑龙江中天昊元贸易有限公司</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸货地</view>
+				<view>黑龙江省齐齐哈尔市梅里斯达斡尔族区杜尔门沁达斡尔乡53农场</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货名</view>
+				<view>玉米</view>
+			</view>
+			<view class='row-between'>
+				<view class="">距离</view>
+				<view>约15公里</view>
+			</view>
+			<view class='row-between'>
+				<view class="">货运费</view>
+				<view>100元/吨</view>
+			</view>
+		</view>
+		<u-divider text="承运信息"></u-divider>
+		<view class="content2">
+			<view class='row-between'>
+				<view class="">合同编号</view>
+				<view>待签订 ></view>
+			</view>
+			<view class='row-between'>
+				<view class="">订单编号</view>
+				<view>CY20220210666666</view>
+			</view>
+			<view class='row-between'>
+				<view class="">装车反馈</view>
+				<view>未装车</view>
+			</view>
+			<view class='row-between'>
+				<view class="">车牌号</view>
+				<view>辽H12345</view>
+			</view>
+			<view class='row-between'>
+				<view class="">装车净重</view>
+				<view>10吨</view>
+			</view>
+			<view class='row-between'>
+				<view class="">装车时间</view>
+				<view>2022-02-10 16:13:15</view>
+			</view>
+			<view class='row-between'>
+				<view class="">装车照片</view>
+				<view class="flex">
+					<u--image :showLoading="true" :src="src" width="40px" height="40px"></u--image>
+					<u--image :showLoading="true" :src="src" width="40px" height="40px"></u--image>
+				</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸车反馈</view>
+				<view class="flex">
+					<view>已卸车</view>
+					<view>未确认</view>
+				</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸车净重</view>
+				<view>100吨</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸车时间</view>
+				<view>2022-02-10 16:13:15</view>
+			</view>
+			<view class='row-between'>
+				<view class="">卸车照片</view>
+				<view class="flex">
+					<u--image :showLoading="true" :src="src" width="40px" height="40px"></u--image>
+					<u--image :showLoading="true" :src="src" width="40px" height="40px"></u--image>
+				</view>
+			</view>
+		</view>
+		<u-divider text="运费信息"></u-divider>
+		<view class="content3">
+			<view class='row-between'>
+				<view class="">预付运费</view>
+				<view>2000</view>
+			</view>
+			<view class='row-between'>
+				<view class="">2022-02-11 15:15:15</view>
+			</view>
+			<view class='row-between'>
+				<view class="">运费尾款</view>
+				<view>2000</view>
+			</view>
+			<view class='row-between'>
+				<view class="">2022-02-11 15:15:15</view>
+			</view>
+			<view class='row-between'>
+				明细:预付2000元,扣款200元,服务费150元,尾款2000元,合计收款4000元。
+			</view>
+		</view>
+		<u-button text="确认装车" type="primary" @click="goConfirmLoading()"></u-button>
+		<u-button text="联系客服" type="primary" @click="$helper.contactCustomerService"></u-button>
 	</view>
 </template>
 
@@ -9,8 +113,19 @@
 	export default {
 		data() {
 			return {
-				
-			};
+				cyinfoStatus: '未装车',
+				src: 'https://cdn.uviewui.com/uview/album/1.jpg',
+				id: 1
+			}
+
+		},
+		methods: {
+			goConfirmLoading(id) {
+				console.log('点击详情id:', id)
+				uni.$u.route('/pages/order/confirmLoading', {
+					id: this.id,
+				});
+			},
 		}
 	}
 </script>

+ 5 - 1
pages/public/login.vue

@@ -14,6 +14,7 @@
 			</u-code>
 		</u--form>
 		<u-button type="primary" text="提交" customStyle="margin-top: 50px" @click="submit"></u-button>
+		<u-button  type="primary" @click='goregister'>手机号一键注册</u-button>
 		<u-loading-page :loading="isLoading" bg-color="#e8e8e8"></u-loading-page>
 	</view>
 </template>
@@ -120,7 +121,10 @@
 			},
 			hideKeyboard() {
 				uni.hideKeyboard()
-			}
+			},
+			goregister(){
+					uni.$u.route('/pages/public/register');
+			},
 		},
 	}
 </script>

+ 208 - 0
pages/public/register.vue

@@ -0,0 +1,208 @@
+<template>
+	<view class="u-page">
+		<u--form labelPosition="left" :model="registerData" ref="registerForm">
+			<u-form-item label="电话" prop="phone" borderBottom>
+				<u--input v-model="registerData.phone" border="none" placeholder="电话"></u--input>
+			</u-form-item>
+
+			<u-form-item label="验证码" prop="code" labelWidth="80" borderBottom>
+				<u--input v-model="registerData.verifyCode" border="none" placeholder="请填写验证码"></u--input>
+				<u-button slot="right" @tap="getCode" :text="tips" type="success" size="mini" :disabled="disabled1">
+				</u-button>
+			</u-form-item>
+			<u-form-item label="密码" prop="password" borderBottom>
+				<u--input v-model="registerData.password" border="none" placeholder="请输入密码,6-16位字符"></u--input>
+			</u-form-item>
+
+			<u-code ref="uCode" @change="codeChange" seconds="20" @start="disabled1 = true" @end="disabled1 = false">
+			</u-code>
+		</u--form>
+		<u-button type="primary" @click='register'>注册</u-button>
+		<view style='color:#6A6A6A;margin-top:10px;text-align:center;' class="flex">
+			<u--image @click='consent' :src="consentStatus==true?'../../static/images/login/select@2x.png':'../../static/images/login/selected2.png'"
+				width="40px" height="40px"></u--image>
+			<!-- <image @click='consent' style='width:14px;height:14px;position:relative;top:2px;margin-right:5px;'
+				:src="consentStatus==true?'../../static/img/login/select@2x.png':'../../static/img/login/selected2.png'"
+				alt=""></image> -->
+			已阅读并同意
+			<navigator url="/pages/sale/webview?can_share=false&url=https://liangxin.zthymaoyi.com/userAgreement.html"
+				class="path" hover-class="navigator-hover">《服务协议》</navigator>和<navigator
+				url="/pages/sale/webview?can_share=false&url=https://liangxin.zthymaoyi.com/screctAgreement.html"
+				class="path" hover-class="navigator-hover">《隐私政策》</navigator>
+		</view>
+	</view>
+</template>
+
+<script>
+	var _this
+	import helper from '@/common/helper.js';
+	export default {
+		data() {
+			return {
+				disabled1: false,
+				tips: '',
+				consentStatus: false,
+				codestatus: false,
+				registerData: {
+					phone: '',
+					password: '',
+					verifyCode: '',
+					userName: ''
+				},
+				rules: {
+					phone: {
+						type: 'string',
+						required: true,
+						len: 11,
+						message: '请填写11位手机号',
+						trigger: ['blur']
+					},
+					verifyCode: {
+						type: 'string',
+						required: true,
+						len: 6,
+						message: '请填写6位验证码',
+						trigger: ['blur']
+					},
+				}
+			}
+		},
+		onReady() {
+			// 如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则
+			this.$refs.registerForm.setRules(this.rules)
+		},
+		onLoad() {
+			_this = this
+		},
+		methods: {
+			codeChange(text) {
+				this.tips = text;
+			},
+			// 获取验证码
+			getCode() {
+				if (/^0?1[3|4|5|6|7|8][0-9]\d{8}$/.test(this.registerData.phone)) {
+					if (this.$refs.uCode.canGetCode) {
+
+						// 模拟向后端请求验证码
+						uni.showLoading({
+							title: '正在获取验证码'
+						})
+						_this.$request.baseRequest('get', '/commonUser/sendVerifyCode', {
+								phone: this.registerData.phone
+							}).then(res => {
+								uni.hideLoading();
+								// 这里此提示会被this.start()方法中的提示覆盖
+								uni.$u.toast('验证码已发送');
+								// 通知验证码组件内部开始倒计时
+								this.$refs.uCode.start();
+
+							})
+							.catch(res => {
+								uni.$u.toast(res.message);
+							});
+
+						// setTimeout(() => {
+
+						// }, 2000);
+					} else {
+						uni.$u.toast('倒计时结束后再发送');
+					}
+				} else {
+					uni.$u.toast('请输入正确手机号');
+				}
+
+			},
+			consent() {
+				this.consentStatus = !this.consentStatus
+				uni.setStorage({
+					key: 'policyStorageKey',
+					data: this.consentStatus
+				});
+			},
+			// 随机数
+			randomAccess(min, max) {
+				return Math.floor(Math.random() * (min - max) + max)
+			},
+			getRandomName(NameLength) {
+				let name = ""
+				for (let i = 0; i < NameLength; i++) {
+					let unicodeNum = ""
+					unicodeNum = this.randomAccess(0x4e00, 0x9fa5).toString(16)
+					name += this.decodeUnicode(unicodeNum)
+				}
+				return name
+			},
+			// 解码
+			decodeUnicode(str) {
+				//Unicode显示方式是\u4e00
+				str = "\\u" + str
+				str = str.replace(/\\/g, "%");
+				//转换中文
+				str = unescape(str);
+				//将其他受影响的转换回原来
+				str = str.replace(/%/g, "\\");
+				return str;
+			},
+			//注册
+			register() {
+				if (!this.consentStatus) {
+					uni.showToast({
+						title: '请勾选协议',
+						icon: 'none',
+						duration: 2000
+					})
+					return
+				}
+				this.$refs.registerForm.validate().then(res => {debugger
+					_this.registerData.userName = _this.getRandomName(3)
+					uni.$u.toast('校验通过')
+					_this.isLoading = true
+					_this.$request.baseRequest('post', '/commonUser/register', _this.registerData).then(res => {
+							if (res.data.code == '11002') {
+								uni.$u.toast('验证码错误或过期,请重新获取')
+
+								return
+							} else if (res.data.code == '11004') {
+								uni.$u.toast('该手机号已注册,可直接登录')
+
+								return
+							} 
+							uni.showLoading({
+								title: '登录中',
+								mask: true
+							})
+							debugger
+							_this.$request.baseRequest('get', '/commonUser/login', {
+								phone: _this.registerData.phone,
+								password: _this.registerData.password,
+								cid: uni.getStorageSync("clientId")
+							}).then(res => {
+								uni.hideLoading()
+								uni.setStorageSync('userInfo', res.data)
+								_this.$store.commit('login', res.data)
+								uni.switchTab({
+									url: '/pages/goodSource/index'
+								});
+									
+								})
+								.catch(res => {
+									uni.$u.toast(res.message)
+								});
+							
+							
+							
+						})
+						.catch(res => {
+							uni.$u.toast(res.message)
+						});
+				}).catch(errors => {
+					uni.$u.toast('校验失败')
+				})
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+
+</style>

+ 89 - 0
static/css/common.scss

@@ -0,0 +1,89 @@
+// 全局公共样式
+.content{
+	background: $ac-bgc;
+	padding:$uni-spacing-row-base;
+	overflow: hidden;
+	
+}
+// 常用公共样式
+// 布局相关 start
+.flex{
+	display: flex;
+}
+.inline-block{
+	display: inline-block;
+}
+.s-row{
+	display: flex;
+	flex-direction: column;
+}
+
+.flex-center{
+	justify-content: center;
+	align-items: center;
+}
+.flex-space-between{
+	justify-content: space-between;
+	align-items: center;
+}
+.flex-space-around{
+	justify-content: space-around;
+	align-items: center;
+}
+.flex-space-evenly{
+	justify-content: space-evenly;
+	align-items: center;
+}
+.flex-end{
+	    justify-content: flex-end;
+}
+.flex-start{
+	    justify-content: flex-start;
+}
+.m-topr20{
+	margin-top: 20rpx;
+}
+.paddingr20{
+	padding:20rpx;
+}
+.lr-paddingr20{
+	padding: 0 20rpx;
+}
+.fixed{
+	position: fixed;
+}
+.row-between{
+	display: flex;
+	justify-content: space-between;
+}
+.content-other{
+	background: white;
+	padding:10rpx 20rpx;
+	border-radius: 10rpx;
+}
+.width100{
+	width: 100%;
+}
+// 布局相关 end
+
+// 边线相关start
+.border-bottom{
+	border-bottom: 1px solid $uni-border-color;
+	padding-bottom: 10rpx;
+}
+// 边线相关end
+.red{
+	background: red;
+}
+.yellow{
+	background:yellow;
+}
+
+// 文字相关start
+.level1-title{
+	
+}
+// 文字相关end
+// 边线相关start
+// 边线相关start
+

+ 20 - 0
static/css/font.css

@@ -0,0 +1,20 @@
+@font-face {
+	font-family: "PingFang SC";
+	src: url('https://taohaoliang.oss-accelerate.aliyuncs.com/app/tmp/PingFang-Bold.ttf'),
+/* 		url('https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/PingFang-ExtraLight.ttf'),
+		url('https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/PingFang-Heavy.ttf'),
+		url('https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/PingFang-Light.ttf'), */
+		url('https://taohaoliang.oss-accelerate.aliyuncs.com/app/tmp/PingFang-Medium.ttf'),
+		url('https://taohaoliang.oss-accelerate.aliyuncs.com/app/tmp/PingFang-Regular.ttf');
+		font-weight: normal;
+	font-style: normal;
+}
+@font-face {
+	font-family: "DINPro";
+	src:url('https://taohaoliang.oss-accelerate.aliyuncs.com/app/tmp/DINPro-Bold.ttf'),
+		/* url('https://taohaoliang.oss-cn-beijing.aliyuncs.com/app/tmp/DINPro-Light.ttf'), */
+		url('https://taohaoliang.oss-accelerate.aliyuncs.com/app/tmp/DINPro-Medium.ttf');
+		font-weight: normal;
+	font-style: normal;
+}
+

BIN
static/icon_delete.png


BIN
static/icon_down.png


BIN
static/images/login/bg.png


BIN
static/images/login/bg@2x.png


BIN
static/images/login/bg@3x.png


BIN
static/images/login/bg_slices/bg.png


BIN
static/images/login/bg_slices/bg@2x.png


BIN
static/images/login/bg_slices/bg@3x.png


BIN
static/images/login/duihao2.png


BIN
static/images/login/duihao2@2x.png


BIN
static/images/login/duihao2@3x.png


BIN
static/images/login/guanbi@2x.png


BIN
static/images/login/logo.png


BIN
static/images/login/logo@2x.png


BIN
static/images/login/logo@3x.png


BIN
static/images/login/select.png


BIN
static/images/login/select@2x.png


BIN
static/images/login/select@3x.png


BIN
static/images/login/selected1.png


BIN
static/images/login/selected2.png


BIN
static/images/login/selected3.png


BIN
static/images/mine/saoma.png


BIN
static/images/myimg/LiangNong.png


BIN
static/images/myimg/LiangNong@2x.png


BIN
static/images/myimg/LiangNong@3x.png


BIN
static/images/myimg/LiangShang@2x.png


BIN
static/images/myimg/LiangShang@3x.png


BIN
static/images/myimg/SiJi.png


BIN
static/images/myimg/SiJi@2x.png


BIN
static/images/myimg/SiJi@3x.png


BIN
static/images/myimg/YongHu.png


BIN
static/images/myimg/YongHu@2x.png


BIN
static/images/myimg/YongHu@3x.png


BIN
static/images/myimg/erp.png


BIN
static/images/myimg/fabu@3x.png


BIN
static/images/myimg/gengduo1.png


BIN
static/images/myimg/gengduo1@2x.png


BIN
static/images/myimg/gengduo1@3x.png


BIN
static/images/myimg/liangmai@3x.png


BIN
static/images/myimg/renzheng@3x.png


BIN
static/images/myimg/sg.png


BIN
static/images/xiangji-2.png


BIN
static/live-camera/back.png


BIN
static/live-camera/bar.png


BIN
static/live-camera/flip.png


BIN
static/live-camera/outline/idcardbadge.png


BIN
static/live-camera/outline/idcardface.png


BIN
static/live-camera/outline/idphoto.png


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff