Forráskód Böngészése

优化考核评估布局:5卡片行+分级表格+双图表

Lin Qilong 5 napja
szülő
commit
31a4cf3293
1 módosított fájl, 78 hozzáadás és 190 törlés
  1. 78 190
      gw-ui/src/views/hlgl/assess/index.vue

+ 78 - 190
gw-ui/src/views/hlgl/assess/index.vue

@@ -2,29 +2,26 @@
   <div class="assess-page">
     <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>
       <div class="chart-row">
         <div ref="scoreMap" class="chart-half"></div>
@@ -35,188 +32,79 @@
 </template>
 
 <script setup>
-import {nextTick, onMounted, ref} from 'vue'
+import {computed, nextTick, onMounted, ref} from 'vue'
 import * as echarts from 'echarts'
 import chinaGeo from '@/assets/geoData/china_xh.json'
 
-const activeTab = ref('plan')
+const activeStat = ref('plan')
 
 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)
 echarts.registerMap('taihu', chinaGeo)
 
-// 太湖流域5省(GeoJSON properties.name = "江苏省" 等)
 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)
 
-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>
 
 <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>