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); } } }