using APT.Infrastructure.Core;
using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.IServices.FM;
using APT.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Immutable;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums;
using APT.Infrastructure.Api;
using APT.MS.Domain.Entities.PF;
using APT.BaseData.Domain.Dtos;
using Castle.Core.Internal;

namespace APT.BaseData.Services.Services.FM
{
    public partial class FMUserService : CommonService, IFMUserService
    {
        public FMUserService(IRepository repository)
            : base(repository)
        {
        }


        public List<T_FM_USER> Login(string userName, string pwd)
        {
            var person = this.GetEntities<T_FM_USER>(i => i.CODE == userName && i.PASSWORD == pwd.Trim()).ToList();
            return person;
        }

        public UserRoleModel GetRolesByUser(Guid userId, KeywordFilter filter)
        {
            List<Guid> list = new List<Guid>();
            list.Add(userId);
            var result = GetRolesByUser(list, filter);
            if (result != null && result.Any())
                return result[0];
            return null;
        }

        public UserRoleModel AppGetRolesByUser(Guid userId, KeywordFilter filter)
        {
            List<Guid> list = new List<Guid>();
            list.Add(userId);
            var result = GetAppRolesByUser(list, filter);
            if (result != null && result.Any())
                return result[0];
            return null;
        }
        public List<UserRoleModel> GetAppRolesByUser(IEnumerable<Guid> userIds, KeywordFilter filter)
        {
            try
            {
                if (userIds == null || userIds.Count() <= 0) return null;
                var list = this.GetEntities<T_FM_USER>(t => userIds.Contains(t.ID), filter, new string[] { "Nav_BelongRoles.Nav_BelongRole",
                             "Nav_Org","Nav_Department"}).ToList();
                List<UserRoleModel> result = new List<UserRoleModel>();
                List<T_FM_ROLE_GROUP> roleGroupList = null;
                List<T_FM_USER_GROUP> userGroupList = null;
                foreach (var user in list)
                {
                    Dictionary<Guid, byte> existsUserGroupIds = new Dictionary<Guid, byte>();
                    List<Guid> roleIds = new List<Guid>();
                    if (user.Nav_BelongRoles != null && user.Nav_BelongRoles.Any())
                    {
                        var tmpList = user.Nav_BelongRoles.Where(x => x.Nav_BelongRole.PLATFORM_TYPE ==
                        (int)PFPlatTypeEnum.APP).Select(t => t.BELONG_ROLE_ID).ToList();
                        GetRoleByStr(tmpList, roleIds);
                    }
                    if (user.Nav_BelongRoleGroups != null && user.Nav_BelongRoleGroups.Any())
                    {
                        var tmpList = user.Nav_BelongRoleGroups.Select(t => t.BELONG_ROLE_GROUP_ID).ToList();
                        GetRoleByRoleGroupStr(user.ORG_ID, tmpList, roleIds, ref roleGroupList);
                    }

                    if (user.Nav_BelongUserGroups != null && user.Nav_BelongUserGroups.Any())
                    {
                        var tmpList = user.Nav_BelongUserGroups.Select(t => t.BELONG_USER_GROUP_ID).ToList();
                        foreach (var s in tmpList)
                            GetRoleByUserGroup(user.ORG_ID, s, existsUserGroupIds, ref userGroupList,
                                ref roleGroupList, roleIds);
                    }
                    UserRoleModel userRoleModel = new UserRoleModel();
                    userRoleModel.User = user;


                    if (roleIds.Any())
                    {
                        RolePerm rolePerm = new RolePerm();
                        userRoleModel.Nav_RolePerm = rolePerm;

                        var roles = this.GetEntities<T_FM_ROLE>(t => roleIds.Contains(t.ID) && t.ENABLE_STATUS == 0, filter,
                             new string[] { "Nav_MenuPermissions.Nav_PermissionForm" }).ToList();
                        userRoleModel.Roles = roles;
                        var menuIds = roles.SelectMany(i => i.Nav_MenuPermissions).Select(i => i?.MENU_ID).Distinct().ToList();
                        if (!roles.Any(x => x.ROLE_TYPE == (int)PFUserTypeEnum.管理员))
                        {
                            foreach (var item in roles)
                            {
                                //表单授权
                                if (item.Nav_MenuPermissions != null && item.Nav_MenuPermissions.Any())
                                {
                                    foreach (var menu in item.Nav_MenuPermissions)
                                    {
                                        if (!menu.IS_PERMISSION || menu.Nav_PermissionForm == null) continue;
                                        var form = rolePerm.Nav_RolePermForms.Where(t => t.MenuId == menu.MENU_ID.ToString() && t.PermFormId == menu.PERMISSION_FORM_ID.ToString()).FirstOrDefault();
                                        if (form == null)
                                        {
                                            form = new PermMenuDto();
                                            form.PermFormId = menu.PERMISSION_FORM_ID.ToString();
                                            form.MenuId = menu.MENU_ID?.ToString();
                                            //form.Nav_PermForm = menu.Nav_PermissionForm;
                                            rolePerm.Nav_RolePermForms.Add(form);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    //清空导航
                    user.Nav_BelongRoleGroups = null;
                    user.Nav_BelongRoles = null;
                    user.Nav_BelongUserGroups = null;
                    result.Add(userRoleModel);
                }
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception(LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message);
            }
        }
        public List<UserRoleModel> GetRolesByUser(IEnumerable<Guid> userIds, KeywordFilter filter)
        {
            try
            {
                if (userIds == null || userIds.Count() <= 0) return null;
                //var list = this.GetEntities<T_FM_USER>(t => userIds.Contains(t.ID));
                //if (list == null || !list.Any()) return null;
                //var def = list.FirstOrDefault();
                var list = this.GetEntities<T_FM_USER>(t => userIds.Contains(t.ID), filter, new string[] { "Nav_BelongRoles.Nav_BelongRole",
                             "Nav_BelongRoleGroups.Nav_BelongRoleGroup",
                             "Nav_BelongUserGroups.Nav_BelongUserGroup","Nav_Org","Nav_Department"}).ToList();
                //var userBelongRules = this.GetEntitiesByRedis<T_FM_USER_BELONG_ROLE>(def.ORG_ID ?? Guid.Empty);
                //var belongRules = this.GetEntitiesByRedis<T_FM_ROLE>(def.ORG_ID ?? Guid.Empty);
                //userBelongRules = userBelongRules.Where(i => userIds.Contains(i.USER_ID)).ToList();
                //foreach (var u in userBelongRules)
                //{
                //    u.Nav_BelongRole = belongRules.FirstOrDefault(i => i.ID == u.BELONG_ROLE_ID);
                //}


                //var userBelongRuleGroups = this.GetEntitiesByRedis<T_FM_USER_BELONG_ROLE_GROUP>(def.ORG_ID ?? Guid.Empty);
                //var belongRuleGroups = this.GetEntitiesByRedis<T_FM_ROLE_GROUP>(def.ORG_ID ?? Guid.Empty);
                //userBelongRuleGroups = userBelongRuleGroups.Where(i => userIds.Contains(i.USER_ID)).ToList();
                //foreach (var u in userBelongRuleGroups)
                //{
                //    u.Nav_BelongRoleGroup = belongRuleGroups.FirstOrDefault(i => i.ID == u.BELONG_ROLE_GROUP_ID);
                //}

                //var userBelongUserGroups = this.GetEntitiesByRedis<T_FM_USER_BELONG_USER_GROUP>(def.ORG_ID ?? Guid.Empty);
                //var belongUserGroups = this.GetEntitiesByRedis<T_FM_USER_GROUP>(def.ORG_ID ?? Guid.Empty);
                //userBelongUserGroups = userBelongUserGroups.Where(i => userIds.Contains(i.USER_ID)).ToList();
                //foreach (var u in userBelongUserGroups)
                //{
                //    u.Nav_BelongUserGroup = belongUserGroups.FirstOrDefault(i => i.ID == u.BELONG_USER_GROUP_ID);
                //}

                //foreach (var l in list)
                //{
                //    l.Nav_BelongRoles = userBelongRules.Where(i => i.USER_ID == l.ID).ToList();
                //    l.Nav_BelongRoleGroups = userBelongRuleGroups.Where(i => i.USER_ID == l.ID).ToList();
                //    l.Nav_BelongUserGroups = userBelongUserGroups.Where(i => i.USER_ID == l.ID).ToList();
                //}


                List<UserRoleModel> result = new List<UserRoleModel>();

                //var roleService = ServiceUtils.GetCommonService<T_FM_ROLE>();
                //var roleGroupService = ServiceUtils.GetCommonService<T_FM_ROLE_GROUP>();
                //var userGroupService = ServiceUtils.GetCommonService<T_FM_USER_GROUP>();
                List<T_FM_ROLE_GROUP> roleGroupList = null;
                List<T_FM_USER_GROUP> userGroupList = null;
                foreach (var user in list)
                {
                    Dictionary<Guid, byte> existsUserGroupIds = new Dictionary<Guid, byte>();
                    List<Guid> roleIds = new List<Guid>();
                    if (user.Nav_BelongRoles != null && user.Nav_BelongRoles.Any())
                    {
                        var tmpList = user.Nav_BelongRoles.Where(x => x.Nav_BelongRole.PLATFORM_TYPE == Convert.ToInt32(filter.Parameter3)).Select(t => t.BELONG_ROLE_ID).ToList();
                        GetRoleByStr(tmpList, roleIds);
                    }
                    if (user.Nav_BelongRoleGroups != null && user.Nav_BelongRoleGroups.Any())
                    {
                        var tmpList = user.Nav_BelongRoleGroups.Select(t => t.BELONG_ROLE_GROUP_ID).ToList();
                        GetRoleByRoleGroupStr(user.ORG_ID, tmpList, roleIds, ref roleGroupList);
                    }

                    if (user.Nav_BelongUserGroups != null && user.Nav_BelongUserGroups.Any())
                    {
                        var tmpList = user.Nav_BelongUserGroups.Select(t => t.BELONG_USER_GROUP_ID).ToList();
                        foreach (var s in tmpList)
                            GetRoleByUserGroup(user.ORG_ID, s, existsUserGroupIds, ref userGroupList,
                                ref roleGroupList, roleIds);
                    }

                    UserRoleModel userRoleModel = new UserRoleModel();
                    userRoleModel.User = user;


                    if (roleIds.Any())
                    {
                        RolePerm rolePerm = new RolePerm();
                        userRoleModel.Nav_RolePerm = rolePerm;

                        var roles = this.GetEntities<T_FM_ROLE>(t => roleIds.Contains(t.ID) && t.ENABLE_STATUS == 0, filter,
                             new string[] { "Nav_MenuPermissions.Nav_PermissionBtns.Nav_Btn",
                                "Nav_MenuPermissions.Nav_PermissionForm",
                                "Nav_Panels.Nav_Panel.Nav_PanelInfo.Nav_Info",
                                "Nav_MenuPermissions.Nav_PermissionColumns.Nav_Column"
                            }).ToList();


                        //var roles = this.GetEntities<T_FM_ROLE>(i => i.ORG_ID == orgId);
                        //roles = roles.Where(t => roleIds.Contains(t.ID) && t.ENABLE_STATUS == 0).ToList();

                        //List<T_FM_ROLE_MENU_PERM> nav_MenuPermissions = new List<T_FM_ROLE_MENU_PERM>();

                        //foreach (var s in roleIds)
                        //{
                        //    var roleMenuPerm = this.GetEntitiesByRedis<T_FM_ROLE_MENU_PERM>(i => i.ORG_ID == def.ORG_ID, new BaseFilter(), s.ToString());
                        //    nav_MenuPermissions.AddRange(roleMenuPerm);
                        //}

                        //nav_MenuPermissions = nav_MenuPermissions.Where(i => roleIds.Contains(i.ROLE_ID)).ToList();

                        //var nav_Panels = this.GetEntitiesByRedis<T_FM_PANEL_BELONG_ROLE>(def.ORG_ID ?? Guid.Empty);
                        //nav_Panels = nav_Panels.Where(i => roleIds.Contains(i.BELONG_ROLE_ID)).ToList();

                        //var nav_PermissionBtns = this.GetEntitiesByRedis<T_FM_ROLE_MENU_PERM_BTN>(def.ORG_ID ?? Guid.Empty);
                        //var nav_Btn = this.GetEntitiesByRedis<T_PF_BTN>(def.ORG_ID ?? Guid.Empty);
                        //var nav_PermissionForm = this.GetEntitiesByRedis<T_PF_FORM>(def.ORG_ID ?? Guid.Empty);
                        //var nav_Panel = this.GetEntitiesByRedis<T_FM_PANEL>(def.ORG_ID ?? Guid.Empty);
                        //var nav_PanelInfo = this.GetEntitiesByRedis<T_FM_PANEL_INFO>(def.ORG_ID ?? Guid.Empty);
                        //var nav_Info = this.GetEntitiesByRedis<T_FM_INFO>(def.ORG_ID ?? Guid.Empty);
                        //var nav_PermissionColumns = this.GetEntitiesByRedis<T_FM_ROLE_MENU_PERM_COL>(def.ORG_ID ?? Guid.Empty);
                        //var nav_Column = this.GetEntitiesByRedis<T_PF_COLUMN>(def.ORG_ID ?? Guid.Empty);
                        //// "Nav_Panels.Nav_Panel.Nav_PanelInfo.Nav_Info"
                        //foreach (var p in nav_Panels)
                        //{
                        //    p.Nav_Panel = nav_Panel.FirstOrDefault(i => i.ID == p.PANEL_ID);
                        //    if (p.Nav_Panel != null)
                        //        p.Nav_Panel.Nav_PanelInfo = nav_PanelInfo.Where(i => i.PANEL_ID == p.PANEL_ID).ToList();
                        //    if (p.Nav_Panel.Nav_PanelInfo.Any())
                        //    {
                        //        foreach (var info in p.Nav_Panel.Nav_PanelInfo)
                        //        {
                        //            info.Nav_Info = nav_Info.FirstOrDefault(i => i.ID == info.INFO_ID);
                        //        }
                        //    }
                        //}
                        ////"Nav_MenuPermissions.Nav_PermissionBtns.Nav_Btn";"Nav_Panels.Nav_Panel.Nav_PanelInfo.Nav_Info"
                        ////"Nav_MenuPermissions.Nav_PermissionColumns.Nav_Column"
                        //foreach (var p in nav_MenuPermissions)
                        //{
                        //    p.Nav_PermissionBtns = nav_PermissionBtns.Where(i => i.ROLE_MENU_PERMISSION_ID == p.ID).ToList();
                        //    if (p.Nav_PermissionBtns.Any())
                        //    {
                        //        foreach (var btn in p.Nav_PermissionBtns)
                        //        {
                        //            btn.Nav_Btn = nav_Btn.FirstOrDefault(i => i.ID == btn.BTN_ID);
                        //        }
                        //    }
                        //    p.Nav_PermissionForm = nav_PermissionForm.FirstOrDefault(i => i.ID == p.PERMISSION_FORM_ID);

                        //    //Nav_Column
                        //    p.Nav_PermissionColumns = nav_PermissionColumns.Where(i => i.ROLE_MENU_PERMISSION_ID == p.ID).ToList();
                        //    if (p.Nav_PermissionColumns.Any())
                        //    {
                        //        foreach (var col in p.Nav_PermissionColumns)
                        //        {
                        //            col.Nav_Column = nav_Column.FirstOrDefault(i => i.ID == col.COLUMN_ID);
                        //        }
                        //    }
                        //}



                        ////因MySQL 不支持多个列表的导航取值，这里对Nav_MenuPermissions.Nav_PermissionColumns特殊处理

                        //var tempRoles = this.GetEntities<T_FM_ROLE>(t => roleIds.Contains(t.ID) && t.ENABLE_STATUS == 0,
                        //             new string[] { "Nav_MenuPermissions.Nav_PermissionColumns.Nav_Column" }).ToList();
                        userRoleModel.Roles = roles;
                        var menuIds = roles.SelectMany(i => i.Nav_MenuPermissions).Select(i => i?.MENU_ID).Distinct().ToList();
                        //var filter = new BaseFilter();
                        //filter.SelectField = new string[] { "ID", "MENU_ID", "BTN_ID", "Nav_Column" };
                        var perBtns = this.GetEntities<T_FM_ROLE_MENU_PERM_BTN>(i => menuIds.Contains(i.MENU_ID)
                           && roleIds.Contains(i.ROLE_ID ?? Guid.Empty), filter, "Nav_Btn");
                        //filter.SelectField = new string[] { "ID", "MENU_ID", "COLUMN_ID", "Nav_Column.IS_RULE",
                        //    "Nav_Column.FIELD_NAME", "Nav_Column.LABEL", "Nav_Column.PAGE_TABLE_ID", "Nav_Column.IS_DEFAULT",
                        //     "Nav_Column.NUM", "Nav_Column.WIDTH", "Nav_Column.PAGE_TABLE_ID", "Nav_Column.IS_DEFAULT",
                        //      "Nav_Column.FIELD_NAME", "Nav_Column.LABEL", "Nav_Column.PAGE_TABLE_ID", "Nav_Column.IS_DEFAULT",
                        //    "Nav_Column.DATA_TYPE","Nav_Column.NO_SORT","Nav_Column.CONTROL_TYPE", "Nav_Column.VALIDATA_TYPE","Nav_Column.FORMAT","Nav_Column.ENUM" };
                        var perColumns = this.GetEntities<T_FM_ROLE_MENU_PERM_COL>(i => menuIds.Contains(i.MENU_ID)
                        && roleIds.Contains(i.ROLE_ID ?? Guid.Empty), filter, "Nav_Column");
                        if (!roles.Any(x => x.ROLE_TYPE == (int)PFUserTypeEnum.管理员))
                        {
                            foreach (var item in roles)
                            {
                                //表单授权
                                if (item.Nav_MenuPermissions != null && item.Nav_MenuPermissions.Any())
                                {
                                    //var tempRole = tempRoles.FirstOrDefault(t => t.ID == item.ID);

                                    foreach (var menu in item.Nav_MenuPermissions)
                                    {
                                        //if (!menu.IS_PERMISSION || menu.Nav_PermissionForm == null || menu.Nav_PermissionForm.ENABLE_STATUS == 1) continue;
                                        if (!menu.IS_PERMISSION || menu.Nav_PermissionForm == null) continue;
                                        var form = rolePerm.Nav_RolePermForms.Where(t => t.MenuId == menu.MENU_ID.ToString() && t.PermFormId == menu.PERMISSION_FORM_ID.ToString()).FirstOrDefault();
                                        if (form == null)
                                        {
                                            form = new PermMenuDto();
                                            form.PermFormId = menu.PERMISSION_FORM_ID.ToString();
                                            form.MenuId = menu.MENU_ID?.ToString();
                                            //form.Nav_PermForm = menu.Nav_PermissionForm;
                                            rolePerm.Nav_RolePermForms.Add(form);
                                        }
                                        //按钮
                                        if (perBtns != null && perBtns.Any())
                                        {
                                            perBtns.ForEach(t =>
                                            {
                                                if (t.MENU_ID.ToString() == form.MenuId)
                                                {
                                                    if (!form.Nav_Btns.Any(t1 => t1.BtnId == t.BTN_ID.ToString() && t1.MenuId == t.MENU_ID.ToString()))
                                                    {
                                                        BtnDto btn = new BtnDto();
                                                        btn.BtnId = t.BTN_ID.ToString();
                                                        btn.MenuId = t.MENU_ID?.ToString();
                                                        //btn.Nav_Btn = t.Nav_Btn;
                                                        form.Nav_Btns.Add(btn);
                                                    }
                                                }

                                            });
                                        }
                                        //列
                                        if (perColumns != null && perColumns.Any())
                                        {
                                            perColumns.ForEach(t =>
                                            {
                                                if (t.MENU_ID.ToString() == form.MenuId)
                                                {
                                                    if (!form.Nav_Columns.Any(t1 => t1.ColumnId == t.COLUMN_ID.ToString() && t1.MenuId == t.MENU_ID.ToString()))
                                                    {
                                                        ClumnDto col = new ClumnDto();
                                                        col.ColumnId = t.COLUMN_ID.ToString();
                                                        col.MenuId = t.MENU_ID?.ToString();
                                                        //col.Nav_Column = t.Nav_Column;
                                                        form.Nav_Columns.Add(col);
                                                    }
                                                }
                                            });
                                        }

                                    }
                                }


                                //工作中心授权
                                //if (item.Nav_Workstages != null && item.Nav_Workstages.Any())
                                //{
                                //foreach (var workstate in item.Nav_Workstages)
                                //{
                                //	if (!workstate.IS_PERMISSION) continue;
                                //	if (workstate.Nav_Workstage == null || workstate.Nav_Workstage.ENABLE_STATUS == 1) continue;
                                //	if (!rolePerm.Nav_RolePermWorkStages.Any(t => t.WorkstageId == workstate.WORKSTAGE_ID))
                                //	{
                                //		RolePermWorkStage tmp = new RolePermWorkStage();
                                //		tmp.WorkstageId = workstate.WORKSTAGE_ID;
                                //		tmp.Nav_WorkStage = workstate.Nav_Workstage;
                                //		rolePerm.Nav_RolePermWorkStages.Add(tmp);
                                //	}
                                //}
                                //}

                                //区域授权
                                //if (item.Nav_Panels != null && item.Nav_Panels.Any())
                                //{
                                //    foreach (var panel in item.Nav_Panels)
                                //    {
                                //        if (panel.Nav_Panel == null || panel.Nav_Panel.ENABLE_STATUS == 1) continue;
                                //        if (!rolePerm.Nav_RolePermPanels.Any(t => t.PanelId == panel.PANEL_ID))
                                //        {
                                //            RolePermPanel tmp = new RolePermPanel();
                                //            tmp.PanelId = panel.PANEL_ID;
                                //            tmp.Nav_Panel = panel.Nav_Panel;
                                //            rolePerm.Nav_RolePermPanels.Add(tmp);
                                //        }
                                //    }
                                //}
                            }
                        }
                    }
                    //清空导航
                    user.Nav_BelongRoleGroups = null;
                    user.Nav_BelongRoles = null;
                    user.Nav_BelongUserGroups = null;
                    result.Add(userRoleModel);
                }
                return result;
            }
            catch (Exception ex)
            {
                throw new Exception(LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message);
            }
        }

        public UserRoleModel NewGetRolesByUser(Guid userId, KeywordFilter filter)
        {
            try
            {

                var newUser = this.GetEntity<T_FM_USER>(userId, new string[] { "Nav_Org", "Nav_Department" });
                //var newUser = this.GetEntities<T_FM_USER>(t => userId == t.ID, filter, new string[] { "Nav_Org", "Nav_Department" }).FirstOrDefault();
                var newFilter = new BaseFilter(filter.GetOrgId());
                newFilter.SelectField = new string[] { "ID", "ROLE_TYPE", "PLATFORM_TYPE" };
                var rolesa = this.GetEntities<T_FM_ROLE>(i => i.Nav_UserBelongRoles.Any(i => i.USER_ID == userId) && i.PLATFORM_TYPE == Convert.ToInt32(filter.Parameter3), newFilter);
                UserRoleModel userRoleModel = new UserRoleModel();
                userRoleModel.User = newUser;
                userRoleModel.Roles = rolesa.ToList();
                if (rolesa.Any(i => i.ROLE_TYPE == (int)FMRoleTypeEnum.管理角色))
                {

                }
                else
                {

                    if (rolesa.Any())
                    {
                        var rolesId = rolesa.Select(i => i.ID).ToArray();
                        RolePerm rolePerm = new RolePerm();
                        userRoleModel.Nav_RolePerm = rolePerm;
                        newFilter.SelectField = new string[] { "ID", "MENU_ID", "IS_PERMISSION", "PERMISSION_FORM_ID" };
                        var menuPer = this.GetEntities<T_FM_ROLE_MENU_PERM>(i => rolesId.Contains(i.ROLE_ID), newFilter);
                        userRoleModel.Roles.FirstOrDefault().Nav_MenuPermissions = menuPer.ToList();
                        var menuPerIds = menuPer.Select(i => i.ID).ToArray();
                        var menuFormIds = menuPer.Select(i => i.PERMISSION_FORM_ID).ToArray();
                        var menuIds = menuPer.Select(i => i?.MENU_ID).Distinct().ToList();

                        newFilter.SelectField = new string[] { "ID", "MENU_ID", "Nav_Btn.ID" };
                        var perBtns = this.GetEntities<T_FM_ROLE_MENU_PERM_BTN>(i => menuIds.Contains(i.MENU_ID)
                           && rolesId.Contains(i.ROLE_ID ?? Guid.Empty) && i.Nav_Btn.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, newFilter, "Nav_Btn");

                        newFilter.SelectField = new string[] { "ID", "MENU_ID", "Nav_Column.ID" };
                        var perColumns = this.GetEntities<T_FM_ROLE_MENU_PERM_COL>(i => menuIds.Contains(i.MENU_ID)
                        && rolesId.Contains(i.ROLE_ID ?? Guid.Empty) && i.Nav_Column.IS_DEFAULT, newFilter, "Nav_Column");

                        newFilter.SelectField = new string[] { "ID", "CODE" };
                        var perForms = this.GetEntities<T_PF_FORM>(i => menuFormIds.Contains(i.ID), newFilter);
                        //表单授权
                        foreach (var menu in menuPer)
                        {
                            //if (!menu.IS_PERMISSION) continue;
                            if (menu.PERMISSION_FORM_ID != null)
                            {
                                var form = rolePerm.Nav_RolePermForms.FirstOrDefault(t => t.MenuId == menu.MENU_ID.ToString() && t.PermFormId == menu.PERMISSION_FORM_ID.ToString());
                                if (form == null)
                                {
                                    form = new PermMenuDto();
                                    form.PermFormId = menu.PERMISSION_FORM_ID.ToString();
                                    form.MenuId = menu.MENU_ID?.ToString();
                                    //form.Nav_PermForm = perForms.FirstOrDefault(i => i.ID == menu.PERMISSION_FORM_ID);
                                    rolePerm.Nav_RolePermForms.Add(form);
                                    //按钮
                                    var btns = perBtns.Where(i => i.MENU_ID == menu.MENU_ID);
                                    if (btns != null && btns.Any())
                                    {
                                        btns.ForEach(t =>
                                        {
                                            if (!form.Nav_Btns.Any(t1 => t1.BtnId == t.BTN_ID.ToString() && t1.MenuId == t.MENU_ID.ToString()))
                                            {
                                                BtnDto btn = new BtnDto();
                                                btn.BtnId = t.BTN_ID.ToString();
                                                btn.MenuId = t.MENU_ID?.ToString();
                                                //btn.Nav_Btn = t.Nav_Btn;
                                                form.Nav_Btns.Add(btn);
                                            }


                                        });
                                    }
                                    //列
                                    var columns = perColumns.Where(i => i.MENU_ID == menu.MENU_ID);
                                    if (columns != null && columns.Any())
                                    {
                                        columns.ForEach(t =>
                                        {
                                            if (!form.Nav_Columns.Any(t1 => t1.ColumnId == t.COLUMN_ID.ToString() && t1.MenuId == t.MENU_ID.ToString()))
                                            {
                                                ClumnDto col = new ClumnDto();
                                                col.ColumnId = t.COLUMN_ID.ToString();
                                                col.MenuId = t.MENU_ID?.ToString();
                                                //col.Nav_Column = t.Nav_Column;
                                                form.Nav_Columns.Add(col);
                                            }
                                        });
                                    }
                                }
                            }

                        }



                    }
                }


                return userRoleModel;
            }
            catch (Exception ex)
            {
                throw new Exception(LogHelper.GetCurSourceFileName() + " - " + LogHelper.GetLineNum() + ":" + ex.Message);
            }
        }
        /// <summary>
        /// 通过角色获取人员列表
        /// </summary>
        /// <param name="roleIds"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public List<T_FM_USER> GetUsersByRoles(IEnumerable<string> roleIds, Guid? orgId)
        {
            //var roleService = ServiceUtils.GetCommonService<T_FM_ROLE>();
            //var roleGroupService = ServiceUtils.GetCommonService<T_FM_ROLE_GROUP>();
            //var userGroupService = ServiceUtils.GetCommonService<T_FM_USER_GROUP>();

            Expression<Func<T_FM_USER, bool>> userExpression = t => false;
            Expression<Func<T_FM_ROLE_GROUP, bool>> roleGroupExpression = t => false;
            Expression<Func<T_FM_USER_GROUP, bool>> userGroupExpression = t => false;

            foreach (var item in roleIds)
            {
                Guid tmp = new Guid(item);
                userExpression = userExpression.Or(t => t.Nav_BelongRoles.Any(i => i.BELONG_ROLE_ID == tmp));
                roleGroupExpression = roleGroupExpression.Or(t => t.Nav_BelongRoles.Any(i => i.BELONG_ROLE_ID == tmp));
                userGroupExpression = userGroupExpression.Or(t => t.Nav_BelongRoles.Any(i => i.BELONG_ROLE_ID == tmp));
            }
            roleGroupExpression = roleGroupExpression.And(t => t.ENABLE_STATUS == 0);
            var roleGroupIds = this.GetEntities<T_FM_ROLE_GROUP>(roleGroupExpression, new string[] { "Nav_BelongRoles.Nav_BelongRole" }).Select(t => t.ID).ToList();
            if (roleGroupIds != null && roleGroupIds.Any())
            {
                foreach (var item in roleGroupIds)
                {
                    userExpression = userExpression.Or(t => t.Nav_BelongRoleGroups.Any(i => i.BELONG_ROLE_GROUP_ID == item));
                    userGroupExpression = userGroupExpression.Or(t => t.Nav_BelongRoleGroups.Any(i => i.BELONG_ROLE_GROUP_ID == item));
                }
            }
            userGroupExpression = userGroupExpression.And(t => t.ENABLE_STATUS == 0);
            var userGroupList = this.GetEntities<T_FM_USER_GROUP>(userGroupExpression, new string[] { "Nav_BelongRoles.Nav_BelongRole", "Nav_BelongRoleGroups.Nav_BelongRoleGroup", "Nav_BelongUserGroups.Nav_BelongUserGroup" }).Select(t => t.ID).ToList();
            if (userGroupList.Any())
            {
                List<Guid> userGroupIds = new List<Guid>();
                Expression<Func<T_FM_USER_GROUP, bool>> tmpExpression = t => true;
                if (orgId != null)
                    tmpExpression = tmpExpression.And(t => t.ORG_ID == orgId);
                tmpExpression = tmpExpression.And(t => t.ENABLE_STATUS == 0);
                var tmpUserGroupList = this.GetEntities(tmpExpression, new string[] { "Nav_BelongRoles.Nav_BelongRole", "Nav_BelongRoleGroups.Nav_BelongRoleGroup", "Nav_BelongUserGroups.Nav_BelongUserGroup" }).ToList();
                GetUserGroups(userGroupList, userGroupIds, tmpUserGroupList);
                if (userGroupIds.Any())
                {
                    foreach (var item in userGroupIds)
                        userExpression = userExpression.Or(t => t.Nav_BelongUserGroups.Any(i => i.BELONG_USER_GROUP_ID == item));
                }
            }
            userExpression = userExpression.And(t => t.ENABLE_STATUS == 0);
            return this.GetEntities(userExpression, new string[] { "Nav_BelongRoles.Nav_BelongRole", "Nav_BelongRoleGroups.Nav_BelongRoleGroup", "Nav_BelongUserGroups.Nav_BelongUserGroup" }).ToList();
        }

        #region 私有方法
        private void GetRoleByStr(List<Guid> list, List<Guid> roleIds)
        {
            if (list == null || list.Count <= 0) return;
            foreach (var item in list)
            {
                if (!roleIds.Contains(item))
                    roleIds.Add(item);
            }
        }

        private void GetRoleByRoleGroupStr(Guid? orgId, List<Guid> list, List<Guid> roleIds, ref List<T_FM_ROLE_GROUP> roleGroupList)
        {
            if (list == null || list.Count <= 0) return;

            if (roleGroupList == null)
            {
                //Expression<Func<T_FM_ROLE_GROUP, bool>> expression = t => true;
                //if (orgId != null)
                //    expression = expression.And(t => t.ORG_ID == orgId);
                //expression = expression.And(t => t.ENABLE_STATUS == 0);
                //roleGroupList = this.GetEntities<T_FM_ROLE_GROUP>(expression, new string[] { "Nav_BelongRoles.Nav_BelongRole" }).ToList();
                //
                var baseFilter = new BaseFilter(orgId ?? Guid.Empty);
                baseFilter.IgnoreDataRule = true;
                roleGroupList = this.GetEntitiesByRedis<T_FM_ROLE_GROUP>(baseFilter);
                roleGroupList = roleGroupList.Where(t => t.ENABLE_STATUS == 0).ToList();
                var belongRules = this.GetEntitiesByRedis<T_FM_ROLE_GROUP_BELONG_ROLE>(baseFilter);
                var belongRule = this.GetEntitiesByRedis<T_FM_ROLE>(baseFilter);
                foreach (var role in belongRules)
                {
                    role.Nav_BelongRole = belongRule.FirstOrDefault(i => i.ID == role.BELONG_ROLE_ID);
                }
                foreach (var role in roleGroupList)
                {
                    role.Nav_BelongRoles = belongRules.Where(i => i.ROLE_GROUP_ID == role.ID).ToList();
                }
            }
            foreach (var s in list)
            {
                var rg = roleGroupList.Where(t => t.ID == s).FirstOrDefault();
                if (rg != null)
                {
                    if (rg.Nav_BelongRoles != null && rg.Nav_BelongRoles.Any())
                    {
                        var tmpList = rg.Nav_BelongRoles.Select(t => t.BELONG_ROLE_ID).ToList();
                        GetRoleByStr(tmpList, roleIds);
                    }
                }
            }
        }

        private void GetRoleByUserGroup(Guid? orgId, Guid userGroupId, Dictionary<Guid, byte> existsUserGroupIds,
            ref List<T_FM_USER_GROUP> userGroupList, ref List<T_FM_ROLE_GROUP> roleGroupList, List<Guid> roleIds)
        {
            if (userGroupList == null)
            {
                //Expression<Func<T_FM_USER_GROUP, bool>> expression = t => true;
                //if (orgId != null)
                //    expression = expression.And(t => t.ORG_ID == orgId);
                //expression = expression.And(t => t.ENABLE_STATUS == 0);
                //userGroupList = this.GetEntities<T_FM_USER_GROUP>(expression, new string[] { "Nav_BelongRoles.Nav_BelongRole",
                //    "Nav_BelongRoleGroups.Nav_BelongRoleGroup", 
                //    "Nav_BelongUserGroups.Nav_BelongUserGroup" }).ToList();
                var baseFilter = new BaseFilter(orgId ?? Guid.Empty);
                baseFilter.IgnoreDataRule = true;
                userGroupList = this.GetEntitiesByRedis<T_FM_USER_GROUP>(baseFilter);
                userGroupList = userGroupList.Where(t => t.ENABLE_STATUS == 0).ToList();

                var nav_BelongRoles = this.GetEntitiesByRedis<T_FM_USER_GROUP_BELONG_ROLE>(baseFilter);
                var nav_BelongRoleGroups = this.GetEntitiesByRedis<T_FM_USER_GROUP_BELONG_R_G>(baseFilter);
                var nav_BelongUserGroups = this.GetEntitiesByRedis<T_FM_USER_GROUP_BELONG_U_G>(baseFilter);

                var belongRule = this.GetEntitiesByRedis<T_FM_ROLE>(baseFilter);
                var belongRoleGroup = this.GetEntitiesByRedis<T_FM_ROLE_GROUP>(baseFilter);
                var belonUserGroup = this.GetEntitiesByRedis<T_FM_USER_GROUP>(baseFilter);

                foreach (var role in nav_BelongRoles)
                {
                    role.Nav_BelongRole = belongRule.FirstOrDefault(i => i.ID == role.BELONG_ROLE_ID);
                }
                foreach (var role in nav_BelongRoleGroups)
                {
                    role.Nav_BelongRoleGroup = belongRoleGroup.FirstOrDefault(i => i.ID == role.BELONG_ROLE_GROUP_ID);
                }
                foreach (var role in nav_BelongUserGroups)
                {
                    role.Nav_BelongUserGroup = belonUserGroup.FirstOrDefault(i => i.ID == role.BELONG_USER_GROUP_ID);
                }

                foreach (var u in userGroupList)
                {
                    u.Nav_BelongRoles = nav_BelongRoles.Where(i => i.BELONG_ROLE_ID == u.ID).ToList();
                    u.Nav_BelongRoleGroups = nav_BelongRoleGroups.Where(i => i.BELONG_ROLE_GROUP_ID == u.ID).ToList();
                    u.Nav_BelongUserGroups = nav_BelongUserGroups.Where(i => i.BELONG_USER_GROUP_ID == u.ID).ToList();
                }

            }

            if (userGroupList == null || userGroupList.Count <= 0) return;
            var userGroup = userGroupList.Where(t => t.ID == userGroupId).FirstOrDefault();
            if (userGroup == null) return;
            if (existsUserGroupIds.ContainsKey(userGroup.ID)) return;
            existsUserGroupIds.Add(userGroup.ID, 0);
            if (userGroup.Nav_BelongRoles != null && userGroup.Nav_BelongRoles.Any())
            {
                var list = userGroup.Nav_BelongRoles.Select(t => t.BELONG_ROLE_ID).ToList();
                GetRoleByStr(list, roleIds);
            }

            if (userGroup.Nav_BelongRoleGroups != null && userGroup.Nav_BelongRoleGroups.Any())
            {
                var list = userGroup.Nav_BelongRoleGroups.Select(t => t.BELONG_ROLE_GROUP_ID).ToList();
                GetRoleByRoleGroupStr(orgId, list, roleIds, ref roleGroupList);
            }

            if (userGroup.Nav_BelongUserGroups != null && userGroup.Nav_BelongUserGroups.Any())
            {
                var list = userGroup.Nav_BelongUserGroups.Select(t => t.BELONG_USER_GROUP_ID).ToList();
                foreach (var s in list)
                    GetRoleByUserGroup(orgId, s, existsUserGroupIds, ref userGroupList,
                        ref roleGroupList, roleIds);
            }
        }
        private void GetUserGroups(List<Guid> ids, List<Guid> resultList, List<T_FM_USER_GROUP> tmpUserGroupList)
        {
            if (ids == null || ids.Count <= 0) return;
            resultList.AddRange(ids);
            var list = tmpUserGroupList.Where(t => t.Nav_BelongUserGroups.Any(t1 => ids.Contains(t1.BELONG_USER_GROUP_ID))).Select(t => t.ID).ToList();
            if (list.Any())
            {
                List<Guid> tmps = new List<Guid>();
                foreach (var item in list)
                {
                    if (!resultList.Any(t => t == item))
                        tmps.Add(item);
                }
                if (tmps.Count > 0)
                    GetUserGroups(tmps, resultList, tmpUserGroupList);
            }

        }
        #endregion

        #region      wyw

        /// <summary>
        /// 获取部门节点下所有人员信息
        /// </summary>
        /// <param name="BaseDepartMentID"></param>
        /// <returns></returns>
        public List<T_FM_USER> GetDownUser(Guid BaseDepartMentID, string[] UserParts = null)
        {
            List<T_FM_DEPARTMENT> listTemp = null;
            List<Guid> listDepartMentID = new List<Guid>();
            List<Guid> listDepartMentIDAll = new List<Guid>();

            var listDep = GetEntities<T_FM_DEPARTMENT>(e => e.ID == BaseDepartMentID, null, new string[] { "Nav_Children" });
            if (listDep.Any())
            {
                listTemp = listDep.ToList();
                listDepartMentID = listTemp.Select(x => x.ID).ToList();
                listDepartMentIDAll = listTemp.Select(x => x.ID).ToList();
            }
            else
            {
                return null;
            }
            IEnumerable<T_FM_DEPARTMENT> listDeps = null;
            IEnumerable<T_FM_DEPARTMENT> listTempChil = null;
            do
            {
                listDeps = GetEntities<T_FM_DEPARTMENT>(e => e.PARENT_ID.HasValue && listDepartMentID.Contains(e.PARENT_ID.Value), null, new string[] { "Nav_Children" });
                if (listDeps.Any())
                {
                    listTemp = listDeps.ToList();
                    listDepartMentID = listTemp.Select(x => x.ID).ToList();
                    listDepartMentIDAll.AddRange(listDepartMentID);
                    listTempChil = listDeps.Where(e => e.Nav_Children != null && e.Nav_Children.Count > 0);
                }
                else
                {
                    listTempChil = null;
                }
            } while (listTempChil != null && listTempChil.Any());
            if (UserParts == null)
            {
                UserParts = new string[] { "Nav_Department" };
            }
            return GetEntities<T_FM_USER>(e => listDepartMentIDAll.Contains(e.DEPARTMENT_ID.Value) && e.ENABLE_STATUS == 0 && !e.IS_DELETED, null, UserParts).OrderBy(e => e.Nav_Department.DEPARTMENT_TYPE).ThenByDescending(e => e.APPROVE_ROLE_ID).ToList();

        }

        /// <summary>
        /// 获取组织成员和下属有审批角色的人（负责人、安全员）
        /// </summary>
        /// <param name="DepartMentID"></param>
        /// <returns></returns>
        public List<T_FM_USER> GetUserContentNextHead(Guid DepartMentID)
        {
            List<T_FM_USER> listUser = new List<T_FM_USER>();
            var userDep = GetEntities<T_FM_USER>(e => e.DEPARTMENT_ID.HasValue && e.DEPARTMENT_ID.Value == DepartMentID && e.ENABLE_STATUS == 0, "Nav_Department", "Nav_Person.Nav_Post");
            if (userDep != null && userDep.Any())
                listUser = userDep.OrderByDescending(e => e.APPROVE_ROLE_ID).ToList();
            else
                return listUser;

            var depChilID = GetEntities<T_FM_DEPARTMENT>(e => e.PARENT_ID.HasValue && e.PARENT_ID.Value == DepartMentID).Select(e => e.ID);
            if (depChilID == null || !depChilID.Any())
                return listUser;

            var listChilUser = GetEntities<T_FM_USER>(e => e.DEPARTMENT_ID.HasValue && depChilID.Contains(e.DEPARTMENT_ID.Value) && e.ENABLE_STATUS == 0 && e.APPROVE_ROLE_ID.HasValue, "Nav_Department", "Nav_Person.Nav_Post");
            if (listChilUser == null || !listChilUser.Any())
                return listUser;

            listUser.AddRange(listChilUser.OrderBy(e => e.DEPARTMENT_ID).ToList());
            return listUser;
        }

        /// <summary>
        /// 获取登陆者的生产单元
        /// </summary>
        /// <returns></returns>
        public List<int> GetMineType(string minType = null)
        {
            List<int> listResult = new List<int>();
            if (minType == null)
            {
                minType = APT.Infrastructure.Api.AppContext.CurrentSession.MineType;
            }

            try
            {
                if (string.IsNullOrEmpty(minType))
                {

                }
                else if (minType.Contains(","))
                {
                    var listMine = minType.Split(",", StringSplitOptions.RemoveEmptyEntries);
                    if (listMine != null && listMine.Any())
                    {
                        listMine.ForEach(x => listResult.Add(int.Parse(x)));
                    }
                }
                else
                {
                    listResult.Add(int.Parse(minType));
                }
            }
            catch { }

            return listResult;
        }


        /// <summary>
        /// 获取登陆者的生产单元
        /// </summary>
        /// <returns></returns>
        public List<string> GetDepmentMineType()
        {
            List<string> listResult = new List<string>();
            string minType = APT.Infrastructure.Api.AppContext.CurrentSession.MineType;

            if (string.IsNullOrEmpty(minType))
            {

            }
            else if (minType.Contains(","))
            {
                var listMine = minType.Split(",", StringSplitOptions.RemoveEmptyEntries);
                if (listMine != null && listMine.Any())
                {
                    listMine.ForEach(x => listResult.Add(x));
                }
            }
            else
            {
                listResult.Add(minType);
            }

            return listResult;
        }



        #endregion


        /// <summary>
        /// 获取特定岗位的人
        /// </summary>
        /// <param name="Msg"></param>
        /// <param name="postName"></param>
        /// <returns></returns>
        public T_FM_USER GetPostUser(ref string Msg, string postName = "人事专员")
        {
            var post = GetEntity<T_FM_USER_POST>(e => e.NAME.Contains(postName));
            if (post == null)
            {
                Msg = "未找到岗位【" + postName + "】";
                return null;
            }
            T_FM_USER user = GetEntity<T_FM_USER>(e => e.Nav_Person.POST_ID == post.ID, new string[] { "Nav_Person" });
            if (user == null)
            {
                Msg = "系统未配置【" + postName + "】岗位人员";
            }
            return user;
        }

        /// <summary>
        /// 获取某个（部门）审批角色对应人
        /// </summary>
        /// <param name="Msg"></param>
        /// <param name="RoleName"></param>
        /// <param name="DEPARTMENT_ID"></param>
        /// <param name="DEPARTMENT_TYPE">FMDepartmentType 部门=0,  车间=1,   班组=2,  公司=3</param>
        /// <returns></returns>
        public T_FM_USER GetRoleUser(ref string Msg, string RoleName, Guid? DEPARTMENT_ID, int? DEPARTMENT_TYPE)
        {
            T_FM_USER result = null;
            var approveRole = GetEntity<T_PF_APPROVAL_ROLE>(e => e.NAME.Contains(RoleName));
            if (approveRole != null)
            {
                Expression<Func<T_FM_USER, bool>> expression = e => e.APPROVE_ROLE_ID == approveRole.ID;
                if (DEPARTMENT_ID.HasValue && DEPARTMENT_ID != Guid.Empty)
                {
                    if (DEPARTMENT_TYPE.HasValue)
                    {
                    again:
                        var dep = GetEntity<T_FM_DEPARTMENT>(e => e.ID == DEPARTMENT_ID.Value, new string[] { "Nav_Parent" });
                        if (dep == null)
                        {
                            Msg = "获取部门失败";
                            return result;
                        }
                        else
                        {
                            if (dep.DEPARTMENT_TYPE == DEPARTMENT_TYPE)
                            {
                                DEPARTMENT_ID = dep.ID;
                            }
                            else if (dep.Nav_Parent != null && dep.Nav_Parent.DEPARTMENT_TYPE == DEPARTMENT_TYPE)
                            {
                                DEPARTMENT_ID = dep.PARENT_ID;
                            }
                            else
                            {
                                if (dep.PARENT_ID.HasValue)
                                {
                                    DEPARTMENT_ID = dep.PARENT_ID;
                                    goto again;
                                }
                                else
                                {
                                    Msg = "获取部门失败";
                                    return result;
                                }

                            }
                        }
                    }

                    expression = expression.And(e => e.DEPARTMENT_ID.HasValue && e.DEPARTMENT_ID == DEPARTMENT_ID);
                }
                result = GetEntity<T_FM_USER>(expression);
            }
            else
            {
                Msg = "未找到审批角色【" + RoleName + "】";
            }
            return result;
        }


        /// <summary>
        /// 获取部门岗位人员
        /// </summary>
        /// <param name="Msg"></param>
        /// <param name="DEPARTMENT_ID"></param>
        /// <param name="POST_ID"></param>
        /// <param name="IsOnly">只返回一个人</param>
        /// <returns></returns>
        public List<T_FM_USER> GetDepPostUser(ref string Msg, Guid DEPARTMENT_ID, Guid POST_ID, bool IsOnly)
        {
            if (DEPARTMENT_ID == Guid.Empty || POST_ID == Guid.Empty)
            {
                Msg = "入参有误";
                return null;
            }

            var listPerson = GetEntities<T_FM_PERSON>(e => e.DEPARTMENT_ID.HasValue && e.DEPARTMENT_ID.Value == DEPARTMENT_ID && e.POST_ID.HasValue && e.POST_ID.Value == POST_ID);
            if (listPerson == null || !listPerson.Any())
            {
                Msg = "后勤部门岗位人员信息失败";
            }
            Expression<Func<T_FM_USER, bool>> expression = e => !e.IS_DELETED && e.PERSON_ID.HasValue && e.ENABLE_STATUS == 0;
            var listPersonID = listPerson.Select(e => e.ID);
            if (IsOnly || listPersonID.Count() == 1)
            {
                Guid personID = listPersonID.ToList()[0];
                expression = expression.And(e => e.PERSON_ID.Value == personID);
            }
            else
            {
                expression = expression.And(e => listPersonID.Contains(e.PERSON_ID.Value));
            }
            return GetEntities(expression).ToList();
        }
    }
}
