| | |
| | | <div class="title"> |
| | | <div class="name"> |
| | | <span> 综合统计分析</span> |
| | | <img src="/src/assets/images/workbench/st1.png" alt="" /> |
| | | <img @click="refresh" src="/src/assets/images/workbench/st1.png" alt="" /> |
| | | <div class="time-card"> |
| | | <div |
| | | class="card-item" |
| | |
| | | <img :src="overviewImg1" alt="" /> |
| | | <div class="cardtotal"> |
| | | <p>工单统计占比</p> |
| | | <!-- <div class="total-number">{{ eventTotal }}</div> |
| | | <span>个</span> --> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | <div class="status-item" v-for="(item, index) in eventTypeList" :key="index"> |
| | | <div class="statusCon"> |
| | | <div class="status-label">{{ item.name }}</div> |
| | | <!-- <div :style="{ color: item.color }" class="status-value"> |
| | | {{ item.value }}<span>个</span> |
| | | </div> --> |
| | | <div class="status-value">{{ item.value }}<span>个</span></div> |
| | | <div class="ratio"> |
| | | 占比 |
| | |
| | | <!-- 飞行统计 --> |
| | | <div class="flyOrder"> |
| | | <div class="fytitle"> |
| | | <img src="@/assets/images/workbench/fy1.png" alt="" /> |
| | | <img :src="fy1" alt="" /> |
| | | <span>飞行统计</span> |
| | | </div> |
| | | <div class="flycenter"> |
| | |
| | | import overviewImg3 from '@/assets/images/workbench/tc3.svg'; |
| | | import overviewImg4 from '@/assets/images/workbench/tc4.svg'; |
| | | import overviewImg5 from '@/assets/images/workbench/tc5.svg'; |
| | | |
| | | import fy1 from '@/assets/images/workbench/fy1.png'; |
| | | import flyImg1 from '@/assets/images/workbench/fy2.svg'; |
| | | import flyImg2 from '@/assets/images/workbench/fy3.svg'; |
| | | import flyImg3 from '@/assets/images/workbench/fy4.svg'; |
| | |
| | | checked.value = item; |
| | | params.value.date_enum = item; |
| | | dateSelect.value = item; |
| | | getTypeData(); |
| | | getFlyList(); |
| | | getFlyTimeList(); |
| | | }; |
| | | const refresh = () => { |
| | | params.value.date_enum = 'CURRENT_YEAR'; |
| | | checked.value = 'CURRENT_YEAR'; |
| | | dateSelect.value = 'CURRENT_YEAR'; |
| | | getTypeData(); |
| | | getFlyList(); |
| | | getFlyTimeList(); |
| | |
| | | const getTypeData = () => { |
| | | getJobEventByStatus(params.value).then(res => { |
| | | const resList = res?.data?.data || []; |
| | | |
| | | resList.forEach(item => { |
| | | eventTypeList.value.forEach(item1 => { |
| | | if (item1.name === item.name) { |
| | |
| | | }); |
| | | }; |
| | | // 飞行统计 |
| | | |
| | | const getFlyList = () => { |
| | | getFly(params.value).then(res => { |
| | | flyTypeList.value = flyTypeList.value.map(item => ({ |
| | |
| | | const data = { |
| | | total: { |
| | | title: '总计', |
| | | |
| | | figure: totalNum.toString(), // 动态计算总数 |
| | | }, |
| | | data: val.map(item => ({ |
| | |
| | | rate: item.rate, |
| | | })), |
| | | }; |
| | | |
| | | const containerWidth = chart.value.clientWidth |
| | | const isSmallScreen = containerWidth < 768 // 移动端判断 |
| | | const echartsOption = { |
| | | color: ['#FF472F', '#FF7411', '#FFC300', '#0291A1'], |
| | | tooltip: { |
| | |
| | | borderWidth: 0, |
| | | formatter: params => { |
| | | return `<div style="background-color: rgba($color: #FFFFFF, $alpha: 0.95); |
| | | box-shadow: 0 4px 9px 0 rgba($color: #000000, $alpha: 0.1); |
| | | padding:0 12px; |
| | | box-shadow: 0 0.4rem 0.9rem 0 rgba($color: #000000, $alpha: 0.1); |
| | | padding:0 1.2rem; |
| | | display: flex; |
| | | align-items: center; |
| | | border-radius: 4px; |
| | | font-size: 12px;" class="tooltip-area"> |
| | | border-radius: 0.4rem; |
| | | font-size: 1.2rem;" class="tooltip-area"> |
| | | <p>${params.marker}${params.name}</p> |
| | | <h4 style="margin-left: 30px;">${params.data.rate || params.percent}%</h4> |
| | | <h4 style="margin-left: 1rem;">${params.data.rate || params.percent}%</h4> |
| | | </div>`; |
| | | }, |
| | | }, |
| | |
| | | text: data.total.title, |
| | | textStyle: { |
| | | color: 'rgba(28, 31, 35, 0.80)', |
| | | fontSize: '12px', |
| | | fontSize: '1.2rem', |
| | | fontWeight: 'bold', |
| | | }, |
| | | subtext: data.total.figure, |
| | | subtextStyle: { |
| | | color: '#1C1F23', |
| | | fontSize: '20px', |
| | | fontSize: '2rem', |
| | | fontWeight: '600', |
| | | }, |
| | | top: '40%', |
| | |
| | | // 使用 b 样式标记包裹百分比数值 |
| | | return `{a|${params.name}}: {b|${params.data.rate}%}`; |
| | | }, |
| | | fontSize: isSmallScreen ? '0.8rem' : '1.2rem', |
| | | position: isSmallScreen ? 'outer' : 'outer', |
| | | alignTo: 'labelLine', |
| | | overflow: 'truncate', |
| | | overflow: 'none', // 禁用省略号 |
| | | bleedMargin: 30, // 防止标签被截断 |
| | | rich: { |
| | | a: { |
| | | color: 'rgba(28, 31, 35, 0.80)', |
| | | fontSize: 12, // 建议去掉引号使用数字 |
| | | fontSize: isSmallScreen ? '1rem' : '1.2rem', |
| | | }, |
| | | b: { |
| | | color: '#1C1F23', |
| | | fontSize: 14, |
| | | fontWeight: 'bold', // 确保加粗 |
| | | color: '#1C1F23', |
| | | fontSize: isSmallScreen ? '1rem' : '1.3rem', |
| | | fontWeight: 'bold', |
| | | }, |
| | | }, |
| | | }, |
| | | labelLine: { |
| | | show: true, |
| | | length: 5, // 调整引导线长度 |
| | | length2: 15, |
| | | length: 3, // 调整引导线长度 |
| | | length2: 5, |
| | | lineStyle: { |
| | | cap: 'round', |
| | | }, |
| | | minTurnAngle: 45, // 防止小角度重叠 |
| | | }, |
| | | data: data.data, |
| | | }, |
| | |
| | | chart.value.setOption(echartsOption); |
| | | }; |
| | | |
| | | // 柱状图 |
| | | // 折线/柱状图 |
| | | const lineCharts = bardata => { |
| | | const categories = bardata?.map(item => item.name); // x轴类别 |
| | | const flight_distance = []; |
| | |
| | | itemWidth: 15, |
| | | itemHeight: 10, |
| | | itemGap: 25, |
| | | fontSize:'1.2rem' |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | |
| | | }, |
| | | axisLabel: { |
| | | interval: 0, |
| | | color: '#383838', // 直接配置颜色 |
| | | color: '#383838', |
| | | }, |
| | | }, |
| | | yAxis: [ |
| | |
| | | name: '单位:万套', |
| | | nameTextStyle: { |
| | | color: '#383838', |
| | | fontSize:'1.2rem' |
| | | }, |
| | | min: 1, |
| | | logBase: 3, |
| | |
| | | </style> |
| | | <style scoped lang="scss"> |
| | | .workbench { |
| | | padding: 0px 20px 0 20px; |
| | | padding: 0px 20px 0 10px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | } |
| | |
| | | span { |
| | | margin-right: 4px; |
| | | } |
| | | img { |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | .arrow { |
| | | cursor: pointer; |
| | |
| | | line-height: 32px; |
| | | cursor: pointer; |
| | | font-family: 'Source Han Sans CN'; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #1441FF; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #7c8091; |
| | | } |
| | | .card-item:first-child { |
| | | border-right: 1px solid #e5e5e5; |
| | |
| | | color: #7c8091; |
| | | } |
| | | .total-number { |
| | | font-family: 'Source Han Sans CN'; |
| | | font-family: 'Source Han Sans CN'; |
| | | |
| | | font-weight: bold; |
| | | font-size: 32px; |
| | |
| | | text-align: center; |
| | | justify-content: space-between; |
| | | height: 97px; |
| | | max-width: 148px; |
| | | max-width: 158px; |
| | | background: #f6f8fe; |
| | | border-radius: 8px 8px 8px 8px; |
| | | img { |
| | |
| | | display: flex; |
| | | flex-direction: column; |
| | | // align-items: center; |
| | | padding: 9px 4px 7px 10px; |
| | | padding: 5px 4px 9px 10px; |
| | | text-align: left; |
| | | .status-label { |
| | | font-weight: 400; |