|
|
|
|
using Furion;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DistributedIDGenerator;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.AspNetCore.StaticFiles.Infrastructure;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Myshipping.Application.ConfigOption;
|
|
|
|
|
using Myshipping.Application.Entity;
|
|
|
|
|
using Myshipping.Core;
|
|
|
|
|
using Myshipping.Core.Service;
|
|
|
|
|
using NPOI.Util;
|
|
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Myshipping.Application.Service.TaskManagePlat
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 任务分享链接服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
[ApiDescriptionSettings("Application", Name = "TaskManageShareLink", Order = 10)]
|
|
|
|
|
public class TaskManageShareLinkService : ITaskManageShareLinkService, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private readonly ISysCacheService _cache;
|
|
|
|
|
private readonly ILogger<TaskManageShareLinkService> _logger;
|
|
|
|
|
private readonly SqlSugarRepository<TaskShareLinkInfo> _taskShareLinkInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskShareLinkDynamicDataInfo> _taskShareLinkDynamicDataInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskBaseInfo> _taskBaseRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationInfo> _taskRollingNominationInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationDispatchInfo> _taskRollingNominationDispatchInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationShipInfo> _taskRollingNominationShipInfoRepository;
|
|
|
|
|
private readonly SqlSugarRepository<TaskRollingNominationDetailInfo> _taskRollingNominationDetailInfoRepository;
|
|
|
|
|
|
|
|
|
|
private const string SHARE_LINK_CACHE_KEY_TEMPLATE = "ShareLinkKeyIncrement";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TaskManageShareLinkService(ISysCacheService cache, ILogger<TaskManageShareLinkService> logger,
|
|
|
|
|
SqlSugarRepository<TaskShareLinkInfo> taskShareLinkInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskShareLinkDynamicDataInfo> taskShareLinkDynamicDataInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskBaseInfo> taskBaseRepository,
|
|
|
|
|
SqlSugarRepository<TaskRollingNominationInfo> taskRollingNominationInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskRollingNominationDispatchInfo> taskRollingNominationDispatchInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskRollingNominationShipInfo> taskRollingNominationShipInfoRepository,
|
|
|
|
|
SqlSugarRepository<TaskRollingNominationDetailInfo> taskRollingNominationDetailInfoRepository)
|
|
|
|
|
{
|
|
|
|
|
_cache = cache;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
|
|
|
|
_taskShareLinkInfoRepository = taskShareLinkInfoRepository;
|
|
|
|
|
_taskShareLinkDynamicDataInfoRepository = taskShareLinkDynamicDataInfoRepository;
|
|
|
|
|
_taskBaseRepository = taskBaseRepository;
|
|
|
|
|
_taskRollingNominationInfoRepository = taskRollingNominationInfoRepository;
|
|
|
|
|
_taskRollingNominationDispatchInfoRepository = taskRollingNominationDispatchInfoRepository;
|
|
|
|
|
_taskRollingNominationShipInfoRepository = taskRollingNominationShipInfoRepository;
|
|
|
|
|
_taskRollingNominationDetailInfoRepository = taskRollingNominationDetailInfoRepository;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 生成访问链接
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成访问链接
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="model">创建分享链接请求</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpPost("/TaskManageShareLink/CreateShareLink")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> CreateShareLink([FromBody] ShareLinkRequestDto model)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1、判断当前businessId是否有STATUS=ACTIVE的记录,如果有记录不允许重复分享。
|
|
|
|
|
2、创建分享记录,并生成动态数据(预甩需要生成免责声明)
|
|
|
|
|
3、判断有效期是否小于等于当前日期,如果是不能生成分享。
|
|
|
|
|
4、创建完记录后,把生成后的SHARE_LINK_KEY写入redis并用expireDate作为失效日期。
|
|
|
|
|
5、返回SHARE_LINK_KEY。
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string shareKey = string.Empty;
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.businessId))
|
|
|
|
|
throw Oops.Oh($"业务ID不能为空");
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.taskType))
|
|
|
|
|
throw Oops.Oh($"任务类型不能为空");
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.businessType))
|
|
|
|
|
throw Oops.Oh($"业务类型不能为空");
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.expireDate))
|
|
|
|
|
throw Oops.Oh($"失效时间不能为空");
|
|
|
|
|
|
|
|
|
|
DateTime expireDateTime = DateTime.MinValue;
|
|
|
|
|
DateTime nowDate = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
if(!DateTime.TryParse(model.expireDate, out expireDateTime))
|
|
|
|
|
throw Oops.Oh($"失效时间格式错误,请参考格式yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
|
|
|
|
if(expireDateTime <= DateTime.Now)
|
|
|
|
|
throw Oops.Oh($"失效时间不能早于或等于当前时间");
|
|
|
|
|
|
|
|
|
|
if (!model.businessType.Equals("NOMI_DISPATCH", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"当前只支持预甩调度分享");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var nomDispatchList = _taskRollingNominationDispatchInfoRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.InnerJoin<TaskRollingNominationDetailInfo>((dispatch,detail) => dispatch.DETAIL_ID == detail.PK_ID)
|
|
|
|
|
.Where((dispatch,detail) => dispatch.BATCH_ID == model.businessId
|
|
|
|
|
&& detail.IsDeleted == false && dispatch.IsDeleted == false)
|
|
|
|
|
.Select((dispatch, detail) => new { Detail = detail, Dispatch = dispatch }).ToList();
|
|
|
|
|
|
|
|
|
|
if (nomDispatchList.Count == 0)
|
|
|
|
|
throw Oops.Oh($"预甩调度获取详情失败,已删除或不存在");
|
|
|
|
|
|
|
|
|
|
if (nomDispatchList.Any(a => !string.IsNullOrWhiteSpace(a.Dispatch.USER_OPINION)))
|
|
|
|
|
throw Oops.Oh($"当前预甩调度已有用户反馈,不能创建分享");
|
|
|
|
|
|
|
|
|
|
var shareInfo = _taskShareLinkInfoRepository.AsQueryable()
|
|
|
|
|
.First(a => a.BUSI_ID == model.businessId && a.TASK_TYPE == model.taskType
|
|
|
|
|
&& a.STATUS == TaskShareLinkStatusEnum.ACTIVE.ToString() && a.IsDeleted == false);
|
|
|
|
|
|
|
|
|
|
if (!model.isRenew)
|
|
|
|
|
{
|
|
|
|
|
if (shareInfo != null)
|
|
|
|
|
{
|
|
|
|
|
throw Oops.Oh($"已有分享记录不能重复生成");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
shareInfo.IsDeleted = true;
|
|
|
|
|
shareInfo.UpdatedTime = nowDate;
|
|
|
|
|
shareInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
shareInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskShareLinkInfoRepository.AsUpdateable(shareInfo)
|
|
|
|
|
.UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.IsDeleted,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskShareLinkInfo taskShareLinkInfo = new TaskShareLinkInfo {
|
|
|
|
|
EXPIRE_DATE = expireDateTime,
|
|
|
|
|
STATUS = TaskShareLinkStatusEnum.ACTIVE.ToString(),
|
|
|
|
|
BUSI_ID = model.businessId,
|
|
|
|
|
IS_MANUAL = false,
|
|
|
|
|
CreatedTime = nowDate,
|
|
|
|
|
UpdatedTime = nowDate,
|
|
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
|
|
TASK_TYPE = model.taskType,
|
|
|
|
|
IS_USER_FEEDBACK = model.isUserFeedBack,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//写入分享记录
|
|
|
|
|
await _taskShareLinkInfoRepository.InsertAsync(taskShareLinkInfo);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"写入分享记录表完成,id={taskShareLinkInfo.Id}");
|
|
|
|
|
|
|
|
|
|
var autoIncrementKey = RedisHelper.IncrBy(SHARE_LINK_CACHE_KEY_TEMPLATE);
|
|
|
|
|
//生成分享KEY
|
|
|
|
|
SuperShortLinkHelper codeHelper = new SuperShortLinkHelper();
|
|
|
|
|
shareKey = codeHelper.Confuse(autoIncrementKey);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"生成分享KEY完成,id={taskShareLinkInfo.Id} shareKey={shareKey}");
|
|
|
|
|
|
|
|
|
|
//更新分享表
|
|
|
|
|
var shareEntity = _taskShareLinkInfoRepository.AsQueryable().First(a => a.Id == taskShareLinkInfo.Id);
|
|
|
|
|
|
|
|
|
|
string taskId = nomDispatchList.FirstOrDefault().Dispatch.TASK_ID;
|
|
|
|
|
|
|
|
|
|
var taskInfo = _taskBaseRepository.AsQueryable().First(a => a.PK_ID == taskId);
|
|
|
|
|
|
|
|
|
|
//写入redis缓存
|
|
|
|
|
string cacheVal = $"{taskShareLinkInfo.Id}_{taskInfo.TASK_TYPE}_{taskInfo.TASK_NO}_{nomDispatchList.FirstOrDefault().Detail.SHIPMENT}_{taskInfo.TenantName}_{model.expireDate}";
|
|
|
|
|
|
|
|
|
|
var expireTimeSpan = expireDateTime.Subtract(nowDate).Duration();
|
|
|
|
|
//new DateTimeOffset(expireDateTime).ToUnixTimeSeconds();
|
|
|
|
|
|
|
|
|
|
if (_cache.Exists(shareKey))
|
|
|
|
|
{
|
|
|
|
|
shareEntity.SHARE_LINK_KEY = shareKey;
|
|
|
|
|
shareEntity.STATUS = "REPEAT_KEY";//REPEAT_KEY-重复KEY被取消
|
|
|
|
|
shareEntity.INCREMENT_KEY = autoIncrementKey;
|
|
|
|
|
|
|
|
|
|
await _taskShareLinkInfoRepository.AsUpdateable(shareEntity)
|
|
|
|
|
.UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.SHARE_LINK_KEY,
|
|
|
|
|
it.STATUS,
|
|
|
|
|
it.INCREMENT_KEY
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"分享KEY存在重复终止生成分享(cache),id={taskShareLinkInfo.Id} shareKey={shareKey} cache={_cache.Get<string>(shareKey)}");
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"已有分享记录不能重复生成");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
shareEntity.SHARE_LINK_KEY = shareKey;
|
|
|
|
|
shareEntity.INCREMENT_KEY = autoIncrementKey;
|
|
|
|
|
|
|
|
|
|
await _taskShareLinkInfoRepository.AsUpdateable(shareEntity)
|
|
|
|
|
.UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.SHARE_LINK_KEY,
|
|
|
|
|
it.INCREMENT_KEY
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
await _cache.SetTimeoutAsync(shareKey, cacheVal, expireTimeSpan);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"分享KEY写入cache完成,id={taskShareLinkInfo.Id} shareKey={shareKey} cache={cacheVal}");
|
|
|
|
|
|
|
|
|
|
//这里生成动态数据
|
|
|
|
|
if (taskInfo.TASK_BASE_TYPE == TaskBaseTypeEnum.ROLLING_NOMINATION.ToString() ||
|
|
|
|
|
taskInfo.TASK_BASE_TYPE == TaskBaseTypeEnum.TRANSFER_NOMINATION.ToString())
|
|
|
|
|
{
|
|
|
|
|
var shareTxt = GenerateShareDynamicData(expireDateTime, taskInfo.TenantName);
|
|
|
|
|
|
|
|
|
|
TaskShareLinkDynamicDataInfo dataInfo = new TaskShareLinkDynamicDataInfo {
|
|
|
|
|
SHARE_ID = shareEntity.Id,
|
|
|
|
|
DATA_TYPE = "DISCLAIMERS",
|
|
|
|
|
DATA_MSG = shareTxt,
|
|
|
|
|
DATA_MSG_TYPE = "HTML",
|
|
|
|
|
CreatedTime = nowDate,
|
|
|
|
|
UpdatedTime = nowDate,
|
|
|
|
|
CreatedUserId = UserManager.UserId,
|
|
|
|
|
CreatedUserName = UserManager.Name,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await _taskShareLinkDynamicDataInfoRepository.InsertAsync(dataInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.ext = shareKey;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"获取预甩详情异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 取消访问链接
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 取消访问链接
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="busiId">访问链接业务主键</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageShareLink/CancelShareLink")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> CancelShareLink(string busiId)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var shareInfo = _taskShareLinkInfoRepository.AsQueryable()
|
|
|
|
|
.First(a => a.BUSI_ID == busiId && a.IsDeleted == false);
|
|
|
|
|
|
|
|
|
|
if(shareInfo == null)
|
|
|
|
|
throw Oops.Oh($"分享链接不存在或已删除");
|
|
|
|
|
|
|
|
|
|
var statusArg = new string[] {
|
|
|
|
|
RollingNominationDispatchStatusEnum.COMPLETE.ToString(),
|
|
|
|
|
RollingNominationDispatchStatusEnum.EXPIRE.ToString(),
|
|
|
|
|
RollingNominationDispatchStatusEnum.CANCEL.ToString()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(statusArg.Any(a=>a.Equals(shareInfo.STATUS,StringComparison.OrdinalIgnoreCase)))
|
|
|
|
|
throw Oops.Oh($"分享链接状态{shareInfo.STATUS} 不需要取消");
|
|
|
|
|
|
|
|
|
|
shareInfo.STATUS = RollingNominationDispatchStatusEnum.CANCEL.ToString();
|
|
|
|
|
shareInfo.UpdatedTime = DateTime.Now;
|
|
|
|
|
shareInfo.UpdatedUserId = UserManager.UserId;
|
|
|
|
|
shareInfo.UpdatedUserName = UserManager.Name;
|
|
|
|
|
|
|
|
|
|
await _taskShareLinkInfoRepository.AsUpdateable(shareInfo)
|
|
|
|
|
.UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.STATUS,
|
|
|
|
|
it.UpdatedTime,
|
|
|
|
|
it.UpdatedUserId,
|
|
|
|
|
it.UpdatedUserName
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
if (_cache.Exists(shareInfo.SHARE_LINK_KEY))
|
|
|
|
|
await _cache.DelAsync(shareInfo.SHARE_LINK_KEY);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"取消访问链接异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"取消访问链接异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 校验成访问链接
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 校验成访问链接
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Url">请求链接</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[HttpGet("/TaskManageShareLink/ValidateShareLink")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> ValidateShareLink(string Url)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 访问链接
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 访问链接
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Url">请求链接</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
public async Task<TaskManageOrderResultDto> QueryShareLink(string Url)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取分享详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取分享详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="shareKey">链接分享KEY</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[AllowAnonymous,HttpGet("/TaskManageShareLink/GetInfo")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> GetInfo([FromQuery] string shareKey)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1、先验证shareKey是否在缓存存在,存在继续,不存在返回错误。
|
|
|
|
|
2、获取分享的表记录,根据任务类型调取不同的接口,返回详情数据。
|
|
|
|
|
3、查看是否存在分享的声明内容,如果存在,需要返回。
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(shareKey))
|
|
|
|
|
throw Oops.Oh($"链接分享KEY不能为空");
|
|
|
|
|
|
|
|
|
|
if (!_cache.Exists(shareKey))
|
|
|
|
|
throw Oops.Oh($"链接分享已失效");
|
|
|
|
|
|
|
|
|
|
var cacheVal = _cache.Get<string>(shareKey);
|
|
|
|
|
|
|
|
|
|
long shareId = long.Parse(cacheVal.Split(new char[]{ '_'}).FirstOrDefault());
|
|
|
|
|
|
|
|
|
|
var shareEntity = _taskShareLinkInfoRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.First(a => a.Id == shareId);
|
|
|
|
|
|
|
|
|
|
if (shareEntity == null)
|
|
|
|
|
throw Oops.Oh($"链接分享不存在");
|
|
|
|
|
|
|
|
|
|
var showModel = await InnerGetInfo(shareEntity.BUSI_ID);
|
|
|
|
|
|
|
|
|
|
var list = _taskShareLinkDynamicDataInfoRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.Where(a => a.SHARE_ID == shareEntity.Id).ToList();
|
|
|
|
|
|
|
|
|
|
if (list.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var dyData = list.FirstOrDefault(a => a.DATA_TYPE == "DISCLAIMERS");
|
|
|
|
|
|
|
|
|
|
if (dyData != null)
|
|
|
|
|
showModel.DynamicData = dyData.DATA_MSG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.ext = showModel;
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"获取分享详情异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"获取分享详情异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 生成分享的动态数据
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成分享的动态数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="expireDateTime">最后失效时间</param>
|
|
|
|
|
/// <param name="TenantCompanyName">企业名称</param>
|
|
|
|
|
/// <returns>返回填充模板后文本</returns>
|
|
|
|
|
private string GenerateShareDynamicData(DateTime expireDateTime,string TenantCompanyName)
|
|
|
|
|
{
|
|
|
|
|
string result = string.Empty;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//调取模板
|
|
|
|
|
string templatePath = App.Configuration["EmailTemplateFilePath"];
|
|
|
|
|
|
|
|
|
|
var opt = App.GetOptions<BookingAttachOptions>();
|
|
|
|
|
var dirAbs = opt.basePath;
|
|
|
|
|
if (string.IsNullOrEmpty(dirAbs))
|
|
|
|
|
{
|
|
|
|
|
dirAbs = App.WebHostEnvironment.WebRootPath;
|
|
|
|
|
}
|
|
|
|
|
templatePath = $"{dirAbs}{templatePath}\\NominationShareTemplate.html";
|
|
|
|
|
|
|
|
|
|
result = File.ReadAllText(templatePath);
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(result))
|
|
|
|
|
{
|
|
|
|
|
if (Regex.IsMatch(result, "#DeadLineDate#"))
|
|
|
|
|
result = Regex.Replace(result, "#DeadLineDate#", expireDateTime.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
|
|
|
|
|
if (Regex.IsMatch(result, "#TenantCompanyName#"))
|
|
|
|
|
result = Regex.Replace(result, "#TenantCompanyName#", TenantCompanyName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"生成分享动态数据异常,原因:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 获取预甩详情
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取预甩详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dispatchBatchId">预甩货详调度批次号</param>
|
|
|
|
|
/// <returns>返回详情</returns>
|
|
|
|
|
private async Task<TaskRollingNominationShowDto> InnerGetInfo(string dispatchBatchId)
|
|
|
|
|
{
|
|
|
|
|
TaskRollingNominationShowDto model = null;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
List<string> rollingPlanList = new List<string>();
|
|
|
|
|
|
|
|
|
|
var list = _taskRollingNominationInfoRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.InnerJoin<TaskRollingNominationDispatchInfo>((nom, dispatch) => nom.PK_ID == dispatch.NOM_ID)
|
|
|
|
|
.InnerJoin<TaskRollingNominationDetailInfo>((nom, dispatch, detail)
|
|
|
|
|
=> dispatch.DETAIL_ID == detail.PK_ID)
|
|
|
|
|
.Where((nom, dispatch, detail) => dispatch.BATCH_ID == dispatchBatchId
|
|
|
|
|
&& nom.IsDeleted == false && detail.IsDeleted == false && dispatch.IsDeleted == false)
|
|
|
|
|
.Select((nom, dispatch, detail) => new { Nom = nom, Detail = detail, Dispatch = dispatch }).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var rollModel = list.FirstOrDefault().Nom;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(rollModel.PLAN_TXT))
|
|
|
|
|
{
|
|
|
|
|
rollingPlanList = rollModel.PLAN_TXT.Split("\\n").ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model = new TaskRollingNominationShowDto
|
|
|
|
|
{
|
|
|
|
|
PlanType = rollModel.PLAN_TYPE,
|
|
|
|
|
CarrierId = rollModel.CARRIERID,
|
|
|
|
|
Carrier = rollModel.CARRIER,
|
|
|
|
|
ConfirmDeadLine = rollModel.CONFIRM_DEAD_LINE,
|
|
|
|
|
CreateTime = rollModel.READ_CREATE_TIME,
|
|
|
|
|
RollingTouchDoubleRollRemark = rollModel.ROLL_DOUBLE_REMARK,
|
|
|
|
|
LoadDetailList = new List<TaskRollingNominationShipDetailShowDto>(),
|
|
|
|
|
RollingPlanList = rollingPlanList,
|
|
|
|
|
PreBillList = new List<TaskRollingNominationShipPreBillShowDto>()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var shipList = _taskRollingNominationShipInfoRepository.AsQueryable().Filter(null, true)
|
|
|
|
|
.Where(a => a.NOM_ID == rollModel.PK_ID && a.IsDeleted == false).ToList();
|
|
|
|
|
|
|
|
|
|
var fromEntity = shipList.Where(a =>
|
|
|
|
|
a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase)).ToList();
|
|
|
|
|
|
|
|
|
|
if (fromEntity.Count > 0)
|
|
|
|
|
model.From = fromEntity.Select(p => p.Adapt<TaskRollingNominationShipDto>()).ToList();
|
|
|
|
|
|
|
|
|
|
var toEntity = shipList.Where(a => Regex.IsMatch(a.SHIP_TYPE, "To(\\s+[0-9]+)?"
|
|
|
|
|
, RegexOptions.IgnoreCase)).ToList();
|
|
|
|
|
|
|
|
|
|
if (toEntity.Count > 0)
|
|
|
|
|
model.To = toEntity.Select(p => p.Adapt<TaskRollingNominationShipDto>()).ToList();
|
|
|
|
|
|
|
|
|
|
List<TaskRollingNominationShipFromToDto> fromToList = new List<TaskRollingNominationShipFromToDto>();
|
|
|
|
|
|
|
|
|
|
//优先PORT关联FROM和TO,也有PORT为空的情况,这种就需要用Terminal来关联
|
|
|
|
|
if (model.From.Any(t => string.IsNullOrWhiteSpace(t.Port)))
|
|
|
|
|
{
|
|
|
|
|
//这里为了前端原船和换船做了根据Terminal对应
|
|
|
|
|
fromToList = model.From.GroupJoin(model.To, l => l.Terminal?.Trim(), r => r.Terminal?.Trim(), (l, r) =>
|
|
|
|
|
{
|
|
|
|
|
TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto();
|
|
|
|
|
|
|
|
|
|
dto.FromShip = l;
|
|
|
|
|
|
|
|
|
|
var currArg = r.ToList();
|
|
|
|
|
|
|
|
|
|
if (currArg.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
dto.ToShipList = currArg.Select((p, idx) =>
|
|
|
|
|
{
|
|
|
|
|
if (Regex.IsMatch(p.ShipType, "[0-9]+"))
|
|
|
|
|
return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p };
|
|
|
|
|
|
|
|
|
|
return new { SortNo = idx + 1, Obj = p };
|
|
|
|
|
}).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dto;
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//这里为了前端原船和换船做了根据PORT对应
|
|
|
|
|
fromToList = model.From.GroupJoin(model.To, l => l.Port?.Trim(), r => r.Port?.Trim(), (l, r) =>
|
|
|
|
|
{
|
|
|
|
|
TaskRollingNominationShipFromToDto dto = new TaskRollingNominationShipFromToDto();
|
|
|
|
|
|
|
|
|
|
dto.FromShip = l;
|
|
|
|
|
|
|
|
|
|
var currArg = r.ToList();
|
|
|
|
|
|
|
|
|
|
if (currArg.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
dto.ToShipList = currArg.Select((p, idx) =>
|
|
|
|
|
{
|
|
|
|
|
if (Regex.IsMatch(p.ShipType, "[0-9]+"))
|
|
|
|
|
return new { SortNo = int.Parse(Regex.Match(p.ShipType, "[0-9]+").Value), Obj = p };
|
|
|
|
|
|
|
|
|
|
return new { SortNo = idx + 1, Obj = p };
|
|
|
|
|
}).OrderBy(p => p.SortNo).Select(p => p.Obj).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dto;
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Tuple<string, int>> tuples = new List<Tuple<string, int>>();
|
|
|
|
|
|
|
|
|
|
model.LoadDetailList = list.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
|
|
|
|
|
|
|
|
|
|
model.FromToList = new List<TaskRollingNominationShipFromToDto>();
|
|
|
|
|
|
|
|
|
|
if (model.LoadDetailList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
model.TotalLoadCtnStat = string.Join(",", model.LoadDetailList.GroupBy(x => x.CtnAll)
|
|
|
|
|
.Select(x =>
|
|
|
|
|
$"{x.Key}*{x.Sum(t => t.CtnNum)}").ToArray());
|
|
|
|
|
|
|
|
|
|
string rollRegex = "Roll\\s+to\\s+\\w+\\s+\\w{3,}\\/\\w+,\\s?if\\s+cannot\\s+catch\\s?,\\s+roll\\s+to\\s+\\w{3,}\\s+next\\s+sailing";
|
|
|
|
|
string rollontoRegex = "Roll\\s+onto\\s+\\w{3,}\\s+\\w+,\\s+[0-9]+\\s+days\\s+delay\\.";
|
|
|
|
|
|
|
|
|
|
bool isSelectRoll = false;
|
|
|
|
|
bool isRoll = false;
|
|
|
|
|
bool isRollOnto = false;
|
|
|
|
|
|
|
|
|
|
model.LoadDetailList.ForEach(p =>
|
|
|
|
|
{
|
|
|
|
|
string vslCode = string.Empty;
|
|
|
|
|
string voyNo = string.Empty;
|
|
|
|
|
string strCode = string.Empty;
|
|
|
|
|
string strCode2 = string.Empty;
|
|
|
|
|
|
|
|
|
|
if (Regex.IsMatch(p.Status, rollRegex, RegexOptions.IgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
string currS = Regex.Match(p.Status, "(?<=Roll\\sto\\s\\w+\\s)\\w{3,}\\/\\w+(?=,)").Value;
|
|
|
|
|
vslCode = Regex.Split(currS, "\\/")[0]?.Trim();
|
|
|
|
|
voyNo = Regex.Split(currS, "\\/")[1]?.Trim();
|
|
|
|
|
|
|
|
|
|
strCode = Regex.Match(p.Status, "(?<=if\\scannot\\scatch\\s?,\\sroll\\sto\\s)\\w{3,}(?=\\s+next\\s+sailing)").Value?.Trim();
|
|
|
|
|
|
|
|
|
|
isSelectRoll = true;
|
|
|
|
|
}
|
|
|
|
|
else if (p.Status.Trim().Equals("roll", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
isRoll = true;
|
|
|
|
|
}
|
|
|
|
|
else if(Regex.IsMatch(p.Status, rollontoRegex, RegexOptions.IgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
vslCode = Regex.Match(p.Status, "(?<=Roll\\sonto\\s)\\w{3,}(?=\\s+\\w+,)").Value?.Trim();
|
|
|
|
|
|
|
|
|
|
isRollOnto = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < fromToList.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(fromToList[i].FromShip.Port))
|
|
|
|
|
{
|
|
|
|
|
if (fromToList[i].FromShip.Port.Equals(p.PlaceOfReceipt, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
var fromInfo = fromToList[i].FromShip.Adapt<TaskRollingNominationShipDto>();
|
|
|
|
|
|
|
|
|
|
List<TaskRollingNominationShipDto> toShipList = new List<TaskRollingNominationShipDto>();
|
|
|
|
|
|
|
|
|
|
if (isSelectRoll)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < fromToList[i].ToShipList.Count; j++)
|
|
|
|
|
{
|
|
|
|
|
if (fromToList[i].ToShipList[j].VslCode.Equals(vslCode, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
|
|
}
|
|
|
|
|
else if (fromToList[i].ToShipList[j].ShipString.Equals(strCode, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (isRoll)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < fromToList[i].ToShipList.Count; j++)
|
|
|
|
|
{
|
|
|
|
|
if (fromToList[i].ToShipList[j].Port.Equals(p.PlaceOfDelivery?.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (toShipList.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
if (fromToList[i].ToShipList.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
toShipList.Add(fromToList[i].ToShipList.FirstOrDefault().Adapt<TaskRollingNominationShipDto>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model.FromToList.Add(new TaskRollingNominationShipFromToDto
|
|
|
|
|
{
|
|
|
|
|
FromShip = fromInfo,
|
|
|
|
|
ToShipList = toShipList
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (fromToList[i].FromShip.Terminal.Contains(p.PlaceOfReceipt, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
var fromInfo = fromToList[i].FromShip.Adapt<TaskRollingNominationShipDto>();
|
|
|
|
|
|
|
|
|
|
List<TaskRollingNominationShipDto> toShipList = new List<TaskRollingNominationShipDto>();
|
|
|
|
|
|
|
|
|
|
if (isRollOnto)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < fromToList[i].ToShipList.Count; j++)
|
|
|
|
|
{
|
|
|
|
|
if (fromToList[i].ToShipList[j].VslCode.Equals(vslCode, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
toShipList.Add(fromToList[i].ToShipList[j].Adapt<TaskRollingNominationShipDto>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model.FromToList.Add(new TaskRollingNominationShipFromToDto
|
|
|
|
|
{
|
|
|
|
|
FromShip = fromInfo,
|
|
|
|
|
ToShipList = toShipList
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 推送分享链接反馈意见
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="model">推送分享链接反馈意见请求</param>
|
|
|
|
|
/// <returns>返回回执</returns>
|
|
|
|
|
[AllowAnonymous, HttpPost("/TaskManageShareLink/PushShareLinkFeedBack")]
|
|
|
|
|
public async Task<TaskManageOrderResultDto> PushShareLinkFeedBack(PushShareLinkFeedBackDto model)
|
|
|
|
|
{
|
|
|
|
|
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1、验证shareKey是否有效。
|
|
|
|
|
2、查看分享记录找到对应的预甩调度详情。
|
|
|
|
|
3、用户已经提交过意见的不能再发起
|
|
|
|
|
3、更新用户反馈意见。
|
|
|
|
|
4、返回成功
|
|
|
|
|
*/
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(model.shareKey))
|
|
|
|
|
throw Oops.Oh($"链接分享KEY不能为空");
|
|
|
|
|
|
|
|
|
|
if (!_cache.Exists(model.shareKey))
|
|
|
|
|
throw Oops.Oh($"链接分享已失效");
|
|
|
|
|
|
|
|
|
|
var shareEntity = _taskShareLinkInfoRepository.AsQueryable()
|
|
|
|
|
.First(a => a.SHARE_LINK_KEY == model.shareKey);
|
|
|
|
|
|
|
|
|
|
if (shareEntity == null)
|
|
|
|
|
throw Oops.Oh($"链接分享不存在");
|
|
|
|
|
|
|
|
|
|
if(shareEntity.STATUS != TaskShareLinkStatusEnum.ACTIVE.ToString())
|
|
|
|
|
{
|
|
|
|
|
if(shareEntity.STATUS != TaskShareLinkStatusEnum.COMPLETE.ToString())
|
|
|
|
|
throw Oops.Oh($"预甩通知用户已反馈,不能重复提交");
|
|
|
|
|
|
|
|
|
|
throw Oops.Oh($"分享链接已失效,请咨询操作重新获取");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
shareEntity.USER_OPINION = model.userOpinion;
|
|
|
|
|
shareEntity.USER_OPINION_TXT = model.userOpinionTxt;
|
|
|
|
|
shareEntity.CONFIRM_DATE = DateTime.Now;
|
|
|
|
|
shareEntity.IS_MANUAL = model.isManual;
|
|
|
|
|
|
|
|
|
|
await _taskShareLinkInfoRepository.AsUpdateable(shareEntity)
|
|
|
|
|
.UpdateColumns(it => new
|
|
|
|
|
{
|
|
|
|
|
it.USER_OPINION,
|
|
|
|
|
it.USER_OPINION_TXT,
|
|
|
|
|
it.CONFIRM_DATE,
|
|
|
|
|
it.IS_MANUAL,
|
|
|
|
|
}).ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
//需要回写预甩任务的
|
|
|
|
|
|
|
|
|
|
result.succ = true;
|
|
|
|
|
result.msg = "成功";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError($"推送分享链接反馈意见异常,原因:{ex.Message}");
|
|
|
|
|
|
|
|
|
|
result.succ = false;
|
|
|
|
|
result.msg = $"推送分享链接反馈意见异常,原因:{ex.Message}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|