<template>
|
<view class="login-container">
|
<view class="login-header">
|
<text class="login-title">用户登录</text>
|
</view>
|
<view class="login-form">
|
<view class="input-group">
|
<input
|
class="login-input"
|
type="text"
|
placeholder="请输入用户名"
|
v-model="loginForm.username"
|
@blur="validateUsername"
|
/>
|
<view class="error" v-if="errors.username">{{ errors.username }}</view>
|
</view>
|
<view class="input-group password-group">
|
<input
|
class="login-input"
|
placeholder="请输入密码"
|
:password="!showPassword"
|
v-model="loginForm.password"
|
@blur="validatePassword"
|
/>
|
<view class="password-eye" @click="togglePassword">
|
<text class="eye-icon">{{ !showPassword ? '🙈' : '👁' }}</text>
|
</view>
|
<view class="error" v-if="errors.password">{{ errors.password }}</view>
|
</view>
|
<view class="input-group captcha-group" v-if="captchaEnabled">
|
<view class="captcha-row">
|
<input
|
class="login-input code-input"
|
type="text"
|
placeholder="请输入验证码"
|
v-model="loginForm.code"
|
maxlength="6"
|
@blur="validateCode"
|
/>
|
<image
|
class="captcha-img"
|
:src="codeUrl"
|
mode="aspectFit"
|
@click="getCode"
|
/>
|
</view>
|
<view class="error" v-if="errors.code">{{ errors.code }}</view>
|
</view>
|
<button
|
class="login-button"
|
@click="handleLogin"
|
:loading="loading"
|
>
|
{{ loading ? '登录中...' : '登录' }}
|
</button>
|
</view>
|
<view class="login-footer">
|
<text class="footer-text">© 2025 农投系统</text>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from 'vue'
|
import { login, getCodeImg } from '@/api/login/login.js'
|
import { getInfo } from '@/api/user/user.js'
|
|
// 定义响应式数据
|
const loginForm = reactive({
|
username: '',
|
password: '',
|
code: '',
|
uuid: ''
|
})
|
const codeUrl = ref('')
|
const captchaEnabled = ref(false)
|
const showPassword = ref(false)
|
const loading = ref(false)
|
const errors = reactive({ username: '', password: '', code: '' })
|
const currentTab=ref("corporation")
|
// 切换密码可见性
|
const togglePassword = () => {
|
showPassword.value = !showPassword.value
|
}
|
// 法人登录
|
const currentClick = (tab) =>{
|
currentTab.value = tab;
|
loginForm.role = "2";
|
console.log(loginForm);
|
}
|
// 监管部门登录
|
const superviseClick = (tab) =>{
|
currentTab.value = tab;
|
loginForm.role = "1";
|
console.log(loginForm);
|
}
|
|
const getCode = async () => {
|
try {
|
const res = await getCodeImg()
|
if(res.statusCode ===200){
|
captchaEnabled.value = res.data.captchaEnabled === undefined ? true : res.data.captchaEnabled;
|
if (captchaEnabled.value) {
|
codeUrl.value = 'data:image/gif;base64,' + res.data.img;
|
loginForm.uuid = res.data.uuid || ''
|
}
|
}
|
} catch (error) {
|
uni.showToast({ title: '获取验证码失败,请重试', icon: 'none' })
|
}
|
}
|
// 处理登录
|
const handleLogin = async () => {
|
if (!validateAll()) {
|
uni.showToast({ title: '请完善表单后再登录', icon: 'none' })
|
return
|
}
|
|
loading.value = true
|
|
try {
|
const loginData = {
|
username: (loginForm.username || '').trim(),
|
password: loginForm.password,
|
code: (loginForm.code || '').trim(),
|
uuid: loginForm.uuid
|
}
|
const res = await login(loginData)
|
const data = res && res.data ? res.data : {}
|
console.log("登录信息:{}",data)
|
console.log(data)
|
if (data.code === 200) {
|
uni.showToast({ title: '登录成功', icon: 'success' })
|
//存放token
|
uni.setStorageSync('token', data.token || '')
|
//存放对应用户信息
|
await getInfo().then(res => {
|
console.log("获取用户信息:{}",res)
|
if (res.statusCode === 200) {
|
uni.setStorageSync('userInfo', res.data || {})
|
}
|
})
|
|
uni.reLaunch({ url: '/pages/index/index' })
|
} else {
|
uni.showToast({ title: data.msg || '登录失败', icon: 'none' })
|
getCode();//刷新验证码
|
}
|
} catch (error) {
|
uni.showToast({ title: '登录失败,请重试', icon: 'none' })
|
getCode();//刷新验证码
|
} finally {
|
loading.value = false
|
}
|
|
}
|
onMounted(() => { getCode() })
|
|
function validateUsername() {
|
const u = (loginForm.username || '').trim()
|
if (!u) { errors.username = '请输入用户名'; return false }
|
if (u.length < 2 || u.length > 20) { errors.username = '用户名长度需在2-20之间'; return false }
|
errors.username = ''
|
return true
|
}
|
function validatePassword() {
|
const p = loginForm.password || ''
|
if (!p) { errors.password = '请输入密码'; return false }
|
|
errors.password = ''
|
return true
|
}
|
function validateCode() {
|
if (!captchaEnabled.value) { errors.code = ''; return true }
|
const c = (loginForm.code || '').trim()
|
if (!c) { errors.code = '请输入验证码'; return false }
|
|
errors.code = ''
|
return true
|
}
|
function validateAll() {
|
const a = validateUsername()
|
const b = validatePassword()
|
const c = validateCode()
|
return a && b && c
|
}
|
</script>
|
|
<style scoped>
|
.login-container {
|
padding: 40rpx;
|
background-color: #f5f5f5;
|
min-height: 100vh;
|
}
|
|
.login-header {
|
text-align: center;
|
margin-bottom: 80rpx;
|
padding-top: 100rpx;
|
}
|
|
.login-title {
|
font-size: 48rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.login-form {
|
background-color: #fff;
|
border-radius: 20rpx;
|
padding: 40rpx;
|
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.1);
|
}
|
|
.input-group {
|
margin-bottom: 30rpx;
|
border-bottom: 1rpx solid #eee;
|
}
|
.input-group.invalid { border-bottom-color: #FF5252; }
|
.error { color: #FF5252; font-size: 24rpx; padding-top: 8rpx; }
|
|
.password-group {
|
position: relative;
|
}
|
|
.login-input {
|
height: 80rpx;
|
font-size: 32rpx;
|
padding: 0 20rpx;
|
}
|
|
.password-eye {
|
position: absolute;
|
right: 20rpx;
|
top: 50%;
|
transform: translateY(-50%);
|
cursor: pointer;
|
padding: 10rpx;
|
transition: all 0.3s ease;
|
opacity: 0.8;
|
box-sizing: border-box;
|
z-index: 999;
|
}
|
|
.password-eye:active {
|
opacity: 0.5;
|
transform: translateY(-50%) scale(0.95);
|
}
|
|
.password-eye:hover {
|
opacity: 1;
|
padding: 10rpx;
|
}
|
|
.eye-icon {
|
font-size: 36rpx;
|
color: #666;
|
font-weight: bold;
|
text-shadow: 0 0 2px rgba(0,0,0,0.1);
|
}
|
|
.captcha-group { padding-top: 10rpx; }
|
.captcha-row { display: flex; align-items: center; justify-content: space-between; }
|
.code-input { flex: 1; }
|
.captcha-img { width: 180rpx; height: 70rpx; margin-left: 20rpx; border-radius: 8rpx; overflow: hidden; }
|
|
.login-button {
|
background-color: #007AFF;
|
color: white;
|
border-radius: 10rpx;
|
height: 80rpx;
|
line-height: 80rpx;
|
font-size: 32rpx;
|
margin-top: 50rpx;
|
}
|
|
.login-button:active {
|
background-color: #0062cc;
|
}
|
|
.login-footer {
|
text-align: center;
|
margin-top: 80rpx;
|
}
|
|
.footer-text {
|
color: #999;
|
font-size: 24rpx;
|
}
|
</style>
|