执行过npm install命令的vue-element-admin源码
康凯
2022-05-20 aa4c235a8ca67ea8b731f90c951a465e92c0a865
1
{"remainingRequest":"D:\\源码\\vue-element-admin-master\\node_modules\\vue-loader\\lib\\index.js??vue-loader-options!D:\\源码\\vue-element-admin-master\\src\\views\\permission\\role.vue?vue&type=script&lang=js&","dependencies":[{"path":"D:\\源码\\vue-element-admin-master\\src\\views\\permission\\role.vue","mtime":1649647926000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\cache-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\babel-loader\\lib\\index.js","mtime":315532800000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\cache-loader\\dist\\cjs.js","mtime":499162500000},{"path":"D:\\源码\\vue-element-admin-master\\node_modules\\vue-loader\\lib\\index.js","mtime":499162500000}],"contextDependencies":[],"result":[{"type":"Buffer","data":"base64:Ly8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KLy8KCmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnCmltcG9ydCB7IGRlZXBDbG9uZSB9IGZyb20gJ0AvdXRpbHMnCmltcG9ydCB7IGdldFJvdXRlcywgZ2V0Um9sZXMsIGFkZFJvbGUsIGRlbGV0ZVJvbGUsIHVwZGF0ZVJvbGUgfSBmcm9tICdAL2FwaS9yb2xlJwoKY29uc3QgZGVmYXVsdFJvbGUgPSB7CiAga2V5OiAnJywKICBuYW1lOiAnJywKICBkZXNjcmlwdGlvbjogJycsCiAgcm91dGVzOiBbXQp9CgpleHBvcnQgZGVmYXVsdCB7CiAgZGF0YSgpIHsKICAgIHJldHVybiB7CiAgICAgIHJvbGU6IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRSb2xlKSwKICAgICAgcm91dGVzOiBbXSwKICAgICAgcm9sZXNMaXN0OiBbXSwKICAgICAgZGlhbG9nVmlzaWJsZTogZmFsc2UsCiAgICAgIGRpYWxvZ1R5cGU6ICduZXcnLAogICAgICBjaGVja1N0cmljdGx5OiBmYWxzZSwKICAgICAgZGVmYXVsdFByb3BzOiB7CiAgICAgICAgY2hpbGRyZW46ICdjaGlsZHJlbicsCiAgICAgICAgbGFiZWw6ICd0aXRsZScKICAgICAgfQogICAgfQogIH0sCiAgY29tcHV0ZWQ6IHsKICAgIHJvdXRlc0RhdGEoKSB7CiAgICAgIHJldHVybiB0aGlzLnJvdXRlcwogICAgfQogIH0sCiAgY3JlYXRlZCgpIHsKICAgIC8vIE1vY2s6IGdldCBhbGwgcm91dGVzIGFuZCByb2xlcyBsaXN0IGZyb20gc2VydmVyCiAgICB0aGlzLmdldFJvdXRlcygpCiAgICB0aGlzLmdldFJvbGVzKCkKICB9LAogIG1ldGhvZHM6IHsKICAgIGFzeW5jIGdldFJvdXRlcygpIHsKICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ2V0Um91dGVzKCkKICAgICAgdGhpcy5zZXJ2aWNlUm91dGVzID0gcmVzLmRhdGEKICAgICAgdGhpcy5yb3V0ZXMgPSB0aGlzLmdlbmVyYXRlUm91dGVzKHJlcy5kYXRhKQogICAgfSwKICAgIGFzeW5jIGdldFJvbGVzKCkgewogICAgICBjb25zdCByZXMgPSBhd2FpdCBnZXRSb2xlcygpCiAgICAgIHRoaXMucm9sZXNMaXN0ID0gcmVzLmRhdGEKICAgIH0sCgogICAgLy8gUmVzaGFwZSB0aGUgcm91dGVzIHN0cnVjdHVyZSBzbyB0aGF0IGl0IGxvb2tzIHRoZSBzYW1lIGFzIHRoZSBzaWRlYmFyCiAgICBnZW5lcmF0ZVJvdXRlcyhyb3V0ZXMsIGJhc2VQYXRoID0gJy8nKSB7CiAgICAgIGNvbnN0IHJlcyA9IFtdCgogICAgICBmb3IgKGxldCByb3V0ZSBvZiByb3V0ZXMpIHsKICAgICAgICAvLyBza2lwIHNvbWUgcm91dGUKICAgICAgICBpZiAocm91dGUuaGlkZGVuKSB7IGNvbnRpbnVlIH0KCiAgICAgICAgY29uc3Qgb25seU9uZVNob3dpbmdDaGlsZCA9IHRoaXMub25seU9uZVNob3dpbmdDaGlsZChyb3V0ZS5jaGlsZHJlbiwgcm91dGUpCgogICAgICAgIGlmIChyb3V0ZS5jaGlsZHJlbiAmJiBvbmx5T25lU2hvd2luZ0NoaWxkICYmICFyb3V0ZS5hbHdheXNTaG93KSB7CiAgICAgICAgICByb3V0ZSA9IG9ubHlPbmVTaG93aW5nQ2hpbGQKICAgICAgICB9CgogICAgICAgIGNvbnN0IGRhdGEgPSB7CiAgICAgICAgICBwYXRoOiBwYXRoLnJlc29sdmUoYmFzZVBhdGgsIHJvdXRlLnBhdGgpLAogICAgICAgICAgdGl0bGU6IHJvdXRlLm1ldGEgJiYgcm91dGUubWV0YS50aXRsZQoKICAgICAgICB9CgogICAgICAgIC8vIHJlY3Vyc2l2ZSBjaGlsZCByb3V0ZXMKICAgICAgICBpZiAocm91dGUuY2hpbGRyZW4pIHsKICAgICAgICAgIGRhdGEuY2hpbGRyZW4gPSB0aGlzLmdlbmVyYXRlUm91dGVzKHJvdXRlLmNoaWxkcmVuLCBkYXRhLnBhdGgpCiAgICAgICAgfQogICAgICAgIHJlcy5wdXNoKGRhdGEpCiAgICAgIH0KICAgICAgcmV0dXJuIHJlcwogICAgfSwKICAgIGdlbmVyYXRlQXJyKHJvdXRlcykgewogICAgICBsZXQgZGF0YSA9IFtdCiAgICAgIHJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IHsKICAgICAgICBkYXRhLnB1c2gocm91dGUpCiAgICAgICAgaWYgKHJvdXRlLmNoaWxkcmVuKSB7CiAgICAgICAgICBjb25zdCB0ZW1wID0gdGhpcy5nZW5lcmF0ZUFycihyb3V0ZS5jaGlsZHJlbikKICAgICAgICAgIGlmICh0ZW1wLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgZGF0YSA9IFsuLi5kYXRhLCAuLi50ZW1wXQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSkKICAgICAgcmV0dXJuIGRhdGEKICAgIH0sCiAgICBoYW5kbGVBZGRSb2xlKCkgewogICAgICB0aGlzLnJvbGUgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0Um9sZSkKICAgICAgaWYgKHRoaXMuJHJlZnMudHJlZSkgewogICAgICAgIHRoaXMuJHJlZnMudHJlZS5zZXRDaGVja2VkTm9kZXMoW10pCiAgICAgIH0KICAgICAgdGhpcy5kaWFsb2dUeXBlID0gJ25ldycKICAgICAgdGhpcy5kaWFsb2dWaXNpYmxlID0gdHJ1ZQogICAgfSwKICAgIGhhbmRsZUVkaXQoc2NvcGUpIHsKICAgICAgdGhpcy5kaWFsb2dUeXBlID0gJ2VkaXQnCiAgICAgIHRoaXMuZGlhbG9nVmlzaWJsZSA9IHRydWUKICAgICAgdGhpcy5jaGVja1N0cmljdGx5ID0gdHJ1ZQogICAgICB0aGlzLnJvbGUgPSBkZWVwQ2xvbmUoc2NvcGUucm93KQogICAgICB0aGlzLiRuZXh0VGljaygoKSA9PiB7CiAgICAgICAgY29uc3Qgcm91dGVzID0gdGhpcy5nZW5lcmF0ZVJvdXRlcyh0aGlzLnJvbGUucm91dGVzKQogICAgICAgIHRoaXMuJHJlZnMudHJlZS5zZXRDaGVja2VkTm9kZXModGhpcy5nZW5lcmF0ZUFycihyb3V0ZXMpKQogICAgICAgIC8vIHNldCBjaGVja2VkIHN0YXRlIG9mIGEgbm9kZSBub3QgYWZmZWN0cyBpdHMgZmF0aGVyIGFuZCBjaGlsZCBub2RlcwogICAgICAgIHRoaXMuY2hlY2tTdHJpY3RseSA9IGZhbHNlCiAgICAgIH0pCiAgICB9LAogICAgaGFuZGxlRGVsZXRlKHsgJGluZGV4LCByb3cgfSkgewogICAgICB0aGlzLiRjb25maXJtKCdDb25maXJtIHRvIHJlbW92ZSB0aGUgcm9sZT8nLCAnV2FybmluZycsIHsKICAgICAgICBjb25maXJtQnV0dG9uVGV4dDogJ0NvbmZpcm0nLAogICAgICAgIGNhbmNlbEJ1dHRvblRleHQ6ICdDYW5jZWwnLAogICAgICAgIHR5cGU6ICd3YXJuaW5nJwogICAgICB9KQogICAgICAgIC50aGVuKGFzeW5jKCkgPT4gewogICAgICAgICAgYXdhaXQgZGVsZXRlUm9sZShyb3cua2V5KQogICAgICAgICAgdGhpcy5yb2xlc0xpc3Quc3BsaWNlKCRpbmRleCwgMSkKICAgICAgICAgIHRoaXMuJG1lc3NhZ2UoewogICAgICAgICAgICB0eXBlOiAnc3VjY2VzcycsCiAgICAgICAgICAgIG1lc3NhZ2U6ICdEZWxldGUgc3VjY2VkIScKICAgICAgICAgIH0pCiAgICAgICAgfSkKICAgICAgICAuY2F0Y2goZXJyID0+IHsgY29uc29sZS5lcnJvcihlcnIpIH0pCiAgICB9LAogICAgZ2VuZXJhdGVUcmVlKHJvdXRlcywgYmFzZVBhdGggPSAnLycsIGNoZWNrZWRLZXlzKSB7CiAgICAgIGNvbnN0IHJlcyA9IFtdCgogICAgICBmb3IgKGNvbnN0IHJvdXRlIG9mIHJvdXRlcykgewogICAgICAgIGNvbnN0IHJvdXRlUGF0aCA9IHBhdGgucmVzb2x2ZShiYXNlUGF0aCwgcm91dGUucGF0aCkKCiAgICAgICAgLy8gcmVjdXJzaXZlIGNoaWxkIHJvdXRlcwogICAgICAgIGlmIChyb3V0ZS5jaGlsZHJlbikgewogICAgICAgICAgcm91dGUuY2hpbGRyZW4gPSB0aGlzLmdlbmVyYXRlVHJlZShyb3V0ZS5jaGlsZHJlbiwgcm91dGVQYXRoLCBjaGVja2VkS2V5cykKICAgICAgICB9CgogICAgICAgIGlmIChjaGVja2VkS2V5cy5pbmNsdWRlcyhyb3V0ZVBhdGgpIHx8IChyb3V0ZS5jaGlsZHJlbiAmJiByb3V0ZS5jaGlsZHJlbi5sZW5ndGggPj0gMSkpIHsKICAgICAgICAgIHJlcy5wdXNoKHJvdXRlKQogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gcmVzCiAgICB9LAogICAgYXN5bmMgY29uZmlybVJvbGUoKSB7CiAgICAgIGNvbnN0IGlzRWRpdCA9IHRoaXMuZGlhbG9nVHlwZSA9PT0gJ2VkaXQnCgogICAgICBjb25zdCBjaGVja2VkS2V5cyA9IHRoaXMuJHJlZnMudHJlZS5nZXRDaGVja2VkS2V5cygpCiAgICAgIHRoaXMucm9sZS5yb3V0ZXMgPSB0aGlzLmdlbmVyYXRlVHJlZShkZWVwQ2xvbmUodGhpcy5zZXJ2aWNlUm91dGVzKSwgJy8nLCBjaGVja2VkS2V5cykKCiAgICAgIGlmIChpc0VkaXQpIHsKICAgICAgICBhd2FpdCB1cGRhdGVSb2xlKHRoaXMucm9sZS5rZXksIHRoaXMucm9sZSkKICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5yb2xlc0xpc3QubGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICBpZiAodGhpcy5yb2xlc0xpc3RbaW5kZXhdLmtleSA9PT0gdGhpcy5yb2xlLmtleSkgewogICAgICAgICAgICB0aGlzLnJvbGVzTGlzdC5zcGxpY2UoaW5kZXgsIDEsIE9iamVjdC5hc3NpZ24oe30sIHRoaXMucm9sZSkpCiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHsgZGF0YSB9ID0gYXdhaXQgYWRkUm9sZSh0aGlzLnJvbGUpCiAgICAgICAgdGhpcy5yb2xlLmtleSA9IGRhdGEua2V5CiAgICAgICAgdGhpcy5yb2xlc0xpc3QucHVzaCh0aGlzLnJvbGUpCiAgICAgIH0KCiAgICAgIGNvbnN0IHsgZGVzY3JpcHRpb24sIGtleSwgbmFtZSB9ID0gdGhpcy5yb2xlCiAgICAgIHRoaXMuZGlhbG9nVmlzaWJsZSA9IGZhbHNlCiAgICAgIHRoaXMuJG5vdGlmeSh7CiAgICAgICAgdGl0bGU6ICdTdWNjZXNzJywKICAgICAgICBkYW5nZXJvdXNseVVzZUhUTUxTdHJpbmc6IHRydWUsCiAgICAgICAgbWVzc2FnZTogYAogICAgICAgICAgICA8ZGl2PlJvbGUgS2V5OiAke2tleX08L2Rpdj4KICAgICAgICAgICAgPGRpdj5Sb2xlIE5hbWU6ICR7bmFtZX08L2Rpdj4KICAgICAgICAgICAgPGRpdj5EZXNjcmlwdGlvbjogJHtkZXNjcmlwdGlvbn08L2Rpdj4KICAgICAgICAgIGAsCiAgICAgICAgdHlwZTogJ3N1Y2Nlc3MnCiAgICAgIH0pCiAgICB9LAogICAgLy8gcmVmZXJlbmNlOiBzcmMvdmlldy9sYXlvdXQvY29tcG9uZW50cy9TaWRlYmFyL1NpZGViYXJJdGVtLnZ1ZQogICAgb25seU9uZVNob3dpbmdDaGlsZChjaGlsZHJlbiA9IFtdLCBwYXJlbnQpIHsKICAgICAgbGV0IG9ubHlPbmVDaGlsZCA9IG51bGwKICAgICAgY29uc3Qgc2hvd2luZ0NoaWxkcmVuID0gY2hpbGRyZW4uZmlsdGVyKGl0ZW0gPT4gIWl0ZW0uaGlkZGVuKQoKICAgICAgLy8gV2hlbiB0aGVyZSBpcyBvbmx5IG9uZSBjaGlsZCByb3V0ZSwgdGhlIGNoaWxkIHJvdXRlIGlzIGRpc3BsYXllZCBieSBkZWZhdWx0CiAgICAgIGlmIChzaG93aW5nQ2hpbGRyZW4ubGVuZ3RoID09PSAxKSB7CiAgICAgICAgb25seU9uZUNoaWxkID0gc2hvd2luZ0NoaWxkcmVuWzBdCiAgICAgICAgb25seU9uZUNoaWxkLnBhdGggPSBwYXRoLnJlc29sdmUocGFyZW50LnBhdGgsIG9ubHlPbmVDaGlsZC5wYXRoKQogICAgICAgIHJldHVybiBvbmx5T25lQ2hpbGQKICAgICAgfQoKICAgICAgLy8gU2hvdyBwYXJlbnQgaWYgdGhlcmUgYXJlIG5vIGNoaWxkIHJvdXRlIHRvIGRpc3BsYXkKICAgICAgaWYgKHNob3dpbmdDaGlsZHJlbi5sZW5ndGggPT09IDApIHsKICAgICAgICBvbmx5T25lQ2hpbGQgPSB7IC4uLiBwYXJlbnQsIHBhdGg6ICcnLCBub1Nob3dpbmdDaGlsZHJlbjogdHJ1ZSB9CiAgICAgICAgcmV0dXJuIG9ubHlPbmVDaGlsZAogICAgICB9CgogICAgICByZXR1cm4gZmFsc2UKICAgIH0KICB9Cn0K"},{"version":3,"sources":["role.vue"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA","file":"role.vue","sourceRoot":"src/views/permission","sourcesContent":["<template>\n  <div class=\"app-container\">\n    <el-button type=\"primary\" @click=\"handleAddRole\">New Role</el-button>\n\n    <el-table :data=\"rolesList\" style=\"width: 100%;margin-top:30px;\" border>\n      <el-table-column align=\"center\" label=\"Role Key\" width=\"220\">\n        <template slot-scope=\"scope\">\n          {{ scope.row.key }}\n        </template>\n      </el-table-column>\n      <el-table-column align=\"center\" label=\"Role Name\" width=\"220\">\n        <template slot-scope=\"scope\">\n          {{ scope.row.name }}\n        </template>\n      </el-table-column>\n      <el-table-column align=\"header-center\" label=\"Description\">\n        <template slot-scope=\"scope\">\n          {{ scope.row.description }}\n        </template>\n      </el-table-column>\n      <el-table-column align=\"center\" label=\"Operations\">\n        <template slot-scope=\"scope\">\n          <el-button type=\"primary\" size=\"small\" @click=\"handleEdit(scope)\">Edit</el-button>\n          <el-button type=\"danger\" size=\"small\" @click=\"handleDelete(scope)\">Delete</el-button>\n        </template>\n      </el-table-column>\n    </el-table>\n\n    <el-dialog :visible.sync=\"dialogVisible\" :title=\"dialogType==='edit'?'Edit Role':'New Role'\">\n      <el-form :model=\"role\" label-width=\"80px\" label-position=\"left\">\n        <el-form-item label=\"Name\">\n          <el-input v-model=\"role.name\" placeholder=\"Role Name\" />\n        </el-form-item>\n        <el-form-item label=\"Desc\">\n          <el-input\n            v-model=\"role.description\"\n            :autosize=\"{ minRows: 2, maxRows: 4}\"\n            type=\"textarea\"\n            placeholder=\"Role Description\"\n          />\n        </el-form-item>\n        <el-form-item label=\"Menus\">\n          <el-tree\n            ref=\"tree\"\n            :check-strictly=\"checkStrictly\"\n            :data=\"routesData\"\n            :props=\"defaultProps\"\n            show-checkbox\n            node-key=\"path\"\n            class=\"permission-tree\"\n          />\n        </el-form-item>\n      </el-form>\n      <div style=\"text-align:right;\">\n        <el-button type=\"danger\" @click=\"dialogVisible=false\">Cancel</el-button>\n        <el-button type=\"primary\" @click=\"confirmRole\">Confirm</el-button>\n      </div>\n    </el-dialog>\n  </div>\n</template>\n\n<script>\nimport path from 'path'\nimport { deepClone } from '@/utils'\nimport { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role'\n\nconst defaultRole = {\n  key: '',\n  name: '',\n  description: '',\n  routes: []\n}\n\nexport default {\n  data() {\n    return {\n      role: Object.assign({}, defaultRole),\n      routes: [],\n      rolesList: [],\n      dialogVisible: false,\n      dialogType: 'new',\n      checkStrictly: false,\n      defaultProps: {\n        children: 'children',\n        label: 'title'\n      }\n    }\n  },\n  computed: {\n    routesData() {\n      return this.routes\n    }\n  },\n  created() {\n    // Mock: get all routes and roles list from server\n    this.getRoutes()\n    this.getRoles()\n  },\n  methods: {\n    async getRoutes() {\n      const res = await getRoutes()\n      this.serviceRoutes = res.data\n      this.routes = this.generateRoutes(res.data)\n    },\n    async getRoles() {\n      const res = await getRoles()\n      this.rolesList = res.data\n    },\n\n    // Reshape the routes structure so that it looks the same as the sidebar\n    generateRoutes(routes, basePath = '/') {\n      const res = []\n\n      for (let route of routes) {\n        // skip some route\n        if (route.hidden) { continue }\n\n        const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route)\n\n        if (route.children && onlyOneShowingChild && !route.alwaysShow) {\n          route = onlyOneShowingChild\n        }\n\n        const data = {\n          path: path.resolve(basePath, route.path),\n          title: route.meta && route.meta.title\n\n        }\n\n        // recursive child routes\n        if (route.children) {\n          data.children = this.generateRoutes(route.children, data.path)\n        }\n        res.push(data)\n      }\n      return res\n    },\n    generateArr(routes) {\n      let data = []\n      routes.forEach(route => {\n        data.push(route)\n        if (route.children) {\n          const temp = this.generateArr(route.children)\n          if (temp.length > 0) {\n            data = [...data, ...temp]\n          }\n        }\n      })\n      return data\n    },\n    handleAddRole() {\n      this.role = Object.assign({}, defaultRole)\n      if (this.$refs.tree) {\n        this.$refs.tree.setCheckedNodes([])\n      }\n      this.dialogType = 'new'\n      this.dialogVisible = true\n    },\n    handleEdit(scope) {\n      this.dialogType = 'edit'\n      this.dialogVisible = true\n      this.checkStrictly = true\n      this.role = deepClone(scope.row)\n      this.$nextTick(() => {\n        const routes = this.generateRoutes(this.role.routes)\n        this.$refs.tree.setCheckedNodes(this.generateArr(routes))\n        // set checked state of a node not affects its father and child nodes\n        this.checkStrictly = false\n      })\n    },\n    handleDelete({ $index, row }) {\n      this.$confirm('Confirm to remove the role?', 'Warning', {\n        confirmButtonText: 'Confirm',\n        cancelButtonText: 'Cancel',\n        type: 'warning'\n      })\n        .then(async() => {\n          await deleteRole(row.key)\n          this.rolesList.splice($index, 1)\n          this.$message({\n            type: 'success',\n            message: 'Delete succed!'\n          })\n        })\n        .catch(err => { console.error(err) })\n    },\n    generateTree(routes, basePath = '/', checkedKeys) {\n      const res = []\n\n      for (const route of routes) {\n        const routePath = path.resolve(basePath, route.path)\n\n        // recursive child routes\n        if (route.children) {\n          route.children = this.generateTree(route.children, routePath, checkedKeys)\n        }\n\n        if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) {\n          res.push(route)\n        }\n      }\n      return res\n    },\n    async confirmRole() {\n      const isEdit = this.dialogType === 'edit'\n\n      const checkedKeys = this.$refs.tree.getCheckedKeys()\n      this.role.routes = this.generateTree(deepClone(this.serviceRoutes), '/', checkedKeys)\n\n      if (isEdit) {\n        await updateRole(this.role.key, this.role)\n        for (let index = 0; index < this.rolesList.length; index++) {\n          if (this.rolesList[index].key === this.role.key) {\n            this.rolesList.splice(index, 1, Object.assign({}, this.role))\n            break\n          }\n        }\n      } else {\n        const { data } = await addRole(this.role)\n        this.role.key = data.key\n        this.rolesList.push(this.role)\n      }\n\n      const { description, key, name } = this.role\n      this.dialogVisible = false\n      this.$notify({\n        title: 'Success',\n        dangerouslyUseHTMLString: true,\n        message: `\n            <div>Role Key: ${key}</div>\n            <div>Role Name: ${name}</div>\n            <div>Description: ${description}</div>\n          `,\n        type: 'success'\n      })\n    },\n    // reference: src/view/layout/components/Sidebar/SidebarItem.vue\n    onlyOneShowingChild(children = [], parent) {\n      let onlyOneChild = null\n      const showingChildren = children.filter(item => !item.hidden)\n\n      // When there is only one child route, the child route is displayed by default\n      if (showingChildren.length === 1) {\n        onlyOneChild = showingChildren[0]\n        onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path)\n        return onlyOneChild\n      }\n\n      // Show parent if there are no child route to display\n      if (showingChildren.length === 0) {\n        onlyOneChild = { ... parent, path: '', noShowingChildren: true }\n        return onlyOneChild\n      }\n\n      return false\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.app-container {\n  .roles-table {\n    margin-top: 30px;\n  }\n  .permission-tree {\n    margin-bottom: 30px;\n  }\n}\n</style>\n"]}]}