Procházet zdrojové kódy

完善角色菜单授权

zuohuaijun před 3 roky
rodič
revize
b43b26a38e

+ 1 - 1
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -36,7 +36,7 @@
     <PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.1.8" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.17.0" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.13.1" />
-    <PackageReference Include="SqlSugarCore" Version="5.1.3.25-preview01" />
+    <PackageReference Include="SqlSugarCore" Version="5.1.3.25" />
     <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.20" />
     <PackageReference Include="UAParser" Version="3.1.47" />
     <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />

+ 53 - 5
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -6031,6 +6031,11 @@
             名称
             </summary>
         </member>
+        <member name="P:Admin.NET.Core.Service.AddRoleInput.MenuIdList">
+            <summary>
+            菜单Id集合
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.Service.RoleMenuInput">
             <summary>
             授权角色菜单
@@ -6041,6 +6046,21 @@
             菜单Id集合
             </summary>
         </member>
+        <member name="T:Admin.NET.Core.Service.RoleMenuOutput">
+            <summary>
+            角色菜单输出参数
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.RoleMenuOutput.Id">
+            <summary>
+            Id
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.RoleMenuOutput.Title">
+            <summary>
+            名称
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.Service.RoleOrgInput">
             <summary>
             授权角色机构
@@ -6088,13 +6108,20 @@
             <param name="roleIdList"></param>
             <returns></returns>
         </member>
-        <member name="M:Admin.NET.Core.Service.SysRoleMenuService.GetRoleMenu(System.Collections.Generic.List{System.Int64})">
+        <member name="M:Admin.NET.Core.Service.SysRoleMenuService.GetRoleMenuTree(System.Collections.Generic.List{System.Int64})">
             <summary>
             根据角色Id集合获取菜单树
             </summary>
             <param name="roleIdList"></param>
             <returns></returns>
         </member>
+        <member name="M:Admin.NET.Core.Service.SysRoleMenuService.GetRoleMenuList(System.Collections.Generic.List{System.Int64})">
+            <summary>
+            根据角色Id集合获取菜单集合
+            </summary>
+            <param name="roleIdList"></param>
+            <returns></returns>
+        </member>
         <member name="M:Admin.NET.Core.Service.SysRoleMenuService.GrantRoleMenu(Admin.NET.Core.Service.RoleMenuInput)">
             <summary>
             授权角色菜单
@@ -6174,6 +6201,13 @@
             <param name="input"></param>
             <returns></returns>
         </member>
+        <member name="M:Admin.NET.Core.Service.SysRoleService.UpdateRoleMenu(Admin.NET.Core.Service.AddRoleInput)">
+            <summary>
+            更新角色菜单权限
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
         <member name="M:Admin.NET.Core.Service.SysRoleService.UpdateRole(Admin.NET.Core.Service.UpdateRoleInput)">
             <summary>
             更新角色
@@ -6202,9 +6236,16 @@
             <param name="input"></param>
             <returns></returns>
         </member>
-        <member name="M:Admin.NET.Core.Service.SysRoleService.GetRoleOwnMenu(Admin.NET.Core.Service.RoleInput)">
+        <member name="M:Admin.NET.Core.Service.SysRoleService.GetRoleOwnMenuTree(Admin.NET.Core.Service.RoleInput)">
             <summary>
-            根据角色Id获取菜单树(前端区分父子节点)
+            根据角色Id获取菜单树(Antd)
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.SysRoleService.GetRoleOwnMenuList(Admin.NET.Core.Service.RoleInput)">
+            <summary>
+            根据角色Id获取菜单集合(Element)
             </summary>
             <param name="input"></param>
             <returns></returns>
@@ -6380,9 +6421,16 @@
             <param name="input"></param>
             <returns></returns>
         </member>
-        <member name="M:Admin.NET.Core.Service.SysTenantService.OwnMenu(Admin.NET.Core.Service.QueryeTenantInput)">
+        <member name="M:Admin.NET.Core.Service.SysTenantService.OwnMenuTree(Admin.NET.Core.Service.QueryeTenantInput)">
+            <summary>
+            获取租户管理员角色拥有菜单树
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.SysTenantService.OwnMenuList(Admin.NET.Core.Service.QueryeTenantInput)">
             <summary>
-            获取租户管理员角色拥有菜单Id集合
+            获取租户管理员角色拥有菜单
             </summary>
             <param name="input"></param>
             <returns></returns>

+ 5 - 0
Admin.NET/Admin.NET.Core/Service/Role/Dto/RoleInput.cs

@@ -29,6 +29,11 @@ public class AddRoleInput : SysRole
     /// </summary>
     [Required(ErrorMessage = "角色名称不能为空")]
     public override string Name { get; set; }
+
+    /// <summary>
+    /// 菜单Id集合
+    /// </summary>
+    public List<long> MenuIdList { get; set; }
 }
 
 [NotTable]

+ 17 - 0
Admin.NET/Admin.NET.Core/Service/Role/Dto/RoleMenuOutput .cs

@@ -0,0 +1,17 @@
+namespace Admin.NET.Core.Service;
+
+/// <summary>
+/// 角色菜单输出参数
+/// </summary>
+public class RoleMenuOutput
+{
+    /// <summary>
+    /// Id
+    /// </summary>
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 名称
+    /// </summary>
+    public string Title { get; set; }
+}

+ 17 - 1
Admin.NET/Admin.NET.Core/Service/Role/SysRoleMenuService.cs

@@ -32,7 +32,7 @@ public class SysRoleMenuService : ITransient
     /// </summary>
     /// <param name="roleIdList"></param>
     /// <returns></returns>
-    public async Task<List<SysMenu>> GetRoleMenu(List<long> roleIdList)
+    public async Task<List<SysMenu>> GetRoleMenuTree(List<long> roleIdList)
     {
         var menuIdList = await _sysRoleMenuRep.AsQueryable()
             .Where(u => roleIdList.Contains(u.RoleId))
@@ -43,6 +43,22 @@ public class SysRoleMenuService : ITransient
             .ToTreeAsync(u => u.Children, u => u.Pid, 0);
     }
 
+    /// <summary>
+    /// 根据角色Id集合获取菜单集合
+    /// </summary>
+    /// <param name="roleIdList"></param>
+    /// <returns></returns>
+    public async Task<List<long>> GetRoleMenuList(List<long> roleIdList)
+    {
+        var menuIdList = await _sysRoleMenuRep.AsQueryable()
+            .Where(u => roleIdList.Contains(u.RoleId))
+            .Select(u => u.MenuId).ToListAsync();
+
+        return await _sysRoleMenuRep.ChangeRepository<SqlSugarRepository<SysMenu>>().AsQueryable()
+            .Where(u => menuIdList.Contains(u.Id))
+            .Select(u => u.Id).ToListAsync();
+    }
+
     /// <summary>
     /// 授权角色菜单
     /// </summary>

+ 36 - 4
Admin.NET/Admin.NET.Core/Service/Role/SysRoleService.cs

@@ -74,7 +74,26 @@ public class SysRoleService : IDynamicApiController, ITransient
         if (isExist)
             throw Oops.Oh(ErrorCodeEnum.D1006);
 
-        await _sysRoleRep.InsertAsync(input.Adapt<SysRole>());
+        input.Id = (await _sysRoleRep.AsInsertable(input.Adapt<SysRole>()).ExecuteReturnEntityAsync()).Id;
+
+        await UpdateRoleMenu(input);
+    }
+
+    /// <summary>
+    /// 更新角色菜单权限
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    private async Task UpdateRoleMenu(AddRoleInput input)
+    {
+        // 更新角色菜单权限集合
+        if (input.MenuIdList == null || input.MenuIdList.Count < 1)
+            return;
+        await GrantRoleMenu(new RoleMenuInput()
+        {
+            Id = input.Id,
+            MenuIdList = input.MenuIdList
+        });
     }
 
     /// <summary>
@@ -95,6 +114,8 @@ public class SysRoleService : IDynamicApiController, ITransient
 
         await _sysRoleRep.AsUpdateable(input.Adapt<SysRole>()).IgnoreColumns(true)
             .IgnoreColumns(u => new { u.DataScope }).ExecuteCommandAsync();
+
+        await UpdateRoleMenu(input);
     }
 
     /// <summary>
@@ -176,14 +197,25 @@ public class SysRoleService : IDynamicApiController, ITransient
     }
 
     /// <summary>
-    /// 根据角色Id获取菜单树(前端区分父子节点)
+    /// 根据角色Id获取菜单树(Antd)
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
     [HttpGet("/sysRole/ownMenu")]
-    public async Task<List<SysMenu>> GetRoleOwnMenu([FromQuery] RoleInput input)
+    public async Task<List<SysMenu>> GetRoleOwnMenuTree([FromQuery] RoleInput input)
+    {
+        return await _sysRoleMenuService.GetRoleMenuTree(new List<long> { input.Id });
+    }
+
+    /// <summary>
+    /// 根据角色Id获取菜单集合(Element)
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpGet("/sysRole/ownMenuList")]
+    public async Task<List<long>> GetRoleOwnMenuList([FromQuery] RoleInput input)
     {
-        return await _sysRoleMenuService.GetRoleMenu(new List<long> { input.Id });
+        return await _sysRoleMenuService.GetRoleMenuList(new List<long> { input.Id });
     }
 
     /// <summary>

+ 18 - 3
Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs

@@ -231,18 +231,33 @@ public class SysTenantService : IDynamicApiController, ITransient
     }
 
     /// <summary>
-    /// 获取租户管理员角色拥有菜单Id集合
+    /// 获取租户管理员角色拥有菜单
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
     [HttpGet("/sysTenant/ownMenu")]
-    public async Task<List<SysMenu>> OwnMenu([FromQuery] QueryeTenantInput input)
+    public async Task<List<SysMenu>> OwnMenuTree([FromQuery] QueryeTenantInput input)
     {
         var tenantAdminUser = await GetTenantAdminUser(input.Id);
         if (tenantAdminUser == null) return new List<SysMenu>();
         var roleIds = await _sysUserRoleService.GetUserRoleIdList(tenantAdminUser.Id);
         var tenantAdminRoleId = roleIds[0]; // 租户管理员角色Id
-        return await _sysRoleMenuService.GetRoleMenu(new List<long> { tenantAdminRoleId });
+        return await _sysRoleMenuService.GetRoleMenuTree(new List<long> { tenantAdminRoleId });
+    }
+
+    /// <summary>
+    /// 获取租户管理员角色拥有菜单树
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpGet("/sysTenant/ownMenuList")]
+    public async Task<List<long>> OwnMenuList([FromQuery] QueryeTenantInput input)
+    {
+        var tenantAdminUser = await GetTenantAdminUser(input.Id);
+        if (tenantAdminUser == null) return new List<long>();
+        var roleIds = await _sysUserRoleService.GetUserRoleIdList(tenantAdminUser.Id);
+        var tenantAdminRoleId = roleIds[0]; // 租户管理员角色Id
+        return await _sysRoleMenuService.GetRoleMenuList(new List<long> { tenantAdminRoleId });
     }
 
     /// <summary>

+ 92 - 4
vue-next-admin/src/api-services/apis/sys-role-api.ts

@@ -236,7 +236,7 @@ export const SysRoleApiAxiosParamCreator = function (configuration?: Configurati
         },
         /**
          * 
-         * @summary 根据角色Id获取菜单树(前端区分父子节点)
+         * @summary 根据角色Id获取菜单树(Antd)
          * @param {number} id 主键Id
          * @param {StatusEnum} [status] 状态
          * @param {*} [options] Override http request option.
@@ -284,6 +284,56 @@ export const SysRoleApiAxiosParamCreator = function (configuration?: Configurati
                 options: localVarRequestOptions,
             };
         },
+        /**
+         * 
+         * @summary 根据角色Id获取菜单集合(Element)
+         * @param {number} id 主键Id
+         * @param {StatusEnum} [status] 状态
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        sysRoleOwnMenuListGet: async (id: number, status?: StatusEnum, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            // verify required parameter 'id' is not null or undefined
+            if (id === null || id === undefined) {
+                throw new RequiredError('id','Required parameter id was null or undefined when calling sysRoleOwnMenuListGet.');
+            }
+            const localVarPath = `/sysRole/ownMenuList`;
+            // 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
+
+            if (status !== undefined) {
+                localVarQueryParameter['Status'] = status;
+            }
+
+            if (id !== undefined) {
+                localVarQueryParameter['Id'] = id;
+            }
+
+            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 根据角色Id获取机构Id集合
@@ -567,7 +617,7 @@ export const SysRoleApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 根据角色Id获取菜单树(前端区分父子节点)
+         * @summary 根据角色Id获取菜单树(Antd)
          * @param {number} id 主键Id
          * @param {StatusEnum} [status] 状态
          * @param {*} [options] Override http request option.
@@ -580,6 +630,21 @@ export const SysRoleApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 根据角色Id获取菜单集合(Element)
+         * @param {number} id 主键Id
+         * @param {StatusEnum} [status] 状态
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async sysRoleOwnMenuListGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListInt64>>> {
+            const localVarAxiosArgs = await SysRoleApiAxiosParamCreator(configuration).sysRoleOwnMenuListGet(id, status, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 根据角色Id获取机构Id集合
@@ -703,7 +768,7 @@ export const SysRoleApiFactory = function (configuration?: Configuration, basePa
         },
         /**
          * 
-         * @summary 根据角色Id获取菜单树(前端区分父子节点)
+         * @summary 根据角色Id获取菜单树(Antd)
          * @param {number} id 主键Id
          * @param {StatusEnum} [status] 状态
          * @param {*} [options] Override http request option.
@@ -712,6 +777,17 @@ export const SysRoleApiFactory = function (configuration?: Configuration, basePa
         async sysRoleOwnMenuGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysMenu>> {
             return SysRoleApiFp(configuration).sysRoleOwnMenuGet(id, status, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 根据角色Id获取菜单集合(Element)
+         * @param {number} id 主键Id
+         * @param {StatusEnum} [status] 状态
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async sysRoleOwnMenuListGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListInt64>> {
+            return SysRoleApiFp(configuration).sysRoleOwnMenuListGet(id, status, options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 根据角色Id获取机构Id集合
@@ -825,7 +901,7 @@ export class SysRoleApi extends BaseAPI {
     }
     /**
      * 
-     * @summary 根据角色Id获取菜单树(前端区分父子节点)
+     * @summary 根据角色Id获取菜单树(Antd)
      * @param {number} id 主键Id
      * @param {StatusEnum} [status] 状态
      * @param {*} [options] Override http request option.
@@ -835,6 +911,18 @@ export class SysRoleApi extends BaseAPI {
     public async sysRoleOwnMenuGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysMenu>> {
         return SysRoleApiFp(this.configuration).sysRoleOwnMenuGet(id, status, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 根据角色Id获取菜单集合(Element)
+     * @param {number} id 主键Id
+     * @param {StatusEnum} [status] 状态
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysRoleApi
+     */
+    public async sysRoleOwnMenuListGet(id: number, status?: StatusEnum, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListInt64>> {
+        return SysRoleApiFp(this.configuration).sysRoleOwnMenuListGet(id, status, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 根据角色Id获取机构Id集合

+ 85 - 4
vue-next-admin/src/api-services/apis/sys-tenant-api.ts

@@ -17,6 +17,7 @@ import { Configuration } from '../configuration';
 // @ts-ignore
 import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
 import { AddTenantInput } from '../models';
+import { AdminResultListInt64 } from '../models';
 import { AdminResultListSysMenu } from '../models';
 import { AdminResultObject } from '../models';
 import { AdminResultSysTenant } from '../models';
@@ -277,7 +278,7 @@ export const SysTenantApiAxiosParamCreator = function (configuration?: Configura
         },
         /**
          * 
-         * @summary 获取租户管理员角色拥有菜单Id集合
+         * @summary 获取租户管理员角色拥有菜单
          * @param {number} id Id
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -320,6 +321,51 @@ export const SysTenantApiAxiosParamCreator = function (configuration?: Configura
                 options: localVarRequestOptions,
             };
         },
+        /**
+         * 
+         * @summary 获取租户管理员角色拥有菜单树
+         * @param {number} id Id
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        sysTenantOwnMenuListGet: async (id: number, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            // verify required parameter 'id' is not null or undefined
+            if (id === null || id === undefined) {
+                throw new RequiredError('id','Required parameter id was null or undefined when calling sysTenantOwnMenuListGet.');
+            }
+            const localVarPath = `/sysTenant/ownMenuList`;
+            // 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
+
+            if (id !== undefined) {
+                localVarQueryParameter['Id'] = id;
+            }
+
+            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 获取租户分页列表
@@ -556,7 +602,7 @@ export const SysTenantApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 获取租户管理员角色拥有菜单Id集合
+         * @summary 获取租户管理员角色拥有菜单
          * @param {number} id Id
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -568,6 +614,20 @@ export const SysTenantApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 获取租户管理员角色拥有菜单树
+         * @param {number} id Id
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async sysTenantOwnMenuListGet(id: number, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListInt64>>> {
+            const localVarAxiosArgs = await SysTenantApiAxiosParamCreator(configuration).sysTenantOwnMenuListGet(id, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 获取租户分页列表
@@ -678,7 +738,7 @@ export const SysTenantApiFactory = function (configuration?: Configuration, base
         },
         /**
          * 
-         * @summary 获取租户管理员角色拥有菜单Id集合
+         * @summary 获取租户管理员角色拥有菜单
          * @param {number} id Id
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -686,6 +746,16 @@ export const SysTenantApiFactory = function (configuration?: Configuration, base
         async sysTenantOwnMenuGet(id: number, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysMenu>> {
             return SysTenantApiFp(configuration).sysTenantOwnMenuGet(id, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 获取租户管理员角色拥有菜单树
+         * @param {number} id Id
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async sysTenantOwnMenuListGet(id: number, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListInt64>> {
+            return SysTenantApiFp(configuration).sysTenantOwnMenuListGet(id, options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 获取租户分页列表
@@ -795,7 +865,7 @@ export class SysTenantApi extends BaseAPI {
     }
     /**
      * 
-     * @summary 获取租户管理员角色拥有菜单Id集合
+     * @summary 获取租户管理员角色拥有菜单
      * @param {number} id Id
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
@@ -804,6 +874,17 @@ export class SysTenantApi extends BaseAPI {
     public async sysTenantOwnMenuGet(id: number, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysMenu>> {
         return SysTenantApiFp(this.configuration).sysTenantOwnMenuGet(id, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 获取租户管理员角色拥有菜单树
+     * @param {number} id Id
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysTenantApi
+     */
+    public async sysTenantOwnMenuListGet(id: number, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListInt64>> {
+        return SysTenantApiFp(this.configuration).sysTenantOwnMenuListGet(id, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 获取租户分页列表

+ 3 - 5
vue-next-admin/src/views/system/menu/component/editMenu.vue

@@ -68,8 +68,7 @@
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 							<el-form-item label="菜单排序">
-								<el-input-number v-model="ruleForm.order" controls-position="right" placeholder="排序"
-									class="w100" />
+								<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
 							</el-form-item>
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -113,8 +112,7 @@
 						</el-col>
 						<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 							<el-form-item label="菜单排序">
-								<el-input-number v-model="ruleForm.order" controls-position="right" placeholder="排序"
-									class="w100" />
+								<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
 							</el-form-item>
 						</el-col>
 					</template>
@@ -158,7 +156,7 @@ export default defineComponent({
 		// 弹窗标题
 		title: {
 			type: String,
-			default: () => "",
+			default: "",
 		},
 		// 菜单数据
 		menuData: {

+ 2 - 3
vue-next-admin/src/views/system/org/component/editOrg.vue

@@ -31,8 +31,7 @@
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						<el-form-item label="排序">
-							<el-input-number v-model="ruleForm.order" controls-position="right" placeholder="排序"
-								class="w100" />
+							<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -74,7 +73,7 @@ export default defineComponent({
 		// 弹窗标题
 		title: {
 			type: String,
-			default: () => "",
+			default: "",
 		},
 		// 机构数据
 		orgData: {

+ 2 - 12
vue-next-admin/src/views/system/org/component/orgTree.vue

@@ -27,7 +27,7 @@
       </div>
     </template>
     <div style="margin-bottom: 45px" v-loading="state.loading">
-      <el-tree ref='treeRef' class='filter-tree' :data='state.orgData' :props='defaultProps'
+      <el-tree ref='treeRef' class='filter-tree' :data='state.orgData' :props="{children: 'children', label: 'name'}"
         :filter-node-method='filterNode' @node-click="nodeClick" />
     </div>
   </el-card>
@@ -41,18 +41,8 @@ import { Search, MoreFilled } from '@element-plus/icons-vue';
 import { getAPI } from '/@/utils/axios-utils';
 import { SysOrgApi } from '/@/api-services/api';
 
-interface Tree {
-  id: number;
-  name: string;
-  children?: Tree[];
-}
-
 const filterText = ref('');
 const treeRef = ref<InstanceType<typeof ElTree>>();
-const defaultProps = {
-  children: 'children',
-  label: 'name',
-};
 
 const state = reactive({
   loading: true,
@@ -74,7 +64,7 @@ const initTreeData = async () => {
   state.loading = false;
 };
 
-const filterNode = (value: string, data: Tree) => {
+const filterNode = (value: string, data: any) => {
   if (!value) return true;
   return data.name.includes(value);
 };

+ 2 - 3
vue-next-admin/src/views/system/pos/component/editPos.vue

@@ -20,8 +20,7 @@
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						<el-form-item label="排序">
-							<el-input-number v-model="ruleForm.order" controls-position="right" placeholder="排序"
-								class="w100" />
+							<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -63,7 +62,7 @@ export default defineComponent({
 		// 弹窗标题
 		title: {
 			type: String,
-			default: () => "",
+			default: "",
 		},
 	},
 	setup() {

+ 14 - 10
vue-next-admin/src/views/system/role/component/editRole.vue

@@ -20,8 +20,7 @@
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
 						<el-form-item label="排序">
-							<el-input-number v-model="ruleForm.order" controls-position="right" placeholder="排序"
-								class="w100" />
+							<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
@@ -42,7 +41,7 @@
 						<el-form-item label="菜单权限" v-loading="loading">
 							<el-tree ref="treeRef" :data="menuData" node-key="id" show-checkbox
 								:props="{ children: 'children', label: 'title', class: treeNodeClass }"
-								:default-checked-keys="ownMenuData" class="menu-data-tree" highlight-current
+								:default-checked-keys="ownMenuData" highlight-current class="menu-data-tree"
 								icon="ele-Menu" />
 						</el-form-item>
 					</el-col>
@@ -61,7 +60,7 @@
 
 <script lang="ts">
 import { reactive, toRefs, defineComponent, getCurrentInstance, ref, unref, onMounted } from 'vue';
-import { ElTree } from 'element-plus';
+import type { ElTree } from 'element-plus';
 import type Node from 'element-plus/es/components/tree/src/model/node'
 
 import { getAPI } from '/@/utils/axios-utils';
@@ -74,7 +73,12 @@ export default defineComponent({
 		// 弹窗标题
 		title: {
 			type: String,
-			default: () => "",
+			default: "",
+		},
+		// 拥有菜单集合
+		ownMenuData: {
+			type: Array,
+			default: () => [252885263003711],
 		},
 	},
 	setup() {
@@ -91,13 +95,13 @@ export default defineComponent({
 				order: 10, // 排序
 				status: 1, // 是否启用
 				remark: '', // 备注
+				menuIdList: [] as any, // 菜单权限
 			},
 			ruleRules: {
 				name: [{ required: true, message: "角色名称不能为空", trigger: "blur" }],
 				code: [{ required: true, message: "角色编码不能为空", trigger: "blur" }],
 			},
 			menuData: [] as any, // 菜单数据
-			ownMenuData: [] as any, // 拥有菜单
 		});
 		onMounted(async () => {
 			state.loading = true;
@@ -107,6 +111,7 @@ export default defineComponent({
 		});
 		// 打开弹窗
 		const openDialog = (row: any) => {
+			treeRef.value?.setCheckedKeys([]); // 先清空已选择节点
 			state.ruleForm = row;
 			state.isShowDialog = true;
 		};
@@ -125,6 +130,7 @@ export default defineComponent({
 			if (!formWrap) return;
 
 			formWrap.validate(async () => {
+				state.ruleForm.menuIdList = treeRef.value?.getCheckedKeys(); //.concat(treeRef.value?.getHalfCheckedKeys());
 				if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
 					await getAPI(SysRoleApi).sysRoleUpdatePost(state.ruleForm);
 				}
@@ -134,6 +140,7 @@ export default defineComponent({
 				closeDialog();
 			})
 		};
+		// 叶子节点同行显示样式
 		const treeNodeClass = (node: Node) => {
 			if (node.isLeaf) return '';
 			let addClass = true;
@@ -143,17 +150,14 @@ export default defineComponent({
 			}
 			return addClass ? 'penultimate-node' : '';
 		};
-		const getCheckeds = () => {
-			return treeRef.value!.getCheckedKeys().concat(treeRef.value!.getHalfCheckedKeys())
-		};
 		return {
 			ruleFormRef,
+			treeRef,
 			openDialog,
 			closeDialog,
 			cancel,
 			submit,
 			treeNodeClass,
-			getCheckeds,
 			...toRefs(state),
 		};
 	},

+ 7 - 2
vue-next-admin/src/views/system/role/index.vue

@@ -80,7 +80,7 @@
 				layout="total, sizes, prev, pager, next, jumper" />
 		</el-card>
 
-		<EditRole ref="editRoleRef" :title="editRoleTitle" />
+		<EditRole ref="editRoleRef" :title="editRoleTitle" :ownMenuData="ownMenuData" />
 	</div>
 </template>
 
@@ -112,6 +112,7 @@ export default defineComponent({
 				total: 0 as any,
 			},
 			editRoleTitle: "",
+			ownMenuData: [] as any,
 		});
 		onMounted(async () => {
 			handleQuery();
@@ -143,8 +144,12 @@ export default defineComponent({
 			editRoleRef.value.openDialog({});
 		};
 		// 打开编辑页面
-		const openEditRole = (row: any) => {
+		const openEditRole = async (row: any) => {
 			state.editRoleTitle = "编辑角色";
+			state.loading = true;
+			var res = await getAPI(SysRoleApi).sysRoleOwnMenuListGet(row.id);
+			state.ownMenuData = res.data.result;
+			state.loading = false;
 			editRoleRef.value.openDialog(row);
 		};
 		// 删除

+ 2 - 3
vue-next-admin/src/views/system/user/component/editUser.vue

@@ -54,8 +54,7 @@
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb5">
 						<el-form-item label="排序">
-							<el-input-number v-model="ruleForm.order" controls-position="right" placeholder="排序"
-								class="w100" />
+							<el-input-number v-model="ruleForm.order" placeholder="排序" class="w100" />
 						</el-form-item>
 					</el-col>
 					<el-divider border-style="dashed" content-position="center">
@@ -133,7 +132,7 @@ export default defineComponent({
 		// 弹窗标题
 		title: {
 			type: String,
-			default: () => "",
+			default: "",
 		},
 		// 机构数据
 		orgData: {