dever преди 4 години
родител
ревизия
534636c103
променени са 100 файла, в които са добавени 3058 реда и са изтрити 1689 реда
  1. 1 1
      lib/clipboard.thorui.js
  2. 7 0
      lib/dever/components/drawerWindow.vue
  3. 33 20
      lib/graceUI/components/graceActionSheet.vue
  4. 1 1
      lib/graceUI/components/graceAddressPicker.vue
  5. 40 0
      lib/graceUI/components/graceBanner.vue
  6. 1 1
      lib/graceUI/components/graceBottomDialog.vue
  7. 1 1
      lib/graceUI/components/graceDate.vue
  8. 2 2
      lib/graceUI/components/graceDateTime.vue
  9. 2 2
      lib/graceUI/components/graceDateTimeBetween.vue
  10. 1 1
      lib/graceUI/components/graceDialog.vue
  11. 4 11
      lib/graceUI/components/graceDrawer.vue
  12. 4 3
      lib/graceUI/components/graceFaceGroup.vue
  13. 7 2
      lib/graceUI/components/graceFullLoading.vue
  14. 41 35
      lib/graceUI/components/graceHeaderAlert.vue
  15. 31 45
      lib/graceUI/components/graceImageCrop.vue
  16. 1 1
      lib/graceUI/components/graceNavBar.vue
  17. 1 1
      lib/graceUI/components/graceNavBar2.vue
  18. 19 5
      lib/graceUI/components/graceNumberBox.vue
  19. 47 43
      lib/graceUI/components/graceNumberKeyboard.vue
  20. 16 9
      lib/graceUI/components/graceNvueActionSheet.vue
  21. 2 2
      lib/graceUI/components/graceNvueAddressPicker.vue
  22. 40 40
      lib/graceUI/components/graceNvueBottomDialog.vue
  23. 1 1
      lib/graceUI/components/graceNvueDate.vue
  24. 75 75
      lib/graceUI/components/graceNvueDateTime.vue
  25. 1 1
      lib/graceUI/components/graceNvueDialog.vue
  26. 9 9
      lib/graceUI/components/graceNvueDrawer.vue
  27. 24 17
      lib/graceUI/components/graceNvueFullLoading.vue
  28. 45 19
      lib/graceUI/components/graceNvueHeaderAlert.vue
  29. 1 1
      lib/graceUI/components/graceNvueNavBar.vue
  30. 1 1
      lib/graceUI/components/graceNvueNavBar2.vue
  31. 12 3
      lib/graceUI/components/graceNvueNumberBox.vue
  32. 84 80
      lib/graceUI/components/graceNvueNumberKeyboard.vue
  33. 70 0
      lib/graceUI/components/graceNvuePK.vue
  34. 7 6
      lib/graceUI/components/graceNvuePage.vue
  35. 60 44
      lib/graceUI/components/graceNvuePopupMenu.vue
  36. 2 2
      lib/graceUI/components/graceNvueReload.vue
  37. 46 0
      lib/graceUI/components/graceNvueRightMessage.vue
  38. 254 0
      lib/graceUI/components/graceNvueSchedule.vue
  39. 27 12
      lib/graceUI/components/graceNvueSelectImg.vue
  40. 4 2
      lib/graceUI/components/graceNvueSelectImgAndUpload.vue
  41. 17 9
      lib/graceUI/components/graceNvueSelectList.vue
  42. 29 11
      lib/graceUI/components/graceNvueSelectMenu.vue
  43. 46 41
      lib/graceUI/components/graceNvueSelectTags.vue
  44. 49 10
      lib/graceUI/components/graceNvueShade.vue
  45. 2 2
      lib/graceUI/components/graceNvueSlider.vue
  46. 7 3
      lib/graceUI/components/graceNvueSpeaker.vue
  47. 122 0
      lib/graceUI/components/graceNvueSwipeList.vue
  48. 16 8
      lib/graceUI/components/graceNvueSwiper.vue
  49. 0 5
      lib/graceUI/components/graceNvueSwiperCard.vue
  50. 6 6
      lib/graceUI/components/graceNvueTouch.vue
  51. 10 5
      lib/graceUI/components/graceNvueTree.vue
  52. 60 0
      lib/graceUI/components/gracePK.vue
  53. 20 20
      lib/graceUI/components/gracePage.vue
  54. 66 46
      lib/graceUI/components/gracePopupMenu.vue
  55. 1 1
      lib/graceUI/components/graceReload.vue
  56. 46 0
      lib/graceUI/components/graceRightMessage.vue
  57. 253 0
      lib/graceUI/components/graceSchedule.vue
  58. 27 10
      lib/graceUI/components/graceSelectImg.vue
  59. 4 2
      lib/graceUI/components/graceSelectImgAndUpload.vue
  60. 17 10
      lib/graceUI/components/graceSelectList.vue
  61. 34 16
      lib/graceUI/components/graceSelectMenu.vue
  62. 12 5
      lib/graceUI/components/graceSelectTags.vue
  63. 23 10
      lib/graceUI/components/graceShade.vue
  64. 2 2
      lib/graceUI/components/graceSlider.vue
  65. 14 7
      lib/graceUI/components/graceSpeaker.vue
  66. 9 1
      lib/graceUI/components/graceSwipeList.vue
  67. 143 133
      lib/graceUI/components/graceSwiper.vue
  68. 6 6
      lib/graceUI/components/graceTouch.vue
  69. 15 6
      lib/graceUI/components/graceTree.vue
  70. 0 371
      lib/graceUI/grace.js
  71. 2 2
      lib/graceUI/graceIcons.css
  72. 2 1
      lib/graceUI/graceUI.css
  73. 16 9
      lib/graceUI/weexComponents/graceActionSheet.nvue
  74. 2 2
      lib/graceUI/weexComponents/graceAddressPicker.nvue
  75. 40 40
      lib/graceUI/weexComponents/graceBottomDialog.nvue
  76. 1 1
      lib/graceUI/weexComponents/graceDate.nvue
  77. 77 76
      lib/graceUI/weexComponents/graceDateTime.nvue
  78. 40 40
      lib/graceUI/weexComponents/graceDateTimeBetween.nvue
  79. 1 1
      lib/graceUI/weexComponents/graceDialog.nvue
  80. 9 9
      lib/graceUI/weexComponents/graceDrawer.nvue
  81. 24 17
      lib/graceUI/weexComponents/graceFullLoading.nvue
  82. 45 19
      lib/graceUI/weexComponents/graceHeaderAlert.nvue
  83. 1 1
      lib/graceUI/weexComponents/graceNavBar.nvue
  84. 1 1
      lib/graceUI/weexComponents/graceNavBar2.nvue
  85. 12 3
      lib/graceUI/weexComponents/graceNumberBox.nvue
  86. 84 80
      lib/graceUI/weexComponents/graceNumberKeyboard.nvue
  87. 70 0
      lib/graceUI/weexComponents/gracePK.nvue
  88. 7 6
      lib/graceUI/weexComponents/gracePage.nvue
  89. 60 44
      lib/graceUI/weexComponents/gracePopupMenu.nvue
  90. 2 2
      lib/graceUI/weexComponents/graceReload.nvue
  91. 46 0
      lib/graceUI/weexComponents/graceRightMessage.nvue
  92. 254 0
      lib/graceUI/weexComponents/graceSchedule.nvue
  93. 27 12
      lib/graceUI/weexComponents/graceSelectImg.nvue
  94. 4 2
      lib/graceUI/weexComponents/graceSelectImgAndUpload.nvue
  95. 17 9
      lib/graceUI/weexComponents/graceSelectList.nvue
  96. 29 11
      lib/graceUI/weexComponents/graceSelectMenu.nvue
  97. 46 41
      lib/graceUI/weexComponents/graceSelectTags.nvue
  98. 49 10
      lib/graceUI/weexComponents/graceShade.nvue
  99. 2 2
      lib/graceUI/weexComponents/graceSlider.nvue
  100. 7 3
      lib/graceUI/weexComponents/graceSpeaker.nvue

+ 1 - 1
lib/clipboard.thorui.js

@@ -5,7 +5,7 @@
  * @version 1.0.0
  **/
 // #ifdef H5
-import ClipboardJS from "@/components/clipboard.min.js"
+import ClipboardJS from "@/lib/clipboard.min.js"
 // #endif
 const thorui = {
 	getClipboardData: function(data, callback) {

+ 7 - 0
lib/dever/components/drawerWindow.vue

@@ -55,6 +55,10 @@ export default {
 			default : 0
 		},
 		// #endif
+		type : {
+			type : String,
+			default : ''
+		},
 	},
 	data() {
 		return {
@@ -72,6 +76,9 @@ export default {
 			this.$emit('closeDrawer');
 		},
 		end : function(e) {
+			if (this.type == 'share') {
+				return;
+			}
 			var type = this.Dever.slideEnd(e);
 			if (type == 3 || type == 4) {
 				this.closeDrawer();

+ 33 - 20
lib/graceUI/components/graceActionSheet.vue

@@ -1,23 +1,35 @@
 <template>
-	<view class="graceActionSheet" @tap.stop="closeByShade" @touchmove.stop="stopFun" 
+	<view class="graceActionSheet" @tap.stop="closeByShade" @touchmove.stop.prevent="stopFun" 
 	:style="{backgroundColor:background, zIndex:zIndex, width:realShow ? '750rpx' : '0rpx'}">
-		<view :class="['graceActionSheetBody', isIpx ? 'grace-ipx-bottom' : '']" 
-		:style="{width:realShow ? width : '0rpx',left:left,borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius, zIndex:zIndex+1}" 
+		<view :class="['graceActionSheetBody', isIpx ? 'grace-ipx-bottom' : '']" 
+		:style="{
+			width:realShow?width:'0rpx',left:left,
+			borderTopLeftRadius:borderRadius,
+			borderTopRightRadius:borderRadius,
+			zIndex:zIndex+1}" 
 		@tap.stop="stopFun">
 			<view class="graceActionSheetTitle" :style="{color:titleColor}">{{title}}</view>
-			<view class="graceActionSheetList" v-for="(item, index) in items" :key="index" @tap.stop="selected" :data-index="index" 
-			:style="{color:listColor, lineHeight:listLineHeight, fontSize:listFontSize}">{{item}}</view>
-			<view class="graceActionSheetList" :style="{border:'none', color:cancelBtnColor}" @tap.stop="cancel">{{cancelBtnName}}</view>
+			<scroll-view scroll-y :style="{height:height}">
+				<view class="graceActionSheetList" 
+				v-for="(item, index) in items" :key="index" 
+				@tap.stop="selected" :data-index="index" 
+				:style="{
+					color:listColor, 
+					lineHeight:listLineHeight, 
+					fontSize:listFontSize}">{{item}}</view>
+			</scroll-view>
+			<view class="graceActionSheetList" :style="{border:'none', color:cancelBtnColor}" v-if="isCancelBtn" @tap.stop="cancel">{{cancelBtnName}}</view>
 		</view>
 	</view>
 </template>
 <script>
 export default {
-	props: {
-		width:{type:String,default:'720rpx'},
+	props: {
+		width:{type:String,default:'720rpx'},
+		height:{type:String,default:'500rpx'},
 		left:{type:String,default:'15rpx'},
-		background:{type : String,default : 'rgba(0, 0, 0, 0.3)'},
-		borderRadius : {type : String,default : '10rpx'},
+		background:{type : String,default : 'rgba(0, 0, 0, 0.3)'},
+		borderRadius : {type : String,default : '10rpx'},
 		zIndex:{type : Number,default : 99},
 		title:{type:String,default:''},
 		titleColor:{type:String, default:'#323232'},
@@ -25,6 +37,7 @@ export default {
 		listColor:{type:String, default:'#3688FF'},
 		listLineHeight:{type:String, default:'100rpx'},
 		listFontSize:{type:String, default:'30rpx'},
+		isCancelBtn:{type:Boolean, default:true},
 		cancelBtnName:{type:String,default:'取消'},
 		cancelBtnColor:{type:String, default:'#999999'}
 	},
@@ -34,16 +47,16 @@ export default {
 			isIpx:false
 		}
 	},
-	created : function(){
-		// #ifndef APP-PLUS
-		try {
-		    var res = uni.getSystemInfoSync();
-			res.model = res.model.replace(' ', '');
-			res.model = res.model.toLowerCase();
-			if(res.model.indexOf('iphonex') != -1 || res.model.indexOf('iphone11') != -1){
-				this.isIpx = true;
-			}
-		} catch (e){return null;}
+	created : function(){
+		// #ifndef APP-PLUS
+		try {
+		    var res = uni.getSystemInfoSync();
+			res.model = res.model.replace(' ', '');
+			res.model = res.model.toLowerCase();
+			if(res.model.indexOf('iphonex') != -1 || res.model.indexOf('iphone11') != -1){
+				this.isIpx = true;
+			}
+		} catch (e){return null;}
 		// #endif
 	},
 	methods:{

+ 1 - 1
lib/graceUI/components/graceAddressPicker.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="gap" v-if="show" @touchmove.stop="" @tap.stop="" :style="{backgroundColor:background}">
+	<view class="gap" v-if="show" @touchmove.stop.prevent="" @tap.stop="" :style="{backgroundColor:background}">
 		<view class="gap-body">
 			<view class="gap-header grace-space-between">
 				<text class="gap-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>

+ 40 - 0
lib/graceUI/components/graceBanner.vue

@@ -0,0 +1,40 @@
+<template name="graceBanner">
+	<view style="margin-top:20px;">
+		<grace-sup text="graceui" textColor="#A5A7B2" textSize="24px"  sup="2.0" supSize="14px" :isBold="true"></grace-sup>
+		<view class="grace-banner">
+			<view class="logo">
+				<image src="https://graceui.oss-cn-beijing.aliyuncs.com/logo.png" mode="widthFix"></image>
+			</view>
+			<view class="body">
+				<view class="title">{{title}}</view>
+				<view class="desc">{{desc}}</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+import graceSup from './graceSup.vue';
+export default {
+	components:{
+		'grace-sup' : graceSup
+	},
+	props: {
+		title:{
+			type : String,
+			default : "..."
+		},
+		desc:{
+			type : String,
+			default : "再出发 更轻快 更漂亮 更丰富"
+		},
+	}
+}
+</script>
+<style scoped>
+.grace-banner{display:flex; flex-wrap:nowrap; justify-content:center; background:#FFFFFF; padding:30upx; box-shadow:0px 0px 8px #D5D6D8; margin-top:20px; border-radius:8px;}
+.grace-banner .logo{width:100upx; height:100upx; margin-right:30upx; font-size:0;}
+.grace-banner .logo image{width:100upx; height:100upx;}
+.grace-banner .body{width:auto; display:inline-block; margin-right:30px;}
+.grace-banner .body .title{font-size:32upx; font-weight:700; color:#3688FF; line-height:1.5em;}
+.grace-banner .body .desc{font-size:22upx; color:#A5A7B2; line-height:1.5em; margin-top:5px;}
+</style>

+ 1 - 1
lib/graceUI/components/graceBottomDialog.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="grace-btdialog-shade" v-if="realShow" @tap.stop="closeDialog" @touchmove.stop="stopFun" 
+	<view class="grace-btdialog-shade" v-if="realShow" @tap.stop="closeDialog" @touchmove.stop.prevent="stopFun" 
 	:style="{backgroundColor:background, zIndex:zIndex}">
 		<view :class="['dialog', 'gdIn', isIpx ? 'grace-ipx-bottom' : '', isOut ? 'gdOut' : '']" 
 		:style="{width:width,left:left,borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius}" 

+ 1 - 1
lib/graceUI/components/graceDate.vue

@@ -1,5 +1,5 @@
 <template name="graceDate">
-	<view class="grace-date" v-if="show" :style="{top:top, zIndex:zIndex}" @tap.stop="" @touchmove.stop="">
+	<view class="grace-date" v-if="show" :style="{top:top, zIndex:zIndex}" @tap.stop="" @touchmove.stop.prevent="">
 		<view class="grace-date-header">
 			<text class="grace-date-header-btn grace-icons" @click="prevYear">&#xe600;&#xe600;</text>
 			<text class="grace-date-header-btn grace-icons" @click="prevMonth">&#xe600;</text>

+ 2 - 2
lib/graceUI/components/graceDateTime.vue

@@ -1,8 +1,8 @@
 <template>
 	<view>
 		<view @tap.stop="open"><slot></slot></view>
-		<view class="graceDateTime" v-if="show" @touchmove.stop="" @tap.self="close" :style="{backgroundColor:background}"></view>
-		<view class="graceDateTime-body" :class="[show?'gdIn':'gdOut']" @touchmove.stop="" :style="{paddingBottom:paddingBottom}">
+		<view class="graceDateTime" v-if="show" @touchmove.stop.prevent="" @tap.self="close" :style="{backgroundColor:background}"></view>
+		<view class="graceDateTime-body" :class="[show?'gdIn':'gdOut']" @touchmove.stop.prevent="" :style="{paddingBottom:paddingBottom}">
 			<view class="graceDateTime-header grace-space-between" v-if="isHeaderBar">
 				<text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
 				<text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>

+ 2 - 2
lib/graceUI/components/graceDateTimeBetween.vue

@@ -1,8 +1,8 @@
 <template>
 	<view>
 		<view @tap.stop="open"><slot></slot></view>
-		<view class="graceDateTimeBT" v-if="show" @touchmove.stop="" @tap.self="close" :style="{backgroundColor:background}"></view>
-		<view class="graceDateTimeBT-body" :class="[show?'gdIn':'gdOut']" @touchmove.stop="" :style="{paddingBottom:paddingBottom}">
+		<view class="graceDateTimeBT" v-if="show" @touchmove.stop.prevent="" @tap.self="close" :style="{backgroundColor:background}"></view>
+		<view class="graceDateTimeBT-body" :class="[show?'gdIn':'gdOut']" @touchmove.stop.prevent="" :style="{paddingBottom:paddingBottom}">
 			<view class="graceDateTimeBT-header grace-space-between">
 				<text class="graceDateTime-header-btn" 
 				:style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>

+ 1 - 1
lib/graceUI/components/graceDialog.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="grace-dialog-shade" v-if="show" @tap.stop="closeDialogByShade" @touchmove.stop="stopFun" :style="{backgroundColor:background, zIndex:zIndex}">
+	<view class="grace-dialog-shade" v-if="show" @tap.stop="closeDialogByShade" @touchmove.stop.prevent="stopFun" :style="{backgroundColor:background, zIndex:zIndex}">
 		<view class="grace-dialog gdFadeIn" @tap.stop="stopFun" :style="{width:width, borderRadius:borderRadius}">
 			<view class="grace-dialog-title" v-if="isTitle" 
 			:style="{fontSize:titleSize, color:titleColor, fontWeight:titleWeight?'bold':'', background:titleBg, lineHeight:titleHeight}">{{title}}</view>

+ 4 - 11
lib/graceUI/components/graceDrawer.vue

@@ -1,8 +1,8 @@
 <template>
-	<view class="grace-drawer-shade" v-if="show" :style="{background:background,zIndex:zIndex, top:top+'px'}">
-		<scroll-view scroll-y="true" :class="['grace-drawer-shade-nav', direction == 'left' ? 'gdSlideLeft' : 'gdSlideRight']" :style="{width:width,padding:padding, zIndex:zIndex+1, background:slotBg}" @tap.stop="stopFun" @touchstart="Dever.slide" @touchend="end">
+	<view class="grace-drawer-shade" v-if="show" @tap.stop="closeDrawer" @touchmove.stop.prevent="" :style="{background:background,zIndex:zIndex, top:top+'px'}">
+		<view  :class="['grace-drawer-shade-nav', direction == 'left' ? 'gdSlideLeft' : 'gdSlideRight']" :style="{width:width,padding:padding, zIndex:zIndex+1, background:slotBg}" @tap.stop="stopFun">
 			<slot name="links"></slot>
-		</scroll-view>
+		</view>
 	</view>
 </template>
 <script>
@@ -54,12 +54,6 @@ export default {
 		closeDrawer : function(){
 			this.$emit('closeDrawer');
 		},
-		end : function(e) {
-			var type = this.Dever.slideEnd(e);
-			if (type == 3 || type == 4) {
-				this.closeDrawer();
-			}
-		},
 		stopFun : function(){}
 	}
 }
@@ -68,8 +62,7 @@ export default {
 @keyframes gdSlideLeft{ from {left:-300px; } 100% { left:0px; }}
 .gdSlideLeft {animation:gdSlideLeft 200ms linear; left:0;}
 @keyframes gdSlideRight{ from {right:-300px; } 100% { right:0px; }}
-.gdSlideRight1 {animation:gdSlideRight 200ms linear; right:0;}
-.gdSlideRight {right:0;}
+.gdSlideRight {animation:gdSlideRight 200ms linear; right:0;}
 .grace-drawer-shade{position:fixed; width:100%; height:100%; top:0; left:0; z-index:1; background:rgba(0, 0, 0, 0.5);}
 .grace-drawer-shade-nav{height:100%; background:#FFFFFF; position:absolute; top:0; z-index:2; box-sizing:border-box;}
 </style>

+ 4 - 3
lib/graceUI/components/graceFaceGroup.vue

@@ -1,13 +1,13 @@
 <template>
 	<view class="grace-face-group" :style="{height:(size + borderWidth * 2 ) +'rpx'}">
 		<view class="grace-face-items" v-if="isAddBtn" 
-		:style="{'z-index':2, width:size+'rpx', height:size+'rpx', border:borderWidth + 'rpx solid ' + borderColor}" 
+		:style="{'z-index':startIndex, width:size+'rpx', height:size+'rpx', border:borderWidth + 'rpx solid ' + borderColor}" 
 		@tap.stop="addBtnClick">
 			<slot></slot>
 		</view>
 		<view class="grace-face-items" 
 		v-for="(item, index) in items" :key="index" 
-		:style="{'z-index':1 - index, 
+		:style="{'z-index':startIndex - index - 1, 
 			left:isAddBtn ? (space * (index+1)) + 'rpx' : (space * index) + 'rpx', 
 			border:borderWidth + 'rpx solid ' + borderColor, 
 			width:size+'rpx', height:size+'rpx'}">
@@ -43,7 +43,8 @@ export default{
 		isAddBtn : {
 			type : Boolean,
 			default : false
-		}
+		},
+		startIndex : {type:Number, default:100}
 	},
 	methods:{
 		addBtnClick : function () {

+ 7 - 2
lib/graceUI/components/graceFullLoading.vue

@@ -1,5 +1,10 @@
 <template name="graceFullLoading">
-	<view class="grace-full-loading" v-if="graceFullLoading" :style="{background:background}"  @tap.stop="stopFun" @touchmove.stop="stopFun">
+	<view class="grace-full-loading" 
+	:style="{
+		background:background,
+		height:graceFullLoading?'100%':'0px',
+		opacity:graceFullLoading?1:0}" 
+	@tap.stop="stopFun" @touchmove.stop.prevent="stopFun">
 		<view class="content">
 			<view class="image"><image :src="logoUrl" mode="widthFix" :style="{width:size, height:size}"></image></view>
 			<view class="text" :style="{fontSize:fontSize, color:textColor}">{{text}}</view>
@@ -46,7 +51,7 @@ export default {
 </script>
 <style scoped>
 @keyframes grace-fade{0%{opacity:0.6;} 25%{opacity:1;} 50%{opacity:0.6;} 75%{opacity:1;} 100%{opacity:0.6;}}
-.grace-full-loading{width:100%; height:100%; background:#FFFFFF; position:fixed; z-index:9999; left:0; top:0; bottom:0;}
+.grace-full-loading{width:100%; background:#FFFFFF; position:fixed; z-index:9999; top:0; left:0; bottom:0; overflow:hidden;}
 .grace-full-loading .content{width:300rpx; height:auto; position:absolute; z-index:100; left:50%; top:50%; transform:translate(-50%, -50%); animation:grace-fade 3500ms infinite linear; opacity:0.6; padding:10rpx;}
 .grace-full-loading .image{text-align:center; font-size:0;}
 .grace-full-loading .image image{width:138rpx; height:138rpx; border-radius:138rpx;}

+ 41 - 35
lib/graceUI/components/graceHeaderAlert.vue

@@ -1,48 +1,54 @@
 <template name="graceHeaderAlert">
-	<view :class="[show ? 'ganimate-show grace-alert' : 'grace-alert']" :style="{background:background, top : topReal + 'px'}" v-if="showIn">
+	<view :class="['grace-alert',showIn ? 'ganimate-show' : 'ganimate-hide']" 
+	:style="{background:background, top : topReal + 'px', width:width+'rpx', left:((750-width)/2)+'rpx'}" v-if="showIn">
 		<slot></slot>
 	</view>
 </template>
 <script>
-	export default {
-		name: "graceHeaderAlert",
-		props: {
-			show    : {
-				type : Boolean,
-				default : false
-			},
-			background : {
-				type : String,
-				default : '#F1F2F3'
-			},
-			top:{
-				type : Number,
-				default: 5
-			}
-		},
-		data() {
-			return {
-				showIn : false,
-				topReal : 0
+export default {
+	name: "graceHeaderAlert",
+	props: {
+		show       : { type : Boolean, default : false },
+		background : { type : String, default : '#F1F2F3' },
+		top        : { type : Number, default : 20 },
+		width      : { type : Number, default : 580},
+		duration   : { type : Number, default : 2500}
+	},
+	data() {
+		return {
+			showIn : false,
+			topReal : 0
+		}
+	},
+	created:function(){
+		this.topReal = this.top;
+		// #ifdef H5
+		this.topReal += 46;
+		// #endif
+		this.showIn = this.show;
+	},
+	watch: {
+		show : function(n , o){
+			if(n){
+				this.showIn = n;
+				setTimeout(()=>{this.showIn = false;}, this.duration);
 			}
+		}
+	},
+	methods:{
+		open:function(){
+			this.showIn = true;
+			setTimeout(()=>{this.showIn = false;}, this.duration);
 		},
-		created:function(){
-			this.topReal = this.top;
-			// #ifdef H5
-			this.topReal += 46;
-			// #endif
-		},
-		watch: {
-			show : function(n , o){
-				this.showIn = true;
-				setTimeout(function(){this.showIn = false}.bind(this), 2000);
-			}
+		close:function(){
+			this.showIn = false;
 		}
 	}
+}
 </script>
 <style scoped>
-@keyframes g-show{from {opacity:0; transform:scale3d(0.1, 0.1, 0.1);} to {opacity:1;}}
-.ganimate-show{animation:g-show 200ms linear;}
-.grace-alert{display:flex; width:580rpx; padding:25rpx; border-radius:10rpx; flex-wrap:nowrap; justify-content:center; align-items:center; background:#FFF; position:fixed; z-index:99999; left:60rpx; top:50px;}
+@keyframes g-show{from {opacity:0; transform:scale3d(0.1, 0.1, 0.1);} to {opacity:1; transform:scale3d(1, 1, 1);}}
+.ganimate-show{animation:g-show 250ms linear;}
+.grace-alert{display:flex; box-sizing:border-box; padding:25rpx; border-radius:10rpx; flex-wrap:nowrap; justify-content:center; align-items:center; background:#FFF; position:fixed; z-index:99999; top:50px;}
 .grace-alert::before{content:""; display:block; background:inherit; filter:blur(6rpx); position:absolute; width:100%; height:100%; top:8rpx; left:8rpx; z-index:-1; opacity:0.38; transform-origin:0 0; border-radius:inherit; transform:scale(1, 1);}
 </style>

+ 31 - 45
lib/graceUI/components/graceImageCrop.vue

@@ -1,18 +1,25 @@
 <template>
     <view class="vue-cropper" ref="cropper" :style="{top:`${containerTop}px`}" v-show="show">
         <view class="cropper-box">
-            <view class="cropper-box-canvas" @touchstart.stop.prevent="imgTouchStart" @touchmove.stop.prevent="imgMoveing" @touchend.stop.prevent="imgMoveEnd" :style="{
-			'width': imageWidth + 'px',
-			'height': imageHeight + 'px',
+            <view class="cropper-box-canvas" @touchstart.stop.prevent="imgTouchStart" 
+			@touchmove.stop.prevent="imgMoveing" @touchend.stop.prevent="imgMoveEnd" :style="{
+			'width': '750rpx',
 			'transform': 'scale(' + scale + ',' + scale + ') ' + 'translate3d('+ x / scale + 'px,' + y / scale + 'px,' + '0)'
 			+ 'rotateZ('+ rotate * 90 +'deg)'}">
-                <image :src="src" alt="cropper-img" ref="cropperImg" mode="scaleToFill" class="uni-image"></image>
+                <image :src="src" mode="widthFix" :style="{width:'100%', height : imageHeight +'px'}"></image>
             </view>
         </view>
         <view class="cropper-drag-box cropper-modal cropper-move pointer-events"></view>
-        <view class="cropper-crop-box" :class="{'pointer-events': cropFixed}" :style="{'width': cropW + 'px','height': cropH + 'px','transform': 'translate3d('+ cropOffsertX + 'px,' + cropOffsertY + 'px,' + '0)'}">
+        <view class="cropper-crop-box" :class="{'pointer-events': cropFixed}" 
+		:style="{
+			'width': cropW + 'px','height': cropH + 'px',
+			'transform': 'translate3d('+ cropOffsertX + 'px,' + cropOffsertY + 'px,' + '0)'}">
             <view class="cropper-view-box">
-                <image :style="{'width': imageWidth + 'px','height': imageHeight + 'px','transform': 'scale(' + scale + ',' + scale + ') ' + 'translate3d('+ (x - cropOffsertX) / scale  + 'px,' + (y - cropOffsertY) / scale + 'px,' + '0)' + 'rotateZ('+ rotate * 90 +'deg)'}" mode="scaleToFill" :src="src" alt="cropper-img"></image>
+                <image :style="{
+					'width': imageWidth + 'px',
+					height : imageHeight +'px',
+					'transform': 'scale(' + scale + ',' + scale + ') ' + 'translate3d('+ (x - cropOffsertX) / scale  + 'px,' + (y - cropOffsertY) / scale + 'px,' + '0)' + 'rotateZ('+ rotate * 90 +'deg)'}" 
+					:src="src"></image>
             </view>
             <view v-if="!cropFixed" class="cropper-face cropper-move" @touchstart.stop.prevent="touchStart" @touchmove.stop.prevent="cropMoveing"></view>
             <view class="crop-line line-w"></view>
@@ -21,11 +28,6 @@
             <view class="crop-line line-d"></view>
         </view>
 		<canvas  id="myCanvas" canvas-id="myCanvas" class="cropper-canvas" :style="{ 'width': cropW + 'px','height': cropH + 'px' }"></canvas>
-        <view class="btn-group">
-            <view class="btn-item reset-btn" v-show="showResetBtn" @tap="init"></view>
-            <view class="btn-item rotate-btn" v-show="showRotateBtn" @tap="rotateHandler"></view>
-        </view>
-
         <view class="uni-info__ft" :style="{paddingBottom:iPhoneXBottomHeightRpx+'rpx', background:'#FFFFFF'}">
             <view class="uni-modal__btn uni-modal__btn_default" style="color: rgb(0, 0, 0);" @tap="cancel">取消</view>
             <view class="uni-modal__btn uni-modal__btn_primary" style="color: rgb(0, 122, 255);" @tap="confirm">确定</view>
@@ -85,7 +87,10 @@ export default {
 			y: 0,
 			startL: 0,
 			oldScale: 1,
-			iPhoneXBottomHeightRpx:0
+			iPhoneXBottomHeightRpx:0,
+			imageWidth : 100,
+			imageHeight : 100,
+			imageRatio : 1
 		}
 	},
 	created:function(){
@@ -122,27 +127,7 @@ export default {
 		},
 		windowHeight() {
 			return this.sysInfo.windowHeight;
-		},
-		// 图片宽高比
-		imageRatio() {
-			if (this.imageRealHeight > 0) {
-				return this.imageRealWidth / this.imageRealHeight;;
-			}
-			return 0;
-		},
-		// 等比缩放后的宽度
-		imageWidth() {
-			if (this.imageRatio >= 1) {
-				return this.windowWidth;
-			}
-			var imageWidth = this.windowWidth * this.imageRatio;
-			if(imageWidth < this.cropWidth){return this.cropWidth;}
-			return this.windowWidth
-		},
-		// 等比缩放后的高度
-		imageHeight() {
-			return this.windowWidth / this.imageRatio
-		},
+		}
 	},
 	methods: {
 		rotateHandler() {
@@ -162,29 +147,30 @@ export default {
 				uni.hideLoading()
 			}).catch((e) => {
 				uni.hideLoading()
-				uni.showModal({
-					title: '标题',
-					content: '图片加载失败'
-				})
+				uni.showModal({ title: '标题', content: '图片加载失败'});
 			})
 		},
-		loadImage(src) {
+		loadImage(src) {
 			const _this = this
 			return new Promise((resolve, reject) => {
 				uni.getImageInfo({
 					src: src,
 					success: (res) => {
-					
-						_this.imageRealWidth = res.width
-						_this.imageRealHeight = res.height
-
+						_this.imageRealWidth  = res.width
+						_this.imageRealHeight = res.height
+						
+						_this.imageRatio   = _this.imageRealWidth / _this.imageRealHeight;
+						// 等比缩放后的宽度
+						_this.imageWidth   = _this.windowWidth;
+						// 等比缩放后的高度
+						_this.imageHeight  = _this.windowWidth / _this.imageRatio;
 						_this.cropOffsertX = _this.windowWidth / 2 - _this.cropW / 2
 						_this.cropOffsertY = _this.windowHeight / 2 - _this.cropH / 2
-						_this.show = true
+						_this.show = true;
 
 						_this.$nextTick(() => {
-							_this.x = _this.windowWidth / 2 - _this.imageWidth / 2
-							_this.y = _this.containerHeight / 2 - _this.imageHeight / 2
+							_this.x = 0;
+							_this.y = 0
 						});
 						resolve(res)
 					},

+ 1 - 1
lib/graceUI/components/graceNavBar.vue

@@ -1,5 +1,5 @@
 <template>
-	<scroll-view 
+	<scroll-view scroll-with-animation 
 	:class="['grace-nav-bar', isCenter ? 'grace-nav-center' : '']" :scroll-x="true" :show-scrollbar="false" 
 	:scroll-into-view="'tab-'+currentIndex+autoLeft">
 		<view class="nav-item" :id="'tab-'+index" 

+ 1 - 1
lib/graceUI/components/graceNavBar2.vue

@@ -1,5 +1,5 @@
 <template>
-	<scroll-view
+	<scroll-view scroll-with-animation 
 	:class="['grace-nav-bar2', isCenter ? 'grace-nav2-center' : '']" :scroll-x="true" :show-scrollbar="false" 
 	:scroll-into-view="'tab-'+currentIndex+autoLeft">
 		<view class="nav2-item" :id="'tab-'+index" :style="{width:size+'rpx', height:(lineHeight+lineHeightSamll+6)+'rpx'}" 

+ 19 - 5
lib/graceUI/components/graceNumberBox.vue

@@ -1,11 +1,20 @@
 <template>
 	<view class="grace-number-box" :style="{width:width}">
 		<view class="grace-number-box-doBtn" @tap.stop="reduce" 
-		:style="{width:btnSize, height:btnSize, fontSize:btnFontSize, lineHeight:btnSize, color:btnColr}">-</view>
-		<input class="grace-number-box-input" type="number" v-model="inputNumber" :disabled="disabled" 
-		:style="{background:inputBG, height:inputHeight, lineHeight:inputHeight, fontSize:inputFontSize, color:inputColor, padding:inputPadding, borderRadius:inputBorderRadius}"></input>
+		:style="{
+			width:btnSize, height:btnSize, fontSize:btnFontSize, 
+			lineHeight:btnSize, color:btnColr
+		}">-</view>
+		<input class="grace-number-box-input" :value="inputNumber" 
+		type="number" @blur="inputval" :disabled="disabled" 
+		:style="{
+			background:inputBG, height:inputHeight, lineHeight:inputHeight, 
+			fontSize:inputFontSize, color:inputColor, padding:inputPadding, 
+			borderRadius:inputBorderRadius}"></input>
 		<view class="grace-number-box-doBtn" @tap.stop="add" 
-		:style="{width:btnSize, height:btnSize, fontSize:btnFontSize, lineHeight:btnSize, color:btnColr}">+</view>
+		:style="{
+			width:btnSize, height:btnSize, fontSize:btnFontSize, 
+			lineHeight:btnSize, color:btnColr}">+</view>
 	</view>
 </template>
 <script>
@@ -95,7 +104,9 @@ export default {
 		value :function(val, vo){this.inputNumber = Number(val);},
 		inputNumber :function(val, vo){
 			val = Number(val);
-			if(isNaN(val)){ setTimeout(()=>{this.inputNumber = Number(vo);}, 200);  return; }
+			if(isNaN(val)){
+				setTimeout(()=>{this.inputNumber = Number(vo);}, 200);  return; 
+			}
 			if(val > this.maxNum){
 				this.$emit('change', [this.maxNum, this.index, this.datas]);
 				setTimeout(()=>{this.inputNumber = this.maxNum;}, 200);
@@ -119,6 +130,9 @@ export default {
 			var newVal = Number(this.inputNumber) - Number(this.step);
 			if(newVal < this.minNum){return ;}
 			this.inputNumber = newVal;
+		},
+		inputval:function (e) {
+			this.inputNumber = e.detail.value;
 		}
 	}
 }

+ 47 - 43
lib/graceUI/components/graceNumberKeyboard.vue

@@ -1,8 +1,8 @@
 <template>
-	<view>
-		<view class="grace-mask" @tap.stop="done" @touchmove.stop="" v-if="show"></view>
+	<view>
+		<view class="grace-mask" @tap.stop="masktap" @touchmove.stop.prevent="" v-if="show"></view>
 		<view class="grace-keyboard" v-if="show">
-			<view class="grace-keyboard-res" v-if="showInputRes" 
+			<view class="grace-keyboard-res" v-if="showInputRes" 
 			:style="{color:resultColor, fontSize:resultSize}">{{resVal}}</view>
 			<view class="grace-keyboard-body">
 				<view class="grace-keyboard-left">
@@ -20,54 +20,58 @@
 				<view class="grace-keyboard-right">
 					<view class="grace-keyboard-keys grace-keyboard-delete grace-icons" 
 					hover-class="keydown" hover-stay-time="100" @tap.stop="deleteNow"></view>
-					<view class="grace-keyboard-keys grace-keyboard-done" @tap.stop="done" 
+					<view class="grace-keyboard-keys grace-keyboard-done" @tap.stop="done" 
 					:style="{background:confirmBtnColor}">{{doneBtnName}}</view>
 				</view>
 			</view>
-		</view>
+		</view>
 	</view>
 </template>
-<script>
-export default {
-	props: {
-		show : { type : Boolean, default : false },
-		doneBtnName   : { type : String, default : "完成" },
-		isPoint       : { type : Boolean, default : true },
-		showInputRes  : {type : Boolean, default : true},
-		value         : {type:String, default:''},
-		confirmBtnColor:{type:String, default:'#3688FF'},
-		resultColor   : {type:String, default:'#323232'},
-		resultSize    : {type:String, default:'32rpx'}
-	},
-	data() {
-		return {
-			resVal: ''
-		}
-	},
-	created:function(){
-		this.resVal = this.value;
-	},
-	methods: {
-		inputNow : function (e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.resVal += k+'';
-			this.$emit('keyboardInput', k);
-		},
-		deleteNow : function (e){
-			this.resVal = this.resVal.substring(0, this.resVal.length - 1);
-			this.$emit('keyboardDelete');
-		},
+<script>
+export default {
+	props: {
+		show : { type : Boolean, default : false },
+		doneBtnName   : { type : String, default : "完成" },
+		isPoint       : { type : Boolean, default : true },
+		showInputRes  : {type : Boolean, default : true},
+		value         : {type:String, default:''},
+		confirmBtnColor:{type:String, default:'#3688FF'},
+		resultColor   : {type:String, default:'#323232'},
+		resultSize    : {type:String, default:'32rpx'},
+		closeByShade  : {type:Boolean, default:true}
+	},
+	data() {
+		return {
+			resVal: ''
+		}
+	},
+	created:function(){
+		this.resVal = this.value+'';
+	},
+	methods: {
+		inputNow : function (e){
+			var k = e.currentTarget.dataset.keynumber;
+			this.resVal += k+'';
+			this.$emit('keyboardInput', k);
+		},
+		deleteNow : function (e){
+			this.resVal = this.resVal.substring(0, this.resVal.length - 1);
+			this.$emit('keyboardDelete');
+		},
 		done : function(e){
-			console.log('ok');
-			this.$emit('keyboardDone');
-		},
-		setVal : function (val) {
-			this.resVal = val;
-		}
-	}
+			this.$emit('keyboardDone');
+		},
+		setVal : function (val) {
+			this.resVal = val;
+		},
+		masktap : function(){
+			if(!this.closeByShade){return ;}
+			this.done();
+		}
+	}
 }
 </script>
-<style scoped>
+<style scoped>
 .grace-mask{background:rgba(255, 255, 255, 0); position:fixed; width:100%; height:100%; left:0; top:0; z-index:1;}
 .grace-keyboard{background:#F4F5F6; position:fixed; width:100%; height:auto; left:0; bottom:0; z-index:3;}
 .grace-keyboard-body{display:flex; flex-direction:row; justify-content:space-between; padding:10px 0;}

+ 16 - 9
lib/graceUI/components/graceNvueActionSheet.vue

@@ -1,24 +1,30 @@
 <template>
 	<view class="">
-	<view class="graceActionSheet" @tap.stop="closeByShade" @touchmove.stop="stopFun" 
+	<view class="graceActionSheet" @tap.stop="closeByShade" @touchmove.stop.prevent="stopFun" 
 	:style="{backgroundColor:background}" v-if="realShow"></view>
 	<view :class="['graceActionSheetBody', isIpx ? 'grace-ipx-bottom' : '']"
-	:style="{width:realShow ? width : '0rpx',left:left,borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius}" 
+	:style="{
+		width:realShow ? width : '0rpx',left:left,
+		borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius}" 
 	@tap.stop="stopFun" v-if="realShow">
 		<text class="graceActionSheetTitle border-bottom" :style="{color:titleColor}">{{title}}</text>
-		<text class="graceActionSheetList border-bottom" v-for="(item, index) in items" :key="index" @tap.stop="selected" :data-index="index" 
-		:style="{color:listColor, lineHeight:listLineHeight, fontSize:listFontSize}">{{item}}</text>
-		<text class="graceActionSheetList" :style="{border:'none', color:cancelBtnColor}" @tap.stop="cancel">{{cancelBtnName}}</text>
+		<scroll-view scroll-y="true" :style="{height:height}">
+			<text class="graceActionSheetList border-bottom" 
+			v-for="(item, index) in items" :key="index" @tap.stop="selected" :data-index="index"
+			:style="{color:listColor, lineHeight:listLineHeight, fontSize:listFontSize}">{{item}}</text>
+		</scroll-view>
+		<text class="graceActionSheetList" v-if="isCancelBtn" :style="{border:'none', color:cancelBtnColor}" @tap.stop="cancel">{{cancelBtnName}}</text>
 	</view>
 	</view>
 </template>
 <script>
 export default {
-	props: {
-		width:{type:String,default:'720rpx'},
+	props: {
+		width:{type:String,default:'720rpx'},
+		height:{type:String,default:'500rpx'},
 		left:{type:String,default:'15rpx'},
-		background:{type : String,default : 'rgba(0, 0, 0, 0.3)'},
-		borderRadius : {type : String,default : '10rpx'},
+		background:{type : String,default : 'rgba(0, 0, 0, 0.3)'},
+		borderRadius : {type : String,default : '10rpx'},
 		zIndex:{type : Number,default : 99},
 		title:{type:String,default:''},
 		titleColor:{type:String, default:'#323232'},
@@ -26,6 +32,7 @@ export default {
 		listColor:{type:String, default:'#3688FF'},
 		listLineHeight:{type:String, default:'100rpx'},
 		listFontSize:{type:String, default:'30rpx'},
+		isCancelBtn:{type:Boolean, default:true},
 		cancelBtnName:{type:String,default:'取消'},
 		cancelBtnColor:{type:String, default:'#999999'}
 	},

+ 2 - 2
lib/graceUI/components/graceNvueAddressPicker.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="gap" v-if="show" @touchmove.stop="" @tap.stop="" :style="{backgroundColor:background}">
+	<view class="gap" v-if="show" @touchmove.stop.prevent="" @tap.stop="" :style="{backgroundColor:background}">
 		<view class="gap-body">
 			<view class="gap-header grace-space-between">
 				<text class="gap-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
@@ -115,4 +115,4 @@ export default {
 .gap-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
 .gap-main{width:750rpx; height:280px;}
 .gap-item{height:35px; font-size:12px; line-height:35px; overflow:hidden; text-align:center;}
-</style>
+</style>

+ 40 - 40
lib/graceUI/components/graceNvueBottomDialog.vue

@@ -1,44 +1,44 @@
-<template>
-	<view class="grace-btdialog-shade" v-if="show" @tap.stop="closeDialog" @touchmove.stop="stopFun" :style="{backgroundColor:background}">
+<template>
+	<view class="grace-btdialog-shade" v-if="show" @tap.stop="closeDialog" @touchmove.stop.prevent="stopFun" :style="{backgroundColor:background}">
 		<view class="grace-btdialog-shade-dialog" @tap.stop="stopFun" 
-		:style="{borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius,width:width,left:left}">
-			<view class="title"><slot name="btns"></slot></view>
-			<view class="content" @tap.stop="stopFun"><slot name="content"></slot></view>
-		</view>
-	</view>
-</template>
-<script>
-export default {
+		:style="{borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius,width:width,left:left}">
+			<view class="title"><slot name="btns"></slot></view>
+			<view class="content" @tap.stop="stopFun"><slot name="content"></slot></view>
+		</view>
+	</view>
+</template>
+<script>
+export default {
 	props: {
 		width:{type:String,default:'750rpx'},
-		left:{type:String,default:'0rpx'},
-		show : {
-			type : Boolean,
-			default : false
-		},
-		background:{
-			type : String,
-			default : 'rgba(0, 0, 0, 0.5)'
-		},
-		borderRadius : {
-			type : String,
-			default : '0rpx'
-		}
-	},
-	data() {
-		return {}
-	},
-	methods:{
-		closeDialog : function(){
-			this.$emit('closeDialog');
-		},
-		stopFun : function(){}
-	}
-}
-</script>
-<style scoped>
-.grace-btdialog-shade{position:fixed; width:750rpx; left:0; top:0; bottom:0; background-color:rgba(0, 0, 0, 0.5);}
-.grace-btdialog-shade-dialog{width:750rpx; background-color:#FFFFFF; position:absolute; bottom:0; left:0;}
-.grace-btdialog-shade-title{flex-direction:row; flex-wrap:nowrap; justify-content:space-between;}
-.grace-btdialog-shade-content{}
+		left:{type:String,default:'0rpx'},
+		show : {
+			type : Boolean,
+			default : false
+		},
+		background:{
+			type : String,
+			default : 'rgba(0, 0, 0, 0.5)'
+		},
+		borderRadius : {
+			type : String,
+			default : '0rpx'
+		}
+	},
+	data() {
+		return {}
+	},
+	methods:{
+		closeDialog : function(){
+			this.$emit('closeDialog');
+		},
+		stopFun : function(){}
+	}
+}
+</script>
+<style scoped>
+.grace-btdialog-shade{position:fixed; width:750rpx; left:0; top:0; bottom:0; background-color:rgba(0, 0, 0, 0.5);}
+.grace-btdialog-shade-dialog{width:750rpx; background-color:#FFFFFF; position:absolute; bottom:0; left:0;}
+.grace-btdialog-shade-title{flex-direction:row; flex-wrap:nowrap; justify-content:space-between;}
+.grace-btdialog-shade-content{}
 </style>

+ 1 - 1
lib/graceUI/components/graceNvueDate.vue

@@ -1,5 +1,5 @@
 <template name="graceDate">
-	<view class="grace-date" v-if="show" :style="{top:top}" @tap.stop="" @touchmove.stop="">
+	<view class="grace-date" v-if="show" :style="{top:top}" @tap.stop="" @touchmove.stop.prevent="">
 		<view class="grace-date-header">
 			<text class="grace-date-header-btn grace-icons" @click="prevYear">&#xe600;&#xe600;</text>
 			<text class="grace-date-header-btn grace-icons" @click="prevMonth">&#xe600;</text>

+ 75 - 75
lib/graceUI/components/graceNvueDateTime.vue

@@ -1,44 +1,44 @@
 <template>
 	<view>
 		<view @tap.stop="open"><slot></slot></view>
-		<view class="graceDateTime" @touchmove.stop="" @tap.self="close" :style="{backgroundColor:background, width:show ? '750rpx' : '0px'}"></view>
-		<view class="graceDateTime-body" :style="{bottom : show ? '0px' : '-1000px', paddingBottom:paddingBottom}">
-			<view class="graceDateTime-header grace-space-between" v-if="isHeaderBar">
-				<text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
-				<text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>
-			</view>
-			<picker-view :indicator-style="indicatorStyle" class="graceDateTime-main" 
-			:value="defaultVal" @change="change" :style="{height:height}">
-				<picker-view-column>
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[0]" :key="index">{{item}}{{units[0]}}</text>
-				</picker-view-column>
-				<picker-view-column>
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[1]" :key="index">{{item}}{{units[1]}}</text>
-				</picker-view-column>
-				<picker-view-column>
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[2]" :key="index">{{item}}{{units[2]}}</text>
-				</picker-view-column>
-				<picker-view-column v-if="isTime">
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[3]" :key="index">{{item}}{{units[3]}}</text>
-				</picker-view-column>
-				<picker-view-column v-if="isTime">
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[4]" :key="index">{{item}}{{units[4]}}</text>
-				</picker-view-column>
-				<picker-view-column  v-if="isTime && isSecond">
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[5]" :key="index">{{item}}{{units[5]}}</text>
-				</picker-view-column>
-			</picker-view>
+		<view class="graceDateTime" @touchmove.stop.prevent="" @tap.self="close" :style="{backgroundColor:background, width:show ? '750rpx' : '0px'}"></view>
+		<view class="graceDateTime-body" :style="{bottom : show ? '0px' : '-1000px', paddingBottom:paddingBottom}">
+			<view class="graceDateTime-header grace-space-between" v-if="isHeaderBar">
+				<text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
+				<text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>
+			</view>
+			<picker-view :indicator-style="indicatorStyle" class="graceDateTime-main" 
+			:value="defaultVal" @change="change" :style="{height:height}">
+				<picker-view-column>
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[0]" :key="index">{{item}}{{units[0]}}</text>
+				</picker-view-column>
+				<picker-view-column>
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[1]" :key="index">{{item}}{{units[1]}}</text>
+				</picker-view-column>
+				<picker-view-column>
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[2]" :key="index">{{item}}{{units[2]}}</text>
+				</picker-view-column>
+				<picker-view-column v-if="isTime">
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[3]" :key="index">{{item}}{{units[3]}}</text>
+				</picker-view-column>
+				<picker-view-column v-if="isTime">
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[4]" :key="index">{{item}}{{units[4]}}</text>
+				</picker-view-column>
+				<picker-view-column  v-if="isTime && isSecond">
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[5]" :key="index">{{item}}{{units[5]}}</text>
+				</picker-view-column>
+			</picker-view>
 		</view>
-	</view>
-</template>
-<script>
-export default {
-	props: {
-		background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' },
-		cancelText : { type : String, default : '取消' },
-		cancelTColor : { type : String, default : '#888888' },
-		confirmText : { type : String, default : '确定' },
-		confirmColor : { type : String, default : '#3688FF' },
+	</view>
+</template>
+<script>
+export default {
+	props: {
+		background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' },
+		cancelText : { type : String, default : '取消' },
+		cancelTColor : { type : String, default : '#888888' },
+		confirmText : { type : String, default : '确定' },
+		confirmColor : { type : String, default : '#3688FF' },
 		value : { type : String , default:''},
 		isTime : {type : Boolean, default : true},
 		isSecond : {type : Boolean, default : true},
@@ -46,21 +46,21 @@ export default {
 		endYear : {type : Number, default : 2050},
 		units : {type : Array , default:function(){return new Array('年','月','日','时','分','秒')}},
 		height:{ type : String, default : '300rpx' },
-		isHeaderBar : {type : Boolean, default : true},
-		paddingBottom :{ type : String, default : '0rpx' }
-	},
-	data() {
+		isHeaderBar : {type : Boolean, default : true},
+		paddingBottom :{ type : String, default : '0rpx' }
+	},
+	data() {
 		return {
-			show:false,
-			indicatorStyle : 'height:35px',
+			show:false,
+			indicatorStyle : 'height:35px',
 			defaultVal     : [0,0,0,0,0,0],
-			sDate:[[],[],[],[],[],[]],
-			timer:null
-		}
-	},
-	created() {
-		this.init();
-	},
+			sDate:[[],[],[],[],[],[]],
+			timer:null
+		}
+	},
+	created() {
+		this.init();
+	},
 	methods: {
 		now : function () {
 			var date = new Date();
@@ -125,17 +125,17 @@ export default {
 			}
 			this.sDate = [years, months, days, hours, minutes, seconds];
 			this.$nextTick(()=>{setTimeout(()=>{ this.setValue(this.value);},300);});
-		},
-		change : function (res) {
-			if(this.timer != null){clearTimeout(this.timer);}
-			this.timer = setTimeout(()=>{this.changeBase(res.detail.value);},500);
+		},
+		change : function (res) {
+			if(this.timer != null){clearTimeout(this.timer);}
+			this.timer = setTimeout(()=>{this.changeBase(res.detail.value);},500);
 		},
 		changeBase:function(res){
 			var date = new Date(this.sDate[0][res[0]], this.sDate[1][res[1]], 0);
 			var days = date.getDate();
 			var daysOut = new Array();
 			for(let i = 1; i <= days; i++){if(i < 10){daysOut.push('0'+i);}else{daysOut.push(i);}}
-			this.sDate.splice(2, 1, daysOut);
+			this.sDate.splice(2, 1, daysOut);
 			if(res[2] + 1 > days){res[2] = days - 1;}
 			this.defaultVal = res;
 			if(this.isTime){
@@ -146,14 +146,14 @@ export default {
 				this.sDate[4][this.defaultVal[4]],
 				this.sDate[5][this.defaultVal[5]]);
 			}else{
-				var resdata = new Array(
+				var resdata = new Array(
 					this.sDate[0][this.defaultVal[0]],
 					this.sDate[1][this.defaultVal[1]],
-					this.sDate[2][this.defaultVal[2]]
+					this.sDate[2][this.defaultVal[2]]
 				)
 			}
 			this.$emit('change', resdata);
-		},
+		},
 		confirm:function () {
 			if(this.isTime){
 				var res = new Array(this.sDate[0][this.defaultVal[0]],
@@ -168,22 +168,22 @@ export default {
 				this.sDate[2][this.defaultVal[2]])
 			}
 			this.$emit('confirm', res);
-			this.show = false;
+			this.show = false;
+		},
+		open : function () {
+			this.show = true;
 		},
-		open : function () {
-			this.show = true;
-		},
-		close : function () {
-			this.show = false;
-		}
-	}
-}
-</script>
-<style scoped>
-.graceDateTime{position:fixed; top:0; left:0; bottom:0; width:0rpx; flex:1;}
-.graceDateTime-body{background-color:#FFFFFF; position:fixed; bottom:-1000px; left:0; width:750rpx;}
-.graceDateTime-header{padding:25rpx;}
-.graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
-.graceDateTime-main{width:750rpx;}
-.graceDateTime-item{height:35px; font-size:28rpx; line-height:35px; overflow:hidden; text-align:center;}
+		close : function () {
+			this.show = false;
+		}
+	}
+}
+</script>
+<style scoped>
+.graceDateTime{position:fixed; top:0; left:0; bottom:0; width:0rpx; flex:1;}
+.graceDateTime-body{background-color:#FFFFFF; position:fixed; bottom:-1000px; left:0; width:750rpx;}
+.graceDateTime-header{padding:25rpx;}
+.graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
+.graceDateTime-main{width:750rpx;}
+.graceDateTime-item{height:35px; font-size:28rpx; line-height:35px; overflow:hidden; text-align:center;}
 </style>

+ 1 - 1
lib/graceUI/components/graceNvueDialog.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="grace-dialog-shade" v-if="show" @tap.stop="closeDialogByShade" @touchmove.stop="stopFun" :style="{backgroundColor:background}">
+	<view class="grace-dialog-shade" v-if="show" @tap.stop="closeDialogByShade" @touchmove.stop.prevent="stopFun" :style="{backgroundColor:background}">
 		<view class="grace-dialog gdFadeIn" @tap.stop="stopFun" :style="{width:width, borderRadius:borderRadius}">
 			<text class="grace-dialog-title" v-if="isTitle" 
 			:style="{fontSize:titleSize, color:titleColor,fontWeight:titleWeight?'900':'',backgroundColor:titleBg, lineHeight:titleHeight}">{{title}}</text>

+ 9 - 9
lib/graceUI/components/graceNvueDrawer.vue

@@ -1,6 +1,6 @@
 <template>
 	<view>
-		<view class="grace-drawer-shade" v-if="show" @click.stop="closeDrawer" @touchmove.stop="" :style="{backgroundColor:background}"></view>
+		<view class="grace-drawer-shade" v-if="show" @click.stop="closeDrawer" @touchmove.stop.prevent="" :style="{backgroundColor:background}"></view>
 		<view ref="graceDrawerMenu" v-if="show" class="grace-drawer-nav" @tap.stop="stopFun" 
 		:style="{width:width+'rpx', left : direction == 'left' ? (width*-1)+'rpx' : 'none', top : top+'px', 
 			right : direction == 'right' ? (width*-1)+'rpx' : 'none', 
@@ -24,10 +24,10 @@ export default {
 		direction : {
 			type : String,
 			default : 'left'
-		},
-		background:{
-			type : String,
-			default : 'rgba(0, 0, 0, 0.5)'
+		},
+		background:{
+			type : String,
+			default : 'rgba(0, 0, 0, 0.5)'
 		},
 		slotBg:{
 			type : String,
@@ -36,11 +36,11 @@ export default {
 		padding : {
 			type : String,
 			default : '30rpx'
-		},
+		},
 		top:{type:Number, value:0}
 	},
 	updated:function(){
-		if(this.show){
+		if(this.show){
 			setTimeout(()=>{
 				var moveX = this.direction == 'left' ? uni.upx2px(this.width) + 'px' : (uni.upx2px(this.width) * -1) + 'px';
 				var animation = weex.requireModule('animation');
@@ -51,8 +51,8 @@ export default {
 					needLayout:false,
 					delay: 0 
 					}, function (){}
-				);
-			}, 100);
+				);
+			}, 100);
 		}
 	},
 	methods:{

+ 24 - 17
lib/graceUI/components/graceNvueFullLoading.vue

@@ -1,5 +1,8 @@
 <template>
-	<view class="grace-full-loading" v-if="graceFullLoading" :style="{backgroundColor:background}" @tap.stop="" @touchmove.stop="">
+	<view class="grace-full-loading" v-if="graceFullLoading" @tap.stop="" @touchmove.stop.prevent="" 
+	:style="{
+		backgroundColor:background, left:graceFullLoading?'0px':'-1000px',
+		opacity:graceFullLoading?1:0}">
 		<image class="grace-full-loading-image" ref="loadingLogos" :src="logoUrl" mode="widthFix" :style="{width:size, height:size}"></image>
 		<text class="grace-full-loading-text" :style="{color:textColor, fontSize:fontSize}">{{text}}</text>
 	</view>
@@ -20,32 +23,33 @@ export default {
 		text : {
 			type    : String,
 			default : "Loading ..."
-		},
-		fontSize : {
-			type    : String,
-			default : "22rpx"
+		},
+		fontSize : {
+			type    : String,
+			default : "22rpx"
 		},
 		textColor : {
 			type    : String,
 			default : "#999999"
-		},
-		size : {
-			type    : String,
-			default : "138rpx"
-		},
-		background : {
-			type    : String,
-			default : 'rgba(255,255,255,1)'
+		},
+		size : {
+			type    : String,
+			default : "138rpx"
+		},
+		background : {
+			type    : String,
+			default : 'rgba(255,255,255,1)'
 		}
 	},
-	updated : function(){
+	updated : function(){
 		setTimeout(()=>{
 			var loadingLogos = this.$refs.loadingLogos;
-			this.animation1(loadingLogos);
+			this.animation1(loadingLogos);
 		}, 200);
 	},
 	methods: {
 		animation1 : function(loadingLogos){
+			if(!this.graceFullLoading){return ;}
 			var _self = this;
 			animation.transition(loadingLogos, {
 				styles: { opacity:0.3},
@@ -53,9 +57,12 @@ export default {
 				timingFunction: 'linear',
 				needLayout:false,
 				delay: 0 
-			}, function (){_self.animation2(loadingLogos);});
+			}, function (){
+				_self.animation2(loadingLogos);
+			});
 		},
 		animation2 : function(loadingLogos){
+			if(!this.graceFullLoading){return ;}
 			var _self = this;
 			animation.transition(loadingLogos, {
 				styles: { opacity: 1},
@@ -70,7 +77,7 @@ export default {
 }
 </script>
 <style scoped>
-.grace-full-loading{width:750rpx; justify-content:center; align-items:center; background-color:rgba(255,255,255,0.9); position:fixed; left:0; top:0; bottom:0;}
+.grace-full-loading{width:750rpx; justify-content:center; align-items:center; background-color:rgba(255,255,255,0.9); position:fixed; top:0; bottom:0;}
 .grace-full-loading-image{width:150rpx; height:150rpx; border-radius:150rpx;}
 .grace-full-loading-text{line-height:50rpx; font-size:22rpx; margin-top:10rpx; text-align:center;}
 </style>

+ 45 - 19
lib/graceUI/components/graceNvueHeaderAlert.vue

@@ -1,47 +1,73 @@
 <template>
-	<view class="grace-alert" v-if="showIn">
-		<view class="grace-alert-body" :style="{'background-color':background}"  ref="gracealert">
+	<view class="grace-alert" v-if="showIn" :style="{top : topReal + 'px'}">
+		<view class="grace-alert-body" ref="gracealert" 
+		:style="{'background-color':background, width:width+'rpx'}">
 			<slot></slot>
 		</view>
 	</view>
 </template>
 <script>
-var animation = weex.requireModule('animation');
 export default {
 	name: "graceHeaderAlert",
 	props: {
-		show    : {
-			type : Boolean,
-			default : false
-		},
-		background : {
-			type : String,
-			default : '#F1F2F3'
-		}
+		show       : { type : Boolean, default : false },
+		background : { type : String, default : '#F1F2F3' },
+		top        : { type : Number, default : 20 },
+		width      : { type : Number, default : 580},
+		duration   : { type : Number, default : 2500}
 	},
 	data() {
 		return {
-			showIn : false
+			showIn : false,
+			topReal : 0
 		}
 	},
+	created:function(){
+		this.topReal = this.top;
+		this.showIn  = this.show;
+	},
 	watch: {
 		show : function(n , o){
+			if(n){
+				this.showIn = n;
+				this.animation();
+			}
+		}
+	},
+	methods:{
+		open:function(){
 			this.showIn = true;
-			setTimeout(() => {
+			this.animation();
+		},
+		close:function(){
+			this.showIn = false;
+		},
+		animation : function(){
+			setTimeout(()=>{
+				var animation = weex.requireModule('animation');
 				animation.transition(this.$refs.gracealert, {
-					styles         : {opacity:1},
-					duration       : 50, 
+					styles         : {opacity:0, transform:'scale(0.1,0.1)'},
+					duration       : 1, 
 					timingFunction : 'linear',
 					needLayout     : false,
-					delay          : 0 
+					delay          : 0 ,
+				}, ()=>{
+					animation.transition(this.$refs.gracealert, {
+						styles         : {opacity:1, transform:'scale(1,1)'},
+						duration       : 150, 
+						timingFunction : 'linear',
+						needLayout     : false,
+						delay          : 0 ,
+					});
 				});
-			}, 100);
-			setTimeout(function(){this.showIn = false;}.bind(this), 3000);
+			}, 200);
+			setTimeout(()=>{this.showIn = false;}, this.duration);
 		}
 	}
+	
 }
 </script>
 <style scoped>
 .grace-alert{width:750rpx; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center;  position:fixed; left:0rpx; top:20rpx;}
-.grace-alert-body{width:600rpx; padding:20rpx 25rpx; border-radius:10rpx; background-color:#FFFFFF; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; opacity:0.1;}
+.grace-alert-body{padding:25rpx; border-radius:10rpx; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; opacity:0;}
 </style>

+ 1 - 1
lib/graceUI/components/graceNvueNavBar.vue

@@ -1,5 +1,5 @@
 <template>
-	<scroll-view
+	<scroll-view scroll-with-animation 
 	:class="['grace-nav-bar', isCenter ? 'grace-nav-center' : '']" :scroll-x="true" 
 	:scroll-into-view="'tab-'+currentIndex" :show-scrollbar="false">
 		<view class="nav-item" :id="'tab-'+index" 

+ 1 - 1
lib/graceUI/components/graceNvueNavBar2.vue

@@ -1,5 +1,5 @@
 <template>
-	<scroll-view
+	<scroll-view scroll-with-animation 
 	:class="['grace-nav-bar2', isCenter ? 'grace-nav2-center' : '']" :scroll-x="true" :show-scrollbar="false" 
 	:scroll-into-view="'tab-'+currentIndex">
 		<view class="nav2-item" :id="'tab-'+index" :style="{width:size+'rpx', height:(lineHeight+lineHeightSamll+18)+'rpx'}" 

+ 12 - 3
lib/graceUI/components/graceNvueNumberBox.vue

@@ -1,9 +1,15 @@
 <template>
 	<view class="grace-number-box" :style="{width:width}">
 		<text class="grace-number-box-doBtn" @tap.stop="reduce" 
-		:style="{width:btnSize, height:btnSize, fontSize:btnFontSize, lineHeight:btnSize, color:btnColr}">-</text>
-		<input class="grace-number-box-input" type="number" v-model="inputNumber" :disabled="disabled" 
-		:style="{backgroundColor:inputBG, height:inputHeight, lineHeight:inputHeight, fontSize:inputFontSize, color:inputColor, padding:inputPadding, borderRadius:inputBorderRadius}"></input>
+		:style="{
+			width:btnSize, height:btnSize, fontSize:btnFontSize, 
+			lineHeight:btnSize, color:btnColr}">-</text>
+		<input class="grace-number-box-input" type="number" 
+		:value="inputNumber" :disabled="disabled"  @blur="inputval" 
+		:style="{
+			backgroundColor:inputBG, height:inputHeight, lineHeight:inputHeight, 
+			fontSize:inputFontSize, color:inputColor, padding:inputPadding, 
+			borderRadius:inputBorderRadius}"></input>
 		<text class="grace-number-box-doBtn" @tap.stop="add" 
 		:style="{width:btnSize, height:btnSize, fontSize:btnFontSize, lineHeight:btnSize, color:btnColr}">+</text>
 	</view>
@@ -119,6 +125,9 @@ export default {
 			var newVal = Number(this.inputNumber) - Number(this.step);
 			if(newVal < this.minNum){return ;}
 			this.inputNumber = newVal;
+		},
+		inputval:function (e) {
+			this.inputNumber = e.detail.value;
 		}
 	}
 }

+ 84 - 80
lib/graceUI/components/graceNvueNumberKeyboard.vue

@@ -1,87 +1,91 @@
 <template>
-	<view>
-		<view class="grace-mask" @tap.stop="done" @touchmove.stop="" v-if="show"></view>
-		<view class="grace-keyboard" v-if="show">
-			<text class="grace-keyboard-res" v-if="showInputRes" 
-			:style="{color:resultColor, fontSize:resultSize}">{{resVal}}</text>
-			<view class="grace-keyboard-body">
-				<view class="grace-keyboard-left">
-					<text v-for="(item, index) in [1,2,3,4,5,6,7,8,9]" :key="index" 
-					class="grace-keyboard-keys" :class="[tapIndex == item ? 'keydown' : '']" :data-keynumber="item" @tap.stop="inputNow">{{item}}</text>
-					<text class="grace-keyboard-keys" :class="[tapIndex == 0 ? 'keydown' : '']" 
-					:style="{width: isPoint ? '259rpx':'538rpx'}" data-keynumber="0" @tap.stop="inputNow">0</text>
-					<text v-if="isPoint" class="grace-keyboard-keys" style="width:259rpx;" 
-					:class="[tapIndex == '.' ? 'keydown' : '']" data-keynumber="." @tap.stop="inputNow">.</text>
-				</view>
-				<view class="grace-keyboard-right">
-					<text class="grace-keyboard-keys grace-icons" 
-					:class="[tapIndex == -3 ? 'keydown' : '']" :data-keynumber="-3" @tap.stop="deleteNow">&#xe623;</text>
-					<text class="grace-keyboard-keys grace-keyboard-done" 
-					:style="{backgroundColor:confirmBtnColor}" @tap.stop="done">{{doneBtnName}}</text>
-				</view>
-			</view>
-		</view>
+	<view>
+		<view class="grace-mask" @tap.stop="masktap" @touchmove.stop.prevent="" v-if="show"></view>
+		<view class="grace-keyboard" v-if="show">
+			<text class="grace-keyboard-res" v-if="showInputRes" 
+			:style="{color:resultColor, fontSize:resultSize}">{{resVal}}</text>
+			<view class="grace-keyboard-body">
+				<view class="grace-keyboard-left">
+					<text v-for="(item, index) in [1,2,3,4,5,6,7,8,9]" :key="index" 
+					class="grace-keyboard-keys" :class="[tapIndex == item ? 'keydown' : '']" :data-keynumber="item" @tap.stop="inputNow">{{item}}</text>
+					<text class="grace-keyboard-keys" :class="[tapIndex == 0 ? 'keydown' : '']" 
+					:style="{width: isPoint ? '259rpx':'538rpx'}" data-keynumber="0" @tap.stop="inputNow">0</text>
+					<text v-if="isPoint" class="grace-keyboard-keys" style="width:259rpx;" 
+					:class="[tapIndex == '.' ? 'keydown' : '']" data-keynumber="." @tap.stop="inputNow">.</text>
+				</view>
+				<view class="grace-keyboard-right">
+					<text class="grace-keyboard-keys grace-icons" 
+					:class="[tapIndex == -3 ? 'keydown' : '']" :data-keynumber="-3" @tap.stop="deleteNow">&#xe623;</text>
+					<text class="grace-keyboard-keys grace-keyboard-done" 
+					:style="{backgroundColor:confirmBtnColor}" @tap.stop="done">{{doneBtnName}}</text>
+				</view>
+			</view>
+		</view>
 	</view>
 </template>
-<script>
-export default {
-	props: {
-		show         : { type : Boolean, default : false },
-		doneBtnName  : { type : String, default : "完成" },
-		isPoint      : { type : Boolean, default : true },
-		showInputRes : {type : Boolean, default : true},
-		value        : {type:String, default:''},
-		confirmBtnColor : {type:String, default:'#3688FF'},
-		resultColor  : {type:String, default:'#323232'},
-		resultSize   : {type:String, default:'32rpx'}
-	},
-	data() {
-		return {
-			resVal: '',
-			tapIndex : -1
-		}
-	},
-	created:function(){
-		this.resVal = this.value;
-	},
-	methods: {
-		inputNow : function (e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.resVal += k+'';
-			this.tapIndex = k;
-			this.$emit('keyboardInput', k);
-			this.removeClass();
-		},
-		deleteNow : function (e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.tapIndex = k;
-			this.resVal = this.resVal.substring(0, this.resVal.length - 1);
-			this.$emit('keyboardDelete');
-			this.removeClass();
-		},
-		done : function(e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.tapIndex = k;
-			this.$emit('keyboardDone');
-			this.removeClass();
-		},
-		setVal : function (val) {
-			this.resVal = val;
-		},
-		removeClass : function () {
-			setTimeout(()=>{this.tapIndex = -1;}, 200);
-		}
-	}
+<script>
+export default {
+	props: {
+		show         : { type : Boolean, default : false },
+		doneBtnName  : { type : String, default : "完成" },
+		isPoint      : { type : Boolean, default : true },
+		showInputRes : {type : Boolean, default : true},
+		value        : {type:String, default:''},
+		confirmBtnColor : {type:String, default:'#3688FF'},
+		resultColor  : {type:String, default:'#323232'},
+		resultSize   : {type:String, default:'32rpx'},
+		closeByShade  : {type:Boolean, default:true}
+	},
+	data() {
+		return {
+			resVal: '',
+			tapIndex : -1
+		}
+	},
+	created:function(){
+		this.resVal = this.value+'';
+	},
+	methods: {
+		inputNow : function (e){
+			var k = e.currentTarget.dataset.keynumber;
+			this.resVal += k+'';
+			this.tapIndex = k;
+			this.$emit('keyboardInput', k);
+			this.removeClass();
+		},
+		deleteNow : function (e){
+			var k = e.currentTarget.dataset.keynumber;
+			this.tapIndex = k;
+			this.resVal = this.resVal.substring(0, this.resVal.length - 1);
+			this.$emit('keyboardDelete');
+			this.removeClass();
+		},
+		done : function(){
+			this.tapIndex = -3;
+			this.$emit('keyboardDone');
+			this.removeClass();
+		},
+		setVal : function (val) {
+			this.resVal = val;
+		},
+		removeClass : function () {
+			setTimeout(()=>{this.tapIndex = -1;}, 200);
+		},
+		masktap : function(){
+			if(!this.closeByShade){return ;}
+			this.done();
+		}
+	}
 }
 </script>
-<style scoped>
-.grace-mask{background-color:rgba(255, 255, 255, 0); position:fixed; width:750rpx; flex:1; left:0; top:0; bottom:0;}
-.grace-keyboard{background-color:#F4F5F6; position:fixed; width:750rpx; left:0; bottom:0;}
-.grace-keyboard-body{flex-direction:row; justify-content:space-between; padding:10px 0;}
-.grace-keyboard-left{width:560rpx; flex-direction:row; flex-wrap:wrap; justify-content:space-between;}
-.grace-keyboard-right{width:188rpx; flex-direction:column; justify-content:space-between;}
-.grace-keyboard-keys{width:166rpx; height:100rpx; margin:10rpx; background-color:#FFFFFF; text-align:center; line-height:100rpx; border-radius:8rpx; font-weight:700; font-size:50rpx;}
-.grace-keyboard-done{height:340rpx; line-height:340rpx; font-size:36rpx; font-weight:400; color:#FFFFFF;}
-.grace-keyboard-res{line-height:60rpx; text-align:center; font-size:32rpx; font-weight:bold; padding-top:20rpx;}
+<style scoped>
+.grace-mask{background-color:rgba(255, 255, 255, 0); position:fixed; width:750rpx; flex:1; left:0; top:0; bottom:0;}
+.grace-keyboard{background-color:#F4F5F6; position:fixed; width:750rpx; left:0; bottom:0;}
+.grace-keyboard-body{flex-direction:row; justify-content:space-between; padding:10px 0;}
+.grace-keyboard-left{width:560rpx; flex-direction:row; flex-wrap:wrap; justify-content:space-between;}
+.grace-keyboard-right{width:188rpx; flex-direction:column; justify-content:space-between;}
+.grace-keyboard-keys{width:166rpx; height:100rpx; margin:10rpx; background-color:#FFFFFF; text-align:center; line-height:100rpx; border-radius:8rpx; font-weight:700; font-size:50rpx;}
+.grace-keyboard-done{height:340rpx; line-height:340rpx; font-size:36rpx; font-weight:400; color:#FFFFFF;}
+.grace-keyboard-res{line-height:60rpx; text-align:center; font-size:32rpx; font-weight:bold; padding-top:20rpx;}
 .keydown{background-color:#3688FF; color:#FFFFFF;}
 </style>

+ 70 - 0
lib/graceUI/components/graceNvuePK.vue

@@ -0,0 +1,70 @@
+<template>
+	<view class="grace-pk-wrap" :style="{height:height,borderRadius:borderRadius}">
+		<!-- 背景 -->
+		<image src="https://img-cdn-qiniu.dcloud.net.cn/uploads/article/20200806/24692285f85690abbc762512ce22d2c5.png" 
+		class="grace-pk-bg" style="width:700rpx; height:466rpx;"></image>
+		<!-- pk 图标 -->
+		<view class="grace-pk-icon-wrap" :style="{height:height,borderRadius:borderRadius}">
+			<view class="grace-pk-icon">
+				<image src="https://img-cdn-qiniu.dcloud.net.cn/uploads/article/20200806/84515c21a39e8382addbeca53462e3a0.png" 
+				mode="widthFix" style="width:80rpx; height:80rpx;"></image>
+			</view>
+		</view>
+		<view class="grace-pk" :style="{height:height,borderRadius:borderRadius}">
+			<view class="grace-pk-item">
+				<text class="grace-pk-title">{{title[0]}}</text>
+				<view class="grace-pk-btn-wrap" v-if="status == 'button'">
+					<text class="grace-pk-btn" hover-class="grace-pk-btn-hv" 
+					data-index="left" @tap="choose">{{btnName}}</text>
+				</view>
+				<view class="grace-pk-btn-wrap" v-if="status == 'progress'">
+					<progress :percent="progress[0]" activeColor="#FFFFFF" stroke-width="3" class="grace-pk-progress" backgroundColor="#3699ff" />
+				</view>
+				<text class="grace-pk-text" v-if="status == 'progress'">{{progress[2]}}</text>
+			</view>
+			<view class="grace-pk-item">
+				<text class="grace-pk-title" style="text-align:right;">{{title[1]}}</text>
+				<view class="grace-pk-btn-wrap" style="justify-content:flex-end;" v-if="status == 'button'">
+					<text class="grace-pk-btn" hover-class="grace-pk-btn-hv" 
+					style="color:#FF0036;" data-index="right" @tap="choose">{{btnName}}</text>
+				</view>
+				<view class="grace-pk-btn-wrap" style="justify-content:flex-end;" v-if="status == 'progress'">
+					<progress :percent="progress[1]" stroke-width="3" class="grace-pk-progress" 
+					activeColor="#FFFFFF" backgroundColor="#FF6666"/>
+				</view>
+				<text class="grace-pk-text" style="text-align:right;" v-if="status == 'progress'">{{progress[3]}}</text>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		height       : {type:String, default:'260rpx'},
+		borderRadius : {type:String, default:'8rpx'},
+		title        : {type:Array, default:function(){return ['',''];}},
+		btnName      : {type:String, default:'站队'},
+		status       : {type:String, default:'button'},
+		progress     : {type:Array, default:function(){return [80,20,'8000 票', '2000 票'];}}
+	},
+	methods:{
+		choose:function (e) {
+			this.$emit('choose', e.currentTarget.dataset.index);
+		}
+	}
+}
+</script>
+<style>
+.grace-pk-wrap{font-size:0; overflow:hidden;}
+.grace-pk-bg{width:700rpx; position:absolute; left:0; top:0;}
+.grace-pk{flex-direction:row; justify-content:space-between;}
+.grace-pk-item{width:100rpx; overflow:hidden; padding-left:35rpx; padding-right:35rpx; flex:1; flex-direction:column; justify-content:center;}
+.grace-pk-title{color:#FFFFFF; font-size:50rpx; line-height:60rpx;}
+.grace-pk-btn-wrap{flex-direction:row; margin-top:32rpx;}
+.grace-pk-btn{width:150rpx; height:50rpx; line-height:50rpx; text-align:center; background-color:#FFFFFF; font-size:22rpx; border-radius:100rpx; color:#3687FF;}
+.grace-pk-btn-hv{font-weight:bold;}
+.grace-pk-progress{width:200rpx;}
+.grace-pk-text{font-size:22rpx; color:#FFFFFF; line-height:50rpx; margin-top:2px;}
+.grace-pk-icon-wrap{width:700rpx; position:absolute; top:0px; left:0rpx; flex-direction:row; justify-content:center; align-items:center;}
+.grace-pk-icon{width:120rpx; height:120rpx; padding-top:20rpx; padding-bottom:20rpx; padding-left:20rpx; padding-right:20rpx; background-color:#FFFFFF; border-radius:100rpx; font-size:0;}
+</style>

+ 7 - 6
lib/graceUI/components/graceNvuePage.vue

@@ -14,7 +14,7 @@
 				<view class="gui-page-header-nav" ref="gracePageHeader">
 					<view class="gui-header-main gui-flex-auto">
 						<slot name="gHeader"></slot>
-					</view>
+					</view>
 				</view>
 			</view>
 		</view>
@@ -25,7 +25,7 @@
 		<!-- 右下角悬浮按钮 -->
 		<view class="gui-page-rb-area" :style="{right:rbRight+'rpx', bottom:rbBottom+'rpx', width:rbWidth+'rpx'}"><slot name="gRTArea"></slot></view>
 		<!-- 全屏 loading -->
-		<view class="grace-page-loading" @tap.stop="" @touchmove.stop="" :style="{backgroundColor:loadingBG}" v-if="isLoading">
+		<view class="grace-page-loading" @tap.stop="" @touchmove.stop.prevent="" :style="{backgroundColor:loadingBG}" v-if="isLoading">
 			<view class="grace-page-loading-point">
 				<view class="grace-page-loading-points" ref="loadingPoints1" :style="{background:loadingPointBg}"></view>
 				<view class="grace-page-loading-points" ref="loadingPoints2" :style="{background:loadingPointBg}"></view>
@@ -49,8 +49,8 @@ export default{
 		rbBottom     : { type : Number, default : 100 },
 		rbRight      : { type : Number, default : 20 },
 		footerBg     : { type : String, default : '' },
-		flexVal      : { type : String, default : ''},
-		borderWidth  : { type : String,  default : '0' },
+		flexVal      : { type : String, default : ''},
+		borderWidth  : { type : String,  default : '0' },
 		borderColor  : { type : String,  default : '#D1D1D1' },
 		loadingBG    : { type : String,  default : 'rgba(255,255,255, 0.1)'},
 		isLoading    :  { type : Boolean, default : false },
@@ -72,7 +72,7 @@ export default{
 	},
 	methods:{
 		ldAnimation : function(){
-			if(this.animateCount >= 10){return ;}
+			if(!this.isLoading){return ;}
 			this.animateCount++;
 			var animations1 = this.$refs.loadingPoints1;
 			var animations2 = this.$refs.loadingPoints2;
@@ -100,6 +100,7 @@ export default{
 			},() => {this.ldAnimation2();});
 		},
 		ldAnimation2 : function(){
+			if(!this.isLoading){return ;}
 			var animations1 = this.$refs.loadingPoints1;
 			var animations2 = this.$refs.loadingPoints2;
 			var animations3 = this.$refs.loadingPoints3;
@@ -126,7 +127,7 @@ export default{
 			},() => {this.ldAnimation();});
 		},
 		getHeaderHeight:function(){
-			return this.headerHeight + thi.statusBarHeight;
+			return this.headerHeight + this.statusBarHeight;
 		}
 	},
 	created:function(){

+ 60 - 44
lib/graceUI/components/graceNvuePopupMenu.vue

@@ -1,54 +1,70 @@
 <template name="gracePopupMenu">
-	<view>
-		<view 
-		class="grace-popup-mask" v-if="show" @tap.stop="hideMenu" @touchmove.stop="" 
-		:style="{backgroundColor:background}">
-			<view class="grace-popup-menu" v-if="show"
-			:style="{top:top+'px', right:right, backgroundColor:bgColor, width:menuWidth, borderRadius:borderRadius}">
-				<slot></slot>
-			</view>
+	<view  class="grace-popup-mask" v-if="showIn" @tap.stop="hideMenu" @touchmove.stop.prevent=""
+	:style="{backgroundColor:background}">
+		<view class="grace-popup-menu" 
+		:style="{top:top+'px', right:right, backgroundColor:bgColor, width:menuWidth, borderRadius:borderRadius}">
+			<slot></slot>
 		</view>
 	</view>
 </template>
 <script>
-	export default {
-		name: "gracePopupMenu",
-		props: {
-			show:{
-				type : Boolean,
-				default : false
-			},
-			top:{
-				type : Number,
-				default : 0
-			},
-			bgColor:{
-				type : String,
-				default :'#FFFFFF'
-			},
-			menuWidth :{
-				type : String,
-				default : '258rpx'
-			},
-			background : {
-				type : String,
-				default : 'rgba(0,0,0, 0.3)'
-			},
-			right:{
-				type : String,
-				default:'0rpx'
-			},
-			borderRadius:{
-				type : String,
-				default:'0rpx'
-			}
-		},
-		methods: {
-			hideMenu : function() {
-				this.$emit('hideMenu');
-			}
+export default {
+	name: "gracePopupMenu",
+	props: {
+		show:{
+			type : Boolean,
+			default : false
 		},
+		top:{
+			type : Number,
+			default : 0
+		},
+		bgColor:{
+			type : String,
+			default :'#FFFFFF'
+		},
+		menuWidth :{
+			type : String,
+			default : '258rpx'
+		},
+		background : {
+			type : String,
+			default : 'rgba(0,0,0, 0.3)'
+		},
+		right:{
+			type : String,
+			default:'0rpx'
+		},
+		borderRadius:{
+			type : String,
+			default:'0rpx'
+		}
+	},
+	data() {
+		return {
+			showIn : false
+		}
+	},
+	created:function(){
+		if(this.show){this.open();}else{this.hide();}
+	},
+	watch:{
+		show : function(val,oval){
+			this.showIn = val;
+		}
+	},
+	methods: {
+		hideMenu : function() {
+			this.$emit('hideMenu');
+		},
+		open : function(){
+			this.showIn = true;
+		},
+		hide:function(){
+			this.showIn = false;
+		}
 	}
+}
 </script>
 <style scoped>
 .grace-popup-menu{background-color:#FFFFFF; width:258rpx; padding:10rpx; right:0px; top:0px; position:absolute;}

+ 2 - 2
lib/graceUI/components/graceNvueReload.vue

@@ -6,7 +6,7 @@
 			<text class="grace-reload-icon grace-icons" v-if="reloadStatus == 2" :style="{color:reloadColor[reloadStatus]}">&#xe7f8;</text>
 			<text class="grace-reload-text" :style="{color:reloadColor[reloadStatus]}">{{reloadTxt[reloadStatus]}}</text>
 		</view>
-		<!-- view class="grace-reload-shade" @tap.stop="" @touchstart.stop="" @touchmove.stop="" v-if="reloadStatus != 5"></view -->
+		<!-- view class="grace-reload-shade" @tap.stop="" @touchstart.stop="" @touchmove.stop.prevent="" v-if="reloadStatus != 5"></view -->
 	</view>
 </template>
 <script>
@@ -94,7 +94,7 @@ export default{
 			this.startY = e.moveY;
 			this.startTime = new Date().getTime();
 		},
-		touchmove:function (e) {
+		touchmove:function (e) {
 			if(this.reloadStatus == 3){
 				// 检查时间是否够长
 				var timer = new Date().getTime() - this.startTime;

+ 46 - 0
lib/graceUI/components/graceNvueRightMessage.vue

@@ -0,0 +1,46 @@
+<template>
+	<view class="graceRightMessage" v-if="showIn" 
+	:style="{
+		zIndex:zIndex, bottom:bottom, backgroundColor:background, width:status == 1 ? width : minWidth, 
+		height:height, borderRadius:height}">
+		<view class="graceRightMessageIcon"><slot name="icon"></slot></view>
+		<view class="graceRightMessageContent"><slot name="content"></slot></view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		zIndex : {type:Number, default:99},
+		bottom : {type:String, default:'150rpx'},
+		width  : {type:String, default:'360rpx'},
+		height : {type:String, default:'80rpx'},
+		minWidth : {type:String, default:'180rpx'},
+		background : {type:String, default:'#3688FF'}
+	},
+	data() {
+		return {
+			showIn : true,
+			status : 1
+		}
+	},
+	methods:{
+		open:function () {
+			this.status = 1;
+		},
+		hide:function(){
+			this.showIn = false;
+		},
+		shrink:function(){
+			this.status = 2;
+		},
+		show:function(){
+			this.showIn = true;
+		}
+	}
+}
+</script>
+<style>
+.graceRightMessage{position:fixed; right:-100rpx; bottom:0; padding:10rpx; overflow:hidden; flex-direction:row; flex-wrap:nowrap; align-items:center; padding-right:100rpx;}
+.graceRightMessageIcon{text-align:center;}
+.graceRightMessageContent{width:1rpx; flex:1}
+</style>

+ 254 - 0
lib/graceUI/components/graceNvueSchedule.vue

@@ -0,0 +1,254 @@
+<template>
+	<view class="grace-schedule-wrap">
+		<view class="grace-schedule-header">
+			<picker class="grace-flex-center grace-flex-vcenter" 
+			mode="date" :value="currentDayIn" :start="startDate" :end="endDate" @change="selectDate">
+				<text class="grace-schedule-header-date grace-icons">{{cYear}} 年 {{cMonthStr}} 月 &#xe603;</text>
+			</picker>
+			<text class="grace-schedule-today" @tap="gotoToday">返回今天</text>
+		</view>
+		<view class="grace-date-week">
+			<text class="grace-date-weeks" v-for="(item, index) in weeks" :key="index">{{item}}</text>
+		</view>
+		<view class="grace-date-days">
+			<block v-for="(item, index) in days" :key="index">
+				<view class="grace-date-ditems"  v-if="item != ''" 
+				:style="{backgroundColor:currentDayIn == cYear+'-'+cMonthStr+'-'+ item.date ? activeBgColor : bgColor}" 
+				@click="chooseDate(cYear+'-'+cMonthStr+'-'+item.date, item.date)">
+					<text class="grace-date-day" 
+					:class="[currentDayIn == (cYear+'-'+cMonthStr+'-'+item.date) ? 'grace-d-current-txt' : '']">{{item.date}}</text>
+					<text class="grace-date-nl" v-if="isLunar" 
+					:class="[currentDayIn == (cYear+'-'+cMonthStr+'-'+item.date) ? 'grace-d-current-txt' : '']">{{item.nl}}</text>
+					<view class="grace-schedule-point" v-if="item.haveSe" :style="{backgroundColor:pointColor}"></view>
+				</view>
+				<view class="grace-date-ditems" v-else style="background-color:none;"></view>
+			</block>
+		</view>
+		<view class="grace-schedule-line"></view>
+		<view class="grace-schedule-time-list-wrap">
+			<view class="grace-schedule-time-list" v-for="(item, index) in hours" :key="index">
+				<text class="grace-schedule-timer">{{item}}:00</text>
+				<view class="grace-schedule-body">
+					<text class="grace-schedules" v-for="(schedule, idx) in schedulesIn[index]" :key="idx" 
+					@tap="scheduleTap" :data-id="schedule.id" 
+					:style="{backgroundColor:schedule.bgColor, color:schedule.color}">{{schedule.content}}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	data() {
+		return {
+			cYear      : 2020,
+			cMonth     : 1,
+			cDay       : 10,
+			cMonthStr  : '01',
+			weeks      : ['一', '二', '三', '四', '五', '六', '日'],
+			days       : [],
+			currentDayIn : '',
+			hours      : ['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'],
+			schedulesIn: [] 
+		}
+	},
+	props:{
+		// 当前默认日期
+		currentDate   : {type:String, default:""},
+		bgColor       : {type:String, default:"#F8F8F8"},
+		activeBgColor : {type:String, default:"#3688FF"},
+		isLunar       : {type:Boolean, default:true },
+		startDate     : {type:String, default:'1950-01-01'},
+		endDate       : {type:String, default:'2050-01-01'},
+		schedules     : {type:Array, default:function () {return []}},
+		pointColor    : {type:String, default:"#FF0036"}
+	},
+	created:function(){
+		this.currentDayIn = this.currentDate;
+		this.initTime();
+		this.getSchedulesIn();
+	},
+	methods:{
+		initTime : function(){
+			if(this.currentDayIn == ''){
+				var dateObj        = new Date();
+				this.cYear         = Number(dateObj.getFullYear());
+				this.cMonth        = Number(dateObj.getMonth() + 1);
+				this.cMonthStr     = this.cMonth < 10 ? '0' + this.cMonth : this.cMonth;
+				this.cDay          = dateObj.getDate();
+				this.cDay          = this.cDay < 10 ? '0' + this.cDay : this.cDay;
+				this.currentDayIn  = this.cYear + '-' + this.cMonthStr + '-' + this.cDay;
+				this.changeMonth();
+			}else{
+				var dates          = this.currentDayIn.split(' ');
+				if (!dates[1]) { dates[1] = '';}
+				var dayArr         = dates[0].split('-');
+				this.cYear         = Number(dayArr[0]);
+				this.cMonth        = dayArr[1];
+				this.cDay          = dayArr[2];
+				var reg            = new RegExp('^0[0-9]+$');
+				if(reg.test(this.cMonth)){this.cMonth = this.cMonth.substr(1,1);}
+				this.cMonth        = Number(this.cMonth);
+				this.cMonthStr     = this.cMonth < 10 ? '0'+this.cMonth : this.cMonth;
+				this.currentDayIn  = dates[0];
+				this.currentTimeIn = dates[1];
+				this.changeMonth();
+			}
+		},
+		changeMonth:function(){
+			var daysList  = [];
+			var days      = this.getDaysInOneMonth();
+			var startWeek = this.getDay();
+			var forSteps  = 0;
+			for (var i = (0 - startWeek); i < days; i++){
+				if(i >= 0){
+					daysList[forSteps] = {date : i >= 9 ? i + 1 : '0' + (i+1), nl : ''};
+					daysList[forSteps].nl = GetLunarDay(this.cYear, this.cMonth, i + 1);
+					daysList[forSteps].haveSe = this.haveSchedule(daysList[forSteps].date);
+				}else{
+					daysList[forSteps] = '';
+				}
+				forSteps++;
+			}
+			this.days    = daysList;
+		},
+		haveSchedule : function (day) {
+			var cDay = this.cYear+'-'+this.cMonthStr+'-'+day;
+			for(let i = 0; i < this.schedules.length; i++){
+				if(this.schedules[i].datetime.indexOf(cDay) != -1){
+					return true;
+				}
+			}
+			return false;
+		},
+		getDaysInOneMonth : function (){
+			var d = new Date(this.cYear, this.cMonth, 0);
+			return d.getDate();
+		},
+		getDay : function (){
+			var d = new Date(this.cYear, this.cMonth - 1, 0);
+			return d.getDay();
+		},
+		selectDate : function(e){
+			this.currentDayIn = e.detail.value;
+			this.initTime();
+			this.getSchedulesIn();
+			this.$emit('selectDate', e.detail.value);
+		},
+		chooseDate: function (sedDate) {
+			this.currentDayIn = sedDate;
+			this.getSchedulesIn();
+			this.$emit('chooseDate', sedDate);
+		},
+		getSchedulesIn : function (){
+			var res = [];
+			for(let i = 0; i < this.hours.length; i++){
+				var ctime = this.currentDayIn + ' ' + this.hours[i] + ':00';
+				res.push([]);
+				for(let ii = 0; ii < this.schedules.length; ii++){
+					if(this.schedules[ii].datetime == ctime){
+						res[i].push(this.schedules[ii]);
+					}
+				}
+			}
+			this.schedulesIn = res;
+		},
+		scheduleTap : function (e) {
+			var id = e.currentTarget.dataset.id;
+			this.$emit('scheduleTap', id);
+		},
+		gotoToday : function(){
+			var dateObj        = new Date();
+			this.cYear         = Number(dateObj.getFullYear());
+			this.cMonth        = Number(dateObj.getMonth() + 1);
+			this.cMonthStr     = this.cMonth < 10 ? '0' + this.cMonth : this.cMonth;
+			this.cDay          = dateObj.getDate();
+			this.cDay          = this.cDay < 10 ? '0' + this.cDay : this.cDay;
+			this.currentDayIn  = this.cYear + '-' + this.cMonthStr + '-' + this.cDay;
+			this.changeMonth();
+			this.getSchedulesIn();
+			this.$emit('gotoToday', this.currentDayIn);
+		}
+	}
+}
+var CalendarData = new Array(100);
+var madd = new Array(12);
+var tgString = "甲乙丙丁戊己庚辛壬癸";
+var dzString = "子丑寅卯辰巳午未申酉戌亥";
+var numString = "一二三四五六七八九十";
+var monString = "正二三四五六七八九十冬腊";
+var weekString = "日一二三四五六";
+var sx = "鼠牛虎兔龙蛇马羊猴鸡狗猪";
+var cYear, cMonth, cDay, TheDate;
+CalendarData = new Array(0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5, 0x50DA9, 0x5AD, 0x2B6, 0x3126E, 0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A, 0x4155B, 0x25D, 0x92D, 0x2192B, 0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5, 0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6, 0x414AE, 0xA57, 0x526, 0x31D26, 0xD95, 0x70B55, 0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54, 0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B, 0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957, 0x5092F, 0x497, 0x64B, 0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96, 0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D, 0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5, 0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95);
+madd[0] = 0;
+madd[1] = 31;
+madd[2] = 59;
+madd[3] = 90;
+madd[4] = 120;
+madd[5] = 151;
+madd[6] = 181;
+madd[7] = 212;
+madd[8] = 243;
+madd[9] = 273;
+madd[10] = 304;
+madd[11] = 334;
+function GetBit(m, n){return (m >> n) & 1;}
+//农历转换
+function e2c() {
+	TheDate = (arguments.length != 3) ? new Date() : new Date(arguments[0], arguments[1], arguments[2]);
+	var total, m, n, k;
+	var isEnd = false;
+	var tmp = TheDate.getYear();
+	if (tmp < 1900) {tmp += 1900;}
+	total = (tmp - 1921) * 365 + Math.floor((tmp - 1921) / 4) + madd[TheDate.getMonth()] + TheDate.getDate() - 38;
+	if (TheDate.getYear() % 4 == 0 && TheDate.getMonth() > 1) {total++;}
+	for (m = 0; ; m++) {
+		k = (CalendarData[m] < 0xfff) ? 11 : 12;
+		for (n = k; n >= 0; n--) {
+			if (total <= 29 + GetBit(CalendarData[m], n)) {isEnd = true; break;}
+			total = total - 29 - GetBit(CalendarData[m], n);
+		}
+		if (isEnd) break;
+	}
+	cYear = 1921 + m;
+	cMonth = k - n + 1;
+	cDay = total;
+	if (k == 12) {
+		if (cMonth == Math.floor(CalendarData[m] / 0x10000) + 1) {cMonth = 1 - cMonth;}
+		if (cMonth > Math.floor(CalendarData[m] / 0x10000) + 1) {cMonth--;}
+	}
+}
+function GetcDateString() {
+	var tmp = "";
+	tmp += (cDay < 11) ? "初" : ((cDay < 20) ? "十" : ((cDay < 30) ? "廿" : "三十"));
+	if (cDay % 10 != 0 || cDay == 10) {tmp += numString.charAt((cDay - 1) % 10);}
+	return tmp;
+}
+function GetLunarDay(solarYear, solarMonth, solarDay) {
+	if (solarYear < 1921) {return "";}
+	solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11;
+	e2c(solarYear, solarMonth, solarDay);
+	return GetcDateString();
+}
+</script>
+<style>
+.grace-schedule-wrap{width:702rpx; margin-left:24rpx;}
+.grace-schedule-header{flex-direction:row; justify-content:space-between; align-items:center;}
+.grace-schedule-header-date{height:88rpx; line-height:88rpx; color:#323232; font-size:32rpx;}
+.grace-date-week{width:702rpx; flex-wrap:nowrap; flex-direction:row; justify-content:center;}
+.grace-date-weeks{width:100rpx; height:60rpx; font-size:26rpx; line-height:60rpx; color:#666666; text-align:center;}
+.grace-date-days{width:702rpx; flex-direction:row; flex-wrap:wrap;}
+.grace-date-ditems{width:80rpx; height:80rpx; flex-direction:column; align-items:center; justify-content:center; margin:10rpx; border-radius:80rpx;}
+.grace-d-current-txt{color:#FFFFFF !important;}
+.grace-date-day{height:38rpx; line-height:38rpx; text-align:center; font-size:28rpx;}
+.grace-date-nl{height:26rpx; line-height:26rpx; color:#888888; font-size:20rpx; text-align:center;}
+.grace-schedule-line{height:20rpx; border-style:solid; border-color:#F8F8F8; border-bottom-width:1px;}
+.grace-schedule-time-list{margin-top:20rpx; flex-direction:row; flex-wrap:nowrap; align-items:flex-start;}
+.grace-schedule-timer{width:100rpx; font-size:22rpx; color:#999999; line-height:36rpx;}
+.grace-schedule-body{width:200rpx; flex:1; border-style:solid; border-color:#F8F8F8; border-top-width:1px; margin-top:15rpx;}
+.grace-schedules{padding:10rpx; line-height:30rpx; font-size:22rpx; margin-top:15rpx; border-radius:8rpx;}
+.grace-schedule-time-list-wrap{padding:20rpx;}
+.grace-schedule-today{line-height:50rpx; height:50rpx; font-size:22rpx; color:#828282; padding-left:20rpx; padding-right:20rpx; margin-left:30rpx; border-radius:8rpx; border-width:1px; border-style:solid; border-color:#F1F2F3;}
+.grace-schedule-point{width:18rpx; height:18rpx; border-radius:10rpx; background-color:#FF0036; position:absolute; right:5rpx; top:5rpx;}
+</style>

+ 27 - 12
lib/graceUI/components/graceNvueSelectImg.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="grace-add-list">
 		<view class="grace-add-list-items" v-for="(item, index) in imgLists" :key="index">
-			<image :src="item" :data-imgurl="item" @tap="showImgs" class="grace-add-list-img" :mode="imgMode"></image>
+			<image :src="item.url" :data-imgurl="item.url" @tap="showImgs" class="grace-add-list-img" :mode="imgMode"></image>
 			<text class="grace-add-list-remove grace-icons" @tap="removeImg" :id="'grace-items-img-'+index" :style="{color:closeBtnColor}">&#xe632;</text>
 		</view>
 		<view class="grace-add-list-items grace-add-list-btn" @tap="addImg" v-if="imgLists.length < maxFileNumber">
@@ -42,43 +42,58 @@ export default {
 		}
 	},
 	created:function () {
-		this.imgLists = this.items;
+		this.initImgs();
 	},
 	watch:{
-		imgLists : function(newVal, oldVal){
-			this.$emit('change', newVal);
-		}
+		items:function(){this.initImgs();}
 	},
     methods:{
+		initImgs : function(){
+			var imgs = [];
+			for(let i = 0; i < this.items.length; i++){
+				imgs.push({url:this.items[i],  progress : 100});
+			}
+			this.imgLists = imgs;
+		},
         addImg : function(){
             var num = this.maxFileNumber - this.imgLists.length;
             if(num < 1){return false;}
-            uni.showLoading({title:""});
             uni.chooseImage({
                 count: num,
                 sizeType: ['compressed'],
                 success:(res) => {
-                    this.imgLists = this.imgLists.concat(res.tempFilePaths);
-                    uni.hideLoading();
+					for(let i = 0; i < res.tempFilePaths.length; i++){
+						this.imgLists.push({url:res.tempFilePaths[i], progress:0})
+					}
+                    this.$emit('change', this.imgLists);
                 },
 				fail:function(){
-					uni.hideLoading();
+					//uni.hideLoading();
 				}
             });
         },
         removeImg : function(e){
             var index = e.currentTarget.id.replace('grace-items-img-', '');
-            this.imgLists.splice(index, 1);
+			var removeImg =  this.imgLists.splice(index, 1);
+			this.$emit('removeImg', removeImg[0]);
+			this.$emit('change', this.imgLists);
         },
         showImgs : function(e){
             var currentImg = e.currentTarget.dataset.imgurl;
+			var imgs = [];
+			for(let i = 0; i < this.imgLists.length; i++){
+				imgs.push(this.imgLists[i].url);
+			}
             uni.previewImage({
-              urls: this.imgLists,
+              urls: imgs,
               current : currentImg
             })
         },
 		setItems : function(items){
-			this.imgLists = items;
+			this.imgLists = [];
+			for(let i = 0; i < items.length; i++){
+				this.imgLists.push({url : items[i], progress : 100});
+			}
 		}
     }
 }

+ 4 - 2
lib/graceUI/components/graceNvueSelectImgAndUpload.vue

@@ -99,7 +99,8 @@ export default {
         },
         removeImg : function(e){
             var index = e.currentTarget.id.replace('grace-items-img-', '');
-            this.imgLists.splice(index, 1);
+            var removeImg =  this.imgLists.splice(index, 1);
+            this.$emit('removeImg', removeImg[0]);
         },
         showImgs : function(e){
             var currentImg = e.currentTarget.dataset.imgurl;
@@ -186,8 +187,9 @@ export default {
 		},
 		// 设置默认值
 		setItems : function(items){
+			this.imgLists = [];
 			for(let i = 0; i < items.length; i++){
-				this.imgLists.push({url : items[i], progress : 100, error : false});
+				this.imgLists.push({url : items[i], progress : 100});
 			}
 		},
 		imgLoad : function (e) {

+ 17 - 9
lib/graceUI/components/graceNvueSelectList.vue

@@ -1,14 +1,19 @@
 <template>
 	<view class="select-list">
 		<view v-for="(item, index) in dataIn" :key="index" class="select-list-item" :data-index="index" @tap.stop="choose">
-			<image :src="item.img" class="select-list-img" v-if="item.img" mode="widthFix" :style="{width:imgSize[0], height:imgSize[1]}"></image>
-			<view class="select-list-body" :class="[isBorder?'grace-border-b':'']">
-				<text class="select-list-content" :style="{fontSize:fontSize, lineHeight:lineHeight, color:itemColor}">{{item.title}}</text>
+			<image :src="item.img" class="select-list-img" v-if="item.img" mode="widthFix" 
+			:style="{width:imgSize[0], height:imgSize[1], borderRadius:imgBorderRadius}"></image>
+			<view class="select-list-body" :class="[isBorder?'grace-border-b':'']" 
+			:style="{borderBottomColor:borderColor}">
+				<view class="select-list-content">
+					<text :style="{fontSize:fontSize, lineHeight:lineHeight, color:itemColor}">{{item.title}}</text>
+					<text class="select-list-desc" v-if="item.desc">{{item.desc}}</text>
+				</view>
 				<text class="select-list-icon grace-icons" v-if="item.checked" :style="{color:item.checked ? checkColor : '#A5A7B2'}">&#xe60f;</text>
 			</view>
 		</view>
-	</view>
-</template>
+	</view>
+</template>
 <script>
 export default{
 	props:{
@@ -16,10 +21,12 @@ export default{
 		checkColor:{type:String, default:"#3688FF"},
 		type : { type: String, default: "radio"},
 		imgSize:{type:Array, default:function(){return ['68rpx','68rpx'];}},
+		imgBorderRadius:{type: String, default: "60rpx"},
 		fontSize:{type: String, default: "28rpx"},
 		isBorder:{type:Boolean, default:true},
 		lineHeight:{type: String, default: "50rpx"},
-		itemColor:{type:String, default:"#323232"}
+		itemColor:{type:String, default:"#323232"},
+		borderColor:{type:String, default:"#F6F6F6"}
 	},
 	data() {
 		return {
@@ -64,13 +71,14 @@ export default{
 			}
 		}
 	}
-}
-</script>
+}
+</script>
 <style>
 .select-list{}
 .select-list-item{flex-direction:row; flex-wrap:nowrap; align-items:center; font-size:0;}
 .select-list-icon{width:60rpx; line-height:60rpx; text-align:center; font-size:36rpx; color:#A5A7B2; font-weight:700; margin-left:28rpx;}
 .select-list-img{border-radius:60rpx; margin-right:28rpx;}
 .select-list-body{width:300rpx; flex:1; flex-wrap:nowrap; flex-direction:row; align-items:center;}
-.select-list-content{width:200rpx; flex:1; overflow:hidden; margin-top:25rpx; margin-bottom:25rpx;}
+.select-list-content{width:200rpx; flex:1; overflow:hidden; margin-top:25rpx; margin-bottom:25rpx;}
+.select-list-desc{font-size:22rpx; color:#828282; line-height:40rpx;}
 </style>

+ 29 - 11
lib/graceUI/components/graceNvueSelectMenu.vue

@@ -5,8 +5,15 @@
 			<text class="grace-select-menu-title-icon grace-icons" v-if="!show">&#xe603;</text>
 			<text class="grace-select-menu-title-icon grace-icons" v-if="show">&#xe654;</text>
 		</view>
-		<view class="grace-select-menu" @click.stop="close" @touchmove.stop="" v-if="show">
+		<view class="grace-select-menu" @click.stop="close" @touchmove.stop.prevent="" v-if="show">
 			<scroll-view class="grace-select-menus" scroll-y :style="{padding:padding, height:height+'rpx'}">
+				<view @tap.stop="" class="grace-select-item" v-if="isInput"
+				style="flex-direction:row; flex-wrap:nowrap; align-items:center;">
+					<view class="grace-select-input-wrap">
+						<input type="text" v-model="inputVal" class="grace-select-input" @confirm="addTag" :placeholder="placeholder" />
+					</view>
+					<text class="grace-select-input-btn" @tap.stop="addTag" @touchmove.stop.prevent="">{{addBtnName}}</text>
+				</view>
 				<view class="grace-select-item" v-for="(item, index) in items" :key="index" :data-index="index" @click.stop="select">
 					<text class="grace-selected-icon grace-icons" :style="{color : index == currentIndex ? activeColor : color}" v-if="index == currentIndex">&#xe7f8;</text>
 					<text class="grace-selected-text" :style="{color : index == currentIndex ? activeColor : color, fontSize:fontSize}">{{item}}</text>
@@ -30,7 +37,7 @@ export default {
 		},
 		height : {
 			type : Number,
-			default : 300
+			default : 500
 		},
 		color : {
 			type : String,
@@ -43,15 +50,18 @@ export default {
 		selectIndex : {
 			type : Number,
 			default : 0
-		},
-		fontSize : {
-			type : String,
-			default : '26rpx'
-		},
-		padding:{
-			type : String,
-			default : "20rpx"
-		}
+		},
+		fontSize : {
+			type : String,
+			default : '26rpx'
+		},
+		padding:{
+			type : String,
+			default : "20rpx"
+		},
+		isInput:{type:Boolean, default:false},
+		placeholder:{type:String, default:"自定义"},
+		addBtnName:{type:String, default:"+ 添加"}
 	},
 	data() {
 		return {
@@ -79,6 +89,11 @@ export default {
 			this.currentIndex = index;
 			this.$emit('select', index);
 			this.close();
+		},
+		addTag : function () {
+			if(this.inputVal == ''){return ;}
+			this.$emit('submit', this.inputVal);
+			this.inputVal = '';
 		}
 	}
 }
@@ -93,4 +108,7 @@ export default {
 .grace-select-item{padding:10rpx; background-color:#FFFFFF; font-size:28rpx; color:#333333; border-bottom-width:1px; border-bottom-style:solid; border-bottom-color:#F8F8F8; flex-direction:row; flex-wrap:nowrap; align-items:center;}
 .grace-selected-icon{font-size:28rpx; line-height:80rpx; margin-right:20rpx;}
 .grace-selected-text{font-size:28rpx; line-height:80rpx;}
+.grace-select-input-wrap{width:200rpx; flex:1;}
+.grace-select-input{line-height:60rpx; height:60rpx; font-size:28rpx; margin-top:20rpx;margin-bottom:20rpx;}
+.grace-select-input-btn{width:120rpx; line-height:60rpx; height:60rpx; text-align:center; background-color:#F8F8F8; font-size:24rpx; border-radius:6rpx; color:#3688FF;}
 </style>

+ 46 - 41
lib/graceUI/components/graceNvueSelectTags.vue

@@ -12,35 +12,33 @@
 <script>
 export default {
 	props: {
-		type : { type: String, default: "radio"},
-		items : { type: Array, default : function(){return []}},
-		itemWidth : {type: String, default:"220rpx"},
-		selectedColor:{type: String, default:"#3688FF"},
+		itemWidth : {type: String, default:"200rpx"},
+		type : { type: String, default: ""},
+		selectedColor : { type: String, default: "#3688FF"},
 		fontSize : { type: String, default: "26rpx"},
+		items : { type: Array, default : function(){return []}},
+		datas : { type: Array, default : function(){return []}},
 		bgColor :  { type: String, default: "#F6F7F8"},
 		height:{type: String, default:"68rpx"},
 		borderRadius : {type: String, default:"10rpx"},
 		fontColor:{type: String, default:"#323232"},
 		fontActiveColor:{type: String, default:"#FFFFFF"}
 	},
-	created : function(){
-		this.tagsData = this.items;
-	},
 	created : function(){
-		this.tagsData = this.items == null ? [] : this.items;
-		this.initChange();
-	},
-	data() {
-		return {
-			tagsData : []
-		}
+		this.tagsData = this.items == null ? [] : this.items;
+		this.initChange();
+	},
+	data() {
+		return {
+			tagsData : []
+		}
 	},
 	watch:{
 		items:function(val){
 			this.tagsData = val;
 			this.initChange();
 		}
-	},
+	},
 	methods:{
 		initChange : function () {
 			if(this.type == 'radio'){
@@ -52,7 +50,7 @@ export default {
 						selectVal   = this.tagsData[i].value;
 					}
 				}
-				this.$emit("change", selectVal, this.datas, selectIndex);
+				//this.$emit("change", selectVal, this.datas, selectIndex);
 			}else{
 				var sedRes = [], indexs = [];
 				for (var i = 0; i < this.tagsData.length; i++){
@@ -61,38 +59,44 @@ export default {
 						indexs.push(i);
 					}
 				}
-				this.$emit("change", sedRes, this.datas, indexs);
+				//this.$emit("change", sedRes, this.datas, indexs);
 			}
-		},
-		graceSelectChange : function(index){
-			if(this.type == 'radio'){
+		},
+		graceSelectChange : function(index){
+			// 单选
+			if(this.type == 'radio'){
 				for (var i = 0; i < this.tagsData.length; i++){
 					this.tagsData[i].checked = false;
 					this.tagsData.splice(i,1,this.tagsData[i]);
-				}
+				}
 				this.tagsData[index].checked = true;
-				this.tagsData.splice(index,1,this.tagsData[index]);
-				this.$emit("change", this.tagsData[index].value, this.datas, index);
-			}else{
-				if(this.tagsData[index].checked){
-					this.tagsData[index].checked = false;
-				}else{
-					this.tagsData[index].checked = true;
-				}
-				var sedRes = [], indexs = [];
-				for (var i = 0; i < this.tagsData.length; i++){
-					if(this.tagsData[i].checked){
+				this.tagsData.splice(index,1,this.tagsData[index]);
+				this.$emit("change", this.tagsData[index].value, this.datas, index);
+			}
+			//  多选
+			else{
+				if(this.tagsData[index].checked){
+					this.tagsData[index].checked = false;
+				}else{
+					this.tagsData[index].checked = true;
+				}
+				this.tagsData.splice(index,1,this.tagsData[index]);
+				var sedRes = [], indexs = [];
+				for (var i = 0; i < this.tagsData.length; i++){
+					if(this.tagsData[i].checked){
 						sedRes.push(this.tagsData[i].value);
-						indexs.push(i);
-					}
-				}
-				this.$emit("change", sedRes, this.datas, indexs);
-			}
-		},
+						indexs.push(i);
+					}
+				}
+				this.$emit("change", sedRes, this.datas, indexs);
+			}
+		},
+		// 设置新的选项
 		setItems : function(items){
 			this.tagsData = items;
 			this.initChange();
-		},
+		},
+		// 全不选
 		clearSelected:function(){
 			var newData = [];
 			for(let i = 0; i < this.tagsData.length; i++){
@@ -105,7 +109,8 @@ export default {
 			}else{
 				this.$emit("change", [], this.datas, []);
 			}
-		},
+		},
+		// 全选
 		selectAll : function () {
 			if(this.type == 'radio'){return ;}
 			var newData = [],reDatas = [], reIndex = [];
@@ -117,7 +122,7 @@ export default {
 			}
 			this.tagsData = newData;
 			this.$emit("change", reDatas, this.datas, reIndex);
-		}
+		}
 	}
 }
 </script>

+ 49 - 10
lib/graceUI/components/graceNvueShade.vue

@@ -1,22 +1,61 @@
 <template>
-	<view class="grace-shade" :style="{backgroundColor:background}" v-if="show" @tap.stop="closeShade" @touchmove.stop="">
+	<view class="grace-shade" ref="graceShade" 
+	:style="{backgroundColor:background, left:left}" 
+	@tap.stop="closeShade" @touchmove.stop.prevent="">
 		<slot></slot>
-	</view>
-</template>
+	</view>
+</template>
 <script>
+var animation = weex.requireModule('animation');
+const dom = weex.requireModule('dom');
 export default{
 	props:{
 		background : {type:String, default:"rgba(0, 0, 0, 0.1)"},
 		zIndex : {type:Number, default:1},
 		show : {type:Boolean, default:true}
 	},
-	methods:{
-		closeShade : function(){
-			this.$emit('closeShade');
-		}
+	data() {
+		return {
+			left : '-2000px'
+		}
+	},
+	created:function(){
+		if(this.show){ this.showIt(); }else{ this.hideIt();}
+	},
+	watch:{
+		show:function(val){
+			if(val){ this.showIt(); }else{ this.hideIt(); }
+		}
+	},
+	methods:{
+		closeShade : function(){this.$emit('closeShade');},
+		showIt : function(){
+			this.left = '0px';
+			var graceShade = this.$refs.graceShade;
+			animation.transition(graceShade, {
+				styles: {opacity:1},
+				duration:280, 
+				timingFunction: 'ease',
+				needLayout:false,
+				delay: 0 
+			});
+		},
+		hideIt : function(){
+			var graceShade = this.$refs.graceShade;
+			animation.transition(graceShade, {
+				styles: {opacity:0},
+				duration:280, 
+				timingFunction: 'ease',
+				needLayout:false,
+				delay: 0 
+			});
+			setTimeout(()=>{
+				this.left = '0px';
+			}, 280);
+		}
 	}
-}
-</script>
+}
+</script>
 <style scoped>
-.grace-shade{position:fixed; width:750rpx; left:0; top:0; bottom:0; z-index:1; justify-content:center; align-items:center;}
+.grace-shade{position:fixed; width:750rpx; left:-2000px; opacity:0; top:0; bottom:0; z-index:1; justify-content:center; align-items:center;}
 </style>

+ 2 - 2
lib/graceUI/components/graceNvueSlider.vue

@@ -6,10 +6,10 @@
 		:style="{backgroundColor:activeColor, width:activeWidth+'px', height:height+'px', marginLeft:activeLeft+'px', top:lineTop+'px'}"></view>
 		<view class="grace-slider-block" 
 		:style="{backgroundColor:blockBgColor, height:blockSize+'px', width:blockSize+'px', 'margin-left':xMin+'px'}" 
-		@touchstart.stop="touchstart" @touchmove.stop="touchmove" data-tag="min"></view>
+		@touchstart.stop="touchstart" @touchmove.stop.prevent="touchmove" data-tag="min"></view>
 		<view class="grace-slider-block" 
 		:style="{backgroundColor:blockBgColor, height:blockSize+'px', width:blockSize+'px', 'margin-left':xMax+'px'}" 
-		@touchstart.stop="touchstart" @touchmove.stop="touchmove" data-tag="max"></view>
+		@touchstart.stop="touchstart" @touchmove.stop.prevent="touchmove" data-tag="max"></view>
 	</view>
 </template>
 <script>

+ 7 - 3
lib/graceUI/components/graceNvueSpeaker.vue

@@ -1,7 +1,8 @@
 <template name="graceSpeaker">
 	<view class="grace-swiper-msg">
 		<view class="grace-swiper-msg-icon"><slot></slot></view>
-		<swiper :vertical="vertical" autoplay="true" circular="true" :interval="interval" class="grace-swiper-msg-swiper" :style="{height:height}">
+		<swiper :vertical="vertical" autoplay="true" circular="true" @change="change" 
+		:interval="interval" class="grace-swiper-msg-swiper" :style="{height:height}">
 			<swiper-item v-for="(item, index) in msgs" :key="index" class="grace-swiper-msg-swiper-item" :style="{height:height}">
 				<text @tap="navto"
 				:data-url="item.url" :data-opentype="item.opentype" class="grace-swiper-msg-text" 
@@ -20,7 +21,7 @@ export default {
 		},
 		interval : {
 			type : Number,
-			default: 3000
+			default: 5000
 		},
 		vertical : {
 			type : Boolean,
@@ -45,7 +46,7 @@ export default {
 		fontWeight : {
 			type  : String,
 			default : ""
-		},
+		}
 	},
 	methods:{
 		navto : function (e) {
@@ -70,6 +71,9 @@ export default {
 				default:
 					break;
 			}
+		},
+		change:function (index) {
+			this.$emit('change', index.detail.current);
 		}
 	}
 }

+ 122 - 0
lib/graceUI/components/graceNvueSwipeList.vue

@@ -0,0 +1,122 @@
+<template>
+	<view class="grace-swipe-list" :style="{width:width+'rpx'}">
+		<graceNvueTouch v-for="(item, index) in msgsIn" :key="index" @thStart="thStart" @thMove="thMove" @thEnd="thEnd" :datas="[index]">
+			<view class="grace-swipe-list-item" :style="{width:width+'rpx'}">
+				<view class="grace-swipe-list-item-body" :style="{width:width+'rpx', marginLeft:(item.x * -1) + 'px'}">
+					<view class="grace-swipe-list-img" :style="{width:imgSize[0], height:imgSize[1]}">
+						<image :src="item.img" mode="widthFix" :style="{width:imgSize[0], height:imgSize[1], borderRadius:'6rpx'}"></image>
+						<text class="grace-swipe-list-point" v-if="item.msgnumber > 0">{{item.msgnumber}}</text>
+					</view>
+					<view class="grace-swipe-list-content">
+						<view class="grace-swipe-list-title">
+							<text class="grace-swipe-list-title-text" :style="{fontSize:fontSizes[0], color:fontColors[0], flex:1}">{{item.title}}</text>
+							<text class="grace-swipe-list-title-text" :style="{fontSize:fontSizes[1], color:fontColors[1], marginLeft:'25rpx', marginRight:'25rpx'}">{{item.time}}</text>
+						</view>
+						<text class="grace-swipe-list-desc" :style="{fontSize:fontSizes[2], color:fontColors[2], marginTop:'6rpx'}">{{item.content}}</text>
+					</view>
+				</view>
+				<view class="grace-swipe-btns" :style="{width:item.x+'px'}">
+					<view class="grace-swipe-btn" v-for="(btn, btnIndex) in item.btns" :key="btnIndex" 
+					:style="{backgroundColor:btn.bgColor}" @tap.stop="btnTap(index, btnIndex)">
+						<text class="grace-swipe-btn-text">{{btn.name}}</text>
+					</view>
+				</view>
+			</view>
+		</graceNvueTouch>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		width:{type:Number, default:750},
+		msgs:{type:Array,default:function(){return [];}},
+		imgSize:{type:Array,default:function(){return ['80rpx', '80rpx'];}},
+		fontSizes:{type:Array,default:function(){return ['28rpx','22rpx', '22rpx'];}},
+		fontColors:{type:Array,default:function(){return ['#323232','#888888', '#888888'];}},
+		btnWidth:{type:Number, default:160}
+	},
+	data() {
+		return {
+			msgsIn: [],
+			damping : 0.1
+		}
+	},
+	created:function(){
+		this.init(this.msgs);
+	},
+	watch:{
+		msgs : function(nv){
+			this.init(nv);
+		}
+	},
+	methods:{
+		init:function(msgs){
+			var newmsg = [];
+			msgs.forEach((item) => { item.x = 0; newmsg.push(item); });
+			this.msgsIn = newmsg;
+		},
+		setItems : function (msgs){
+			
+		},
+		thStart : function(e, index){
+			this.damping = 0.1;
+			var i = 0;
+			this.msgsIn.forEach((item) => { 
+				if(i != index){
+					if(item.x > 10){this.toZero(i);}
+				}
+				i++;
+			});
+		},
+		thMove : function (e, index){
+			var item = this.msgsIn[index];
+			item.x -= e[0][0] * this.damping;
+			if(item.x > this.btnWidth){item.x = this.btnWidth;}
+			if(item.x < 0){item.x = 0;}
+			this.msgsIn.splice(index, 1, item);
+			this.damping *= 1.2;
+		},
+		thEnd : function(e, index){
+			if(e[1] < 150){
+				if(this.msgsIn[index].x >= 5){
+					this.toZero(index);
+					return;
+				}
+				if(Math.abs(e[0][0]) < 30){this.$emit('itemTap',index);}
+				return ;
+			}
+			var item = this.msgsIn[index];
+			if(item.x < this.btnWidth / 3){item.x = 0;}else{item.x = this.btnWidth;}
+			this.msgsIn.splice(index, 1, item);
+		},
+		toZero:function(index){
+			if(this.msgsIn[index].x < 0 ){
+				this.msgsIn[index].x = 0;
+				this.msgsIn.splice(index, 1, this.msgs[index]);
+				return;
+			}
+			this.msgsIn[index].x -= 10;
+			this.msgsIn.splice(index, 1, this.msgsIn[index]);
+			setTimeout(()=>{this.toZero(index);},10);
+		},
+		btnTap : function (index, indexBtn) {
+			this.$emit('btnTap',index, indexBtn);
+		}
+	},
+	components:{}
+}
+</script>
+<style>
+.grace-swipe-list{overflow:hidden;}
+.grace-swipe-list-item{overflow:hidden; position:relative;}
+.grace-swipe-list-item-body{flex-direction:row; flex-wrap:nowrap; font-size:0; align-items:center;}
+.grace-swipe-list-img{flex-shrink:0; margin-left:25rpx; font-size:0;}
+.grace-swipe-list-point{border-radius:32rpx; height:30rpx; line-height:30rpx; padding:0 10rpx; font-size:20rpx; background-color:#FF0036; color:#FFFFFF; position:absolute; z-index:1; right:0; top:0;}
+.grace-swipe-list-content{width:500rpx; flex:1; overflow:hidden; padding-top:25rpx; padding-bottom:25rpx; margin-left:22rpx; border-bottom-width:1px; border-style:solid; border-color:#F1F2F3;}
+.grace-swipe-list-title{flex-direction:row; flex-wrap:nowrap; justify-content:space-between; overflow:hidden;}
+.grace-swipe-list-title-text{line-height:38rpx; height:38rpx; overflow:hidden;}
+.grace-swipe-list-desc{line-height:32rpx; height:32rpx; overflow:hidden; padding-right:25rpx;}
+.grace-swipe-btns{width:0rpx; position:absolute; z-index:1; right:0; top:0; height:116rpx; flex-direction:row; flex-wrap:nowrap;}
+.grace-swipe-btn{width:100rpx; flex:1; height:125rpx; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; padding:20rpx; overflow:hidden;}
+.grace-swipe-btn-text{line-height:36rpx; height:36rpx; overflow:hidden; font-size:28rpx; color:#FFFFFF;}
+</style>

+ 16 - 8
lib/graceUI/components/graceNvueSwiper.vue

@@ -5,7 +5,8 @@
 		:indicator-color="indicatorColor" :indicator-active-color="indicatorActiveColor" 
 		:duration="500" :circular="true" :autoplay="autoplay" :current="currentIndex" @change="swiperchange">
 			<swiper-item v-for="(item, index) in swiperItems" :key="index" class="grace-swiper-card-item">
-				<navigator class="grace-swiper-card-nav" :url="item.url" :open-type="item.opentype" hover-class="none" v-if="item.opentype != 'click'">
+				<navigator class="grace-swiper-card-nav" :url="item.url" 
+				:open-type="item.opentype" hover-class="none" v-if="item.opentype != 'click'">
 					<image :style="{ borderRadius : borderRadius, width:width+'rpx', height:height+'rpx'}" 
 					:src="item.img" class="grace-swiper-card-image" />
 				</navigator>
@@ -15,16 +16,22 @@
 					:src="item.img" class="grace-swiper-card-image" />
 				</view>
 				<view v-if="indicatorType == 'number'" class="grace-indicator-dot-numbers" 
-				:style="{height:indicatorBarHeight+'rpx', backgroundColor:indicatorBarBgColor, width:width+'rpx', left:'0rpx', bottom:'0rpx'}">
-					<text class="grace-indicator-dot-text" :style="{paddingLeft:'20rpx', 'fontStyle':'italic', color:titleColor}">{{index+1}}</text>
+				:style="{height:indicatorBarHeight+'rpx', backgroundColor:indicatorBarBgColor, 
+				width:width+'rpx', left:'0rpx', bottom:'0rpx'}">
+					<text class="grace-indicator-dot-text" 
+					:style="{paddingLeft:'20rpx', 'fontStyle':'italic', color:titleColor}">{{index+1}}</text>
 					<text class="grace-indicator-dot-text" :style="{'fontSize':'36rpx', color:titleColor}">/</text>
-					<text class="grace-indicator-dot-text" :style="{fontSize:'28rpx', paddingRight:'20rpx', fontStyle:'italic', color:titleColor}">{{swiperItems.length}}</text>
-					<text class="grace-swiper-text" :style="{color:titleColor, fontSize:titleSize, height:indicatorBarHeight+'rpx', lineHeight:indicatorBarHeight+'rpx'}">{{item.title}}</text>
+					<text class="grace-indicator-dot-text" 
+					:style="{fontSize:'28rpx', paddingRight:'20rpx', fontStyle:'italic', color:titleColor}">{{swiperItems.length}}</text>
+					<text class="grace-swiper-text" 
+					:style="{color:titleColor, fontSize:titleSize, height:indicatorBarHeight+'rpx', 
+					lineHeight:indicatorBarHeight+'rpx'}">{{item.title}}</text>
 				</view>
 			</swiper-item>
 		</swiper>
-		<view class="grace-indicator-dots" :style="{width:width+'rpx', height:indicatorBarHeight+'rpx'}">
-			<view v-for="(item, index) in swiperItems" :key="index" class="grace-indicator-dot" v-if="indicatorType == 'dot'" 
+		<view class="grace-indicator-dots" v-if="indicatorType == 'dot'" 
+		:style="{width:width+'rpx', height:indicatorBarHeight+'rpx', position:indicatorPosition}">
+			<view v-for="(item, index) in swiperItems" :key="index" class="grace-indicator-dot" 
 			:style="{
 				width           : current != index ? indicatorWidth+'rpx' : indicatorActiveWidth +'rpx',
 				height          : indicatorHeight+'rpx',
@@ -49,6 +56,7 @@ export default{
 		indicatorColor : { type : String, default : "rgba(255, 255, 255, 0.6)" },
 		indicatorActiveColor : { type : String, default : "#3688FF" },
 		indicatorType:{ type : String, default : "dot" },
+		indicatorPosition:{ type : String, default : "absolute" },
 		spacing : { type : Number, default : 50 },
 		padding : { type : Number, default : 26 },
 		interval : { type : Number, default : 5000 },
@@ -95,7 +103,7 @@ export default{
 .grace-swiper-card-item{font-size:0; overflow:hidden; line-height:0;}
 .grace-swiper-card-nav{font-size:0; position:relative;}
 .grace-swiper-card-image{}
-.grace-indicator-dots{width:750rpx; height:68rpx; overflow:hidden; position:absolute; z-index:1; left:0; bottom:0; flex-direction:row; flex-wrap:nowrap; align-items:center; justify-content:center;}
+.grace-indicator-dots{width:750rpx; height:68rpx; overflow:hidden; left:0; bottom:0; flex-direction:row; flex-wrap:nowrap; align-items:center; justify-content:center;}
 .grace-indicator-dot{margin:6rpx;}
 .grace-indicator-dot-text{text-align:center; line-height:68rpx; padding:0 4rpx; color:#FFFFFF; font-size:32rpx;}
 .grace-indicator-dot-numbers{flex-direction:row; flex-wrap:nowrap; justify-content:center; overflow:hidden; align-items:center; position:absolute; z-index:1; left:0; bottom:0;}

+ 0 - 5
lib/graceUI/components/graceNvueSwiperCard.vue

@@ -96,11 +96,6 @@ export default{
 						url:url
 					});
 					break;
-				case 'redirect':
-					uni.redirectTo({
-						url:url
-					});
-					break;
 				default:
 					break;
 			}

+ 6 - 6
lib/graceUI/components/graceNvueTouch.vue

@@ -1,8 +1,8 @@
 <template>
-	<view @touchstart="touchstart" @touchmove.stop="touchmove" @touchend.stop="touchend">
+	<view @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
 		<slot></slot>
-	</view>
-</template>
+	</view>
+</template>
 <script>
 export default{
 	
@@ -111,8 +111,8 @@ export default{
 			return Math.round(s * 10000) / 10000;
 		}
 	}
-}
-</script>
+}
+</script>
 <style>
-	
+	
 </style>

+ 10 - 5
lib/graceUI/components/graceNvueTree.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<view v-for="(tree,index) in treesIN" :key="index">
-			<view class="grace-tree" :data-tree="tree" :data-treeindexs="indexesIn" :data-index="index" :data-treelevel="level" 
+			<view class="grace-tree" :data-havsons="tree.children" :data-treeindexs="indexesIn" :data-index="index" :data-treelevel="level" 
 			:style="{paddingLeft:(indent*level)+'rpx'}" @tap.stop="taped" :data-cancheck="(allCanCheck || !tree.children)">
 				<view class="grace-tree-icons" v-if="type == 'text' && isIcon" style="width:38rpx;">
 					<text class="grace-tree-icons-text grace-icons icon-arrow-down" v-if="tree.children">&#xe62d;</text>
@@ -17,7 +17,7 @@
 				<text class="grace-tree-label" :style="{lineHeight:lineHeight,fontSize:fontSize, color:fontColor}">{{tree.label}}</text>
 			</view>
 			<view>
-				<graceTree 
+				<graceTree v-if="!fold" 
 				:trees="tree.children" :indent="indent" :level="level+1" :lineHeight="lineHeight" :allCanCheck="allCanCheck" 
 				:fontSize="fontSize" :fontColor="fontColor" :isIcon="isIcon" :checkedId="checkedId" :checkedIds="checkedIds" 
 				:type="type" :indexes="[indexesIn,index]" @taped="tapbase"></graceTree>
@@ -42,12 +42,14 @@ export default{
 		checkedId : {type:[String, Number], default:'-1'},
 		checkedIds : {type:Array, default:function () {return [];}},
 		checkedColor:{type:String, default:'#3688FF'},
-		allCanCheck: {type:Boolean, default:true}
+		allCanCheck: {type:Boolean, default:true},
+		isFold : {type:Boolean, default:true}
 	},
 	data() {
 		return {
 			treesIN:[],
-			indexesIn : []
+			indexesIn : [],
+			fold:false
 		}
 	},
 	created:function(){
@@ -62,13 +64,16 @@ export default{
 	},
 	methods:{
 		taped : function(e){
-			var tree       = e.currentTarget.dataset.tree;
+			var havsons       = e.currentTarget.dataset.havsons;
 			var treeindexs = e.currentTarget.dataset.treeindexs;
 			treeindexs = treeindexs.split(',');
 			var index      = e.currentTarget.dataset.index;
 			treeindexs.push(index);
 			treeindexs.shift();
 			if(this.type == 'text'){
+				if(this.isFold){
+					if(havsons){this.fold = !this.fold; return;}
+				}
 				this.tapbase(treeindexs);
 			}else{
 				var cancheck = e.currentTarget.dataset.cancheck;

+ 60 - 0
lib/graceUI/components/gracePK.vue

@@ -0,0 +1,60 @@
+<template>
+	<view class="grace-pk" :style="{height:height,borderRadius:borderRadius}">
+		<view class="grace-pk-item">
+			<text class="grace-pk-title">{{title[0]}}</text>
+			<view class="grace-pk-btn-wrap" v-if="status == 'button'">
+				<view class="grace-pk-btn" hover-class="grace-pk-btn-hv" 
+				data-index="left" @tap="choose">{{btnName}}</view>
+			</view>
+			<view class="grace-pk-btn-wrap" v-if="status == 'progress'">
+				<progress :percent="progress[0]" stroke-width="3" class="grace-pk-progress" active 
+				activeColor="#FFFFFF" border-radius="10" backgroundColor="#3699ff"/>
+			</view>
+			<view class="grace-pk-text" v-if="status == 'progress'">{{progress[2]}}</view>
+		</view>
+		<view class="grace-pk-item">
+			<text class="grace-pk-title" style="text-align:right;">{{title[1]}}</text>
+			<view class="grace-pk-btn-wrap" style="justify-content:flex-end;" v-if="status == 'button'">
+				<view class="grace-pk-btn" hover-class="grace-pk-btn-hv" 
+				style="color:#FF0036;" data-index="right" @tap="choose">{{btnName}}</view>
+			</view>
+			<view class="grace-pk-btn-wrap" style="justify-content:flex-end;" v-if="status == 'progress'">
+				<progress :percent="progress[1]" active stroke-width="3" class="grace-pk-progress" 
+				activeColor="#FFFFFF" border-radius="10" backgroundColor="#FF6666"/>
+			</view>
+			<view class="grace-pk-text" style="text-align:right;" v-if="status == 'progress'">{{progress[3]}}</view>
+		</view>
+		<view class="grace-pk-icon">
+			<image src="https://img-cdn-qiniu.dcloud.net.cn/uploads/article/20200806/84515c21a39e8382addbeca53462e3a0.png" 
+			mode="widthFix" style="width:88rpx; height:88rpx;"></image>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		height       : {type:String, default:'260rpx'},
+		borderRadius : {type:String, default:'8rpx'},
+		title        : {type:Array, default:function(){return ['',''];}},
+		btnName      : {type:String, default:'站队'},
+		status       : {type:String, default:'button'},
+		progress     : {type:Array, default:function(){return [80,20,'8000 票', '2000 票'];}}
+	},
+	methods:{
+		choose:function (e) {
+			this.$emit('choose', e.currentTarget.dataset.index);
+		}
+	}
+}
+</script>
+<style>
+.grace-pk{display:flex; flex-direction:row; justify-content:space-between; background-image:url(https://img-cdn-qiniu.dcloud.net.cn/uploads/article/20200806/24692285f85690abbc762512ce22d2c5.png); background-repeat:repeat-y; background-size:100% auto; background-position:left center; position:relative;}
+.grace-pk-item{width:750rpx; overflow:hidden; padding:0rpx 35rpx; box-sizing:border-box; display:flex; flex-direction:column; justify-content:center;}
+.grace-pk-title{display:block; color:#FFFFFF; font-size:50rpx; line-height:60rpx;}
+.grace-pk-btn-wrap{display:flex; flex-direction:row; margin-top:32rpx;}
+.grace-pk-btn{width:150rpx; height:50rpx; line-height:50rpx; text-align:center; background-color:#FFFFFF; font-size:22rpx; border-radius:100rpx; color:#3687FF;}
+.grace-pk-btn-hv{font-weight:bold;}
+.grace-pk-progress{width:200rpx;}
+.grace-pk-text{font-size:22rpx; color:#FFFFFF; line-height:50rpx; margin-top:2px;}
+.grace-pk-icon{width:88rpx; height:88rpx; background-color:#FFFFFF; border-radius:100rpx; font-size:0; position:absolute; top:50%; left: 50%; transform: translate(-50%, -50%); padding:20rpx;}
+</style>

+ 20 - 20
lib/graceUI/components/gracePage.vue

@@ -4,7 +4,7 @@
 		<view v-if="customHeader">
 			<view class="grace-page-header" :style="{'z-index':headerIndex, background:headerBG, borderBottomWidth:borderWidth, borderBottomColor:borderColor}">
 				<!-- 沉浸式状态栏 -->
-				<view class="grace-page-status-bar" 
+				<view class="grace-page-status-bar" 
 				:style="{height:statusBarHeight+'px', background:statusBarBG}"></view>
 				<!-- 头部核心 -->
 				<view class="grace-page-header-nav" id="gracePageHeader">
@@ -33,12 +33,12 @@
 			<!-- #endif -->
 		</view>
 		<!-- 右下角悬浮按钮 -->
-		<view class="gui-page-rb-area" 
-		:style="{right:rbRight+'rpx', bottom:rbBottom+'rpx', width:rbWidth+'rpx', zIndex:rbIndex}">
-			<slot name="gRTArea"></slot>
+		<view class="gui-page-rb-area" 
+		:style="{right:rbRight+'rpx', bottom:rbBottom+'rpx', width:rbWidth+'rpx', zIndex:rbIndex}">
+			<slot name="gRTArea"></slot>
 		</view>
 		<!-- 全屏 loading -->
-		<view class="grace-page-loading" @tap.stop="" @touchmove.stop="" :style="{background:loadingBG}" v-if="isLoading">
+		<view class="grace-page-loading" @tap.stop="" @touchmove.stop.prevent="" :style="{background:loadingBG}" v-if="isLoading">
 			<view class="grace-page-loading-point">
 				<view class="grace-page-loading-points animate1" :style="{background:loadingPointBg}"></view>
 				<view class="grace-page-loading-points animate2" :style="{background:loadingPointBg}"></view>
@@ -61,13 +61,13 @@ export default{
 		isSwitchPage :  { type : Boolean, default : false },
 		rbWidth      : { type : Number, default : 100},
 		rbBottom     : { type : Number, default : 100 },
-		rbRight      : { type : Number, default : 20 },
-		rbIndex      : { type : Number,  default : 1 },
-		borderWidth  : { type : String,  default : '0' },
+		rbRight      : { type : Number, default : 20 },
+		rbIndex      : { type : Number,  default : 1 },
+		borderWidth  : { type : String,  default : '0' },
 		borderColor  : { type : String,  default : '#D1D1D1'},
 		loadingBG    : { type : String,  default : 'rgba(255,255,255, 0.1)'},
 		isLoading    :  { type : Boolean, default : false },
-		loadingPointBg : {type : String,  default : '#3688FF'},
+		loadingPointBg : {type : String,  default : '#3688FF'},
 		bounding     : { type : Boolean, default : true }
 	},
 	data() {
@@ -83,10 +83,10 @@ export default{
 			system.model = system.model.replace(' ', '');
 			system.model = system.model.toLowerCase();
 			if(system.model.indexOf('iphonex') != -1 || system.model.indexOf('iphone11') != -1){this.iphoneXButtomHeight = uni.upx2px(50);}
-			if(!this.customHeader){return ;}
-			this.statusBarHeight = system.statusBarHeight;
-			// #ifdef MP-ALIPAY
-			this.statusBarHeight = 0;
+			if(!this.customHeader){return ;}
+			this.statusBarHeight = system.statusBarHeight;
+			// #ifdef MP-ALIPAY
+			this.statusBarHeight = 0;
 			// #endif
 			// #ifndef MP-ALIPAY
 				// #ifdef MP-WEIXIN
@@ -104,13 +104,13 @@ export default{
 	}
 }
 </script>
-<style>
-/* #ifndef MP */
-page{width:100%; min-height:100%; display:flex; flex-direction:column; flex:1;}
-/* #endif */
-.grace-sbody{display:flex; flex-direction:column; width:100%; min-height:100%; flex:1;}
-/* #ifdef MP */
-.grace-sbody{min-height:100vh;}
+<style>
+/* #ifndef MP */
+page{width:100%; min-height:100%; display:flex; flex-direction:column; flex:1;}
+/* #endif */
+.grace-sbody{display:flex; flex-direction:column; width:100%; min-height:100%; flex:1;}
+/* #ifdef MP */
+.grace-sbody{min-height:100vh;}
 /* #endif */
 .grace-page-header{width:100%; position:fixed; left:0; top:0; z-index:99; border-bottom:0px solid #FFFFFF;}
 .grace-page-status-bar{width:100%; height:0;}

+ 66 - 46
lib/graceUI/components/gracePopupMenu.vue

@@ -1,7 +1,10 @@
 <template name="gracePopupMenu">
 	<view>
-		<view class="grace-popup-mask" v-if="show" @tap.stop="hideMenu" @touchmove.stop="" :style="{background:background, zIndex:zIndex}"></view>
-		<view class="grace-popup-menu" v-if="show" :style="{top:top+'px', width:menuWidth, zIndex:zIndex+1}">
+		<view class="grace-popup-mask" @tap.stop="hideMenu" @touchmove.stop.prevent="" 
+		:style="{background:background, zIndex:zIndex, top:showIn?'0px':'-3000px'}"></view>
+		<view class="grace-popup-menu" 
+		:class="[showIn?'grace-shade-in':'grace-shade-out']"
+		:style="{top:top+'px', width:menuWidth, zIndex:zIndex+1, height:showIn?'':'0rpx'}">
 			<view :class="['grace-rows', 'arrow-d-'+arrowDirection]" v-if="isArrow">
 				<view class="arrow-up" :style="{borderBottomColor:bgColor, margin:arrowMargin}"></view>
 			</view>
@@ -10,56 +13,73 @@
 	</view>
 </template>
 <script>
-	export default {
-		name: "gracePopupMenu",
-		props: {
-			show:{
-				type : Boolean,
-				default : false
-			},
-			top:{
-				type : Number,
-				default : 0
-			},
-			bgColor:{
-				type : String,
-				default :'#FFFFFF'
-			},
-			menuWidth :{
-				type : String,
-				default : '258rpx'
-			},
-			background : {
-				type : String,
-				default : 'rgba(0,0,0, 0.3)'
-			},
-			borderRadius:{
-				type : String,
-				default:'0rpx'
-			},
-			zIndex : {type:Number, default:3},
-			isArrow:{type:Boolean, default:true},
-			arrowDirection:{type:String, default:"right"},
-			arrowMargin:{type:String, default:"0 12rpx"}
+export default {
+	name: "gracePopupMenu",
+	props: {
+		show:{
+			type : Boolean,
+			default : false
 		},
-		methods: {
-			hideMenu : function() {
-				this.$emit('hideMenu');
-			}
+		top:{
+			type : Number,
+			default : 0
 		},
+		bgColor:{
+			type : String,
+			default :'#FFFFFF'
+		},
+		menuWidth :{
+			type : String,
+			default : '258rpx'
+		},
+		background : {
+			type : String,
+			default : 'rgba(0,0,0, 0.3)'
+		},
+		borderRadius:{
+			type : String,
+			default:'0rpx'
+		},
+		zIndex : {type:Number, default:3},
+		isArrow:{type:Boolean, default:true},
+		arrowDirection:{type:String, default:"right"},
+		arrowMargin:{type:String, default:"0 12rpx"}
+	},
+	data() {
+		return {
+			showIn : false
+		}
+	},
+	created:function(){
+		if(this.show){this.open();}else{this.hide();}
+	},
+	watch:{
+		show : function(val,oval){
+			this.showIn = val;
+		}
+	},
+	methods: {
+		hideMenu : function() {
+			this.$emit('hideMenu');
+		},
+		open : function(){
+			this.showIn = true;
+		},
+		hide:function(){
+			this.showIn = false;
+		}
 	}
+}
 </script>
 <style scoped>
-.grace-popup-menu{width:258rpx; padding:10rpx; right:0px; top:0px; position:absolute; z-index:3;}
-.grace-popup-mask{background:rgba(0,0,0, 0.3); width:100%; height:100%; position:fixed; left:0; top:0; z-index:4;}
-.arrow-up {
-    width:0; 
-    height:0; 
-    border-left:18rpx solid transparent;
-    border-right:18rpx solid transparent;
-    border-bottom:18rpx solid #FFFFFF;
-}
+.grace-popup-menu{width:258rpx; padding:10rpx; right:0px; overflow:hidden; top:0px; position:absolute; z-index:3; opacity:0;}
+.grace-popup-mask{background:rgba(0,0,0, 0.3); width:100%; height:100%; position:fixed; left:0; top:-3000px; z-index:4;}
+.arrow-up{width:0; height:0; border-left:18rpx solid transparent; border-right:18rpx solid transparent; border-bottom:18rpx solid #FFFFFF;}
 .arrow-d-right{justify-content:flex-end;}
 .arrow-d-center{justify-content:center;}
 .arrow-d-left{justify-content:flex-start;}
+.grace-shade-in{animation:grace-shade-in-a 150ms ease-in forwards;}
+@keyframes grace-shade-in-a{0%{transform: scale(0.1); opacity:0;} 100%{transform: scale(1); opacity:1;}}
+.grace-shade-out{animation:grace-shade-out-a 150ms ease-out forwards;}
+@keyframes grace-shade-out-a{0%{opacity:1; height:'';} 100%{ opacity:0; height:0;}}
 </style>

+ 1 - 1
lib/graceUI/components/graceReload.vue

@@ -8,7 +8,7 @@
 			<text class="grace-reload-icon icon-ok" v-if="reloadStatus == 2" :style="{color:reloadColor[reloadStatus]}"></text>
 			<text class="grace-reload-text" :style="{color:reloadColor[reloadStatus]}">{{reloadTxt[reloadStatus]}}</text>
 		</view>
-		<!-- view class="grace-reload-shade" @tap.stop="" @touchstart.stop="" @touchmove.stop="" v-if="reloadStatus != 5"></view -->
+		<!-- view class="grace-reload-shade" @tap.stop="" @touchstart.stop="" @touchmove.stop.prevent="" v-if="reloadStatus != 5"></view -->
 	</view>
 </template>
 <script>

+ 46 - 0
lib/graceUI/components/graceRightMessage.vue

@@ -0,0 +1,46 @@
+<template>
+	<view class="graceRightMessage" v-if="showIn" 
+	:style="{
+		zIndex:zIndex, bottom:bottom, background:background, width:status == 1 ? width : minWidth, 
+		height:height, borderTopLeftRadius:height, borderBottomLeftRadius:height}">
+		<view class="graceRightMessageIcon"><slot name="icon"></slot></view>
+		<view class="graceRightMessageContent"><slot name="content"></slot></view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		zIndex : {type:Number, default:99},
+		bottom : {type:String, default:'150rpx'},
+		width  : {type:String, default:'260rpx'},
+		height : {type:String, default:'80rpx'},
+		minWidth : {type:String, default:'80rpx'},
+		background : {type:String, default:'#3688FF'}
+	},
+	data() {
+		return {
+			showIn : true,
+			status : 1
+		}
+	},
+	methods:{
+		open:function () {
+			this.status = 1;
+		},
+		hide:function(){
+			this.showIn = false;
+		},
+		shrink:function(){
+			this.status = 2;
+		},
+		show:function(){
+			this.showIn = true;
+		}
+	}
+}
+</script>
+<style>
+.graceRightMessage{position:fixed; right:0; bottom:0; padding:10rpx; box-sizing:border-box; overflow:hidden; display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center;}
+.graceRightMessageIcon{text-align:center; flex-shrink:0;}
+.graceRightMessageContent{width:700rpx;}
+</style>

+ 253 - 0
lib/graceUI/components/graceSchedule.vue

@@ -0,0 +1,253 @@
+<template>
+	<view class="grace-schedule-wrap">
+		<view class="grace-schedule-header grace-space-between grace-flex-vcenter">
+			<picker class="grace-flex-center grace-flex-vcenter" 
+			mode="date" :value="currentDayIn" :start="startDate" :end="endDate" @change="selectDate">
+				<text class="grace-schedule-header-date grace-icons">{{cYear}} 年 {{cMonthStr}} 月 &#xe603;</text>
+			</picker>
+			<view class="grace-schedule-today" @tap="gotoToday">返回今天</view>
+		</view>
+		<view class="grace-date-week">
+			<text class="grace-date-weeks" v-for="(item, index) in weeks" :key="index">{{item}}</text>
+		</view>
+		<view class="grace-date-days">
+			<block v-for="(item, index) in days" :key="index">
+				<view class="grace-date-ditems" v-if="item != ''" 
+				:style="{background:currentDayIn == cYear+'-'+cMonthStr+'-'+ item.date ? activeBgColor : bgColor}" 
+				@click="chooseDate(cYear+'-'+cMonthStr+'-'+item.date, item.date)">
+					<text class="grace-date-day" 
+					:class="[currentDayIn == (cYear+'-'+cMonthStr+'-'+item.date) ? 'grace-d-current-txt' : '']">{{item.date}}</text>
+					<text class="grace-date-nl" v-if="isLunar" 
+					:class="[currentDayIn == (cYear+'-'+cMonthStr+'-'+item.date) ? 'grace-d-current-txt' : '']">{{item.nl}}</text>
+					<view class="grace-schedule-point" v-if="item.haveSe" :style="{backgroundColor:pointColor}"></view>
+				</view>
+				<view class="grace-date-ditems" v-else style="background-color:none;"></view>
+			</block>
+		</view>
+		<view class="grace-schedule-line"></view>
+		<view class="grace-schedule-time-list-wrap">
+			<view class="grace-schedule-time-list" v-for="(item, index) in hours" :key="index">
+				<text class="grace-schedule-timer">{{item}}:00</text>
+				<view class="grace-schedule-body">
+					<view class="grace-schedules" v-for="(schedule, idx) in schedulesIn[index]" :key="idx" 
+					@tap="scheduleTap" :data-id="schedule.id" 
+					:style="{background:schedule.bgColor, color:schedule.color}">{{schedule.content}}</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	data() {
+		return {
+			cYear      : 2020,
+			cMonth     : 1,
+			cDay       : 10,
+			cMonthStr  : '01',
+			weeks      : ['一', '二', '三', '四', '五', '六', '日'],
+			days       : [],
+			currentDayIn : '',
+			hours      : ['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'],
+			schedulesIn: [] 
+		}
+	},
+	props:{
+		// 当前默认日期
+		currentDate   : {type:String, default:""},
+		bgColor       : {type:String, default:"#F8F8F8"},
+		activeBgColor : {type:String, default:"#3688FF"},
+		isLunar       : {type:Boolean, default:true },
+		startDate     : {type:String, default:'1950-01-01'},
+		endDate       : {type:String, default:'2050-01-01'},
+		schedules     : {type:Array, default:function () {return []}},
+		pointColor    : {type:String, default:"#FF0036"}
+	},
+	created:function(){
+		this.currentDayIn = this.currentDate;
+		this.initTime();
+		this.getSchedulesIn();
+	},
+	methods:{
+		initTime : function(){
+			if(this.currentDayIn == ''){
+				var dateObj        = new Date();
+				this.cYear         = Number(dateObj.getFullYear());
+				this.cMonth        = Number(dateObj.getMonth() + 1);
+				this.cMonthStr     = this.cMonth < 10 ? '0' + this.cMonth : this.cMonth;
+				this.cDay          = dateObj.getDate();
+				this.cDay          = this.cDay < 10 ? '0' + this.cDay : this.cDay;
+				this.currentDayIn  = this.cYear + '-' + this.cMonthStr + '-' + this.cDay;
+				this.changeMonth();
+			}else{
+				var dates          = this.currentDayIn.split(' ');
+				if (!dates[1]) { dates[1] = '';}
+				var dayArr         = dates[0].split('-');
+				this.cYear         = Number(dayArr[0]);
+				this.cMonth        = dayArr[1];
+				this.cDay          = dayArr[2];
+				var reg            = new RegExp('^0[0-9]+$');
+				if(reg.test(this.cMonth)){this.cMonth = this.cMonth.substr(1,1);}
+				this.cMonth        = Number(this.cMonth);
+				this.cMonthStr     = this.cMonth < 10 ? '0'+this.cMonth : this.cMonth;
+				this.currentDayIn  = dates[0];
+				this.currentTimeIn = dates[1];
+				this.changeMonth();
+			}
+		},
+		changeMonth:function(){
+			var daysList  = [];
+			var days      = this.getDaysInOneMonth();
+			var startWeek = this.getDay();
+			var forSteps  = 0;
+			for (var i = (0 - startWeek); i < days; i++){
+				if(i >= 0){
+					daysList[forSteps] = {date : i >= 9 ? i + 1 : '0' + (i+1), nl : ''};
+					daysList[forSteps].nl = GetLunarDay(this.cYear, this.cMonth, i + 1);
+					daysList[forSteps].haveSe = this.haveSchedule(daysList[forSteps].date);
+				}else{
+					daysList[forSteps] = '';
+				}
+				forSteps++;
+			}
+			this.days    = daysList;
+		},
+		haveSchedule : function (day) {
+			var cDay = this.cYear+'-'+this.cMonthStr+'-'+day;
+			for(let i = 0; i < this.schedules.length; i++){
+				if(this.schedules[i].datetime.indexOf(cDay) != -1){
+					return true;
+				}
+			}
+			return false;
+		},
+		getDaysInOneMonth : function (){
+			var d = new Date(this.cYear, this.cMonth, 0);
+			return d.getDate();
+		},
+		getDay : function (){
+			var d = new Date(this.cYear, this.cMonth - 1, 0);
+			return d.getDay();
+		},
+		selectDate : function(e){
+			this.currentDayIn = e.detail.value;
+			this.initTime();
+			this.getSchedulesIn();
+			this.$emit('selectDate', e.detail.value);
+		},
+		chooseDate: function (sedDate) {
+			this.currentDayIn = sedDate;
+			this.getSchedulesIn();
+			this.$emit('chooseDate', sedDate);
+		},
+		getSchedulesIn : function (){
+			var res = [];
+			for(let i = 0; i < this.hours.length; i++){
+				var ctime = this.currentDayIn + ' ' + this.hours[i] + ':00';
+				res.push([]);
+				for(let ii = 0; ii < this.schedules.length; ii++){
+					if(this.schedules[ii].datetime == ctime){
+						res[i].push(this.schedules[ii]);
+					}
+				}
+			}
+			this.schedulesIn = res;
+		},
+		scheduleTap : function (e) {
+			var id = e.currentTarget.dataset.id;
+			this.$emit('scheduleTap', id);
+		},
+		gotoToday : function(){
+			var dateObj        = new Date();
+			this.cYear         = Number(dateObj.getFullYear());
+			this.cMonth        = Number(dateObj.getMonth() + 1);
+			this.cMonthStr     = this.cMonth < 10 ? '0' + this.cMonth : this.cMonth;
+			this.cDay          = dateObj.getDate();
+			this.cDay          = this.cDay < 10 ? '0' + this.cDay : this.cDay;
+			this.currentDayIn  = this.cYear + '-' + this.cMonthStr + '-' + this.cDay;
+			this.changeMonth();
+			this.getSchedulesIn();
+			this.$emit('gotoToday', this.currentDayIn);
+		}
+	}
+}
+var CalendarData = new Array(100);
+var madd = new Array(12);
+var tgString = "甲乙丙丁戊己庚辛壬癸";
+var dzString = "子丑寅卯辰巳午未申酉戌亥";
+var numString = "一二三四五六七八九十";
+var monString = "正二三四五六七八九十冬腊";
+var weekString = "日一二三四五六";
+var sx = "鼠牛虎兔龙蛇马羊猴鸡狗猪";
+var cYear, cMonth, cDay, TheDate;
+CalendarData = new Array(0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5, 0x50DA9, 0x5AD, 0x2B6, 0x3126E, 0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A, 0x4155B, 0x25D, 0x92D, 0x2192B, 0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5, 0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6, 0x414AE, 0xA57, 0x526, 0x31D26, 0xD95, 0x70B55, 0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54, 0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B, 0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957, 0x5092F, 0x497, 0x64B, 0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96, 0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D, 0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5, 0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95);
+madd[0] = 0;
+madd[1] = 31;
+madd[2] = 59;
+madd[3] = 90;
+madd[4] = 120;
+madd[5] = 151;
+madd[6] = 181;
+madd[7] = 212;
+madd[8] = 243;
+madd[9] = 273;
+madd[10] = 304;
+madd[11] = 334;
+function GetBit(m, n){return (m >> n) & 1;}
+//农历转换
+function e2c() {
+	TheDate = (arguments.length != 3) ? new Date() : new Date(arguments[0], arguments[1], arguments[2]);
+	var total, m, n, k;
+	var isEnd = false;
+	var tmp = TheDate.getYear();
+	if (tmp < 1900) {tmp += 1900;}
+	total = (tmp - 1921) * 365 + Math.floor((tmp - 1921) / 4) + madd[TheDate.getMonth()] + TheDate.getDate() - 38;
+	if (TheDate.getYear() % 4 == 0 && TheDate.getMonth() > 1) {total++;}
+	for (m = 0; ; m++) {
+		k = (CalendarData[m] < 0xfff) ? 11 : 12;
+		for (n = k; n >= 0; n--) {
+			if (total <= 29 + GetBit(CalendarData[m], n)) {isEnd = true; break;}
+			total = total - 29 - GetBit(CalendarData[m], n);
+		}
+		if (isEnd) break;
+	}
+	cYear = 1921 + m;
+	cMonth = k - n + 1;
+	cDay = total;
+	if (k == 12) {
+		if (cMonth == Math.floor(CalendarData[m] / 0x10000) + 1) {cMonth = 1 - cMonth;}
+		if (cMonth > Math.floor(CalendarData[m] / 0x10000) + 1) {cMonth--;}
+	}
+}
+function GetcDateString() {
+	var tmp = "";
+	tmp += (cDay < 11) ? "初" : ((cDay < 20) ? "十" : ((cDay < 30) ? "廿" : "三十"));
+	if (cDay % 10 != 0 || cDay == 10) {tmp += numString.charAt((cDay - 1) % 10);}
+	return tmp;
+}
+function GetLunarDay(solarYear, solarMonth, solarDay) {
+	if (solarYear < 1921) {return "";}
+	solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11;
+	e2c(solarYear, solarMonth, solarDay);
+	return GetcDateString();
+}
+</script>
+<style>
+.grace-schedule-wrap{width:702rpx; margin:0 auto;}
+.grace-schedule-header-date{display:block; height:100rpx; line-height:100rpx; color:#323232; font-size:32rpx; margin:0 20rpx;}
+.grace-date-week{width:702rpx; display:flex; flex-wrap:nowrap; flex-direction:row; justify-content:center;}
+.grace-date-weeks{display:block; width:100rpx; height:60rpx; font-size:26rpx; line-height:60rpx; color:#666666; text-align:center;}
+.grace-date-days{width:702rpx; display:flex; flex-direction:row; flex-wrap:wrap;}
+.grace-date-ditems{width:80rpx; height:80rpx; display:flex; flex-direction:column; align-items:center; justify-content:center; margin:3px 10rpx; border-radius:80rpx; position:relative;}
+.grace-d-current-txt{color:#FFFFFF !important;}
+.grace-date-day{display:block; width:100%; height:38rpx; line-height:38rpx; text-align:center; font-size:28rpx;}
+.grace-date-nl{display:block; width:100%; height:26rpx; line-height:26rpx; color:#888888; font-size:20rpx; text-align:center;}
+.grace-schedule-line{height:20rpx; border-bottom:1px solid #F8F8F8;}
+.grace-schedule-time-list{margin-top:28rpx; display:flex; flex-direction:row; flex-wrap:nowrap;}
+.grace-schedule-timer{display:block; width:100rpx; font-size:22rpx; color:#999999; line-height:36rpx; flex-shrink:0;}
+.grace-schedule-body{width:700rpx; border-top:1px solid #F8F8F8; padding:5rpx 0; margin-top:15rpx;}
+.grace-schedules{padding:10rpx; line-height:30rpx; font-size:22rpx; margin-top:15rpx; border-radius:8rpx; width:auto;}
+.grace-schedule-time-list-wrap{padding:20rpx;}
+.grace-schedule-today{line-height:30rpx; height:30rpx; font-size:22rpx; color:#828282; padding:10rpx 20rpx; margin-left:30rpx; border-radius:8rpx; border:1px solid #F1F2F3;}
+.grace-schedule-point{width:18rpx; height:18rpx; border-radius:10rpx; background-color:#FF0036; position:absolute; right:5rpx; top:5rpx; z-index:1;}
+</style>

+ 27 - 10
lib/graceUI/components/graceSelectImg.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="grace-add-list">
 		<view class="grace-add-list-items" v-for="(item, index) in imgLists" :key="index">
-			<image :src="item" :data-imgurl="item" @tap="showImgs" class="grace-add-list-img" :mode="imgMode"></image>
+			<image :src="item.url" :data-imgurl="item.url" @tap="showImgs" class="grace-add-list-img" :mode="imgMode"></image>
 			<view class="grace-add-list-remove grace-icons icon-close" :style="{color:closeBtnColor}" @tap="removeImg" :id="'grace-items-img-'+index"></view>
 		</view>
 		<view class="grace-add-list-items grace-add-list-btn" @tap="addImg" v-if="imgLists.length < maxFileNumber">
@@ -42,24 +42,32 @@ export default {
 		}
 	},
 	created:function () {
-		this.imgLists = this.items;
+		this.initImgs();
 	},
 	watch:{
-		imgLists : function(newVal, oldVal){
-			this.$emit('change', newVal);
+		items:function(){
+			this.initImgs();
 		}
 	},
     methods:{
+		initImgs : function(){
+			var imgs = [];
+			for(let i = 0; i < this.items.length; i++){
+				imgs.push({url:this.items[i],  progress : 100});
+			}
+			this.imgLists = imgs;
+		},
         addImg : function(){
             var num = this.maxFileNumber - this.imgLists.length;
             if(num < 1){return false;}
-            //uni.showLoading({title:""});
             uni.chooseImage({
                 count: num,
                 sizeType: ['compressed'],
                 success:(res) => {
-                    this.imgLists = this.imgLists.concat(res.tempFilePaths);
-                    //uni.hideLoading();
+					for(let i = 0; i < res.tempFilePaths.length; i++){
+						this.imgLists.push({url:res.tempFilePaths[i], progress:0})
+					}
+                    this.$emit('change', this.imgLists);
                 },
 				fail:function(){
 					//uni.hideLoading();
@@ -68,17 +76,26 @@ export default {
         },
         removeImg : function(e){
             var index = e.currentTarget.id.replace('grace-items-img-', '');
-            this.imgLists.splice(index, 1);
+			var removeImg =  this.imgLists.splice(index, 1);
+			this.$emit('removeImg', removeImg[0]);
+			this.$emit('change', this.imgLists);
         },
         showImgs : function(e){
             var currentImg = e.currentTarget.dataset.imgurl;
+			var imgs = [];
+			for(let i = 0; i < this.imgLists.length; i++){
+				imgs.push(this.imgLists[i].url);
+			}
             uni.previewImage({
-              urls: this.imgLists,
+              urls: imgs,
               current : currentImg
             })
         },
 		setItems : function(items){
-			this.imgLists = items;
+			this.imgLists = [];
+			for(let i = 0; i < items.length; i++){
+				this.imgLists.push({url : items[i], progress : 100});
+			}
 		}
     }
 }

+ 4 - 2
lib/graceUI/components/graceSelectImgAndUpload.vue

@@ -99,7 +99,8 @@ export default {
         },
         removeImg : function(e){
             var index = e.currentTarget.id.replace('grace-items-img-', '');
-            this.imgLists.splice(index, 1);
+            var removeImg =  this.imgLists.splice(index, 1);
+			this.$emit('removeImg', removeImg[0]);
         },
         showImgs : function(e){
             var currentImg = e.currentTarget.dataset.imgurl;
@@ -186,8 +187,9 @@ export default {
 		},
 		// 设置默认值
 		setItems : function(items){
+			this.imgLists = [];
 			for(let i = 0; i < items.length; i++){
-				this.imgLists.push({url : items[i], progress : 100, error : false});
+				this.imgLists.push({url : items[i], progress : 100});
 			}
 		}
     }

+ 17 - 10
lib/graceUI/components/graceSelectList.vue

@@ -1,14 +1,18 @@
 <template>
 	<view class="select-list">
 		<view v-for="(item, index) in dataIn" :key="index" class="select-list-item" :data-index="index" @tap.stop="choose">
-			<image :src="item.img" class="select-list-img" v-if="item.img" mode="widthFix" :style="{width:imgSize[0], height:imgSize[1]}"></image>
-			<view class="select-list-body" :class="[isBorder?'grace-border-b':'']">
-				<view class="select-list-content" :style="{fontSize:fontSize, lineHeight:lineHeight, color:itemColor}">{{item.title}}</view>
+			<image :src="item.img" class="select-list-img" v-if="item.img" mode="widthFix" 
+			:style="{width:imgSize[0], height:imgSize[1], borderRadius:imgBorderRadius}"></image>
+			<view class="select-list-body" :class="[isBorder?'grace-border-b':'']" :style="{borderColor:borderColor}">
+				<view class="select-list-content">
+					<view :style="{fontSize:fontSize, lineHeight:lineHeight, color:itemColor}">{{item.title}}</view>
+					<view class="select-list-desc" v-if="item.desc">{{item.desc}}</view>
+				</view>
 				<view class="select-list-icon grace-icons" v-if="item.checked" :style="{color:item.checked ? checkColor : '#A5A7B2'}">&#xe60f;</view>
 			</view>
 		</view>
-	</view>
-</template>
+	</view>
+</template>
 <script>
 export default{
 	props:{
@@ -16,10 +20,12 @@ export default{
 		checkColor:{type:String, default:"#3688FF"},
 		type : { type: String, default: "radio"},
 		imgSize:{type:Array, default:function(){return ['68rpx','68rpx'];}},
+		imgBorderRadius:{type: String, default: "60rpx"},
 		fontSize:{type: String, default: "28rpx"},
 		isBorder:{type:Boolean, default:true},
 		lineHeight:{type: String, default: "50rpx"},
-		itemColor:{type:String, default:"#323232"}
+		itemColor:{type:String, default:"#323232"},
+		borderColor:{type:String, default:"#F6F6F6"}
 	},
 	data() {
 		return {
@@ -64,13 +70,14 @@ export default{
 			}
 		}
 	}
-}
-</script>
+}
+</script>
 <style>
 .select-list{}
 .select-list-item{display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center; font-size:0;}
 .select-list-icon{width:60rpx; line-height:60rpx; text-align:center; flex-shrink:0; font-size:32rpx; color:#A5A7B2; font-weight:700; margin-left:28rpx;}
 .select-list-img{flex-shrink:0; border-radius:60rpx; margin-right:28rpx;}
 .select-list-body{width:700rpx; display:flex; flex-wrap:nowrap; flex-direction:row; align-items:center;}
-.select-list-content{width:200rpx; flex:1; overflow:hidden; padding:25rpx 0;}
-</style>
+.select-list-content{width:200rpx; flex:1; overflow:hidden; padding:25rpx 0;}
+.select-list-desc{font-size:22rpx; color:#828282; line-height:40rpx;}
+</style>

+ 34 - 16
lib/graceUI/components/graceSelectMenu.vue

@@ -5,15 +5,22 @@
 			<text class="grace-select-menu-icon icon-allow-b" v-if="!show"></text>
 			<text class="grace-select-menu-icon icon-allow-t" v-if="show"></text>
 		</view>
-		<view class="grace-select-menu" :style="{top : top +'px', height:heightIn+'px', zIndex:zIndex}" @click.stop="close" v-if="show">
+		<view class="grace-select-menu" :style="{top : top +'px', height:heightIn+'px', zIndex:zIndex}" @click.stop="close" @touchmove.stop.prevent="" v-if="show">
 			<view style="height:92rpx; width:100%; flex-shrink:0;"></view>
 			<scroll-view scroll-y class="grace-select-menus" :style="{padding:padding}">
+				<view @tap.stop="" class="grace-select-item" v-if="isInput" 
+				style="display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center;">
+					<view class="grace-select-input-wrap">
+						<input type="text" v-model="inputVal" class="grace-select-input" @confirm="addTag" :placeholder="placeholder" />
+					</view>
+					<view class="grace-select-input-btn" @tap.stop="addTag">{{addBtnName}}</view>
+				</view>
 				<view :class="['grace-select-item', index == currentIndex ? 'grace-selected' : '']" 
 				v-for="(item, index) in items" :style="{color : index == currentIndex ? activeColor : color}"
 				:key="index" :data-index="index" @click.stop="select">
 					<text class="grace-selected-icon" v-if="index == currentIndex"></text>
 					<text :style="{fontSize:fontSize}">{{item}}</text>
-				</view>
+				</view>
 				<view style="height:100rpx; width:100%"></view>
 			</scroll-view>
 		</view>
@@ -24,9 +31,7 @@ export default {
 	props:{
 		items : {
 			type : Array,
-			default : function () {
-				return []
-			}
+			default : function () { return [] }
 		},
 		show : {
 			type : Boolean,
@@ -51,25 +56,30 @@ export default {
 		isH5header : {
 			type : Boolean,
 			default : true
-		},
-		fontSize : {
-			type : String,
-			default : '26rpx'
-		},
-		padding:{
-			type : String,
-			default : "0 20rpx"
+		},
+		fontSize : {
+			type : String,
+			default : '26rpx'
+		},
+		padding:{
+			type : String,
+			default : "0 20rpx"
 		},
 		zIndex:{
 			type : Number,
 			default : 9999
-		}
+		},
+		isInput:{type:Boolean, default:false},
+		placeholder:{type:String, default:"自定义"},
+		addBtnName:{type:String, default:"+ 添加"}
 	},
 	data() {
 		return {
 			currentIndex : 0,
-			top : 0,
-			heightIn : 200
+			top          : 0,
+			heightIn     : 200,
+			showRes      : [],
+			inputVal     : ''
 		}
 	},
 	watch:{
@@ -106,6 +116,11 @@ export default {
 			this.currentIndex = index;
 			this.$emit('select', index);
 			this.close();
+		},
+		addTag : function () {
+			if(this.inputVal == ''){return ;}
+			this.$emit('submit', this.inputVal);
+			this.inputVal = '';
 		}
 	}
 }
@@ -123,4 +138,7 @@ export default {
 .grace-selected{font-weight:bold;}
 .grace-selected-icon{margin-right:15rpx; font-family:"grace-iconfont";}
 .grace-selected-icon:after{content:"\e7f8";}
+.grace-select-input-wrap{width:700rpx;}
+.grace-select-input{line-height:60rpx; padding:25rpx 0; font-size:28rpx;}
+.grace-select-input-btn{width:120rpx; line-height:60rpx; height:60rpx; text-align:center; background:#F8F8F8; font-size:24rpx; border-radius:6rpx; color:#3688FF; flex-shrink:0;}
 </style>

+ 12 - 5
lib/graceUI/components/graceSelectTags.vue

@@ -58,10 +58,11 @@ export default{
 						indexs.push(i);
 					}
 				}
-				this.$emit("change", sedRes, this.datas, indexs);
+				//this.$emit("change", sedRes, this.datas, indexs);
 			}
 		},
 		graceSelectChange : function(index){
+			// 单选
 			if(this.type == 'radio'){
 				for (var i = 0; i < this.tagsData.length; i++){
 					this.tagsData[i].checked = false;
@@ -70,12 +71,15 @@ export default{
 				this.tagsData[index].checked = true;
 				this.tagsData.splice(index,1,this.tagsData[index]);
 				this.$emit("change", this.tagsData[index].value, this.datas, index);
-			}else{
+			}
+			//  多选
+			else{
 				if(this.tagsData[index].checked){
 					this.tagsData[index].checked = false;
 				}else{
 					this.tagsData[index].checked = true;
 				}
+				this.tagsData.splice(index,1,this.tagsData[index]);
 				var sedRes = [], indexs = [];
 				for (var i = 0; i < this.tagsData.length; i++){
 					if(this.tagsData[i].checked){
@@ -85,11 +89,13 @@ export default{
 				}
 				this.$emit("change", sedRes, this.datas, indexs);
 			}
-		},
+		},
+		// 设置新的选项
 		setItems : function(items){
 			this.tagsData = items;
 			this.initChange();
-		},
+		},
+		// 全不选
 		clearSelected:function(){
 			var newData = [];
 			for(let i = 0; i < this.tagsData.length; i++){
@@ -102,7 +108,8 @@ export default{
 			}else{
 				this.$emit("change", [], this.datas, []);
 			}
-		},
+		},
+		// 全选
 		selectAll : function () {
 			if(this.type == 'radio'){return ;}
 			var newData = [],reDatas = [], reIndex = [];

+ 23 - 10
lib/graceUI/components/graceShade.vue

@@ -1,6 +1,8 @@
 <template>
-	<view class="grace-shade" :style="{zIndex:zIndex, background:background}" v-if="showInReal" @tap.stop="closeShade" @touchmove.stop="">
-		<view :class="[show ? 'grace-shade-in' : 'grace-shade-out']"><slot></slot></view>
+	<view class="grace-shade" 
+	:style="{zIndex:zIndex, background:background, height:shadeShow?'100%':'0px'}" 
+	@tap.stop="closeShade" @touchmove.stop.prevent="">
+		<view :class="[showInReal ? 'grace-shade-in' : 'grace-shade-out']"><slot></slot></view>
 	</view>
 </template>
 <script>
@@ -8,34 +10,45 @@ export default{
 	props:{
 		background : {type:String, default:"rgba(0, 0, 0, 0.1)"},
 		zIndex : {type:Number, default:1},
-		show : {type:Boolean, default:true}
+		show : {type:Boolean, default:false}
 	},
 	data() {
 		return {
+			shadeShow : false,
 			showInReal : false
 		}
 	},
 	created:function(){
-		this.showInReal = this.show;
+		if(this.show){ this.showIt(); }else{ this.hideIt();}
 	},
 	watch:{
 		show:function(val){
-			if(val){this.showInReal = val;}else{
-				setTimeout(()=>{this.showInReal = false}, 200);
-			}
+			if(val){ this.showIt(); }else{ this.hideIt(); }
 		}
 	},
 	methods:{
 		closeShade : function(){
 			this.$emit('closeShade');
+		},
+		showIt : function(){
+			this.shadeShow = true;
+			setTimeout(()=>{
+				this.showInReal = true;
+			}, 50);
+		},
+		hideIt : function(){
+			this.showInReal = false;
+			setTimeout(()=>{
+				this.shadeShow = false;
+			}, 150);
 		}
 	}
 }
 </script>
 <style scoped>
-.grace-shade{position:fixed; width:100%; height:100%; left:0; top:0; bottom:0; z-index:1; background:rgba(255, 255, 255, 1); display:flex; justify-content:center; align-items:center;}
-.grace-shade-in{animation:grace-shade-in-a 200ms ease-in forwards;}
+.grace-shade{position:fixed; width:100%; height:100%; left:0; top:0; bottom:0; overflow:hidden; display:flex; justify-content:center; align-items:center;}
+.grace-shade-in{animation:grace-shade-in-a 150ms ease-in forwards;}
 @keyframes grace-shade-in-a{0%{transform: scale(0.1); opacity:0;} 100%{transform: scale(1); opacity:1;}}
-.grace-shade-out{animation:grace-shade-out-a 200ms ease-in forwards;}
+.grace-shade-out{animation:grace-shade-out-a 150ms ease-out forwards;}
 @keyframes grace-shade-out-a{0%{transform: scale(1); opacity:1;} 100%{transform: scale(0.1); opacity:0;}}
 </style>

+ 2 - 2
lib/graceUI/components/graceSlider.vue

@@ -7,12 +7,12 @@
 		<view class="grace-slider-block" 
 		:style="{background:blockBgColor, height:blockSize+'px', width:blockSize+'px', 'margin-left':xMin+'px'}" 
 		@touchstart.stop="touchstart" 
-		@touchmove.stop="touchmove" 
+		@touchmove.stop.prevent="touchmove" 
 		data-tag="min"></view>
 		<view class="grace-slider-block" 
 		:style="{background:blockBgColor, height:blockSize+'px', width:blockSize+'px', 'margin-left':xMax+'px'}" 
 		@touchstart.stop="touchstart" 
-		@touchmove.stop="touchmove" 
+		@touchmove.stop.prevent="touchmove" 
 		data-tag="max"></view>
 	</view>
 </template>

+ 14 - 7
lib/graceUI/components/graceSpeaker.vue

@@ -1,9 +1,11 @@
 <template name="graceSpeaker">
 	<view class="grace-swiper-msg">
 		<view class="grace-swiper-msg-icon" :class="[iconClass]" :style="{color:iconColor}"></view>
-		<swiper :vertical="vertical" autoplay="true" circular="true" :interval="interval" :style="{height:height}">
-			<swiper-item v-for="(item, index) in msgs" :key="index" :style="{height:height}">
-				<navigator 
+		<swiper class="grace-swiper-msg-swiper" 
+		:vertical="vertical" @change="change" autoplay="true" circular="true" :interval="interval" :style="{height:height}">
+			<swiper-item class="grace-swiper-item" 
+			v-for="(item, index) in msgs" :key="index" :style="{height:height}">
+				<navigator class="grace-swiper-msg-navigator" 
 				:url="item.url" :open-type="item.opentype" 
 				:style="{fontSize:fontSize, fontWeight:fontWeight, color:fontColor, height:height, lineHeight:height}">{{item.title}}</navigator>
 			</swiper-item>
@@ -28,7 +30,7 @@ export default {
 		},
 		interval : {
 		  type : Number,
-		  default: 3000
+		  default: 5000
 		},
 		vertical : {
 		  type : Boolean,
@@ -50,13 +52,18 @@ export default {
 			type  : String,
 			default : "60rpx"
 		}
+	},
+	methods:{
+		change:function (index) {
+			this.$emit('change', index.detail.current);
+		}
 	}
 }
 </script>
 <style scoped>
 .grace-swiper-msg{width:100%; display:flex; flex-wrap:nowrap; align-items:center;}
 .grace-swiper-msg-icon{margin-right:16rpx; display:inline-block; flex-shrink:0;}
-.grace-swiper-msg swiper{width:100%; height:60rpx; overflow:hidden;}
-.grace-swiper-msg swiper-item{overflow:hidden;}
-.grace-swiper-msg navigator{line-height:60rpx; overflow:hidden;}
+.grace-swiper-msg-swiper{width:100%; height:60rpx; overflow:hidden;}
+.grace-swiper-item{overflow:hidden;}
+.grace-swiper-msg-navigator{line-height:60rpx; overflow:hidden;}
 </style>

+ 9 - 1
lib/graceUI/components/graceSwipeList.vue

@@ -78,6 +78,14 @@ export default{
 			this.damping *= 1.2;
 		},
 		thEnd : function(e, index){
+			if(e[1] < 150){
+				if(this.msgsIn[index].x >= 5){
+					this.toZero(index);
+					return;
+				}
+				if(Math.abs(e[0][0]) < 30){this.$emit('itemTap',index);}
+				return ;
+			}
 			var item = this.msgsIn[index];
 			if(item.x < this.btnWidth / 3){item.x = 0;}else{item.x = this.btnWidth;}
 			this.msgsIn.splice(index, 1, item);
@@ -114,4 +122,4 @@ export default{
 .grace-swipe-btns{width:0rpx; position:absolute; z-index:1; right:0; top:0; height:116rpx; display:flex; flex-direction:row; flex-wrap:nowrap;}
 .grace-swipe-btn{width:400rpx; height:125rpx; display:flex; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; box-sizing:border-box; padding:20rpx; overflow:hidden;}
 .grace-swipe-btn-text{line-height:36rpx; height:36rpx; overflow:hidden; display:block; font-size:28rpx; color:#FFFFFF;}
-</style>
+</style>

+ 143 - 133
lib/graceUI/components/graceSwiper.vue

@@ -1,134 +1,144 @@
-<template>
-	<view class="grace-swiper-card-wrap">
-		<swiper :style="{width:width+'rpx', height:heightIn+'rpx'}" class="grace-swiper-card" 
-		:indicator-dots="false" :interval="interval" :circular="true" :autoplay="autoplay" :current="currentIndex" 
-		:previous-margin="spacing+'rpx'" :next-margin="spacing+'rpx'" @change="swiperchange">
-			<swiper-item v-for="(item, index) in swiperItems" :key="index" class="grace-swiper-card-item">
-				<navigator class="grace-swiper-card-nav" :url="item.url" :open-type="item.opentype" hover-class="none" v-if="item.opentype != 'click'" 
-				:style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
-				paddingRight:current != index ? padding +'rpx':'0rpx',
-				paddingTop:current != index ? paddingY +'rpx':'0rpx',
-				paddingBottom:current != index ? paddingY +'rpx':'0rpx'}">
-					<image :style="{
-						borderRadius : borderRadius, 
-						width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
-						height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
-						opacity:current != index ? opacity : 1
-					}" :src="item.img" class="grace-swiper-card-image" />
-				</navigator>
-				<view class="grace-swiper-card-nav" hover-class="none" v-if="item.opentype == 'click'" @tap.stop="taped" :data-index="index" 
-				:style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
-				paddingRight:current != index ? padding +'rpx':'0rpx',
-				paddingTop:current != index ? paddingY +'rpx':'0rpx',
-				paddingBottom:current != index ? paddingY +'rpx':'0rpx'}">
-					<image :style="{
-						borderRadius : borderRadius, 
-						width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
-						height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
-						opacity:current != index ? opacity : 1
-					}" 
-					:src="item.img" class="grace-swiper-card-image" />
-				</view>
-				<view v-if="indicatorType == 'number'" class="grace-indicator-dot-numbers" 
-				:style="{
-					height:indicatorBarHeight+'rpx', backgroundColor:indicatorBarBgColor, 
-					width:current != index ? widthInSamll+'rpx':widthIn+'rpx', 
-					left:current != index ? padding+'rpx':'0rpx', bottom:current != index ? paddingY+'rpx':'0rpx'}">
-					<text class="grace-indicator-dot-text" :style="{paddingLeft:'20rpx', 'fontStyle':'italic', color:titleColor}">{{index+1}}</text>
-					<text class="grace-indicator-dot-text" :style="{'fontSize':'36rpx', color:titleColor}">/</text>
-					<text class="grace-indicator-dot-text" :style="{fontSize:'28rpx', paddingRight:'20rpx', fontStyle:'italic', color:titleColor}">{{swiperItems.length}}</text>
-					<text class="grace-swiper-text" :style="{color:titleColor, fontSize:titleSize, height:indicatorBarHeight+'rpx', lineHeight:indicatorBarHeight+'rpx'}">{{item.title}}</text>
-				</view>
-			</swiper-item>
-		</swiper>
-		<view class="grace-indicator-dots" :style="{
-			width:width+'rpx', height:indicatorBarHeight+'rpx', paddingLeft:spacing+'rpx', paddingRight:spacing+'rpx'}">
-			<view v-for="(item, index) in swiperItems" :key="index" :class="['grace-indicator-dot',current == index ? 'dot-show' : '']" v-if="indicatorType == 'dot'" 
-			:style="{
-				width           : current != index ? indicatorWidth+'rpx' : indicatorActiveWidth +'rpx',
-				height          : indicatorHeight+'rpx',
-				borderRadius    : indicatorRadius+'rpx',
-				backgroundColor : current != index ? indicatorColor : indicatorActiveColor
-			}"></view>
-		</view>
-	</view>
-</template>
-<script>
-export default{
-	props:{
-		width:{ type : Number, default : 750 },
-		height:{ type : Number, default : 300 },
-		swiperItems : { type : Array, default : function(){return new Array();} },
-		borderRadius : { type : String, default : '10rpx'},
-		indicatorBarHeight:{type : Number, default : 68},
-		indicatorBarBgColor:{type : String, default : 'rgba(0,0,0,0)'},
-		indicatorWidth : { type:Number, default:18 },
-		indicatorActiveWidth :{ type:Number, default:18 },
-		indicatorHeight : { type:Number, default:18 },
-		indicatorRadius:{ type:Number, default:18 },
-		indicatorColor : { type : String, default : "rgba(255, 255, 255, 0.6)" },
-		indicatorActiveColor : { type : String, default : "#3688FF" },
+<template>
+	<view class="grace-swiper-card-wrap">
+		<swiper :style="{width:width+'rpx', height:heightIn+'rpx'}" class="grace-swiper-card" 
+		:indicator-dots="false" :interval="interval" :circular="true" :autoplay="autoplay" :current="currentIndex" 
+		:previous-margin="spacing+'rpx'" :next-margin="spacing+'rpx'" @change="swiperchange">
+			<swiper-item v-for="(item, index) in swiperItems" :key="index" class="grace-swiper-card-item">
+				<navigator class="grace-swiper-card-nav" :url="item.url" :open-type="item.opentype" hover-class="none" v-if="item.opentype != 'click'" 
+				:style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
+				paddingRight:current != index ? padding +'rpx':'0rpx',
+				paddingTop:current != index ? paddingY +'rpx':'0rpx',
+				paddingBottom:current != index ? paddingY +'rpx':'0rpx',
+				transition: 'all 0.2s ease-in 0s'}">
+					<image :style="{
+						borderRadius : borderRadius, 
+						transition: 'all 0.2s ease-in 0s',
+						width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
+						height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
+						opacity:current != index ? opacity : 1}" 
+						:src="item.img" class="grace-swiper-card-image" />
+				</navigator>
+				<view class="grace-swiper-card-nav" hover-class="none" v-if="item.opentype == 'click'" @tap.stop="taped" :data-index="index" 
+				:style="{paddingLeft:current != index ? padding +'rpx':'0rpx',
+				paddingRight:current != index ? padding +'rpx':'0rpx',
+				paddingTop:current != index ? paddingY +'rpx':'0rpx',
+				paddingBottom:current != index ? paddingY +'rpx':'0rpx',
+				transition: 'all 0.2s ease-in 0s'}">
+					<image :style="{
+						borderRadius : borderRadius, 
+						transition: 'all 0.2s ease-in 0s',
+						width:current != index ? widthInSamll+'rpx':widthIn+'rpx',
+						height:current != index ? heightInSmall+'rpx':heightIn+'rpx',
+						opacity:current != index ? opacity : 1}" 
+					:src="item.img" class="grace-swiper-card-image" />
+				</view>
+				<view v-if="indicatorType == 'number'" class="grace-indicator-dot-numbers" 
+				:style="{
+					height:indicatorBarHeight+'rpx', background:indicatorBarBgColor, 
+					width:current != index ? widthInSamll+'rpx':widthIn+'rpx', 
+					left:current != index ? padding+'rpx':'0rpx', bottom:current != index ? paddingY+'rpx':'0rpx'}">
+					<text class="grace-indicator-dot-text" 
+					:style="{paddingLeft:'20rpx', 'fontStyle':'italic', color:titleColor}">{{index+1}}</text>
+					<text class="grace-indicator-dot-text" 
+					:style="{'fontSize':'36rpx', color:titleColor}">/</text>
+					<text class="grace-indicator-dot-text" 
+					:style="{fontSize:'28rpx', paddingRight:'20rpx', fontStyle:'italic', color:titleColor}">{{swiperItems.length}}</text>
+					<text class="grace-swiper-text" 
+					:style="{color:titleColor, fontSize:titleSize, height:indicatorBarHeight+'rpx', 
+					lineHeight:indicatorBarHeight+'rpx'}">{{item.title}}</text>
+				</view>
+			</swiper-item>
+		</swiper>
+		<view class="grace-indicator-dots" v-if="indicatorType == 'dot'" 
+		:style="{width:width+'rpx', height:indicatorBarHeight+'rpx', position:indicatorPosition, 
+		paddingLeft:spacing+'rpx', paddingRight:spacing+'rpx'}">
+			<view v-for="(item, index) in swiperItems" :key="index" 
+			:class="['grace-indicator-dot',current == index ? 'dot-show' : '']" 
+			:style="{
+				width           : current != index ? indicatorWidth+'rpx' : indicatorActiveWidth +'rpx',
+				height          : indicatorHeight+'rpx',
+				borderRadius    : indicatorRadius+'rpx',
+				background      : current != index ? indicatorColor : indicatorActiveColor}"></view>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		width:{ type : Number, default : 750 },
+		height:{ type : Number, default : 300 },
+		swiperItems : { type : Array, default : function(){return new Array();} },
+		borderRadius : { type : String, default : '10rpx'},
+		indicatorBarHeight:{type : Number, default : 68},
+		indicatorBarBgColor:{type : String, default : 'rgba(0,0,0,0)'},
+		indicatorWidth : { type:Number, default:18 },
+		indicatorActiveWidth :{ type:Number, default:18 },
+		indicatorHeight : { type:Number, default:18 },
+		indicatorRadius:{ type:Number, default:18 },
+		indicatorColor : { type : String, default : "rgba(255, 255, 255, 0.6)" },
+		indicatorActiveColor : { type : String, default : "#3688FF" },
 		indicatorType:{ type : String, default : "dot" },
-		spacing : { type : Number, default : 50 },
-		padding : { type : Number, default : 26 },
-		interval : { type : Number, default : 5000 },
-		autoplay : { type : Boolean, default : true },
-		currentIndex : { type : Number, default : 0 },
-		opacity:{ type : Number, default:0.66},
-		titleColor:{type:String, default:"#FFFFFF"},
-		titleSize:{type:String, default:"28rpx"}
-	},
-	data() {
-		return {
-			current : 0,
-			isReady : false,
-			widthIn : 750,
-			heightIn  : 300,
-			widthInSamll:700,
-			heightInSmall:280,
-			paddingY:0
-		}
-	},
-	watch:{
-		currentIndex : function (val) {
-			this.current = val;
-		}
-	},
-	created:function(){
-		this.current = this.currentIndex;
-		this.init();
-	},
-	methods:{
-		init : function(){
-			// 图片宽高计算
-			this.widthIn   = this.width - this.spacing*2;
-			this.heightIn  = this.height / this.width * this.widthIn;
-			this.paddingY  = this.padding * this.height / this.width;
-			this.widthInSamll  = this.widthIn -  this.padding * 2;
-			this.heightInSmall = this.heightIn - this.paddingY * 2;
-		},
-		swiperchange : function (e) {
-			var current = e.detail.current;
-			this.current = current;
-			this.$emit('swiperchange', current);
-		},
-		taped : function(e){
-			this.$emit('taped', e.currentTarget.dataset.index);
-		}
-	}
-}
-</script>
-<style scoped>
-.grace-swiper-card-wrap{position:relative;}
-.grace-swiper-card{overflow:hidden;}
-.grace-swiper-card-item{box-sizing:border-box; font-size:0; overflow:hidden; line-height:0;}
-.grace-swiper-card-nav{font-size:0; display:block; position:relative;}
-.grace-swiper-card-image{}
-.grace-indicator-dots{width:750rpx; height:68rpx; overflow:hidden; position:absolute; z-index:1; left:0; bottom:0; display:flex; flex-direction:row; flex-wrap:nowrap; box-sizing:border-box; align-items:center; justify-content:center;}
-.grace-indicator-dot{margin:6rpx;}
-.grace-indicator-dot-text{display:block; text-align:center; line-height:68rpx; padding:0 4rpx; color:#FFFFFF; font-size:32rpx; flex-shrink:0;}
-.grace-indicator-dot-numbers{display:flex; flex-direction:row; flex-wrap:nowrap; justify-content:center; overflow:hidden; align-items:center; position:absolute; z-index:1; left:0; bottom:0;}
-.grace-swiper-text{width:750rpx; line-height:68rpx; padding-right:25rpx; box-sizing:border-box; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
-@keyframes dot-show{from{opacity:0.1;}to{opacity:1;}}
-.dot-show{animation:dot-show 300ms linear forwards;}
-</style>
+		indicatorPosition:{ type : String, default : "absolute" },
+		spacing : { type : Number, default : 50 },
+		padding : { type : Number, default : 26 },
+		interval : { type : Number, default : 5000 },
+		autoplay : { type : Boolean, default : true },
+		currentIndex : { type : Number, default : 0 },
+		opacity:{ type : Number, default:0.66},
+		titleColor:{type:String, default:"#FFFFFF"},
+		titleSize:{type:String, default:"28rpx"}
+	},
+	data() {
+		return {
+			current : 0,
+			isReady : false,
+			widthIn : 750,
+			heightIn  : 300,
+			widthInSamll:700,
+			heightInSmall:280,
+			paddingY:0
+		}
+	},
+	watch:{
+		currentIndex : function (val) {
+			this.current = val;
+		}
+	},
+	created:function(){
+		this.current = this.currentIndex;
+		this.init();
+	},
+	methods:{
+		init : function(){
+			// 图片宽高计算
+			this.widthIn   = this.width - this.spacing*2;
+			this.heightIn  = this.height / this.width * this.widthIn;
+			this.paddingY  = this.padding * this.height / this.width;
+			this.widthInSamll  = this.widthIn -  this.padding * 2;
+			this.heightInSmall = this.heightIn - this.paddingY * 2;
+		},
+		swiperchange : function (e) {
+			var current = e.detail.current;
+			this.current = current;
+			this.$emit('swiperchange', current);
+		},
+		taped : function(e){
+			this.$emit('taped', e.currentTarget.dataset.index);
+		}
+	}
+}
+</script>
+<style scoped>
+.grace-swiper-card-wrap{position:relative;}
+.grace-swiper-card{overflow:hidden;}
+.grace-swiper-card-item{box-sizing:border-box; font-size:0; overflow:hidden; line-height:0;}
+.grace-swiper-card-nav{font-size:0; display:block; position:relative;}
+.grace-swiper-card-image{}
+.grace-indicator-dots{width:750rpx; height:68rpx; overflow:hidden; z-index:1; left:0; bottom:0; display:flex; flex-direction:row; flex-wrap:nowrap; box-sizing:border-box; align-items:center; justify-content:center;}
+.grace-indicator-dot{margin:6rpx;}
+.grace-indicator-dot-text{display:block; text-align:center; line-height:68rpx; padding:0 4rpx; color:#FFFFFF; font-size:32rpx; flex-shrink:0;}
+.grace-indicator-dot-numbers{display:flex; flex-direction:row; flex-wrap:nowrap; justify-content:center; overflow:hidden; align-items:center; position:absolute; z-index:1; left:0; bottom:0;}
+.grace-swiper-text{width:750rpx; line-height:68rpx; padding-right:25rpx; box-sizing:border-box; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;}
+@keyframes dot-show{from{opacity:0.1;}to{opacity:1;}}
+.dot-show{animation:dot-show 300ms linear forwards;}
+</style>

+ 6 - 6
lib/graceUI/components/graceTouch.vue

@@ -1,8 +1,8 @@
 <template>
-	<view @touchstart="touchstart" @touchmove.stop="touchmove" @touchend.stop="touchend">
+	<view @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
 		<slot></slot>
-	</view>
-</template>
+	</view>
+</template>
 <script>
 export default{
 	props:{
@@ -110,8 +110,8 @@ export default{
 			return Math.round(s * 10000) / 10000;
 		}
 	}
-}
-</script>
+}
+</script>
 <style>
-	
+	
 </style>

+ 15 - 6
lib/graceUI/components/graceTree.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<view v-for="(tree,index) in treesIN" :key="index">
-			<view class="grace-tree" :data-tree="tree" :data-treeindexs="indexesIn" :data-index="index" :data-treelevel="level" 
+			<view class="grace-tree" :data-havsons="tree.children" :data-treeindexs="indexesIn" :data-index="index" :data-treelevel="level" 
 			:style="{paddingLeft:(indent*level)+'rpx'}" @tap.stop="taped" :data-cancheck="(allCanCheck || !tree.children)">
 				<view class="grace-tree-icons" v-if="type == 'text' && isIcon" style="width:22rpx;">
 					<text class="grace-tree-icons-text grace-icons icon-line" v-if="tree.children"></text>
@@ -14,10 +14,10 @@
 					<text class="grace-tree-icons-text grace-icons icon-checkbox-ckd" :style="{color:checkedColor, fontSize:iconSize}" v-if="isChecked(tree.id)"></text>
 					<text class="grace-tree-icons-text grace-icons icon-checkbox" :style="{fontSize:iconSize}" v-else></text>
 				</view>
-				<text class="grace-tree-label" :style="{lineHeight:lineHeight,fontSize:fontSize, color:fontColor}">{{tree.label}}</text>
+				<text class="grace-tree-label" :style="{lineHeight:lineHeight,fontSize:fontSize, color:fontColor}">{{tree.label}}-{{fold}}</text>
 			</view>
 			<view>
-				<graceTree 
+				<graceTree v-if="!fold" 
 				:trees="tree.children" :indent="indent" :level="level+1" :lineHeight="lineHeight" :allCanCheck="allCanCheck" :iconSize="iconSize" 
 				:fontSize="fontSize" :fontColor="fontColor" :isIcon="isIcon" :checkedId="checkedId" :checkedIds="checkedIds" 
 				:type="type" :indexes="[indexesIn,index]" @taped="tapbase"></graceTree>
@@ -42,12 +42,14 @@ export default{
 		checkedId : {type:[String, Number], default:'-1'},
 		checkedIds : {type:Array, default:function () {return [];}},
 		checkedColor:{type:String, default:'#3688FF'},
-		allCanCheck: {type:Boolean, default:true}
+		allCanCheck: {type:Boolean, default:true},
+		isFold : {type:Boolean, default:true}
 	},
 	data() {
 		return {
 			treesIN:[],
-			indexesIn : []
+			indexesIn : [],
+			fold:false
 		}
 	},
 	created:function(){
@@ -62,13 +64,16 @@ export default{
 	},
 	methods:{
 		taped : function(e){
-			var tree       = e.currentTarget.dataset.tree;
+			var havsons       = e.currentTarget.dataset.havsons;
 			var treeindexs = e.currentTarget.dataset.treeindexs;
 			treeindexs = treeindexs.split(',');
 			var index      = e.currentTarget.dataset.index;
 			treeindexs.push(index);
 			treeindexs.shift();
 			if(this.type == 'text'){
+				if(this.isFold){
+					if(havsons){this.fold = !this.fold; return;}
+				}
 				this.tapbase(treeindexs);
 			}else{
 				var cancheck = e.currentTarget.dataset.cancheck;
@@ -89,6 +94,10 @@ export default{
 				}
 			}
 			return false;
+		},
+		foldIt : function(){
+			console.log(1);
+			this.fold = !this.fold;
 		}
 	}
 }

+ 0 - 371
lib/graceUI/grace.js

@@ -1,371 +0,0 @@
-/*
-link   : http://grace.hcoder.net
-author : 刘海君 5213606@qq.com 
-verson : 1.01
-last update date : 2020-03-19
-*/
-module.exports = {
-	// 版本检查
-	verson : function(){
-		var currentVersion = '1.0';
-		console.log(currentVersion);
-	},
-	// --- 页面跳转相关 ---
-	// 页面跳转
-	navigate:function (url, type, success, fail, complete) {
-		if(!type){type = 'navigateTo';}
-		if(!success){success = function(){};}
-		if(!fail){fail = function(){};}
-		if(!complete){complete = function(){};}
-		switch(type){
-			case 'navigateTo' : 
-			uni.navigateTo({url:url, success:success, fail:fail, complete:complete});
-			break;
-			case 'redirectTo' : 
-			uni.redirectTo({url:url, success:success, fail:fail, complete:complete});
-			break;
-			case 'switchTab' : 
-			uni.switchTab({url:url, success:success, fail:fail, complete:complete});
-			break;
-			case 'reLaunch' : 
-			uni.reLaunch({url:url, success:success, fail:fail, complete:complete});
-			break;
-		}
-	},
-	// 返回
-	back:function(delta){
-		if(!delta){delta = 1;}
-		uni.navigateBack({delta:delta});
-	},
-	
-	// --- 网络请求 ---
-	// get
-	get : function(url, data, headers, success, fail){
-		if(!fail){fail = () => {this.msg("网络请求失败");}}
-		if(!headers){headers={};}
-		if(this.__before != null){this.__before(); this.__before = null;}
-		uni.request({
-			url      : url,
-			data     : data,
-			method   : "GET",
-			dataType : "json",
-			header   : headers,
-			success  : (res) => {success(res.data);},
-			fail     : fail,
-			complete : () => {if(this.__after != null){this.__after(); this.__after = null;}}
-		});
-	},
-	// post
-	post : function(url, data, contentType, headers, success, fail){
-		if(!fail){fail = () => {this.msg("网络请求失败");}}
-		if(!headers){headers={};}
-		if(!contentType){contentType = 'form';}
-		if(this.__before != null){this.__before(); this.__before = null;}
-		switch(contentType){
-			case "form" : 
-			headers['content-type'] = 'application/x-www-form-urlencoded';
-			break;
-			case "json" : 
-			headers['content-type'] = 'application/json';
-			break;
-			default :
-			headers['content-type'] = 'application/x-www-form-urlencoded';
-		}
-		uni.request({
-			url      : url,
-			data     : data,
-			method   : "POST",
-			dataType : "json",
-			header   : headers,
-			success  : (res) => {success(res.data);},
-			fail     : fail,
-			complete : () => {if(this.__after != null){this.__after(); this.__after = null;}}
-		});
-	},
-	// 请求前置函数
-	__before : null,
-	setBefore : function(func){
-		this.__before = func;
-	},
-	// 请求后置函数
-	__after : null,
-	setAfter : function(func){
-		this.__after = func;
-	},
-	
-	// --- 数据缓存 ---
-	setStorage : function(data){
-		try {
-			for(let k in data){uni.setStorageSync(k, data[k]+'');}
-			return true;
-		} catch (e){return false;}
-	},
-	getStorage : function(keyName){
-		try {
-			var tmpVal = uni.getStorageSync(keyName);
-			if(tmpVal == ''){return false;}
-			return tmpVal;
-		} catch (e){return false;}
-	},
-	removeStorage : function(keyName){
-		try {
-			uni.removeStorageSync(keyName);
-			return true;
-		} catch (e){return false;}
-	},
-	clearStorage : function(){
-		try { uni.clearStorageSync(); } catch (e) {}
-	},
-	
-	// --- 图片相关 ---
-	chooseImgs : function(sets, success, fail, complete) {
-		if(!sets.count){sets.count = 1;}
-		if(!sets.sizeType){sets.sizeType = ['original', 'compressed'];}
-		if(!sets.sourceType){sets.sourceType = ['album', 'camera'];}
-		uni.chooseImage({
-		    count: sets.count, //默认9
-		    sizeType: sets.sizeType, //可以指定是原图还是压缩图,默认二者都有
-		    sourceType: sets.sourceType, //从相册选择
-		    success:(res) => {success(res.tempFilePaths);},
-			fail: (e) => { if(fail){fail(e);}},
-			complete: (e) => { if(complete){complete(e);}}
-		});
-	},
-	getImageInfo : function(imgUrl, success, fail, complete){
-		uni.getImageInfo({
-			src: imgUrl,
-			success: function (info) {success(info);},
-			fail: (e) => { if(fail){fail(e);}},
-			complete: (e) => { if(complete){complete(e);}}
-		});
-	},
-	previewImage : function (items, currentImg) {
-		uni.previewImage({ urls: items, current:currentImg});
-	},
-	
-	// --- 系统信息 ---
-	system : function () {
-		try {
-		    var res = uni.getSystemInfoSync();
-			var iPhoneXBottom = 0;
-			res.model = res.model.replace(' ', '');
-			res.model = res.model.toLowerCase();
-			if(res.model.indexOf('iphonex') != -1 || res.model.indexOf('iphone11') != -1){
-				res.iPhoneXBottomHeightRpx = 50;
-				res.iPhoneXBottomHeightPx = uni.upx2px(50);
-			}else{
-				res.iPhoneXBottomHeightRpx = 0;
-				res.iPhoneXBottomHeightPx  = 0;
-			}
-			return res;
-		} catch (e){
-		    return null;
-		}
-	},
-	
-	// --- 消息弹框 ---
-	msg : function(msg){uni.showToast({title:msg, icon:"none"});},
-	showLoading : function (title) {uni.showLoading({  title:title });},
-	
-	// --- 导航条设置 ---
-	setNavBar : function(sets){
-		if(sets.title){uni.setNavigationBarTitle({title:sets.title});}
-		if(sets.color){
-			uni.setNavigationBarColor({
-			    frontColor: sets.color.frontColor,
-			    backgroundColor:sets.color.backgroundColor,
-			    animation: {
-			        duration: 400,
-			        timingFunc: 'easeIn'
-			    }
-			});
-		}
-		if(sets.loading){
-			uni.showNavigationBarLoading();
-		}else{
-			uni.hideNavigationBarLoading();
-		}
-	},
-	
-	// --- 元素选择 ---
-	// 单个元素选择
-	select : function (selector, callBack) {
-		uni.createSelectorQuery().select(selector).boundingClientRect().exec((res)=>{callBack(res[0]);});
-	},
-	// 多个元素获取
-	selectAll : function (selector, callBack) {
-		uni.createSelectorQuery().selectAll(selector).boundingClientRect().exec((res)=>{callBack(res[0]);});
-	},
-	
-	// --- 数组操作 ---
-	// 数组合并
-	arrayConcat : function(){
-		var tmpArr = [];
-		for(let i = 0; i < arguments.length; i++){tmpArr = tmpArr.concat(arguments[i]);}
-		return tmpArr;
-	},
-	arrayDrop : function(array, index, howmany){
-		if(!index){index = 0;}
-		if(!howmany){howmany = 1;}
-		array.splice(index, howmany);
-		return array;
-	},
-	arrayIndexOf : function(arr, needFind){
-		var index = -1;
-		for(let i = 0; i < arr.length; i++){
-			if(arr[i] == needFind){index = i; return i;}
-		}
-		return index;
-	},
-	arrayDifference : function(a, b){
-		const set = new Set(b);
-		return a.filter(x => !set.has(x));
-	},
-	arrayShuffle : function (arr) {
-		let l = arr.length;
-		while (l) {
-			const i = Math.floor(Math.random() * l--);
-			[arr[l], arr[i]] = [arr[i], arr[l]];
-			console.log(i);
-		}
-		return arr;
-	},
-	arraySum: function(arr){
-		return arr.reduce((acc, val) => acc + val, 0);
-	},
-	arrayAvg: function(arr){
-		return arr.reduce((acc, val) => acc + val, 0) / arr.length;
-	},
-	arrayEach : function(arr, fun){
-		for(let i = 0; i < arr.length; i++) {fun(arr[i], i);}
-	},
-	
-	// 2数之间的随机数
-	random : function(min, max){ 
-		switch(arguments.length){ 
-			case 1: 
-			return parseInt(Math.random() * min + 1,10); 
-			break;
-			case 2: 
-			return parseInt(Math.random() * (max - min + 1 ) + min, 10); 
-			break;
-			default: 
-			return 0;
-		}
-	},
-	
-	// UUID
-	uuid : function(len){
-		var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
-	    var uuid = [], i;
-	    if(len){
-	        for (i = 0; i < len; i++){uuid[i] = chars[0 | Math.random() * chars.length];}
-	    }else{
-	        var r;
-	        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
-	        uuid[14] = '4';
-	        for(i = 0; i < 36; i++){
-	            if (!uuid[i]){
-	                r = 0 | Math.random() * 16;
-	                uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
-	            }
-	        }
-	    }
-	    return uuid.join('');
-	},
-	
-	// --- 日期时间 ---
-	now : function (type, addTime) {
-		var dateObj = new Date();
-		var cTime = dateObj.getTime();
-		if(addTime){cTime += addTime;}
-		if(!type){type = 'number';}
-		if(type == 'number'){return cTime;}
-		return this.toDate(cTime / 1000, 'str');
-	},
-	// 时间戳转 YY-mm-dd HH:ii:ss
-	toDate : function(timeStamp, returnType){
-		timeStamp = parseInt(timeStamp);
-		var date = new Date();
-		if(timeStamp < 90000000000 ){
-			date.setTime(timeStamp * 1000);
-		}else{
-			date.setTime(timeStamp );
-		}
-		var y = date.getFullYear();
-		var m = date.getMonth() + 1;
-		m = m < 10 ? ('0' + m) : m;
-		var d = date.getDate();
-		d = d < 10 ? ('0' + d) : d;
-		var h = date.getHours();
-		h = h < 10 ? ('0' + h) : h;
-		var minute = date.getMinutes();
-		var second = date.getSeconds();
-		minute = minute < 10 ? ('0' + minute) : minute;
-		second = second < 10 ? ('0' + second) : second;
-		if(returnType == 'str'){return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;}
-		return [y, m, d, h, minute, second];
-	},
-	// 字符串转时间戳
-	toTimeStamp : function(timeStamp){
-		var reg = /^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
-		var res = timeStamp.match(reg);
-		if (res == null){
-			var reg2 = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
-			var res2 = timeStamp.match(reg2);
-			if(res2 == null){ console.log('时间格式错误 E001'); return false;}
-			var year  = parseInt(res2[3]);
-			var month = parseInt(res2[1]);
-			var day   = parseInt(res2[2]);
-			var h     = parseInt(res2[4]);
-			var i     = parseInt(res2[5]);
-			var s     = parseInt(res2[6]);
-		}else{
-			var year  = parseInt(res[1]);
-			var month = parseInt(res[2]);
-			var day   = parseInt(res[3]);
-			var h     = parseInt(res[4]);
-			var i     = parseInt(res[5]);
-			var s     = parseInt(res[6]);
-		}
-		if (year < 1000) { console.log('时间格式错误'); return false; }
-		if (h < 0 || h > 24) { console.log('时间格式错误'); return false; }
-		if (i < 0 || i > 60) { console.log('时间格式错误'); return false; }
-		if (s < 0 || s > 60) { console.log('时间格式错误'); return false; }
-		return Date.parse(new Date(year, month - 1, day, h, i, s));
-	},
-	// 根据时间戳计算多少分钟/小时/天之前
-	fromTime : function (time){
-		if(time < 90000000000 ){time *= 1000;}
-	    var timer = new Date().getTime() - time;
-		timer = parseInt(timer / 1000);
-	    if(timer < 180){
-	        return '刚刚';
-	    }else if(timer >= 180 && timer < 3600){
-	        return parseInt(timer / 60) + '分钟前';
-	    }else if(timer >= 3600 && timer < 86400){
-	        return parseInt(timer / 3600) + '小时前';
-	    }else if(timer >= 86400 && timer < 2592000){
-	        return parseInt(timer / 86400) + '天前';
-	    }else{
-	        return this.toDate(time, 'str');
-	    }
-	},
-	
-	// 延迟操作
-	delay:function (timer, func){
-		return setTimeout(func, timer);
-	},
-	// 间隔指定时间循环某个函数
-	interval:function (timer, func){
-		return setInterval(func, timer);
-	},
-	
-	// 对象操作
-	assign : function (obj, key, val) {obj[key] = val;},
-	removeByKey : function (obj, key) {delete obj[key];},
-	each : function(obj, func){
-		for(let k in obj){func(k, obj[k]);}
-	},
-	isEmptyObj : function(obj){return JSON.stringify(obj) === '{}';}
-}

Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
lib/graceUI/graceIcons.css


+ 2 - 1
lib/graceUI/graceUI.css

@@ -2,7 +2,7 @@
 link   : http://grace.hcoder.net
 author : 刘海君 5213606@qq.com 
 verson : 3.0
-last update date : 2020-05-20
+last update date : 2020-06-16
 GraceUI 的版权约束是不能转售或者将 GraceUI 直接发布到公开渠道!侵权必究,请遵守版权约定!
 GraceUI 软著号 2019SR0533188 版权机器人启动中,侵权会追责,请遵守极其简单的版权规定
 */
@@ -133,6 +133,7 @@ button[loading][type=primary] {background-color:#3688FF; color:#FFFFFF;}
 button[loading][type=warn] {background-color:#ee0a25; color:#FFFFFF;}
 .grace-button[type=warn][plain] {color:#FF0036;  border:1px solid #FF0036; background-color:rgba(0,0,0,0);}
 .grace-box-btn{width:80rpx; height:80rpx; line-height:80rpx; padding:0; text-align:center; font-size:50rpx;}
+button[disabled][type=primary] {background-color:#3688FF; opacity:0.8;}
 
 /* 标题及更多 */
 .grace-title{padding:10rpx 0; line-height:2em; display:flex; flex-wrap:nowrap; font-size:28rpx; justify-content:space-between; font-weight:bold; align-items:center;}

+ 16 - 9
lib/graceUI/weexComponents/graceActionSheet.nvue

@@ -1,24 +1,30 @@
 <template>
 	<view class="">
-	<view class="graceActionSheet" @tap.stop="closeByShade" @touchmove.stop="stopFun" 
+	<view class="graceActionSheet" @tap.stop="closeByShade" @touchmove.stop.prevent="stopFun" 
 	:style="{backgroundColor:background}" v-if="realShow"></view>
 	<view :class="['graceActionSheetBody', isIpx ? 'grace-ipx-bottom' : '']"
-	:style="{width:realShow ? width : '0rpx',left:left,borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius}" 
+	:style="{
+		width:realShow ? width : '0rpx',left:left,
+		borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius}" 
 	@tap.stop="stopFun" v-if="realShow">
 		<text class="graceActionSheetTitle border-bottom" :style="{color:titleColor}">{{title}}</text>
-		<text class="graceActionSheetList border-bottom" v-for="(item, index) in items" :key="index" @tap.stop="selected" :data-index="index" 
-		:style="{color:listColor, lineHeight:listLineHeight, fontSize:listFontSize}">{{item}}</text>
-		<text class="graceActionSheetList" :style="{border:'none', color:cancelBtnColor}" @tap.stop="cancel">{{cancelBtnName}}</text>
+		<scroll-view scroll-y="true" :style="{height:height}">
+			<text class="graceActionSheetList border-bottom" 
+			v-for="(item, index) in items" :key="index" @tap.stop="selected" :data-index="index"
+			:style="{color:listColor, lineHeight:listLineHeight, fontSize:listFontSize}">{{item}}</text>
+		</scroll-view>
+		<text class="graceActionSheetList" v-if="isCancelBtn" :style="{border:'none', color:cancelBtnColor}" @tap.stop="cancel">{{cancelBtnName}}</text>
 	</view>
 	</view>
 </template>
 <script>
 export default {
-	props: {
-		width:{type:String,default:'720rpx'},
+	props: {
+		width:{type:String,default:'720rpx'},
+		height:{type:String,default:'500rpx'},
 		left:{type:String,default:'15rpx'},
-		background:{type : String,default : 'rgba(0, 0, 0, 0.3)'},
-		borderRadius : {type : String,default : '10rpx'},
+		background:{type : String,default : 'rgba(0, 0, 0, 0.3)'},
+		borderRadius : {type : String,default : '10rpx'},
 		zIndex:{type : Number,default : 99},
 		title:{type:String,default:''},
 		titleColor:{type:String, default:'#323232'},
@@ -26,6 +32,7 @@ export default {
 		listColor:{type:String, default:'#3688FF'},
 		listLineHeight:{type:String, default:'100rpx'},
 		listFontSize:{type:String, default:'30rpx'},
+		isCancelBtn:{type:Boolean, default:true},
 		cancelBtnName:{type:String,default:'取消'},
 		cancelBtnColor:{type:String, default:'#999999'}
 	},

+ 2 - 2
lib/graceUI/weexComponents/graceAddressPicker.nvue

@@ -1,5 +1,5 @@
 <template>
-	<view class="gap" v-if="show" @touchmove.stop="" @tap.stop="" :style="{backgroundColor:background}">
+	<view class="gap" v-if="show" @touchmove.stop.prevent="" @tap.stop="" :style="{backgroundColor:background}">
 		<view class="gap-body">
 			<view class="gap-header grace-space-between">
 				<text class="gap-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
@@ -115,4 +115,4 @@ export default {
 .gap-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
 .gap-main{width:750rpx; height:280px;}
 .gap-item{height:35px; font-size:12px; line-height:35px; overflow:hidden; text-align:center;}
-</style>
+</style>

+ 40 - 40
lib/graceUI/weexComponents/graceBottomDialog.nvue

@@ -1,44 +1,44 @@
-<template>
-	<view class="grace-btdialog-shade" v-if="show" @tap.stop="closeDialog" @touchmove.stop="stopFun" :style="{backgroundColor:background}">
+<template>
+	<view class="grace-btdialog-shade" v-if="show" @tap.stop="closeDialog" @touchmove.stop.prevent="stopFun" :style="{backgroundColor:background}">
 		<view class="grace-btdialog-shade-dialog" @tap.stop="stopFun" 
-		:style="{borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius,width:width,left:left}">
-			<view class="title"><slot name="btns"></slot></view>
-			<view class="content" @tap.stop="stopFun"><slot name="content"></slot></view>
-		</view>
-	</view>
-</template>
-<script>
-export default {
+		:style="{borderTopLeftRadius:borderRadius,borderTopRightRadius:borderRadius,width:width,left:left}">
+			<view class="title"><slot name="btns"></slot></view>
+			<view class="content" @tap.stop="stopFun"><slot name="content"></slot></view>
+		</view>
+	</view>
+</template>
+<script>
+export default {
 	props: {
 		width:{type:String,default:'750rpx'},
-		left:{type:String,default:'0rpx'},
-		show : {
-			type : Boolean,
-			default : false
-		},
-		background:{
-			type : String,
-			default : 'rgba(0, 0, 0, 0.5)'
-		},
-		borderRadius : {
-			type : String,
-			default : '0rpx'
-		}
-	},
-	data() {
-		return {}
-	},
-	methods:{
-		closeDialog : function(){
-			this.$emit('closeDialog');
-		},
-		stopFun : function(){}
-	}
-}
-</script>
-<style scoped>
-.grace-btdialog-shade{position:fixed; width:750rpx; left:0; top:0; bottom:0; background-color:rgba(0, 0, 0, 0.5);}
-.grace-btdialog-shade-dialog{width:750rpx; background-color:#FFFFFF; position:absolute; bottom:0; left:0;}
-.grace-btdialog-shade-title{flex-direction:row; flex-wrap:nowrap; justify-content:space-between;}
-.grace-btdialog-shade-content{}
+		left:{type:String,default:'0rpx'},
+		show : {
+			type : Boolean,
+			default : false
+		},
+		background:{
+			type : String,
+			default : 'rgba(0, 0, 0, 0.5)'
+		},
+		borderRadius : {
+			type : String,
+			default : '0rpx'
+		}
+	},
+	data() {
+		return {}
+	},
+	methods:{
+		closeDialog : function(){
+			this.$emit('closeDialog');
+		},
+		stopFun : function(){}
+	}
+}
+</script>
+<style scoped>
+.grace-btdialog-shade{position:fixed; width:750rpx; left:0; top:0; bottom:0; background-color:rgba(0, 0, 0, 0.5);}
+.grace-btdialog-shade-dialog{width:750rpx; background-color:#FFFFFF; position:absolute; bottom:0; left:0;}
+.grace-btdialog-shade-title{flex-direction:row; flex-wrap:nowrap; justify-content:space-between;}
+.grace-btdialog-shade-content{}
 </style>

+ 1 - 1
lib/graceUI/weexComponents/graceDate.nvue

@@ -1,5 +1,5 @@
 <template name="graceDate">
-	<view class="grace-date" v-if="show" :style="{top:top}" @tap.stop="" @touchmove.stop="">
+	<view class="grace-date" v-if="show" :style="{top:top}" @tap.stop="" @touchmove.stop.prevent="">
 		<view class="grace-date-header">
 			<text class="grace-date-header-btn grace-icons" @click="prevYear">&#xe600;&#xe600;</text>
 			<text class="grace-date-header-btn grace-icons" @click="prevMonth">&#xe600;</text>

+ 77 - 76
lib/graceUI/weexComponents/graceDateTime.nvue

@@ -1,44 +1,44 @@
 <template>
 	<view>
 		<view @tap.stop="open"><slot></slot></view>
-		<view class="graceDateTime" @touchmove.stop="" @tap.self="close" :style="{backgroundColor:background, width:show ? '750rpx' : '0px'}"></view>
-		<view class="graceDateTime-body" :style="{bottom : show ? '0px' : '-1000px', paddingBottom:paddingBottom}">
-			<view class="graceDateTime-header grace-space-between" v-if="isHeaderBar">
-				<text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
-				<text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>
-			</view>
-			<picker-view :indicator-style="indicatorStyle" class="graceDateTime-main" 
-			:value="defaultVal" @change="change" :style="{height:height}">
-				<picker-view-column>
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[0]" :key="index">{{item}}{{units[0]}}</text>
-				</picker-view-column>
-				<picker-view-column>
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[1]" :key="index">{{item}}{{units[1]}}</text>
-				</picker-view-column>
-				<picker-view-column>
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[2]" :key="index">{{item}}{{units[2]}}</text>
-				</picker-view-column>
-				<picker-view-column v-if="isTime">
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[3]" :key="index">{{item}}{{units[3]}}</text>
-				</picker-view-column>
-				<picker-view-column v-if="isTime">
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[4]" :key="index">{{item}}{{units[4]}}</text>
-				</picker-view-column>
-				<picker-view-column  v-if="isTime && isSecond">
-					<text class="graceDateTime-item" v-for="(item, index) in sDate[5]" :key="index">{{item}}{{units[5]}}</text>
-				</picker-view-column>
-			</picker-view>
+		<view class="graceDateTime" @touchmove.stop.prevent="" @tap.self="close" :style="{backgroundColor:background, width:show ? '750rpx' : '0px'}"></view>
+		<view class="graceDateTime-body" :style="{bottom : show ? '0px' : '-1000px', paddingBottom:paddingBottom}">
+			<view class="graceDateTime-header grace-space-between" v-if="isHeaderBar">
+				<text class="graceDateTime-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
+				<text class="graceDateTime-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>
+			</view>
+			<picker-view :indicator-style="indicatorStyle" class="graceDateTime-main" 
+			:value="defaultVal" @change="change" :style="{height:height}">
+				<picker-view-column>
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[0]" :key="index">{{item}}{{units[0]}}</text>
+				</picker-view-column>
+				<picker-view-column>
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[1]" :key="index">{{item}}{{units[1]}}</text>
+				</picker-view-column>
+				<picker-view-column>
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[2]" :key="index">{{item}}{{units[2]}}</text>
+				</picker-view-column>
+				<picker-view-column v-if="isTime">
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[3]" :key="index">{{item}}{{units[3]}}</text>
+				</picker-view-column>
+				<picker-view-column v-if="isTime">
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[4]" :key="index">{{item}}{{units[4]}}</text>
+				</picker-view-column>
+				<picker-view-column  v-if="isTime && isSecond">
+					<text class="graceDateTime-item" v-for="(item, index) in sDate[5]" :key="index">{{item}}{{units[5]}}</text>
+				</picker-view-column>
+			</picker-view>
 		</view>
-	</view>
-</template>
-<script>
-export default {
-	props: {
-		background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' },
-		cancelText : { type : String, default : '取消' },
-		cancelTColor : { type : String, default : '#888888' },
-		confirmText : { type : String, default : '确定' },
-		confirmColor : { type : String, default : '#3688FF' },
+	</view>
+</template>
+<script>
+export default {
+	props: {
+		background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' },
+		cancelText : { type : String, default : '取消' },
+		cancelTColor : { type : String, default : '#888888' },
+		confirmText : { type : String, default : '确定' },
+		confirmColor : { type : String, default : '#3688FF' },
 		value : { type : String , default:''},
 		isTime : {type : Boolean, default : true},
 		isSecond : {type : Boolean, default : true},
@@ -46,21 +46,21 @@ export default {
 		endYear : {type : Number, default : 2050},
 		units : {type : Array , default:function(){return new Array('年','月','日','时','分','秒')}},
 		height:{ type : String, default : '300rpx' },
-		isHeaderBar : {type : Boolean, default : true},
-		paddingBottom :{ type : String, default : '0rpx' }
-	},
-	data() {
+		isHeaderBar : {type : Boolean, default : true},
+		paddingBottom :{ type : String, default : '0rpx' }
+	},
+	data() {
 		return {
-			show:false,
-			indicatorStyle : 'height:35px',
+			show:false,
+			indicatorStyle : 'height:35px',
 			defaultVal     : [0,0,0,0,0,0],
-			sDate:[[],[],[],[],[],[]],
-			timer:null
-		}
-	},
-	created() {
-		this.init();
-	},
+			sDate:[[],[],[],[],[],[]],
+			timer:null
+		}
+	},
+	created() {
+		this.init();
+	},
 	methods: {
 		now : function () {
 			var date = new Date();
@@ -98,6 +98,7 @@ export default {
 				res[6] = '00';
 			}
 			this.setDefaults([res[1],res[2],res[3],res[4],res[5],res[6]]);
+			console.log('ok');
 		},
 		setDefaults : function (res) {
 			for(let i = 0; i < res.length; i++){
@@ -124,18 +125,18 @@ export default {
 				if(i < 10){minutes.push('0'+i); seconds.push('0'+i);}else{minutes.push(i); seconds.push(i);}
 			}
 			this.sDate = [years, months, days, hours, minutes, seconds];
-			this.$nextTick(()=>{setTimeout(()=>{ this.setValue(this.value);},300);});
-		},
-		change : function (res) {
-			if(this.timer != null){clearTimeout(this.timer);}
-			this.timer = setTimeout(()=>{this.changeBase(res.detail.value);},500);
+			this.$nextTick(()=>{setTimeout(()=>{ this.setValue(this.value);}, 500);});
+		},
+		change : function (res) {
+			if(this.timer != null){clearTimeout(this.timer);}
+			this.timer = setTimeout(()=>{this.changeBase(res.detail.value);},500);
 		},
 		changeBase:function(res){
 			var date = new Date(this.sDate[0][res[0]], this.sDate[1][res[1]], 0);
 			var days = date.getDate();
 			var daysOut = new Array();
 			for(let i = 1; i <= days; i++){if(i < 10){daysOut.push('0'+i);}else{daysOut.push(i);}}
-			this.sDate.splice(2, 1, daysOut);
+			this.sDate.splice(2, 1, daysOut);
 			if(res[2] + 1 > days){res[2] = days - 1;}
 			this.defaultVal = res;
 			if(this.isTime){
@@ -146,14 +147,14 @@ export default {
 				this.sDate[4][this.defaultVal[4]],
 				this.sDate[5][this.defaultVal[5]]);
 			}else{
-				var resdata = new Array(
+				var resdata = new Array(
 					this.sDate[0][this.defaultVal[0]],
 					this.sDate[1][this.defaultVal[1]],
-					this.sDate[2][this.defaultVal[2]]
+					this.sDate[2][this.defaultVal[2]]
 				)
 			}
 			this.$emit('change', resdata);
-		},
+		},
 		confirm:function () {
 			if(this.isTime){
 				var res = new Array(this.sDate[0][this.defaultVal[0]],
@@ -168,22 +169,22 @@ export default {
 				this.sDate[2][this.defaultVal[2]])
 			}
 			this.$emit('confirm', res);
-			this.show = false;
+			this.show = false;
+		},
+		open : function () {
+			this.show = true;
 		},
-		open : function () {
-			this.show = true;
-		},
-		close : function () {
-			this.show = false;
-		}
-	}
-}
-</script>
-<style scoped>
-.graceDateTime{position:fixed; top:0; left:0; bottom:0; width:0rpx; flex:1;}
-.graceDateTime-body{background-color:#FFFFFF; position:fixed; bottom:-1000px; left:0; width:750rpx;}
-.graceDateTime-header{padding:25rpx;}
-.graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
-.graceDateTime-main{width:750rpx;}
-.graceDateTime-item{height:35px; font-size:28rpx; line-height:35px; overflow:hidden; text-align:center;}
+		close : function () {
+			this.show = false;
+		}
+	}
+}
+</script>
+<style scoped>
+.graceDateTime{position:fixed; top:0; left:0; bottom:0; width:0rpx; flex:1;}
+.graceDateTime-body{background-color:#FFFFFF; position:fixed; bottom:-1000px; left:0; width:750rpx;}
+.graceDateTime-header{padding:25rpx;}
+.graceDateTime-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
+.graceDateTime-main{width:750rpx;}
+.graceDateTime-item{height:35px; font-size:28rpx; line-height:35px; overflow:hidden; text-align:center;}
 </style>

+ 40 - 40
lib/graceUI/weexComponents/graceDateTimeBetween.nvue

@@ -1,8 +1,8 @@
-<template>
-	<view>
-		<view @tap.stop="open"><slot></slot></view>
-		<view class="graceDateTimeBT" @touchmove.stop="" @tap.self="close" :style="{backgroundColor:background, width:show ? '750rpx' : '0px'}"></view>
-		<view class="graceDateTimeBT-body"  @touchmove.stop="" :style="{paddingBottom:paddingBottom, bottom:show?'0px':'-1000px'}">
+<template>
+	<view>
+		<view @tap.stop="open"><slot></slot></view>
+		<view class="graceDateTimeBT" @touchmove.stop.prevent="" @tap.self="close" :style="{backgroundColor:background, width:show ? '750rpx' : '0px'}"></view>
+		<view class="graceDateTimeBT-body"  @touchmove.stop.prevent="" :style="{paddingBottom:paddingBottom, bottom:show?'0px':'-1000px'}">
 			<view class="graceDateTimeBT-header grace-space-between">
 				<text class="graceDateTimeBT-header-btn" :style="{color:cancelTColor}" @tap="close">{{cancelText}}</text>
 				<text class="graceDateTimeBT-header-btn" :style="{textAlign:'right', color:confirmColor}" @tap="confirm">{{confirmText}}</text>
@@ -21,12 +21,12 @@
 				<graceDateTimeBetweenBase :value="endValue" :isTime="isTime" @change="chang2" 
 				:isSecond="isSecond" :startYear="startYear" :endYear="endYear" :units="units"></graceDateTimeBetweenBase>
 			</view>
-		</view>
-	</view>
-</template>
-<script>
-import graceDateTimeBetweenBase from "./graceDateTimeBetweenBase.nvue";
-export default {
+		</view>
+	</view>
+</template>
+<script>
+import graceDateTimeBetweenBase from "./graceDateTimeBetweenBase.nvue";
+export default {
 	components:{graceDateTimeBetweenBase},
 	props: {
 		background:{ type : String, default : 'rgba(0, 0, 0, 0.5)' },
@@ -34,49 +34,49 @@ export default {
 		cancelTColor : { type : String, default : '#888888' },
 		confirmText : { type : String, default : '确定' },
 		confirmColor : { type : String, default : '#3688FF' },
-		startValue : { type : String , default:''},
-		endValue : { type : String , default:''},
-		isTime : {type : Boolean, default : true},
-		isSecond : {type : Boolean, default : true},
-		startYear : {type : Number, default : 1980},
-		endYear : {type : Number, default : 2050},
+		startValue : { type : String , default:''},
+		endValue : { type : String , default:''},
+		isTime : {type : Boolean, default : true},
+		isSecond : {type : Boolean, default : true},
+		startYear : {type : Number, default : 1980},
+		endYear : {type : Number, default : 2050},
 		units : {type : Array , default:function(){return new Array('年','月','日','时','分','秒')}},
 		titles : {type : Array , default:function(){return new Array('请选择开始时间','请选择结束时间')}},
-		paddingBottom:{type : String , default:'0rpx'}
+		paddingBottom:{type : String , default:'0rpx'}
 	},
 	data() {
-		return {
+		return {
 			show:false,
 			indicatorStyle : 'height:35px',
-			defaultVal     : [0,0,0,0,0,0],
+			defaultVal     : [0,0,0,0,0,0],
 			sDate:[[],[],[],[],[],[]],
 			recDate:[[],[]]
 		}
-	},
-	methods:{
-		open : function () {
-			this.show = true;
-		},
-		close : function () {
-			this.show = false;
-		},
-		confirm : function(){
+	},
+	methods:{
+		open : function () {
+			this.show = true;
+		},
+		close : function () {
 			this.show = false;
-			this.$emit('confirm', this.recDate);
+		},
+		confirm : function(){
+			this.show = false;
+			this.$emit('confirm', this.recDate);
 		},
 		chang1 : function(res){
 			this.recDate[0] = res;
 		},
 		chang2 : function(res){
 			this.recDate[1] = res;
-		}
-	}
-}
-</script>
-<style>
+		}
+	}
+}
+</script>
+<style>
 .graceDateTimeBT{position:fixed; width:750rpx; top:0; left:0; bottom:0; flex:1;}
-.graceDateTimeBT-body{background-color:#FFFFFF; position:fixed; bottom:-1000px; left:0; width:750rpx;}
-.graceDateTimeBT-header{padding:25rpx;}
-.graceDateTimeBT-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
-.graceDateTimeBT-text{padding:15rpx; background-color:#FFFFFF; line-height:60rpx; height:100rpx; color:#666666; font-size:28rpx;}
-</style>
+.graceDateTimeBT-body{background-color:#FFFFFF; position:fixed; bottom:-1000px; left:0; width:750rpx;}
+.graceDateTimeBT-header{padding:25rpx;}
+.graceDateTimeBT-header-btn{width:200rpx; line-height:38rpx; height:38rpx; font-size:28rpx;}
+.graceDateTimeBT-text{padding:15rpx; background-color:#FFFFFF; line-height:60rpx; height:100rpx; color:#666666; font-size:28rpx;}
+</style>

+ 1 - 1
lib/graceUI/weexComponents/graceDialog.nvue

@@ -1,5 +1,5 @@
 <template>
-	<view class="grace-dialog-shade" v-if="show" @tap.stop="closeDialogByShade" @touchmove.stop="stopFun" :style="{backgroundColor:background}">
+	<view class="grace-dialog-shade" v-if="show" @tap.stop="closeDialogByShade" @touchmove.stop.prevent="stopFun" :style="{backgroundColor:background}">
 		<view class="grace-dialog gdFadeIn" @tap.stop="stopFun" :style="{width:width, borderRadius:borderRadius}">
 			<text class="grace-dialog-title" v-if="isTitle" 
 			:style="{fontSize:titleSize, color:titleColor,fontWeight:titleWeight?'900':'',backgroundColor:titleBg, lineHeight:titleHeight}">{{title}}</text>

+ 9 - 9
lib/graceUI/weexComponents/graceDrawer.nvue

@@ -1,6 +1,6 @@
 <template>
 	<view>
-		<view class="grace-drawer-shade" v-if="show" @click.stop="closeDrawer" @touchmove.stop="" :style="{backgroundColor:background}"></view>
+		<view class="grace-drawer-shade" v-if="show" @click.stop="closeDrawer" @touchmove.stop.prevent="" :style="{backgroundColor:background}"></view>
 		<view ref="graceDrawerMenu" v-if="show" class="grace-drawer-nav" @tap.stop="stopFun" 
 		:style="{width:width+'rpx', left : direction == 'left' ? (width*-1)+'rpx' : 'none', top : top+'px', 
 			right : direction == 'right' ? (width*-1)+'rpx' : 'none', 
@@ -24,10 +24,10 @@ export default {
 		direction : {
 			type : String,
 			default : 'left'
-		},
-		background:{
-			type : String,
-			default : 'rgba(0, 0, 0, 0.5)'
+		},
+		background:{
+			type : String,
+			default : 'rgba(0, 0, 0, 0.5)'
 		},
 		slotBg:{
 			type : String,
@@ -36,11 +36,11 @@ export default {
 		padding : {
 			type : String,
 			default : '30rpx'
-		},
+		},
 		top:{type:Number, value:0}
 	},
 	updated:function(){
-		if(this.show){
+		if(this.show){
 			setTimeout(()=>{
 				var moveX = this.direction == 'left' ? uni.upx2px(this.width) + 'px' : (uni.upx2px(this.width) * -1) + 'px';
 				var animation = weex.requireModule('animation');
@@ -51,8 +51,8 @@ export default {
 					needLayout:false,
 					delay: 0 
 					}, function (){}
-				);
-			}, 100);
+				);
+			}, 100);
 		}
 	},
 	methods:{

+ 24 - 17
lib/graceUI/weexComponents/graceFullLoading.nvue

@@ -1,5 +1,8 @@
 <template>
-	<view class="grace-full-loading" v-if="graceFullLoading" :style="{backgroundColor:background}" @tap.stop="" @touchmove.stop="">
+	<view class="grace-full-loading" v-if="graceFullLoading" @tap.stop="" @touchmove.stop.prevent="" 
+	:style="{
+		backgroundColor:background, left:graceFullLoading?'0px':'-1000px',
+		opacity:graceFullLoading?1:0}">
 		<image class="grace-full-loading-image" ref="loadingLogos" :src="logoUrl" mode="widthFix" :style="{width:size, height:size}"></image>
 		<text class="grace-full-loading-text" :style="{color:textColor, fontSize:fontSize}">{{text}}</text>
 	</view>
@@ -20,32 +23,33 @@ export default {
 		text : {
 			type    : String,
 			default : "Loading ..."
-		},
-		fontSize : {
-			type    : String,
-			default : "22rpx"
+		},
+		fontSize : {
+			type    : String,
+			default : "22rpx"
 		},
 		textColor : {
 			type    : String,
 			default : "#999999"
-		},
-		size : {
-			type    : String,
-			default : "138rpx"
-		},
-		background : {
-			type    : String,
-			default : 'rgba(255,255,255,1)'
+		},
+		size : {
+			type    : String,
+			default : "138rpx"
+		},
+		background : {
+			type    : String,
+			default : 'rgba(255,255,255,1)'
 		}
 	},
-	updated : function(){
+	updated : function(){
 		setTimeout(()=>{
 			var loadingLogos = this.$refs.loadingLogos;
-			this.animation1(loadingLogos);
+			this.animation1(loadingLogos);
 		}, 200);
 	},
 	methods: {
 		animation1 : function(loadingLogos){
+			if(!this.graceFullLoading){return ;}
 			var _self = this;
 			animation.transition(loadingLogos, {
 				styles: { opacity:0.3},
@@ -53,9 +57,12 @@ export default {
 				timingFunction: 'linear',
 				needLayout:false,
 				delay: 0 
-			}, function (){_self.animation2(loadingLogos);});
+			}, function (){
+				_self.animation2(loadingLogos);
+			});
 		},
 		animation2 : function(loadingLogos){
+			if(!this.graceFullLoading){return ;}
 			var _self = this;
 			animation.transition(loadingLogos, {
 				styles: { opacity: 1},
@@ -70,7 +77,7 @@ export default {
 }
 </script>
 <style scoped>
-.grace-full-loading{width:750rpx; justify-content:center; align-items:center; background-color:rgba(255,255,255,0.9); position:fixed; left:0; top:0; bottom:0;}
+.grace-full-loading{width:750rpx; justify-content:center; align-items:center; background-color:rgba(255,255,255,0.9); position:fixed; top:0; bottom:0;}
 .grace-full-loading-image{width:150rpx; height:150rpx; border-radius:150rpx;}
 .grace-full-loading-text{line-height:50rpx; font-size:22rpx; margin-top:10rpx; text-align:center;}
 </style>

+ 45 - 19
lib/graceUI/weexComponents/graceHeaderAlert.nvue

@@ -1,47 +1,73 @@
 <template>
-	<view class="grace-alert" v-if="showIn">
-		<view class="grace-alert-body" :style="{'background-color':background}"  ref="gracealert">
+	<view class="grace-alert" v-if="showIn" :style="{top : topReal + 'px'}">
+		<view class="grace-alert-body" ref="gracealert" 
+		:style="{'background-color':background, width:width+'rpx'}">
 			<slot></slot>
 		</view>
 	</view>
 </template>
 <script>
-var animation = weex.requireModule('animation');
 export default {
 	name: "graceHeaderAlert",
 	props: {
-		show    : {
-			type : Boolean,
-			default : false
-		},
-		background : {
-			type : String,
-			default : '#F1F2F3'
-		}
+		show       : { type : Boolean, default : false },
+		background : { type : String, default : '#F1F2F3' },
+		top        : { type : Number, default : 20 },
+		width      : { type : Number, default : 580},
+		duration   : { type : Number, default : 2500}
 	},
 	data() {
 		return {
-			showIn : false
+			showIn : false,
+			topReal : 0
 		}
 	},
+	created:function(){
+		this.topReal = this.top;
+		this.showIn  = this.show;
+	},
 	watch: {
 		show : function(n , o){
+			if(n){
+				this.showIn = n;
+				this.animation();
+			}
+		}
+	},
+	methods:{
+		open:function(){
 			this.showIn = true;
-			setTimeout(() => {
+			this.animation();
+		},
+		close:function(){
+			this.showIn = false;
+		},
+		animation : function(){
+			setTimeout(()=>{
+				var animation = weex.requireModule('animation');
 				animation.transition(this.$refs.gracealert, {
-					styles         : {opacity:1},
-					duration       : 50, 
+					styles         : {opacity:0, transform:'scale(0.1,0.1)'},
+					duration       : 1, 
 					timingFunction : 'linear',
 					needLayout     : false,
-					delay          : 0 
+					delay          : 0 ,
+				}, ()=>{
+					animation.transition(this.$refs.gracealert, {
+						styles         : {opacity:1, transform:'scale(1,1)'},
+						duration       : 150, 
+						timingFunction : 'linear',
+						needLayout     : false,
+						delay          : 0 ,
+					});
 				});
-			}, 100);
-			setTimeout(function(){this.showIn = false;}.bind(this), 3000);
+			}, 200);
+			setTimeout(()=>{this.showIn = false;}, this.duration);
 		}
 	}
+	
 }
 </script>
 <style scoped>
 .grace-alert{width:750rpx; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center;  position:fixed; left:0rpx; top:20rpx;}
-.grace-alert-body{width:600rpx; padding:20rpx 25rpx; border-radius:10rpx; background-color:#FFFFFF; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; opacity:0.1;}
+.grace-alert-body{padding:25rpx; border-radius:10rpx; flex-direction:row; flex-wrap:nowrap; justify-content:center; align-items:center; opacity:0;}
 </style>

+ 1 - 1
lib/graceUI/weexComponents/graceNavBar.nvue

@@ -1,5 +1,5 @@
 <template>
-	<scroll-view
+	<scroll-view scroll-with-animation 
 	:class="['grace-nav-bar', isCenter ? 'grace-nav-center' : '']" :scroll-x="true" 
 	:scroll-into-view="'tab-'+currentIndex" :show-scrollbar="false">
 		<view class="nav-item" :id="'tab-'+index" 

+ 1 - 1
lib/graceUI/weexComponents/graceNavBar2.nvue

@@ -1,5 +1,5 @@
 <template>
-	<scroll-view
+	<scroll-view scroll-with-animation 
 	:class="['grace-nav-bar2', isCenter ? 'grace-nav2-center' : '']" :scroll-x="true" :show-scrollbar="false" 
 	:scroll-into-view="'tab-'+currentIndex">
 		<view class="nav2-item" :id="'tab-'+index" :style="{width:size+'rpx', height:(lineHeight+lineHeightSamll+18)+'rpx'}" 

+ 12 - 3
lib/graceUI/weexComponents/graceNumberBox.nvue

@@ -1,9 +1,15 @@
 <template>
 	<view class="grace-number-box" :style="{width:width}">
 		<text class="grace-number-box-doBtn" @tap.stop="reduce" 
-		:style="{width:btnSize, height:btnSize, fontSize:btnFontSize, lineHeight:btnSize, color:btnColr}">-</text>
-		<input class="grace-number-box-input" type="number" v-model="inputNumber" :disabled="disabled" 
-		:style="{backgroundColor:inputBG, height:inputHeight, lineHeight:inputHeight, fontSize:inputFontSize, color:inputColor, padding:inputPadding, borderRadius:inputBorderRadius}"></input>
+		:style="{
+			width:btnSize, height:btnSize, fontSize:btnFontSize, 
+			lineHeight:btnSize, color:btnColr}">-</text>
+		<input class="grace-number-box-input" type="number" 
+		:value="inputNumber" :disabled="disabled"  @blur="inputval" 
+		:style="{
+			backgroundColor:inputBG, height:inputHeight, lineHeight:inputHeight, 
+			fontSize:inputFontSize, color:inputColor, padding:inputPadding, 
+			borderRadius:inputBorderRadius}"></input>
 		<text class="grace-number-box-doBtn" @tap.stop="add" 
 		:style="{width:btnSize, height:btnSize, fontSize:btnFontSize, lineHeight:btnSize, color:btnColr}">+</text>
 	</view>
@@ -119,6 +125,9 @@ export default {
 			var newVal = Number(this.inputNumber) - Number(this.step);
 			if(newVal < this.minNum){return ;}
 			this.inputNumber = newVal;
+		},
+		inputval:function (e) {
+			this.inputNumber = e.detail.value;
 		}
 	}
 }

+ 84 - 80
lib/graceUI/weexComponents/graceNumberKeyboard.nvue

@@ -1,87 +1,91 @@
 <template>
-	<view>
-		<view class="grace-mask" @tap.stop="done" @touchmove.stop="" v-if="show"></view>
-		<view class="grace-keyboard" v-if="show">
-			<text class="grace-keyboard-res" v-if="showInputRes" 
-			:style="{color:resultColor, fontSize:resultSize}">{{resVal}}</text>
-			<view class="grace-keyboard-body">
-				<view class="grace-keyboard-left">
-					<text v-for="(item, index) in [1,2,3,4,5,6,7,8,9]" :key="index" 
-					class="grace-keyboard-keys" :class="[tapIndex == item ? 'keydown' : '']" :data-keynumber="item" @tap.stop="inputNow">{{item}}</text>
-					<text class="grace-keyboard-keys" :class="[tapIndex == 0 ? 'keydown' : '']" 
-					:style="{width: isPoint ? '259rpx':'538rpx'}" data-keynumber="0" @tap.stop="inputNow">0</text>
-					<text v-if="isPoint" class="grace-keyboard-keys" style="width:259rpx;" 
-					:class="[tapIndex == '.' ? 'keydown' : '']" data-keynumber="." @tap.stop="inputNow">.</text>
-				</view>
-				<view class="grace-keyboard-right">
-					<text class="grace-keyboard-keys grace-icons" 
-					:class="[tapIndex == -3 ? 'keydown' : '']" :data-keynumber="-3" @tap.stop="deleteNow">&#xe623;</text>
-					<text class="grace-keyboard-keys grace-keyboard-done" 
-					:style="{backgroundColor:confirmBtnColor}" @tap.stop="done">{{doneBtnName}}</text>
-				</view>
-			</view>
-		</view>
+	<view>
+		<view class="grace-mask" @tap.stop="masktap" @touchmove.stop.prevent="" v-if="show"></view>
+		<view class="grace-keyboard" v-if="show">
+			<text class="grace-keyboard-res" v-if="showInputRes" 
+			:style="{color:resultColor, fontSize:resultSize}">{{resVal}}</text>
+			<view class="grace-keyboard-body">
+				<view class="grace-keyboard-left">
+					<text v-for="(item, index) in [1,2,3,4,5,6,7,8,9]" :key="index" 
+					class="grace-keyboard-keys" :class="[tapIndex == item ? 'keydown' : '']" :data-keynumber="item" @tap.stop="inputNow">{{item}}</text>
+					<text class="grace-keyboard-keys" :class="[tapIndex == 0 ? 'keydown' : '']" 
+					:style="{width: isPoint ? '259rpx':'538rpx'}" data-keynumber="0" @tap.stop="inputNow">0</text>
+					<text v-if="isPoint" class="grace-keyboard-keys" style="width:259rpx;" 
+					:class="[tapIndex == '.' ? 'keydown' : '']" data-keynumber="." @tap.stop="inputNow">.</text>
+				</view>
+				<view class="grace-keyboard-right">
+					<text class="grace-keyboard-keys grace-icons" 
+					:class="[tapIndex == -3 ? 'keydown' : '']" :data-keynumber="-3" @tap.stop="deleteNow">&#xe623;</text>
+					<text class="grace-keyboard-keys grace-keyboard-done" 
+					:style="{backgroundColor:confirmBtnColor}" @tap.stop="done">{{doneBtnName}}</text>
+				</view>
+			</view>
+		</view>
 	</view>
 </template>
-<script>
-export default {
-	props: {
-		show         : { type : Boolean, default : false },
-		doneBtnName  : { type : String, default : "完成" },
-		isPoint      : { type : Boolean, default : true },
-		showInputRes : {type : Boolean, default : true},
-		value        : {type:String, default:''},
-		confirmBtnColor : {type:String, default:'#3688FF'},
-		resultColor  : {type:String, default:'#323232'},
-		resultSize   : {type:String, default:'32rpx'}
-	},
-	data() {
-		return {
-			resVal: '',
-			tapIndex : -1
-		}
-	},
-	created:function(){
-		this.resVal = this.value;
-	},
-	methods: {
-		inputNow : function (e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.resVal += k+'';
-			this.tapIndex = k;
-			this.$emit('keyboardInput', k);
-			this.removeClass();
-		},
-		deleteNow : function (e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.tapIndex = k;
-			this.resVal = this.resVal.substring(0, this.resVal.length - 1);
-			this.$emit('keyboardDelete');
-			this.removeClass();
-		},
-		done : function(e){
-			var k = e.currentTarget.dataset.keynumber;
-			this.tapIndex = k;
-			this.$emit('keyboardDone');
-			this.removeClass();
-		},
-		setVal : function (val) {
-			this.resVal = val;
-		},
-		removeClass : function () {
-			setTimeout(()=>{this.tapIndex = -1;}, 200);
-		}
-	}
+<script>
+export default {
+	props: {
+		show         : { type : Boolean, default : false },
+		doneBtnName  : { type : String, default : "完成" },
+		isPoint      : { type : Boolean, default : true },
+		showInputRes : {type : Boolean, default : true},
+		value        : {type:String, default:''},
+		confirmBtnColor : {type:String, default:'#3688FF'},
+		resultColor  : {type:String, default:'#323232'},
+		resultSize   : {type:String, default:'32rpx'},
+		closeByShade  : {type:Boolean, default:true}
+	},
+	data() {
+		return {
+			resVal: '',
+			tapIndex : -1
+		}
+	},
+	created:function(){
+		this.resVal = this.value+'';
+	},
+	methods: {
+		inputNow : function (e){
+			var k = e.currentTarget.dataset.keynumber;
+			this.resVal += k+'';
+			this.tapIndex = k;
+			this.$emit('keyboardInput', k);
+			this.removeClass();
+		},
+		deleteNow : function (e){
+			var k = e.currentTarget.dataset.keynumber;
+			this.tapIndex = k;
+			this.resVal = this.resVal.substring(0, this.resVal.length - 1);
+			this.$emit('keyboardDelete');
+			this.removeClass();
+		},
+		done : function(){
+			this.tapIndex = -3;
+			this.$emit('keyboardDone');
+			this.removeClass();
+		},
+		setVal : function (val) {
+			this.resVal = val;
+		},
+		removeClass : function () {
+			setTimeout(()=>{this.tapIndex = -1;}, 200);
+		},
+		masktap : function(){
+			if(!this.closeByShade){return ;}
+			this.done();
+		}
+	}
 }
 </script>
-<style scoped>
-.grace-mask{background-color:rgba(255, 255, 255, 0); position:fixed; width:750rpx; flex:1; left:0; top:0; bottom:0;}
-.grace-keyboard{background-color:#F4F5F6; position:fixed; width:750rpx; left:0; bottom:0;}
-.grace-keyboard-body{flex-direction:row; justify-content:space-between; padding:10px 0;}
-.grace-keyboard-left{width:560rpx; flex-direction:row; flex-wrap:wrap; justify-content:space-between;}
-.grace-keyboard-right{width:188rpx; flex-direction:column; justify-content:space-between;}
-.grace-keyboard-keys{width:166rpx; height:100rpx; margin:10rpx; background-color:#FFFFFF; text-align:center; line-height:100rpx; border-radius:8rpx; font-weight:700; font-size:50rpx;}
-.grace-keyboard-done{height:340rpx; line-height:340rpx; font-size:36rpx; font-weight:400; color:#FFFFFF;}
-.grace-keyboard-res{line-height:60rpx; text-align:center; font-size:32rpx; font-weight:bold; padding-top:20rpx;}
+<style scoped>
+.grace-mask{background-color:rgba(255, 255, 255, 0); position:fixed; width:750rpx; flex:1; left:0; top:0; bottom:0;}
+.grace-keyboard{background-color:#F4F5F6; position:fixed; width:750rpx; left:0; bottom:0;}
+.grace-keyboard-body{flex-direction:row; justify-content:space-between; padding:10px 0;}
+.grace-keyboard-left{width:560rpx; flex-direction:row; flex-wrap:wrap; justify-content:space-between;}
+.grace-keyboard-right{width:188rpx; flex-direction:column; justify-content:space-between;}
+.grace-keyboard-keys{width:166rpx; height:100rpx; margin:10rpx; background-color:#FFFFFF; text-align:center; line-height:100rpx; border-radius:8rpx; font-weight:700; font-size:50rpx;}
+.grace-keyboard-done{height:340rpx; line-height:340rpx; font-size:36rpx; font-weight:400; color:#FFFFFF;}
+.grace-keyboard-res{line-height:60rpx; text-align:center; font-size:32rpx; font-weight:bold; padding-top:20rpx;}
 .keydown{background-color:#3688FF; color:#FFFFFF;}
 </style>

+ 70 - 0
lib/graceUI/weexComponents/gracePK.nvue

@@ -0,0 +1,70 @@
+<template>
+	<view class="grace-pk-wrap" :style="{height:height,borderRadius:borderRadius}">
+		<!-- 背景 -->
+		<image src="https://img-cdn-qiniu.dcloud.net.cn/uploads/article/20200806/24692285f85690abbc762512ce22d2c5.png" 
+		class="grace-pk-bg" style="width:700rpx; height:466rpx;"></image>
+		<!-- pk 图标 -->
+		<view class="grace-pk-icon-wrap" :style="{height:height,borderRadius:borderRadius}">
+			<view class="grace-pk-icon">
+				<image src="https://img-cdn-qiniu.dcloud.net.cn/uploads/article/20200806/84515c21a39e8382addbeca53462e3a0.png" 
+				mode="widthFix" style="width:80rpx; height:80rpx;"></image>
+			</view>
+		</view>
+		<view class="grace-pk" :style="{height:height,borderRadius:borderRadius}">
+			<view class="grace-pk-item">
+				<text class="grace-pk-title">{{title[0]}}</text>
+				<view class="grace-pk-btn-wrap" v-if="status == 'button'">
+					<text class="grace-pk-btn" hover-class="grace-pk-btn-hv" 
+					data-index="left" @tap="choose">{{btnName}}</text>
+				</view>
+				<view class="grace-pk-btn-wrap" v-if="status == 'progress'">
+					<progress :percent="progress[0]" activeColor="#FFFFFF" stroke-width="3" class="grace-pk-progress" backgroundColor="#3699ff" />
+				</view>
+				<text class="grace-pk-text" v-if="status == 'progress'">{{progress[2]}}</text>
+			</view>
+			<view class="grace-pk-item">
+				<text class="grace-pk-title" style="text-align:right;">{{title[1]}}</text>
+				<view class="grace-pk-btn-wrap" style="justify-content:flex-end;" v-if="status == 'button'">
+					<text class="grace-pk-btn" hover-class="grace-pk-btn-hv" 
+					style="color:#FF0036;" data-index="right" @tap="choose">{{btnName}}</text>
+				</view>
+				<view class="grace-pk-btn-wrap" style="justify-content:flex-end;" v-if="status == 'progress'">
+					<progress :percent="progress[1]" stroke-width="3" class="grace-pk-progress" 
+					activeColor="#FFFFFF" backgroundColor="#FF6666"/>
+				</view>
+				<text class="grace-pk-text" style="text-align:right;" v-if="status == 'progress'">{{progress[3]}}</text>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		height       : {type:String, default:'260rpx'},
+		borderRadius : {type:String, default:'8rpx'},
+		title        : {type:Array, default:function(){return ['',''];}},
+		btnName      : {type:String, default:'站队'},
+		status       : {type:String, default:'button'},
+		progress     : {type:Array, default:function(){return [80,20,'8000 票', '2000 票'];}}
+	},
+	methods:{
+		choose:function (e) {
+			this.$emit('choose', e.currentTarget.dataset.index);
+		}
+	}
+}
+</script>
+<style>
+.grace-pk-wrap{font-size:0; overflow:hidden;}
+.grace-pk-bg{width:700rpx; position:absolute; left:0; top:0;}
+.grace-pk{flex-direction:row; justify-content:space-between;}
+.grace-pk-item{width:100rpx; overflow:hidden; padding-left:35rpx; padding-right:35rpx; flex:1; flex-direction:column; justify-content:center;}
+.grace-pk-title{color:#FFFFFF; font-size:50rpx; line-height:60rpx;}
+.grace-pk-btn-wrap{flex-direction:row; margin-top:32rpx;}
+.grace-pk-btn{width:150rpx; height:50rpx; line-height:50rpx; text-align:center; background-color:#FFFFFF; font-size:22rpx; border-radius:100rpx; color:#3687FF;}
+.grace-pk-btn-hv{font-weight:bold;}
+.grace-pk-progress{width:200rpx;}
+.grace-pk-text{font-size:22rpx; color:#FFFFFF; line-height:50rpx; margin-top:2px;}
+.grace-pk-icon-wrap{width:700rpx; position:absolute; top:0px; left:0rpx; flex-direction:row; justify-content:center; align-items:center;}
+.grace-pk-icon{width:120rpx; height:120rpx; padding-top:20rpx; padding-bottom:20rpx; padding-left:20rpx; padding-right:20rpx; background-color:#FFFFFF; border-radius:100rpx; font-size:0;}
+</style>

+ 7 - 6
lib/graceUI/weexComponents/gracePage.nvue

@@ -14,7 +14,7 @@
 				<view class="gui-page-header-nav" ref="gracePageHeader">
 					<view class="gui-header-main gui-flex-auto">
 						<slot name="gHeader"></slot>
-					</view>
+					</view>
 				</view>
 			</view>
 		</view>
@@ -25,7 +25,7 @@
 		<!-- 右下角悬浮按钮 -->
 		<view class="gui-page-rb-area" :style="{right:rbRight+'rpx', bottom:rbBottom+'rpx', width:rbWidth+'rpx'}"><slot name="gRTArea"></slot></view>
 		<!-- 全屏 loading -->
-		<view class="grace-page-loading" @tap.stop="" @touchmove.stop="" :style="{backgroundColor:loadingBG}" v-if="isLoading">
+		<view class="grace-page-loading" @tap.stop="" @touchmove.stop.prevent="" :style="{backgroundColor:loadingBG}" v-if="isLoading">
 			<view class="grace-page-loading-point">
 				<view class="grace-page-loading-points" ref="loadingPoints1" :style="{background:loadingPointBg}"></view>
 				<view class="grace-page-loading-points" ref="loadingPoints2" :style="{background:loadingPointBg}"></view>
@@ -49,8 +49,8 @@ export default{
 		rbBottom     : { type : Number, default : 100 },
 		rbRight      : { type : Number, default : 20 },
 		footerBg     : { type : String, default : '' },
-		flexVal      : { type : String, default : ''},
-		borderWidth  : { type : String,  default : '0' },
+		flexVal      : { type : String, default : ''},
+		borderWidth  : { type : String,  default : '0' },
 		borderColor  : { type : String,  default : '#D1D1D1' },
 		loadingBG    : { type : String,  default : 'rgba(255,255,255, 0.1)'},
 		isLoading    :  { type : Boolean, default : false },
@@ -72,7 +72,7 @@ export default{
 	},
 	methods:{
 		ldAnimation : function(){
-			if(this.animateCount >= 10){return ;}
+			if(!this.isLoading){return ;}
 			this.animateCount++;
 			var animations1 = this.$refs.loadingPoints1;
 			var animations2 = this.$refs.loadingPoints2;
@@ -100,6 +100,7 @@ export default{
 			},() => {this.ldAnimation2();});
 		},
 		ldAnimation2 : function(){
+			if(!this.isLoading){return ;}
 			var animations1 = this.$refs.loadingPoints1;
 			var animations2 = this.$refs.loadingPoints2;
 			var animations3 = this.$refs.loadingPoints3;
@@ -126,7 +127,7 @@ export default{
 			},() => {this.ldAnimation();});
 		},
 		getHeaderHeight:function(){
-			return this.headerHeight + thi.statusBarHeight;
+			return this.headerHeight + this.statusBarHeight;
 		}
 	},
 	created:function(){

+ 60 - 44
lib/graceUI/weexComponents/gracePopupMenu.nvue

@@ -1,54 +1,70 @@
 <template name="gracePopupMenu">
-	<view>
-		<view 
-		class="grace-popup-mask" v-if="show" @tap.stop="hideMenu" @touchmove.stop="" 
-		:style="{backgroundColor:background}">
-			<view class="grace-popup-menu" v-if="show"
-			:style="{top:top+'px', right:right, backgroundColor:bgColor, width:menuWidth, borderRadius:borderRadius}">
-				<slot></slot>
-			</view>
+	<view  class="grace-popup-mask" v-if="showIn" @tap.stop="hideMenu" @touchmove.stop.prevent=""
+	:style="{backgroundColor:background}">
+		<view class="grace-popup-menu" 
+		:style="{top:top+'px', right:right, backgroundColor:bgColor, width:menuWidth, borderRadius:borderRadius}">
+			<slot></slot>
 		</view>
 	</view>
 </template>
 <script>
-	export default {
-		name: "gracePopupMenu",
-		props: {
-			show:{
-				type : Boolean,
-				default : false
-			},
-			top:{
-				type : Number,
-				default : 0
-			},
-			bgColor:{
-				type : String,
-				default :'#FFFFFF'
-			},
-			menuWidth :{
-				type : String,
-				default : '258rpx'
-			},
-			background : {
-				type : String,
-				default : 'rgba(0,0,0, 0.3)'
-			},
-			right:{
-				type : String,
-				default:'0rpx'
-			},
-			borderRadius:{
-				type : String,
-				default:'0rpx'
-			}
-		},
-		methods: {
-			hideMenu : function() {
-				this.$emit('hideMenu');
-			}
+export default {
+	name: "gracePopupMenu",
+	props: {
+		show:{
+			type : Boolean,
+			default : false
 		},
+		top:{
+			type : Number,
+			default : 0
+		},
+		bgColor:{
+			type : String,
+			default :'#FFFFFF'
+		},
+		menuWidth :{
+			type : String,
+			default : '258rpx'
+		},
+		background : {
+			type : String,
+			default : 'rgba(0,0,0, 0.3)'
+		},
+		right:{
+			type : String,
+			default:'0rpx'
+		},
+		borderRadius:{
+			type : String,
+			default:'0rpx'
+		}
+	},
+	data() {
+		return {
+			showIn : false
+		}
+	},
+	created:function(){
+		if(this.show){this.open();}else{this.hide();}
+	},
+	watch:{
+		show : function(val,oval){
+			this.showIn = val;
+		}
+	},
+	methods: {
+		hideMenu : function() {
+			this.$emit('hideMenu');
+		},
+		open : function(){
+			this.showIn = true;
+		},
+		hide:function(){
+			this.showIn = false;
+		}
 	}
+}
 </script>
 <style scoped>
 .grace-popup-menu{background-color:#FFFFFF; width:258rpx; padding:10rpx; right:0px; top:0px; position:absolute;}

+ 2 - 2
lib/graceUI/weexComponents/graceReload.nvue

@@ -6,7 +6,7 @@
 			<text class="grace-reload-icon grace-icons" v-if="reloadStatus == 2" :style="{color:reloadColor[reloadStatus]}">&#xe7f8;</text>
 			<text class="grace-reload-text" :style="{color:reloadColor[reloadStatus]}">{{reloadTxt[reloadStatus]}}</text>
 		</view>
-		<!-- view class="grace-reload-shade" @tap.stop="" @touchstart.stop="" @touchmove.stop="" v-if="reloadStatus != 5"></view -->
+		<!-- view class="grace-reload-shade" @tap.stop="" @touchstart.stop="" @touchmove.stop.prevent="" v-if="reloadStatus != 5"></view -->
 	</view>
 </template>
 <script>
@@ -94,7 +94,7 @@ export default{
 			this.startY = e.moveY;
 			this.startTime = new Date().getTime();
 		},
-		touchmove:function (e) {
+		touchmove:function (e) {
 			if(this.reloadStatus == 3){
 				// 检查时间是否够长
 				var timer = new Date().getTime() - this.startTime;

+ 46 - 0
lib/graceUI/weexComponents/graceRightMessage.nvue

@@ -0,0 +1,46 @@
+<template>
+	<view class="graceRightMessage" v-if="showIn" 
+	:style="{
+		zIndex:zIndex, bottom:bottom, backgroundColor:background, width:status == 1 ? width : minWidth, 
+		height:height, borderRadius:height}">
+		<view class="graceRightMessageIcon"><slot name="icon"></slot></view>
+		<view class="graceRightMessageContent"><slot name="content"></slot></view>
+	</view>
+</template>
+<script>
+export default{
+	props:{
+		zIndex : {type:Number, default:99},
+		bottom : {type:String, default:'150rpx'},
+		width  : {type:String, default:'360rpx'},
+		height : {type:String, default:'80rpx'},
+		minWidth : {type:String, default:'180rpx'},
+		background : {type:String, default:'#3688FF'}
+	},
+	data() {
+		return {
+			showIn : true,
+			status : 1
+		}
+	},
+	methods:{
+		open:function () {
+			this.status = 1;
+		},
+		hide:function(){
+			this.showIn = false;
+		},
+		shrink:function(){
+			this.status = 2;
+		},
+		show:function(){
+			this.showIn = true;
+		}
+	}
+}
+</script>
+<style>
+.graceRightMessage{position:fixed; right:-100rpx; bottom:0; padding:10rpx; overflow:hidden; flex-direction:row; flex-wrap:nowrap; align-items:center; padding-right:100rpx;}
+.graceRightMessageIcon{text-align:center;}
+.graceRightMessageContent{width:1rpx; flex:1}
+</style>

+ 254 - 0
lib/graceUI/weexComponents/graceSchedule.nvue

@@ -0,0 +1,254 @@
+<template>
+	<view class="grace-schedule-wrap">
+		<view class="grace-schedule-header">
+			<picker class="grace-flex-center grace-flex-vcenter" 
+			mode="date" :value="currentDayIn" :start="startDate" :end="endDate" @change="selectDate">
+				<text class="grace-schedule-header-date grace-icons">{{cYear}} 年 {{cMonthStr}} 月 &#xe603;</text>
+			</picker>
+			<text class="grace-schedule-today" @tap="gotoToday">返回今天</text>
+		</view>
+		<view class="grace-date-week">
+			<text class="grace-date-weeks" v-for="(item, index) in weeks" :key="index">{{item}}</text>
+		</view>
+		<view class="grace-date-days">
+			<block v-for="(item, index) in days" :key="index">
+				<view class="grace-date-ditems"  v-if="item != ''" 
+				:style="{backgroundColor:currentDayIn == cYear+'-'+cMonthStr+'-'+ item.date ? activeBgColor : bgColor}" 
+				@click="chooseDate(cYear+'-'+cMonthStr+'-'+item.date, item.date)">
+					<text class="grace-date-day" 
+					:class="[currentDayIn == (cYear+'-'+cMonthStr+'-'+item.date) ? 'grace-d-current-txt' : '']">{{item.date}}</text>
+					<text class="grace-date-nl" v-if="isLunar" 
+					:class="[currentDayIn == (cYear+'-'+cMonthStr+'-'+item.date) ? 'grace-d-current-txt' : '']">{{item.nl}}</text>
+					<view class="grace-schedule-point" v-if="item.haveSe" :style="{backgroundColor:pointColor}"></view>
+				</view>
+				<view class="grace-date-ditems" v-else style="background-color:none;"></view>
+			</block>
+		</view>
+		<view class="grace-schedule-line"></view>
+		<view class="grace-schedule-time-list-wrap">
+			<view class="grace-schedule-time-list" v-for="(item, index) in hours" :key="index">
+				<text class="grace-schedule-timer">{{item}}:00</text>
+				<view class="grace-schedule-body">
+					<text class="grace-schedules" v-for="(schedule, idx) in schedulesIn[index]" :key="idx" 
+					@tap="scheduleTap" :data-id="schedule.id" 
+					:style="{backgroundColor:schedule.bgColor, color:schedule.color}">{{schedule.content}}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default{
+	data() {
+		return {
+			cYear      : 2020,
+			cMonth     : 1,
+			cDay       : 10,
+			cMonthStr  : '01',
+			weeks      : ['一', '二', '三', '四', '五', '六', '日'],
+			days       : [],
+			currentDayIn : '',
+			hours      : ['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'],
+			schedulesIn: [] 
+		}
+	},
+	props:{
+		// 当前默认日期
+		currentDate   : {type:String, default:""},
+		bgColor       : {type:String, default:"#F8F8F8"},
+		activeBgColor : {type:String, default:"#3688FF"},
+		isLunar       : {type:Boolean, default:true },
+		startDate     : {type:String, default:'1950-01-01'},
+		endDate       : {type:String, default:'2050-01-01'},
+		schedules     : {type:Array, default:function () {return []}},
+		pointColor    : {type:String, default:"#FF0036"}
+	},
+	created:function(){
+		this.currentDayIn = this.currentDate;
+		this.initTime();
+		this.getSchedulesIn();
+	},
+	methods:{
+		initTime : function(){
+			if(this.currentDayIn == ''){
+				var dateObj        = new Date();
+				this.cYear         = Number(dateObj.getFullYear());
+				this.cMonth        = Number(dateObj.getMonth() + 1);
+				this.cMonthStr     = this.cMonth < 10 ? '0' + this.cMonth : this.cMonth;
+				this.cDay          = dateObj.getDate();
+				this.cDay          = this.cDay < 10 ? '0' + this.cDay : this.cDay;
+				this.currentDayIn  = this.cYear + '-' + this.cMonthStr + '-' + this.cDay;
+				this.changeMonth();
+			}else{
+				var dates          = this.currentDayIn.split(' ');
+				if (!dates[1]) { dates[1] = '';}
+				var dayArr         = dates[0].split('-');
+				this.cYear         = Number(dayArr[0]);
+				this.cMonth        = dayArr[1];
+				this.cDay          = dayArr[2];
+				var reg            = new RegExp('^0[0-9]+$');
+				if(reg.test(this.cMonth)){this.cMonth = this.cMonth.substr(1,1);}
+				this.cMonth        = Number(this.cMonth);
+				this.cMonthStr     = this.cMonth < 10 ? '0'+this.cMonth : this.cMonth;
+				this.currentDayIn  = dates[0];
+				this.currentTimeIn = dates[1];
+				this.changeMonth();
+			}
+		},
+		changeMonth:function(){
+			var daysList  = [];
+			var days      = this.getDaysInOneMonth();
+			var startWeek = this.getDay();
+			var forSteps  = 0;
+			for (var i = (0 - startWeek); i < days; i++){
+				if(i >= 0){
+					daysList[forSteps] = {date : i >= 9 ? i + 1 : '0' + (i+1), nl : ''};
+					daysList[forSteps].nl = GetLunarDay(this.cYear, this.cMonth, i + 1);
+					daysList[forSteps].haveSe = this.haveSchedule(daysList[forSteps].date);
+				}else{
+					daysList[forSteps] = '';
+				}
+				forSteps++;
+			}
+			this.days    = daysList;
+		},
+		haveSchedule : function (day) {
+			var cDay = this.cYear+'-'+this.cMonthStr+'-'+day;
+			for(let i = 0; i < this.schedules.length; i++){
+				if(this.schedules[i].datetime.indexOf(cDay) != -1){
+					return true;
+				}
+			}
+			return false;
+		},
+		getDaysInOneMonth : function (){
+			var d = new Date(this.cYear, this.cMonth, 0);
+			return d.getDate();
+		},
+		getDay : function (){
+			var d = new Date(this.cYear, this.cMonth - 1, 0);
+			return d.getDay();
+		},
+		selectDate : function(e){
+			this.currentDayIn = e.detail.value;
+			this.initTime();
+			this.getSchedulesIn();
+			this.$emit('selectDate', e.detail.value);
+		},
+		chooseDate: function (sedDate) {
+			this.currentDayIn = sedDate;
+			this.getSchedulesIn();
+			this.$emit('chooseDate', sedDate);
+		},
+		getSchedulesIn : function (){
+			var res = [];
+			for(let i = 0; i < this.hours.length; i++){
+				var ctime = this.currentDayIn + ' ' + this.hours[i] + ':00';
+				res.push([]);
+				for(let ii = 0; ii < this.schedules.length; ii++){
+					if(this.schedules[ii].datetime == ctime){
+						res[i].push(this.schedules[ii]);
+					}
+				}
+			}
+			this.schedulesIn = res;
+		},
+		scheduleTap : function (e) {
+			var id = e.currentTarget.dataset.id;
+			this.$emit('scheduleTap', id);
+		},
+		gotoToday : function(){
+			var dateObj        = new Date();
+			this.cYear         = Number(dateObj.getFullYear());
+			this.cMonth        = Number(dateObj.getMonth() + 1);
+			this.cMonthStr     = this.cMonth < 10 ? '0' + this.cMonth : this.cMonth;
+			this.cDay          = dateObj.getDate();
+			this.cDay          = this.cDay < 10 ? '0' + this.cDay : this.cDay;
+			this.currentDayIn  = this.cYear + '-' + this.cMonthStr + '-' + this.cDay;
+			this.changeMonth();
+			this.getSchedulesIn();
+			this.$emit('gotoToday', this.currentDayIn);
+		}
+	}
+}
+var CalendarData = new Array(100);
+var madd = new Array(12);
+var tgString = "甲乙丙丁戊己庚辛壬癸";
+var dzString = "子丑寅卯辰巳午未申酉戌亥";
+var numString = "一二三四五六七八九十";
+var monString = "正二三四五六七八九十冬腊";
+var weekString = "日一二三四五六";
+var sx = "鼠牛虎兔龙蛇马羊猴鸡狗猪";
+var cYear, cMonth, cDay, TheDate;
+CalendarData = new Array(0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5, 0x50DA9, 0x5AD, 0x2B6, 0x3126E, 0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A, 0x4155B, 0x25D, 0x92D, 0x2192B, 0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5, 0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6, 0x414AE, 0xA57, 0x526, 0x31D26, 0xD95, 0x70B55, 0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54, 0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B, 0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957, 0x5092F, 0x497, 0x64B, 0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96, 0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D, 0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5, 0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95);
+madd[0] = 0;
+madd[1] = 31;
+madd[2] = 59;
+madd[3] = 90;
+madd[4] = 120;
+madd[5] = 151;
+madd[6] = 181;
+madd[7] = 212;
+madd[8] = 243;
+madd[9] = 273;
+madd[10] = 304;
+madd[11] = 334;
+function GetBit(m, n){return (m >> n) & 1;}
+//农历转换
+function e2c() {
+	TheDate = (arguments.length != 3) ? new Date() : new Date(arguments[0], arguments[1], arguments[2]);
+	var total, m, n, k;
+	var isEnd = false;
+	var tmp = TheDate.getYear();
+	if (tmp < 1900) {tmp += 1900;}
+	total = (tmp - 1921) * 365 + Math.floor((tmp - 1921) / 4) + madd[TheDate.getMonth()] + TheDate.getDate() - 38;
+	if (TheDate.getYear() % 4 == 0 && TheDate.getMonth() > 1) {total++;}
+	for (m = 0; ; m++) {
+		k = (CalendarData[m] < 0xfff) ? 11 : 12;
+		for (n = k; n >= 0; n--) {
+			if (total <= 29 + GetBit(CalendarData[m], n)) {isEnd = true; break;}
+			total = total - 29 - GetBit(CalendarData[m], n);
+		}
+		if (isEnd) break;
+	}
+	cYear = 1921 + m;
+	cMonth = k - n + 1;
+	cDay = total;
+	if (k == 12) {
+		if (cMonth == Math.floor(CalendarData[m] / 0x10000) + 1) {cMonth = 1 - cMonth;}
+		if (cMonth > Math.floor(CalendarData[m] / 0x10000) + 1) {cMonth--;}
+	}
+}
+function GetcDateString() {
+	var tmp = "";
+	tmp += (cDay < 11) ? "初" : ((cDay < 20) ? "十" : ((cDay < 30) ? "廿" : "三十"));
+	if (cDay % 10 != 0 || cDay == 10) {tmp += numString.charAt((cDay - 1) % 10);}
+	return tmp;
+}
+function GetLunarDay(solarYear, solarMonth, solarDay) {
+	if (solarYear < 1921) {return "";}
+	solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11;
+	e2c(solarYear, solarMonth, solarDay);
+	return GetcDateString();
+}
+</script>
+<style>
+.grace-schedule-wrap{width:702rpx; margin-left:24rpx;}
+.grace-schedule-header{flex-direction:row; justify-content:space-between; align-items:center;}
+.grace-schedule-header-date{height:88rpx; line-height:88rpx; color:#323232; font-size:32rpx;}
+.grace-date-week{width:702rpx; flex-wrap:nowrap; flex-direction:row; justify-content:center;}
+.grace-date-weeks{width:100rpx; height:60rpx; font-size:26rpx; line-height:60rpx; color:#666666; text-align:center;}
+.grace-date-days{width:702rpx; flex-direction:row; flex-wrap:wrap;}
+.grace-date-ditems{width:80rpx; height:80rpx; flex-direction:column; align-items:center; justify-content:center; margin:10rpx; border-radius:80rpx;}
+.grace-d-current-txt{color:#FFFFFF !important;}
+.grace-date-day{height:38rpx; line-height:38rpx; text-align:center; font-size:28rpx;}
+.grace-date-nl{height:26rpx; line-height:26rpx; color:#888888; font-size:20rpx; text-align:center;}
+.grace-schedule-line{height:20rpx; border-style:solid; border-color:#F8F8F8; border-bottom-width:1px;}
+.grace-schedule-time-list{margin-top:20rpx; flex-direction:row; flex-wrap:nowrap; align-items:flex-start;}
+.grace-schedule-timer{width:100rpx; font-size:22rpx; color:#999999; line-height:36rpx;}
+.grace-schedule-body{width:200rpx; flex:1; border-style:solid; border-color:#F8F8F8; border-top-width:1px; margin-top:15rpx;}
+.grace-schedules{padding:10rpx; line-height:30rpx; font-size:22rpx; margin-top:15rpx; border-radius:8rpx;}
+.grace-schedule-time-list-wrap{padding:20rpx;}
+.grace-schedule-today{line-height:50rpx; height:50rpx; font-size:22rpx; color:#828282; padding-left:20rpx; padding-right:20rpx; margin-left:30rpx; border-radius:8rpx; border-width:1px; border-style:solid; border-color:#F1F2F3;}
+.grace-schedule-point{width:18rpx; height:18rpx; border-radius:10rpx; background-color:#FF0036; position:absolute; right:5rpx; top:5rpx;}
+</style>

+ 27 - 12
lib/graceUI/weexComponents/graceSelectImg.nvue

@@ -1,7 +1,7 @@
 <template>
 	<view class="grace-add-list">
 		<view class="grace-add-list-items" v-for="(item, index) in imgLists" :key="index">
-			<image :src="item" :data-imgurl="item" @tap="showImgs" class="grace-add-list-img" :mode="imgMode"></image>
+			<image :src="item.url" :data-imgurl="item.url" @tap="showImgs" class="grace-add-list-img" :mode="imgMode"></image>
 			<text class="grace-add-list-remove grace-icons" @tap="removeImg" :id="'grace-items-img-'+index" :style="{color:closeBtnColor}">&#xe632;</text>
 		</view>
 		<view class="grace-add-list-items grace-add-list-btn" @tap="addImg" v-if="imgLists.length < maxFileNumber">
@@ -42,43 +42,58 @@ export default {
 		}
 	},
 	created:function () {
-		this.imgLists = this.items;
+		this.initImgs();
 	},
 	watch:{
-		imgLists : function(newVal, oldVal){
-			this.$emit('change', newVal);
-		}
+		items:function(){this.initImgs();}
 	},
     methods:{
+		initImgs : function(){
+			var imgs = [];
+			for(let i = 0; i < this.items.length; i++){
+				imgs.push({url:this.items[i],  progress : 100});
+			}
+			this.imgLists = imgs;
+		},
         addImg : function(){
             var num = this.maxFileNumber - this.imgLists.length;
             if(num < 1){return false;}
-            uni.showLoading({title:""});
             uni.chooseImage({
                 count: num,
                 sizeType: ['compressed'],
                 success:(res) => {
-                    this.imgLists = this.imgLists.concat(res.tempFilePaths);
-                    uni.hideLoading();
+					for(let i = 0; i < res.tempFilePaths.length; i++){
+						this.imgLists.push({url:res.tempFilePaths[i], progress:0})
+					}
+                    this.$emit('change', this.imgLists);
                 },
 				fail:function(){
-					uni.hideLoading();
+					//uni.hideLoading();
 				}
             });
         },
         removeImg : function(e){
             var index = e.currentTarget.id.replace('grace-items-img-', '');
-            this.imgLists.splice(index, 1);
+			var removeImg =  this.imgLists.splice(index, 1);
+			this.$emit('removeImg', removeImg[0]);
+			this.$emit('change', this.imgLists);
         },
         showImgs : function(e){
             var currentImg = e.currentTarget.dataset.imgurl;
+			var imgs = [];
+			for(let i = 0; i < this.imgLists.length; i++){
+				imgs.push(this.imgLists[i].url);
+			}
             uni.previewImage({
-              urls: this.imgLists,
+              urls: imgs,
               current : currentImg
             })
         },
 		setItems : function(items){
-			this.imgLists = items;
+			this.imgLists = [];
+			for(let i = 0; i < items.length; i++){
+				this.imgLists.push({url : items[i], progress : 100});
+			}
 		}
     }
 }

+ 4 - 2
lib/graceUI/weexComponents/graceSelectImgAndUpload.nvue

@@ -99,7 +99,8 @@ export default {
         },
         removeImg : function(e){
             var index = e.currentTarget.id.replace('grace-items-img-', '');
-            this.imgLists.splice(index, 1);
+            var removeImg =  this.imgLists.splice(index, 1);
+            this.$emit('removeImg', removeImg[0]);
         },
         showImgs : function(e){
             var currentImg = e.currentTarget.dataset.imgurl;
@@ -186,8 +187,9 @@ export default {
 		},
 		// 设置默认值
 		setItems : function(items){
+			this.imgLists = [];
 			for(let i = 0; i < items.length; i++){
-				this.imgLists.push({url : items[i], progress : 100, error : false});
+				this.imgLists.push({url : items[i], progress : 100});
 			}
 		},
 		imgLoad : function (e) {

+ 17 - 9
lib/graceUI/weexComponents/graceSelectList.nvue

@@ -1,14 +1,19 @@
 <template>
 	<view class="select-list">
 		<view v-for="(item, index) in dataIn" :key="index" class="select-list-item" :data-index="index" @tap.stop="choose">
-			<image :src="item.img" class="select-list-img" v-if="item.img" mode="widthFix" :style="{width:imgSize[0], height:imgSize[1]}"></image>
-			<view class="select-list-body" :class="[isBorder?'grace-border-b':'']">
-				<text class="select-list-content" :style="{fontSize:fontSize, lineHeight:lineHeight, color:itemColor}">{{item.title}}</text>
+			<image :src="item.img" class="select-list-img" v-if="item.img" mode="widthFix" 
+			:style="{width:imgSize[0], height:imgSize[1], borderRadius:imgBorderRadius}"></image>
+			<view class="select-list-body" :class="[isBorder?'grace-border-b':'']" 
+			:style="{borderBottomColor:borderColor}">
+				<view class="select-list-content">
+					<text :style="{fontSize:fontSize, lineHeight:lineHeight, color:itemColor}">{{item.title}}</text>
+					<text class="select-list-desc" v-if="item.desc">{{item.desc}}</text>
+				</view>
 				<text class="select-list-icon grace-icons" v-if="item.checked" :style="{color:item.checked ? checkColor : '#A5A7B2'}">&#xe60f;</text>
 			</view>
 		</view>
-	</view>
-</template>
+	</view>
+</template>
 <script>
 export default{
 	props:{
@@ -16,10 +21,12 @@ export default{
 		checkColor:{type:String, default:"#3688FF"},
 		type : { type: String, default: "radio"},
 		imgSize:{type:Array, default:function(){return ['68rpx','68rpx'];}},
+		imgBorderRadius:{type: String, default: "60rpx"},
 		fontSize:{type: String, default: "28rpx"},
 		isBorder:{type:Boolean, default:true},
 		lineHeight:{type: String, default: "50rpx"},
-		itemColor:{type:String, default:"#323232"}
+		itemColor:{type:String, default:"#323232"},
+		borderColor:{type:String, default:"#F6F6F6"}
 	},
 	data() {
 		return {
@@ -64,13 +71,14 @@ export default{
 			}
 		}
 	}
-}
-</script>
+}
+</script>
 <style>
 .select-list{}
 .select-list-item{flex-direction:row; flex-wrap:nowrap; align-items:center; font-size:0;}
 .select-list-icon{width:60rpx; line-height:60rpx; text-align:center; font-size:36rpx; color:#A5A7B2; font-weight:700; margin-left:28rpx;}
 .select-list-img{border-radius:60rpx; margin-right:28rpx;}
 .select-list-body{width:300rpx; flex:1; flex-wrap:nowrap; flex-direction:row; align-items:center;}
-.select-list-content{width:200rpx; flex:1; overflow:hidden; margin-top:25rpx; margin-bottom:25rpx;}
+.select-list-content{width:200rpx; flex:1; overflow:hidden; margin-top:25rpx; margin-bottom:25rpx;}
+.select-list-desc{font-size:22rpx; color:#828282; line-height:40rpx;}
 </style>

+ 29 - 11
lib/graceUI/weexComponents/graceSelectMenu.nvue

@@ -5,8 +5,15 @@
 			<text class="grace-select-menu-title-icon grace-icons" v-if="!show">&#xe603;</text>
 			<text class="grace-select-menu-title-icon grace-icons" v-if="show">&#xe654;</text>
 		</view>
-		<view class="grace-select-menu" @click.stop="close" @touchmove.stop="" v-if="show">
+		<view class="grace-select-menu" @click.stop="close" @touchmove.stop.prevent="" v-if="show">
 			<scroll-view class="grace-select-menus" scroll-y :style="{padding:padding, height:height+'rpx'}">
+				<view @tap.stop="" class="grace-select-item" v-if="isInput"
+				style="flex-direction:row; flex-wrap:nowrap; align-items:center;">
+					<view class="grace-select-input-wrap">
+						<input type="text" v-model="inputVal" class="grace-select-input" @confirm="addTag" :placeholder="placeholder" />
+					</view>
+					<text class="grace-select-input-btn" @tap.stop="addTag" @touchmove.stop.prevent="">{{addBtnName}}</text>
+				</view>
 				<view class="grace-select-item" v-for="(item, index) in items" :key="index" :data-index="index" @click.stop="select">
 					<text class="grace-selected-icon grace-icons" :style="{color : index == currentIndex ? activeColor : color}" v-if="index == currentIndex">&#xe7f8;</text>
 					<text class="grace-selected-text" :style="{color : index == currentIndex ? activeColor : color, fontSize:fontSize}">{{item}}</text>
@@ -30,7 +37,7 @@ export default {
 		},
 		height : {
 			type : Number,
-			default : 300
+			default : 500
 		},
 		color : {
 			type : String,
@@ -43,15 +50,18 @@ export default {
 		selectIndex : {
 			type : Number,
 			default : 0
-		},
-		fontSize : {
-			type : String,
-			default : '26rpx'
-		},
-		padding:{
-			type : String,
-			default : "20rpx"
-		}
+		},
+		fontSize : {
+			type : String,
+			default : '26rpx'
+		},
+		padding:{
+			type : String,
+			default : "20rpx"
+		},
+		isInput:{type:Boolean, default:false},
+		placeholder:{type:String, default:"自定义"},
+		addBtnName:{type:String, default:"+ 添加"}
 	},
 	data() {
 		return {
@@ -79,6 +89,11 @@ export default {
 			this.currentIndex = index;
 			this.$emit('select', index);
 			this.close();
+		},
+		addTag : function () {
+			if(this.inputVal == ''){return ;}
+			this.$emit('submit', this.inputVal);
+			this.inputVal = '';
 		}
 	}
 }
@@ -93,4 +108,7 @@ export default {
 .grace-select-item{padding:10rpx; background-color:#FFFFFF; font-size:28rpx; color:#333333; border-bottom-width:1px; border-bottom-style:solid; border-bottom-color:#F8F8F8; flex-direction:row; flex-wrap:nowrap; align-items:center;}
 .grace-selected-icon{font-size:28rpx; line-height:80rpx; margin-right:20rpx;}
 .grace-selected-text{font-size:28rpx; line-height:80rpx;}
+.grace-select-input-wrap{width:200rpx; flex:1;}
+.grace-select-input{line-height:60rpx; height:60rpx; font-size:28rpx; margin-top:20rpx;margin-bottom:20rpx;}
+.grace-select-input-btn{width:120rpx; line-height:60rpx; height:60rpx; text-align:center; background-color:#F8F8F8; font-size:24rpx; border-radius:6rpx; color:#3688FF;}
 </style>

+ 46 - 41
lib/graceUI/weexComponents/graceSelectTags.nvue

@@ -12,35 +12,33 @@
 <script>
 export default {
 	props: {
-		type : { type: String, default: "radio"},
-		items : { type: Array, default : function(){return []}},
-		itemWidth : {type: String, default:"220rpx"},
-		selectedColor:{type: String, default:"#3688FF"},
+		itemWidth : {type: String, default:"200rpx"},
+		type : { type: String, default: ""},
+		selectedColor : { type: String, default: "#3688FF"},
 		fontSize : { type: String, default: "26rpx"},
+		items : { type: Array, default : function(){return []}},
+		datas : { type: Array, default : function(){return []}},
 		bgColor :  { type: String, default: "#F6F7F8"},
 		height:{type: String, default:"68rpx"},
 		borderRadius : {type: String, default:"10rpx"},
 		fontColor:{type: String, default:"#323232"},
 		fontActiveColor:{type: String, default:"#FFFFFF"}
 	},
-	created : function(){
-		this.tagsData = this.items;
-	},
 	created : function(){
-		this.tagsData = this.items == null ? [] : this.items;
-		this.initChange();
-	},
-	data() {
-		return {
-			tagsData : []
-		}
+		this.tagsData = this.items == null ? [] : this.items;
+		this.initChange();
+	},
+	data() {
+		return {
+			tagsData : []
+		}
 	},
 	watch:{
 		items:function(val){
 			this.tagsData = val;
 			this.initChange();
 		}
-	},
+	},
 	methods:{
 		initChange : function () {
 			if(this.type == 'radio'){
@@ -52,7 +50,7 @@ export default {
 						selectVal   = this.tagsData[i].value;
 					}
 				}
-				this.$emit("change", selectVal, this.datas, selectIndex);
+				//this.$emit("change", selectVal, this.datas, selectIndex);
 			}else{
 				var sedRes = [], indexs = [];
 				for (var i = 0; i < this.tagsData.length; i++){
@@ -61,38 +59,44 @@ export default {
 						indexs.push(i);
 					}
 				}
-				this.$emit("change", sedRes, this.datas, indexs);
+				//this.$emit("change", sedRes, this.datas, indexs);
 			}
-		},
-		graceSelectChange : function(index){
-			if(this.type == 'radio'){
+		},
+		graceSelectChange : function(index){
+			// 单选
+			if(this.type == 'radio'){
 				for (var i = 0; i < this.tagsData.length; i++){
 					this.tagsData[i].checked = false;
 					this.tagsData.splice(i,1,this.tagsData[i]);
-				}
+				}
 				this.tagsData[index].checked = true;
-				this.tagsData.splice(index,1,this.tagsData[index]);
-				this.$emit("change", this.tagsData[index].value, this.datas, index);
-			}else{
-				if(this.tagsData[index].checked){
-					this.tagsData[index].checked = false;
-				}else{
-					this.tagsData[index].checked = true;
-				}
-				var sedRes = [], indexs = [];
-				for (var i = 0; i < this.tagsData.length; i++){
-					if(this.tagsData[i].checked){
+				this.tagsData.splice(index,1,this.tagsData[index]);
+				this.$emit("change", this.tagsData[index].value, this.datas, index);
+			}
+			//  多选
+			else{
+				if(this.tagsData[index].checked){
+					this.tagsData[index].checked = false;
+				}else{
+					this.tagsData[index].checked = true;
+				}
+				this.tagsData.splice(index,1,this.tagsData[index]);
+				var sedRes = [], indexs = [];
+				for (var i = 0; i < this.tagsData.length; i++){
+					if(this.tagsData[i].checked){
 						sedRes.push(this.tagsData[i].value);
-						indexs.push(i);
-					}
-				}
-				this.$emit("change", sedRes, this.datas, indexs);
-			}
-		},
+						indexs.push(i);
+					}
+				}
+				this.$emit("change", sedRes, this.datas, indexs);
+			}
+		},
+		// 设置新的选项
 		setItems : function(items){
 			this.tagsData = items;
 			this.initChange();
-		},
+		},
+		// 全不选
 		clearSelected:function(){
 			var newData = [];
 			for(let i = 0; i < this.tagsData.length; i++){
@@ -105,7 +109,8 @@ export default {
 			}else{
 				this.$emit("change", [], this.datas, []);
 			}
-		},
+		},
+		// 全选
 		selectAll : function () {
 			if(this.type == 'radio'){return ;}
 			var newData = [],reDatas = [], reIndex = [];
@@ -117,7 +122,7 @@ export default {
 			}
 			this.tagsData = newData;
 			this.$emit("change", reDatas, this.datas, reIndex);
-		}
+		}
 	}
 }
 </script>

+ 49 - 10
lib/graceUI/weexComponents/graceShade.nvue

@@ -1,22 +1,61 @@
 <template>
-	<view class="grace-shade" :style="{backgroundColor:background}" v-if="show" @tap.stop="closeShade" @touchmove.stop="">
+	<view class="grace-shade" ref="graceShade" 
+	:style="{backgroundColor:background, left:left}" 
+	@tap.stop="closeShade" @touchmove.stop.prevent="">
 		<slot></slot>
-	</view>
-</template>
+	</view>
+</template>
 <script>
+var animation = weex.requireModule('animation');
+const dom = weex.requireModule('dom');
 export default{
 	props:{
 		background : {type:String, default:"rgba(0, 0, 0, 0.1)"},
 		zIndex : {type:Number, default:1},
 		show : {type:Boolean, default:true}
 	},
-	methods:{
-		closeShade : function(){
-			this.$emit('closeShade');
-		}
+	data() {
+		return {
+			left : '-2000px'
+		}
+	},
+	created:function(){
+		if(this.show){ this.showIt(); }else{ this.hideIt();}
+	},
+	watch:{
+		show:function(val){
+			if(val){ this.showIt(); }else{ this.hideIt(); }
+		}
+	},
+	methods:{
+		closeShade : function(){this.$emit('closeShade');},
+		showIt : function(){
+			this.left = '0px';
+			var graceShade = this.$refs.graceShade;
+			animation.transition(graceShade, {
+				styles: {opacity:1},
+				duration:280, 
+				timingFunction: 'ease',
+				needLayout:false,
+				delay: 0 
+			});
+		},
+		hideIt : function(){
+			var graceShade = this.$refs.graceShade;
+			animation.transition(graceShade, {
+				styles: {opacity:0},
+				duration:280, 
+				timingFunction: 'ease',
+				needLayout:false,
+				delay: 0 
+			});
+			setTimeout(()=>{
+				this.left = '0px';
+			}, 280);
+		}
 	}
-}
-</script>
+}
+</script>
 <style scoped>
-.grace-shade{position:fixed; width:750rpx; left:0; top:0; bottom:0; z-index:1; justify-content:center; align-items:center;}
+.grace-shade{position:fixed; width:750rpx; left:-2000px; opacity:0; top:0; bottom:0; z-index:1; justify-content:center; align-items:center;}
 </style>

+ 2 - 2
lib/graceUI/weexComponents/graceSlider.nvue

@@ -6,10 +6,10 @@
 		:style="{backgroundColor:activeColor, width:activeWidth+'px', height:height+'px', marginLeft:activeLeft+'px', top:lineTop+'px'}"></view>
 		<view class="grace-slider-block" 
 		:style="{backgroundColor:blockBgColor, height:blockSize+'px', width:blockSize+'px', 'margin-left':xMin+'px'}" 
-		@touchstart.stop="touchstart" @touchmove.stop="touchmove" data-tag="min"></view>
+		@touchstart.stop="touchstart" @touchmove.stop.prevent="touchmove" data-tag="min"></view>
 		<view class="grace-slider-block" 
 		:style="{backgroundColor:blockBgColor, height:blockSize+'px', width:blockSize+'px', 'margin-left':xMax+'px'}" 
-		@touchstart.stop="touchstart" @touchmove.stop="touchmove" data-tag="max"></view>
+		@touchstart.stop="touchstart" @touchmove.stop.prevent="touchmove" data-tag="max"></view>
 	</view>
 </template>
 <script>

+ 7 - 3
lib/graceUI/weexComponents/graceSpeaker.nvue

@@ -1,7 +1,8 @@
 <template name="graceSpeaker">
 	<view class="grace-swiper-msg">
 		<view class="grace-swiper-msg-icon"><slot></slot></view>
-		<swiper :vertical="vertical" autoplay="true" circular="true" :interval="interval" class="grace-swiper-msg-swiper" :style="{height:height}">
+		<swiper :vertical="vertical" autoplay="true" circular="true" @change="change" 
+		:interval="interval" class="grace-swiper-msg-swiper" :style="{height:height}">
 			<swiper-item v-for="(item, index) in msgs" :key="index" class="grace-swiper-msg-swiper-item" :style="{height:height}">
 				<text @tap="navto"
 				:data-url="item.url" :data-opentype="item.opentype" class="grace-swiper-msg-text" 
@@ -20,7 +21,7 @@ export default {
 		},
 		interval : {
 			type : Number,
-			default: 3000
+			default: 5000
 		},
 		vertical : {
 			type : Boolean,
@@ -45,7 +46,7 @@ export default {
 		fontWeight : {
 			type  : String,
 			default : ""
-		},
+		}
 	},
 	methods:{
 		navto : function (e) {
@@ -70,6 +71,9 @@ export default {
 				default:
 					break;
 			}
+		},
+		change:function (index) {
+			this.$emit('change', index.detail.current);
 		}
 	}
 }

Някои файлове не бяха показани, защото твърде много файлове са промени