Files
novalon-manage-system/novalon-manage-web/src/views/system/Login.vue
T
张翔 f0746d06db feat(web): 迁移前端源代码(任务 T4.1)
- 删除 novalon 前端 src/ 下所有文件
- 从 gym-manage 复制前端 src/ 完整目录树
- 替换 gym-manage-api → novalon-manage-api
- 替换 gym_system → manage_system
- 无 gym 残留引用
2026-04-27 14:57:45 +08:00

144 lines
3.6 KiB
Vue

<template>
<div class="login-container">
<el-card class="login-card">
<template #header>
<h2>登录 - Novalon 管理系统</h2>
</template>
<el-form
:model="formState"
label-position="top"
@submit.prevent="onFinish"
>
<el-form-item
label="用户名"
prop="username"
:rules="[{ required: true, message: '请输入用户名', trigger: 'blur' }]"
>
<el-input
v-model="formState.username"
placeholder="请输入用户名"
/>
</el-form-item>
<el-form-item
label="密码"
prop="password"
:rules="[{ required: true, message: '请输入密码', trigger: 'blur' }]"
>
<el-input
v-model="formState.password"
type="password"
placeholder="请输入密码"
show-password
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
native-type="submit"
:loading="loading"
style="width: 100%"
>
登录
</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'
import { onMounted } from 'vue'
import { jwtDecode } from 'jwt-decode'
import { usePermissionStore } from '@/stores/permission'
const router = useRouter()
const loading = ref(false)
const permissionStore = usePermissionStore()
const formState = reactive({
username: '',
password: ''
})
onMounted(() => {
document.title = '登录 - Novalon 管理系统'
})
interface JwtPayload {
userId: number
username: string
roles: string[]
exp: number
iat: number
}
const onFinish = async () => {
loading.value = true
try {
console.log('开始登录请求...')
const res: any = await request.post('/auth/login', formState)
console.log('登录响应:', res)
if (!res || !res.token) {
console.error('登录失败:未收到有效响应')
ElMessage.error('登录失败:未收到有效响应')
return
}
localStorage.setItem('token', res.token)
if (res.userId) {
localStorage.setItem('userId', String(res.userId))
}
if (res.username) {
localStorage.setItem('username', res.username)
}
try {
const decoded = jwtDecode<JwtPayload>(res.token)
if (decoded.roles && Array.isArray(decoded.roles)) {
localStorage.setItem('roles', JSON.stringify(decoded.roles))
}
} catch (decodeError) {
console.warn('解析Token中的角色信息失败:', decodeError)
}
console.log('开始获取用户菜单...')
try {
await permissionStore.fetchUserMenus()
console.log('获取用户菜单成功')
} catch (menuError) {
console.error('获取用户菜单失败:', menuError)
}
ElMessage.success('登录成功')
console.log('准备跳转到首页...')
await router.push('/')
console.log('跳转完成')
} catch (error: any) {
console.error('登录错误:', error)
ElMessage.error(error.response?.data?.message || error.message || '登录失败')
} finally {
loading.value = false
}
}
</script>
<style scoped lang="css">
.login-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: var(--el-color-primary-light-9);
.login-card {
width: 400px;
}
}
</style>