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

三、总结

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

相关推荐
heartbeat..2 小时前
Spring AOP 全面详解(通俗易懂 + 核心知识点 + 完整案例)
java·数据库·spring·aop
元Y亨H4 小时前
Nacos - 服务发现
java·微服务
麦聪聊数据4 小时前
MySQL并发与锁:从“防止超卖”到排查“死锁”
数据库·sql·mysql
AC赳赳老秦5 小时前
DeepSeek 私有化部署避坑指南:敏感数据本地化处理与合规性检测详解
大数据·开发语言·数据库·人工智能·自动化·php·deepseek
YMatrix 官方技术社区6 小时前
YMatrix 存储引擎解密:MARS3 存储引擎如何超越传统行存、列存实现“时序+分析“场景性能大幅提升?
开发语言·数据库·时序数据库·数据库架构·智慧工厂·存储引擎·ymatrix
辞砚技术录7 小时前
MySQL面试题——索引2nd
数据库·mysql·面试
linweidong7 小时前
C++thread pool(线程池)设计应关注哪些扩展性问题?
java·数据库·c++
欧亚学术8 小时前
突发!刚刚新增17本期刊被剔除!
数据库·论文·sci·期刊·博士·scopus·发表
黑白极客8 小时前
怎么给字符串字段加索引?日志系统 一条更新语句是怎么执行的
java·数据库·sql·mysql·引擎
大厂技术总监下海9 小时前
数据湖加速、实时数仓、统一查询层:Apache Doris 如何成为现代数据架构的“高性能中枢”?
大数据·数据库·算法·apache