wzy 1 год назад
Родитель
Сommit
fef673ad27
100 измененных файлов с 9363 добавлено и 1319 удалено
  1. 1 0
      App.vue
  2. 7 2
      components/keyboard/keyboard.vue
  3. 127 78
      components/thorui/tui-picker/tui-picker.vue
  4. 75 1
      config/modules/home.js
  5. 15 0
      config/modules/user.js
  6. 171 0
      order_module/orderDetail/index.scss
  7. 191 0
      order_module/orderDetail/index.vue
  8. 199 0
      order_module/searchOrder/index.scss
  9. 205 0
      order_module/searchOrder/index.vue
  10. 94 1
      pages.json
  11. 1 1
      pages/login/index.vue
  12. 30 26
      pages/tabbar/index/data.js
  13. 12 5
      pages/tabbar/index/index.scss
  14. 186 118
      pages/tabbar/index/index.vue
  15. 73 39
      pages/tabbar/order/index.vue
  16. 5 2
      pages/tabbar/user/index.vue
  17. 120 0
      pages_module/bindingCard/index.scss
  18. 313 0
      pages_module/bindingCard/index.vue
  19. 270 0
      pages_module/components/waterContainer/index.vue
  20. 48 0
      pages_module/financial/data.js
  21. 263 0
      pages_module/financial/index.scss
  22. 114 0
      pages_module/financial/index.vue
  23. 138 0
      pages_module/operateData/index.scss
  24. 217 0
      pages_module/operateData/index.vue
  25. 36 26
      pages_module/orderVerifica/index.vue
  26. 93 0
      pages_module/receiving/index.scss
  27. 133 0
      pages_module/receiving/index.vue
  28. 7 3
      pages_module/scanCode/index.vue
  29. 137 110
      pages_module/scanCoupons/index.vue
  30. 57 0
      pages_module/walSuccess/index.vue
  31. 188 0
      pages_module/withdrawal/index.scss
  32. 221 0
      pages_module/withdrawal/index.vue
  33. BIN
      static/image/home/bg_index.png
  34. BIN
      static/image/order/complete_icon.png
  35. BIN
      static/image/order/error_icon.png
  36. BIN
      static/image/order/search-empty.png
  37. BIN
      static/image/order/success_icon.png
  38. BIN
      static/image/user/business_phone.png
  39. BIN
      static/image/user/business_user.png
  40. BIN
      static/image/user/code.png
  41. BIN
      static/image/user/header-bg.png
  42. BIN
      static/image/user/logo.png
  43. BIN
      static/image/user/pay_1.png
  44. BIN
      static/image/user/pay_2.png
  45. BIN
      static/image/user/pay_3.png
  46. BIN
      static/image/user/pay_4.png
  47. BIN
      static/image/user/pay_5.png
  48. BIN
      static/image/user/pay_6.png
  49. 0 907
      static/js/qrcode.js
  50. 201 0
      uni_modules/Sansnn-uQRCode/LICENSE.md
  51. 207 0
      uni_modules/Sansnn-uQRCode/README.md
  52. 12 0
      uni_modules/Sansnn-uQRCode/changelog.md
  53. 1 0
      uni_modules/Sansnn-uQRCode/common/cache.js
  54. 41 0
      uni_modules/Sansnn-uQRCode/common/queue.js
  55. 3 0
      uni_modules/Sansnn-uQRCode/common/types/cache.d.ts
  56. 4 0
      uni_modules/Sansnn-uQRCode/common/types/queue.d.ts
  57. 25 0
      uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue
  58. 25 0
      uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue
  59. 241 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js
  60. 18 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js
  61. 8 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js
  62. 17 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js
  63. 666 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js
  64. 11 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js
  65. 21 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js
  66. 21 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js
  67. 298 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js
  68. 142 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js
  69. 23 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js
  70. 21 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js
  71. 21 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js
  72. 1191 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js
  73. 22 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js
  74. 11 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js
  75. 22 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js
  76. 22 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js
  77. 3 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js
  78. 74 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js
  79. 96 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js
  80. 24 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js
  81. 39 0
      uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js
  82. 33 0
      uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js
  83. 80 0
      uni_modules/Sansnn-uQRCode/package.json
  84. 223 0
      uni_modules/lime-painter/changelog.md
  85. 150 0
      uni_modules/lime-painter/components/common/relation.js
  86. 28 0
      uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue
  87. 27 0
      uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue
  88. 33 0
      uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue
  89. 34 0
      uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue
  90. 461 0
      uni_modules/lime-painter/components/l-painter/l-painter.vue
  91. 214 0
      uni_modules/lime-painter/components/l-painter/nvue.js
  92. 0 0
      uni_modules/lime-painter/components/l-painter/painter.js
  93. 56 0
      uni_modules/lime-painter/components/l-painter/props.js
  94. 0 0
      uni_modules/lime-painter/components/l-painter/single.js
  95. 368 0
      uni_modules/lime-painter/components/l-painter/utils.js
  96. 166 0
      uni_modules/lime-painter/components/lime-painter/lime-painter.vue
  97. 119 0
      uni_modules/lime-painter/hybrid/html/index.html
  98. 0 0
      uni_modules/lime-painter/hybrid/html/painter.js
  99. 0 0
      uni_modules/lime-painter/hybrid/html/uni.webview.1.5.3.js
  100. 93 0
      uni_modules/lime-painter/package.json

+ 1 - 0
App.vue

@@ -16,3 +16,4 @@
 <style>
 	/* 每个页面公共css */
 </style>
+

+ 7 - 2
components/keyboard/keyboard.vue

@@ -11,7 +11,7 @@
                 <view class="right-top" @click="deleteOneWord">
                     <tui-icon name="deletekey" :size="30" color="#ACACAC"></tui-icon>
                 </view>
-                <view class="right-bottom" :style="{ backgroundColor: iptValue == '' ? '#FFD2BE' : '' }">验劵</view>
+                <view class="right-bottom" @click="setVerifica" :style="{ backgroundColor: iptValue == '' ? '#FFD2BE' : '' }">验劵</view>
             </view>
         </view>
         <view class="eng-board" v-else>
@@ -42,7 +42,7 @@
             </view>
             <view class="eng-topFour">
                 <view class="eng-number" @click="changeBoard">123</view>
-                <view class="eng-coupons" :style="{ backgroundColor: iptValue == '' ? '#FFD2BE' : '' }">验劵</view>
+                <view class="eng-coupons" @click="setVerifica" :style="{ backgroundColor: iptValue == '' ? '#FFD2BE' : '' }">验劵</view>
                 <view class="eng-empty" @click="deleteAll">清空</view>
             </view>
         </view>
@@ -101,6 +101,7 @@ export default {
             this.handleTouchEnd()
             if (val == 'ABC') {
                 this.changeBoard()
+                return
             } else if (val == '清空') {
                 this.deleteAll()
                 return
@@ -117,6 +118,10 @@ export default {
             this.handleTouchEnd()
             this.$emit('deleteAll')
         },
+        //  验劵
+        setVerifica(){
+            this.$emit('setVerifica')
+        },
 
         changeBoard() {
             this.isBoard = !this.isBoard

+ 127 - 78
components/thorui/tui-picker/tui-picker.vue

@@ -1,7 +1,8 @@
 <template>
 	<view class="tui-picker__box">
-		<view class="tui-mask__screen" :class="[visible?'tui-picker__mask-show':'']" @tap="maskClick"></view>
-		<view class="tui-picker__wrap" :style="{backgroundColor:backgroundColor}"
+		<view class="tui-mask__screen" :style="{zIndex}" :class="[visible?'tui-picker__mask-show':'']" @tap="maskClick">
+		</view>
+		<view class="tui-picker__wrap" :style="{backgroundColor:backgroundColor,zIndex:getIndex}"
 			:class="[visible?'tui-picker__show':'',radius?'tui-picker__radius':'']">
 			<view class="tui-picker__header" :style="{backgroundColor:headerBgColor}">
 				<view class="tui-picker__btn-cancle" hover-class="tui-picker__opcity" :hover-stay-time="150"
@@ -11,24 +12,28 @@
 				<view class="tui-picker__title" :style="{fontSize:titleSize+'rpx',color:titleColor}">{{title}}</view>
 				<view class="tui-picker__btn-sure" hover-class="tui-picker__opcity" :hover-stay-time="150"
 					@tap.stop="picker"
-					:style="{color:confirmColor,fontSize:btnSize+'rpx',fontWeight:bold?'bold':'normal'}">{{confirmText}}
+					:style="{color:getConfirmColor,fontSize:btnSize+'rpx',fontWeight:bold?'bold':'normal'}">
+					{{confirmText}}
 				</view>
 			</view>
-			<picker-view :mask-style="maskStyle" :indicator-style="indicatorStyle" class="tui-picker__view"
-				:value="vals" @change="columnPicker" @pickstart="pickstart" @pickend="pickend">
-				<picker-view-column>
-					<view :style="{color:color,fontSize:size+'px'}" v-for="(item,index) in layer1__data" :key="index"
-						class="tui-picker__item">{{item}}</view>
-				</picker-view-column>
-				<picker-view-column v-if="layer==2 || layer==3">
-					<view :style="{color:color,fontSize:size+'px'}" v-for="(item,index) in layer2__data" :key="index"
-						class="tui-picker__item">{{item}}</view>
-				</picker-view-column>
-				<picker-view-column v-if="layer==3">
-					<view :style="{color:color,fontSize:size+'px'}" v-for="(item,index) in layer3__data" :key="index"
-						class="tui-picker__item">{{item}}</view>
-				</picker-view-column>
-			</picker-view>
+			<view @touchstart.stop="pickstart">
+				<picker-view :key="maskStyle+layer" :mask-style="maskStyle" :indicator-style="indicatorStyle"
+					class="tui-picker__view" :value="vals" :immediate-change="immediate" @change="columnPicker"
+					@pickend="pickend">
+					<picker-view-column>
+						<view :style="{color:color,fontSize:size+'px'}" v-for="(item,index) in layer1__data"
+							:key="index" class="tui-picker__item">{{item}}</view>
+					</picker-view-column>
+					<picker-view-column v-if="layer==2 || layer==3">
+						<view :style="{color:color,fontSize:size+'px'}" v-for="(item,index) in layer2__data"
+							:key="index" class="tui-picker__item">{{item}}</view>
+					</picker-view-column>
+					<picker-view-column v-if="layer==3">
+						<view :style="{color:color,fontSize:size+'px'}" v-for="(item,index) in layer3__data"
+							:key="index" class="tui-picker__item">{{item}}</view>
+					</picker-view-column>
+				</picker-view>
+			</view>
 		</view>
 	</view>
 </template>
@@ -50,6 +55,18 @@
 					return []
 				}
 			},
+			textField: {
+				type: String,
+				default: 'text'
+			},
+			valueField: {
+				type: String,
+				default: 'value'
+			},
+			childrenField: {
+				type: String,
+				default: 'children'
+			},
 			//是否显示
 			show: {
 				type: Boolean,
@@ -105,7 +122,7 @@
 			//确认按钮文本颜色
 			confirmColor: {
 				type: String,
-				default: '#5677fc'
+				default: ''
 			},
 			//取消按钮文本
 			cancelText: {
@@ -151,40 +168,71 @@
 			params: {
 				type: [Number, String],
 				default: 0
+			},
+			zIndex: {
+				type: [Number, String],
+				default: 998
+			}
+		},
+		computed: {
+			getConfirmColor() {
+				return this.confirmColor || (uni && uni.$tui && uni.$tui.color.primary) || '#5677fc'
+			},
+			getIndex() {
+				return Number(this.zIndex) + 2
 			}
 		},
 		data() {
+			let immediate = true;
+			// #ifdef MP-TOUTIAO
+			immediate = false
+			// #endif
 			return {
+				immediate,
 				visible: false,
-				vals: [0],
+				vals: [],
 				layer1__data: [],
 				layer2__data: [],
 				layer3__data: [],
 				isEnd: true,
-				timer: null
+				firstShow: false
 			};
 		},
 		created() {
 			this.initData(-1, 0, 0);
-			setTimeout(() => {
-				this.setDefaultOptions()
-			}, 50)
+			this.$nextTick(() => {
+				setTimeout(() => {
+					this.setDefaultOptions()
+				}, 50)
+			})
 			this.visible = this.show;
+			if (this.visible) {
+				this.firstShow = true
+			}
 		},
 		watch: {
 			show(val) {
 				this.visible = val;
+				if (val) {
+					setTimeout(() => {
+						this.firstShow = true
+					}, 260)
+				}
 			},
 			value(vals) {
 				if (vals && vals.length > 0) {
-					this.setDefaultOptions()
+					setTimeout(() => {
+						this.setDefaultOptions()
+					}, 20)
 				}
 			},
 			pickerData(newVal) {
 				this.initData(-1, 0, 0)
-				setTimeout(() => {
-					this.setDefaultOptions()
-				}, 50)
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.setDefaultOptions()
+					}, 50)
+				})
 			}
 		},
 		methods: {
@@ -202,61 +250,61 @@
 				let vals = this.vals;
 				let data = this.pickerData;
 				let result = ''
-				if (layer === 1) {
+				if (layer == 1) {
 					result = data[vals[0]][key]
 				} else if (layer == 2) {
-					if (data[vals[0]].children) {
-						result = data[vals[0]].children[vals[1]][key]
+					if (data[vals[0]][this.childrenField]) {
+						result = data[vals[0]][this.childrenField][vals[1]][key]
 					}
 				} else {
-					if (data[vals[0]].children && data[vals[0]].children[vals[1]].children) {
-						result = data[vals[0]].children[vals[1]].children[vals[2]][key]
+					if (data[vals[0]][this.childrenField] && data[vals[0]][this.childrenField][vals[1]][this
+						.childrenField]) {
+						result = data[vals[0]][this.childrenField][vals[1]][this.childrenField][vals[2]][key]
 					}
 				}
 				return result;
 			},
-			loop() {
+			loop(index = 0) {
 				if (this.isEnd) {
 					this.pickerChange()
 				} else {
+					index++
+					if (index >= 30) {
+						this.isEnd = true
+					}
 					setTimeout(() => {
-						this.loop()
+						this.loop(index)
 					}, 50)
 				}
 			},
 			picker() {
 				this.hidePicker()
-				// #ifdef MP-WEIXIN
 				this.loop()
-				// #endif
-				// #ifndef MP-WEIXIN
-				this.pickerChange()
-				// #endif
 			},
 			pickerChange() {
-				if(!this.show) return;
 				let text = [];
 				let value = [];
 				let result = '';
 				if (this.pickerData.length > 0) {
 					if (this.layer == 1) {
-						text = this.getValue();
-						value = this.getValue('value');
+						text = this.getValue(this.textField);
+						value = this.getValue(this.valueField);
 						result = text;
 					} else if (this.layer == 2) {
-						text = [this.getValue(), this.getValue('text', 2)];
-						value = [this.getValue('value'), this.getValue('value', 2)];
+						text = [this.getValue(this.textField), this.getValue(this.textField, 2)];
+						value = [this.getValue(this.valueField), this.getValue(this.valueField, 2)];
 						result = text.join('');
 					} else {
-						text = [this.getValue(), this.getValue('text', 2), this.getValue('text', 3)];
-						value = [this.getValue('value'), this.getValue('value', 2), this.getValue('value', 3)];
+						text = [this.getValue(this.textField), this.getValue(this.textField, 2), this.getValue(this.textField, 3)];
+						value = [this.getValue(this.valueField), this.getValue(this.valueField, 2), this.getValue(this
+							.valueField, 3)];
 						result = text.join('');
 					}
 				}
 
 				this.$emit('change', {
-					text: text,
-					value: value,
+					[this.textField]: text,
+					[this.valueField]: value,
 					index: this.vals,
 					result: result,
 					params: this.params
@@ -266,19 +314,19 @@
 				let arr = [];
 				if (data && data.length > 0) {
 					for (let item of data) {
-						arr.push(item.text);
+						arr.push(item[this.textField]);
 					}
 				}
 				return arr;
 			},
 			checkChildrenData(data, layer, index, idx) {
 				let arr = [];
-				if (layer === 1) {
+				if (layer == 1) {
 					if (data[index])
-						arr = data[index].children || [];
+						arr = data[index][this.childrenField] || [];
 				} else {
-					if (data[index] && data[index].children && data[index].children[idx])
-						arr = data[index].children[idx].children || [];
+					if (data[index] && data[index][this.childrenField] && data[index][this.childrenField][idx])
+						arr = data[index][this.childrenField][idx][this.childrenField] || [];
 				}
 				return arr;
 			},
@@ -288,13 +336,13 @@
 				if (this.layer1__data.length > 0 && textArr.length > 0) {
 					textArr.forEach((item, idx) => {
 						let index = this[`layer${idx+1}__data`].indexOf(item);
-						if (idx === 0) {
+						if (idx == 0) {
 							this.layer2__data = this.toArr(this.checkChildrenData(this.pickerData, 1, index))
-						} else if (idx === 1) {
+						} else if (idx == 1) {
 							this.layer3__data = this.toArr(this.checkChildrenData(this.pickerData, 2, vals[0],
 								index))
 						}
-						if (index === -1) {
+						if (index == -1) {
 							vals.push(0)
 						} else {
 							vals.push(index)
@@ -313,23 +361,33 @@
 							0))
 					}
 				}
-				this.vals = vals;
+				if (this.vals.join(',') == vals.join(',')) return;
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.vals = vals;
+					}, 200)
+				})
 			},
 			initData(layer, index, idx) {
 				let data = this.pickerData;
-				if (!data || data.length === 0) return;
+				if (!data || data.length == 0) {
+					this.layer1__data = [];
+					this.layer2__data = [];
+					this.layer3__data = [];
+					return;
+				}
 				if (this.layer == 1) {
 					this.layer1__data = this.toArr(data)
 				} else if (this.layer == 2) {
-					if (layer === -1)
+					if (layer == -1)
 						this.layer1__data = this.toArr(data)
 
 					this.layer2__data = this.toArr(this.checkChildrenData(data, 1, index))
 				} else {
-					if (layer === -1)
+					if (layer == -1)
 						this.layer1__data = this.toArr(data)
 
-					if (layer === 0 || layer === -1)
+					if (layer == 0 || layer == -1)
 						this.layer2__data = this.toArr(this.checkChildrenData(data, 1, index))
 
 					this.layer3__data = this.toArr(this.checkChildrenData(data, 2, index, idx))
@@ -337,6 +395,7 @@
 			},
 			columnPicker: function(e) {
 				let value = e.detail.value;
+				if (!this.firstShow || value.length != this.layer) return;
 				if (this.layer == 1) {
 					this.layer__one(value)
 				} else if (this.layer == 2) {
@@ -344,14 +403,15 @@
 				} else {
 					this.layer__three(value)
 				}
+				this.isEnd = true
 			},
 			layer__one(value) {
-				if (this.vals[0] !== value[0]) {
+				if (this.vals[0] != value[0]) {
 					this.vals = value;
 				}
 			},
 			layer__two(value) {
-				if (this.vals[0] !== value[0]) {
+				if (this.vals[0] != value[0]) {
 					this.initData(0, value[0])
 					this.vals = [value[0], 0]
 				} else {
@@ -359,10 +419,10 @@
 				}
 			},
 			layer__three(value) {
-				if (this.vals[0] !== value[0]) {
+				if (this.vals[0] != value[0]) {
 					this.initData(0, value[0], 0)
 					this.vals = [value[0], 0, 0]
-				} else if (this.vals[1] !== value[1]) {
+				} else if (this.vals[1] != value[1]) {
 					this.initData(0, value[0], value[1])
 					this.vals = [value[0], value[1], 0]
 				} else {
@@ -370,22 +430,13 @@
 				}
 			},
 			pickstart(e) {
-				// #ifdef MP-WEIXIN
-				clearTimeout(this.timer)
 				this.isEnd = false;
-				// #endif
-				//仅微信小程序支持
 				this.$emit('pickstart', {
 					params: this.params
 				})
 			},
 			pickend(e) {
 				//仅微信小程序支持
-				// #ifdef MP-WEIXIN
-				this.timer = setTimeout(() => {
-					this.isEnd = true;
-				}, 100)
-				// #endif
 				this.$emit('pickend', {
 					params: this.params
 				})
@@ -402,7 +453,6 @@
 		right: 0;
 		bottom: 0;
 		background: rgba(0, 0, 0, 0.6);
-		z-index: 1001;
 		transition: all 0.3s ease-in-out;
 		opacity: 0;
 		visibility: hidden;
@@ -419,7 +469,6 @@
 		left: 0;
 		right: 0;
 		bottom: 0;
-		z-index: 1002;
 		visibility: hidden;
 		transform: translate3d(0, 100%, 0);
 		transform-origin: center;
@@ -499,4 +548,4 @@
 	.tui-picker__opcity {
 		opacity: 0.5;
 	}
-</style>
+</style>

+ 75 - 1
config/modules/home.js

@@ -1,6 +1,80 @@
 import { request, request1 } from "@/utils/request.js";
 
+/* 首页---------------------------- */
 // 获取店铺详情
 export function getShopDetail(data) {
-  return request("/shop/getById",data,'POST');
+  return request("/shop/getById", data, "POST");
+}
+
+//   获取经营数据
+export function getBusinessData(data){
+  return request("/index/summarizeStatistics", data, "POST");
+}
+
+/* 输码验劵--------------- */
+export function getCoupons(data) {
+  return request("/order/inputWrite", data, "POST");
+}
+
+
+/* 收款账户---------------------- */
+
+// 获取收款账户列表
+
+export function getReceiving(data) {
+  return request("/bank/getById", data, "POST");
+}
+//  保存银行卡
+export function saveReceiving(data) {
+  return request("/bank/save", data, "POST");
+}
+
+//  修改收款账户列表
+export function updateReceiving(data) {
+  return request("/bank/update", data, "POST");
+}
+
+// 获取所有银行列表
+
+export function getSelect(data) {
+  return request("/dict/getSelect", data, "POST");
+}
+
+/* 经营数据------------------- */
+
+//  获取经营数据
+export function getOperateData(data) {
+  return request("/index/index", data, "POST");
+}
+
+//  获取客户列表
+export function getCustomerList(data) {
+  return request("/buyer/getAll", data, "POST");
+}
+
+/* 财务对账---------------------- */
+
+//  获取财务对账数据
+export function getFinancial(data) {
+  return request("/finance/getFinanceCount", data, "POST");
+}
+
+// 查看当天财务详情
+export function getDayDetail(data) {
+  return request("/finance/getDetails", data, "POST");
+}
+
+// 获取提现记录
+export function getWithdrawal(data) {
+  return request("/finance/getWithdrawalDetails", data, "POST");
+}
+
+//  获取银行卡信息
+export function financeBank(data) {
+  return request("/finance/getBank", data, "POST");
+}
+
+//  申请提现
+export function applyWithdrawal(data) {
+  return request("/finance/withdrawal", data, "POST");
 }

+ 15 - 0
config/modules/user.js

@@ -13,4 +13,19 @@ export function getFinanceCount(data) {
   //  获取店铺收款码
   export function getShopQrcode(data) {
     return request(`/paymentCode/generateCode`, data, "POST");
+  }
+
+  // 修改密码
+  export function updatePassword(data) {
+    return request(`/business/updatePassword`, data, "POST");
+  }
+
+  // 获取我的账户信息
+  export function getMyAccount(data){
+    return request(`/index/shopAccount`, data, "POST");
+  }
+
+  // 获取会员列表 
+  export function getBuyerList(data){
+    return request(`/index/buyerList`, data, "POST");
   }

+ 171 - 0
order_module/orderDetail/index.scss

@@ -0,0 +1,171 @@
+%state {
+  width: 100%;
+  height: 80rpx;
+  font-size: 24rpx;
+  @include flex(flex-start, null, 9rpx);
+  padding-left: 32rpx;
+  box-sizing: border-box;
+  image {
+    width: 30rpx;
+    height: 30rpx;
+  }
+}
+
+%info {
+  width: 100%;
+  padding: 32rpx;
+  box-sizing: border-box;
+  .info-title {
+    font-size: 32rpx;
+    color: rgba(0, 0, 0, 0.9);
+    font-weight: 700;
+    margin-bottom: 16rpx;
+  }
+  .info-detail {
+    width: 100%;
+    padding: 32rpx;
+    box-sizing: border-box;
+    border-radius: 16rpx;
+    background-color: #ffffff;
+    @include flex(center, column, 16rpx);
+    .info-box {
+      width: 100%;
+      @include flex(flex-start, null, 32rpx);
+      text {
+        font-size: 28rpx;
+        &:nth-of-type(1) {
+          width: 176rpx;
+          text-align: start;
+          color: rgba(0, 0, 0, 0.4);
+        }
+        &:nth-of-type(2) {
+          color: #000000;
+        }
+      }
+    }
+  }
+}
+.order-detail {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  .detail-state {
+    .state-error {
+      @extend %state;
+      background-color: #ffd2d2;
+      color: #d40f0f;
+    }
+    .state-success {
+      @extend %state;
+      background-color: #c2efce;
+      color: #0e852e;
+    }
+    .state-complete {
+      @extend %state;
+      background-color: #e0e0e0;
+      color: rgba(0, 0, 0, 0.6);
+    }
+  }
+  .product-detail {
+    width: 100%;
+    padding: 32rpx;
+    box-sizing: border-box;
+    background-color: #ffffff;
+    .product-list {
+      .product-item {
+        @include flex(space-between, null, 32rpx);
+        .item-left {
+          width: 160rpx;
+          height: 160rpx;
+          border-radius: 8rpx;
+          border: 2rpx solid #e7e7e7;
+          image {
+            width: 160rpx;
+            height: 160rpx;
+            border-radius: 8rpx;
+          }
+        }
+        .item-right {
+          flex: 1;
+          height: 160rpx;
+          @include flex(space-between, column);
+          .right-title {
+            width: 100%;
+            height: 80rpx;
+            font-size: 28rpx;
+            color: #000000;
+            font-weight: 600;
+            //  多行文本溢出
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 2; /* 控制显示的行数 */
+            overflow: hidden;
+            text-overflow: ellipsis;
+          }
+          .right-bottom {
+            width: 100%;
+            @include flex(space-between);
+            color: #3d3d3d;
+            font-size: 28rpx;
+            .number {
+              width: 130rpx;
+              height: 48rpx;
+              line-height: 48rpx;
+              text-align: center;
+              border-radius: 4rpx;
+              background-color: #f4f4f4;
+            }
+          }
+        }
+      }
+    }
+    .load-more{
+        margin-top: 34rpx;
+        width: 100%;
+        height: 40rpx;
+        @include flex(center,null,8rpx);
+        text{
+            color: #EF530E;
+            font-size: 24rpx;
+        }
+    }
+  }
+  .order-info {
+    @extend %info;
+  }
+  .pay-info {
+    @extend %info;
+    .info-detail {
+      .price {
+        text {
+          &:nth-of-type(2) {
+            color: $primary-color;
+            font-weight: 600;
+          }
+        }
+      }
+    }
+  }
+  .write-off {
+    width: 100%;
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    padding: 16rpx 32rpx;
+    box-sizing: border-box;
+    background-color: #FFFFFF;
+    padding-bottom: calc(constant(safe-area-inset-bottom) + 12rpx); //兼容 IOS<11.2
+    padding-bottom: calc(env(safe-area-inset-bottom) + 12rpx); //兼容 IOS>11.2
+    .off-btn{
+        width: 100%;
+        background-color: $primary-color;
+        font-size: 28rpx;
+        height: 80rpx;
+        text-align: center;
+        line-height: 80rpx;
+        color: #FFFFFF;
+        font-weight: 600;
+        border-radius: 16rpx;
+    }
+  }
+}

+ 191 - 0
order_module/orderDetail/index.vue

@@ -0,0 +1,191 @@
+<template>
+  <view class="order-detail">
+    <view class="detail-state">
+      <template
+        v-if="
+          orderInfo.state == 8 ||
+            orderInfo.state == 9 ||
+            orderInfo.state == 2 ||
+            orderInfo.state == 3
+        "
+      >
+        <view class="state-error">
+          <image class="" src="@/static/image/order/error_icon.png" />
+          <text v-if="orderInfo.state == 8">当前订单待核销(未付款)</text>
+          <text v-if="orderInfo.state == 9">当前订单待核销(已付款)</text>
+          <text v-if="orderInfo.state == 2">待发货</text>
+          <text v-if="orderInfo.state == 3">待收货</text>
+        </view></template
+      >
+
+      <template v-else-if="orderInfo.state == 10 || orderInfo.state == 4">
+        <view class="state-success">
+          <image class="" src="@/static/image/order/success_icon.png" />
+          <text v-if="orderInfo.state == 10">当前订单已核销</text>
+          <text v-if="orderInfo.state == 4">当前订单已完成</text>
+        </view>
+      </template>
+      <template v-else-if="orderInfo.state == 5">
+        <view class="state-complete">
+          <image class="" src="@/static/image/order/complete_icon.png" />
+          <text>当前订单交易关闭(已取消)</text>
+        </view>
+      </template>
+    </view>
+
+    <view class="product-detail">
+      <view class="product-list">
+        <view
+          class="product-item"
+          v-for="item in renderData"
+          :key="item.productId"
+        >
+          <view class="item-left">
+            <image class="" :src="item.image" />
+          </view>
+          <view class="item-right">
+            <view class="right-title">{{ item.productName }}</view>
+            <view class="right-bottom">
+              <view class="number">数量&nbsp;&nbsp;*{{ item.number }}</view>
+              <view class="onePrice">¥{{ item.productPrice }}/1个</view>
+            </view>
+          </view>
+        </view>
+      </view>
+      <view class="load-more" v-if="productData.length > 2">
+        <template v-if="!isShow">
+          <view @click="expand">
+            <tui-icon name="down" :size="16" color="#EF530E"></tui-icon>
+            <text
+              >展开剩余&nbsp;{{
+                productData.length - renderData.length
+              }}&nbsp;件商品</text
+            >
+          </view>
+        </template>
+        <template v-else>
+          <view @click="expand">
+            <tui-icon name="up" :size="16" color="#EF530E"></tui-icon>
+            <text>收起</text>
+          </view>
+        </template>
+      </view>
+    </view>
+    <view class="order-info">
+      <view class="info-title">订单信息</view>
+      <view class="info-detail">
+        <view class="info-box">
+          <text>订单编号</text>
+          <text>{{ orderInfo.orderFormid }}</text>
+        </view>
+        <view class="info-box">
+          <text>创建时间</text>
+          <text>{{ orderInfo.createTime }}</text>
+        </view>
+        <view class="info-box">
+          <text>订单类型</text>
+          <text v-if="orderInfo.scanType == 1">常规订单</text>
+          <text v-if="orderInfo.scanType == 2">收款码订单</text>
+        </view>
+        <view class="info-box">
+          <text>下单账户</text>
+          <text>{{ orderInfo.customerName }}</text>
+        </view>
+        <view class="info-box">
+          <text>下单号码</text>
+          <text>{{ orderInfo.buyerPhone }}</text>
+        </view>
+      </view>
+    </view>
+    <view class="pay-info">
+      <view class="info-title">支付信息</view>
+      <view class="info-detail">
+        <view class="info-box">
+          <text>支付方式</text>
+          <text v-if="orderInfo.paymentMode == 1">微信</text>
+          <text v-else-if="orderInfo.paymentMode == 2">支付宝</text>
+          <text v-else-if="orderInfo.paymentMode == 3">花呗分期</text>
+          <text v-else-if="orderInfo.paymentMode == 4">通联支付</text>
+          <text v-else-if="orderInfo.paymentMode == 5">平台余额支付</text>
+          <text v-else-if="orderInfo.paymentMode == 6">商家余额支付</text>
+          <text v-else-if="orderInfo.paymentMode == 7">佣金支付</text>
+          <text v-else-if="orderInfo.paymentMode == 8">消费金支付</text>
+          <text v-else-if="orderInfo.paymentMode == 9">惠市宝支付</text>
+          <text v-else>--</text>
+        </view>
+        <view class="info-box">
+          <text>支付时间</text>
+          <text>{{ orderInfo.paymentTime || "--" }}</text>
+        </view>
+        <view class="info-box price">
+          <text>支付金额</text>
+          <text>{{ orderInfo.price }}元</text>
+        </view>
+        <view class="info-box price">
+          <text>赠送代金券</text>
+          <text>{{ orderInfo.presenterVoucher }}</text>
+        </view>
+      </view>
+    </view>
+    <view class="write-off" v-if="orderInfo.state == 8 || orderInfo.state == 9">
+      <view class="off-btn" @click="navigateTo('/pages_module/scanCode/index')"
+        >去核销</view
+      >
+      <view class="seat"></view>
+    </view>
+  </view>
+</template>
+
+<script>
+import { orderGetById } from "@/config/index.js";
+export default {
+  onLoad(option) {
+    this.orderId = option.orderId;
+    console.log(this.orderId, option);
+    this.orderGetDetail();
+  },
+  data() {
+    return {
+      orderId: "",
+      orderInfo: {},
+      //  实际渲染的数据
+      renderData: [],
+      //  总商品数据
+      productData: [],
+      //  控制收起以及展开
+      isShow: false,
+    };
+  },
+  methods: {
+    //  请求订单详情
+    async orderGetDetail() {
+      try {
+        let res = await orderGetById({ orderId: this.orderId });
+        this.orderInfo = res.data;
+        this.productData = res.data.products;
+        //  判断上坡是否超过两行
+        if (res.data.products.length > 2) {
+          this.renderData = res.data.products.slice(0, 2);
+        } else {
+          this.renderData = res.data.products;
+        }
+      } catch (error) {
+        console.log(error);
+      }
+    },
+    //  展开商品 expand
+    expand() {
+      this.isShow = !this.isShow;
+      if (this.isShow) {
+        this.renderData = this.productData;
+      } else {
+        this.renderData = this.productData.slice(0, 2);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 199 - 0
order_module/searchOrder/index.scss

@@ -0,0 +1,199 @@
+.searchOrder {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  .serch-box {
+    width: 100%;
+    height: 84rpx;
+    background-color: #ffffff;
+    padding: 8rpx 32rpx;
+    box-sizing: border-box;
+    .search-container {
+      width: 100%;
+      height: 100%;
+      background-color: #f4f4f4;
+      border-radius: 50rpx;
+      padding: 0 32rpx;
+      box-sizing: border-box;
+      @include flex(flex-start, null, null);
+      .box-left {
+        width: 260rpx;
+        height: 100%;
+        @include flex(flex-start, null, null);
+        .picker{
+            font-size: 48rpx;
+            color: #000;
+        }
+        .search-text {
+          flex: 1;
+          padding-right: 19rpx;
+          position: relative;
+          @include flex(flex-start,null,8rpx);
+          .text {
+            width: 140rpx;
+            color: #a3a3a3;
+            font-size: 27rpx;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            margin-right: 8rpx;
+          }
+          &::after {
+            content: "";
+            position: absolute;
+            top: 50%;
+            transform: translateY(-50%);
+            right: 0;
+            width: 2rpx;
+            height: 80%;
+            background-color: #d8d8d8;
+          }
+        }
+        .search-icon {
+          width: 56rpx;
+          height: 100%;
+          padding-left: 16rpx;
+          @include flex(center,null,0);
+        }
+      }
+      .box-ipt {
+        flex: 1;
+        font-size: 24rpx;
+        input{
+            caret-color: #ea5c1e;
+        }
+      }
+      .box-delete{
+        width: 40rpx;
+        height: 100%;
+        @include flex(center,null,0);
+      }
+    }
+  }
+  .order-container {
+    padding: 0 32rpx 32rpx;
+
+    .order-list {
+      .order-item {
+        width: auto;
+        margin-top: 32rpx;
+        padding: 32rpx;
+        box-sizing: border-box;
+        background-color: #ffffff;
+        border-radius: 16rpx;
+        display: flex;
+        justify-content: center;
+        gap: 24rpx;
+        flex-direction: column;
+        .order-number {
+          width: 100%;
+          @include flex(space-between);
+
+          .number {
+            font-size: 32rpx;
+            font-weight: 700;
+          }
+
+          .number-icon {
+            color: #999999;
+            @include flex(center);
+            font-size: 28rpx;
+            text {
+              padding-bottom: 2rpx;
+            }
+          }
+        }
+        .text-info {
+          font-size: 28rpx;
+          color: #999999;
+        }
+        .commodity-list {
+          width: 100%;
+          display: flex;
+          justify-content: center;
+          gap: 12rpx;
+          flex-direction: column;
+          .commodity-item {
+            display: flex;
+            justify-content: space-between;
+            .item-left {
+              display: flex;
+              gap: 12rpx;
+              .left-image {
+                width: 124rpx;
+                height: 124rpx;
+                image {
+                  width: 100%;
+                  height: 100%;
+                  border-radius: 12rpx;
+                }
+              }
+              .left-text {
+                flex: 1;
+                display: flex;
+                flex-direction: column;
+                gap: 6rpx;
+                .text-title {
+                  color: #333333;
+                  font-size: 28rpx;
+                }
+                .text-price {
+                  font-size: 24rpx;
+                  color: #999999;
+                }
+              }
+            }
+            .item-right {
+              color: #333333;
+              font-size: 28rpx;
+            }
+          }
+        }
+        .gifts {
+          @include flex(space-between);
+          font-size: 28rpx;
+          color: #333333;
+          .gifs-right {
+            color: #ea1717;
+          }
+        }
+        .all-price {
+          color: #333333;
+          font-size: 28rpx;
+        }
+        .border-box {
+          width: 100%;
+          height: 2rpx;
+          background-color: #d8d8d8;
+        }
+        .order-state {
+          text-align: end;
+          color: #999999;
+          font-size: 28rpx;
+          margin-top: 3rpx;
+        }
+      }
+    }
+  }
+  .empty{
+    width: 100%;
+    height: 100%;
+    margin-top: 200rpx;
+    position: relative;
+  }
+  .order-empty{
+    position: absolute;
+    top: 0;
+    left: 50%;
+    transform: translateX(-50%);
+    @include flex(center,column,32rpx);
+    font-size: 28rpx;
+    image{
+      width: 320rpx;
+      height: 320rpx;
+    }
+    .empty-title{
+      color: rgba(0, 0, 0, 0.4);
+    }
+  }
+}

+ 205 - 0
order_module/searchOrder/index.vue

@@ -0,0 +1,205 @@
+<template>
+  <view class="searchOrder">
+    <view class="serch-box">
+      <view class="search-container">
+        <view class="box-left">
+          <view class="search-text" @click="changePicker">
+            <view class="text">{{ searchText }}</view>
+            <tui-icon name="arrowdown" color="#999999" :size="15"></tui-icon>
+          </view>
+          <view class="search-icon">
+            <tui-icon name="search-2" color="#999999" :size="15"></tui-icon>
+          </view>
+        </view>
+        <view class="box-ipt">
+          <input
+            type="text"
+            v-model="queryData.search"
+            confirm-type="search"
+            placeholder="请搜索订单"
+            @confirm="searchConfirm"
+          />
+        </view>
+        <view class="box-delete" @click="deleteSearch">
+          <tui-icon name="close-fill" color="#999999" :size="15"></tui-icon>
+        </view>
+      </view>
+    </view>
+    <!-- v-if="orderList.length > 0" -->
+    <view class="order-container" v-if="orderList.length > 0">
+      <view class="order-list">
+        <view
+          class="order-item"
+          v-for="item in orderList"
+          :key="item.orderId"
+          @click="goOrderDetail(item)"
+        >
+          <view class="order-number">
+            <view class="number">订单编号:{{ item.orderFormid }}</view>
+            <view class="number-icon">
+              <text>详情</text>
+              <tui-icon
+                name="arrowright"
+                :size="20"
+                color="#999999"
+                style="padding: 0;"
+              ></tui-icon>
+            </view>
+          </view>
+          <view class="text-info">用户昵称:{{ item.customerName }}</view>
+          <view class="text-info">用户手机号:{{ item.customerPhone }}</view>
+          <view class="commodity-list">
+            <view
+              class="commodity-item"
+              v-for="item2 in item.products"
+              :key="item2.orderProductId"
+            >
+              <view class="item-left">
+                <view class="left-image">
+                  <image :src="item2.image" />
+                </view>
+                <view class="left-text">
+                  <view class="text-title">{{ item2.productName }}</view>
+                  <template v-if="item2.productName == '扫码付款商品'">
+                    <view class="text-price">扫码付款商品</view>
+                  </template>
+                  <template v-else>
+                    <view class="text-price">小份</view>
+                    <view class="text-price">x1</view>
+                  </template>
+                </view>
+              </view>
+              <view class="item-right">¥{{ item2.productPrice }}</view>
+            </view>
+          </view>
+          <view class="gifts">
+            <view class="gifs-left">赠送代金券</view>
+            <view class="gifs-right">¥{{ item.presenterVoucher }}</view>
+          </view>
+          <view class="all-price">总价¥{{ item.price }}</view>
+          <view class="border-box"></view>
+          <view class="order-state">
+            <text v-if="item.state == 1">待付款</text>
+            <text v-if="item.state == 2">待发货</text>
+            <text v-if="item.state == 3">待收货</text>
+            <text v-if="item.state == 4">已完成</text>
+            <text v-if="item.state == 5">交易关闭(已取消)</text>
+            <text v-if="item.state == 6">待成团</text>
+            <text v-if="item.state == 7">待售后</text>
+            <text v-if="item.state == 8" :style="{ color: '#EA1717' }"
+              >待核销(未付款)</text
+            >
+            <text v-if="item.state == 9">待核销(已付款)</text>
+            <text v-if="item.state == 10">已核销</text>
+          </view>
+        </view>
+      </view>
+    </view>
+    <!-- v-else -->
+    <view class="empty" v-else>
+      <view class="order-empty">
+        <image src="@/static/image/order/search-empty.png" />
+        <view class="empty-title">您还没有相关订单</view>
+      </view>
+    </view>
+
+    <tui-picker
+      :show="showPicker"
+      :pickerData="array"
+      title="请选择"
+      confirmColor="#ea5c1e"
+      @hide="hide"
+      @change="pickerChange"
+    >
+    </tui-picker>
+  </view>
+</template>
+
+<script>
+import { orderGetAll } from "@/config/index";
+export default {
+  data() {
+    return {
+      array: [
+        {
+          text: "订单Id",
+          value: "1",
+        },
+        {
+          text: "买家账户",
+          value: "2",
+        },
+        {
+          text: "收件人姓名",
+          value: "3",
+        },
+        {
+          text: "收件人电话号码",
+          value: "4",
+        },
+        {
+          text: "下单号码",
+          value: "6",
+        },
+      ],
+      showPicker: false,
+      searchText: "订单Id",
+      queryData: {
+        afterState: "",
+        dates: [],
+        page: 1,
+        pageSize: 10,
+        search: "",
+        searchType: "1",
+        state: "",
+      },
+      orderList: [],
+      total: 0,
+    };
+  },
+  methods: {
+    async searchConfirm(e) {
+      if (this.queryData.search == "") {
+        this.$showToast("请输入你要搜索的内容");
+        return;
+      }
+      let res = await orderGetAll(this.queryData);
+      this.orderList = [...this.orderList, ...res.data.list];
+      this.total = res.data.total;
+    },
+    pickerChange(val) {
+      this.searchText = val.text;
+      this.queryData.searchType = val.value;
+    },
+    // 清除查询参数
+    deleteSearch() {
+      this.queryData.search = "";
+    },
+    // 去到订单详情
+    goOrderDetail(item) {
+      this.navigateTo(
+        `/order_module/orderDetail/index?orderId=${item.orderId}`
+      );
+    },
+    hide(e) {
+      this.showPicker = false;
+    },
+    changePicker() {
+      this.showPicker = true;
+    },
+  },
+  //  触底加载
+  onReachBottom() {
+    if (this.orderList.length >= this.total) {
+      this.$showToast("暂无更多订单数据");
+      return
+    };
+    this.queryData.page++;
+    this.searchConfirm();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 94 - 1
pages.json

@@ -66,7 +66,50 @@
 						"enablePullDownRefresh": true,
 						"navigationStyle":"custom"
 					}
-				}
+				},
+        {
+					"path": "receiving/index",
+					"style": {
+						"navigationBarTitleText": "收款账户",
+						"enablePullDownRefresh": false
+					}
+				},
+        {
+					"path": "bindingCard/index",
+					"style": {
+						"navigationBarTitleText": "绑定银行卡",
+						"enablePullDownRefresh": false,
+						"navigationStyle":"custom"
+					}
+				},
+        {
+					"path": "operateData/index",
+					"style": {
+						"navigationBarTitleText": "经营数据",
+						"enablePullDownRefresh": false
+					}
+				},
+        {
+					"path": "financial/index",
+					"style": {
+						"navigationBarTitleText": "财务对账",
+						"enablePullDownRefresh": false
+					}
+				},
+        {
+          "path": "withdrawal/index",
+					"style": {
+						"navigationBarTitleText": "提现申请",
+						"enablePullDownRefresh": false
+					}
+        },
+        {
+          "path": "walSuccess/index",
+					"style": {
+						"navigationBarTitleText": "申请成功",
+						"enablePullDownRefresh": false
+					}
+        }
       ]
     },
     {
@@ -107,6 +150,56 @@
 						"navigationBarTitleText": "商家码详情",
             "navigationStyle": "custom"
 					}
+				},
+        {
+					"path": "changePassword/index",
+					"style": {
+						"navigationBarTitleText": "修改密码"
+					}
+				},
+        {
+					"path": "changeSuccess/index",
+					"style": {
+						"navigationBarTitleText": "修改成功"
+					}
+				},
+        {
+					"path": "myAccount/index",
+					"style": {
+						"navigationBarTitleText": "我的账户",
+            "navigationStyle":"custom"
+					}
+				},
+        {
+          "path": "memberManage/index",
+					"style": {
+						"navigationBarTitleText": "会员管理"
+					}
+        },
+        {
+					"path": "webview/index",
+					"style": {
+						"navigationBarTitleText": "官方客服",
+						"enablePullDownRefresh": false
+					}
+				}
+      ]
+    },
+    {
+      "root": "order_module",
+			"name":"order_module",
+      "pages":[
+        {
+					"path": "orderDetail/index",
+					"style": {
+						"navigationBarTitleText": "订单详情"
+					}
+				},
+        {
+					"path": "searchOrder/index",
+					"style": {
+						"navigationBarTitleText": "订单搜索"
+					}
 				}
       ]
     }

+ 1 - 1
pages/login/index.vue

@@ -56,7 +56,7 @@
             </view>
             <view class="btn-list">
                 <view class="login-btn" @click="landing">登陆</view>
-                <view class="register-btn">注册开店</view>
+                <!-- <view class="register-btn">注册开店</view> -->
             </view>
         </view>
         <modal :showModal="modal" :promptList="promptList" @closeModal="closeModal" :showBtn="showBtn"></modal>

+ 30 - 26
pages/tabbar/index/data.js

@@ -28,60 +28,64 @@ export const tobeList = [
     {
         title:'经营数据',
         img: require('@/static/image/home/tobe_1.png'),
+        url:"/pages_module/operateData/index"
     },
-    {
-        title:'商品管理',
-        img: require('@/static/image/home/tobe_2.png'),
-    },
+    // {
+    //     title:'商品管理',
+    //     img: require('@/static/image/home/tobe_2.png'),
+    // },
     {
         title:'订单管理',
         img: require('@/static/image/home/tobe_3.png'),
+        url:"/pages/tabbar/order/index"
     },
     {
         title:'财务对账',
         img: require('@/static/image/home/tobe_4.png'),
+        url:"/pages_module/financial/index"
     },
     {
         title:'收款账户',
         img: require('@/static/image/home/tobe_5.png'),
-    },
-    {
-        title:'活动中心',
-        img: require('@/static/image/home/tobe_6.png'),
-    },
-    {
-        title:'会员管理',
-        img: require('@/static/image/home/tobe_7.png'),
-    },
-    {
-        title:'更多',
-        img: require('@/static/image/home/tobe_8.png'),
-    },
+        url:"/pages_module/receiving/index"
+    },
+    // {
+    //     title:'活动中心',
+    //     img: require('@/static/image/home/tobe_6.png'),
+    // },
+    // {
+    //     title:'会员管理',
+    //     img: require('@/static/image/home/tobe_7.png'),
+    // },
+    // {
+    //     title:'更多',
+    //     img: require('@/static/image/home/tobe_8.png'),
+    // },
 ]
 
 export const statisticsList =  [
     {
         title: "今日成交金额",
-        price: "16500元",
-        proportion: "16",
+        price: "todayAmount",
+        proportion: "",
         state: 0
     },
     {
         title: "今日成交订单量",
-        price: "60单",
-        proportion: "20",
+        price: "todayOrder",
+        proportion: "",
         state: 0
     },
     {
         title: "今日核销金额",
-        price: "14200元",
-        proportion: "16",
+        price: "todayWriteAmount",
+        proportion: "",
         state: 1
     },
     {
-        title: "今日成交订单量",
-        price: "0",
-        proportion: "16",
+        title: "今日核销订单",
+        price: "todayWriteOrder",
+        proportion: "",
         state: 2
     },
 ]

+ 12 - 5
pages/tabbar/index/index.scss

@@ -10,13 +10,15 @@
     top: 0;
     left: 0;
     width: 100vw;
-    height: 654rpx;
+    // height: 654rpx;
     z-index: 1;
     background: linear-gradient(
       136deg,
       rgba(239, 83, 14, 0.63) 13%,
       rgba(239, 83, 14, 0.27) 54%
     );
+    // background: url('https://jufeng-shop-1317254189.cos.ap-guangzhou.myqcloud.com/1720408189735-bg_index.png') no-repeat center center;
+    background-size: 100% 100%;
   }
 
   .header-top {
@@ -53,10 +55,10 @@
     box-sizing: border-box;
     width: 100%;
     height: 479rpx;
+    @include flex(center, column,30rpx);
     background: rgba(255, 255, 255, 0.8);
     .main-tool {
       width: 100%;
-      margin-top: 28rpx;
       .tool-list {
         @include flex(center);
         .tool-item {
@@ -79,6 +81,10 @@
           }
         }
       }
+      
+    }
+    .main-container{
+      width: 100%;
       .tube-list{
         @include flex(center);
         flex-wrap: wrap;
@@ -193,10 +199,11 @@
       }
 
       .proportion {
+        
         @include flex(flex-end);
         margin: 20rpx 0 12rpx;
-
-        .proportion-box {
+        display: none;
+        .proportion-box { 
           @include flex(center, null, 5rpx);
 
           text {
@@ -214,7 +221,7 @@
       .chart-img {
         width: 100%;
         height: 80rpx;
-
+        margin-top: 30rpx;
         image {
           width: 100%;
           height: 100%;

+ 186 - 118
pages/tabbar/index/index.vue

@@ -1,34 +1,52 @@
 <template>
-	<view class="home">
-		<capsule @getHeight="getCapusleHeight"></capsule>
-		<view class="bg-box"></view>
-		<view class="header-top" :style="{ height: menuButtonHeight + 'px' }">
-			<view class="shop-title">{{ shopInfo.shopName }}</view>
-			<view class="shop-state">
-				<tui-icon style="height: 36rpx;" name="circle-fill" color="rgb(70,208,88)" :size="20"></tui-icon>
-				<text>营业中</text>
-			</view>
-		</view>
-		<view class="main" :style="{ height: mainHeight + 'px' }">
-			<view class="main-tool">
-				<view class="tool-list">
-					<view class="tool-item" v-for="item in toolList" :key="item.title" @click="scanCode(item.url)">
-						<view class="item-img" :style="{ background: item.background }">
-							<image class="" :src="item.img" />
-						</view>
-						<view class="item-text">{{ item.title }}</view>
-					</view>
-				</view>
-				<view class="tube-list">
-					<view class="tube-item" v-for="item in tobeList" :key="item.title">
-						<image :src="item.img" />
-						<text>{{ item.title }}</text>
-					</view>
-				</view>
-			</view>
-			<view class="main-container"></view>
-		</view>
-		<!-- <view class="header-content"></view>
+  <view class="home">
+    <view class="bg-box" :style="{height:bgHeight + 'px'}"></view>
+    <view id="computed-box">
+      <capsule @getHeight="getCapusleHeight"></capsule>
+      <view class="header-top" :style="{ height: menuButtonHeight + 'px' }">
+        <view class="shop-title">{{ shopInfo.shopName }}</view>
+        <view class="shop-state">
+          <tui-icon
+            style="margin-top: 4rpx;"
+            name="circle-fill"
+            :color="shopInfo.trade?'rgb(70,208,88)':'rgba(239, 83, 14, 0.63)'"
+            :size="20"
+          ></tui-icon>
+          <text>{{ shopInfo.trade || '营业中' }}</text>
+        </view>
+      </view>
+      <view class="main" >
+        <view class="main-tool">
+          <view class="tool-list">
+            <view
+              class="tool-item"
+              v-for="item in toolList"
+              :key="item.title"
+              @click="scanCode(item.url)"
+            >
+              <view class="item-img" :style="{ background: item.background }">
+                <image class="" :src="item.img" />
+              </view>
+              <view class="item-text">{{ item.title }}</view>
+            </view>
+          </view>
+        </view>
+        <view class="main-container">
+          <view class="tube-list">
+            <view
+              class="tube-item"
+              v-for="item in tobeList"
+              :key="item.title"
+              @click="tobeNavigate(item)"
+            >
+              <image :src="item.img" />
+              <text>{{ item.title }}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+    <!-- <view class="header-content"></view>
 		<view class="main-tool">
 			<view class="tool-list">
 				<view class="tool-item" v-for="item in toolList" :key="item.title" @click="scanCode(item.url)">
@@ -37,100 +55,150 @@
 				</view>
 			</view>
 		</view> -->
-		<view class="summarize-box">
-			<view class="summarize-left">经营概括</view>
-			<view class="summarize-right">
-				<text>更多</text>
-				<tui-icon name="arrowright" :size="24"></tui-icon>
-			</view>
-		</view>
-		<view class="statistics-list">
-			<view class="statistics-item" v-for="(item, index) in statisticsList" :key="index">
-				<view class="statistics-trans">{{ item.title }}</view>
-				<view class="statistics-price">
-					<view class="price">{{ item.price }}</view>
-					<view class="text">较昨日</view>
-				</view>
-				<view class="proportion" v-if="item.state !== 2">
-					<view class="proportion-box">
-						<text :style="{ color: item.state == 0 ? '#42D373' : '#EF530E' }">{{ item.proportion }}%</text>
-						<image
-							:src="item.state == 0 ? require('@/static/image/home/decline-icon.png') : require('@/static/image/home/rise-icon.png')"
-							alt="" />
-						<!-- <image src="@/static/image/home/decline-icon.png" alt="" /> -->
-					</view>
-				</view>
-				<view class="chart-img" v-if="item.state !== 2">
-					<template v-if="item.state == 0">
-						<image
-							:src="item.proportion <= 16 ? require('@/static/image/home/green.png') : require('@/static/image/home/green-more.png')"
-							alt="" />
-					</template>
-					<template v-if="item.state == 1">
-						<image src="@/static/image/home/red.png" alt="" />
-					</template>
-				</view>
-				<view class="empty" v-if="item.state == 2">
-					<view class="left"></view>
-					<view class="bottom"></view>
-				</view>
-			</view>
-		</view>
-	</view>
+    <view class="summarize-box">
+      <view class="summarize-left">经营概括</view>
+      <view class="summarize-right" @click="navigateTo('/pages_module/operateData/index')">
+        <text>更多</text>
+        <tui-icon name="arrowright" :size="24"></tui-icon>
+      </view>
+    </view>
+    <view class="statistics-list">
+      <view
+        class="statistics-item"
+        v-for="(item, index) in statisticsList"
+        :key="index"
+      >
+        <view class="statistics-trans">{{ item.title }}</view>
+        <view class="statistics-price">
+          <view class="price">{{ todayData[item.price] >= 0 && !Object.is(todayData[item.price], null) ? todayData[item.price] : '--' }}</view>
+          <!-- <view class="text">较昨日</view> -->
+        </view>
+        <view class="proportion" v-if="item.state !== 2">
+          <view class="proportion-box">
+            <text :style="{ color: item.state == 0 ? '#42D373' : '#EF530E' }"
+              >{{ item.proportion }}%</text
+            >
+            <image
+              :src="
+                item.state == 0
+                  ? require('@/static/image/home/decline-icon.png')
+                  : require('@/static/image/home/rise-icon.png')
+              "
+              alt=""
+            />
+          </view>
+        </view>
+        <view class="chart-img" v-if="todayData[item.price]">
+          <template v-if="item.state == 0">
+            <image
+              :src="
+                item.proportion <= 16
+                  ? require('@/static/image/home/green.png')
+                  : require('@/static/image/home/green-more.png')
+              "
+              alt=""
+            />
+          </template>
+          <template v-if="item.state == 1">
+            <image src="@/static/image/home/red.png" alt="" />
+          </template>
+        </view>
+        <view class="empty" v-else>
+          <view class="left"></view>
+          <view class="bottom"></view>
+        </view>
+      </view>
+    </view>
+  </view>
 </template>
 
 <script>
-import { getShopDetail } from '@/config/index.js'
-import { toolList, tobeList, statisticsList } from './data'
+import { getShopDetail,getBusinessData } from "@/config/index.js";
+import { toolList, tobeList, statisticsList } from "./data";
 export default {
-	created() {
-		//  获取胶囊的高度
-		// #ifdef MP-WEIXIN
-		let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
-		this.menuButtonHeight = menuButtonInfo.height
-		// #endif
-
-		//  请求获取店铺的信息
-		this.getShop()
-	},
-	data() {
-		return {
-			//  胶囊的高度
-			menuButtonHeight: null,
-			toolList: toolList,
-			tobeList: tobeList,
-			statisticsList: statisticsList,
-			// 店铺信息
-			shopInfo: {},
-			//  动态计算 main 的高度
-			mainHeight: 0
-		}
-	},
-	onLoad() {
+  mounted() {
+    //.box获取class为box的元素,如果使用的id= 'box' 则使用'#box'
+    uni
+      .createSelectorQuery()
+      .select("#computed-box")
+      .boundingClientRect((data) => {
+        console.log(data);
+        this.bgHeight = data.height
+        console.log(this.bgHeight,98989898);
+      }).exec();
+  },
+  created() {
+    //  获取胶囊的高度
+    // #ifdef MP-WEIXIN
+    let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
+    this.menuButtonHeight = menuButtonInfo.height;
+    // #endif
 
-	},
-	methods: {
-		getCapusleHeight(e) {
-			this.mainHeight = 327 - e - this.menuButtonHeight + 16
-			console.log(this.mainHeight);
-		},
-		//  获取店铺详情
-		async getShop() {
-			let { data } = await getShopDetail({});
-			this.shopInfo = data
-			//  将店铺存到本地
-			uni.setStorageSync('shopInfo', data)
-		},
-		// 扫码
-		scanCode(url) {
-			uni.navigateTo({
-				url: url
-			});
-		}
-	}
-}
+    //  请求获取店铺的信息
+    this.getShop();
+    // 获取经营数据信息
+    this.getData()
+  },
+  data() {
+    return {
+      //  背景高度
+      bgHeight:0,
+      //  胶囊的高度
+      menuButtonHeight: null,
+      toolList: toolList,
+      tobeList: tobeList,
+      statisticsList: statisticsList,
+      // 店铺信息
+      shopInfo: {},
+      //  动态计算 main 的高度
+      mainHeight: 0,
+      todayData:{}
+    };
+  },
+  onLoad() {},
+  methods: {
+    //  获取经营数据
+    async getData(){
+      let res = await getBusinessData({});
+      this.todayData = res.data;
+    },
+    getCapusleHeight(e) {
+      // this.mainHeight = 327 - e - this.menuButtonHeight + 16;
+      console.log(this.mainHeight);
+    },
+    //  底部菜单跳转
+    tobeNavigate(item) {
+      if (item.title == "订单管理") {
+        uni.switchTab({
+          url: item.url,
+        });
+      } else if (item.url) {
+        this.navigateTo(item.url);
+      } else {
+        this.$showToast("功能暂未开放");
+      }
+    },
+    //  获取店铺详情
+    async getShop() {
+      let { data } = await getShopDetail({});
+      this.shopInfo = data;
+      //  将店铺存到本地
+      uni.setStorageSync("shopInfo", data);
+    },
+    // 扫码
+    scanCode(url) {
+      if(!url){
+        this.$showToast("功能暂未开放");
+        return
+      }
+      uni.navigateTo({
+        url: url,
+      });
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-@import './index.scss';
+@import "./index.scss";
 </style>

+ 73 - 39
pages/tabbar/order/index.vue

@@ -6,7 +6,7 @@
       </template>
     </capsule>
     <view class="order-top">
-      <view class="search-box">
+      <view class="search-box" @click="navigateTo('/order_module/searchOrder/index')">
         <view class="search-icon">
           <tui-icon name="search-2" :size="18" color="#999999"></tui-icon>
         </view>
@@ -14,25 +14,45 @@
       </view>
       <view class="order-state">
         <scroll-view scroll-x="true" class="scroll-X">
-          <view class="scroll-item" v-for="(item, index) in orderState" :key="index"
-            :class="item.state == orderIdx ? 'act' : ''" @click="changeState(item.state)">{{ item.title }}</view>
+          <view
+            class="scroll-item"
+            v-for="(item, index) in orderState"
+            :key="index"
+            :class="item.state == orderIdx ? 'act' : ''"
+            @click="changeState(item.state)"
+            >{{ item.title }}</view
+          >
         </scroll-view>
       </view>
     </view>
     <view class="order-container" v-if="orderList.length > 0">
       <view class="order-list">
-        <view class="order-item" v-for="item in orderList" :key="item.orderId">
+        <view
+          class="order-item"
+          v-for="item in orderList"
+          :key="item.orderId"
+          @click="goOrderDetail(item)"
+        >
           <view class="order-number">
             <view class="number">订单编号:{{ item.orderFormid }}</view>
             <view class="number-icon">
               <text>详情</text>
-              <tui-icon name="arrowright" :size="20" color="#999999" style="padding: 0;"></tui-icon>
+              <tui-icon
+                name="arrowright"
+                :size="20"
+                color="#999999"
+                style="padding: 0;"
+              ></tui-icon>
             </view>
           </view>
           <view class="text-info">用户昵称:{{ item.customerName }}</view>
           <view class="text-info">用户手机号:{{ item.customerPhone }}</view>
           <view class="commodity-list">
-            <view class="commodity-item" v-for="item2 in item.products" :key="item2.orderProductId">
+            <view
+              class="commodity-item"
+              v-for="item2 in item.products"
+              :key="item2.orderProductId"
+            >
               <view class="item-left">
                 <view class="left-image">
                   <image :src="item2.image" />
@@ -44,7 +64,7 @@
                   </template>
                   <template v-else>
                     <view class="text-price">小份</view>
-                  <view class="text-price">x1</view>
+                    <view class="text-price">x1</view>
                   </template>
                 </view>
               </view>
@@ -53,9 +73,11 @@
           </view>
           <view class="gifts">
             <view class="gifs-left">赠送代金券</view>
-            <view class="gifs-right">¥1 x 1</view>
+            <view class="gifs-right">¥{{ item.presenterVoucher }}</view>
           </view>
-          <view class="all-price">总价¥{{ item.price }},优惠¥99.99,实付¥100</view>
+          <view class="all-price"
+            >总价¥{{ item.price }}</view
+          >
           <view class="border-box"></view>
           <view class="order-state">
             <text v-if="item.state == 1">待付款</text>
@@ -65,7 +87,9 @@
             <text v-if="item.state == 5">交易关闭(已取消)</text>
             <text v-if="item.state == 6">待成团</text>
             <text v-if="item.state == 7">待售后</text>
-            <text v-if="item.state == 8" :style="{color:'#EA1717'}">待核销(未付款)</text>
+            <text v-if="item.state == 8" :style="{ color: '#EA1717' }"
+              >待核销(未付款)</text
+            >
             <text v-if="item.state == 9">待核销(已付款)</text>
             <text v-if="item.state == 10">已核销</text>
           </view>
@@ -73,45 +97,44 @@
       </view>
     </view>
     <view class="order-empty" v-else>
-      <image src="@/static/image/order/empty.png"  />
-       <view class="empty-title">暂无订单信息</view>
-       <view class="empty-info">有订单信息您会在这边看到的</view>
+      <image src="@/static/image/order/empty.png" />
+      <view class="empty-title">暂无订单信息</view>
+      <view class="empty-info">有订单信息您会在这边看到的</view>
     </view>
   </view>
 </template>
 
 <script>
-import { orderGetAll } from '@/config/index.js'
+import { orderGetAll } from "@/config/index.js";
 export default {
   created() {
-    this.getOrderList()
+    this.getOrderList();
   },
   data() {
     return {
       orderState: [
         {
-          title: '全部',
-          state: ''
+          title: "全部",
+          state: "",
         },
         {
-          title: '未付款',
-          state:8
+          title: "未付款",
+          state: 8,
         },
         {
-          title: '已付款',
-          state:9
+          title: "已付款",
+          state: 9,
         },
         {
-          title: '已核销',
-          state:10
+          title: "已核销",
+          state: 10,
         },
         {
-          title: '已取消',
-          state:5
+          title: "已取消",
+          state: 5,
         },
         {
-          title: '售后订单',
-
+          title: "售后订单",
         },
       ],
       orderIdx: 0,
@@ -123,35 +146,46 @@ export default {
         pageSize: 10,
         search: "",
         searchType: "1",
-        state: ""
+        state: "",
       },
-      orderList: []
-    }
+      orderList: [],
+    };
   },
   methods: {
     // 状态修改
     changeState(state) {
-      this.orderIdx = state
-      this.serachParams.state = state
+      this.orderIdx = state;
+      this.serachParams.state = state;
+      this.orderList = []
       //  请求新的数据
-      this.getOrderList()
+      this.getOrderList();
     },
     //  获取订单列表
     async getOrderList() {
       this.$loading.show("加载中!");
       try {
         let { data } = await orderGetAll(this.serachParams);
-        console.log(data);
-        this.orderList = data.list
+        this.orderList = [...this.orderList,...data.list];
       } catch (error) {
       } finally {
         this.$loading.hide();
       }
     },
-  }
-}
+    // 去到订单详情
+    goOrderDetail(item) {
+      this.navigateTo(
+        `/order_module/orderDetail/index?orderId=${item.orderId}`
+      );
+    },
+  },
+  //  触底加载
+  onReachBottom() {
+    this.serachParams.page++;
+    this.getOrderList();
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-@import './index.scss';
-</style>
+@import "./index.scss";
+</style>

+ 5 - 2
pages/tabbar/user/index.vue

@@ -53,7 +53,7 @@
         </view>
       </view>
       <view class="user-account">
-        <view class="account-top">
+        <view class="account-top" @click="navigateTo('/user_module/myAccount/index')">
           <text>我的账户</text>
           <tui-icon name="arrowright" :size="26" colo="#666666"></tui-icon>
         </view>
@@ -97,6 +97,7 @@ export default {
         {
           title: "商家入驻",
           image: require("@/static/image/user/account_01.png"),
+          url: "/user_module/webview/index?type=1",
         },
         {
           title: "商家码",
@@ -104,12 +105,14 @@ export default {
           url: "/user_module/merchantCode/index",
         },
         {
-          title: "员工账户",
+          title: "会员管理",
           image: require("@/static/image/user/account_03.png"),
+          url: "/user_module/memberManage/index",
         },
         {
           title: "官方客服",
           image: require("@/static/image/user/account_04.png"),
+          url: "/user_module/webview/index?type=2",
         },
       ],
       financeInfo: {},

+ 120 - 0
pages_module/bindingCard/index.scss

@@ -0,0 +1,120 @@
+.bindingCard {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  .detail-top {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    z-index: 999;
+    @include flex(center);
+
+    .back-icon {
+      position: absolute;
+      left: 0;
+      top: 50%;
+      transform: translateY(-50%);
+    }
+
+    .shop-name {
+      color: #000;
+      font-size: 28rpx;
+    }
+  }
+  .seize {
+    width: 100%;
+    height: 16rpx;
+    background-color: #ffffff;
+  }
+  .binding-box {
+    width: 100%;
+    padding: 32rpx;
+    box-sizing: border-box;
+    .binding-title {
+      font-size: 32rpx;
+      color: rgba(0, 0, 0, 0.9);
+      font-weight: 500;
+      margin-bottom: 16rpx;
+    }
+    .binding-container {
+      width: 100%;
+      padding: 0 32rpx;
+      box-sizing: border-box;
+      background-color: #ffffff;
+      border-radius: 16rpx;
+      position: relative;
+      .change-box {
+        width: 100%;
+        padding: 32rpx 0;
+        border-bottom: 2rpx solid #e7e7e7;
+        .change-title {
+          margin-bottom: 16rpx;
+          font-size: 28rpx;
+          color: rgba(0, 0, 0, 0.9);
+        }
+        .ipt-left {
+          padding-right: 32rpx;
+          position: relative;
+          font-size: 28rpx;
+          color: rgba(0, 0, 0, 0.9);
+          &::after {
+            content: "";
+            position: absolute;
+            top: 0;
+            right: 16rpx;
+            width: 4rpx;
+            border-radius: 8rpx;
+            background-color: #e7e7e7;
+            height: 100%;
+          }
+        }
+        .right-text{
+          font-size: 28rpx;
+          color: #EA5C1E;
+        }
+        .ipt-right{
+          width: 168rpx;
+          height: 60rpx;
+          text-align: center;
+          line-height: 60rpx;
+          font-size: 28rpx;
+          color: rgba(0, 0, 0, 0.6);
+          border: 2rpx solid #E7E7E7;
+          border-radius: 8rpx;
+        }
+      }
+      .inconsis {
+        position: absolute;
+        right: 32rpx;
+        bottom: 28rpx;
+        font-size: 24rpx;
+        color: #d40f0f;
+        @include flex(center, null, 8rpx);
+      }
+    }
+  }
+  .btn-list{
+    width: 100%;
+    padding: 0 32rpx;
+    margin-top: 38rpx;
+    box-sizing: border-box;
+    @include flex(center,null,19rpx);
+    .btn{
+      width: 335rpx;
+      height: 96rpx;
+      text-align: center;
+      line-height: 96rpx;
+      border-radius: 16rpx;
+      &:nth-of-type(1){
+        background-color: #FFFFFF;
+        border: 2rpx solid #E7E7E7;
+        color: rgba(0, 0, 0, 0.6);
+      }
+      &:nth-of-type(2){
+        background-color: #FE4B1E;
+        color: #FFFFFF;
+      }
+    }
+  }
+}
+

+ 313 - 0
pages_module/bindingCard/index.vue

@@ -0,0 +1,313 @@
+<template>
+  <view class="bindingCard">
+    <capsule :showBorder="true" bgColor="#FFFFFF">
+      <template v-slot:top>
+        <view class="detail-top">
+          <view class="back-icon" @click="backClick">
+            <tui-icon name="arrowleft" :size="32" color="#000"></tui-icon>
+          </view>
+          <view class="shop-name">{{ title }}</view>
+        </view>
+      </template>
+    </capsule>
+    <view class="seize"></view>
+    <view class="binding-box">
+      <view class="binding-title">绑定账户</view>
+      <view class="binding-container">
+        <view class="change-box">
+          <view class="change-title">银行卡卡号</view>
+          <view class="change-ipt">
+            <tui-input
+              placeholder="请输入"
+              padding="0 16rpx 0 0 "
+              :size="28"
+              :inputBorder="false"
+              :borderBottom="false"
+              v-model="bankInfo.cardNumber"
+            >
+            </tui-input>
+          </view>
+        </view>
+        <view class="change-box">
+          <view class="change-title">持卡人姓名</view>
+          <view class="change-ipt">
+            <tui-input
+              placeholder="请输入"
+              padding="0 16rpx 0 0 "
+              :size="28"
+              :inputBorder="false"
+              :borderBottom="false"
+              v-model="bankInfo.cardName"
+              @blur="changeCardName"
+            >
+            </tui-input>
+          </view>
+        </view>
+        <view class="change-box">
+          <view class="change-title">银行</view>
+          <view class="change-ipt">
+            <tui-input
+              placeholder="请输入"
+              padding="0 16rpx 0 0 "
+              :size="28"
+              :inputBorder="false"
+              :borderBottom="false"
+              :disabled="true"
+              :value="dictName"
+            >
+              <template #right>
+                <view class="right-text" @click="showChange">选择</view>
+              </template>
+            </tui-input>
+          </view>
+        </view>
+        <view class="change-box">
+          <view class="change-title">注册手机号</view>
+          <view class="change-ipt">
+            <tui-input
+              placeholder="请输入手机号码"
+              padding="0 16rpx 0 0 "
+              :size="28"
+              :inputBorder="false"
+              :borderBottom="false"
+              v-model="bankInfo.phone"
+            >
+              <template #left>
+                <view class="ipt-left">+86</view>
+              </template>
+            </tui-input>
+          </view>
+        </view>
+        <view class="change-box">
+          <view class="change-title">短信验证码</view>
+          <view class="change-ipt">
+            <tui-input
+              placeholder="请输入"
+              padding="0 16rpx 0 0 "
+              :size="28"
+              :inputBorder="false"
+              :borderBottom="false"
+              v-model="code"
+            >
+              <template #right>
+                <tui-countdown-verify
+                  text="获取验证码"
+                  sendText="发送中..."
+                  borderColor="#E7E7E7"
+                  color="rgba(0, 0, 0, 0.6)"
+                  :size="28"
+                  :seconds="60"
+                  :successVal="successVal"
+                  :resetVal="resetVal"
+                  @send="getVerify"
+                ></tui-countdown-verify>
+                <!-- <view class="ipt-right">获取验证码</view> -->
+              </template>
+            </tui-input>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="btn-list">
+      <view class="btn" @click="backClick">取消</view>
+      <view class="btn" @click="btnClick">{{ btnTitle }}</view>
+    </view>
+    <tui-picker
+      :show="showPicker"
+      :layer="1"
+      :pickerData="bankList"
+      textField="dictName"
+      valueField="dictId"
+      cancelColor="rgba(0, 0, 0, 0.6)"
+      confirmColor="#EA5C1E"
+      :value="value"
+      @change="nameChange"
+      @hide="showChange"
+    ></tui-picker>
+  </view>
+</template>
+
+<script>
+import {
+  getSelect,
+  getCode,
+  updateReceiving,
+  saveReceiving,
+} from "@/config/index.js";
+// {
+//     "id": "",
+//     "cardName": "徐枝浪",
+//     "cardNumber": "1234567893333",
+//     "bank": 2001,
+//     "phone": "13539102414",
+//     "code": "1",
+//     "bankType": 2,
+//     "province": "",
+//     "city": "",
+//     "bankName": "",
+//     "unionBank": "",
+//     "bankCode": ""
+// }
+export default {
+  created() {
+    //  获取所有银行列表
+    this.getBankAll();
+  },
+  onLoad(option) {
+    //  type == 1 表示已经有银行卡了
+    if (option.type == 1) {
+      this.title = "修改银行卡";
+      this.btnTitle = "修改";
+      //  本地获取数据
+      this.bankInfo = uni.getStorageSync("bankInfo");
+      this.dictName = this.bankInfo.dictName;
+      //  给 value 赋值
+      this.value = [this.bankInfo.dictName];
+    }
+  },
+  data() {
+    return {
+      title: "绑定银行卡",
+      btnTitle: "确认",
+      //  银行卡名称
+      dictName: "",
+      bankInfo: {
+        // cardNumber: "",
+        // cardName: "",
+        // bank: "",
+        // phone: "",
+        // code: "",
+
+        id: "",
+        cardName: "",
+        cardNumber: "",
+        bank: "",
+        phone: "",
+        bankType: "",
+        province: "",
+        city: "",
+        bankName: "",
+        unionBank: "",
+        bankCode: "",
+      },
+      //  控制 选择银行显示
+      showPicker: false,
+      bankList: [],
+      value: [],
+      //  控制获取验证码成功
+      successVal: 0,
+      //  控制获取验证码失败
+      resetVal: 0,
+      //  二维码
+      code: "",
+    };
+  },
+  methods: {
+    //  姓名特殊字符判断
+    changeCardName() {
+      let rule = /[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、' ']/g;
+      if (rule.test(this.bankInfo.cardName)) {
+        this.$showToast("姓名不能包含特殊字符!");
+        this.bankInfo.cardName = this.bankInfo.cardName.replace(rule, "");
+      }
+    },
+    //  获取所有银行
+    async getBankAll() {
+      let { data } = await getSelect({ dictName: "所属银行" });
+      this.bankList = data;
+    },
+    //  获取验证码
+    async getVerify() {
+      const phoneCodeVerification = /^[1][3-9][0-9]{9}$/;
+      if (!phoneCodeVerification.test(this.bankInfo.phone)) {
+        this.$showToast("请输入正确的手机号!");
+        this.resetVal++;
+        return;
+      }
+      let res = await getCode({ phone: this.bankInfo.phone });
+      if (res.message == "") {
+        this.successVal++;
+      } else {
+        this.$showToast(res.message);
+        this.resetVal++;
+      }
+    },
+    //  保存 / 修改点击事件
+    btnClick() {
+      //  进去先对数据进行正则判断
+      const phoneCodeVerification = /^[1][3-9][0-9]{9}$/;
+      const cardRule = /^([1-9]{1})(\d{15}|\d{18})$/;
+      if (!phoneCodeVerification.test(this.bankInfo.phone)) {
+        this.$showToast("请输入正确的手机号!");
+        return;
+      }
+      if (!cardRule.test(this.bankInfo.cardNumber)) {
+        this.$showToast("卡号需为16~19位的数字");
+        return;
+      }
+      if (this.code == "") {
+        this.$showToast("验证码不能为空");
+        return;
+      }
+      this.bankInfo.code = this.code;
+      if (this.btnTitle == "修改") {
+        this.updateAccount();
+      } else {
+        this.saveAccount();
+      }
+    },
+    //  修改账户信息
+    async updateAccount() {
+      //  对数据进行处理
+      let obj = { ...this.bankInfo };
+      // 删除自己添加的数据
+      delete obj.dictName;
+      let res = await updateReceiving(obj);
+      if (res.code == "") {
+        this.$showToast("修改成功");
+        //  跳转回我的账户页面
+        setTimeout(() => {
+          this.backClick();
+        }, 1500);
+      }
+    },
+    //  保存账户信息
+    async saveAccount() {
+      let res = await saveReceiving(this.bankInfo);
+      if (res.code == "") {
+        this.$showToast("保存成功");
+        //  跳转回我的账户页面
+        setTimeout(() => {
+          this.backClick();
+        }, 1500);
+      }
+    },
+    //  控制选择显示
+    showChange() {
+      this.showPicker = !this.showPicker;
+    },
+    //  选择银行确认
+    nameChange(key) {
+      this.bankInfo.bank = key.dictId;
+      this.dictName = key.dictName;
+    },
+    backClick() {
+      uni.navigateBack({
+        fail: () => {
+          uni.redirectTo({
+            url: "/pages_module/receiving/index",
+          });
+        },
+      });
+    },
+  },
+    //    页面卸载清除缓存
+    onUnload() {
+    uni.removeStorageSync("bankInfo");
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 270 - 0
pages_module/components/waterContainer/index.vue

@@ -0,0 +1,270 @@
+<template>
+  <view class="water-container">
+    <view class="water-date" @click="showDatePicker">
+      <text>{{ defaultTime }}</text>
+      <tui-icon name="turningdown" color="#C9CDD4" :size="24"></tui-icon>
+    </view>
+    <view class="water-all">
+      <view class="all-item">
+        <text>收入</text>
+        <text>{{ todayWater[0].income || "0" }}</text>
+      </view>
+      <view class="all-item">
+        <text>支出</text>
+        <text>{{ todayWater[0].expenditure || "0" }}</text>
+      </view>
+    </view>
+    <view class="water-order">
+      <view class="order-title">订单明细</view>
+      <template v-if="dayOrderList.length > 0">
+        <view class="order-list">
+          <view
+            class="order-item"
+            v-for="(item, index) in dayOrderList"
+            :key="index"
+          >
+            <view class="item-text">
+              <text>订单单号</text>
+              <text>{{ item.orderFormid }}</text>
+            </view>
+            <view class="item-text">
+              <text>订单金额</text>
+              <text>{{ item.money }}</text>
+            </view>
+            <view class="item-text">
+              <text>收支类型</text>
+              <text>{{ item.incomeType }}</text>
+            </view>
+            <view class="item-text">
+              <text>流水类型</text>
+              <text>{{ item.waterType }}</text>
+            </view>
+            <view class="item-text">
+              <text>到账时间</text>
+              <text>{{ item.time }}</text>
+            </view>
+          </view>
+        </view>
+      </template>
+      <template v-else>
+        <view class="no-data">
+          <image src="@/static/image/order/empty.png" />
+          <text>暂无数据</text>
+        </view>
+      </template>
+    </view>
+    <tui-datetime
+      ref="dateTime"
+      :setDateTime="defaultTime"
+      :type="defaultType"
+      color="#EA5C1E"
+      :radius="true"
+      @confirm="dateConfirm"
+    ></tui-datetime>
+  </view>
+</template>
+
+<script>
+import { getDayDetail } from "@/config/index";
+import { getNowDate } from "@/utils/index";
+export default {
+  props: {
+    type: {
+      type: String,
+      default: "",
+    },
+    financialData: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  created() {
+    if (this.type == 1) {
+      this.defaultType = 2;
+      this.defaultTime = getNowDate(3);
+    } else if (this.type == 2) {
+      this.defaultType = 3;
+      this.defaultTime = getNowDate(2);
+    }
+  },
+  computed: {
+    //  过滤当日流水
+    todayWater() {
+      //  判断当前有没有数据
+      if (Object.keys(this.financialData).length <= 0) return "";
+      let list = this.financialData.finances.filter((item) => {
+        return item.time == this.defaultTime;
+      });
+      if (list.length > 0) {
+        //  给获取当日订单数据参数赋值
+        this.queryOrder.time = this.defaultTime;
+        //  请求当日订单数据
+        this.getDayOrder();
+      } else {
+        //  重置订单数据
+        this.dayOrderList = [];
+      }
+      return list;
+    },
+  },
+  data() {
+    return {
+      //  请求总流水的参数
+      waterAll: {
+        condition: "1",
+        time: "",
+      },
+      //    默认时间
+      defaultTime: "",
+      //   控制年月
+      defaultType: 2,
+      //  请求 日 订单数据的参数
+      queryOrder: {
+        income: "",
+        page: 1,
+        pageSize: 10,
+        state: "",
+        time: "",
+      },
+      //  订单数据列表
+      dayOrderList: [],
+      //  订单总数
+      dayOrderTotal: 0,
+    };
+  },
+  methods: {
+    //  获取当日订单数据
+    async getDayOrder() {
+      let res = await getDayDetail(this.queryOrder);
+      this.dayOrderList = res.data.list;
+      this.dayOrderTotal = res.data.total;
+    },
+    //  控制日期选择显示
+    showDatePicker() {
+      this.$refs.dateTime && this.$refs.dateTime.show();
+    },
+    //  日期确定点击
+    dateConfirm(date) {
+      // 对日期重新赋值
+      this.defaultTime = date.result;
+      
+    },
+  },
+  watch: {
+    type(val) {
+      if (val == 1) {
+        this.defaultType = 2;
+        this.defaultTime = getNowDate(3);
+      } else if (val == 2) {
+        this.defaultType = 3;
+        this.defaultTime = getNowDate(2);
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.water-container {
+  padding: 0 32rpx;
+  box-sizing: border-box;
+  .water-date {
+    margin: 32rpx 0;
+    font-size: 28rpx;
+    color: #3d3d3d;
+    font-weight: 400;
+    @include flex(flex-start, null, 13rpx);
+  }
+  .water-all {
+    @include flex(space-between, null);
+    .all-item {
+      width: 304rpx;
+      height: 104rpx;
+      border-radius: 8rpx;
+      background-color: #fff3ee;
+      padding: 16rpx;
+      box-sizing: border-box;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      text {
+        &:nth-of-type(1) {
+          font-size: 24rpx;
+          color: rgba(77, 51, 39, 0.41);
+          font-weight: 500;
+        }
+        &:nth-of-type(2) {
+          font-size: 28rpx;
+          color: #ea5c1e;
+          font-weight: 900;
+        }
+      }
+    }
+  }
+  .water-order {
+    width: 100%;
+    margin-top: 32rpx;
+    .order-title {
+      position: relative;
+      color: rgba(0, 0, 0, 0.9);
+      font-size: 28rpx;
+      font-weight: 600;
+      &::after {
+        content: "";
+        position: absolute;
+        left: -32rpx;
+        top: 50%;
+        transform: translateY(-50%);
+        width: 8rpx;
+        height: 24rpx;
+        background-color: #ea5c1e;
+      }
+    }
+    .order-list {
+      width: 100%;
+      margin-top: 32rpx;
+      .order-item {
+        margin-top: 16rpx;
+        padding: 0 16rpx 16rpx;
+        box-sizing: border-box;
+        width: 100%;
+        background-color: #f5f4f3;
+        border-radius: 16rpx;
+        .item-text {
+          width: 100%;
+          @include flex(flex-start);
+          height: 44rpx;
+          line-height: 44rpx;
+          padding-top: 16rpx;
+          text {
+            font-size: 28rpx;
+            &:nth-of-type(1) {
+              width: 208rpx;
+              color: rgba(0, 0, 0, 0.4);
+            }
+            &:nth-of-type(2) {
+              color: #000000;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+            }
+          }
+        }
+      }
+    }
+    .no-data {
+      height: 736rpx;
+      @include flex(center, column, 32rpx);
+      image {
+        width: 320rpx;
+        height: 320rpx;
+        display: block;
+      }
+      text {
+        color: rgba(0, 0, 0, 0.4);
+        font-size: 28rpx;
+        font-weight: 600;
+      }
+    }
+  }
+}
+</style>

+ 48 - 0
pages_module/financial/data.js

@@ -0,0 +1,48 @@
+
+
+export const detailedList = [
+    {
+        title:"累计营业额(元)",
+        name:"turnover"
+    },
+    {
+        title:"冻结金额(元)",
+        name:"frozenMoney"
+    },
+    {
+        title:"可提现金额(元)",
+        name:"withdrawableMoney"
+    },
+    {
+        title:"提现中(元)",
+        name:"withdrawableStayMoney"
+    },
+    {
+        title:"赠送代金券",
+        name:"presenterVoucher"
+    },
+]
+
+
+export const voucherList = [
+    {
+        title:"营业额",
+        name:"beeTurnover"
+    },
+    {
+        title:"可提现",
+        name:"beeWithdrawal"
+    },
+    {
+        title:"待到账冻结",
+        name:"beeFreeze"
+    },
+    {
+        title:"已提现",
+        name:"withdrawn"
+    },
+    {
+        title:"提现中",
+        name:"withdrawalIn"
+    },
+]

+ 263 - 0
pages_module/financial/index.scss

@@ -0,0 +1,263 @@
+.financial {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  padding: 32rpx;
+  padding-bottom: 50rpx;
+  box-sizing: border-box;
+  .financial-box {
+    width: 100%;
+    background: linear-gradient(108deg, #fe4b1e 0%, #fb8857 100%);
+    padding: 32rpx;
+    border-radius: 16rpx;
+    box-sizing: border-box;
+    position: relative;
+    @include flex(space-between, null);
+    .drawable-price {
+      display: flex;
+      justify-content: space-between;
+      flex-direction: column;
+      text {
+        &:nth-of-type(1) {
+          color: rgba(255, 255, 255, 0.8);
+          font-size: 32rpx;
+          font-weight: 500;
+        }
+        &:nth-of-type(2) {
+          color: #ffffff;
+          font-size: 64rpx;
+          font-weight: 900;
+        }
+      }
+    }
+    .detailed {
+      width: 152rpx;
+      height: 60rpx;
+      text-align: center;
+      line-height: 60rpx;
+      background: rgba(255, 255, 255, 0.2);
+      color: #ffffff;
+      font-size: 24rpx;
+      border-radius: 30rpx;
+    }
+  }
+  .financial-price {
+    width: 100%;
+    margin-top: 32rpx;
+    padding: 16rpx 32rpx 32rpx 32rpx;
+    box-sizing: border-box;
+    border-radius: 16rpx;
+    background-color: #ffffff;
+    position: relative;
+    &::after {
+      content: "";
+      position: absolute;
+      left: 0;
+      top: 26rpx;
+      width: 8rpx;
+      height: 24rpx;
+      background-color: #ea5c1e;
+    }
+    .price-title {
+      color: #000000;
+      font-size: 28rpx;
+      font-weight: 600;
+      margin-top: 3rpx;
+    }
+    .price-list {
+      width: 100%;
+      @include flex(space-between, null, null);
+      flex-wrap: wrap;
+      .price-item {
+        width: 202rpx;
+        height: 124rpx;
+        margin-top: 16rpx;
+        background-color: #fff3ee;
+        padding: 16rpx;
+        box-sizing: border-box;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        border-radius: 8rpx;
+        text {
+          &:nth-of-type(1) {
+            color: rgba(77, 51, 39, 0.41);
+            font-size: 24rpx;
+            line-height: 40rpx;
+            font-weight: 600;
+          }
+          &:nth-of-type(2) {
+            color: #ea5c1e;
+            font-size: 28rpx;
+            line-height: 44rpx;
+            font-weight: 900;
+          }
+        }
+        &.hide {
+          visibility: hidden;
+        }
+      }
+    }
+  }
+  .water {
+    width: 100%;
+    margin-top: 32rpx;
+
+    .water-title {
+      margin-bottom: 16rpx;
+      font-size: 32rpx;
+      font-weight: 600;
+      color: rgba(0, 0, 0, 0.9);
+    }
+    .water-box {
+      background-color: #ffffff;
+      border-radius: 16rpx;
+      padding-bottom: 32rpx;
+      .water-header {
+        width: 100%;
+        height: 92rpx;
+        line-height: 92rpx;
+        @include flex(space-between, null);
+        border-bottom: 2rpx solid #e7e7e7;
+        .header-item {
+          flex: 1;
+          text-align: center;
+          font-size: 28rpx;
+          font-weight: 600;
+          color: rgba(0, 0, 0, 0.4);
+          &:nth-of-type(1) {
+            position: relative;
+            &::after {
+              content: "";
+              width: 2rpx;
+              height: 50%;
+              background-color: #e7e7e7;
+              position: absolute;
+              right: 0;
+              top: 50%;
+              transform: translateY(-50%);
+            }
+          }
+          &.active {
+            color: rgba(0, 0, 0, 0.9);
+            position: relative;
+            &::before {
+              content: "";
+              width: 32rpx;
+              height: 4rpx;
+              background-color: #ea5c1e;
+              position: absolute;
+              left: 50%;
+              transform: translateX(-50%);
+              bottom: 0;
+            }
+          }
+        }
+      }
+      .water-container {
+        padding: 0 32rpx;
+        box-sizing: border-box;
+        .water-date {
+          margin: 32rpx 0;
+          font-size: 28rpx;
+          color: #3d3d3d;
+          font-weight: 400;
+          @include flex(flex-start, null, 13rpx);
+        }
+        .water-all {
+          @include flex(space-between, null);
+          .all-item {
+            width: 304rpx;
+            height: 104rpx;
+            border-radius: 8rpx;
+            background-color: #fff3ee;
+            padding: 16rpx;
+            box-sizing: border-box;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
+            text {
+              &:nth-of-type(1) {
+                font-size: 24rpx;
+                color: rgba(77, 51, 39, 0.41);
+                font-weight: 500;
+              }
+              &:nth-of-type(2) {
+                font-size: 28rpx;
+                color: #ea5c1e;
+                font-weight: 900;
+              }
+            }
+          }
+        }
+        .water-order {
+          width: 100%;
+          margin-top: 32rpx;
+          .order-title {
+            position: relative;
+            color: rgba(0, 0, 0, 0.9);
+            font-size: 28rpx;
+            font-weight: 600;
+            &::after {
+              content: "";
+              position: absolute;
+              left: -32rpx;
+              top: 50%;
+              transform: translateY(-50%);
+              width: 8rpx;
+              height: 24rpx;
+              background-color: #ea5c1e;
+            }
+          }
+          .order-list {
+            width: 100%;
+            margin-top: 32rpx;
+            .order-item {
+              margin-top: 16rpx;
+              padding: 0 16rpx 16rpx;
+              box-sizing: border-box;
+              width: 100%;
+              background-color: #F5F4F3;
+              border-radius: 16rpx;
+              .item-text {
+                width: 100%;
+                @include flex(flex-start);
+                height: 44rpx;
+                line-height: 44rpx;
+                padding-top: 16rpx;
+                text {
+                  font-size: 28rpx;
+                  &:nth-of-type(1) {
+                    width: 208rpx;
+                    color: rgba(0, 0, 0, 0.4);
+                  }
+                  &:nth-of-type(2) {
+                    color: #000000;
+                    //  单行溢出
+                    overflow: hidden;
+                    text-overflow: ellipsis;
+                    white-space: nowrap;
+                  }
+                }
+              }
+            }
+          }
+          .no-data{
+            height: 736rpx;
+            @include flex(center, column,32rpx);
+            image{
+              width: 320rpx;
+              height: 320rpx;
+              display: block;
+            }
+            text{
+              color: rgba(0, 0, 0, 0.4);
+              font-size: 28rpx;
+              font-weight: 600;
+            }
+          }
+        }
+      }
+    }
+  }
+}

+ 114 - 0
pages_module/financial/index.vue

@@ -0,0 +1,114 @@
+<template>
+  <view class="financial">
+    <view class="financial-box">
+      <view class="drawable-price">
+        <text>可提现金额(元)</text>
+        <text>{{ financialData.withdrawableMoney || "0" }}</text>
+      </view>
+      <view class="detailed" @click="navigateTo(`/pages_module/withdrawal/index?balance=${financialData.withdrawableMoney}&trading=${financialData.beeWithdrawal}`)">查看明细</view>
+    </view>
+    <view class="financial-price">
+      <view class="price-title">基本数据</view>
+      <view class="price-list">
+        <view
+          class="price-item"
+          v-for="(item, index) in detailedList"
+          :key="index"
+        >
+          <text>{{ item.title }}</text>
+          <text>{{ financialData[item.name] || "0" }}</text>
+        </view>
+        <!--  占位盒子  -->
+        <view class="price-item hide"></view>
+      </view>
+    </view>
+    <view class="financial-price">
+      <view class="price-title">消费金相关</view>
+      <view class="price-list">
+        <view
+          class="price-item"
+          v-for="(item, index) in voucherList"
+          :key="index"
+        >
+          <text>{{ item.title }}</text>
+          <text>{{ financialData[item.name] || "0" }}</text>
+        </view>
+        <!--  占位盒子  -->
+        <view class="price-item hide"></view>
+      </view>
+    </view>
+    <view class="water">
+      <view class="water-title">流水</view>
+      <view class="water-box">
+        <view class="water-header">
+          <view
+            class="header-item"
+            :class="idx == 1 ? 'active' : ''"
+            @click="changeIdx(1)"
+            >日流水</view
+          >
+          <view
+            class="header-item"
+            :class="idx == 2 ? 'active' : ''"
+            @click="changeIdx(2)"
+            >月流水</view
+          >
+        </view>
+        <WaterContainer :type="idx" :financialData="financialData"></WaterContainer>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import { getFinancial } from "@/config/index";
+import { detailedList, voucherList } from "./data";
+import WaterContainer from "../components/waterContainer/index"
+export default {
+  onShow(){
+    this.getFinancialData();
+  },
+  components:{
+    WaterContainer
+  },
+  data() {
+    return {
+      //  静态数据
+      detailedList: detailedList,
+      voucherList: voucherList,
+      //    动态数据
+      //  切换日数据 以及 月数据
+      idx: 1,
+      financialData: {},
+      queryData: {
+        condition: "1",
+        time: "",
+      },
+    };
+  },
+  methods: {
+    //  获取 总 数据
+    async getFinancialData() {
+      try {
+        this.$loading.show("统计中...");
+        const res = await getFinancial(this.queryData);
+        this.financialData = res.data;
+        // console.log(this.financialData);
+      } finally {
+        this.$loading.hide();
+      }
+    },
+    //  控制激活态
+    changeIdx(val) {
+      this.idx = val;
+      this.queryData.condition = val
+      //  重新获取总数据
+      this.getFinancialData()
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 138 - 0
pages_module/operateData/index.scss

@@ -0,0 +1,138 @@
+.operateData {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  padding: 32rpx;
+  padding-bottom: 50rpx;
+  box-sizing: border-box;
+  .operate-box {
+    width: 100%;
+    padding: 4rpx 0 32rpx 0;
+    height: 304rpx;
+    border-radius: 16rpx;
+    box-sizing: border-box;
+    background: linear-gradient(115deg, #fe4b1e 0%, #fb8857 100%);
+    @include flex(center, null);
+    flex-wrap: wrap;
+    .operate-item {
+      margin-left: 32rpx;
+      width: 310rpx;
+      height: 104rpx;
+      position: relative;
+      padding-left: 48rpx;
+      padding-top: 12rpx;
+      box-sizing: border-box;
+      margin-top: 32rpx;
+      .item-icon {
+        position: absolute;
+        left: 4rpx;
+        top: 8rpx;
+      }
+      .item-text {
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        text {
+          &:nth-of-type(1) {
+            color: rgba(255, 255, 255, 0.8);
+            font-size: 24rpx;
+            font-weight: 500;
+          }
+          &:nth-of-type(2) {
+            color: #ffffff;
+            font-size: 28rpx;
+            font-weight: 900;
+          }
+        }
+      }
+      &.border {
+        border-right: 2rpx solid rgba(255, 255, 255, 0.2);
+      }
+    }
+  }
+  .list-container {
+    margin-top: 32rpx;
+    .list-title {
+      margin-bottom: 24rpx;
+      color: rgba(0, 0, 0, 0.9);
+      font-size: 32rpx;
+      font-weight: 600;
+    }
+    .list-box {
+      width: 100%;
+      height: 362rpx;
+      padding: 32rpx;
+      box-sizing: border-box;
+      background-color: #ffffff;
+      border-radius: 32rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+  .custom-container {
+    margin-top: 32rpx;
+    .custom-title {
+      margin-bottom: 24rpx;
+      color: rgba(0, 0, 0, 0.9);
+      font-size: 32rpx;
+      font-weight: 600;
+    }
+    .custom-list{
+        .item{
+            margin-top: 16rpx;
+            width: 100%;
+            height: 484rpx;
+            padding: 0 32rpx;
+            box-sizing: border-box;
+            background-color: #FFFFFF;
+            border-radius: 16rpx;
+            .item-top{
+                padding: 24rpx 0;
+                display: flex;
+                justify-content: center;
+                flex-direction: column;
+                gap: 16rpx;
+                border-bottom: 2rpx solid #EEEEEE;
+                text{
+                    height: 44rpx;
+                    line-height: 44rpx;
+                    &:nth-of-type(1){
+                        font-size: 32rpx;
+                        color: rgba(0, 0, 0, 0.9);
+                        font-weight: 600;
+                    }
+                    &:nth-of-type(2){
+                        font-size: 28rpx;
+                        color: rgba(0, 0, 0, 0.26);
+                    }
+                }
+            }
+            .item-bottom{
+                width: 100%;
+                padding-top: 8rpx;
+                padding-bottom: 32rpx;
+                box-sizing: border-box;
+                .text-box{
+                    height: 44rpx;
+                    line-height: 44rpx;
+                    margin-top: 16rpx;
+                    @include flex(flex-start,null,32rpx);
+                    text{
+                        &:nth-of-type(1){
+                            width: 176rpx;
+                            font-size: 28rpx;
+                            color: rgba(0, 0, 0, 0.4);
+                        }
+                        &:nth-of-type(2){
+                            font-size: 28rpx;
+                            color: rgba(0, 0, 0, 0.9);
+                        }
+                    }
+                }
+            }
+        }
+    }
+  }
+}

+ 217 - 0
pages_module/operateData/index.vue

@@ -0,0 +1,217 @@
+<template>
+  <view class="operateData">
+    <view class="operate-box">
+      <view class="operate-item border">
+        <view class="item-icon">
+          <tui-icon name="seen" :size="16" color="#FFFFFF"></tui-icon>
+        </view>
+        <view class="item-text">
+          <text>店铺访问次数</text>
+          <text>{{ operateData.total }}</text>
+        </view>
+      </view>
+      <view class="operate-item">
+        <view class="item-icon">
+          <tui-icon name="time" :size="16" color="#FFFFFF"></tui-icon>
+        </view>
+        <view class="item-text">
+          <text>待处理订单</text>
+          <text>{{ operateData.stayOrders }}</text>
+        </view>
+      </view>
+      <view class="operate-item border">
+        <view class="item-icon">
+          <tui-icon name="wealth" :size="16" color="#FFFFFF"></tui-icon>
+        </view>
+        <view class="item-text">
+          <text>成交金额</text>
+          <text>{{ operateData.money || 0 }}</text>
+        </view>
+      </view>
+      <view class="operate-item">
+        <view class="item-icon">
+          <tui-icon name="order" :size="16" color="#FFFFFF"></tui-icon>
+        </view>
+        <view class="item-text">
+          <text>售后订单</text>
+          <text>{{ operateData.stayAfters }}</text>
+        </view>
+      </view>
+    </view>
+    <view class="list-container">
+      <view class="list-title">用户访问趋势</view>
+      <view class="list-box">
+        <tui-charts-line
+          ref="tui_line_1"
+          tooltip
+          :width="588"
+          :xAxis="options1.xAxis"
+          :dataset="options1.dataset"
+          :max="options1.max"
+          :splitNumber="options1.splitNumber"
+          @click="dotClick"
+        ></tui-charts-line>
+      </view>
+    </view>
+    <view class="list-container">
+      <view class="list-title">订单转换漏斗</view>
+      <view class="list-box">
+        <tui-charts-line
+          ref="tui_line_2"
+          tooltip
+          :width="588"
+          :xAxis="options2.xAxis"
+          :dataset="options2.dataset"
+          :max="options2.max"
+          :splitNumber="options2.splitNumber"
+          @click="dotClick"
+        ></tui-charts-line>
+      </view>
+    </view>
+    <view class="custom-container">
+      <view class="custom-title">客户列表</view>
+      <view class="custom-list">
+        <view class="item" v-for="item in buyerList" :key="item.buyerUserId">
+          <view class="item-top">
+            <text>{{ item.name }}</text>
+            <text>{{ item.phone }}</text>
+          </view>
+          <view class="item-bottom">
+            <view class="text-box">
+              <text>消费次数</text>
+              <text>{{ item.frequency || 0 }}</text>
+            </view>
+            <view class="text-box">
+              <text>累计消费金额</text>
+              <text>{{ item.total || 0 }}元</text>
+            </view>
+            <view class="text-box">
+              <text>上次消费时间</text>
+              <text>{{ item.lastTime }}</text>
+            </view>
+            <view class="text-box">
+              <text>成为客户时间</text>
+              <text>{{ item.time }}</text>
+            </view>
+            <view class="text-box">
+              <text>客户等级</text>
+              <text>{{ item.userGrade }}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import { getOperateData, getCustomerList } from "@/config/index";
+export default {
+  created() {
+    //  获取客户列表
+    this.getBuyerAll();
+  },
+  async onReady() {
+    this.getBusinessData();
+  },
+  data() {
+    return {
+      // 总体数据
+      operateData: {},
+      options1: {
+        xAxis: ["一月", "二月", "三月", "四月", "五月", "六月"],
+        dataset: [
+          {
+            name: "访问量",
+            color: "#EA5C1E",
+            source: [1, 2, 3, 4, 5, 6],
+          },
+        ],
+        max: 10,
+        splitNumber: 2,
+      },
+      options2: {
+        xAxis: ["一月", "二月", "三月", "四月", "五月", "六月"],
+        dataset: [
+          {
+            name: "转化率(%)",
+            color: "#EA5C1E",
+            source: [],
+          },
+        ],
+        max: 100,
+        splitNumber: 25,
+      },
+      //    获取客户列表的参数
+      queryData: {
+        dates: [],
+        labelId: null,
+        lastTimes: [],
+        page: 1,
+        pageSize: 20,
+        phone: "",
+      },
+      // 客户列表
+      buyerList: [],
+    };
+  },
+  methods: {
+    //  获取经营数据
+    async getBusinessData() {
+      let res = await getOperateData({ condition: 3 });
+      this.operateData = res.data;
+      this.handleData();
+      this.orderData();
+    },
+    //  获取客户数据
+    async getBuyerAll() {
+      let { data } = await getCustomerList(this.queryData);
+      this.buyerList = [...this.buyerList, ...data.list];
+    },
+
+    // 对数据进行处理
+    handleData() {
+      let { visitWeek } = this.operateData;
+      let list = visitWeek.time.reduce((prev, item, index) => {
+        if (index == 0) return prev;
+        let arr = item.split("-");
+        prev.push(`${arr[1]}.${arr[2]}`);
+        return prev;
+      }, []);
+      this.options1.xAxis = list;
+      //  删除第一个
+      visitWeek.total.shift();
+      this.options1.dataset[0].source = visitWeek.total;
+
+      let max = Math.max(...visitWeek.total);
+      //    设置最大值和最小值
+      this.options1.max = max + 4;
+      this.options1.splitNumber = Math.ceil(max / 4) + 1;
+      this.$nextTick(() => {
+        this.$refs.tui_line_1.draw(this.options1.dataset);
+      });
+    },
+    //  订单转化率画图
+    orderData() {
+      let { conversion } = this.operateData;
+      this.options2.xAxis = conversion.names;
+      this.options2.dataset[0].source = conversion.rates;
+      this.$nextTick(() => {
+        this.$refs.tui_line_2.draw(this.options2.dataset);
+      });
+    },
+    dotClick(e) {
+      console.log(e);
+    },
+  },
+  //  触底加载
+  onReachBottom() {
+    this.queryData.page++;
+    this.getBuyerAll();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 36 - 26
pages_module/orderVerifica/index.vue

@@ -3,7 +3,7 @@
     <capsule :showBorder="true">
       <template v-slot:top>
         <view class="shop-top">
-          <view class="back-icon" @click="backClick">
+          <view class="back-icon" @click="back">
             <tui-icon name="arrowleft" :size="36" color="#000"></tui-icon>
           </view>
           <view class="shop-name">订单核销</view>
@@ -215,17 +215,27 @@ export default {
     },
     async backClick() {
       if (this.showText == "返回扫码") {
-        uni.navigateBack();
+        this.back();
         return;
       }
       if (this.showText == "确认") {
         let res = await orderVerify({ orderId: this.orderId, noticeId: 0 });
-        this.flag = true
+        if(res.code == ""){
+          this.flag = true;
+        }
       }
     },
-    back(){
-        uni.navigateBack();
-    }
+    //  返回扫码
+    back() {
+      uni.navigateBack({
+        delta: 1,
+        fail: () => {
+          uni.redirectTo({
+            url: "/pages_module/scanCoupons/index",
+          });
+        },
+      });
+    },
   },
 };
 </script>
@@ -377,30 +387,30 @@ export default {
     }
   }
 
-  .success-container{
+  .success-container {
     margin-top: 208rpx;
     width: 100%;
-    @include flex(center,column);
-    image{
-        width: 300rpx;
-        height: 300rpx;
-        display: block;
+    @include flex(center, column);
+    image {
+      width: 300rpx;
+      height: 300rpx;
+      display: block;
     }
-    text{
-        margin-top: 25rpx;
-        color: #666666;
-        font-size: 28rpx;
+    text {
+      margin-top: 25rpx;
+      color: #666666;
+      font-size: 28rpx;
     }
-    .success-back{
-        margin-top: 52rpx;
-        border-radius: 100rpx;
-        background-color: #05C160;
-        width: 246rpx;
-        height: 88rpx;
-        text-align: center;
-        line-height: 88rpx;
-        color: #FFFFFF;
-        font-size: 28rpx;
+    .success-back {
+      margin-top: 52rpx;
+      border-radius: 100rpx;
+      background-color: #05c160;
+      width: 246rpx;
+      height: 88rpx;
+      text-align: center;
+      line-height: 88rpx;
+      color: #ffffff;
+      font-size: 28rpx;
     }
   }
 }

+ 93 - 0
pages_module/receiving/index.scss

@@ -0,0 +1,93 @@
+.receiving {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  position: relative;
+  .empty {
+    position: absolute;
+    top: 176rpx;
+    left: 50%;
+    transform: translateX(-50%);
+    @include flex(center, column, 0);
+    image {
+      width: 320rpx;
+      height: 320rpx;
+      display: block;
+    }
+    text {
+      color: rgba(0, 0, 0, 0.4);
+      font-size: 28rpx;
+      font-weight: 500;
+      margin: 32rpx 0 48rpx;
+    }
+    .btn {
+      width: 246rpx;
+      height: 88rpx;
+      text-align: center;
+      line-height: 88rpx;
+      background-color: #fe4b1e;
+      border-radius: 16rpx;
+      color: #ffffff;
+      font-size: 28rpx;
+    }
+  }
+  .receiving-box {
+    width: 100%;
+    // padding-top: 32rpx;
+    padding: 32rpx;
+    box-sizing: border-box;
+    .receiving-title {
+      width: 100%;
+      margin-bottom: 16rpx;
+      color: rgba(0, 0, 0, 0.9);
+      font-size: 32rpx;
+      font-weight: 600;
+    }
+    .receiving-card {
+      width: 100%;
+      padding-right: 8rpx;
+      box-sizing: border-box;
+      .card-box {
+        width: 100%;
+        height: 270rpx;
+        padding: 0 32rpx;
+        padding-top: 32rpx;
+        box-sizing: border-box;
+        background-color: #C22525;
+        border-radius: 16rpx;
+        .card-title{
+            @include flex(space-between, null);
+            text{
+                color: #FFFFFF;
+                font-size: 32rpx;
+                font-size: 500;
+            }
+        }
+        .card-eye{
+            margin-top: 24rpx;
+            @include flex(flex-start,null,18rpx);
+            padding-bottom: 26rpx;
+            border-bottom: 2rpx solid rgba(255, 255, 255, 0.2);
+            text{
+                color: #FFFFFF;
+                font-size: 32rpx;
+                font-size: 500;
+            }
+        }
+        .card-prople{
+            margin-top: 24rpx;
+            font-size: 28rpx;
+            text{
+                &:nth-of-type(1){
+                    color: rgba(255, 255, 255, 0.4);
+                }
+                &:nth-of-type(2){
+                    color: #FFFFFF;
+                    margin-left: 100rpx;
+                }
+            }
+        }
+      }
+    }
+  }
+}

+ 133 - 0
pages_module/receiving/index.vue

@@ -0,0 +1,133 @@
+<template>
+  <view class="receiving">
+    <template v-if="Object.keys(receivingInfo).length <= 0">
+      <view class="empty">
+        <image class="" src="@/static/image/order/empty.png" />
+        <text>暂未绑定账户</text>
+        <view class="btn" @click="navigateTo('/pages_module/bindingCard/index')"
+          >去绑定</view
+        >
+      </view>
+    </template>
+    <template v-else>
+      <view class="receiving-box">
+        <view class="receiving-title">已绑定账户</view>
+        <viwe class="receiving-card">
+          <view class="card-box">
+            <view class="card-title">
+              <text>{{ bankName }}</text>
+              <tui-icon
+                name="evaluate"
+                color="#FFFFFF"
+                :size="20"
+                @click="goBankCard(1)"
+              ></tui-icon>
+            </view>
+            <view class="card-eye">
+              <text>{{ cardNumber }}</text>
+              <template v-if="showEye">
+                <tui-icon
+                  name="seen"
+                  :size="20"
+                  color="#FFFFFF"
+                  @click="changeIcon(false)"
+                ></tui-icon>
+              </template>
+              <template v-else>
+                <tui-icon
+                  name="unseen"
+                  :size="20"
+                  color="#FFFFFF"
+                  @click="changeIcon(true)"
+                ></tui-icon>
+              </template>
+            </view>
+            <view class="card-prople">
+              <text>持卡人</text>
+              <text>{{ receivingInfo.cardName }}</text>
+            </view>
+          </view>
+        </viwe>
+      </view>
+    </template>
+  </view>
+</template>
+
+<script>
+import { getReceiving, getSelect } from "@/config/index.js";
+export default {
+  created() {
+    this.getBankAll();
+  },
+  onShow(){
+    this.getAccount();
+  },
+  data() {
+    return {
+      receivingInfo: {},
+      bankList: [],
+      cardNumber: "",
+      //    控制眼睛
+      showEye: true,
+    };
+  },
+  computed: {
+    bankName() {
+      return this.bankList.filter((item) => {
+        return item.dictId == this.receivingInfo.bank;
+      })[0]?.dictName;
+    },
+  },
+  methods: {
+    //  获取收款商户
+    async getAccount() {
+      let { data } = await getReceiving({});
+      this.receivingInfo = data;
+      if(Object.keys(data).length <= 0) return
+      //    调用函数返回隐藏的字符
+      this.cardNumber = this.convert(data.cardNumber, false);
+    },
+    //  获取所有银行
+    async getBankAll() {
+      let { data } = await getSelect({ dictName: "所属银行" });
+      this.bankList = data;
+    },
+    //  小眼睛切换
+    changeIcon(flag) {
+      this.showEye = flag;
+      this.cardNumber = this.convert(this.receivingInfo.cardNumber);
+    },
+    //  转换银行卡符号
+    convert(str) {
+      let lastFour = str.slice(-4);
+      if (this.showEye) {
+        let maskedStr = `${"*".repeat(str.length - 4)} ${lastFour}`;
+        let card1 = maskedStr
+          .split(" ")[0]
+          .replace(/(.{4})/g, (match) => `${match} `);
+        let card2 = maskedStr.split(" ")[1];
+        return `${card1} ${card2}`;
+      } else {
+        //  不截取后面四位
+        let numStr = str.slice(0, str.length - 4);
+        let card1 = numStr.replace(/(.{4})/g, (match) => `${match} `);
+        return `${card1} ${lastFour}`;
+      }
+    },
+    //  跳转到编辑银行卡
+    goBankCard(type) {
+      uni.navigateTo({
+        url: `/pages_module/bindingCard/index?type=${type}`,
+      });
+      let obj = {...this.receivingInfo};
+      obj.dictName = this.bankName
+      //    本地存储银行卡信息
+      uni.setStorageSync("bankInfo", obj);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 7 - 3
pages_module/scanCode/index.vue

@@ -198,9 +198,13 @@ export default {
       });
     },
     backClick() {
-      // uni.navigateBack()
-      uni.switchTab({
-        url: "/pages/tabbar/index/index",
+      uni.navigateBack({
+        delta: 1,
+        fail: () => {
+            uni.switchTab({
+              url: "/pages/tabbar/index/index",
+            });
+        },
       });
     },
   },

+ 137 - 110
pages_module/scanCoupons/index.vue

@@ -1,139 +1,166 @@
 <template>
-    <view class="scanCoupons">
-        <capsule :showBorder="true" bgColor="#FFFFFF">
-            <template v-slot:top>
-                <view class="shop-top">
-                    <view class="back-icon" @click="backClick">
-                        <tui-icon name="arrowleft" :size="42" color="#000000"></tui-icon>
-                    </view>
-                    <view class="shop-name">{{ shopInfo.shopName }}</view>
-                </view>
-            </template>
-        </capsule>
-        <view class="seat"></view>
-        <view class="ipt">
-            <view class="ipt-box">
-                <template v-if="iptValue == ''">
-                    <view class="ipt-empty">请输入劵码</view>
-                </template>
-                <template v-else>
-                    <view class="ipt-code">{{ iptValue }}</view>
-                </template>
-            </view>
-        </view>
-        <view class="footer">
-            <keyboard :iptValue='iptValue' @single="singleWord" @deleteOne="deleteOne" @deleteAll="this.iptValue = ''">
-            </keyboard>
+  <view class="scanCoupons">
+    <capsule :showBorder="true" bgColor="#FFFFFF">
+      <template v-slot:top>
+        <view class="shop-top">
+          <view class="back-icon" @click="backClick">
+            <tui-icon name="arrowleft" :size="42" color="#000000"></tui-icon>
+          </view>
+          <view class="shop-name">{{ shopInfo.shopName }}</view>
         </view>
+      </template>
+    </capsule>
+    <view class="seat"></view>
+    <view class="ipt">
+      <view class="ipt-box">
+        <template v-if="iptValue == ''">
+          <view class="ipt-empty">请输入劵码</view>
+        </template>
+        <template v-else>
+          <view class="ipt-code">{{ iptValue }}</view>
+        </template>
+      </view>
+    </view>
+    <view class="footer">
+      <keyboard
+        :iptValue="iptValue"
+        @single="singleWord"
+        @deleteOne="deleteOne"
+        @deleteAll="this.iptValue = ''"
+        @setVerifica="setVerifica"
+      >
+      </keyboard>
     </view>
+  </view>
 </template>
 
 <script>
+import { getCoupons } from "@/config/index";
 export default {
-    created() {
-        //  获取本地存储的店铺数据
-        this.shopInfo = uni.getStorageSync('shopInfo')
+  created() {
+    //  获取本地存储的店铺数据
+    this.shopInfo = uni.getStorageSync("shopInfo");
+  },
+  data() {
+    return {
+      shopInfo: {},
+      iptValue: "",
+    };
+  },
+  methods: {
+    backClick() {
+      uni.navigateBack({
+        delta: 1,
+        fail: () => {
+            uni.switchTab({
+              url: "/pages/tabbar/index/index",
+            });
+        },
+      });
     },
-    data() {
-        return {
-            shopInfo: {},
-            iptValue: '',
-        }
+    //  修改单个验劵码
+    singleWord(val) {
+      this.iptValue = `${this.iptValue}${val}`;
     },
-    methods: {
-        backClick() {
-            uni.navigateBack()
-        },
-        //  修改单个验劵码
-        singleWord(val) {
-            this.iptValue = `${this.iptValue}${val}`
-        },
-        //  删除单个字符
-        deleteOne() {
-            this.iptValue = this.iptValue.slice(0, this.iptValue.length - 1)
-        },
+    //  验劵
+    async setVerifica() {
+      if (this.iptValue == "") {
+        this.$showToast("请输入劵码");
+        return;
+      }
+      let {data} = await getCoupons({ writeCode: this.iptValue });
+      //  传递值过去
+      uni.navigateTo({
+          url: `/pages_module/orderVerifica/index?orderId=${data.orderId}&code=${data.writeCode}`,
+        });
+      console.log(res);
     },
-}
+    //  删除单个字符
+    deleteOne() {
+      this.iptValue = this.iptValue.slice(0, this.iptValue.length - 1);
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
 .scanCoupons {
-    width: 100%;
-    height: 100vh;
-    background-color: rgb(241, 241, 241);
-
-    .shop-top {
-        width: 100%;
-        height: 100%;
-        position: relative;
-        z-index: 999;
-        @include flex(center);
+  width: 100%;
+  height: 100vh;
+  background-color: rgb(241, 241, 241);
 
-        .back-icon {
-            position: absolute;
-            left: 0;
-            top: 50%;
-            transform: translateY(-50%);
-        }
+  .shop-top {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    z-index: 999;
+    @include flex(center);
 
-        .shop-name {
-            color: #000000;
-        }
+    .back-icon {
+      position: absolute;
+      left: 0;
+      top: 50%;
+      transform: translateY(-50%);
     }
 
-    .seat {
-        width: 100%;
-        height: 30rpx;
-        background-color: #FFFFFF;
+    .shop-name {
+      color: #000000;
     }
+  }
 
-    .ipt {
-        margin-top: 50rpx;
-        width: 100%;
+  .seat {
+    width: 100%;
+    height: 30rpx;
+    background-color: #ffffff;
+  }
 
-        .ipt-box {
-            width: 686rpx;
-            height: 108rpx;
-            background-color: #FFFFFF;
-            margin: 0 auto;
-            box-sizing: border-box;
-            padding: 32rpx 0 32rpx 38rpx;
-            border-radius: 16rpx;
+  .ipt {
+    margin-top: 50rpx;
+    width: 100%;
 
-            .ipt-empty {
-                color: #999999;
-                font-size: 36rpx;
-                position: relative;
+    .ipt-box {
+      width: 686rpx;
+      height: 108rpx;
+      background-color: #ffffff;
+      margin: 0 auto;
+      box-sizing: border-box;
+      padding: 32rpx 0 32rpx 38rpx;
+      border-radius: 16rpx;
 
-                &::after {
-                    content: '';
-                    width: 6rpx;
-                    height: 80%;
-                    background-color: #EF530E;
-                    position: absolute;
-                    left: -14rpx;
-                    top: 60%;
-                    transform: translateY(-60%);
-                }
-            }
+      .ipt-empty {
+        color: #999999;
+        font-size: 36rpx;
+        position: relative;
 
-            .ipt-code {
-                width: 100%;
-                overflow-x: scroll;
-                color: #333333;
-                font-size: 36rpx;
-            }
+        &::after {
+          content: "";
+          width: 6rpx;
+          height: 80%;
+          background-color: #ef530e;
+          position: absolute;
+          left: -14rpx;
+          top: 60%;
+          transform: translateY(-60%);
         }
-    }
+      }
 
-    .footer {
-        position: fixed;
-        left: 0;
-        bottom: 0;
+      .ipt-code {
         width: 100%;
-        /*  底部安全区域 */
-        padding-bottom: constant(safe-area-inset-bottom); //兼容 IOS<11.2
-        padding-bottom: env(safe-area-inset-bottom); //兼容 IOS>11.2
+        overflow-x: scroll;
+        color: #333333;
+        font-size: 36rpx;
+      }
     }
+  }
+
+  .footer {
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    /*  底部安全区域 */
+    padding-bottom: constant(safe-area-inset-bottom); //兼容 IOS<11.2
+    padding-bottom: env(safe-area-inset-bottom); //兼容 IOS>11.2
+  }
 }
-</style>
+</style>

+ 57 - 0
pages_module/walSuccess/index.vue

@@ -0,0 +1,57 @@
+<template>
+    <view class="changeSuccess">
+      <view class="container">
+        <image class="" src="@/static/image/code/success.png" />
+        <view class="text">已成功申请提现!!!</view>
+        <view class="back" @click="goLogin">返回</view>
+      </view>
+    </view>
+  </template>
+  
+  <script>
+  export default {
+    methods: {
+      goLogin() {
+        uni.redirectTo({
+          url: "/pages_module/financial/index",
+        });
+      },
+    },
+  };
+  </script>
+  
+  <style lang="scss" scoped>
+  .changeSuccess {
+    width: 100vw;
+    min-height: 100vh;
+    background-color: #ffffff;
+    position: relative;
+    .container {
+      position: absolute;
+      top: 200rpx;
+      left: 50%;
+      transform: translateX(-50%);
+      @include flex(center, column, 52rpx);
+      image {
+        width: 280rpx;
+        height: 280rpx;
+        display: block;
+      }
+      .text {
+        font-size: 28rpx;
+        color: #666666;
+      }
+      .back {
+        width: 226rpx;
+        height: 88rpx;
+        text-align: center;
+        line-height: 88rpx;
+        font-size: 28rpx;
+        color: rgba(0, 0, 0, 0.9);
+        border: 2rpx solid #e7e7e7;
+        border-radius: 200rpx;
+      }
+    }
+  }
+  </style>
+  

+ 188 - 0
pages_module/withdrawal/index.scss

@@ -0,0 +1,188 @@
+.withdrawal {
+  width: 100vw;
+  min-height: 100vh;
+  background-color: rgb(247, 247, 247);
+  padding: 32rpx;
+  padding-bottom: 50rpx;
+  box-sizing: border-box;
+  .withdrawal-box {
+    width: 100%;
+    height: 192rpx;
+    background-color: #ffffff;
+    border-radius: 16rpx;
+    padding: 32rpx;
+    box-sizing: border-box;
+    position: relative;
+    .box-text {
+      height: 100%;
+      @include flex(space-between, column);
+      align-items: flex-start;
+      text {
+        &:nth-of-type(1) {
+          color: rgba(0, 0, 0, 0.4);
+          font-size: 32rpx;
+          font-weight: 600;
+        }
+        &:nth-of-type(2) {
+          color: #ea5c1e;
+          font-size: 48rpx;
+          font-weight: 900;
+        }
+      }
+    }
+    .goWithd {
+      position: absolute;
+      top: 50%;
+      transform: translateY(-50%);
+      right: 38rpx;
+      width: 148rpx;
+      height: 60rpx;
+      border-radius: 30rpx;
+      text-align: center;
+      line-height: 60rpx;
+      background: linear-gradient(180deg, #fe4b1e 0%, #fb8857 100%);
+      color: #ffffff;
+      font-size: 28rpx;
+    }
+  }
+  .prompt {
+    margin-top: 8rpx;
+    margin-bottom: 32rpx;
+    font-size: 20rpx;
+    color: rgba(0, 0, 0, 0.4);
+  }
+  .withdrawal-container {
+    .withdrawal-title {
+      margin-bottom: 16rpx;
+      text {
+        color: rgba(0, 0, 0, 0.9);
+        font-size: 32rpx;
+        font-weight: 600;
+      }
+    }
+    .withdrawal-list {
+      padding: 0 32rpx;
+      background-color: #ffffff;
+      border-radius: 16rpx;
+      .list-item {
+        width: 100%;
+        height: 168rpx;
+        padding: 32rpx 0;
+        @include flex(space-between, null);
+        border-bottom: 2rpx solid #e7e7e7;
+        box-sizing: border-box;
+        .item-text {
+          height: 100%;
+          @include flex(space-between, column);
+          align-items: flex-start;
+          text {
+            &:nth-of-type(1) {
+              color: rgba(0, 0, 0, 0.9);
+              font-size: 32rpx;
+              font-weight: 600;
+            }
+            &:nth-of-type(2) {
+              color: rgba(0, 0, 0, 0.4);
+              font-size: 28rpx;
+            }
+          }
+        }
+        .item-price {
+          color: #ea5c1e;
+          font-weight: 900;
+          font-size: 28rpx;
+        }
+      }
+    }
+  }
+  .popup-container {
+    width: 100%;
+    padding: 0 32rpx;
+    box-sizing: border-box;
+    padding-bottom: 50rpx;
+    .popup-title {
+      margin-top: 48rpx;
+      text-align: center;
+      color: rgba(0, 0, 0, 0.9);
+      font-size: 32rpx;
+      font-weight: 600;
+    }
+    .popup-type {
+      margin-top: 32rpx;
+      .type-title {
+        color: rgba(0, 0, 0, 0.9);
+        font-size: 28rpx;
+        font-weight: 600;
+        margin-bottom: 16rpx;
+      }
+      .type-btn {
+        @include flex(flex-start, null, 32rpx);
+        .btn-box {
+          padding: 16rpx 32rpx;
+          font-size: 24rpx;
+          color: #444444;
+          border: 2rpx solid #c9c9c9;
+          box-sizing: border-box;
+          border-radius: 8rpx;
+        }
+        .active {
+          background-color: rgba(254, 75, 30, 0.1);
+          border-color: #fe4b1e;
+          color: #fe4b1e;
+        }
+      }
+    }
+    .popup-amount {
+      @include flex(flex-start, null, 16rpx);
+      margin-top: 40rpx;
+      margin-bottom: 32rpx;
+      text {
+        &:nth-of-type(1) {
+          color: rgba(0, 0, 0, 0.9);
+          font-size: 28rpx;
+          font-weight: 600;
+        }
+        &:nth-of-type(2) {
+          color: rgba(0, 0, 0, 0.4);
+          font-size: 24rpx;
+        }
+      }
+    }
+    .popup-ipt {
+      .ipt-left {
+        color: rgba(0, 0, 0, 0.9);
+        font-weight: 600;
+        font-size: 64rpx;
+      }
+      .ipt-right {
+        color: #ea5c1e;
+        font-size: 28rpx;
+      }
+    }
+    .popup-to {
+      margin-top: 32rpx;
+      margin-bottom: 48rpx;
+      @include flex(space-between, null, null);
+      text {
+        color: rgba(0, 0, 0, 0.9);
+        font-size: 28rpx;
+      }
+    }
+    .popup-btn {
+      width: 100%;
+      height: 96rpx;
+      background-color: #fe4b1e;
+      text-align: center;
+      line-height: 96rpx;
+      color: #ffffff;
+      font-size: 32rpx;
+      font-weight: 500;
+      border-radius: 16rpx;
+    }
+  }
+
+  ::v-deep .tui-input__self {
+    height: 72rpx;
+    caret-color: #ea5c1e;
+  }
+}

+ 221 - 0
pages_module/withdrawal/index.vue

@@ -0,0 +1,221 @@
+<template>
+  <view class="withdrawal">
+    <view class="withdrawal-box">
+      <view class="box-text">
+        <text>可提现金额</text>
+        <text>{{ balance }}</text>
+      </view>
+      <view class="goWithd" @click="goWithdClick">去提现</view>
+    </view>
+    <view class="prompt"
+      >注:可提现金额已扣除赠送会员代金券金额中的50%费用</view
+    >
+    <view class="withdrawal-container">
+      <view class="withdrawal-title">
+        <text>提现记录</text>
+      </view>
+      <view class="withdrawal-list">
+        <view
+          class="list-item"
+          v-for="(item, index) in withdrawalList"
+          :key="index"
+        >
+          <view class="item-text">
+            <text v-if="item.state == 1">已处理</text>
+            <text v-else-if="item.state == 2">通过</text>
+            <text v-else-if="item.state == 3">拒绝</text>
+            <text v-else-if="item.state == 4">待确认</text>
+            <!-- 0-待处理 1-已处理 2-通过 3-拒绝 4-待确认 -->
+            <text>{{ item.applyTime }}</text>
+          </view>
+          <view class="item-price">{{ item.withdrawalMoney }}</view>
+        </view>
+      </view>
+    </view>
+    <tui-bottom-popup
+      :zIndex="1000"
+      backgroundColor="#FFFFFF"
+      :show="showPopup"
+      @close="clonePopup"
+    >
+      <view class="popup-container">
+        <view class="popup-title">提现</view>
+        <view class="popup-type">
+          <view class="type-title">提现类型</view>
+          <view class="type-btn">
+            <view
+              class="btn-box"
+              :class="popupIdx == 1 ? 'active' : ''"
+              @click="changeIdx(1)"
+              >正常支付订单</view
+            >
+            <view
+              class="btn-box"
+              :class="popupIdx == 2 ? 'active' : ''"
+              @click="changeIdx(2)"
+              >交易金</view
+            >
+          </view>
+        </view>
+        <view class="popup-amount">
+          <text>提现金额</text>
+          <text>{{ popupText }}</text>
+        </view>
+        <view class="popup-ipt">
+          <tui-input
+            type="number"
+            :focus="true"
+            :size="64"
+            padding="16rpx 0rpx"
+            :disabled="true"
+            v-model="applyInfo.withdrawalMoney"
+          >
+            <template #left>
+              <view class="ipt-left">¥</view>
+            </template>
+            <template #right>
+              <view class="ipt-right" @click="allRawal">全部提现</view>
+            </template>
+          </tui-input>
+        </view>
+        <view class="popup-to">
+          <text>提现至</text>
+          <text>{{
+            `${bankInfo.bankName}(${
+              bankInfo.bankCard ? bankInfo.bankCard.slice(-4) : ""
+            })`
+          }}</text>
+        </view>
+        <view class="popup-btn" @click="confirmBtn">确认申请提现</view>
+      </view>
+    </tui-bottom-popup>
+  </view>
+</template>
+
+<script>
+import { getWithdrawal, financeBank, applyWithdrawal } from "@/config/index";
+export default {
+  onLoad(props) {
+    //  余额
+    this.balance = props.balance;
+    //  交易金
+    this.trading = props.trading;
+  },
+  onShow() {
+    this.getAll();
+  },
+  computed: {
+    popupText() {
+      //  可提现{{ popupIdx == 1 ? "金额" : "交易金余额" }}:8483元
+      if (this.popupIdx == 1) {
+        return `可提现金额余额${this.balance}元`;
+      } else {
+        return `可提交易金余额${this.trading}元`;
+      }
+    },
+  },
+  data() {
+    return {
+      balance: "",
+      trading: "",
+      queryData: {
+        page: 1,
+        pageSize: 10,
+      },
+      //  提现记录列表
+      withdrawalList: [],
+      //  底部弹框控制
+      showPopup: false,
+      popupIdx: 1,
+      // 弹窗的信息
+      bankInfo: {},
+      // 提现请求信息
+      applyInfo: {
+        bankCard: "",
+        bankName: "",
+        shopCode: "",
+        shopName: "",
+        withdrawalMoney: "",
+        withdrawalType: "",
+      },
+    };
+  },
+  methods: {
+    async getAll() {
+      let { data } = await getWithdrawal(this.queryData);
+      this.withdrawalList = [...this.withdrawalList, ...data];
+      console.log(data);
+    },
+    //  去提现点击事件
+    async goWithdClick() {
+      this.showPopup = true;
+      //  获取 bankInfo
+      let { data } = await financeBank({});
+      this.applyInfo.withdrawalMoney = this.balance;
+      this.bankInfo = data;
+    },
+    //  确认申请提现
+    async confirmBtn() {
+      //  对数据进行判断
+      if (
+        this.applyInfo.withdrawalMoney >
+        (this.popupIdx === 1 ? this.balance : this.trading)
+      ) {
+        this.$showToast("提现金额不能大于余额");
+        return;
+      }
+      let { bankCard, bankName, shopCode, shopName } = this.bankInfo;
+      //  对提交的信息进行处理
+      this.applyInfo = {
+        bankCard,
+        bankName,
+        shopCode,
+        shopName,
+        withdrawalMoney: this.applyInfo.withdrawalMoney,
+        withdrawalType: this.popupIdx == 1 ? "1" : "2",
+      };
+
+      this.$loading.show("申请提现中");
+      try {
+        let res = await applyWithdrawal(this.applyInfo);
+        if (res.code == "") {
+          uni.redirectTo({
+            url: "/pages_module/walSuccess/index",
+          });
+        }
+      } finally {
+        this.$loading.hide();
+      }
+    },
+    //  提现类型点击
+    changeIdx(val) {
+      this.popupIdx = val;
+      if (val == 1) {
+        this.applyInfo.withdrawalMoney = this.balance;
+      } else if (val == 2) {
+        this.applyInfo.withdrawalMoney = this.trading;
+      }
+    },
+
+    //  全部提现点击
+    allRawal() {
+      this.applyInfo.withdrawalMoney =
+        this.popupIdx == 1 ? this.balance : this.trading;
+    },
+    // 关闭弹框事件
+    clonePopup() {
+      this.showPopup = false;
+    },
+  },
+  //  触底加载
+  onReachBottom() {
+    if (this.withdrawalList.length < 10) return;
+    this.queryData.page++;
+    this.getAll();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

BIN
static/image/home/bg_index.png


BIN
static/image/order/complete_icon.png


BIN
static/image/order/error_icon.png


BIN
static/image/order/search-empty.png


BIN
static/image/order/success_icon.png


BIN
static/image/user/business_phone.png


BIN
static/image/user/business_user.png


BIN
static/image/user/code.png


BIN
static/image/user/header-bg.png


BIN
static/image/user/logo.png


BIN
static/image/user/pay_1.png


BIN
static/image/user/pay_2.png


BIN
static/image/user/pay_3.png


BIN
static/image/user/pay_4.png


BIN
static/image/user/pay_5.png


BIN
static/image/user/pay_6.png


+ 0 - 907
static/js/qrcode.js

@@ -1,907 +0,0 @@
-/**
- * weapp.qrcode.js v1.0.0 (https://github.com/yingye/weapp-qrcode#readme)
- */
-
-var hasOwn = Object.prototype.hasOwnProperty,
-  toStr = Object.prototype.toString,
-  defineProperty = Object.defineProperty,
-  gOPD = Object.getOwnPropertyDescriptor,
-  isArray = function (t) {
-    return "function" == typeof Array.isArray
-      ? Array.isArray(t)
-      : "[object Array]" === toStr.call(t);
-  },
-  isPlainObject = function (t) {
-    if (!t || "[object Object]" !== toStr.call(t)) return !1;
-    var e,
-      r = hasOwn.call(t, "constructor"),
-      o =
-        t.constructor &&
-        t.constructor.prototype &&
-        hasOwn.call(t.constructor.prototype, "isPrototypeOf");
-    if (t.constructor && !r && !o) return !1;
-    for (e in t);
-    return void 0 === e || hasOwn.call(t, e);
-  },
-  setProperty = function (t, e) {
-    defineProperty && "__proto__" === e.name
-      ? defineProperty(t, e.name, {
-          enumerable: !0,
-          configurable: !0,
-          value: e.newValue,
-          writable: !0,
-        })
-      : (t[e.name] = e.newValue);
-  },
-  getProperty = function (t, e) {
-    if ("__proto__" === e) {
-      if (!hasOwn.call(t, e)) return;
-      if (gOPD) return gOPD(t, e).value;
-    }
-    return t[e];
-  },
-  extend = function t() {
-    var e,
-      r,
-      o,
-      n,
-      i,
-      a,
-      s = arguments[0],
-      u = 1,
-      l = arguments.length,
-      h = !1;
-    for (
-      "boolean" == typeof s && ((h = s), (s = arguments[1] || {}), (u = 2)),
-        (null == s || ("object" != typeof s && "function" != typeof s)) &&
-          (s = {});
-      u < l;
-      ++u
-    )
-      if (null != (e = arguments[u]))
-        for (r in e)
-          (o = getProperty(s, r)),
-            s !== (n = getProperty(e, r)) &&
-              (h && n && (isPlainObject(n) || (i = isArray(n)))
-                ? (i
-                    ? ((i = !1), (a = o && isArray(o) ? o : []))
-                    : (a = o && isPlainObject(o) ? o : {}),
-                  setProperty(s, { name: r, newValue: t(h, a, n) }))
-                : void 0 !== n && setProperty(s, { name: r, newValue: n }));
-    return s;
-  };
-function QR8bitByte(t) {
-  (this.mode = QRMode.MODE_8BIT_BYTE), (this.data = t);
-}
-function QRCode(t, e) {
-  (this.typeNumber = t),
-    (this.errorCorrectLevel = e),
-    (this.modules = null),
-    (this.moduleCount = 0),
-    (this.dataCache = null),
-    (this.dataList = new Array());
-}
-(QR8bitByte.prototype = {
-  getLength: function (t) {
-    return this.data.length;
-  },
-  write: function (t) {
-    for (var e = 0; e < this.data.length; e++)
-      t.put(this.data.charCodeAt(e), 8);
-  },
-}),
-  (QRCode.prototype = {
-    addData: function (t) {
-      var e = new QR8bitByte(t);
-      this.dataList.push(e), (this.dataCache = null);
-    },
-    isDark: function (t, e) {
-      if (t < 0 || this.moduleCount <= t || e < 0 || this.moduleCount <= e)
-        throw new Error(t + "," + e);
-      return this.modules[t][e];
-    },
-    getModuleCount: function () {
-      return this.moduleCount;
-    },
-    make: function () {
-      if (this.typeNumber < 1) {
-        var t = 1;
-        for (t = 1; t < 40; t++) {
-          for (
-            var e = QRRSBlock.getRSBlocks(t, this.errorCorrectLevel),
-              r = new QRBitBuffer(),
-              o = 0,
-              n = 0;
-            n < e.length;
-            n++
-          )
-            o += e[n].dataCount;
-          for (n = 0; n < this.dataList.length; n++) {
-            var i = this.dataList[n];
-            r.put(i.mode, 4),
-              r.put(i.getLength(), QRUtil.getLengthInBits(i.mode, t)),
-              i.write(r);
-          }
-          if (r.getLengthInBits() <= 8 * o) break;
-        }
-        this.typeNumber = t;
-      }
-      this.makeImpl(!1, this.getBestMaskPattern());
-    },
-    makeImpl: function (t, e) {
-      (this.moduleCount = 4 * this.typeNumber + 17),
-        (this.modules = new Array(this.moduleCount));
-      for (var r = 0; r < this.moduleCount; r++) {
-        this.modules[r] = new Array(this.moduleCount);
-        for (var o = 0; o < this.moduleCount; o++) this.modules[r][o] = null;
-      }
-      this.setupPositionProbePattern(0, 0),
-        this.setupPositionProbePattern(this.moduleCount - 7, 0),
-        this.setupPositionProbePattern(0, this.moduleCount - 7),
-        this.setupPositionAdjustPattern(),
-        this.setupTimingPattern(),
-        this.setupTypeInfo(t, e),
-        this.typeNumber >= 7 && this.setupTypeNumber(t),
-        null == this.dataCache &&
-          (this.dataCache = QRCode.createData(
-            this.typeNumber,
-            this.errorCorrectLevel,
-            this.dataList
-          )),
-        this.mapData(this.dataCache, e);
-    },
-    setupPositionProbePattern: function (t, e) {
-      for (var r = -1; r <= 7; r++)
-        if (!(t + r <= -1 || this.moduleCount <= t + r))
-          for (var o = -1; o <= 7; o++)
-            e + o <= -1 ||
-              this.moduleCount <= e + o ||
-              (this.modules[t + r][e + o] =
-                (0 <= r && r <= 6 && (0 == o || 6 == o)) ||
-                (0 <= o && o <= 6 && (0 == r || 6 == r)) ||
-                (2 <= r && r <= 4 && 2 <= o && o <= 4));
-    },
-    getBestMaskPattern: function () {
-      for (var t = 0, e = 0, r = 0; r < 8; r++) {
-        this.makeImpl(!0, r);
-        var o = QRUtil.getLostPoint(this);
-        (0 == r || t > o) && ((t = o), (e = r));
-      }
-      return e;
-    },
-    createMovieClip: function (t, e, r) {
-      var o = t.createEmptyMovieClip(e, r);
-      this.make();
-      for (var n = 0; n < this.modules.length; n++)
-        for (var i = 1 * n, a = 0; a < this.modules[n].length; a++) {
-          var s = 1 * a;
-          this.modules[n][a] &&
-            (o.beginFill(0, 100),
-            o.moveTo(s, i),
-            o.lineTo(s + 1, i),
-            o.lineTo(s + 1, i + 1),
-            o.lineTo(s, i + 1),
-            o.endFill());
-        }
-      return o;
-    },
-    setupTimingPattern: function () {
-      for (var t = 8; t < this.moduleCount - 8; t++)
-        null == this.modules[t][6] && (this.modules[t][6] = t % 2 == 0);
-      for (var e = 8; e < this.moduleCount - 8; e++)
-        null == this.modules[6][e] && (this.modules[6][e] = e % 2 == 0);
-    },
-    setupPositionAdjustPattern: function () {
-      for (
-        var t = QRUtil.getPatternPosition(this.typeNumber), e = 0;
-        e < t.length;
-        e++
-      )
-        for (var r = 0; r < t.length; r++) {
-          var o = t[e],
-            n = t[r];
-          if (null == this.modules[o][n])
-            for (var i = -2; i <= 2; i++)
-              for (var a = -2; a <= 2; a++)
-                this.modules[o + i][n + a] =
-                  -2 == i || 2 == i || -2 == a || 2 == a || (0 == i && 0 == a);
-        }
-    },
-    setupTypeNumber: function (t) {
-      for (
-        var e = QRUtil.getBCHTypeNumber(this.typeNumber), r = 0;
-        r < 18;
-        r++
-      ) {
-        var o = !t && 1 == ((e >> r) & 1);
-        this.modules[Math.floor(r / 3)][(r % 3) + this.moduleCount - 8 - 3] = o;
-      }
-      for (r = 0; r < 18; r++) {
-        o = !t && 1 == ((e >> r) & 1);
-        this.modules[(r % 3) + this.moduleCount - 8 - 3][Math.floor(r / 3)] = o;
-      }
-    },
-    setupTypeInfo: function (t, e) {
-      for (
-        var r = (this.errorCorrectLevel << 3) | e,
-          o = QRUtil.getBCHTypeInfo(r),
-          n = 0;
-        n < 15;
-        n++
-      ) {
-        var i = !t && 1 == ((o >> n) & 1);
-        n < 6
-          ? (this.modules[n][8] = i)
-          : n < 8
-          ? (this.modules[n + 1][8] = i)
-          : (this.modules[this.moduleCount - 15 + n][8] = i);
-      }
-      for (n = 0; n < 15; n++) {
-        i = !t && 1 == ((o >> n) & 1);
-        n < 8
-          ? (this.modules[8][this.moduleCount - n - 1] = i)
-          : n < 9
-          ? (this.modules[8][15 - n - 1 + 1] = i)
-          : (this.modules[8][15 - n - 1] = i);
-      }
-      this.modules[this.moduleCount - 8][8] = !t;
-    },
-    mapData: function (t, e) {
-      for (
-        var r = -1,
-          o = this.moduleCount - 1,
-          n = 7,
-          i = 0,
-          a = this.moduleCount - 1;
-        a > 0;
-        a -= 2
-      )
-        for (6 == a && a--; ; ) {
-          for (var s = 0; s < 2; s++)
-            if (null == this.modules[o][a - s]) {
-              var u = !1;
-              i < t.length && (u = 1 == ((t[i] >>> n) & 1)),
-                QRUtil.getMask(e, o, a - s) && (u = !u),
-                (this.modules[o][a - s] = u),
-                -1 == --n && (i++, (n = 7));
-            }
-          if ((o += r) < 0 || this.moduleCount <= o) {
-            (o -= r), (r = -r);
-            break;
-          }
-        }
-    },
-  }),
-  (QRCode.PAD0 = 236),
-  (QRCode.PAD1 = 17),
-  (QRCode.createData = function (t, e, r) {
-    for (
-      var o = QRRSBlock.getRSBlocks(t, e), n = new QRBitBuffer(), i = 0;
-      i < r.length;
-      i++
-    ) {
-      var a = r[i];
-      n.put(a.mode, 4),
-        n.put(a.getLength(), QRUtil.getLengthInBits(a.mode, t)),
-        a.write(n);
-    }
-    var s = 0;
-    for (i = 0; i < o.length; i++) s += o[i].dataCount;
-    if (n.getLengthInBits() > 8 * s)
-      throw new Error(
-        "code length overflow. (" + n.getLengthInBits() + ">" + 8 * s + ")"
-      );
-    for (
-      n.getLengthInBits() + 4 <= 8 * s && n.put(0, 4);
-      n.getLengthInBits() % 8 != 0;
-
-    )
-      n.putBit(!1);
-    for (
-      ;
-      !(
-        n.getLengthInBits() >= 8 * s ||
-        (n.put(QRCode.PAD0, 8), n.getLengthInBits() >= 8 * s)
-      );
-
-    )
-      n.put(QRCode.PAD1, 8);
-    return QRCode.createBytes(n, o);
-  }),
-  (QRCode.createBytes = function (t, e) {
-    for (
-      var r = 0,
-        o = 0,
-        n = 0,
-        i = new Array(e.length),
-        a = new Array(e.length),
-        s = 0;
-      s < e.length;
-      s++
-    ) {
-      var u = e[s].dataCount,
-        l = e[s].totalCount - u;
-      (o = Math.max(o, u)), (n = Math.max(n, l)), (i[s] = new Array(u));
-      for (var h = 0; h < i[s].length; h++) i[s][h] = 255 & t.buffer[h + r];
-      r += u;
-      var f = QRUtil.getErrorCorrectPolynomial(l),
-        g = new QRPolynomial(i[s], f.getLength() - 1).mod(f);
-      a[s] = new Array(f.getLength() - 1);
-      for (h = 0; h < a[s].length; h++) {
-        var c = h + g.getLength() - a[s].length;
-        a[s][h] = c >= 0 ? g.get(c) : 0;
-      }
-    }
-    var d = 0;
-    for (h = 0; h < e.length; h++) d += e[h].totalCount;
-    var R = new Array(d),
-      m = 0;
-    for (h = 0; h < o; h++)
-      for (s = 0; s < e.length; s++) h < i[s].length && (R[m++] = i[s][h]);
-    for (h = 0; h < n; h++)
-      for (s = 0; s < e.length; s++) h < a[s].length && (R[m++] = a[s][h]);
-    return R;
-  });
-for (
-  var QRMode = {
-      MODE_NUMBER: 1,
-      MODE_ALPHA_NUM: 2,
-      MODE_8BIT_BYTE: 4,
-      MODE_KANJI: 8,
-    },
-    QRErrorCorrectLevel = { L: 1, M: 0, Q: 3, H: 2 },
-    QRMaskPattern = {
-      PATTERN000: 0,
-      PATTERN001: 1,
-      PATTERN010: 2,
-      PATTERN011: 3,
-      PATTERN100: 4,
-      PATTERN101: 5,
-      PATTERN110: 6,
-      PATTERN111: 7,
-    },
-    QRUtil = {
-      PATTERN_POSITION_TABLE: [
-        [],
-        [6, 18],
-        [6, 22],
-        [6, 26],
-        [6, 30],
-        [6, 34],
-        [6, 22, 38],
-        [6, 24, 42],
-        [6, 26, 46],
-        [6, 28, 50],
-        [6, 30, 54],
-        [6, 32, 58],
-        [6, 34, 62],
-        [6, 26, 46, 66],
-        [6, 26, 48, 70],
-        [6, 26, 50, 74],
-        [6, 30, 54, 78],
-        [6, 30, 56, 82],
-        [6, 30, 58, 86],
-        [6, 34, 62, 90],
-        [6, 28, 50, 72, 94],
-        [6, 26, 50, 74, 98],
-        [6, 30, 54, 78, 102],
-        [6, 28, 54, 80, 106],
-        [6, 32, 58, 84, 110],
-        [6, 30, 58, 86, 114],
-        [6, 34, 62, 90, 118],
-        [6, 26, 50, 74, 98, 122],
-        [6, 30, 54, 78, 102, 126],
-        [6, 26, 52, 78, 104, 130],
-        [6, 30, 56, 82, 108, 134],
-        [6, 34, 60, 86, 112, 138],
-        [6, 30, 58, 86, 114, 142],
-        [6, 34, 62, 90, 118, 146],
-        [6, 30, 54, 78, 102, 126, 150],
-        [6, 24, 50, 76, 102, 128, 154],
-        [6, 28, 54, 80, 106, 132, 158],
-        [6, 32, 58, 84, 110, 136, 162],
-        [6, 26, 54, 82, 110, 138, 166],
-        [6, 30, 58, 86, 114, 142, 170],
-      ],
-      G15: 1335,
-      G18: 7973,
-      G15_MASK: 21522,
-      getBCHTypeInfo: function (t) {
-        for (
-          var e = t << 10;
-          QRUtil.getBCHDigit(e) - QRUtil.getBCHDigit(QRUtil.G15) >= 0;
-
-        )
-          e ^=
-            QRUtil.G15 <<
-            (QRUtil.getBCHDigit(e) - QRUtil.getBCHDigit(QRUtil.G15));
-        return ((t << 10) | e) ^ QRUtil.G15_MASK;
-      },
-      getBCHTypeNumber: function (t) {
-        for (
-          var e = t << 12;
-          QRUtil.getBCHDigit(e) - QRUtil.getBCHDigit(QRUtil.G18) >= 0;
-
-        )
-          e ^=
-            QRUtil.G18 <<
-            (QRUtil.getBCHDigit(e) - QRUtil.getBCHDigit(QRUtil.G18));
-        return (t << 12) | e;
-      },
-      getBCHDigit: function (t) {
-        for (var e = 0; 0 != t; ) e++, (t >>>= 1);
-        return e;
-      },
-      getPatternPosition: function (t) {
-        return QRUtil.PATTERN_POSITION_TABLE[t - 1];
-      },
-      getMask: function (t, e, r) {
-        switch (t) {
-          case QRMaskPattern.PATTERN000:
-            return (e + r) % 2 == 0;
-          case QRMaskPattern.PATTERN001:
-            return e % 2 == 0;
-          case QRMaskPattern.PATTERN010:
-            return r % 3 == 0;
-          case QRMaskPattern.PATTERN011:
-            return (e + r) % 3 == 0;
-          case QRMaskPattern.PATTERN100:
-            return (Math.floor(e / 2) + Math.floor(r / 3)) % 2 == 0;
-          case QRMaskPattern.PATTERN101:
-            return ((e * r) % 2) + ((e * r) % 3) == 0;
-          case QRMaskPattern.PATTERN110:
-            return (((e * r) % 2) + ((e * r) % 3)) % 2 == 0;
-          case QRMaskPattern.PATTERN111:
-            return (((e * r) % 3) + ((e + r) % 2)) % 2 == 0;
-          default:
-            throw new Error("bad maskPattern:" + t);
-        }
-      },
-      getErrorCorrectPolynomial: function (t) {
-        for (var e = new QRPolynomial([1], 0), r = 0; r < t; r++)
-          e = e.multiply(new QRPolynomial([1, QRMath.gexp(r)], 0));
-        return e;
-      },
-      getLengthInBits: function (t, e) {
-        if (1 <= e && e < 10)
-          switch (t) {
-            case QRMode.MODE_NUMBER:
-              return 10;
-            case QRMode.MODE_ALPHA_NUM:
-              return 9;
-            case QRMode.MODE_8BIT_BYTE:
-            case QRMode.MODE_KANJI:
-              return 8;
-            default:
-              throw new Error("mode:" + t);
-          }
-        else if (e < 27)
-          switch (t) {
-            case QRMode.MODE_NUMBER:
-              return 12;
-            case QRMode.MODE_ALPHA_NUM:
-              return 11;
-            case QRMode.MODE_8BIT_BYTE:
-              return 16;
-            case QRMode.MODE_KANJI:
-              return 10;
-            default:
-              throw new Error("mode:" + t);
-          }
-        else {
-          if (!(e < 41)) throw new Error("type:" + e);
-          switch (t) {
-            case QRMode.MODE_NUMBER:
-              return 14;
-            case QRMode.MODE_ALPHA_NUM:
-              return 13;
-            case QRMode.MODE_8BIT_BYTE:
-              return 16;
-            case QRMode.MODE_KANJI:
-              return 12;
-            default:
-              throw new Error("mode:" + t);
-          }
-        }
-      },
-      getLostPoint: function (t) {
-        for (var e = t.getModuleCount(), r = 0, o = 0; o < e; o++)
-          for (var n = 0; n < e; n++) {
-            for (var i = 0, a = t.isDark(o, n), s = -1; s <= 1; s++)
-              if (!(o + s < 0 || e <= o + s))
-                for (var u = -1; u <= 1; u++)
-                  n + u < 0 ||
-                    e <= n + u ||
-                    (0 == s && 0 == u) ||
-                    (a == t.isDark(o + s, n + u) && i++);
-            i > 5 && (r += 3 + i - 5);
-          }
-        for (o = 0; o < e - 1; o++)
-          for (n = 0; n < e - 1; n++) {
-            var l = 0;
-            t.isDark(o, n) && l++,
-              t.isDark(o + 1, n) && l++,
-              t.isDark(o, n + 1) && l++,
-              t.isDark(o + 1, n + 1) && l++,
-              (0 != l && 4 != l) || (r += 3);
-          }
-        for (o = 0; o < e; o++)
-          for (n = 0; n < e - 6; n++)
-            t.isDark(o, n) &&
-              !t.isDark(o, n + 1) &&
-              t.isDark(o, n + 2) &&
-              t.isDark(o, n + 3) &&
-              t.isDark(o, n + 4) &&
-              !t.isDark(o, n + 5) &&
-              t.isDark(o, n + 6) &&
-              (r += 40);
-        for (n = 0; n < e; n++)
-          for (o = 0; o < e - 6; o++)
-            t.isDark(o, n) &&
-              !t.isDark(o + 1, n) &&
-              t.isDark(o + 2, n) &&
-              t.isDark(o + 3, n) &&
-              t.isDark(o + 4, n) &&
-              !t.isDark(o + 5, n) &&
-              t.isDark(o + 6, n) &&
-              (r += 40);
-        var h = 0;
-        for (n = 0; n < e; n++) for (o = 0; o < e; o++) t.isDark(o, n) && h++;
-        return (r += 10 * (Math.abs((100 * h) / e / e - 50) / 5));
-      },
-    },
-    QRMath = {
-      glog: function (t) {
-        if (t < 1) throw new Error("glog(" + t + ")");
-        return QRMath.LOG_TABLE[t];
-      },
-      gexp: function (t) {
-        for (; t < 0; ) t += 255;
-        for (; t >= 256; ) t -= 255;
-        return QRMath.EXP_TABLE[t];
-      },
-      EXP_TABLE: new Array(256),
-      LOG_TABLE: new Array(256),
-    },
-    i = 0;
-  i < 8;
-  i++
-)
-  QRMath.EXP_TABLE[i] = 1 << i;
-for (i = 8; i < 256; i++)
-  QRMath.EXP_TABLE[i] =
-    QRMath.EXP_TABLE[i - 4] ^
-    QRMath.EXP_TABLE[i - 5] ^
-    QRMath.EXP_TABLE[i - 6] ^
-    QRMath.EXP_TABLE[i - 8];
-for (i = 0; i < 255; i++) QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
-function QRPolynomial(t, e) {
-  if (void 0 == t.length) throw new Error(t.length + "/" + e);
-  for (var r = 0; r < t.length && 0 == t[r]; ) r++;
-  this.num = new Array(t.length - r + e);
-  for (var o = 0; o < t.length - r; o++) this.num[o] = t[o + r];
-}
-function QRRSBlock(t, e) {
-  (this.totalCount = t), (this.dataCount = e);
-}
-function QRBitBuffer() {
-  (this.buffer = new Array()), (this.length = 0);
-}
-function utf16to8(t) {
-  var e, r, o, n;
-  for (e = "", o = t.length, r = 0; r < o; r++)
-    (n = t.charCodeAt(r)) >= 1 && n <= 127
-      ? (e += t.charAt(r))
-      : n > 2047
-      ? ((e += String.fromCharCode(224 | ((n >> 12) & 15))),
-        (e += String.fromCharCode(128 | ((n >> 6) & 63))),
-        (e += String.fromCharCode(128 | ((n >> 0) & 63))))
-      : ((e += String.fromCharCode(192 | ((n >> 6) & 31))),
-        (e += String.fromCharCode(128 | ((n >> 0) & 63))));
-  return e;
-}
-function drawQrcode(t) {
-  (t = t || {}),
-    (t = extend(
-      !0,
-      {
-        width: 256,
-        height: 256,
-        x: 0,
-        y: 0,
-        typeNumber: -1,
-        correctLevel: QRErrorCorrectLevel.H,
-        background: "#ffffff",
-        foreground: "#000000",
-        image: { imageResource: "", dx: 0, dy: 0, dWidth: 100, dHeight: 100 },
-      },
-      t
-    )).canvasId || t.ctx
-      ? (function () {
-          var e,
-            r = new QRCode(t.typeNumber, t.correctLevel);
-          r.addData(utf16to8(t.text)),
-            r.make(),
-            (e = t.ctx
-              ? t.ctx
-              : t._this
-              ? wx.createCanvasContext &&
-                wx.createCanvasContext(t.canvasId, t._this)
-              : wx.createCanvasContext && wx.createCanvasContext(t.canvasId));
-          for (
-            var o = t.width / r.getModuleCount(),
-              n = t.height / r.getModuleCount(),
-              i = 0;
-            i < r.getModuleCount();
-            i++
-          )
-            for (var a = 0; a < r.getModuleCount(); a++) {
-              var s = r.isDark(i, a) ? t.foreground : t.background;
-              e.setFillStyle(s);
-              var u = Math.ceil((a + 1) * o) - Math.floor(a * o),
-                l = Math.ceil((i + 1) * o) - Math.floor(i * o);
-              e.fillRect(
-                Math.round(a * o) + t.x,
-                Math.round(i * n) + t.y,
-                u,
-                l
-              );
-            }
-          t.image.imageResource &&
-            e.drawImage(
-              t.image.imageResource,
-              t.image.dx,
-              t.image.dy,
-              t.image.dWidth,
-              t.image.dHeight
-            );
-          e.draw(!1, function (e) {
-            t.callback && t.callback(e);
-          });
-        })()
-      : console.warn("please set canvasId or ctx!");
-}
-(QRPolynomial.prototype = {
-  get: function (t) {
-    return this.num[t];
-  },
-  getLength: function () {
-    return this.num.length;
-  },
-  multiply: function (t) {
-    for (
-      var e = new Array(this.getLength() + t.getLength() - 1), r = 0;
-      r < this.getLength();
-      r++
-    )
-      for (var o = 0; o < t.getLength(); o++)
-        e[r + o] ^= QRMath.gexp(
-          QRMath.glog(this.get(r)) + QRMath.glog(t.get(o))
-        );
-    return new QRPolynomial(e, 0);
-  },
-  mod: function (t) {
-    if (this.getLength() - t.getLength() < 0) return this;
-    for (
-      var e = QRMath.glog(this.get(0)) - QRMath.glog(t.get(0)),
-        r = new Array(this.getLength()),
-        o = 0;
-      o < this.getLength();
-      o++
-    )
-      r[o] = this.get(o);
-    for (o = 0; o < t.getLength(); o++)
-      r[o] ^= QRMath.gexp(QRMath.glog(t.get(o)) + e);
-    return new QRPolynomial(r, 0).mod(t);
-  },
-}),
-  (QRRSBlock.RS_BLOCK_TABLE = [
-    [1, 26, 19],
-    [1, 26, 16],
-    [1, 26, 13],
-    [1, 26, 9],
-    [1, 44, 34],
-    [1, 44, 28],
-    [1, 44, 22],
-    [1, 44, 16],
-    [1, 70, 55],
-    [1, 70, 44],
-    [2, 35, 17],
-    [2, 35, 13],
-    [1, 100, 80],
-    [2, 50, 32],
-    [2, 50, 24],
-    [4, 25, 9],
-    [1, 134, 108],
-    [2, 67, 43],
-    [2, 33, 15, 2, 34, 16],
-    [2, 33, 11, 2, 34, 12],
-    [2, 86, 68],
-    [4, 43, 27],
-    [4, 43, 19],
-    [4, 43, 15],
-    [2, 98, 78],
-    [4, 49, 31],
-    [2, 32, 14, 4, 33, 15],
-    [4, 39, 13, 1, 40, 14],
-    [2, 121, 97],
-    [2, 60, 38, 2, 61, 39],
-    [4, 40, 18, 2, 41, 19],
-    [4, 40, 14, 2, 41, 15],
-    [2, 146, 116],
-    [3, 58, 36, 2, 59, 37],
-    [4, 36, 16, 4, 37, 17],
-    [4, 36, 12, 4, 37, 13],
-    [2, 86, 68, 2, 87, 69],
-    [4, 69, 43, 1, 70, 44],
-    [6, 43, 19, 2, 44, 20],
-    [6, 43, 15, 2, 44, 16],
-    [4, 101, 81],
-    [1, 80, 50, 4, 81, 51],
-    [4, 50, 22, 4, 51, 23],
-    [3, 36, 12, 8, 37, 13],
-    [2, 116, 92, 2, 117, 93],
-    [6, 58, 36, 2, 59, 37],
-    [4, 46, 20, 6, 47, 21],
-    [7, 42, 14, 4, 43, 15],
-    [4, 133, 107],
-    [8, 59, 37, 1, 60, 38],
-    [8, 44, 20, 4, 45, 21],
-    [12, 33, 11, 4, 34, 12],
-    [3, 145, 115, 1, 146, 116],
-    [4, 64, 40, 5, 65, 41],
-    [11, 36, 16, 5, 37, 17],
-    [11, 36, 12, 5, 37, 13],
-    [5, 109, 87, 1, 110, 88],
-    [5, 65, 41, 5, 66, 42],
-    [5, 54, 24, 7, 55, 25],
-    [11, 36, 12],
-    [5, 122, 98, 1, 123, 99],
-    [7, 73, 45, 3, 74, 46],
-    [15, 43, 19, 2, 44, 20],
-    [3, 45, 15, 13, 46, 16],
-    [1, 135, 107, 5, 136, 108],
-    [10, 74, 46, 1, 75, 47],
-    [1, 50, 22, 15, 51, 23],
-    [2, 42, 14, 17, 43, 15],
-    [5, 150, 120, 1, 151, 121],
-    [9, 69, 43, 4, 70, 44],
-    [17, 50, 22, 1, 51, 23],
-    [2, 42, 14, 19, 43, 15],
-    [3, 141, 113, 4, 142, 114],
-    [3, 70, 44, 11, 71, 45],
-    [17, 47, 21, 4, 48, 22],
-    [9, 39, 13, 16, 40, 14],
-    [3, 135, 107, 5, 136, 108],
-    [3, 67, 41, 13, 68, 42],
-    [15, 54, 24, 5, 55, 25],
-    [15, 43, 15, 10, 44, 16],
-    [4, 144, 116, 4, 145, 117],
-    [17, 68, 42],
-    [17, 50, 22, 6, 51, 23],
-    [19, 46, 16, 6, 47, 17],
-    [2, 139, 111, 7, 140, 112],
-    [17, 74, 46],
-    [7, 54, 24, 16, 55, 25],
-    [34, 37, 13],
-    [4, 151, 121, 5, 152, 122],
-    [4, 75, 47, 14, 76, 48],
-    [11, 54, 24, 14, 55, 25],
-    [16, 45, 15, 14, 46, 16],
-    [6, 147, 117, 4, 148, 118],
-    [6, 73, 45, 14, 74, 46],
-    [11, 54, 24, 16, 55, 25],
-    [30, 46, 16, 2, 47, 17],
-    [8, 132, 106, 4, 133, 107],
-    [8, 75, 47, 13, 76, 48],
-    [7, 54, 24, 22, 55, 25],
-    [22, 45, 15, 13, 46, 16],
-    [10, 142, 114, 2, 143, 115],
-    [19, 74, 46, 4, 75, 47],
-    [28, 50, 22, 6, 51, 23],
-    [33, 46, 16, 4, 47, 17],
-    [8, 152, 122, 4, 153, 123],
-    [22, 73, 45, 3, 74, 46],
-    [8, 53, 23, 26, 54, 24],
-    [12, 45, 15, 28, 46, 16],
-    [3, 147, 117, 10, 148, 118],
-    [3, 73, 45, 23, 74, 46],
-    [4, 54, 24, 31, 55, 25],
-    [11, 45, 15, 31, 46, 16],
-    [7, 146, 116, 7, 147, 117],
-    [21, 73, 45, 7, 74, 46],
-    [1, 53, 23, 37, 54, 24],
-    [19, 45, 15, 26, 46, 16],
-    [5, 145, 115, 10, 146, 116],
-    [19, 75, 47, 10, 76, 48],
-    [15, 54, 24, 25, 55, 25],
-    [23, 45, 15, 25, 46, 16],
-    [13, 145, 115, 3, 146, 116],
-    [2, 74, 46, 29, 75, 47],
-    [42, 54, 24, 1, 55, 25],
-    [23, 45, 15, 28, 46, 16],
-    [17, 145, 115],
-    [10, 74, 46, 23, 75, 47],
-    [10, 54, 24, 35, 55, 25],
-    [19, 45, 15, 35, 46, 16],
-    [17, 145, 115, 1, 146, 116],
-    [14, 74, 46, 21, 75, 47],
-    [29, 54, 24, 19, 55, 25],
-    [11, 45, 15, 46, 46, 16],
-    [13, 145, 115, 6, 146, 116],
-    [14, 74, 46, 23, 75, 47],
-    [44, 54, 24, 7, 55, 25],
-    [59, 46, 16, 1, 47, 17],
-    [12, 151, 121, 7, 152, 122],
-    [12, 75, 47, 26, 76, 48],
-    [39, 54, 24, 14, 55, 25],
-    [22, 45, 15, 41, 46, 16],
-    [6, 151, 121, 14, 152, 122],
-    [6, 75, 47, 34, 76, 48],
-    [46, 54, 24, 10, 55, 25],
-    [2, 45, 15, 64, 46, 16],
-    [17, 152, 122, 4, 153, 123],
-    [29, 74, 46, 14, 75, 47],
-    [49, 54, 24, 10, 55, 25],
-    [24, 45, 15, 46, 46, 16],
-    [4, 152, 122, 18, 153, 123],
-    [13, 74, 46, 32, 75, 47],
-    [48, 54, 24, 14, 55, 25],
-    [42, 45, 15, 32, 46, 16],
-    [20, 147, 117, 4, 148, 118],
-    [40, 75, 47, 7, 76, 48],
-    [43, 54, 24, 22, 55, 25],
-    [10, 45, 15, 67, 46, 16],
-    [19, 148, 118, 6, 149, 119],
-    [18, 75, 47, 31, 76, 48],
-    [34, 54, 24, 34, 55, 25],
-    [20, 45, 15, 61, 46, 16],
-  ]),
-  (QRRSBlock.getRSBlocks = function (t, e) {
-    var r = QRRSBlock.getRsBlockTable(t, e);
-    if (void 0 == r)
-      throw new Error(
-        "bad rs block @ typeNumber:" + t + "/errorCorrectLevel:" + e
-      );
-    for (var o = r.length / 3, n = new Array(), i = 0; i < o; i++)
-      for (
-        var a = r[3 * i + 0], s = r[3 * i + 1], u = r[3 * i + 2], l = 0;
-        l < a;
-        l++
-      )
-        n.push(new QRRSBlock(s, u));
-    return n;
-  }),
-  (QRRSBlock.getRsBlockTable = function (t, e) {
-    switch (e) {
-      case QRErrorCorrectLevel.L:
-        return QRRSBlock.RS_BLOCK_TABLE[4 * (t - 1) + 0];
-      case QRErrorCorrectLevel.M:
-        return QRRSBlock.RS_BLOCK_TABLE[4 * (t - 1) + 1];
-      case QRErrorCorrectLevel.Q:
-        return QRRSBlock.RS_BLOCK_TABLE[4 * (t - 1) + 2];
-      case QRErrorCorrectLevel.H:
-        return QRRSBlock.RS_BLOCK_TABLE[4 * (t - 1) + 3];
-      default:
-        return;
-    }
-  }),
-  (QRBitBuffer.prototype = {
-    get: function (t) {
-      var e = Math.floor(t / 8);
-      return 1 == ((this.buffer[e] >>> (7 - (t % 8))) & 1);
-    },
-    put: function (t, e) {
-      for (var r = 0; r < e; r++) this.putBit(1 == ((t >>> (e - r - 1)) & 1));
-    },
-    getLengthInBits: function () {
-      return this.length;
-    },
-    putBit: function (t) {
-      var e = Math.floor(this.length / 8);
-      this.buffer.length <= e && this.buffer.push(0),
-        t && (this.buffer[e] |= 128 >>> this.length % 8),
-        this.length++;
-    },
-  });
-export default drawQrcode;

+ 201 - 0
uni_modules/Sansnn-uQRCode/LICENSE.md

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Разница между файлами не показана из-за своего большого размера
+ 207 - 0
uni_modules/Sansnn-uQRCode/README.md


+ 12 - 0
uni_modules/Sansnn-uQRCode/changelog.md

@@ -0,0 +1,12 @@
+## 4.0.6(2022-12-12)
+修复`getDrawModules`,第一次获取结果正常,后续获取`tile`模块不存在的问题;  
+修复安卓type:normal因Canvas API使用了小数或为0的参数导致生成异常的问题(注:安卓非2d Canvas部分API参数不支持携带小数,部分API参数必须大于0)。
+## 4.0.1(2022-11-28)
+优化组件loading属性的表现;  
+新增组件type选项normal,以便于在某些条件编译初始为type=2d时还可以选择使用非2d组件类型;  
+修复组件条件编译在其他编辑器语法提示报错;  
+修复原生对es5的支持。
+## 4.0.0(2022-11-21)
+v4版本源代码全面开放,开源地址:[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode);  
+
+升级说明:v4为大版本更新,虽然已尽可能兼容上一代版本,但不可避免的还是存在一些细节差异,若更新后出现问题,请参考对照[v3 文档](https://uqrcode.cn/doc/v3),[v4 文档](https://uqrcode.cn/doc)进行修改。

+ 1 - 0
uni_modules/Sansnn-uQRCode/common/cache.js

@@ -0,0 +1 @@
+export const cacheImageList = [];

+ 41 - 0
uni_modules/Sansnn-uQRCode/common/queue.js

@@ -0,0 +1,41 @@
+function Queue() {
+  let waitingQueue = this.waitingQueue = [];
+  let isRunning = this.isRunning = false; // 记录是否有未完成的任务
+
+  function execute(task, resolve, reject) {
+    task()
+      .then((data) => {
+        resolve(data);
+      })
+      .catch((e) => {
+        reject(e);
+      })
+      .finally(() => {
+        // 等待任务队列中如果有任务,则触发它;否则设置isRunning = false,表示无任务状态
+        if (waitingQueue.length) {
+          const next = waitingQueue.shift();
+          execute(next.task, next.resolve, next.reject);
+        } else {
+          isRunning = false;
+        }
+      });
+  }
+  this.exec = function(task) {
+    return new Promise((resolve, reject) => {
+      if (isRunning) {
+        waitingQueue.push({
+          task,
+          resolve,
+          reject
+        });
+      } else {
+        isRunning = true;
+        execute(task, resolve, reject);
+      }
+    });
+  }
+}
+
+/* 队列实例,某些平台一起使用多个组件时需要通过队列逐一绘制,否则部分绘制方法异常,nvue端的iOS gcanvas尤其明显,在不通过队列绘制时会出现图片丢失的情况 */
+export const queueDraw = new Queue();
+export const queueLoadImage = new Queue();

+ 3 - 0
uni_modules/Sansnn-uQRCode/common/types/cache.d.ts

@@ -0,0 +1,3 @@
+declare module '*/common/cache' {
+  export const cacheImageList: Array;
+}

+ 4 - 0
uni_modules/Sansnn-uQRCode/common/types/queue.d.ts

@@ -0,0 +1,4 @@
+declare module '*/common/queue' {
+  export const queueDraw: any;
+  export const queueLoadImage: any;
+}

Разница между файлами не показана из-за своего большого размера
+ 25 - 0
uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue


Разница между файлами не показана из-за своего большого размера
+ 25 - 0
uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue


+ 241 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js

@@ -0,0 +1,241 @@
+const isWeex = typeof WXEnvironment !== 'undefined';
+const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
+const isWeexAndroid = isWeex && !isWeexIOS;
+
+import GLmethod from '../context-webgl/GLmethod';
+
+const GCanvasModule =
+    (typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
+        (typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
+
+let isDebugging = false;
+
+let isComboDisabled = false;
+
+const logCommand = (function () {
+    const methodQuery = [];
+    Object.keys(GLmethod).forEach(key => {
+        methodQuery[GLmethod[key]] = key;
+    })
+    const queryMethod = (id) => {
+        return methodQuery[parseInt(id)] || 'NotFoundMethod';
+    }
+    const logCommand = (id, cmds) => {
+        const mId = cmds.split(',')[0];
+        const mName = queryMethod(mId);
+        console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
+    }
+    return logCommand;
+})();
+
+function joinArray(arr, sep) {
+    let res = '';
+    for (let i = 0; i < arr.length; i++) {
+        if (i !== 0) {
+            res += sep;
+        }
+        res += arr[i];
+    }
+    return res;
+}
+
+const commandsCache = {}
+
+const GBridge = {
+
+    callEnable: (ref, configArray) => {
+
+        commandsCache[ref] = [];
+
+        return GCanvasModule.enable({
+            componentId: ref,
+            config: configArray
+        });
+    },
+
+    callEnableDebug: () => {
+        isDebugging = true;
+    },
+
+    callEnableDisableCombo: () => {
+        isComboDisabled = true;
+    },
+
+    callSetContextType: function (componentId, context_type) {
+        GCanvasModule.setContextType(context_type, componentId);
+    },
+
+    callReset: function(id){
+        GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
+    },
+
+    render: isWeexIOS ? function (componentId) {
+        return GCanvasModule.extendCallNative({
+            contextId: componentId,
+            type: 0x60000001
+        });
+    } : function (componentId) {
+        return callGCanvasLinkNative(componentId, 0x60000001, 'render');
+    },
+
+    render2d: isWeexIOS ? function (componentId, commands, callback) {
+
+        if (isDebugging) {
+            console.log('>>> >>> render2d ===');
+            console.log('>>> commands: ' + commands);
+        }
+		
+        GCanvasModule.render([commands, callback?true:false], componentId, callback);
+
+    } : function (componentId, commands,callback) {
+
+        if (isDebugging) {
+            console.log('>>> >>> render2d ===');
+            console.log('>>> commands: ' + commands);
+        }
+
+        callGCanvasLinkNative(componentId, 0x20000001, commands);
+		if(callback){
+		callback();
+		}
+    },
+
+    callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
+
+        throw 'should not be here anymore ' + cmdArgs;
+
+    } : function (componentId, cmdArgs) {
+
+        throw 'should not be here anymore ' + cmdArgs;
+
+    },
+
+
+    flushNative: isWeexIOS ? function (componentId) {
+
+        const cmdArgs = joinArray(commandsCache[componentId], ';');
+        commandsCache[componentId] = [];
+
+        if (isDebugging) {
+            console.log('>>> >>> flush native ===');
+            console.log('>>> commands: ' + cmdArgs);
+        }
+
+        const result = GCanvasModule.extendCallNative({
+            "contextId": componentId,
+            "type": 0x60000000,
+            "args": cmdArgs
+        });
+
+        const res = result && result.result;
+
+        if (isDebugging) {
+            console.log('>>> result: ' + res);
+        }
+
+        return res;
+
+    } : function (componentId) {
+
+        const cmdArgs = joinArray(commandsCache[componentId], ';');
+        commandsCache[componentId] = [];
+
+        if (isDebugging) {
+            console.log('>>> >>> flush native ===');
+            console.log('>>> commands: ' + cmdArgs);
+        }
+
+        const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
+
+        if (isDebugging) {
+            console.log('>>> result: ' + result);
+        }
+
+        return result;
+    },
+
+    callNative: function (componentId, cmdArgs, cache) {
+
+        if (isDebugging) {
+            logCommand(componentId, cmdArgs);
+        }
+
+        commandsCache[componentId].push(cmdArgs);
+
+        if (!cache || isComboDisabled) {
+            return GBridge.flushNative(componentId);
+        } else {
+            return undefined;
+        }
+    },
+
+    texImage2D(componentId, ...args) {
+        if (isWeexIOS) {
+            if (args.length === 6) {
+                const [target, level, internalformat, format, type, image] = args;
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
+                )
+            } else if (args.length === 9) {
+                const [target, level, internalformat, width, height, border, format, type, image] = args;
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
+                    + format + ',' + type + ',' + (image ? image.src : 0)
+                )
+            }
+        } else if (isWeexAndroid) {
+            if (args.length === 6) {
+                const [target, level, internalformat, format, type, image] = args;
+                GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
+            } else if (args.length === 9) {
+                const [target, level, internalformat, width, height, border, format, type, image] = args;
+                GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
+            }
+        }
+    },
+
+    texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
+        if (isWeexIOS) {
+            if (arguments.length === 8) {
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
+                )
+            }
+        } else if (isWeexAndroid) {
+            GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
+        }
+    },
+
+    bindImageTexture(componentId, src, imageId) {
+        GCanvasModule.bindImageTexture([src, imageId], componentId);
+    },
+
+    perloadImage([url, id], callback) {
+        GCanvasModule.preLoadImage([url, id], function (image) {
+            image.url = url;
+            image.id = id;
+            callback(image);
+        });
+    },
+	
+	measureText(text, fontStyle, componentId) {
+	    return GCanvasModule.measureText([text, fontStyle], componentId);
+	},
+	
+	getImageData (componentId, x, y, w, h, callback) {
+		GCanvasModule.getImageData([x, y,w,h],componentId,callback);
+	},
+	
+	putImageData (componentId, data, x, y, w, h, callback) {
+		GCanvasModule.putImageData([x, y,w,h,data],componentId,callback);
+	},
+	
+	toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){ 
+		GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback);
+	}
+}
+
+export default GBridge;

+ 18 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js

@@ -0,0 +1,18 @@
+class FillStyleLinearGradient {
+
+    constructor(x0, y0, x1, y1) {
+        this._start_pos = { _x: x0, _y: y0 };
+        this._end_pos = { _x: x1, _y: y1 };
+        this._stop_count = 0;
+        this._stops = [0, 0, 0, 0, 0];
+    }
+
+    addColorStop = function (pos, color) {
+        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
+            this._stops[this._stop_count] = { _pos: pos, _color: color };
+            this._stop_count++;
+        }
+    }
+}
+
+export default FillStyleLinearGradient;

+ 8 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js

@@ -0,0 +1,8 @@
+class FillStylePattern {
+    constructor(img, pattern) {
+        this._style = pattern;
+        this._img = img;
+    }
+}
+
+export default FillStylePattern;

+ 17 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js

@@ -0,0 +1,17 @@
+class FillStyleRadialGradient {
+    constructor(x0, y0, r0, x1, y1, r1) {
+        this._start_pos = { _x: x0, _y: y0, _r: r0 };
+        this._end_pos = { _x: x1, _y: y1, _r: r1 };
+        this._stop_count = 0;
+        this._stops = [0, 0, 0, 0, 0];
+    }
+
+    addColorStop(pos, color) {
+        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
+            this._stops[this._stop_count] = { _pos: pos, _color: color };
+            this._stop_count++;
+        }
+    }
+}
+
+export default FillStyleRadialGradient;

+ 666 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js

@@ -0,0 +1,666 @@
+import FillStylePattern from './FillStylePattern';
+import FillStyleLinearGradient from './FillStyleLinearGradient';
+import FillStyleRadialGradient from './FillStyleRadialGradient';
+import GImage from '../env/image.js';
+import {
+	ArrayBufferToBase64,
+	Base64ToUint8ClampedArray
+} from '../env/tool.js';
+
+export default class CanvasRenderingContext2D {
+
+	_drawCommands = '';
+
+	_globalAlpha = 1.0;
+
+	_fillStyle = 'rgb(0,0,0)';
+	_strokeStyle = 'rgb(0,0,0)';
+
+	_lineWidth = 1;
+	_lineCap = 'butt';
+	_lineJoin = 'miter';
+
+	_miterLimit = 10;
+
+	_globalCompositeOperation = 'source-over';
+
+	_textAlign = 'start';
+	_textBaseline = 'alphabetic';
+
+	_font = '10px sans-serif';
+
+	_savedGlobalAlpha = [];
+
+	timer = null;
+	componentId = null;
+
+	_notCommitDrawImageCache = [];
+	_needRedrawImageCache = [];
+	_redrawCommands = '';
+	_autoSaveContext = true;
+	// _imageMap = new GHashMap();
+	// _textureMap = new GHashMap();
+
+	constructor() {
+		this.className = 'CanvasRenderingContext2D';
+		//this.save()
+	}
+
+	setFillStyle(value) {
+		this.fillStyle = value;
+	}
+
+	set fillStyle(value) {
+		this._fillStyle = value;
+
+		if (typeof(value) == 'string') {
+			this._drawCommands = this._drawCommands.concat("F" + value + ";");
+		} else if (value instanceof FillStylePattern) {
+			const image = value._img;
+			if (!image.complete) {
+				image.onload = () => {
+					var index = this._needRedrawImageCache.indexOf(image);
+					if (index > -1) {
+						this._needRedrawImageCache.splice(index, 1);
+						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+						this._redrawflush(true);
+					}
+				}
+				this._notCommitDrawImageCache.push(image);
+			} else {
+				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			}
+
+			//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
+		} else if (value instanceof FillStyleLinearGradient) {
+			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
+				value._stop_count;
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		} else if (value instanceof FillStyleRadialGradient) {
+			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
+				.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +
+				value._stop_count;
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		}
+	}
+
+	get fillStyle() {
+		return this._fillStyle;
+	}
+
+	get globalAlpha() {
+		return this._globalAlpha;
+	}
+
+	setGlobalAlpha(value) {
+		this.globalAlpha = value;
+	}
+
+	set globalAlpha(value) {
+		this._globalAlpha = value;
+		this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");
+	}
+
+
+	get strokeStyle() {
+		return this._strokeStyle;
+	}
+
+	setStrokeStyle(value) {
+		this.strokeStyle = value;
+	}
+
+	set strokeStyle(value) {
+
+		this._strokeStyle = value;
+
+		if (typeof(value) == 'string') {
+			this._drawCommands = this._drawCommands.concat("S" + value + ";");
+		} else if (value instanceof FillStylePattern) {
+			CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
+		} else if (value instanceof FillStyleLinearGradient) {
+			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
+				value._stop_count;
+
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		} else if (value instanceof FillStyleRadialGradient) {
+			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
+				.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +
+				value._stop_count;
+
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		}
+	}
+
+	get lineWidth() {
+		return this._lineWidth;
+	}
+
+	setLineWidth(value) {
+		this.lineWidth = value;
+	}
+
+	set lineWidth(value) {
+		this._lineWidth = value;
+		this._drawCommands = this._drawCommands.concat("W" + value + ";");
+	}
+
+	get lineCap() {
+		return this._lineCap;
+	}
+
+	setLineCap(value) {
+		this.lineCap = value;
+	}
+
+	set lineCap(value) {
+		this._lineCap = value;
+		this._drawCommands = this._drawCommands.concat("C" + value + ";");
+	}
+
+	get lineJoin() {
+		return this._lineJoin;
+	}
+
+	setLineJoin(value) {
+		this.lineJoin = value
+	}
+
+	set lineJoin(value) {
+		this._lineJoin = value;
+		this._drawCommands = this._drawCommands.concat("J" + value + ";");
+	}
+
+	get miterLimit() {
+		return this._miterLimit;
+	}
+
+	setMiterLimit(value) {
+		this.miterLimit = value
+	}
+
+	set miterLimit(value) {
+		this._miterLimit = value;
+		this._drawCommands = this._drawCommands.concat("M" + value + ";");
+	}
+
+	get globalCompositeOperation() {
+		return this._globalCompositeOperation;
+	}
+
+	set globalCompositeOperation(value) {
+
+		this._globalCompositeOperation = value;
+		let mode = 0;
+		switch (value) {
+			case "source-over":
+				mode = 0;
+				break;
+			case "source-atop":
+				mode = 5;
+				break;
+			case "source-in":
+				mode = 0;
+				break;
+			case "source-out":
+				mode = 2;
+				break;
+			case "destination-over":
+				mode = 4;
+				break;
+			case "destination-atop":
+				mode = 4;
+				break;
+			case "destination-in":
+				mode = 4;
+				break;
+			case "destination-out":
+				mode = 3;
+				break;
+			case "lighter":
+				mode = 1;
+				break;
+			case "copy":
+				mode = 2;
+				break;
+			case "xor":
+				mode = 6;
+				break;
+			default:
+				mode = 0;
+		}
+
+		this._drawCommands = this._drawCommands.concat("B" + mode + ";");
+	}
+
+	get textAlign() {
+		return this._textAlign;
+	}
+
+	setTextAlign(value) {
+		this.textAlign = value
+	}
+
+	set textAlign(value) {
+
+		this._textAlign = value;
+		let Align = 0;
+		switch (value) {
+			case "start":
+				Align = 0;
+				break;
+			case "end":
+				Align = 1;
+				break;
+			case "left":
+				Align = 2;
+				break;
+			case "center":
+				Align = 3;
+				break;
+			case "right":
+				Align = 4;
+				break;
+			default:
+				Align = 0;
+		}
+
+		this._drawCommands = this._drawCommands.concat("A" + Align + ";");
+	}
+
+	get textBaseline() {
+		return this._textBaseline;
+	}
+
+	setTextBaseline(value) {
+		this.textBaseline = value
+	}
+
+	set textBaseline(value) {
+		this._textBaseline = value;
+		let baseline = 0;
+		switch (value) {
+			case "alphabetic":
+				baseline = 0;
+				break;
+			case "middle":
+				baseline = 1;
+				break;
+			case "top":
+				baseline = 2;
+				break;
+			case "hanging":
+				baseline = 3;
+				break;
+			case "bottom":
+				baseline = 4;
+				break;
+			case "ideographic":
+				baseline = 5;
+				break;
+			default:
+				baseline = 0;
+				break;
+		}
+
+		this._drawCommands = this._drawCommands.concat("E" + baseline + ";");
+	}
+
+	get font() {
+		return this._font;
+	}
+
+	setFontSize(size) {
+		var str = this._font;
+		var strs = str.trim().split(/\s+/);
+		for (var i = 0; i < strs.length; i++) {
+			var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",
+				"bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",
+				"normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
+				"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
+			];
+
+			if (-1 == values.indexOf(strs[i].trim())) {
+				if (typeof size === 'string') {
+					strs[i] = size;
+				} else if (typeof size === 'number') {
+					strs[i] = String(size) + 'px';
+				}
+				break;
+			}
+		}
+		this.font = strs.join(" ");
+	}
+
+	set font(value) {
+		this._font = value;
+		this._drawCommands = this._drawCommands.concat("j" + value + ";");
+	}
+
+	setTransform(a, b, c, d, tx, ty) {
+		this._drawCommands = this._drawCommands.concat("t" +
+			(a === 1 ? "1" : a.toFixed(2)) + "," +
+			(b === 0 ? "0" : b.toFixed(2)) + "," +
+			(c === 0 ? "0" : c.toFixed(2)) + "," +
+			(d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
+	}
+
+	transform(a, b, c, d, tx, ty) {
+		this._drawCommands = this._drawCommands.concat("f" +
+			(a === 1 ? "1" : a.toFixed(2)) + "," +
+			(b === 0 ? "0" : b.toFixed(2)) + "," +
+			(c === 0 ? "0" : c.toFixed(2)) + "," +
+			(d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");
+	}
+
+	resetTransform() {
+		this._drawCommands = this._drawCommands.concat("m;");
+	}
+
+	scale(a, d) {
+		this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +
+			d.toFixed(2) + ";");
+	}
+
+	rotate(angle) {
+		this._drawCommands = this._drawCommands
+			.concat("r" + angle.toFixed(6) + ";");
+	}
+
+	translate(tx, ty) {
+		this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
+	}
+
+	save() {
+		this._savedGlobalAlpha.push(this._globalAlpha);
+		this._drawCommands = this._drawCommands.concat("v;");
+	}
+
+	restore() {
+		this._drawCommands = this._drawCommands.concat("e;");
+		this._globalAlpha = this._savedGlobalAlpha.pop();
+	}
+
+	createPattern(img, pattern) {
+		if (typeof img === 'string') {
+			var imgObj = new GImage();
+			imgObj.src = img;
+			img = imgObj;
+		}
+		return new FillStylePattern(img, pattern);
+	}
+
+	createLinearGradient(x0, y0, x1, y1) {
+		return new FillStyleLinearGradient(x0, y0, x1, y1);
+	}
+
+	createRadialGradient = function(x0, y0, r0, x1, y1, r1) {
+		return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);
+	};
+
+	createCircularGradient = function(x0, y0, r0) {
+		return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);
+	};
+
+	strokeRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");
+	}
+
+
+	clearRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +
+			"," + h + ";");
+	}
+
+	clip() {
+		this._drawCommands = this._drawCommands.concat("p;");
+	}
+
+	resetClip() {
+		this._drawCommands = this._drawCommands.concat("q;");
+	}
+
+	closePath() {
+		this._drawCommands = this._drawCommands.concat("o;");
+	}
+
+	moveTo(x, y) {
+		this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	lineTo(x, y) {
+		this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	quadraticCurveTo = function(cpx, cpy, x, y) {
+		this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");
+	}
+
+	bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {
+		this._drawCommands = this._drawCommands.concat(
+			"z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +
+			x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	arcTo(x1, y1, x2, y2, radius) {
+		this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");
+	}
+
+	beginPath() {
+		this._drawCommands = this._drawCommands.concat("b;");
+	}
+
+
+	fillRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +
+			"," + h + ";");
+	}
+
+	rect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");
+	}
+
+	fill() {
+		this._drawCommands = this._drawCommands.concat("L;");
+	}
+
+	stroke(path) {
+		this._drawCommands = this._drawCommands.concat("x;");
+	}
+
+	arc(x, y, radius, startAngle, endAngle, anticlockwise) {
+
+		let ianticlockwise = 0;
+		if (anticlockwise) {
+			ianticlockwise = 1;
+		}
+
+		this._drawCommands = this._drawCommands.concat(
+			"y" + x.toFixed(2) + "," + y.toFixed(2) + "," +
+			radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
+			";"
+		);
+	}
+
+	fillText(text, x, y) {
+		let tmptext = text.replace(/!/g, "!!");
+		tmptext = tmptext.replace(/,/g, "!,");
+		tmptext = tmptext.replace(/;/g, "!;");
+		this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");
+	}
+
+	strokeText = function(text, x, y) {
+		let tmptext = text.replace(/!/g, "!!");
+		tmptext = tmptext.replace(/,/g, "!,");
+		tmptext = tmptext.replace(/;/g, "!;");
+		this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");
+	}
+
+	measureText(text) {
+		return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);
+	}
+
+	isPointInPath = function(x, y) {
+		throw new Error('GCanvas not supported yet');
+	}
+
+	drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
+		if (typeof image === 'string') {
+			var imgObj = new GImage();
+			imgObj.src = image;
+			image = imgObj;
+		}
+		if (image instanceof GImage) {
+			if (!image.complete) {
+				imgObj.onload = () => {
+					var index = this._needRedrawImageCache.indexOf(image);
+					if (index > -1) {
+						this._needRedrawImageCache.splice(index, 1);
+						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+						this._redrawflush(true);
+					}
+				}
+				this._notCommitDrawImageCache.push(image);
+			} else {
+				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			}
+			var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];
+			var args = [];
+			for (var arg in srcArgs) {
+				if (typeof(srcArgs[arg]) != 'undefined') {
+					args.push(srcArgs[arg]);
+				}
+			}
+			this.__drawImage.apply(this, args);
+			//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
+		}
+	}
+
+	__drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
+		const numArgs = arguments.length;
+
+		function drawImageCommands() {
+
+			if (numArgs === 3) {
+				const x = parseFloat(sx) || 0.0;
+				const y = parseFloat(sy) || 0.0;
+
+				return ("d" + image._id + ",0,0," +
+					image.width + "," + image.height + "," +
+					x + "," + y + "," + image.width + "," + image.height + ";");
+			} else if (numArgs === 5) {
+				const x = parseFloat(sx) || 0.0;
+				const y = parseFloat(sy) || 0.0;
+				const width = parseInt(sw) || image.width;
+				const height = parseInt(sh) || image.height;
+
+				return ("d" + image._id + ",0,0," +
+					image.width + "," + image.height + "," +
+					x + "," + y + "," + width + "," + height + ";");
+			} else if (numArgs === 9) {
+				sx = parseFloat(sx) || 0.0;
+				sy = parseFloat(sy) || 0.0;
+				sw = parseInt(sw) || image.width;
+				sh = parseInt(sh) || image.height;
+				dx = parseFloat(dx) || 0.0;
+				dy = parseFloat(dy) || 0.0;
+				dw = parseInt(dw) || image.width;
+				dh = parseInt(dh) || image.height;
+
+				return ("d" + image._id + "," +
+					sx + "," + sy + "," + sw + "," + sh + "," +
+					dx + "," + dy + "," + dw + "," + dh + ";");
+			}
+		}
+		this._drawCommands += drawImageCommands();
+	}
+
+	_flush(reserve, callback) {
+		const commands = this._drawCommands;
+		this._drawCommands = '';
+		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
+		this._needRender = false;
+	}
+
+	_redrawflush(reserve, callback) {
+		const commands = this._redrawCommands;
+		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
+		if (this._needRedrawImageCache.length == 0) {
+			this._redrawCommands = '';
+		}
+	}
+
+	draw(reserve, callback) {
+		if (!reserve) {
+			this._globalAlpha = this._savedGlobalAlpha.pop();
+			this._savedGlobalAlpha.push(this._globalAlpha);
+			this._redrawCommands = this._drawCommands;
+			this._needRedrawImageCache = this._notCommitDrawImageCache;
+			if (this._autoSaveContext) {
+				this._drawCommands = ("v;" + this._drawCommands);
+				this._autoSaveContext = false;
+			} else {
+				this._drawCommands = ("e;X;v;" + this._drawCommands);
+			}
+		} else {
+			this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);
+			this._redrawCommands += this._drawCommands;
+			if (this._autoSaveContext) {
+				this._drawCommands = ("v;" + this._drawCommands);
+				this._autoSaveContext = false;
+			}
+		}
+		this._notCommitDrawImageCache = [];
+		if (this._flush) {
+			this._flush(reserve, callback);
+		}
+	}
+
+	getImageData(x, y, w, h, callback) {
+		CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {
+			res.data = Base64ToUint8ClampedArray(res.data);
+			if (typeof(callback) == 'function') {
+				callback(res);
+			}
+		});
+	}
+
+	putImageData(data, x, y, w, h, callback) {
+		if (data instanceof Uint8ClampedArray) {
+			data = ArrayBufferToBase64(data);
+			CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {
+				if (typeof(callback) == 'function') {
+					callback(res);
+				}
+			});
+		}
+	}
+
+	toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {
+		CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,
+			fileType, quality,
+			function(res) {
+				if (typeof(callback) == 'function') {
+					callback(res);
+				}
+			});
+	}
+}

+ 11 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js

@@ -0,0 +1,11 @@
+export default class WebGLActiveInfo {
+    className = 'WebGLActiveInfo';
+
+    constructor({
+        type, name, size
+    }) {
+        this.type = type;
+        this.name = name;
+        this.size = size;
+    }
+}

+ 21 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLBuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 21 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLFrameBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLFramebuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 298 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js

@@ -0,0 +1,298 @@
+export default {
+    "DEPTH_BUFFER_BIT": 256,
+    "STENCIL_BUFFER_BIT": 1024,
+    "COLOR_BUFFER_BIT": 16384,
+    "POINTS": 0,
+    "LINES": 1,
+    "LINE_LOOP": 2,
+    "LINE_STRIP": 3,
+    "TRIANGLES": 4,
+    "TRIANGLE_STRIP": 5,
+    "TRIANGLE_FAN": 6,
+    "ZERO": 0,
+    "ONE": 1,
+    "SRC_COLOR": 768,
+    "ONE_MINUS_SRC_COLOR": 769,
+    "SRC_ALPHA": 770,
+    "ONE_MINUS_SRC_ALPHA": 771,
+    "DST_ALPHA": 772,
+    "ONE_MINUS_DST_ALPHA": 773,
+    "DST_COLOR": 774,
+    "ONE_MINUS_DST_COLOR": 775,
+    "SRC_ALPHA_SATURATE": 776,
+    "FUNC_ADD": 32774,
+    "BLEND_EQUATION": 32777,
+    "BLEND_EQUATION_RGB": 32777,
+    "BLEND_EQUATION_ALPHA": 34877,
+    "FUNC_SUBTRACT": 32778,
+    "FUNC_REVERSE_SUBTRACT": 32779,
+    "BLEND_DST_RGB": 32968,
+    "BLEND_SRC_RGB": 32969,
+    "BLEND_DST_ALPHA": 32970,
+    "BLEND_SRC_ALPHA": 32971,
+    "CONSTANT_COLOR": 32769,
+    "ONE_MINUS_CONSTANT_COLOR": 32770,
+    "CONSTANT_ALPHA": 32771,
+    "ONE_MINUS_CONSTANT_ALPHA": 32772,
+    "BLEND_COLOR": 32773,
+    "ARRAY_BUFFER": 34962,
+    "ELEMENT_ARRAY_BUFFER": 34963,
+    "ARRAY_BUFFER_BINDING": 34964,
+    "ELEMENT_ARRAY_BUFFER_BINDING": 34965,
+    "STREAM_DRAW": 35040,
+    "STATIC_DRAW": 35044,
+    "DYNAMIC_DRAW": 35048,
+    "BUFFER_SIZE": 34660,
+    "BUFFER_USAGE": 34661,
+    "CURRENT_VERTEX_ATTRIB": 34342,
+    "FRONT": 1028,
+    "BACK": 1029,
+    "FRONT_AND_BACK": 1032,
+    "TEXTURE_2D": 3553,
+    "CULL_FACE": 2884,
+    "BLEND": 3042,
+    "DITHER": 3024,
+    "STENCIL_TEST": 2960,
+    "DEPTH_TEST": 2929,
+    "SCISSOR_TEST": 3089,
+    "POLYGON_OFFSET_FILL": 32823,
+    "SAMPLE_ALPHA_TO_COVERAGE": 32926,
+    "SAMPLE_COVERAGE": 32928,
+    "NO_ERROR": 0,
+    "INVALID_ENUM": 1280,
+    "INVALID_VALUE": 1281,
+    "INVALID_OPERATION": 1282,
+    "OUT_OF_MEMORY": 1285,
+    "CW": 2304,
+    "CCW": 2305,
+    "LINE_WIDTH": 2849,
+    "ALIASED_POINT_SIZE_RANGE": 33901,
+    "ALIASED_LINE_WIDTH_RANGE": 33902,
+    "CULL_FACE_MODE": 2885,
+    "FRONT_FACE": 2886,
+    "DEPTH_RANGE": 2928,
+    "DEPTH_WRITEMASK": 2930,
+    "DEPTH_CLEAR_VALUE": 2931,
+    "DEPTH_FUNC": 2932,
+    "STENCIL_CLEAR_VALUE": 2961,
+    "STENCIL_FUNC": 2962,
+    "STENCIL_FAIL": 2964,
+    "STENCIL_PASS_DEPTH_FAIL": 2965,
+    "STENCIL_PASS_DEPTH_PASS": 2966,
+    "STENCIL_REF": 2967,
+    "STENCIL_VALUE_MASK": 2963,
+    "STENCIL_WRITEMASK": 2968,
+    "STENCIL_BACK_FUNC": 34816,
+    "STENCIL_BACK_FAIL": 34817,
+    "STENCIL_BACK_PASS_DEPTH_FAIL": 34818,
+    "STENCIL_BACK_PASS_DEPTH_PASS": 34819,
+    "STENCIL_BACK_REF": 36003,
+    "STENCIL_BACK_VALUE_MASK": 36004,
+    "STENCIL_BACK_WRITEMASK": 36005,
+    "VIEWPORT": 2978,
+    "SCISSOR_BOX": 3088,
+    "COLOR_CLEAR_VALUE": 3106,
+    "COLOR_WRITEMASK": 3107,
+    "UNPACK_ALIGNMENT": 3317,
+    "PACK_ALIGNMENT": 3333,
+    "MAX_TEXTURE_SIZE": 3379,
+    "MAX_VIEWPORT_DIMS": 3386,
+    "SUBPIXEL_BITS": 3408,
+    "RED_BITS": 3410,
+    "GREEN_BITS": 3411,
+    "BLUE_BITS": 3412,
+    "ALPHA_BITS": 3413,
+    "DEPTH_BITS": 3414,
+    "STENCIL_BITS": 3415,
+    "POLYGON_OFFSET_UNITS": 10752,
+    "POLYGON_OFFSET_FACTOR": 32824,
+    "TEXTURE_BINDING_2D": 32873,
+    "SAMPLE_BUFFERS": 32936,
+    "SAMPLES": 32937,
+    "SAMPLE_COVERAGE_VALUE": 32938,
+    "SAMPLE_COVERAGE_INVERT": 32939,
+    "COMPRESSED_TEXTURE_FORMATS": 34467,
+    "DONT_CARE": 4352,
+    "FASTEST": 4353,
+    "NICEST": 4354,
+    "GENERATE_MIPMAP_HINT": 33170,
+    "BYTE": 5120,
+    "UNSIGNED_BYTE": 5121,
+    "SHORT": 5122,
+    "UNSIGNED_SHORT": 5123,
+    "INT": 5124,
+    "UNSIGNED_INT": 5125,
+    "FLOAT": 5126,
+    "DEPTH_COMPONENT": 6402,
+    "ALPHA": 6406,
+    "RGB": 6407,
+    "RGBA": 6408,
+    "LUMINANCE": 6409,
+    "LUMINANCE_ALPHA": 6410,
+    "UNSIGNED_SHORT_4_4_4_4": 32819,
+    "UNSIGNED_SHORT_5_5_5_1": 32820,
+    "UNSIGNED_SHORT_5_6_5": 33635,
+    "FRAGMENT_SHADER": 35632,
+    "VERTEX_SHADER": 35633,
+    "MAX_VERTEX_ATTRIBS": 34921,
+    "MAX_VERTEX_UNIFORM_VECTORS": 36347,
+    "MAX_VARYING_VECTORS": 36348,
+    "MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661,
+    "MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660,
+    "MAX_TEXTURE_IMAGE_UNITS": 34930,
+    "MAX_FRAGMENT_UNIFORM_VECTORS": 36349,
+    "SHADER_TYPE": 35663,
+    "DELETE_STATUS": 35712,
+    "LINK_STATUS": 35714,
+    "VALIDATE_STATUS": 35715,
+    "ATTACHED_SHADERS": 35717,
+    "ACTIVE_UNIFORMS": 35718,
+    "ACTIVE_ATTRIBUTES": 35721,
+    "SHADING_LANGUAGE_VERSION": 35724,
+    "CURRENT_PROGRAM": 35725,
+    "NEVER": 512,
+    "LESS": 513,
+    "EQUAL": 514,
+    "LEQUAL": 515,
+    "GREATER": 516,
+    "NOTEQUAL": 517,
+    "GEQUAL": 518,
+    "ALWAYS": 519,
+    "KEEP": 7680,
+    "REPLACE": 7681,
+    "INCR": 7682,
+    "DECR": 7683,
+    "INVERT": 5386,
+    "INCR_WRAP": 34055,
+    "DECR_WRAP": 34056,
+    "VENDOR": 7936,
+    "RENDERER": 7937,
+    "VERSION": 7938,
+    "NEAREST": 9728,
+    "LINEAR": 9729,
+    "NEAREST_MIPMAP_NEAREST": 9984,
+    "LINEAR_MIPMAP_NEAREST": 9985,
+    "NEAREST_MIPMAP_LINEAR": 9986,
+    "LINEAR_MIPMAP_LINEAR": 9987,
+    "TEXTURE_MAG_FILTER": 10240,
+    "TEXTURE_MIN_FILTER": 10241,
+    "TEXTURE_WRAP_S": 10242,
+    "TEXTURE_WRAP_T": 10243,
+    "TEXTURE": 5890,
+    "TEXTURE_CUBE_MAP": 34067,
+    "TEXTURE_BINDING_CUBE_MAP": 34068,
+    "TEXTURE_CUBE_MAP_POSITIVE_X": 34069,
+    "TEXTURE_CUBE_MAP_NEGATIVE_X": 34070,
+    "TEXTURE_CUBE_MAP_POSITIVE_Y": 34071,
+    "TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072,
+    "TEXTURE_CUBE_MAP_POSITIVE_Z": 34073,
+    "TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074,
+    "MAX_CUBE_MAP_TEXTURE_SIZE": 34076,
+    "TEXTURE0": 33984,
+    "TEXTURE1": 33985,
+    "TEXTURE2": 33986,
+    "TEXTURE3": 33987,
+    "TEXTURE4": 33988,
+    "TEXTURE5": 33989,
+    "TEXTURE6": 33990,
+    "TEXTURE7": 33991,
+    "TEXTURE8": 33992,
+    "TEXTURE9": 33993,
+    "TEXTURE10": 33994,
+    "TEXTURE11": 33995,
+    "TEXTURE12": 33996,
+    "TEXTURE13": 33997,
+    "TEXTURE14": 33998,
+    "TEXTURE15": 33999,
+    "TEXTURE16": 34000,
+    "TEXTURE17": 34001,
+    "TEXTURE18": 34002,
+    "TEXTURE19": 34003,
+    "TEXTURE20": 34004,
+    "TEXTURE21": 34005,
+    "TEXTURE22": 34006,
+    "TEXTURE23": 34007,
+    "TEXTURE24": 34008,
+    "TEXTURE25": 34009,
+    "TEXTURE26": 34010,
+    "TEXTURE27": 34011,
+    "TEXTURE28": 34012,
+    "TEXTURE29": 34013,
+    "TEXTURE30": 34014,
+    "TEXTURE31": 34015,
+    "ACTIVE_TEXTURE": 34016,
+    "REPEAT": 10497,
+    "CLAMP_TO_EDGE": 33071,
+    "MIRRORED_REPEAT": 33648,
+    "FLOAT_VEC2": 35664,
+    "FLOAT_VEC3": 35665,
+    "FLOAT_VEC4": 35666,
+    "INT_VEC2": 35667,
+    "INT_VEC3": 35668,
+    "INT_VEC4": 35669,
+    "BOOL": 35670,
+    "BOOL_VEC2": 35671,
+    "BOOL_VEC3": 35672,
+    "BOOL_VEC4": 35673,
+    "FLOAT_MAT2": 35674,
+    "FLOAT_MAT3": 35675,
+    "FLOAT_MAT4": 35676,
+    "SAMPLER_2D": 35678,
+    "SAMPLER_CUBE": 35680,
+    "VERTEX_ATTRIB_ARRAY_ENABLED": 34338,
+    "VERTEX_ATTRIB_ARRAY_SIZE": 34339,
+    "VERTEX_ATTRIB_ARRAY_STRIDE": 34340,
+    "VERTEX_ATTRIB_ARRAY_TYPE": 34341,
+    "VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922,
+    "VERTEX_ATTRIB_ARRAY_POINTER": 34373,
+    "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975,
+    "IMPLEMENTATION_COLOR_READ_TYPE": 35738,
+    "IMPLEMENTATION_COLOR_READ_FORMAT": 35739,
+    "COMPILE_STATUS": 35713,
+    "LOW_FLOAT": 36336,
+    "MEDIUM_FLOAT": 36337,
+    "HIGH_FLOAT": 36338,
+    "LOW_INT": 36339,
+    "MEDIUM_INT": 36340,
+    "HIGH_INT": 36341,
+    "FRAMEBUFFER": 36160,
+    "RENDERBUFFER": 36161,
+    "RGBA4": 32854,
+    "RGB5_A1": 32855,
+    "RGB565": 36194,
+    "DEPTH_COMPONENT16": 33189,
+    "STENCIL_INDEX8": 36168,
+    "DEPTH_STENCIL": 34041,
+    "RENDERBUFFER_WIDTH": 36162,
+    "RENDERBUFFER_HEIGHT": 36163,
+    "RENDERBUFFER_INTERNAL_FORMAT": 36164,
+    "RENDERBUFFER_RED_SIZE": 36176,
+    "RENDERBUFFER_GREEN_SIZE": 36177,
+    "RENDERBUFFER_BLUE_SIZE": 36178,
+    "RENDERBUFFER_ALPHA_SIZE": 36179,
+    "RENDERBUFFER_DEPTH_SIZE": 36180,
+    "RENDERBUFFER_STENCIL_SIZE": 36181,
+    "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048,
+    "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049,
+    "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050,
+    "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051,
+    "COLOR_ATTACHMENT0": 36064,
+    "DEPTH_ATTACHMENT": 36096,
+    "STENCIL_ATTACHMENT": 36128,
+    "DEPTH_STENCIL_ATTACHMENT": 33306,
+    "NONE": 0,
+    "FRAMEBUFFER_COMPLETE": 36053,
+    "FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054,
+    "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055,
+    "FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057,
+    "FRAMEBUFFER_UNSUPPORTED": 36061,
+    "FRAMEBUFFER_BINDING": 36006,
+    "RENDERBUFFER_BINDING": 36007,
+    "MAX_RENDERBUFFER_SIZE": 34024,
+    "INVALID_FRAMEBUFFER_OPERATION": 1286,
+    "UNPACK_FLIP_Y_WEBGL": 37440,
+    "UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441,
+    "CONTEXT_LOST_WEBGL": 37442,
+    "UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443,
+    "BROWSER_DEFAULT_WEBGL": 37444
+};

+ 142 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js

@@ -0,0 +1,142 @@
+let i = 1;
+
+const GLmethod = {};
+
+GLmethod.activeTexture = i++;         //1
+GLmethod.attachShader = i++;
+GLmethod.bindAttribLocation = i++;
+GLmethod.bindBuffer = i++;
+GLmethod.bindFramebuffer = i++;
+GLmethod.bindRenderbuffer = i++;
+GLmethod.bindTexture = i++;
+GLmethod.blendColor = i++;
+GLmethod.blendEquation = i++;
+GLmethod.blendEquationSeparate = i++; //10
+GLmethod.blendFunc = i++;
+GLmethod.blendFuncSeparate = i++;
+GLmethod.bufferData = i++;
+GLmethod.bufferSubData = i++;
+GLmethod.checkFramebufferStatus = i++;
+GLmethod.clear = i++;
+GLmethod.clearColor = i++;
+GLmethod.clearDepth = i++;
+GLmethod.clearStencil = i++;
+GLmethod.colorMask = i++;              //20
+GLmethod.compileShader = i++;
+GLmethod.compressedTexImage2D = i++;
+GLmethod.compressedTexSubImage2D = i++;
+GLmethod.copyTexImage2D = i++;
+GLmethod.copyTexSubImage2D = i++;
+GLmethod.createBuffer = i++;
+GLmethod.createFramebuffer = i++;
+GLmethod.createProgram = i++;
+GLmethod.createRenderbuffer = i++;
+GLmethod.createShader = i++;           //30
+GLmethod.createTexture = i++;
+GLmethod.cullFace = i++;
+GLmethod.deleteBuffer = i++;
+GLmethod.deleteFramebuffer = i++;
+GLmethod.deleteProgram = i++;
+GLmethod.deleteRenderbuffer = i++;
+GLmethod.deleteShader = i++;
+GLmethod.deleteTexture = i++;
+GLmethod.depthFunc = i++;
+GLmethod.depthMask = i++;              //40
+GLmethod.depthRange = i++;
+GLmethod.detachShader = i++;
+GLmethod.disable = i++;
+GLmethod.disableVertexAttribArray = i++;
+GLmethod.drawArrays = i++;
+GLmethod.drawArraysInstancedANGLE = i++;
+GLmethod.drawElements = i++;
+GLmethod.drawElementsInstancedANGLE = i++;
+GLmethod.enable = i++;
+GLmethod.enableVertexAttribArray = i++;    //50
+GLmethod.flush = i++;
+GLmethod.framebufferRenderbuffer = i++;
+GLmethod.framebufferTexture2D = i++;
+GLmethod.frontFace = i++;
+GLmethod.generateMipmap = i++;
+GLmethod.getActiveAttrib = i++;
+GLmethod.getActiveUniform = i++;
+GLmethod.getAttachedShaders = i++;
+GLmethod.getAttribLocation = i++;
+GLmethod.getBufferParameter = i++;         //60
+GLmethod.getContextAttributes = i++;
+GLmethod.getError = i++;
+GLmethod.getExtension = i++;
+GLmethod.getFramebufferAttachmentParameter = i++;
+GLmethod.getParameter = i++;
+GLmethod.getProgramInfoLog = i++;
+GLmethod.getProgramParameter = i++;
+GLmethod.getRenderbufferParameter = i++;
+GLmethod.getShaderInfoLog = i++;
+GLmethod.getShaderParameter = i++;         //70
+GLmethod.getShaderPrecisionFormat = i++;
+GLmethod.getShaderSource = i++;
+GLmethod.getSupportedExtensions = i++;
+GLmethod.getTexParameter = i++;
+GLmethod.getUniform = i++;
+GLmethod.getUniformLocation = i++;
+GLmethod.getVertexAttrib = i++;
+GLmethod.getVertexAttribOffset = i++;
+GLmethod.isBuffer = i++;
+GLmethod.isContextLost = i++;              //80
+GLmethod.isEnabled = i++;
+GLmethod.isFramebuffer = i++;
+GLmethod.isProgram = i++;
+GLmethod.isRenderbuffer = i++;
+GLmethod.isShader = i++;
+GLmethod.isTexture = i++;
+GLmethod.lineWidth = i++;
+GLmethod.linkProgram = i++;
+GLmethod.pixelStorei = i++;
+GLmethod.polygonOffset = i++;              //90
+GLmethod.readPixels = i++;
+GLmethod.renderbufferStorage = i++;
+GLmethod.sampleCoverage = i++;
+GLmethod.scissor = i++;
+GLmethod.shaderSource = i++;
+GLmethod.stencilFunc = i++;
+GLmethod.stencilFuncSeparate = i++;
+GLmethod.stencilMask = i++;
+GLmethod.stencilMaskSeparate = i++;
+GLmethod.stencilOp = i++;                  //100
+GLmethod.stencilOpSeparate = i++;
+GLmethod.texImage2D = i++;
+GLmethod.texParameterf = i++;
+GLmethod.texParameteri = i++;
+GLmethod.texSubImage2D = i++;
+GLmethod.uniform1f = i++;
+GLmethod.uniform1fv = i++;
+GLmethod.uniform1i = i++;
+GLmethod.uniform1iv = i++;
+GLmethod.uniform2f = i++;                  //110
+GLmethod.uniform2fv = i++;
+GLmethod.uniform2i = i++;
+GLmethod.uniform2iv = i++;
+GLmethod.uniform3f = i++;
+GLmethod.uniform3fv = i++;
+GLmethod.uniform3i = i++;
+GLmethod.uniform3iv = i++;
+GLmethod.uniform4f = i++;
+GLmethod.uniform4fv = i++;
+GLmethod.uniform4i = i++;                  //120
+GLmethod.uniform4iv = i++;
+GLmethod.uniformMatrix2fv = i++;
+GLmethod.uniformMatrix3fv = i++;
+GLmethod.uniformMatrix4fv = i++;
+GLmethod.useProgram = i++;
+GLmethod.validateProgram = i++;
+GLmethod.vertexAttrib1f = i++; //new
+GLmethod.vertexAttrib2f = i++; //new
+GLmethod.vertexAttrib3f = i++; //new
+GLmethod.vertexAttrib4f = i++; //new       //130
+GLmethod.vertexAttrib1fv = i++; //new
+GLmethod.vertexAttrib2fv = i++; //new
+GLmethod.vertexAttrib3fv = i++; //new
+GLmethod.vertexAttrib4fv = i++; //new
+GLmethod.vertexAttribPointer = i++;
+GLmethod.viewport = i++;
+
+export default GLmethod;

+ 23 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js

@@ -0,0 +1,23 @@
+const GLtype = {};
+
+[
+    "GLbitfield",    
+    "GLboolean",
+    "GLbyte",
+    "GLclampf",
+    "GLenum",
+    "GLfloat",
+    "GLint",
+    "GLintptr",
+    "GLsizei",
+    "GLsizeiptr",
+    "GLshort",
+    "GLubyte",
+    "GLuint",
+    "GLushort"
+].sort().map((typeName, i) => GLtype[typeName] = 1 >> (i + 1));
+
+export default GLtype;
+
+
+

+ 21 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLProgram';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLProgram {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 21 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLRenderBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLRenderbuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 1191 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js

@@ -0,0 +1,1191 @@
+import GLenum from './GLenum';
+import ActiveInfo from './ActiveInfo';
+import Buffer from './Buffer';
+import Framebuffer from './Framebuffer';
+import Renderbuffer from './Renderbuffer';
+import Texture from './Texture';
+import Program from './Program';
+import Shader from './Shader';
+import ShaderPrecisionFormat from './ShaderPrecisionFormat';
+import UniformLocation from './UniformLocation';
+import GLmethod from './GLmethod';
+
+const processArray = (array, checkArrayType = false) => {
+
+    function joinArray(arr, sep) {
+        let res = '';
+        for (let i = 0; i < arr.length; i++) {
+            if (i !== 0) {
+                res += sep;
+            }
+            res += arr[i];
+        }
+        return res;
+    }
+
+    let type = 'Float32Array';
+    if (checkArrayType) {
+        if (array instanceof Uint8Array) {
+            type = 'Uint8Array'
+        } else if (array instanceof Uint16Array) {
+            type = 'Uint16Array';
+        } else if (array instanceof Uint32Array) {
+            type = 'Uint32Array';
+        } else if (array instanceof Float32Array) {
+            type = 'Float32Array';
+        } else {
+            throw new Error('Check array type failed. Array type is ' + typeof array);
+        }
+    }
+
+    const ArrayTypes = {
+        Uint8Array: 1,
+        Uint16Array: 2,
+        Uint32Array: 4,
+        Float32Array: 14
+    };
+    return ArrayTypes[type] + ',' + btoa(joinArray(array, ','))
+}
+
+export default class WebGLRenderingContext {
+
+    // static GBridge = null;
+
+    className = 'WebGLRenderingContext';
+
+    constructor(canvas, type, attrs) {
+        this._canvas = canvas;
+        this._type = type;
+        this._version = 'WebGL 1.0';
+        this._attrs = attrs;
+        this._map = new Map();
+
+        Object.keys(GLenum)
+            .forEach(name => Object.defineProperty(this, name, {
+                value: GLenum[name]
+            }));
+    }
+
+    get canvas() {
+        return this._canvas;
+    }
+
+    activeTexture = function (textureUnit) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.activeTexture + ',' + textureUnit,
+            true
+        );
+    }
+
+    attachShader = function (progarm, shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.attachShader + ',' + progarm.id + ',' + shader.id,
+            true
+        );
+    }
+
+    bindAttribLocation = function (program, index, name) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindAttribLocation + ',' + program.id + ',' + index + ',' + name,
+            true
+        )
+    }
+
+    bindBuffer = function (target, buffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindBuffer + ',' + target + ',' + (buffer ? buffer.id : 0),
+            true
+        );
+    }
+
+    bindFramebuffer = function (target, framebuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindFramebuffer + ',' + target + ',' + (framebuffer ? framebuffer.id : 0),
+            true
+        )
+    }
+
+    bindRenderbuffer = function (target, renderBuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindRenderbuffer + ',' + target + ',' + (renderBuffer ? renderBuffer.id : 0),
+            true
+        )
+    }
+
+    bindTexture = function (target, texture) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindTexture + ',' + target + ',' + (texture ? texture.id : 0),
+            true
+        )
+    }
+
+    blendColor = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendColor + ',' + target + ',' + r + ',' + g + ',' + b + ',' + a,
+            true
+        )
+    }
+
+    blendEquation = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendEquation + ',' + mode,
+            true
+        )
+    }
+
+    blendEquationSeparate = function (modeRGB, modeAlpha) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendEquationSeparate + ',' + modeRGB + ',' + modeAlpha,
+            true
+        )
+    }
+
+
+    blendFunc = function (sfactor, dfactor) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendFunc + ',' + sfactor + ',' + dfactor,
+            true
+        );
+    }
+
+    blendFuncSeparate = function (srcRGB, dstRGB, srcAlpha, dstAlpha) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendFuncSeparate + ',' + srcRGB + ',' + dstRGB + ',' + srcAlpha + ',' + dstAlpha,
+            true
+        );
+    }
+
+    bufferData = function (target, data, usage) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bufferData + ',' + target + ',' + processArray(data, true) + ',' + usage,
+            true
+        )
+    }
+
+    bufferSubData = function (target, offset, data) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bufferSubData + ',' + target + ',' + offset + ',' + processArray(data, true),
+            true
+        )
+    }
+
+    checkFramebufferStatus = function (target) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.checkFramebufferStatus + ',' + target
+        );
+        return Number(result);
+    }
+
+    clear = function (mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clear + ',' + mask
+        );
+        this._canvas._needRender = true;
+    }
+
+    clearColor = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearColor + ',' + r + ',' + g + ',' + b,
+            true
+        )
+    }
+
+    clearDepth = function (depth) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearDepth + ',' + depth,
+            true
+        )
+    }
+
+    clearStencil = function (s) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearStencil + ',' + s
+        );
+    }
+
+    colorMask = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.colorMask + ',' + r + ',' + g + ',' + b + ',' + a
+        )
+    }
+
+    compileShader = function (shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compileShader + ',' + shader.id,
+            true
+        )
+    }
+
+    compressedTexImage2D = function (target, level, internalformat, width, height, border, pixels) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compressedTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' +
+            width + ',' + height + ',' + border + ',' + processArray(pixels),
+            true
+        )
+    }
+
+    compressedTexSubImage2D = function (target, level, xoffset, yoffset, width, height, format, pixels) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compressedTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' +
+            width + ',' + height + ',' + format + ',' + processArray(pixels),
+            true
+        )
+    }
+
+
+    copyTexImage2D = function (target, level, internalformat, x, y, width, height, border) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.copyTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' + x + ',' + y + ',' +
+            width + ',' + height + ',' + border,
+            true
+        );
+    }
+
+    copyTexSubImage2D = function (target, level, xoffset, yoffset, x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.copyTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' + x + ',' + y + ',' +
+            width + ',' + height
+        );
+    }
+
+    createBuffer = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createBuffer + ''
+        );
+        const buffer = new Buffer(result);
+        this._map.set(buffer.uuid(), buffer);
+        return buffer;
+    }
+
+    createFramebuffer = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createFramebuffer + ''
+        );
+        const framebuffer = new Framebuffer(result);
+        this._map.set(framebuffer.uuid(), framebuffer);
+        return framebuffer;
+    }
+
+
+    createProgram = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createProgram + ''
+        );
+        const program = new Program(id);
+        this._map.set(program.uuid(), program);
+        return program;
+    }
+
+    createRenderbuffer = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createRenderbuffer + ''
+        )
+        const renderBuffer = new Renderbuffer(id);
+        this._map.set(renderBuffer.uuid(), renderBuffer);
+        return renderBuffer;
+    }
+
+    createShader = function (type) {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createShader + ',' + type
+        )
+        const shader = new Shader(id, type);
+        this._map.set(shader.uuid(), shader);
+        return shader;
+    }
+
+    createTexture = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createTexture + ''
+        );
+        const texture = new Texture(id);
+        this._map.set(texture.uuid(), texture);
+        return texture;
+    }
+
+    cullFace = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.cullFace + ',' + mode,
+            true
+        )
+    }
+
+
+    deleteBuffer = function (buffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteBuffer + ',' + buffer.id,
+            true
+        )
+    }
+
+    deleteFramebuffer = function (framebuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteFramebuffer + ',' + framebuffer.id,
+            true
+        )
+    }
+
+    deleteProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteProgram + ',' + program.id,
+            true
+        )
+    }
+
+    deleteRenderbuffer = function (renderbuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteRenderbuffer + ',' + renderbuffer.id,
+            true
+        )
+    }
+
+    deleteShader = function (shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteShader + ',' + shader.id,
+            true
+        )
+    }
+
+    deleteTexture = function (texture) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteTexture + ',' + texture.id,
+            true
+        )
+    }
+
+    depthFunc = function (func) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthFunc + ',' + func
+        )
+    }
+
+    depthMask = function (flag) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthMask + ',' + Number(flag),
+            true
+        )
+    }
+
+    depthRange = function (zNear, zFar) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthRange + ',' + zNear + ',' + zFar,
+            true
+        )
+    }
+
+    detachShader = function (program, shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.detachShader + ',' + program.id + ',' + shader.id,
+            true
+        )
+    }
+
+    disable = function (cap) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.disable + ',' + cap,
+            true
+        )
+    }
+
+    disableVertexAttribArray = function (index) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.disableVertexAttribArray + ',' + index,
+            true
+        );
+    }
+
+    drawArrays = function (mode, first, count) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.drawArrays + ',' + mode + ',' + first + ',' + count
+        )
+        this._canvas._needRender = true;
+    }
+
+    drawElements = function (mode, count, type, offset) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.drawElements + ',' + mode + ',' + count + ',' + type + ',' + offset + ';'
+        );
+        this._canvas._needRender = true;
+    }
+
+    enable = function (cap) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.enable + ',' + cap,
+            true
+        );
+    }
+
+    enableVertexAttribArray = function (index) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.enableVertexAttribArray + ',' + index,
+            true
+        )
+    }
+
+
+    flush = function () {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.flush + ''
+        )
+    }
+
+    framebufferRenderbuffer = function (target, attachment, textarget, texture, level) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.framebufferRenderbuffer + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
+            true
+        )
+    }
+
+    framebufferTexture2D = function (target, attachment, textarget, texture, level) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.framebufferTexture2D + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
+            true
+        )
+    }
+
+    frontFace = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.frontFace + ',' + mode,
+            true
+        )
+    }
+
+    generateMipmap = function (target) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.generateMipmap + ',' + target,
+            true
+        )
+    }
+
+    getActiveAttrib = function (progarm, index) {
+        const resultString = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getActiveAttrib + ',' + progarm.id + ',' + index
+        )
+        const [type, size, name] = resultString.split(',');
+        return new ActiveInfo({
+            type: Number(type),
+            size: Number(size),
+            name
+        });
+    }
+
+    getActiveUniform = function (progarm, index) {
+        const resultString = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getActiveUniform + ',' + progarm.id + ',' + index
+        );
+        const [type, size, name] = resultString.split(',');
+        return new ActiveInfo({
+            type: Number(type),
+            size: Number(size),
+            name
+        })
+    }
+
+    getAttachedShaders = function (progarm) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getAttachedShaders + ',' + progarm.id
+        );
+        const [type, ...ids] = result;
+        return ids.map(id => this._map.get(Shader.uuid(id)));
+    }
+
+    getAttribLocation = function (progarm, name) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getAttribLocation + ',' + progarm.id + ',' + name
+        )
+    }
+
+    getBufferParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getBufferParameter + ',' + target + ',' + pname
+        );
+        const [type, res] = getBufferParameter;
+        return res;
+    }
+
+    getError = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getError + ''
+        )
+        return result;
+    }
+
+    getExtension = function (name) {
+        return null;
+    }
+
+    getFramebufferAttachmentParameter = function (target, attachment, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getFramebufferAttachmentParameter + ',' + target + ',' + attachment + ',' + pname
+        )
+        switch (pname) {
+            case GLenum.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+                return this._map.get(Renderbuffer.uuid(result)) || this._map.get(Texture.uuid(result)) || null;
+            default:
+                return result;
+        }
+    }
+
+    getParameter = function (pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getParameter + ',' + pname
+        )
+        switch (pname) {
+            case GLenum.VERSION:
+                return this._version;
+            case GLenum.ARRAY_BUFFER_BINDING: // buffer
+            case GLenum.ELEMENT_ARRAY_BUFFER_BINDING: // buffer
+                return this._map.get(Buffer.uuid(result)) || null;
+            case GLenum.CURRENT_PROGRAM: // program
+                return this._map.get(Program.uuid(result)) || null;
+            case GLenum.FRAMEBUFFER_BINDING: // framebuffer
+                return this._map.get(Framebuffer.uuid(result)) || null;
+            case GLenum.RENDERBUFFER_BINDING: // renderbuffer
+                return this._map.get(Renderbuffer.uuid(result)) || null;
+            case GLenum.TEXTURE_BINDING_2D: // texture
+            case GLenum.TEXTURE_BINDING_CUBE_MAP: // texture
+                return this._map.get(Texture.uuid(result)) || null;
+            case GLenum.ALIASED_LINE_WIDTH_RANGE: // Float32Array
+            case GLenum.ALIASED_POINT_SIZE_RANGE: // Float32Array
+            case GLenum.BLEND_COLOR: // Float32Array
+            case GLenum.COLOR_CLEAR_VALUE: // Float32Array
+            case GLenum.DEPTH_RANGE: // Float32Array
+            case GLenum.MAX_VIEWPORT_DIMS: // Int32Array
+            case GLenum.SCISSOR_BOX: // Int32Array
+            case GLenum.VIEWPORT: // Int32Array            
+            case GLenum.COMPRESSED_TEXTURE_FORMATS: // Uint32Array
+            default:
+                const [type, ...res] = result.split(',');
+                if (res.length === 1) {
+                    return Number(res[0]);
+                } else {
+                    return res.map(Number);
+                }
+        }
+    }
+
+    getProgramInfoLog = function (progarm) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getProgramInfoLog + ',' + progarm.id
+        )
+    }
+
+    getProgramParameter = function (program, pname) {
+        const res = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getProgramParameter + ',' + program.id + ',' + pname
+        );
+
+        const [type, result] = res.split(',').map(i => parseInt(i));
+
+        if (type === 1) {
+            return Boolean(result);
+        } else if (type === 2) {
+            return result;
+        } else {
+            throw new Error('Unrecongized program paramater ' + res + ', type: ' + typeof res);
+        }
+    }
+
+
+    getRenderbufferParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getRenderbufferParameter + ',' + target + ',' + pname
+        )
+        return result;
+    }
+
+
+    getShaderInfoLog = function (shader) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderInfoLog + ',' + shader.id
+        );
+    }
+
+    getShaderParameter = function (shader, pname) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderParameter + ',' + shader.id + ',' + pname
+        )
+    }
+
+    getShaderPrecisionFormat = function (shaderType, precisionType) {
+        const [rangeMin, rangeMax, precision] = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderPrecisionFormat + ',' + shaderType + ',' + precisionType
+        );
+        const shaderPrecisionFormat = new ShaderPrecisionFormat({
+            rangeMin: Number(rangeMin),
+            rangeMax: Number(rangeMax),
+            precision: Number(precision)
+        });
+        return shaderPrecisionFormat;
+    }
+
+    getShaderSource = function (shader) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderSource + ',' + shader.id
+        );
+        return result;
+    }
+
+    getSupportedExtensions = function () {
+        return Object.keys({});
+    }
+
+    getTexParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getTexParameter + ',' + target + ',' + pname
+        )
+        return result;
+    }
+
+    getUniformLocation = function (program, name) {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getUniformLocation + ',' + program.id + ',' + name
+        );
+        if (id === -1) {
+            return null;
+        } else {
+            return new UniformLocation(Number(id));
+        }
+    }
+
+    getVertexAttrib = function (index, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getVertexAttrib + ',' + index + ',' + pname
+        );
+        switch (pname) {
+            case GLenum.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+                return this._map.get(Buffer.uuid(result)) || null;
+            case GLenum.CURRENT_VERTEX_ATTRIB: // Float32Array
+            default:
+                return result;
+        }
+    }
+
+    getVertexAttribOffset = function (index, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getVertexAttribOffset + ',' + index + ',' + pname
+        )
+        return Number(result);
+    }
+
+    isBuffer = function (buffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isBuffer + ',' + buffer.id
+        )
+        return Boolean(result);
+    }
+
+    isContextLost = function () {
+        return false;
+    }
+
+    isEnabled = function (cap) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isEnabled + ',' + cap
+        )
+        return Boolean(result);
+    }
+
+    isFramebuffer = function (framebuffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isFramebuffer + ',' + framebuffer.id
+        )
+        return Boolean(result);
+    }
+
+    isProgram = function (program) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isProgram + ',' + program.id
+        )
+        return Boolean(result);
+    }
+
+    isRenderbuffer = function (renderBuffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isRenderbuffer + ',' + renderbuffer.id
+        )
+        return Boolean(result);
+    }
+
+    isShader = function (shader) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isShader + ',' + shader.id
+        )
+        return Boolean(result);
+    }
+
+    isTexture = function (texture) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isTexture + ',' + texture.id
+        );
+        return Boolean(result);
+    }
+
+    lineWidth = function (width) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.lineWidth + ',' + width,
+            true
+        )
+    }
+
+    linkProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.linkProgram + ',' + program.id,
+            true
+        );
+    }
+
+
+    pixelStorei = function (pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.pixelStorei + ',' + pname + ',' + Number(param)
+        )
+    }
+
+    polygonOffset = function (factor, units) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.polygonOffset + ',' + factor + ',' + units
+        )
+    }
+
+    readPixels = function (x, y, width, height, format, type, pixels) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.readPixels + ',' + x + ',' + y + ',' + width + ',' + height + ',' + format + ',' + type
+        )
+        return result;
+    }
+
+    renderbufferStorage = function (target, internalFormat, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.renderbufferStorage + ',' + target + ',' + internalFormat + ',' + width + ',' + height,
+            true
+        )
+    }
+
+    sampleCoverage = function (value, invert) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.sampleCoverage + ',' + value + ',' + Number(invert),
+            true
+        )
+    }
+
+    scissor = function (x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.scissor + ',' + x + ',' + y + ',' + width + ',' + height,
+            true
+        )
+    }
+
+    shaderSource = function (shader, source) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.shaderSource + ',' + shader.id + ',' + source
+        )
+    }
+
+    stencilFunc = function (func, ref, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilFunc + ',' + func + ',' + ref + ',' + mask,
+            true
+        )
+    }
+
+    stencilFuncSeparate = function (face, func, ref, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilFuncSeparate + ',' + face + ',' + func + ',' + ref + ',' + mask,
+            true
+        )
+    }
+
+    stencilMask = function (mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilMask + ',' + mask,
+            true
+        )
+    }
+
+    stencilMaskSeparate = function (face, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilMaskSeparate + ',' + face + ',' + mask,
+            true
+        )
+    }
+
+    stencilOp = function (fail, zfail, zpass) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilOp + ',' + fail + ',' + zfail + ',' + zpass
+        )
+    }
+
+    stencilOpSeparate = function (face, fail, zfail, zpass) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilOp + ',' + face + ',' + fail + ',' + zfail + ',' + zpass,
+            true
+        )
+    }
+
+    texImage2D = function (...args) {
+        WebGLRenderingContext.GBridge.texImage2D(this._canvas.id, ...args);
+    }
+
+
+    texParameterf = function (target, pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.texParameterf + ',' + target + ',' + pname + ',' + param,
+            true
+        )
+    }
+
+    texParameteri = function (target, pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.texParameteri + ',' + target + ',' + pname + ',' + param
+        )
+    }
+
+    texSubImage2D = function (...args) {
+        WebGLRenderingContext.GBridge.texSubImage2D(this._canvas.id, ...args);
+    }
+
+    uniform1f = function (location, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1f + ',' + location.id + ',' + v0
+        )
+    }
+
+    uniform1fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform1i = function (location, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1i + ',' + location.id + ',' + v0,
+            // true
+        )
+    }
+
+    uniform1iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform2f = function (location, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2f + ',' + location.id + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    uniform2fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform2i = function (location, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2i + ',' + location.id + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    uniform2iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform3f = function (location, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    uniform3fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform3i = function (location, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    uniform3iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform4f = function (location, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    uniform4fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform4i = function (location, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    uniform4iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4iv + ',' + location.id + ',' + processArray(value, true),
+            true
+        )
+    }
+
+    uniformMatrix2fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix2fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniformMatrix3fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix3fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniformMatrix4fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix4fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        );
+    }
+
+    useProgram = function (progarm) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.useProgram + ',' + progarm.id + '',
+            true
+        )
+    }
+
+
+    validateProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.validateProgram + ',' + program.id,
+            true
+        )
+    }
+
+    vertexAttrib1f = function (index, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib1f + ',' + index + ',' + v0,
+            true
+        )
+    }
+
+    vertexAttrib2f = function (index, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib2f + ',' + index + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    vertexAttrib3f = function (index, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib3f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    vertexAttrib4f = function (index, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib4f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    vertexAttrib1fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib1fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib2fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib2fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib3fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib3fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib4fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib4fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttribPointer = function (index, size, type, normalized, stride, offset) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttribPointer + ',' + index + ',' + size + ',' + type + ',' + Number(normalized) + ',' + stride + ',' + offset,
+            true
+        )
+    }
+
+    viewport = function (x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.viewport + ',' + x + ',' + y + ',' + width + ',' + height,
+            true
+        )
+    }
+}

+ 22 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js

@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLShader';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLShader {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 11 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js

@@ -0,0 +1,11 @@
+export default class WebGLShaderPrecisionFormat {
+    className = 'WebGLShaderPrecisionFormat';
+
+    constructor({
+        rangeMin, rangeMax, precision
+    }) {
+        this.rangeMin = rangeMin;
+        this.rangeMax = rangeMax;
+        this.precision = precision;
+    }
+}

+ 22 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js

@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLTexture';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLTexture {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 22 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js

@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLUniformLocation';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLUniformLocation {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 3 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js

@@ -0,0 +1,3 @@
+export function getTransferedObjectUUID(name, id) {
+    return `${name.toLowerCase()}-${id}`;
+}

+ 74 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js

@@ -0,0 +1,74 @@
+import GContext2D from '../context-2d/RenderingContext';
+import GContextWebGL from '../context-webgl/RenderingContext';
+
+export default class GCanvas {
+
+    // static GBridge = null;
+
+    id = null;
+
+    _needRender = true;
+
+    constructor(id, { disableAutoSwap }) {
+        this.id = id;
+
+        this._disableAutoSwap = disableAutoSwap;
+        if (disableAutoSwap) {
+            this._swapBuffers = () => {
+                GCanvas.GBridge.render(this.id);
+            }
+        }
+    }
+
+    getContext(type) {
+
+        let context = null;
+
+        if (type.match(/webgl/i)) {
+            context = new GContextWebGL(this);
+
+            context.componentId = this.id;
+
+            if (!this._disableAutoSwap) {
+                const render = () => {
+                    if (this._needRender) {
+                        GCanvas.GBridge.render(this.id);
+                        this._needRender = false;
+                    }
+                }
+                setInterval(render, 16);
+            }
+
+            GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
+        } else if (type.match(/2d/i)) {
+            context = new GContext2D(this);
+
+            context.componentId = this.id;
+
+//             const render = ( callback ) => {
+// 
+//                 const commands = context._drawCommands;
+//                 context._drawCommands = '';
+// 
+//                 GCanvas.GBridge.render2d(this.id, commands, callback);
+//                 this._needRender = false;
+//             }
+// 			//draw方法触发
+// 			context._flush = render;
+//             //setInterval(render, 16);
+
+            GCanvas.GBridge.callSetContextType(this.id, 0);
+        } else {
+            throw new Error('not supported context ' + type);
+        }
+
+        return context;
+
+    }
+
+    reset() {
+        GCanvas.GBridge.callReset(this.id);
+    }
+
+
+}

+ 96 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js

@@ -0,0 +1,96 @@
+let incId = 1;
+
+const noop = function () { };
+
+class GImage {
+
+    static GBridge = null;
+
+    constructor() {
+        this._id = incId++;
+        this._width = 0;
+        this._height = 0;
+        this._src = undefined;
+        this._onload = noop;
+        this._onerror = noop;
+        this.complete = false;
+    }
+
+    get width() {
+        return this._width;
+    }
+    set width(v) {
+        this._width = v;
+    }
+
+    get height() {
+        return this._height;
+    }
+
+    set height(v) {
+        this._height = v;
+    }
+
+    get src() {
+        return this._src;
+    }
+
+    set src(v) {
+
+        if (v.startsWith('//')) {
+            v = 'http:' + v;
+        }
+
+        this._src = v;
+
+        GImage.GBridge.perloadImage([this._src, this._id], (data) => {
+            if (typeof data === 'string') {
+                data = JSON.parse(data);
+            }
+            if (data.error) {
+                var evt = { type: 'error', target: this };
+                this.onerror(evt);
+            } else {
+                this.complete = true;
+                this.width = typeof data.width === 'number' ? data.width : 0;
+                this.height = typeof data.height === 'number' ? data.height : 0;
+                var evt = { type: 'load', target: this };
+                this.onload(evt);
+            }
+        });
+    }
+
+    addEventListener(name, listener) {
+        if (name === 'load') {
+            this.onload = listener;
+        } else if (name === 'error') {
+            this.onerror = listener;
+        }
+    }
+
+    removeEventListener(name, listener) {
+        if (name === 'load') {
+            this.onload = noop;
+        } else if (name === 'error') {
+            this.onerror = noop;
+        }
+    }
+
+    get onload() {
+        return this._onload;
+    }
+
+    set onload(v) {
+        this._onload = v;
+    }
+
+    get onerror() {
+        return this._onerror;
+    }
+
+    set onerror(v) {
+        this._onerror = v;
+    }
+}
+
+export default GImage;

+ 24 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js

@@ -0,0 +1,24 @@
+
+export function ArrayBufferToBase64 (buffer) {
+    var binary = '';
+    var bytes = new Uint8ClampedArray(buffer);
+    for (var len = bytes.byteLength, i = 0; i < len; i++) {
+        binary += String.fromCharCode(bytes[i]);
+    }
+    return btoa(binary);
+}
+	
+export function Base64ToUint8ClampedArray(base64String) {
+	const padding = '='.repeat((4 - base64String.length % 4) % 4);
+	const base64 = (base64String + padding)
+		.replace(/\-/g, '+')
+		.replace(/_/g, '/');
+
+	const rawData = atob(base64);
+	const outputArray = new Uint8ClampedArray(rawData.length);
+
+	for (let i = 0; i < rawData.length; ++i) {
+		outputArray[i] = rawData.charCodeAt(i);
+	}
+	return outputArray;
+}

+ 39 - 0
uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js

@@ -0,0 +1,39 @@
+import GCanvas from './env/canvas';
+import GImage from './env/image';
+
+import GWebGLRenderingContext from './context-webgl/RenderingContext';
+import GContext2D from './context-2d/RenderingContext';
+
+import GBridgeWeex from './bridge/bridge-weex';
+
+export let Image = GImage;
+
+export let WeexBridge = GBridgeWeex;
+
+export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) {
+
+    const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
+
+    GBridge.callEnable(el.ref, [
+        0,      // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY
+        -1,     // hybridLayerType:  0--LAYER_TYPE_NONE 1--LAYER_TYPE_SOFTWARE 2--LAYER_TYPE_HARDWARE
+        false,  // supportScroll
+        false,  // newCanvasMode
+        1,      // compatible
+        'white',// clearColor
+        false   // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
+    ]);
+
+    if (debug === true) {
+        GBridge.callEnableDebug();
+    }
+    if (disableComboCommands) {
+        GBridge.callEnableDisableCombo();
+    }
+
+    var canvas = new GCanvas(el.ref, { disableAutoSwap });
+    canvas.width = el.style.width;
+    canvas.height = el.style.height;
+
+    return canvas;
+};

Разница между файлами не показана из-за своего большого размера
+ 33 - 0
uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js


+ 80 - 0
uni_modules/Sansnn-uQRCode/package.json

@@ -0,0 +1,80 @@
+{
+  "id": "Sansnn-uQRCode",
+  "displayName": "uQRCode 全端二维码生成插件 支持nvue 支持nodejs服务端",
+  "version": "4.0.6",
+  "description": "uQRCode是一款基于Javascript环境开发的二维码生成插件,适用所有Javascript运行环境的前端应用和Node.js。",
+  "keywords": [
+    "二维码",
+    "uQRCode",
+    "qrcode",
+    "qr"
+],
+  "repository": "https://github.com/Sansnn/uQRCode",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/uqrcodejs",
+    "type": "sdk-js"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        },
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 223 - 0
uni_modules/lime-painter/changelog.md

@@ -0,0 +1,223 @@
+## 1.9.6.5(2024-04-14)
+- fix: 修复`nvue`无法生图的问题
+## 1.9.6.4(2024-03-10)
+- fix: 修复代理ctx导致H5不能使用ctx.save
+## 1.9.6.3(2024-03-08)
+- fix: 修复支付宝真机无法使用的问题
+## 1.9.6.2(2024-02-22)
+- fix: 修复使用render函数报错的问题
+## 1.9.6.1(2023-12-22)
+- fix: 修复字节小程序非2d字体偏移
+- fix: 修复`canvasToTempFilePathSync`会触发两次的问题
+- fix: 修复`parser`图片没有宽度的问题
+## 1.9.6(2023-12-06)
+- fix: 修复背景图受padding影响
+- fix: 修复因字节报错改了代理实现导致微信报错
+- 1.9.5.8(2023-11-16)
+- fix: 修复margin问题
+- fix: 修复borderWidth问题
+- fix: 修复textBox问题
+- fix: 修复字节开发工具报`could not be cloned.`问题
+## 1.9.5.7(2023-07-27)
+- fix: 去掉多余的方法
+- chore: 更新文档,增加自定义字体说明
+## 1.9.5.6(2023-07-21)
+- feat: 有限的支持富文本
+- feat: H5和APP 增加 `hidpi` prop,主要用于大尺寸无法生成图片时用
+- fix: 修复 钉钉小程序 缺少 `measureText` 方法
+- chore: 由于微信小程序 pc 端的 canvas 2d 时不时抽风,故不使用canvas 2d
+## 1.9.5.5(2023-06-27)
+- fix: 修复把`emoji`表情字符拆分成多个字符的情况
+## 1.9.5.4(2023-06-05)
+- fix: 修复因`canvasToTempFilePathSync`监听导致重复调用
+## 1.9.5.3(2023-05-23)
+- fix: 因isPc错写成了isPC导致小程序PC不能生成图片
+## 1.9.5.2(2023-05-22)
+- feat: 删除多余文件
+## 1.9.5.1(2023-05-22)
+- fix: 修复 文字行数与`line-clamp`相同但不满一行时也加了省略号的问题
+## 1.9.5(2023-05-14)
+- feat: 增加 `text-indent` 和 `calc` 方法
+- feat: 优化 布局时间
+## 1.9.4.4(2023-04-15)
+- fix: 修复无法匹配负值
+- fix: 修复 Nvue IOS getImageInfo `useCORS` 为 undefined
+## 1.9.4.3(2023-04-01)
+- feat: 增加支持文字描边 `text-stroke: '5rpx #fff'`
+## 1.9.4.2(2023-03-30)
+- fix: 修复 支付宝小程序 isPC 在手机也为true的问题
+- feat: 由 微信开发工具 3060 版 无法获取图片尺寸,现 微信开发工具 3220 版 修复该问题,故还原上一版的获取图片方式。
+## 1.9.4.1(2023-03-28)
+- fix: 修复固定高度不正确问题
+## 1.9.4(2023-03-17)
+- fix: nvue ios getImageInfo缺少this报错
+- fix: pathType 非2d无效问题
+- fix: 修复 小米9se 可能会存在多次init 导致画面多次放大
+- fix: 修复 border 分开写 width style无效问题
+- fix: 修复 支付宝小程序IOS 再次进入不渲染的问题
+- fix: 修复 支付宝小程序安卓Zindex排序错乱问题
+- fix: 修复 微信开发工具 3060 版 无法获取图片的问题
+- feat: 把 for in 改为 forEach
+- feat: 增加 hidden
+- feat: 根节点 box-sizing 默认 `border-box`
+- feat: 增加支持 `vw` `wh`
+- chore: pathType 取消 默认值,因为字节开发工具不能显示
+- chore: 支付宝小程序开发工具不支持 生成图片 请以真机调试为准
+- bug: 企业微信 2.20.3无法使用
+## 1.9.3.5(2022-06-29)
+- feat: justifyContent 增加 `space-around`、`space-between`
+- feat: canvas 2d 也使用`getImageInfo`
+- fix: 修复 `text`的 `text-decoration`错位
+## 1.9.3.4(2022-06-20)
+- fix: 修复 因创建节点速度问题导致顺序出错。 
+- fix: 修复 微信小程序 PC 无法显示本地图片 
+- fix: 修复 flex-box 对齐问题 
+- feat: 增加 `text-shadow`
+- feat: 重写 `text` 对齐方式
+- chore: 更新文档
+## 1.9.3.3(2022-06-17)
+- fix: 修复 支付宝小程序 canvas 2d 存在ctx.draw问题导致报错
+- fix: 修复 支付宝小程序 toDataURL 存在权限问题改用 `toTempFilePath`
+- fix: 修复 支付宝小程序 image size 问题导致 `objectFit` 无效
+## 1.9.3.2(2022-06-14)
+- fix: 修复 image 设置背景色不生效问题
+- fix: 修复 nvue 环境判断缺少参数问题
+## 1.9.3.1(2022-06-14)
+- fix: 修复 bottom 定位不对问题
+- fix: 修复 因小数导致计算出错换行问题
+- feat: 增加 `useCORS` h5端图片跨域 在设置请求头无效果后试一下设置这个值
+- chore: 更新文档
+## 1.9.3(2022-06-13)
+- feat: 增加 `zIndex`
+- feat: 增加 `flex-box` 该功能处于原始阶段,非常简陋。
+- tips: QQ小程序 vue3 不支持, 为 uni 官方BUG
+## 1.9.2.9(2022-06-10)
+- fix: 修复`text-align`及`margin`居中问题
+## 1.9.2.8(2022-06-10)
+- fix: 修复 Nvue `canvasToTempFilePathSync` 不生效问题
+## 1.9.2.7(2022-06-10)
+- fix: 修复 margin及padding的bug
+- fix: 修复 Nvue `isCanvasToTempFilePath` 不生效问题
+## 1.9.2.6(2022-06-09)
+- fix: 修复 Nvue 不显示
+- feat: 增加支持字体渐变
+```html
+<l-painter-text 
+	text="水调歌头\n明月几时有?把酒问青天。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不胜寒。起舞弄清影,何似在人间。"
+	css="background: linear-gradient(,#ff971b 0%, #1989fa 100%); background-clip: text" />
+```
+## 1.9.2.5(2022-06-09)
+- chore: 更变获取父级宽度的设定
+- chore: `pathType` 在canvas 2d 默认为 `url`
+## 1.9.2.4(2022-06-08)
+- fix: 修复 `pathType` 不生效问题
+## 1.9.2.3(2022-06-08)
+- fix: 修复 `canvasToTempFilePath` 漏写 `success` 参数
+## 1.9.2.2(2022-06-07)
+- chore: 更新文档
+## 1.9.2.1(2022-06-07)
+- fix: 修复 vue3 赋值给this再传入导致image无法绘制
+- fix: 修复 `canvasToTempFilePathSync` 时机问题
+- feat: canvas 2d 更改图片生成方式 `toDataURL` 
+## 1.9.2(2022-05-30)
+- fix: 修复 `canvasToTempFilePathSync` 在 vue3 下只生成一次
+## 1.9.1.7(2022-05-28)
+- fix: 修复 `qrcode`显示不全问题
+## 1.9.1.6(2022-05-28)
+- fix: 修复 `canvasToTempFilePathSync` 会重复多次问题
+- fix: 修复 `view` css `backgroundImage` 图片下载失败导致 子节点不渲染
+## 1.9.1.5(2022-05-27)
+- fix: 修正支付宝小程序 canvas 2d版本号 2.7.15
+## 1.9.1.4(2022-05-22)
+- fix: 修复字节小程序无法使用xml方式
+- fix: 修复字节小程序无法使用base64(非2D情况下工具上无法显示)
+- fix: 修复支付宝小程序 `canvasToTempFilePath` 报错
+## 1.9.1.3(2022-04-29)
+- fix: 修复vue3打包后uni对象为空后的报错
+## 1.9.1.2(2022-04-25)
+- fix: 删除多余文件
+## 1.9.1.1(2022-04-25)
+- fix: 修复图片不显示问题
+## 1.9.1(2022-04-12)
+- fix: 因四舍五入导致有些机型错位
+- fix: 修复无views报错 
+- chore: nvue下因ios无法读取插件内static文件,改由下载方式
+## 1.9.0(2022-03-20)
+- fix: 因无法固定尺寸导致生成图片不全
+- fix: 特定情况下text判断无效
+- chore: 本地化APP Nvue webview
+## 1.8.9(2022-02-20)
+- fix: 修复 小程序下载最多10次并发的问题
+- fix: 修复 APP端无法获取本地图片
+- fix: 修复 APP Nvue端不执行问题
+- chore: 增加图片缓存机制
+## 1.8.8.8(2022-01-27)
+- fix: 修复 主动调用尺寸问题
+## 1.8.8.6(2022-01-26)
+- fix: 修复 nvue 下无宽度时获取父级宽度 
+- fix: 修复 ios app 无法渲染问题
+## 1.8.8(2022-01-23)
+- fix: 修复 主动调用时无节点问题
+- fix: 修复 `box-shadow` 颜色问题
+- fix: 修复 `transform:rotate` 角度位置问题
+- feat: 增加 `overflow:hidden`
+## 1.8.7(2022-01-07)
+- fix: 修复 image 方向为 `right` 时原始宽高问题
+- feat: 支持 view 设置背景图 `background-image: url(xxx)`
+- chore: 去掉可选链
+## 1.8.6(2021-11-28)
+- feat: 支持`view`对`inline-block`的子集使用`text-align`
+## 1.8.5.5(2021-08-17)
+- chore: 更新文档,删除 replace
+- fix: 修复 text 值为 number时报错
+## 1.8.5.4(2021-08-16)
+- fix: 字节小程序兼容
+## 1.8.5.3(2021-08-15)
+- fix: 修复线性渐变与css现实效果不一致的问题
+- chore: 更新文档
+## 1.8.5.2(2021-08-13)
+- chore: 增加`background-image`、`background-repeat` 能力,主要用于背景纹理的绘制,并不是代替`image`。例如:大面积的重复平铺的水印
+- 注意:这个功能H5暂时无法使用,因为[官方的API有BUG](https://ask.dcloud.net.cn/question/128793),待官方修复!!!
+## 1.8.5.1(2021-08-10)
+- fix: 修复因`margin`报错问题
+## 1.8.5(2021-08-09)
+- chore: 增加margin支持`auto`,以达到居中效果
+## 1.8.4(2021-08-06)
+- chore: 增加判断缓存文件条件
+- fix: 修复css 多余空格报错问题
+## 1.8.3(2021-08-04)
+- tips: 1.6.x 以下的版本升级到1.8.x后要为每个元素都加上定位:position: 'absolute'
+- fix: 修复只有一个view子元素时不计算高度的问题
+## 1.8.2(2021-08-03)
+- fix: 修复 path-type 为 `url` 无效问题
+- fix: 修复 qrcode `text` 为空时报错问题
+- fix: 修复 image `src` 动态设置时不生效问题
+- feat: 增加 css 属性 `min-width` `max-width`
+## 1.8.1(2021-08-02)
+- fix: 修复无法加载本地图片
+## 1.8.0(2021-08-02)
+- chore 文档更新
+- 使用旧版的同学不要升级!
+## 1.8.0-beta(2021-07-30)
+- ## 全新布局方式 不兼容旧版!
+- chore: 布局方式变更
+- tips: 微信canvas 2d 不支持真机调试
+## 1.6.6(2021-07-09)
+- chore: 统一命名规范,无须主动引入组件
+## 1.6.5(2021-06-08)
+- chore: 去掉console
+## 1.6.4(2021-06-07)
+- fix: 修复 数字 为纯字符串时不转换的BUG
+## 1.6.3(2021-06-06)
+- fix: 修复 PC 端放大的BUG
+## 1.6.2(2021-05-31)
+- fix: 修复 报`adaptor is not a function`错误
+- fix: 修复 text 多行高度
+- fix: 优化 默认文字的基准线
+- feat: `@progress`事件,监听绘制进度
+## 1.6.1(2021-02-28)
+- 删除多余节点
+## 1.6.0(2021-02-26)
+- 调整为uni_modules目录规范
+- 修复:transform的rotate不能为负数问题
+- 新增:`pathType` 指定生成图片返回的路径类型,可选值有 `base64`、`url`

+ 150 - 0
uni_modules/lime-painter/components/common/relation.js

@@ -0,0 +1,150 @@
+const styles = (v ='') =>  v.split(';').filter(v => v && !/^[\n\s]+$/.test(v)).map(v => {
+						const key = v.slice(0, v.indexOf(':'))
+						const value = v.slice(v.indexOf(':')+1)
+						return {
+							[key
+								.replace(/-([a-z])/g, function() { return arguments[1].toUpperCase()})
+								.replace(/\s+/g, '')
+							]: value.replace(/^\s+/, '').replace(/\s+$/, '') || ''
+						}
+					})
+export function parent(parent) {
+	return {
+		provide() {
+			return {
+				[parent]: this
+			}
+		},
+		data() {
+			return {
+				el: {
+					id: null,
+					css: {},
+					views: []
+				},
+			}
+		},
+		watch: {
+			css: { 
+				handler(v) {
+					if(this.canvasId) {
+						this.el.css = (typeof v == 'object' ? v : v && Object.assign(...styles(v))) || {}
+						this.canvasWidth = this.el.css && this.el.css.width || this.canvasWidth
+						this.canvasHeight = this.el.css && this.el.css.height || this.canvasHeight
+					}
+				},
+				immediate: true
+			}
+		}
+	}
+}
+export function children(parent, options = {}) {
+	const indexKey = options.indexKey || 'index'
+	return {
+		inject: {
+			[parent]: {
+				default: null
+			}
+		},
+		watch: {
+			el: {
+				handler(v, o) {
+					if(JSON.stringify(v) != JSON.stringify(o))
+						this.bindRelation()
+				},
+				deep: true,
+				immediate: true
+			},
+			src: {
+				handler(v, o) {
+					if(v != o)
+						this.bindRelation()
+				},
+				immediate: true
+			},
+			text: {
+				handler(v, o) {
+					if(v != o) this.bindRelation()
+				},
+				immediate: true
+			},
+			css: {
+				handler(v, o) {
+					if(v != o)
+						this.el.css = (typeof v == 'object' ? v : v && Object.assign(...styles(v))) || {}
+				},
+				immediate: true
+			},
+			replace: {
+				handler(v, o) {
+					if(JSON.stringify(v) != JSON.stringify(o))
+						this.bindRelation()
+				},
+				deep: true,
+				immediate: true
+			}
+		},
+		created() {
+			if(!this._uid) {
+				this._uid = this._.uid
+			}
+			Object.defineProperty(this, 'parent', {
+				get: () => this[parent] || [],
+			})
+			Object.defineProperty(this, 'index', {
+				get: () =>  {
+					this.bindRelation();
+					const {parent: {el: {views=[]}={}}={}} = this
+					return views.indexOf(this.el)
+				},
+			});
+			this.el.type = this.type
+			if(this.uid) {
+				this.el.uid = this.uid
+			}
+			this.bindRelation()
+		},
+		// #ifdef VUE3
+		beforeUnmount() {
+			this.removeEl()
+		},
+		// #endif
+		// #ifdef VUE2
+		beforeDestroy() {
+			this.removeEl()
+		},
+		// #endif
+		methods: {
+			removeEl() {
+				if (this.parent) {
+					this.parent.el.views = this.parent.el.views.filter(
+						(item) => item._uid !== this._uid
+					);
+				}
+			},
+			bindRelation() {
+				if(!this.el._uid) {
+					this.el._uid = this._uid 
+				}
+				if(['text','qrcode'].includes(this.type)) {
+					this.el.text = this.$slots && this.$slots.default && this.$slots.default[0].text || `${this.text || ''}`.replace(/\\n/g, '\n')
+				}
+				if(this.type == 'image') {
+					this.el.src = this.src
+				}
+				if (!this.parent) {
+					return;
+				}
+				let views = this.parent.el.views || [];
+				if(views.indexOf(this.el) !== -1) {
+					this.parent.el.views = views.map(v => v._uid == this._uid ? this.el : v)
+				} else {
+					this.parent.el.views = [...views, this.el];
+				}
+			}
+		},
+		mounted() {
+			// this.bindRelation()
+		},
+	}
+}

+ 28 - 0
uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue

@@ -0,0 +1,28 @@
+<template>
+	
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-image',
+		mixins:[children('painter')],
+		props: {
+			id: String,
+			css: [String, Object],
+			src: String
+		},
+		data() {
+			return {
+				type: 'image',
+				el: {
+					css: {},
+					src: null
+				},
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 27 - 0
uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue

@@ -0,0 +1,27 @@
+<template>
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-qrcode',
+		mixins:[children('painter')],
+		props: {
+			id: String,
+			css: [String, Object],
+			text: String
+		},
+		data() {
+			return {
+				type: 'qrcode',
+				el: {
+					css: {},
+					text: null
+				},
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 33 - 0
uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue

@@ -0,0 +1,33 @@
+<template>
+	<text style="opacity: 0;height: 0;"><slot/></text>
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-text',
+		mixins:[children('painter')],
+		props: {
+			type: {
+				type: String,
+				default: 'text'
+			},
+			uid: String,
+			css: [String, Object],
+			text: [String, Number],
+			replace: Object,
+		},
+		data() {
+			return {
+				// type: 'text',
+				el: {
+					css: {},
+					text: null
+				},
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 34 - 0
uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue

@@ -0,0 +1,34 @@
+<template>
+	<view><slot/></view>
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-view',
+		mixins:[children('painter'), parent('painter')],
+		props: {
+			id: String,
+			type: {
+				type: String,
+				default: 'view'
+			},
+			css: [String, Object],
+		},
+		data() {
+			return {
+				// type: 'view',
+				el: {
+					css: {},
+					views:[]
+				},
+			}
+		},
+		mounted() {
+			
+		}
+	}
+</script>
+
+<style>
+</style>

+ 461 - 0
uni_modules/lime-painter/components/l-painter/l-painter.vue

@@ -0,0 +1,461 @@
+<template>
+	<view class="lime-painter" ref="limepainter">
+		<view v-if="canvasId && size" :style="styles">
+			<!-- #ifndef APP-NVUE -->
+			<canvas class="lime-painter__canvas" v-if="use2dCanvas" :id="canvasId" type="2d" :style="size"></canvas>
+			<canvas class="lime-painter__canvas" v-else :id="canvasId" :canvas-id="canvasId" :style="size"
+				:width="boardWidth * dpr" :height="boardHeight * dpr" :hidpi="hidpi"></canvas>
+
+			<!-- #endif -->
+			<!-- #ifdef APP-NVUE -->
+			<web-view :style="size" ref="webview"
+				src="/uni_modules/lime-painter/hybrid/html/index.html"
+				class="lime-painter__canvas" @pagefinish="onPageFinish" @error="onError" @onPostMessage="onMessage">
+			</web-view>
+			<!-- #endif -->
+		</view>
+		<slot />
+	</view>
+</template>
+
+<script>
+	import { parent } from '../common/relation'
+	import props from './props'
+	import {toPx, base64ToPath, pathToBase64, isBase64, sleep, getImageInfo }from './utils';
+	//  #ifndef APP-NVUE
+	import { canIUseCanvas2d, isPC} from './utils';
+	import Painter from './painter';
+	// import Painter from '@painter'
+	const nvue = {}
+	//  #endif
+	//  #ifdef APP-NVUE
+	import nvue from './nvue'
+	//  #endif
+	export default {
+		name: 'lime-painter',
+		mixins: [props, parent('painter'), nvue],
+		data() {
+			return {
+				use2dCanvas: false,
+				canvasHeight: 150,
+				canvasWidth: null,
+				parentWidth: 0,
+				inited: false,
+				progress: 0,
+				firstRender: 0,
+				done: false,
+				tasks: []
+			};
+		},
+		computed: {
+			styles() {
+				return `${this.size}${this.customStyle||''};` + (this.hidden && 'position: fixed; left: 1500rpx;')
+			},
+			canvasId() {
+				return `l-painter${this._ && this._.uid || this._uid}`
+			},
+			size() {
+				if (this.boardWidth && this.boardHeight) {
+					return `width:${this.boardWidth}px; height: ${this.boardHeight}px;`;
+				}
+			},
+			dpr() {
+				return this.pixelRatio || uni.getSystemInfoSync().pixelRatio;
+			},
+			boardWidth() {
+				const {width = 0} = (this.elements && this.elements.css) || this.elements || this
+				const w = toPx(width||this.width)
+				return w || Math.max(w, toPx(this.canvasWidth));
+			},
+			boardHeight() {
+				const {height = 0} = (this.elements && this.elements.css) || this.elements || this
+				const h = toPx(height||this.height)
+				return h || Math.max(h, toPx(this.canvasHeight));
+			},
+			hasBoard() {
+				return this.board && Object.keys(this.board).length
+			},
+			elements() {
+				return this.hasBoard ? this.board : JSON.parse(JSON.stringify(this.el))
+			}
+		},
+		created() {
+			this.use2dCanvas = this.type === '2d' && canIUseCanvas2d() && !isPC
+		},
+		async mounted() {
+			await sleep(30)
+			await this.getParentWeith()
+			this.$nextTick(() => {
+				setTimeout(() => {
+					this.$watch('elements', this.watchRender, {
+						deep: true,
+						immediate: true
+					});
+				}, 30)
+			})
+		},
+		// #ifdef VUE3
+		unmounted() {
+			this.done = false
+			this.inited = false
+			this.firstRender = 0
+			this.progress = 0
+			this.painter = null
+			clearTimeout(this.rendertimer)
+		},
+		// #endif
+		// #ifdef VUE2
+		destroyed() {
+			this.done = false
+			this.inited = false
+			this.firstRender = 0
+			this.progress = 0
+			this.painter = null
+			clearTimeout(this.rendertimer)
+		},
+		// #endif
+		methods: {
+			async watchRender(val, old) {
+				if (!val || !val.views || (!this.firstRender ? !val.views.length : !this.firstRender) || !Object.keys(val).length || JSON.stringify(val) == JSON.stringify(old)) return;
+				this.firstRender = 1
+				this.progress = 0
+				this.done = false
+				clearTimeout(this.rendertimer)
+				this.rendertimer = setTimeout(() => {
+					this.render(val);
+				}, this.beforeDelay)
+			},
+			async setFilePath(path, param) {
+				let filePath = path
+				const {pathType = this.pathType} =  param || this
+				if (pathType == 'base64' && !isBase64(path)) {
+					filePath = await pathToBase64(path)
+				} else if (pathType == 'url' && isBase64(path)) {
+					filePath = await base64ToPath(path)
+				}
+				if (param && param.isEmit) {
+					this.$emit('success', filePath);
+				}
+				return filePath
+			},
+			async getSize(args) {
+				const {width} = args.css || args
+				const {height} = args.css || args
+				if (!this.size) {
+					if (width || height) {
+						this.canvasWidth = width || this.canvasWidth
+						this.canvasHeight = height || this.canvasHeight
+						await sleep(30);
+					} else {
+						await this.getParentWeith()
+					}
+				}
+			},
+			canvasToTempFilePathSync(args) {
+				// this.stopWatch && this.stopWatch()
+				// this.stopWatch = this.$watch('done', (v) => {
+				// 	if (v) {
+				// 		this.canvasToTempFilePath(args)
+				// 		this.stopWatch && this.stopWatch()
+				// 	}
+				// }, {
+				// 	immediate: true
+				// })
+				this.tasks.push(args)
+				if(this.done){
+					this.runTask()
+				}
+			},
+			runTask(){
+				while(this.tasks.length){
+					const task = this.tasks.shift()	
+					 this.canvasToTempFilePath(task)
+				}
+			},
+			// #ifndef APP-NVUE
+			getParentWeith() {
+				return new Promise(resolve => {
+					uni.createSelectorQuery()
+						.in(this)
+						.select(`.lime-painter`)
+						.boundingClientRect()
+						.exec(res => {
+							const {width, height} = res[0]||{}
+							this.parentWidth = Math.ceil(width||0)
+							this.canvasWidth = this.parentWidth || 300
+							this.canvasHeight = height || this.canvasHeight||150
+							resolve(res[0])
+						})
+				})
+			},
+			async render(args = {}) {
+				if(!Object.keys(args).length) {
+					return console.error('空对象')
+				}
+				this.progress = 0
+				this.done = false
+				// #ifdef APP-NVUE
+				this.tempFilePath.length = 0
+				// #endif
+				await this.getSize(args)
+				const ctx = await this.getContext();
+				
+				let {
+					use2dCanvas,
+					boardWidth,
+					boardHeight,
+					canvas,
+					afterDelay
+				} = this;
+				if (use2dCanvas && !canvas) {
+					return Promise.reject(new Error('canvas 没创建'));
+				}
+				this.boundary = {
+					top: 0,
+					left: 0,
+					width: boardWidth,
+					height: boardHeight
+				};
+				this.painter = null
+				if (!this.painter) {
+					const {width} = args.css || args
+					const {height} = args.css || args
+					if(!width && this.parentWidth) {
+						Object.assign(args, {width: this.parentWidth})
+					}
+					const param = {
+						context: ctx,
+						canvas,
+						width: boardWidth,
+						height: boardHeight,
+						pixelRatio: this.dpr,
+						useCORS: this.useCORS,
+						createImage: getImageInfo.bind(this),
+						performance: this.performance,
+						listen: {
+							onProgress: (v) => {
+								this.progress = v
+								this.$emit('progress', v)
+							},
+							onEffectFail: (err) => {
+								this.$emit('faill', err)
+							}
+						}
+					}
+					this.painter = new Painter(param)
+				} 
+				try{
+					// vue3 赋值给data会引起图片无法绘制
+					const { width, height } = await this.painter.source(JSON.parse(JSON.stringify(args)))
+					this.boundary.height = this.canvasHeight = height
+					this.boundary.width = this.canvasWidth = width
+					await sleep(this.sleep);
+					await this.painter.render()
+					await new Promise(resolve => this.$nextTick(resolve));
+					if (!use2dCanvas) {
+						await this.canvasDraw();
+					}
+					if (afterDelay && use2dCanvas) {
+						await sleep(afterDelay);
+					}
+					this.$emit('done');
+					this.done = true
+					if (this.isCanvasToTempFilePath) {
+						this.canvasToTempFilePath()
+							.then(res => {
+								this.$emit('success', res.tempFilePath)
+							})
+							.catch(err => {
+								this.$emit('fail', new Error(JSON.stringify(err)));
+							});
+					}
+					this.runTask()
+					return Promise.resolve({
+						ctx,
+						draw: this.painter,
+						node: this.node
+					});
+				}catch(e){
+					//TODO handle the exception
+				}
+				
+			},
+			canvasDraw(flag = false) {
+				return new Promise((resolve, reject) => this.ctx.draw(flag, () => setTimeout(() => resolve(), this
+					.afterDelay)));
+			},
+			async getContext() {
+				if (!this.canvasWidth) {
+					this.$emit('fail', 'painter no size')
+					console.error('[lime-painter]: 给画板或父级设置尺寸')
+					return Promise.reject();
+				}
+				if (this.ctx && this.inited) {
+					return Promise.resolve(this.ctx);
+				}
+				const { type, use2dCanvas, dpr, boardWidth, boardHeight } = this;
+				const _getContext = () => {
+					return new Promise(resolve => {
+						uni.createSelectorQuery()
+							.in(this)
+							.select(`#${this.canvasId}`)
+							.boundingClientRect()
+							.exec(res => {
+								if (res) {
+									const ctx = uni.createCanvasContext(this.canvasId, this);
+									if (!this.inited) {
+										this.inited = true;
+										this.use2dCanvas = false;
+										this.canvas = res;
+									}
+									
+									// 钉钉小程序框架不支持 measureText 方法,用此方法 mock
+									if (!ctx.measureText) {
+										function strLen(str) {
+											let len = 0;
+											for (let i = 0; i < str.length; i++) {
+												if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) {
+													len++;
+												} else {
+													len += 2;
+												}
+											}
+											return len;
+										}
+										ctx.measureText = text => {
+											let fontSize = ctx.state && ctx.state.fontSize || 12;
+											const font = ctx.__font
+											if (font && fontSize == 12) {
+												fontSize = parseInt(font.split(' ')[3], 10);
+											}
+											fontSize /= 2;
+											return {
+												width: strLen(text) * fontSize
+											};
+										}
+									}
+									
+									// #ifdef MP-ALIPAY
+									ctx.scale(dpr, dpr);
+									// #endif
+									this.ctx = ctx
+									resolve(this.ctx);
+								} else {
+									console.error('[lime-painter] no node')
+								}
+							});
+					});
+				};
+				if (!use2dCanvas) {
+					return _getContext();
+				}
+				return new Promise(resolve => {
+					uni.createSelectorQuery()
+						.in(this)
+						.select(`#${this.canvasId}`)
+						.node()
+						.exec(res => {
+							let {node: canvas} = res && res[0]||{};
+							if(canvas) {
+								const ctx = canvas.getContext(type);
+								if (!this.inited) {
+									this.inited = true;
+									this.use2dCanvas = true;
+									this.canvas = canvas;
+								}
+								this.ctx = ctx
+								resolve(this.ctx);
+							} else {
+								console.error('[lime-painter]: no size')
+							}
+						});
+				});
+			},
+			canvasToTempFilePath(args = {}) {
+				return new Promise(async (resolve, reject) => {
+					const { use2dCanvas, canvasId, dpr, fileType, quality } = this;
+					const success = async (res) => {
+						try {
+							const tempFilePath = await this.setFilePath(res.tempFilePath || res, args)
+							const result = Object.assign(res, {tempFilePath})
+							args.success && args.success(result)
+							resolve(result)
+						} catch (e) {
+							this.$emit('fail', e)
+						}
+					}
+					
+					let { top: y = 0, left: x = 0, width, height } = this.boundary || this;
+					// let destWidth = width * dpr;
+					// let destHeight = height * dpr;
+					// #ifdef MP-ALIPAY
+					// width = destWidth;
+					// height = destHeight;
+					// #endif
+					
+					const copyArgs = Object.assign({
+						// x,
+						// y,
+						// width,
+						// height,
+						// destWidth,
+						// destHeight,
+						canvasId,
+						id: canvasId,
+						fileType,
+						quality,
+					}, args, {success});
+					// if(this.isPC || use2dCanvas) {
+					// 	copyArgs.canvas = this.canvas
+					// }
+					if (use2dCanvas) {
+						copyArgs.canvas = this.canvas
+						try{
+							// #ifndef MP-ALIPAY
+							const oFilePath = this.canvas.toDataURL(`image/${args.fileType||fileType}`.replace(/pg/, 'peg'), args.quality||quality)
+							if(/data:,/.test(oFilePath)) {
+								uni.canvasToTempFilePath(copyArgs, this);
+							} else {
+								const tempFilePath = await this.setFilePath(oFilePath, args)
+								args.success && args.success({tempFilePath})
+								resolve({tempFilePath})
+							}
+							// #endif
+							// #ifdef MP-ALIPAY
+							this.canvas.toTempFilePath(copyArgs)
+							// #endif
+						}catch(e){
+							args.fail && args.fail(e)
+							reject(e)
+						}
+					} else {
+						// #ifdef MP-ALIPAY
+						if(this.ctx.toTempFilePath) {
+							// 钉钉
+							const ctx = uni.createCanvasContext(canvasId);
+							ctx.toTempFilePath(copyArgs);
+						} else {
+							my.canvasToTempFilePath(copyArgs);
+						}
+						// #endif
+						// #ifndef MP-ALIPAY
+						uni.canvasToTempFilePath(copyArgs, this);
+						// #endif
+					}
+				})
+			}
+			// #endif
+		}
+	};
+</script>
+<style>
+	.lime-painter,
+	.lime-painter__canvas {
+		// #ifndef APP-NVUE
+		width: 100%;
+		// #endif
+		// #ifdef APP-NVUE
+		flex: 1;
+		// #endif
+	}
+</style>

+ 214 - 0
uni_modules/lime-painter/components/l-painter/nvue.js

@@ -0,0 +1,214 @@
+// #ifdef APP-NVUE
+import {
+	sleep,
+	getImageInfo,
+	isBase64,
+	networkReg
+} from './utils';
+const dom = weex.requireModule('dom')
+import {
+	version
+} from '../../package.json'
+
+export default {
+	data() {
+		return {
+			tempFilePath: [],
+			isInitFile: false,
+			osName: uni.getSystemInfoSync().osName
+		}
+	},
+	methods: {
+		getParentWeith() {
+			return new Promise(resolve => {
+				dom.getComponentRect(this.$refs.limepainter, (res) => {
+					this.parentWidth = Math.ceil(res.size.width)
+					this.canvasWidth = this.canvasWidth || this.parentWidth || 300
+					this.canvasHeight = res.size.height || this.canvasHeight || 150
+					resolve(res.size)
+				})
+			})
+		},
+		onPageFinish() {
+			this.webview = this.$refs.webview
+			this.webview.evalJS(`init(${this.dpr})`)
+		},
+		onMessage(e) {
+			const res = e.detail.data[0] || null;
+			if (res.event) {
+				if (res.event == 'inited') {
+					this.inited = true
+				}
+				if (res.event == 'fail') {
+					this.$emit('fail', res)
+				}
+				if (res.event == 'layoutChange') {
+					const data = typeof res.data == 'string' ? JSON.parse(res.data) : res.data
+					this.canvasWidth = Math.ceil(data.width);
+					this.canvasHeight = Math.ceil(data.height);
+				}
+				if (res.event == 'progressChange') {
+					this.progress = res.data * 1
+				}
+				if (res.event == 'file') {
+					this.tempFilePath.push(res.data)
+					if (this.tempFilePath.length > 7) {
+						this.tempFilePath.shift()
+					}
+					return
+				}
+				if (res.event == 'success') {
+					if (res.data) {
+						this.tempFilePath.push(res.data)
+						if (this.tempFilePath.length > 8) {
+							this.tempFilePath.shift()
+						}
+						if (this.isCanvasToTempFilePath) {
+							this.setFilePath(this.tempFilePath.join(''), {
+								isEmit: true
+							})
+						}
+					} else {
+						this.$emit('fail', 'canvas no data')
+					}
+					return
+				}
+				this.$emit(res.event, JSON.parse(res.data));
+			} else if (res.file) {
+				this.file = res.data;
+			} else {
+				console.info(res[0])
+			}
+		},
+		getWebViewInited() {
+			if (this.inited) return Promise.resolve(this.inited);
+			return new Promise((resolve) => {
+				this.$watch(
+					'inited',
+					async val => {
+						if (val) {
+							resolve(val)
+						}
+					}, {
+						immediate: true
+					}
+				);
+			})
+		},
+		getTempFilePath() {
+			if (this.tempFilePath.length == 8) return Promise.resolve(this.tempFilePath)
+			return new Promise((resolve) => {
+				this.$watch(
+					'tempFilePath',
+					async val => {
+						if (val.length == 8) {
+							resolve(val.join(''))
+						}
+					}, {
+						deep: true
+					}
+				);
+			})
+		},
+		getWebViewDone() {
+			if (this.progress == 1) return Promise.resolve(this.progress);
+			return new Promise((resolve) => {
+				this.$watch(
+					'progress',
+					async val => {
+						if (val == 1) {
+							this.$emit('done')
+							this.done = true
+							this.runTask()
+							resolve(val)
+						}
+					}, {
+						immediate: true
+					}
+				);
+			})
+		},
+		async render(args) {
+			try {
+				await this.getSize(args)
+				const {
+					width
+				} = args.css || args
+				if (!width && this.parentWidth) {
+					Object.assign(args, {
+						width: this.parentWidth
+					})
+				}
+				const newNode = await this.calcImage(args);
+				await this.getWebViewInited()
+				this.webview.evalJS(`source(${JSON.stringify(newNode)})`)
+				await this.getWebViewDone()
+				await sleep(this.afterDelay)
+				if (this.isCanvasToTempFilePath) {
+					const params = {
+						fileType: this.fileType,
+						quality: this.quality
+					}
+					this.webview.evalJS(`save(${JSON.stringify(params)})`)
+				}
+				return Promise.resolve()
+			} catch (e) {
+				this.$emit('fail', e)
+			}
+		},
+		async calcImage(args) {
+			let node = JSON.parse(JSON.stringify(args))
+			const urlReg = /url\((.+)\)/
+			const {
+				backgroundImage
+			} = node.css || {}
+			const isBG = backgroundImage && urlReg.exec(backgroundImage)[1]
+			const url = node.url || node.src || isBG
+			if (['text', 'qrcode'].includes(node.type)) {
+				return node
+			}
+			if ((node.type === "image" || isBG) && url && !isBase64(url) && (this.osName == 'ios' || !networkReg
+					.test(url))) {
+				let {
+					path
+				} = await getImageInfo(url, true)
+				if (isBG) {
+					node.css.backgroundImage = `url(${path})`
+				} else {
+					node.src = path
+				}
+			} else if (node.views && node.views.length) {
+				for (let i = 0; i < node.views.length; i++) {
+					node.views[i] = await this.calcImage(node.views[i])
+				}
+			}
+			return node
+		},
+		async canvasToTempFilePath(args = {}) {
+			if (!this.inited) {
+				return this.$emit('fail', 'no init')
+			}
+			this.tempFilePath = []
+			if (args.fileType == 'jpg') {
+				args.fileType = 'jpeg'
+			}
+
+			this.webview.evalJS(`save(${JSON.stringify(args)})`)
+			try {
+				let tempFilePath = await this.getTempFilePath()
+
+				tempFilePath = await this.setFilePath(tempFilePath, args)
+				args.success({
+					errMsg: "canvasToTempFilePath:ok",
+					tempFilePath
+				})
+			} catch (e) {
+				console.log('e', e)
+				args.fail({
+					error: e
+				})
+			}
+		}
+	}
+}
+// #endif

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
uni_modules/lime-painter/components/l-painter/painter.js


+ 56 - 0
uni_modules/lime-painter/components/l-painter/props.js

@@ -0,0 +1,56 @@
+export default {
+	props: {
+		board: Object,
+		pathType: String, // 'base64'、'url'
+		fileType: {
+			type: String,
+			default: 'png'
+		},
+		hidden: Boolean,
+		quality: {
+			type: Number,
+			default: 1
+		},
+		css: [String, Object],
+		// styles: [String, Object],
+		width: [Number, String],
+		height: [Number, String],
+		pixelRatio: Number,
+		customStyle: String,
+		isCanvasToTempFilePath: Boolean,
+		// useCanvasToTempFilePath: Boolean,
+		sleep: {
+			type: Number,
+			default: 1000 / 30
+		},
+		beforeDelay: {
+			type: Number,
+			default: 100
+		},
+		afterDelay: {
+			type: Number,
+			default: 100
+		},
+		performance: Boolean,
+		// #ifdef MP-WEIXIN || MP-TOUTIAO || MP-ALIPAY
+		type: {
+			type: String,
+			default: '2d'
+		},
+		// #endif
+		// #ifdef APP-NVUE
+		hybrid: Boolean,
+		timeout: {
+			type: Number,
+			default: 2000
+		},
+		// #endif
+		// #ifdef H5 || APP-PLUS
+		useCORS: Boolean,
+		hidpi: {
+			type: Boolean,
+			default: true
+		}
+		// #endif
+	}
+}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
uni_modules/lime-painter/components/l-painter/single.js


+ 368 - 0
uni_modules/lime-painter/components/l-painter/utils.js

@@ -0,0 +1,368 @@
+export const networkReg = /^(http|\/\/)/;
+export const isBase64 = (path) => /^data:image\/(\w+);base64/.test(path);
+export function sleep(delay) {
+	return new Promise(resolve => setTimeout(resolve, delay))
+}
+let {platform, SDKVersion} = uni.getSystemInfoSync() 
+export const isPC = /windows|mac/.test(platform)
+// 缓存图片
+let cache = {}
+export function isNumber(value) {
+	return /^-?\d+(\.\d+)?$/.test(value);
+}
+export function toPx(value, baseSize, isDecimal = false) {
+	// 如果是数字
+	if (typeof value === 'number') {
+		return value
+	}
+	// 如果是字符串数字
+	if (isNumber(value)) {
+		return value * 1
+	}
+	// 如果有单位
+	if (typeof value === 'string') {
+		const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g
+		const results = reg.exec(value);
+		if (!value || !results) {
+			return 0;
+		}
+		const unit = results[3];
+		value = parseFloat(value);
+		let res = 0;
+		if (unit === 'rpx') {
+			res = uni.upx2px(value);
+		} else if (unit === 'px') {
+			res = value * 1;
+		} else if (unit === '%') {
+			res = value * toPx(baseSize) / 100;
+		} else if (unit === 'em') {
+			res = value * toPx(baseSize || 14);
+		}
+		return isDecimal ? res.toFixed(2) * 1 : Math.round(res);
+	}
+	return 0
+}
+
+// 计算版本
+export function compareVersion(v1, v2) {
+	v1 = v1.split('.')
+	v2 = v2.split('.')
+	const len = Math.max(v1.length, v2.length)
+	while (v1.length < len) {
+		v1.push('0')
+	}
+	while (v2.length < len) {
+		v2.push('0')
+	}
+	for (let i = 0; i < len; i++) {
+		const num1 = parseInt(v1[i], 10)
+		const num2 = parseInt(v2[i], 10)
+
+		if (num1 > num2) {
+			return 1
+		} else if (num1 < num2) {
+			return -1
+		}
+	}
+	return 0
+}
+
+function gte(version) {
+  // #ifdef MP-ALIPAY
+  SDKVersion = my.SDKVersion
+  // #endif
+  return compareVersion(SDKVersion, version) >= 0;
+}
+export function canIUseCanvas2d() {
+	// #ifdef MP-WEIXIN
+	return gte('2.9.2');
+	// #endif
+	// #ifdef MP-ALIPAY
+	return gte('2.7.15');
+	// #endif
+	// #ifdef MP-TOUTIAO
+	return gte('1.78.0');
+	// #endif
+	return false
+}
+
+// #ifdef MP
+export const prefix = () => {
+	// #ifdef MP-TOUTIAO
+	return tt
+	// #endif
+	// #ifdef MP-WEIXIN
+	return wx
+	// #endif
+	// #ifdef MP-BAIDU
+	return swan
+	// #endif
+	// #ifdef MP-ALIPAY
+	return my
+	// #endif
+	// #ifdef MP-QQ
+	return qq
+	// #endif
+	// #ifdef MP-360
+	return qh
+	// #endif
+}
+// #endif
+
+
+
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64) {
+	const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
+
+	return new Promise((resolve, reject) => {
+		// #ifdef MP
+		const fs = uni.getFileSystemManager()
+		//自定义文件名
+		if (!format) {
+			reject(new Error('ERROR_BASE64SRC_PARSE'))
+		}
+		const time = new Date().getTime();
+		let pre = prefix()
+		// #ifdef MP-TOUTIAO
+		const filePath = `${pre.getEnvInfoSync().common.USER_DATA_PATH}/${time}.${format}`
+		// #endif
+		// #ifndef MP-TOUTIAO
+		const filePath = `${pre.env.USER_DATA_PATH}/${time}.${format}`
+		// #endif
+		fs.writeFile({
+			filePath,
+			data: base64.split(',')[1],
+			encoding: 'base64',
+			success() {
+				resolve(filePath)
+			},
+			fail(err) {
+				console.error(err)
+				reject(err)
+			}
+		})
+		// #endif
+
+		// #ifdef H5
+		// mime类型
+		let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
+		//base64 解码
+		let byteString = atob(base64.split(',')[1]);
+		//创建缓冲数组
+		let arrayBuffer = new ArrayBuffer(byteString.length);
+		//创建视图
+		let intArray = new Uint8Array(arrayBuffer);
+		for (let i = 0; i < byteString.length; i++) {
+			intArray[i] = byteString.charCodeAt(i);
+		}
+		resolve(URL.createObjectURL(new Blob([intArray], {
+			type: mimeString
+		})))
+		// #endif
+
+		// #ifdef APP-PLUS
+		const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+		bitmap.loadBase64Data(base64, () => {
+			if (!format) {
+				reject(new Error('ERROR_BASE64SRC_PARSE'))
+			}
+			const time = new Date().getTime();
+			const filePath = `_doc/uniapp_temp/${time}.${format}`
+			bitmap.save(filePath, {},
+				() => {
+					bitmap.clear()
+					resolve(filePath)
+				},
+				(error) => {
+					bitmap.clear()
+					reject(error)
+				})
+		}, (error) => {
+			bitmap.clear()
+			reject(error)
+		})
+		// #endif
+	})
+}
+
+/**
+ * 路径转base64
+ * @param {Object} string
+ */
+export function pathToBase64(path) {
+	if (/^data:/.test(path)) return path
+	return new Promise((resolve, reject) => {
+		// #ifdef H5
+		let image = new Image();
+		image.setAttribute("crossOrigin", 'Anonymous');
+		image.onload = function() {
+			let canvas = document.createElement('canvas');
+			canvas.width = this.naturalWidth;
+			canvas.height = this.naturalHeight;
+			canvas.getContext('2d').drawImage(image, 0, 0);
+			let result = canvas.toDataURL('image/png')
+			resolve(result);
+			canvas.height = canvas.width = 0
+		}
+		image.src = path + '?v=' + Math.random()
+		image.onerror = (error) => {
+			reject(error);
+		};
+		// #endif
+
+		// #ifdef MP
+		if (uni.canIUse('getFileSystemManager')) {
+			uni.getFileSystemManager().readFile({
+				filePath: path,
+				encoding: 'base64',
+				success: (res) => {
+					resolve('data:image/png;base64,' + res.data)
+				},
+				fail: (error) => {
+					console.error({error, path})
+					reject(error)
+				}
+			})
+		}
+		// #endif
+
+		// #ifdef APP-PLUS
+		plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => {
+			entry.file((file) => {
+				const fileReader = new plus.io.FileReader()
+				fileReader.onload = (data) => {
+					resolve(data.target.result)
+				}
+				fileReader.onerror = (error) => {
+					reject(error)
+				}
+				fileReader.readAsDataURL(file)
+			}, reject)
+		}, reject)
+		// #endif
+	})
+}
+
+
+
+export function getImageInfo(path, useCORS) {
+	const isCanvas2D = this && this.canvas && this.canvas.createImage
+	return new Promise(async (resolve, reject) => {
+		// let time = +new Date()
+		let src = path.replace(/^@\//,'/')
+		if (cache[path] && cache[path].errMsg) {
+			resolve(cache[path])
+		} else {
+			try {
+				// #ifdef MP || APP-PLUS
+				if (isBase64(path) && (isCanvas2D ? isPC : true)) {
+					src = await base64ToPath(path)
+				}
+				// #endif
+				// #ifdef H5
+				if(useCORS) {
+					src = await pathToBase64(path)
+				}
+				// #endif
+			} catch (error) {
+				reject({
+					...error,
+					src
+				})
+			}
+			// #ifndef APP-NVUE
+			if(isCanvas2D && !isPC) {
+				const img = this.canvas.createImage()
+				img.onload = function() {
+					const image = {
+						path: img,
+						width:  img.width,
+						height:  img.height
+					}
+					cache[path] = image
+					resolve(cache[path])
+				}
+				img.onerror = function(err) {
+					reject({err,path})
+				}
+				img.src = src
+				return
+			}
+			// #endif
+			uni.getImageInfo({
+				src,
+				success: (image) => {
+					const localReg = /^\.|^\/(?=[^\/])/;
+					// #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
+					image.path = localReg.test(src) ?  `/${image.path}` : image.path;
+					// #endif
+					if(isCanvas2D) {
+						const img = this.canvas.createImage()
+						img.onload = function() {
+							image.path = img
+							cache[path] = image
+							resolve(cache[path])
+						}
+						img.onerror = function(err) {
+							reject({err,path})
+						}
+						img.src = src
+						return
+					}
+					// #ifdef APP-PLUS
+					// console.log('getImageInfo', +new Date() - time)
+					// ios 比较严格 可能需要设置跨域
+					if(uni.getSystemInfoSync().osName == 'ios' && useCORS) {
+						pathToBase64(image.path).then(base64 => {
+							image.path = base64
+							cache[path] = image
+							resolve(cache[path])
+						}).catch(err => {
+							console.error({err, path})
+							reject({err,path})
+						})
+						return
+					}
+					// #endif
+					cache[path] = image
+					resolve(cache[path])
+				},
+				fail(err) {
+					console.error({err, path})
+					reject({err,path})
+				}
+			})
+		}
+	})
+}
+
+
+// #ifdef APP-PLUS
+const getLocalFilePath = (path) => {
+	if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path
+		.indexOf('_downloads') === 0) {
+		return path
+	}
+	if (path.indexOf('file://') === 0) {
+		return path
+	}
+	if (path.indexOf('/storage/emulated/0/') === 0) {
+		return path
+	}
+	if (path.indexOf('/') === 0) {
+		const localFilePath = plus.io.convertAbsoluteFileSystem(path)
+		if (localFilePath !== path) {
+			return localFilePath
+		} else {
+			path = path.substr(1)
+		}
+	}
+	return '_www/' + path
+}
+// #endif
+
+

Разница между файлами не показана из-за своего большого размера
+ 166 - 0
uni_modules/lime-painter/components/lime-painter/lime-painter.vue


+ 119 - 0
uni_modules/lime-painter/hybrid/html/index.html

@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+	<meta charset="UTF-8">
+	<meta name="viewport" content="width=device-width, initial-scale=1.0">
+	<meta http-equiv="X-UA-Compatible" content="ie=edge">
+	<title></title>
+	<style type="text/css">
+		html,
+		body,
+		canvas {
+			padding: 0;
+			margin: 0;
+			width: 100%;
+			height: 100%;
+			overflow-y: hidden;
+			background-color: transparent;
+		}
+	</style>
+</head>
+
+<body>
+	<canvas id="lime-painter"></canvas>
+	<script type="text/javascript" src="./uni.webview.1.5.3.js"></script>
+	<script type="text/javascript" src="./painter.js"></script>
+	<script> 
+		var cache = [];
+		var painter = null;
+		var canvas = null;
+		var context = null;
+		var timer = null;
+		var pixelRatio = 1;
+		console.log = function (...args) {
+			postMessage(args);
+		};
+		// function stringify(key, value) {
+		// 	if (typeof value === 'object' && value !== null) {
+		// 		if (cache.indexOf(value) !== -1) {
+		// 			return;
+		// 		}
+		// 		cache.push(value);
+		// 	}
+		// 	return value;
+		// };
+
+		function emit(event, data) {
+			postMessage({
+				event,
+				data: (typeof data !== 'object' && data !== null ? data : JSON.stringify(data)) 
+			});
+			cache = [];
+		};
+		function postMessage(data) {
+			uni.postMessage({
+				data
+			});
+		};
+		
+		function init(dpr) {
+			canvas = document.querySelector('#lime-painter');
+			context = canvas.getContext('2d');
+			pixelRatio = dpr || window.devicePixelRatio;
+			painter = new Painter({
+				id: 'lime-painter',
+				context,
+				canvas,
+				pixelRatio,
+				width: canvas.offsetWidth,
+				height: canvas.offsetHeight,
+				listen: {
+					onProgress(v) {
+						emit('progressChange', v);
+					},
+					onEffectFail(err) {
+						//console.error(err)
+						emit('fail', err);
+					}
+				}
+			});
+			emit('inited', true);
+		};
+		function save(args) {
+			delete args.success;
+			delete args.fail;
+			clearTimeout(timer);
+			timer = setTimeout(() => {
+				const path = painter.save(args);
+				if (typeof path == 'string') {
+					const index = Math.ceil(path.length / 8);
+					for (var i = 0; i < 8; i++) {
+						if (i == 7) {
+							emit('success', path.substr(i * index, index));
+						} else {
+							emit('file', path.substr(i * index, index));
+						}
+					};
+				} else {
+					// console.log('canvas no data')
+					emit('fail', 'canvas no data');
+				};
+			}, 30);
+		};
+		async function source(args) {
+			let size = await painter.source(args);
+			emit('layoutChange', size);
+			if(!canvas.height) {
+				console.log('canvas no size')
+				emit('fail', 'canvas no size');
+			}
+			painter.render().catch(err => {
+				// console.error(err)
+				emit('fail', err);
+			});
+		};
+	</script>
+</body>
+
+</html>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
uni_modules/lime-painter/hybrid/html/painter.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
uni_modules/lime-painter/hybrid/html/uni.webview.1.5.3.js


+ 93 - 0
uni_modules/lime-painter/package.json

@@ -0,0 +1,93 @@
+{
+  "id": "lime-painter",
+  "displayName": "海报画板",
+  "version": "1.9.6.5",
+  "description": "一款canvas海报组件,更优雅的海报生成方案,有限的支持富文本",
+  "keywords": [
+    "海报",
+    "富文本",
+    "生成海报",
+    "生成二维码",
+    "JSON"
+],
+  "repository": "https://gitee.com/liangei/lime-painter", 
+  "engines": {
+    "HBuilderX": "^3.4.14"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "305716444"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+        "QQ": "y",
+        "钉钉": "u",
+        "快手": "u",
+        "飞书": "u",
+        "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  },
+  "name": "lime-painter",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC"
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов