6 changed files with 433 additions and 0 deletions
			
			
		- 
					54components/lf-code/helper.js
 - 
					2components/lf-code/index.js
 - 
					87components/lf-code/lf-barcode.vue
 - 
					84components/lf-code/lf-qrcode.vue
 - 
					7pages.json
 - 
					199pages/user/member/code.vue
 
@ -0,0 +1,54 @@ | 
				
			|||
// 判断arr是否为一个数组,返回一个bool值
 | 
				
			|||
function isArray(arr) { | 
				
			|||
	return Object.prototype.toString.call(arr) === '[object Array]'; | 
				
			|||
} | 
				
			|||
// 深度克隆
 | 
				
			|||
function deepClone(obj) { | 
				
			|||
	// 对常见的“非”值,直接返回原来值
 | 
				
			|||
	if ([null, undefined, NaN, false].includes(obj)) return obj; | 
				
			|||
	if (typeof obj !== "object" && typeof obj !== 'function') { | 
				
			|||
		//原始类型直接返回
 | 
				
			|||
		return obj; | 
				
			|||
	} | 
				
			|||
	var o = isArray(obj) ? [] : {}; | 
				
			|||
	for (let i in obj) { | 
				
			|||
		if (obj.hasOwnProperty(i)) { | 
				
			|||
			o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
	return o; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function getUUid(len = 32, firstU = true, radix = null) { | 
				
			|||
	let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); | 
				
			|||
	let uuid = []; | 
				
			|||
	radix = radix || chars.length; | 
				
			|||
 | 
				
			|||
	if (len) { | 
				
			|||
		// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
 | 
				
			|||
		for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; | 
				
			|||
	} else { | 
				
			|||
		let r; | 
				
			|||
		// rfc4122标准要求返回的uuid中,某些位为固定的字符
 | 
				
			|||
		uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; | 
				
			|||
		uuid[14] = '4'; | 
				
			|||
 | 
				
			|||
		for (let i = 0; i < 36; i++) { | 
				
			|||
			if (!uuid[i]) { | 
				
			|||
				r = 0 | Math.random() * 16; | 
				
			|||
				uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
	// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
 | 
				
			|||
	if (firstU) { | 
				
			|||
		uuid.shift(); | 
				
			|||
		return 'u' + uuid.join(''); | 
				
			|||
	} else { | 
				
			|||
		return uuid.join(''); | 
				
			|||
	} | 
				
			|||
} | 
				
			|||
export { | 
				
			|||
	deepClone, | 
				
			|||
	getUUid | 
				
			|||
}; | 
				
			|||
						
							
						
						
							2
	
						
						components/lf-code/index.js
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						@ -0,0 +1,87 @@ | 
				
			|||
<template> | 
				
			|||
    <view> | 
				
			|||
		<!-- #ifdef MP-WEIXIN  --> | 
				
			|||
		<canvas :canvas-id="item.id" :id="item.id" :style="{width:width,height: height}" v-for="(item,index) in listCode" :key="item.id" /> | 
				
			|||
		<!-- #endif --> | 
				
			|||
		 | 
				
			|||
		<!-- #ifndef MP-WEIXIN --> | 
				
			|||
		<canvas :canvas-id="id" :id="id" :style="{width:width,height: height}" /> | 
				
			|||
		<!-- #endif --> | 
				
			|||
	</view> | 
				
			|||
</template> | 
				
			|||
<script> | 
				
			|||
	import QRCODE from './index.js'; | 
				
			|||
	import { getUUid, deepClone } from './helper.js' | 
				
			|||
	export default { | 
				
			|||
		name: 'WBarcode', | 
				
			|||
		props:{ | 
				
			|||
			options:{ | 
				
			|||
				type: Object, | 
				
			|||
				required: true, | 
				
			|||
				default: () =>{ | 
				
			|||
					return { | 
				
			|||
						 | 
				
			|||
					} | 
				
			|||
				} | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		data () { | 
				
			|||
			return { | 
				
			|||
				listCode: [], | 
				
			|||
				id: getUUid(), | 
				
			|||
				height: null, | 
				
			|||
				width: null, | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		created() { | 
				
			|||
			this.height = this.options.height + 'rpx'; | 
				
			|||
			this.width = this.options.width + 'rpx'; | 
				
			|||
			this.SpecialTreatment(this.options) | 
				
			|||
			this.$nextTick(()=>{ | 
				
			|||
				this.generateCode(); | 
				
			|||
			}) | 
				
			|||
		}, | 
				
			|||
		watch: { | 
				
			|||
			options:{ | 
				
			|||
				deep: true, | 
				
			|||
				handler (val) { | 
				
			|||
					this.height = val.height + 'rpx'; | 
				
			|||
					this.width = val.width + 'rpx'; | 
				
			|||
					this.SpecialTreatment(val) | 
				
			|||
					// #ifdef H5 | 
				
			|||
					setTimeout(()=>{// h5平台动态改变canvas大小 | 
				
			|||
						this.generateCode(); | 
				
			|||
					},50) | 
				
			|||
					// #endif | 
				
			|||
					 | 
				
			|||
					// #ifdef APP-NVUE || APP-PLUS || MP || QUICKAPP-WEBVIEW || QUICKAPP-WEBVIEW-HUAWEI || QUICKAPP-WEBVIEW-UNION | 
				
			|||
					this.generateCode(); | 
				
			|||
					// #endif | 
				
			|||
				} | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		methods: { | 
				
			|||
			SpecialTreatment (val) {//微信小程序渲染多个canvas特殊处理 | 
				
			|||
				// #ifdef MP-WEIXIN | 
				
			|||
					let obj = deepClone(val); | 
				
			|||
					this.id = obj.id = getUUid(); | 
				
			|||
					this.listCode = [obj] | 
				
			|||
				// #endif | 
				
			|||
			}, | 
				
			|||
			generateCode () { | 
				
			|||
				try{ | 
				
			|||
					const parameter = {...this.options,id: this.id,ctx: this}; | 
				
			|||
					QRCODE.BarCode(parameter,(res)=>{ | 
				
			|||
						this.$emit('generate',res) | 
				
			|||
					}) | 
				
			|||
				}catch(err){} | 
				
			|||
			}, | 
				
			|||
			async saveImg (){ | 
				
			|||
				try{ | 
				
			|||
					const res = await QRCODE.SaveImg({id: this.id,width: this.width,height: this.width,ctx: this}); | 
				
			|||
					return res | 
				
			|||
				}catch(e){} | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
</script> | 
				
			|||
@ -0,0 +1,84 @@ | 
				
			|||
<template> | 
				
			|||
    <view> | 
				
			|||
		<!-- #ifdef MP-WEIXIN  --> | 
				
			|||
		<canvas :canvas-id="item.id" :id="item.id" :style="{width:size,height: size}" v-for="(item,index) in listCode" :key="item.id" /> | 
				
			|||
		<!-- #endif --> | 
				
			|||
		 | 
				
			|||
		<!-- #ifndef MP-WEIXIN --> | 
				
			|||
		<canvas :canvas-id="id" :id="id" :style="{width:size,height: size}" /> | 
				
			|||
		<!-- #endif --> | 
				
			|||
	</view> | 
				
			|||
</template> | 
				
			|||
<script> | 
				
			|||
	import QRCODE from './index.js'; | 
				
			|||
	import { getUUid, deepClone } from './helper.js' | 
				
			|||
	export default { | 
				
			|||
		name: 'WQrcode', | 
				
			|||
		props:{ | 
				
			|||
			options:{ | 
				
			|||
				type: Object, | 
				
			|||
				required: true, | 
				
			|||
				default: () =>{ | 
				
			|||
					return { | 
				
			|||
						 | 
				
			|||
					} | 
				
			|||
				} | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		data () { | 
				
			|||
			return { | 
				
			|||
				listCode:[], | 
				
			|||
				id: getUUid(), | 
				
			|||
				size: null, | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		created() { | 
				
			|||
			this.size = this.options.size + 'rpx'; | 
				
			|||
			this.SpecialTreatment(this.options) | 
				
			|||
			this.$nextTick(()=>{ | 
				
			|||
				this.generateCode(); | 
				
			|||
			}) | 
				
			|||
		}, | 
				
			|||
		watch: { | 
				
			|||
			options:{ | 
				
			|||
				deep: true, | 
				
			|||
				handler (val) { | 
				
			|||
					this.size = val.size +'rpx'; | 
				
			|||
					this.SpecialTreatment(val) | 
				
			|||
					// #ifdef H5 | 
				
			|||
					setTimeout(()=>{// h5平台动态改变canvas大小 | 
				
			|||
						this.generateCode(); | 
				
			|||
					},50) | 
				
			|||
					// #endif | 
				
			|||
					 | 
				
			|||
					// #ifdef APP-NVUE || APP-PLUS || MP || QUICKAPP-WEBVIEW || QUICKAPP-WEBVIEW-HUAWEI || QUICKAPP-WEBVIEW-UNION | 
				
			|||
					this.generateCode(); | 
				
			|||
					// #endif | 
				
			|||
				} | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		methods: { | 
				
			|||
			SpecialTreatment (val) {//微信小程序渲染多个canvas特殊处理 | 
				
			|||
				// #ifdef MP-WEIXIN | 
				
			|||
					let obj = deepClone(val); | 
				
			|||
					this.id = obj.id = getUUid(); | 
				
			|||
					this.listCode = [obj] | 
				
			|||
				// #endif | 
				
			|||
			}, | 
				
			|||
			generateCode () { | 
				
			|||
				try{ | 
				
			|||
					const parameter = {...this.options,id: this.id,ctx: this}; | 
				
			|||
					QRCODE.QRCode(parameter,(res)=>{ | 
				
			|||
						this.$emit('generate',res) | 
				
			|||
					}) | 
				
			|||
				}catch(err){} | 
				
			|||
			}, | 
				
			|||
			async saveImg (){ | 
				
			|||
				try{ | 
				
			|||
					const res = await QRCODE.SaveImg({id: this.id,width: this.size,height: this.size,ctx: this}); | 
				
			|||
					return res | 
				
			|||
				}catch(e){} | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
</script> | 
				
			|||
@ -0,0 +1,199 @@ | 
				
			|||
<template> | 
				
			|||
	<view class="page"> | 
				
			|||
		<lf-nav title="会员码" bgColor="transparent" :spreadOut="false" titleColor="#fff" :showIcon="true"></lf-nav> | 
				
			|||
		<view class="bg-viewleft"></view> | 
				
			|||
		<view class="bg-viewright"></view> | 
				
			|||
		<view class="content"> | 
				
			|||
			<view class="top"> | 
				
			|||
				<view class="lf-flex"> | 
				
			|||
					<view class="avatar"> | 
				
			|||
						<image src="https://picsum.photos/200"></image> | 
				
			|||
					</view> | 
				
			|||
					<view class="phone">182****5380</view> | 
				
			|||
				</view> | 
				
			|||
				<view class="card"> | 
				
			|||
					<text class="lf-iconfont icon--1"></text> | 
				
			|||
				</view> | 
				
			|||
			</view> | 
				
			|||
			<view class="balance">余额 ¥1829.83</view> | 
				
			|||
			<view class="barcode"> | 
				
			|||
				<lf-barcode :options="config.bar"></lf-barcode> | 
				
			|||
			</view> | 
				
			|||
			<view class="qrcode"> | 
				
			|||
				<lf-qrcode :options="config.qrc"></lf-qrcode> | 
				
			|||
			</view> | 
				
			|||
			<view class="tips">{{ num }}s后自动刷新</view> | 
				
			|||
		</view> | 
				
			|||
	</view> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<script> | 
				
			|||
	import lfBarcode from '@/components/lf-code/lf-barcode.vue'; | 
				
			|||
	import lfQrcode from '@/components/lf-code/lf-qrcode.vue'; | 
				
			|||
	export default { | 
				
			|||
		components: { | 
				
			|||
			lfBarcode, | 
				
			|||
			lfQrcode | 
				
			|||
		}, | 
				
			|||
		data(){ | 
				
			|||
			return { | 
				
			|||
				config: { | 
				
			|||
					bar: { | 
				
			|||
						code: 'E01181016286106', | 
				
			|||
						color: '#000', // 条形码的颜色 | 
				
			|||
						bgColor: '#FFFFFF', // 背景色 | 
				
			|||
						width: 586, // 宽度 | 
				
			|||
						height: 210 // 高度 | 
				
			|||
					}, | 
				
			|||
					qrc: { | 
				
			|||
						code: "https://weixin.qq.com/g/AwYAAHO3aO4zlasEij6bLsk4hlZd5XNFkkBmqyS55mLPFxmn5c9PaI1omqLhd24fABCD23333", | 
				
			|||
						size: 352, // 二维码大小 | 
				
			|||
						level: 4, //等级 0~4 | 
				
			|||
						bgColor: '#FFFFFF', //二维码背景色 默认白色 | 
				
			|||
						// border: { | 
				
			|||
						// 	color: ['#8A2387', '#F27121'], //边框颜色支持渐变色 | 
				
			|||
						// 	lineWidth: 3, //边框宽度 | 
				
			|||
						// }, | 
				
			|||
						// img: '/static/logo.png', //图片 | 
				
			|||
						// iconSize: 40, //二维码图标的大小 | 
				
			|||
						color: '#000000', //边框颜色支持渐变色 | 
				
			|||
					} | 
				
			|||
				}, | 
				
			|||
				timer: null, | 
				
			|||
				num: 90 | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		onLoad(){ | 
				
			|||
			this.refreshCode(); | 
				
			|||
		}, | 
				
			|||
		onUnload(){ | 
				
			|||
			if(this.timer){ | 
				
			|||
				clearInterval(this.timer); | 
				
			|||
				this.timer = null; | 
				
			|||
			} | 
				
			|||
		}, | 
				
			|||
		methods: { | 
				
			|||
			// rpx 转 px | 
				
			|||
			rpxTransformPx(num){ | 
				
			|||
				let systemInfo = uni.getSystemInfoSync(); | 
				
			|||
				let pxWidth = num / 750 * systemInfo.windowWidth; | 
				
			|||
				return pxWidth; | 
				
			|||
			}, | 
				
			|||
			// 刷新code | 
				
			|||
			refreshCode(){ | 
				
			|||
				if(this.timer){ | 
				
			|||
					clearInterval(this.timer); | 
				
			|||
					this.timer = null; | 
				
			|||
				} | 
				
			|||
				this.timer = setInterval(() => { | 
				
			|||
					this.num--; | 
				
			|||
					if(this.num <= 0){ | 
				
			|||
						clearInterval(this.timer); | 
				
			|||
						this.timer = null; | 
				
			|||
						this.num = 90; | 
				
			|||
						this.refreshCode(); // 重新执行 | 
				
			|||
					} | 
				
			|||
				}, 1000); | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
</script> | 
				
			|||
 | 
				
			|||
<style> | 
				
			|||
	page{ | 
				
			|||
		overflow: hidden; | 
				
			|||
	} | 
				
			|||
</style> | 
				
			|||
<style lang="scss" scoped="scoped"> | 
				
			|||
	.page{ | 
				
			|||
		width: 100vw; | 
				
			|||
		height: 100vh; | 
				
			|||
		background: linear-gradient(270deg, #187B7A 0%, #2FAAA7 100%, #22A2A0 100%); | 
				
			|||
		position: relative; | 
				
			|||
		overflow: hidden; | 
				
			|||
		.bg-viewleft{ | 
				
			|||
			position: absolute; | 
				
			|||
			left: -100rpx; | 
				
			|||
			top: 59rpx; | 
				
			|||
			width: 585rpx; | 
				
			|||
			height: 585rpx; | 
				
			|||
			border-radius: 50%; | 
				
			|||
			background-color: rgba(255,255,255,0.04); | 
				
			|||
		} | 
				
			|||
		.bg-viewright{ | 
				
			|||
			position: absolute; | 
				
			|||
			right: -38rpx; | 
				
			|||
			top: 102rpx; | 
				
			|||
			width: 127rpx; | 
				
			|||
			height: 127rpx; | 
				
			|||
			border-radius: 50%; | 
				
			|||
			background-color: rgba(255,255,255,0.04); | 
				
			|||
		} | 
				
			|||
		.content{ | 
				
			|||
			position: absolute; | 
				
			|||
			top: 260rpx; | 
				
			|||
			left: calc(50% - 343rpx); | 
				
			|||
			width: 686rpx; | 
				
			|||
			height: 986rpx; | 
				
			|||
			background: #FFFFFF; | 
				
			|||
			border-radius: 20rpx; | 
				
			|||
			.top{ | 
				
			|||
				display: flex; | 
				
			|||
				justify-content: space-between; | 
				
			|||
				padding: 0 40rpx; | 
				
			|||
				width: 100%; | 
				
			|||
				box-sizing: border-box; | 
				
			|||
				align-items: center; | 
				
			|||
				margin-top: -20rpx; | 
				
			|||
				.avatar{ | 
				
			|||
					width: 160rpx; | 
				
			|||
					height: 160rpx; | 
				
			|||
					border-radius: 50%; | 
				
			|||
					background-color: #FFFFFF; | 
				
			|||
					box-shadow: 0rpx 2rpx 8rpx 1rpx rgba(21, 113, 110, 0.2); | 
				
			|||
					border: 5rpx solid #FFFFFF; | 
				
			|||
					display: flex; | 
				
			|||
					justify-content: center; | 
				
			|||
					align-items: center; | 
				
			|||
					margin-right: 20rpx; | 
				
			|||
					&>image{ | 
				
			|||
						width: 148rpx; | 
				
			|||
						height: 148rpx; | 
				
			|||
						border-radius: 50%; | 
				
			|||
					} | 
				
			|||
				} | 
				
			|||
				.phone{ | 
				
			|||
					font-size: 36rpx; | 
				
			|||
					font-weight: bold; | 
				
			|||
					color: #15716E; | 
				
			|||
				} | 
				
			|||
				.card{ | 
				
			|||
					padding: 10rpx 20rpx; | 
				
			|||
					&>text{ | 
				
			|||
						font-size: 40rpx; | 
				
			|||
						color: #15716E; | 
				
			|||
					} | 
				
			|||
				} | 
				
			|||
			} | 
				
			|||
			.balance{ | 
				
			|||
				font-size: 32rpx; | 
				
			|||
				color: #555555; | 
				
			|||
				text-align: center; | 
				
			|||
				font-weight: bold; | 
				
			|||
				margin-top: 60rpx; | 
				
			|||
				line-height: 1; | 
				
			|||
			} | 
				
			|||
			.barcode, .qrcode{ | 
				
			|||
				display: flex; | 
				
			|||
				justify-content: center; | 
				
			|||
				margin-top: 30rpx; | 
				
			|||
			} | 
				
			|||
			.tips{ | 
				
			|||
				font-size: 24rpx; | 
				
			|||
				color: #777777; | 
				
			|||
				text-align: center; | 
				
			|||
				margin-top: 30rpx; | 
				
			|||
			} | 
				
			|||
		} | 
				
			|||
	} | 
				
			|||
</style> | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue