first commit
This commit is contained in:
373
pages/Login/Login.vue
Normal file
373
pages/Login/Login.vue
Normal file
@@ -0,0 +1,373 @@
|
||||
<template>
|
||||
<view class="status-bar"></view>
|
||||
<view class="login-container page-container">
|
||||
<view class="login-card">
|
||||
<!-- <view class="conner conner-tl"></view>
|
||||
<view class="conner conner-tr"></view>
|
||||
<view class="conner conner-bl"></view>
|
||||
<view class="conner conner-br"></view> -->
|
||||
<view class="login-header">
|
||||
<view class="login-header-logo">
|
||||
<view class="icon-wrapper">
|
||||
<view class="iconfont icon-brain-2-fill danao-style"></view>
|
||||
</view>
|
||||
<text>YXD</text>
|
||||
</view>
|
||||
<view class="sub-title">File Handling Chat</view>
|
||||
|
||||
</view>
|
||||
<!-- 表单 -->
|
||||
<view class="form-wrapper">
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<!-- <uni-icons type="person" size="24" color="#aaaaff"></uni-icons> -->
|
||||
<text>用户名</text>
|
||||
</view>
|
||||
<input class="form-input" :class="{focused: isUsernameFocused, error: isUsernameError}"
|
||||
v-model="UsernameValue" @focus="usernameFocused" @blur="handleUsernameBlur"
|
||||
@input="validateUsername" placeholder="请输入用户名" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
<!-- <uni-icons type="locked" size="24" color="#aaaaff"></uni-icons> -->
|
||||
<text>密码</text>
|
||||
</view>
|
||||
<input type="password" class="form-input"
|
||||
:class="{focused: isPasswordFocused, error: isPasswordError}" v-model="PasswordValue"
|
||||
@focus="passwordFocused" @blur="handlePasswordBlur" placeholder="请输入密码" />
|
||||
</view>
|
||||
<text v-if="formDataHasNull" class="error-info">用户名或密码不能为空</text>
|
||||
<view class="form-option">
|
||||
<view class="checkbox-wrapper" @click="form.remember = !form.remember">
|
||||
<view class="checkbox" :class="{ checked: form.remember}">
|
||||
<text v-if="form.remember">✓</text>
|
||||
</view>
|
||||
<text class="checkbox-text">记住密码</text>
|
||||
|
||||
</view>
|
||||
<text class="forget-pwd">忘记密码?</text>
|
||||
</view>
|
||||
<button class="login-btn" :disabled="loading" :loading="loading"
|
||||
@click="handleLogin">{{loading ? 'Loading...' : '登录'}}</button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
ref,
|
||||
computed,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
import {
|
||||
login
|
||||
} from '../../utils/cloud-api';
|
||||
|
||||
// 表单用户名变量
|
||||
const UsernameValue = ref('');
|
||||
const isUsernameFocused = ref(false);
|
||||
const isUsernameError = ref(false)
|
||||
const usernameFocused = () => {
|
||||
isUsernameFocused.value = true;
|
||||
formDataHasNull.value = false;
|
||||
}
|
||||
const handleUsernameBlur = () => {
|
||||
isUsernameFocused.value = false;
|
||||
}
|
||||
// 用户名实时校验
|
||||
const validateUsername = () => {
|
||||
// if (UsernameValue.value && UsernameValue.value.length < 3) {
|
||||
// isUsernameError.value = true;
|
||||
// } else {
|
||||
// isUsernameError.value = false;
|
||||
// }
|
||||
};
|
||||
// 表单密码变量
|
||||
const PasswordValue = ref('');
|
||||
const isPasswordFocused = ref(false);
|
||||
const isPasswordError = ref(false);
|
||||
const passwordFocused = () => {
|
||||
isPasswordFocused.value = true;
|
||||
formDataHasNull.value = false;
|
||||
}
|
||||
const handlePasswordBlur = () => {
|
||||
isPasswordFocused.value = false;
|
||||
}
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
username: computed(() => UsernameValue.value),
|
||||
password: computed(() => PasswordValue.value),
|
||||
remember: true
|
||||
})
|
||||
// 登录状态
|
||||
const loading = ref(false)
|
||||
|
||||
//用户名密码是否非空
|
||||
const formDataHasNull = ref(false)
|
||||
const handleLogin = async() => {
|
||||
checkFormData();
|
||||
if (formDataHasNull.value) return
|
||||
loading.value = true
|
||||
try {
|
||||
const token = await login(UsernameValue.value, PasswordValue.value)
|
||||
// 登陆成功,保存登录数据到手机
|
||||
saveLoginInfo();
|
||||
uni.reLaunch({
|
||||
url: '/pages/Chat/Chat'
|
||||
})
|
||||
} catch(err) {
|
||||
console.log('登录失败',err);
|
||||
uni.showToast({
|
||||
title:err || '失败',
|
||||
icon:'error'
|
||||
})
|
||||
}finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 检查用户名或密码是否为空
|
||||
const checkFormData = () => {
|
||||
if (!UsernameValue.value || !PasswordValue.value) {
|
||||
formDataHasNull.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存登录信息到手机
|
||||
const saveLoginInfo = () => {
|
||||
if (form.remember) {
|
||||
const loginInfo = {
|
||||
username: form.username,
|
||||
password: form.password,
|
||||
remember: true
|
||||
}
|
||||
uni.setStorageSync('login_info', loginInfo)
|
||||
uni.setStorageSync('chatType', 0)
|
||||
} else {
|
||||
uni.removeStorageSync('login_info')
|
||||
}
|
||||
}
|
||||
|
||||
// 从手机加载登录消息
|
||||
const loadLoginInfo = () => {
|
||||
try {
|
||||
const loginInfo = uni.getStorageSync('login_info')
|
||||
if (loginInfo) {
|
||||
UsernameValue.value = loginInfo.username || '';
|
||||
PasswordValue.value = loginInfo.password || '';
|
||||
form.remember = loginInfo.remember ?? true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('读取登录信息失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadLoginInfo();
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-container {
|
||||
padding: 140rpx 60rpx 100rpx 60rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.conner {
|
||||
position: absolute;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.conner-tl {
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-top: 2px solid #aaaaff;
|
||||
border-left: 2px solid #aaaaff;
|
||||
}
|
||||
|
||||
.conner-tr {
|
||||
top: 0;
|
||||
right: 0;
|
||||
border-top: 2px solid #aaaaff;
|
||||
border-right: 2px solid #aaaaff;
|
||||
}
|
||||
|
||||
.conner-bl {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-bottom: 2px solid #aaaaff;
|
||||
border-left: 2px solid #aaaaff;
|
||||
}
|
||||
|
||||
.conner-br {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border-bottom: 2px solid #aaaaff;
|
||||
border-right: 2px solid #aaaaff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.login-header {
|
||||
/* position: absolute;
|
||||
top: 80rpx; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.login-header-logo {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.login-header-logo text {
|
||||
margin-left: 8rpx;
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
color: #aaaaff;
|
||||
text-shadow: 0 0 10rpx rgba(170, 170, 255, 0.4),
|
||||
0 0 20rpx rgba(170, 170, 255, 0.3);
|
||||
}
|
||||
|
||||
.icon-wrapper {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 50%;
|
||||
background-color: rgb(255, 255, 255);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes glow {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 0 20rpx rgba(170, 170, 255, 0.3);
|
||||
}
|
||||
|
||||
50% {
|
||||
box-shadow: 0 0 20rpx rgba(170, 170, 255, 0.4),
|
||||
0 0 30rpx rgba(170, 170, 255, 0.3),
|
||||
0 0 50rpx rgba(170, 170, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-wrapper .danao-style {
|
||||
font-size: 70rpx;
|
||||
color: #aaaaff;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
margin-top: 20rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
text-shadow: 0 0 10rpx #999;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
margin-top: 50rpx;
|
||||
width: 500rpx;
|
||||
padding: 80rpx 30rpx;
|
||||
background-color: rgba(170, 170, 255, 0.05);
|
||||
border-radius: 20rpx;
|
||||
/* border: 1rpx solid #aaaaff; */
|
||||
box-shadow: 0 0 10rpx rgba(170, 170, 255, 0.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.form-item .form-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 30rpx;
|
||||
border: 1rpx solid #e5e5e5;
|
||||
}
|
||||
|
||||
.form-item .focused {
|
||||
border-color: #aaaaff;
|
||||
box-shadow: 0 0 10rpx rgba(170, 170, 255, 0.5);
|
||||
}
|
||||
|
||||
.form-item .error {
|
||||
border-color: #ff0000;
|
||||
box-shadow: 0 0 10rpx rgba(255, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.error-info {
|
||||
font-size: 24rpx;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.form-option {
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.form-option .checkbox-wrapper {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-option .checkbox-wrapper .checkbox {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
border: 1rpx solid #666;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-option .checkbox-wrapper .checked {
|
||||
background-color: #aaaaff;
|
||||
}
|
||||
|
||||
.form-option .checkbox-wrapper .checkbox text {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
:deep(.login-btn) {
|
||||
margin-top: 30rpx;
|
||||
width: 500rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 80rpx;
|
||||
background: linear-gradient(to right, #aaaaff, #2969ed);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user