using Ewide.Core.Service.Role;
using Ewide.Core.Service.User.Dto;
using Ewide.Core.Util;
using Furion;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Ewide.Core.Service
{
    /// <summary>
    /// 用户服务
    /// </summary>
    [ApiDescriptionSettings(Name = "User", Order = 150)]
    public class SysUserService : ISysUserService, IDynamicApiController, ITransient
    {
        private readonly IRepository<SysUser> _sysUserRep;  // 用户表仓储 
        private readonly IRepository<SysOrg> _sysOrgRep;
        private readonly IRepository<SysEmp> _sysEmpRep;
        private readonly IUserManager _userManager;
        private readonly ISysCacheService _sysCacheService;
        private readonly ISysEmpService _sysEmpService;
        private readonly IMemoryCache _iMemoryCache;
        private readonly ISysUserDataScopeService _sysUserDataScopeService;
        private readonly ISysUserRoleService _sysUserRoleService;
        private readonly ISysUserAreaService _sysUserAreaService;

        public SysUserService(IRepository<SysUser> sysUserRep,
                              IRepository<SysOrg> sysOrgRep,
                               IRepository<SysEmp> sysEmpRep,
                              IUserManager userManager,
                              IMemoryCache memoryCache,
                              ISysCacheService sysCacheService,
                              ISysEmpService sysEmpService,
                              ISysUserDataScopeService sysUserDataScopeService,
                              ISysUserRoleService sysUserRoleService,
                              ISysUserAreaService sysUserAreaService)
        {
            _sysUserRep = sysUserRep;
            _sysOrgRep = sysOrgRep;
            _sysEmpRep = sysEmpRep;
            _userManager = userManager;
            _iMemoryCache = memoryCache;
            _sysCacheService = sysCacheService;
            _sysEmpService = sysEmpService;
            _sysUserDataScopeService = sysUserDataScopeService;
            _sysUserRoleService = sysUserRoleService;
            _sysUserAreaService = sysUserAreaService;
        }

        /// <summary>
        /// 分页查询用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/page")]
        public async Task<dynamic> QueryUserPageList([FromBody] UserInput input)
        {
            var superAdmin = _userManager.SuperAdmin;
            var searchValue = input.SearchValue;
            var pid = input.SysEmpParam.OrgId;

            var sysEmpRep = Db.GetRepository<SysEmp>();
            var dataScopes = await _userManager.GetUserAllDataScopeList();
            var users = await _sysUserRep.DetachedEntities
                                         .Join(sysEmpRep.DetachedEntities, u => u.Id, e => e.Id, (u, e) => new { u, e })
                                         .Join(_sysOrgRep.DetachedEntities, n => n.e.OrgId, o => o.Id, (n, o) => new { n, o })
                                         .Where(!string.IsNullOrEmpty(searchValue), x => (x.n.u.Account.Contains(input.SearchValue) ||
                                                                                    x.n.u.Name.Contains(input.SearchValue) ||
                                                                                    x.n.u.Phone.Contains(input.SearchValue)))
                                         .Where(!string.IsNullOrEmpty(pid), x => input.TreeNodeDataScope.GetValueOrDefault(1) == 2 ? (x.n.e.OrgId == pid ||
                                                                            x.o.Pids.Contains($"[{pid.Trim()}]")) : x.n.e.OrgId == pid )
                                         .Where(input.SearchStatus >= 0, x => x.n.u.Status == input.SearchStatus)
                                         .Where(!superAdmin, x => x.n.u.AdminType != AdminType.SuperAdmin)
                                         .Where(!superAdmin && dataScopes.Count > 0, x => dataScopes.Contains(x.n.e.OrgId))
                                         .Select(u => u.n.u.Adapt<UserOutput>()).ToPagedListAsync(input.PageIndex, input.PageSize);

            //var emps = new List<Task<EmpOutput>>();
            //users.Items.ToList().ForEach(u =>
            //{
            //    emps.Add(_sysEmpService.GetEmpInfo(long.Parse(u.Id)));
            //});
            //await Task.WhenAll(emps);
            //foreach (var user in users.Items)
            //{
            //    user.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
            //}
            return PageDataResult<UserOutput>.PageResult(users);
        }

        /// <summary>
        /// 增加用户       
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/add")]
        [UnitOfWork]
        public async Task<dynamic> AddUser(AddUserInput input)
        {
            // 数据范围检查
            await CheckDataScope(input);

            var email = input.Email?.ToLower();

            var isExist = await _sysUserRep.AnyAsync(u =>
                input.Account.Equals(u.Account) ||
                input.Account.Equals(u.Phone) ||
                input.Account.Equals(u.Email) ||
                (!string.IsNullOrWhiteSpace(input.Phone) && (
                    input.Phone.Equals(u.Account) ||
                    input.Phone.Equals(u.Phone)
                )) ||
                (!string.IsNullOrWhiteSpace(email) && (
                    email.Equals(u.Account) ||
                    email.Equals(u.Email)
                ))
            , false);
            if (isExist) throw Oops.Oh(ErrorCode.D1003);
            input.Password = CommonConst.DEFAULT_PASSWORD;
            var user = input.Adapt<SysUser>();
            user.Password = MD5Encryption.Encrypt(input.Password);
            if (string.IsNullOrEmpty(user.Name))
                user.Name = user.Account;
            if (string.IsNullOrEmpty(user.NickName))
                user.NickName = user.Name;
            var id = Guid.NewGuid().ToString();
            user.Id = id;
            await _sysUserRep.InsertAsync(user);
            input.SysEmpParam.Id = id;
            // 增加员工信息
            await _sysEmpService.AddOrUpdate(input.SysEmpParam);

            return id;
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/delete")]
        [UnitOfWork]
        public async Task DeleteUser(DeleteUserInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == input.Id);
            if (user.AdminType == AdminType.SuperAdmin)
                throw Oops.Oh(ErrorCode.D1014);

            // 数据范围检查
            await CheckDataScope(input);

            // 直接删除用户
            await user.DeleteAsync();

            // 删除员工及附属机构职位信息
            await _sysEmpService.DeleteEmpInfoByUserId(user.Id);

            //删除该用户对应的用户-角色表关联信息
            await _sysUserRoleService.DeleteUserRoleListByUserId(user.Id);

            //删除该用户对应的用户-数据范围表关联信息
            await _sysUserDataScopeService.DeleteUserDataScopeListByUserId(user.Id);
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/edit")]
        [UnitOfWork]
        public async Task UpdateUser(UpdateUserInput input)
        {
            // 数据范围检查
            await CheckDataScope(input);

            var email = input.Email?.ToLower();

            // 排除自己并且判断与其他是否相同
            var isExist = await _sysUserRep.AnyAsync(u => 
                (input.Account.Equals(u.Account) && !input.Id.Equals(u.Id)) ||
                input.Account.Equals(u.Phone) ||
                input.Account.Equals(u.Email) ||
                (!string.IsNullOrWhiteSpace(input.Phone) && (
                    input.Phone.Equals(u.Account) ||
                    (input.Phone.Equals(u.Phone) && !input.Id.Equals(u.Id))
                )) ||
                (!string.IsNullOrWhiteSpace(email) && (
                    email.Equals(u.Account) ||
                    (email.Equals(u.Email) && !input.Id.Equals(u.Id))
                ))
            , false);
            if (isExist) throw Oops.Oh(ErrorCode.D1003);

            var user = input.Adapt<SysUser>();
            await user.UpdateIncludeAsync(new[] {
                nameof(SysUser.Account),
                nameof(SysUser.NickName),
                nameof(SysUser.Name),
                nameof(SysUser.Birthday),
                nameof(SysUser.Sex),
                nameof(SysUser.Email),
                nameof(SysUser.Phone),
                nameof(SysUser.Tel),
            }, true);
            // user.UpdateIncludeNow(new[] { nameof(SysUser.Birthday) });
            input.SysEmpParam.Id = user.Id.ToString();
            // 更新员工及附属机构职位信息
            await _sysEmpService.AddOrUpdate(input.SysEmpParam);
        }

        /// <summary>
        /// 查看用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("/sysUser/detail")]
        public async Task<dynamic> GetUser([FromQuery] QueryUserInput input)
        {
            var user = await _sysUserRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
            var userDto = user.Adapt<UserOutput>();
            if (userDto != null)
            {
                userDto.SysEmpInfo = await _sysEmpService.GetEmpInfo(user.Id);
            }
            return userDto;
        }

        /// <summary>
        /// 修改用户状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/changeStatus")]
        public async Task ChangeUserStatus(UpdateUserInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == input.Id);
            if (user.AdminType == AdminType.SuperAdmin)
                throw Oops.Oh(ErrorCode.D1015);

            if (!Enum.IsDefined(typeof(CommonStatus), input.Status))
                throw Oops.Oh(ErrorCode.D3005);
            user.Status = input.Status;
        }

        /// <summary>
        /// 授权用户角色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/grantRole")]
        public async Task GrantUserRole(UpdateUserInput input)
        {
            // 数据范围检查
            await CheckDataScope(input);
            await _sysUserRoleService.GrantRole(input);
        }

        /// <summary>
        /// 授权用户数据范围
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/grantData")]
        public async Task GrantUserData(UpdateUserInput input)
        {
            // 数据范围检查
            await CheckDataScope(input);
            await _sysUserDataScopeService.GrantData(input);
        }

        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/updateInfo")]
        public async Task UpdateUserInfo(UserInput input)
        {
            var user = input.Adapt<SysUser>();
            user.Id = _userManager.UserId;
            await user.UpdateExcludeAsync(new string[] {
                nameof(SysUser.Account),
                nameof(SysUser.SecurityLevel),
                nameof(SysUser.Name),
                nameof(SysUser.Password),
                nameof(SysUser.AdminType),
                nameof(SysUser.Status),
                // 邮箱和手机号作为安全验证的方式,不能在此处直接进行修改
                nameof(SysUser.Phone),
                nameof(SysUser.Email)
            }, true);
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/updatePwd")]
        public async Task UpdateUserPwd(ChangePasswordUserInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
            var Password = RSAHandler.RSADecrypt(input.Password);
            Password = MD5Encryption.Encrypt(Password);
            if (Password != user.Password)
            {
                throw Oops.Oh("旧密码不正确");
            }
            var newPassword = RSAHandler.RSADecrypt(input.NewPassword);
            // 验证新密码强度
            var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value;
            if (!Regex.Match(newPassword, pattern).Success)
            {
                throw Oops.Oh("新密码强度不符合规则");
            }

            newPassword = MD5Encryption.Encrypt(newPassword);
            if (newPassword.Equals(user.Password))
                throw Oops.Oh(ErrorCode.D10041);

            user.Password = newPassword;

        }

        /// <summary>
        /// 获取用户拥有角色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("/sysUser/ownRole")]
        public async Task<dynamic> GetUserOwnRole([FromQuery] QueryUserInput input)
        {
            return await _sysUserRoleService.GetUserRoleIdList(input.Id);
        }

        /// <summary>
        /// 获取用户拥有数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("/sysUser/ownData")]
        public async Task<dynamic> GetUserOwnData([FromQuery] QueryUserInput input)
        {
            return await _userManager.GetUserExtraDataScopeList(input.Id);
        }
        /// <summary>
        /// 获取用户拥有区域
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("/sysUser/ownArea")]
        public async Task<dynamic> GetUserOwnArea([FromQuery] QueryUserInput input)
        {
            return await _userManager.GetUserExtraAreaScopeList(input.Id);
        }
        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/resetPwd")]
        public async Task ResetUserPwd(QueryUserInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == input.Id);
            user.Password = MD5Encryption.Encrypt(CommonConst.DEFAULT_PASSWORD);
        }

        /// <summary>
        /// 修改用户头像(未实现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/updateAvatar")]
        public async Task UpdateAvatar(UserInput input)
        {
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
            // 调用文件上传
            //sysFileInfoService.assertFile(input.Avatar);
            user.Avatar = input.Avatar;
        }

        /// <summary>
        /// 获取用户选择器
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("/sysUser/selector")]
        public async Task<dynamic> GetUserSelector([FromQuery] UserInput input)
        {
            var name = !string.IsNullOrEmpty(input.Name?.Trim());
            return await _sysUserRep.DetachedEntities
                                    .Where(name, u => EF.Functions.Like(u.Name, $"%{input.Name.Trim()}%"))
                                    .Where(u => u.Status != CommonStatus.DELETED)
                                    .Where(u => u.AdminType != AdminType.SuperAdmin)
                                    .Select(u => new
                                    {
                                        u.Id,
                                        u.Name
                                    }).ToListAsync();
        }

        /// <summary>
        /// 用户导出(未实现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("/sysUser/export")]
        public async Task ExportUser([FromQuery] UserInput input)
        {
            await Task.CompletedTask;
        }

        /// <summary>
        /// 根据用户Id获取用户
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>       
        [NonAction]
        public async Task<dynamic> GetUserById(string userId)
        {
            return await _sysUserRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == userId);
        }

        /// <summary>
        /// 将OAuth账号转换成账号
        /// </summary>
        /// <param name="authUser"></param>
        /// <param name="sysUser"></param>
        /// <returns></returns>
        [NonAction]
        public async Task SaveAuthUserToUser(AuthUserInput authUser, UserInput sysUser)
        {
            var user = sysUser.Adapt<SysUser>();
            user.AdminType = AdminType.None; // 非管理员

            // oauth账号与系统账号判断
            var isExist = await _sysUserRep.DetachedEntities.AnyAsync(u => u.Account == authUser.Username);
            user.Account = isExist ? authUser.Username + DateTime.Now.Ticks : authUser.Username;
            user.Name = user.NickName = authUser.Nickname;
            user.Email = authUser.Email;
            user.Sex = (int)authUser.Gender;
            await user.InsertAsync();
        }


        /// <summary>
        /// 检查普通用户数据范围
        /// </summary>
        /// <param name="userParam"></param>
        /// <returns></returns>
        private async Task CheckDataScope(UserInput userParam)
        {
            // 如果当前用户不是超级管理员，则进行数据范围校验
            if (!_userManager.SuperAdmin)
            {
                var dataScopes = await _userManager.GetUserAllDataScopeList();
                if (dataScopes == null || (userParam.SysEmpParam.OrgId != null && !dataScopes.Contains(userParam.SysEmpParam.OrgId)))
                    throw Oops.Oh(ErrorCode.D1013);
            }
        }

        ///<summary>
        ///发送验证码
        /// </summary>
        [HttpPost("/sysUser/sendCode")]
        public async Task<dynamic> SendCode(Usermailphone input)
        {
            var Orgcode_Key = "ewide_Orgcode";
            var Smscode_Key = "ewide_smscode";
            var Mailcode_Key = "ewide_mailcode";
            var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
            var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
            CodeHelper ch = new CodeHelper(_iMemoryCache, _sysUserRep, _userManager);
            //Type为1时，给原手机号发送验证码
            if (input.Type == 1)
            {
                try
                {
                    return ch.SendSmscode(_userManager.User.Phone, Orgcode_Key);
                }
                catch (Exception e)
                {
                    throw Oops.Oh(ErrorCode.D1018);
                }

            }
            //Type为2时，给原邮箱发送验证码
            else if (input.Type == 2)
            {
                if (new Regex(Regex_Email).IsMatch(_userManager.User.Email))
                {
                    try
                    {
                        return ch.SendMail(_userManager.User.Email, Orgcode_Key);
                    }
                    catch (Exception e)
                    {
                        throw Oops.Oh(ErrorCode.D1018);
                    }
                }
                throw Oops.Oh("原邮箱错误");
            }
            //Type为null时，则发验证码
            else
            {
                await ch.CheckRepeat(input.Target);
                //通过正则判断绑定类型
                if (new Regex(Regex_phone).IsMatch(input.Target))
                {
                    try
                    {

                        ch.SendSmscode(input.Target, Smscode_Key);
                        return true;
                    }
                    catch (Exception e)
                    {
                        throw Oops.Oh(ErrorCode.D1018);
                    }
                }
                if (new Regex(Regex_Email).IsMatch(input.Target))
                {
                    try
                    {
                        ch.SendMail(input.Target, Mailcode_Key);
                        return true;
                    }
                    catch (Exception e)
                    {
                        throw Oops.Oh(ErrorCode.D1018);
                    }
                }
                throw Oops.Oh("格式错误");
            }
        }

        ///<summary>
        ///检验验证码并且绑定
        /// </summary>
        [HttpPost("/sysUser/checkBindcode")]
        public async Task<dynamic> CheckBindcode(Usermailphone input)
        {
            var Orgcode_Key = "ewide_Orgcode";
            var Smscode_Key = "ewide_smscode";
            var Mailcode_Key = "ewide_mailcode";
            var Regex_phone = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$";
            var Regex_Email = @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";
            var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Id == _userManager.UserId);
            CodeHelper ch = new CodeHelper(_iMemoryCache, _sysUserRep,_userManager);
            if (input.Type == 1)
            {
                if (ch.Checkcode(_userManager.User.Phone, input.Orgcode, Orgcode_Key))
                {
                    return true;
                };
                throw Oops.Oh("验证错误");
            }
            else if (input.Type == 2)
            {
                if (ch.Checkcode(_userManager.User.Email, input.Orgcode, Orgcode_Key))
                {
                    return true;
                }
                throw Oops.Oh("验证错误");
            }
            else
            {
                //为第一次绑定
                if (string.IsNullOrEmpty(_userManager.User.Phone) && string.IsNullOrEmpty(_userManager.User.Email))
                {
                    if (new Regex(Regex_phone).IsMatch(input.Target))
                    {
                        if (ch.Checkcode(input.Target, input.Code, Smscode_Key))
                        {
                            try
                            {
                                user.Phone = input.Target;
                                await user.UpdateIncludeNowAsync(new string[] {
                                nameof(SysUser.Phone)
                                }, true);
                                return "手机绑定成功";
                            }
                            catch
                            {
                                throw Oops.Oh("手机绑定错误");
                            }
                        }
                        throw Oops.Oh("验证码失效");
                    }
                    if (new Regex(Regex_Email).IsMatch(input.Target))
                    {
                        if (ch.Checkcode(input.Target, input.Code, Mailcode_Key))
                        {
                            try
                            {
                                user.Email = input.Target;
                                await user.UpdateIncludeNowAsync(new string[] {
                                nameof(SysUser.Email)
                                }, true);
                                return "邮箱绑定成功";
                            }
                            catch
                            {
                                throw Oops.Oh("邮箱绑定错误");
                            }
                        }
                        throw Oops.Oh("验证码失效");
                    }
                    throw Oops.Oh("号码格式不对");
                }
                else
                {
                    bool CheckOrgPhone = ch.Checkcode(_userManager.User.Phone, input.Orgcode, Orgcode_Key);
                    bool CheckOrgEmail = ch.Checkcode(_userManager.User.Email, input.Orgcode, Orgcode_Key);
                    if (CheckOrgPhone || CheckOrgEmail)
                    {
                        if (new Regex(Regex_phone).IsMatch(input.Target))
                        {
                            if (ch.Checkcode(input.Target, input.Code, Smscode_Key))
                            {
                                try
                                {
                                    user.Phone = input.Target;
                                    await user.UpdateIncludeNowAsync(new string[] {
                                nameof(SysUser.Phone)
                                }, true);
                                    return "手机改绑成功";
                                }
                                catch
                                {
                                    throw Oops.Oh("手机绑定错误");
                                }
                            }
                            throw Oops.Oh("验证码失效");
                        }
                        if (new Regex(Regex_Email).IsMatch(input.Target))
                        {
                            if (ch.Checkcode(input.Target, input.Code, Mailcode_Key))
                            {
                                try
                                {
                                    user.Email = input.Target;
                                    await user.UpdateIncludeNowAsync(new string[] {
                                nameof(SysUser.Email)
                                }, true);
                                    return "邮箱改绑成功";
                                }
                                catch
                                {
                                    throw Oops.Oh("邮箱绑定错误");
                                }
                            }
                            throw Oops.Oh("验证码失效");
                        }
                        throw Oops.Oh("号码格式不对");
                    }
                    throw Oops.Oh("验证码失效");
                }
            }
        }

        /// <summary>
        /// 获取密码强度配置
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/sysUser/getPwdRule")]
        public async Task<dynamic> GetPwdRule()
        {
            return new LoginOutput
            {
                Pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value,
                Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value
            };
        }



        [HttpPost("/sysUser/GetOrgUserTree")]
        public async Task<dynamic> GetOrgUserTree(OrgUserInput input)
        {
            var list = await (from u in _sysUserRep.DetachedEntities
                              join e in _sysEmpRep.DetachedEntities on u.Id equals e.Id
                              select new OrgUserTreeNode { Id = u.Id, ParentId = e.OrgId, Type = 1, Name = u.Name }).Union(
                from o in _sysOrgRep.DetachedEntities
                select new OrgUserTreeNode { Id = o.Id, ParentId = o.Pid, Type = 0, Name = o.Name }).ToListAsync();

            return new TreeBuildUtil<OrgUserTreeNode>(new TreeBuildSetting { AddEmptyChildren = false }).DoTreeBuild(list);
        }
    }
}
