|
|
|
|
using Furion;
|
|
|
|
|
using Furion.DataEncryption;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Furion.EventBus;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using Myshipping.Core.Entity;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using UAParser;
|
|
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Myshipping.Core.Const;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using NPOI.POIFS.Crypt.Dsig;
|
|
|
|
|
|
|
|
|
|
namespace Myshipping.Core.Service;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 登录授权相关服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
[ApiDescriptionSettings(Name = "Auth", Order = 160)]
|
|
|
|
|
public class AuthService : IAuthService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRep; // 用户表仓储
|
|
|
|
|
private readonly SqlSugarRepository<SysLogVis> _sysLogVisRep;
|
|
|
|
|
private readonly SqlSugarRepository<SysTenant> _sysTenantRep;
|
|
|
|
|
private readonly SqlSugarRepository<SysUserAccountRelation> _sysUserAccountRelation;
|
|
|
|
|
private readonly ISysCacheService _cache;
|
|
|
|
|
|
|
|
|
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
|
|
|
private readonly ISysEmpService _sysEmpService; // 系统员工服务
|
|
|
|
|
private readonly ISysRoleService _sysRoleService; // 系统角色服务
|
|
|
|
|
private readonly ISysMenuService _sysMenuService; // 系统菜单服务
|
|
|
|
|
private readonly ISysAppService _sysAppService; // 系统应用服务
|
|
|
|
|
private readonly IClickWordCaptcha _captchaHandle; // 验证码服务
|
|
|
|
|
private readonly ISysConfigService _sysConfigService; // 验证码服务
|
|
|
|
|
private readonly IDjyTenantParamService _djyTenantParamService; // 租户参数服务
|
|
|
|
|
private readonly IEventPublisher _eventPublisher;
|
|
|
|
|
|
|
|
|
|
private readonly ILogger<AuthService> _logger;
|
|
|
|
|
|
|
|
|
|
private readonly SqlSugarRepository<PingTaiUser> _pingtaiUser; // 平台用户
|
|
|
|
|
|
|
|
|
|
public AuthService(SqlSugarRepository<SysUser> sysUserRep, SqlSugarRepository<SysLogVis> sysLogVisRep, SqlSugarRepository<SysTenant> sysTenantRep,
|
|
|
|
|
IHttpContextAccessor httpContextAccessor, ISysCacheService cache,
|
|
|
|
|
ISysEmpService sysEmpService, ISysRoleService sysRoleService, ISysMenuService sysMenuService,
|
|
|
|
|
ISysAppService sysAppService, IClickWordCaptcha captchaHandle, ISysConfigService sysConfigService,
|
|
|
|
|
IEventPublisher eventPublisher,
|
|
|
|
|
ILogger<AuthService> logger, IDjyTenantParamService djyTenantParamService, SqlSugarRepository<SysUserAccountRelation> sysUserAccountRelation)
|
|
|
|
|
{
|
|
|
|
|
_sysUserRep = sysUserRep;
|
|
|
|
|
_sysLogVisRep = sysLogVisRep;
|
|
|
|
|
_sysTenantRep = sysTenantRep;
|
|
|
|
|
_httpContextAccessor = httpContextAccessor;
|
|
|
|
|
_sysEmpService = sysEmpService;
|
|
|
|
|
_sysRoleService = sysRoleService;
|
|
|
|
|
_sysMenuService = sysMenuService;
|
|
|
|
|
_sysAppService = sysAppService;
|
|
|
|
|
_captchaHandle = captchaHandle;
|
|
|
|
|
_sysConfigService = sysConfigService;
|
|
|
|
|
_eventPublisher = eventPublisher;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_cache = cache;
|
|
|
|
|
_djyTenantParamService = djyTenantParamService;
|
|
|
|
|
_sysUserAccountRelation = sysUserAccountRelation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 用户登录
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <remarks>默认用户名/密码:admin/admin</remarks>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/login")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<string> LoginAsync([Required] LoginInput input)
|
|
|
|
|
{
|
|
|
|
|
var keyDES = App.GetOptions<EncryptKeyOptions>().DES;
|
|
|
|
|
// 获取加密后的密码
|
|
|
|
|
var encryptPassword = DESCEncryption.Encrypt(input.Password, keyDES);
|
|
|
|
|
|
|
|
|
|
// 判断用户名和密码是否正确(排除全局多租户过滤器)Filter(null,true)
|
|
|
|
|
var user = _sysUserRep.AsQueryable().Filter(null, true)
|
|
|
|
|
.WhereIF(input.TenantId.HasValue && input.TenantId.Value > 0, m => m.TenantId == input.TenantId).First(u =>
|
|
|
|
|
u.Account.Equals(input.Account) && u.Password.Equals(encryptPassword) && !u.IsDeleted);
|
|
|
|
|
_ = user ?? throw Oops.Oh(ErrorCode.D1000);
|
|
|
|
|
|
|
|
|
|
// 验证账号是否被冻结
|
|
|
|
|
if (user.Status == CommonStatus.DISABLE)
|
|
|
|
|
throw Oops.Oh(ErrorCode.D1017);
|
|
|
|
|
|
|
|
|
|
//是否需要修改密码
|
|
|
|
|
var needModifyPassword = true;
|
|
|
|
|
if (user.LastModifyPassword.HasValue && (DateTime.Now - user.LastModifyPassword.Value).TotalDays < 90)
|
|
|
|
|
{
|
|
|
|
|
needModifyPassword = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needModifyPassword)
|
|
|
|
|
{
|
|
|
|
|
_httpContextAccessor.HttpContext.Response.Headers["need-modify-password"] = "1";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取对应租户
|
|
|
|
|
var tenant = _sysTenantRep.Single(user.TenantId);
|
|
|
|
|
// 生成Token令牌
|
|
|
|
|
return await GetLoginToken(user, tenant);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<string> GetLoginToken(SysUser user, SysTenant tenant)
|
|
|
|
|
{
|
|
|
|
|
// 生成Token令牌
|
|
|
|
|
//var accessToken = await _jwtBearerManager.CreateTokenAdmin(user);
|
|
|
|
|
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ClaimConst.CLAINM_USERID, user.Id},
|
|
|
|
|
{ClaimConst.TENANT_ID, user.TenantId},
|
|
|
|
|
{ClaimConst.CLAINM_ACCOUNT, user.Account},
|
|
|
|
|
{ClaimConst.CLAINM_NAME, user.Name},
|
|
|
|
|
{ClaimConst.CLAINM_SUPERADMIN, user.AdminType},
|
|
|
|
|
{ ClaimConst.CLAINM_TENANT_TYPE, tenant.TenantType },
|
|
|
|
|
{ ClaimConst.TENANT_NAME, tenant.Name },
|
|
|
|
|
{ ClaimConst.DjyCompanyId, tenant.CompId == null ? string.Empty : tenant.CompId },
|
|
|
|
|
{ ClaimConst.DjyUserId, user.DjyUserId },
|
|
|
|
|
{ ClaimConst.Tel, user.Tel },
|
|
|
|
|
{ ClaimConst.Phone, user.Phone },
|
|
|
|
|
{ ClaimConst.Email, user.Email },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 设置Swagger自动登录
|
|
|
|
|
_httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
|
|
|
|
|
|
|
|
|
|
var jwtSettinng = App.GetConfig<JWTSettingsOptions>("JWTSettings");
|
|
|
|
|
|
|
|
|
|
// 生成刷新Token令牌
|
|
|
|
|
var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, jwtSettinng.RefreshTokenExpired);
|
|
|
|
|
|
|
|
|
|
// 设置刷新Token令牌
|
|
|
|
|
_httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
|
|
|
|
|
_logger.LogInformation($"{user.Account} 登录颁发刷新token,有效期:{jwtSettinng.RefreshTokenExpired} 分钟");
|
|
|
|
|
|
|
|
|
|
var httpContext = App.HttpContext;
|
|
|
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource("Update:UserLoginInfo",
|
|
|
|
|
new SysUser { Id = user.Id, LastLoginIp = httpContext.GetLocalIpAddressToIPv4(), LastLoginTime = DateTime.Now }));
|
|
|
|
|
return accessToken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 模拟租户登录
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <remarks>默认用户名/密码:admin/admin</remarks>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/simulationTenantLogin")]
|
|
|
|
|
public async Task<string> SimulationLoginAsync([Required] LoginInput input)
|
|
|
|
|
{
|
|
|
|
|
SysTenant tenant = null;
|
|
|
|
|
if (input.TenantId.HasValue && input.TenantId.Value > 0)
|
|
|
|
|
{
|
|
|
|
|
tenant = _sysTenantRep.Single(input.TenantId.Value);
|
|
|
|
|
if (tenant == null || (tenant.IsDeleted && tenant.TenantType != TenantTypeEnum.SYSTEM))
|
|
|
|
|
throw Oops.Oh("租户不存在");
|
|
|
|
|
}
|
|
|
|
|
// 判断用户名和密码是否正确(排除全局多租户过滤器)Filter(null,true)
|
|
|
|
|
var user = _sysUserRep.AsQueryable().Filter(null, true)
|
|
|
|
|
.Where(m => m.TenantId == input.TenantId)
|
|
|
|
|
.First(u => u.Account.Equals(input.Account) && !u.IsDeleted);
|
|
|
|
|
_ = user ?? throw Oops.Oh(ErrorCode.D1000);
|
|
|
|
|
|
|
|
|
|
// 验证账号是否被冻结
|
|
|
|
|
if (user.Status == CommonStatus.DISABLE)
|
|
|
|
|
throw Oops.Oh(ErrorCode.D1017);
|
|
|
|
|
|
|
|
|
|
// 生成Token令牌
|
|
|
|
|
//var accessToken = await _jwtBearerManager.CreateTokenAdmin(user);
|
|
|
|
|
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ ClaimConst.CLAINM_USERID, user.Id },
|
|
|
|
|
{ ClaimConst.TENANT_ID, user.TenantId },
|
|
|
|
|
{ ClaimConst.CLAINM_ACCOUNT, user.Account },
|
|
|
|
|
{ ClaimConst.CLAINM_NAME, user.Name },
|
|
|
|
|
{ ClaimConst.CLAINM_SUPERADMIN, user.AdminType },
|
|
|
|
|
{ ClaimConst.CLAINM_TENANT_TYPE, tenant.TenantType },
|
|
|
|
|
{ ClaimConst.TENANT_NAME, tenant.Name },
|
|
|
|
|
{ ClaimConst.DjyCompanyId, tenant.CompId == null ? string.Empty : tenant.CompId },
|
|
|
|
|
{ ClaimConst.DjyUserId, user.DjyUserId },
|
|
|
|
|
{ ClaimConst.Tel, user.Tel },
|
|
|
|
|
{ ClaimConst.Phone, user.Phone },
|
|
|
|
|
{ ClaimConst.Email, user.Email },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 设置Swagger自动登录
|
|
|
|
|
_httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
|
|
|
|
|
|
|
|
|
|
var jwtSettinng = App.GetConfig<JWTSettingsOptions>("JWTSettingsOptions");
|
|
|
|
|
|
|
|
|
|
// 生成刷新Token令牌
|
|
|
|
|
var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, jwtSettinng.RefreshTokenExpired);
|
|
|
|
|
|
|
|
|
|
// 设置刷新Token令牌
|
|
|
|
|
_httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
|
|
|
|
|
|
|
|
|
|
var httpContext = App.HttpContext;
|
|
|
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource("Update:UserLoginInfo",
|
|
|
|
|
new SysUser { Id = user.Id, LastLoginIp = httpContext.GetLocalIpAddressToIPv4(), LastLoginTime = DateTime.Now }));
|
|
|
|
|
return accessToken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取当前登录用户信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("getLoginUser")]
|
|
|
|
|
public async Task<LoginOutput> GetLoginUserAsync()
|
|
|
|
|
{
|
|
|
|
|
var user = _sysUserRep.Single(UserManager.UserId);
|
|
|
|
|
var userId = user.Id;
|
|
|
|
|
|
|
|
|
|
var httpContext = App.GetService<IHttpContextAccessor>().HttpContext;
|
|
|
|
|
var loginOutput = user.Adapt<LoginOutput>();
|
|
|
|
|
|
|
|
|
|
loginOutput.LastLoginTime = user.LastLoginTime = DateTime.Now;
|
|
|
|
|
var ip = HttpNewUtil.Ip;
|
|
|
|
|
loginOutput.LastLoginIp = user.LastLoginIp =
|
|
|
|
|
string.IsNullOrEmpty(user.LastLoginIp) ? HttpNewUtil.Ip : ip;
|
|
|
|
|
|
|
|
|
|
var clent = Parser.GetDefault().Parse(httpContext.Request.Headers["User-Agent"]);
|
|
|
|
|
loginOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major;
|
|
|
|
|
loginOutput.LastLoginOs = clent.OS.Family + clent.OS.Major;
|
|
|
|
|
|
|
|
|
|
// 员工信息
|
|
|
|
|
loginOutput.LoginEmpInfo = await _sysEmpService.GetEmpInfo(userId);
|
|
|
|
|
|
|
|
|
|
// 角色信息
|
|
|
|
|
loginOutput.Roles = await _sysRoleService.GetUserRoleList(userId);
|
|
|
|
|
|
|
|
|
|
// 权限信息
|
|
|
|
|
loginOutput.Permissions = await _sysMenuService.GetLoginPermissionList(userId);
|
|
|
|
|
|
|
|
|
|
// 数据范围信息(机构Id集合)
|
|
|
|
|
loginOutput.DataScopes = await DataFilterExtensions.GetDataScopeIdList();
|
|
|
|
|
|
|
|
|
|
// 具备应用信息(多系统,默认激活一个,可根据系统切换菜单),返回的结果中第一个为激活的系统
|
|
|
|
|
loginOutput.Apps = await _sysAppService.GetLoginApps(userId);
|
|
|
|
|
|
|
|
|
|
// 菜单信息
|
|
|
|
|
if (loginOutput.Apps.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var defaultActiveAppCode = loginOutput.Apps.FirstOrDefault().Code;
|
|
|
|
|
loginOutput.Menus = await _sysMenuService.GetLoginMenusAntDesign(userId, "");
|
|
|
|
|
loginOutput.Menus.ForEach(item => { item.Hidden = item.Application != defaultActiveAppCode; });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回前端需要使用的租户参数
|
|
|
|
|
var paraCodeArr = new string[] { TenantParamCode.ENABLE_SLOT_ABILITY, TenantParamCode.ENABLE_FEE_ABILITY, TenantParamCode.VESSEL_FROM_CONFIG_ONLY,
|
|
|
|
|
TenantParamCode.BOOKING_CHANNEL_SELECT_SHOW, TenantParamCode.BC_TASK_CREATE_ORDER,TenantParamCode.BOOKING_SUB_TENANT,TenantParamCode.DESCRIP_CAN_CHINESE,
|
|
|
|
|
TenantParamCode.BOOKING_LIST_SHOW_CANCEL,TenantParamCode.ERP_CODE_CAN_EDIT};
|
|
|
|
|
loginOutput.TenantParams = await _djyTenantParamService.GetParaCodeWithValue(paraCodeArr);
|
|
|
|
|
|
|
|
|
|
//多账号关联
|
|
|
|
|
var accRela = await _sysUserAccountRelation.AsQueryable().Filter(null, true).Where(x => x.UserId == userId && x.IsDeleted == false).FirstAsync();
|
|
|
|
|
if (accRela != null)
|
|
|
|
|
{
|
|
|
|
|
var accRelaList = await _sysUserAccountRelation.AsQueryable().Filter(null, true).Where(x => x.GroupId == accRela.GroupId && x.IsDeleted == false && x.UserId != userId).ToListAsync();
|
|
|
|
|
loginOutput.UserAccountRelation = accRelaList.Adapt<List<UserAccountRelationDto>>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 增加登录日志
|
|
|
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource("Create:VisLog",
|
|
|
|
|
new SysLogVis
|
|
|
|
|
{
|
|
|
|
|
Name = user.Name,
|
|
|
|
|
Success = YesOrNot.Y,
|
|
|
|
|
Message = "登录成功",
|
|
|
|
|
Ip = loginOutput.LastLoginIp,
|
|
|
|
|
Browser = loginOutput.LastLoginBrowser,
|
|
|
|
|
Os = loginOutput.LastLoginOs,
|
|
|
|
|
VisType = LoginType.LOGIN,
|
|
|
|
|
VisTime = loginOutput.LastLoginTime,
|
|
|
|
|
Account = user.Name
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
return loginOutput;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 退出
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("logout")]
|
|
|
|
|
public async Task LogoutAsync()
|
|
|
|
|
{
|
|
|
|
|
_httpContextAccessor.HttpContext.SignoutToSwagger();
|
|
|
|
|
var ip = HttpNewUtil.Ip;
|
|
|
|
|
var user = _sysUserRep.Single(UserManager.UserId);
|
|
|
|
|
// 增加退出日志
|
|
|
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource("Create:VisLog",
|
|
|
|
|
new SysLogVis
|
|
|
|
|
{
|
|
|
|
|
Name = user.Name,
|
|
|
|
|
Success = YesOrNot.Y,
|
|
|
|
|
Message = "退出成功",
|
|
|
|
|
VisType = LoginType.LOGOUT,
|
|
|
|
|
VisTime = DateTime.Now,
|
|
|
|
|
Account = user.Account,
|
|
|
|
|
Ip = ip
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取验证码开关
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("getCaptchaOpen")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<bool> GetCaptchaOpen()
|
|
|
|
|
{
|
|
|
|
|
return await _sysConfigService.GetCaptchaOpenFlag();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取验证码(默认点选模式)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("captcha/get")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[NonUnify]
|
|
|
|
|
public async Task<dynamic> GetCaptcha()
|
|
|
|
|
{
|
|
|
|
|
// 图片大小要与前端保持一致(坐标范围)
|
|
|
|
|
return await Task.FromResult(_captchaHandle.CreateCaptchaImage(_captchaHandle.RandomCode(6), 310, 155));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 校验验证码
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("captcha/check")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[NonUnify]
|
|
|
|
|
public async Task<dynamic> VerificationCode(ClickWordCaptchaInput input)
|
|
|
|
|
{
|
|
|
|
|
return await Task.FromResult(_captchaHandle.CheckCode(input));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 使用跳转code登录
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="code"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[HttpPost("/loginWithCode")]
|
|
|
|
|
public async Task<string> LoginWithCode(string code)
|
|
|
|
|
{
|
|
|
|
|
var cfg = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyAuthUrl");
|
|
|
|
|
if (cfg == null || string.IsNullOrEmpty(cfg.Value))
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("未找到大简云授权登录URL配置,请联系管理员");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var djyAuthUrl = cfg.Value;
|
|
|
|
|
if (!djyAuthUrl.EndsWith("/"))
|
|
|
|
|
{
|
|
|
|
|
djyAuthUrl += "/";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var loginUrl = djyAuthUrl + "user/login";
|
|
|
|
|
var infoUrl = djyAuthUrl + "user/info";
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"统一登录:{loginUrl}");
|
|
|
|
|
|
|
|
|
|
//跳转登录
|
|
|
|
|
var result = await loginUrl
|
|
|
|
|
.SetBody(new { code }, "application/json")
|
|
|
|
|
.PostAsStringAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"登录返回:{result}");
|
|
|
|
|
|
|
|
|
|
var jRtn = JObject.Parse(result);
|
|
|
|
|
if (jRtn.GetIntValue("code") == 200)
|
|
|
|
|
{
|
|
|
|
|
var jData = jRtn.GetJObjectValue("data");
|
|
|
|
|
var token = jData.GetStringValue("token");
|
|
|
|
|
|
|
|
|
|
var headers = new Dictionary<string, object>();
|
|
|
|
|
headers.Add("Authorization", $"Bearer {token}");
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"获取登录信息:{infoUrl}");
|
|
|
|
|
|
|
|
|
|
//获取登录信息
|
|
|
|
|
result = await infoUrl
|
|
|
|
|
.SetHeaders(headers)
|
|
|
|
|
.GetAsStringAsync();
|
|
|
|
|
_logger.LogInformation($"登录信息返回:{result}");
|
|
|
|
|
jRtn = JObject.Parse(result);
|
|
|
|
|
if (jRtn.GetIntValue("code") == 200)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
jData = jRtn.GetJObjectValue("data");
|
|
|
|
|
|
|
|
|
|
var compId = jData.GetStringValue("compId");
|
|
|
|
|
var comname = jData.GetStringValue("comname");
|
|
|
|
|
var userId = jData.GetStringValue("gid");
|
|
|
|
|
var showname = jData.GetStringValue("showname");
|
|
|
|
|
|
|
|
|
|
var tenant = _sysTenantRep.AsQueryable().Filter(null, true).First(x => x.CompId == compId);
|
|
|
|
|
if (tenant == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah($"{comname}不存在,请先完成公司认证!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var user = _sysUserRep.AsQueryable().Filter(null, true).First(u => u.DjyUserId == userId);
|
|
|
|
|
if (user == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah($"{showname}不存在,请先加入公司{comname}!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return await GetLoginToken(user, tenant);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah(jRtn.GetStringValue("message"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah(jRtn.GetStringValue("message"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 切换登录账号
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="changeTo"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/ChangeLogin")]
|
|
|
|
|
public async Task<string> ChangeLogin(long changeTo)
|
|
|
|
|
{
|
|
|
|
|
var accRela = await _sysUserAccountRelation.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == changeTo && x.IsDeleted == false);
|
|
|
|
|
if (accRela == null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("未找到账号关联数据");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//判断当前用户的账号和要切换到的账号是否在一个关联配置中
|
|
|
|
|
var cc = await _sysUserAccountRelation.AsQueryable().Filter(null, true).CountAsync(x => x.GroupId == accRela.GroupId && x.UserId == UserManager.UserId && x.IsDeleted == false);
|
|
|
|
|
if (cc == 0)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("无权切换到此账号");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var user = await _sysUserRep.AsQueryable().Filter(null, true).FirstAsync(u => u.Id == accRela.UserId);
|
|
|
|
|
|
|
|
|
|
//获取对应租户
|
|
|
|
|
var tenant = _sysTenantRep.Single(user.TenantId);
|
|
|
|
|
// 生成Token令牌
|
|
|
|
|
return await GetLoginToken(user, tenant);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取跨站点登录授权key
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <remarks>默认用户名/密码:admin/admin</remarks>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/GetAuthorizationKey")]
|
|
|
|
|
[AllowAnonymous, ApiUser(ApiCode = "GetAuthorizationKey")]
|
|
|
|
|
public async Task<string> GetAuthorizationKey([Required] GetAuthorizationKeyInput input)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//验证用户ID有效性
|
|
|
|
|
var user = _sysUserRep.AsQueryable().Filter(null, true).Where(u => u.DjyUserId == input.UserId).First();
|
|
|
|
|
|
|
|
|
|
if (user is null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("用户Id不存在");
|
|
|
|
|
}
|
|
|
|
|
//将key写入到redis 并指定五秒过期
|
|
|
|
|
string key = Guid.NewGuid().ToString();
|
|
|
|
|
await _cache.SetTimeoutAsync(key, JsonConvert.SerializeObject(input), TimeSpan.FromSeconds(50));
|
|
|
|
|
//将key返回
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 授权key换取token
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <remarks>默认用户名/密码:admin/admin</remarks>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/GetTokenByAuthorizationKey")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<string> GetTokenByAuthorizationKey([Required] GetTokenByAuthorizationKeyInput input)
|
|
|
|
|
{
|
|
|
|
|
var _repPingTaiUser = App.GetService<SqlSugarRepository<PingTaiUser>>();
|
|
|
|
|
|
|
|
|
|
//判断key有效性
|
|
|
|
|
if (!_cache.Exists(input.Key))
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Bah("授权码无效");
|
|
|
|
|
}
|
|
|
|
|
//获取缓存数据
|
|
|
|
|
GetAuthorizationKeyInput data = JsonConvert.DeserializeObject<GetAuthorizationKeyInput>(_cache.Get(input.Key));
|
|
|
|
|
var datainfo = _sysUserRep.AsQueryable().Filter(null, true).First(u => u.DjyUserId == data.UserId);
|
|
|
|
|
|
|
|
|
|
//如果类型为公司,将公司下所有用户关联出
|
|
|
|
|
if (data.AuthorityType == 2)
|
|
|
|
|
{
|
|
|
|
|
data.Authority = _repPingTaiUser.Where(t => data.Authority.Contains(t.CompId)).Select(t => t.GID).ToList();
|
|
|
|
|
}
|
|
|
|
|
await _cache.SetAsync(datainfo.DjyUserId + "Authorization", data.Authority);
|
|
|
|
|
|
|
|
|
|
//获取对应租户
|
|
|
|
|
var tenant = _sysTenantRep.Single(datainfo.TenantId);
|
|
|
|
|
//颁发token
|
|
|
|
|
return await GetLoginToken(datainfo, tenant);
|
|
|
|
|
}
|
|
|
|
|
}
|