hookehuyr

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

在注册页面中新增了用户协议和隐私政策的弹窗组件,并为其添加了点击事件处理逻辑,以便用户在注册时查看相关条款
...@@ -25,6 +25,7 @@ declare module 'vue' { ...@@ -25,6 +25,7 @@ declare module 'vue' {
25 SearchBar: typeof import('./components/ui/SearchBar.vue')['default'] 25 SearchBar: typeof import('./components/ui/SearchBar.vue')['default']
26 SummerCampCard: typeof import('./components/ui/SummerCampCard.vue')['default'] 26 SummerCampCard: typeof import('./components/ui/SummerCampCard.vue')['default']
27 TermsContent: typeof import('./components/ui/TermsContent.vue')['default'] 27 TermsContent: typeof import('./components/ui/TermsContent.vue')['default']
28 + TermsPopup: typeof import('./components/ui/TermsPopup.vue')['default']
28 VanDatePicker: typeof import('vant/es')['DatePicker'] 29 VanDatePicker: typeof import('vant/es')['DatePicker']
29 VanIcon: typeof import('vant/es')['Icon'] 30 VanIcon: typeof import('vant/es')['Icon']
30 VanList: typeof import('vant/es')['List'] 31 VanList: typeof import('vant/es')['List']
......
1 +<!--
2 + * @Date: 2025-03-21 16:52:39
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-03-21 16:56:29
5 + * @FilePath: /mlaj/src/components/ui/TermsPopup.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <van-popup
10 + :show="show"
11 + @update:show="$emit('update:show', $event)"
12 + position="bottom"
13 + :style="{ height: '100%' }"
14 + >
15 + <div class="flex flex-col h-full relative">
16 + <div class="sticky top-0 flex justify-between items-center p-4 border-b border-gray-100 bg-white z-10">
17 + <h3 class="font-medium text-lg">{{ title }}</h3>
18 + <van-icon name="cross" @click="$emit('update:show', false)" class="text-gray-500" />
19 + </div>
20 +
21 + <div class="flex-1 overflow-y-auto p-4 pt-0">
22 + <div v-if="type === 'terms'" class="space-y-4 text-gray-600">
23 + <p>欢迎使用亲子学院!在使用我们的服务之前,请仔细阅读以下用户协议。</p>
24 +
25 + <h5 class="font-medium text-gray-800">1. 服务内容</h5>
26 + <p>亲子学院为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。</p>
27 +
28 + <h5 class="font-medium text-gray-800">2. 用户责任</h5>
29 + <p>用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。</p>
30 +
31 + <h5 class="font-medium text-gray-800">3. 知识产权</h5>
32 + <p>本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。</p>
33 +
34 + <h5 class="font-medium text-gray-800">4. 免责声明</h5>
35 + <p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p>
36 + <h5 class="font-medium text-gray-800">1. 服务内容</h5>
37 + <p>亲子学院为用户提供在线教育、活动报名等服务。我们保留随时修改或中断服务的权利,而无需事先通知用户。</p>
38 +
39 + <h5 class="font-medium text-gray-800">2. 用户责任</h5>
40 + <p>用户在使用本服务时必须遵守所有适用的法律法规。用户承诺提供真实、准确、完整的个人信息。</p>
41 +
42 + <h5 class="font-medium text-gray-800">3. 知识产权</h5>
43 + <p>本平台的所有内容,包括但不限于文字、图片、音频、视频等,均受著作权法和其他知识产权法律法规的保护。</p>
44 +
45 + <h5 class="font-medium text-gray-800">4. 免责声明</h5>
46 + <p>对于因不可抗力或非本平台原因造成的服务中断或其他缺陷,本平台不承担任何责任。</p>
47 + </div>
48 +
49 + <div v-else-if="type === 'privacy'" class="space-y-4 text-gray-600">
50 + <p>我们重视您的隐私保护。本隐私政策说明我们如何收集、使用和保护您的个人信息。</p>
51 +
52 + <h5 class="font-medium text-gray-800">1. 信息收集</h5>
53 + <p>我们收集的信息包括但不限于:姓名、联系方式、位置信息等。这些信息用于提供更好的服务体验。</p>
54 +
55 + <h5 class="font-medium text-gray-800">2. 信息使用</h5>
56 + <p>我们承诺对您的个人信息进行严格保密,不会将其出售、出租或以其他方式泄露给任何第三方。</p>
57 +
58 + <h5 class="font-medium text-gray-800">3. 信息安全</h5>
59 + <p>我们采用行业标准的安全措施保护您的个人信息,防止未经授权的访问、使用或泄露。</p>
60 +
61 + <h5 class="font-medium text-gray-800">4. Cookie使用</h5>
62 + <p>我们使用Cookie和类似技术来提供更好的用户体验,您可以通过浏览器设置管理Cookie。</p>
63 + </div>
64 + </div>
65 + </div>
66 + </van-popup>
67 +</template>
68 +
69 +<script setup>
70 +defineProps({
71 + show: {
72 + type: Boolean,
73 + required: true,
74 + default: false
75 + },
76 + type: {
77 + type: String,
78 + required: true,
79 + validator: (value) => ['terms', 'privacy'].includes(value)
80 + },
81 + title: {
82 + type: String,
83 + required: true
84 + }
85 +})
86 +
87 +defineEmits(['update:show'])
88 +</script>
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
87 class="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded" 87 class="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded"
88 /> 88 />
89 <label for="agreeTerms" class="ml-2 block text-sm text-gray-700"> 89 <label for="agreeTerms" class="ml-2 block text-sm text-gray-700">
90 - 我已阅读并同意 <a href="#" class="text-green-600 hover:text-green-500">用户协议</a> 和 <a href="#" class="text-green-600 hover:text-green-500">隐私政策</a> 90 + 我已阅读并同意 <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>
91 </label> 91 </label>
92 </div> 92 </div>
93 93
...@@ -147,6 +147,17 @@ ...@@ -147,6 +147,17 @@
147 </div> 147 </div>
148 </FrostedGlass> 148 </FrostedGlass>
149 </div> 149 </div>
150 +
151 + <TermsPopup
152 + v-model:show="showTerms"
153 + :type="popupType"
154 + :title="popupTitle"
155 + />
156 + <TermsPopup
157 + v-model:show="showPrivacy"
158 + :type="popupType"
159 + :title="popupTitle"
160 + />
150 </div> 161 </div>
151 </template> 162 </template>
152 163
...@@ -154,6 +165,7 @@ ...@@ -154,6 +165,7 @@
154 import { ref, reactive } from 'vue' 165 import { ref, reactive } from 'vue'
155 import { useRoute, useRouter } from 'vue-router' 166 import { useRoute, useRouter } from 'vue-router'
156 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 167 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
168 +import TermsPopup from '@/components/ui/TermsPopup.vue'
157 import { useAuth } from '@/contexts/auth' 169 import { useAuth } from '@/contexts/auth'
158 import { useTitle } from '@vueuse/core'; 170 import { useTitle } from '@vueuse/core';
159 171
...@@ -175,6 +187,22 @@ const formData = reactive({ ...@@ -175,6 +187,22 @@ const formData = reactive({
175 187
176 const error = ref('') 188 const error = ref('')
177 const loading = ref(false) 189 const loading = ref(false)
190 +const showTerms = ref(false)
191 +const showPrivacy = ref(false)
192 +const popupTitle = ref('')
193 +const popupType = ref('')
194 +
195 +const openTerms = () => {
196 + popupTitle.value = '用户协议'
197 + popupType.value = 'terms'
198 + showTerms.value = true
199 +}
200 +
201 +const openPrivacy = () => {
202 + popupTitle.value = '隐私政策'
203 + popupType.value = 'privacy'
204 + showPrivacy.value = true
205 +}
178 206
179 const handleSubmit = async () => { 207 const handleSubmit = async () => {
180 if (!formData.name || !formData.email || !formData.password) { 208 if (!formData.name || !formData.email || !formData.password) {
......