Bladeren bron

feat: 开放接口身份界面

许俊杰 2 jaren geleden
bovenliggende
commit
614e020617
32 gewijzigde bestanden met toevoegingen van 2007 en 19 verwijderingen
  1. 17 5
      Admin.NET/Admin.NET.Core/Entity/SysOpenAccess.cs
  2. 6 0
      Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs
  3. 6 0
      Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs
  4. 31 2
      Admin.NET/Admin.NET.Core/Service/Auth/Dto/OpenAccessInput.cs
  5. 23 0
      Admin.NET/Admin.NET.Core/Service/Auth/Dto/OpenAccessOutput.cs
  6. 85 12
      Admin.NET/Admin.NET.Core/Service/Auth/SysOpenAccessService.cs
  7. 8 0
      Admin.NET/Admin.NET.Core/Service/Tenant/Dto/TenantInput.cs
  8. 11 0
      Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs
  9. 1 0
      Web/src/api-services/api.ts
  10. 75 0
      Web/src/api-services/apis/sys-dict-type-api.ts
  11. 466 0
      Web/src/api-services/apis/sys-open-access-api.ts
  12. 85 0
      Web/src/api-services/apis/sys-tenant-api.ts
  13. 7 0
      Web/src/api-services/models/add-dict-type-input.ts
  14. 94 0
      Web/src/api-services/models/add-open-access-input.ts
  15. 57 0
      Web/src/api-services/models/admin-result-list-sys-user.ts
  16. 57 0
      Web/src/api-services/models/admin-result-sql-sugar-paged-list-open-access-output.ts
  17. 57 0
      Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-open-access.ts
  18. 26 0
      Web/src/api-services/models/delete-open-access-input.ts
  19. 10 0
      Web/src/api-services/models/index.ts
  20. 6 0
      Web/src/api-services/models/login-user-output.ts
  21. 56 0
      Web/src/api-services/models/open-access-input.ts
  22. 106 0
      Web/src/api-services/models/open-access-output.ts
  23. 63 0
      Web/src/api-services/models/sql-sugar-paged-list-open-access-output.ts
  24. 63 0
      Web/src/api-services/models/sql-sugar-paged-list-sys-open-access.ts
  25. 7 0
      Web/src/api-services/models/sys-dict-type.ts
  26. 81 0
      Web/src/api-services/models/sys-open-access.ts
  27. 119 0
      Web/src/api-services/models/sys-tenant.ts
  28. 26 0
      Web/src/api-services/models/tenant-id-input.ts
  29. 7 0
      Web/src/api-services/models/update-dict-type-input.ts
  30. 94 0
      Web/src/api-services/models/update-open-access-input.ts
  31. 123 0
      Web/src/views/system/openAccess/component/editOpenAccess.vue
  32. 134 0
      Web/src/views/system/openAccess/index.vue

+ 17 - 5
Admin.NET/Admin.NET.Core/Entity/SysOpenAccess.cs

@@ -10,9 +10,9 @@
 namespace Admin.NET.Core;
 
 /// <summary>
-/// 开放接口访问
+/// 开放接口身份
 /// </summary>
-[SugarTable(null, "开放接口访问表")]
+[SugarTable(null, "开放接口身份表")]
 [SysTable]
 public class SysOpenAccess : EntityBase
 {
@@ -20,19 +20,31 @@ public class SysOpenAccess : EntityBase
     /// 身份标识
     /// </summary>
     [SugarColumn(ColumnDescription = "身份标识", Length = 80)]
-    public string AccessKey { get; set; }
+    public virtual string AccessKey { get; set; }
 
     /// <summary>
     /// 密钥
     /// </summary>
     [SugarColumn(ColumnDescription = "密钥", Length = 255)]
-    public string AccessSecret { get; set; }
+    public virtual string AccessSecret { get; set; }
+
+    /// <summary>
+    /// 绑定租户Id
+    /// </summary>
+    [SugarColumn(ColumnDescription = "绑定租户Id")]
+    public long BindTenantId { get; set; }
+
+    /// <summary>
+    /// 绑定租户
+    /// </summary>
+    [Navigate(NavigateType.OneToOne, nameof(BindTenantId))]
+    public SysTenant BindTenant { get; set; }
 
     /// <summary>
     /// 绑定用户Id
     /// </summary>
     [SugarColumn(ColumnDescription = "绑定用户Id")]
-    public long BindUserId { get; set; }
+    public virtual long BindUserId { get; set; }
 
     /// <summary>
     /// 绑定用户

+ 6 - 0
Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs

@@ -633,4 +633,10 @@ public enum ErrorCodeEnum
     /// </summary>
     [ErrorCodeItemMetadata("租户已禁用")]
     Z1003,
+
+    /// <summary>
+    /// 身份标识已存在
+    /// </summary>
+    [ErrorCodeItemMetadata("身份标识已存在")]
+    O1000,
 }

+ 6 - 0
Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs

@@ -149,6 +149,12 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
             new SysMenu{ Id=1310000000414, Pid=1310000000411, Title="增加", Permission="sysPlugin:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000415, Pid=1310000000411, Title="删除", Permission="sysPlugin:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
 
+            new SysMenu{ Id=1310000000421, Pid=1310000000301, Title="开放接口身份", Path="/platform/openAccess", Name="sysOpenAccess", Component="/system/openAccess/index", Icon="ele-Link", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=210 },
+            new SysMenu{ Id=1310000000422, Pid=1310000000421, Title="查询", Permission="sysOpenAccess:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000423, Pid=1310000000421, Title="编辑", Permission="sysOpenAccess:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000424, Pid=1310000000421, Title="增加", Permission="sysOpenAccess:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000425, Pid=1310000000421, Title="删除", Permission="sysOpenAccess:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
             new SysMenu{ Id=1310000000501, Pid=0, Title="日志管理", Path="/log", Name="log", Component="Layout", Icon="ele-DocumentCopy", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=12000 },
             new SysMenu{ Id=1310000000511, Pid=1310000000501, Title="访问日志", Path="/log/vislog", Name="sysVislog", Component="/system/log/vislog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000512, Pid=1310000000511, Title="查询", Permission="sysVislog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },

+ 31 - 2
Admin.NET/Admin.NET.Core/Service/Auth/Dto/OpenAccessInput.cs

@@ -1,7 +1,7 @@
 namespace Admin.NET.Core.Service;
 
 /// <summary>
-/// 开放接口访问输入参数
+/// 开放接口身份输入参数
 /// </summary>
 public class OpenAccessInput : BasePageInput
 {
@@ -9,4 +9,33 @@ public class OpenAccessInput : BasePageInput
     /// 身份标识
     /// </summary>
     public string AccessKey { get; set; }
-}
+}
+
+public class AddOpenAccessInput : SysOpenAccess
+{
+    /// <summary>
+    /// 身份标识
+    /// </summary>
+    [Required(ErrorMessage = "身份标识不能为空")]
+    public override string AccessKey { get; set; }
+
+    /// <summary>
+    /// 密钥
+    /// </summary>
+    [Required(ErrorMessage = "密钥不能为空")]
+    public override string AccessSecret { get; set; }
+
+    /// <summary>
+    /// 绑定用户Id
+    /// </summary>
+    [Required(ErrorMessage = "绑定用户不能为空")]
+    public override long BindUserId { get; set; }
+}
+
+public class UpdateOpenAccessInput : AddOpenAccessInput
+{
+}
+
+public class DeleteOpenAccessInput : BaseIdInput
+{
+}

+ 23 - 0
Admin.NET/Admin.NET.Core/Service/Auth/Dto/OpenAccessOutput.cs

@@ -0,0 +1,23 @@
+// 麻省理工学院许可证
+// 
+// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
+// 
+// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
+// 
+// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
+// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
+
+namespace Admin.NET.Core.Service;
+
+public class OpenAccessOutput : SysOpenAccess
+{
+    /// <summary>
+    /// 绑定用户账号
+    /// </summary>
+    public string BindUserAccount { get; set; }
+
+    /// <summary>
+    /// 绑定租户名称
+    /// </summary>
+    public string BindTenantName { get; set; }
+}

+ 85 - 12
Admin.NET/Admin.NET.Core/Service/Auth/SysOpenAccessService.cs

@@ -1,45 +1,118 @@
-using System.Security.Claims;
+using Microsoft.VisualBasic;
+using System.Security.Claims;
 
 namespace Admin.NET.Core.Service;
 
 /// <summary>
-/// 开放接口访问服务
+/// 开放接口身份服务
 /// </summary>
-[ApiDescriptionSettings(Order = 510)]
+[ApiDescriptionSettings(Order = 244)]
 public class SysOpenAccessService : IDynamicApiController, ITransient
 {
     private readonly SqlSugarRepository<SysOpenAccess> _sysOpenAccessRep;
+    private readonly SqlSugarRepository<SysUser> _sysUserRep;
     private readonly SysCacheService _sysCacheService;
+
     /// <summary>
-    /// 开放接口访问服务构造函数
+    /// 开放接口身份服务构造函数
     /// </summary>
     public SysOpenAccessService(SqlSugarRepository<SysOpenAccess> sysOpenAccessRep,
+        SqlSugarRepository<SysUser> sysUserRep,
         SysCacheService sysCacheService)
     {
         _sysOpenAccessRep = sysOpenAccessRep;
+        _sysUserRep = sysUserRep;
         _sysCacheService = sysCacheService;
     }
 
     /// <summary>
-    /// 获取开放接口访问分页列表
+    /// 获取开放接口身份分页列表
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
-    [DisplayName("获取开放接口访问分页列表")]
-    public async Task<SqlSugarPagedList<SysOpenAccess>> Page(OpenAccessInput input)
+    [DisplayName("获取开放接口身份分页列表")]
+    public async Task<SqlSugarPagedList<OpenAccessOutput>> Page(OpenAccessInput input)
     {
         return await _sysOpenAccessRep.AsQueryable()
-            .WhereIF(!string.IsNullOrWhiteSpace(input.AccessKey?.Trim()), u => u.AccessKey.Contains(input.AccessKey))
-            .OrderBuilder(input)
+            .LeftJoin<SysUser>((o, u) => o.BindUserId == u.Id)
+            .LeftJoin<SysTenant>((o, u, t) => o.BindTenantId == t.Id)
+            .LeftJoin<SysOrg>((o, u, t, oo) => t.OrgId == oo.Id)
+            .WhereIF(!string.IsNullOrWhiteSpace(input.AccessKey?.Trim()), (o, u, t, oo) => o.AccessKey.Contains(input.AccessKey))
+            .Select((o, u, t, oo) =>
+                new OpenAccessOutput
+                {
+                    BindUserAccount = u.Account,
+                    BindTenantName = oo.Name,
+                }, true)
             .ToPagedListAsync(input.Page, input.PageSize);
     }
 
+    /// <summary>
+    /// 增加开放接口身份
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [ApiDescriptionSettings(Name = "Add"), HttpPost]
+    [DisplayName("增加开放接口身份")]
+    public async Task AddOpenAccess(AddOpenAccessInput input)
+    {
+        if (await _sysOpenAccessRep.AsQueryable().AnyAsync(u => u.AccessKey == input.AccessKey && u.Id != input.Id))
+            throw Oops.Oh(ErrorCodeEnum.O1000);
+
+        var openAccess = input.Adapt<SysOpenAccess>();
+        await _sysOpenAccessRep.InsertAsync(openAccess);
+    }
+
+    /// <summary>
+    /// 更新开放接口身份
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [ApiDescriptionSettings(Name = "Update"), HttpPost]
+    [DisplayName("更新开放接口身份")]
+    public async Task UpdateOpenAccess(UpdateOpenAccessInput input)
+    {
+        if (await _sysOpenAccessRep.AsQueryable().AnyAsync(u => u.AccessKey == input.AccessKey && u.Id != input.Id))
+            throw Oops.Oh(ErrorCodeEnum.O1000);
+
+        var openAccess = input.Adapt<SysOpenAccess>();
+        _sysCacheService.Remove(CacheConst.KeyOpenAccess + openAccess.AccessKey);
+
+        await _sysOpenAccessRep.UpdateAsync(openAccess);
+    }
+
+    /// <summary>
+    /// 删除开放接口身份
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [ApiDescriptionSettings(Name = "Delete"), HttpPost]
+    [DisplayName("删除开放接口身份")]
+    public async Task DeleteOpenAccess(DeleteOpenAccessInput input)
+    {
+        var openAccess = await _sysOpenAccessRep.GetFirstAsync(u => u.Id == input.Id);
+        if (openAccess != null)
+            _sysCacheService.Remove(CacheConst.KeyOpenAccess + openAccess.AccessKey);
+
+        await _sysOpenAccessRep.DeleteAsync(u => u.Id == input.Id);
+    }
+
+    /// <summary>
+    /// 创建密钥
+    /// </summary>
+    /// <returns></returns>
+    [DisplayName("创建密钥")]
+    public Task<string> CreateSecret()
+    {
+        return Task.FromResult(Convert.ToBase64String(Guid.NewGuid().ToByteArray())[..^2]);
+    }
+
     /// <summary>
     /// 根据 Key 获取对象
     /// </summary>
     /// <param name="accessKey"></param>
     /// <returns></returns>
-    [HttpGet("getByKey")]
+    [NonAction]
     public Task<SysOpenAccess> GetByKey([FromQuery] string accessKey)
     {
         return Task.FromResult(
@@ -84,8 +157,8 @@ public class SysOpenAccessService : IDynamicApiController, ITransient
 
                 identity.AddClaims(new[]
                 {
-                    new Claim(ClaimConst.UserId, openAccess.BindUser.Id + ""),
-                    new Claim(ClaimConst.TenantId, openAccess.BindUser.TenantId + ""),
+                    new Claim(ClaimConst.UserId, openAccess.BindUserId + ""),
+                    new Claim(ClaimConst.TenantId, openAccess.BindTenantId + ""),
                     new Claim(ClaimConst.Account, openAccess.BindUser.Account + ""),
                     new Claim(ClaimConst.RealName, openAccess.BindUser.RealName),
                     new Claim(ClaimConst.AccountType, ((int) openAccess.BindUser.AccountType).ToString()),

+ 8 - 0
Admin.NET/Admin.NET.Core/Service/Tenant/Dto/TenantInput.cs

@@ -59,4 +59,12 @@ public class TenantUserInput
     /// 用户Id
     /// </summary>
     public long UserId { get; set; }
+}
+
+public class TenantIdInput
+{
+    /// <summary>
+    /// 租户Id
+    /// </summary>
+    public long TenantId { get; set; }
 }

+ 11 - 0
Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs

@@ -401,4 +401,15 @@ public class SysTenantService : IDynamicApiController, ITransient
         };
         SqlSugarSetup.InitTenantDatabase(App.GetRequiredService<ISqlSugarClient>().AsTenant(), config);
     }
+
+    /// <summary>
+    /// 获取租户下的用户列表
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [DisplayName("获取租户下的用户列表")]
+    public async Task<List<SysUser>> UserList(TenantIdInput input)
+    {
+        return await _sysUserRep.AsQueryable().Filter(null, true).Where(u => u.TenantId == input.TenantId).ToListAsync();
+    }
 }

+ 1 - 0
Web/src/api-services/api.ts

@@ -32,6 +32,7 @@ export * from './apis/sys-message-api';
 export * from './apis/sys-notice-api';
 export * from './apis/sys-oauth-api';
 export * from './apis/sys-online-user-api';
+export * from './apis/sys-open-access-api';
 export * from './apis/sys-org-api';
 export * from './apis/sys-plugin-api';
 export * from './apis/sys-pos-api';

+ 75 - 0
Web/src/api-services/apis/sys-dict-type-api.ts

@@ -237,6 +237,49 @@ export const SysDictTypeApiAxiosParamCreator = function (configuration?: Configu
                 options: localVarRequestOptions,
             };
         },
+        /**
+         * 
+         * @summary 获取所有字典集合
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysDictTypeGetAllDictGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysDictType/getAllDict`;
+            // 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 获取字典类型列表
@@ -490,6 +533,19 @@ export const SysDictTypeApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 获取所有字典集合
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysDictTypeGetAllDictGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListSysDictType>>> {
+            const localVarAxiosArgs = await SysDictTypeApiAxiosParamCreator(configuration).apiSysDictTypeGetAllDictGet(options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 获取字典类型列表
@@ -595,6 +651,15 @@ export const SysDictTypeApiFactory = function (configuration?: Configuration, ba
         async apiSysDictTypeDetailGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSysDictType>> {
             return SysDictTypeApiFp(configuration).apiSysDictTypeDetailGet(id, status, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 获取所有字典集合
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysDictTypeGetAllDictGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysDictType>> {
+            return SysDictTypeApiFp(configuration).apiSysDictTypeGetAllDictGet(options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 获取字典类型列表
@@ -689,6 +754,16 @@ export class SysDictTypeApi extends BaseAPI {
     public async apiSysDictTypeDetailGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSysDictType>> {
         return SysDictTypeApiFp(this.configuration).apiSysDictTypeDetailGet(id, status, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 获取所有字典集合
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysDictTypeApi
+     */
+    public async apiSysDictTypeGetAllDictGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysDictType>> {
+        return SysDictTypeApiFp(this.configuration).apiSysDictTypeGetAllDictGet(options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 获取字典类型列表

+ 466 - 0
Web/src/api-services/apis/sys-open-access-api.ts

@@ -0,0 +1,466 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import globalAxios, { AxiosResponse, AxiosInstance, AxiosRequestConfig } from 'axios';
+import { Configuration } from '../configuration';
+// Some imports not used depending on template conditions
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
+import { AddOpenAccessInput } from '../models';
+import { AdminResultSqlSugarPagedListOpenAccessOutput } from '../models';
+import { AdminResultString } from '../models';
+import { DeleteOpenAccessInput } from '../models';
+import { OpenAccessInput } from '../models';
+import { UpdateOpenAccessInput } from '../models';
+/**
+ * SysOpenAccessApi - axios parameter creator
+ * @export
+ */
+export const SysOpenAccessApiAxiosParamCreator = function (configuration?: Configuration) {
+    return {
+        /**
+         * 
+         * @summary 增加开放接口身份
+         * @param {AddOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysOpenAccessAddPost: async (body?: AddOpenAccessInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysOpenAccess/add`;
+            // 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 删除开放接口身份
+         * @param {DeleteOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysOpenAccessDeletePost: async (body?: DeleteOpenAccessInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysOpenAccess/delete`;
+            // 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 获取开放接口身份分页列表
+         * @param {OpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysOpenAccessPagePost: async (body?: OpenAccessInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysOpenAccess/page`;
+            // 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 创建密钥
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysOpenAccessSecretPost: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysOpenAccess/secret`;
+            // 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;
+            }
+
+            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 更新开放接口身份
+         * @param {UpdateOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysOpenAccessUpdatePost: async (body?: UpdateOpenAccessInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysOpenAccess/update`;
+            // 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,
+            };
+        },
+    }
+};
+
+/**
+ * SysOpenAccessApi - functional programming interface
+ * @export
+ */
+export const SysOpenAccessApiFp = function(configuration?: Configuration) {
+    return {
+        /**
+         * 
+         * @summary 增加开放接口身份
+         * @param {AddOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessAddPost(body?: AddOpenAccessInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
+            const localVarAxiosArgs = await SysOpenAccessApiAxiosParamCreator(configuration).apiSysOpenAccessAddPost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 删除开放接口身份
+         * @param {DeleteOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessDeletePost(body?: DeleteOpenAccessInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
+            const localVarAxiosArgs = await SysOpenAccessApiAxiosParamCreator(configuration).apiSysOpenAccessDeletePost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 获取开放接口身份分页列表
+         * @param {OpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessPagePost(body?: OpenAccessInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSqlSugarPagedListOpenAccessOutput>>> {
+            const localVarAxiosArgs = await SysOpenAccessApiAxiosParamCreator(configuration).apiSysOpenAccessPagePost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 创建密钥
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessSecretPost(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultString>>> {
+            const localVarAxiosArgs = await SysOpenAccessApiAxiosParamCreator(configuration).apiSysOpenAccessSecretPost(options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 更新开放接口身份
+         * @param {UpdateOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessUpdatePost(body?: UpdateOpenAccessInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
+            const localVarAxiosArgs = await SysOpenAccessApiAxiosParamCreator(configuration).apiSysOpenAccessUpdatePost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+    }
+};
+
+/**
+ * SysOpenAccessApi - factory interface
+ * @export
+ */
+export const SysOpenAccessApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
+    return {
+        /**
+         * 
+         * @summary 增加开放接口身份
+         * @param {AddOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessAddPost(body?: AddOpenAccessInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
+            return SysOpenAccessApiFp(configuration).apiSysOpenAccessAddPost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 删除开放接口身份
+         * @param {DeleteOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessDeletePost(body?: DeleteOpenAccessInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
+            return SysOpenAccessApiFp(configuration).apiSysOpenAccessDeletePost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 获取开放接口身份分页列表
+         * @param {OpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessPagePost(body?: OpenAccessInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListOpenAccessOutput>> {
+            return SysOpenAccessApiFp(configuration).apiSysOpenAccessPagePost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 创建密钥
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessSecretPost(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultString>> {
+            return SysOpenAccessApiFp(configuration).apiSysOpenAccessSecretPost(options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 更新开放接口身份
+         * @param {UpdateOpenAccessInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysOpenAccessUpdatePost(body?: UpdateOpenAccessInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
+            return SysOpenAccessApiFp(configuration).apiSysOpenAccessUpdatePost(body, options).then((request) => request(axios, basePath));
+        },
+    };
+};
+
+/**
+ * SysOpenAccessApi - object-oriented interface
+ * @export
+ * @class SysOpenAccessApi
+ * @extends {BaseAPI}
+ */
+export class SysOpenAccessApi extends BaseAPI {
+    /**
+     * 
+     * @summary 增加开放接口身份
+     * @param {AddOpenAccessInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysOpenAccessApi
+     */
+    public async apiSysOpenAccessAddPost(body?: AddOpenAccessInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
+        return SysOpenAccessApiFp(this.configuration).apiSysOpenAccessAddPost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 删除开放接口身份
+     * @param {DeleteOpenAccessInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysOpenAccessApi
+     */
+    public async apiSysOpenAccessDeletePost(body?: DeleteOpenAccessInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
+        return SysOpenAccessApiFp(this.configuration).apiSysOpenAccessDeletePost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 获取开放接口身份分页列表
+     * @param {OpenAccessInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysOpenAccessApi
+     */
+    public async apiSysOpenAccessPagePost(body?: OpenAccessInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListOpenAccessOutput>> {
+        return SysOpenAccessApiFp(this.configuration).apiSysOpenAccessPagePost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 创建密钥
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysOpenAccessApi
+     */
+    public async apiSysOpenAccessSecretPost(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultString>> {
+        return SysOpenAccessApiFp(this.configuration).apiSysOpenAccessSecretPost(options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 更新开放接口身份
+     * @param {UpdateOpenAccessInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysOpenAccessApi
+     */
+    public async apiSysOpenAccessUpdatePost(body?: UpdateOpenAccessInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
+        return SysOpenAccessApiFp(this.configuration).apiSysOpenAccessUpdatePost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+}

+ 85 - 0
Web/src/api-services/apis/sys-tenant-api.ts

@@ -19,11 +19,13 @@ import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } fr
 import { AddTenantInput } from '../models';
 import { AdminResultInt32 } from '../models';
 import { AdminResultListInt64 } from '../models';
+import { AdminResultListSysUser } from '../models';
 import { AdminResultSqlSugarPagedListTenantOutput } from '../models';
 import { AdminResultString } from '../models';
 import { DeleteTenantInput } from '../models';
 import { PageTenantInput } from '../models';
 import { RoleMenuInput } from '../models';
+import { TenantIdInput } from '../models';
 import { TenantInput } from '../models';
 import { TenantUserInput } from '../models';
 import { UpdateTenantInput } from '../models';
@@ -460,6 +462,54 @@ export const SysTenantApiAxiosParamCreator = function (configuration?: Configura
             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 获取租户下的用户列表
+         * @param {TenantIdInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysTenantUserListPost: async (body?: TenantIdInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysTenant/userList`;
+            // 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,
@@ -600,6 +650,20 @@ export const SysTenantApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 获取租户下的用户列表
+         * @param {TenantIdInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysTenantUserListPost(body?: TenantIdInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListSysUser>>> {
+            const localVarAxiosArgs = await SysTenantApiAxiosParamCreator(configuration).apiSysTenantUserListPost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
     }
 };
 
@@ -699,6 +763,16 @@ export const SysTenantApiFactory = function (configuration?: Configuration, base
         async apiSysTenantUpdatePost(body?: UpdateTenantInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
             return SysTenantApiFp(configuration).apiSysTenantUpdatePost(body, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 获取租户下的用户列表
+         * @param {TenantIdInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysTenantUserListPost(body?: TenantIdInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysUser>> {
+            return SysTenantApiFp(configuration).apiSysTenantUserListPost(body, options).then((request) => request(axios, basePath));
+        },
     };
 };
 
@@ -808,4 +882,15 @@ export class SysTenantApi extends BaseAPI {
     public async apiSysTenantUpdatePost(body?: UpdateTenantInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
         return SysTenantApiFp(this.configuration).apiSysTenantUpdatePost(body, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 获取租户下的用户列表
+     * @param {TenantIdInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysTenantApi
+     */
+    public async apiSysTenantUserListPost(body?: TenantIdInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysUser>> {
+        return SysTenantApiFp(this.configuration).apiSysTenantUserListPost(body, options).then((request) => request(this.axios, this.basePath));
+    }
 }

+ 7 - 0
Web/src/api-services/models/add-dict-type-input.ts

@@ -12,6 +12,7 @@
  * Do not edit the class manually.
  */
 import { StatusEnum } from './status-enum';
+import { SysDictData } from './sys-dict-data';
 /**
  * 
  * @export
@@ -84,4 +85,10 @@ export interface AddDictTypeInput {
      * @memberof AddDictTypeInput
      */
     status?: StatusEnum;
+    /**
+     * 字典值集合
+     * @type {Array<SysDictData>}
+     * @memberof AddDictTypeInput
+     */
+    children?: Array<SysDictData> | null;
 }

+ 94 - 0
Web/src/api-services/models/add-open-access-input.ts

@@ -0,0 +1,94 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SysTenant } from './sys-tenant';
+import { SysUser } from './sys-user';
+/**
+ * 
+ * @export
+ * @interface AddOpenAccessInput
+ */
+export interface AddOpenAccessInput {
+    /**
+     * 雪花Id
+     * @type {number}
+     * @memberof AddOpenAccessInput
+     */
+    id?: number;
+    /**
+     * 创建时间
+     * @type {Date}
+     * @memberof AddOpenAccessInput
+     */
+    createTime?: Date | null;
+    /**
+     * 更新时间
+     * @type {Date}
+     * @memberof AddOpenAccessInput
+     */
+    updateTime?: Date | null;
+    /**
+     * 创建者Id
+     * @type {number}
+     * @memberof AddOpenAccessInput
+     */
+    createUserId?: number | null;
+    /**
+     * 修改者Id
+     * @type {number}
+     * @memberof AddOpenAccessInput
+     */
+    updateUserId?: number | null;
+    /**
+     * 软删除
+     * @type {boolean}
+     * @memberof AddOpenAccessInput
+     */
+    isDelete?: boolean;
+    /**
+     * 
+     * @type {SysUser}
+     * @memberof AddOpenAccessInput
+     */
+    bindUser?: SysUser;
+    /**
+     * 绑定租户Id
+     * @type {number}
+     * @memberof AddOpenAccessInput
+     */
+    bindTenantId?: number;
+    /**
+     * 
+     * @type {SysTenant}
+     * @memberof AddOpenAccessInput
+     */
+    bindTenant?: SysTenant;
+    /**
+     * 身份标识
+     * @type {string}
+     * @memberof AddOpenAccessInput
+     */
+    accessKey: string;
+    /**
+     * 密钥
+     * @type {string}
+     * @memberof AddOpenAccessInput
+     */
+    accessSecret: string;
+    /**
+     * 绑定用户Id
+     * @type {number}
+     * @memberof AddOpenAccessInput
+     */
+    bindUserId: number;
+}

+ 57 - 0
Web/src/api-services/models/admin-result-list-sys-user.ts

@@ -0,0 +1,57 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SysUser } from './sys-user';
+/**
+ * 全局返回结果
+ * @export
+ * @interface AdminResultListSysUser
+ */
+export interface AdminResultListSysUser {
+    /**
+     * 状态码
+     * @type {number}
+     * @memberof AdminResultListSysUser
+     */
+    code?: number;
+    /**
+     * 类型success、warning、error
+     * @type {string}
+     * @memberof AdminResultListSysUser
+     */
+    type?: string | null;
+    /**
+     * 错误信息
+     * @type {string}
+     * @memberof AdminResultListSysUser
+     */
+    message?: string | null;
+    /**
+     * 数据
+     * @type {Array<SysUser>}
+     * @memberof AdminResultListSysUser
+     */
+    result?: Array<SysUser> | null;
+    /**
+     * 附加数据
+     * @type {any}
+     * @memberof AdminResultListSysUser
+     */
+    extras?: any | null;
+    /**
+     * 时间
+     * @type {Date}
+     * @memberof AdminResultListSysUser
+     */
+    time?: Date;
+}

+ 57 - 0
Web/src/api-services/models/admin-result-sql-sugar-paged-list-open-access-output.ts

@@ -0,0 +1,57 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SqlSugarPagedListOpenAccessOutput } from './sql-sugar-paged-list-open-access-output';
+/**
+ * 全局返回结果
+ * @export
+ * @interface AdminResultSqlSugarPagedListOpenAccessOutput
+ */
+export interface AdminResultSqlSugarPagedListOpenAccessOutput {
+    /**
+     * 状态码
+     * @type {number}
+     * @memberof AdminResultSqlSugarPagedListOpenAccessOutput
+     */
+    code?: number;
+    /**
+     * 类型success、warning、error
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListOpenAccessOutput
+     */
+    type?: string | null;
+    /**
+     * 错误信息
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListOpenAccessOutput
+     */
+    message?: string | null;
+    /**
+     * 
+     * @type {SqlSugarPagedListOpenAccessOutput}
+     * @memberof AdminResultSqlSugarPagedListOpenAccessOutput
+     */
+    result?: SqlSugarPagedListOpenAccessOutput;
+    /**
+     * 附加数据
+     * @type {any}
+     * @memberof AdminResultSqlSugarPagedListOpenAccessOutput
+     */
+    extras?: any | null;
+    /**
+     * 时间
+     * @type {Date}
+     * @memberof AdminResultSqlSugarPagedListOpenAccessOutput
+     */
+    time?: Date;
+}

+ 57 - 0
Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-open-access.ts

@@ -0,0 +1,57 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SqlSugarPagedListSysOpenAccess } from './sql-sugar-paged-list-sys-open-access';
+/**
+ * 全局返回结果
+ * @export
+ * @interface AdminResultSqlSugarPagedListSysOpenAccess
+ */
+export interface AdminResultSqlSugarPagedListSysOpenAccess {
+    /**
+     * 状态码
+     * @type {number}
+     * @memberof AdminResultSqlSugarPagedListSysOpenAccess
+     */
+    code?: number;
+    /**
+     * 类型success、warning、error
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListSysOpenAccess
+     */
+    type?: string | null;
+    /**
+     * 错误信息
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListSysOpenAccess
+     */
+    message?: string | null;
+    /**
+     * 
+     * @type {SqlSugarPagedListSysOpenAccess}
+     * @memberof AdminResultSqlSugarPagedListSysOpenAccess
+     */
+    result?: SqlSugarPagedListSysOpenAccess;
+    /**
+     * 附加数据
+     * @type {any}
+     * @memberof AdminResultSqlSugarPagedListSysOpenAccess
+     */
+    extras?: any | null;
+    /**
+     * 时间
+     * @type {Date}
+     * @memberof AdminResultSqlSugarPagedListSysOpenAccess
+     */
+    time?: Date;
+}

+ 26 - 0
Web/src/api-services/models/delete-open-access-input.ts

@@ -0,0 +1,26 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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 DeleteOpenAccessInput
+ */
+export interface DeleteOpenAccessInput {
+    /**
+     * 主键Id
+     * @type {number}
+     * @memberof DeleteOpenAccessInput
+     */
+    id: number;
+}

+ 10 - 0
Web/src/api-services/models/index.ts

@@ -7,6 +7,7 @@ export * from './add-job-detail-input';
 export * from './add-job-trigger-input';
 export * from './add-menu-input';
 export * from './add-notice-input';
+export * from './add-open-access-input';
 export * from './add-org-input';
 export * from './add-plugin-input';
 export * from './add-pos-input';
@@ -46,12 +47,14 @@ export * from './admin-result-list-sys-notice';
 export * from './admin-result-list-sys-org';
 export * from './admin-result-list-sys-pos';
 export * from './admin-result-list-sys-region';
+export * from './admin-result-list-sys-user';
 export * from './admin-result-list-sys-user-ext-org';
 export * from './admin-result-list-table-output';
 export * from './admin-result-login-output';
 export * from './admin-result-login-user-output';
 export * from './admin-result-object';
 export * from './admin-result-sql-sugar-paged-list-job-output';
+export * from './admin-result-sql-sugar-paged-list-open-access-output';
 export * from './admin-result-sql-sugar-paged-list-sys-code-gen';
 export * from './admin-result-sql-sugar-paged-list-sys-config';
 export * from './admin-result-sql-sugar-paged-list-sys-dict-data';
@@ -113,6 +116,7 @@ export * from './delete-job-trigger-input';
 export * from './delete-menu-input';
 export * from './delete-message-template-input';
 export * from './delete-notice-input';
+export * from './delete-open-access-input';
 export * from './delete-org-input';
 export * from './delete-plugin-input';
 export * from './delete-pos-input';
@@ -151,6 +155,8 @@ export * from './notice-input';
 export * from './notice-status-enum';
 export * from './notice-type-enum';
 export * from './notice-user-status-enum';
+export * from './open-access-input';
+export * from './open-access-output';
 export * from './page-config-input';
 export * from './page-dict-data-input';
 export * from './page-dict-type-input';
@@ -174,6 +180,7 @@ export * from './role-output';
 export * from './send-subscribe-message-input';
 export * from './signature-input';
 export * from './sql-sugar-paged-list-job-output';
+export * from './sql-sugar-paged-list-open-access-output';
 export * from './sql-sugar-paged-list-sys-code-gen';
 export * from './sql-sugar-paged-list-sys-config';
 export * from './sql-sugar-paged-list-sys-dict-data';
@@ -223,11 +230,13 @@ export * from './sys-pos';
 export * from './sys-print';
 export * from './sys-region';
 export * from './sys-role';
+export * from './sys-tenant';
 export * from './sys-user';
 export * from './sys-user-ext-org';
 export * from './sys-wechat-pay';
 export * from './sys-wechat-user';
 export * from './table-output';
+export * from './tenant-id-input';
 export * from './tenant-input';
 export * from './tenant-output';
 export * from './tenant-type-enum';
@@ -243,6 +252,7 @@ export * from './update-job-detail-input';
 export * from './update-job-trigger-input';
 export * from './update-menu-input';
 export * from './update-notice-input';
+export * from './update-open-access-input';
 export * from './update-org-input';
 export * from './update-plugin-input';
 export * from './update-pos-input';

+ 6 - 0
Web/src/api-services/models/login-user-output.ts

@@ -17,6 +17,12 @@
  * @interface LoginUserOutput
  */
 export interface LoginUserOutput {
+    /**
+     * 用户id
+     * @type {number}
+     * @memberof LoginUserOutput
+     */
+    id?: number;
     /**
      * 账号名称
      * @type {string}

+ 56 - 0
Web/src/api-services/models/open-access-input.ts

@@ -0,0 +1,56 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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 OpenAccessInput
+ */
+export interface OpenAccessInput {
+    /**
+     * 当前页码
+     * @type {number}
+     * @memberof OpenAccessInput
+     */
+    page?: number;
+    /**
+     * 页码容量
+     * @type {number}
+     * @memberof OpenAccessInput
+     */
+    pageSize?: number;
+    /**
+     * 排序字段
+     * @type {string}
+     * @memberof OpenAccessInput
+     */
+    field?: string | null;
+    /**
+     * 排序方向
+     * @type {string}
+     * @memberof OpenAccessInput
+     */
+    order?: string | null;
+    /**
+     * 降序排序
+     * @type {string}
+     * @memberof OpenAccessInput
+     */
+    descStr?: string | null;
+    /**
+     * 身份标识
+     * @type {string}
+     * @memberof OpenAccessInput
+     */
+    accessKey?: string | null;
+}

+ 106 - 0
Web/src/api-services/models/open-access-output.ts

@@ -0,0 +1,106 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SysTenant } from './sys-tenant';
+import { SysUser } from './sys-user';
+/**
+ * 
+ * @export
+ * @interface OpenAccessOutput
+ */
+export interface OpenAccessOutput {
+    /**
+     * 雪花Id
+     * @type {number}
+     * @memberof OpenAccessOutput
+     */
+    id?: number;
+    /**
+     * 创建时间
+     * @type {Date}
+     * @memberof OpenAccessOutput
+     */
+    createTime?: Date | null;
+    /**
+     * 更新时间
+     * @type {Date}
+     * @memberof OpenAccessOutput
+     */
+    updateTime?: Date | null;
+    /**
+     * 创建者Id
+     * @type {number}
+     * @memberof OpenAccessOutput
+     */
+    createUserId?: number | null;
+    /**
+     * 修改者Id
+     * @type {number}
+     * @memberof OpenAccessOutput
+     */
+    updateUserId?: number | null;
+    /**
+     * 软删除
+     * @type {boolean}
+     * @memberof OpenAccessOutput
+     */
+    isDelete?: boolean;
+    /**
+     * 身份标识
+     * @type {string}
+     * @memberof OpenAccessOutput
+     */
+    accessKey?: string | null;
+    /**
+     * 密钥
+     * @type {string}
+     * @memberof OpenAccessOutput
+     */
+    accessSecret?: string | null;
+    /**
+     * 绑定用户Id
+     * @type {number}
+     * @memberof OpenAccessOutput
+     */
+    bindUserId?: number;
+    /**
+     * 
+     * @type {SysUser}
+     * @memberof OpenAccessOutput
+     */
+    bindUser?: SysUser;
+    /**
+     * 绑定租户Id
+     * @type {number}
+     * @memberof OpenAccessOutput
+     */
+    bindTenantId?: number;
+    /**
+     * 
+     * @type {SysTenant}
+     * @memberof OpenAccessOutput
+     */
+    bindTenant?: SysTenant;
+    /**
+     * 绑定用户账号
+     * @type {string}
+     * @memberof OpenAccessOutput
+     */
+    bindUserAccount?: string | null;
+    /**
+     * 绑定租户名称
+     * @type {string}
+     * @memberof OpenAccessOutput
+     */
+    bindTenantName?: string | null;
+}

+ 63 - 0
Web/src/api-services/models/sql-sugar-paged-list-open-access-output.ts

@@ -0,0 +1,63 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { OpenAccessOutput } from './open-access-output';
+/**
+ * 分页泛型集合
+ * @export
+ * @interface SqlSugarPagedListOpenAccessOutput
+ */
+export interface SqlSugarPagedListOpenAccessOutput {
+    /**
+     * 页码
+     * @type {number}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    page?: number;
+    /**
+     * 页容量
+     * @type {number}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    pageSize?: number;
+    /**
+     * 总条数
+     * @type {number}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    total?: number;
+    /**
+     * 总页数
+     * @type {number}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    totalPages?: number;
+    /**
+     * 当前页集合
+     * @type {Array<OpenAccessOutput>}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    items?: Array<OpenAccessOutput> | null;
+    /**
+     * 是否有上一页
+     * @type {boolean}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    hasPrevPage?: boolean;
+    /**
+     * 是否有下一页
+     * @type {boolean}
+     * @memberof SqlSugarPagedListOpenAccessOutput
+     */
+    hasNextPage?: boolean;
+}

+ 63 - 0
Web/src/api-services/models/sql-sugar-paged-list-sys-open-access.ts

@@ -0,0 +1,63 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SysOpenAccess } from './sys-open-access';
+/**
+ * 分页泛型集合
+ * @export
+ * @interface SqlSugarPagedListSysOpenAccess
+ */
+export interface SqlSugarPagedListSysOpenAccess {
+    /**
+     * 页码
+     * @type {number}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    page?: number;
+    /**
+     * 页容量
+     * @type {number}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    pageSize?: number;
+    /**
+     * 总条数
+     * @type {number}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    total?: number;
+    /**
+     * 总页数
+     * @type {number}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    totalPages?: number;
+    /**
+     * 当前页集合
+     * @type {Array<SysOpenAccess>}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    items?: Array<SysOpenAccess> | null;
+    /**
+     * 是否有上一页
+     * @type {boolean}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    hasPrevPage?: boolean;
+    /**
+     * 是否有下一页
+     * @type {boolean}
+     * @memberof SqlSugarPagedListSysOpenAccess
+     */
+    hasNextPage?: boolean;
+}

+ 7 - 0
Web/src/api-services/models/sys-dict-type.ts

@@ -12,6 +12,7 @@
  * Do not edit the class manually.
  */
 import { StatusEnum } from './status-enum';
+import { SysDictData } from './sys-dict-data';
 /**
  * 系统字典类型表
  * @export
@@ -84,4 +85,10 @@ export interface SysDictType {
      * @memberof SysDictType
      */
     status?: StatusEnum;
+    /**
+     * 字典值集合
+     * @type {Array<SysDictData>}
+     * @memberof SysDictType
+     */
+    children?: Array<SysDictData> | null;
 }

+ 81 - 0
Web/src/api-services/models/sys-open-access.ts

@@ -0,0 +1,81 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SysUser } from './sys-user';
+/**
+ * 开放接口身份表
+ * @export
+ * @interface SysOpenAccess
+ */
+export interface SysOpenAccess {
+    /**
+     * 雪花Id
+     * @type {number}
+     * @memberof SysOpenAccess
+     */
+    id?: number;
+    /**
+     * 创建时间
+     * @type {Date}
+     * @memberof SysOpenAccess
+     */
+    createTime?: Date | null;
+    /**
+     * 更新时间
+     * @type {Date}
+     * @memberof SysOpenAccess
+     */
+    updateTime?: Date | null;
+    /**
+     * 创建者Id
+     * @type {number}
+     * @memberof SysOpenAccess
+     */
+    createUserId?: number | null;
+    /**
+     * 修改者Id
+     * @type {number}
+     * @memberof SysOpenAccess
+     */
+    updateUserId?: number | null;
+    /**
+     * 软删除
+     * @type {boolean}
+     * @memberof SysOpenAccess
+     */
+    isDelete?: boolean;
+    /**
+     * 身份标识
+     * @type {string}
+     * @memberof SysOpenAccess
+     */
+    accessKey?: string | null;
+    /**
+     * 密钥
+     * @type {string}
+     * @memberof SysOpenAccess
+     */
+    accessSecret?: string | null;
+    /**
+     * 绑定用户Id
+     * @type {number}
+     * @memberof SysOpenAccess
+     */
+    bindUserId?: number;
+    /**
+     * 
+     * @type {SysUser}
+     * @memberof SysOpenAccess
+     */
+    bindUser?: SysUser;
+}

+ 119 - 0
Web/src/api-services/models/sys-tenant.ts

@@ -0,0 +1,119 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { DbType } from './db-type';
+import { StatusEnum } from './status-enum';
+import { TenantTypeEnum } from './tenant-type-enum';
+/**
+ * 系统租户表
+ * @export
+ * @interface SysTenant
+ */
+export interface SysTenant {
+    /**
+     * 雪花Id
+     * @type {number}
+     * @memberof SysTenant
+     */
+    id?: number;
+    /**
+     * 创建时间
+     * @type {Date}
+     * @memberof SysTenant
+     */
+    createTime?: Date | null;
+    /**
+     * 更新时间
+     * @type {Date}
+     * @memberof SysTenant
+     */
+    updateTime?: Date | null;
+    /**
+     * 创建者Id
+     * @type {number}
+     * @memberof SysTenant
+     */
+    createUserId?: number | null;
+    /**
+     * 修改者Id
+     * @type {number}
+     * @memberof SysTenant
+     */
+    updateUserId?: number | null;
+    /**
+     * 软删除
+     * @type {boolean}
+     * @memberof SysTenant
+     */
+    isDelete?: boolean;
+    /**
+     * 用户Id
+     * @type {number}
+     * @memberof SysTenant
+     */
+    userId?: number;
+    /**
+     * 机构Id
+     * @type {number}
+     * @memberof SysTenant
+     */
+    orgId?: number;
+    /**
+     * 主机
+     * @type {string}
+     * @memberof SysTenant
+     */
+    host?: string | null;
+    /**
+     * 
+     * @type {TenantTypeEnum}
+     * @memberof SysTenant
+     */
+    tenantType?: TenantTypeEnum;
+    /**
+     * 
+     * @type {DbType}
+     * @memberof SysTenant
+     */
+    dbType?: DbType;
+    /**
+     * 数据库连接
+     * @type {string}
+     * @memberof SysTenant
+     */
+    connection?: string | null;
+    /**
+     * 数据库标识
+     * @type {string}
+     * @memberof SysTenant
+     */
+    configId?: string | null;
+    /**
+     * 排序
+     * @type {number}
+     * @memberof SysTenant
+     */
+    orderNo?: number;
+    /**
+     * 备注
+     * @type {string}
+     * @memberof SysTenant
+     */
+    remark?: string | null;
+    /**
+     * 
+     * @type {StatusEnum}
+     * @memberof SysTenant
+     */
+    status?: StatusEnum;
+}

+ 26 - 0
Web/src/api-services/models/tenant-id-input.ts

@@ -0,0 +1,26 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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 TenantIdInput
+ */
+export interface TenantIdInput {
+    /**
+     * 租户Id
+     * @type {number}
+     * @memberof TenantIdInput
+     */
+    tenantId?: number;
+}

+ 7 - 0
Web/src/api-services/models/update-dict-type-input.ts

@@ -12,6 +12,7 @@
  * Do not edit the class manually.
  */
 import { StatusEnum } from './status-enum';
+import { SysDictData } from './sys-dict-data';
 /**
  * 
  * @export
@@ -84,4 +85,10 @@ export interface UpdateDictTypeInput {
      * @memberof UpdateDictTypeInput
      */
     status?: StatusEnum;
+    /**
+     * 字典值集合
+     * @type {Array<SysDictData>}
+     * @memberof UpdateDictTypeInput
+     */
+    children?: Array<SysDictData> | null;
 }

+ 94 - 0
Web/src/api-services/models/update-open-access-input.ts

@@ -0,0 +1,94 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * 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.
+ */
+import { SysTenant } from './sys-tenant';
+import { SysUser } from './sys-user';
+/**
+ * 
+ * @export
+ * @interface UpdateOpenAccessInput
+ */
+export interface UpdateOpenAccessInput {
+    /**
+     * 雪花Id
+     * @type {number}
+     * @memberof UpdateOpenAccessInput
+     */
+    id?: number;
+    /**
+     * 创建时间
+     * @type {Date}
+     * @memberof UpdateOpenAccessInput
+     */
+    createTime?: Date | null;
+    /**
+     * 更新时间
+     * @type {Date}
+     * @memberof UpdateOpenAccessInput
+     */
+    updateTime?: Date | null;
+    /**
+     * 创建者Id
+     * @type {number}
+     * @memberof UpdateOpenAccessInput
+     */
+    createUserId?: number | null;
+    /**
+     * 修改者Id
+     * @type {number}
+     * @memberof UpdateOpenAccessInput
+     */
+    updateUserId?: number | null;
+    /**
+     * 软删除
+     * @type {boolean}
+     * @memberof UpdateOpenAccessInput
+     */
+    isDelete?: boolean;
+    /**
+     * 
+     * @type {SysUser}
+     * @memberof UpdateOpenAccessInput
+     */
+    bindUser?: SysUser;
+    /**
+     * 绑定租户Id
+     * @type {number}
+     * @memberof UpdateOpenAccessInput
+     */
+    bindTenantId?: number;
+    /**
+     * 
+     * @type {SysTenant}
+     * @memberof UpdateOpenAccessInput
+     */
+    bindTenant?: SysTenant;
+    /**
+     * 身份标识
+     * @type {string}
+     * @memberof UpdateOpenAccessInput
+     */
+    accessKey: string;
+    /**
+     * 密钥
+     * @type {string}
+     * @memberof UpdateOpenAccessInput
+     */
+    accessSecret: string;
+    /**
+     * 绑定用户Id
+     * @type {number}
+     * @memberof UpdateOpenAccessInput
+     */
+    bindUserId: number;
+}

+ 123 - 0
Web/src/views/system/openAccess/component/editOpenAccess.vue

@@ -0,0 +1,123 @@
+<template>
+	<div class="sys-notice-container">
+		<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="600px">
+			<template #header>
+				<div style="color: #fff">
+					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
+					<span> {{ props.title }} </span>
+				</div>
+			</template>
+			<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
+				<el-row :gutter="35">
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+						<el-form-item label="身份标识" prop="accessKey" :rules="[{ required: true, message: '身份标识不能为空', trigger: 'blur' }]">
+							<el-input v-model="state.ruleForm.accessKey" placeholder="身份标识" clearable />
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+						<el-form-item label="密钥" prop="accessSecret" :rules="[{ required: true, message: '密钥不能为空', trigger: 'blur' }]">
+							<el-input v-model="state.ruleForm.accessSecret" placeholder="密钥" clearable>
+								<template #append>
+									<el-button @click="createSecret">生成密钥</el-button>
+								</template>
+							</el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+						<el-form-item label="绑定租户" prop="bindTenantId" :rules="[{ required: true, message: '绑定租户不能为空', trigger: 'blur' }]">
+							<el-select v-model="state.ruleForm.bindTenantId" placeholder="绑定租户" filterable default-first-option style="width: 100%" @change="tenantChange">
+								<el-option v-for="item in state.tenantData" :key="item.id" :label="item.name" :value="item.id" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+						<el-form-item label="绑定用户" prop="bindUserId" :rules="[{ required: true, message: '绑定用户不能为空', trigger: 'blur' }]">
+							<el-select v-model="state.ruleForm.bindUserId" placeholder="绑定用户" filterable default-first-option style="width: 100%">
+								<el-option v-for="item in state.userData" :key="item.id" :label="`${item.account}(${item.realName})`" :value="item.id" />
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="cancel">取 消</el-button>
+					<el-button type="primary" @click="submit">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts" setup name="sysNoticeEdit">
+import { onMounted, reactive, ref } from 'vue';
+
+import { getAPI } from '/@/utils/axios-utils';
+import { SysOpenAccessApi, SysTenantApi } from '/@/api-services/api';
+import { SysUser, TenantOutput, UpdateOpenAccessInput } from '/@/api-services/models';
+
+const props = defineProps({
+	title: String,
+});
+const emits = defineEmits(['handleQuery']);
+const ruleFormRef = ref();
+const state = reactive({
+	isShowDialog: false,
+	ruleForm: {} as UpdateOpenAccessInput,
+	tenantData: [] as Array<TenantOutput>, // 租户数据
+	userData: [] as Array<SysUser>, // 用户数据
+});
+
+onMounted(async () => {
+	var res = await getAPI(SysTenantApi).apiSysTenantPagePost({ page: 1, pageSize: 10000 });
+	state.tenantData = res.data.result?.items ?? [];
+});
+
+// 打开弹窗
+const openDialog = (row: any) => {
+	state.ruleForm = JSON.parse(JSON.stringify(row));
+	state.isShowDialog = true;
+	ruleFormRef.value?.resetFields();
+
+	tenantChange();
+};
+
+// 关闭弹窗
+const closeDialog = () => {
+	emits('handleQuery');
+	state.isShowDialog = false;
+};
+
+// 取消
+const cancel = () => {
+	state.isShowDialog = false;
+};
+
+// 提交
+const submit = () => {
+	ruleFormRef.value.validate(async (valid: boolean) => {
+		if (!valid) return;
+		if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
+			await getAPI(SysOpenAccessApi).apiSysOpenAccessUpdatePost(state.ruleForm);
+		} else {
+			await getAPI(SysOpenAccessApi).apiSysOpenAccessAddPost(state.ruleForm);
+		}
+		closeDialog();
+	});
+};
+
+/** 租户值变更 */
+const tenantChange = async () => {
+	var res = await getAPI(SysTenantApi).apiSysTenantUserListPost({ tenantId: state.ruleForm.bindTenantId ?? 0 });
+	state.userData = res.data.result ?? [];
+};
+
+/** 生成密钥 */
+const createSecret = async () => {
+	var res = await getAPI(SysOpenAccessApi).apiSysOpenAccessSecretPost();
+	state.ruleForm.accessSecret = res.data.result!;
+};
+
+// 导出对象
+defineExpose({ openDialog });
+</script>

+ 134 - 0
Web/src/views/system/openAccess/index.vue

@@ -0,0 +1,134 @@
+<template>
+	<div class="sys-open-access-container">
+		<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
+			<el-form :model="state.queryParams" ref="queryForm" :inline="true">
+				<el-form-item label="身份标识">
+					<el-input v-model="state.queryParams.accessKey" placeholder="身份标识" clearable />
+				</el-form-item>
+				<el-form-item>
+					<el-button-group>
+						<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysOpenAccess:page'"> 查询 </el-button>
+						<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
+					</el-button-group>
+				</el-form-item>
+				<el-form-item>
+					<el-button type="primary" icon="ele-Plus" @click="openAddOpenAccess" v-auth="'sysOpenAccess:add'"> 新增 </el-button>
+				</el-form-item>
+			</el-form>
+		</el-card>
+
+		<el-card class="full-table" shadow="hover" style="margin-top: 8px">
+			<el-table :data="state.openAccessData" style="width: 100%" v-loading="state.loading" border>
+				<el-table-column type="index" label="序号" width="55" align="center" />
+				<el-table-column prop="accessKey" label="身份标识" header-align="center" show-overflow-tooltip />
+				<el-table-column prop="accessSecret" label="密钥" header-align="center" show-overflow-tooltip />
+				<el-table-column prop="bindUserAccount" label="绑定用户账号" header-align="center" show-overflow-tooltip />
+				<el-table-column prop="bindTenantName" label="绑定租户名称" header-align="center" show-overflow-tooltip />
+				<el-table-column prop="createTime" label="创建时间" align="center" show-overflow-tooltip />
+				<el-table-column label="操作" width="200" fixed="right" align="center" show-overflow-tooltip>
+					<template #default="scope">
+						<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditOpenAccess(scope.row)" v-auth="'sysOpenAccess:update'" :disabled="scope.row.status === 1"> 编辑 </el-button>
+						<el-button icon="ele-Delete" size="small" text type="danger" @click="delOpenAccess(scope.row)" v-auth="'sysOpenAccess:delete'" :disabled="scope.row.status === 1"> 删除 </el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			<el-pagination
+				v-model:currentPage="state.tableParams.page"
+				v-model:page-size="state.tableParams.pageSize"
+				:total="state.tableParams.total"
+				:page-sizes="[10, 20, 50, 100]"
+				small
+				background
+				@size-change="handleSizeChange"
+				@current-change="handleCurrentChange"
+				layout="total, sizes, prev, pager, next, jumper"
+			/>
+		</el-card>
+
+		<EditOpenAccess ref="editOpenAccessRef" :title="state.editOpenAccessTitle" @handleQuery="handleQuery" />
+	</div>
+</template>
+
+<script lang="ts" setup name="sysNotice">
+import { onMounted, reactive, ref } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import EditOpenAccess from '/@/views/system/openAccess/component/editOpenAccess.vue';
+
+import { getAPI } from '/@/utils/axios-utils';
+import { SysOpenAccessApi } from '/@/api-services/api';
+import { SysOpenAccess } from '/@/api-services/models';
+
+const editOpenAccessRef = ref<InstanceType<typeof EditOpenAccess>>();
+const state = reactive({
+	loading: false,
+	openAccessData: [] as Array<SysOpenAccess>,
+	queryParams: {
+		accessKey: undefined,
+	},
+	tableParams: {
+		page: 1,
+		pageSize: 20,
+		total: 0 as any,
+	},
+	editOpenAccessTitle: '',
+});
+
+onMounted(async () => {
+	handleQuery();
+});
+
+// 查询操作
+const handleQuery = async () => {
+	state.loading = true;
+	let params = Object.assign(state.queryParams, state.tableParams);
+	var res = await getAPI(SysOpenAccessApi).apiSysOpenAccessPagePost(params);
+	state.openAccessData = res.data.result?.items ?? [];
+	state.tableParams.total = res.data.result?.total;
+	state.loading = false;
+};
+
+// 重置操作
+const resetQuery = () => {
+	state.queryParams.accessKey = undefined;
+	handleQuery();
+};
+
+// 打开新增页面
+const openAddOpenAccess = () => {
+	state.editOpenAccessTitle = '添加开放接口身份';
+	editOpenAccessRef.value?.openDialog({ type: 1 });
+};
+
+// 打开编辑页面
+const openEditOpenAccess = (row: any) => {
+	state.editOpenAccessTitle = '编辑开放接口身份';
+	editOpenAccessRef.value?.openDialog(row);
+};
+
+// 删除
+const delOpenAccess = (row: any) => {
+	ElMessageBox.confirm(`确定删除开放接口身份:【${row.accessKey}】?`, '提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(async () => {
+			await getAPI(SysOpenAccessApi).apiSysOpenAccessDeletePost({ id: row.id });
+			handleQuery();
+			ElMessage.success('删除成功');
+		})
+		.catch(() => {});
+};
+
+// 改变页面容量
+const handleSizeChange = (val: number) => {
+	state.tableParams.pageSize = val;
+	handleQuery();
+};
+
+// 改变页码序号
+const handleCurrentChange = (val: number) => {
+	state.tableParams.page = val;
+	handleQuery();
+};
+</script>