|
@@ -2,29 +2,26 @@
|
|
|
<div class="assess-page">
|
|
<div class="assess-page">
|
|
|
<h1 class="page-title">考核评估</h1>
|
|
<h1 class="page-title">考核评估</h1>
|
|
|
|
|
|
|
|
- <el-tabs v-model="activeTab" type="border-card" class="assess-tabs">
|
|
|
|
|
- <el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.label" :name="tab.name">
|
|
|
|
|
- <div class="tab-card">
|
|
|
|
|
- <div class="big-number">
|
|
|
|
|
- <span class="num">{{ tab.total }}</span>
|
|
|
|
|
- <span class="unit">{{ tab.unit }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="sub-title">{{ tab.desc }}</div>
|
|
|
|
|
- <template v-if="tab.rows">
|
|
|
|
|
- <div class="divider"><span>其中</span></div>
|
|
|
|
|
- <table class="stat-table">
|
|
|
|
|
- <tr v-for="(r,i) in tab.rows" :key="i" :class="{ stripe: i%2===0 }">
|
|
|
|
|
- <td>{{ r.label }}</td>
|
|
|
|
|
- <td>{{ r.value }}</td>
|
|
|
|
|
- </tr>
|
|
|
|
|
- </table>
|
|
|
|
|
- </template>
|
|
|
|
|
- </div>
|
|
|
|
|
- </el-tab-pane>
|
|
|
|
|
- </el-tabs>
|
|
|
|
|
|
|
+ <!-- 5 个统计卡片 -->
|
|
|
|
|
+ <div class="stat-cards">
|
|
|
|
|
+ <div class="stat-card" v-for="tab in tabs" :key="tab.name" :class="{ active: activeStat === tab.name }" @click="activeStat = tab.name">
|
|
|
|
|
+ <div class="stat-num">{{ tab.total }}<span class="stat-unit">{{ tab.unit }}</span></div>
|
|
|
|
|
+ <div class="stat-label">{{ tab.label }}</div>
|
|
|
|
|
+ <div class="stat-desc">{{ tab.desc }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 选中卡片的分级表格 -->
|
|
|
|
|
+ <el-card shadow="never" class="detail-card" v-if="activeRows">
|
|
|
|
|
+ <template #header>{{ activeStatLabel }} 分级统计</template>
|
|
|
|
|
+ <el-table :data="activeRows" border size="small" style="max-width:500px">
|
|
|
|
|
+ <el-table-column prop="label" label="级别" width="100" />
|
|
|
|
|
+ <el-table-column prop="value" label="数量" />
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </el-card>
|
|
|
|
|
|
|
|
- <!-- 中期评估定量赋分结果 -->
|
|
|
|
|
- <el-card shadow="never" class="score-card" style="margin-bottom:16px">
|
|
|
|
|
|
|
+ <!-- 中期评估图表 -->
|
|
|
|
|
+ <el-card shadow="never" class="chart-card">
|
|
|
<template #header>中期评估定量赋分结果</template>
|
|
<template #header>中期评估定量赋分结果</template>
|
|
|
<div class="chart-row">
|
|
<div class="chart-row">
|
|
|
<div ref="scoreMap" class="chart-half"></div>
|
|
<div ref="scoreMap" class="chart-half"></div>
|
|
@@ -35,188 +32,79 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import {nextTick, onMounted, ref} from 'vue'
|
|
|
|
|
|
|
+import {computed, nextTick, onMounted, ref} from 'vue'
|
|
|
import * as echarts from 'echarts'
|
|
import * as echarts from 'echarts'
|
|
|
import chinaGeo from '@/assets/geoData/china_xh.json'
|
|
import chinaGeo from '@/assets/geoData/china_xh.json'
|
|
|
|
|
|
|
|
-const activeTab = ref('plan')
|
|
|
|
|
|
|
+const activeStat = ref('plan')
|
|
|
|
|
|
|
|
const tabs = [
|
|
const tabs = [
|
|
|
- {
|
|
|
|
|
- name: 'plan', label: '工作方案', total: 44107, unit: '份', desc: '省、市、县、乡四级共正式印发',
|
|
|
|
|
- rows: [{label: '省级', value: 31}, {label: '市级', value: 359}, {label: '县级', value: 3244}, {
|
|
|
|
|
- label: '乡级',
|
|
|
|
|
- value: 40472
|
|
|
|
|
- }]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- name: 'chief', label: '河长湖长', total: 947974, unit: '名', desc: '设立了省、市、县、乡、村五级河长',
|
|
|
|
|
- rows: [{label: '省级', value: 336}, {label: '市级', value: 5435}, {label: '县级', value: 51935}, {
|
|
|
|
|
- label: '乡级',
|
|
|
|
|
- value: 262966
|
|
|
|
|
- }, {label: '村级', value: 627302}]
|
|
|
|
|
- },
|
|
|
|
|
- {name: 'office', label: '河长办', total: 13571, unit: '人', desc: '河长制办公室人员情况', rows: null},
|
|
|
|
|
- {name: 'signboard', label: '公示牌', total: 680000, unit: '个', desc: '河长公示牌统计', rows: null},
|
|
|
|
|
- {
|
|
|
|
|
- name: 'rule', label: '出台规定制度', total: 6863, unit: '项', desc: '出台规定制度统计',
|
|
|
|
|
- rows: [{label: '省级', value: 31}, {label: '市级', value: 245}, {label: '县级', value: 2951}, {
|
|
|
|
|
- label: '乡级',
|
|
|
|
|
- value: 3636
|
|
|
|
|
- }]
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ {name:'plan',label:'工作方案', total:44107,unit:'份',desc:'省、市、县、乡四级共正式印发',
|
|
|
|
|
+ rows:[{label:'省级',value:31},{label:'市级',value:359},{label:'县级',value:3244},{label:'乡级',value:40472}]},
|
|
|
|
|
+ {name:'chief',label:'河长湖长', total:947974,unit:'名',desc:'设立了省、市、县、乡、村五级河长',
|
|
|
|
|
+ rows:[{label:'省级',value:336},{label:'市级',value:5435},{label:'县级',value:51935},{label:'乡级',value:262966},{label:'村级',value:627302}]},
|
|
|
|
|
+ {name:'office',label:'河长办', total:13571,unit:'人',desc:'河长制办公室人员情况',rows:null},
|
|
|
|
|
+ {name:'signboard',label:'公示牌', total:680000,unit:'个',desc:'河长公示牌统计',rows:null},
|
|
|
|
|
+ {name:'rule',label:'出台规定制度', total:6863,unit:'项',desc:'出台规定制度统计',
|
|
|
|
|
+ rows:[{label:'省级',value:31},{label:'市级',value:245},{label:'县级',value:2951},{label:'乡级',value:3636}]},
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
+const activeRows = computed(() => tabs.find(t=>t.name===activeStat.value)?.rows || null)
|
|
|
|
|
+const activeStatLabel = computed(() => tabs.find(t=>t.name===activeStat.value)?.label || '')
|
|
|
|
|
+
|
|
|
const scoreMap = ref(null), provinceBar = ref(null)
|
|
const scoreMap = ref(null), provinceBar = ref(null)
|
|
|
echarts.registerMap('taihu', chinaGeo)
|
|
echarts.registerMap('taihu', chinaGeo)
|
|
|
|
|
|
|
|
-// 太湖流域5省(GeoJSON properties.name = "江苏省" 等)
|
|
|
|
|
const provinceData = [
|
|
const provinceData = [
|
|
|
- {name:'江苏省',total:99.95},{name:'上海市',total:99},{name:'浙江省',total:98.95},
|
|
|
|
|
- {name:'福建省',total:99},{name:'安徽省',total:99},
|
|
|
|
|
|
|
+ {name:'江苏省',total:99.95},{name:'上海市',total:99},{name:'浙江省',total:98.95},{name:'福建省',total:99},{name:'安徽省',total:99},
|
|
|
].sort((a,b)=>b.total-a.total)
|
|
].sort((a,b)=>b.total-a.total)
|
|
|
|
|
|
|
|
-const initCharts = () => {
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- // 地图
|
|
|
|
|
- if (scoreMap.value) {
|
|
|
|
|
- const c0 = echarts.init(scoreMap.value)
|
|
|
|
|
- c0.setOption({
|
|
|
|
|
- title: { text: '太湖流域各省总分分布', left:'center', textStyle:{fontSize:14} },
|
|
|
|
|
- tooltip: { trigger:'item', formatter: (p)=>`${p.name}: ${p.value} 分` },
|
|
|
|
|
- visualMap: { min:94, max:100, left:'left', bottom:10, text:['高','低'], inRange:{color:['#e0f3f8','#abd9e9','#74add1','#4575b4','#313695']} },
|
|
|
|
|
- series: [{ type:'map', map:'taihu', nameProperty:'name', roam:false, label:{show:true,fontSize:12}, data: provinceData.map(d=>({name:d.name,value:d.total})) }]
|
|
|
|
|
- })
|
|
|
|
|
- window.addEventListener('resize', ()=>c0.resize())
|
|
|
|
|
- }
|
|
|
|
|
- // 柱状图
|
|
|
|
|
- if (provinceBar.value) {
|
|
|
|
|
- const c = echarts.init(provinceBar.value)
|
|
|
|
|
- c.setOption({
|
|
|
|
|
- title: {text:'太湖流域各省总分排名', left:'center', textStyle:{fontSize:14}},
|
|
|
|
|
- grid: {left:60,right:40,top:40,bottom:20},
|
|
|
|
|
- yAxis: {type:'category', data:provinceData.map(d=>d.name.replace('省','').replace('市','')), inverse:true},
|
|
|
|
|
- xAxis: {type:'value', name:'分', min:94, max:100},
|
|
|
|
|
- series: [{type:'bar', data:provinceData.map(d=>d.total), itemStyle:{color:'#409EFF'}, barMaxWidth:24, label:{show:true,position:'right',formatter:'{c}分'}}]
|
|
|
|
|
- })
|
|
|
|
|
- window.addEventListener('resize', ()=>c.resize())
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-onMounted(() => initCharts())
|
|
|
|
|
|
|
+const initCharts = () => { nextTick(() => {
|
|
|
|
|
+ if (scoreMap.value) {
|
|
|
|
|
+ const c0 = echarts.init(scoreMap.value)
|
|
|
|
|
+ c0.setOption({
|
|
|
|
|
+ title:{text:'太湖流域各省总分分布',left:'center',textStyle:{fontSize:14}},
|
|
|
|
|
+ tooltip:{trigger:'item',formatter:(p)=>`${p.name}: ${p.value} 分`},
|
|
|
|
|
+ visualMap:{min:94,max:100,left:'left',bottom:10,text:['高','低'],inRange:{color:['#e0f3f8','#abd9e9','#74add1','#4575b4','#313695']}},
|
|
|
|
|
+ series:[{type:'map',map:'taihu',nameProperty:'name',roam:false,label:{show:true,fontSize:12},data:provinceData.map(d=>({name:d.name,value:d.total}))}]
|
|
|
|
|
+ })
|
|
|
|
|
+ window.addEventListener('resize',()=>c0.resize())
|
|
|
|
|
+ }
|
|
|
|
|
+ if (provinceBar.value) {
|
|
|
|
|
+ const c = echarts.init(provinceBar.value)
|
|
|
|
|
+ c.setOption({
|
|
|
|
|
+ title:{text:'太湖流域各省总分排名',left:'center',textStyle:{fontSize:14}},
|
|
|
|
|
+ grid:{left:60,right:40,top:40,bottom:20},
|
|
|
|
|
+ yAxis:{type:'category',data:provinceData.map(d=>d.name.replace('省','').replace('市','')),inverse:true},
|
|
|
|
|
+ xAxis:{type:'value',name:'分',min:94,max:100},
|
|
|
|
|
+ series:[{type:'bar',data:provinceData.map(d=>d.total),itemStyle:{color:'#409EFF'},barMaxWidth:24,label:{show:true,position:'right',formatter:'{c}分'}}]
|
|
|
|
|
+ })
|
|
|
|
|
+ window.addEventListener('resize',()=>c.resize())
|
|
|
|
|
+ }
|
|
|
|
|
+})}
|
|
|
|
|
+onMounted(()=>initCharts())
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.assess-page {
|
|
|
|
|
- padding: 20px 24px;
|
|
|
|
|
- height: calc(100vh - 84px);
|
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
- background: #f0f2f5;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.page-title {
|
|
|
|
|
- font-size: 20px;
|
|
|
|
|
- color: #1a1a2e;
|
|
|
|
|
- margin: 0 0 16px;
|
|
|
|
|
- font-weight: 600;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.page-title::before {
|
|
|
|
|
- content: '';
|
|
|
|
|
- display: inline-block;
|
|
|
|
|
- width: 4px;
|
|
|
|
|
- height: 20px;
|
|
|
|
|
- background: #409EFF;
|
|
|
|
|
- margin-right: 10px;
|
|
|
|
|
- vertical-align: middle;
|
|
|
|
|
- border-radius: 2px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.assess-tabs {
|
|
|
|
|
- margin-bottom: 20px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.assess-tabs :deep(.el-tabs__header) {
|
|
|
|
|
- background: #fff;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.tab-card {
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- padding: 28px 20px 20px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.big-number {
|
|
|
|
|
- margin-bottom: 8px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.num {
|
|
|
|
|
- font-size: 42px;
|
|
|
|
|
- font-weight: 700;
|
|
|
|
|
- color: #409EFF;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.unit {
|
|
|
|
|
- font-size: 20px;
|
|
|
|
|
- color: #888;
|
|
|
|
|
- margin-left: 4px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.sub-title {
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- color: #999;
|
|
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.divider {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- gap: 12px;
|
|
|
|
|
- margin: 16px 0;
|
|
|
|
|
- color: #bbb;
|
|
|
|
|
- font-size: 13px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.divider::before, .divider::after {
|
|
|
|
|
- content: '';
|
|
|
|
|
- flex: 1;
|
|
|
|
|
- border-top: 1px dashed #dcdfe6;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.stat-table {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- max-width: 420px;
|
|
|
|
|
- margin: 0 auto;
|
|
|
|
|
- border-collapse: collapse;
|
|
|
|
|
- border: 1px solid #e4e7ed;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.stat-table td {
|
|
|
|
|
- padding: 10px;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.stat-table tr.stripe {
|
|
|
|
|
- background: #f5f7fa;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.score-card {
|
|
|
|
|
- border-radius: 8px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.score-card :deep(.el-card__header) {
|
|
|
|
|
- font-weight: 600;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.chart-row {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- gap: 16px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.chart-half {
|
|
|
|
|
- flex: 1;
|
|
|
|
|
- height: 400px;
|
|
|
|
|
- min-width: 0;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+.assess-page { padding:20px 24px; height:calc(100vh - 84px); overflow-y:auto; background:#f0f2f5; }
|
|
|
|
|
+.page-title { font-size:20px; color:#1a1a2e; margin:0 0 16px; font-weight:600; }
|
|
|
|
|
+.page-title::before { content:''; display:inline-block; width:4px; height:20px; background:#409EFF; margin-right:10px; vertical-align:middle; border-radius:2px; }
|
|
|
|
|
+
|
|
|
|
|
+/* 统计卡片 */
|
|
|
|
|
+.stat-cards { display:flex; gap:12px; margin-bottom:16px; }
|
|
|
|
|
+.stat-card { flex:1; background:#fff; border-radius:8px; padding:16px; text-align:center; cursor:pointer; transition:all .2s; box-shadow:0 1px 4px rgba(0,0,0,.06); border:2px solid transparent; }
|
|
|
|
|
+.stat-card:hover { box-shadow:0 4px 12px rgba(0,0,0,.1); }
|
|
|
|
|
+.stat-card.active { border-color:#409EFF; }
|
|
|
|
|
+.stat-num { font-size:28px; font-weight:700; color:#409EFF; }
|
|
|
|
|
+.stat-unit { font-size:14px; color:#999; margin-left:2px; font-weight:400; }
|
|
|
|
|
+.stat-label { font-size:13px; color:#333; margin:4px 0; font-weight:500; }
|
|
|
|
|
+.stat-desc { font-size:11px; color:#aaa; }
|
|
|
|
|
+
|
|
|
|
|
+.detail-card { margin-bottom:16px; border-radius:8px; }
|
|
|
|
|
+.detail-card :deep(.el-card__header) { font-weight:600; padding:10px 16px; }
|
|
|
|
|
+
|
|
|
|
|
+.chart-card { border-radius:8px; }
|
|
|
|
|
+.chart-card :deep(.el-card__header) { font-weight:600; }
|
|
|
|
|
+.chart-row { display:flex; gap:16px; }
|
|
|
|
|
+.chart-half { flex:1; height:380px; min-width:0; }
|
|
|
</style>
|
|
</style>
|