Files
kami/license-system-frontend/src/pages/LoginView.vue
2026-01-04 23:00:21 +08:00

158 lines
3.8 KiB
Vue

<template>
<div class="login-page">
<div class="login-card glass-card">
<div class="login-hero">
<div class="hero-mark">LS</div>
<div>
<h1 class="section-title">{{ '\u6388\u6743\u7cfb\u7edf' }}</h1>
<p class="hero-sub">{{ '\u7ba1\u7406\u5458\u4e0e\u4ee3\u7406\u5b89\u5168\u767b\u5f55' }}</p>
</div>
</div>
<el-form :model="form" class="login-form" @submit.prevent>
<el-segmented v-model="loginType" :options="loginOptions" class="segment" />
<el-form-item :label="'\u8d26\u53f7'" v-if="loginType === 'admin'">
<el-input v-model="form.username" :placeholder="'\u8bf7\u8f93\u5165\u7ba1\u7406\u5458\u8d26\u53f7'" autocomplete="username" />
</el-form-item>
<el-form-item :label="'\u4ee3\u7406\u7f16\u7801'" v-else>
<el-input v-model="form.agentCode" :placeholder="'\u8bf7\u8f93\u5165\u4ee3\u7406\u7f16\u7801'" autocomplete="username" />
</el-form-item>
<el-form-item :label="'\u5bc6\u7801'">
<el-input v-model="form.password" type="password" show-password autocomplete="current-password" />
</el-form-item>
<el-button type="primary" size="large" class="submit" :loading="loading" @click="handleLogin">
{{ '\u767b\u5f55' }}
</el-button>
</el-form>
<div class="login-foot">
<span>{{ '\u9700\u8981\u5e2e\u52a9\uff1f' }}</span>
<a :href="helpUrl" target="_blank" rel="noreferrer">{{ '\u8054\u7cfb\u652f\u6301' }}</a>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { adminLogin } from '@/api/admin';
import { agentLogin } from '@/api/agent';
import { setAdminSession, setAgentSession } from '@/store/session';
const router = useRouter();
const loginType = ref('admin');
const loginOptions = [
{ label: '\u7ba1\u7406\u5458', value: 'admin' },
{ label: '\u4ee3\u7406\u5546', value: 'agent' }
];
const form = reactive({
username: '',
agentCode: '',
password: ''
});
const loading = ref(false);
const helpUrl = 'https://example.com/support';
const handleLogin = async () => {
loading.value = true;
try {
if (loginType.value === 'admin') {
const data = await adminLogin({
username: form.username,
password: form.password,
captcha: ''
});
setAdminSession(data);
router.push('/admin/dashboard');
} else {
const data = await agentLogin({
agentCode: form.agentCode,
password: form.password
});
setAgentSession(data);
router.push('/agent/cards');
}
} catch (err) {
const message = err?.message || err?.data?.message || '\u767b\u5f55\u5931\u8d25';
ElMessage.error(message);
} finally {
loading.value = false;
}
};
</script>
<style scoped>
.login-page {
min-height: 100vh;
display: grid;
place-items: center;
padding: 32px 16px;
}
.login-card {
width: min(460px, 92vw);
padding: 28px;
border-radius: 24px;
animation: fadeUp 0.6s ease;
}
.login-hero {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 20px;
}
.hero-mark {
width: 52px;
height: 52px;
border-radius: 16px;
background: linear-gradient(140deg, var(--accent-500), var(--teal-500));
color: #fff;
display: grid;
place-items: center;
font-weight: 700;
}
.hero-sub {
margin: 4px 0 0;
color: var(--ink-500);
}
.login-form {
display: grid;
gap: 12px;
}
.segment {
margin-bottom: 6px;
}
.submit {
width: 100%;
border-radius: 12px;
font-weight: 600;
}
.login-foot {
margin-top: 16px;
display: flex;
justify-content: space-between;
font-size: 13px;
color: var(--ink-500);
}
.login-foot a {
color: var(--teal-700);
font-weight: 600;
}
</style>