|
@@ -1,5 +1,7 @@
|
|
|
using System.Security.Claims;
|
|
|
+using Fw.Utility.UnifyResponse;
|
|
|
using Hotline.Caching.Interfaces;
|
|
|
+using Hotline.Caching.Services;
|
|
|
using Hotline.Identity;
|
|
|
using Hotline.Identity.Accounts;
|
|
|
using Hotline.Orders;
|
|
@@ -9,16 +11,18 @@ using Hotline.SeedData;
|
|
|
using Hotline.Settings;
|
|
|
using Hotline.Share.Dtos.FlowEngine;
|
|
|
using Hotline.Share.Dtos.Identity;
|
|
|
+using Hotline.Share.Dtos.Snapshot;
|
|
|
using Hotline.Share.Enums.FlowEngine;
|
|
|
using Hotline.Share.Enums.Identity;
|
|
|
+using Hotline.Share.Enums.Snapshot;
|
|
|
+using Hotline.Share.Tools;
|
|
|
+using Hotline.Snapshot;
|
|
|
using Hotline.Users;
|
|
|
using IdentityModel;
|
|
|
-using Microsoft.AspNetCore.Http;
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
using XF.Domain.Authentications;
|
|
|
using XF.Domain.Cache;
|
|
|
-using XF.Domain.Constants;
|
|
|
using XF.Domain.Dependency;
|
|
|
using XF.Domain.Exceptions;
|
|
|
using XF.Domain.Options;
|
|
@@ -29,6 +33,8 @@ namespace Hotline.Application.Identity;
|
|
|
public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
{
|
|
|
private readonly IAccountRepository _accountRepository;
|
|
|
+ private readonly IRepository<Citizen> _citizenRepository;
|
|
|
+ private readonly ISessionContext _sessionContext;
|
|
|
private readonly IAccountDomainService _accountDomainService;
|
|
|
private readonly IRepository<User> _userRepository;
|
|
|
private readonly IJwtSecurity _jwtSecurity;
|
|
@@ -38,8 +44,11 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
private readonly IRepository<Scheduling> _schedulingRepository;
|
|
|
private readonly IOrderDomainService _orderDomainService;
|
|
|
private readonly ISystemSettingCacheManager _systemSettingCacheManager;
|
|
|
+ private readonly IThirdIdentiyService _thirdIdentiyService;
|
|
|
+ private readonly IThirdAccountRepository _thirdAccountRepository;
|
|
|
+ private readonly IRepository<GuiderInfo> _guiderInfoRepository;
|
|
|
|
|
|
- public IdentityAppService(
|
|
|
+ public IdentityAppService(
|
|
|
IAccountRepository accountRepository,
|
|
|
IAccountDomainService accountDomainService,
|
|
|
IRepository<User> userRepository,
|
|
@@ -49,7 +58,12 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
IMessageCodeDomainService messageCodeDomainService,
|
|
|
IRepository<Scheduling> schedulingRepository,
|
|
|
IOrderDomainService orderDomainService,
|
|
|
- ISystemSettingCacheManager systemSettingCacheManager)
|
|
|
+ ISystemSettingCacheManager systemSettingCacheManager,
|
|
|
+ IThirdIdentiyService thirdIdentiyService,
|
|
|
+ IThirdAccountRepository thirdAccountRepository,
|
|
|
+ ISessionContext sessionContext,
|
|
|
+ IRepository<Citizen> citizenRepository,
|
|
|
+ IRepository<GuiderInfo> guiderInfoRepository)
|
|
|
{
|
|
|
_accountRepository = accountRepository;
|
|
|
_accountDomainService = accountDomainService;
|
|
@@ -61,8 +75,12 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
_schedulingRepository = schedulingRepository;
|
|
|
_orderDomainService = orderDomainService;
|
|
|
_systemSettingCacheManager = systemSettingCacheManager;
|
|
|
-
|
|
|
- }
|
|
|
+ _thirdIdentiyService = thirdIdentiyService;
|
|
|
+ _thirdAccountRepository = thirdAccountRepository;
|
|
|
+ _sessionContext = sessionContext;
|
|
|
+ _citizenRepository = citizenRepository;
|
|
|
+ _guiderInfoRepository = guiderInfoRepository;
|
|
|
+ }
|
|
|
|
|
|
public async Task<string> OldToNewLoginAsync(HotlineLoginOldToNewDto dto, CancellationToken cancellationToken)
|
|
|
{
|
|
@@ -214,12 +232,12 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
.FirstAsync(d => d.Id == account.Id);
|
|
|
if (user == null)
|
|
|
throw UserFriendlyException.SameMessage("未查询到用户数据");
|
|
|
- //平均派单
|
|
|
- var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
|
|
|
- if (averageSendOrder)
|
|
|
- {
|
|
|
- await AverageOrderScheduling(account.Id, cancellationToken);
|
|
|
- }
|
|
|
+ //平均派单
|
|
|
+ var averageSendOrder = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.AverageSendOrder).SettingValue[0]);
|
|
|
+ if (averageSendOrder)
|
|
|
+ {
|
|
|
+ await AverageOrderScheduling(account.Id, cancellationToken);
|
|
|
+ }
|
|
|
var jwtOptions = _identityOptionsAccessor.Value.Jwt;
|
|
|
var claims = new List<Claim>
|
|
|
{
|
|
@@ -259,13 +277,13 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
try
|
|
|
{
|
|
|
DateTime time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd"));
|
|
|
-
|
|
|
+
|
|
|
//&& x.AtWork!.Value != true
|
|
|
//根据当前时间获取排班信息
|
|
|
var scheduling = await _schedulingRepository.Queryable()
|
|
|
.Includes(x => x.SchedulingUser)
|
|
|
.Where(x => x.SchedulingTime == time &&
|
|
|
- (x.AtWork == true || x.AtWork == null) &&
|
|
|
+ (x.AtWork == true || x.AtWork == null) &&
|
|
|
x.SchedulingUser.UserId == id)
|
|
|
.OrderBy(x => x.SendOrderNum).FirstAsync(cancellationToken);
|
|
|
if (scheduling != null)
|
|
@@ -280,4 +298,101 @@ public class IdentityAppService : IIdentityAppService, IScopeDependency
|
|
|
// ignored
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取三方令牌
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ /// <exception cref="UserFriendlyException"></exception>
|
|
|
+ public async Task<ApiResponse<TokenOutDto>> GetThredTokenAsync(ThirdTokenInDto dto)
|
|
|
+ {
|
|
|
+ var thirdDto = dto.MapTo<ThirdTokenDto>();
|
|
|
+ thirdDto.AppId = _systemSettingCacheManager.GetSetting(SettingConstants.WxOpenAppId)!.SettingValue.First();
|
|
|
+ thirdDto.Secret = _systemSettingCacheManager.GetSetting(SettingConstants.WxOpenAppSecret)!.SettingValue.First();
|
|
|
+ var thirdToken = await _thirdIdentiyService.GetTokenAsync(thirdDto);
|
|
|
+ if (thirdToken.OpenId.IsNullOrEmpty()) throw new UserFriendlyException("获取微信用户信息失败");
|
|
|
+ var thirdAccount = await _thirdAccountRepository.QueryByOpenIdAsync(thirdToken.OpenId);
|
|
|
+
|
|
|
+ // 新用户注册
|
|
|
+ if (thirdAccount is null)
|
|
|
+ {
|
|
|
+ thirdAccount = thirdToken.MapTo<ThirdAccount>();
|
|
|
+ thirdAccount.Id = await _thirdAccountRepository.AddAsync(thirdAccount);
|
|
|
+ }
|
|
|
+
|
|
|
+ var jwtOptions = _identityOptionsAccessor.Value.Jwt;
|
|
|
+ var claims = new List<Claim>
|
|
|
+ {
|
|
|
+ new(JwtClaimTypes.Subject, thirdAccount.Id),
|
|
|
+ new(JwtClaimTypes.PhoneNumber, thirdAccount.PhoneNumber ?? string.Empty),
|
|
|
+ new(JwtClaimTypes.Scope, jwtOptions.Scope),
|
|
|
+ new(AppClaimTypes.OpenId, thirdAccount.WXOpenId),
|
|
|
+ };
|
|
|
+ var audience = new AudienceTicket(thirdAccount.Id);
|
|
|
+ var expiredSeconds = jwtOptions.Expired <= 0 ? 3600 : jwtOptions.Expired;
|
|
|
+ await _cacheAudience.SetAsync(audience.Id, audience, TimeSpan.FromSeconds(expiredSeconds));
|
|
|
+ var token = _jwtSecurity.EncodeJwtToken(claims, audience.Ticket);
|
|
|
+ if (thirdAccount.PhoneNumber.IsNullOrEmpty())
|
|
|
+ return new ApiResponse<TokenOutDto>
|
|
|
+ {
|
|
|
+ Code = 201,
|
|
|
+ Message = "请绑定手机号码 '/Identity/third/phone'",
|
|
|
+ Result = new TokenOutDto(thirdAccount.CitizenType, token),
|
|
|
+ };
|
|
|
+ return new ApiResponse<TokenOutDto> {
|
|
|
+ Code = 0,
|
|
|
+ Result = new TokenOutDto(thirdAccount.CitizenType, token),
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取微信用户手机号码
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ /// <exception cref="UserFriendlyException"></exception>
|
|
|
+ public async Task GetThirdPhoneAsync(ThirdPhoneInDto dto)
|
|
|
+ {
|
|
|
+ var thirdAccount = await _thirdAccountRepository.QueryByOpenIdAsync(_sessionContext.OpenId)
|
|
|
+ ?? throw new UserFriendlyException(401, "请重新登录");
|
|
|
+
|
|
|
+ var thirdDto = dto.MapTo<ThirdTokenDto>();
|
|
|
+ thirdDto.AppId = _systemSettingCacheManager.GetSetting(SettingConstants.WxOpenAppId)!.SettingValue.First();
|
|
|
+ var thirdPhone = await _thirdIdentiyService.GetPhoneNumberAsync(thirdDto);
|
|
|
+ if (thirdPhone.IsError)
|
|
|
+ throw new UserFriendlyException(thirdPhone.ErrorCode + ":" + thirdPhone.ErrorMessage);
|
|
|
+
|
|
|
+ thirdAccount.PhoneNumber = thirdPhone.PhoneNumber;
|
|
|
+ var guider = await _guiderInfoRepository.Queryable()
|
|
|
+ .Where(m => m.PhoneNumber == thirdAccount.PhoneNumber)
|
|
|
+ .FirstAsync();
|
|
|
+ if (guider is not null)
|
|
|
+ { // 回填网格员信息
|
|
|
+ thirdAccount.UserId = guider.Id;
|
|
|
+ thirdAccount.CitizenType = EReadPackUserType.Gukder;
|
|
|
+ await _thirdAccountRepository.UpdateAsync(thirdAccount);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var citizen = await _citizenRepository.Queryable()
|
|
|
+ .Where(m => m.PhoneNumber == thirdAccount.PhoneNumber)
|
|
|
+ .FirstAsync();
|
|
|
+ if (citizen is not null)
|
|
|
+ {
|
|
|
+ thirdAccount.CitizenType = EReadPackUserType.Citizen;
|
|
|
+ thirdAccount.UserId = citizen.Id;
|
|
|
+ await _thirdAccountRepository.UpdateAsync(thirdAccount);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ citizen = new Citizen
|
|
|
+ {
|
|
|
+ PhoneNumber = thirdAccount.PhoneNumber
|
|
|
+ };
|
|
|
+ thirdAccount.UserId = await _citizenRepository.AddAsync(citizen);
|
|
|
+ thirdAccount.CitizenType = EReadPackUserType.Citizen;
|
|
|
+ await _thirdAccountRepository.UpdateAsync(thirdAccount);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|