完成了登录模块
This commit is contained in:
142
pages/loginModule/forgetPwd/forgetPwd.js
Normal file
142
pages/loginModule/forgetPwd/forgetPwd.js
Normal file
@ -0,0 +1,142 @@
|
||||
// pages/loginModule/forgetPwd/forgetPwd.js
|
||||
const { baseUrl } = require('../../../request');
|
||||
const { validate } = require('../../../utils/validate');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
phone: '',
|
||||
code: '',
|
||||
newPwd: '',
|
||||
confirmPwd: '',
|
||||
countdown: 0,
|
||||
codeButtonText: '发送验证码',
|
||||
_timer: null
|
||||
},
|
||||
|
||||
// 手机号输入
|
||||
onPhoneInput(e) {
|
||||
this.setData({ phone: e.detail.value });
|
||||
},
|
||||
// 验证码输入
|
||||
onCodeInput(e) {
|
||||
this.setData({ code: e.detail.value });
|
||||
},
|
||||
// 新密码输入
|
||||
onNewPwdInput(e) {
|
||||
this.setData({ newPwd: e.detail.value });
|
||||
},
|
||||
// 确认密码输入
|
||||
onConfirmPwdInput(e) {
|
||||
this.setData({ confirmPwd: e.detail.value });
|
||||
},
|
||||
|
||||
// 发送验证码
|
||||
getSmsCode() {
|
||||
const { phone } = this.data;
|
||||
// 1. 非空
|
||||
if (!validate(this.data, { phone: '请输入手机号' })) return;
|
||||
// 2. 格式
|
||||
if (!/^1\d{10}$/.test(phone)) {
|
||||
return wx.showToast({ title: '手机号格式不正确', icon: 'none' });
|
||||
}
|
||||
// 3. 请求验证码
|
||||
wx.request({
|
||||
url: baseUrl + '/userInfo/code',
|
||||
method: 'POST',
|
||||
data: { templateString: phone },
|
||||
success: () => {
|
||||
wx.showToast({ title: '验证码已发送', icon: 'none' });
|
||||
this._startCountdown(60);
|
||||
},
|
||||
fail: () => {
|
||||
wx.showToast({ title: '发送失败,请重试', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 开始倒计时
|
||||
_startCountdown(seconds) {
|
||||
this.setData({
|
||||
countdown: seconds,
|
||||
codeButtonText: `${seconds}s后重试`
|
||||
});
|
||||
if (this.data._timer) return; // 已在倒计时中
|
||||
this.data._timer = setInterval(() => {
|
||||
let cd = this.data.countdown - 1;
|
||||
if (cd <= 0) {
|
||||
this._clearTimer();
|
||||
this.setData({
|
||||
countdown: 0,
|
||||
codeButtonText: '发送验证码'
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
countdown: cd,
|
||||
codeButtonText: `${cd}s后重试`
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// 清除定时器
|
||||
_clearTimer() {
|
||||
if (this.data._timer) {
|
||||
clearInterval(this.data._timer);
|
||||
this.data._timer = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 重置密码
|
||||
resetPassword() {
|
||||
const { phone, code, newPwd, confirmPwd } = this.data;
|
||||
// 1. 非空校验
|
||||
if (!validate(this.data, {
|
||||
phone: '请输入手机号',
|
||||
code: '请输入验证码',
|
||||
newPwd: '请输入新密码',
|
||||
confirmPwd: '请再次输入新密码'
|
||||
})) return;
|
||||
// 2. 密码一致
|
||||
if (newPwd !== confirmPwd) {
|
||||
return wx.showToast({ title: '两次密码不一致', icon: 'none' });
|
||||
}
|
||||
// 3. 格式校验手机号
|
||||
if (!/^1\d{10}$/.test(phone)) {
|
||||
return wx.showToast({ title: '手机号格式不正确', icon: 'none' });
|
||||
}
|
||||
// 4. 发起重置请求
|
||||
wx.request({
|
||||
url: baseUrl + '/userInfo/mini/forgetPwd',
|
||||
method: 'POST',
|
||||
data: {
|
||||
phoneNumber: phone,
|
||||
verificationCode: code,
|
||||
newPassword: newPwd
|
||||
},
|
||||
success: res => {
|
||||
if (res.data.code === 1) {
|
||||
wx.showToast({ title: '重置成功', icon: 'success' });
|
||||
// 清理并跳登录
|
||||
this._clearTimer();
|
||||
setTimeout(() => {
|
||||
wx.navigateTo({ url: '/pages/login/login' });
|
||||
}, 800);
|
||||
} else {
|
||||
wx.showToast({ title: res.data.message||'重置失败', icon: 'none' });
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
wx.showToast({ title: '网络错误,请重试', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 点击“登录账号”回登录页
|
||||
gotoLogin() {
|
||||
wx.navigateTo({ url: '/pages/loginModule/pwdLogin/pwdLogin' });
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
this._clearTimer();
|
||||
}
|
||||
});
|
3
pages/loginModule/forgetPwd/forgetPwd.json
Normal file
3
pages/loginModule/forgetPwd/forgetPwd.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
75
pages/loginModule/forgetPwd/forgetPwd.wxml
Normal file
75
pages/loginModule/forgetPwd/forgetPwd.wxml
Normal file
@ -0,0 +1,75 @@
|
||||
<view class="flex-col page">
|
||||
<image
|
||||
class="self-center image"
|
||||
src="https://ide.code.fun/api/image?token=6827630f4ae84d00122fd0c8&name=f8bf0cb3ec8201f89a31727a655c0709.png"
|
||||
/>
|
||||
<text class="self-center text">欢迎登陆—青橙校园</text>
|
||||
|
||||
<view class="flex-col self-stretch group">
|
||||
<text class="self-start font text_2">忘记密码</text>
|
||||
|
||||
<!-- 手机号 -->
|
||||
<view class="flex-col justify-start self-stretch relative section mt-20">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper view input"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="11"
|
||||
model:value="{{phone}}"
|
||||
bindinput="onPhoneInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="flex-col self-stretch group_2 mt-20">
|
||||
<!-- 验证码 + 发送 -->
|
||||
<view class="flex-row items-center self-stretch relative section_2">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper_2 view_2 input_1"
|
||||
placeholder="请输入验证码"
|
||||
maxlength="6"
|
||||
model:value="{{code}}"
|
||||
bindinput="onCodeInput"
|
||||
/>
|
||||
<text
|
||||
class="flex-col justify-start items-center shrink-0 text-wrapper_3 ml-12 text_6 send-code {{ countdown>0 ? 'disabled' : '' }}"
|
||||
bindtap="{{ countdown>0 ? '' : 'getSmsCode' }}"
|
||||
>{{ codeButtonText }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 新密码 -->
|
||||
<view class="flex-col justify-start self-stretch relative section_1 mt-22">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper text-wrapper_1 input_2"
|
||||
placeholder="请输入密码"
|
||||
password="true"
|
||||
model:value="{{newPwd}}"
|
||||
bindinput="onNewPwdInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 确认密码 -->
|
||||
<view class="flex-col justify-start self-stretch relative section_3 mt-22">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper text-wrapper_5 input_3"
|
||||
placeholder="请再次输入密码"
|
||||
password="true"
|
||||
model:value="{{confirmPwd}}"
|
||||
bindinput="onConfirmPwdInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 登录账号 -->
|
||||
<text
|
||||
class="self-end text_9 mt-22 link"
|
||||
bindtap="gotoLogin"
|
||||
>登录账号</text>
|
||||
|
||||
<!-- 重置密码 按钮 -->
|
||||
<view
|
||||
class="flex-col justify-start items-center self-stretch text-wrapper_4 mt-22 reset-button"
|
||||
bindtap="resetPassword"
|
||||
>
|
||||
<text class="text_10">重置密码</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
131
pages/loginModule/forgetPwd/forgetPwd.wxss
Normal file
131
pages/loginModule/forgetPwd/forgetPwd.wxss
Normal file
@ -0,0 +1,131 @@
|
||||
.page {
|
||||
padding: 86.25rpx 46.2rpx 326.25rpx 49.89rpx;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
.image {
|
||||
width: 232.5rpx;
|
||||
height: 232.5rpx;
|
||||
}
|
||||
.text {
|
||||
margin-top: 37.8rpx;
|
||||
color: #1c2023;
|
||||
font-size: 37.5rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 35.18rpx;
|
||||
}
|
||||
.group {
|
||||
margin-top: 86.14rpx;
|
||||
}
|
||||
.font {
|
||||
font-size: 30rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 27.79rpx;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
.text_2 {
|
||||
color: #1c2023;
|
||||
line-height: 28.09rpx;
|
||||
}
|
||||
.section {
|
||||
margin-left: 2.61rpx;
|
||||
margin-right: 4.42rpx;
|
||||
padding: 20.63rpx 0 18.75rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 11.25rpx #00000040;
|
||||
}
|
||||
.text-wrapper {
|
||||
margin-left: 16.88rpx;
|
||||
margin-right: 16.88rpx;
|
||||
}
|
||||
.view {
|
||||
padding: 15.92rpx 0 12.64rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.group_2 {
|
||||
padding-left: 2.61rpx;
|
||||
}
|
||||
.section_2 {
|
||||
margin-right: 4.42rpx;
|
||||
padding: 20.16rpx 16.88rpx 19.22rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.text-wrapper_2 {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
.view_2 {
|
||||
padding: 12.51rpx 0 15.96rpx;
|
||||
background-color: #ffffff00;
|
||||
height: 66.25rpx;
|
||||
}
|
||||
.text-wrapper_3 {
|
||||
margin-right: 18.77rpx;
|
||||
padding: 13.16rpx 0 10.93rpx;
|
||||
background-color: #ff8d1a;
|
||||
border-radius: 9.38rpx;
|
||||
width: 157.5rpx;
|
||||
height: 45rpx;
|
||||
}
|
||||
.text_6 {
|
||||
color: #ffffff;
|
||||
font-size: 22.5rpx;
|
||||
font-family: AlibabaPuHuiTi;
|
||||
line-height: 20.91rpx;
|
||||
}
|
||||
.section_1 {
|
||||
margin-right: 4.42rpx;
|
||||
padding: 21.56rpx 0 17.81rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.text-wrapper_1 {
|
||||
padding: 13.84rpx 0 14.55rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.section_3 {
|
||||
margin-right: 4.42rpx;
|
||||
padding: 19.22rpx 0 20.16rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.text-wrapper_5 {
|
||||
padding: 13.37rpx 0 14.87rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.text_9 {
|
||||
color: #1c2023;
|
||||
font-size: 26.25rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 24.23rpx;
|
||||
}
|
||||
.text-wrapper_4 {
|
||||
margin-right: 4.42rpx;
|
||||
padding: 36.04rpx 0 34.01rpx;
|
||||
background-color: #ff8d1a;
|
||||
border-radius: 9.38rpx;
|
||||
}
|
||||
.text_10 {
|
||||
color: #ffffff;
|
||||
font-size: 30rpx;
|
||||
font-family: AlibabaPuHuiTi;
|
||||
line-height: 27.45rpx;
|
||||
}
|
||||
.input {
|
||||
padding: 15rpx 16.26rpx 13.13rpx 16.26rpx;
|
||||
}
|
||||
.input_1 {
|
||||
padding: 13.13rpx 16.26rpx 16.88rpx 16.26rpx;
|
||||
}
|
||||
.input_2 {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
||||
.input_3 {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
181
pages/loginModule/pwdLogin/pwdLogin.js
Normal file
181
pages/loginModule/pwdLogin/pwdLogin.js
Normal file
@ -0,0 +1,181 @@
|
||||
// pages/login/login.js
|
||||
const { baseUrl } = require('../../../request');
|
||||
const { validate } = require('../../../utils/validate');
|
||||
|
||||
Page({
|
||||
data: {
|
||||
loginType: 'password', // 'password' 或 'sms'
|
||||
phone: '',
|
||||
credential: '',
|
||||
isAgree: false, // 用户协议是否勾选
|
||||
countdown: 0, // 剩余秒数
|
||||
codeButtonText: '获取验证码',
|
||||
_timer: null
|
||||
},
|
||||
|
||||
// 切换到“密码登录”,只清空表单字段
|
||||
switchToPassword() {
|
||||
this.setData({
|
||||
loginType: 'password',
|
||||
phone: '',
|
||||
credential: ''
|
||||
// 不清除 countdown、codeButtonText、_timer
|
||||
});
|
||||
},
|
||||
|
||||
// 切换到“验证码登录”,只清空表单字段
|
||||
switchToSms() {
|
||||
this.setData({
|
||||
loginType: 'sms',
|
||||
phone: '',
|
||||
credential: ''
|
||||
// 不清除 countdown、codeButtonText、_timer
|
||||
});
|
||||
},
|
||||
|
||||
// 手机号输入
|
||||
onPhoneInput(e) {
|
||||
this.setData({ phone: e.detail.value });
|
||||
},
|
||||
|
||||
// 密码/验证码输入
|
||||
onCredentialInput(e) {
|
||||
this.setData({ credential: e.detail.value });
|
||||
},
|
||||
|
||||
// 协议勾选
|
||||
onAgreeChange(e) {
|
||||
this.setData({ isAgree: e.detail.value.includes('agree') });
|
||||
},
|
||||
|
||||
// 获取验证码(仅校验手机号)
|
||||
getSmsCode() {
|
||||
const { phone } = this.data;
|
||||
|
||||
// 1. 非空校验
|
||||
if (!validate(this.data, { phone: '请输入手机号' })) {
|
||||
return;
|
||||
}
|
||||
// 2. 格式校验
|
||||
if (!/^1\d{10}$/.test(phone)) {
|
||||
return wx.showToast({ title: '手机号格式不正确', icon: 'none' });
|
||||
}
|
||||
|
||||
// 3. 发送验证码请求
|
||||
wx.request({
|
||||
url: baseUrl + '/userInfo/code',
|
||||
method: 'POST',
|
||||
data: { templateString: phone },
|
||||
success: () => {
|
||||
wx.showToast({ title: '验证码已发送', icon: 'none' });
|
||||
this._startCountdown(60);
|
||||
},
|
||||
fail: () => {
|
||||
wx.showToast({ title: '发送失败,请重试', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 开始倒计时
|
||||
_startCountdown(seconds) {
|
||||
this.setData({
|
||||
countdown: seconds,
|
||||
codeButtonText: `${seconds}s后重试`
|
||||
});
|
||||
// 如果已有定时器,不重复创建
|
||||
if (this.data._timer) return;
|
||||
this.data._timer = setInterval(() => {
|
||||
const cd = this.data.countdown - 1;
|
||||
if (cd <= 0) {
|
||||
this._clearTimer();
|
||||
this.setData({
|
||||
countdown: 0,
|
||||
codeButtonText: '获取验证码'
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
countdown: cd,
|
||||
codeButtonText: `${cd}s后重试`
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// 清除倒计时定时器
|
||||
_clearTimer() {
|
||||
if (this.data._timer) {
|
||||
clearInterval(this.data._timer);
|
||||
this.data._timer = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 登录
|
||||
onLogin() {
|
||||
const { loginType, phone, credential, isAgree } = this.data;
|
||||
|
||||
// 非空校验(手机号、密码/验证码、协议)
|
||||
if (!validate(this.data, {
|
||||
phone: '请输入手机号',
|
||||
credential: loginType === 'password' ? '请输入密码' : '请输入验证码',
|
||||
isAgree: '请先同意用户协议'
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
// 手机号格式校验
|
||||
if (!/^1\d{10}$/.test(phone)) {
|
||||
return wx.showToast({ title: '手机号格式不正确', icon: 'none' });
|
||||
}
|
||||
|
||||
// 组装请求
|
||||
const url = loginType === 'password'
|
||||
? baseUrl + '/userInfo/mini/pwd/login'
|
||||
: baseUrl + '/userInfo/mini/vcd/login';
|
||||
const payload = loginType === 'password'
|
||||
? { phoneNumber: phone, userPassword: credential }
|
||||
: { phoneNumber: phone, verificationCode: credential };
|
||||
|
||||
wx.request({
|
||||
url,
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
success: res => {
|
||||
if (res.data.code === 1) {
|
||||
// ← 新增:从返回数据中取出 token
|
||||
const token = res.data.data.token || res.data.data;
|
||||
// ← 新增:将 token 存到本地缓存
|
||||
wx.setStorageSync('token', token);
|
||||
|
||||
wx.showToast({ title: '登录成功', icon: 'success' });
|
||||
wx.navigateTo({
|
||||
url: '/pages/projectModule/projectList/projectList'
|
||||
});
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: res.data.message || '登录失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
wx.showToast({ title: '网络错误,请重试', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
gotoForgetPwd() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/loginModule/forgetPwd/forgetPwd',
|
||||
})
|
||||
},
|
||||
|
||||
gotoRegister() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/loginModule/register/register',
|
||||
})
|
||||
},
|
||||
|
||||
// 页面卸载时清理定时器
|
||||
onUnload() {
|
||||
this._clearTimer();
|
||||
}
|
||||
});
|
3
pages/loginModule/pwdLogin/pwdLogin.json
Normal file
3
pages/loginModule/pwdLogin/pwdLogin.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
87
pages/loginModule/pwdLogin/pwdLogin.wxml
Normal file
87
pages/loginModule/pwdLogin/pwdLogin.wxml
Normal file
@ -0,0 +1,87 @@
|
||||
<view class="flex-col page">
|
||||
<image
|
||||
class="self-center image"
|
||||
src="https://ide.code.fun/api/image?token=6827630f4ae84d00122fd0c8&name=f8bf0cb3ec8201f89a31727a655c0709.png"
|
||||
/>
|
||||
<text class="self-center text">欢迎登陆—青橙校园</text>
|
||||
<view class="flex-col self-stretch group">
|
||||
|
||||
<!-- 切换登录方式 -->
|
||||
<view class="flex-row">
|
||||
<text
|
||||
class="font switch {{loginType==='password'?'active':'inactive'}} text_2"
|
||||
bindtap="switchToPassword"
|
||||
>密码登录</text>
|
||||
<text
|
||||
class="font switch {{loginType==='sms'?'active':'inactive'}} text_3 ml-8"
|
||||
bindtap="switchToSms"
|
||||
>验证码登录</text>
|
||||
</view>
|
||||
|
||||
<view class="flex-col group_1 mt-20">
|
||||
|
||||
<!-- 手机号输入 -->
|
||||
<view class="flex-col self-stretch">
|
||||
<view class="flex-col justify-start relative section">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper view input"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="11"
|
||||
model:value="{{phone}}"
|
||||
bindinput="onPhoneInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 密码 / 验证码 输入 + 获取验证码按钮 -->
|
||||
<view class="flex-row items-center section_2 mt-21">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper_2 view_2 input_1"
|
||||
placeholder="{{ loginType==='password' ? '请输入密码' : '请输入验证码' }}"
|
||||
password="{{ loginType==='password' }}"
|
||||
model:value="{{credential}}"
|
||||
bindinput="onCredentialInput"
|
||||
/>
|
||||
<text
|
||||
wx:if="{{loginType==='sms'}}"
|
||||
class="text_6 ml-10 get-code {{ countdown>0 ? 'disabled' : '' }}"
|
||||
bindtap="{{ countdown>0 ? '' : 'getSmsCode' }}"
|
||||
>{{ codeButtonText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text class="self-end font_3 text_7" bindtap="gotoForgetPwd">忘记密码</text>
|
||||
|
||||
<!-- 登录按钮 -->
|
||||
<view
|
||||
class="flex-col justify-start items-center self-stretch text-wrapper_3 login-button"
|
||||
bindtap="onLogin"
|
||||
>
|
||||
<text class="text_8">登录</text>
|
||||
</view>
|
||||
|
||||
<!-- 用户协议勾选 -->
|
||||
<view class="flex-row items-center self-stretch group_2">
|
||||
<checkbox-group bindchange="onAgreeChange">
|
||||
<checkbox
|
||||
class="checkbox"
|
||||
value="agree"
|
||||
checked="{{isAgree}}"
|
||||
bindchange="onAgreeChange"
|
||||
color="#FF8D1A"
|
||||
/>
|
||||
</checkbox-group>
|
||||
<view class="group_3 ml-12">
|
||||
<text class="font_4 text_9">登录代表您已同意</text>
|
||||
<text class="font_4">《用户协议》</text>
|
||||
<text class="text_10">&</text>
|
||||
<text class="font_4">《隐私协议》</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="self-center group_4">
|
||||
<text class="font_3 text_11">没有账号?</text>
|
||||
<text class="font_4 text_12" bindtap="gotoRegister">去注册→</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
163
pages/loginModule/pwdLogin/pwdLogin.wxss
Normal file
163
pages/loginModule/pwdLogin/pwdLogin.wxss
Normal file
@ -0,0 +1,163 @@
|
||||
/* 切换按钮样式 */
|
||||
.switch {
|
||||
font-size: 30rpx; /* 基础字体大小 */
|
||||
font-family: SourceHanSansCN;
|
||||
}
|
||||
.switch.active {
|
||||
font-size: 36rpx; /* 激活时更大 */
|
||||
font-weight: bold; /* 加粗 */
|
||||
color: #1c2023;
|
||||
}
|
||||
.switch.inactive {
|
||||
color: #888888; /* 不活跃时灰色 */
|
||||
}
|
||||
|
||||
/* 其它原来样式保持不变 */
|
||||
.mt-21 {
|
||||
margin-top: 39.38rpx;
|
||||
}
|
||||
.page {
|
||||
padding: 105rpx 45.69rpx 381.68rpx 49.76rpx;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
.image {
|
||||
width: 232.5rpx;
|
||||
height: 232.5rpx;
|
||||
}
|
||||
.text {
|
||||
margin-top: 35.14rpx;
|
||||
color: #1c2023;
|
||||
font-size: 37.5rpx;
|
||||
font-family: AlibabaPuHuiTi;
|
||||
line-height: 35.21rpx;
|
||||
}
|
||||
.group {
|
||||
margin-top: 145.01rpx;
|
||||
}
|
||||
.font {
|
||||
font-size: 30rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 27.69rpx;
|
||||
color: #1c2023;
|
||||
}
|
||||
.text_2 {
|
||||
line-height: 28.29rpx;
|
||||
}
|
||||
.text_3 {
|
||||
line-height: 28.2rpx;
|
||||
}
|
||||
.group_1 {
|
||||
padding-left: 2.74rpx;
|
||||
}
|
||||
.section {
|
||||
margin-right: 4.93rpx;
|
||||
padding: 20.63rpx 0 18.75rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 11.25rpx #00000040;
|
||||
}
|
||||
.text-wrapper {
|
||||
margin-left: 16.88rpx;
|
||||
margin-right: 16.88rpx;
|
||||
}
|
||||
.view {
|
||||
padding: 15.92rpx 0 12.64rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.section_2 {
|
||||
margin-right: 4.93rpx;
|
||||
padding: 20.63rpx 16.88rpx 18.75rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.text-wrapper_2 {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
.view_2 {
|
||||
padding: 11.96rpx 0 16.43rpx;
|
||||
background-color: #ffffff00;
|
||||
height: 76.25rpx;
|
||||
}
|
||||
.text_6 {
|
||||
margin-right: 14.72rpx;
|
||||
color: #f7810a;
|
||||
font-size: 26.25rpx;
|
||||
font-family: AlibabaPuHuiTi;
|
||||
line-height: 23.94rpx;
|
||||
}
|
||||
.get-code {
|
||||
/* 可根据需求再调样式 */
|
||||
}
|
||||
.font_3 {
|
||||
font-size: 26.25rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 24.49rpx;
|
||||
color: #383838;
|
||||
}
|
||||
.text_7 {
|
||||
margin-top: 28.76rpx;
|
||||
line-height: 24.36rpx;
|
||||
}
|
||||
.text-wrapper_3 {
|
||||
margin-right: 4.93rpx;
|
||||
margin-top: 46.26rpx;
|
||||
padding: 36.73rpx 0 34.16rpx;
|
||||
background-color: #ff8d1a;
|
||||
border-radius: 9.38rpx;
|
||||
}
|
||||
.text_8 {
|
||||
color: #ffffff;
|
||||
font-size: 30rpx;
|
||||
font-family: AlibabaPuHuiTi;
|
||||
line-height: 26.61rpx;
|
||||
}
|
||||
.group_2 {
|
||||
margin-top: 48.75rpx;
|
||||
}
|
||||
.group_3 {
|
||||
line-height: 24.49rpx;
|
||||
height: 24.56rpx;
|
||||
}
|
||||
.font_4 {
|
||||
font-size: 26.25rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 24.49rpx;
|
||||
color: #ff5e00;
|
||||
}
|
||||
.text_9 {
|
||||
color: #1c2023;
|
||||
line-height: 24.43rpx;
|
||||
}
|
||||
.text_10 {
|
||||
color: #1c2023;
|
||||
font-size: 26.25rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 19.93rpx;
|
||||
}
|
||||
.group_4 {
|
||||
margin-top: 43.91rpx;
|
||||
line-height: 24.41rpx;
|
||||
}
|
||||
.text_11 {
|
||||
line-height: 24.28rpx;
|
||||
}
|
||||
.text_12 {
|
||||
line-height: 24.41rpx;
|
||||
}
|
||||
.input {
|
||||
padding: 15rpx 16.26rpx 13.13rpx 16.26rpx;
|
||||
}
|
||||
.input_1 {
|
||||
padding: 15rpx 16.26rpx 13.13rpx 16.26rpx;
|
||||
}
|
||||
.checkbox {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.checkbox .wx-checkbox-input {
|
||||
width: 37.5rpx;
|
||||
height: 37.5rpx;
|
||||
}
|
194
pages/loginModule/register/register.js
Normal file
194
pages/loginModule/register/register.js
Normal file
@ -0,0 +1,194 @@
|
||||
import { url } from "../../../request";
|
||||
import { requestAsync } from "../../../utils/request";
|
||||
import { validate } from "../../../utils/validate";
|
||||
|
||||
// pages/loginModule/register/register.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
nickname: 'cxz',
|
||||
phone: '13888610253',
|
||||
captcha: '111111',
|
||||
inviteCode: '123456',
|
||||
password: '123456',
|
||||
agree: false,
|
||||
sending: false,
|
||||
count: 60,
|
||||
},
|
||||
|
||||
sendSmsCode() {
|
||||
const { phone } = this.data;
|
||||
if (!/^1\d{10}$/.test(phone)) {
|
||||
wx.showToast({ title: '请输入有效的手机号', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
wx.request({
|
||||
url: url + '/userInfo/code',
|
||||
method: 'POST',
|
||||
header: { 'content-type': 'application/json' },
|
||||
data: {
|
||||
templateString: phone
|
||||
},
|
||||
success: res => {
|
||||
// 假设后端返回 { success: true, ... }
|
||||
if (res.data.code === 1) {
|
||||
wx.showToast({ title: '验证码已发送' });
|
||||
this.startCountdown();
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: res.data.message || '发送失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
startCountdown() {
|
||||
this.setData({ sending: true, count: 60 });
|
||||
const timer = setInterval(() => {
|
||||
let { count } = this.data;
|
||||
if (count <= 1) {
|
||||
clearInterval(timer);
|
||||
this.setData({ sending: false });
|
||||
} else {
|
||||
this.setData({ count: count - 1 });
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// 通用输入事件处理函数
|
||||
onInput(e) {
|
||||
const field = e.currentTarget.dataset.field; // 获取字段名
|
||||
const value = e.detail.value; // 获取输入内容
|
||||
this.setData({
|
||||
[field]: value // 动态更新对应字段
|
||||
});
|
||||
},
|
||||
|
||||
// 复选框事件处理(如果使用 checkbox-group 推荐用 change)
|
||||
onCheckboxChange(e) {
|
||||
this.setData({
|
||||
agree: e.detail.value.length > 0
|
||||
});
|
||||
},
|
||||
|
||||
// 注册按钮点击
|
||||
async onRegister() {
|
||||
if (!this.data.agree) {
|
||||
wx.showToast({
|
||||
title: '请先勾选同意协议',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 调用通用校验,失败时已提示并 return
|
||||
if (!validate(this.data, {
|
||||
agree: '请先勾选同意协议',
|
||||
nickname: '请输入昵称',
|
||||
phone: '请输入手机号',
|
||||
captcha: '请输入验证码',
|
||||
inviteCode: '请输入邀请码',
|
||||
password: '请输入密码'
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
const { nickname, phone, captcha, inviteCode, password } = this.data;
|
||||
const res = await requestAsync({
|
||||
url: url + '/userInfo/register',
|
||||
method: 'POST',
|
||||
header: { 'content-type': 'application/json' },
|
||||
data: {
|
||||
nickName: nickname,
|
||||
phoneNumber: phone,
|
||||
verificationCode: captcha,
|
||||
invitationCode: inviteCode,
|
||||
userPassword: password
|
||||
}
|
||||
});
|
||||
if (res.data.code === 1) {
|
||||
wx.showToast({
|
||||
title: '注册成功',
|
||||
icon: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
setTimeout(() => {
|
||||
wx.navigateTo({
|
||||
url: '/pages/loginModule/pwdLogin/pwdLogin',
|
||||
success: () => {
|
||||
this.setData({ nickname:'', phone:'', captcha:'', inviteCode:'', password:'', agree:false });
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: res.data.message || '注册失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
gotoLogin() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/loginModule/pwdLogin/pwdLogin',
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
|
||||
}
|
||||
})
|
3
pages/loginModule/register/register.json
Normal file
3
pages/loginModule/register/register.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
74
pages/loginModule/register/register.wxml
Normal file
74
pages/loginModule/register/register.wxml
Normal file
@ -0,0 +1,74 @@
|
||||
<view class="flex-col page">
|
||||
<image
|
||||
class="self-center image"
|
||||
src="https://ide.code.fun/api/image?token=68274ca04ae84d00122fcf90&name=f8bf0cb3ec8201f89a31727a655c0709.png"
|
||||
/>
|
||||
<text class="self-center text">欢迎登陆—青橙校园</text>
|
||||
<view class="flex-col self-stretch group">
|
||||
<view class="flex-col register">
|
||||
<text class="self-start font text_2">账号注册</text>
|
||||
<view class="flex-col self-stretch group_6 mt-20">
|
||||
<view class="flex-col">
|
||||
<view class="flex-col justify-start relative section">
|
||||
<input class="flex-col justify-start items-start text-wrapper_5 view input"
|
||||
placeholder="请输入昵称"
|
||||
bindinput="onInput" data-field="nickname" value="{{nickname}}"
|
||||
/>
|
||||
</view>
|
||||
<view class="flex-col justify-start section_1 mt-22">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper_5 text-wrapper_1 input_1"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="11"
|
||||
bindinput="onInput" data-field="phone" value="{{phone}}"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row items-center relative section_3 mt-22">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper_2 view_6 input_2"
|
||||
placeholder="请输入验证码"
|
||||
maxlength="6"
|
||||
bindinput="onInput" data-field="captcha" value="{{captcha}}"
|
||||
/>
|
||||
<view bindtap="{{sending ? '' : 'sendSmsCode'}}" class="flex-col justify-start items-center shrink-0 text-wrapper_3 ml-18">
|
||||
<text class="text_7">{{ sending ? count + 's后重发' : '发送验证码' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-col mt-22">
|
||||
<view class="flex-col justify-start relative section_2">
|
||||
<input
|
||||
class="flex-col justify-start items-start text-wrapper_5 view_1 input_3"
|
||||
placeholder="请输入邀请码"
|
||||
maxlength="6"
|
||||
bindinput="onInput" data-field="inviteCode" value="{{inviteCode}}"
|
||||
/>
|
||||
</view>
|
||||
<view class="flex-col justify-start section_2 mt-22">
|
||||
<input class="flex-col justify-start items-start text-wrapper_5 view_3 input_4"
|
||||
placeholder="请输入密码"
|
||||
bindinput="onInput" data-field="password" value="{{password}}"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row items-center group_1 mt-26">
|
||||
<!-- 复选框 -->
|
||||
<checkbox-group bindchange="onCheckboxChange">
|
||||
<checkbox value="agree" checked="{{agree}}" color="#FF8D1A" />
|
||||
</checkbox-group>
|
||||
<view class="group_2 ml-13">
|
||||
<text class="font_2 text_10">我已阅读并同意</text>
|
||||
<text class="font_2">《用户协议》</text>
|
||||
<text class="text_11">&</text>
|
||||
<text class="font_2">《隐私协议》</text>
|
||||
</view>
|
||||
</view>
|
||||
<view bindtap="onRegister" class="flex-col justify-start items-center text-wrapper_6 mt-26"><text class="font text_12">注册</text></view>
|
||||
</view>
|
||||
<view class="self-center group_3">
|
||||
<text class="font_2 text_13">已有账号?</text>
|
||||
<text bindtap="gotoLogin" class="font_2 text_14" >立即登录→</text>
|
||||
</view>
|
||||
</view>
|
172
pages/loginModule/register/register.wxss
Normal file
172
pages/loginModule/register/register.wxss
Normal file
@ -0,0 +1,172 @@
|
||||
.ml-13 {
|
||||
margin-left: 24.38rpx;
|
||||
}
|
||||
.page {
|
||||
padding: 0rpx 49.74rpx 79.82rpx 49.74rpx;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
.register {
|
||||
margin-top: -30rpx;
|
||||
}
|
||||
.image {
|
||||
width: 232.5rpx;
|
||||
height: 232.5rpx;
|
||||
}
|
||||
.text {
|
||||
margin-top: 37.8rpx;
|
||||
color: #1c2023;
|
||||
font-size: 37.5rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 35.18rpx;
|
||||
}
|
||||
.group {
|
||||
margin-top: 86.36rpx;
|
||||
}
|
||||
.font {
|
||||
font-size: 30rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 27.79rpx;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
.text_2 {
|
||||
color: #1c2023;
|
||||
line-height: 28.2rpx;
|
||||
}
|
||||
.group_6 {
|
||||
padding-left: 2.76rpx;
|
||||
}
|
||||
.section {
|
||||
padding: 20.63rpx 0 18.75rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 11.25rpx #00000040;
|
||||
}
|
||||
.text-wrapper_5 {
|
||||
margin-left: 16.88rpx;
|
||||
margin-right: 16.88rpx;
|
||||
}
|
||||
.view {
|
||||
padding: 15.92rpx 0 12.62rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.section_1 {
|
||||
padding: 20.16rpx 0 19.22rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.text-wrapper_1 {
|
||||
padding: 12.64rpx 0 15.92rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.section_3 {
|
||||
padding: 25.63rpx 16.88rpx 28.75rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.text-wrapper_2 {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
.view_6 {
|
||||
padding: 16.73rpx 0 11.74rpx;
|
||||
background-color: #ffffff00;
|
||||
height: 66.25rpx;
|
||||
}
|
||||
.text-wrapper_3 {
|
||||
margin-right: 15rpx;
|
||||
padding: 13.16rpx 0 10.93rpx;
|
||||
background-color: #ff8d1a;
|
||||
border-radius: 9.38rpx;
|
||||
width: 157.5rpx;
|
||||
height: 45rpx;
|
||||
}
|
||||
.text_7 {
|
||||
color: #ffffff;
|
||||
font-size: 22.5rpx;
|
||||
font-family: AlibabaPuHuiTi;
|
||||
line-height: 20.91rpx;
|
||||
}
|
||||
.section_2 {
|
||||
padding: 20.63rpx 0 18.75rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 9.38rpx;
|
||||
box-shadow: 0rpx 3.75rpx 7.5rpx #00000040;
|
||||
}
|
||||
.view_1 {
|
||||
padding: 11.7rpx 0 16.89rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.view_3 {
|
||||
padding: 11.96rpx 0 16.29rpx;
|
||||
background-color: #ffffff00;
|
||||
}
|
||||
.group_1 {
|
||||
padding: 0 2.76rpx;
|
||||
}
|
||||
.group_2 {
|
||||
line-height: 24.56rpx;
|
||||
height: 24.56rpx;
|
||||
}
|
||||
.font_2 {
|
||||
font-size: 26.25rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 24.49rpx;
|
||||
color: #ff5e00;
|
||||
}
|
||||
.text_10 {
|
||||
color: #1c2023;
|
||||
line-height: 24.56rpx;
|
||||
}
|
||||
.text_11 {
|
||||
color: #1c2023;
|
||||
font-size: 26.25rpx;
|
||||
font-family: SourceHanSansCN;
|
||||
line-height: 19.93rpx;
|
||||
}
|
||||
.text-wrapper_6 {
|
||||
margin-left: 2.76rpx;
|
||||
padding: 37.63rpx 0 32.27rpx;
|
||||
background-color: #ff8d1a;
|
||||
border-radius: 9.38rpx;
|
||||
}
|
||||
.text_12 {
|
||||
color: #ffffff;
|
||||
line-height: 27.6rpx;
|
||||
}
|
||||
.group_3 {
|
||||
margin-top: 37rpx;
|
||||
line-height: 24.36rpx;
|
||||
}
|
||||
.text_13 {
|
||||
color: #383838;
|
||||
line-height: 24.28rpx;
|
||||
}
|
||||
.text_14 {
|
||||
line-height: 24.36rpx;
|
||||
}
|
||||
.input {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
||||
.input_1 {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
||||
.input_2 {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
||||
.input_3 {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
||||
.input_4 {
|
||||
padding: 13.13rpx 16.26rpx 15rpx 16.26rpx;
|
||||
}
|
||||
.checkbox {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.checkbox .wx-checkbox-input {
|
||||
width: 37.5rpx;
|
||||
height: 37.5rpx;
|
||||
}
|
Reference in New Issue
Block a user