hookehuyr

feat(隐私协议): 完善隐私协议弹窗和收款信息检查逻辑

- 在隐私协议弹窗中添加 catch-move 属性防止滑动穿透
- 简化隐私协议文本内容,移除冗余信息
- 添加收款信息检查逻辑和隐私弹窗触发来源区分
- 重构支付协议弹窗样式和交互,改为右侧弹出并优化滚动体验
......@@ -2,6 +2,7 @@
<nut-popup
v-model:visible="visible"
position="bottom"
:catch-move="true"
:style="{ width: '100%', height: '100%' }"
>
<div class="payment-agreement-modal">
......@@ -73,19 +74,29 @@
<!-- 支付协议弹框 -->
<nut-popup
v-model:visible="protocolVisible"
position="bottom"
:style="{ width: '100%', height: '70%' }"
round
closeable
position="right"
:closeable="true"
:close-on-click-overlay="true"
:safe-area-inset-bottom="true"
:style="{ width: '100%', height: '100%' }"
@close="protocolVisible = false"
>
<div class="protocol-modal">
<div class="protocol-header">
<h3>支付协议</h3>
</div>
<div class="protocol-content">
<p>{{ protocolContent }}</p>
</div>
</div>
<view class="protocol-container">
<!-- 标题栏 -->
<view class="protocol-header">
<text class="protocol-title">支付协议</text>
<view class="close-btn" @click="protocolVisible = false">
<text class="close-text">×</text>
</view>
</view>
<!-- 内容区域 -->
<scroll-view class="protocol-scroll" :scroll-y="true">
<view class="protocol-body">
<view class="protocol-text">{{ protocolContent }}</view>
</view>
</scroll-view>
</view>
</nut-popup>
</nut-popup>
</template>
......@@ -219,7 +230,7 @@ const handleClose = () => {
}
// 组件挂载时检查协议状态
onMounted(() => {
onMounted(async () => {
checkAgreementStatus()
})
</script>
......@@ -312,35 +323,64 @@ onMounted(() => {
}
}
.protocol-modal {
padding: 32rpx;
height: 100%;
/* 支付协议弹框样式 */
.protocol-container {
width: 100%;
height: 100vh;
background: white;
display: flex;
flex-direction: column;
}
.protocol-header {
text-align: center;
margin-bottom: 32rpx;
.protocol-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx 40rpx;
border-bottom: 1rpx solid #eee;
background: white;
position: sticky;
top: 0;
z-index: 10;
}
h3 {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin: 0;
}
}
.protocol-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.protocol-content {
flex: 1;
overflow-y: auto;
.close-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
border-radius: 50%;
cursor: pointer;
}
p {
font-size: 28rpx;
color: #666;
line-height: 1.8;
white-space: pre-line;
margin: 0;
}
}
.close-text {
font-size: 40rpx;
color: #666;
line-height: 1;
}
.protocol-scroll {
flex: 1;
height: 0;
}
.protocol-body {
padding: 40rpx;
}
.protocol-text {
font-size: 28rpx;
line-height: 1.8;
color: #666;
white-space: pre-line;
word-wrap: break-word;
}
</style>
......
......@@ -6,6 +6,7 @@
:close-on-click-overlay="false"
round
:safe-area-inset-bottom="true"
:catch-move="true"
class="privacy-modal"
>
<view class="privacy-content">
......@@ -17,7 +18,7 @@
<!-- 内容 -->
<view class="privacy-body">
<text class="privacy-text">
你好,小程序【手机号】涉及收集、使用和存储用户信息,增加了
你好,小程序涉及收集、使用和存储用户信息,增加了
<text class="privacy-link" @tap="onUserAgreementClick">《用户服务协议》</text>
<text class="privacy-link" @tap="onPrivacyPolicyClick">《隐私政策》</text>
......
......@@ -109,6 +109,8 @@ const userInfo = computed(() => userStore.userInfo)
// 隐私政策弹框状态
const showPrivacyModal = ref(false)
// 隐私政策弹框触发来源('editProfile' 或 'collectionSettings')
const privacyModalSource = ref('editProfile')
useDidShow(async () => {
await userStore.fetchUserInfo()
......@@ -128,6 +130,7 @@ const onEditProfile = async () => {
})
} else {
// 未完善资料,显示隐私政策同意弹框
privacyModalSource.value = 'editProfile'
showPrivacyModal.value = true
}
}
......@@ -136,10 +139,18 @@ const onEditProfile = async () => {
* 隐私政策确认
*/
const onPrivacyConfirm = () => {
// 用户同意隐私政策后,跳转到编辑资料页面
Taro.navigateTo({
url: '/pages/editProfile/index'
})
// 根据触发来源跳转到不同页面
if (privacyModalSource.value === 'editProfile') {
// 从编辑资料触发,跳转到编辑资料页面
Taro.navigateTo({
url: '/pages/editProfile/index'
})
} else if (privacyModalSource.value === 'collectionSettings') {
// 从收款设置触发,跳转到收款设置页面
Taro.navigateTo({
url: '/pages/collectionSettings/index'
})
}
}
/**
......@@ -215,10 +226,20 @@ const onFeedback = () => {
/**
* 收款设置
*/
const onCollectionSettings = () => {
Taro.navigateTo({
url: '/pages/collectionSettings/index'
})
const onCollectionSettings = async () => {
// 检查用户是否已完善收款信息
const hasCompleteCollectionInfo = userStore.hasCompleteCollectionInfo
if (hasCompleteCollectionInfo) {
// 已完善收款信息,直接进入收款设置页面
Taro.navigateTo({
url: '/pages/collectionSettings/index'
})
} else {
// 未完善收款信息,显示隐私政策同意弹框
privacyModalSource.value = 'collectionSettings'
showPrivacyModal.value = true
}
}
/**
......
/*
* @Date: 2025-01-08 18:00:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-08-05 17:51:14
* @LastEditTime: 2025-08-05 18:16:58
* @FilePath: /jgdl/src/stores/user.js
* @Description: 用户状态管理
*/
......@@ -44,6 +44,18 @@ export const useUserStore = defineStore('user', {
},
/**
* 检查用户是否已完善收款信息(银行信息和身份信息)
*/
hasCompleteCollectionInfo: (state) => {
return !!(
state.userInfo.bank && state.userInfo.bank.trim() &&
state.userInfo.bank_no && state.userInfo.bank_no.trim() &&
state.userInfo.name && state.userInfo.name.trim() &&
state.userInfo.idcard && state.userInfo.idcard.trim()
)
},
/**
* 检查用户是否已认证
*/
isUserAuthenticated: (state) => {
......