实习生进了公司不会开发?一个真实业务教会你如何分析业务!

一、权限业务介绍

本业务为个人试用期的时候的真实企业级业务,进行了简单的替换词和业务内容模糊,但是业务逻辑没有变化,值得学习,代码部分可能因为替换词有部分误解,发现问题请评论区提醒我。
这个业务教会了我,代码应当复用率高,操作应闭环简化,利用算法的思想,设计任务处理队列,进行批处理,一次性批处理,数据库应交互次数少,巧妙的利用LINQ语句,简化代码难度
坚持看完,一定对你有所帮助,开头业务描述可能会有点枯燥,但是一定要看完

1. 业务字段介绍

在这里插入图片描述权限数据库字段是这样的,权限种类有四种,决定一级权限的归属

权限种类: 2
一级权限: “R1”
二级权限: “String1,String2”
指的是一个人有2权限的R1中的Sstring1和2的权限

权限种类: 1
一级权限: " * "
二级权限: " * "
指的是一个人有1权限的全权限的权限

权限种类: 1
一级权限: " R1 "
二级权限: “String1,String2”
指的是一个人有1权限的全权限的权限
权限种类: 1
一级权限: " R2 "
二级权限: “String3”
指的是一个人有1权限的R1中的Sstring1和2,和R2的String3 的权限

2. 业务需求分析

2.1 保存接口

需要实现对用户的新增权限、修改(覆盖)权限、取消权限的综合性接口。
在这里插入图片描述

图示权限选择:
权限种类: 1(A)
一级权限: " R1 "
二级权限: “String3”
指的是一个人有1权限的全权限的权限
权限种类: 1(A)
一级权限: " R2 "
二级权限: “String1,String2”
指的是一个人有1权限的R1中的Sstring1和2,和R2的String3 的权限

业务问题
  1. 用户本身有权限,要考虑是不是得软删除原有的权限新增新权限进行覆盖

  2. 从单独权限到全权限(全部勾选),前端发送数据直接改成*删除原有种类下所有的所有权限,新增一条*权限。
    在这里插入图片描述

  3. 可能会出现新增、修改、删除三种操作同时出现的情况。
    在这里插入图片描述

二、权限业务解析

1. 常规解析

根据业务逻辑一步一步思考
在这里插入图片描述

2. 企业级闭环高效解析

代码复用率高,操作闭环简化,利用交并集的思想,设计任务处理队列,进行批处理,一次性批处理,数据库交互次数少,巧妙的利用LINQ语句,简化代码难度
在这里插入图片描述
在这里插入图片描述

三、代码实现

1. BLL

1.1 获取用户存储的全部非删除权限

/// <summary>
/// 获取用户存储的全部权限(不包含删除)
/// </summary>
/// <param name="RoleType">权限类型1:A权限,2:D权限,3:M权限,4: E报表权限,*->5:所有权限</param>
/// <param name="UserAccount">用户账号</param>
/// <returns></returns>
public List<UserRoleEntity> GetAllUserRole(int RoleType, string UserAccount)
{
    // 获取符合条件的权限记录
    List<UserRoleEntity>? allPower = _roleDB.AsQueryable()
        .Where(a => a.UserAccount == UserAccount&&!a.IsDelete) // 过滤条件:指定用户账号&&存在
        .WhereIF(RoleType != 5, w => w.RoleType == Convert.ToByte(RoleType)) // 过滤条件:指定权限类型,若为 5 则不过滤
        .ToList();
    return allPower;
}

1.2 删除用户权限

/// <summary>
/// 删除用户权限
/// </summary>
/// <param name="RoleType">权限类型</param>
/// <param name="UserAccount">用户账号</param>
/// <param name="RoleName">权限组名称(可选)</param>
/// <returns></returns>
public async Task<dynamic> DeleteUserRole(int RoleType, string UserAccount, string? RoleName = null)
{
    _logger.LogInformation("开始软删除角色,用户账号: {UserAccount}, 权限类型: {RoleType}, 角色名称: {RoleName}", UserAccount, RoleType, RoleName);

    if (string.IsNullOrEmpty(UserAccount))
    {
        _logger.LogWarning("用户账号不能为空。");
        return HttpMsgResult.FailureResult(msg: "用户账号不能为空。");
    }

    var query = _roleDB.AsQueryable()
                       .Where(r => r.RoleType == RoleType && r.UserAccount == UserAccount);

    if (!string.IsNullOrEmpty(RoleName))
    {
        query = query.Where(r => r.RoleName == RoleName);
    }

    var existingRoles = await query.ToListAsync();

    if (existingRoles == null || existingRoles.Count == 0)
    {
        _logger.LogWarning("未找到对应的角色,无法删除,用户账号: {UserAccount}, 权限类型: {RoleType}, 角色名称: {RoleName}", UserAccount, RoleType, RoleName);
        return HttpMsgResult.FailureResult(msg: "未找到对应的角色,无法删除。");
    }

    try
    {
        var affectedRows = _roleDB.FakeDeleteRange(existingRoles);

        if (affectedRows > 0)
        {
            _logger.LogInformation("成功软删除 {Count} 条角色记录,用户账号: {UserAccount}", affectedRows, UserAccount);
            return HttpMsgResult.SuccessResult(msg: $"用户权限已被软删除,共删除 {affectedRows} 条记录。");
        }
        else
        {
            _logger.LogWarning("未能软删除角色记录,用户账号: {UserAccount}", UserAccount);
            return HttpMsgResult.FailureResult(msg: "未能删除用户权限。");
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "软删除角色时发生错误,用户账号: {UserAccount}, 权限类型: {RoleType}, 角色名称: {RoleName}", UserAccount, RoleType, RoleName);
        return HttpMsgResult.FailureResult(msg: "删除用户权限时发生错误:" + ex.Message);
    }
}

1.3 数据传输对象解析

/// <summary>
/// 将综合的用户角色数据传输对象解析为多个 UserRoleEntity 对象。
/// </summary>
/// <param name="userRoleJsonDto">用户角色数据传输对象综合列表。</param>
/// <returns>解析后的 UserRoleEntity 对象列表。</returns>
public List<UserRoleEntity> ParseJsonDtoToUserRoleDtos(UserRoleJsonDto userRoleJsonDto)
{
    List<UserRoleEntity>? userRoleDtos = new List<UserRoleEntity>();

    foreach (RoleDetailDto role in userRoleJsonDto.Roles)
    {
        UserRoleEntity? userRoleDto = new UserRoleEntity
        {
            UserAccount = userRoleJsonDto.UserAccount, // 将用户账号赋值给每个 UserRoleDto
            UserRealName = userRoleJsonDto.UserRealName, // 将用户真实姓名赋值给每个 UserRoleDto
            RoleType = (byte?)role.RoleType, // 赋值权限类型
            RoleName = role.RoleName, // 赋值角色名称
            SubRole = string.Join(",", role.SubRoles ?? Array.Empty<string>()), // 赋值子类Code数组
            IsDelete = userRoleJsonDto.IsDelete == 1 // 继承综合对象的删除状态
        };

        userRoleDtos.Add(userRoleDto);
    }

    return userRoleDtos;
}

2. Dto

2.1 userRoleJsonDto

namespace OPC.PR.Application.Objects
{
    /// <summary>
    /// 角色详细信息数据传输对象
    /// </summary>
    public class RoleDetailDto
    {
        /// <summary>
        /// 所属权限组的类型 权限类型1:A权限,2:D权限,3:M权限,4: E报表权限,*->5:所有权限</param>
        /// </summary>
        public int RoleType { get; set; }
        /// <summary>
        /// 所属权限组的名称(全部时为*)
        /// </summary>
        public string? RoleName { get; set; }

        /// <summary>
        /// 所属权限大类下得子类Code
        /// </summary>
        public string[]? SubRoles { get; set; }
    }

    /// <summary>
    /// 角色数据传输对象,用于接收复杂结构的 JSON 数据
    /// </summary>
    public class UserRoleJsonDto
    {
        /// <summary>
        /// 用户账号
        /// </summary>
        public string UserAccount { get; set; }

        /// <summary>
        /// 用户真实姓名
        /// </summary>
        public string? UserRealName { get; set; }

        /// <summary>
        /// 冻结标识
        /// </summary>
        public int IsDelete { get; set; } = 0;


        /// <summary>
        /// 权限详细信息列表
        /// </summary>
        public List<RoleDetailDto> Roles { get; set; }

    }
}

2.2 UserRoleDto

namespace OPC.PR.Application.Objects
{
    /// <summary>
    /// 角色数据传输对象
    /// </summary>
    public class UserRoleDto
    {
        /// <summary>
        /// 用户账号
        /// </summary>
        public string UserAccount { get; set; }

        /// <summary>
        /// 用户真实姓名
        /// </summary>
        public string? UserRealName { get; set; }

        /// <summary>
        /// 所属权限组的名称(全部时为*)
        /// </summary>
        public string? RoleName { get; set; }

        /// <summary>
        /// 所属权限组的类型
        /// </summary>
        public int RoleType { get; set; }

        /// <summary>
        /// 所属权限大类下得子类Code
        /// </summary>
        public string[]? SubRoles { get; set; }

        /// <summary>
        /// 冻结标识
        /// </summary>
        public int IsDelete { get; set; } = 0;

    }
}

2.3 UserRoleEntity

namespace OPC.PR.Application.Entity
{
    [SugarTable("b_user_role", "用户权限配置表")]
    [Tenant(DBConfigIds.PR)]
    public class UserRoleEntity : EntityBase
    {
        /// <summary>
        ///  用户账号
        /// </summary>
        public string? UserAccount { get; set; }
        /// <summary>
        ///   用户姓名
        /// </summary>
        public string? UserRealName { get; set; }
        /// <summary>
        ///  所属权限组的名称(全部时为*)
        /// </summary>
        public string? RoleName { get; set; }
        /// <summary>
        /// 所属权限组的类型
        /// </summary>
        public byte? RoleType { get; set; }
        /// <summary>
        /// 所属权限大类下得子类Code,多个时以逗号分隔
        /// </summary>
        public string? SubRole { get; set; }


    }
}

3. Service

3.1 展示角色全部权限

/// <summary>
/// 展示角色全部权限
/// </summary>
/// <param name="RoleType"></param>
/// <param name="UserAccount"></param>
/// <returns></returns>
[DisplayName("展示角色全部权限"), ActionName("GetRole")]
[HttpPost]
[NonUnify]
public dynamic GetRole(string RoleType, string UserAccount)
{
    _logger.LogInformation("开始调用 GetRole 方法,权限类型: {RoleType}, 用户账号: {UserAccount}", RoleType, UserAccount);
    // 转化成全部情况
    if (RoleType == "*") RoleType = "5";
    // 获取全部权限
    List<UserRoleEntity>? getResult;
    try
    {
        getResult = _bllrole.GetAllUserRole(RoleType: int.Parse(RoleType), UserAccount);
        // 将数据库查询结果映射到 UserRoleDto 列表
        var qresult = getResult.Select(x => new UserRoleDto
        {
            UserAccount = x.UserAccount, // 映射用户账号
            UserRealName = x.UserRealName, // 映射用户真实姓名
            RoleName = x.RoleName, // 映射角色名称
            RoleType = x.RoleType.HasValue ? (int)x.RoleType : 0, // 映射角色类型,若为空则设为 0
            SubRoles = x.SubRole != null ? x.SubRole.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) : new string[] { }, // 映射子权限,将其分割为数组
            IsDelete = x.IsDelete ? 1 : 0 // 映射删除状态,已删除标识为 1,未删除为 0
        }).ToList();
        _logger.LogInformation("开始调用 GetRole 方法,权限类型: {RoleType}, 用户账号: {UserAccount}", RoleType, UserAccount);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "获取用户权限时发生错误,用户账号: {UserAccount}, 权限类型: {RoleType}", UserAccount, RoleType);
        return HttpMsgResult.FailureResult(msg: "获取用户权限时发生错误.");
    }
    // 过滤掉已软删除的记录
    var activeRoles = getResult.Where(r => !r.IsDelete).ToList();
    _logger.LogInformation("找到 {Count} 条有效权限记录,用户账号: {UserAccount}", activeRoles.Count, UserAccount);
    // 构造固定字段名称的数据
    var data = activeRoles.Select(role =>
    {
        // 调用判断器获取字段名
        (string fieldName1, string fieldName2) = GetFieldNames((int)role.RoleType);
        // 构造字段名和子权限
        return new Dictionary<string, object>
{
    { fieldName1, role.RoleName },
    { fieldName2, role.SubRole} // 直接返回子权限列表
};
    }).ToList();

    _logger.LogInformation("结束调用 GetRole 方法");
    return data;
}

/// <summary>
/// 根据RoleType生成字段名称
/// </summary>
/// <param name="roleType">角色类型</param>
/// <returns>字段名称元组</returns>
private (string fieldName1, string fieldName2) GetFieldNames(int roleType)
{
    return roleType switch
    {
        1 => ("A1", "A2"),
        2 => ("D", "Dsub"),
        3 or 4 => ("Other1", "Other2"),
        _ => ("Error1", "Error2"),
    };
}

3.2 保存用户权限

/// <summary>
/// 保存用户权限
/// </summary>
/// <param name="userRoleJsonDto"> Body格式的数据,不多传输</param>
[DisplayName("保存用户权限"), ActionName("SetUserRole")]
[HttpPost]
[NonUnify]
public async Task<dynamic> SetUserRole(UserRoleJsonDto userRoleJsonDto)
{
    _logger.LogInformation("开始保存用户权限,用户账号: {UserAccount}", userRoleJsonDto.UserAccount);

    // 解析 JSON DTO 为多个 UserRoleDto
    List<UserRoleEntity>? userRoleDtos = _bllrole.ParseJsonDtoToUserRoleDtos(userRoleJsonDto);

    if (userRoleDtos == null || !userRoleDtos.Any())
    {
        _logger.LogWarning("未找到有效的用户角色数据,用户账号: {UserAccount}", userRoleJsonDto.UserAccount);
        return HttpMsgResult.FailureResult(msg: "未找到有效的用户角色数据。");
    }

    // 查询数据库中的现有权限
    List<UserRoleEntity>? allCurrentRoles = _bllrole.GetAllUserRole(5, userRoleJsonDto.UserAccount);

    if (userRoleJsonDto.Roles.Any(s => s.RoleName == "*"))
    {
        // 查询数据库中是否存在RoleName为*的记录
        UserRoleEntity? existingStarRole = allCurrentRoles.FirstOrDefault(w => w.RoleName == "*");

        if (existingStarRole == null)
        {
            // 将相同 RoleType 的所有记录加入软删除队列
            List<UserRoleEntity>? rolesToDelete = allCurrentRoles.Where(w => userRoleJsonDto.Roles.Any(s => s.RoleType == w.RoleType)).ToList();
             _roleDB.FakeDeleteRange(rolesToDelete);
            _logger.LogInformation("批量删除完成,删除数量: {Count}", rolesToDelete.Count);

            // 构造新增的*权限
            var starRoleEntity = new UserRoleEntity
            {
                UserAccount = userRoleJsonDto.UserAccount,
                UserRealName = userRoleJsonDto.UserRealName, // 从 JsonDto 获取的真实用户姓名
                RoleType = Convert.ToByte(userRoleJsonDto.Roles.FirstOrDefault(r => r.RoleName == "*")?.RoleType),
                RoleName = "*",
                SubRole = string.Join(",", userRoleJsonDto.Roles.FirstOrDefault(r => r.RoleName == "*")?.SubRoles ?? Array.Empty<string>()),
                IsDelete = false
            };

            _roleDB.Insert(starRoleEntity);
            _logger.LogInformation("新增角色: *, 类型: {RoleType}, 用户账号: {UserAccount}", starRoleEntity.RoleType, starRoleEntity.UserAccount);
            return HttpMsgResult.SuccessResult(msg: "新增角色全权限。");
        }
        else
        {
            _logger.LogError("已经是全权限");
            return HttpMsgResult.FailureResult(msg: "已经是全权限。");
        }
    }

    // 删除队列
    var DeleteRoles = allCurrentRoles.Where(w => userRoleJsonDto.Roles.Any(s => s.RoleType == w.RoleType) && !userRoleJsonDto.Roles.Any(s => s.RoleType == w.RoleType && s.RoleName == w.RoleName)).ToList();
    // 更新队列 - 保留从数据库中获取的原始记录,但更新 DTO 中传入的新值
    var updateRoles = userRoleDtos.Where(r => allCurrentRoles.Any(existingRole => existingRole.RoleType == r.RoleType && existingRole.RoleName == r.RoleName)) .Select(r =>{var originalEntity = allCurrentRoles.FirstOrDefault(existingRole => existingRole.RoleType == r.RoleType &&existingRole.RoleName == r.RoleName);if (originalEntity != null){originalEntity.UserRealName = r.UserRealName;originalEntity.SubRole = r.SubRole;
      originalEntity.IsDelete = r.IsDelete;}return originalEntity;}) .ToList();

    // 增加队列 - 构建新的实体,保持从 DTO 传入的数据
    var addRoles = userRoleDtos.Where(r => !allCurrentRoles.Any(existingRole => existingRole.RoleType == r.RoleType &&
    existingRole.RoleName == r.RoleName)).Select(r => new UserRoleEntity{UserAccount = r.UserAccount,UserRealName = r.UserRealName, RoleType = r.RoleType,
      RoleName = r.RoleName,SubRole = r.SubRole,IsDelete = r.IsDelete}) .ToList();

    try
    {
        // 批量执行删除操作
        if (DeleteRoles.Any())
        {
            _roleDB.FakeDeleteRange(DeleteRoles);
            _logger.LogInformation("批量删除完成,删除数量: {Count}", DeleteRoles.Count);
        }

        // 批量执行更新操作
        if (updateRoles.Any())
        {
            _roleDB.UpdateRange(updateRoles);
            _logger.LogInformation("批量更新完成,更新数量: {Count}", updateRoles.Count);
        }

        // 批量执行新增操作
        if (addRoles.Any())
        {
            _roleDB.InsertRange(addRoles);
            _logger.LogInformation("批量新增完成,新增数量: {Count}", addRoles.Count);
        }

        _logger.LogInformation("用户权限保存完成,用户账号: {UserAccount}", userRoleJsonDto.UserAccount);
        return HttpMsgResult.SuccessResult(msg: "用户操作已完成。");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "批量操作时发生错误,用户账号: {UserAccount}", userRoleJsonDto.UserAccount);
        return HttpMsgResult.FailureResult(msg: "用户操作失败。");
    }
    finally
    {
        _logger.LogInformation("保存用户权限操作结束,用户账号: {UserAccount}", userRoleJsonDto.UserAccount);
    }
}

3.3 软删除用户权限

/// <summary>
/// 软删除用户权限
/// </summary>
/// <param name="RoleType">权限类型</param>
/// <param="UserAccount">用户账号</param>
/// <param="RoleName">权限组名称(可选)</param>
/// <returns></returns>
public async Task<dynamic> DeleteUserRole(int RoleType, string UserAccount)
{
    _logger.LogInformation("开始软删除角色,用户账号: {UserAccount}, 权限类型: {RoleType}", UserAccount, RoleType);

    if (string.IsNullOrEmpty(UserAccount))
    {
        _logger.LogWarning("用户账号不能为空。");
        return HttpMsgResult.FailureResult(msg: "用户账号不能为空。");
    }

    try
    {
        // 调用 BLL 的 DeleteUserRole 方法
        var result = await _bllrole.DeleteUserRole(RoleType, UserAccount, null);
        return result;
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "软删除角色时发生错误,用户账号: {UserAccount}, 权限类型: {RoleType},", UserAccount, RoleType);
        return HttpMsgResult.FailureResult(msg: "删除用户权限时发生错误:" + ex.Message);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰冰在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值