You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookingHeChuan/ServiceProjectSyncWin/Program.cs

421 lines
16 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Furion;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Furion.FriendlyException;
using Furion.JsonSerialization;
using Furion.RemoteRequest.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ServiceProjectSyncWin;
using SqlSugar;
using System.Text;
using System.Text.RegularExpressions;
using static System.Net.Mime.MediaTypeNames;
Serve.RunGeneric(additional: services =>
{
services.AddRemoteRequest();
services.AddSqlsugarSetup(App.Configuration);
}, true, true);
Console.WriteLine("开始准备同步历史服务状态数据");
var service1 = App.GetService<ISyncHisRecord>();
//service1.SyncServiceProjectRecord();
service1.SyncServiceProjectRecord2();
Console.ReadKey();
public interface ISyncHisRecord
{
void SyncServiceProjectRecord();
void SyncServiceProjectRecord2();
//void SyncServiceProjectRecord3();
}
public class SyncHisRecord: ISyncHisRecord,ITransient
{
SqlSugar.ISqlSugarClient _db;
private readonly ILogger<SyncHisRecord> _logger;
public SyncHisRecord(ISqlSugarClient db, ILogger<SyncHisRecord> logger)
{
_db = db;
_logger = logger;
}
public void SyncServiceProjectRecord()
{
int totalSyncNum = 0;
int succSyncNum = 0;
long maxId = 0;
//349708986646597/中集世联达领鲜物流科技(山东)有限公司
long tenantId = 349708986646597;
string batchNo = Guid.NewGuid().ToString();
_logger.LogInformation("批次={no} 触发同步货物状态 tenantId={tenantId}", batchNo, tenantId);
try
{
var tenantInfo = _db.Queryable<SysTenant>().First(a => a.Id == tenantId);
/*
1、按批次读取服务状态数据。去掉没有完成时间的、并且订舱数据是已删除的记录
2、写入历史记录表。
3、单票生成触发报文并推送状态。
4、更新历史记录标记同步状态
*/
maxId = _db.Queryable<ServiceStatusBookingSyncHisInfo>().Max(a => a.ORG_STATUS_ID);
_logger.LogInformation("批次={no} 获取最后同步服务状态的ID={maxId}", batchNo, maxId);
int takeNum = 1000;
while (true)
{
var takeList = _db.Queryable<BookingGoodsStatus>()
.InnerJoin<BookingGoodsStatusConfig>((gs, cfg) => gs.ConfigId == cfg.Id)
.InnerJoin<BookingOrder>((gs, cfg, bk) => gs.bookingId == bk.Id)
.Where((gs, cfg, bk) =>
gs.FinishTime.HasValue && gs.TenantId == tenantId
&& !bk.IsDeleted && gs.FinishUserId != 142307070910551
&& (maxId == 0 || gs.Id > maxId))
.OrderBy((gs, cfg, bk) => gs.Id)
.Select((gs, cfg, bk) => new { GS = gs, CFG = cfg, BK = bk })
.Take(takeNum).ToList();
totalSyncNum += takeList.Count;
Console.WriteLine($"批次={batchNo} 同步待处理任务 totalSyncNum={totalSyncNum}");
_logger.LogInformation("批次={no} 同步待处理任务 totalSyncNum={totalSyncNum}", batchNo, totalSyncNum);
//没有记录跳出循环
if (takeList.Count == 0)
{
Console.WriteLine($"没有记录跳出循环 total={succSyncNum}");
break;
}
maxId = takeList.Max(a => a.GS.Id);
_logger.LogInformation("批次={no} 获取最后同步服务状态的 maxId={maxId}", batchNo, maxId);
//写入记录表
takeList.ForEach(async record =>
{
var entity = new ServiceStatusBookingSyncHisInfo
{
PK_ID = Guid.NewGuid().ToString(),
ORG_STATUS_ID = record.GS.Id,
BOOKING_ID = record.BK.Id,
FINISH_TIME = record.GS.FinishTime.Value,
FINISH_USER_ID = record.GS.FinishUserId.Value,
FINISH_USER_NAME = record.GS.FinishUser,
MBL_NO = record.BK.MBLNO,
SORT_NO = record.CFG.Sort,
STATUS_SKU_CODE = record.CFG.SystemCode,
STATUS_SKU_NAME = record.CFG.StatusName,
STATUS_REMARK = record.GS.Remark,
STATUS_VAL = record.GS.ExtData,
TENANT_ID = record.GS.TenantId.Value,
TENANT_NAME = tenantInfo.Name,
VESSEL = record.BK.VESSEL,
VOYNO = record.BK.VOYNO,
};
_db.Insertable<ServiceStatusBookingSyncHisInfo>(entity).ExecuteCommand();
//await _serviceStatusBookingSyncHisInfoRepository.InsertAsync(entity);
succSyncNum++;
Console.WriteLine($"ORG_STATUS_ID={record.GS.Id} 写入成功 total={succSyncNum}");
Thread.Sleep(300);
});
Console.WriteLine($"等待500毫秒");
Thread.Sleep(500);
}
//停用的状态(接受委托、放箱指令、已发账单、账单确认、账单已回传)
string[] deletedStatusCodeArg = new string[] { "JSWTUO", "FXZLING", "YFZD", "ZDQR", "ZDYHC" };
/*
单票触发推送状态
1、取状态是null的并且每次取前100个订舱记录。
2、按订舱记录取所有的状态记录。
3、生成触发脚本推送PUSH状态。部分状态自动不执行
4、执行成功后更新对应的状态。
*/
Console.WriteLine($"开始推送记录 succ={succSyncNum}");
while (true)
{
var bookingList = _db.Queryable<ServiceStatusBookingSyncHisInfo>()
.Where(a => a.TENANT_ID == tenantId && a.STATUS == null)
.Take(100).Select(a => a.BOOKING_ID).Distinct().ToList();
//无数据跳出
if (bookingList.Count == 0)
{
Console.WriteLine($"没有待推送记录跳出循环 succ={succSyncNum}");
break;
}
var taskList = _db.Queryable<ServiceStatusBookingSyncHisInfo>()
.Where(a => a.TENANT_ID == tenantId && bookingList.Contains(a.BOOKING_ID)).ToList();
taskList.GroupBy(a => a.BOOKING_ID).ToList().ForEach(a =>
{
DateTime currDate = DateTime.Now;
var currStatusList = a.ToList();
var groupCheckList = currStatusList
.Where(b => !deletedStatusCodeArg.Contains(b.STATUS_SKU_CODE))
.GroupBy(b => b.STATUS_SKU_CODE).Select(b =>
{
var currList = b.ToList();
if (currList.Count == 1)
return currList.FirstOrDefault();
return currList.OrderByDescending(c => c.ORG_STATUS_ID).FirstOrDefault();
}).ToList();
if (groupCheckList.Count > 0)
{
var firstInfo = groupCheckList.FirstOrDefault();
TrackingMessageInfo msgInfo = new TrackingMessageInfo
{
Head = new TrackingMessageHeadInfo
{
GID = IDGen.NextID().ToString(),
MessageType = "PROJECT",
ReceiverId = "ServiceProjectStatus",
ReceiverName = "服务项目和状态",
SenderId = "BookingOrder",
SenderName = "海运订舱",
RequestDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
Version = "2.0",
RequestAction = "AddOrModify",
},
Main = new TrackingMessageMainInfo
{
BusiId = firstInfo.BOOKING_ID.ToString(),
BusiSystemCode = "BOOKING_ORDER",
MBlNo = firstInfo.MBL_NO,
VesselVoyno = $"{firstInfo.VESSEL}/{firstInfo.VOYNO}",
OrderNo = "",
PushType = TrackingPushTypeEnum.Status,
OperTenantId = firstInfo.TENANT_ID,
OperTenantName = firstInfo.TENANT_NAME,
OpertType = TrackingOperTypeEnum.AUTO,
OperUserId = firstInfo.FINISH_USER_ID.ToString(),
OperUserName = firstInfo.FINISH_USER_NAME,
SourceType = TrackingSourceTypeEnum.AUTO,
StatusList = groupCheckList.Select(a => new TrackingMessageMainStatusInfo
{
StatusCode = a.STATUS_SKU_CODE,
StatusDate = a.FINISH_TIME,
StatusVal = a.STATUS_VAL,
Remark = a.STATUS_REMARK
}).ToList()
}
};
Console.WriteLine($"准备PUSH状态 msg={JSON.Serialize(msgInfo.Main)}");
//推送状态
var pushRlt = PushStatus(msgInfo).GetAwaiter().GetResult();
Console.WriteLine($"PUSH返回结果 rlt={JSON.Serialize(pushRlt)}");
groupCheckList.ForEach(async t => {
t.STATUS = pushRlt.succ ? "SUCC" : "FAILURE";
t.SYNC_TIME = currDate;
t.SYNC_RESULT = pushRlt.msg;
if (deletedStatusCodeArg.Contains(t.STATUS_SKU_CODE))
{
t.STATUS = "FAILURE";
t.SYNC_RESULT = "状态已取消不再同步";
}
await _db.Updateable<ServiceStatusBookingSyncHisInfo>(t)
.UpdateColumns(it => new
{
it.STATUS,
it.SYNC_TIME,
it.SYNC_RESULT
}).ExecuteCommandAsync();
});
var undoList = currStatusList.GroupJoin(groupCheckList, l => l.ORG_STATUS_ID,
r => r.ORG_STATUS_ID, (l, r) =>
{
var currList = r.ToList();
if (currList.Count == 0)
return new { IsUpdate = true, Obj = l };
return new { IsUpdate = false, Obj = l };
}).Where(c => c.IsUpdate)
.Select(c => c.Obj).ToList();
if (undoList.Count > 0)
{
undoList.ForEach(async t => {
t.STATUS = "FAILURE";
t.SYNC_RESULT = "状态已取最后触发记录";
t.SYNC_TIME = currDate;
if (deletedStatusCodeArg.Contains(t.STATUS_SKU_CODE))
{
t.SYNC_RESULT = "状态已取消不再同步";
}
await _db.Updateable<ServiceStatusBookingSyncHisInfo>(t)
.UpdateColumns(it => new
{
it.STATUS,
it.SYNC_TIME,
it.SYNC_RESULT
}).ExecuteCommandAsync();
});
}
Console.WriteLine($"更新表结束");
}
else
{
Console.WriteLine($"没有可用记录");
}
Thread.Sleep(300);
});
Thread.Sleep(500);
}
}
catch(Exception ex)
{
_logger.LogInformation("批次={no} 同步异常ex={ex}", batchNo, maxId);
}
}
public async Task<TaskManageOrderResultDto> PushStatus(TrackingMessageInfo info)
{
TaskManageOrderResultDto model = null;
/*
1、读取配置文件中的规则引擎URL
2、填充请求的类并生成JSON报文
3、POST请求接口并记录回执。
4、返回信息。
*/
var url = App.Configuration["ServiceStatusPushUrl"];
try
{
var res = await url.SetHttpMethod(HttpMethod.Post)
.SetBody(JSON.Serialize(info), "application/json")
.SetContentEncoding(Encoding.UTF8)
.PostAsync();
_logger.LogInformation("批次={no} 对应请求报文完成 res={res}", info.Head.GID, JSON.Serialize(res));
if (res.StatusCode == System.Net.HttpStatusCode.OK)
{
var userResult = await res.Content.ReadAsStringAsync();
var cmRlt = JSON.Deserialize<CommonRlt>(userResult);
if(cmRlt.success)
model = JSON.Deserialize<TaskManageOrderResultDto>(JSON.Serialize(cmRlt.data));
}
}
catch (Exception ex)
{
//写日志
if (ex is HttpRequestException)
throw Oops.Oh(10000002);
}
return model;
}
public void SyncServiceProjectRecord2()
{
/*
string fmt = "(16)PortofDischarge(17)PlaceofDelivery";
var fmtList = fmt.Select(a => a).ToList();
string name = "(1P6)E PNorAt oNf GDi,scMhaArgLeA YSIA P(1E7)N PAlaNceG o,f DMeAlivLerAy YSIA";
List<char> array = new List<char>();
List<char> array2 = new List<char>();
for (var i=0;i< name.Length;i++)
{
bool isExists = false;
if(fmtList.Count > 0)
{
if (name[i] == fmtList.First())
{
array.Add(name[i]);
fmtList.Remove(fmtList[0]);
isExists = true;
}
}
if (!isExists)
array2.Add(name[i]);
}
string s1 = string.Join("", array);
string s2 = string.Join("", array2);
*/
string Consignee = "LOT 13/3,KAWASAN PERINDUSTRIAN, K AMPUNG KOLAM PADANG BESAR,02100 P ADANG BESAR,PERLIS. T EL;04-949 0507 FAX 94-949 2888";
string NotifyParty = "SHUN EE TRADING SDN BHD (1183208 U) LOT 13/3,KAWASAN PERINDUSTRIAN, K AMPUNG KOLAM PADANG BESAR,02100 P ADANG BESAR,PERLIS. T EL;04-949 0507 FAX 94-949 2888";
if (Regex.IsMatch(Consignee, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b"))
{
Consignee = Regex.Replace(Consignee, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b", m => Regex.Replace(m.Value, "\\s+", ""));
}
if (Regex.IsMatch(NotifyParty, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b"))
{
NotifyParty = Regex.Replace(NotifyParty, "\\b[a-zA-Z]{1}\\b\\s+\\b[a-zA-Z]+\\b", m => Regex.Replace(m.Value, "\\s+", ""));
}
decimal similarity = 100;
for (int i = 0; i < NotifyParty.Length; i++)
{
}
}
}