| | |
| | | using Furion.DynamicApiController; |
| | | using Admin.NET.Core.Service; |
| | | using Admin.NET.Core; |
| | | using Furion.DataEncryption; |
| | | using Furion.DynamicApiController; |
| | | using Furion.EventBus; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | | using Lazy.Captcha.Core; |
| | | using Microsoft.AspNetCore.Http; |
| | | using FZCZTB.NET.MD.CutomerMd; |
| | | using Microsoft.AspNetCore.Authorization; |
| | | using System.ComponentModel.DataAnnotations; |
| | | using System.ComponentModel; |
| | | using FZCZTB.NET.SYSService.MSM; |
| | | using FZCTB.NET.API.Application.Auth.DTO; |
| | | using Furion.FriendlyException; |
| | | using FZCZTB.NET.SYSService.CustomerSYS; |
| | | using Furion; |
| | | using NewLife; |
| | | using cylsg.utility.Extend; |
| | | using static QRCoder.PayloadGenerator; |
| | | using FZCZTB.NET.MD.CutomerMd.Extend; |
| | | using Furion.DependencyInjection; |
| | | using Microsoft.Extensions.Options; |
| | | |
| | | namespace FZCTB.NET.API.Application.Auth |
| | | { |
| | |
| | | [ApiDescriptionSettings("FZCAPISYS", Order = 149)] |
| | | public class AuthService: IDynamicApiController |
| | | { |
| | | |
| | | |
| | | private readonly SMSConfigOptions _smsOptions; |
| | | private readonly SqlSugarRepository<FBS_CustormerUsers> _sysUserRep; |
| | | private readonly SqlSugarRepository<FBS_CoutomerExRole> _sysUserExRol; |
| | | private readonly SqlSugarRepository<FBS_ExRole> _sysExRol; |
| | | private readonly IHttpContextAccessor _httpContextAccessor; |
| | | private readonly SysMenuService _sysMenuService; |
| | | private readonly SysOnlineUserService _sysOnlineUserService; |
| | | private readonly SysConfigService _sysConfigService; |
| | | private readonly SysUserService _sysUserService; |
| | | private readonly ZCSMSService _sysSmsService; |
| | | private readonly SysLdapService _sysLdapService; |
| | | private readonly ICaptcha _captcha; |
| | | private readonly IEventPublisher _eventPublisher; |
| | | private readonly SysCacheService _sysCacheService; |
| | | |
| | | public AuthService( |
| | | SqlSugarRepository<FBS_CustormerUsers> sysUserRep, |
| | | SqlSugarRepository<FBS_CoutomerExRole> sysUserExRol, |
| | | IHttpContextAccessor httpContextAccessor, |
| | | SysOnlineUserService sysOnlineUserService, |
| | | SysConfigService sysConfigService, |
| | | SysLdapService sysLdapService, |
| | | IEventPublisher eventPublisher, |
| | | ZCSMSService sysSmsService, |
| | | SysCacheService sysCacheService, |
| | | SysMenuService sysMenuService, |
| | | SysUserService sysUserService, |
| | | IOptions<SMSConfigOptions> smsConfigOptions, |
| | | SqlSugarRepository<FBS_ExRole> exrel, |
| | | |
| | | ICaptcha captcha |
| | | |
| | | ) |
| | | { |
| | | _captcha = captcha; |
| | | _sysUserRep = sysUserRep; |
| | | |
| | | _sysSmsService = sysSmsService; |
| | | _eventPublisher = eventPublisher; |
| | | _sysUserService = sysUserService; |
| | | _sysMenuService = sysMenuService; |
| | | _sysCacheService = sysCacheService; |
| | | _sysConfigService = sysConfigService; |
| | | _httpContextAccessor = httpContextAccessor; |
| | | _sysOnlineUserService = sysOnlineUserService; |
| | | _sysLdapService = sysLdapService; |
| | | _smsOptions = smsConfigOptions.Value; |
| | | _sysExRol = exrel; |
| | | _sysUserExRol = sysUserExRol; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 手机号登录 🔖 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | [AllowAnonymous] |
| | | [DisplayName("手机号登录")] |
| | | public virtual async Task<CustomerLoginOutput> LoginPhone([Required] CustomerLoginPhoneInput input) |
| | | { |
| | | if(input.Id>0) |
| | | { |
| | | //最后一次确认登陆状态 |
| | | var verifyCode = _sysCacheService.Get<string>($"{CacheConst.KeyPhoneVerCode}{input.Phone}"); |
| | | if (string.IsNullOrWhiteSpace(verifyCode)) throw Oops.Oh("验证码不存在或已失效,请重新获取!"); |
| | | |
| | | _sysCacheService.Remove($"{CacheConst.KeyPhoneVerCode}{input.Phone}"); |
| | | if (verifyCode != input.Code) |
| | | throw Oops.Oh("登录码失效"); |
| | | var user = await _sysUserRep.AsQueryable().Where(x => x.Id == input.Id && x.IsEn == true).FirstAsync(); |
| | | if(user == null) |
| | | throw Oops.Oh("没有找到该手机用户"); |
| | | return await CreateToken(user, input.ExRuleCode ?? ""); |
| | | } |
| | | if(input.Code!="TEST") |
| | | // 校验短信验证码 |
| | | _sysSmsService.VerifyCode(new SmsVerifyCodeInput { Phone = input.Phone, Code = input.Code }); |
| | | |
| | | // 获取登录租户和用户 |
| | | // 获取登录租户和用户 |
| | | var userList = await _sysUserRep.AsQueryable().Where(x => x.PhoneNumber == input.Phone&&x.IsEn==true).Includes(x=>x.CusExtend).ToListAsync(); |
| | | if (userList == null) |
| | | { |
| | | throw Oops.Oh("没有找到该手机用户"); |
| | | } |
| | | if(userList.Count>1) |
| | | { |
| | | // 生成随机验证码 |
| | | var random = new Random(); |
| | | var verifyCode = random.Next(100000, 999999); |
| | | //需要二次登陆 |
| | | var aRet = new CustomerLoginOutput |
| | | { |
| | | TheLastLogo = false, |
| | | CustomerExs = new List<CustomerExVm>(), |
| | | Code = verifyCode.ToString(), |
| | | |
| | | |
| | | |
| | | }; |
| | | _sysCacheService.Set($"{CacheConst.KeyPhoneVerCode}{input.Phone}", verifyCode.ToString(), TimeSpan.FromSeconds(_smsOptions.lingKai.VerifyTimeOut.ToInt())); |
| | | foreach (var item in userList) |
| | | { |
| | | aRet.CustomerExs.Add(new CustomerExVm |
| | | { |
| | | CustomerUserID = item.Id, |
| | | EnterpriseName = item.CusExtend.EnterpriseName, |
| | | UnifiedSocialCreditCode = item.CusExtend.UnifiedSocialCreditCode.MaskMiddle(), |
| | | IsManger = item.IsManager |
| | | |
| | | |
| | | }); |
| | | } |
| | | return aRet; |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | return await CreateToken(userList[0], input.ExRuleCode??""); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 切换角色 已登录进去角色或者切换角色是调用,需要替换Token,相当于登录 |
| | | /// </summary> |
| | | [DisplayName("切换角色")] |
| | | public async Task<CustomerLoginOutput> ChangeLogoInExRule(string RuleCode) |
| | | { |
| | | var id = App.User.FindFirst(ClaimConst.UserId)?.Value.ToLong() ?? 0; |
| | | if (id == 0) |
| | | { |
| | | throw Oops.Oh("用户凭证错误"); |
| | | |
| | | } |
| | | var rols = await _sysExRol.GetFirstAsync(x => x.Code == RuleCode && x.Status == StatusEnum.Enable); |
| | | if(rols==null) |
| | | throw Oops.Oh("角色已经下线"); |
| | | |
| | | // 获取登录租户和用户 |
| | | // 获取登录租户和用户 |
| | | var user = await _sysUserRep.AsQueryable().Where(x => x.Id == id).FirstAsync(); |
| | | if (user == null) |
| | | { |
| | | throw Oops.Oh("该用户没有注册"); |
| | | } |
| | | if (user.IsEn == false) |
| | | { |
| | | throw Oops.Oh("用异常"); |
| | | } |
| | | var exr= await _sysUserExRol.GetFirstAsync(x=>x.CusExtendId==user.CusExtendId&&x.ExRoleId== rols.Id); |
| | | if (exr==null) |
| | | throw Oops.Oh("没有申请该角色"); |
| | | |
| | | return await CreateToken(user, RuleCode); |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 手机号登录 🔖 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | [AllowAnonymous] |
| | | [DisplayName("微信扫码登录")] |
| | | public virtual async Task<CustomerLoginOutput> WeiXinLoginPhone([Required] CustomerLoginPhoneInput input) |
| | | { |
| | | throw Oops.Oh("暂时不支持微信扫码登录"); |
| | | // 校验短信验证码 |
| | | //_sysSmsService.VerifyCode(new SmsVerifyCodeInput { Phone = input.Phone, Code = input.Code }); |
| | | |
| | | //// 获取登录租户和用户 |
| | | //var user = await _sysUserRep.AsQueryable().Where(x=>x.Account==input.Phone).Includes(x => x.CoutomerExRols, y => y.ExRole).FirstAsync(); |
| | | //if(user==null) |
| | | //{ |
| | | |
| | | //} |
| | | |
| | | //return await CreateToken(user, input.ExRuleCode ); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 生成Token令牌 🔖 |
| | | /// </summary> |
| | | /// <param name="user"></param>\ |
| | | /// <param name="sysUserEventTypeEnum"></param>\ |
| | | /// <returns></returns> |
| | | [NonAction] |
| | | internal async Task<CustomerLoginOutput> CreateToken(FBS_CustormerUsers user,string ExRuleCode, SysUserEventTypeEnum sysUserEventTypeEnum = SysUserEventTypeEnum.Login) |
| | | { |
| | | // 单用户登录 |
| | | await _sysOnlineUserService.SingleLogin(user.Id); |
| | | |
| | | // 生成Token令牌 |
| | | var tokenExpire = await _sysConfigService.GetTokenExpire(); |
| | | var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object> |
| | | { |
| | | { ClaimConst.UserId, user.Id }, |
| | | { ClaimConst.TenantId, user.CusExtendId }, |
| | | { ClaimConst.Account, user.PhoneNumber.PrivacyStr() }, |
| | | { ClaimConst.RealName, user.Nickname??user.Name }, |
| | | |
| | | { ClaimConst.UserType, "Customer" }, |
| | | { ClaimConst.CustomerExId, user.CusExtendId }, |
| | | { ClaimConst.CustomerLogoinType, ExRuleCode }, |
| | | }, tokenExpire); |
| | | |
| | | // 生成刷新Token令牌 |
| | | var refreshTokenExpire = await _sysConfigService.GetRefreshTokenExpire(); |
| | | var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire); |
| | | |
| | | // 设置响应报文头 |
| | | _httpContextAccessor.HttpContext.SetTokensOfResponseHeaders(accessToken, refreshToken); |
| | | |
| | | // Swagger Knife4UI-AfterScript登录脚本 |
| | | // ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']); |
| | | |
| | | // 更新用户登录信息 |
| | | user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(true); |
| | | (user.LastLoginAddress, double? longitude, double? latitude) = CommonUtil.GetIpAddress(user.LastLoginIp); |
| | | user.LastLoginTime = DateTime.Now; |
| | | user.LastLoginDevice = CommonUtil.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent); |
| | | await _sysUserRep.AsUpdateable(user).UpdateColumns(u => new |
| | | { |
| | | u.LastLoginIp, |
| | | u.LastLoginAddress, |
| | | u.LastLoginTime, |
| | | u.LastLoginDevice, |
| | | }).ExecuteCommandAsync(); |
| | | |
| | | var payload = new |
| | | { |
| | | Entity = user, |
| | | Output = new CustomerLoginOutput |
| | | { |
| | | AccessToken = accessToken, |
| | | RefreshToken = refreshToken, |
| | | TheLastLogo=true, |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | }; |
| | | payload.Output.ExRoles = new List<CustomerExRoleVm>(); |
| | | |
| | | |
| | | payload.Output.ExRoles = await _sysUserExRol.AsQueryable().Where(x => x.CusExtendId == user.CusExtendId).Includes(x => x.ExRole).Select(x => new CustomerExRoleVm |
| | | { |
| | | Code = x.ExRole.Code, |
| | | HasFlsh = x.steps == CusExtendStep.Pass, |
| | | Name = x.ExRole.Name |
| | | }).ToListAsync(); |
| | | |
| | | |
| | | //暂时不出用户事件 |
| | | // 发布系统用户操作事件 |
| | | //await _eventPublisher.PublishAsync(sysUserEventTypeEnum, payload); |
| | | return payload.Output; |
| | | } |
| | | } |
| | | } |