369 lines
14 KiB
C#
Raw Normal View History

2024-11-28 13:36:05 +08:00
using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Mvc;
2024-12-03 09:25:16 +08:00
using DOAN.Admin.WebApi.Filters;
using DOAN.Model.Models;
using DOAN.Model.System;
using DOAN.Model.System.Dto;
using DOAN.ServiceCore.Model.Dto;
2024-11-28 13:36:05 +08:00
2024-12-03 09:25:16 +08:00
namespace DOAN.Admin.WebApi.Controllers.System
2024-11-28 13:36:05 +08:00
{
/// <summary>
/// 登录
/// </summary>
[ApiExplorerSettings(GroupName = "sys")]
public class SysLoginController : BaseController
{
private readonly ISysUserService sysUserService;
private readonly ISysMenuService sysMenuService;
private readonly ISysLoginService sysLoginService;
private readonly ISysPermissionService permissionService;
private readonly ICaptcha SecurityCodeHelper;
private readonly ISysConfigService sysConfigService;
private readonly ISysRoleService roleService;
private readonly ISmsCodeLogService smsCodeLogService;
public SysLoginController(
ISysMenuService sysMenuService,
ISysUserService sysUserService,
ISysLoginService sysLoginService,
ISysPermissionService permissionService,
ISysConfigService configService,
ISysRoleService sysRoleService,
ISmsCodeLogService smsCodeLogService,
ICaptcha captcha)
{
SecurityCodeHelper = captcha;
this.sysMenuService = sysMenuService;
this.sysUserService = sysUserService;
this.sysLoginService = sysLoginService;
this.permissionService = permissionService;
this.sysConfigService = configService;
this.smsCodeLogService = smsCodeLogService;
roleService = sysRoleService;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="loginBody">登录对象</param>
/// <returns></returns>
[Route("login")]
[HttpPost]
[Log(Title = "登录")]
public IActionResult Login([FromBody] LoginBodyDto loginBody)
{
if (loginBody == null) { throw new CustomException("请求参数错误"); }
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
if (sysConfig?.ConfigValue != "off" && !SecurityCodeHelper.Validate(loginBody.Uuid, loginBody.Code))
{
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
}
sysLoginService.CheckLockUser(loginBody.Username);
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
var user = sysLoginService.Login(loginBody, new SysLogininfor() { LoginLocation = location });
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
//权限集合 eg *:*:*,system:user:list
List<string> permissions = permissionService.GetMenuPermission(user);
TokenModel loginUser = new(user.Adapt<TokenModel>(), roles.Adapt<List<Roles>>());
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
}
/// <summary>
/// 注销
/// </summary>
/// <returns></returns>
[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 });
}
/// <summary>
/// 获取用户信息
/// </summary>
/// <returns></returns>
[Verify]
[HttpGet("getInfo")]
public IActionResult GetUserInfo()
{
long userid = HttpContext.GetUId();
var user = sysUserService.SelectUserById(userid);
//前端校验按钮权限使用
//角色集合 eg: admin,yunying,common
List<string> roles = permissionService.GetRolePermission(user);
//权限集合 eg *:*:*,system:user:list
List<string> permissions = permissionService.GetMenuPermission(user);
user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)];
user.Password = string.Empty;
return SUCCESS(new { user = user.Adapt<SysUserDto>(), roles, permissions });
}
/// <summary>
/// 获取路由信息
/// </summary>
/// <returns></returns>
[Verify]
[HttpGet("getRouters")]
public IActionResult GetRouters()
{
long uid = HttpContext.GetUId();
var menus = sysMenuService.SelectMenuTreeByUserId(uid);
return SUCCESS(sysMenuService.BuildMenus(menus));
}
/// <summary>
/// 获取路由信息
/// </summary>
/// <returns></returns>
[Verify]
[HttpGet("getAppRouters")]
public IActionResult GetAppRouters()
{
long uid = HttpContext.GetUId();
var perms = permissionService.GetMenuPermission(new SysUser() { UserId = uid });
return SUCCESS(sysMenuService.GetAppMenus(perms));
}
/// <summary>
/// 生成图片验证码
/// </summary>
/// <returns></returns>
[HttpGet("captchaImage")]
public IActionResult CaptchaImage()
{
string uuid = Guid.NewGuid().ToString().Replace("-", "");
SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
var captchaOff = sysConfig?.ConfigValue ?? "0";
var info = SecurityCodeHelper.Generate(uuid, 60);
var obj = new { captchaOff, uuid, img = info.Base64 };// File(stream, "image/png")
return SUCCESS(obj);
}
/// <summary>
/// 注册
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("/register")]
[AllowAnonymous]
[Log(Title = "注册", BusinessType = 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" && !SecurityCodeHelper.Validate(dto.Uuid, dto.Code))
{
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
}
dto.UserIP = HttpContext.GetClientUserIp();
SysUser user = sysUserService.Register(dto);
if (user.UserId > 0)
{
return SUCCESS(user);
}
return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员");
}
#region
/// <summary>
/// 生成二维码
/// </summary>
/// <param name="uuid"></param>
/// <param name="deviceId"></param>
/// <returns></returns>
[HttpGet("/GenerateQrcode")]
public IActionResult GenerateQrcode(string uuid, string deviceId)
{
var state = Guid.NewGuid().ToString();
var dict = new Dictionary<string, object>
{
{ "state", state }
};
CacheService.SetScanLogin(uuid, dict);
return SUCCESS(new
{
status = 1,
state,
uuid,
codeContent = new { uuid, deviceId }// "https://qm.qq.com/cgi-bin/qm/qr?k=kgt4HsckdljU0VM-0kxND6d_igmfuPlL&authKey=r55YUbruiKQ5iwC/folG7KLCmZ++Y4rQVgNlvLbUniUMkbk24Y9+zNuOmOnjAjRc&noverify=0"
});
}
/// <summary>
/// 轮询判断扫码状态
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("/VerifyScan")]
[AllowAnonymous]
public IActionResult VerifyScan([FromBody] ScanDto dto)
{
int status = -1;
object token = string.Empty;
if (CacheService.GetScanLogin(dto.Uuid) is Dictionary<string, object> str)
{
status = 0;
str.TryGetValue("token", out token);
if (str.ContainsKey("status") && (string)str.GetValueOrDefault("status") == "success")
{
status = 2;//扫码成功
CacheService.RemoveScanLogin(dto.Uuid);
}
}
return SUCCESS(new { status, token });
}
/// <summary>
/// 移动端扫码登录
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("/ScanLogin")]
[Log(Title = "扫码登录")]
[Verify]
public IActionResult ScanLogin([FromBody] ScanDto dto)
{
if (dto == null) { return ToResponse(ResultCode.CUSTOM_ERROR, "扫码失败"); }
var name = App.HttpContext.GetName();
sysLoginService.CheckLockUser(name);
TokenModel tokenModel = JwtUtil.GetLoginUser(HttpContext);
if (CacheService.GetScanLogin(dto.Uuid) is not null)
{
Dictionary<string, object> dict = new() { };
dict.Add("status", "success");
dict.Add("token", JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(tokenModel)));
CacheService.SetScanLogin(dto.Uuid, dict);
return SUCCESS(1);
}
return ToResponse(ResultCode.FAIL, "二维码已失效");
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("/checkMobile")]
[Log(Title = "发送短息", BusinessType = BusinessType.INSERT)]
public IActionResult CheckMobile([FromBody] PhoneLoginDto dto)
{
dto.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
var uid = HttpContext.GetUId();
//SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
//if (!SecurityCodeHelper.Validate(dto.Uuid, dto.Code, false))
//{
// return ToResponse(ResultCode.CUSTOM_ERROR, "验证码错误");
//}
if (dto.SendType == 0)
{
var info = sysUserService.GetFirst(f => f.Phonenumber == dto.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
uid = info.UserId;
}
if (dto.SendType == 1)
{
if (sysUserService.CheckPhoneBind(dto.PhoneNum).Count > 0)
{
return ToResponse(ResultCode.CUSTOM_ERROR, "手机号已绑定其他账号");
}
}
string location = HttpContextExtension.GetIpInfo(dto.LoginIP);
smsCodeLogService.AddSmscodeLog(new SmsCodeLog()
{
Userid = uid,
PhoneNum = dto.PhoneNum.ParseToLong(),
SendType = dto.SendType,
UserIP = dto.LoginIP,
Location = location,
});
return SUCCESS(1);
}
/// <summary>
/// 手机号登录
/// </summary>
/// <param name="loginBody">登录对象</param>
/// <returns></returns>
[Route("PhoneLogin")]
[HttpPost]
[Log(Title = "手机号登录")]
public IActionResult PhoneLogin([FromBody] PhoneLoginDto loginBody)
{
if (loginBody == null) { throw new CustomException("请求参数错误"); }
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
if (!CacheService.CheckPhoneCode(loginBody.PhoneNum, loginBody.PhoneCode))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "短信验证码错误");
}
var info = sysUserService.GetFirst(f => f.Phonenumber == loginBody.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
sysLoginService.CheckLockUser(info.UserName);
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
var user = sysLoginService.PhoneLogin(loginBody, new SysLogininfor() { LoginLocation = location }, info);
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
//权限集合 eg *:*:*,system:user:list
List<string> permissions = permissionService.GetMenuPermission(user);
TokenModel loginUser = new(user.Adapt<TokenModel>(), roles.Adapt<List<Roles>>());
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
}
/// <summary>
/// 手机号绑定
/// </summary>
/// <param name="loginBody"></param>
/// <returns></returns>
[Route("/PhoneBind")]
[HttpPost]
[Log(Title = "手机号绑定")]
public IActionResult PhoneBind([FromBody] PhoneLoginDto loginBody)
{
if (loginBody == null) { throw new CustomException("请求参数错误"); }
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
var uid = HttpContext.GetUId();
if (!CacheService.CheckPhoneCode(loginBody.PhoneNum, loginBody.PhoneCode))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "短信验证码错误");
}
var result = sysUserService.ChangePhoneNum(uid, loginBody.PhoneNum);
return SUCCESS(result);
}
}
}