feat:权限改版第一版

feature/permission-0723-ch
ch 3 years ago
parent ca1149eb9c
commit eaf030fa6f

@ -1,4 +1,4 @@
VITE_BASE_URL=https://k8s-horse-gateway.mashibing.cn
VITE_BASE_URL=http://192.168.10.27:8090
VITE_SOCKET_URL=wss://k8s-horse-gateway.mashibing.cn/ws
VITE_BROWSER_URL = https://k8s-shop-pc.mashibing.cn

2
components.d.ts vendored

@ -14,6 +14,7 @@ declare module 'vue' {
ElCascader: typeof import('./src/components/extra/ElCascader.vue')['default']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('./src/components/extra/ElCheckboxGroup.vue')['default']
ElCol: typeof import('element-plus/es')['ElCol']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
@ -35,6 +36,7 @@ declare module 'vue' {
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('./src/components/extra/ElRadioGroup.vue')['default']
ElRate: typeof import('element-plus/es')['ElRate']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('./src/components/extra/ElSelect.vue')['default']
ElStep: typeof import('element-plus/es')['ElStep']

@ -0,0 +1,800 @@
/*
* @Author: ch
* @Date: 2022-07-23 10:21:58
* @LastEditors: ch
* @LastEditTime: 2022-07-23 11:10:13
* @Description: 维护路由及权限的文件每次路由有更新需要到后台去导入
*/
export default [
{
id: 40,
parentId: 0,
systemId: 1,
title: '首页',
permission: 'App',
type: 0,
page: 'Layout',
path: '/',
icon: 'home-fill',
sort: 0,
menuChild: [
{
id: 41,
parentId: 40,
systemId: 1,
title: '数据看板',
permission: 'Home',
type: 1,
page: 'home',
path: 'home',
icon: 'home-fill',
sort: 10,
menuChild: null,
},
],
},
{
id: 32,
parentId: 0,
systemId: 1,
title: '商品',
permission: 'Product',
type: 0,
page: 'Layout',
path: 'product',
icon: 'product-hunt-fill',
sort: 10,
menuChild: [
{
id: 52,
parentId: 32,
systemId: 1,
title: '商品评价',
permission: 'CommentManagement',
type: 1,
page: 'goods/comment/list',
path: 'comment',
icon: 'Comment',
sort: 0,
menuChild: [
{
id: 53,
parentId: 52,
systemId: 1,
title: '评价详情',
permission: 'CommentDetail',
type: 2,
page: 'goods/comment/detail',
path: 'detail/:id',
icon: 'Comment',
sort: 0,
menuChild: null,
},
],
},
{
id: 26,
parentId: 32,
systemId: 1,
title: '商品列表',
permission: 'ProductManagement',
type: 1,
page: 'sales/product',
path: 'management',
icon: 'MessageBox',
sort: 10,
menuChild: [
{
id: 27,
parentId: 26,
systemId: 1,
title: '创建商品',
permission: 'CreateProduct',
type: 2,
page: 'sales/product/form',
path: 'create',
icon: 'MessageBox',
sort: 10,
menuChild: null,
},
{
id: 28,
parentId: 26,
systemId: 1,
title: '编辑商品',
permission: 'UpdateProduct',
type: 2,
page: 'sales/product/form',
path: 'update/:id/:step?',
icon: 'MessageBox',
sort: 20,
menuChild: null,
},
],
},
{
id: 23,
parentId: 32,
systemId: 1,
title: '商品分类',
permission: 'CategoryManagement',
type: 1,
page: 'sales/category',
path: 'category',
icon: 'TakeawayBox',
sort: 20,
menuChild: [
{
id: 24,
parentId: 23,
systemId: 1,
title: '创建分类',
permission: 'CreateCategory',
type: 2,
page: 'sales/category/form',
path: 'create',
icon: 'TakeawayBox',
sort: 10,
menuChild: null,
},
{
id: 25,
parentId: 23,
systemId: 1,
title: '编辑分类',
permission: 'UpdateCategory',
type: 2,
page: 'sales/category/form',
path: 'update/:id',
icon: 'TakeawayBox',
sort: 20,
menuChild: null,
},
],
},
],
},
{
id: 18,
parentId: 0,
systemId: 1,
title: '订单',
permission: 'SalesCenter',
type: 0,
page: 'Layout',
path: '/sales',
icon: 'money-dollar-circle-fill',
sort: 20,
menuChild: [
{
id: 19,
parentId: 18,
systemId: 1,
title: '订单列表',
permission: 'OrderManagement',
type: 1,
page: 'sales/order',
path: 'order',
icon: 'Checked',
sort: 10,
menuChild: [
{
id: 20,
parentId: 19,
systemId: 1,
title: '订单详情',
permission: 'OrderDetail',
type: 2,
page: 'sales/order/detail',
path: 'detail/:id',
icon: 'Checked',
sort: 10,
menuChild: null,
},
],
},
{
id: 21,
parentId: 18,
systemId: 1,
title: '售后申请处理',
permission: 'ServiceApplication',
type: 0,
page: 'sales/service',
path: 'service',
icon: 'barcode-box-fill',
sort: 20,
menuChild: [
{
id: 22,
parentId: 21,
systemId: 1,
title: '售后详情',
permission: 'ServiceDetail',
type: 2,
page: 'sales/service/detail',
path: 'detail/:id',
icon: 'barcode-box-fill',
sort: 10,
menuChild: null,
},
],
},
],
},
{
id: 34,
parentId: 0,
systemId: 1,
title: '用户',
permission: 'Customer',
type: 0,
page: 'Layout',
path: '/customer',
icon: 'user-5-fill',
sort: 30,
menuChild: [
{
id: 30,
parentId: 34,
systemId: 1,
title: '用户列表',
permission: 'CustomerManagement',
type: 1,
page: 'system/customer',
path: 'customer',
icon: 'user-1',
sort: 10,
menuChild: null,
},
],
},
{
id: 6,
parentId: 0,
systemId: 1,
title: '促销',
permission: 'OperationCenter',
type: 0,
page: 'Layout',
path: '/operation',
icon: 'computer-fill',
sort: 40,
menuChild: [
{
id: 7,
parentId: 6,
systemId: 1,
title: '秒杀活动',
permission: 'LimitActivity',
type: 1,
page: 'operation/limit',
path: 'limit',
icon: 'auction',
sort: 10,
menuChild: [
{
id: 8,
parentId: 7,
systemId: 1,
title: '设置时段',
permission: 'UpdateLimitTime',
type: 2,
page: 'operation/limit/time',
path: 'time/:id',
icon: 'fire-fill',
sort: 10,
menuChild: null,
},
{
id: 9,
parentId: 7,
systemId: 1,
title: '设置商品',
permission: 'UpdateLimitProduct',
type: 2,
page: 'operation/limit/product',
path: 'product/:id',
icon: 'fire-fill',
sort: 20,
menuChild: null,
},
],
},
{
id: 10,
parentId: 6,
systemId: 1,
title: '推荐专区',
permission: 'RecommandActivity',
type: 1,
page: 'operation/recommend',
path: 'recommend',
icon: 'fire',
sort: 20,
menuChild: null,
},
],
},
{
id: 29,
parentId: 0,
systemId: 1,
title: '运营',
permission: 'SystemManagement',
type: 0,
page: 'Layout',
path: '/system',
icon: 'base-station',
sort: 50,
menuChild: [
{
id: 31,
parentId: 29,
systemId: 1,
title: '消息管理',
permission: 'NotifyManagement',
type: 1,
page: 'system/notify',
path: 'notify',
icon: 'notification-2',
sort: 20,
menuChild: null,
},
{
id: 36,
parentId: 29,
systemId: 1,
title: '广告管理',
permission: 'AdvertiseManagement',
type: 1,
page: 'operation/advertise',
path: 'advertise',
icon: 'advertisement',
sort: 20,
menuChild: [
{
id: 37,
parentId: 36,
systemId: 1,
title: '创建广告',
permission: 'CreateAdvertise',
type: 2,
page: 'operation/advertise/form',
path: 'create',
icon: 'advertisement',
sort: 10,
menuChild: null,
},
{
id: 38,
parentId: 36,
systemId: 1,
title: '编辑广告',
permission: 'UpdateAdvertise',
type: 2,
page: 'operation/advertise/form',
path: 'update/:id',
icon: 'advertisement',
sort: 20,
menuChild: null,
},
],
},
],
},
{
id: 2,
parentId: 0,
systemId: 1,
title: '设置',
permission: 'ChatManagement',
type: 0,
page: 'Layout',
path: '/chat',
icon: 'settings-3-fill',
sort: 60,
menuChild: [
{
id: 46,
parentId: 2,
systemId: 1,
title: '订单设置',
permission: 'OrderConfig',
type: 1,
page: 'config/order',
path: 'order',
icon: 'file-settings',
sort: 20,
menuChild: null,
},
],
},
{
id: 50,
parentId: 0,
systemId: 1,
title: '客服',
permission: 'CustomerService',
type: 0,
page: 'Layout',
path: 'cs',
icon: 'wechat-2-fill',
sort: 60,
menuChild: [
{
id: 4,
parentId: 50,
systemId: 1,
title: '聊天会话',
permission: 'ChatSession',
type: 1,
page: 'chat',
path: 'session',
icon: 'wechat-2-fill',
sort: 10,
menuChild: null,
},
{
id: 51,
parentId: 50,
systemId: 1,
title: '客服管理',
permission: 'WaiterManagement',
type: 1,
page: 'chat/waiter',
path: 'waiter',
icon: 'customer-service-2',
sort: 20,
menuChild: null,
},
],
},
{
id: 35,
parentId: 0,
systemId: 1,
title: 'IM中台',
permission: 'IM',
type: 0,
page: 'Layout',
path: 'im',
icon: 'wechat-2-fill',
sort: 70,
menuChild: [
{
id: 44,
parentId: 35,
systemId: 1,
title: '首页',
permission: 'ImHome',
type: 1,
page: 'im/home',
path: 'home',
icon: 'home-heart',
sort: 20,
menuChild: null,
},
{
id: 42,
parentId: 35,
systemId: 1,
title: '系统管理',
permission: 'ImSystem',
type: 1,
page: 'im/system',
path: 'system',
icon: 'apps-2',
sort: 30,
menuChild: null,
},
{
id: 43,
parentId: 35,
systemId: 1,
title: '店铺管理',
permission: 'ImStore',
type: 1,
page: 'im/store',
path: 'store',
icon: 'building',
sort: 40,
menuChild: null,
},
{
id: 45,
parentId: 35,
systemId: 1,
title: '客服管理',
permission: 'ImWaiter',
type: 1,
page: 'im/waiter',
path: 'waiter',
icon: 'customer-service-2',
sort: 50,
menuChild: null,
},
],
},
{
id: 11,
parentId: 0,
systemId: 1,
title: '权限中台',
permission: 'UserCenter',
type: 0,
page: 'Layout',
path: '/uc',
icon: 'admin-fill',
sort: 80,
menuChild: [
{
id: 12,
parentId: 11,
systemId: 1,
title: '组织架构',
permission: 'DeptManagement',
type: 1,
page: 'permission/dept',
path: 'dept',
icon: 'organization-chart',
sort: 10,
menuChild: null,
},
{
id: 13,
parentId: 11,
systemId: 1,
title: '菜单管理',
permission: 'MenuManagement',
type: 0,
page: 'permission/menu',
path: 'menu',
icon: 'menu-2',
sort: 20,
menuChild: null,
},
{
id: 14,
parentId: 11,
systemId: 1,
title: '角色管理',
permission: 'RoleManagement',
type: 0,
page: 'permission/role',
path: 'role',
icon: 'account-box-fill',
sort: 30,
menuChild: null,
},
{
id: 15,
parentId: 11,
systemId: 1,
title: '员工管理',
permission: 'EmployeeManagement',
type: 0,
page: 'permission/employee',
path: 'employee',
icon: 'account-box',
sort: 40,
menuChild: [
{
id: 16,
parentId: 15,
systemId: 1,
title: '创建员工',
permission: 'CreateEmployee',
type: 2,
page: 'permission/employee/form',
path: 'create',
icon: 'Avatar',
sort: 10,
menuChild: null,
},
{
id: 17,
parentId: 15,
systemId: 1,
title: '编辑员工',
permission: 'UpdateEmployee',
type: 2,
page: 'permission/employee/form',
path: 'update/:id',
icon: 'Avatar',
sort: 20,
menuChild: null,
},
],
},
],
},
{
id: 54,
parentId: 0,
systemId: 1,
title: '搜索中台',
permission: 'SearchCenter',
type: 0,
page: 'Layout',
path: '/search',
icon: 'search-eye-fill',
sort: 220,
menuChild: [
{
id: 55,
parentId: 54,
systemId: 1,
title: '系统配置',
permission: 'SearchSystem',
type: 1,
page: 'search/system',
path: 'system',
icon: 'apps-2',
sort: 10,
menuChild: null,
},
{
id: 56,
parentId: 54,
systemId: 1,
title: '搜索配置',
permission: 'SearchConfig',
type: 1,
page: 'search/config',
path: 'config',
icon: 'file-settings',
sort: 20,
menuChild: null,
},
],
},
{
id: 57,
parentId: 0,
systemId: 1,
title: '支付中台',
permission: 'PayCenter',
type: 0,
page: 'Layout',
path: '/pay',
icon: 'Wallet',
sort: 230,
menuChild: [
{
id: 58,
parentId: 57,
systemId: 1,
title: '商户管理',
permission: 'PayMerchant',
type: 1,
page: 'pay/merchant',
path: 'merchant',
icon: 'Shop',
sort: 10,
menuChild: [
{
id: 60,
parentId: 58,
systemId: 1,
title: '新增商户',
permission: 'CreateMerchant',
type: 2,
page: 'pay/merchant/form',
path: 'create',
icon: 'Shop',
sort: 0,
menuChild: null,
},
{
id: 61,
parentId: 58,
systemId: 1,
title: '编辑商户',
permission: 'UpdateMerchant',
type: 2,
page: 'pay/merchant/form',
path: 'update/:id',
icon: 'Shop',
sort: 0,
menuChild: null,
},
],
},
{
id: 59,
parentId: 57,
systemId: 1,
title: '应用管理',
permission: 'PayApplication',
type: 1,
page: 'pay/application',
path: 'application',
icon: 'Cellphone',
sort: 20,
menuChild: [
{
id: 62,
parentId: 59,
systemId: 1,
title: '新增应用',
permission: 'CreateApplication',
type: 2,
page: 'pay/application/form',
path: 'create',
icon: 'Cellphone',
sort: 0,
menuChild: null,
},
{
id: 63,
parentId: 59,
systemId: 1,
title: '编辑应用',
permission: 'UpdateApplication',
type: 2,
page: 'pay/application/form',
path: 'update/:id',
icon: 'Cellphone',
sort: 0,
menuChild: null,
},
],
},
{
id: 64,
parentId: 57,
systemId: 1,
title: '支付订单',
permission: 'PayPayOrder',
type: 0,
page: 'pay/payOrder/list',
path: 'payOrder',
icon: 'DocumentChecked',
sort: 30,
menuChild: [
{
id: 66,
parentId: 64,
systemId: 1,
title: '支付订单详情',
permission: 'PayOrderDetail',
type: 2,
page: 'pay/payOrder/detail',
path: 'detail/:id',
icon: 'DocumentChecked',
sort: 0,
menuChild: null,
},
],
},
{
id: 65,
parentId: 57,
systemId: 1,
title: '退款订单',
permission: 'RefundOrder',
type: 0,
page: 'pay/refundOrder/list',
path: 'refundOrder',
icon: 'DocumentDelete',
sort: 40,
menuChild: [
{
id: 67,
parentId: 65,
systemId: 1,
title: '退款订单详情',
permission: 'RefundOrderDetail',
type: 2,
page: 'pay/refundOrder/detail',
path: 'detail/:id',
icon: 'DocumentDelete',
sort: 0,
menuChild: null,
},
],
},
],
},
];

@ -1,17 +1,23 @@
/*
* @Author: ch
* @Date: 2022-05-17 21:23:11
* @LastEditors: ch
* @LastEditTime: 2022-07-20 17:57:02
* @Description: file content
*/
import '@/icons';
import usePlugins from '@/plugins';
import router from '@/router';
import store from '@/store';
import { createApp } from 'vue';
import App from './App.vue';
import '@/icons';
const app = createApp(App);
import store from '@/store';
app.use(store);
import router from '@/router';
app.use(router);
import usePlugins from '@/plugins';
usePlugins(app);
app.mount('#app');

@ -1,11 +1,11 @@
import { ElNotification } from 'element-plus/es/components/notification/index';
import 'element-plus/es/components/notification/style/css';
import { ElMessage } from 'element-plus/es/components/message/index';
import 'element-plus/es/components/message/style/css';
import { ElMessageBox } from 'element-plus/es/components/message-box/index';
import 'element-plus/es/components/message-box/style/css';
import { ElLoading } from 'element-plus/es/components/loading/index';
import 'element-plus/es/components/loading/style/css';
import { ElMessageBox } from 'element-plus/es/components/message-box/index';
import 'element-plus/es/components/message-box/style/css';
import { ElMessage } from 'element-plus/es/components/message/index';
import 'element-plus/es/components/message/style/css';
import { ElNotification } from 'element-plus/es/components/notification/index';
import 'element-plus/es/components/notification/style/css';
// 只需要引用带有全局方法的组件,其他组件插件会自动按需引入
export default (app) => {
app.use(ElNotification);

@ -1,8 +1,23 @@
import { getPermission, getUserInfo, login, sendSmsCode } from '@/api/auth';
import config from '@/configs';
import routerData from '@/configs/menu';
import { ElMessage } from '@/plugins/element-plus';
import router, { demoRoutes, globalRoutes, reset as resetRoutes } from '@/router';
const viewComponents = import.meta.glob('../../../views/**/*.vue');
/**
* 拿到后台返回的权限列表对比本地路由找出有权限的路由
* @param { } data
* @param {*} permissionData
*/
const _verifyPermission = (data, permissionData) => {
return data.filter((item) => {
const isPermission = permissionData.findIndex((i) => i.permission === item.permission) > -1;
if (isPermission && item.menuChild) {
item.menuChild = _verifyPermission(item.menuChild, permissionData);
}
return isPermission;
});
};
const state = () => ({
userInfo: null,
permission: [],
@ -109,9 +124,12 @@ const actions = {
location.reload();
},
getPermission: async ({ commit }) => {
let res = await getPermission();
if (res) {
commit('setPermission', res);
let res = await getPermission({ systemId: 1 });
console.log(routerData);
const permissionData = _verifyPermission(routerData, res);
console.log(res, permissionData);
if (permissionData) {
commit('setPermission', permissionData);
} else {
ElMessage.error('加载权限信息失败');
}

@ -1,4 +1,3 @@
import * as featureAPI from '@/api/permission/feature.js';
import * as api from '@/api/permission/menu.js';
import * as systemAPI from '@/api/permission/system.js';
import { ElMessage, ElMessageBox } from '@/plugins/element-plus';
@ -66,7 +65,7 @@ const actions = {
...state.opts,
init: true,
system: await systemAPI.search(),
free: await featureAPI.searchFree(),
// free: await featureAPI.searchFree(),
});
},
detail: async (context, id) => {

@ -55,60 +55,16 @@
</el-tree>
</el-scrollbar>
</el-card>
<el-card v-show="state.condition2.menuId" class="feature">
<template #header>
<div class="card-header">
<div class="title">功能</div>
<div class="action">
<el-button type="text" @click="handlePickFeature()"></el-button>
</div>
</div>
</template>
<el-scrollbar v-loading="loading2" class="card-body">
<el-tree
:data="featureList"
default-expand-all
:expand-on-click-node="false"
highlight-current
node-key="id"
:props="{
label: 'name',
value: 'id',
}"
@node-click="(data) => handleCreateFeature(data)"
>
<template #default="{ data }">
<div class="flex">
<!-- <el-tooltip :content="data.name" placement="right"> -->
<div class="name" :title="data.name">
{{ data.name }}
</div>
<!-- </el-tooltip> -->
<div class="btns">
<!-- <el-button type="text" @click.stop="handleDeleteFeature([data])">
<el-icon name="Delete" />
</el-button> -->
</div>
</div>
</template>
</el-tree>
</el-scrollbar>
</el-card>
<el-card v-show="menuState.formVisible" class="form">
<template #header>
<div class="card-header">
<div class="title">菜单表单</div>
<div class="action"></div>
</div>
</template>
<el-scrollbar v-loading="loading2" class="card-body">
<el-dialog v-model="menuState.formVisible" class="form" title="菜单表单">
<el-form
ref="refsMenuForm"
v-loading="menuState.submitting"
label-width="100px"
v-loading="menuState.submitting"
:model="menuState.form"
:rules="menuState.rules"
>
<el-row>
<el-col :span="12">
<el-form-item label="所属系统" prop="systemId">
<el-select
v-model="menuState.form.systemId"
@ -116,6 +72,8 @@
:opts="opts.system"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="上级菜单" prop="parentId">
<el-cascader
v-model="menuState.form.parentId"
@ -130,119 +88,62 @@
}"
/>
</el-form-item>
<el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="menuState.form.type" :opts="opts.type" />
</el-form-item>
<el-form-item label="菜单名称" prop="title">
<el-input v-model="menuState.form.title" maxlength="6" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="权限标识" prop="permission">
<el-input v-model="menuState.form.permission" maxlength="20" />
</el-form-item>
<el-form-item label="路由路径" prop="path">
<el-input v-model="menuState.form.path" />
</el-form-item>
<el-form-item label="前端页面" prop="page">
<el-input v-model="menuState.form.page" />
</el-form-item>
<el-form-item label="菜单图标" prop="icon">
<el-input v-model="menuState.form.icon" />
</el-form-item>
<el-form-item label="激活菜单" prop="activeMenu">
<el-input v-model="menuState.form.activeMenu" />
</el-col>
<el-col :span="10">
<el-form-item label="菜单名称" prop="title">
<el-input v-model="menuState.form.title" maxlength="6" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="菜单排序" prop="sort">
<el-input-number v-model="menuState.form.sort" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSaveMenu"></el-button>
</el-form-item>
</el-form>
</el-scrollbar>
</el-card>
<el-card v-show="featureState.formVisible" class="form">
<template #header>
<div class="card-header">
<div class="title">功能表单</div>
<div class="action"></div>
</div>
</template>
<el-scrollbar v-loading="loading2" class="card-body">
<el-form
ref="refsFeatureForm"
v-loading="featureState.submitting"
label-width="100px"
:model="featureState.form"
:rules="featureState.rules"
>
<el-form-item label="所属系统" prop="systemId">
<el-select
v-model="featureState.form.systemId"
:config="{ label: 'systemName', value: 'id' }"
:opts="opts.system"
@change="state.condition.systemId = $event"
/>
</el-form-item>
<el-form-item label="所属菜单" prop="menuId">
<el-cascader
v-model="featureState.form.menuId"
:options="list"
:props="{
label: 'title',
value: 'id',
children: 'menuChild',
checkStrictly: true,
expandTrigger: 'hover',
emitPath: false,
}"
/>
</el-form-item>
<el-form-item label="功能名称" prop="name">
<el-input v-model="featureState.form.name" maxlength="50" type="textarea" />
</el-form-item>
<el-form-item label="服务名称" prop="service">
<el-input v-model="featureState.form.service" />
</el-form-item>
<el-form-item label="请求方式" prop="method">
<el-select v-model="featureState.form.method" :opts="opts.method" />
</el-form-item>
<el-form-item label="接口路径" prop="uri">
<el-input v-model="featureState.form.uri" :rows="3" type="textarea" />
<el-scrollbar maxHeight="180px">
<el-form-item label="接口权限" v-if="!menuState.form.permissionListVO.length">
<el-button @click="handelAddPermission(0)"></el-button>
</el-form-item>
<el-form-item label="是否启用" prop="isEnable">
<el-switch v-model="featureState.form.isEnable" />
<template v-else>
<el-row v-for="(item, idx) in menuState.form.permissionListVO" :key="idx">
<el-col :span="8">
<el-form-item label="关联接口">
<el-input v-model="item.service" placeholder="请输入服务名" />
</el-form-item>
<el-form-item label="权限类型" prop="type">
<el-radio-group v-model="featureState.form.type" :opts="opts2.type" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSaveFeature"></el-button>
</el-col>
<el-col :span="13">
<el-form-item :labelWidth="5">
<el-input v-model="item.uri" placeholder="请输入请求URL">
<template #prepend>
<el-select v-model="item.method" style="width: 80px">
<el-option value="get">get</el-option>
<el-option value="post">post</el-option>
<el-option value="put">put</el-option>
<el-option value="delete">delete</el-option>
</el-select>
</template>
</el-input>
</el-form-item>
</el-form>
</el-col>
<el-col :span="2">
<div class="icon">
<el-icon name="CirclePlus" @click="handelAddPermission(idx)" />
<el-icon name="Remove" @click="handelDelPermission(idx)" />
</div>
</el-col>
</el-row>
</template>
</el-scrollbar>
</el-card>
<el-dialog v-model="featureState.pickVisible" title="选择功能权限">
<el-form
ref="refsPickForm"
v-loading="featureState.submitting"
label-width="100px"
:model="featureState.pick"
:rules="featureState.pickRules"
>
<el-form-item label="功能菜单" prop="permissionId">
<el-select
v-model="featureState.pick.permissionId"
:config="{ label: 'name', value: 'id' }"
:opts="opts.free"
/>
<el-form-item>
<el-button type="primary" @click="handleSaveMenu"></el-button>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleCancelPick"></el-button>
<el-button :loading="featureState.submitting" type="primary" @click="handleSavePick">
保存
</el-button>
</template>
</el-dialog>
</div>
</div>
@ -253,7 +154,6 @@
const store = useStore();
const { proxy } = getCurrentInstance();
const opts = computed(() => store.state.menu.opts);
const opts2 = computed(() => store.state.feature.opts);
if (!unref(opts).init) {
store.dispatch('menu/load');
}
@ -290,20 +190,6 @@
/* 查询功能 */
const loading2 = ref(false);
const featureList = computed(() => _.cloneDeep(store.state.feature.list));
const handleSearchFeature = async () => {
loading2.value = true;
await store.dispatch('feature/search');
loading2.value = false;
};
watch(
() => state.condition2,
(value) => {
store.commit('feature/setCondition', _.cloneDeep(value));
handleSearchFeature();
},
{ immediate: true, deep: true }
);
/* 菜单表单 */
const refsMenuForm = ref(null);
@ -321,15 +207,16 @@
page: '',
icon: '',
activeMenu: '',
permissionListVO: [],
sort: 0,
},
rules: {
systemId: [{ required: true, message: '所属系统不能为空' }],
type: [{ required: true, message: '菜单类型不能为空' }],
title: [{ required: true, message: '菜单名称不能为空' }],
// type: [{ required: true, message: '' }],
// title: [{ required: true, message: '' }],
permission: [{ required: true, message: '权限标识不能为空' }],
path: [{ required: true, message: '路由路径不能为空' }],
page: [{ required: true, message: '前端页面不能为空' }],
// path: [{ required: true, message: '' }],
// page: [{ required: true, message: '' }],
},
});
const handleCreateMenu = (row, parent) => {
@ -337,7 +224,6 @@
state.condition2.menuId = row.id;
}
menuState.formVisible = true;
featureState.formVisible = false;
Object.assign(
menuState.form,
row || {
@ -351,6 +237,7 @@
page: '',
icon: '',
activeMenu: '',
permissionListVO: [],
sort: 0,
}
);
@ -363,6 +250,7 @@
try {
await proxy.$validate(refsMenuForm);
let data = _.cloneDeep(menuState.form);
data.permissionList = data.permissionListVO.filter((i) => i.method && i.service && i.uri);
let res = await store.dispatch('menu/save', data);
if (res) {
menuState.formVisible = false;
@ -378,113 +266,12 @@
data.map((item) => item.id)
);
};
/* 功能表单 */
const refsFeatureForm = ref(null);
const refsPickForm = ref(null);
const featureState = reactive({
formVisible: false,
submitting: false,
form: {
id: null,
systemId: null,
menuId: null,
name: null,
service: null,
method: 'GET',
uri: null,
type: 1,
isEnable: true,
},
rules: {
systemId: [{ required: true, message: '所属系统不能为空' }],
menuId: [{ required: true, message: '所属菜单不能为空' }],
name: [{ required: true, message: '功能名称不能为空' }],
service: [{ required: true, message: '服务名称不能为空' }],
method: [{ required: true, message: '请求方式不能为空' }],
uri: [{ required: true, message: '接口路径不能为空' }],
type: [{ required: true, message: '权限类型不能为空' }],
isEnable: [{ required: true, message: '是否启用不能为空' }],
},
pickVisible: false,
pick: {
permissionId: null,
menuId: null,
},
pickRules: {
permissionId: [{ required: true, message: '功能权限不能为空' }],
},
});
const handleCancelPick = () => {
featureState.pickVisible = false;
featureState.pick = {
permissionId: null,
menuId: null,
};
};
const handleSavePick = async () => {
featureState.submitting = true;
try {
await proxy.$validate(refsPickForm);
let res = await store.dispatch('feature/assign', featureState.pick);
if (res) {
handleSearchFeature();
handleCancelPick();
store.dispatch('menu/load');
}
} catch (e) {
console.info('取消保存', e);
}
featureState.submitting = false;
const handelAddPermission = (idx) => {
menuState.form.permissionListVO.splice(idx, 0, { method: 'get' });
};
const handlePickFeature = async () => {
try {
await proxy.$confirm('是否选择尚未分配菜单的功能权限?');
featureState.formVisible = false;
featureState.pickVisible = true;
featureState.pick.menuId = state.condition2.menuId;
} catch (e) {
handleCreateFeature();
}
const handelDelPermission = (idx) => {
menuState.form.permissionListVO.splice(idx, 1);
};
const handleCreateFeature = async (row) => {
featureState.formVisible = true;
menuState.formVisible = false;
Object.assign(
featureState.form,
row || {
id: null,
systemId: state.condition.systemId,
menuId: state.condition2.menuId,
name: null,
service: null,
method: 'GET',
uri: null,
type: 1,
isEnable: true,
}
);
};
const handleSaveFeature = async () => {
featureState.submitting = true;
try {
await proxy.$validate(refsFeatureForm);
let data = _.cloneDeep(featureState.form);
let res = await store.dispatch('feature/save', data);
if (res) {
featureState.formVisible = false;
}
} catch (e) {
console.info('取消保存', e);
}
featureState.submitting = false;
};
// const handleDeleteFeature = (data) => {
// store.dispatch(
// 'feature/remove',
// data.map((item) => item.id)
// );
// };
</script>
<style lang="less" scoped>
@ -557,4 +344,15 @@
}
}
}
.icon {
margin: 10px 0 10px;
display: flex;
justify-content: space-evenly;
:deep .el-icon {
cursor: pointer;
&:hover {
color: var(--el-color-primary);
}
}
}
</style>

@ -90,11 +90,10 @@
}"
show-checkbox
@check-change="handleCheckMenu"
@node-click="handleLoadPermission"
/>
</el-scrollbar>
</el-form-item>
<el-form-item label="功能权限" prop="permissionIds">
<!-- <el-form-item label="功能权限" prop="permissionIds">
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAll">
全选
</el-checkbox>
@ -115,7 +114,7 @@
@check-change="handleCheckPermission"
/>
</el-scrollbar>
</el-form-item>
</el-form-item> -->
</el-form>
</el-tab-pane>
<el-tab-pane :disabled="!formState.form.id" label="绑定组织" name="3">
@ -255,9 +254,6 @@
},
{ immediate: true, deep: true }
);
const handleCheckAll = () => {
unref(refsTree2).setCheckedKeys(unref(checkAll) ? unref(permissionList).map((item) => item.id) : []);
};
const handleLoadPermission = async (data) => {
permissionList.value = await store.dispatch('role/loadPermission', data.id);
};
@ -268,13 +264,6 @@
formState.form.menuIds.splice(formState.form.menuIds.indexOf(data.id), 1);
}
};
const handleCheckPermission = (data, checked, childChecked) => {
if (checked || childChecked) {
formState.form.permissionIds.push(data.id);
} else {
formState.form.permissionIds.splice(formState.form.permissionIds.indexOf(data.id), 1);
}
};
const refsTree3 = ref(null);
const handleCheckDept = async (data, checked, childChecked) => {
formState.submitting = true;

Loading…
Cancel
Save