gcz 4 rokov pred
rodič
commit
4d6d5f4e8c
68 zmenil súbory, kde vykonal 1756 pridanie a 4521 odobranie
  1. 1 1
      components/custom-nodata/custom-nodata.vue
  2. 1 1
      config/config.js
  3. 26 24
      main.js
  4. 9 9
      pages.json
  5. 1 2
      pages/index/index.css
  6. 39 35
      pages/index/index.vue
  7. 5 5
      pages/index/modal/quickBuy.vue
  8. 0 43
      pages/login/login.vue
  9. 12 9
      pages/login/loginType.vue
  10. 1 1
      pages/use/use.css
  11. 5 2
      pages/use/use.vue
  12. 136 0
      pages/usercenter/certificateList/certificate/certificate-bak.vue
  13. 108 102
      pages/usercenter/certificateList/certificate/certificate.vue
  14. 2 2
      pages/usercenter/certificateList/certificateList.vue
  15. 5 4
      pages/usercenter/orderList/orderList.vue
  16. 1 1
      pages/usercenter/usercenter.vue
  17. BIN
      static/html2canvas/bg.png
  18. BIN
      static/html2canvas/bg.webp
  19. BIN
      static/html2canvas/code.png
  20. 0 368
      static/html2canvas/credTpl.html
  21. 0 3519
      static/html2canvas/html2canvas.js
  22. 0 128
      static/html2canvas/index.html
  23. BIN
      static/html2canvas/logo.png
  24. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/common/main.js.map
  25. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/common/vendor.js.map
  26. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/components/mescroll-uni/components/mescroll-empty.js.map
  27. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/components/mescroll-uni/components/mescroll-top.js.map
  28. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/components/mescroll-uni/mescroll-body.js.map
  29. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/components/uni-popup/uni-popup-dialog.js.map
  30. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/components/uni-popup/uni-popup.js.map
  31. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/components/uni-transition/uni-transition.js.map
  32. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/guide.js.map
  33. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/index.js.map
  34. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/init.js.map
  35. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/login/companyLogin.js.map
  36. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/login/loginType.js.map
  37. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/use/use.js.map
  38. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/certificateList/certificateList.js.map
  39. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/orderList/orderList.js.map
  40. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/orderList/orderdetails/orderdetails.js.map
  41. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/subscribe/subscribe.js.map
  42. 1 1
      unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/usercenter.js.map
  43. 1 0
      unpackage/dist/dev/mp-weixin/app.json
  44. 30 28
      unpackage/dist/dev/mp-weixin/common/main.js
  45. 575 20
      unpackage/dist/dev/mp-weixin/common/vendor.js
  46. 15 15
      unpackage/dist/dev/mp-weixin/components/mescroll-uni/components/mescroll-empty.js
  47. 14 14
      unpackage/dist/dev/mp-weixin/components/mescroll-uni/components/mescroll-top.js
  48. 22 22
      unpackage/dist/dev/mp-weixin/components/mescroll-uni/mescroll-body.js
  49. 14 14
      unpackage/dist/dev/mp-weixin/components/uni-popup/uni-popup-dialog.js
  50. 16 16
      unpackage/dist/dev/mp-weixin/components/uni-popup/uni-popup.js
  51. 14 14
      unpackage/dist/dev/mp-weixin/components/uni-transition/uni-transition.js
  52. 34 26
      unpackage/dist/dev/mp-weixin/pages/index/index.js
  53. 1 0
      unpackage/dist/dev/mp-weixin/pages/index/index.json
  54. 1 1
      unpackage/dist/dev/mp-weixin/pages/index/index.wxml
  55. 1 0
      unpackage/dist/dev/mp-weixin/pages/index/index.wxss
  56. 12 9
      unpackage/dist/dev/mp-weixin/pages/login/loginType.js
  57. 3 0
      unpackage/dist/dev/mp-weixin/pages/login/loginType.wxss
  58. 3 5
      unpackage/dist/dev/mp-weixin/pages/use/use.js
  59. 1 1
      unpackage/dist/dev/mp-weixin/pages/use/use.wxml
  60. 1 1
      unpackage/dist/dev/mp-weixin/pages/use/use.wxss
  61. 2 2
      unpackage/dist/dev/mp-weixin/pages/usercenter/certificateList/certificateList.js
  62. 1 1
      unpackage/dist/dev/mp-weixin/pages/usercenter/certificateList/certificateList.wxml
  63. 42 20
      unpackage/dist/dev/mp-weixin/pages/usercenter/orderList/orderList.js
  64. 1 1
      unpackage/dist/dev/mp-weixin/pages/usercenter/orderList/orderList.wxml
  65. 18 18
      unpackage/dist/dev/mp-weixin/pages/usercenter/orderList/orderdetails/orderdetails.js
  66. 17 17
      unpackage/dist/dev/mp-weixin/pages/usercenter/subscribe/subscribe.js
  67. 1 1
      unpackage/dist/dev/mp-weixin/pages/usercenter/usercenter.wxml
  68. 545 0
      utils/wxml2canvas.js

+ 1 - 1
components/custom-nodata/custom-nodata.vue

@@ -28,7 +28,7 @@
 	}
 </script>
 
-<style scoped>
+<style>
 	.nodata{
 		width:560rpx;
 		margin:0 auto;

+ 1 - 1
config/config.js

@@ -30,7 +30,7 @@ const config = {
 	// 云图片(产品)
 	onlineImg:"http://cqth.hw.hongweisoft.com/ht/",
 	// 七牛云
-	qny:"http://fqn.hongweisoft.com/cqcarbon/wxapp/",
+	qnyImg:"http://fqn.hongweisoft.com/cqcarbon/wxapp/",
 }
 export {
 	config

+ 26 - 24
main.js

@@ -6,32 +6,33 @@ import store from './store'
 import Request from '@/js_sdk/luch-request/luch-request/index.js';
 const http = new Request();
 http.interceptors.response.use((response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
-  //  if (response.data.retHead.errCode !== 200) { // 服务端返回的状态码不等于200,则reject()
-	 //   uni.showToast({
-		// icon:'none',
-		// mask:false,
-		// title:`${response.data.message}`,
-		// duration: 2000
-	 //   });
-	 // };
+   if (response.data.code == 1) { // 服务端返回的状态码不等于200,则reject()
+	   uni.showToast({
+		icon:'none',
+		mask:false,
+		title:`${response.data.msg}`,
+		duration: 2000
+	   });
+	   return Promise.reject(response) 
+	 };
 	 // console.log('response',response);
-	 // if(response.data.code == 401){
-		// uni.showToast({
-		//  	title:response.data.message + "    即将跳转到登录页",
-		//  	icon:"none",
-		//  	duration:2000
-		// });
-		// setTimeout(i=>{
-		// 	uni.navigateTo({
-		// 		url: '/pages/login/loginType',
-		// 		fail:function(err){
-		// 			console.log(err)
-		// 		}
-		// 	});
-		// },2000);
-		// return Promise.reject(response) 
+	 if(response.data.code == 401){
+		uni.showToast({
+		 	title:response.data.message + "    即将跳转到登录页",
+		 	icon:"none",
+		 	duration:2000
+		});
+		setTimeout(i=>{
+			uni.navigateTo({
+				url: '/pages/login/loginType',
+				fail:function(err){
+					console.log(err)
+				}
+			});
+		},2000);
+		return Promise.reject(response) 
 		
-	 // };
+	 };
      // return Promise.reject(response) // return Promise.reject 可使promise状态进入catch
  if (response.config.custom.verification) { // 演示自定义参数的作用
     return response.data
@@ -81,6 +82,7 @@ Vue.prototype.$getimg = config.imgUrl;
 Vue.prototype.$getInnerImg = config.innerImgUrl;
 Vue.prototype.$onlineImg = config.onlineImg;
 Vue.prototype.$placeImg = config.placeImg;
+Vue.prototype.$qnyImg = config.qnyImg;
 Vue.prototype.$store = store;
 Vue.prototype.config = config;
 

+ 9 - 9
pages.json

@@ -1,14 +1,14 @@
 {
 	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
-		// {
-		// 	"path": "pages/index/init",
-		// 	"navigationStyle":"custom"
-		// 	,"style": {
-		// 		"navigationBarBackgroundColor":"#fff",
-		// 		"navigationBarTitleText": "入口页"//入口页
-		// 		// ,"titleNView": false
-		// 	}
-		// },
+		{
+			"path": "pages/index/init",
+			"navigationStyle":"custom"
+			,"style": {
+				"navigationBarBackgroundColor":"#fff",
+				"navigationBarTitleText": "入口页"//入口页
+				// ,"titleNView": false
+			}
+		},
 		{
 			"path": "pages/index/guide",
 			"navigationStyle":"custom"

+ 1 - 2
pages/index/index.css

@@ -69,5 +69,4 @@ page{background-color: #f5f5f5;}
 .rank-list-user .photo{width: 88rpx;height: 88rpx;border-radius: 50%;margin-right: 24rpx;}
 .rank-list-user .name{font-size: 28rpx;color: #333;flex: 1;}
 .rank-list-carbon{width: 170rpx;margin-left: 0;font-size: 26rpx;color: #26D18B;line-height: 37rpx;}
-
-
+.rank-wrap >>> .nodata {width: auto;padding: 100rpx 0;background-color: #fff;border-radius: 16rpx;}

+ 39 - 35
pages/index/index.vue

@@ -84,46 +84,49 @@
 			<view class="title">购买排行榜</view>
 			<view class="rank-wrap">
 				<view class="rank-tab">
-					<view class="rank-tab-item" :class="{active: rankType == 1 }" @click="rankTab(1)">
+					<view class="rank-tab-item" :class="{active: rankType == 2 }" @click="rankTab(2)">
 						企业排行榜
 					</view>
-					<view class="rank-tab-item" :class="{active: rankType == 2 }" @click="rankTab(2)">
+					<view class="rank-tab-item" :class="{active: rankType == 1 }" @click="rankTab(1)">
 						个人排行榜
 					</view>
 				</view>
-				<view class="rank-top">
+				<custom-nodata v-if="rankResult.list == ''"></custom-nodata>
+				<view class="rank-top" v-if="rankTop.length > 0">
 					<view class="rank-top-item" v-for="(item, index) in rankTop" :key="index">
 						<view class="rank-top-imgwrap">
-							<image :src="$getimg+'rank-top01.png'" class="rank-top-bg" mode="aspectFit"></image>
-							<image :src="item.img" class="rank-top-photo" mode="scaleToFill"></image>
+							<image :src="$getimg+'rank-top-1.png'" v-if="item.rank == '1'" class="rank-top-bg" mode="aspectFit"></image>
+							<image :src="$getimg+'rank-top-2.png'" v-if="item.rank == '2'" class="rank-top-bg" mode="aspectFit"></image>
+							<image :src="$getimg+'rank-top-3.png'" v-if="item.rank == '3'" class="rank-top-bg" mode="aspectFit"></image>							
+							<image :src="item.headImage" class="rank-top-photo" mode="scaleToFill"></image>
 						</view>
-						<view class="rank-top-name f-ellipsis">{{item.name}}</view>
-						<view class="rank-top-carbon f-ellipsis">共购买{{item.carbon}}kg碳汇</view>
+						<view class="rank-top-name f-ellipsis">{{item.customerName}}</view>
+						<view class="rank-top-carbon f-ellipsis">共购买{{item.carbonVal}}kg碳汇</view>
 					</view>
-					<view class="my-rank-wrap">
+					<view class="my-rank-wrap" v-if="myRank.rank">
 						<view class="my-rank-photo">
-							<image :src="myRank.img" class="photo" mode="scaleToFill"></image>
+							<image :src="myRank.headImage" class="photo" mode="scaleToFill"></image>
 						</view>
 						<view class="my-rank-text">
 							<view class="my-rank">第{{myRank.rank}}名</view>
-							<view class="my-rank-num">共购买{{myRank.carbon}}kg碳汇</view>
+							<view class="my-rank-num">共购买{{myRank.carbonVal}}kg碳汇</view>
 						</view>
 					</view>
 				</view>
 				<!-- rank-top end -->
-				<view class="rank-list-header">
+				<view class="rank-list-header" v-if="rankList">
 					<view class="rank-list-header-rank">排名</view>
 					<view class="rank-list-header-user">用户</view>
 					<view class="rank-list-header-carbon">购买碳汇</view>
 				</view>
-				<view class="rank-list">
+				<view class="rank-list" v-if="rankList">
 					<view class="rank-list-item" v-for="(item, index) in rankList" :key="index">
 						<view class="rank-list-rank">{{item.rank}}</view>
 						<view class="rank-list-user">
 							<image :src="item.img" class="photo" mode="scaleToFill"></image>
-							<view class="name f-ellipsis">{{item.name}}</view>
+							<view class="name f-ellipsis">{{item.customerName}}</view>
 						</view>
-						<view class="rank-list-carbon">共购买{{item.carbon}}kg<br />碳汇</view>
+						<view class="rank-list-carbon">共购买{{item.carbonVal}}kg<br />碳汇</view>
 					</view>
 				</view>
 			</view>
@@ -138,10 +141,12 @@
 <script>
 	import quickBuy from './modal/quickBuy';
 	import uniPopup from '@/components/uni-popup/uni-popup.vue';
+	import customNodata from '@/components/custom-nodata/custom-nodata.vue';
 	export default {
 		components:{
 			uniPopup,
 			quickBuy,
+			customNodata
 			
 		},
 		data() {
@@ -167,24 +172,17 @@
 				swiperCurrent: 0,
 				productList:[],
 				rankType:1,
-				rankTop:[
-					{name:'酉阳土家族苗',carbon:1000,img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-					{name:'酉阳土家族苗',carbon:1000,img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-					{name:'酉阳土家族苗',carbon:1000,img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},					
-				],
-				myRank:{name:'家族苗',carbon:1000,rank:11,img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-				rankList:[
-					{name:'家族苗',carbon:1000,rank:'04',img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-					{name:'家族苗',carbon:1000,rank:'05',img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-					{name:'家族苗',carbon:1000,rank:'06',img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-					{name:'家族苗',carbon:1000,rank:'07',img:'http://qny.gzsdtfp.com/gzth005/imgupload/39b6b37e61e240c98e4c8ca392c5f3a5.jpg'},
-				],
+				rankTop:[],
+				myRank:{},
+				rankList:[],
+				rankResult:{}
 				
 			}
 		},
 		onLoad() {
 			this.thetoken = 'Bearer' + ' ' + this.$store.state.token;
 			this.getProductList();
+			this.getRank();
 		},
 		methods: {
 			swiperChange (e) {
@@ -197,7 +195,7 @@
 				this.$api.http.post(this.config.apiBaseurl + '/carbon-h5/wap/goodsManage/pushGoods',{"pageNo":1,"pageSize":6},{
 					header: {
 					Accept:'application/json',
-					Authorization: 'Bearer '+ this.thetoken, //注意Bearer后面有一空格
+					Authorization: this.thetoken, //注意Bearer后面有一空格
 				},
 				}).then(res => {
 					this.productList = res.data.retBody;
@@ -217,14 +215,20 @@
 				this.rankType = type;
 				this.getRank(type);
 			},
-			getRank(type){
-				this.$api.http.post(this.config.apiBaseurl + '/carbon-h5/wap/goodsManage/pushGoods',{"pageNo":1,"pageSize":6},{
-					header: {
-					Accept:'application/json',
-					Authorization: 'Bearer '+ this.thetoken, //注意Bearer后面有一空格
-				},
-				}).then(res => {
-					// this.productList = res.data.retBody;
+			getRank(){
+				let params = {"type":this.rankType};
+				this.$api.http.get(this.config.apiBaseurl+'/carbon-h5/wap/carbonVal/getCustomerCarbonValRank',{params:params,header: {Authorization:this.thetoken}}).then(res => {
+					if(!res.data.retBody){
+						this.rankResult.currCustomerRankForm='';
+						this.rankResult.list='';
+					}else{
+						this.rankResult = res.data.retBody
+					};
+					console.log('this.rankResult',this.rankResult);
+					this.myRank = this.rankResult.currCustomerRankForm;					
+					this.rankTop = this.rankResult.list.slice(0,3);
+					console.log('this.rankTop',JSON.parse(JSON.stringify(this.rankTop)))
+					this.rankList =this.rankResult.list.slice(3,this.rankResult.list.length);
 					console.log('res',JSON.parse(JSON.stringify(res.data.retBody)))
 				}).catch(err =>{
 					console.log('err',err)

+ 5 - 5
pages/index/modal/quickBuy.vue

@@ -4,7 +4,7 @@
 			<view class="popup-head">				
 				<text v-if="customerType==1">购买碳汇</text>
 				<text v-else>线下认购</text>
-				<text class="close iconfont icon-shense" @click="closePop"></text>
+				<text class="close" @click="closePop">X</text>
 			</view>
 			<view class="popup-body">
 				<view class="conditions-item input-number">
@@ -163,10 +163,10 @@
 			//碳汇购入量计算
 			shoppingNum(n, o) {
 				if (n > 1000) {
-					this.$api.msg("单次购买不得超过1000KG!")
-					setTimeout(res => {
-						this.shoppingNum = 1000
-					}, 200)
+					// this.$api.msg("单次购买不得超过1000KG!")
+					// setTimeout(res => {
+					// 	this.shoppingNum = 1000
+					// }, 200)
 				}
 				this.getHelpPeople(n)
 				this.totalMoney = this.price * n;

+ 0 - 43
pages/login/login.vue

@@ -1,43 +0,0 @@
-<template>
-	<view class="pages">
-		
-		<view class="login">
-			<image class="loginbg" src="/static/img/loginbg.png" mode="widthFix"></image>
-			<button type="default" class="big-btn" @click="wxclick">微信登录</button>
-		</view>
-		
-	</view>
-</template>
-
-<script>
-	import { mapState, mapMutations } from 'vuex';
-	export default{
-		components:{
-			
-		},
-		props:{
-			
-		},
-		data(){
-			return{
-				
-			}
-		},
-		onLoad(options){
-			this.backpage = options.backpage
-			
-		},
-		methods:{
-			wxclick(){
-				window.location.replace(this.config.loginUrl);
-			}
-			
-		}
-	}
-</script>
-
-<style scoped>
-page{background: #fff;}
-.loginbg{width: 100%;height: auto;margin: 80rpx 0 40rpx;}
-.big-btn{margin: 0 95rpx;background-color: #65B74E;border-radius: 100rpx;color: #fff;font-size: 32rpx;font-weight: 400;line-height: 45rpx;letter-spacing: 5rpx;}
-</style>

+ 12 - 9
pages/login/loginType.vue

@@ -81,15 +81,18 @@
 							};
 							serf.login(res.data.retBody);
 							serf.upInfo();
-							let userKey = uni.getStorageSync('userInfo');
-							console.log('userKey',userKey.phone);
-							if(userKey.phone){
-								serf.havePhone = true;
-							}else{
-								// console.log('hasLogin',serf.hasLogin);
-								// console.log('havePhone==false',serf.havePhone==false);
-								return;
-							}
+							uni.getStorage({
+							    key: 'userInfo',
+							    success: function (res) {
+							        // console.log('userInfo',res.data);
+									if(res.data.phone){
+										serf.havePhone = true;
+									}else{
+										return;
+									}
+							    }
+							});
+							
 							if(serf.backUrl == '' || !serf.backUrl){
 								uni.switchTab({
 									url: '/pages/usercenter/usercenter'

+ 1 - 1
pages/use/use.css

@@ -1,5 +1,5 @@
 page{background-color: #f5f5f5;}
-.top-img{height: 344rpx;}
+.top-img{height: 344rpx;z-index: -1;}
 .use-wrap{margin: -153rpx 40rpx 40rpx;padding: 60rpx 24rpx 24rpx;background-color: #fff;box-shadow: 0px 0px 12rpx 0px rgba(0, 0, 0, 0.04);border-radius: 16rpx;}
 .use-wrap-header{display: flex;justify-content: space-between;align-items: center;margin-bottom: 60rpx;}
 .use-wrap-header .til{font-size: 32rpx;color: #333;font-weight: 500;}

+ 5 - 2
pages/use/use.vue

@@ -1,12 +1,12 @@
 <template>
 	<view class="pages">
 		<view class="top-img">
-			<image :src="$getimg + 'banner01.png'" class="img" mode="widthFix"></image>
+			<image :src="$getimg + 'use-bg.png'" class="img" mode="widthFix"></image>
 		</view>
 		<view class="use-wrap">
 			<view class="use-wrap-header">
 				<view class="til">价值实现</view>
-				<view class="subtil"  @click="this.$api.msg('稍后展示')">
+				<view class="subtil" @click="useClick">
 					<text>关于价值实现</text>
 					<text class="iconfont icon-jiantou"></text>
 				</view>
@@ -53,6 +53,9 @@
 			},
 			huodong(){
 				this.$api.msg('暂未开放')
+			},
+			useClick(){
+				this.$api.msg('稍后展示')
 			}
 
 		}

+ 136 - 0
pages/usercenter/certificateList/certificate/certificate-bak.vue

@@ -0,0 +1,136 @@
+<template>
+	<view class="content">
+		<web-view v-if="info.url" class="web-view" :src="info.url"></web-view>
+		<view class="btns">
+			<!-- <button class="my-btn" @click="$api.goto('/pages/home/home', '', true)">首页</button> -->
+			<!-- <button class="my-btn" type="gradient" @tap="$api.goto('/pages/usercenter/certificateList/certificateList')">我的证书</button> -->
+			<!--#ifdef H5-->
+			<!-- <button class="my-btn" type="gradient" @tap="share" v-show="$api.clientType.isWeiXin">分享证书</button> -->
+			<!--#endif-->
+		</view>
+		<!--#ifdef H5-->
+		<!-- <view v-show="showShare" class="share-bg" @tap="showShareFun"></view> -->
+		<!--#endif-->
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			thetoken:'',
+			orderid:'',
+			info: {
+				url: ''
+			},
+			//#ifdef H5
+			showShare:false,
+			//#endif
+		};
+	},
+	onLoad(e) {
+		console.log('e',e);
+		this.thetoken = 'Bearer' + ' ' + this.$store.state.token;
+		this.orderid = e.orderid;
+		// const data = this.$api.getE();
+		// this.info = Object.assign(this.info, data);
+		//自定义证书ID字段  orderId
+		//通过订单id获取证书信息
+		uni.showLoading({
+			title: '正在获取证书信息'
+		});
+		this.$api.http.get(this.config.apiBaseurl + '/carbon-h5/wap/order/getCredentialByOrderId?orderId='+this.orderid,{
+			header: {
+			Accept:'application/json',
+			Authorization: this.thetoken, 
+		},
+		}).then(res => {
+			uni.hideLoading();
+			// this.info = Object.assign(this.info, data);
+			this.info.url = '/static/html2canvas/index.html?key=' + this.orderid;
+			console.log('res',JSON.parse(JSON.stringify(res.data.retBody)));
+		}).catch(err =>{
+			console.log('err',err)
+		});
+		// this.$api
+		// 	.$http({
+		// 		url: '/wap/order/getCredentialByOrderId',
+		// 		data: {
+		// 			orderId: data.orderId
+		// 		}
+		// 	})
+		// 	.then(res => {
+		// 		const info = res.data instanceof Object ? res.data : {};
+		// 		this.info = Object.assign(this.info, res.data);
+		// 		if (res.code == 0) {
+		// 			//更新缓存信息
+		// 			uni.setStorageSync(data.orderId, info);
+		// 			//调用生成
+		// 			this.info.url = '/static/html2canvas/index.html?key=' + data.orderId;
+		// 		} else {
+		// 			uni.hideLoading();
+		// 		}
+		// 	});
+	},
+	//标题栏按钮监听
+	onNavigationBarButtonTap(e) {
+		this.$api.gohome(e);
+	},
+	methods: {
+		//#ifdef H5
+		showShareFun(){
+			this.showShare = !this.showShare;
+		},
+		share() {
+			//显示菜单
+			this.$wxApi.showMenu();
+			this.showShareFun();
+			//注册分享数据
+			this.$wxApi.share({
+				orderId: this.info.orderId
+			});
+		}
+		//#endif
+	}
+};
+</script>
+
+<style lang="scss">
+.content {
+	.btns {
+		position: absolute;
+		top: 88%;
+		width: 100%;
+		display: flex;
+		z-index: 1;
+		button {
+			flex: 1;
+			margin: 0 10% 10% 10%;
+		}
+	}
+}
+.web-view {
+	box-sizing: border-box;
+}
+.share-bg{
+	position: fixed;
+	z-index: 998;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	overflow: hidden;
+	background: rgba(0,0,0,.7);
+	box-sizing: border-box;
+	&::after{
+		content: "";
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background: url(http://fqn.hongweisoft.com/cqcarbon/wxapp/guide01.png) no-repeat top right;
+		background-size: 80% auto;
+	}
+}
+</style>

+ 108 - 102
pages/usercenter/certificateList/certificate/certificate.vue

@@ -1,118 +1,124 @@
 <template>
-	<view class="content">
-		<web-view v-if="info.url" class="web-view" :src="info.url"></web-view>
-		<view class="btns">
-			<!-- <button class="my-btn" @click="$api.goto('/pages/home/home', '', true)">首页</button> -->
-			<!-- <button class="my-btn" type="gradient" @tap="$api.goto('/pages/usercenter/certificateList/certificateList')">我的证书</button> -->
-			<!--#ifdef H5-->
-			<!-- <button class="my-btn" type="gradient" @tap="share" v-show="$api.clientType.isWeiXin">分享证书</button> -->
-			<!--#endif-->
+	<view class="pages">
+		<view class="container" id="wrapper">
+		  <text class="title draw" data-text="Hello there">Hello there</text>
+		  <text class="info draw" data-text="小程序是一种新的开放能力,开发者可以快速地开发一个小程序。">
+		   小程序是一种新的开放能力,开发者可以快速地开发一个小程序。
+		  </text>
+		  <view class="image-wrapper draw">
+		    <image class="draw" :src="$getimg + 'guide02.png'"/>
+			<image class="draw" src="../../../../static/img/icon_use_active.png"/>
+		  </view>
+		  
+		  <button class="generate-btn" @click="drawCanvas">generate</button>
 		</view>
-		<!--#ifdef H5-->
-		<!-- <view v-show="showShare" class="share-bg" @tap="showShareFun"></view> -->
-		<!--#endif-->
+		<canvas canvas-id="canvas" class="share-canvas"></canvas>
 	</view>
 </template>
 
 <script>
-export default {
-	data() {
-		return {
-			info: {
-				url: ''
-			},
-			//#ifdef H5
-			showShare:false,
-			//#endif
-		};
-	},
-	onLoad(e) {
-		const data = this.$api.getE();
-		this.info = Object.assign(this.info, data);
-		//自定义证书ID字段  orderId
-		//通过订单id获取证书信息
-		uni.showLoading({
-			title: '正在获取证书信息'
-		});
-		this.$api
-			.$http({
-				url: '/wap/order/getCredentialByOrderId',
-				data: {
-					orderId: data.orderId
-				}
-			})
-			.then(res => {
-				const info = res.data instanceof Object ? res.data : {};
-				this.info = Object.assign(this.info, res.data);
-				if (res.code == 0) {
-					//更新缓存信息
-					uni.setStorageSync(data.orderId, info);
-					//调用生成
-					this.info.url = '/static/html2canvas/index.html?key=' + data.orderId;
-				} else {
-					uni.hideLoading();
+	const wxml2canvas = require('@/utils/wxml2canvas.js');
+	export default {
+		data() {
+			return {
+				$getimg:this.$getimg,
+				thetoken:'',
+				orderid:'',
+				
+				params:{
 				}
-			});
-	},
-	//标题栏按钮监听
-	onNavigationBarButtonTap(e) {
-		this.$api.gohome(e);
-	},
-	methods: {
-		//#ifdef H5
-		showShareFun(){
-			this.showShare = !this.showShare;
+				
+			}
 		},
-		share() {
-			//显示菜单
-			this.$wxApi.showMenu();
-			this.showShareFun();
-			//注册分享数据
-			this.$wxApi.share({
-				orderId: this.info.orderId
+		onShow() {
+		
+		},
+		onLoad(e) {
+			this.thetoken = 'Bearer' + ' ' + this.$store.state.token;
+			this.orderid = e.orderid;
+			uni.showLoading({
+				title: '正在获取证书信息'
+			});
+			this.$api.http.get(this.config.apiBaseurl + '/carbon-h5/wap/order/getCredentialByOrderId?orderId='+this.orderid,{
+				header: {
+				Accept:'application/json',
+				Authorization: this.thetoken, 
+			},
+			}).then(res => {
+				uni.hideLoading();
+				// this.info = Object.assign(this.info, data);
+				// this.info.url = '/static/html2canvas/index.html?key=' + this.orderid;
+				console.log('res',JSON.parse(JSON.stringify(res.data.retBody)));
+			}).catch(err =>{
+				console.log('err',err)
 			});
+
+		},
+		methods: {
+			drawCanvas: function() {
+				const wrapperId = '#wrapper'
+				const drawClassName = '.draw'
+				const canvasId = 'canvas'
+				
+				wxml2canvas(wrapperId, drawClassName, canvasId).then(() => {
+					uni.showLoading({
+						title: '生成中'
+					});
+					uni.canvasToTempFilePath({
+					  x: 0,
+					  y: 0,
+					  // width: 500,
+					  // height: 500,
+					  // destWidth: 100,
+					  // destHeight: 100,
+					  canvasId: 'canvas',
+					  success: function(res) {
+						uni.hideLoading();
+						uni.showLoading({
+							title: '保存中'
+						});
+					    console.log(res.tempFilePath);
+						uni.saveImageToPhotosAlbum({
+							filePath:res.tempFilePath,
+							success:function(res){
+								uni.hideLoading();
+							}							
+						})
+					  } 
+					})
+				  // canvas has been drawn
+				  // can save the image with wx.canvasToTempFilePath and wx.saveImageToPhotosAlbum 
+				})
+		  }
+
 		}
-		//#endif
 	}
-};
 </script>
 
-<style lang="scss">
-.content {
-	.btns {
-		position: absolute;
-		top: 88%;
-		width: 100%;
-		display: flex;
-		z-index: 1;
-		button {
-			flex: 1;
-			margin: 0 10% 10% 10%;
-		}
+<style>
+	/* @import url("./index.css"); */
+	.container {
+	  height: 100%;
+	  box-sizing: border-box;
+	  padding: 10px 20px;
+	  display: flex;
+	  flex-direction: column;
+	 
+	} 
+	.container .title {
+	  font-size:36px;
+	  text-align: left;
+	  margin-bottom: 10px;
+	
+	}
+	.container .info {
+	  font-size: 14px;
+	  line-height: 18px;
+	  color: grey;
+	  text-align: left;
+	  margin-bottom: 40px;
 	}
-}
-.web-view {
-	box-sizing: border-box;
-}
-.share-bg{
-	position: fixed;
-	z-index: 998;
-	top: 0;
-	bottom: 0;
-	left: 0;
-	right: 0;
-	overflow: hidden;
-	background: rgba(0,0,0,.7);
-	box-sizing: border-box;
-	&::after{
-		content: "";
-		position: absolute;
-		top: 0;
-		bottom: 0;
-		left: 0;
-		right: 0;
-		// background: url(../../../../static/img/share-bg.png) no-repeat top right;
-		background-size: 80% auto;
+	.container .image-wrapper image {
+	  width: 100%;
 	}
-}
 </style>

+ 2 - 2
pages/usercenter/certificateList/certificateList.vue

@@ -2,7 +2,7 @@
 	<view class="pages">
 		<mescroll-body class="certificateList-wrap" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
 			<view class="certificate">
-				<view v-for="(item,index) in certificateList" :key="index" class="certificate-item" @click="goDetails(item.id)">
+				<view v-for="(item,index) in certificateList" :key="index" class="certificate-item" @click="goCertDetails(item.fkOrderId)">
 					<image :src="$getInnerImg + 'certificate.png'" class="certificate-item-img" mode="scaleToFill"></image>
 					<view class="certificate-item-text">
 						<view class="num">证书编号:{{item.credentialNo}}</view>
@@ -120,7 +120,7 @@
 				});
 				
 			},
-			goDetails(id){
+			goCertDetails(id){
 				console.log(id)
 				uni.navigateTo({
 					url: '/pages/usercenter/certificateList/certificate/certificate?orderid=' + id,

+ 5 - 4
pages/usercenter/orderList/orderList.vue

@@ -25,7 +25,7 @@
 					</view>
 					<!-- order-info end -->
 					<view class="order-product">
-						<image :src="item.goodsOrderDetailForm[0].goodsImages" class="order-product-img" mode="scaleToFill"></image>
+						<image :src="$onlineImg+ item.goodsOrderDetailForm[0].goodsImages | firstImg" class="order-product-img" mode="scaleToFill"></image>
 						<view class="order-product-text">
 							<view class="order-product-til">
 								{{item.goodsOrderDetailForm.length}}个碳汇产品,共计{{item.orderCarbonAmount}}kg碳汇量
@@ -36,8 +36,8 @@
 							</view>
 							<view class="order-product-carbon">共{{item.orderCarbonAmount}}kg碳汇量</view>
 							<view class="order-btn topay" v-if="item.orderStatus == 1&&item.state==1" @click.stop="pay(item)">立即支付</view>
-							<view class="order-btn" v-if="item.orderStatus == 2" @click.stop="$api.href('/pages/usercenter/certificateList/certificate?id='+item.id)">查看证书</view>	
-							<view class="order-btn" v-if="item.orderStatus == 5" @click.stop="$api.href('/pages/usercenter/certificateList/certificate?id='+item.id)">查看证书</view>							
+							<view class="order-btn" v-if="item.orderStatus == 2" @click.stop="$api.href('/pages/usercenter/certificateList/certificate?orderid='+item.guid)">查看证书</view>	
+							<view class="order-btn" v-if="item.orderStatus == 5" @click.stop="$api.href('/pages/usercenter/certificateList/certificate?orderid='+item.guid)">查看证书</view>							
 						</view>
 					</view>
 				</view>
@@ -295,7 +295,8 @@
 					console.log('pay err',err)
 				})
 
-			},
+			}
+			
 
 		}
 	}

+ 1 - 1
pages/usercenter/usercenter.vue

@@ -16,7 +16,7 @@
 				<view class="tool-bar-item">
 					<view class="tool-bar-til">我的碳汇量(kg)</view>
 					<view class="tool-bar-num">
-						<text class="num">4090</text>
+						<text class="num">{{userInfo.carbonAmount || '0'}}</text>
 						<text class="iconfont icon-jiantou"></text>
 					</view>
 				</view>

BIN
static/html2canvas/bg.png


BIN
static/html2canvas/bg.webp


BIN
static/html2canvas/code.png


+ 0 - 368
static/html2canvas/credTpl.html

@@ -1,368 +0,0 @@
-<!DOCTYPE html>
-<html>
-
-	<head>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<!-- 强制让文档与设备的宽度保持1:1 -->
-		<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-		<script type="text/javascript" src="http://cdn.webfont.youziku.com/wwwroot/js/wf/youziku.api.min.js"></script>
-		<script type="text/javascript">
-			$youziku.load(".title span", "94d4ba0acbef4c97b7abfecaa9a3e1a8", "cyjianxk");
-			$youziku.draw();
-		</script>
-		<style type="text/css">
-			* {
-				margin: 0;
-				padding: 0;
-				border: 0;
-			}
-
-			.ui-absolute {
-				position: absolute;
-				top: 0;
-				bottom: 0;
-				left: 0;
-				right: 0;
-				margin: auto;
-			}
-
-			.ui-relative {
-				position: relative;
-			}
-
-			.cred {
-				background: url(bg.png) no-repeat center center;
-				background-size: 100% 100%;
-				width: calc(908px/1.5);
-				height: calc(1304px/1.5);
-				font-size: calc(908px/1.5*0.11);
-				margin: 0 auto;
-			}
-
-			.cred .logo,
-			.cred .QR-code {
-				bottom: auto;
-				padding-top: 20%;
-				width: 20%;
-				border-radius: 50%;
-				overflow: hidden;
-				left: 50%;
-				right: auto;
-				transform: translateX(-50%);
-			}
-
-			.cred .logo {
-				top: 6%;
-				background: url(logo.png) no-repeat center center;
-				background-size: 100% 100%;
-			}
-
-			.cred .QR-code {
-				top: 68%;
-				background: url(code.png) no-repeat center center;
-				background-size: 100% 100%;
-				border-radius: 0;
-			}
-
-			.cred .title {
-				font-size: .40em;
-				top: 19%;
-				bottom: auto;
-				text-align: center;
-				line-height: 1.5em;
-				color: #00984C;
-			}
-
-			.cred .number {
-				top: 29%;
-				bottom: auto;
-				font-size: .28em;
-				text-align: center;
-				line-height: 1em;
-				color: #000;
-			}
-
-			.cred .content {
-				top: 33%;
-				bottom: auto;
-				font-size: .32em;
-				color: #333333;
-				margin: auto 12% auto 13%;
-				font-weight: 300;
-			}
-
-			.cred .content p {
-				text-indent: 2em;
-				line-height: 2em;
-				letter-spacing: .05em;
-				word-wrap: break-word;
-				word-break: break-all;
-			}
-
-			.cred .content .name {
-				text-indent: 0;
-			}
-
-			.cred .content p span {
-				border-bottom: 2px solid #010101;
-				overflow: hidden;
-			}
-
-			.cred .seal-1,
-			.cred .seal-2 {
-				top: 72%;
-				bottom: auto;
-				width: 26.22%;
-				padding-top: 26.22%;
-				border-radius: 50%;
-			}
-
-			.cred .seal-1 {
-				background: url(z1.png) no-repeat center center;
-				background-size: 100% 100%;
-				left: 20%;
-				right: auto;
-			}
-
-			.cred .seal-2 {
-				background: url(z2.png) no-repeat center center;
-				background-size: 100% 100%;
-				right: 20%;
-				left: auto;
-			}
-
-			.cred .seal-1-text {
-				top: 84%;
-				padding-top: 0;
-				background: none;
-				font-size: .25em;
-				bottom: auto;
-				line-height: 1em;
-				color: #000;
-				display: flex;
-				text-align: center;
-				width: 60%;
-				left: 10%;
-				right: 10%;
-			}
-
-			.cred .seal-1-text span {
-				flex: 1;
-			}
-
-			.cred .seal-1-text.time {
-				top: 90%;
-				right: 0;
-				left: 0;
-				margin: auto;
-				text-align: center;
-			}
-
-			.cred .foot-text {
-				top: auto;
-				bottom: 6.82%;
-				font-size: .23em;
-				line-height: 1.5em;
-				left: 13.43%;
-				right: 13.43%;
-				color: #595656;
-				text-indent: 2em;
-				letter-spacing: .1em;
-			}
-		</style>
-	</head>
-
-	<body>
-		<div class="ui-relative cred" id="cred">
-			<div class="ui-absolute logo"></div>
-			<div class="ui-absolute QR-code"></div>
-			<div class='ui-absolute title'>
-				<p><span>重庆</span>"<span>碳汇</span>+"<span>生态产品价值实现</span></p>
-				<p><span>碳信用证书</span></p>
-			</div>
-			<div class="ui-absolute number">
-				<!-- 证书编号:G18G0000001 -->
-			</div>
-			<div class="ui-absolute content">
-				<!-- <p class="name">
-				尊敬的
-				<span>雷</span><span>电</span>:</p>
-			<p>感谢您对贵州省单株碳汇精准扶贫的支持。您购买了
-				<span>2018</span>年度单株碳汇
-				<span>100</span>株,碳汇签发量
-				<span>1000</span>千克二氧化碳当量,帮助了来自
-				<span>贵</span>
-				<span>州</span>
-				<span>省</span>
-				<span>安</span>
-				<span>顺</span>
-				<span>市</span>
-				<span>平</span>
-				<span>坝</span>
-				<span>区</span>深度贫困村
-				<span>关口村</span>的
-				<span>刘兴莲</span>等
-				<span>15</span>户贫困户。您购碳资金
-				<span>30000</span>元,已全额转入
-				<span>刘兴莲</span>等
-				<span>15</span>户贫困户的个人银行账户。</p>
-			<p>※该笔碳汇可用于抵消您个人碳排放,为应对全球气候变化做出贡献。</p> -->
-			</div>
-			<div class="ui-absolute seal-1-text">
-				<span>重庆市生态环境局</span>
-				<span>中国质量认证中心</span>
-			</div>
-			<div class="ui-absolute seal-1-text time">
-				<!-- <span>2018年8月10日</span> -->
-			</div>
-			<!-- <div class="ui-absolute seal-1"></div> -->
-			<!-- <div class="ui-absolute seal-2"></div> -->
-			<!-- <div class="ui-absolute foot-text">※实名认购记录可作为个人(企业)优良信息,归集到全国信用信息共享平台(贵州)个人(企业)名下。</div> -->
-		</div>
-	</body>
-	<script src="html2canvas.js" type="text/javascript" charset="utf-8"></script>
-	<script type="text/javascript">
-		//下载图片
-		let downloadImg = function(obj) {
-			obj = obj || {};
-			this.imgData = obj.data.toDataURL((obj.format || 'image/jpg')) || null;
-			this.src = '';
-			this.init();
-		};
-		downloadImg.prototype.init = function() {
-			this.downloadImgFile(this.imgData);
-		};
-		//下载
-		downloadImg.prototype.downloadImgFile = function(content) {
-			var _this = this;
-			var blob = this.base64ToBlob(content);
-			this.src = URL.createObjectURL(blob);
-		};
-		downloadImg.prototype.base64ToBlob = function(code) {
-			let parts = code.split(';base64,');
-			let contentType = parts[0].split(':')[1];
-			let raw = window.atob(parts[1]);
-			let rawLength = raw.length;
-			let uInt8Array = new Uint8Array(rawLength);
-			for (let i = 0; i < rawLength; ++i) {
-				uInt8Array[i] = raw.charCodeAt(i);
-			}
-			return new Blob([uInt8Array], {
-				type: contentType
-			});
-		};
-
-		window.certificate = function(obj) {
-			var _this = this;
-			_this.obj = obj || {
-				elem: 'cred'
-			};
-			_this.contentData = obj.data || {};
-			_this.content();
-			_this.elem = _this.obj.elem || 'cred'; //要绘制的页面
-			_this.elemObj = document.getElementById(_this.elem);
-			_this.format = _this.obj.format || "jpg"; //下载格式
-			_this.success = obj.success || function(url, data) {
-				console.log("没有配置success接收函数");
-			};
-			_this.type = null;
-			_this.A0 = {
-				width: '1080px',
-				height: '1551px',
-				'font-size': '118.8px'
-			};
-			_this.A3 = {
-				width: '3058px',
-				'height': '4961px',
-				'font-size': '336.38px'
-			};
-			_this.A4 = {
-				'width': '2048px',
-				'height': '3508px',
-				'font-size': '225.28px'
-			};
-			// _this.down('A0');
-		};
-		certificate.prototype.content = function(obj) {
-			var _this = this;
-			this.contentData = obj || this.contentData;
-			let span = function(name, bool) {
-				let html = '';
-				let arr = (typeof(_this.contentData[name]) == 'undefined' ? [] : _this.contentData[name]) + '';
-				for (let i in arr) {
-					html += bool ? '<span>' + arr[i] + '</span>' : arr[i];
-				}
-				return html;
-			};
-			document.getElementsByClassName('number')[0].innerHTML = this.contentData.code == '0' ? '' : '普惠证书编号:' + this.contentData
-				.code;
-			document.getElementsByClassName('content')[0].innerHTML = '<p class="name">尊敬的' + span('name', true) +
-				':</p>\
-				<p>欢迎参与重庆“碳汇+”生态产品价值实现试点示范,您此单购买“碳汇+”生态产品' + span('co2') + 'kgCO2减排量,\
-				资金支出' + span('money') +
-				'元,生成碳信用额' + span('credit') + '个,可等量累计“碳汇+”积分' + span('integral') + '分。</p>\
-				<p>感谢您为生态文明建设做出的贡献!</p>';
-			document.getElementsByClassName('time')[0].innerHTML = "<span>" + this.contentData.date + "</span>";
-		};
-		certificate.prototype.generate = function() {
-			var _this = this;
-			_this.style(_this.elemObj, _this[_this.type]);
-			return _this;
-		};
-		certificate.prototype.style = function(elem, styleObj) {
-			for (let i in styleObj) {
-				elem.style[i] = styleObj[i];
-			}
-			return elem;
-		};
-		certificate.prototype.down = function(type) {
-			if (this.type == type) {
-				this.aLink.dispatchEvent(this.evt);
-				return -1;
-			} else {
-				this.type = type;
-				return this.generate().html2canvas();
-			}
-		};
-		certificate.prototype.html2canvas = function() {
-			var _this = this;
-			html2canvas(_this.elemObj).then(function(canvas) {
-				let img = new downloadImg({
-					data: canvas,
-					format: 'image/' + (_this.format || 'jpg'),
-				});
-				if (img.src) {
-					_this.src = img.src;
-					if (_this.success) {
-						_this.data = canvas.toDataURL('image/' + (_this.format || 'jpg'));
-						_this.aLink = document.createElement('a');
-						_this.evt = document.createEvent("MouseEvents");
-						_this.evt.initEvent("click", true, true);
-						_this.aLink.download = new Date().getTime() + '.' + (_this.format || 'jpg');
-						_this.aLink.href = _this.src;
-						_this.success(function(type) {
-							switch (type) {
-								case 'down':
-									_this.aLink.dispatchEvent(_this.evt);
-									return _this.src;
-									break;
-								case 'url':
-									return _this.src;
-									break;
-								case 'data':
-									return _this.data;
-									break;
-								default:
-									return _this.src;
-							}
-						}, _this.data);
-					}
-				}
-			});
-			return _this;
-		};
-	</script>
-
-</html>

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 3519
static/html2canvas/html2canvas.js


+ 0 - 128
static/html2canvas/index.html

@@ -1,128 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8" />
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<script type="text/javascript">
-			/**
-			 * URL参数转换为对象
-			 */
-			Location.prototype.searchObj = function(url) {
-				var obj = {};
-				var arr = (url || this.search).match(/[?&][^?&]+=[^?&]+/g);
-				if (arr) {
-					arr.forEach(function(item) {
-						var tempArr = item.substring(1).split('=');
-						obj[decodeURIComponent(tempArr[0])] = decodeURIComponent(tempArr[1]);
-						length++;
-					});
-				}
-				return obj;
-			}
-		</script>
-		<style type="text/css">
-			#credTpl {
-				overflow: hidden;
-				position: fixed;
-				padding: 0;
-				margin: 0;
-				border: 0;
-				height: 0;
-				width: 0;
-				top: 0;
-				left: 0;
-			}
-			.showImg{
-				position: fixed;
-				padding: 0;
-				margin: 0;
-				border: 0;
-				top: 1%;
-				left: 5%;
-				bottom: 18%;
-				right: 5%;
-			}
-			#showImg {
-				position: absolute;
-				padding: 0;
-				margin: 0;
-				border: 0;
-				top: 0;
-				left: 0;
-				bottom: 0;
-				right: 0;
-				width: 100%;
-				height: 100%;
-			}
-		</style>
-	</head>
-
-	<body>
-		<div class="showImg">
-			<img src="bg.png" id="showImg">
-		</div>
-		<iframe id="credTpl" name="credTpl" src="credTpl.html"></iframe>
-	</body>
-
-	<script type="text/javascript">
-		window.parent.uni && window.parent.uni.showLoading({
-			title: '证书生成中'
-		});
-		let imgSrcFun = function() {};
-		let showimg = function() {
-			window.parent.uni && window.parent.uni.previewImage({
-				current: 0,
-				urls: [imgSrcFun]
-			});
-		}
-		let iframeOnload = function() {
-			//框架加载成功
-			let getE = function(e) {
-				let data = {};
-				//获取参数
-				if (e.key) {
-					try {
-						const value = window.parent.uni.getStorageSync(e.key);
-						if (value) {
-							data = value;
-						}
-					} catch (e) {
-
-					}
-				}
-				return data;
-			}
-			//取得证书信息缓存
-			let obj = getE(location.searchObj());
-			let credTpl = window.frames['credTpl'].window; //获取证书框架window
-			let mycertificate = new credTpl.certificate({ //生成图片
-				format: 'jpg',
-				data: {
-					code: obj.credentialNo || '', //编号
-					name: obj.companyName || obj.customerName || obj.nickName || '匿名用户', //购买者名字
-					co2: obj.carbonAmount || 0, //碳汇量
-					credit: obj.carbonAmount || 0, //碳信用额
-					integral: obj.carbonAmount || 0, //碳积分
-					money: obj.orderAmount || 0, //购买多少钱
-					date: obj.buyDate || '' //购买日期
-				},
-				success: function(_function) {
-					imgSrcFun = _function('data');
-					document.getElementById('showImg').src = imgSrcFun; //预览图片
-					window.parent.uni && window.parent.uni.hideLoading();
-				}
-			});
-			mycertificate.down('A0');
-		};
-		/**
-		 * 证书框架加载完毕开始生成
-		 */
-		let iframe = document.getElementById("credTpl");
-		if (iframe.attachEvent) {
-			iframe.attachEvent("onload", iframeOnload);
-		} else {
-			iframe.onload = iframeOnload;
-		}
-	</script>
-
-</html>

BIN
static/html2canvas/logo.png


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/common/main.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/common/vendor.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/components/mescroll-uni/components/mescroll-empty.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/components/mescroll-uni/components/mescroll-top.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/components/mescroll-uni/mescroll-body.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/components/uni-popup/uni-popup-dialog.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/components/uni-popup/uni-popup.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/components/uni-transition/uni-transition.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/guide.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/index.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/init.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/login/companyLogin.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/login/loginType.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/use/use.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/certificateList/certificateList.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/orderList/orderList.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/orderList/orderdetails/orderdetails.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/subscribe/subscribe.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/.sourcemap/mp-weixin/pages/usercenter/usercenter.js.map


+ 1 - 0
unpackage/dist/dev/mp-weixin/app.json

@@ -1,5 +1,6 @@
 {
   "pages": [
+    "pages/index/init",
     "pages/index/guide",
     "pages/login/loginType",
     "pages/login/companyLogin",

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 30 - 28
unpackage/dist/dev/mp-weixin/common/main.js


+ 575 - 20
unpackage/dist/dev/mp-weixin/common/vendor.js

@@ -2051,7 +2051,562 @@ Object.defineProperty(exports, "__esModule", { value: true });exports.config = v
   // 云图片(产品)
   onlineImg: "http://cqth.hw.hongweisoft.com/ht/",
   // 七牛云
-  qny: "http://fqn.hongweisoft.com/cqcarbon/wxapp/" };exports.config = config;
+  qnyImg: "http://fqn.hongweisoft.com/cqcarbon/wxapp/" };exports.config = config;
+
+/***/ }),
+
+/***/ 115:
+/*!*****************************************************!*\
+  !*** D:/wwwroot/cqcarbonwxapp/utils/wxml2canvas.js ***!
+  \*****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+/* eslint-disable */
+var PROPERTIES = ['hover-class', 'hover-start-time', 'space', 'src'];
+var COMPUTED_STYLE = [
+'color',
+'font-size',
+'font-weight',
+'font-family',
+'backgroundColor',
+'border',
+'border-radius',
+'box-sizing',
+'line-height'];
+
+var DEFAULT_BORDER = '0px none rgb(0, 0, 0)';
+var DEFAULT_BORDER_RADIUS = '0px';
+
+// default z-index??
+var DEFAULT_RANK = {
+  view: 0,
+  image: 1,
+  text: 2 };
+
+
+var drawWrapper = function drawWrapper(context, data) {var
+  backgroundColor = data.backgroundColor,width = data.width,height = data.height;
+  context.setFillStyle(backgroundColor);
+  context.fillRect(0, 0, width, height);
+};
+
+// todo: do more for different language
+var strLen = function strLen(str) {
+  var count = 0;
+  for (var i = 0, len = str.length; i < len; i++) {
+    count += str.charCodeAt(i) < 256 ? 1 : 2;
+  }
+  return count / 2;
+};
+
+var isMuitlpleLine = function isMuitlpleLine(data, text) {var
+  letterWidth = data['font-size'],width = data.width;
+  var length = strLen(text);
+  var rowlineLength = length * parseInt(letterWidth, 10);
+  return rowlineLength > width;
+};
+
+var drawMutipleLine = function drawMutipleLine(context, data, text) {var
+
+  letterWidth =
+
+
+
+
+  data['font-size'],width = data.width,left = data.left,top = data.top,lineHeightAttr = data['line-height'];
+  var lineHieght = lineHeightAttr === 'normal' ? Math.round(1.2 * letterWidth) : lineHeightAttr;
+  var rowLetterCount = Math.floor(width / parseInt(letterWidth, 10));
+  var length = strLen(text);
+  for (var i = 0; i < length; i += rowLetterCount) {
+    var lineText = text.substring(i, i + rowLetterCount);
+    var rowNumber = Math.floor(i / rowLetterCount);
+    var rowTop = top + rowNumber * parseInt(lineHieght, 10);
+    context.fillText(lineText, left, rowTop);
+  }
+};
+
+// enable color, font, for now only support chinese
+var drawText = function drawText(context, data) {var
+
+  text =
+
+
+
+
+
+
+  data.dataset.text,left = data.left,top = data.top,color = data.color,fontWeight = data['font-weight'],fontSize = data['font-size'],fontFamily = data['font-family'];
+  var canvasText = Array.isArray(text) ? text[0] : text;
+  context.font = "".concat(fontWeight, " ").concat(Math.round(
+  parseFloat(fontSize)), "px ").concat(
+  fontFamily);
+  context.setFillStyle(color);
+  if (isMuitlpleLine(data, canvasText)) {
+    drawMutipleLine(context, data, canvasText);
+  } else {
+    context.fillText(canvasText, left, top);
+  }
+  context.restore();
+};
+
+var getImgInfo = function getImgInfo(src) {return (
+    new Promise(function (resolve, reject) {
+      wx.getImageInfo({
+        src: src,
+        success: function success(res) {
+          resolve(res);
+        } });
+
+    }));};
+
+var hasBorder = function hasBorder(border) {return border !== DEFAULT_BORDER;};
+var hasBorderRadius = function hasBorderRadius(borderRadius) {return borderRadius !== DEFAULT_BORDER_RADIUS;};
+
+var getBorderAttributes = function getBorderAttributes(border) {
+  var borderColor, borderStyle;
+  var borderWidth = 0;
+
+  if (hasBorder) {
+    borderWidth = parseInt(border.split(/\s/)[0], 10);
+    borderStyle = border.split(/\s/)[1];
+    borderColor = border.match(/(rgb).*/gi)[0];
+  }
+  return {
+    borderWidth: borderWidth,
+    borderStyle: borderStyle,
+    borderColor: borderColor };
+
+};
+
+var getImgRect = function getImgRect(imgData, borderWidth) {var
+  width = imgData.width,height = imgData.height,left = imgData.left,top = imgData.top;
+  var imgWidth = width - 2 * borderWidth;
+  var imgHeight = height - 2 * borderWidth;
+  var imgLeft = left + borderWidth;
+  var imgTop = top + borderWidth;
+  return {
+    imgWidth: imgWidth,
+    imgHeight: imgHeight,
+    imgLeft: imgLeft,
+    imgTop: imgTop };
+
+};
+
+var getArcCenterPosition = function getArcCenterPosition(imgData) {var
+  width = imgData.width,height = imgData.height,left = imgData.left,top = imgData.top;
+  var coordX = width / 2 + left;
+  var coordY = height / 2 + top;
+  return {
+    coordX: coordX,
+    coordY: coordY };
+
+};
+
+var getArcRadius = function getArcRadius(imgData) {var borderWidth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;var
+  width = imgData.width;
+  return width / 2 - borderWidth / 2;
+};
+
+var getCalculatedImagePosition = function getCalculatedImagePosition(imgData, naturalWidth, naturalHeight) {var
+  border = imgData.border;var _getBorderAttributes =
+  getBorderAttributes(border),borderWidth = _getBorderAttributes.borderWidth;var _getImgRect =
+  getImgRect(
+  imgData,
+  borderWidth),imgWidth = _getImgRect.imgWidth,imgHeight = _getImgRect.imgHeight,imgLeft = _getImgRect.imgLeft,imgTop = _getImgRect.imgTop;
+
+  var ratio = naturalWidth / naturalHeight;
+  // tweak for real width and position => center center
+  var realWidth = ratio > 0 ? imgWidth : imgHeight * ratio;
+  var realHeight = ratio > 0 ? imgWidth * (1 / ratio) : imgHeight;
+  var offsetLeft = ratio > 0 ? 0 : (imgWidth - realWidth) / 2;
+  var offsetTop = ratio > 0 ? (imgHeight - realHeight) / 2 : 0;
+  return {
+    realWidth: realWidth,
+    realHeight: realHeight,
+    left: imgLeft + offsetLeft,
+    top: imgTop + offsetTop };
+
+};
+
+var drawArcImage = function drawArcImage(context, imgData) {var
+  src = imgData.src;var _getArcCenterPosition =
+  getArcCenterPosition(imgData),coordX = _getArcCenterPosition.coordX,coordY = _getArcCenterPosition.coordY;
+  return getImgInfo(src).then(function (res) {var
+    naturalWidth = res.width,naturalHeight = res.height;
+    var arcRadius = getArcRadius(imgData);
+    context.save();
+    context.beginPath();
+    context.arc(coordX, coordY, arcRadius, 0, 2 * Math.PI);
+    context.closePath();
+    context.clip();var _getCalculatedImagePo =
+    getCalculatedImagePosition(
+    imgData,
+    naturalWidth,
+    naturalHeight),left = _getCalculatedImagePo.left,top = _getCalculatedImagePo.top,realWidth = _getCalculatedImagePo.realWidth,realHeight = _getCalculatedImagePo.realHeight;
+
+    context.drawImage(
+    src,
+    0,
+    0,
+    naturalWidth,
+    naturalHeight,
+    left,
+    top,
+    realWidth,
+    realHeight);
+
+    context.restore();
+  });
+};
+
+var drawRectImage = function drawRectImage(context, imgData) {var
+  src = imgData.src,width = imgData.width,height = imgData.height,left = imgData.left,top = imgData.top;
+
+  return getImgInfo(src).then(function (res) {var
+    naturalWidth = res.width,naturalHeight = res.height;
+    context.save();
+    context.beginPath();
+    context.rect(left, top, width, height);
+    context.closePath();
+    context.clip();var _getCalculatedImagePo2 =
+
+
+
+
+
+
+    getCalculatedImagePosition(imgData, naturalWidth, naturalHeight),realLeft = _getCalculatedImagePo2.left,realTop = _getCalculatedImagePo2.top,realWidth = _getCalculatedImagePo2.realWidth,realHeight = _getCalculatedImagePo2.realHeight;
+    context.drawImage(
+    src,
+    0,
+    0,
+    naturalWidth,
+    naturalHeight,
+    realLeft,
+    realTop,
+    realWidth,
+    realHeight);
+
+    context.restore();
+  });
+};
+
+var drawArcBorder = function drawArcBorder(context, imgData) {var
+  border = imgData.border;var _getArcCenterPosition2 =
+  getArcCenterPosition(imgData),coordX = _getArcCenterPosition2.coordX,coordY = _getArcCenterPosition2.coordY;var _getBorderAttributes2 =
+  getBorderAttributes(border),borderWidth = _getBorderAttributes2.borderWidth,borderColor = _getBorderAttributes2.borderColor;
+  var arcRadius = getArcRadius(imgData, borderWidth);
+  context.save();
+  context.beginPath();
+  context.setLineWidth(borderWidth);
+  context.setStrokeStyle(borderColor);
+  context.arc(coordX, coordY, arcRadius, 0, 2 * Math.PI);
+  context.stroke();
+  context.restore();
+};
+
+var drawRectBorder = function drawRectBorder(context, imgData) {var
+  border = imgData.border;var
+  left = imgData.left,top = imgData.top,width = imgData.width,height = imgData.height;var _getBorderAttributes3 =
+  getBorderAttributes(border),borderWidth = _getBorderAttributes3.borderWidth,borderColor = _getBorderAttributes3.borderColor;
+
+  var correctedBorderWidth = borderWidth + 1; // draw may cause empty 0.5 space
+  context.save();
+  context.beginPath();
+  context.setLineWidth(correctedBorderWidth);
+  context.setStrokeStyle(borderColor);
+
+  context.rect(
+  left + borderWidth / 2,
+  top + borderWidth / 2,
+  width - borderWidth,
+  height - borderWidth);
+
+  context.stroke();
+  context.restore();
+};
+
+// image, enable border-radius: 50%, border, bgColor
+var drawImage = function drawImage(context, imgData) {var
+  border = imgData.border,borderRadius = imgData['border-radius'];
+  var drawImagePromise;
+  if (hasBorderRadius(borderRadius)) {
+    drawImagePromise = drawArcImage(context, imgData);
+  } else {
+    drawImagePromise = drawRectImage(context, imgData);
+  }
+
+  return drawImagePromise.then(function () {
+    if (hasBorder(border)) {
+      if (hasBorderRadius(borderRadius)) {
+        return drawArcBorder(context, imgData);
+      } else {
+        return drawRectBorder(context, imgData);
+      }
+    }
+    return Promise.resolve();
+  });
+};
+
+// e.g. 10%, 4px
+var getBorderRadius = function getBorderRadius(imgData) {var
+  width = imgData.width,height = imgData.height,borderRadiusAttr = imgData['border-radius'];
+  var borderRadius = parseInt(borderRadiusAttr, 10);
+  if (borderRadiusAttr.indexOf('%') !== -1) {
+    var borderRadiusX = parseInt(borderRadius / 100 * width, 10);
+    var borderRadiusY = parseInt(borderRadius / 100 * height, 10);
+    return {
+      isCircle: borderRadiusX === borderRadiusY,
+      borderRadius: borderRadiusX,
+      borderRadiusX: borderRadiusX,
+      borderRadiusY: borderRadiusY };
+
+  } else {
+    return {
+      isCircle: true,
+      borderRadius: borderRadius };
+
+  }
+};
+
+var drawViewArcBorder = function drawViewArcBorder(context, imgData) {var
+  width = imgData.width,height = imgData.height,left = imgData.left,top = imgData.top,backgroundColor = imgData.backgroundColor,border = imgData.border;var _getBorderRadius =
+  getBorderRadius(imgData),borderRadius = _getBorderRadius.borderRadius;var _getBorderAttributes4 =
+  getBorderAttributes(border),borderWidth = _getBorderAttributes4.borderWidth,borderColor = _getBorderAttributes4.borderColor;
+  // console.log('🐞-imgData', imgData)
+  context.beginPath();
+  context.moveTo(left + borderRadius, top);
+  context.lineTo(left + width - borderRadius, top);
+  context.arcTo(
+  left + width,
+  top,
+  left + width,
+  top + borderRadius,
+  borderRadius);
+
+  context.lineTo(left + width, top + height - borderRadius);
+  context.arcTo(
+  left + width,
+  top + height,
+  left + width - borderRadius,
+  top + height,
+  borderRadius);
+
+  context.lineTo(left + borderRadius, top + height);
+  context.arcTo(
+  left,
+  top + height,
+  left,
+  top + height - borderRadius,
+  borderRadius);
+
+  context.lineTo(left, top + borderRadius);
+  context.arcTo(left, top, left + borderRadius, top, borderRadius);
+  context.closePath();
+  if (backgroundColor) {
+    context.setFillStyle(backgroundColor);
+    context.fill();
+  }
+  if (borderColor && borderWidth) {
+    context.setLineWidth(borderWidth);
+    context.setStrokeStyle(borderColor);
+    context.stroke();
+  }
+};
+
+var drawViewBezierBorder = function drawViewBezierBorder(context, imgData) {var
+  width = imgData.width,height = imgData.height,left = imgData.left,top = imgData.top,backgroundColor = imgData.backgroundColor,border = imgData.border;var _getBorderAttributes5 =
+  getBorderAttributes(border),borderWidth = _getBorderAttributes5.borderWidth,borderColor = _getBorderAttributes5.borderColor;var _getBorderRadius2 =
+  getBorderRadius(imgData),borderRadiusX = _getBorderRadius2.borderRadiusX,borderRadiusY = _getBorderRadius2.borderRadiusY;
+  context.beginPath();
+  context.moveTo(left + borderRadiusX, top);
+  context.lineTo(left + width - borderRadiusX, top);
+  context.quadraticCurveTo(left + width, top, left + width, top + borderRadiusY);
+  context.lineTo(left + width, top + height - borderRadiusY);
+  context.quadraticCurveTo(
+  left + width,
+  top + height,
+  left + width - borderRadiusX,
+  top + height);
+
+  context.lineTo(left + borderRadiusX, top + height);
+  context.quadraticCurveTo(
+  left,
+  top + height,
+  left,
+  top + height - borderRadiusY);
+
+  context.lineTo(left, top + borderRadiusY);
+  context.quadraticCurveTo(left, top, left + borderRadiusX, top);
+  context.closePath();
+  if (backgroundColor) {
+    context.setFillStyle(backgroundColor);
+    context.fill();
+  }
+  if (borderColor && borderWidth) {
+    context.setLineWidth(borderWidth);
+    context.setStrokeStyle(borderColor);
+    context.stroke();
+  }
+};
+
+// enable border, border-radius, bgColor, position
+var drawView = function drawView(context, imgData) {var _getBorderRadius3 =
+  getBorderRadius(imgData),isCircle = _getBorderRadius3.isCircle;
+  if (isCircle) {
+    drawViewArcBorder(context, imgData);
+  } else {
+    drawViewBezierBorder(context, imgData);
+  }
+};
+
+var isTextElement = function isTextElement(item) {var
+  text = item.dataset.text,type = item.type;
+  return Boolean(text) || type === 'text';
+};
+
+var isImageElement = function isImageElement(item) {var
+  src = item.src,type = item.type;
+  return Boolean(src) || type === 'image';
+};
+
+var isViewElement = function isViewElement(item) {var
+  type = item.type;
+  return type === 'view';
+};
+
+var formatElementData = function formatElementData(elements) {return (
+    elements.map(function (element) {
+      if (isTextElement(element)) {
+        element.type = 'text';
+        element.rank = DEFAULT_RANK.text;
+      } else if (isImageElement(element)) {
+        element.type = 'image';
+        element.rank = DEFAULT_RANK.image;
+      } else {
+        element.type = 'view';
+        element.rank = DEFAULT_RANK.view;
+      }
+      return element;
+    }));};
+
+// todo: use z-index as order to draw??
+var getSortedElementsData = function getSortedElementsData(elements) {return (
+    elements.sort(function (a, b) {
+      if (a.rank < b.rank) {
+        return -1;
+      } else if (a.rank > b.rank) {
+        return 1;
+      }
+      return 0;
+    }));};
+
+var drawElements = function drawElements(context, storeItems) {
+  var itemPromise = [];
+  storeItems.forEach(function (item) {
+    if (isTextElement(item)) {
+      var text = drawText(context, item);
+      itemPromise.push(text);
+    } else if (isImageElement(item)) {
+      var image = drawImage(context, item);
+      itemPromise.push(image);
+    } else {
+      var view = drawView(context, item);
+      itemPromise.push(view);
+    }
+  });
+  return itemPromise;
+};
+
+// storeObject: { 0: [...], 1: [...] }
+// chain call promise based on Object key
+var drawElementBaseOnIndex = function drawElementBaseOnIndex(context, storeObject) {var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;var drawPromise = arguments.length > 3 ? arguments[3] : undefined;
+  if (typeof drawPromise === 'undefined') {
+    drawPromise = Promise.resolve();
+  }
+  var objectKey = key; // note: key is changing when execute promise then
+  var chainPromise = drawPromise.then(function () {
+    var nextPromise = storeObject[objectKey] ?
+    Promise.all(drawElements(context, storeObject[objectKey])) :
+    Promise.resolve();
+    return nextPromise;
+  });
+
+  if (key >= Object.keys(storeObject).length) {
+    return chainPromise;
+  } else {
+    return drawElementBaseOnIndex(context, storeObject, key + 1, chainPromise);
+  }
+};
+
+var drawCanvas = function drawCanvas(canvasId, wrapperData, innerData) {
+  var context = wx.createCanvasContext(canvasId);
+  context.setTextBaseline('top');
+
+  // todo: use this after weixin fix stupid clip can't work bug in fillRect
+  // for now, just set canvas background as a compromise
+  drawWrapper(context, wrapperData[0]);
+
+  var storeObject = {};
+
+  var sortedElementData = getSortedElementsData(formatElementData(innerData)); // fake z-index
+
+  sortedElementData.forEach(function (item) {
+    if (!storeObject[item.rank]) {
+      // initialize
+      storeObject[item.rank] = [];
+    }
+    if (isTextElement(item) || isImageElement(item) || isViewElement(item)) {
+      storeObject[item.rank].push(item);
+    }
+  });
+  // note: draw is async
+  return drawElementBaseOnIndex(context, storeObject).then(
+  function () {return (
+      new Promise(function (resolve, reject) {
+        context.draw(true, function () {
+          resolve();
+        });
+      }));});
+
+};
+
+var wxSelectorQuery = function wxSelectorQuery(element) {return (
+    new Promise(function (resolve, reject) {
+      try {
+        wx.
+        createSelectorQuery().
+        selectAll(element).
+        fields(
+        {
+          dataset: true,
+          size: true,
+          rect: true,
+          properties: PROPERTIES,
+          computedStyle: COMPUTED_STYLE },
+
+        function (res) {
+          resolve(res);
+        }).
+
+        exec();
+      } catch (error) {
+        reject(error);
+      }
+    }));};
+
+var wxml2canvas = function wxml2canvas(wrapperId, elementsClass, canvasId) {
+  var getWrapperElement = wxSelectorQuery(wrapperId);
+  var getInnerElements = wxSelectorQuery(elementsClass);
+
+  return Promise.all([getWrapperElement, getInnerElements]).then(function (data) {
+    return drawCanvas(canvasId, data[0], data[1]);
+  });
+};
+
+// export default wxml2canvas
+module.exports = wxml2canvas;
 
 /***/ }),
 
@@ -4146,7 +4701,20 @@ var index = {
 
 /***/ }),
 
-/***/ 169:
+/***/ 17:
+/*!**************************************************************************!*\
+  !*** D:/wwwroot/cqcarbonwxapp/js_sdk/luch-request/luch-request/index.js ***!
+  \**************************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });exports.default = void 0;var _Request = _interopRequireDefault(__webpack_require__(/*! ./core/Request */ 18));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}var _default =
+_Request.default;exports.default = _default;
+
+/***/ }),
+
+/***/ 177:
 /*!**************************************************************!*\
   !*** D:/wwwroot/cqcarbonwxapp/components/uni-popup/popup.js ***!
   \**************************************************************/
@@ -4154,7 +4722,7 @@ var index = {
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
-Object.defineProperty(exports, "__esModule", { value: true });exports.default = void 0;var _message = _interopRequireDefault(__webpack_require__(/*! ./message.js */ 170));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
+Object.defineProperty(exports, "__esModule", { value: true });exports.default = void 0;var _message = _interopRequireDefault(__webpack_require__(/*! ./message.js */ 178));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}
 // 定义 type 类型:弹出类型:top/bottom/center
 var config = {
   // 顶部弹出
@@ -4181,20 +4749,7 @@ var config = {
 
 /***/ }),
 
-/***/ 17:
-/*!**************************************************************************!*\
-  !*** D:/wwwroot/cqcarbonwxapp/js_sdk/luch-request/luch-request/index.js ***!
-  \**************************************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });exports.default = void 0;var _Request = _interopRequireDefault(__webpack_require__(/*! ./core/Request */ 18));function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}var _default =
-_Request.default;exports.default = _default;
-
-/***/ }),
-
-/***/ 170:
+/***/ 178:
 /*!****************************************************************!*\
   !*** D:/wwwroot/cqcarbonwxapp/components/uni-popup/message.js ***!
   \****************************************************************/
@@ -4435,7 +4990,7 @@ Request = /*#__PURE__*/function () {
 
 /***/ }),
 
-/***/ 185:
+/***/ 186:
 /*!************************************************************************!*\
   !*** D:/wwwroot/cqcarbonwxapp/components/mescroll-uni/mescroll-uni.js ***!
   \************************************************************************/
@@ -5246,7 +5801,7 @@ MeScroll.prototype.preventDefault = function (e) {
 
 /***/ }),
 
-/***/ 186:
+/***/ 187:
 /*!*******************************************************************************!*\
   !*** D:/wwwroot/cqcarbonwxapp/components/mescroll-uni/mescroll-uni-option.js ***!
   \*******************************************************************************/
@@ -5293,7 +5848,7 @@ GlobalOption;exports.default = _default;
 
 /***/ }),
 
-/***/ 187:
+/***/ 188:
 /*!**********************************************************************!*\
   !*** D:/wwwroot/cqcarbonwxapp/components/mescroll-uni/wxs/mixins.js ***!
   \**********************************************************************/

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 15 - 15
unpackage/dist/dev/mp-weixin/components/mescroll-uni/components/mescroll-empty.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 14 - 14
unpackage/dist/dev/mp-weixin/components/mescroll-uni/components/mescroll-top.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 22 - 22
unpackage/dist/dev/mp-weixin/components/mescroll-uni/mescroll-body.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 14 - 14
unpackage/dist/dev/mp-weixin/components/uni-popup/uni-popup-dialog.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 16 - 16
unpackage/dist/dev/mp-weixin/components/uni-popup/uni-popup.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 14 - 14
unpackage/dist/dev/mp-weixin/components/uni-transition/uni-transition.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 34 - 26
unpackage/dist/dev/mp-weixin/pages/index/index.js


+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/index/index.json

@@ -1,6 +1,7 @@
 {
   "navigationBarTitleText": "",
   "usingComponents": {
+    "custom-nodata": "/components/custom-nodata/custom-nodata",
     "uni-popup": "/components/uni-popup/uni-popup",
     "quick-buy": "/pages/index/modal/quickBuy"
   }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/index/index.wxml


+ 1 - 0
unpackage/dist/dev/mp-weixin/pages/index/index.wxss

@@ -61,4 +61,5 @@ page{background-color: #f5f5f5;}
 .rank-list-user .photo{width: 88rpx;height: 88rpx;-webkit-border-radius: 50%;border-radius: 50%;margin-right: 24rpx;}
 .rank-list-user .name{font-size: 28rpx;color: #333;-webkit-box-flex: 1;-webkit-flex: 1;flex: 1;}
 .rank-list-carbon{width: 170rpx;margin-left: 0;font-size: 26rpx;color: #26D18B;line-height: 37rpx;}
+.rank-wrap .nodata {width: auto;padding: 100rpx 0;background-color: #fff;-webkit-border-radius: 16rpx;border-radius: 16rpx;}
 

+ 12 - 9
unpackage/dist/dev/mp-weixin/pages/login/loginType.js

@@ -213,15 +213,18 @@ var _vuex = __webpack_require__(/*! vuex */ 16);function ownKeys(object, enumera
             };
             serf.login(res.data.retBody);
             serf.upInfo();
-            var userKey = uni.getStorageSync('userInfo');
-            console.log('userKey', userKey.phone);
-            if (userKey.phone) {
-              serf.havePhone = true;
-            } else {
-              // console.log('hasLogin',serf.hasLogin);
-              // console.log('havePhone==false',serf.havePhone==false);
-              return;
-            }
+            uni.getStorage({
+              key: 'userInfo',
+              success: function success(res) {
+                // console.log('userInfo',res.data);
+                if (res.data.phone) {
+                  serf.havePhone = true;
+                } else {
+                  return;
+                }
+              } });
+
+
             if (serf.backUrl == '' || !serf.backUrl) {
               uni.switchTab({
                 url: '/pages/usercenter/usercenter' });

+ 3 - 0
unpackage/dist/dev/mp-weixin/pages/login/loginType.wxss

@@ -149,6 +149,9 @@
 
 
 
+
+
+
 
 
 

+ 3 - 5
unpackage/dist/dev/mp-weixin/pages/use/use.js

@@ -97,11 +97,6 @@ var render = function() {
   var _vm = this
   var _h = _vm.$createElement
   var _c = _vm._self._c || _h
-  if (!_vm._isMounted) {
-    _vm.e0 = function($event) {
-      return this.$api.msg("稍后展示")
-    }
-  }
 }
 var recyclableRender = false
 var staticRenderFns = []
@@ -190,6 +185,9 @@ var _default =
     },
     huodong: function huodong() {
       this.$api.msg('暂未开放');
+    },
+    useClick: function useClick() {
+      this.$api.msg('稍后展示');
     } } };exports.default = _default;
 
 /***/ }),

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/use/use.wxml


+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/use/use.wxss

@@ -1,5 +1,5 @@
 page{background-color: #f5f5f5;}
-.top-img{height: 344rpx;}
+.top-img{height: 344rpx;z-index: -1;}
 .use-wrap{margin: -153rpx 40rpx 40rpx;padding: 60rpx 24rpx 24rpx;background-color: #fff;-webkit-box-shadow: 0px 0px 12rpx 0px rgba(0, 0, 0, 0.04);box-shadow: 0px 0px 12rpx 0px rgba(0, 0, 0, 0.04);-webkit-border-radius: 16rpx;border-radius: 16rpx;}
 .use-wrap-header{display: -webkit-box;display: -webkit-flex;display: flex;-webkit-box-pack: justify;-webkit-justify-content: space-between;justify-content: space-between;-webkit-box-align: center;-webkit-align-items: center;align-items: center;margin-bottom: 60rpx;}
 .use-wrap-header .til{font-size: 32rpx;color: #333;font-weight: 500;}

+ 2 - 2
unpackage/dist/dev/mp-weixin/pages/usercenter/certificateList/certificateList.js

@@ -167,7 +167,7 @@ var _mescrollMixins = _interopRequireDefault(__webpack_require__(/*! @/component
 //
 //
 // 引入mescroll-mixins.js
-var MescrollBody = function MescrollBody() {Promise.all(/*! require.ensure | components/mescroll-uni/mescroll-body */[__webpack_require__.e("common/vendor"), __webpack_require__.e("components/mescroll-uni/mescroll-body")]).then((function () {return resolve(__webpack_require__(/*! @/components/mescroll-uni/mescroll-body.vue */ 180));}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);}; // 注意.vue后缀不能省
+var MescrollBody = function MescrollBody() {Promise.all(/*! require.ensure | components/mescroll-uni/mescroll-body */[__webpack_require__.e("common/vendor"), __webpack_require__.e("components/mescroll-uni/mescroll-body")]).then((function () {return resolve(__webpack_require__(/*! @/components/mescroll-uni/mescroll-body.vue */ 181));}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);}; // 注意.vue后缀不能省
 var _default = { mixins: [_mescrollMixins.default], // 使用mixin
   components: { MescrollBody: MescrollBody }, data: function data() {return { $getInnerImg: this.$getInnerImg, mescroll: null, // mescroll实例对象 (此行可删,mixins已默认)
       // 下拉刷新的配置(可选, 绝大部分情况无需配置)
@@ -252,7 +252,7 @@ var _default = { mixins: [_mescrollMixins.default], // 使用mixin
       });
 
     },
-    goDetails: function goDetails(id) {
+    goCertDetails: function goCertDetails(id) {
       console.log(id);
       uni.navigateTo({
         url: '/pages/usercenter/certificateList/certificate/certificate?orderid=' + id });

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/usercenter/certificateList/certificateList.wxml


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 42 - 20
unpackage/dist/dev/mp-weixin/pages/usercenter/orderList/orderList.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/usercenter/orderList/orderList.wxml


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 18 - 18
unpackage/dist/dev/mp-weixin/pages/usercenter/orderList/orderdetails/orderdetails.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 17 - 17
unpackage/dist/dev/mp-weixin/pages/usercenter/subscribe/subscribe.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
unpackage/dist/dev/mp-weixin/pages/usercenter/usercenter.wxml


+ 545 - 0
utils/wxml2canvas.js

@@ -0,0 +1,545 @@
+/* eslint-disable */
+const PROPERTIES = ['hover-class', 'hover-start-time', 'space', 'src']
+const COMPUTED_STYLE = [
+  'color',
+  'font-size',
+  'font-weight',
+  'font-family',
+  'backgroundColor',
+  'border',
+  'border-radius',
+  'box-sizing',
+  'line-height',
+]
+const DEFAULT_BORDER = '0px none rgb(0, 0, 0)'
+const DEFAULT_BORDER_RADIUS = '0px'
+
+// default z-index??
+const DEFAULT_RANK = {
+  view: 0,
+  image: 1,
+  text: 2,
+}
+
+const drawWrapper = (context, data) => {
+  const { backgroundColor, width, height } = data
+  context.setFillStyle(backgroundColor)
+  context.fillRect(0, 0, width, height)
+}
+
+// todo: do more for different language
+const strLen = str => {
+  let count = 0
+  for (let i = 0, len = str.length; i < len; i++) {
+    count += str.charCodeAt(i) < 256 ? 1 : 2
+  }
+  return count / 2
+}
+
+const isMuitlpleLine = (data, text) => {
+  const { 'font-size': letterWidth, width } = data
+  const length = strLen(text)
+  const rowlineLength = length * parseInt(letterWidth, 10)
+  return rowlineLength > width
+}
+
+const drawMutipleLine = (context, data, text) => {
+  const {
+    'font-size': letterWidth,
+    width,
+    left,
+    top,
+    'line-height': lineHeightAttr,
+  } = data
+  const lineHieght = lineHeightAttr === 'normal' ? Math.round(1.2 * letterWidth) : lineHeightAttr
+  const rowLetterCount = Math.floor(width / parseInt(letterWidth, 10))
+  const length = strLen(text)
+  for (let i = 0; i < length; i += rowLetterCount) {
+    const lineText = text.substring(i, i + rowLetterCount)
+    const rowNumber = Math.floor(i / rowLetterCount)
+    const rowTop = top + rowNumber * parseInt(lineHieght, 10)
+    context.fillText(lineText, left, rowTop)
+  }
+}
+
+// enable color, font, for now only support chinese
+const drawText = (context, data) => {
+  const {
+    dataset: { text },
+    left,
+    top,
+    color,
+    'font-weight': fontWeight,
+    'font-size': fontSize,
+    'font-family': fontFamily,
+  } = data
+  const canvasText = Array.isArray(text) ? text[0] : text
+  context.font = `${fontWeight} ${Math.round(
+    parseFloat(fontSize),
+  )}px ${fontFamily}`
+  context.setFillStyle(color)
+  if (isMuitlpleLine(data, canvasText)) {
+    drawMutipleLine(context, data, canvasText)
+  } else {
+    context.fillText(canvasText, left, top)
+  }
+  context.restore()
+}
+
+const getImgInfo = src =>
+  new Promise((resolve, reject) => {
+    wx.getImageInfo({
+      src,
+      success(res) {
+        resolve(res)
+      },
+    })
+  })
+
+const hasBorder = border => border !== DEFAULT_BORDER
+const hasBorderRadius = borderRadius => borderRadius !== DEFAULT_BORDER_RADIUS
+
+const getBorderAttributes = border => {
+  let borderColor, borderStyle
+  let borderWidth = 0
+
+  if (hasBorder) {
+    borderWidth = parseInt(border.split(/\s/)[0], 10)
+    borderStyle = border.split(/\s/)[1]
+    borderColor = border.match(/(rgb).*/gi)[0]
+  }
+  return {
+    borderWidth,
+    borderStyle,
+    borderColor,
+  }
+}
+
+const getImgRect = (imgData, borderWidth) => {
+  const { width, height, left, top } = imgData
+  const imgWidth = width - 2 * borderWidth
+  const imgHeight = height - 2 * borderWidth
+  const imgLeft = left + borderWidth
+  const imgTop = top + borderWidth
+  return {
+    imgWidth,
+    imgHeight,
+    imgLeft,
+    imgTop,
+  }
+}
+
+const getArcCenterPosition = imgData => {
+  const { width, height, left, top } = imgData
+  const coordX = width / 2 + left
+  const coordY = height / 2 + top
+  return {
+    coordX,
+    coordY,
+  }
+}
+
+const getArcRadius = (imgData, borderWidth = 0) => {
+  const { width } = imgData
+  return width / 2 - borderWidth / 2
+}
+
+const getCalculatedImagePosition = (imgData, naturalWidth, naturalHeight) => {
+  const { border } = imgData
+  const { borderWidth } = getBorderAttributes(border)
+  const { imgWidth, imgHeight, imgLeft, imgTop } = getImgRect(
+    imgData,
+    borderWidth,
+  )
+  const ratio = naturalWidth / naturalHeight
+  // tweak for real width and position => center center
+  const realWidth = ratio > 0 ? imgWidth : imgHeight * ratio
+  const realHeight = ratio > 0 ? imgWidth * (1 / ratio) : imgHeight
+  const offsetLeft = ratio > 0 ? 0 : (imgWidth - realWidth) / 2
+  const offsetTop = ratio > 0 ? (imgHeight - realHeight) / 2 : 0
+  return {
+    realWidth,
+    realHeight,
+    left: imgLeft + offsetLeft,
+    top: imgTop + offsetTop,
+  }
+}
+
+const drawArcImage = (context, imgData) => {
+  const { src } = imgData
+  const { coordX, coordY } = getArcCenterPosition(imgData)
+  return getImgInfo(src).then(res => {
+    const { width: naturalWidth, height: naturalHeight } = res
+    const arcRadius = getArcRadius(imgData)
+    context.save()
+    context.beginPath()
+    context.arc(coordX, coordY, arcRadius, 0, 2 * Math.PI)
+    context.closePath()
+    context.clip()
+    const { left, top, realWidth, realHeight } = getCalculatedImagePosition(
+      imgData,
+      naturalWidth,
+      naturalHeight,
+    )
+    context.drawImage(
+      src,
+      0,
+      0,
+      naturalWidth,
+      naturalHeight,
+      left,
+      top,
+      realWidth,
+      realHeight,
+    )
+    context.restore()
+  })
+}
+
+const drawRectImage = (context, imgData) => {
+  const { src, width, height, left, top } = imgData
+
+  return getImgInfo(src).then(res => {
+    const { width: naturalWidth, height: naturalHeight } = res
+    context.save()
+    context.beginPath()
+    context.rect(left, top, width, height)
+    context.closePath()
+    context.clip()
+
+    const {
+      left: realLeft,
+      top: realTop,
+      realWidth,
+      realHeight,
+    } = getCalculatedImagePosition(imgData, naturalWidth, naturalHeight)
+    context.drawImage(
+      src,
+      0,
+      0,
+      naturalWidth,
+      naturalHeight,
+      realLeft,
+      realTop,
+      realWidth,
+      realHeight,
+    )
+    context.restore()
+  })
+}
+
+const drawArcBorder = (context, imgData) => {
+  const { border } = imgData
+  const { coordX, coordY } = getArcCenterPosition(imgData)
+  const { borderWidth, borderColor } = getBorderAttributes(border)
+  const arcRadius = getArcRadius(imgData, borderWidth)
+  context.save()
+  context.beginPath()
+  context.setLineWidth(borderWidth)
+  context.setStrokeStyle(borderColor)
+  context.arc(coordX, coordY, arcRadius, 0, 2 * Math.PI)
+  context.stroke()
+  context.restore()
+}
+
+const drawRectBorder = (context, imgData) => {
+  const { border } = imgData
+  const { left, top, width, height } = imgData
+  const { borderWidth, borderColor } = getBorderAttributes(border)
+
+  const correctedBorderWidth = borderWidth + 1 // draw may cause empty 0.5 space
+  context.save()
+  context.beginPath()
+  context.setLineWidth(correctedBorderWidth)
+  context.setStrokeStyle(borderColor)
+
+  context.rect(
+    left + borderWidth / 2,
+    top + borderWidth / 2,
+    width - borderWidth,
+    height - borderWidth,
+  )
+  context.stroke()
+  context.restore()
+}
+
+// image, enable border-radius: 50%, border, bgColor
+const drawImage = (context, imgData) => {
+  const { border, 'border-radius': borderRadius } = imgData
+  let drawImagePromise
+  if (hasBorderRadius(borderRadius)) {
+    drawImagePromise = drawArcImage(context, imgData)
+  } else {
+    drawImagePromise = drawRectImage(context, imgData)
+  }
+
+  return drawImagePromise.then(() => {
+    if (hasBorder(border)) {
+      if (hasBorderRadius(borderRadius)) {
+        return drawArcBorder(context, imgData)
+      } else {
+        return drawRectBorder(context, imgData)
+      }
+    }
+    return Promise.resolve()
+  })
+}
+
+// e.g. 10%, 4px
+const getBorderRadius = imgData => {
+  const { width, height, 'border-radius': borderRadiusAttr } = imgData
+  const borderRadius = parseInt(borderRadiusAttr, 10)
+  if (borderRadiusAttr.indexOf('%') !== -1) {
+    const borderRadiusX = parseInt(borderRadius / 100 * width, 10)
+    const borderRadiusY = parseInt(borderRadius / 100 * height, 10)
+    return {
+      isCircle: borderRadiusX === borderRadiusY,
+      borderRadius: borderRadiusX,
+      borderRadiusX,
+      borderRadiusY,
+    }
+  } else {
+    return {
+      isCircle: true,
+      borderRadius,
+    }
+  }
+}
+
+const drawViewArcBorder = (context, imgData) => {
+  const { width, height, left, top, backgroundColor, border } = imgData
+  const { borderRadius } = getBorderRadius(imgData)
+  const { borderWidth, borderColor } = getBorderAttributes(border)
+  // console.log('🐞-imgData', imgData)
+  context.beginPath()
+  context.moveTo(left + borderRadius, top)
+  context.lineTo(left + width - borderRadius, top)
+  context.arcTo(
+    left + width,
+    top,
+    left + width,
+    top + borderRadius,
+    borderRadius,
+  )
+  context.lineTo(left + width, top + height - borderRadius)
+  context.arcTo(
+    left + width,
+    top + height,
+    left + width - borderRadius,
+    top + height,
+    borderRadius,
+  )
+  context.lineTo(left + borderRadius, top + height)
+  context.arcTo(
+    left,
+    top + height,
+    left,
+    top + height - borderRadius,
+    borderRadius,
+  )
+  context.lineTo(left, top + borderRadius)
+  context.arcTo(left, top, left + borderRadius, top, borderRadius)
+  context.closePath()
+  if (backgroundColor) {
+    context.setFillStyle(backgroundColor)
+    context.fill()
+  }
+  if (borderColor && borderWidth) {
+    context.setLineWidth(borderWidth)
+    context.setStrokeStyle(borderColor)
+    context.stroke()
+  }
+}
+
+const drawViewBezierBorder = (context, imgData) => {
+  const { width, height, left, top, backgroundColor, border } = imgData
+  const { borderWidth, borderColor } = getBorderAttributes(border)
+  const { borderRadiusX, borderRadiusY } = getBorderRadius(imgData)
+  context.beginPath()
+  context.moveTo(left + borderRadiusX, top)
+  context.lineTo(left + width - borderRadiusX, top)
+  context.quadraticCurveTo(left + width, top, left + width, top + borderRadiusY)
+  context.lineTo(left + width, top + height - borderRadiusY)
+  context.quadraticCurveTo(
+    left + width,
+    top + height,
+    left + width - borderRadiusX,
+    top + height,
+  )
+  context.lineTo(left + borderRadiusX, top + height)
+  context.quadraticCurveTo(
+    left,
+    top + height,
+    left,
+    top + height - borderRadiusY,
+  )
+  context.lineTo(left, top + borderRadiusY)
+  context.quadraticCurveTo(left, top, left + borderRadiusX, top)
+  context.closePath()
+  if (backgroundColor) {
+    context.setFillStyle(backgroundColor)
+    context.fill()
+  }
+  if (borderColor && borderWidth) {
+    context.setLineWidth(borderWidth)
+    context.setStrokeStyle(borderColor)
+    context.stroke()
+  }
+}
+
+// enable border, border-radius, bgColor, position
+const drawView = (context, imgData) => {
+  const { isCircle } = getBorderRadius(imgData)
+  if (isCircle) {
+    drawViewArcBorder(context, imgData)
+  } else {
+    drawViewBezierBorder(context, imgData)
+  }
+}
+
+const isTextElement = item => {
+  const { dataset: { text }, type } = item
+  return Boolean(text) || type === 'text'
+}
+
+const isImageElement = item => {
+  const { src, type } = item
+  return Boolean(src) || type === 'image'
+}
+
+const isViewElement = item => {
+  const { type } = item
+  return type === 'view'
+}
+
+const formatElementData = elements =>
+  elements.map(element => {
+    if (isTextElement(element)) {
+      element.type = 'text'
+      element.rank = DEFAULT_RANK.text
+    } else if (isImageElement(element)) {
+      element.type = 'image'
+      element.rank = DEFAULT_RANK.image
+    } else {
+      element.type = 'view'
+      element.rank = DEFAULT_RANK.view
+    }
+    return element
+  })
+
+// todo: use z-index as order to draw??
+const getSortedElementsData = elements =>
+  elements.sort((a, b) => {
+    if (a.rank < b.rank) {
+      return -1
+    } else if (a.rank > b.rank) {
+      return 1
+    }
+    return 0
+  })
+
+const drawElements = (context, storeItems) => {
+  const itemPromise = []
+  storeItems.forEach(item => {
+    if (isTextElement(item)) {
+      const text = drawText(context, item)
+      itemPromise.push(text)
+    } else if (isImageElement(item)) {
+      const image = drawImage(context, item)
+      itemPromise.push(image)
+    } else {
+      const view = drawView(context, item)
+      itemPromise.push(view)
+    }
+  })
+  return itemPromise
+}
+
+// storeObject: { 0: [...], 1: [...] }
+// chain call promise based on Object key
+const drawElementBaseOnIndex = (context, storeObject, key = 0, drawPromise) => {
+  if (typeof drawPromise === 'undefined') {
+    drawPromise = Promise.resolve()
+  }
+  const objectKey = key // note: key is changing when execute promise then
+  const chainPromise = drawPromise.then(() => {
+    const nextPromise = storeObject[objectKey]
+      ? Promise.all(drawElements(context, storeObject[objectKey]))
+      : Promise.resolve()
+    return nextPromise
+  })
+
+  if (key >= Object.keys(storeObject).length) {
+    return chainPromise
+  } else {
+    return drawElementBaseOnIndex(context, storeObject, key + 1, chainPromise)
+  }
+}
+
+const drawCanvas = (canvasId, wrapperData, innerData) => {
+  const context = wx.createCanvasContext(canvasId)
+  context.setTextBaseline('top')
+
+  // todo: use this after weixin fix stupid clip can't work bug in fillRect
+  // for now, just set canvas background as a compromise
+  drawWrapper(context, wrapperData[0])
+
+  const storeObject = {}
+
+  const sortedElementData = getSortedElementsData(formatElementData(innerData)) // fake z-index
+
+  sortedElementData.forEach(item => {
+    if (!storeObject[item.rank]) {
+      // initialize
+      storeObject[item.rank] = []
+    }
+    if (isTextElement(item) || isImageElement(item) || isViewElement(item)) {
+      storeObject[item.rank].push(item)
+    }
+  })
+  // note: draw is async
+  return drawElementBaseOnIndex(context, storeObject).then(
+    () =>
+      new Promise((resolve, reject) => {
+        context.draw(true, () => {
+          resolve()
+        })
+      }),
+  )
+}
+
+const wxSelectorQuery = element =>
+  new Promise((resolve, reject) => {
+    try {
+      wx
+        .createSelectorQuery()
+        .selectAll(element)
+        .fields(
+          {
+            dataset: true,
+            size: true,
+            rect: true,
+            properties: PROPERTIES,
+            computedStyle: COMPUTED_STYLE,
+          },
+          res => {
+            resolve(res)
+          },
+        )
+        .exec()
+    } catch (error) {
+      reject(error)
+    }
+  })
+
+const wxml2canvas = (wrapperId, elementsClass, canvasId) => {
+  const getWrapperElement = wxSelectorQuery(wrapperId)
+  const getInnerElements = wxSelectorQuery(elementsClass)
+
+  return Promise.all([getWrapperElement, getInnerElements]).then(data => {
+    return drawCanvas(canvasId, data[0], data[1])
+  })
+}
+
+// export default wxml2canvas
+module.exports = wxml2canvas