评论

小程序隐私弹框组件

根据官方提供的文档及demo提供以下见解,希望对部分开发者有帮助吧!

一、前言

文章这个编辑器真的太恶心了

代码块不仅不能设置缩进还不能使用tab增加缩进只能空格一个一个打

调个字体和代码格式太TM麻烦了

2023.08.22更新:

以下指南中涉及的 getPrivacySetting、onNeedPrivacyAuthorization、requirePrivacyAuthorize 等接口目前可以正常接入调试。调试说明:

  1. 在 2023年9月15号之前,在 app.json 中配置 __usePrivacyCheck__: true 后,会启用隐私相关功能,如果不配置或者配置为 false 则不会启用。
  2. 在 2023年9月15号之后,不论 app.json 中是否有配置 __usePrivacyCheck__,隐私相关功能都会启用

首先了解官方提供demo:

demo1: 演示使用 wx.getPrivacySetting 和 <button open-type="agreePrivacyAuthorization"> 在首页处理隐私弹窗逻辑 https://developers.weixin.qq.com/s/gi71sGm67hK0

demo2: 演示使用 wx.onNeedPrivacyAuthorization 和 <button open-type="agreePrivacyAuthorization"> 在多个页面处理隐私弹窗逻辑,同时演示了如何处理多个隐私接口同时调用。 https://developers.weixin.qq.com/s/4X7yyGmQ7EKp

demo3: 演示 wx.onNeedPrivacyAuthorizationwx.requirePrivacyAuthorize<button open-type="agreePrivacyAuthorization"> 和 <input type="nickname"> 组件如何结合使用 https://developers.weixin.qq.com/s/jX7xWGmA7UKa

demo4: 演示使用 wx.onNeedPrivacyAuthorization 和 <button open-type="agreePrivacyAuthorization"> 在多个 tabBar 页面处理隐私弹窗逻辑。 https://developers.weixin.qq.com/s/g6BWZGmt7XK9

  • 小程序后台隐私协议添加对应隐私协议(例如:剪贴板、手机号授权等)协议更新后有一定时间的缓存才能测试(大概是在半天之后可以测试)优先处理添加协议 (如果之前小程序已经添加过对应的协议,则需要重新提交审核同步信息才会返回正常用来测试)
  • 基础库设置3.23.3及以上 (微信版本:iOS 8.0.36、安卓 8.0.35会携带此基础库版本)
  • app.json文件内这个配置__usePrivacyCheck__属性为true (uniapp开发参考下图) 
  • 开发工具清除全部缓存之后重新编译、手机微信下拉删除最近小程序等进行隐私协议同步信息获取测试

二、关于小程序隐私保护指引设置的公告

为规范开发者的用户个人信息处理行为,保障用户的合法权益,自2023年9月15日起,对于涉及处理用户个人信息的小程序开发者,
微信要求,仅当开发者主动向平台同步用户已阅读并同意了小程序的隐私保护指引等信息处理规则后,方可调用微信提供的隐私接口。
开发者首先需确定小程序是否涉及处理用户个人信息,如涉及,则需配置用户隐私授权弹窗,
且仅有在平台《小程序用户隐私保护指引》中声明了所处理的用户个人信息,才可以调用平台提供的对应接口或组件。

三、设置《小程序用户隐私保护指引》

四、填写《小程序用户隐私保护指引》

只有在指引中声明所处理的用户个人信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将无法调用成功。


五、配置用户隐私授权弹窗 (触发方式:隐私API、组件)


1.了解隐私协议所需相关API

01.wx.requirePrivacyAuthorize() 用于模拟隐私接口调用

02.wx.openPrivacyContract() 用于打开下面封装好隐私弹框中的隐私协议

03.wx.onNeedPrivacyAuthorization() 用于监听用户是否吊起相关的隐私协议

04.wx.getPrivacySetting() 用于查询微信侧记录用户隐私协议状态

基本流程为:03 -----> 04 -----> 02

2.封装微信侧用户隐私协议状态

//获取微信侧同步的用户隐私协议开关
function getPrivacySetting(callback){
  if(wx.getPrivacySetting){
    wx.getPrivacySetting({
      success: result => {
        console.log(result,"同步信息结果") // 返回结果为: result = { needAuthorization: true/false, privacyContractName: '《xxx隐私保护指引》' }
        if (result.needAuthorization) {
          // 需要弹出隐私协议
          console.log("获取微信储存的用户协议同步信息-用户未同意,请弹框处理")
          callback && callback(result);
        } else {
          console.log("获取微信储存的用户协议同步信息-用户已同意,请忽略")
        }
      },
      fail: () => {},
      complete: () => {}
    })
  }
}

3.封装隐私协议弹框放置全局组件中

全局组件-wxml

  
    用户隐私保护提示
    
       
         亲爱的用户,感谢您的信任!您使用本小程序提供的产品服务前应当阅读并同意
	   
	   
  	      {{urlTitle}}
  	   
        当您点击同意并开始使用产品服务时,即表示你已理解并同息该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用本小程序提供的相关产品及服务。 
      
      
        
          不同意
          同意
        
      
    


全局组件-JS

JS//引入相关模块
const { getPrivacySetting } = require("../utils/utils")
//设置协议回调、关闭回调数组变量
let privacyHandler
let privacyResolves = new Set()
let closeOtherPagePopUpHooks = new Set()
//注册并监听隐私API调用
if (wx.onNeedPrivacyAuthorization) {
  wx.onNeedPrivacyAuthorization(resolve => {
    //获取用户微信侧同步结果
    getPrivacySetting(result=>{
      console.log(result,"同步信息结果") // 返回结果为: result = { needAuthorization: true/false, privacyContractName: '《xxx隐私保护指引》' }
      if (result.needAuthorization) {
        // 需要弹出隐私协议
        if (typeof privacyHandler === 'function') privacyHandler(resolve,result)
        console.log("获取微信储存的用户协议同步信息-用户未同意,请弹框处理-页面")
      }
    })
  })
}
//处理关闭页面其他弹框
const closeOtherPagePopUp = (closePopUp) => {
  closeOtherPagePopUpHooks.forEach(hook => {
    if (closePopUp !== hook) {
      hook()
    }
  })
}
Component({
  options: {
    styleIsolation: 'shared',
    multipleSlots: true
  },
  data: {
    urlTitle: "",
    privacyFlag: false,
    height: 0,
  },
  lifetimes: {
    attached: function() {
      const closePopUp = () => {
        this.disPopUp()
      }
      privacyHandler = (resolve,result) => {
        this.setUrlTitle(result);
        console.log(result,"999999")
        privacyResolves.add(resolve)
        this.popUp()
        // 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
        closeOtherPagePopUp(closePopUp)
      }
      
      closeOtherPagePopUpHooks.add(closePopUp)


      this.closePopUp = closePopUp
    },
    detached: function() {
      closeOtherPagePopUpHooks.delete(this.closePopUp)
    }
  },
  methods: {
    //处理隐私弹框内展示的隐私协议标题
    setUrlTitle(result){
      this.setData({urlTitle:result.privacyContractName})
    },
    //用户同意相关协议
    handleAgree(e) {
      this.disPopUp()
      // 这里演示了同时调用多个wx隐私接口时要如何处理:让隐私弹窗保持单例,
点击一次同意按钮即可让所有pending中的wx隐私接口继续执行 (看page/index/index中的 wx.getClipboardData 和 wx.startCompass)
      privacyResolves.forEach(resolve => {
        resolve({
          event: 'agree',
          buttonId: 'agree-btn'
        })
      })
      privacyResolves.clear()
      this.triggerEvent('handleAgree', {result:true});
    },
    //用户拒绝相关协议
    handleDisagree(e) {
      this.disPopUp()
      privacyResolves.forEach(resolve => {
        resolve({
          event: 'disagree',
        })
      })
      privacyResolves.clear()
      this.triggerEvent('handleAgree', {result:true});
    },
    //打开隐私弹框
    popUp() {
      if (this.data.privacyFlag === false) {
        this.setData({
          privacyFlag: true
        })
      }
    },
    //关闭隐私弹框
    disPopUp() {
      if (this.data.privacyFlag === true) {
        this.setData({
          privacyFlag: false
        })
      }
    },
    //打开微信提供的小程序侧隐私协议
    openPrivacyContract() {
      wx.openPrivacyContract({
        success: res => {
          console.log('openPrivacyContract success')
        },
        fail: res => {
          console.error('openPrivacyContract fail', res)
        }
      })
    },
    checkPrivacyStatus() {
      let that = this;
      getPrivacySetting(result=>{
        if (result.needAuthorization) {
          that.setUrlTitle(result);
          that.popUp();
        } else {
          console.log("微信侧已记录用户同意");
        }
      })
    }
  }
})


父组件监听全局隐私弹框时间回调

父组件-wxml


父组件-JS
//隐私协议弹框按钮回调
  handleAgree(event){
    let that = this;
    console.log(event);
    let {result} = event.detail;
    // result 根据用户选择可处理后续相关逻辑
    true 用户同意相关隐私  例如:因昵称组件弹出的框 为true之后就可将昵称组件设置为聚焦状态
    false 用户拒绝 例如:音视频组件  用户拒绝之后可返回上级页面、继续弹框进行处理等
  },


4.app.json中引入全局组件:"privacy-popup": "/components/privacyPopup"

5.全局使用(隐私弹框)

全局隐私弹框相关代码如下:

首页wxml引入组件



首页onReady时触发检测隐私弹框逻辑

that.selectComponent("#privacyPop") && that.selectComponent("#privacyPop").checkPrivacyStatus();


6.按需使用(隐私弹框)进入单个隐私页面时优先检测(手机号授权API触发隐私弹框)

6-1.1.引入全局组件到手机号授权页面:
6-1.2.页面onReady的时候开始检测:that.selectComponent("#privacyPop") && that.selectComponent("#privacyPop").checkPrivacyStatus();


6-2.1.在用户点击按钮即将吊起隐私弹框时使用如下代码:
getPrivacySetting(result=>{
  if (result.needAuthorization) {
    // 需要弹出隐私协议
    that.selectComponent("#privacyPop") && that.selectComponent("#privacyPop").setUrlTitle(result);
    console.log("获取微信储存的用户协议同步信息-用户未同意,请弹框处理")
  } else {
    console.log("获取微信储存的用户协议同步信息-用户已同意,请忽略")
   //走隐私允许之后的逻辑
  }
})


六、清空历史同步状态

1.微信下拉---最近---最近使用的小程序

2.开发工具---清除模拟器缓存---清除全部数据/授权数据

七、常见错误说明

  1. { "errMsg": "A:fail api scope is not declared in the privacy agreement", "errno": 112 } 使用到了 A 隐私接口,但是开发者未在[mp后台-设置-服务内容声明-用户隐私保护指引]中声明收集 A 接口对应的隐私类型。
  2. 还有个114的忘记统计是啥原因了(希望官方尽快能把错误码及对应的原因贴出来)


最后一次编辑于  2023-10-12  
点赞 4
收藏
评论

1 个评论

  • 周quan
    周quan
    2023-10-25

    卧槽,这比官网文档写的好太多了。官网文档看的我一愣一愣的。如果在监听还有组件上画一个逻辑流程图就更棒了

    2023-10-25
    赞同 1
    回复
登录 后发表内容