| | |
| | | .DS_Store |
| | | coderd.json |
| | | node_modules |
| | | /dist |
| | | |
| | | *.class |
| | | |
| | | # Mobile Tools for Java (J2ME) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ç¯å¢éç¨é
ç½® |
| | | |
| | | # è·¯ç±æ¹å¼ |
| | | VUE_APP_ROUTER_MODE = 'hash' |
| | | |
| | | # 项ç®ä¸ä¸æè·¯å¾ |
| | | VUE_APP_CONTEXT_PATH = '/' |
| | | |
| | | # æ¥å£åç¼ |
| | | VUE_APP_API_PREFIX = '/api' |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å¼åç¯å¢é
ç½® |
| | | NODE_ENV = 'development' |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ç产ç¯å¢é
ç½® |
| | | NODE_ENV = 'production' |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æµè¯ç¯å¢é
ç½® |
| | | NODE_ENV = 'production' |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | .DS_Store |
| | | coderd.json |
| | | node_modules |
| | | /dist |
| | | |
| | | |
| | | # local env files |
| | | .env.local |
| | | .env.*.local |
| | | |
| | | # Log files |
| | | npm-debug.log* |
| | | yarn-debug.log* |
| | | yarn-error.log* |
| | | pnpm-debug.log* |
| | | |
| | | # Editor directories and files |
| | | .idea |
| | | .vscode |
| | | *.suo |
| | | *.ntvs* |
| | | *.njsproj |
| | | *.sln |
| | | *.sw? |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | æ¡æ¶ï¼Eva v2.0 |
| | | Evaå®ç½ï¼http://eva.adjust-rd.com |
| | | |
| | | # 项ç®ç®å½è¯´æ |
| | | - src/assetsï¼éæèµæºç®å½ |
| | | - src/componentsï¼èªå®ä¹ç»ä»¶ç®å½ |
| | | - src/pluginsï¼æä»¶ç®å½ |
| | | - src/routerï¼è·¯ç±é
ç½®ç®å½ |
| | | - src/storeï¼vuex storeç®å½ |
| | | - src/utilsï¼å·¥å
·ç®å½ |
| | | - src/viewsï¼é¡µé¢ç®å½ |
| | | |
| | | # ææ¯æ |
| | | - è·¯ç±ï¼Vue-Router-3.2.0 |
| | | - é¢ç¼è¯ï¼SASS-4.12.0 |
| | | - HTTPåºï¼axios-0.21.1 |
| | | - UIåºï¼element-ui-2.3.6 |
| | | - 代ç è§èæ£æ¥ï¼eslint-6.7.2 |
| | | |
| | | # ä»£ç æ£æ¥ |
| | | ä»£ç æ£æ¥è§åé
ç½®å¨package.jsonçeslintConfigå¯¹è±¡ä¸ |
| | | |
| | | # è·¯ç± |
| | | è·¯ç±é
ç½®å¨src/router/index.jsä¸ |
| | | |
| | | # æ¥å£ä»£çåè°ç¨ |
| | | æ¥å£ä»£çè·¯å¾é
ç½®å¨vue.config.jsæä»¶ä¸ï¼æ¥å£è°ç¨å·¥å
·å°è£
å¨src/utils/request.jsä¸ï¼è°ç¨ç¤ºä¾å¦ä¸ |
| | | ```javascript |
| | | import request from '@/utils/request' |
| | | |
| | | request.post('/api/myinterface', { |
| | | param1: 'param value' |
| | | }) |
| | | .then(data => { |
| | | console.log('è¯·æ±æåï¼æ¥å£è¿å', data) |
| | | }) |
| | | .catch(e => { |
| | | console.log('è°ç¨å¤±è´¥', e) |
| | | }) |
| | | ``` |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | module.exports = { |
| | | presets: [ |
| | | '@vue/cli-plugin-babel/preset' |
| | | ] |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "dmtiaotiao", |
| | | "version": "1.0.0", |
| | | "private": true, |
| | | "scripts": { |
| | | "serve": "vue-cli-service serve", |
| | | "build": "vue-cli-service build", |
| | | "build:staging": "vue-cli-service build --mode staging", |
| | | "lint": "vue-cli-service lint", |
| | | "fix": "eslint --ext .js,.vue src --fix" |
| | | }, |
| | | "dependencies": { |
| | | "@riophae/vue-treeselect": "^0.4.0", |
| | | "axios": "^0.21.1", |
| | | "core-js": "^3.6.5", |
| | | "element-ui": "^2.3.6", |
| | | "js-cookie": "^2.2.1", |
| | | "js-file-download": "^0.4.12", |
| | | "vue": "^2.6.11", |
| | | "vue-clipboard2": "^0.3.1", |
| | | "vue-router": "^3.5.1", |
| | | "vuescroll": "^4.17.3", |
| | | "vuex": "^3.4.0" |
| | | }, |
| | | "devDependencies": { |
| | | "@vue/cli-plugin-babel": "~4.5.0", |
| | | "@vue/cli-plugin-eslint": "~4.5.0", |
| | | "@vue/cli-plugin-router": "~4.5.0", |
| | | "@vue/cli-plugin-vuex": "~4.5.0", |
| | | "@vue/cli-service": "~4.5.0", |
| | | "@vue/eslint-config-standard": "^5.1.2", |
| | | "babel-eslint": "^10.1.0", |
| | | "eslint": "^6.7.2", |
| | | "eslint-plugin-import": "^2.20.2", |
| | | "eslint-plugin-node": "^11.1.0", |
| | | "eslint-plugin-promise": "^4.2.1", |
| | | "eslint-plugin-standard": "^4.0.0", |
| | | "eslint-plugin-vue": "^6.2.2", |
| | | "lint-staged": "^9.5.0", |
| | | "node-sass": "^4.12.0", |
| | | "sass-loader": "^8.0.2", |
| | | "vue-cli-plugin-element-ui": "~1.1.4", |
| | | "vue-template-compiler": "^2.6.11" |
| | | }, |
| | | "eslintConfig": { |
| | | "root": true, |
| | | "env": { |
| | | "node": true |
| | | }, |
| | | "extends": [ |
| | | "plugin:vue/essential", |
| | | "@vue/standard" |
| | | ], |
| | | "parserOptions": { |
| | | "parser": "babel-eslint" |
| | | }, |
| | | "rules": { |
| | | "indent": [ |
| | | "error", |
| | | 2 |
| | | ], |
| | | "generator-star-spacing": "off", |
| | | "no-debugger": "error" |
| | | } |
| | | }, |
| | | "browserslist": [ |
| | | "> 1%", |
| | | "last 2 versions", |
| | | "not dead" |
| | | ], |
| | | "gitHooks": { |
| | | "pre-commit": "lint-staged" |
| | | }, |
| | | "lint-staged": { |
| | | "*.{js,jsx,vue}": [ |
| | | "vue-cli-service lint", |
| | | "git add" |
| | | ] |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <!DOCTYPE html> |
| | | <html lang=""> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| | | <meta name="viewport" content="width=device-width,initial-scale=1.0"> |
| | | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
| | | <title>è±ç±³è·³è·³</title> |
| | | </head> |
| | | <body> |
| | | <noscript> |
| | | <strong>We're sorry but è±ç±³è·³è·³ doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
| | | </noscript> |
| | | <div id="app"></div> |
| | | <!-- built files will be auto injected --> |
| | | </body> |
| | | </html> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <router-view/> |
| | | </template> |
| | | |
| | | <style lang="scss"> |
| | | // å¼å
¥å
¨å±æ ·å¼ |
| | | @import "assets/style/style"; |
| | | // å¼å
¥ç³»ç»å
ç½®å¾æ |
| | | @import "assets/icons/system/index"; |
| | | // å¼å
¥èªå®ä¹å¾æ |
| | | @import "assets/icons/ext/index"; |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // è·åå¾çéªè¯ç |
| | | export function getCaptcha () { |
| | | return request.get('/common/captcha') |
| | | } |
| | | |
| | | // æ ¹æ®å¯ç ç»å½ |
| | | export function loginByPassword (data) { |
| | | return request.post('/system/login', data) |
| | | } |
| | | |
| | | // ç»åº |
| | | export function logout (data) { |
| | | return request.post('/system/logout', data) |
| | | } |
| | | |
| | | // ä¿®æ¹å¯ç |
| | | export function updatePwd (data) { |
| | | return request.post('/system/updatePwd', data) |
| | | } |
| | | |
| | | // è·åå·²ç»å½çç¨æ·ä¿¡æ¯ |
| | | export function getUserInfo () { |
| | | return request.get('/system/getUserInfo', { |
| | | autoLogin: false |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '../../utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/dataPermission/page', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢æ°æ®æé模å |
| | | export function fetchModules () { |
| | | return request.cache('DATA_PERMISSION_MODULES').get('/system/dataPermission/modules') |
| | | } |
| | | |
| | | // æ¥è¯¢æ°æ®æéç±»å |
| | | export function fetchTypes () { |
| | | return request.cache('DATA_PERMISSION_TYPES').get('/system/dataPermission/types') |
| | | } |
| | | |
| | | // å建 |
| | | export function create (data) { |
| | | return request.post('/system/dataPermission/create', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/dataPermission/updateById', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ç¶æ |
| | | export function updateStatus (data) { |
| | | return request.post('/system/dataPermission/updateStatus', data) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/dataPermission/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/dataPermission/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchTree () { |
| | | return request.post('/system/department/tree') |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨ç¨æ· |
| | | export function fetchUserList (data) { |
| | | return request.post('/system/department/users', data) |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/department/create', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/department/updateById', data) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/department/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/department/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/dict/page', data) |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/dict/create', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/dict/updateById', data) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/dict/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/dict/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/dictData/page', data) |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/dictData/create', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/dictData/updateById', data) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/dictData/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/dictData/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '../../utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/loginLog/page', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // 导åºExcel |
| | | export function exportExcel (data) { |
| | | return request.post('/system/loginLog/exportExcel', data, { |
| | | download: true, |
| | | trim: true |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchTree (data) { |
| | | return request.post('/system/menu/treeList', data) |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/menu/create', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/menu/updateById', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ç¶æ |
| | | export function updateStatus (data) { |
| | | return request.post('/system/menu/updateStatus', data) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/menu/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/menu/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢èåæ |
| | | export function fetchMenuTree () { |
| | | return request.get('/system/menu/treeNodes') |
| | | } |
| | | |
| | | // æåº |
| | | export function sort (data) { |
| | | return request.post('/system/menu/updateSort', data) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // è·åç³»ç»ä¿¡æ¯ |
| | | export function getSystemInfo () { |
| | | return request.get('/system/monitor/getSystemInfo') |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/permission/page', data) |
| | | } |
| | | |
| | | // æ¥è¯¢ææ |
| | | export function fetchAll () { |
| | | return request.get('/system/permission/all') |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/permission/create', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/permission/updateById', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/permission/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/permission/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢å表æ |
| | | export function fetchTree (data) { |
| | | return request.post('/system/position/tree', data) |
| | | } |
| | | |
| | | // æ¥è¯¢å表 |
| | | export function fetchList (data) { |
| | | return request.post('/system/position/list', data) |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/position/create', data) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/position/updateById', data) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/position/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/position/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/role/page', data) |
| | | } |
| | | |
| | | // æ¥è¯¢ææ |
| | | export function fetchAll () { |
| | | return request.get('/system/role/all') |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/role/create', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/role/updateById', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/role/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/role/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // é
ç½®æé |
| | | export function createRolePermission (data) { |
| | | return request.post('/system/role/createRolePermission', data) |
| | | } |
| | | |
| | | // é
ç½®èå |
| | | export function createRoleMenu (data) { |
| | | return request.post('/system/role/createRoleMenu', data) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '../../utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/traceLog/page', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // 导åºExcel |
| | | export function exportExcel (data) { |
| | | return request.post('/system/traceLog/exportExcel', data, { |
| | | download: true, |
| | | trim: true |
| | | }) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ |
| | | export function fetchList (data) { |
| | | return request.post('/system/user/page', data) |
| | | } |
| | | |
| | | // æ°å»º |
| | | export function create (data) { |
| | | return request.post('/system/user/create', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ |
| | | export function updateById (data) { |
| | | return request.post('/system/user/updateById', data, { |
| | | trim: true |
| | | }) |
| | | } |
| | | |
| | | // å é¤ |
| | | export function deleteById (id) { |
| | | return request.get(`/system/user/delete/${id}`) |
| | | } |
| | | |
| | | // æ¹éå é¤ |
| | | export function deleteByIdInBatch (ids) { |
| | | return request.get('/system/user/delete/batch', { |
| | | params: { |
| | | ids |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // é
ç½®ç¨æ·è§è² |
| | | export function createUserRole (data) { |
| | | return request.post('/system/user/createUserRole', data) |
| | | } |
| | | |
| | | // éç½®å¯ç |
| | | export function resetPwd (data) { |
| | | return request.post('/system/user/resetPwd', data) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * æ¤æä»¶ç¨äºæ·»å èªå®ä¹ç徿 |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621750709361" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7590" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M890.96986 479.671711 545.11094 479.671711 545.11094 271.38592 684.78875 271.38592 684.78875 64.500013 343.028339 64.500013 343.028339 271.38592 480.338121 271.38592 480.338121 479.671711 133.397522 479.671711 133.397522 532.849864 133.397522 548.629245 133.397522 755.515153 64.284683 755.515153 64.284683 959.499987 270.160836 959.499987 270.160836 755.515153 202.498081 755.515153 202.498081 548.629245 480.338121 548.629245 480.338121 755.515153 409.786454 755.515153 409.786454 959.499987 615.662607 959.499987 615.662607 755.515153 545.11094 755.515153 545.11094 548.629245 822.225426 548.629245 822.225426 755.515153 753.863725 755.515153 753.863725 959.499987 959.714294 959.499987 959.714294 755.515153 890.96986 755.515153Z" p-id="7591" fill="#f7f7f7"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621751616853" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12750" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M225.5 596.7h63.8V652h-63.8v-55.3z m0-165.8h63.8v55.3h-63.8v-55.3z m0-165.7h63.8v55.3h-63.8v-55.3z m127.6 331.5h446.3V652H353.1v-55.3z m0-165.8h446.3v55.3H353.1v-55.3z m0-165.7h446.3v55.3H353.1v-55.3zM98 156.3v694.3c0 46.6 45 77.7 96.4 77.7h732.5v-46.6H194.4c-19.3 0-32.2-10.4-32.2-25.9 0-15.5 12.8-25.9 32.2-25.9h732.5V99.4H168.7c-32.1 5.1-64.3 31.1-70.7 56.9z" fill="#f7f7f7" p-id="12751"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * æ¤æä»¶ä¸ºç³»ç»èªå¸¦ç徿 å®ä¹ï¼å¦æ¨éè¦æ©å±å¾æ 请å¨ext.scssæä»¶ä¸å¤çã |
| | | */ |
| | | // 徿 æ ·å¼ |
| | | [class^="eva-icon-"], [class*=" eva-icon-"] { |
| | | display: inline-block; |
| | | width: 18px; |
| | | height: 18px; |
| | | background-size: 13px; |
| | | background-repeat: no-repeat; |
| | | background-position: center; |
| | | } |
| | | // å¯ç |
| | | .eva-icon-password { |
| | | background-image: url("assets/icons/system/pwd.svg"); |
| | | } |
| | | // ç¾ç |
| | | .eva-icon-shield { |
| | | background-image: url("assets/icons/system/shield.svg"); |
| | | } |
| | | // æé |
| | | .eva-icon-permission { |
| | | background-image: url("assets/icons/system/permission.svg"); |
| | | } |
| | | // è§è² |
| | | .eva-icon-role { |
| | | background-image: url("assets/icons/system/role.svg"); |
| | | } |
| | | // é¨é¨ |
| | | .eva-icon-department { |
| | | background-image: url("assets/icons/system/department.svg"); |
| | | } |
| | | // å²ä½ |
| | | .eva-icon-position { |
| | | background-image: url("assets/icons/system/position.svg"); |
| | | } |
| | | // åå
¸ |
| | | .eva-icon-dictionary { |
| | | background-image: url("assets/icons/system/dictionary.svg"); |
| | | } |
| | | // çæµ |
| | | .eva-icon-listener { |
| | | background-image: url("assets/icons/system/listener.svg"); |
| | | } |
| | | // æ¥å¿ |
| | | .eva-icon-log { |
| | | background-image: url("assets/icons/system/log.svg"); |
| | | } |
| | | // æä½æ¥å¿ |
| | | .eva-icon-log-opera { |
| | | background-image: url("assets/icons/system/log-opera.svg"); |
| | | } |
| | | // ç»å½æ¥å¿ |
| | | .eva-icon-log-login { |
| | | background-image: url("assets/icons/system/log-login.svg"); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621751666911" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13701" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M64.28 671v80.3c0 34.76 26.84 62.94 60 62.94h297.47v94.15H285.53c-24.17 0-48.38-0.49-72.54 0h-1.06c-12.54 0-24.55 11.58-24 25.18s10.53 25.17 24 25.17h525.88c24.16 0 48.37 0.49 72.53 0h1.06c12.54 0 24.56-11.58 24-25.17s-10.54-25.18-24-25.18H601.59v-94.11H899.1c33.11 0 59.95-28.18 59.95-62.94V671zM899.77 65H124.9A60 60 0 0 0 65 125v499.3h894.72V125a60 60 0 0 0-59.95-60zM757.46 296.75l-6.89 7.53-77 84.15-36.78 40.22c0.08 1.2 0.14 2.41 0.14 3.63a51.09 51.09 0 1 1-100.6-12.67l-55.74-65.31-38.46-45a51 51 0 0 1-21.7 0.18l-6 5.78-71.92 69.71-30.85 29.9a45.45 45.45 0 1 1-36.1-35.1l2.85-2.76 71.92-69.72 32.2-31.21A51.09 51.09 0 1 1 482 259.44a51.66 51.66 0 0 1-1.28 11.34l10.62 12.44L561.13 365l14.72 17.23a51.85 51.85 0 0 1 10-1 50.84 50.84 0 0 1 22.14 5l76.82-84q15.3-16.73 30.59-33.44a45.42 45.42 0 1 1 42 28z" p-id="13702" fill="#f7f7f7"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622347607410" class="icon" viewBox="0 0 1038 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3794" width="64.875" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M76.778433 76.778433h776.41112v328.249368h77.209773v-345.071609A59.956192 59.956192 0 0 0 872.599832 0H59.956192A59.956192 59.956192 0 0 0 0 59.956192v898.048863a59.956192 59.956192 0 0 0 59.956192 59.956192H474.473463v-75.915754H76.778433z" p-id="3795" fill="#f7f7f7"></path><path d="M209.631003 256.647009h513.294018v81.091828H209.631003zM209.631003 472.748104h389.068239v81.091829H209.631003zM209.631003 684.535805h278.213984v81.091828H209.631003zM914.871104 774.685762a163.046335 163.046335 0 1 0-227.747262 0 180.731255 180.731255 0 0 0-122.069082 180.731256c0 68.582982 102.227464 68.582982 243.706824 68.582982h86.267902c59.956192 0 101.364785-3.450716 125.088458-27.605729a57.799495 57.799495 0 0 0 17.68492-43.133951 172.535805 172.535805 0 0 0-122.93176-178.574558zM733.277169 590.503791a94.894693 94.894693 0 0 1 67.288964-28.037068 92.306655 92.306655 0 1 1-67.288964 26.74305z m122.500422 364.913227h-46.584668a862.679023 862.679023 0 0 1-172.535804-10.352149c5.607414-99.639427 92.737995-121.206403 166.065712-121.206402 144.498736 0 164.771693 70.73968 166.497051 125.951137a480.943555 480.943555 0 0 1-113.442291 5.607414z" p-id="3796" fill="#f7f7f7"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622347629380" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4602" width="64.0625" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M548.075474 961.502824H37.281249a39.060735 39.060735 0 0 1-37.257932-40.262603V103.368526a39.060735 39.060735 0 0 1 37.257932-40.262604h717.515653a39.060735 39.060735 0 0 1 37.257931 40.262604V513.205775h-60.093438V128.006836H61.919559v773.40255H487.982036l60.093438 63.699045z" fill="#f7f7f7" p-id="4603"></path><path d="M733.764198 513.205775a223.54759 223.54759 0 1 1-225.350393 223.54759 227.153197 227.153197 0 0 1 225.350393-223.54759m0-63.699045A287.246635 287.246635 0 1 0 1022.813636 736.753365a287.246635 287.246635 0 0 0-289.049438-287.246635zM210.951285 0.007812h18.028032a22.835507 22.835507 0 0 1 22.835506 22.835507v145.42612a23.436441 23.436441 0 0 1-22.835506 23.436441h-18.028032a23.436441 23.436441 0 0 1-23.436441-23.436441V25.247056a22.835507 22.835507 0 0 1 22.835507-25.239244z m385.19894 0h18.028031a22.835507 22.835507 0 0 1 23.436441 22.835507v145.42612a23.436441 23.436441 0 0 1-23.436441 23.436441h-18.028031a23.436441 23.436441 0 0 1-22.835507-23.436441V25.247056a22.835507 22.835507 0 0 1 22.835507-25.239244zM157.468125 321.507707h514.399832a31.849522 31.849522 0 0 1 31.849522 31.849522 31.849522 31.849522 0 0 1-31.849522 31.849522H157.468125a31.849522 31.849522 0 0 1-31.849522-31.849522 31.849522 31.849522 0 0 1 31.849522-31.849522z m0 191.698068h257.199916a31.849522 31.849522 0 0 1 31.849522 31.849522 31.849522 31.849522 0 0 1-31.849522 31.849522H157.468125a31.849522 31.849522 0 0 1-31.849522-31.849522 31.849522 31.849522 0 0 1 31.849522-31.849522z m0 191.698068h192.899937a31.248588 31.248588 0 0 1 31.849522 31.849522 31.849522 31.849522 0 0 1-31.849522 31.849522H157.468125a31.849522 31.849522 0 0 1-31.849522-31.849522 31.849522 31.849522 0 0 1 31.849522-31.849522z" fill="#f7f7f7" p-id="4604"></path><path d="M870.777237 829.29726h-152.637333v-212.730771a30.647654 30.647654 0 0 1 30.647654-30.647654 30.647654 30.647654 0 0 1 30.647653 30.647654v152.036398h91.342026a30.046719 30.046719 0 0 1 30.04672 30.647654 30.046719 30.046719 0 0 1-30.04672 30.046719z" fill="#f7f7f7" p-id="4605"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1622347409604" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2382" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M299.1872 255.5904a42.496 42.496 0 0 0 42.5728-42.5472V42.752a42.5728 42.5728 0 0 0-85.1712 0v170.24c0 23.552 19.0464 42.5984 42.5984 42.5984zM512.1536 255.5904a42.496 42.496 0 0 0 42.5984-42.5472V42.752a42.5728 42.5728 0 1 0-85.1712 0v170.24c0 23.552 19.0976 42.5984 42.5728 42.5984zM384.4096 81.792h42.5984v85.0688h-42.5984zM597.4784 81.792h42.5728v85.0688H597.504z" fill="#f7f7f7" p-id="2383"></path><path d="M1023.3088 896.1024v-691.2c0.1536-70.6048-57.2416-127.6928-127.744-127.6928h-85.1712v85.0688h85.1712c23.4752 0 42.7264 19.072 42.7264 42.5216v691.3024c0 23.4496-19.2512 42.5984-42.752 42.5984H128.768a42.7264 42.7264 0 0 1-42.5728-42.5984H85.504l0.6656-691.2c0-23.4752 19.0976-42.5472 42.5728-42.5472h85.1712V77.2096H128.768A127.6928 127.6928 0 0 0 1.024 204.8768v691.2a127.616 127.616 0 0 0 127.744 127.6928h766.7968a127.3344 127.3344 0 0 0 127.232-121.344c0.0768-0.3584 0.512-0.7936 0.512-1.152v-3.7888c0-0.512 0.1536-0.9472 0.1536-1.4592h-0.1536v0.0768z" fill="#f7f7f7" p-id="2384"></path><path d="M725.248 255.5904c23.4496 0 42.5728-19.0208 42.5728-42.5472V42.752a42.5728 42.5728 0 0 0-85.1712 0v170.24c0 23.552 18.8672 42.5984 42.5728 42.5984zM255.872 426.4448h511.2064c23.3472 0 42.5728-19.072 42.5728-42.5216 0-23.552-19.2256-42.5472-42.5728-42.5472H255.8464a42.496 42.496 0 1 0 0 85.0688zM767.0784 551.3728H255.8464a42.5728 42.5728 0 1 0 0 85.0688h511.232c23.3216 0 42.5728-19.0976 42.5728-42.5472 0-23.4496-19.2512-42.5216-42.5728-42.5216zM767.0784 769.5872H255.8464a42.5216 42.5216 0 1 0 0 85.0688h511.232c23.3216 0 42.5728-19.1488 42.5728-42.6752 0-23.3984-19.2512-42.3936-42.5728-42.3936z" fill="#f7f7f7" p-id="2385"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621746809427" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4923" width="64.0625" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M928.612599 95.57028a325.17778 325.17778 0 0 0-523.501496 370.143341l-383.852354 383.852354a72.018013 72.018013 0 0 0 0 102.177841L73.352997 1002.741343a72.018013 72.018013 0 0 0 102.177841 0L329.254566 847.920893l19.192618 19.192618a73.114734 73.114734 0 0 0 102.177841 0l51.180314-51.180314a73.114734 73.114734 0 0 0 0-102.177841L482.978295 694.928312l75.490963-75.490963A325.17778 325.17778 0 0 0 928.612599 95.57028zM777.447886 402.469376a109.672101 109.672101 0 1 1-2.741802-155.186023 109.672101 109.672101 0 0 1 2.741802 155.186023z" p-id="4924" fill="#f7f7f7"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621751435396" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11906" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M870 96H154c-49.5 0-90 40.6-90 90.2v651.6c0 49.6 40.5 90.2 90 90.2h716c49.5 0 90-40.6 90-90.2V186.2c0-49.6-40.5-90.2-90-90.2zM177.5 314.4h167.3v59.9H177.5v-59.9z m0 223.5h167.3v59.9H177.5v-59.9z m646.4 229.9v-0.2H362.8v0.2h-59.7c0-20.1 2.3-39.9 6.9-59.1v-1.2h0.3c3.8-15.7 9.1-31 16-46 14.8-32.3 35.9-61.3 62.7-86.1 36.8-34 81.6-57.7 130.5-69.7-39.8-24.8-66.3-69-66.3-119.4 0-77.6 62.7-140.6 140.2-140.6 77.5 0 140.2 63 140.2 140.6 0 50.4-26.5 94.6-66.3 119.4 48.9 11.9 93.7 35.6 130.5 69.7 26.8 24.8 47.9 53.8 62.7 86.1 15.4 33.7 23.2 69.4 23.2 106.3h-59.8z" fill="#f7f7f7" p-id="11907"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621744473001" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2398" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M822.857143 475.428571a36.571429 36.571429 0 0 1 36.571428 36.571429v91.428571a347.428571 347.428571 0 0 1-694.857142 0v-91.428571a36.571429 36.571429 0 0 1 36.571428-36.571429h621.714286m0-73.142857H201.142857a109.714286 109.714286 0 0 0-109.714286 109.714286v91.428571a420.571429 420.571429 0 0 0 420.571429 420.571429 420.571429 420.571429 0 0 0 420.571429-420.571429v-91.428571a109.714286 109.714286 0 0 0-109.714286-109.714286z" p-id="2399" fill="#c1c4cc"></path><path d="M731.428571 475.428571a36.571429 36.571429 0 0 1-36.571428-36.571428V256a182.857143 182.857143 0 0 0-365.714286 0v182.857143a36.571429 36.571429 0 0 1-73.142857 0V256a256 256 0 0 1 512 0v182.857143a36.571429 36.571429 0 0 1-36.571429 36.571428zM512 768a36.571429 36.571429 0 0 1-36.571429-36.571429v-146.285714a36.571429 36.571429 0 0 1 73.142858 0v146.285714a36.571429 36.571429 0 0 1-36.571429 36.571429z" p-id="2400" fill="#c1c4cc"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621750614796" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6622" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M782.215429 604.888761l-18.436207-15.623905-4.609052-3.749737c-3.827857-3.2029-7.811952-6.249562-11.48357-9.296223l-5.234008-3.905976-1.093673-0.859315-6.56204-4.765291c-3.359139-2.421705-6.796398-4.765291-10.233658-7.030757l-2.343585-1.56239a382.082586 382.082586 0 0 0-109.367332-49.293419 264.668943 264.668943 0 1 0-204.438791 0 385.129247 385.129247 0 0 0-108.0393 48.98094l-2.265466 1.562391c-3.515379 2.265466-6.952638 4.609052-10.233658 7.030757l-6.640159 4.84341-0.937434 0.624957-5.312128 4.062215c-3.905976 2.968542-7.811952 6.093323-11.952287 9.608701l-4.062215 3.437259-18.592446 15.623905 0.937434 0.546836A397.159653 397.159653 0 0 0 122.183582 889.321943V914.085832a109.757929 109.757929 0 0 0 109.757929 109.367331h559.257663a109.757929 109.757929 0 0 0 109.367332-109.367331v-24.998248a396.847175 396.847175 0 0 0-119.288511-283.730106z" fill="#f7f7f7" p-id="6623"></path><path d="M232.253989 576.297015c3.984096-3.359139 7.811952-6.327681 11.327331-9.139984l5.858964-4.452813 0.859315-0.624956 6.952637-5.077769 10.936734-7.811952 2.421705-1.562391a403.409215 403.409215 0 0 1 74.526024-38.512924 286.698648 286.698648 0 0 1-138.115316-244.748465c0-6.405801 0-12.733482 0.703076-18.983044a171.081755 171.081755 0 0 0 24.52953 330.914298zM225.926308 581.609143a252.951015 252.951015 0 0 0-102.805292 39.059761l-1.562391 1.015554c-2.265466 1.56239-4.530932 3.046661-6.718278 4.687171l-4.374694 3.202901c-1.406151 1.015554-2.812303 2.031108-4.140334 3.124781-2.577944 1.952988-5.155888 3.984096-7.811953 6.093322l-0.859314 0.781196-2.187347 1.718629A262.950313 262.950313 0 0 0 5.004298 839.872285v17.342534a63.979889 63.979889 0 0 0 63.979889 63.979889h12.186645v-21.482869a421.220466 421.220466 0 0 1 107.648703-281.230281zM678.863301 509.426704a406.221518 406.221518 0 0 1 74.526024 38.512925l2.343586 1.56239 11.014853 7.811952 6.874518 5.077769 0.937434 0.624956 5.858964 4.452813c3.593498 2.812303 7.343235 5.780845 11.327331 9.139984a171.081755 171.081755 0 0 0 24.52953-330.914298c0.390598 6.249562 0.703076 12.577243 0.703076 18.983044A286.698648 286.698648 0 0 1 678.863301 509.426704zM928.220817 641.136219l-2.109227-1.718629-0.937434-0.781196c-2.499825-2.109227-4.999649-4.140335-7.811953-6.093322l-4.140334-3.124781-4.374694-3.202901c-2.187347-1.64051-4.452813-3.124781-6.796398-4.687171l-1.484271-1.015554a253.341612 253.341612 0 0 0-102.805292-39.059761l37.106773 36.716175a421.142347 421.142347 0 0 1 107.570583 281.230282v21.482869h12.186646a64.058009 64.058009 0 0 0 64.058008-63.979889v-17.030056a262.715955 262.715955 0 0 0-90.462407-198.736066z" fill="#f7f7f7" p-id="6624"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621745695957" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3315" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M517.094527 1024c-153.345274 0-438.129353-228.234826-438.129353-444.242786V167.60995c0-10.189055 8.151244-17.830846 18.849751-18.340298l24.963184-0.509453c1.018905 0 98.324378-2.037811 198.686568-41.775124C423.864677 66.228856 490.093532 19.359204 491.112438 18.849751l14.774129-10.189054c3.056716-2.037811 7.132338-3.566169 11.20796-3.56617 4.075622 0 8.151244 1.018905 11.207961 3.56617l14.774129 10.698507c0.509453 0.509453 67.247761 47.379104 170.157214 88.135323 100.362189 39.737313 197.667662 41.775124 198.686567 41.775125l24.453731 0.509452c10.189055 0 18.849751 8.151244 18.849752 18.340299v412.147264c0 215.498507-284.78408 443.733333-438.129354 443.733333z m370.881592-808.501493c-37.699502-3.056716-117.174129-12.736318-199.196019-45.341293-84.569154-33.114428-146.212935-70.304478-171.685573-87.116418-25.472637 16.302488-87.116418 54.00199-171.685572 87.116418-82.021891 32.604975-160.987065 42.284577-199.19602 45.341293v364.258707c0 169.138308 248.103483 376.485572 370.881592 376.485572 47.379104 0 140.099502-38.718408 230.78209-123.287562 87.625871-81.512438 140.099502-176.270647 140.099502-253.19801V215.498507z m-406.03383 433.544279c-6.113433 6.622886-14.774129 10.189055-23.944279 10.189055-9.170149 0-17.321393-3.566169-23.944279-10.189055l-101.381094-101.890547a33.827662 33.827662 0 0 1 0-47.888557c13.245771-13.245771 34.133333-13.245771 47.379104-0.509453l0.509453 0.509453 77.436816 77.946268 195.120398-196.648756c12.736318-13.245771 34.133333-13.245771 47.379104-0.509453l0.509453 0.509453c13.245771 13.245771 13.245771 34.642786 0 47.888557l-219.064676 220.593035z" p-id="3316" fill="#c1c4cc"></path></svg> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | @import "variables"; |
| | | /* theme color */ |
| | | $--color-primary: $primary-color; |
| | | |
| | | /* icon font path, required */ |
| | | $--font-path: '~element-ui/lib/theme-chalk/fonts'; |
| | | |
| | | @import "~element-ui/packages/theme-chalk/src/index"; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | @import "variables.scss"; |
| | | // æ ·å¼éç½® |
| | | html { |
| | | height: 100%; |
| | | padding: 0; |
| | | margin: 0; |
| | | color: $font-color; |
| | | font-family: 'Avenir', Helvetica, Arial, sans-serif; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | body { |
| | | height: 100%; |
| | | padding: 0; |
| | | margin: 0; |
| | | } |
| | | h1,h2,h3,h4,h5,h6,ul { |
| | | margin: 0; |
| | | padding: 0; |
| | | } |
| | | ul { |
| | | list-style: none; |
| | | } |
| | | #app { |
| | | height: 100%; |
| | | min-width: $page-min-width; |
| | | } |
| | | } |
| | | |
| | | // ç©¿æ¢æ¡çæé® |
| | | .el-transfer__buttons { |
| | | padding: 0 16px !important; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 主è²è° |
| | | $primary-color: #2E68EC; |
| | | // 头é¨é«åº¦ |
| | | $header-height: 60px; |
| | | // èå宽度 |
| | | $menu-width: 208px; |
| | | // 页颿å°å®½åº¦ |
| | | $page-min-width: 1000px; |
| | | |
| | | // åä½ |
| | | $font-color: #282828; // é¢è² |
| | | $font-size: 12px; // å¤§å° |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script> |
| | | export default { |
| | | name: 'BaseOpera', |
| | | data () { |
| | | return { |
| | | title: '', |
| | | visible: false, |
| | | isWorking: false, |
| | | // æ¥å£ |
| | | api: null, |
| | | // é
ç½®æ°æ® |
| | | configData: { |
| | | 'field.id': 'id' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // é
ç½® |
| | | config (extParams = {}) { |
| | | if (extParams == null) { |
| | | throw new Error('Parameter can not be null of method \'config\' .') |
| | | } |
| | | if (extParams.api == null) { |
| | | throw new Error('Missing config option \'api\'.') |
| | | } |
| | | this.api = require('@/api' + extParams.api) |
| | | extParams['field.id'] && (this.configData['field.id'] = extParams['field.id']) |
| | | }, |
| | | /** |
| | | * æå¼çªå£ |
| | | * @title çªå£æ é¢ |
| | | * @target ç¼è¾ç对象 |
| | | */ |
| | | open (title, target) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form[this.configData['field.id']] = null |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | }, |
| | | // 确认æ°å»º/ä¿®æ¹ |
| | | confirm () { |
| | | if (this.form.id == null || this.form.id === '') { |
| | | this.__confirmCreate() |
| | | return |
| | | } |
| | | this.__confirmEdit() |
| | | }, |
| | | // 确认æ°å»º |
| | | __confirmCreate () { |
| | | this.$refs.form.validate((valid) => { |
| | | if (!valid) { |
| | | return |
| | | } |
| | | // è°ç¨æ°å»ºæ¥å£ |
| | | this.isWorking = true |
| | | this.api.create(this.form) |
| | | .then(() => { |
| | | this.visible = false |
| | | this.$tip.apiSuccess('æ°å»ºæå') |
| | | this.$emit('success') |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking = false |
| | | }) |
| | | }) |
| | | }, |
| | | // ç¡®è®¤ä¿®æ¹ |
| | | __confirmEdit () { |
| | | this.$refs.form.validate((valid) => { |
| | | if (!valid) { |
| | | return |
| | | } |
| | | // è°ç¨æ°å»ºæ¥å£ |
| | | this.isWorking = true |
| | | this.api.updateById(this.form) |
| | | .then(() => { |
| | | this.visible = false |
| | | this.$tip.apiSuccess('ä¿®æ¹æå') |
| | | this.$emit('success') |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking = false |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | export default { |
| | | name: 'BasePage', |
| | | data () { |
| | | return { |
| | | // è¶
级管çåè§è²code |
| | | adminCode: 'admin' |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapState(['userInfo']), |
| | | // æ¯å¦ä¸ºè¶
级管çå |
| | | isAdmin () { |
| | | return this.userInfo.roles.findIndex(code => code === this.adminCode) > -1 |
| | | } |
| | | }, |
| | | methods: { |
| | | // æ¯å¦å
嫿å®è§è² |
| | | containRoles (roles) { |
| | | if (roles == null) { |
| | | return true |
| | | } |
| | | if (this.userInfo == null) { |
| | | return false |
| | | } |
| | | if (this.userInfo.roles == null || this.userInfo.roles.length === 0) { |
| | | return false |
| | | } |
| | | for (const code of roles) { |
| | | if (this.userInfo.roles.findIndex(r => r === code) > -1) { |
| | | return true |
| | | } |
| | | } |
| | | return false |
| | | }, |
| | | // æ¯å¦å
嫿宿é |
| | | containPermissions (permissions) { |
| | | if (permissions == null) { |
| | | return true |
| | | } |
| | | if (this.userInfo == null) { |
| | | return false |
| | | } |
| | | if (this.userInfo.permissions == null || this.userInfo.permissions.length === 0) { |
| | | return false |
| | | } |
| | | for (const code of permissions) { |
| | | if (this.userInfo.permissions.findIndex(p => p === code) > -1) { |
| | | return true |
| | | } |
| | | } |
| | | return false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script> |
| | | import BasePage from './BasePage' |
| | | export default { |
| | | name: 'BaseTable', |
| | | extends: BasePage, |
| | | data () { |
| | | return { |
| | | // æ¥å£ |
| | | api: null, |
| | | // 模ååç§° |
| | | module: 'æ°æ®', |
| | | // é
ç½®æ°æ® |
| | | configData: { |
| | | // idåæ®µ |
| | | 'field.id': 'id', |
| | | // 䏻忮µ |
| | | 'field.main': 'name' |
| | | }, |
| | | // æ¯å¦æ£å¨æ§è¡ |
| | | isWorking: { |
| | | // æç´¢ä¸ |
| | | search: false, |
| | | // å é¤ä¸ |
| | | delete: false, |
| | | // 导åºä¸ |
| | | export: false |
| | | }, |
| | | // è¡¨æ ¼æ°æ® |
| | | tableData: { |
| | | // å·²éä¸çæ°æ® |
| | | selectedRows: [], |
| | | // æåºçåæ®µ |
| | | sorts: [], |
| | | // å½åé¡µæ°æ® |
| | | list: [], |
| | | // å页 |
| | | pagination: { |
| | | pageIndex: 1, |
| | | pageSize: 10, |
| | | total: 0 |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // é
ç½® |
| | | config (extParams) { |
| | | if (extParams == null) { |
| | | throw new Error('Parameter can not be null of method \'config\' .') |
| | | } |
| | | if (extParams.api == null) { |
| | | throw new Error('Missing config option \'api\'.') |
| | | } |
| | | this.api = require('@/api' + extParams.api) |
| | | extParams.module && (this.module = extParams.module) |
| | | extParams['field.id'] && (this.configData['field.id'] = extParams['field.id']) |
| | | extParams['field.main'] && (this.configData['field.main'] = extParams['field.main']) |
| | | this.tableData.sorts = extParams.sorts |
| | | }, |
| | | // æç´¢ |
| | | search () { |
| | | this.handlePageChange(1) |
| | | }, |
| | | // 导åºExcel |
| | | exportExcel () { |
| | | this.__checkApi() |
| | | this.$dialog.exportConfirm('确认导åºåï¼') |
| | | .then(() => { |
| | | this.isWorking.export = true |
| | | this.api.exportExcel({ |
| | | page: this.tableData.pagination.pageIndex, |
| | | capacity: 1000000, |
| | | model: this.searchForm, |
| | | sorts: this.tableData.sorts |
| | | }) |
| | | .then(response => { |
| | | this.download(response) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.export = false |
| | | }) |
| | | }) |
| | | .catch(() => {}) |
| | | }, |
| | | // æç´¢æ¡éç½® |
| | | reset () { |
| | | this.$refs.searchForm.resetFields() |
| | | this.search() |
| | | }, |
| | | // æ¯é¡µæ¾ç¤ºæ°éåæ´å¤ç |
| | | handleSizeChange (pageSize) { |
| | | this.tableData.pagination.pageSize = pageSize |
| | | this.search() |
| | | }, |
| | | // è¡éä¸å¤ç |
| | | handleSelectionChange (selectedRows) { |
| | | this.tableData.selectedRows = selectedRows |
| | | }, |
| | | // æåº |
| | | handleSortChange (sortData) { |
| | | this.tableData.sorts = [] |
| | | if (sortData.order != null) { |
| | | this.tableData.sorts.push({ |
| | | property: sortData.column.sortBy, |
| | | direction: sortData.order === 'descending' ? 'DESC' : 'ASC' |
| | | }) |
| | | } |
| | | this.handlePageChange() |
| | | }, |
| | | // 页ç åæ´å¤ç |
| | | handlePageChange (pageIndex) { |
| | | this.__checkApi() |
| | | this.tableData.pagination.pageIndex = pageIndex || this.tableData.pagination.pageIndex |
| | | this.isWorking.search = true |
| | | this.api.fetchList({ |
| | | page: this.tableData.pagination.pageIndex, |
| | | capacity: this.tableData.pagination.pageSize, |
| | | model: this.searchForm, |
| | | sorts: this.tableData.sorts |
| | | }) |
| | | .then(data => { |
| | | this.tableData.list = data.records |
| | | this.tableData.pagination.total = data.total |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.search = false |
| | | }) |
| | | }, |
| | | // å é¤ |
| | | deleteById (row, childConfirm = true) { |
| | | this.__checkApi() |
| | | let message = `确认å é¤${this.module}ã${row[this.configData['field.main']]}ãå?` |
| | | if (childConfirm && row.children != null && row.children.length > 0) { |
| | | message = `确认å é¤${this.module}ã${row[this.configData['field.main']]}ãåå
¶å${this.module}å?` |
| | | } |
| | | this.$dialog.deleteConfirm(message) |
| | | .then(() => { |
| | | this.isWorking.delete = true |
| | | this.api.deleteById(row[this.configData['field.id']]) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('å 餿å') |
| | | this.__afterDelete() |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.delete = false |
| | | }) |
| | | }) |
| | | .catch(() => {}) |
| | | }, |
| | | /** |
| | | * æ¹éå é¤ |
| | | * @treeMode æ¯å¦æ·»å åèç¹å é¤ç¡®è®¤ |
| | | */ |
| | | deleteByIdInBatch (childConfirm = true) { |
| | | this.__checkApi() |
| | | if (this.tableData.selectedRows.length === 0) { |
| | | this.$tip.warning('请è³å°éæ©ä¸æ¡æ°æ®') |
| | | return |
| | | } |
| | | let message = `确认å é¤å·²éä¸ç ${this.tableData.selectedRows.length} æ¡${this.module}è®°å½å?` |
| | | if (childConfirm) { |
| | | const containChildrenRows = [] |
| | | for (const row of this.tableData.selectedRows) { |
| | | if (row.children != null && row.children.length > 0) { |
| | | containChildrenRows.push(row[this.configData['field.main']]) |
| | | } |
| | | } |
| | | if (containChildrenRows.length > 0) { |
| | | message = `æ¬æ¬¡å°å é¤${this.module}ã${containChildrenRows.join('ã')}ãåå
¶å${this.module}è®°å½ï¼ç¡®è®¤å é¤åï¼` |
| | | } |
| | | } |
| | | this.$dialog.deleteConfirm(message) |
| | | .then(() => { |
| | | this.isWorking.delete = true |
| | | this.api.deleteByIdInBatch(this.tableData.selectedRows.map(row => row.id).join(',')) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('å 餿å') |
| | | this.__afterDelete(this.tableData.selectedRows.length) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.delete = false |
| | | }) |
| | | }) |
| | | .catch(() => {}) |
| | | }, |
| | | // å é¤å¤ç |
| | | __afterDelete (deleteCount = 1) { |
| | | // å é¤å½å页æå䏿¡è®°å½æ¶æ¥è¯¢ä¸ä¸é¡µæ°æ® |
| | | if (this.tableData.list.length - deleteCount === 0) { |
| | | this.handlePageChange(this.tableData.pagination.pageIndex - 1 === 0 ? 1 : this.tableData.pagination.pageIndex - 1) |
| | | } else { |
| | | this.handlePageChange(this.tableData.pagination.pageIndex) |
| | | } |
| | | }, |
| | | // æ£æ¥æ¥å£æ¯å¦é
ç½® |
| | | __checkApi () { |
| | | if (this.api == null) { |
| | | throw new Error('The page is not initialized, you can use method \'this.config\' to initialize this page.') |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <span v-if="content.length <= limit">{{content}}</span> |
| | | <el-popover |
| | | v-else |
| | | v-model="visible" |
| | | popper-class="eva-column-detail-popover" |
| | | trigger="click" |
| | | > |
| | | <div class="eva-column-detail"> |
| | | <pre class="eva-column-detail__main">{{formattedContent}}</pre> |
| | | <div class="eva-column-detail__action"> |
| | | <el-button size="mini" @click="cancel">å
³é</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | v-clipboard:copy="formattedContent" |
| | | v-clipboard:success="copySuccess" |
| | | v-clipboard:error="copyFailed" |
| | | @click="confirm" |
| | | >{{ confirmButtonText }}</el-button> |
| | | </div> |
| | | </div> |
| | | <el-button slot="reference" :type="buttonType">æ¥ç</el-button> |
| | | </el-popover> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'ColumnDetail', |
| | | props: { |
| | | // æé®ç±»å |
| | | buttonType: { |
| | | type: String |
| | | }, |
| | | // å
容 |
| | | content: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // éå¶ï¼å¤§äºéå¶æ¶å±ç¤ºæ¥çæé® |
| | | limit: { |
| | | type: Number, |
| | | default: 12 |
| | | }, |
| | | // èªå¨è¯å«æ°æ®ç±»åå¹¶æ ¼å¼å |
| | | analyse: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // æ¯å¦å
许å¤å¶ |
| | | allowCopy: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | data () { |
| | | return { |
| | | visible: false |
| | | } |
| | | }, |
| | | computed: { |
| | | // 确认æé®ææ¡ |
| | | confirmButtonText () { |
| | | return this.allowCopy ? 'å¤å¶' : 'ç¡®å®' |
| | | }, |
| | | // æ ¼å¼ååçå
容 |
| | | formattedContent () { |
| | | let content = this.content |
| | | if (this.analyse) { |
| | | try { |
| | | content = JSON.stringify(JSON.parse(this.content), null, 2) |
| | | } catch (e) { |
| | | } |
| | | } |
| | | return content |
| | | } |
| | | }, |
| | | methods: { |
| | | // ç¹å»ç¡®è®¤ |
| | | confirm () { |
| | | this.visible = false |
| | | this.$emit('confirm') |
| | | }, |
| | | // ç¹å»åæ¶ |
| | | cancel () { |
| | | this.visible = false |
| | | this.$emit('cancel') |
| | | }, |
| | | // å¤å¶æå |
| | | copySuccess () { |
| | | this.$tip.success('å¤å¶æå') |
| | | }, |
| | | // å¤å¶å¤±è´¥ |
| | | copyFailed () { |
| | | this.$tip.error('å¤å¶å¤±è´¥') |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .eva-column-detail-popover { |
| | | max-width: 80%; |
| | | } |
| | | </style> |
| | | <style scoped lang="scss"> |
| | | .eva-column-detail { |
| | | .eva-column-detail__main { |
| | | max-height: 500px; |
| | | overflow: auto; |
| | | } |
| | | .eva-column-detail__action { |
| | | text-align: right; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TreeSelect |
| | | :placeholder="placeholder" |
| | | :value="value" |
| | | :data="data" |
| | | :clearable="clearable" |
| | | :append-to-body="appendToBody" |
| | | :inline="inline" |
| | | :multiple="multiple" |
| | | :flat="multiple" |
| | | @input="$emit('input', $event)" |
| | | /> |
| | | </template> |
| | | |
| | | <script> |
| | | import TreeSelect from './TreeSelect' |
| | | import { fetchTree } from '@/api/system/department' |
| | | export default { |
| | | name: 'DepartmentSelect', |
| | | components: { TreeSelect }, |
| | | props: { |
| | | value: {}, |
| | | inline: { |
| | | default: true |
| | | }, |
| | | multiple: { |
| | | default: false |
| | | }, |
| | | placeholder: { |
| | | default: 'è¯·éæ©é¨é¨' |
| | | }, |
| | | // æ¯å¦å¯æ¸
空 |
| | | clearable: { |
| | | default: false |
| | | }, |
| | | appendToBody: { |
| | | default: false |
| | | }, |
| | | // é被æé¤çé¨é¨ID |
| | | excludeId: {} |
| | | }, |
| | | data () { |
| | | return { |
| | | data: [] |
| | | } |
| | | }, |
| | | watch: { |
| | | excludeId () { |
| | | this.fetchData() |
| | | } |
| | | }, |
| | | methods: { |
| | | // è·åææé¨é¨ |
| | | fetchData () { |
| | | fetchTree() |
| | | .then(records => { |
| | | this.data = [] |
| | | this.__fillData(this.data, records) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | }, |
| | | // å¡«å
é¨é¨æ |
| | | __fillData (list, pool) { |
| | | for (const dept of pool) { |
| | | if (dept.id === this.excludeId) { |
| | | continue |
| | | } |
| | | const deptNode = { |
| | | id: dept.id, |
| | | label: dept.name |
| | | } |
| | | list.push(deptNode) |
| | | if (dept.children != null && dept.children.length > 0) { |
| | | deptNode.children = [] |
| | | this.__fillData(deptNode.children, dept.children) |
| | | if (deptNode.children.length === 0) { |
| | | deptNode.children = undefined |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.fetchData() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-drawer |
| | | class="global-window" |
| | | title="title" |
| | | :visible="visible" |
| | | :with-header="true" |
| | | :size="width" |
| | | :close-on-press-escape="false" |
| | | :wrapper-closable="false" |
| | | :append-to-body="true" |
| | | @close="close" |
| | | > |
| | | <div slot="title" class="window__header"> |
| | | <span class="header__btn-back" @click="close"><i class="el-icon-arrow-left"></i></span>{{title}} |
| | | </div> |
| | | <div class="window__body"> |
| | | <slot></slot> |
| | | </div> |
| | | <div v-if="withFooter" class="window__footer"> |
| | | <slot name="footer"> |
| | | <el-button @click="confirm" :loading="confirmWorking" type="primary">ç¡®å®</el-button> |
| | | <el-button @click="close">åæ¶</el-button> |
| | | </slot> |
| | | </div> |
| | | </el-drawer> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'GlobalWindow', |
| | | props: { |
| | | width: { |
| | | type: String, |
| | | default: '36%' |
| | | }, |
| | | // æ¯å¦å
å«åºé¨æä½ |
| | | withFooter: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 确认æé®loadingç¶æ |
| | | confirmWorking: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // æ é¢ |
| | | title: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // æ¯å¦å±ç¤º |
| | | visible: { |
| | | type: Boolean, |
| | | required: true |
| | | } |
| | | }, |
| | | methods: { |
| | | confirm () { |
| | | this.$emit('confirm') |
| | | }, |
| | | close () { |
| | | this.$emit('update:visible', false) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | // è¾å
¥æ¡é«åº¦ |
| | | $input-height: 32px; |
| | | .global-window { |
| | | // 头鍿 é¢ |
| | | /deep/ .el-drawer__header { |
| | | padding: 0 10px 0 0; |
| | | line-height: 40px; |
| | | border-bottom: 1px solid #eee; |
| | | // è¿åæé® |
| | | .header__btn-back { |
| | | display: inline-block; |
| | | width: 30px; |
| | | background: $primary-color; |
| | | color: #fff; |
| | | text-align: center; |
| | | margin-right: 12px; |
| | | border-right: 1px solid #eee; |
| | | } |
| | | .el-drawer__close-btn:focus { |
| | | outline: none; |
| | | } |
| | | } |
| | | // ä¸»ä½ |
| | | /deep/ .el-drawer__body { |
| | | display: flex; |
| | | flex-direction: column; |
| | | position: absolute; |
| | | top: 40px; |
| | | bottom: 0; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | // å
容 |
| | | .window__body { |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | padding: 12px 16px; |
| | | // æ ç¾ |
| | | .el-form-item__label { |
| | | float: none; |
| | | } |
| | | // å
ç´ å®½åº¦ä¸º100% |
| | | .el-form-item__content > *{ |
| | | width: 100%; |
| | | } |
| | | } |
| | | // å°¾é¨ |
| | | .window__footer { |
| | | user-select: none; |
| | | border-top: 1px solid #eee; |
| | | height: 60px; |
| | | line-height: 60px; |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="main-header"> |
| | | <div class="header"> |
| | | <h2> |
| | | <i class="el-icon-s-unfold" v-if="menuData.collapse" @click="switchCollapseMenu(null)"></i> |
| | | <i class="el-icon-s-fold" v-else @click="switchCollapseMenu(null)"></i> |
| | | {{title}} |
| | | </h2> |
| | | <div class="user"> |
| | | <el-dropdown trigger="click"> |
| | | <span class="el-dropdown-link"> |
| | | <img v-if="userInfo != null" :src="userInfo.avatar == null ? '@/assets/images/avatar/man.png' : userInfo.avatar" alt="">{{userInfo | displayName}}<i class="el-icon-arrow-down el-icon--right"></i> |
| | | </span> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <el-dropdown-item @click.native="changePwd">ä¿®æ¹å¯ç </el-dropdown-item> |
| | | <el-dropdown-item @click.native="logout">éåºç»å½</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </div> |
| | | </div> |
| | | <!-- ä¿®æ¹å¯ç --> |
| | | <GlobalWindow |
| | | title="ä¿®æ¹å¯ç " |
| | | :visible.sync="visible.changePwd" |
| | | @confirm="confirmChangePwd" |
| | | @close="visible.changePwd = false" |
| | | > |
| | | <el-form :model="changePwdData.form" ref="changePwdDataForm" :rules="changePwdData.rules"> |
| | | <el-form-item label="åå§å¯ç " prop="oldPwd" required> |
| | | <el-input v-model="changePwdData.form.oldPwd" type="password" placeholder="请è¾å
¥åå§å¯ç " maxlength="30" show-password></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="æ°å¯ç " prop="newPwd" required> |
| | | <el-input v-model="changePwdData.form.newPwd" type="password" placeholder="请è¾å
¥æ°å¯ç " maxlength="30" show-password></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="确认æ°å¯ç " prop="confirmPwd" required> |
| | | <el-input v-model="changePwdData.form.confirmPwd" type="password" placeholder="è¯·åæ¬¡è¾å
¥æ°å¯ç " maxlength="30" show-password></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState, mapMutations } from 'vuex' |
| | | import GlobalWindow from './GlobalWindow' |
| | | import { logout, updatePwd } from '@/api/system/common' |
| | | export default { |
| | | name: 'Header', |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | visible: { |
| | | // ä¿®æ¹å¯ç |
| | | changePwd: false |
| | | }, |
| | | isWorking: { |
| | | // ä¿®æ¹å¯ç |
| | | changePwd: false |
| | | }, |
| | | username: 'bob', // ç¨æ·å |
| | | // ä¿®æ¹å¯ç å¼¹æ¡ |
| | | changePwdData: { |
| | | form: { |
| | | oldPwd: '', |
| | | newPwd: '', |
| | | confirmPwd: '' |
| | | }, |
| | | rules: { |
| | | oldPwd: [ |
| | | { required: true, message: '请è¾å
¥åå§å¯ç ' } |
| | | ], |
| | | newPwd: [ |
| | | { required: true, message: '请è¾å
¥æ°å¯ç ' } |
| | | ], |
| | | confirmPwd: [ |
| | | { required: true, message: 'è¯·åæ¬¡è¾å
¥æ°å¯ç ' } |
| | | ] |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapState(['menuData', 'userInfo']), |
| | | title () { |
| | | return this.$route.meta.title |
| | | } |
| | | }, |
| | | filters: { |
| | | // å±ç¤ºåç§° |
| | | displayName (userInfo) { |
| | | if (userInfo == null) { |
| | | return '' |
| | | } |
| | | if (userInfo.realname != null && userInfo.realname.trim().length > 0) { |
| | | return userInfo.realname |
| | | } |
| | | return userInfo.username |
| | | } |
| | | }, |
| | | methods: { |
| | | ...mapMutations(['setUserInfo', 'switchCollapseMenu']), |
| | | // ä¿®æ¹å¯ç |
| | | changePwd () { |
| | | this.visible.changePwd = true |
| | | this.$nextTick(() => { |
| | | this.$refs.changePwdDataForm.resetFields() |
| | | }) |
| | | }, |
| | | // ç¡®å®ä¿®æ¹å¯ç |
| | | confirmChangePwd () { |
| | | if (this.isWorking.changePwd) { |
| | | return |
| | | } |
| | | this.$refs.changePwdDataForm.validate((valid) => { |
| | | if (!valid) { |
| | | return |
| | | } |
| | | // éªè¯ä¸¤æ¬¡å¯ç è¾å
¥æ¯å¦ä¸è´ |
| | | if (this.changePwdData.form.newPwd !== this.changePwdData.form.confirmPwd) { |
| | | this.$tip.warning('两次å¯ç è¾å
¥ä¸ä¸è´') |
| | | return |
| | | } |
| | | // æ§è¡ä¿®æ¹ |
| | | this.isWorking.changePwd = true |
| | | updatePwd({ |
| | | oldPwd: this.changePwdData.form.oldPwd, |
| | | newPwd: this.changePwdData.form.newPwd |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('ä¿®æ¹æå') |
| | | this.visible.changePwd = false |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.changePwd = false |
| | | }) |
| | | }) |
| | | }, |
| | | // éåºç»å½ |
| | | logout () { |
| | | logout() |
| | | .then(() => { |
| | | this.setUserInfo(null) |
| | | this.$router.push({ name: 'login' }) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .header { |
| | | overflow: hidden; |
| | | padding: 0 25px; |
| | | background: #fff; |
| | | height: 100%; |
| | | display: flex; |
| | | h2 { |
| | | width: 50%; |
| | | flex-shrink: 0; |
| | | line-height: $header-height; |
| | | font-size: 19px; |
| | | font-weight: 600; |
| | | color: #606263; |
| | | display: inline; |
| | | & > i { |
| | | font-size: 20px; |
| | | margin-right: 12px; |
| | | } |
| | | } |
| | | .user { |
| | | width: 50%; |
| | | flex-shrink: 0; |
| | | text-align: right; |
| | | .el-dropdown { |
| | | top: 2px; |
| | | } |
| | | img { |
| | | width: 32px; |
| | | position: relative; |
| | | top: 10px; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | } |
| | | // 䏿èåæ¡ |
| | | .el-dropdown-menu { |
| | | width: 140px; |
| | | .el-dropdown-menu__item:hover { |
| | | background: #E3EDFB; |
| | | color: $primary-color; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="light" :class="{normal: !warn && !danger, warn: !danger && warn, danger, mini: mini}"> |
| | | <em><i></i></em> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'Light', |
| | | props: { |
| | | warn: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | danger: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | mini: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | $cycle-size01: 16px; |
| | | $cycle-size02: 6px; |
| | | $normal-color: #00CC99; |
| | | $warn-color: #FFCC33; |
| | | $danger-color: #FF3300; |
| | | @mixin light-status ($cycle-bg) { |
| | | em { |
| | | background: $cycle-bg; |
| | | i { |
| | | background: $cycle-bg - 30; |
| | | } |
| | | } |
| | | } |
| | | .light { |
| | | display: inline-block; |
| | | border-radius: 50%; |
| | | em { |
| | | width: $cycle-size01; |
| | | height: $cycle-size01; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | i { |
| | | display: block; |
| | | width: $cycle-size02; |
| | | height: $cycle-size02; |
| | | border-radius: 50%; |
| | | } |
| | | } |
| | | &.mini { |
| | | em { |
| | | width: 12px; |
| | | height: 12px; |
| | | } |
| | | } |
| | | // æ£å¸¸ |
| | | &.normal { |
| | | @include light-status($normal-color); |
| | | animation: shine-normal infinite 1s; |
| | | } |
| | | // è¦å |
| | | &.warn { |
| | | @include light-status($warn-color); |
| | | animation: shine-warn infinite .8s; |
| | | } |
| | | // å±é© |
| | | &.danger { |
| | | @include light-status($danger-color); |
| | | animation: shine-danger infinite .5s; |
| | | } |
| | | } |
| | | @keyframes shine-normal { |
| | | 0% { |
| | | box-shadow: 0 0 5px $normal-color + 10; |
| | | } |
| | | 25% { |
| | | box-shadow: 0 0 10px $normal-color + 10; |
| | | } |
| | | 50% { |
| | | box-shadow: 0 0 15px $normal-color + 10; |
| | | } |
| | | 100% { |
| | | box-shadow: 0 0 20px $normal-color + 10; |
| | | } |
| | | } |
| | | @keyframes shine-warn { |
| | | 0% { |
| | | box-shadow: 0 0 5px $warn-color - 50; |
| | | } |
| | | 25% { |
| | | box-shadow: 0 0 10px $warn-color - 50; |
| | | } |
| | | 50% { |
| | | box-shadow: 0 0 15px $warn-color - 50; |
| | | } |
| | | 100% { |
| | | box-shadow: 0 0 20px $warn-color - 50; |
| | | } |
| | | } |
| | | @keyframes shine-danger { |
| | | 0% { |
| | | box-shadow: 0 0 5px $danger-color + 10; |
| | | } |
| | | 25% { |
| | | box-shadow: 0 0 10px $danger-color + 10; |
| | | } |
| | | 50% { |
| | | box-shadow: 0 0 15px $danger-color + 10; |
| | | } |
| | | 100% { |
| | | box-shadow: 0 0 20px $danger-color + 10; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="menu" :class="{collapse: menuData.collapse}"> |
| | | <div class="logo"> |
| | | <div><img src="@/assets/logo.png"></div> |
| | | <h1 :class="{hidden: menuData.collapse}">è±ç±³è·³è·³</h1> |
| | | </div> |
| | | <scrollbar> |
| | | <el-menu |
| | | ref="menu" |
| | | :default-active="activeIndex" |
| | | text-color="#fff" |
| | | active-text-color="#fff" |
| | | :collapse="menuData.collapse" |
| | | :default-openeds="defaultOpeneds" |
| | | :collapse-transition="false" |
| | | @select="handleSelect" |
| | | > |
| | | <MenuItems v-for="menu in menuData.list" :key="menu.index" :menu="menu" :is-root-menu="true"/> |
| | | </el-menu> |
| | | </scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | import MenuItems from './MenuItems' |
| | | import Scrollbar from './Scrollbar' |
| | | export default { |
| | | name: 'Menu', |
| | | components: { Scrollbar, MenuItems }, |
| | | computed: { |
| | | ...mapState(['menuData']), |
| | | // éä¸çèåindex |
| | | activeIndex () { |
| | | let path = this.$route.path |
| | | if (path.endsWith('/')) { |
| | | path = path.substring(0, path.length - 1) |
| | | } |
| | | const menuConfig = this.__getMenuConfig(path, 'url', this.menuData.list) |
| | | if (menuConfig == null) { |
| | | return null |
| | | } |
| | | return menuConfig.index |
| | | }, |
| | | // é»è®¤å±å¼çèåindex |
| | | defaultOpeneds () { |
| | | return this.menuData.list.map(menu => menu.index) |
| | | } |
| | | }, |
| | | methods: { |
| | | // å¤çèåéä¸ |
| | | handleSelect (menuIndex) { |
| | | const menuConfig = this.__getMenuConfig(menuIndex, 'index', this.menuData.list) |
| | | // æ¾ä¸å°é¡µé¢ |
| | | try { |
| | | require('@/views' + menuConfig.url) |
| | | } catch (e) { |
| | | this.$tip.error('æªæ¾å°é¡µé¢æä»¶@/views' + menuConfig.url + '.vueï¼è¯·æ£æ¥èåè·¯å¾æ¯å¦æ£ç¡®') |
| | | } |
| | | // ç¹å»å½åèåä¸åå¤ç |
| | | if (menuConfig.url === this.$route.path) { |
| | | return |
| | | } |
| | | if (menuConfig.url == null || menuConfig.url.trim().length === 0) { |
| | | return |
| | | } |
| | | this.$router.push(menuConfig.url) |
| | | }, |
| | | // è·åèåé
ç½® |
| | | __getMenuConfig (value, key, menus) { |
| | | for (const menu of menus) { |
| | | if (menu[key] === value) { |
| | | return menu |
| | | } |
| | | if (menu.children != null && menu.children.length > 0) { |
| | | const menuConfig = this.__getMenuConfig(value, key, menu.children) |
| | | if (menuConfig != null) { |
| | | return menuConfig |
| | | } |
| | | } |
| | | } |
| | | return null |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "@/assets/style/variables.scss"; |
| | | .menu { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | // LOGO |
| | | .logo { |
| | | height: 60px; |
| | | flex-shrink: 0; |
| | | line-height: 60px; |
| | | overflow: hidden; |
| | | display: flex; |
| | | background: $primary-color - 20; |
| | | padding: 0 16px; |
| | | & > div { |
| | | width: 32px; |
| | | flex-shrink: 0; |
| | | margin-right: 12px; |
| | | img { |
| | | width: 100%; |
| | | flex-shrink: 0; |
| | | vertical-align: middle; |
| | | position: relative; |
| | | top: -2px; |
| | | } |
| | | } |
| | | h1 { |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | transition: opacity ease .3s; |
| | | overflow: hidden; |
| | | &.hidden { |
| | | opacity: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | <style lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | // èåæ ·å¼ |
| | | .el-menu { |
| | | border-right: 0 !important; |
| | | user-select: none; |
| | | background: $primary-color !important; |
| | | .el-menu-item { |
| | | background: $primary-color; |
| | | // éä¸ç¶æ |
| | | &.is-active { |
| | | background: $primary-color - 40 !important; |
| | | } |
| | | // æ¬æµ® |
| | | &:hover { |
| | | background-color: $primary-color - 12; |
| | | } |
| | | &:focus { |
| | | background: $primary-color; |
| | | } |
| | | } |
| | | // åèå |
| | | .el-submenu { |
| | | .el-submenu__title{ |
| | | background-color: $primary-color; |
| | | } |
| | | &.is-active { |
| | | .el-submenu__title{ |
| | | background-color: $primary-color - 20; |
| | | } |
| | | .el-menu .el-menu-item{ |
| | | background-color: $primary-color - 20; |
| | | // æ¬æµ® |
| | | &:hover { |
| | | background-color: $primary-color - 30; |
| | | } |
| | | } |
| | | } |
| | | // èåä¸ä¸ç®å¤´ |
| | | .el-submenu__title i { |
| | | color: #f7f7f7; |
| | | } |
| | | } |
| | | // èå徿 |
| | | i:not(.el-submenu__icon-arrow) { |
| | | color: #f7f7f7 !important; |
| | | position: relative; |
| | | top: -1px; |
| | | // èªå®ä¹å¾æ |
| | | &[class^="eva-icon-"] { |
| | | width: 24px; |
| | | margin-right: 5px; |
| | | background-size: 15px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-menu-item v-if="menu.children == null || menu.children.length == 0" :key="menu.index" :index="menu.index"> |
| | | <i :class="menu.icon"></i> |
| | | <span slot="title">{{menu.label}}</span> |
| | | </el-menu-item> |
| | | <el-submenu v-else :index="menu.index"> |
| | | <template slot="title"> |
| | | <i :class="menu.icon"></i> |
| | | <span slot="title">{{menu.label}}</span> |
| | | </template> |
| | | <MenuItems v-for="child in menu.children" :menu="child" :key="child.index"/> |
| | | </el-submenu> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'MenuItems', |
| | | props: { |
| | | menu: { |
| | | type: Object, |
| | | required: true |
| | | } |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TreeSelect |
| | | :placeholder="placeholder" |
| | | :value="value" |
| | | :data="data" |
| | | :append-to-body="appendToBody" |
| | | :clearable="clearable" |
| | | :inline="inline" |
| | | @input="$emit('input', $event)" |
| | | /> |
| | | </template> |
| | | |
| | | <script> |
| | | import TreeSelect from './TreeSelect' |
| | | import { fetchTree } from '@/api/system/menu' |
| | | export default { |
| | | name: 'MenuSelect', |
| | | components: { TreeSelect }, |
| | | props: { |
| | | value: {}, |
| | | inline: { |
| | | default: true |
| | | }, |
| | | placeholder: { |
| | | default: 'è¯·éæ©èå' |
| | | }, |
| | | // æ¯å¦å¯æ¸
空 |
| | | clearable: { |
| | | default: false |
| | | }, |
| | | appendToBody: { |
| | | default: false |
| | | }, |
| | | // é被æé¤çé¨é¨ID |
| | | excludeId: {} |
| | | }, |
| | | data () { |
| | | return { |
| | | data: [] |
| | | } |
| | | }, |
| | | watch: { |
| | | excludeId () { |
| | | this.fetchData() |
| | | } |
| | | }, |
| | | methods: { |
| | | // è·åææèå |
| | | fetchData () { |
| | | fetchTree() |
| | | .then(records => { |
| | | this.data = [] |
| | | this.__fillData(this.data, records) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | }, |
| | | // å¡«å
èåæ |
| | | __fillData (list, pool) { |
| | | for (const menu of pool) { |
| | | if (menu.id === this.excludeId) { |
| | | continue |
| | | } |
| | | const menuNode = { |
| | | id: menu.id, |
| | | label: menu.name |
| | | } |
| | | list.push(menuNode) |
| | | if (menu.children != null && menu.children.length > 0) { |
| | | menuNode.children = [] |
| | | this.__fillData(menuNode.children, menu.children) |
| | | if (menuNode.children.length === 0) { |
| | | menuNode.children = undefined |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.fetchData() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="not-allow"> |
| | | <slot> |
| | | <div class="content"> |
| | | <img src="../../assets/images/not-allow.png"> |
| | | <h2>æ æè®¿é®</h2> |
| | | <p>妿¨éè¦è®¿é®è¯¥é¡µé¢ï¼è¯·è系系ç»ç®¡çå</p> |
| | | </div> |
| | | </slot> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'NotAllow' |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .not-allow { |
| | | height: 100%; |
| | | background: #fff; |
| | | box-sizing: border-box; |
| | | padding-top: 160px; |
| | | .content { |
| | | height: 200px; |
| | | text-align: center; |
| | | h2 { |
| | | font-size: 18px; |
| | | font-weight: normal; |
| | | margin-top: 8px; |
| | | } |
| | | p { |
| | | font-size: 13px; |
| | | color: #999; |
| | | margin: 6px 0; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="table-pagination"> |
| | | <el-pagination |
| | | :current-page="pagination.pageIndex" |
| | | :page-sizes="[10, 20, 30, 40]" |
| | | :page-size="pagination.pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="pagination.total" |
| | | @size-change="sizeChange" |
| | | @current-change="currentChange" |
| | | background> |
| | | </el-pagination> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'Pagination', |
| | | props: { |
| | | pagination: { |
| | | type: Object, |
| | | default: function () { |
| | | return {} |
| | | } |
| | | } |
| | | }, |
| | | data () { |
| | | return { |
| | | } |
| | | }, |
| | | methods: { |
| | | sizeChange (value) { |
| | | this.$emit('size-change', value) |
| | | }, |
| | | currentChange (value) { |
| | | this.$emit('current-change', value) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TreeSelect |
| | | :placeholder="placeholder" |
| | | :value="value" |
| | | :data="data" |
| | | :clearable="clearable" |
| | | :append-to-body="appendToBody" |
| | | :inline="inline" |
| | | :multiple="multiple" |
| | | :flat="multiple" |
| | | @input="$emit('input', $event)" |
| | | /> |
| | | </template> |
| | | |
| | | <script> |
| | | import TreeSelect from './TreeSelect' |
| | | import { fetchTree } from '@/api/system/position' |
| | | export default { |
| | | name: 'PositionSelect', |
| | | components: { TreeSelect }, |
| | | props: { |
| | | value: {}, |
| | | inline: { |
| | | default: true |
| | | }, |
| | | multiple: { |
| | | default: false |
| | | }, |
| | | placeholder: { |
| | | default: 'è¯·éæ©å²ä½' |
| | | }, |
| | | // æ¯å¦å¯æ¸
空 |
| | | clearable: { |
| | | default: false |
| | | }, |
| | | appendToBody: { |
| | | default: false |
| | | }, |
| | | // é被æé¤çé¨é¨ID |
| | | excludeId: {} |
| | | }, |
| | | data () { |
| | | return { |
| | | data: [] |
| | | } |
| | | }, |
| | | watch: { |
| | | excludeId () { |
| | | this.fetchData() |
| | | } |
| | | }, |
| | | methods: { |
| | | // è·åææå²ä½ |
| | | fetchData () { |
| | | fetchTree() |
| | | .then(records => { |
| | | this.data = [] |
| | | this.__fillData(this.data, records) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | }, |
| | | // å¡«å
å²ä½æ |
| | | __fillData (list, pool) { |
| | | for (const dept of pool) { |
| | | if (dept.id === this.excludeId) { |
| | | continue |
| | | } |
| | | const deptNode = { |
| | | id: dept.id, |
| | | label: dept.name |
| | | } |
| | | list.push(deptNode) |
| | | if (dept.children != null && dept.children.length > 0) { |
| | | deptNode.children = [] |
| | | this.__fillData(deptNode.children, dept.children) |
| | | if (deptNode.children.length === 0) { |
| | | deptNode.children = undefined |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.fetchData() |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .inline { |
| | | width: 178px; |
| | | } |
| | | .vue-treeselect { |
| | | line-height: 30px; |
| | | /deep/ .vue-treeselect__control { |
| | | height: 32px; |
| | | .vue-treeselect__single-value { |
| | | line-height: 30px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div v-if="containRoles(roles) && containPermissions(permissions)"> |
| | | <slot></slot> |
| | | </div> |
| | | <div v-else class="not-allow-wrap"> |
| | | <slot name="not-allow"><NotAllow/></slot> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import BasePage from '@/components/base/BasePage' |
| | | import NotAllow from './NotAllow' |
| | | export default { |
| | | name: 'Profile', |
| | | components: { NotAllow }, |
| | | extends: BasePage, |
| | | props: { |
| | | permissions: { |
| | | type: Array |
| | | }, |
| | | roles: { |
| | | type: Array |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .not-allow-wrap { |
| | | height: 100%; |
| | | padding: 10px 16px; |
| | | box-sizing: border-box; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <vue-scroll :ops="options"> |
| | | <slot></slot> |
| | | </vue-scroll> |
| | | </template> |
| | | |
| | | <script> |
| | | import VueScroll from 'vuescroll' |
| | | export default { |
| | | name: 'Scrollbar', |
| | | components: { VueScroll }, |
| | | data () { |
| | | return { |
| | | options: { |
| | | bar: { |
| | | background: 'rgba(20,20,20,.3)' |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="search-form-collapse" :class="{'collapse__hidden': !showMore}"> |
| | | <slot></slot> |
| | | <el-button v-if="!showMore" class="collapse__switch" @click="showMore = true">æ´å¤æ¥è¯¢...</el-button> |
| | | <el-button v-else class="collapse__switch" @click="showMore = false">æ¶èµ·</el-button> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'SearchFormCollapse', |
| | | data () { |
| | | return { |
| | | showMore: false |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .search-form-collapse { |
| | | position: relative; |
| | | padding-right: 75px; |
| | | height: auto; |
| | | .collapse__switch { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | } |
| | | &.collapse__hidden { |
| | | height: 50px; |
| | | overflow: hidden; |
| | | padding-right: 250px; |
| | | /deep/ section { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 100px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- ç»ä»¶è¯¦æ
请åé
宿¹ææ¡£ï¼https://www.vue-treeselect.cn/ --> |
| | | <template> |
| | | <vue-tree-select |
| | | :class="{inline}" |
| | | :placeholder="placeholder" |
| | | :value="value" |
| | | :options="data" |
| | | :clearable="clearable" |
| | | :flat="flat" |
| | | :append-to-body="appendToBody" |
| | | :multiple="multiple" |
| | | no-children-text="æ è®°å½" |
| | | no-options-text="æ è®°å½" |
| | | no-results-text="æªå¹é
å°æ°æ®" |
| | | @input="$emit('input', $event)" |
| | | /> |
| | | </template> |
| | | |
| | | <script> |
| | | import VueTreeSelect from '@riophae/vue-treeselect' |
| | | import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
| | | export default { |
| | | name: 'TreeSelect', |
| | | props: { |
| | | inline: { |
| | | default: false |
| | | }, |
| | | multiple: { |
| | | default: false |
| | | }, |
| | | flat: { |
| | | default: false |
| | | }, |
| | | value: {}, |
| | | placeholder: { |
| | | default: 'è¯·éæ©' |
| | | }, |
| | | // æ¯å¦å¯æ¸
空 |
| | | clearable: { |
| | | default: false |
| | | }, |
| | | data: { |
| | | type: Array, |
| | | required: true |
| | | }, |
| | | appendToBody: { |
| | | default: false |
| | | } |
| | | }, |
| | | components: { VueTreeSelect } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .inline { |
| | | width: 178px; |
| | | } |
| | | .vue-treeselect { |
| | | line-height: 30px; |
| | | /deep/ .vue-treeselect__control { |
| | | height: 32px; |
| | | .vue-treeselect__single-value { |
| | | line-height: 30px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="value"> |
| | | <i class="el-icon-loading" v-if="data == null"></i> |
| | | <slot v-else>{{getValue()}}{{suffix}}</slot> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'Value', |
| | | props: { |
| | | data: { |
| | | type: Object |
| | | }, |
| | | prop: { |
| | | type: String |
| | | }, |
| | | suffix: { |
| | | type: String |
| | | }, |
| | | handler: { |
| | | type: Function |
| | | } |
| | | }, |
| | | methods: { |
| | | getValue () { |
| | | if (this.data == null) { |
| | | return '' |
| | | } |
| | | if (this.prop == null) { |
| | | return this.data |
| | | } |
| | | const props = this.prop.split('.') |
| | | let i = 0 |
| | | let value = this.data |
| | | while (i < props.length) { |
| | | value = value[props[i]] |
| | | i++ |
| | | } |
| | | if (this.handler == null) { |
| | | return value |
| | | } |
| | | return this.handler(value) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .value { |
| | | word-break: break-all; |
| | | .el-icon-loading { |
| | | font-size: 16px; |
| | | color: #999; |
| | | position: relative; |
| | | top: 1px; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <component :is="component" :value="values" :inline="false" @input="handleInput" multiple/> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'CustomSelect', |
| | | props: { |
| | | value: {}, |
| | | businessCode: { |
| | | type: String, |
| | | required: true |
| | | } |
| | | }, |
| | | computed: { |
| | | // vuetreeselectå¼ç±»åå¹é
ï¼è§£å³ç¼è¾æ¶æ æ³å é¤å·²æå¼çBUGï¼ |
| | | values () { |
| | | if (this.businessCode === 'DEPARTMENT' || this.businessCode === 'POSITION') { |
| | | const values = [] |
| | | for (const id of this.value) { |
| | | values.push(parseInt(id)) |
| | | } |
| | | return values |
| | | } |
| | | return this.value |
| | | }, |
| | | component () { |
| | | // é¨é¨éæ©å¨ |
| | | if (this.businessCode === 'DEPARTMENT') { |
| | | return () => import('@/components/common/DepartmentSelect') |
| | | } |
| | | // å²ä½éæ©å¨ |
| | | if (this.businessCode === 'POSITION') { |
| | | return () => import('@/components/common/PositionSelect') |
| | | } |
| | | return null |
| | | } |
| | | }, |
| | | methods: { |
| | | handleInput (value) { |
| | | this.$emit('input', value) |
| | | this.$emit('change', value) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-select |
| | | class="data-perm-module-select" |
| | | :class="{select__block: !inline}" |
| | | :value="value" |
| | | :placeholder="placeholder" |
| | | :clearable="clearable" |
| | | :disabled="disabled" |
| | | @change="$emit('change', $event)" |
| | | @input="$emit('input', $event)" |
| | | > |
| | | <el-option v-for="module in modules" :key="module.businessCode" :value="module.businessCode" :label="module.moduleName"/> |
| | | </el-select> |
| | | </template> |
| | | |
| | | <script> |
| | | import { fetchModules } from '@/api/system/dataPermission' |
| | | export default { |
| | | name: 'DataPermModuleSelect', |
| | | props: { |
| | | value: {}, |
| | | placeholder: { |
| | | default: 'è¯·éæ©æé模å' |
| | | }, |
| | | inline: { |
| | | default: true |
| | | }, |
| | | disabled: {}, |
| | | clearable: { |
| | | default: false |
| | | } |
| | | }, |
| | | data () { |
| | | return { |
| | | modules: [] |
| | | } |
| | | }, |
| | | created () { |
| | | fetchModules() |
| | | .cache() |
| | | .then(data => { |
| | | this.modules = data |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .select__block { |
| | | display: block; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-select |
| | | class="data-perm-type-select" |
| | | :class="{select__block: !inline}" |
| | | :value="value" |
| | | :placeholder="placeholder" |
| | | :clearable="clearable" |
| | | :disabled="disabled" |
| | | @change="$emit('change', $event)" |
| | | @input="$emit('input', $event)" |
| | | > |
| | | <el-option v-for="type in filterTypes" :key="type.code" :value="type.code" :label="type.remark"/> |
| | | </el-select> |
| | | </template> |
| | | |
| | | <script> |
| | | import { fetchTypes } from '@/api/system/dataPermission' |
| | | export default { |
| | | name: 'DataPermTypeSelect', |
| | | props: { |
| | | value: {}, |
| | | // 模ååç§° |
| | | module: {}, |
| | | placeholder: { |
| | | default: 'è¯·éæ©æéç±»å' |
| | | }, |
| | | inline: { |
| | | default: true |
| | | }, |
| | | disabled: {}, |
| | | clearable: { |
| | | default: false |
| | | } |
| | | }, |
| | | data () { |
| | | return { |
| | | types: [] |
| | | } |
| | | }, |
| | | computed: { |
| | | filterTypes () { |
| | | if (this.module == null || this.module === '') { |
| | | return [] |
| | | } |
| | | const types = [] |
| | | for (const type of this.types) { |
| | | if (type.modules.length === 0 || type.modules.indexOf(this.module) !== -1) { |
| | | types.push(type) |
| | | } |
| | | } |
| | | return types |
| | | } |
| | | }, |
| | | created () { |
| | | fetchTypes() |
| | | .cache() |
| | | .then(data => { |
| | | this.types = data |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .select__block { |
| | | display: block; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="ä¸å¡æ¨¡å" prop="businessCode" required> |
| | | <DataPermModuleSelect v-model="form.businessCode" :disabled="form.id != null" :inline="false" @change="handleBusinessChange"/> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²" prop="roleId" required> |
| | | <RoleSelect v-model="form.roleId" :disabled="form.id != null" :inline="false"/> |
| | | </el-form-item> |
| | | <el-form-item label="æéç±»å" prop="type" required> |
| | | <DataPermTypeSelect v-model="form.type" :module="form.businessCode" :inline="false" @change="handleTypeChange"/> |
| | | </el-form-item> |
| | | <el-form-item v-show="showCustomData" label="èªå®ä¹æ°æ®" prop="customData"> |
| | | <CustomSelect v-if="visible" v-model="customData" :business-code="form.businessCode" @change="handleCustomDataChange"/> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input type="textarea" v-model="form.remark" placeholder="请è¾å
¥å¤æ³¨" v-trim :rows="3" maxlength="500"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import RoleSelect from '@/components/system/role/RoleSelect' |
| | | import DataPermModuleSelect from './DataPermModuleSelect' |
| | | import DataPermTypeSelect from './DataPermTypeSelect' |
| | | import CustomSelect from './CustomSelect' |
| | | export default { |
| | | name: 'OperaDataPermissionWindow', |
| | | extends: BaseOpera, |
| | | components: { CustomSelect, RoleSelect, DataPermTypeSelect, DataPermModuleSelect, GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // èªå®ä¹æ°æ® |
| | | customData: [], |
| | | // å±ç¤ºèªå®ä¹æ°æ®æ è¯ |
| | | showCustomData: false, |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | businessCode: '', |
| | | roleId: '', |
| | | type: '', |
| | | remark: '', |
| | | customData: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | businessCode: [ |
| | | { required: true, message: 'è¯·éæ©ä¸å¡æ¨¡å' } |
| | | ], |
| | | roleId: [ |
| | | { required: true, message: 'è¯·éæ©è§è²' } |
| | | ], |
| | | type: [ |
| | | { required: true, message: 'è¯·éæ©æéç±»å' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @title çªå£æ é¢ |
| | | * @target ç¼è¾ç对象 |
| | | */ |
| | | open (title, target) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.$nextTick(() => { |
| | | this.customData = [] |
| | | this.showCustomData = false |
| | | this.$refs.form.resetFields() |
| | | this.form[this.configData['field.id']] = null |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | this.customData = this.form.customData == null || this.form.customData === '' ? [] : this.form.customData.split(',') |
| | | this.handleTypeChange() |
| | | }) |
| | | }, |
| | | // ä¸å¡æ¨¡å忢 |
| | | handleBusinessChange () { |
| | | this.form.customData = '' |
| | | this.customData = [] |
| | | this.handleTypeChange() |
| | | }, |
| | | // æéç±»å忢 |
| | | handleTypeChange () { |
| | | if ((this.form.type === 11 || this.form.type === 21) && this.form.businessCode != null && this.form.businessCode !== '') { |
| | | this.showCustomData = true |
| | | } else { |
| | | this.showCustomData = false |
| | | } |
| | | }, |
| | | // èªå®ä¹æ°æ®åå |
| | | handleCustomDataChange (values) { |
| | | this.form.customData = values.join(',') |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/dataPermission', |
| | | 'field.id': 'id' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | class="position-user-window" |
| | | width="80%" |
| | | :title="departmentName + '人åå表'" |
| | | :visible.sync="visible" |
| | | :with-footer="false" |
| | | > |
| | | <TableLayout :with-breadcrumb="false"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="80px" inline> |
| | | <el-form-item label="ç¨æ·å" prop="username"> |
| | | <el-input v-model="searchForm.username" placeholder="请è¾å
¥ç¨æ·å" v-trim @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="å§å" prop="realname"> |
| | | <el-input v-model="searchForm.realname" placeholder="请è¾å
¥å§å" v-trim @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="mobile"> |
| | | <el-input v-model="searchForm.mobile" placeholder="请è¾å
¥ææºå·ç " v-trim @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" icon="el-icon-search" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <div slot="space" class="toolbar"> |
| | | <el-switch v-model="onlyCurrentDept" @change="search" :disabled="isWorking.search"/> |
| | | <label>ä»
æ¥çå½åé¨é¨äººå</label> |
| | | </div> |
| | | <template v-slot:table-wrap> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column prop="avatar" label="头å" width="80px" class-name="table-column-avatar" fixed="left"> |
| | | <template slot-scope="{row}"> |
| | | <img :src="row.avatar == null ? '/static/avatar/man.png' : row.avatar"> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="realname" label="å§å" min-width="100px" fixed="left"></el-table-column> |
| | | <el-table-column prop="username" label="ç¨æ·å" min-width="100px"></el-table-column> |
| | | <el-table-column prop="empNo" label="å·¥å·" min-width="80px"></el-table-column> |
| | | <el-table-column prop="department" label="é¨é¨" min-width="120px"> |
| | | <template slot-scope="{row}">{{row.department == null ? '' : row.department.name}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="position" label="å²ä½" min-width="120px" class-name="table-column-strings"> |
| | | <template slot-scope="{row}"> |
| | | <ul> |
| | | <li v-for="position in row.positions" :key="position.id">{{position.name}}</li> |
| | | </ul> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="sex" label="æ§å«" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.sex | sex}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="mobile" label="ææºå·ç " min-width="100px"></el-table-column> |
| | | <el-table-column prop="email" label="é®ç®±" min-width="180px"></el-table-column> |
| | | <el-table-column prop="birthday" label="çæ¥" min-width="100px"></el-table-column> |
| | | <el-table-column prop="birthday" label="è§è²" min-width="160px" class-name="table-column-role"> |
| | | <template slot-scope="{row}"> |
| | | <ul> |
| | | <li v-for="role in row.roles" :key="role.id">{{role.name}}</li> |
| | | </ul> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | </TableLayout> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import Pagination from '@/components/common/Pagination' |
| | | import { fetchUserList } from '@/api/system/department' |
| | | export default { |
| | | name: 'DepartmentUserWindow', |
| | | extends: BaseTable, |
| | | components: { Pagination, GlobalWindow, TableLayout }, |
| | | data () { |
| | | return { |
| | | departmentId: null, |
| | | departmentName: '', |
| | | visible: false, |
| | | // ä»
æ¥çå½åé¨é¨ |
| | | onlyCurrentDept: true, |
| | | // æç´¢è¡¨å |
| | | searchForm: { |
| | | departmentId: null, |
| | | username: '', |
| | | realname: '', |
| | | mobile: '' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // æå¼æ¥ç人åçªå£ |
| | | open (departmentId, departmentName) { |
| | | this.departmentId = departmentId |
| | | this.departmentName = departmentName |
| | | this.searchForm.departmentId = departmentId |
| | | this.visible = true |
| | | this.search() |
| | | }, |
| | | // å¤çå页 |
| | | handlePageChange (pageIndex) { |
| | | // ä»
æ¥çå½åé¨é¨å¤ç |
| | | this.searchForm.strictDeptId = null |
| | | this.searchForm.rootDeptId = this.searchForm.departmentId |
| | | if (this.onlyCurrentDept) { |
| | | this.searchForm.strictDeptId = this.searchForm.departmentId |
| | | this.searchForm.rootDeptId = null |
| | | } |
| | | this.tableData.pagination.pageIndex = pageIndex |
| | | this.isWorking.search = true |
| | | fetchUserList({ |
| | | page: pageIndex, |
| | | capacity: this.tableData.pagination.pageSize, |
| | | model: this.searchForm |
| | | }) |
| | | .then(data => { |
| | | this.tableData.list = data.records |
| | | this.tableData.pagination.total = data.total |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.search = false |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .position-user-window { |
| | | /deep/ .table-search-form { |
| | | padding: 0; |
| | | } |
| | | /deep/ .window__body { |
| | | background: #f7f7f7; |
| | | .table-content { |
| | | padding: 0; |
| | | .table-wrap { |
| | | padding: 0; |
| | | } |
| | | } |
| | | } |
| | | .toolbar { |
| | | margin-top: 10px; |
| | | padding: 6px 12px; |
| | | background: #fff; |
| | | font-size: 13px; |
| | | label { |
| | | margin-left: 8px; |
| | | vertical-align: middle; |
| | | color: #999; |
| | | } |
| | | } |
| | | // å表头åå¤ç |
| | | .table-column-avatar { |
| | | img { |
| | | width: 48px; |
| | | } |
| | | } |
| | | // å表è§è²å¤ç |
| | | .table-column-role { |
| | | ul { |
| | | li { |
| | | display: inline-block; |
| | | background: #eee; |
| | | border-radius: 3px; |
| | | padding: 0 3px; |
| | | margin-right: 3px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="ä¸çº§é¨é¨" prop="parentId"> |
| | | <DepartmentSelect v-if="visible" ref="departmentSelect" placeholder="è¯·éæ©ä¸çº§é¨é¨" v-model="form.parentId" :exclude-id="excludeDeptId" :inline="false"/> |
| | | </el-form-item> |
| | | <el-form-item label="é¨é¨ç¼ç " prop="code" required> |
| | | <el-input v-model="form.code" placeholder="请è¾å
¥é¨é¨ç¼ç " v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="é¨é¨åç§°" prop="name" required> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥é¨é¨åç§°" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" v-trim maxlength="11"/> |
| | | </el-form-item> |
| | | <el-form-item label="é¨é¨é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥é¨é¨é®ç®±" v-trim maxlength="200"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import DepartmentSelect from '@/components/common/DepartmentSelect' |
| | | import { checkMobile, checkEmail } from '@/utils/form' |
| | | export default { |
| | | name: 'OperaDepartmentWindow', |
| | | extends: BaseOpera, |
| | | components: { DepartmentSelect, GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // éæé¤éæ©çé¨é¨ID |
| | | excludeDeptId: null, |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | parentId: null, |
| | | code: '', |
| | | name: '', |
| | | phone: '', |
| | | email: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | code: [ |
| | | { required: true, message: '请è¾å
¥é¨é¨ç¼ç ' } |
| | | ], |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥é¨é¨åç§°' } |
| | | ], |
| | | phone: [ |
| | | { validator: checkMobile } |
| | | ], |
| | | email: [ |
| | | { validator: checkEmail } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @title çªå£æ é¢ |
| | | * @target ç¼è¾çé¨é¨å¯¹è±¡ |
| | | * @parent æ°å»ºæ¶çä¸çº§é¨é¨å¯¹è±¡ |
| | | * @departmentList é¨é¨å表 |
| | | */ |
| | | open (title, target, parent) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.excludeDeptId = null |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form.id = null |
| | | this.form.parentId = parent == null ? null : parent.id |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | this.excludeDeptId = target.id |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/department' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="dictName + 'æ°æ®ç®¡ç'" |
| | | width="78%" |
| | | :visible.sync="visible" |
| | | :with-footer="false" |
| | | > |
| | | <TableLayout :with-breadcrumb="false"> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar"> |
| | | <li><el-button type="primary" @click="$refs.operaDictDataWindow.open('æ°å»ºåå
¸æ°æ®', searchForm.dictId)" icon="el-icon-plus">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | | <el-table-column prop="label" label="æ°æ®æ ç¾" min-width="100px"></el-table-column> |
| | | <el-table-column prop="code" label="æ°æ®å¼" min-width="100px"></el-table-column> |
| | | <el-table-column prop="disabled" label="ç¶æ" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.disabled | disabledText}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="100px"></el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="100px"></el-table-column> |
| | | <el-table-column |
| | | label="æä½" |
| | | min-width="120" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button type="text" @click="$refs.operaDictDataWindow.open('ç¼è¾åå
¸æ°æ®', dictId, row)" icon="el-icon-edit">ç¼è¾</el-button> |
| | | <el-button type="text" @click="deleteById(row)" icon="el-icon-delete">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaDictDataWindow ref="operaDictDataWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | </TableLayout> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import Pagination from '@/components/common/Pagination' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import OperaDictDataWindow from './OperaDictDataWindow' |
| | | export default { |
| | | name: 'DictDataManagerWindow', |
| | | extends: BaseTable, |
| | | components: { OperaDictDataWindow, TableLayout, GlobalWindow, Pagination }, |
| | | data () { |
| | | return { |
| | | visible: false, |
| | | searchForm: { |
| | | // åå
¸ID |
| | | dictId: null |
| | | }, |
| | | // åå
¸åç§° |
| | | dictName: '' |
| | | } |
| | | }, |
| | | methods: { |
| | | // æå¼æ°æ®ç®¡ç |
| | | open (dictId, dictName) { |
| | | this.searchForm.dictId = dictId |
| | | this.dictName = dictName |
| | | this.visible = true |
| | | this.search() |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/dictData', |
| | | 'field.main': 'label' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | /deep/ .window__body { |
| | | .table-content { |
| | | padding: 0; |
| | | .table-wrap { |
| | | padding-top: 0; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking.create" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="æ°æ®æ ç¾" prop="label" required> |
| | | <el-input v-model="form.label" placeholder="请è¾å
¥æ°æ®æ ç¾" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®å¼" prop="code" required> |
| | | <el-input v-model="form.code" placeholder="请è¾å
¥æ°æ®å¼" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="disabled" required class="form-item-status"> |
| | | <el-switch v-model="form.disabled" :active-value="false" :inactive-value="true"/> |
| | | <span class="status-text">{{form.disabled | disabledText}}</span> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | export default { |
| | | name: 'OperaDictDataWindow', |
| | | extends: BaseOpera, |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | dictId: null, |
| | | code: '', |
| | | label: '', |
| | | disabled: false |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | label: [ |
| | | { required: true, message: '请è¾å
¥æ°æ®æ ç¾' } |
| | | ], |
| | | code: [ |
| | | { required: true, message: '请è¾å
¥æ°æ®å¼' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @title çªå£æ é¢ |
| | | * @dict æå±åå
¸ID |
| | | * @target ç¼è¾çåå
¸æ°æ®å¯¹è±¡ |
| | | */ |
| | | open (title, dictId, target) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form.id = null |
| | | this.form.dictId = dictId |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/dictData' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .form-item-status { |
| | | .status-text { |
| | | color: #999; |
| | | margin-left: 6px; |
| | | font-size: 13px; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="åå
¸ç¼ç " prop="code" required> |
| | | <el-input v-model="form.code" placeholder="请è¾å
¥åå
¸ç¼ç " v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸åç§°" prop="name" required> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥åå
¸åç§°" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å¤æ³¨" :rows="3" v-trim maxlength="500"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | export default { |
| | | name: 'OperaDictWindow', |
| | | extends: BaseOpera, |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | code: '', |
| | | name: '', |
| | | remark: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | code: [ |
| | | { required: true, message: '请è¾å
¥åå
¸ç¼ç ' } |
| | | ], |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥åå
¸åç§°' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/dict' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | class="handle-table-dialog" |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <p class="tip" v-if="form.parent != null && form.id == null">为 <em>{{parentName}}</em> æ°å»ºåèå</p> |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="ä¸çº§èå" prop="parentId"> |
| | | <MenuSelect v-if="visible" v-model="form.parentId" placeholder="è¯·éæ©ä¸çº§èå" :exclude-id="excludeMenuId" clearable :inline="false"/> |
| | | </el-form-item> |
| | | <el-form-item label="èååç§°" prop="name" required> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥èååç§°" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="访é®è·¯å¾" prop="path"> |
| | | <el-input v-model="form.path" placeholder="请è¾å
¥è®¿é®è·¯å¾" v-trim maxlength="200"/> |
| | | </el-form-item> |
| | | <el-form-item label="徿 " prop="icon" class="form-item-icon"> |
| | | <el-radio-group v-model="form.icon"> |
| | | <el-radio :label="icon" v-for="icon in icons" :key="icon"> |
| | | <i :class="{[icon]: true}"></i> |
| | | </el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input type="textarea" v-model="form.remark" placeholder="请è¾å
¥èå夿³¨" v-trim :rows="3" maxlength="500"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import MenuSelect from '@/components/common/MenuSelect' |
| | | import icons from '@/utils/icons' |
| | | export default { |
| | | name: 'OperaMenuWindow', |
| | | extends: BaseOpera, |
| | | components: { MenuSelect, GlobalWindow }, |
| | | data () { |
| | | return { |
| | | icons, |
| | | // ä¸çº§èååç§° |
| | | parentName: '', |
| | | // éæé¤éæ©çèåID |
| | | excludeMenuId: null, |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | parentId: null, |
| | | name: '', |
| | | path: '', |
| | | icon: '', |
| | | remark: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥èååç§°' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @title: çªå£æ é¢ |
| | | * @target: ç¼è¾çèå对象 |
| | | * @parent: æ°å»ºæ¶çä¸çº§èå |
| | | */ |
| | | open (title, target, parent) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»ºï¼menu为空æ¶è¡¨ç¤ºæ°å»ºèå |
| | | if (target == null) { |
| | | this.excludeMenuId = null |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form.id = null |
| | | this.form.parentId = parent == null ? null : parent.id |
| | | this.parentName = parent == null ? null : parent.name |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | this.excludeMenuId = target.id |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/menu' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables"; |
| | | $icon-background-color: $primary-color; |
| | | .global-window { |
| | | .tip { |
| | | margin-bottom: 12px; |
| | | em { |
| | | font-style: normal; |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | // 徿 |
| | | /deep/ .form-item-icon { |
| | | .el-form-item__content { |
| | | height: 193px; |
| | | overflow-y: auto; |
| | | } |
| | | .el-radio-group { |
| | | background: $icon-background-color; |
| | | padding: 4px; |
| | | .el-radio { |
| | | margin-right: 0; |
| | | color: #fff; |
| | | padding: 6px; |
| | | &.is-checked { |
| | | background: $icon-background-color - 30; |
| | | border-radius: 10px; |
| | | } |
| | | .el-radio__input.is-checked + .el-radio__label { |
| | | color: #fff; |
| | | } |
| | | } |
| | | .el-radio__input { |
| | | display: none; |
| | | } |
| | | .el-radio__label { |
| | | padding-left: 0; |
| | | // element-ui徿 |
| | | i { |
| | | font-size: 30px; |
| | | } |
| | | // èªå®ä¹å¾æ |
| | | [class^="eva-icon-"], [class*=" eva-icon-"] { |
| | | width: 30px; |
| | | height: 30px; |
| | | background-size: 25px; |
| | | vertical-align: bottom; |
| | | } |
| | | } |
| | | .el-radio--small { |
| | | height: auto; |
| | | padding: 8px; |
| | | margin-left: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="æéç¼ç " prop="code" required> |
| | | <el-input v-model="form.code" placeholder="请è¾å
¥æéç¼ç " v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="æéåç§°" prop="name" required> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥æéåç§°" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="æé夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" placeholder="请è¾å
¥æé夿³¨" type="textarea" :rows="3" v-trim maxlength="500"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | export default { |
| | | name: 'OperaPermissionWindow', |
| | | extends: BaseOpera, |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // åæéç |
| | | originPermissionCode: '', |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | code: '', |
| | | name: '', |
| | | remark: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | code: [ |
| | | { required: true, message: '请è¾å
¥æéç¼ç ' } |
| | | ], |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥æéåç§°' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | open (title, target) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form[this.configData['field.id']] = null |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | this.originPermissionCode = target.code |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | }, |
| | | confirm () { |
| | | if (this.form.id == null || this.form.id === '') { |
| | | this.__confirmCreate() |
| | | return |
| | | } |
| | | if (this.originPermissionCode === this.form.code) { |
| | | this.__confirmEdit() |
| | | return |
| | | } |
| | | // ä¿®æ¹äºæéç¼ç |
| | | this.$dialog.confirm('æ£æµå°æ¨ä¿®æ¹äºæéç¼ç ï¼æéç¼ç ä¿®æ¹ååå端åå¯è½éè¦è°æ´ä»£ç ï¼ç¡®è®¤ä¿®æ¹åï¼', 'æç¤º', { |
| | | confirmButtonText: '确认修æ¹', |
| | | type: 'warning' |
| | | }) |
| | | .then(() => { |
| | | this.__confirmEdit() |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/permission' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="ä¸çº§å²ä½" prop="parentId"> |
| | | <PositionSelect v-if="visible" v-model="form.parentId" placeholder="è¯·éæ©ä¸çº§å²ä½" :exclude-id="excludePositionId" clearable :inline="false"/> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½ç¼ç " prop="code" required> |
| | | <el-input v-model="form.code" placeholder="请è¾å
¥å²ä½ç¼ç " v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½åç§°" prop="name" required> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥å²ä½åç§°" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import PositionSelect from '@/components/common/PositionSelect' |
| | | export default { |
| | | name: 'OperaPositionWindow', |
| | | extends: BaseOpera, |
| | | components: { PositionSelect, GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // éæé¤éæ©çå²ä½ID |
| | | excludePositionId: null, |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | parentId: null, |
| | | code: '', |
| | | name: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | code: [ |
| | | { required: true, message: '请è¾å
¥å²ä½ç¼ç ' } |
| | | ], |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥å²ä½åç§°' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @title çªå£æ é¢ |
| | | * @target ç¼è¾çå²ä½å¯¹è±¡ |
| | | * @parent æ°å»ºæ¶çä¸çº§å²ä½å¯¹è±¡ |
| | | * @positionList å²ä½å表 |
| | | */ |
| | | open (title, target, parent) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.excludePositionId = null |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form.id = null |
| | | this.form.parentId = parent == null ? null : parent.id |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | this.excludePositionId = target.id |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/position' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | class="position-user-window" |
| | | width="80%" |
| | | :title="positionName + '人åå表'" |
| | | :visible.sync="visible" |
| | | :with-footer="false" |
| | | > |
| | | <TableLayout :with-breadcrumb="false"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="80px" inline> |
| | | <el-form-item label="ç¨æ·å" prop="username"> |
| | | <el-input v-model="searchForm.username" v-trim placeholder="请è¾å
¥ç¨æ·å" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="å§å" prop="realname"> |
| | | <el-input v-model="searchForm.realname" v-trim placeholder="请è¾å
¥å§å" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="mobile"> |
| | | <el-input v-model="searchForm.mobile" v-trim placeholder="请è¾å
¥ææºå·ç " @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" icon="el-icon-search" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <template v-slot:table-wrap> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | | <el-table-column prop="avatar" label="头å" width="80px" class-name="table-column-avatar" fixed="left"> |
| | | <template slot-scope="{row}"> |
| | | <img :src="row.avatar == null ? '/static/avatar/man.png' : row.avatar"> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="realname" label="å§å" min-width="100px" fixed="left"></el-table-column> |
| | | <el-table-column prop="username" label="ç¨æ·å" min-width="100px"></el-table-column> |
| | | <el-table-column prop="empNo" label="å·¥å·" min-width="80px"></el-table-column> |
| | | <el-table-column prop="department" label="é¨é¨" min-width="120px"> |
| | | <template slot-scope="{row}">{{row.department == null ? '' : row.department.name}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="position" label="å²ä½" min-width="120px" class-name="table-column-strings"> |
| | | <template slot-scope="{row}"> |
| | | <ul> |
| | | <li v-for="position in row.positions" :key="position.id">{{position.name}}</li> |
| | | </ul> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="sex" label="æ§å«" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.sex | sex}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="mobile" label="ææºå·ç " min-width="100px"></el-table-column> |
| | | <el-table-column prop="email" label="é®ç®±" min-width="180px"></el-table-column> |
| | | <el-table-column prop="birthday" label="çæ¥" min-width="100px"></el-table-column> |
| | | <el-table-column prop="birthday" label="è§è²" min-width="160px" class-name="table-column-role"> |
| | | <template slot-scope="{row}"> |
| | | <ul> |
| | | <li v-for="role in row.roles" :key="role.id">{{role.name}}</li> |
| | | </ul> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | </TableLayout> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import Pagination from '@/components/common/Pagination' |
| | | export default { |
| | | name: 'PositionUserWindow', |
| | | extends: BaseTable, |
| | | components: { Pagination, GlobalWindow, TableLayout }, |
| | | data () { |
| | | return { |
| | | positionId: null, |
| | | positionName: '', |
| | | visible: false, |
| | | // æç´¢è¡¨å |
| | | searchForm: { |
| | | positionId: null, |
| | | username: '', |
| | | realname: '', |
| | | mobile: '' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // æå¼æ¥ç人åçªå£ |
| | | open (positionId, positionName) { |
| | | this.positionId = positionId |
| | | this.positionName = positionName |
| | | this.searchForm.positionId = positionId |
| | | this.visible = true |
| | | this.search() |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/user' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .position-user-window { |
| | | /deep/ .table-search-form { |
| | | padding: 0; |
| | | } |
| | | /deep/ .window__body { |
| | | background: #f7f7f7; |
| | | .table-content { |
| | | padding: 0; |
| | | .table-wrap { |
| | | padding: 0; |
| | | } |
| | | } |
| | | } |
| | | // å表头åå¤ç |
| | | .table-column-avatar { |
| | | img { |
| | | width: 48px; |
| | | } |
| | | } |
| | | // å表è§è²å¤ç |
| | | .table-column-role { |
| | | ul { |
| | | li { |
| | | display: inline-block; |
| | | background: #eee; |
| | | border-radius: 3px; |
| | | padding: 0 3px; |
| | | margin-right: 3px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | class="menu-config-dialog" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | width="576px" |
| | | title="ææèå" |
| | | @confirm="confirm" |
| | | > |
| | | <p class="tip" v-if="role != null">为è§è² <em>{{role.name}}</em> é
ç½®å¯è®¿é®çèå</p> |
| | | <el-tree |
| | | ref="menuTree" |
| | | :data="menus" |
| | | show-checkbox |
| | | node-key="id" |
| | | default-expand-all |
| | | :default-checked-keys="selectedIds" |
| | | :expand-on-click-node="false" |
| | | :check-on-click-node="true" |
| | | :props="{children: 'children',label: 'name'}"> |
| | | </el-tree> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import { createRoleMenu } from '@/api/system/role' |
| | | import { fetchTree as fetchMenuList } from '@/api/system/menu' |
| | | export default { |
| | | name: 'MenuConfigWindow', |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | visible: false, |
| | | isWorking: false, |
| | | // è§è² |
| | | role: null, |
| | | // ææèå |
| | | menus: [], |
| | | // å·²éä¸çèå |
| | | selectedIds: [] |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @role è§è²å¯¹è±¡ |
| | | */ |
| | | open (role) { |
| | | fetchMenuList({}) |
| | | .then(records => { |
| | | this.role = role |
| | | this.menus = records |
| | | // å¦æä¸ºåºå®è§è²ï¼ååºå®èåä¸å¯æ´æ¹ |
| | | this.__resetDisabled(this.menus, this.role) |
| | | // æ¾åºå¶èç¹ |
| | | role.menus = role.menus.filter(menu => role.menus.findIndex(m => m.parentId === menu.id) === -1) |
| | | // åå§åéä¸ |
| | | this.selectedIds = role.menus.map(r => r.id) |
| | | this.visible = true |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | }, |
| | | // ç¡®è®¤éæ©èå |
| | | confirm () { |
| | | const selectedMenus = this.$refs.menuTree.getCheckedNodes(false, true) |
| | | this.isWorking = true |
| | | createRoleMenu({ |
| | | roleId: this.role.id, |
| | | menuIds: selectedMenus.map(menu => menu.id) |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('èåæææå') |
| | | this.visible = false |
| | | this.$emit('success') |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking = false |
| | | }) |
| | | }, |
| | | // éç½®disabled |
| | | __resetDisabled (menus, role) { |
| | | if (menus == null || menus.length === 0) { |
| | | return |
| | | } |
| | | for (const menu of menus) { |
| | | menu.disabled = false |
| | | if (role.fixed && menu.fixed) { |
| | | menu.disabled = true |
| | | } |
| | | this.__resetDisabled(menu.children, role) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .global-window { |
| | | .tip { |
| | | margin-bottom: 12px; |
| | | em { |
| | | font-style: normal; |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="è§è²ç¼ç " prop="code" required> |
| | | <el-input v-model="form.code" placeholder="请è¾å
¥è§è²ç¼ç " v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²åç§°" prop="name" required> |
| | | <el-input v-model="form.name" placeholder="请è¾å
¥è§è²åç§°" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²å¤æ³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥è§è²å¤æ³¨" :rows="3" v-trim maxlength="500"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | export default { |
| | | name: 'OperaRoleWindow', |
| | | extends: BaseOpera, |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // åè§è²ç |
| | | originRoleCode: '', |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | code: '', |
| | | name: '', |
| | | remark: '' |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | code: [ |
| | | { required: true, message: '请è¾å
¥è§è²ç¼ç ' } |
| | | ], |
| | | name: [ |
| | | { required: true, message: '请è¾å
¥è§è²åç§°' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | open (title, target) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form[this.configData['field.id']] = null |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | this.originRoleCode = target.code |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | }) |
| | | }, |
| | | confirm () { |
| | | if (this.form.id == null || this.form.id === '') { |
| | | this.__confirmCreate() |
| | | return |
| | | } |
| | | if (this.originRoleCode === this.form.code) { |
| | | this.__confirmEdit() |
| | | return |
| | | } |
| | | // ä¿®æ¹äºè§è²ç¼ç |
| | | this.$dialog.confirm('æ£æµå°æ¨ä¿®æ¹äºè§è²ç¼ç ï¼è§è²ç¼ç ä¿®æ¹ååå端åå¯è½éè¦è°æ´ä»£ç ï¼ç¡®è®¤ä¿®æ¹åï¼', 'æç¤º', { |
| | | confirmButtonText: '确认修æ¹', |
| | | type: 'warning' |
| | | }) |
| | | .then(() => { |
| | | this.__confirmEdit() |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/role' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | width="582px" |
| | | title="é
ç½®è§è²æé" |
| | | @confirm="confirm" |
| | | > |
| | | <p class="tip" v-if="role != null">为è§è² <em>{{role.name}}</em> é
ç½®æé</p> |
| | | <p class="tip-warn"><i class="el-icon-warning"></i>æéï¼æéé
ç½®åééæ°ç»å½åçæ</p> |
| | | <el-transfer |
| | | ref="permissionTransfer" |
| | | v-model="selectedIds" |
| | | filterable |
| | | :filter-method="filterPermissions" |
| | | :titles="['æªæææé', 'å·²æææé']" |
| | | :props="{ |
| | | key: 'id', |
| | | label: 'name' |
| | | }" |
| | | :data="permissions"> |
| | | </el-transfer> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import { createRolePermission } from '@/api/system/role' |
| | | import { fetchAll } from '@/api/system/permission' |
| | | export default { |
| | | name: 'PermissionConfigWindow', |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | visible: false, |
| | | isWorking: false, |
| | | // è§è²å¯¹è±¡ |
| | | role: null, |
| | | // æéå表 |
| | | permissions: [], |
| | | // å·²éä¸çæéID |
| | | selectedIds: [] |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @role è§è²å¯¹è±¡ |
| | | */ |
| | | open (role) { |
| | | if (this.$refs.permissionTransfer) { |
| | | this.$refs.permissionTransfer.clearQuery('left') |
| | | this.$refs.permissionTransfer.clearQuery('right') |
| | | } |
| | | fetchAll() |
| | | .then(records => { |
| | | this.role = role |
| | | this.permissions = records |
| | | // å¦æä¸ºåºå®è§è²ï¼ååºå®æéä¸å¯æ´æ¹ |
| | | if (this.role.fixed) { |
| | | for (const perm of this.permissions) { |
| | | if (perm.fixed) { |
| | | perm.disabled = true |
| | | } |
| | | } |
| | | } |
| | | this.selectedIds = role.permissions.map(r => r.id) |
| | | this.visible = true |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | }, |
| | | // ç¡®è®¤éæ©æé |
| | | confirm () { |
| | | this.isWorking = true |
| | | createRolePermission({ |
| | | roleId: this.role.id, |
| | | permissionIds: this.selectedIds |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('æéé
ç½®æåï¼ç¨æ·éæ°ç»å½åçæ') |
| | | this.visible = false |
| | | this.$emit('success') |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking = false |
| | | }) |
| | | }, |
| | | // æç´¢æé |
| | | filterPermissions (query, item) { |
| | | const lowerCaseQuery = query.toLowerCase() |
| | | return item.code.toLowerCase().indexOf(lowerCaseQuery) > -1 || item.name.toLowerCase().indexOf(lowerCaseQuery) > -1 |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .global-window { |
| | | .tip { |
| | | em { |
| | | font-style: normal; |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | .tip-warn { |
| | | margin: 4px 0 12px 0; |
| | | font-size: 12px; |
| | | color: #999; |
| | | i { |
| | | color: orange; |
| | | margin-right: 4px; |
| | | font-size: 14px; |
| | | position: relative; |
| | | top: 1px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-select |
| | | class="role-select" |
| | | :class="{select__block: !inline}" |
| | | :value="value" |
| | | :placeholder="placeholder" |
| | | :clearable="clearable" |
| | | :disabled="disabled" |
| | | @change="$emit('change', $event)" |
| | | @input="$emit('input', $event)" |
| | | > |
| | | <el-option v-for="role in roles" :key="role.id" :value="role.id" :label="role.name"/> |
| | | </el-select> |
| | | </template> |
| | | |
| | | <script> |
| | | import { fetchAll } from '@/api/system/role' |
| | | |
| | | export default { |
| | | name: 'RoleSelect', |
| | | props: { |
| | | value: {}, |
| | | placeholder: { |
| | | default: 'è¯·éæ©è§è²' |
| | | }, |
| | | inline: { |
| | | default: true |
| | | }, |
| | | disabled: {}, |
| | | clearable: { |
| | | default: false |
| | | } |
| | | }, |
| | | data () { |
| | | return { |
| | | roles: [] |
| | | } |
| | | }, |
| | | created () { |
| | | fetchAll() |
| | | .then(data => { |
| | | this.roles = data |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .select__block { |
| | | display: block; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <GlobalWindow |
| | | :title="title" |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | @confirm="confirm" |
| | | > |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="ç¨æ·å" prop="username" required> |
| | | <el-input v-model="form.username" placeholder="请è¾å
¥ç¨æ·å" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="å§å" prop="realname" required> |
| | | <el-input v-model="form.realname" placeholder="请è¾å
¥å§å" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="æ§å«" prop="sex" required> |
| | | <el-radio-group v-model="form.sex"> |
| | | <el-radio label="1">ç·</el-radio> |
| | | <el-radio label="0">女</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="头å" prop="avatar" required> |
| | | <el-radio-group v-model="form.avatar" class="form-item-avatar"> |
| | | <el-radio label="/avatar/man.png" border><img src="/avatar/man.png" alt=""></el-radio> |
| | | <el-radio label="/avatar/woman.png" border><img src="/avatar/woman.png" alt=""></el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="form.id == null" label="åå§å¯ç " prop="password" required> |
| | | <el-input v-model="form.password" type="password" placeholder="请è¾å
¥åå§å¯ç " maxlength="30" show-password/> |
| | | </el-form-item> |
| | | <el-form-item label="æå±é¨é¨" prop="departmentId" required> |
| | | <DepartmentSelect v-model="form.departmentId" placeholder="è¯·éæ©ç¨æ·æå±é¨é¨" :inline="false" clearable/> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½" prop="positionId"> |
| | | <PositionSelect v-model="form.positionIds" placeholder="è¯·éæ©ç¨æ·æå¨å²ä½" :inline="false" :multiple="true" clearable/> |
| | | </el-form-item> |
| | | <el-form-item label="å·¥å·" prop="empNo"> |
| | | <el-input v-model="form.empNo" placeholder="请è¾å
¥å·¥å·" v-trim maxlength="50"/> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="mobile"> |
| | | <el-input v-model="form.mobile" placeholder="请è¾å
¥ææºå·ç " v-trim maxlength="11"/> |
| | | </el-form-item> |
| | | <el-form-item label="é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥é®ç®±" v-trim maxlength="200"/> |
| | | </el-form-item> |
| | | <el-form-item label="çæ¥" prop="birthday"> |
| | | <el-date-picker v-model="form.birthday" value-format="yyyy-MM-dd" placeholder="è¯·éæ©ç¨æ·çæ¥"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseOpera from '@/components/base/BaseOpera' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import DepartmentSelect from '@/components/common/DepartmentSelect' |
| | | import PositionSelect from '@/components/common/PositionSelect' |
| | | import { checkMobile, checkEmail } from '@/utils/form' |
| | | |
| | | export default { |
| | | name: 'OperaUserWindow', |
| | | extends: BaseOpera, |
| | | components: { PositionSelect, DepartmentSelect, GlobalWindow }, |
| | | data () { |
| | | return { |
| | | // è¡¨åæ°æ® |
| | | form: { |
| | | id: null, |
| | | username: '', // ç¨æ·å |
| | | realname: '', // å§å |
| | | empNo: '', // å·¥å· |
| | | departmentId: null, // æå±é¨é¨ID |
| | | positionIds: [], // æå±å²ä½IDé |
| | | avatar: '/avatar/man.png', // 头å |
| | | password: '', // å¯ç |
| | | mobile: '', // ææºå·ç |
| | | email: '', // é®ç®± |
| | | sex: '1', // æ§å« |
| | | birthday: '' // çæ¥ |
| | | }, |
| | | // éªè¯è§å |
| | | rules: { |
| | | username: [ |
| | | { required: true, message: '请è¾å
¥ç¨æ·å' } |
| | | ], |
| | | realname: [ |
| | | { required: true, message: '请è¾å
¥å§å' } |
| | | ], |
| | | password: [ |
| | | { required: true, message: '请è¾å
¥å¯ç ' } |
| | | ], |
| | | departmentId: [ |
| | | { required: true, message: 'è¯·éæ©é¨é¨' } |
| | | ], |
| | | avatar: [ |
| | | { required: true, message: 'è¯·éæ©ç¨æ·å¤´å' } |
| | | ], |
| | | sex: [ |
| | | { required: true, message: 'è¯·éæ©ç¨æ·æ§å«' } |
| | | ], |
| | | mobile: [ |
| | | { validator: checkMobile } |
| | | ], |
| | | email: [ |
| | | { validator: checkEmail } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | /** |
| | | * @title çªå£æ é¢ |
| | | * @target ç¼è¾çç¨æ·å¯¹è±¡ |
| | | */ |
| | | open (title, target) { |
| | | this.title = title |
| | | this.visible = true |
| | | // æ°å»º |
| | | if (target == null) { |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | this.form.id = null |
| | | this.form.departmentId = null |
| | | this.form.positionIds = [] |
| | | }) |
| | | return |
| | | } |
| | | // ç¼è¾ |
| | | this.$nextTick(() => { |
| | | for (const key in this.form) { |
| | | this.form[key] = target[key] |
| | | } |
| | | this.form.departmentId = target.department == null ? null : target.department.id |
| | | this.form.positionIds = target.positions == null ? [] : target.positions.map(p => p.id) |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/user' |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .global-window { |
| | | /deep/ .el-date-editor { |
| | | width: 100%; |
| | | } |
| | | // 表å头åå¤ç |
| | | /deep/ .form-item-avatar { |
| | | .el-radio.is-bordered { |
| | | height: auto; |
| | | padding: 6px; |
| | | margin: 0 10px 0 0; |
| | | .el-radio__input { |
| | | display: none; |
| | | } |
| | | .el-radio__label { |
| | | padding: 0; |
| | | width: 48px; |
| | | display: block; |
| | | img { |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | width="576px" |
| | | title="éç½®å¯ç " |
| | | @confirm="confirm" |
| | | > |
| | | <p class="tip" v-if="user != null">ä¸ºç¨æ· <em>{{user.realname}}</em> éç½®å¯ç </p> |
| | | <el-form :model="form" ref="form" :rules="rules"> |
| | | <el-form-item label="æ°å¯ç " prop="password" required> |
| | | <el-input v-model="form.password" type="password" placeholder="请è¾å
¥æ°å¯ç " maxlength="30" show-password></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import { resetPwd } from '@/api/system/user' |
| | | export default { |
| | | name: 'ResetPwdWindow', |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | isWorking: false, |
| | | visible: false, |
| | | user: null, |
| | | form: { |
| | | password: '' |
| | | }, |
| | | rules: { |
| | | password: [ |
| | | { required: true, message: '请è¾å
¥å¯ç ' } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | open (user) { |
| | | this.user = user |
| | | this.visible = true |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetFields() |
| | | }) |
| | | }, |
| | | // 确认éç½®å¯ç |
| | | confirm () { |
| | | if (this.isWorking) { |
| | | return |
| | | } |
| | | this.$refs.form.validate((valid) => { |
| | | if (!valid) { |
| | | return |
| | | } |
| | | this.isWorking = true |
| | | resetPwd({ |
| | | id: this.user.id, |
| | | password: this.form.password |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('å¯ç éç½®æå') |
| | | this.visible = false |
| | | this.$emit('success') |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking = false |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | // è§è²é
ç½® |
| | | .global-window { |
| | | .tip { |
| | | margin-bottom: 12px; |
| | | em { |
| | | font-style: normal; |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <GlobalWindow |
| | | :visible.sync="visible" |
| | | :confirm-working="isWorking" |
| | | width="582px" |
| | | title="é
ç½®ç¨æ·è§è²" |
| | | @confirm="confirm" |
| | | > |
| | | <p class="tip" v-if="user != null">ä¸ºç¨æ· <em>{{user.realname}}</em> é
ç½®è§è²</p> |
| | | <p class="tip-warn"><i class="el-icon-warning"></i>æéï¼è§è²é
ç½®åééæ°ç»å½åçæ</p> |
| | | <el-transfer |
| | | v-model="selectedIds" |
| | | :titles="['æªææè§è²', 'å·²ææè§è²']" |
| | | :props="{ |
| | | key: 'id', |
| | | label: 'name' |
| | | }" |
| | | :data="roles"> |
| | | </el-transfer> |
| | | </GlobalWindow> |
| | | </template> |
| | | |
| | | <script> |
| | | import BasePage from '@/components/base/BasePage' |
| | | import GlobalWindow from '@/components/common/GlobalWindow' |
| | | import { createUserRole } from '@/api/system/user' |
| | | import { fetchAll as fetchAllRoles } from '@/api/system/role' |
| | | export default { |
| | | name: 'RoleConfigWindow', |
| | | extends: BasePage, |
| | | components: { GlobalWindow }, |
| | | data () { |
| | | return { |
| | | visible: false, |
| | | isWorking: false, |
| | | // ç¨æ· |
| | | user: null, |
| | | // è§è²å表 |
| | | roles: null, |
| | | // å·²éä¸çè§è²ID |
| | | selectedIds: [] |
| | | } |
| | | }, |
| | | methods: { |
| | | open (user) { |
| | | fetchAllRoles() |
| | | .then(records => { |
| | | this.roles = records |
| | | this.user = user |
| | | // å¦æä¸ºåºå®ç¨æ·ï¼ååºå®è§è²ä¸å¯æ´æ¹ |
| | | if (this.user.fixed) { |
| | | for (const role of this.roles) { |
| | | if (role.fixed) { |
| | | role.disabled = true |
| | | } |
| | | } |
| | | } |
| | | // 妿å½åç¨æ·ä¸ºéè¶
级管çåç¨æ·ï¼åä¸å
许ææè¶
级管çåè§è² |
| | | if (!this.isAdmin) { |
| | | for (const role of this.roles) { |
| | | if (role.code === this.adminCode) { |
| | | role.disabled = true |
| | | } |
| | | } |
| | | } |
| | | this.selectedIds = this.user.roles.map(r => r.id) |
| | | this.visible = true |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | }, |
| | | // ç¡®è®¤éæ©è§è² |
| | | confirm () { |
| | | if (this.isWorking) { |
| | | return |
| | | } |
| | | this.isWorking = true |
| | | createUserRole({ |
| | | userId: this.user.id, |
| | | roleIds: this.selectedIds |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('è§è²é
ç½®æåï¼ç¨æ·éæ°ç»å½åçæ') |
| | | this.visible = false |
| | | this.$emit('success') |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking = false |
| | | }) |
| | | }, |
| | | // å
³é |
| | | close () { |
| | | this.$emit('update:visible', false) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | // è§è²é
ç½® |
| | | .global-window { |
| | | .tip { |
| | | em { |
| | | font-style: normal; |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | .tip-warn { |
| | | margin: 4px 0 12px 0; |
| | | font-size: 12px; |
| | | color: #999; |
| | | i { |
| | | color: orange; |
| | | margin-right: 4px; |
| | | font-size: 14px; |
| | | position: relative; |
| | | top: 1px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import vPermissions from './v-permissions' |
| | | import vRoles from './v-roles' |
| | | import vTrim from './v-trim' |
| | | export default { |
| | | install (Vue) { |
| | | // è§è²æ§å¶æä»¤ |
| | | Vue.directive('roles', vRoles) |
| | | // æéæ§å¶æä»¤ |
| | | Vue.directive('permissions', vPermissions) |
| | | // èªå¨å»ç©ºæä»¤ |
| | | Vue.directive('trim', vTrim) |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | inserted: function (el, binding, vnode) { |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | const userInfo = vnode.context.$store.state.userInfo |
| | | if (userInfo == null) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | return |
| | | } |
| | | // è·åé
ç½®æé |
| | | const configPermissions = binding.value |
| | | if (configPermissions == null) { |
| | | return |
| | | } |
| | | if (!(configPermissions instanceof Array)) { |
| | | throw new Error('v-permissionsçå¼å¿
须为ä¸ä¸ªæ°ç»') |
| | | } |
| | | // éªè¯æé |
| | | if (configPermissions.findIndex(code => userInfo.permissions.findIndex(p => p === code) > -1) === -1) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | inserted: function (el, binding, vnode) { |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | const userInfo = vnode.context.$store.state.userInfo |
| | | if (userInfo == null) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | return |
| | | } |
| | | // è·åé
ç½®è§è² |
| | | const configRoles = binding.value |
| | | if (configRoles == null) { |
| | | return |
| | | } |
| | | if (!(configRoles instanceof Array)) { |
| | | throw new Error('v-rolesçå¼å¿
须为ä¸ä¸ªæ°ç»') |
| | | } |
| | | // éªè¯æé |
| | | if (configRoles.findIndex(code => userInfo.roles.findIndex(r => r === code) > -1) === -1) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | inserted: function (el) { |
| | | let input = el |
| | | let classes = input.getAttribute('class') || '' |
| | | if (classes != null) { |
| | | classes = classes.split(' ') |
| | | } |
| | | // è¾å
¥æ¡ï¼<el-input/> |
| | | if (classes.indexOf('el-input') > -1) { |
| | | input = input.querySelector('input') |
| | | } |
| | | // å¤è¡è¾å
¥æ¡ï¼<el-input type="textarea"/> |
| | | if (classes.indexOf('el-textarea') > -1) { |
| | | input = input.querySelector('textarea') |
| | | } |
| | | // 失å»ç¦ç¹æ¶å»æä¸¤ä¾§ç©ºæ ¼ |
| | | input.addEventListener('blur', (e) => { |
| | | e.target.value = e.target.value.trim() |
| | | input.dispatchEvent(new Event('input')) |
| | | }) |
| | | // å车æ¶å»æä¸¤ä¾§ç©ºæ ¼ï¼ä»
è¾å
¥æ¡ï¼ |
| | | if (classes.indexOf('el-input') > -1) { |
| | | input.addEventListener('keydown', (e) => { |
| | | if (e.key === 'Enter') { |
| | | e.target.value = e.target.value.trim() |
| | | input.dispatchEvent(new Event('input')) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | install (Vue) { |
| | | // æ§å« |
| | | Vue.filter('sex', (value) => { |
| | | if (value === '1') { |
| | | return 'ç·' |
| | | } |
| | | if (value === '0') { |
| | | return '女' |
| | | } |
| | | return 'æªç¥' |
| | | }) |
| | | // å¯ç¨ç¦ç¨ |
| | | Vue.filter('disabledText', (value) => { |
| | | if (value) { |
| | | return 'åç¨' |
| | | } |
| | | return 'å¯ç¨' |
| | | }) |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-container class="app-layout"> |
| | | <el-aside :class="{collapse:menuData.collapse}"> |
| | | <Menu/> |
| | | </el-aside> |
| | | <el-main> |
| | | <header> |
| | | <AppHeader/> |
| | | </header> |
| | | <main> |
| | | <transition name="fade"> |
| | | <router-view></router-view> |
| | | </transition> |
| | | </main> |
| | | </el-main> |
| | | </el-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | import Header from '@/components/common/Header' |
| | | import Menu from '@/components/common/Menu' |
| | | export default { |
| | | name: 'DefaultLayout', |
| | | components: { AppHeader: Header, Menu }, |
| | | computed: { |
| | | ...mapState(['menuData']) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .el-container { |
| | | background: #F7F8F9; |
| | | height: 100%; |
| | | display: flex; |
| | | overflow: hidden; |
| | | // 左边èå |
| | | .el-aside { |
| | | width: $menu-width !important; |
| | | flex-shrink: 0; |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | background: $primary-color; |
| | | color: #fff; |
| | | transition: width ease .3s; |
| | | &.collapse { |
| | | width: 64px !important; |
| | | } |
| | | } |
| | | // å³è¾¹å
容 |
| | | .el-main { |
| | | width: 100%; |
| | | height: 100%; |
| | | padding: 0; |
| | | position: relative; |
| | | display: flex; |
| | | flex-direction: column; |
| | | overflow: hidden; |
| | | & > header { |
| | | height: $header-height; |
| | | flex-shrink: 0; |
| | | } |
| | | & > main { |
| | | height: 100%; |
| | | overflow-y: auto; |
| | | } |
| | | } |
| | | } |
| | | // 页é¢è¿æ¸¡å¨ç» |
| | | .fade-enter-active, .fade-leave-active { |
| | | transition: all .5s; |
| | | opacity: 1; |
| | | position: absolute; |
| | | width: 100%; |
| | | } |
| | | .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { |
| | | transform: translateY(200px); |
| | | opacity: 0; |
| | | transition: all .5s; |
| | | position: absolute; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="table-layout"> |
| | | <!-- å¤´é¨ --> |
| | | <div v-if="withBreadcrumb" class="table-header"> |
| | | <el-breadcrumb separator="/"> |
| | | <el-breadcrumb-item v-for="path in paths" :key="path">{{path}}</el-breadcrumb-item> |
| | | </el-breadcrumb> |
| | | </div> |
| | | <Profile :roles="roles" :permissions="permissions"> |
| | | <!-- æç´¢è¡¨åé¨å --> |
| | | <div class="table-search-form"> |
| | | <div class="form-wrap"> |
| | | <slot name="search-form"></slot> |
| | | </div> |
| | | </div> |
| | | <slot name="space"></slot> |
| | | <!-- å表åå页é¨å --> |
| | | <div class="table-content"> |
| | | <div class="table-wrap"> |
| | | <slot name="table-wrap"></slot> |
| | | </div> |
| | | </div> |
| | | <slot></slot> |
| | | </Profile> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import Profile from '../components/common/Profile' |
| | | export default { |
| | | name: 'TableLayout', |
| | | components: { Profile }, |
| | | props: { |
| | | // è§è² |
| | | roles: { |
| | | type: Array |
| | | }, |
| | | // æé |
| | | permissions: { |
| | | type: Array |
| | | }, |
| | | // æ¯å¦å±ç¤ºå¤´é¨é¢å
å± |
| | | withBreadcrumb: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | computed: { |
| | | paths () { |
| | | return this.$route.meta.paths |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .table-layout { |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | .not-allow-wrap { |
| | | padding-top: 0; |
| | | } |
| | | } |
| | | // å¤´é¨ |
| | | .table-header { |
| | | overflow: hidden; |
| | | padding: 12px 16px; |
| | | flex-shrink: 0; |
| | | // 页é¢è·¯å¾ |
| | | .el-breadcrumb { |
| | | .el-breadcrumb__item { |
| | | .el-breadcrumb__inner { |
| | | color: #ABB2BE; |
| | | font-size: 12px; |
| | | } |
| | | &:last-of-type .el-breadcrumb__inner { |
| | | color: #606263; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // æç´¢ |
| | | .table-search-form { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | padding: 0 16px; |
| | | .form-wrap { |
| | | padding: 16px 16px 0 16px; |
| | | width: 100%; |
| | | background: #fff; |
| | | &:empty { |
| | | padding: 0; |
| | | } |
| | | } |
| | | section { |
| | | display: inline-block; |
| | | margin-left: 16px; |
| | | margin-bottom: 18px; |
| | | } |
| | | } |
| | | // å表åå页 |
| | | .table-content { |
| | | margin-top: 10px; |
| | | padding: 0 16px; |
| | | .table-wrap { |
| | | padding: 16px 16px 0 16px; |
| | | background: #fff; |
| | | // å·¥å
·æ |
| | | .toolbar { |
| | | border-bottom: 1px solid #eee; |
| | | padding-bottom: 10px; |
| | | li { |
| | | display: inline-block; |
| | | margin-right: 6px; |
| | | } |
| | | } |
| | | // è¡¨æ ¼ |
| | | .el-table { |
| | | th { |
| | | .cell { |
| | | color: #666; |
| | | } |
| | | } |
| | | // å¤éæ¡å |
| | | .el-table-column--selection { |
| | | .cell { |
| | | text-align: center !important; |
| | | } |
| | | } |
| | | // å¤å¼å段 |
| | | .table-column-strings { |
| | | ul { |
| | | li { |
| | | display: inline-block; |
| | | background: #eee; |
| | | border-radius: 3px; |
| | | padding: 0 3px; |
| | | margin-right: 3px; |
| | | margin-bottom: 3px; |
| | | } |
| | | } |
| | | } |
| | | // æ è§è§è°æ´ |
| | | [class*=el-table__row--level] .el-table__expand-icon { |
| | | position: relative; |
| | | left: -6px; |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | // å页 |
| | | .table-pagination { |
| | | padding: 16px 0; |
| | | text-align: left; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import Vue from 'vue' |
| | | import App from './App.vue' |
| | | import router from './router' |
| | | import store from './store' |
| | | import ElementUI from 'element-ui' |
| | | import './assets/style/element-variables.scss' |
| | | import VueClipboard from 'vue-clipboard2' |
| | | import directives from './directives' |
| | | import filters from './filters' |
| | | import plugins from './plugins' |
| | | import { mapState, mapMutations } from 'vuex' |
| | | import { fetchMenuTree } from './api/system/menu' |
| | | |
| | | Vue.config.productionTip = false |
| | | Vue.use(ElementUI, { |
| | | size: 'small' |
| | | }) |
| | | Vue.use(VueClipboard) |
| | | Vue.use(directives) |
| | | Vue.use(filters) |
| | | Vue.use(plugins) |
| | | |
| | | new Vue({ |
| | | data: { |
| | | loading: false |
| | | }, |
| | | router, |
| | | store, |
| | | computed: { |
| | | ...mapState(['userInfo', 'homePage']) |
| | | }, |
| | | watch: { |
| | | async userInfo () { |
| | | if (this.userInfo == null) { |
| | | return |
| | | } |
| | | await this.initRoutes() |
| | | } |
| | | }, |
| | | methods: { |
| | | ...mapMutations(['switchCollapseMenu', 'setHomePage']), |
| | | // åå§åæ¬å°é
ç½® |
| | | initLocalConfig () { |
| | | // èåç¶æé
ç½® |
| | | const menuStatus = window.localStorage.getItem('MENU_STATUS') |
| | | if (menuStatus != null) { |
| | | this.switchCollapseMenu(menuStatus === 'true') |
| | | } |
| | | }, |
| | | // åå§åè·¯ç± |
| | | async initRoutes () { |
| | | if (this.loading || this.userInfo == null) { |
| | | return |
| | | } |
| | | this.loading = true |
| | | // éç½®èå |
| | | this.$store.commit('resetMenus') |
| | | // è·åèå |
| | | const storeMenus = this.$store.state.menuData.list |
| | | if (storeMenus.length > 0 && this.homePage == null) { |
| | | this.setHomePage(storeMenus[0]) |
| | | } |
| | | await fetchMenuTree() |
| | | .then(menus => { |
| | | // æ·»å èå |
| | | storeMenus.push.apply(storeMenus, menus) |
| | | // æ·»å è·¯ç± |
| | | this.__addRouters(storeMenus) |
| | | // 404 |
| | | router.addRoute({ |
| | | path: '*', |
| | | redirect: '/not-found' |
| | | }) |
| | | // é¦é¡µ |
| | | router.addRoute({ |
| | | name: 'index', |
| | | path: '/', |
| | | redirect: this.homePage.url |
| | | }) |
| | | // è·¯ç±å è½½å®æåï¼å¦æè®¿é®çæ¯/ï¼è·³è½¬è³å¨æè¯å«çé¦é¡µ |
| | | if (this.$route.path === '/') { |
| | | this.$router.push(this.homePage.url) |
| | | } |
| | | }) |
| | | .catch(e => { |
| | | throw e |
| | | }) |
| | | .finally(() => { |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | // æ°å»ºè·¯ç± |
| | | __addRouters (routes, parents = []) { |
| | | if (routes == null || routes.length === 0) { |
| | | return |
| | | } |
| | | const rs = router.getRoutes() |
| | | for (const route of routes) { |
| | | const parentsDump = JSON.parse(JSON.stringify(parents)) |
| | | parentsDump.push(route) |
| | | if (route.url == null || route.url === '') { |
| | | this.__addRouters(route.children, parentsDump) |
| | | continue |
| | | } |
| | | if (rs.findIndex(r => r.path === route.url) > -1) { |
| | | this.__addRouters(route.children, parentsDump) |
| | | continue |
| | | } |
| | | if (this.homePage == null) { |
| | | this.setHomePage(route) |
| | | } |
| | | router.addRoute('layout', { |
| | | path: route.url, |
| | | name: route.label, |
| | | meta: { |
| | | title: route.label, |
| | | paths: [...parents.map(p => p.label), route.label] |
| | | }, |
| | | component: () => import('@/views' + route.url) |
| | | }) |
| | | this.__addRouters(route.children, parentsDump) |
| | | } |
| | | } |
| | | }, |
| | | async created () { |
| | | if (this.userInfo == null) { |
| | | return |
| | | } |
| | | await this.initRoutes() |
| | | .catch(() => {}) |
| | | }, |
| | | mounted () { |
| | | this.initLocalConfig() |
| | | }, |
| | | render: h => h(App) |
| | | }).$mount('#app') |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | const sessionCache = { |
| | | set (key, value) { |
| | | if (!sessionStorage) { |
| | | return |
| | | } |
| | | if (key != null && value != null) { |
| | | sessionStorage.setItem(key, value) |
| | | } |
| | | }, |
| | | get (key) { |
| | | if (!sessionStorage) { |
| | | return null |
| | | } |
| | | if (key == null) { |
| | | return null |
| | | } |
| | | return sessionStorage.getItem(key) |
| | | }, |
| | | setJSON (key, jsonValue) { |
| | | if (jsonValue != null) { |
| | | this.set(key, JSON.stringify(jsonValue)) |
| | | } |
| | | }, |
| | | getJSON (key) { |
| | | const value = this.get(key) |
| | | if (value != null) { |
| | | return JSON.parse(value) |
| | | } |
| | | } |
| | | } |
| | | const localCache = { |
| | | set (key, value) { |
| | | if (!localStorage) { |
| | | return |
| | | } |
| | | if (key != null && value != null) { |
| | | localStorage.setItem(key, value) |
| | | } |
| | | }, |
| | | get (key) { |
| | | if (!localStorage) { |
| | | return null |
| | | } |
| | | if (key == null) { |
| | | return null |
| | | } |
| | | return localStorage.getItem(key) |
| | | }, |
| | | setJSON (key, jsonValue) { |
| | | if (jsonValue != null) { |
| | | this.set(key, JSON.stringify(jsonValue)) |
| | | } |
| | | }, |
| | | getJSON (key) { |
| | | const value = this.get(key) |
| | | if (value != null) { |
| | | return JSON.parse(value) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | /** |
| | | * ä¼è¯çº§ç¼å |
| | | */ |
| | | session: sessionCache, |
| | | /** |
| | | * æ¬å°ç¼å |
| | | */ |
| | | local: localCache |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * 常éå®ä¹ |
| | | */ |
| | | export default { |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import fileDownload from 'js-file-download' |
| | | import message from './message' |
| | | |
| | | export default function (response, decode = true, mime = 'application/octet-stream') { |
| | | // å½ä¸è½½æ¥å£æ²¡ææåè¿åæµå¹¶ä¸æ¥å£è¿åçæ¯JSONæ¶éè¦å¯¹ååºæµè¿è¡è§£æå¹¶æç¤ºé误ãï¼å¤çä¸è½½æ¥å£åºç°æªç¥å¼å¸¸çæ
åµï¼ |
| | | if (response.headers['content-type'] === 'application/json') { |
| | | const blob = new Blob([response.data]) |
| | | const fileReader = new FileReader() |
| | | fileReader.readAsText(blob, 'utf-8') |
| | | fileReader.onload = function () { |
| | | message.apiFailed(JSON.parse(fileReader.result)) |
| | | } |
| | | return |
| | | } |
| | | if (response.headers['content-length'] === '0') { |
| | | message.error('æ æ³ä¸è½½æä»¶ï¼å¯è½å ä¸ºæ°æ®å¤çéè¯¯å¯¼è´æä»¶å¤§å°ä¸º0B') |
| | | return |
| | | } |
| | | // ä¸è½½æ¥å£å¨ååºå¤´eva-download-filenameä¸åæ¾æä»¶åç§°ï¼æ¥å£çè¿åçæä»¶åç§°ééç¨url encodeçæ¹å¼è¿è¡ç¼ç |
| | | fileDownload(response.data, decode ? decodeURI(response.headers['eva-download-filename']) : response.headers['eva-download-filename'], mime) |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import consts from './consts' |
| | | import message from './message' |
| | | import messagebox from './messagebox' |
| | | import cache from './cache' |
| | | import download from './download' |
| | | export default { |
| | | install (Vue) { |
| | | // 常é |
| | | Vue.prototype.$consts = consts |
| | | // æé对象 |
| | | Vue.prototype.$tip = message |
| | | // æç¤ºæ¡å¯¹è±¡ |
| | | Vue.prototype.$dialog = messagebox |
| | | // ç¼å对象 |
| | | Vue.prototype.$cache = cache |
| | | // ä¸è½½æä»¶ |
| | | Vue.prototype.download = download |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { Message } from 'element-ui' |
| | | |
| | | export default { |
| | | ...Message, |
| | | // æ¥å£è°ç¨æå |
| | | apiSuccess (message) { |
| | | Message.success(message) |
| | | }, |
| | | // æ¥å£è°ç¨å¤±è´¥ |
| | | apiFailed (err) { |
| | | // ä¸è½½æ¥å£è¿åçæ¯ArrayBufferï¼æ¤æ¶éè¦è§£æä¸ºJSONå¹¶æç¤ºéè¯¯æ¶æ¯ãï¼ä¸è½½æ¥å£åºç°ä¸å¡å¤±è´¥çæ
åµï¼ä¾å¦æ æéçï¼ |
| | | if (err instanceof ArrayBuffer) { |
| | | const blob = new Blob([err]) |
| | | const fileReader = new FileReader() |
| | | fileReader.readAsText(blob, 'utf-8') |
| | | fileReader.onload = function () { |
| | | Message.error(JSON.parse(fileReader.result).message) |
| | | } |
| | | return |
| | | } |
| | | Message.error(err.message) |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { MessageBox } from 'element-ui' |
| | | |
| | | export default { |
| | | ...MessageBox, |
| | | // å é¤äºæ¬¡ç¡®è®¤ |
| | | deleteConfirm (message) { |
| | | return MessageBox.confirm(message, 'å 餿é', { |
| | | confirmButtonText: '确认å é¤', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | }, |
| | | // ç¦ç¨äºæ¬¡ç¡®è®¤ |
| | | disableConfirm (message) { |
| | | return MessageBox.confirm(message, 'ç¦ç¨æé', { |
| | | confirmButtonText: '确认ç¦ç¨', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | }, |
| | | // 导åºäºæ¬¡ç¡®è®¤ |
| | | exportConfirm (message) { |
| | | return MessageBox.confirm(message, 'å¯¼åºæé', { |
| | | confirmButtonText: '确认导åº', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }) |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import Vue from 'vue' |
| | | import VueRouter from 'vue-router' |
| | | import AppLayout from '@/layouts/AppLayout' |
| | | import { getUserInfo } from '@/api/system/common' |
| | | const Login = () => import('@/views/login') |
| | | const ErrorNoPermissions = () => import('@/views/no-permissions') |
| | | const Error404 = () => import('@/views/not-found') |
| | | |
| | | Vue.use(VueRouter) |
| | | |
| | | const router = new VueRouter({ |
| | | base: process.env.VUE_APP_CONTEXT_PATH + (process.env.VUE_APP_ROUTER_MODE === 'hash' ? '#' : ''), |
| | | mode: process.env.VUE_APP_ROUTER_MODE, |
| | | routes: [ |
| | | // ç»å½ |
| | | { |
| | | name: 'login', |
| | | path: '/login', |
| | | component: Login |
| | | }, |
| | | // æ æé |
| | | { |
| | | name: 'no-permissions', |
| | | path: '/no-permissions', |
| | | component: ErrorNoPermissions |
| | | }, |
| | | // 404 |
| | | { |
| | | name: 'not-found', |
| | | path: '/not-found', |
| | | component: Error404 |
| | | }, |
| | | // å
容页ï¼å¨æå è½½ï¼ |
| | | { |
| | | name: 'layout', |
| | | path: '', |
| | | component: AppLayout, |
| | | children: [] |
| | | } |
| | | ] |
| | | }) |
| | | router.beforeEach((to, from, next) => { |
| | | // æ æè®¿é®&404页é¢å¯ç´æ¥è®¿é® |
| | | if (to.name === 'no-permissions' || to.name === 'not-found') { |
| | | next() |
| | | return |
| | | } |
| | | // å¦æè®¿é®çæ¯layoutï¼åéæ¶å¯è½åå¨è¯¥æ
åµï¼ï¼ç´å¥index |
| | | if (to.name === 'layout') { |
| | | next({ name: 'index' }) |
| | | return |
| | | } |
| | | // éªè¯ç¨æ·æ¯å¦ç»å½ |
| | | const userInfo = router.app.$options.store.state.userInfo |
| | | if (userInfo != null) { |
| | | // å¦æç¨æ·ä¸å卿é |
| | | if (userInfo.permissions.length === 0) { |
| | | next({ name: 'no-permissions' }) |
| | | return |
| | | } |
| | | // å¦æè®¿é®çæ¯ç»å½é¡µé¢ï¼åç´æ¥è·³è½¬è³é¦é¡µ |
| | | if (to.name === 'login') { |
| | | next({ name: 'index' }) |
| | | return |
| | | } |
| | | next() |
| | | return |
| | | } |
| | | getUserInfo() |
| | | .then(userInfo => { |
| | | // å¦æç¨æ·ä¸å卿é |
| | | if (userInfo.permissions.length === 0) { |
| | | next({ name: 'no-permissions' }) |
| | | return |
| | | } |
| | | // å·²ç»å½ï¼åå¨userInfo |
| | | router.app.$store.commit('setUserInfo', userInfo) |
| | | // å¦æè®¿é®çæ¯ç»å½é¡µé¢ï¼åç´æ¥è·³è½¬è³é¦é¡µ |
| | | if (to.name === 'login') { |
| | | next({ name: 'index' }) |
| | | return |
| | | } |
| | | next() |
| | | }) |
| | | .catch(e => { |
| | | // å¦æè®¿é®çæ¯ç»å½é¡µé¢ï¼åç´æ¥æ¾è¡ |
| | | if (to.name === 'login') { |
| | | next() |
| | | return |
| | | } |
| | | // æªç»å½ï¼è·³è½¬è³ç»å½é¡µ |
| | | next({ name: 'login' }) |
| | | }) |
| | | }) |
| | | |
| | | export default router |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import Vue from 'vue' |
| | | import Vuex from 'vuex' |
| | | Vue.use(Vuex) |
| | | |
| | | const state = { |
| | | // ç»å½ç¨æ·ä¿¡æ¯ |
| | | userInfo: null, |
| | | // é¦é¡µ |
| | | homePage: null, |
| | | // èå |
| | | menuData: { |
| | | // èåå表 |
| | | list: [], |
| | | // æ¯å¦æ¶èµ· |
| | | collapse: false |
| | | } |
| | | } |
| | | |
| | | const mutations = { |
| | | // 忢èåç¶æ |
| | | switchCollapseMenu (state, value) { |
| | | if (value != null) { |
| | | state.menuData.collapse = value |
| | | } else { |
| | | state.menuData.collapse = !state.menuData.collapse |
| | | } |
| | | window.localStorage.setItem('MENU_STATUS', state.menuData.collapse) |
| | | }, |
| | | // 设置已ç»å½çç¨æ·ä¿¡æ¯ |
| | | setUserInfo: (state, data) => { |
| | | state.userInfo = data |
| | | }, |
| | | // 设置é¦é¡µè·¯ç±ä¿¡æ¯ |
| | | setHomePage (state, homePage) { |
| | | state.homePage = homePage |
| | | }, |
| | | // éç½®èå |
| | | resetMenus: (state) => { |
| | | state.menuData.list = [] |
| | | } |
| | | } |
| | | const actions = {} |
| | | const getters = {} |
| | | export default new Vuex.Store({ |
| | | state, |
| | | mutations, |
| | | actions, |
| | | getters |
| | | }) |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // éªè¯ææºå·ç |
| | | export function checkMobile (rule, value, callback) { |
| | | if (value == null || value.trim() === '') { |
| | | callback() |
| | | return |
| | | } |
| | | if (!/^1\d{10}$/.test(value)) { |
| | | callback(new Error('ææºå·ç æ ¼å¼ä¸æ£ç¡®')) |
| | | return |
| | | } |
| | | callback() |
| | | } |
| | | |
| | | // éªè¯é®ç®± |
| | | export function checkEmail (rule, value, callback) { |
| | | if (value == null || value.trim() === '') { |
| | | callback() |
| | | return |
| | | } |
| | | if (!/^\S+@\S+\.\S+$/.test(value)) { |
| | | callback(new Error('é®ç®±æ ¼å¼ä¸æ£ç¡®')) |
| | | return |
| | | } |
| | | callback() |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export default [ |
| | | // èªå®ä¹å¾æ |
| | | 'eva-icon-role', |
| | | 'eva-icon-permission', |
| | | 'eva-icon-department', |
| | | 'eva-icon-position', |
| | | 'eva-icon-dictionary', |
| | | 'eva-icon-listener', |
| | | 'eva-icon-log', |
| | | 'eva-icon-log-opera', |
| | | 'eva-icon-log-login', |
| | | // element-ui徿 |
| | | 'el-icon-platform-eleme', |
| | | 'el-icon-eleme', |
| | | 'el-icon-delete-solid', |
| | | 'el-icon-delete', |
| | | 'el-icon-s-tools', |
| | | 'el-icon-setting', |
| | | 'el-icon-user-solid', |
| | | 'el-icon-user', |
| | | 'el-icon-phone', |
| | | 'el-icon-phone-outline', |
| | | 'el-icon-more', |
| | | 'el-icon-more-outline', |
| | | 'el-icon-star-on', |
| | | 'el-icon-star-off', |
| | | 'el-icon-s-goods', |
| | | 'el-icon-goods', |
| | | 'el-icon-warning', |
| | | 'el-icon-warning-outline', |
| | | 'el-icon-question', |
| | | 'el-icon-info', |
| | | 'el-icon-remove', |
| | | 'el-icon-circle-plus', |
| | | 'el-icon-success', |
| | | 'el-icon-error', |
| | | 'el-icon-zoom-in', |
| | | 'el-icon-zoom-out', |
| | | 'el-icon-remove-outline', |
| | | 'el-icon-circle-plus-outline', |
| | | 'el-icon-circle-check', |
| | | 'el-icon-circle-close', |
| | | 'el-icon-s-help', |
| | | 'el-icon-help', |
| | | 'el-icon-minus', |
| | | 'el-icon-plus', |
| | | 'el-icon-check', |
| | | 'el-icon-close', |
| | | 'el-icon-picture', |
| | | 'el-icon-picture-outline', |
| | | 'el-icon-picture-outline-round', |
| | | 'el-icon-upload', |
| | | 'el-icon-upload2', |
| | | 'el-icon-download', |
| | | 'el-icon-camera-solid', |
| | | 'el-icon-camera', |
| | | 'el-icon-video-camera-solid', |
| | | 'el-icon-video-camera', |
| | | 'el-icon-message-solid', |
| | | 'el-icon-bell', |
| | | 'el-icon-s-cooperation', |
| | | 'el-icon-s-order', |
| | | 'el-icon-s-platform', |
| | | 'el-icon-s-fold', |
| | | 'el-icon-s-unfold', |
| | | 'el-icon-s-operation', |
| | | 'el-icon-s-promotion', |
| | | 'el-icon-s-home', |
| | | 'el-icon-s-release', |
| | | 'el-icon-s-ticket', |
| | | 'el-icon-s-management', |
| | | 'el-icon-s-open', |
| | | 'el-icon-s-shop', |
| | | 'el-icon-s-marketing', |
| | | 'el-icon-s-flag', |
| | | 'el-icon-s-comment', |
| | | 'el-icon-s-finance', |
| | | 'el-icon-s-claim', |
| | | 'el-icon-s-custom', |
| | | 'el-icon-s-opportunity', |
| | | 'el-icon-s-data', |
| | | 'el-icon-s-check', |
| | | 'el-icon-s-grid', |
| | | 'el-icon-menu', |
| | | 'el-icon-share', |
| | | 'el-icon-d-caret', |
| | | 'el-icon-caret-left', |
| | | 'el-icon-caret-right', |
| | | 'el-icon-caret-bottom', |
| | | 'el-icon-caret-top', |
| | | 'el-icon-bottom-left', |
| | | 'el-icon-bottom-right', |
| | | 'el-icon-back', |
| | | 'el-icon-right', |
| | | 'el-icon-bottom', |
| | | 'el-icon-top', |
| | | 'el-icon-top-left', |
| | | 'el-icon-top-right', |
| | | 'el-icon-arrow-left', |
| | | 'el-icon-arrow-right', |
| | | 'el-icon-arrow-down', |
| | | 'el-icon-arrow-up', |
| | | 'el-icon-d-arrow-left', |
| | | 'el-icon-d-arrow-right', |
| | | 'el-icon-video-pause', |
| | | 'el-icon-video-play', |
| | | 'el-icon-refresh', |
| | | 'el-icon-refresh-right', |
| | | 'el-icon-refresh-left', |
| | | 'el-icon-finished', |
| | | 'el-icon-sort', |
| | | 'el-icon-sort-up', |
| | | 'el-icon-sort-down', |
| | | 'el-icon-rank', |
| | | 'el-icon-loading', |
| | | 'el-icon-view', |
| | | 'el-icon-c-scale-to-original', |
| | | 'el-icon-date', |
| | | 'el-icon-edit', |
| | | 'el-icon-edit-outline', |
| | | 'el-icon-folder', |
| | | 'el-icon-folder-opened', |
| | | 'el-icon-folder-add', |
| | | 'el-icon-folder-remove', |
| | | 'el-icon-folder-delete', |
| | | 'el-icon-folder-checked', |
| | | 'el-icon-tickets', |
| | | 'el-icon-document-remove', |
| | | 'el-icon-document-delete', |
| | | 'el-icon-document-copy', |
| | | 'el-icon-document-checked', |
| | | 'el-icon-document', |
| | | 'el-icon-document-add', |
| | | 'el-icon-printer', |
| | | 'el-icon-paperclip', |
| | | 'el-icon-takeaway-box', |
| | | 'el-icon-search', |
| | | 'el-icon-monitor', |
| | | 'el-icon-attract', |
| | | 'el-icon-mobile', |
| | | 'el-icon-scissors', |
| | | 'el-icon-umbrella', |
| | | 'el-icon-headset', |
| | | 'el-icon-brush', |
| | | 'el-icon-mouse', |
| | | 'el-icon-coordinate', |
| | | 'el-icon-magic-stick', |
| | | 'el-icon-reading', |
| | | 'el-icon-data-line', |
| | | 'el-icon-data-board', |
| | | 'el-icon-pie-chart', |
| | | 'el-icon-data-analysis', |
| | | 'el-icon-collection-tag', |
| | | 'el-icon-film', |
| | | 'el-icon-suitcase', |
| | | 'el-icon-suitcase-1', |
| | | 'el-icon-receiving', |
| | | 'el-icon-collection', |
| | | 'el-icon-files', |
| | | 'el-icon-notebook-1', |
| | | 'el-icon-notebook-2', |
| | | 'el-icon-toilet-paper', |
| | | 'el-icon-office-building', |
| | | 'el-icon-school', |
| | | 'el-icon-table-lamp', |
| | | 'el-icon-house', |
| | | 'el-icon-no-smoking', |
| | | 'el-icon-smoking', |
| | | 'el-icon-shopping-cart-full', |
| | | 'el-icon-shopping-cart-1', |
| | | 'el-icon-shopping-cart-2', |
| | | 'el-icon-shopping-bag-1', |
| | | 'el-icon-shopping-bag-2', |
| | | 'el-icon-sold-out', |
| | | 'el-icon-sell', |
| | | 'el-icon-present', |
| | | 'el-icon-box', |
| | | 'el-icon-bank-card', |
| | | 'el-icon-money', |
| | | 'el-icon-coin', |
| | | 'el-icon-wallet', |
| | | 'el-icon-discount', |
| | | 'el-icon-price-tag', |
| | | 'el-icon-news', |
| | | 'el-icon-guide', |
| | | 'el-icon-male', |
| | | 'el-icon-female', |
| | | 'el-icon-thumb', |
| | | 'el-icon-cpu', |
| | | 'el-icon-link', |
| | | 'el-icon-connection', |
| | | 'el-icon-open', |
| | | 'el-icon-turn-off', |
| | | 'el-icon-set-up', |
| | | 'el-icon-chat-round', |
| | | 'el-icon-chat-line-round', |
| | | 'el-icon-chat-square', |
| | | 'el-icon-chat-dot-round', |
| | | 'el-icon-chat-dot-square', |
| | | 'el-icon-chat-line-square', |
| | | 'el-icon-message', |
| | | 'el-icon-postcard', |
| | | 'el-icon-position', |
| | | 'el-icon-turn-off-microphone', |
| | | 'el-icon-microphone', |
| | | 'el-icon-close-notification', |
| | | 'el-icon-bangzhu', |
| | | 'el-icon-time', |
| | | 'el-icon-odometer', |
| | | 'el-icon-crop', |
| | | 'el-icon-aim', |
| | | 'el-icon-switch-button', |
| | | 'el-icon-full-screen', |
| | | 'el-icon-copy-document', |
| | | 'el-icon-mic', |
| | | 'el-icon-stopwatch', |
| | | 'el-icon-medal-1', |
| | | 'el-icon-medal', |
| | | 'el-icon-trophy', |
| | | 'el-icon-trophy-1', |
| | | 'el-icon-first-aid-kit', |
| | | 'el-icon-discover', |
| | | 'el-icon-place', |
| | | 'el-icon-location', |
| | | 'el-icon-location-outline', |
| | | 'el-icon-location-information', |
| | | 'el-icon-add-location', |
| | | 'el-icon-delete-location', |
| | | 'el-icon-map-location', |
| | | 'el-icon-alarm-clock', |
| | | 'el-icon-timer', |
| | | 'el-icon-watch-1', |
| | | 'el-icon-watch', |
| | | 'el-icon-lock', |
| | | 'el-icon-unlock', |
| | | 'el-icon-key', |
| | | 'el-icon-service', |
| | | 'el-icon-mobile-phone', |
| | | 'el-icon-bicycle', |
| | | 'el-icon-truck', |
| | | 'el-icon-ship', |
| | | 'el-icon-basketball', |
| | | 'el-icon-football', |
| | | 'el-icon-soccer', |
| | | 'el-icon-baseball', |
| | | 'el-icon-wind-power', |
| | | 'el-icon-light-rain', |
| | | 'el-icon-lightning', |
| | | 'el-icon-heavy-rain', |
| | | 'el-icon-sunrise', |
| | | 'el-icon-sunrise-1', |
| | | 'el-icon-sunset', |
| | | 'el-icon-sunny', |
| | | 'el-icon-cloudy', |
| | | 'el-icon-partly-cloudy', |
| | | 'el-icon-cloudy-and-sunny', |
| | | 'el-icon-moon', |
| | | 'el-icon-moon-night', |
| | | 'el-icon-dish', |
| | | 'el-icon-dish-1', |
| | | 'el-icon-food', |
| | | 'el-icon-chicken', |
| | | 'el-icon-fork-spoon', |
| | | 'el-icon-knife-fork', |
| | | 'el-icon-burger', |
| | | 'el-icon-tableware', |
| | | 'el-icon-sugar', |
| | | 'el-icon-dessert', |
| | | 'el-icon-ice-cream', |
| | | 'el-icon-hot-water', |
| | | 'el-icon-water-cup', |
| | | 'el-icon-coffee-cup', |
| | | 'el-icon-cold-drink', |
| | | 'el-icon-goblet', |
| | | 'el-icon-goblet-full', |
| | | 'el-icon-goblet-square', |
| | | 'el-icon-goblet-square-full', |
| | | 'el-icon-refrigerator', |
| | | 'el-icon-grape', |
| | | 'el-icon-watermelon', |
| | | 'el-icon-cherry', |
| | | 'el-icon-apple', |
| | | 'el-icon-pear', |
| | | 'el-icon-orange', |
| | | 'el-icon-coffee', |
| | | 'el-icon-ice-tea', |
| | | 'el-icon-ice-drink', |
| | | 'el-icon-milk-tea', |
| | | 'el-icon-potato-strips', |
| | | 'el-icon-lollipop', |
| | | 'el-icon-ice-cream-square', |
| | | 'el-icon-ice-cream-round' |
| | | ] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import axios from 'axios' |
| | | import Cookies from 'js-cookie' |
| | | import pkg from '../../package' |
| | | import { trim } from './util' |
| | | import cache from '../plugins/cache' |
| | | |
| | | axios.defaults.headers.common['Content-Type'] = 'application/json;charset=UTF-8' |
| | | const axiosInstance = axios.create({ |
| | | baseURL: process.env.VUE_APP_API_PREFIX, |
| | | // 请æ±è¶
æ¶æ¶é´ |
| | | timeout: 60000 |
| | | }) |
| | | |
| | | // æ°å»ºè¯·æ±æ¦æªå¨ |
| | | axiosInstance.interceptors.request.use(config => { |
| | | // åæ°å»ç©ºæ ¼ |
| | | if (config.trim === true) { |
| | | if (config.data != null) { |
| | | config.data = trim(config.data) |
| | | } |
| | | if (config.params != null) { |
| | | config.params = trim(config.params) |
| | | } |
| | | } |
| | | // 导åºå¤ç |
| | | if (config.download === true) { |
| | | config.responseType = 'blob' |
| | | } |
| | | // 设置æä½å¹³å° |
| | | config.headers['eva-platform'] = `pc-${pkg.version}` |
| | | // 设置认è¯å¤´ |
| | | const authToken = Cookies.get('eva-auth-token') |
| | | if (authToken != null) { |
| | | config.headers['eva-auth-token'] = authToken |
| | | } |
| | | return config |
| | | }, function (error) { |
| | | return Promise.reject(error) |
| | | }) |
| | | |
| | | // æ°å»ºååºæ¦æªå¨ |
| | | axiosInstance.interceptors.response.use((response) => { |
| | | // 请æ±å¤±è´¥ |
| | | if (response.status !== 200) { |
| | | return Promise.reject(new Error('æå¡å¨ç¹å¿ï¼è¯·ç¨ååè¯')) |
| | | } |
| | | // ä¸è½½æ¥å£å¤ç |
| | | if (response.headers['eva-opera-type'] === 'download') { |
| | | return Promise.resolve(response) |
| | | } |
| | | // æªç»å½ |
| | | if (response.data.code === 401) { |
| | | if (response.config.autoLogin !== false) { |
| | | window.location.href = process.env.VUE_APP_ROUTER_MODE === 'history' ? '/#/login' : '/login' |
| | | } |
| | | return Promise.reject(response.data) |
| | | } |
| | | // ä¸å¡å¤±è´¥ |
| | | if (!response.data.success) { |
| | | return Promise.reject(response.data) |
| | | } |
| | | return response.data.data |
| | | }, function (error) { |
| | | if (error.code == null) { |
| | | return Promise.reject(new Error('æå¡å¨ç¹å¿ï¼è¯·ç¨ååè¯')) |
| | | } |
| | | if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) { |
| | | return Promise.reject(new Error('æå¡å¨ååºè¶
æ¶ï¼è¯·ç¨ååè¯')) |
| | | } |
| | | return Promise.reject(error) |
| | | }) |
| | | |
| | | // ç¼å请æ±ç»æ |
| | | const buildCachePromise = (cacheKey, method, args, cacheImpl) => { |
| | | return { |
| | | __cacheImpl: cache[cacheImpl], |
| | | __arguments: args, |
| | | __result_promise: null, |
| | | // å¼å¯ç¼å |
| | | cache () { |
| | | const data = this.__cacheImpl.getJSON(cacheKey) |
| | | if (data != null) { |
| | | this.__result_promise = Promise.resolve(data) |
| | | } |
| | | if (this.__result_promise != null) { |
| | | return this.__result_promise |
| | | } |
| | | return this |
| | | }, |
| | | then () { |
| | | return this.__access('then', arguments) |
| | | }, |
| | | catch () { |
| | | return this.__access('catch', arguments) |
| | | }, |
| | | finally () { |
| | | return this.__access('finally', arguments) |
| | | }, |
| | | __access (methodName, args) { |
| | | if (this.__result_promise != null) { |
| | | return this.__result_promise |
| | | } |
| | | this.__result_promise = axiosInstance[method].apply(axiosInstance, this.__arguments) |
| | | this.__result_promise.then(data => { |
| | | this.__cacheImpl.setJSON(cacheKey, data) |
| | | return data |
| | | }) |
| | | return this.__result_promise[methodName].apply(this.__result_promise, args) |
| | | } |
| | | } |
| | | } |
| | | const methods = ['get', 'post', 'delete', 'put', 'head', 'options', 'patch', 'request'] |
| | | axiosInstance.cache = function (cacheKey, isLocal = false) { |
| | | if (cacheKey == null) { |
| | | throw Error('Request cache key can not be null.') |
| | | } |
| | | const cacheAxiosInstance = {} |
| | | for (const method of methods) { |
| | | cacheAxiosInstance[method] = function () { |
| | | return buildCachePromise(cacheKey, method, arguments, isLocal ? 'local' : 'session') |
| | | } |
| | | } |
| | | return cacheAxiosInstance |
| | | } |
| | | |
| | | export default axiosInstance |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å»ç©º |
| | | export function trim (data) { |
| | | if (data == null) { |
| | | return null |
| | | } |
| | | if (typeof data === 'string') { |
| | | return data.trim() |
| | | } |
| | | if (data instanceof Array) { |
| | | for (const item of data) { |
| | | trim(item) |
| | | } |
| | | } |
| | | if (typeof data === 'object') { |
| | | for (const key in data) { |
| | | data[key] = trim(data[key]) |
| | | } |
| | | } |
| | | return data |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="home"> |
| | | <div class="wrap"> |
| | | <h2>欢è¿ä½¿ç¨ä¼å¨æéå¼åæ¡æ¶</h2> |
| | | <p>æ¨ä½¿ç¨çæ¤å¥å¼æºæ¡æ¶æ²¡æä»»ä½çæé®é¢ï¼å¯å¦ä¹ å¯åç¨ï¼è¯·æ¾å¿ä½¿ç¨ï¼</p> |
| | | <p>ä¼å¨è´åäºæé ç®æ´ãåçã髿çå¼åä½éªï¼ä¸ºæ¤æä»¬å°ä¸æåçº§ï¼æè°¢æ¨çæ¯æï¼</p> |
| | | <p style="margin-top: 12px;"> |
| | | <a href="https://gitee.com/coderd-repos/eva" target="_blank">GITEE</a> |
| | | <a href="https://github.com/coderd-repos/eva" target="_blank">GITHUB</a> |
| | | </p> |
| | | <div class="guide"> |
| | | <a href="http://eva.adjustrd.com" target="_blank">åå¾å®ç½</a> |
| | | <a href="http://coderd.adjustrd.com/template/308/default" target="_blank">åå¾CodeRd</a> |
| | | </div> |
| | | <img src="@/assets/images/qq.png"> |
| | | <p>ä½ å¯ä»¥æ«ç å å
¥ç¾¤è以è·å¾ææ¯æ¯æ</p> |
| | | <div class="award"> |
| | | <h4>æ¿å±ä½è
å徿´å¥½</h4> |
| | | <img src="@/assets/images/alipay.jpeg"> |
| | | <img src="@/assets/images/wxpay.jpeg"> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'Index', |
| | | data () { |
| | | return {} |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .home { |
| | | text-align: center; |
| | | color: #777; |
| | | .wrap { |
| | | margin-top: 80px; |
| | | img { |
| | | width: 240px; |
| | | } |
| | | } |
| | | h2 { |
| | | font-size: 32px; |
| | | color: #555; |
| | | margin-bottom: 20px; |
| | | } |
| | | p { |
| | | line-height: 24px; |
| | | margin: 0; |
| | | } |
| | | .start-up { |
| | | margin-top: 8px; |
| | | } |
| | | .guide { |
| | | margin: 30px 0 40px 0; |
| | | display: flex; |
| | | justify-content: center; |
| | | a { |
| | | margin-right: 12px; |
| | | padding: 12px 40px; |
| | | border-radius: 30px; |
| | | background: $primary-color; |
| | | color: #fff; |
| | | text-decoration: none; |
| | | } |
| | | } |
| | | em,a { |
| | | font-style: normal; |
| | | font-weight: bold; |
| | | margin: 0 3px; |
| | | color: $primary-color; |
| | | } |
| | | .award { |
| | | position: absolute; |
| | | right: 20px; |
| | | bottom: 60px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | text-align: left; |
| | | padding: 12px; |
| | | border: 1px solid #eee; |
| | | box-shadow: -1px 1px 10px #ccc; |
| | | h4 { |
| | | font-weight: bold; |
| | | margin-bottom: 8px; |
| | | } |
| | | img { |
| | | width: 160px; |
| | | margin-bottom: 20px; |
| | | transition: opacity ease .3s; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="wrap"> |
| | | <div class="introduce"> |
| | | <h2>è±ç±³è·³è·³</h2> |
| | | <h3></h3> |
| | | </div> |
| | | <div class="login"> |
| | | <h1>ç³»ç»ç»å½ / LOGIN IN</h1> |
| | | <div class="info-input"> |
| | | <el-input v-model="username" placeholder="请è¾å
¥ç¨æ·å" prefix-icon="el-icon-user-solid" maxlength="50" v-trim/> |
| | | <el-input v-model="password" placeholder="请è¾å
¥å¯ç " type="password" prefix-icon="eva-icon-password" maxlength="30" show-password/> |
| | | <div class="captcha-input"> |
| | | <el-input v-model="captcha.value" placeholder="å¾çéªè¯ç " prefix-icon="eva-icon-shield" maxlength="4" @keypress.enter.native="login"/> |
| | | <img v-if="!captcha.loading" :src="captcha.uri" @click="refreshCaptcha"> |
| | | <span v-else><i class="el-icon-loading"></i></span> |
| | | </div> |
| | | </div> |
| | | <el-button :loading="loading" @click="login">ç» å½</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapMutations } from 'vuex' |
| | | import { getCaptcha, loginByPassword } from '@/api/system/common' |
| | | |
| | | export default { |
| | | name: 'Login', |
| | | data () { |
| | | return { |
| | | loading: false, |
| | | username: '', |
| | | password: '', |
| | | // éªè¯ç |
| | | captcha: { |
| | | loading: false, |
| | | value: '', |
| | | uuid: '', |
| | | uri: '' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | ...mapMutations(['setUserInfo']), |
| | | // ç»å½ |
| | | login () { |
| | | if (this.loading) { |
| | | return |
| | | } |
| | | if (!this.__check()) { |
| | | return |
| | | } |
| | | this.loading = true |
| | | loginByPassword({ |
| | | username: this.username.trim(), |
| | | password: this.password, |
| | | code: this.captcha.value.trim(), |
| | | uuid: this.captcha.uuid |
| | | }) |
| | | .then(() => { |
| | | window.location.href = process.env.VUE_APP_CONTEXT_PATH |
| | | }) |
| | | .catch(e => { |
| | | this.refreshCaptcha() |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | // å·æ°éªè¯ç |
| | | refreshCaptcha () { |
| | | this.captcha.loading = true |
| | | getCaptcha() |
| | | .then(data => { |
| | | this.captcha.uri = data.image |
| | | this.captcha.uuid = data.uuid |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | setTimeout(() => { |
| | | this.captcha.loading = false |
| | | }, 150) |
| | | }) |
| | | }, |
| | | // ç»å½åéªè¯ |
| | | __check () { |
| | | if (this.username.trim() === '') { |
| | | this.$tip.error('请è¾å
¥ç¨æ·å') |
| | | return false |
| | | } |
| | | if (this.password === '') { |
| | | this.$tip.error('请è¾å
¥å¯ç ') |
| | | return false |
| | | } |
| | | if (this.captcha.value.trim() === '') { |
| | | this.$tip.error('请è¾å
¥å¾çéªè¯ç ') |
| | | return false |
| | | } |
| | | return true |
| | | } |
| | | }, |
| | | created () { |
| | | this.refreshCaptcha() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | $input-gap: 30px; |
| | | .wrap { |
| | | display: flex; |
| | | width: 100%; |
| | | height: 100vh; |
| | | background-image: url("../assets/images/login.jpg"); |
| | | background-repeat: no-repeat; |
| | | background-size: auto 180%; |
| | | background-clip: content-box; |
| | | background-position: center; |
| | | // 左边ä»ç» |
| | | .introduce { |
| | | padding-left: 10%; |
| | | width: 100%; |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | color: #fff; |
| | | background: rgba(0, 0, 0, 0.4); |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | h2 { |
| | | font-size:34px; |
| | | font-style: italic; |
| | | font-weight: 900; |
| | | margin-top: 50px; |
| | | } |
| | | h3 { |
| | | font-size: 49px; |
| | | font-weight: 300; |
| | | margin: 25px 0; |
| | | } |
| | | } |
| | | // å³è¾¹ç»å½ |
| | | .login { |
| | | height: 100%; |
| | | width: 38%; |
| | | max-width: 560px; |
| | | min-width: 460px; |
| | | flex-shrink: 0; |
| | | text-align: center; |
| | | background: #fff; |
| | | padding: 0 80px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | box-sizing: border-box; |
| | | h1 { |
| | | font-size: 28px; |
| | | font-weight: 500; |
| | | } |
| | | .info-input { |
| | | margin-top: $input-gap; |
| | | margin-bottom: 60px; |
| | | /deep/ .el-input { |
| | | margin-top: 30px; |
| | | .el-input__inner { |
| | | height: 50px; |
| | | background: #F9F9F9; |
| | | border: 1px solid transparent; |
| | | &:focus { |
| | | border: 1px solid $primary-color; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // éªè¯ç è¾å
¥ |
| | | .captcha-input { |
| | | display: flex; |
| | | margin-top: $input-gap; |
| | | height: 50px; |
| | | .el-input { |
| | | width: 100%; |
| | | margin-top: 0; |
| | | } |
| | | span, img { |
| | | width: 45%; |
| | | height: 100%; |
| | | flex-shrink: 0; |
| | | margin-left: 16px; |
| | | } |
| | | span { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background: #f7f7f7; |
| | | border-radius: 8px; |
| | | } |
| | | } |
| | | .el-button { |
| | | height: 50px; |
| | | width: 100%; |
| | | color: #fff; |
| | | font-size: 16px; |
| | | background: linear-gradient(130deg, $primary-color + 20 0%, $primary-color - 20 100%); |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <NotAllow> |
| | | <div class="content"> |
| | | <img src="../assets/images/not-allow.png"> |
| | | <h2>æ æè®¿é®</h2> |
| | | <p>妿¨éè¦è®¿é®è¯¥ç³»ç»ï¼è¯·è系系ç»ç®¡çå</p> |
| | | <el-button @click="logout" type="primary">éåºç³»ç»</el-button> |
| | | </div> |
| | | </NotAllow> |
| | | </template> |
| | | |
| | | <script> |
| | | import NotAllow from '../components/common/NotAllow' |
| | | import { mapMutations } from 'vuex' |
| | | import { logout } from '@/api/system/common' |
| | | export default { |
| | | name: 'NoPermissions', |
| | | components: { NotAllow }, |
| | | methods: { |
| | | ...mapMutations(['setUserInfo']), |
| | | // éåºç»å½ |
| | | logout () { |
| | | logout() |
| | | .then(() => { |
| | | this.$router.push({ name: 'login' }) |
| | | this.setUserInfo(null) |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="error-404"> |
| | | <div> |
| | | <div class="left"> |
| | | <img src="../assets/images/404.png"> |
| | | <h1>æ¾ä¸å°ç½é¡µ</h1> |
| | | <p></p> |
| | | <div class="opera"> |
| | | <el-button @click="$router.back()">è¿å</el-button> |
| | | <el-button type="primary" @click="$router.push('/index')">åå¾é¦é¡µ</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="right"> |
| | | <h2>ä½ å¯ä»¥å°è¯ä»¥ä¸æä½</h2> |
| | | <p>1. å¦ææ¯æå¨æ´æ¹çç½é¡µå°åï¼è¯·æ£æ¥ç½é¡µå°åæ¯å¦æ£ç¡®</p> |
| | | <p>2. ç¹å»ãè¿åãæé®å·æ°é¡µé¢åéè¯</p> |
| | | <p>3. è系系ç»ç®¡çå</p> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'NotFound' |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .error-404 { |
| | | height: 100%; |
| | | text-align: center; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | & > div { |
| | | margin-top: -100px; |
| | | display: flex; |
| | | } |
| | | .left { |
| | | h1 { |
| | | font-size: 26px; |
| | | } |
| | | .opera { |
| | | margin-top: 30px; |
| | | } |
| | | } |
| | | .right { |
| | | text-align: left; |
| | | margin-top: 16px; |
| | | margin-left: 40px; |
| | | padding: 30px 50px; |
| | | border-radius: 16px; |
| | | background: url("../assets/images/404-tip.png") no-repeat; |
| | | background-size: 100% 100%; |
| | | box-sizing: border-box; |
| | | h2 { |
| | | font-size: 16px; |
| | | margin-bottom: 16px; |
| | | } |
| | | p { |
| | | margin: 0; |
| | | padding: 0; |
| | | font-size: 14px; |
| | | line-height: 26px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:datapermission:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline> |
| | | <el-form-item label="ä¸å¡æ¨¡å" prop="businessCode"> |
| | | <DataPermModuleSelect v-model="searchForm.businessCode" clearable @change="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²" prop="roleId"> |
| | | <RoleSelect v-model="searchForm.roleId" clearable @change="search"/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:datapermission:create', 'system:datapermission:delete']"> |
| | | <li><el-button type="primary" @click="$refs.operaDataPermissionWindow.open('æ°å»ºæ°æ®æé')" icon="el-icon-plus" v-permissions="['system:datapermission:create']">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:datapermission:delete']">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | | <el-table-column prop="businessCode" label="ä¸å¡æ¨¡å" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.businessCode | moduleText(modules)}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="roleId" label="è§è²" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.role.name}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="type" label="æéç±»å" min-width="140px"> |
| | | <template slot-scope="{row}">{{row.type | typeText(types)}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="disabled" label="æ¯å¦å¯ç¨" min-width="100px"> |
| | | <template slot-scope="{row}"> |
| | | <el-switch v-model="row.disabled" :active-value="false" :inactive-value="true" @change="switchDisabled(row)"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="remark" label="夿³¨" min-width="100px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column prop="updateUser" label="ä¿®æ¹äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="ä¿®æ¹æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:datapermission:update', 'system:datapermission:delete'])" |
| | | label="æä½" |
| | | min-width="120" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button type="text" @click="$refs.operaDataPermissionWindow.open('ç¼è¾æ°æ®æé', row)" icon="el-icon-edit" v-permissions="['system:datapermission:update']">ç¼è¾</el-button> |
| | | <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:datapermission:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | > |
| | | </pagination> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaDataPermissionWindow ref="operaDataPermissionWindow" @success="handlePageChange"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import Pagination from '@/components/common/Pagination' |
| | | import OperaDataPermissionWindow from '@/components/system/datapermission/OperaDataPermissionWindow' |
| | | import DataPermModuleSelect from '@/components/system/datapermission/DataPermModuleSelect' |
| | | import RoleSelect from '../../components/system/role/RoleSelect' |
| | | |
| | | // è·å模ååç§° |
| | | const __getModuleName = function (businessCode, modules) { |
| | | for (const module of modules) { |
| | | if (module.businessCode === businessCode) { |
| | | return module.moduleName |
| | | } |
| | | } |
| | | return 'æªç¥' |
| | | } |
| | | |
| | | export default { |
| | | name: 'DataPermission', |
| | | extends: BaseTable, |
| | | components: { RoleSelect, DataPermModuleSelect, TableLayout, Pagination, OperaDataPermissionWindow }, |
| | | data () { |
| | | return { |
| | | // æ°æ®æé模å |
| | | modules: [], |
| | | // æ°æ®æéç±»å |
| | | types: [], |
| | | // æç´¢ |
| | | searchForm: { |
| | | businessCode: '', |
| | | roleId: null, |
| | | type: '' |
| | | } |
| | | } |
| | | }, |
| | | filters: { |
| | | // æ°æ®æéç±»åææ¡ |
| | | typeText (value, types) { |
| | | for (const type of types) { |
| | | if (type.code === value) { |
| | | return type.remark |
| | | } |
| | | } |
| | | return 'æªç¥' |
| | | }, |
| | | // æ°æ®æéæ¨¡åææ¡ |
| | | moduleText (value, modules) { |
| | | return __getModuleName(value, modules) |
| | | } |
| | | }, |
| | | methods: { |
| | | // å¯ç¨/ç¦ç¨èå |
| | | switchDisabled (row) { |
| | | if (!row.disabled) { |
| | | this.__updateStatus(row) |
| | | return |
| | | } |
| | | this.$dialog.disableConfirm(`确认ç¦ç¨ ${__getModuleName(row.businessCode, this.modules)}/${row.role.name} æ°æ®æéåï¼`) |
| | | .then(() => { |
| | | this.__updateStatus(row) |
| | | }).catch(() => { |
| | | row.disabled = !row.disabled |
| | | }) |
| | | }, |
| | | // å é¤è¡ |
| | | deleteById (row) { |
| | | this.$dialog.deleteConfirm(`确认å é¤ã${__getModuleName(row.businessCode, this.modules)}/${row.role.name}ãæ°æ®æéåï¼`) |
| | | .then(() => { |
| | | this.isWorking.delete = true |
| | | this.api.deleteById(row.id) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('å 餿å') |
| | | this.__afterDelete() |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.delete = false |
| | | }) |
| | | }) |
| | | .catch(() => {}) |
| | | }, |
| | | // ä¿®æ¹ç¶æ |
| | | __updateStatus (row) { |
| | | this.api.updateStatus({ |
| | | id: row.id, |
| | | disabled: row.disabled |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('ä¿®æ¹æå') |
| | | }) |
| | | .catch(e => { |
| | | row.disabled = !row.disabled |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | } |
| | | }, |
| | | async created () { |
| | | this.config({ |
| | | module: 'æ°æ®æé', |
| | | api: '/system/dataPermission' |
| | | }) |
| | | // åå§åæ°æ®æé模å |
| | | await this.api.fetchModules() |
| | | .then(data => { |
| | | this.modules = data |
| | | }) |
| | | // åå§åæ°æ®æé模å |
| | | await this.api.fetchTypes() |
| | | .then(data => { |
| | | this.types = data |
| | | }) |
| | | .catch(e => { |
| | | console.log(e) |
| | | }) |
| | | // æ§è¡æç´¢ |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:department:query']"> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:department:create', 'system:department:delete']"> |
| | | <li><el-button type="primary" @click="$refs.operaDepartmentWindow.open('æ°å»ºé¨é¨')" icon="el-icon-plus" v-permissions="['system:department:create']">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:department:delete']">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | row-key="id" |
| | | stripe |
| | | default-expand-all |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" fixed="left" width="55"></el-table-column> |
| | | <el-table-column prop="name" label="é¨é¨åç§°" fixed="left" min-width="200px"></el-table-column> |
| | | <el-table-column prop="code" label="é¨é¨ç¼ç " fixed="left" min-width="100px"></el-table-column> |
| | | <el-table-column prop="userCount" label="é¨é¨äººæ°" min-width="100px"></el-table-column> |
| | | <el-table-column prop="phone" label="èç³»çµè¯" min-width="100px"></el-table-column> |
| | | <el-table-column prop="email" label="é¨é¨é®ç®±" min-width="180px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:department:update', 'system:department:create', 'system:department:delete', 'system:department:queryUsers'])" |
| | | label="æä½" |
| | | min-width="310" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button type="text" @click="$refs.operaDepartmentWindow.open('ç¼è¾é¨é¨', row)" icon="el-icon-edit" v-permissions="['system:department:update']">ç¼è¾</el-button> |
| | | <el-button type="text" @click="$refs.operaDepartmentWindow.open('æ°å»ºä¸çº§é¨é¨', null, row)" icon="el-icon-edit" v-permissions="['system:department:create']">æ°å»ºä¸çº§é¨é¨</el-button> |
| | | <el-button type="text" @click="$refs.departmentUserWindow.open(row.id, row.name)" icon="el-icon-user-solid" v-permissions="['system:department:queryUsers']">æ¥ç人å</el-button> |
| | | <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:department:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaDepartmentWindow ref="operaDepartmentWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | <!-- æ¥ç人å --> |
| | | <DepartmentUserWindow ref="departmentUserWindow"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import { fetchTree } from '@/api/system/department' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaDepartmentWindow from '@/components/system/department/OperaDepartmentWindow' |
| | | import DepartmentUserWindow from '@/components/system/department/DepartmentUserWindow' |
| | | export default { |
| | | name: 'SystemDepartment', |
| | | extends: BaseTable, |
| | | components: { DepartmentUserWindow, OperaDepartmentWindow, TableLayout }, |
| | | data () { |
| | | return { |
| | | // æç´¢ |
| | | searchForm: { |
| | | name: '' |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // æ¥è¯¢æ°æ® |
| | | handlePageChange () { |
| | | this.tableData.list.splice(0, this.tableData.list.length) |
| | | this.isWorking.search = true |
| | | fetchTree() |
| | | .then(records => { |
| | | this.tableData.list = records |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.search = false |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'é¨é¨', |
| | | api: '/system/department' |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .table-layout { |
| | | /deep/ .table-content { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:dict:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline> |
| | | <el-form-item label="åå
¸ç¼ç " prop="code"> |
| | | <el-input v-model="searchForm.code" v-trim placeholder="请è¾å
¥åå
¸ç¼ç " @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸åç§°" prop="name"> |
| | | <el-input v-model="searchForm.name" v-trim placeholder="请è¾å
¥åå
¸åç§°" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:dict:create', 'system:dict:delete']"> |
| | | <li><el-button type="primary" @click="$refs.operaDictWindow.open('æ°å»ºåå
¸')" icon="el-icon-plus" v-permissions="['system:dict:create']">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:dict:delete']">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :default-sort = "{prop: 'createTime', order: 'descending'}" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" fixed="left" width="55"></el-table-column> |
| | | <el-table-column prop="code" label="åå
¸ç¼ç " fixed="left" min-width="100px"></el-table-column> |
| | | <el-table-column prop="name" label="åå
¸åç§°" fixed="left" min-width="100px"></el-table-column> |
| | | <el-table-column prop="remark" label="夿³¨" min-width="100px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px" sortable="custom" sort-by="dict.CREATE_TIME"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:dict:update', 'system:dict:delete'])" |
| | | label="æä½" |
| | | min-width="210" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button type="text" @click="$refs.operaDictWindow.open('ç¼è¾åå
¸', row)" icon="el-icon-edit" v-permissions="['system:dict:update']">ç¼è¾</el-button> |
| | | <el-button type="text" @click="$refs.dictDataManagerWindow.open(row.id, row.name)" icon="el-icon-edit" v-permissions="['system:dict:update']">æ°æ®ç®¡ç</el-button> |
| | | <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:dict:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaDictWindow ref="operaDictWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | <!-- æ°æ®ç®¡ç --> |
| | | <DictDataManagerWindow ref="dictDataManagerWindow"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import Pagination from '@/components/common/Pagination' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaDictWindow from '@/components/system/dict/OperaDictWindow' |
| | | import DictDataManagerWindow from '@/components/system/dict/DictDataManagerWindow' |
| | | export default { |
| | | name: 'SystemDict', |
| | | extends: BaseTable, |
| | | components: { DictDataManagerWindow, OperaDictWindow, TableLayout, Pagination }, |
| | | data () { |
| | | return { |
| | | // æç´¢ |
| | | searchForm: { |
| | | code: '', |
| | | name: '' |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'åå
¸', |
| | | api: '/system/dict', |
| | | sorts: [{ |
| | | property: 'dict.CREATE_TIME', |
| | | direction: 'DESC' |
| | | }] |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:loginLog:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline> |
| | | <el-form-item label="ç»å½ç¨æ·å" prop="loginUsername"> |
| | | <el-input v-model="searchForm.loginUsername" placeholder="请è¾å
¥ç»å½ç¨æ·å" @keypress.enter.native="search"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ç»å½IP" prop="ip"> |
| | | <el-input v-model="searchForm.ip" placeholder="请è¾å
¥ç»å½IP" @keypress.enter.native="search"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="æå¡å¨IP" prop="serverIp"> |
| | | <el-input v-model="searchForm.serverIp" placeholder="请è¾å
¥æå¡å¨IP" @keypress.enter.native="search"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="æ¯å¦ç»å½æå" prop="success"> |
| | | <el-select v-model="searchForm.success" placeholder="è¯·éæ©æ¯å¦ç»å½ç¶æ" clearable @change="search"> |
| | | <el-option value="true" label="ç»å½æå"/> |
| | | <el-option value="false" label="ç»å½å¤±è´¥"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç»å½æ¶é´" prop="loginTime"> |
| | | <el-date-picker |
| | | v-model="searchDateRange" |
| | | type="datetimerange" |
| | | range-separator="è³" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | start-placeholder="å¼å§æ¶é´" |
| | | end-placeholder="ç»ææ¶é´" |
| | | @change="handleSearchTimeChange" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" @click="search">æç´¢</el-button> |
| | | <el-button type="primary" :loading="isWorking.export" @click="exportExcel">导åº</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | stripe |
| | | :default-sort="{prop: 'loginTime', order: 'descending'}" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column prop="loginUsername" label="ç»å½ç¨æ·å" min-width="100px"></el-table-column> |
| | | <el-table-column prop="ip" label="ç»å½IP" min-width="120px"></el-table-column> |
| | | <el-table-column prop="location" label="ç»å½å°å" min-width="160px"></el-table-column> |
| | | <el-table-column prop="clientInfo" label="客æ·ç«¯" min-width="160px"></el-table-column> |
| | | <el-table-column prop="osInfo" label="æä½ç³»ç»" min-width="100px"></el-table-column> |
| | | <el-table-column prop="platform" label="ç»å½å¹³å°" min-width="100px"></el-table-column> |
| | | <el-table-column prop="loginTime" label="ç»å½æ¶é´" min-width="160px" sortable="custom" sort-by="LOGIN_TIME"></el-table-column> |
| | | <el-table-column prop="systemVersion" label="ç³»ç»çæ¬" min-width="100px"></el-table-column> |
| | | <el-table-column prop="serverIp" label="æå¡å¨IP" min-width="120px"></el-table-column> |
| | | <el-table-column prop="success" label="ç¶æ" min-width="100px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.success | statusText}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="reason" label="失败åå " min-width="160px"></el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import Pagination from '@/components/common/Pagination' |
| | | |
| | | export default { |
| | | name: 'SystemLoginLog', |
| | | extends: BaseTable, |
| | | components: { TableLayout, Pagination }, |
| | | data () { |
| | | return { |
| | | // æç´¢æ¶é´èå´ |
| | | searchDateRange: [], |
| | | // æç´¢ |
| | | searchForm: { |
| | | loginUsername: '', |
| | | ip: '', |
| | | serverIp: '', |
| | | success: '', |
| | | startTime: null, |
| | | endTime: null |
| | | } |
| | | } |
| | | }, |
| | | filters: { |
| | | // ç»å½ç¶æ |
| | | statusText (value) { |
| | | if (value) { |
| | | return 'ç»å½æå' |
| | | } |
| | | return 'ç»å½å¤±è´¥' |
| | | } |
| | | }, |
| | | methods: { |
| | | // æ¶é´æç´¢èå´åå |
| | | handleSearchTimeChange (value) { |
| | | this.searchForm.startTime = null |
| | | this.searchForm.endTime = null |
| | | if (value != null) { |
| | | this.searchForm.startTime = value[0] |
| | | this.searchForm.endTime = value[1] |
| | | } |
| | | this.search() |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'ç»å½æ¥å¿', |
| | | api: '/system/loginLog', |
| | | 'field.id': 'id', |
| | | 'field.main': 'id', |
| | | sorts: [{ |
| | | property: 'LOGIN_TIME', |
| | | direction: 'DESC' |
| | | }] |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout class="menu-layout" :permissions="['system:menu:query']"> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:menu:create', 'system:menu:delete', 'system:menu:sort']"> |
| | | <li><el-button type="primary" @click="$refs.operaMenuWindow.open('æ°å»ºä¸çº§èå')" icon="el-icon-plus" v-permissions="['system:menu:create']">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:menu:delete']">å é¤</el-button></li> |
| | | <li><el-button @click="sort('top')" :loading="isWorking.sort" icon="el-icon-sort-up" v-permissions="['system:menu:sort']">ä¸ç§»</el-button></li> |
| | | <li><el-button @click="sort('bottom')" :loading="isWorking.sort" icon="el-icon-sort-down" v-permissions="['system:menu:sort']">ä¸ç§»</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | ref="table" |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | row-key="id" |
| | | stripe |
| | | default-expand-all |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55" fixed="left"></el-table-column> |
| | | <el-table-column prop="name" label="èååç§°" fixed="left" min-width="160px"></el-table-column> |
| | | <el-table-column prop="icon" label="徿 " min-width="80px" class-name="table-column-icon"> |
| | | <template slot-scope="{row}"> |
| | | <i v-if="row.icon != null && row.icon !== ''" :class="{[row.icon]: true}"></i> |
| | | <template v-else>æªè®¾ç½®</template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="path" label="访é®è·¯å¾" min-width="140px"></el-table-column> |
| | | <el-table-column prop="remark" label="夿³¨" min-width="120px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column prop="disabled" label="æ¯å¦å¯ç¨" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | <el-switch v-model="row.disabled" :active-value="false" :inactive-value="true" @change="switchDisabled(row)"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:menu:update', 'system:menu:create', 'system:menu:delete'])" |
| | | label="æä½" |
| | | min-width="220" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button type="text" icon="el-icon-edit" @click="$refs.operaMenuWindow.open('ç¼è¾èå', row)" v-permissions="['system:menu:update']">ç¼è¾</el-button> |
| | | <el-button type="text" icon="el-icon-plus" @click="$refs.operaMenuWindow.open('æ°å»ºåèå', null, row)" v-permissions="['system:menu:create']">æ°å»ºåèå</el-button> |
| | | <el-button v-if="!row.fixed" type="text" icon="el-icon-delete" @click="deleteById(row)" v-permissions="['system:menu:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaMenuWindow ref="operaMenuWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaMenuWindow from '@/components/system/menu/OperaMenuWindow' |
| | | import { fetchTree, updateStatus, sort } from '@/api/system/menu' |
| | | export default { |
| | | name: 'SystemMenu', |
| | | extends: BaseTable, |
| | | components: { OperaMenuWindow, TableLayout }, |
| | | data () { |
| | | return { |
| | | // æ¯å¦æ£å¨å¤çä¸ |
| | | isWorking: { |
| | | sort: false |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // æ¥è¯¢æ°æ® |
| | | handlePageChange () { |
| | | this.isWorking.search = true |
| | | fetchTree() |
| | | .then(records => { |
| | | this.tableData.list = records |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.search = false |
| | | }) |
| | | }, |
| | | // æåº |
| | | sort (direction) { |
| | | if (this.isWorking.sort) { |
| | | return |
| | | } |
| | | if (this.tableData.selectedRows.length === 0) { |
| | | this.$tip.warning('è¯·éæ©ä¸æ¡æ°æ®') |
| | | return |
| | | } |
| | | if (this.tableData.selectedRows.length > 1) { |
| | | this.$tip.warning('æåºæ¶ä»
å
è®¸éæ©ä¸æ¡æ°æ®') |
| | | return |
| | | } |
| | | const menuId = this.tableData.selectedRows[0].id |
| | | // æ¾å°èåèå´ |
| | | let menuPool |
| | | for (const rootMenu of this.tableData.list) { |
| | | const parent = this.__findParent(menuId, rootMenu) |
| | | if (parent != null) { |
| | | menuPool = parent.children |
| | | } |
| | | } |
| | | menuPool = menuPool || this.tableData.list |
| | | const menuIndex = menuPool.findIndex(menu => menu.id === menuId) |
| | | // ä¸ç§»æ ¡éª |
| | | if (direction === 'top' && menuIndex === 0) { |
| | | this.$tip.warning('èåå·²å°é¡¶é¨') |
| | | return |
| | | } |
| | | // ä¸ç§»æ ¡éª |
| | | if (direction === 'bottom' && menuIndex === menuPool.length - 1) { |
| | | this.$tip.warning('èåå·²å°åºé¨') |
| | | return |
| | | } |
| | | this.isWorking.sort = true |
| | | sort({ |
| | | id: this.tableData.selectedRows[0].id, |
| | | direction |
| | | }) |
| | | .then(() => { |
| | | if (direction === 'top') { |
| | | menuPool.splice(menuIndex, 0, menuPool.splice(menuIndex - 1, 1)[0]) |
| | | } else { |
| | | menuPool.splice(menuIndex, 0, menuPool.splice(menuIndex + 1, 1)[0]) |
| | | } |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.sort = false |
| | | }) |
| | | }, |
| | | // å¯ç¨/ç¦ç¨èå |
| | | switchDisabled (row) { |
| | | if (!row.disabled) { |
| | | this.__updateMenuStatus(row) |
| | | return |
| | | } |
| | | this.$dialog.disableConfirm(`确认ç¦ç¨ ${row.name} èååï¼`) |
| | | .then(() => { |
| | | this.__updateMenuStatus(row) |
| | | }).catch(() => { |
| | | row.disabled = !row.disabled |
| | | }) |
| | | }, |
| | | // æ¥è¯¢ç¶èç¹ |
| | | __findParent (id, parent) { |
| | | if (parent.children === 0) { |
| | | return |
| | | } |
| | | for (const menu of parent.children) { |
| | | if (menu.id === id) { |
| | | return parent |
| | | } |
| | | if (menu.children.length > 0) { |
| | | const m = this.__findParent(id, menu) |
| | | if (m != null) { |
| | | return m |
| | | } |
| | | } |
| | | } |
| | | return null |
| | | }, |
| | | // ä¿®æ¹èåç¶æ |
| | | __updateMenuStatus (row) { |
| | | updateStatus({ |
| | | id: row.id, |
| | | parentId: row.parentId, |
| | | disabled: row.disabled |
| | | }) |
| | | .then(() => { |
| | | this.$tip.apiSuccess('ä¿®æ¹æå') |
| | | }) |
| | | .catch(e => { |
| | | row.disabled = !row.disabled |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'èå', |
| | | api: '/system/menu' |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "@/assets/style/variables.scss"; |
| | | .menu-layout { |
| | | /deep/ .table-content { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | // 徿 å |
| | | .table-column-icon { |
| | | // element-ui徿 |
| | | i { |
| | | background-color: $primary-color; |
| | | opacity: 0.72; |
| | | font-size: 20px; |
| | | color: #fff; |
| | | padding: 4px; |
| | | border-radius: 50%; |
| | | } |
| | | // èªå®ä¹å¾æ |
| | | [class^="eva-icon-"] { |
| | | width: 20px; |
| | | height: 20px; |
| | | background-size: 16px; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <Profile :permissions="['system:monitor:query']"> |
| | | <div class="monitor"> |
| | | <div class="toolbar"> |
| | | <el-switch v-model="autoRefresh" @change="changeAutoRefresh"/><label>{{autoRefresh | autoRefreshText}}</label> |
| | | </div> |
| | | <ul> |
| | | <li class="wrap"> |
| | | <h2>CPU<Light v-if="data != null" :warn="data.cpu.useRatio > 60" :danger="data.cpu.useRatio > 80"/></h2> |
| | | <div> |
| | | <dl> |
| | | <dt>ç©çæ ¸æ°</dt> |
| | | <dd><Value :data="data" prop="cpu.physicalCount"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>é»è¾æ ¸æ°</dt> |
| | | <dd><Value :data="data" prop="cpu.logicalCount"/></dd> |
| | | </dl> |
| | | <dl class="important"> |
| | | <dt>å½å使ç¨ç</dt> |
| | | <dd><Value :data="data" prop="cpu.useRatio" :handler="keep2decimals" suffix="%"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>å½å空é²ç</dt> |
| | | <dd><Value :data="data" prop="cpu.freeRatio" :handler="keep2decimals" suffix="%"/></dd> |
| | | </dl> |
| | | </div> |
| | | </li> |
| | | <li class="wrap"> |
| | | <h2>å
å<Light v-if="data != null" :warn="data.memory.useRatio > 60" :danger="data.memory.useRatio > 80"/></h2> |
| | | <div> |
| | | <dl> |
| | | <dt>æ»ç©ºé´</dt> |
| | | <dd><Value :data="data" prop="memory.size" suffix="G" :handler="toG"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>空é²ç©ºé´</dt> |
| | | <dd><Value :data="data" prop="memory.freeSpace" suffix="G" :handler="toG"/></dd> |
| | | </dl> |
| | | <dl class="important"> |
| | | <dt>å·²ç¨ç©ºé´</dt> |
| | | <dd><Value :data="data" prop="memory.usedSpace" suffix="G" :handler="toG"/></dd> |
| | | </dl> |
| | | <dl class="important"> |
| | | <dt>使ç¨ç</dt> |
| | | <dd><Value :data="data" prop="memory.useRatio" suffix="%" :handler="keep2decimals"/></dd> |
| | | </dl> |
| | | </div> |
| | | </li> |
| | | <li class="wrap"> |
| | | <h2>JVM<Light v-if="data != null" :warn="data.jvm.memory.useRatio > 60" :danger="data.jvm.memory.useRatio > 80"/></h2> |
| | | <div> |
| | | <dl> |
| | | <dt>å®è£
è·¯å¾</dt> |
| | | <dd><Value :data="data" prop="jvm.home"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>çæ¬</dt> |
| | | <dd><Value :data="data" prop="jvm.version"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>å¯å¨æ¶é´</dt> |
| | | <dd><Value :data="data" prop="jvm.bootTime"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>è¿è¡æ¶é¿</dt> |
| | | <dd><Value :data="data" prop="jvm.runtime"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>æ»ç©ºé´</dt> |
| | | <dd><Value :data="data" prop="jvm.memory.size" suffix="M" :handler="keep2decimals"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>空é²ç©ºé´</dt> |
| | | <dd><Value :data="data" prop="jvm.memory.freeSpace" suffix="M" :handler="keep2decimals"/></dd> |
| | | </dl> |
| | | <dl class="important"> |
| | | <dt>å·²ç¨ç©ºé´</dt> |
| | | <dd><Value :data="data" prop="jvm.memory.usedSpace" suffix="M" :handler="keep2decimals"/></dd> |
| | | </dl> |
| | | <dl class="important"> |
| | | <dt>使ç¨ç</dt> |
| | | <dd><Value :data="data" prop="jvm.memory.useRatio" suffix="%" :handler="keep2decimals"/></dd> |
| | | </dl> |
| | | </div> |
| | | </li> |
| | | <li class="wrap"> |
| | | <h2>æå¡å¨</h2> |
| | | <div> |
| | | <dl> |
| | | <dt>æä½ç³»ç»</dt> |
| | | <dd><Value :data="data" prop="osName"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>ç³»ç»çæ¬</dt> |
| | | <dd><Value :data="data" prop="osVersion"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>ç³»ç»æ¶æ</dt> |
| | | <dd><Value :data="data" prop="osArch"/></dd> |
| | | </dl> |
| | | <dl class="important"> |
| | | <dt>IPå°å</dt> |
| | | <dd><Value :data="data" prop="ip"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>MACå°å</dt> |
| | | <dd><Value :data="data" prop="mac"/></dd> |
| | | </dl> |
| | | <dl> |
| | | <dt>æå¡å¨æ¶é´</dt> |
| | | <dd><Value :data="data" prop="currentTime"/></dd> |
| | | </dl> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | | <div class="wrap"> |
| | | <h2>ç£çä¿¡æ¯</h2> |
| | | <el-table :data="data ? data.disks : []" v-loading="loading"> |
| | | <el-table-column prop="name" label="ç£çåç§°"/> |
| | | <el-table-column prop="dir" label="ç£çè·¯å¾"/> |
| | | <el-table-column prop="fsType" label="æä»¶ç³»ç»"/> |
| | | <el-table-column prop="size" label="æ»ç©ºé´"> |
| | | <template slot-scope="{row}"> |
| | | {{toG(row.size)}}G |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="freeSpace" label="å¯ç¨ç©ºé´"> |
| | | <template slot-scope="{row}"> |
| | | {{toG(row.freeSpace)}}G |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="usedSpace" label="å·²ç¨ç©ºé´"> |
| | | <template slot-scope="{row}"> |
| | | <label class="important">{{toG(row.usedSpace)}}G</label> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="useRatio" label="å·²ç¨å æ¯"> |
| | | <template slot-scope="{row}"> |
| | | <label class="important">{{keep2decimals(row.useRatio)}}%</label> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column> |
| | | <template slot-scope="{row}"> |
| | | <Light :warn="row.useRatio > 60" :danger="row.useRatio > 80" :mini="true"/> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </Profile> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getSystemInfo } from '@/api/system/monitor' |
| | | import Value from '@/components/common/Value' |
| | | import Light from '@/components/common/Light' |
| | | import Profile from '../../components/common/Profile' |
| | | |
| | | export default { |
| | | name: 'SystemMonitor', |
| | | components: { Profile, Light, Value }, |
| | | data () { |
| | | return { |
| | | // å è½½ä¸ |
| | | loading: false, |
| | | // èªå¨å·æ°æ è¯ |
| | | autoRefresh: false, |
| | | // æ°æ® |
| | | data: null, |
| | | // èªå¨å·æ°å®æ¶å¨ |
| | | interval: null |
| | | } |
| | | }, |
| | | filters: { |
| | | autoRefreshText (value) { |
| | | if (value) { |
| | | return 'å·²å¼å¯èªå¨å·æ°' |
| | | } |
| | | return 'å·²å
³éèªå¨å·æ°' |
| | | } |
| | | }, |
| | | methods: { |
| | | // 忢èªå¨å·æ° |
| | | changeAutoRefresh (value) { |
| | | if (this.interval != null) { |
| | | clearInterval(this.interval) |
| | | } |
| | | if (value) { |
| | | this.getSystemInfo() |
| | | this.interval = setInterval(() => { |
| | | this.getSystemInfo() |
| | | }, 3000) |
| | | } |
| | | }, |
| | | // è·åç³»ç»ä¿¡æ¯ |
| | | getSystemInfo () { |
| | | if (this.loading) { |
| | | return |
| | | } |
| | | this.loading = true |
| | | getSystemInfo() |
| | | .then(data => { |
| | | this.data = data |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | // åä½è½¬ä¸ºG |
| | | toG (value) { |
| | | return Math.round(value / 1024 * 100) / 100 |
| | | }, |
| | | // 转为æ¯ç |
| | | keep2decimals (value) { |
| | | return Math.round(value * 100) / 100 |
| | | } |
| | | }, |
| | | beforeRouteLeave (from, to, next) { |
| | | clearInterval(this.interval) |
| | | next() |
| | | }, |
| | | created () { |
| | | this.getSystemInfo() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | .monitor { |
| | | padding: 20px 20px; |
| | | } |
| | | // å·¥å
·æ |
| | | .toolbar { |
| | | margin-bottom: 12px; |
| | | background: #fff; |
| | | padding: 8px 16px; |
| | | label { |
| | | font-size: 12px; |
| | | margin-left: 8px; |
| | | color: #999; |
| | | } |
| | | } |
| | | ul { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | li { |
| | | width: 49.5%; |
| | | min-height: 200px; |
| | | flex-shrink: 0; |
| | | } |
| | | } |
| | | // ä¿¡æ¯æ¨¡å |
| | | .wrap { |
| | | background: #fff; |
| | | box-shadow: 2px 2px 10px -5px #999; |
| | | border-radius: 8px; |
| | | margin-bottom: 16px; |
| | | h2 { |
| | | border-bottom: 1px solid #eee; |
| | | font-size: 18px; |
| | | font-weight: normal; |
| | | line-height: 40px; |
| | | padding: 0 16px; |
| | | color: #555; |
| | | position: relative; |
| | | .light { |
| | | position: absolute; |
| | | top: 12px; |
| | | right: 12px; |
| | | } |
| | | } |
| | | & > div { |
| | | padding: 0 16px; |
| | | font-size: 14px; |
| | | dl { |
| | | display: flex; |
| | | dt { |
| | | width: 80px; |
| | | text-align: right; |
| | | flex-shrink: 0; |
| | | color: #999; |
| | | } |
| | | dd { |
| | | width: 100%; |
| | | margin: 0; |
| | | padding-left: 12px; |
| | | color: #555; |
| | | overflow: hidden; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // éè¦ä¿¡æ¯ |
| | | .important { |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | & > dd > div { |
| | | color: $primary-color; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:permission:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline> |
| | | <el-form-item label="æéç¼ç " prop="code"> |
| | | <el-input v-model="searchForm.code" v-trim placeholder="请è¾å
¥æéç¼ç " @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="æéåç§°" prop="name"> |
| | | <el-input v-model="searchForm.name" v-trim placeholder="请è¾å
¥æéåç§°" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:permission:create', 'system:permission:delete']"> |
| | | <li><el-button type="primary" @click="$refs.operaPermissionWindow.open('æ°å»ºç³»ç»æé')" icon="el-icon-plus" v-permissions="['system:permission:create']">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:permission:delete']">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :default-sort = "{prop: 'createTime', order: 'descending'}" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" fixed="left" width="55"></el-table-column> |
| | | <el-table-column prop="code" label="æéç¼ç " fixed="left" min-width="200px"></el-table-column> |
| | | <el-table-column prop="name" label="æéåç§°" fixed="left" min-width="120px"></el-table-column> |
| | | <el-table-column prop="remark" label="æé夿³¨" min-width="120px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px" sortable="custom" sort-by="perm.CREATE_TIME"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:permission:update', 'system:permission:delete'])" |
| | | label="æä½" |
| | | min-width="130" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button v-if="!row.fixed" type="text" @click="$refs.operaPermissionWindow.open('ç¼è¾ç³»ç»æé', row)" icon="el-icon-edit" v-permissions="['system:permission:update']">ç¼è¾</el-button> |
| | | <el-button v-if="!row.fixed" type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:permission:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaPermissionWindow ref="operaPermissionWindow" @success="handlePageChange"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import Pagination from '@/components/common/Pagination' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaPermissionWindow from '@/components/system/permission/OperaPermissionWindow' |
| | | export default { |
| | | name: 'SystemPermission', |
| | | extends: BaseTable, |
| | | components: { OperaPermissionWindow, TableLayout, Pagination }, |
| | | data () { |
| | | return { |
| | | // æç´¢ |
| | | searchForm: { |
| | | code: '', |
| | | name: '', |
| | | remark: '' |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'æé', |
| | | api: '/system/permission', |
| | | sorts: [{ |
| | | property: 'perm.CREATE_TIME', |
| | | direction: 'DESC' |
| | | }] |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:position:query']"> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:position:create', 'system:position:delete']"> |
| | | <li><el-button type="primary" @click="$refs.operaPositionWindow.open('æ°å»ºå²ä½')" icon="el-icon-plus" v-permissions="['system:position:create']">æ°å»º</el-button></li> |
| | | <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['system:position:delete']">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | row-key="id" |
| | | stripe |
| | | default-expand-all |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55" fixed="left"></el-table-column> |
| | | <el-table-column prop="name" label="å²ä½åç§°" fixed="left" min-width="200px"></el-table-column> |
| | | <el-table-column prop="code" label="å²ä½ç¼ç " fixed="left" min-width="100px"></el-table-column> |
| | | <el-table-column prop="userCount" label="å²ä½äººæ°" min-width="100px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:position:update', 'system:position:query', 'system:position:delete'])" |
| | | label="æä½" |
| | | min-width="310" |
| | | fixed="right" |
| | | > |
| | | <template slot-scope="{row}"> |
| | | <el-button type="text" @click="$refs.operaPositionWindow.open('ç¼è¾å²ä½', row)" icon="el-icon-edit" v-permissions="['system:position:update']">ç¼è¾</el-button> |
| | | <el-button type="text" @click="$refs.operaPositionWindow.open('æ°å¢ä¸çº§å²ä½', null, row)" icon="el-icon-edit" v-permissions="['system:position:update']">æ°å¢ä¸çº§å²ä½</el-button> |
| | | <el-button type="text" @click="$refs.positionUserWindow.open(row.id, row.name)" icon="el-icon-user-solid" v-permissions="['system:position:queryUsers']">æ¥ç人å</el-button> |
| | | <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:position:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaPositionWindow ref="operaPositionWindow" @success="handlePageChange"/> |
| | | <!-- 人å管ç --> |
| | | <PositionUserWindow ref="positionUserWindow"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaPositionWindow from '@/components/system/position/OperaPositionWindow' |
| | | import PositionUserWindow from '@/components/system/position/PositionUserWindow' |
| | | import { fetchTree } from '@/api/system/position' |
| | | export default { |
| | | name: 'SystemPosition', |
| | | extends: BaseTable, |
| | | components: { PositionUserWindow, OperaPositionWindow, TableLayout }, |
| | | methods: { |
| | | // æ¥è¯¢æ°æ® |
| | | handlePageChange () { |
| | | this.isWorking.search = true |
| | | fetchTree() |
| | | .then(records => { |
| | | this.tableData.list = records |
| | | }) |
| | | .catch(e => { |
| | | this.$tip.apiFailed(e) |
| | | }) |
| | | .finally(() => { |
| | | this.isWorking.search = false |
| | | }) |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'å²ä½', |
| | | api: '/system/position' |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | .table-layout { |
| | | /deep/ .table-content { |
| | | margin-top: 0; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:role:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline> |
| | | <el-form-item label="è§è²ç¼ç " prop="code"> |
| | | <el-input v-model="searchForm.code" v-trim placeholder="请è¾å
¥è§è²ç¼ç " @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²åç§°" prop="name"> |
| | | <el-input v-model="searchForm.name" v-trim placeholder="请è¾å
¥è§è²åç§°" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" icon="el-icon-search" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:role:create', 'system:role:delete']"> |
| | | <li v-permissions="['system:role:create']"><el-button type="primary" @click="$refs.operaRoleWindow.open('æ°å»ºè§è²')" icon="el-icon-plus">æ°å»º</el-button></li> |
| | | <li v-permissions="['system:role:delete']"><el-button @click="deleteByIdInBatch" icon="el-icon-delete">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :default-sort = "{prop: 'createTime', order: 'descending'}" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" fixed="left" width="55"></el-table-column> |
| | | <el-table-column prop="code" label="è§è²ç¼ç " fixed="left" min-width="100px"></el-table-column> |
| | | <el-table-column prop="name" label="è§è²åç§°" fixed="left" min-width="100px"></el-table-column> |
| | | <el-table-column prop="remark" label="è§è²å¤æ³¨" min-width="120px"></el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" min-width="140px" sortable="custom" sort-by="role.CREATE_TIME"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:role:update', 'system:role:createRolePermission', 'system:role:createRoleMenu', 'system:role:delete'])" |
| | | label="æä½" |
| | | min-width="270" |
| | | fixed="right" |
| | | > |
| | | <template v-if="isAdmin || (row.code !== adminCode && userInfo.roles.findIndex(code => code === row.code) === -1)" slot-scope="{row}"> |
| | | <el-button type="text" @click="$refs.operaRoleWindow.open('ç¼è¾è§è²', row)" icon="el-icon-edit" v-permissions="['system:role:update']">ç¼è¾</el-button> |
| | | <el-button type="text" @click="$refs.permissionConfigWindow.open(row)" v-permissions="['system:role:createRolePermission']">é
ç½®æé</el-button> |
| | | <el-button type="text" @click="$refs.menuConfigWindow.open(row)" icon="el-icon-menu" v-permissions="['system:role:createRoleMenu']">ææèå</el-button> |
| | | <el-button v-if="!row.fixed" type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['system:role:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaRoleWindow ref="operaRoleWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | <!-- é
ç½®æé --> |
| | | <PermissionConfigWindow ref="permissionConfigWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | <!-- ææèå --> |
| | | <MenuConfigWindow ref="menuConfigWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import Pagination from '@/components/common/Pagination' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaRoleWindow from '@/components/system/role/OperaRoleWindow' |
| | | import PermissionConfigWindow from '@/components/system/role/PermissionConfigWindow' |
| | | import MenuConfigWindow from '@/components/system/role/MenuConfigWindow' |
| | | export default { |
| | | name: 'SystemRole', |
| | | extends: BaseTable, |
| | | components: { MenuConfigWindow, PermissionConfigWindow, OperaRoleWindow, TableLayout, Pagination }, |
| | | data () { |
| | | return { |
| | | // æç´¢ |
| | | searchForm: { |
| | | code: '', |
| | | name: '', |
| | | remark: '' |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'è§è²', |
| | | api: '/system/role', |
| | | sorts: [{ |
| | | property: 'role.CREATE_TIME', |
| | | direction: 'DESC' |
| | | }] |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:traceLog:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline> |
| | | <el-form-item label="ç¨æ·å§å" prop="userRealname"> |
| | | <el-input v-model="searchForm.userRealname" placeholder="请è¾å
¥åºåç¨æ·å§å" @keypress.enter.native="search"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ä¸å¡æ¨¡å" prop="operaModule"> |
| | | <el-input v-model="searchForm.operaModule" placeholder="请è¾å
¥ä¸å¡æ¨¡å" @keypress.enter.native="search"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="请æ±å°å" prop="requestUri"> |
| | | <el-input v-model="searchForm.requestUri" placeholder="请è¾å
¥è¯·æ±å°å" @keypress.enter.native="search"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="searchForm.status" clearable @change="search"> |
| | | <el-option value="-1" label="æªå¤ç"/> |
| | | <el-option value="0" label="失败"/> |
| | | <el-option value="1" label="æå"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å¼å¸¸ç级" prop="exceptionLevel"> |
| | | <el-select v-model="searchForm.exceptionLevel" clearable @change="search"> |
| | | <el-option value="10" label="é«"/> |
| | | <el-option value="5" label="ä¸"/> |
| | | <el-option value="0" label="ä½"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æä½æ¶é´èå´"> |
| | | <el-date-picker |
| | | v-model="searchDateRange" |
| | | type="datetimerange" |
| | | range-separator="è³" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | start-placeholder="å¼å§æ¶é´" |
| | | end-placeholder="ç»ææ¶é´" |
| | | @change="handleSearchTimeChange" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" @click="search">æç´¢</el-button> |
| | | <el-button type="primary" :loading="isWorking.export" @click="exportExcel">导åº</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <div slot="space" class="status-bar"> |
| | | <label class="status-normal">æ£å¸¸</label> |
| | | <label class="status-warn">è¦åå¼å¸¸(éææ¥)</label> |
| | | <label class="status-danger">ç³»ç»å¼å¸¸(éä¿®å¤)</label> |
| | | </div> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | stripe |
| | | :default-sort="{prop: 'operaTime', order: 'descending'}" |
| | | :row-class-name="tableRowClassName" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column prop="operaModule" label="ä¸å¡æ¨¡å" min-width="100px"></el-table-column> |
| | | <el-table-column prop="operaRemark" label="æä½è¯´æ" min-width="100px"></el-table-column> |
| | | <el-table-column prop="requestMethod" label="è¯·æ±æ¹å¼" min-width="80px"></el-table-column> |
| | | <el-table-column prop="requestUri" label="请æ±å°å" min-width="200px"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.status | statusText}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="requestParams" label="请æ±åæ°" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | <ColumnDetail v-if="row.requestParams != null" :content="row.requestParams" :limit="0"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="requestResult" label="请æ±ç»æ" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | <ColumnDetail v-if="row.requestResult != null" :content="row.requestResult"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="exceptionLevel" label="å¼å¸¸ç级" sortable="custom" sort-by="EXCEPTION_LEVEL" min-width="100px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.exceptionLevel | exceptionLevelText}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="exceptionStack" label="å¼å¸¸ä¿¡æ¯" min-width="170px"> |
| | | <template slot-scope="{row}"> |
| | | <ColumnDetail v-if="row.exceptionStack != null" :content="row.exceptionStack" :button-type="getExceptionButtonType(row.exceptionLevel)"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="operaSpendTime" label="请æ±èæ¶(ms)" sortable="custom" sort-by="OPERA_SPEND_TIME" min-width="120px"></el-table-column> |
| | | <el-table-column prop="userRealname" label="æä½äºº" min-width="100px"></el-table-column> |
| | | <el-table-column prop="operaTime" label="æä½æ¶é´" sortable="custom" sort-by="OPERA_TIME" min-width="140px"></el-table-column> |
| | | <el-table-column prop="platform" label="æä½å¹³å°" min-width="100px"></el-table-column> |
| | | <el-table-column prop="systemVersion" label="ç³»ç»çæ¬" min-width="80px"></el-table-column> |
| | | <el-table-column prop="serverIp" label="å¤çæå¡å¨IP" min-width="100px"></el-table-column> |
| | | <el-table-column prop="ip" label="ç¨æ·IP" min-width="100px"></el-table-column> |
| | | <el-table-column prop="clientInfo" label="ç¨æ·å®¢æ·ç«¯" min-width="200px"></el-table-column> |
| | | <el-table-column prop="osInfo" label="ç¨æ·æä½ç³»ç»" min-width="100px"></el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import Pagination from '@/components/common/Pagination' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import ColumnDetail from '../../components/common/ColumnDetail' |
| | | |
| | | export default { |
| | | name: 'SystemTraceLog', |
| | | extends: BaseTable, |
| | | components: { ColumnDetail, TableLayout, Pagination }, |
| | | data () { |
| | | return { |
| | | // æç´¢æ¶é´åè |
| | | searchDateRange: [], |
| | | // æç´¢ |
| | | searchForm: { |
| | | userRealname: '', |
| | | operaModule: '', |
| | | requestUri: '', |
| | | status: null, |
| | | exceptionLevel: null, |
| | | startTime: null, |
| | | endTime: null |
| | | } |
| | | } |
| | | }, |
| | | filters: { |
| | | // ç¶æ |
| | | statusText (value) { |
| | | if (value === 1) { |
| | | return 'æå' |
| | | } |
| | | if (value === 0) { |
| | | return '失败' |
| | | } |
| | | return 'æªå¤ç' |
| | | }, |
| | | // å¼å¸¸ç级 |
| | | exceptionLevelText (value) { |
| | | if (value == null) { |
| | | return '' |
| | | } |
| | | if (value === 0) { |
| | | return 'ä½' |
| | | } |
| | | if (value === 5) { |
| | | return 'ä¸' |
| | | } |
| | | if (value === 10) { |
| | | return 'é«' |
| | | } |
| | | return 'æªç¥' |
| | | } |
| | | }, |
| | | methods: { |
| | | // æç´¢æ¡éç½® |
| | | reset () { |
| | | this.$refs.searchForm.resetFields() |
| | | this.searchDateRange = [] |
| | | this.searchForm.startTime = null |
| | | this.searchForm.endTime = null |
| | | this.search() |
| | | }, |
| | | // æ è®°è¡class |
| | | tableRowClassName ({ row }) { |
| | | if (row.exceptionLevel === 5 || row.status === -1) { |
| | | return 'warning-log' |
| | | } else if (row.exceptionLevel === 10) { |
| | | return 'danger-log' |
| | | } |
| | | return '' |
| | | }, |
| | | // è·åå¼å¸¸æ¥çæé®ç±»å |
| | | getExceptionButtonType (level) { |
| | | if (level === 5) { |
| | | return 'warning' |
| | | } |
| | | if (level === 10) { |
| | | return 'danger' |
| | | } |
| | | return null |
| | | }, |
| | | // æ¶é´æç´¢èå´åå |
| | | handleSearchTimeChange (value) { |
| | | this.searchForm.startTime = null |
| | | this.searchForm.endTime = null |
| | | if (value != null) { |
| | | this.searchForm.startTime = value[0] |
| | | this.searchForm.endTime = value[1] |
| | | } |
| | | this.search() |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | api: '/system/traceLog', |
| | | sorts: [{ |
| | | property: 'OPERA_TIME', |
| | | direction: 'DESC' |
| | | }] |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // ç¶ææ |
| | | .status-bar { |
| | | padding: 0 16px; |
| | | [class^=status-] { |
| | | font-size: 13px; |
| | | margin-right: 12px; |
| | | line-height: 40px; |
| | | &::before { |
| | | position: relative; |
| | | top: 2px; |
| | | display: inline-block; |
| | | content: ''; |
| | | width: 12px; |
| | | height: 12px; |
| | | border: 1px solid #ccc; |
| | | background: #fff; |
| | | margin-right: 6px; |
| | | } |
| | | } |
| | | .status-warn::before { |
| | | background-color: oldlace; |
| | | border-color: orange; |
| | | } |
| | | .status-danger::before { |
| | | background-color: #fdf0f0; |
| | | border-color: indianred; |
| | | } |
| | | } |
| | | /deep/ .table-content { |
| | | margin-top: 0; |
| | | } |
| | | // è¦å级æ¥å¿ |
| | | /deep/ .warning-log td { |
| | | background-color: oldlace !important; |
| | | } |
| | | // å±é©çº§æ¥å¿ |
| | | /deep/ .danger-log td { |
| | | background-color: #fdf0f0 !important; |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <TableLayout :permissions="['system:user:query']"> |
| | | <!-- æç´¢è¡¨å --> |
| | | <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="80px" inline> |
| | | <el-form-item label="ç¨æ·å" prop="username"> |
| | | <el-input v-model="searchForm.username" v-trim placeholder="请è¾å
¥ç¨æ·å" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="å§å" prop="realname"> |
| | | <el-input v-model="searchForm.realname" v-trim placeholder="请è¾å
¥å§å" @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="mobile"> |
| | | <el-input v-model="searchForm.mobile" v-trim placeholder="请è¾å
¥ææºå·ç " @keypress.enter.native="search"/> |
| | | </el-form-item> |
| | | <el-form-item label="æå±é¨é¨" prop="rootDeptId"> |
| | | <DepartmentSelect v-model="searchForm.rootDeptId" placeholder="è¯·éæ©æå±é¨é¨" clearable/> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½" prop="positionId"> |
| | | <PositionSelect v-model="searchForm.positionId" placeholder="è¯·éæ©å²ä½" clearable/> |
| | | </el-form-item> |
| | | <section> |
| | | <el-button type="primary" icon="el-icon-search" @click="search">æç´¢</el-button> |
| | | <el-button @click="reset">éç½®</el-button> |
| | | </section> |
| | | </el-form> |
| | | <!-- è¡¨æ ¼åå页 --> |
| | | <template v-slot:table-wrap> |
| | | <ul class="toolbar" v-permissions="['system:user:create', 'system:user:delete']"> |
| | | <li v-permissions="['system:user:create']"><el-button icon="el-icon-plus" type="primary" @click="$refs.operaUserWindow.open('æ°å»ºç¨æ·')">æ°å»º</el-button></li> |
| | | <li v-permissions="['system:user:delete']"><el-button icon="el-icon-delete" @click="deleteByIdInBatch">å é¤</el-button></li> |
| | | </ul> |
| | | <el-table |
| | | v-loading="isWorking.search" |
| | | :data="tableData.list" |
| | | :default-sort = "{prop: 'createTime', order: 'descending'}" |
| | | stripe |
| | | @selection-change="handleSelectionChange" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | | <el-table-column prop="avatar" label="头å" width="80px" class-name="table-column-avatar" fixed="left"> |
| | | <template slot-scope="{row}"> |
| | | <img :src="row.avatar == null ? '/static/avatar/man.png' : row.avatar"> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="realname" label="å§å" min-width="100px" fixed="left"></el-table-column> |
| | | <el-table-column prop="username" label="ç¨æ·å" min-width="120px"></el-table-column> |
| | | <el-table-column prop="empNo" label="å·¥å·" sortable="custom" sort-by="EMP_NO" min-width="80px"></el-table-column> |
| | | <el-table-column prop="department" label="é¨é¨" min-width="120px"> |
| | | <template slot-scope="{row}">{{row.department == null ? '' : row.department.name}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="position" label="å²ä½" min-width="160px" class-name="table-column-strings"> |
| | | <template slot-scope="{row}"> |
| | | <ul> |
| | | <li v-for="position in row.positions" :key="position.id">{{position.name}}</li> |
| | | </ul> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="sex" label="æ§å«" sortable="custom" sort-by="SEX" min-width="80px"> |
| | | <template slot-scope="{row}"> |
| | | {{row.sex | sex}} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="mobile" label="ææºå·ç " min-width="100px"></el-table-column> |
| | | <el-table-column prop="email" label="é®ç®±" min-width="180px"></el-table-column> |
| | | <el-table-column prop="birthday" label="çæ¥" sortable="custom" sort-by="BIRTHDAY" min-width="100px"></el-table-column> |
| | | <el-table-column prop="roles" label="è§è²" min-width="160px" class-name="table-column-strings"> |
| | | <template slot-scope="{row}"> |
| | | <ul> |
| | | <li v-for="role in row.roles" :key="role.id">{{role.name}}</li> |
| | | </ul> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="createUser" label="å建人" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="å建æ¶é´" sortable="custom" sort-by="CREATE_TIME" min-width="140px"></el-table-column> |
| | | <el-table-column prop="updateUser" label="æ´æ°äºº" min-width="100px"> |
| | | <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="updateTime" label="æ´æ°æ¶é´" sortable="custom" sort-by="UPDATE_TIME" min-width="140px"></el-table-column> |
| | | <el-table-column |
| | | v-if="containPermissions(['system:user:update', 'system:user:createUserRole', 'system:user:resetPwd', 'system:user:delete'])" |
| | | label="æä½" |
| | | width="270" |
| | | fixed="right" |
| | | > |
| | | <template v-if="isAdmin || (row.id !== userInfo.id && row.roles.findIndex(r => r.code === adminCode) === -1)" slot-scope="{row}"> |
| | | <el-button type="text" icon="el-icon-edit" @click="$refs.operaUserWindow.open('ç¼è¾ç¨æ·', row)" v-permissions="['system:user:update']">ç¼è¾</el-button> |
| | | <el-button type="text" icon="el-icon-s-custom" @click="$refs.roleConfigWindow.open(row)" v-permissions="['system:user:createUserRole']">é
ç½®è§è²</el-button> |
| | | <el-button type="text" @click="$refs.resetPwdWindow.open(row)" v-permissions="['system:user:resetPwd']">éç½®å¯ç </el-button> |
| | | <el-button v-if="!row.fixed" type="text" icon="el-icon-delete" @click="deleteById(row)" v-permissions="['system:user:delete']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | @size-change="handleSizeChange" |
| | | @current-change="handlePageChange" |
| | | :pagination="tableData.pagination" |
| | | ></pagination> |
| | | </template> |
| | | <!-- æ°å»º/ä¿®æ¹ --> |
| | | <OperaUserWindow ref="operaUserWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | <!-- é
ç½®è§è² --> |
| | | <RoleConfigWindow ref="roleConfigWindow" @success="handlePageChange(tableData.pagination.pageIndex)"/> |
| | | <!-- éç½®å¯ç --> |
| | | <ResetPwdWindow ref="resetPwdWindow"/> |
| | | </TableLayout> |
| | | </template> |
| | | |
| | | <script> |
| | | import Pagination from '@/components/common/Pagination' |
| | | import TableLayout from '@/layouts/TableLayout' |
| | | import BaseTable from '@/components/base/BaseTable' |
| | | import OperaUserWindow from '@/components/system/user/OperaUserWindow' |
| | | import RoleConfigWindow from '@/components/system/user/RoleConfigWindow' |
| | | import ResetPwdWindow from '@/components/system/user/ResetPwdWindow' |
| | | import DepartmentSelect from '@/components/common/DepartmentSelect' |
| | | import PositionSelect from '@/components/common/PositionSelect' |
| | | |
| | | export default { |
| | | name: 'SystemUser', |
| | | extends: BaseTable, |
| | | components: { PositionSelect, DepartmentSelect, ResetPwdWindow, RoleConfigWindow, OperaUserWindow, TableLayout, Pagination }, |
| | | data () { |
| | | return { |
| | | // æç´¢ |
| | | searchForm: { |
| | | username: '', // åå |
| | | realname: '', // å§å |
| | | rootDeptId: null, // é¨é¨ID |
| | | positionId: null, // å²ä½ID |
| | | mobile: '' // ææºå·ç |
| | | } |
| | | } |
| | | }, |
| | | created () { |
| | | this.config({ |
| | | module: 'ç¨æ·', |
| | | api: '/system/user', |
| | | 'field.main': 'realname', |
| | | sorts: [{ |
| | | property: 'CREATE_TIME', |
| | | direction: 'DESC' |
| | | }] |
| | | }) |
| | | this.search() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | @import "@/assets/style/variables.scss"; |
| | | // å表头åå¤ç |
| | | .table-column-avatar { |
| | | img { |
| | | width: 48px; |
| | | } |
| | | } |
| | | </style> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 详ç»é
置请åèhttps://cli.vuejs.org/zh/config/#vue-config-js |
| | | const outputDir = process.env.VUE_APP_CONTEXT_PATH.substring(1, process.env.VUE_APP_CONTEXT_PATH.length - 1) |
| | | module.exports = { |
| | | publicPath: process.env.VUE_APP_CONTEXT_PATH, |
| | | outputDir: outputDir === '/' ? 'dist' : outputDir, |
| | | assetsDir: 'static', |
| | | lintOnSave: false, |
| | | devServer: { |
| | | host: '0.0.0.0', |
| | | port: 10012, |
| | | proxy: { |
| | | [process.env.VUE_APP_API_PREFIX]: { |
| | | target: 'http://192.168.0.197:10013', |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | [`^${[process.env.VUE_APP_API_PREFIX]}`]: '' |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |