integration/src/views/regulatoryPlatForm/index.vue

481 lines
12 KiB
Vue

<template>
<div class="main-content">
<div class="todo-and-card">
<!-- 待办事项总览 -->
<div class="todo-header">
<span class="title">待办事项总览</span>
<span class="tag normal">正常 <span class="color">{{ statusData.normal }}</span></span>
<span class="tag overdue">超期 <span class="color">{{ statusData.overdue }}</span></span>
<span class="tag soon-overdue">即将超期 <span class="color">{{ statusData.soonOverdue }}</span></span>
</div>
<!-- 统计卡片 -->
<div class="card-group">
<div class="stat-card" @click="goToTodoList('all')">
<div class="icon">
<svg-icon icon-class="d1" />
</div>
<div class="info">
<div class="card-icon">我的待办</div>
<div class="card-num">{{ cardData.myTodo }}</div>
</div>
</div>
<div class="stat-card" @click="goToTodoList('abnormal')">
<div class="icon">
<svg-icon icon-class="d2" />
</div>
<div class="info">
<div class="card-icon">经营异常(列入)</div>
<div class="card-num">{{ cardData.abnormal }}</div>
</div>
</div>
<div class="stat-card" @click="goToTodoList('illegal')">
<div class="icon">
<svg-icon icon-class="d3" />
</div>
<div class="info">
<div class="card-icon">严重违法失信</div>
<div class="card-num">{{ cardData.illegal }}</div>
</div>
</div>
<div class="stat-card" @click="goToTodoList('repair')">
<div class="icon">
<svg-icon icon-class="d1" />
</div>
<div class="info">
<div class="card-icon">信用修复</div>
<div class="card-num">{{ cardData.creditRepair }}</div>
</div>
</div>
<div class="stat-card" @click="goToTodoList('correct')">
<div class="icon">
<svg-icon icon-class="d2" />
</div>
<div class="info">
<div class="card-icon">数据勘误</div>
<div class="card-num">{{ cardData.dataCorrection }}</div>
</div>
</div>
</div>
</div>
<!-- 图表区域 -->
<div class="chart-container">
<!-- 柱状图 -->
<div class="chart-item bar-chart">
<div class="chart-title">各市经营异常主体数量对比</div>
<div id="barChart" class="chart-box" />
</div>
<!-- 环形图 -->
<div class="chart-item pie-chart">
<div class="chart-title">经营异常主体类型分布</div>
<div id="pieChart" class="chart-box" />
</div>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts'
import { taskUnionPageStatistic, indexPageStatistic } from '@/api/regulatoryPlatForm'
export default {
name: 'BusinessAbnormalDashboard',
data() {
return {
barChart: null,
pieChart: null,
cardData: {
myTodo: 0,
abnormal: 0,
illegal: 0,
creditRepair: 0,
dataCorrection: 0
},
statusData: {
normal: 0,
overdue: 0,
soonOverdue: 0
}
}
},
mounted() {
this.initBarChart()
this.initPieChart()
this.getCardData()
this.getStatusData()
// 监听窗口大小变化,自适应图表
window.addEventListener('resize', () => {
this.barChart.resize()
this.pieChart.resize()
})
},
beforeDestroy() {
window.removeEventListener('resize', () => {
this.barChart.resize()
this.pieChart.resize()
})
},
methods: {
// 初始化柱状图
initBarChart() {
const chartDom = document.getElementById('barChart')
this.barChart = echarts.init(chartDom)
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
containLabel: true
},
dataZoom: [
{
type: 'slider',
show: true,
xAxisIndex: [0],
bottom: 5,
height: 20,
startValue: 0,
endValue: 5
}
],
xAxis: {
type: 'category',
data: [],
axisLabel: {
rotate: 0,
fontSize: 12,
interval: 0,
formatter: function(value) {
// 每6个字符换行
let result = ''
for (let i = 0; i < value.length; i += 6) {
result += value.substring(i, i + 6) + '\n'
}
return result.trim()
}
}
},
yAxis: {
type: 'value',
name: '数量(家)',
nameTextStyle: { fontSize: 12 }
},
series: [
{
data: [],
type: 'bar',
itemStyle: {
color: function(params) {
const colors = ['#66b1ff', '#409eff', '#337ecc', '#2662a6', '#194680', '#0c2a5a']
return colors[params.dataIndex % colors.length]
}
}
}
]
}
this.barChart.setOption(option)
},
// 初始化环形图
initPieChart() {
const chartDom = document.getElementById('pieChart')
this.pieChart = echarts.init(chartDom)
const option = {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
right: 10,
top: 'center',
textStyle: { fontSize: 12 }
},
series: [
{
name: '主体类型',
type: 'pie',
radius: ['40%', '70%'],
center: ['35%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 16,
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [],
color: ['#409eff', '#66b1ff', '#a0cfff']
}
]
}
this.pieChart.setOption(option)
},
// 获取卡片数据
async getCardData() {
try {
const userId = this.$store.state.user.keys
const res = await taskUnionPageStatistic({
customParamMap: {
userId: userId,
type: '',
currentNodeOrBizStatus: ''
}
})
if (res && res.data) {
this.cardData.myTodo = res.data.allnum || 0
this.cardData.abnormal = res.data.abnormalnum || 0
this.cardData.illegal = res.data.illegalnum || 0
this.cardData.creditRepair = res.data.repairnum || 0
this.cardData.dataCorrection = res.data.correctnum || 0
}
} catch (error) {
console.error('获取待办数据失败:', error)
}
},
// 获取待办总览状态数据(正常、超期、即将超期)
async getStatusData() {
try {
const userId = this.$store.state.user.keys
const res = await indexPageStatistic({
customParamMap: {
userId: userId,
type: '',
currentNodeOrBizStatus: ''
}
})
if (res && res.data) {
// 更新状态数据
const repairStatistic = res.data.repairStatistic || {}
this.statusData.normal = repairStatistic.normalnum || 0
this.statusData.overdue = repairStatistic.expirednum || 0
this.statusData.soonOverdue = repairStatistic.aboutExpirenum || 0
// 更新柱状图数据
const abnEntLocStatistic = res.data.abnEntLocStatistic || []
if (abnEntLocStatistic.length > 0) {
const xAxisData = abnEntLocStatistic.map(item => item.orgName)
const seriesData = abnEntLocStatistic.map(item => item.abnNum)
this.updateBarChart(xAxisData, seriesData)
}
// 更新饼状图数据
const entTypeStatistic = res.data.entTypeStatistic || {}
const pieData = [
{ value: entTypeStatistic.enterpriseNum || 0, name: '企业' },
{ value: entTypeStatistic.individualNum || 0, name: '个体工商户' },
{ value: entTypeStatistic.coopNum || 0, name: '农民专业合作社' }
]
this.updatePieChart(pieData)
}
} catch (error) {
console.error('获取待办总览状态数据失败:', error)
}
},
// 更新柱状图数据
updateBarChart(xAxisData, seriesData) {
const colors = ['#66b1ff', '#409eff', '#337ecc', '#2662a6', '#194680', '#0c2a5a']
this.barChart.setOption({
xAxis: {
data: xAxisData
},
series: [{
data: seriesData,
itemStyle: {
color: function(params) {
return colors[params.dataIndex % colors.length]
}
}
}]
})
},
// 更新饼状图数据
updatePieChart(pieData) {
this.pieChart.setOption({
series: [{
data: pieData
}]
})
},
// 跳转到我的待办对应 tab
goToTodoList(activeName) {
this.$router.push({
path: '/toDoList',
query: { activeName, activeNamet: Date.now() }
})
}
}
}
</script>
<style lang="scss" scoped>
// 右侧主内容
.main-content {
flex: 1;
padding: 0 20px 20px 20px;
overflow-y: auto;
.todo-and-card{
background: #FFFFFF;
box-shadow: 0px 2px 6px 0px #DDDDDD;
padding: 16px 13px;
margin-bottom: 20px;
// 待办事项头部
.todo-header {
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 15px;
padding-left: 15px;
.title {
font-size: 18px;
font-weight: bold;
color: #333;
position: relative;
margin-right: 94px;
&::before{
content: "";
position: absolute;
left: -8px;
top: 50%;
transform: translateY(-50%);
width: 2px;
height: 14px;
border-radius: 1px;
background: #3296FA;
}
}
.tag {
padding: 4px 8px;
border-radius: 12px;
font-size: 14px;
.color{
margin-left: 14px;
}
&.normal {
.color{
color: #409eff;
}
}
&.overdue {
.color{
color: #f56c6c;
}
}
&.soon-overdue {
.color{
color: #e6a23c;
}
}
}
}
// 统计卡片组
.card-group {
display: flex;
gap: 20px;
flex-wrap: wrap;
.stat-card {
background: #fff;
border-radius: 8px;
padding: 35px 30px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}
.icon{
background: #EBF5FF;
border-radius: 65px;
padding: 4px;
border: 4px solid #FFFFFF;
box-shadow: 0px 2px 8px 0px rgba(50, 150, 250, 0.32);
.svg-icon{
width: 60px;
height: 60px;
}
}
.info{
margin-left: 20px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
.card-icon {
font-size: 16px;
color: #666;
margin-bottom: 10px;
}
.card-num {
font-size: 32px;
font-weight: bold;
color: #409eff;
}
}
}
}
}
// 图表容器
.chart-container {
display: flex;
gap: 20px;
height: 400px;
.chart-item {
background: #fff;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
&.bar-chart {
flex: 3;
}
&.pie-chart {
flex: 1;
}
.chart-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.chart-box {
width: 100%;
height: calc(100% - 30px);
}
}
}
}
</style>