引入订舱:查询可用的舱位及箱子接口

optimize
zhangxiaofeng 11 months ago
parent f66f83c6d7
commit 18029a5771

@ -226,6 +226,96 @@ namespace Myshipping.Application
//更新库存
await _publisher.PublishAsync(new ChannelEventSource("BookingSlotStock:Update", input));
}
/// <summary>
/// 查询可用的舱位及箱子
/// </summary>
[HttpGet("/BookingSlot/getAvailableSlots")]
public async Task<List<BookingSlotAvailableDto>> GetAvailableSlots([FromQuery] BookingSlotBaseDto input)
{
string[] ctnCodeList = null;
if (!string.IsNullOrEmpty(input.CTN_STAT))
{
ctnCodeList = input.CTN_STAT.Split(',');
}
// 1. 【舱位基础表】与【箱子表】做关联并根据【舱位主键】、【箱型】做分组统计出【总的箱量】作为queryable1
var queryable1 = _repBase.Context.Queryable<BookingSlotBase, BookingSlotCtn>((bas, ctn) => bas.Id == ctn.SLOT_ID)
.WhereIF(!string.IsNullOrEmpty(input.PORTLOAD), bas => bas.PORTLOAD.Contains(input.PORTLOAD))
.WhereIF(!string.IsNullOrEmpty(input.PORTDISCHARGE), bas => bas.PORTLOAD.Contains(input.PORTLOAD))
.WhereIF(!string.IsNullOrEmpty(input.VESSEL), bas => bas.VESSEL.Contains(input.VESSEL))
.WhereIF(!string.IsNullOrEmpty(input.VOYNO), bas => bas.VOYNO.Contains(input.VOYNO))
.WhereIF(!string.IsNullOrEmpty(input.CARRIAGE_TYPE), bas => bas.CARRIAGE_TYPE == input.CARRIAGE_TYPE)
.WhereIF(!string.IsNullOrEmpty(input.BOOKING_SLOT_TYPE), bas => bas.BOOKING_SLOT_TYPE == input.BOOKING_SLOT_TYPE)
.WhereIF(ctnCodeList != null, (bas, ctn) => ctnCodeList.Contains(ctn.CTNCODE))
.GroupBy((bas, ctn) => new
{
bas.Id,
ctn.CTNCODE
})
.Select((bas, ctn) => new
{
id = bas.Id,
ctnCode = ctn.CTNCODE,
numAll = SqlFunc.AggregateSum(ctn.CTNNUM)
})
.MergeTable();
// 2. 【已引入舱位表】与【已使用的箱子表】做关联并根据【舱位主键】、【箱型】做分组统计出【已使用的箱量】作为queryable2
var queryable2 = _repBase.Context.Queryable<BookingSlotAllocation, BookingSlotAllocationCtn>((alc, ctn) => alc.Id == ctn.SLOT_ALLOC_ID)
.GroupBy((alc, ctn) => new
{
alc.BOOKING_SLOT_ID,
ctn.CTNCODE
})
.Select((alc, ctn) => new
{
id = alc.BOOKING_SLOT_ID,
ctnCode = ctn.CTNCODE,
numUse = SqlFunc.AggregateSum(ctn.CTNNUM)
})
.MergeTable();
// 3. 将queryable1 左连接 queryable2使用【总的箱量】减去【已使用的箱量】得到【剩余的箱量】添加【剩余的箱量】> 0 的条件作为queryable3
var queryable3 = queryable1.LeftJoin(queryable2, (q1, q2) => q1.id == q2.id && q1.ctnCode == q2.ctnCode)
.Select((q1, q2) => new
{
q1.id,
q1.ctnCode,
numResidue = SqlFunc.IsNull(q1.numAll - q2.numUse, q1.numAll)
})
.MergeTable()
.Where(r => r.numResidue > 0);
// 4. 执行ToList(),得到可用的【舱位主键】、【箱型】、【箱量】列表
var canUselist = await queryable3.ToListAsync();
// 查询舱位列表
var baseIdList = canUselist.Select(c => c.id);
List<BookingSlotBase> baseList = await _repBase.AsQueryable()
.Where(u => baseIdList.Contains(u.Id))
.ToListAsync();
List<Core.Entity.CodeCtn> ctnCodeCache = await _cache.GetAllCodeCtn();
// 构建结果
List<BookingSlotAvailableDto> result = baseList.Adapt<List<BookingSlotAvailableDto>>();
foreach (var item in result)
{
var ctnList = canUselist.Where(c => c.id == item.Id).ToList();
if (ctnList?.Any() == true)
{
item.CtnList = ctnList.Select(c => new BookingSlotCtnDto()
{
CTNCODE = c.ctnCode,
CTNNUM = c.numResidue,
CTNALL = ctnCodeCache.FirstOrDefault(e => e.Code == c.ctnCode)?.Name ?? throw new Exception($"舱位信息中存在未收录的箱型:{c.ctnCode},需要在箱型字典中补充"),
}).ToList();
}
}
return result;
}
#endregion
}
}

@ -298,4 +298,15 @@ namespace Myshipping.Application.Service.BookingSlot.Dto
/// </summary>
public string UpdatedUserName { get; set; }
}
/// <summary>
/// 查询可用舱位信息Dto
/// </summary>
public class BookingSlotAvailableDto: BookingSlotBaseDto
{
/// <summary>
/// 舱位箱信息
/// </summary>
public List<BookingSlotCtnDto> CtnList { get; set; }
}
}

Loading…
Cancel
Save