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>
 |