wet 1 year ago
commit 8ded3742aa

@ -441,7 +441,8 @@ namespace Myshipping.Application.EDI.TSL
else
{
//2023-03-02 测试发现与东胜的限制行数不同东胜是8行跟韩工确认限制从6改为8
error += formatlengthError("txt", headData.SHIPPER, 35, headData.MBLNO, "发货人", 8, "*", false);
//2023-06-19 合川操作提出收、发、通需要能录超过最大8行查看TSL报文允许最大10行将最大8行改为10行
error += formatlengthError("txt", headData.SHIPPER, 35, headData.MBLNO, "发货人", 10, "*", false);
}
}
}
@ -468,7 +469,8 @@ namespace Myshipping.Application.EDI.TSL
else
{
//2023-03-02 测试发现与东胜的限制行数不同东胜是8行跟韩工确认限制从6改为8
error += formatlengthError("txt", headData.CONSIGNEE, 35, headData.MBLNO, "收货人", 8, "**", false);
//2023-06-19 合川操作提出收、发、通需要能录超过最大8行查看TSL报文允许最大10行将最大8行改为10行
error += formatlengthError("txt", headData.CONSIGNEE, 35, headData.MBLNO, "收货人", 10, "**", false);
}
}
}
@ -523,7 +525,8 @@ namespace Myshipping.Application.EDI.TSL
else
{
//2023-03-02 测试发现与东胜的限制行数不同东胜是8行跟韩工确认限制从6改为8
error += formatlengthError("txt", headData.NOTIFYPARTY, 35, headData.MBLNO, "通知人", 8, "***", false);
//2023-06-19 合川操作提出收、发、通需要能录超过最大8行查看TSL报文允许最大10行将最大8行改为10行
error += formatlengthError("txt", headData.NOTIFYPARTY, 35, headData.MBLNO, "通知人", 10, "***", false);
}
}
}

@ -11,6 +11,10 @@ namespace Myshipping.Application.Entity
[Description("客户订舱")]
public class BookingCustomerOrder : DBEntityTenant
{
/// <summary>
/// 其他业务系统ID
/// </summary>
public string BSNO { get; set; }
/// <summary>
/// 业务状态
/// </summary>
@ -188,5 +192,41 @@ namespace Myshipping.Application.Entity
/// 租户名称
/// </summary>
public string TenantName { get; set; }
/// <summary>
/// 订舱台账ID
/// </summary>
public long BookingId { get; set; }
/// <summary>
/// 订舱租户id
/// </summary>
public long BookingTenantId { get; set; }
/// <summary>
/// 订舱租户名称
/// </summary>
public string BookingTenantName { get; set; }
/// <summary>
/// 订舱租户大简云公司id
/// </summary>
public string BookingCompanyId { get; set; }
/// <summary>
/// 订舱用户id
/// </summary>
public long BookingUserId { get; set; }
/// <summary>
/// 订舱用户名称
/// </summary>
public string BookingUserName { get; set; }
/// <summary>
/// 订舱大简云用户id
/// </summary>
public string BookingDjyUserId { get; set; }
}
}

@ -2,6 +2,7 @@
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.RemoteRequest.Extensions;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@ -11,6 +12,8 @@ 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;
@ -34,9 +37,13 @@ namespace Myshipping.Application
private readonly ISysCacheService _cache;
private readonly SqlSugarRepository<BookingFile> _repFile;
private readonly SqlSugarRepository<BookingStatusLog> _repStatuslog;
private readonly SqlSugarRepository<BookingServiceItem> _repServiceItem;
private readonly SqlSugarRepository<BookingOrder> _repOrder;
public BookingCustomerOrderService(SqlSugarRepository<BookingCustomerOrder> rep, SqlSugarRepository<BookingCtn> repCtn,
ILogger<BookingOrderService> logger, ISysCacheService cache, SqlSugarRepository<BookingFile> repFile, SqlSugarRepository<BookingStatusLog> statuslog)
ILogger<BookingOrderService> logger, ISysCacheService cache, SqlSugarRepository<BookingFile> repFile,
SqlSugarRepository<BookingStatusLog> statuslog, SqlSugarRepository<BookingServiceItem> repServiceItem,
SqlSugarRepository<BookingOrder> repOrder)
{
this._logger = logger;
this._rep = rep;
@ -44,23 +51,62 @@ namespace Myshipping.Application
this._cache = cache;
this._repFile = repFile;
this._repStatuslog = statuslog;
this._repServiceItem = repServiceItem;
this._repOrder = repOrder;
}
//查询台账
#region 订舱草稿及附件
/// <summary>
/// 订舱草稿台账
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/PageData")]
public async Task<SqlSugarPagedList<BookingCustomerOrderListOutput>> PageData(BookingCustomerOrderQueryInput input)
{
var query = _rep.AsQueryable();
var query = _rep.AsQueryable().Filter(null, true).Where(x => x.TenantId == UserManager.TENANT_ID)
.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(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.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)).ToList();
foreach (var item in list.Items)
{
item.LogList = staLogList.Where(x => x.BookingId == item.Id).OrderBy(x => x.OpTime).Adapt<List<BookingCustomerLogDto>>();
}
return list;
}
/// <summary>
/// 保存数据
/// 保存草稿数据
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
@ -95,7 +141,7 @@ namespace Myshipping.Application
else
{
entity = await _rep.AsQueryable().Filter(null, true).FirstAsync(x => x.Id == input.Id);
if (entity.BSSTATUS != "已录入" || entity.BSSTATUS != "已驳回")
if (entity.BSSTATUS != "已录入" && entity.BSSTATUS != "已驳回")
{
throw Oops.Bah("当前状态不允许修改");
}
@ -123,6 +169,25 @@ namespace Myshipping.Application
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);
}
//文件
@ -141,6 +206,17 @@ namespace Myshipping.Application
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)
{
@ -171,17 +247,6 @@ namespace Myshipping.Application
}
}
//清除前端已删除的文件
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);
}
//日志动态
var staLog = new BookingStatusLog();
@ -193,14 +258,15 @@ namespace Myshipping.Application
staLog.BookingId = entity.Id;
_repStatuslog.Insert(staLog);
//返回给前端数据
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).ToList().Adapt<List<BookingCustomerLogDto>>();
outModel.ServiceItemList = _repServiceItem.AsQueryable().Where(x => x.BookingId == entity.Id).ToList().Adapt<List<BookingServiceItemCustomerDto>>();
return outModel;
}
@ -221,8 +287,8 @@ namespace Myshipping.Application
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).ToList().Adapt<List<BookingCustomerLogDto>>();
outModel.ServiceItemList = _repServiceItem.AsQueryable().Where(x => x.BookingId == entity.Id).ToList().Adapt<List<BookingServiceItemCustomerDto>>();
return outModel;
}
@ -283,19 +349,441 @@ namespace Myshipping.Application
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 = fileName };
//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;
}
#endregion
#region 客户订舱系统操作与接口
/// <summary>
/// 提交订舱
/// </summary>
/// <returns></returns>
[HttpPost("/BookingCustomerOrder/Submit")]
public async Task 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.GetAllTenantParam().Result.FirstOrDefault(x => x.TenantId == UserManager.TENANT_ID && x.ParaCode == "DjyBookingReceiveUserId");
var userSecret = _cache.GetAllTenantParam().Result.FirstOrDefault(x => x.TenantId == UserManager.TENANT_ID && x.ParaCode == "DjyBookingReceiveUserSecret");
if (userId == null || string.IsNullOrEmpty(userId.ItemCode) || userSecret == null || string.IsNullOrEmpty(userSecret.ItemCode))
{
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);
}
_logger.LogInformation($"提交订舱数据({recUrl.Value}{userId.ItemCode}{userSecret.ItemCode}{JsonConvert.SerializeObject(sendList)}");
var rtn = await recUrl.Value
.SetHeaders(new Dictionary<string, object> {
{ CommonConst.API_USER_HEADER_KEY, userId.ItemCode},
{ CommonConst.API_USER_HEADER_SECRET, userSecret.ItemCode}
})
.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);
//日志动态
var staLog = new BookingStatusLog();
staLog.Status = "已提交";
staLog.CreatedUserId = UserManager.UserId;
staLog.CreatedUserName = UserManager.Name;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = id;
_repStatuslog.Insert(staLog);
}
else
{
//日志动态
var staLog = new BookingStatusLog();
staLog.Status = $"提交失败:{item.GetBooleanValue("message")}";
staLog.CreatedUserId = UserManager.UserId;
staLog.CreatedUserName = UserManager.Name;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = id;
_repStatuslog.Insert(staLog);
}
resultText.AppendLine($"{bookingno}{message}");
}
return resultText.ToString();
}
}
/// <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);
//日志动态
var staLog = new BookingStatusLog();
staLog.Status = $"{model.BSSTATUS},审核意见:{dto.Comment}";
staLog.CreatedUserId = UserManager.UserId;
staLog.CreatedUserName = UserManager.Name;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = id;
_repStatuslog.Insert(staLog);
//进入客户订舱系统的订舱台账
if (dto.Accept)
{
var bkOrder = model.Adapt<BookingOrder>();
bkOrder.Id = YitIdHelper.NextId();
bkOrder.BSSTATUS = "已录入";
await _repOrder.InsertAsync(bkOrder);
model.BookingId = bkOrder.Id; //客户订舱数据与订舱台账数据关联
await _rep.UpdateAsync(model);
var ctnList = await _repCtn.Where(x => x.BILLID == model.Id).ToListAsync();
foreach (var ctn in ctnList)
{
ctn.Id = YitIdHelper.NextId();
ctn.BILLID = bkOrder.Id;
await _repCtn.InsertAsync(ctn);
}
return bkOrder.Id;
}
return 0;
}
#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.IsDeleted && 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 = order.Adapt(order);
order.Id = idBackup;
order.BSNO = bsnoBackup;
order.BSSTATUS = "已接收";
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 = $"提交成功"
});
//日志动态
var staLog = new BookingStatusLog();
staLog.Status = "已接收";
staLog.CreatedUserId = UserManager.UserId;
staLog.CreatedUserName = UserManager.Name;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = order.Id;
_repStatuslog.Insert(staLog);
}
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 == "DjyBookingCustomerRecAuditFeedbackURL");
if (recFeedbackConfig == null || string.IsNullOrEmpty(recFeedbackConfig.Value))
{
throw Oops.Bah("回推订舱审核结果的URL地址未配置请联系管理员");
}
var recFeedbackUserKey = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecAuditFeedbackUserKey");
if (recFeedbackUserKey == null || string.IsNullOrEmpty(recFeedbackUserKey.Value))
{
throw Oops.Bah("回推订舱审核结果的用户KEY未配置请联系管理员");
}
var recFeedbackUserSecret = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyBookingCustomerRecAuditFeedbackUserSecret");
if (recFeedbackUserSecret == null || string.IsNullOrEmpty(recFeedbackUserSecret.Value))
{
throw Oops.Bah("回推订舱审核结果的用户秘钥未配置,请联系管理员");
}
var sendObj = new BookingCustomerRecAduitFeedbackDto()
{
Id = model.BSNO,
Accept = accept,
Comment = comment
};
_logger.LogInformation($"回推审核数据:{JsonConvert.SerializeObject(sendObj)}");
var rtn = await recFeedbackConfig.Value
.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); //回推成功后,存库
//日志动态
var staLog = new BookingStatusLog();
staLog.Status = $"{(accept ? "" : "")},审核意见:{comment}";
staLog.CreatedUserId = UserManager.UserId;
staLog.CreatedUserName = UserManager.Name;
staLog.CreatedTime = DateTime.Now;
staLog.OpTime = DateTime.Now;
staLog.BookingId = id;
_repStatuslog.Insert(staLog);
//进入订舱台账
if (accept)
{
var custBookId = jobjRtn.GetStringValue("data"); //返回的客户订舱系统的订舱数据id
var bkOrder = model.Adapt<BookingOrder>();
bkOrder.Id = YitIdHelper.NextId();
bkOrder.BSNO = custBookId;
bkOrder.BSSTATUS = "已录入";
await _repOrder.InsertAsync(bkOrder);
model.BookingId = bkOrder.Id; //客户订舱数据与订舱台账数据关联
await _rep.UpdateAsync(model);
var ctnList = await _repCtn.Where(x => x.BILLID == model.Id).ToListAsync();
foreach (var ctn in ctnList)
{
ctn.Id = YitIdHelper.NextId();
ctn.BILLID = bkOrder.Id;
await _repCtn.InsertAsync(ctn);
}
}
}
#endregion
}
}

@ -9,6 +9,66 @@ namespace Myshipping.Application
{
public class BookingCustomerOrderQueryInput : PageInputBase
{
/// <summary>
/// 系统编号(订舱编号)
/// </summary>
public string BOOKINGNO { get; set; }
/// <summary>
/// 船名
/// </summary>
public string VESSEL { get; set; }
/// <summary>
/// 海关航次
/// </summary>
public string VOYNO { get; set; }
/// <summary>
/// 场站代码
/// </summary>
public string YARDID { get; set; }
/// <summary>
/// 场站
/// </summary>
public string YARD { get; set; }
/// <summary>
/// 开船日期起始
/// </summary>
public DateTime? ETDStart { get; set; }
/// <summary>
/// 开船日期截止
/// </summary>
public DateTime? ETDEnd { get; set; }
/// <summary>
/// 卸货港代码
/// </summary>
public string PORTDISCHARGEID { get; set; }
/// <summary>
/// 卸货港
/// </summary>
public string PORTDISCHARGE { get; set; }
/// <summary>
/// 船公司代号
/// </summary>
public string CARRIERID { get; set; }
/// <summary>
/// 船公司
/// </summary>
public string CARRIER { get; set; }
/// <summary>
/// 录入日期起始
/// </summary>
public DateTime? CreatedTimeStart { get; set; }
/// <summary>
/// 录入日期截止
/// </summary>
public DateTime? CreatedTimeEnd { get; set; }
/// <summary>
/// 业务状态
/// </summary>
public List<string> BSStatusList { get; set; }
}
//dto
@ -197,6 +257,11 @@ namespace Myshipping.Application
/// 箱信息
/// </summary>
public List<BookingCustomerCtnDto> CtnList { get; set; }
/// <summary>
/// 服务项目
/// </summary>
public List<BookingServiceItemCustomerDto> ServiceItemList { get; set; }
}
//台账返回dto
@ -206,7 +271,16 @@ namespace Myshipping.Application
/// 系统编号
/// </summary>
public string BOOKINGNO { get; set; }
/// <summary>
/// 业务状态
/// </summary>
public string BSSTATUS { get; set; }
/// <summary>
/// 日志信息
/// </summary>
public List<BookingCustomerLogDto> LogList { get; set; }
}
//保存返回dto
@ -217,6 +291,11 @@ namespace Myshipping.Application
/// </summary>
public string BOOKINGNO { get; set; }
/// <summary>
/// 业务状态
/// </summary>
public string BSSTATUS { get; set; }
/// <summary>
/// 文件列表
/// </summary>
@ -231,6 +310,11 @@ namespace Myshipping.Application
/// 日志信息
/// </summary>
public List<BookingCustomerLogDto> LogList { get; set; }
/// <summary>
/// 服务项目
/// </summary>
public List<BookingServiceItemCustomerDto> ServiceItemList { get; set; }
}
/// <summary>
@ -279,4 +363,124 @@ namespace Myshipping.Application
public virtual string CreatedUserName { get; set; }
}
/// <summary>
/// 大简云客户订舱发送与接收dto
/// </summary>
public class BookingCustomerSubmitReceiveDto : BookingCustomerOrderDto
{
/// <summary>
/// 系统编号(订舱编号)
/// </summary>
public string BOOKINGNO { get; set; }
/// <summary>
/// 订舱租户id
/// </summary>
public long BookingTenantId { get; set; }
/// <summary>
/// 订舱租户名称
/// </summary>
public string BookingTenantName { get; set; }
/// <summary>
/// 订舱租户大简云公司id
/// </summary>
public string BookingCompanyId { get; set; }
/// <summary>
/// 订舱用户id
/// </summary>
public long BookingUserId { get; set; }
/// <summary>
/// 订舱用户名称
/// </summary>
public string BookingUserName { get; set; }
/// <summary>
/// 订舱大简云用户id
/// </summary>
public string BookingDjyUserId { get; set; }
/// <summary>
/// 文件列表key文件名称value文件内容base64
/// </summary>
public Dictionary<string, string> Files { get; set; }
/// <summary>
/// 箱信息
/// </summary>
public List<BookingCustomerCtnDto> CtnList { get; set; }
/// <summary>
/// 服务项目
/// </summary>
public List<BookingServiceItemCustomerDto> ServiceItemList { get; set; }
}
/// <summary>
/// 提交订舱返回对象
/// </summary>
public class BookingSubmitResultModel
{
/// <summary>
/// ID
/// </summary>
public long Id { get; set; }
/// <summary>
/// 客户订舱系统中的订舱编号
/// </summary>
public string BOOKINGNO { get; set; }
/// <summary>
/// 是否成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string Message { get; set; }
}
/// <summary>
/// 服务项目
/// </summary>
public class BookingServiceItemCustomerDto
{
/// <summary>
/// 状态代码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 状态名称
/// </summary>
public string Value { get; set; }
}
/// <summary>
/// 接收(发送)客户订舱审核结果
/// </summary>
public class BookingCustomerRecAduitFeedbackDto
{
/// <summary>
/// 客户订舱系统中的ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 是否接收订舱
/// </summary>
public bool Accept { get; set; }
/// <summary>
/// 审核意见
/// </summary>
public string Comment { get; set; }
}
}

@ -36,6 +36,11 @@ public class ClaimConst
/// </summary>
public const string TENANT_NAME = "TenantName";
/// <summary>
/// 大简云companyid
/// </summary>
public const string DjyCompanyId = "DjyCompanyId";
/// <summary>
/// 大简云userid
/// </summary>

@ -62,4 +62,10 @@ public class SysTenant : DEntityBase
/// 租户类型
/// </summary>
public TenantTypeEnum TenantType { get; set; }
/// <summary>
/// 大简云公司ID
/// </summary>
[MaxLength(50)]
public string CompId { get; set; }
}

@ -80,6 +80,26 @@ namespace Myshipping.Core
return rtnVal;
}
/// <summary>
/// 获取long值
/// </summary>
/// <param name="jobj"></param>
/// <param name="prop"></param>
/// <returns></returns>
public static long GetLongValue(this JObject jobj, string prop)
{
var jt = jobj[prop];
if (jt == null)
{
return 0;
}
var strVal = jt.ToString();
long rtnVal = 0;
long.TryParse(strVal, out rtnVal);
return rtnVal;
}
/// <summary>
/// 获取decimal值
/// </summary>

@ -65,6 +65,7 @@ namespace Myshipping.Core
identity.AddClaim(new Claim(type: ClaimConst.CLAINM_TENANT_TYPE, value: tenant.TenantType.ToString()));
identity.AddClaim(new Claim(type: ClaimConst.TENANT_ID, value: tenant.Id.ToString()));
identity.AddClaim(new Claim(type: ClaimConst.TENANT_NAME, value: tenant.Name));
identity.AddClaim(new Claim(type: ClaimConst.DjyCompanyId, value: tenant.CompId == null ? string.Empty : tenant.CompId));
identity.AddClaim(new Claim(type: ClaimConst.DjyUserId, value: user.DjyUserId));
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity);
httpContext.User = claimsPrincipal;

@ -42,6 +42,11 @@ public static class UserManager
/// </summary>
public static string TENANT_NAME => App.User.FindFirst(ClaimConst.TENANT_NAME)?.Value;
/// <summary>
/// 大简云公司id
/// </summary>
public static string DjyCompanyId => App.User.FindFirst(ClaimConst.DjyCompanyId)?.Value;
/// <summary>
/// 大简云userid
/// </summary>

@ -537,6 +537,11 @@
租户名称
</summary>
</member>
<member name="F:Myshipping.Core.ClaimConst.DjyCompanyId">
<summary>
大简云companyid
</summary>
</member>
<member name="F:Myshipping.Core.ClaimConst.DjyUserId">
<summary>
大简云userid
@ -3860,6 +3865,11 @@
租户类型
</summary>
</member>
<member name="P:Myshipping.Core.Entity.SysTenant.CompId">
<summary>
大简云公司ID
</summary>
</member>
<member name="T:Myshipping.Core.Entity.SysTimer">
<summary>
定时任务
@ -5389,6 +5399,14 @@
<param name="prop"></param>
<returns></returns>
</member>
<member name="M:Myshipping.Core.JsonExtension.GetLongValue(Newtonsoft.Json.Linq.JObject,System.String)">
<summary>
获取long值
</summary>
<param name="jobj"></param>
<param name="prop"></param>
<returns></returns>
</member>
<member name="M:Myshipping.Core.JsonExtension.GetDecimalValue(Newtonsoft.Json.Linq.JObject,System.String)">
<summary>
获取decimal值
@ -5829,6 +5847,11 @@
租户名称
</summary>
</member>
<member name="P:Myshipping.Core.UserManager.DjyCompanyId">
<summary>
大简云公司id
</summary>
</member>
<member name="P:Myshipping.Core.UserManager.DjyUserId">
<summary>
大简云userid
@ -6144,6 +6167,13 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:Myshipping.Core.Service.AuthService.LoginWithCode(System.String)">
<summary>
使用跳转code登录
</summary>
<param name="code"></param>
<returns></returns>
</member>
<member name="T:Myshipping.Core.Service.LoginInput">
<summary>
登录输入参数

@ -15,6 +15,9 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using UAParser;
using Furion.RemoteRequest.Extensions;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging;
namespace Myshipping.Core.Service;
@ -27,6 +30,7 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
private readonly SqlSugarRepository<SysUser> _sysUserRep; // 用户表仓储
private readonly SqlSugarRepository<SysLogVis> _sysLogVisRep;
private readonly SqlSugarRepository<SysTenant> _sysTenantRep;
private readonly ISysCacheService _cache;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ISysEmpService _sysEmpService; // 系统员工服务
@ -37,12 +41,14 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
private readonly ISysConfigService _sysConfigService; // 验证码服务
private readonly IEventPublisher _eventPublisher;
private readonly ILogger<AuthService> _logger;
public AuthService(SqlSugarRepository<SysUser> sysUserRep, SqlSugarRepository<SysLogVis> sysLogVisRep, SqlSugarRepository<SysTenant> sysTenantRep,
IHttpContextAccessor httpContextAccessor,
IHttpContextAccessor httpContextAccessor, ISysCacheService cache,
ISysEmpService sysEmpService, ISysRoleService sysRoleService, ISysMenuService sysMenuService,
ISysAppService sysAppService, IClickWordCaptcha captchaHandle, ISysConfigService sysConfigService,
IEventPublisher eventPublisher
IEventPublisher eventPublisher,
ILogger<AuthService> logger
)
{
_sysUserRep = sysUserRep;
@ -56,6 +62,8 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
_captchaHandle = captchaHandle;
_sysConfigService = sysConfigService;
_eventPublisher = eventPublisher;
_logger = logger;
_cache = cache;
}
/// <summary>
@ -83,6 +91,12 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
throw Oops.Oh(ErrorCode.D1017);
//获取对应租户
var tenant = _sysTenantRep.Single(user.TenantId);
// 生成Token令牌
return await GetLoginToken(user, tenant);
}
private async Task<string> GetLoginToken(SysUser user, SysTenant tenant)
{
// 生成Token令牌
//var accessToken = await _jwtBearerManager.CreateTokenAdmin(user);
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
@ -94,6 +108,7 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
{ClaimConst.CLAINM_SUPERADMIN, user.AdminType},
{ ClaimConst.CLAINM_TENANT_TYPE, tenant.TenantType },
{ ClaimConst.TENANT_NAME, tenant.Name },
{ ClaimConst.DjyCompanyId, tenant.CompId == null ? string.Empty : tenant.CompId },
{ ClaimConst.DjyUserId, user.DjyUserId },
{ ClaimConst.Tel, user.Tel },
{ ClaimConst.Phone, user.Phone },
@ -152,6 +167,7 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
{ ClaimConst.CLAINM_SUPERADMIN, user.AdminType },
{ ClaimConst.CLAINM_TENANT_TYPE, tenant.TenantType },
{ ClaimConst.TENANT_NAME, tenant.Name },
{ ClaimConst.DjyCompanyId, tenant.CompId == null ? string.Empty : tenant.CompId },
{ ClaimConst.DjyUserId, user.DjyUserId },
{ ClaimConst.Tel, user.Tel },
{ ClaimConst.Phone, user.Phone },
@ -298,4 +314,93 @@ public class AuthService : IAuthService, IDynamicApiController, ITransient
{
return await Task.FromResult(_captchaHandle.CheckCode(input));
}
/// <summary>
/// 使用跳转code登录
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("/loginWithCode")]
public async Task<string> LoginWithCode(string code)
{
var cfg = _cache.GetAllSysConfig().Result.FirstOrDefault(x => x.Code == "DjyAuthUrl");
if (cfg == null || string.IsNullOrEmpty(cfg.Value))
{
throw Oops.Bah("未找到大简云授权登录URL配置请联系管理员");
}
var djyAuthUrl = cfg.Value;
if (!djyAuthUrl.EndsWith("/"))
{
djyAuthUrl += "/";
}
var loginUrl = djyAuthUrl + "user/login";
var infoUrl = djyAuthUrl + "user/info";
_logger.LogInformation($"统一登录:{loginUrl}");
//跳转登录
var result = await loginUrl
.SetBody(new { code }, "application/json")
.PostAsStringAsync();
_logger.LogInformation($"登录返回:{result}");
var jRtn = JObject.Parse(result);
if (jRtn.GetIntValue("code") == 200)
{
var jData = jRtn.GetJObjectValue("data");
var token = jData.GetStringValue("token");
var headers = new Dictionary<string, object>();
headers.Add("Authorization", $"Bearer {token}");
_logger.LogInformation($"获取登录信息:{infoUrl}");
//获取登录信息
result = await infoUrl
.SetHeaders(headers)
.GetAsStringAsync();
_logger.LogInformation($"登录信息返回:{result}");
jRtn = JObject.Parse(result);
if (jRtn.GetIntValue("code") == 200)
{
jData = jRtn.GetJObjectValue("data");
var compId = jData.GetStringValue("compId");
var comname = jData.GetStringValue("comname");
var userId = jData.GetStringValue("gid");
var showname = jData.GetStringValue("showname");
var tenant = _sysTenantRep.AsQueryable().Filter(null, true).First(x => x.CompId == compId);
if (tenant == null)
{
throw Oops.Bah($"{comname}不存在,请先完成公司认证!");
}
var user = _sysUserRep.AsQueryable().Filter(null, true).First(u => u.DjyUserId == userId);
if (tenant == null)
{
throw Oops.Bah($"{showname}不存在,请先加入公司{comname}");
}
return await GetLoginToken(user, tenant);
}
else
{
throw Oops.Bah(jRtn.GetStringValue("message"));
}
}
else
{
throw Oops.Bah(jRtn.GetStringValue("message"));
}
}
}

Loading…
Cancel
Save