ForgeFlow-ERP/frontend/src/views/LoginView.vue
2026-06-14 21:05:49 +08:00

174 lines
6.1 KiB
Vue

<template>
<section class="login-shell login-industrial-stage login-production-layout">
<div class="login-kinetic-field" aria-hidden="true">
<span class="login-depth-grid"></span>
<span class="login-scan-plane login-scan-plane-a"></span>
<span class="login-scan-plane login-scan-plane-b"></span>
<span class="login-data-thread login-data-thread-a"></span>
<span class="login-data-thread login-data-thread-b"></span>
<span class="login-data-thread login-data-thread-c"></span>
<span class="login-heat-column login-heat-column-a"></span>
<span class="login-heat-column login-heat-column-b"></span>
<span class="login-heat-column login-heat-column-c"></span>
</div>
<main class="login-production-cockpit" @click.stop>
<section class="login-line-area" aria-label="百华五金冲压产线">
<div class="login-line-brand">
<img class="login-logo login-logo-wordmark" src="/logo.png" alt="宁波百华智能科技有限公司 logo" />
<div>
<span>百华智能</span>
</div>
</div>
<div class="login-production-line" aria-hidden="true">
<div class="login-line-floor"></div>
<span class="login-forge-beam login-forge-beam-a"></span>
<span class="login-forge-beam login-forge-beam-b"></span>
<div class="login-coil">
<span></span>
<span></span>
<span></span>
</div>
<div class="login-feeder-line">
<span class="login-metal-strip login-metal-strip-a"></span>
<span class="login-metal-strip login-metal-strip-b"></span>
<span class="login-metal-strip login-metal-strip-c"></span>
</div>
<div class="login-line-machine">
<div class="login-press-machine">
<span class="login-press-aura"></span>
<span class="login-press-arm"></span>
<span class="login-press-hammer"></span>
<span class="login-press-die"></span>
<span class="login-spark login-spark-a"></span>
<span class="login-spark login-spark-b"></span>
<span class="login-spark login-spark-c"></span>
</div>
</div>
<div class="login-inspection-gate">
<span></span>
<span></span>
</div>
<div class="login-stamped-stack">
<span></span>
<span></span>
<span></span>
</div>
<div class="login-part-runner">
<span></span>
<span></span>
<span></span>
</div>
<div class="login-console-link"></div>
</div>
<div class="login-line-labels" aria-label="生产流向">
<article class="login-conveyor-label">
<AppIcon name="material" />
<span>卷料入线</span>
</article>
<article class="login-conveyor-label">
<AppIcon name="production" />
<span>冲压成型</span>
</article>
<article class="login-conveyor-label">
<AppIcon name="quality" />
<span>质检扫描</span>
</article>
<article class="login-conveyor-label">
<AppIcon name="warehouseFinished" />
<span>成品入库</span>
</article>
</div>
</section>
<section class="login-console-dock" aria-label="系统登录">
<span class="login-dock-rail login-dock-rail-a" aria-hidden="true"></span>
<span class="login-dock-rail login-dock-rail-b" aria-hidden="true"></span>
<span class="login-dock-floor" aria-hidden="true"></span>
<div class="login-console-frame">
<div class="login-control-console">
<div class="login-panel-head">
<h2>百华智能五金 ERP</h2>
</div>
<form class="login-form" @submit.prevent="handleLogin">
<label class="login-input-shell">
<span>账号</span>
<div class="login-input-frame">
<AppIcon name="employee" />
<input v-model.trim="form.username" type="text" autocomplete="username" placeholder="请输入系统账号" />
</div>
</label>
<label class="login-input-shell">
<span>密码</span>
<div class="login-input-frame">
<AppIcon name="permissions" />
<input v-model="form.password" type="password" autocomplete="current-password" placeholder="请输入登录密码" />
</div>
</label>
<div class="login-actions">
<button class="primary-button login-submit-button" type="submit" :disabled="submitting">
<span>{{ submitting ? "正在校验身份..." : "进入智能工厂" }}</span>
<AppIcon name="arrowRight" />
</button>
<p v-if="message" class="form-message">{{ message }}</p>
<p v-if="errorMessage" class="form-error">{{ errorMessage }}</p>
</div>
</form>
</div>
</div>
</section>
</main>
</section>
</template>
<script setup>
import { reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import AppIcon from "../components/AppIcon.vue";
import { login, saveSession } from "../services/api";
const router = useRouter();
const route = useRoute();
const form = reactive({
username: "",
password: ""
});
const submitting = ref(false);
const message = ref("");
const errorMessage = ref("");
async function handleLogin() {
submitting.value = true;
message.value = "";
errorMessage.value = "";
try {
const user = await login(form.username, form.password);
saveSession(user);
message.value = `欢迎回来,${user.display_name}`;
const redirect = typeof route.query.redirect === "string" ? route.query.redirect : "/";
router.push(redirect);
} catch (error) {
errorMessage.value = error.message || "登录失败";
} finally {
submitting.value = false;
}
}
</script>