465 lines
12 KiB
Vue
465 lines
12 KiB
Vue
<template>
|
|
<div class="warp">
|
|
<div class="item df">
|
|
<div>
|
|
<div class="title">
|
|
<div class="title-text">装备台账分析</div>
|
|
<div class="tab" :class="{ active: activeTab1 == 1 }" @click="handleActiveTab(1)">总价值</div>
|
|
<div class="tab" :class="{ active: activeTab1 == 2 }" @click="handleActiveTab(2)">配置率</div>
|
|
</div>
|
|
<div v-if="activeTab1 == 1" class="price">
|
|
<div class="tab-title">装备资产总价值</div>
|
|
<div style="margin-bottom: 35px">
|
|
<span class="price-text">{{ priceData.total || 0 }}</span>
|
|
<span class="unit-text">万元</span>
|
|
</div>
|
|
<div class="df" style="justify-content: space-between">
|
|
<div>
|
|
<div class="tab-title">线路装备</div>
|
|
<div class="price-small-text p-df">
|
|
<span>{{ priceData.line || 0 }}</span>
|
|
<span class="unit-text">万元</span>
|
|
</div>
|
|
</div>
|
|
<el-divider direction="vertical" class="tab-divider" />
|
|
<div>
|
|
<div class="tab-title">变电装备</div>
|
|
<div class="price-small-text p-df">
|
|
{{ priceData.substation || 0 }}
|
|
<span class="unit-text">万元</span>
|
|
</div>
|
|
</div>
|
|
<el-divider direction="vertical" class="tab-divider" />
|
|
<div>
|
|
<div class="tab-title">电缆装备</div>
|
|
<div class="price-small-text p-df">
|
|
{{ priceData.cable || 0 }}
|
|
<span class="unit-text">万元</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else class="config">
|
|
<div class="tab-title">装备配置率</div>
|
|
<div style="margin-bottom: 35px">
|
|
<span class="price-text config-color">{{ configData.total || 0 }}</span>
|
|
<span class="unit-text">分</span>
|
|
</div>
|
|
<div class="df" style="justify-content: space-between">
|
|
<div>
|
|
<div class="tab-title">线路装备</div>
|
|
<div class="price-small-text config-color">
|
|
{{ configData.line || 0 }}
|
|
<span class="unit-text">分</span>
|
|
</div>
|
|
</div>
|
|
<el-divider direction="vertical" class="tab-divider" />
|
|
<div>
|
|
<div class="tab-title">变电装备</div>
|
|
<div class="price-small-text config-color">
|
|
{{ configData.substation || 0 }}
|
|
<span class="unit-text">分</span>
|
|
</div>
|
|
</div>
|
|
<el-divider direction="vertical" class="tab-divider" />
|
|
<div>
|
|
<div class="tab-title">电缆装备</div>
|
|
<div class="price-small-text config-color">
|
|
{{ configData.cable || 0 }}
|
|
<span class="unit-text">分</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<el-divider direction="vertical" class="v-divider" />
|
|
<div class="item-right">
|
|
<div class="title">
|
|
<div class="title-text">装备状态分析</div>
|
|
</div>
|
|
<div class="chart-wrapper">
|
|
<div ref="chart" class="chart"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<el-divider direction="vertical" class="v-divider" />
|
|
<div class="item">
|
|
<div class="title">
|
|
<div class="title-text">装备数量分析</div>
|
|
<div class="tab" :class="{ active: activeTab2 == 'major' }" @click="handleActiveTab('major')">三大专业</div>
|
|
<div class="tab" :class="{ active: activeTab2 == 'process' }" @click="handleActiveTab('process')">十大工序</div>
|
|
</div>
|
|
<div ref="barChart" class="barChart"></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import * as echarts from 'echarts'
|
|
import {
|
|
getTotalValueApi,
|
|
getConfigurationRateApi,
|
|
getEquipmentStatusApi,
|
|
getThreeMajorApi,
|
|
getTenMajorApi,
|
|
} from '@/api/EquipmentEntryApply'
|
|
|
|
export default {
|
|
name: 'EquAnalysis',
|
|
props: {
|
|
queryParams: {
|
|
type: Object,
|
|
default: {},
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
priceData: {},
|
|
configData: {},
|
|
activeTab1: 1,
|
|
activeTab2: 'major',
|
|
total: 0,
|
|
chartData: [
|
|
{ name: '在库数量', value: 0 },
|
|
{ name: '维修数量', value: 0 },
|
|
{ name: '自用数量', value: 0 },
|
|
{ name: '共享数量', value: 0 },
|
|
{ name: '退役数量', value: 0 },
|
|
],
|
|
chart: null,
|
|
dataMap: {
|
|
major: [],
|
|
process: [],
|
|
},
|
|
barChart: null,
|
|
}
|
|
},
|
|
mounted() {},
|
|
beforeDestroy() {
|
|
window.removeEventListener('resize', this.resizeChart)
|
|
this.chart && this.chart.dispose()
|
|
window.removeEventListener('resize', this.resizeBarChart)
|
|
this.barChart && this.barChart.dispose()
|
|
},
|
|
methods: {
|
|
handleActiveTab(type) {
|
|
if (this.activeTab1 == type || this.activeTab2 == type) return
|
|
if (type == 1 || type == 2) {
|
|
this.activeTab1 = type
|
|
} else {
|
|
this.activeTab2 = type
|
|
this.renderBarChart()
|
|
}
|
|
},
|
|
async init() {
|
|
try {
|
|
console.log('🚀 ~ this.queryParams:', this.queryParams)
|
|
const res = await getTotalValueApi(this.queryParams)
|
|
this.priceData = res.data
|
|
const res2 = await getConfigurationRateApi(this.queryParams)
|
|
this.configData = res2.data
|
|
const res3 = await getEquipmentStatusApi(this.queryParams)
|
|
this.total = res3.data.total
|
|
const fieldMap = [
|
|
{ name: '在库数量', key: 'availableNum' },
|
|
{ name: '维修数量', key: 'repairNum' },
|
|
{ name: '自用数量', key: 'inNum' },
|
|
{ name: '共享数量', key: 'shareNum' },
|
|
{ name: '退役数量', key: 'scrapNum' },
|
|
]
|
|
this.chartData = fieldMap.map((item) => ({
|
|
name: item.name,
|
|
value: res3.data[item.key] || 0,
|
|
}))
|
|
const res4 = await getThreeMajorApi(this.queryParams)
|
|
|
|
if (res4.data && res4.data.length > 0) {
|
|
this.dataMap.major = res4.data.map((item) => ({
|
|
name: item.type,
|
|
value: item.total,
|
|
}))
|
|
} else {
|
|
this.dataMap.major = []
|
|
}
|
|
const res5 = await getTenMajorApi(this.queryParams)
|
|
if (res5.data && res5.data.length > 0) {
|
|
this.dataMap.process = res5.data.map((item) => ({
|
|
name: item.type,
|
|
value: item.total,
|
|
}))
|
|
} else {
|
|
this.dataMap.process = []
|
|
}
|
|
} catch (error) {
|
|
console.log('🚀 ~ error-->装备台账分析:', error)
|
|
} finally {
|
|
this.initChart()
|
|
this.initBarChart()
|
|
window.addEventListener('resize', this.resizeChart)
|
|
window.addEventListener('resize', this.resizeBarChart)
|
|
}
|
|
},
|
|
// 饼图
|
|
resizeChart() {
|
|
this.chart && this.chart.resize()
|
|
},
|
|
initChart() {
|
|
this.chart = echarts.init(this.$refs.chart)
|
|
|
|
const option = {
|
|
tooltip: {
|
|
trigger: 'item',
|
|
formatter: (params) => {
|
|
const percent = ((params.value / this.total) * 100).toFixed(2)
|
|
return `${params.name}<br/>${percent}% / ${params.value}`
|
|
},
|
|
},
|
|
legend: {
|
|
orient: 'vertical',
|
|
right: '5%',
|
|
top: 'center',
|
|
itemWidth: 10,
|
|
itemHeight: 10,
|
|
formatter: (name) => {
|
|
const item = this.chartData.find((i) => i.name === name)
|
|
const percent = item.value > 0 && this.total > 0 ? ((item.value / this.total) * 100).toFixed(2) : '0.00'
|
|
return `${name} ${percent}% / ${item.value}`
|
|
},
|
|
},
|
|
series: [
|
|
{
|
|
type: 'pie',
|
|
radius: ['60%', '80%'],
|
|
center: ['35%', '50%'],
|
|
avoidLabelOverlap: false,
|
|
label: { show: false },
|
|
labelLine: { show: false },
|
|
data: this.chartData,
|
|
},
|
|
],
|
|
graphic: [
|
|
{
|
|
type: 'text',
|
|
left: '27%',
|
|
top: '40%',
|
|
style: {
|
|
text: `${this.total}台`,
|
|
textAlign: 'center',
|
|
fill: '#3F3F3F',
|
|
fontSize: 22,
|
|
fontWeight: 'bold',
|
|
},
|
|
},
|
|
{
|
|
type: 'text',
|
|
left: '29%',
|
|
top: '53%',
|
|
style: {
|
|
text: '装备台账',
|
|
textAlign: 'center',
|
|
fill: '#3F3F3F',
|
|
fontSize: 14,
|
|
},
|
|
},
|
|
],
|
|
color: ['#33C3C8', '#FF6B6B', '#FFA940', '#FADB14', '#597EF7'],
|
|
}
|
|
|
|
this.chart.setOption(option)
|
|
},
|
|
// 柱状图
|
|
resizeBarChart() {
|
|
this.barChart && this.barChart.resize()
|
|
},
|
|
initBarChart() {
|
|
this.barChart = echarts.init(this.$refs.barChart)
|
|
this.renderBarChart()
|
|
},
|
|
renderBarChart() {
|
|
const list = this.dataMap[this.activeTab2]
|
|
const xData = list.map((i) => i.name)
|
|
const yData = list.map((i) => i.value)
|
|
|
|
const option = {
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
axisPointer: {
|
|
type: 'shadow',
|
|
},
|
|
formatter: (params) => {
|
|
const item = params[0]
|
|
return `
|
|
<div>
|
|
<div>${item.name}</div>
|
|
<div>数量:${item.value}</div>
|
|
</div>
|
|
`
|
|
},
|
|
},
|
|
grid: {
|
|
left: 40,
|
|
right: 20,
|
|
top: 30,
|
|
bottom: 50,
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: xData,
|
|
axisTick: { show: false },
|
|
axisLine: { lineStyle: { color: '#E5E5E5' } },
|
|
axisLabel: {
|
|
color: '#666',
|
|
interval: 0,
|
|
},
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
axisLine: { show: false },
|
|
axisTick: { show: false },
|
|
splitLine: {
|
|
lineStyle: {
|
|
type: 'dashed',
|
|
color: '#EAEAEA',
|
|
},
|
|
},
|
|
},
|
|
series: [
|
|
{
|
|
type: 'bar',
|
|
data: yData,
|
|
barWidth: 24,
|
|
itemStyle: {
|
|
borderRadius: [12, 12, 0, 0],
|
|
color: (params) => {
|
|
const colors = [
|
|
['#5DA9FF', '#8EC5FF'],
|
|
['#4ED6C8', '#7BE7D7'],
|
|
['#FDBA4F', '#FFD78A'],
|
|
]
|
|
return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: colors[params.dataIndex % 3][0] },
|
|
{ offset: 1, color: colors[params.dataIndex % 3][1] },
|
|
])
|
|
},
|
|
},
|
|
},
|
|
],
|
|
}
|
|
|
|
this.barChart.setOption(option, true)
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.warp {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
.item {
|
|
width: 50%;
|
|
}
|
|
.item-right {
|
|
width: 100%;
|
|
}
|
|
}
|
|
.v-divider {
|
|
height: 16rem;
|
|
}
|
|
.df {
|
|
display: flex;
|
|
}
|
|
.title {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 16px;
|
|
color: #3f3f3f;
|
|
line-height: 24px;
|
|
margin-bottom: 20px;
|
|
.title-text {
|
|
font-weight: bold;
|
|
}
|
|
.tab {
|
|
margin-left: 20px;
|
|
font-weight: 400;
|
|
cursor: pointer;
|
|
}
|
|
.active {
|
|
color: #2cbab2;
|
|
border-bottom: 2px solid #2cbab2;
|
|
}
|
|
}
|
|
.price,
|
|
.config {
|
|
width: 260px;
|
|
height: 206px;
|
|
padding: 10px;
|
|
}
|
|
.price {
|
|
background: url('~@/assets/images/equ-price.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
.config {
|
|
background: url('~@/assets/images/equ-config.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
.tab-title {
|
|
font-weight: 400;
|
|
font-size: 14px;
|
|
color: #3f3f3f;
|
|
line-height: 22px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.price-text {
|
|
font-family: 'OpenSans-BoldItalic';
|
|
font-weight: normal;
|
|
font-size: 30px;
|
|
color: #ffab29;
|
|
line-height: 24px;
|
|
}
|
|
.price-small-text {
|
|
font-family: 'OpenSans-BoldItalic';
|
|
font-weight: normal;
|
|
font-size: 18px;
|
|
color: #ffab29;
|
|
line-height: 24px;
|
|
}
|
|
.p-df {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.config-color {
|
|
color: #2cbab2;
|
|
}
|
|
.unit-text {
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #808080;
|
|
line-height: 18px;
|
|
}
|
|
.tab-divider {
|
|
margin-top: 5px;
|
|
height: 70px;
|
|
background-color: #fff;
|
|
}
|
|
|
|
// 饼图
|
|
.chart-wrapper {
|
|
width: 80%;
|
|
height: 220px;
|
|
}
|
|
|
|
.chart {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
// 柱状图
|
|
.barChart {
|
|
width: 90%;
|
|
height: 220px;
|
|
}
|
|
</style>
|