11th_fix logo

This commit is contained in:
beabigegg
2025-09-04 08:20:32 +08:00
parent aba50891ef
commit d638d682b7
8 changed files with 105 additions and 58 deletions

2
.env
View File

@@ -32,7 +32,7 @@ SMTP_PORT=25
SMTP_USE_TLS=false
SMTP_USE_SSL=false
SMTP_AUTH_REQUIRED=false
SMTP_SENDER_EMAIL=todo-system@panjit.com.tw
SMTP_SENDER_EMAIL=document_translator@panjit.com.tw
SMTP_SENDER_PASSWORD=
# 檔案儲存

View File

@@ -56,15 +56,15 @@ body {
background: var(--el-border-color);
}
// Element Plus 主題色彩自定義
// Element Plus 主題色彩自定義 - 深色系
:root {
--el-color-primary: #409eff;
--el-color-primary-light-3: #79bbff;
--el-color-primary-light-5: #a0cfff;
--el-color-primary-light-7: #c6e2ff;
--el-color-primary-light-8: #d9ecff;
--el-color-primary-light-9: #ecf5ff;
--el-color-primary-dark-2: #337ecc;
--el-color-primary: #2c3e50;
--el-color-primary-light-3: #5d6d7e;
--el-color-primary-light-5: #85929e;
--el-color-primary-light-7: #aeb6bf;
--el-color-primary-light-8: #d5d8dc;
--el-color-primary-light-9: #eaeded;
--el-color-primary-dark-2: #1a252f;
}
// 過渡動畫

View File

@@ -69,18 +69,29 @@ export const useAuthStore = defineStore('auth', {
/**
* 使用者登出
* @param {boolean} showMessage - 是否顯示登出訊息(預設為 true
* @param {boolean} isAutoLogout - 是否為自動登出(預設為 false
*/
async logout() {
async logout(showMessage = true, isAutoLogout = false) {
try {
console.log('🚪 [Auth] 開始登出流程')
await authAPI.logout()
console.log('🚪 [Auth] 登出 API 完成')
console.log('🚪 [Auth] 開始登出流程', { showMessage, isAutoLogout })
// 只有手動登出時才呼叫 API
if (!isAutoLogout) {
await authAPI.logout()
console.log('🚪 [Auth] 登出 API 完成')
}
} catch (error) {
console.error('❌ [Auth] 登出錯誤:', error)
// 登出 API 失敗不影響本地清除動作,且不顯示錯誤
console.error('❌ [Auth] 登出 API 錯誤(已忽略):', error)
} finally {
console.log('🚪 [Auth] 清除認證資料')
this.clearAuth()
ElMessage.success('已安全登出')
// 只在需要時顯示訊息
if (showMessage && !isAutoLogout) {
ElMessage.success('已安全登出')
}
}
},

View File

@@ -335,7 +335,7 @@
// 登入頁面布局
.login-layout {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
@include flex-center;
padding: $spacing-lg;
@@ -348,20 +348,23 @@
overflow: hidden;
.login-header {
background: linear-gradient(45deg, $primary-color, lighten($primary-color, 10%));
background: linear-gradient(45deg, #1a1a2e, #16213e);
padding: $spacing-xxl;
text-align: center;
color: white;
.login-logo {
width: 64px;
height: 64px;
width: 200px;
height: 80px;
margin: 0 auto $spacing-lg;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
@include flex-center;
font-size: $font-size-extra-large;
font-weight: bold;
img {
width: 100%;
height: 100%;
object-fit: contain;
// 移除濾鏡,讓白色 LOGO 在深色背景上自然顯示
}
}
.login-title {

View File

@@ -1,11 +1,11 @@
// SCSS 變數定義
// 顏色系統
$primary-color: #409eff;
$success-color: #67c23a;
$warning-color: #e6a23c;
$danger-color: #f56c6c;
$info-color: #909399;
// 顏色系統 - 調整為深色系
$primary-color: #2c3e50;
$success-color: #27ae60;
$warning-color: #f39c12;
$danger-color: #e74c3c;
$info-color: #34495e;
// 文字顏色
$text-color-primary: #303133;
@@ -81,17 +81,17 @@ $ease-in-out-back: cubic-bezier(0.71, -0.46, 0.29, 1.46);
// 組件特定顏色
$header-bg: #fff;
$sidebar-bg: #304156;
$sidebar-bg: #1a1a2e;
$sidebar-text-color: #bfcbd9;
$sidebar-active-color: #409eff;
$sidebar-active-color: #3498db;
// 狀態顏色映射
$status-colors: (
'PENDING': #909399,
'PROCESSING': #409eff,
'COMPLETED': #67c23a,
'FAILED': #f56c6c,
'RETRY': #e6a23c
'PENDING': #7f8c8d,
'PROCESSING': #3498db,
'COMPLETED': #27ae60,
'FAILED': #e74c3c,
'RETRY': #f39c12
);
// 檔案類型圖示顏色

View File

@@ -43,6 +43,9 @@ service.interceptors.request.use(
}
)
// 用於防止重複處理 401 錯誤
let isHandling401 = false
// 回應攔截器
service.interceptors.response.use(
response => {
@@ -95,19 +98,32 @@ service.interceptors.response.use(
currentPath,
isLoginPage: currentPath === '/login',
isLoginRequest: requestUrl.includes('/auth/login'),
willTriggerLogout: currentPath !== '/login' && !requestUrl.includes('/auth/login'),
timestamp: new Date().toISOString(),
errorData: data,
requestHeaders: error.config?.headers
isHandling401,
willTriggerLogout: currentPath !== '/login' && !requestUrl.includes('/auth/login') && !isHandling401,
timestamp: new Date().toISOString()
})
if (currentPath !== '/login' && !requestUrl.includes('/auth/login')) {
// 防止重複處理
if (!isHandling401 && currentPath !== '/login' && !requestUrl.includes('/auth/login')) {
isHandling401 = true
console.error('🚪 [Auto Logout] 認證失效,觸發自動登出')
ElMessage.error('認證失效,請重新登入')
authStore.logout()
router.push('/login')
// 只顯示一次訊息
ElMessage.error('認證已過期,請重新登入')
// 使用自動登出模式,不顯示額外訊息
authStore.logout(false, true).finally(() => {
router.push('/login').then(() => {
// 導航完成後重置標記
setTimeout(() => {
isHandling401 = false
}, 1000)
})
})
} else if (isHandling401) {
console.log('🔐 [401 Skipped] 已在處理其他 401 錯誤')
} else {
console.log('🔐 [401 Ignored] 在登入頁面或登入請求,不觸發自動登出')
console.log('🔐 [401 Ignored] 在登入頁面或登入請求')
}
break

View File

@@ -316,22 +316,37 @@ onMounted(async () => {
console.log('🏠 [HomeView] 當前認證狀態', {
isAuthenticated: authStore.isAuthenticated,
user: authStore.user,
token: authStore.token
hasToken: !!authStore.token
})
// 如果沒有認證,不要嘗試載入資料
if (!authStore.isAuthenticated || !authStore.token) {
console.warn('🏠 [HomeView] 未認證,跳過資料載入')
loading.value = false
return
}
try {
// 延遲載入任務列表,避免登入後立即請求造成認證問題
console.log('🏠 [HomeView] 等待 500ms 後載入任務列表')
await new Promise(resolve => setTimeout(resolve, 500))
// 再次檢查認證狀態(可能在延遲期間已登出)
if (!authStore.isAuthenticated) {
console.log('🏠 [HomeView] 認證狀態已改變,取消載入')
return
}
console.log('🏠 [HomeView] 開始載入任務列表')
// 載入最近的任務
await jobsStore.fetchJobs({ per_page: 10 })
console.log('🏠 [HomeView] 任務列表載入成功')
} catch (error) {
console.error('❌ [HomeView] 載入任務失敗:', error)
// 如果是認證錯誤,不顯示錯誤訊息,因為 request.js 會處理
if (!error.message?.includes('認證') && !error.response?.status === 401) {
// 如果是認證錯誤,不顯示額外的錯誤訊息
if (error.response?.status !== 401 &&
!error.message?.includes('認證') &&
!error.message?.includes('401')) {
ElMessage.error('載入任務失敗,請稍後重試')
}
} finally {

View File

@@ -3,7 +3,7 @@
<div class="login-container">
<div class="login-header">
<div class="login-logo">
<el-icon><Document /></el-icon>
<img src="/panjit-logo.png" alt="PANJIT Logo" />
</div>
<h1 class="login-title">PANJIT 翻譯系統</h1>
<p class="login-subtitle">企業級文件批量翻譯管理系統</p>
@@ -48,12 +48,13 @@
<el-form-item>
<el-button
type="primary"
size="large"
:loading="loading"
:disabled="!loginForm.username || !loginForm.password"
@click="handleLogin"
style="width: 100%"
style="width: 100%; background-color: #3498db; border-color: #3498db; color: white;"
@mouseenter="$event.currentTarget.style.backgroundColor='#2980b9'"
@mouseleave="$event.currentTarget.style.backgroundColor='#3498db'"
>
{{ loading ? '登入中...' : '登入' }}
</el-button>
@@ -83,11 +84,6 @@
</el-alert>
</div>
</div>
<div class="login-footer">
<p>&copy; 2024 PANJIT Group. All rights reserved.</p>
<p>Powered by PANJIT IT Team</p>
</div>
</div>
</div>
</template>
@@ -277,9 +273,15 @@ onMounted(() => {
padding: 24px;
.login-logo {
width: 48px;
height: 48px;
width: 120px;
height: 60px;
margin-bottom: 16px;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.login-title {