From e3c2cd23253f3501be7d31e03955fbb6f4aa3556 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 15 May 2026 16:30:04 +0800
Subject: [PATCH] Merge branch 'refs/heads/feature/v9.0/9.0.4' into prod

---
 src/components/GetPrivacy.vue |  199 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 199 insertions(+), 0 deletions(-)

diff --git a/src/components/GetPrivacy.vue b/src/components/GetPrivacy.vue
new file mode 100644
index 0000000..8ab4609
--- /dev/null
+++ b/src/components/GetPrivacy.vue
@@ -0,0 +1,199 @@
+<template>
+  <view v-if="showPrivacy" :class="privacyClass">
+    <view :class="contentClass">
+      <view class="title">用户隐私保护指引</view>
+      <view class="des">
+        感谢您选择使用掌控智飞小程序,我们非常重视您的个人信息安全和隐私保护。使用我们的产品前,请您仔细阅读“
+        <text class="link" @tap="openPrivacyContract">{{privacyContractName}} </text>”,
+        如您同意此隐私保护指引,请点击同意按钮,开始使用此小程序,我们将尽全力保护您的个人信息及合法权益,感谢您的信任!<br />
+      </view>
+      <view class="btns">
+        <button class="item reject" @click="exitMiniProgram">拒绝</button>
+        <button id="agree-btn" class="item agree" open-type="agreePrivacyAuthorization"
+                @agreeprivacyauthorization="handleAgreePrivacyAuthorization">同意</button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, computed, onMounted } from 'vue';
+
+const props = defineProps({
+  position: {
+    type: String,
+    default: 'center'
+  }
+});
+
+const emit = defineEmits(['allowPrivacy']);
+
+const isRead = ref(false);
+const showPrivacy = ref(false);
+const privacyContractName = ref('');
+const resolvePrivacyAuthorization = ref(null);
+
+const privacyClass = computed(() => {
+  return props.position === 'bottom' ? 'privacy privacy-bottom' : 'privacy';
+});
+
+const contentClass = computed(() => {
+  return props.position === 'bottom' ? 'content content-bottom' : 'content';
+});
+
+onMounted(() => {
+  if (uni.onNeedPrivacyAuthorization) {
+    uni.onNeedPrivacyAuthorization((resolve) => {
+      resolvePrivacyAuthorization.value = resolve;
+    });
+  }
+
+  if (uni.getPrivacySetting) {
+    uni.getPrivacySetting({
+      success: (res) => {
+        if (res.needAuthorization) {
+          privacyContractName.value = res.privacyContractName;
+          showPrivacy.value = true;
+        } else {
+          console.log('已经同意隐私授权,不需要再次授权')
+          showPrivacy.value = false;
+        }
+      },
+    });
+  }
+});
+
+const openPrivacyContract = () => {
+  uni.openPrivacyContract({
+    success: () => {
+      isRead.value = true;
+    },
+    fail: () => {
+      uni.showToast({
+        title: '遇到错误',
+        icon: 'error',
+      });
+    },
+  });
+};
+
+const exitMiniProgram = () => {
+  wx.exitMiniProgram();
+};
+
+const handleAgreePrivacyAuthorization = () => {
+  showPrivacy.value = false;
+  emit('allowPrivacy');
+  if (typeof resolvePrivacyAuthorization.value === 'function') {
+    resolvePrivacyAuthorization.value({
+      buttonId: 'agree-btn',
+      event: 'agree',
+    });
+  }
+};
+
+const closePrivacy = () => {
+  showPrivacy.value = false;
+};
+
+// 暴露给父组件使用
+defineExpose({
+  closePrivacy
+});
+</script>
+
+<style scoped>
+.privacy {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  background: rgba(0, 0, 0, .5);
+  z-index: 9999999;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.privacy-bottom {
+  align-items: flex-end;
+}
+
+.content {
+  width: 632rpx;
+  padding: 48rpx;
+  box-sizing: border-box;
+  background: #fff;
+  border-radius: 16rpx;
+}
+
+.content-bottom {
+  position: absolute;
+  bottom: 0;
+  width: 96%;
+  padding: 36rpx;
+  border-radius: 16rpx 16rpx 0 0;
+}
+
+.content .title {
+  text-align: center;
+  color: #333;
+  font-weight: bold;
+  font-size: 32rpx;
+}
+
+.content .des {
+  font-size: 26rpx;
+  color: #666;
+  margin-top: 40rpx;
+  text-align: justify;
+  line-height: 1.6;
+}
+
+.content .des .link {
+  color: #1989ff;
+  text-decoration: underline;
+}
+
+.btns {
+  margin-top: 48rpx;
+  margin-bottom: 12rpx;
+  display: flex;
+}
+
+.btns .item {
+  width: 200rpx;
+  height: 72rpx;
+  overflow: visible;
+  display: flex;
+  align-items: center;
+
+  justify-content: center;
+  /* border-radius: 16rpx; */
+  box-sizing: border-box;
+  border: none !important;
+}
+
+.btns .reject {
+  background: #f4f4f5;
+  color: #1989ff;
+  font-size: 14px;
+  background: #edf5fe;
+  font-weight: 300;
+  margin-right: 16rpx;
+}
+
+.btns .agree {
+  width: 200rpx;
+  background: #1989ff;
+  color: #fff;
+  font-size: 16px;
+
+}
+
+.privacy-bottom .btns .agree {
+  width: 440rpx;
+
+}
+</style>

--
Gitblit v1.9.3