Files
Document_translator_V2_nodo…/frontend/src/views/NotFoundView.vue
beabigegg 4cace93934 NO docker
2025-10-02 18:50:53 +08:00

278 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="not-found-view">
<div class="not-found-container">
<div class="not-found-illustration">
<div class="error-code">404</div>
<div class="error-icon">
<el-icon><QuestionFilled /></el-icon>
</div>
</div>
<div class="not-found-content">
<h1 class="error-title">頁面不存在</h1>
<p class="error-description">
抱歉您訪問的頁面不存在或已被移除
</p>
<div class="error-actions">
<el-button type="primary" size="large" @click="goHome">
<el-icon><House /></el-icon>
回到首頁
</el-button>
<el-button size="large" @click="goBack">
<el-icon><ArrowLeft /></el-icon>
返回上頁
</el-button>
</div>
</div>
<div class="helpful-links">
<h3>您可能在尋找</h3>
<div class="links-grid">
<router-link to="/upload" class="link-card">
<div class="link-icon">
<el-icon><Upload /></el-icon>
</div>
<div class="link-content">
<div class="link-title">檔案上傳</div>
<div class="link-desc">上傳新的檔案進行翻譯</div>
</div>
</router-link>
<router-link to="/jobs" class="link-card">
<div class="link-icon">
<el-icon><List /></el-icon>
</div>
<div class="link-content">
<div class="link-title">任務列表</div>
<div class="link-desc">查看您的翻譯任務</div>
</div>
</router-link>
<router-link to="/history" class="link-card">
<div class="link-icon">
<el-icon><Clock /></el-icon>
</div>
<div class="link-content">
<div class="link-title">歷史記錄</div>
<div class="link-desc">瀏覽過往的翻譯記錄</div>
</div>
</router-link>
<router-link to="/profile" class="link-card">
<div class="link-icon">
<el-icon><User /></el-icon>
</div>
<div class="link-content">
<div class="link-title">個人設定</div>
<div class="link-desc">管理您的個人資料</div>
</div>
</router-link>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
import {
QuestionFilled, House, ArrowLeft, Upload, List, Clock, User
} from '@element-plus/icons-vue'
const router = useRouter()
const goHome = () => {
router.push('/')
}
const goBack = () => {
if (window.history.length > 1) {
router.back()
} else {
router.push('/')
}
}
</script>
<style lang="scss" scoped>
.not-found-view {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 20px;
.not-found-container {
max-width: 800px;
width: 100%;
text-align: center;
.not-found-illustration {
position: relative;
margin-bottom: 40px;
.error-code {
font-size: 120px;
font-weight: bold;
color: var(--el-color-primary);
line-height: 1;
margin-bottom: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
@media (max-width: 480px) {
font-size: 80px;
}
}
.error-icon {
font-size: 60px;
color: var(--el-color-info);
opacity: 0.6;
@media (max-width: 480px) {
font-size: 40px;
}
}
}
.not-found-content {
margin-bottom: 50px;
.error-title {
font-size: 32px;
font-weight: bold;
color: var(--el-text-color-primary);
margin: 0 0 16px 0;
@media (max-width: 480px) {
font-size: 24px;
}
}
.error-description {
font-size: 16px;
color: var(--el-text-color-regular);
line-height: 1.6;
margin: 0 0 32px 0;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
.error-actions {
display: flex;
justify-content: center;
gap: 16px;
@media (max-width: 480px) {
flex-direction: column;
align-items: center;
}
}
}
.helpful-links {
background: white;
border-radius: 16px;
padding: 32px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
h3 {
font-size: 18px;
color: var(--el-text-color-primary);
margin: 0 0 24px 0;
}
.links-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
@media (max-width: 480px) {
grid-template-columns: 1fr;
}
.link-card {
display: flex;
align-items: center;
gap: 12px;
padding: 16px;
background: var(--el-fill-color-lighter);
border-radius: 12px;
text-decoration: none;
transition: all 0.3s ease;
&:hover {
background: var(--el-color-primary-light-9);
transform: translateY(-2px);
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.2);
}
.link-icon {
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--el-color-primary);
color: white;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.link-content {
text-align: left;
.link-title {
font-size: 14px;
font-weight: 600;
color: var(--el-text-color-primary);
margin-bottom: 4px;
}
.link-desc {
font-size: 12px;
color: var(--el-text-color-secondary);
line-height: 1.4;
}
}
}
}
}
}
}
// 動畫效果
.not-found-container {
animation: fadeInUp 0.8s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.error-code {
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
</style>