403 lines
19 KiB
C#
403 lines
19 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|