jiawuxian 2 år sedan
förälder
incheckning
5600dbfb9f

BIN
src/assets/board/area_border.png


BIN
src/assets/board/area_title-bg.png


BIN
src/assets/board/bg.png


BIN
src/assets/board/title-bg.png


+ 1 - 0
src/layout/components/AppMain.vue

@@ -30,6 +30,7 @@ export default {
 .app-main {
   /* 50= navbar  50  */
   min-height: calc(100vh - 50px);
+  height: calc(100vh - 50px);
   width: 100%;
   position: relative;
   overflow: hidden;

+ 11 - 0
src/router/index.js

@@ -127,6 +127,17 @@ export const constantRoutes = [
       meta:{title:'检查登记'}
     }]
   },
+  {
+    path: '/board',
+    component: Layout,    
+    hidden: true,
+    children:[{
+      path:'',
+      name:'board',
+      component: () => import('@/views/board/index.vue'),
+      meta:{title:'驾驶舱'}
+    }]
+  },
 ]
 
 // 动态路由,基于用户权限动态去加载

+ 51 - 0
src/views/board/board.scss

@@ -0,0 +1,51 @@
+.chart-template {
+  width: 100%;
+  height: 100%;
+
+  & > div:last-child {
+    width: 100%;
+    height: calc(100% - 26px);
+    overflow: hidden;
+  }
+
+  & > p {
+    background-image: url(@/assets/board/area_title-bg.png);
+    background-repeat: no-repeat;
+    background-position: left;
+    background-size: 300px 26px;
+    height: 26px;
+    // text-align: center;
+    font-size: 16px;
+    padding-left: 40px;
+   color:rgb(1,243  ,247);    
+    margin: 0;
+    margin-top: 5px;
+    // cursor: pointer;
+  }
+}
+
+.chart-template-withperiod{
+    & > div:last-child {
+        height: calc(100% - 66px); 
+    }
+}
+
+// .map-chart{
+
+// }
+
+
+.board-org-popper {
+  // background-color: rgb(6, 19, 57);
+  // border: 1px solid rgba(0, 217, 255, 0.25) !important;
+  // color:white;
+  
+
+  // ::v-deep .el-cascader-panel {
+  //   background-color: rgb(6, 19, 57);
+  //   border: 1px solid rgba(0, 217, 255, 0.25) !important;
+  // }
+}
+.el-cascader-menu__wrap{
+  height:  260px !important;
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
src/views/board/charts/map/maps/fj.json


+ 343 - 0
src/views/board/charts/map/report.vue

@@ -0,0 +1,343 @@
+<!--  -->
+<template>
+  <div class="chart-template">
+    <div id="map_Chart" style="height:100%"></div>
+  </div>
+</template>
+<script>
+import "./../../board.scss";
+import * as echarts from "echarts";
+import fjMap from "./maps/fj.json";
+import {
+  findMaxIndex,
+  getChartDOMSize,
+  getNextPeriod,
+  getPeriodText,
+} from "../../utils.js";
+
+export default {
+  props: ["orgId"],
+  data() {
+    return {
+      data: {},
+      icon: "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAA/5JREFUaEPtmEuIHFUUhv/TPXVbXWkw4KK7ShPGrlIzEB9IdJNZKIgLnQhGGXERFzHJwsRF4qjkIZqom8SFmRBQEF8RZSIuBFFIcBHdGDRD0jXkwfStLEQJxI3atyZ9pDqTOMSurntvdSEDXdv6z/n/r86txy3CIj9okefHAOD/nuBgAoMJ5LwChS6hU9XKMIgr15fVmdtm8XfOrF3L+wZwsool5bJ4BIwVDKwk4D4ANy1wPQ0gBPhciXnq9mju+34A9QUg9MQ4MSYYuFMz1CVmbA8itVtTnyrLDRC64iMA45ZBvvaletSytlOWCyB0xQUAS/IEAPCHL9WNtj2sARqe+JQYT9kaL6xjwqGgqZ626WUFMOOJMWZM2Rim1RBhTb2pDpv2NAaYrlWWO8QnANxgapah/zNmGlkRtc6a9DUGaNTEFBHGNEwuApid190KIHOdM+NwEKk1Gr2vSowBwprzG4iW9jIhYE9dqpcXakKvsh/MGzLCXfClurkwgLAqRlDCLxnhJ+pSvdlNo3PvMPjeQMY/6UIYTWDGdZ5l0Ac9mh8vC/XA8Bm00jShK74B8HDaeQavD2R8sBCA0HX2ArQ51Zx4b9CMX+xl3nDFbgImUp9GoIN12VpfDEDNOQKi1akA7fZocH7uaE+A6tBqKpWO9JjAd4GMHyoEoOGKLwh4It0cuwKpdvYyDz1nHZjeS58APqtLpf2CNLoHQrdyAOBe4532pRrpOYGa+IQI6W9dokm/2dpYyARCT7wOxisZzT/3pXqymyZ0xVsAtvasJ7zhN9WrhQCcrDr3l0v0o0bzD5nak0Fz7odE2/CGVhFKW8F4PKu2THzPcDM+nqW7ct5oCSVFoSumAdylaXB+XlfV0TNwLJDqQR2tNUDDFTsJ2GFioq+lLb5s7dPXW+wHTnnO3SWmYwAqJkYa2rNlpVYN/4rfNbRXJcZLqLOmXbGHgJdMjLK0xLypHsX7s3TXnrcCOH0Lll4SIrlBl5sadtUzH/WjeNSmlxVAYjRTczYy0bs2pv+pYXrMj1pf2fSyBph/Ih0CsNbG+N8a3ufLeIttj1wAJ9zrllXQ/paBZZYBfv6rpEZXziLZ/FgduQAuLyWxNtmU27i3GWN3ROpLm1rr90A3s4YrthOwyyQIAzsCqV4zqemmzT2BK01DVyTfOMm3js6xzZfqbR1hlqZvAJdv6soLAGe8SWmzL1vvZAXTPd9XgA5EzXkeRJNdAzBv8KP4gG44HV3fAeYh1oGu2bQwP+dH8fs6oUw0hQB0IDwxDkby4zf54nrGb6qPTYLpagsDSAI0qkOd/XPWPlk3bKFPoTwh8tQWOoE8wXRrBwC6V6oo3WACRV1Z3b6LfgL/ALy9JUD5S/MIAAAAAElFTkSuQmCC",
+    };
+  },
+
+  components: {},
+
+  computed: {},
+
+  watch: {
+    orgId: {
+      deep: true,
+      handler(val) {
+        //   this.resetTimer();
+        this.getData();
+      },
+    },
+    data: {
+      deep: true,
+      handler() {
+        this.$nextTick(() => {
+          this.initMap();
+        });
+      },
+    },
+  },
+
+  created() {
+    //   this.types = types;
+    //   this.maxDisplay = 16;
+    //   this.refreshTime = 1 * 10 * 1000;
+    this.isMouseOver = false;
+  },
+
+  async mounted() {
+    // console.info(this.fjMap)
+
+    window.addEventListener("resize", this.windowResize);
+  },
+  beforeDestroy() {
+    this.timer && clearInterval(this.timer);
+    this.timer = null;
+
+    window.removeEventListener("resize", this.windowResize);
+  },
+
+  methods: {
+    handleClick() {
+      this.resetTimer();
+      this.getData();
+    },
+    handleMouseEnter() {
+      this.isMouseOver = true;
+    },
+    handleMouseLeave() {
+      this.isMouseOver = false;
+    },
+    async getData() {
+      this.data = fjMap;
+    },
+    initMap() {
+      this.myChart && this.myChart.dispose();
+
+      // 基于准备好的dom,初始化echarts实例
+      this.myChart = echarts.init(document.getElementById("map_Chart"));
+      echarts.registerMap("map", this.data);
+      let t = this;
+      //   this.myChart.hideLoading();
+
+      // 指定图表的配置项和数据
+      //   let option = {
+      //     tooltip: {
+      //       trigger: "item",
+      //       showDelay: 0,
+      //       transitionDuration: 0.2,
+      //     },
+      //     // visualMap:{
+      //     //     type:
+      //     // }
+      //     // toolbox:{
+      //     //     show:true,
+      //     //     left:'left'
+      //     // }
+      //     geo: {
+      //       roam: true,
+      //       map: "map",
+      //       label: {
+      //         show: true,
+      //         color: "#ffffff00",
+      //         emphasis: {
+      //           color: "#fff",
+      //           show: true,
+      //         },
+      //       },
+      //       tooltip: {
+      //         show: true,
+      //         confine: true,
+      //         formatter: function (params) {
+      //           return params[0].value
+      //         }
+      //       },
+      //       layoutCenter: ["50%", "50%"], //地图位置
+      //       layoutSize: "100%",
+      //       x: "55%",
+      //       itemStyle: {
+      //         normal: {
+      //           areaColor: "#3fdaff30",
+      //           borderColor: "#3fdaff",
+      //           borderWidth: 1,
+      //           shadowColor: "rgba(63, 218, 255, 0.5)",
+      //           shadowBlur: 10,
+      //         },
+      //         emphasis: {
+      //           areaColor: "#2B91B7",
+      //         },
+      //       },
+      //     },
+      //     series: [
+      //       {
+      //         name: "map",
+      //         type: "effectScatter",
+      //         coordinateSystem: 'geo',
+      //         roam: true,
+      //         map: "map",
+      //         datasetIndex:0,
+      // 		geoIndex: 0,
+      //         // emphasis: {
+      //         //   label: {
+      //         //     show: true,
+      //         //   },
+      //         // },
+      //         zoom: 1.2,
+      //         itemStyle: {
+      //           normal: {
+      //             areaColor: "#3fdaff30",
+      //             borderColor: "#3fdaff",
+      //             borderWidth: 0.2,
+      //             shadowColor: "rgba(63, 218, 255, 0.5)",
+      //             shadowBlur: 2,
+      //           },
+      //           emphasis: {
+      //             areaColor: "#2B91B7",
+      //           },
+      //         },
+      //         symbol: this.icon, //自定义图标
+      //         symbolSize: 20,
+      //         data: [{name:'三明市',value:[117.635001,26.265444,10]}],
+      //       },
+      //     ],
+      //   };
+      let option = {
+        tooltip:{
+          trigger:'item'
+        },
+        geo: {
+          show: true,
+          map: "map",
+          zoom: 1.25,
+
+          showLegendSymbol: false, // 存在legend时显示
+
+          label: {
+            normal: {
+              show: true,
+              color: "#c1b496", //控制地图省市文字颜色
+              fontSize: 14,
+            },
+            emphasis: {
+              show: true,
+              color: "#fff", //悬浮字体颜色
+            },
+          },
+
+          roam: true,
+          selectedMode: "single", //选择模式,单选,只能选中一个地市
+          select: {
+            //这个就是鼠标点击后,地图想要展示的配置
+            disabled: false, //可以被选中
+            itemStyle: {
+              //相关配置项很多,可以参考echarts官网
+              borderWidth: 1, //区域边框宽度
+              borderColor: "#2B91B7ff", //区域边框颜色
+              areaColor: "#2B91B730", //选中
+            },
+            label: {
+              color: "#fff", //悬浮字体颜色
+            },
+          },
+          itemStyle: {
+            normal: {
+              borderWidth: 1, //区域边框宽度
+              borderColor: "#3fdaffff", //区域边框颜色
+              areaColor: "#3fdaff30", //区域颜色
+            },
+            emphasis: {
+              borderWidth: 1,
+              borderColor: "#fff",
+              areaColor: "#2B91B7",
+            },
+          },
+        },
+        legend: [
+          {
+            selectedMode: true, //取消图例上的点击事件
+          },
+        ],
+        series: [
+          {
+            map: "map",
+            type: "effectScatter",
+            // silent: true,
+            coordinateSystem: "geo",
+            // datasetIndex: 0,
+            // geoIndex: 0,
+            // selectedMode: false,
+            // focusNodeAdjacency: false,
+            // label: {
+            // 	show: true,
+            // 	width: 13,
+            // 	height: 15,
+            // 	fontSize: 0,
+            // 	color: "#1DF9FC",
+            // 	backgroundColor: {
+            // 		image: iconRQ
+            // 	},
+            // },
+            label: {
+              // formatter: "{b}",
+              // position: "right",
+              // color:'#fff',
+              show:false
+            },
+             tooltip:{
+              position: "right",              
+              textStyle:{
+                // color:'#fff',
+              },
+              // backgroundColor:'rgba(184,189,192,1)',
+              formatter:function(param){               
+                return `<div >
+                <div> ${param.data.name} </div>
+                <div>履职总数:85 </div>
+                <div> 已完成:67 </div>
+                </div>`
+              }
+            },
+            itemStyle: {
+              color: "#ddb926",
+            },           
+            symbol: this.icon, //自定义图标
+            symbolSize: [40, 40],
+            // encode: {
+            //   value: 2,
+            // },
+            // showEffectOn: "emphasis", //关闭涟漪
+            // hoverEffectOn: true,
+            rippleEffect: {
+              brushType: "fill",
+              period: 0,
+              number: 0,
+            },
+            data: [
+              { name: "三明", value: [117.635001, 26.265444, 10] },
+              { name: "南平", value: [118.178459, 26.635627, 10] },
+              { name: "宁德", value: [119.527082, 26.65924, 10] },
+              { name: "福州", value: [119.306239, 26.075302, 10] },
+              { name: "莆田", value: [119.007558, 25.431011, 10] },
+              { name: "泉州", value: [118.589421, 24.908853, 10] },
+              { name: "龙岩", value: [117.02978, 25.091603, 10] },
+              { name: "厦门", value: [118.11022, 24.490474, 10] },
+              { name: "漳州", value: [117.661801, 24.510897, 10] },
+            ],
+          },
+        ],
+      };
+      if (option && typeof option === "object") {
+        this.myChart.setOption(option);
+      }
+    },
+    windowResize() {
+      this.myChart && this.myChart.resize();
+    },
+
+    resetTimer() {
+      this.timer && clearInterval(this.timer);
+      this.timer = setInterval(() => {
+        if (this.isMouseOver) {
+          return;
+        }
+        this.activeName = getNextPeriod(this.types, this.activeName);
+        this.getData();
+      }, this.refreshTime);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scope>
+.content {
+  display: flex;
+
+  margin-bottom: 20px;
+  margin-left: 5px;
+  margin-right: 5px;
+  border: solid 1px #b8bdc088;
+
+  & > span {
+    margin-right: 10px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    height: 30px;
+    color: rgb(245, 245, 245);
+    font-size: 14px;
+  }
+
+  & > span:first-child {
+    width: 100px;
+    background-color: #b8bdc088;
+    text-align: center;
+  }
+}
+</style>

+ 380 - 0
src/views/board/charts/org/report.vue

@@ -0,0 +1,380 @@
+<!--  -->
+<template>
+  <div
+    class="chart-template map-template"
+    style="display: flex; flex-direction: row"
+  >
+    <div>机构统计</div>
+    <div id="org_Chart"></div>
+  </div>
+</template>
+
+<script>
+import "./../../board.scss";
+import * as echarts from "echarts";
+import {
+  findMaxIndex,
+  getChartDOMSize,
+  getNextPeriod,
+  getPeriodText,
+} from "../../utils.js";
+
+export default {
+  props: ["orgId"],
+  data() {
+    return {
+      data: {
+        all: [],
+        completed: [],
+        name: [],
+      },
+    };
+  },
+
+  components: {},
+
+  computed: {},
+
+  watch: {
+    orgId: {
+      deep: true,
+      handler(val) {
+        // this.resetTimer();
+        this.getData();
+      },
+    },
+    data: {
+      deep: true,
+      handler() {
+        this.initMap();
+      },
+    },
+  },
+
+  created() {
+    // this.types = types;
+    this.maxDisplay = 16;
+    // this.refreshTime = 1 * 10 * 1000;
+    // this.isMouseOver = false;
+  },
+
+  async mounted() {
+    window.addEventListener("resize", this.windowResize);
+  },
+  beforeDestroy() {
+    this.timer && clearInterval(this.timer);
+    this.timer = null;
+
+    window.removeEventListener("resize", this.windowResize);
+  },
+
+  methods: {
+    handleClick() {
+      this.resetTimer();
+      this.getData();
+    },
+    handleMouseEnter() {
+      this.isMouseOver = true;
+    },
+    handleMouseLeave() {
+      this.isMouseOver = false;
+    },
+    async getData() {
+      // let bs = parseInt(this.activeName) + 1;
+      this.data = {
+        all: 500,
+        unconfirm: 112, //未确认
+        auditing: 20, //异议审批中
+        unreform: 50, //待整改
+        notQuestion: 4,
+        reformed: 500 - 112 - 20 - 50 - 4,
+      };
+    },
+
+    windowResize() {
+      this.myChart && this.myChart.resize();
+    },
+    initMap() {
+      this.myChart && this.myChart.dispose();
+
+      // 基于准备好的dom,初始化echarts实例
+      this.myChart = echarts.init(document.getElementById("org_Chart"));
+
+      let t = this;
+      // 指定图表的配置项和数据
+      var option = {
+        backgroundColor: "rgba(0,0,0,0)",
+        // color: ["#C0FBB5", "#46557B"],
+        legend: {
+          show: false,
+          icon: "circle",
+          //   data: ["达标数", "自有产权数","区域外网数"],
+          textStyle: {
+            color: "#fff",
+            // fontSize:18
+          },
+          left: "center",
+          top: "5%",
+        },
+        tooltip: {
+          trigger: "item",
+        },
+        series: [
+          {
+            name: "营业网点",
+            type: "pie",
+            radius: ["65%", "85%"],
+            center: [`12.5%`, "50%"],
+            data: [
+              {
+                name: "达标数",
+                value: 2000,
+              },
+              {
+                name: "自有产权数",
+                value: 1500,
+              },
+              {
+                name: "区域外网数",
+                value: 80,
+              },
+            ],
+            label: {
+              show: true,
+              position: "center",
+              color: "#fff",
+              fontSize: 14,
+              formatter: function (value) {
+                return "3020\n" + "\n营业网点";
+              },
+            },
+            tooltip: {
+              show: true,
+              trigger: "item",
+              backgroundColor: "#b8bdc0",
+              textStyle: {
+                color: "#000",
+              },
+              confine:true,
+              formatter: function (value) {
+                let html=`<div style="z-index:999;">
+                        <div>营业网点</div>
+                        <div>总数:3020</div>
+                        <div>达标数:2000</div>                        
+                        <div>自有产权数:1500</div>
+                        <div>区域外网数:80</div>
+                    </div>`
+                return html;
+              },
+            },
+
+            //   alignTo: 'none',
+            //   bleedMargin: 5,
+
+            // left: 0,
+            // right: 0,
+            // top: 0,
+            // bottom: 0,
+          },
+          {
+            name: "业务库",
+            type: "pie",
+            radius: ["65%", "85%"],
+            center: [`37.5%`, "50%"],
+            data: [
+              {
+                name: "一类库",
+                value: 2000,
+              },
+              {
+                name: "二类库",
+                value: 1500,
+              },
+              {
+                name: "三类库",
+                value: 80,
+              },
+              {
+                name: "四类库",
+                value: 80,
+              },
+            ],
+            label: {
+              show: true,
+              position: "center",
+              color: "#fff",
+              fontSize: 14,
+              formatter: function (value) {
+                return "2000\n" + "\n业务库";
+              },
+            },
+            tooltip: {
+              show: true,
+              trigger: "item",
+              backgroundColor: "#b8bdc0",
+              textStyle: {
+                color: "#000",
+              },
+              confine:true,
+              formatter: function (value) {
+                let html=`<div style="z-index:999;">
+                        <div>业务库</div>
+                        <div>总数:3020</div>
+                        <div>一类库:2000</div>                        
+                        <div>二类库:1500</div>
+                        <div>三类库:80</div>
+                        <div>四类库:80</div>
+                    </div>`
+                return html;
+              },
+            },
+
+            //   alignTo: 'none',
+            //   bleedMargin: 5,
+
+            // left: 0,
+            // right: 0,
+            // top: 0,
+            // bottom: 0,
+          },
+          {
+            name: "自助银行",
+            type: "pie",
+            radius: ["62%", "85%"],
+            center: [`62.5%`, "50%"],
+            data: [
+              {
+                name: "在行式自助银行",
+                value: 2000,
+              },
+              {
+                name: "离行式自助银行",
+                value: 1500,
+              },
+            ],
+            label: {
+              show: true,
+              position: "center",
+              color: "#fff",
+              fontSize: 14,
+              formatter: function (value) {
+                return "4000\n" + "\n自助银行";
+              },
+            },
+            tooltip: {
+              show: true,
+              trigger: "item",
+              backgroundColor: "#b8bdc0",
+              textStyle: {
+                color: "#000",
+              },
+              confine:true,
+              formatter: function (value) {
+                let html=`<div style="z-index:999;">
+                        <div>自助银行</div>
+                        <div>总数:4000</div>
+                        <div>在行式自助银行:2000</div>                        
+                        <div>离行式自助银行:1500</div>
+                    </div>`
+                return html;
+              },
+            },
+          },
+          {
+            name: "自助设备",
+            type: "pie",
+            radius: ["62%", "85%"],
+            center: [`87.5%`, "50%"],
+            data: [
+              {
+                name: "在行式穿墙机具",
+                value: 2000,
+              },
+              {
+                name: "在行式堂式机具",
+                value: 1500,
+              },
+              {
+                name: "离行式穿墙机具",
+                value: 2000,
+              },
+              {
+                name: "离行式堂式机具",
+                value: 1500,
+              },
+            ],
+            label: {
+              show: true,
+              position: "center",
+              color: "#fff",
+              fontSize: 14,
+              formatter: function (value) {
+                return "10000\n" + "\n自助设备";
+              },
+            },
+            tooltip: {
+              show: true,
+              trigger: "item",
+              backgroundColor: "#b8bdc0",
+              textStyle: {
+                color: "#000",
+              },
+              confine:true,
+              formatter: function (value) {
+                let html=`<div style="z-index:999;">
+                        <div>自助设备</div>
+                        <div>总数:4000</div>
+                        <div>在行式穿墙机具:2000</div>                        
+                        <div>在行式堂式机具:1500</div>
+                        <div>离行式穿墙机具:2000</div>                        
+                        <div>离行式堂式机具:1500</div>
+                    </div>`
+                return html;
+              },
+            },
+          },
+        ],
+      };
+      if (option && typeof option === "object") {
+        this.myChart.setOption(option);
+      }
+    },
+
+    resetTimer() {
+      // this.timer && clearInterval(this.timer);
+      // this.timer = setInterval(() => {
+      //   if (this.isMouseOver) {
+      //     return;
+      //   }
+      //   this.activeName = getNextPeriod(this.types, this.activeName);
+      //   this.getData();
+      // }, this.refreshTime);
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.map-template {
+  & > div {
+    margin: 0px;
+    padding: 0px;
+  }
+
+  & > div:first-child {
+    width: 30px;
+    height: 100%;
+    color: rgb(245, 245, 245);
+    background-color: #b8bdc088;
+    text-align: center;
+    font-size: 14px;
+    writing-mode: vertical-lr;
+    padding-left: 5px;
+    padding-right: 5px;
+  }
+
+  & > div:last-child {
+    height: 100%;
+    width: calc(100% - 30px);
+  }
+}
+</style>

+ 197 - 0
src/views/board/charts/otherTask/report.vue

@@ -0,0 +1,197 @@
+<!--  -->
+<template>
+  <div class="chart-template">
+    <p>
+      <span>其它任务情况</span>
+    </p>
+    <div>
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+        <el-tab-pane
+          v-for="t in types"
+          :key="t.value"
+          :label="t.text"
+          :name="t.value"
+        ></el-tab-pane>
+      </el-tabs>
+    </div>
+    <div>
+      <div class="content">
+        <span> 安全检查 </span>
+        <span> 任务总数 {{ data.safetyCheck.all }} </span>
+        <span> 已完成 {{ data.safetyCheck.completed }} </span>
+      </div>
+      <div class="content">
+        <span> 教育培训 </span>
+        <span> 任务总数 {{ data.edu.all }} </span>
+        <span> 已完成 {{ data.edu.completed }} </span>
+      </div>
+      <div class="content">
+        <span> 预案演练 </span>
+        <span> 任务总数 {{ data.drill.all }} </span>
+        <span> 已完成 {{ data.drill.completed }} </span>
+      </div>
+      <div class="content">
+        <span> 监控调阅 </span>
+        <span> 任务总数 {{ data.monitor.all }} </span>
+        <span> 已完成 {{ data.monitor.completed }} </span>
+        <span> 未完成 {{ data.monitor.all - data.monitor.completed }} </span>
+      </div>
+      <div class="content">
+        <span> 来访 </span>
+        <span> 来访次数 {{ data.visit.times }} </span>
+        <span> 来访人数 {{ data.visit.personCount }} </span>
+        <span> 陪同人数 {{ data.visit.accompanyCount }} </span>
+      </div>
+    </div>
+    <!-- <div id="commAlarmEvent_Chart"></div> -->
+  </div>
+</template>
+<script>
+import "./../../board.scss";
+import * as echarts from "echarts";
+import {
+  findMaxIndex,
+  getChartDOMSize,
+  getNextPeriod,
+  getPeriodText,
+} from "../../utils.js";
+const types = [
+  {
+    text: "今天",
+    value: "0",
+  },
+  {
+    text: "近7天",
+    value: "1",
+  },
+  {
+    text: "近30天",
+    value: "2",
+  },
+  {
+    text: "近90天",
+    value: "3",
+  },
+  {
+    text: "本年",
+    value: "4",
+  },
+];
+export default {
+  props: ["orgId"],
+  data() {
+    return {
+      data: {
+        safetyCheck: {},
+        edu: {},
+        drill: {},
+        monitor: {},
+        visit: {},
+      },
+      activeName: types[0].value,
+    };
+  },
+
+  components: {},
+
+  computed: {},
+
+  watch: {
+    orgId: {
+      deep: true,
+      handler(val) {
+        this.resetTimer();
+        this.getData();
+      },
+    },   
+  },
+
+  created() {
+    this.types = types;
+    this.maxDisplay = 16;
+    this.refreshTime = 1 * 10 * 1000;
+    this.isMouseOver = false;
+  },
+
+  async mounted() {
+    window.addEventListener("resize", this.windowResize);
+  },
+  beforeDestroy() {
+    this.timer && clearInterval(this.timer);
+    this.timer = null;
+
+    window.removeEventListener("resize", this.windowResize);
+  },
+
+  methods: {
+    handleClick() {
+      this.resetTimer();
+      this.getData();
+    },
+    handleMouseEnter() {
+      this.isMouseOver = true;
+    },
+    handleMouseLeave() {
+      this.isMouseOver = false;
+    },
+    async getData() {
+      let bs = parseInt(this.activeName) + 1;
+      this.data = {
+        safetyCheck: {
+          all: 18 * bs,
+          completed: 16 * bs,
+        },
+        edu: { all: 2 * bs, completed: 1 * bs },
+        drill: { all: 3 * bs, completed: 2 * bs },
+        monitor: { all: 66 * bs, completed: 65 * bs },
+        visit: {
+          times: 5 * bs,
+          personCount: 6 * bs,
+          accompanyCount: 2 * bs,
+        },
+      };
+    },
+
+    windowResize() {
+      this.myChart && this.myChart.resize();
+    },
+
+    resetTimer() {
+      this.timer && clearInterval(this.timer);
+      this.timer = setInterval(() => {
+        if (this.isMouseOver) {
+          return;
+        }
+        this.activeName = getNextPeriod(this.types, this.activeName);
+        this.getData();
+      }, this.refreshTime);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scope>
+.content {
+  display: flex;
+
+  margin-bottom: 20px;
+  margin-left: 5px;
+  margin-right: 5px;
+  border: solid 1px #b8bdc088;
+
+  & > span {
+    margin-right: 10px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    height: 30px;
+    color: rgb(245, 245, 245);
+    font-size: 14px;
+  }
+
+  & > span:first-child {
+    width: 100px;
+    background-color: #b8bdc088;
+    text-align: center;
+  }
+}
+</style>

+ 196 - 0
src/views/board/charts/question/report.vue

@@ -0,0 +1,196 @@
+<!--  -->
+<template>
+  <div class="chart-template">
+    <p>
+      <span> 问题整改(近一月) </span>
+    </p>
+    <div id="question_Chart"></div>
+  </div>
+</template>
+
+<script>
+import "./../../board.scss";
+import * as echarts from "echarts";
+import {
+  findMaxIndex,
+  getChartDOMSize,
+  getNextPeriod,
+  getPeriodText,
+} from "../../utils.js";
+
+export default {
+  props: ["orgId"],
+  data() {
+    return {
+      data: {
+        all: [],
+        completed: [],
+        name: [],
+      },
+      // activeName: types[0].value,
+    };
+  },
+
+  components: {},
+
+  computed: {},
+
+  watch: {
+    orgId: {
+      deep: true,
+      handler(val) {
+        // this.resetTimer();
+        this.getData();
+      },
+    },
+    data: {
+      deep: true,
+      handler() {
+        this.initMap();
+      },
+    },
+  },
+
+  created() {
+    // this.types = types;
+    this.maxDisplay = 16;
+    // this.refreshTime = 1 * 10 * 1000;
+    // this.isMouseOver = false;
+  },
+
+  async mounted() {
+    window.addEventListener("resize", this.windowResize);
+  },
+  beforeDestroy() {
+    this.timer && clearInterval(this.timer);
+    this.timer = null;
+
+    window.removeEventListener("resize", this.windowResize);
+  },
+
+  methods: {
+    handleClick() {
+      this.resetTimer();
+      this.getData();
+    },
+    handleMouseEnter() {
+      this.isMouseOver = true;
+    },
+    handleMouseLeave() {
+      this.isMouseOver = false;
+    },
+    async getData() {
+      // let bs = parseInt(this.activeName) + 1;
+      this.data = {
+        all: 500,
+        unconfirm: 112, //未确认
+        auditing: 20, //异议审批中
+        unreform: 50, //待整改
+        notQuestion: 4,
+        reformed: 500 - 112 - 20 - 50 - 4,
+      };
+    },
+
+    windowResize() {
+      this.myChart && this.myChart.resize();
+    },
+    initMap() {
+      this.myChart && this.myChart.dispose();
+
+      // 基于准备好的dom,初始化echarts实例
+      this.myChart = echarts.init(
+        document.getElementById("question_Chart")
+      );
+
+      let chartData = [
+        {
+          name: "未确认",
+          value: this.data.unconfirm,
+        },
+        {
+          name: "异议审批中",
+          value: this.data.auditing,
+        },
+        {
+          name: "待整改",
+          value: this.data.unreform,
+        },
+        {
+          name: "异议隐患",
+          value: this.data.notQuestion,
+        },
+        {
+          name: "整改完成",
+          value: this.data.reformed,
+        },
+      ];
+      let t = this;
+      // 指定图表的配置项和数据
+      var option = {
+        title: {
+          left: "center",
+        },
+        tooltip: {
+          trigger: "item",
+          formatter: "{a} <br/>{b} : {c} ({d}%)",
+        },
+        legend: {
+          type: "scroll",
+          orient: "vertical",
+          right: 10,
+          top: 20,
+          bottom: 20,         
+          data: chartData.map((d) =>d.name),
+          formatter:function(name) {
+            let d=chartData.find(c=>c.name===name);
+            return d.name+"  "+d.value+"项";            
+          },
+          textStyle:{
+            color:'white',
+          }
+        },
+        series: [
+          {
+            name: "问题整改",
+            type: "pie",
+            radius: ["50%","70%"],
+            center: ["30%", "50%"],
+            data: chartData,
+            label: {
+              show: true,
+              position: "center",
+              color: "#fff",
+              fontSize: 14,
+              formatter: function (value) {
+                return "100\n" + "\n整改率:78%";
+              },
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+          },
+        ],
+      };
+      if (option && typeof option === "object") {
+        this.myChart.setOption(option);
+      }
+    },
+
+    resetTimer() {
+      // this.timer && clearInterval(this.timer);
+      // this.timer = setInterval(() => {
+      //   if (this.isMouseOver) {
+      //     return;
+      //   }
+      //   this.activeName = getNextPeriod(this.types, this.activeName);
+      //   this.getData();
+      // }, this.refreshTime);
+    },
+  },
+};
+</script>
+<style lang="less" scoped></style>

+ 246 - 0
src/views/board/charts/resumption/report.vue

@@ -0,0 +1,246 @@
+<!--  -->
+<template>
+  <div class="chart-template chart-template-withperiod">
+    <p>
+      <span> 日常安全履职 </span>
+    </p>
+    <div>
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+        <el-tab-pane
+          v-for="t in types"
+          :key="t.value"
+          :label="t.text"
+          :name="t.value"
+        ></el-tab-pane>
+      </el-tabs>
+    </div>
+    <div id="commAlarmEvent_Chart"></div>
+  </div>
+</template>
+
+<script>
+import "./../../board.scss";
+import * as echarts from "echarts";
+import {
+  findMaxIndex,
+  getChartDOMSize,
+  getNextPeriod,
+  getPeriodText,
+} from "../../utils.js";
+const types = [
+  {
+    text: "今天",
+    value: "0",
+  },
+  {
+    text: "近7天",
+    value: "1",
+  },
+  {
+    text: "近30天",
+    value: "2",
+  },
+  {
+    text: "近90天",
+    value: "3",
+  },
+  {
+    text: "本年",
+    value: "4",
+  },
+];
+export default {
+  props: ["orgId"],
+  data() {
+    return {
+      data: {
+        all: [],
+        completed: [],
+        name: [],
+      },
+      activeName: types[0].value,
+    };
+  },
+
+  components: {},
+
+  computed: {},
+
+  watch: {
+    orgId: {
+      deep: true,
+      handler(val) {        
+        this.resetTimer();
+        this.getData();
+      },
+    },
+    data: {
+      deep: true,
+      handler() {
+        this.initMap();
+      },
+    },
+  },
+
+  created() {
+    this.types = types;
+    this.maxDisplay = 16;
+    this.refreshTime = 1 * 10 * 1000;
+    this.isMouseOver = false;
+  },
+
+  async mounted() {
+    window.addEventListener("resize", this.windowResize);
+  },
+  beforeDestroy() {
+    this.timer && clearInterval(this.timer);
+    this.timer = null;
+
+    window.removeEventListener("resize", this.windowResize);
+  },
+
+  methods: {
+    handleClick() {
+      this.resetTimer();
+      this.getData();
+    },
+    handleMouseEnter() {
+      this.isMouseOver = true;
+    },
+    handleMouseLeave() {
+      this.isMouseOver = false;
+    },
+    async getData() {
+      let bs = parseInt(this.activeName) + 1;
+      this.data = {
+        all: [210 * bs, 101 * bs, 117 * bs, 78 * bs, 107 * bs, 105 * bs],
+        completed: [155 * bs, 99 * bs, 110 * bs, 78 * bs, 104 * bs, 102 * bs],
+        name: ["福州", "漳州", "泉州", "三明", "南平", "宁德"],
+      };
+    },
+
+    windowResize() {
+      this.myChart && this.myChart.resize();
+    },
+    initMap() {
+      this.myChart && this.myChart.dispose();
+
+      // 基于准备好的dom,初始化echarts实例
+      this.myChart = echarts.init(
+        document.getElementById("commAlarmEvent_Chart")
+      );
+
+      let t = this;
+      // 指定图表的配置项和数据
+      var option = {
+        color: ["#008CD6", "#82D5AE"],
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            type: "shadow",
+          },
+        },
+        grid: {
+          left: "3%",
+          right: "4%",
+          bottom: "2%",
+          top: "5%",
+          containLabel: true,
+        },
+
+        xAxis: [
+          {
+            type: "category",
+            data: this.data.name,
+            // data: this.mapdata.totalDataVo.xlist,
+            axisTick: {
+              alignWithLabel: true,
+            },
+            axisLine: {
+              show: true,
+              lineStyle: {
+                type: "solid",
+                color: "rgb(245, 245, 245)", //左边线的颜⾊
+              },
+            },
+            axisLabel: {
+              interval: 0,
+              rotate: -30,
+              fontSize: 12,
+              color: "#fff",
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            minInterval: 1,
+            // max: function (value) {
+            //   let m = value.max == Math.ceil(value.max) ? Math.ceil(value.max * 1.0001) : Math.ceil(value.max);
+            //   return m
+            // },
+          },
+        ],
+        series: [
+          {
+            name: "总数",
+            type: "bar",
+            barWidth: "14",
+            // label: {
+            //   show: true,
+            //   position: 'top',
+            // },
+            data: this.data.all,
+          },
+          {
+            name: "已完成",
+            type: "bar",
+            barWidth: "14",
+            // label: {
+            //   show: true,
+            //   position: 'top',
+            // },
+            data: this.data.completed,
+            itemStyle: {
+              normal: {
+                label: {
+                  formatter: function (param) {
+                    if (t.data.all[param.dataIndex]) {
+                      let rate = param.value / t.data.all[param.dataIndex];
+                      return (Math.floor(rate * 1000) / 10).toFixed(1) + "%";
+                    } else {
+                      return "";
+                    }
+                  },
+                  show: true,
+                  position: "top",
+                  textStyle: {
+                    fontWeight: "bolder",
+                    fontSize: "12",
+                    color: "rgb(245, 245, 245)",
+                  },
+                },
+              },
+            },
+          },
+        ],
+      };
+      if (option && typeof option === "object") {
+        this.myChart.setOption(option);
+      }
+    },
+   
+    resetTimer() {
+      this.timer && clearInterval(this.timer);
+      this.timer = setInterval(() => {
+        if (this.isMouseOver) {
+          return;
+        }
+        this.activeName = getNextPeriod(this.types, this.activeName);
+        this.getData();
+      }, this.refreshTime);
+    },
+  },
+};
+</script>
+<style lang="less" scoped></style>

+ 271 - 0
src/views/board/charts/safetyIndex/report.vue

@@ -0,0 +1,271 @@
+<!--  -->
+<template>
+  <div class="chart-template">
+    <p>
+      <span> 安全指数排名(上月) </span>
+    </p>
+    <div id="safetyIndex_Chart"></div>
+  </div>
+</template>
+
+<script>
+import "./../../board.scss";
+import * as echarts from "echarts";
+import {
+  findMaxIndex,
+  getChartDOMSize,
+  getNextPeriod,
+  getPeriodText,
+} from "../../utils.js";
+
+export default {
+  props: ["orgId"],
+  data() {
+    return {
+      data: {
+        all: [],
+        completed: [],
+        name: [],
+      },
+    };
+  },
+
+  components: {},
+
+  computed: {},
+
+  watch: {
+    orgId: {
+      deep: true,
+      handler(val) {
+        this.resetTimer();
+        this.getData();
+      },
+    },
+    data: {
+      deep: true,
+      handler() {
+        this.initMap();
+      },
+    },
+  },
+
+  created() {
+    this.maxDisplay = 16;
+    this.isMouseOver = false;
+  },
+
+  async mounted() {
+    window.addEventListener("resize", this.windowResize);
+  },
+  beforeDestroy() {
+    this.timer && clearInterval(this.timer);
+    this.timer = null;
+
+    window.removeEventListener("resize", this.windowResize);
+  },
+
+  methods: {
+    handleClick() {
+      this.resetTimer();
+      this.getData();
+    },
+    handleMouseEnter() {
+      this.isMouseOver = true;
+    },
+    handleMouseLeave() {
+      this.isMouseOver = false;
+    },
+    async getData() {
+      this.data = {
+        value: [
+          100, 99.4, 99, 98, 97.8, 97.6, 97.4, 97, 96.9, 96.7, 96.3, 96, 95.8,95.7,95.6,95
+        ],
+        name: [
+          "玉塘分理处",
+          "寿宁县农联社鳌阳社",
+          "永春县农联社仙溪社",
+          "永春县农联社曲斗社",
+          "连江县农联社东湖社",
+          "连江县农联社江南社",
+          "霞浦联社海滨社",
+          "霞浦联社南街社",
+          "闽侯县农联社甘蔗社",
+          "闽侯县农联社荆溪社",
+          "闽侯县农联社洋里社",
+          "闽侯县农联社青口社",
+          // "永泰县农联社红星社",
+          // "罗源县农联社洪洋社",
+          // "云霄县农联社下河社",
+          // "诏安县农联社南门社",
+        ],
+      };
+    },
+
+    windowResize() {
+      this.myChart && this.myChart.resize();
+    },
+    initMap() {
+      this.myChart && this.myChart.dispose();
+
+      // 基于准备好的dom,初始化echarts实例
+      this.myChart = echarts.init(document.getElementById("safetyIndex_Chart"));
+
+      let t = this;
+      // 指定图表的配置项和数据
+      var option = {
+        // tooltip: {
+        //   trigger: "axis",
+        //   axisPointer: {
+        //     type: "shadow",
+        //   },
+        // },
+        color: ["#008CD6"],
+        grid: {
+          left: "3%",
+          right: "80px",
+          bottom: "2%",
+          top: "30px",
+          containLabel: true,
+        },
+        legend: {
+          show: true,
+          textStyle:{
+           color:"rgb(245, 245, 245)"
+          }
+        },
+        xAxis: {
+          max: "dataMax",
+          show:false,
+        },
+        yAxis: {
+          type: "category",
+          data: this.data.name,
+          inverse: true,
+
+          axisLabel: {
+            interval: 0,
+            // rotate: -30,
+            fontSize: 12,
+            color: "rgb(245, 245, 245)",
+          },
+          // animationDuration: 300,
+          // animationDurationUpdate: 300,
+          // max: this.maxDisplay, // only the largest 3 bars will be displayed
+        },
+        series: [
+          {
+            realtimeSort: true,
+            name: "安全评分",
+            type: "bar",
+            data: this.data.value,
+            barWidth: 14,
+            label: {
+              show: true,
+              position: "right",
+              valueAnimation: true,
+              formatter:"{c}分",
+              textStyle: {
+                fontWeight: "bolder",
+                fontSize: "12",
+                color: "rgb(245, 245, 245)",
+              },
+            },
+          },
+        ],
+        // xAxis: [
+        //   {
+        //     type: "category",
+        //     data: this.data.name,
+        //     // data: this.mapdata.totalDataVo.xlist,
+        //     axisTick: {
+        //       alignWithLabel: true,
+        //     },
+        //     axisLine: {
+        //       show: true,
+        //       lineStyle: {
+        //         type: "solid",
+        //         color: "#ccc", //左边线的颜⾊
+        //       },
+        //     },
+        //     axisLabel: {
+        //       interval: 0,
+        //       rotate: -30,
+        //       fontSize: 12,
+        //       color: "#fff",
+        //     },
+        //   },
+        // ],
+        // yAxis: [
+        //   {
+        //     type: "value",
+        //     minInterval: 1,
+        //     // max: function (value) {
+        //     //   let m = value.max == Math.ceil(value.max) ? Math.ceil(value.max * 1.0001) : Math.ceil(value.max);
+        //     //   return m
+        //     // },
+        //   },
+        // ],
+        // series: [
+        //   {
+        //     name: "总数",
+        //     type: "bar",
+        //     barWidth: "14",
+        //     // label: {
+        //     //   show: true,
+        //     //   position: 'top',
+        //     // },
+        //     data: this.data.all,
+        //   },
+        //   {
+        //     name: "已完成",
+        //     type: "bar",
+        //     barWidth: "14",
+        //     // label: {
+        //     //   show: true,
+        //     //   position: 'top',
+        //     // },
+        //     data: this.data.completed,
+        //     itemStyle: {
+        //       normal: {
+        //         label: {
+        //           formatter: function (param) {
+        //             if (t.data.all[param.dataIndex]) {
+        //               let rate = param.value / t.data.all[param.dataIndex];
+        //               return (Math.floor(rate * 1000) / 10).toFixed(1) + "%";
+        //             } else {
+        //               return "";
+        //             }
+        //           },
+        //           show: true,
+        //           position: "top",
+        //           textStyle: {
+        //             fontWeight: "bolder",
+        //             fontSize: "12",
+        //             color: "#fff",
+        //           },
+        //         },
+        //       },
+        //     },
+        //   },
+        // ],
+      };
+      if (option && typeof option === "object") {
+        this.myChart.setOption(option);
+      }
+    },
+
+    resetTimer() {
+      // this.timer && clearInterval(this.timer);
+      // this.timer = setInterval(() => {
+      //   if (this.isMouseOver) {
+      //     return;
+      //   }
+      //   this.activeName = getNextPeriod(this.types, this.activeName);
+      //   this.getData();
+      // }, this.refreshTime);
+    },
+  },
+};
+</script>
+<style lang="less" scoped></style>

+ 612 - 0
src/views/board/index.vue

@@ -0,0 +1,612 @@
+<!--  -->
+<template>
+  <div class="body">
+    <!-- 标题栏-->
+    <div class="topDiv">
+      <div class="logoDiv">
+        <img width="160px" height="30px" src="@/assets/logo/logo.png" />
+        <el-divider direction="vertical" style="margin-top: 5px"></el-divider>
+        <el-cascader
+          :options="orgOptions"
+          v-model="selectedOrg.id"
+          :props="{ checkStrictly: true, value: 'id', label: 'shortName' }"
+          :show-all-levels="false"
+          class="org-cascader"
+          popper-class="board-org-popper"
+        ></el-cascader>
+        <!-- <orgDropDown
+          v-model="selectedOrg.orgId"
+          style="width: 250px"
+          @nodeChanged="handleOrgNodeClick"
+        ></orgDropDown> -->
+      </div>
+      <div class="title">
+        <span>移动安全保卫管理平台项目</span>
+      </div>
+      <div class="iconDiv">
+        <span> {{ time }} {{ week }}</span>
+        <span>|</span>
+      </div>
+    </div>
+    <div class="main">
+      <div>
+        <div>
+          <resumptionReport :orgId="selectedOrg.id" />
+        </div>
+        <div>
+          <otherTask :orgId="selectedOrg.id" />
+        </div>
+      </div>
+      <div>
+        <div class="box">
+          <mapChart :orgId="selectedOrg.id" />
+        </div>
+        <div>
+          <orgStatis :orgId="selectedOrg.id" />
+        </div>
+      </div>
+      <div>
+        <div>
+          <div>
+            <question :orgId="selectedOrg.id" />
+          </div>
+        </div>
+        <div>
+          <div>
+            <safetyIndex :orgId="selectedOrg.id" />
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+import resumptionReport from "./charts/resumption/report.vue";
+import otherTask from "./charts/otherTask/report.vue";
+import question from "./charts/question/report.vue";
+import safetyIndex from "./charts/safetyIndex/report.vue";
+import mapChart from "./charts/map/report.vue";
+import orgStatis from "./charts/org/report.vue";
+import orgDropDown from "@/components/orgTree/orgDropDown.vue";
+import dayjs from "dayjs";
+
+import "./board.scss";
+export default {
+  props: [],
+  data() {
+    return {
+      time: "",
+      week: "",
+      orgTree: [], //分行下拉列表
+      activeIndex: "0",
+      selectedOrg: {
+        id: null,
+      },
+      electricHost: undefined,
+    };
+  },
+
+  components: {
+    orgDropDown,
+    resumptionReport,
+    otherTask,
+    question,
+    safetyIndex,
+    mapChart,
+    orgStatis,
+  },
+
+  computed: {
+    ...mapGetters(["orgId", "depTree"]),
+    orgOptions() {
+      let deps = this.depTree;
+      let recursion = (deps) => {
+        for (let index in deps) {
+          let dep = deps[index];
+          if (!dep.children) {
+            continue;
+          }
+          if (dep.children.length === 0) {
+            delete dep.children;
+            continue;
+          }
+
+          recursion(dep.children);
+        }
+      };
+      recursion(deps);
+      console.info(deps);
+      return deps;
+    },
+  },
+
+  watch: {
+    // depTree: {
+    //   deep:true,
+    //   immediate:true,
+    //   handler(trees) {
+    //   },
+    // },
+  },
+
+  created() {
+    this.time = dayjs().format("YYYY-MM-DD HH:mm:ss");
+    // this.week = this.getweek();
+  },
+
+  mounted() {
+    // getElectricUrl().then((h) => {
+    //   // let h='10.87.10.105:8090';
+    //   this.electricHost = h;
+    //   Vue.$electricHost = h;
+    //   getCurrentUserInfo().then((r) => {
+    //     if (r.ret != 1) {
+    //       this.$notify.error({
+    //         message: "未获取到登录用户信息",
+    //       });
+    //       return;
+    //     }
+    //     const userInfo = {
+    //       orgId: r.data,
+    //     };
+
+    //     Vue.$currentUserInfo = userInfo;
+    //     this.getOrgList(userInfo.orgId);
+    //     this.orgtimer = setInterval(() => {
+    //       this.getOrgList(userInfo.orgId);
+    //     }, 1 * 60 * 60 * 1000);
+    //   });
+    // });
+    this.selectedOrg.id = this.orgId;
+  },
+  beforeDestroy() {
+    clearInterval(this.orgtimer);
+    this.orgtimer = null;
+  },
+  methods: {
+    getweek() {
+      let week = this.moment().day();
+      switch (week) {
+        case 1:
+          return "星期一";
+        case 2:
+          return "星期二";
+        case 3:
+          return "星期三";
+        case 4:
+          return "星期四";
+        case 5:
+          return "星期五";
+        case 6:
+          return "星期六";
+        case 0:
+          return "星期日";
+      }
+    },
+    handleOrgNodeClick(org) {
+      this.selectedOrg = { ...org };
+    },
+    // handleSelect(e) {
+    //   var item = this.branchlist.find((o) => o.orgId === parseInt(e));
+    //   this.activeIndex = e;
+    //   this.selectedOrg = { ...item };
+    // },
+    async getOrgList(currentUserOrgId) {
+      let r = await getOrgList();
+      if (r.ret === 2) {
+        this.exitSys();
+      } else if (r.ret != 1) {
+        this.$notify.error({
+          message: `获取机构列表错误:${r.errorMsg}`,
+          duration: 20 * 1000,
+        });
+
+        return;
+      }
+
+      let { data } = r;
+      Vue.prototype.$treeList = data;
+      const tree = this.genDropdownTree(data, currentUserOrgId);
+      if (tree && tree.length > 0) {
+        this.selectedOrg = {
+          orgId: tree[0].id,
+          name: tree[0].label,
+        };
+      }
+      this.orgTree = tree;
+
+      let top = data.find((d) => !data.find((d2) => d2.orgId == d.parentId));
+      if (!top) {
+        this.$$notify.error({
+          message: "未找到顶级机构",
+          duration: 20 * 1000,
+        });
+        return;
+      }
+
+      let branchlist = [];
+      if (
+        top.orgType != dictionary.orgType.firstLevelBranchType &&
+        top.orgType != dictionary.orgType.secondLevelBranchType &&
+        top.orgType != dictionary.orgType.subBranchType
+      ) {
+        this.$$notify.error({
+          message: "不支持机构类型" + top.orgType,
+          duration: 20 * 1000,
+        });
+        return;
+      }
+
+      branchlist.push(top);
+      var subOrgType =
+        top.orgType == dictionary.orgType.firstLevelBranchType
+          ? dictionary.orgType.secondLevelBranchType
+          : top.orgType == dictionary.orgType.secondLevelBranchType
+          ? dictionary.orgType.subBranchType
+          : undefined;
+      let subs = data.filter(
+        (d) => d.orgId != top.orgId && d.orgType == subOrgType
+      );
+
+      this.branchlist = branchlist.concat(subs);
+      if (!this.branchlist || this.branchlist.length === 0) {
+        this.$notify.error({
+          message: "机构列表为空",
+          duration: 20 * 1000,
+        });
+      } else {
+        if (!this.selectedOrg) {
+          this.selectedOrg = {
+            ...this.branchlist[0],
+          };
+        }
+      }
+    },
+
+    /**生成下拉树 */
+    genDropdownTree(orgList, topOrgId) {
+      const orgTypeConst = dictionary.orgType;
+      const needOrgTypes = [
+        orgTypeConst.firstLevelBranchType,
+        orgTypeConst.secondLevelBranchType,
+        orgTypeConst.subBranchType,
+      ];
+      const topOrg = orgList.find((org) => org.orgId == topOrgId);
+      var top = { id: topOrg.orgId, label: topOrg.orgName, path: topOrg.path };
+      var topTypeIndex = needOrgTypes.indexOf(topOrg.orgType);
+      if (topTypeIndex < 0) {
+        return [];
+      }
+
+      var nodes = [top];
+      if (topTypeIndex == needOrgTypes.length - 1) {
+        return [top];
+      }
+
+      for (var i = topTypeIndex + 1; i < needOrgTypes.length; i++) {
+        let tmpNodes = [];
+        nodes.forEach((item) => {
+          var children = orgList.filter(
+            (org) =>
+              org.path.startsWith(item.path) && org.orgType == needOrgTypes[i]
+          );
+          children = children.map((c) => ({
+            id: c.orgId,
+            label: c.orgName,
+            path: c.path,
+          }));
+
+          tmpNodes = tmpNodes.concat(children);
+          item.children = children;
+        });
+        nodes = tmpNodes;
+      }
+
+      return [top];
+    },
+
+    exitSys() {
+      this.$alert("确定退出系统吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        showCancelButton: true,
+        callback: (r) => {
+          if (r === "confirm") {
+            logout()
+              .then((r) => {
+                location.href =
+                  Vue.$electricHost + "/security/login/sysCenterMain.html";
+              })
+              .catch((e) => {
+                location.href =
+                  Vue.$electricHost + "/security/login/sysCenterMain.html";
+              });
+          }
+        },
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.body {
+  background-image: url(@/assets/board/bg.png);
+  background-position: 100%;
+  background-color: rgba(8, 8, 8);
+  color: white;
+  /* text-shadow: 0 0 5px #252525; */
+  font-size: 18px;
+  height: 100%;
+  position: relative;
+  overflow: hidden;
+}
+.topDiv {
+  background-image: url(@/assets/board/title-bg.png);
+  /* position: absolute; */
+  z-index: 100;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 65px;
+  display: flex;
+  background-size: 100% 65px;
+  justify-content: space-between;
+
+  .logoDiv {
+    padding-top: 0;
+    padding-top: 10px !important;
+    display: flex;
+    width: 30%;
+    padding-left: 60px;
+    // img {
+    //   //   margin-bottom: 20px;
+    // }
+
+    // ::v-deep .el-divider--vertical {
+    //   margin-left: 16px;
+    // }
+
+    // ::v-deep .el-select {
+    //   //   margin-bottom: 30px;
+    //   margin-top: 0;
+    //   width: 120px;
+
+    //   .el-input--suffix .el-input__inner {
+    //     padding-left: 0;
+    //   }
+    // }
+  }
+  .title {
+    flex: 1;
+    text-align: center;
+    padding-top: 10px;
+  }
+
+  .title > span:first-child {
+    font-size: 1.5rem;
+    letter-spacing: 0.3rem;
+    color: white;
+    line-height: 35px;
+  }
+
+  .title > div:last-child {
+    line-height: 35px;
+    /* width: 300px; */
+    margin-top: -20px;
+    margin-left: auto;
+    margin-right: auto;
+  }
+  .iconDiv {
+    text-align: right;
+    padding-right: 2.5rem;
+    padding-top: 1.5rem;
+    font-size: 16px;
+    width: 30%;
+  }
+
+  .iconDiv > span {
+    margin-left: 5px;
+    margin-right: 5px;
+  }
+
+  // .iconDiv > span .exit_btn {
+  //   // background: url("../../../public/images/exit.png") no-repeat left center;
+  //   // background-size: 20px 24px;
+  //   padding-left: 25px;
+  //   color: #fff;
+  //   text-decoration: none;
+  //   cursor: pointer;
+  // }
+
+  // .iconDiv > span .exit_btn:hover {
+  //   text-decoration: underline;
+  // }
+}
+
+.main {
+  padding: 0 20px;
+  padding-top: 5px;
+  height: calc(100% - 90px);
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+
+  ::v-deep .el-tabs__nav-wrap::after {
+    height: 1 !important;
+    background-color: #424040;
+  }
+
+  ::v-deep .el-tabs__item {
+    color: #8e949c;
+    padding: 0 5px;
+    font-size: 12px;
+
+    &:hover {
+      color: #ffffff;
+    }
+  }
+
+  ::v-deep .el-tabs {
+    .is-active {
+      color: #ffffff;
+    }
+
+    .el-tabs__header {
+      margin: 0 0 8px;
+    }
+
+    .el-tabs__active-bar {
+      background-color: #2754dd;
+    }
+
+    .el-tabs__nav-scroll {
+      display: flex;
+      justify-content: center;
+    }
+  }
+
+  & > div {
+    //height: calc(100% - 100px);
+
+    & > div {
+      // border: 1px solid rgba(0, 217, 255, 0.25);
+      // background-color: rgba(0, 119, 255, 0.06);
+      // border-radius: 8px;
+      margin: 0.5rem;
+      background-image: url(@/assets/board/area_border.png);
+      background-size: 100% 100%;
+    }
+
+    &:first-child {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      width: 30%;
+      & > div {
+        width: calc(100% - 10px);
+      }
+      & > div:first-child {
+        // border: none;
+        // border-radius: 0px;
+
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        height: 34%;
+        // padding: 0;
+        // margin-bottom: 0px;
+        // padding-bottom: 10px;
+
+        // & > div {
+        //   width: 49.2%;
+
+        //   & > div {
+        //     width: 100%;
+        //     height: 100%;
+        //     padding: 0.5rem 1rem;
+        //     border: 1px solid rgba(0, 217, 255, 0.25);
+        //     background-color: rgba(0, 119, 255, 0.06);
+        //     border-radius: 8px;
+
+        //     & > p {
+        //       text-align: center;
+        //       font-size: 16px;
+        //     }
+        //   }
+        // }
+      }
+
+      & > div:nth-child(2) {
+        // width: 100%;
+        height: calc(66% - 10px);
+        display: flex;
+        justify-content: space-between;
+        // border: none;
+        // padding: 0;
+      }
+    }
+
+    &:nth-child(2) {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      width: 45%;
+      & > div {
+        width: calc(100% - 10px);
+      }
+      .el-divider {
+        background-color: #1c326a;
+      }
+
+      .el-divider--horizontal {
+        margin: 10px 0;
+      }
+
+      & > div:first-child {
+        height: 80%;
+        display: flex;
+        background-image: none;
+        flex-direction: column;
+        // padding: 0.5rem 1rem;
+        overflow: hidden;
+
+        .box {
+          width: 100%;
+          height: 58%;
+        }
+      }
+
+      & > div:nth-child(2) {
+        height: 20%;
+      }
+    }
+
+    &:nth-child(3) {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      width: 25%;
+
+      & > div:first-child {
+        width: 100%;
+        height: 34%;
+
+        & > div {
+          height: calc(100% - 21px);
+        }
+      }
+
+      & > div:nth-child(2) {
+        width: 100%;
+        height: 66%;
+
+        & > div {
+          height: calc(100% - 21px);
+        }
+      }
+
+      // & > div:nth-child(3) {
+      //   width: 100%;
+      //   height: 34%;
+
+      //   & > div {
+      //     height: calc(100% - 21px);
+      //   }
+      // }
+    }
+  }
+}
+.org-cascader {
+  margin-top: -5px;
+  width:180px;
+
+  ::v-deep .el-input__inner {
+    background-color: transparent !important;
+    border: none !important;
+    color: rgb(230, 230, 230);
+    font-size: 16px;
+  }
+}
+</style>

+ 226 - 0
src/views/board/utils.js

@@ -0,0 +1,226 @@
+// import { dictionary } from "./dictionary";
+
+/**为数组条件增加order属性 */
+function appendOrder(pageResult) {
+  let r = [];
+  let start = (pageResult.pageNumber - 1) * pageResult.pageSize + 1;
+  if (pageResult.list) {
+    pageResult.list.forEach((element) => {
+      r.push({ order: start++, ...element });
+    });
+  }
+
+  return r;
+}
+
+function findMaxIndex(array) {
+  if (!array || array.length === 0) {
+    return;
+  }
+  let max = Math.max(...array);
+  return array.indexOf(max);
+}
+
+function setEchartsTooltip(
+  myChart,
+  xTooptipFormatter,
+  yTooltipFormatter,
+  seriesTooltipFormatter
+) {
+  myChart.on("mouseover", (params) => {
+    xLabel = params.value;
+
+    if (params.componentType === "yAxis") {
+      myChart.setOption({
+        tooltip: {
+          formatter: yTooltipFormatter ? yTooltipFormatter : formateTooltip,
+          alwaysShowContent: true,
+        },
+      });
+    } else if (params.componentType === "series") {
+      myChart.setOption({
+        tooltip: {
+          formatter: seriesTooltipFormatter,
+          alwaysShowContent: true,
+        },
+      });
+    } else if (params.componentType === "xAxis") {
+      myChart.setOption({
+        tooltip: {
+          formatter: xTooptipFormatter ? xTooptipFormatter : formateTooltip,
+          alwaysShowContent: true,
+        },
+      });
+    } else {
+      return;
+    }
+
+    let offsetX = params.event.offsetX + 10;
+    let offsetY = params.event.offsetY + 10;
+    myChart.dispatchAction({
+      type: "showTip",
+      seriesIndex: 0,
+      dataIndex: 0,
+      position: [offsetX, offsetY],
+    });
+  });
+  myChart.on("mouseout", (params) => {
+    xLabel = "";
+    myChart.setOption({
+      tooltip: {
+        formatter: null,
+        alwaysShowContent: false,
+      },
+    });
+  });
+}
+var xLabel = "";
+function formateTooltip(params) {
+  return xLabel;
+}
+
+function getChartDOMSize(chart) {
+  if (!chart) {
+    return;
+  }
+
+  let width = chart._dom.clientWidth;
+  let height = chart._dom.clientHeight;
+  return { width, height };
+}
+
+/**
+ * 生成树
+ * treelist:所有机构列表
+ * topOrgId:顶级机构id,没有则自动查找
+ * miniorType:显示到的最低级机构类型,没有则显示全部
+ */
+function getOrgTree(treelist, topOrgId, miniorType) {
+  let data = treelist;
+  if (!data || data.length === 0) {
+    this.selectedOrg = null;
+    this.defaultExpandedKeys = [];
+    return [];
+  } else {
+    if (!topOrgId) {
+      const topOrg = data.find(
+        (d) => !data.find((d2) => d2.orgId == d.parentId)
+      );
+      if (topOrg) {
+        topOrgId = topOrg.orgId;
+      } else {
+        return [];
+      }
+    }
+    let temp = data.find((d) => d.orgId == topOrgId);
+    if (!temp) {
+      return [];
+    }
+    let top = { id: temp.orgId, label: temp.orgName };
+    top.children = convertToTreeData(data, temp, miniorType);
+    return [top];
+  }
+}
+
+//将机构列表转换为树结构
+function convertToTreeData(array, parent, miniorType) {
+  if (!parent || parent.orgType == miniorType) {
+    return [];
+  }
+
+  let nodes = array.filter((i) => i.parentId == parent.orgId);
+
+  let list = [];
+  nodes.forEach((child) => {
+    let c = { id: child.orgId, label: child.orgName };
+    let children = convertToTreeData(array, child, miniorType);
+    if (children && children.length > 0) {
+      c.children = children;
+    }
+    list.push(c);
+  });
+
+  return list;
+}
+
+// /**找到该机构的上级分行 */
+// function getBranchOrg(orgList, current) {
+//   if (dictionary.orgType.isBranchType(current.orgType)) {
+//     return current;
+//   }
+
+//   var up = current;
+//   while (!dictionary.orgType.isBranchType(up.orgType)) {
+//     up = orgList.find((o) => o.orgId == up.parentId);
+//     if (!up) {
+//       return;
+//     }
+//   }
+
+//   return up;
+// }
+
+// function getBranchOrgById(orgList, orgId) {
+//   let org = orgList.find((org) => org.orgId == orgId);
+//   return getBranchOrg(orgList, org);
+// }
+
+function getURLParam(url, queryName) {
+  if (!url) {
+    return null;
+  }
+  let strs = url.split("?");
+  if (strs.length < 2) {
+    return "";
+  }
+
+  var query = strs[1];
+  var vars = query.split("&");
+  for (var i = 0; i < vars.length; i++) {
+    var pair = vars[i].split("=");
+    if (pair[0] == queryName) {
+      return pair[1];
+    }
+  }
+  return null;
+}
+
+function replaceEmptyProperty(obj, defaultValue) {
+  let copy = { ...obj };
+  for (var p in copy) {
+    if ((typeof copy[p] == "string" && copy[p] == "") || copy[p] == null) {
+      copy[p] = defaultValue;
+    }
+  }
+
+  return copy;
+}
+
+/**********************时间周期定制 **************/
+/**返回时间周期tab中的下一个 */
+function getNextPeriod(periods, current) {
+  let currentIndex = periods.map((t) => t.value).indexOf(current);
+  var nextIndex = periods.length - 1 == currentIndex ? 0 : currentIndex + 1;
+  let next = periods[nextIndex].value;
+  return next;
+}
+/**返回时间周期对应的文件描述 */
+function getPeriodText(periods, value) {
+  const period = periods.find((p) => p.value == value);
+  if (period) {
+    return period.text;
+  }
+  return "";
+}
+/**********************时间周期定制 **************/
+export {
+  appendOrder,
+  findMaxIndex,
+  setEchartsTooltip,
+  getChartDOMSize,
+  getOrgTree,
+  getURLParam,
+  replaceEmptyProperty,
+  getNextPeriod,
+  getPeriodText
+};

Vissa filer visades inte eftersom för många filer har ändrats