feat: 引入 ECharts 统一图表并完善员工画像标签分页
后端优化员工行为画像服务和辅助函数,完善系统设置模型和 配置持久化,前端引入 ECharts 替换所有图表组件实现统一 渲染,新增员工画像标签分页器和数字员工工作记录组件,优 化工作台响应式布局和登录页过渡动画,完善预算中心和数字 员工页面样式细节。
This commit is contained in:
@@ -1,6 +1,27 @@
|
||||
<template>
|
||||
<div class="app" :class="{ 'sidebar-collapsed': sidebarCollapsed, 'mobile-sidebar-open': mobileSidebarOpen }">
|
||||
<div
|
||||
class="app"
|
||||
:class="{
|
||||
'sidebar-collapsed': sidebarCollapsed,
|
||||
'mobile-sidebar-open': mobileSidebarOpen,
|
||||
'login-entry-active': loginEntryAnimating
|
||||
}"
|
||||
>
|
||||
<div class="mobile-overlay" aria-hidden="true" @click="mobileSidebarOpen = false"></div>
|
||||
<Transition name="login-entry-veil">
|
||||
<div v-if="loginEntryAnimating" class="login-entry-veil" aria-live="polite" aria-label="登录成功,正在进入工作台">
|
||||
<div class="login-entry-card">
|
||||
<span class="login-entry-mark" aria-hidden="true">
|
||||
<i class="mdi mdi-shield-check-outline"></i>
|
||||
</span>
|
||||
<div class="login-entry-copy">
|
||||
<strong>登录成功</strong>
|
||||
<span>正在进入工作台</span>
|
||||
</div>
|
||||
<span class="login-entry-progress" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
<div class="app-sidebar">
|
||||
<SidebarRail
|
||||
:nav-items="filteredNavItems"
|
||||
@@ -148,7 +169,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
|
||||
import SidebarRail from '../components/layout/SidebarRail.vue'
|
||||
import TopBar from '../components/layout/TopBar.vue'
|
||||
@@ -170,14 +191,35 @@ import SettingsView from './SettingsView.vue'
|
||||
import { useAppShell } from '../composables/useAppShell.js'
|
||||
import { useSystemState } from '../composables/useSystemState.js'
|
||||
import { filterNavItemsByAccess } from '../utils/accessControl.js'
|
||||
import { consumeLoginEntryTransition } from '../utils/loginEntryTransition.js'
|
||||
|
||||
const employeeSummary = ref(null)
|
||||
const knowledgeSummary = ref(null)
|
||||
const logsSummary = ref(null)
|
||||
const documentSummary = ref(null)
|
||||
const auditDetailOpen = ref(false)
|
||||
const loginEntryAnimating = ref(false)
|
||||
const sidebarCollapsed = ref(false)
|
||||
const mobileSidebarOpen = ref(false)
|
||||
let loginEntryTimer = null
|
||||
|
||||
function stopLoginEntryAnimation() {
|
||||
if (loginEntryTimer) {
|
||||
window.clearTimeout(loginEntryTimer)
|
||||
loginEntryTimer = null
|
||||
}
|
||||
|
||||
loginEntryAnimating.value = false
|
||||
}
|
||||
|
||||
function playLoginEntryAnimation() {
|
||||
if (!consumeLoginEntryTransition()) {
|
||||
return
|
||||
}
|
||||
|
||||
loginEntryAnimating.value = true
|
||||
loginEntryTimer = window.setTimeout(stopLoginEntryAnimation, 920)
|
||||
}
|
||||
|
||||
function toggleSidebarCollapsed() {
|
||||
sidebarCollapsed.value = !sidebarCollapsed.value
|
||||
@@ -236,4 +278,12 @@ const filteredNavItems = computed(() => filterNavItemsByAccess(navItems, current
|
||||
function handleLogout() {
|
||||
logout('manual')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
playLoginEntryAnimation()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopLoginEntryAnimation()
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user