using Hei.Captcha; using Infrastructure; using Infrastructure.Attribute; using Infrastructure.Model; using IPTools.Core; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using UAParser; using ZR.Admin.WebApi.Extensions; using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Framework; using ZR.Common; using ZR.Model.System; using ZR.Model.System.Dto; using ZR.Service.System; using ZR.Service.System.IService; namespace ZR.Admin.WebApi.Controllers.System { /// /// 登录 /// public class SysLoginController : BaseController { static readonly NLog.Logger logger = NLog.LogManager.GetLogger("LoginController"); private readonly IHttpContextAccessor httpContextAccessor; private readonly ISysUserService sysUserService; private readonly ISysMenuService sysMenuService; private readonly ISysLoginService sysLoginService; private readonly ISysPermissionService permissionService; private readonly SecurityCodeHelper SecurityCodeHelper; private readonly ISysConfigService sysConfigService; private readonly ISysRoleService roleService; private readonly OptionsSetting jwtSettings; private readonly IPdaAutoUpdateService pdaAutoUpdateService; private IWebHostEnvironment _HostEnvironment; /// /// /// /// /// /// /// /// /// /// /// /// public SysLoginController( IHttpContextAccessor contextAccessor, ISysMenuService sysMenuService, ISysUserService sysUserService, ISysLoginService sysLoginService, ISysPermissionService permissionService, ISysConfigService configService, ISysRoleService sysRoleService, SecurityCodeHelper captcha, IOptions jwtSettings, IPdaAutoUpdateService pdaAutoUpdateService, IWebHostEnvironment hostEnvironment) { httpContextAccessor = contextAccessor; SecurityCodeHelper = captcha; this.sysMenuService = sysMenuService; this.sysUserService = sysUserService; this.sysLoginService = sysLoginService; this.permissionService = permissionService; this.sysConfigService = configService; roleService = sysRoleService; this.jwtSettings = jwtSettings.Value; this.pdaAutoUpdateService = pdaAutoUpdateService; _HostEnvironment = hostEnvironment; } /// /// 登录 /// /// 登录对象 /// [Route("login")] [HttpPost] //[Log(Title = "登录")] public IActionResult Login([FromBody] LoginBodyDto loginBody) { if (loginBody == null) { throw new CustomException("请求参数错误"); } loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext); //2023 0223 孙亚龙注释 不需要校验动态验证码 //SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff"); //if (sysConfig?.ConfigValue != "off" && CacheHelper.Get(loginBody.Uuid) is string str && !str.ToLower().Equals(loginBody.Code.ToLower())) //{ // return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误"); //} var user = sysLoginService.Login(loginBody, RecordLogInfo(httpContextAccessor.HttpContext)); List roles = roleService.SelectUserRoleListByUserId(user.UserId); //权限集合 eg *:*:*,system:user:list List permissions = permissionService.GetMenuPermission(user); LoginUser loginUser = new(user, roles, permissions); CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions); return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings.JwtSettings)); } /// /// 注销 /// /// [Log(Title = "注销")] [HttpPost("logout")] public IActionResult LogOut() { //Task.Run(async () => //{ // //注销登录的用户,相当于ASP.NET中的FormsAuthentication.SignOut // await HttpContext.SignOutAsync(); //}).Wait(); var userid = HttpContext.GetUId(); var name = HttpContext.GetName(); CacheService.RemoveUserPerms(GlobalConstant.UserPermKEY + userid); return SUCCESS(new { name, id = userid }); } /// /// 获取用户信息 /// /// [Verify] [HttpGet("getInfo")] public IActionResult GetUserInfo() { long userid = HttpContext.GetUId(); var user = sysUserService.SelectUserById(userid); //前端校验按钮权限使用 //角色集合 eg: admin,yunying,common List roles = permissionService.GetRolePermission(user); //权限集合 eg *:*:*,system:user:list List permissions = permissionService.GetMenuPermission(user); user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)]; return SUCCESS(new { user, roles, permissions }); } /// /// 获取路由信息 /// /// [Verify] [HttpGet("getRouters")] public IActionResult GetRouters() { long uid = HttpContext.GetUId(); var menus = sysMenuService.SelectMenuTreeByUserId(uid); return ToResponse(ToJson(1, sysMenuService.BuildMenus(menus))); } /// /// 生成图片验证码 /// /// [HttpGet("captchaImage")] public ApiResult CaptchaImage() { string uuid = Guid.NewGuid().ToString().Replace("-", ""); SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff"); var captchaOff = sysConfig?.ConfigValue ?? "0"; var length = AppSettings.GetAppConfig("CaptchaOptions:length", 4); var code = SecurityCodeHelper.GetRandomEnDigitalText(length); byte[] imgByte = GenerateCaptcha(captchaOff, code); string base64Str = Convert.ToBase64String(imgByte); CacheHelper.SetCache(uuid, code); var obj = new { captchaOff, uuid, img = base64Str };// File(stream, "image/png") return ToJson(1, obj); } /// /// 生成图片验证码 /// /// /// /// private byte[] GenerateCaptcha(string captchaOff, string code) { byte[] imgByte; if (captchaOff == "1") { imgByte = SecurityCodeHelper.GetGifEnDigitalCodeByte(code);//动态gif数字字母 } else if (captchaOff == "2") { imgByte = SecurityCodeHelper.GetGifBubbleCodeByte(code);//动态gif泡泡 } else if (captchaOff == "3") { imgByte = SecurityCodeHelper.GetBubbleCodeByte(code);//泡泡 } else { imgByte = SecurityCodeHelper.GetEnDigitalCodeByte(code);//英文字母加数字 } return imgByte; } /// /// 记录用户登陆信息 /// /// /// public SysLogininfor RecordLogInfo(HttpContext context) { var ipAddr = context.GetClientUserIp(); var ip_info = IpTool.Search(ipAddr); ClientInfo clientInfo = context.GetClientInfo(); SysLogininfor sysLogininfor = new() { Browser = clientInfo.ToString(), Os = clientInfo.OS.ToString(), Ipaddr = ipAddr, UserName = context.GetName(), LoginLocation = ip_info?.Province + "-" + ip_info?.City }; return sysLogininfor; } /// /// 注册 /// /// /// [HttpPost("/register")] [AllowAnonymous] [Log(Title = "注册", BusinessType = Infrastructure.Enums.BusinessType.INSERT)] public IActionResult Register([FromBody] RegisterDto dto) { SysConfig config = sysConfigService.GetSysConfigByKey("sys.account.register"); if (config?.ConfigValue != "true") { return ToResponse(ResultCode.CUSTOM_ERROR, "当前系统没有开启注册功能!"); } SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff"); if (sysConfig?.ConfigValue != "off" && CacheHelper.Get(dto.Uuid) is string str && !str.ToLower().Equals(dto.Code.ToLower())) { return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误"); } if (UserConstants.NOT_UNIQUE.Equals(sysUserService.CheckUserNameUnique(dto.Username))) { return ToResponse(ResultCode.CUSTOM_ERROR, $"保存用户{dto.Username}失败,注册账号已存在"); } SysUser user = sysUserService.Register(dto); if (user.UserId > 0) { return SUCCESS(user); } return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员"); } #region 20240314 孙亚龙新增 PDA程序自动更新 [HttpGet("GetPdaLatestmsg")] public IActionResult GetPdaLatestmsg() { var response = pdaAutoUpdateService.GetPdaLatestmsg(); return SUCCESS(response); } [HttpGet("GetPdaPackage")] public FileResult GetPdaPackage(string fileName) { string filePath = _HostEnvironment.WebRootPath + "/" + fileName; Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); FileStreamResult actionresult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream")); actionresult.FileDownloadName = fileName; return actionresult; } #endregion } }