using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.SingleData;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Options;
using WMS.Web.Domain.Values.Single;
namespace WMS.Web.Domain.Services.Public
{
///
/// 单点数据返回服务
///
public class SingleDataService : ISingleDataService
{
private readonly AppOptions _options;
private readonly IHttpClientService _httpClientService;
private readonly ILogger _logger;
private readonly IMemoryCache _memoryCache;
private int hours = 10;//过期时间 默认10小时
public SingleDataService(IOptions options, IHttpClientService httpClientService, ILogger logger, IMemoryCache memoryCache)
{
this._memoryCache = memoryCache;
this._options = options?.Value;
this._httpClientService = httpClientService;
this._logger = logger;
}
///
/// 获取单点数据:根据接口方法名和公司ID
/// 后端列表查询统一使用
///
///
///
///
public string GetSingleData(SingleAction action, int companyId, int id)
{
try
{
if (id == 0)
return "";
var cache_key = action + "_" + companyId + "_IdGetName";
var dic = _memoryCache.Get>(cache_key);
if (dic == null || dic.Count <= 0 || !dic.ContainsKey(id))
{
if (dic != null)
{
string no_data_key = cache_key + "_NoData";
var cache_id = _memoryCache.Get(no_data_key);
if (cache_id == true) return "";
//未找到数据请求
if (!dic.ContainsKey(id))
{
_memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
}
}
var list = SingleDataPost(action, companyId, cache_key);
if (list.Count() <= 0) return "";
dic = list.ToDictionary(s => s.Id, s => s.Name);
_memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
}
if (!dic.ContainsKey(id)) return "";
return dic[id];
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:Action->{action.ToString()},CompanyeId->{companyId},Id->{id},(错误原因)=>{ex.Message}");
return "";
}
}
///
/// 获取单点数据:根据接口方法名和公司ID
/// 后端列表查询统一使用
///
///
///
///
public decimal GetSingleDataNumber(SingleAction action, int companyId, int id)
{
try
{
if (id == 0)
return 0;
var cache_key = action + "_" + companyId + "_IdGetNumber";
var dic = _memoryCache.Get>(cache_key);
if (dic == null || dic.Count <= 0 || !dic.ContainsKey(id))
{
if (dic != null)
{
string no_data_key = cache_key + "_NoData";
var cache_id = _memoryCache.Get(no_data_key);
if (cache_id == true) return 0;
//未找到数据请求
if (!dic.ContainsKey(id))
{
_memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
}
}
var list = SingleDataPost(action, companyId, cache_key);
if (list.Count() <= 0) return 0;
dic = list.ToDictionary(s => s.Id, s => s.Number);
_memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
}
if (!dic.ContainsKey(id)) return 0;
return dic[id];
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return 0;
}
}
///
/// 获取单点数据:根据接口方法名和公司ID
/// 后端列表查询统一使用
///
///
///
///
public string GetSingleDataCode(SingleAction action, int companyId, int id)
{
try
{
if (id == 0)
return "";
var cache_key = action + "_" + companyId + "_IdGetCode";
var dic = _memoryCache.Get>(cache_key);
if (dic == null || dic.Count <= 0 || !dic.ContainsKey(id))
{
if (dic != null)
{
string no_data_key = cache_key + "_NoData";
var cache_id = _memoryCache.Get(no_data_key);
if (cache_id == true) return "";
//未找到数据请求
if (!dic.ContainsKey(id))
{
_memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
}
}
var list = SingleDataPost(action, companyId, cache_key);
if (list.Count() <= 0) return "";
dic = list.ToDictionary(s => s.Id, s => s.Code);
_memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
}
if (!dic.ContainsKey(id)) return "";
return dic[id];
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return "";
}
}
///
/// 根据名字模糊匹配
///
///
///
///
///
public List GetIdsBySingleName(SingleAction action, int companyId, string name)
{
try
{
var cache_key = action + "_" + companyId + "_NameGetIds";
var dic = _memoryCache.Get>(cache_key);
if (dic == null || dic.Count <= 0)
{
var list = SingleDataPost(action, companyId, cache_key);
if (list.Count() <= 0) return new List();
dic = list.ToDictionary(s => s.Id, s => s.Name);
_memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
}
var res = from d in dic where d.Value.Contains(name) select d;
return res.Select(s => s.Key).ToList();
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return new List();
}
}
///
/// 获取单点数据:根据接口方法名和公司ID
/// 后端列表查询统一使用
///
///
///
///
public string GetSingleData(SingleAction action, int companyId, string code)
{
try
{
if (string.IsNullOrEmpty(code))
return "";
var cache_key = action + "_" + companyId + "_CodeGetName";
var dic = _memoryCache.Get>(cache_key);
//仓库和客户仓库 不能为空了就重新请求 应为 这里是从仓库和客户仓库取值 有一个必然取不到
if (dic == null || dic.Count <= 0)
{
if (dic != null)
{
string no_data_key = cache_key + "_NoData";
var cache_id = _memoryCache.Get(no_data_key);
if (cache_id == true) return "";
//未找到数据请求
if (!dic.ContainsKey(code))
{
_memoryCache.Set(no_data_key, true, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));
}
}
var list = SingleDataPost(action, companyId, cache_key);
var json = JsonSerializer.Serialize(list);
if (list.Count() <= 0) return "";
dic = list.ToDictionary(s => s.Code, s => s.Name);
_memoryCache.Set(cache_key, dic, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
}
if (!dic.ContainsKey(code)) return "";
var name = dic[code];
return dic[code];
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return "";
}
}
///
/// 获取单点数据集合:泛型-同步
///
///
///
///
///
public List GetSingleData(SingleAction action, int companyId) where T : class
{
try
{
var cache_key = action + "_list_" + companyId;
var list = _memoryCache.Get>(cache_key);
if (list == null || list.Count <= 0)
list = SingleDataPost(action, companyId, cache_key);
return list;
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return null;
}
}
///
/// 获取单点数据集合:泛型-异步
///
///
///
///
///
public async Task> GetSingleDataAsync(SingleAction action, int companyId) where T : class
{
try
{
var cache_key = action + "_list_" + companyId;
var list = _memoryCache.Get>(cache_key);
if (list == null || list.Count <= 0)
list = await SingleDataPostAsync(action, companyId, cache_key);
return list;
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return null;
}
}
///
/// 获取单点数据集合:泛型-异步-无缓存
///
///
///
///
///
public async Task> GetSingleDataNoCacheAsync(SingleAction action, int companyId) where T : class
{
try
{
var list = await SingleDataPostAsync(action, companyId, "");
return list;
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return null;
}
}
///
/// 单点数据:可对接全部接口
///
/// 返回对象
/// 请求对象
/// 方法名称
/// 请求对象
/// 方法名称
/// 控制器名称
///
public async Task GetSingleData(X dto, Y action, SingleControllerType type = SingleControllerType.Single) where T : class
{
try
{
var para = JsonExtensions.SerializeToJson(dto);
var cache_key = action + "_list_" + type + "_" + para;
var list = _memoryCache.Get(cache_key);
if (list == null)
{
var url = _options.SingleBaseUrl + "/" + type.ToString() + "/" + action.ToString();
var result = await _httpClientService.PostAsync(url, para);
_memoryCache.Set(cache_key, result, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
}
return _memoryCache.Get(cache_key);
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return default(T);
}
}
///
/// 单点数据:可对接全部接口
///
/// 返回对象
/// 请求对象
/// 方法名称
/// 请求对象
/// 方法名称
/// 控制器名称
///
public async Task GetSingleDataNoCache(X dto, Y action, SingleControllerType type = SingleControllerType.Single) where T : class
{
try
{
var para = JsonExtensions.SerializeToJson(dto);
var url = _options.SingleBaseUrl + "/" + type.ToString() + "/" + action.ToString();
var result = await _httpClientService.PostAsync(url, para);
return result;
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return default(T);
}
}
///
/// 获取单点数据:配置项接口
///
///
///
///
///
///
public async Task GetSysConfigData(X dto, SysConfigAction action)
{
try
{
var para = JsonExtensions.SerializeToJson(dto);
var url = _options.SingleBaseUrl + "/" + SingleControllerType.SysConfig.ToString() + "/" + action.ToString();
var result = await _httpClientService.PostAsync(url, para);
return result;
}
catch (Exception ex)
{
_logger.LogError($"请求单点数据错误:{action.ToString()}=>{ex.Message}");
return default(T);
}
}
#region 私有方法
///
/// 请求单点服务接口:同步
///
///
///
///
///
private List SingleDataPost(SingleAction action, int companyId, string cache_key)
{
var dto = new SingleDataRequest(companyId);
//var para = JsonExtensions.SerializeToJson(dto);
var para = JsonSerializer.Serialize(dto);
var url = _options.SingleBaseUrl + "/" + SingleControllerType.Single.ToString() + "/" + action.ToString();
var result = _httpClientService.PostAsync>(url, para).GetAwaiter().GetResult();
if (!result.Success)
return new List();
return result.Data.ToList();
}
///
/// 请求单点服务接口:异步
///
///
///
///
///
private async Task> SingleDataPostAsync(SingleAction action, int companyId, string cache_key)
{
var dto = new SingleDataRequest(companyId);
var para = JsonSerializer.Serialize(dto);
var url = _options.SingleBaseUrl + "/" + SingleControllerType.Single.ToString() + "/" + action.ToString();
var result = await _httpClientService.PostAsync>(url, para);
if (result.Success)
{
if (!string.IsNullOrEmpty(cache_key))
{
_memoryCache.Set(cache_key, result.Data.ToList(), new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(hours)));
return _memoryCache.Get>(cache_key);
}
return result.Data.ToList();
}
return null;
}
#endregion
///
/// 获取客户仓库
///
///
///
///
public string GetCustomerStock(int companyId, string customerStockCode)
{
return string.IsNullOrEmpty(this.GetSingleData(SingleAction.CustomerStocks, companyId, customerStockCode)) ?
this.GetSingleData(SingleAction.Stocks, companyId, customerStockCode) :
this.GetSingleData(SingleAction.CustomerStocks, companyId, customerStockCode);
}
}
}