uniapp使用uQRCode绘制二维码,下载到本地,调起微信扫一扫二维码核销

1.效果

2.在utils文件夹下创建uqrcode.js

html 复制代码
// uqrcode.js
//---------------------------------------------------------------------
// github https://github.com/Sansnn/uQRCode
//---------------------------------------------------------------------
 
let uQRCode = {};
 
(function() {
	//---------------------------------------------------------------------
	// QRCode for JavaScript
	//
	// Copyright (c) 2009 Kazuhiko Arase
	//
	// URL: http://www.d-project.com/
	//
	// Licensed under the MIT license:
	//   http://www.opensource.org/licenses/mit-license.php
	//
	// The word "QR Code" is registered trademark of 
	// DENSO WAVE INCORPORATED
	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
	//
	//---------------------------------------------------------------------
 
	//---------------------------------------------------------------------
	// QR8bitByte
	//---------------------------------------------------------------------
 
	function QR8bitByte(data) {
		this.mode = QRMode.MODE_8BIT_BYTE;
		this.data = data;
	}
 
	QR8bitByte.prototype = {
 
		getLength: function(buffer) {
			return this.data.length;
		},
 
		write: function(buffer) {
			for (var i = 0; i < this.data.length; i++) {
				// not JIS ...
				buffer.put(this.data.charCodeAt(i), 8);
			}
		}
	};
 
	//---------------------------------------------------------------------
	// QRCode
	//---------------------------------------------------------------------
 
	function QRCode(typeNumber, errorCorrectLevel) {
		this.typeNumber = typeNumber;
		this.errorCorrectLevel = errorCorrectLevel;
		this.modules = null;
		this.moduleCount = 0;
		this.dataCache = null;
		this.dataList = new Array();
	}
 
	QRCode.prototype = {
 
		addData: function(data) {
			var newData = new QR8bitByte(data);
			this.dataList.push(newData);
			this.dataCache = null;
		},
 
		isDark: function(row, col) {
			if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
				throw new Error(row + "," + col);
			}
			return this.modules[row][col];
		},
 
		getModuleCount: function() {
			return this.moduleCount;
		},
 
		make: function() {
			// Calculate automatically typeNumber if provided is < 1
			if (this.typeNumber < 1) {
				var typeNumber = 1;
				for (typeNumber = 1; typeNumber < 40; typeNumber++) {
					var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
 
					var buffer = new QRBitBuffer();
					var totalDataCount = 0;
					for (var i = 0; i < rsBlocks.length; i++) {
						totalDataCount += rsBlocks[i].dataCount;
					}
 
					for (var i = 0; i < this.dataList.length; i++) {
						var data = this.dataList[i];
						buffer.put(data.mode, 4);
						buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
						data.write(buffer);
					}
					if (buffer.getLengthInBits() <= totalDataCount * 8)
						break;
				}
				this.typeNumber = typeNumber;
			}
			this.makeImpl(false, this.getBestMaskPattern());
		},
 
		makeImpl: function(test, maskPattern) {
 
			this.moduleCount = this.typeNumber * 4 + 17;
			this.modules = new Array(this.moduleCount);
 
			for (var row = 0; row < this.moduleCount; row++) {
 
				this.modules[row] = new Array(this.moduleCount);
 
				for (var col = 0; col < this.moduleCount; col++) {
					this.modules[row][col] = null; //(col + row) % 3;
				}
			}
 
			this.setupPositionProbePattern(0, 0);
			this.setupPositionProbePattern(this.moduleCount - 7, 0);
			this.setupPositionProbePattern(0, this.moduleCount - 7);
			this.setupPositionAdjustPattern();
			this.setupTimingPattern();
			this.setupTypeInfo(test, maskPattern);
 
			if (this.typeNumber >= 7) {
				this.setupTypeNumber(test);
			}
 
			if (this.dataCache == null) {
				this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
			}
 
			this.mapData(this.dataCache, maskPattern);
		},
 
		setupPositionProbePattern: function(row, col) {
 
			for (var r = -1; r <= 7; r++) {
 
				if (row + r <= -1 || this.moduleCount <= row + r) continue;
 
				for (var c = -1; c <= 7; c++) {
 
					if (col + c <= -1 || this.moduleCount <= col + c) continue;
 
					if ((0 <= r && r <= 6 && (c == 0 || c == 6)) ||
						(0 <= c && c <= 6 && (r == 0 || r == 6)) ||
						(2 <= r && r <= 4 && 2 <= c && c <= 4)) {
						this.modules[row + r][col + c] = true;
					} else {
						this.modules[row + r][col + c] = false;
					}
				}
			}
		},
 
		getBestMaskPattern: function() {
 
			var minLostPoint = 0;
			var pattern = 0;
 
			for (var i = 0; i < 8; i++) {
 
				this.makeImpl(true, i);
 
				var lostPoint = QRUtil.getLostPoint(this);
 
				if (i == 0 || minLostPoint > lostPoint) {
					minLostPoint = lostPoint;
					pattern = i;
				}
			}
 
			return pattern;
		},
 
		createMovieClip: function(target_mc, instance_name, depth) {
 
			var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
			var cs = 1;
 
			this.make();
 
			for (var row = 0; row < this.modules.length; row++) {
 
				var y = row * cs;
 
				for (var col = 0; col < this.modules[row].length; col++) {
 
					var x = col * cs;
					var dark = this.modules[row][col];
 
					if (dark) {
						qr_mc.beginFill(0, 100);
						qr_mc.moveTo(x, y);
						qr_mc.lineTo(x + cs, y);
						qr_mc.lineTo(x + cs, y + cs);
						qr_mc.lineTo(x, y + cs);
						qr_mc.endFill();
					}
				}
			}
 
			return qr_mc;
		},
 
		setupTimingPattern: function() {
 
			for (var r = 8; r < this.moduleCount - 8; r++) {
				if (this.modules[r][6] != null) {
					continue;
				}
				this.modules[r][6] = (r % 2 == 0);
			}
 
			for (var c = 8; c < this.moduleCount - 8; c++) {
				if (this.modules[6][c] != null) {
					continue;
				}
				this.modules[6][c] = (c % 2 == 0);
			}
		},
 
		setupPositionAdjustPattern: function() {
 
			var pos = QRUtil.getPatternPosition(this.typeNumber);
 
			for (var i = 0; i < pos.length; i++) {
 
				for (var j = 0; j < pos.length; j++) {
 
					var row = pos[i];
					var col = pos[j];
 
					if (this.modules[row][col] != null) {
						continue;
					}
 
					for (var r = -2; r <= 2; r++) {
 
						for (var c = -2; c <= 2; c++) {
 
							if (r == -2 || r == 2 || c == -2 || c == 2 ||
								(r == 0 && c == 0)) {
								this.modules[row + r][col + c] = true;
							} else {
								this.modules[row + r][col + c] = false;
							}
						}
					}
				}
			}
		},
 
		setupTypeNumber: function(test) {
 
			var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
 
			for (var i = 0; i < 18; i++) {
				var mod = (!test && ((bits >> i) & 1) == 1);
				this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
			}
 
			for (var i = 0; i < 18; i++) {
				var mod = (!test && ((bits >> i) & 1) == 1);
				this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
			}
		},
 
		setupTypeInfo: function(test, maskPattern) {
 
			var data = (this.errorCorrectLevel << 3) | maskPattern;
			var bits = QRUtil.getBCHTypeInfo(data);
 
			// vertical		
			for (var i = 0; i < 15; i++) {
 
				var mod = (!test && ((bits >> i) & 1) == 1);
				if (i < 6) {
					this.modules[i][8] = mod;
				} else if (i < 8) {
					this.modules[i + 1][8] = mod;
				} else {
					this.modules[this.moduleCount - 15 + i][8] = mod;
				}
			}
 
			// horizontal
			for (var i = 0; i < 15; i++) {
 
				var mod = (!test && ((bits >> i) & 1) == 1);
				if (i < 8) {
					this.modules[8][this.moduleCount - i - 1] = mod;
				} else if (i < 9) {
					this.modules[8][15 - i - 1 + 1] = mod;
				} else {
					this.modules[8][15 - i - 1] = mod;
				}
			}
 
			// fixed module
			this.modules[this.moduleCount - 8][8] = (!test);
 
		},
 
		mapData: function(data, maskPattern) {
 
			var inc = -1;
			var row = this.moduleCount - 1;
			var bitIndex = 7;
			var byteIndex = 0;
 
			for (var col = this.moduleCount - 1; col > 0; col -= 2) {
 
				if (col == 6) col--;
 
				while (true) {
 
					for (var c = 0; c < 2; c++) {
 
						if (this.modules[row][col - c] == null) {
 
							var dark = false;
 
							if (byteIndex < data.length) {
								dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
							}
 
							var mask = QRUtil.getMask(maskPattern, row, col - c);
 
							if (mask) {
								dark = !dark;
							}
 
							this.modules[row][col - c] = dark;
							bitIndex--;
 
							if (bitIndex == -1) {
								byteIndex++;
								bitIndex = 7;
							}
						}
					}
 
					row += inc;
 
					if (row < 0 || this.moduleCount <= row) {
						row -= inc;
						inc = -inc;
						break;
					}
				}
			}
 
		}
 
	};
 
	QRCode.PAD0 = 0xEC;
	QRCode.PAD1 = 0x11;
 
	QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
 
		var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
 
		var buffer = new QRBitBuffer();
 
		for (var i = 0; i < dataList.length; i++) {
			var data = dataList[i];
			buffer.put(data.mode, 4);
			buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
			data.write(buffer);
		}
 
		// calc num max data.
		var totalDataCount = 0;
		for (var i = 0; i < rsBlocks.length; i++) {
			totalDataCount += rsBlocks[i].dataCount;
		}
 
		if (buffer.getLengthInBits() > totalDataCount * 8) {
			throw new Error("code length overflow. (" +
				buffer.getLengthInBits() +
				">" +
				totalDataCount * 8 +
				")");
		}
 
		// end code
		if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
			buffer.put(0, 4);
		}
 
		// padding
		while (buffer.getLengthInBits() % 8 != 0) {
			buffer.putBit(false);
		}
 
		// padding
		while (true) {
 
			if (buffer.getLengthInBits() >= totalDataCount * 8) {
				break;
			}
			buffer.put(QRCode.PAD0, 8);
 
			if (buffer.getLengthInBits() >= totalDataCount * 8) {
				break;
			}
			buffer.put(QRCode.PAD1, 8);
		}
 
		return QRCode.createBytes(buffer, rsBlocks);
	}
 
	QRCode.createBytes = function(buffer, rsBlocks) {
 
		var offset = 0;
 
		var maxDcCount = 0;
		var maxEcCount = 0;
 
		var dcdata = new Array(rsBlocks.length);
		var ecdata = new Array(rsBlocks.length);
 
		for (var r = 0; r < rsBlocks.length; r++) {
 
			var dcCount = rsBlocks[r].dataCount;
			var ecCount = rsBlocks[r].totalCount - dcCount;
 
			maxDcCount = Math.max(maxDcCount, dcCount);
			maxEcCount = Math.max(maxEcCount, ecCount);
 
			dcdata[r] = new Array(dcCount);
 
			for (var i = 0; i < dcdata[r].length; i++) {
				dcdata[r][i] = 0xff & buffer.buffer[i + offset];
			}
			offset += dcCount;
 
			var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
			var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
 
			var modPoly = rawPoly.mod(rsPoly);
			ecdata[r] = new Array(rsPoly.getLength() - 1);
			for (var i = 0; i < ecdata[r].length; i++) {
				var modIndex = i + modPoly.getLength() - ecdata[r].length;
				ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
			}
 
		}
 
		var totalCodeCount = 0;
		for (var i = 0; i < rsBlocks.length; i++) {
			totalCodeCount += rsBlocks[i].totalCount;
		}
 
		var data = new Array(totalCodeCount);
		var index = 0;
 
		for (var i = 0; i < maxDcCount; i++) {
			for (var r = 0; r < rsBlocks.length; r++) {
				if (i < dcdata[r].length) {
					data[index++] = dcdata[r][i];
				}
			}
		}
 
		for (var i = 0; i < maxEcCount; i++) {
			for (var r = 0; r < rsBlocks.length; r++) {
				if (i < ecdata[r].length) {
					data[index++] = ecdata[r][i];
				}
			}
		}
 
		return data;
 
	}
 
	//---------------------------------------------------------------------
	// QRMode
	//---------------------------------------------------------------------
 
	var QRMode = {
		MODE_NUMBER: 1 << 0,
		MODE_ALPHA_NUM: 1 << 1,
		MODE_8BIT_BYTE: 1 << 2,
		MODE_KANJI: 1 << 3
	};
 
	//---------------------------------------------------------------------
	// QRErrorCorrectLevel
	//---------------------------------------------------------------------
 
	var QRErrorCorrectLevel = {
		L: 1,
		M: 0,
		Q: 3,
		H: 2
	};
 
	//---------------------------------------------------------------------
	// QRMaskPattern
	//---------------------------------------------------------------------
 
	var QRMaskPattern = {
		PATTERN000: 0,
		PATTERN001: 1,
		PATTERN010: 2,
		PATTERN011: 3,
		PATTERN100: 4,
		PATTERN101: 5,
		PATTERN110: 6,
		PATTERN111: 7
	};
 
	//---------------------------------------------------------------------
	// QRUtil
	//---------------------------------------------------------------------
 
	var QRUtil = {
 
		PATTERN_POSITION_TABLE: [
			[],
			[6, 18],
			[6, 22],
			[6, 26],
			[6, 30],
			[6, 34],
			[6, 22, 38],
			[6, 24, 42],
			[6, 26, 46],
			[6, 28, 50],
			[6, 30, 54],
			[6, 32, 58],
			[6, 34, 62],
			[6, 26, 46, 66],
			[6, 26, 48, 70],
			[6, 26, 50, 74],
			[6, 30, 54, 78],
			[6, 30, 56, 82],
			[6, 30, 58, 86],
			[6, 34, 62, 90],
			[6, 28, 50, 72, 94],
			[6, 26, 50, 74, 98],
			[6, 30, 54, 78, 102],
			[6, 28, 54, 80, 106],
			[6, 32, 58, 84, 110],
			[6, 30, 58, 86, 114],
			[6, 34, 62, 90, 118],
			[6, 26, 50, 74, 98, 122],
			[6, 30, 54, 78, 102, 126],
			[6, 26, 52, 78, 104, 130],
			[6, 30, 56, 82, 108, 134],
			[6, 34, 60, 86, 112, 138],
			[6, 30, 58, 86, 114, 142],
			[6, 34, 62, 90, 118, 146],
			[6, 30, 54, 78, 102, 126, 150],
			[6, 24, 50, 76, 102, 128, 154],
			[6, 28, 54, 80, 106, 132, 158],
			[6, 32, 58, 84, 110, 136, 162],
			[6, 26, 54, 82, 110, 138, 166],
			[6, 30, 58, 86, 114, 142, 170]
		],
 
		G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
		G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
		G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
 
		getBCHTypeInfo: function(data) {
			var d = data << 10;
			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
				d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
			}
			return ((data << 10) | d) ^ QRUtil.G15_MASK;
		},
 
		getBCHTypeNumber: function(data) {
			var d = data << 12;
			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
				d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
			}
			return (data << 12) | d;
		},
 
		getBCHDigit: function(data) {
 
			var digit = 0;
 
			while (data != 0) {
				digit++;
				data >>>= 1;
			}
 
			return digit;
		},
 
		getPatternPosition: function(typeNumber) {
			return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
		},
 
		getMask: function(maskPattern, i, j) {
 
			switch (maskPattern) {
 
				case QRMaskPattern.PATTERN000:
					return (i + j) % 2 == 0;
				case QRMaskPattern.PATTERN001:
					return i % 2 == 0;
				case QRMaskPattern.PATTERN010:
					return j % 3 == 0;
				case QRMaskPattern.PATTERN011:
					return (i + j) % 3 == 0;
				case QRMaskPattern.PATTERN100:
					return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
				case QRMaskPattern.PATTERN101:
					return (i * j) % 2 + (i * j) % 3 == 0;
				case QRMaskPattern.PATTERN110:
					return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
				case QRMaskPattern.PATTERN111:
					return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
 
				default:
					throw new Error("bad maskPattern:" + maskPattern);
			}
		},
 
		getErrorCorrectPolynomial: function(errorCorrectLength) {
 
			var a = new QRPolynomial([1], 0);
 
			for (var i = 0; i < errorCorrectLength; i++) {
				a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
			}
 
			return a;
		},
 
		getLengthInBits: function(mode, type) {
 
			if (1 <= type && type < 10) {
 
				// 1 - 9
 
				switch (mode) {
					case QRMode.MODE_NUMBER:
						return 10;
					case QRMode.MODE_ALPHA_NUM:
						return 9;
					case QRMode.MODE_8BIT_BYTE:
						return 8;
					case QRMode.MODE_KANJI:
						return 8;
					default:
						throw new Error("mode:" + mode);
				}
 
			} else if (type < 27) {
 
				// 10 - 26
 
				switch (mode) {
					case QRMode.MODE_NUMBER:
						return 12;
					case QRMode.MODE_ALPHA_NUM:
						return 11;
					case QRMode.MODE_8BIT_BYTE:
						return 16;
					case QRMode.MODE_KANJI:
						return 10;
					default:
						throw new Error("mode:" + mode);
				}
 
			} else if (type < 41) {
 
				// 27 - 40
 
				switch (mode) {
					case QRMode.MODE_NUMBER:
						return 14;
					case QRMode.MODE_ALPHA_NUM:
						return 13;
					case QRMode.MODE_8BIT_BYTE:
						return 16;
					case QRMode.MODE_KANJI:
						return 12;
					default:
						throw new Error("mode:" + mode);
				}
 
			} else {
				throw new Error("type:" + type);
			}
		},
 
		getLostPoint: function(qrCode) {
 
			var moduleCount = qrCode.getModuleCount();
 
			var lostPoint = 0;
 
			// LEVEL1
 
			for (var row = 0; row < moduleCount; row++) {
 
				for (var col = 0; col < moduleCount; col++) {
 
					var sameCount = 0;
					var dark = qrCode.isDark(row, col);
 
					for (var r = -1; r <= 1; r++) {
 
						if (row + r < 0 || moduleCount <= row + r) {
							continue;
						}
 
						for (var c = -1; c <= 1; c++) {
 
							if (col + c < 0 || moduleCount <= col + c) {
								continue;
							}
 
							if (r == 0 && c == 0) {
								continue;
							}
 
							if (dark == qrCode.isDark(row + r, col + c)) {
								sameCount++;
							}
						}
					}
 
					if (sameCount > 5) {
						lostPoint += (3 + sameCount - 5);
					}
				}
			}
 
			// LEVEL2
 
			for (var row = 0; row < moduleCount - 1; row++) {
				for (var col = 0; col < moduleCount - 1; col++) {
					var count = 0;
					if (qrCode.isDark(row, col)) count++;
					if (qrCode.isDark(row + 1, col)) count++;
					if (qrCode.isDark(row, col + 1)) count++;
					if (qrCode.isDark(row + 1, col + 1)) count++;
					if (count == 0 || count == 4) {
						lostPoint += 3;
					}
				}
			}
 
			// LEVEL3
 
			for (var row = 0; row < moduleCount; row++) {
				for (var col = 0; col < moduleCount - 6; col++) {
					if (qrCode.isDark(row, col) &&
						!qrCode.isDark(row, col + 1) &&
						qrCode.isDark(row, col + 2) &&
						qrCode.isDark(row, col + 3) &&
						qrCode.isDark(row, col + 4) &&
						!qrCode.isDark(row, col + 5) &&
						qrCode.isDark(row, col + 6)) {
						lostPoint += 40;
					}
				}
			}
 
			for (var col = 0; col < moduleCount; col++) {
				for (var row = 0; row < moduleCount - 6; row++) {
					if (qrCode.isDark(row, col) &&
						!qrCode.isDark(row + 1, col) &&
						qrCode.isDark(row + 2, col) &&
						qrCode.isDark(row + 3, col) &&
						qrCode.isDark(row + 4, col) &&
						!qrCode.isDark(row + 5, col) &&
						qrCode.isDark(row + 6, col)) {
						lostPoint += 40;
					}
				}
			}
 
			// LEVEL4
 
			var darkCount = 0;
 
			for (var col = 0; col < moduleCount; col++) {
				for (var row = 0; row < moduleCount; row++) {
					if (qrCode.isDark(row, col)) {
						darkCount++;
					}
				}
			}
 
			var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
			lostPoint += ratio * 10;
 
			return lostPoint;
		}
 
	};
 
 
	//---------------------------------------------------------------------
	// QRMath
	//---------------------------------------------------------------------
 
	var QRMath = {
 
		glog: function(n) {
 
			if (n < 1) {
				throw new Error("glog(" + n + ")");
			}
 
			return QRMath.LOG_TABLE[n];
		},
 
		gexp: function(n) {
 
			while (n < 0) {
				n += 255;
			}
 
			while (n >= 256) {
				n -= 255;
			}
 
			return QRMath.EXP_TABLE[n];
		},
 
		EXP_TABLE: new Array(256),
 
		LOG_TABLE: new Array(256)
 
	};
 
	for (var i = 0; i < 8; i++) {
		QRMath.EXP_TABLE[i] = 1 << i;
	}
	for (var i = 8; i < 256; i++) {
		QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
			QRMath.EXP_TABLE[i - 5] ^
			QRMath.EXP_TABLE[i - 6] ^
			QRMath.EXP_TABLE[i - 8];
	}
	for (var i = 0; i < 255; i++) {
		QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
	}
 
	//---------------------------------------------------------------------
	// QRPolynomial
	//---------------------------------------------------------------------
 
	function QRPolynomial(num, shift) {
 
		if (num.length == undefined) {
			throw new Error(num.length + "/" + shift);
		}
 
		var offset = 0;
 
		while (offset < num.length && num[offset] == 0) {
			offset++;
		}
 
		this.num = new Array(num.length - offset + shift);
		for (var i = 0; i < num.length - offset; i++) {
			this.num[i] = num[i + offset];
		}
	}
 
	QRPolynomial.prototype = {
 
		get: function(index) {
			return this.num[index];
		},
 
		getLength: function() {
			return this.num.length;
		},
 
		multiply: function(e) {
 
			var num = new Array(this.getLength() + e.getLength() - 1);
 
			for (var i = 0; i < this.getLength(); i++) {
				for (var j = 0; j < e.getLength(); j++) {
					num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
				}
			}
 
			return new QRPolynomial(num, 0);
		},
 
		mod: function(e) {
 
			if (this.getLength() - e.getLength() < 0) {
				return this;
			}
 
			var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
 
			var num = new Array(this.getLength());
 
			for (var i = 0; i < this.getLength(); i++) {
				num[i] = this.get(i);
			}
 
			for (var i = 0; i < e.getLength(); i++) {
				num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
			}
 
			// recursive call
			return new QRPolynomial(num, 0).mod(e);
		}
	};
 
	//---------------------------------------------------------------------
	// QRRSBlock
	//---------------------------------------------------------------------
 
	function QRRSBlock(totalCount, dataCount) {
		this.totalCount = totalCount;
		this.dataCount = dataCount;
	}
 
	QRRSBlock.RS_BLOCK_TABLE = [
 
		// L
		// M
		// Q
		// H
 
		// 1
		[1, 26, 19],
		[1, 26, 16],
		[1, 26, 13],
		[1, 26, 9],
 
		// 2
		[1, 44, 34],
		[1, 44, 28],
		[1, 44, 22],
		[1, 44, 16],
 
		// 3
		[1, 70, 55],
		[1, 70, 44],
		[2, 35, 17],
		[2, 35, 13],
 
		// 4		
		[1, 100, 80],
		[2, 50, 32],
		[2, 50, 24],
		[4, 25, 9],
 
		// 5
		[1, 134, 108],
		[2, 67, 43],
		[2, 33, 15, 2, 34, 16],
		[2, 33, 11, 2, 34, 12],
 
		// 6
		[2, 86, 68],
		[4, 43, 27],
		[4, 43, 19],
		[4, 43, 15],
 
		// 7		
		[2, 98, 78],
		[4, 49, 31],
		[2, 32, 14, 4, 33, 15],
		[4, 39, 13, 1, 40, 14],
 
		// 8
		[2, 121, 97],
		[2, 60, 38, 2, 61, 39],
		[4, 40, 18, 2, 41, 19],
		[4, 40, 14, 2, 41, 15],
 
		// 9
		[2, 146, 116],
		[3, 58, 36, 2, 59, 37],
		[4, 36, 16, 4, 37, 17],
		[4, 36, 12, 4, 37, 13],
 
		// 10		
		[2, 86, 68, 2, 87, 69],
		[4, 69, 43, 1, 70, 44],
		[6, 43, 19, 2, 44, 20],
		[6, 43, 15, 2, 44, 16],
 
		// 11
		[4, 101, 81],
		[1, 80, 50, 4, 81, 51],
		[4, 50, 22, 4, 51, 23],
		[3, 36, 12, 8, 37, 13],
 
		// 12
		[2, 116, 92, 2, 117, 93],
		[6, 58, 36, 2, 59, 37],
		[4, 46, 20, 6, 47, 21],
		[7, 42, 14, 4, 43, 15],
 
		// 13
		[4, 133, 107],
		[8, 59, 37, 1, 60, 38],
		[8, 44, 20, 4, 45, 21],
		[12, 33, 11, 4, 34, 12],
 
		// 14
		[3, 145, 115, 1, 146, 116],
		[4, 64, 40, 5, 65, 41],
		[11, 36, 16, 5, 37, 17],
		[11, 36, 12, 5, 37, 13],
 
		// 15
		[5, 109, 87, 1, 110, 88],
		[5, 65, 41, 5, 66, 42],
		[5, 54, 24, 7, 55, 25],
		[11, 36, 12],
 
		// 16
		[5, 122, 98, 1, 123, 99],
		[7, 73, 45, 3, 74, 46],
		[15, 43, 19, 2, 44, 20],
		[3, 45, 15, 13, 46, 16],
 
		// 17
		[1, 135, 107, 5, 136, 108],
		[10, 74, 46, 1, 75, 47],
		[1, 50, 22, 15, 51, 23],
		[2, 42, 14, 17, 43, 15],
 
		// 18
		[5, 150, 120, 1, 151, 121],
		[9, 69, 43, 4, 70, 44],
		[17, 50, 22, 1, 51, 23],
		[2, 42, 14, 19, 43, 15],
 
		// 19
		[3, 141, 113, 4, 142, 114],
		[3, 70, 44, 11, 71, 45],
		[17, 47, 21, 4, 48, 22],
		[9, 39, 13, 16, 40, 14],
 
		// 20
		[3, 135, 107, 5, 136, 108],
		[3, 67, 41, 13, 68, 42],
		[15, 54, 24, 5, 55, 25],
		[15, 43, 15, 10, 44, 16],
 
		// 21
		[4, 144, 116, 4, 145, 117],
		[17, 68, 42],
		[17, 50, 22, 6, 51, 23],
		[19, 46, 16, 6, 47, 17],
 
		// 22
		[2, 139, 111, 7, 140, 112],
		[17, 74, 46],
		[7, 54, 24, 16, 55, 25],
		[34, 37, 13],
 
		// 23
		[4, 151, 121, 5, 152, 122],
		[4, 75, 47, 14, 76, 48],
		[11, 54, 24, 14, 55, 25],
		[16, 45, 15, 14, 46, 16],
 
		// 24
		[6, 147, 117, 4, 148, 118],
		[6, 73, 45, 14, 74, 46],
		[11, 54, 24, 16, 55, 25],
		[30, 46, 16, 2, 47, 17],
 
		// 25
		[8, 132, 106, 4, 133, 107],
		[8, 75, 47, 13, 76, 48],
		[7, 54, 24, 22, 55, 25],
		[22, 45, 15, 13, 46, 16],
 
		// 26
		[10, 142, 114, 2, 143, 115],
		[19, 74, 46, 4, 75, 47],
		[28, 50, 22, 6, 51, 23],
		[33, 46, 16, 4, 47, 17],
 
		// 27
		[8, 152, 122, 4, 153, 123],
		[22, 73, 45, 3, 74, 46],
		[8, 53, 23, 26, 54, 24],
		[12, 45, 15, 28, 46, 16],
 
		// 28
		[3, 147, 117, 10, 148, 118],
		[3, 73, 45, 23, 74, 46],
		[4, 54, 24, 31, 55, 25],
		[11, 45, 15, 31, 46, 16],
 
		// 29
		[7, 146, 116, 7, 147, 117],
		[21, 73, 45, 7, 74, 46],
		[1, 53, 23, 37, 54, 24],
		[19, 45, 15, 26, 46, 16],
 
		// 30
		[5, 145, 115, 10, 146, 116],
		[19, 75, 47, 10, 76, 48],
		[15, 54, 24, 25, 55, 25],
		[23, 45, 15, 25, 46, 16],
 
		// 31
		[13, 145, 115, 3, 146, 116],
		[2, 74, 46, 29, 75, 47],
		[42, 54, 24, 1, 55, 25],
		[23, 45, 15, 28, 46, 16],
 
		// 32
		[17, 145, 115],
		[10, 74, 46, 23, 75, 47],
		[10, 54, 24, 35, 55, 25],
		[19, 45, 15, 35, 46, 16],
 
		// 33
		[17, 145, 115, 1, 146, 116],
		[14, 74, 46, 21, 75, 47],
		[29, 54, 24, 19, 55, 25],
		[11, 45, 15, 46, 46, 16],
 
		// 34
		[13, 145, 115, 6, 146, 116],
		[14, 74, 46, 23, 75, 47],
		[44, 54, 24, 7, 55, 25],
		[59, 46, 16, 1, 47, 17],
 
		// 35
		[12, 151, 121, 7, 152, 122],
		[12, 75, 47, 26, 76, 48],
		[39, 54, 24, 14, 55, 25],
		[22, 45, 15, 41, 46, 16],
 
		// 36
		[6, 151, 121, 14, 152, 122],
		[6, 75, 47, 34, 76, 48],
		[46, 54, 24, 10, 55, 25],
		[2, 45, 15, 64, 46, 16],
 
		// 37
		[17, 152, 122, 4, 153, 123],
		[29, 74, 46, 14, 75, 47],
		[49, 54, 24, 10, 55, 25],
		[24, 45, 15, 46, 46, 16],
 
		// 38
		[4, 152, 122, 18, 153, 123],
		[13, 74, 46, 32, 75, 47],
		[48, 54, 24, 14, 55, 25],
		[42, 45, 15, 32, 46, 16],
 
		// 39
		[20, 147, 117, 4, 148, 118],
		[40, 75, 47, 7, 76, 48],
		[43, 54, 24, 22, 55, 25],
		[10, 45, 15, 67, 46, 16],
 
		// 40
		[19, 148, 118, 6, 149, 119],
		[18, 75, 47, 31, 76, 48],
		[34, 54, 24, 34, 55, 25],
		[20, 45, 15, 61, 46, 16]
	];
 
	QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
 
		var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
 
		if (rsBlock == undefined) {
			throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
		}
 
		var length = rsBlock.length / 3;
 
		var list = new Array();
 
		for (var i = 0; i < length; i++) {
 
			var count = rsBlock[i * 3 + 0];
			var totalCount = rsBlock[i * 3 + 1];
			var dataCount = rsBlock[i * 3 + 2];
 
			for (var j = 0; j < count; j++) {
				list.push(new QRRSBlock(totalCount, dataCount));
			}
		}
 
		return list;
	}
 
	QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
 
		switch (errorCorrectLevel) {
			case QRErrorCorrectLevel.L:
				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
			case QRErrorCorrectLevel.M:
				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
			case QRErrorCorrectLevel.Q:
				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
			case QRErrorCorrectLevel.H:
				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
			default:
				return undefined;
		}
	}
 
	//---------------------------------------------------------------------
	// QRBitBuffer
	//---------------------------------------------------------------------
 
	function QRBitBuffer() {
		this.buffer = new Array();
		this.length = 0;
	}
 
	QRBitBuffer.prototype = {
 
		get: function(index) {
			var bufIndex = Math.floor(index / 8);
			return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
		},
 
		put: function(num, length) {
			for (var i = 0; i < length; i++) {
				this.putBit(((num >>> (length - i - 1)) & 1) == 1);
			}
		},
 
		getLengthInBits: function() {
			return this.length;
		},
 
		putBit: function(bit) {
 
			var bufIndex = Math.floor(this.length / 8);
			if (this.buffer.length <= bufIndex) {
				this.buffer.push(0);
			}
 
			if (bit) {
				this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
			}
 
			this.length++;
		}
	};
 
	//---------------------------------------------------------------------
	// Support Chinese
	//---------------------------------------------------------------------
	function utf16To8(text) {
		var result = '';
		var c;
		for (var i = 0; i < text.length; i++) {
			c = text.charCodeAt(i);
			if (c >= 0x0001 && c <= 0x007F) {
				result += text.charAt(i);
			} else if (c > 0x07FF) {
				result += String.fromCharCode(0xE0 | c >> 12 & 0x0F);
				result += String.fromCharCode(0x80 | c >> 6 & 0x3F);
				result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
			} else {
				result += String.fromCharCode(0xC0 | c >> 6 & 0x1F);
				result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
			}
		}
		return result;
	}
 
	uQRCode = {
 
		errorCorrectLevel: QRErrorCorrectLevel,
 
		defaults: {
			size: 354,
			margin: 0,
			backgroundColor: '#ffffff',
			foregroundColor: '#000000',
			fileType: 'png', // 'jpg', 'png'
			errorCorrectLevel: QRErrorCorrectLevel.H,
			typeNumber: -1
		},
 
		make: function(options) {
			return new Promise((reslove, reject) => {
				var defaultOptions = {
					canvasId: options.canvasId,
					componentInstance: options.componentInstance,
					text: options.text,
					size: this.defaults.size,
					margin: this.defaults.margin,
					backgroundColor: this.defaults.backgroundColor,
					foregroundColor: this.defaults.foregroundColor,
					fileType: this.defaults.fileType,
					errorCorrectLevel: this.defaults.errorCorrectLevel,
					typeNumber: this.defaults.typeNumber
				};
				if (options) {
					for (var i in options) {
						defaultOptions[i] = options[i];
					}
				}
				options = defaultOptions;
				if (!options.canvasId) {
					console.error('uQRCode: Please set canvasId!');
					return;
				}
 
				function createCanvas() {
					var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
					qrcode.addData(utf16To8(options.text));
					qrcode.make();
 
					var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance);
					ctx.setFillStyle(options.backgroundColor);
					ctx.fillRect(0, 0, options.size, options.size);
 
					var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount();
					var tileH = tileW;
 
					for (var row = 0; row < qrcode.getModuleCount(); row++) {
						for (var col = 0; col < qrcode.getModuleCount(); col++) {
							var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor;
							ctx.setFillStyle(style);
							var x = Math.round(col * tileW) + options.margin;
							var y = Math.round(row * tileH) + options.margin;
							var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
							var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
							ctx.fillRect(x, y, w, h);
						}
					}
 
					setTimeout(function() {
						ctx.draw(false, (function() {
							setTimeout(function() {
								uni.canvasToTempFilePath({
									canvasId: options.canvasId,
									fileType: options.fileType,
									width: options.size,
									height: options.size,
									destWidth: options.size,
									destHeight: options.size,
									success: function(res) {
										let resData; // 将统一为base64格式
										let tempFilePath = res.tempFilePath; // H5为base64,其他为相对路径
 
										// #ifdef H5
										resData = tempFilePath;
										options.success && options.success(resData);
										reslove(resData);
										// #endif
 
										// #ifdef APP-PLUS
										const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
										let fileReader = new plus.io.FileReader();
										fileReader.readAsDataURL(path);
										fileReader.onloadend = res => {
											resData = res.target.result;
											options.success && options.success(resData);
											reslove(resData);
										};
										// #endif
 
										// #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
										uni.getFileSystemManager().readFile({
											filePath: tempFilePath,
											encoding: 'base64',
											success: res => {
												resData = 'data:image/png;base64,' + res.data;
												options.success && options.success(resData);
												reslove(resData);
											}
										})
										// #endif
 
										// #ifndef H5 || APP-PLUS || MP-WEIXIN || MP-QQ || MP-TOUTIAO
										if (plus) {
											const path = plus.io.convertLocalFileSystemURL(tempFilePath) // 绝对路径
											let fileReader = new plus.io.FileReader();
											fileReader.readAsDataURL(path);
											fileReader.onloadend = res => {
												resData = res.target.result;
												options.success && options.success(resData);
												reslove(resData);
											};
										} else {
											uni.request({
												url: tempFilePath,
												method: 'GET',
												responseType: 'arraybuffer',
												success: res => {
													resData = `data:image/png;base64,${uni.arrayBufferToBase64(res.data)}`; // 把arraybuffer转成base64
													options.success && options.success(resData);
													reslove(resData);
												}
											})
										}
										// #endif
									},
									fail: function(error) {
										options.fail && options.fail(error);
										reject(error);
									},
									complete: function(res) {
										options.complete && options.complete(res);
									}
								}, options.componentInstance);
							}, options.text.length + 100);
						})());
					}, 150);
				}
 
				createCanvas();
			});
		}
	}
 
})()
 
export default uQRCode

3.在需要使用的页面引入js

html 复制代码
<template>
<view>
<view class="codeBox" @click="save">
				<!-- 二维码 -->
				<canvas id="qrcode" canvas-id="qrcode" style="width: 200px;height: 200px;"></canvas>
				<view class="saveCode">
					保存二维码
				</view>
			</view>
</view>
</template>
<script>
	import uqrCode from '@/utils/uqrcode.js'
	export default {
		data() {
			return {
			qrcode: false,
			imgCode: '', // 后续保存到手机相册所需要用到的字段
			}
			},
			onLoad(){
			this.generate('https://www.baidu.com?id=1')
			},
			methods:{
			//  生成二维码事件
			generate(e) {
				uqrCode.make({
					canvasId: 'qrcode',
					componentInstance: this,
					text: e, // 想生成二维码到内容
					size: 200,
					margin: 0,
					backgroundColor: '#ffffff',
					foregroundColor: '#000000',
					fileType: 'jpg',
					errorCorrectLevel: uqrCode.errorCorrectLevel.H,
					success: res => {
						this.imgCode = res // base64的图片格式
					}
				})
			},
			// 保存到手机
			save() {
				uni.getSetting({ //获取用户的当前设置
					success: (res) => {
						if (res.authSetting['scope.writePhotosAlbum']) { //验证用户是否授权可以访问相册
							this.aveImageToPhotosAlbum();
						} else {
							uni.authorize({ //如果没有授权,向用户发起请求
								scope: 'scope.writePhotosAlbum',
								success: () => {
									this.aveImageToPhotosAlbum();
								},
								fail: () => {
									// 提示
									uni.showToast({
										title: "请打开保存相册权限,再点击保存到手机",
										icon: "none",
										duration: 3000
									});
									setTimeout(() => {
										uni.openSetting({ //调起客户端小程序设置界面,让用户开启访问相册
											success: (res2) => {
												// console.log(res2.authSetting)
											}
										});
									}, 3000);
								}
							})
						}
					}
				})
			},
			aveImageToPhotosAlbum() {
				let base64 = this.imgCode.replace(/^data:image\/\w+;base64,/, ""); //去掉data:image/png;base64,
				let filePath = wx.env.USER_DATA_PATH + '/writeOff.png'; //   路径文件名
				uni.showLoading({
					title: '加载中',
					mask: true
				})
				uni.getFileSystemManager().writeFile({ // 获取全局唯一的文件管理器
					filePath: filePath, //创建一个临时文件名
					data: base64, //写入的文本或二进制数据
					encoding: 'base64', //写入当前文件的字符编码
					success: res => {
						uni.saveImageToPhotosAlbum({ // 保存图片到系统相册
							filePath: filePath,
							success: function(res2) {
								uni.hideLoading();
								uni.showToast({
									title: '保存成功',
									icon: "none",
									duration: 5000
								})
							},
							fail: function(err) {
								uni.hideLoading();
								// console.log(err.errMsg);
							}
						})
					},
					fail: err => {
						uni.hideLoading();
						//console.log(err)
					}
				})
			},
			}
			}

4.掉起微信扫一扫核销,将二维码扫出来的参数传个后端

html 复制代码
<template>
	<view>
	<view  @click="scanCode">点击核销</view>
	</view>
</template>
<script>
	export default {
		data() {
			return {
			}
			},
			onLoad() {},
			methods: {
			scanCode() {
				let that = this;
				uni.scanCode({
					onlyFromCamera: true, //只能通过相机扫码
					success: function(res) {
						console.log('扫码', res.result)
						let obj = {id:that.getQueryString(res.result,'id'),
						}
						uni.showLoading({
							mask: true,
							title: '核销中...'
						})
						setTimeout(res => {
							uni.hideLoading();
						}, 500)
					}
				});
			},
			// 解析链接中的参数
			getQueryString (url, name) {
  console.log("url = " + url)
  console.log("name = " + name)
  var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
  var r = url.substr(1).match(reg)
  if (r != null) {
    console.log("r = " + r)
    console.log("r[2] = " + r[2])
    return r[2]
  }
  return null;
}
			}
			}
相关推荐
baozhengw2 小时前
UniAPP快速入门教程(一)
前端·uni-app
公子艾6 小时前
uniapp设置tabBar高斯模糊并设置tabBar高度占位
uni-app
晓风伴月8 小时前
uniapp: IOS微信小程序输入框部分被软键盘遮挡问题
微信小程序·小程序·uni-app
转角羊儿8 小时前
uni-app文章列表制作⑧
前端·javascript·uni-app
糊涂涂是个小盆友9 小时前
前端 - 使用uniapp+vue搭建前端项目(app端)
前端·vue.js·uni-app
阿巴阿巴Ovo10 小时前
uniapp中多角色导致tabbar过多的解决方式
uni-app
Json____13 小时前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库
云深时现月14 小时前
jenkins使用cli发行uni-app到h5
前端·uni-app·jenkins
diygwcom14 小时前
低代码可视化-uniapp开关选择组件-低码生成器
uni-app
fakaifa1 天前
CRMEB Pro版v3.1源码全开源+PC端+Uniapp前端+搭建教程
前端·小程序·uni-app·php·源码下载