Files
saleShopUni/src/pages/login/login.vue
2026-07-15 16:21:47 +08:00

336 lines
7.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="login-page">
<view class="login-container">
<view class="login-header">
<!-- <image :src="Service.GetIconImg('/static/logo/logo.png')" class="logo"></image> -->
<view class="app-title">欢迎登录</view>
</view>
<view class="login-tabs">
<view class="tab-item" :class="{ active: currentTab === 0 }" @click="switchTab(0)">
账户密码登录
</view>
<view class="tab-item" :class="{ active: currentTab === 1 }" @click="switchTab(1)">
手机号登录
</view>
</view>
<view class="login-form">
<view v-if="currentTab === 0" class="form-section">
<view class="input-item">
<u-icon name="account" size="20" color="#999"></u-icon>
<input v-model="passwordForm.username" class="input-field" type="text" placeholder="请输入手机号" />
</view>
<view class="input-item">
<u-icon name="lock" size="20" color="#999"></u-icon>
<input v-model="passwordForm.password" class="input-field"
:type="!showPassword?'password':'text'" placeholder="请输入密码" />
<u-icon :name="!showPassword ? 'eye-off' : 'eye'" size="20" color="#999"
@click="togglePassword"></u-icon>
</view>
</view>
<view v-if="currentTab === 1" class="form-section">
<view class="input-item">
<u-icon name="phone" size="20" color="#999"></u-icon>
<input v-model="phoneForm.phone" class="input-field" type="number" maxlength="11"
placeholder="请输入手机号" />
</view>
<view class="input-item">
<u-icon name="error-circle" size="20" color="#999"></u-icon>
<input v-model="phoneForm.code" class="input-field code-input" type="number" maxlength="6"
placeholder="请输入验证码" />
<button class="code-btn" :disabled="counting" @click="getCode">
{{ counting ? `${countdown}s` : '获取验证码' }}
</button>
</view>
</view>
<button class="login-btn" @click="handleLogin">
</button>
<view class="login-footer">
<text class="footer-text" @click="goToRegister">注册账户</text>
<text class="footer-text" @click="goToForgotPassword">忘记密码</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Service } from '@/Service/Service';
import { LoginService } from "@/Service/api/LoginService"
import { onLoad } from '@dcloudio/uni-app';
const currentTab = ref(0);
const showPassword = ref(false);
const counting = ref(false);
const countdown = ref(60);
const passwordForm = ref({
username: '',
password: ''
});
const phoneForm = ref({
phone: '',
code: ''
});
onLoad((data:any) => {
console.log('onload',data);
})
const switchTab = (index : number) => {
currentTab.value = index;
};
const togglePassword = () => {
showPassword.value = !showPassword.value;
};
const getCode = () => {
if (!phoneForm.value.phone) {
Service.Msg('请输入手机号!');
return;
}
const phoneReg = /^1[3-9]\d{9}$/;
if (!phoneReg.test(phoneForm.value.phone)) {
Service.Msg('请输入正确的手机号!');
return;
}
counting.value = true;
LoginService.SendSms(phoneForm.value.phone, 'Login').then(res => {
if (res.code == 0) {
Service.Msg('验证码已发送!');
} else {
Service.Msg(res.msg)
}
})
const timer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
counting.value = false;
countdown.value = 60;
}
}, 1000);
};
const handleLogin = () => {
if (currentTab.value === 0) {
if (!passwordForm.value.username) {
Service.Msg('请输入手机号!');
return;
}
if (!passwordForm.value.password) {
Service.Msg('请输入密码!');
return;
}
Service.LoadIng('登录中...');
LoginService.Login(passwordForm.value.username, passwordForm.value.password).then(res => {
if (res.code == 0) {
Service.LoadClose();
Service.Msg('登录成功!');
Service.SetUserToken(res.data.token)
Service.GoPageTab('/pages/index/index')
} else {
Service.Msg(res.msg)
}
})
} else {
if (!phoneForm.value.phone) {
Service.Msg('请输入手机号!');
return;
}
if (!phoneForm.value.code) {
Service.Msg('请输入验证码!');
return;
}
Service.LoadIng('登录中...');
LoginService.PhoneLogin(phoneForm.value.phone, phoneForm.value.code).then(res => {
if (res.code == 0) {
Service.LoadClose();
Service.Msg('登录成功!');
// Service.SetUserToken(res.data.token)
let local = 'http://pt.pccsh.cn/#/pages/index/index';
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + 'wxf892fef3811b3ded' + "&redirect_uri=" + local + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
} else {
Service.Msg(res.msg)
}
})
}
};
const goToRegister = () => {
Service.GoPage('/pages/login/register');
};
const goToForgotPassword = () => {
Service.GoPage('/pages/login/forgotPassword');
};
</script>
<style scoped lang="scss">
.login-page {
min-height: 100vh;
background: linear-gradient(135deg, #FFF7ED 0%, #FFEDD5 100%);
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx;
}
.login-container {
width: 100%;
background-color: #FFFFFF;
border-radius: 32rpx;
padding: 60rpx 40rpx;
box-shadow: 0 8rpx 32rpx rgba(249, 115, 22, 0.1);
}
.login-header {
text-align: center;
margin-bottom: 60rpx;
}
.logo {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
margin-bottom: 30rpx;
}
.app-title {
font-size: 48rpx;
font-weight: bold;
color: #1F2937;
}
.login-tabs {
display: flex;
margin-bottom: 50rpx;
border-bottom: 2rpx solid #F3F4F6;
}
.tab-item {
flex: 1;
text-align: center;
padding: 24rpx 0;
font-size: 30rpx;
color: #6B7280;
position: relative;
transition: all 0.3s;
}
.tab-item.active {
color: #F97316;
font-weight: 600;
}
.tab-item.active::after {
content: '';
position: absolute;
bottom: -2rpx;
left: 50%;
transform: translateX(-50%);
width: 80rpx;
height: 4rpx;
background: linear-gradient(90deg, #F97316, #FB923C);
border-radius: 2rpx;
}
.login-form {
.form-section {
margin-bottom: 40rpx;
}
}
.input-item {
display: flex;
align-items: center;
background-color: #F9FAFB;
border-radius: 16rpx;
padding: 24rpx 30rpx;
margin-bottom: 30rpx;
border: 2rpx solid transparent;
transition: all 0.3s;
&:focus-within {
border-color: #F97316;
background-color: #FFF;
}
}
.input-field {
flex: 1;
margin-left: 20rpx;
font-size: 30rpx;
color: #1F2937;
}
.code-input {
flex: 1;
}
.code-btn {
margin-left: 20rpx;
padding: 16rpx 24rpx;
background: linear-gradient(135deg, #F97316, #FB923C);
color: #FFFFFF;
font-size: 26rpx;
border-radius: 12rpx;
border: none;
line-height: 1;
white-space: nowrap;
&:disabled {
background: #D1D5DB;
color: #fff;
}
}
.login-btn {
width: 100%;
padding: 0 30rpx;
background: linear-gradient(135deg, #F97316, #FB923C);
color: #FFFFFF;
font-size: 34rpx;
font-weight: 600;
border: none;
border-radius: 16rpx;
margin-top: 40rpx;
box-shadow: 0 8rpx 24rpx rgba(249, 115, 22, 0.3);
transition: all 0.3s;
&:active {
transform: scale(0.98);
box-shadow: 0 4rpx 12rpx rgba(249, 115, 22, 0.2);
}
}
.login-footer {
display: flex;
justify-content: space-between;
margin-top: 40rpx;
}
.footer-text {
font-size: 26rpx;
color: #6B7280;
}
</style>