xuhuajiao
10 months ago
13 changed files with 1000 additions and 889 deletions
-
15.env.development
-
230package.json
-
32src/views/archivesManage/archivesList/index.vue
-
2src/views/archivesManage/archivesList/mixins/archives.js
-
106src/views/archivesManage/fileImport/dataImport/index.vue
-
23src/views/archivesManage/fileImport/importLog/index.vue
-
92src/views/archivesManage/fileImport/module/detail.vue
-
22src/views/archivesManage/outInStorage/inStorage/index.vue
-
1src/views/archivesManage/outInStorage/outInHistory/index.vue
-
2src/views/system/logManage/loginLog/index.vue
-
530src/views/system/menu/index.vue
-
762src/views/system/role/index.vue
-
72src/views/system/user/index.vue
@ -1,115 +1,115 @@ |
|||||
{ |
|
||||
"name": "yxk-storeroom-system", |
|
||||
"version": "1.0.0", |
|
||||
"description": "智能库房综合管理系统", |
|
||||
"author": "刘力", |
|
||||
"license": "", |
|
||||
"scripts": { |
|
||||
"dev": "vue-cli-service serve", |
|
||||
"build:prod": "vue-cli-service build", |
|
||||
"build:stage": "vue-cli-service build --mode staging", |
|
||||
"preview": "node build/index.js --preview", |
|
||||
"lint": "eslint --ext .js,.vue src", |
|
||||
"test:unit": "jest --clearCache && vue-cli-service test:unit", |
|
||||
"svgo": "svgo -f src/assets/icons/svg --config=src/assets/icons/svgo.yml", |
|
||||
"new": "plop" |
|
||||
}, |
|
||||
"husky": { |
|
||||
"hooks": { |
|
||||
"pre-commit": "lint-staged" |
|
||||
} |
|
||||
}, |
|
||||
"lint-staged": { |
|
||||
"src/**/*.{js,vue}": [ |
|
||||
"eslint --fix", |
|
||||
"git add" |
|
||||
] |
|
||||
}, |
|
||||
"dependencies": { |
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", |
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.18.9", |
|
||||
"@riophae/vue-treeselect": "^0.4.0", |
|
||||
"axios": "^0.21.1", |
|
||||
"clipboard": "2.0.4", |
|
||||
"codemirror": "^5.49.2", |
|
||||
"connect": "3.6.6", |
|
||||
"core-js": "^2.6.12", |
|
||||
"echarts": "^4.2.1", |
|
||||
"echarts-gl": "^1.1.1", |
|
||||
"echarts-wordcloud": "^1.1.3", |
|
||||
"element-ui": "^2.15.6", |
|
||||
"file-saver": "1.3.8", |
|
||||
"fuse.js": "3.4.4", |
|
||||
"highlight.js": "^11.5.1", |
|
||||
"html2canvas": "^1.4.1", |
|
||||
"js-beautify": "^1.10.2", |
|
||||
"js-cookie": "2.2.0", |
|
||||
"jsencrypt": "^3.0.0-rc.1", |
|
||||
"jszip": "^3.7.1", |
|
||||
"mavon-editor": "^2.9.1", |
|
||||
"normalize.css": "7.0.0", |
|
||||
"nprogress": "0.2.0", |
|
||||
"path-to-regexp": "2.4.0", |
|
||||
"print-js": "^1.6.0", |
|
||||
"qs": "^6.10.1", |
|
||||
"screenfull": "4.2.0", |
|
||||
"sortablejs": "1.8.4", |
|
||||
"vkbeautify": "^0.99.3", |
|
||||
"vue": "^2.6.14", |
|
||||
"vue-count-to": "^1.0.13", |
|
||||
"vue-cropper": "0.4.9", |
|
||||
"vue-echarts": "^5.0.0-beta.0", |
|
||||
"vue-highlightjs": "^1.3.3", |
|
||||
"vue-image-crop-upload": "^2.5.0", |
|
||||
"vue-router": "3.0.2", |
|
||||
"vue-splitpane": "1.0.4", |
|
||||
"vuedraggable": "2.20.0", |
|
||||
"vuex": "3.1.0", |
|
||||
"wangeditor": "^4.7.11", |
|
||||
"x2js": "^3.4.3", |
|
||||
"xlsx": "^0.17.4" |
|
||||
}, |
|
||||
"devDependencies": { |
|
||||
"@babel/parser": "^7.7.4", |
|
||||
"@babel/register": "7.0.0", |
|
||||
"@vue/babel-plugin-transform-vue-jsx": "^1.2.1", |
|
||||
"@vue/cli-plugin-babel": "3.5.3", |
|
||||
"@vue/cli-plugin-eslint": "^3.9.1", |
|
||||
"@vue/cli-plugin-unit-jest": "3.5.3", |
|
||||
"@vue/cli-service": "3.5.3", |
|
||||
"@vue/test-utils": "1.0.0-beta.29", |
|
||||
"autoprefixer": "^9.5.1", |
|
||||
"babel-core": "7.0.0-bridge.0", |
|
||||
"babel-eslint": "10.0.1", |
|
||||
"babel-jest": "23.6.0", |
|
||||
"babel-plugin-dynamic-import-node": "2.3.0", |
|
||||
"babel-plugin-transform-remove-console": "^6.9.4", |
|
||||
"chalk": "2.4.2", |
|
||||
"chokidar": "2.1.5", |
|
||||
"connect": "3.6.6", |
|
||||
"eslint": "5.15.3", |
|
||||
"eslint-plugin-vue": "5.2.2", |
|
||||
"html-webpack-plugin": "3.2.0", |
|
||||
"http-proxy-middleware": "^0.19.1", |
|
||||
"husky": "1.3.1", |
|
||||
"lint-staged": "8.1.5", |
|
||||
"plop": "2.3.0", |
|
||||
"sass": "1.32.13", |
|
||||
"sass-loader": "10.2.0", |
|
||||
"script-ext-html-webpack-plugin": "2.1.3", |
|
||||
"script-loader": "0.7.2", |
|
||||
"serve-static": "^1.13.2", |
|
||||
"svg-sprite-loader": "4.1.3", |
|
||||
"svgo": "1.2.0", |
|
||||
"tasksfile": "^5.1.1", |
|
||||
"vue-template-compiler": "2.6.14" |
|
||||
}, |
|
||||
"engines": { |
|
||||
"node": ">=8.9", |
|
||||
"npm": ">= 3.0.0" |
|
||||
}, |
|
||||
"browserslist": [ |
|
||||
"> 1%", |
|
||||
"last 2 versions" |
|
||||
] |
|
||||
} |
|
||||
|
{ |
||||
|
"name": "yxk-storeroom-system", |
||||
|
"version": "1.0.0", |
||||
|
"description": "智能库房综合管理系统", |
||||
|
"author": "刘力", |
||||
|
"license": "", |
||||
|
"scripts": { |
||||
|
"dev": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve", |
||||
|
"build:prod": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build", |
||||
|
"build:stage": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --mode staging", |
||||
|
"preview": "node build/index.js --preview", |
||||
|
"lint": "eslint --ext .js,.vue src", |
||||
|
"test:unit": "jest --clearCache && vue-cli-service test:unit", |
||||
|
"svgo": "svgo -f src/assets/icons/svg --config=src/assets/icons/svgo.yml", |
||||
|
"new": "plop" |
||||
|
}, |
||||
|
"husky": { |
||||
|
"hooks": { |
||||
|
"pre-commit": "lint-staged" |
||||
|
} |
||||
|
}, |
||||
|
"lint-staged": { |
||||
|
"src/**/*.{js,vue}": [ |
||||
|
"eslint --fix", |
||||
|
"git add" |
||||
|
] |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", |
||||
|
"@babel/plugin-proposal-optional-chaining": "^7.18.9", |
||||
|
"@riophae/vue-treeselect": "^0.4.0", |
||||
|
"axios": "^0.21.1", |
||||
|
"clipboard": "2.0.4", |
||||
|
"codemirror": "^5.49.2", |
||||
|
"connect": "3.6.6", |
||||
|
"core-js": "^2.6.12", |
||||
|
"echarts": "^4.2.1", |
||||
|
"echarts-gl": "^1.1.1", |
||||
|
"echarts-wordcloud": "^1.1.3", |
||||
|
"element-ui": "^2.15.6", |
||||
|
"file-saver": "1.3.8", |
||||
|
"fuse.js": "3.4.4", |
||||
|
"highlight.js": "^11.5.1", |
||||
|
"html2canvas": "^1.4.1", |
||||
|
"js-beautify": "^1.10.2", |
||||
|
"js-cookie": "2.2.0", |
||||
|
"jsencrypt": "^3.0.0-rc.1", |
||||
|
"jszip": "^3.7.1", |
||||
|
"mavon-editor": "^2.9.1", |
||||
|
"normalize.css": "7.0.0", |
||||
|
"nprogress": "0.2.0", |
||||
|
"path-to-regexp": "2.4.0", |
||||
|
"print-js": "^1.6.0", |
||||
|
"qs": "^6.10.1", |
||||
|
"screenfull": "4.2.0", |
||||
|
"sortablejs": "1.8.4", |
||||
|
"vkbeautify": "^0.99.3", |
||||
|
"vue": "^2.6.14", |
||||
|
"vue-count-to": "^1.0.13", |
||||
|
"vue-cropper": "0.4.9", |
||||
|
"vue-echarts": "^5.0.0-beta.0", |
||||
|
"vue-highlightjs": "^1.3.3", |
||||
|
"vue-image-crop-upload": "^2.5.0", |
||||
|
"vue-router": "3.0.2", |
||||
|
"vue-splitpane": "1.0.4", |
||||
|
"vuedraggable": "2.20.0", |
||||
|
"vuex": "3.1.0", |
||||
|
"wangeditor": "^4.7.11", |
||||
|
"x2js": "^3.4.3", |
||||
|
"xlsx": "^0.17.4" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@babel/parser": "^7.7.4", |
||||
|
"@babel/register": "7.0.0", |
||||
|
"@vue/babel-plugin-transform-vue-jsx": "^1.2.1", |
||||
|
"@vue/cli-plugin-babel": "3.5.3", |
||||
|
"@vue/cli-plugin-eslint": "^3.9.1", |
||||
|
"@vue/cli-plugin-unit-jest": "3.5.3", |
||||
|
"@vue/cli-service": "3.5.3", |
||||
|
"@vue/test-utils": "1.0.0-beta.29", |
||||
|
"autoprefixer": "^9.5.1", |
||||
|
"babel-core": "7.0.0-bridge.0", |
||||
|
"babel-eslint": "10.0.1", |
||||
|
"babel-jest": "23.6.0", |
||||
|
"babel-plugin-dynamic-import-node": "2.3.0", |
||||
|
"babel-plugin-transform-remove-console": "^6.9.4", |
||||
|
"chalk": "2.4.2", |
||||
|
"chokidar": "2.1.5", |
||||
|
"connect": "3.6.6", |
||||
|
"eslint": "5.15.3", |
||||
|
"eslint-plugin-vue": "5.2.2", |
||||
|
"html-webpack-plugin": "3.2.0", |
||||
|
"http-proxy-middleware": "^0.19.1", |
||||
|
"husky": "1.3.1", |
||||
|
"lint-staged": "8.1.5", |
||||
|
"plop": "2.3.0", |
||||
|
"sass": "1.32.13", |
||||
|
"sass-loader": "10.2.0", |
||||
|
"script-ext-html-webpack-plugin": "2.1.3", |
||||
|
"script-loader": "0.7.2", |
||||
|
"serve-static": "^1.13.2", |
||||
|
"svg-sprite-loader": "4.1.3", |
||||
|
"svgo": "1.2.0", |
||||
|
"tasksfile": "^5.1.1", |
||||
|
"vue-template-compiler": "2.6.14" |
||||
|
}, |
||||
|
"engines": { |
||||
|
"node": ">=8.9", |
||||
|
"npm": ">= 3.0.0" |
||||
|
}, |
||||
|
"browserslist": [ |
||||
|
"> 1%", |
||||
|
"last 2 versions" |
||||
|
] |
||||
|
} |
@ -1,265 +1,265 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
|
|
||||
<!--工具栏--> |
|
||||
<div class="head-container"> |
|
||||
<div v-if="crud.props.searchToggle" class="head-search"> |
|
||||
<!-- 搜索 --> |
|
||||
<el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" /> |
|
||||
<date-range-picker v-model="query.createTime" class="date-item" /> |
|
||||
<rrOperation /> |
|
||||
</div> |
|
||||
<crudOperation :permission="permission" /> |
|
||||
</div> |
|
||||
<!--表单渲染--> |
|
||||
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title"> |
|
||||
<span class="dialog-right-top" /> |
|
||||
<span class="dialog-left-bottom" /> |
|
||||
<div class="setting-dialog"> |
|
||||
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> |
|
||||
<el-form-item label="菜单类型" prop="type"> |
|
||||
<el-radio-group v-model="form.type" size="mini" style="width: 178px"> |
|
||||
<el-radio-button label="0">目录</el-radio-button> |
|
||||
<el-radio-button label="1">菜单</el-radio-button> |
|
||||
<el-radio-button label="2">按钮</el-radio-button> |
|
||||
</el-radio-group> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.type.toString() !== '2'" label="菜单图标" prop="icon"> |
|
||||
<el-popover |
|
||||
placement="bottom-start" |
|
||||
width="450" |
|
||||
trigger="click" |
|
||||
@show="$refs['iconSelect'].reset()" |
|
||||
> |
|
||||
<IconSelect ref="iconSelect" @selected="selected" /> |
|
||||
<el-input slot="reference" v-model="form.icon" style="width: 450px;" placeholder="点击选择图标" readonly> |
|
||||
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 30px;width: 16px;" /> |
|
||||
<i v-else slot="prefix" class="el-icon-search el-input__icon" /> |
|
||||
</el-input> |
|
||||
</el-popover> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.type.toString() !== '2'" label="外链菜单" prop="iFrame"> |
|
||||
<el-radio-group v-model="form.iFrame" size="mini"> |
|
||||
<el-radio-button label="true">是</el-radio-button> |
|
||||
<el-radio-button label="false">否</el-radio-button> |
|
||||
</el-radio-group> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.type.toString() === '1'" label="菜单缓存" prop="cache"> |
|
||||
<el-radio-group v-model="form.cache" size="mini"> |
|
||||
<el-radio-button label="true">是</el-radio-button> |
|
||||
<el-radio-button label="false">否</el-radio-button> |
|
||||
</el-radio-group> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.type.toString() !== '2'" label="菜单可见" prop="hidden"> |
|
||||
<el-radio-group v-model="form.hidden" size="mini"> |
|
||||
<el-radio-button label="false">是</el-radio-button> |
|
||||
<el-radio-button label="true">否</el-radio-button> |
|
||||
</el-radio-group> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-if="form.type.toString() !== '2'" label="菜单标题" prop="title"> |
|
||||
<el-input v-model="form.title" :style=" form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'" placeholder="菜单标题" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-if="form.type.toString() === '2'" label="按钮名称" prop="title"> |
|
||||
<el-input v-model="form.title" placeholder="按钮名称" style="width: 178px;" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.type.toString() !== '0'" label="权限标识" prop="permission"> |
|
||||
<el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="权限标识" style="width: 178px;" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path"> |
|
||||
<el-input v-model="form.path" placeholder="路由地址" style="width: 178px;" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="菜单排序" prop="menuSort"> |
|
||||
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" style="width: 178px;" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName"> |
|
||||
<el-input v-model="form.componentName" style="width: 178px;" placeholder="匹配组件内Name字段" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component"> |
|
||||
<el-input v-model="form.component" style="width: 178px;" placeholder="组件路径" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="上级类目" prop="pid"> |
|
||||
<treeselect |
|
||||
v-model="form.pid" |
|
||||
:options="menus" |
|
||||
:load-options="loadMenus" |
|
||||
style="width: 450px;" |
|
||||
placeholder="选择上级类目" |
|
||||
/> |
|
||||
</el-form-item> |
|
||||
</el-form> |
|
||||
<div slot="footer" class="dialog-footer"> |
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button> |
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-dialog> |
|
||||
<!--表格渲染--> |
|
||||
<div class="app-container container-wrap" style="margin-top:0;min-height: calc(100vh - 292px);"> |
|
||||
<span class="right-top-line" /> |
|
||||
<span class="left-bottom-line" /> |
|
||||
<el-table |
|
||||
ref="table" |
|
||||
v-loading="crud.loading" |
|
||||
lazy |
|
||||
:load="getMenus" |
|
||||
:data="crud.data" |
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
|
||||
row-key="id" |
|
||||
@select="crud.selectChange" |
|
||||
@select-all="crud.selectAllChange" |
|
||||
@selection-change="crud.selectionChangeHandler" |
|
||||
> |
|
||||
<el-table-column type="selection" align="center" width="55" /> |
|
||||
<el-table-column :show-overflow-tooltip="true" label="菜单标题" width="125px" prop="title" /> |
|
||||
<el-table-column prop="icon" label="图标" align="center" width="60px"> |
|
||||
<template slot-scope="scope"> |
|
||||
<svg-icon :icon-class="scope.row.icon ? scope.row.icon : ''" /> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column prop="menuSort" align="center" label="排序"> |
|
||||
<template slot-scope="scope"> |
|
||||
{{ scope.row.menuSort }} |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column :show-overflow-tooltip="true" prop="permission" label="权限标识" /> |
|
||||
<el-table-column :show-overflow-tooltip="true" prop="component" label="组件路径" /> |
|
||||
<el-table-column prop="iFrame" label="外链" width="75px"> |
|
||||
<template slot-scope="scope"> |
|
||||
<span v-if="scope.row.iFrame">是</span> |
|
||||
<span v-else>否</span> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column prop="cache" label="缓存" width="75px"> |
|
||||
<template slot-scope="scope"> |
|
||||
<span v-if="scope.row.cache">是</span> |
|
||||
<span v-else>否</span> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column prop="hidden" label="可见" width="75px"> |
|
||||
<template slot-scope="scope"> |
|
||||
<span v-if="scope.row.hidden">否</span> |
|
||||
<span v-else>是</span> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column prop="createTime" label="创建日期" width="150px"> |
|
||||
<template slot-scope="scope"> |
|
||||
<div>{{ scope.row.createTime | parseTime }}</div> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="130px" align="center" fixed="right"> |
|
||||
<template slot-scope="scope"> |
|
||||
<udOperation |
|
||||
:data="scope.row" |
|
||||
:permission="permission" |
|
||||
msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!" |
|
||||
/> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
</el-table> |
|
||||
</div> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import crudMenu from '@/api/system/menu' |
|
||||
import IconSelect from '@/components/IconSelect' |
|
||||
import Treeselect from '@riophae/vue-treeselect' |
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
|
||||
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' |
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud' |
|
||||
import rrOperation from '@crud/RR.operation' |
|
||||
import crudOperation from '@crud/CRUD.operation' |
|
||||
import udOperation from '@crud/UD.operation' |
|
||||
import DateRangePicker from '@/components/DateRangePicker' |
|
||||
|
|
||||
// crud交由presenter持有 |
|
||||
const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iFrame: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null } |
|
||||
export default { |
|
||||
name: 'Menu', |
|
||||
components: { Treeselect, IconSelect, crudOperation, rrOperation, udOperation, DateRangePicker }, |
|
||||
cruds() { |
|
||||
return CRUD({ title: '菜单', url: 'api/menus', crudMethod: { ...crudMenu }}) |
|
||||
}, |
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()], |
|
||||
data() { |
|
||||
return { |
|
||||
menus: [], |
|
||||
permission: { |
|
||||
add: ['admin', 'menu:add'], |
|
||||
edit: ['admin', 'menu:edit'], |
|
||||
del: ['admin', 'menu:del'] |
|
||||
}, |
|
||||
rules: { |
|
||||
title: [ |
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' } |
|
||||
], |
|
||||
path: [ |
|
||||
{ required: true, message: '请输入地址', trigger: 'blur' } |
|
||||
] |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
// 新增与编辑前做的操作 |
|
||||
[CRUD.HOOK.afterToCU](crud, form) { |
|
||||
this.menus = [] |
|
||||
if (form.id != null) { |
|
||||
if (form.pid === null) { |
|
||||
form.pid = 0 |
|
||||
} |
|
||||
this.getSupDepts(form.id) |
|
||||
} else { |
|
||||
this.menus.push({ id: 0, label: '顶级类目', children: null }) |
|
||||
} |
|
||||
}, |
|
||||
getMenus(tree, treeNode, resolve) { |
|
||||
const params = { pid: tree.id } |
|
||||
setTimeout(() => { |
|
||||
crudMenu.getMenus(params).then(res => { |
|
||||
resolve(res.content) |
|
||||
}) |
|
||||
}, 100) |
|
||||
}, |
|
||||
getSupDepts(id) { |
|
||||
crudMenu.getMenuSuperior(id).then(res => { |
|
||||
const children = res.map(function(obj) { |
|
||||
if (!obj.leaf && !obj.children) { |
|
||||
obj.children = null |
|
||||
} |
|
||||
return obj |
|
||||
}) |
|
||||
this.menus = [{ id: 0, label: '顶级类目', children: children }] |
|
||||
}) |
|
||||
}, |
|
||||
loadMenus({ action, parentNode, callback }) { |
|
||||
if (action === LOAD_CHILDREN_OPTIONS) { |
|
||||
crudMenu.getMenusTree(parentNode.id).then(res => { |
|
||||
parentNode.children = res.map(function(obj) { |
|
||||
if (!obj.leaf) { |
|
||||
obj.children = null |
|
||||
} |
|
||||
return obj |
|
||||
}) |
|
||||
setTimeout(() => { |
|
||||
callback() |
|
||||
}, 100) |
|
||||
}) |
|
||||
} |
|
||||
}, |
|
||||
// 选中图标 |
|
||||
selected(name) { |
|
||||
this.form.icon = name |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style rel="stylesheet/scss" lang="scss" scoped> |
|
||||
::v-deep .el-input-number .el-input__inner { |
|
||||
text-align: left; |
|
||||
} |
|
||||
// ::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value { |
|
||||
// height: 30px; |
|
||||
// line-height: 30px; |
|
||||
// } |
|
||||
</style> |
|
||||
|
<template> |
||||
|
<div> |
||||
|
|
||||
|
<!--工具栏--> |
||||
|
<div class="head-container"> |
||||
|
<div v-if="crud.props.searchToggle" class="head-search"> |
||||
|
<!-- 搜索 --> |
||||
|
<el-input v-model="query.blurry" clearable size="small" placeholder="模糊搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" /> |
||||
|
<date-range-picker v-model="query.createTime" class="date-item" /> |
||||
|
<rrOperation /> |
||||
|
</div> |
||||
|
<crudOperation :permission="permission" /> |
||||
|
</div> |
||||
|
<!--表单渲染--> |
||||
|
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title"> |
||||
|
<span class="dialog-right-top" /> |
||||
|
<span class="dialog-left-bottom" /> |
||||
|
<div class="setting-dialog"> |
||||
|
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> |
||||
|
<el-form-item label="菜单类型" prop="type"> |
||||
|
<el-radio-group v-model="form.type" size="mini" style="width: 178px"> |
||||
|
<el-radio-button label="0">目录</el-radio-button> |
||||
|
<el-radio-button label="1">菜单</el-radio-button> |
||||
|
<el-radio-button label="2">按钮</el-radio-button> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.type.toString() !== '2'" label="菜单图标" prop="icon"> |
||||
|
<el-popover |
||||
|
placement="bottom-start" |
||||
|
width="450" |
||||
|
trigger="click" |
||||
|
@show="$refs['iconSelect'].reset()" |
||||
|
> |
||||
|
<IconSelect ref="iconSelect" @selected="selected" /> |
||||
|
<el-input slot="reference" v-model="form.icon" style="width: 450px;" placeholder="点击选择图标" readonly> |
||||
|
<svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 30px;width: 16px;" /> |
||||
|
<i v-else slot="prefix" class="el-icon-search el-input__icon" /> |
||||
|
</el-input> |
||||
|
</el-popover> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.type.toString() !== '2'" label="外链菜单" prop="iFrame"> |
||||
|
<el-radio-group v-model="form.iFrame" size="mini"> |
||||
|
<el-radio-button label="true">是</el-radio-button> |
||||
|
<el-radio-button label="false">否</el-radio-button> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.type.toString() === '1'" label="菜单缓存" prop="cache"> |
||||
|
<el-radio-group v-model="form.cache" size="mini"> |
||||
|
<el-radio-button label="true">是</el-radio-button> |
||||
|
<el-radio-button label="false">否</el-radio-button> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.type.toString() !== '2'" label="菜单可见" prop="hidden"> |
||||
|
<el-radio-group v-model="form.hidden" size="mini"> |
||||
|
<el-radio-button label="false">是</el-radio-button> |
||||
|
<el-radio-button label="true">否</el-radio-button> |
||||
|
</el-radio-group> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-if="form.type.toString() !== '2'" label="菜单标题" prop="title"> |
||||
|
<el-input v-model="form.title" :style=" form.type.toString() === '0' ? 'width: 450px' : 'width: 178px'" placeholder="菜单标题" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-if="form.type.toString() === '2'" label="按钮名称" prop="title"> |
||||
|
<el-input v-model="form.title" placeholder="按钮名称" style="width: 178px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.type.toString() !== '0'" label="权限标识" prop="permission"> |
||||
|
<el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="权限标识" style="width: 178px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path"> |
||||
|
<el-input v-model="form.path" placeholder="路由地址" style="width: 178px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="菜单排序" prop="menuSort"> |
||||
|
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" style="width: 178px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName"> |
||||
|
<el-input v-model="form.componentName" style="width: 178px;" placeholder="匹配组件内Name字段" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component"> |
||||
|
<el-input v-model="form.component" style="width: 178px;" placeholder="组件路径" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="上级类目" prop="pid"> |
||||
|
<treeselect |
||||
|
v-model="form.pid" |
||||
|
:options="menus" |
||||
|
:load-options="loadMenus" |
||||
|
style="width: 450px;" |
||||
|
placeholder="选择上级类目" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="text" @click="crud.cancelCU">取消</el-button> |
||||
|
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
<!--表格渲染--> |
||||
|
<div class="app-container container-wrap" style="margin-top:0;min-height: calc(100vh - 292px);"> |
||||
|
<span class="right-top-line" /> |
||||
|
<span class="left-bottom-line" /> |
||||
|
<el-table |
||||
|
ref="table" |
||||
|
v-loading="crud.loading" |
||||
|
lazy |
||||
|
:load="getMenus" |
||||
|
:data="crud.data" |
||||
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
||||
|
row-key="id" |
||||
|
@select="crud.selectChange" |
||||
|
@select-all="crud.selectAllChange" |
||||
|
@selection-change="crud.selectionChangeHandler" |
||||
|
> |
||||
|
<el-table-column type="selection" align="center" width="55" /> |
||||
|
<el-table-column :show-overflow-tooltip="true" label="菜单标题" min-width="100px" prop="title" /> |
||||
|
<el-table-column prop="icon" label="图标" align="center" width="60px"> |
||||
|
<template slot-scope="scope"> |
||||
|
<svg-icon :icon-class="scope.row.icon ? scope.row.icon : ''" /> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="menuSort" align="center" label="排序" width="60px"> |
||||
|
<template slot-scope="scope"> |
||||
|
{{ scope.row.menuSort }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column :show-overflow-tooltip="true" prop="permission" label="权限标识" /> |
||||
|
<el-table-column :show-overflow-tooltip="true" prop="component" label="组件路径" /> |
||||
|
<el-table-column prop="iFrame" label="外链" width="75px"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span v-if="scope.row.iFrame">是</span> |
||||
|
<span v-else>否</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="cache" label="缓存" width="75px"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span v-if="scope.row.cache">是</span> |
||||
|
<span v-else>否</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="hidden" label="可见" width="75px"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span v-if="scope.row.hidden">否</span> |
||||
|
<span v-else>是</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="createTime" label="创建日期" width="150px"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div>{{ scope.row.createTime | parseTime }}</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="130px" align="center" fixed="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<udOperation |
||||
|
:data="scope.row" |
||||
|
:permission="permission" |
||||
|
msg="确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!" |
||||
|
/> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import crudMenu from '@/api/system/menu' |
||||
|
import IconSelect from '@/components/IconSelect' |
||||
|
import Treeselect from '@riophae/vue-treeselect' |
||||
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
||||
|
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' |
||||
|
import CRUD, { presenter, header, form, crud } from '@crud/crud' |
||||
|
import rrOperation from '@crud/RR.operation' |
||||
|
import crudOperation from '@crud/CRUD.operation' |
||||
|
import udOperation from '@crud/UD.operation' |
||||
|
import DateRangePicker from '@/components/DateRangePicker' |
||||
|
|
||||
|
// crud交由presenter持有 |
||||
|
const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iFrame: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null } |
||||
|
export default { |
||||
|
name: 'Menu', |
||||
|
components: { Treeselect, IconSelect, crudOperation, rrOperation, udOperation, DateRangePicker }, |
||||
|
cruds() { |
||||
|
return CRUD({ title: '菜单', url: 'api/menus', crudMethod: { ...crudMenu }}) |
||||
|
}, |
||||
|
mixins: [presenter(), header(), form(defaultForm), crud()], |
||||
|
data() { |
||||
|
return { |
||||
|
menus: [], |
||||
|
permission: { |
||||
|
add: ['admin', 'menu:add'], |
||||
|
edit: ['admin', 'menu:edit'], |
||||
|
del: ['admin', 'menu:del'] |
||||
|
}, |
||||
|
rules: { |
||||
|
title: [ |
||||
|
{ required: true, message: '请输入标题', trigger: 'blur' } |
||||
|
], |
||||
|
path: [ |
||||
|
{ required: true, message: '请输入地址', trigger: 'blur' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 新增与编辑前做的操作 |
||||
|
[CRUD.HOOK.afterToCU](crud, form) { |
||||
|
this.menus = [] |
||||
|
if (form.id != null) { |
||||
|
if (form.pid === null) { |
||||
|
form.pid = 0 |
||||
|
} |
||||
|
this.getSupDepts(form.id) |
||||
|
} else { |
||||
|
this.menus.push({ id: 0, label: '顶级类目', children: null }) |
||||
|
} |
||||
|
}, |
||||
|
getMenus(tree, treeNode, resolve) { |
||||
|
const params = { pid: tree.id } |
||||
|
setTimeout(() => { |
||||
|
crudMenu.getMenus(params).then(res => { |
||||
|
resolve(res.content) |
||||
|
}) |
||||
|
}, 100) |
||||
|
}, |
||||
|
getSupDepts(id) { |
||||
|
crudMenu.getMenuSuperior(id).then(res => { |
||||
|
const children = res.map(function(obj) { |
||||
|
if (!obj.leaf && !obj.children) { |
||||
|
obj.children = null |
||||
|
} |
||||
|
return obj |
||||
|
}) |
||||
|
this.menus = [{ id: 0, label: '顶级类目', children: children }] |
||||
|
}) |
||||
|
}, |
||||
|
loadMenus({ action, parentNode, callback }) { |
||||
|
if (action === LOAD_CHILDREN_OPTIONS) { |
||||
|
crudMenu.getMenusTree(parentNode.id).then(res => { |
||||
|
parentNode.children = res.map(function(obj) { |
||||
|
if (!obj.leaf) { |
||||
|
obj.children = null |
||||
|
} |
||||
|
return obj |
||||
|
}) |
||||
|
setTimeout(() => { |
||||
|
callback() |
||||
|
}, 100) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
// 选中图标 |
||||
|
selected(name) { |
||||
|
this.form.icon = name |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style rel="stylesheet/scss" lang="scss" scoped> |
||||
|
::v-deep .el-input-number .el-input__inner { |
||||
|
text-align: left; |
||||
|
} |
||||
|
// ::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value { |
||||
|
// height: 30px; |
||||
|
// line-height: 30px; |
||||
|
// } |
||||
|
</style> |
@ -1,381 +1,381 @@ |
|||||
<template> |
|
||||
<div class="app-container"> |
|
||||
<!--工具栏--> |
|
||||
<div class="head-container"> |
|
||||
<div v-if="crud.props.searchToggle" class="head-search"> |
|
||||
<!-- 搜索 --> |
|
||||
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" /> |
|
||||
<date-range-picker v-model="query.createTime" class="date-item" /> |
|
||||
<rrOperation /> |
|
||||
</div> |
|
||||
<crudOperation :permission="permission" /> |
|
||||
</div> |
|
||||
<!-- 表单渲染 --> |
|
||||
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title"> |
|
||||
<span class="dialog-right-top" /> |
|
||||
<span class="dialog-left-bottom" /> |
|
||||
<div class="setting-dialog"> |
|
||||
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> |
|
||||
<el-form-item label="角色名称" prop="name"> |
|
||||
<el-input v-model="form.name" style="width: 380px;" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="角色级别" prop="level"> |
|
||||
<el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;" /> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="数据范围" prop="dataScope"> |
|
||||
<el-select v-model="form.dataScope" style="width: 140px" placeholder="请选择数据范围" @change="changeScope"> |
|
||||
<el-option |
|
||||
v-for="item in dateScopes" |
|
||||
:key="item" |
|
||||
:label="item" |
|
||||
:value="item" |
|
||||
/> |
|
||||
</el-select> |
|
||||
</el-form-item> |
|
||||
<el-form-item v-if="form.dataScope === '自定义'" label="数据权限" prop="depts"> |
|
||||
<treeselect |
|
||||
v-model="deptDatas" |
|
||||
:load-options="loadDepts" |
|
||||
:options="depts" |
|
||||
multiple |
|
||||
style="width: 380px" |
|
||||
placeholder="请选择" |
|
||||
/> |
|
||||
</el-form-item> |
|
||||
<el-form-item label="描述信息" prop="description"> |
|
||||
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" /> |
|
||||
</el-form-item> |
|
||||
</el-form> |
|
||||
<div slot="footer" class="dialog-footer"> |
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button> |
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> |
|
||||
</div> |
|
||||
</div> |
|
||||
</el-dialog> |
|
||||
<el-row :gutter="15"> |
|
||||
<!--角色管理--> |
|
||||
<el-col :xs="15" :sm="17" :md="18" :lg="19" :xl="19"> |
|
||||
<el-card class="box-card" shadow="never"> |
|
||||
<span class="right-top-line" /> |
|
||||
<span class="left-bottom-line" /> |
|
||||
<div slot="header" class="clearfix"> |
|
||||
<span class="role-span">角色列表</span> |
|
||||
</div> |
|
||||
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" height="calc(100vh - 400px)" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange"> |
|
||||
<el-table-column :selectable="checkboxT" type="selection" align="center" width="55" /> |
|
||||
<el-table-column prop="name" label="名称" /> |
|
||||
<el-table-column prop="dataScope" label="数据权限" /> |
|
||||
<el-table-column prop="level" label="角色级别" /> |
|
||||
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" /> |
|
||||
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期"> |
|
||||
<template slot-scope="scope"> |
|
||||
<div>{{ scope.row.createTime | parseTime }}</div> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right"> |
|
||||
<template slot-scope="scope"> |
|
||||
<udOperation |
|
||||
v-if="scope.row.level >= level" |
|
||||
:data="scope.row" |
|
||||
:permission="permission" |
|
||||
/> |
|
||||
</template> |
|
||||
</el-table-column> |
|
||||
</el-table> |
|
||||
<!--分页组件--> |
|
||||
<pagination /> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
<!-- 菜单授权 --> |
|
||||
<el-col :xs="9" :sm="7" :md="6" :lg="5" :xl="5"> |
|
||||
<el-card class="box-card" shadow="never" style="min-height:calc(100vh - 292px)"> |
|
||||
<span class="right-top-line" /> |
|
||||
<span class="left-bottom-line" /> |
|
||||
<div slot="header" class="clearfix"> |
|
||||
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top"> |
|
||||
<span class="role-span">菜单分配</span> |
|
||||
</el-tooltip> |
|
||||
<el-button |
|
||||
v-permission="['admin','roles:edit']" |
|
||||
:disabled="!showButton" |
|
||||
:loading="menuLoading" |
|
||||
icon="el-icon-check" |
|
||||
size="mini" |
|
||||
style="float: right; padding: 6px 9px" |
|
||||
@click="saveMenu" |
|
||||
>保存</el-button> |
|
||||
</div> |
|
||||
<el-tree |
|
||||
ref="menu" |
|
||||
lazy |
|
||||
:data="menus" |
|
||||
:default-checked-keys="menuIds" |
|
||||
:load="getMenuDatas" |
|
||||
:props="defaultProps" |
|
||||
check-strictly |
|
||||
accordion |
|
||||
show-checkbox |
|
||||
node-key="id" |
|
||||
@check="menuChange" |
|
||||
/> |
|
||||
</el-card> |
|
||||
</el-col> |
|
||||
</el-row> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import crudRoles from '@/api/system/role' |
|
||||
import { getDepts, getDeptSuperior } from '@/api/system/dept' |
|
||||
import { getMenusTree, getChild } from '@/api/system/menu' |
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud' |
|
||||
import rrOperation from '@crud/RR.operation' |
|
||||
import crudOperation from '@crud/CRUD.operation' |
|
||||
import udOperation from '@crud/UD.operation' |
|
||||
import pagination from '@crud/Pagination' |
|
||||
import Treeselect from '@riophae/vue-treeselect' |
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
|
||||
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' |
|
||||
import DateRangePicker from '@/components/DateRangePicker' |
|
||||
|
|
||||
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 } |
|
||||
export default { |
|
||||
name: 'Role', |
|
||||
components: { Treeselect, pagination, crudOperation, rrOperation, udOperation, DateRangePicker }, |
|
||||
cruds() { |
|
||||
return CRUD({ title: '角色', url: 'api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }}) |
|
||||
}, |
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()], |
|
||||
data() { |
|
||||
return { |
|
||||
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' }, |
|
||||
dateScopes: ['全部', '本级', '自定义'], level: 3, |
|
||||
currentId: 0, menuLoading: false, showButton: false, |
|
||||
menus: [], menuIds: [], depts: [], deptDatas: [], // 多选时使用 |
|
||||
permission: { |
|
||||
add: ['admin', 'roles:add'], |
|
||||
edit: ['admin', 'roles:edit'], |
|
||||
del: ['admin', 'roles:del'] |
|
||||
}, |
|
||||
rules: { |
|
||||
name: [ |
|
||||
{ required: true, message: '请输入名称', trigger: 'blur' } |
|
||||
], |
|
||||
permission: [ |
|
||||
{ required: true, message: '请输入权限', trigger: 'blur' } |
|
||||
] |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
created() { |
|
||||
crudRoles.getLevel().then(data => { |
|
||||
this.level = data.level |
|
||||
}) |
|
||||
}, |
|
||||
methods: { |
|
||||
getMenuDatas(node, resolve) { |
|
||||
setTimeout(() => { |
|
||||
getMenusTree(node.data.id ? node.data.id : 0).then(res => { |
|
||||
resolve(res) |
|
||||
}) |
|
||||
}, 100) |
|
||||
}, |
|
||||
[CRUD.HOOK.afterRefresh]() { |
|
||||
this.$refs.menu.setCheckedKeys([]) |
|
||||
}, |
|
||||
// 新增前初始化部门信息 |
|
||||
[CRUD.HOOK.beforeToAdd](crud, form) { |
|
||||
this.deptDatas = [] |
|
||||
form.menus = null |
|
||||
}, |
|
||||
// 编辑前初始化自定义数据权限的部门信息 |
|
||||
[CRUD.HOOK.beforeToEdit](crud, form) { |
|
||||
this.deptDatas = [] |
|
||||
if (form.dataScope === '自定义') { |
|
||||
this.getSupDepts(form.depts) |
|
||||
} |
|
||||
const _this = this |
|
||||
form.depts.forEach(function(dept) { |
|
||||
_this.deptDatas.push(dept.id) |
|
||||
}) |
|
||||
// 将角色的菜单清空,避免日志入库数据过长 |
|
||||
form.menus = null |
|
||||
}, |
|
||||
// 提交前做的操作 |
|
||||
[CRUD.HOOK.afterValidateCU](crud) { |
|
||||
if (crud.form.dataScope === '自定义' && this.deptDatas.length === 0) { |
|
||||
this.$message({ |
|
||||
message: '自定义数据权限不能为空', |
|
||||
type: 'warning' |
|
||||
}) |
|
||||
return false |
|
||||
} else if (crud.form.dataScope === '自定义') { |
|
||||
const depts = [] |
|
||||
this.deptDatas.forEach(function(data) { |
|
||||
const dept = { id: data } |
|
||||
depts.push(dept) |
|
||||
}) |
|
||||
crud.form.depts = depts |
|
||||
} else { |
|
||||
crud.form.depts = [] |
|
||||
} |
|
||||
return true |
|
||||
}, |
|
||||
// 触发单选 |
|
||||
handleCurrentChange(val) { |
|
||||
if (val) { |
|
||||
const _this = this |
|
||||
// 清空菜单的选中 |
|
||||
this.$refs.menu.setCheckedKeys([]) |
|
||||
// 保存当前的角色id |
|
||||
this.currentId = val.id |
|
||||
// 初始化默认选中的key |
|
||||
this.menuIds = [] |
|
||||
val.menus.forEach(function(data) { |
|
||||
_this.menuIds.push(data.id) |
|
||||
}) |
|
||||
this.showButton = true |
|
||||
} |
|
||||
}, |
|
||||
menuChange(menu) { |
|
||||
// 获取该节点的所有子节点,id 包含自身 |
|
||||
getChild(menu.id).then(childIds => { |
|
||||
// 判断是否在 menuIds 中,如果存在则删除,否则添加 |
|
||||
if (this.menuIds.indexOf(menu.id) !== -1) { |
|
||||
for (let i = 0; i < childIds.length; i++) { |
|
||||
const index = this.menuIds.indexOf(childIds[i]) |
|
||||
if (index !== -1) { |
|
||||
this.menuIds.splice(index, 1) |
|
||||
} |
|
||||
} |
|
||||
} else { |
|
||||
for (let i = 0; i < childIds.length; i++) { |
|
||||
const index = this.menuIds.indexOf(childIds[i]) |
|
||||
if (index === -1) { |
|
||||
this.menuIds.push(childIds[i]) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
this.$refs.menu.setCheckedKeys(this.menuIds) |
|
||||
}) |
|
||||
}, |
|
||||
// 保存菜单 |
|
||||
saveMenu() { |
|
||||
this.menuLoading = true |
|
||||
const role = { id: this.currentId, menus: [] } |
|
||||
// 得到已选中的 key 值 |
|
||||
this.menuIds.forEach(function(id) { |
|
||||
const menu = { id: id } |
|
||||
role.menus.push(menu) |
|
||||
}) |
|
||||
crudRoles.editMenu(role).then(() => { |
|
||||
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS) |
|
||||
this.menuLoading = false |
|
||||
this.update() |
|
||||
}).catch(err => { |
|
||||
this.menuLoading = false |
|
||||
console.log(err.response.data.message) |
|
||||
}) |
|
||||
}, |
|
||||
// 改变数据 |
|
||||
update() { |
|
||||
// 无刷新更新 表格数据 |
|
||||
crudRoles.get(this.currentId).then(res => { |
|
||||
for (let i = 0; i < this.crud.data.length; i++) { |
|
||||
if (res.id === this.crud.data[i].id) { |
|
||||
this.crud.data[i] = res |
|
||||
break |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
// 获取部门数据 |
|
||||
getDepts() { |
|
||||
getDepts({ enabled: true }).then(res => { |
|
||||
this.depts = res.content.map(function(obj) { |
|
||||
if (obj.hasChildren) { |
|
||||
obj.children = null |
|
||||
} |
|
||||
return obj |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
getSupDepts(depts) { |
|
||||
const ids = [] |
|
||||
depts.forEach(dept => { |
|
||||
ids.push(dept.id) |
|
||||
}) |
|
||||
getDeptSuperior(ids).then(res => { |
|
||||
const date = res.content |
|
||||
this.buildDepts(date) |
|
||||
this.depts = date |
|
||||
}) |
|
||||
}, |
|
||||
buildDepts(depts) { |
|
||||
depts.forEach(data => { |
|
||||
if (data.children) { |
|
||||
this.buildDepts(data.children) |
|
||||
} |
|
||||
if (data.hasChildren && !data.children) { |
|
||||
data.children = null |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
// 获取弹窗内部门数据 |
|
||||
loadDepts({ action, parentNode, callback }) { |
|
||||
if (action === LOAD_CHILDREN_OPTIONS) { |
|
||||
getDepts({ enabled: true, pid: parentNode.id }).then(res => { |
|
||||
parentNode.children = res.content.map(function(obj) { |
|
||||
if (obj.hasChildren) { |
|
||||
obj.children = null |
|
||||
} |
|
||||
return obj |
|
||||
}) |
|
||||
setTimeout(() => { |
|
||||
callback() |
|
||||
}, 200) |
|
||||
}) |
|
||||
} |
|
||||
}, |
|
||||
// 如果数据权限为自定义则获取部门数据 |
|
||||
changeScope() { |
|
||||
if (this.form.dataScope === '自定义') { |
|
||||
this.getDepts() |
|
||||
} |
|
||||
}, |
|
||||
checkboxT(row) { |
|
||||
return row.level >= this.level |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style rel="stylesheet/scss" lang="scss"> |
|
||||
.role-span { |
|
||||
font-weight: bold;color: #303133; |
|
||||
font-size: 15px; |
|
||||
} |
|
||||
</style> |
|
||||
|
|
||||
<style rel="stylesheet/scss" lang="scss" scoped> |
|
||||
.head-container{ |
|
||||
padding: 0 0 20px 0; |
|
||||
} |
|
||||
::v-deep .el-input-number .el-input__inner { |
|
||||
text-align: left; |
|
||||
} |
|
||||
::v-deep .vue-treeselect__multi-value{ |
|
||||
margin-bottom: 0; |
|
||||
} |
|
||||
::v-deep .vue-treeselect__multi-value-item{ |
|
||||
border: 0; |
|
||||
padding: 0; |
|
||||
} |
|
||||
::v-deep .el-table__body tr.current-row > td{ |
|
||||
color: #fff; |
|
||||
background-color: #13439E; |
|
||||
} |
|
||||
::v-deep .el-table__header{ |
|
||||
border-top: 1px solid #113D72; |
|
||||
} |
|
||||
</style> |
|
||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<!--工具栏--> |
||||
|
<div class="head-container"> |
||||
|
<div v-if="crud.props.searchToggle" class="head-search"> |
||||
|
<!-- 搜索 --> |
||||
|
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" /> |
||||
|
<date-range-picker v-model="query.createTime" class="date-item" /> |
||||
|
<rrOperation /> |
||||
|
</div> |
||||
|
<crudOperation :permission="permission" /> |
||||
|
</div> |
||||
|
<!-- 表单渲染 --> |
||||
|
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title"> |
||||
|
<span class="dialog-right-top" /> |
||||
|
<span class="dialog-left-bottom" /> |
||||
|
<div class="setting-dialog"> |
||||
|
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> |
||||
|
<el-form-item label="角色名称" prop="name"> |
||||
|
<el-input v-model="form.name" style="width: 380px;" /> |
||||
|
</el-form-item> |
||||
|
<!-- <el-form-item label="角色级别" prop="level"> |
||||
|
<el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;" /> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="数据范围" prop="dataScope"> |
||||
|
<el-select v-model="form.dataScope" style="width: 140px" placeholder="请选择数据范围" @change="changeScope"> |
||||
|
<el-option |
||||
|
v-for="item in dateScopes" |
||||
|
:key="item" |
||||
|
:label="item" |
||||
|
:value="item" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</el-form-item> --> |
||||
|
<el-form-item v-if="form.dataScope === '自定义'" label="数据权限" prop="depts"> |
||||
|
<treeselect |
||||
|
v-model="deptDatas" |
||||
|
:load-options="loadDepts" |
||||
|
:options="depts" |
||||
|
multiple |
||||
|
style="width: 380px" |
||||
|
placeholder="请选择" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
<el-form-item label="描述信息" prop="description"> |
||||
|
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" /> |
||||
|
</el-form-item> |
||||
|
</el-form> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="text" @click="crud.cancelCU">取消</el-button> |
||||
|
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
<el-row :gutter="15"> |
||||
|
<!--角色管理--> |
||||
|
<el-col :xs="15" :sm="17" :md="18" :lg="19" :xl="19"> |
||||
|
<el-card class="box-card" shadow="never"> |
||||
|
<span class="right-top-line" /> |
||||
|
<span class="left-bottom-line" /> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<span class="role-span">角色列表</span> |
||||
|
</div> |
||||
|
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" height="calc(100vh - 400px)" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange"> |
||||
|
<el-table-column :selectable="checkboxT" type="selection" align="center" width="55" /> |
||||
|
<el-table-column prop="name" label="名称" /> |
||||
|
<el-table-column prop="dataScope" label="数据权限" /> |
||||
|
<el-table-column prop="level" label="角色级别" /> |
||||
|
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" /> |
||||
|
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期"> |
||||
|
<template slot-scope="scope"> |
||||
|
<div>{{ scope.row.createTime | parseTime }}</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
<udOperation |
||||
|
v-if="scope.row.level >= level" |
||||
|
:data="scope.row" |
||||
|
:permission="permission" |
||||
|
/> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<!--分页组件--> |
||||
|
<pagination /> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
<!-- 菜单授权 --> |
||||
|
<el-col :xs="9" :sm="7" :md="6" :lg="5" :xl="5"> |
||||
|
<el-card class="box-card" shadow="never" style="min-height:calc(100vh - 292px)"> |
||||
|
<span class="right-top-line" /> |
||||
|
<span class="left-bottom-line" /> |
||||
|
<div slot="header" class="clearfix"> |
||||
|
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top"> |
||||
|
<span class="role-span">菜单分配</span> |
||||
|
</el-tooltip> |
||||
|
<el-button |
||||
|
v-permission="['admin','roles:edit']" |
||||
|
:disabled="!showButton" |
||||
|
:loading="menuLoading" |
||||
|
icon="el-icon-check" |
||||
|
size="mini" |
||||
|
style="float: right; padding: 6px 9px" |
||||
|
@click="saveMenu" |
||||
|
>保存</el-button> |
||||
|
</div> |
||||
|
<el-tree |
||||
|
ref="menu" |
||||
|
lazy |
||||
|
:data="menus" |
||||
|
:default-checked-keys="menuIds" |
||||
|
:load="getMenuDatas" |
||||
|
:props="defaultProps" |
||||
|
check-strictly |
||||
|
accordion |
||||
|
show-checkbox |
||||
|
node-key="id" |
||||
|
@check="menuChange" |
||||
|
/> |
||||
|
</el-card> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import crudRoles from '@/api/system/role' |
||||
|
import { getDepts, getDeptSuperior } from '@/api/system/dept' |
||||
|
import { getMenusTree, getChild } from '@/api/system/menu' |
||||
|
import CRUD, { presenter, header, form, crud } from '@crud/crud' |
||||
|
import rrOperation from '@crud/RR.operation' |
||||
|
import crudOperation from '@crud/CRUD.operation' |
||||
|
import udOperation from '@crud/UD.operation' |
||||
|
import pagination from '@crud/Pagination' |
||||
|
import Treeselect from '@riophae/vue-treeselect' |
||||
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
||||
|
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' |
||||
|
import DateRangePicker from '@/components/DateRangePicker' |
||||
|
|
||||
|
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 } |
||||
|
export default { |
||||
|
name: 'Role', |
||||
|
components: { Treeselect, pagination, crudOperation, rrOperation, udOperation, DateRangePicker }, |
||||
|
cruds() { |
||||
|
return CRUD({ title: '角色', url: 'api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }}) |
||||
|
}, |
||||
|
mixins: [presenter(), header(), form(defaultForm), crud()], |
||||
|
data() { |
||||
|
return { |
||||
|
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' }, |
||||
|
dateScopes: ['全部', '本级', '自定义'], level: 3, |
||||
|
currentId: 0, menuLoading: false, showButton: false, |
||||
|
menus: [], menuIds: [], depts: [], deptDatas: [], // 多选时使用 |
||||
|
permission: { |
||||
|
add: ['admin', 'roles:add'], |
||||
|
edit: ['admin', 'roles:edit'], |
||||
|
del: ['admin', 'roles:del'] |
||||
|
}, |
||||
|
rules: { |
||||
|
name: [ |
||||
|
{ required: true, message: '请输入名称', trigger: 'blur' } |
||||
|
], |
||||
|
permission: [ |
||||
|
{ required: true, message: '请输入权限', trigger: 'blur' } |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
crudRoles.getLevel().then(data => { |
||||
|
this.level = data.level |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
getMenuDatas(node, resolve) { |
||||
|
setTimeout(() => { |
||||
|
getMenusTree(node.data.id ? node.data.id : 0).then(res => { |
||||
|
resolve(res) |
||||
|
}) |
||||
|
}, 100) |
||||
|
}, |
||||
|
[CRUD.HOOK.afterRefresh]() { |
||||
|
this.$refs.menu.setCheckedKeys([]) |
||||
|
}, |
||||
|
// 新增前初始化部门信息 |
||||
|
[CRUD.HOOK.beforeToAdd](crud, form) { |
||||
|
this.deptDatas = [] |
||||
|
form.menus = null |
||||
|
}, |
||||
|
// 编辑前初始化自定义数据权限的部门信息 |
||||
|
[CRUD.HOOK.beforeToEdit](crud, form) { |
||||
|
this.deptDatas = [] |
||||
|
if (form.dataScope === '自定义') { |
||||
|
this.getSupDepts(form.depts) |
||||
|
} |
||||
|
const _this = this |
||||
|
form.depts.forEach(function(dept) { |
||||
|
_this.deptDatas.push(dept.id) |
||||
|
}) |
||||
|
// 将角色的菜单清空,避免日志入库数据过长 |
||||
|
form.menus = null |
||||
|
}, |
||||
|
// 提交前做的操作 |
||||
|
[CRUD.HOOK.afterValidateCU](crud) { |
||||
|
if (crud.form.dataScope === '自定义' && this.deptDatas.length === 0) { |
||||
|
this.$message({ |
||||
|
message: '自定义数据权限不能为空', |
||||
|
type: 'warning' |
||||
|
}) |
||||
|
return false |
||||
|
} else if (crud.form.dataScope === '自定义') { |
||||
|
const depts = [] |
||||
|
this.deptDatas.forEach(function(data) { |
||||
|
const dept = { id: data } |
||||
|
depts.push(dept) |
||||
|
}) |
||||
|
crud.form.depts = depts |
||||
|
} else { |
||||
|
crud.form.depts = [] |
||||
|
} |
||||
|
return true |
||||
|
}, |
||||
|
// 触发单选 |
||||
|
handleCurrentChange(val) { |
||||
|
if (val) { |
||||
|
const _this = this |
||||
|
// 清空菜单的选中 |
||||
|
this.$refs.menu.setCheckedKeys([]) |
||||
|
// 保存当前的角色id |
||||
|
this.currentId = val.id |
||||
|
// 初始化默认选中的key |
||||
|
this.menuIds = [] |
||||
|
val.menus.forEach(function(data) { |
||||
|
_this.menuIds.push(data.id) |
||||
|
}) |
||||
|
this.showButton = true |
||||
|
} |
||||
|
}, |
||||
|
menuChange(menu) { |
||||
|
// 获取该节点的所有子节点,id 包含自身 |
||||
|
getChild(menu.id).then(childIds => { |
||||
|
// 判断是否在 menuIds 中,如果存在则删除,否则添加 |
||||
|
if (this.menuIds.indexOf(menu.id) !== -1) { |
||||
|
for (let i = 0; i < childIds.length; i++) { |
||||
|
const index = this.menuIds.indexOf(childIds[i]) |
||||
|
if (index !== -1) { |
||||
|
this.menuIds.splice(index, 1) |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
for (let i = 0; i < childIds.length; i++) { |
||||
|
const index = this.menuIds.indexOf(childIds[i]) |
||||
|
if (index === -1) { |
||||
|
this.menuIds.push(childIds[i]) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
this.$refs.menu.setCheckedKeys(this.menuIds) |
||||
|
}) |
||||
|
}, |
||||
|
// 保存菜单 |
||||
|
saveMenu() { |
||||
|
this.menuLoading = true |
||||
|
const role = { id: this.currentId, menus: [] } |
||||
|
// 得到已选中的 key 值 |
||||
|
this.menuIds.forEach(function(id) { |
||||
|
const menu = { id: id } |
||||
|
role.menus.push(menu) |
||||
|
}) |
||||
|
crudRoles.editMenu(role).then(() => { |
||||
|
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS) |
||||
|
this.menuLoading = false |
||||
|
this.update() |
||||
|
}).catch(err => { |
||||
|
this.menuLoading = false |
||||
|
console.log(err.response.data.message) |
||||
|
}) |
||||
|
}, |
||||
|
// 改变数据 |
||||
|
update() { |
||||
|
// 无刷新更新 表格数据 |
||||
|
crudRoles.get(this.currentId).then(res => { |
||||
|
for (let i = 0; i < this.crud.data.length; i++) { |
||||
|
if (res.id === this.crud.data[i].id) { |
||||
|
this.crud.data[i] = res |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// 获取部门数据 |
||||
|
getDepts() { |
||||
|
getDepts({ enabled: true }).then(res => { |
||||
|
this.depts = res.content.map(function(obj) { |
||||
|
if (obj.hasChildren) { |
||||
|
obj.children = null |
||||
|
} |
||||
|
return obj |
||||
|
}) |
||||
|
}) |
||||
|
}, |
||||
|
getSupDepts(depts) { |
||||
|
const ids = [] |
||||
|
depts.forEach(dept => { |
||||
|
ids.push(dept.id) |
||||
|
}) |
||||
|
getDeptSuperior(ids).then(res => { |
||||
|
const date = res.content |
||||
|
this.buildDepts(date) |
||||
|
this.depts = date |
||||
|
}) |
||||
|
}, |
||||
|
buildDepts(depts) { |
||||
|
depts.forEach(data => { |
||||
|
if (data.children) { |
||||
|
this.buildDepts(data.children) |
||||
|
} |
||||
|
if (data.hasChildren && !data.children) { |
||||
|
data.children = null |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
// 获取弹窗内部门数据 |
||||
|
loadDepts({ action, parentNode, callback }) { |
||||
|
if (action === LOAD_CHILDREN_OPTIONS) { |
||||
|
getDepts({ enabled: true, pid: parentNode.id }).then(res => { |
||||
|
parentNode.children = res.content.map(function(obj) { |
||||
|
if (obj.hasChildren) { |
||||
|
obj.children = null |
||||
|
} |
||||
|
return obj |
||||
|
}) |
||||
|
setTimeout(() => { |
||||
|
callback() |
||||
|
}, 200) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
// 如果数据权限为自定义则获取部门数据 |
||||
|
changeScope() { |
||||
|
if (this.form.dataScope === '自定义') { |
||||
|
this.getDepts() |
||||
|
} |
||||
|
}, |
||||
|
checkboxT(row) { |
||||
|
return row.level >= this.level |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style rel="stylesheet/scss" lang="scss"> |
||||
|
.role-span { |
||||
|
font-weight: bold;color: #303133; |
||||
|
font-size: 15px; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style rel="stylesheet/scss" lang="scss" scoped> |
||||
|
.head-container{ |
||||
|
padding: 0 0 20px 0; |
||||
|
} |
||||
|
::v-deep .el-input-number .el-input__inner { |
||||
|
text-align: left; |
||||
|
} |
||||
|
::v-deep .vue-treeselect__multi-value{ |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
::v-deep .vue-treeselect__multi-value-item{ |
||||
|
border: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
::v-deep .el-table__body tr.current-row > td{ |
||||
|
color: #fff; |
||||
|
background-color: #13439E; |
||||
|
} |
||||
|
::v-deep .el-table__header{ |
||||
|
border-top: 1px solid #113D72; |
||||
|
} |
||||
|
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue