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; namespace FZCTB.NET.API.Application.Auth { /// /// 鉴权服务 /// [ApiDescriptionSettings("FZCAPISYS", Order = 149)] public class AuthService: IDynamicApiController { private readonly UserManager _userManager; private readonly SqlSugarRepository _sysUserRep; 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 sysUserRep, IHttpContextAccessor httpContextAccessor, SysOnlineUserService sysOnlineUserService, SysConfigService sysConfigService, SysLdapService sysLdapService, IEventPublisher eventPublisher, ZCSMSService sysSmsService, SysCacheService sysCacheService, SysMenuService sysMenuService, SysUserService sysUserService, UserManager userManager, ICaptcha captcha) { _captcha = captcha; _sysUserRep = sysUserRep; _userManager = userManager; _sysSmsService = sysSmsService; _eventPublisher = eventPublisher; _sysUserService = sysUserService; _sysMenuService = sysMenuService; _sysCacheService = sysCacheService; _sysConfigService = sysConfigService; _httpContextAccessor = httpContextAccessor; _sysOnlineUserService = sysOnlineUserService; _sysLdapService = sysLdapService; } /// /// 手机号登录 🔖 /// /// /// [AllowAnonymous] [DisplayName("手机号登录")] public virtual async Task LoginPhone([Required] CustomerLoginPhoneInput input) { if(input.Code!="TEST") // 校验短信验证码 _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) { throw Oops.Oh("该用户没有注册"); } if(user.Status== StatusEnum.Disable) { throw Oops.Oh("用异常"); } return await CreateToken(user, input.ExRuleCode??""); } /// /// 手机号登录 🔖 /// /// /// [AllowAnonymous] [DisplayName("微信扫码登录")] public virtual async Task 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 ); } /// /// 生成Token令牌 🔖 /// /// \ /// \ /// [NonAction] internal async Task CreateToken(FBS_Customer user,string ExRuleCode, SysUserEventTypeEnum sysUserEventTypeEnum = SysUserEventTypeEnum.Login) { // 单用户登录 await _sysOnlineUserService.SingleLogin(user.Id); // 生成Token令牌 var tokenExpire = await _sysConfigService.GetTokenExpire(); var accessToken = JWTEncryption.Encrypt(new Dictionary { { ClaimConst.UserId, user.Id }, { ClaimConst.TenantId, user.TenantId }, { ClaimConst.Account, user.Account }, { ClaimConst.RealName, user.RealName }, { ClaimConst.UserType, "Customer" }, { 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, } }; payload.Output.ExRoles = new List(); foreach (var item in user.CoutomerExRols) { payload.Output.ExRoles.Add(new CustomerExRoleVm { Code = item.ExRole.Code, Name = item.ExRole.Name, HasFlsh = item.HasFlsh }); } //暂时不出用户事件 // 发布系统用户操作事件 //await _eventPublisher.PublishAsync(sysUserEventTypeEnum, payload); return payload.Output; } } }