| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <PanelHeader title="å¨å¶åç»è®¡åæ" /> |
| | | <div class="main-panel panel-item-customers"> |
| | | <CarouselCards :items="cardItems" :visible-count="3" /> |
| | | <div class="chart-wrapper"> |
| | | <Echarts |
| | | ref="chart" |
| | | :chartStyle="chartStyle" |
| | | :grid="grid" |
| | | :legend="workInProcessBarLegend" |
| | | :series="workInProcessBarSeries" |
| | | :tooltip="tooltip" |
| | | :xAxis="workInProcessXAxis" |
| | | :yAxis="workInProcessYAxis" |
| | | :options="{ backgroundColor: 'transparent', textStyle: { color: '#B8C8E0' } }" |
| | | style="height: 100%" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, inject, watch } from 'vue' |
| | | import Echarts from '@/components/Echarts/echarts.vue' |
| | | import PanelHeader from './PanelHeader.vue' |
| | | import CarouselCards from './CarouselCards.vue' |
| | | import { getWorkInProcessTurnover } from '@/api/viewIndex.js' |
| | | |
| | | // å¨å¶åå¨è½¬ç»è®¡å¯¹è±¡ |
| | | const workInProcessStatistics = ref({ |
| | | totalQuantity: 0, |
| | | avgTurnoverDays: 0, |
| | | turnoverEfficiency: 0, |
| | | }) |
| | | |
| | | // è½®æå¡çæ°æ®ï¼ç± workInProcessStatistics åæ¥ï¼ |
| | | const cardItems = ref([]) |
| | | |
| | | const chartStyle = { |
| | | width: '100%', |
| | | height: '100%', |
| | | } |
| | | |
| | | const grid = { |
| | | left: '3%', |
| | | right: '4%', |
| | | bottom: '3%', |
| | | containLabel: true, |
| | | } |
| | | |
| | | const tooltip = { |
| | | trigger: 'axis', |
| | | axisPointer: { type: 'shadow' }, |
| | | formatter: function (params) { |
| | | let result = params[0].axisValueLabel + '<br/>' |
| | | params.forEach((item) => { |
| | | result += `<div style="color: #B8C8E0">${item.marker} ${item.seriesName}: ${item.value}</div>` |
| | | }) |
| | | return result |
| | | }, |
| | | } |
| | | |
| | | // å¨å¶åå·¥åºæ±ç¶å¾é
ç½® |
| | | const workInProcessXAxis = ref([ |
| | | { |
| | | type: 'category', |
| | | axisTick: { show: false }, |
| | | axisLabel: { color: '#B8C8E0' }, |
| | | data: [], |
| | | }, |
| | | ]) |
| | | const workInProcessYAxis = [ |
| | | { |
| | | type: 'value', |
| | | axisLabel: { color: '#B8C8E0' }, |
| | | name: '', |
| | | }, |
| | | ] |
| | | const workInProcessBarLegend = { |
| | | show: false, |
| | | textStyle: { color: '#B8C8E0' }, |
| | | data: [], |
| | | } |
| | | const workInProcessBarSeries = ref([ |
| | | { |
| | | name: 'å¨å¶åæ°é', |
| | | type: 'bar', |
| | | barWidth: 25, |
| | | barGap: 0, |
| | | emphasis: { focus: 'series' }, |
| | | itemStyle: { |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 1, color: 'rgba(0,164,237,0)' }, |
| | | { offset: 0, color: '#4EE4FF' }, |
| | | ], |
| | | }, |
| | | }, |
| | | label: { |
| | | show: true, |
| | | position: 'top', |
| | | color: '#B8C8E0', |
| | | }, |
| | | data: [], |
| | | }, |
| | | ]) |
| | | |
| | | const workInProcessTurnoverInfo = () => { |
| | | getWorkInProcessTurnover() |
| | | .then((res) => { |
| | | if (!res || !res.data) return |
| | | const stats = { |
| | | totalQuantity: res.data.totalOrderCount || 0, |
| | | avgTurnoverDays: res.data.averageTurnoverDays || 0, |
| | | turnoverEfficiency: res.data.turnoverEfficiency || 0, |
| | | } |
| | | workInProcessStatistics.value = stats |
| | | cardItems.value = [ |
| | | { label: 'æ»å¨å¶æ°é', value: stats.totalQuantity, unit: 'ä»¶' }, |
| | | { label: 'å¹³åå¨è½¬å¤©æ°', value: stats.avgTurnoverDays, unit: '天' }, |
| | | { label: 'å¨è½¬æç', value: stats.turnoverEfficiency, unit: '%' }, |
| | | ] |
| | | if (res.data.processDetails && Array.isArray(res.data.processDetails)) { |
| | | workInProcessXAxis.value[0].data = res.data.processDetails |
| | | } else { |
| | | workInProcessXAxis.value[0].data = [] |
| | | } |
| | | if (res.data.processQuantityDetails && Array.isArray(res.data.processQuantityDetails)) { |
| | | workInProcessBarSeries.value[0].data = res.data.processQuantityDetails |
| | | } else { |
| | | workInProcessBarSeries.value[0].data = [] |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.error('è·åå¨å¶åå¨è½¬ç»è®¡å¤±è´¥:', err) |
| | | }) |
| | | } |
| | | |
| | | const dataDashboardRefreshTick = inject('dataDashboardRefreshTick', null) |
| | | if (dataDashboardRefreshTick) { |
| | | watch(dataDashboardRefreshTick, () => { |
| | | workInProcessTurnoverInfo() |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | workInProcessTurnoverInfo() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .main-panel { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | |
| | | .panel-item-customers { |
| | | border: 1px solid #1a58b0; |
| | | border-radius: 16px; |
| | | padding: 18px; |
| | | width: 100%; |
| | | height: 449px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .chart-wrapper { |
| | | height: 70%; |
| | | flex: 1; |
| | | min-height: 200px; |
| | | } |
| | | </style> |