【.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;
        }
    }

三、总结

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

相关推荐
White_Mountain9 分钟前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship10 分钟前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站14 分钟前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
装不满的克莱因瓶16 分钟前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
Java程序之猿33 分钟前
微服务分布式(一、项目初始化)
分布式·微服务·架构
数据的世界012 小时前
.NET开发人员学习书籍推荐
学习·.net
梦想平凡2 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
TianyaOAO2 小时前
mysql的事务控制和数据库的备份和恢复
数据库·mysql
Ewen Seong2 小时前
mysql系列5—Innodb的缓存
数据库·mysql·缓存
Yvemil73 小时前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务