\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n\r\n\r\n\r\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./index.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--12-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./index.vue?vue&type=script&lang=js&\"","import { render, staticRenderFns } from \"./index.vue?vue&type=template&id=31cdb644&\"\nimport script from \"./index.vue?vue&type=script&lang=js&\"\nexport * from \"./index.vue?vue&type=script&lang=js&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import Vue from 'vue'\r\n\r\nimport d2Container from './d2-container'\r\n\r\n// 注意 有些组件使用异步加载会有影响\r\nVue.component('d2-container', d2Container)\r\nVue.component('d2-page-cover', () => import('./d2-page-cover'))\r\nVue.component('d2-icon', () => import('./d2-icon'))\r\nVue.component('d2-icon-svg', () => import('./d2-icon-svg/index.vue'))\r\nVue.component('d2-icon-select', () => import('./d2-icon-select/index.vue'))\r\n","import Vue from 'vue'\r\n\r\nconst requireAll = requireContext => requireContext.keys().map(requireContext)\r\nconst req = require.context('./icons', false, /\\.svg$/)\r\nconst iconMap = requireAll(req)\r\n\r\nVue.prototype.$IconSvg = iconMap.map(e => e.default.id.slice(3))\r\n","import store from '@/store'\r\nimport util from '@/libs/util'\r\n\r\nexport default {\r\n install (Vue, options) {\r\n Vue.config.errorHandler = function (err, vm, info) {\r\n Vue.nextTick(() => {\r\n // 添加 log\r\n store.dispatch('d2admin/log/add', {\r\n type: 'error',\r\n err,\r\n vm,\r\n info\r\n })\r\n // 只在开发模式下打印 log\r\n if (process.env.NODE_ENV === 'development') {\r\n util.log.capsule('D2Admin', 'ErrorHandler', 'danger')\r\n util.log.danger('>>>>>> 错误信息 >>>>>>')\r\n console.log(info)\r\n util.log.danger('>>>>>> Vue 实例 >>>>>>')\r\n console.log(vm)\r\n util.log.danger('>>>>>> Error >>>>>>')\r\n console.log(err)\r\n }\r\n })\r\n }\r\n }\r\n}\r\n","import store from '@/store'\r\nimport util from '@/libs/util'\r\n\r\nexport default {\r\n install (Vue, options) {\r\n // 快速打印 log\r\n Vue.prototype.$log = util.log\r\n // 快速记录日志\r\n Vue.prototype.$logAdd = function (info, show = true) {\r\n // store 赋值\r\n store.dispatch('d2admin/log/add', {\r\n type: 'log',\r\n info\r\n })\r\n // 显示在控制台\r\n if (show && process.env.NODE_ENV === 'development') {\r\n util.log.default(info)\r\n }\r\n }\r\n }\r\n}\r\n","import util from '@/libs/util'\r\n\r\nexport default {\r\n install (Vue, options) {\r\n Vue.prototype.$open = util.open\r\n }\r\n}\r\n","export default {\r\n install(Vue, options) {\r\n let store = options.store\r\n Vue.directive('permission', {\r\n inserted: function (el, binding, vnode) {\r\n let isAdmin = store.state.d2admin.permission.isAdmin;\r\n if (isAdmin) {\r\n return\r\n }\r\n let checkCodes = [];\r\n if (binding.arg === \"function\") {\r\n checkCodes = store.state.d2admin.permission.functions;\r\n } else if (binding.arg === \"role\") {\r\n checkCodes = store.state.d2admin.permission.roles;\r\n } else {\r\n checkCodes = store.state.d2admin.permission.functions.concat(store.state.d2admin.permission.roles);\r\n }\r\n let access = true;\r\n if (binding.modifiers.all) {\r\n for (let need of binding.value) {\r\n if (checkCodes.some(s => s !== need)) {\r\n access = false;\r\n break;\r\n }\r\n }\r\n } else {\r\n access = false;\r\n for (let need of binding.value) {\r\n if (checkCodes.some(s => s === need)) {\r\n access = true;\r\n break;\r\n }\r\n }\r\n }\r\n if (!access) {\r\n el.parentNode.removeChild(el);\r\n }\r\n }\r\n })\r\n Vue.prototype.hasPermissions = (permissions) => {\r\n let isAdmin = store.state.d2admin.permission.isAdmin;\r\n if (isAdmin) {\r\n return true\r\n }\r\n let has = false;\r\n let checkCodes = store.state.d2admin.permission.functions.concat(store.state.d2admin.permission.roles);\r\n for (let need of permissions) {\r\n if (checkCodes.some(s => s === need)) {\r\n has = true;\r\n break;\r\n }\r\n }\r\n return has\r\n }\r\n Vue.prototype.hasFunctions = (functions) => {\r\n let isAdmin = store.state.d2admin.permission.isAdmin;\r\n if (isAdmin) {\r\n return true\r\n }\r\n let has = false;\r\n let checkCodes = store.state.d2admin.permission.functions\r\n for (let need of functions) {\r\n if (checkCodes.some(s => s === need)) {\r\n has = true;\r\n break;\r\n }\r\n }\r\n return has;\r\n }\r\n Vue.prototype.hasRoles = (roles) => {\r\n let isAdmin = store.state.d2admin.permission.isAdmin;\r\n if (isAdmin) {\r\n return true\r\n }\r\n let has = false;\r\n let checkCodes = store.state.d2admin.permission.roles\r\n for (let need of roles) {\r\n if (checkCodes.some(s => s === need)) {\r\n has = true;\r\n break;\r\n }\r\n }\r\n return has;\r\n }\r\n }\r\n}\r\n","// Element\r\nimport ElementUI from 'element-ui'\r\nimport 'element-ui/lib/theme-chalk/index.css'\r\n// flex 布局库\r\nimport 'flex.css'\r\n// 组件\r\nimport '@/components'\r\n// svg 图标\r\nimport '@/assets/svg-icons'\r\n// 功能插件\r\nimport pluginError from '@/plugin/error'\r\nimport pluginLog from '@/plugin/log'\r\nimport pluginOpen from '@/plugin/open'\r\nimport pluginPermission from '@/plugin/permission'\r\n\r\nexport default {\r\n async install(Vue, options) {\r\n // 设置为 false 以阻止 vue 在启动时生成生产提示。https://cn.vuejs.org/v2/api/#productionTip\r\n Vue.config.productionTip = false\r\n // 当前环境\r\n Vue.prototype.$env = process.env.NODE_ENV\r\n // 当前的 baseUrl\r\n Vue.prototype.$baseUrl = process.env.BASE_URL\r\n // Element\r\n Vue.use(ElementUI)\r\n // 插件\r\n Vue.use(pluginError)\r\n Vue.use(pluginLog)\r\n Vue.use(pluginOpen)\r\n Vue.use(pluginPermission, options)\r\n }\r\n}\r\n","// polyfill\r\nimport 'babel-polyfill'\r\n// Vue\r\nimport Vue from 'vue'\r\nimport App from './App'\r\n// store\r\nimport store from '@/store/index'\r\n// 模拟数据\r\nimport '@/mock'\r\n// 多国语\r\nimport i18n from './i18n'\r\n// 核心插件\r\nimport d2Admin from '@/plugin/d2admin'\r\n// 路由\r\nimport router from './router'\r\n// 核心插件\r\nVue.use(d2Admin, { store })\r\n\r\nnew Vue({\r\n router,\r\n store,\r\n i18n,\r\n render: h => h(App),\r\n created () {\r\n\r\n },\r\n mounted () {\r\n // 展示系统信息\r\n this.$store.commit('d2admin/releases/versionShow')\r\n // 用户登录后从数据库加载一系列的设置\r\n this.$store.dispatch('d2admin/account/load')\r\n // 获取并记录用户 UA\r\n this.$store.commit('d2admin/ua/get')\r\n // 初始化全屏监听\r\n this.$store.dispatch('d2admin/fullscreen/listen')\r\n },\r\n watch: {\r\n '$route.matched' (val) {\r\n let fullAside = this.$store.state.d2admin.menu.fullAside\r\n const _side = fullAside.filter(menu => menu.path === val[0].path)\r\n this.$store.commit('d2admin/menu/asideSet', _side.length > 0 ? _side[0].children : [])\r\n }\r\n }\r\n}).$mount('#app')\r\n","const files = require.context('./', true, /\\.js$/);\r\n\r\nlet autoGenerateMenus = []\r\nlet autoGenerateRouters = []\r\nconsole.log(files)\r\nfiles.keys().forEach((key) => {\r\n console.log(key)\r\n if (key === './index.js') return\r\n if (key.indexOf('menu') > -1) {\r\n autoGenerateMenus.push(files(key).default)\r\n } else if (key.indexOf('router') > -1) {\r\n autoGenerateRouters.push(files(key).default)\r\n }\r\n})\r\nexport default {\r\n menus: autoGenerateMenus,\r\n routers: autoGenerateRouters\r\n}\r\n","import { remove, get } from 'lodash'\r\n\r\n// 设置文件\r\nimport setting from '@/setting.js'\r\n\r\n// 判定是否需要缓存\r\nconst isKeepAlive = data => get(data, 'meta.cache', false)\r\n\r\nexport default {\r\n namespaced: true,\r\n state: {\r\n // 可以在多页 tab 模式下显示的页面\r\n pool: [],\r\n // 当前显示的多页面列表\r\n opened: setting.page.opened,\r\n // 当前页面\r\n current: '',\r\n // 需要缓存的页面 name\r\n keepAlive: []\r\n },\r\n actions: {\r\n /**\r\n * @class opened\r\n * @description 从持久化数据载入分页列表\r\n * @param {Object} state vuex state\r\n */\r\n openedLoad ({ state, commit, dispatch }) {\r\n return new Promise(async resolve => {\r\n // store 赋值\r\n const value = await dispatch('d2admin/db/get', {\r\n dbName: 'sys',\r\n path: 'page.opened',\r\n defaultValue: setting.page.opened,\r\n user: true\r\n }, { root: true })\r\n // 在处理函数中进行数据优化 过滤掉现在已经失效的页签或者已经改变了信息的页签\r\n // 以 name 字段为准\r\n // 如果页面过多的话可能需要优化算法\r\n // valid 有效列表 1, 1, 0, 1 => 有效, 有效, 失效, 有效\r\n const valid = []\r\n // 处理数据\r\n state.opened = value.map(opened => {\r\n // 忽略首页\r\n if (opened.name === 'index') {\r\n valid.push(1)\r\n return opened\r\n }\r\n // 尝试在所有的支持多标签页的页面里找到 name 匹配的页面\r\n const find = state.pool.find(item => item.name === opened.name)\r\n // 记录有效或无效信息\r\n valid.push(find ? 1 : 0)\r\n // 返回合并后的数据 新的覆盖旧的\r\n // 新的数据中一般不会携带 params 和 query, 所以旧的参数会留存\r\n return Object.assign({}, opened, find)\r\n }).filter((opened, index) => valid[index] === 1)\r\n // 根据 opened 数据生成缓存设置\r\n commit('keepAliveRefresh')\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * 将 opened 属性赋值并持久化 在这之前请先确保已经更新了 state.opened\r\n * @param {Object} state vuex state\r\n */\r\n opend2db ({ state, dispatch }) {\r\n return new Promise(async resolve => {\r\n // 设置数据\r\n dispatch('d2admin/db/set', {\r\n dbName: 'sys',\r\n path: 'page.opened',\r\n value: state.opened,\r\n user: true\r\n }, { root: true })\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 更新页面列表上的某一项\r\n * @param {Object} state vuex state\r\n * @param {Object} param { index, params, query } 路由信息\r\n */\r\n openedUpdate ({ state, commit, dispatch }, { index, params, query }) {\r\n return new Promise(async resolve => {\r\n // 更新页面列表某一项\r\n let page = state.opened[index]\r\n page.params = params || page.params\r\n page.query = query || page.query\r\n state.opened.splice(index, 1, page)\r\n // 增加缓存设置\r\n if (isKeepAlive(page)) {\r\n commit('keepAlivePush', page.name)\r\n }\r\n // 持久化\r\n await dispatch('opend2db')\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 新增一个 tag (打开一个页面)\r\n * @param {Object} state vuex state\r\n * @param {Object} param new tag info\r\n */\r\n add ({ state, commit, dispatch }, { tag, params, query }) {\r\n return new Promise(async resolve => {\r\n // 设置新的 tag 在新打开一个以前没打开过的页面时使用\r\n let newTag = tag\r\n newTag.params = params || newTag.params\r\n newTag.query = query || newTag.query\r\n // 添加进当前显示的页面数组\r\n state.opened.push(newTag)\r\n // 如果这个页面需要缓存 将其添加到缓存设置\r\n if (isKeepAlive(newTag)) {\r\n commit('keepAlivePush', tag.name)\r\n }\r\n // 持久化\r\n await dispatch('opend2db')\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class current\r\n * @description 打开一个新的页面\r\n * @param {Object} state vuex state\r\n * @param {Object} param { name, params, query } 路由信息\r\n */\r\n open ({ state, commit, dispatch }, { name, params, query }) {\r\n return new Promise(async resolve => {\r\n // 已经打开的页面\r\n let opened = state.opened\r\n // 判断此页面是否已经打开 并且记录位置\r\n let pageOpendIndex = 0\r\n const pageOpend = opened.find((page, index) => {\r\n const same = page.name === name\r\n pageOpendIndex = same ? index : pageOpendIndex\r\n return same\r\n })\r\n if (pageOpend) {\r\n // 页面以前打开过 但是新的页面可能 name 一样,参数不一样\r\n await dispatch('openedUpdate', {\r\n index: pageOpendIndex,\r\n params,\r\n query\r\n })\r\n } else {\r\n // 页面以前没有打开过\r\n let page = state.pool.find(t => t.name === name)\r\n // 如果这里没有找到 page 代表这个路由虽然在框架内 但是不参与标签页显示\r\n if (page) {\r\n await dispatch('add', {\r\n tag: page,\r\n params,\r\n query\r\n })\r\n }\r\n }\r\n commit('currentSet', name)\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 关闭一个 tag (关闭一个页面)\r\n * @param {Object} state vuex state\r\n * @param {Object} param { tagName: 要关闭的标签名字, vm: vue }\r\n */\r\n close ({ state, commit, dispatch }, { tagName, vm }) {\r\n return new Promise(async resolve => {\r\n // 下个新的页面\r\n let newPage = state.opened[0]\r\n const isCurrent = state.current === tagName\r\n // 如果关闭的页面就是当前显示的页面\r\n if (isCurrent) {\r\n // 去找一个新的页面\r\n let len = state.opened.length\r\n for (let i = 1; i < len; i++) {\r\n if (state.opened[i].name === tagName) {\r\n if (i < len - 1) {\r\n newPage = state.opened[i + 1]\r\n } else {\r\n newPage = state.opened[i - 1]\r\n }\r\n break\r\n }\r\n }\r\n }\r\n // 找到这个页面在已经打开的数据里是第几个\r\n const index = state.opened.findIndex(page => page.name === tagName)\r\n if (index >= 0) {\r\n // 更新数据 删除关闭的页面\r\n state.opened.splice(index, 1)\r\n // 如果这个页面是缓存的页面 将其在缓存设置中删除\r\n commit('keepAliveRemove', tagName)\r\n }\r\n // 持久化\r\n await dispatch('opend2db')\r\n // 最后需要判断是否需要跳到首页\r\n if (isCurrent) {\r\n const { name = '', params = {}, query = {} } = newPage\r\n let routerObj = {\r\n name,\r\n params,\r\n query\r\n }\r\n vm.$router.push(routerObj)\r\n }\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 关闭当前标签左边的标签\r\n * @param {Object} state vuex state\r\n * @param {Object} param { pageSelect: 当前选中的tagName, vm: vue }\r\n */\r\n closeLeft ({ state, commit, dispatch }, { pageSelect, vm } = {}) {\r\n return new Promise(async resolve => {\r\n const pageAim = pageSelect || state.current\r\n let currentIndex = 0\r\n state.opened.forEach((page, index) => {\r\n if (page.name === pageAim) {\r\n currentIndex = index\r\n }\r\n })\r\n if (currentIndex > 0) {\r\n // 删除打开的页面 并在缓存设置中删除\r\n state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name))\r\n }\r\n state.current = pageAim\r\n if (vm && vm.$route.name !== pageAim) {\r\n vm.$router.push({\r\n name: pageAim\r\n })\r\n }\r\n // 持久化\r\n await dispatch('opend2db')\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 关闭当前标签右边的标签\r\n * @param {Object} state vuex state\r\n * @param {Object} param { pageSelect: 当前选中的tagName, vm: vue }\r\n */\r\n closeRight ({ state, commit, dispatch }, { pageSelect, vm } = {}) {\r\n return new Promise(async resolve => {\r\n const pageAim = pageSelect || state.current\r\n let currentIndex = 0\r\n state.opened.forEach((page, index) => {\r\n if (page.name === pageAim) {\r\n currentIndex = index\r\n }\r\n })\r\n // 删除打开的页面 并在缓存设置中删除\r\n state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name))\r\n // 设置当前的页面\r\n state.current = pageAim\r\n if (vm && vm.$route.name !== pageAim) {\r\n vm.$router.push({\r\n name: pageAim\r\n })\r\n }\r\n // 持久化\r\n await dispatch('opend2db')\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 关闭当前激活之外的 tag\r\n * @param {Object} state vuex state\r\n * @param {Object} param { pageSelect: 当前选中的tagName, vm: vue }\r\n */\r\n closeOther ({ state, commit, dispatch }, { pageSelect, vm } = {}) {\r\n return new Promise(async resolve => {\r\n const pageAim = pageSelect || state.current\r\n let currentIndex = 0\r\n state.opened.forEach((page, index) => {\r\n if (page.name === pageAim) {\r\n currentIndex = index\r\n }\r\n })\r\n // 删除打开的页面数据 并更新缓存设置\r\n if (currentIndex === 0) {\r\n state.opened.splice(1).forEach(({ name }) => commit('keepAliveRemove', name))\r\n } else {\r\n state.opened.splice(currentIndex + 1).forEach(({ name }) => commit('keepAliveRemove', name))\r\n state.opened.splice(1, currentIndex - 1).forEach(({ name }) => commit('keepAliveRemove', name))\r\n }\r\n // 设置新的页面\r\n state.current = pageAim\r\n if (vm && vm.$route.name !== pageAim) {\r\n vm.$router.push({\r\n name: pageAim\r\n })\r\n }\r\n // 持久化\r\n await dispatch('opend2db')\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @class opened\r\n * @description 关闭所有 tag\r\n * @param {Object} state vuex state\r\n * @param {Object} vm vue\r\n */\r\n closeAll ({ state, commit, dispatch }, vm) {\r\n return new Promise(async resolve => {\r\n // 删除打开的页面 并在缓存设置中删除\r\n state.opened.splice(1).forEach(({ name }) => commit('keepAliveRemove', name))\r\n // 持久化\r\n await dispatch('opend2db')\r\n // 关闭所有的标签页后需要判断一次现在是不是在首页\r\n if (vm.$route.name !== 'index') {\r\n vm.$router.push({\r\n name: 'index'\r\n })\r\n }\r\n // end\r\n resolve()\r\n })\r\n }\r\n },\r\n mutations: {\r\n /**\r\n * @class keepAlive\r\n * @description 从已经打开的页面记录中更新需要缓存的页面记录\r\n * @param {Object} state vuex state\r\n */\r\n keepAliveRefresh (state) {\r\n state.keepAlive = state.opened.filter(item => isKeepAlive(item)).map(e => e.name)\r\n },\r\n /**\r\n * @description 删除一个页面的缓存设置\r\n * @param {Object} state vuex state\r\n * @param {String} name name\r\n */\r\n keepAliveRemove (state, name) {\r\n const list = [ ...state.keepAlive ]\r\n remove(list, item => item === name)\r\n state.keepAlive = list\r\n },\r\n /**\r\n * @description 增加一个页面的缓存设置\r\n * @param {Object} state vuex state\r\n * @param {String} name name\r\n */\r\n keepAlivePush (state, name) {\r\n const keep = [ ...state.keepAlive ]\r\n keep.push(name)\r\n state.keepAlive = Array.from(new Set(keep))\r\n },\r\n /**\r\n * @description 清空页面缓存设置\r\n * @param {Object} state vuex state\r\n */\r\n keepAliveClean (state) {\r\n state.keepAlive = []\r\n },\r\n /**\r\n * @class current\r\n * @description 设置当前激活的页面 name\r\n * @param {Object} state vuex state\r\n * @param {String} name new name\r\n */\r\n currentSet (state, name) {\r\n state.current = name\r\n },\r\n /**\r\n * @class pool\r\n * @description 保存 pool (候选池)\r\n * @param {Object} state vuex state\r\n * @param {Array} routes routes\r\n */\r\n init (state, routes) {\r\n const pool = []\r\n const push = function (routes) {\r\n routes.forEach(route => {\r\n if (route.children) {\r\n push(route.children)\r\n } else {\r\n if (!route.hidden) {\r\n const { meta, name, path } = route\r\n pool.push({ meta, name, path })\r\n }\r\n }\r\n })\r\n }\r\n push(routes)\r\n state.pool = pool\r\n }\r\n }\r\n}\r\n","export default {\r\n namespaced: true,\r\n state: {\r\n // 尺寸\r\n value: '' // medium small mini\r\n },\r\n actions: {\r\n /**\r\n * @description 设置尺寸\r\n * @param {Object} state vuex state\r\n * @param {String} size 尺寸\r\n */\r\n set ({ state, dispatch }, size) {\r\n return new Promise(async resolve => {\r\n // store 赋值\r\n state.value = size\r\n // 持久化\r\n await dispatch('d2admin/db/set', {\r\n dbName: 'sys',\r\n path: 'size.value',\r\n value: state.value,\r\n user: true\r\n }, { root: true })\r\n // end\r\n resolve()\r\n })\r\n },\r\n /**\r\n * @description 从持久化数据读取尺寸设置\r\n * @param {Object} state vuex state\r\n */\r\n load ({ state, dispatch }) {\r\n return new Promise(async resolve => {\r\n // store 赋值\r\n state.value = await dispatch('d2admin/db/get', {\r\n dbName: 'sys',\r\n path: 'size.value',\r\n defaultValue: 'default',\r\n user: true\r\n }, { root: true })\r\n // end\r\n resolve()\r\n })\r\n }\r\n }\r\n}\r\n","export default {\r\n namespaced: true,\r\n state: {\r\n // 灰度\r\n active: false\r\n },\r\n mutations: {\r\n /**\r\n * @description 切换灰度状态\r\n * @param {Object} state vuex state\r\n */\r\n toggle (state) {\r\n state.active = !state.active\r\n },\r\n /**\r\n * @description 设置灰度模式\r\n * @param {Object} state vuex state\r\n * @param {Boolean} active active\r\n */\r\n set (state, active) {\r\n state.active = active\r\n }\r\n }\r\n}\r\n","import low from 'lowdb'\r\nimport LocalStorage from 'lowdb/adapters/LocalStorage'\r\nimport setting from '@/setting.js'\r\n\r\nconst adapter = new LocalStorage(`d2admin-${setting.releases.version}`)\r\nconst db = low(adapter)\r\n\r\ndb\r\n .defaults({\r\n sys: {},\r\n database: {}\r\n })\r\n .write()\r\n\r\nexport default db\r\n","import db from '@/libs/db.js'\r\nimport util from '@/libs/util.js'\r\n\r\n/**\r\n * @description 检查路径是否存在 不存在的话初始化\r\n * @param {Object} param dbName {String} 数据库名称\r\n * @param {Object} param path {String} 路径\r\n * @param {Object} param user {Boolean} 区分用户\r\n * @param {Object} param validator {Function} 数据校验钩子 返回 true 表示验证通过\r\n * @param {Object} param defaultValue {*} 初始化默认值\r\n * @returns {String} 可以直接使用的路径\r\n */\r\nfunction pathInit ({\r\n dbName = 'database',\r\n path = '',\r\n user = true,\r\n validator = () => true,\r\n defaultValue = ''\r\n}) {\r\n const uuid = util.cookies.get('uuid') || 'ghost-uuid'\r\n const currentPath = `${dbName}.${user ? `user.${uuid}` : 'public'}${path ? `.${path}` : ''}`\r\n const value = db.get(currentPath).value()\r\n if (!(value !== undefined && validator(value))) {\r\n db\r\n .set(currentPath, defaultValue)\r\n .write()\r\n }\r\n return currentPath\r\n}\r\n\r\nexport default {\r\n namespaced: true,\r\n actions: {\r\n /**\r\n * @description 将数据存储到指定位置 | 路径不存在会自动初始化\r\n * @description 效果类似于取值 dbName.path = value\r\n * @param {Object} param dbName {String} 数据库名称\r\n * @param {Object} param path {String} 存储路径\r\n * @param {Object} param value {*} 需要存储的值\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n set (context, {\r\n dbName = 'database',\r\n path = '',\r\n value = '',\r\n user = false\r\n }) {\r\n db.set(pathInit({\r\n dbName,\r\n path,\r\n user\r\n }), value).write()\r\n },\r\n /**\r\n * @description 获取数据\r\n * @description 效果类似于取值 dbName.path || defaultValue\r\n * @param {Object} param dbName {String} 数据库名称\r\n * @param {Object} param path {String} 存储路径\r\n * @param {Object} param defaultValue {*} 取值失败的默认值\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n get (context, {\r\n dbName = 'database',\r\n path = '',\r\n defaultValue = '',\r\n user = false\r\n }) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName,\r\n path,\r\n user,\r\n defaultValue\r\n })).value())\r\n })\r\n },\r\n /**\r\n * @description 获取存储数据库对象\r\n * @param {Object} context context\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n database (context, {\r\n user = false\r\n } = {}) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: '',\r\n user,\r\n defaultValue: {}\r\n })))\r\n })\r\n },\r\n /**\r\n * @description 清空存储数据库对象\r\n * @param {Object} context context\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n databaseClear (context, {\r\n user = false\r\n } = {}) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: '',\r\n user,\r\n validator: () => false,\r\n defaultValue: {}\r\n })))\r\n })\r\n },\r\n /**\r\n * @description 获取存储数据库对象 [ 区分页面 ]\r\n * @param {Object} context context\r\n * @param {Object} param vm {Object} vue\r\n * @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n databasePage (context, {\r\n vm,\r\n basis = 'name',\r\n user = false\r\n } = {}) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: `$page.${vm.$route[basis]}`,\r\n user,\r\n defaultValue: {}\r\n })))\r\n })\r\n },\r\n /**\r\n * @description 清空存储数据库对象 [ 区分页面 ]\r\n * @param {Object} context context\r\n * @param {Object} param vm {Object} vue\r\n * @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n databasePageClear (context, {\r\n vm,\r\n basis = 'name',\r\n user = false\r\n } = {}) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: `$page.${vm.$route[basis]}`,\r\n user,\r\n validator: () => false,\r\n defaultValue: {}\r\n })))\r\n })\r\n },\r\n /**\r\n * @description 快速将页面当前的数据 ( $data ) 持久化\r\n * @param {Object} context context\r\n * @param {Object} param vm {Object} vue\r\n * @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n pageSet (context, {\r\n vm,\r\n basis = 'name',\r\n user = false\r\n }) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: `$page.${vm.$route[basis]}.$data`,\r\n user,\r\n validator: () => false,\r\n defaultValue: vm.$data\r\n })))\r\n })\r\n },\r\n /**\r\n * @description 快速获取页面快速持久化的数据\r\n * @param {Object} context context\r\n * @param {Object} param vm {Object} vue\r\n * @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n pageGet (context, {\r\n vm,\r\n basis = 'name',\r\n user = false\r\n }) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: `$page.${vm.$route[basis]}.$data`,\r\n user,\r\n defaultValue: vm.$data\r\n })).value())\r\n })\r\n },\r\n /**\r\n * @description 清空页面快照\r\n * @param {Object} context context\r\n * @param {Object} param vm {Object} vue\r\n * @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]\r\n * @param {Object} param user {Boolean} 是否区分用户\r\n */\r\n pageClear (context, {\r\n vm,\r\n basis = 'name',\r\n user = false\r\n }) {\r\n return new Promise(resolve => {\r\n resolve(db.get(pathInit({\r\n dbName: 'database',\r\n path: `$page.${vm.$route[basis]}.$data`,\r\n user,\r\n validator: () => false,\r\n defaultValue: {}\r\n })))\r\n })\r\n }\r\n }\r\n}\r\n","var map = {\n\t\"./index.js\": \"bf9e\"\n};\n\n\nfunction webpackContext(req) {\n\tvar id = webpackContextResolve(req);\n\treturn __webpack_require__(id);\n}\nfunction webpackContextResolve(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\treturn map[req];\n}\nwebpackContext.keys = function webpackContextKeys() {\n\treturn Object.keys(map);\n};\nwebpackContext.resolve = webpackContextResolve;\nmodule.exports = webpackContext;\nwebpackContext.id = \"758e\";","export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--8-oneOf-1-0!../node_modules/css-loader/index.js??ref--8-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--8-oneOf-1-2!../node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=style&index=0&id=29a75034&prod&lang=scss&\"","import { Loading } from 'element-ui';\r\nimport NProgress from 'nprogress'\r\nimport 'nprogress/nprogress.css'\r\nlet loading = {\r\n}\r\nlet loadingInstance = null;\r\n\r\nlet lastRequest = new Date('2018');\r\n\r\nloading.show = function (config) {\r\n if (config && config.loading) {\r\n let now = new Date();\r\n let ms = now - lastRequest;\r\n lastRequest = now;\r\n if (ms > config.loading.interval || 2000) {//默认相隔超过两秒的请求才重新显示loading\r\n if (config.loading.type === \"loading\") {\r\n loadingInstance = Loading.service(config.loading.options)\r\n } else if (config.loading.type === \"nprogress\") {\r\n NProgress.start()\r\n }\r\n }\r\n }\r\n\r\n}\r\n\r\nloading.hide = function (config) {\r\n if (config && config.loading) {\r\n if (config.loading.type === \"loading\" && loadingInstance) {\r\n loadingInstance.close();\r\n loadingInstance = null;\r\n } else if (config.loading.type === \"nprogress\") {\r\n NProgress.done()\r\n }\r\n }\r\n}\r\n\r\nexport default loading;","import { Message, MessageBox, Notification } from 'element-ui';\r\nexport default function (config) {\r\n if (config && config.success) {\r\n if (config.success.type === 'message') {\r\n Message(config.success.options)\r\n } else if (config.success.type === 'messagebox') {\r\n MessageBox(config.success.options)\r\n } else if (config.success.type === 'notification') {\r\n Notification(config.success.options)\r\n }\r\n }\r\n}","import { match } from 'matchit'\r\nexport default {\r\n access: function (config, store) {\r\n let functionAccess = true\r\n let interfaceAccess = true\r\n let isAdmin = store.state.d2admin.permission.isAdmin\r\n if (config.permission && config.permission.length > 0) {\r\n let needPermissions = config.permission\r\n let permissions = store.state.d2admin.permission.functions.concat(store.state.d2admin.permission.roles)\r\n let hasPermission = permissions.some(s => {\r\n return needPermissions.indexOf(s) > -1\r\n })\r\n if (!hasPermission && !isAdmin) {\r\n functionAccess = false\r\n }\r\n }\r\n if (config.interfaceCheck) {\r\n let path = config.url.replace(config.baseURL, '')\r\n let method = config.method.toUpperCase()\r\n let interfaces = store.state.d2admin.permission.interfaces[method]\r\n let matched = match(path.split('?')[0], interfaces)\r\n if (matched.length == 0 && !isAdmin) {\r\n interfaceAccess = false\r\n }\r\n }\r\n return functionAccess && interfaceAccess\r\n }\r\n}\r\n","import store from '@/store'\r\nimport axios from 'axios'\r\nimport router from '@/router/index'\r\nimport { Message } from 'element-ui'\r\nimport util from '@/libs/util'\r\nimport loading from '@/libs/loading'\r\nimport message from '@/libs/message'\r\nimport permission from '@/libs/permission'\r\n\r\n// 记录和显示错误\r\nfunction errorLog (err) {\r\n // 添加到日志\r\n store.dispatch('d2admin/log/add', {\r\n type: 'error',\r\n err,\r\n info: '数据请求异常'\r\n })\r\n // 打印到控制台\r\n if (process.env.NODE_ENV === 'development') {\r\n util.log.danger('>>>>>> Error >>>>>>')\r\n console.log(err)\r\n }\r\n // 显示提示\r\n Message({\r\n message: err.message,\r\n type: 'error',\r\n duration: 5 * 1000\r\n })\r\n}\r\n\r\n// 创建一个 axios 实例\r\nconst service = axios.create({\r\n baseURL: process.env.VUE_APP_API,\r\n timeout: 20000 // 请求超时时间\r\n})\r\n\r\n// 请求拦截器\r\nservice.interceptors.request.use(\r\n config => {\r\n if (!permission.access(config, store)) {\r\n // eslint-disable-next-line no-throw-literal\r\n throw {\r\n type: '403',\r\n config: config\r\n }\r\n }\r\n loading.show(config)\r\n // 在请求发送之前做一些处理\r\n if (!(/^https:\\/\\/|http:\\/\\//.test(config.url))) {\r\n const token = util.cookies.get('token')\r\n if (token && token !== 'undefined') {\r\n // 让每个请求携带token-- ['Authorization']为自定义key 请根据实际情况自行修改\r\n config.headers['Authorization'] = 'Bearer ' + token\r\n }\r\n }\r\n return config\r\n },\r\n error => {\r\n // 发送失败\r\n console.log(error)\r\n Promise.reject(error)\r\n }\r\n)\r\n\r\n// 响应拦截器\r\nservice.interceptors.response.use(\r\n response => {\r\n loading.hide(response.config)\r\n const res = response.data\r\n if (res.statusCode !== 200) {\r\n Message({\r\n message: res.message,\r\n type: 'error',\r\n duration: 3 * 1000\r\n })\r\n return Promise.reject(res.message)\r\n } else {\r\n message(response.config)\r\n return res.data\r\n }\r\n },\r\n error => {\r\n console.log(error)\r\n loading.hide(error.config)\r\n if (error.response && error.response.status === 401) {\r\n util.cookies.remove()\r\n if (error.config.url.indexOf('logout') === -1) {\r\n Message({\r\n message: '登陆信息已过期,请重新登陆!',\r\n type: 'error',\r\n duration: 3 * 1000\r\n })\r\n }\r\n setTimeout(() => {\r\n // 删除cookie\r\n util.cookies.remove('token')\r\n util.cookies.remove('uuid')\r\n // 跳转路由\r\n router.push({\r\n name: 'login'\r\n })\r\n }, 1000)\r\n } else if (error.response && error.response.status === 500) {\r\n errorLog(new Error(`系统错误!: ${error.config.url}`))\r\n } else if (error.message && error.message.indexOf('timeout') > -1) {\r\n errorLog(new Error(`网络超时!: ${error.config.url}`))\r\n } else if (error.type === '403') {\r\n errorLog(new Error(`没有请求权限!: ${error.config.url}`))\r\n } else {\r\n errorLog(new Error(`网络错误!: ${error.config.url}`))\r\n }\r\n return Promise.reject(error)\r\n }\r\n)\r\n\r\nexport default service\r\n","import layoutHeaderAside from '@/layout/header-aside'\r\n\r\nconst meta = { requiresAuth: true }\r\n\r\nexport default {\r\n path: '/demo',\r\n name: 'demo',\r\n meta,\r\n redirect: { name: 'demo-page1' },\r\n component: layoutHeaderAside,\r\n children: (pre => [\r\n { path: 'page1', name: `${pre}page1`, component: () => import('@/pages/demo/page1'), meta: { meta, title: '页面 1' } },\r\n { path: 'page2', name: `${pre}page2`, component: () => import('@/pages/demo/page2'), meta: { meta, title: '页面 2' } },\r\n { path: 'page3', name: `${pre}page3`, component: () => import('@/pages/demo/page3'), meta: { meta, title: '页面 3' } },\r\n { path: 'page4', name: `${pre}page4`, component: () => import('@/pages/demo/page4'), meta: { meta, title: '页面 4' } }\r\n ])('demo-')\r\n}\r\n","import demo from './modules/demo'\r\n\r\nimport layoutHeaderAside from '@/layout/header-aside'\r\n\r\nconst meta = { requiresAuth: true }\r\n\r\n/**\r\n * 在主框架内显示\r\n */\r\nconst frameIn = [\r\n {\r\n path: '/',\r\n redirect: { name: 'index' },\r\n component: layoutHeaderAside,\r\n children: [\r\n // 首页 必须 name:index\r\n {\r\n path: 'index',\r\n name: 'index',\r\n meta,\r\n component: () => import('@/pages/index')\r\n },\r\n // 刷新页面 必须保留\r\n {\r\n path: 'refresh',\r\n name: 'refresh',\r\n hidden: true,\r\n component: {\r\n beforeRouteEnter (to, from, next) {\r\n next(vm => vm.$router.replace(from.fullPath))\r\n },\r\n render: h => h()\r\n }\r\n },\r\n // 页面重定向 必须保留\r\n {\r\n path: 'redirect/:route*',\r\n name: 'redirect',\r\n hidden: true,\r\n component: {\r\n beforeRouteEnter (to, from, next) {\r\n next(vm => vm.$router.replace(JSON.parse(from.params.route)))\r\n },\r\n render: h => h()\r\n }\r\n }\r\n ]\r\n },\r\n demo\r\n]\r\n\r\n/**\r\n * 在主框架之外显示\r\n */\r\nconst frameOut = [\r\n // 登录\r\n {\r\n path: '/login',\r\n name: 'login',\r\n component: () => import('@/pages/login')\r\n }\r\n]\r\n\r\n/**\r\n * 错误页面\r\n */\r\nconst errorPage = [\r\n // 404\r\n {\r\n path: '*',\r\n name: '404',\r\n component: () => import('@/pages/error-page-404')\r\n }\r\n]\r\n\r\n// 导出需要显示菜单的\r\nexport const frameInRoutes = frameIn\r\n\r\n// 重新组织后导出\r\nexport default [\r\n ...frameIn,\r\n ...frameOut,\r\n ...errorPage\r\n]\r\n","// 菜单 顶栏\r\nexport default [\r\n\r\n]\r\n","// 菜单 侧边栏\r\nexport default [\r\n\r\n]\r\n","import request from '@/plugin/axios'\r\n\r\nexport function getUserPermissionInfo () {\r\n return request({\r\n url: '/api/admin/user/v2/front/info',\r\n method: 'get'\r\n })\r\n}\r\n","import Vue from 'vue'\r\nimport VueRouter from 'vue-router'\r\n\r\n// 进度条\r\nimport NProgress from 'nprogress'\r\nimport 'nprogress/nprogress.css'\r\n\r\nimport store from '@/store/index'\r\n\r\nimport util from '@/libs/util.js'\r\n\r\n// 路由数据\r\nimport routes from './routes'\r\n\r\n// 固定菜单与路由\r\nimport menuHeader from '@/menu/header'\r\nimport menuAside from '@/menu/aside'\r\nimport { frameInRoutes } from '@/router/routes'\r\n// 路由与组件映射关系\r\nimport routerMapComponents from '@/routerMapComponents'\r\n// 模拟动态菜单与路由\r\n// import { permissionMenu, permissionRouter } from '@/mock/permissionMenuAndRouter'\r\n// 代码生成器生成的菜单与路由\r\nimport autoGenerateMenusAndRouters from '@/development'\r\nimport * as userService from '@/api/sys/user'\r\n\r\nVue.use(VueRouter)\r\n\r\n// 导出路由 在 main.js 里使用\r\nconst router = new VueRouter({\r\n routes\r\n})\r\n\r\n// eslint-disable-next-line one-var\r\nlet permissionMenu, permissionRouter, permissionHeader = []\r\nlet userInfo = {}\r\nlet permission = {\r\n functions: [],\r\n roles: [],\r\n isAdmin: false\r\n}\r\n\r\n// 标记是否已经拉取权限信息\r\nlet isFetchPermissionInfo = false\r\n\r\nlet fetchPermissionInfo = async () => {\r\n // 处理动态添加的路由\r\n const formatRoutes = function (routes) {\r\n routes.forEach(route => {\r\n route.component = routerMapComponents[route.component]\r\n if (route.children) {\r\n formatRoutes(route.children)\r\n }\r\n })\r\n }\r\n\r\n // const formatRoutesByComponentPath = function (routes) {\r\n // routes.forEach(route => {\r\n // route.component = function (resolve) {\r\n // require([`../${route.componentPath}.vue`], resolve)\r\n // }\r\n // if (route.children) {\r\n // formatRoutesByComponentPath(route.children)\r\n // }\r\n // })\r\n // }\r\n\r\n // const formatRoutesByComponentPath = function (routes) {\r\n // routes.forEach(route => {\r\n // route.component = () => import(`../${route.componentPath}.vue`)\r\n // if (route.children) {\r\n // formatRoutesByComponentPath(route.children)\r\n // }\r\n // })\r\n // }\r\n try {\r\n let userPermissionInfo = await userService.getUserPermissionInfo()\r\n userInfo.name = userPermissionInfo.userName\r\n userInfo.avatarUrl = userPermissionInfo.avatarUrl\r\n permissionMenu = userPermissionInfo.accessMenus\r\n permissionHeader = userPermissionInfo.accessHeader\r\n permissionRouter = userPermissionInfo.accessRoutes\r\n permission.functions = userPermissionInfo.userPermissions\r\n permission.roles = userPermissionInfo.userRoles\r\n permission.interfaces = util.formatInterfaces(userPermissionInfo.accessInterfaces)\r\n permission.isAdmin = userPermissionInfo.isAdmin === 1\r\n } catch (ex) {\r\n console.log(ex)\r\n }\r\n\r\n // 组合代码生成器生成的菜单和路由\r\n console.log(autoGenerateMenusAndRouters)\r\n permissionMenu = [...permissionMenu, ...autoGenerateMenusAndRouters.menus]\r\n permissionRouter = [...permissionRouter, ...autoGenerateMenusAndRouters.routers]\r\n\r\n formatRoutes(permissionRouter)\r\n let allMenuAside = [...menuAside, ...permissionMenu]\r\n let allMenuHeader = [...menuHeader, ...permissionHeader]\r\n // 动态添加路由\r\n router.addRoutes(permissionRouter)\r\n store.dispatch('d2admin/user/set', userInfo)\r\n // 处理路由 得到每一级的路由设置\r\n store.commit('d2admin/page/init', [...frameInRoutes, ...permissionRouter])\r\n // 设置顶栏菜单\r\n store.commit('d2admin/menu/headerSet', allMenuHeader)\r\n // 设置侧边栏菜单\r\n store.commit('d2admin/menu/fullAsideSet', allMenuAside)\r\n // 初始化菜单搜索功能\r\n store.commit('d2admin/search/init', allMenuAside)\r\n // 设置权限信息\r\n store.commit('d2admin/permission/set', permission)\r\n // 加载上次退出时的多页列表\r\n store.dispatch('d2admin/page/openedLoad')\r\n await Promise.resolve()\r\n}\r\n// 免校验token白名单\r\nlet whiteList = ['/login']\r\n\r\n/**\r\n * 路由拦截\r\n * 权限验证\r\n */\r\nrouter.beforeEach(async (to, from, next) => {\r\n // 进度条\r\n NProgress.start()\r\n // 关闭搜索面板\r\n store.commit('d2admin/search/set', false)\r\n const token = util.cookies.get('token')\r\n if (whiteList.indexOf(to.path) === -1) {\r\n // 这里暂时将cookie里是否存有token作为验证是否登录的条件\r\n // 请根据自身业务需要修改\r\n if (token && token !== 'undefined') {\r\n // 拉取权限信息\r\n if (!isFetchPermissionInfo) {\r\n await fetchPermissionInfo()\r\n isFetchPermissionInfo = true\r\n next(to.path, true)\r\n } else {\r\n next()\r\n }\r\n } else {\r\n // 将当前预计打开的页面完整地址临时存储 登录后继续跳转\r\n // 这个 cookie(redirect) 会在登录后自动删除\r\n util.cookies.set('redirect', to.fullPath)\r\n // 没有登录的时候跳转到登录界面\r\n next({\r\n name: 'login'\r\n })\r\n }\r\n } else {\r\n if (to.name === 'login') {\r\n // 如果已经登录,则直接进入系统\r\n if (token && token !== undefined) {\r\n next(from.path, true)\r\n NProgress.done()\r\n } else {\r\n next()\r\n }\r\n } else {\r\n next()\r\n }\r\n }\r\n})\r\n\r\nrouter.afterEach(to => {\r\n // 进度条\r\n NProgress.done()\r\n // 需要的信息\r\n const app = router.app\r\n const { name, params, query } = to\r\n // 多页控制 打开新的页面\r\n app.$store.dispatch('d2admin/page/open', { name, params, query })\r\n // 更改标题\r\n util.title(to.meta.title)\r\n})\r\n\r\nexport default router\r\n","import SpriteSymbol from \"svg-baker-runtime/browser-symbol\";\nimport sprite from \"svg-sprite-loader/runtime/browser-sprite.build\";\nvar symbol = new SpriteSymbol({\n \"id\": \"d2-d2-admin-text\",\n \"use\": \"d2-d2-admin-text-usage\",\n \"viewBox\": \"0 0 88 84\",\n \"content\": \"