| 1 |
- {"ast":null,"code":"import \"core-js/modules/es.iterator.constructor.js\";\nimport \"core-js/modules/es.iterator.map.js\";\nimport * as echarts from 'echarts';\nimport { getEquipmentStats } from '@/api';\nexport default {\n name: 'EquipmentStats',\n data() {\n return {\n chart: null,\n summary: {\n totalDevices: 0,\n totalHours: '',\n usageRate: ''\n },\n status: {\n using: 0,\n idle: 0,\n normal: 0,\n repair: 0\n }\n };\n },\n async mounted() {\n const res = await getEquipmentStats();\n this.summary = res.data.summary;\n this.status = res.data.status;\n this.$nextTick(() => this.initChart(res.data.categories));\n },\n beforeDestroy() {\n if (this.chart) this.chart.dispose();\n },\n methods: {\n initChart(categories) {\n this.chart = echarts.init(this.$refs.chart);\n const option = {\n tooltip: {\n trigger: 'item',\n backgroundColor: 'rgba(13,34,71,0.9)',\n borderColor: '#1a3a6a',\n textStyle: {\n color: '#fff',\n fontSize: 12\n }\n },\n legend: {\n orient: 'vertical',\n right: 10,\n top: 'center',\n textStyle: {\n color: '#8cb8e6',\n fontSize: 11\n },\n itemWidth: 10,\n itemHeight: 10,\n itemGap: 10,\n icon: 'circle'\n },\n series: [{\n type: 'pie',\n radius: ['35%', '60%'],\n center: ['35%', '50%'],\n avoidLabelOverlap: false,\n label: {\n show: false\n },\n emphasis: {\n label: {\n show: false\n },\n scaleSize: 5\n },\n data: categories.map(c => ({\n name: c.name,\n value: c.value,\n itemStyle: {\n color: c.color\n }\n }))\n }]\n };\n this.chart.setOption(option);\n }\n }\n};","map":{"version":3,"names":["echarts","getEquipmentStats","name","data","chart","summary","totalDevices","totalHours","usageRate","status","using","idle","normal","repair","mounted","res","$nextTick","initChart","categories","beforeDestroy","dispose","methods","init","$refs","option","tooltip","trigger","backgroundColor","borderColor","textStyle","color","fontSize","legend","orient","right","top","itemWidth","itemHeight","itemGap","icon","series","type","radius","center","avoidLabelOverlap","label","show","emphasis","scaleSize","map","c","value","itemStyle","setOption"],"sources":["src/components/LabStats/EquipmentStats.vue"],"sourcesContent":["<template>\n <div class=\"panel-box equipment-stats\">\n <div class=\"panel-title\">实验室设备分类及使用统计</div>\n <div class=\"panel-content\">\n <div ref=\"chart\" class=\"chart-area\"></div>\n <div class=\"stats-row top-stats\">\n <div class=\"stat-item\">\n <div class=\"stat-value blue\">{{ summary.totalDevices }}</div>\n <div class=\"stat-label\">设备总数</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value cyan\">{{ summary.totalHours }}<span class=\"stat-unit\">h</span></div>\n <div class=\"stat-label\">使用总时长</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value green\">{{ summary.usageRate }}<span class=\"stat-unit\">%</span></div>\n <div class=\"stat-label\">设备使用率</div>\n </div>\n </div>\n <div class=\"stats-row bottom-stats\">\n <div class=\"stat-item\">\n <div class=\"stat-value blue\">{{ status.using }}</div>\n <div class=\"stat-label\">使用</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value cyan\">{{ status.idle }}</div>\n <div class=\"stat-label\">空闲</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value green\">{{ status.normal }}</div>\n <div class=\"stat-label\">正常</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value orange\">{{ status.repair }}</div>\n <div class=\"stat-label\">维修</div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\nimport * as echarts from 'echarts'\nimport { getEquipmentStats } from '@/api'\n\nexport default {\n name: 'EquipmentStats',\n data() {\n return {\n chart: null,\n summary: { totalDevices: 0, totalHours: '', usageRate: '' },\n status: { using: 0, idle: 0, normal: 0, repair: 0 }\n }\n },\n async mounted() {\n const res = await getEquipmentStats()\n this.summary = res.data.summary\n this.status = res.data.status\n this.$nextTick(() => this.initChart(res.data.categories))\n },\n beforeDestroy() {\n if (this.chart) this.chart.dispose()\n },\n methods: {\n initChart(categories) {\n this.chart = echarts.init(this.$refs.chart)\n const option = {\n tooltip: {\n trigger: 'item',\n backgroundColor: 'rgba(13,34,71,0.9)',\n borderColor: '#1a3a6a',\n textStyle: { color: '#fff', fontSize: 12 }\n },\n legend: {\n orient: 'vertical',\n right: 10,\n top: 'center',\n textStyle: { color: '#8cb8e6', fontSize: 11 },\n itemWidth: 10,\n itemHeight: 10,\n itemGap: 10,\n icon: 'circle'\n },\n series: [{\n type: 'pie',\n radius: ['35%', '60%'],\n center: ['35%', '50%'],\n avoidLabelOverlap: false,\n label: { show: false },\n emphasis: {\n label: { show: false },\n scaleSize: 5\n },\n data: categories.map(c => ({\n name: c.name,\n value: c.value,\n itemStyle: { color: c.color }\n }))\n }]\n }\n this.chart.setOption(option)\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.equipment-stats {\n height: 100%;\n display: flex;\n flex-direction: column;\n\n .panel-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n}\n\n.chart-area {\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.stats-row {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.top-stats {\n margin-bottom: 8px;\n\n .stat-item {\n flex: 1;\n text-align: center;\n padding: 8px 4px;\n background: rgba(255, 255, 255, 0.03);\n border: 1px solid rgba(255, 255, 255, 0.05);\n border-radius: 4px;\n }\n}\n\n.bottom-stats {\n .stat-item {\n flex: 1;\n text-align: center;\n padding: 8px 4px;\n background: rgba(255, 255, 255, 0.03);\n border: 1px solid rgba(255, 255, 255, 0.05);\n border-radius: 4px;\n }\n}\n\n.stat-value {\n font-size: 22px;\n font-weight: bold;\n font-family: 'Courier New', monospace;\n line-height: 1.2;\n\n &.blue { color: #2196f3; }\n &.cyan { color: $accent-cyan; }\n &.green { color: $accent-green; }\n &.orange { color: $accent-orange; }\n}\n\n.stat-unit {\n font-size: 12px;\n font-weight: normal;\n opacity: 0.7;\n}\n\n.stat-label {\n font-size: 11px;\n color: $text-muted;\n margin-top: 3px;\n}\n</style>\n"],"mappings":";;AA0CA,YAAAA,OAAA;AACA,SAAAC,iBAAA;AAEA;EACAC,IAAA;EACAC,KAAA;IACA;MACAC,KAAA;MACAC,OAAA;QAAAC,YAAA;QAAAC,UAAA;QAAAC,SAAA;MAAA;MACAC,MAAA;QAAAC,KAAA;QAAAC,IAAA;QAAAC,MAAA;QAAAC,MAAA;MAAA;IACA;EACA;EACA,MAAAC,QAAA;IACA,MAAAC,GAAA,SAAAd,iBAAA;IACA,KAAAI,OAAA,GAAAU,GAAA,CAAAZ,IAAA,CAAAE,OAAA;IACA,KAAAI,MAAA,GAAAM,GAAA,CAAAZ,IAAA,CAAAM,MAAA;IACA,KAAAO,SAAA,YAAAC,SAAA,CAAAF,GAAA,CAAAZ,IAAA,CAAAe,UAAA;EACA;EACAC,cAAA;IACA,SAAAf,KAAA,OAAAA,KAAA,CAAAgB,OAAA;EACA;EACAC,OAAA;IACAJ,UAAAC,UAAA;MACA,KAAAd,KAAA,GAAAJ,OAAA,CAAAsB,IAAA,MAAAC,KAAA,CAAAnB,KAAA;MACA,MAAAoB,MAAA;QACAC,OAAA;UACAC,OAAA;UACAC,eAAA;UACAC,WAAA;UACAC,SAAA;YAAAC,KAAA;YAAAC,QAAA;UAAA;QACA;QACAC,MAAA;UACAC,MAAA;UACAC,KAAA;UACAC,GAAA;UACAN,SAAA;YAAAC,KAAA;YAAAC,QAAA;UAAA;UACAK,SAAA;UACAC,UAAA;UACAC,OAAA;UACAC,IAAA;QACA;QACAC,MAAA;UACAC,IAAA;UACAC,MAAA;UACAC,MAAA;UACAC,iBAAA;UACAC,KAAA;YAAAC,IAAA;UAAA;UACAC,QAAA;YACAF,KAAA;cAAAC,IAAA;YAAA;YACAE,SAAA;UACA;UACA7C,IAAA,EAAAe,UAAA,CAAA+B,GAAA,CAAAC,CAAA;YACAhD,IAAA,EAAAgD,CAAA,CAAAhD,IAAA;YACAiD,KAAA,EAAAD,CAAA,CAAAC,KAAA;YACAC,SAAA;cAAAtB,KAAA,EAAAoB,CAAA,CAAApB;YAAA;UACA;QACA;MACA;MACA,KAAA1B,KAAA,CAAAiD,SAAA,CAAA7B,MAAA;IACA;EACA;AACA","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}
|