480 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			480 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<template>
 | 
						|
  <section class="AppGovInteractionDV">
 | 
						|
    <el-row type="flex" justify="space-between" align="bottom">
 | 
						|
      <div flex class="framePane column top">
 | 
						|
        <div class="titlePane" v-text="'事件内容'"/>
 | 
						|
        <div class="fill">
 | 
						|
          <dv-scroll-board :config="topLeftData"/>
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
      <div class="centerTopPane" id="centerTopPane">
 | 
						|
        <b class="title gradientFont">事件统计</b>
 | 
						|
        <el-row type="flex" justify="space-between" align="middle"
 | 
						|
                v-for="(row,i) in topCenterData" :key="i">
 | 
						|
          <div class="dataPane" v-for="(op,j) in row" :key="j">
 | 
						|
            <span class="gradientFont" v-text="op.label"/>
 | 
						|
            <dv-digital-flop class="gradientFont" :config="op.v1"/>
 | 
						|
          </div>
 | 
						|
        </el-row>
 | 
						|
      </div>
 | 
						|
      <div flex class="framePane column top">
 | 
						|
        <div class="titlePane" v-text="'政务微信群'"/>
 | 
						|
        <div class="totalPane" flex>
 | 
						|
          <div class="dataPanel fill" flex v-for="(op,i) in rightTopData.total" :key="i">
 | 
						|
            <span v-text="op.label"/>
 | 
						|
            <b v-text="op.v1"/>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
        <div class="fill">
 | 
						|
          <ai-echart class="chart" :data="rightTopData.list" :ops="rightTopData.ops"/>
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
    </el-row>
 | 
						|
    <div flex class="gap fill">
 | 
						|
      <div flex class="framePane fill column" v-for="c in charts" :key="c.id">
 | 
						|
        <div class="titlePane" v-text="c.label"/>
 | 
						|
        <div class="fill">
 | 
						|
          <ai-echart class="chart" :data="chartData[c.id]" :ops="c.ops"/>
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
    </div>
 | 
						|
  </section>
 | 
						|
</template>
 | 
						|
 | 
						|
<script>
 | 
						|
import {digitalFlop, scrollBoard} from '@jiaminghi/data-view'
 | 
						|
import Vue from "vue";
 | 
						|
 | 
						|
Vue.use(digitalFlop)
 | 
						|
Vue.use(scrollBoard)
 | 
						|
 | 
						|
export default {
 | 
						|
  name: "AppGovInteractionDV",
 | 
						|
  label: "数据大屏-政民互动",
 | 
						|
  props: {
 | 
						|
    instance: Function
 | 
						|
  },
 | 
						|
  computed: {
 | 
						|
    topCenterData() {
 | 
						|
      let meta = [
 | 
						|
        [{label: "待受理", name: 'pending'}, {label: "累计上报", name: 'total_case'}],
 | 
						|
        [{label: "办理中", name: 'processing'}, {label: "累计受理", name: 'total_accepted'}],
 | 
						|
        [{label: "今日上报", name: "added_today"}, {label: "累计办结", name: 'total_solved'}],
 | 
						|
        [{label: "今日办结", name: 'solved_today'}, {label: "累计办结率", name: 'total_solved_percent'}],
 | 
						|
      ]
 | 
						|
      return meta.map(e => e.map(s => {
 | 
						|
        let v1 = {
 | 
						|
          number: [this.meta.residentCategoryReport?.[s.name] || 0],
 | 
						|
          style: {
 | 
						|
            fontFamily: 'dineng',
 | 
						|
            fontWeight: 'bold',
 | 
						|
            fontSize: 40,
 | 
						|
            gradientType: 'linear',
 | 
						|
            gradientColor: ['#fff', '#fff', '#6BC7FF'],
 | 
						|
            gradientParams: [0, 0, 0, 40],
 | 
						|
            gradientWith: 'fill',
 | 
						|
            gradientStops: [0, .18, 1]
 | 
						|
          }
 | 
						|
        }
 | 
						|
        if (s.name == 'total_solved_percent') {
 | 
						|
          v1 = {
 | 
						|
            ...v1,
 | 
						|
            number: [v1.number * 100], content: '{nt}%'
 | 
						|
          }
 | 
						|
        }
 | 
						|
        return {...s, v1}
 | 
						|
      }))
 | 
						|
    },
 | 
						|
    topLeftData() {
 | 
						|
      let statusColor = {
 | 
						|
            0: 'doing',
 | 
						|
            1: 'done',
 | 
						|
            2: 'pending',
 | 
						|
          },
 | 
						|
          statusLabel = {
 | 
						|
            0: '处理中',
 | 
						|
            1: '已处理'
 | 
						|
          },
 | 
						|
          list = this.meta.residentOrderList?.map(e => {
 | 
						|
            let status = e.process_list.slice(-1)?.[0]?.status
 | 
						|
            return {
 | 
						|
              ...e, status, statusLabel: statusLabel[status]
 | 
						|
            }
 | 
						|
          })
 | 
						|
      return {
 | 
						|
        oddRowBGC: 'transparent',
 | 
						|
        evenRowBGC: 'transparent',
 | 
						|
        rowNum: 10,
 | 
						|
        data: list?.map(e => [`
 | 
						|
          <div flex class="eventItem">
 | 
						|
            <span class="tag ${statusColor[e.status]}">${e.statusLabel}</span>
 | 
						|
            <div class="fill">${e.desc}</div>
 | 
						|
          </div>`]) || []
 | 
						|
      }
 | 
						|
    },
 | 
						|
    rightTopData() {
 | 
						|
      let obj = this.meta.groupMap?.list || {},
 | 
						|
          list = Object.keys(obj).map(e => {
 | 
						|
            let {total, increase, decrease} = obj?.[e],
 | 
						|
                time = this.$moment(e).format('MM-DD')
 | 
						|
            return {time, total, increase, decrease}
 | 
						|
          })
 | 
						|
      return {
 | 
						|
        total: [
 | 
						|
          {label: '群聊总数', v1: this.meta.groupMap?.groupSum || 0},
 | 
						|
          {label: '群成员数', v1: this.meta.groupMap?.today?.total || 0},
 | 
						|
        ],
 | 
						|
        ops: {
 | 
						|
          color: ['rgba(54, 165, 255, 0.2)', 'rgba(28, 212, 68, 0.2)', 'rgba(255, 215, 109, 0.2)'],
 | 
						|
          legend: {
 | 
						|
            itemWidth: 16,
 | 
						|
            itemHeight: 16,
 | 
						|
            textStyle: {color: '#82C5FF', padding: [0, 0, 0, 8], fontSize: 14},
 | 
						|
            icon: 'rect',
 | 
						|
            itemGap: 40
 | 
						|
          },
 | 
						|
          tooltip: {},
 | 
						|
          xAxis: {
 | 
						|
            type: 'category', axisTick: false,
 | 
						|
            nameGap: 20,
 | 
						|
            axisLabel: {color: '#fff'},
 | 
						|
            axisLine: {lineStyle: {color: '#263763'}}
 | 
						|
          },
 | 
						|
          // 声明一个 Y 轴,数值轴。
 | 
						|
          yAxis: {
 | 
						|
            nameGap: 30, minInterval: 1,
 | 
						|
            splitLine: {lineStyle: {color: '#263763'}},
 | 
						|
            axisLabel: {color: 'rgba(255,255,255,.8)'}
 | 
						|
          },
 | 
						|
          series: [
 | 
						|
            {
 | 
						|
              type: 'line', name: "群成员数", symbol: 'none', lineStyle: {color: '#36A5FF', borderWidth: 1},
 | 
						|
              itemStyle: {borderColor: '#36A5FF', borderWidth: 1},
 | 
						|
            },
 | 
						|
            {
 | 
						|
              type: 'line', name: "新增人数", symbol: 'none', lineStyle: {color: '#1CD444', borderWidth: 1},
 | 
						|
              itemStyle: {borderColor: '#1CD444', borderWidth: 1},
 | 
						|
            },
 | 
						|
            {
 | 
						|
              type: 'line', name: "退群人数", symbol: 'none', lineStyle: {color: '#FFD76D', borderWidth: 1},
 | 
						|
              itemStyle: {borderColor: '#FFD76D', borderWidth: 1},
 | 
						|
            }
 | 
						|
          ],
 | 
						|
          grid: {left: 60, bottom: 58, right: 20}
 | 
						|
        },
 | 
						|
        list
 | 
						|
      }
 | 
						|
    },
 | 
						|
    chartData() {
 | 
						|
      return {
 | 
						|
        EventType: this.meta.residentCategoryReportList?.map(e => {
 | 
						|
          let {category_name: name, total_case, total_solved} = e
 | 
						|
          return {name, total_case, total_solved}
 | 
						|
        }) || [],
 | 
						|
        EventSource: this.meta.unitReportList?.map(e => {
 | 
						|
          let {grid_name: name, total_case, total_solved} = e
 | 
						|
          return {name, total_case, total_solved}
 | 
						|
        }) || []
 | 
						|
      }
 | 
						|
    },
 | 
						|
  },
 | 
						|
  data() {
 | 
						|
    return {
 | 
						|
      charts: [
 | 
						|
        {
 | 
						|
          label: "事件类型", id: "EventType", ops: {
 | 
						|
            color: ['rgba(54, 165, 255, 0.2)', 'rgba(28, 212, 68, 0.2)'],
 | 
						|
            legend: {
 | 
						|
              itemWidth: 16,
 | 
						|
              itemHeight: 16,
 | 
						|
              textStyle: {color: '#82C5FF', padding: [0, 0, 0, 8], fontSize: 14},
 | 
						|
              icon: 'rect',
 | 
						|
              itemGap: 40
 | 
						|
            },
 | 
						|
            tooltip: {},
 | 
						|
            xAxis: {
 | 
						|
              type: 'category', nameGap: 20, axisTick: false,
 | 
						|
              axisLabel: {color: '#fff'},
 | 
						|
              axisLine: {lineStyle: {color: '#263763'}}
 | 
						|
            },
 | 
						|
            // 声明一个 Y 轴,数值轴。
 | 
						|
            yAxis: {
 | 
						|
              nameGap: 23, minInterval: 1,
 | 
						|
              splitLine: {lineStyle: {color: '#263763'}},
 | 
						|
              axisLabel: {color: 'rgba(255,255,255,.8)'}
 | 
						|
            },
 | 
						|
            series: [
 | 
						|
              {
 | 
						|
                type: 'bar',
 | 
						|
                name: "累计受理",
 | 
						|
                barWidth: 10,
 | 
						|
                barGap: '20%',
 | 
						|
                itemStyle: {borderColor: '#36A5FF', borderWidth: 1}
 | 
						|
              },
 | 
						|
              {
 | 
						|
                type: 'bar',
 | 
						|
                name: "累计办结",
 | 
						|
                barWidth: 10,
 | 
						|
                barGap: '20%',
 | 
						|
                itemStyle: {borderColor: '#1CD444', borderWidth: 1}
 | 
						|
              }
 | 
						|
            ],
 | 
						|
            grid: {left: 40, bottom: 58, right: 20}
 | 
						|
          }
 | 
						|
        },
 | 
						|
        {
 | 
						|
          label: "上报来源", id: "EventSource", ops: {
 | 
						|
            color: ['rgba(54, 165, 255, 0.2)', 'rgba(28, 212, 68, 0.2)'],
 | 
						|
            legend: {
 | 
						|
              itemWidth: 16,
 | 
						|
              itemHeight: 16,
 | 
						|
              textStyle: {color: '#82C5FF', padding: [0, 0, 0, 8], fontSize: 14},
 | 
						|
              icon: 'rect',
 | 
						|
              itemGap: 40
 | 
						|
            },
 | 
						|
            tooltip: {},
 | 
						|
            xAxis: {
 | 
						|
              type: 'category', axisTick: false,
 | 
						|
              nameGap: 20,
 | 
						|
              axisLabel: {color: '#fff'},
 | 
						|
              axisLine: {lineStyle: {color: '#263763'}}
 | 
						|
            },
 | 
						|
            // 声明一个 Y 轴,数值轴。
 | 
						|
            yAxis: {
 | 
						|
              nameGap: 30, minInterval: 1,
 | 
						|
              splitLine: {lineStyle: {color: '#263763'}},
 | 
						|
              axisLabel: {color: 'rgba(255,255,255,.8)'}
 | 
						|
            },
 | 
						|
            series: [
 | 
						|
              {
 | 
						|
                type: 'line', name: "事件数", symbol: 'none', lineStyle: {color: '#36A5FF', borderWidth: 1},
 | 
						|
                itemStyle: {borderColor: '#36A5FF', borderWidth: 1, show: false},
 | 
						|
                areaStyle: {
 | 
						|
                  color: {
 | 
						|
                    type: 'linear', x2: 0, y2: 1, colorStops: [
 | 
						|
                      {offset: 0, color: 'rgba(37, 161, 255, 0.5)'}, {offset: 1, color: 'rgba(37, 161, 255, 0)'}]
 | 
						|
                  }
 | 
						|
                }
 | 
						|
              },
 | 
						|
              {
 | 
						|
                type: 'line', name: "办理数", symbol: 'none', lineStyle: {color: '#1CD444', borderWidth: 1},
 | 
						|
                itemStyle: {borderColor: '#1CD444', borderWidth: 1, show: false},
 | 
						|
                areaStyle: {
 | 
						|
                  color: {
 | 
						|
                    type: 'linear', x2: 0, y2: 1, colorStops: [
 | 
						|
                      {offset: 0, color: 'rgba(37, 206, 55, 0.5)'}, {offset: 1, color: 'rgba(37, 206, 55, 0)'}]
 | 
						|
                  }
 | 
						|
                }
 | 
						|
              }
 | 
						|
            ],
 | 
						|
            grid: {left: 40, bottom: 58, right: 20}
 | 
						|
          }
 | 
						|
        },
 | 
						|
      ],
 | 
						|
      meta: {},
 | 
						|
    }
 | 
						|
  },
 | 
						|
  methods: {
 | 
						|
    getData() {
 | 
						|
      this.instance.post("/app/statistics/governmentPeople/queryResidentReport").then(res => {
 | 
						|
        if (res?.data) this.meta = res.data
 | 
						|
      })
 | 
						|
    },
 | 
						|
  },
 | 
						|
  created() {
 | 
						|
    this.getData()
 | 
						|
  }
 | 
						|
}
 | 
						|
</script>
 | 
						|
 | 
						|
<style lang="scss" scoped>
 | 
						|
.AppGovInteractionDV {
 | 
						|
  height: 100%;
 | 
						|
  padding: 6px 0 10px;
 | 
						|
  gap: 20px;
 | 
						|
  font-size: 16px;
 | 
						|
  color: #82C5FF;
 | 
						|
  display: flex;
 | 
						|
  flex-direction: column;
 | 
						|
 | 
						|
 | 
						|
  ::v-deep .eventItem {
 | 
						|
    width: 100%;
 | 
						|
    color: #82C5FF;
 | 
						|
 | 
						|
    & > .fill {
 | 
						|
      white-space: nowrap;
 | 
						|
      overflow: hidden;
 | 
						|
      text-overflow: ellipsis;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  ::v-deep .communityEvent {
 | 
						|
    list-style-type: circle;
 | 
						|
    white-space: nowrap;
 | 
						|
    overflow: hidden;
 | 
						|
    text-overflow: ellipsis;
 | 
						|
    height: 40px;
 | 
						|
    line-height: 40px;
 | 
						|
    padding-left: 1px;
 | 
						|
    color: #82C5FF;
 | 
						|
  }
 | 
						|
 | 
						|
  ::v-deep .tag {
 | 
						|
    padding: 0 10px;
 | 
						|
    border-radius: 4px;
 | 
						|
    margin-right: 10px;
 | 
						|
    font-size: 14px;
 | 
						|
    line-height: 28px;
 | 
						|
    color: #fff;
 | 
						|
    box-sizing: border-box;
 | 
						|
 | 
						|
    &.doing {
 | 
						|
      background-image: radial-gradient(rgba(#1B1BD6, .4), #208FFF);
 | 
						|
    }
 | 
						|
 | 
						|
    &.pending {
 | 
						|
      background-image: radial-gradient(rgba(#FF9333, .4), #FFE959);
 | 
						|
    }
 | 
						|
 | 
						|
    &.done {
 | 
						|
      background-image: radial-gradient(rgba(#1BD622, .4), #2CFF7C);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  .centerTopPane {
 | 
						|
    background-image: url("../assets/govInteraction/globe_map.png");
 | 
						|
    background-repeat: no-repeat;
 | 
						|
    background-size: 100% 100%;
 | 
						|
    height: 540px;
 | 
						|
    width: 940px;
 | 
						|
    flex-shrink: 0;
 | 
						|
    position: relative;
 | 
						|
    padding: 30px 50px 50px;
 | 
						|
    box-sizing: border-box;
 | 
						|
 | 
						|
    .title {
 | 
						|
      font-size: 60px;
 | 
						|
      position: absolute;
 | 
						|
      left: 50%;
 | 
						|
      top: 50%;
 | 
						|
      transform: translate(-50%, -50%);
 | 
						|
    }
 | 
						|
 | 
						|
    ::v-deep .gradientFont {
 | 
						|
      background-image: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 18%, #6BC7FF 100%);
 | 
						|
      -webkit-background-clip: text;
 | 
						|
      -webkit-text-fill-color: transparent;
 | 
						|
    }
 | 
						|
 | 
						|
    .el-row {
 | 
						|
      &:first-of-type, &:last-of-type {
 | 
						|
        margin: 0 110px;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    ::v-deep .dataPane {
 | 
						|
      width: 122px;
 | 
						|
      height: 114px;
 | 
						|
      background-image: url("../assets/govInteraction/kuaikuai.png");
 | 
						|
      background-repeat: no-repeat;
 | 
						|
      background-size: 100% 80px;
 | 
						|
      background-position: bottom center;
 | 
						|
      display: flex;
 | 
						|
      flex-direction: column;
 | 
						|
      align-items: center;
 | 
						|
      font-weight: bold;
 | 
						|
 | 
						|
      & > b {
 | 
						|
        font-size: 50px;
 | 
						|
        line-height: 50px;
 | 
						|
 | 
						|
        span {
 | 
						|
          font-weight: normal;
 | 
						|
          font-size: 32px;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      & > span {
 | 
						|
        font-size: 18px;
 | 
						|
        line-height: 18px;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  .framePane {
 | 
						|
    width: 100%;
 | 
						|
    height: 100%;
 | 
						|
    background: rgba(7, 11, 35, 0.4);
 | 
						|
    border: 1px solid #14345F;
 | 
						|
    display: flex;
 | 
						|
    flex-direction: column;
 | 
						|
 | 
						|
    &.top {
 | 
						|
      width: 440px;
 | 
						|
      height: 520px;
 | 
						|
    }
 | 
						|
 | 
						|
    & > .fill {
 | 
						|
      width: 100%;
 | 
						|
      height: 100%;
 | 
						|
      padding: 20px;
 | 
						|
      box-sizing: border-box;
 | 
						|
      overflow-y: auto;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  .titlePane {
 | 
						|
    width: 100%;
 | 
						|
    background-image: url("../assets/govInteraction/title.png");
 | 
						|
    background-repeat: no-repeat;
 | 
						|
    background-size: 309px 100%;
 | 
						|
    height: 60px;
 | 
						|
    padding-left: 30px;
 | 
						|
    color: #fff;
 | 
						|
    font-weight: bold;
 | 
						|
    font-size: 20px;
 | 
						|
    line-height: 48px;
 | 
						|
  }
 | 
						|
 | 
						|
  .chart {
 | 
						|
    width: 100%;
 | 
						|
  }
 | 
						|
 | 
						|
  .el-image {
 | 
						|
    width: 100%;
 | 
						|
    height: 100%;
 | 
						|
  }
 | 
						|
 | 
						|
  .totalPane {
 | 
						|
    width: 100%;
 | 
						|
 | 
						|
    .dataPanel {
 | 
						|
      height: 60px;
 | 
						|
      background: linear-gradient(270deg, rgba(119, 169, 255, 0.1) 0%, rgba(66, 112, 255, 0.25) 100%);
 | 
						|
      border-radius: 4px;
 | 
						|
      padding: 0 10px;
 | 
						|
      font-size: 16px;
 | 
						|
      justify-content: space-between;
 | 
						|
      margin-left: 20px;
 | 
						|
 | 
						|
      & > span {
 | 
						|
        white-space: nowrap;
 | 
						|
      }
 | 
						|
 | 
						|
      & > b {
 | 
						|
        font-size: 24px;
 | 
						|
        color: #fff;
 | 
						|
        font-family: Arial-BoldMT, Arial, serif;
 | 
						|
      }
 | 
						|
 | 
						|
      &:last-of-type {
 | 
						|
        margin-right: 20px;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
</style>
 |