| | |
| | | <Box v-if="index === 0" /> |
| | | <Download v-else-if="index === 1" /> |
| | | <Upload v-else-if="index === 2" /> |
| | | <List v-else /> |
| | | <List v-else-if="index === 3" /> |
| | | <Box v-else-if="index === 4" /> |
| | | <Box v-else /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="metric-content"> |
| | | <div class="metric-value">{{ item.value }}</div> |
| | | <div class="metric-value">{{ formatNumber(item.value) }}</div> |
| | | <div class="metric-label">{{ item.label }}</div> |
| | | <div class="metric-trend" :class="item.trend > 0 ? 'up' : 'down'"> |
| | | <el-icon> |
| | |
| | | <div ref="categoryChartRef" class="chart-container"></div> |
| | | </div> |
| | | |
| | | <!-- ä½ä¸æç --> |
| | | <!-- ç©æä¸´ææ°æ® --> |
| | | <div class="chart-card"> |
| | | <div class="card-title"> |
| | | <span>ä½ä¸æçç»è®¡</span> |
| | | <span>ç©æä¸´ææ°æ®</span> |
| | | <span class="task-count">å
± {{ nearExpirationList.length }} æ¡è®°å½</span> |
| | | </div> |
| | | <div ref="efficiencyChartRef" class="chart-container"></div> |
| | | <el-table |
| | | :data="showNearExpirationList" |
| | | style="width: 100%" |
| | | :height="250" |
| | | :empty-text="nearExpirationList.length === 0 ? 'ææ ä¸´ææ°æ®' : ''" |
| | | > |
| | | <el-table-column prop="materielCode" label="ç©æç¼ç " min-width="120" /> |
| | | <el-table-column prop="batchNo" label="æ¹æ¬¡å·" min-width="100" /> |
| | | <el-table-column prop="palletCode" label="æçç¼å·" min-width="100" /> |
| | | <el-table-column prop="locationCode" label="åºä½" min-width="100" /> |
| | | <el-table-column prop="stockQuantity" label="åºåæ°é" width="100" /> |
| | | <el-table-column prop="daysToExpiration" label="临æå¤©æ°" width="100"> |
| | | <template #default="{ row }"> |
| | | <div :class="getExpirationClass(row.daysToExpiration)"> |
| | | {{ row.daysToExpiration }}天 |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="validDate" label="æææè³" width="160" /> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <div class="table-card"> |
| | | <div class="card-title"> |
| | | <span>宿¶ä½ä¸ä»»å¡</span> |
| | | <span class="task-count">å
± {{ taskList.length }} æ¡ä»»å¡</span> |
| | | </div> |
| | | <el-table :data="showTaskList" style="width: 100%" :height="tableHeight"> |
| | | <el-table-column prop="taskNum" label="ä»»å¡å·" /> |
| | | <el-table-column prop="taskStatus" label="ä»»å¡ç¶æ" width="120"> |
| | | <el-table |
| | | :data="showTaskList" |
| | | style="width: 100%" |
| | | :height="tableHeight" |
| | | :empty-text="taskList.length === 0 ? 'ææ ä½ä¸ä»»å¡æ°æ®' : ''" |
| | | > |
| | | <el-table-column prop="taskNum" label="ä»»å¡å·" min-width="120" /> |
| | | <el-table-column prop="taskStatus" label="ä»»å¡ç¶æ" width="140"> |
| | | <template #default="{ row }"> |
| | | <div class="status-container" :class="getStatusClass(row.taskStatus)"> |
| | | <div class="status-dot"></div> |
| | |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="taskType" label="ä»»å¡ç±»å" width="100"> |
| | | <el-table-column prop="taskType" label="ä»»å¡ç±»å" width="120"> |
| | | <template #default="{ row }"> |
| | | <div class="type-container" :class="getTypeClass(row.taskType)"> |
| | | <el-icon class="type-icon"> |
| | |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="palletCode" label="æçç¼å·" /> |
| | | <el-table-column prop="sourceAddress" label="èµ·ç¹ä½ç½®"/> |
| | | <el-table-column prop="targetAddress" label="ç»ç¹ä½ç½®"/> |
| | | <el-table-column prop="createDate" label="å建æ¶é´"/> |
| | | <el-table-column prop="palletCode" label="æçç¼å·" min-width="100" /> |
| | | <el-table-column prop="sourceAddress" label="èµ·ç¹ä½ç½®" min-width="100"/> |
| | | <el-table-column prop="targetAddress" label="ç»ç¹ä½ç½®" min-width="100"/> |
| | | <el-table-column prop="createDate" label="å建æ¶é´" width="180"/> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { ref, onMounted, onUnmounted, nextTick } from 'vue' |
| | | import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue' |
| | | import * as echarts from 'echarts' |
| | | import { http } from '@/utils/http' |
| | | import { formatDateTime } from '@/utils' |
| | |
| | | 110: "æåæºæ§è¡ä¸" |
| | | } |
| | | |
| | | // å
³é®ææ ï¼ååºå¼ï¼ |
| | | // å
³é®ææ ï¼ååºå¼ï¼- ä¿®æ£æ å°å
³ç³» |
| | | const metrics = ref([ |
| | | { |
| | | label: 'æ»åºåé', |
| | | label: 'å¾
å
¥åºè®¢å', |
| | | value: 0, |
| | | icon: 'Box', |
| | | color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', |
| | | trend: 8.5 |
| | | }, |
| | | { |
| | | label: '仿¥å
¥åº', |
| | | label: 'å¾
åºåºè®¢å', |
| | | value: 0, |
| | | icon: 'Download', |
| | | color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)', |
| | | trend: 12.3 |
| | | }, |
| | | { |
| | | label: '仿¥åºåº', |
| | | label: '仿¥å
¥åºå®ææ°', |
| | | value: 0, |
| | | icon: 'Upload', |
| | | color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)', |
| | | trend: -3.2 |
| | | }, |
| | | { |
| | | label: 'å¾
å¤çä»»å¡', |
| | | label: '仿¥åºåºå®ææ°', |
| | | value: 0, |
| | | icon: 'List', |
| | | color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)', |
| | | trend: 5.7 |
| | | }, |
| | | { |
| | | label: 'æè´§æç®±', |
| | | value: 0, |
| | | icon: 'List', |
| | | color: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)', |
| | | trend: 2.1 |
| | | }, |
| | | { |
| | | label: '空箱æ°é', |
| | | value: 0, |
| | | icon: 'List', |
| | | color: 'linear-gradient(135deg, #8176af 0%, #c0b7e8 100%)', |
| | | trend: -1.8 |
| | | } |
| | | ]) |
| | | |
| | |
| | | const currentTaskIndex = ref(7) // åå§ä»ç¬¬8æ¡å¼å§ï¼å7æ¡é»è®¤æ¾ç¤ºï¼ |
| | | let taskCarouselTimer = null |
| | | |
| | | // 临æç©æå表ç¸å
³ |
| | | const nearExpirationList = ref([]) |
| | | const showNearExpirationList = ref([]) |
| | | const currentExpirationIndex = ref(7) // åå§ä»ç¬¬8æ¡å¼å§ï¼å7æ¡é»è®¤æ¾ç¤ºï¼ |
| | | let expirationCarouselTimer = null |
| | | |
| | | // èªå¨å·æ°ç¸å
³é
ç½® |
| | | const lastInboundToday = ref(0) // ä¸ä¸æ¬¡å½å¤©å
¥åºé |
| | | const lastOutboundToday = ref(0) // ä¸ä¸æ¬¡å½å¤©åºåºé |
| | |
| | | let lastRefreshTime = ref(0) // ä¸ä¸æ¬¡å·æ°æ¶é´ |
| | | let autoRefreshTimer = null // èªå¨å·æ°å®æ¶å¨ |
| | | |
| | | // æ°åæ ¼å¼å |
| | | const formatNumber = (num) => { |
| | | if (num === undefined || num === null || isNaN(num)) return '0'; |
| | | return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); |
| | | } |
| | | |
| | | // è·åä»»å¡ç¶æææ¬ |
| | | const getTaskStatusText = (statusNum) => { |
| | | if (statusNum === undefined || statusNum === null || isNaN(statusNum)) { |
| | | return "æªç¥ç¶æ"; |
| | | } |
| | | return taskStatusMap[statusNum] || "æªç¥ç¶æ"; |
| | | return taskStatusMap[statusNum] || `æªç¥ç¶æ(${statusNum})`; |
| | | } |
| | | |
| | | // å¯å¨ä»»å¡è½®æ |
| | | const startTaskCarousel = () => { |
| | | // æ¸
餿§å®æ¶å¨ |
| | | if (taskCarouselTimer) clearInterval(taskCarouselTimer); |
| | | |
| | | const totalTask = bigscreendata.value.taskList.length; |
| | | if (totalTask <= 7) { // 任塿°<=7æ¶ä¸è½®æ |
| | | showTaskList.value = [...bigscreendata.value.taskList]; |
| | | const totalTask = taskList.value.length; |
| | | // 任塿°<=7æ¶ä¸è½®æ |
| | | if (totalTask <= 7) { |
| | | showTaskList.value = [...taskList.value]; |
| | | return; |
| | | } |
| | | |
| | | // éç½®ç´¢å¼ |
| | | currentTaskIndex.value = 7; |
| | | // åå§æ¾ç¤ºå7æ¡ |
| | | showTaskList.value = taskList.value.slice(0, 7); |
| | | |
| | | // å¯å¨è½®æ |
| | | taskCarouselTimer = setInterval(() => { |
| | | const tableElement = document.querySelector('.el-table'); |
| | | if (tableElement) { |
| | |
| | | } |
| | | |
| | | // æ°å¢ä¸1æ¡ï¼å 餿å1æ¡ï¼ä¿æ7æ¡æ¾ç¤ºï¼ |
| | | showTaskList.value.push(bigscreendata.value.taskList[currentTaskIndex.value]); |
| | | showTaskList.value.push(taskList.value[currentTaskIndex.value]); |
| | | showTaskList.value.shift(); |
| | | |
| | | // 循ç¯ç´¢å¼ |
| | |
| | | currentTaskIndex.value = 0; |
| | | } |
| | | }, 5000); // 5ç§è½®æä¸æ¬¡ |
| | | } |
| | | |
| | | // 忢任å¡è½®æ |
| | | const stopTaskCarousel = () => { |
| | | if (taskCarouselTimer) { |
| | | clearInterval(taskCarouselTimer); |
| | | taskCarouselTimer = null; |
| | | } |
| | | } |
| | | |
| | | // å¯å¨ä¸´æç©æè½®æ |
| | | const startExpirationCarousel = () => { |
| | | // æ¸
餿§å®æ¶å¨ |
| | | if (expirationCarouselTimer) clearInterval(expirationCarouselTimer); |
| | | |
| | | const totalExpiration = nearExpirationList.value.length; |
| | | // è®°å½æ°<=7æ¶ä¸è½®æ |
| | | if (totalExpiration <= 7) { |
| | | showNearExpirationList.value = [...nearExpirationList.value]; |
| | | return; |
| | | } |
| | | |
| | | // éç½®ç´¢å¼ |
| | | currentExpirationIndex.value = 7; |
| | | // åå§æ¾ç¤ºå7æ¡ |
| | | showNearExpirationList.value = nearExpirationList.value.slice(0, 7); |
| | | |
| | | // å¯å¨è½®æ |
| | | expirationCarouselTimer = setInterval(() => { |
| | | // æ°å¢ä¸1æ¡ï¼å 餿å1æ¡ï¼ä¿æ7æ¡æ¾ç¤ºï¼ |
| | | showNearExpirationList.value.push(nearExpirationList.value[currentExpirationIndex.value]); |
| | | showNearExpirationList.value.shift(); |
| | | |
| | | // 循ç¯ç´¢å¼ |
| | | currentExpirationIndex.value++; |
| | | if (currentExpirationIndex.value >= totalExpiration) { |
| | | currentExpirationIndex.value = 0; |
| | | } |
| | | }, 5000); // 5ç§è½®æä¸æ¬¡ |
| | | } |
| | | |
| | | // 忢䏴æç©æè½®æ |
| | | const stopExpirationCarousel = () => { |
| | | if (expirationCarouselTimer) { |
| | | clearInterval(expirationCarouselTimer); |
| | | expirationCarouselTimer = null; |
| | | } |
| | | } |
| | | |
| | | // è·å临æå¤©æ°æ ·å¼ç±» |
| | | const getExpirationClass = (days) => { |
| | | if (days === undefined || days === null || isNaN(days)) return "exp-unknown"; |
| | | if (days <= 0) return "exp-expired"; // å·²è¿æ |
| | | if (days <= 7) return "exp-critical"; // 7天å
临æ |
| | | if (days <= 30) return "exp-warning"; // 30天å
临æ |
| | | return "exp-normal"; // æ£å¸¸ |
| | | } |
| | | |
| | | // è·åä»»å¡ç±»åææ¬ |
| | |
| | | return "status-unknown"; |
| | | } |
| | | |
| | | if (statusNum >= 900) return "status-completed"; // 宿 |
| | | if (statusNum >= 400) return "status-processing"; // è¾é线æ§è¡ä¸ |
| | | if (statusNum >= 300) return "status-processing"; // AGVæ§è¡ä¸ |
| | | if (statusNum >= 200) return "status-processing"; // å åæºæ§è¡ä¸ |
| | | if (statusNum >= 100) return "status-pending"; // æ°å»ºãå·²åé |
| | | if (statusNum === 900) return "status-completed"; // 宿 |
| | | if (statusNum === 970) return "status-suspended"; // æèµ· |
| | | if (statusNum === 980) return "status-canceled"; // åæ¶ |
| | | if (statusNum === 990) return "status-error"; // å¼å¸¸ |
| | | if (statusNum >= 200 && statusNum < 900) return "status-processing"; // æ§è¡ä¸ |
| | | if (statusNum >= 100 && statusNum < 200) return "status-pending"; // æ°å»ºãå·²åé |
| | | |
| | | return "status-unknown"; |
| | | } |
| | |
| | | |
| | | // ä»å端è·åæ°æ® |
| | | const fetchBigGreenData = async () => { |
| | | try { |
| | | const res = await http.get('/api/BigScreen/GetBigGreenData'); |
| | | console.log('大屿°æ®', res); |
| | | bigscreendata.value = res.data || res; |
| | | try { |
| | | // 鲿å¤çï¼é¿å
çæ¶é´å
夿¬¡è¯·æ± |
| | | const now = Date.now(); |
| | | if (now - lastRefreshTime.value < minRefreshGap.value) { |
| | | return; |
| | | } |
| | | lastRefreshTime.value = now; |
| | | |
| | | updateMetrics(); |
| | | const res = await http.get('/api/BigScreen/GetBigGreenData'); |
| | | console.log('大屿°æ®', res); |
| | | bigscreendata.value = res.data || res; |
| | | |
| | | taskList.value = bigscreendata.value.taskList || []; |
| | | showTaskList.value = taskList.value.slice(0, 7); |
| | | startTaskCarousel(); |
| | | updateMetrics(); |
| | | |
| | | // æ°æ®å è½½å®æååå§åå¾è¡¨ |
| | | nextTick(() => { |
| | | initEfficiencyChart(); |
| | | initTrendChart(); |
| | | initCategoryChart(); |
| | | }); |
| | | } catch (error) { |
| | | console.error('è·å大屿°æ®å¤±è´¥:', error); |
| | | ElMessage.error('è·åæ°æ®å¤±è´¥ï¼è¯·ç¨åéè¯'); |
| | | } |
| | | }; |
| | | // æ´æ°ä»»å¡å表 |
| | | taskList.value = Array.isArray(bigscreendata.value.taskList) ? bigscreendata.value.taskList : []; |
| | | // éå¯è½®æ |
| | | stopTaskCarousel(); |
| | | startTaskCarousel(); |
| | | |
| | | // æ´æ°å
³é®ææ |
| | | // æ´æ°ä¸´æç©æå表 |
| | | nearExpirationList.value = Array.isArray(bigscreendata.value.nearExpirationList) ? bigscreendata.value.nearExpirationList : []; |
| | | // éå¯ä¸´æç©æè½®æ |
| | | stopExpirationCarousel(); |
| | | startExpirationCarousel(); |
| | | |
| | | // æ°æ®å è½½å®æåå·æ°å¾è¡¨ |
| | | nextTick(() => { |
| | | refreshCharts(true); |
| | | }); |
| | | } catch (error) { |
| | | console.error('è·å大屿°æ®å¤±è´¥:', error); |
| | | ElMessage.error('è·åæ°æ®å¤±è´¥ï¼è¯·ç¨åéè¯'); |
| | | } |
| | | }; |
| | | |
| | | // æ´æ°å
³é®ææ - ä¿®æ£æ°æ®æ å° |
| | | const updateMetrics = () => { |
| | | metrics.value[0].value = bigscreendata.value.totalStockQuantity || 0 |
| | | metrics.value[1].value = bigscreendata.value.inboundCount || 0 |
| | | metrics.value[2].value = bigscreendata.value.outboundCount || 0 |
| | | metrics.value[3].value = bigscreendata.value.unOutBoundOrderCount || 0 |
| | | metrics.value[0].value = bigscreendata.value.unInBoundOrderCount || 0; // å¾
å
¥åºè®¢å |
| | | metrics.value[1].value = bigscreendata.value.unOutBoundOrderCount || 0; // å¾
åºåºè®¢å |
| | | metrics.value[2].value = bigscreendata.value.inboundCount || 0; // 仿¥å
¥åºå®ææ° |
| | | metrics.value[3].value = bigscreendata.value.outboundCount || 0; // 仿¥åºåºå®ææ° |
| | | metrics.value[4].value = bigscreendata.value.inStockPallet || 0; // æè´§æç®± |
| | | metrics.value[5].value = bigscreendata.value.freeStockPallet || 0; // 空箱æ°é |
| | | } |
| | | |
| | | // æ´æ°æ¶é´ |
| | |
| | | currentTime.value = formatDateTime(new Date()) |
| | | } |
| | | |
| | | // åå§åè¶å¿å¾ï¼ç´æ¥ä½¿ç¨åç«¯æ¥æï¼ |
| | | // åå§åè¶å¿å¾ |
| | | const initTrendChart = () => { |
| | | if (!trendChartRef.value) return |
| | | if (!trendChartRef.value) return; |
| | | |
| | | trendChart.value = echarts.init(trendChartRef.value) |
| | | |
| | | // ç´æ¥ä»å端è·åæ¥æåæ°æ® |
| | | const dates = [] |
| | | const inboundData = [] |
| | | const outboundData = [] |
| | | |
| | | if (bigscreendata.value.dailyInOutBoundList && bigscreendata.value.dailyInOutBoundList.length > 0) { |
| | | bigscreendata.value.dailyInOutBoundList.forEach(item => { |
| | | dates.push(item.date) // ç´æ¥ä½¿ç¨å端è¿åçæ¥æ |
| | | inboundData.push(item.dailyInboundQuantity || 0) |
| | | outboundData.push(item.dailyOutboundQuantity || 0) |
| | | }) |
| | | // 鿝æ§å®ä¾ |
| | | if (trendChart.value) { |
| | | trendChart.value.dispose(); |
| | | } |
| | | |
| | | const hasData = dates.length > 0 |
| | | trendChart.value = echarts.init(trendChartRef.value); |
| | | |
| | | // ç´æ¥ä»å端è·åæ¥æåæ°æ® |
| | | const dates = []; |
| | | const inboundData = []; |
| | | const outboundData = []; |
| | | |
| | | if (Array.isArray(bigscreendata.value.dailyInOutBoundList) && bigscreendata.value.dailyInOutBoundList.length > 0) { |
| | | bigscreendata.value.dailyInOutBoundList.forEach(item => { |
| | | dates.push(item.date || ''); // ç´æ¥ä½¿ç¨å端è¿åçæ¥æ |
| | | inboundData.push(item.dailyInboundQuantity || 0); |
| | | outboundData.push(item.dailyOutboundQuantity || 0); |
| | | }); |
| | | } |
| | | |
| | | const hasData = dates.length > 0; |
| | | |
| | | const option = { |
| | | |
| | | backgroundColor: 'transparent', |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | textStyle: { color: '#fff', fontSize: 12 }, |
| | | backgroundColor: 'rgba(0,0,0,0.7)' |
| | | }, |
| | | legend: { |
| | | data: ['å
¥åºé', 'åºåºé'], |
| | | textStyle: { color: '#fff' } |
| | | textStyle: { color: '#e0e0e0', fontSize: 12 } |
| | | }, |
| | | grid: { |
| | | left: '3%', |
| | |
| | | xAxis: { |
| | | type: 'category', |
| | | boundaryGap: false, |
| | | data: dates, |
| | | axisLine: { lineStyle: { color: '#fff' } }, |
| | | axisLabel: { color: '#fff' } |
| | | data: hasData ? dates : ['ææ æ°æ®'], |
| | | axisLine: { lineStyle: { color: '#666' } }, |
| | | axisLabel: { color: '#e0e0e0', fontSize: 11 } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | axisLine: { lineStyle: { color: '#fff' } }, |
| | | axisLine: { lineStyle: { color: '#666' } }, |
| | | splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }, |
| | | axisLabel: { color: '#fff' }, |
| | | axisLabel: { color: '#e0e0e0', fontSize: 11 }, |
| | | min: 0 |
| | | }, |
| | | series: [ |
| | |
| | | name: 'å
¥åºé', |
| | | type: 'line', |
| | | smooth: true, |
| | | data: inboundData, |
| | | data: hasData ? inboundData : [0], |
| | | itemStyle: { color: '#5470c6' }, |
| | | lineStyle: { color: '#5470c6' }, |
| | | areaStyle: { |
| | |
| | | name: 'åºåºé', |
| | | type: 'line', |
| | | smooth: true, |
| | | data: outboundData, |
| | | data: hasData ? outboundData : [0], |
| | | itemStyle: { color: '#91cc75' }, |
| | | lineStyle: { color: '#91cc75' }, |
| | | areaStyle: { |
| | |
| | | symbol: 'circle', |
| | | symbolSize: 6 |
| | | } |
| | | ], |
| | | |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | trendChart.value.setOption(option) |
| | | return trendChart.value |
| | | trendChart.value.setOption(option); |
| | | return trendChart.value; |
| | | } |
| | | |
| | | // åå§ååç±»å æ¯å¾ |
| | | const initCategoryChart = () => { |
| | | if (!categoryChartRef.value) return |
| | | if (!categoryChartRef.value) return; |
| | | |
| | | categoryChart.value = echarts.init(categoryChartRef.value) |
| | | // 鿝æ§å®ä¾ |
| | | if (categoryChart.value) { |
| | | categoryChart.value.dispose(); |
| | | } |
| | | |
| | | categoryChart.value = echarts.init(categoryChartRef.value); |
| | | |
| | | const chartData = Array.isArray(bigscreendata.value.inventoryLocationDist) && bigscreendata.value.inventoryLocationDist.length > 0 |
| | | ? bigscreendata.value.inventoryLocationDist |
| | | : [ |
| | | { value: 3580, name: 'åææ', itemStyle: { color: '#5470c6' } }, |
| | | { value: 2840, name: 'åæå', itemStyle: { color: '#91cc75' } }, |
| | | { value: 4120, name: 'æå', itemStyle: { color: '#fac858' } }, |
| | | { value: 2040, name: 'è¾
æ', itemStyle: { color: '#ee6666' } } |
| | | ]; |
| | | |
| | | const option = { |
| | | tooltip: { trigger: 'item' }, |
| | | backgroundColor: 'transparent', |
| | | tooltip: { |
| | | trigger: 'item', |
| | | textStyle: { color: '#fff', fontSize: 12 }, |
| | | backgroundColor: 'rgba(0,0,0,0.7)', |
| | | formatter: '{b}: {c} ({d}%)' |
| | | }, |
| | | legend: { |
| | | orient: 'vertical', |
| | | right: '10%', |
| | | top: 'center', |
| | | textStyle: { color: '#fff' } |
| | | textStyle: { color: '#e0e0e0', fontSize: 12 } |
| | | }, |
| | | series: [ |
| | | { |
| | |
| | | }, |
| | | label: { show: false }, |
| | | emphasis: { |
| | | label: { show: true, fontSize: 16, fontWeight: 'bold' } |
| | | label: { show: true, fontSize: 14, fontWeight: 'bold', color: '#fff' } |
| | | }, |
| | | data: bigscreendata.value.inventoryLocationDist.length > 0 |
| | | ? bigscreendata.value.inventoryLocationDist |
| | | : [ |
| | | { value: 3580, name: 'åææ', itemStyle: { color: '#5470c6' } }, |
| | | { value: 2840, name: 'åæå', itemStyle: { color: '#91cc75' } }, |
| | | { value: 4120, name: 'æå', itemStyle: { color: '#fac858' } }, |
| | | { value: 2040, name: 'è¾
æ', itemStyle: { color: '#ee6666' } } |
| | | ] |
| | | data: chartData |
| | | } |
| | | ] |
| | | } |
| | | }; |
| | | |
| | | categoryChart.value.setOption(option) |
| | | return categoryChart.value |
| | | categoryChart.value.setOption(option); |
| | | return categoryChart.value; |
| | | } |
| | | |
| | | // åå§åæçç»è®¡å¾ |
| | | // åå§åæçç»è®¡å¾ |
| | | // åå§åæçç»è®¡å¾ï¼ä¿®å¤çï¼ |
| | | const initEfficiencyChart = () => { |
| | | if (!efficiencyChartRef.value) { |
| | | console.warn('æçå¾è¡¨å®¹å¨ä¸åå¨ï¼'); |
| | | return; |
| | | } |
| | | |
| | | // ç¡®ä¿å®¹å¨æé«åº¦ |
| | | efficiencyChartRef.value.style.height = '250px'; |
| | | efficiencyChartRef.value.style.width = '100%'; |
| | | |
| | | // 鿝æ§å®ä¾ |
| | | if (efficiencyChart.value) { |
| | | efficiencyChart.value.dispose(); |
| | | } |
| | | |
| | | // åå§å ECharts |
| | | efficiencyChart.value = echarts.init(efficiencyChartRef.value); |
| | | |
| | | // æ°æ®å¤ç |
| | | const taskData = { |
| | | 'å
¥åº': 0, |
| | | 'åºåº': 0 |
| | | }; |
| | | bigscreendata.value.completeTask.forEach(item => { |
| | | if (item.taskType && typeof item.count === 'number') { |
| | | taskData[item.taskType] = item.count; |
| | | } |
| | | }); |
| | | |
| | | const option = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { type: 'shadow' }, |
| | | formatter: params => { |
| | | return params.map(p => `${p.seriesName}: ${p.value || 0} å`).join('<br/>'); |
| | | const initEfficiencyChart = () => { |
| | | if (!efficiencyChartRef.value) { |
| | | console.warn('æçå¾è¡¨å®¹å¨ä¸åå¨ï¼'); |
| | | return; |
| | | } |
| | | }, |
| | | grid: { |
| | | left: '5%', |
| | | right: '5%', |
| | | bottom: '10%', |
| | | top: '15%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: ['å
¥åºä½ä¸', 'åºåºä½ä¸'], |
| | | axisLine: { lineStyle: { color: '#fff' } }, |
| | | axisLabel: { color: '#fff' } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '宿æ°é(å)', |
| | | nameTextStyle: { color: '#fff' }, |
| | | axisLine: { lineStyle: { color: '#fff' } }, |
| | | splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }, |
| | | axisLabel: { color: '#fff' }, |
| | | min: 0 |
| | | }, |
| | | series: [ |
| | | { |
| | | name: 'ä½ä¸æ°é', |
| | | data: [taskData['å
¥åº'], taskData['åºåº']], |
| | | type: 'bar', |
| | | barWidth: '40%', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: '#83bff6' }, |
| | | { offset: 1, color: '#188df0' } |
| | | ]), |
| | | borderRadius: [5, 5, 0, 0] |
| | | |
| | | // ç¡®ä¿å®¹å¨æé«åº¦ |
| | | efficiencyChartRef.value.style.height = '250px'; |
| | | efficiencyChartRef.value.style.width = '100%'; |
| | | |
| | | // 鿝æ§å®ä¾ |
| | | if (efficiencyChart.value) { |
| | | efficiencyChart.value.dispose(); |
| | | } |
| | | |
| | | // åå§å ECharts |
| | | efficiencyChart.value = echarts.init(efficiencyChartRef.value); |
| | | |
| | | // æ°æ®å¤ç |
| | | const taskData = { |
| | | 'å
¥åº': 0, |
| | | 'åºåº': 0 |
| | | }; |
| | | |
| | | if (Array.isArray(bigscreendata.value.completeTask)) { |
| | | bigscreendata.value.completeTask.forEach(item => { |
| | | if (item.taskType && typeof item.count === 'number') { |
| | | taskData[item.taskType] = item.count; |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const hasData = taskData.å
¥åº > 0 || taskData.åºåº > 0; |
| | | |
| | | const option = { |
| | | backgroundColor: 'transparent', |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { type: 'shadow' }, |
| | | textStyle: { color: '#fff', fontSize: 12 }, |
| | | backgroundColor: 'rgba(0,0,0,0.7)', |
| | | formatter: params => { |
| | | return params.map(p => `${p.seriesName}: ${p.value || 0} å`).join('<br/>'); |
| | | } |
| | | }, |
| | | label: { |
| | | show: true, |
| | | position: 'top', |
| | | color: '#fff', |
| | | fontSize: 12 |
| | | } |
| | | } |
| | | ] |
| | | }; |
| | | grid: { |
| | | left: '5%', |
| | | right: '5%', |
| | | bottom: '10%', |
| | | top: '15%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: hasData ? ['å
¥åºä½ä¸', 'åºåºä½ä¸'] : ['ææ æ°æ®'], |
| | | axisLine: { lineStyle: { color: '#666' } }, |
| | | axisLabel: { color: '#e0e0e0', fontSize: 11 } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '宿æ°é(å)', |
| | | nameTextStyle: { color: '#e0e0e0', fontSize: 12 }, |
| | | axisLine: { lineStyle: { color: '#666' } }, |
| | | splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } }, |
| | | axisLabel: { color: '#e0e0e0', fontSize: 11 }, |
| | | min: 0 |
| | | }, |
| | | series: [ |
| | | { |
| | | name: 'ä½ä¸æ°é', |
| | | data: hasData ? [taskData['å
¥åº'], taskData['åºåº']] : [0], |
| | | type: 'bar', |
| | | barWidth: '40%', |
| | | itemStyle: { |
| | | color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
| | | { offset: 0, color: '#83bff6' }, |
| | | { offset: 1, color: '#188df0' } |
| | | ]), |
| | | borderRadius: [5, 5, 0, 0] |
| | | }, |
| | | label: { |
| | | show: hasData, |
| | | position: 'top', |
| | | color: '#ffffff', |
| | | fontSize: 12, |
| | | fontWeight: 600 |
| | | } |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | efficiencyChart.value.setOption(option, true); |
| | | console.log('æçå¾è¡¨æ¸²æå®æï¼æ°æ®ï¼', taskData); |
| | | }; |
| | | efficiencyChart.value.setOption(option, true); |
| | | console.log('æçå¾è¡¨æ¸²æå®æï¼æ°æ®ï¼', taskData); |
| | | }; |
| | | |
| | | // å·æ°å¾è¡¨æ°æ®ï¼isDataChangeï¼æ¯å¦æ¯æ°æ®åå导è´çå·æ°ï¼ |
| | | // å·æ°å¾è¡¨æ°æ® |
| | | const refreshCharts = (isDataChange = false) => { |
| | | // æ°æ®ååæ¶æ·»å éªçææ |
| | | if (isDataChange) { |
| | | const chartElements = [trendChartRef.value, categoryChartRef.value, efficiencyChartRef.value] |
| | | const chartElements = [trendChartRef.value, categoryChartRef.value, efficiencyChartRef.value]; |
| | | chartElements.forEach(el => { |
| | | if (el) { |
| | | el.classList.add('flash-effect'); |
| | | setTimeout(() => el.classList.remove('flash-effect'), 600); |
| | | } |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // 鿝æ§å¾è¡¨å®ä¾ |
| | | if (trendChart.value) trendChart.value.dispose() |
| | | if (categoryChart.value) categoryChart.value.dispose() |
| | | if (efficiencyChart.value) efficiencyChart.value.dispose() |
| | | |
| | | // éæ°åå§åå¾è¡¨ |
| | | initTrendChart() |
| | | initCategoryChart() |
| | | initEfficiencyChart() |
| | | initTrendChart(); |
| | | initCategoryChart(); |
| | | initEfficiencyChart(); |
| | | } |
| | | |
| | | // æå¨å·æ°æ°æ® |
| | | const refreshData = () => { |
| | | fetchBigGreenData() |
| | | fetchBigGreenData(); |
| | | } |
| | | |
| | | // å¯å¨èªå¨å·æ° |
| | | const startAutoRefresh = () => { |
| | | if (autoRefreshTimer) clearInterval(autoRefreshTimer) |
| | | if (autoRefreshTimer) clearInterval(autoRefreshTimer); |
| | | autoRefreshTimer = setInterval(() => { |
| | | console.log('宿¶å·æ°æ°æ®:', new Date().toLocaleString()) |
| | | fetchBigGreenData() |
| | | }, refreshInterval.value) |
| | | console.log('宿¶å·æ°æ°æ®:', new Date().toLocaleString()); |
| | | fetchBigGreenData(); |
| | | }, refreshInterval.value); |
| | | } |
| | | |
| | | // 忢èªå¨å·æ° |
| | | const stopAutoRefresh = () => { |
| | | if (autoRefreshTimer) { |
| | | clearInterval(autoRefreshTimer); |
| | | autoRefreshTimer = null; |
| | | } |
| | | } |
| | | |
| | | // çªå£å¤§å°æ¹åæ¶éç»å¾è¡¨åè°æ´è¡¨æ ¼é«åº¦ |
| | | const handleResize = () => { |
| | | try { |
| | | const windowHeight = window.innerHeight |
| | | const headerHeight = 60 |
| | | const navHeight = 50 |
| | | const metricsHeight = 120 |
| | | const chartsHeight = 300 |
| | | const padding = 80 |
| | | const windowHeight = window.innerHeight; |
| | | const headerHeight = 60; |
| | | const navHeight = 50; |
| | | const metricsHeight = 120; |
| | | const chartsHeight = 300; |
| | | const padding = 80; |
| | | |
| | | const availableHeight = windowHeight - headerHeight - navHeight - metricsHeight - chartsHeight - padding |
| | | tableHeight.value = Math.max(200, Math.min(availableHeight, 400)) |
| | | const availableHeight = windowHeight - headerHeight - navHeight - metricsHeight - chartsHeight - padding; |
| | | tableHeight.value = Math.max(200, Math.min(availableHeight, 400)); |
| | | |
| | | // éç»å¾è¡¨ |
| | | const charts = [trendChart.value, categoryChart.value, efficiencyChart.value] |
| | | const charts = [trendChart.value, categoryChart.value, efficiencyChart.value]; |
| | | charts.forEach(chart => { |
| | | if (chart) chart.resize() |
| | | }) |
| | | if (chart) chart.resize(); |
| | | }); |
| | | } catch (error) { |
| | | console.warn('å¾è¡¨éç»æ¶åºé:', error) |
| | | console.warn('å¾è¡¨éç»æ¶åºé:', error); |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // åå§åæ¶é´ |
| | | updateTime() |
| | | timer = setInterval(updateTime, 1000) |
| | | updateTime(); |
| | | timer = setInterval(updateTime, 1000); |
| | | |
| | | // åå§åæ°æ®åå¾è¡¨ |
| | | fetchBigGreenData() |
| | | // åå§åæ°æ® |
| | | fetchBigGreenData(); |
| | | |
| | | nextTick(() => { |
| | | initTrendChart() |
| | | initCategoryChart() |
| | | initEfficiencyChart() |
| | | handleResize() |
| | | startAutoRefresh() // å¯å¨èªå¨å·æ° |
| | | }) |
| | | handleResize(); |
| | | startAutoRefresh(); // å¯å¨èªå¨å·æ° |
| | | }); |
| | | |
| | | // çå¬çªå£å¤§å°åå |
| | | window.addEventListener('resize', handleResize) |
| | | }) |
| | | window.addEventListener('resize', handleResize); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | // æ¸
餿æå®æ¶å¨ |
| | | clearInterval(timer) |
| | | if (taskCarouselTimer) clearInterval(taskCarouselTimer) |
| | | if (autoRefreshTimer) clearInterval(autoRefreshTimer) |
| | | clearInterval(timer); |
| | | stopTaskCarousel(); |
| | | stopExpirationCarousel(); |
| | | stopAutoRefresh(); |
| | | |
| | | // ç§»é¤çªå£çå¬ |
| | | window.removeEventListener('resize', handleResize) |
| | | window.removeEventListener('resize', handleResize); |
| | | |
| | | // 鿝å¾è¡¨å®ä¾ |
| | | try { |
| | | if (trendChart.value) trendChart.value.dispose() |
| | | if (categoryChart.value) categoryChart.value.dispose() |
| | | if (efficiencyChart.value) efficiencyChart.value.dispose() |
| | | if (trendChart.value) trendChart.value.dispose(); |
| | | if (categoryChart.value) categoryChart.value.dispose(); |
| | | if (efficiencyChart.value) efficiencyChart.value.dispose(); |
| | | } catch (error) { |
| | | console.warn('å¾è¡¨éæ¯æ¶åºé:', error) |
| | | console.warn('å¾è¡¨éæ¯æ¶åºé:', error); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | // çå¬ä»»å¡å表ååï¼èªå¨éå¯è½®æ |
| | | watch(taskList, () => { |
| | | stopTaskCarousel(); |
| | | startTaskCarousel(); |
| | | }, { deep: true }); |
| | | |
| | | return { |
| | | currentTime, |
| | | metrics, |
| | | taskList, |
| | | showTaskList, |
| | | nearExpirationList, |
| | | showNearExpirationList, |
| | | trendChartRef, |
| | | categoryChartRef, |
| | | efficiencyChartRef, |
| | | tableHeight, |
| | | formatNumber, |
| | | getTaskTypeText, |
| | | getTaskStatusText, |
| | | getStatusClass, |
| | | getTypeClass, |
| | | getExpirationClass, |
| | | refreshData |
| | | } |
| | | }; |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | height: 60px; |
| | | background: linear-gradient(90deg, rgba(30, 58, 138, 0.5) 0%, rgba(30, 58, 138, 0.1) 100%); |
| | | border-radius: 10px; |
| | | border: 1px solid rgba(255, 255, 255, 0.1); |
| | | border: 1px solid rgba(255, 255, 255, 0.15); |
| | | } |
| | | |
| | | .title { |
| | |
| | | background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | margin: 0; |
| | | } |
| | | |
| | | .datetime { |
| | | font-size: 16px; |
| | | color: #4facfe; |
| | | font-weight: 600; |
| | | font-family: 'Consolas', monospace; |
| | | } |
| | | |
| | | .nav-menu { |
| | |
| | | gap: 8px; |
| | | padding: 10px 25px; |
| | | background: rgba(255, 255, 255, 0.05); |
| | | border: 1px solid rgba(255, 255, 255, 0.1); |
| | | border: 1px solid rgba(255, 255, 255, 0.15); |
| | | border-radius: 8px; |
| | | color: #fff; |
| | | color: #e0e0e0; |
| | | text-decoration: none; |
| | | transition: all 0.3s; |
| | | cursor: pointer; |
| | |
| | | .nav-item:hover { |
| | | background: rgba(79, 172, 254, 0.2); |
| | | border-color: #4facfe; |
| | | transform: translateY(-1px); |
| | | } |
| | | |
| | | .nav-item.active { |
| | | background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); |
| | | border-color: transparent; |
| | | color: #fff; |
| | | box-shadow: 0 4px 12px rgba(79, 172, 254, 0.3); |
| | | } |
| | | |
| | | .main-content { |
| | |
| | | gap: 15px; |
| | | } |
| | | |
| | | /* å
³é®ææ å¡ç - ä¼åç½æ ¼å¸å±åæ ·å¼å¯¹æ¯åº¦ */ |
| | | .metrics-row { |
| | | display: grid; |
| | | grid-template-columns: repeat(4, 1fr); |
| | | grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); |
| | | gap: 15px; |
| | | } |
| | | |
| | |
| | | gap: 20px; |
| | | padding: 20px; |
| | | background: rgba(255, 255, 255, 0.05); |
| | | border: 1px solid rgba(255, 255, 255, 0.1); |
| | | border: 1px solid rgba(255, 255, 255, 0.15); |
| | | border-radius: 10px; |
| | | transition: all 0.3s; |
| | | } |
| | |
| | | .metric-card:hover { |
| | | transform: translateY(-5px); |
| | | box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); |
| | | border-color: rgba(79, 172, 254, 0.5); |
| | | } |
| | | |
| | | .metric-icon { |
| | |
| | | } |
| | | |
| | | .metric-value { |
| | | font-size: 28px; |
| | | font-weight: bold; |
| | | color: #fff; |
| | | font-size: 32px; |
| | | font-weight: 700; |
| | | color: #ffffff; |
| | | margin-bottom: 5px; |
| | | text-shadow: 0 0 8px rgba(255,255,255,0.2); |
| | | } |
| | | |
| | | .metric-label { |
| | | font-size: 14px; |
| | | color: rgba(255, 255, 255, 0.6); |
| | | color: #cccccc; |
| | | margin-bottom: 5px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .metric-trend { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 5px; |
| | | font-size: 12px; |
| | | font-size: 13px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .metric-trend.up { |
| | |
| | | color: #f56c6c; |
| | | } |
| | | |
| | | /* å¾è¡¨åºå - ä¼åå¸å±åæ ·å¼ */ |
| | | .charts-row { |
| | | display: grid; |
| | | grid-template-columns: repeat(3, 1fr); |
| | | grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); |
| | | gap: 15px; |
| | | } |
| | | |
| | | .chart-card { |
| | | padding: 20px; |
| | | background: rgba(255, 255, 255, 0.05); |
| | | border: 1px solid rgba(255, 255, 255, 0.1); |
| | | border: 1px solid rgba(255, 255, 255, 0.15); |
| | | border-radius: 10px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .card-title { |
| | |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | font-weight: 600; |
| | | color: #4facfe; |
| | | } |
| | | |
| | | .chart-container { |
| | | width: 100%; |
| | | height: 250px; |
| | | .task-count { |
| | | font-size: 12px; |
| | | color: #cccccc; |
| | | font-weight: normal; |
| | | } |
| | | |
| | | .chart-container { |
| | | flex: 1; |
| | | width: 100%; |
| | | min-height: 250px; |
| | | } |
| | | |
| | | /* è¡¨æ ¼åºå */ |
| | | .table-row { |
| | | flex: 1; |
| | | } |
| | |
| | | height: 100%; |
| | | padding: 20px; |
| | | background: rgba(255, 255, 255, 0.05); |
| | | border: 1px solid rgba(255, 255, 255, 0.1); |
| | | border: 1px solid rgba(255, 255, 255, 0.15); |
| | | border-radius: 10px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | /* Element Plus Table æ ·å¼è¦ç */ |
| | | /* Element Plus Table æ ·å¼æ·±åº¦ä¼å */ |
| | | :deep(.el-table) { |
| | | background: transparent !important; |
| | | color: #e0e0e0; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | :deep(.el-table th) { |
| | | background: rgba(255, 255, 255, 0.1) !important; |
| | | color: #fff !important; |
| | | border-color: rgba(255, 255, 255, 0.1) !important; |
| | | background: rgba(255, 255, 255, 0.15) !important; |
| | | color: #ffffff !important; |
| | | border-color: rgba(255, 255, 255, 0.2) !important; |
| | | font-weight: 600; |
| | | padding: 10px 0; |
| | | } |
| | | |
| | | :deep(.el-table td) { |
| | | border-color: rgba(255, 255, 255, 0.1) !important; |
| | | color: rgba(255, 255, 255, 0.9) !important; |
| | | color: #e0e0e0 !important; |
| | | padding: 12px 0; |
| | | } |
| | | |
| | | :deep(.el-table tr) { |
| | |
| | | } |
| | | |
| | | :deep(.el-table__row:hover td) { |
| | | background: rgba(255, 255, 255, 0.05) !important; |
| | | background: rgba(255, 255, 255, 0.08) !important; |
| | | } |
| | | |
| | | :deep(.el-table--enable-row-hover .el-table__body tr:hover > td) { |
| | | background: rgba(255, 255, 255, 0.05) !important; |
| | | :deep(.el-table--border) { |
| | | border: 1px solid rgba(255,255,255,0.15) !important; |
| | | } |
| | | |
| | | /* ä»»å¡ç¶ææ ·å¼ */ |
| | | :deep(.el-table__empty-text) { |
| | | color: #cccccc !important; |
| | | } |
| | | |
| | | /* ä»»å¡ç¶ææ ·å¼ - é«å¯¹æ¯åº¦ä¼å */ |
| | | .status-container { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | position: relative; |
| | | overflow: hidden; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .status-dot { |
| | |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | /* ä¸åç¶æçé¢è² */ |
| | | /* ä¸åç¶æçé¢è² - æ·±è²ä¸»é¢é«å¯¹æ¯åº¦ */ |
| | | .status-completed { |
| | | background: rgba(103, 194, 58, 0.15); |
| | | color: #67c23a; |
| | |
| | | background: rgba(245, 108, 108, 0.5); |
| | | } |
| | | |
| | | /* ä»»å¡ç±»åæ ·å¼ */ |
| | | .status-unknown { |
| | | background: rgba(75, 85, 99, 0.15); |
| | | color: #9ca3af; |
| | | } |
| | | |
| | | .status-unknown .status-dot { |
| | | background: #9ca3af; |
| | | } |
| | | |
| | | .status-unknown .status-dot::after { |
| | | background: rgba(156, 163, 175, 0.5); |
| | | } |
| | | |
| | | /* ä»»å¡ç±»åæ ·å¼ - é«å¯¹æ¯åº¦ä¼å */ |
| | | .type-container { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | border-radius: 20px; |
| | | position: relative; |
| | | font-size: 12px; |
| | | font-weight: 500; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .type-icon { |
| | |
| | | .type-other { |
| | | background: rgba(144, 147, 153, 0.15); |
| | | color: #909399; |
| | | } |
| | | |
| | | .type-unknown { |
| | | background: rgba(75, 85, 99, 0.15); |
| | | color: #9ca3af; |
| | | } |
| | | |
| | | /* 临æå¤©æ°æ ·å¼ */ |
| | | .exp-expired { |
| | | color: #f56c6c; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .exp-critical { |
| | | color: #e6a23c; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .exp-warning { |
| | | color: #f0ad4e; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .exp-normal { |
| | | color: #67c23a; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .exp-unknown { |
| | | color: #909399; |
| | | font-weight: 400; |
| | | } |
| | | |
| | | /* å¨ç»ææ */ |
| | |
| | | } |
| | | } |
| | | |
| | | /* ååºå¼éé
*/ |
| | | /* ååºå¼éé
å¢å¼º */ |
| | | @media screen and (max-width: 1920px) { |
| | | .metric-value { |
| | | font-size: 24px; |
| | | font-size: 28px; |
| | | } |
| | | |
| | | .chart-container { |
| | | height: 220px; |
| | | min-height: 220px; |
| | | } |
| | | } |
| | | |
| | | @media screen and (max-width: 1600px) { |
| | | .metrics-row { |
| | | grid-template-columns: repeat(2, 1fr); |
| | | } |
| | | |
| | | .charts-row { |
| | | grid-template-columns: repeat(2, 1fr); |
| | | } |
| | | |
| | | .title { |
| | | font-size: 20px; |
| | | } |
| | | |
| | | .metric-value { |
| | | font-size: 20px; |
| | | font-size: 24px; |
| | | } |
| | | |
| | | .chart-container { |
| | | height: 200px; |
| | | min-height: 200px; |
| | | } |
| | | } |
| | | |
| | |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .metrics-row { |
| | | grid-template-columns: repeat(2, 1fr); |
| | | gap: 10px; |
| | | } |
| | | |
| | | .metric-card { |
| | | padding: 15px; |
| | | } |
| | | |
| | | .metric-value { |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .charts-row { |
| | | grid-template-columns: 1fr; |
| | | gap: 10px; |
| | | font-size: 22px; |
| | | } |
| | | |
| | | .chart-card { |
| | |
| | | } |
| | | |
| | | .chart-container { |
| | | height: 180px; |
| | | } |
| | | } |
| | | |
| | | @media screen and (max-width: 1024px) { |
| | | .metrics-row { |
| | | grid-template-columns: 1fr 1fr; |
| | | } |
| | | |
| | | .nav-menu { |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .nav-item { |
| | | flex: 1; |
| | | min-width: 100px; |
| | | justify-content: center; |
| | | min-height: 180px; |
| | | } |
| | | } |
| | | |
| | |
| | | .nav-menu { |
| | | gap: 8px; |
| | | padding: 0; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .nav-item { |
| | | padding: 6px 12px; |
| | | font-size: 12px; |
| | | flex: 1; |
| | | min-width: 80px; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | | gap: 4px; |
| | | } |
| | | |
| | | .metrics-row { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | |
| | | .metric-card { |
| | |
| | | height: 45px; |
| | | } |
| | | |
| | | .chart-container { |
| | | height: 150px; |
| | | .metric-trend { |
| | | justify-content: center; |
| | | } |
| | | } |
| | | </style> |