From e3afb7ab25d2709d4e2fe8859bb23ef56b5a1360 Mon Sep 17 00:00:00 2001
From: qx <1084500556@qq.com>
Date: 星期三, 06 八月 2025 09:43:30 +0800
Subject: [PATCH] :qx

---
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js              |  142 +
 pages/mine/erweima.vue                                                           |  356 +++
 uni_modules/Sansnn-uQRCode/changelog.md                                          |   12 
 uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue                        | 1131 ++++++++++
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js                            |   24 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js  |   18 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js               |   21 
 pages/index.html                                                                 |   36 
 uni_modules/Sansnn-uQRCode/common/types/cache.d.ts                               |    3 
 uni_modules/Sansnn-uQRCode/package.json                                          |   79 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js                |   23 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js         |  666 ++++++
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js                          |   74 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js                  |  241 ++
 uni_modules/Sansnn-uQRCode/common/cache.js                                       |    1 
 uni_modules/Sansnn-uQRCode/common/queue.js                                       |   41 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js           |   21 
 pagesA/Examiner/Examiner.vue                                                     |    1 
 uni_modules/Sansnn-uQRCode/README.md                                             |  392 +++
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js                |   21 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js       |   22 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js            |   11 
 pages.json                                                                       |    5 
 uni_modules/Sansnn-uQRCode/LICENSE.md                                            |  201 +
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js                           |   96 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js |   11 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js                |   22 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js      | 1191 +++++++++++
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js                               |   39 
 uni_modules/Sansnn-uQRCode/common/types/queue.d.ts                               |    4 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js          |   21 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js            |    3 
 uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js                             |   34 
 uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue                      | 1131 ++++++++++
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js               |   22 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js         |    8 
 package.json                                                                     |    4 
 config.js                                                                        |    2 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js  |   17 
 pages/mine/index.vue                                                             |   15 
 uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js                |  298 ++
 41 files changed, 6,440 insertions(+), 20 deletions(-)

diff --git a/config.js b/config.js
index efc1dfb..f8b0aeb 100644
--- a/config.js
+++ b/config.js
@@ -3,7 +3,7 @@
 	// baseUrl: 'https://ltpeis.xaltjdkj.cn:5011/ltkj-admin',
 	// baseUrl: 'https://ltpeis.xaltjdkj.cn:5021',
 	// baseUrl: 'http://ltpeis.xaltjdkj.cn:5801',
-	baseUrl: 'http://192.168.1.244:5011',
+	baseUrl: 'http://192.168.1.113:5011',
 	
   // 搴旂敤淇℃伅
   appInfo: {
diff --git a/package.json b/package.json
index 6c6966a..bc2f004 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,11 @@
 {
   "dependencies": {
+    "@uqrcode/js": "^4.0.7",
     "crypto-js": "^4.2.0",
     "jsencrypt": "^3.3.2",
+    "qrcode": "^1.5.4",
+    "qrcode.vue": "^3.6.0",
+    "uqrcodejs": "^4.0.7",
     "uview-ui": "^2.0.38"
   },
   "devDependencies": {
diff --git a/pages.json b/pages.json
index 0af4775..05cf127 100644
--- a/pages.json
+++ b/pages.json
@@ -29,6 +29,11 @@
 				"navigationBarTitleText": "鎴戠殑"
 			}
 		}, {
+			"path": "pages/mine/erweima",
+			"style": {
+				"navigationBarTitleText": "鎴戠殑"
+			}
+		},{
 			"path": "pages/cart/cart",
 			"style": {
 				"navigationBarTitleText": "棰勭害鍋ュ悍"
diff --git a/pages/index.html b/pages/index.html
index c3ff205..15c44db 100644
--- a/pages/index.html
+++ b/pages/index.html
@@ -1,20 +1,20 @@
 <!DOCTYPE html>
 <html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <script>
-      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
-        CSS.supports('top: constant(a)'))
-      document.write(
-        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
-        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
-    </script>
-    <title></title>
-    <!--preload-links-->
-    <!--app-context-->
-  </head>
-  <body>
-    <div id="app"><!--app-html--></div>
-    <script type="module" src="/main.js"></script>
-  </body>
-</html>
+	<head>
+		<meta charset="UTF-8" />
+		<script>
+			var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+				CSS.supports('top: constant(a)'))
+			document.write(
+				'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+				(coverSupport ? ', viewport-fit=cover' : '') + '" />')
+		</script>
+		<title></title>
+		<!--preload-links-->
+		<!--app-context-->
+	</head>
+	<body>
+		<div id="app"><!--app-html--></div>
+		<script type="module" src="/main.js"></script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/pages/mine/erweima.vue b/pages/mine/erweima.vue
new file mode 100644
index 0000000..9f63565
--- /dev/null
+++ b/pages/mine/erweima.vue
@@ -0,0 +1,356 @@
+<template>
+	<view class="container">
+
+		<!-- 杈撳叆鍖哄煙 -->
+		<view class="input-group">
+			<text class="label">
+				<uni-icons type="compose" size="16" color="#2c3e50" />
+				杈撳叆鏂囨湰鎴朥RL锛�
+			</text>
+			<textarea v-model="inputText" placeholder="鍦ㄦ杈撳叆鏂囨湰銆佺綉鍧�鎴栧叾浠栦俊鎭�..." />
+		</view>
+
+		<!-- 绀轰緥鎸夐挳 -->
+		<view class="examples">
+			<view v-for="(example, index) in examples" :key="index" class="example-btn" @tap="setExample(example.text)">
+				{{ example.label }}
+			</view>
+		</view>
+
+		<!-- 鐢熸垚鎸夐挳 -->
+		<button class="generate-btn" @tap="generateQRCode">
+			<uni-icons type="bolt" size="20" color="#fff" />
+			<text>{{generating ? "鐢熸垚涓�...." :"鐢熸垚浜岀淮鐮�" }}</text>
+		</button>
+
+		<!-- 浜岀淮鐮佹樉绀哄尯鍩� -->
+		<view class="qrcode-container">
+
+			<canvas v-if="qrCodeGenerated" ref="qrcodeCanvas" canvas-id="qrcodeCanvas" class="qrcode-canvas"
+				@longpress="handleLongPress" width="200" height="200" />
+			<view v-else class="placeholder">
+				<uni-icons type="qrcode" size="48" color="#95a5a6" />
+				<text>浜岀淮鐮佸皢鍦ㄦ澶勬樉绀�</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+
+
+<script>
+	import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js
+	export default {
+		data() {
+			return {
+				inputText: 'https://www.example.com',
+				qrCodeGenerated: false,
+				isMiniprogram: false,
+				qrCodeDataUrl: null,
+				platformName: 'H5',
+				platformIcon: 'circle',
+				error: null,
+				generating: false,
+				saveButtonText: '淇濆瓨浜岀淮鐮�',
+				examples: [{
+						label: '绀轰緥缃戝潃',
+						text: 'https://www.example.com'
+					},
+					{
+						label: '绀轰緥鏂囨湰',
+						text: 'Hello, World!'
+					},
+					{
+						label: '鑱旂郴鏂瑰紡',
+						text: '寰俊锛歟xample_user'
+					},
+					{
+						label: 'WiFi杩炴帴',
+						text: 'WIFI:T:WPA;S:MyNetwork;P:password123;;'
+					}
+				]
+			};
+		},
+		mounted() {
+			// this.detectPlatform();
+		},
+		methods: {
+			// detectPlatform() {
+			// 	// 鍒ゆ柇鏄惁鍦ㄥ皬绋嬪簭鐜涓�
+			// 	// #ifdef MP-WEIXIN
+			// 	this.isMiniprogram = true;
+			// 	this.platformName = '寰俊灏忕▼搴�';
+			// 	this.platformIcon = 'weixin';
+			// 	this.saveButtonText = '淇濆瓨鍒扮浉鍐�';
+			// 	// #endif
+
+			// 	// #ifdef APP-PLUS
+			// 	this.isMiniprogram = true;
+			// 	this.platformName = 'App';
+			// 	this.platformIcon = 'mobile';
+			// 	this.saveButtonText = '淇濆瓨鍒扮浉鍐�';
+			// 	// #endif
+			// },
+
+			setExample(text) {
+				this.inputText = text;
+				this.generateQRCode();
+			},
+
+			// 鐢熸垚浜岀淮鐮� - 浣跨敤 canvas-id 鏇夸唬 ref
+			async generateQRCode() {
+				const text = this.inputText.trim();
+
+				if (!text) {
+					this.error = '璇疯緭鍏ヨ鐢熸垚浜岀淮鐮佺殑鍐呭锛�';
+					return;
+				}
+
+				this.generating = true;
+				this.error = null;
+				this.qrCodeGenerated = true;
+				try {
+					const qr = new UQRCode();
+					qr.data = text;
+					qr.size = 200;
+					qr.make();
+					const ctx = uni.createCanvasContext('qrcodeCanvas',
+					this); // 缁勪欢鍐呰皟鐢ㄩ渶浼爐his锛寁ue3 涓� this 涓� getCurrentInstance()?.proxy
+					qr.canvasContext = ctx;
+					qr.drawCanvas();
+					this.generating = false;
+				} catch (e) {
+					console.error('浜岀淮鐮佺敓鎴愬紓甯�:', e);
+					alert('鐢熸垚浜岀淮鐮佹椂鍑洪敊锛�');
+					this.qrCodeGenerated = false;
+
+				}
+			},
+
+			// 淇濆瓨浜岀淮鐮�
+			saveQRCode() {
+				if (!this.qrCodeGenerated) {
+					alert('璇峰厛鐢熸垚浜岀淮鐮�');
+					return;
+				}
+
+				const canvas = this.$refs.qrcodeCanvas;
+				if (!canvas) return;
+
+				// 鍦ㄤ笉鍚屽钩鍙颁娇鐢ㄤ笉鍚岀殑淇濆瓨鏂瑰紡
+				if (this.isMiniprogram) {
+					// 灏忕▼搴忕幆澧冧繚瀛�
+					this.saveInMiniprogram(canvas);
+				} else {
+					// H5鐜淇濆瓨
+					this.saveInH5(canvas);
+				}
+			},
+			// 鍦℉5鐜涓繚瀛樹簩缁寸爜
+			saveInH5(canvas) {
+				const dataURL = canvas.toDataURL('image/png');
+				const link = document.createElement('a');
+				link.href = dataURL;
+				link.download = `qrcode-${new Date().getTime()}.png`;
+				document.body.appendChild(link);
+				link.click();
+				document.body.removeChild(link);
+
+				alert('浜岀淮鐮佸凡淇濆瓨');
+			},
+
+			// 鍦ㄥ皬绋嬪簭鐜涓繚瀛樹簩缁寸爜
+			saveInMiniprogram(canvas) {
+				// 妯℃嫙Uniapp淇濆瓨鍥剧墖鍒扮浉鍐�
+				if (typeof uni !== 'undefined') {
+					uni.canvasToTempFilePath({
+						canvas: canvas,
+						success: (res) => {
+							uni.saveImageToPhotosAlbum({
+								filePath: res.tempFilePath,
+								success: () => {
+									uni.showToast({
+										title: '淇濆瓨鎴愬姛',
+										icon: 'success'
+									});
+								},
+								fail: () => {
+									uni.showToast({
+										title: '淇濆瓨澶辫触',
+										icon: 'none'
+									});
+								}
+							});
+						},
+						fail: (err) => {
+							console.error('淇濆瓨澶辫触:', err);
+							uni.showToast({
+								title: '淇濆瓨澶辫触',
+								icon: 'none'
+							});
+						}
+					});
+				}
+				// 寰俊鍘熺敓灏忕▼搴忎繚瀛�
+				else if (typeof wx !== 'undefined') {
+					wx.canvasToTempFilePath({
+						canvas: canvas,
+						success: (res) => {
+							wx.saveImageToPhotosAlbum({
+								filePath: res.tempFilePath,
+								success: () => {
+									wx.showToast({
+										title: '淇濆瓨鎴愬姛',
+										icon: 'success'
+									});
+								},
+								fail: () => {
+									wx.showToast({
+										title: '淇濆瓨澶辫触',
+										icon: 'none'
+									});
+								}
+							});
+						},
+						fail: (err) => {
+							console.error('淇濆瓨澶辫触:', err);
+							wx.showToast({
+								title: '淇濆瓨澶辫触',
+								icon: 'none'
+							});
+						}
+					});
+				}
+			},
+
+
+			// 灏忕▼搴忛暱鎸変簨浠�
+			handleLongPress() {
+				if (this.isMiniprogram) {
+					this.saveQRCode();
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	* {
+		margin: 0;
+		padding: 0;
+		box-sizing: border-box;
+		font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
+	}
+
+	textarea {
+		width: 100%;
+		height: 120px;
+		padding: 15px;
+		border: 2px solid #ddd;
+		border-radius: 12px;
+		font-size: 1rem;
+		resize: none;
+		transition: all 0.3s ease;
+	}
+
+	textarea:focus {
+		border-color: #3498db;
+		outline: none;
+		box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
+	}
+
+	.generate-btn {
+		width: 100%;
+		padding: 15px;
+		background: linear-gradient(to right, #3498db, #2c3e50);
+		color: white;
+		border: none;
+		border-radius: 12px;
+		font-size: 1.2rem;
+		font-weight: 600;
+		cursor: pointer;
+		transition: all 0.3s ease;
+		margin-bottom: 25px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		gap: 10px;
+	}
+
+	.generate-btn:hover {
+		background: linear-gradient(to right, #2980b9, #1a252f);
+		transform: translateY(-2px);
+		box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
+	}
+
+	.qrcode-container {
+		text-align: center;
+		margin-bottom: 25px;
+		padding: 20px;
+		border-radius: 15px;
+		background: #f8f9fa;
+		box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
+		min-height: 260px;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.qrcode-canvas {
+		width: 200px;
+		height: 200px;
+		margin: 0 auto;
+		padding: 10px;
+		background: white;
+		border-radius: 10px;
+		box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
+	}
+
+	.placeholder {
+		color: #95a5a6;
+		font-size: 1.1rem;
+	}
+	.examples {
+		display: flex;
+		gap: 15px;
+		flex-wrap: wrap;
+		margin-top: 15px;
+		justify-content: center;
+	}
+
+	.example-btn {
+		padding: 8px 15px;
+		background: #e0e7ff;
+		color: #4f46e5;
+		border-radius: 20px;
+		font-size: 0.9rem;
+		cursor: pointer;
+		transition: all 0.2s;
+	}
+
+	.example-btn:hover {
+		background: #c7d2fe;
+	}
+
+
+
+	@media (max-width: 500px) {
+		#app {
+			padding: 20px;
+		}
+
+		.header h1 {
+			font-size: 1.8rem;
+		}
+
+		.header p {
+			font-size: 1rem;
+		}
+
+		.qrcode-canvas {
+			width: 180px;
+			height: 180px;
+		}
+	}
+</style>
\ No newline at end of file
diff --git a/pages/mine/index.vue b/pages/mine/index.vue
index 1ed273b..bb672ce 100644
--- a/pages/mine/index.vue
+++ b/pages/mine/index.vue
@@ -136,6 +136,16 @@
 							<uni-icons type="right" size="16" color="#999" />
 						</view>
 					</view>
+					<view class="tool-item" @click="handleerweima">
+						<view class="tool-item__left">
+							<!-- <uni-icons type="help" size="20" color="#666" /> -->
+							<image class="rt-image" src="/static/images/index/wt.png" mode="scaleToFill"></image>
+							<text class="tool-text">浜岀淮鐮佹祴璇�</text>
+						</view>
+						<view class="tool-item__right">
+							<uni-icons type="right" size="16" color="#999" />
+						</view>
+					</view>
 
 					<view class="tool-item">
 						<view class="tool-item__left" @click="handleLogout">
@@ -531,6 +541,11 @@
 				}
 
 			},
+			handleerweima(){
+				uni.navigateTo({
+					url: `/pages/mine/erweima`
+				})
+			},
 			personnel(canshu) {
 				if (this.token) {
 					// this.$tab.navigateTo('/pagesA/Examiner/Examiner')
diff --git a/pagesA/Examiner/Examiner.vue b/pagesA/Examiner/Examiner.vue
index 75aa5f7..02295e8 100644
--- a/pagesA/Examiner/Examiner.vue
+++ b/pagesA/Examiner/Examiner.vue
@@ -288,7 +288,6 @@
 				this.index1 = e.detail.value;
 			},
 			saveInspect() {
-				console.log(1111)
 				let inspect = this.form;
 				if (inspect.cusName == '') {
 					this.$modal.msgError("璇疯緭鍏ュ鍚�")
diff --git a/uni_modules/Sansnn-uQRCode/LICENSE.md b/uni_modules/Sansnn-uQRCode/LICENSE.md
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/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.
diff --git a/uni_modules/Sansnn-uQRCode/README.md b/uni_modules/Sansnn-uQRCode/README.md
new file mode 100644
index 0000000..77d7925
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/README.md
@@ -0,0 +1,392 @@
+# 浠嬬粛
+
+`uQRCode`鏄竴娆惧熀浜巂Javascript`鐜寮�鍙戠殑浜岀淮鐮佺敓鎴愭彃浠讹紝閫傜敤鎵�鏈塦Javascript`杩愯鐜鐨勫墠绔簲鐢ㄥ拰`Node.js`搴旂敤銆�
+
+`uQRCode`鍙墿灞曟�ч珮锛屽畠鏀寔鑷畾涔夋覆鏌撲簩缁寸爜锛屽彲閫氳繃`uQRCode API`寰楀埌浜岀淮鐮佺粯鍒跺叧閿俊鎭悗锛屼娇鐢╜canvas`銆乣svg`鎴朻js`鎿嶄綔`dom`鐨勬柟寮忕粯鍒朵簩缁寸爜鍥炬銆傝繕鍙嚜瀹氫箟浜岀淮鐮佹牱寮忥紝濡傞殢鏈洪鑹层�佸渾鐐广�佹柟鍧椼�佸潡涓庡潡涔嬮棿鐨勯棿璺濈瓑銆�
+
+娆㈣繋鍔犲叆缇よ亰銆恥QRCode浜ゆ祦缇ゃ�戯細[695070434](https://jq.qq.com/?_wv=1027&k=JRjzDqiw)銆�
+
+# 璁捐鍣�
+
+uQRCode鍙戝竷浜嗛厤濂楃殑鍙鍖栬璁″櫒锛屽彲鏍规嵁鑷繁鍠滃ソ鍦ㄨ璁″櫒涓璁′簩缁寸爜鏍峰紡锛屼竴閿敓鎴愰厤缃唬鐮佸鍒跺埌椤圭洰涓紝璇︽儏璇峰湪寰俊灏忕▼搴忔悳绱⑩�滄煔瀛愪簩缁寸爜鈥濓紝鎴栨壂鎻忎笅鏂瑰皬绋嬪簭鐮佷綋楠屻��
+
+![uQRCode璁捐鍣╙(https://uqrcode.cn/mp_weixin_code.jpg)
+
+## 璁捐鍣ㄦā鏉跨ず渚�
+
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_1.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_2.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_3.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_4.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_5.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_6.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_7.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_8.png)
+![uQRCode璁捐鍣╙(https://uqrcode.cn/yz_9.png)
+
+# 蹇�熶笂鎵�
+
+> 鍦╜uni-app`涓紝鎴戜滑鏇存帹鑽愪娇鐢ㄧ粍浠舵柟寮忔潵鐢熸垚浜岀淮鐮侊紝缁勪欢鏂瑰紡澶уぇ鎻愰珮浜嗛〉闈㈢殑鍙鎬т互鍙婇伩寮�浜嗕竴浜涘钩鍙板鏄撳嚭闂鐨勫湴鏂癸紝褰撶粍浠舵棤娉曟弧瓒抽渶姹傜殑鏃跺�欙紝鍐嶈�冭檻鍒囨崲鎴愬師鐢熸柟寮忋��
+
+瀹樻柟鏂囨。锛歔https://uqrcode.cn/doc](https://uqrcode.cn/doc)銆�
+
+github鍦板潃锛歔https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode)銆�
+
+npm鍦板潃锛歔https://www.npmjs.com/package/uqrcodejs](https://www.npmjs.com/package/uqrcodejs)銆�
+
+uni-app鎻掍欢甯傚満鍦板潃锛歔https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)銆�
+
+## 鍘熺敓鏂瑰紡
+
+鍘熺敓鏂瑰紡浠呴渶瑕佽幏鍙朻uqrcode.js`鏂囦欢渚垮彲浣跨敤銆傝缁嗛厤缃绉绘鍒帮細鏂囨。 > [鍘熺敓](https://uqrcode.cn/doc/document/native.html)銆�
+
+### 瀹夎
+
+1. 閫氳繃`npm`瀹夎锛屾垚鍔熷悗鍗冲彲浣跨敤`import`鎴朻require`杩涜寮曠敤銆�
+``` bash
+# npm瀹夎
+npm install uqrcodejs
+# 鎴栬��
+npm install @uqrcode/js
+```
+
+2. 閫氳繃椤圭洰寮�婧愬湴鍧�鑾峰彇`uqrcode.js`锛屼笅杞絗uqrcode.js`鍚庯紝灏嗗叾澶嶅埗鍒版偍椤圭洰鎸囧畾鐩綍锛屽湪椤甸潰涓紩鍏uqrcode.js`鏂囦欢鍗冲彲寮�濮嬩娇鐢ㄣ��
+
+### 寮曞叆
+
+- 閫氳繃`import`寮曞叆銆�
+``` javascript
+// npm瀹夎
+import UQRCode from 'uqrcodejs'; // npm install uqrcodejs
+// 鎴栬��
+import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js
+```
+
+- `Node.js`閫氳繃`require`寮曞叆銆�
+``` javascript
+// npm瀹夎
+const UQRCode = require('uqrcodejs'); // npm install uqrcodejs
+// 鎴栬��
+const UQRCode = require('@uqrcode/js'); // npm install @uqrcode/js
+```
+
+- 鍘熺敓娴忚鍣ㄧ幆澧冿紝鍦╦s鑴氭湰鍔犺浇鏃舵坊鍔犲埌`window`銆�
+``` html
+<script type="text/javascript" src="uqrcode.js"></script>
+<script>
+    var UQRCode = window.UQRCode;
+</script>
+```
+
+### 绠�鍗曠敤娉�
+
+`uQRCode`鍩轰簬`Canvas API`灏佽浜嗕竴濂楁柟娉曪紝寤鸿寮�鍙戣�呬娇鐢╜canvas`鐢熸垚锛屼竴閿皟鐢紝闈炲父鏂逛究銆備互涓嬫槸绀轰緥锛�
+
+- HTML绀轰緥
+  - DOM閮ㄥ垎
+  ``` html
+  <canvas id="qrcode" width="200" height="200"></canvas>
+  ```
+
+  - JS閮ㄥ垎
+  ``` javascript
+  // 鑾峰彇uQRCode瀹炰緥
+  var qr = new UQRCode();
+  // 璁剧疆浜岀淮鐮佸唴瀹�
+  qr.data = "https://uqrcode.cn/doc";
+  // 璁剧疆浜岀淮鐮佸ぇ灏忥紝蹇呴』涓巆anvas璁剧疆鐨勫楂樹竴鑷�
+  qr.size = 200;
+  // 璋冪敤鍒朵綔浜岀淮鐮佹柟娉�
+  qr.make();
+  // 鑾峰彇canvas鍏冪礌
+  var canvas = document.getElementById("qrcode");
+  // 鑾峰彇canvas涓婁笅鏂�
+  var canvasContext = canvas.getContext("2d");
+  // 璁剧疆uQRCode瀹炰緥鐨刢anvas涓婁笅鏂�
+  qr.canvasContext = canvasContext;
+  // 璋冪敤缁樺埗鏂规硶灏嗕簩缁寸爜鍥炬缁樺埗鍒癱anvas涓�
+  qr.drawCanvas();
+  ```
+
+- uni-app绀轰緥
+  - Template閮ㄥ垎
+  ``` html
+  <canvas id="qrcode" canvas-id="qrcode" style="width: 200px;height: 200px;"></canvas>
+  ```
+  
+  - JS閮ㄥ垎
+  ``` javascript
+  onReady() {
+    // 鑾峰彇uQRCode瀹炰緥
+    var qr = new UQRCode();
+    // 璁剧疆浜岀淮鐮佸唴瀹�
+    qr.data = "https://uqrcode.cn/doc";
+    // 璁剧疆浜岀淮鐮佸ぇ灏忥紝蹇呴』涓巆anvas璁剧疆鐨勫楂樹竴鑷�
+    qr.size = 200;
+    // 璋冪敤鍒朵綔浜岀淮鐮佹柟娉�
+    qr.make();
+    // 鑾峰彇canvas涓婁笅鏂�
+    var canvasContext = uni.createCanvasContext('qrcode', this); // 濡傛灉鏄粍浠讹紝this蹇呴』浼犲叆
+    // 璁剧疆uQRCode瀹炰緥鐨刢anvas涓婁笅鏂�
+    qr.canvasContext = canvasContext;
+    // 璋冪敤缁樺埗鏂规硶灏嗕簩缁寸爜鍥炬缁樺埗鍒癱anvas涓�
+    qr.drawCanvas();
+  }
+  ```
+  
+- 寰俊灏忕▼搴忥紝鎺ㄨ崘浣跨敤Canvas 2D锛屽叧浜嶤anvas 2D鐨勪娇鐢ㄨ鍙傝�冨井淇″紑鏀炬枃妗c��
+
+### 楂樼骇鐢ㄦ硶
+
+鑰冭檻鍒伴儴鍒嗗钩鍙板彲鑳戒笉鏀寔`canvas`锛屾墍浠uQRCode`骞舵病鏈夊己鍒惰姹傚拰`canvas`涓�璧蜂娇鐢紝鎮ㄨ繕鍙互閫夋嫨鍏朵粬鏂瑰紡鏉ョ敓鎴愪簩缁寸爜锛屼緥濡備娇鐢╜js`鎿嶄綔`dom`杩涜缁樺埗鎴栨槸浣跨敤`svg`缁樺埗绛夈�備互涓嬫槸绀轰緥锛�
+
+- uni-app v-for+view
+
+```html
+<template>
+  <view>
+    <view class="qrcode">
+      <view v-for="(row, rowI) in modules" :key="rowI" style="display: flex;flex-direction: row;">
+        <view v-for="(col, colI) in row" :key="colI">
+          <view v-if="col.isBlack" style="width: 10px;height: 10px;background-color: black;">
+            <!-- 榛戣壊鐮佺偣 -->
+          </view>
+          <view v-else style="width: 10px;height: 10px;background-color: white;">
+            <!-- 鐧借壊鐮佺偣 -->
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import UQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js';
+
+  export default {
+    data() {
+      return {
+        modules: []
+      }
+    },
+    onLoad() {
+      const qr = new UQRCode();
+      qr.data = 'uQRCode';
+      qr.make();
+      this.modules = qr.modules;
+    },
+    methods: {
+
+    }
+  }
+</script>
+```
+
+- js鎿嶄綔dom
+
+``` html
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>uQRCode浜岀淮鐮佺敓鎴�</title>
+</head>
+<body>
+    <div id="qrcode" style="position: relative;"></div>
+    <script type="text/javascript" src="uqrcode.js"></script>
+    <script>
+    // 寮曞叆uQRCode
+    var UQRCode = window.UQRCode;
+    // 鑾峰彇uQRCode瀹炰緥
+    var qr = new UQRCode();
+    // 璁剧疆浜岀淮鐮佸唴瀹�
+    qr.data = "https://uqrcode.cn/doc";
+    // 璁剧疆浜岀淮鐮佸ぇ灏忥紝蹇呴』涓巆anvas璁剧疆鐨勫楂樹竴鑷�
+    qr.size = 200;
+    // 璁剧疆浜岀淮鐮佸墠鏅浘锛屽彲浠ユ槸璺緞
+    qr.foregroundImageSrc =
+        'data:image/png;base64,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';
+    // 璋冪敤鍒朵綔浜岀淮鐮佹柟娉�
+    qr.make();
+
+    var drawModules = qr.getDrawModules();
+    // 閬嶅巻drawModules鍒涘缓dom鍏冪礌
+    var qrHtml = '';
+    for (var i = 0; i < drawModules.length; i++) {
+        var drawModule = drawModules[i];
+        switch (drawModule.type) {
+        case 'tile':
+            /* 缁樺埗灏忓潡 */
+            qrHtml += `<div style="position: absolute;left: ${drawModule.x}px;top: ${drawModule.y}px;width: ${drawModule.width}px;height: ${drawModule.height}px;background: ${drawModule.color};"></div>`;
+            break;
+        case 'image':
+            /* 缁樺埗鍥惧儚 */
+            qrHtml += `<img style="position: absolute;left: ${drawModule.x}px;top: ${drawModule.y}px;width: ${drawModule.width}px;height: ${drawModule.height}px;" src="${drawModule.imageSrc}" />`;
+            break;
+        }
+    }
+    document.getElementById('qrcode').innerHTML = qrHtml;
+    </script>
+</body>
+</html>
+```
+
+- svg
+``` html
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>uQRCode浜岀淮鐮佺敓鎴�</title>
+</head>
+<body>
+    <svg id="qrcode" width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>
+    <script type="text/javascript" src="uqrcode.js"></script>
+    <script>
+    // 寮曞叆uQRCode
+    var UQRCode = window.UQRCode;
+    // 鑾峰彇uQRCode瀹炰緥
+    var qr = new UQRCode();
+    // 璁剧疆浜岀淮鐮佸唴瀹�
+    qr.data = "https://uqrcode.cn/doc";
+    // 璁剧疆浜岀淮鐮佸ぇ灏忥紝蹇呴』涓巆anvas璁剧疆鐨勫楂樹竴鑷�
+    qr.size = 200;
+    // 璁剧疆浜岀淮鐮佸墠鏅浘锛屽彲浠ユ槸璺緞
+    qr.foregroundImageSrc =
+        'data:image/png;base64,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';
+    // 璋冪敤鍒朵綔浜岀淮鐮佹柟娉�
+    qr.make();
+
+    var drawModules = qr.getDrawModules();
+    // 閬嶅巻drawModules鍒涘缓svg鍏冪礌
+    var qrHtml = '';
+    for (var i = 0; i < drawModules.length; i++) {
+        var drawModule = drawModules[i];
+        switch (drawModule.type) {
+        case 'tile':
+            /* 缁樺埗灏忓潡 */
+            qrHtml += `<rect x="${drawModule.x}" y="${drawModule.y}" width="${drawModule.width}" height="${drawModule.height}" style="fill: ${drawModule.color};" />`;
+            break;
+        case 'image':
+            /* 缁樺埗鍥惧儚 */
+            qrHtml += `<image href="${drawModule.imageSrc}" x="${drawModule.x}" y="${drawModule.y}" width="${drawModule.width}" height="${drawModule.height}" />`;
+            break;
+        }
+    }
+    document.getElementById('qrcode').innerHTML = qrHtml;
+    </script>
+</body>
+</html>
+```
+
+> 鏇村鐢ㄦ硶澶у鑷鎺㈢储鍜紝鏈熷緟鍒嗕韩鍝焴
+
+### 瀵煎嚭涓存椂鏂囦欢璺緞
+
+鍘熺敓鏂瑰紡鍩轰簬`Canvas`鐨勶紝璇疯嚜琛屽弬闃呭悇骞冲彴`Canvas`鐨勫鍑烘柟寮忋�備互涓嬫槸閮ㄥ垎绀轰緥锛�
+
+- uni-app
+```javascript
+// 閫氳繃uni.createCanvasContext鏂瑰紡鍒涘缓缁樺埗涓婁笅鏂囩殑锛屽搴斿鍑篈PI涓簎ni.canvasToTempFilePath
+// 璋冪敤瀹宑tx.draw()鏂规硶鍚庝笉鑳界涓�鏃堕棿瀵煎嚭锛屽惁鍒欎細寮傚父锛岄渶瑕佹湁涓�瀹氱殑寤舵椂
+setTimeout(() => {
+    uni.canvasToTempFilePath(
+        {
+            canvasId: this.canvasId,
+            fileType: this.fileType,
+            width: this.canvasWidth,
+            height: this.canvasHeight,
+            success: res => {
+                console.log(res);
+            },
+            fail: err => {
+                console.log(err);
+            }
+        }, 
+        // this // 缁勪欢鍐呬娇鐢ㄥ繀浼犲綋鍓嶅疄渚�
+    );
+}, 300);
+```
+
+- Canvas2D
+```javascript
+// 寰楀埌base64
+console.log(canvas.toDataURL());
+// 寰楀埌buffer
+console.log(canvas.toBuffer());
+```
+
+### 淇濆瓨浜岀淮鐮佸埌鏈湴鐩稿唽
+
+蹇呴』鍦ㄥ鍑轰复鏃舵枃浠惰矾寰勬垚鍔熷悗鍐嶆墽琛屼繚瀛樸�倁ni-app閫氱敤淇濆瓨鏂瑰紡锛圚5闄ゅ锛夛細
+```javascript
+uni.saveImageToPhotosAlbum({
+    filePath: tempFilePath,
+    success: res => {
+        console.log(res);
+    },
+    fail: err => {
+        console.log(err);
+    }
+});
+```
+
+H5鍙互閫氳繃璁剧疆`<a>`鏍囩`href`灞炴�х殑鏂瑰紡杩涜淇濆瓨锛�
+```javascript
+const aEle = document.createElement('a');
+aEle.download = 'uQRCode'; // 璁剧疆涓嬭浇鐨勬枃浠跺悕锛岄粯璁ゆ槸'涓嬭浇'
+aEle.href = tempFilePath;
+document.body.appendChild(aEle);
+aEle.click();
+aEle.remove(); // 涓嬭浇涔嬪悗鎶婂垱寤虹殑鍏冪礌鍒犻櫎
+```
+缁忚繃娴嬭瘯锛孭C绔祻瑙堝櫒鍙互涓嬭浇锛岄儴鍒嗗畨鍗撹嚜甯︽垨绗笁鏂规祻瑙堝櫒鍙互涓嬭浇锛屽畨鍗撳井淇℃祻瑙堝櫒涓嶉�傜敤锛岀Щ鍔ㄧiOS鎵�鏈夋祻瑙堝櫒鍧囦笉閫傜敤锛屽樊寮傝緝澶э紝杩樻槸鎺ㄨ崘鍚勪綅瀵煎嚭鏂囦欢缁欏浘鐗囩粍浠舵樉绀猴紝鐒跺悗鎻愮ず鐢ㄦ埛閫氳繃闀挎寜鍥剧墖杩涜淇濆瓨杩欑鏂瑰紡銆�
+
+## uni-app缁勪欢鏂瑰紡
+
+### 瀹夎
+
+閫氳繃uni-app鎻掍欢甯傚満鍦板潃瀹夎锛歔https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)銆傝缁嗛厤缃绉绘鍒帮細鏂囨。 > [uni-app缁勪欢](https://uqrcode.cn/doc/document/uni-app.html)銆�
+
+### 寮曞叆
+
+uni-app榛樿涓篹asycom妯″紡锛屽彲鐩存帴閿叆`<uqrcode>`鏍囩銆�
+
+### 绠�鍗曠敤娉�
+
+瀹夎`uqrcode`缁勪欢鍚庯紝鍦╜template`涓敭鍏<uqrcode/>`銆傝缃甡ref`灞炴�у彲浣跨敤缁勪欢鍐呴儴鏂规硶锛宍canvas-id`灞炴�т负缁勪欢鍐呴儴鐨刢anvas缁勪欢鏍囪瘑锛宍value`灞炴�т负浜岀淮鐮佺敓鎴愬搴斿唴瀹癸紝`options`涓洪厤缃�夐」锛屽彲閰嶇疆浜岀淮鐮佹牱寮忥紝缁樺埗Logo绛夛紝璇﹁锛歔options](https://uqrcode.cn/doc/document/uni-app.html#options) 銆�
+
+``` html
+<uqrcode ref="uqrcode" canvas-id="qrcode" value="https://uqrcode.cn/doc" :options="{ margin: 10 }"></uqrcode>
+```
+
+### 瀵煎嚭涓存椂鏂囦欢璺緞
+
+涓轰簡淇濊瘉鏂规硶璋冪敤鎴愬姛锛岃鍦� [complete](https://uqrcode.cn/doc/document/uni-app.html#complete) 浜嬩欢杩斿洖`success=true`鍚庤皟鐢ㄣ��
+
+```javascript
+// uqrcode涓虹粍浠剁殑ref鍚嶇О
+this.$refs.uqrcode.toTempFilePath({
+  success: res => {
+    console.log(res);
+  }
+});
+```
+
+### 淇濆瓨浜岀淮鐮佸埌鏈湴鐩稿唽
+
+涓轰簡淇濊瘉鏂规硶璋冪敤鎴愬姛锛岃鍦� [complete](https://uqrcode.cn/doc/document/uni-app.html#complete) 浜嬩欢杩斿洖`success=true`鍚庤皟鐢ㄣ��
+
+```javascript
+// uqrcode涓虹粍浠剁殑ref鍚嶇О
+this.$refs.uqrcode.save({
+  success: () => {
+    uni.showToast({
+      icon: 'success',
+      title: '淇濆瓨鎴愬姛'
+    });
+  }
+});
+```
+
+## 鏇村浣跨敤璇存槑璇峰墠寰�瀹樻柟鏂囨。鏌ョ湅锛歔https://uqrcode.cn/doc](https://uqrcode.cn/doc)銆�
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/changelog.md b/uni_modules/Sansnn-uQRCode/changelog.md
new file mode 100644
index 0000000..74a6e4c
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/changelog.md
@@ -0,0 +1,12 @@
+## 4.0.6锛�2022-12-12锛�
+淇`getDrawModules`锛岀涓�娆¤幏鍙栫粨鏋滄甯革紝鍚庣画鑾峰彇`tile`妯″潡涓嶅瓨鍦ㄧ殑闂锛�  
+淇瀹夊崜type:normal鍥燙anvas API浣跨敤浜嗗皬鏁版垨涓�0鐨勫弬鏁板鑷寸敓鎴愬紓甯哥殑闂锛堟敞锛氬畨鍗撻潪2d Canvas閮ㄥ垎API鍙傛暟涓嶆敮鎸佹惡甯﹀皬鏁帮紝閮ㄥ垎API鍙傛暟蹇呴』澶т簬0锛夈��
+## 4.0.1锛�2022-11-28锛�
+浼樺寲缁勪欢loading灞炴�х殑琛ㄧ幇锛�  
+鏂板缁勪欢type閫夐」normal锛屼互渚夸簬鍦ㄦ煇浜涙潯浠剁紪璇戝垵濮嬩负type=2d鏃惰繕鍙互閫夋嫨浣跨敤闈�2d缁勪欢绫诲瀷锛�  
+淇缁勪欢鏉′欢缂栬瘧鍦ㄥ叾浠栫紪杈戝櫒璇硶鎻愮ず鎶ラ敊锛�  
+淇鍘熺敓瀵筫s5鐨勬敮鎸併��
+## 4.0.0锛�2022-11-21锛�
+v4鐗堟湰婧愪唬鐮佸叏闈㈠紑鏀撅紝寮�婧愬湴鍧�锛歔https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode)锛�  
+
+鍗囩骇璇存槑锛歷4涓哄ぇ鐗堟湰鏇存柊锛岃櫧鐒跺凡灏藉彲鑳藉吋瀹逛笂涓�浠g増鏈紝浣嗕笉鍙伩鍏嶇殑杩樻槸瀛樺湪涓�浜涚粏鑺傚樊寮傦紝鑻ユ洿鏂板悗鍑虹幇闂锛岃鍙傝�冨鐓v3 鏂囨。](https://uqrcode.cn/doc/v3)锛孾v4 鏂囨。](https://uqrcode.cn/doc)杩涜淇敼銆�
diff --git a/uni_modules/Sansnn-uQRCode/common/cache.js b/uni_modules/Sansnn-uQRCode/common/cache.js
new file mode 100644
index 0000000..d897d26
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/common/cache.js
@@ -0,0 +1 @@
+export const cacheImageList = [];
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/common/queue.js b/uni_modules/Sansnn-uQRCode/common/queue.js
new file mode 100644
index 0000000..be6b1d2
--- /dev/null
+++ b/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();
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/common/types/cache.d.ts b/uni_modules/Sansnn-uQRCode/common/types/cache.d.ts
new file mode 100644
index 0000000..9b6c3ce
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/common/types/cache.d.ts
@@ -0,0 +1,3 @@
+declare module '*/common/cache' {
+  export const cacheImageList: Array;
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/common/types/queue.d.ts b/uni_modules/Sansnn-uQRCode/common/types/queue.d.ts
new file mode 100644
index 0000000..f81ab97
--- /dev/null
+++ b/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;
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue b/uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue
new file mode 100644
index 0000000..4fefaac
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/components/u-qrcode/u-qrcode.vue
@@ -0,0 +1,1131 @@
+<template>
+  <view class="uqrcode" :class="{ 'uqrcode-hide': hide }" :style="{ width: `${templateOptions.width}px`, height: `${templateOptions.height}px` }">
+    <view class="uqrcode-canvas-wrapper">
+      <!-- 鐢诲竷 -->
+      <!-- #ifndef APP-NVUE -->
+      <canvas class="uqrcode-canvas" :id="canvasId" :canvas-id="canvasId" :type="canvasType" :style="{
+          width: `${templateOptions.canvasWidth}px`,
+          height: `${templateOptions.canvasHeight}px`,
+          transform: templateOptions.canvasTransform
+        }" v-if="templateOptions.canvasDisplay" @click="onClick"></canvas>
+      <!-- #endif -->
+
+      <!-- nvue鐢╣canvas -->
+      <!-- #ifdef APP-NVUE -->
+      <gcanvas class="uqrcode-canvas" ref="gcanvas" :style="{
+          width: `${templateOptions.canvasWidth}px`,
+          height: `${templateOptions.canvasHeight}px`
+        }" v-if="templateOptions.canvasDisplay" @click="onClick"></gcanvas>
+      <!-- #endif -->
+    </view>
+
+    <!-- 鍔犺浇鏁堟灉 -->
+    <view class="uqrcode-makeing" v-if="loading === undefined ? makeing : loading">
+      <slot name="loading">
+        <image class="uqrcode-makeing-image" :style="{ width: `${templateOptions.size / 4}px`, height: `${templateOptions.size / 4}px` }"
+          src="data:image/gif;base64,R0lGODlhAAEAAfIEAOHh4SSsWuDg4N3d3f///wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjAyODhGMzM4RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjAyODhGMzM5RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4OEYzMzZEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4OEYzMzdEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQ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">
+        </image>
+      </slot>
+    </view>
+
+    <!-- 閿欒澶勭悊 -->
+    <view class="uqrcode-error" v-if="isError" @click="onClick">
+      <slot name="error" :error="error">
+        <text class="uqrcode-error-message">{{ error.errMsg }}</text>
+      </slot>
+    </view>
+
+    <!-- H5淇濆瓨鎻愮ず -->
+    <!-- #ifdef H5 -->
+    <view class="uqrcode-h5-save" v-if="isH5Save">
+      <slot name="h5save" :tempFilePath="tempFilePath">
+        <image class="uqrcode-h5-save-image" :src="tempFilePath"></image>
+        <text class="uqrcode-h5-save-text">{{ h5SaveIsDownload ? '鑻ヤ繚瀛樺け璐ワ紝' : '' }}璇烽暱鎸変簩缁寸爜杩涜淇濆瓨</text>
+      </slot>
+      <view class="uqrcode-h5-save-close" @click.stop="isH5Save = false">
+        <view class="uqrcode-h5-save-close-before"></view>
+        <view class="uqrcode-h5-save-close-after"></view>
+      </view>
+    </view>
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+  // #ifdef VUE3
+  import {
+    toRaw
+  } from 'vue';
+  // #endif
+
+  /* 寮曞叆uQRCode鏍稿績js */
+  import UQRCode from '../../js_sdk/uqrcode/uqrcode';
+
+  /* 寮曞叆nvue鎵�闇�妯″潡 */
+  // #ifdef APP-NVUE
+  import {
+    enable,
+    WeexBridge
+  } from '../../js_sdk/gcanvas';
+  const modal = weex.requireModule('modal');
+  // #endif
+
+  /* 寮曞叆闃熷垪 */
+  import {
+    queueDraw,
+    queueLoadImage
+  } from '../../common/queue';
+  /* 寮曞叆缂撳瓨鍥剧墖 */
+  import {
+    cacheImageList
+  } from '../../common/cache';
+
+  let instance = null;
+
+  export default {
+    name: 'uqrcode',
+    props: {
+      /**
+       * canvas缁勪欢id
+       */
+      canvasId: {
+        type: String,
+        required: true // canvasId鍦ㄥ井淇″皬绋嬪簭鍒濆鍊间笉鑳戒负绌猴紝created涓祴鍊间篃涓嶈锛屽繀椤荤粰涓�涓�硷紝鍚﹀垯鎸傝浇缁勪欢鍚庢棤娉曠粯鍒躲�備笉鑰冭檻鐢ㄩ殢鏈篿d锛寀uid
+      },
+      /**
+       * 浜岀淮鐮佸唴瀹�
+       */
+      value: {
+        type: [String, Number]
+      },
+      /**
+       * 閫夐」
+       */
+      options: {
+        type: Object,
+        default: () => {
+          return {};
+        }
+      },
+      /**
+       * 浜岀淮鐮佸ぇ灏�
+       */
+      size: {
+        type: [String, Number],
+        default: 200
+      },
+      /**
+       * 浜岀淮鐮佸昂瀵稿崟浣�
+       */
+      sizeUnit: {
+        type: String,
+        default: 'px'
+      },
+      /**
+       * 瀵煎嚭鐨勬枃浠剁被鍨�
+       */
+      fileType: {
+        type: String,
+        default: 'png'
+      },
+      /**
+       * 鏄惁鍒濆鍖栫粍浠跺悗灏卞紑濮嬬敓鎴�
+       */
+      start: {
+        type: Boolean,
+        default: true
+      },
+      /**
+       * 鏄惁鏁版嵁鍙戠敓鏀瑰彉鑷姩閲嶇粯
+       */
+      auto: {
+        type: Boolean,
+        default: true
+      },
+      /**
+       * 闅愯棌缁勪欢
+       */
+      hide: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * canvas 绫诲瀷锛屽井淇″皬绋嬪簭榛樿浣跨敤2d锛岄潪2d寰俊瀹樻柟宸叉斁寮冪淮鎶わ紝闂姣旇緝澶�
+       * 娉ㄦ剰锛氬井淇″皬绋嬪簭type2d鎵嬫満涓婃甯革紝PC涓婂井淇″唴鎵撳紑灏忕▼搴弔oDataURL鎶ラ敊锛岀湅鍚庢湡寰俊瀹樻柟鍥㈤槦浼氫笉浼氬仛鍏煎锛屼笉鍏煎鐨勮瘽鍙兘鍦ㄨ嚜琛屽垽鏂湪PC浣跨敤闈�2d锛屾垨鑰呯洿鎺ユ彁绀虹敤鎴疯鍦ㄦ墜鏈轰笂鎿嶄綔锛屽井淇″洟闃熺殑娴锋姤涓績灏忕▼搴忓氨鏄繖涔堝仛鐨�
+       */
+      type: {
+        type: String,
+        default: () => {
+          // #ifdef MP-WEIXIN
+          return '2d';
+          // #endif
+          // #ifndef MP-WEIXIN
+          return 'normal';
+          // #endif
+        }
+      },
+      /**
+       * 闃熷垪缁樺埗锛屼富瑕侀拡瀵筃Vue绔�
+       */
+      queue: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * 鏄惁闃熷垪鍔犺浇鍥剧墖锛屽彲鍑忓皯canvas鍙戣捣鐨勭綉缁滆祫婧愯姹傦紝鑺傜渷鏈嶅姟鍣ㄨ祫婧�
+       */
+      isQueueLoadImage: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * loading鎬�
+       */
+      loading: {
+        type: Boolean,
+        default: undefined
+      },
+      /**
+       * H5淇濆瓨鍗宠嚜鍔ㄤ笅杞斤紙鍦ㄦ敮鎸佺殑鐜涓嬶級锛岄粯璁alse涓轰粎寮瑰眰鎻愮ず鐢ㄦ埛闇�瑕侀暱鎸夊浘鐗囦繚瀛橈紝涓嶄細鑷姩涓嬭浇
+       */
+      h5SaveIsDownload: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * H5涓嬭浇鍚嶇О
+       */
+      h5DownloadName: {
+        type: String,
+        default: 'uQRCode'
+      }
+    },
+    data() {
+      return {
+        canvas: undefined,
+        canvasType: undefined,
+        canvasContext: undefined,
+        makeDelegate: undefined,
+        drawDelegate: undefined,
+        toTempFilePathDelegate: undefined,
+        makeExecuted: false,
+        makeing: false,
+        drawing: false,
+        isError: false,
+        error: undefined,
+        isH5Save: false,
+        tempFilePath: '',
+        templateOptions: {
+          size: 0,
+          width: 0, // 缁勪欢瀹藉害
+          height: 0,
+          canvasWidth: 0, // canvas瀹藉害
+          canvasHeight: 0,
+          canvasTransform: '',
+          canvasDisplay: false
+        },
+        uqrcodeOptions: {
+          data: ''
+        },
+        plugins: [],
+        makeingPattern: [
+          [
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true]
+          ],
+          [
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, true, true, true, false, true, true, true],
+            [true, true, true, true, true, true, false, true, true, true],
+            [true, true, true, true, true, true, false, true, true, true]
+          ],
+          [
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, true, true, true, true, false, false, false],
+            [true, true, true, true, true, true, true, false, false, false],
+            [true, true, true, true, true, true, true, false, false, false],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true]
+          ],
+          [
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true]
+          ]
+        ]
+      };
+    },
+    watch: {
+      type: {
+        handler(val) {
+          const types = ['2d'];
+          if (types.includes(val)) {
+            this.canvasType = val;
+          } else {
+            this.canvasType = undefined;
+          }
+        },
+        immediate: true
+      },
+      value: {
+        handler() {
+          if (this.auto) {
+            this.remake();
+          }
+        }
+      },
+      size: {
+        handler() {
+          if (this.auto) {
+            this.remake();
+          }
+        }
+      },
+      options: {
+        handler() {
+          if (this.auto) {
+            this.remake();
+          }
+        },
+        deep: true
+      },
+      makeing: {
+        handler(val) {
+          if (!val) {
+            if (typeof this.toTempFilePathDelegate === 'function') {
+              this.toTempFilePathDelegate();
+            }
+          }
+        }
+      }
+    },
+    mounted() {
+      this.templateOptions.size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
+      this.templateOptions.width = this.templateOptions.size;
+      this.templateOptions.height = this.templateOptions.size;
+      this.templateOptions.canvasWidth = this.templateOptions.size;
+      this.templateOptions.canvasHeight = this.templateOptions.size;
+      if (this.canvasType == '2d') {
+        // #ifndef MP-WEIXIN
+        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+        this.templateOptions.canvasHeight})`;
+        // #endif
+      } else {
+        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+        this.templateOptions.canvasHeight})`;
+      }
+      if (this.start) {
+        this.make();
+      }
+    },
+    methods: {
+      /**
+       * 鑾峰彇妯℃澘閫夐」
+       */
+      getTemplateOptions() {
+        var size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
+        return deepReplace(this.templateOptions, {
+          size,
+          width: size,
+          height: size
+        });
+      },
+      /**
+       * 鑾峰彇鎻掍欢閫夐」
+       */
+      getUqrcodeOptions() {
+        return deepReplace(this.options, {
+          data: String(this.value),
+          size: Number(this.templateOptions.size)
+        });
+      },
+      /**
+       * 閲嶇疆鐢诲竷
+       */
+      resetCanvas(callback) {
+        this.templateOptions.canvasDisplay = false;
+        this.$nextTick(() => {
+          this.templateOptions.canvasDisplay = true;
+          this.$nextTick(() => {
+            callback && callback();
+          });
+        });
+      },
+      /**
+       * 缁樺埗浜岀淮鐮�
+       */
+      async draw(callback = {}, isDrawDelegate = false) {
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        if (this.drawing) {
+          if (!isDrawDelegate) {
+            this.drawDelegate = () => {
+              this.draw(callback, true);
+            };
+            return;
+          }
+        } else {
+          this.drawing = true;
+        }
+
+        if (!this.canvasId) {
+          console.error('[uQRCode]: canvasId must be set!');
+          this.isError = true;
+          this.drawing = false;
+          callback.fail({
+            errMsg: '[uQRCode]: canvasId must be set!'
+          });
+          callback.complete({
+            errMsg: '[uQRCode]: canvasId must be set!'
+          });
+          return;
+        }
+        if (!this.value) {
+          console.error('[uQRCode]: value must be set!');
+          this.isError = true;
+          this.drawing = false;
+          callback.fail({
+            errMsg: '[uQRCode]: value must be set!'
+          });
+          callback.complete({
+            errMsg: '[uQRCode]: value must be set!'
+          });
+          return;
+        }
+
+        /* 缁勪欢鏁版嵁 */
+        this.templateOptions = this.getTemplateOptions();
+        /* uQRCode閫夐」 */
+        this.uqrcodeOptions = this.getUqrcodeOptions();
+        /* 绾犻敊绛夌骇鍏煎瀛楁瘝鍐欐硶 */
+        if (typeof this.uqrcodeOptions.errorCorrectLevel === 'string') {
+          this.uqrcodeOptions.errorCorrectLevel = UQRCode.errorCorrectLevel[this.uqrcodeOptions.errorCorrectLevel];
+        }
+        /* nvue涓嶆敮鎸佸姩鎬佷慨鏀筭canvas灏哄锛岄櫎nvue澶栵紝榛樿浣跨敤useDynamicSize */
+        // #ifndef APP-NVUE
+        if (typeof this.options.useDynamicSize === 'undefined') {
+          this.uqrcodeOptions.useDynamicSize = true;
+        }
+        // #endif
+        // #ifdef APP-NVUE
+        if (typeof this.options.useDynamicSize === 'undefined') {
+          this.uqrcodeOptions.useDynamicSize = false;
+        }
+        // if (typeof this.options.drawReserve === 'undefined') {
+        //   this.uqrcodeOptions.drawReserve = true;
+        // }
+        // #endif
+
+        /* 鑾峰彇uQRCode瀹炰緥 */
+        const qr = instance = new UQRCode();
+        /* 娉ㄥ唽鎵╁睍 */
+        this.plugins.forEach(p => qr.register(p.plugin));
+        /* 璁剧疆uQRCode閫夐」 */
+        qr.setOptions(this.uqrcodeOptions);
+        /* 璋冪敤鍒朵綔浜岀淮鐮佹柟娉� */
+        qr.make();
+
+        /* 鑾峰彇canvas涓婁笅鏂� */
+        let canvasContext = null;
+        // #ifndef APP-NVUE
+        if (this.canvasType === '2d') {
+          // #ifdef MP-WEIXIN
+          /* 寰俊灏忕▼搴忚幏鍙朿anvas2d涓婁笅鏂囨柟寮� */
+          const canvas = (this.canvas = await new Promise(resolve => {
+            uni
+              .createSelectorQuery()
+              .in(this) // 鍦ㄧ粍浠跺唴浣跨敤闇�瑕�
+              .select(`#${this.canvasId}`)
+              .fields({
+                node: true,
+                size: true
+              })
+              .exec(res => {
+                resolve(res[0].node);
+              });
+          }));
+          canvasContext = this.canvasContext = canvas.getContext('2d');
+          /* 2d鐨勭粍浠惰缃楂樹笌瀹為檯canvas缁樺埗瀹介珮涓嶆槸涓�涓紝鎵撲釜姣旀柟锛岀粍浠秙ize=200锛宑anvas.width璁剧疆涓�100锛岄偅涔堢粯鍒跺嚭鏉ュ氨鏄�100=200锛岀粍浠秙ize=400锛宑anvas.width璁剧疆涓�800锛岀粯鍒跺ぇ灏忚繕鏄�800=400锛屾墍浠ユ棤闇�鐞嗕細涓嬫柟杩斿洖鐨刣ynamicSize鏄灏戯紝鎸塪pr閲嶆柊璧嬪�肩粰canvas鍗冲彲 */
+          this.templateOptions.canvasWidth = qr.size;
+          this.templateOptions.canvasHeight = qr.size;
+          this.templateOptions.canvasTransform = '';
+          /* 浣跨敤dynamicSize+scale锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛宒pr鍙互瑙e喅妯$硦闂 */
+          const dpr = uni.getSystemInfoSync().pixelRatio;
+          canvas.width = qr.dynamicSize * dpr;
+          canvas.height = qr.dynamicSize * dpr;
+          canvasContext.scale(dpr, dpr);
+          /* 寰俊灏忕▼搴忚幏鍙栧浘鍍忔柟寮� */
+          qr.loadImage = this.getLoadImage(function(src) {
+            /* 灏忕▼搴忎笅鑾峰彇缃戠粶鍥剧墖淇℃伅闇�鍏堥厤缃甦ownload鍩熷悕鐧藉悕鍗曟墠鑳界敓鏁� */
+            return new Promise((resolve, reject) => {
+              const img = canvas.createImage();
+              img.src = src;
+              img.onload = () => {
+                resolve(img);
+              };
+              img.onerror = err => {
+                reject(err);
+              };
+            });
+          });
+          // #endif
+          // #ifndef MP-WEIXIN
+          /* 闈炲井淇″皬绋嬪簭涓嶆敮鎸�2d锛屽垏鎹㈠洖uniapp鑾峰彇canvas涓婁笅鏂囨柟寮� */
+          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
+          /* 浣跨敤dynamicSize锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛屽啀閫氳繃scale缂╂斁鑷硈ize锛屼娇鍏惰揪鍒版墍璁惧昂瀵� */
+          this.templateOptions.canvasWidth = qr.dynamicSize;
+          this.templateOptions.canvasHeight = qr.dynamicSize;
+          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+          this.templateOptions.canvasHeight})`;
+          /* uniapp鑾峰彇鍥惧儚鏂瑰紡 */
+          qr.loadImage = this.getLoadImage(function(src) {
+            return new Promise((resolve, reject) => {
+              if (src.startsWith('http')) {
+                uni.getImageInfo({
+                  src,
+                  success: res => {
+                    resolve(res.path);
+                  },
+                  fail: err => {
+                    reject(err);
+                  }
+                });
+              } else {
+                if (src.startsWith('.')) {
+                  console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+                  throw new Error('[uQRCode]: local image path only supports absolute path!');
+                } else {
+                  resolve(src);
+                }
+              }
+            });
+          });
+          // #endif
+        } else {
+          /* uniapp鑾峰彇canvas涓婁笅鏂囨柟寮� */
+          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
+          /* 浣跨敤dynamicSize锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛屽啀閫氳繃scale缂╂斁鑷硈ize锛屼娇鍏惰揪鍒版墍璁惧昂瀵� */
+          this.templateOptions.canvasWidth = qr.dynamicSize;
+          this.templateOptions.canvasHeight = qr.dynamicSize;
+          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+          this.templateOptions.canvasHeight})`;
+          /* uniapp鑾峰彇鍥惧儚鏂瑰紡 */
+          qr.loadImage = this.getLoadImage(function(src) {
+            return new Promise((resolve, reject) => {
+              /* getImageInfo鍦ㄥ井淇″皬绋嬪簭鐨刡ug锛氭湰鍦拌矾寰勮繑鍥炶矾寰勪細鎶婂紑澶寸殑/鎴�../绉婚櫎锛屽鑷磋矾寰勯敊璇紝瑙e喅鏂规硶锛氶檺鍒跺彧鑳戒娇鐢ㄧ粷瀵硅矾寰� */
+              if (src.startsWith('http')) {
+                uni.getImageInfo({
+                  src,
+                  success: res => {
+                    resolve(res.path);
+                  },
+                  fail: err => {
+                    reject(err);
+                  }
+                });
+              } else {
+                if (src.startsWith('.')) {
+                  console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+                  throw new Error('[uQRCode]: local image path only supports absolute path!');
+                } else {
+                  resolve(src);
+                }
+              }
+            });
+          });
+        }
+        // #endif
+        // #ifdef APP-NVUE
+        /* NVue鑾峰彇canvas涓婁笅鏂囨柟寮� */
+        const gcanvas = this.$refs['gcanvas'];
+        const canvas = enable(gcanvas, {
+          bridge: WeexBridge
+        });
+        canvasContext = this.canvasContext = canvas.getContext('2d');
+        /* NVue鑾峰彇鍥惧儚鏂瑰紡 */
+        qr.loadImage = this.getLoadImage(function(src) {
+          return new Promise((resolve, reject) => {
+            /* getImageInfo鍦╪vue鐨刡ug锛氳幏鍙栧悓涓�涓矾寰勭殑鍥剧墖淇℃伅锛屽悓涓�鏃堕棿绗竴娆¤幏鍙栨垚鍔燂紝鍚庣画澶辫触锛岀寽娴嬫槸鍐欏叆鏈湴鏃朵骇鐢熸枃浠跺啓鍏ュ啿绐侊紝鎵�浠ユ病鏈夎繑鍥烇紝鐗瑰埆鏄浜庣綉缁滆祫婧� --- 宸插疄鐜伴槦鍒楃粯鍒讹紝宸茶В鍐虫闂 */
+            if (src.startsWith('.')) {
+              console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+              throw new Error('[uQRCode]: local image path only supports absolute path!');
+            } else {
+              uni.getImageInfo({
+                src,
+                success: res => {
+                  resolve(res.path);
+                },
+                fail: err => {
+                  reject(err);
+                }
+              });
+            }
+          });
+        });
+        // #endif
+
+        /* 璁剧疆uQRCode瀹炰緥鐨刢anvas涓婁笅鏂� */
+        qr.canvasContext = canvasContext;
+        /* 寤舵椂绛夊緟椤甸潰閲嶆柊缁樺埗瀹屾瘯 */
+        setTimeout(() => {
+          /* 浠庢彃浠惰幏鍙栧叿浣撹璋冪敤鍝竴涓墿灞曞嚱鏁� */
+          var plugin = this.plugins.find(p => p.name == qr.style);
+          var drawCanvasName = plugin ? plugin.drawCanvas : 'drawCanvas';
+          /* 铏界劧qr[drawCanvasName]鏄洿鎺ヨ繑鍥濸romise鐨勶紝浣嗙敱浜巎s鍐呴儴this鎸囧悜闂锛屾晠涓嶈兘鐩存帴exec(qr[drawCanvasName])姝ゆ柟寮忔墽琛岋紝闇�瑕佹敼鎴恊xec(() => qr[drawCanvasName]())鎵嶈兘姝g‘鑾峰彇this */
+          var drawCanvas;
+          if (this.queue) {
+            drawCanvas = () => queueDraw.exec(() => qr[drawCanvasName]());
+            // drawCanvas = () => queueDraw.exec(() => new Promise((resolve, reject) => {
+            //   setTimeout(() => {
+            //     qr[drawCanvasName]().then(resolve).catch(reject);
+            //   }, 1000);
+            // }));
+          } else {
+            drawCanvas = () => qr[drawCanvasName]();
+          }
+          /* 璋冪敤缁樺埗鏂规硶灏嗕簩缁寸爜鍥炬缁樺埗鍒癱anvas涓� */
+          drawCanvas()
+            .then(() => {
+              if (this.drawDelegate) {
+                /* 楂橀閲嶇粯绾犳 */
+                let delegate = this.drawDelegate;
+                this.drawDelegate = undefined;
+                delegate();
+              } else {
+                this.drawing = false;
+                callback.success();
+              }
+            })
+            .catch(err => {
+              console.log(err);
+              if (this.drawDelegate) {
+                /* 楂橀閲嶇粯绾犳 */
+                let delegate = this.drawDelegate;
+                this.drawDelegate = undefined;
+                delegate();
+              } else {
+                this.drawing = false;
+                this.isError = true;
+                callback.fail(err);
+              }
+            })
+            .finally(() => {
+              callback.complete();
+            });
+        }, 300);
+      },
+      /**
+       * 鐢熸垚浜岀淮鐮�
+       */
+      make(callback = {}) {
+        this.makeExecuted = true;
+        this.makeing = true;
+        this.isError = false;
+
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        this.resetCanvas(() => {
+          clearTimeout(this.makeDelegate);
+          this.makeDelegate = setTimeout(() => {
+            this.draw({
+              success: () => {
+                setTimeout(() => {
+                  callback.success();
+                  this.complete(true);
+                }, 300);
+              },
+              fail: err => {
+                callback.fail(err);
+                this.error = err;
+                this.complete(false, err.errMsg);
+              },
+              complete: () => {
+                callback.complete();
+                this.makeing = false;
+              }
+            });
+          }, 300);
+        });
+      },
+      /**
+       * 閲嶆柊鐢熸垚
+       */
+      remake(callback) {
+        this.$emit('change');
+        this.make(callback);
+      },
+      /**
+       * 鐢熸垚瀹屾垚
+       */
+      complete(success = true, errMsg = '') {
+        if (success) {
+          this.$emit('complete', {
+            success
+          });
+        } else {
+          this.$emit('complete', {
+            success,
+            errMsg
+          });
+        }
+      },
+      /**
+       * 瀵煎嚭涓存椂璺緞
+       */
+      toTempFilePath(callback = {}) {
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        if (!this.makeExecuted) {
+          console.error('[uQRCode]: make() 鏂规硶浠庢湭璋冪敤锛佽鍏堟垚鍔熻皟鐢� make() 鍚庡啀杩涜鎿嶄綔銆�');
+          var err = {
+            errMsg: '[uQRCode]: make() method has never been executed! please execute make() successfully before operating.'
+          };
+          callback.fail(err);
+          callback.complete(err);
+          return;
+        }
+
+        if (this.isError) {
+          callback.fail(this.error);
+          callback.complete(this.error);
+          return;
+        }
+
+        if (this.makeing) {
+          /* 濡傛灉杩樺湪鐢熸垚鐘舵�侊紝閭e綋鍓嶆搷浣滃皢鎵樼鍒板鎵橈紝鐩戝惉鐢熸垚瀹屾垚鍚庡啀閫氳繃濮旀墭澶嶈皟褰撳墠鏂规硶 */
+          this.toTempFilePathDelegate = () => {
+            this.toTempFilePath(callback);
+          };
+          return;
+        } else {
+          this.toTempFilePathDelegate = null;
+        }
+
+        // #ifndef APP-NVUE
+        if (this.canvasType === '2d') {
+          // #ifdef MP-WEIXIN
+          try {
+            let dataURL = null;
+            // #ifdef VUE3
+            dataURL = toRaw(this.canvas)
+              .toDataURL();
+            // #endif
+            // #ifndef VUE3
+            dataURL = this.canvas.toDataURL();
+            // #endif
+            callback.success({
+              tempFilePath: dataURL
+            });
+            callback.complete({
+              tempFilePath: dataURL
+            });
+          } catch (e) {
+            callback.fail(e);
+            callback.complete(e);
+          }
+          // #endif
+        } else {
+          uni.canvasToTempFilePath({
+              canvasId: this.canvasId,
+              fileType: this.fileType,
+              width: Number(this.templateOptions.canvasWidth),
+              height: Number(this.templateOptions.canvasHeight),
+              destWidth: Number(this.templateOptions.size),
+              destHeight: Number(this.templateOptions.size),
+              success: res => {
+                callback.success(res);
+              },
+              fail: err => {
+                callback.fail(err);
+              },
+              complete: () => {
+                callback.complete();
+              }
+            },
+            this
+          );
+        }
+        // #endif
+        // #ifdef APP-NVUE
+        const dpr = uni.getSystemInfoSync().pixelRatio;
+        this.canvasContext.toTempFilePath(
+          0,
+          0,
+          this.templateOptions.canvasWidth * dpr,
+          this.templateOptions.canvasHeight * dpr,
+          this.templateOptions.size * dpr,
+          this.templateOptions.size * dpr,
+          '',
+          1,
+          res => {
+            callback.success(res);
+            callback.complete(res);
+          }
+        );
+        // #endif
+      },
+      /**
+       * 淇濆瓨
+       */
+      save(callback = {}) {
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        this.toTempFilePath({
+          success: res => {
+            // #ifndef H5
+            if (this.canvasType === '2d') {
+              // #ifdef MP-WEIXIN
+              /* 闇�瑕佸皢 data:image/png;base64, 杩欐鍘婚櫎 writeFile 鎵嶈兘姝e父鎵撳紑鏂囦欢锛屽惁鍒欐槸鎹熷潖鏂囦欢锛屾棤娉曟墦寮� */
+              const reg = new RegExp('^data:image/png;base64,', 'g');
+              const dataURL = res.tempFilePath.replace(reg, '');
+              const fs = wx.getFileSystemManager();
+              const tempFilePath = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}${
+                Math.random()
+                  .toString()
+                  .split('.')[1]
+              }.png`;
+              fs.writeFile({
+                filePath: tempFilePath, // 瑕佸啓鍏ョ殑鏂囦欢璺緞 (鏈湴璺緞)
+                data: dataURL, // base64鍥剧墖
+                encoding: 'base64',
+                success: res1 => {
+                  uni.saveImageToPhotosAlbum({
+                    filePath: tempFilePath,
+                    success: res2 => {
+                      callback.success(res2);
+                    },
+                    fail: err2 => {
+                      callback.fail(err2);
+                    },
+                    complete: () => {
+                      callback.complete();
+                    }
+                  });
+                },
+                fail: err => {
+                  callback.fail(err);
+                },
+                complete: () => {
+                  callback.complete();
+                }
+              });
+              // #endif
+            } else {
+              uni.saveImageToPhotosAlbum({
+                filePath: res.tempFilePath,
+                success: res1 => {
+                  callback.success(res1);
+                },
+                fail: err1 => {
+                  callback.fail(err1);
+                },
+                complete: () => {
+                  callback.complete();
+                }
+              });
+            }
+            // #endif
+
+            // #ifdef H5
+            /* 鍙互鍦ㄧ數鑴戞祻瑙堝櫒涓嬭浇锛岀Щ鍔ㄧiOS涓嶈锛屽畨鍗撳井淇℃祻瑙堝櫒涓嶈锛屽畨鍗撳閮ㄦ祻瑙堝櫒鍙互 */
+            this.isH5Save = true;
+            this.tempFilePath = res.tempFilePath;
+            if (this.h5SaveIsDownload) {
+              const aEle = document.createElement('a');
+              aEle.download = this.h5DownloadName; // 璁剧疆涓嬭浇鐨勬枃浠跺悕锛岄粯璁ゆ槸'涓嬭浇'
+              aEle.href = res.tempFilePath;
+              document.body.appendChild(aEle);
+              aEle.click();
+              aEle.remove(); // 涓嬭浇涔嬪悗鎶婂垱寤虹殑鍏冪礌鍒犻櫎
+            }
+            callback.success({
+              errMsg: 'ok'
+            });
+            callback.complete({
+              errMsg: 'ok'
+            });
+            // #endif
+          },
+          fail: err => {
+            callback.fail(err);
+            callback.complete(err);
+          }
+        });
+      },
+      /**
+       * 娉ㄥ唽click浜嬩欢
+       */
+      onClick(e) {
+        this.$emit('click', e);
+      },
+      /**
+       * 鑾峰彇瀹炰緥
+       */
+      getInstance() {
+        return instance;
+      },
+      /**
+       * 娉ㄥ唽鎵╁睍锛岀粍浠朵粎鏀寔娉ㄥ唽type涓簊tyle鐨刣rawCanvas鎵╁睍
+       * @param {Object} plugin
+       */
+      registerStyle(plugin) {
+        if (plugin.Type != 'style') {
+          console.warn('[uQRCode]: registerStyle 浠呮敮鎸佹敞鍐� style 绫诲瀷鐨勬墿灞曪紒');
+          return {
+            errMsg: 'registerStyle 浠呮敮鎸佹敞鍐� style 绫诲瀷鐨勬墿灞曪紒'
+          };
+        }
+        if (typeof plugin === 'function') {
+          this.plugins.push({
+            plugin,
+            name: plugin.Name,
+            drawCanvas: plugin.DrawCanvas
+          });
+        }
+      },
+      getLoadImage(loadImage) {
+        var that = this;
+        if (typeof loadImage == 'function') {
+          return function(src) {
+            /* 鍒ゆ柇鏄惁鏄槦鍒楀姞杞藉浘鐗囩殑 */
+            if (that.isQueueLoadImage) {
+              /* 瑙e喅iOS APP||NVUE鍚屾椂缁樺埗澶氫釜浜岀淮鐮佸鑷村浘鐗囦涪澶遍渶浣跨敤闃熷垪 */
+              return queueLoadImage.exec(() => {
+                return new Promise((resolve, reject) => {
+                  setTimeout(() => {
+                    const cache = cacheImageList.find(x => x.src == src);
+                    if (cache) {
+                      resolve(cache.img);
+                    } else {
+                      loadImage(src)
+                        .then(img => {
+                          cacheImageList.push({
+                            src,
+                            img
+                          });
+                          resolve(img);
+                        })
+                        .catch(err => {
+                          reject(err);
+                        });
+                    }
+                  }, 10);
+                });
+              });
+            } else {
+              return loadImage(src);
+            }
+          };
+        } else {
+          return function(src) {
+            return Promise.resolve(src);
+          };
+        }
+      }
+    }
+  };
+
+  /**
+   * 瀵硅薄灞炴�ф繁搴︽浛鎹�
+   * @param {Object} o 鍘熷瀵硅薄/榛樿瀵硅薄/琚浛鎹㈢殑瀵硅薄
+   * @param {Object} r 浠庤繖涓璞¢噷鍙栧�兼浛鎹㈠埌o瀵硅薄閲�
+   * @return {Object} 鏇挎崲鍚庣殑鏂板璞�
+   */
+  function deepReplace(o = {}, r = {}, c = false) {
+    let obj;
+    if (c) {
+      // 浠庢簮鏇挎崲
+      obj = o;
+    } else {
+      // 涓嶆浛鎹㈡簮锛宑opy涓�浠藉浠芥潵鏇挎崲
+      obj = {
+        ...o
+      };
+    }
+    for (let k in r) {
+      var vr = r[k];
+      if (vr != undefined) {
+        if (vr.constructor == Object) {
+          obj[k] = this.deepReplace(obj[k], vr);
+        } else if (vr.constructor == String && !vr) {
+          obj[k] = obj[k];
+        } else {
+          obj[k] = vr;
+        }
+      }
+    }
+    return obj;
+  }
+</script>
+
+<style scoped>
+  .uqrcode {
+    position: relative;
+  }
+
+  .uqrcode-hide {
+    position: fixed;
+    left: 7500rpx;
+  }
+
+  .uqrcode-canvas {
+    transform-origin: top left;
+  }
+
+  .uqrcode-makeing {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 10;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    align-items: center;
+  }
+
+  .uqrcode-makeing-image {
+    /* #ifndef APP-NVUE */
+    display: block;
+    max-width: 120px;
+    max-height: 120px;
+    /* #endif */
+  }
+
+  .uqrcode-error {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    align-items: center;
+  }
+
+  .uqrcode-error-message {
+    font-size: 12px;
+    color: #939291;
+  }
+
+  /* #ifdef H5 */
+  .uqrcode-h5-save {
+    position: fixed;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 100;
+    background-color: rgba(0, 0, 0, 0.68);
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .uqrcode-h5-save-image {
+    width: 512rpx;
+    height: 512rpx;
+    padding: 32rpx;
+  }
+
+  .uqrcode-h5-save-text {
+    margin-top: 20rpx;
+    font-size: 32rpx;
+    font-weight: 700;
+    color: #ffffff;
+  }
+
+  .uqrcode-h5-save-close {
+    position: relative;
+    margin-top: 72rpx;
+    width: 60rpx;
+    height: 60rpx;
+    border: 2rpx solid #ffffff;
+    border-radius: 60rpx;
+    padding: 10rpx;
+  }
+
+  .uqrcode-h5-save-close-before {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%) rotate(45deg);
+    width: 40rpx;
+    height: 4rpx;
+    background: #ffffff;
+  }
+
+  .uqrcode-h5-save-close-after {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%) rotate(-45deg);
+    width: 40rpx;
+    height: 4rpx;
+    background: #ffffff;
+  }
+
+  /* #endif */
+</style>
diff --git a/uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue b/uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue
new file mode 100644
index 0000000..4fefaac
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/components/uqrcode/uqrcode.vue
@@ -0,0 +1,1131 @@
+<template>
+  <view class="uqrcode" :class="{ 'uqrcode-hide': hide }" :style="{ width: `${templateOptions.width}px`, height: `${templateOptions.height}px` }">
+    <view class="uqrcode-canvas-wrapper">
+      <!-- 鐢诲竷 -->
+      <!-- #ifndef APP-NVUE -->
+      <canvas class="uqrcode-canvas" :id="canvasId" :canvas-id="canvasId" :type="canvasType" :style="{
+          width: `${templateOptions.canvasWidth}px`,
+          height: `${templateOptions.canvasHeight}px`,
+          transform: templateOptions.canvasTransform
+        }" v-if="templateOptions.canvasDisplay" @click="onClick"></canvas>
+      <!-- #endif -->
+
+      <!-- nvue鐢╣canvas -->
+      <!-- #ifdef APP-NVUE -->
+      <gcanvas class="uqrcode-canvas" ref="gcanvas" :style="{
+          width: `${templateOptions.canvasWidth}px`,
+          height: `${templateOptions.canvasHeight}px`
+        }" v-if="templateOptions.canvasDisplay" @click="onClick"></gcanvas>
+      <!-- #endif -->
+    </view>
+
+    <!-- 鍔犺浇鏁堟灉 -->
+    <view class="uqrcode-makeing" v-if="loading === undefined ? makeing : loading">
+      <slot name="loading">
+        <image class="uqrcode-makeing-image" :style="{ width: `${templateOptions.size / 4}px`, height: `${templateOptions.size / 4}px` }"
+          src="data:image/gif;base64,R0lGODlhAAEAAfIEAOHh4SSsWuDg4N3d3f///wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ4OCwgMjAyMC8wNy8xMC0yMjowNjo1MyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjAyODhGMzM4RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjAyODhGMzM5RDEwMTExRUM4MDhCRkVBQkE2QUZDQzkwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4OEYzMzZEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4OEYzMzdEMTAxMTFFQzgwOEJGRUFCQTZBRkNDOTAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQ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">
+        </image>
+      </slot>
+    </view>
+
+    <!-- 閿欒澶勭悊 -->
+    <view class="uqrcode-error" v-if="isError" @click="onClick">
+      <slot name="error" :error="error">
+        <text class="uqrcode-error-message">{{ error.errMsg }}</text>
+      </slot>
+    </view>
+
+    <!-- H5淇濆瓨鎻愮ず -->
+    <!-- #ifdef H5 -->
+    <view class="uqrcode-h5-save" v-if="isH5Save">
+      <slot name="h5save" :tempFilePath="tempFilePath">
+        <image class="uqrcode-h5-save-image" :src="tempFilePath"></image>
+        <text class="uqrcode-h5-save-text">{{ h5SaveIsDownload ? '鑻ヤ繚瀛樺け璐ワ紝' : '' }}璇烽暱鎸変簩缁寸爜杩涜淇濆瓨</text>
+      </slot>
+      <view class="uqrcode-h5-save-close" @click.stop="isH5Save = false">
+        <view class="uqrcode-h5-save-close-before"></view>
+        <view class="uqrcode-h5-save-close-after"></view>
+      </view>
+    </view>
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+  // #ifdef VUE3
+  import {
+    toRaw
+  } from 'vue';
+  // #endif
+
+  /* 寮曞叆uQRCode鏍稿績js */
+  import UQRCode from '../../js_sdk/uqrcode/uqrcode';
+
+  /* 寮曞叆nvue鎵�闇�妯″潡 */
+  // #ifdef APP-NVUE
+  import {
+    enable,
+    WeexBridge
+  } from '../../js_sdk/gcanvas';
+  const modal = weex.requireModule('modal');
+  // #endif
+
+  /* 寮曞叆闃熷垪 */
+  import {
+    queueDraw,
+    queueLoadImage
+  } from '../../common/queue';
+  /* 寮曞叆缂撳瓨鍥剧墖 */
+  import {
+    cacheImageList
+  } from '../../common/cache';
+
+  let instance = null;
+
+  export default {
+    name: 'uqrcode',
+    props: {
+      /**
+       * canvas缁勪欢id
+       */
+      canvasId: {
+        type: String,
+        required: true // canvasId鍦ㄥ井淇″皬绋嬪簭鍒濆鍊间笉鑳戒负绌猴紝created涓祴鍊间篃涓嶈锛屽繀椤荤粰涓�涓�硷紝鍚﹀垯鎸傝浇缁勪欢鍚庢棤娉曠粯鍒躲�備笉鑰冭檻鐢ㄩ殢鏈篿d锛寀uid
+      },
+      /**
+       * 浜岀淮鐮佸唴瀹�
+       */
+      value: {
+        type: [String, Number]
+      },
+      /**
+       * 閫夐」
+       */
+      options: {
+        type: Object,
+        default: () => {
+          return {};
+        }
+      },
+      /**
+       * 浜岀淮鐮佸ぇ灏�
+       */
+      size: {
+        type: [String, Number],
+        default: 200
+      },
+      /**
+       * 浜岀淮鐮佸昂瀵稿崟浣�
+       */
+      sizeUnit: {
+        type: String,
+        default: 'px'
+      },
+      /**
+       * 瀵煎嚭鐨勬枃浠剁被鍨�
+       */
+      fileType: {
+        type: String,
+        default: 'png'
+      },
+      /**
+       * 鏄惁鍒濆鍖栫粍浠跺悗灏卞紑濮嬬敓鎴�
+       */
+      start: {
+        type: Boolean,
+        default: true
+      },
+      /**
+       * 鏄惁鏁版嵁鍙戠敓鏀瑰彉鑷姩閲嶇粯
+       */
+      auto: {
+        type: Boolean,
+        default: true
+      },
+      /**
+       * 闅愯棌缁勪欢
+       */
+      hide: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * canvas 绫诲瀷锛屽井淇″皬绋嬪簭榛樿浣跨敤2d锛岄潪2d寰俊瀹樻柟宸叉斁寮冪淮鎶わ紝闂姣旇緝澶�
+       * 娉ㄦ剰锛氬井淇″皬绋嬪簭type2d鎵嬫満涓婃甯革紝PC涓婂井淇″唴鎵撳紑灏忕▼搴弔oDataURL鎶ラ敊锛岀湅鍚庢湡寰俊瀹樻柟鍥㈤槦浼氫笉浼氬仛鍏煎锛屼笉鍏煎鐨勮瘽鍙兘鍦ㄨ嚜琛屽垽鏂湪PC浣跨敤闈�2d锛屾垨鑰呯洿鎺ユ彁绀虹敤鎴疯鍦ㄦ墜鏈轰笂鎿嶄綔锛屽井淇″洟闃熺殑娴锋姤涓績灏忕▼搴忓氨鏄繖涔堝仛鐨�
+       */
+      type: {
+        type: String,
+        default: () => {
+          // #ifdef MP-WEIXIN
+          return '2d';
+          // #endif
+          // #ifndef MP-WEIXIN
+          return 'normal';
+          // #endif
+        }
+      },
+      /**
+       * 闃熷垪缁樺埗锛屼富瑕侀拡瀵筃Vue绔�
+       */
+      queue: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * 鏄惁闃熷垪鍔犺浇鍥剧墖锛屽彲鍑忓皯canvas鍙戣捣鐨勭綉缁滆祫婧愯姹傦紝鑺傜渷鏈嶅姟鍣ㄨ祫婧�
+       */
+      isQueueLoadImage: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * loading鎬�
+       */
+      loading: {
+        type: Boolean,
+        default: undefined
+      },
+      /**
+       * H5淇濆瓨鍗宠嚜鍔ㄤ笅杞斤紙鍦ㄦ敮鎸佺殑鐜涓嬶級锛岄粯璁alse涓轰粎寮瑰眰鎻愮ず鐢ㄦ埛闇�瑕侀暱鎸夊浘鐗囦繚瀛橈紝涓嶄細鑷姩涓嬭浇
+       */
+      h5SaveIsDownload: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * H5涓嬭浇鍚嶇О
+       */
+      h5DownloadName: {
+        type: String,
+        default: 'uQRCode'
+      }
+    },
+    data() {
+      return {
+        canvas: undefined,
+        canvasType: undefined,
+        canvasContext: undefined,
+        makeDelegate: undefined,
+        drawDelegate: undefined,
+        toTempFilePathDelegate: undefined,
+        makeExecuted: false,
+        makeing: false,
+        drawing: false,
+        isError: false,
+        error: undefined,
+        isH5Save: false,
+        tempFilePath: '',
+        templateOptions: {
+          size: 0,
+          width: 0, // 缁勪欢瀹藉害
+          height: 0,
+          canvasWidth: 0, // canvas瀹藉害
+          canvasHeight: 0,
+          canvasTransform: '',
+          canvasDisplay: false
+        },
+        uqrcodeOptions: {
+          data: ''
+        },
+        plugins: [],
+        makeingPattern: [
+          [
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true]
+          ],
+          [
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, true, true, true, false, true, true, true],
+            [true, true, true, true, true, true, false, true, true, true],
+            [true, true, true, true, true, true, false, true, true, true]
+          ],
+          [
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, true, true, true, true, false, false, false],
+            [true, true, true, true, true, true, true, false, false, false],
+            [true, true, true, true, true, true, true, false, false, false],
+            [true, true, true, false, false, false, false, true, true, true],
+            [true, true, true, false, false, false, false, true, true, true]
+          ],
+          [
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, false, false, false, false, false, false, false],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true],
+            [true, true, true, true, true, true, true, true, true, true]
+          ]
+        ]
+      };
+    },
+    watch: {
+      type: {
+        handler(val) {
+          const types = ['2d'];
+          if (types.includes(val)) {
+            this.canvasType = val;
+          } else {
+            this.canvasType = undefined;
+          }
+        },
+        immediate: true
+      },
+      value: {
+        handler() {
+          if (this.auto) {
+            this.remake();
+          }
+        }
+      },
+      size: {
+        handler() {
+          if (this.auto) {
+            this.remake();
+          }
+        }
+      },
+      options: {
+        handler() {
+          if (this.auto) {
+            this.remake();
+          }
+        },
+        deep: true
+      },
+      makeing: {
+        handler(val) {
+          if (!val) {
+            if (typeof this.toTempFilePathDelegate === 'function') {
+              this.toTempFilePathDelegate();
+            }
+          }
+        }
+      }
+    },
+    mounted() {
+      this.templateOptions.size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
+      this.templateOptions.width = this.templateOptions.size;
+      this.templateOptions.height = this.templateOptions.size;
+      this.templateOptions.canvasWidth = this.templateOptions.size;
+      this.templateOptions.canvasHeight = this.templateOptions.size;
+      if (this.canvasType == '2d') {
+        // #ifndef MP-WEIXIN
+        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+        this.templateOptions.canvasHeight})`;
+        // #endif
+      } else {
+        this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+        this.templateOptions.canvasHeight})`;
+      }
+      if (this.start) {
+        this.make();
+      }
+    },
+    methods: {
+      /**
+       * 鑾峰彇妯℃澘閫夐」
+       */
+      getTemplateOptions() {
+        var size = this.sizeUnit == 'rpx' ? uni.upx2px(this.size) : this.size;
+        return deepReplace(this.templateOptions, {
+          size,
+          width: size,
+          height: size
+        });
+      },
+      /**
+       * 鑾峰彇鎻掍欢閫夐」
+       */
+      getUqrcodeOptions() {
+        return deepReplace(this.options, {
+          data: String(this.value),
+          size: Number(this.templateOptions.size)
+        });
+      },
+      /**
+       * 閲嶇疆鐢诲竷
+       */
+      resetCanvas(callback) {
+        this.templateOptions.canvasDisplay = false;
+        this.$nextTick(() => {
+          this.templateOptions.canvasDisplay = true;
+          this.$nextTick(() => {
+            callback && callback();
+          });
+        });
+      },
+      /**
+       * 缁樺埗浜岀淮鐮�
+       */
+      async draw(callback = {}, isDrawDelegate = false) {
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        if (this.drawing) {
+          if (!isDrawDelegate) {
+            this.drawDelegate = () => {
+              this.draw(callback, true);
+            };
+            return;
+          }
+        } else {
+          this.drawing = true;
+        }
+
+        if (!this.canvasId) {
+          console.error('[uQRCode]: canvasId must be set!');
+          this.isError = true;
+          this.drawing = false;
+          callback.fail({
+            errMsg: '[uQRCode]: canvasId must be set!'
+          });
+          callback.complete({
+            errMsg: '[uQRCode]: canvasId must be set!'
+          });
+          return;
+        }
+        if (!this.value) {
+          console.error('[uQRCode]: value must be set!');
+          this.isError = true;
+          this.drawing = false;
+          callback.fail({
+            errMsg: '[uQRCode]: value must be set!'
+          });
+          callback.complete({
+            errMsg: '[uQRCode]: value must be set!'
+          });
+          return;
+        }
+
+        /* 缁勪欢鏁版嵁 */
+        this.templateOptions = this.getTemplateOptions();
+        /* uQRCode閫夐」 */
+        this.uqrcodeOptions = this.getUqrcodeOptions();
+        /* 绾犻敊绛夌骇鍏煎瀛楁瘝鍐欐硶 */
+        if (typeof this.uqrcodeOptions.errorCorrectLevel === 'string') {
+          this.uqrcodeOptions.errorCorrectLevel = UQRCode.errorCorrectLevel[this.uqrcodeOptions.errorCorrectLevel];
+        }
+        /* nvue涓嶆敮鎸佸姩鎬佷慨鏀筭canvas灏哄锛岄櫎nvue澶栵紝榛樿浣跨敤useDynamicSize */
+        // #ifndef APP-NVUE
+        if (typeof this.options.useDynamicSize === 'undefined') {
+          this.uqrcodeOptions.useDynamicSize = true;
+        }
+        // #endif
+        // #ifdef APP-NVUE
+        if (typeof this.options.useDynamicSize === 'undefined') {
+          this.uqrcodeOptions.useDynamicSize = false;
+        }
+        // if (typeof this.options.drawReserve === 'undefined') {
+        //   this.uqrcodeOptions.drawReserve = true;
+        // }
+        // #endif
+
+        /* 鑾峰彇uQRCode瀹炰緥 */
+        const qr = instance = new UQRCode();
+        /* 娉ㄥ唽鎵╁睍 */
+        this.plugins.forEach(p => qr.register(p.plugin));
+        /* 璁剧疆uQRCode閫夐」 */
+        qr.setOptions(this.uqrcodeOptions);
+        /* 璋冪敤鍒朵綔浜岀淮鐮佹柟娉� */
+        qr.make();
+
+        /* 鑾峰彇canvas涓婁笅鏂� */
+        let canvasContext = null;
+        // #ifndef APP-NVUE
+        if (this.canvasType === '2d') {
+          // #ifdef MP-WEIXIN
+          /* 寰俊灏忕▼搴忚幏鍙朿anvas2d涓婁笅鏂囨柟寮� */
+          const canvas = (this.canvas = await new Promise(resolve => {
+            uni
+              .createSelectorQuery()
+              .in(this) // 鍦ㄧ粍浠跺唴浣跨敤闇�瑕�
+              .select(`#${this.canvasId}`)
+              .fields({
+                node: true,
+                size: true
+              })
+              .exec(res => {
+                resolve(res[0].node);
+              });
+          }));
+          canvasContext = this.canvasContext = canvas.getContext('2d');
+          /* 2d鐨勭粍浠惰缃楂樹笌瀹為檯canvas缁樺埗瀹介珮涓嶆槸涓�涓紝鎵撲釜姣旀柟锛岀粍浠秙ize=200锛宑anvas.width璁剧疆涓�100锛岄偅涔堢粯鍒跺嚭鏉ュ氨鏄�100=200锛岀粍浠秙ize=400锛宑anvas.width璁剧疆涓�800锛岀粯鍒跺ぇ灏忚繕鏄�800=400锛屾墍浠ユ棤闇�鐞嗕細涓嬫柟杩斿洖鐨刣ynamicSize鏄灏戯紝鎸塪pr閲嶆柊璧嬪�肩粰canvas鍗冲彲 */
+          this.templateOptions.canvasWidth = qr.size;
+          this.templateOptions.canvasHeight = qr.size;
+          this.templateOptions.canvasTransform = '';
+          /* 浣跨敤dynamicSize+scale锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛宒pr鍙互瑙e喅妯$硦闂 */
+          const dpr = uni.getSystemInfoSync().pixelRatio;
+          canvas.width = qr.dynamicSize * dpr;
+          canvas.height = qr.dynamicSize * dpr;
+          canvasContext.scale(dpr, dpr);
+          /* 寰俊灏忕▼搴忚幏鍙栧浘鍍忔柟寮� */
+          qr.loadImage = this.getLoadImage(function(src) {
+            /* 灏忕▼搴忎笅鑾峰彇缃戠粶鍥剧墖淇℃伅闇�鍏堥厤缃甦ownload鍩熷悕鐧藉悕鍗曟墠鑳界敓鏁� */
+            return new Promise((resolve, reject) => {
+              const img = canvas.createImage();
+              img.src = src;
+              img.onload = () => {
+                resolve(img);
+              };
+              img.onerror = err => {
+                reject(err);
+              };
+            });
+          });
+          // #endif
+          // #ifndef MP-WEIXIN
+          /* 闈炲井淇″皬绋嬪簭涓嶆敮鎸�2d锛屽垏鎹㈠洖uniapp鑾峰彇canvas涓婁笅鏂囨柟寮� */
+          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
+          /* 浣跨敤dynamicSize锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛屽啀閫氳繃scale缂╂斁鑷硈ize锛屼娇鍏惰揪鍒版墍璁惧昂瀵� */
+          this.templateOptions.canvasWidth = qr.dynamicSize;
+          this.templateOptions.canvasHeight = qr.dynamicSize;
+          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+          this.templateOptions.canvasHeight})`;
+          /* uniapp鑾峰彇鍥惧儚鏂瑰紡 */
+          qr.loadImage = this.getLoadImage(function(src) {
+            return new Promise((resolve, reject) => {
+              if (src.startsWith('http')) {
+                uni.getImageInfo({
+                  src,
+                  success: res => {
+                    resolve(res.path);
+                  },
+                  fail: err => {
+                    reject(err);
+                  }
+                });
+              } else {
+                if (src.startsWith('.')) {
+                  console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+                  throw new Error('[uQRCode]: local image path only supports absolute path!');
+                } else {
+                  resolve(src);
+                }
+              }
+            });
+          });
+          // #endif
+        } else {
+          /* uniapp鑾峰彇canvas涓婁笅鏂囨柟寮� */
+          canvasContext = this.canvasContext = uni.createCanvasContext(this.canvasId, this);
+          /* 浣跨敤dynamicSize锛屽彲浠ヨВ鍐冲皬鍧楅棿鍑虹幇鐧界嚎闂锛屽啀閫氳繃scale缂╂斁鑷硈ize锛屼娇鍏惰揪鍒版墍璁惧昂瀵� */
+          this.templateOptions.canvasWidth = qr.dynamicSize;
+          this.templateOptions.canvasHeight = qr.dynamicSize;
+          this.templateOptions.canvasTransform = `scale(${this.templateOptions.size / this.templateOptions.canvasWidth}, ${this.templateOptions.size /
+          this.templateOptions.canvasHeight})`;
+          /* uniapp鑾峰彇鍥惧儚鏂瑰紡 */
+          qr.loadImage = this.getLoadImage(function(src) {
+            return new Promise((resolve, reject) => {
+              /* getImageInfo鍦ㄥ井淇″皬绋嬪簭鐨刡ug锛氭湰鍦拌矾寰勮繑鍥炶矾寰勪細鎶婂紑澶寸殑/鎴�../绉婚櫎锛屽鑷磋矾寰勯敊璇紝瑙e喅鏂规硶锛氶檺鍒跺彧鑳戒娇鐢ㄧ粷瀵硅矾寰� */
+              if (src.startsWith('http')) {
+                uni.getImageInfo({
+                  src,
+                  success: res => {
+                    resolve(res.path);
+                  },
+                  fail: err => {
+                    reject(err);
+                  }
+                });
+              } else {
+                if (src.startsWith('.')) {
+                  console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+                  throw new Error('[uQRCode]: local image path only supports absolute path!');
+                } else {
+                  resolve(src);
+                }
+              }
+            });
+          });
+        }
+        // #endif
+        // #ifdef APP-NVUE
+        /* NVue鑾峰彇canvas涓婁笅鏂囨柟寮� */
+        const gcanvas = this.$refs['gcanvas'];
+        const canvas = enable(gcanvas, {
+          bridge: WeexBridge
+        });
+        canvasContext = this.canvasContext = canvas.getContext('2d');
+        /* NVue鑾峰彇鍥惧儚鏂瑰紡 */
+        qr.loadImage = this.getLoadImage(function(src) {
+          return new Promise((resolve, reject) => {
+            /* getImageInfo鍦╪vue鐨刡ug锛氳幏鍙栧悓涓�涓矾寰勭殑鍥剧墖淇℃伅锛屽悓涓�鏃堕棿绗竴娆¤幏鍙栨垚鍔燂紝鍚庣画澶辫触锛岀寽娴嬫槸鍐欏叆鏈湴鏃朵骇鐢熸枃浠跺啓鍏ュ啿绐侊紝鎵�浠ユ病鏈夎繑鍥烇紝鐗瑰埆鏄浜庣綉缁滆祫婧� --- 宸插疄鐜伴槦鍒楃粯鍒讹紝宸茶В鍐虫闂 */
+            if (src.startsWith('.')) {
+              console.error('[uQRCode]: 鏈湴鍥剧墖璺緞浠呮敮鎸佺粷瀵硅矾寰勶紒');
+              throw new Error('[uQRCode]: local image path only supports absolute path!');
+            } else {
+              uni.getImageInfo({
+                src,
+                success: res => {
+                  resolve(res.path);
+                },
+                fail: err => {
+                  reject(err);
+                }
+              });
+            }
+          });
+        });
+        // #endif
+
+        /* 璁剧疆uQRCode瀹炰緥鐨刢anvas涓婁笅鏂� */
+        qr.canvasContext = canvasContext;
+        /* 寤舵椂绛夊緟椤甸潰閲嶆柊缁樺埗瀹屾瘯 */
+        setTimeout(() => {
+          /* 浠庢彃浠惰幏鍙栧叿浣撹璋冪敤鍝竴涓墿灞曞嚱鏁� */
+          var plugin = this.plugins.find(p => p.name == qr.style);
+          var drawCanvasName = plugin ? plugin.drawCanvas : 'drawCanvas';
+          /* 铏界劧qr[drawCanvasName]鏄洿鎺ヨ繑鍥濸romise鐨勶紝浣嗙敱浜巎s鍐呴儴this鎸囧悜闂锛屾晠涓嶈兘鐩存帴exec(qr[drawCanvasName])姝ゆ柟寮忔墽琛岋紝闇�瑕佹敼鎴恊xec(() => qr[drawCanvasName]())鎵嶈兘姝g‘鑾峰彇this */
+          var drawCanvas;
+          if (this.queue) {
+            drawCanvas = () => queueDraw.exec(() => qr[drawCanvasName]());
+            // drawCanvas = () => queueDraw.exec(() => new Promise((resolve, reject) => {
+            //   setTimeout(() => {
+            //     qr[drawCanvasName]().then(resolve).catch(reject);
+            //   }, 1000);
+            // }));
+          } else {
+            drawCanvas = () => qr[drawCanvasName]();
+          }
+          /* 璋冪敤缁樺埗鏂规硶灏嗕簩缁寸爜鍥炬缁樺埗鍒癱anvas涓� */
+          drawCanvas()
+            .then(() => {
+              if (this.drawDelegate) {
+                /* 楂橀閲嶇粯绾犳 */
+                let delegate = this.drawDelegate;
+                this.drawDelegate = undefined;
+                delegate();
+              } else {
+                this.drawing = false;
+                callback.success();
+              }
+            })
+            .catch(err => {
+              console.log(err);
+              if (this.drawDelegate) {
+                /* 楂橀閲嶇粯绾犳 */
+                let delegate = this.drawDelegate;
+                this.drawDelegate = undefined;
+                delegate();
+              } else {
+                this.drawing = false;
+                this.isError = true;
+                callback.fail(err);
+              }
+            })
+            .finally(() => {
+              callback.complete();
+            });
+        }, 300);
+      },
+      /**
+       * 鐢熸垚浜岀淮鐮�
+       */
+      make(callback = {}) {
+        this.makeExecuted = true;
+        this.makeing = true;
+        this.isError = false;
+
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        this.resetCanvas(() => {
+          clearTimeout(this.makeDelegate);
+          this.makeDelegate = setTimeout(() => {
+            this.draw({
+              success: () => {
+                setTimeout(() => {
+                  callback.success();
+                  this.complete(true);
+                }, 300);
+              },
+              fail: err => {
+                callback.fail(err);
+                this.error = err;
+                this.complete(false, err.errMsg);
+              },
+              complete: () => {
+                callback.complete();
+                this.makeing = false;
+              }
+            });
+          }, 300);
+        });
+      },
+      /**
+       * 閲嶆柊鐢熸垚
+       */
+      remake(callback) {
+        this.$emit('change');
+        this.make(callback);
+      },
+      /**
+       * 鐢熸垚瀹屾垚
+       */
+      complete(success = true, errMsg = '') {
+        if (success) {
+          this.$emit('complete', {
+            success
+          });
+        } else {
+          this.$emit('complete', {
+            success,
+            errMsg
+          });
+        }
+      },
+      /**
+       * 瀵煎嚭涓存椂璺緞
+       */
+      toTempFilePath(callback = {}) {
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        if (!this.makeExecuted) {
+          console.error('[uQRCode]: make() 鏂规硶浠庢湭璋冪敤锛佽鍏堟垚鍔熻皟鐢� make() 鍚庡啀杩涜鎿嶄綔銆�');
+          var err = {
+            errMsg: '[uQRCode]: make() method has never been executed! please execute make() successfully before operating.'
+          };
+          callback.fail(err);
+          callback.complete(err);
+          return;
+        }
+
+        if (this.isError) {
+          callback.fail(this.error);
+          callback.complete(this.error);
+          return;
+        }
+
+        if (this.makeing) {
+          /* 濡傛灉杩樺湪鐢熸垚鐘舵�侊紝閭e綋鍓嶆搷浣滃皢鎵樼鍒板鎵橈紝鐩戝惉鐢熸垚瀹屾垚鍚庡啀閫氳繃濮旀墭澶嶈皟褰撳墠鏂规硶 */
+          this.toTempFilePathDelegate = () => {
+            this.toTempFilePath(callback);
+          };
+          return;
+        } else {
+          this.toTempFilePathDelegate = null;
+        }
+
+        // #ifndef APP-NVUE
+        if (this.canvasType === '2d') {
+          // #ifdef MP-WEIXIN
+          try {
+            let dataURL = null;
+            // #ifdef VUE3
+            dataURL = toRaw(this.canvas)
+              .toDataURL();
+            // #endif
+            // #ifndef VUE3
+            dataURL = this.canvas.toDataURL();
+            // #endif
+            callback.success({
+              tempFilePath: dataURL
+            });
+            callback.complete({
+              tempFilePath: dataURL
+            });
+          } catch (e) {
+            callback.fail(e);
+            callback.complete(e);
+          }
+          // #endif
+        } else {
+          uni.canvasToTempFilePath({
+              canvasId: this.canvasId,
+              fileType: this.fileType,
+              width: Number(this.templateOptions.canvasWidth),
+              height: Number(this.templateOptions.canvasHeight),
+              destWidth: Number(this.templateOptions.size),
+              destHeight: Number(this.templateOptions.size),
+              success: res => {
+                callback.success(res);
+              },
+              fail: err => {
+                callback.fail(err);
+              },
+              complete: () => {
+                callback.complete();
+              }
+            },
+            this
+          );
+        }
+        // #endif
+        // #ifdef APP-NVUE
+        const dpr = uni.getSystemInfoSync().pixelRatio;
+        this.canvasContext.toTempFilePath(
+          0,
+          0,
+          this.templateOptions.canvasWidth * dpr,
+          this.templateOptions.canvasHeight * dpr,
+          this.templateOptions.size * dpr,
+          this.templateOptions.size * dpr,
+          '',
+          1,
+          res => {
+            callback.success(res);
+            callback.complete(res);
+          }
+        );
+        // #endif
+      },
+      /**
+       * 淇濆瓨
+       */
+      save(callback = {}) {
+        if (typeof callback.success != 'function') {
+          callback.success = () => {};
+        }
+        if (typeof callback.fail != 'function') {
+          callback.fail = () => {};
+        }
+        if (typeof callback.complete != 'function') {
+          callback.complete = () => {};
+        }
+
+        this.toTempFilePath({
+          success: res => {
+            // #ifndef H5
+            if (this.canvasType === '2d') {
+              // #ifdef MP-WEIXIN
+              /* 闇�瑕佸皢 data:image/png;base64, 杩欐鍘婚櫎 writeFile 鎵嶈兘姝e父鎵撳紑鏂囦欢锛屽惁鍒欐槸鎹熷潖鏂囦欢锛屾棤娉曟墦寮� */
+              const reg = new RegExp('^data:image/png;base64,', 'g');
+              const dataURL = res.tempFilePath.replace(reg, '');
+              const fs = wx.getFileSystemManager();
+              const tempFilePath = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}${
+                Math.random()
+                  .toString()
+                  .split('.')[1]
+              }.png`;
+              fs.writeFile({
+                filePath: tempFilePath, // 瑕佸啓鍏ョ殑鏂囦欢璺緞 (鏈湴璺緞)
+                data: dataURL, // base64鍥剧墖
+                encoding: 'base64',
+                success: res1 => {
+                  uni.saveImageToPhotosAlbum({
+                    filePath: tempFilePath,
+                    success: res2 => {
+                      callback.success(res2);
+                    },
+                    fail: err2 => {
+                      callback.fail(err2);
+                    },
+                    complete: () => {
+                      callback.complete();
+                    }
+                  });
+                },
+                fail: err => {
+                  callback.fail(err);
+                },
+                complete: () => {
+                  callback.complete();
+                }
+              });
+              // #endif
+            } else {
+              uni.saveImageToPhotosAlbum({
+                filePath: res.tempFilePath,
+                success: res1 => {
+                  callback.success(res1);
+                },
+                fail: err1 => {
+                  callback.fail(err1);
+                },
+                complete: () => {
+                  callback.complete();
+                }
+              });
+            }
+            // #endif
+
+            // #ifdef H5
+            /* 鍙互鍦ㄧ數鑴戞祻瑙堝櫒涓嬭浇锛岀Щ鍔ㄧiOS涓嶈锛屽畨鍗撳井淇℃祻瑙堝櫒涓嶈锛屽畨鍗撳閮ㄦ祻瑙堝櫒鍙互 */
+            this.isH5Save = true;
+            this.tempFilePath = res.tempFilePath;
+            if (this.h5SaveIsDownload) {
+              const aEle = document.createElement('a');
+              aEle.download = this.h5DownloadName; // 璁剧疆涓嬭浇鐨勬枃浠跺悕锛岄粯璁ゆ槸'涓嬭浇'
+              aEle.href = res.tempFilePath;
+              document.body.appendChild(aEle);
+              aEle.click();
+              aEle.remove(); // 涓嬭浇涔嬪悗鎶婂垱寤虹殑鍏冪礌鍒犻櫎
+            }
+            callback.success({
+              errMsg: 'ok'
+            });
+            callback.complete({
+              errMsg: 'ok'
+            });
+            // #endif
+          },
+          fail: err => {
+            callback.fail(err);
+            callback.complete(err);
+          }
+        });
+      },
+      /**
+       * 娉ㄥ唽click浜嬩欢
+       */
+      onClick(e) {
+        this.$emit('click', e);
+      },
+      /**
+       * 鑾峰彇瀹炰緥
+       */
+      getInstance() {
+        return instance;
+      },
+      /**
+       * 娉ㄥ唽鎵╁睍锛岀粍浠朵粎鏀寔娉ㄥ唽type涓簊tyle鐨刣rawCanvas鎵╁睍
+       * @param {Object} plugin
+       */
+      registerStyle(plugin) {
+        if (plugin.Type != 'style') {
+          console.warn('[uQRCode]: registerStyle 浠呮敮鎸佹敞鍐� style 绫诲瀷鐨勬墿灞曪紒');
+          return {
+            errMsg: 'registerStyle 浠呮敮鎸佹敞鍐� style 绫诲瀷鐨勬墿灞曪紒'
+          };
+        }
+        if (typeof plugin === 'function') {
+          this.plugins.push({
+            plugin,
+            name: plugin.Name,
+            drawCanvas: plugin.DrawCanvas
+          });
+        }
+      },
+      getLoadImage(loadImage) {
+        var that = this;
+        if (typeof loadImage == 'function') {
+          return function(src) {
+            /* 鍒ゆ柇鏄惁鏄槦鍒楀姞杞藉浘鐗囩殑 */
+            if (that.isQueueLoadImage) {
+              /* 瑙e喅iOS APP||NVUE鍚屾椂缁樺埗澶氫釜浜岀淮鐮佸鑷村浘鐗囦涪澶遍渶浣跨敤闃熷垪 */
+              return queueLoadImage.exec(() => {
+                return new Promise((resolve, reject) => {
+                  setTimeout(() => {
+                    const cache = cacheImageList.find(x => x.src == src);
+                    if (cache) {
+                      resolve(cache.img);
+                    } else {
+                      loadImage(src)
+                        .then(img => {
+                          cacheImageList.push({
+                            src,
+                            img
+                          });
+                          resolve(img);
+                        })
+                        .catch(err => {
+                          reject(err);
+                        });
+                    }
+                  }, 10);
+                });
+              });
+            } else {
+              return loadImage(src);
+            }
+          };
+        } else {
+          return function(src) {
+            return Promise.resolve(src);
+          };
+        }
+      }
+    }
+  };
+
+  /**
+   * 瀵硅薄灞炴�ф繁搴︽浛鎹�
+   * @param {Object} o 鍘熷瀵硅薄/榛樿瀵硅薄/琚浛鎹㈢殑瀵硅薄
+   * @param {Object} r 浠庤繖涓璞¢噷鍙栧�兼浛鎹㈠埌o瀵硅薄閲�
+   * @return {Object} 鏇挎崲鍚庣殑鏂板璞�
+   */
+  function deepReplace(o = {}, r = {}, c = false) {
+    let obj;
+    if (c) {
+      // 浠庢簮鏇挎崲
+      obj = o;
+    } else {
+      // 涓嶆浛鎹㈡簮锛宑opy涓�浠藉浠芥潵鏇挎崲
+      obj = {
+        ...o
+      };
+    }
+    for (let k in r) {
+      var vr = r[k];
+      if (vr != undefined) {
+        if (vr.constructor == Object) {
+          obj[k] = this.deepReplace(obj[k], vr);
+        } else if (vr.constructor == String && !vr) {
+          obj[k] = obj[k];
+        } else {
+          obj[k] = vr;
+        }
+      }
+    }
+    return obj;
+  }
+</script>
+
+<style scoped>
+  .uqrcode {
+    position: relative;
+  }
+
+  .uqrcode-hide {
+    position: fixed;
+    left: 7500rpx;
+  }
+
+  .uqrcode-canvas {
+    transform-origin: top left;
+  }
+
+  .uqrcode-makeing {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 10;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    align-items: center;
+  }
+
+  .uqrcode-makeing-image {
+    /* #ifndef APP-NVUE */
+    display: block;
+    max-width: 120px;
+    max-height: 120px;
+    /* #endif */
+  }
+
+  .uqrcode-error {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    /* #ifndef APP-NVUE */
+    display: flex;
+    /* #endif */
+    justify-content: center;
+    align-items: center;
+  }
+
+  .uqrcode-error-message {
+    font-size: 12px;
+    color: #939291;
+  }
+
+  /* #ifdef H5 */
+  .uqrcode-h5-save {
+    position: fixed;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 100;
+    background-color: rgba(0, 0, 0, 0.68);
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .uqrcode-h5-save-image {
+    width: 512rpx;
+    height: 512rpx;
+    padding: 32rpx;
+  }
+
+  .uqrcode-h5-save-text {
+    margin-top: 20rpx;
+    font-size: 32rpx;
+    font-weight: 700;
+    color: #ffffff;
+  }
+
+  .uqrcode-h5-save-close {
+    position: relative;
+    margin-top: 72rpx;
+    width: 60rpx;
+    height: 60rpx;
+    border: 2rpx solid #ffffff;
+    border-radius: 60rpx;
+    padding: 10rpx;
+  }
+
+  .uqrcode-h5-save-close-before {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%) rotate(45deg);
+    width: 40rpx;
+    height: 4rpx;
+    background: #ffffff;
+  }
+
+  .uqrcode-h5-save-close-after {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%) rotate(-45deg);
+    width: 40rpx;
+    height: 4rpx;
+    background: #ffffff;
+  }
+
+  /* #endif */
+</style>
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/bridge/bridge-weex.js
new file mode 100644
index 0000000..27086ec
--- /dev/null
+++ b/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;
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js
new file mode 100644
index 0000000..3e7f03a
--- /dev/null
+++ b/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;
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStylePattern.js
new file mode 100644
index 0000000..6e4f646
--- /dev/null
+++ b/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;
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js
new file mode 100644
index 0000000..7790596
--- /dev/null
+++ b/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;
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-2d/RenderingContext.js
new file mode 100644
index 0000000..e6b8f48
--- /dev/null
+++ b/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);
+				}
+			});
+	}
+}
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ActiveInfo.js
new file mode 100644
index 0000000..b495129
--- /dev/null
+++ b/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;
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Buffer.js
new file mode 100644
index 0000000..4800f67
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Framebuffer.js
new file mode 100644
index 0000000..28b46d3
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLenum.js
new file mode 100644
index 0000000..ac5544d
--- /dev/null
+++ b/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
+};
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLmethod.js
new file mode 100644
index 0000000..f2659be
--- /dev/null
+++ b/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;
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/GLtype.js
new file mode 100644
index 0000000..695abcb
--- /dev/null
+++ b/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;
+
+
+
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Program.js
new file mode 100644
index 0000000..6f5691c
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Renderbuffer.js
new file mode 100644
index 0000000..d3182ae
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/RenderingContext.js
new file mode 100644
index 0000000..5f9608f
--- /dev/null
+++ b/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
+        )
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Shader.js
new file mode 100644
index 0000000..a763886
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js
new file mode 100644
index 0000000..208d6c1
--- /dev/null
+++ b/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;
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/Texture.js
new file mode 100644
index 0000000..de4d806
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/UniformLocation.js
new file mode 100644
index 0000000..f5e99dc
--- /dev/null
+++ b/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);
+    }
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js
new file mode 100644
index 0000000..88716be
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/context-webgl/classUtils.js
@@ -0,0 +1,3 @@
+export function getTransferedObjectUUID(name, id) {
+    return `${name.toLowerCase()}-${id}`;
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/canvas.js
new file mode 100644
index 0000000..a8d9bb9
--- /dev/null
+++ b/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);
+    }
+
+
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/image.js
new file mode 100644
index 0000000..9499a51
--- /dev/null
+++ b/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;
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/env/tool.js
new file mode 100644
index 0000000..d3fb398
--- /dev/null
+++ b/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;
+}
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js b/uni_modules/Sansnn-uQRCode/js_sdk/gcanvas/index.js
new file mode 100644
index 0000000..a34ad58
--- /dev/null
+++ b/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;
+};
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js b/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js
new file mode 100644
index 0000000..2290ab3
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js
@@ -0,0 +1,34 @@
+//---------------------------------------------------------------------
+// uQRCode浜岀淮鐮佺敓鎴愭彃浠� v4.0.6
+// 
+// uQRCode鏄竴娆惧熀浜嶫avascript鐜寮�鍙戠殑浜岀淮鐮佺敓鎴愭彃浠讹紝閫傜敤鎵�鏈塉avascript杩愯鐜鐨勫墠绔簲鐢ㄥ拰Node.js銆�
+// 
+// Copyright (c) Sansnn uQRCode All rights reserved.
+// 
+// Licensed under the Apache License, Version 2.0.
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// github鍦板潃锛�
+//   https://github.com/Sansnn/uQRCode
+// 
+// npm鍦板潃锛�
+//   https://www.npmjs.com/package/uqrcodejs
+// 
+// uni-app鎻掍欢甯傚満鍦板潃锛�
+//   https://ext.dcloud.net.cn/plugin?id=1287
+// 
+// 澶嶅埗浣跨敤璇蜂繚鐣欐湰娈垫敞閲婏紝鎰熻阿鏀寔寮�婧愶紒
+// 
+//---------------------------------------------------------------------
+
+//---------------------------------------------------------------------
+// 褰撳墠鏂囦欢鏍煎紡涓� es锛屽皢 bundle 淇濈暀涓� ES 妯″潡鏂囦欢锛岄�傜敤浜庡叾浠栨墦鍖呭伐鍏蜂互鍙婃敮鎸� <script type=module> 鏍囩鐨勬祻瑙堝櫒锛堝埆鍚�: esm锛宮odule锛�
+// 濡傞渶鍦ㄥ叾浠栫幆澧冧娇鐢紝璇疯幏鍙栫幆澧冨搴旂殑鏍煎紡鏂囦欢
+// 鏍煎紡璇存槑锛�
+// amd - 寮傛妯″潡瀹氫箟锛岄�傜敤浜� RequireJS 绛夋ā鍧楀姞杞藉櫒
+// cjs - CommonJS锛岄�傜敤浜� Node 鐜鍜屽叾浠栨墦鍖呭伐鍏凤紙鍒悕锛歝ommonjs锛�
+// es - 灏� bundle 淇濈暀涓� ES 妯″潡鏂囦欢锛岄�傜敤浜庡叾浠栨墦鍖呭伐鍏蜂互鍙婃敮鎸� <script type=module> 鏍囩鐨勬祻瑙堝櫒锛堝埆鍚�: esm锛宮odule锛�
+// umd - 閫氱敤妯″潡瀹氫箟锛岀敓鎴愮殑鍖呭悓鏃舵敮鎸� amd銆乧js 鍜� iife 涓夌鏍煎紡
+//---------------------------------------------------------------------
+
+function o(o){this.mode=r.MODE_8BIT_BYTE,this.data=o;}function e(o,e){this.typeNumber=o,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array;}o.prototype={getLength:function(o){return this.data.length},write:function(o){for(var e=0;e<this.data.length;e++)o.put(this.data.charCodeAt(e),8);}},e.prototype={addData:function(e){var r=new o(e);this.dataList.push(r),this.dataCache=null;},isDark:function(o,e){if(o<0||this.moduleCount<=o||e<0||this.moduleCount<=e)throw new Error(o+","+e);return this.modules[o][e]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var o=1;for(o=1;o<40;o++){for(var e=v.getRSBlocks(o,this.errorCorrectLevel),r=new p,t=0,i=0;i<e.length;i++)t+=e[i].dataCount;for(i=0;i<this.dataList.length;i++){var n=this.dataList[i];r.put(n.mode,4),r.put(n.getLength(),h.getLengthInBits(n.mode,o)),n.write(r);}if(r.getLengthInBits()<=8*t)break}this.typeNumber=o;}this.makeImpl(!1,this.getBestMaskPattern());},makeImpl:function(o,r){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var t=0;t<this.moduleCount;t++){this.modules[t]=new Array(this.moduleCount);for(var i=0;i<this.moduleCount;i++)this.modules[t][i]=null;}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(o,r),this.typeNumber>=7&&this.setupTypeNumber(o),null==this.dataCache&&(this.dataCache=e.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,r);},setupPositionProbePattern:function(o,e){for(var r=-1;r<=7;r++)if(!(o+r<=-1||this.moduleCount<=o+r))for(var t=-1;t<=7;t++)e+t<=-1||this.moduleCount<=e+t||(this.modules[o+r][e+t]=0<=r&&r<=6&&(0==t||6==t)||0<=t&&t<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=t&&t<=4);},getBestMaskPattern:function(){for(var o=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var t=h.getLostPoint(this);(0==r||o>t)&&(o=t,e=r);}return e},createMovieClip:function(o,e,r){var t=o.createEmptyMovieClip(e,r);this.make();for(var i=0;i<this.modules.length;i++)for(var n=1*i,a=0;a<this.modules[i].length;a++){var d=1*a;this.modules[i][a]&&(t.beginFill(0,100),t.moveTo(d,n),t.lineTo(d+1,n),t.lineTo(d+1,n+1),t.lineTo(d,n+1),t.endFill());}return t},setupTimingPattern:function(){for(var o=8;o<this.moduleCount-8;o++)null==this.modules[o][6]&&(this.modules[o][6]=o%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 o=h.getPatternPosition(this.typeNumber),e=0;e<o.length;e++)for(var r=0;r<o.length;r++){var t=o[e],i=o[r];if(null==this.modules[t][i])for(var n=-2;n<=2;n++)for(var a=-2;a<=2;a++)this.modules[t+n][i+a]=-2==n||2==n||-2==a||2==a||0==n&&0==a;}},setupTypeNumber:function(o){for(var e=h.getBCHTypeNumber(this.typeNumber),r=0;r<18;r++){var t=!o&&1==(e>>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=t;}for(r=0;r<18;r++){t=!o&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=t;}},setupTypeInfo:function(o,e){for(var r=this.errorCorrectLevel<<3|e,t=h.getBCHTypeInfo(r),i=0;i<15;i++){var n=!o&&1==(t>>i&1);i<6?this.modules[i][8]=n:i<8?this.modules[i+1][8]=n:this.modules[this.moduleCount-15+i][8]=n;}for(i=0;i<15;i++){n=!o&&1==(t>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=n:i<9?this.modules[8][15-i-1+1]=n:this.modules[8][15-i-1]=n;}this.modules[this.moduleCount-8][8]=!o;},mapData:function(o,e){for(var r=-1,t=this.moduleCount-1,i=7,n=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var d=0;d<2;d++)if(null==this.modules[t][a-d]){var u=!1;n<o.length&&(u=1==(o[n]>>>i&1)),h.getMask(e,t,a-d)&&(u=!u),this.modules[t][a-d]=u,-1==--i&&(n++,i=7);}if((t+=r)<0||this.moduleCount<=t){t-=r,r=-r;break}}}},e.PAD0=236,e.PAD1=17,e.createData=function(o,r,t){for(var i=v.getRSBlocks(o,r),n=new p,a=0;a<t.length;a++){var d=t[a];n.put(d.mode,4),n.put(d.getLength(),h.getLengthInBits(d.mode,o)),d.write(n);}var u=0;for(a=0;a<i.length;a++)u+=i[a].dataCount;if(n.getLengthInBits()>8*u)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*u+")");for(n.getLengthInBits()+4<=8*u&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*u||(n.put(e.PAD0,8),n.getLengthInBits()>=8*u));)n.put(e.PAD1,8);return e.createBytes(n,i)},e.createBytes=function(o,e){for(var r=0,t=0,i=0,n=new Array(e.length),a=new Array(e.length),d=0;d<e.length;d++){var u=e[d].dataCount,s=e[d].totalCount-u;t=Math.max(t,u),i=Math.max(i,s),n[d]=new Array(u);for(var g=0;g<n[d].length;g++)n[d][g]=255&o.buffer[g+r];r+=u;var l=h.getErrorCorrectPolynomial(s),c=new f(n[d],l.getLength()-1).mod(l);a[d]=new Array(l.getLength()-1);for(g=0;g<a[d].length;g++){var m=g+c.getLength()-a[d].length;a[d][g]=m>=0?c.get(m):0;}}var v=0;for(g=0;g<e.length;g++)v+=e[g].totalCount;var p=new Array(v),C=0;for(g=0;g<t;g++)for(d=0;d<e.length;d++)g<n[d].length&&(p[C++]=n[d][g]);for(g=0;g<i;g++)for(d=0;d<e.length;d++)g<a[d].length&&(p[C++]=a[d][g]);return p};for(var r={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},t={L:1,M:0,Q:3,H:2},i=0,n=1,a=2,d=3,u=4,s=5,g=6,l=7,h={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(o){for(var e=o<<10;h.getBCHDigit(e)-h.getBCHDigit(h.G15)>=0;)e^=h.G15<<h.getBCHDigit(e)-h.getBCHDigit(h.G15);return (o<<10|e)^h.G15_MASK},getBCHTypeNumber:function(o){for(var e=o<<12;h.getBCHDigit(e)-h.getBCHDigit(h.G18)>=0;)e^=h.G18<<h.getBCHDigit(e)-h.getBCHDigit(h.G18);return o<<12|e},getBCHDigit:function(o){for(var e=0;0!=o;)e++,o>>>=1;return e},getPatternPosition:function(o){return h.PATTERN_POSITION_TABLE[o-1]},getMask:function(o,e,r){switch(o){case i:return (e+r)%2==0;case n:return e%2==0;case a:return r%3==0;case d:return (e+r)%3==0;case u:return (Math.floor(e/2)+Math.floor(r/3))%2==0;case s:return e*r%2+e*r%3==0;case g:return (e*r%2+e*r%3)%2==0;case l:return (e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+o)}},getErrorCorrectPolynomial:function(o){for(var e=new f([1],0),r=0;r<o;r++)e=e.multiply(new f([1,c.gexp(r)],0));return e},getLengthInBits:function(o,e){if(1<=e&&e<10)switch(o){case r.MODE_NUMBER:return 10;case r.MODE_ALPHA_NUM:return 9;case r.MODE_8BIT_BYTE:case r.MODE_KANJI:return 8;default:throw new Error("mode:"+o)}else if(e<27)switch(o){case r.MODE_NUMBER:return 12;case r.MODE_ALPHA_NUM:return 11;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 10;default:throw new Error("mode:"+o)}else {if(!(e<41))throw new Error("type:"+e);switch(o){case r.MODE_NUMBER:return 14;case r.MODE_ALPHA_NUM:return 13;case r.MODE_8BIT_BYTE:return 16;case r.MODE_KANJI:return 12;default:throw new Error("mode:"+o)}}},getLostPoint:function(o){for(var e=o.getModuleCount(),r=0,t=0;t<e;t++)for(var i=0;i<e;i++){for(var n=0,a=o.isDark(t,i),d=-1;d<=1;d++)if(!(t+d<0||e<=t+d))for(var u=-1;u<=1;u++)i+u<0||e<=i+u||0==d&&0==u||a==o.isDark(t+d,i+u)&&n++;n>5&&(r+=3+n-5);}for(t=0;t<e-1;t++)for(i=0;i<e-1;i++){var s=0;o.isDark(t,i)&&s++,o.isDark(t+1,i)&&s++,o.isDark(t,i+1)&&s++,o.isDark(t+1,i+1)&&s++,0!=s&&4!=s||(r+=3);}for(t=0;t<e;t++)for(i=0;i<e-6;i++)o.isDark(t,i)&&!o.isDark(t,i+1)&&o.isDark(t,i+2)&&o.isDark(t,i+3)&&o.isDark(t,i+4)&&!o.isDark(t,i+5)&&o.isDark(t,i+6)&&(r+=40);for(i=0;i<e;i++)for(t=0;t<e-6;t++)o.isDark(t,i)&&!o.isDark(t+1,i)&&o.isDark(t+2,i)&&o.isDark(t+3,i)&&o.isDark(t+4,i)&&!o.isDark(t+5,i)&&o.isDark(t+6,i)&&(r+=40);var g=0;for(i=0;i<e;i++)for(t=0;t<e;t++)o.isDark(t,i)&&g++;return r+=10*(Math.abs(100*g/e/e-50)/5)}},c={glog:function(o){if(o<1)throw new Error("glog("+o+")");return c.LOG_TABLE[o]},gexp:function(o){for(;o<0;)o+=255;for(;o>=256;)o-=255;return c.EXP_TABLE[o]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},m=0;m<8;m++)c.EXP_TABLE[m]=1<<m;for(m=8;m<256;m++)c.EXP_TABLE[m]=c.EXP_TABLE[m-4]^c.EXP_TABLE[m-5]^c.EXP_TABLE[m-6]^c.EXP_TABLE[m-8];for(m=0;m<255;m++)c.LOG_TABLE[c.EXP_TABLE[m]]=m;function f(o,e){if(null==o.length)throw new Error(o.length+"/"+e);for(var r=0;r<o.length&&0==o[r];)r++;this.num=new Array(o.length-r+e);for(var t=0;t<o.length-r;t++)this.num[t]=o[t+r];}function v(o,e){this.totalCount=o,this.dataCount=e;}function p(){this.buffer=new Array,this.length=0;}function C(o){return o.setFillStyle=o.setFillStyle||function(e){o.fillStyle=e;},o.setFontSize=o.setFontSize||function(e){o.font=`${e}px`;},o.setTextAlign=o.setTextAlign||function(e){o.textAlign=e;},o.setTextBaseline=o.setTextBaseline||function(e){o.textBaseline=e;},o.setGlobalAlpha=o.setGlobalAlpha||function(e){o.globalAlpha=e;},o.setStrokeStyle=o.setStrokeStyle||function(e){o.strokeStyle=e;},o.setShadow=o.setShadow||function(e,r,t,i){o.shadowOffsetX=e,o.shadowOffsetY=r,o.shadowBlur=t,o.shadowColor=i;},o.draw=o.draw||function(o,e){e&&e();},o.clearRect=o.clearRect||function(e,r,t,i){o.draw(!1);},o}function b(o,e){var r=this.data="",t=this.size=200;this.useDynamicSize=!1,this.dynamicSize=t;var i=this.typeNumber=-1;this.errorCorrectLevel=b.errorCorrectLevel.H;var n=this.margin=0;this.areaColor="#FFFFFF",this.backgroundColor="rgba(255,255,255,0)",this.backgroundImageSrc=void 0;var a=this.backgroundImageWidth=void 0,d=this.backgroundImageHeight=void 0,u=this.backgroundImageX=void 0,s=this.backgroundImageY=void 0;this.backgroundImageAlpha=1,this.backgroundImageBorderRadius=0;var g=this.backgroundPadding=0;this.foregroundColor="#000000",this.foregroundImageSrc=void 0;var l=this.foregroundImageWidth=void 0,h=this.foregroundImageHeight=void 0,c=this.foregroundImageX=void 0,m=this.foregroundImageY=void 0,f=this.foregroundImagePadding=0;this.foregroundImageBackgroundColor="#FFFFFF";var v=this.foregroundImageBorderRadius=0,p=this.foregroundImageShadowOffsetX=0,k=this.foregroundImageShadowOffsetY=0,y=this.foregroundImageShadowBlur=0;this.foregroundImageShadowColor="#808080";var w=this.foregroundPadding=0,I=this.positionProbeBackgroundColor=void 0,B=this.positionProbeForegroundColor=void 0,S=this.separatorColor=void 0,P=this.positionAdjustBackgroundColor=void 0,L=this.positionAdjustForegroundColor=void 0,D=this.timingBackgroundColor=void 0,A=this.timingForegroundColor=void 0,E=this.typeNumberBackgroundColor=void 0,T=this.typeNumberForegroundColor=void 0,N=this.darkBlockColor=void 0;this.base=void 0,this.modules=[],this.moduleCount=0,this.drawModules=[];var M=this.canvasContext=void 0;this.loadImage,this.drawReserve=!1,this.isMaked=!1,Object.defineProperties(this,{data:{get(){if(""===r||void 0===r)throw console.error("[uQRCode]: data must be set!"),new b.Error("data must be set!");return r},set(o){r=String(o);}},size:{get:()=>t,set(o){t=Number(o);}},typeNumber:{get:()=>i,set(o){i=Number(o);}},margin:{get:()=>n,set(o){n=Number(o);}},backgroundImageWidth:{get(){return void 0===a?this.dynamicSize:this.useDynamicSize?this.dynamicSize/this.size*a:a},set(o){a=Number(o);}},backgroundImageHeight:{get(){return void 0===d?this.dynamicSize:this.useDynamicSize?this.dynamicSize/this.size*d:d},set(o){d=Number(o);}},backgroundImageX:{get(){return void 0===u?0:this.useDynamicSize?this.dynamicSize/this.size*u:u},set(o){u=Number(o);}},backgroundImageY:{get(){return void 0===s?0:this.useDynamicSize?this.dynamicSize/this.size*s:s},set(o){s=Number(o);}},backgroundPadding:{get:()=>g,set(o){g=o>1?1:o<0?0:o;}},foregroundImageWidth:{get(){return void 0===l?(this.dynamicSize-2*this.margin)/4:this.useDynamicSize?this.dynamicSize/this.size*l:l},set(o){l=Number(o);}},foregroundImageHeight:{get(){return void 0===h?(this.dynamicSize-2*this.margin)/4:this.useDynamicSize?this.dynamicSize/this.size*h:h},set(o){h=Number(o);}},foregroundImageX:{get(){return void 0===c?this.dynamicSize/2-this.foregroundImageWidth/2:this.useDynamicSize?this.dynamicSize/this.size*c:c},set(o){c=Number(o);}},foregroundImageY:{get(){return void 0===m?this.dynamicSize/2-this.foregroundImageHeight/2:this.useDynamicSize?this.dynamicSize/this.size*m:m},set(o){m=Number(o);}},foregroundImagePadding:{get(){return this.useDynamicSize?this.dynamicSize/this.size*f:f},set(o){f=Number(o);}},foregroundImageBorderRadius:{get(){return this.useDynamicSize?this.dynamicSize/this.size*v:v},set(o){v=Number(o);}},foregroundImageShadowOffsetX:{get(){return this.useDynamicSize?this.dynamicSize/this.size*p:p},set(o){p=Number(o);}},foregroundImageShadowOffsetY:{get(){return this.useDynamicSize?this.dynamicSize/this.size*k:k},set(o){k=Number(o);}},foregroundImageShadowBlur:{get(){return this.useDynamicSize?this.dynamicSize/this.size*y:y},set(o){y=Number(o);}},foregroundPadding:{get:()=>w,set(o){w=o>1?1:o<0?0:o;}},positionProbeBackgroundColor:{get(){return I||this.backgroundColor},set(o){I=o;}},positionProbeForegroundColor:{get(){return B||this.foregroundColor},set(o){B=o;}},separatorColor:{get(){return S||this.backgroundColor},set(o){S=o;}},positionAdjustBackgroundColor:{get(){return P||this.backgroundColor},set(o){P=o;}},positionAdjustForegroundColor:{get(){return L||this.foregroundColor},set(o){L=o;}},timingBackgroundColor:{get(){return D||this.backgroundColor},set(o){D=o;}},timingForegroundColor:{get(){return A||this.foregroundColor},set(o){A=o;}},typeNumberBackgroundColor:{get(){return E||this.backgroundColor},set(o){E=o;}},typeNumberForegroundColor:{get(){return T||this.foregroundColor},set(o){T=o;}},darkBlockColor:{get(){return N||this.foregroundColor},set(o){N=o;}},canvasContext:{get(){if(void 0===M)throw console.error("[uQRCode]: use drawCanvas, you need to set the canvasContext!"),new b.Error("use drawCanvas, you need to set the canvasContext!");return M},set(o){M=C(o);}}}),b.plugins.forEach((o=>o(b,this,!1))),o&&this.setOptions(o),e&&(this.canvasContext=C(e));}f.prototype={get:function(o){return this.num[o]},getLength:function(){return this.num.length},multiply:function(o){for(var e=new Array(this.getLength()+o.getLength()-1),r=0;r<this.getLength();r++)for(var t=0;t<o.getLength();t++)e[r+t]^=c.gexp(c.glog(this.get(r))+c.glog(o.get(t)));return new f(e,0)},mod:function(o){if(this.getLength()-o.getLength()<0)return this;for(var e=c.glog(this.get(0))-c.glog(o.get(0)),r=new Array(this.getLength()),t=0;t<this.getLength();t++)r[t]=this.get(t);for(t=0;t<o.getLength();t++)r[t]^=c.gexp(c.glog(o.get(t))+e);return new f(r,0).mod(o)}},v.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]],v.getRSBlocks=function(o,e){var r=v.getRsBlockTable(o,e);if(null==r)throw new Error("bad rs block @ typeNumber:"+o+"/errorCorrectLevel:"+e);for(var t=r.length/3,i=new Array,n=0;n<t;n++)for(var a=r[3*n+0],d=r[3*n+1],u=r[3*n+2],s=0;s<a;s++)i.push(new v(d,u));return i},v.getRsBlockTable=function(o,e){switch(e){case t.L:return v.RS_BLOCK_TABLE[4*(o-1)+0];case t.M:return v.RS_BLOCK_TABLE[4*(o-1)+1];case t.Q:return v.RS_BLOCK_TABLE[4*(o-1)+2];case t.H:return v.RS_BLOCK_TABLE[4*(o-1)+3];default:return}},p.prototype={get:function(o){var e=Math.floor(o/8);return 1==(this.buffer[e]>>>7-o%8&1)},put:function(o,e){for(var r=0;r<e;r++)this.putBit(1==(o>>>e-r-1&1));},getLengthInBits:function(){return this.length},putBit:function(o){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),o&&(this.buffer[e]|=128>>>this.length%8),this.length++;}},e.errorCorrectLevel=t,b.errorCorrectLevel=e.errorCorrectLevel,b.Error=function(o){this.errMsg="[uQRCode]: "+o;},b.plugins=[],b.use=function(o){"function"==typeof o&&b.plugins.push(o);},b.prototype.loadImage=function(o){return Promise.resolve(o)},b.prototype.setOptions=function(o){var e,r,t,i,n,a,d,u,s,g,l,h,c,m,f,v,p,C,b,k,y,w,I,B,S,P,L,D,A,E,T,N,M,z,R,_,O,F,x,H,X,Y,j,W,G,K,Q,U,$,J,q,V,Z,oo,eo,ro;o&&(Object.keys(o).forEach((e=>{this[e]=o[e];})),function(o={},e={},r=!1){let t;t=r?o:{...o};for(let o in e){var i=e[o];null!=i&&(i.constructor==Object?t[o]=this.deepReplace(t[o],i):i.constructor!=String||i?t[o]=i:t[o]=t[o]);}}(this,{data:o.data||o.text,size:o.size,useDynamicSize:o.useDynamicSize,typeNumber:o.typeNumber,errorCorrectLevel:o.errorCorrectLevel,margin:o.margin,areaColor:o.areaColor,backgroundColor:o.backgroundColor||(null===(e=o.background)||void 0===e?void 0:e.color),backgroundImageSrc:o.backgroundImageSrc||(null===(r=o.background)||void 0===r||null===(t=r.image)||void 0===t?void 0:t.src),backgroundImageWidth:o.backgroundImageWidth||(null===(i=o.background)||void 0===i||null===(n=i.image)||void 0===n?void 0:n.width),backgroundImageHeight:o.backgroundImageHeight||(null===(a=o.background)||void 0===a||null===(d=a.image)||void 0===d?void 0:d.height),backgroundImageX:o.backgroundImageX||(null===(u=o.background)||void 0===u||null===(s=u.image)||void 0===s?void 0:s.x),backgroundImageY:o.backgroundImageY||(null===(g=o.background)||void 0===g||null===(l=g.image)||void 0===l?void 0:l.y),backgroundImageAlpha:o.backgroundImageAlpha||(null===(h=o.background)||void 0===h||null===(c=h.image)||void 0===c?void 0:c.alpha),backgroundImageBorderRadius:o.backgroundImageBorderRadius||(null===(m=o.background)||void 0===m||null===(f=m.image)||void 0===f?void 0:f.borderRadius),backgroundPadding:o.backgroundPadding,foregroundColor:o.foregroundColor||(null===(v=o.foreground)||void 0===v?void 0:v.color),foregroundImageSrc:o.foregroundImageSrc||(null===(p=o.foreground)||void 0===p||null===(C=p.image)||void 0===C?void 0:C.src),foregroundImageWidth:o.foregroundImageWidth||(null===(b=o.foreground)||void 0===b||null===(k=b.image)||void 0===k?void 0:k.width),foregroundImageHeight:o.foregroundImageHeight||(null===(y=o.foreground)||void 0===y||null===(w=y.image)||void 0===w?void 0:w.height),foregroundImageX:o.foregroundImageX||(null===(I=o.foreground)||void 0===I||null===(B=I.image)||void 0===B?void 0:B.x),foregroundImageY:o.foregroundImageY||(null===(S=o.foreground)||void 0===S||null===(P=S.image)||void 0===P?void 0:P.y),foregroundImagePadding:o.foregroundImagePadding||(null===(L=o.foreground)||void 0===L||null===(D=L.image)||void 0===D?void 0:D.padding),foregroundImageBackgroundColor:o.foregroundImageBackgroundColor||(null===(A=o.foreground)||void 0===A||null===(E=A.image)||void 0===E?void 0:E.backgroundColor),foregroundImageBorderRadius:o.foregroundImageBorderRadius||(null===(T=o.foreground)||void 0===T||null===(N=T.image)||void 0===N?void 0:N.borderRadius),foregroundImageShadowOffsetX:o.foregroundImageShadowOffsetX||(null===(M=o.foreground)||void 0===M||null===(z=M.image)||void 0===z?void 0:z.shadowOffsetX),foregroundImageShadowOffsetY:o.foregroundImageShadowOffsetY||(null===(R=o.foreground)||void 0===R||null===(_=R.image)||void 0===_?void 0:_.shadowOffsetY),foregroundImageShadowBlur:o.foregroundImageShadowBlur||(null===(O=o.foreground)||void 0===O||null===(F=O.image)||void 0===F?void 0:F.shadowBlur),foregroundImageShadowColor:o.foregroundImageShadowColor||(null===(x=o.foreground)||void 0===x||null===(H=x.image)||void 0===H?void 0:H.shadowColor),foregroundPadding:o.foregroundPadding,positionProbeBackgroundColor:o.positionProbeBackgroundColor||(null===(X=o.positionProbe)||void 0===X?void 0:X.backgroundColor)||(null===(Y=o.positionDetection)||void 0===Y?void 0:Y.backgroundColor),positionProbeForegroundColor:o.positionProbeForegroundColor||(null===(j=o.positionProbe)||void 0===j?void 0:j.foregroundColor)||(null===(W=o.positionDetection)||void 0===W?void 0:W.foregroundColor),separatorColor:o.separatorColor||(null===(G=o.separator)||void 0===G?void 0:G.color),positionAdjustBackgroundColor:o.positionAdjustBackgroundColor||(null===(K=o.positionAdjust)||void 0===K?void 0:K.backgroundColor)||(null===(Q=o.alignment)||void 0===Q?void 0:Q.backgroundColor),positionAdjustForegroundColor:o.positionAdjustForegroundColor||(null===(U=o.positionAdjust)||void 0===U?void 0:U.foregroundColor)||(null===($=o.alignment)||void 0===$?void 0:$.foregroundColor),timingBackgroundColor:o.timingBackgroundColor||(null===(J=o.timing)||void 0===J?void 0:J.backgroundColor),timingForegroundColor:o.timingForegroundColor||(null===(q=o.timing)||void 0===q?void 0:q.foregroundColor),typeNumberBackgroundColor:o.typeNumberBackgroundColor||(null===(V=o.typeNumber)||void 0===V?void 0:V.backgroundColor)||(null===(Z=o.versionInformation)||void 0===Z?void 0:Z.backgroundColor),typeNumberForegroundColor:o.typeNumberForegroundColor||(null===(oo=o.typeNumber)||void 0===oo?void 0:oo.foregroundColor)||(null===(eo=o.versionInformation)||void 0===eo?void 0:eo.foregroundColor),darkBlockColor:o.darkBlockColor||(null===(ro=o.darkBlock)||void 0===ro?void 0:ro.color)},!0));},b.prototype.make=function(){let{foregroundColor:o,backgroundColor:r,typeNumber:t,errorCorrectLevel:i,data:n,size:a,margin:d,useDynamicSize:u}=this;if(o===r)throw console.error("[uQRCode]: foregroundColor and backgroundColor cannot be the same!"),new b.Error("foregroundColor and backgroundColor cannot be the same!");var s=new e(t,i);s.addData(function(o){o=o.toString();for(var e,r="",t=0;t<o.length;t++)(e=o.charCodeAt(t))>=1&&e<=127?r+=o.charAt(t):e>2047?(r+=String.fromCharCode(224|e>>12&15),r+=String.fromCharCode(128|e>>6&63),r+=String.fromCharCode(128|e>>0&63)):(r+=String.fromCharCode(192|e>>6&31),r+=String.fromCharCode(128|e>>0&63));return r}(n)),s.make(),this.base=s,this.typeNumber=s.typeNumber,this.modules=s.modules,this.moduleCount=s.moduleCount,this.dynamicSize=u?Math.ceil((a-2*d)/s.moduleCount)*s.moduleCount+2*d:a,function(o){let{dynamicSize:e,margin:r,backgroundColor:t,backgroundPadding:i,foregroundColor:n,foregroundPadding:a,modules:d,moduleCount:u}=o,s=(e-2*r)/u,g=s,l=0;i>0&&(l=g*i/2,g-=2*l);let h=s,c=0;a>0&&(c=h*a/2,h-=2*c);for(var m=0;m<u;m++)for(var f=0;f<u;f++){var v=f*s+r,p=m*s+r;if(d[m][f]){var C=c,b=v+c,k=p+c,y=h,w=h;d[m][f]={type:["foreground"],color:n,isBlack:!0,isDrawn:!1,destX:v,destY:p,destWidth:s,destHeight:s,x:b,y:k,width:y,height:w,paddingTop:C,paddingRight:C,paddingBottom:C,paddingLeft:C};}else C=l,b=v+l,k=p+l,y=g,w=g,d[m][f]={type:["background"],color:t,isBlack:!1,isDrawn:!1,destX:v,destY:p,destWidth:s,destHeight:s,x:b,y:k,width:y,height:w,paddingTop:C,paddingRight:C,paddingBottom:C,paddingLeft:C};}}(this),function(o){let{modules:e,moduleCount:r,positionProbeBackgroundColor:t,positionProbeForegroundColor:i}=o,n=r-7;[[0,0,1],[1,0,1],[2,0,1],[3,0,1],[4,0,1],[5,0,1],[6,0,1],[0,1,1],[1,1,0],[2,1,0],[3,1,0],[4,1,0],[5,1,0],[6,1,1],[0,2,1],[1,2,0],[2,2,1],[3,2,1],[4,2,1],[5,2,0],[6,2,1],[0,3,1],[1,3,0],[2,3,1],[3,3,1],[4,3,1],[5,3,0],[6,3,1],[0,4,1],[1,4,0],[2,4,1],[3,4,1],[4,4,1],[5,4,0],[6,4,1],[0,5,1],[1,5,0],[2,5,0],[3,5,0],[4,5,0],[5,5,0],[6,5,1],[0,6,1],[1,6,1],[2,6,1],[3,6,1],[4,6,1],[5,6,1],[6,6,1]].forEach((o=>{var r=e[o[0]][o[1]],a=e[o[0]+n][o[1]],d=e[o[0]][o[1]+n];d.type.push("positionProbe"),a.type.push("positionProbe"),r.type.push("positionProbe"),r.color=1==o[2]?i:t,a.color=1==o[2]?i:t,d.color=1==o[2]?i:t;}));}(this),function(o){let{modules:e,moduleCount:r,separatorColor:t}=o;[[7,0],[7,1],[7,2],[7,3],[7,4],[7,5],[7,6],[7,7],[0,7],[1,7],[2,7],[3,7],[4,7],[5,7],[6,7]].forEach((o=>{var i=e[o[0]][o[1]],n=e[r-o[0]-1][o[1]],a=e[o[0]][r-o[1]-1];a.type.push("separator"),n.type.push("separator"),i.type.push("separator"),i.color=t,n.color=t,a.color=t;}));}(this),function(o){let{typeNumber:e,modules:r,moduleCount:t,foregroundColor:i,backgroundColor:n,positionAdjustForegroundColor:a,positionAdjustBackgroundColor:d,timingForegroundColor:u,timingBackgroundColor:s}=o;const g=[[],[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]][e-1];if(g){const o=[[-2,-2,1],[-1,-2,1],[0,-2,1],[1,-2,1],[2,-2,1],[-2,-1,1],[-1,-1,0],[0,-1,0],[1,-1,0],[2,-1,1],[-2,0,1],[-1,0,0],[0,0,1],[1,0,0],[2,0,1],[-2,1,1],[-1,1,0],[0,1,0],[1,1,0],[2,1,1],[-2,2,1],[-1,2,1],[0,2,1],[1,2,1],[2,2,1]],e=g.length;for(let l=0;l<e;l++)for(let h=0;h<e;h++){let{x:e,y:c}={x:g[l],y:g[h]};e<9&&c<9||e>t-9-1&&c<9||c>t-9-1&&e<9||o.forEach((o=>{var t=r[e+o[0]][c+o[1]];t.type.push("positionAdjust"),t.type.includes("timing")?1==o[2]?t.color=a==i?u:a:t.color=a==i&&d==n?s:d:t.color=1==o[2]?a:d;}));}}}(this),function(o){let{modules:e,moduleCount:r,timingForegroundColor:t,timingBackgroundColor:i}=o,n=r-16;for(let o=0;o<n;o++){var a=e[6][8+o],d=e[8+o][6];a.type.push("timing"),d.type.push("timing"),a.color=1&o^1?t:i,d.color=1&o^1?t:i;}}(this),function(o){let{modules:e,moduleCount:r,darkBlockColor:t}=o;var i=e[r-7-1][8];i.type.push("darkBlock"),i.color=t;}(this),function(o){let{typeNumber:e,modules:r,moduleCount:t,typeNumberBackgroundColor:i,typeNumberForegroundColor:n}=o;if(e<7)return r;const a=[0,0,0,0,0,0,0,"000111110010010100","001000010110111100","001001101010011001","001010010011010011","001011101111110110","001100011101100010","001101100001000111","001110011000001101","001111100100101000","010000101101111000","010001010001011101","010010101000010111","010011010100110010","010100100110100110","010101011010000011","010110100011001001","010111011111101100","011000111011000100","011001000111100001","011010111110101011","011011000010001110","011100110000011010","011101001100111111","011110110101110101","011111001001010000","100000100111010101","100001011011110000","100010100010111010","100011011110011111","100100101100001011","100101010000101110","100110101001100100","100111010101000001","101000110001101001"];let d=a[e]+a[e],u=[t-11,t-10,t-9];[[5,u[2]],[5,u[1]],[5,u[0]],[4,u[2]],[4,u[1]],[4,u[0]],[3,u[2]],[3,u[1]],[3,u[0]],[2,u[2]],[2,u[1]],[2,u[0]],[1,u[2]],[1,u[1]],[1,u[0]],[0,u[2]],[0,u[1]],[0,u[0]],[u[2],5],[u[1],5],[u[0],5],[u[2],4],[u[1],4],[u[0],4],[u[2],3],[u[1],3],[u[0],3],[u[2],2],[u[1],2],[u[0],2],[u[2],1],[u[1],1],[u[0],1],[u[2],0],[u[1],0],[u[0],0]].forEach(((o,e)=>{var t=r[o[0]][o[1]];t.type.push("typeNumber"),t.color="1"==d[e]?n:i;}));}(this),this.isMaked=!0,this.drawModules=[];},b.prototype.getDrawModules=function(){if(this.drawModules&&this.drawModules.length>0)return this.drawModules;let o=this.drawModules=[],{modules:e,moduleCount:r,dynamicSize:t,areaColor:i,backgroundImageSrc:n,backgroundImageX:a,backgroundImageY:d,backgroundImageWidth:u,backgroundImageHeight:s,backgroundImageAlpha:g,backgroundImageBorderRadius:l,foregroundImageSrc:h,foregroundImageX:c,foregroundImageY:m,foregroundImageWidth:f,foregroundImageHeight:v,foregroundImagePadding:p,foregroundImageBackgroundColor:C,foregroundImageBorderRadius:b,foregroundImageShadowOffsetX:k,foregroundImageShadowOffsetY:y,foregroundImageShadowBlur:w,foregroundImageShadowColor:I}=this;i&&o.push({name:"area",type:"area",color:i,x:0,y:0,width:t,height:t}),n&&o.push({name:"backgroundImage",type:"image",imageSrc:n,mappingName:"backgroundImageSrc",x:a,y:d,width:u,height:s,alpha:g,borderRadius:l});for(var B=0;B<r;B++)for(var S=0;S<r;S++){var P=e[B][S];P.isDrawn||(P.type.includes("foreground")?o.push({name:"foreground",type:"tile",color:P.color,destX:P.destX,destY:P.destY,destWidth:P.destWidth,destHeight:P.destHeight,x:P.x,y:P.y,width:P.width,height:P.height,paddingTop:P.paddingTop,paddingRight:P.paddingRight,paddingBottom:P.paddingBottom,paddingLeft:P.paddingLeft,rowIndex:B,colIndex:S}):o.push({name:"background",type:"tile",color:P.color,destX:P.destX,destY:P.destY,destWidth:P.destWidth,destHeight:P.destHeight,x:P.x,y:P.y,width:P.width,height:P.height,paddingTop:P.paddingTop,paddingRight:P.paddingRight,paddingBottom:P.paddingBottom,paddingLeft:P.paddingLeft,rowIndex:B,colIndex:S}),P.isDrawn=!0);}return h&&o.push({name:"foregroundImage",type:"image",imageSrc:h,mappingName:"foregroundImageSrc",x:c,y:m,width:f,height:v,padding:p,backgroundColor:C,borderRadius:b,shadowOffsetX:k,shadowOffsetY:y,shadowBlur:w,shadowColor:I}),o},b.prototype.isBlack=function(o,e){var r=this.moduleCount;return !(0>o||0>e||o>=r||e>=r)&&this.modules[o][e].isBlack},b.prototype.drawCanvas=function(){let{isMaked:o,canvasContext:e,useDynamicSize:r,dynamicSize:t,foregroundColor:i,foregroundPadding:n,backgroundColor:a,backgroundPadding:d,drawReserve:u,margin:s}=this;if(!o)return console.error("[uQRCode]: please execute the make method first!"),Promise.reject(new b.Error("please execute the make method first!"));let g=this.getDrawModules(),l=async(o,r)=>{try{e.clearRect(0,0,t,t),e.draw(!1);for(var i=0;i<g.length;i++){var n=g[i];switch(e.save(),n.type){case"area":e.setFillStyle(n.color),e.fillRect(n.x,n.y,n.width,n.height);break;case"tile":var a=n.x,d=n.y,s=n.width,l=n.height;e.setFillStyle(n.color),e.fillRect(a,d,s,l);break;case"image":if("backgroundImage"===n.name){a=Math.round(n.x),d=Math.round(n.y),s=Math.round(n.width),l=Math.round(n.height);s<2*(c=Math.round(n.borderRadius))&&(c=s/2),l<2*c&&(c=l/2),e.setGlobalAlpha(n.alpha),c>0&&(e.beginPath(),e.moveTo(a+c,d),e.arcTo(a+s,d,a+s,d+l,c),e.arcTo(a+s,d+l,a,d+l,c),e.arcTo(a,d+l,a,d,c),e.arcTo(a,d,a+s,d,c),e.closePath(),e.setStrokeStyle("rgba(0,0,0,0)"),e.stroke(),e.clip());try{var h=await this.loadImage(n.imageSrc);e.drawImage(h,a,d,s,l);}catch(o){throw console.error(`[uQRCode]: ${n.mappingName} invalid!`),new b.Error(`${n.mappingName} invalid!`)}}else if("foregroundImage"===n.name){a=Math.round(n.x),d=Math.round(n.y),s=Math.round(n.width),l=Math.round(n.height);var c,m=Math.round(n.padding);s<2*(c=Math.round(n.borderRadius))&&(c=s/2),l<2*c&&(c=l/2);var f=a-m,v=d-m,p=s+2*m,C=l+2*m,k=Math.round(p/s*c);p<2*k&&(k=p/2),C<2*k&&(k=C/2),e.save(),e.setShadow(n.shadowOffsetX,n.shadowOffsetY,n.shadowBlur,n.shadowColor),k>0?(e.beginPath(),e.moveTo(f+k,v),e.arcTo(f+p,v,f+p,v+C,k),e.arcTo(f+p,v+C,f,v+C,k),e.arcTo(f,v+C,f,v,k),e.arcTo(f,v,f+p,v,k),e.closePath(),e.setFillStyle(n.backgroundColor),e.fill()):(e.setFillStyle(n.backgroundColor),e.fillRect(f,v,p,C)),e.restore(),e.save(),k>0?(e.beginPath(),e.moveTo(f+k,v),e.arcTo(f+p,v,f+p,v+C,k),e.arcTo(f+p,v+C,f,v+C,k),e.arcTo(f,v+C,f,v,k),e.arcTo(f,v,f+p,v,k),e.closePath(),e.setFillStyle(m>0?n.backgroundColor:"rgba(0,0,0,0)"),e.fill()):(e.setFillStyle(m>0?n.backgroundColor:"rgba(0,0,0,0)"),e.fillRect(f,v,p,C)),e.restore(),c>0&&(e.beginPath(),e.moveTo(a+c,d),e.arcTo(a+s,d,a+s,d+l,c),e.arcTo(a+s,d+l,a,d+l,c),e.arcTo(a,d+l,a,d,c),e.arcTo(a,d,a+s,d,c),e.closePath(),e.setStrokeStyle("rgba(0,0,0,0)"),e.stroke(),e.clip());try{h=await this.loadImage(n.imageSrc);e.drawImage(h,a,d,s,l);}catch(o){throw console.error(`[uQRCode]: ${n.mappingName} invalid!`),new b.Error(`${n.mappingName} invalid!`)}}}u&&e.draw(!0),e.restore();}e.draw(!0),setTimeout(o,150);}catch(o){if(!(o instanceof b.Error))throw o;r(o);}};return new Promise(((o,e)=>{l(o,e);}))},b.prototype.draw=function(){return this.drawCanvas()},b.prototype.register=function(o){o&&o(b,this,!0);};export{b as default};
\ No newline at end of file
diff --git a/uni_modules/Sansnn-uQRCode/package.json b/uni_modules/Sansnn-uQRCode/package.json
new file mode 100644
index 0000000..af2df9e
--- /dev/null
+++ b/uni_modules/Sansnn-uQRCode/package.json
@@ -0,0 +1,79 @@
+{
+  "id": "Sansnn-uQRCode",
+  "displayName": "uQRCode 鍏ㄧ浜岀淮鐮佺敓鎴愭彃浠� 鏀寔nvue 鏀寔nodejs鏈嶅姟绔�",
+  "version": "4.0.6",
+  "description": "uQRCode鏄竴娆惧熀浜嶫avascript鐜寮�鍙戠殑浜岀淮鐮佺敓鎴愭彃浠讹紝閫傜敤鎵�鏈塉avascript杩愯鐜鐨勫墠绔簲鐢ㄥ拰Node.js銆�",
+  "keywords": [
+    "浜岀淮鐮�",
+    "uQRCode",
+    "qrcode",
+    "qr"
+],
+  "repository": "https://github.com/Sansnn/uQRCode",
+"engines": {
+  },
+"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"
+        }
+      }
+    }
+  }
+}

--
Gitblit v1.8.0