hmp %!s(int64=4) %!d(string=hai) anos
pai
achega
068d83d2e3

+ 1 - 0
assets/http/api.js

@@ -27,6 +27,7 @@ const mall={
 const appaccount={
 	login:p => http.post('/cyzh-ldt/appaccount/login',p),
 	setPassword:p => http.post('/cyzh-ldt/appaccount/setPassword',p),
+	forgetPassword:p => http.post('/cyzh-ldt/appaccount/forgetPassword',p),
 }
 
 

+ 93 - 0
components/add-tip/add-tip.vue

@@ -0,0 +1,93 @@
+<template>
+	<view>
+		<view class="uni-add-tips-box" v-if="showTip">
+		  <view class='uni-add-tips-content' @tap='hideTip'>
+		    <text>{{tip}}</text>
+		  </view>
+		</view>
+	</view>
+</template>
+
+<script>
+	const SHOW_TIP = "SHOW_TIP"
+	export default{
+		data(){
+			return{
+				showTip:false,
+			}
+		},
+		mounted() {
+			this.showTip = !uni.getStorageInfoSync().keys.includes(SHOW_TIP)
+			setTimeout(()=>{
+				this.showTip = false
+			},this.duration*1000)
+		},
+		props:{
+			tip:{
+				type:String,
+				default:"点击「·•·」,添加至我的小程序"		
+			},
+			duration:{
+				type:Number,
+				default:10
+			}
+		},
+		methods:{
+			hideTip(){
+				uni.setStorageSync(SHOW_TIP,true)
+				this.showTip = false
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	$themeColor:rgba($color: #000000, $alpha: 0.8); //主题色
+	.uni-add-tips-box {
+	  position: fixed;
+	  top: cal(44px + var(--status-bar-height));
+	  right: 0;
+	  z-index: 99999;
+	  opacity: 0.8;
+	  display: flex;
+	  justify-content: flex-end;
+	  align-items: flex-end;
+	  flex-direction: column;
+	  width: 600upx;
+	  animation: opacityC 1s linear infinite;
+	}
+	.uni-add-tips-content::before{
+		content: "";
+		position: absolute;
+		width: 0;
+		height: 0;
+		top:-38upx;
+		right:105upx;
+		border-width: 20upx;
+		border-style: solid;
+		display: block;
+		border-color:  transparent transparent $themeColor transparent;
+	}
+	.uni-add-tips-content {
+	  border-width: 0upx;
+	  margin-top: 20upx;
+	  position: relative;
+	  background-color: $themeColor;
+	  box-shadow: 0 10upx 20upx -10upx $themeColor;
+	  border-radius: 12upx;
+	  display: flex;
+	  align-items: center;
+	  justify-content: center;
+	  padding: 18upx 20upx;
+	  margin-right: 40upx;
+	}
+	.uni-add-tips-content > text {
+	  color: #fff;
+	  font-size: 28upx;
+	  font-weight: 400;
+	}
+	@keyframes opacityC{
+		0%{opacity: 0.8;}
+		50%{opacity: 1;}
+	}
+</style>

+ 1 - 1
components/mescroll-body/mescroll-uni-option.js

@@ -27,7 +27,7 @@ const GlobalOption = {
 		},
 		empty: {
 			use: true, // 是否显示空布局
-			icon: "/static/icon/empty.png", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
+			icon: "/static/icon/empty5.png", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
 			tip: '数据为空' // 提示
 		}
 	}

+ 11 - 6
pages/activity/activity.vue

@@ -70,16 +70,17 @@
 			operate(){
 				if (this.current==0) {
 					this.stop()
-				}else if (this.current==1) {
-					this.join()
 				}else if (this.current==2) {
 					this.exit()
 				}
 			},
-			
 			exit(){
+				let ids= this.dataList.filter(item=>item.checked==true).map(item=>item.id)
+				if (this.$isEmpty(ids)) {
+					this.$u.toast('至少选择一项活动')
+					return
+				}
 				this.$dialog.showModal("确定退出?").then(res=>{
-					let ids= this.dataList.filter(item=>item.checked==true).map(item=>item.id)
 					let operateList=[]
 					ids.forEach(item=>{
 						let tmp={
@@ -98,9 +99,13 @@
 				})
 			},
 			stop(){
+				let tmp=this.$u.deepClone(this.dataList)
+				let operateList= tmp.filter(item=>item.checked==true)
+				if (this.$isEmpty(operateList)) {
+					this.$u.toast('至少选择一项活动')
+					return
+				}
 				this.$dialog.showModal('确定停用活动?').then(res=>{
-					let tmp=this.$u.deepClone(this.dataList)
-					let operateList= tmp.filter(item=>item.checked==true)
 					operateList.forEach(item=>{
 						item.auditStatus=3
 					})

+ 46 - 42
pages/activity/comps/card.vue

@@ -4,14 +4,14 @@
 			<view v-if="checkAllShow" class="center" style="width: 10%;background-color: #F1F1F1;">
 				<u-checkbox shape="circle" @change="checkboxChange" v-model="item.checked" :name="index"></u-checkbox>
 			</view>
-			<navigator :url="`/pages/activity/detail?id=${item.id}&current=${current}`" hover-class="none" class="" >
+			<navigator :url="`/pages/activity/detail?id=${item.id}&current=${current}`" hover-class="none" class="">
 				<image class="bg" :src="item.pic"></image>
 				<view class="content">
 					<text class="text-cut-1 title">{{item.title}}</text>
 					<view class="cu-tag btn-bg-color round sm tag" v-for="(item1,index1) in item.labels" :key="index1">
 						{{item1}}
 					</view>
-		
+
 					<view class="time">
 						<text>报名截至时间:{{item.endTime}}</text>
 					</view>
@@ -21,131 +21,135 @@
 				<image v-if="item.auditStatus==2" class="status" src="@/static/icon/fail.png" mode="widthFix"></image>
 			</navigator>
 		</view>
-		
+
 		<block v-if="checkAllShow">
 			<view class="" style="height: 110rpx;"></view>
-			<view class="bottom-bar" >
+			<view class="bottom-bar">
 				<view class="left">
-					<u-checkbox @change="checkAllChange" shape="circle" v-model="checkAll" >全选</u-checkbox>
+					<u-checkbox @change="checkAllChange" shape="circle" v-model="checkAll">
+						全选
+					</u-checkbox>
 				</view>
-				<view @click="operate" class="btn-bg-color center right">
+				<view @click="operate" style="font-size: 28rpx;" class="btn-bg-color center round right">
 					<text v-if="current==0">结束活动</text>
 					<text v-if="current==1">参加活动</text>
 					<text v-if="current==2">退出活动</text>
 				</view>
+
 			</view>
 		</block>
 	</view>
 </template>
 
 <script>
-	export default{
-		props:{
-			cardList:Array,
-			current:Number
+	export default {
+		props: {
+			cardList: Array,
+			current: Number
 		},
-		data(){
+		data() {
 			return {
-				checkAllShow:false,
+				checkAllShow: false,
 			}
 		},
-		computed:{
-			checkAll:{
-				get(){
-					let tmpList= this.cardList.filter(item=>item.checked == true)
+		computed: {
+			checkAll: {
+				get() {
+					let tmpList = this.cardList.filter(item => item.checked == true)
 					if (tmpList.length == this.cardList.length) {
 						return true
 					}
 					return false
 				},
-				set(){
-					
+				set() {
+
 				}
 			}
 		},
 		methods: {
-			showCheckAll(){
-				this.checkAllShow=!this.checkAllShow
+			showCheckAll() {
+				this.checkAllShow = !this.checkAllShow
 			},
-			hideCheckAll(){
-				this.checkAllShow=false
+			hideCheckAll() {
+				this.checkAllShow = false
 			},
 			checkboxChange(e) {
-				this.$emit('checkboxChange',e)
+				this.$emit('checkboxChange', e)
 			},
-			checkAllChange(e){
-				this.$emit('checkAllChange',e)
+			checkAllChange(e) {
+				this.$emit('checkAllChange', e)
 			},
-			operate(){
+			operate() {
 				this.$emit('operate')
 			}
 		}
-		
+
 	}
 </script>
 
 <style lang="scss" scoped>
 	.bottom-bar {
 		position: fixed;
-		bottom: 0;
+		bottom: env(safe-area-inset-bottom);
 		z-index: 99;
 		width: 100%;
 		background-color: #FFFFFF;
 		height: 100rpx;
 		display: flex;
-	
+		padding: 20rpx 30rpx;
+
 		.left {
-			width: 70%;
+			width: 75%;
 			display: flex;
 			flex-direction: column;
-			justify-content: center;
+			justify-content: flex-end;
 			padding-left: 30rpx;
 		}
-	
+
 		.right {
-			width: 30%;
+			width: 25%;
 		}
 	}
-	
+
 	.card {
 		overflow: hidden;
 		position: relative;
 		background-color: #FFFFFF;
 		margin: 20rpx;
 		border-radius: 20rpx;
-	
+
 		.bg {
 			border-radius: 20rpx 20rpx 0 0;
 			width: 100vw;
 			height: 250rpx;
 		}
-	
+
 		.status {
 			position: absolute;
 			right: 10rpx;
 			bottom: 10rpx;
 			width: 100rpx;
 		}
-	
+
 		.content {
 			padding: 10rpx 20rpx;
-	
+
 			.title {
 				font-weight: 800;
 				font-size: 30rpx;
 			}
-	
+
 			.tag {
 				padding: 20rpx 32rpx;
 				margin: 20rpx 20rpx 20rpx 0;
 			}
-	
+
 			.time {
 				font-size: 24rpx;
 				margin-bottom: 20rpx;
 			}
-	
-	
+
+
 		}
 	}
 </style>

+ 2 - 2
pages/activity/detail.vue

@@ -77,7 +77,7 @@
 				<view class="flex " style="width: 90%;">
 					<view class="data" v-for="(item,index) in detail.activityJoinRecords" :key="index">
 						<view class="item">
-							<image :src="item.joinPic" mode=""></image>
+							<image style="border-radius: 50%;" :src="item.joinPic" mode=""></image>
 							<view>
 								<text>{{name | ellipsis}}</text>
 								<text>{{item.finalSupplyPrice}}折</text>
@@ -96,7 +96,7 @@
 			<view @click="operate" :style="{paddingBottom:safeAreaBottom}" class="footer-fixed center">
 				<view  class="cu-btn df btn-bg-color  round " style="width: 90%;height: 80rpx;">
 					<block v-if="current==0">
-						<text v-if="detail.auditStatus==0">待审核</text>
+						<text v-if="detail.auditStatus==0 || detail.auditStatus == 4">待审核</text>
 						<text v-if="detail.auditStatus==1">审核通过</text>
 						<text v-if="detail.auditStatus==2">审核不通过</text>
 						<text v-if="detail.auditStatus==3">已停用</text>

+ 295 - 0
pages/image-cropper/image-cropper.vue

@@ -0,0 +1,295 @@
+<template>
+	<view class="content">
+		<view class="cropper-wrapper" :style="{ height: cropperOpt.height + 'px' }">
+			<canvas
+				class="cropper"
+				:disable-scroll="true"
+				@touchstart="touchStart"
+				@touchmove="touchMove"
+				@touchend="touchEnd"
+				:style="{ width: cropperOpt.width, height: cropperOpt.height, backgroundColor: 'rgba(0, 0, 0, 0.8)' }"
+				canvas-id="cropper"
+				id="cropper"
+			></canvas>
+			<canvas
+				class="cropper"
+				:disable-scroll="true"
+				:style="{
+					position: 'fixed',
+					top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,
+					left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,
+					width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,
+					height: `${cropperOpt.height * cropperOpt.pixelRatio}`
+				}"
+				canvas-id="targetId"
+				id="targetId"
+			></canvas>
+		</view>
+		<view class="cropper-buttons safe-area-padding" :style="{ height: bottomNavHeight + 'px' }">
+			<!-- #ifdef H5 -->
+			<view class="upload" @tap="uploadTap">选择图片</view>
+			<!-- #endif -->
+			<!-- #ifndef H5 -->
+			<view class="upload" @tap="uploadTap">重新选择</view>
+			<!-- #endif -->
+			<view class="getCropperImage" @tap="getCropperImage(false)">确定</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import WeCropper from './weCropper.js';
+export default {
+	props: {
+		// 裁剪矩形框的样式,其中可包含的属性为lineWidth-边框宽度(单位rpx),color: 边框颜色,
+		// mask-遮罩颜色,一般设置为一个rgba的透明度,如"rgba(0, 0, 0, 0.35)"
+		boundStyle: {
+			type: Object,
+			default() {
+				return {
+					lineWidth: 4,
+					borderColor: 'rgb(245, 245, 245)',
+					mask: 'rgba(0, 0, 0, 0.35)'
+				};
+			}
+		}
+		// // 裁剪框宽度,单位rpx
+		// rectWidth: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 裁剪框高度,单位rpx
+		// rectHeight: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 输出图片宽度,单位rpx
+		// destWidth: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 输出图片高度,单位rpx
+		// destHeight: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 输出的图片类型,如果发现裁剪的图片很大,可能是因为设置为了"png",改成"jpg"即可
+		// fileType: {
+		// 	type: String,
+		// 	default: 'jpg',
+		// },
+		// // 生成的图片质量
+		// // H5上无效,目前不考虑使用此参数
+		// quality: {
+		// 	type: [Number, String],
+		// 	default: 1
+		// }
+	},
+	data() {
+		return {
+			// 底部导航的高度
+			bottomNavHeight: 50,
+			originWidth: 200,
+			width: 0,
+			height: 0,
+			cropperOpt: {
+				id: 'cropper',
+				targetId: 'targetCropper',
+				pixelRatio: 1,
+				width: 0,
+				height: 0,
+				scale: 2.5,
+				zoom: 8,
+				cut: {
+					x: (this.width - this.originWidth) / 2,
+					y: (this.height - this.originWidth) / 2,
+					width: this.originWidth,
+					height: this.originWidth
+				},
+				boundStyle: {
+					lineWidth: uni.upx2px(this.boundStyle.lineWidth),
+					mask: this.boundStyle.mask,
+					color: this.boundStyle.borderColor
+				}
+			},
+			// 裁剪框和输出图片的尺寸,高度默认等于宽度
+			// 输出图片宽度,单位px
+			destWidth: 200,
+			//输出图片高低,单位px
+			destHeight:200,
+			// 裁剪框宽度,单位px
+			rectWidth: 200,
+			// 输出的图片类型,如果'png'类型发现裁剪的图片太大,改成"jpg"即可
+			fileType: 'jpg',
+			src: '', // 选择的图片路径,用于在点击确定时,判断是否选择了图片
+		};
+	},
+	onLoad(option) {
+		let rectInfo = uni.getSystemInfoSync();
+		this.width = rectInfo.windowWidth;
+		this.height = rectInfo.windowHeight - this.bottomNavHeight;
+		this.cropperOpt.width = this.width;
+		this.cropperOpt.height = this.height;
+		this.cropperOpt.pixelRatio = rectInfo.pixelRatio;
+
+		if (option.destWidth) this.destWidth = option.destWidth;
+		if (option.destHeight) this.destHeight = option.destHeight;
+		
+		if (option.rectWidth &&  option.rectHeight) {
+			let rectWidth = Number(option.rectWidth);
+			let rectHeight = Number(option.rectHeight)
+			this.cropperOpt.cut = {
+				x: (this.width - rectWidth) / 2,
+				y: (this.height - rectWidth) / 2,
+				width: rectWidth,
+				height: rectHeight
+			};
+		}
+		this.rectWidth = option.rectWidth;
+		if (option.fileType) this.fileType = option.fileType;
+		// 初始化
+		this.cropper = new WeCropper(this.cropperOpt)
+			.on('ready', ctx => {
+				// wecropper is ready for work!
+			})
+			.on('beforeImageLoad', ctx => {
+				// before picture loaded, i can do something
+			})
+			.on('imageLoad', ctx => {
+				// picture loaded
+			})
+			.on('beforeDraw', (ctx, instance) => {
+				// before canvas draw,i can do something
+			});
+		// 设置导航栏样式,以免用户在page.json中没有设置为黑色背景
+		uni.setNavigationBarColor({
+			frontColor: '#ffffff',
+			backgroundColor: '#000000'
+		});
+		uni.chooseImage({
+			count: 1, // 默认9
+			sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
+			sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
+			success: res => {
+				this.src = res.tempFilePaths[0];
+				//  获取裁剪图片资源后,给data添加src属性及其值
+				this.cropper.pushOrign(this.src);
+			}
+		});
+	},
+	methods: {
+		touchStart(e) {
+			this.cropper.touchStart(e);
+		},
+		touchMove(e) {
+			this.cropper.touchMove(e);
+		},
+		touchEnd(e) {
+			this.cropper.touchEnd(e);
+		},
+		getCropperImage(isPre = false) {
+			if(!this.src) return this.$u.toast('请先选择图片再裁剪');
+
+			let cropper_opt = {
+				destHeight: Number(this.destHeight), // uni.canvasToTempFilePath要求这些参数为数值
+				destWidth: Number(this.destWidth),
+				fileType: this.fileType
+			};
+			this.cropper.getCropperImage(cropper_opt, (path, err) => {
+				if (err) {
+					uni.showModal({
+						title: '温馨提示',
+						content: err.message
+					});
+				} else {
+					if (isPre) {
+						uni.previewImage({
+							current: '', // 当前显示图片的 http 链接
+							urls: [path] // 需要预览的图片 http 链接列表
+						});
+					} else {
+						uni.$emit('uAvatarCropper', path);
+						this.$u.route({
+							type: 'back'
+						});
+					}
+				}
+			});
+		},
+		uploadTap() {
+			const self = this;
+			uni.chooseImage({
+				count: 1, // 默认9
+				sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
+				sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
+				success: (res) => {
+					self.src = res.tempFilePaths[0];
+					//  获取裁剪图片资源后,给data添加src属性及其值
+
+					self.cropper.pushOrign(this.src);
+				}
+			});
+		}
+	}
+};
+</script>
+
+<style scoped lang="scss">
+@import '/style.components.scss';
+
+.content {
+	background: rgba(255, 255, 255, 1);
+}
+
+.cropper {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	z-index: 11;
+}
+
+.cropper-buttons {
+	background-color: #000000;
+	color: #eee;
+}
+
+.cropper-wrapper {
+	position: relative;
+	@include vue-flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+	width: 100%;
+	background-color: #000;
+}
+
+.cropper-buttons {
+	width: 100vw;
+	@include vue-flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	font-size: 28rpx;
+}
+
+.cropper-buttons .upload,
+.cropper-buttons .getCropperImage {
+	width: 50%;
+	text-align: center;
+}
+
+.cropper-buttons .upload {
+	text-align: left;
+	padding-left: 50rpx;
+}
+
+.cropper-buttons .getCropperImage {
+	text-align: right;
+	padding-right: 50rpx;
+}
+</style>

+ 7 - 0
pages/image-cropper/style.components.scss

@@ -0,0 +1,7 @@
+// 定义混入指令,用于在非nvue环境下的flex定义,因为nvue没有display属性,会报错
+@mixin vue-flex($direction: row) {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	flex-direction: $direction;
+	/* #endif */
+}

+ 1265 - 0
pages/image-cropper/weCropper.js

@@ -0,0 +1,1265 @@
+/**
+ * we-cropper v1.3.9
+ * (c) 2020 dlhandsome
+ * @license MIT
+ */
+(function(global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+		typeof define === 'function' && define.amd ? define(factory) :
+		(global.WeCropper = factory());
+}(this, (function() {
+	'use strict';
+
+	var device = void 0;
+	var TOUCH_STATE = ['touchstarted', 'touchmoved', 'touchended'];
+
+	function firstLetterUpper(str) {
+		return str.charAt(0).toUpperCase() + str.slice(1)
+	}
+
+	function setTouchState(instance) {
+		var arg = [],
+			len = arguments.length - 1;
+		while (len-- > 0) arg[len] = arguments[len + 1];
+
+		TOUCH_STATE.forEach(function(key, i) {
+			if (arg[i] !== undefined) {
+				instance[key] = arg[i];
+			}
+		});
+	}
+
+	function validator(instance, o) {
+		Object.defineProperties(instance, o);
+	}
+
+	function getDevice() {
+		if (!device) {
+			device = uni.getSystemInfoSync();
+		}
+		return device
+	}
+
+	var tmp = {};
+
+	var ref = getDevice();
+	var pixelRatio = ref.pixelRatio;
+
+	var DEFAULT = {
+		id: {
+			default: 'cropper',
+			get: function get() {
+				return tmp.id
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'string') {
+					console.error(("id:" + value + " is invalid"));
+				}
+				tmp.id = value;
+			}
+		},
+		width: {
+			default: 750,
+			get: function get() {
+				return tmp.width
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'number') {
+					console.error(("width:" + value + " is invalid"));
+				}
+				tmp.width = value;
+			}
+		},
+		height: {
+			default: 750,
+			get: function get() {
+				return tmp.height
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'number') {
+					console.error(("height:" + value + " is invalid"));
+				}
+				tmp.height = value;
+			}
+		},
+		pixelRatio: {
+			default: pixelRatio,
+			get: function get() {
+				return tmp.pixelRatio
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'number') {
+					console.error(("pixelRatio:" + value + " is invalid"));
+				}
+				tmp.pixelRatio = value;
+			}
+		},
+		scale: {
+			default: 2.5,
+			get: function get() {
+				return tmp.scale
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'number') {
+					console.error(("scale:" + value + " is invalid"));
+				}
+				tmp.scale = value;
+			}
+		},
+		zoom: {
+			default: 5,
+			get: function get() {
+				return tmp.zoom
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'number') {
+					console.error(("zoom:" + value + " is invalid"));
+				} else if (value < 0 || value > 10) {
+					console.error("zoom should be ranged in 0 ~ 10");
+				}
+				tmp.zoom = value;
+			}
+		},
+		src: {
+			default: '',
+			get: function get() {
+				return tmp.src
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'string') {
+					console.error(("src:" + value + " is invalid"));
+				}
+				tmp.src = value;
+			}
+		},
+		cut: {
+			default: {},
+			get: function get() {
+				return tmp.cut
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'object') {
+					console.error(("cut:" + value + " is invalid"));
+				}
+				tmp.cut = value;
+			}
+		},
+		boundStyle: {
+			default: {},
+			get: function get() {
+				return tmp.boundStyle
+			},
+			set: function set(value) {
+				if (typeof(value) !== 'object') {
+					console.error(("boundStyle:" + value + " is invalid"));
+				}
+				tmp.boundStyle = value;
+			}
+		},
+		onReady: {
+			default: null,
+			get: function get() {
+				return tmp.ready
+			},
+			set: function set(value) {
+				tmp.ready = value;
+			}
+		},
+		onBeforeImageLoad: {
+			default: null,
+			get: function get() {
+				return tmp.beforeImageLoad
+			},
+			set: function set(value) {
+				tmp.beforeImageLoad = value;
+			}
+		},
+		onImageLoad: {
+			default: null,
+			get: function get() {
+				return tmp.imageLoad
+			},
+			set: function set(value) {
+				tmp.imageLoad = value;
+			}
+		},
+		onBeforeDraw: {
+			default: null,
+			get: function get() {
+				return tmp.beforeDraw
+			},
+			set: function set(value) {
+				tmp.beforeDraw = value;
+			}
+		}
+	};
+
+	var ref$1 = getDevice();
+	var windowWidth = ref$1.windowWidth;
+
+	function prepare() {
+		var self = this;
+
+		// v1.4.0 版本中将不再自动绑定we-cropper实例
+		self.attachPage = function() {
+			var pages = getCurrentPages();
+			// 获取到当前page上下文
+			var pageContext = pages[pages.length - 1];
+			// 把this依附在Page上下文的wecropper属性上,便于在page钩子函数中访问
+			Object.defineProperty(pageContext, 'wecropper', {
+				get: function get() {
+					console.warn(
+						'Instance will not be automatically bound to the page after v1.4.0\n\n' +
+						'Please use a custom instance name instead\n\n' +
+						'Example: \n' +
+						'this.mycropper = new WeCropper(options)\n\n' +
+						'// ...\n' +
+						'this.mycropper.getCropperImage()'
+					);
+					return self
+				},
+				configurable: true
+			});
+		};
+
+		self.createCtx = function() {
+			var id = self.id;
+			var targetId = self.targetId;
+
+			if (id) {
+				self.ctx = self.ctx || uni.createCanvasContext(id);
+				self.targetCtx = self.targetCtx || uni.createCanvasContext(targetId);
+			} else {
+				console.error("constructor: create canvas context failed, 'id' must be valuable");
+			}
+		};
+
+		self.deviceRadio = windowWidth / 750;
+	}
+
+	var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !==
+		'undefined' ? self : {};
+
+
+
+
+
+	function createCommonjsModule(fn, module) {
+		return module = {
+			exports: {}
+		}, fn(module, module.exports), module.exports;
+	}
+
+	var tools = createCommonjsModule(function(module, exports) {
+		/**
+		 * String type check
+		 */
+		exports.isStr = function(v) {
+			return typeof v === 'string';
+		};
+		/**
+		 * Number type check
+		 */
+		exports.isNum = function(v) {
+			return typeof v === 'number';
+		};
+		/**
+		 * Array type check
+		 */
+		exports.isArr = Array.isArray;
+		/**
+		 * undefined type check
+		 */
+		exports.isUndef = function(v) {
+			return v === undefined;
+		};
+
+		exports.isTrue = function(v) {
+			return v === true;
+		};
+
+		exports.isFalse = function(v) {
+			return v === false;
+		};
+		/**
+		 * Function type check
+		 */
+		exports.isFunc = function(v) {
+			return typeof v === 'function';
+		};
+		/**
+		 * Quick object check - this is primarily used to tell
+		 * Objects from primitive values when we know the value
+		 * is a JSON-compliant type.
+		 */
+		exports.isObj = exports.isObject = function(obj) {
+			return obj !== null && typeof obj === 'object'
+		};
+
+		/**
+		 * Strict object type check. Only returns true
+		 * for plain JavaScript objects.
+		 */
+		var _toString = Object.prototype.toString;
+		exports.isPlainObject = function(obj) {
+			return _toString.call(obj) === '[object Object]'
+		};
+
+		/**
+		 * Check whether the object has the property.
+		 */
+		var hasOwnProperty = Object.prototype.hasOwnProperty;
+		exports.hasOwn = function(obj, key) {
+			return hasOwnProperty.call(obj, key)
+		};
+
+		/**
+		 * Perform no operation.
+		 * Stubbing args to make Flow happy without leaving useless transpiled code
+		 * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)
+		 */
+		exports.noop = function(a, b, c) {};
+
+		/**
+		 * Check if val is a valid array index.
+		 */
+		exports.isValidArrayIndex = function(val) {
+			var n = parseFloat(String(val));
+			return n >= 0 && Math.floor(n) === n && isFinite(val)
+		};
+	});
+
+	var tools_7 = tools.isFunc;
+	var tools_10 = tools.isPlainObject;
+
+	var EVENT_TYPE = ['ready', 'beforeImageLoad', 'beforeDraw', 'imageLoad'];
+
+	function observer() {
+		var self = this;
+
+		self.on = function(event, fn) {
+			if (EVENT_TYPE.indexOf(event) > -1) {
+				if (tools_7(fn)) {
+					event === 'ready' ?
+						fn(self) :
+						self[("on" + (firstLetterUpper(event)))] = fn;
+				}
+			} else {
+				console.error(("event: " + event + " is invalid"));
+			}
+			return self
+		};
+	}
+
+	function wxPromise(fn) {
+		return function(obj) {
+			var args = [],
+				len = arguments.length - 1;
+			while (len-- > 0) args[len] = arguments[len + 1];
+
+			if (obj === void 0) obj = {};
+			return new Promise(function(resolve, reject) {
+				obj.success = function(res) {
+					resolve(res);
+				};
+				obj.fail = function(err) {
+					reject(err);
+				};
+				fn.apply(void 0, [obj].concat(args));
+			})
+		}
+	}
+
+	function draw(ctx, reserve) {
+		if (reserve === void 0) reserve = false;
+
+		return new Promise(function(resolve) {
+			ctx.draw(reserve, resolve);
+		})
+	}
+
+	var getImageInfo = wxPromise(uni.getImageInfo);
+
+	var canvasToTempFilePath = wxPromise(uni.canvasToTempFilePath);
+
+	var base64 = createCommonjsModule(function(module, exports) {
+		/*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */
+		(function(root) {
+
+			// Detect free variables `exports`.
+			var freeExports = 'object' == 'object' && exports;
+
+			// Detect free variable `module`.
+			var freeModule = 'object' == 'object' && module &&
+				module.exports == freeExports && module;
+
+			// Detect free variable `global`, from Node.js or Browserified code, and use
+			// it as `root`.
+			var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal;
+			if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
+				root = freeGlobal;
+			}
+
+			/*--------------------------------------------------------------------------*/
+
+			var InvalidCharacterError = function(message) {
+				this.message = message;
+			};
+			InvalidCharacterError.prototype = new Error;
+			InvalidCharacterError.prototype.name = 'InvalidCharacterError';
+
+			var error = function(message) {
+				// Note: the error messages used throughout this file match those used by
+				// the native `atob`/`btoa` implementation in Chromium.
+				throw new InvalidCharacterError(message);
+			};
+
+			var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+			// http://whatwg.org/html/common-microsyntaxes.html#space-character
+			var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g;
+
+			// `decode` is designed to be fully compatible with `atob` as described in the
+			// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob
+			// The optimized base64-decoding algorithm used is based on @atk’s excellent
+			// implementation. https://gist.github.com/atk/1020396
+			var decode = function(input) {
+				input = String(input)
+					.replace(REGEX_SPACE_CHARACTERS, '');
+				var length = input.length;
+				if (length % 4 == 0) {
+					input = input.replace(/==?$/, '');
+					length = input.length;
+				}
+				if (
+					length % 4 == 1 ||
+					// http://whatwg.org/C#alphanumeric-ascii-characters
+					/[^+a-zA-Z0-9/]/.test(input)
+				) {
+					error(
+						'Invalid character: the string to be decoded is not correctly encoded.'
+					);
+				}
+				var bitCounter = 0;
+				var bitStorage;
+				var buffer;
+				var output = '';
+				var position = -1;
+				while (++position < length) {
+					buffer = TABLE.indexOf(input.charAt(position));
+					bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
+					// Unless this is the first of a group of 4 characters…
+					if (bitCounter++ % 4) {
+						// …convert the first 8 bits to a single ASCII character.
+						output += String.fromCharCode(
+							0xFF & bitStorage >> (-2 * bitCounter & 6)
+						);
+					}
+				}
+				return output;
+			};
+
+			// `encode` is designed to be fully compatible with `btoa` as described in the
+			// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa
+			var encode = function(input) {
+				input = String(input);
+				if (/[^\0-\xFF]/.test(input)) {
+					// Note: no need to special-case astral symbols here, as surrogates are
+					// matched, and the input is supposed to only contain ASCII anyway.
+					error(
+						'The string to be encoded contains characters outside of the ' +
+						'Latin1 range.'
+					);
+				}
+				var padding = input.length % 3;
+				var output = '';
+				var position = -1;
+				var a;
+				var b;
+				var c;
+				var buffer;
+				// Make sure any padding is handled outside of the loop.
+				var length = input.length - padding;
+
+				while (++position < length) {
+					// Read three bytes, i.e. 24 bits.
+					a = input.charCodeAt(position) << 16;
+					b = input.charCodeAt(++position) << 8;
+					c = input.charCodeAt(++position);
+					buffer = a + b + c;
+					// Turn the 24 bits into four chunks of 6 bits each, and append the
+					// matching character for each of them to the output.
+					output += (
+						TABLE.charAt(buffer >> 18 & 0x3F) +
+						TABLE.charAt(buffer >> 12 & 0x3F) +
+						TABLE.charAt(buffer >> 6 & 0x3F) +
+						TABLE.charAt(buffer & 0x3F)
+					);
+				}
+
+				if (padding == 2) {
+					a = input.charCodeAt(position) << 8;
+					b = input.charCodeAt(++position);
+					buffer = a + b;
+					output += (
+						TABLE.charAt(buffer >> 10) +
+						TABLE.charAt((buffer >> 4) & 0x3F) +
+						TABLE.charAt((buffer << 2) & 0x3F) +
+						'='
+					);
+				} else if (padding == 1) {
+					buffer = input.charCodeAt(position);
+					output += (
+						TABLE.charAt(buffer >> 2) +
+						TABLE.charAt((buffer << 4) & 0x3F) +
+						'=='
+					);
+				}
+
+				return output;
+			};
+
+			var base64 = {
+				'encode': encode,
+				'decode': decode,
+				'version': '0.1.0'
+			};
+
+			// Some AMD build optimizers, like r.js, check for specific condition patterns
+			// like the following:
+			if (
+				typeof undefined == 'function' &&
+				typeof undefined.amd == 'object' &&
+				undefined.amd
+			) {
+				undefined(function() {
+					return base64;
+				});
+			} else if (freeExports && !freeExports.nodeType) {
+				if (freeModule) { // in Node.js or RingoJS v0.8.0+
+					freeModule.exports = base64;
+				} else { // in Narwhal or RingoJS v0.7.0-
+					for (var key in base64) {
+						base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
+					}
+				}
+			} else { // in Rhino or a web browser
+				root.base64 = base64;
+			}
+
+		}(commonjsGlobal));
+	});
+
+	function makeURI(strData, type) {
+		return 'data:' + type + ';base64,' + strData
+	}
+
+	function fixType(type) {
+		type = type.toLowerCase().replace(/jpg/i, 'jpeg');
+		var r = type.match(/png|jpeg|bmp|gif/)[0];
+		return 'image/' + r
+	}
+
+	function encodeData(data) {
+		var str = '';
+		if (typeof data === 'string') {
+			str = data;
+		} else {
+			for (var i = 0; i < data.length; i++) {
+				str += String.fromCharCode(data[i]);
+			}
+		}
+		return base64.encode(str)
+	}
+
+	/**
+	 * 获取图像区域隐含的像素数据
+	 * @param canvasId canvas标识
+	 * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标
+	 * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标
+	 * @param width 将要被提取的图像数据矩形区域的宽度
+	 * @param height 将要被提取的图像数据矩形区域的高度
+	 * @param done 完成回调
+	 */
+	function getImageData(canvasId, x, y, width, height, done) {
+		uni.canvasGetImageData({
+			canvasId: canvasId,
+			x: x,
+			y: y,
+			width: width,
+			height: height,
+			success: function success(res) {
+				done(res, null);
+			},
+			fail: function fail(res) {
+				done(null, res);
+			}
+		});
+	}
+
+	/**
+	 * 生成bmp格式图片
+	 * 按照规则生成图片响应头和响应体
+	 * @param oData 用来描述 canvas 区域隐含的像素数据 { data, width, height } = oData
+	 * @returns {*} base64字符串
+	 */
+	function genBitmapImage(oData) {
+		//
+		// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
+		// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
+		//
+		var biWidth = oData.width;
+		var biHeight = oData.height;
+		var biSizeImage = biWidth * biHeight * 3;
+		var bfSize = biSizeImage + 54; // total header size = 54 bytes
+
+		//
+		//  typedef struct tagBITMAPFILEHEADER {
+		//  	WORD bfType;
+		//  	DWORD bfSize;
+		//  	WORD bfReserved1;
+		//  	WORD bfReserved2;
+		//  	DWORD bfOffBits;
+		//  } BITMAPFILEHEADER;
+		//
+		var BITMAPFILEHEADER = [
+			// WORD bfType -- The file type signature; must be "BM"
+			0x42, 0x4D,
+			// DWORD bfSize -- The size, in bytes, of the bitmap file
+			bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
+			// WORD bfReserved1 -- Reserved; must be zero
+			0, 0,
+			// WORD bfReserved2 -- Reserved; must be zero
+			0, 0,
+			// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
+			54, 0, 0, 0
+		];
+
+		//
+		//  typedef struct tagBITMAPINFOHEADER {
+		//  	DWORD biSize;
+		//  	LONG  biWidth;
+		//  	LONG  biHeight;
+		//  	WORD  biPlanes;
+		//  	WORD  biBitCount;
+		//  	DWORD biCompression;
+		//  	DWORD biSizeImage;
+		//  	LONG  biXPelsPerMeter;
+		//  	LONG  biYPelsPerMeter;
+		//  	DWORD biClrUsed;
+		//  	DWORD biClrImportant;
+		//  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
+		//
+		var BITMAPINFOHEADER = [
+			// DWORD biSize -- The number of bytes required by the structure
+			40, 0, 0, 0,
+			// LONG biWidth -- The width of the bitmap, in pixels
+			biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
+			// LONG biHeight -- The height of the bitmap, in pixels
+			biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
+			// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
+			1, 0,
+			// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
+			// has a maximum of 2^24 colors (16777216, Truecolor)
+			24, 0,
+			// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
+			0, 0, 0, 0,
+			// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
+			biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
+			// LONG biXPelsPerMeter, unused
+			0, 0, 0, 0,
+			// LONG biYPelsPerMeter, unused
+			0, 0, 0, 0,
+			// DWORD biClrUsed, the number of color indexes of palette, unused
+			0, 0, 0, 0,
+			// DWORD biClrImportant, unused
+			0, 0, 0, 0
+		];
+
+		var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
+
+		var aImgData = oData.data;
+
+		var strPixelData = '';
+		var biWidth4 = biWidth << 2;
+		var y = biHeight;
+		var fromCharCode = String.fromCharCode;
+
+		do {
+			var iOffsetY = biWidth4 * (y - 1);
+			var strPixelRow = '';
+			for (var x = 0; x < biWidth; x++) {
+				var iOffsetX = x << 2;
+				strPixelRow += fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
+					fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
+					fromCharCode(aImgData[iOffsetY + iOffsetX]);
+			}
+
+			for (var c = 0; c < iPadding; c++) {
+				strPixelRow += String.fromCharCode(0);
+			}
+
+			strPixelData += strPixelRow;
+		} while (--y)
+
+		var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
+
+		return strEncoded
+	}
+
+	/**
+	 * 转换为图片base64
+	 * @param canvasId canvas标识
+	 * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标
+	 * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标
+	 * @param width 将要被提取的图像数据矩形区域的宽度
+	 * @param height 将要被提取的图像数据矩形区域的高度
+	 * @param type 转换图片类型
+	 * @param done 完成回调
+	 */
+	function convertToImage(canvasId, x, y, width, height, type, done) {
+		if (done === void 0) done = function() {};
+
+		if (type === undefined) {
+			type = 'png';
+		}
+		type = fixType(type);
+		if (/bmp/.test(type)) {
+			getImageData(canvasId, x, y, width, height, function(data, err) {
+				var strData = genBitmapImage(data);
+				tools_7(done) && done(makeURI(strData, 'image/' + type), err);
+			});
+		} else {
+			console.error('暂不支持生成\'' + type + '\'类型的base64图片');
+		}
+	}
+
+	var CanvasToBase64 = {
+		convertToImage: convertToImage,
+		// convertToPNG: function (width, height, done) {
+		//   return convertToImage(width, height, 'png', done)
+		// },
+		// convertToJPEG: function (width, height, done) {
+		//   return convertToImage(width, height, 'jpeg', done)
+		// },
+		// convertToGIF: function (width, height, done) {
+		//   return convertToImage(width, height, 'gif', done)
+		// },
+		convertToBMP: function(ref, done) {
+			if (ref === void 0) ref = {};
+			var canvasId = ref.canvasId;
+			var x = ref.x;
+			var y = ref.y;
+			var width = ref.width;
+			var height = ref.height;
+			if (done === void 0) done = function() {};
+
+			return convertToImage(canvasId, x, y, width, height, 'bmp', done)
+		}
+	};
+
+	function methods() {
+		var self = this;
+
+		var boundWidth = self.width; // 裁剪框默认宽度,即整个画布宽度
+		var boundHeight = self.height; // 裁剪框默认高度,即整个画布高度
+
+		var id = self.id;
+		var targetId = self.targetId;
+		var pixelRatio = self.pixelRatio;
+
+		var ref = self.cut;
+		var x = ref.x;
+		if (x === void 0) x = 0;
+		var y = ref.y;
+		if (y === void 0) y = 0;
+		var width = ref.width;
+		if (width === void 0) width = boundWidth;
+		var height = ref.height;
+		if (height === void 0) height = boundHeight;
+
+		self.updateCanvas = function(done) {
+			if (self.croperTarget) {
+				//  画布绘制图片
+				self.ctx.drawImage(
+					self.croperTarget,
+					self.imgLeft,
+					self.imgTop,
+					self.scaleWidth,
+					self.scaleHeight
+				);
+			}
+			tools_7(self.onBeforeDraw) && self.onBeforeDraw(self.ctx, self);
+
+			self.setBoundStyle(self.boundStyle); //	设置边界样式
+
+			self.ctx.draw(false, done);
+			return self
+		};
+
+		self.pushOrigin = self.pushOrign = function(src) {
+			self.src = src;
+
+			tools_7(self.onBeforeImageLoad) && self.onBeforeImageLoad(self.ctx, self);
+
+			return getImageInfo({
+					src: src
+				})
+				.then(function(res) {
+					var innerAspectRadio = res.width / res.height;
+					var customAspectRadio = width / height;
+
+					self.croperTarget = res.path;
+
+					if (innerAspectRadio < customAspectRadio) {
+						self.rectX = x;
+						self.baseWidth = width;
+						self.baseHeight = width / innerAspectRadio;
+						self.rectY = y - Math.abs((height - self.baseHeight) / 2);
+					} else {
+						self.rectY = y;
+						self.baseWidth = height * innerAspectRadio;
+						self.baseHeight = height;
+						self.rectX = x - Math.abs((width - self.baseWidth) / 2);
+					}
+
+					self.imgLeft = self.rectX;
+					self.imgTop = self.rectY;
+					self.scaleWidth = self.baseWidth;
+					self.scaleHeight = self.baseHeight;
+
+					self.update();
+
+					return new Promise(function(resolve) {
+						self.updateCanvas(resolve);
+					})
+				})
+				.then(function() {
+					tools_7(self.onImageLoad) && self.onImageLoad(self.ctx, self);
+				})
+		};
+
+		self.removeImage = function() {
+			self.src = '';
+			self.croperTarget = '';
+			return draw(self.ctx)
+		};
+
+		self.getCropperBase64 = function(done) {
+			if (done === void 0) done = function() {};
+
+			CanvasToBase64.convertToBMP({
+				canvasId: id,
+				x: x,
+				y: y,
+				width: width,
+				height: height
+			}, done);
+		};
+
+		self.getCropperImage = function(opt, fn) {
+			var customOptions = opt;
+
+			var canvasOptions = {
+				canvasId: id,
+				x: x,
+				y: y,
+				width: width,
+				height: height
+			};
+
+			var task = function() {
+				return Promise.resolve();
+			};
+
+			if (
+				tools_10(customOptions) &&
+				customOptions.original
+			) {
+				// original mode
+				task = function() {
+					self.targetCtx.drawImage(
+						self.croperTarget,
+						self.imgLeft * pixelRatio,
+						self.imgTop * pixelRatio,
+						self.scaleWidth * pixelRatio,
+						self.scaleHeight * pixelRatio
+					);
+
+					canvasOptions = {
+						canvasId: targetId,
+						x: x * pixelRatio,
+						y: y * pixelRatio,
+						width: width * pixelRatio,
+						height: height * pixelRatio
+					};
+
+					return draw(self.targetCtx)
+				};
+			}
+
+			return task()
+				.then(function() {
+					if (tools_10(customOptions)) {
+						canvasOptions = Object.assign({}, canvasOptions, customOptions);
+					}
+
+					if (tools_7(customOptions)) {
+						fn = customOptions;
+					}
+
+					var arg = canvasOptions.componentContext ?
+						[canvasOptions, canvasOptions.componentContext] :
+						[canvasOptions];
+
+					return canvasToTempFilePath.apply(null, arg)
+				})
+				.then(function(res) {
+					var tempFilePath = res.tempFilePath;
+
+					return tools_7(fn) ?
+						fn.call(self, tempFilePath, null) :
+						tempFilePath
+				})
+				.catch(function(err) {
+					if (tools_7(fn)) {
+						fn.call(self, null, err);
+					} else {
+						throw err
+					}
+				})
+		};
+	}
+
+	/**
+	 * 获取最新缩放值
+	 * @param oldScale 上一次触摸结束后的缩放值
+	 * @param oldDistance 上一次触摸结束后的双指距离
+	 * @param zoom 缩放系数
+	 * @param touch0 第一指touch对象
+	 * @param touch1 第二指touch对象
+	 * @returns {*}
+	 */
+	var getNewScale = function(oldScale, oldDistance, zoom, touch0, touch1) {
+		var xMove, yMove, newDistance;
+		// 计算二指最新距离
+		xMove = Math.round(touch1.x - touch0.x);
+		yMove = Math.round(touch1.y - touch0.y);
+		newDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));
+
+		return oldScale + 0.001 * zoom * (newDistance - oldDistance)
+	};
+
+	function update() {
+		var self = this;
+
+		if (!self.src) {
+			return
+		}
+
+		self.__oneTouchStart = function(touch) {
+			self.touchX0 = Math.round(touch.x);
+			self.touchY0 = Math.round(touch.y);
+		};
+
+		self.__oneTouchMove = function(touch) {
+			var xMove, yMove;
+			// 计算单指移动的距离
+			if (self.touchended) {
+				return self.updateCanvas()
+			}
+			xMove = Math.round(touch.x - self.touchX0);
+			yMove = Math.round(touch.y - self.touchY0);
+
+			var imgLeft = Math.round(self.rectX + xMove);
+			var imgTop = Math.round(self.rectY + yMove);
+
+			self.outsideBound(imgLeft, imgTop);
+
+			self.updateCanvas();
+		};
+
+		self.__twoTouchStart = function(touch0, touch1) {
+			var xMove, yMove, oldDistance;
+
+			self.touchX1 = Math.round(self.rectX + self.scaleWidth / 2);
+			self.touchY1 = Math.round(self.rectY + self.scaleHeight / 2);
+
+			// 计算两指距离
+			xMove = Math.round(touch1.x - touch0.x);
+			yMove = Math.round(touch1.y - touch0.y);
+			oldDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));
+
+			self.oldDistance = oldDistance;
+		};
+
+		self.__twoTouchMove = function(touch0, touch1) {
+			var oldScale = self.oldScale;
+			var oldDistance = self.oldDistance;
+			var scale = self.scale;
+			var zoom = self.zoom;
+
+			self.newScale = getNewScale(oldScale, oldDistance, zoom, touch0, touch1);
+
+			//  设定缩放范围
+			self.newScale <= 1 && (self.newScale = 1);
+			self.newScale >= scale && (self.newScale = scale);
+
+			self.scaleWidth = Math.round(self.newScale * self.baseWidth);
+			self.scaleHeight = Math.round(self.newScale * self.baseHeight);
+			var imgLeft = Math.round(self.touchX1 - self.scaleWidth / 2);
+			var imgTop = Math.round(self.touchY1 - self.scaleHeight / 2);
+
+			self.outsideBound(imgLeft, imgTop);
+
+			self.updateCanvas();
+		};
+
+		self.__xtouchEnd = function() {
+			self.oldScale = self.newScale;
+			self.rectX = self.imgLeft;
+			self.rectY = self.imgTop;
+		};
+	}
+
+	var handle = {
+		//  图片手势初始监测
+		touchStart: function touchStart(e) {
+			var self = this;
+			var ref = e.touches;
+			var touch0 = ref[0];
+			var touch1 = ref[1];
+
+			if (!self.src) {
+				return
+			}
+
+			setTouchState(self, true, null, null);
+
+			// 计算第一个触摸点的位置,并参照改点进行缩放
+			self.__oneTouchStart(touch0);
+
+			// 两指手势触发
+			if (e.touches.length >= 2) {
+				self.__twoTouchStart(touch0, touch1);
+			}
+		},
+
+		//  图片手势动态缩放
+		touchMove: function touchMove(e) {
+			var self = this;
+			var ref = e.touches;
+			var touch0 = ref[0];
+			var touch1 = ref[1];
+
+			if (!self.src) {
+				return
+			}
+
+			setTouchState(self, null, true);
+
+			// 单指手势时触发
+			if (e.touches.length === 1) {
+				self.__oneTouchMove(touch0);
+			}
+			// 两指手势触发
+			if (e.touches.length >= 2) {
+				self.__twoTouchMove(touch0, touch1);
+			}
+		},
+
+		touchEnd: function touchEnd(e) {
+			var self = this;
+
+			if (!self.src) {
+				return
+			}
+
+			setTouchState(self, false, false, true);
+			self.__xtouchEnd();
+		}
+	};
+
+	function cut() {
+		var self = this;
+		var boundWidth = self.width; // 裁剪框默认宽度,即整个画布宽度
+		var boundHeight = self.height;
+		// 裁剪框默认高度,即整个画布高度
+		var ref = self.cut;
+		var x = ref.x;
+		if (x === void 0) x = 0;
+		var y = ref.y;
+		if (y === void 0) y = 0;
+		var width = ref.width;
+		if (width === void 0) width = boundWidth;
+		var height = ref.height;
+		if (height === void 0) height = boundHeight;
+
+		/**
+		 * 设置边界
+		 * @param imgLeft 图片左上角横坐标值
+		 * @param imgTop 图片左上角纵坐标值
+		 */
+		self.outsideBound = function(imgLeft, imgTop) {
+			self.imgLeft = imgLeft >= x ?
+				x :
+				self.scaleWidth + imgLeft - x <= width ?
+				x + width - self.scaleWidth :
+				imgLeft;
+
+			self.imgTop = imgTop >= y ?
+				y :
+				self.scaleHeight + imgTop - y <= height ?
+				y + height - self.scaleHeight :
+				imgTop;
+		};
+
+		/**
+		 * 设置边界样式
+		 * @param color	边界颜色
+		 */
+		self.setBoundStyle = function(ref) {
+			if (ref === void 0) ref = {};
+			var color = ref.color;
+			if (color === void 0) color = '#04b00f';
+			var mask = ref.mask;
+			if (mask === void 0) mask = 'rgba(0, 0, 0, 0.3)';
+			var lineWidth = ref.lineWidth;
+			if (lineWidth === void 0) lineWidth = 1;
+
+			var half = lineWidth / 2;
+			var boundOption = [{
+					start: {
+						x: x - half,
+						y: y + 10 - half
+					},
+					step1: {
+						x: x - half,
+						y: y - half
+					},
+					step2: {
+						x: x + 10 - half,
+						y: y - half
+					}
+				},
+				{
+					start: {
+						x: x - half,
+						y: y + height - 10 + half
+					},
+					step1: {
+						x: x - half,
+						y: y + height + half
+					},
+					step2: {
+						x: x + 10 - half,
+						y: y + height + half
+					}
+				},
+				{
+					start: {
+						x: x + width - 10 + half,
+						y: y - half
+					},
+					step1: {
+						x: x + width + half,
+						y: y - half
+					},
+					step2: {
+						x: x + width + half,
+						y: y + 10 - half
+					}
+				},
+				{
+					start: {
+						x: x + width + half,
+						y: y + height - 10 + half
+					},
+					step1: {
+						x: x + width + half,
+						y: y + height + half
+					},
+					step2: {
+						x: x + width - 10 + half,
+						y: y + height + half
+					}
+				}
+			];
+
+			// 绘制半透明层
+			self.ctx.beginPath();
+			self.ctx.setFillStyle(mask);
+			self.ctx.fillRect(0, 0, x, boundHeight);
+			self.ctx.fillRect(x, 0, width, y);
+			self.ctx.fillRect(x, y + height, width, boundHeight - y - height);
+			self.ctx.fillRect(x + width, 0, boundWidth - x - width, boundHeight);
+			self.ctx.fill();
+
+			boundOption.forEach(function(op) {
+				self.ctx.beginPath();
+				self.ctx.setStrokeStyle(color);
+				self.ctx.setLineWidth(lineWidth);
+				self.ctx.moveTo(op.start.x, op.start.y);
+				self.ctx.lineTo(op.step1.x, op.step1.y);
+				self.ctx.lineTo(op.step2.x, op.step2.y);
+				self.ctx.stroke();
+			});
+		};
+	}
+
+	var version = "1.3.9";
+
+	var WeCropper = function WeCropper(params) {
+		var self = this;
+		var _default = {};
+
+		validator(self, DEFAULT);
+
+		Object.keys(DEFAULT).forEach(function(key) {
+			_default[key] = DEFAULT[key].default;
+		});
+		Object.assign(self, _default, params);
+
+		self.prepare();
+		self.attachPage();
+		self.createCtx();
+		self.observer();
+		self.cutt();
+		self.methods();
+		self.init();
+		self.update();
+
+		return self
+	};
+
+	WeCropper.prototype.init = function init() {
+		var self = this;
+		var src = self.src;
+
+		self.version = version;
+
+		typeof self.onReady === 'function' && self.onReady(self.ctx, self);
+
+		if (src) {
+			self.pushOrign(src);
+		} else {
+			self.updateCanvas();
+		}
+		setTouchState(self, false, false, false);
+
+		self.oldScale = 1;
+		self.newScale = 1;
+
+		return self
+	};
+
+	Object.assign(WeCropper.prototype, handle);
+
+	WeCropper.prototype.prepare = prepare;
+	WeCropper.prototype.observer = observer;
+	WeCropper.prototype.methods = methods;
+	WeCropper.prototype.cutt = cut;
+	WeCropper.prototype.update = update;
+
+	return WeCropper;
+
+})));

+ 4 - 2
pages/index/index.vue

@@ -163,8 +163,10 @@
 		},
 		methods: {
 			logout(){
-				uni.clearStorage()
-				this.$jump('/pages/login/account-login')
+				this.$dialog.showModal('确定退出?').then(res=>{
+					uni.clearStorage()
+					this.$jump('/pages/login/account-login')
+				})
 			},
 			async init(){
 				let phone=this.$cache.get('phone')

+ 8 - 6
pages/login/account-login.vue

@@ -12,14 +12,10 @@
 			<view  style="width: 76%;margin-top: 30rpx;">
 				<u-form :model="form" :error-type="['message']"  ref="uForm">
 					<u-form-item  label-position="top" label="账号" prop="phone" label-width="150">
-						<view style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input :border="false" placeholder="请输入账号" v-model="form.phone" type="number"></u-input>
-						</view>
+						<u-input :border="false" placeholder="请输入账号" v-model="form.phone" type="number"></u-input>
 					</u-form-item>
 					<u-form-item   label-position="top" label="密码" prop="password" label-width="150">
-						<view  style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input :border="false" placeholder="请输入登录密码" type="password" v-model="form.password"></u-input>
-						</view>
+						<u-input :border="false" placeholder="请输入登录密码" type="password" v-model="form.password"></u-input>
 					</u-form-item>
 				</u-form>
 				<view  class="text-right margin-top-10 text-sm">
@@ -112,6 +108,12 @@
 	}
 </script>
 
+<style>
+	page{
+		background-color: #FFFFFF;
+	}
+</style>
+
 <style lang="scss" scoped>
 	$color:#d18c42;
 	

+ 117 - 68
pages/login/forget.vue

@@ -5,115 +5,163 @@
 		<view class="back" @click="$back">
 			<u-icon name="arrow-left" size="50" color="#919191"></u-icon>
 		</view>
-		
+
 		<view class="content">
 			<view class="top">
 				<view class="title">
 					<text>忘记登录密码</text>
-					<text>输入手机号进行找回密码</text>
+					<text>输入手机号重新设置新密码</text>
 				</view>
 			</view>
-			
-			<view  style="width: 76%;margin-top: 80rpx;">
-				<u-form >
-					<u-form-item    label="手机号" prop="phone" label-width="150">
-						<view style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input :border="false" placeholder="请输入手机号" v-model="phone" type="number"></u-input>
-						</view>
+
+			<view style="width: 76%;margin-top: 80rpx;">
+				<u-form>
+					<u-form-item label="手机号" prop="phone" label-width="150">
+						<u-input :border="false" placeholder="请输入手机号" v-model="form.phone" type="number"></u-input>
 					</u-form-item>
-					<u-form-item    label="验证码" prop="code" label-width="150">
-						<view class="flex" style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input style="width: 100%;" :border="false" placeholder="请输入验证码" v-model="code" type="text"></u-input>
-							<u-button shape="circle" slot="right" :custom-style="customStyle" size="mini" @click="getCode">{{codeTips}}</u-button>
-						</view>
+					<u-form-item label="验证码" prop="code" label-width="150">
+						<u-input style="width: 100%;" :border="false" placeholder="请输入验证码" v-model="form.code"
+							type="text"></u-input>
+						<u-button shape="circle" slot="right" :custom-style="customStyle" size="mini" @click="getCode">
+							{{codeTips}}</u-button>
 					</u-form-item>
-					<u-form-item    label="密码" prop="phone" label-width="150">
-						<view style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input :border="false" placeholder="请设置新的登录密码" v-model="phone" type="password"></u-input>
-						</view>
+					<u-form-item label="新密码" prop="phone" label-width="150">
+						<u-input :border="false" placeholder="请设置新的登录密码" v-model="form.password" type="password">
+						</u-input>
 					</u-form-item>
-					<u-form-item    label="确认密码" prop="phone" label-width="150">
-						<view style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input :border="false" placeholder="请再次输入密码" v-model="phone" type="password"></u-input>
-						</view>
+					<u-form-item label="确认新密码" prop="phone" label-width="170">
+						<u-input :border="false" placeholder="请再次输入新密码" v-model="form.confirmPassword" type="password">
+						</u-input>
 					</u-form-item>
 				</u-form>
 			</view>
-			
-			<view  style="width: 86%;margin-top: 80rpx;">
-				<view @click="login" class="btn cu-btn round" style="width:100%;height: 90rpx;font-size: 34rpx;">
-					确认修改并登录
+			<view style="width: 86%;margin-top: 80rpx;">
+				<view @click="submit" class="btn cu-btn round" style="width:100%;height: 90rpx;font-size: 34rpx;">
+					确认修改密码
 				</view>
 			</view>
 		</view>
-		
+
 		<u-verification-code seconds="60" ref="uCode" @change="codeChange"></u-verification-code>
 	</view>
 </template>
 
 <script>
+	import md5Libs from "uview-ui/libs/function/md5";
 	export default {
 		data() {
 			return {
-				customStyle:{
-					'backgroundColor':'#d18c42',
-					'color':'#ffffff'
+				customStyle: {
+					'backgroundColor': '#d18c42',
+					'color': '#ffffff'
 				},
 				codeTips: '',
-				phone:'',
-				code:'',
+				form: {
+					phone: '',
+					password: '',
+					confirmPassword: '',
+					code: '',
+				},
+
 			}
 		},
 		methods: {
-			login(){
-				uni.reLaunch({
-					url:"/pages/index/index"
-				})
+			async submit() {
+				if (this.$isEmpty(this.form.phone)) {
+					this.$u.toast('请输入手机号')
+					return
+				}
+				if (this.$isEmpty(this.form.code)) {
+					this.$u.toast('请输入验证码')
+					return
+				}
+				if (this.$isEmpty(this.form.password)) {
+					this.$u.toast('请输入新密码')
+					return
+				}
+				if (this.$isEmpty(this.form.confirmPassword)) {
+					this.$u.toast('请再次输入新密码')
+					return
+				}
+				if (this.form.password != this.form.confirmPassword) {
+					this.$u.toast('两次输入的新密码不正确!')
+					return
+				}
+				let params = {
+					type: 1,
+					code:this.form.code,
+					phone: this.form.phone,
+					password: md5Libs.md5(this.form.password),
+				}
+				let res = await this.$api.appaccount.forgetPassword(params)
+				if (res.success) {
+					this.$dialog.showModalAndBack('操作成功')
+				} else {
+					this.$u.toast(res.msg)
+				}
 			},
 			codeChange(text) {
 				this.codeTips = text;
 			},
 			// 获取验证码
 			getCode() {
-				if(this.$refs.uCode.canGetCode) {
+				if (this.$isEmpty(this.form.phone)) {
+					this.$u.toast('请输入手机号')
+					return
+				}
+				if (this.$refs.uCode.canGetCode) {
 					// 模拟向后端请求验证码
 					uni.showLoading({
 						title: '正在获取验证码',
 						mask: true
 					})
 					setTimeout(() => {
-						uni.hideLoading();
-						// 这里此提示会被this.start()方法中的提示覆盖
-						this.$u.toast('验证码已发送');
-						// 通知验证码组件内部开始倒计时
-						this.$refs.uCode.start();
+						let params = {
+							phone: this.form.phone
+						}
+						let p = this.$u.queryParams(params)
+						this.$api.sms.send(p).then(res => {
+							if (res.data == "success") {
+								this.$u.toast('验证码已发送');
+								// 通知验证码组件内部开始倒计时
+							} else {
+								this.$u.toast(res.data);
+							}
+							this.$refs.uCode.start();
+						})
 					}, 2000);
 				} else {
 					this.$u.toast('倒计时结束后再发送');
 				}
-			},
+			}
 		}
 	}
 </script>
 
+<style>
+	page {
+		background-color: #FFFFFF;
+	}
+</style>
+
 <style lang="scss" scoped>
 	$color:#d18c42;
-	
-	page{
+
+	page {
 		background-color: #FFFFFF;
 	}
-	
-	.btn{
+
+	.btn {
 		background-color: $color;
-		color:#FFFFFF;
+		color: #FFFFFF;
 	}
-	
-	.btn{
+
+	.btn {
 		background-color: $color;
-		color:#FFFFFF;
+		color: #FFFFFF;
 	}
-	
-	.bg{
+
+	.bg {
 		z-index: 99;
 		height: 440rpx;
 		width: 440rpx;
@@ -124,8 +172,8 @@
 		border-radius: 50%;
 		box-shadow: 0rpx 0rpx 50rpx #c5803b;
 	}
-	
-	.bg1{
+
+	.bg1 {
 		height: 500rpx;
 		width: 500rpx;
 		position: absolute;
@@ -135,46 +183,47 @@
 		border-radius: 50%;
 		box-shadow: #c6813b;
 	}
-	
-	.back{
+
+	.back {
 		position: absolute;
 		top: var(--status-bar-height);
 		left: 20rpx;
 		padding-top: var(--status-bar-height);
 	}
-	
-	.content{
+
+	.content {
 		height: 90vh;
 		display: flex;
 		flex-direction: column;
 		justify-content: center;
 		align-items: center;
-		
-		.top{
+
+		.top {
 			width: 76%;
 			display: flex;
-			.title{
+
+			.title {
 				margin-right: 20rpx;
 				display: flex;
 				flex-direction: column;
 				justify-content: center;
 				align-items: flex-start;
 				text-align: left;
-				
-				text:first-child{
+
+				text:first-child {
 					font-weight: 800;
 					font-size: 60rpx;
 					color: #000;
 					margin-bottom: 20rpx;
 				}
-				
-				text:last-child{
+
+				text:last-child {
 					font-size: 28rpx;
 					color: #7f7f7f;
 				}
 			}
-			
-			
+
+
 		}
 	}
 </style>

+ 13 - 11
pages/login/login.vue

@@ -21,17 +21,13 @@
 				<u-form ref="uForm" label-width="150" :model="form" label-position="top" :error-type="['message']">
 					<u-form-item   label="手机号" prop="phone"
 						label-width="150">
-						<view style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input :border="false" placeholder="请输入手机号" v-model="form.phone" type="number"></u-input>
-						</view>
+						<u-input :border="false" placeholder="请输入手机号" v-model="form.phone" type="number"></u-input>
 					</u-form-item>
 					<u-form-item  label="验证码" prop="code" >
-						<view class="flex" style="border-bottom: 1rpx solid #DDDDDD;">
-							<u-input style="width: 100%;" :border="false" placeholder="请输入验证码" v-model="form.code"
-								type="text"></u-input>
-							<u-button shape="circle" slot="right" :custom-style="customStyle" size="mini"
-								@click="getCode">{{codeTips}}</u-button>
-						</view>
+						<u-input style="width: 100%;" :border="false" placeholder="请输入验证码" v-model="form.code"
+							type="text"></u-input>
+						<u-button shape="circle" slot="right" :custom-style="customStyle" size="mini"
+							@click="getCode">{{codeTips}}</u-button>
 					</u-form-item>
 				</u-form>
 			</view>
@@ -40,10 +36,10 @@
 				<view @click="login" class="btn cu-btn round" style="width:100%;height: 90rpx;font-size: 34rpx;">
 					立即登录
 				</view>
-				<view class="center" style="margin-top: 100rpx;">
+				<!-- <view class="center" style="margin-top: 100rpx;">
 					<text style="color: #949494;">登录即代表已阅读并同意</text>
 					<text style="color: #0000ff;">《软件服务协议》</text>
-				</view>
+				</view> -->
 			</view>
 		</view>
 
@@ -161,6 +157,12 @@
 	}
 </script>
 
+<style>
+	page{
+		background-color: #FFFFFF;
+	}
+</style>
+
 <style lang="scss" scoped>
 	$color:#d18c42;
 

+ 40 - 10
pages/publish/publish.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<my-bar title="发布活动" :transparent="transparent">
-			<view slot="content" class="publish" @click="chooseImage">
+			<view slot="content" class="publish" @click="cropperSelect()">
 				<block v-if="!form.pic">
 					<u-icon name="photo" size="100" color="#cecece"></u-icon>
 					<text>上传活动封面</text>
@@ -88,7 +88,7 @@
 				</view>
 				<view class="text-center margin-top-20">
 					<text>提交即表示同意</text>
-					<text class="btn-color">《商家活动工具活动发布规则》</text>
+					<text class="btn-color" @click="protocol">《联兑通商家联营协议》</text>
 				</view>
 			</view>
 		</view>
@@ -104,6 +104,9 @@
 			</view>
 		</u-popup>
 
+		<cropper ref="cropper" selWidth="800rpx" selHeight="400rpx" @upload="cropperCondirm" :avatarSrc="form.pic"
+			avatarStyle="width:100vw;height:100vw;">
+		</cropper>
 		<u-picker v-model="timeShow" mode="time" @confirm="timeConfirm" :params="params"></u-picker>
 		<u-picker mode="region" v-model="regionShow" @confirm="regionConfirm"></u-picker>
 	</view>
@@ -185,7 +188,11 @@
 						message: '请输入积分通兑',
 						trigger: ['blur', 'change']
 					}],
-
+					
+					//裁剪框宽度
+					rectWidth:200,
+					//裁剪框高度
+					rectHeight:200
 				}
 			}
 		},
@@ -193,12 +200,42 @@
 			this.transparent = obj.scrollTop * 0.006;
 		},
 		onReady() {
+			this.getElInfo()
 			this.$refs.uForm.setRules(this.rules);
 		},
 		onLoad() {
+			uni.$on('uAvatarCropper',(path)=>{
+				this.$api.uploadFile(path).then(res=>{
+					this.form.pic=res.data.link
+				})
+			})
 			this.getShopLabelByMallId()
 		},
 		methods: {
+			protocol(){
+				uni.navigateTo({
+					url: "/pages/webView/webView?url=" + this.$global.publishActivity
+				})
+			},
+			async getElInfo() {
+				let rectInfo = await this.$u.getRect('.publish');
+				let scale=rectInfo.height/rectInfo.width
+				this.rectWidth=parseInt(this.$u.sys().windowWidth - 20)  
+				this.rectHeight=parseInt(this.rectWidth * scale)
+			},
+			//图片裁剪
+		   cropperSelect(){
+				let params={
+					destWidth:this.rectWidth,
+					destHeight:this.rectHeight,
+					rectWidth:this.rectWidth,
+					rectHeight:this.rectHeight,
+					fileType: 'jpg',
+				}
+				uni.navigateTo({
+					url:"../image-cropper/image-cropper"+this.$u.queryParams(params)
+				})
+			},
 			//显示多选框
 			showCheckBox() {
 				this.checkboxShow = true
@@ -231,13 +268,6 @@
 				this.checkboxList[e.name].checked = e.value
 				this.$forceUpdate()
 			},
-			//选择图片
-			async chooseImage() {
-				let res = await this.$mpi.chooseImage()
-				this.$api.uploadFile(res[0]).then(res => {
-					this.form.pic = res.data.link
-				})
-			},
 			//确认发布
 			publish() {
 				this.$refs.uForm.validate(valid => {

+ 1 - 1
pages/shopAudit/detail.vue

@@ -53,7 +53,7 @@
 			</view>
 			<view class="item">
 				<text class="left">商场区域</text>
-				<text class="right">{{detail.mallAreaName}}</text>
+				<text class="right">{{detail.mallAreaName || '暂无'}}</text>
 			</view>
 			<view class="item">
 				<text class="left">单位全称</text>

+ 25 - 0
pages/webView/webView.vue

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

BIN=BIN
static/icon/empty5.png


+ 15 - 0
utils/dialog.js

@@ -17,6 +17,21 @@ dialog.showModal=(content,isShowCancel=true,title='提示',)=>{
 		});
 	})
 }
+
+dialog.showModalAndBack=(content)=>{
+    uni.showModal({
+    	title: "提示",
+    	content: content,
+    	showCancel:false,
+    	success: (res)=>{
+    		if (res.confirm) {
+    			uni.navigateBack({
+    				delta:1
+    			})
+    		} 
+    	}
+    });
+}
 dialog.showLoading=(title='加载中...')=>{
 	uni.showLoading({
 		title

+ 62 - 63
utils/digital.js

@@ -2,71 +2,70 @@ let digital = {}
 
 //浮点数相加
 digital.floatAdd = (arg1, arg2) => {
-	var r1, r2, m;
-	try {
-		r1 = arg1.toString().split(".")[1].length
-	} catch (e) {
-		r1 = 0
-	}
-	try {
-		r2 = arg2.toString().split(".")[1].length
-	} catch (e) {
-		r2 = 0
-	}
-	m = Math.pow(10, Math.max(r1, r2));
-	return (arg1 * m + arg2 * m) / m;
-},
-
-//浮点数相减
-digital.floatSub = (arg1, arg2) => {
-	var r1, r2, m, n;
-	try {
-		r1 = arg1.toString().split(".")[1].length
-	} catch (e) {
-		r1 = 0
-	}
-	try {
-		r2 = arg2.toString().split(".")[1].length
-	} catch (e) {
-		r2 = 0
-	}
-	m = Math.pow(10, Math.max(r1, r2));
-	n = (r1 >= r2) ? r1 : r2;
-	return ((arg1 * m - arg2 * m) / m).toFixed(n)
-},
+		var r1, r2, m;
+		try {
+			r1 = arg1.toString().split(".")[1].length
+		} catch (e) {
+			r1 = 0
+		}
+		try {
+			r2 = arg2.toString().split(".")[1].length
+		} catch (e) {
+			r2 = 0
+		}
+		m = Math.pow(10, Math.max(r1, r2));
+		return (arg1 * m + arg2 * m) / m;
+	},
 
-//浮点数相乘
-digital.floatMul=(arg1, arg2)=> {
-	var m = 0;
-	var s1 = arg1.toString();
-	var s2 = arg2.toString();
-	try {
-		m += s1.split(".")[1].length;
-	} catch (e) {}
-	try {
-		m += s2.split(".")[1].length;
-	} catch (e) {}
+	//浮点数相减
+	digital.floatSub = (arg1, arg2) => {
+		var r1, r2, m, n;
+		try {
+			r1 = arg1.toString().split(".")[1].length
+		} catch (e) {
+			r1 = 0
+		}
+		try {
+			r2 = arg2.toString().split(".")[1].length
+		} catch (e) {
+			r2 = 0
+		}
+		m = Math.pow(10, Math.max(r1, r2));
+		n = (r1 >= r2) ? r1 : r2;
+		return ((arg1 * m - arg2 * m) / m).toFixed(n)
+	},
 
-	return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
-},
+	//浮点数相乘
+	digital.floatMul = (arg1, arg2) => {
+		var m = 0;
+		var s1 = arg1.toString();
+		var s2 = arg2.toString();
+		try {
+			m += s1.split(".")[1].length;
+		} catch (e) {}
+		try {
+			m += s2.split(".")[1].length;
+		} catch (e) {}
 
-//四舍五入保留2位小数(不够位数,则用0替补)
-digital.keepTwoDecimalFull = num => {
-  var result = parseFloat(num)
-  if (isNaN(result)) {
-    return false
-  }
-  result = Math.round(num * 100) / 100
-  var s_x = result.toString()
-  var pos_decimal = s_x.indexOf('.')
-  if (pos_decimal < 0) {
-    pos_decimal = s_x.length
-    s_x += '.'
-  }
-  while (s_x.length <= pos_decimal + 2) {
-    s_x += '0'
-  }
-  return s_x
-}
+		return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
+	},
+	//四舍五入保留2位小数(不够位数,则用0替补)
+	digital.keepTwoDecimalFull = num => {
+		var result = parseFloat(num)
+		if (isNaN(result)) {
+			return false
+		}
+		result = Math.round(num * 100) / 100
+		var s_x = result.toString()
+		var pos_decimal = s_x.indexOf('.')
+		if (pos_decimal < 0) {
+			pos_decimal = s_x.length
+			s_x += '.'
+		}
+		while (s_x.length <= pos_decimal + 2) {
+			s_x += '0'
+		}
+		return s_x
+	}
 
 export default digital

+ 1 - 0
utils/global.js

@@ -1,5 +1,6 @@
 let global = {
 	
+	publishActivity:'https://ldt.guosen-fumao.cn/publish_activity.html',
 	//发起者类型
 	sponsorType:{
 		mall:'1',//商场