161 lines
6.7 KiB
C#
161 lines
6.7 KiB
C#
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using Dlhis.Middle.Entities;
|
|
using Dlhis.Middle.Response;
|
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
|
using Kurisu.AspNetCore.UnifyResultAndValidation;
|
|
using Kurisu.AspNetCore.Utils.Extensions;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Dlhis.Middle.Services.Implements;
|
|
|
|
public class BalanceRecordCheckBackgroundService : BackgroundService
|
|
{
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly ILogger<BalanceRecordCheckBackgroundService> _logger;
|
|
private readonly IMemoryCache _memoryCache;
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
|
|
private readonly IHealthCheckService _healthCheckService;
|
|
|
|
private readonly string _factory;
|
|
private readonly string _hostName;
|
|
|
|
public BalanceRecordCheckBackgroundService(IServiceProvider serviceProvider,
|
|
ILogger<BalanceRecordCheckBackgroundService> logger,
|
|
IMemoryCache memoryCache,
|
|
IHttpClientFactory httpClientFactory,
|
|
IHealthCheckService healthCheckService,
|
|
IConfiguration configuration)
|
|
{
|
|
_serviceProvider = serviceProvider;
|
|
_logger = logger;
|
|
_memoryCache = memoryCache;
|
|
_httpClientFactory = httpClientFactory;
|
|
_healthCheckService = healthCheckService;
|
|
_factory = configuration.GetSection("Factory").Value;
|
|
_hostName = configuration.GetSection("HostName").Value;
|
|
}
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
if (!_healthCheckService.GetIsOffline())
|
|
{
|
|
var now = DateTime.Now;
|
|
|
|
using var scope = _serviceProvider.CreateScope();
|
|
var db = scope.ServiceProvider.GetService<IDbContext>();
|
|
var ds = scope.ServiceProvider.GetService<IDataDownloadService>();
|
|
|
|
foreach (var factory in _factory.Split(','))
|
|
{
|
|
try
|
|
{
|
|
var balanceRecords = await db.Queryable<LocalBalanceRecordEntity>().Where(x => x.TenantId == factory).Where(x => !x.IsSync).ToListAsync(stoppingToken);
|
|
if (balanceRecords.Any())
|
|
{
|
|
_logger.LogInformation("上传离线订单");
|
|
foreach (var balanceRecord in balanceRecords)
|
|
{
|
|
//事务
|
|
await db.Client.Ado.BeginTranAsync();
|
|
try
|
|
{
|
|
//设置为已同步
|
|
balanceRecord.IsSync = true;
|
|
await db.UpdateAsync(balanceRecord);
|
|
|
|
var r = await UploadAsync(balanceRecord);
|
|
if (r.Code == ApiStateCode.Success)
|
|
{
|
|
var d = r.Data;
|
|
//更新本地余额表
|
|
await db.Updateable<LocalGainfoMealEntity>()
|
|
.SetColumns(x => x.Balance == d.Balance)
|
|
.Where(x => x.UserCode == d.UserCode)
|
|
.ExecuteCommandAsync(stoppingToken);
|
|
|
|
await db.Client.Ado.CommitTranAsync();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.LogError(e, "{factory}上传离线消费失败:{message}", factory, e.Message);
|
|
await db.Client.Ado.RollbackTranAsync();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.LogError(e, "{factory}同步离线数据失败:{message}", factory, e.Message);
|
|
}
|
|
}
|
|
|
|
|
|
if (now is { Hour: 4, Minute: 1 }
|
|
&& !_healthCheckService.GetIsOffline()
|
|
&& !await db.Queryable<LocalBalanceRecordEntity>().Where(x => !x.IsSync).AnyAsync())
|
|
{
|
|
await ds.InitAsync(_factory);
|
|
}
|
|
else if (now is { Hour: 15, Minute: 1 }
|
|
&& !_healthCheckService.GetIsOffline()
|
|
&& !await db.Queryable<LocalBalanceRecordEntity>().Where(x => !x.IsSync).AnyAsync())
|
|
{
|
|
await ds.InitAsync(_factory);
|
|
}
|
|
else if (now is { Hour: 20, Minute: 1 }
|
|
&& !_healthCheckService.GetIsOffline()
|
|
&& !await db.Queryable<LocalBalanceRecordEntity>().Where(x => !x.IsSync).AnyAsync())
|
|
{
|
|
await ds.InitAsync(_factory);
|
|
}
|
|
}
|
|
|
|
await Task.Delay(60 * 1000, stoppingToken);
|
|
}
|
|
}
|
|
|
|
public async Task<DefaultApiResult<OrderResultResponse>> UploadAsync(LocalBalanceRecordEntity entity)
|
|
{
|
|
var token = await AuthAsync();
|
|
|
|
var httpClient = _httpClientFactory.CreateClient("face");
|
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
|
|
|
var url = $"https://{_hostName}/api/canteen/middle/upload";
|
|
|
|
var json = entity.ToJson();
|
|
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
|
|
|
var response = await httpClient.PostAsync(url, content);
|
|
var responseJson = await response.Content.ReadAsStringAsync();
|
|
return responseJson.ToObject<DefaultApiResult<OrderResultResponse>>();
|
|
}
|
|
|
|
private async Task<string> AuthAsync()
|
|
{
|
|
var httpClient = _httpClientFactory.CreateClient("face");
|
|
|
|
if (_memoryCache.TryGetValue("token", out string token)) return token;
|
|
|
|
var tokenResponse = await httpClient.PostAsync($"https://{_hostName}/api/User/OAuth2/clientgrant", new StringContent(JsonConvert.SerializeObject(new
|
|
{
|
|
ClientId = "e509c2aaa98e300c",
|
|
ClientSecret = "6184d8979fc48105"
|
|
}), Encoding.UTF8, "application/json"));
|
|
|
|
var tokenJson = await tokenResponse.Content.ReadAsStringAsync();
|
|
var tokenInfo = JsonConvert.DeserializeObject<DefaultApiResult<TokenResponse>>(tokenJson);
|
|
|
|
token = tokenInfo.Data.AccessToken;
|
|
|
|
_memoryCache.Set("token", token, TimeSpan.FromSeconds(tokenInfo.Data.Expires));
|
|
|
|
return token;
|
|
}
|
|
} |