485 lines
12 KiB
Vue
Raw Normal View History

<template>
<view class="lsl-protocol" :class="[{'lsl-bottom':position=='bottom'}]" v-if="showPrivacy">
<view class="lsl-protocol-container" :style="{'--color':color,'--bgcolor':bgcolor,'--agree_btn_back_color':agree_btn_back_color,'--bd_radius':bd_radius}">
2025-06-13 17:59:09 +08:00
<!-- <image :src="top_img" class="top_img" :style="top_img_style" mode=""></image> -->
<view class="title">
{{title}}
</view>
<view class="content">{{predesc}}
<text @click.stop="handleOpenPrivacyContract">{{ privacyContractNameCustom||privacyContractName }}</text>
<text v-for="(item,index) in other" @click.stop="other_btn(item)" :key="index"><text style="color:#595959;">{{symbol}}</text>{{item.tit}}</text>
{{subdesc}}
</view>
2025-06-12 15:10:21 +08:00
<view style="padding-bottom: 30rpx;">
<cc-protocolBox :agree="agree" :nameOne="protocolArr1" :name="protocolArr" @clickTwo="clickTwo" @clickOne="clickOne" @click="protocolClick"></cc-protocolBox>
</view>
<view class="footer">
<navigator v-if="refuse_tbn_exit" open-type="exit" target="miniProgram" hover-class="none">
<view class="btn disagree-btn" @click="handleRefuse">{{refuse_tbn_text}}</view>
</navigator>
<view v-else class="btn disagree-btn" @click="handleRefuse">{{refuse_tbn_text}}</view>
2025-06-12 15:25:15 +08:00
<button v-if="!agree" id="agree-btn" class="btn agree-btn-no">{{agree_btn_text}}</button>
<button v-if="agree" id="agree-btn" class="btn agree-btn"
@click="getphonenumber">{{agree_btn_text}}</button>
</view>
</view>
</view>
</template>
<script>
/**
* @name emits
* @function agree 点击同意回调
* @function disagree 点击拒绝回调
* @function other_call 点击其他协议回调
*/
export default {
name: "lsl-protocol-popup",
emits: ['agree', 'disagree','other_call','get_phone_number'],
props: {
// 顶部图标
top_img: {
type: String,
default: ''
},
// 顶部图标 自定义样式
top_img_style: {
type: String,
default: ''
},
// 弹窗位置
position: {
type: String,
default: 'center'
},
// 弹窗圆角
bd_radius: {
type: String,
default: '18rpx'
},
// 协议颜色
color: {
type: String,
default: '#0396FF'
},
// 弹窗背景色
bgcolor: {
type: String,
default: '#ffffff'
},
// 是否开启隐私保护协议授权
onNeed: {
type: Boolean,
default: true
},
// 是否隐藏 底部按钮
hideTabBar: {
type: Boolean,
default: true
},
// 标题
title: {
type: String,
default: '用户隐私保护提示'
},
// 标题 自定义样式
title_style: {
type: String,
default: ''
},
// 协议前 文字
predesc: {
type: String,
default: '使用前请仔细阅读'
},
// 协议后 文字
subdesc: {
type: String,
default: '当您点击同意后,即表示您已理解并同意该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用该服务。'
},
// 隐私 自定义协议名称,不传则由小程序自动获取
privacyContractNameCustom:{
type: String,
default: ''
},
// 同意按钮文案
agree_btn_text:{
type: String,
default: '同意并继续'
},
// 同意按钮背景色
agree_btn_back_color:{
type: String,
default: '#333333'
},
// 拒绝按钮文案
refuse_tbn_text:{
type: String,
default: '退出应用'
},
// 点击拒绝是否 关闭协议
refuse_pop_close:{
type: Boolean,
default: true
},
// 点击拒绝是否 退出小程序
refuse_tbn_exit:{
type: Boolean,
default: true
},
// 协议中间的分割符号
symbol:{
type: String,
default: '和'
},
// 自定义 open-type 有效值
open_type:{
type: String,
default: 'agreePrivacyAuthorization'
},
// 是否强制授权手机号
is_force_phone:{
type: Boolean,
default: false
},
// 授权手机号 点击拒绝时提醒内容
show_toast_phone: {
type: String,
default: ''
},
// 其他协议列表
other:{
type: Array,
default: [
// {
// tit:'《用户协议》',
// type:'doc', // doc自行下载打开文档 page跳转页面
// content:'https://cdn.baidu.com/14_dbd7dcc9.docx', // 文档地址/页面跳转地址
// }
]
},
},
data() {
return {
2025-06-12 15:10:21 +08:00
protocolArr: "《用户协议》",
protocolArr1: "《隐私政策》",
agree:false,
resolvePrivacyAuthorization: null,
showPrivacy: false,
privacyContractName: "", // 小程序协议名称 基础库2.32.3 才会生效
};
},
methods: {
2025-06-12 15:10:21 +08:00
clickTwo(){
2025-06-12 17:31:01 +08:00
//隐私政策
2025-06-12 15:10:21 +08:00
console.log(2);
2025-06-12 17:31:01 +08:00
uni.navigateTo({
url:'/packageB/privacy?type=privacy'
})
2025-06-12 15:10:21 +08:00
},
clickOne(){
2025-06-12 17:31:01 +08:00
//用户协议
2025-06-12 15:10:21 +08:00
console.log(0);
2025-06-12 17:31:01 +08:00
uni.navigateTo({
url:'/packageB/privacy?type=user_protocol'
})
2025-06-12 15:10:21 +08:00
},
protocolClick(){
console.log(1);
2025-06-12 15:25:15 +08:00
this.agree=true;
2025-06-12 15:10:21 +08:00
},
open(name) {
if (this.hideTabBar) {
uni.hideTabBar();
}
this.privacyContractName = name
this.showPrivacy = true;
},
close() {
this.showPrivacy = false;
if (this.hideTabBar) {
uni.hideTabBar();
}
},
// 点击同意
handleAgree(e) {
console.log('// 点击同意',e)
if(this.is_force_phone && this.open_type.indexOf('getPhoneNumber')>=0){
if (this.onNeed) {
this.resolvePrivacyAuthorization({
event: "disagree",
});
}
return;
}
// 需要用户同意隐私授权时
if (this.onNeed) {
this.resolvePrivacyAuthorization({
buttonId: "agree-btn",
event: "agree",
});
}
uni.showTabBar();
this.close();
this.$emit('agree_call')
},
// 授权手机号
getphonenumber(e){
console.log('// 授权手机号',e)
2025-06-13 17:29:27 +08:00
this.$emit('agree_call');
2025-06-12 15:25:15 +08:00
this.close();
// if(this.open_type.indexOf('getPhoneNumber')>=0){
// if(e.detail.errMsg == 'getPhoneNumber:ok'){
// uni.showTabBar();
// this.close();
// this.$emit('agree_call')
// this.$emit('get_phone_number',e);
// }else{
// if(this.show_toast_phone){
// uni.showToast({
// title: this.show_toast_phone,
// icon: 'none'
// })
// }
// if(this.is_force_phone){
// return;
// }
// }
2025-06-12 15:25:15 +08:00
// }
},
// 点击取消
handleRefuse() {
if (this.onNeed) {
this.resolvePrivacyAuthorization({
event: "disagree",
});
}
if(this.refuse_pop_close){
this.close();
}
this.$emit('disagree_call')
},
// 查看隐私协议内容
handleOpenPrivacyContract() {
uni.openPrivacyContract({
success: (res) => {
// console.log("openPrivacyContract success", res);
},
fail: (err) => {
// console.error("openPrivacyContract fail", err);
},
});
},
// 进入时获取隐私是否需要弹出隐私协议
checkPrivacySetting() {
uni.getPrivacySetting({
success: (res) => {
// console.log('getPrivacySetting', res);
// 如果是needAuthorization为false无需弹出隐私协议
if (res.needAuthorization === false) {
return;
}
if (this.onNeed) {
uni.onNeedPrivacyAuthorization((resolve) => {
this.open(res.privacyContractName)
this.resolvePrivacyAuthorization = resolve;
});
} else {
this.open(res.privacyContractName)
}
},
fail: () => {},
complete: () => {},
});
},
// 点击其他协议
other_btn(item){
if(item.type == 'doc'){ // 自行下载打开文档
uni.downloadFile({
url: item.content,
success: (res) => {
const filePath = res.tempFilePath;
uni.openDocument({
filePath: filePath,
fileType: item.content.substring(item.content.lastIndexOf('.') + 1),
success: (res) => {
console.log('打开文档成功')
}
});
}
});
}else if(item.type == 'page'){
uni.navigateTo({
url: item.content
});
}
this.$emit('other_call',item);
},
},
created() {
this.checkPrivacySetting();
},
};
</script>
<style lang="scss">
.lsl-protocol {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
box-sizing: border-box;
align-items: center;
justify-content: center;
-webkit-justify-content: center;
animation: fadeIn 0.2s linear both;
}
.lsl-protocol-container {
position: relative;
width: 620rpx;
min-height: 400rpx;
background: var(--bgcolor);
border-radius: var(--bd_radius);
padding: 50rpx;
font-size: 14px;
animation: fadeInBig 0.2s 0.2s linear both;
backdrop-filter: blur(10rpx); //毛玻璃属性
.top_img{
width: 164rpx;
height: 164rpx;
position: absolute;
left: 50%;
top: 0%;
transform: translate(-50%, -50%);
}
.title {
color: #333333;
font-size: 36rpx;
text-align: center;
font-weight: 600;
}
.content {
color: #595959;
margin-top: 36rpx;
margin-bottom: 36rpx;
line-height: 50rpx;
white-space: pre-wrap;
text {
color: var(--color);
}
}
.footer {
display: flex;
justify-content: space-between;
// 重置微信小程序的按钮样式
button:after {
border: none;
}
.btn {
width: 285rpx;
line-height: 80rpx;
font-size: 28rpx;
border-radius: 24px;
text-align: center;
}
.disagree-btn {
2025-06-13 17:59:09 +08:00
background-color: #ffffff;
color: #999999;
color: #4c4c4c;
2025-06-13 17:59:09 +08:00
border: 1px solid #999999;
}
.agree-btn {
line-height: 80rpx;
background-color: var(--agree_btn_back_color);
color: #fff;
margin: 0;
}
2025-06-12 15:25:15 +08:00
.agree-btn-no {
line-height: 80rpx;
background: #E4E4E4;
color: #9C9C9C;
margin: 0;
}
}
}
.lsl-bottom {
align-items: flex-end;
.lsl-protocol-container {
width: 100%;
animation: fadeIn 0.2s linear both;
animation: fadeInUp 0.2s 0.2s linear both;
padding-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
border-radius: 24px 24px 0 0;
}
.footer {
padding: 0 40rpx;
.btn {
width: 250rpx;
}
}
}
@keyframes fadeIn {
0% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
@keyframes fadeInBig {
0% {
opacity: 0;
transform: scale(0.5);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes fadeInUp {
0% {
opacity: 0;
transform: translate3d(0, 100%, 0);
}
100% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
</style>