mat/frontend/src/views/screen/ScreenFactories.vue

110 lines
3.5 KiB
Vue

<template>
<div>
<div class="screen-grid">
<div class="screen-card" style="grid-column: span 6;">
<h3>工厂地区分布</h3>
<div ref="regionChart" style="height: 260px;"></div>
</div>
<div class="screen-card" style="grid-column: span 6;">
<h3>工厂材料分类分布</h3>
<div ref="categoryChart" style="height: 260px;"></div>
</div>
<div class="screen-card" style="grid-column: span 12;">
<h3>工厂列表</h3>
<div class="scroll-list">
<div class="scroll-inner">
<div v-for="item in factories" :key="item.id" class="scroll-item" @click="goDetail(item)">
<div>{{ item.factory_name }} · {{ formatRegion(item.province, item.city, '') }}</div>
<div style="font-size: 12px; color: #9fb3c8;">{{ item.website }}</div>
</div>
<div v-for="item in factories" :key="`copy-${item.id}`" class="scroll-item" @click="goDetail(item)">
<div>{{ item.factory_name }} · {{ formatRegion(item.province, item.city, '') }}</div>
<div style="font-size: 12px; color: #9fb3c8;">{{ item.website }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'
import * as echarts from 'echarts'
import { regionLabel, formatRegion } from '@/utils/region'
import { fetchFactoryStats } from '@/api/statistics'
const router = useRouter()
const factories = ref([])
const regionChart = ref(null)
const categoryChart = ref(null)
let charts = []
let timer = null
const onResize = () => charts.forEach((chart) => chart.resize())
const initCharts = () => {
charts = [
echarts.init(regionChart.value),
echarts.init(categoryChart.value)
]
}
const updateCharts = (data) => {
const regionData = (data.region_stats || []).map((item) => ({
name: `${regionLabel(item.province)}-${regionLabel(item.city)}`,
value: item.count
}))
charts[0].setOption({
tooltip: { trigger: 'item' },
series: [{ type: 'pie', radius: ['30%', '70%'], data: regionData }]
})
const factoryStats = data.factory_category_stats || []
const factoriesAxis = factoryStats.map((item) => item.factory_name)
const categories = [...new Set(factoryStats.flatMap((item) => item.categories.map((c) => c.material_category)))]
const series = categories.map((cat) => ({
name: cat,
type: 'bar',
stack: 'total',
data: factoryStats.map((item) => {
const found = item.categories.find((c) => c.material_category === cat)
return found ? found.count : 0
})
}))
charts[1].setOption({
tooltip: { trigger: 'axis' },
legend: { textStyle: { color: '#c9d7e6' } },
grid: { left: 40, right: 20, top: 30, bottom: 40 },
xAxis: { type: 'category', data: factoriesAxis, axisLabel: { color: '#9fb3c8', rotate: 20 } },
yAxis: { type: 'value', axisLabel: { color: '#9fb3c8' } },
series
})
}
const loadData = async () => {
const data = await fetchFactoryStats()
factories.value = data.factories_list || []
updateCharts(data)
}
const goDetail = (item) => {
router.push(`/factories/${item.id}`)
}
onMounted(async () => {
initCharts()
await loadData()
timer = setInterval(loadData, 10000)
window.addEventListener('resize', onResize)
})
onBeforeUnmount(() => {
charts.forEach((chart) => chart.dispose())
clearInterval(timer)
window.removeEventListener('resize', onResize)
})
</script>