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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|