You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookingHeChuan/Myshipping.Application/Service/TaskManagePlat/TaskManageShareLinkService.cs

598 lines
26 KiB
C#

using Furion;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
10 months ago
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
10 months ago
using Microsoft.Extensions.Logging;
using Myshipping.Application.ConfigOption;
10 months ago
using Myshipping.Application.Entity;
using Myshipping.Core;
using Myshipping.Core.Service;
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
{
10 months ago
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;
10 months ago
private const string SHARE_LINK_CACHE_KEY_TEMPLATE = "ShareLinkKeyIncrement";
10 months ago
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)
10 months ago
{
_cache = cache;
_logger = logger;
_taskShareLinkInfoRepository = taskShareLinkInfoRepository;
_taskShareLinkDynamicDataInfoRepository = taskShareLinkDynamicDataInfoRepository;
_taskBaseRepository = taskBaseRepository;
_taskRollingNominationInfoRepository = taskRollingNominationInfoRepository;
_taskRollingNominationDispatchInfoRepository = taskRollingNominationDispatchInfoRepository;
_taskRollingNominationShipInfoRepository = taskRollingNominationShipInfoRepository;
_taskRollingNominationDetailInfoRepository = taskRollingNominationDetailInfoRepository;
10 months ago
}
#region 生成访问链接
/// <summary>
/// 生成访问链接
/// </summary>
10 months ago
/// <param name="model">创建分享链接请求</param>
/// <returns>返回回执</returns>
10 months ago
[HttpPost("/TaskManageShareLink/CreateShareLink")]
public async Task<TaskManageOrderResultDto> CreateShareLink([FromBody] ShareLinkRequestDto model)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
10 months ago
/*
1businessIdSTATUS=ACTIVE
2
3
4SHARE_LINK_KEYredisexpireDate
5SHARE_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($"业务类型不能为空");
10 months ago
if (string.IsNullOrWhiteSpace(model.expireDate))
throw Oops.Oh($"失效时间不能为空");
DateTime expireDateTime = DateTime.MinValue;
DateTime nowDate = DateTime.Now;
10 months ago
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();
10 months ago
if (nomDispatchList.Count == 0)
throw Oops.Oh($"预甩调度获取详情失败,已删除或不存在");
if (nomDispatchList.Any(a => !string.IsNullOrWhiteSpace(a.Dispatch.USER_OPINION)))
throw Oops.Oh($"当前预甩调度已有用户反馈,不能创建分享");
10 months ago
var shareInfo = _taskShareLinkInfoRepository.AsQueryable()
.First(a => a.BUSI_ID == model.businessId && a.TASK_TYPE == model.taskType
&& a.STATUS == TaskShareLinkStatusEnum.ACTIVE.ToString() && a.IsDeleted == false);
10 months ago
if (!model.isRenew)
10 months ago
{
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();
10 months ago
}
TaskShareLinkInfo taskShareLinkInfo = new TaskShareLinkInfo {
EXPIRE_DATE = expireDateTime,
STATUS = TaskShareLinkStatusEnum.ACTIVE.ToString(),
10 months ago
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);
10 months ago
//生成分享KEY
SuperShortLinkHelper codeHelper = new SuperShortLinkHelper();
shareKey = codeHelper.Confuse(autoIncrementKey);
10 months ago
_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);
10 months ago
//写入redis缓存
string cacheVal = $"{taskShareLinkInfo.Id}_{taskInfo.TASK_TYPE}_{taskInfo.TASK_NO}_{nomDispatchList.FirstOrDefault().Detail.SHIPMENT}_{taskInfo.TenantName}_{model.expireDate}";
10 months ago
var expireTimeSpan = expireDateTime.Subtract(nowDate).Duration();
//new DateTimeOffset(expireDateTime).ToUnixTimeSeconds();
10 months ago
if (_cache.Exists(shareKey))
{
shareEntity.SHARE_LINK_KEY = shareKey;
shareEntity.STATUS = "REPEAT_KEY";//REPEAT_KEY-重复KEY被取消
shareEntity.INCREMENT_KEY = autoIncrementKey;
10 months ago
await _taskShareLinkInfoRepository.AsUpdateable(shareEntity)
.UpdateColumns(it => new
{
it.SHARE_LINK_KEY,
it.STATUS,
it.INCREMENT_KEY
10 months ago
}).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;
10 months ago
await _taskShareLinkInfoRepository.AsUpdateable(shareEntity)
.UpdateColumns(it => new
{
it.SHARE_LINK_KEY,
it.INCREMENT_KEY
10 months ago
}).ExecuteCommandAsync();
await _cache.SetTimeoutAsync(shareKey, cacheVal, expireTimeSpan);
10 months ago
_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);
}
10 months ago
}
result.succ = true;
result.ext = shareKey;
}
catch (Exception ex)
{
_logger.LogError($"获取预甩详情异常,原因:{ex.Message}");
result.succ = false;
result.msg = $"获取预甩详情异常,原因:{ex.Message}";
}
return result;
}
10 months ago
#endregion
10 months ago
#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;
}
10 months ago
#endregion
10 months ago
#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;
}
10 months ago
#endregion
10 months ago
#region 访问链接
/// <summary>
/// 访问链接
/// </summary>
/// <param name="Url">请求链接</param>
/// <returns>返回回执</returns>
public async Task<TaskManageOrderResultDto> QueryShareLink(string Url)
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
return result;
}
10 months ago
#endregion
#region 获取分享详情
/// <summary>
/// 获取分享详情
/// </summary>
/// <param name="shareKey">链接分享KEY</param>
/// <returns>返回回执</returns>
[AllowAnonymous,HttpGet("/TaskManageShareLink/GetInfo")]
public async Task<TaskManageOrderResultDto> GetInfo([FromQuery] string shareKey)
10 months ago
{
TaskManageOrderResultDto result = new TaskManageOrderResultDto();
/*
1shareKey
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}";
}
10 months ago
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.GROUP_INDX == 1 && !a.IsDeleted).ToList();
var fromEntity = shipList.FirstOrDefault(a =>
a.SHIP_TYPE.Equals("From", StringComparison.OrdinalIgnoreCase));
if (fromEntity != null)
model.From = fromEntity.Adapt<TaskRollingNominationShipDto>();
var toEntity = shipList.FirstOrDefault(a =>
a.SHIP_TYPE.Equals("To", StringComparison.OrdinalIgnoreCase));
if (toEntity != null)
model.To = toEntity.Adapt<TaskRollingNominationShipDto>();
List<Tuple<string, int>> tuples = new List<Tuple<string, int>>();
model.LoadDetailList = list.Select(a => a.Detail.Adapt<TaskRollingNominationShipDetailShowDto>()).ToList();
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());
}
}
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();
/*
1shareKey
2
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($"链接分享不存在");
shareEntity.USER_OPINION = model.userOpinion;
shareEntity.USER_OPINION_TXT = model.userOpinionTxt;
shareEntity.CONFIRM_DATE = DateTime.Now;
await _taskShareLinkInfoRepository.AsUpdateable(shareEntity)
.UpdateColumns(it => new
{
it.USER_OPINION,
it.USER_OPINION_TXT,
it.CONFIRM_DATE,
}).ExecuteCommandAsync();
result.succ = true;
result.msg = "成功";
}
catch (Exception ex)
{
_logger.LogError($"推送分享链接反馈意见异常,原因:{ex.Message}");
result.succ = false;
result.msg = $"推送分享链接反馈意见异常,原因:{ex.Message}";
}
return result;
}
}
}