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