Files
RBMESAPICore/Controllers/Cloud/HostService/PushBackgroundService.cs

403 lines
19 KiB
C#
Raw Normal View History

2025-09-09 22:41:29 +08:00
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> _timer = new List<Timer>();
private readonly IServiceScopeFactory _serviceScopeFactory;
/// <summary>
///
/// </summary>
/// <param name="serviceScopeFactory"></param>
public PushBackgroundService(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
}
/// <summary>
///
/// </summary>
public class ClientRequestStr
{
/// <summary>
/// 从沃比服务器取回来的加密字符串
/// </summary>
public string token { get; set; } = string.Empty;
/// <summary>
/// 客户基本资料的信用代码
/// </summary>
public string FKey { get; set; } = string.Empty;
/// <summary>
/// 组织机构软件34科技35
/// </summary>
public string organization { get; set; } = "34";
/// <summary>
/// 合同号
/// </summary>
public string contractno { get; set; } = "230523";
}
/// <summary>
/// 执行异步定时器
/// </summary>
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<IShareController>();
List<ApiHostService> systimeds = await myScopedService.GetAPIList<ApiHostService>();
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));
}
}
/// <summary>
/// 优先加载系统必须的静态数据
/// </summary>
private void LoadLocalStaticRequest()
{
try
{
//如果缓存中不存在,就从数据库里取出来再放进缓存
List<SystemProfile> sys = CacheHelper.GetCache<List<SystemProfile>>("sys");
if (sys == null)
{
using var scope = _serviceScopeFactory.CreateScope();
RBContext myScopedService = scope.ServiceProvider.GetRequiredService<RBContext>();
//先初始化全局变量
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));
}
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
private async void AddUnitCache(object state)
{
try
{
using var scope = _serviceScopeFactory.CreateScope();
IKDCloudHttpClient myScopedService = scope.ServiceProvider.GetRequiredService<IKDCloudHttpClient>();
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<IShareController>();
List<BD_UNIT> units = myScopedService1.GetNewObjForChild<BD_UNIT>(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<IShareController>();
List<CloudBillQuery> queryJsons = myScopedService.GetAPIList<CloudBillQuery>().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));
}
}
/// <summary>
/// 将自定义SQL查询结果推送给MES
/// </summary>
/// <param name="formtypeid"></param>
/// <param name="url"></param>
public void GetSelfDBbaseAsync(int formtypeid, string url)
{
using var scope = _serviceScopeFactory.CreateScope();
IShareController myScopedService = scope.ServiceProvider.GetRequiredService<IShareController>();
IChiledSelect myChiledSelect = scope.ServiceProvider.GetRequiredService<IChiledSelect>();
string result = myChiledSelect.GetCustomRequestTBAsync(formtypeid).Result;
List<CloudBillQuery> query = myScopedService.GetAPIList<CloudBillQuery>().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<IKDCloudHttpClient>();
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(); }
}
/// <summary>
/// 查询Cloud表单。
/// </summary>
/// <param name="formtypeid"></param>
/// <param name="url"></param>
public async void GetBDbase(int formtypeid, string url)
{
string reason = string.Empty;
using var scope = _serviceScopeFactory.CreateScope();
IShareController myScopedService = scope.ServiceProvider.GetRequiredService<IShareController>();
IKDCloudHttpClient myScopedService1 = scope.ServiceProvider.GetRequiredService<IKDCloudHttpClient>();
List<CloudBillQuery> queryJsons = await myScopedService.GetAPIList<CloudBillQuery>();
if (queryJsons.Count == 0)
{
LogHelper.WriteLog("PushBackgroundService的GetBDbase方法_shareController.GetAPIList<CloudBillQuery>()缓存过期");
}
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<Dictionary<string, object>> 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<IKDCloudHttpClient>();
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<Dictionary<string, object>> GetClassList(int fid, string decname, DataTable table)
{
using var scope = _serviceScopeFactory.CreateScope();
IShareController myScopedService = scope.ServiceProvider.GetRequiredService<IShareController>();
List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
List<SelectClumnConvert> scc = myScopedService.GetAPIList<SelectClumnConvert>().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<string, object> keyValuePairs = new Dictionary<string, object>();
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;
}
/// <inheritdoc/>
public override Task StopAsync(CancellationToken cancellationToken)
{
//t调用 StopAsync时触发cancellationToken改变
DisposeAsync();
return _completedTask;
}
/// <inheritdoc/>
public ValueTask DisposeAsync()
{
foreach (var item in _timer)
{
item.DisposeAsync();
}
return ValueTask.CompletedTask;
}
/// <inheritdoc/>
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;
}
}
}