using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.Msg;
using APT.Infrastructure.Core;
using APT.MS.Domain.ApiModel;

using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.IServices.FM;
using APT.Utility;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.IdentityModel.Tokens;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Threading;

using APT.Utility;
using APT.BaseData.Domain.ApiModel;
using APT.PF.WebApi.Models;
using APT.Infrastructure.Api.Redis;
using APT.BaseData.Domain.Enums.PF;
using Newtonsoft.Json;
using APT.BaseData.Domain.Entities.NW;
using APT.Infrastructure.Api;
using IdentityModel.Client;
using System.Threading.Tasks;
using APT.MS.Domain.ApiModel.PF;
using APT.MS.Domain.Entities.BI;

namespace APT.PF.WebApiControllers.Api.PF
{
    /// <summary>登入</summary>
    [Route("api/PF/Login")]
    public class LoginController : CommonApiController
    {
        private const string SUPER_PASSWORD = "@MH!20220101";
        [HttpGet, Route("InitDataBase")]
        public JsonActionResult<bool> InitDataBase()
        {
            return SafeExecute<bool>(() =>
            {
                var orgEntites = this.GetEntities<T_FM_ORGANIZATION>(null, new BaseFilter());
                if (!orgEntites.Any())
                {
                    T_FM_ORGANIZATION org = new T_FM_ORGANIZATION();
                    org.CODE = "001";
                    org.NAME = "默认组织";
                    this.AddEntity<T_FM_ORGANIZATION>(org);
                }
                var userEntites = this.GetEntities<T_FM_USER>(null, new BaseFilter());
                if (!userEntites.Any())
                {
                    var org = this.GetEntity<T_FM_ORGANIZATION>(t => true);
                    if (org == null)
                        throw new Exception("设置组织");
                    T_FM_USER user = new T_FM_USER();
                    user.CODE = "admin";
                    user.NAME = "Admin";
                    user.ORG_ID = org.ID;
                    user.PASSWORD = "E10ADC3949BA59ABBE56E057F20F883E";//默认密码为123456
                    this.AddEntity<T_FM_USER>(user);
                }
                return true;
            });
        }

        /// <summary>
        /// 获取子菜单
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="m"></param>
        private void GetChildrenMenu(List<T_PF_MENU> menus, UserLoginMenuModel m)
        {
            var tmps = menus.Where(t => t.PARENT_ID == m.Menu.ID).OrderBy(t => t.NUM).ToList();

            if (tmps != null && tmps.Any())
            {
                foreach (var item in tmps)
                {
                    UserLoginMenuModel cm = new UserLoginMenuModel();
                    cm.Menu = item;
                    GetChildrenMenu(menus, cm);
                    if (cm.Menu.MENU_FORM_ID != null || cm.ChildMenus.Count > 0)
                        m.ChildMenus.Add(cm);
                }
            }
        }

        /// <summary>
        /// 获取子菜单
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="m"></param>
        private void GetClientChildrenMenu(List<T_PF_CLIENT_MENU> menus, UserClientLoginMenuModel m, List<T_PF_PAGE_CUSTOM> pageCustoms)
        {
            var tmps = menus.Where(t => t.PARENT_ID == m.Menu.ID).OrderBy(t => t.NUM).ToList();
            if (tmps != null && tmps.Any())
            {
                foreach (var item in tmps)
                {
                    if (item.MENU_FORM_ID != null)
                    {
                        var pageCustom = pageCustoms == null ? null : pageCustoms.Where(t => t.PAGE_FORM_ID == item.MENU_FORM_ID).FirstOrDefault();
                        if (pageCustom != null)
                            item.VIRTUAL_URL = pageCustom.COMPONENT_NAME;//URL
                    }
                    UserClientLoginMenuModel cm = new UserClientLoginMenuModel();
                    cm.Menu = item;
                    GetClientChildrenMenu(menus, cm, pageCustoms);
                    m.ChildMenus.Add(cm);
                }
            }
        }


        /// <summary>
        /// 获取子菜单
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="m"></param>
        /// <param name="pageCustoms"></param>
        private void GetAppChildrenMenu(List<T_PF_APPMENU> menus, UserAppLoginMenuModel m, List<T_PF_PAGE_CUSTOM> pageCustoms)
        {
            var tmps = menus.Where(t => t.PARENT_ID == m.Menu.ID).OrderBy(t => t.NUM).ToList();
            if (tmps != null && tmps.Any())
            {
                foreach (var item in tmps)
                {
                    if (item.MENU_FORM_ID != null)
                    {
                        var pageCustom = pageCustoms == null ? null : pageCustoms.Where(t => t.PAGE_FORM_ID == item.MENU_FORM_ID).FirstOrDefault();
                        if (pageCustom != null)
                            item.VIRTUAL_URL = pageCustom.COMPONENT_NAME;//URL
                    }
                    UserAppLoginMenuModel cm = new UserAppLoginMenuModel();
                    cm.Menu = item;
                    GetAppChildrenMenu(menus, cm, pageCustoms);
                    m.ChildMenus.Add(cm);
                }
            }
        }

        public const string VERFYCODE = "VerifyCode_";

        [HttpPost, Route("OpLogin")]
        public JsonActionResult<bool> OpLogin([FromBody] KeywordFilter filter)
        {
            return SafeExecute<bool>(() =>
            {
                string userCode = filter.Parameter1.ToUpper();
                string userPassword = filter.Parameter2;

                if (string.IsNullOrEmpty(userCode))
                {
                    throw new Exception(ErrMsg.FM_NO_USER);
                }
                if (string.IsNullOrEmpty(userPassword))
                {
                    throw new Exception(ErrMsg.FM_NO_PWD);
                }
                if (userCode != "SUPADMIN")
                {
                    throw new Exception("只允许超级管理员登录");
                }
                var usr = this.GetEntity<T_FM_USER>(i => i.CODE == userCode);
                if (usr == null)
                {
                    throw new Exception("用户不存在");
                }
                if (usr.PASSWORD.ToUpper() != userPassword.ToUpper())
                {
                    throw new Exception("密码不正确");
                }
                return true;
            });
        }
        /// <summary>
        /// 后台登入/APP登录
        /// </summary>
        /// <param name="filter">
        /// Keyword：用户ID
        /// Parameter1：用户Code
        /// Parameter2：密码
        /// Parameter3：平台类型
        /// Parameter4：Orgid
        /// Parameter5：//表单配置版本，取消
        /// Parameter6：手机验证码
        /// Parameter7：随机数
        /// </param>
        /// <returns></returns>
        [HttpPost, Route("Login")]
        public JsonActionResult<UserLoginBaseModel> Login([FromBody] KeywordFilter filter)
        {
            return base.SafeExecute(() =>
            {
                try
                {
                    string telnetCode = Request.Headers["Tenant"];
                    if (string.IsNullOrEmpty(telnetCode))
                    {
                        throw new Exception("企业信息未成功加载，请重试!");
                    }
                    if (filter == null)
                    {
                        throw new Exception("参数为空，请重试!");
                    }
                    var md5SuperPwd = DataHelper.MD5(SUPER_PASSWORD);
                    UserLoginBaseModel result = new UserLoginModel();
                    string userId = filter == null ? string.Empty : filter.Keyword;
                    int platformType = filter == null ? (int)PFPlatTypeEnum.后台 : string.IsNullOrEmpty(filter.Parameter3)
                    ? (int)PFPlatTypeEnum.后台 : Convert.ToInt32(filter.Parameter3);
                    var orgId = new Guid(filter.Parameter4);
                    filter.OrgId = orgId;
                    T_FM_USER user = null;
                    if (platformType == (int)PFPlatTypeEnum.后台)
                    {
                        if (string.IsNullOrEmpty(filter.Parameter4))
                            throw new Exception(ErrMsg.FM_NO_ORG);
                        if (string.IsNullOrEmpty(userId))
                        {
                            string userCode = filter.Parameter1;
                            string userPassword = filter.Parameter2.ToUpper();
                            string userPasswordLower = filter.Parameter2.ToLower();
                            if (string.IsNullOrEmpty(userCode))
                                throw new Exception(ErrMsg.FM_NO_USER);
                            if (string.IsNullOrEmpty(userPassword))
                                throw new Exception(ErrMsg.FM_NO_PWD);
                            var userFilter = new BaseFilter(orgId);
                            userFilter.SelectField = new string[] { "CODE", "DEPARTMENT_ID" };// "Nav_ProdutionUnit.Nav_Enums.VALUE",
                            Expression<Func<T_FM_USER, bool>> uExpress = t => t.CODE == userCode;
                            if (userPassword != md5SuperPwd && userPasswordLower != md5SuperPwd)
                            {
                                uExpress = uExpress.And(t => t.PASSWORD == userPassword || t.PASSWORD == userPasswordLower);
                            }
                            user = this.GetEntity<T_FM_USER>(uExpress, userFilter);
                            if (user == null)
                                throw new Exception(ErrMsg.PM_PSD_ERROR);
                            userId = user.ID.GetString();
                        }
                        #region 手机验证码
                        if (Convert.ToBoolean(filter.Parameter6))
                        {
                            var verCode = CsRedisManager.StringGet<Dictionary<string, string>>(SessionKey.VERIFY_MESSAGE_CODE + userId.ToString());
                            if (verCode == null)
                                throw new Exception("手机验证码不存在!");
                            if (filter.Parameter7.ToUpper() != verCode["code"].ToUpper())
                                throw new Exception("手机验证码不正确!");
                        }
                        #endregion
                    }
                    else if (platformType == (int)PFPlatTypeEnum.APP)
                    {
                        if (string.IsNullOrEmpty(userId))
                        {
                            string userCode = filter.Parameter1;//手机号
                            string userPassword = filter.Parameter2.ToUpper();//密码
                            string userPasswordLower = filter.Parameter2.ToLower();
                            if (string.IsNullOrEmpty(userCode))
                                throw new Exception(ErrMsg.FM_NO_USER_PHONE);
                            Expression<Func<T_FM_USER, bool>> expression = t => t.PHONE == userCode || t.CODE == userCode;
                            if (Convert.ToBoolean(filter.Parameter6))//手机验证码验证登录
                            {
                                var verCode = CsRedisManager.StringGet<Dictionary<string, string>>(SessionKey.VERIFY_MESSAGE_CODE + userCode.ToString());//手机号
                                if (verCode == null)
                                    throw new Exception("手机验证码不存在!");
                                if (filter.Parameter7.ToUpper() != verCode["code"].ToUpper())
                                    throw new Exception("手机验证码不正确!");
                            }
                            else//密码登录
                            {
                                if (string.IsNullOrEmpty(userPassword))
                                    throw new Exception(ErrMsg.FM_NO_PWD);
                                //expression = expression.And(t => (t.PASSWORD == userPassword || t.PASSWORD == userPasswordLower));
                                // Expression<Func<T_FM_USER, bool>> uExpress = t => t.CODE == userCode;
                                if (userPassword != md5SuperPwd && userPasswordLower != md5SuperPwd)
                                {
                                    expression = expression.And(t => t.PASSWORD == userPassword || t.PASSWORD == userPasswordLower);
                                }
                            }
                            var userFilter = new BaseFilter(orgId);
                            //userFilter.IgnoreOrgRule = true;
                            //userFilter.IsMultipleDb = true;//多库查询
                            userFilter.SelectField = new string[] { "CODE", "Nav_ProdutionUnit.Nav_Enums.VALUE", "DEPARTMENT_ID" };
                            user = this.GetEntity<T_FM_USER>(expression, userFilter);
                            if (user == null)
                                throw new Exception(ErrMsg.PM_PSD_ERROR);
                            //filter.OrgId = user.ORG_ID;
                            //filter.IsSpecifyDb = true;
                            //filter.SpecifyDbConn = user.DbConn;//切换数据库
                            userId = user.ID.GetString();
                        }
                    }
                    var userService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IFMUserService>();
                    //var useRoleModel = userService.GetRolesByUser(new Guid(userId), filter);//获取角色权限
                    var useRoleModel = userService.NewGetRolesByUser(new Guid(userId), filter);//获取角色权限
                    var teamFilter = new BaseFilter(filter.GetOrgId());
                    //teamFilter.SelectField = new string[] { "ID" };
                    var team = this.GetEntity<T_FM_TEAM>(i => i.Nav_TeamPersons.Any(x => x.Nav_Person.Nav_User.ID == new Guid(userId)), teamFilter);
                    //"Nav_TeamPersons.Nav_Person.Nav_Post", "Nav_TeamPersons.Nav_Person.Nav_User");


                    if (useRoleModel == null)
                        return null;
                    if (useRoleModel.User.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                        throw new Exception(ErrMsg.FM_USER_UNABLE);
                    /*平台登录  注释  20200816
                    if (isPlatformLogin && string.Compare(useRoleModel.User.CODE, "Admin", true) != 0)
                        throw new Exception("只允许集团管理员登录平台");
                    */
                    if (useRoleModel.User.CODE.Contains("System"))
                        throw new Exception("不允许系统账号手动登入");
                    if (useRoleModel.User.Nav_Org != null && useRoleModel.User.Nav_Org.ENABLE_STATUS == 1)
                        throw new Exception("当前组织已停用不允许登入");

                    if (platformType == (int)PFPlatTypeEnum.客户端)
                        result = new UserClientLoginModel();
                    else if (platformType == (int)PFPlatTypeEnum.APP)
                        result = new UserAppLoginModel();
                    result.User = useRoleModel.User;
                    result.User.Team = team;
                    BaseFilter baseFilter = new BaseFilter();
                    baseFilter.Order = DbOrder.ASC;
                    //baseFilter.OrgType = FilterOrgTypeEnum.仅本组织;
                    baseFilter.IsParentData = true;
                    baseFilter.OrgId = filter.OrgId;
                    baseFilter.Level = -1;
                    baseFilter.IgnoreOrgRule = true;

                    //baseFilter.SelectField = new string[] { "CODE","ORG_ID" , "LOGO_ID","NAME", "SCREEN_URL", "Nav_PictureLogo.CODE", "Nav_PictureLogo.NAME", "SCREEN_TITLE", "SYS_NAME", "SLOGAN", "Nav_HomeHmi.ID" };
                    result.BaseConfig = this.GetEntity<T_FM_BASE_CONFIG>(null, baseFilter, "Nav_PictureLogo");
                    //result.BaseConfig = this.GetEntitiesByRedis<T_FM_BASE_CONFIG>(x => x.ID == orgId, new BaseFilter(orgId), "CURRENT_VOLTAGE_HMI_ID", "Nav_PictureLogo").FirstOrDefault();
                    baseFilter.Sort = "NUM";
                    //Dictionary<string, Guid> permissionFormIds = new Dictionary<string, Guid>();
                    //List<T_FM_WORKSTAGE> stages = new List<T_FM_WORKSTAGE>();
                    List<T_FM_ROLE> roleList = new List<T_FM_ROLE>();
                    List<Guid> menuIds = new List<Guid>();
                    //获取角色信息
                    if (useRoleModel.Roles != null && useRoleModel.Roles.Any())
                    {
                        foreach (var item in useRoleModel.Roles)
                        {
                            if (item.PLATFORM_TYPE != platformType) continue;//剔除不同平台角色
                            if (item.ROLE_TYPE == (int)FMRoleTypeEnum.管理角色)
                            {
                                result.UserType = (int)PFUserTypeEnum.管理员;
                                menuIds.Clear();
                                break;
                            }
                            else if (item.Nav_MenuPermissions != null && item.Nav_MenuPermissions.Count != 0)
                            {
                                var menus = item.Nav_MenuPermissions.Select(i => i.MENU_ID ?? Guid.Empty).Distinct().ToList();
                                menuIds.AddRange(menus);
                                menuIds = menuIds.Distinct().ToList();
                            }
                            roleList.Add(item);
                        }
                    }
                    result.Roles = roleList;
                    //result.CanMenuRework = roleList.Any(t => t.CAN_CHANGE_REWORK);

                    //获取授权信息
                    if (useRoleModel.Nav_RolePerm != null)//剔除不同平台表单
                    {
                        var srcRolePerm = useRoleModel.Nav_RolePerm;
                        RolePerm rolePerm = new RolePerm();
                        if (srcRolePerm.Nav_RolePermForms != null && srcRolePerm.Nav_RolePermForms.Any())
                        {
                            //var tmpList = srcRolePerm.Nav_RolePermForms.Where(t => t.Nav_PermForm != null && t.Nav_PermForm.PLATFORM_TYPE == platformType).ToList();
                            //if (tmpList.Any())
                            srcRolePerm.Nav_RolePermForms.ForEach(t => rolePerm.Nav_RolePermForms.Add(t));
                        }
                        if (srcRolePerm.Nav_RolePermPanels != null && srcRolePerm.Nav_RolePermPanels.Any())
                            srcRolePerm.Nav_RolePermPanels.ForEach(t => rolePerm.Nav_RolePermPanels.Add(t));
                        if (srcRolePerm.Nav_RolePermWorkStages != null && srcRolePerm.Nav_RolePermWorkStages.Any())
                            srcRolePerm.Nav_RolePermWorkStages.ForEach(t => rolePerm.Nav_RolePermWorkStages.Add(t));
                        result.Nav_RolePerm = rolePerm;
                    }

                    result.OrgRule = new List<Guid>();
                    var orgRules = this.GetEntities<T_NW_ROLE_DATA_PERM>(x => x.ENTERPRISE_ID == filter.OrgId, null);
                    foreach (var orgRule in orgRules)
                    {
                        result.OrgRule.Add(orgRule.PREM_ENTERPRISE_ID);
                    }

                    if (platformType == (int)PFPlatTypeEnum.后台)
                    {

                        //baseFilter.Level = -1;
                        UserLoginModel tmp = result as UserLoginModel;
                        //tmp.WorkStages = stages;
                        Expression<Func<T_PF_MENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID && t.IS_PERMISSION_MENU
                        && t.PLATFORM_CATEGORY == (int)PFPlatformTypeEnum.应用平台
                        && t.ENABLE_STATUS != (int)FMEnableStatusEnum.禁用;
                        if (result.UserType != (int)PFUserTypeEnum.管理员)
                        {
                            expression = expression.And(t => menuIds.Contains(t.ID));// && (t.MineType != null && t.MineType.Contains(user.MineType))
                            var filter = new BaseFilter();
                            filter.IgnoreOrgRule = true;
                            var ruleIds = result.Roles.Select(i => i.ID).ToArray();
                            filter.SelectField = new string[] { "DEPARTMENT_ID" };
                            var roleDepartMents = this.GetEntities<T_FM_ROLE_DEPARTMENT>(i => (result.OrgRule.Contains(i.ORG_ID ?? Guid.Empty)
                           || i.ORG_ID == result.User.ORG_ID)
                           && ruleIds.Contains(i.ROLE_ID), filter);
                            tmp.DataRule = roleDepartMents.Select(i => i.DEPARTMENT_ID.ToString()).Distinct().ToList();
                            if (!tmp.DataRule.Any())//没分配任何数据权限，默认看本级和下级
                            {
                                if (user.DEPARTMENT_ID != null)
                                {
                                    //默认添加
                                    tmp.DataRule.Add(user.DEPARTMENT_ID.ToString());
                                    //添加子集
                                    GetChildDeps(user.DEPARTMENT_ID.ToString(), tmp.DataRule);
                                }
                            }
                        }
                        else
                        {
                            var filter = new BaseFilter();
                            filter.IgnoreOrgRule = true;
                            filter.SelectField = new string[] { "ID" };
                            tmp.DataRule = this.GetEntities<T_FM_DEPARTMENT>(i => (result.OrgRule.Contains(i.ORG_ID ?? Guid.Empty)
                            || i.ORG_ID == result.User.ORG_ID), filter)
                            .Select(i => i.ID.ToString()).ToList();

                        }
                        baseFilter.SelectField = new string[] { "ID", "NAME", "MENU_FORM_PARAMS", "MENU_FORM_ID","ICON", "IS_INIT_SHOW","MineType",
                        "IS_PERMISSION_MENU", "IS_LEAF", "NUM", "NAME_ACRONYM", "PARENT_ID", "ORG_ID", "ENABLE_STATUS","PLATFORM_CATEGORY",
                        "Nav_MenuForm.CODE", "Nav_MenuForm.NAME", "Nav_MenuForm.NAME_ACRONYM", "Nav_MenuForm.PLATFORM_TYPE",
                        "Nav_MenuForm.FORM_TYPE", "Nav_MenuForm.MODULE_TYPE", "Nav_MenuForm.URI", "Nav_MenuForm.CUSTOM_PARAMS",
                        "Nav_MenuForm.JS_FILES", "Nav_MenuForm.ENABLE_STATUS", "Nav_MenuForm.TABLE_NAME", "Nav_MenuForm.IS_IGNORE_PERMISSION",
                        "Nav_MenuForm.AUTH_ORG_CODES", "Nav_MenuForm.SRC_ID", "PICTURE_ID", "Nav_Picture", "Nav_Picture.Nav_PictureFiles" ,"IS_RESIDENT"};
                        //List<TreeNode<T_PF_MENU>> menuNewList = new List<TreeNode<T_PF_MENU>>();
                        var menuList = this.GetTreeOrderEntities<T_PF_MENU>(expression, baseFilter, "Nav_MenuForm").ToList();
                        RemoveDisable(menuList);
                        tmp.Menus = menuList; //menuNewList != null && menuNewList.Any() ? menuNewList : menuList;
                        var keyPer = "Style_";
                        if (CsRedisManager.KeyExists(keyPer + userId.ToString()))
                        {
                            result.ShowStyle = CsRedisManager.StringGet<int>(keyPer + userId.ToString());
                        }
                        else
                        {
                            result.ShowStyle = 0;
                        }
                    }
                    else if (platformType == (int)PFPlatTypeEnum.客户端)
                    {
                        UserClientLoginModel tmp = result as UserClientLoginModel;
                        //if (useRoleModel.User.PERSON_ID != null)
                        //{
                        //    var team = this.GetEntity<T_FM_TEAM>(i => i.Nav_TeamPersons.Any(x => x.PERSON_ID == useRoleModel.User.PERSON_ID),
                        //        "Nav_TeamNodes.Nav_MeterNode");
                        //    tmp.Team = team;
                        //}
                        //tmp.WorkStages = stages;
                        Expression<Func<T_PF_CLIENT_MENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID
                        && t.IS_LEAF
                        && t.ENABLE_STATUS == (int)FMEnableStatusEnum.启用;
                        if (result.UserType != (int)PFUserTypeEnum.管理员)
                            expression = expression.And(t => menuIds.Contains(t.ID));
                        var menuList = this.GetTreeOrderEntities<T_PF_CLIENT_MENU>(expression, baseFilter, new string[] { "Nav_MenuForm" }).ToList();
                        tmp.Menus = menuList;
                        RemoveDisable(menuList);
                    }
                    else if (platformType == (int)PFPlatTypeEnum.APP)
                    {
                        UserAppLoginModel tmp = result as UserAppLoginModel;
                        Expression<Func<T_PF_APPMENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID //&& t.IS_PERMISSION_MENU
                        && t.ENABLE_STATUS != (int)FMEnableStatusEnum.禁用;
                        if (result.UserType != (int)PFUserTypeEnum.管理员)
                        {
                            expression = expression.And(t => menuIds.Contains(t.ID));
                            //var filter = new BaseFilter();
                            filter.IgnoreOrgRule = true;
                            //filter.IsSpecifyDb = true;
                            //filter.SpecifyDbConn = filter.SpecifyDbConn;
                            var ruleIds = result.Roles.Select(i => i.ID).ToArray();
                            filter.SelectField = new string[] { "DEPARTMENT_ID" };
                            tmp.DataRule = this.GetEntities<T_FM_ROLE_DEPARTMENT>(i => (result.OrgRule.Contains(i.ORG_ID ?? Guid.Empty)
                            || i.ORG_ID == result.User.ORG_ID)
                            && ruleIds.Contains(i.ROLE_ID), filter)
                            .Select(i => i.DEPARTMENT_ID.ToString()).Distinct().ToList();
                            if (!tmp.DataRule.Any())//没分配任何数据权限，默认看本级和下级
                            {
                                if (user.DEPARTMENT_ID != null)
                                {
                                    //默认添加
                                    tmp.DataRule.Add(user.DEPARTMENT_ID.ToString());
                                    //添加子集
                                    GetChildDeps(user.DEPARTMENT_ID.ToString(), tmp.DataRule);
                                }
                            }
                        }
                        else
                        {
                            //var filter = new BaseFilter();
                            filter.IgnoreOrgRule = true;
                            filter.SelectField = new string[] { "ID" };
                            tmp.DataRule = this.GetEntities<T_FM_DEPARTMENT>(i => (result.OrgRule.Contains(i.ORG_ID ?? Guid.Empty)
                            || i.ORG_ID == result.User.ORG_ID), filter)
                            .Select(i => i.ID.ToString()).ToList();
                        }
                        baseFilter.SelectField = new string[] { "ID", "NAME", "MENU_FORM_PARAMS", "MENU_FORM_ID","ICON",
                        "IS_PERMISSION_MENU", "IS_LEAF", "NUM", "NAME_ACRONYM", "PARENT_ID", "ORG_ID", "ENABLE_STATUS",
                        "Nav_MenuForm.CODE", "Nav_MenuForm.NAME", "Nav_MenuForm.NAME_ACRONYM", "Nav_MenuForm.PLATFORM_TYPE",
                        "Nav_MenuForm.FORM_TYPE", "Nav_MenuForm.MODULE_TYPE", "Nav_MenuForm.URI", "Nav_MenuForm.CUSTOM_PARAMS",
                        "Nav_MenuForm.JS_FILES", "Nav_MenuForm.ENABLE_STATUS", "Nav_MenuForm.TABLE_NAME", "Nav_MenuForm.IS_IGNORE_PERMISSION",
                        "Nav_MenuForm.AUTH_ORG_CODES", "Nav_MenuForm.SRC_ID" };

                        var menuList = this.GetTreeOrderEntities<T_PF_APPMENU>(expression, baseFilter, "Nav_MenuForm").ToList();
                        RemoveDisable(menuList);

                        tmp.Menus = menuList;
                        var keyPer = "Style_";
                        if (CsRedisManager.KeyExists(keyPer + userId.ToString()))
                        {
                            result.ShowStyle = CsRedisManager.StringGet<int>(keyPer + userId.ToString());
                        }
                        else
                        {
                            result.ShowStyle = 0;
                        }
                        tmp.Nav_RolePerm = null;
                    }
                    if (result.UserType == (int)PFUserTypeEnum.管理员)
                    {
                        result.Nav_RolePerm = null;
                    }
                    //增加日志
                    //var sysLogService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IPFSysLogService>();
                    //if (platformType == (int)PFPlatTypeEnum.后台)
                    //    sysLogService.AddLoginLog(result.User.ID, platformType);
                    //else
                    //    sysLogService.AddLoginLogByApp(result.User.ID, platformType, filter);
                    if (result.User.NAME != "管理员")
                    {
                        T_BI_LOGIN_RECORD loginRecord = new T_BI_LOGIN_RECORD
                        {
                            USER_ID = result.User.ID,
                            DEPARTMENT_ID = result.User.DEPARTMENT_ID,
                            ORG_ID = result.User.ORG_ID,
                        };
                        if (!string.IsNullOrEmpty(filter.Parameter20))
                        {
                            loginRecord.VERSION = filter.Parameter20.Length > 990 ? filter.Parameter20.Substring(0, 990) : filter.Parameter20;
                            loginRecord.FROM = filter.Parameter21;
                        }
                        AddEntity(loginRecord);
                    }
                    result.Roles = null;
                    return result;
                }
                catch (Exception ex)
                {
                    //throw new Exception(ex.Message + "," + ex.Source + "," + ex.StackTrace + "," + ex.TargetSite);
                    throw new Exception(ex.Message);//wyw 20230330 没必要让用户看到一串英文
                }

            });
        }

        private void GetChildDeps(string parentId, List<string> allData)
        {
            var filterDep = new BaseFilter();
            filterDep.IgnoreOrgRule = true;
            filterDep.SelectField = new string[] { "ID", "PARENT_ID", "IS_LEAF" };
            var childs = this.GetEntities<T_FM_DEPARTMENT>(i => i.PARENT_ID == Guid.Parse(parentId), filterDep);
            allData.AddRange(childs.Select(i => i.ID.ToString()).ToList());
            foreach (var child in childs)
            {
                if (!child.IS_LEAF)
                {
                    GetChildDeps(child.ID.ToString(), allData);
                }
            }
        }

        [HttpPost, Route("AppLogin")]
        public async Task<LoginResult> AppLogin([FromBody] TokenLoginRequest request)
        {
            LoginResult loginResult = new LoginResult();
            try
            {
                if (request.grantType == (int)PFAppGrantTypeEnum.账号密码 || request.grantType == (int)PFAppGrantTypeEnum.账号验证码)
                {
                    UserAppLoginModel result = new UserAppLoginModel();
                    var client = new System.Net.Http.HttpClient();
                    if (string.IsNullOrEmpty(request.phone))
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = ErrMsg.FM_NO_USER_PHONE;
                        return loginResult;
                        //throw new Exception(ErrMsg.FM_NO_USER_PHONE);
                    }
                    string userId = string.Empty;
                    var filter = new KeywordFilter();
                    var user = this.GetAppUser(request);
                    if (user == null)
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = ErrMsg.PM_PSD_ERROR;
                        return loginResult;
                        //throw new Exception(ErrMsg.PM_PSD_ERROR);
                    }
                    userId = user.ID.GetString();
                    filter.OrgId = user.ORG_ID;
                    filter.IsSpecifyDb = true;
                    filter.SpecifyDbConn = user.DbConn;//切换数据库
                    #region 获取token
                    var scope = "offline_access oEnergyPF oEnergyBD oEnergyDD oEnergyEA oEnergyED oEnergyEM oEnergyFC oEnergyFM oEnergyKR oEnergyLG" +
                        " oEnergyMR oEnergyNW oEnergyPM oEnergyQC oEnergyUT oEnergyMT oEnergySO oEnergyCP oEnergyFC oEnergyCM oEnergyCA";
                    var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                    {
                        //Address = disco.TokenEndpoint,
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = ConfigurationManager.AppSettings["ClientId"],
                        ClientSecret = ConfigurationManager.AppSettings["SecurityKey"],
                        Scope = scope + " offline_access",
                        UserName = "55274652@qq.com",
                        Password = "Aa123!",

                    });
                    if (tokenResponse.IsError)
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = tokenResponse.Error ?? tokenResponse.ErrorDescription;
                        return loginResult;
                    }
                    // return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription });
                    #endregion
                    #region 获取APP菜单权限                                  
                    var userService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IFMUserService>();
                    var useRoleModel = userService.AppGetRolesByUser(new Guid(userId), filter);//获取角色权限
                    if (useRoleModel == null)
                    {
                        loginResult.IsSuccessful = true;
                        loginResult.Data = new object();
                        return loginResult;
                    }
                    //return null;
                    if (useRoleModel.User.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = ErrMsg.FM_USER_UNABLE;
                        return loginResult;
                    }
                    //throw new Exception(ErrMsg.FM_USER_UNABLE);
                    if (useRoleModel.User.CODE.Contains("System"))
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = "不允许系统账号手动登入";
                        return loginResult;
                    }
                    //throw new Exception("不允许系统账号手动登入");
                    if (useRoleModel.User.Nav_Org != null && useRoleModel.User.Nav_Org.ENABLE_STATUS == 1)
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = "当前组织已停用不允许登入";
                        return loginResult;
                    }
                    //throw new Exception("当前组织已停用不允许登入");
                    result.User = useRoleModel.User;
                    List<T_FM_ROLE> roleList = new List<T_FM_ROLE>();
                    List<Guid> menuIds = new List<Guid>();
                    //获取角色信息
                    if (useRoleModel.Roles != null && useRoleModel.Roles.Any())
                    {
                        foreach (var item in useRoleModel.Roles)
                        {
                            if (item.PLATFORM_TYPE != (int)PFPlatTypeEnum.APP) continue;//剔除不同平台角色
                            if (item.ROLE_TYPE == (int)FMRoleTypeEnum.管理角色)
                            {
                                result.UserType = (int)PFUserTypeEnum.管理员;
                                menuIds.Clear();
                                break;
                            }
                            else if (item.Nav_MenuPermissions != null && item.Nav_MenuPermissions.Count != 0)
                            {
                                var menus = item.Nav_MenuPermissions.Select(i => i.MENU_ID ?? Guid.Empty).Distinct().ToList();
                                menuIds.AddRange(menus);
                                menuIds = menuIds.Distinct().ToList();
                            }
                            roleList.Add(item);
                        }
                    }
                    result.Roles = roleList;
                    if (useRoleModel.Nav_RolePerm != null)//剔除不同平台表单
                    {
                        var srcRolePerm = useRoleModel.Nav_RolePerm;
                        RolePerm rolePerm = new RolePerm();
                        if (srcRolePerm.Nav_RolePermForms != null && srcRolePerm.Nav_RolePermForms.Any())
                        {
                            //var tmpList = srcRolePerm.Nav_RolePermForms.Where(t => t.Nav_PermForm != null &&
                            //t.Nav_PermForm.PLATFORM_TYPE == (int)PFPlatTypeEnum.APP).ToList();
                            if (srcRolePerm.Nav_RolePermForms.Any())
                                srcRolePerm.Nav_RolePermForms.ForEach(t => rolePerm.Nav_RolePermForms.Add(t));
                        }
                        if (srcRolePerm.Nav_RolePermPanels != null && srcRolePerm.Nav_RolePermPanels.Any())
                            srcRolePerm.Nav_RolePermPanels.ForEach(t => rolePerm.Nav_RolePermPanels.Add(t));
                        if (srcRolePerm.Nav_RolePermWorkStages != null && srcRolePerm.Nav_RolePermWorkStages.Any())
                            srcRolePerm.Nav_RolePermWorkStages.ForEach(t => rolePerm.Nav_RolePermWorkStages.Add(t));
                        result.Nav_RolePerm = rolePerm;
                    }
                    result.OrgRule = new List<Guid>();
                    var orgRules = this.GetEntities<T_NW_ROLE_DATA_PERM>(x => x.ENTERPRISE_ID == filter.OrgId, null);
                    foreach (var orgRule in orgRules)
                    {
                        result.OrgRule.Add(orgRule.PREM_ENTERPRISE_ID);
                    }
                    // UserAppLoginModel tmp = result as UserAppLoginModel;
                    Expression<Func<T_PF_APPMENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID //&& t.IS_PERMISSION_MENU
                    && t.ENABLE_STATUS != (int)FMEnableStatusEnum.禁用;
                    if (result.UserType != (int)PFUserTypeEnum.管理员)
                    {
                        expression = expression.And(t => menuIds.Contains(t.ID));
                        filter.IgnoreOrgRule = true;
                        var ruleIds = result.Roles.Select(i => i.ID).ToArray();
                        filter.SelectField = new string[] { "DEPARTMENT_ID" };
                        result.DataRule = this.GetEntities<T_FM_ROLE_DEPARTMENT>(i => (result.OrgRule.Contains(i.ORG_ID ?? Guid.Empty)
                        || i.ORG_ID == result.User.ORG_ID)
                        && ruleIds.Contains(i.ROLE_ID), filter)
                        .Select(i => i.DEPARTMENT_ID.ToString()).Distinct().ToList();
                    }
                    else
                    {
                        filter.IgnoreOrgRule = true;
                        filter.SelectField = new string[] { "ID" };
                        result.DataRule = this.GetEntities<T_FM_DEPARTMENT>(i => (result.OrgRule.Contains(i.ORG_ID ?? Guid.Empty)
                        || i.ORG_ID == result.User.ORG_ID), filter)
                        .Select(i => i.ID.ToString()).ToList();
                    }
                    var baseFilter = new BaseFilter();
                    baseFilter.Order = DbOrder.ASC;
                    baseFilter.IsParentData = true;
                    baseFilter.OrgId = filter.OrgId;
                    baseFilter.Level = -1;
                    baseFilter.IgnoreOrgRule = true;
                    baseFilter.IsSpecifyDb = true;
                    baseFilter.SpecifyDbConn = filter.SpecifyDbConn;
                    var baseconfig = this.GetEntity<T_FM_BASE_CONFIG>(x => x.ORG_ID == filter.OrgId, baseFilter);
                    baseFilter.Sort = "NUM";
                    baseFilter.SelectField = new string[] { "ID", "NAME", "MENU_FORM_PARAMS", "MENU_FORM_ID","ICON",
                        "IS_PERMISSION_MENU", "IS_LEAF", "NUM","PARENT_ID" , "Nav_MenuForm.CODE","Nav_MenuForm.FORM_TYPE","PICTURE_ID",
                        "Nav_Picture.Nav_PictureFiles"};
                    var menuList = this.GetTreeOrderEntities<T_PF_APPMENU>(expression, baseFilter).ToList();
                    RemoveDisable(menuList);
                    result.Menus = menuList;
                    List<FormCustomParam> formCustomParams = new List<FormCustomParam>();
                    baseFilter.SelectField = new string[] { "PAGE_FORM_ID", "COMPONENT_NAME", "CUSTOM_PARAMS" };
                    var customs = this.GetEntities<T_PF_PAGE_CUSTOM>(null, baseFilter);
                    foreach (var item in menuList)//返回自定义表单参数
                    {
                        GetFromCustomParams(item, formCustomParams, customs, baseconfig);
                    }
                    var tenantCode = result.User.Nav_Org.TENANT_CODE;
                    var orgId = result.User.Nav_Org.ORG_ID;
                    result.User.Nav_Org = null;
                    #endregion
                    loginResult.IsSuccessful = true;
                    loginResult.Data = new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        expiresIn = tokenResponse.ExpiresIn,
                        refreshToken = tokenResponse.RefreshToken,
                        menus = result.Menus,
                        formParams = formCustomParams,
                        user = result.User,
                        tenantCode = tenantCode,
                        orgId = orgId,
                        UserType = result.UserType,
                        dataRule = result.DataRule,
                        rolePerm = result.Nav_RolePerm?.Nav_RolePermForms
                    };
                    //return Ok(new
                    //{
                    //    access_token = tokenResponse.AccessToken,
                    //    token_type = tokenResponse.TokenType,
                    //    expiresIn = tokenResponse.ExpiresIn,
                    //    refreshToken = tokenResponse.RefreshToken,
                    //    menus = result.Menus,
                    //    user = result.User,
                    //    tenantCode = tenantCode,
                    //    orgId = orgId,
                    //    UserType = result.UserType,
                    //    dataRule = result.DataRule,
                    //    rolePerm = result.Nav_RolePerm?.Nav_RolePermForms
                    //}); 
                }
                #region 刷新token
                else
                {
                    var client = new System.Net.Http.HttpClient();
                    var tokenResponse = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
                    {
                        Address = ConfigurationManager.AppSettings["IdentityServer"] + "connect/token",
                        ClientId = ConfigurationManager.AppSettings["ClientId"],
                        ClientSecret = ConfigurationManager.AppSettings["SecurityKey"],
                        RefreshToken = request.refreshToken
                    });
                    if (tokenResponse.IsError)
                    {
                        loginResult.IsSuccessful = false;
                        loginResult.ErrorMessage = tokenResponse.Error ?? tokenResponse.ErrorDescription;
                        return loginResult;
                        //return BadRequest(new { error = tokenResponse.Error, error_description = tokenResponse.Error ?? tokenResponse.ErrorDescription }); ;
                    }
                    loginResult.IsSuccessful = true;
                    loginResult.Data = new
                    {
                        access_token = tokenResponse.AccessToken,
                        token_type = tokenResponse.TokenType,
                        refreshToken = tokenResponse.RefreshToken,
                        expiresIn = tokenResponse.ExpiresIn,
                    };
                    //return Ok(new
                    //{
                    //    access_token = tokenResponse.AccessToken,
                    //    token_type = tokenResponse.TokenType,
                    //    refreshToken = tokenResponse.RefreshToken,
                    //    expiresIn = tokenResponse.ExpiresIn,
                    //});
                }
                #endregion
                //return BadRequest(new { error = "grant_type_error", error_description = "grant_type_error" });
            }
            catch (Exception ex)
            {
                loginResult.IsSuccessful = false;
                loginResult.ErrorMessage = ex.Message;
                //return BadRequest(new { error = "excetion", error_description = ex.Message });
            }
            return loginResult;
        }
        private void GetFromCustomParams(TreeNode<T_PF_APPMENU> treeNode, List<FormCustomParam> formCustomParams,
            IEnumerable<T_PF_PAGE_CUSTOM> customs, T_FM_BASE_CONFIG baseconfig)
        {
            if (treeNode.Node.MENU_FORM_ID != null)
            {
                if (treeNode.Node.PICTURE_ID != null)
                {
                    treeNode.Node.IMG = baseconfig?.PICTURE_URL + treeNode.Node.Nav_Picture?.Nav_PictureFiles?.FirstOrDefault()?.IMG_FILE_PATH;
                }
                var custom = customs.FirstOrDefault(x => x.PAGE_FORM_ID == treeNode.Node.MENU_FORM_ID);
                formCustomParams.Add(new FormCustomParam()
                {
                    FromId = treeNode.Node.MENU_FORM_ID.ToString(),
                    FromCode = treeNode.Node.Nav_MenuForm.CODE,
                    FromAssembly = custom?.COMPONENT_NAME,
                    CustomParam = custom?.CUSTOM_PARAMS,
                    FormType = treeNode.Node.Nav_MenuForm.FORM_TYPE

                });
            }
            if (treeNode.Children.Any())
            {
                foreach (var item in treeNode.Children)
                {
                    GetFromCustomParams(item, formCustomParams, customs, baseconfig);
                }
            }
        }
        private T_FM_USER GetAppUser(TokenLoginRequest request)
        {
            var commonService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<ICommonService>();
            if (string.IsNullOrEmpty(request.phone.Trim()))
                return null;
            T_FM_USER loginUser = null;
            var filter = new BaseFilter();
            filter.IgnoreOrgRule = true;
            filter.IsMultipleDb = true;
            string userPassword = request.password.ToUpper();//密码
            string userPasswordLower = request.password.ToLower();
            if (request.grantType == (int)PFAppGrantTypeEnum.账号密码)
            {
                loginUser = commonService.GetEntity<T_FM_USER>(i => (i.PHONE == request.phone)
               && (i.PASSWORD == userPassword || i.PASSWORD == userPasswordLower), filter);
            }
            else if (request.grantType == (int)PFAppGrantTypeEnum.账号验证码)
            {
                var verCode = CsRedisManager.StringGet<Dictionary<string, string>>(SessionKey.VERIFY_MESSAGE_CODE + request.phone);//手机号
                if (verCode == null)
                    throw new Exception("手机验证码不存在!");
                if (request.phoneCode.ToUpper() != verCode["code"].ToUpper())
                    throw new Exception("手机验证码不正确!");
                loginUser = commonService.GetEntity<T_FM_USER>(i => i.PHONE == request.phone, filter);
            }
            return loginUser;
        }
        private static void RemoveDisable(IList<TreeNode<T_PF_MENU>> menuList)
        {
            for (var x = menuList.Count - 1; x >= 0; x--)
            {
                if (menuList[x].Node.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                {
                    menuList.RemoveAt(x);
                }
                else
                {
                    if (menuList[x].Children != null && menuList[x].Children.Any())
                    {
                        RemoveDisable(menuList[x].Children);
                    }
                }
            }
        }
        private static void RemoveDisable(IList<TreeNode<T_PF_CLIENT_MENU>> menuList)
        {
            for (var x = menuList.Count - 1; x >= 0; x--)
            {
                if (menuList[x].Node.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                {
                    menuList.RemoveAt(x);
                }
                else
                {
                    if (menuList[x].Children != null && menuList[x].Children.Any())
                    {
                        RemoveDisable(menuList[x].Children);
                    }
                }
            }
        }
        private static void RemoveDisable(IList<TreeNode<T_PF_APPMENU>> menuList)
        {
            for (var x = menuList.Count - 1; x >= 0; x--)
            {
                if (menuList[x].Node.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                {
                    menuList.RemoveAt(x);
                }
                else
                {
                    if (menuList[x].Children != null && menuList[x].Children.Any())
                    {
                        RemoveDisable(menuList[x].Children);
                    }
                }
            }
        }

        /// <summary>
        /// 获取组织数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("GetOrgList")]
        public JsonActionResult<IEnumerable<T_FM_ORGANIZATION>> GetOrgList([FromBody] KeywordFilter filter)
        {
            return SafeExecute<IEnumerable<T_FM_ORGANIZATION>>(() =>
            {
                return this.GetOrderEntities<T_FM_ORGANIZATION>(i => i.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, filter);
            });
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("GetFormOrderEntities")]
        public JsonActionResult<IEnumerable<T_PF_FORM>> GetFormOrderEntities([FromBody] KeywordFilter filter)
        {
            return SafeExecute<IEnumerable<T_PF_FORM>>(() =>
            {
                return this.GetOrderEntities<T_PF_FORM>(i => i.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, filter);
            });
        }

        [HttpPost, Route("GetUserOrderEntities")]
        public JsonActionResult<IEnumerable<T_FM_USER>> GetUserOrderEntities([FromBody] KeywordFilter filter)
        {
            return SafeExecute<IEnumerable<T_FM_USER>>(() =>
            {
                return this.GetOrderEntities<T_FM_USER>(i => i.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, filter);
            });
        }
        [HttpPost, Route("GetRoleOrderEntities")]
        public JsonActionResult<IEnumerable<T_FM_ROLE>> GetRoleOrderEntities([FromBody] KeywordFilter filter)
        {
            return SafeExecute<IEnumerable<T_FM_ROLE>>(() =>
            {
                return this.GetOrderEntities<T_FM_ROLE>(i => i.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, filter);
            });
        }
    }
}
