sunlupeng 1 jaar geleden
bovenliggende
commit
fabeebd4b5
10 gewijzigde bestanden met toevoegingen van 550 en 12 verwijderingen
  1. 1 1
      config/index.js
  2. 2 1
      package.json
  3. 54 0
      src/api/certManage.js
  4. 104 0
      src/components/RightToolbar/index.vue
  5. 9 1
      src/main.js
  6. 2 1
      src/permission.js
  7. 1 0
      src/router/index.js
  8. 7 0
      src/utils/index.js
  9. 299 0
      src/views/certManage/certSetList.vue
  10. 71 8
      yarn.lock

+ 1 - 1
config/index.js

@@ -14,7 +14,7 @@ module.exports = {
 
     // Various Dev Server settings
     // host: 'localhost', // can be overwritten by process.env.HOST
-    host: '192.168.100.205', // can be overwritten by process.env.HOST
+    host: '192.168.100.104', // can be overwritten by process.env.HOST
     port: 8081, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
     autoOpenBrowser: true,
     errorOverlay: true,

+ 2 - 1
package.json

@@ -12,10 +12,11 @@
     "test": "npm run lint"
   },
   "dependencies": {
+    "@riophae/vue-treeselect": "0.4.0",
     "axios": "0.17.1",
     "clipboard": "1.7.1",
     "echarts": "3.8.5",
-    "element-ui": "2.0.8",
+    "element-ui": "2.15.13",
     "file-saver": "1.3.3",
     "font-awesome": "4.7.0",
     "js-cookie": "2.2.0",

+ 54 - 0
src/api/certManage.js

@@ -1,5 +1,59 @@
 import request from '@/utils/request'
 
+// 查询证书列表
+export function listDept(query) {
+  return request({
+    url: '/mall-certificat/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询证书列表(排除节点)
+export function listDeptExcludeChild(query) {
+  return request({
+    url: '/mall-certificat/list/excludeChild',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询证书详细
+export function getDept(query) {
+  return request({
+    url: '/mall-certificat/getInfo',
+    method: 'get',
+    params: query
+  })
+}
+
+// 新增证书
+export function addDept(data) {
+  return request({
+    url: '/mall-certificat/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改证书
+export function updateDept(data) {
+  return request({
+    url: '/mall-certificat/edit',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除证书
+export function delDept(query) {
+  return request({
+    url: '/mall-certificat/remove',
+    method: 'post',
+    params: query
+  })
+}
+
 export function list(query) {
   return request({
     url: '/mall-integral-obtain/certificate/sys/page',

+ 104 - 0
src/components/RightToolbar/index.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="top-right-btn" :style="style">
+    <el-row>
+      <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
+        <el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
+      </el-tooltip>
+      <el-tooltip class="item" effect="dark" content="刷新" placement="top">
+        <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
+      </el-tooltip>
+      <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
+        <el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" />
+      </el-tooltip>
+    </el-row>
+    <el-dialog :title="title" :visible.sync="open" append-to-body>
+      <el-transfer
+        :titles="['显示', '隐藏']"
+        v-model="value"
+        :data="columns"
+        @change="dataChange"
+      ></el-transfer>
+    </el-dialog>
+  </div>
+</template>
+<script>
+export default {
+  name: "RightToolbar",
+  data() {
+    return {
+      // 显隐数据
+      value: [],
+      // 弹出层标题
+      title: "显示/隐藏",
+      // 是否显示弹出层
+      open: false,
+    };
+  },
+  props: {
+    showSearch: {
+      type: Boolean,
+      default: true,
+    },
+    columns: {
+      type: Array,
+    },
+    search: {
+      type: Boolean,
+      default: true,
+    },
+    gutter: {
+      type: Number,
+      default: 10,
+    },
+  },
+  computed: {
+    style() {
+      const ret = {};
+      if (this.gutter) {
+        ret.marginRight = `${this.gutter / 2}px`;
+      }
+      return ret;
+    }
+  },
+  created() {
+    // 显隐列初始默认隐藏列
+    for (let item in this.columns) {
+      if (this.columns[item].visible === false) {
+        this.value.push(parseInt(item));
+      }
+    }
+  },
+  methods: {
+    // 搜索
+    toggleSearch() {
+      this.$emit("update:showSearch", !this.showSearch);
+    },
+    // 刷新
+    refresh() {
+      this.$emit("queryTable");
+    },
+    // 右侧列表元素变化
+    dataChange(data) {
+      for (let item in this.columns) {
+        const key = this.columns[item].key;
+        this.columns[item].visible = !data.includes(key);
+      }
+    },
+    // 打开显隐列dialog
+    showColumn() {
+      this.open = true;
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+::v-deep .el-transfer__button {
+  border-radius: 50%;
+  padding: 12px;
+  display: block;
+  margin-left: 0px;
+}
+::v-deep .el-transfer__button:first-child {
+  margin-bottom: 10px;
+}
+</style>

+ 9 - 1
src/main.js

@@ -13,6 +13,9 @@ import store from './store'
 import './icons' // icon
 import './permission' // permission control
 // import './mock' // simulation data
+import { handleTree,resetForm } from "@/utils/index";
+// 自定义表格工具组件
+import RightToolbar from "@/components/RightToolbar"
 
 Vue.use(Element, {
   size: 'medium' // set element-ui default size
@@ -24,8 +27,13 @@ const prodUrl = 'http://47.103.79.143:9085/admin/storage/create';//阿里云测
 const devUrl = 'http://47.103.79.143:9085/admin/storage/create';//本地测试地址
 
 const baseUrl = process.env.NODE_ENV === 'production' ? prodUrl : devUrl;
+// 全局方法挂载
 Vue.prototype.upLoadUrl = baseUrl;
-Vue.config.productionTip = false
+Vue.config.productionTip = false;
+Vue.prototype.handleTree = handleTree;
+Vue.prototype.resetForm = resetForm;
+// 全局组件挂载
+Vue.component('RightToolbar', RightToolbar);
 
 new Vue({
   el: '#app',

+ 2 - 1
src/permission.js

@@ -83,7 +83,8 @@ const myRoles = [
   'festivalManage', 
   'festivalList', 
 
-  'certManage', 
+  'certManage',
+  'certSetList', 
   'certRules',
   'certList', 
 

+ 1 - 0
src/router/index.js

@@ -280,6 +280,7 @@ export const asyncRouterMap = [
       icon: 'zhengshu'
     },
     children: [
+      { path: 'certSetList', component: _import('certManage/certSetList'), name: 'certSetList', meta: { title: '证书配置列表', noCache: true }},
       { path: 'certRules', component: _import('certManage/certRules'), name: 'certRules', meta: { title: '积分获取规则', noCache: true }},
       { path: 'certList', component: _import('certManage/certList'), name: 'certList', meta: { title: '证书列表', noCache: true }},
       

+ 7 - 0
src/utils/index.js

@@ -53,6 +53,13 @@ export function handleTree(data, id, parentId, children) {
   return tree;
 }
 
+// 表单重置
+export function resetForm(refName) {
+  if (this.$refs[refName]) {
+    this.$refs[refName].resetFields();
+  }
+}
+
 export function parseTime(time, cFormat) {
   if (arguments.length === 0) {
     return null

+ 299 - 0
src/views/certManage/certSetList.vue

@@ -0,0 +1,299 @@
+<template>
+    <div class="app-container">
+      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
+        <el-form-item label="证书类型" prop="typeName">
+          <el-input
+            v-model="queryParams.typeName"
+            placeholder="请输入证书类型"
+            clearable
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleQuery">查找</el-button>
+          <el-button class="filter-item" type="primary" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+          <el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleAdd">添加</el-button>
+          <el-button class="filter-item" type="info" icon="el-icon-sort" @click="toggleExpandAll">展开/折叠</el-button>
+        </el-form-item>
+      </el-form>
+      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
+      <el-table
+        v-if="refreshTable"
+        v-loading="loading"
+        :data="deptList"
+        row-key="id"
+        border
+        :default-expand-all="isExpandAll"
+        :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+      >
+        <el-table-column prop="typeName" label="证书类型" min-width="180px"></el-table-column>
+        <el-table-column prop="orderNum" label="排序" align="center"></el-table-column>
+        <el-table-column prop="integral" label="积分" align="center"></el-table-column>
+        <el-table-column label="创建时间" align="center" prop="createTime">
+        </el-table-column>
+        <el-table-column label="操作" align="center" min-width="110px">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="primary"
+              @click="handleUpdate(scope.row)"
+            >修改</el-button>
+            <el-button
+              size="mini"
+              type="success"
+              @click="handleAdd(scope.row)"
+            >添加</el-button>
+            <el-button
+              v-if="scope.row.parentId != 0"
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+  
+      <!-- 添加或修改证书对话框 -->
+      <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
+        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+          <el-row>
+            <el-col :span="24" v-if="form.parentId !== 0">
+              <el-form-item label="上级类型" prop="parentId">
+                <treeselect default-expand-all v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级类型" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="证书类型" prop="typeName">
+                <el-input v-model="form.typeName" placeholder="请输入证书类型" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="积分" prop="integral">
+                <el-input-number v-model="form.integral" controls-position="right" :min="0" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="显示排序" prop="orderNum">
+                <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/certManage";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  
+  export default {
+    components: { Treeselect },
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 表格树数据
+        deptList: [],
+        // 证书树选项
+        deptOptions: [],
+        // 弹出层标题
+        title: "",
+        // 是否显示弹出层
+        open: false,
+        // 是否展开,默认全部展开
+        isExpandAll: true,
+        // 重新渲染表格状态
+        refreshTable: true,
+        // 查询参数
+        queryParams: {
+          typeName: undefined,
+        },
+        // 表单参数
+        form: {},
+        // 表单校验
+        rules: {
+          parentId: [
+            { required: true, message: "上级类型不能为空", trigger: "blur" }
+          ],
+          typeName: [
+            { required: true, message: "证书类型不能为空", trigger: "blur" }
+          ],
+          orderNum: [
+            { required: true, message: "显示排序不能为空", trigger: "blur" }
+          ],
+          integral: [
+            { required: true, message: "积分不能为空", trigger: "blur" }
+          ],
+          email: [
+            {
+              type: "email",
+              message: "请输入正确的邮箱地址",
+              trigger: ["blur", "change"]
+            }
+          ],
+          phone: [
+            {
+              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+              message: "请输入正确的手机号码",
+              trigger: "blur"
+            }
+          ]
+        }
+      };
+    },
+    created() {
+      this.getList();
+    },
+    methods: {
+      /** 查询证书列表 */
+      getList() {
+        this.loading = true;
+        listDept(this.queryParams).then(response => {
+          this.deptList = this.handleTree(response.data.data,'id');
+          console.log(this.deptList);
+          this.loading = false;
+        });
+      },
+      /** 转换证书数据结构 */
+      normalizer(node) {
+        if (node.children && !node.children.length) {
+          delete node.children;
+        }
+        return {
+          id: node.id,
+          label: node.typeName,
+          children: node.children
+        };
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          id: undefined,
+          parentId: undefined,
+          typeName: undefined,
+          orderNum: undefined,
+          integral:undefined,
+          leader: undefined,
+          phone: undefined,
+          email: undefined,
+          status: "0"
+        };
+        this.resetForm("form");
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm("queryForm");
+        this.handleQuery();
+      },
+      /** 新增按钮操作 */
+      handleAdd(row) {
+        this.reset();
+        if (row != undefined) {
+          this.form.parentId = row.id;
+        }
+        this.open = true;
+        this.title = "添加证书";
+        listDept().then(response => {
+          this.deptOptions = this.handleTree(response.data.data, "id");
+        });
+      },
+      /** 展开/折叠操作 */
+      toggleExpandAll() {
+        this.refreshTable = false;
+        this.isExpandAll = !this.isExpandAll;
+        this.$nextTick(() => {
+          this.refreshTable = true;
+        });
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        this.reset();
+        getDept({id:row.id}).then(response => {
+          this.form = response.data.data;
+          this.open = true;
+          this.title = "修改证书";
+          listDeptExcludeChild({id:row.id}).then(response => {
+            this.deptOptions = this.handleTree(response.data.data, "id");
+            if (this.deptOptions.length == 0) {
+              const noResultsOptions = { id: this.form.parentId, typeName: this.form.parentName, children: [] };
+              this.deptOptions.push(noResultsOptions);
+            }
+          });
+        });
+      },
+      /** 提交按钮 */
+      submitForm: function() {
+        this.$refs["form"].validate(valid => {
+          if (valid) {
+            if (this.form.id != undefined) {
+              updateDept(this.form).then(response => {
+                this.$notify({
+                            title: '成功',
+                            message: '修改成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                this.open = false;
+                this.getList();
+              });
+            } else {
+              addDept(this.form).then(response => {
+                this.$notify({
+                            title: '成功',
+                            message: '新增成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                this.open = false;
+                this.getList();
+              });
+            }
+          }
+        });
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        this.$confirm('是否确认删除名称为"' + row.typeName + '"的数据项?', "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+        .then(function() {
+          return delDept({id:row.id});
+        }).then(() => {
+          this.getList();
+          this.$notify({
+                            title: '成功',
+                            message: '删除成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+        }).catch(() => {});
+      }
+    }
+  };
+  </script>
+  

+ 71 - 8
yarn.lock

@@ -49,6 +49,13 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
+"@babel/runtime@^7.3.1":
+  version "7.23.2"
+  resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
+  integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
+  dependencies:
+    regenerator-runtime "^0.14.0"
+
 "@babel/template@7.0.0-beta.31":
   version "7.0.0-beta.31"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
@@ -103,6 +110,20 @@
     mkdirp "^1.0.4"
     rimraf "^3.0.2"
 
+"@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"
+
 "@tootallnate/once@1":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -732,9 +753,9 @@ babel-helper-replace-supers@^6.24.1:
     babel-traverse "^6.24.1"
     babel-types "^6.24.1"
 
-babel-helper-vue-jsx-merge-props@2.0.3, babel-helper-vue-jsx-merge-props@^2.0.0:
+babel-helper-vue-jsx-merge-props@2.0.3, babel-helper-vue-jsx-merge-props@^2.0.0, babel-helper-vue-jsx-merge-props@^2.0.3:
   version "2.0.3"
-  resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6"
+  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-helpers@^6.24.1:
@@ -2730,6 +2751,11 @@ duplexify@^3.4.2, duplexify@^3.6.0:
     readable-stream "^2.0.0"
     stream-shift "^1.0.0"
 
+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==
+
 ecc-jsbn@~0.1.1:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@@ -2760,14 +2786,16 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz#0f75a1dce26dffbd5a0f7212e5b87fe0b61cbc76"
   integrity sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==
 
-element-ui@2.0.8:
-  version "2.0.8"
-  resolved "https://registry.npmmirror.com/element-ui/-/element-ui-2.0.8.tgz#cee493530a8e7a3c69bb83dc22f252a5b9ce0a11"
-  integrity sha512-Y0eiOhJZl4lgrGaGK6z02YtLsWljochxKud6IX4q2ju/NraZfexTah3GH+6x8D0IhplVP+QxHZ1+gSqnIbnmmQ==
+element-ui@2.15.13:
+  version "2.15.13"
+  resolved "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.13.tgz#380f019ee7d15b181105587b41fd5914c308a143"
+  integrity sha512-LJoatEYX6WV74FqXBss8Xfho9fh9rjDSzrDrTyREdGb1h1R3uRvmLh5jqp2JU137aj4/BgqA3K06RQpQBX33Bg==
   dependencies:
     async-validator "~1.8.1"
     babel-helper-vue-jsx-merge-props "^2.0.0"
     deepmerge "^1.2.0"
+    normalize-wheel "^1.0.1"
+    resize-observer-polyfill "^1.5.0"
     throttle-debounce "^1.0.1"
 
 elliptic@^6.5.3:
@@ -3655,6 +3683,11 @@ functional-red-black-tree@^1.0.1:
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
   integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
 
+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==
+
 gauge@^3.0.0:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"
@@ -4640,6 +4673,11 @@ is-primitive@^2.0.0:
   resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
   integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU=
 
+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-regex@^1.0.4, is-regex@^1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@@ -5013,9 +5051,9 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
+lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
   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@^1.0.2:
@@ -5121,6 +5159,11 @@ map-visit@^1.0.0:
   dependencies:
     object-visit "^1.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==
+
 math-expression-evaluator@^1.2.14:
   version "1.3.8"
   resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.8.tgz#320da3b2bc1512f4f50fc3020b2b1cd5c8e9d577"
@@ -5678,6 +5721,11 @@ normalize-url@^1.4.0:
     query-string "^4.1.0"
     sort-keys "^1.0.0"
 
+normalize-wheel@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmmirror.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45"
+  integrity sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==
+
 normalize.css@7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf"
@@ -6962,6 +7010,11 @@ regenerator-runtime@^0.11.0:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
   integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
 
+regenerator-runtime@^0.14.0:
+  version "0.14.0"
+  resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
+  integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
+
 regenerator-transform@^0.10.0:
   version "0.10.1"
   resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
@@ -7107,6 +7160,11 @@ requires-port@^1.0.0:
   resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
   integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
 
+resize-observer-polyfill@^1.5.0:
+  version "1.5.1"
+  resolved "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
+  integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
+
 resolve-cwd@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
@@ -8608,6 +8666,11 @@ vuex@3.0.1:
   resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"
   integrity sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w==
 
+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-chokidar2@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"