装备配置率
This commit is contained in:
parent
70d537e7ad
commit
a93e385a16
|
|
@ -2,63 +2,44 @@
|
|||
<div class="app-container">
|
||||
<!-- 图表卡片:纯div布局,保留核心ref和样式类 -->
|
||||
<div class="chart-card">
|
||||
<div class="chart-container" ref="chartContainer">
|
||||
<div class="tabs">
|
||||
<div class="tab-item" :class="{ active: activeTab == 1 }" @click="handleTab(1)">总配置率</div>
|
||||
<div class="tab-item" :class="{ active: activeTab == 2 }" @click="handleTab(2)">分项配置率统计</div>
|
||||
</div>
|
||||
<div class="chart-container" v-show="activeTab === 1">
|
||||
<div ref="totalChartRef" class="echarts echarts-box"></div>
|
||||
</div>
|
||||
|
||||
<div class="chart-container" v-show="activeTab === 2">
|
||||
<div ref="chartRef" class="echarts echarts-box"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
<div class="table-header">
|
||||
<el-button
|
||||
type="primary"
|
||||
style="float: right"
|
||||
icon="el-icon-download"
|
||||
@click="exportTableData"
|
||||
>
|
||||
<el-button type="primary" style="float: right" icon="el-icon-download" @click="exportTableData">
|
||||
导出数据
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
border
|
||||
stripe
|
||||
:fit="true"
|
||||
class="stats-table"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<el-table-column label="序号" type="index" width="60" align="center"/>
|
||||
<el-table-column label="公司" prop="deptName" min-width="150" align="center"/>
|
||||
<el-table-column
|
||||
label="线路设备配置率"
|
||||
prop="lineNum"
|
||||
min-width="120"
|
||||
align="center"
|
||||
>
|
||||
<el-table :data="tableData" border stripe :fit="true" class="stats-table" v-loading="tableLoading">
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="公司名称" prop="deptName" min-width="150" align="center" />
|
||||
<el-table-column label="线路设备配置率" prop="lineNum" min-width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span class="link" @click="handleCellClick(scope.row.deptId, 0)">{{ scope.row.lineNum }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="电缆设备配置率"
|
||||
prop="cableNum"
|
||||
min-width="120"
|
||||
align="center"
|
||||
>
|
||||
<el-table-column label="电缆设备配置率" prop="cableNum" min-width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span class="link" @click="handleCellClick(scope.row.deptId, 2)">{{ scope.row.cableNum }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="变电设备配置率"
|
||||
prop="substationNum"
|
||||
min-width="120"
|
||||
align="center"
|
||||
>
|
||||
<el-table-column label="变电设备配置率" prop="substationNum" min-width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span class="link" @click="handleCellClick(scope.row.deptId, 1)">{{ scope.row.substationNum }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总配置率" prop="num" min-width="100" align="center"/>
|
||||
<el-table-column label="总配置率" prop="num" min-width="100" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
|
|
@ -70,28 +51,21 @@
|
|||
top="20px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-table
|
||||
:data="detailTableData"
|
||||
border
|
||||
stripe
|
||||
|
||||
v-loading="detailTableLoading"
|
||||
max-height="600px"
|
||||
>
|
||||
<el-table :data="detailTableData" border stripe v-loading="detailTableLoading" max-height="600px">
|
||||
<!-- 明细表格列(匹配用户提供的表格结构) -->
|
||||
<el-table-column label="序号" type="index" width="60" align="center"/>
|
||||
<el-table-column label="装备名称" prop="typeName" min-width="120" align="center"/>
|
||||
<el-table-column label="电压等级" prop="vol" min-width="100" align="center"/>
|
||||
<el-table-column label="地理特征" prop="type" min-width="100" align="center"/>
|
||||
<el-table-column label="配置标准(台)" prop="configValue" min-width="100" align="center"/>
|
||||
<el-table-column label="装备种类" prop="jijuType" min-width="100" align="center"/>
|
||||
<el-table-column label="配置说明" prop="configDescription" min-width="120" align="center"/>
|
||||
<el-table-column label="装备配置率赋值" prop="configRate" min-width="120" align="center"/>
|
||||
<el-table-column label="自有装配数量" prop="ownNum" min-width="120" align="center"/>
|
||||
<el-table-column label="共享装备数量" prop="shareNum" min-width="120" align="center"/>
|
||||
<el-table-column label="外租装备数量" prop="rentOutNum" min-width="120" align="center"/>
|
||||
<el-table-column label="装备实际配置率" prop="baseAddNum" min-width="120" align="center"/>
|
||||
<el-table-column label="特殊装备配备原因" prop="remark" min-width="150" align="center"/>
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="装备名称" prop="typeName" min-width="120" align="center" />
|
||||
<el-table-column label="电压等级" prop="vol" min-width="100" align="center" />
|
||||
<el-table-column label="地理特征" prop="type" min-width="100" align="center" />
|
||||
<el-table-column label="配置标准(台)" prop="configValue" min-width="100" align="center" />
|
||||
<el-table-column label="装备种类" prop="jijuType" min-width="100" align="center" />
|
||||
<el-table-column label="配置说明" prop="configDescription" min-width="120" align="center" />
|
||||
<el-table-column label="装备配置率赋值" prop="configRate" min-width="120" align="center" />
|
||||
<el-table-column label="自有装配数量" prop="ownNum" min-width="120" align="center" />
|
||||
<el-table-column label="共享装备数量" prop="shareNum" min-width="120" align="center" />
|
||||
<el-table-column label="外租装备数量" prop="rentOutNum" min-width="120" align="center" />
|
||||
<el-table-column label="装备实际配置率" prop="baseAddNum" min-width="120" align="center" />
|
||||
<el-table-column label="特殊装备配备原因" prop="remark" min-width="150" align="center" />
|
||||
</el-table>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
|
|
@ -112,117 +86,14 @@ export default {
|
|||
searchForm: {
|
||||
companyName: '',
|
||||
voltageLevel: '',
|
||||
terrainType: ''
|
||||
terrainType: '',
|
||||
},
|
||||
tableData: [],
|
||||
tableLoading: false,
|
||||
tableHeight: 'auto',
|
||||
activeTab: 1,
|
||||
chartInstance: null,
|
||||
chartOption: {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: { type: 'shadow' },
|
||||
formatter: function(params) {
|
||||
let res = params[0].name
|
||||
params.forEach((item) => {
|
||||
const nameMap = {
|
||||
xianlu: '线路配置率',
|
||||
dianlan: '电缆配置率',
|
||||
biandian: '变电配置率'
|
||||
}
|
||||
res += `<br/>${nameMap[item.seriesName] || item.seriesName}:${item.value}`
|
||||
})
|
||||
return res
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['xianlu', 'dianlan', 'biandian'],
|
||||
formatter: function(name) {
|
||||
const nameMap = { xianlu: '线路', dianlan: '电缆', biandian: '变电' }
|
||||
return nameMap[name] || name
|
||||
},
|
||||
itemGap: 20,
|
||||
bottom: 15, // 核心1:改为数值(px),预留图例+间距空间,值越大间距越宽
|
||||
left: 'center',
|
||||
orient: 'horizontal'
|
||||
},
|
||||
// 核心2:调整grid.bottom为15%(字符串格式),释放底部空间,避免圆角被挤压
|
||||
grid: { left: '3%', right: '4%', bottom: '15%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
axisLabel: {
|
||||
rotate: 0,
|
||||
fontSize: 12,
|
||||
interval: 0,
|
||||
width: 80,
|
||||
lineHeight: 20,
|
||||
align: 'center',
|
||||
formatter: function(value) {
|
||||
let str = ''
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
str += value[i]
|
||||
if ((i + 1) % 6 === 0) str += '\n'
|
||||
}
|
||||
return str
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: { type: 'value', axisLabel: { formatter: '{value}' } },
|
||||
series: [
|
||||
{
|
||||
name: 'xianlu',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
barBorderRadius: [10, 10, 0, 0], // 圆角正常生效
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0, y: 0,
|
||||
x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#46A8FF' },
|
||||
{ offset: 1, color: '#7BC2FF' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'dianlan',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
barBorderRadius: [10, 10, 0, 0], // 圆角正常生效
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0, y: 0,
|
||||
x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#5EDDCA' },
|
||||
{ offset: 1, color: '#32E1C6' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'biandian',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
barBorderRadius: [10, 10, 0, 0], // 圆角正常生效
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0, y: 0,
|
||||
x2: 0, y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#fdbe56' },
|
||||
{ offset: 1, color: '#FFC468' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
resizeTimer: null,
|
||||
// 新增:弹窗相关数据
|
||||
detailDialogVisible: false,
|
||||
|
|
@ -230,15 +101,24 @@ export default {
|
|||
detailTableLoading: false,
|
||||
// 记录当前点击的行数据和列类型
|
||||
currentClickRow: null,
|
||||
currentClickType: '' // line(线路)/cable(电缆)/substation(变电)
|
||||
currentClickType: '', // line(线路)/cable(电缆)/substation(变电)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(async() => {
|
||||
this.$nextTick(async () => {
|
||||
await this.initPage()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleTab(tab) {
|
||||
if (this.activeTab === tab) return
|
||||
this.activeTab = tab
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
this.updateChartData(this.tableData)
|
||||
})
|
||||
},
|
||||
// 初始化页面数据:请求成功后再初始化图表
|
||||
async initPage() {
|
||||
this.tableLoading = true
|
||||
|
|
@ -262,58 +142,169 @@ export default {
|
|||
|
||||
// 初始化ECharts:增加DOM宽高校验+兜底
|
||||
initChart() {
|
||||
const chartDom = this.$refs.chartRef
|
||||
if (!chartDom || this.chartInstance) return
|
||||
|
||||
const clientWidth = chartDom.clientWidth || 600
|
||||
const clientHeight = chartDom.clientHeight || 300
|
||||
if (clientWidth === 0 || clientHeight === 0) {
|
||||
chartDom.style.width = '100%'
|
||||
chartDom.style.height = '450px'
|
||||
}
|
||||
|
||||
if (this.chartInstance) {
|
||||
this.chartInstance.dispose()
|
||||
this.chartInstance = null
|
||||
}
|
||||
|
||||
this.chartInstance = echarts.init(chartDom)
|
||||
this.chartInstance.setOption(this.chartOption, true)
|
||||
const dom = this.activeTab === 1 ? this.$refs.totalChartRef : this.$refs.chartRef
|
||||
|
||||
if (!dom) return
|
||||
|
||||
this.chartInstance = echarts.init(dom)
|
||||
|
||||
this.chartInstance.setOption(this.activeTab === 1 ? this.getTotalOption() : this.getSubOption(), true)
|
||||
},
|
||||
|
||||
// 更新图表数据:数据同步后强制重绘
|
||||
updateChartData(data) {
|
||||
if (!this.chartInstance || !Array.isArray(data) || data.length === 0) return
|
||||
console.log('🚀 ~ data:', data)
|
||||
if (!this.chartInstance || !data.length) return
|
||||
|
||||
const xAxisData = []
|
||||
const xianluData = []
|
||||
const dianlanData = []
|
||||
const biandianData = []
|
||||
const xAxis = []
|
||||
const total = []
|
||||
const xianlu = []
|
||||
const dianlan = []
|
||||
const biandian = []
|
||||
|
||||
data.forEach((item) => {
|
||||
xAxisData.push(item.deptName || '')
|
||||
xianluData.push(item.lineNum || 0)
|
||||
dianlanData.push(item.cableNum || 0)
|
||||
biandianData.push(item.substationNum || 0)
|
||||
xAxis.push(item.deptName)
|
||||
total.push(item.num)
|
||||
xianlu.push(item.lineNum)
|
||||
dianlan.push(item.cableNum)
|
||||
biandian.push(item.substationNum)
|
||||
})
|
||||
|
||||
const allData = [...xianluData, ...dianlanData, ...biandianData]
|
||||
const maxValue = Math.max(...allData)
|
||||
const dynamicYmax = Math.ceil(maxValue * 1.1)
|
||||
|
||||
this.chartInstance.setOption({
|
||||
xAxis: { data: xAxisData },
|
||||
yAxis: { max: dynamicYmax },
|
||||
series: [
|
||||
{ name: 'xianlu', data: xianluData },
|
||||
{ name: 'dianlan', data: dianlanData },
|
||||
{ name: 'biandian', data: biandianData }
|
||||
]
|
||||
})
|
||||
if (this.activeTab === 1) {
|
||||
this.chartInstance.setOption({
|
||||
xAxis: { data: xAxis },
|
||||
series: [{ name: '总配置率', data: total }],
|
||||
})
|
||||
} else {
|
||||
this.chartInstance.setOption({
|
||||
xAxis: { data: xAxis },
|
||||
series: [
|
||||
{ name: '线路配置率', data: xianlu },
|
||||
{ name: '电缆配置率', data: dianlan },
|
||||
{ name: '变电配置率', data: biandian },
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
this.chartInstance.resize()
|
||||
},
|
||||
|
||||
/** Tab1 配置 */
|
||||
getTotalOption() {
|
||||
return {
|
||||
tooltip: { trigger: 'axis' },
|
||||
grid: { left: '3%', right: '4%', bottom: '15%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
axisLabel: {
|
||||
interval: 0, // 必须
|
||||
formatter(value) {
|
||||
const max = 6 // 每行最多 6 个字
|
||||
let res = ''
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
res += value[i]
|
||||
if ((i + 1) % max === 0 && i !== value.length - 1) {
|
||||
res += '\n'
|
||||
}
|
||||
}
|
||||
return res
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: { type: 'value' },
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
barWidth: 18,
|
||||
itemStyle: {
|
||||
borderRadius: [50, 50, 0, 0],
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#5EDDCA' },
|
||||
{ offset: 1, color: '#32E1C6' },
|
||||
],
|
||||
},
|
||||
},
|
||||
data: [],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
/** Tab2 配置 */
|
||||
getSubOption() {
|
||||
return {
|
||||
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
||||
legend: {
|
||||
right: 20,
|
||||
top: 10,
|
||||
data: ['xianlu', 'dianlan', 'biandian'],
|
||||
formatter(name) {
|
||||
return { xianlu: '线路', dianlan: '电缆', biandian: '变电' }[name]
|
||||
},
|
||||
},
|
||||
grid: { left: '3%', right: '4%', bottom: '15%', containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
axisLabel: {
|
||||
interval: 0, // 必须
|
||||
formatter(value) {
|
||||
const max = 6 // 每行最多 6 个字
|
||||
let res = ''
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
res += value[i]
|
||||
if ((i + 1) % max === 0 && i !== value.length - 1) {
|
||||
res += '\n'
|
||||
}
|
||||
}
|
||||
return res
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: { type: 'value' },
|
||||
series: [
|
||||
this.barSeries('xianlu', ['#46A8FF', '#7BC2FF']),
|
||||
this.barSeries('dianlan', ['#5EDDCA', '#32E1C6']),
|
||||
this.barSeries('biandian', ['#FDBE56', '#FFC468']),
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
barSeries(name, colors) {
|
||||
return {
|
||||
name,
|
||||
type: 'bar',
|
||||
barWidth: 18,
|
||||
itemStyle: {
|
||||
borderRadius: [50, 50, 0, 0],
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: colors[0] },
|
||||
{ offset: 1, color: colors[1] },
|
||||
],
|
||||
},
|
||||
},
|
||||
data: [],
|
||||
}
|
||||
},
|
||||
|
||||
// 导出数据:保持原有逻辑,增加loading
|
||||
async exportTableData() {
|
||||
this.$loading({ text: '正在导出,请稍候...' })
|
||||
|
|
@ -344,7 +335,7 @@ export default {
|
|||
// 构造请求参数(公司名称+配置类型+搜索条件)
|
||||
const params = {
|
||||
deptId: deptId,
|
||||
configType: configType
|
||||
configType: configType,
|
||||
}
|
||||
const res = await getConfigurationDetails(params)
|
||||
if (res.code === 200) {
|
||||
|
|
@ -357,8 +348,8 @@ export default {
|
|||
} finally {
|
||||
this.detailTableLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -431,11 +422,28 @@ export default {
|
|||
}
|
||||
|
||||
.link {
|
||||
color: #2CBAB2;
|
||||
color: #2cbab2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: #23b8b1;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.tab-item {
|
||||
line-height: 24px;
|
||||
margin-right: 16px;
|
||||
padding: 6px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
&.active {
|
||||
color: #2cbab2;
|
||||
border-bottom: 2px solid #2cbab2;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue