fjrcloud-community-app/pages/index/login-page.vue

366 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 智慧社区登录页 - 严格还原蓝湖设计图 -->
<template>
<view class="login-page">
<!-- 状态栏占位 -->
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
<!-- 顶部Logo区域 -->
<view class="logo-section">
<image class="logo-img" src="/static/img/login_img.png" mode="aspectFit"></image>
<text class="logo-title">智慧社区</text>
</view>
<!-- 表单区域 -->
<view class="form-section">
<!-- 手机号输入框 -->
<view class="input-wrapper">
<input
class="form-input"
type="number"
maxlength="11"
placeholder="请输入账号/手机号"
placeholder-class="input-placeholder"
v-model="formData.mobile"
/>
</view>
<!-- 验证码输入框 -->
<view class="input-wrapper">
<input
class="form-input"
type="number"
maxlength="4"
placeholder="请输入验证码"
placeholder-class="input-placeholder"
v-model="formData.code"
/>
<view
class="code-btn"
:class="{ 'code-btn-disabled': !canSendCode }"
@tap="handleSendCode"
>
{{ codeBtnText }}
</view>
</view>
<!-- 登录按钮 -->
<view class="login-btn" @tap="handleLogin">
<text class="btn-text">登陆</text>
</view>
<!-- 隐私协议 -->
<view class="agreement-box" @tap="toggleAgreement">
<view class="checkbox" :class="{ checked: agreed }">
<text v-if="agreed" class="check-icon">✓</text>
</view>
<text class="agreement-text">已充分阅读并同意隐私政策和用户协议</text>
</view>
</view>
<!-- 底部微信登录 -->
<view class="wechat-login" @tap="wechatLogin">
<image class="wechat-icon" src="/static/img/wx-icon.png" mode="aspectFit"></image>
</view>
</view>
</template>
<script setup>
import { ref, reactive, computed } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import sheep from '@/sheep';
import AuthUtil from '@/sheep/api/member/auth';
import { getSmsTimer } from '@/sheep/hooks/useModal';
// 状态栏高度
const statusBarHeight = ref(0);
// 表单数据
const formData = reactive({
mobile: '',
code: '',
});
// 协议同意状态
const agreed = ref(false);
// 倒计时相关
const countdown = ref(0);
let timer = null;
// 是否可以发送验证码
const canSendCode = computed(() => countdown.value <= 0);
// 按钮文案
const codeBtnText = computed(() => {
if (countdown.value > 0) {
return `${countdown.value}s`;
}
return '获取验证码';
});
onLoad(() => {
// 获取状态栏高度
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = systemInfo.statusBarHeight || 0;
});
// 切换协议同意状态
const toggleAgreement = () => {
agreed.value = !agreed.value;
};
// 手机号格式校验
const validateMobile = (mobile) => {
return /^1[3-9]\d{9}$/.test(mobile);
};
// 发送验证码
const handleSendCode = () => {
if (!canSendCode.value) return;
if (!agreed.value) {
uni.showToast({ title: '请先同意隐私政策和用户协议', icon: 'none' });
return;
}
if (!formData.mobile) {
uni.showToast({ title: '请输入手机号', icon: 'none' });
return;
}
if (!validateMobile(formData.mobile)) {
uni.showToast({ title: '手机号格式不正确', icon: 'none' });
return;
}
// 调用发送验证码接口
AuthUtil.sendSmsCode(formData.mobile, 1).then((res) => {
if (res.code === 0) {
// 开始倒计时
countdown.value = 60;
timer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer);
timer = null;
}
}, 1000);
}
});
};
// 登录处理
const handleLogin = async () => {
if (!agreed.value) {
uni.showToast({ title: '请先同意隐私政策和用户协议', icon: 'none' });
return;
}
if (!formData.mobile) {
uni.showToast({ title: '请输入手机号', icon: 'none' });
return;
}
if (!validateMobile(formData.mobile)) {
uni.showToast({ title: '手机号格式不正确', icon: 'none' });
return;
}
if (!formData.code) {
uni.showToast({ title: '请输入验证码', icon: 'none' });
return;
}
// 调用短信登录接口
const { code } = await AuthUtil.smsLogin({
mobile: formData.mobile,
code: formData.code,
});
if (code === 0) {
// 登录成功,获取用户信息
await sheep.$store('user').getInfo();
// 返回上一页
uni.navigateBack();
}
};
// 微信登录
const wechatLogin = async () => {
if (!agreed.value) {
uni.showToast({ title: '请先同意隐私政策和用户协议', icon: 'none' });
return;
}
// 微信小程序环境下使用微信登录
if (sheep.$platform.name === 'WechatMiniProgram') {
const result = await sheep.$platform.useProvider('wechat').login();
if (result) {
await sheep.$store('user').getInfo();
uni.navigateBack();
} else {
uni.showToast({ title: '微信登录失败', icon: 'none' });
}
} else {
uni.showToast({ title: '当前环境不支持微信登录', icon: 'none' });
}
};
</script>
<style lang="scss" scoped>
// 页面容器 - flex布局禁止滚动
.login-page {
height: 100vh;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #F5F7FA 0%, #FFFFFF 100%);
overflow: hidden;
}
// 状态栏占位
.status-bar {
width: 100%;
flex-shrink: 0;
background: transparent;
}
// 顶部Logo区域 - 可收缩
.logo-section {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 120rpx;
padding-bottom: 80rpx;
flex-shrink: 0;
.logo-img {
width: 280rpx;
height: 280rpx;
margin-bottom: 32rpx;
}
.logo-title {
font-size: 48rpx;
font-weight: 600;
color: #333333;
font-family: 'PingFang SC', sans-serif;
}
}
// 表单区域 - 可收缩
.form-section {
padding: 0 59rpx;
flex-shrink: 0;
// 输入框容器
.input-wrapper {
width: 632rpx;
height: 107rpx;
background: #F7F8F9;
border-radius: 15rpx;
border: 2rpx solid #D9E1EF;
margin-bottom: 32rpx;
display: flex;
align-items: center;
padding: 0 32rpx;
box-sizing: border-box;
.form-input {
flex: 1;
height: 100%;
font-size: 28rpx;
color: #333333;
font-family: 'PingFang SC', sans-serif;
}
.input-placeholder {
font-size: 28rpx;
color: #999999;
font-family: 'PingFang SC', sans-serif;
}
// 获取验证码按钮
.code-btn {
font-size: 26rpx;
color: #FD9568;
font-family: 'PingFang SC', sans-serif;
flex-shrink: 0;
padding-left: 20rpx;
&.code-btn-disabled {
color: #CCCCCC;
}
}
}
// 登录按钮
.login-btn {
width: 632rpx;
height: 107rpx;
background: #FD9568;
border-radius: 31rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 48rpx;
margin-bottom: 40rpx;
.btn-text {
font-size: 32rpx;
font-weight: 500;
color: #FFFFFF;
font-family: 'PingFang SC', sans-serif;
}
}
// 隐私协议
.agreement-box {
display: flex;
align-items: center;
justify-content: center;
.checkbox {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #D9E1EF;
border-radius: 6rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12rpx;
flex-shrink: 0;
&.checked {
background: #FD9568;
border-color: #FD9568;
.check-icon {
font-size: 20rpx;
color: #FFFFFF;
}
}
}
.agreement-text {
font-size: 24rpx;
color: #999999;
font-family: 'PingFang SC', sans-serif;
}
}
}
// 底部微信登录 - 自动推到底部
.wechat-login {
flex: 1;
display: flex;
align-items: flex-end;
justify-content: center;
padding-bottom: 80rpx;
.wechat-icon {
width: 88rpx;
height: 88rpx;
}
}
</style>