hookehuyr

feat(注册页面): 添加用户协议和隐私政策弹窗

在注册页面中新增了用户协议和隐私政策的弹窗组件,并为其添加了点击事件处理逻辑,以便用户在注册时查看相关条款
......@@ -25,6 +25,7 @@ declare module 'vue' {
SearchBar: typeof import('./components/ui/SearchBar.vue')['default']
SummerCampCard: typeof import('./components/ui/SummerCampCard.vue')['default']
TermsContent: typeof import('./components/ui/TermsContent.vue')['default']
TermsPopup: typeof import('./components/ui/TermsPopup.vue')['default']
VanDatePicker: typeof import('vant/es')['DatePicker']
VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
......
<!--
* @Date: 2025-03-21 16:52:39
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-21 16:56:29
* @FilePath: /mlaj/src/components/ui/TermsPopup.vue
* @Description: 文件描述
-->
<template>
<van-popup
:show="show"
@update:show="$emit('update:show', $event)"
position="bottom"
:style="{ height: '100%' }"
>
<div class="flex flex-col h-full relative">
<div class="sticky top-0 flex justify-between items-center p-4 border-b border-gray-100 bg-white z-10">
<h3 class="font-medium text-lg">{{ title }}</h3>
<van-icon name="cross" @click="$emit('update:show', false)" class="text-gray-500" />
</div>
<div class="flex-1 overflow-y-auto p-4 pt-0">
<div v-if="type === 'terms'" class="space-y-4 text-gray-600">
<p>欢迎使用亲子学院!在使用我们的服务之前,请仔细阅读以下用户协议。</p>
<h5 class="font-medium text-gray-800">1. 服务内容</h5>
<p>亲子学院为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。</p>
<h5 class="font-medium text-gray-800">2. 用户责任</h5>
<p>用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。</p>
<h5 class="font-medium text-gray-800">3. 知识产权</h5>
<p>本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。</p>
<h5 class="font-medium text-gray-800">4. 免责声明</h5>
<p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p>
<h5 class="font-medium text-gray-800">1. 服务内容</h5>
<p>亲子学院为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。</p>
<h5 class="font-medium text-gray-800">2. 用户责任</h5>
<p>用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。</p>
<h5 class="font-medium text-gray-800">3. 知识产权</h5>
<p>本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。</p>
<h5 class="font-medium text-gray-800">4. 免责声明</h5>
<p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p>
</div>
<div v-else-if="type === 'privacy'" class="space-y-4 text-gray-600">
<p>我们重视您的隐私保护。本隐私政策说明我们如何收集、使用和保护您的个人信息。</p>
<h5 class="font-medium text-gray-800">1. 信息收集</h5>
<p>我们收集的信息包括但不限于:姓名、联系方式、位置信息等。这些信息用于提供更好的服务体验。</p>
<h5 class="font-medium text-gray-800">2. 信息使用</h5>
<p>我们承诺对您的个人信息进行严格保密,不会将其出售、出租或以其他方式泄露给任何第三方。</p>
<h5 class="font-medium text-gray-800">3. 信息安全</h5>
<p>我们采用行业标准的安全措施保护您的个人信息,防止未经授权的访问、使用或泄露。</p>
<h5 class="font-medium text-gray-800">4. Cookie使用</h5>
<p>我们使用Cookie和类似技术来提供更好的用户体验,您可以通过浏览器设置管理Cookie。</p>
</div>
</div>
</div>
</van-popup>
</template>
<script setup>
defineProps({
show: {
type: Boolean,
required: true,
default: false
},
type: {
type: String,
required: true,
validator: (value) => ['terms', 'privacy'].includes(value)
},
title: {
type: String,
required: true
}
})
defineEmits(['update:show'])
</script>
......@@ -87,7 +87,7 @@
class="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded"
/>
<label for="agreeTerms" class="ml-2 block text-sm text-gray-700">
我已阅读并同意 <a href="#" class="text-green-600 hover:text-green-500">用户协议</a> 和 <a href="#" class="text-green-600 hover:text-green-500">隐私政策</a>
我已阅读并同意 <a href="#" class="text-green-600 hover:text-green-500" @click.prevent="openTerms">用户协议</a> 和 <a href="#" class="text-green-600 hover:text-green-500" @click.prevent="openPrivacy">隐私政策</a>
</label>
</div>
......@@ -147,6 +147,17 @@
</div>
</FrostedGlass>
</div>
<TermsPopup
v-model:show="showTerms"
:type="popupType"
:title="popupTitle"
/>
<TermsPopup
v-model:show="showPrivacy"
:type="popupType"
:title="popupTitle"
/>
</div>
</template>
......@@ -154,6 +165,7 @@
import { ref, reactive } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import FrostedGlass from '@/components/ui/FrostedGlass.vue'
import TermsPopup from '@/components/ui/TermsPopup.vue'
import { useAuth } from '@/contexts/auth'
import { useTitle } from '@vueuse/core';
......@@ -175,6 +187,22 @@ const formData = reactive({
const error = ref('')
const loading = ref(false)
const showTerms = ref(false)
const showPrivacy = ref(false)
const popupTitle = ref('')
const popupType = ref('')
const openTerms = () => {
popupTitle.value = '用户协议'
popupType.value = 'terms'
showTerms.value = true
}
const openPrivacy = () => {
popupTitle.value = '隐私政策'
popupType.value = 'privacy'
showPrivacy.value = true
}
const handleSubmit = async () => {
if (!formData.name || !formData.email || !formData.password) {
......