PrivacyPopup.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <script lang="ts" setup>
  2. import { onBeforeMount, ref } from 'vue'
  3. interface Props {
  4. title?: string // 标题
  5. desc?: string // 描述
  6. subDesc?: string // 字描述
  7. protocol?: string // 协议名称
  8. }
  9. withDefaults(defineProps<Props>(), {
  10. title: '用户隐私保护提示',
  11. desc: '感谢您使用本应用,您使用本应用的服务之前请仔细阅读并同意',
  12. subDesc: '。当您点击同意并开始时用产品服务时,即表示你已理解并同意该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用相应服务。',
  13. protocol: '《用户隐私保护指引》',
  14. })
  15. const emit = defineEmits(['agree', 'disagree'])
  16. const showPopup = ref<boolean>(false) // 是否展示popup
  17. const privacyResolves = ref(new Set()) // onNeedPrivacyAuthorization的reslove
  18. function privacyHandler(resolve: any) {
  19. showPopup.value = true
  20. privacyResolves.value.add(resolve)
  21. }
  22. onBeforeMount(() => {
  23. // 注册监听
  24. if (wx.onNeedPrivacyAuthorization) {
  25. wx.onNeedPrivacyAuthorization((resolve: any) => {
  26. if (typeof privacyHandler === 'function') {
  27. privacyHandler(resolve)
  28. }
  29. })
  30. }
  31. })
  32. /**
  33. * 同意隐私协议
  34. */
  35. function handleAgree() {
  36. showPopup.value = false
  37. privacyResolves.value.forEach((resolve: any) => {
  38. resolve({
  39. event: 'agree',
  40. buttonId: 'agree-btn',
  41. })
  42. })
  43. privacyResolves.value.clear()
  44. emit('agree')
  45. }
  46. /**
  47. * 拒绝隐私协议
  48. */
  49. function handleDisagree() {
  50. showPopup.value = false
  51. privacyResolves.value.forEach((resolve: any) => {
  52. resolve({
  53. event: 'disagree',
  54. })
  55. })
  56. privacyResolves.value.clear()
  57. }
  58. /**
  59. * 打开隐私协议
  60. */
  61. function openPrivacyContract() {
  62. wx.openPrivacyContract({})
  63. }
  64. /**
  65. * 弹出框关闭时清空
  66. */
  67. function handleClose() {
  68. privacyResolves.value.clear()
  69. }
  70. </script>
  71. <script lang="ts">
  72. export default {
  73. options: {
  74. virtualHost: true,
  75. addGlobalClass: true,
  76. styleIsolation: 'shared',
  77. },
  78. }
  79. </script>
  80. <template>
  81. <view>
  82. <wd-popup v-model="showPopup" :close-on-click-modal="false" custom-class="wd-privacy-popup" @close="handleClose">
  83. <view class="wd-privacy-popup__header">
  84. <!-- 标题 -->
  85. <view class="wd-picker__title">
  86. {{ title }}
  87. </view>
  88. </view>
  89. <view class="wd-privacy-popup__container">
  90. <text>{{ desc }}</text>
  91. <text class="wd-privacy-popup__container-protocol" @click="openPrivacyContract">
  92. {{ protocol }}
  93. </text>
  94. <text>{{ subDesc }}</text>
  95. </view>
  96. <view class="wd-privacy-popup__footer">
  97. <button id="disagree-btn" class="is-block is-round is-medium is-plain wd-privacy-popup__footer-disagree wd-button" @click="handleDisagree">
  98. 拒绝
  99. </button>
  100. <button
  101. id="agree-btn"
  102. class="wd-button is-block is-round is-medium is-primary wd-privacy-popup__footer-agree"
  103. open-type="agreePrivacyAuthorization"
  104. @agreeprivacyauthorization="handleAgree"
  105. >
  106. 同意
  107. </button>
  108. </view>
  109. </wd-popup>
  110. </view>
  111. </template>
  112. <style lang="scss" scoped>
  113. @import 'wot-design-uni/components/wd-button/index.scss';
  114. :deep(.wd-privacy-popup) {
  115. width: 600rpx;
  116. padding: 0 24rpx;
  117. box-sizing: border-box;
  118. border-radius: 32rpx;
  119. overflow: hidden;
  120. }
  121. .wd-privacy-popup {
  122. &__header {
  123. width: 100%;
  124. height: 128rpx;
  125. line-height: 128rpx;
  126. color: rgba(0, 0, 0, 0.85);
  127. font-size: 30rpx;
  128. padding: 0 12rpx;
  129. box-sizing: border-box;
  130. }
  131. &__container {
  132. width: 100%;
  133. box-sizing: border-box;
  134. padding: 0 12rpx;
  135. margin-bottom: 32rpx;
  136. font-size: 28rpx;
  137. line-height: 1.8;
  138. color: #3e3e3e;
  139. text-align: left;
  140. font-weight: 550;
  141. &-protocol {
  142. color: #4d80f0;
  143. }
  144. }
  145. &__footer {
  146. display: flex;
  147. justify-content: space-between;
  148. padding-bottom: 36rpx;
  149. button {
  150. border: none;
  151. outline: none;
  152. }
  153. }
  154. }
  155. </style>