【.NET 8 实战--孢子记账--从单体到微服务】--简易权限--角色可访问接口管理

咱们继续来编写孢子记账的简易权限,这篇文章中我们将编写角色可访问接口的管理API,同样我不会把完整的代码全都列出来,只会列出部分代码,其余代码我希望大家能自己手动编写,然后对比项目代码。废话不多说,开讲。

一、需求

角色可访问接口的需求很简单,也就是简单的增删改查。

编号 功能 描述
1 新增 一个角色可绑定多个接口,但一个角色不能绑定同一个接口多次
2 删除 系统角色可访问的URL不可删除
3 修改 一个角色不能绑定同一个接口多次
4 查询 可根据角色名、接口地址进行模糊查询,实现分页功能
5 查询 根据角色可访问接口Id查询单个数据

二、编写代码

2.1 编写数据库映射类并迁移数据库
  1. 新增SysRoleUrl类,代码如下:

    csharp 复制代码
    using SporeAccounting.BaseModels;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace SporeAccounting.Models;
    /// <summary>
    /// 角色可访问的URL
    /// </summary>
    [Table(name: "SysRoleUrl")]
    public class SysRoleUrl : BaseModel
    {
        /// <summary>
        /// 角色Id
        /// </summary>
        [Column(TypeName = "nvarchar(36)")]
        [Required]
        [ForeignKey("FK_SysRoleUrl_SysRole")]
        public string RoleId { get; set; }
        /// <summary>
        /// 接口路径
        /// </summary>
        [Column(TypeName = "nvarchar(36)")]
        [Required]
        [ForeignKey("FK_SysRoleUrl_SysUrl")]
        public string UrlId { get; set; }
    
        /// <summary>
        /// 导航属性
        /// </summary>
        public SysRole Role { get; set; }
        /// <summary>
        /// 导航属性
        /// </summary>
        public SysUrl Url { get; set; }
    }
  2. 在数据库链接上下文类SporeAccountingDBContext1中增加SysRoleUrl

    csharp 复制代码
    /// <summary>
    /// 接口URL表
    /// </summary>
    public DbSet<SysUrl> SysUrls { get; set; }
  3. SysRole类中增加SysRoleUrl的导航属性:

    csharp 复制代码
    /// <summary>
    /// SysRoleUrl导航属性
    /// </summary>
    public ICollection<SysRoleUrl> RoleUrls { get; set; }
  4. 迁移数据库,迁移后的数据库如下图

2.2 编写业务逻辑

我们以删除为例,来看一下角色可访问接口如何编写。

  1. 新建服务接口ISysRoleUrlServer及其实现类SysRoleUrlImp

  2. 在接口及其实现类中增加Delete方法

    csharp 复制代码
    //ISysRoleUrlServer
    /// <summary>
    /// 删除角色可访问的URL
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="urlId"></param>
    void Delete(string roleId, string urlId);
    
    //SysRoleUrlImp
    /// <summary>
    /// 删除角色可访问的URL
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="urlId"></param>
    public void Delete(string roleId, string urlId)
    {
        try
        {
            SysRoleUrl roleUrl = _dbContext.SysRoleUrls.
                FirstOrDefault(x => x.RoleId == roleId && x.UrlId == urlId);
            if (roleUrl != null)
            {
                _dbContext.SysRoleUrls.Remove(roleUrl);
                _dbContext.SaveChanges();
            }
        }
        catch (Exception e)
        {
            throw;
        }
    }
  3. 新建SysRoleUrlController ,并实现Delete方法

    csharp 复制代码
    using AutoMapper;
    using Microsoft.AspNetCore.Mvc;
    using SporeAccounting.BaseModels;
    using SporeAccounting.BaseModels.ViewModel.Response;
    using SporeAccounting.Models;
    using SporeAccounting.Models.ViewModels;
    using SporeAccounting.Server.Interface;
    using System.Net;
    
    namespace SporeAccounting.Controllers
    {
        /// <summary>
        /// 角色可访问URL
        /// </summary>
        [Route("api/[controller]")]
        [ApiController]
        public class SysRoleUrlController : ControllerBase
        {
            private readonly ISysRoleUrlServer _sysRoleUrlServer;
            private readonly IMapper _mapper;
            public SysRoleUrlController(ISysRoleUrlServer sysRoleUrlServer,IMapper mapper)
            {
                _sysRoleUrlServer = sysRoleUrlServer;
                _mapper = mapper;
            }
            /// <summary>
            /// 删除角色可访问的URL
            /// </summary>
            /// <param name="roleId"></param>
            /// <param name="urlId"></param>
            /// <returns></returns>
            [HttpDelete]
            [Route("Delete/{roleId}/{urlId}")]
            public ActionResult<ResponseData<bool>> Delete([FromRoute] string roleId, [FromRoute] string urlId)
            {
                try
                {
                    bool isExist = _sysRoleUrlServer.IsExist(roleId, urlId);
                    if (!isExist)
                    {
                        return Ok(new ResponseData<bool>(HttpStatusCode.NotFound, $"角色{roleId}不存在URL{urlId}!", false));
                    }
                    bool isDelete= _sysRoleUrlServer.IsDelete(roleId, urlId);
                    if (!isDelete)
                    {
                        return Ok(new ResponseData<bool>(HttpStatusCode.Conflict, $"角色{roleId}不允许删除URL{urlId}!", false));
                    }
                    _sysRoleUrlServer.Delete(roleId, urlId);
                    return Ok(new ResponseData<bool>(HttpStatusCode.OK, data: true));
                }
                catch (Exception e)
                {
                    return Ok(new ResponseData<bool>(HttpStatusCode.InternalServerError, "服务器异常", false));
                }
            }
        }
    }
  4. 在上述代码中我们在执行删除操作时需要判断角色可访问接口是否存在以及角色可访问接口是否可以删除,因此需要在接口及其实现类中增加IsExistIsDelete方法

    csharp 复制代码
    //ISysRoleUrlServer
    /// <summary>
    /// 角色可访问的URL是否存在
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="urlId"></param>
    /// <returns></returns>
    bool IsExist(string roleId, string urlId);
    
    /// <summary>
    /// 是否可以删除
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="urlId"></param>
    /// <returns></returns>
    bool IsDelete(string roleId, string urlId);
    
    //SysRoleUrlImp
    /// <summary>
    /// 角色可访问的URL是否存在
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="url"></param>
    /// <returns></returns>
    public bool IsExist(string roleId, string urlId)
    {
        try
        {
            return _dbContext.SysRoleUrls.Any(x => x.RoleId == roleId && x.UrlId == urlId);
        }
        catch (Exception e)
        {
            throw;
        }
    }
    
    /// <summary>
    /// 是否可以删除
    /// </summary>
    /// <param name="roleId"></param>
    /// <param name="urlId"></param>
    /// <returns></returns>
    public bool IsDelete(string roleId, string urlId)
    {
        try
        {
            return _dbContext.SysRoleUrls
                .Any(x => x.RoleId == roleId && x.UrlId == urlId && x.CanDelete);
        }
        catch (Exception e)
        {
            throw;
        }
    }

三、总结

这篇文章主要讲解了角色可访问接口管理的编写,代码和逻辑也很简单,因此没有详细讲解。角色可访问接口管理的剩余需求我希望大家一起来编写出来。

相关推荐
Leo.yuan40 分钟前
数据量大Excel卡顿严重?选对报表工具提高10倍效率
数据库·数据分析·数据可视化·powerbi
Runing_WoNiu1 小时前
MySQL与Oracle对比及区别
数据库·mysql·oracle
天道有情战天下1 小时前
mysql锁机制详解
数据库·mysql
看山还是山,看水还是。1 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
谷新龙0011 小时前
Redis运行时的10大重要指标
数据库·redis·缓存
CodingBrother1 小时前
MySQL 中单列索引与联合索引分析
数据库·mysql
精进攻城狮@1 小时前
Redis缓存雪崩、缓存击穿、缓存穿透
数据库·redis·缓存
小酋仍在学习1 小时前
光驱验证 MD5 校验和
数据库·postgresql
keep__go2 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
问道飞鱼2 小时前
【微服务知识】开源RPC框架Dubbo入门介绍
微服务·rpc·开源·dubbo