|
|
using Furion;
|
|
|
using Furion.DatabaseAccessor;
|
|
|
using Furion.DependencyInjection;
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using HtmlAgilityPack;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using MimeKit;
|
|
|
using ServiceProjectSyncWin;
|
|
|
using ServiceProjectSyncWin.Entities;
|
|
|
using SqlSugar;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.Specialized;
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
using System.Net.Http.Headers;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Web;
|
|
|
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.SyncServiceProjectRecord5();
|
|
|
service1.SyncServiceProjectRecord6();
|
|
|
Console.ReadKey();
|
|
|
|
|
|
public interface ISyncHisRecord
|
|
|
{
|
|
|
void SyncServiceProjectRecord4();
|
|
|
|
|
|
void SyncServiceProjectRecord5();
|
|
|
|
|
|
void SyncServiceProjectRecord6();
|
|
|
//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++)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
public void SyncServiceProjectRecord4()
|
|
|
{
|
|
|
|
|
|
/*
|
|
|
批量更新SI 截止时间
|
|
|
1、更新任务台
|
|
|
2、更新舱位的截止时间记录
|
|
|
*/
|
|
|
var taskList = _db.Queryable<TaskBCEntity>().Where(a => (a.BUSI_TYPE == "BookingConfirmation" || a.BUSI_TYPE == "BookingAmendment"))
|
|
|
.OrderBy(t=>t.CreatedTime)
|
|
|
.ToList();
|
|
|
|
|
|
string batchNo = Guid.NewGuid().ToString();
|
|
|
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 num={taskList.Count}");
|
|
|
|
|
|
string bcReadUrl = "http://47.104.73.97:7115/api/TaskBCParser/ExcuteBCFileRead";
|
|
|
string amendReadUrl = "http://47.104.73.97:7115/api/TaskBookingAmendmentParser/ExcuteBookingAmendmentRead";
|
|
|
|
|
|
//foreach (var task in taskList)
|
|
|
for(int i=0;i<taskList.Count;i++)
|
|
|
{
|
|
|
var task = taskList[i];
|
|
|
//BookingConfirmation、BookingAmendment
|
|
|
|
|
|
if (task.BUSI_TYPE == "BookingConfirmation")
|
|
|
{
|
|
|
_logger.LogInformation($"批次={batchNo} 处理任务 No={i} MBLNO={task.MBL_NO} 开始");
|
|
|
|
|
|
var fileInfo = _db.Queryable<TaskFileEntities>().Where(a => a.TASK_PKID == task.TASK_ID && a.FILE_CATEGORY == "BC").First();
|
|
|
|
|
|
if (fileInfo != null)
|
|
|
{
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 取到文件");
|
|
|
|
|
|
string bcFileFullPath = $"D:\\djy\\backend\\wwwroot\\{fileInfo.FILE_PATH}";
|
|
|
|
|
|
var bcFileName = Path.GetFileName(bcFileFullPath);
|
|
|
|
|
|
if(!File.Exists(bcFileFullPath))
|
|
|
{
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 取到文件不存在 path={bcFileFullPath}");
|
|
|
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
TaskBCInfoReadDto BCReadInfo = GetBCReaderInfo(bcFileFullPath, bcFileName, task.TenantId.Value, task.TASK_ID, bcReadUrl).GetAwaiter().GetResult();
|
|
|
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 识别完文件 BCReadInfo={JSON.Serialize(BCReadInfo)}");
|
|
|
|
|
|
StringBuilder msgBuilder = new StringBuilder();
|
|
|
|
|
|
if (BCReadInfo != null)
|
|
|
{
|
|
|
//SI_CUT_DATE
|
|
|
if (BCReadInfo.SICutDate.HasValue)
|
|
|
{
|
|
|
if (!task.SI_CUT_DATE.HasValue || task.SI_CUT_DATE.Value != BCReadInfo.SICutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar={BCReadInfo.SICutDate.Value}##");
|
|
|
|
|
|
task.SI_CUT_DATE = BCReadInfo.SICutDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar=null");
|
|
|
|
|
|
task.SI_CUT_DATE = null;
|
|
|
}
|
|
|
//VGM_CUTOFF_TIME
|
|
|
if (BCReadInfo.VGMCutoffTime.HasValue)
|
|
|
{
|
|
|
if (!task.VGM_CUTOFF_TIME.HasValue || task.VGM_CUTOFF_TIME.Value != BCReadInfo.VGMCutoffTime.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar={BCReadInfo.VGMCutoffTime.Value}##");
|
|
|
|
|
|
task.VGM_CUTOFF_TIME = BCReadInfo.VGMCutoffTime.Value;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar=null##");
|
|
|
|
|
|
task.VGM_CUTOFF_TIME = null;
|
|
|
}
|
|
|
|
|
|
//MANIFEST_CUT_DATE
|
|
|
if (BCReadInfo.ManifestCutDate.HasValue)
|
|
|
{
|
|
|
if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.ManifestCutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar={BCReadInfo.ManifestCutDate.Value}##");
|
|
|
|
|
|
task.MANIFEST_CUT_DATE = BCReadInfo.ManifestCutDate.Value;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar=null##");
|
|
|
|
|
|
task.MANIFEST_CUT_DATE = null;
|
|
|
}
|
|
|
//CY_CUTOFF_TIME
|
|
|
if (BCReadInfo.CYCutoffTime.HasValue)
|
|
|
{
|
|
|
if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.CYCutoffTime.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar={BCReadInfo.CYCutoffTime.Value}##");
|
|
|
|
|
|
task.CY_CUTOFF_TIME = BCReadInfo.CYCutoffTime.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar=null##");
|
|
|
|
|
|
task.CY_CUTOFF_TIME = null;
|
|
|
}
|
|
|
|
|
|
//MDGF_CUT_DATE
|
|
|
if (BCReadInfo.MDGFCutDate.HasValue)
|
|
|
{
|
|
|
if (!task.MDGF_CUT_DATE.HasValue || task.MDGF_CUT_DATE.Value != BCReadInfo.MDGFCutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar={BCReadInfo.MDGFCutDate.Value}##");
|
|
|
|
|
|
task.MDGF_CUT_DATE = BCReadInfo.MDGFCutDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar=null##");
|
|
|
|
|
|
task.MDGF_CUT_DATE = null;
|
|
|
}
|
|
|
//CLOSING_DATE
|
|
|
if (BCReadInfo.ClosingDate.HasValue)
|
|
|
{
|
|
|
if (!task.CLOSING_DATE.HasValue || task.CLOSING_DATE.Value != BCReadInfo.ClosingDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar={BCReadInfo.ClosingDate.Value}##");
|
|
|
|
|
|
task.CLOSING_DATE = BCReadInfo.ClosingDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar=null##");
|
|
|
|
|
|
task.CLOSING_DATE = null;
|
|
|
}
|
|
|
|
|
|
//CLOSING_DATE
|
|
|
if (BCReadInfo.CustomSICutDate.HasValue)
|
|
|
{
|
|
|
if (!task.CUSTOM_SI_CUT_DATE.HasValue || task.CUSTOM_SI_CUT_DATE.Value != BCReadInfo.CustomSICutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar={BCReadInfo.CustomSICutDate.Value}##");
|
|
|
|
|
|
task.CUSTOM_SI_CUT_DATE = BCReadInfo.CustomSICutDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar=null##");
|
|
|
|
|
|
task.CUSTOM_SI_CUT_DATE = null;
|
|
|
}
|
|
|
|
|
|
_db.Updateable<TaskBCEntity>(task).UpdateColumns(it => new
|
|
|
{
|
|
|
it.SI_CUT_DATE,
|
|
|
it.CUSTOM_SI_CUT_DATE,
|
|
|
it.VGM_CUTOFF_TIME,
|
|
|
it.MANIFEST_CUT_DATE,
|
|
|
it.CY_CUTOFF_TIME,
|
|
|
it.MDGF_CUT_DATE,
|
|
|
it.CLOSING_DATE
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 识别完文件 有变更 结果={msgBuilder.ToString()}");
|
|
|
}
|
|
|
}
|
|
|
else if (task.BUSI_TYPE == "BookingAmendment")
|
|
|
{
|
|
|
var fileInfo = _db.Queryable<TaskFileEntities>().Where(a => a.TASK_PKID == task.TASK_ID && a.FILE_CATEGORY == "BC_MODIFY").First();
|
|
|
|
|
|
if (fileInfo != null)
|
|
|
{
|
|
|
string bcFileFullPath = $"D:\\djy\\backend\\wwwroot\\{fileInfo.FILE_PATH}";
|
|
|
|
|
|
var bcFileName = Path.GetFileName(bcFileFullPath);
|
|
|
|
|
|
if (!File.Exists(bcFileFullPath))
|
|
|
{
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 取到文件不存在 path={bcFileFullPath}");
|
|
|
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
TaskBCInfoReadDto BCReadInfo = GetBCReaderInfo(bcFileFullPath, bcFileName, task.TenantId.Value, task.TASK_ID, amendReadUrl).GetAwaiter().GetResult();
|
|
|
|
|
|
StringBuilder msgBuilder = new StringBuilder();
|
|
|
|
|
|
if (BCReadInfo != null)
|
|
|
{
|
|
|
//SI_CUT_DATE
|
|
|
if (BCReadInfo.SICutDate.HasValue)
|
|
|
{
|
|
|
if (!task.SI_CUT_DATE.HasValue || task.SI_CUT_DATE.Value != BCReadInfo.SICutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar={BCReadInfo.SICutDate.Value}##");
|
|
|
|
|
|
task.SI_CUT_DATE = BCReadInfo.SICutDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"SI_CUT_DATE org={task.SI_CUT_DATE} tar=null");
|
|
|
|
|
|
task.SI_CUT_DATE = null;
|
|
|
}
|
|
|
//VGM_CUTOFF_TIME
|
|
|
if (BCReadInfo.VGMCutoffTime.HasValue)
|
|
|
{
|
|
|
if (!task.VGM_CUTOFF_TIME.HasValue || task.VGM_CUTOFF_TIME.Value != BCReadInfo.VGMCutoffTime.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar={BCReadInfo.VGMCutoffTime.Value}##");
|
|
|
|
|
|
task.VGM_CUTOFF_TIME = BCReadInfo.VGMCutoffTime.Value;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"VGM_CUTOFF_TIME org={task.VGM_CUTOFF_TIME} tar=null##");
|
|
|
|
|
|
task.VGM_CUTOFF_TIME = null;
|
|
|
}
|
|
|
|
|
|
//MANIFEST_CUT_DATE
|
|
|
if (BCReadInfo.ManifestCutDate.HasValue)
|
|
|
{
|
|
|
if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.ManifestCutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar={BCReadInfo.ManifestCutDate.Value}##");
|
|
|
|
|
|
task.MANIFEST_CUT_DATE = BCReadInfo.ManifestCutDate.Value;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"MANIFEST_CUT_DATE org={task.MANIFEST_CUT_DATE} tar=null##");
|
|
|
|
|
|
task.MANIFEST_CUT_DATE = null;
|
|
|
}
|
|
|
//CY_CUTOFF_TIME
|
|
|
if (BCReadInfo.CYCutoffTime.HasValue)
|
|
|
{
|
|
|
if (!task.MANIFEST_CUT_DATE.HasValue || task.MANIFEST_CUT_DATE.Value != BCReadInfo.CYCutoffTime.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar={BCReadInfo.CYCutoffTime.Value}##");
|
|
|
|
|
|
task.CY_CUTOFF_TIME = BCReadInfo.CYCutoffTime.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"CY_CUTOFF_TIME org={task.CY_CUTOFF_TIME} tar=null##");
|
|
|
|
|
|
task.CY_CUTOFF_TIME = null;
|
|
|
}
|
|
|
|
|
|
//MDGF_CUT_DATE
|
|
|
if (BCReadInfo.MDGFCutDate.HasValue)
|
|
|
{
|
|
|
if (!task.MDGF_CUT_DATE.HasValue || task.MDGF_CUT_DATE.Value != BCReadInfo.MDGFCutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar={BCReadInfo.MDGFCutDate.Value}##");
|
|
|
|
|
|
task.MDGF_CUT_DATE = BCReadInfo.MDGFCutDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"MDGF_CUT_DATE org={task.MDGF_CUT_DATE} tar=null##");
|
|
|
|
|
|
task.MDGF_CUT_DATE = null;
|
|
|
}
|
|
|
//CLOSING_DATE
|
|
|
if (BCReadInfo.ClosingDate.HasValue)
|
|
|
{
|
|
|
if (!task.CLOSING_DATE.HasValue || task.CLOSING_DATE.Value != BCReadInfo.ClosingDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar={BCReadInfo.ClosingDate.Value}##");
|
|
|
|
|
|
task.CLOSING_DATE = BCReadInfo.ClosingDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"CLOSING_DATE org={task.CLOSING_DATE} tar=null##");
|
|
|
|
|
|
task.CLOSING_DATE = null;
|
|
|
}
|
|
|
|
|
|
//CLOSING_DATE
|
|
|
if (BCReadInfo.CustomSICutDate.HasValue)
|
|
|
{
|
|
|
if (!task.CUSTOM_SI_CUT_DATE.HasValue || task.CUSTOM_SI_CUT_DATE.Value != BCReadInfo.CustomSICutDate.Value)
|
|
|
{
|
|
|
msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar={BCReadInfo.CustomSICutDate.Value}##");
|
|
|
|
|
|
task.CUSTOM_SI_CUT_DATE = BCReadInfo.CustomSICutDate.Value;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msgBuilder.Append($"CUSTOM_SI_CUT_DATE org={task.CUSTOM_SI_CUT_DATE} tar=null##");
|
|
|
|
|
|
task.CUSTOM_SI_CUT_DATE = null;
|
|
|
}
|
|
|
|
|
|
_db.Updateable<TaskBCEntity>(task).UpdateColumns(it => new
|
|
|
{
|
|
|
it.SI_CUT_DATE,
|
|
|
it.CUSTOM_SI_CUT_DATE,
|
|
|
it.VGM_CUTOFF_TIME,
|
|
|
it.MANIFEST_CUT_DATE,
|
|
|
it.CY_CUTOFF_TIME,
|
|
|
it.MDGF_CUT_DATE,
|
|
|
it.CLOSING_DATE
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"批次={batchNo} 提取待处理任务 MBLNO={task.MBL_NO} 识别完文件 有变更 结果={msgBuilder.ToString()}");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
Thread.Sleep(500);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
public void SyncServiceProjectRecord5()
|
|
|
{
|
|
|
string strBody = File.ReadAllText("C:\\Users\\Administrator\\Desktop\\测试HTML.txt", Encoding.UTF8);
|
|
|
//FileStream f = new FileStream("C:\\Users\\Administrator\\Desktop\\测试HTML.txt", FileMode.Create);
|
|
|
//StreamWriter r = new StreamWriter(f, Encoding.Default);
|
|
|
|
|
|
//r.WriteLine(strBody);
|
|
|
|
|
|
HtmlDocument html = new HtmlDocument();
|
|
|
html.LoadHtml(strBody);
|
|
|
|
|
|
List<TransPlanHasChangeDto> list = new List<TransPlanHasChangeDto>();
|
|
|
|
|
|
var divTopList = html.DocumentNode.SelectSingleNode("//div[@class='data__top']");
|
|
|
|
|
|
if (divTopList == null)
|
|
|
return;
|
|
|
|
|
|
//先获取第一层的div
|
|
|
var rootDivNode = divTopList.ParentNode.ChildNodes.Where(a => a.Name.Equals("div", StringComparison.OrdinalIgnoreCase)
|
|
|
&& a.Attributes.Contains("class") && (a.Attributes["class"].Value.Equals("data__top") || a.Attributes["class"].Value.Equals("data")))
|
|
|
.ToList();
|
|
|
|
|
|
//先遍历第一层子节点
|
|
|
for (int i = 0; i < rootDivNode.Count; i++)
|
|
|
{
|
|
|
//先取top
|
|
|
if (rootDivNode[i].Attributes["class"].Value.Equals("data__top", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
TransPlanHasChangeDto dto = new TransPlanHasChangeDto
|
|
|
{
|
|
|
From = new TransPlanHasChangeDetailDto
|
|
|
{
|
|
|
portList = new List<TransPlanHasChangePortDto>(),
|
|
|
dateList = new List<TransPlanHasChangeDateDto>(),
|
|
|
vesselList = new List<TransPlanHasChangeVesselVoynoDto>()
|
|
|
},
|
|
|
To = new TransPlanHasChangeDetailDto
|
|
|
{
|
|
|
portList = new List<TransPlanHasChangePortDto>(),
|
|
|
dateList = new List<TransPlanHasChangeDateDto>(),
|
|
|
vesselList = new List<TransPlanHasChangeVesselVoynoDto>()
|
|
|
},
|
|
|
Carrier = "MSK",
|
|
|
ContaNoList = new List<string>()
|
|
|
};
|
|
|
|
|
|
if (i == rootDivNode.Count - 1)
|
|
|
{
|
|
|
var innerList = GetChildList(rootDivNode[i]);
|
|
|
|
|
|
if (innerList != null && innerList.Count > 0)
|
|
|
{
|
|
|
list.AddRange(innerList);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
#region 解析TOP
|
|
|
var ctnNode = rootDivNode[i].SelectSingleNode("./table[not(contains(@class,'reason'))]/tbody/tr[1]/th[contains(@class,'last')]");
|
|
|
|
|
|
if (ctnNode != null)
|
|
|
{
|
|
|
string s = ctnNode.SelectSingleNode("./table/tr/th/table/tbody/tr/th/table/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s) && (Regex.IsMatch(s, "集装箱号码") || Regex.IsMatch(s, "Container\\(s\\)")))
|
|
|
{
|
|
|
string ctnStr = Regex.Match(s, "(?<=集装箱号码).*").Value?.Trim();
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(ctnStr))
|
|
|
{
|
|
|
ctnStr = Regex.Match(s, "(?<=Container\\(s\\)).*").Value?.Trim();
|
|
|
}
|
|
|
|
|
|
if (ctnStr.IndexOf(",") >= 0)
|
|
|
{
|
|
|
dto.ContaNoList = ctnStr.Split(new char[] { ',' }).Select(a => a.Trim()).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(ctnStr))
|
|
|
dto.ContaNoList.Add(ctnStr.Trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Dictionary<int, string> labelDict = new Dictionary<int, string>();
|
|
|
Dictionary<int, string> valDict = new Dictionary<int, string>();
|
|
|
Dictionary<int, Tuple<string, string>> reasonDict = new Dictionary<int, Tuple<string, string>>();
|
|
|
|
|
|
string lableXpath = "./table[not(contains(@class,'reason'))]/tbody/tr[1]/th[1]/table/tr[1]/";
|
|
|
|
|
|
var currLabel1 = rootDivNode[i].SelectSingleNode($"{lableXpath}/th[1]/table/tbody/tr[1]/th[1]/table/tr[1]/th[1]").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currLabel1))
|
|
|
{
|
|
|
labelDict.Add(1, currLabel1);
|
|
|
}
|
|
|
|
|
|
var currLabel2Node = rootDivNode[i].SelectSingleNode($"{lableXpath}/th[1]/table/tbody/tr[1]/th[1]/table/tr[2]/th[1]");
|
|
|
|
|
|
if (currLabel2Node != null)
|
|
|
{
|
|
|
var currLabel2 = currLabel2Node.InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currLabel2))
|
|
|
{
|
|
|
labelDict.Add(2, currLabel2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var currValue1 = rootDivNode[i].SelectSingleNode($"{lableXpath}/th[2]/table/tr[1]/th[1]").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currValue1))
|
|
|
{
|
|
|
valDict.Add(1, currValue1);
|
|
|
}
|
|
|
|
|
|
var currValue2Node = rootDivNode[i].SelectSingleNode($"{lableXpath}/th[2]/table/tr[2]/th[1]");
|
|
|
|
|
|
if (currValue2Node != null)
|
|
|
{
|
|
|
var currValue2 = currValue2Node.InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currValue2))
|
|
|
{
|
|
|
valDict.Add(2, currValue2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (KeyValuePair<int, string> kvp in labelDict)
|
|
|
{
|
|
|
if (kvp.Value.Equals("订舱号") || Regex.IsMatch(kvp.Value, "Booking\\s+Number", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.BookingNo = valDict[kvp.Key];
|
|
|
}
|
|
|
else if (kvp.Value.Equals("提单号码") || Regex.IsMatch(kvp.Value, "Bill\\s+of\\s+Lading", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.BillNo = valDict[kvp.Key];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
string reason1 = string.Empty;
|
|
|
string reason2 = string.Empty;
|
|
|
|
|
|
bool isReasonNote = false;
|
|
|
|
|
|
var reasonTables = rootDivNode[i].SelectNodes("./table[contains(@class,'reason')]");
|
|
|
|
|
|
if (reasonTables.Count > 0)
|
|
|
{
|
|
|
for (int k = 0; k < reasonTables.Count; k++)
|
|
|
{
|
|
|
var thFirstNode = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tbody/tr/th[contains(@class,'columns first')]");
|
|
|
|
|
|
if (thFirstNode != null)
|
|
|
{
|
|
|
isReasonNote = true;
|
|
|
}
|
|
|
|
|
|
if (!isReasonNote)
|
|
|
{
|
|
|
string s = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s) && s.IndexOf("此订舱号派生自原单号") >= 0)
|
|
|
{
|
|
|
reasonDict.Add(k + 1, new Tuple<string, string>(s, Regex.Match(s, "(?<=此订舱号派生自原单号\\:)\\?\\w+").Value?.Trim()));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var labelNode = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tbody/tr/th[contains(@class,'columns first')]");
|
|
|
var notesNode = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tbody/tr/th[contains(@class,'columns last')]");
|
|
|
|
|
|
string label = string.Empty;
|
|
|
string notes = string.Empty;
|
|
|
|
|
|
if (labelNode != null)
|
|
|
{
|
|
|
label = labelNode.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
|
|
|
if (notesNode != null)
|
|
|
{
|
|
|
notes = notesNode.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(notes))
|
|
|
{
|
|
|
reasonDict.Add(k + 1, new Tuple<string, string>(label, notes));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (KeyValuePair<int, Tuple<string, string>> kvp in reasonDict)
|
|
|
{
|
|
|
if (Regex.IsMatch(kvp.Value.Item1, "此订舱号派生自原单号", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.OrigBillNo = kvp.Value.Item2;
|
|
|
}
|
|
|
else if (Regex.IsMatch(kvp.Value.Item1, "((变更原因)|(Reason))", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.ChangeReasonNotes = kvp.Value.Item2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region 解析DATA
|
|
|
//如果下一个节点是data表示后面是详情
|
|
|
if (rootDivNode[i + 1].Attributes["class"].Value.Equals("data", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
var title = rootDivNode[i + 1].SelectSingleNode("./table[1]/tbody/tr/th[1]/table/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
var title2 = rootDivNode[i + 1].SelectSingleNode("./table[2]/tbody/tr/th[1]/table/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
var title3 = rootDivNode[i + 1].SelectSingleNode(".//b[1]");
|
|
|
|
|
|
if (title3 != null)
|
|
|
{
|
|
|
dto.PleaseNotes = title3.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
//From
|
|
|
if (Regex.IsMatch(title, "((出运计划)|(From))", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
//port
|
|
|
var portNodes = rootDivNode[i + 1].SelectNodes("./table[1]/tbody/tr/th[2]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (portNodes.Count == 1)
|
|
|
{
|
|
|
string s = portNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (portNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < portNodes.Count; t++)
|
|
|
{
|
|
|
string s = portNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//date
|
|
|
var dateNodes = rootDivNode[i + 1].SelectNodes("./table[1]/tbody/tr/th[3]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (dateNodes.Count == 1)
|
|
|
{
|
|
|
string s = dateNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.From.dateList.Add(currInfo);
|
|
|
}
|
|
|
else if (dateNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < dateNodes.Count; t++)
|
|
|
{
|
|
|
string s = dateNodes[t].InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.From.dateList.Add(currInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//vessel
|
|
|
var vesselNodes = rootDivNode[i + 1].SelectNodes("./table[1]/tbody/tr/th[4]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (vesselNodes.Count == 1)
|
|
|
{
|
|
|
string s = vesselNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (vesselNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < vesselNodes.Count; t++)
|
|
|
{
|
|
|
string s = vesselNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (Regex.IsMatch(title2, "((到达计划)|(To))", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
//to
|
|
|
//port
|
|
|
var portNodes = rootDivNode[i + 1].SelectNodes("./table[2]/tbody/tr/th[2]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (portNodes.Count == 1)
|
|
|
{
|
|
|
string s = portNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (portNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < portNodes.Count; t++)
|
|
|
{
|
|
|
string s = portNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//date
|
|
|
var dateNodes = rootDivNode[i + 1].SelectNodes("./table[2]/tbody/tr/th[3]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (dateNodes.Count == 1)
|
|
|
{
|
|
|
string s = dateNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.To.dateList.Add(currInfo);
|
|
|
}
|
|
|
else if (dateNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < dateNodes.Count; t++)
|
|
|
{
|
|
|
string s = dateNodes[t].InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.To.dateList.Add(currInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//vessel
|
|
|
var vesselNodes = rootDivNode[i + 1].SelectNodes("./table[2]/tbody/tr/th[4]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (vesselNodes.Count == 1)
|
|
|
{
|
|
|
string s = vesselNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (vesselNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < vesselNodes.Count; t++)
|
|
|
{
|
|
|
string s = vesselNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
list.Add(dto);
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void SyncServiceProjectRecord6()
|
|
|
{
|
|
|
string mailFilePath = "C:\\Users\\Administrator\\Desktop\\日志\\For Information - Shipment # 234581255.eml";
|
|
|
//读取邮件,解析邮件正文
|
|
|
MimeMessage mimeMsg = MimeMessage.Load(mailFilePath);
|
|
|
|
|
|
var strBody = mimeMsg.HtmlBody;
|
|
|
HtmlDocument html = new HtmlDocument();
|
|
|
html.LoadHtml(strBody);
|
|
|
|
|
|
//获取第一个font节点的内容
|
|
|
var baseNode = html.DocumentNode.SelectSingleNode("//font");
|
|
|
|
|
|
var s = baseNode.InnerText;
|
|
|
|
|
|
string billNo = string.Empty;
|
|
|
//提取单号
|
|
|
if(Regex.IsMatch(s,"(?<=订舱号)[a-zA-Z0-9]+"))
|
|
|
{
|
|
|
billNo = Regex.Match(s, "(?<=订舱号)[a-zA-Z0-9]+").Value;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
private List<TransPlanHasChangeDto> GetChildList(HtmlNode node)
|
|
|
{
|
|
|
List<TransPlanHasChangeDto> list = new List<TransPlanHasChangeDto>();
|
|
|
|
|
|
string firstBillNo = string.Empty;
|
|
|
string firstBookingNo = string.Empty;
|
|
|
//string firstCtnNo = string.Empty;
|
|
|
|
|
|
bool isDiv = false;
|
|
|
|
|
|
for (int i = 0; i < node.ChildNodes.Count; i++)
|
|
|
{
|
|
|
if (node.ChildNodes[i].Name.Equals("table", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
var currLabel1 = node.ChildNodes[i].SelectSingleNode($"./tbody/tr[1]/th[1]/table/tr[1]/th[1]/table/tbody/tr[1]/th[1]").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
var currValue2Node = node.ChildNodes[i].SelectSingleNode("./tbody/tr[1]/th[1]/table/tr[1]/th[1]/table/tbody/tr[1]/th[2]");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currLabel1))
|
|
|
{
|
|
|
if (currLabel1.Equals("订舱号") || Regex.IsMatch(currLabel1, "Booking\\s+Number", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
if(currValue2Node != null)
|
|
|
{
|
|
|
firstBookingNo = currValue2Node.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
}
|
|
|
else if (currLabel1.Equals("提单号码") || Regex.IsMatch(currLabel1, "Bill\\s+of\\s+Lading", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
if (currValue2Node != null)
|
|
|
{
|
|
|
firstBillNo = currValue2Node.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (node.ChildNodes[i].Name.Equals("div", StringComparison.OrdinalIgnoreCase))
|
|
|
isDiv = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
//先获取第一层的div
|
|
|
var rootDivNode = node.ChildNodes.Where(a => a.Name.Equals("div", StringComparison.OrdinalIgnoreCase)
|
|
|
&& a.Attributes.Contains("class") && (a.Attributes["class"].Value.Equals("data__top") || a.Attributes["class"].Value.Equals("data")))
|
|
|
.ToList();
|
|
|
|
|
|
for (int i = 0; i < rootDivNode.Count; i++)
|
|
|
{
|
|
|
//先取top
|
|
|
if (rootDivNode[i].Attributes["class"].Value.Equals("data__top", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
TransPlanHasChangeDto dto = new TransPlanHasChangeDto
|
|
|
{
|
|
|
From = new TransPlanHasChangeDetailDto
|
|
|
{
|
|
|
portList = new List<TransPlanHasChangePortDto>(),
|
|
|
dateList = new List<TransPlanHasChangeDateDto>(),
|
|
|
vesselList = new List<TransPlanHasChangeVesselVoynoDto>()
|
|
|
},
|
|
|
To = new TransPlanHasChangeDetailDto
|
|
|
{
|
|
|
portList = new List<TransPlanHasChangePortDto>(),
|
|
|
dateList = new List<TransPlanHasChangeDateDto>(),
|
|
|
vesselList = new List<TransPlanHasChangeVesselVoynoDto>()
|
|
|
},
|
|
|
Carrier = "MSK",
|
|
|
ContaNoList = new List<string>()
|
|
|
};
|
|
|
|
|
|
if (i == rootDivNode.Count - 1)
|
|
|
{
|
|
|
var innerList = GetChildList(rootDivNode[i]);
|
|
|
|
|
|
if (innerList != null && innerList.Count > 0)
|
|
|
{
|
|
|
list.AddRange(innerList);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
#region 解析TOP
|
|
|
var ctnNode = rootDivNode[i].SelectSingleNode("./table[not(contains(@class,'reason'))]/tbody/tr[1]/th[contains(@class,'last')]");
|
|
|
|
|
|
if (ctnNode != null)
|
|
|
{
|
|
|
string s = ctnNode.SelectSingleNode("./table/tr/th/table/tbody/tr/th/table/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s) && (Regex.IsMatch(s, "集装箱号码") || Regex.IsMatch(s, "Container\\(s\\)")))
|
|
|
{
|
|
|
string ctnStr = Regex.Match(s, "(?<=集装箱号码).*").Value?.Trim();
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(ctnStr))
|
|
|
{
|
|
|
ctnStr = Regex.Match(s, "(?<=Container\\(s\\)).*").Value?.Trim();
|
|
|
}
|
|
|
|
|
|
if (ctnStr.IndexOf(",") >= 0)
|
|
|
{
|
|
|
dto.ContaNoList = ctnStr.Split(new char[] { ',' }).Select(a => a.Trim()).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(ctnStr))
|
|
|
dto.ContaNoList.Add(ctnStr.Trim());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Dictionary<int, string> labelDict = new Dictionary<int, string>();
|
|
|
Dictionary<int, string> valDict = new Dictionary<int, string>();
|
|
|
Dictionary<int, Tuple<string, string>> reasonDict = new Dictionary<int, Tuple<string, string>>();
|
|
|
|
|
|
string lableXpath = "./table[not(contains(@class,'reason'))]/tbody/tr[1]/th[1]/table/tr[1]/";
|
|
|
|
|
|
var currLabel1 = rootDivNode[i].SelectSingleNode($"{lableXpath}/th[1]/table/tbody/tr[1]/th[1]").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currLabel1))
|
|
|
{
|
|
|
labelDict.Add(1, currLabel1);
|
|
|
}
|
|
|
|
|
|
var currLabel2Node = rootDivNode[i].SelectSingleNode("./table[not(contains(@class,'reason'))]/tbody/tr[1]/th[1]/table/tbody/tr[1]/th[1]/table/tr[2]/th[1]");
|
|
|
|
|
|
if (currLabel2Node != null)
|
|
|
{
|
|
|
var currLabel2 = currLabel2Node.InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currLabel2))
|
|
|
{
|
|
|
labelDict.Add(2, currLabel2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var currValue1 = rootDivNode[i].SelectSingleNode($"{lableXpath}/th[2]/table/tr[1]/th[1]").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currValue1))
|
|
|
{
|
|
|
valDict.Add(1, currValue1);
|
|
|
}
|
|
|
|
|
|
var currValue2Node = rootDivNode[i].SelectSingleNode("./table[not(contains(@class,'reason'))]/tbody/tr[1]/th[1]/table/tbody/tr[1]/th[2]/table/tr[2]/th[1]");
|
|
|
|
|
|
if (currValue2Node != null)
|
|
|
{
|
|
|
var currValue2 = currValue2Node.InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(currValue2))
|
|
|
{
|
|
|
valDict.Add(2, currValue2);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (KeyValuePair<int, string> kvp in labelDict)
|
|
|
{
|
|
|
if (kvp.Value.Equals("订舱号") || Regex.IsMatch(kvp.Value, "Booking\\s+Number", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.BookingNo = valDict[kvp.Key];
|
|
|
}
|
|
|
else if (kvp.Value.Equals("提单号码") || Regex.IsMatch(kvp.Value, "Bill\\s+of\\s+Lading", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
if (Regex.IsMatch(valDict[kvp.Key], "BL\\s+number\\s+not\\s+yet\\s+generated", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.BillNotes = valDict[kvp.Key];
|
|
|
|
|
|
if(i ==0)
|
|
|
{
|
|
|
dto.BillNo = firstBillNo;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dto.BillNo = valDict[kvp.Key];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
string reason1 = string.Empty;
|
|
|
string reason2 = string.Empty;
|
|
|
|
|
|
bool isReasonNote = false;
|
|
|
|
|
|
var reasonTables = rootDivNode[i].SelectNodes("./table[contains(@class,'reason')]");
|
|
|
|
|
|
if (reasonTables.Count > 0)
|
|
|
{
|
|
|
for (int k = 0; k < reasonTables.Count; k++)
|
|
|
{
|
|
|
var thFirstNode = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tbody/tr/th[contains(@class,'columns first')]");
|
|
|
|
|
|
if (thFirstNode != null)
|
|
|
{
|
|
|
isReasonNote = true;
|
|
|
}
|
|
|
|
|
|
if (!isReasonNote)
|
|
|
{
|
|
|
string s = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s) && s.IndexOf("此订舱号派生自原单号") >= 0)
|
|
|
{
|
|
|
reasonDict.Add(k + 1, new Tuple<string, string>(s, Regex.Match(s, "(?<=此订舱号派生自原单号\\:)\\?\\w+").Value?.Trim()));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var labelNode = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tbody/tr/th[contains(@class,'columns first')]");
|
|
|
var notesNode = rootDivNode[i].SelectSingleNode("./table[contains(@class,'reason')][" + (k + 1) + "]/tbody/tr/th[contains(@class,'columns last')]");
|
|
|
|
|
|
string label = string.Empty;
|
|
|
string notes = string.Empty;
|
|
|
|
|
|
if (labelNode != null)
|
|
|
{
|
|
|
label = labelNode.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
|
|
|
if (notesNode != null)
|
|
|
{
|
|
|
notes = notesNode.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(notes))
|
|
|
{
|
|
|
reasonDict.Add(k + 1, new Tuple<string, string>(label, notes));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (KeyValuePair<int, Tuple<string, string>> kvp in reasonDict)
|
|
|
{
|
|
|
if (Regex.IsMatch(kvp.Value.Item1, "此订舱号派生自原单号", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.OrigBillNo = kvp.Value.Item2;
|
|
|
}
|
|
|
else if (Regex.IsMatch(kvp.Value.Item1, "((变更原因)|(Reason))", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
dto.ChangeReasonNotes = kvp.Value.Item2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region 解析DATA
|
|
|
//如果下一个节点是data表示后面是详情
|
|
|
if (rootDivNode[i + 1].Attributes["class"].Value.Equals("data", StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
var title = rootDivNode[i + 1].SelectSingleNode("./table[1]/tbody/tr/th[1]/table/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
var title2 = rootDivNode[i + 1].SelectSingleNode("./table[2]/tbody/tr/th[1]/table/tr/th").InnerText.ReplaceHtmlStr();
|
|
|
|
|
|
var title3 = rootDivNode[i + 1].SelectSingleNode(".//b[1]");
|
|
|
|
|
|
if (title3 != null)
|
|
|
{
|
|
|
dto.PleaseNotes = title3.InnerText.ReplaceHtmlStr();
|
|
|
}
|
|
|
//From
|
|
|
if (Regex.IsMatch(title, "((出运计划)|(From))", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
//port
|
|
|
var portNodes = rootDivNode[i + 1].SelectNodes("./table[1]/tbody/tr/th[2]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (portNodes.Count == 1)
|
|
|
{
|
|
|
string s = portNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (portNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < portNodes.Count; t++)
|
|
|
{
|
|
|
string s = portNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//date
|
|
|
var dateNodes = rootDivNode[i + 1].SelectNodes("./table[1]/tbody/tr/th[3]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (dateNodes.Count == 1)
|
|
|
{
|
|
|
string s = dateNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.From.dateList.Add(currInfo);
|
|
|
}
|
|
|
else if (dateNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < dateNodes.Count; t++)
|
|
|
{
|
|
|
string s = dateNodes[t].InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.From.dateList.Add(currInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//vessel
|
|
|
var vesselNodes = rootDivNode[i + 1].SelectNodes("./table[1]/tbody/tr/th[4]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (vesselNodes.Count == 1)
|
|
|
{
|
|
|
string s = vesselNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (vesselNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < vesselNodes.Count; t++)
|
|
|
{
|
|
|
string s = vesselNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.From.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (Regex.IsMatch(title2, "((到达计划)|(To))", RegexOptions.IgnoreCase))
|
|
|
{
|
|
|
//to
|
|
|
//port
|
|
|
var portNodes = rootDivNode[i + 1].SelectNodes("./table[2]/tbody/tr/th[2]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (portNodes.Count == 1)
|
|
|
{
|
|
|
string s = portNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (portNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < portNodes.Count; t++)
|
|
|
{
|
|
|
string s = portNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.portList.Add(new TransPlanHasChangePortDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
PortName = currArg[0].Trim(),
|
|
|
IsRemoved = portNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
CountryCode = currArg[1].Trim(),
|
|
|
TerminalName = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//date
|
|
|
var dateNodes = rootDivNode[i + 1].SelectNodes("./table[2]/tbody/tr/th[3]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (dateNodes.Count == 1)
|
|
|
{
|
|
|
string s = dateNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.To.dateList.Add(currInfo);
|
|
|
}
|
|
|
else if (dateNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < dateNodes.Count; t++)
|
|
|
{
|
|
|
string s = dateNodes[t].InnerText;
|
|
|
|
|
|
var currInfo = new TransPlanHasChangeDateDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
OrigDateTxt = s,
|
|
|
IsRemoved = dateNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
};
|
|
|
|
|
|
DateTime currDate = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(s))
|
|
|
{
|
|
|
if (DateTime.TryParse(s, out currDate))
|
|
|
currInfo.DateVal = currDate;
|
|
|
}
|
|
|
|
|
|
dto.To.dateList.Add(currInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//vessel
|
|
|
var vesselNodes = rootDivNode[i + 1].SelectNodes("./table[2]/tbody/tr/th[4]/table/tr/th//div[contains(@class,'remove') or contains(@class,'updated') or contains(@class,'no-change')]");
|
|
|
|
|
|
if (vesselNodes.Count == 1)
|
|
|
{
|
|
|
string s = vesselNodes.FirstOrDefault().InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[0].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
else if (vesselNodes.Count > 1)
|
|
|
{
|
|
|
for (int t = 0; t < vesselNodes.Count; t++)
|
|
|
{
|
|
|
string s = vesselNodes[t].InnerText;
|
|
|
|
|
|
var currArg = s.Split(new char[] { ',' });
|
|
|
|
|
|
dto.To.vesselList.Add(new TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
Indx = t + 1,
|
|
|
Vessel = currArg[0].Trim(),
|
|
|
IsRemoved = vesselNodes[t].Attributes["class"].Value.Equals("remove", StringComparison.OrdinalIgnoreCase),
|
|
|
Voyno = currArg[1].Trim(),
|
|
|
Flag = currArg[2].Trim(),
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
list.Add(dto);
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
#region 读BC详情详情
|
|
|
/// <summary>
|
|
|
/// 读BC详情详情
|
|
|
/// </summary>
|
|
|
/// <param name="attachFullName">文件完整路径</param>
|
|
|
/// <param name="fileName">文件名称</param>
|
|
|
/// <param name="tenantId">所属租户</param>
|
|
|
/// <param name="taskPKId">任务ID</param>
|
|
|
/// <param name="url">请求URL</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<TaskBCInfoReadDto> GetBCReaderInfo(string attachFullName, string fileName, long tenantId, string taskPKId, string url)
|
|
|
{
|
|
|
TaskBCInfoReadDto taskBCInfoReadDto = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
EmailBCReadMessageInfo messageInfo = new EmailBCReadMessageInfo
|
|
|
{
|
|
|
Head = new TaskMessageHead
|
|
|
{
|
|
|
GID = IDGen.NextID().ToString(),
|
|
|
MessageType = "BOOKING_AMENDMENT",
|
|
|
SenderId = "DJY",
|
|
|
SenderName = "新大简云",
|
|
|
ReceiverId = "RulesEngine",
|
|
|
ReceiverName = "大简云规则引擎",
|
|
|
Version = "1.0",
|
|
|
RequestDate = nowDate.ToString("yyyy-MM-dd HH:mm:ss"),
|
|
|
RequestAction = "ReadFile",
|
|
|
},
|
|
|
Main = new EmailBCReadMessageMainInfo
|
|
|
{
|
|
|
TenantId = tenantId > 0 ? tenantId.ToString() : ""
|
|
|
}
|
|
|
};
|
|
|
|
|
|
NameValueCollection par = new NameValueCollection();
|
|
|
par.Add("jsonData", JSON.Serialize(messageInfo));
|
|
|
|
|
|
//解析BookingAmendment
|
|
|
var compareRlt = await ExcuteReadFile(par, url, new
|
|
|
{
|
|
|
file = "file",
|
|
|
fileName = fileName,
|
|
|
fileBytes = File.ReadAllBytes(attachFullName)
|
|
|
});
|
|
|
|
|
|
_logger.LogInformation($"读取BC附件详情 taskPKId={taskPKId},compareRlt={JSON.Serialize(compareRlt)}");
|
|
|
|
|
|
if (compareRlt.succ)
|
|
|
{
|
|
|
taskBCInfoReadDto = JSON.Deserialize<TaskBCInfoReadDto>(JSON.Serialize(compareRlt.extra));
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogError($"读取BC附件详情异常,原因:{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return taskBCInfoReadDto;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 请求BookingAmendment解析
|
|
|
/// <summary>
|
|
|
/// 请求BookingAmendment解析
|
|
|
/// </summary>
|
|
|
/// <param name="nameValueCollection">请求参数</param>
|
|
|
/// <param name="url">请求url</param>
|
|
|
/// <param name="fileInfo">文件</param>
|
|
|
/// <param name="contentType">请求类型</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[NonAction]
|
|
|
private async Task<ParserReaderExcuteResultDto> ExcuteReadFile(NameValueCollection nameValueCollection, string url, dynamic fileInfo,
|
|
|
string contentType = "application/json")
|
|
|
{
|
|
|
ParserReaderExcuteResultDto model = null;
|
|
|
var result = string.Empty;
|
|
|
|
|
|
using (var httpClient = new HttpClient())
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
using (var reduceAttach = new MultipartFormDataContent())
|
|
|
{
|
|
|
string[] allKeys = nameValueCollection.AllKeys;
|
|
|
foreach (string key in allKeys)
|
|
|
{
|
|
|
var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(nameValueCollection[key]));
|
|
|
|
|
|
dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue($"form-data")
|
|
|
{
|
|
|
Name = key
|
|
|
};
|
|
|
|
|
|
reduceAttach.Add(dataContent);
|
|
|
}
|
|
|
|
|
|
#region 文件参数
|
|
|
if (fileInfo != null)
|
|
|
{
|
|
|
var Content = new ByteArrayContent(fileInfo.fileBytes);
|
|
|
|
|
|
//Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
|
|
|
//{
|
|
|
// Name = fileInfo.file.ToString(),
|
|
|
// FileName = fileInfo.fileName.ToString(),
|
|
|
|
|
|
//};
|
|
|
|
|
|
Content.Headers.Add("Content-Type", contentType);
|
|
|
|
|
|
reduceAttach.Add(Content, fileInfo.file.ToString(), HttpUtility.UrlEncode(fileInfo.fileName.ToString()));
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
//httpClient.DefaultRequestHeaders.Add("USER_KEY", App.Configuration["ApiUserKey"]);
|
|
|
//httpClient.DefaultRequestHeaders.Add("USER_SECRET", App.Configuration["ApiUserSecret"]);
|
|
|
//请求
|
|
|
var response = httpClient.PostAsync(url, reduceAttach).Result;
|
|
|
result = response.Content.ReadAsStringAsync().Result;
|
|
|
|
|
|
model = JSON.Deserialize<ParserReaderExcuteResultDto>(result);
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation("请求读取BC附件详情读取详情异常,原因:{error}", ex.Message);
|
|
|
|
|
|
throw Oops.Oh($"请求读取BC附件详情读取详情异常,原因:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
public class EmailBCReadMessageInfo
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 表头
|
|
|
/// </summary>
|
|
|
public TaskMessageHead Head { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 表体
|
|
|
/// </summary>
|
|
|
public EmailBCReadMessageMainInfo Main { get; set; }
|
|
|
}
|
|
|
|
|
|
public class EmailBCReadMessageMainInfo
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 所属租户ID
|
|
|
/// </summary>
|
|
|
public string TenantId { get; set; }
|
|
|
}
|
|
|
|
|
|
public class TaskMessageHead : WebAPIHeadBase
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
public class WebAPIHeadBase
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 报文惟一主键
|
|
|
/// </summary>
|
|
|
/// <example>08dab66c-96a1-4f90-8606-2626e06202ad</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string GID { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 报文类型 BUSI_RULE-业务规则校验
|
|
|
/// </summary>
|
|
|
/// <example>BUSI_RULE</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string MessageType { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发送方代码
|
|
|
/// </summary>
|
|
|
/// <example>CUSTOMER1</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string SenderId { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发送方名称
|
|
|
/// </summary>
|
|
|
/// <example>企业A</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string SenderName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 接收方代码
|
|
|
/// </summary>
|
|
|
/// <example>RulesEngine</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string ReceiverId { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 接收方名称
|
|
|
/// </summary>
|
|
|
/// <example>大简云规则引擎</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string ReceiverName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 请求方登录TOKEN(可以是真实的登录人TOKEN或者是服务模拟登录人TOKEN)
|
|
|
/// </summary>
|
|
|
/// <example>eyJhbGciOiJSUzI1NiIsImtpZCI6IkQ1RTkxMDI5OUU0RURFNUZEM0EwNTJBMEFDRDUzMUQzIiwidHlwIjoiYXQrand0In0</example>
|
|
|
public string Token { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 版本号 默认1.0
|
|
|
/// </summary>
|
|
|
/// <example>1.0</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string Version { get; set; } = "1.0";
|
|
|
|
|
|
/// <summary>
|
|
|
/// 请求时间
|
|
|
/// </summary>
|
|
|
/// <example>2022-10-10 10:00:00</example>
|
|
|
public string RequestDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 请求操作类型
|
|
|
/// </summary>
|
|
|
/// <example>Add</example>
|
|
|
[Required(ErrorMessage = "必填")]
|
|
|
public string RequestAction { get; set; } = "Add";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public class ParserReaderExcuteResultDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 是否成功 true=成功 false=失败
|
|
|
/// </summary>
|
|
|
public bool succ { get; set; } = false;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 状态 0-成功
|
|
|
/// </summary>
|
|
|
public int status { get; set; } = 0;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 返回消息
|
|
|
/// </summary>
|
|
|
public string msg { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 总记录数
|
|
|
/// </summary>
|
|
|
public int total { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 当前页列表数据
|
|
|
/// </summary>
|
|
|
public object rows { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 合计信息
|
|
|
/// </summary>
|
|
|
public object summary { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 扩展信息
|
|
|
/// </summary>
|
|
|
public object extra { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 扩展信息2
|
|
|
/// </summary>
|
|
|
public object extra2 { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 扩展信息场站统计
|
|
|
/// </summary>
|
|
|
public object yardStatInfo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否异常
|
|
|
/// </summary>
|
|
|
public bool exceptionflag { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 生成HTML
|
|
|
/// </summary>
|
|
|
public string ResultHtml { get; set; }
|
|
|
}
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
public class TaskBCInfoReadDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 订舱单位
|
|
|
/// </summary>
|
|
|
public string BookingParty { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发货人
|
|
|
/// </summary>
|
|
|
public string Shipper { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 收货人
|
|
|
/// </summary>
|
|
|
public string Consignee { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通知人
|
|
|
/// </summary>
|
|
|
public string NotifyParty { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// BC更新次数
|
|
|
/// </summary>
|
|
|
public Nullable<int> BCModifyTimes { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// BC更新时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> BCModifyDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 主单号
|
|
|
/// </summary>
|
|
|
public string MBLNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船名
|
|
|
/// </summary>
|
|
|
public string Vessel { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 航次
|
|
|
/// </summary>
|
|
|
public string VoyNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船公司
|
|
|
/// </summary>
|
|
|
public string Carrier { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 收货地
|
|
|
/// </summary>
|
|
|
public string PlaceReceipt { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 装货港
|
|
|
/// </summary>
|
|
|
public string Portload { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 截关时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> ClosingDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 截VGM时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> VGMCutoffTime { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// ETA(预计到港时间)
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> ETA { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// ETD(预计离港时间)
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> ETD { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 目的港ETA
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> PODETA { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 截单时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> CutSingleTime { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 卸货港
|
|
|
/// </summary>
|
|
|
public string PortDischarge { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 交货地
|
|
|
/// </summary>
|
|
|
public string PlaceDelivery { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 装运方式
|
|
|
/// </summary>
|
|
|
public string ShippingMethod { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 运输条款
|
|
|
/// </summary>
|
|
|
public string Service { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 港前运输形态
|
|
|
/// </summary>
|
|
|
public string PreTransMode { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 品名
|
|
|
/// </summary>
|
|
|
public string Description { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 签单地点
|
|
|
/// </summary>
|
|
|
public string IssuePlace { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 集港码头
|
|
|
/// </summary>
|
|
|
public string CollectionTerminal { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 约号
|
|
|
/// </summary>
|
|
|
public string ContractNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 预付地点
|
|
|
/// </summary>
|
|
|
public string PrepardAT { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船代
|
|
|
/// </summary>
|
|
|
public string ShipAgent { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 场站
|
|
|
/// </summary>
|
|
|
public string Yard { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 场站联系人
|
|
|
/// </summary>
|
|
|
public string YardContactUserName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 场站联系电话
|
|
|
/// </summary>
|
|
|
public string YardContactTel { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 一代客服姓名
|
|
|
/// </summary>
|
|
|
public string FstCustomerSerUserName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 一代客服电话
|
|
|
/// </summary>
|
|
|
public string FstCustomerSerUserTel { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 一代客服邮箱
|
|
|
/// </summary>
|
|
|
public string FstCustomerSerUserEmail { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 备注1
|
|
|
/// </summary>
|
|
|
public string Remark1 { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 截港时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> CYCutoffTime { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 状态 TEMP-暂存 SUCC-已对应 ERROR-异常
|
|
|
/// </summary>
|
|
|
public string Status { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 文件MD5
|
|
|
/// </summary>
|
|
|
public string FileMD5 { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 最后对应时间,最后关联到订舱日期
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> LastToBookingDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 来源邮箱
|
|
|
/// </summary>
|
|
|
public string FromEmail { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 接收邮箱
|
|
|
/// </summary>
|
|
|
public string RecvEmail { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 订舱ID,对应成功后,订舱ID写入
|
|
|
/// </summary>
|
|
|
public Nullable<long> BookingOrderId { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 集装箱列表
|
|
|
/// </summary>
|
|
|
public List<TaskBCInfoReadCtnDto> CtnList { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 顺序号
|
|
|
/// </summary>
|
|
|
public int Indx { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 对应订舱序号
|
|
|
/// </summary>
|
|
|
public int BKOrderIndx { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 舱位主键
|
|
|
/// </summary>
|
|
|
public Nullable<long> BookingSlotId { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船公司代号
|
|
|
/// </summary>
|
|
|
public string CarrierId { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 航线代码(船公司)
|
|
|
/// </summary>
|
|
|
public string LaneCode { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 航线名称(船公司)
|
|
|
/// </summary>
|
|
|
public string LaneName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 承运方式 DIRECT_SHIP-直达;TRANSFER_SHIP-中转
|
|
|
/// </summary>
|
|
|
public string CarriageType { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 承运方式名称 DIRECT_SHIP-直达;TRANSFER_SHIP-中转
|
|
|
/// </summary>
|
|
|
public string CarriageTypeName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 订舱方式 CONTRACT_ORDER-合约订舱;SPOT_ORDER-SPOT订舱
|
|
|
/// </summary>
|
|
|
public string BookingSlotType { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 订舱方式名称 CONTRACT_ORDER-合约订舱;SPOT_ORDER-SPOT订舱
|
|
|
/// </summary>
|
|
|
public string BookingSlotTypeName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 箱型箱量
|
|
|
/// </summary>
|
|
|
public string CtnStat { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 所在周数
|
|
|
/// </summary>
|
|
|
public string WeekAt { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 箱使天数
|
|
|
/// </summary>
|
|
|
public int DetensionFreeDays { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 样单截止日期
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> SICutDate { get; set; }
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 舱单截止时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> ManifestCutDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// MDGF提交截止时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> MDGFCutDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 中转港1
|
|
|
/// </summary>
|
|
|
public string TransferPort1 { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 中转港2
|
|
|
/// </summary>
|
|
|
public string TransferPort2 { get; set; }
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 二程船名
|
|
|
/// </summary>
|
|
|
public string SecondVessel { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 二程航次
|
|
|
/// </summary>
|
|
|
public string SecondVoyno { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 二程ETD
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> SecondETD { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 二程ETA
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> SecondETA { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 订舱确认时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> BookingConfirmDate { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 客户样单截止日期
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> CustomSICutDate { get; set; }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 任务BC集装箱
|
|
|
/// </summary>
|
|
|
public class TaskBCInfoReadCtnDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 箱型代码
|
|
|
/// </summary>
|
|
|
public string CtnCode { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 箱型
|
|
|
/// </summary>
|
|
|
public string CtnALL { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 箱量
|
|
|
/// </summary>
|
|
|
public Nullable<int> CTNNUM { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 件数
|
|
|
/// </summary>
|
|
|
public Nullable<int> PKGS { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 尺码
|
|
|
/// </summary>
|
|
|
public Nullable<decimal> CBM { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 毛重
|
|
|
/// </summary>
|
|
|
public Nullable<decimal> KGS { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 皮重
|
|
|
/// </summary>
|
|
|
public Nullable<decimal> TareWeight { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 危品票标示
|
|
|
/// </summary>
|
|
|
public string IODGT { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 特殊装载需求
|
|
|
/// </summary>
|
|
|
public string SpecialLoadingRequire { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提箱场站
|
|
|
/// </summary>
|
|
|
public string TakeCTNYard { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提箱时间
|
|
|
/// </summary>
|
|
|
public Nullable<DateTime> TakeCTNTime { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 还箱场站
|
|
|
/// </summary>
|
|
|
public string ReturnCTNYard { get; set; }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// MSK 您的货物运输计划已变更
|
|
|
/// </summary>
|
|
|
public class TransPlanHasChangeDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 订舱编号
|
|
|
/// </summary>
|
|
|
public string BookingNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船公司代码
|
|
|
/// </summary>
|
|
|
public string Carrier { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提单号码
|
|
|
/// </summary>
|
|
|
public string BillNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 派生自原单号
|
|
|
/// </summary>
|
|
|
public string OrigBillNo { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 集装箱号列表
|
|
|
/// </summary>
|
|
|
public List<string> ContaNoList { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 变更原因
|
|
|
/// </summary>
|
|
|
public string ChangeReasonNotes { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 出运计划
|
|
|
/// </summary>
|
|
|
public TransPlanHasChangeDetailDto From { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 到达计划
|
|
|
/// </summary>
|
|
|
public TransPlanHasChangeDetailDto To { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 特别提示
|
|
|
/// </summary>
|
|
|
public string PleaseNotes { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提单号特殊提示
|
|
|
/// </summary>
|
|
|
public string BillNotes { get; set; }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 您的货物运输计划已变更明细
|
|
|
/// </summary>
|
|
|
public class TransPlanHasChangeDetailDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 港口变更明细
|
|
|
/// </summary>
|
|
|
public List<TransPlanHasChangePortDto> portList { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 日期变更明细(ETD或者ATD)
|
|
|
/// </summary>
|
|
|
public List<TransPlanHasChangeDateDto> dateList { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船名航次变更
|
|
|
/// </summary>
|
|
|
public List<TransPlanHasChangeVesselVoynoDto> vesselList { get; set; }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 您的货物运输计划已变更-港口
|
|
|
/// </summary>
|
|
|
public class TransPlanHasChangePortDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 顺序号
|
|
|
/// </summary>
|
|
|
public int Indx { get; set; }
|
|
|
/// <summary>
|
|
|
/// 港口名
|
|
|
/// </summary>
|
|
|
public string PortName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 国家
|
|
|
/// </summary>
|
|
|
public string CountryCode { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 码头
|
|
|
/// </summary>
|
|
|
public string TerminalName { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否被作废掉了
|
|
|
/// </summary>
|
|
|
public bool IsRemoved { get; set; } = false;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 您的货物运输计划已变更-日期
|
|
|
/// </summary>
|
|
|
public class TransPlanHasChangeDateDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 顺序号
|
|
|
/// </summary>
|
|
|
public int Indx { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 提取日期文本
|
|
|
/// </summary>
|
|
|
public string OrigDateTxt { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 日期
|
|
|
/// </summary>
|
|
|
public DateTime DateVal { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否被作废掉了
|
|
|
/// </summary>
|
|
|
public bool IsRemoved { get; set; } = false;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 您的货物运输计划已变更-船名航次
|
|
|
/// </summary>
|
|
|
public class TransPlanHasChangeVesselVoynoDto
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 顺序号
|
|
|
/// </summary>
|
|
|
public int Indx { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船名
|
|
|
/// </summary>
|
|
|
public string Vessel { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 航次
|
|
|
/// </summary>
|
|
|
public string Voyno { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 船旗
|
|
|
/// </summary>
|
|
|
public string Flag { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 是否被作废掉了
|
|
|
/// </summary>
|
|
|
public bool IsRemoved { get; set; } = false;
|
|
|
}
|
|
|
|
|
|
public static class StringUtilsExtension
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 格式化文件名,去掉非法字符
|
|
|
/// </summary>
|
|
|
/// <param name="inputVal">请求参数</param>
|
|
|
/// <returns>返回格式化表达式值</returns>
|
|
|
public static string FormatFileName(this string inputVal)
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(inputVal))
|
|
|
return Regex.Replace(inputVal, "\\|\\/|\\:|\\*|\\?|\\\"|\\<|\\>|\\|", "_");
|
|
|
|
|
|
return inputVal;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 清理HTML字符
|
|
|
/// </summary>
|
|
|
/// <param name="inputVal">请求参数</param>
|
|
|
/// <returns>返回格式化表达式值</returns>
|
|
|
public static string ReplaceHtmlStr(this string inputVal)
|
|
|
{
|
|
|
if (!string.IsNullOrWhiteSpace(inputVal))
|
|
|
return Regex.Replace(Regex.Replace(inputVal, "\\ \\;", " "), "\\s{2,}", " ")?.Trim();
|
|
|
|
|
|
return inputVal;
|
|
|
}
|
|
|
} |