//----------SysRole开始----------



using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Admin.Core.IRepository;
using Admin.Core.Model;
using Admin.Core.Common;
using AutoMapper;
using System.Linq.Expressions;
using Admin.Core.IRepository.ISys;
using Admin.Core.IService.ISys;
using Admin.Core.Model.Sys;

namespace Admin.Core.Service.Sys
{
    /// <summary>
    /// 角色信息表Service
    /// </summary>	
    public partial class SysRoleService : BaseServices<SysRole>, ISysRoleService
    {
        IBaseRepository<SysRole> dal;
        private readonly ISysRoleRepository _sysRoleRepository;
        private readonly ISysUserRoleRepository _sysUserRoleRepository;
        private readonly ISysMenuRepository _sysMenuRepository;
        private readonly ISysRoleMenuRepository _sysRoleMenuRepository;
        private readonly ISysRoleDeptRepository _sysRoleDeptRepository;
        private readonly IMapper _mapper;

        public SysRoleService(IBaseRepository<SysRole> dal, ISysRoleRepository sysRoleRepository, ISysUserRoleRepository sysUserRoleRepository, ISysMenuRepository sysMenuRepository,
           ISysRoleMenuRepository sysRoleMenuRepository, ISysRoleDeptRepository sysRoleDeptRepository, IMapper mapper)
        {
            this.dal = dal;
            BaseDal = dal;
            _sysRoleRepository = sysRoleRepository;
            _sysUserRoleRepository = sysUserRoleRepository;
            _sysMenuRepository = sysMenuRepository;
            _sysRoleMenuRepository = sysRoleMenuRepository;
            _sysRoleDeptRepository = sysRoleDeptRepository;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取权限Perms
        /// </summary>
        /// <param name="roles"></param>
        /// <returns></returns>
        public async Task<List<string>> GetUserPermsStr(List<int> roleIDs)
        {
            var menus = await _sysRoleMenuRepository.QueryAsync(a => roleIDs.Contains((int)a.RoleID));
            var perms = await _sysMenuRepository.QueryAsync(a => menus.Select(x => x.MenuID).Contains(a.MenuID));

            return perms.Select(x => x.Perms).ToList();
        }

        /// <summary>
        /// 获取所有角色信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<List<SysRole>> GetUserRolesByUserId(int userId)
        {
            return await _sysRoleRepository.GetUserRolesByUserId(userId);
        }

        /// <summary>
        /// 根据条件分页查询角色数据
        /// </summary>
        /// <param name="role"> 角色信息 </param>
        /// <returns> 角色数据集合信息 </returns>
        public async Task<PageModel<SysRole>> SelectRoleList(PageQuery<RoleQuery> pageQuery)
        {
            Expression<Func<SysRole, bool>> whereExpression = x => (bool)x.DelFlag == false;
            if (pageQuery.Query.RoleName.IsNotEmptyOrNull())
            {
                whereExpression = whereExpression.And(x => x.RoleName.Contains(pageQuery.Query.RoleName));
            }
            if (pageQuery.Query.RoleKey.IsNotEmptyOrNull())
            {
                whereExpression = whereExpression.And(x => x.RoleKey.Contains(pageQuery.Query.RoleKey));
            }
            if (pageQuery.Query.Status.IsNotEmptyOrNull())
            {
                whereExpression = whereExpression.And(x => x.Status == pageQuery.Query.Status);
            }
            if (pageQuery.Query.DateRange.IsNotEmptyOrNull() && pageQuery.Query.DateRange.Count > 0)
            {
                if (pageQuery.Query.DateRange[0].IsNotEmptyOrNull())
                {
                    whereExpression = whereExpression.And(x => x.CreateTime >= pageQuery.Query.DateRange[0]);
                }
                if (pageQuery.Query.DateRange.Count > 1 && pageQuery.Query.DateRange[1].IsNotEmptyOrNull())
                {
                    whereExpression = whereExpression.And(x => x.CreateTime <= pageQuery.Query.DateRange[1]);
                }
            }

            var data = await dal.QueryPageAsync(whereExpression, pageQuery.Page, pageQuery.PageSize, "RoleSort asc");

            return data;
        }

        /// <summary>
        /// 根据编号获取详细信息
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public async Task<RoleView> GetInfo(int roleId)
        {
            var role = await dal.QueryByIdAsync(roleId);

            var roleMenus = await _sysRoleMenuRepository.QueryAsync(x => x.RoleID == roleId);
            var userRoles = await _sysRoleDeptRepository.QueryAsync(x => x.RoleID == roleId);
            RoleView roleView = new RoleView
            {
                SysRole = role,
                MenuIds = roleMenus.Select(x => x.MenuID).ToArray(),
                DeptIds = userRoles.Select(x => x.DeptID).ToArray()
            };
            return roleView;
        }

        /// <summary>
        /// 查询所有角色
        /// </summary>
        /// <returns> 角色列表 </returns>
        public async Task<List<SysRole>> SelectRoleAll()
        {
            return await dal.QueryAsync();
        }

        /// <summary>
        /// 根据用户ID获取角色选择框列表
        /// </summary>
        /// <param name="userId"> 用户ID </param>
        /// <returns> 选中角色ID列表 </returns>
        public async Task<List<int>> SelectRoleListByUserId(int userId)
        {
            var roles = await _sysUserRoleRepository.QueryAsync(x => x.UserID == userId);
            return roles.Select(x => (int)x.RoleID).ToList();
        }

        /// <summary>
        /// 通过角色ID查询角色
        /// </summary>
        /// <param name="roleId"> 角色ID </param>
        /// <returns> 角色对象信息 </returns>
        public async Task<SysRole> SelectRoleById(int roleId)
        {
            return await dal.QueryByIdAsync(roleId);
        }

        /// <summary>
        /// 校验角色名称是否存在
        /// </summary>
        /// <param name="roleName"> 角色名称 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> CheckRoleNameUnique(string roleName)
        {
            var data = await dal.QueryAsync(x => x.RoleName == roleName);
            return data.Count > 0;
        }

        /// <summary>
        /// 校验角色key是否存在
        /// </summary>
        /// <param name="roleKey"> 角色Key </param>
        /// <returns> 结果 </returns>
        public async Task<bool> CheckRoleKeyUnique(string roleKey)
        {
            var data = await dal.QueryAsync(x => x.RoleKey == roleKey);
            return data.Count > 0;
        }

        /// <summary>
        /// 通过角色ID查询角色使用数量
        /// </summary>
        /// <param name="roleId"> 角色ID </param>
        /// <returns> 结果 </returns>
        public async Task<int> CountUserRoleByRoleId(int roleId)
        {
            var roles = await _sysUserRoleRepository.QueryAsync(x => x.RoleID == roleId);
            return roles.Count;
        }

        /// <summary>
        /// 新增保存角色信息
        /// </summary>
        /// <param name="role"> 角色信息 </param>
        /// <param name="loginName"> 操作人 </param>
        /// <returns> 结果 </returns>
        public async Task<int> InsertRole(RoleView role)
        {
            // 新增角色信息
            role.SysRole.CreateTime = DateTime.Now;
            role.SysRole.UpdateTime = DateTime.Now;
            role.SysRole.DelFlag = false;
            var addId = await dal.AddAsync(role.SysRole);
            if (addId > 0)
            {
                await InsertRoleMenu(addId, role.MenuIds);
            }
            return addId;
        }

        /// <summary>
        /// 修改保存角色信息
        /// </summary>
        /// <param name="role"> 角色信息 </param>
        /// <param name="updateBy"> 修改者 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> UpdateRole(RoleView role, string updateBy = "")
        {
            var Del = true;
            var Add = true;
            // 修改角色信息
            var update = await UpdateRoleBase(role.SysRole, updateBy);

            if (update)
            {
                // 删除角色与菜单关联
                var roleMenu = await _sysRoleMenuRepository.QueryAsync(x => x.RoleID == role.SysRole.RoleID);
                if (roleMenu.Count > 0)
                {
                    Del = await _sysRoleMenuRepository.DeletesAsync(roleMenu);
                }
            }

            if (Del)
            {
                // 新增角色和部门信息(数据权限)
                Add = await InsertRoleMenu(role.SysRole.RoleID, role.MenuIds);
            }

            return Add;
        }

        /// <summary>
        /// 修改角色状态
        /// </summary>
        /// <param name="role"> 角色信息 </param>
        /// <param name="updateBy"> 修改者 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> UpdateRoleStatus(SysRole role, string updateBy = "")
        {
            var data = await SelectRoleById(role.RoleID);
            data.UpdateBy = updateBy;
            data.UpdateTime = DateTime.Now;
            data.Status = role.Status;
            return await dal.UpdateAsync(data);
        }

        /// <summary>
        /// 修改角色基础信息
        /// </summary>
        /// <param name="role"> 角色信息 </param>
        /// <param name="updateBy"> 修改者 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> UpdateRoleBase(SysRole role, string updateBy = "")
        {
            role.UpdateBy = updateBy;
            role.UpdateTime = DateTime.Now;
            return await dal.UpdateAsync(role);
        }

        /// <summary>
        /// 修改数据权限信息
        /// </summary>
        /// <param name="role"> 角色信息 </param>
        /// <param name="updateBy"> 修改者 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> AuthDataScope(RoleView role, string updateBy = "")
        {
            var Del = true;
            var Add = true;
            // 修改角色信息
            var update = await UpdateRoleBase(role.SysRole, updateBy);

            if (update)
            {
                // 删除角色与部门表
                var roleDept = await _sysRoleDeptRepository.QueryAsync(x => x.RoleID == role.SysRole.RoleID);
                if (roleDept.Count > 0)
                {
                    Del = await _sysRoleDeptRepository.DeletesAsync(roleDept);
                }
            }

            if (Del)
            {
                // 新增角色和部门信息(数据权限)
                Add = await InsertRoleDept(role.SysRole.RoleID, role.DeptIds);
            }

            return Add;
        }

        /// <summary>
        /// 新增角色菜单信息
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="menuIds"></param>
        /// <returns></returns>
        public async Task<bool> InsertRoleMenu(int roleId, int?[] menuIds)
        {
            if (menuIds.IsNotEmptyOrNull() && menuIds.Length > 0)
            {
                // 新增用户与角色管理
                List<SysRoleMenu> list = new List<SysRoleMenu>();
                foreach (var item in menuIds)
                {
                    SysRoleMenu rm = new SysRoleMenu()
                    {
                        RoleID = roleId,
                        MenuID = item
                    };
                    list.Add(rm);
                }
                var R = await _sysRoleMenuRepository.AddAsync(list);
                return R > 0;
            }

            return true;
        }

        /// <summary>
        /// 新增角色部门信息(数据权限)
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="deptIds"></param>
        /// <param name="role"> 角色对象 </param>
        public async Task<bool> InsertRoleDept(int roleId, int?[] deptIds)
        {
            if (deptIds.IsNotEmptyOrNull() && deptIds.Length > 0)
            {
                // 新增用户与角色管理
                List<SysRoleDept> list = new List<SysRoleDept>();
                foreach (var item in deptIds)
                {
                    SysRoleDept rm = new SysRoleDept()
                    {
                        RoleID = roleId,
                        DeptID = item
                    };
                    list.Add(rm);
                }
                var R = await _sysRoleDeptRepository.AddAsync(list);
                return R > 0;
            }

            return true;
        }

        /// <summary>
        /// 通过角色ID删除角色
        /// </summary>
        /// <param name="roleId"> 角色ID </param>
        /// <param name="updateBy"> 修改者 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> DeleteRoleById(int roleId, string updateBy = "")
        {
            var DRoleMenus = true;
            var DRoleDepts = true;
            var DRole = true;

            // 删除角色与菜单关联
            var RRoleMenus = await _sysRoleMenuRepository.QueryAsync(x => x.RoleID == roleId);
            if (RRoleMenus.Count > 0)
            {
                DRoleMenus = await _sysRoleMenuRepository.DeletesAsync(RRoleMenus);
            }
            // 删除角色与部门表
            var RRoleDepts = await _sysRoleDeptRepository.QueryAsync(x => x.RoleID == roleId);
            if (RRoleDepts.Count > 0)
            {
                DRoleDepts = await _sysRoleDeptRepository.DeletesAsync(RRoleDepts);
            }
            //删除角色:逻辑删除
            var sysRole = await dal.QueryByIdAsync(roleId);
            sysRole.DelFlag = true;
            sysRole.UpdateBy = updateBy;
            sysRole.UpdateTime = DateTime.Now;

            if (DRoleMenus && DRoleDepts)
            {
                DRole = await dal.UpdateAsync(sysRole);
            }

            return DRole;
        }

        /// <summary>
        /// 批量删除角色信息
        /// </summary>
        /// <param name="roleIds"> 需要删除的角色ID </param>
        /// <param name="updateBy"> 修改者 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> DeleteRoleByIds(int[] roleIds, string updateBy = "")
        {
            var DRoleMenus = true;
            var DRoleDepts = true;
            var DUserRole = true;
            var DRole = true;

            foreach (var roleId in roleIds)
            {
                if (RoleView.IsAdmin(roleId))
                {
                    return false;
                }
            }
            // 删除角色与菜单关联
            var RRoleMenus = await _sysRoleMenuRepository.QueryAsync(x => roleIds.ToList().Contains((int)x.RoleID));
            if (RRoleMenus.Count > 0)
            {
                DRoleMenus = await _sysRoleMenuRepository.DeletesAsync(RRoleMenus);
            }
            // 删除角色与部门表
            var RRoleDepts = await _sysRoleDeptRepository.QueryAsync(x => roleIds.ToList().Contains((int)x.RoleID));
            if (RRoleDepts.Count > 0)
            {
                DRoleDepts = await _sysRoleDeptRepository.DeletesAsync(RRoleDepts);
            }
            // 删除角色与部门表
            var RUserRoles = await _sysUserRoleRepository.QueryAsync(x => roleIds.ToList().Contains((int)x.RoleID));
            if (RUserRoles.Count > 0)
            {
                DUserRole = await _sysUserRoleRepository.DeletesAsync(RUserRoles);
            }
            //删除角色:逻辑删除
            var sysRoles = await dal.QueryAsync(x => roleIds.ToList().Contains(x.RoleID));
            sysRoles.ForEach(x =>
            {
                x.DelFlag = true;
                x.UpdateBy = updateBy;
                x.UpdateTime = DateTime.Now;
            });

            if (DRoleMenus && DRoleDepts && DUserRole)
            {
                DRole = await dal.UpdateAsync(sysRoles);
            }

            return DRole;
        }

        /// <summary>
        /// 取消授权用户角色
        /// </summary>
        /// <param name="userRole"> 用户和角色关联信息 </param>
        /// <returns> 结果 </returns>
        public async Task<bool> DeleteAuthUser(SysUserRole userRole)
        {
            if (!userRole.IsNotEmptyOrNull())
            {
                return true;
            }
            var data = await _sysUserRoleRepository.QueryAsync(x => x.UserID == userRole.UserID && x.RoleID == userRole.RoleID);
            return await _sysUserRoleRepository.DeletesAsync(data);
        }

        /// <summary>
        /// 批量取消授权用户角色
        /// </summary>
        /// <param name="roleId"> 角色ID </param>
        /// <param name="userIds"> 需要取消授权的用户数据ID </param>
        /// <returns> 结果 </returns>
        public async Task<bool> DeleteAuthUsers(int roleId, int[] userIds)
        {
            if (userIds.IsNotEmptyOrNull() && userIds.Length > 0)
            {
                var data = await _sysUserRoleRepository.QueryAsync(x => x.RoleID == roleId && userIds.ToList().Contains((int)x.UserID));
                return await _sysUserRoleRepository.DeletesAsync(data);
            }
            return true;
        }

        /// <summary>
        /// 批量选择授权用户角色
        /// </summary>
        /// <param name="roleId"> 角色ID </param>
        /// <param name="userIds"> 需要新增的用户数据ID </param>
        /// <returns> 结果 </returns>
        public async Task<bool> InsertAuthUsers(int roleId, int[] userIds)
        {
            if (userIds.IsNotEmptyOrNull() && userIds.Length > 0)
            {
                List<SysUserRole> list = new List<SysUserRole>();
                foreach (var item in userIds)
                {
                    SysUserRole ur = new SysUserRole()
                    {
                        UserID = item,
                        RoleID = roleId
                    };
                    list.Add(ur);
                }
                var R = await _sysUserRoleRepository.AddAsync(list);
                return R > 0;
            }
            return true;
        }
    }
}

//----------SysRole结束----------