|
|
|
|
using Furion;
|
|
|
|
|
using System;
|
|
|
|
|
using GDZZ.Core;
|
|
|
|
|
using GDZZ.Core.OAuth;
|
|
|
|
|
using Furion.EventBus;
|
|
|
|
|
using GDZZ.Core.Entity;
|
|
|
|
|
using Furion.DataEncryption;
|
|
|
|
|
using GDZZ.Application.Entity;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using GDZZ.Application.Help;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using GDZZ.Core.Service;
|
|
|
|
|
|
|
|
|
|
namespace GDZZ.Application.Service.Auth
|
|
|
|
|
{
|
|
|
|
|
[ApiDescriptionSettings("Application", Name = "Auth", Order = 1)]
|
|
|
|
|
public class AuthService : IAuthService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
#region 仓储
|
|
|
|
|
private readonly SqlSugarRepository<BaseUser> Baseuser; // wx用户仓储
|
|
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRep; // 用户表仓储
|
|
|
|
|
private readonly SqlSugarRepository<SysTenant> _sysTenantRep; //租户仓储
|
|
|
|
|
private readonly SqlSugarRepository<SeIF> Self; //职业仓储
|
|
|
|
|
private readonly SqlSugarRepository<Company> CompanyRep;
|
|
|
|
|
private readonly SqlSugarRepository<MiniPayTake> payTakeRep; //支付仓储
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 服务
|
|
|
|
|
private readonly ICacheService cacheService; //
|
|
|
|
|
private readonly WechatOAuth _wechatOAuth; //微信权限服务
|
|
|
|
|
private readonly IHttpContextAccessor _httpContextAccessor; //http服务
|
|
|
|
|
private readonly IEventPublisher _eventPublisher; //事件写入服务
|
|
|
|
|
#endregion
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取配置文件
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly ThirdParty _oauthConfig;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AuthService(
|
|
|
|
|
IOptions<OAuthOptions> options,
|
|
|
|
|
SqlSugarRepository<BaseUser> Baseuser,
|
|
|
|
|
SqlSugarRepository<SysTenant> sysTenantRep,
|
|
|
|
|
SqlSugarRepository<SysUser> sysUserRep,
|
|
|
|
|
SqlSugarRepository<SeIF> Self,
|
|
|
|
|
SqlSugarRepository<Company> CompanyRep,
|
|
|
|
|
SqlSugarRepository<MiniPayTake> payTakeRep,
|
|
|
|
|
ICacheService cacheService,
|
|
|
|
|
WechatOAuth wechatOAuth,
|
|
|
|
|
IEventPublisher eventPublisher,
|
|
|
|
|
IHttpContextAccessor httpContextAccessor)
|
|
|
|
|
{
|
|
|
|
|
this.CompanyRep= CompanyRep;
|
|
|
|
|
this._eventPublisher= eventPublisher;
|
|
|
|
|
this._sysUserRep = sysUserRep;
|
|
|
|
|
this._sysTenantRep = sysTenantRep;
|
|
|
|
|
this.Baseuser = Baseuser;
|
|
|
|
|
this._httpContextAccessor = httpContextAccessor;
|
|
|
|
|
this.cacheService= cacheService;
|
|
|
|
|
this.Self = Self;
|
|
|
|
|
this.payTakeRep = payTakeRep;
|
|
|
|
|
_wechatOAuth = wechatOAuth;
|
|
|
|
|
_oauthConfig = options.Value.Wechat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 手机端登录
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("/Mini/SignIn")]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<AuthUserOut> SignInAsync(PhoneModel phoneModel)
|
|
|
|
|
{
|
|
|
|
|
AuthUserOut authUserOut = new AuthUserOut();
|
|
|
|
|
|
|
|
|
|
Company company = new Company();
|
|
|
|
|
|
|
|
|
|
//读取凭证
|
|
|
|
|
var tokenModel = await this._wechatOAuth.GetAccessTokenAsync(phoneModel.code);
|
|
|
|
|
//解析电话
|
|
|
|
|
var phoneInfo = MiniProgramUtil.AESDecrypt(phoneModel.encryptedDataStr, tokenModel.SessionKey, phoneModel.iv);
|
|
|
|
|
|
|
|
|
|
//查询系统用户
|
|
|
|
|
var sysUser = this._sysUserRep.AsQueryable()
|
|
|
|
|
.Filter("TenantId", true)
|
|
|
|
|
.First(x => x.Phone == phoneInfo.PhoneNumber);
|
|
|
|
|
|
|
|
|
|
var wxUser = await this.Baseuser.AsQueryable()
|
|
|
|
|
.Filter("TenantId", true)
|
|
|
|
|
.Where(x => x.OpenID == tokenModel.OpenId).SingleAsync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//账号不存在 生成系统账号
|
|
|
|
|
if (sysUser.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
sysUser = await this._sysUserRep.InsertReturnEntityAsync(new SysUser()
|
|
|
|
|
{
|
|
|
|
|
Account = phoneInfo.PurePhoneNumber,
|
|
|
|
|
AdminType = AdminType.None,
|
|
|
|
|
Avatar = "https://gdzongzhi.com/assets/img/logo.png",
|
|
|
|
|
Birthday = DateTime.Now,
|
|
|
|
|
CreatedTime = DateTime.Now,
|
|
|
|
|
CreatedUserId = null,
|
|
|
|
|
CreatedUserName = null,
|
|
|
|
|
Sex = Gender.UNKNOWN,
|
|
|
|
|
Status = CommonStatus.ENABLE,
|
|
|
|
|
Email = null,
|
|
|
|
|
IsDeleted = false,
|
|
|
|
|
Name = phoneInfo.PhoneNumber,
|
|
|
|
|
Password = MD5Encryption.Encrypt("123456"),
|
|
|
|
|
TenantId = 392820661919813,
|
|
|
|
|
Phone = phoneInfo.PhoneNumber,
|
|
|
|
|
NickName = "",
|
|
|
|
|
Tel = null,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//区分不同类型账号
|
|
|
|
|
if (phoneModel.logInType ==(int)UserEnum.JOB)
|
|
|
|
|
{
|
|
|
|
|
if (wxUser.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
wxUser = await this.Baseuser.InsertReturnEntityAsync(new BaseUser()
|
|
|
|
|
{
|
|
|
|
|
UnionId = tokenModel.Unionid,
|
|
|
|
|
CreatedUserId = sysUser.Id,
|
|
|
|
|
CreatedTime = DateTime.Now,
|
|
|
|
|
CreatedUserName = sysUser.Name,
|
|
|
|
|
AvatarUrl = "https://gdzongzhi.com/assets/img/logo.png",
|
|
|
|
|
Status =(int)CommonStatus.ENABLE,
|
|
|
|
|
OpenID = tokenModel.OpenId,
|
|
|
|
|
TenantId = 392820661919813,
|
|
|
|
|
Type = (int)UserEnum.JOB,
|
|
|
|
|
UserName = phoneInfo.PhoneNumber,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
wxUser.Type = (int)UserEnum.JOB;
|
|
|
|
|
var bsUser = await this.Baseuser.UpdateAsync(wxUser);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//如果是企业账号,应该是绑定了企业租户信息
|
|
|
|
|
if (wxUser.IsEmpty()|| wxUser.CompanyID.IsNullOrZero())
|
|
|
|
|
throw Oops.Oh(ErrorCode.xg1002);
|
|
|
|
|
|
|
|
|
|
wxUser.Type= (int)UserEnum.ADVERTISE;
|
|
|
|
|
var bsUser = await this.Baseuser.UpdateAsync(wxUser);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获取公司信息
|
|
|
|
|
company = await this.CompanyRep.SingleAsync(x=>x.Id == wxUser.CompanyID);
|
|
|
|
|
authUserOut.companyDto = company.Adapt<CompanyDto>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (wxUser.IsEmpty() || sysUser.IsEmpty())
|
|
|
|
|
throw Oops.Oh(ErrorCode.xg1002);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var Self = await this.Self.FirstOrDefaultAsync(x => x.CreatedUserId == sysUser.Id);
|
|
|
|
|
|
|
|
|
|
// 获取加密后的密码
|
|
|
|
|
var encryptPassword = MD5Encryption.Encrypt(sysUser.Password);
|
|
|
|
|
|
|
|
|
|
// 验证账号是否被冻结
|
|
|
|
|
if (sysUser.Status == CommonStatus.DISABLE)
|
|
|
|
|
throw Oops.Oh(ErrorCode.D1017);
|
|
|
|
|
//获取对应租户
|
|
|
|
|
var tenant = this._sysTenantRep.Single(sysUser.TenantId);
|
|
|
|
|
|
|
|
|
|
if (tenant.IsNullOrZero())
|
|
|
|
|
throw Oops.Oh(ErrorCode.F1001);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 生成Token令牌
|
|
|
|
|
authUserOut.Token = JWTEncryption.Encrypt(new Dictionary<string, object>
|
|
|
|
|
{
|
|
|
|
|
{ClaimConst.CLAINM_USERID, sysUser.Id},
|
|
|
|
|
{ClaimConst.TENANT_ID, sysUser.TenantId},
|
|
|
|
|
{ClaimConst.CLAINM_ACCOUNT, sysUser.Account},
|
|
|
|
|
{ClaimConst.CLAINM_NAME, sysUser.Name},
|
|
|
|
|
{ClaimConst.CLAINM_SUPERADMIN, sysUser.AdminType},
|
|
|
|
|
{ ClaimConst.CLAINM_TENANT_TYPE, tenant.TenantType },
|
|
|
|
|
{ ClaimConst.CLAINM_TENANT_NAME, tenant.Name },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 设置Swagger自动登录
|
|
|
|
|
_httpContextAccessor.HttpContext.SigninToSwagger(authUserOut.Token);
|
|
|
|
|
|
|
|
|
|
// 生成刷新Token令牌
|
|
|
|
|
var refreshToken = JWTEncryption.GenerateRefreshToken(authUserOut.Token, 30);
|
|
|
|
|
|
|
|
|
|
// 设置刷新Token令牌
|
|
|
|
|
_httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
|
|
|
|
|
|
|
|
|
|
var httpContext = App.HttpContext;
|
|
|
|
|
await _eventPublisher.PublishAsync(new ChannelEventSource("Update:UserLoginInfo",
|
|
|
|
|
new SysUser { Id = sysUser.Id, LastLoginIp = httpContext.GetLocalIpAddressToIPv4(), LastLoginTime = DateTime.Now }));
|
|
|
|
|
|
|
|
|
|
authUserOut.Avatar = sysUser.Avatar;
|
|
|
|
|
authUserOut.Phone = sysUser.Phone;
|
|
|
|
|
authUserOut.Sex = sysUser.Sex;
|
|
|
|
|
authUserOut.UserId = sysUser.Id;
|
|
|
|
|
authUserOut.UserName = sysUser.Name;
|
|
|
|
|
authUserOut.Self = Self.IsEmpty() ? null : Self.Name;
|
|
|
|
|
authUserOut.Type = (UserEnum)wxUser.Type;
|
|
|
|
|
authUserOut.OpenID = tokenModel.OpenId;
|
|
|
|
|
authUserOut.Tenant = tenant.Adapt<TenantOutput>();
|
|
|
|
|
authUserOut.Describe = wxUser.Describe;
|
|
|
|
|
|
|
|
|
|
await this.cacheService.SetUserInfoAsync(authUserOut, authUserOut.UserId);
|
|
|
|
|
return authUserOut;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取当前登录用户信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("/Mini/GetLoginUser")]
|
|
|
|
|
public async Task<AuthUserOut> GetLoginUserAsync()
|
|
|
|
|
{
|
|
|
|
|
return await this.cacheService.GetUserInfoAsync(UserManager.UserId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|