Quellcode durchsuchen

添加教育培训计划报表页面

凉纪 vor 2 Jahren
Ursprung
Commit
1d1441d388

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
     "build": "vue-cli-service build"
   },
   "dependencies": {
+    "@riophae/vue-treeselect": "0.4.0",
     "amfe-flexible": "^2.2.1",
     "axios": "^1.3.4",
     "core-js": "^3.23.3",

+ 9 - 13
src/components/dateCell/index.vue

@@ -40,27 +40,28 @@ export default {
       type: String,
       default: 'time',
     },
-    //时间格式 个别模式下不启用
-    format:{
-      type: String,
-      default: 'YYYY-MM-DD',
-    }
   },
   data(){
     return{
       showPicker:false,
       selected:null,
       columns: [],
+      type: {
+        'date': {value: 'YYYY-MM-DD'},
+        'time': {value: 'mm:ss'},
+        'year-month':{ value: 'YYYY-MM'},
+        'month-day': {value: 'MM-DD'},
+        'datetime':{ value: 'YYYY-MM-DD HH:mm:ss'},
+      }
     }
   },
   watch:{
     value:{
       handler (val) {
-        console.log(val,'val111')
         if(!val){
           this.selected = null
         }else{
-          this.selected =  formatDate(val,'YYYY-MM-DD HH:mm:ss');
+          this.selected =  formatDate(val,this.type[this.dateType].value);
         }
       },
       immediate: true
@@ -71,12 +72,7 @@ export default {
       this.showPicker = false;
     },
     pickerConfirm(val){
-      console.log(val,'val')
-      if(this.dateType === 'time' || this.dateType === 'year-month' || this.dateType === 'month-day') {
-        this.selected = val;
-      }else {
-        this.selected = dayjs(val).format(this.format) ;
-      }
+      this.selected = formatDate(val,this.type[this.dateType].value);
       this.showPicker = false;
       this.$emit('change',this.selected)
     },

+ 117 - 0
src/components/orgTree/index.vue

@@ -0,0 +1,117 @@
+<template>
+  <div class="orgTree">
+      <tree-select
+        @select="onSelect"
+        v-model="orgId"
+        :options="treeData"
+        placeholder="请选择归属机构"
+        :normalizer="tenantIdnormalizer"
+        :show-count="true" >
+      </tree-select>
+  </div>
+</template>
+<script>
+import TreeSelect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import {deptTreeList} from "@/api/public";
+
+export default {
+  components:{
+    TreeSelect
+  },
+  props:{
+    value:{
+      type: String,
+      default: null,
+    },
+  },
+  data() {
+    return {
+      treeData: [],
+      orgId:null,
+    }
+  },
+  created() {
+    this.getTreeList();
+  },
+  watch:{
+    value:{
+      handler (val) {
+        this.orgId = val;
+      }
+    },
+  },
+  methods: {
+    /** treeSelect组件自定义数据*/
+    tenantIdnormalizer(node, instanceId) {
+      if (!node.children) {
+        delete node.children
+      }
+      return {
+        id: node.id,
+        label: node.name,
+        children: node.children
+      }
+    },
+    //获取机构树
+    getTreeList(){
+      deptTreeList(this.orgId).then(res=>{
+        this.$nextTick(()=>{
+          this.treeData = res.data;
+        })
+        console.log(res,'3333')
+      })
+    },
+    onSelect(value){
+      console.log(value,'tttttt')
+      this.$emit('change',value.id);
+    }
+  },
+  model:{
+    prop:'orgId',
+    event:'change'
+  }
+}
+</script>
+
+<style lang="scss">
+  .orgTree {
+    font-size: 28px;
+    svg {
+      background-size: 22px 22px;
+      width: 22px;
+      height: 22px;
+    }
+
+    .vue-treeselect__control {
+      width: 100%;
+      height: 90px;
+      padding: 0 20px;
+      border-radius: 0;
+      border: none;
+      border-bottom: 1px solid #dcdfe6;
+    }
+
+    .vue-treeselect__placeholder, .vue-treeselect__single-value {
+      height: 90px;
+      line-height: 90px;
+    }
+
+    .vue-treeselect__menu {
+      padding: 20px;
+    }
+    .vue-treeselect__label {
+      padding: 15px 20px;
+    }
+    .vue-treeselect__x-container{
+      width:  50px;
+    }
+    .vue-treeselect__control-arrow-container {
+      width: 50px;
+    }
+    .vue-treeselect--single .vue-treeselect__option--selected{
+      font-weight: 500;
+      color: #589eec;
+    }
+  }
+</style>

+ 29 - 6
src/components/selectCell/index.vue

@@ -5,7 +5,7 @@
       <van-picker
         v-bind="$attrs"
         show-toolbar
-        value-key="dictLabel"
+        :value-key="prop.label"
         v-model="selected"
         :columns="columns"
         @confirm="pickerConfirm"
@@ -19,18 +19,36 @@
 import {getDict} from "@/api/toConsult";
 export default {
   props:{
+    //双向绑定的数据
     value:{
       type: [String,Number],
       default: null,
     },
+    //字典表
     dict:{
       type: String,
       default: null,
     },
+    //标题
     title:{
       type: String,
       default: null,
     },
+    //父组件给的列表数据
+    dataList:{
+      type: Array,
+      default: ()=>[],
+    },
+    //自定义字段
+    prop:{
+      type: Object,
+      default: ()=>(
+        {
+          label:'dictLabel',
+          value:'dictValue'
+        }
+      ) ,
+    }
   },
   data(){
     return{
@@ -41,9 +59,14 @@ export default {
     }
   },
   created() {
+    if(!this.dict) return;
     this.queryDict();
   },
   watch:{
+    dataList(){
+      if(this.dict) return;
+      this.columns = this.dataList;
+    },
     value:{
       handler (val) {
         if(!val){
@@ -51,9 +74,9 @@ export default {
           this.label = null;
         }else{
           this.columns.forEach(v=>{
-            if(v.dictValue === val){
+            if(v[this.prop.value] === val){
               this.selected = v;
-              this.label = v.dictLabel;
+              this.label = v[this.prop.label];
             }
           })
           // this.selected = val;
@@ -66,7 +89,7 @@ export default {
   methods:{
     queryDict(){
       getDict( this.dict ).then(res => {
-        let { code, data, msg } = res
+        let { code, data, msg } = res;
         if (code == 200) {
          this.columns = data;
         }
@@ -77,9 +100,9 @@ export default {
     },
     pickerConfirm(val){
       this.selected = val;
-      this.label = val.dictLabel;
+      this.label = val[this.prop.label];
       this.showPicker = false;
-      this.$emit('change',this.selected.dictValue)
+      this.$emit('change',this.selected[this.prop.value])
     },
     clickItem(){
       this.showPicker = true;

+ 6 - 1
src/router/router.config.js

@@ -114,7 +114,12 @@ export let routers = [
         component: () => import('@/views/menu/monitoringCall/index'),
         meta: { title: '监控调阅', keepAlive: false }
       },
-      
+      {
+        path: '/educationStatistics',
+        name: 'educationStatistics',
+        component: () => import('@/views/menu/educationStatistics/index'),
+        meta: { title: '教育培训统计报表', keepAlive: false }
+      },
     ],
   },
 ]

+ 3 - 4
src/utils/request.js

@@ -1,6 +1,5 @@
 import axios from 'axios'
 import router from '@/router'
-import store from '@/store'
 import { Toast } from 'vant'
 // 根据环境不同引入不同api地址
 import { baseApi } from '@/config'
@@ -51,14 +50,14 @@ let success = response => {
     Toast.fail(res.msg);
     sessionStorage.clear();
     router.push('/login');
-    return  Promise.reject('error');
+    return  Promise.reject(res.msg);
   }
   if (res.code === 500) {
     Toast.fail('请求错误');
-    return  Promise.reject('error');
+    return  Promise.reject(res.msg);
   }
   Toast.fail(res.msg);
-  return  Promise.reject('error');
+  return  Promise.reject(res.msg);
 }
 
 let error = error => {

+ 2 - 1
src/views/home/menu.vue

@@ -55,7 +55,8 @@ export default {
               menu:'安全检查登记',
             },
             {
-              menu:'隐患问题清单',
+              menu:'教育培训统计报表',
+              path:'/educationStatistics',
             },
             {
               menu:'外包评价',

+ 7 - 3
src/views/menu/LZRegister/edit.vue

@@ -141,7 +141,7 @@
 
     <!--  nfc弹窗  -->
     <transition name="van-fade">
-      <van-popup v-model="visible" get-container="#app" lock-scroll>
+      <van-popup v-model="visible" get-container="lz-edit" lock-scroll>
         <div class="nfc-panel">
            <div>
               <p class="top-text">将手机背部靠近NFC标签扫描</p>
@@ -168,7 +168,7 @@ import NavBar from '@/components/NavBar';
 import SelectCell from '@/components/selectCell';
 import DateCell from '@/components/dateCell';
 import Uploader from '@/components/upload';
-import {taskDetails,saveTaskData,json} from "@/views/menu/LZRegister/api";
+import {taskDetails,saveTaskData} from "@/views/menu/LZRegister/api";
 import {formatDate} from "@/filters/filter";
 export default {
   components:{NavBar,SelectCell,DateCell,Uploader},
@@ -396,7 +396,11 @@ export default {
 }
 </script>
 <style lang="scss">
-
+  .lz-edit{
+    .van-popup--center{
+      border-radius: 20px;
+    }
+  }
 </style>
 <style lang="scss" scoped>
   .lz-edit{

+ 86 - 0
src/views/menu/educationStatistics/api.js

@@ -0,0 +1,86 @@
+import request from "@/utils/request";
+//获取列表
+export function dataList(data) {
+  return request({
+    url: "/core/eduTask/report",
+    method: "post",
+    data,
+  });
+}
+//获取计划列表
+export function planList(orgId){
+  return request({
+    url: "/core/plan/planList/"+orgId,
+    method: "get",
+  });
+}
+export const json = {
+  "msg": "操作成功",
+  "code": 200,
+  "data": [
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974731112400,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974794027000,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974794027000,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974794027000,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974794027000,
+      "name": "网点安全员每月培训计划"
+    },
+    {
+      "id": 1698299974794027000,
+      "name": "网点安全员每月培训计划"
+    }
+  ]
+}

+ 127 - 0
src/views/menu/educationStatistics/index.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="educationStatistics">
+    <NavBar />
+    <div class="statistics-container">
+      <org-tree v-model="query.orgId" @change="getDataList"></org-tree>
+      <select-cell title="教育计划名称" v-model="query.planId" :dataList="planList" :prop="prop" @change="getDataList"/>
+      <date-cell title="统计月份"  v-model="query.date" date-type="year-month" @change="getDataList"/>
+      <div class="card-list">
+        <van-empty description="暂无数据" v-if="!dataList || dataList.length === 0" />
+        <template v-else>
+          <van-cell-group  v-for="(v,i) in dataList">
+            <van-cell :title="v.orgName" >
+              <template #extra>
+                <div class="card-num">
+                  {{v.finishRate}}
+                </div>
+              </template>
+              <template #label>
+                <div class="flex-box">
+                  <div>应培训数:{{v.shouldFinish}}</div>
+                  <div>已培训数:{{v.finish}}</div>
+                </div>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </template>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import NavBar from '@/components/NavBar'
+import OrgTree from '@/components/orgTree'
+import dateCell from '@/components/dateCell'
+import selectCell from '@/components/selectCell'
+import {dataList,planList} from './api'
+import {mapGetters} from "vuex";
+import {formatDate} from "@/filters/filter";
+export default {
+  components: {
+    NavBar,
+    OrgTree,
+    dateCell,
+    selectCell
+  },
+  data() {
+    return {
+      query:{
+        date:null,
+        orgId:null,
+        planId:null,
+      },
+      planList:[],
+      prop:{
+        label:'name',
+        value:'id',
+      },
+      loading:false,
+      dataList:[]
+    }
+  },
+  mounted() {
+    this.initData();
+  },
+  computed:{
+    ...mapGetters(['orgId']),
+  },
+  methods: {
+    initData(){
+      this.query.orgId = this.orgId;
+      this.getPlanList();
+    },
+    getPlanList(){
+      planList(this.query.orgId).then(res=>{
+        this.planList = res.data;
+        this.query.planId = res.data[0].id;
+        this.query.date = formatDate(new Date(),'YYYY-MM');
+        this.getDataList();
+      })
+    },
+    getDataList(){
+      let data = {
+        ...this.query
+      }
+      data.date = `${this.query.date}-01`;
+      if(!this.query.orgId) return this.$toast('请选择机构');
+      dataList(data).then(res=>{
+        this.dataList = res.data;
+      })
+    }
+  }
+}
+</script>
+<style lang="scss">
+.van-cell-group{
+  margin-bottom: 20px;
+}
+.van-cell-group:last-child{
+  margin-bottom: 0;
+}
+</style>
+<style lang="scss" scoped>
+  .educationStatistics{
+
+  }
+  .statistics-container{
+
+  }
+  .card-list{
+    padding: 20px;
+    height: calc(100vh - 550px);
+    overflow: auto;
+  }
+  .card-num{
+    display: flex;
+    align-items: center;
+    font-size: 28px;
+    color: #009dff;
+  }
+  .flex-box{
+    display: flex;
+    align-items: center;
+    >div{
+      margin-right: 40px;
+    }
+  }
+</style>

+ 58 - 20
yarn.lock

@@ -1073,6 +1073,13 @@
   dependencies:
     regenerator-runtime "^0.14.0"
 
+"@babel/runtime@^7.3.1":
+  version "7.22.11"
+  resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4"
+  integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==
+  dependencies:
+    regenerator-runtime "^0.14.0"
+
 "@babel/template@^7.0.0":
   version "7.18.6"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31"
@@ -1310,6 +1317,20 @@
   resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
   integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
 
+"@riophae/vue-treeselect@0.4.0":
+  version "0.4.0"
+  resolved "https://registry.npmmirror.com/@riophae/vue-treeselect/-/vue-treeselect-0.4.0.tgz#0baed5a794cffc580b63591f35c125e51c0df241"
+  integrity sha512-J4atYmBqXQmiPFK/0B5sXKjtnGc21mBJEiyKIDZwk0Q9XuynVFX6IJ4EpaLmUgL5Tve7HAS7wkiGGSti6Uaxcg==
+  dependencies:
+    "@babel/runtime" "^7.3.1"
+    babel-helper-vue-jsx-merge-props "^2.0.3"
+    easings-css "^1.0.0"
+    fuzzysearch "^1.0.3"
+    is-promise "^2.1.0"
+    lodash "^4.0.0"
+    material-colors "^1.2.6"
+    watch-size "^2.0.0"
+
 "@sideway/address@^4.1.3":
   version "4.1.4"
   resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
@@ -2107,6 +2128,11 @@ axios@^1.3.4:
     form-data "^4.0.0"
     proxy-from-env "^1.1.0"
 
+babel-helper-vue-jsx-merge-props@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.npmmirror.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6"
+  integrity sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==
+
 babel-loader@^8.2.2:
   version "8.2.5"
   resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e"
@@ -2192,11 +2218,6 @@ bluebird@^3.1.1:
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
   integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
 
-blueimp-canvas-to-blob@^3.29.0:
-  version "3.29.0"
-  resolved "https://registry.npmmirror.com/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.29.0.tgz#d965f06cb1a67fdae207a2be56683f55ef531466"
-  integrity sha512-0pcSSGxC0QxT+yVkivxIqW0Y4VlO2XSDPofBAqoJ1qJxgH9eiUDLv50Rixij2cDuEfx4M6DpD9UGZpRhT5Q8qg==
-
 body-parser@1.20.0:
   version "1.20.0"
   resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5"
@@ -2560,14 +2581,6 @@ compression@^1.7.4:
     safe-buffer "5.1.2"
     vary "~1.1.2"
 
-compressorjs@^1.2.1:
-  version "1.2.1"
-  resolved "https://registry.npmmirror.com/compressorjs/-/compressorjs-1.2.1.tgz#4dee18ef5032f8166bd0a3258f045eda2cd07671"
-  integrity sha512-+geIjeRnPhQ+LLvvA7wxBQE5ddeLU7pJ3FsKFWirDw6veY3s9iLxAQEw7lXGHnhCJvBujEQWuNnGzZcvCvdkLQ==
-  dependencies:
-    blueimp-canvas-to-blob "^3.29.0"
-    is-blob "^2.1.0"
-
 concat-map@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -2978,6 +2991,11 @@ duplexer@^0.1.2:
   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
   integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
 
+easings-css@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmmirror.com/easings-css/-/easings-css-1.0.0.tgz#dde569003bb7a4a0c0b77878f5db3e0be5679c81"
+  integrity sha512-7Uq7NdazNfVtr0RNmPAys8it0zKCuaqxJStYKEl72D3j4gbvXhhaM7iWNbqhA4C94ygCye6VuyhzBRQC4szeBg==
+
 easy-stack@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066"
@@ -3341,6 +3359,11 @@ function-bind@^1.1.1:
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
   integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
 
+fuzzysearch@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/fuzzysearch/-/fuzzysearch-1.0.3.tgz#dffc80f6d6b04223f2226aa79dd194231096d008"
+  integrity sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg==
+
 gensync@^1.0.0-beta.2:
   version "1.0.0-beta.2"
   resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@@ -3681,11 +3704,6 @@ is-binary-path@~2.1.0:
   dependencies:
     binary-extensions "^2.0.0"
 
-is-blob@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.npmmirror.com/is-blob/-/is-blob-2.1.0.tgz#e36cd82c90653f1e1b930f11baf9c64216a05385"
-  integrity sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw==
-
 is-core-module@^2.9.0:
   version "2.9.0"
   resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
@@ -3749,6 +3767,11 @@ is-plain-object@^2.0.4:
   dependencies:
     isobject "^3.0.1"
 
+is-promise@^2.1.0:
+  version "2.2.2"
+  resolved "https://registry.npmmirror.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
+  integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
+
 is-stream@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -3982,9 +4005,9 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
 
-lodash@^4.17.14, lodash@^4.17.20, lodash@^4.17.21:
+lodash@^4.0.0, lodash@^4.17.14, lodash@^4.17.20, lodash@^4.17.21:
   version "4.17.21"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+  resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 
 log-symbols@^4.1.0:
@@ -4040,6 +4063,11 @@ make-dir@^3.0.2, make-dir@^3.1.0:
   dependencies:
     semver "^6.0.0"
 
+material-colors@^1.2.6:
+  version "1.2.6"
+  resolved "https://registry.npmmirror.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
+  integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==
+
 mdn-data@2.0.14:
   version "2.0.14"
   resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
@@ -5773,6 +5801,11 @@ vue-hot-reload-api@^2.3.0:
   resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
   integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
 
+vue-jstree@^2.1.6:
+  version "2.1.6"
+  resolved "https://registry.npmmirror.com/vue-jstree/-/vue-jstree-2.1.6.tgz#44827ad72953ed77da6590ce4e8f37f7787f8653"
+  integrity sha512-vtUmhLbfE2JvcnYNRXauJPkNJSRO/f9BTsbxV+ESXP/mMQPVUIYI4EkSHKSEOxVDHTU7SfLp/AxplmaAl6ctcg==
+
 vue-lazyload@1.2.3:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/vue-lazyload/-/vue-lazyload-1.2.3.tgz#901f9ec15c7e6ca78781a2bae4a343686bdedb2c"
@@ -5818,6 +5851,11 @@ vuex@^3.6.2:
   resolved "https://registry.npmmirror.com/vuex/-/vuex-3.6.2.tgz#236bc086a870c3ae79946f107f16de59d5895e71"
   integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==
 
+watch-size@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/watch-size/-/watch-size-2.0.0.tgz#096ee28d0365bd7ea03d9c8bf1f2f50a73be1474"
+  integrity sha512-M92R89dNoTPWyCD+HuUEDdhaDnh9jxPGOwlDc0u51jAgmjUvzqaEMynXSr3BaWs+QdHYk4KzibPy1TFtjLmOZQ==
+
 watchpack@^2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"