Refactor processing logic and enhance error handling
- Cleaned up code in processing.py by removing inline semicolons and improving readability. - Updated upsert_file_relation calls to ensure consistent handling of file relations. - Enhanced query_file_relations in db_schema.py to support filtering by file existence. - Improved API error handling in index.ts with user-friendly messages for 401 and 403 errors. - Added online/offline status tracking in Layout.vue. - Implemented debounced search functionality across multiple views to optimize performance. - Introduced loading skeletons in Dashboard.vue for better user experience during data fetching. - Enhanced file preview cleanup logic in Images.vue, Orders.vue, and Tables.vue to prevent memory leaks. - Updated global styles to include new loading and notification animations.
This commit is contained in:
@@ -86,6 +86,11 @@
|
||||
<h2 class="page-title">{{ pageTitle }}</h2>
|
||||
</div>
|
||||
<div class="topbar-right">
|
||||
<!-- Online indicator -->
|
||||
<div v-if="!isOnline" class="offline-badge">
|
||||
<span class="offline-dot"></span>
|
||||
离线
|
||||
</div>
|
||||
<el-dropdown @command="handleCommand" trigger="click">
|
||||
<div class="user-chip">
|
||||
<div class="user-avatar">{{ (authStore.username || 'U')[0].toUpperCase() }}</div>
|
||||
@@ -135,7 +140,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from 'vue'
|
||||
import { ref, computed, reactive, onMounted, onUnmounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {
|
||||
@@ -152,6 +157,20 @@ const authStore = useAuthStore()
|
||||
const isCollapse = ref(false)
|
||||
const showPwd = ref(false)
|
||||
const pwdForm = reactive({ old_password: '', new_password: '' })
|
||||
const isOnline = ref(navigator.onLine !== false)
|
||||
|
||||
// Track online/offline status
|
||||
function updateOnlineStatus() {
|
||||
isOnline.value = navigator.onLine !== false
|
||||
}
|
||||
onMounted(() => {
|
||||
window.addEventListener('online', updateOnlineStatus)
|
||||
window.addEventListener('offline', updateOnlineStatus)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('online', updateOnlineStatus)
|
||||
window.removeEventListener('offline', updateOnlineStatus)
|
||||
})
|
||||
|
||||
const navItems: { path: string; label: string; icon: any; badge?: string }[] = [
|
||||
{ path: '/', label: '处理中心', icon: HomeFilled },
|
||||
@@ -415,6 +434,27 @@ async function changePassword() {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ── Offline badge ── */
|
||||
.offline-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 12px;
|
||||
border-radius: var(--radius-sm);
|
||||
background: rgba(239,68,68,0.1);
|
||||
color: #ef4444;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.offline-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #ef4444;
|
||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
/* ── Content ── */
|
||||
.content {
|
||||
flex: 1;
|
||||
|
||||
Reference in New Issue
Block a user