PrivacyAgreementModal.vue
15.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
<template>
<nut-popup
v-model:visible="modalVisible"
position="bottom"
:closeable="false"
:close-on-click-overlay="false"
round
:safe-area-inset-bottom="true"
class="privacy-modal"
>
<view class="privacy-content">
<!-- 标题 -->
<view class="privacy-header">
<text class="privacy-title">隐私政策与用户协议</text>
</view>
<!-- 内容 -->
<view class="privacy-body">
<text class="privacy-text">
你好,小程序【手机号】涉及收集、使用和存储用户信息,增加了
<text class="privacy-link" @tap="onUserAgreementClick">《用户服务协议》</text>
及
<text class="privacy-link" @tap="onPrivacyPolicyClick">《隐私政策》</text>
,明确告知收集用户信息的使用目的、方式和用途,并取得用户授权同意后,才能获取用户收集用户信息。
</text>
</view>
<!-- 同意选择 -->
<view class="privacy-agreement">
<nut-checkbox v-model="agreed" class="agreement-checkbox">
<text class="agreement-text">我已阅读并同意上述协议</text>
</nut-checkbox>
</view>
<!-- 操作按钮 -->
<view class="privacy-actions">
<nut-button
class="action-btn cancel-btn"
@click="onCancel"
>
关闭
</nut-button>
<nut-button
class="action-btn confirm-btn"
type="primary"
:disabled="!agreed"
@click="onConfirm"
>
确认进入
</nut-button>
</view>
</view>
</nut-popup>
<!-- 内容全屏显示弹框 -->
<nut-popup
v-model:visible="showContentModal"
position="right"
:closeable="true"
:close-on-click-overlay="true"
:safe-area-inset-bottom="true"
:style="{ width: '100%', height: '100%' }"
@close="onCloseContentModal"
>
<view class="content-container">
<!-- 标题栏 -->
<view class="content-header">
<text class="content-title">{{ contentTitle }}</text>
<view class="close-btn" @click="onCloseContentModal">
<text class="close-text">×</text>
</view>
</view>
<!-- 内容区域 -->
<scroll-view class="content-scroll" :scroll-y="true">
<view class="content-body">
<view class="content-text" v-html="contentText"></view>
</view>
</scroll-view>
</view>
</nut-popup>
</template>
<script setup>
import { ref, computed, defineEmits, defineProps } from 'vue'
import Taro from '@tarojs/taro'
// Props
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
// Emits
const emit = defineEmits(['update:visible', 'confirm', 'cancel'])
// 响应式数据
const agreed = ref(false)
// 计算属性
const modalVisible = computed({
get() {
return props.visible
},
set(value) {
emit('update:visible', value)
}
})
// 用户服务协议内容
const userAgreementContent = `
<div class="agreement-section">
<div class="section-title">第一条 协议的范围</div>
<div class="section-content">
<div class="clause-item">1.1 本协议是您与捡个电驴小程序(以下简称"本平台")之间关于您使用本平台服务所订立的协议。</div>
<div class="clause-item">1.2 本协议描述本平台与用户之间关于"捡个电驴"服务相关的权利义务。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第二条 服务内容</div>
<div class="section-content">
<div class="clause-item">2.1 本平台为用户提供二手电动车交易信息发布、浏览、联系等服务。</div>
<div class="clause-item">2.2 用户可以通过本平台发布车辆出售信息、浏览车辆信息、联系买卖双方等。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第三条 用户注册</div>
<div class="section-content">
<div class="clause-item">3.1 用户需要注册账户才能使用本平台的完整服务。</div>
<div class="clause-item">3.2 用户应提供真实、准确、完整的个人信息。</div>
<div class="clause-item">3.3 用户应妥善保管账户信息,对账户下的所有活动承担责任。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第四条 用户行为规范</div>
<div class="section-content">
<div class="clause-item">4.1 用户不得发布虚假信息或进行欺诈行为。</div>
<div class="clause-item">4.2 用户不得发布违法违规内容。</div>
<div class="clause-item">4.3 用户应遵守平台的交易规则和社区准则。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第五条 隐私保护</div>
<div class="section-content">
<div class="clause-item">5.1 本平台重视用户隐私保护,具体内容请参见《隐私政策》。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第六条 免责声明</div>
<div class="section-content">
<div class="clause-item">6.1 本平台仅提供信息发布平台,不参与具体交易。</div>
<div class="clause-item">6.2 用户之间的交易风险由用户自行承担。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第七条 协议修改</div>
<div class="section-content">
<div class="clause-item">7.1 本平台有权根据需要修改本协议。</div>
<div class="clause-item">7.2 修改后的协议将在平台上公布。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">第八条 争议解决</div>
<div class="section-content">
<div class="clause-item">8.1 因本协议产生的争议,双方应友好协商解决。</div>
<div class="clause-item">8.2 协商不成的,可向有管辖权的人民法院提起诉讼。</div>
</div>
</div>
<div class="agreement-footer">本协议自用户点击同意之日起生效。</div>
`
// 隐私政策内容
const privacyPolicyContent = `
<div class="agreement-section">
<div class="section-title">引言</div>
<div class="section-content">
<div class="clause-item">捡个电驴小程序(以下简称"我们")非常重视用户的隐私保护。本隐私政策说明了我们如何收集、使用、存储和保护您的个人信息。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">一、我们收集的信息</div>
<div class="section-content">
<div class="clause-item">1.1 您主动提供的信息</div>
<div class="clause-list">
<div class="list-item1">注册信息:手机号码、昵称、头像等</div>
<div class="list-item1">个人资料:性别、学校、生日等</div>
<div class="list-item1">车辆信息:发布的车辆详情、图片等</div>
<div class="list-item1">联系信息:与其他用户的沟通记录</div>
</div>
<div class="clause-item">1.2 自动收集的信息</div>
<div class="clause-list">
<div class="list-item1">设备信息:设备型号、操作系统版本等</div>
<div class="list-item1">使用信息:访问时间、使用功能、操作记录等</div>
<div class="list-item1">位置信息:用于提供本地化服务(需要您的授权)</div>
</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">二、信息使用目的</div>
<div class="section-content">
<div class="clause-item">2.1 提供服务</div>
<div class="clause-list">
<div class="list-item1">账户注册和身份验证</div>
<div class="list-item1">车辆信息发布和展示</div>
<div class="list-item1">用户间沟通和交易撮合</div>
<div class="list-item1">个性化推荐服务</div>
</div>
<div class="clause-item">2.2 改善服务</div>
<div class="clause-list">
<div class="list-item1">分析用户使用习惯</div>
<div class="list-item1">优化产品功能</div>
<div class="list-item1">提升用户体验</div>
</div>
<div class="clause-item">2.3 安全保障</div>
<div class="clause-list">
<div class="list-item1">防范欺诈和违法行为</div>
<div class="list-item1">保护用户和平台安全</div>
<div class="list-item1">维护正常的服务秩序</div>
</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">三、信息共享</div>
<div class="section-content">
<div class="clause-item">3.1 我们不会出售您的个人信息</div>
<div class="clause-item">3.2 在以下情况下,我们可能会共享您的信息:</div>
<div class="clause-list">
<div class="list-item1">获得您的明确同意</div>
<div class="list-item1">法律法规要求</div>
<div class="list-item1">保护用户或公众的重大利益</div>
<div class="list-item1">与服务提供商共享(仅限于提供服务所需)</div>
</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">四、信息存储和保护</div>
<div class="section-content">
<div class="clause-item">4.1 存储期限</div>
<div class="clause-list">
<div class="list-item1">在您使用服务期间持续存储</div>
<div class="list-item1">账户注销后,我们将删除或匿名化处理您的个人信息</div>
</div>
<div class="clause-item">4.2 安全措施</div>
<div class="clause-list">
<div class="list-item1">采用行业标准的安全技术</div>
<div class="list-item1">定期进行安全评估</div>
<div class="list-item1">限制员工访问权限</div>
<div class="list-item1">建立数据泄露应急响应机制</div>
</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">五、您的权利</div>
<div class="section-content">
<div class="clause-item">5.1 访问权:您有权了解我们收集的关于您的个人信息</div>
<div class="clause-item">5.2 更正权:您有权要求我们更正不准确的个人信息</div>
<div class="clause-item">5.3 删除权:在特定情况下,您有权要求我们删除您的个人信息</div>
<div class="clause-item">5.4 撤回同意:您有权随时撤回对个人信息处理的同意</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">六、未成年人保护</div>
<div class="section-content">
<div class="clause-item">我们不会故意收集未满14周岁儿童的个人信息。如果您是未成年人,请在监护人指导下使用我们的服务。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">七、第三方服务</div>
<div class="section-content">
<div class="clause-item">我们的服务可能包含第三方链接或服务,这些第三方有自己的隐私政策,我们不对其隐私做法承担责任。</div>
</div>
</div>
<div class="agreement-section">
<div class="section-title">八、政策更新</div>
<div class="section-content">
<div class="clause-item">我们可能会不时更新本隐私政策。重大变更时,我们会通过适当方式通知您。</div>
</div>
</div>
<div class="agreement-footer">本隐私政策最后更新日期:2024年7月29日</div>
`
// 显示内容的状态
const showContentModal = ref(false)
const contentTitle = ref('')
const contentText = ref('')
/**
* 点击用户服务协议
*/
const onUserAgreementClick = () => {
contentTitle.value = '用户服务协议'
contentText.value = userAgreementContent
showContentModal.value = true
}
/**
* 点击隐私政策
*/
const onPrivacyPolicyClick = () => {
contentTitle.value = '隐私政策'
contentText.value = privacyPolicyContent
showContentModal.value = true
}
/**
* 关闭内容弹框
*/
const onCloseContentModal = () => {
showContentModal.value = false
contentTitle.value = ''
contentText.value = ''
}
/**
* 取消操作
*/
const onCancel = () => {
agreed.value = false
emit('update:visible', false)
emit('cancel')
}
/**
* 确认操作
*/
const onConfirm = () => {
if (!agreed.value) {
Taro.showToast({
title: '请先同意协议',
icon: 'none'
})
return
}
emit('update:visible', false)
emit('confirm')
}
</script>
<style lang="less">
.privacy-modal {
// width: 680rpx;
}
.privacy-content {
padding: 40rpx 32rpx;
background: white;
border-radius: 16rpx;
}
.privacy-header {
text-align: center;
margin-bottom: 32rpx;
}
.privacy-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.privacy-body {
margin-bottom: 32rpx;
}
.privacy-text {
font-size: 28rpx;
line-height: 1.6;
color: #666;
}
.privacy-link {
color: #fb923c;
text-decoration: underline;
font-weight: 500;
}
.privacy-agreement {
margin-bottom: 32rpx;
padding: 16rpx 0;
}
.agreement-checkbox {
display: flex;
align-items: center;
}
.agreement-text {
font-size: 28rpx;
color: #666;
margin-left: 16rpx;
}
.privacy-actions {
display: flex;
gap: 24rpx;
}
.action-btn {
flex: 1;
height: 88rpx;
border-radius: 44rpx;
font-size: 32rpx;
}
.cancel-btn {
background: #f5f5f5;
color: #666;
border: none;
}
.confirm-btn {
background: #fb923c;
border: none;
}
.confirm-btn:disabled {
background: #ccc;
color: #999;
}
/* 内容弹框样式 */
.content-modal {
width: 100vw;
height: 100vh;
}
.content-container {
width: 100%;
height: 100vh;
background: white;
display: flex;
flex-direction: column;
}
.content-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;
}
.content-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.close-btn {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background: #f5f5f5;
border-radius: 50%;
cursor: pointer;
}
.close-text {
font-size: 40rpx;
color: #666;
line-height: 1;
}
.content-scroll {
flex: 1;
height: 0;
}
.content-body {
padding: 40rpx;
}
// .content-text {
// font-size: 28rpx;
// line-height: 1.8;
// color: #333;
// white-space: pre-line;
// word-wrap: break-word;
// }
// 协议内容样式
.agreement-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 40rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #e5e5e5;
}
.agreement-section {
margin-bottom: 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
padding-left: 10rpx;
border-left: 6rpx solid #007aff;
}
.section-content {
padding-left: 20rpx;
}
.clause-item {
font-size: 28rpx;
color: #666;
line-height: 1.6;
margin-bottom: 15rpx;
}
.clause-list {
margin: 15rpx 0;
padding-left: 20rpx;
}
.list-item {
font-size: 26rpx;
color: #666;
line-height: 1.5;
margin-bottom: 10rpx;
padding-left: 20rpx;
position: relative;
}
.list-item::before {
content: '•';
position: absolute;
left: 0;
color: #007aff;
font-weight: bold;
}
.list-item1 {
font-size: 26rpx;
color: #666;
line-height: 1.5;
margin-bottom: 10rpx;
padding-left: 20rpx;
position: relative;
}
.list-item1::before {
content: '•';
position: absolute;
left: 0;
color: #007aff;
font-weight: bold;
}
.agreement-footer {
font-size: 28rpx;
color: #999;
text-align: center;
margin-top: 40rpx;
padding-top: 20rpx;
border-top: 2rpx solid #e5e5e5;
font-style: italic;
}
</style>