微信小程序-增加隐私协议弹窗

发布于:2023-09-16 ⋅ 阅读:(161) ⋅ 点赞:(0)

真的加了非常之久,非常简单的一个功能,但是因为之前没弄过,加上系统有点bug,软件也有点抽风......

  1. 在微信后台配置-更新用户隐私协议信息
  2. 增加 "__usePrivacyCheck__" : true, 9月15号之后不加也行,好象今天刚刚好9月15
     "mp-weixin" : {
            "appid" : "xxxxxxxxxx",
            "__usePrivacyCheck__" : true,
    
    
    "permission": {
        "scope.userLocation": {
            "desc": "提供准确的定位服务"
        }
    },
    "requiredPrivateInfos": [
        "getLocation"
    ]

  3. 微信开发者工具的基础库切换到>3.0(本地运行和发布时都要改,不改不弹窗)
  4. 首页增加隐私协议弹窗控件,加在最后一个view的上边
    <!-- #ifdef MP-WEIXIN -->
    <ws-wx-privacy id="privacy-popup"></ws-wx-privacy>
    <!-- #endif -->

  5. 增加隐私协议组件,增加到components文件夹下

  6. ws-wx-privacy.vue代码:
     

    <template>
    	<uni-popup id="privacy" type="center" ref="privacyPopup" :maskClick="false">
    		<view class="ws-privacy-popup" :style="rootStyle">
    			<view class="ws-privacy-popup__header">
    				<!--标题-->
    				<view class="ws-picker__title">{{ title }}</view>
    			</view>
    			<view class="ws-privacy-popup__container">
    				<text>{{ desc }}</text>
    				<text class="ws-privacy-popup__container-protocol" :style="protocolStyle"
    					@click="openPrivacyContract">{{ protocol }}</text>
    				<text>{{ subDesc }}</text>
    			</view>
    			<view class="ws-privacy-popup__footer">
    				<button class="is-agree" :style="agreeStyle" id="agree-btn" open-type="agreePrivacyAuthorization"
    					@agreeprivacyauthorization="handleAgree">
    					{{agreeText}}
    				</button>
    				<button class="is-disagree" id="disagree-btn" @click="handleDisagree">
    					{{disagreeText}}
    				</button>
    			</view>
    		</view>
    	</uni-popup>
    </template>
    <script>
    	import {
    		getContext,
    		getComponent
    	} from './util'
    	const privacyResolves = new Set() // onNeedPrivacyAuthorization的reslove
    
    	let privacyHandler = null
    	// 注册监听
    	if (uni.onNeedPrivacyAuthorization) {
    		console.log('register uni.onNeedPrivacyAuthorization')
    		uni.onNeedPrivacyAuthorization((resolve) => {
    			if (typeof privacyHandler === 'function') {
    				privacyHandler(resolve)
    			}
    		})
    	}
    
    	export default {
    		name: 'wsWxPrivacy',
    		emits: ['disagree', 'agree'],
    		props: {
    			// 标题
    			title: {
    				type: String,
    				default: '用户隐私保护提示'
    			},
    			// 描述
    			desc: {
    				type: String,
    				default: '感谢您使用本应用,您使用本应用的服务之前请仔细阅读并同意'
    			},
    			// 隐私保护指引名称
    			protocol: {
    				type: String,
    				default: '《用户隐私保护指引》'
    			},
    			// 子描述
    			subDesc: {
    				type: String,
    				default: '。当您点击同意并开始使用产品服务时,即表示你已理解并同意该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用相应服务。'
    			},
    			/**
    			 * 控制是否可以点击不同意按钮并显示提示。
    			 * 如果设置为 true,用户可以点击不同意按钮执行后续逻辑。
    			 * 如果设置为 false,点击不同意按钮会显示提示信息,但不会执行后续逻辑。
    			 * 默认为 true
    			 */
    			disagreeEnabled: {
    				type: Boolean,
    				default: true, // 默认为可以点击
    			},
    			/**
    			 * 配置不同意按钮的提示消息内容。
    			 */
    			disagreePromptText: {
    				type: String,
    				default: '请先仔细阅读并同意隐私协议', // 默认提示消息
    			},
    			// 拒绝按钮文字
    			disagreeText: {
    				type: String,
    				default: '不同意'
    			},
    			// 同意按钮文字
    			agreeText: {
    				type: String,
    				default: '同意并继续'
    			},
    			// 自定义背景颜色
    			bgColor: {
    				type: String,
    				default: ''
    			},
    			// 自定义主题颜色(控制同意按钮和隐私协议名称的颜色)
    			themeColor: {
    				type: String,
    				default: ''
    			}
    		},
    		computed: {
    			rootStyle() {
    				if (this.bgColor) {
    					return `background:${this.bgColor}`
    				} else {
    					return ''
    				}
    			},
    			protocolStyle() {
    				if (this.themeColor) {
    					return `color:${this.themeColor}`
    				} else {
    					return ''
    				}
    			},
    			agreeStyle() {
    				if (this.themeColor) {
    					return `background:${this.themeColor}`
    				} else {
    					return ''
    				}
    			}
    		},
    		created() {
    			privacyHandler = (resolve) => {
    				const context = getContext()
    				const privacyPopup = getComponent(context, '#privacy-popup')
    				if (privacyPopup) {
    					const privacy = getComponent(privacyPopup, '#privacy')
    					if (privacy && privacy.open) {
    						uni.hideLoading()
    						privacy.open()
    					}
    				}
    				privacyResolves.add(resolve)
    			}
    		},
    		methods: {
    			/**
    			 * 打开隐私协议
    			 */
    			openPrivacyContract() {
    				wx.openPrivacyContract({
    					success: (res) => {
    						console.log('openPrivacyContract success')
    					},
    					fail: (res) => {
    						console.error('openPrivacyContract fail', res)
    					}
    				})
    			},
    
    			/**
    			 * 拒绝隐私协议
    			 */
    			handleDisagree() {
    				uni.setStorageSync('mpweixin_disagree_authorization', 1) 
    				if (this.disagreeEnabled) {
    					this.$refs.privacyPopup.close()
    					privacyResolves.forEach((resolve) => {
    						resolve({
    							event: 'disagree'
    						})
    					})
    					privacyResolves.clear()
    					this.$emit('disagree')
    				} else {
    					uni.showToast({
    						icon: 'none',
    						title: this.disagreePromptText
    					})
    				}
    
    			},
    
    			/**
    			 * 同意隐私协议
    			 */
    			handleAgree() {
    				uni.setStorageSync('mpweixin_disagree_authorization', 0) 
    				this.$refs.privacyPopup.close()
    				privacyResolves.forEach((resolve) => {
    					resolve({
    						event: 'agree',
    						buttonId: 'agree-btn'
    					})
    				})
    				privacyResolves.clear()
    				this.$emit('agree')
    			}
    		}
    	}
    </script>
    <style lang="scss" scoped>
    	.ws-privacy-popup {
    		width: 600rpx;
    		padding: 48rpx;
    		box-sizing: border-box;
    		overflow: hidden;
    		width: 560rpx;
    		background: linear-gradient(180deg, #e5edff 0%, #ffffff 100%);
    		border-radius: 24rpx;
    
    		&__header {
    			display: flex;
    			align-items: center;
    			justify-content: center;
    			width: 100%;
    			height: 52rpx;
    			font-size: 36rpx;
    			font-family: PingFangSC-Medium, PingFang SC;
    			font-weight: 550;
    			color: #1a1a1a;
    			line-height: 52rpx;
    			margin-bottom: 48rpx;
    		}
    
    		&__container {
    			width: 100%;
    			box-sizing: border-box;
    			font-size: 28rpx;
    			font-family: PingFangSC-Regular, PingFang SC;
    			font-weight: 400;
    			color: #333333;
    			line-height: 48rpx;
    			margin-bottom: 48rpx;
    
    			&-protocol {
    				font-weight: 550;
    				color: #4D80F0;
    			}
    		}
    
    		&__footer {
    			display: flex;
    			flex-direction: column;
    
    			.is-disagree,
    			.is-agree {
    				width: 100%;
    				height: 88rpx;
    				background: #ffffff;
    				border-radius: 44rpx;
    				font-size: 32rpx;
    				font-family: PingFangSC-Regular, PingFang SC;
    				font-weight: 400;
    				color: #666666;
    			}
    
    			.is-agree {
    				background: #4D80F0;
    				color: #ffffff;
    				margin-bottom: 18rpx;
    			}
    
    			button {
    				border: none;
    				outline: none;
    
    				&::after {
    					border: none;
    				}
    			}
    		}
    	}
    </style>

  7. util.js文件代码:
     

    /**
     * 获取当前页面上下文
     * @returns 页面对象
     */
    export function getContext() {
    	// eslint-disable-next-line no-undef
    	const pages = getCurrentPages()
    	return pages[pages.length - 1]
    }
    
    /**
     * 获取上下文中指定节点组件
     * @param context 选择器的选择范围,可以传入自定义组件的 this 作为上下文
     * @param selector 自定义节点选择器
     */
    export function getComponent(context, selector ) {
    	let component = null
    	// #ifdef H5
    	context.$children.forEach((child) => {
    		if (`#${child.$attrs.id}` === selector) {
    			component = child
    		} else if (child.$children && child.$children.length) {
    			if (getComponent(child, selector)) {
    				component = getComponent(child, selector)
    			}
    		}
    		if (component) {
    			return component
    		}
    	})
    	// #endif
    	// #ifdef MP-WEIXIN
    	component = context.selectComponent && context.selectComponent(selector) && context.selectComponent(selector).$vm
    	// #endif
    
    	// #ifdef MP-ALIPAY
    	const alipay = context.$children ? context.$children : context.$vm && context.$vm.$children ? context.$vm
    		.$children : []
    	component = alipay.find((component) => {
    		return `#${component.$scope.props.id}` === selector
    	})
    	// #endif
    	// #ifdef APP-PLUS
    	const app = context.$children ? context.$children : context.$vm && context.$vm.$children ? context.$vm.$children :
    	[]
    	component = app.find((component) => {
    		return `#${component.$attrs.id}` === selector
    	})
    	// #endif
    	return component
    }

  8. 一般到这里再次运行就可以成功了,成功的隐私弹窗:

  9. 如果到这里了还没有成功!!!再来,检查一下弹窗控件对不对
    看一下components 文件夹下边有没有uni-popup文件夹,如果有,一定要删掉!!!
    否则会报错,​easycom组件冲突:[@/components/uni-popup/uni-popup.vue,@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue]​
    如果有页面引用到了,引用的代码也删掉

  10. Hbuilder x 工具更新到最新版本,导入最新版本uni-popup组件
    点击插件安装:

  11. 找到 uni-popup插件,点击安装

  12. 再次运行,就会弹隐私协议的窗口啦

     

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到