ToB企服应用市场:ToB评测及商务社交产业平台

标题: 小程序添加隐私保护指引弹框(包罗设置隐私保护指引方法) [打印本页]

作者: 美食家大橙子    时间: 2024-8-13 02:05
标题: 小程序添加隐私保护指引弹框(包罗设置隐私保护指引方法)
实现效果:


  
前言

从 2023 年 9 月 15 日起必须用户点击同意隐私保护政策并同步给微信之后,开发者才可以调用微信提供的隐私接口。

   9 月 15 号之后涉及隐私的接口将无法利用,严肃影响业务逻辑。开发者要做的就是做一个弹窗提示用户阅读隐私保护指引,在用户点击“同意”按钮之后同步给微信,之后微信才允许开发者调用隐私接口,并且还会检测用户是否点击了按钮。
  一、 涉及到利用了隐私接口的小程序必须在「小程序管理后台」设置《小程序用户隐私保护指引》,微信一共提供了 4 个接口给开发者利用,分别是:

wx.getPrivacySetting:查询隐私授权情况
wx.openPrivacyContract:跳转到隐私协议页面
wx.onNeedPrivacyAuthorization:监听隐私接口需要用户授权变乱
wx.requirePrivacyAuthorize :模拟隐私接口调用,并触发隐私弹窗逻辑
其中隐私保护接口有哪些?
隐私接口链接:https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/miniprogram-intro.html

凡是涉及到以上隐私接口的,必须添加隐私弹框,方可利用
二、 设置隐私协议弹框组件

利用uniapp开发小程序,在项目根目录下创建components组件文件夹,创建组件xc-privacyPopup(组件名称可以自己界说)

在xc-privacyPopup.vue文件中,添加如下代码:
  1. <template>
  2.         <view v-if="showPrivacy" :class="privacyClass">
  3.                 <view :class="contentClass">
  4.                         <view class="title">用户隐私保护指引</view>
  5.                         <view class="des">
  6.                                 感谢您选择使用xxxx小程序,我们非常重视您的个人信息安全和隐私保护。使用我们的产品前,请您仔细阅读“
  7.                                 <text class="link" @tap="openPrivacyContract">{{privacyContractName}} </text>”,
  8.                                 如您同意此隐私保护指引,请点击同意按钮,开始使用此小程序,我们将尽全力保护您的个人信息及合法权益,感谢您的信任!<br />
  9.                         </view>
  10.                         <view class="btns">
  11.                                 <button class="item reject" @click="exitMiniProgram">拒绝</button>
  12.                                 <button id="agree-btn" class="item agree" open-type="agreePrivacyAuthorization"
  13.                                         @agreeprivacyauthorization="handleAgreePrivacyAuthorization">同意</button>
  14.                         </view>
  15.                 </view>
  16.         </view>
  17. </template>
  18. <script>
  19.         export default {
  20.                 name: 'PrivacyPopup',
  21.                 data() {
  22.                         return {
  23.                                 isRead: false,
  24.                                 showPrivacy: false,
  25.                                 privacyContractName: '',
  26.                                 resolvePrivacyAuthorization: null,
  27.                         };
  28.                 },
  29.                 props: {
  30.                         position: {
  31.                                 type: String,
  32.                                 default: 'center'
  33.                         }
  34.                 },
  35.                 computed: {
  36.                         privacyClass() {
  37.                                 return this.position === 'bottom' ? 'privacy privacy-bottom' : 'privacy';
  38.                         },
  39.                         contentClass() {
  40.                                 return this.position === 'bottom' ? 'content content-bottom' : 'content';
  41.                         }
  42.                 },
  43.                 mounted() {
  44.                         if (uni.onNeedPrivacyAuthorization) {
  45.                                 uni.onNeedPrivacyAuthorization((resolve) => {
  46.                                         this.resolvePrivacyAuthorization = resolve;
  47.                                 });
  48.                         }
  49.                         if (uni.getPrivacySetting) {
  50.                                 uni.getPrivacySetting({
  51.                                         success: (res) => {
  52.                                                 if (res.needAuthorization) {
  53.                                                         this.privacyContractName = res.privacyContractName;
  54.                                                         this.showPrivacy = true;
  55.                                                 } else {
  56.                                                         this.showPrivacy = false;
  57.                                                 }
  58.                                         },
  59.                                 });
  60.                         }
  61.                 },
  62.                 methods: {
  63.                         openPrivacyContract() {
  64.                                 uni.openPrivacyContract({
  65.                                         success: () => {
  66.                                                 this.isRead = true;
  67.                                         },
  68.                                         fail: () => {
  69.                                                 uni.showToast({
  70.                                                         title: '遇到错误',
  71.                                                         icon: 'error',
  72.                                                 });
  73.                                         },
  74.                                 });
  75.                         },
  76.                         exitMiniProgram() {
  77.                                 // uni.navigateBack();
  78.                                 wx.exitMiniProgram();
  79.                         },
  80.                         handleAgreePrivacyAuthorization() {
  81.                                 this.showPrivacy = false;
  82.                                 this.$emit('allowPrivacy');
  83.                                 if (typeof this.resolvePrivacyAuthorization === 'function') {
  84.                                         this.resolvePrivacyAuthorization({
  85.                                                 buttonId: 'agree-btn',
  86.                                                 event: 'agree',
  87.                                         });
  88.                                 }
  89.                         },
  90.                         closePrivacy() {
  91.                                 this.showPrivacy = false;
  92.                         }
  93.                 },
  94.         };
  95. </script>
  96. <style scoped>
  97.         .privacy {
  98.                 position: fixed;
  99.                 top: 0;
  100.                 right: 0;
  101.                 bottom: 0;
  102.                 left: 0;
  103.                 background: rgba(0, 0, 0, .5);
  104.                 z-index: 9999999;
  105.                 display: flex;
  106.                 align-items: center;
  107.                 justify-content: center;
  108.         }
  109.         .privacy-bottom {
  110.                 align-items: flex-end;
  111.         }
  112.         .content {
  113.                 width: 632rpx;
  114.                 padding: 48rpx;
  115.                 box-sizing: border-box;
  116.                 background: #fff;
  117.                 border-radius: 16rpx;
  118.         }
  119.         .content-bottom {
  120.                 position: absolute;
  121.                 bottom: 0;
  122.                 width: 96%;
  123.                 padding: 36rpx;
  124.                 padding-bottom: constant(safe-area-inset-bottom);
  125.                 padding-bottom: env(safe-area-inset-bottom);
  126.                 border-radius: 16rpx 16rpx 0 0;
  127.         }
  128.         .content .title {
  129.                 text-align: center;
  130.                 color: #333;
  131.                 font-weight: bold;
  132.                 font-size: 32rpx;
  133.         }
  134.         .content .des {
  135.                 font-size: 26rpx;
  136.                 color: #666;
  137.                 margin-top: 40rpx;
  138.                 text-align: justify;
  139.                 line-height: 1.6;
  140.         }
  141.         .content .des .link {
  142.                 color: #1989ff;
  143.                 text-decoration: underline;
  144.         }
  145.         .btns {
  146.                 margin-top: 48rpx;
  147.                 margin-bottom: 12rpx;
  148.                 display: flex;
  149.         }
  150.         .btns .item {
  151.                 width: 200rpx;
  152.                 height: 72rpx;
  153.                 overflow: visible;
  154.                 display: flex;
  155.                 align-items: center;
  156.                 justify-content: center;
  157.                 /* border-radius: 16rpx; */
  158.                 box-sizing: border-box;
  159.                 border: none !important;
  160.         }
  161.         .btns .reject {
  162.                 background: #f4f4f5;
  163.                 color: #1989ff;
  164.                 font-size: 14px;
  165.                 background: #edf5fe;
  166.                 font-weight: 300;
  167.                 margin-right: 16rpx;
  168.         }
  169.         .btns .agree {
  170.                 width: 200rpx;
  171.                 background: #1989ff;
  172.                 color: #fff;
  173.                 font-size: 16px;
  174.         }
  175.         .privacy-bottom .btns .agree {
  176.                 width: 440rpx;
  177.         }
  178. </style>
复制代码
三、在页面中利用协议弹窗组件

在页面中直接引用<xc-privacyPopup ref=“privacyComponent” position=“center” @allowPrivacy=“allowPrivacy”>即可
1、平凡页面利用协议弹窗:
  1. <template>
  2.         <view>
  3.                 <!-- 用户隐私保护指引 -->
  4.                 <xc-privacyPopup ref="privacyComponent" position="center"></xc-privacyPopup>
  5.         </view>
  6. </template>
  7. <script>
  8.         export default {
  9.                 data() {
  10.                         return {};
  11.                 }
  12.         }
  13. </script>
  14. <style lang="scss" scoped>
  15. </style>
复制代码
2、存在条件判断的页面利用协议弹窗:
  1. <template>
  2.         <view>
  3.                 <!-- 用户隐私保护指引 -->
  4.                 <xc-privacyPopup ref="privacyComponent" position="center" @allowPrivacy="allowPrivacy"></xc-privacyPopup>
  5.         </view>
  6. </template>
  7. <script>
  8.         export default {
  9.                 data() {
  10.                         return {};
  11.                 },
  12.                 onLoad() {},
  13.                 onShow() {
  14.                         // 查询隐私协议
  15.                         wx.getPrivacySetting({
  16.                                 success: res => {
  17.                                         if (!res.needAuthorization) {
  18.                                                 this.$refs.privacyComponent.closePrivacy();
  19.                                                 // 查询授权,针对有tab切换的页面,可以在onshow中查询隐私授权状态,判断在tab切换后是否需要关闭授权弹框
  20.                                                 console.log('已经同意隐私授权,不需要再次授权')
  21.                                         }
  22.                                 },
  23.                                 fail: () => {},
  24.                                 complete: () => {}
  25.                         })
  26.                 },
  27.                 methods: {
  28.                         // 同意隐私协议
  29.                         allowPrivacy() {
  30.                                 // 同意隐私协议触发事件,有些接口需要同意授权后才能执行,比如获取手机号授权接口,可以在同意隐私协议后,再执行授权获取手机号接口,如果不需要可以不添加该方法
  31.                                 console.log('同意隐私授权')
  32.                         }
  33.                 }
  34.         }
  35. </script>
  36. <style lang="scss" scoped>
  37. </style>
复制代码
四、uniapp开发,在manifest.json中添加"usePrivacyCheck" : true;

官方说明:https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html
隐私相关功能启用时间延期至 2023年10月17日。在 2023年10月17日之前,在 app.json 中设置 usePrivacyCheck: true 后,会启用隐私相关功能,如果不设置或者设置为 false 则不会启用。在 2023年10月17日之后,岂论 app.json 中是否有设置 usePrivacyCheck,隐私相关功能都会启用。
添加方法,点击manifest.json,再点击源码视图,在mp-weixin模块下添加"usePrivacyCheck" : true;

五、测试方法

当用户从「微信下拉-近来-近来利用的小程序」中删除小程序,将清空历史同步状态。下次访问小程序后,需要重新同步微信当前用户已阅读并同意小程序的隐私政策等网络利用规则。
开发者可通过此方式进行调试,也可以在开发者工具中「扫除模拟器缓存-扫除授权数据」清空历史同步状态。
线上版本,拉起一次授权同意后,不会再次拉起授权弹框。

六、设置隐私指引

登录小程序公众平台,点击设置–>根本信息设置
小程序公众平台链接:https://mp.weixin.qq.com/

找到用户隐私保护指引,点击更新,设置方法,可以参照微信提供的《标准化用户隐私保护指引》

选择在项目中利用到的隐私接口涉及到的小程序功能,并填写利用的来由,根据要求将隐私保护指引填写完成,并点击确定并生成协议


设置完成后,会有微信官方审核,大约需要15分钟-1小时审核完成。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4