|
|
using Furion;
|
|
|
using Furion.DependencyInjection;
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
using Furion.DynamicApiController;
|
|
|
using Furion.FriendlyException;
|
|
|
using Furion.JsonSerialization;
|
|
|
using Furion.Localization;
|
|
|
using Furion.RemoteRequest;
|
|
|
using Furion.RemoteRequest.Extensions;
|
|
|
using Mapster;
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Myshipping.Application.EDI;
|
|
|
using Myshipping.Application.Entity;
|
|
|
using Myshipping.Application.Helper;
|
|
|
using Myshipping.Core;
|
|
|
using Myshipping.Core.Entity;
|
|
|
using Myshipping.Core.Helper;
|
|
|
using Myshipping.Core.Service;
|
|
|
using MySqlX.XDevAPI.Common;
|
|
|
using Newtonsoft.Json;
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
using Npoi.Mapper;
|
|
|
using NPOI.HPSF;
|
|
|
using NPOI.HSSF.UserModel;
|
|
|
using NPOI.POIFS.Crypt.Dsig;
|
|
|
using NPOI.SS.Formula.Eval;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using NPOI.SS.UserModel;
|
|
|
using NPOI.XSSF.Model;
|
|
|
using Org.BouncyCastle.Asn1.X500;
|
|
|
using SixLabors.ImageSharp.Processing.Processors.Transforms;
|
|
|
using SqlSugar;
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.DirectoryServices.ActiveDirectory;
|
|
|
using System.Dynamic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net;
|
|
|
using System.Net.Http;
|
|
|
using System.Reflection.Metadata.Ecma335;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using System.Security.Policy;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Xml.Linq;
|
|
|
using static Aliyun.OSS.Model.CreateSelectObjectMetaInputFormatModel;
|
|
|
|
|
|
namespace Myshipping.Application
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 任务管理
|
|
|
/// </summary>
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskManage", Order = 10)]
|
|
|
public class TaskManageService : ITaskManageService, IDynamicApiController
|
|
|
{
|
|
|
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskSIFeedBackInfo> _taskSIFeedBackInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskSIFeedBackContaInfo> _taskSIFeedBackContaInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskBillFeeDetailInfo> _taskBillFeeDetailInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskFileInfo> _taskFileInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskEmailInfo> _taskEmailInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskVGMFeedBackInfo> _taskVGMFeedBackInfoRepository;
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRepository;
|
|
|
private readonly SqlSugarRepository<TaskStatManageInfo> _taskStatManageInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskOriginalDownloadHisInfo> _taskOriginalDownloadHisInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskChargesHisInfo> _taskChargesHisInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskLARAPaperInfo> _taskLARAPaperInfoRepository;
|
|
|
private readonly SqlSugarRepository<TaskPerBillBaseInfo> _taskPerBillBaseInfoRepository;
|
|
|
|
|
|
private readonly SqlSugarRepository<BookingOrder> _bookingOrderRepository;
|
|
|
private readonly SqlSugarRepository<BookingCtn> _bookingOrderContaRepository;
|
|
|
private readonly SqlSugarRepository<BookingCtnDetail> _bookingOrderContaCargoRepository;
|
|
|
private readonly SqlSugarRepository<BookingStatus> _bookingStatusRepository;
|
|
|
|
|
|
private readonly SqlSugarRepository<DjyUserMailAccount> _djyUserMailAccountRepository;
|
|
|
|
|
|
private readonly IDjyWebsiteAccountConfigService _webAccountConfig;
|
|
|
private readonly ISysCacheService _cache;
|
|
|
private readonly ILogger<BookingOrderService> _logger;
|
|
|
|
|
|
|
|
|
const string CONST_WEB_ACCOUNT_TYPE = "CmaWeb";
|
|
|
const string CONST_BOOK_ORIGINAL_DOWN_URL_CODE = "bookOriginalDownUrl";
|
|
|
|
|
|
const string CONST_WEB_LARA_ACCOUNT_TYPE = "LaraWeb";
|
|
|
const string CONST_LARA_DOWN_URL_CODE = "LaraPaperPostUrl";
|
|
|
|
|
|
public TaskManageService(SqlSugarRepository<TaskBaseInfo> taskBaseInfoRepository,
|
|
|
SqlSugarRepository<TaskSIFeedBackInfo> taskSIFeedBackInfoRepository,
|
|
|
SqlSugarRepository<TaskSIFeedBackContaInfo> taskSIFeedBackContaInfoRepository,
|
|
|
SqlSugarRepository<TaskBillFeeDetailInfo> taskBillFeeDetailInfoRepository,
|
|
|
SqlSugarRepository<TaskFileInfo> taskFileInfoRepository,
|
|
|
SqlSugarRepository<TaskEmailInfo> taskEmailInfoRepository,
|
|
|
SqlSugarRepository<TaskVGMFeedBackInfo> taskVGMFeedBackInfoRepository,
|
|
|
SqlSugarRepository<SysUser> sysUserRepository,
|
|
|
SqlSugarRepository<TaskStatManageInfo> taskStatManageInfoRepository,
|
|
|
SqlSugarRepository<TaskOriginalDownloadHisInfo> taskOriginalDownloadHisInfoRepository,
|
|
|
SqlSugarRepository<TaskChargesHisInfo> taskChargesHisInfoRepository,
|
|
|
SqlSugarRepository<BookingOrder> bookingOrderRepository,
|
|
|
SqlSugarRepository<TaskLARAPaperInfo> taskLARAPaperInfoRepository,
|
|
|
SqlSugarRepository<BookingCtn> bookingOrderContaRepository,
|
|
|
SqlSugarRepository<BookingCtnDetail> bookingOrderContaCargoRepository,
|
|
|
SqlSugarRepository<BookingStatus> bookingStatusRepository,
|
|
|
SqlSugarRepository<DjyUserMailAccount> djyUserMailAccountRepository,
|
|
|
SqlSugarRepository<TaskPerBillBaseInfo> taskPerBillBaseInfoRepository,
|
|
|
IDjyWebsiteAccountConfigService webAccountConfig,
|
|
|
ISysCacheService cache,
|
|
|
ILogger<BookingOrderService> logger)
|
|
|
{
|
|
|
_taskBaseInfoRepository = taskBaseInfoRepository;
|
|
|
_taskSIFeedBackInfoRepository = taskSIFeedBackInfoRepository;
|
|
|
_taskSIFeedBackContaInfoRepository = taskSIFeedBackContaInfoRepository;
|
|
|
_taskBillFeeDetailInfoRepository = taskBillFeeDetailInfoRepository;
|
|
|
_taskFileInfoRepository = taskFileInfoRepository;
|
|
|
_taskEmailInfoRepository = taskEmailInfoRepository;
|
|
|
_taskVGMFeedBackInfoRepository = taskVGMFeedBackInfoRepository;
|
|
|
_sysUserRepository = sysUserRepository;
|
|
|
_taskStatManageInfoRepository = taskStatManageInfoRepository;
|
|
|
_taskOriginalDownloadHisInfoRepository = taskOriginalDownloadHisInfoRepository;
|
|
|
_taskChargesHisInfoRepository = taskChargesHisInfoRepository;
|
|
|
_bookingOrderRepository = bookingOrderRepository;
|
|
|
_taskLARAPaperInfoRepository = taskLARAPaperInfoRepository;
|
|
|
_bookingOrderContaRepository = bookingOrderContaRepository;
|
|
|
_bookingOrderContaCargoRepository = bookingOrderContaCargoRepository;
|
|
|
_bookingStatusRepository = bookingStatusRepository;
|
|
|
_djyUserMailAccountRepository = djyUserMailAccountRepository;
|
|
|
_taskPerBillBaseInfoRepository = taskPerBillBaseInfoRepository;
|
|
|
|
|
|
_webAccountConfig = webAccountConfig;
|
|
|
_cache = cache;
|
|
|
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
#region 创建任务
|
|
|
/// <summary>
|
|
|
/// 创建任务
|
|
|
/// </summary>
|
|
|
/// <param name="info">任务详情</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[AllowAnonymous, HttpPost("/TaskManage/CreateTaskJob")]
|
|
|
public async Task<TaskManageOrderResultDto> CreateTaskJob(TaskManageOrderMessageInfo info)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
/*
|
|
|
创建任务
|
|
|
1、判断当前任务的主键是否已入库,已入库不允许重复,返回错误提示。
|
|
|
2、
|
|
|
*/
|
|
|
result = await InitTaskJob(info);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"请求任务异常,{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 新增任务
|
|
|
/// <summary>
|
|
|
/// 新增任务
|
|
|
/// </summary>
|
|
|
/// <param name="info">任务详情</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InitTaskJob(TaskManageOrderMessageInfo info)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.OUT_BUSI_NO == info.Head.GID);
|
|
|
|
|
|
if (taskInfo != null)
|
|
|
throw Oops.Oh($"任务已经存在不能重复提交");
|
|
|
|
|
|
taskInfo = new TaskBaseInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_NO = info.Head.GID,
|
|
|
STATUS = TaskStatusEnum.Create.ToString(),
|
|
|
IsDeleted = false,
|
|
|
IS_EXCEPT = 0,
|
|
|
IS_COMPLETE = 0,
|
|
|
MBL_NO = info.Main.MBlNo,
|
|
|
TASK_BASE_TYPE = info.Main.TaskType.ToString(),
|
|
|
CARRIER_ID = info.Main.CarrierId?.Trim(),
|
|
|
IS_PUBLIC = string.IsNullOrWhiteSpace(info.Main.TaskUserId) ? 1 : 0,
|
|
|
BOOK_ORDER_NO = info.Main.BookingOrderNo,
|
|
|
OUT_BUSI_NO = info.Head.GID,
|
|
|
TASK_TITLE = info.Main.TaskTitle,
|
|
|
TASK_DESP = info.Main.TaskDesp,
|
|
|
TASK_SOURCE = info.Main.TaskSource.ToString(),
|
|
|
TASK_TYPE = info.Main.TaskType.ToString(),
|
|
|
};
|
|
|
|
|
|
taskInfo.CreatedTime = DateTime.Now;
|
|
|
taskInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(taskInfo.CARRIER_ID)
|
|
|
&& taskInfo.CARRIER_ID == "MSC")
|
|
|
{
|
|
|
if (TaskBaseTypeEnum.BC.ToString() == taskInfo.TASK_BASE_TYPE)
|
|
|
taskInfo.TASK_TYPE = TaskBusiTypeEnum.MSC_BC.ToString();
|
|
|
|
|
|
if (taskInfo.IS_EXCEPT == 1)
|
|
|
taskInfo.TASK_TYPE = TaskBusiTypeEnum.MSC_EXCEPT.ToString();
|
|
|
}
|
|
|
|
|
|
//新增
|
|
|
await _taskBaseInfoRepository.InsertAsync(taskInfo);
|
|
|
|
|
|
//附件
|
|
|
if (info.Main.FileList != null && info.Main.FileList.Count > 0)
|
|
|
{
|
|
|
info.Main.FileList.ForEach(async file =>
|
|
|
{
|
|
|
var fileInfo = new TaskFileInfo();
|
|
|
|
|
|
fileInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
fileInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
fileInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
fileInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
fileInfo.FILE_PATH = file.FilePath;
|
|
|
fileInfo.FILE_NAME = file.FileName;
|
|
|
fileInfo.FILE_TYPE = file.FileType;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(fileInfo.FILE_NAME))
|
|
|
{
|
|
|
var fileModel = new FileInfo(file.FilePath);
|
|
|
|
|
|
fileInfo.FILE_NAME = fileModel.Name;
|
|
|
fileInfo.FILE_TYPE = fileModel.Extension?.Replace(".", "");
|
|
|
}
|
|
|
|
|
|
await _taskFileInfoRepository.InsertAsync(fileInfo);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
//邮件
|
|
|
if (info.Main.EmailList != null && info.Main.EmailList.Count > 0)
|
|
|
{
|
|
|
info.Main.EmailList.ForEach(async email =>
|
|
|
{
|
|
|
var emailInfo = new TaskEmailInfo();
|
|
|
|
|
|
emailInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
emailInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
emailInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
emailInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
emailInfo.MAIL_PATH = email.MailPath;
|
|
|
|
|
|
await _taskEmailInfoRepository.InsertAsync(emailInfo);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
//SI反馈入库
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.SI_FEEDBACK)
|
|
|
{
|
|
|
if (info.Main.SIFeedBack == null)
|
|
|
throw Oops.Oh($"任务类型={info.Main.TaskType.ToString()} SIFeedBack信息必传");
|
|
|
|
|
|
TaskSIFeedBackInfo taskSIFeedBackInfo = info.Main.SIFeedBack.Adapt<TaskSIFeedBackInfo>();
|
|
|
|
|
|
taskSIFeedBackInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
taskSIFeedBackInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
taskSIFeedBackInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
taskSIFeedBackInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
await _taskSIFeedBackInfoRepository.InsertAsync(taskSIFeedBackInfo);
|
|
|
|
|
|
//SI反馈箱信息入库
|
|
|
if (info.Main.SIFeedBack.ContaList != null && info.Main.SIFeedBack.ContaList.Count > 0)
|
|
|
{
|
|
|
info.Main.SIFeedBack.ContaList.ForEach(async ctn =>
|
|
|
{
|
|
|
var contaInfo = ctn.Adapt<TaskSIFeedBackContaInfo>();
|
|
|
|
|
|
contaInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
contaInfo.P_PKID = taskSIFeedBackInfo.PK_ID;
|
|
|
|
|
|
contaInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
contaInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
await _taskSIFeedBackContaInfoRepository.InsertAsync(contaInfo);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//费用明细
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.INVOICE_BILL_MAIL)
|
|
|
{
|
|
|
if (info.Main.FeeList != null && info.Main.FeeList.Count > 0)
|
|
|
{
|
|
|
info.Main.FeeList.ForEach(async fee =>
|
|
|
{
|
|
|
var feeInfo = fee.Adapt<TaskBillFeeDetailInfo>();
|
|
|
|
|
|
feeInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
feeInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
feeInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
feeInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
await _taskBillFeeDetailInfoRepository.InsertAsync(feeInfo);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (info.Main.TaskType == TaskBaseTypeEnum.PER_BILL)
|
|
|
{
|
|
|
TaskPerBillBaseInfo taskPerBillBaseInfo = info.Main.PerBillInfo.Adapt<TaskPerBillBaseInfo>();
|
|
|
//写入
|
|
|
await _taskPerBillBaseInfoRepository.InsertAsync(taskPerBillBaseInfo);
|
|
|
|
|
|
if (info.Main.FeeList != null && info.Main.FeeList.Count > 0)
|
|
|
{
|
|
|
info.Main.FeeList.ForEach(async fee =>
|
|
|
{
|
|
|
var feeInfo = fee.Adapt<TaskBillFeeDetailInfo>();
|
|
|
|
|
|
feeInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
feeInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
feeInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
feeInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
await _taskBillFeeDetailInfoRepository.InsertAsync(feeInfo);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//VGM反馈入库
|
|
|
if (info.Main.VGMFeedBackList != null && info.Main.VGMFeedBackList.Count > 0)
|
|
|
{
|
|
|
info.Main.VGMFeedBackList.ForEach(async vgm =>
|
|
|
{
|
|
|
var vgmInfo = vgm.Adapt<TaskVGMFeedBackInfo>();
|
|
|
|
|
|
vgmInfo.PK_ID = IDGen.NextID().ToString();
|
|
|
vgmInfo.TASK_PKID = taskInfo.PK_ID;
|
|
|
|
|
|
vgmInfo.CreatedTime = taskInfo.CreatedTime;
|
|
|
vgmInfo.UpdatedTime = taskInfo.CreatedTime;
|
|
|
|
|
|
await _taskVGMFeedBackInfoRepository.InsertAsync(vgmInfo);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.msg = "新增任务成功";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Oh($"{ex.Message}");
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取查询参数
|
|
|
/// <summary>
|
|
|
/// 获取查询参数
|
|
|
/// </summary>
|
|
|
/// <param name="ParaType">参数类型 STATUS-任务状态;TASK_TYPE-任务类型;SOURCE-任务来源 CATEGORY-分类</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
/// <example>TASK_TYPE</example>
|
|
|
[HttpGet("/TaskManage/GetParaInfo")]
|
|
|
public async Task<TaskManageOrderResultDto> GetParaInfo([QueryString] string ParaType)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
try
|
|
|
{
|
|
|
Dictionary<string, string> dict = new Dictionary<string, string>();
|
|
|
|
|
|
if (ParaType == "STATUS")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskStatusEnum));
|
|
|
}
|
|
|
else if (ParaType == "TASK_TYPE")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskBusiTypeEnum));
|
|
|
}
|
|
|
else if (ParaType == "SOURCE")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskSourceEnum));
|
|
|
}
|
|
|
else if (ParaType == "CATEGORY")
|
|
|
{
|
|
|
dict = EnumUtil.GetEnumDictionaryWithKey(typeof(TaskStatLevelEnum));
|
|
|
}
|
|
|
|
|
|
result.succ = true;
|
|
|
result.rows = dict.Select(t => new { Code = t.Key, Name = t.Value }).ToList();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取登陆人相关的任务统计信息
|
|
|
/// <summary>
|
|
|
/// 获取登陆人相关的任务统计信息
|
|
|
/// </summary>
|
|
|
/// <param name="isReCalc">是否强制计算</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
[HttpGet("/TaskManage/GetCurrentTotalStat")]
|
|
|
public async Task<TaskUserStatResultInfo> GetCurrentTotalStat([FromQuery] bool isReCalc = false)
|
|
|
{
|
|
|
TaskUserStatResultInfo resultInfo = new TaskUserStatResultInfo
|
|
|
{
|
|
|
LevelTop = new List<TaskUserStatItem>(),
|
|
|
LevelNext = new List<TaskUserStatItemNext>(),
|
|
|
LevelTree = new List<TaskUserStatItemTree>()
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
1、首先判断当前登陆人是否有统计记录,如果没有触发统计生成统计记录。
|
|
|
2、如果isReCalc=true,表示强制重新统计数据,并重新更新统计数据。
|
|
|
3、按照统计类型(个人/公共)、任务状态、是否异常分组汇总,并写入统计表。
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var userTendInfo = await _sysUserRepository.AsQueryable()
|
|
|
.LeftJoin<SysTenant>((usr, ten) => usr.TenantId == ten.Id)
|
|
|
.Where(usr => usr.Id == UserManager.UserId)
|
|
|
.Select((usr, ten) => new { User = usr, Tend = ten }).FirstAsync();
|
|
|
|
|
|
if (userTendInfo == null)
|
|
|
throw Oops.Oh($"当前用户关联租户信息获取失败");
|
|
|
|
|
|
var statList = _taskStatManageInfoRepository.AsQueryable().Where(t => (t.USER_ID == userTendInfo.User.Id
|
|
|
&& t.STAT_TYPE == TaskStatLevelEnum.PERSON.ToString()) || (t.COMP_ID == userTendInfo.Tend.Id && t.STAT_TYPE == TaskStatLevelEnum.PUBLIC.ToString())).ToList();
|
|
|
|
|
|
if (true)
|
|
|
{
|
|
|
//任务列表分组统计
|
|
|
var groupList = _taskBaseInfoRepository.AsQueryable()
|
|
|
.Where(t => (t.CreatedUserId == UserManager.UserId && t.IS_PUBLIC == 0) || (t.TenantId == userTendInfo.Tend.Id && t.IS_PUBLIC == 1))
|
|
|
.GroupBy(p => new { p.TASK_TYPE, p.STATUS, p.IS_EXCEPT, p.IS_PUBLIC })
|
|
|
.Select(p => new
|
|
|
{
|
|
|
Total = SqlFunc.AggregateCount(p.PK_ID),
|
|
|
TaskType = p.TASK_TYPE,
|
|
|
Status = p.STATUS,
|
|
|
IsExcept = p.IS_EXCEPT,
|
|
|
IsPublic = p.IS_PUBLIC
|
|
|
}).ToList();
|
|
|
|
|
|
var exceptList = groupList
|
|
|
.Where(t => t.IsExcept == 1).ToList();
|
|
|
|
|
|
var personList = groupList
|
|
|
.Where(t => t.IsExcept == 0 && t.IsPublic == 0).ToList();
|
|
|
|
|
|
var publicList = groupList
|
|
|
.Where(t => t.IsExcept == 0 && t.IsPublic == 1).ToList();
|
|
|
|
|
|
#region 异常
|
|
|
if (exceptList.Count > 0)
|
|
|
{
|
|
|
resultInfo.LevelTop.Add(new TaskUserStatItem
|
|
|
{
|
|
|
Key = TaskStatLevelEnum.EXCPTION.ToString(),
|
|
|
Name = TaskStatLevelEnum.EXCPTION.GetDescription(),
|
|
|
Total = exceptList.Sum(t => t.Total),
|
|
|
SortNo = (int)TaskStatLevelEnum.EXCPTION,
|
|
|
ActionKey = TaskStatLevelEnum.EXCPTION.ToString()
|
|
|
});
|
|
|
|
|
|
exceptList.GroupBy(t => t.Status)
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
|
|
|
|
|
|
resultInfo.LevelNext.Add(new TaskUserStatItemNext
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.EXCPTION.ToString(),
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.EXCPTION.ToString()}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
exceptList.GroupBy(t => new { t.Status, t.TaskType })
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
|
|
|
|
|
|
resultInfo.LevelTree.Add(new TaskUserStatItemTree
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.EXCPTION.ToString(),
|
|
|
NextKey = t.Key.Status,
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.EXCPTION.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 个人
|
|
|
if (personList.Count > 0)
|
|
|
{
|
|
|
resultInfo.LevelTop.Add(new TaskUserStatItem
|
|
|
{
|
|
|
Key = TaskStatLevelEnum.PERSON.ToString(),
|
|
|
Name = TaskStatLevelEnum.PERSON.GetDescription(),
|
|
|
Total = personList.Sum(t => t.Total),
|
|
|
SortNo = (int)TaskStatLevelEnum.PERSON,
|
|
|
ActionKey = TaskStatLevelEnum.PERSON.ToString()
|
|
|
});
|
|
|
|
|
|
personList.GroupBy(t => t.Status)
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
|
|
|
|
|
|
resultInfo.LevelNext.Add(new TaskUserStatItemNext
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PERSON.ToString(),
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PERSON.ToString()}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
personList.GroupBy(t => new { t.Status, t.TaskType })
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
|
|
|
|
|
|
resultInfo.LevelTree.Add(new TaskUserStatItemTree
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PERSON.ToString(),
|
|
|
NextKey = t.Key.Status,
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PERSON.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 公共
|
|
|
if (publicList.Count > 0)
|
|
|
{
|
|
|
resultInfo.LevelTop.Add(new TaskUserStatItem
|
|
|
{
|
|
|
Key = TaskStatLevelEnum.PUBLIC.ToString(),
|
|
|
Name = TaskStatLevelEnum.PUBLIC.GetDescription(),
|
|
|
Total = publicList.Sum(t => t.Total),
|
|
|
SortNo = (int)TaskStatLevelEnum.PUBLIC,
|
|
|
ActionKey = TaskStatLevelEnum.PUBLIC.ToString()
|
|
|
});
|
|
|
|
|
|
publicList.GroupBy(t => t.Status)
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskStatusEnum currEnum = (TaskStatusEnum)System.Enum.Parse(typeof(TaskStatusEnum), t.Key);
|
|
|
|
|
|
resultInfo.LevelNext.Add(new TaskUserStatItemNext
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PUBLIC.ToString()}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
publicList.GroupBy(t => new { t.Status, t.TaskType })
|
|
|
.Select(t => new { Key = t.Key, Total = t.ToList().Sum(p => p.Total) })
|
|
|
.ToList().ForEach(t =>
|
|
|
{
|
|
|
TaskBusiTypeEnum currEnum = (TaskBusiTypeEnum)System.Enum.Parse(typeof(TaskBusiTypeEnum), t.Key.TaskType);
|
|
|
|
|
|
resultInfo.LevelTree.Add(new TaskUserStatItemTree
|
|
|
{
|
|
|
TopKey = TaskStatLevelEnum.PUBLIC.ToString(),
|
|
|
NextKey = t.Key.Status,
|
|
|
Key = currEnum.ToString(),
|
|
|
Name = currEnum.GetDescription(),
|
|
|
Total = t.Total,
|
|
|
SortNo = (int)currEnum,
|
|
|
ActionKey = $"{TaskStatLevelEnum.PUBLIC.ToString()}#{t.Key.Status}#{currEnum.ToString()}"
|
|
|
});
|
|
|
|
|
|
});
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取登陆人相关的任务统计信息异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return resultInfo;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 任务台账查询
|
|
|
/// <summary>
|
|
|
/// 任务台账查询
|
|
|
/// </summary>
|
|
|
/// <param name="QuerySearch">任务台账查询请求</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/GetPage")]
|
|
|
public async Task<SqlSugarPagedList<TaskBaseInfoDto>> GetPageAsync(QueryTaskManageDto QuerySearch)
|
|
|
{
|
|
|
List<string> mblList = new List<string>();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.MBlNo))
|
|
|
{
|
|
|
if (Regex.IsMatch(QuerySearch.MBlNo, "(\\t|\\n\\r|\\n)"))
|
|
|
{
|
|
|
mblList = Regex.Replace(QuerySearch.MBlNo, "(\\t |\\n\\r |\\n)", "#").Split(new char[] { '#' }).Select(t => t?.Trim()).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
mblList.Add(QuerySearch.MBlNo.Trim());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
DateTime etdBegin = DateTime.MinValue;
|
|
|
DateTime etdEnd = DateTime.MinValue;
|
|
|
|
|
|
DateTime taskDateBegin = DateTime.MinValue;
|
|
|
DateTime taskDateEnd = DateTime.MinValue;
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDBegin, out etdBegin))
|
|
|
throw Oops.Oh($"开船起始日期格式错误,{QuerySearch.ETDBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.ETDEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.ETDEnd, out etdEnd))
|
|
|
throw Oops.Oh($"开船结束日期格式错误,{QuerySearch.ETDEnd}");
|
|
|
|
|
|
etdEnd = etdEnd.AddDays(1);
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.TaskDateBegin))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.TaskDateBegin, out taskDateBegin))
|
|
|
throw Oops.Oh($"任务起始日期格式错误,{QuerySearch.TaskDateBegin}");
|
|
|
}
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.TaskDateEnd))
|
|
|
{
|
|
|
if (!DateTime.TryParse(QuerySearch.TaskDateEnd, out taskDateEnd))
|
|
|
throw Oops.Oh($"任务结束日期格式错误,{QuerySearch.TaskDateEnd}");
|
|
|
|
|
|
etdEnd = etdEnd.AddDays(1);
|
|
|
}
|
|
|
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
//这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段
|
|
|
if (!string.IsNullOrWhiteSpace(QuerySearch.SortField))
|
|
|
entityOrderCol = MapsterExtHelper.GetAdaptProperty<TaskBaseInfoDto, TaskBaseInfo>(QuerySearch.SortField);
|
|
|
|
|
|
var entities = await _taskBaseInfoRepository.AsQueryable()
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.MBlNo), t => mblList.Any(p => p.Contains(t.MBL_NO, StringComparison.OrdinalIgnoreCase)))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskRecvName), t => t.CreatedUserName.Contains(QuerySearch.TaskRecvName.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
|
.WhereIF(etdBegin != DateTime.MinValue, t => t.ETD.HasValue && t.ETD.Value >= etdBegin)
|
|
|
.WhereIF(etdEnd != DateTime.MinValue, t => t.ETD.HasValue && t.ETD.Value < etdEnd)
|
|
|
.WhereIF(taskDateBegin != DateTime.MinValue, t => t.CreatedTime >= taskDateBegin)
|
|
|
.WhereIF(taskDateEnd != DateTime.MinValue, t => t.CreatedTime < taskDateEnd)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskType), t => t.TASK_TYPE.Equals(QuerySearch.TaskType, StringComparison.OrdinalIgnoreCase))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskSource), t => t.TASK_SOURCE.Equals(QuerySearch.TaskSource, StringComparison.OrdinalIgnoreCase))
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.EXCPTION.ToString(), t => t.IS_EXCEPT == 1)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.PUBLIC.ToString(), t => t.IS_PUBLIC == 1)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.TaskCategory) && QuerySearch.TaskCategory == TaskStatLevelEnum.PERSON.ToString(), t => t.IS_PUBLIC == 0 && t.IS_EXCEPT == 0)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(QuerySearch.Status), t => t.STATUS.Equals(QuerySearch.Status, StringComparison.OrdinalIgnoreCase))
|
|
|
.OrderBy(entityOrderCol + (QuerySearch.descSort ? " asc " : " desc "))
|
|
|
.ToPagedListAsync(QuerySearch.PageNo, QuerySearch.PageSize);
|
|
|
|
|
|
|
|
|
return entities.Adapt<SqlSugarPagedList<TaskBaseInfoDto>>();
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载正本提单(可批量)
|
|
|
/// <summary>
|
|
|
/// 下载正本提单(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/DownloadOriginalTask")]
|
|
|
public async Task<TaskManageOrderResultDto> DownloadOriginalTask(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 下载正本提单开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置
|
|
|
var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_WEB_ACCOUNT_TYPE, UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig));
|
|
|
|
|
|
if (userWebAccountConfig == null)
|
|
|
throw Oops.Bah($"个人/公司网站【{CONST_WEB_ACCOUNT_TYPE}】获取失败,请维护个人/公司网站账户信息");
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerDownloadOriginalTask(batchNo, tsk, userWebAccountConfig);
|
|
|
});
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"下载正本提单异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 单票正本下载
|
|
|
/// <summary>
|
|
|
/// 单票正本下载
|
|
|
/// </summary>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <param name="taskBaseInfo">任务详情</param>
|
|
|
/// <param name="webAccountConfig">网站账户配置</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerDownloadOriginalTask(string batchNo, TaskBaseInfo taskBaseInfo,
|
|
|
DjyWebsiteAccountConfig webAccountConfig)
|
|
|
{
|
|
|
var result = new TaskManageOrderResultDto();
|
|
|
|
|
|
/*
|
|
|
1、TaskOriginalDownloadHisInfo表中处理任务是succ/temp不允许重复下载。failure/timeout的记录可以再次发起下载。
|
|
|
2、从任务表提取RESULT_NOTE回执信息,里面包含了JSON数据 {"pageUrl":"http://www.cnc-ebusiness.com/ebusiness/bl/detail/AASM104300"}
|
|
|
3、异步请求正本下载的链接,有超时时间。
|
|
|
4、下载完成后写入记录
|
|
|
*/
|
|
|
|
|
|
//正本下载URL
|
|
|
string originalUrl = string.Empty;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var hisList = _taskOriginalDownloadHisInfoRepository
|
|
|
.Where(t => t.TASK_ID == taskBaseInfo.PK_ID).ToList();
|
|
|
|
|
|
if (hisList.Any(t => new string[] { "succ", "temp" }.Contains(t.STATUS)))
|
|
|
throw Oops.Bah("下载URL不存在,请用最新任务数据");
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskBaseInfo.RESULT_NOTE))
|
|
|
throw Oops.Bah("下载URL不存在,请用最新任务数据");
|
|
|
|
|
|
var resultObj = JSON.Deserialize<dynamic>(taskBaseInfo.RESULT_NOTE);
|
|
|
|
|
|
originalUrl = resultObj.pageUrl.ToString();
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(originalUrl))
|
|
|
throw Oops.Bah("解析下载URL不存在,请用最新任务数据");
|
|
|
|
|
|
DateTime startDate = DateTime.Now;
|
|
|
|
|
|
var downloadUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.First(t => t.Code.Equals(CONST_BOOK_ORIGINAL_DOWN_URL_CODE, StringComparison.OrdinalIgnoreCase))?.Value;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(downloadUrl))
|
|
|
throw Oops.Bah($"正本下载URL不存在,请确认字典是否配置 code={CONST_BOOK_ORIGINAL_DOWN_URL_CODE}");
|
|
|
|
|
|
TaskOriginalDownloadHisInfo taskOriginalDownloadHisInfo = new TaskOriginalDownloadHisInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
REQUEST_URL = originalUrl,
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
STATUS = "temp",
|
|
|
IS_TIMEOUT = 0,
|
|
|
START_DATE = startDate,
|
|
|
TenantId = UserManager.TENANT_ID,
|
|
|
TenantName = UserManager.TENANT_NAME
|
|
|
};
|
|
|
|
|
|
//写入记录
|
|
|
_taskOriginalDownloadHisInfoRepository.Insert(taskOriginalDownloadHisInfo);
|
|
|
|
|
|
//请求远程链接
|
|
|
Dictionary<string, string> formDict = new Dictionary<string, string> {
|
|
|
{"bno", taskBaseInfo.MBL_NO },
|
|
|
{"page_url", downloadUrl },
|
|
|
{"web_user", webAccountConfig.Account },
|
|
|
{"web_pwd", webAccountConfig.Password },
|
|
|
{"web_pwd", "myshipping_task" },
|
|
|
{"web_pwd", "" }
|
|
|
};
|
|
|
|
|
|
//请求下载正本
|
|
|
var postResult = await InnerRemoteDownOriginal(batchNo, downloadUrl, formDict);
|
|
|
|
|
|
//重新获取下载历史
|
|
|
var downloadHisInfo = _taskOriginalDownloadHisInfoRepository.AsQueryable()
|
|
|
.First(t => t.PK_ID == taskOriginalDownloadHisInfo.PK_ID);
|
|
|
|
|
|
//更新任务状态
|
|
|
var taskModel = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskBaseInfo.PK_ID);
|
|
|
|
|
|
downloadHisInfo.END_DATE = (DateTime)postResult.ext;
|
|
|
downloadHisInfo.RESULT_NOTE = postResult.msg;
|
|
|
|
|
|
bool isDownSucc = false;
|
|
|
|
|
|
//下载返回成功后,更新记录并生成扣费记录
|
|
|
if (postResult.succ)
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "succ";
|
|
|
downloadHisInfo.RESULT_URL = postResult.msg;
|
|
|
|
|
|
taskModel.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskModel.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
taskModel.COMPLETE_DATE = DateTime.Now;
|
|
|
taskModel.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskModel.IS_COMPLETE = 1;
|
|
|
|
|
|
isDownSucc = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (postResult.isTimeout)
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "timeout";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "failure";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//更新下载历史
|
|
|
await _taskOriginalDownloadHisInfoRepository.AsUpdateable(downloadHisInfo).IgnoreColumns(it => new
|
|
|
{
|
|
|
it.TenantId,
|
|
|
it.CreatedUserId,
|
|
|
it.CreatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
//异步扣费,这里不管是否失败都生成扣费记录,只在状态上做标识。
|
|
|
var chargeResult = await InnerChargeFee(taskBaseInfo, isDownSucc);
|
|
|
|
|
|
_taskBaseInfoRepository.AsUpdateable(taskModel).UpdateColumns(it => new
|
|
|
{
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME
|
|
|
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 远程请求正本下载
|
|
|
/// <summary>
|
|
|
/// 远程请求正本下载
|
|
|
/// </summary>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <param name="url">请求URL</param>
|
|
|
/// <param name="dic">请求参数</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerRemoteDownOriginal(string batchNo, string url, Dictionary<string, string> dic)
|
|
|
{
|
|
|
var result = new TaskManageOrderResultDto();
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
_logger.LogInformation("批次={no} 请求报文开始", batchNo);
|
|
|
|
|
|
var res = await url.SetHttpMethod(HttpMethod.Post)
|
|
|
.SetBody(dic, "application/x-www-form-urlencoded")
|
|
|
.SetContentEncoding(Encoding.UTF8)
|
|
|
.PostAsync();
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(res));
|
|
|
|
|
|
if (res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
var downResult = JSON.Deserialize<dynamic>(userResult);
|
|
|
|
|
|
//返回详情
|
|
|
result.msg = downResult.message.ToString();
|
|
|
|
|
|
//返回代码
|
|
|
if (downResult.status.ToString() == "1")
|
|
|
{
|
|
|
result.succ = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
result.ext = eDate;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
//如果有异常直接抛出错误
|
|
|
throw Oops.Bah(ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 扣费
|
|
|
/// <summary>
|
|
|
/// 扣费
|
|
|
/// </summary>
|
|
|
/// <param name="taskBaseInfo">任务信息</param>
|
|
|
/// <param name="isCharge">是否执行扣费 true-执行扣费 false-不执行扣费(主要是符合扣费条件但是由于超时没有得到准确回执)</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerChargeFee(TaskBaseInfo taskBaseInfo, bool isCharge = true)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto { succ = false };
|
|
|
try
|
|
|
{
|
|
|
decimal balance = 0;
|
|
|
decimal price = 0;
|
|
|
decimal total = 0;
|
|
|
|
|
|
TaskChargesHisInfo model = new TaskChargesHisInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
BEFORE_BALANCE = balance,
|
|
|
PRICE = price,
|
|
|
BUSI_TYPE = "21",
|
|
|
BUSI_TYPE_NAME = String.Empty,
|
|
|
SEND_TYPE = "1001",
|
|
|
SEND_TYPE_NAME = String.Empty,
|
|
|
REMARK = "正本下载",
|
|
|
QTY = 1,
|
|
|
TOTAL_AMOUNT = total,
|
|
|
};
|
|
|
|
|
|
if (!isCharge)
|
|
|
{
|
|
|
model.STATUS = TaskChargeStatusEnum.UNKNOW_RESULT.ToString();
|
|
|
model.STATUS_NAME = TaskChargeStatusEnum.UNKNOW_RESULT.GetDescription();
|
|
|
}
|
|
|
|
|
|
//写入记录
|
|
|
await _taskChargesHisInfoRepository.InsertAsync(model);
|
|
|
|
|
|
result.succ = false;
|
|
|
result.msg = "扣费失败";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 完成任务(可批量)
|
|
|
/// <summary>
|
|
|
/// 完成任务(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/CompleteTask")]
|
|
|
public async Task<TaskManageOrderResultDto> CompleteTask(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 完成任务开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerManualTask(batchNo, tsk, TaskOperTypeEnum.COMPLETE_TASK);
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"完成任务异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
private async Task<TaskManageOrderResultDto> InnerManualTask(string batchNo, TaskBaseInfo taskBaseInfo, TaskOperTypeEnum taskOperTypeEnum)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var model = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskBaseInfo.PK_ID);
|
|
|
|
|
|
if (taskOperTypeEnum == TaskOperTypeEnum.COMPLETE_TASK)
|
|
|
{
|
|
|
|
|
|
if (taskBaseInfo.TASK_TYPE == TaskBusiTypeEnum.CANCELLATION.ToString())
|
|
|
{
|
|
|
//收到订舱已被取消邮件后生成的任务,如果点击完成,(订舱状态变为【退舱】,注意这里还需要确认)
|
|
|
}
|
|
|
|
|
|
model.COMPLETE_DATE = DateTime.Now;
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
model.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
model.IS_COMPLETE = 1;
|
|
|
|
|
|
_taskBaseInfoRepository.AsUpdateable(model).UpdateColumns(it => new
|
|
|
{
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.IS_COMPLETE
|
|
|
}).ExecuteCommand();
|
|
|
}
|
|
|
else if (taskOperTypeEnum == TaskOperTypeEnum.CANCEL_TASK)
|
|
|
{
|
|
|
if (taskBaseInfo.TASK_TYPE == TaskBusiTypeEnum.CHANGE_SHIP.ToString())
|
|
|
{
|
|
|
model.STATUS = TaskStatusEnum.Cancel.ToString();
|
|
|
}
|
|
|
else if (taskBaseInfo.TASK_TYPE == TaskBusiTypeEnum.ABORT_CHANGE_SHIP.ToString())
|
|
|
{
|
|
|
/*
|
|
|
1.如果原换船通知已经接受,需要把原船名航次恢复并通知客户取消换船。
|
|
|
2.如果原换船通知未作处理,点击接受或者结束任务时提示:本票货存在未处理换船通知,请先结束原换船任务然后结束本任务。
|
|
|
3.如果原换船任务为结束任务,在取消换船任务点接受时,提示未做换船,请点击结束任务。
|
|
|
*/
|
|
|
|
|
|
//查询同票主单的是否有未处理的换船通知
|
|
|
//_taskBaseInfoRepository.AsQueryable().Where(t=>t.MBL_NO.Equals(taskBaseInfo.MBL_NO) && )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = $"异常,{ex.Message}";
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
#region 取消任务(可批量)
|
|
|
/// <summary>
|
|
|
/// 取消任务(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/CancelTask")]
|
|
|
public async Task<TaskManageOrderResultDto> CancelTask(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 取消任务开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerManualTask(batchNo, tsk, TaskOperTypeEnum.CANCEL_TASK);
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"完成任务异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 挂起任务(可批量)
|
|
|
/// <summary>
|
|
|
/// 挂起任务(可批量)
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/PendingTask")]
|
|
|
public async Task<TaskManageOrderResultDto> PendingTask(string[] PKIds)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 挂起任务开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID)).ToList();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成,Num={Num}", batchNo, taskList.Count);
|
|
|
|
|
|
taskList.ForEach(async tsk =>
|
|
|
{
|
|
|
|
|
|
await InnerManualTask(batchNo, tsk, TaskOperTypeEnum.PENDING_TASK);
|
|
|
});
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"完成任务异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 提单纸页数计算
|
|
|
/// <summary>
|
|
|
/// 提单纸页数计算
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/LaraPaperCalc")]
|
|
|
public async Task<List<LaraPaperCalcInfo>> LaraPaperCalc(string[] PKIds)
|
|
|
{
|
|
|
List<LaraPaperCalcInfo> list = new List<LaraPaperCalcInfo>();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} 提单纸页数计算开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
try
|
|
|
{
|
|
|
//根据任务主键获取所有主单号列表
|
|
|
var mblnoList = _taskBaseInfoRepository.AsQueryable().Where(t => PKIds.Contains(t.PK_ID) && !string.IsNullOrWhiteSpace(t.MBL_NO))
|
|
|
.Select(t => t.MBL_NO).Distinct().ToList();
|
|
|
|
|
|
if (mblnoList.Count > 0)
|
|
|
{
|
|
|
//根据主单号获取任务类型是DRAFT的任务,取时间最新的
|
|
|
var fileList = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskFileInfo>((tsk, file) => tsk.PK_ID == file.TASK_PKID)
|
|
|
.Where((tsk, file) =>
|
|
|
tsk.TASK_TYPE == TaskBusiTypeEnum.DRAFT.ToString() && mblnoList.Contains(tsk.MBL_NO))
|
|
|
.Select((tsk, file) => new { tsk = tsk, file = file }).ToList();
|
|
|
|
|
|
var calcList = fileList.GroupBy(t => t.tsk.PK_ID)
|
|
|
.Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new
|
|
|
{
|
|
|
tsk = currList.FirstOrDefault().tsk,
|
|
|
clist = a.Select(x => x.file).ToList()
|
|
|
};
|
|
|
}).OrderByDescending(t => t.tsk.CreatedTime).ToList();
|
|
|
|
|
|
|
|
|
list = mblnoList.Select((mbl, idx) =>
|
|
|
{
|
|
|
var calcInfo = new LaraPaperCalcInfo();
|
|
|
|
|
|
calcInfo.MBLNo = mbl;
|
|
|
calcInfo.Indx = idx + 1;
|
|
|
|
|
|
var files = calcList.FirstOrDefault(t => t.tsk.MBL_NO.Equals(mbl, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (files != null)
|
|
|
{
|
|
|
calcInfo.DraftNum = files.clist.Select(t => t.FILE_NAME.GetPageNum()).Sum();
|
|
|
}
|
|
|
|
|
|
calcInfo.PaperNum = calcInfo.DraftNum * 3;
|
|
|
|
|
|
return calcInfo;
|
|
|
}).ToList();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"提单纸页数计算异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 请求提单纸登记
|
|
|
/// <summary>
|
|
|
/// 请求提单纸登记
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="model">提单纸登记请求参数</param>
|
|
|
/// <returns></returns>
|
|
|
[HttpPost("/TaskManage/LaraPaperRegistPost")]
|
|
|
public async Task<TaskManageOrderResultDto> LaraPaperRegistPost(string taskPKId, LaraPaperRegistPostDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} id={id} LARA提单纸登记开始", batchNo, taskPKId);
|
|
|
|
|
|
/*
|
|
|
1、读取LARA网站的配置账户。
|
|
|
2、读取字典的URL。
|
|
|
3、组织请求参数。
|
|
|
4、写入TASK_LARA_PAPER。
|
|
|
5、远程请求。
|
|
|
6、更新状态
|
|
|
*/
|
|
|
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取任务完成", batchNo);
|
|
|
|
|
|
//获取个人对应的账户,这里GetAccountConfig逻辑优先取个人,个人没有配置取公司对应配置
|
|
|
var userWebAccountConfig = _webAccountConfig.GetAccountConfig(CONST_WEB_LARA_ACCOUNT_TYPE, UserManager.UserId).GetAwaiter().GetResult();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 获取获取网站的账户完成,result={Num}", batchNo, JSON.Serialize(userWebAccountConfig));
|
|
|
|
|
|
if (userWebAccountConfig == null)
|
|
|
throw Oops.Bah($"个人/公司网站【{CONST_WEB_LARA_ACCOUNT_TYPE}】获取失败,请维护个人/公司网站账户信息");
|
|
|
|
|
|
await InnerDownloadOriginalTask(batchNo, taskInfo, userWebAccountConfig);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"请求提单纸登记异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
//LaraPaperPostUrl
|
|
|
private async Task<TaskManageOrderResultDto> InnerLaraPaperRegistPost(string batchNo, TaskBaseInfo taskBaseInfo, LaraPaperRegistPostDto model,
|
|
|
DjyWebsiteAccountConfig webAccountConfig)
|
|
|
{
|
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
//正本下载URL
|
|
|
string originalUrl = string.Empty;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
DateTime startDate = DateTime.Now;
|
|
|
|
|
|
var downloadUrl = _cache.GetAllDictData().GetAwaiter().GetResult()
|
|
|
.First(t => t.Code.Equals(CONST_LARA_DOWN_URL_CODE, StringComparison.OrdinalIgnoreCase))?.Value;
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(downloadUrl))
|
|
|
throw Oops.Bah($"正本下载URL不存在,请确认字典是否配置 code={CONST_BOOK_ORIGINAL_DOWN_URL_CODE}");
|
|
|
|
|
|
TaskLARAPaperInfo taskLARAPaperInfo = new TaskLARAPaperInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
BOOKING_ORDER_NO = "",
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
STATUS = "temp",
|
|
|
IS_TIMEOUT = 0,
|
|
|
START_DATE = startDate,
|
|
|
TenantId = UserManager.TENANT_ID,
|
|
|
TenantName = UserManager.TENANT_NAME
|
|
|
};
|
|
|
|
|
|
//写入记录
|
|
|
_taskLARAPaperInfoRepository.Insert(taskLARAPaperInfo);
|
|
|
|
|
|
//请求远程链接
|
|
|
Dictionary<string, string> formDict = new Dictionary<string, string> {
|
|
|
{"bno", taskBaseInfo.MBL_NO },
|
|
|
{"num_from", model.NumberFrom },
|
|
|
{"num_to", model.NumberTo },
|
|
|
{"numbers", model.PageNumbers },
|
|
|
{"vessel_code", "" },
|
|
|
{"voyage_code", "" },
|
|
|
{"bl_status", "All" },
|
|
|
{"bl_type", "Original Bill" },
|
|
|
{"issue_code", "ALL" },
|
|
|
{"web_user", webAccountConfig.Account },
|
|
|
{"web_pwd", webAccountConfig.Password },
|
|
|
{"customer_user", "myshipping" },
|
|
|
{"customer_pwd", "" },
|
|
|
};
|
|
|
|
|
|
//请求
|
|
|
var postResult = await InnerRemoteDownLaraPaper(batchNo, downloadUrl, formDict);
|
|
|
|
|
|
//重新获取下载历史
|
|
|
var downloadHisInfo = _taskOriginalDownloadHisInfoRepository.AsQueryable()
|
|
|
.First(t => t.PK_ID == taskLARAPaperInfo.PK_ID);
|
|
|
|
|
|
//更新任务状态
|
|
|
var taskModel = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskBaseInfo.PK_ID);
|
|
|
|
|
|
downloadHisInfo.END_DATE = (DateTime)postResult.ext;
|
|
|
downloadHisInfo.RESULT_NOTE = postResult.msg;
|
|
|
|
|
|
bool isDownSucc = false;
|
|
|
|
|
|
//下载返回成功后,更新记录并生成扣费记录
|
|
|
if (postResult.succ)
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "succ";
|
|
|
downloadHisInfo.RESULT_URL = postResult.msg;
|
|
|
|
|
|
taskModel.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskModel.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
taskModel.COMPLETE_DATE = DateTime.Now;
|
|
|
taskModel.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskModel.IS_COMPLETE = 1;
|
|
|
|
|
|
isDownSucc = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (postResult.isTimeout)
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "timeout";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
downloadHisInfo.STATUS = "failure";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//更新下载历史
|
|
|
await _taskOriginalDownloadHisInfoRepository.AsUpdateable(downloadHisInfo).IgnoreColumns(it => new
|
|
|
{
|
|
|
it.TenantId,
|
|
|
it.CreatedUserId,
|
|
|
it.CreatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
#region 远程请求请求提单纸登记
|
|
|
/// <summary>
|
|
|
/// 远程请求请求提单纸登记
|
|
|
/// </summary>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <param name="url">请求URL</param>
|
|
|
/// <param name="dic">请求参数</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerRemoteDownLaraPaper(string batchNo, string url, Dictionary<string, string> dic)
|
|
|
{
|
|
|
var result = new TaskManageOrderResultDto();
|
|
|
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
_logger.LogInformation("批次={no} 请求报文开始", batchNo);
|
|
|
|
|
|
var res = await url.SetHttpMethod(HttpMethod.Post)
|
|
|
.SetBody(dic, "application/x-www-form-urlencoded")
|
|
|
.SetContentEncoding(Encoding.UTF8)
|
|
|
.PostAsync();
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.LogInformation("批次={no} 请求完成,耗时:{timeDiff}ms. 结果{msg}", batchNo, timeDiff, JSON.Serialize(res));
|
|
|
|
|
|
if (res.StatusCode == System.Net.HttpStatusCode.OK)
|
|
|
{
|
|
|
var userResult = await res.Content.ReadAsStringAsync();
|
|
|
|
|
|
var downResult = JSON.Deserialize<dynamic>(userResult);
|
|
|
|
|
|
//返回详情
|
|
|
result.msg = downResult.message.ToString();
|
|
|
|
|
|
//返回代码
|
|
|
if (downResult.status.ToString() == "1")
|
|
|
{
|
|
|
result.succ = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
result.succ = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
result.ext = eDate;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
//如果有异常直接抛出错误
|
|
|
throw Oops.Bah(ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region LARA提单纸登记
|
|
|
/// <summary>
|
|
|
/// LARA提单纸登记
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/LaraPaperRegist")]
|
|
|
public async Task<LaraPaperRegistDto> LaraPaperRegist(string[] PKIds)
|
|
|
{
|
|
|
LaraPaperRegistDto result = new LaraPaperRegistDto();
|
|
|
|
|
|
List<LaraPaperRegistDetailDto> list = new List<LaraPaperRegistDetailDto>();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
_logger.LogInformation("批次={no} ids={ids} LARA提单纸登记开始", batchNo, string.Join(",", PKIds));
|
|
|
|
|
|
/*
|
|
|
1、通过任务主键记录关联所有相同订舱主键相同并且任务类型是(DRAFT)的记录。
|
|
|
2、关联任务正本下载运行表(结束时间)
|
|
|
|
|
|
问题:提单纸页数计算是通过主单号来最新记录提取文件页数,为什么LARA提单纸登记没有用这个模式。(没理解)
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
//
|
|
|
var List = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskBaseInfo>((tsk, tsk2) => tsk.BOOK_ORDER_NO == tsk2.BOOK_ORDER_NO)
|
|
|
.Where((tsk, tsk2) => PKIds.Contains(tsk.PK_ID) && tsk2.TASK_TYPE == TaskBusiTypeEnum.DRAFT.ToString())
|
|
|
.Select((tsk, tsk2) => new { tsk = tsk, tsk2 = tsk2 }).ToList();
|
|
|
|
|
|
var list2 = List.GroupBy(t => t.tsk.PK_ID).Select(t =>
|
|
|
{
|
|
|
var curList = t.ToList();
|
|
|
|
|
|
if (curList.Count > 0)
|
|
|
{
|
|
|
return new { tsk = curList.FirstOrDefault().tsk, tsk2 = curList.OrderByDescending(a => a.tsk2.CreatedTime).FirstOrDefault().tsk2 };
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}).Where(t => t != null).ToList();
|
|
|
|
|
|
if (list2.Count > 0)
|
|
|
{
|
|
|
var taskPKIdList = list2.Select(t => t.tsk2.PK_ID).Distinct().ToArray();
|
|
|
|
|
|
var originalDownloadHisInfo = _taskOriginalDownloadHisInfoRepository.AsQueryable()
|
|
|
.Where(t => taskPKIdList.Contains(t.TASK_ID))
|
|
|
.OrderByDescending(t => t.END_DATE)
|
|
|
.First();
|
|
|
|
|
|
var fileList = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskFileInfo>((tsk, file) => tsk.PK_ID == file.TASK_PKID)
|
|
|
.Where((tsk, file) =>
|
|
|
tsk.TASK_TYPE == TaskBusiTypeEnum.DRAFT.ToString() && taskPKIdList.Contains(tsk.PK_ID))
|
|
|
.Select((tsk, file) => new { tsk = tsk, file = file }).ToList();
|
|
|
|
|
|
var calcList = fileList.GroupBy(t => t.tsk.PK_ID)
|
|
|
.Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new
|
|
|
{
|
|
|
tsk = currList.FirstOrDefault().tsk,
|
|
|
clist = a.Select(x => x.file).ToList()
|
|
|
};
|
|
|
}).OrderByDescending(t => t.tsk.CreatedTime).ToList();
|
|
|
|
|
|
list2.ForEach(t =>
|
|
|
{
|
|
|
LaraPaperRegistDetailDto laraInfo = new LaraPaperRegistDetailDto();
|
|
|
|
|
|
laraInfo.OrderNo = t.tsk.BOOK_ORDER_NO;
|
|
|
laraInfo.TaskId = t.tsk.PK_ID;
|
|
|
laraInfo.MBLNo = t.tsk.MBL_NO;
|
|
|
|
|
|
var files = calcList.FirstOrDefault(a => a.tsk.PK_ID.Equals(t.tsk.PK_ID));
|
|
|
|
|
|
if (files != null)
|
|
|
{
|
|
|
laraInfo.DraftNum = files.clist.Select(t => t.FILE_NAME.GetPageNum()).Sum();
|
|
|
}
|
|
|
|
|
|
laraInfo.OriginalDownTime = originalDownloadHisInfo.END_DATE;
|
|
|
laraInfo.IssueType = t.tsk.ISSUE_TYPE;
|
|
|
laraInfo.IssueTypeName = t.tsk2.ISSUE_TYPE_NAME;
|
|
|
|
|
|
list.Add(laraInfo);
|
|
|
});
|
|
|
|
|
|
result.DetailList = list;
|
|
|
}
|
|
|
|
|
|
var laraPaperInfo = _taskLARAPaperInfoRepository.AsQueryable()
|
|
|
.Where(t => t.CreatedUserId == UserManager.UserId)
|
|
|
.OrderByDescending(t => t.NUMBER_TO).First();
|
|
|
|
|
|
result.NumberTo = laraPaperInfo != null ? Int32.Parse(laraPaperInfo.NUMBER_TO) : 0;
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"LARA提单纸登记异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载任务附件
|
|
|
/// <summary>
|
|
|
/// 下载任务附件
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId"></param>
|
|
|
/// <returns>返回文件流</returns>
|
|
|
[HttpGet("/TaskManage/DownloadTaskAttach")]
|
|
|
public async Task<IActionResult> DownloadTaskAttach([FromQuery] string taskPKId)
|
|
|
{
|
|
|
FileStreamResult result = null;
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
var fileList = _taskFileInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskPKId).OrderByDescending(t=>t.CreatedTime).ToList();
|
|
|
|
|
|
var fileInfo = fileList.FirstOrDefault();
|
|
|
if (fileInfo.FILE_PATH.StartsWith("http://"))
|
|
|
{
|
|
|
var fileStream = await InnerGetDownloadFile(fileInfo.FILE_PATH, taskPKId, batchNo);
|
|
|
|
|
|
result = new FileStreamResult(fileStream, "application/octet-stream") { FileDownloadName = fileInfo.FILE_NAME };
|
|
|
}
|
|
|
else if (System.IO.File.Exists(fileInfo.FILE_PATH))
|
|
|
{
|
|
|
result = new FileStreamResult(new FileStream(fileInfo.FILE_PATH, FileMode.Open), "application/octet-stream") { FileDownloadName = fileInfo.FILE_NAME };
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 异步下载文件
|
|
|
/// <summary>
|
|
|
/// 异步下载文件
|
|
|
/// </summary>
|
|
|
/// <param name="fileUrl">文件请求URL</param>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="batchNo">批次号</param>
|
|
|
/// <returns>返回文件流</returns>
|
|
|
private async Task<Stream> InnerGetDownloadFile(string fileUrl,string taskPKId,string batchNo)
|
|
|
{
|
|
|
Stream stream = null;
|
|
|
try
|
|
|
{
|
|
|
DateTime bDate = DateTime.Now;
|
|
|
|
|
|
stream = await fileUrl.GetAsStreamAsync();
|
|
|
|
|
|
DateTime eDate = DateTime.Now;
|
|
|
TimeSpan ts = eDate.Subtract(bDate);
|
|
|
var timeDiff = ts.TotalMilliseconds;
|
|
|
|
|
|
_logger.LogInformation("批次={no} url={url} 请求完成,耗时:{timeDiff}ms.", batchNo, fileUrl, timeDiff);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
_logger.LogInformation("批次={no} url={url} 下载文件异常, 结果{msg}", batchNo, fileUrl, ex.Message);
|
|
|
|
|
|
throw Oops.Bah($"{nameof(InnerGetDownloadFile)}下载文件异常", ex.Message);
|
|
|
}
|
|
|
|
|
|
return stream;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 正本附件批量打印
|
|
|
/// <summary>
|
|
|
/// 正本附件批量打印
|
|
|
/// </summary>
|
|
|
/// <param name="PKIds">任务主键数组</param>
|
|
|
/// <returns>返回文件流</returns>
|
|
|
[HttpPost("/TaskManage/PrintBatch")]
|
|
|
public async Task<IActionResult> PrintBatch(string[] PKIds)
|
|
|
{
|
|
|
FileStreamResult result = null;
|
|
|
/*
|
|
|
1、通过任务主键获取所有的文件列表。只合并PDF文件,其他的文件不处理。
|
|
|
2、创建临时文件存放目录。
|
|
|
3、如果是http://开头的文档,需要使用下载文件,并变更为本地文件
|
|
|
4、PDF合成所有文件。
|
|
|
5、写入下载记录表。
|
|
|
6、返回文件流。
|
|
|
*/
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var fileList = _taskBaseInfoRepository.EntityContext.Queryable<TaskBaseInfo>()
|
|
|
.InnerJoin<TaskFileInfo>((tsk, file) => tsk.PK_ID == file.TASK_PKID)
|
|
|
.Where((tsk, file) => PKIds.Contains(tsk.PK_ID) && file.FILE_TYPE.Equals(".pdf"))
|
|
|
.Select((tsk, file) => new { tsk = tsk, file = file }).ToList();
|
|
|
|
|
|
var calcList = fileList.GroupBy(t => t.tsk.PK_ID)
|
|
|
.Select(a =>
|
|
|
{
|
|
|
var currList = a.ToList();
|
|
|
|
|
|
return new
|
|
|
{
|
|
|
tsk = currList.FirstOrDefault().tsk,
|
|
|
clist = a.Select(x => x.file).ToList()
|
|
|
};
|
|
|
}).OrderByDescending(t => t.tsk.CreatedTime).ToList();
|
|
|
|
|
|
var pdfList = calcList.SelectMany(t => t.clist).Select((t, idx) => new
|
|
|
{
|
|
|
Idx = idx,
|
|
|
file = t
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
if (pdfList.Count == 0)
|
|
|
throw Oops.Oh($"没有可以合并的PDF文件");
|
|
|
|
|
|
string filePath = string.Empty;
|
|
|
string tempFileName = IDGen.NextID().ToString();
|
|
|
|
|
|
var opt = App.GetOptions<TempFileOptions>().Path;
|
|
|
|
|
|
filePath = $"{Path.Combine(App.WebHostEnvironment.WebRootPath, opt)}\\TempPDFMerge\\";//服务器路径
|
|
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
|
|
{
|
|
|
filePath = filePath.Replace("\\", "/");
|
|
|
}
|
|
|
|
|
|
//预先创建目录
|
|
|
if (!Directory.Exists(filePath))
|
|
|
{
|
|
|
Directory.CreateDirectory(filePath);
|
|
|
}
|
|
|
|
|
|
var mergePdfPath = Path.Combine(filePath, $"{tempFileName}.pdf");
|
|
|
|
|
|
/*
|
|
|
Document document = null;
|
|
|
PdfCopy copy = null;
|
|
|
|
|
|
pdfList.ForEach(t => {
|
|
|
if(t.Idx == 0)
|
|
|
{
|
|
|
if(t.file.FILE_PATH.IndexOf("http://") >=0)
|
|
|
{
|
|
|
//var dw = InnerRemoteDownFile(t.file.FILE_PATH).GetAwaiter().GetResult();
|
|
|
|
|
|
WebClient wc = new WebClient();
|
|
|
wc.DownloadFile(t.file.FILE_PATH, Path.Combine(filePath, $"{tempFileName}abc.pdf"));
|
|
|
|
|
|
//document = new Document(new PdfReader(dw).GetPageSize(1));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
document = new Document(new PdfReader(t.file.FILE_PATH).GetPageSize(1));
|
|
|
}
|
|
|
|
|
|
copy = new PdfCopy(document, new FileStream(mergePdfPath, FileMode.Create));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
PdfReader reader = null;
|
|
|
|
|
|
if (t.file.FILE_PATH.IndexOf("http://") >= 0)
|
|
|
{
|
|
|
var dw = InnerRemoteDownFile(t.file.FILE_PATH).GetAwaiter().GetResult();
|
|
|
|
|
|
reader = new PdfReader(dw);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
reader = new PdfReader(t.file.FILE_PATH);
|
|
|
}
|
|
|
|
|
|
int n = reader.NumberOfPages;
|
|
|
for (int j = 1; j <= n; j++)
|
|
|
{
|
|
|
document.NewPage();
|
|
|
PdfImportedPage page = copy.GetImportedPage(reader, j);
|
|
|
copy.AddPage(page);
|
|
|
}
|
|
|
reader.Close();
|
|
|
}
|
|
|
});
|
|
|
|
|
|
document.Close();
|
|
|
*/
|
|
|
|
|
|
result = new FileStreamResult(new FileStream(mergePdfPath, FileMode.Open), "application/octet-stream") { FileDownloadName = $"{tempFileName}.pdf" };
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"LARA提单纸登记异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下载文件
|
|
|
private async Task<Stream> InnerRemoteDownFile(string filePath)
|
|
|
{
|
|
|
using (HttpClient client = new HttpClient())
|
|
|
{
|
|
|
HttpResponseMessage response = await client.GetAsync(filePath);
|
|
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
|
{
|
|
|
System.Net.Http.HttpContent content = response.Content;
|
|
|
var contentStream = await content.ReadAsStreamAsync(); // get the actual content stream
|
|
|
return contentStream;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
throw new FileNotFoundException($"{filePath} 文件下载失败");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 接收换船
|
|
|
/// <summary>
|
|
|
/// 接收换船
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/AcceptChangeShip")]
|
|
|
public async Task<TaskManageOrderResultDto> AcceptChangeShip([FromQuery]string taskPKId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.TELEX_NOTICE.ToString() || taskInfo.TASK_TYPE != TaskBusiTypeEnum.SEAWAYBILL_DOWN.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.TELEX_NOTICE.GetDescription()}、{TaskBusiTypeEnum.SEAWAYBILL_DOWN.GetDescription()},不能转发邮件");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
|
|
|
var userMail = _djyUserMailAccountRepository.AsQueryable().First(x => x.CreatedUserId == orderInfo.CreatedUserId);
|
|
|
|
|
|
|
|
|
if (userMail == null || string.IsNullOrWhiteSpace(userMail.SmtpServer) || userMail.SmtpPort == 0)
|
|
|
{
|
|
|
Oops.Oh($"发件邮箱未配置,或者配置不完整");
|
|
|
}
|
|
|
|
|
|
string emailSubject = string.Empty;
|
|
|
string emailBody = string.Empty;
|
|
|
|
|
|
//var sendResult = await MailSendHelper.SendMail(userMail, emailSubject, emailBody, toMail);
|
|
|
|
|
|
//if (!sendResult.Key)
|
|
|
//{
|
|
|
// Oops.Oh(sendResult.Value);
|
|
|
//}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取发送下货纸异常,{0}", ex.Message);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 取消换船
|
|
|
/// <summary>
|
|
|
/// 取消换船
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/AcceptCancelChangeShip")]
|
|
|
public async Task<TaskManageOrderResultDto> AcceptCancelChangeShip([FromQuery] string taskPKId)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.TELEX_NOTICE.ToString() || taskInfo.TASK_TYPE != TaskBusiTypeEnum.SEAWAYBILL_DOWN.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.TELEX_NOTICE.GetDescription()}、{TaskBusiTypeEnum.SEAWAYBILL_DOWN.GetDescription()},不能转发邮件");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
|
|
|
var userMail = _djyUserMailAccountRepository.AsQueryable().First(x => x.CreatedUserId == orderInfo.CreatedUserId);
|
|
|
|
|
|
|
|
|
if (userMail == null || string.IsNullOrWhiteSpace(userMail.SmtpServer) || userMail.SmtpPort == 0)
|
|
|
{
|
|
|
Oops.Oh($"发件邮箱未配置,或者配置不完整");
|
|
|
}
|
|
|
|
|
|
string emailSubject = string.Empty;
|
|
|
string emailBody = string.Empty;
|
|
|
|
|
|
//var sendResult = await MailSendHelper.SendMail(userMail, emailSubject, emailBody, toMail);
|
|
|
|
|
|
//if (!sendResult.Key)
|
|
|
//{
|
|
|
// Oops.Oh(sendResult.Value);
|
|
|
//}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取发送下货纸异常,{0}", ex.Message);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 转发电放邮件
|
|
|
/// <summary>
|
|
|
/// 转发电放邮件
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="toMail">指定邮件地址</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/SendTelexEmail")]
|
|
|
public async Task<TaskManageOrderResultDto> SendTelexEmail([FromQuery] string taskPKId, [FromQuery] string toMail)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.TELEX_NOTICE.ToString() || taskInfo.TASK_TYPE != TaskBusiTypeEnum.SEAWAYBILL_DOWN.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.TELEX_NOTICE.GetDescription()}、{TaskBusiTypeEnum.SEAWAYBILL_DOWN.GetDescription()},不能转发邮件");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
|
|
|
var userMail = _djyUserMailAccountRepository.AsQueryable().First(x => x.CreatedUserId == orderInfo.CreatedUserId);
|
|
|
|
|
|
|
|
|
if (userMail == null || string.IsNullOrWhiteSpace(userMail.SmtpServer) || userMail.SmtpPort == 0)
|
|
|
{
|
|
|
Oops.Oh($"发件邮箱未配置,或者配置不完整");
|
|
|
}
|
|
|
|
|
|
string emailSubject = string.Empty;
|
|
|
string emailBody = string.Empty;
|
|
|
|
|
|
var sendResult = await MailSendHelper.SendMail(userMail, emailSubject, emailBody, toMail);
|
|
|
|
|
|
if (!sendResult.Key)
|
|
|
{
|
|
|
Oops.Oh(sendResult.Value);
|
|
|
}
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取发送下货纸异常,{0}", ex.Message);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 发送下货纸
|
|
|
/// <summary>
|
|
|
/// 发送下货纸
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <param name="fileRole">文件功能 (9原始)</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/SendShippingOrder")]
|
|
|
public async Task<TaskManageOrderResultDto> SendShippingOrder([FromQuery] string taskPKId, [FromQuery] string fileRole = "9")
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
|
|
|
/*
|
|
|
1、查询任务关联的订舱信息。
|
|
|
2、触发下货纸发送。
|
|
|
3、发送成功更新任务状态为成功。
|
|
|
4、查看用户公司是否配置了反馈地址,如果有配置则触发反馈推送,否则显示反馈失败提示。
|
|
|
5、触发扣费
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if(taskInfo.TASK_TYPE != TaskBusiTypeEnum.SHIPPING_ORDER.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SHIPPING_ORDER.GetDescription()},不能发送下货纸");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if (orderInfo == null)
|
|
|
Oops.Oh($"订舱信息获取失败");
|
|
|
|
|
|
//推送下货纸业务
|
|
|
var rtn = await XiahuozhiHelpler.Send(orderInfo.Id, fileRole);
|
|
|
|
|
|
if (!rtn.Key)
|
|
|
{
|
|
|
throw Oops.Bah($"发送失败:{rtn.Value}");
|
|
|
}
|
|
|
|
|
|
//订舱状态写入
|
|
|
await SaveBookingStatus(orderInfo.Id, "sta_xhz", "下货纸");
|
|
|
|
|
|
taskInfo.STATUS = TaskStatusEnum.Complete.ToString();
|
|
|
taskInfo.STATUS_NAME = TaskStatusEnum.Complete.GetDescription();
|
|
|
|
|
|
taskInfo.COMPLETE_DATE = DateTime.Now;
|
|
|
taskInfo.COMPLETE_DEAL = TaskCompleteDealEnum.MANUAL.ToString();
|
|
|
taskInfo.COMPLETE_DEAL_NAME = TaskCompleteDealEnum.MANUAL.GetDescription();
|
|
|
|
|
|
taskInfo.UpdatedTime = DateTime.Now;
|
|
|
taskInfo.UpdatedUserId = UserManager.UserId;
|
|
|
taskInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
//更新任务表
|
|
|
await _taskBaseInfoRepository.AsUpdateable(taskInfo).UpdateColumns(it => new
|
|
|
{
|
|
|
it.STATUS,
|
|
|
it.STATUS_NAME,
|
|
|
it.COMPLETE_DATE,
|
|
|
it.COMPLETE_DEAL,
|
|
|
it.COMPLETE_DEAL_NAME,
|
|
|
it.UpdatedTime,
|
|
|
it.UpdatedUserId,
|
|
|
it.UpdatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
await InnerChargeFeeShippingOrder(taskInfo);
|
|
|
|
|
|
//反馈用户(这里预留,主要考虑是否通过用户配置确定是否需要推送回执)
|
|
|
await FeedbackXiaHuoZhi("");
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"发送下货纸异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 更新订舱的状态
|
|
|
/// <summary>
|
|
|
/// 更新订舱的状态
|
|
|
/// </summary>
|
|
|
/// <param name="bookingId">订舱主键</param>
|
|
|
/// <param name="code">状态代码</param>
|
|
|
/// <param name="name">状态名称</param>
|
|
|
/// <returns></returns>
|
|
|
private async Task SaveBookingStatus(long bookingId, string code, string name)
|
|
|
{
|
|
|
var bookSta = _bookingStatusRepository.FirstOrDefault(x => x.BookingId == bookingId && x.StaCode == code);
|
|
|
|
|
|
if (bookSta == null)
|
|
|
{
|
|
|
//记录状态
|
|
|
bookSta = new BookingStatus();
|
|
|
bookSta.BookingId = bookingId;
|
|
|
bookSta.StaCode = code;
|
|
|
bookSta.StaName = name;
|
|
|
bookSta.StaTime = DateTime.Now;
|
|
|
await _bookingStatusRepository.InsertAsync(bookSta);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bookSta.StaTime = DateTime.Now;
|
|
|
await _bookingStatusRepository.UpdateAsync(bookSta);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 扣费
|
|
|
/// <summary>
|
|
|
/// 扣费
|
|
|
/// </summary>
|
|
|
/// <param name="taskBaseInfo">任务信息</param>
|
|
|
/// <param name="isCharge">是否执行扣费 true-执行扣费 false-不执行扣费(主要是符合扣费条件但是由于超时没有得到准确回执)</param>
|
|
|
/// <returns>返回回执</returns>
|
|
|
private async Task<TaskManageOrderResultDto> InnerChargeFeeShippingOrder(TaskBaseInfo taskBaseInfo, bool isCharge = true)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto { succ = false };
|
|
|
try
|
|
|
{
|
|
|
decimal balance = 0;
|
|
|
decimal price = 0;
|
|
|
decimal total = 0;
|
|
|
|
|
|
TaskChargesHisInfo model = new TaskChargesHisInfo
|
|
|
{
|
|
|
PK_ID = IDGen.NextID().ToString(),
|
|
|
TASK_ID = taskBaseInfo.PK_ID,
|
|
|
BEFORE_BALANCE = balance,
|
|
|
PRICE = price,
|
|
|
BUSI_TYPE = "21",
|
|
|
BUSI_TYPE_NAME = String.Empty,
|
|
|
SEND_TYPE = "1001",
|
|
|
SEND_TYPE_NAME = String.Empty,
|
|
|
REMARK = "下货纸",
|
|
|
QTY = 1,
|
|
|
TOTAL_AMOUNT = total,
|
|
|
};
|
|
|
|
|
|
if (!isCharge)
|
|
|
{
|
|
|
model.STATUS = TaskChargeStatusEnum.UNKNOW_RESULT.ToString();
|
|
|
model.STATUS_NAME = TaskChargeStatusEnum.UNKNOW_RESULT.GetDescription();
|
|
|
}
|
|
|
|
|
|
//写入记录
|
|
|
await _taskChargesHisInfoRepository.InsertAsync(model);
|
|
|
|
|
|
result.succ = false;
|
|
|
result.msg = "扣费失败";
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
result.succ = false;
|
|
|
result.msg = ex.Message;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取订舱详情
|
|
|
/// <summary>
|
|
|
/// 获取订舱详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetBookingOrderInfo")]
|
|
|
public async Task<TaskBookingOrderDto> GetBookingOrderInfo([FromQuery]string taskPKId)
|
|
|
{
|
|
|
TaskBookingOrderDto model = new TaskBookingOrderDto();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
if(orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
|
|
|
var contaList = await _bookingOrderContaRepository.AsQueryable().Where(x => x.BILLID == orderInfo.Id).ToListAsync();
|
|
|
|
|
|
//获取集装箱的主键
|
|
|
var ctnArg = contaList.Select(t => t.Id).ToArray();
|
|
|
|
|
|
//查询集装箱所有的货物信息
|
|
|
var cargoList = await _bookingOrderContaCargoRepository.AsQueryable()
|
|
|
.Where(x => ctnArg.Contains(x.CTNID.Value)).ToListAsync();
|
|
|
|
|
|
_logger.LogInformation("批次={no} 提取货物明细完成 数量={total}", batchNo, cargoList.Count);
|
|
|
|
|
|
if (cargoList.Count > 0)
|
|
|
{
|
|
|
model.ContaList = contaList.GroupJoin(cargoList, l => l.Id, r => r.CTNID, (l, r) => {
|
|
|
var currList = r.ToList();
|
|
|
|
|
|
if (currList.Count > 0)
|
|
|
{
|
|
|
var info = l.Adapt<TaskBookingOrderContaDto>();
|
|
|
info.CargoList = currList.Adapt<List<TaskBookingOrderCargoDto>>();
|
|
|
|
|
|
return info;
|
|
|
}
|
|
|
|
|
|
return l.Adapt<TaskBookingOrderContaDto>();
|
|
|
|
|
|
}).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
model.ContaList = contaList.Adapt<List<TaskBookingOrderContaDto>>();
|
|
|
}
|
|
|
|
|
|
//任务
|
|
|
model.TaskBaseInfo = taskInfo.Adapt<TaskBaseInfoDto>();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取订舱详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 下货纸反馈
|
|
|
/// <summary>
|
|
|
/// 下货纸反馈
|
|
|
/// </summary>
|
|
|
/// <param name="bsno"></param>
|
|
|
/// <returns></returns>
|
|
|
private async Task FeedbackXiaHuoZhi(string bsno)
|
|
|
{
|
|
|
/*
|
|
|
var para = commonData.ParamValues.AsNoTracking().FirstOrDefault(x => x.CompId == compid && x.ParaCode == "XHZ_FEEDBACK_URL");
|
|
|
if (para == null || string.IsNullOrEmpty(para.ItemCode))
|
|
|
{
|
|
|
msg = "下货纸反馈地址未配置";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var feedbask = new BackgroundTaskCommon();
|
|
|
feedbask.GID = Guid.NewGuid().ToString();
|
|
|
feedbask.Status = BackgroundTaskCommon.StatusCreate;
|
|
|
feedbask.Type = BackgroundTaskCommon.TypeHttpFeedback;
|
|
|
feedbask.CreateTime = DateTime.Now;
|
|
|
feedbask.ParamData = JsonConvert.SerializeObject(new
|
|
|
{
|
|
|
url = para.ItemCode,
|
|
|
method = "POST",
|
|
|
json = JsonConvert.SerializeObject(new
|
|
|
{
|
|
|
bsno,
|
|
|
status
|
|
|
})
|
|
|
});
|
|
|
commonData.BackgroundTaskCommon.Add(feedbask);
|
|
|
|
|
|
msg = "成功";
|
|
|
return true;
|
|
|
*/
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取航次账单详情
|
|
|
/// <summary>
|
|
|
/// 获取航次账单详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetInvoiceBillInfo")]
|
|
|
public async Task<TaskInvoiceBillBaseInfo> GetInvoiceBillInfo([FromQuery] string taskPKId)
|
|
|
{
|
|
|
TaskInvoiceBillBaseInfo model = new TaskInvoiceBillBaseInfo();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if(taskInfo.TASK_TYPE != TaskBusiTypeEnum.INVOICE_BILL_MAIL.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.INVOICE_BILL_MAIL.GetDescription()}");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
|
|
|
if (orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model.BookingOrder = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
}
|
|
|
|
|
|
//获取文件
|
|
|
var fileList = _taskFileInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.TaskFile = fileList.Adapt<List<TaskManageOrderFileInfo>>();
|
|
|
|
|
|
var feeList = _taskBillFeeDetailInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.FeeList = feeList.Where(t => t.IS_TOTAL == 0).Select(t=>t.Adapt<TaskInvoiceBillFeeDto>()).ToList();
|
|
|
|
|
|
var totalUSD = feeList.FirstOrDefault(t => t.IS_TOTAL == 1 && t.FEE_NAME == "TotalUSD" && t.CURRENCY == "USD");
|
|
|
|
|
|
model.TotalAmountUSD = totalUSD != null ? totalUSD.TOTAL_AMOUNT : 0;
|
|
|
|
|
|
var totalCNY = feeList.FirstOrDefault(t => t.IS_TOTAL == 1 && t.FEE_NAME == "TotalCNY" && t.CURRENCY == "CNY");
|
|
|
|
|
|
model.TotalAmountCNY = totalCNY != null ? totalCNY.TOTAL_AMOUNT : 0;
|
|
|
|
|
|
model.InvoiceBillSendList = new List<TaskInvoiceBillFileHis>();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取获取航次账单详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取单票账单详情
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetTaskPerBillInfo")]
|
|
|
public async Task<TaskPerBillResultInfo> GetTaskPerBillInfo([FromQuery] string taskPKId)
|
|
|
{
|
|
|
TaskPerBillResultInfo model = new TaskPerBillResultInfo();
|
|
|
|
|
|
string batchNo = IDGen.NextID().ToString();
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.PER_BILL.ToString())
|
|
|
Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.PER_BILL.GetDescription()}");
|
|
|
|
|
|
var orderInfo = _bookingOrderRepository.AsQueryable()
|
|
|
.First(t => t.Id == long.Parse(taskInfo.BOOK_ORDER_NO));
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
|
|
|
var perBillInfo = _taskPerBillBaseInfoRepository.AsQueryable().First(t => t.TASK_PKID == taskInfo.PK_ID);
|
|
|
|
|
|
if (perBillInfo == null)
|
|
|
Oops.Oh($"单票账单不存在");
|
|
|
|
|
|
model.TaskPerBillBaseInfoDto = perBillInfo.Adapt<TaskPerBillBaseInfoDto>();
|
|
|
|
|
|
if (orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model.BookingOrder = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
}
|
|
|
|
|
|
//获取文件
|
|
|
var fileList = _taskFileInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.TaskFile = fileList.Adapt<List<TaskManageOrderFileInfo>>();
|
|
|
|
|
|
var feeList = _taskBillFeeDetailInfoRepository.AsQueryable().Where(t => t.TASK_PKID == taskInfo.PK_ID).ToList();
|
|
|
|
|
|
model.FeeList = feeList.Where(t => t.IS_TOTAL == 0).Select(t => t.Adapt<TaskPerBillFeeDto>()).ToList();
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取获取单票账单详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取提单纸登记记录
|
|
|
/// </summary>
|
|
|
/// <param name="querySearch">查询条件</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/GetLaraPaperRecordPage")]
|
|
|
public async Task<SqlSugarPagedList<LaraPaperRecordDto>> GetLaraPaperRecordPageAsync(QueryTaskManageBaseDto querySearch)
|
|
|
{
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
//这里因为返回给前端的台账数据是DTO,所以这里排序时候需要转换成Entity对应的字段
|
|
|
if (!string.IsNullOrWhiteSpace(querySearch.SortField))
|
|
|
entityOrderCol = MapsterExtHelper.GetAdaptProperty<LaraPaperRecordDto, TaskLARAPaperInfo>(querySearch.SortField);
|
|
|
|
|
|
var entities = await _taskLARAPaperInfoRepository.AsQueryable()
|
|
|
.OrderBy(entityOrderCol + (querySearch.descSort ? " asc " : " desc "))
|
|
|
.ToPagedListAsync(querySearch.PageNo, pageSize: querySearch.PageSize);
|
|
|
|
|
|
|
|
|
return entities.Adapt<SqlSugarPagedList<LaraPaperRecordDto>>();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 导出LARA提单纸登记记录
|
|
|
/// </summary>
|
|
|
/// <param name="sortField">排序字段</param>
|
|
|
/// <param name="pageNo">当前页码</param>
|
|
|
/// <param name="pageSize">页码容量</param>
|
|
|
/// <param name="descSort">排序方法,默认降序</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/LaraPaperRecordExport")]
|
|
|
public async Task<IActionResult> LaraPaperRecordExport([FromQuery] string sortField,[FromQuery] int pageNo = 1, [FromQuery] int pageSize = 30, [FromQuery] bool descSort = true)
|
|
|
{
|
|
|
QueryTaskManageBaseDto querySearch = new QueryTaskManageBaseDto
|
|
|
{
|
|
|
SortField = sortField,
|
|
|
PageNo = pageNo,
|
|
|
PageSize = pageSize,
|
|
|
descSort = descSort
|
|
|
};
|
|
|
|
|
|
string entityOrderCol = "CreatedTime";
|
|
|
|
|
|
var entities = await _taskLARAPaperInfoRepository.AsQueryable()
|
|
|
.OrderBy(entityOrderCol + (querySearch.descSort ? " asc " : " desc "))
|
|
|
.ToPagedListAsync(querySearch.PageNo, pageSize: querySearch.PageSize);
|
|
|
|
|
|
if(entities.Items.Count() == 0)
|
|
|
{
|
|
|
throw Oops.Oh($"没有可以导出的数据");
|
|
|
}
|
|
|
|
|
|
var list = entities.Items.Adapt<List<LaraPaperRecordDto>>();
|
|
|
|
|
|
//导出Excel文件流
|
|
|
var ms = ExportXlsLaraPaperRecord(list);
|
|
|
|
|
|
return new FileStreamResult(ms, "application/vnd.ms-excel") { FileDownloadName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}_LaraPaperRecord.xls" };
|
|
|
}
|
|
|
|
|
|
#region 导出提单纸登记记录生成Excel
|
|
|
/// <summary>
|
|
|
/// 导出提单纸登记记录生成Excel
|
|
|
/// </summary>
|
|
|
/// <param name="list">LARA提单纸登记记录列表</param>
|
|
|
/// <returns>返回Excel文件流</returns>
|
|
|
private MemoryStream ExportXlsLaraPaperRecord(List<LaraPaperRecordDto> list)
|
|
|
{
|
|
|
MemoryStream ms = new MemoryStream();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
IWorkbook workbook = new HSSFWorkbook();
|
|
|
ISheet sheet = workbook.CreateSheet();
|
|
|
IRow headerRow = sheet.CreateRow(0);
|
|
|
var headers = new string[] { "打印日期", "提单号", "Paper Number From", "Paper Number To", "Sum", "签单方式", "LARA登记时间", "LARA登记人" };
|
|
|
for (int i = 0; i < headers.Length; i++)
|
|
|
{
|
|
|
string head = headers[i];
|
|
|
var headCell = headerRow.CreateCell(i);
|
|
|
headCell.SetCellValue(head);
|
|
|
}
|
|
|
|
|
|
int rowIndex = 1;
|
|
|
foreach (var item in list)
|
|
|
{
|
|
|
IRow dataRow = sheet.CreateRow(rowIndex);
|
|
|
var cell0 = dataRow.CreateCell(0);
|
|
|
cell0.SetCellValue(item.OriginalDownTime);
|
|
|
|
|
|
var cell1 = dataRow.CreateCell(1);
|
|
|
cell1.SetCellValue(item.MBLNo);
|
|
|
|
|
|
var cell2 = dataRow.CreateCell(2);
|
|
|
cell2.SetCellValue(item.NumberFrom);
|
|
|
|
|
|
var cell3 = dataRow.CreateCell(3);
|
|
|
cell3.SetCellValue(item.NumberTo);
|
|
|
|
|
|
var cell4 = dataRow.CreateCell(4);
|
|
|
cell4.SetCellValue(item.PageSum);
|
|
|
|
|
|
var cell5 = dataRow.CreateCell(5);
|
|
|
cell5.SetCellValue(item.IssueTypeName);
|
|
|
|
|
|
var cell6 = dataRow.CreateCell(6);
|
|
|
cell6.SetCellValue(item.CreatedTime);
|
|
|
|
|
|
var cell7 = dataRow.CreateCell(7);
|
|
|
cell7.SetCellValue(item.CreatedUserName);
|
|
|
|
|
|
rowIndex++;
|
|
|
}
|
|
|
|
|
|
workbook.Write(ms, true);
|
|
|
ms.Flush();
|
|
|
ms.Position = 0;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"导出提单纸登记记录生成Excel异常,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return ms;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 保存SI信息
|
|
|
/// <summary>
|
|
|
/// 保存SI信息
|
|
|
/// </summary>
|
|
|
/// <param name="model">订舱信息</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpPost("/TaskManage/SaveBookingSI")]
|
|
|
public async Task<TaskManageOrderResultDto> SaveBookingSI(TaskBookingOrderDto model)
|
|
|
{
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
/*
|
|
|
1、比较原始数据和修改数据内容,记录差异。
|
|
|
2、更新订舱主信息和集装箱信息。
|
|
|
3、写入本地历史记录表。
|
|
|
*/
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == model.TaskBaseInfo.PKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}");
|
|
|
|
|
|
var bookOrderList = _bookingOrderRepository.EntityContext.Queryable<BookingOrder>()
|
|
|
.InnerJoin<BookingCtn>((bk, ctn) => bk.Id == ctn.BILLID)
|
|
|
.Where((bk, ctn) => bk.Id == long.Parse(taskInfo.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList();
|
|
|
|
|
|
var orderInfo = bookOrderList.FirstOrDefault().bk;
|
|
|
|
|
|
//比对差异,更新订舱主信息
|
|
|
var mdBookingOrder = model.Adapt<BookingOrder>();
|
|
|
|
|
|
await _bookingOrderRepository.AsUpdateable(mdBookingOrder).IgnoreColumns(it => new
|
|
|
{
|
|
|
it.ParentId,
|
|
|
it.TenantId,
|
|
|
it.CreatedTime,
|
|
|
it.CreatedUserId,
|
|
|
it.CreatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
var ctnlist = await _bookingOrderContaRepository.AsQueryable().Where(x => x.BILLID == mdBookingOrder.Id).ToListAsync();
|
|
|
|
|
|
//更新订舱的集装箱信息
|
|
|
ctnlist.ForEach(async ctn => {
|
|
|
|
|
|
await _bookingOrderContaRepository.AsUpdateable(ctn).IgnoreColumns(it => new
|
|
|
{
|
|
|
it.TenantId,
|
|
|
it.CreatedTime,
|
|
|
it.CreatedUserId,
|
|
|
it.CreatedUserName
|
|
|
}).ExecuteCommandAsync();
|
|
|
});
|
|
|
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"保存SI信息,{0}", ex.Message);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 获取SI反馈信息
|
|
|
/// <summary>
|
|
|
/// 获取SI反馈信息
|
|
|
/// </summary>
|
|
|
/// <param name="taskPKId">任务主键</param>
|
|
|
/// <returns>返回结果</returns>
|
|
|
[HttpGet("/TaskManage/GetSIFeedBackInfo")]
|
|
|
public async Task<TaskSIFeedBackResultDto> GetSIFeedBackInfo(string taskPKId)
|
|
|
{
|
|
|
TaskSIFeedBackResultDto model = new TaskSIFeedBackResultDto();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var taskInfo = _taskBaseInfoRepository.AsQueryable().First(t => t.PK_ID == taskPKId);
|
|
|
|
|
|
if (taskInfo == null)
|
|
|
throw Oops.Oh($"任务信息获取失败");
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskInfo.BOOK_ORDER_NO))
|
|
|
throw Oops.Oh($"任务信息的订舱主键不存在");
|
|
|
|
|
|
if (taskInfo.TASK_TYPE != TaskBusiTypeEnum.SI_FEEDBACK.ToString())
|
|
|
throw Oops.Oh($"当前任务类型不是{TaskBusiTypeEnum.SI_FEEDBACK.GetDescription()}");
|
|
|
|
|
|
|
|
|
var bookOrderList = _bookingOrderRepository.EntityContext.Queryable<BookingOrder>()
|
|
|
.InnerJoin<BookingCtn>((bk, ctn) => bk.Id == ctn.BILLID)
|
|
|
.Where((bk, ctn) => bk.Id == long.Parse(taskInfo.BOOK_ORDER_NO) && bk.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((bk, ctn) => new { bk = bk, ctn = ctn }).ToList();
|
|
|
|
|
|
var orderInfo = bookOrderList.FirstOrDefault().bk;
|
|
|
|
|
|
model.TaskId = taskInfo.PK_ID;
|
|
|
|
|
|
var siFeedBackList = _taskSIFeedBackInfoRepository.EntityContext.Queryable<TaskSIFeedBackInfo>()
|
|
|
.InnerJoin<TaskSIFeedBackContaInfo>((si, ctn) => si.PK_ID == ctn.P_PKID)
|
|
|
.Where((si, ctn) => si.TASK_PKID == model.TaskId && si.TenantId == UserManager.TENANT_ID)
|
|
|
.Select((si, ctn) => new { si = si, ctn = ctn }).ToList();
|
|
|
|
|
|
if (siFeedBackList.Count == 0)
|
|
|
Oops.Oh($"SI反馈信息不存在");
|
|
|
|
|
|
var siFeedBackInfo = siFeedBackList.FirstOrDefault().si;
|
|
|
|
|
|
var resultInfo = siFeedBackInfo.Adapt<TaskSIFeedBackResultBusiDto>();
|
|
|
|
|
|
resultInfo.ContaList = siFeedBackList.Select(t => t.ctn.Adapt<TaskSIFeedBackResultContaDto>()).ToList();
|
|
|
|
|
|
model.BusiInfo = resultInfo;
|
|
|
|
|
|
if (orderInfo != null)
|
|
|
{
|
|
|
//订舱
|
|
|
model.BookingOrder = orderInfo.Adapt<TaskBookingOrderDto>();
|
|
|
}
|
|
|
|
|
|
//进行数据比对确认差异字段KEY
|
|
|
var mainDiff = await InnerCompareMainInfoDiff(orderInfo, siFeedBackInfo);
|
|
|
|
|
|
model.SICompareOrderKeyList = mainDiff;
|
|
|
|
|
|
var contaDiff = await InnerCompareContaInfoDiff(bookOrderList.Select(t=>t.ctn).ToList(),
|
|
|
siFeedBackList.Select(t=>t.ctn).ToList());
|
|
|
|
|
|
model.SICompareOrderContaKeyList = contaDiff;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"获取获取单票账单详情异常,{0}", ex.Message);
|
|
|
}
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
private List<TaskCompareResultDto> InnerCompare(object srcModel,object targetModel)
|
|
|
{
|
|
|
List<TaskCompareResultDto> list = new List<TaskCompareResultDto>();
|
|
|
|
|
|
if(srcModel is BookingOrder)
|
|
|
{
|
|
|
var srcBK = (BookingOrder)srcModel;
|
|
|
var targetBK = (BookingOrder)targetModel;
|
|
|
|
|
|
var bookProps = typeof(BookingOrder).GetProperties();
|
|
|
|
|
|
list = bookProps.Select(prop =>
|
|
|
{
|
|
|
var bk1Val = prop.GetValue(srcBK);
|
|
|
var bk2Val = prop.GetValue(targetBK);
|
|
|
|
|
|
if (prop.PropertyType == typeof(string))
|
|
|
{
|
|
|
string st1 = (bk1Val as string).AdjustString();
|
|
|
string st2 = (bk2Val as string).AdjustString();
|
|
|
|
|
|
if (!st1.Equals(st2))
|
|
|
{
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = false, ValType = prop.PropertyType };
|
|
|
}
|
|
|
else if (prop.PropertyType == typeof(int?))
|
|
|
{
|
|
|
var dt1 = bk1Val as int?;
|
|
|
var dt2 = bk2Val as int?;
|
|
|
|
|
|
if (!dt1.Equals(dt2))
|
|
|
{
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
else if (prop.PropertyType == typeof(decimal?))
|
|
|
{
|
|
|
var dt1 = bk1Val as decimal?;
|
|
|
var dt2 = bk2Val as decimal?;
|
|
|
|
|
|
if (!dt1.Equals(dt2))
|
|
|
{
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
}
|
|
|
|
|
|
if (!bk1Val.Equals(bk2Val))
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = true, ValType = prop.PropertyType };
|
|
|
|
|
|
|
|
|
return new TaskCompareResultDto { Code = prop.Name, SrcVal = bk1Val, TargetVal = bk2Val, IsDiff = false, ValType = prop.PropertyType };
|
|
|
}).ToList();
|
|
|
}
|
|
|
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
#region 比较主信息
|
|
|
/// <summary>
|
|
|
/// 比较主信息
|
|
|
/// </summary>
|
|
|
/// <param name="bookingOrder">订舱详情</param>
|
|
|
/// <param name="taskSIFeedBackInfo">SI反馈详情</param>
|
|
|
/// <returns>返回差异</returns>
|
|
|
private async Task<List<string>> InnerCompareMainInfoDiff(BookingOrder bookingOrder, TaskSIFeedBackInfo taskSIFeedBackInfo)
|
|
|
{
|
|
|
List<string> resultList = new List<string>();
|
|
|
|
|
|
//需要比对的字段
|
|
|
var compareField = new string[] { "SHIPPER", "CONSIGNEE", "NOTIFYPARTY", "MARKS", "DESCRIPTION", "BLFRT", "SERVICE", "ISSUETYPE", "PORTLOAD", "PORTDISCHARGE",
|
|
|
"TRANSPORT", "DESTINATION", "PKGS", "KGS", "CBM", "KINDPKGS", "THIRDPAYADDR" };
|
|
|
|
|
|
var bookProps = typeof(BookingOrder).GetProperties();
|
|
|
var feedProps = typeof(TaskSIFeedBackInfo).GetProperties();
|
|
|
|
|
|
resultList = bookProps.GroupJoin(feedProps, l => l.Name.ToUpper(),
|
|
|
r => r.Name.ToUpper(), (l, r) =>
|
|
|
{
|
|
|
if (compareField.Any(x => x.Equals(l.Name, StringComparison.OrdinalIgnoreCase)))
|
|
|
{
|
|
|
var currList = r.ToList();
|
|
|
|
|
|
if (currList.Count > 0)
|
|
|
{
|
|
|
var si = r.FirstOrDefault();
|
|
|
|
|
|
var bkVal = l.GetValue(bookingOrder);
|
|
|
var siVal = si.GetValue(taskSIFeedBackInfo);
|
|
|
|
|
|
if (l.PropertyType == typeof(string))
|
|
|
{
|
|
|
string st1 = (bkVal as string).AdjustString();
|
|
|
string st2 = (siVal as string).AdjustString();
|
|
|
|
|
|
if (!st1.Equals(st2))
|
|
|
{
|
|
|
return l.Name.ToUpper();
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
else if (l.PropertyType == typeof(int?))
|
|
|
{
|
|
|
var dt1 = bkVal as int?;
|
|
|
var dt2 = siVal as int?;
|
|
|
|
|
|
if (!dt1.Equals(dt2))
|
|
|
{
|
|
|
return l.Name.ToUpper();
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
else if (l.PropertyType == typeof(decimal?))
|
|
|
{
|
|
|
var dt1 = bkVal as decimal?;
|
|
|
var dt2 = siVal as decimal?;
|
|
|
|
|
|
if (!dt1.Equals(dt2))
|
|
|
{
|
|
|
return l.Name.ToUpper();
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
}
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
}).Where(t => !string.IsNullOrWhiteSpace(t)).ToList();
|
|
|
|
|
|
return resultList;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 比较箱信息
|
|
|
/// <summary>
|
|
|
/// 比较箱信息
|
|
|
/// </summary>
|
|
|
/// <param name="bookContaList">订舱箱信息</param>
|
|
|
/// <param name="siContaList">SI反馈箱信息</param>
|
|
|
/// <returns>返回差异</returns>
|
|
|
private async Task<List<string>> InnerCompareContaInfoDiff(List<BookingCtn> bookContaList,List<TaskSIFeedBackContaInfo> siContaList)
|
|
|
{
|
|
|
List<string> resultList = new List<string>();
|
|
|
|
|
|
var bookProps = typeof(BookingCtn).GetProperties();
|
|
|
var feedProps = typeof(TaskSIFeedBackContaInfo).GetProperties();
|
|
|
|
|
|
resultList = siContaList.GroupJoin(bookContaList, l => l.CONTA_NO, r => r.CNTRNO, (l, r) =>
|
|
|
{
|
|
|
var currList = r.ToList();
|
|
|
|
|
|
if (currList.Count > 0)
|
|
|
{
|
|
|
var bkCtn = currList.FirstOrDefault();
|
|
|
|
|
|
if (!l.KGS.Equals(bkCtn.KGS)
|
|
|
|| !l.PKGS.Equals(bkCtn.PKGS)
|
|
|
|| !l.SEAL_NO.Equals(bkCtn.SEALNO)
|
|
|
|| !l.CONTA_TYPE.Equals(bkCtn.CTNALL)
|
|
|
|| !l.CBM.Equals(bkCtn.CBM))
|
|
|
{
|
|
|
return l.CONTA_NO;
|
|
|
}
|
|
|
|
|
|
return String.Empty;
|
|
|
}
|
|
|
|
|
|
return l.CONTA_NO;
|
|
|
}).Where(t => !string.IsNullOrWhiteSpace(t)).ToList();
|
|
|
|
|
|
return resultList;
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
|
|
|
#region 样本业务提取帮助类
|
|
|
/// <summary>
|
|
|
/// 样本业务提取帮助类
|
|
|
/// </summary>
|
|
|
public static class DraftPaperExtension
|
|
|
{
|
|
|
public static int GetPageNum(this string Name)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(Name))
|
|
|
return 0;
|
|
|
|
|
|
string s = Regex.Replace(Name.Substring(Name.LastIndexOf('-') + 1), "\\.[a-zA-Z]+", "");
|
|
|
|
|
|
return int.Parse(s);
|
|
|
}
|
|
|
catch(Exception ex)
|
|
|
{
|
|
|
throw Oops.Bah($"文件名{0} 取页数异常,{1}", Name, ex.Message);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 整理文本数据
|
|
|
public static class CompareObjExtension
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 整理文本数据
|
|
|
/// </summary>
|
|
|
/// <param name="str">文本</param>
|
|
|
/// <returns></returns>
|
|
|
public static string AdjustString(this string str)
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace(str))
|
|
|
return str;
|
|
|
|
|
|
var rtn = str.Replace("\r\n", "\n").Trim();
|
|
|
if (rtn.EndsWith("\n"))
|
|
|
{
|
|
|
rtn = rtn.Substring(0, rtn.Length - 1);
|
|
|
}
|
|
|
|
|
|
return rtn;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
}
|