Files
spring-festival-greetings/components/PrivacyPopup/PrivacyPopup.vue
2026-02-03 02:41:19 +08:00

206 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view v-if="show" class="privacy-popup">
<view class="mask"></view>
<view class="content">
<view class="title">用户隐私保护指引</view>
<view class="desc">
感谢您使用本小程序在使用前请您仔细阅读
<text class="link" @click="openPrivacyContract">{{
privacyContractName
}}</text>
当您点击同意并开始使用产品服务时即表示您已理解并同意该条款内容该条款将对您产生法律约束力如您拒绝将无法进入小程序
</view>
<view class="btns">
<button class="btn refuse" @click="handleDisagree">拒绝</button>
<button
id="agree-btn"
class="btn agree"
open-type="agreePrivacyAuthorization"
@agreeprivacyauthorization="handleAgree"
>
同意
</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { reportPrivacy } from "@/api/auth.js";
const show = ref(false);
const privacyContractName = ref("《用户隐私保护指引》");
const emit = defineEmits(["agree"]);
let resolveCheck = null;
// #ifdef MP-WEIXIN
const check = () => {
return new Promise((resolve) => {
if (uni.getPrivacySetting) {
uni.getPrivacySetting({
success: (res) => {
if (res.needAuthorization) {
privacyContractName.value =
res.privacyContractName || "《用户隐私保护指引》";
show.value = true;
resolveCheck = resolve;
} else {
resolve(true);
}
},
fail: (err) => {
console.error("getPrivacySetting fail:", err);
resolve(true);
},
});
} else {
resolve(true);
}
});
};
// #endif
// Only for WeChat Mini Program
// #ifdef MP-WEIXIN
// onMounted(() => {
// check();
// });
// #endif
const openPrivacyContract = () => {
uni.openPrivacyContract({
success: () => {},
fail: (err) => {
console.error("openPrivacyContract fail", err);
},
});
};
const handleAgree = async (e) => {
if (!show.value) return; // Prevent double execution
console.log("handleAgree triggered", e);
// 1. Save to local storage
uni.setStorageSync("hasAgreedPrivacy", true);
// 2. Hide popup
show.value = false;
emit("agree");
// 3. Resolve the check promise
if (resolveCheck) {
resolveCheck(true);
resolveCheck = null;
}
// 4. Call server API
try {
await reportPrivacy();
} catch (e) {
console.error("Report privacy failed", e);
}
};
const handleDisagree = () => {
// Exit mini program
// #ifdef MP-WEIXIN
uni.exitMiniProgram({
success: () => {
console.log("Exit success");
},
});
// #endif
};
defineExpose({
check,
});
</script>
<style lang="scss" scoped>
.privacy-popup {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
}
.content {
position: relative;
width: 600rpx;
background: #fff;
border-radius: 24rpx;
padding: 48rpx 40rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 32rpx;
}
.desc {
font-size: 28rpx;
color: #666;
line-height: 1.6;
margin-bottom: 48rpx;
text-align: justify;
.link {
color: #576b95;
display: inline;
}
}
.btns {
display: flex;
justify-content: space-between;
width: 100%;
.btn {
width: 240rpx;
height: 88rpx;
line-height: 88rpx;
text-align: center;
border-radius: 12rpx;
font-size: 32rpx;
font-weight: 500;
margin: 0;
&::after {
border: none;
}
&.refuse {
background: #f2f2f2;
color: #666;
}
&.agree {
background: #07c160;
color: #fff;
}
}
}
}
</style>