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/BookingCustomerOrder/BookingCustomerOrderService.cs

1174 lines
47 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Furion;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.RemoteRequest.Extensions;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Myshipping.Application.ConfigOption;
using Myshipping.Application.Entity;
using Myshipping.Core;
using Myshipping.Core.Service;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Yitter.IdGenerator;
namespace Myshipping.Application
{
/// <summary>
/// 客户订舱
/// </summary>
[ApiDescriptionSettings("Application", Name = "BookingCustomerOrder", Order = 1)]
public class BookingCustomerOrderService : IDynamicApiController, ITransient
{
private const string StaLogCateAudit = "cust_audit";
private readonly SqlSugarRepository<BookingCustomerOrder> _rep;
private readonly SqlSugarRepository<BookingCtn> _repCtn;
private readonly ILogger<BookingOrderService> _logger;
private readonly ISysCacheService _cache;
private readonly SqlSugarRepository<BookingFile> _repFile;
private readonly SqlSugarRepository<BookingStatusLog> _repStatuslog;
private readonly SqlSugarRepository<BookingStatusLogDetail> _repStatuslogDetail;
private readonly SqlSugarRepository<BookingServiceItem> _repServiceItem;
private readonly SqlSugarRepository<BookingOrder> _repOrder;
private readonly SqlSugarRepository<BookingCustomerOrderTemplate> _repOrderTempl;
public BookingCustomerOrderService(SqlSugarRepository<BookingCustomerOrder> rep, SqlSugarRepository<BookingCtn> repCtn,
ILogger<BookingOrderService> logger, ISysCacheService cache, SqlSugarRepository<BookingFile> repFile,
SqlSugarRepository<BookingStatusLog> statuslog, SqlSugarRepository<BookingServiceItem> repServiceItem,
SqlSugarRepository<BookingOrder> repOrder, SqlSugarRepository<BookingStatusLogDetail> repStatuslogDetail,
SqlSugarRepository<BookingCustomerOrderTemplate> repOrderTempl)
{
this._logger = logger;
this._rep = rep;
this._repCtn = repCtn;
this._cache = cache;
this._repFile = repFile;
this._repStatuslog = statuslog;
this._repServiceItem = repServiceItem;
this._repOrder = repOrder;
this._repStatuslogDetail = repStatuslogDetail;
this._repOrderTempl = repOrderTempl;
}
#region 订舱草稿及附件
/// <summary>
/// 订舱草稿台账
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/PageData")]
public async Task<SqlSugarPagedList<BookingCustomerOrderListOutput>> PageData(BookingCustomerOrderQueryInput input)
{
var query = _rep.AsQueryable().Filter(null, true).Where(x => x.TenantId == UserManager.TENANT_ID)
.Where(x => !x.IsDeleted)
.WhereIF(!string.IsNullOrEmpty(input.BOOKINGNO), x => x.BOOKINGNO.Contains(input.BOOKINGNO))
.WhereIF(!string.IsNullOrEmpty(input.VESSEL), x => x.VESSEL.Contains(input.VESSEL))
.WhereIF(!string.IsNullOrEmpty(input.VOYNO), x => x.VOYNO.Contains(input.VOYNO))
.WhereIF(!string.IsNullOrEmpty(input.YARDID), x => x.YARDID == input.YARDID)
.WhereIF(!string.IsNullOrEmpty(input.YARD), x => x.YARD.Contains(input.YARD))
.WhereIF(!string.IsNullOrEmpty(input.PORTDISCHARGEID), x => x.PORTDISCHARGEID == input.PORTDISCHARGEID)
.WhereIF(!string.IsNullOrEmpty(input.PORTDISCHARGE), x => x.PORTDISCHARGE.Contains(input.PORTDISCHARGE))
.WhereIF(!string.IsNullOrEmpty(input.CARRIERID), x => x.CARRIERID == input.CARRIERID)
.WhereIF(!string.IsNullOrEmpty(input.CARRIER), x => x.CARRIER.Contains(input.CARRIER))
.WhereIF(!string.IsNullOrEmpty(input.BookingTenantName), x => x.BookingTenantName.Contains(input.BookingTenantName))
.WhereIF(input.ETDStart.HasValue, x => x.ETD >= input.ETDStart)
.WhereIF(input.ETDEnd.HasValue, x => x.ETD < input.ETDEnd.Value.Date.AddDays(1))
.WhereIF(input.CreatedTimeStart.HasValue, x => x.CreatedTime >= input.CreatedTimeStart)
.WhereIF(input.CreatedTimeEnd.HasValue, x => x.CreatedTime < input.CreatedTimeEnd.Value.Date.AddDays(1))
.WhereIF(input.UpdateTimeStart.HasValue, x => x.UpdatedTime >= input.UpdateTimeStart)
.WhereIF(input.UpdateTimeEnd.HasValue, x => x.UpdatedTime < input.UpdateTimeEnd.Value.Date.AddDays(1))
.WhereIF(input.BSStatusList != null && input.BSStatusList.Count > 0, x => input.BSStatusList.Contains(x.BSSTATUS))
;
if (!string.IsNullOrEmpty(input.SortField) || input.MultiSort == null || input.MultiSort.Count == 0)
{
query = query.OrderBy(PageInputOrder.OrderBuilder(input.SortField, input.DescSort));
}
else
{
query = query.OrderBy(PageInputOrder.MultiOrderBuilder(input.MultiSort));
}
var entities = await query.ToPagedListAsync(input.PageNo, input.PageSize);
var list = entities.Adapt<SqlSugarPagedList<BookingCustomerOrderListOutput>>();
//动态日志
var bkIdList = list.Items.Select(x => x.Id).ToList();
var staLogList = _repStatuslog.Where(x => bkIdList.Contains(x.BookingId.Value) && x.Category == StaLogCateAudit).ToList();
foreach (var item in list.Items)
{
item.LogList = staLogList.Where(x => x.BookingId == item.Id).OrderByDescending(x => x.OpTime).Adapt<List<BookingCustomerLogDto>>();
}
return list;
}
/// <summary>
/// 保存草稿数据
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/Save")]
public async Task<BookingCustomerOrderSaveOutput> Save(BookingCustomerOrderSaveInput input)
{
if (input == null)
{
throw Oops.Bah("请传入正常数据!");
}
var ms = JsonUtil.TrimFields(input);
if (!string.IsNullOrEmpty(ms))
{
throw Oops.Bah(ms);
}
BookingCustomerOrder entity = null;
List<BookingCtn> ctnList = new List<BookingCtn>();
if (input.Id == 0)
{
entity = input.Adapt<BookingCustomerOrder>();
if (string.IsNullOrEmpty(entity.VOYNO))
{
entity.VOYNO = entity.VOYNOINNER;
}
entity.BSSTATUS = "已录入";
entity.BOOKINGNO = $"BK{YitIdHelper.NextId()}";
await _rep.InsertAsync(entity);
}
else
{
entity = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == input.Id);
if (entity.BSSTATUS != "已录入" && entity.BSSTATUS != "已驳回")
{
throw Oops.Bah("当前状态不允许修改");
}
if (string.IsNullOrEmpty(entity.VOYNO))
{
entity.VOYNO = entity.VOYNOINNER;
}
entity = input.Adapt(entity);
await _rep.UpdateAsync(entity);
await _repCtn.DeleteAsync(x => x.BILLID == input.Id);
}
//箱信息保存
if (input.CtnList != null)
{
foreach (var item in input.CtnList)
{
var ctnentity = item.Adapt<BookingCtn>();
ctnentity.BILLID = entity.Id;
await _repCtn.InsertAsync(ctnentity);
ctnList.Add(ctnentity);
}
var groupList = input.CtnList.Where(x => x.CTNNUM > 0).GroupBy(c => c.CTNALL).Select(g => $"{g.Key}*{g.Sum(gg => gg.CTNNUM)}");
entity.CNTRTOTAL = string.Join(" / ", groupList);
}
else
{
entity.CNTRTOTAL = "";
}
await _rep.UpdateAsync(entity);
//服务项目
_repServiceItem.Delete(x => x.BookingId == entity.Id);
foreach (var item in input.ServiceItemList)
{
var bsi = item.Adapt<BookingServiceItem>();
bsi.Id = YitIdHelper.NextId();
bsi.BookingId = entity.Id;
await _repServiceItem.InsertAsync(bsi);
}
//文件
var dbFiles = _repFile.AsQueryable().Where(x => x.BookingId == entity.Id).ToList();
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = string.Empty;
if (string.IsNullOrEmpty(opt.basePath))
{
dirAbs = Path.Combine(App.WebHostEnvironment.WebRootPath, opt.relativePath);
}
else
{
dirAbs = Path.Combine(opt.basePath, opt.relativePath);
}
if (!Directory.Exists(dirAbs))
Directory.CreateDirectory(dirAbs);
//清除前端已删除的文件
if (input.Files != null && input.Files.Count() > 0)
{
var delIds = dbFiles.Where(x => !input.Files.Contains(x.Id)).Select(x => x.Id);
await _repFile.DeleteAsync(x => delIds.Contains(x.Id));
}
else
{
await _repFile.DeleteAsync(x => x.BookingId == entity.Id);
}
//临时文件转为正式文件
if (input.TempFileNames != null && input.TempFileNames.Count() > 0)
{
var optTempFile = App.GetOptions<TempFileOptions>().Path;
foreach (var tmpFile in input.TempFileNames)
{
var tempPath = Path.Combine(optTempFile, tmpFile);
if (File.Exists(tempPath))
{
var saveFileName = $"{DateTime.Now.Ticks}{Path.GetExtension(tmpFile)}";
var fileRelaPath = Path.Combine(opt.relativePath, saveFileName).ToLower();
var fileAbsPath = Path.Combine(dirAbs, saveFileName).ToLower();
File.Copy(tempPath, fileAbsPath, true);
var newFile = new BookingFile
{
Id = YitIdHelper.NextId(),
FileName = Path.GetFileName(tmpFile),
FilePath = fileRelaPath,
TypeCode = "tuodan",
TypeName = "托单文件",
BookingId = entity.Id,
};
await _repFile.InsertAsync(newFile);
}
}
}
//日志动态
SaveAuditLog(input.Id == 0 ? "已录入" : "已修改", entity.Id);
//返回给前端数据
var outModel = entity.Adapt<BookingCustomerOrderSaveOutput>();
outModel.CtnList = ctnList.Adapt<List<BookingCustomerCtnDto>>();
var dicFile = new Dictionary<long, string>();
_repFile.AsQueryable().Where(x => x.BookingId == entity.Id).ForEach(x => dicFile.Add(x.Id, x.FileName));
outModel.Files = dicFile;
outModel.LogList = _repStatuslog.AsQueryable().Where(x => x.BookingId == entity.Id && x.Category == StaLogCateAudit).OrderByDescending(x => x.OpTime).ToList().Adapt<List<BookingCustomerLogDto>>();
outModel.ServiceItemList = _repServiceItem.AsQueryable().Where(x => x.BookingId == entity.Id).ToList().Adapt<List<BookingServiceItemCustomerDto>>();
return outModel;
}
/// <summary>
/// 获取详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/Get")]
public async Task<BookingCustomerOrderSaveOutput> Get(long id)
{
var entity = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == id);
var outModel = entity.Adapt<BookingCustomerOrderSaveOutput>();
outModel.CtnList = _repCtn.Where(x => x.BILLID == id).ToList().Adapt<List<BookingCustomerCtnDto>>();
var dicFile = new Dictionary<long, string>();
_repFile.AsQueryable().Where(x => x.BookingId == entity.Id).ForEach(x => dicFile.Add(x.Id, x.FileName));
outModel.Files = dicFile;
outModel.LogList = _repStatuslog.AsQueryable().Where(x => x.BookingId == entity.Id && x.Category == StaLogCateAudit).OrderByDescending(x => x.OpTime).ToList().Adapt<List<BookingCustomerLogDto>>();
outModel.ServiceItemList = _repServiceItem.AsQueryable().Where(x => x.BookingId == entity.Id).ToList().Adapt<List<BookingServiceItemCustomerDto>>();
return outModel;
}
/// <summary>
/// 上传临时文件
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/UploadTempFile")]
public async Task<string> UploadTempFile(IFormFile file)
{
//未上传文件
if (file == null || file.Length == 0)
{
throw Oops.Bah("未上传任何文件");
}
var optTempFile = App.GetOptions<TempFileOptions>().Path;
var tempFilePath = $"{DateTime.Now.Ticks}"; //临时存放目录
var tempSavePath = Path.Combine(optTempFile, tempFilePath);
Directory.CreateDirectory(tempSavePath);
var fileFullPath = Path.Combine(tempSavePath, file.FileName);//服务器路径
using (var stream = File.Create(fileFullPath))
{
await file.CopyToAsync(stream);
}
return Path.Combine(tempFilePath, file.FileName);
}
/// <summary>
/// 下载查看上传的文件
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("/BookingCustomerOrder/GetFile"), AllowAnonymous]
public async Task<IActionResult> GetFile(long id)
{
var savedFile = await _repFile.AsQueryable().Filter(null, true).FirstAsync(u => u.Id == id);
if (savedFile == null)
{
throw Oops.Oh("文件不存在");
}
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
var fileFullPath = Path.Combine(dirAbs, savedFile.FilePath);
if (!File.Exists(fileFullPath))
{
throw Oops.Oh("文件不存在");
}
//var fileName = HttpUtility.UrlEncode(savedFile.FileName, Encoding.GetEncoding("UTF-8"));
var result = new FileStreamResult(new FileStream(fileFullPath, FileMode.Open), "application/octet-stream") { FileDownloadName = savedFile.FileName };
return result;
}
/// <summary>
/// 删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/Delete")]
public async Task Delete(List<long> ids)
{
var list = await _rep.AsQueryable().Filter(null, true).Where(x => ids.Contains(x.Id)).ToListAsync();
var canNotDelList = list.Where(x => x.BSSTATUS != "已录入" && x.BSSTATUS != "已驳回");
if (canNotDelList.Any())
{
var errMsg = string.Join("\r\n", canNotDelList.Select(x => $"{x.BOOKINGNO}的数据当前状态不能删除").ToList());
throw Oops.Bah(errMsg);
}
list.ForEach(x =>
{
x.IsDeleted = true;
_rep.Update(x);
});
}
#endregion
#region 客户订舱系统操作与接口
/// <summary>
/// 提交订舱
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/Submit")]
public async Task<string> Submit(List<long> ids)
{
var recUrl = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingRequestReceiveUrl");
if (recUrl == null || string.IsNullOrEmpty(recUrl.Value))
{
throw Oops.Bah("大简云接收订舱URL地址未配置请联系管理员");
}
var userId = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingReceiveUserId");
var userSecret = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingReceiveUserSecret");
if (userId == null || string.IsNullOrEmpty(userId.Value) || userSecret == null || string.IsNullOrEmpty(userSecret.Value))
{
throw Oops.Bah("大简云接收订舱用户key和秘钥未配置请联系管理员");
}
//构建数据并发送
var orderList = _rep.AsQueryable().Where(x => ids.Contains(x.Id)).ToList();
var ordIdList = orderList.Select(o => o.Id).ToList();
var ctnList = _repCtn.AsQueryable().Where(x => ordIdList.Contains(x.BILLID.Value)).ToList();
var fileList = _repFile.AsQueryable().Where(x => ordIdList.Contains(x.BookingId)).ToList();
var serviceItemList = _repServiceItem.AsQueryable().Where(x => ordIdList.Contains(x.BookingId.Value)).ToList();
var sendList = new List<BookingCustomerSubmitReceiveDto>();
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = opt.basePath;
if (string.IsNullOrEmpty(dirAbs))
{
dirAbs = App.WebHostEnvironment.WebRootPath;
}
foreach (var order in orderList)
{
if (order.BSSTATUS != "已录入" && order.BSSTATUS != "已驳回")
{
throw Oops.Bah($"{order.BOOKINGNO} 当前状态为{order.BSSTATUS},不能提交");
}
var dto = order.Adapt<BookingCustomerSubmitReceiveDto>();
dto.BookingTenantId = UserManager.TENANT_ID;
dto.BookingTenantName = UserManager.TENANT_NAME;
dto.BookingCompanyId = UserManager.DjyCompanyId;
dto.BookingUserId = UserManager.UserId;
dto.BookingUserName = UserManager.Name;
dto.BookingDjyUserId = UserManager.DjyUserId;
dto.CtnList = ctnList.Where(x => x.BILLID == dto.Id).ToList().Adapt<List<BookingCustomerCtnDto>>();
dto.ServiceItemList = serviceItemList.Where(x => x.BookingId == dto.Id).ToList().Adapt<List<BookingServiceItemCustomerDto>>();
dto.Files = new Dictionary<string, string>();
foreach (var file in fileList.Where(x => x.BookingId == dto.Id))
{
var fileAbsPath = Path.Combine(dirAbs, file.FilePath);
if (File.Exists(fileAbsPath))
{
dto.Files.Add(file.FileName, Convert.ToBase64String(File.ReadAllBytes(fileAbsPath)));
}
}
sendList.Add(dto);
}
//构建完整url
var submitUrl = recUrl.Value;
if (!submitUrl.EndsWith("/"))
{
submitUrl += "/";
}
submitUrl += "BookingCustomerOrder/ReceiveBooking";
_logger.LogInformation($"提交订舱数据({submitUrl}{userId.Value}{userSecret.Value}{JsonConvert.SerializeObject(sendList)}");
var rtn = await submitUrl
.SetHeaders(new Dictionary<string, object> {
{ CommonConst.API_USER_HEADER_KEY, userId.Value},
{ CommonConst.API_USER_HEADER_SECRET, userSecret.Value}
})
.SetBody(sendList)
.PostAsStringAsync();
_logger.LogInformation($"返回数据:{rtn}");
var resultText = new StringBuilder();
var jobjRtn = JObject.Parse(rtn);
if (jobjRtn.GetIntValue("code") != 200)
{
throw Oops.Bah(jobjRtn.GetStringValue("message"));
}
else
{
var arrData = jobjRtn.GetJArrayValue("data");
foreach (JObject item in arrData)
{
var id = item.GetLongValue("id");
var bookingno = item.GetStringValue("bookingno");
var message = item.GetStringValue("message");
var succ = item.GetBooleanValue("success");
if (succ)
{
var model = _rep.AsQueryable().First(x => x.Id == id);
model.BSSTATUS = "已提交";
await _rep.UpdateAsync(model);
//日志动态
SaveAuditLog("已提交", id);
}
else
{
//日志动态
SaveAuditLog($"提交失败:{item.GetBooleanValue("message")}", id);
}
resultText.AppendLine($"{bookingno}{message}");
}
return resultText.ToString();
}
}
/// <summary>
/// 取消提交订舱
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/CancelSubmit")]
public async Task<string> CancelSubmit(List<long> ids)
{
var recUrl = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingRequestReceiveUrl");
if (recUrl == null || string.IsNullOrEmpty(recUrl.Value))
{
throw Oops.Bah("大简云接收订舱URL地址未配置请联系管理员");
}
var userId = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingReceiveUserId");
var userSecret = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingReceiveUserSecret");
if (userId == null || string.IsNullOrEmpty(userId.Value) || userSecret == null || string.IsNullOrEmpty(userSecret.Value))
{
throw Oops.Bah("大简云接收订舱用户key和秘钥未配置请联系管理员");
}
var orderList = _rep.AsQueryable().Where(x => ids.Contains(x.Id)).ToList();
var noSubmitList = orderList.Where(x => x.BSSTATUS != "已提交").Select(x => x.BOOKINGNO).ToList();
if (noSubmitList.Count > 0)
{
throw Oops.Bah($"编号为 {string.Join(",", noSubmitList)} 的状态不能取消订舱");
}
var sendList = orderList.Select(x => new BookingCustomerCancelSubmitDto()
{
Id = x.Id,
BOOKINGNO = x.BOOKINGNO
}).ToList();
//构建完整url
var submitUrl = recUrl.Value;
if (!submitUrl.EndsWith("/"))
{
submitUrl += "/";
}
submitUrl += "BookingCustomerOrder/CancelBooking";
_logger.LogInformation($"取消提交订舱数据({submitUrl}{userId.Value}{userSecret.Value}{JsonConvert.SerializeObject(sendList)}");
var rtn = await submitUrl
.SetHeaders(new Dictionary<string, object> {
{ CommonConst.API_USER_HEADER_KEY, userId.Value},
{ CommonConst.API_USER_HEADER_SECRET, userSecret.Value}
})
.SetBody(sendList)
.PostAsStringAsync();
_logger.LogInformation($"返回数据:{rtn}");
var resultText = new StringBuilder();
var jobjRtn = JObject.Parse(rtn);
if (jobjRtn.GetIntValue("code") != 200)
{
throw Oops.Bah(jobjRtn.GetStringValue("message"));
}
else
{
var arrData = jobjRtn.GetJArrayValue("data");
foreach (JObject item in arrData)
{
var id = item.GetLongValue("id");
var bookingno = item.GetStringValue("bookingno");
var message = item.GetStringValue("message");
var succ = item.GetBooleanValue("success");
if (succ)
{
var model = _rep.AsQueryable().First(x => x.Id == id);
model.BSSTATUS = "已录入";
await _rep.UpdateAsync(model);
//日志动态
SaveAuditLog($"取消提交", id);
}
else
{
//日志动态
SaveAuditLog($"取消提交失败:{item.GetBooleanValue("message")}", id);
}
resultText.AppendLine($"{bookingno}{message}");
}
return resultText.ToString();
}
}
#region 客户订舱模板
/// <summary>
/// 客户订舱模板列表
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/OrderTemplateList")]
public async Task<SqlSugarPagedList<BookingCustomerTemplateQueryOutput>> OrderTemplateList(BookingCustomerTemplateQueryInput input)
{
var query = _repOrderTempl.AsQueryable()
.Where(t => t.CreatedUserId == UserManager.UserId)
.WhereIF(!string.IsNullOrEmpty(input.Title), t => t.Title.Contains(input.Title))
.Select(t => new BookingCustomerTemplateQueryOutput()
{
Id = t.Id,
Title = t.Title,
OrderId = t.OrderId
});
if (!string.IsNullOrEmpty(input.SortField) || input.MultiSort == null || input.MultiSort.Count == 0)
{
query = query.OrderBy(PageInputOrder.OrderBuilder(input.SortField, input.DescSort));
}
else
{
query = query.OrderBy(PageInputOrder.MultiOrderBuilder(input.MultiSort));
}
return await query.ToPagedListAsync(input.PageNo, input.PageSize);
}
/// <summary>
/// 客户订舱模板删除
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/OrderTemplateDel")]
public async Task OrderTemplateDel(long id)
{
await _repOrderTempl.DeleteAsync(id);
}
/// <summary>
/// 客户订舱模板保存(将某条订舱数据设置为模板)
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/OrderTemplateSave")]
public async Task OrderTemplateSave(long id, string title)
{
var order = _rep.AsQueryable().Filter(null, true).First(x => x.Id == id);
var template = _repOrderTempl.FirstOrDefault(x => x.OrderId == id);
if (order == null)
{
throw Oops.Bah("客户订舱数据未找到");
}
if (template == null)
{
template = new BookingCustomerOrderTemplate();
template.Title = title;
template.OrderId = id;
await _repOrderTempl.InsertAsync(template);
}
else
{
template.Title = title;
await _repOrderTempl.UpdateAsync(template);
}
}
#endregion
/// <summary>
/// 接收反馈订舱审核回执
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/RecBookingAuditFeedback"), AllowAnonymous, ApiUser(ApiCode = "BookingRecAuditFeedback")]
public async Task<long> RecBookingAuditFeedback(BookingCustomerRecAduitFeedbackDto dto)
{
var id = Convert.ToInt64(dto.Id);
var model = _rep.AsQueryable().Filter(null, true).First(x => x.Id == id);
if (model == null)
{
throw Oops.Bah("未找到数据");
}
if (model.BSSTATUS != "已提交")
{
throw Oops.Bah("当前状态不能接受审核回推");
}
if (dto.Accept)
{
model.BSSTATUS = "已审核";
}
else
{
model.BSSTATUS = "已驳回";
}
await _rep.UpdateAsync(model);
//日志动态
SaveAuditLog($"{model.BSSTATUS},审核意见:{dto.Comment}", id, model.CreatedUserId.Value, model.TenantId.Value, "系统");
//进入客户订舱系统的订舱台账
if (dto.Accept)
{
var bkOrder = model.Adapt<BookingOrder>();
bkOrder.Id = YitIdHelper.NextId();
bkOrder.BSSTATUS = "已录入";
bkOrder.ParentId = 0;
await _repOrder.InsertAsync(bkOrder);
model.BookingId = bkOrder.Id; //客户订舱数据与订舱台账数据关联
await _rep.UpdateAsync(model);
var ctnList = await _repCtn.AsQueryable().Filter(null, true).Where(x => x.BILLID == model.Id).ToListAsync();
foreach (var ctn in ctnList)
{
ctn.Id = YitIdHelper.NextId();
ctn.BILLID = bkOrder.Id;
await _repCtn.InsertAsync(ctn);
}
//服务项目
var servList = await _repServiceItem.Where(x => x.BookingId == model.Id).ToListAsync();
foreach (var serv in servList)
{
serv.Id = YitIdHelper.NextId();
serv.BookingId = bkOrder.Id;
await _repServiceItem.InsertAsync(serv);
}
return bkOrder.Id;
}
return 0;
}
/// <summary>
/// 接收订舱数据的回推
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/RecBookingDataFeedback"), AllowAnonymous, ApiUser(ApiCode = "BookingRecAuditFeedback")]
public async Task RecBookingDataFeedback(BookingCustomerRecDataFeedbackDto recModel)
{
_logger.LogInformation($"收到订舱回推数据:{recModel.ToJsonString()}");
var dbOrder = await _repOrder.AsQueryable().Filter(null, true).FirstAsync(x => !x.IsDeleted && x.Id == recModel.Order.Id);
if (dbOrder == null)
{
throw Oops.Bah($"未找到id为{recModel.Order.Id}的数据");
}
if (!string.IsNullOrEmpty(dbOrder.MBLNO)) //提单号不覆盖
{
recModel.Order.MBLNO = dbOrder.MBLNO;
}
//保存主表
recModel.Order.Adapt(dbOrder);
await _repOrder.UpdateAsync(dbOrder);
//更新箱信息
await _repCtn.DeleteAsync(x => x.BILLID == recModel.Order.Id);
foreach (var ctn in recModel.Ctns)
{
var saveCtn = ctn.Adapt<BookingCtn>();
saveCtn.BILLID = recModel.Order.Id;
saveCtn.CreatedUserId = dbOrder.CreatedUserId;
saveCtn.CreatedUserName = "系统";
saveCtn.CreatedTime = DateTime.Now;
saveCtn.TenantId = dbOrder.TenantId;
await _repCtn.InsertAsync(saveCtn);
}
//货运动态
foreach (var sta in recModel.StatusLogs)
{
await _repStatuslogDetail.DeleteAsync(x => x.PId == sta.Id);
await _repStatuslog.DeleteAsync(x => x.Id == sta.Id);
var insStaLog = sta.Adapt<BookingStatusLog>();
insStaLog.BookingId = recModel.Order.Id;
await _repStatuslog.InsertAsync(insStaLog);
foreach (var staDetail in sta.Details)
{
var insStaDetail = staDetail.Adapt<BookingStatusLogDetail>();
insStaDetail.PId = insStaLog.Id;
await _repStatuslogDetail.InsertAsync(insStaDetail);
}
}
//文件
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = string.Empty;
if (string.IsNullOrEmpty(opt.basePath))
{
dirAbs = Path.Combine(App.WebHostEnvironment.WebRootPath, opt.relativePath);
}
else
{
dirAbs = Path.Combine(opt.basePath, opt.relativePath);
}
if (!Directory.Exists(dirAbs))
Directory.CreateDirectory(dirAbs);
var dbFiles = await _repFile.Where(f => f.BookingId == recModel.Order.Id).ToListAsync();
foreach (var file in recModel.Files)
{
if (dbFiles.Count(ff => ff.Id == file.Id) == 0) //新文件
{
var insFile = file.Adapt<BookingFile>();
insFile.BookingId = recModel.Order.Id;
insFile.CreatedUserId = dbOrder.CreatedUserId;
insFile.CreatedUserName = "系统";
insFile.CreatedTime = DateTime.Now;
insFile.TenantId = dbOrder.TenantId;
var saveFileName = $"{DateTime.Now.Ticks}{Path.GetExtension(file.FileName)}";
var fileRelaPath = Path.Combine(opt.relativePath, saveFileName).ToLower();
var fileAbsPath = Path.Combine(dirAbs, saveFileName).ToLower();
insFile.FilePath = fileRelaPath;
File.WriteAllBytes(fileAbsPath, file.FileContent);
await _repFile.InsertAsync(insFile);
}
}
}
#endregion
#region 大简云订舱平台操作与接口
/// <summary>
/// 接收客户订舱系统提交的数据
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/ReceiveBooking"), AllowAnonymous, ApiUser(ApiCode = "DjyBookingReceiveApi")]
public async Task<List<BookingSubmitResultModel>> ReceiveBooking(List<BookingCustomerSubmitReceiveDto> list)
{
_logger.LogInformation($"收到提交的订舱数据:{JsonConvert.SerializeObject(list)}");
var rtnList = new List<BookingSubmitResultModel>();
foreach (var item in list)
{
var strId = item.Id.ToString();
var order = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.TenantId == UserManager.TENANT_ID && x.BSNO == strId);
if (order == null)
{
order = item.Adapt<BookingCustomerOrder>();
order.BSNO = order.Id.ToString(); //客户订舱系统中的id
order.Id = YitIdHelper.NextId();
order.BSSTATUS = "已接收";
await _rep.InsertAsync(order);
}
else
{
if (order.BSSTATUS == "已审核")
{
rtnList.Add(new BookingSubmitResultModel()
{
Id = item.Id,
Success = false,
BOOKINGNO = item.BOOKINGNO,
Message = $"数据已审核,不能重复提交"
}); ;
continue;
}
var idBackup = order.Id; //防止覆盖
var bsnoBackup = order.BSNO; //防止覆盖
order = item.Adapt(order);
order.Id = idBackup;
order.BSNO = bsnoBackup;
order.BSSTATUS = "已接收";
order.IsDeleted = false;
await _rep.UpdateAsync(order);
}
//箱信息
await _repCtn.DeleteAsync(x => x.BILLID == order.Id);
foreach (var ctn in item.CtnList)
{
var bkCtn = ctn.Adapt<BookingCtn>();
bkCtn.Id = YitIdHelper.NextId();
bkCtn.BILLID = order.Id;
await _repCtn.InsertAsync(bkCtn);
}
//服务项目
await _repServiceItem.DeleteAsync(x => x.BookingId == order.Id);
foreach (var serv in item.ServiceItemList)
{
var bkServ = serv.Adapt<BookingServiceItem>();
bkServ.Id = YitIdHelper.NextId();
bkServ.BookingId = order.Id;
await _repServiceItem.InsertAsync(bkServ);
}
//文件
await _repFile.DeleteAsync(x => x.BookingId == order.Id);
var opt = App.GetOptions<BookingAttachOptions>();
var dirAbs = string.Empty;
if (string.IsNullOrEmpty(opt.basePath))
{
dirAbs = Path.Combine(App.WebHostEnvironment.WebRootPath, opt.relativePath);
}
else
{
dirAbs = Path.Combine(opt.basePath, opt.relativePath);
}
foreach (var file in item.Files)
{
var saveFileName = $"{DateTime.Now.Ticks}{Path.GetExtension(file.Key)}";
var fileRelaPath = Path.Combine(opt.relativePath, saveFileName).ToLower();
var fileAbsPath = Path.Combine(dirAbs, saveFileName).ToLower();
File.WriteAllBytes(fileAbsPath, Convert.FromBase64String(file.Value));
var bkFile = new BookingFile
{
Id = YitIdHelper.NextId(),
FileName = Path.GetFileName(file.Key),
FilePath = fileRelaPath,
TypeCode = "tuodan",
TypeName = "托单文件",
BookingId = order.Id,
};
await _repFile.InsertAsync(bkFile);
}
rtnList.Add(new BookingSubmitResultModel()
{
Id = item.Id,
Success = true,
BOOKINGNO = item.BOOKINGNO,
Message = $"提交成功"
});
//日志动态
SaveAuditLog($"已接收", order.Id);
}
return rtnList;
}
/// <summary>
/// 审核订舱请求
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/AuditBooking")]
public async Task AuditBooking(long id, bool accept, string comment)
{
var model = _rep.FirstOrDefault(x => x.Id == id);
if (model == null)
{
throw Oops.Bah("未找到业务信息");
}
if (model.BSSTATUS != "已接收")
{
throw Oops.Bah("当前状态不能审核");
}
if (accept)
{
model.BSSTATUS = "已审核";
}
else
{
model.BSSTATUS = "已驳回";
}
//回推回执
var recFeedbackConfig = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackURL");
if (recFeedbackConfig == null || string.IsNullOrEmpty(recFeedbackConfig.Value))
{
throw Oops.Bah("回推订舱审核结果的URL地址未配置请联系管理员");
}
var recFeedbackUserKey = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackUserKey");
if (recFeedbackUserKey == null || string.IsNullOrEmpty(recFeedbackUserKey.Value))
{
throw Oops.Bah("回推订舱审核结果的用户KEY未配置请联系管理员");
}
var recFeedbackUserSecret = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecFeedbackUserSecret");
if (recFeedbackUserSecret == null || string.IsNullOrEmpty(recFeedbackUserSecret.Value))
{
throw Oops.Bah("回推订舱审核结果的用户秘钥未配置,请联系管理员");
}
var sendObj = new BookingCustomerRecAduitFeedbackDto()
{
Id = model.BSNO,
Accept = accept,
Comment = comment
};
var feedbackUrl = recFeedbackConfig.Value;
if (!feedbackUrl.EndsWith("/"))
{
feedbackUrl += "/";
}
feedbackUrl += "BookingCustomerOrder/RecBookingAuditFeedback";
_logger.LogInformation($"回推审核数据:{JsonConvert.SerializeObject(sendObj)}URL{feedbackUrl}");
var rtn = await feedbackUrl
.SetHeaders(new Dictionary<string, object> {
{ CommonConst.API_USER_HEADER_KEY, recFeedbackUserKey.Value},
{ CommonConst.API_USER_HEADER_SECRET, recFeedbackUserSecret.Value}
})
.SetBody(sendObj)
.PostAsStringAsync();
_logger.LogInformation($"回推审核返回:{rtn}");
var jobjRtn = JObject.Parse(rtn);
if (jobjRtn.GetIntValue("code") != 200)
{
throw Oops.Bah(jobjRtn.GetStringValue("message"));
}
await _rep.UpdateAsync(model); //回推成功后,存库
//日志动态
SaveAuditLog($"{(accept ? "" : "")},审核意见:{comment}", id);
//进入订舱台账
if (accept)
{
var custBookId = jobjRtn.GetStringValue("data"); //返回的客户订舱系统的订舱数据id
var bkOrder = model.Adapt<BookingOrder>();
bkOrder.Id = YitIdHelper.NextId();
bkOrder.BSNO = custBookId;
bkOrder.BSSTATUS = "已录入";
bkOrder.CUSTOMERNAME = model.BookingTenantName;
bkOrder.ParentId = 0;
await _repOrder.InsertAsync(bkOrder);
model.BookingId = bkOrder.Id; //客户订舱数据与订舱台账数据关联
await _rep.UpdateAsync(model);
var ctnList = await _repCtn.AsQueryable().Filter(null, true).Where(x => x.BILLID == model.Id).ToListAsync();
foreach (var ctn in ctnList)
{
ctn.Id = YitIdHelper.NextId();
ctn.BILLID = bkOrder.Id;
await _repCtn.InsertAsync(ctn);
}
//服务项目
var servList = await _repServiceItem.Where(x => x.BookingId == model.Id).ToListAsync();
foreach (var serv in servList)
{
serv.Id = YitIdHelper.NextId();
serv.BookingId = bkOrder.Id;
await _repServiceItem.InsertAsync(serv);
}
}
}
/// <summary>
/// 接收客户订舱系统取消提交的数据
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/CancelBooking"), AllowAnonymous, ApiUser(ApiCode = "DjyBookingReceiveApi")]
public async Task<List<BookingSubmitResultModel>> CancelBooking(List<BookingCustomerCancelSubmitDto> list)
{
_logger.LogInformation($"收到提交的订舱数据:{JsonConvert.SerializeObject(list)}");
var rtnList = new List<BookingSubmitResultModel>();
foreach (var item in list)
{
var strId = item.Id.ToString();
var order = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.TenantId == UserManager.TENANT_ID && !x.IsDeleted && x.BSNO == strId);
if (order == null)
{
rtnList.Add(new BookingSubmitResultModel()
{
Id = item.Id,
Success = false,
BOOKINGNO = item.BOOKINGNO,
Message = $"未找到订舱数据"
});
}
else
{
if (order.BSSTATUS != "已接收")
{
rtnList.Add(new BookingSubmitResultModel()
{
Id = item.Id,
Success = false,
BOOKINGNO = item.BOOKINGNO,
Message = $"当前状态不能取消"
});
continue;
}
order.IsDeleted = true;
await _rep.UpdateAsync(order);
rtnList.Add(new BookingSubmitResultModel()
{
Id = item.Id,
Success = true,
BOOKINGNO = item.BOOKINGNO,
Message = $"已成功取消"
});
//日志动态
SaveAuditLog($"取消提交", order.Id);
}
}
return rtnList;
}
#endregion
#region 私有方法
/// <summary>
/// 保存审核的日志动态(使用当前登录人信息)
/// </summary>
private void SaveAuditLog(string status, long bookId)
{
var staLog = new BookingStatusLog();
staLog.Status = status;
staLog.CreatedUserId = UserManager.UserId;
staLog.CreatedUserName = UserManager.Name;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = bookId;
staLog.Category = StaLogCateAudit;
_repStatuslog.Insert(staLog);
}
/// <summary>
/// 保存审核的日志动态
/// </summary>
private void SaveAuditLog(string status, long bookId, long userId, long tenantId, string userName)
{
var staLog = new BookingStatusLog();
staLog.Status = status;
staLog.CreatedUserId = userId;
staLog.CreatedUserName = userName;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = bookId;
staLog.Category = StaLogCateAudit;
staLog.TenantId = tenantId;
_repStatuslog.Insert(staLog);
}
#endregion
}
}