😎优化授权角色接口资源
This commit is contained in:
parent
95d156fe71
commit
3001840e6e
@ -36,8 +36,8 @@
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.5.0" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.159" />
|
||||
<PackageReference Include="SSH.NET" Version="2024.0.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.1" />
|
||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1033" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.2" />
|
||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1034" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -35,14 +35,17 @@ public class RoleApiJob : IJob
|
||||
var sysRoleApis = new List<SysRoleApi>();
|
||||
foreach (var baseApi in apiList)
|
||||
{
|
||||
foreach (var api in baseApi.Apis)
|
||||
foreach (var controller in baseApi.Children)
|
||||
{
|
||||
// 排除租户管理接口
|
||||
if (api.ControllerName == "sysTenant") continue;
|
||||
if (controller.Name == "sysTenant") continue;
|
||||
|
||||
// 为系统管理员分配接口
|
||||
sysRoleApis.Add(new SysRoleApi { Id = 1400000000101 + index, RoleId = 1300000000101, Route = api.Route });
|
||||
index++;
|
||||
foreach (var api in controller.Children)
|
||||
{
|
||||
// 为系统管理员分配接口
|
||||
sysRoleApis.Add(new SysRoleApi { Id = 1400000000101 + index, RoleId = 1300000000101, Route = api.Route });
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
var db = serviceScope.ServiceProvider.GetRequiredService<ISqlSugarClient>();
|
||||
|
||||
@ -31,10 +31,10 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
new SysConfig{ Id=1300000000191, Name="发送异常日志邮件", Code="sys_error_mail", Value="True", SysFlag=YesNoEnum.Y, Remark="是否发送异常日志邮件", OrderNo=100, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000201, Name="开启域登录验证", Code="sys_domain_login", Value="False", SysFlag=YesNoEnum.Y, Remark="是否开启域登录验证", OrderNo=110, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000211, Name="开启数据校验日志", Code="sys_validation_log", Value="True", SysFlag=YesNoEnum.Y, Remark="是否数据校验日志", OrderNo=120, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000221, Name="系统主标题", Code="sys_web_title", Value="Admin.NET", SysFlag=YesNoEnum.Y, Remark="系统主标题", OrderNo=130, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000231, Name="系统副标题", Code="sys_web_viceTitle", Value="Admin.NET", SysFlag=YesNoEnum.Y, Remark="系统副标题", OrderNo=140, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000221, Name="系统主标题", Code="sys_web_title", Value="Admin.NET.Pro", SysFlag=YesNoEnum.Y, Remark="系统主标题", OrderNo=130, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000231, Name="系统副标题", Code="sys_web_viceTitle", Value="Admin.NET.Pro", SysFlag=YesNoEnum.Y, Remark="系统副标题", OrderNo=140, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000241, Name="系统描述", Code="sys_web_viceDesc", Value="站在巨人肩膀上的 .NET 通用权限开发框架", SysFlag=YesNoEnum.Y, Remark="系统描述", OrderNo=150, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000251, Name="水印内容", Code="sys_web_watermark", Value="Admin.NET", SysFlag=YesNoEnum.Y, Remark="水印内容", OrderNo=160, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000251, Name="水印内容", Code="sys_web_watermark", Value="Admin.NET.Pro", SysFlag=YesNoEnum.Y, Remark="水印内容", OrderNo=160, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000261, Name="版权说明", Code="sys_web_copyright", Value="Copyright © 2021-present Admin.NET All rights reserved.", SysFlag=YesNoEnum.Y, Remark="版权说明", OrderNo=170, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000271, Name="系统图标", Code="sys_web_logo", Value="/Upload/logo.png", SysFlag=YesNoEnum.Y, Remark="系统图标", OrderNo=180, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000281, Name="ICP备案号", Code="sys_web_icp", Value="省ICP备12345678号", SysFlag=YesNoEnum.Y, Remark="ICP备案号", OrderNo=190, GroupCode="WebConfig", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
|
||||
@ -343,7 +343,7 @@ public class SysCodeGenService : IDynamicApiController, ITransient
|
||||
PrintType = input.PrintType,
|
||||
PrintName = input.PrintName,
|
||||
};
|
||||
//模板目录
|
||||
// 模板目录
|
||||
var templatePathList = GetTemplatePathList(input);
|
||||
var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template");
|
||||
|
||||
|
||||
@ -7,30 +7,14 @@
|
||||
namespace Admin.NET.Core.Service;
|
||||
|
||||
/// <summary>
|
||||
/// 接口/动态API输出
|
||||
/// 接口/动态API 树形列表
|
||||
/// </summary>
|
||||
public class ApiOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 组名称
|
||||
/// 名称(组名、路由名)
|
||||
/// </summary>
|
||||
public string GroupName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 接口列表
|
||||
/// </summary>
|
||||
public List<ApiInfo> Apis { get; set; } = new List<ApiInfo>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接口/动态API信息
|
||||
/// </summary>
|
||||
public class ApiInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 接口名称
|
||||
/// </summary>
|
||||
public string DisplayName { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路由
|
||||
@ -43,17 +27,12 @@ public class ApiInfo
|
||||
public string HttpMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 控制器名称
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public string ControllerName { get; set; }
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法名称
|
||||
/// 接口列表
|
||||
/// </summary>
|
||||
public string ActionName { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 组名称
|
||||
///// </summary>
|
||||
//public string GroupName { get; set; }
|
||||
public List<ApiOutput> Children { get; set; } = new List<ApiOutput>();
|
||||
}
|
||||
@ -77,32 +77,44 @@ public class SysCommonService : IDynamicApiController, ITransient
|
||||
|
||||
var apiOuput = new ApiOutput
|
||||
{
|
||||
GroupName = string.IsNullOrWhiteSpace(group.GroupName) ? "系统接口" : group.GroupName
|
||||
Name = string.IsNullOrWhiteSpace(group.GroupName) ? "系统接口" : group.GroupName,
|
||||
Route = "",
|
||||
};
|
||||
// 获取接口分组的所有方法/接口
|
||||
// 获取分组的所有接口
|
||||
var actions = group.Items;
|
||||
foreach (ApiDescription action in actions)
|
||||
{
|
||||
// 路由名称(去掉参数)
|
||||
var routeName = action.RelativePath.Contains('{') ? action.RelativePath[..action.RelativePath.IndexOf('{')] : action.RelativePath;
|
||||
// 去掉路由前缀
|
||||
routeName = routeName[(routeName.IndexOf('/') + 1)..];
|
||||
// 路由
|
||||
var route = action.RelativePath.Contains('{') ? action.RelativePath[..action.RelativePath.IndexOf('{')] : action.RelativePath; // 去掉路由参数
|
||||
route = route[(route.IndexOf('/') + 1)..]; // 去掉路由前缀
|
||||
|
||||
// 接口分组/控制器信息
|
||||
var controllerActionDescriptor = action.ActionDescriptor as ControllerActionDescriptor;
|
||||
var displayName = controllerActionDescriptor.MethodInfo.GetCustomAttribute<DisplayNameAttribute>(true)?.DisplayName;
|
||||
|
||||
apiOuput.Apis.Add(new ApiInfo
|
||||
var apiDescription = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute<ApiDescriptionSettingsAttribute>(true);
|
||||
var controllerName = controllerActionDescriptor.ControllerName;
|
||||
if (!apiOuput.Children.Exists(u => u.Name == controllerName))
|
||||
{
|
||||
DisplayName = displayName,
|
||||
Route = routeName,
|
||||
apiOuput.Children.Add(new ApiOutput
|
||||
{
|
||||
Name = controllerName,
|
||||
Route = "",
|
||||
Order = apiDescription?.Order ?? 0,
|
||||
});
|
||||
}
|
||||
|
||||
// 接口信息
|
||||
var apiController = apiOuput.Children.FirstOrDefault(u => u.Name.Equals(controllerName));
|
||||
var displayName = controllerActionDescriptor.MethodInfo.GetCustomAttribute<DisplayNameAttribute>(true)?.DisplayName;
|
||||
apiController.Children.Add(new ApiOutput
|
||||
{
|
||||
Name = displayName,
|
||||
Route = route,
|
||||
HttpMethod = action.HttpMethod,
|
||||
ControllerName = controllerActionDescriptor.ControllerName,
|
||||
ActionName = controllerActionDescriptor.ActionName,
|
||||
//GroupName = string.IsNullOrWhiteSpace(action.GroupName) ? "Default" : action.GroupName,
|
||||
Order = apiDescription?.Order ?? 0,
|
||||
});
|
||||
|
||||
// 按照控制器名称进行排序
|
||||
apiOuput.Apis = apiOuput.Apis.OrderBy(u => u.ControllerName).ToList();
|
||||
// 接口分组/控制器排序
|
||||
apiOuput.Children = apiOuput.Children.OrderByDescending(u => u.Order).ToList();
|
||||
}
|
||||
|
||||
apiList.Add(apiOuput);
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
"devDependencies": {
|
||||
"@plugin-web-update-notification/vite": "^1.7.1",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.14.8",
|
||||
"@types/node": "^20.14.9",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/sortablejs": "^1.15.8",
|
||||
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 接口/动态API信息
|
||||
*
|
||||
* @export
|
||||
* @interface ApiInfo
|
||||
*/
|
||||
export interface ApiInfo {
|
||||
|
||||
/**
|
||||
* 接口名称
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiInfo
|
||||
*/
|
||||
displayName?: string | null;
|
||||
|
||||
/**
|
||||
* 路由
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiInfo
|
||||
*/
|
||||
route?: string | null;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiInfo
|
||||
*/
|
||||
httpMethod?: string | null;
|
||||
|
||||
/**
|
||||
* 控制器名称
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiInfo
|
||||
*/
|
||||
controllerName?: string | null;
|
||||
|
||||
/**
|
||||
* 方法名称
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiInfo
|
||||
*/
|
||||
actionName?: string | null;
|
||||
}
|
||||
@ -12,9 +12,9 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { ApiInfo } from './api-info';
|
||||
import { ApiOutput } from './api-output';
|
||||
/**
|
||||
* 接口/动态API输出
|
||||
* 接口/动态API 树形列表
|
||||
*
|
||||
* @export
|
||||
* @interface ApiOutput
|
||||
@ -22,18 +22,42 @@ import { ApiInfo } from './api-info';
|
||||
export interface ApiOutput {
|
||||
|
||||
/**
|
||||
* 组名称
|
||||
* 名称(组名、路由名)
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiOutput
|
||||
*/
|
||||
groupName?: string | null;
|
||||
name?: string | null;
|
||||
|
||||
/**
|
||||
* 路由
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiOutput
|
||||
*/
|
||||
route?: string | null;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof ApiOutput
|
||||
*/
|
||||
httpMethod?: string | null;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof ApiOutput
|
||||
*/
|
||||
order?: number;
|
||||
|
||||
/**
|
||||
* 接口列表
|
||||
*
|
||||
* @type {Array<ApiInfo>}
|
||||
* @type {Array<ApiOutput>}
|
||||
* @memberof ApiOutput
|
||||
*/
|
||||
apis?: Array<ApiInfo> | null;
|
||||
children?: Array<ApiOutput> | null;
|
||||
}
|
||||
|
||||
@ -98,7 +98,6 @@ export * from './admin-result-visual-db-table';
|
||||
export * from './admin-result-wechat-pay-output';
|
||||
export * from './admin-result-wx-open-id-output';
|
||||
export * from './admin-result-wx-phone-output';
|
||||
export * from './api-info';
|
||||
export * from './api-output';
|
||||
export * from './assembly';
|
||||
export * from './base-api-input';
|
||||
|
||||
@ -1,32 +1,47 @@
|
||||
<template>
|
||||
<div class="sys-baseApi-container">
|
||||
<el-drawer v-model="state.isVisible" :title="state.drawerTitle" size="50%">
|
||||
<el-tabs v-loading="state.loading" v-model="state.selectedTabName" style="margin: 10px">
|
||||
<el-tab-pane v-for="(item, i) in state.allApiData" :label="item.groupName" :name="i">
|
||||
<template #label>
|
||||
<el-icon style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Promotion /></el-icon>
|
||||
<span>{{ item.groupName }}</span>
|
||||
</template>
|
||||
<el-table ref="tableRef" :data="item.apis" style="width: 100%" v-loading="state.loading" border @selection-change="handleSelectionChange" height="calc(100vh - 180px)">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column prop="displayName" label="接口名称" min-width="170" header-align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="route" label="路由" min-width="300" header-align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="httpMethod" label="请求方式" min-width="80" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="primary" v-if="scope.row.httpMethod === 'GET'">GET</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.httpMethod === 'POST'">POST</el-tag>
|
||||
<el-tag type="warning" v-else-if="scope.row.httpMethod === 'PUT'">PUT</el-tag>
|
||||
<el-tag type="danger" v-else-if="scope.row.httpMethod === 'DELETE'">DELETE</el-tag>
|
||||
<el-tag type="info" v-else>{{ scope.row.httpMethod }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="controllerName" label="控制器" min-width="150" header-align="center" show-overflow-tooltip />
|
||||
<!-- <el-table-column prop="actionName" label="方法名" header-align="center" show-overflow-tooltip /> -->
|
||||
<!-- <el-table-column prop="groupName" label="分组" min-width="150" header-align="center" show-overflow-tooltip /> -->
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-drawer v-model="state.isVisible" :title="state.drawerTitle" size="35%">
|
||||
<el-card class="tree-card" shadow="hover" style="height: calc(100vh - 110px)" body-style="height:100%; overflow:auto">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<div class="tree-h-flex">
|
||||
<div class="tree-h-left">
|
||||
<el-input :prefix-icon="Search" v-model="filterText" placeholder="API路由" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-form-item v-loading="state.loading" style="margin-bottom: 45px">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb8">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
class="filter-tree"
|
||||
:data="state.allApiData"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="route"
|
||||
:props="{ children: 'children', label: 'name' }"
|
||||
show-checkbox
|
||||
icon="ele-Menu"
|
||||
highlight-current
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span v-if="node.level == 1 || node.level == 2">{{ node.label }}</span>
|
||||
<span v-if="node.level == 3">
|
||||
<el-icon style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Link /></el-icon>
|
||||
{{ node.label }} 【{{ node.key }}】
|
||||
<el-tag type="primary" v-if="data.httpMethod === 'GET'">GET</el-tag>
|
||||
<el-tag type="success" v-else-if="data.httpMethod === 'POST'">POST</el-tag>
|
||||
<el-tag type="warning" v-else-if="data.httpMethod === 'PUT'">PUT</el-tag>
|
||||
<el-tag type="danger" v-else-if="data.httpMethod === 'DELETE'">DELETE</el-tag>
|
||||
<el-tag type="info" v-else>{{ data.httpMethod }}</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
<template #footer>
|
||||
<div style="margin-bottom: 20px; margin-right: 20px">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
@ -38,13 +53,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { ElTable } from 'element-plus';
|
||||
|
||||
import { reactive, onMounted, ref, watch } from 'vue';
|
||||
import type { ElTree } from 'element-plus';
|
||||
import { Search, MoreFilled } from '@element-plus/icons-vue';
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCommonApi, SysRoleApi } from '/@/api-services/api';
|
||||
|
||||
const tableRef = ref<InstanceType<typeof ElTable>>() as any;
|
||||
const filterText = ref('');
|
||||
const treeRef = ref<InstanceType<typeof ElTree>>();
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
@ -56,47 +72,46 @@ const state = reactive({
|
||||
selectedTabName: 0,
|
||||
});
|
||||
|
||||
// 打开页面
|
||||
const openDrawer = () => {
|
||||
state.selectedTabName = 0;
|
||||
state.drawerTitle = '基础接口资源';
|
||||
state.isVisible = true;
|
||||
handleQuery();
|
||||
};
|
||||
onMounted(() => {
|
||||
initTreeData();
|
||||
});
|
||||
|
||||
// 查询操作
|
||||
const handleQuery = async () => {
|
||||
// 获取所有接口资源
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value!.filter(val);
|
||||
});
|
||||
|
||||
const initTreeData = async () => {
|
||||
state.loading = true;
|
||||
var res = await getAPI(SysCommonApi).apiSysCommonApiListGet();
|
||||
state.allApiData = res.data.result ?? [];
|
||||
var tData = res.data.result ?? [];
|
||||
|
||||
treeRef.value?.setCheckedKeys([]); // 清空选中值
|
||||
|
||||
state.allApiData = tData;
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
// 打开页面
|
||||
const openDrawer = async () => {
|
||||
state.selectedTabName = 0;
|
||||
state.drawerTitle = '设置基础接口资源【免鉴权授权】';
|
||||
state.isVisible = true;
|
||||
state.loading = false;
|
||||
|
||||
// 获取已有基础接口资源
|
||||
state.loading = true;
|
||||
var res1 = await getAPI(SysRoleApi).apiSysRoleBaseApiListGet();
|
||||
state.ownApiList = res1.data.result ?? [];
|
||||
state.loading = false;
|
||||
|
||||
// 初始化多选回显
|
||||
if (state.ownApiList.length > 0) {
|
||||
for (let index = 0; index < state.ownApiList.length; index++) {
|
||||
for (let i = 0; i < state.allApiData.length; i++) {
|
||||
var row = state.allApiData[i].apis.find((api: any) => api.route === state.ownApiList[index]);
|
||||
if (row != null) {
|
||||
if (tableRef && tableRef.value != undefined && tableRef.value[i]) {
|
||||
tableRef.value[i]!.toggleRowSelection(row, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
treeRef.value?.setCheckedKeys(state.ownApiList ?? []);
|
||||
}, 200);
|
||||
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
// 选择变化
|
||||
const handleSelectionChange = (val: any) => {
|
||||
state.selectRow = val;
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) return true;
|
||||
return data.route.includes(value);
|
||||
};
|
||||
|
||||
// 取消
|
||||
@ -106,15 +121,7 @@ const cancel = () => {
|
||||
|
||||
// 设置基础接口资源
|
||||
const submit = async () => {
|
||||
state.ownApiList = [];
|
||||
for (let i = 0; i < state.allApiData.length; i++) {
|
||||
if (tableRef.value != undefined && tableRef.value[i] && tableRef.value[i]!.getSelectionRows().length > 0) {
|
||||
tableRef.value[i]!.getSelectionRows().forEach(function (item: any) {
|
||||
state.ownApiList.push(item.route);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
state.ownApiList = treeRef.value?.getCheckedKeys() as Array<string>;
|
||||
await getAPI(SysRoleApi).apiSysRoleSetBaseApiPost({ id: 0, apiList: state.ownApiList });
|
||||
cancel();
|
||||
};
|
||||
|
||||
@ -1,32 +1,47 @@
|
||||
<template>
|
||||
<div class="sys-grantApi-container">
|
||||
<el-drawer v-model="state.isVisible" :title="state.drawerTitle" size="50%">
|
||||
<el-tabs v-loading="state.loading" v-model="state.selectedTabName" style="margin: 10px">
|
||||
<el-tab-pane v-for="(item, i) in state.allApiData" :label="item.groupName" :name="i">
|
||||
<template #label>
|
||||
<el-icon style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Promotion /></el-icon>
|
||||
<span>{{ item.groupName }}</span>
|
||||
</template>
|
||||
<el-table ref="tableRef" :data="item.apis" style="width: 100%" v-loading="state.loading" border @selection-change="handleSelectionChange" height="calc(100vh - 180px)">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column prop="displayName" label="接口名称" min-width="170" header-align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="route" label="路由" min-width="300" header-align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="httpMethod" label="请求方式" min-width="80" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag type="primary" v-if="scope.row.httpMethod === 'GET'">GET</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.httpMethod === 'POST'">POST</el-tag>
|
||||
<el-tag type="warning" v-else-if="scope.row.httpMethod === 'PUT'">PUT</el-tag>
|
||||
<el-tag type="danger" v-else-if="scope.row.httpMethod === 'DELETE'">DELETE</el-tag>
|
||||
<el-tag type="info" v-else>{{ scope.row.httpMethod }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="controllerName" label="控制器" min-width="150" header-align="center" show-overflow-tooltip />
|
||||
<!-- <el-table-column prop="actionName" label="方法名" header-align="center" show-overflow-tooltip /> -->
|
||||
<!-- <el-table-column prop="groupName" label="分组" min-width="150" header-align="center" show-overflow-tooltip /> -->
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-drawer v-model="state.isVisible" :title="state.drawerTitle" size="35%">
|
||||
<el-card class="tree-card" shadow="hover" style="height: calc(100vh - 110px)" body-style="height:100%; overflow:auto">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<div class="tree-h-flex">
|
||||
<div class="tree-h-left">
|
||||
<el-input :prefix-icon="Search" v-model="filterText" placeholder="API路由" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-form-item v-loading="state.loading" style="margin-bottom: 45px">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb8">
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
class="filter-tree"
|
||||
:data="state.allApiData"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="route"
|
||||
:props="{ children: 'children', label: 'name' }"
|
||||
show-checkbox
|
||||
icon="ele-Menu"
|
||||
highlight-current
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span v-if="node.level == 1 || node.level == 2">{{ node.label }}</span>
|
||||
<span v-if="node.level == 3">
|
||||
<el-icon style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Link /></el-icon>
|
||||
{{ node.label }} 【{{ node.key }}】
|
||||
<el-tag type="primary" v-if="data.httpMethod === 'GET'">GET</el-tag>
|
||||
<el-tag type="success" v-else-if="data.httpMethod === 'POST'">POST</el-tag>
|
||||
<el-tag type="warning" v-else-if="data.httpMethod === 'PUT'">PUT</el-tag>
|
||||
<el-tag type="danger" v-else-if="data.httpMethod === 'DELETE'">DELETE</el-tag>
|
||||
<el-tag type="info" v-else>{{ data.httpMethod }}</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-card>
|
||||
<template #footer>
|
||||
<div style="margin-bottom: 20px; margin-right: 20px">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
@ -38,13 +53,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { ElTable } from 'element-plus';
|
||||
|
||||
import { reactive, onMounted, ref, watch } from 'vue';
|
||||
import type { ElTree } from 'element-plus';
|
||||
import { Search, MoreFilled } from '@element-plus/icons-vue';
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCommonApi, SysRoleApi } from '/@/api-services/api';
|
||||
|
||||
const tableRef = ref<InstanceType<typeof ElTable>>() as any;
|
||||
const filterText = ref('');
|
||||
const treeRef = ref<InstanceType<typeof ElTree>>();
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
@ -57,48 +73,47 @@ const state = reactive({
|
||||
selectedTabName: 0,
|
||||
});
|
||||
|
||||
// 打开页面
|
||||
const openDrawer = (row: any) => {
|
||||
state.selectedTabName = 0;
|
||||
state.roleId = row.id;
|
||||
state.drawerTitle = '授权接口资源【' + row.name + '】';
|
||||
state.isVisible = true;
|
||||
handleQuery();
|
||||
};
|
||||
onMounted(() => {
|
||||
initTreeData();
|
||||
});
|
||||
|
||||
// 查询操作
|
||||
const handleQuery = async () => {
|
||||
// 获取所有接口资源
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value!.filter(val);
|
||||
});
|
||||
|
||||
const initTreeData = async () => {
|
||||
state.loading = true;
|
||||
var res = await getAPI(SysCommonApi).apiSysCommonApiListGet();
|
||||
state.allApiData = res.data.result ?? [];
|
||||
var tData = res.data.result ?? [];
|
||||
|
||||
treeRef.value?.setCheckedKeys([]); // 清空选中值
|
||||
|
||||
state.allApiData = tData;
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
// 打开页面
|
||||
const openDrawer = async (row: any) => {
|
||||
state.selectedTabName = 0;
|
||||
state.roleId = row.id;
|
||||
state.drawerTitle = '授权角色接口资源【' + row.name + '】';
|
||||
state.isVisible = true;
|
||||
state.loading = false;
|
||||
|
||||
// 获取已有接口资源
|
||||
state.loading = true;
|
||||
var res1 = await getAPI(SysRoleApi).apiSysRoleOwnApiListGet(state.roleId);
|
||||
state.ownApiList = res1.data.result ?? [];
|
||||
state.loading = false;
|
||||
|
||||
// 初始化多选回显
|
||||
if (state.ownApiList.length > 0) {
|
||||
for (let index = 0; index < state.ownApiList.length; index++) {
|
||||
for (let i = 0; i < state.allApiData.length; i++) {
|
||||
var row = state.allApiData[i].apis.find((api: any) => api.route === state.ownApiList[index]);
|
||||
if (row != null) {
|
||||
if (tableRef && tableRef.value != undefined && tableRef.value[i]) {
|
||||
tableRef.value[i]!.toggleRowSelection(row, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
treeRef.value?.setCheckedKeys(state.ownApiList ?? []);
|
||||
}, 200);
|
||||
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
// 选择变化
|
||||
const handleSelectionChange = (val: any) => {
|
||||
state.selectRow = val;
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) return true;
|
||||
return data.route.includes(value);
|
||||
};
|
||||
|
||||
// 取消
|
||||
@ -108,15 +123,7 @@ const cancel = () => {
|
||||
|
||||
// 授权角色接口资源
|
||||
const submit = async () => {
|
||||
state.ownApiList = [];
|
||||
for (let i = 0; i < state.allApiData.length; i++) {
|
||||
if (tableRef.value != undefined && tableRef.value[i] && tableRef.value[i]!.getSelectionRows().length > 0) {
|
||||
tableRef.value[i]!.getSelectionRows().forEach(function (item: any) {
|
||||
state.ownApiList.push(item.route);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
state.ownApiList = treeRef.value?.getCheckedKeys() as Array<string>;
|
||||
await getAPI(SysRoleApi).apiSysRoleGrantApiPost({ id: state.roleId, apiList: state.ownApiList });
|
||||
cancel();
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user