2025-06-13 17:59:09 +08:00

485 lines
12 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 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}">
<!-- <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>
<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>
<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 {
protocolArr: "《用户协议》",
protocolArr1: "《隐私政策》",
agree:false,
resolvePrivacyAuthorization: null,
showPrivacy: false,
privacyContractName: "", // 小程序协议名称 基础库2.32.3 才会生效
};
},
methods: {
clickTwo(){
//隐私政策
console.log(2);
uni.navigateTo({
url:'/packageB/privacy?type=privacy'
})
},
clickOne(){
//用户协议
console.log(0);
uni.navigateTo({
url:'/packageB/privacy?type=user_protocol'
})
},
protocolClick(){
console.log(1);
this.agree=true;
},
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)
this.$emit('agree_call');
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;
// }
// }
// }
},
// 点击取消
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 {
background-color: #ffffff;
color: #999999;
color: #4c4c4c;
border: 1px solid #999999;
}
.agree-btn {
line-height: 80rpx;
background-color: var(--agree_btn_back_color);
color: #fff;
margin: 0;
}
.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>