improve: 权限规则调整

This commit is contained in:
From-wh 2023-05-06 14:21:04 +08:00
parent 888db8a6ef
commit 913be84f27
4 changed files with 1128 additions and 26 deletions

View File

@ -9,25 +9,25 @@
@submit.native.prevent
>
<Row type="flex" :gutter="24">
<Col v-bind="grid">
<!-- <Col v-bind="grid">
<FormItem label="规则状态:">
<Select v-model="roleData.is_show" placeholder="请选择" clearable @on-change="getData">
<Option value="1">显示</Option>
<Option value="0">不显示</Option>
</Select>
</FormItem>
</Col>
</Col> -->
<Col v-bind="grid">
<FormItem label="按钮名称:" prop="status2" label-for="status2">
<Input v-model="roleData.keyword" search enter-button placeholder="请输入按钮名称" @on-search="getData" />
</FormItem>
</Col>
</Row>
<Row type="flex">
<!-- <Row type="flex">
<Col v-bind="grid">
<Button type="primary" @click="menusAdd('添加规则')" icon="md-add">添加规则 </Button>
</Col>
</Row>
</Row> -->
</Form>
<vxe-table
:border="false"
@ -46,38 +46,24 @@
<vxe-table-column field="menu_path" title="路由" min-width="240" tooltip="true">
<template v-slot="{ row }">
<span v-if="row.auth_type == 1">页面:{{ row.menu_path }}</span>
<span v-if="row.auth_type == 2">接口:[{{ row.methods }}]{{ row.api_url }}</span>
<span v-if="row.auth_type == 2">按钮:[{{ row.methods }}]{{ row.api_url }}</span>
</template>
</vxe-table-column>
<vxe-table-column field="flag" title="规则状态" min-width="120">
<vxe-table-column field="flag" title="是否显示" min-width="120">
<template v-slot="{ row }">
<i-switch
v-model="row.is_show"
:value="row.is_show"
v-model="row.is_show_path"
:value="row.is_show_path"
:true-value="1"
:false-value="0"
@on-change="onchangeIsShow(row)"
size="large"
>
<span slot="open">开启</span>
<span slot="close">关闭</span>
<span slot="open">显示</span>
<span slot="close">隐藏</span>
</i-switch>
</template>
</vxe-table-column>
<vxe-table-column field="date" title="操作" align="right" width="250" fixed="right">
<template v-slot="{ row }">
<span>
<a @click="addRoute(row)" v-if="row.auth_type === 1">添加权限</a>
<Divider type="vertical" v-if="row.auth_type === 1" />
<a @click="addE(row, '添加子菜单')" v-if="row.auth_type === 1">添加子菜单</a>
<!-- <a @click="addE(row, '添加规则')" v-else>添加规则</a> -->
</span>
<Divider type="vertical" v-if="row.auth_type === 1" />
<a @click="edit(row, '编辑')">编辑</a>
<Divider type="vertical" />
<a @click="del(row, '删除规则')">删除</a>
</template>
</vxe-table-column>
</vxe-table>
</Card>
<menus-from
@ -183,7 +169,7 @@ export default {
xs: 24,
},
roleData: {
is_show: '',
is_show: 1,
keyword: '',
},
defaultProps: {
@ -314,7 +300,8 @@ export default {
onchangeIsShow(row) {
let data = {
id: row.id,
is_show: row.is_show,
is_show_path: row.is_show_path,
is_show: -1,
};
isShowApi(data)
.then(async (res) => {

View File

@ -0,0 +1,545 @@
<template>
<div>
<Modal
v-model="modals"
width="700"
scrollable
closable
:title="titleFrom"
:mask-closable="false"
:z-index="1"
@on-cancel="handleReset"
@on-visible-change="visible"
>
<Form ref="formValidate" :model="formValidate" :label-width="110" @submit.native.prevent>
<!-- <Row type="flex" :gutter="24">
<Col span="24">
<FormItem label="类型:">
<RadioGroup v-model="formValidate.auth_type" @on-change="changeRadio">
<Radio :label="item.value" v-for="(item, i) in optionsRadio" :key="i">
<Icon type="social-apple"></Icon>
<span>{{ item.label }}</span>
</Radio>
</RadioGroup>
</FormItem>
</Col>
</Row> -->
<Row type="flex" :gutter="24">
<Col v-bind="grid">
<FormItem :label="!authType ? '接口名称:' : '按钮名称:'" prop="menu_name">
<div class="add">
<Input v-model="formValidate.menu_name" :placeholder="!authType ? '请输入接口名称' : '请输入按钮名称'">
</Input>
<!-- <Button class="ml10 df" v-show="!authType" @click="getRuleList()" icon="ios-apps"></Button> -->
</div>
</FormItem>
</Col>
<Col v-bind="grid">
<FormItem label="父级分类:">
<Cascader :data="menuList" change-on-select v-model="formValidate.path" filterable></Cascader>
</FormItem>
</Col>
<!-- <Col v-bind="grid" v-if="!authType">
<FormItem label="请求方式:" prop="methods">
<Select v-model="formValidate.methods">
<Option value="">请求</Option>
<Option value="GET">GET</Option>
<Option value="POST">POST</Option>
<Option value="PUT">PUT</Option>
<Option value="DELETE">DELETE</Option>
</Select>
</FormItem>
</Col> -->
<!-- <Col v-bind="grid" v-if="!authType">
<FormItem label="接口地址:">
<Input v-model="formValidate.api_url" placeholder="请输入接口地址" prop="api_url"></Input>
</FormItem>
</Col> -->
<Col v-bind="grid" v-show="authType">
<FormItem label="路由地址:" prop="menu_path">
<Input v-model="formValidate.menu_path" placeholder="请输入路由地址" @on-change="changeUnique">
<template #prepend>
<span>{{ $routeProStr }}</span>
</template>
</Input>
</FormItem>
</Col>
<Col v-bind="grid">
<FormItem label="权限标识:" prop="unique_auth">
<Input v-model="formValidate.unique_auth" placeholder="请输入权限标识"></Input>
</FormItem>
</Col>
<Col v-bind="grid" v-if="authType">
<FormItem label="图标:">
<Input
v-model="formValidate.icon"
placeholder="请选择图标,点击右面图标"
icon="ios-appstore"
@on-click="iconClick"
></Input>
</FormItem>
</Col>
<Col v-bind="grid" v-if="authType">
<FormItem label="排序:">
<Input type="number" v-model="formValidate.sort" placeholder="请输入排序" number></Input>
</FormItem>
</Col>
<!-- <Col v-bind="grid" v-show="authType">
<FormItem label="隐藏菜单:">
<RadioGroup v-model="formValidate.is_show_path">
<Radio :label="item.value" v-for="(item, i) in isShowPathRadio" :key="i">
<Icon type="social-apple"></Icon>
<span>{{ item.label }}</span>
</Radio>
</RadioGroup>
</FormItem>
</Col> -->
<Col v-bind="grid">
<FormItem label="状态:">
<RadioGroup v-model="formValidate.is_show">
<Radio :label="item.value" v-for="(item, i) in isShowRadio" :key="i">
<Icon type="social-apple"></Icon>
<span>{{ item.label }}</span>
</Radio>
</RadioGroup>
</FormItem>
</Col>
</Row>
</Form>
<template #footer>
<Button @click="modals = false">取消</Button>
<Button type="primary" @click="handleSubmit('formValidate')" :disabled="valids">提交</Button>
</template>
</Modal>
<Modal v-model="modal12" scrollable width="600" title="图标选择" footer-hide>
<Input
v-model="iconVal"
placeholder="输入关键词搜索,注意全是英文"
clearable
style="width: 300px"
@on-change="upIcon(iconVal)"
ref="search"
/>
<div class="trees-coadd">
<div class="scollhide">
<div class="iconlist">
<ul class="list-inline">
<li class="icons-item" v-for="(item, i) in list" :key="i" :title="item.type">
<Icon :type="item.type" @click="iconChange(item.type)" class="ivu-icon" />
</li>
</ul>
</div>
</div>
</div>
</Modal>
<Modal v-model="ruleModal" scrollable width="1100" title="权限列表" footer-hide @on-visible-change="modalchange">
<div class="search-rule">
<Input
class="mr10"
v-model="searchRule"
placeholder="输入关键词搜索"
clearable
style="width: 300px"
ref="search"
/>
<Button class="mr10" type="primary" @click="searchRules">搜索</Button>
<Button @click="init">重置</Button>
</div>
<div class="rule">
<div
class="rule-list"
v-show="!arrs.length || arrs.includes(index)"
:class="{ 'select-rule': arrs.includes(index) }"
v-for="(item, index) in ruleList"
:key="index"
@click="selectRule(item)"
>
<div>接口名称:{{ item.real_name }}</div>
<div>请求方式:{{ item.method }}</div>
<div>接口地址:{{ item.rule }}</div>
</div>
</div>
</Modal>
</div>
</template>
<script>
import { addMenusApi, addMenus, getRuleList } from '@/api/systemMenus';
import icon from '@/utils/icon';
export default {
name: 'menusFrom',
props: {
formValidate: {
type: Object,
default: null,
},
titleFrom: {
type: String,
default: '',
},
},
data() {
return {
arrs: [],
searchRule: '',
iconVal: '',
grid: {
xl: 12,
lg: 12,
md: 12,
sm: 24,
xs: 24,
},
modals: false,
modal12: false,
FromData: [],
valids: false,
list2: [],
list: icon,
authType: true,
search: icon,
ruleModal: false,
ruleList: [],
};
},
watch: {
'formValidate.header': function (n) {
this.formValidate.is_header = n ? 1 : 0;
},
'formValidate.auth_type': function (n) {
if (n === undefined) {
n = 1;
}
this.authType = n === 1;
},
'formValidate.data': function (n) {},
},
computed: {
/* eslint-disable */
optionsList() {
let a = [];
this.FromData.map((item) => {
if ('pid' === item.field) {
a = item.options;
}
});
return a;
},
headerOptionsList() {
let a = [];
this.FromData.map((item) => {
if ('header' === item.field) {
a = item.options;
}
});
return a;
},
optionsListmodule() {
let a = [];
this.FromData.map((item) => {
if ('module' === item.field) {
a = item.options;
}
});
return a;
},
optionsRadio() {
let a = [];
this.FromData.map((item) => {
if ('auth_type' === item.field) {
a = item.options;
}
});
return a;
},
isheaderRadio() {
let a = [];
this.FromData.map((item) => {
if ('is_header' === item.field) {
a = item.options;
}
});
return a;
},
isShowRadio() {
let a = [];
this.FromData.map((item) => {
if ('is_show' === item.field) {
a = item.options;
}
});
return a;
},
isShowPathRadio() {
let a = [];
this.FromData.map((item) => {
if ('is_show_path' === item.field) {
a = item.options;
}
});
return a;
},
menuList() {
let a = [];
this.FromData.map((item) => {
if ('menu_list' === item.field) {
a = item.props.data;
}
});
return a;
},
},
methods: {
// 获取权限列表
getRuleList() {
getRuleList().then((res) => {
this.ruleList = res.data;
this.ruleModal = true;
});
},
modalchange(type) {
if (!type) {
this.arrs = [];
this.ruleModal = '';
this.ruleModal = false;
}
},
changeUnique(val) {
let value = this.$routeProStr + val.target.value;
if (value.slice(0, 1) === '/') value = value.replace('/', '');
this.formValidate.unique_auth = value.replaceAll('/', '-');
},
visible(type) {
if (!type) {
this.authType = true;
}
},
selectRule(data) {
this.$emit('selectRule', data);
this.$nextTick((e) => {
this.ruleModal = false;
});
},
changeRadio(n) {
this.authType = n === 1 ? true : false;
},
// 搜索
upIcon(n) {
let arrs = [];
for (var i = 0; i < this.search.length; i++) {
if (this.search[i].type.indexOf(n) !== -1) {
arrs.push(this.search[i]);
this.list = arrs;
}
}
},
// 搜索规则
searchRules() {
if (this.searchRule.trim()) {
this.arrs = [];
for (var i = 0; i < this.ruleList.length; i++) {
if (this.ruleList[i].real_name.indexOf(this.searchRule) !== -1) {
this.arrs.push(i);
}
}
} else {
this.arrs = [];
}
},
init() {
this.searchRule = '';
this.arrs = [];
},
handleCreate1(val) {
this.headerOptionsList.push({
value: val,
label: val,
});
},
// 获取新增表单
getAddFrom() {
addMenus()
.then(async (res) => {
this.FromData = res.data.rules;
})
.catch((res) => {
this.$Message.error(res.msg);
});
},
iconClick() {
this.modal12 = true;
},
iconChange(n) {
this.formValidate.icon = n;
this.modal12 = false;
},
// 提交
handleSubmit(name) {
//判断是否选择父级分类
if (this.formValidate.path) {
let length = this.formValidate.path.length;
this.formValidate.pid = this.formValidate.path[length - 1] || 0;
}
let data = {
url: this.formValidate.id ? `/setting/menus/${this.formValidate.id}` : '/setting/menus',
method: this.formValidate.id ? 'put' : 'post',
datas: this.formValidate,
};
if (this.authType) {
if (!this.formValidate.menu_name) {
return this.$Message.warning('请填写按钮名称');
}
if (!this.formValidate.menu_path) {
return this.$Message.warning('请填写路由地址');
}
} else {
if (!this.formValidate.menu_name) {
return this.$Message.warning('请填写接口名称');
}
if (!this.formValidate.methods) {
return this.$Message.warning('请选择请求方式');
}
if (!this.formValidate.api_url) {
return this.$Message.warning('请选择接口地址');
}
}
this.valids = true;
addMenusApi(data)
.then(async (res) => {
this.$Message.success(res.msg);
this.modals = false;
this.$emit('changeMenu');
this.getAddFrom();
// this.$store.dispatch('menus/getMenusNavList');
})
.catch((res) => {
this.valids = false;
this.$Message.error(res.msg);
});
},
handleReset() {
this.modals = false;
this.authType = true;
this.$refs['formValidate'].resetFields();
this.$emit('clearFrom');
},
},
created() {
this.list = this.search;
this.getAddFrom();
},
};
</script>
<style scoped>
.trees-coadd {
width: 100%;
height: 500px;
border-radius: 4px;
overflow: hidden;
}
.scollhide {
width: 100%;
height: 100%;
overflow: auto;
margin-left: 18px;
padding: 10px 0 10px 0;
box-sizing: border-box;
}
.content {
font-size: 12px;
}
.time {
font-size: 12px;
color: #2d8cf0;
}
.icons-item {
float: left;
margin: 6px 6px 6px 0;
width: 53px;
text-align: center;
list-style: none;
cursor: pointer;
height: 50px;
color: #5c6b77;
transition: all 0.2s ease;
position: relative;
padding-top: 10px;
}
.icons-item .ivu-icon {
font-size: 16px;
}
.search-rule {
display: flex;
align-items: center;
padding: 10px;
background-color: #f2f2f2;
}
.rule {
display: flex;
flex-wrap: wrap;
max-height: 700px;
overflow: scroll;
}
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
.rule::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: #f5f5f5;
}
/*定义滚动条轨道 内阴影+圆角*/
.rule::-webkit-scrollbar-track {
border-radius: 4px;
background-color: #f5f5f5;
}
/*定义滑块 内阴影+圆角*/
.rule::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: #555;
}
.rule-list {
background-color: #f8f5f5;
width: 32%;
margin: 5px;
border-radius: 3px;
padding: 10px;
color: #333;
cursor: pointer;
transition: all 0.1s;
}
.rule-list:hover {
background-color: #c5d1dd;
}
.rule-list div {
white-space: nowrap;
}
.select-rule {
background-color: #c5d1dd;
}
.add {
display: flex;
align-items: center;
}
.df {
display: flex;
justify-content: center;
}
</style>

View File

@ -0,0 +1,561 @@
<template>
<div>
<Card :bordered="false" dis-hover class="ivu-mt">
<Form
ref="roleData"
:model="roleData"
:label-width="labelWidth"
:label-position="labelPosition"
@submit.native.prevent
>
<Row type="flex" :gutter="24">
<Col v-bind="grid">
<FormItem label="规则状态:">
<Select v-model="roleData.is_show" placeholder="请选择" clearable @on-change="getData">
<Option value="1">显示</Option>
<Option value="0">不显示</Option>
</Select>
</FormItem>
</Col>
<Col v-bind="grid">
<FormItem label="按钮名称:" prop="status2" label-for="status2">
<Input v-model="roleData.keyword" search enter-button placeholder="请输入按钮名称" @on-search="getData" />
</FormItem>
</Col>
</Row>
<Row type="flex">
<Col v-bind="grid">
<Button type="primary" @click="menusAdd('添加规则')" icon="md-add">添加规则 </Button>
</Col>
</Row>
</Form>
<vxe-table
:border="false"
class="vxeTable mt25"
highlight-hover-row
highlight-current-row
:loading="loading"
ref="xTable"
header-row-class-name="false"
:tree-config="tabconfig"
:data="tableData"
row-id="id"
>
<vxe-table-column field="menu_name" tree-node title="按钮名称" min-width="100"></vxe-table-column>
<vxe-table-column field="unique_auth" title="前端权限" min-width="200"></vxe-table-column>
<vxe-table-column field="menu_path" title="路由" min-width="240" tooltip="true">
<template v-slot="{ row }">
<span v-if="row.auth_type == 1">页面:{{ row.menu_path }}</span>
<span v-if="row.auth_type == 2">接口:[{{ row.methods }}]{{ row.api_url }}</span>
</template>
</vxe-table-column>
<vxe-table-column field="flag" title="规则状态" min-width="120">
<template v-slot="{ row }">
<i-switch
v-model="row.is_show"
:value="row.is_show"
:true-value="1"
:false-value="0"
@on-change="onchangeIsShow(row)"
size="large"
>
<span slot="open">开启</span>
<span slot="close">关闭</span>
</i-switch>
</template>
</vxe-table-column>
<vxe-table-column field="date" title="操作" align="right" width="250" fixed="right">
<template v-slot="{ row }">
<span>
<a @click="addRoute(row)" v-if="row.auth_type === 1">添加权限</a>
<Divider type="vertical" v-if="row.auth_type === 1" />
<a @click="addE(row, '添加子菜单')" v-if="row.auth_type === 1">添加子菜单</a>
<!-- <a @click="addE(row, '添加规则')" v-else>添加规则</a> -->
</span>
<Divider type="vertical" v-if="row.auth_type === 1" />
<a @click="edit(row, '编辑')">编辑</a>
<Divider type="vertical" />
<a @click="del(row, '删除规则')">删除</a>
</template>
</vxe-table-column>
</vxe-table>
</Card>
<menus-from
:formValidate="formValidate"
:titleFrom="titleFrom"
@getList="getList"
@changeMenu="getMenusUnique"
ref="menusFrom"
@clearFrom="clearFrom"
></menus-from>
<Modal
v-model="ruleModal"
scrollable
width="1100"
title="权限列表"
@on-ok="addRouters"
@on-cancel="ruleModal = false"
@on-visible-change="modalchange"
>
<div class="search-rule">
<Alert
>基础接口,可多选,并且添加后不会再展示出现;删除权限后才会出现;公共接口,可多选,并且添加后会继续展示;</Alert
>
<Input
class="mr10"
v-model="searchRule"
placeholder="输入关键词搜索"
clearable
style="width: 300px"
ref="search"
@on-enter="searchRules"
@on-clear="searchRules"
/>
<Button class="mr10" type="primary" @click="searchRules">搜索</Button>
<Button @click="init">重置</Button>
</div>
<div class="route-list">
<div class="tree">
<el-tree
ref="treeBox"
:data="ruleCateList"
:highlight-current="true"
:props="defaultProps"
node-key="id"
:default-expanded-keys="expandedKeys"
:current-node-key="nodeKey"
@node-click="handleNodeClick"
></el-tree>
</div>
<div class="rule">
<div
class="rule-list"
v-show="!arrs.length || arrs.includes(item.id)"
:class="{ 'select-rule': seletRouteIds.includes(item.id) }"
v-for="(item, index) in children"
:key="index"
@click="selectRule(item)"
>
<div>接口名称:{{ item.name }}</div>
<div>请求方式:{{ item.method }}</div>
<div>接口地址:{{ item.path }}</div>
</div>
</div>
</div>
<!-- <Tabs v-model="routeType" @on-click="changTab">
<TabPane :label="item.name" :name="'' + index" v-for="(item, index) in foundationList" :key="item"></TabPane>
</Tabs> -->
</Modal>
</div>
</template>
<script>
import { mapState } from 'vuex';
import {
getTable,
menusDetailsApi,
isShowApi,
editMenus,
getRuleList,
menusBatch,
getMenusUnique,
menusRuleCate,
} from '@/api/systemMenus';
import formCreate from '@form-create/iview';
import menusFrom from './components/menusFrom';
import { formatFlatteningRoutes, findFirstNonNullChildren, findFirstNonNullChildrenKeys } from '@/libs/system';
export default {
name: 'systemMenus',
data() {
return {
children: [],
expandedKeys: [],
tabconfig: { children: 'children', reserve: true, accordion: true },
spinShow: false,
ruleModal: false,
searchRule: '',
grid: {
xl: 7,
lg: 7,
md: 12,
sm: 24,
xs: 24,
},
roleData: {
is_show: '',
keyword: '',
},
defaultProps: {
children: 'children',
label: 'name',
},
ruleCateList: [], //权限树
loading: false,
tableData: [],
FromData: null,
icons: '',
formValidate: {},
titleFrom: '',
modalTitleSs: '',
routeType: '0',
arrs: [],
foundationList: [], // 基础接口列表
openList: [], // 公开接口列表
seletRoute: [], // 选中路由
seletRouteIds: [], // 选中id
menusId: 0, // 选中分类id
nodeKey: 0, // 选中节点
};
},
components: { menusFrom, formCreate: formCreate.$form() },
computed: {
...mapState('admin/layout', ['isMobile']),
labelWidth() {
return this.isMobile ? undefined : 75;
},
labelPosition() {
return this.isMobile ? 'top' : 'right';
},
},
mounted() {
this.getData();
},
methods: {
init() {
this.searchRule = '';
this.searchRules();
},
addRouters() {
let data = {
menus: this.seletRoute,
};
menusBatch(data)
.then((res) => {
this.getData();
})
.catch((res) => {
this.$Message.error(res.msg);
});
},
selectRule(data) {
if (this.seletRouteIds.includes(data.id)) {
let i = this.seletRouteIds.findIndex((e) => e == data.id);
this.seletRouteIds.splice(i, 1);
this.seletRoute.splice(i, 1);
} else {
this.seletRouteIds.push(data.id);
this.seletRoute.push({
menu_name: data.name,
unique_auth: '',
api_url: data.path,
path: this.menusId,
method: data.method,
});
}
},
changTab(name) {
this.routeType = name;
let index = parseInt(name);
this.children = this.foundationList[index] ? this.foundationList[index].children : [];
this.searchRules();
},
// 搜索规则
searchRules() {
if (this.searchRule.trim()) {
this.arrs = [];
let arr = this.foundationList;
for (var i = 0; i < arr.length; i++) {
if (arr[i].name.indexOf(this.searchRule) !== -1) {
this.arrs.push(arr[i].id);
}
}
} else {
this.arrs = [];
}
},
addRoute(row) {
this.menusId = row.id;
this.routeType = '0';
// this.getRuleList();
menusRuleCate().then((res) => {
this.ruleCateList = res.data;
this.ruleModal = true;
if (res.data.length) {
this.$nextTick((e) => {
this.expandedKeys = findFirstNonNullChildrenKeys(res.data[0], []);
this.nodeKey = findFirstNonNullChildren(res.data).id;
this.$refs.treeBox.setCurrentKey(this.nodeKey);
this.getRuleList(this.nodeKey);
});
}
});
},
handleNodeClick(data) {
this.getRuleList(data.id);
},
modalchange() {
this.seletRouteIds = [];
this.seletRoute = [];
},
// 获取权限列表
getRuleList(cate_id) {
getRuleList(cate_id).then((res) => {
this.foundationList = res.data;
this.children = res.data;
this.searchRules();
// this.openList = [];
// this.seletRouteIds = [];
// this.seletRoute = [];
});
},
// 修改规则状态
onchangeIsShow(row) {
let data = {
id: row.id,
is_show: row.is_show,
};
isShowApi(data)
.then(async (res) => {
this.$Message.success(res.msg);
this.$store.dispatch('menus/getMenusNavList');
})
.catch((res) => {
this.$Message.error(res.msg);
});
},
// 请求列表
getList() {
this.formValidate = Object.assign({}, this.$options.data().formValidate);
this.getData();
},
// 清除表单数据
clearFrom() {
this.formValidate = Object.assign({}, this.$options.data().formValidate);
},
// 添加子菜单
addE(row, title) {
this.formValidate = {};
let pid = row.id.toString();
if (pid) {
menusDetailsApi(row.id)
.then(async (res) => {
this.formValidate.path = res.data.path;
this.formValidate.path.push(row.id);
this.formValidate.pid = pid;
this.$refs.menusFrom.modals = true;
this.$refs.menusFrom.valids = false;
this.titleFrom = title;
this.formValidate.auth_type = 1;
this.formValidate.is_show = 0;
this.formValidate.is_show_path = 0;
})
.catch((res) => {
this.$Message.error(res.msg);
});
} else {
this.formValidate.pid = pid;
this.$refs.menusFrom.modals = true;
this.$refs.menusFrom.valids = false;
this.titleFrom = title;
this.formValidate.auth_type = 1;
this.formValidate.is_show = 0;
this.formValidate.is_show_path = 0;
}
// this.formValidate.pid = row.id.toString();
// this.$refs.menusFrom.modals = true;
// this.$refs.menusFrom.valids = false;
// this.titleFrom = title;
// this.formValidate.auth_type = 1;
// this.formValidate.is_show = '0';
},
// 删除
del(row, tit) {
let delfromData = {
title: tit,
url: `/setting/menus/${row.id}`,
method: 'DELETE',
ids: '',
};
this.$modalSure(delfromData)
.then((res) => {
this.$Message.success(res.msg);
this.getData();
this.getMenusUnique();
// this.$store.dispatch('menus/getMenusNavList');
})
.catch((res) => {
this.$Message.error(res.msg);
});
},
// 规则详情
menusDetails(id) {
menusDetailsApi(id)
.then(async (res) => {
this.formValidate = res.data;
this.$refs.menusFrom.modals = true;
})
.catch((res) => {
this.$Message.error(res.msg);
});
},
// 编辑
edit(row, title, index) {
this.formValidate = {};
this.menusDetails(row.id);
this.titleFrom = title;
this.$refs.menusFrom.valids = false;
this.$refs.menusFrom.getAddFrom(row.id);
},
// 添加
menusAdd(title) {
this.formValidate = {};
this.$refs.menusFrom.modals = true;
this.$refs.menusFrom.valids = false;
// this.formValidate = Object.assign(this.$data, this.$options.formValidate());
this.titleFrom = title;
this.formValidate.auth_type = 1;
this.formValidate.is_show = 0;
this.formValidate.is_show_path = 0;
},
// 新增页面表单
// getAddFrom () {
// this.spinShow = true;
// addMenus(this.roleData).then(async res => {
// this.FromData = res.data;
// this.$refs.menusFrom.modals = true;
// this.spinShow = false;
// }).catch(res => {
// this.spinShow = false;
// this.$Message.error(res.msg);
// })
// },
// 列表
getData() {
this.loading = true;
this.roleData.is_show = this.roleData.is_show || '';
getTable(this.roleData)
.then(async (res) => {
this.tableData = res.data;
this.loading = false;
})
.catch((res) => {
this.loading = false;
this.$Message.error(res.msg);
});
},
getMenusUnique() {
getMenusUnique().then((res) => {
let data = res.data;
this.$store.commit('userInfo/uniqueAuth', data.uniqueAuth);
this.$store.commit('menus/getmenusNav', data.menus);
this.$store.dispatch('routesList/setRoutesList', data.menus);
let arr = formatFlatteningRoutes(this.$router.options.routes);
this.formatTwoStageRoutes(arr);
let routes = formatFlatteningRoutes(data.menus);
this.$store.commit('menus/setOneLvRoute', routes);
this.bus.$emit('routesListChange');
});
},
formatTwoStageRoutes(arr) {
if (arr.length <= 0) return false;
const newArr = [];
const cacheList = [];
arr.forEach((v) => {
if (v && v.meta && v.meta.keepAlive) {
newArr.push({ ...v });
cacheList.push(v.name);
this.$store.dispatch('keepAliveNames/setCacheKeepAlive', cacheList);
}
});
return newArr;
},
// 关闭按钮
cancel() {
this.$emit('onCancel');
},
},
};
</script>
<style scoped lang="scss">
.vxeTable {
> .vxe-table--header-wrapper {
background: #fff !important;
}
.icon {
font-size: 20px;
}
}
.rule {
display: flex;
flex-wrap: wrap;
overflow-y: scroll;
height: max-content;
max-height: 600px;
flex: 1;
}
.tree::-webkit-scrollbar {
width: 2px;
background-color: #f5f5f5;
}
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
.rule::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: #f5f5f5;
}
/*定义滚动条轨道 内阴影+圆角*/
.rule::-webkit-scrollbar-track {
border-radius: 4px;
background-color: #f5f5f5;
}
/*定义滑块 内阴影+圆角*/
.rule::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: #ccc;
}
.rule-list {
background-color: #f2f2f2;
width: 48.5%;
height: max-content;
margin: 5px;
border-radius: 3px;
padding: 10px;
color: #333;
cursor: pointer;
transition: all 0.1s;
}
.rule-list:hover {
background-color: #badbfb;
}
.rule-list div {
white-space: nowrap;
}
.select-rule {
background-color: #badbfb;
}
.route-list {
display: flex;
margin-top: 10px;
.tree {
width: 200px;
overflow-y: scroll;
max-height: 600px;
/deep/ .el-tree-node__children .el-tree-node .el-tree-node__content {
padding-left: 14px !important;
}
}
}
</style>

View File

@ -190,5 +190,14 @@ export default {
},
component: () => import('@/pages/system/crontab/index'),
},
{
path: 'system_menus/index',
name: `${pre}systemMenus`,
meta: {
auth: ['system-system-menus'],
title: '权限规则',
},
component: () => import('@/pages/system/systemMenus/index'),
},
],
};