index.vue
9.01 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
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-17 14:45:13
* @FilePath: /meihuaApp/src/pages/login/index.vue
* @Description: 文件描述
-->
<template>
<view>
<view style="color: #6A4925; font-size: 56rpx; text-align: center;">登 录</view>
<view style="border: 1px solid #F1EBDF; width: 90%; margin: 0 auto; margin-top: 50rpx; border-radius: 50rpx; padding: 5rpx 0;">
<nut-input v-model="tel" placeholder="请输入手机号" :border="false" type="number" max-length="11" />
</view>
<view style="border: 1px solid #F1EBDF; width: 90%; margin: 0 auto; margin-top: 20rpx; border-radius: 50rpx;">
<!-- <nut-input v-model="code" placeholder="请输入验证码" :border="false" type="number" >
<template #right> <nut-button size="small" color="#6A4925">获取验证码</nut-button> </template>
</nut-input> -->
<nut-row>
<nut-col span="14">
<nut-input v-model="sms_code" placeholder="请输入验证码" :border="false" type="number" :formatter="codeFormatter" max-length="4"></nut-input>
</nut-col>
<nut-col span="10">
<view style="padding: 25rpx 10rpx; line-height: 40rpx; background-color: #6A4925; color: #fff; border-top-right-radius: 50rpx; border-bottom-right-radius: 50rpx; font-size: 28rpx;text-align: center;">
<view @tap="getCode" v-if="!time_remaining">获取验证码</view>
<text v-else>{{ time_remaining }}秒后重新发送</text>
</view>
</nut-col>
</nut-row>
</view>
<view style="color: #7B7B7B; font-size: 28rpx; margin: 20rpx 50rpx;">未注册手机号验证后自动创建新账号</view>
<view style="margin: 50rpx; margin-bottom: 10rpx;">
<nut-button block color="#6A4925" size="large" @tap="login"><text style="font-size: 38rpx;">登 录</text></nut-button>
</view>
<view style="display: flex; align-items: center; margin-left: 60rpx; margin-top: 30rpx; color: #6A4925;">
<IconFont v-if="agree_checked" name="checked" color="#6A4925" @tap="onClickAgree"></IconFont>
<IconFont v-else name="check-normal" color="#000" @tap="onClickAgree"></IconFont>
<text style="margin-left: 5rpx;" @tap="onClickAgree">登录即同意</text><text style="font-weight: bold;" @tap="tapRight">《法律条款及隐私政策》</text>
</view>
<nut-popup position="right" closeable :style="{ width: '100%', height: '100%' }" v-model:visible="showRight">
<view>
<view style="text-align: center; font-size: 35rpx; margin-top: 80rpx; margin-bottom: 20rpx;">隐私条款</view>
<view style="padding: 0 50rpx;">
<view>一、定义</view>
<view style="margin: 20rpx 0;">
<view style="margin-bottom: 10rpx;">
1.个人隐私保护协议:是指依据相关法律法规规定、本协议等文件,由双方就个人信息的收集,使用和保护等问题所订立的协议。
</view>
<view>
2.个人信息:是指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息,包括但不限于自然人的姓名、出生日期、证件号码、个人生物识别信息、地址、电话号码、电子邮件地址等。
</view>
</view>
<view>二、收集个人信息的目的</view>
<view style="margin: 20rpx 0;">
<view style="margin-bottom: 10rpx;">
1. 我方将收集个人信息的目的是为了提供服务和满足客户的要求,并为客户提供更优质的服务和体验;
</view>
<view style="margin-bottom: 10rpx;">
2. 我方将对收集的个人信息进行严格的管理,以确保个人信息安全,不会被不当使用;
</view>
<view>
3. 我方将严格邊守法律法规,尊重客户的隐私权,不会将个人信息提供给第三方。
</view>
</view>
<view>三、收集个人信息的范围</view>
<view style="margin: 20rpx 0;">
<view style="margin-bottom: 10rpx;">1. 我方将仅收集客户提供的个人信息,不收集未经客户许可的其他信息:</view>
<view style="margin-bottom: 10rpx;">2. 如果客户拒绝提供个人信息,我方将无法为某提供服务;</view>
<view>3. 我方可能会通过网络技术收集客户的浏览和使用信息,但未经客户许可不会收集其他个人信息。</view>
</view>
<view>四、个人信息的使用</view>
<view style="margin: 20rpx 0;">
<view style="margin-bottom: 10rpx;">1. 我方将仅为提供服务的目的而使用客户的个人信息,不会将其用于其他用途;</view>
<view style="margin-bottom: 10rpx;">2. 为保护客户的隐私权,我方不会将客户的个人信息提供给第三万,除非经过客户的同意或者依照相关法律法规的规定;</view>
<view>3. 如果客户要求我方删除个人信息,我方将及时删除客户的个人信息。</view>
</view>
</view>
</view>
<view style="padding: 20rpx;">
<nut-button @tap="() => { showRight=false }" block color="#6A4925" size="large">
<text>关 闭</text>
</nut-button>
</view>
</nut-popup>
</view>
</template>
<script setup>
import Taro from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro';
import { ref, nextTick } from "vue";
import { getCurrentPageParam } from "@/utils/weapp";
import { bindPhoneAPI, sendSmsCodeAPI } from '@/api/index'
let countdownIntervalId; // 用于存储倒计时的计时器 ID
const startCountdown = (timeInSeconds, updateCallback, resetCallback) => {
if (countdownIntervalId) {
// 如果已经有倒计时在进行中,则先清除之前的计时器
clearInterval(countdownIntervalId);
}
let timeLeft = timeInSeconds;
// 更新倒计时显示的函数
const updateCountdown = () => {
if (timeLeft <= 0) {
// 倒计时结束
clearInterval(countdownIntervalId);
resetCallback(); // 调用重置函数
} else {
// 更新倒计时显示
updateCallback(timeLeft);
timeLeft--;
}
}
// 立即执行一次更新倒计时显示函数
updateCountdown();
// 每秒调用一次更新倒计时显示函数
countdownIntervalId = setInterval(updateCountdown, 1000);
}
const resetCountdown = () => {
if (countdownIntervalId) {
// 清除倒计时计时器
clearInterval(countdownIntervalId);
countdownIntervalId = undefined;
console.log("倒计时已重置");
time_remaining.value = 0;
}
}
const time_remaining = ref(0);
const tel = ref('');
const sms_code = ref(null);
const agree_checked = ref(false);
const onClickAgree = () => {
agree_checked.value = !agree_checked.value;
}
const showRight = ref(false);
const tapRight = () => {
showRight.value = true;
}
const codeFormatter = (value) => {
return value.substring(0, 4);
}
const isValidTel = (tel) => {
return /^1\d{10}$/.test(tel);
}
const login = async () => {
if (!agree_checked.value) {
Taro.showToast({
title: '请先阅读隐私政策后勾选',
icon: 'none',
duration: 2000
});
return;
}
if (!isValidTel(tel.value) ||!sms_code.value) {
Taro.showToast({
title: '请检查输入项',
icon: 'error',
duration: 2000
});
return;
} else {
const { code } = await bindPhoneAPI({ phone: tel.value, sms_code: sms_code.value });
if (code) {
Taro.showToast({
title: '登录成功',
icon: 'success',
duration: 2000,
success: () => {
setTimeout(() => {
let params = getCurrentPageParam();
if (params.page === 'detail') { // 详情页
Taro.navigateBack({
delta: 1
});
} else if (params.page === 'my') { // 登录页
Taro.redirectTo({
url: '/pages/myInfo/index'
});
} else {
Taro.redirectTo({
url: '/pages/index/index'
});
}
}, 1000);
}
});
}
}
}
const updateDisplay = (timeLeft) => {
// 倒计时剩余时间
time_remaining.value = timeLeft;
}
const resetDisplay = () => {
// 在此处进行重置后的展示操作
resetCountdown();
}
const getCode = async () => {
if (isValidTel(tel.value)) {
const { code } = await sendSmsCodeAPI({ mobile: tel.value });
if (code) {
Taro.showToast({
title: '验证码已发送',
icon:'success',
duration: 2000
});
startCountdown(10, updateDisplay, resetDisplay);
}
} else {
Taro.showToast({
title: '请检查手机号',
icon: 'error',
duration: 2000
});
}
}
</script>
<script>
import "./index.less";
import mixin from '@/utils/mixin';
export default {
name: "loginPage",
mixins: [mixin.init],
};
</script>