Files
todo-frontend/src/pages/login/index.vue
Agent 7ca2e1d5a4
Some checks failed
continuous-integration/drone/push Build is failing
fix: 登录改为账号密码+微信登录
2026-03-24 00:25:10 +00:00

388 lines
8.0 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="login-container">
<!-- 背景装饰 -->
<view class="bg-decoration">
<view class="circle circle-1"></view>
<view class="circle circle-2"></view>
<view class="circle circle-3"></view>
</view>
<!-- Logo区域 -->
<view class="logo-section">
<view class="logo-wrapper">
<text class="logo-icon">🏠</text>
</view>
<text class="app-title">建材销售管家</text>
<text class="app-subtitle">高效 · 便捷 · 专业</text>
</view>
<!-- 登录表单 -->
<view class="form-section">
<view class="input-group">
<view class="input-wrapper">
<text class="input-icon">👤</text>
<input
class="input"
v-model="username"
placeholder="请输入用户名"
placeholder-class="placeholder"
/>
</view>
</view>
<view class="input-group">
<view class="input-wrapper">
<text class="input-icon">🔒</text>
<input
class="input"
:password="!showPassword"
v-model="password"
placeholder="请输入密码"
placeholder-class="placeholder"
/>
<text class="eye-icon" @click="showPassword = !showPassword">
{{ showPassword ? '👁' : '👁🗨' }}
</text>
</view>
</view>
<view class="login-btn-wrapper">
<button class="login-btn" @click="passwordLogin">
<text>账号密码登录</text>
</button>
</view>
<!-- 微信登录 -->
<view class="wechat-login" @click="wechatLogin">
<text class="wechat-icon">💬</text>
<text class="wechat-text">微信登录</text>
</view>
<view class="agreement">
<text class="agreement-text">登录即表示同意</text>
<text class="link">用户协议</text>
<text class="agreement-text"></text>
<text class="link">隐私政策</text>
</view>
</view>
<!-- 底部 -->
<view class="footer">
<text class="footer-text">© 2026 建材销售管家</text>
</view>
</view>
</template>
<script>
import authApi from '@/api/auth'
export default {
data() {
return {
username: '',
password: '',
showPassword: false
}
},
methods: {
async passwordLogin() {
if (!this.username) {
uni.showToast({ title: '请输入用户名', icon: 'none' })
return
}
if (!this.password) {
uni.showToast({ title: '请输入密码', icon: 'none' })
return
}
try {
const data = await authApi.passwordLogin(this.username, this.password)
uni.setStorageSync('token', data.token)
uni.setStorageSync('refreshToken', data.refreshToken)
uni.setStorageSync('userId', data.userId)
uni.showToast({ title: '登录成功', icon: 'success' })
setTimeout(() => {
uni.reLaunch({ url: '/pages/index/index' })
}, 1000)
} catch (e) {
console.error(e)
}
},
async wechatLogin() {
// #ifdef MP-WEIXIN
uni.getProvider({
service: 'oauth',
success: (res) => {
if (res.provider.includes('weixin')) {
uni.login({
provider: 'weixin',
success: async (loginRes) => {
try {
const data = await authApi.wechatLogin(loginRes.code)
uni.setStorageSync('token', data.token)
uni.setStorageSync('refreshToken', data.refreshToken)
uni.setStorageSync('userId', data.userId)
uni.showToast({ title: '登录成功', icon: 'success' })
setTimeout(() => {
uni.reLaunch({ url: '/pages/index/index' })
}, 1000)
} catch (e) {
console.error(e)
}
}
})
}
}
})
// #endif
// #ifndef MP-WEIXIN
uni.showToast({ title: '请在微信小程序中使用', icon: 'none' })
// #endif
}
}
}
</script>
<style>
.login-container {
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
position: relative;
overflow: hidden;
}
/* 背景装饰 */
.bg-decoration {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.circle {
position: absolute;
border-radius: 50%;
opacity: 0.1;
}
.circle-1 {
width: 600rpx;
height: 600rpx;
background: #e94560;
top: -200rpx;
right: -200rpx;
animation: float 8s ease-in-out infinite;
}
.circle-2 {
width: 400rpx;
height: 400rpx;
background: #0f3460;
bottom: -100rpx;
left: -100rpx;
animation: float 10s ease-in-out infinite reverse;
}
.circle-3 {
width: 200rpx;
height: 200rpx;
background: #e94560;
top: 30%;
left: 10%;
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(0deg); }
50% { transform: translateY(-30px) rotate(10deg); }
}
/* Logo区域 */
.logo-section {
position: relative;
z-index: 1;
padding-top: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.logo-wrapper {
width: 180rpx;
height: 180rpx;
background: linear-gradient(135deg, #e94560 0%, #ff6b6b 100%);
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 20rpx 60rpx rgba(233, 69, 96, 0.4);
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.logo-icon {
font-size: 80rpx;
}
.app-title {
font-size: 44rpx;
font-weight: bold;
color: #fff;
margin-top: 40rpx;
letter-spacing: 4rpx;
}
.app-subtitle {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.6);
margin-top: 16rpx;
letter-spacing: 8rpx;
}
/* 表单区域 */
.form-section {
position: relative;
z-index: 1;
padding: 80rpx 60rpx;
}
.input-group {
margin-bottom: 30rpx;
}
.input-wrapper {
display: flex;
align-items: center;
background: rgba(255, 255, 255, 0.1);
border-radius: 16rpx;
padding: 0 30rpx;
height: 100rpx;
border: 1rpx solid rgba(255, 255, 255, 0.1);
transition: all 0.3s;
}
.input-wrapper:focus-within {
border-color: #e94560;
background: rgba(255, 255, 255, 0.15);
}
.input-icon {
font-size: 36rpx;
margin-right: 20rpx;
}
.input {
flex: 1;
font-size: 28rpx;
color: #fff;
height: 100%;
}
.placeholder {
color: rgba(255, 255, 255, 0.4);
}
.eye-icon {
font-size: 36rpx;
padding: 10rpx;
}
.login-btn-wrapper {
margin-top: 50rpx;
}
.login-btn {
width: 100%;
height: 100rpx;
line-height: 100rpx;
background: linear-gradient(135deg, #e94560 0%, #ff6b6b 100%);
color: #fff;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
box-shadow: 0 10rpx 40rpx rgba(233, 69, 96, 0.4);
position: relative;
overflow: hidden;
}
.login-btn::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
animation: shine 3s infinite;
}
@keyframes shine {
0% { left: -100%; }
50%, 100% { left: 100%; }
}
/* 微信登录 */
.wechat-login {
display: flex;
align-items: center;
justify-content: center;
margin-top: 40rpx;
padding: 20rpx;
background: rgba(255, 255, 255, 0.1);
border-radius: 16rpx;
}
.wechat-icon {
font-size: 40rpx;
margin-right: 16rpx;
}
.wechat-text {
font-size: 28rpx;
color: #fff;
}
/* 协议 */
.agreement {
display: flex;
justify-content: center;
margin-top: 40rpx;
flex-wrap: wrap;
}
.agreement-text {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.5);
}
.link {
font-size: 22rpx;
color: #e94560;
margin: 0 4rpx;
}
/* 底部 */
.footer {
position: absolute;
bottom: 60rpx;
left: 0;
right: 0;
text-align: center;
}
.footer-text {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.3);
}
</style>