@ -1,8 +1,16 @@
using Furion ;
using Furion ;
using Furion.DatabaseAccessor ;
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.DependencyInjection ;
using Microsoft.Extensions.Logging ;
using ServiceProjectSyncWin ;
using ServiceProjectSyncWin ;
using SqlSugar ;
using SqlSugar ;
using System.Text ;
using static System . Net . Mime . MediaTypeNames ;
Serve . RunGeneric ( additional : services = >
Serve . RunGeneric ( additional : services = >
{
{
@ -13,91 +21,333 @@ Serve.RunGeneric(additional: services =>
} , true , true ) ;
} , true , true ) ;
Console . WriteLine ( "开始准备同步历史服务状态数据" ) ;
Console . WriteLine ( "开始准备同步历史服务状态数据" ) ;
var service1 = App . GetService < ISyncHisRecord > ( ) ;
service1 . SyncServiceProjectRecord ( ) ;
Console . ReadKey ( ) ;
Console . ReadKey ( ) ;
public interface ISyncHisRecord
{
void SyncServiceProjectRecord ( ) ;
}
public class SyncHisRecord
public class SyncHisRecord : ISyncHisRecord , ITransient
{
{
SqlSugar . ISqlSugarClient _db ;
SqlSugar . ISqlSugarClient _db ;
private readonly ILogger < SyncHisRecord > _logger ;
public SyncHisRecord ( ISqlSugarClient db )
public SyncHisRecord ( ISqlSugarClient db , ILogger < SyncHisRecord > logger )
{
{
_db = db ;
_db = db ;
_logger = logger ;
}
}
public void SyncServiceProjectRecord ( )
public void SyncServiceProjectRecord ( )
{
{
/ *
int totalSyncNum = 0 ;
//_db.Queryable<Order>()
int succSyncNum = 0 ;
var tenantInfo = _sysTenantRepository . AsQueryable ( ) . Filter ( null , true ) . First ( a = > a . Id = = tenantId ) ;
/ *
long maxId = 0 ;
1 、 按 批 次 读 取 服 务 状 态 数 据 。 ( 去 掉 没 有 完 成 时 间 的 、 并 且 订 舱 数 据 是 已 删 除 的 记 录 )
2 、 写 入 历 史 记 录 表 。
3 、 单 票 生 成 触 发 报 文 , 并 推 送 状 态 。
4 、 更 新 历 史 记 录 , 标 记 同 步 状 态
maxId = _serviceStatusBookingSyncHisInfoRepository . AsQueryable ( ) . Max ( a = > a . ORG_STATUS_ID ) ;
//349708986646597/中集世联达领鲜物流科技(山东)有限公司
long tenantId = 349708986646597 ;
_logger . LogInformation ( "批次={no} 获取最后同步服务状态的ID={maxId}" , batchNo , maxId ) ;
string batchNo = Guid . NewGuid ( ) . ToString ( ) ;
int takeNum = 1000 ;
_logger . LogInformation ( "批次={no} 触发同步货物状态 tenantId={tenantId}" , batchNo , tenantId ) ;
while ( true )
try
{
{
var takeList = _bookingGoodsStatusRepository . AsQueryable ( ) . Filter ( null , true )
var tenantInfo = _db . Queryable < SysTenant > ( ) . First ( a = > a . Id = = tenantId ) ;
. InnerJoin < BookingGoodsStatusConfig > ( ( gs , cfg ) = > gs . ConfigId = = cfg . Id )
/ *
. InnerJoin < BookingOrder > ( ( gs , cfg , bk ) = > gs . bookingId = = bk . Id )
1 、 按 批 次 读 取 服 务 状 态 数 据 。 ( 去 掉 没 有 完 成 时 间 的 、 并 且 订 舱 数 据 是 已 删 除 的 记 录 )
. Where ( ( gs , cfg , bk ) = >
2 、 写 入 历 史 记 录 表 。
gs . FinishTime . HasValue & & gs . TenantId = = tenantId
3 、 单 票 生 成 触 发 报 文 , 并 推 送 状 态 。
& & ! bk . IsDeleted & & gs . FinishUserId ! = 142307070910551
4 、 更 新 历 史 记 录 , 标 记 同 步 状 态
& & ( maxId = = 0 | | gs . Id > maxId ) )
* /
. OrderBy ( ( gs , cfg , bk ) = > gs . Id )
maxId = _db . Queryable < ServiceStatusBookingSyncHisInfo > ( ) . Max ( a = > a . ORG_STATUS_ID ) ;
. Select ( ( gs , cfg , bk ) = > new { GS = gs , CFG = cfg , BK = bk } )
. Take ( takeNum ) . ToList ( ) ;
totalSyncNum + = takeList . Count ;
_logger . LogInformation ( "批次={no} 获取最后同步服务状态的ID={maxId}" , batchNo , maxId ) ;
_logger . LogInformation ( "批次={no} 同步待处理任务 totalSyncNum={totalSyncNum}" , batchNo , totalSyncNum ) ;
int takeNum = 1000 ;
//没有记录跳出循环
while ( true )
if ( takeList . Count = = 0 )
{
break ;
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 ( ) ;
maxId = takeList . Max ( a = > a . GS . Id ) ;
totalSyncNum + = takeList . Count ;
_logger . LogInformation ( "批次={no} 获取最后同步服务状态的 maxId={maxId}" , batchNo , maxId ) ;
Console . WriteLine ( $"批次={batchNo} 同步待处理任务 totalSyncNum={totalSyncNum}" ) ;
//写入记录表
_logger . LogInformation ( "批次={no} 同步待处理任务 totalSyncNum={totalSyncNum}" , batchNo , totalSyncNum ) ;
takeList . ForEach ( async record = > {
var entity = new ServiceStatusBookingSyncHisInfo
//没有记录跳出循环
if ( takeList . Count = = 0 )
{
{
PK_ID = IDGen . NextID ( ) . ToString ( ) ,
Console . WriteLine ( $"没有记录跳出循环 total={succSyncNum}" ) ;
ORG_STATUS_ID = record . GS . Id ,
break ;
BOOKING_ID = record . BK . Id ,
}
FINISH_TIME = record . GS . FinishTime . Value ,
FINISH_USER_ID = record . GS . FinishUserId . Value ,
maxId = takeList . Max ( a = > a . GS . Id ) ;
FINISH_USER_NAME = record . GS . FinishUser ,
MBL_NO = record . BK . MBLNO ,
_logger . LogInformation ( "批次={no} 获取最后同步服务状态的 maxId={maxId}" , batchNo , maxId ) ;
SORT_NO = record . CFG . Sort ,
STATUS_SKU_CODE = record . CFG . SystemCode ,
//写入记录表
STATUS_SKU_NAME = record . CFG . StatusName ,
takeList . ForEach ( async record = >
STATUS_REMARK = record . GS . Remark ,
{
STATUS_VAL = record . GS . ExtData ,
var entity = new ServiceStatusBookingSyncHisInfo
TENANT_ID = record . GS . TenantId . Value ,
{
TENANT_NAME = tenantInfo . Name ,
PK_ID = Guid . NewGuid ( ) . ToString ( ) ,
VESSEL = record . BK . VESSEL ,
ORG_STATUS_ID = record . GS . Id ,
VOYNO = record . BK . VOYNO ,
BOOKING_ID = record . BK . Id ,
FINISH_TIME = record . GS . FinishTime . Value ,
} ;
FINISH_USER_ID = record . GS . FinishUserId . Value ,
FINISH_USER_NAME = record . GS . FinishUser ,
await _serviceStatusBookingSyncHisInfoRepository . InsertAsync ( entity ) ;
MBL_NO = record . BK . MBLNO ,
SORT_NO = record . CFG . Sort ,
succSyncNum + + ;
STATUS_SKU_CODE = record . CFG . SystemCode ,
} ) ;
STATUS_SKU_NAME = record . CFG . StatusName ,
STATUS_REMARK = record . GS . Remark ,
Thread . Sleep ( 500 ) ;
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 ;
}
}
}
}