😎增加基础接口资源管理(无需权限验证的接口)

This commit is contained in:
zuohuaijun 2024-06-20 03:04:31 +08:00
parent 6744c5471a
commit 613e50bd4c
20 changed files with 536 additions and 64 deletions

View File

@ -37,7 +37,7 @@
<PackageReference Include="SqlSugarCore" Version="5.1.4.158" />
<PackageReference Include="SSH.NET" Version="2024.0.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.0" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1028" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1029" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>

View File

@ -21,6 +21,11 @@ public class CacheConst
/// </summary>
public const string KeyUserApi = "sys_user_api:";
/// <summary>
/// 基础接口缓存(接口集合)
/// </summary>
public const string KeyBaseApi = "sys_base_api:";
/// <summary>
/// 用户机构缓存
/// </summary>

View File

@ -91,11 +91,4 @@ public class CommonConst
/// 事件-发送异常邮件
/// </summary>
public const string SendErrorMail = "Send:ErrorMail";
/// <summary>
/// 基础接口资源列表
/// </summary>
public static readonly List<string> SysBaseRoutes = new() { "sysAuth/login", "sysAuth/unLockScreen", "sysAuth/loginPhone", "sysAuth/userInfo", "sysAuth/refreshToken", "sysAuth/logout", "sysAuth/loginConfig", "sysAuth/watermarkConfig", "sysAuth/captcha", "sysMenu/loginMenuTree", "sysOAuth/signIn", "sysOAuth/signInCallback", "sysOnlineUser/page", "sysOrg/list", "sysPos/list", "sysRole/page", "sysRole/list",
"sysFile/uploadAvatar", "sysFile/uploadSignature", "sysUser/baseInfo", "sysUser/baseInfo", "sysUser/changePwd", "sysNotice/page", "sysNotice/add", "sysNotice/update", "sysNotice/delete", "sysNotice/public", "sysNotice/setRead", "sysNotice/pageReceived", "sysNotice/unReadList" };
}

View File

@ -0,0 +1,22 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统基础接口表
/// </summary>
[SugarTable(null, "系统基础接口表")]
[SysTable]
public class SysBaseApi : EntityBaseId
{
/// <summary>
/// 接口路由
/// </summary>
[SugarColumn(ColumnDescription = "接口路由", ColumnDataType = StaticConfig.CodeFirst_BigString)]
[Required]
public string Route { get; set; }
}

View File

@ -0,0 +1,51 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统基础接口资源表种子数据
/// </summary>
public class SysBaseApiSeedData : ISqlSugarEntitySeedData<SysBaseApi>
{
/// <summary>
/// 种子数据
/// </summary>
/// <returns></returns>
public IEnumerable<SysBaseApi> HasData()
{
return new[]
{
new SysBaseApi { Id = 1300000000001, Route = "sysAuth/login" },
new SysBaseApi { Id = 1300000000002, Route = "sysAuth/unLockScreen" },
new SysBaseApi { Id = 1300000000003, Route = "sysAuth/userInfo" },
new SysBaseApi { Id = 1300000000004, Route = "sysAuth/refreshToken" },
new SysBaseApi { Id = 1300000000005, Route = "sysAuth/loginConfig" },
new SysBaseApi { Id = 1300000000006, Route = "sysAuth/watermarkConfig" },
new SysBaseApi { Id = 1300000000007, Route = "sysAuth/captcha" },
new SysBaseApi { Id = 1300000000008, Route = "sysMenu/loginMenuTree" },
new SysBaseApi { Id = 1300000000009, Route = "sysOAuth/signIn" },
new SysBaseApi { Id = 1300000000010, Route = "sysOAuth/signInCallback" },
new SysBaseApi { Id = 1300000000011, Route = "sysOnlineUser/page" },
new SysBaseApi { Id = 1300000000012, Route = "sysOrg/list" },
new SysBaseApi { Id = 1300000000013, Route = "sysPos/list" },
new SysBaseApi { Id = 1300000000014, Route = "sysRole/page" },
new SysBaseApi { Id = 1300000000015, Route = "sysRole/list" },
new SysBaseApi { Id = 1300000000016, Route = "sysFile/uploadAvatar" },
new SysBaseApi { Id = 1300000000017, Route = "sysFile/uploadSignature" },
new SysBaseApi { Id = 1300000000018, Route = "sysUser/baseInfo" },
new SysBaseApi { Id = 1300000000019, Route = "sysUser/changePwd" },
new SysBaseApi { Id = 1300000000020, Route = "sysNotice/page" },
new SysBaseApi { Id = 1300000000021, Route = "sysNotice/add" },
new SysBaseApi { Id = 1300000000022, Route = "sysNotice/update" },
new SysBaseApi { Id = 1300000000023, Route = "sysNotice/delete" },
new SysBaseApi { Id = 1300000000024, Route = "sysNotice/public" },
new SysBaseApi { Id = 1300000000025, Route = "sysNotice/setRead" },
new SysBaseApi { Id = 1300000000026, Route = "sysNotice/pageReceived" },
new SysBaseApi { Id = 1300000000027, Route = "sysNotice/unReadList" },
};
}
}

View File

@ -1,41 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统角色接口资源表种子数据
/// </summary>
public class SysRoleApiSeedData : ISqlSugarEntitySeedData<SysRoleApi>
{
/// <summary>
/// 种子数据
/// </summary>
/// <returns></returns>
public IEnumerable<SysRoleApi> HasData()
{
var index = 0;
var sysRoleApis = new List<SysRoleApi>();
foreach (var route in CommonConst.SysBaseRoutes)
{
var id = 1300000000101 + index * 4;
// 本部门及以下数据
sysRoleApis.Add(new SysRoleApi { Id = id + 1, RoleId = 1300000000102, Route = route });
// 本部门数据
sysRoleApis.Add(new SysRoleApi { Id = id + 2, RoleId = 1300000000103, Route = route });
// 仅本人数据
sysRoleApis.Add(new SysRoleApi { Id = id + 3, RoleId = 1300000000104, Route = route });
// 自定义数据
sysRoleApis.Add(new SysRoleApi { Id = id + 4, RoleId = 1300000000105, Route = route });
index++;
}
return sysRoleApis;
}
}

View File

@ -0,0 +1,18 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
/// <summary>
/// 设置基础接口资源
/// </summary>
public class BaseApiInput : BaseIdInput
{
/// <summary>
/// 接口路由集合
/// </summary>
public List<string> ApiList { get; set; }
}

View File

@ -0,0 +1,45 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
/// <summary>
/// 系统基础接口资源服务
/// </summary>
public class SysBaseApiService : ITransient
{
private readonly SqlSugarRepository<SysBaseApi> _sysBaseApiRep;
public SysBaseApiService(SqlSugarRepository<SysBaseApi> sysBaseApiRep)
{
_sysBaseApiRep = sysBaseApiRep;
}
/// <summary>
/// 设置基础接口资源
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task SetBaseApi(BaseApiInput input)
{
await _sysBaseApiRep.DeleteAsync(u => u.Id > 0);
var baseApis = input.ApiList.Select(u => new SysBaseApi
{
Route = u
}).ToList();
await _sysBaseApiRep.InsertRangeAsync(baseApis);
}
/// <summary>
/// 获取基础接口资源集合
/// </summary>
/// <returns></returns>
public async Task<List<string>> GetBaseApiList()
{
return await _sysBaseApiRep.AsQueryable().Select(u => u.Route).ToListAsync();
}
}

View File

@ -13,9 +13,9 @@ public class SysRoleApiService : ITransient
{
private readonly SqlSugarRepository<SysRoleApi> _sysRoleApiRep;
public SysRoleApiService(SqlSugarRepository<SysRoleApi> sysRoleApi)
public SysRoleApiService(SqlSugarRepository<SysRoleApi> sysRoleApiRep)
{
_sysRoleApiRep = sysRoleApi;
_sysRoleApiRep = sysRoleApiRep;
}
/// <summary>

View File

@ -17,6 +17,7 @@ public class SysRoleService : IDynamicApiController, ITransient
private readonly SysRoleOrgService _sysRoleOrgService;
private readonly SysRoleMenuService _sysRoleMenuService;
private readonly SysRoleApiService _sysRoleApiService;
private readonly SysBaseApiService _sysBaseApiService;
private readonly SysOrgService _sysOrgService;
private readonly SysUserRoleService _sysUserRoleService;
private readonly SysCacheService _sysCacheService;
@ -26,6 +27,7 @@ public class SysRoleService : IDynamicApiController, ITransient
SysRoleOrgService sysRoleOrgService,
SysRoleMenuService sysRoleMenuService,
SysRoleApiService sysRoleApiService,
SysBaseApiService sysBaseApiService,
SysOrgService sysOrgService,
SysUserRoleService sysUserRoleService,
SysCacheService sysCacheService)
@ -35,6 +37,7 @@ public class SysRoleService : IDynamicApiController, ITransient
_sysRoleOrgService = sysRoleOrgService;
_sysRoleMenuService = sysRoleMenuService;
_sysRoleApiService = sysRoleApiService;
_sysBaseApiService = sysBaseApiService;
_sysOrgService = sysOrgService;
_sysUserRoleService = sysUserRoleService;
_sysCacheService = sysCacheService;
@ -94,9 +97,6 @@ public class SysRoleService : IDynamicApiController, ITransient
var newRole = await _sysRoleRep.AsInsertable(input.Adapt<SysRole>()).ExecuteReturnEntityAsync();
input.Id = newRole.Id;
await UpdateRoleMenu(input);
// 增加基础接口资源
await _sysRoleApiService.GrantRoleApi(new RoleApiInput { Id = newRole.Id, ApiList = CommonConst.SysBaseRoutes });
}
/// <summary>
@ -322,4 +322,33 @@ public class SysRoleService : IDynamicApiController, ITransient
}
return apiList;
}
/// <summary>
/// 设置基础接口资源
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("设置基础接口资源")]
public async Task SetBaseApi(BaseApiInput input)
{
_sysCacheService.Remove(CacheConst.KeyBaseApi);
await _sysBaseApiService.SetBaseApi(input);
}
/// <summary>
/// 获取基础接口资源集合
/// </summary>
/// <returns></returns>
[DisplayName("获取基础接口资源集合")]
public async Task<List<string>> GetBaseApiList()
{
var apiList = _sysCacheService.Get<List<string>>(CacheConst.KeyBaseApi);
if (apiList == null)
{
apiList = await _sysBaseApiService.GetBaseApiList();
_sysCacheService.Set(CacheConst.KeyBaseApi, apiList);
}
return apiList;
}
}

View File

@ -104,24 +104,24 @@ public static class CommonUtil
/// 导出模板Excel
/// </summary>
/// <returns></returns>
public static async Task<IActionResult> ExportExcelTemplate<T>() where T : class, new()
public static async Task<IActionResult> ExportExcelTemplate<T>(string fileName = null) where T : class, new()
{
IImporter importer = new ExcelImporter();
var res = await importer.GenerateTemplateBytes<T>();
return new FileContentResult(res, "application/octet-stream") { FileDownloadName = typeof(T).Name + ".xlsx" };
return new FileContentResult(res, "application/octet-stream") { FileDownloadName = $"{(string.IsNullOrEmpty(fileName) ? typeof(T).Name : fileName)}.xlsx" };
}
/// <summary>
/// 导出数据excel
/// </summary>
/// <returns></returns>
public static async Task<IActionResult> ExportExcelData<T>(ICollection<T> data) where T : class, new()
public static async Task<IActionResult> ExportExcelData<T>(ICollection<T> data, string fileName = null) where T : class, new()
{
var export = new ExcelExporter();
var res = await export.ExportAsByteArray<T>(data);
return new FileContentResult(res, "application/octet-stream") { FileDownloadName = typeof(T).Name + ".xlsx" };
return new FileContentResult(res, "application/octet-stream") { FileDownloadName = $"{(string.IsNullOrEmpty(fileName) ? typeof(T).Name : fileName)}.xlsx" };
}
/// <summary>
@ -275,7 +275,7 @@ public static class CommonUtil
// 整理导入对象的属性名称,<字典数据,原属性信息,目标属性信息>
var propMappings = new Dictionary<string, Tuple<Dictionary<string, object>, PropertyInfo, PropertyInfo>>();
var dictService = App.GetRequiredService<SqlSugarRepository<SysDictData>>();
var dictService = App.GetService<SqlSugarRepository<SysDictData>>();
var tSourceProps = typeof(TSource).GetProperties().ToList();
var tTargetProps = typeof(TTarget).GetProperties().ToDictionary(m => m.Name);
foreach (var propertyInfo in tSourceProps)
@ -317,7 +317,7 @@ public static class CommonUtil
// 整理导入对象的属性名称,<字典数据,原属性信息,目标属性信息>
var propMappings = new Dictionary<string, Tuple<Dictionary<object, string>, PropertyInfo, PropertyInfo>>();
var dictService = App.GetRequiredService<SqlSugarRepository<SysDictData>>();
var dictService = App.GetService<SqlSugarRepository<SysDictData>>();
var targetProps = typeof(TTarget).GetProperties().ToList();
var sourceProps = typeof(TSource).GetProperties().ToDictionary(m => m.Name);
foreach (var propertyInfo in targetProps)

View File

@ -85,8 +85,17 @@ namespace Admin.NET.Web.Core
// 接口路由权限
var path = httpContext.Request.Path.ToString();
var apis = await App.GetRequiredService<SysRoleService>().GetUserApiList();
return apis.Exists(u => path.Contains(u, StringComparison.CurrentCulture));
var sysRoleService = App.GetRequiredService<SysRoleService>();
// 若当前路由在基础接口资源集合里面则放行
var baseApis = await sysRoleService.GetBaseApiList();
if (baseApis.Exists(u => path.Contains(u, StringComparison.CurrentCulture)))
return true;
// 判断当前路由是否在角色已有接口资源里面
var roleApis = await sysRoleService.GetUserApiList();
return roleApis.Exists(u => path.Contains(u, StringComparison.CurrentCulture));
}
}
}

View File

@ -23,6 +23,7 @@ import { AdminResultListInt64 } from '../models';
import { AdminResultListRoleOutput } from '../models';
import { AdminResultListString } from '../models';
import { AdminResultSqlSugarPagedListPageRoleOutput } from '../models';
import { BaseApiInput } from '../models';
import { DeleteRoleInput } from '../models';
import { PageRoleInput } from '../models';
import { RoleApiInput } from '../models';
@ -85,6 +86,49 @@ export const SysRoleApiAxiosParamCreator = function (configuration?: Configurati
options: localVarRequestOptions,
};
},
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysRoleBaseApiListGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/sysRole/baseApiList`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication Bearer required
// http bearer authentication required
if (configuration && configuration.accessToken) {
const accessToken = typeof configuration.accessToken === 'function'
? await configuration.accessToken()
: await configuration.accessToken;
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
}
const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
query.set(key, localVarQueryParameter[key]);
}
for (const key in options.params) {
query.set(key, options.params[key]);
}
localVarUrlObj.search = (new URLSearchParams(query)).toString();
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
/**
*
* @summary 🔖
@ -539,6 +583,54 @@ export const SysRoleApiAxiosParamCreator = function (configuration?: Configurati
options: localVarRequestOptions,
};
},
/**
*
* @summary
* @param {BaseApiInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiSysRoleSetBaseApiPost: async (body?: BaseApiInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/api/sysRole/setBaseApi`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication Bearer required
// http bearer authentication required
if (configuration && configuration.accessToken) {
const accessToken = typeof configuration.accessToken === 'function'
? await configuration.accessToken()
: await configuration.accessToken;
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
}
localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
query.set(key, localVarQueryParameter[key]);
}
for (const key in options.params) {
query.set(key, options.params[key]);
}
localVarUrlObj.search = (new URLSearchParams(query)).toString();
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
/**
*
* @summary 🔖
@ -701,6 +793,19 @@ export const SysRoleApiFp = function(configuration?: Configuration) {
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysRoleBaseApiListGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListString>>> {
const localVarAxiosArgs = await SysRoleApiAxiosParamCreator(configuration).apiSysRoleBaseApiListGet(options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary 🔖
@ -829,6 +934,20 @@ export const SysRoleApiFp = function(configuration?: Configuration) {
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary
* @param {BaseApiInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysRoleSetBaseApiPost(body?: BaseApiInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
const localVarAxiosArgs = await SysRoleApiAxiosParamCreator(configuration).apiSysRoleSetBaseApiPost(body, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary 🔖
@ -889,6 +1008,15 @@ export const SysRoleApiFactory = function (configuration?: Configuration, basePa
async apiSysRoleAddPost(body?: AddRoleInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
return SysRoleApiFp(configuration).apiSysRoleAddPost(body, options).then((request) => request(axios, basePath));
},
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysRoleBaseApiListGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListString>> {
return SysRoleApiFp(configuration).apiSysRoleBaseApiListGet(options).then((request) => request(axios, basePath));
},
/**
*
* @summary 🔖
@ -981,6 +1109,16 @@ export const SysRoleApiFactory = function (configuration?: Configuration, basePa
async apiSysRolePagePost(body?: PageRoleInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListPageRoleOutput>> {
return SysRoleApiFp(configuration).apiSysRolePagePost(body, options).then((request) => request(axios, basePath));
},
/**
*
* @summary
* @param {BaseApiInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiSysRoleSetBaseApiPost(body?: BaseApiInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
return SysRoleApiFp(configuration).apiSysRoleSetBaseApiPost(body, options).then((request) => request(axios, basePath));
},
/**
*
* @summary 🔖
@ -1031,6 +1169,16 @@ export class SysRoleApi extends BaseAPI {
public async apiSysRoleAddPost(body?: AddRoleInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
return SysRoleApiFp(this.configuration).apiSysRoleAddPost(body, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysRoleApi
*/
public async apiSysRoleBaseApiListGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListString>> {
return SysRoleApiFp(this.configuration).apiSysRoleBaseApiListGet(options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary 🔖
@ -1132,6 +1280,17 @@ export class SysRoleApi extends BaseAPI {
public async apiSysRolePagePost(body?: PageRoleInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListPageRoleOutput>> {
return SysRoleApiFp(this.configuration).apiSysRolePagePost(body, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary
* @param {BaseApiInput} [body]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SysRoleApi
*/
public async apiSysRoleSetBaseApiPost(body?: BaseApiInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
return SysRoleApiFp(this.configuration).apiSysRoleSetBaseApiPost(body, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary 🔖

View File

@ -0,0 +1,38 @@
/* 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.
*/
/**
*
*
* @export
* @interface BaseApiInput
*/
export interface BaseApiInput {
/**
* Id
*
* @type {number}
* @memberof BaseApiInput
*/
id: number;
/**
*
*
* @type {Array<string>}
* @memberof BaseApiInput
*/
apiList?: Array<string> | null;
}

View File

@ -28,6 +28,14 @@ export interface EnumEntity {
*/
describe?: string | null;
/**
*
*
* @type {string}
* @memberof EnumEntity
*/
theme?: string | null;
/**
*
*

View File

@ -101,6 +101,7 @@ export * from './admin-result-wx-phone-output';
export * from './api-info';
export * from './api-output';
export * from './assembly';
export * from './base-api-input';
export * from './base-proc-input';
export * from './batch-config-input';
export * from './calendar';

View File

@ -0,0 +1,124 @@
<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>
<template #footer>
<div style="margin-bottom: 20px; margin-right: 20px">
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</div>
</template>
</el-drawer>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { ElTable } from 'element-plus';
import { getAPI } from '/@/utils/axios-utils';
import { SysCommonApi, SysRoleApi } from '/@/api-services/api';
const tableRef = ref<InstanceType<typeof ElTable>>() as any;
const state = reactive({
loading: false,
isVisible: false,
allApiData: [] as any,
ownApiList: [] as any,
selectRow: [] as any,
drawerTitle: '',
selectedTabName: 0,
});
//
const openDrawer = () => {
state.selectedTabName = 0;
state.drawerTitle = '基础接口资源';
state.isVisible = true;
handleQuery();
};
//
const handleQuery = async () => {
//
state.loading = true;
var res = await getAPI(SysCommonApi).apiSysCommonApiListGet();
state.allApiData = res.data.result ?? [];
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;
}
}
}
}
};
//
const handleSelectionChange = (val: any) => {
state.selectRow = val;
};
//
const cancel = () => {
state.isVisible = false;
};
//
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);
});
}
}
await getAPI(SysRoleApi).apiSysRoleSetBaseApiPost({ id: 0, apiList: state.ownApiList });
cancel();
};
//
defineExpose({ openDrawer });
</script>

View File

@ -48,7 +48,7 @@
icon="ele-Menu"
highlight-current
default-expand-all
style="height: 600px;overflow-y: auto;"
style="height: 600px; overflow-y: auto; width: 100%"
/>
</el-form-item>
</el-col>

View File

@ -30,7 +30,7 @@
<template #footer>
<div style="margin-bottom: 20px; margin-right: 20px">
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="submit">认授权接口资源</el-button>
<el-button type="primary" @click="submit"> </el-button>
</div>
</template>
</el-drawer>

View File

@ -17,6 +17,9 @@
<el-form-item>
<el-button type="primary" icon="ele-Plus" @click="openAddRole" v-auth="'sysRole:add'"> 新增 </el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="ele-Link" @click="openBaseApi" plain> 设置基础接口资源 </el-button>
</el-form-item>
</el-form>
</el-card>
@ -72,6 +75,7 @@
<EditRole ref="editRoleRef" :title="state.editRoleTitle" @handleQuery="handleQuery" />
<GrantData ref="grantDataRef" @handleQuery="handleQuery" />
<GrantApi ref="grantApiRef" @handleQuery="handleQuery" />
<BaseApi ref="baseApiRef" />
</div>
</template>
@ -82,6 +86,7 @@ import { auth } from '/@/utils/authFunction';
import EditRole from '/@/views/system/role/component/editRole.vue';
import GrantData from '/@/views/system/role/component/grantData.vue';
import GrantApi from '/@/views/system/role/component/grantApi.vue';
import BaseApi from '/@/views/system/role/component/baseApi.vue';
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import { getAPI } from '/@/utils/axios-utils';
@ -91,6 +96,7 @@ import { PageRoleOutput } from '/@/api-services/models';
const editRoleRef = ref<InstanceType<typeof EditRole>>();
const grantDataRef = ref<InstanceType<typeof GrantData>>();
const grantApiRef = ref<InstanceType<typeof GrantApi>>();
const baseApiRef = ref<InstanceType<typeof BaseApi>>();
const state = reactive({
loading: false,
roleData: [] as Array<PageRoleOutput>,
@ -149,6 +155,11 @@ const openGrantApi = (row: any) => {
grantApiRef.value?.openDrawer(row);
};
//
const openBaseApi = () => {
baseApiRef.value?.openDrawer();
};
//
const delRole = (row: any) => {
ElMessageBox.confirm(`确定删角色:【${row.name}】?`, '提示', {