SysLoginController.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. using Hei.Captcha;
  2. using Infrastructure;
  3. using Infrastructure.Attribute;
  4. using Infrastructure.Model;
  5. using IPTools.Core;
  6. using Microsoft.AspNetCore.Authorization;
  7. using Microsoft.AspNetCore.Http;
  8. using Microsoft.AspNetCore.Mvc;
  9. using Microsoft.Extensions.Options;
  10. using System;
  11. using System.Collections.Generic;
  12. using UAParser;
  13. using ZR.Admin.WebApi.Extensions;
  14. using ZR.Admin.WebApi.Filters;
  15. using ZR.Admin.WebApi.Framework;
  16. using ZR.Common;
  17. using ZR.Model.System;
  18. using ZR.Model.System.Dto;
  19. using ZR.Service.System;
  20. using ZR.Service.System.IService;
  21. namespace ZR.Admin.WebApi.Controllers.System
  22. {
  23. /// <summary>
  24. /// 登录
  25. /// </summary>
  26. public class SysLoginController : BaseController
  27. {
  28. static readonly NLog.Logger logger = NLog.LogManager.GetLogger("LoginController");
  29. private readonly IHttpContextAccessor httpContextAccessor;
  30. private readonly ISysUserService sysUserService;
  31. private readonly ISysMenuService sysMenuService;
  32. private readonly ISysLoginService sysLoginService;
  33. private readonly ISysPermissionService permissionService;
  34. private readonly SecurityCodeHelper SecurityCodeHelper;
  35. private readonly ISysConfigService sysConfigService;
  36. private readonly ISysRoleService roleService;
  37. private readonly OptionsSetting jwtSettings;
  38. private readonly IPdaAutoUpdateService pdaAutoUpdateService;
  39. private IWebHostEnvironment _HostEnvironment;
  40. /// <summary>
  41. ///
  42. /// </summary>
  43. /// <param name="contextAccessor"></param>
  44. /// <param name="sysMenuService"></param>
  45. /// <param name="sysUserService"></param>
  46. /// <param name="sysLoginService"></param>
  47. /// <param name="permissionService"></param>
  48. /// <param name="configService"></param>
  49. /// <param name="sysRoleService"></param>
  50. /// <param name="captcha"></param>
  51. /// <param name="jwtSettings"></param>
  52. public SysLoginController(
  53. IHttpContextAccessor contextAccessor,
  54. ISysMenuService sysMenuService,
  55. ISysUserService sysUserService,
  56. ISysLoginService sysLoginService,
  57. ISysPermissionService permissionService,
  58. ISysConfigService configService,
  59. ISysRoleService sysRoleService,
  60. SecurityCodeHelper captcha,
  61. IOptions<OptionsSetting> jwtSettings,
  62. IPdaAutoUpdateService pdaAutoUpdateService,
  63. IWebHostEnvironment hostEnvironment)
  64. {
  65. httpContextAccessor = contextAccessor;
  66. SecurityCodeHelper = captcha;
  67. this.sysMenuService = sysMenuService;
  68. this.sysUserService = sysUserService;
  69. this.sysLoginService = sysLoginService;
  70. this.permissionService = permissionService;
  71. this.sysConfigService = configService;
  72. roleService = sysRoleService;
  73. this.jwtSettings = jwtSettings.Value;
  74. this.pdaAutoUpdateService = pdaAutoUpdateService;
  75. _HostEnvironment = hostEnvironment;
  76. }
  77. /// <summary>
  78. /// 登录
  79. /// </summary>
  80. /// <param name="loginBody">登录对象</param>
  81. /// <returns></returns>
  82. [Route("login")]
  83. [HttpPost]
  84. //[Log(Title = "登录")]
  85. public IActionResult Login([FromBody] LoginBodyDto loginBody)
  86. {
  87. if (loginBody == null) { throw new CustomException("请求参数错误"); }
  88. loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
  89. //2023 0223 孙亚龙注释 不需要校验动态验证码
  90. //SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
  91. //if (sysConfig?.ConfigValue != "off" && CacheHelper.Get(loginBody.Uuid) is string str && !str.ToLower().Equals(loginBody.Code.ToLower()))
  92. //{
  93. // return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
  94. //}
  95. var user = sysLoginService.Login(loginBody, RecordLogInfo(httpContextAccessor.HttpContext));
  96. List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
  97. //权限集合 eg *:*:*,system:user:list
  98. List<string> permissions = permissionService.GetMenuPermission(user);
  99. LoginUser loginUser = new(user, roles, permissions);
  100. CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
  101. return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings.JwtSettings));
  102. }
  103. /// <summary>
  104. /// 注销
  105. /// </summary>
  106. /// <returns></returns>
  107. [Log(Title = "注销")]
  108. [HttpPost("logout")]
  109. public IActionResult LogOut()
  110. {
  111. //Task.Run(async () =>
  112. //{
  113. // //注销登录的用户,相当于ASP.NET中的FormsAuthentication.SignOut
  114. // await HttpContext.SignOutAsync();
  115. //}).Wait();
  116. var userid = HttpContext.GetUId();
  117. var name = HttpContext.GetName();
  118. CacheService.RemoveUserPerms(GlobalConstant.UserPermKEY + userid);
  119. return SUCCESS(new { name, id = userid });
  120. }
  121. /// <summary>
  122. /// 获取用户信息
  123. /// </summary>
  124. /// <returns></returns>
  125. [Verify]
  126. [HttpGet("getInfo")]
  127. public IActionResult GetUserInfo()
  128. {
  129. long userid = HttpContext.GetUId();
  130. var user = sysUserService.SelectUserById(userid);
  131. //前端校验按钮权限使用
  132. //角色集合 eg: admin,yunying,common
  133. List<string> roles = permissionService.GetRolePermission(user);
  134. //权限集合 eg *:*:*,system:user:list
  135. List<string> permissions = permissionService.GetMenuPermission(user);
  136. user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)];
  137. return SUCCESS(new { user, roles, permissions });
  138. }
  139. /// <summary>
  140. /// 获取路由信息
  141. /// </summary>
  142. /// <returns></returns>
  143. [Verify]
  144. [HttpGet("getRouters")]
  145. public IActionResult GetRouters()
  146. {
  147. long uid = HttpContext.GetUId();
  148. var menus = sysMenuService.SelectMenuTreeByUserId(uid);
  149. return ToResponse(ToJson(1, sysMenuService.BuildMenus(menus)));
  150. }
  151. /// <summary>
  152. /// 生成图片验证码
  153. /// </summary>
  154. /// <returns></returns>
  155. [HttpGet("captchaImage")]
  156. public ApiResult CaptchaImage()
  157. {
  158. string uuid = Guid.NewGuid().ToString().Replace("-", "");
  159. SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
  160. var captchaOff = sysConfig?.ConfigValue ?? "0";
  161. var length = AppSettings.GetAppConfig<int>("CaptchaOptions:length", 4);
  162. var code = SecurityCodeHelper.GetRandomEnDigitalText(length);
  163. byte[] imgByte = GenerateCaptcha(captchaOff, code);
  164. string base64Str = Convert.ToBase64String(imgByte);
  165. CacheHelper.SetCache(uuid, code);
  166. var obj = new { captchaOff, uuid, img = base64Str };// File(stream, "image/png")
  167. return ToJson(1, obj);
  168. }
  169. /// <summary>
  170. /// 生成图片验证码
  171. /// </summary>
  172. /// <param name="captchaOff"></param>
  173. /// <param name="code"></param>
  174. /// <returns></returns>
  175. private byte[] GenerateCaptcha(string captchaOff, string code)
  176. {
  177. byte[] imgByte;
  178. if (captchaOff == "1")
  179. {
  180. imgByte = SecurityCodeHelper.GetGifEnDigitalCodeByte(code);//动态gif数字字母
  181. }
  182. else if (captchaOff == "2")
  183. {
  184. imgByte = SecurityCodeHelper.GetGifBubbleCodeByte(code);//动态gif泡泡
  185. }
  186. else if (captchaOff == "3")
  187. {
  188. imgByte = SecurityCodeHelper.GetBubbleCodeByte(code);//泡泡
  189. }
  190. else
  191. {
  192. imgByte = SecurityCodeHelper.GetEnDigitalCodeByte(code);//英文字母加数字
  193. }
  194. return imgByte;
  195. }
  196. /// <summary>
  197. /// 记录用户登陆信息
  198. /// </summary>
  199. /// <param name="context"></param>
  200. /// <returns></returns>
  201. public SysLogininfor RecordLogInfo(HttpContext context)
  202. {
  203. var ipAddr = context.GetClientUserIp();
  204. var ip_info = IpTool.Search(ipAddr);
  205. ClientInfo clientInfo = context.GetClientInfo();
  206. SysLogininfor sysLogininfor = new()
  207. {
  208. Browser = clientInfo.ToString(),
  209. Os = clientInfo.OS.ToString(),
  210. Ipaddr = ipAddr,
  211. UserName = context.GetName(),
  212. LoginLocation = ip_info?.Province + "-" + ip_info?.City
  213. };
  214. return sysLogininfor;
  215. }
  216. /// <summary>
  217. /// 注册
  218. /// </summary>
  219. /// <param name="dto"></param>
  220. /// <returns></returns>
  221. [HttpPost("/register")]
  222. [AllowAnonymous]
  223. [Log(Title = "注册", BusinessType = Infrastructure.Enums.BusinessType.INSERT)]
  224. public IActionResult Register([FromBody] RegisterDto dto)
  225. {
  226. SysConfig config = sysConfigService.GetSysConfigByKey("sys.account.register");
  227. if (config?.ConfigValue != "true")
  228. {
  229. return ToResponse(ResultCode.CUSTOM_ERROR, "当前系统没有开启注册功能!");
  230. }
  231. SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
  232. if (sysConfig?.ConfigValue != "off" && CacheHelper.Get(dto.Uuid) is string str && !str.ToLower().Equals(dto.Code.ToLower()))
  233. {
  234. return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
  235. }
  236. if (UserConstants.NOT_UNIQUE.Equals(sysUserService.CheckUserNameUnique(dto.Username)))
  237. {
  238. return ToResponse(ResultCode.CUSTOM_ERROR, $"保存用户{dto.Username}失败,注册账号已存在");
  239. }
  240. SysUser user = sysUserService.Register(dto);
  241. if (user.UserId > 0)
  242. {
  243. return SUCCESS(user);
  244. }
  245. return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员");
  246. }
  247. #region 20240314 孙亚龙新增 PDA程序自动更新
  248. [HttpGet("GetPdaLatestmsg")]
  249. public IActionResult GetPdaLatestmsg()
  250. {
  251. var response = pdaAutoUpdateService.GetPdaLatestmsg();
  252. return SUCCESS(response);
  253. }
  254. [HttpGet("GetPdaPackage")]
  255. public FileResult GetPdaPackage(string fileName)
  256. {
  257. string filePath = _HostEnvironment.WebRootPath + "/" + fileName;
  258. Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  259. FileStreamResult actionresult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"));
  260. actionresult.FileDownloadName = fileName;
  261. return actionresult;
  262. }
  263. #endregion
  264. }
  265. }