97 lines
3.7 KiB
Vue
97 lines
3.7 KiB
Vue
<script setup lang="ts">
|
||
import { nextTick, reactive, ref } from 'vue'
|
||
import { useRoute, useRouter } from 'vue-router'
|
||
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
||
import { ArrowRight, LockKeyhole, UserRound } from '@lucide/vue'
|
||
import { useAuthStore } from '@/modules/auth/store/auth'
|
||
import AuthShell from '@/modules/auth/components/AuthShell.vue'
|
||
|
||
interface LoginForm {
|
||
account: string
|
||
password: string
|
||
remember: boolean
|
||
}
|
||
|
||
const route = useRoute()
|
||
const router = useRouter()
|
||
const auth = useAuthStore()
|
||
const formRef = ref<FormInstance>()
|
||
const loading = ref(false)
|
||
const form = reactive<LoginForm>({
|
||
account: typeof route.query.account === 'string'
|
||
? route.query.account
|
||
: '',
|
||
password: '',
|
||
remember: false,
|
||
})
|
||
const accountPattern = /^[A-Za-z0-9_]{4,64}$/
|
||
|
||
const rules: FormRules<LoginForm> = {
|
||
account: [
|
||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||
{ pattern: accountPattern, message: '用户名为 4–64 位字母、数字或下划线', trigger: 'blur' },
|
||
],
|
||
password: [
|
||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||
{ min: 8, max: 72, message: '密码长度应为 8–72 位', trigger: 'blur' },
|
||
],
|
||
}
|
||
|
||
async function submit() {
|
||
if (!formRef.value || loading.value) return
|
||
const valid = await formRef.value.validate().catch(() => false)
|
||
if (!valid) {
|
||
await nextTick()
|
||
document.querySelector<HTMLElement>('.auth-form-panel .el-form-item.is-error input')?.focus()
|
||
return
|
||
}
|
||
|
||
loading.value = true
|
||
try {
|
||
await auth.login(form.account.trim(), form.password, form.remember)
|
||
ElMessage.success('登录成功')
|
||
await router.replace(String(route.query.redirect || '/'))
|
||
} catch (error) {
|
||
ElMessage.error(error instanceof Error ? error.message : '登录失败,请检查账号后重试')
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
function showResetHint() {
|
||
ElMessage.info('请联系平台客服重置密码')
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<AuthShell
|
||
switch-text="还没有企业账号?"
|
||
switch-label="申请入驻"
|
||
switch-to="/register"
|
||
visual-title="跨境物流业务,一个工作台完成"
|
||
visual-description="从企业协作到头程订单跟进,让业务信息与操作权限始终清晰。"
|
||
:features="['企业级角色与权限', '头程订单全程跟进', '多成员业务协同']"
|
||
>
|
||
<div class="auth-form-content auth-form-content--login">
|
||
<div class="auth-form-heading">
|
||
<h2 id="login-title">登录客户工作台</h2>
|
||
<p>使用企业账号登录,继续管理您的跨境物流业务。</p>
|
||
</div>
|
||
<div class="auth-account-note">企业注册成功后即可登录;提交订单前需完成企业资料审核。</div>
|
||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top" size="large" @submit.prevent="submit">
|
||
<el-form-item label="用户名" prop="account">
|
||
<el-input v-model="form.account" autocomplete="username" maxlength="64" placeholder="请输入用户名" :prefix-icon="UserRound" />
|
||
</el-form-item>
|
||
<el-form-item label="密码" prop="password">
|
||
<el-input v-model="form.password" autocomplete="current-password" maxlength="72" type="password" show-password placeholder="请输入 8–72 位密码" :prefix-icon="LockKeyhole" @keyup.enter="submit" />
|
||
</el-form-item>
|
||
<div class="auth-form-options">
|
||
<el-checkbox v-model="form.remember">记住我</el-checkbox>
|
||
<button type="button" @click="showResetHint">忘记密码?</button>
|
||
</div>
|
||
<el-button native-type="submit" class="auth-submit" type="primary" :loading="loading">登录 <ArrowRight :size="17" /></el-button>
|
||
</el-form>
|
||
</div>
|
||
</AuthShell>
|
||
</template>
|