gaoluyang
2026-06-22 bc365ef47ae4e01754aeadbae26170e11c9bb80e
src/views/reportAnalysis/PSIDataAnalysis/index.vue
@@ -13,7 +13,7 @@
    <!-- 顶部标题栏 -->
    <div class="dashboard-header">
      <div class="factory-name">PSI 数据分析</div>
      <div class="factory-name">进销存数据面板</div>
    </div>
    <!-- 主要内容区域 -->
@@ -43,7 +43,7 @@
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { ref, onMounted, onBeforeUnmount, nextTick, provide } from 'vue'
import autofit from 'autofit.js'
import LeftBottom from './components/left-bottom.vue'
import CenterCenter from './components/center-center.vue'
@@ -65,6 +65,12 @@
// 用户store
const userStore = useUserStore()
/** 与 dataDashboard 共用注入名,子组件(含复用的 right-top/right-bottom)每分钟刷新 */
const DASHBOARD_REFRESH_MS = 60 * 1000
const dataDashboardRefreshTick = ref(0)
provide('dataDashboardRefreshTick', dataDashboardRefreshTick)
let dashboardPollTimer = null
// 计算缩放比例
const calculateScale = () => {
@@ -140,9 +146,17 @@
  window.addEventListener('fullscreenchange', handleFullscreenChange)
  window.addEventListener('webkitfullscreenchange', handleFullscreenChange)
  window.addEventListener('MSFullscreenChange', handleFullscreenChange)
  dashboardPollTimer = setInterval(() => {
    dataDashboardRefreshTick.value++
  }, DASHBOARD_REFRESH_MS)
})
onBeforeUnmount(() => {
  if (dashboardPollTimer) {
    clearInterval(dashboardPollTimer)
    dashboardPollTimer = null
  }
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('fullscreenchange', handleFullscreenChange)
  window.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
@@ -169,6 +183,25 @@
justify-content: center;
background-color: #000;
overflow: hidden;
position: relative;
}
/* 动态网格背景 */
.scale-container::before {
content: '';
position: absolute;
inset: 0;
background-image:
  linear-gradient(rgba(0, 212, 255, 0.03) 1px, transparent 1px),
  linear-gradient(90deg, rgba(0, 212, 255, 0.03) 1px, transparent 1px);
background-size: 50px 50px;
animation: gridMove 20s linear infinite;
z-index: 0;
}
@keyframes gridMove {
0% { transform: translate(0, 0); }
100% { transform: translate(50px, 50px); }
}
/* 内部内容区域 - 固定设计尺寸 */
@@ -232,6 +265,12 @@
color: #FFFFFF;
top: 16px;
position: absolute;
animation: titleGlow 3s ease-in-out infinite;
}
@keyframes titleGlow {
0%, 100% { text-shadow: 0 0 20px rgba(0, 212, 255, 0.3); }
50% { text-shadow: 0 0 40px rgba(0, 212, 255, 0.6), 0 0 60px rgba(0, 212, 255, 0.3); }
}
.fullscreen-btn {
@@ -272,6 +311,33 @@
overflow: hidden;
}
.left-panel {
animation: slideInLeft 0.8s ease-out;
}
.right-panel {
animation: slideInRight 0.8s ease-out;
}
.center-panel {
animation: slideInUp 0.8s ease-out;
}
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(-50px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInRight {
from { opacity: 0; transform: translateX(50px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.left-panel,
.right-panel {
flex: 1;