366 lines
8.1 KiB
Vue
366 lines
8.1 KiB
Vue
<!-- 智慧社区登录页 - 严格还原蓝湖设计图 -->
|
||
<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>
|