定制大屏调整位置
							
								
								
									
										133
									
								
								packages/bigscreen/dv/apps/AppCentralTaskDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,133 @@ | ||||
| <template> | ||||
|   <section class="AppCentralTaskDV"> | ||||
|     <!--    <ai-dv-background :src="bgImage"/>--> | ||||
|     <div class="coreTask"> | ||||
|       <div class="leftBox"> | ||||
|         <div class="boxTitle">{{ coreTaskData.titleText }}</div> | ||||
|         <dv-scroll-board v-if="refresh" :config="coreTaskData"/> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {scrollBoard} from '@jiaminghi/data-view' | ||||
| import bgImage from '../assets/centralTask/bg.png' | ||||
| import Vue from "vue"; | ||||
|  | ||||
| Vue.use(scrollBoard) | ||||
| export default { | ||||
|   name: "AppCentralTaskDV", | ||||
|   label: "数据大屏-重点工作", | ||||
|   props: { | ||||
|     nav: {default: () => ({})} | ||||
|   }, | ||||
|   inject: { | ||||
|     dv: {default: ""} | ||||
|   }, | ||||
|   computed: { | ||||
|     coreTaskData() { | ||||
|       return { | ||||
|         headerHeight: 52, | ||||
|         header: ['基层组织建设', "社区治理", "便民服务效能", "城市管理"], | ||||
|         headerBGC: 'rgba(0, 113, 255, 0.5)', | ||||
|         oddRowBGC: "rgba(5, 65, 139, 0.5)", | ||||
|         evenRowBGC: "rgba(5, 65, 139, 0.5)", | ||||
|         waitTime: 6000, | ||||
|         align: ["center", "start", "center", "center"], | ||||
|         rowNum: 5, | ||||
|         ...this.nav.data, | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   data() { | ||||
|     return {bgImage, refresh: true} | ||||
|   }, | ||||
|   watch: { | ||||
|     nav: { | ||||
|       deep: true, | ||||
|       handler() { | ||||
|         this.refresh = false | ||||
|         this.$nextTick(() => this.refresh = true) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppCentralTaskDV { | ||||
|   height: 100%; | ||||
|   padding: 0 0 60px; | ||||
|   box-sizing: border-box; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|  | ||||
|   .coreTask { | ||||
|     flex: 1; | ||||
|     min-height: 0; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: 53px; | ||||
|     margin-top: 56px; | ||||
|  | ||||
|     .leftBox { | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|       background-image: url("../assets/centralTask/box.png"); | ||||
|       background-size: 100% 100%; | ||||
|       background-repeat: no-repeat; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       align-items: center; | ||||
|       padding: 0 40px 42px; | ||||
|       box-sizing: border-box; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .boxTitle { | ||||
|     height: 68px; | ||||
|     width: 534px; | ||||
|     background-image: url("../assets/centralTask/titleBox.png"); | ||||
|     text-align: center; | ||||
|     font-size: 22px; | ||||
|     font-weight: 400; | ||||
|     color: #71F8FF; | ||||
|     transform: translateY(-32px); | ||||
|     line-height: 68px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .dv-scroll-board { | ||||
|     width: 100%; | ||||
|     flex: 1; | ||||
|     min-height: 0; | ||||
|     border-radius: 6px; | ||||
|     overflow: hidden; | ||||
|  | ||||
|     .header { | ||||
|       color: #9FDBFB; | ||||
|       font-size: 20px; | ||||
|  | ||||
|       .header-item { | ||||
|         text-align: center; | ||||
|         border: 1px solid #054596; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .row-item { | ||||
|       color: #68F0FC; | ||||
|       font-size: 18px; | ||||
|       overflow: hidden; | ||||
|  | ||||
|       .ceil { | ||||
|         border: 1px solid #054596; | ||||
|         border-top: none; | ||||
|         position: relative; | ||||
|         line-height: 30px; | ||||
|         white-space: normal; | ||||
|         padding: 20px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										479
									
								
								packages/bigscreen/dv/apps/AppGovInteractionDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,479 @@ | ||||
| <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> | ||||
							
								
								
									
										848
									
								
								packages/bigscreen/dv/apps/AppGridDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,848 @@ | ||||
| <template> | ||||
|   <div class="griddv"> | ||||
|     <div class="left"> | ||||
|       <div class="griddv-title"> | ||||
|         <h2>网格列表</h2> | ||||
|       </div> | ||||
|       <div class="griddv-tree"> | ||||
|         <el-tree | ||||
|             :data="treeList" | ||||
|             :props="defaultProps" | ||||
|             @node-click="handleNodeClick" | ||||
|             node-key="id" | ||||
|             ref="tree" | ||||
|             default-expand-all | ||||
|             :expand-on-click-node="false" | ||||
|             highlight-current> | ||||
|         </el-tree> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="middle" :class="[girdLevel == '2' ? 'middle-active' : '']" ref="container" v-loading="isLoading" | ||||
|          element-loading-background="rgba(0, 0, 0, 0.5)"> | ||||
|       <div | ||||
|           ref="middleTree" | ||||
|           id="tree" | ||||
|           class="tree" | ||||
|           :style="{left: x, top: y, transform: `scale(${scale}) translate(-50%, -50%) `, 'transform-origin': `${0} ${0}`}"> | ||||
|         <ai-okr-tree ref="VueOkrTree" v-if="chartData.length" | ||||
|                      :data="chartData" | ||||
|                      node-key="id" | ||||
|                      show-collapsable | ||||
|                      aniamte | ||||
|                      animate-name="okr-fade-in-linear" | ||||
|                      :render-content="renderContent" | ||||
|                      default-expand-all/> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="right"> | ||||
|       <div class="right-top"> | ||||
|         <div class="griddv-title"> | ||||
|           <h2>网格内人员情况</h2> | ||||
|         </div> | ||||
|         <div class="right-chart"> | ||||
|           <ai-echart | ||||
|               style="height: 100%; width: 100%;" | ||||
|               :data="userInfo" | ||||
|               :ops="barChart1"> | ||||
|           </ai-echart> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="right-bottom"> | ||||
|         <div class="griddv-title"> | ||||
|           <h2>事件上报情况</h2> | ||||
|         </div> | ||||
|         <div class="right-chart"> | ||||
|           <ai-echart | ||||
|               style="height: 100%; width: 100%;" | ||||
|               :data="eventInfo" | ||||
|               :ops="pieChart2"> | ||||
|           </ai-echart> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <el-dialog :visible.sync="isShowInfo" width="640px" :close-on-click-modal="false" :modal-append-to-body="false"> | ||||
|       <template slot="title"> | ||||
|         <h2>家庭信息</h2> | ||||
|         <img src="../assets/grid/close.png" @click="isShowInfo = false"> | ||||
|       </template> | ||||
|       <div class="grid-info"> | ||||
|         <div class="grid-info__title"> | ||||
|           <h2>家庭地址</h2> | ||||
|           <span>{{ residentInfo.currentAreaName }}</span> | ||||
|         </div> | ||||
|         <ai-table | ||||
|             style="width: 558px" | ||||
|             :tableData="tableData" | ||||
|             :col-configs="colConfigs" | ||||
|             :total="total" | ||||
|             :isShowPagination="false" | ||||
|             :current.sync="search.current" | ||||
|             :size.sync="search.size" | ||||
|             @getList="() => {}"> | ||||
|         </ai-table> | ||||
|       </div> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {barChart1, pieChart2} from "./components/chartOps" | ||||
|  | ||||
| export default { | ||||
|   name: 'AppGridDV', | ||||
|   label: '网格数据大屏', | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       isLoading: false, | ||||
|       treeList: [], | ||||
|       search: { | ||||
|         size: 100, | ||||
|         current: 1 | ||||
|       }, | ||||
|       barChart1, | ||||
|       userInfo: [], | ||||
|       eventInfo: [], | ||||
|       pieChart2, | ||||
|       total: 0, | ||||
|       isShowInfo: false, | ||||
|       defaultProps: { | ||||
|         children: 'girdList', | ||||
|         label: 'girdName', | ||||
|       }, | ||||
|       colConfigs: [ | ||||
|         {prop: 'name', label: '姓名', align: 'center', width: 120}, | ||||
|         { | ||||
|           prop: 'householdRelation', | ||||
|           label: '与户主关系', | ||||
|           align: 'center', | ||||
|           render: (h, {row}) => { | ||||
|             return h('span', { | ||||
|               style: { | ||||
|                 color: row.householdName === '1' ? '#1DE94D' : '#A8D7F3' | ||||
|               } | ||||
|             }, row.householdName === '1' ? '户主' : (this.dict.getLabel('householdRelation', row.householdRelation) || '-')) | ||||
|           }, | ||||
|           formart: v => this.dict.getLabel('householdRelation', v) | ||||
|         }, | ||||
|         { | ||||
|           prop: 'idNumber', | ||||
|           label: '身份证号', | ||||
|           align: 'center', | ||||
|           width: 220, | ||||
|           formart: v => v ? v.replace(/^(\d{10})\d{4}(.{4}$)/g, `$1${Array(5).join('*')}$2`) : '-' | ||||
|         }, | ||||
|         {prop: 'phone', label: '联系方式', align: 'center'} | ||||
|       ], | ||||
|       girdId: '', | ||||
|       residentInfo: {}, | ||||
|       tableData: [], | ||||
|       chartData: [], | ||||
|       girdLevel: '0', | ||||
|       scale: 1, | ||||
|       x: '50%', | ||||
|       y: '50%', | ||||
|       offsetX: 0, | ||||
|       offsetY: 0, | ||||
|       defaultUrl: 'https://cdn.cunwuyun.cn/dvcp/dv/avatar.png' | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     this.dict.load('householdRelation') | ||||
|     this.getTreeList() | ||||
|     this.getGirdInfo() | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     this.bindEvent() | ||||
|   }, | ||||
|  | ||||
|   destroyed() { | ||||
|     document.querySelector('body').removeEventListener('mousewheel', this.onMousewheel) | ||||
|     document.querySelector('body').removeEventListener('mouseup', this.onMouseUp) | ||||
|     document.querySelector('body').removeEventListener('mousedown', this.onMousedown) | ||||
|     document.querySelector('body').removeEventListener('mousemove', this.onMouseMove) | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     bindEvent() { | ||||
|       document.querySelector('body').addEventListener('mousewheel', this.onMousewheel, true) | ||||
|  | ||||
|       document.querySelector('body').addEventListener('mouseup', this.onMouseUp, true) | ||||
|       document.querySelector('body').addEventListener('mousedown', this.onMousedown, true) | ||||
|       document.querySelector('body').addEventListener('mousemove', this.onMouseMove, true) | ||||
|     }, | ||||
|  | ||||
|     onMousewheel(event) { | ||||
|       if (!event) return false | ||||
|       const elClass = event.target.className | ||||
|       if (elClass === 'tree' || elClass === 'middle' || (elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) { | ||||
|         var dir = event.deltaY > 0 ? 'Up' : 'Down' | ||||
|         if (dir === 'Up') { | ||||
|           this.scale = this.scale - 0.2 <= 0.1 ? 0.1 : this.scale - 0.2 | ||||
|         } else { | ||||
|           this.scale = this.scale + 0.2 | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       return false | ||||
|     }, | ||||
|  | ||||
|     onMousedown(e) { | ||||
|       const elClass = e.target.className | ||||
|       if ((elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) { | ||||
|         const left = document.querySelector('#tree').offsetLeft | ||||
|         const top = document.querySelector('#tree').offsetTop | ||||
|         this.isMove = true | ||||
|         this.offsetX = e.clientX - left | ||||
|         this.offsetY = e.clientY - top | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     onMouseMove(e) { | ||||
|       if (!this.isMove) return | ||||
|  | ||||
|       this.x = (e.clientX - this.offsetX) + 'px' | ||||
|       this.y = (e.clientY - this.offsetY) + 'px' | ||||
|     }, | ||||
|  | ||||
|     onMouseUp() { | ||||
|       this.isMove = false | ||||
|     }, | ||||
|  | ||||
|     debounce(func, wait = 1000) { | ||||
|       let timeout | ||||
|       return function (event) { | ||||
|         clearTimeout(timeout) | ||||
|         timeout = setTimeout(() => { | ||||
|           func.call(this, event) | ||||
|         }, wait) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     handleNodeClick(e) { | ||||
|       this.girdLevel = e.girdLevel | ||||
|       this.isLoading = true | ||||
|       this.getGirdInfo(e.id, e.girdLevel) | ||||
|       this.getStatisticsInfo(e.id) | ||||
|     }, | ||||
|  | ||||
|     getStatisticsInfo(id) { | ||||
|       this.instance.post(`/app/appgirdmemberinfo/girdMemberAndResidentStatistic?girdId=${id}`).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.userInfo = [ | ||||
|             { | ||||
|               'name': '网格长', | ||||
|               '人数': res.data['网格长'] || 0 | ||||
|             }, | ||||
|             { | ||||
|               'name': '网格员', | ||||
|               '人数': res.data['网格员'] || 0 | ||||
|             }, | ||||
|             { | ||||
|               'name': '责任家庭数', | ||||
|               '人数': res.data['责任家庭数'] || 0 | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       }) | ||||
|  | ||||
|       this.instance.post(`/app/appclapeventinfo/clapEventStatistic?girdId=${id}`).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.eventInfo = Object.keys(res.data).map(v => { | ||||
|             return { | ||||
|               '事件类型': v, | ||||
|               v1: res.data[v] | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     renderContent(h, node) { | ||||
|       return h('div', { | ||||
|         class: 'userlist-container' | ||||
|       }, [h('div', { | ||||
|         class: `userlist ${node.data.label === '子节点' ? 'last-level' : ''} ${node.data.girdLevel > 1 ? 'userlist-wrapper' : ''} userlist-${node.data.girdLevel}` | ||||
|       }, node.data.userList.map(v => { | ||||
|         return h('div', { | ||||
|           class: `user-item user-item-${v.girdLevel}` | ||||
|         }, [h('img', { | ||||
|           class: 'user-img', | ||||
|           attrs: { | ||||
|             src: v.photo || this.defaultUrl | ||||
|           }, | ||||
|           on: { | ||||
|             dragstart: e => { | ||||
|               e.preventDefault() | ||||
|               e.stopPropagation() | ||||
|               return false | ||||
|             } | ||||
|           } | ||||
|         }), h('p', { | ||||
|           class: 'user-p', | ||||
|           attrs: { | ||||
|             title: v.label, | ||||
|             'data-id': v.id | ||||
|           }, | ||||
|           on: { | ||||
|             click: () => { | ||||
|               if (node.data.label === '子节点') { | ||||
|                 this.getResidentInfo(v.id) | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, v.label), h('span', { | ||||
|           class: 'user-span', | ||||
|           style: { | ||||
|             display: v.girdLevel === '2' ? 'block' : 'none', | ||||
|             fontSize: v.girdLevel === '2' ? '12px' : '' | ||||
|           } | ||||
|         }, v.checkType ? (v.checkType === '1' ? '网格员' : '网格长') : '-')]) | ||||
|       })), h('div', { | ||||
|         class: 'user-gridName', | ||||
|         style: { | ||||
|           display: node.data.label === '子节点' ? 'none' : 'block', | ||||
|           color: 'rgba(255, 255, 255, 0.8)', | ||||
|           fontSize: '12px', | ||||
|           margin: '4px 0' | ||||
|         } | ||||
|       }, node.data.label)]) | ||||
|     }, | ||||
|  | ||||
|     getResidentInfo(id) { | ||||
|       this.isLoading = true | ||||
|       this.instance.post(`/app/appresident/detail?id=${id}`).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.residentInfo.resident = res.data | ||||
|           this.tableData = res.data.family || [] | ||||
|           this.isShowInfo = true | ||||
|         } | ||||
|  | ||||
|         this.isLoading = false | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     autoScale() { | ||||
|       const treeWidth = this.$refs.middleTree.offsetWidth | ||||
|       const containerWidth = this.$refs.container.offsetWidth | ||||
|       this.scale = treeWidth < containerWidth ? 1 : containerWidth / treeWidth | ||||
|       this.x = '50%' | ||||
|       this.y = '50%' | ||||
|     }, | ||||
|  | ||||
|     getGirdInfo(id) { | ||||
|       this.instance.post(`/app/appgirdinfo/listAllGirdAndMemberByTop?id=${id || ''}`).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           const chartData = this.formatList([res.data]) | ||||
|           this.chartData = chartData | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             if (id) { | ||||
|               this.getUserList(id, chartData[0].id) | ||||
|             } else { | ||||
|               this.isLoading = false | ||||
|               this.autoScale() | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     getUserList(id, parentId) { | ||||
|       this.instance.post(`/app/appgirdmemberresident/listByGirdMember`, null, { | ||||
|         params: { | ||||
|           size: 1000, | ||||
|           girdId: id | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           const userList = res.data.records.map(v => { | ||||
|             return { | ||||
|               ...v, | ||||
|               isLast: true, | ||||
|               label: v.name | ||||
|             } | ||||
|           }) | ||||
|  | ||||
|           this.isLoading = false | ||||
|  | ||||
|           if (!userList.length) { | ||||
|             this.autoScale() | ||||
|             return false | ||||
|           } | ||||
|  | ||||
|           const node = this.$refs.VueOkrTree.getNode(parentId) | ||||
|           this.$refs.VueOkrTree.append({ | ||||
|             id: new Date().getTime(), | ||||
|             label: '子节点', | ||||
|             userList: userList || [] | ||||
|           }, node) | ||||
|           this.$nextTick(() => { | ||||
|             this.autoScale() | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     formatList(list) { | ||||
|       return list.map(item => { | ||||
|         let userList = [] | ||||
|         const girdMemberManageList = item.girdMemberManageList ? item.girdMemberManageList.map(v => { | ||||
|           return { | ||||
|             ...v, | ||||
|             label: v.name, | ||||
|             id: v.id, | ||||
|             checkType: '2', | ||||
|             girdName: item.girdName, | ||||
|             girdLevel: item.girdLevel, | ||||
|             isUser: true | ||||
|           } | ||||
|         }) : [] | ||||
|         const girdMemberList = item.girdMemberList ? item.girdMemberList.map(v => { | ||||
|           return { | ||||
|             ...v, | ||||
|             label: v.name, | ||||
|             id: v.id, | ||||
|             checkType: '1', | ||||
|             girdName: item.girdName, | ||||
|             girdLevel: item.girdLevel, | ||||
|             isUser: true | ||||
|           } | ||||
|         }) : [] | ||||
|  | ||||
|         if (this.girdLevel === '2' && item.girdLevel === '2' && girdMemberList.length) { | ||||
|           userList = girdMemberManageList | ||||
|           item.girdList = [{ | ||||
|             girdLevel: '2', | ||||
|             id: item.id, | ||||
|             isUser: false, | ||||
|             userList: girdMemberList, | ||||
|             label: item.girdName, | ||||
|             children: [] | ||||
|           }] | ||||
|         } else { | ||||
|           userList = [...girdMemberManageList, ...girdMemberList] | ||||
|         } | ||||
|         if (!userList.length) { | ||||
|           userList = [{ | ||||
|             label: '-', | ||||
|             id: item.id, | ||||
|             girdLevel: item.girdLevel, | ||||
|             girdName: item.girdName | ||||
|           }] | ||||
|         } | ||||
|  | ||||
|         const obj = { | ||||
|           label: item.girdName, | ||||
|           id: `${new Date().getTime()}-${item.id}`, | ||||
|           girdLevel: item.girdLevel, | ||||
|           isUser: false, | ||||
|           userList: userList, | ||||
|           children: item.girdList || [] | ||||
|         } | ||||
|  | ||||
|         if (obj.children && obj.children.length && this.girdLevel !== '2') { | ||||
|           obj.children = this.formatList(obj.children) | ||||
|         } | ||||
|  | ||||
|         return obj | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     getTreeList() { | ||||
|       this.instance.post('/app/appgirdinfo/listAll').then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.treeList = [...res.data] | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             this.$refs.tree.setCurrentKey(res.data[0].id) | ||||
|             this.getStatisticsInfo(res.data[0].id) | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .griddv { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   height: 100%; | ||||
|   user-select: none; | ||||
|  | ||||
|   ::-webkit-scrollbar { | ||||
|     width: 6px; | ||||
|   } | ||||
|  | ||||
|   ::-webkit-scrollbar-track { | ||||
|     border-radius: 5px; | ||||
|     background: rgba(93, 163, 255, 0.1); | ||||
|   } | ||||
|  | ||||
|   ::-webkit-scrollbar-thumb { | ||||
|     border-radius: 5px; | ||||
|     background: rgba(173, 208, 255, 0.5); | ||||
|   } | ||||
|  | ||||
|   .grid-info { | ||||
|     width: 100%; | ||||
|  | ||||
|     .grid-info__title { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       margin-bottom: 20px; | ||||
|  | ||||
|       h2, span { | ||||
|         color: #fff; | ||||
|         font-size: 14px; | ||||
|         font-weight: 500; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-dialog__body { | ||||
|     padding: 10px 40px 30px; | ||||
|  | ||||
|     .el-table { | ||||
|       background-color: transparent; | ||||
|     } | ||||
|  | ||||
|     .el-table__body tr td:first-child .cell, .ai-table .el-table__header tr th:first-child .cell { | ||||
|       padding-left: 0 !important; | ||||
|     } | ||||
|  | ||||
|     .el-table th, .el-table tr { | ||||
|       color: #fff; | ||||
|       font-size: 14px; | ||||
|       background-color: rgba(28, 39, 65, 0.9); | ||||
|     } | ||||
|  | ||||
|     .el-table__row--striped, .el-table--striped .el-table__body tr.el-table__row--striped td { | ||||
|       background-color: transparent !important; | ||||
|     } | ||||
|  | ||||
|     .el-table__header-wrapper { | ||||
|       display: none; | ||||
|     } | ||||
|  | ||||
|     .el-table--enable-row-hover .el-table__body tr:hover > td, .el-table-filter { | ||||
|       background-color: transparent; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-dialog { | ||||
|     position: absolute; | ||||
|     top: 50%; | ||||
|     left: 50%; | ||||
|     margin: 0 !important; | ||||
|     transform: translate(-50%, -50%); | ||||
|     background: rgba(2, 13, 43, 0.9); | ||||
|     box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.5), inset 0px 0px 10px 0px #2C7CFF; | ||||
|     border: 1px solid #2D65C9; | ||||
|  | ||||
|     .el-dialog__header { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: space-between; | ||||
|       background: transparent; | ||||
|       box-shadow: none; | ||||
|  | ||||
|       h2 { | ||||
|         color: #fff; | ||||
|         font-size: 18px; | ||||
|       } | ||||
|  | ||||
|       img { | ||||
|         cursor: pointer; | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|  | ||||
|         &:hover { | ||||
|           opacity: 0.6; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .el-dialog__headerbtn { | ||||
|       display: none; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .userlist-container { | ||||
|     .userlist { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       padding: 10px; | ||||
|       background: rgba(76, 166, 255, 0.1); | ||||
|       border: 1px solid rgba(255, 255, 255, 0.2); | ||||
|  | ||||
|       .user-item { | ||||
|         margin-right: 10px; | ||||
|         color: #fff; | ||||
|         font-size: 0; | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|  | ||||
|         img { | ||||
|           width: 58px; | ||||
|           height: 80px; | ||||
|           object-fit: cover; | ||||
|           user-select: none; | ||||
|         } | ||||
|  | ||||
|         p { | ||||
|           max-width: 120px; | ||||
|           margin: 4px 0 0 0; | ||||
|           font-size: 19px; | ||||
|           text-align: center; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           white-space: nowrap; | ||||
|         } | ||||
|  | ||||
|         span { | ||||
|           display: block; | ||||
|           max-width: 120px; | ||||
|           font-size: 17px; | ||||
|           color: #9DD3FF; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           white-space: nowrap; | ||||
|         } | ||||
|  | ||||
|         &.user-item-0 { | ||||
|           img { | ||||
|             width: 86px; | ||||
|             height: 120px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         &.user-item-2 { | ||||
|           p { | ||||
|             line-height: 14px; | ||||
|             font-size: 12px; | ||||
|             margin-bottom: 4px; | ||||
|           } | ||||
|  | ||||
|           span { | ||||
|             line-height: 14px; | ||||
|           } | ||||
|  | ||||
|           img { | ||||
|             width: 40px; | ||||
|             height: 56px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       &.userlist-2 { | ||||
|         justify-content: space-between; | ||||
|         max-width: 130px; | ||||
|         flex-wrap: wrap; | ||||
|         padding-bottom: 0; | ||||
|         width: fit-content; | ||||
|         margin: 0 auto; | ||||
|  | ||||
|         .user-item { | ||||
|           width: 48px; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           white-space: nowrap; | ||||
|           margin-bottom: 10px; | ||||
|  | ||||
|           &:nth-of-type(2n) { | ||||
|             margin-right: 0; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       &.last-level { | ||||
|         flex-wrap: wrap; | ||||
|         max-width: 690px; | ||||
|         font-size: 0; | ||||
|         background: rgba(0, 0, 0, 0.1); | ||||
|         border: 1px solid rgba(255, 255, 255, 0.2); | ||||
|         padding: 12px 12px 0 12px; | ||||
|         box-sizing: border-box; | ||||
|  | ||||
|         .user-item { | ||||
|           margin-bottom: 12px; | ||||
|         } | ||||
|  | ||||
|         img { | ||||
|           display: none; | ||||
|         } | ||||
|  | ||||
|         p { | ||||
|           padding: 8px; | ||||
|           font-size: 12px; | ||||
|           background: #0B477D; | ||||
|           border-radius: 4px; | ||||
|         } | ||||
|  | ||||
|         span { | ||||
|           display: none !important; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   * { | ||||
|     box-sizing: border-box; | ||||
|   } | ||||
|  | ||||
|   .griddv-title { | ||||
|     display: flex; | ||||
|     width: 320px; | ||||
|     height: 62px; | ||||
|     background-image: url(../assets/grid/title-bg.png); | ||||
|     background-size: 100% 100%; | ||||
|  | ||||
|     h2 { | ||||
|       width: 100%; | ||||
|       height: 50px; | ||||
|       line-height: 50px; | ||||
|       padding-left: 24px; | ||||
|       font-weight: 600; | ||||
|       font-size: 20px; | ||||
|       letter-spacing: 1px; | ||||
|       color: #fff; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   & > div { | ||||
|     height: 100%; | ||||
|   } | ||||
|  | ||||
|   .right { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     flex-direction: column; | ||||
|     width: 440px; | ||||
|     margin-left: 20px; | ||||
|  | ||||
|     & > div { | ||||
|       flex: 1; | ||||
|       width: 100%; | ||||
|       padding-bottom: 20px; | ||||
|       background: rgba(7, 11, 35, 0.4); | ||||
|       border: 1px solid #2D50B5; | ||||
|       box-sizing: border-box; | ||||
|  | ||||
|       .right-chart { | ||||
|         height: calc(100% - 82px); | ||||
|         padding: 0 20px; | ||||
|       } | ||||
|  | ||||
|       &:last-child { | ||||
|         margin-top: 20px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .middle { | ||||
|     position: relative; | ||||
|     flex: 1; | ||||
|     margin-left: 20px; | ||||
|     background: rgba(7, 11, 35, 0.4); | ||||
|     border: 1px solid #2D50B5; | ||||
|     overflow: hidden; | ||||
|  | ||||
|     #tree { | ||||
|       display: flex; | ||||
|       position: absolute; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       left: 50%; | ||||
|       top: 50%; | ||||
|       padding: 20px; | ||||
|       overflow: hidden; | ||||
|       width: max-content; | ||||
|       height: 300%; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .org-chart-container { | ||||
|       display: flex; | ||||
|       justify-content: center; | ||||
|  | ||||
|       .org-chart-node-children:before, .org-chart-node:after, .org-chart-node:last-child:before, | ||||
|       .org-chart-node.is-leaf:before { | ||||
|         border-radius: 0; | ||||
|         border-color: #9CD7FF !important; | ||||
|       } | ||||
|  | ||||
|       .vertical .org-chart-node:after, .vertical .org-chart-node:before { | ||||
|         border-radius: 0; | ||||
|         border-color: #9CD7FF !important; | ||||
|       } | ||||
|  | ||||
|       .org-chart-node-label-inner { | ||||
|         padding: 0 !important; | ||||
|       } | ||||
|  | ||||
|       .org-chart-node-btn { | ||||
|         margin-left: 0; | ||||
|         transform: translateX(-50%); | ||||
|       } | ||||
|  | ||||
|       .org-chart-node { | ||||
|         // max-width: 500px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     ::v-deep .org-chart-node-children { | ||||
|       display: flex; | ||||
|       justify-content: center; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .left { | ||||
|     width: 320px; | ||||
|     background: rgba(7, 11, 35, 0.4); | ||||
|     border: 1px solid #2D50B5; | ||||
|  | ||||
|     .griddv-tree { | ||||
|       height: calc(100% - 62px); | ||||
|       overflow-y: auto; | ||||
|       margin: 0 8px; | ||||
|       padding-bottom: 8px; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .el-tree { | ||||
|       background: transparent; | ||||
|  | ||||
|       .el-tree-node__expand-icon { | ||||
|         color: #eaeff9; | ||||
|       } | ||||
|  | ||||
|       .el-tree-node__expand-icon.is-leaf { | ||||
|         color: transparent; | ||||
|       } | ||||
|  | ||||
|       .el-tree-node__content { | ||||
|         height: 32px; | ||||
|         color: #eaeff9; | ||||
|         font-size: 14px; | ||||
|         user-select: none; | ||||
|         font-weight: normal !important; | ||||
|         background: transparent; | ||||
|       } | ||||
|  | ||||
|       .is-current > .el-tree-node__content, .el-tree-node__content:hover { | ||||
|         background: linear-gradient(270deg, #4895D9 0%, #2D52CA 100%); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										1467
									
								
								packages/bigscreen/dv/apps/AppHomesteadDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1223
									
								
								packages/bigscreen/dv/apps/AppPdDv.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1233
									
								
								packages/bigscreen/dv/apps/AppSpecialPeopleDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										522
									
								
								packages/bigscreen/dv/apps/AppVideoMonitoringDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,522 @@ | ||||
| <template> | ||||
|   <section class="AppVideoMonitoringDV"> | ||||
|     <el-row type="flex" justify="space-between" class="body"> | ||||
|       <div class="left-wrap column" flex> | ||||
|         <div class="left-top fill"> | ||||
|           <label class="label">设备统计</label> | ||||
|           <dv-scroll-board :header="config.header" :config="config" class="table"/> | ||||
|         </div> | ||||
|         <div class="left-bottom"> | ||||
|           <label class="label">电子地图</label> | ||||
|           <ai-map :areaId="user.info.areaId"/> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="center-wrap column" flex> | ||||
|         <div flex style="width: 100%"> | ||||
|           <div :span="6" class="card fill" v-for="(item,index) in cardList" :key="index"> | ||||
|             <span>{{ item.label }}</span> | ||||
|             <span>{{ item.value }}</span> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="center-bottom fill"> | ||||
|           <label class="label">视频监控</label> | ||||
|           <div class="video-wrap"> | ||||
|             <div class="item" v-for="(item,index) in videoData.slice(0,2)" | ||||
|                  :key="index"> | ||||
|               <template v-if="flag"> | ||||
|                 <iframe class="video" :src="item.url" allow="autoplay *; microphone *; fullscreen *" | ||||
|                         allowfullscreen allowtransparency="true" allowusermedia="true" frameBorder="no"></iframe> | ||||
|               </template> | ||||
|               <template v-else> | ||||
|                 <div class="video"></div> | ||||
|               </template> | ||||
|               <div class="info"> | ||||
|                 <span>{{ item.name }}</span> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="video-wrap"> | ||||
|             <div class="item" v-for="(item,index) in videoData.slice(2,4)" | ||||
|                  :key="index"> | ||||
|               <template v-if="flag"> | ||||
|                 <iframe class="video" :src="item.url" allow="autoplay *; microphone *; fullscreen *" | ||||
|                         allowfullscreen allowtransparency="true" allowusermedia="true" frameBorder="no"></iframe> | ||||
|               </template> | ||||
|               <template v-else> | ||||
|                 <div class="video"></div> | ||||
|               </template> | ||||
|               <div class="info"> | ||||
|                 <span>{{ item.name }}</span> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="right-wrap column" flex> | ||||
|         <div class="right-top fill"> | ||||
|           <label class="label">人员统计</label> | ||||
|           <label class="total">人员总数 | ||||
|             <span>0</span> | ||||
|             <span>人</span> | ||||
|           </label> | ||||
|           <dv-scroll-board :config="config1" class="total-table"/> | ||||
|         </div> | ||||
|         <div class="right-middle"> | ||||
|           <label class="label">动作告警统计</label> | ||||
|           <div class="tag"> | ||||
|             <span></span> | ||||
|           </div> | ||||
|           <ai-echart :ops="getOpt()"/> | ||||
|           <div class="info"> | ||||
|             今日 | ||||
|             <span>0</span> | ||||
|             <span>次</span> | ||||
|             本月 | ||||
|             <span>0</span> | ||||
|             <span>次</span> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="right-bottom"> | ||||
|           <label class="label">声音告警统计</label> | ||||
|           <div class="tag"> | ||||
|             <span></span> | ||||
|           </div> | ||||
|           <ai-echart :ops="getOpt('1')"/> | ||||
|           <div class="info"> | ||||
|             今日 | ||||
|             <span style="color:#00FFDF">0</span> | ||||
|             <span>次</span> | ||||
|             本月 | ||||
|             <span style="color:#00FFDF">0</span> | ||||
|             <span>次</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </el-row> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from "vuex"; | ||||
| import Vue from "vue"; | ||||
| import {scrollBoard} from "@jiaminghi/data-view"; | ||||
|  | ||||
| Vue.use(scrollBoard) | ||||
| export default { | ||||
|   name: "AppVideoMonitoringDV", | ||||
|   label: "数据大屏-平安小区", | ||||
|   inject: { | ||||
|     dv: {default: ""} | ||||
|   }, | ||||
|   props: { | ||||
|     instance: Function | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|     cardList() { | ||||
|       return [ | ||||
|         {label: "总设备数", value: "0"}, | ||||
|         {label: "在线设备", value: "0"}, | ||||
|         {label: "离线设备", value: "0"}, | ||||
|         {label: "设备在线率", value: "0%"}, | ||||
|       ] | ||||
|     }, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       meta: {}, | ||||
|       config: { | ||||
|         data: [ | ||||
|         ], | ||||
|         columnWidth: [60, 140], | ||||
|         header: ["机构", "设备在线率"], | ||||
|         headerBGC: '', | ||||
|         headerHeight: 41, | ||||
|         oddRowBGC: "", | ||||
|         evenRowBGC: "", | ||||
|         align: ["center", "center", "center"], | ||||
|         rowNum: 10, | ||||
|         index: true, | ||||
|         indexHeader: "排名" | ||||
|       }, | ||||
|       config1: { | ||||
|         data: [ | ||||
|           ['普通用户', '-'], | ||||
|           ['村级管理员', '-'], | ||||
|           ['超级管理员', '-'], | ||||
|           ['测试', '-'], | ||||
|         ], | ||||
|         headerHeight: 41, | ||||
|         oddRowBGC: "", | ||||
|         evenRowBGC: "", | ||||
|         align: ["left", "left", "right"], | ||||
|         index: true, | ||||
|         rowNum: 6, | ||||
|         columnWidth: [50] | ||||
|       }, | ||||
|       start: 0, | ||||
|       end: 40, | ||||
|       start1: 0, | ||||
|       end1: 40, | ||||
|       interval: null, | ||||
|       videoData: [], | ||||
|       flag: false, | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     jsonObj(val) { | ||||
|       return JSON.parse(val || "{}")?.url | ||||
|     }, | ||||
|     getOpt(type = "0") { | ||||
|       let opt = { | ||||
|         "0": { | ||||
|           xData: ['2020/7/1', "2020/7/2", "2020/7/3", "2020/7/4", "2020/7/5", "2020/7/6", "2020/7/7", "2020/7/8", "2020/7/9", "2020/7/10", "2020/7/11"], | ||||
|           yData: Array(11).fill(0), | ||||
|           color: "#FFEA2F", | ||||
|           areaStyle: 'rgba(255,234,47,0.2)', | ||||
|           unit: '', | ||||
|         }, | ||||
|         "1": { | ||||
|           xData: ["1:00", "2:00", "3:00", "4:00", "5:00", "6:00", "7:00", "8:00", "9:00", "10:00"], | ||||
|           yData: Array(10).fill(0), | ||||
|           color: "#13B5B1", | ||||
|           areaStyle: 'rgba(255,234,47,0.2)', | ||||
|           unit: '次', | ||||
|         }, | ||||
|       } | ||||
|       return { | ||||
|         grid: { | ||||
|           top: "5%", | ||||
|           left: "16%", | ||||
|           right: "3%", | ||||
|           bottom: "12%" | ||||
|         }, | ||||
|         xAxis: { | ||||
|           show: true, | ||||
|           boundaryGap: false, | ||||
|           type: 'category', | ||||
|           axisLabel: { | ||||
|             show: true, | ||||
|             textStyle: { | ||||
|               color: "#5E9CEA", | ||||
|               fontSize: 12 | ||||
|             } | ||||
|           }, | ||||
|           axisLine: { | ||||
|             show: false | ||||
|           }, | ||||
|           axisTick: { | ||||
|             show: false | ||||
|           }, | ||||
|           data: opt[type]["xData"] | ||||
|         }, | ||||
|         yAxis: { | ||||
|           type: 'value', | ||||
|           show: true, | ||||
|           axisTick: { | ||||
|             show: false | ||||
|           }, | ||||
|           axisLine: { | ||||
|             show: false | ||||
|           }, | ||||
|           splitLine: { | ||||
|             show: true, | ||||
|             lineStyle: { | ||||
|               color: ['#103066'], | ||||
|             } | ||||
|           }, | ||||
|           axisLabel: { | ||||
|             show: true, | ||||
|             formatter: (val) => `${val}${opt[type]["unit"]}`, | ||||
|             textStyle: { | ||||
|               color: "#5E9CEA", | ||||
|               fontSize: 12 | ||||
|             } | ||||
|           }, | ||||
|         }, | ||||
|         series: [{ | ||||
|           symbol: "none", | ||||
|           data: opt[type]["yData"], | ||||
|           type: 'line', | ||||
|           itemStyle: { | ||||
|             normal: { | ||||
|               color: opt[type]["color"], | ||||
|               areaStyle: { | ||||
|                 color: { | ||||
|                   type: 'linear', x2: 0, y2: 1, colorStops: [ | ||||
|                     {offset: 0, color: opt[type]["areaStyle"]}, {offset: 1, color: '#000000'}] | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }] | ||||
|       } | ||||
|     }, | ||||
|     getWebSdkUrlForScreen() { | ||||
|       this.instance.post(`/app/appzyvideoequipment/getWebSdkUrlForTianQiaoScreen`).then(res => { | ||||
|         if (res.code == 0) { | ||||
|           this.videoData = res.data | ||||
|           this.flag = true | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   beforeDestroy() { | ||||
|     this.interval && clearInterval(this.interval); | ||||
|   }, | ||||
|   mounted() { | ||||
|     // this.getWebSdkUrlForScreen() | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppVideoMonitoringDV { | ||||
|   height: 100%; | ||||
|   padding: 6px 0 10px; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 24px; | ||||
|  | ||||
|   .body { | ||||
|     height: 100%; | ||||
|  | ||||
|     .left-wrap { | ||||
|       width: 307px; | ||||
|       height: 100%; | ||||
|  | ||||
|       .left-top { | ||||
|         width: 100%; | ||||
|         background-image: url("../assets/videoMonitor/box1.png"); | ||||
|         background-size: 100% 100%; | ||||
|         position: relative; | ||||
|         overflow: hidden; | ||||
|  | ||||
|         .table { | ||||
|           box-sizing: border-box; | ||||
|           padding: 63px 17px 17px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .left-bottom { | ||||
|         width: 100%; | ||||
|         height: 311px; | ||||
|         background-image: url("../assets/videoMonitor/box2.png"); | ||||
|         background-size: 100% 100%; | ||||
|         margin-top: 7px; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         position: relative; | ||||
|  | ||||
|         .AiMap { | ||||
|           width: 274px; | ||||
|           height: 247px; | ||||
|           margin-top: 40px; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .center-wrap { | ||||
|       width: 1183px; | ||||
|       height: 100%; | ||||
|  | ||||
|       .card { | ||||
|         height: 93.3px; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: center; | ||||
|         background-image: url("../assets/videoMonitor/card.png"); | ||||
|         background-size: 100% 100%; | ||||
|         margin-right: 24px; | ||||
|  | ||||
|         &:last-child { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|  | ||||
|         & > span:first-child { | ||||
|           font-size: 20px; | ||||
|           font-weight: 400; | ||||
|           color: #FFFFFF; | ||||
|         } | ||||
|  | ||||
|         & > span:last-child { | ||||
|           font-size: 38px; | ||||
|           font-family: dineng, serif; | ||||
|           font-weight: bold; | ||||
|           color: #00EDFF; | ||||
|           margin-left: 13px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .center-bottom { | ||||
|         width: 100%; | ||||
|         height: 789px; | ||||
|         background-image: url("../assets/videoMonitor/middlebox.png"); | ||||
|         background-size: 100% 100%; | ||||
|         margin-top: 40px; | ||||
|         position: relative; | ||||
|         box-sizing: border-box; | ||||
|         padding: 61px; | ||||
|  | ||||
|         .video-wrap { | ||||
|           width: 100%; | ||||
|           height: 344px; | ||||
|           display: flex; | ||||
|           justify-content: space-between; | ||||
|           margin-bottom: 12px; | ||||
|  | ||||
|           .item { | ||||
|             .video { | ||||
|               width: 522px; | ||||
|               height: 296px; | ||||
|               object-fit: fill; | ||||
|               vertical-align: bottom; | ||||
|               border: 2px solid #122C7D; | ||||
|             } | ||||
|  | ||||
|             .info { | ||||
|               height: 48px; | ||||
|               display: flex; | ||||
|               align-items: center; | ||||
|               justify-content: space-between; | ||||
|               box-sizing: border-box; | ||||
|               padding: 0 12px; | ||||
|               background-color: #071153; | ||||
|               font-size: 14px; | ||||
|               color: #FFFFFF; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .right-wrap { | ||||
|       width: 297px; | ||||
|       height: 100%; | ||||
|  | ||||
|       .right-top { | ||||
|         width: 100%; | ||||
|         height: 333px; | ||||
|         background-image: url("../assets/videoMonitor/box3.png"); | ||||
|         background-size: 100% 100%; | ||||
|         position: relative; | ||||
|         overflow: hidden; | ||||
|  | ||||
|         .total { | ||||
|           font-size: 16px; | ||||
|           color: #979AB7; | ||||
|           display: inline-block; | ||||
|           margin: 65px 0 16px 23px; | ||||
|  | ||||
|           & > span:nth-child(1) { | ||||
|             font-size: 28px; | ||||
|             font-family: dineng, serif; | ||||
|             font-weight: bold; | ||||
|             color: #01CAFF; | ||||
|           } | ||||
|  | ||||
|           & > span:nth-child(2) { | ||||
|             font-size: 16px; | ||||
|             color: #01CAFF; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .total-table { | ||||
|           height: 200px; | ||||
|           box-sizing: border-box; | ||||
|           padding: 0 23px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .right-middle, .right-bottom { | ||||
|         width: 100%; | ||||
|         height: 276px; | ||||
|         background-image: url("../assets/videoMonitor/box4.png"); | ||||
|         background-size: 100% 100%; | ||||
|         margin: 19px 0; | ||||
|         position: relative; | ||||
|         overflow: hidden; | ||||
|  | ||||
|         .tag { | ||||
|           margin: 28px 18px 0 0; | ||||
|           display: flex; | ||||
|           justify-content: flex-end; | ||||
|           font-size: 12px; | ||||
|           color: #5E9CEA; | ||||
|  | ||||
|           & > span { | ||||
|             font-size: 12px; | ||||
|             color: #FFFFFF; | ||||
|             display: inline-block; | ||||
|             width: 34px; | ||||
|             height: 17px; | ||||
|             text-align: center; | ||||
|             line-height: 18px; | ||||
|             margin-left: 14px; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         ::v-deep .AiEchart { | ||||
|           width: 251px; | ||||
|           height: 175px; | ||||
|           margin: 11px auto 0; | ||||
|         } | ||||
|  | ||||
|         .info { | ||||
|           font-size: 12px; | ||||
|           color: #FFFFFF; | ||||
|           line-height: 24px; | ||||
|           box-sizing: border-box; | ||||
|           padding: 15px 19px 0; | ||||
|  | ||||
|           & > span:nth-child(2n+1) { | ||||
|             font-size: 18px; | ||||
|             font-weight: 400; | ||||
|             line-height: 24px; | ||||
|             color: #FFE930; | ||||
|           } | ||||
|  | ||||
|           & > span:nth-child(2n) { | ||||
|             font-size: 14px; | ||||
|             font-weight: 400; | ||||
|             color: #FFE930; | ||||
|             line-height: 24px; | ||||
|             margin: 0 5px; | ||||
|           } | ||||
|  | ||||
|           & > span:nth-child(2) { | ||||
|             margin-right: 22px; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .right-bottom { | ||||
|         margin: 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .label { | ||||
|     position: absolute; | ||||
|     left: 24px; | ||||
|     top: 23px; | ||||
|     font-size: 16px; | ||||
|     font-weight: 600; | ||||
|     color: #FFFFFF; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .index { | ||||
|     background-color: transparent !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .header { | ||||
|     background: url("../assets/videoMonitor/titlebox.png"); | ||||
|   } | ||||
|  | ||||
|   ::v-deep .row-item div:nth-child(3) { | ||||
|     font-size: 13px; | ||||
|     color: #00CDFF; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										275
									
								
								packages/bigscreen/dv/apps/components/AiGrid.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,275 @@ | ||||
| <template> | ||||
|   <div class="AiGrid" ref="container"> | ||||
|     <div | ||||
|         class="AiGrid-wrapper" | ||||
|         ref="tree" | ||||
|         id="tree" | ||||
|         :style="{left: x, top: y, transform: `scale(${scale}) translate(-50%, -50%) `, 'transform-origin': `${0} ${0}`}"> | ||||
|       <ai-okr-tree | ||||
|           :props="props" | ||||
|           node-key="id" | ||||
|           show-collapsable | ||||
|           show-node-num | ||||
|           current-lable-class-name="aigrid-active" | ||||
|           :default-expanded-keys="defaultExpandedKeys" | ||||
|           ref="VueOkrTree" | ||||
|           @node-click="onNodeClick" | ||||
|           :data="treeData"> | ||||
|       </ai-okr-tree> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'AiGrid', | ||||
|   props: ['instance'], | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       scale: 1, | ||||
|       x: '50%', | ||||
|       y: '50%', | ||||
|       defaultExpandedKeys: [], | ||||
|       treeData: [], | ||||
|       props: { | ||||
|         label: 'girdName', | ||||
|         children: 'children' | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     this.bindEvent() | ||||
|     this.getPartyOrg() | ||||
|   }, | ||||
|  | ||||
|   destroyed() { | ||||
|     document.querySelector('body').removeEventListener('mousewheel', this.onMousewheel) | ||||
|     document.querySelector('body').removeEventListener('mouseup', this.onMouseUp) | ||||
|     document.querySelector('body').removeEventListener('mousedown', this.onMousedown) | ||||
|     document.querySelector('body').removeEventListener('mousemove', this.onMouseMove) | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     bindEvent() { | ||||
|       document.querySelector('body').addEventListener('mousewheel', this.onMousewheel, true) | ||||
|       document.querySelector('body').addEventListener('mouseup', this.onMouseUp, true) | ||||
|       document.querySelector('body').addEventListener('mousedown', this.onMousedown, true) | ||||
|       document.querySelector('body').addEventListener('mousemove', this.onMouseMove, true) | ||||
|     }, | ||||
|  | ||||
|     onMousewheel(event) { | ||||
|       if (!event) return false | ||||
|       const elClass = event.target.className | ||||
|       if (elClass === 'tree' || elClass === 'middle' || (elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) { | ||||
|         var dir = event.deltaY > 0 ? 'Up' : 'Down' | ||||
|         if (dir === 'Up') { | ||||
|           this.scale = this.scale - 0.12 <= 0.1 ? 0.1 : this.scale - 0.12 | ||||
|         } else { | ||||
|           this.scale = this.scale + 0.12 | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       return false | ||||
|     }, | ||||
|  | ||||
|     onMousedown(e) { | ||||
|       const elClass = e.target.className | ||||
|       if ((elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) { | ||||
|         const left = document.querySelector('#tree').offsetLeft | ||||
|         const top = document.querySelector('#tree').offsetTop | ||||
|         this.isMove = true | ||||
|         this.offsetX = e.clientX - left | ||||
|         this.offsetY = e.clientY - top | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     onMouseMove(e) { | ||||
|       if (!this.isMove) return | ||||
|  | ||||
|       this.x = (e.clientX - this.offsetX) + 'px' | ||||
|       this.y = (e.clientY - this.offsetY) + 'px' | ||||
|     }, | ||||
|  | ||||
|     onMouseUp() { | ||||
|       this.isMove = false | ||||
|     }, | ||||
|  | ||||
|     onNodeClick(e) { | ||||
|       this.$emit('nodeClick', e) | ||||
|     }, | ||||
|  | ||||
|     getPartyOrg() { | ||||
|       this.instance.post('/app/appgirdinfo/listAll3').then(res => { | ||||
|         if (res.code === 0) { | ||||
|           this.treeData = res.data.filter(e => !e.parentGirdId) | ||||
|           const parentGirdId = this.treeData[0].id | ||||
|  | ||||
|           this.treeData.map(p => this.addChild(p, res.data.map(v => { | ||||
|             if (v.id === parentGirdId) { | ||||
|               this.defaultExpandedKeys.push(v.id) | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|               ...v, | ||||
|               girdName: v.girdName.substr(0, 11) | ||||
|             } | ||||
|           }), { | ||||
|             parent: 'parentGirdId' | ||||
|           })) | ||||
|  | ||||
|           this.$nextTick(() => { | ||||
|             this.autoScale() | ||||
|             this.$refs.VueOkrTree.setCurrentKey(parentGirdId) | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     autoScale() { | ||||
|       const treeWidth = this.$refs.tree.offsetWidth | ||||
|       const containerWidth = this.$refs.container.offsetWidth - 100 | ||||
|       this.scale = treeWidth < containerWidth ? 1 : containerWidth / treeWidth | ||||
|       this.x = '50%' | ||||
|       this.y = '50%' | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AiGrid { | ||||
|   position: relative; | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   overflow: hidden; | ||||
|   box-sizing: border-box; | ||||
|  | ||||
|   .AiGrid-wrapper { | ||||
|     display: flex; | ||||
|     position: absolute; | ||||
|     align-items: center; | ||||
|     left: 50%; | ||||
|     top: 50%; | ||||
|     padding: 20px; | ||||
|     overflow: hidden; | ||||
|     width: max-content; | ||||
|     height: 300%; | ||||
|   } | ||||
|  | ||||
|   .aigrid-active { | ||||
|     background: linear-gradient(180deg, #42C6CE 0%, #307598 100%); | ||||
|   } | ||||
|  | ||||
|   ::v-deep .org-chart-container { | ||||
|     color: #FFFFFF; | ||||
|     font-size: 16px; | ||||
|  | ||||
|     .org-chart-node-children { | ||||
|       display: flex; | ||||
|       justify-content: center; | ||||
|       float: initial !important; | ||||
|     } | ||||
|  | ||||
|     .org-chart-node-btn { | ||||
|       border: 1px solid #23A0AC !important; | ||||
|       font-size: 16px; | ||||
|       font-weight: bold; | ||||
|       background: #071030; | ||||
|       color: #FF9A02; | ||||
|  | ||||
|       &:after, &::before { | ||||
|         display: none; | ||||
|       } | ||||
|  | ||||
|       &.expanded::before { | ||||
|         display: block; | ||||
|         position: absolute; | ||||
|         top: 50%; | ||||
|         left: 4px; | ||||
|         right: 4px; | ||||
|         height: 0; | ||||
|         border-top: 1px solid #FF9A02; | ||||
|         content: ""; | ||||
|       } | ||||
|  | ||||
|       .org-chart-node-btn-text { | ||||
|         background: transparent; | ||||
|         color: #FF9A02; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .org-chart-node { | ||||
|       // overflow: hidden; | ||||
|  | ||||
|       .org-chart-node-label { | ||||
|         width: 40px; | ||||
|         height: 254px; | ||||
|         margin-right: 15px; | ||||
|         padding: 0 0; | ||||
|  | ||||
|         .org-chart-node-label-inner { | ||||
|           width: 40px !important; | ||||
|           height: 254px !important; | ||||
|           border: 1px solid; | ||||
|           background: linear-gradient(180deg, rgba(69, 210, 218, 0.2500) 0%, rgba(69, 210, 218, 0.1000) 100%) !important; | ||||
|           border-image: linear-gradient(180deg, rgba(5, 185, 203, 1), rgba(73, 214, 207, 1)) 1 1 !important; | ||||
|           line-height: 1.3; | ||||
|           padding: 10px 8px; | ||||
|           text-align: center; | ||||
|           font-size: 18px; | ||||
|           color: rgba(255, 255, 255, 0.8); | ||||
|  | ||||
|           &.aigrid-active { | ||||
|             background: linear-gradient(180deg, #42C6CE 0%, #307598 100%) !important; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         &.is-root-label { | ||||
|           width: auto !important; | ||||
|           min-width: 240px; | ||||
|           height: 40px !important; | ||||
|           line-height: 40px !important; | ||||
|           min-height: 40px !important; | ||||
|           text-align: center; | ||||
|  | ||||
|           .org-chart-node-label-inner { | ||||
|             padding: 0 30px !important; | ||||
|             color: #fff !important; | ||||
|             width: auto !important; | ||||
|             min-width: 240px; | ||||
|             height: 40px !important; | ||||
|             line-height: 40px !important; | ||||
|             min-height: 40px !important; | ||||
|             text-align: center; | ||||
|             background: linear-gradient(180deg, rgba(69, 210, 218, 0.2500) 0%, rgba(69, 210, 218, 0.1000) 100%) !important; | ||||
|             border-image: linear-gradient(180deg, rgba(5, 185, 203, 1), rgba(73, 214, 207, 1)) 1 1 !important; | ||||
|  | ||||
|             &.aigrid-active { | ||||
|               background: linear-gradient(180deg, #42C6CE 0%, #307598 100%) !important; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       &:last-child { | ||||
|         .org-chart-node-label { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .org-chart-node-children:before, .org-chart-node:after, .org-chart-node:last-child:before, | ||||
|     .org-chart-node.is-leaf:before { | ||||
|       border-radius: 0; | ||||
|       border-color: #23A0AC !important; | ||||
|     } | ||||
|  | ||||
|     .vertical .org-chart-node:after, .vertical .org-chart-node:before { | ||||
|       border-radius: 0; | ||||
|       border-color: #23A0AC !important; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										133
									
								
								packages/bigscreen/dv/apps/components/DonutChart.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,133 @@ | ||||
| <template> | ||||
|   <div class="DonutChart" :id="id"> | ||||
|     <canvas :id="canvasId"></canvas> | ||||
|     <div class="DonutChart-text"> | ||||
|       <span>{{ ratio || 0 }}%</span> | ||||
|       <i>{{ text }}</i> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     props: ['ratio', 'text'], | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         id: `DonutChart-${Math.ceil(Math.random() * 10000)}`, | ||||
|         canvasId: `DonutChartCanvas-${Math.ceil(Math.random() * 10000)}`, | ||||
|         canvasWidth: 90, | ||||
|         canvasHeight: 90 | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.$nextTick(() => { | ||||
|         this.init() | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       drawLine(ctx, options) { | ||||
|         const { beginX, beginY, endX, endY, lineColor, lineWidth } = options | ||||
|         ctx.lineWidth = lineWidth | ||||
|         ctx.strokeStyle = lineColor | ||||
|         ctx.beginPath() | ||||
|         ctx.moveTo(beginX, beginY) | ||||
|         ctx.lineTo(endX, endY) | ||||
|         ctx.closePath() | ||||
|         ctx.stroke() | ||||
|       }, | ||||
|  | ||||
|       angle (a, i, ox, oy, or) { | ||||
|         var hudu = (2 * Math.PI / 360) * a * i | ||||
|         var x = ox + Math.sin(hudu) * or | ||||
|         var y = oy - Math.cos(hudu) * or | ||||
|         return x + '_' + y | ||||
|       }, | ||||
|  | ||||
|       mapColor (value) { | ||||
|         if (value < 25) { | ||||
|           return '#FFC139' | ||||
|         } | ||||
|  | ||||
|         if (value < 50) { | ||||
|           return '#21E03E' | ||||
|         } | ||||
|  | ||||
|         return '#05C8FF' | ||||
|       }, | ||||
|  | ||||
|       init () { | ||||
|         const ctx = document.querySelector(`#${this.canvasId}`).getContext('2d') | ||||
|         const canvasWidth = document.querySelector(`#${this.id}`).offsetWidth | ||||
|         const canvasHeight = document.querySelector(`#${this.id}`).offsetHeight | ||||
|         const angle = this.ratio / 100 * 2 | ||||
|         let radian = 0 | ||||
|  | ||||
|         ctx.width = canvasWidth | ||||
|         ctx.height = canvasHeight | ||||
|         const x = canvasWidth / 2 | ||||
|         const y = canvasHeight / 2 | ||||
|         ctx.lineWidth = 2 | ||||
|         ctx.strokeStyle = '#383f56' | ||||
|         ctx.beginPath(); | ||||
|         ctx.arc(x, y, x - 3, 0, 2 * Math.PI) | ||||
|         ctx.stroke() | ||||
|  | ||||
|         ctx.beginPath() | ||||
|         ctx.lineWidth = 4 | ||||
|         ctx.strokeStyle = 'rgba(76, 202, 227, 1)' | ||||
|  | ||||
|         if (this.ratio < 25) { | ||||
|           radian = 3 / 2 + angle | ||||
|           ctx.arc(x, y, x - 4, Math.PI + Math.PI / 2, Math.PI * radian, false) | ||||
|         } else if (this.ratio === 100) { | ||||
|           ctx.arc(x, y, x - 4, 0, Math.PI * 2) | ||||
|         } else { | ||||
|           radian = (this.ratio - 25) / 100 * 2 | ||||
|           ctx.arc(x, y, x - 4, Math.PI + Math.PI / 2, Math.PI * radian, false) | ||||
|         } | ||||
|         ctx.stroke() | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .DonutChart { | ||||
|     position: relative; | ||||
|     width: 84px; | ||||
|     height: 84px; | ||||
|     overflow: hidden; | ||||
|  | ||||
|     .DonutChart-text { | ||||
|       display: flex; | ||||
|       position: absolute; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       flex-direction: column; | ||||
|       top: 50%; | ||||
|       left: 50%; | ||||
|       z-index: 1; | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|       line-height: 1; | ||||
|       transform: translate(-50%, -50%); | ||||
|  | ||||
|       span { | ||||
|         margin-bottom: 8px; | ||||
|         font-size: 20px; | ||||
|         font-weight: bold; | ||||
|         color: #fff; | ||||
|         font-style: oblique; | ||||
|       } | ||||
|  | ||||
|       i { | ||||
|         font-size: 12px; | ||||
|         font-style: normal; | ||||
|         color: rgba(42, 183, 209, 1); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										483
									
								
								packages/bigscreen/dv/apps/components/PdGrid.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,483 @@ | ||||
| <template> | ||||
|   <div class="pdgrid"> | ||||
|     <div class="pdgrid-title"> | ||||
|       <h2>{{ currGird }}</h2> | ||||
|     </div> | ||||
|     <div class="pdgrid-grid__title" @click="isShowGrid2 = true"> | ||||
|       <h2 :title="girdName2">{{ girdName2 }}</h2> | ||||
|     </div> | ||||
|     <div class="pdgrid-body"> | ||||
|       <div class="pdgrid-body__item" @click="isShowGrid3 = true"> | ||||
|         <h2>{{ girdNum3 }}</h2> | ||||
|         <div class="bottom"> | ||||
|           <i></i> | ||||
|           <p>{{ girdName3 }}</p> | ||||
|           <i class="right"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="pdgrid-body__item" @click.stop="isShowGrid4 = true"> | ||||
|         <h2>{{ girdNum4 }}</h2> | ||||
|         <div class="bottom"> | ||||
|           <i></i> | ||||
|           <p>{{ girdName4 }}</p> | ||||
|           <i class="right"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="pdgrid-body__item" @click="isShowGrid5 = true"> | ||||
|         <h2>{{ girdNum5 }}</h2> | ||||
|         <div class="bottom"> | ||||
|           <i></i> | ||||
|           <p>{{ girdName5 }}</p> | ||||
|           <i class="right"></i> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <transition name="fade"> | ||||
|       <div class="grid-dialog" v-show="isShowGrid2"> | ||||
|         <div class="mask" @click="isShowGrid2 = false"></div> | ||||
|         <div class="grid-container"> | ||||
|           <h2 :title="girdName2">{{ girdName2 }}</h2> | ||||
|           <div class="grid-list"> | ||||
|             <div | ||||
|               :class="[currIndex2 === index ? 'grid-active' : '']" | ||||
|               v-for="(item, index) in girdInfoList2" | ||||
|               :key="index" | ||||
|               :title="item.girdName" | ||||
|               @click.stop="onGrid2Click(item, index)"> | ||||
|               {{ item.girdName }} | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </transition> | ||||
|     <transition name="fade"> | ||||
|       <div class="grid-dialog" v-show="isShowGrid3"> | ||||
|         <div class="mask" @click="isShowGrid3 = false"></div> | ||||
|         <div class="grid-container"> | ||||
|           <h2 :title="girdName3">{{ girdName3 }}</h2> | ||||
|           <div class="grid-list"> | ||||
|             <div | ||||
|               :class="[currIndex3 === index ? 'grid-active' : '']" | ||||
|               v-for="(item, index) in girdInfoList3" | ||||
|               :key="index" | ||||
|               :title="item.girdName" | ||||
|               @click.stop="onGrid3Click(item, index)"> | ||||
|               {{ item.girdName }} | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </transition> | ||||
|     <transition name="fade"> | ||||
|       <div class="grid-dialog" v-show="isShowGrid4"> | ||||
|         <div class="mask" @click="isShowGrid4 = false"></div> | ||||
|         <div class="grid-container"> | ||||
|           <h2 :title="girdName4">{{ girdName4 }}</h2> | ||||
|           <div class="grid-list"> | ||||
|             <div | ||||
|               :class="[currIndex4 === index ? 'grid-active' : '']" | ||||
|               v-for="(item, index) in girdInfoList4" | ||||
|               :key="index" | ||||
|               :title="item.girdName" | ||||
|               @click.stop="onGrid4Click(item, index)"> | ||||
|               {{ item.girdName }} | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </transition> | ||||
|     <transition name="fade"> | ||||
|       <div class="grid-dialog" v-show="isShowGrid5"> | ||||
|         <div class="mask" @click="isShowGrid5 = false"></div> | ||||
|         <div class="grid-container"> | ||||
|           <h2 :title="girdName5">{{ girdName5 }}</h2> | ||||
|           <div class="grid-list"> | ||||
|             <div | ||||
|               :class="[currIndex5 === index ? 'grid-active' : '']" | ||||
|               v-for="(item, index) in girdInfoList5" | ||||
|               :key="index" | ||||
|               :title="item.girdName" | ||||
|               @click.stop="onGrid5Click(item, index)"> | ||||
|               {{ item.girdName }} | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </transition> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
|   export default { | ||||
|     name: 'pdgrid', | ||||
|  | ||||
|     props: ['instance'], | ||||
|  | ||||
|     data () { | ||||
|       return { | ||||
|         isShowGrid2: false, | ||||
|         isShowGrid3: false, | ||||
|         isShowGrid4: false, | ||||
|         isShowGrid5: false, | ||||
|         currIndex2: 0, | ||||
|         currIndex3: 0, | ||||
|         currIndex4: 0, | ||||
|         currIndex5: 0, | ||||
|         girdInfoList2: [], | ||||
|         girdInfoList3: [], | ||||
|         girdInfoList4: [], | ||||
|         girdInfoList5: [], | ||||
|         girdName2: '', | ||||
|         girdName3: '', | ||||
|         girdName4: '', | ||||
|         girdName5: '', | ||||
|         girdNum3: 0, | ||||
|         girdNum4: 0, | ||||
|         girdNum5: 0, | ||||
|         currGird: '' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     mounted () { | ||||
|       this.$nextTick(() => { | ||||
|         document.addEventListener('keydown', this.onKeyDown) | ||||
|       }) | ||||
|       this.getInfo() | ||||
|     }, | ||||
|  | ||||
|     destroyed () { | ||||
|       document.removeEventListener('keydown', this.onKeyDown) | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|       onKeyDown (e) { | ||||
|         if (e.keyCode == 27) { | ||||
|           this.isShowGrid2 = false | ||||
|           this.isShowGrid3 = false | ||||
|           this.isShowGrid4 = false | ||||
|           this.isShowGrid5 = false | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       onGrid2Click (item, index) { | ||||
|         this.currIndex2 = index | ||||
|         this.girdName2 = item.girdName | ||||
|         this.currIndex3 = -1 | ||||
|         this.currIndex4 = -1 | ||||
|         this.currIndex5 = -1 | ||||
|         this.isShowGrid2 = false | ||||
|         this.girdInfoList3 = [] | ||||
|         this.girdInfoList4 = [] | ||||
|         this.girdInfoList5 = [] | ||||
|         this.$emit('nodeClick', item.id) | ||||
|  | ||||
|         this.currGird = item.girdName | ||||
|         this.getInfo(item.id) | ||||
|       }, | ||||
|  | ||||
|       onGrid3Click (item, index) { | ||||
|         this.currIndex3 = index | ||||
|         this.girdName3 = item.girdName | ||||
|         this.currIndex4 = -1 | ||||
|         this.currIndex5 = -1 | ||||
|         this.girdNum3 = 1 | ||||
|         this.isShowGrid3 = false | ||||
|         this.$emit('nodeClick', item.id) | ||||
|         this.girdInfoList4 = [] | ||||
|         this.girdInfoList5 = [] | ||||
|         this.currGird = item.girdName | ||||
|         this.getInfo(item.id) | ||||
|       }, | ||||
|  | ||||
|       onGrid4Click (item, index) { | ||||
|         this.currIndex4 = index | ||||
|         this.girdName4 = item.girdName | ||||
|         this.currIndex5 = -1 | ||||
|         this.girdNum4 = 1 | ||||
|         this.isShowGrid4 = false | ||||
|         this.$emit('nodeClick', item.id) | ||||
|         this.girdInfoList5 = [] | ||||
|  | ||||
|         this.currGird = item.girdName | ||||
|         this.getInfo(item.id) | ||||
|       }, | ||||
|  | ||||
|       onGrid5Click (item, index) { | ||||
|         this.currIndex5 = index | ||||
|         this.girdName5 = item.girdName | ||||
|         this.isShowGrid5 = false | ||||
|         this.girdNum5 = 1 | ||||
|         this.$emit('nodeClick', item.id) | ||||
|  | ||||
|         this.currGird = item.girdName | ||||
|         this.getInfo(item.id) | ||||
|       }, | ||||
|  | ||||
|       getInfo (id) { | ||||
|         this.instance.post(`/app/appgirdinfo/queryPdDetailByGirdId?id=${id || ''}`).then(res => { | ||||
|           if (res.code === 0) { | ||||
|             res.data.girdInfoList2 && (this.girdInfoList2 = res.data.girdInfoList2) | ||||
|             res.data.girdInfoList3 && (this.girdInfoList3 = res.data.girdInfoList3) | ||||
|             res.data.girdInfoList4 && (this.girdInfoList4 = res.data.girdInfoList4) | ||||
|             res.data.girdInfoList5 && (this.girdInfoList5 = res.data.girdInfoList5) | ||||
|  | ||||
|             res.data.girdName2 && (this.girdName2 = res.data.girdName2) | ||||
|             res.data.girdName3 && (this.girdName3 = res.data.girdName3) | ||||
|             res.data.girdName4 && (this.girdName4 = res.data.girdName4) | ||||
|             res.data.girdName5 && (this.girdName5 = res.data.girdName5) | ||||
|  | ||||
|             res.data.girdNum3 != null && (this.girdNum3 = res.data.girdNum3) | ||||
|             res.data.girdNum4 != null && (this.girdNum4 = res.data.girdNum4) | ||||
|             res.data.girdNum5 != null && (this.girdNum5 = res.data.girdNum5) | ||||
|  | ||||
|             if (!id) { | ||||
|               this.currGird = res.data.girdName2 | ||||
|               this.currIndex2 = res.data.girdInfoList2.findIndex(v => res.data.girdName2 === v.girdName) | ||||
|             } | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   .pdgrid { | ||||
|     position: relative; | ||||
|     width: 100%; | ||||
|     height: 100%; | ||||
|     overflow: hidden; | ||||
|     box-sizing: border-box; | ||||
|     background: url(https://cdn.cunwuyun.cn/dvcp/dv/pddv/middle-bg.png) no-repeat center; | ||||
|     background-size: contain; | ||||
|  | ||||
|     .fade-enter-active, .fade-leave-active { | ||||
|       transition: opacity .3s ease-in-out; | ||||
|     } | ||||
|     .fade-enter, .fade-leave-to { | ||||
|       opacity: 0; | ||||
|     } | ||||
|  | ||||
|     * { | ||||
|       box-sizing: border-box; | ||||
|     } | ||||
|  | ||||
|     .pdgrid-grid__title { | ||||
|       position: absolute; | ||||
|       top: 40px; | ||||
|       left: 50%; | ||||
|       width: 271px; | ||||
|       height: 53px; | ||||
|       line-height: 53px; | ||||
|       text-align: center; | ||||
|       background: url(https://cdn.cunwuyun.cn/dvcp/dv/pddv/grid-title-sbg.png) no-repeat center; | ||||
|       background-size: 100% 100%; | ||||
|       cursor: pointer; | ||||
|       transform: translateX(-50%); | ||||
|       transition: opacity ease 0.3s; | ||||
|  | ||||
|       &:hover { | ||||
|         opacity: 0.8; | ||||
|       } | ||||
|  | ||||
|       h2 { | ||||
|         width: 182px; | ||||
|         margin: 0 auto; | ||||
|         white-space: nowrap; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|         color: #FFFFFF; | ||||
|         font-size: 21px; | ||||
|         text-shadow: 0px 0px 13px rgb(59 182 255 / 80%); | ||||
|         background: #fff; | ||||
|         -webkit-background-clip: text; | ||||
|         -webkit-text-fill-color: transparent; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .pdgrid-title { | ||||
|       position: absolute; | ||||
|       top: 200px; | ||||
|       left: 50%; | ||||
|       min-width: 640px; | ||||
|       height: 80px; | ||||
|       line-height: 80px; | ||||
|       text-align: center; | ||||
|       background: url(https://cdn.cunwuyun.cn/dvcp/dv/pddv/middle-titlebg.png) no-repeat center; | ||||
|       background-size: 100% 100%; | ||||
|       transform: translateX(-50%); | ||||
|  | ||||
|       h2 { | ||||
|         color: #FFFFFF; | ||||
|         font-size: 22px; | ||||
|         white-space: nowrap; | ||||
|         text-shadow: 0px 0px 13px rgb(59 182 255 / 80%); | ||||
|         background: #fff; | ||||
|         -webkit-background-clip: text; | ||||
|         -webkit-text-fill-color: transparent; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .pdgrid-body { | ||||
|       display: flex; | ||||
|       position: absolute; | ||||
|       justify-content: space-between; | ||||
|       bottom: 200px; | ||||
|       left: 0; | ||||
|       width: 100%; | ||||
|       padding: 0 112px; | ||||
|  | ||||
|       .pdgrid-body__item { | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         width: 200px; | ||||
|         height: 187px; | ||||
|         align-items: center; | ||||
|         padding-top: 71px; | ||||
|         cursor: pointer; | ||||
|         background: url(https://cdn.cunwuyun.cn/dvcp/dv/pddv/item-bg.png) no-repeat center; | ||||
|         background-size: 100% 100%; | ||||
|         transition: opacity ease 0.3s; | ||||
|  | ||||
|         &:hover { | ||||
|           opacity: 0.8; | ||||
|         } | ||||
|  | ||||
|         &:nth-of-type(2) { | ||||
|           position: relative; | ||||
|           top: 67px; | ||||
|         } | ||||
|  | ||||
|         h2 { | ||||
|           font-size: 36px; | ||||
|           color: #FFFFFF; | ||||
|           text-shadow: 0px 0px 13px rgb(59 182 255 / 80%); | ||||
|           background: #fff; | ||||
|           -webkit-background-clip: text; | ||||
|           -webkit-text-fill-color: transparent; | ||||
|         } | ||||
|  | ||||
|         p { | ||||
|           max-width: 164px; | ||||
|           margin-top: 4px; | ||||
|           padding: 0 16px; | ||||
|           font-size: 16px; | ||||
|           color: #FFFFFF; | ||||
|           text-shadow: 0px 0px 13px rgb(59 182 255 / 80%); | ||||
|           background: #fff; | ||||
|           -webkit-background-clip: text; | ||||
|           font-weight: 600; | ||||
|           white-space: nowrap; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           -webkit-text-fill-color: transparent; | ||||
|         } | ||||
|  | ||||
|         .bottom { | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|  | ||||
|           i { | ||||
|             width: 0px; | ||||
|             height: 0px; | ||||
|             border: 6px solid transparent; | ||||
|             border-top-color: transparent; | ||||
|             border-bottom-color: transparent; | ||||
|             border-left-color: transparent; | ||||
|             border-right-color: #FFCB42; | ||||
|  | ||||
|             &.right { | ||||
|               width: 0px; | ||||
|               height: 0px; | ||||
|               border: 6px solid transparent; | ||||
|               border-top-color: transparent; | ||||
|               border-bottom-color: transparent; | ||||
|               border-left-color: #FFCB42; | ||||
|               border-right-color: transparent; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .grid-dialog { | ||||
|       position: fixed; | ||||
|       top: 0; | ||||
|       left: 0; | ||||
|       z-index: 111; | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|  | ||||
|       & > .mask { | ||||
|         position: absolute; | ||||
|         left: 0; | ||||
|         top: 0; | ||||
|         z-index: 1; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         background: rgba(0, 0, 0, 0.5); | ||||
|       } | ||||
|  | ||||
|       .grid-container { | ||||
|         display: flex; | ||||
|         position: absolute; | ||||
|         flex-direction: column; | ||||
|         left: 50%; | ||||
|         top: 50%; | ||||
|         z-index: 2; | ||||
|         width: 640px; | ||||
|         height: 640px; | ||||
|         background: rgba(7,13,41,0.9); | ||||
|         border: 1px solid #144662; | ||||
|         transform: translate(-50%, -50%); | ||||
|  | ||||
|         & > h2 { | ||||
|           width: 100%; | ||||
|           height: 67px; | ||||
|           line-height: 67px; | ||||
|           padding: 0 20px; | ||||
|           text-align: center; | ||||
|           color: #FFFFFF; | ||||
|           font-size: 24px; | ||||
|           white-space: nowrap; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|           text-shadow: 0px 0px 13px rgb(59 182 255 / 80%); | ||||
|           background: url(https://cdn.cunwuyun.cn/dvcp/dv/pddv/grid-title-bg.png) no-repeat center; | ||||
|           background-size: 100% 100%; | ||||
|         } | ||||
|  | ||||
|         .grid-list { | ||||
|           flex: 1; | ||||
|           overflow-y: auto; | ||||
|  | ||||
|           & > div { | ||||
|             height: 67px; | ||||
|             line-height: 67px; | ||||
|             padding: 0 20px; | ||||
|             text-align: center; | ||||
|             color: #FFFFFF; | ||||
|             font-size: 27px; | ||||
|             cursor: pointer; | ||||
|             white-space: nowrap; | ||||
|             overflow: hidden; | ||||
|             text-overflow: ellipsis; | ||||
|             transition: all ease 0.5s; | ||||
|  | ||||
|             &.grid-active { | ||||
|               background: linear-gradient(270deg, rgba(0,48,124,0) 0%, #00307C 16%, rgba(0,99,255,0.9100) 50%, rgba(0,48,124,0.8200) 87%, rgba(0,48,124,0) 100%); | ||||
|               box-shadow: inset 0px -1px 0px 0px rgba(16,34,54,1); | ||||
|               text-shadow: 0px 3px 5px rgba(0,0,0,0.5000); | ||||
|             } | ||||
|  | ||||
|             &:hover { | ||||
|               background: linear-gradient(270deg, rgba(0,48,124,0) 0%, #00307C 16%, rgba(0,99,255,0.9100) 50%, rgba(0,48,124,0.8200) 87%, rgba(0,48,124,0) 100%); | ||||
|               box-shadow: inset 0px -1px 0px 0px rgba(16,34,54,1); | ||||
|               text-shadow: 0px 3px 5px rgba(0,0,0,0.5000); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| </style> | ||||
							
								
								
									
										187
									
								
								packages/bigscreen/dv/apps/components/chartOps.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,187 @@ | ||||
| export const pieChart2 = { | ||||
|   legend: { | ||||
|     bottom: 0, | ||||
|     itemGap: 14, | ||||
|     itemWidth: 16, | ||||
|     itemHeight: 5, | ||||
|     textStyle: {color: "#fff", fontSize: 14} | ||||
|   }, | ||||
|   grid: { | ||||
|     height: 260 | ||||
|   }, | ||||
|   xAxis: {show: false}, | ||||
|   yAxis: {show: false}, | ||||
|   tooltip: { | ||||
|     backgroundColor: "rgba(14, 51, 111, 0.9)", | ||||
|     borderColor: "#1A6ABC", | ||||
|     textStyle: {color: "#fff"} | ||||
|   }, | ||||
|   series: { | ||||
|     type: "pie", | ||||
|     minShowLabelAngle: 10, | ||||
|     radius: [70, 81], | ||||
|     itemStyle: { | ||||
|       borderColor: "#fff", | ||||
|       borderWidth: 2 | ||||
|     }, | ||||
|     label: { | ||||
|       color: "#A8D7F3", | ||||
|       fontSize: 14, | ||||
|       formatter: "{name|{b}}\n{v|{d}%}", | ||||
|       minMargin: 5, | ||||
|       edgeDistance: 10, | ||||
|       lineHeight: 22, | ||||
|       rich: { | ||||
|         v: { | ||||
|           color: "#fff" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     labelLine: {}, | ||||
|     labelLayout: function (params) { | ||||
|       let points = params.labelLinePoints, | ||||
|           isLeft = points[2][0] < points[1][0] | ||||
|       points[2][0] = | ||||
|           points[2][0] + (params.labelRect.width + 4) * (isLeft ? -1 : 1) | ||||
|       return { | ||||
|         labelLinePoints: points | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   render: (h, params) => { | ||||
|     const formatNum = num => { | ||||
|       if (num >= 10000000) { | ||||
|         return num / 10000000 + "千万" | ||||
|       } | ||||
|  | ||||
|       if (num >= 10000) { | ||||
|         return num / 10000 + "万" | ||||
|       } | ||||
|  | ||||
|       return parseFloat(num.toFixed(2)) | ||||
|     } | ||||
|  | ||||
|     let total = params.data.reduce((t, e) => { | ||||
|       return t + Number(Object.values(e)?.[1] || 0) | ||||
|     }, 0) | ||||
|     return h( | ||||
|         "div", | ||||
|         { | ||||
|           style: { | ||||
|             height: "162px", | ||||
|             width: "162px", | ||||
|             color: "#8BCCFF", | ||||
|             left: "50%", | ||||
|             top: "50%", | ||||
|             display: "flex", | ||||
|             alignItems: "center", | ||||
|             justifyContent: "center", | ||||
|             flexDirection: "column", | ||||
|             position: "absolute", | ||||
|             transform: "translate(-50%,-50%)", | ||||
|             backgroundImage: `url('https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie2Circle.png')`, | ||||
|             backgroundPosition: "center" | ||||
|           } | ||||
|         }, | ||||
|         [ | ||||
|           h( | ||||
|               "span", | ||||
|               {style: {fontSize: "28px", color: "#fff", fontFamily: "DIN"}}, | ||||
|               formatNum(total) | ||||
|           ), | ||||
|           h("span", null, "总量") | ||||
|         ] | ||||
|     ) | ||||
|   } | ||||
| } | ||||
| export const barChart1 = { | ||||
|   legend: { | ||||
|     right: 0, | ||||
|     itemHeight: 5, | ||||
|     itemWidth: 16, | ||||
|     textStyle: { color: '#fff' } | ||||
|   }, | ||||
|   yAxis: { | ||||
|     nameGap: 23, | ||||
|     minInterval: 1, | ||||
|     splitLine: { lineStyle: { color: 'rgba(255,255,255,.2)', type: 'dashed' } }, | ||||
|     axisLabel: { color: '#fff' }, | ||||
|     axisPointer: { show: false } | ||||
|   }, | ||||
|   axisPointer: { | ||||
|     type: 'shadow', | ||||
|     triggerTooltip: false, | ||||
|     shadowStyle: { color: 'rgba(46, 153, 255, .2)' } | ||||
|   }, | ||||
|   color: [ | ||||
|     { | ||||
|       type: 'linear', | ||||
|       x: 0, | ||||
|       x2: 0, | ||||
|       y: 0, | ||||
|       y2: 1, | ||||
|       colorStops: [ | ||||
|         { offset: 0, color: 'rgba(66, 187, 255, 1)' }, | ||||
|         { offset: 1, color: 'rgba(37, 143, 255, 0.2)' } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       type: 'linear', | ||||
|       x: 0, | ||||
|       x2: 0, | ||||
|       y: 0, | ||||
|       y2: 1, | ||||
|       colorStops: [ | ||||
|         { offset: 0, color: 'rgba(66, 255, 254, 1)' }, | ||||
|         { offset: 1, color: 'rgba(37, 255, 246, 0.2)' } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       type: 'linear', | ||||
|       x: 0, | ||||
|       x2: 0, | ||||
|       y: 0, | ||||
|       y2: 1, | ||||
|       colorStops: [ | ||||
|         { offset: 0, color: 'rgba(97, 253, 185, 1)' }, | ||||
|         { offset: 1, color: 'rgba(97, 253, 185, 0.2)' } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       type: 'linear', | ||||
|       x: 0, | ||||
|       x2: 0, | ||||
|       y: 0, | ||||
|       y2: 1, | ||||
|       colorStops: [ | ||||
|         { offset: 0, color: 'rgba(253, 108, 57, 1)' }, | ||||
|         { offset: 1, color: 'rgba(253, 108, 57, 0.2)' } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       type: 'linear', | ||||
|       x: 0, | ||||
|       x2: 0, | ||||
|       y: 0, | ||||
|       y2: 1, | ||||
|       colorStops: [ | ||||
|         { offset: 0, color: 'rgba(248, 187, 25, 1)' }, | ||||
|         { offset: 1, color: 'rgba(55, 39, 5, 1)' } | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   daemon: { | ||||
|     type: 'bar', | ||||
|     label: { | ||||
|       show: true, | ||||
|       position: 'top', | ||||
|       color: '#fff', | ||||
|       formatter: e => { | ||||
|         return e.data[e.seriesName] || '' | ||||
|       } | ||||
|     }, | ||||
|     barWidth: 16, | ||||
|     barCategoryGap: 40, | ||||
|     itemStyle: {} | ||||
|   } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/centralTask/bg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 362 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/centralTask/box.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/centralTask/titleBox.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.3 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/govInteraction/globe_map.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 693 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/govInteraction/kuaikuai.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/govInteraction/title.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 24 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/grid/avatar.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/grid/close.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 445 B | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/grid/title-bg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/bg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 140 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/box1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 4.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/box2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/box3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/box4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/card.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/middlebox.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 8.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								packages/bigscreen/dv/assets/videoMonitor/titlebox.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.2 KiB |