using Microsoft.EntityFrameworkCore; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using RB_MES_API.Context; using RB_MES_API.Models; using RB_MES_API.Models.Cloud; using RB_MES_API.Models.Pangu; using RB_MES_APICore.Models; using System.Data; using System.Reflection; using RB_MES_API.Controllers.Cloud; using System.Threading; using Kingdee.CDP.WebApi.SDK; namespace RB_MES_API.Controllers { public sealed class PushBackgroundService : BackgroundService { private readonly Task _completedTask = Task.CompletedTask; private List _timer = new List(); private readonly IServiceScopeFactory _serviceScopeFactory; /// /// /// /// public PushBackgroundService(IServiceScopeFactory serviceScopeFactory) { _serviceScopeFactory = serviceScopeFactory; } /// /// /// public class ClientRequestStr { /// /// 从沃比服务器取回来的加密字符串 /// public string token { get; set; } = string.Empty; /// /// 客户基本资料的信用代码 /// public string FKey { get; set; } = string.Empty; /// /// 组织机构:软件34,科技35 /// public string organization { get; set; } = "34"; /// /// 合同号 /// public string contractno { get; set; } = "230523"; } /// /// 执行异步定时器 /// public async void DoTimerWorkAsyn() { try { string v = LocalStaticRequest.GetSystemProfile(1, "AutoPushTask"); int.TryParse(v, out int at); if (at > 0) { //只要FTimer > 0的接口都有一个属于自己的定时器! using var scope = _serviceScopeFactory.CreateScope(); IShareController myScopedService = scope.ServiceProvider.GetRequiredService(); List systimeds = await myScopedService.GetAPIList(); scope.Dispose(); if (systimeds == null) { return; } var sys = from a in systimeds select new { worktime = a.FTimer, name = a.FDocType }; foreach (var item in sys) { _timer.Add(new Timer(DoWork, item.name, TimeSpan.Zero, TimeSpan.FromMinutes(item.worktime))); } } } catch (Exception ex) { LogHelper.WriteLog(string.Format("PushBackgroundService的DoTimerWorkAsyn发生错误:{0}", ex.Message)); } } /// /// 优先加载系统必须的静态数据 /// private void LoadLocalStaticRequest() { try { //如果缓存中不存在,就从数据库里取出来再放进缓存 List sys = CacheHelper.GetCache>("sys"); if (sys == null) { using var scope = _serviceScopeFactory.CreateScope(); RBContext myScopedService = scope.ServiceProvider.GetRequiredService(); //先初始化全局变量 sys = myScopedService.r_SystemProfiles!.AsNoTracking().ToList(); if (sys.Any()) { CacheHelper.Set_AbsluteExpire("sys", sys); } scope.Dispose(); } //无论是否推送,静态全局设置应该首先加载 LocalStaticRequest.sysprofile = sys; //string svurl = LocalStaticRequest.GetSystemProfile(4, "TokenUrl"); string orgid = LocalStaticRequest.GetSystemProfile(2, "DefaultORGID"); string orgno = LocalStaticRequest.GetSystemProfile(2, "DefaultORG"); LocalStaticRequest.DefaultOrgID = string.IsNullOrEmpty(orgid) ? 1 : int.Parse(orgid); LocalStaticRequest.DefaultOrg = string.IsNullOrEmpty(orgno) ? "100" : orgno; string tokenstr = LocalStaticRequest.GetSystemProfile(4, "TokenPWD"); //客户基本资料的信用代码 string acctid = ApiSettingsHelper.GetConfig("X-KDApi-AcctID"); string appid = ApiSettingsHelper.GetConfig("X-KDApi-AppID"); string sppsec = ApiSettingsHelper.GetConfig("X-KDApi-AppSec"); string apiurl = ApiSettingsHelper.GetConfig("X-KDApi-ServerUrl"); string usname = ApiSettingsHelper.GetConfig("X-KDApi-UserName"); int lcid = 0; int.TryParse(ApiSettingsHelper.GetConfig("X-KDApi-LCID"), out lcid); LocalStaticRequest.cloudApi.InitClient(acctid, appid, sppsec, usname, lcid, orgno, apiurl); } catch (Exception ex) { //如果金蝶Cloud登录失败,就会发生异常,可能导致程序崩溃... string msg = ex.Message; LogHelper.WriteLog(string.Format("PushBackgroundService的LoadHostFunctionAsync发生错误:{0}", msg)); } } /// /// /// /// private async void AddUnitCache(object state) { try { using var scope = _serviceScopeFactory.CreateScope(); IKDCloudHttpClient myScopedService = scope.ServiceProvider.GetRequiredService(); string messstr = string.Empty; string fileds = "FUNITID,FNumber,FName,FIsBaseUnit,FPrecision,FDocumentStatus,FForbidStatus,FConvertDenominator,FConvertNumerator,FRoundType"; BillQuery queryJson = new BillQuery() { FieldKeys = fileds, FormId = "BD_UNIT", FilterString = "FDOCUMENTSTATUS='C' AND FFORBIDSTATUS='A'" }; //从云星空查询 string result = myScopedService.SDKBillQuery(queryJson); if (myScopedService.SDKBillQueryStatus(result)) { IShareController myScopedService1 = scope.ServiceProvider.GetRequiredService(); List units = myScopedService1.GetNewObjForChild(fileds, result, ref messstr); if (units.Count > 0) { CacheHelper.Set_AbsluteExpire("BD_UNIT", units); } } scope.Dispose(); } catch (Exception e) { LogHelper.WriteLog(string.Format("PushBackgroundService的AddUnitCache发生错误:{0}", e.Message)); } } private void DoWork(object state) { try { using var scope = _serviceScopeFactory.CreateScope(); IShareController myScopedService = scope.ServiceProvider.GetRequiredService(); List queryJsons = myScopedService.GetAPIList().Result; scope.Dispose(); var clouds = queryJsons.Where(s => s.GetFormID.FDocType == state.ToString()).ToList(); if (clouds.Count > 0) { new TaskFactory().StartNew(() => { CloudBillQuery query = clouds.FirstOrDefault(); Type type = this.GetType(); MethodInfo? methodInfo = type.GetMethod(query.GetFormID.FActionName); if (methodInfo != null) { object[] para = new object[] { query.GetFormID.FID, query.GetFormID.functions.FUrl }; methodInfo.Invoke(this, para); } }); } } catch (Exception ex) { LogHelper.WriteLog(string.Format("PushBackgroundService的BackgroundServiceWork发生错误:{0}", ex.Message)); } } /// /// 将自定义SQL查询结果推送给MES /// /// /// public void GetSelfDBbaseAsync(int formtypeid, string url) { using var scope = _serviceScopeFactory.CreateScope(); IShareController myScopedService = scope.ServiceProvider.GetRequiredService(); IChiledSelect myChiledSelect = scope.ServiceProvider.GetRequiredService(); string result = myChiledSelect.GetCustomRequestTBAsync(formtypeid).Result; List query = myScopedService.GetAPIList().Result; if (query.Count == 0) { scope.Dispose(); return; }; string doctype = query.Find(s => s.FFormIDTypeID == formtypeid).GetFormID.FDocType; if (string.IsNullOrEmpty(result)) { scope.Dispose(); return; }; try { JArray array = (JArray)JsonConvert.DeserializeObject(result); if (array == null || array.Count == 0) { scope.Dispose(); return; }; PanguPostBill mes = new PanguPostBill() { DocType = doctype, DataSet = myScopedService.GetClassList(array) }; string json = JsonConvert.SerializeObject(mes); //推送给MES IKDCloudHttpClient myhttpclient = scope.ServiceProvider.GetRequiredService(); PanguBreakJson mesjson = myhttpclient.PushMesData(json).Result; if (mesjson.Status) { LogHelper.WriteLog(string.Format("推送【{0}】成功:{1}", doctype, json), doctype); } else { LogHelper.WriteLog(string.Format("PushBackgroundService的GetSelfDBbaseAsync方法推送【{0}】失败:{1}\n原始数据:{2}", doctype, mesjson.Message, json), doctype); } } catch (Exception ex) { LogHelper.WriteLog(string.Format("PushBackgroundService推送【{0}】动态GetSelfDBbaseAsync方法出错:{1}", doctype, ex.Message), doctype); } finally { if (scope != null) scope.Dispose(); } } /// /// 查询Cloud表单。 /// /// /// public async void GetBDbase(int formtypeid, string url) { string reason = string.Empty; using var scope = _serviceScopeFactory.CreateScope(); IShareController myScopedService = scope.ServiceProvider.GetRequiredService(); IKDCloudHttpClient myScopedService1 = scope.ServiceProvider.GetRequiredService(); List queryJsons = await myScopedService.GetAPIList(); if (queryJsons.Count == 0) { LogHelper.WriteLog("PushBackgroundService的GetBDbase方法_shareController.GetAPIList()缓存过期"); } else { var formtype = queryJsons.Where(s => s.GetFormID.FID == formtypeid).FirstOrDefault()!.GetFormID; int fid = formtype.FFunctionID; string doctype = formtype.FDocType; var queryJson = from a in queryJsons.Where(s => s.GetFormID.FID == formtypeid) select new BillQuery { FieldKeys = a.FFieldKeys.Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg), FormId = a.GetFormID.FDBName, FilterString = a.FFiledString.Replace("GETDATE", DateTime.Now.ToShortDateString()).Replace("@defaultorgid", LocalStaticRequest.DefaultOrgID.ToString()).Replace("@defaultorgno", LocalStaticRequest.DefaultOrg), Limit = a.FLimit, OrderString = a.FOrderString, StartRow = a.FStartRow, SubSystemId = a.FSubSystemID, TopRowCount = a.FTopRowCount }; if (queryJson.Any()) { try { string result = myScopedService1.SDKBillQuery(queryJson.FirstOrDefault()); if (myScopedService1.SDKBillQueryStatus(result)) { string fileds = queryJson.FirstOrDefault()!.FieldKeys!; DataTable dt = myScopedService.JsonConvertDatatable(fileds, result, ref reason); if (!string.IsNullOrEmpty(reason)) { goto EBread; } if (dt.Rows.Count > 0) { List> dic = GetClassList(fid, doctype, dt); if (dic.Any()) { PanguPostBill mes = new PanguPostBill() { DocType = doctype, DataSet = dic }; string json = JsonConvert.SerializeObject(mes); //推送给MES IKDCloudHttpClient myhttpclient = scope.ServiceProvider.GetRequiredService(); PanguBreakJson mesjson = await myhttpclient.PushMesData(json); if (mesjson.Status) { reason = string.Format("推送【{0}】成功:{1}", doctype, json); } else { reason = string.Format("PushBackgroundService的GetBDbase方法推送【{0}】失败:{1}\r原始数据:{2}", doctype, mesjson.Message, json); } } else { reason = string.Format("PushBackgroundService的GetBDbase方法推送【{0}】失败:!GetClassList(fid, doctype, dt)Any():{1}}", doctype, result); } } } } catch (Exception ex) { reason = string.Format("PushBackgroundService的GetBDbase方法推送【{0}】过程中发生错误:{1}", doctype, ex.Message); } } EBread: if (!string.IsNullOrEmpty(reason)) { LogHelper.WriteLog(reason, doctype); } } scope.Dispose(); } private List> GetClassList(int fid, string decname, DataTable table) { using var scope = _serviceScopeFactory.CreateScope(); IShareController myScopedService = scope.ServiceProvider.GetRequiredService(); List> list = new List>(); List scc = myScopedService.GetAPIList().Result; scope.Dispose(); scc = scc.Where(s => s.FFunctionID == fid && s.FDesTableName.Equals(decname)).ToList(); if (scc.Any()) { foreach (DataRow row in table.Rows) { Dictionary keyValuePairs = new Dictionary(); foreach (SelectClumnConvert clumnConvert in scc) { string oldname = clumnConvert.FSourceName; if (table.Columns.Contains(oldname)) { string newname = clumnConvert.FDesName; keyValuePairs.Add(newname, row[oldname].ToString()!); } } list.Add(keyValuePairs); } } return list; } /// public override Task StopAsync(CancellationToken cancellationToken) { //t调用 StopAsync时触发cancellationToken改变 DisposeAsync(); return _completedTask; } /// public ValueTask DisposeAsync() { foreach (var item in _timer) { item.DisposeAsync(); } return ValueTask.CompletedTask; } /// protected override Task ExecuteAsync(CancellationToken stoppingToken) { if (ExecuteTask == null) { try { LoadLocalStaticRequest(); DoTimerWorkAsyn(); //只有云星空项目才执行 string sysg = LocalStaticRequest.GetSystemProfile(1, "APIGrouID"); if (sysg == "8") { LogHelper.WriteLog(string.Format("_timer.Count={0}", _timer.Count)); _timer.Add(new Timer(AddUnitCache, null, TimeSpan.Zero, TimeSpan.FromMinutes(20))); } } catch (Exception ex) { LogHelper.WriteLog(string.Format("本地服务启动PushBackgroundService的ExecuteAsync方法发生错误:{0}", ex.Message)); StopAsync(stoppingToken); } } return _completedTask; } } }