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 + + )
{
}
}
}