| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- <template>
- <module-container title="模块三 培训质控分析">
- <div class="module-brigade-content">
- <div class="chart-row">
- <div class="chart-item">
- <div class="chart-title">查堵-人员自测漏检次数</div>
- <div ref="chart1" class="echarts"></div>
- </div>
- <div class="chart-item">
- <div class="chart-title">查堵人员月考成绩</div>
- <div ref="chart2" class="echarts"></div>
- </div>
- </div>
- </div>
- </module-container>
- </template>
- <script setup>
- import { ref, onMounted, watch } from 'vue'
- import * as echarts from 'echarts'
- import ModuleContainer from './ModuleContainer.vue'
- import { useEcharts } from '@/hooks/chart.js'
- import { formatDateHy } from '@/utils/index.js'
- import {
- selfTestHasMissCheck,
- monthlyAssessment
- } from '@/api/blockingData/blockingDataScreen'
- const props = defineProps({
- filterParams: {
- type: Object,
- default: () => ({})
- }
- })
- const loading = ref(false)
- const processFilterParams = (params) => {
- const { dateRange, ...rest } = params
- const processed = { ...rest }
- if (dateRange && Array.isArray(dateRange) && dateRange.length === 2) {
- processed.startTime = formatDateHy(dateRange[0])
- processed.endTime = formatDateHy(dateRange[1])
- }
- if (processed.brigadeId == 'all') {
- delete processed.brigadeId
- }
- if (processed.terminalId == 'all') {
- delete processed.terminalId
- }
- return processed
- }
- const chart1 = ref(null)
- const chart2 = ref(null)
- const { setOption: setOption1 } = useEcharts(chart1)
- const { setOption: setOption2 } = useEcharts(chart2)
- const fetchData = async () => {
- loading.value = true
- try {
- const processedParams = processFilterParams(props.filterParams)
- const [missCheckRes, assessmentRes] = await Promise.all([
- selfTestHasMissCheck(processedParams),
- monthlyAssessment(processedParams)
- ])
- if (missCheckRes.data) {
- const colors = ['#22c55e', '#3b82f6', '#f97316']
- const missCheckData = missCheckRes.data.map(item => ({
- name: item.name || item.level || '未知',
- value: item.total || item.count || 0
- }))
- setOption1(ringChartOption(missCheckData, colors))
- }
- if (assessmentRes.data) {
- const colors = ['#22c55e', '#3b82f6', '#fbbf24', '#ef4444']
- const assessmentData = assessmentRes.data.map(item => ({
- name: item.level || item.name || '',
- value: item.total || 0
- }))
- setOption2(ringChartOption(assessmentData, colors))
- }
- } catch (error) {
- console.error('获取数据失败:', error)
- } finally {
- loading.value = false
- }
- }
- watch(() => props.filterParams, () => {
- fetchData()
- }, { deep: true })
- const ringChartOption = (data, colors) => ({
- color: colors,
- tooltip: { trigger: 'item', formatter: '{b}: {c}' },
- legend: {
- data: data.map(item => item.name),
- top: '0%',
- textStyle: { fontSize: 10 }
- },
- series: [{
- type: 'pie',
- radius: ['35%', '45%'],
- center: ['50%', '55%'],
- data: data,
- label: {
- show: true,
- formatter: (params) => {
- const total = data.reduce((sum, item) => sum + item.value, 0)
- const percentage = ((params.value / total) * 100).toFixed(2)
- return `${params.name}\n${params.value}(${percentage}%)`
- },
- fontSize: 10
- }
- }]
- })
- onMounted(() => {
- fetchData()
- })
- </script>
- <style lang="less" scoped>
- .module-brigade-content {
- height: 100%;
- display: flex;
- flex-direction: column;
- gap: 10px;
- overflow-y: auto;
- }
- .chart-row {
- display: flex;
- gap: 10px;
- flex-shrink: 0;
- }
- .chart-item {
- flex: 1;
- background: #fff;
- border-radius: 6px;
- padding: 10px;
- border: 1px solid #eee;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
- display: flex;
- flex-direction: column;
- min-height: 400px;
- }
- .chart-title {
- font-size: 17px;
- color: black;
- margin-bottom: 5px;
- text-align: left;
- }
- .echarts {
- flex: 1;
- width: 100%;
- min-height: 0;
- }
- </style>
|