diff --git a/nezha-fronted/package-lock.json b/nezha-fronted/package-lock.json index 36ba5d382..fbdd9d2fb 100644 --- a/nezha-fronted/package-lock.json +++ b/nezha-fronted/package-lock.json @@ -4,6 +4,36 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "requires": { + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + } + } + }, + "@riophae/vue-treeselect": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@riophae/vue-treeselect/-/vue-treeselect-0.4.0.tgz", + "integrity": "sha512-J4atYmBqXQmiPFK/0B5sXKjtnGc21mBJEiyKIDZwk0Q9XuynVFX6IJ4EpaLmUgL5Tve7HAS7wkiGGSti6Uaxcg==", + "requires": { + "@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" + } + }, "@sindresorhus/is": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", @@ -3576,6 +3606,11 @@ "stream-shift": "^1.0.0" } }, + "easings-css": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/easings-css/-/easings-css-1.0.0.tgz", + "integrity": "sha512-7Uq7NdazNfVtr0RNmPAys8it0zKCuaqxJStYKEl72D3j4gbvXhhaM7iWNbqhA4C94ygCye6VuyhzBRQC4szeBg==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -5005,6 +5040,11 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "fuzzysearch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fuzzysearch/-/fuzzysearch-1.0.3.tgz", + "integrity": "sha1-3/yA9tawQiPyImqnndGUIxCW0Ag=" + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -5942,6 +5982,11 @@ "isobject": "^3.0.1" } }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -6371,6 +6416,11 @@ "object-visit": "^1.0.0" } }, + "material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, "math-expression-evaluator": { "version": "1.2.17", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", @@ -12354,6 +12404,11 @@ "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.2.tgz", "integrity": "sha512-ha3jNLJqNhhrAemDXcmMJMKf1Zu4sybMPr9KxJIuOpVcsDQlTBYLLladav2U+g1AvdYDG5Gs0xBTb0M5pXXYFQ==" }, + "watch-size": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watch-size/-/watch-size-2.0.0.tgz", + "integrity": "sha512-M92R89dNoTPWyCD+HuUEDdhaDnh9jxPGOwlDc0u51jAgmjUvzqaEMynXSr3BaWs+QdHYk4KzibPy1TFtjLmOZQ==" + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/nezha-fronted/package.json b/nezha-fronted/package.json index 353500894..568bb61e1 100644 --- a/nezha-fronted/package.json +++ b/nezha-fronted/package.json @@ -10,6 +10,7 @@ "build": "node build/build.js" }, "dependencies": { + "@riophae/vue-treeselect": "^0.4.0", "axios": "^0.19.0", "cytoscape": "^3.15.2", "echarts": "^4.7.0", diff --git a/nezha-fronted/src/assets/stylus/main.scss b/nezha-fronted/src/assets/stylus/main.scss index 2e0a7fcda..68b39ad04 100644 --- a/nezha-fronted/src/assets/stylus/main.scss +++ b/nezha-fronted/src/assets/stylus/main.scss @@ -1053,7 +1053,7 @@ li{ } /*此处自定义弹框尺寸,不同功能可能需要的尺寸不一样,需自行添加*/ -.right-box-account, .right-box-prom, .right-box-alert-config, .right-box-project, .right-box-module, .right-box-cabinet, +.right-box-menu ,.right-box-role ,.right-box-account, .right-box-prom, .right-box-alert-config, .right-box-project, .right-box-module, .right-box-cabinet, .right-box-edit-endpoint, .right-box-panel, .right-box-dc, .right-box-model, .right-box-mib, .right-box-asset, .right-box-add-chart { width: 850px; } @@ -2303,3 +2303,15 @@ li{ margin-right: 4px; } } +.el-radio-group .el-radio__inner:hover{ + border-color: #ee9d3f !important; +} +.el-radio-group .is-checked { + .el-radio__inner{ + background-color: #ee9d3f !important; + border-color: #ee9d3f !important; + } + .el-radio__label{ + color: #ee9d3f !important;; + } +} diff --git a/nezha-fronted/src/components/common/header.vue b/nezha-fronted/src/components/common/header.vue index f9af922d3..13c420e60 100644 --- a/nezha-fronted/src/components/common/header.vue +++ b/nezha-fronted/src/components/common/header.vue @@ -124,6 +124,9 @@ {{$t('config.account.account')}} + + {{$t('config.roles.roles')}} + {{$t('config.promServer.promServerList')}} diff --git a/nezha-fronted/src/components/common/home.vue b/nezha-fronted/src/components/common/home.vue index 71463e2a9..b2bfd3b15 100644 --- a/nezha-fronted/src/components/common/home.vue +++ b/nezha-fronted/src/components/common/home.vue @@ -4,7 +4,8 @@ - + + @@ -14,12 +15,20 @@ import Header from "./header"; import webSSH from "../cli/webSSH"; import leftMenu from "./leftMenu"; +import menus from "../page/config/menus"; export default { name: "home", components: { Header, 'web-ssh': webSSH, - 'left-menu': leftMenu + 'left-menu': leftMenu, + menus + }, + computed:{ + isMenuPage:function(){ + console.log(this.$route.path ) + return this.$route.path == '/menu' + } } } diff --git a/nezha-fronted/src/components/common/js/constants.js b/nezha-fronted/src/components/common/js/constants.js index ee20328cc..2ea70afc3 100644 --- a/nezha-fronted/src/components/common/js/constants.js +++ b/nezha-fronted/src/components/common/js/constants.js @@ -5,6 +5,7 @@ export const staticMenus = { title: i18n.t('overall.config'), menu: [ {route: '/account', name: i18n.t('config.account.account')}, + {route: '/roles', name: i18n.t('config.roles.roles')}, {route: '/promServer', name: i18n.t('config.promServer.promServerList')}, {route: '/dc', name: i18n.t('config.dc.dc')}, {route: '/model', name: i18n.t('config.model.model')}, diff --git a/nezha-fronted/src/components/common/language/cn.js b/nezha-fronted/src/components/common/language/cn.js index 7a6e3752d..d4166eed2 100644 --- a/nezha-fronted/src/components/common/language/cn.js +++ b/nezha-fronted/src/components/common/language/cn.js @@ -352,7 +352,7 @@ const cn = { total: "总计", up: "up", down: "down", - prometheus: "prometheus" + prometheus: "prometheus", } } }, @@ -556,6 +556,7 @@ const cn = { account: { accountList: "用户列表", account: "用户", + roles:"角色", language: "语言", receiver: "接收人", createTime: "创建时间", @@ -577,6 +578,35 @@ const cn = { reinputPwd: "请再次输入密码", notification: "通知" }, + roles:{ + roles:"角色", + name:"名称", + remark:"备注", + option: '操作',//"操作" + permission:"权限", + menu:"菜单", + createRole:"新增角色", + editRole:"编辑角色", + + }, + menus:{ + menus:'菜单', + name:"名称", + remark:"备注", + option: '操作',//"操作" + code:'Code', + i18n:'I18n', + type:'类型', + route:'路由', + perms:'权限', + button:"按钮", + menu:"菜单", + parent:"上级菜单", + mainMenu:"主菜单", + createMenu:"新增菜单", + editMenu:"编辑菜单", + orderNum:"排序", + }, promServer: { promServerList: "Prometheus服务", promId: "Prometheus服务ID", diff --git a/nezha-fronted/src/components/common/language/en.js b/nezha-fronted/src/components/common/language/en.js index 92cdac40a..052690431 100644 --- a/nezha-fronted/src/components/common/language/en.js +++ b/nezha-fronted/src/components/common/language/en.js @@ -559,6 +559,7 @@ const en = { accountList: 'Account list',//"用户列表" //列表表头 account: 'Account',//"用户" + roles:"Roles", language: 'Language',//"语言" receiver: 'Receiver',//"用户组" createTime: 'Create time',//"创建时间" @@ -581,6 +582,34 @@ const en = { reinputPwd:'Enter password again', notification: 'Notification' }, + roles:{ + roles:"Roles", + name:"Name", + remark:"Remark", + option: 'Operation',//"操作" + permission:"Permission", + menu:"Menu", + createRole:"Create role", + editRole:"Edit role" + }, + menus:{ + menus:'Menus', + name:"Name", + remark:"Remark", + option: 'Operation',//"操作", + code:'Code', + i18n:'I18n', + type:'Type', + route:'Route', + perms:'Permission', + button:"Button", + menu:"Menu", + parent:"Previous menu", + mainMenu:'Primary menu', + createMenu:"Create menu", + editMenu:"Edit menu", + orderNum:"Order", + }, promServer: { promServerList: 'Prometheus server',//"Prometheus Server" //侧滑框 diff --git a/nezha-fronted/src/components/common/rightBox/accountBox.vue b/nezha-fronted/src/components/common/rightBox/accountBox.vue index 37ce93d0c..710e740e3 100644 --- a/nezha-fronted/src/components/common/rightBox/accountBox.vue +++ b/nezha-fronted/src/components/common/rightBox/accountBox.vue @@ -38,6 +38,14 @@ inactive-value="0"> + + + {this.$forceUpdate()}"> + + + + + {{editUser.createTime}} @@ -109,7 +117,8 @@ }, editUser: {}, scripts: [], - selectableScripts: [] + selectableScripts: [], + roles:[], } }, methods: { @@ -171,6 +180,7 @@ this.scripts = response.data.list; this.getSelectableScripts(); }); + this.getRoles(); /*this.scripts = [ {id: 1, name: "DOLBY"}, {id: 2, name: "IMAX"}, @@ -202,7 +212,16 @@ }); } }, - + getRoles:function(){ + this.roles = []; + this.$get("sys/role").then(response=>{ + if (response.code == 200){ + this.roles = response.data.list; + }else{ + this.$message.error("load roles faild") + } + }) + }, addNotification() { let scripts = this.selectableScripts.find(item => { return item.disabled === false; @@ -229,6 +248,8 @@ deep: true, handler(n) { this.editUser = JSON.parse(JSON.stringify(n)); + this.editUser.roleIds=n.roles&&n.roles.map(t=>t.id) + console.log(this.editUser) } }, "editUser.notifications": { @@ -237,6 +258,13 @@ handler(n) { this.getSelectableScripts(); } + }, + editUser:{ + deep:true, + immediate:true, + handler(n,o){ + console.log('editUser',n) + } } }, } diff --git a/nezha-fronted/src/components/common/rightBox/menuBox.vue b/nezha-fronted/src/components/common/rightBox/menuBox.vue new file mode 100644 index 000000000..b81ea59f1 --- /dev/null +++ b/nezha-fronted/src/components/common/rightBox/menuBox.vue @@ -0,0 +1,266 @@ + + + + + + + {{$t('overall.delete')}} + + + + + + {{editMenu.id ? ($t("config.menus.editMenu") + " ID:" + editMenu.id) : $t("config.menus.createMenu")}} + + + + + + + + + + + {{$t('config.menus.menu')}} + {{$t('config.menus.button')}} + + + + + + + + + + + + + + + + + + + + + {{$t('config.menus.perms')}} + + + + + + + + + + + + + + + + + + {{$t('overall.cancel')}} + + + {{$t('overall.save')}} + + + + + + + diff --git a/nezha-fronted/src/components/common/rightBox/roleBox.vue b/nezha-fronted/src/components/common/rightBox/roleBox.vue new file mode 100644 index 000000000..146a42af3 --- /dev/null +++ b/nezha-fronted/src/components/common/rightBox/roleBox.vue @@ -0,0 +1,219 @@ + + + + + + + {{$t('overall.delete')}} + + + + + + {{editRole.id ? ($t("config.roles.editRole") + " ID:" + editRole.id) : $t("config.roles.createRole")}} + + + + + + + + + + + + + + + + + + + + + + + + {{$t('overall.cancel')}} + + + {{$t('overall.save')}} + + + + + + + diff --git a/nezha-fronted/src/components/page/config/account.vue b/nezha-fronted/src/components/page/config/account.vue index ada6f4bbf..4d8a1d7b0 100644 --- a/nezha-fronted/src/components/page/config/account.vue +++ b/nezha-fronted/src/components/page/config/account.vue @@ -2,6 +2,19 @@ .account { height: 100%; } + .account .account-role-item{ + background-color: #409eff; + border: 1px solid #409eff; + height: 20px; + font-size: 12px; + line-height: 20px; + border-radius: 4px; + display: inline-block; + box-sizing: content-box; + padding:3px; + margin-right: 3px; + color: white; + } @@ -74,6 +87,16 @@ + + + + {{role.i18n?$t(role.i18n):role.name}} + + + + - + + {{scope.row[item.prop] == 'en' ? 'English' : ''}} {{scope.row[item.prop] == 'zh' ? '中文' : ''}} @@ -171,6 +194,7 @@ status: '1', createTime: '', receiver: [], + roles:[], lang: '', notifications: [] }, @@ -189,6 +213,10 @@ label: this.$t("config.account.account"), prop: 'username', show: true, + }, { + label: this.$t("config.account.roles"), + prop: 'roles', + show: true, }, { label: 'E-mail', prop: 'email', diff --git a/nezha-fronted/src/components/page/config/menus.vue b/nezha-fronted/src/components/page/config/menus.vue new file mode 100644 index 000000000..1bac539ae --- /dev/null +++ b/nezha-fronted/src/components/page/config/menus.vue @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + {this.batchDeleteObjs=selection}" + > + + + + + {{item.label}} [Notification] + {{item.label}} + + + + + + + + + + {{$t(scope.row.i18n)}} + + + {{scope.row.name}} + + + - + + + + {{scope.row[item.prop] == 2?$t('config.menus.button'):$t('config.menus.menu')}} + + {{scope.row[item.prop]}} + + + + + + + + + + + + + + + + + + diff --git a/nezha-fronted/src/components/page/config/roles.vue b/nezha-fronted/src/components/page/config/roles.vue new file mode 100644 index 000000000..1fa618596 --- /dev/null +++ b/nezha-fronted/src/components/page/config/roles.vue @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + + + + + + {this.batchDeleteObjs=selection}" + > + + + + + {{item.label}} [Notification] + {{item.label}} + + + + + + + + + + {{$t(scope.row.i18n)}} + + + {{scope.row.name}} + + + - + + + {{scope.row[item.prop]}} + + + + + + + + + + + + + + + + + + diff --git a/nezha-fronted/src/router/index.js b/nezha-fronted/src/router/index.js index 25fc414f2..c5329e208 100644 --- a/nezha-fronted/src/router/index.js +++ b/nezha-fronted/src/router/index.js @@ -60,6 +60,14 @@ export default new Router({ path: '/account', component: resolve => require(['../components/page/config/account.vue'], resolve), }, + { + path: '/menu', + component: resolve => require(['../components/page/config/menus.vue'], resolve), + }, + { + path: '/roles', + component: resolve => require(['../components/page/config/roles.vue'], resolve), + }, { path: '/promServer', component: resolve => require(['../components/page/config/promServer.vue'], resolve),