using Furion.DatabaseAccessor;
|
using Furion.DependencyInjection;
|
using Furion.DynamicApiController;
|
using Furion.FriendlyException;
|
using Mapster;
|
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.EntityFrameworkCore;
|
using System.Linq.Dynamic.Core;
|
using System.Text;
|
using System.Web;
|
using Admin.NET.Core;
|
using Yitter.IdGenerator;
|
using StackExchange.Redis;
|
|
namespace Admin.NET.Application
|
{
|
/// <summary>
|
/// 任务管理服务
|
/// </summary>
|
[ApiDescriptionSettings("仓库作业", Name = "WmsTask", Order = 102)]
|
[Route("api/[Controller]")]
|
public class WmsTaskService : IDynamicApiController, ITransient
|
{
|
private readonly IRepository<SysDictType, MasterDbContextLocator> _sysDictTypeRep;
|
private readonly IRepository<SysDictData, MasterDbContextLocator> _sysDictDataRep;
|
private readonly IRepository<WmsTask, MasterDbContextLocator> _wmsTaskRep;
|
private readonly IRepository<WmsWarehouseEntrance, MasterDbContextLocator> _wmsWarehouseEntranceRep;
|
private readonly IRepository<WmsPlace, MasterDbContextLocator> _wmsPlaceRep;
|
private readonly IRepository<WmsOrder, MasterDbContextLocator> _wmsOrderRep;
|
private readonly IRepository<WmsOrderDetails, MasterDbContextLocator> _wmsOrderDetailsRep;
|
private readonly IRepository<WmsContainerPlace, MasterDbContextLocator> _wmsContainerPlaceRep;
|
private readonly IRepository<WmsMaterialStock, MasterDbContextLocator> _wmsMaterialStockRep;
|
private readonly IRepository<WmsContainer, MasterDbContextLocator> _wmsContainerRep;
|
private readonly IRepository<WmsMaterialContainer, MasterDbContextLocator> _wmsMaterialContainerRep;
|
private readonly IRepository<WmsArea, MasterDbContextLocator> _wmsAreaRep;
|
private readonly ISysExcelTemplateService _sysExcelTemplateService;
|
private readonly static object _lock = new();
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public WmsTaskService(
|
IRepository<SysDictType, MasterDbContextLocator> sysDictTypeRep,
|
IRepository<SysDictData, MasterDbContextLocator> sysDictDataRep,
|
IRepository<WmsTask, MasterDbContextLocator> wmsTaskRep,
|
IRepository<WmsWarehouseEntrance, MasterDbContextLocator> wmsWarehouseEntranceRep,
|
IRepository<WmsOrder, MasterDbContextLocator> wmsOrderRep,
|
IRepository<WmsOrderDetails, MasterDbContextLocator> wmsOrderDetailsRep,
|
IRepository<WmsPlace, MasterDbContextLocator> wmsPlaceRep,
|
IRepository<WmsContainerPlace, MasterDbContextLocator> wmsContainerPlaceRep,
|
IRepository<WmsMaterialStock, MasterDbContextLocator> wmsMaterialStockRep,
|
IRepository<WmsContainer, MasterDbContextLocator> wmsContainerRep,
|
IRepository<WmsMaterialContainer, MasterDbContextLocator> wmsMaterialContainerRep,
|
IRepository<WmsArea, MasterDbContextLocator> wmsAreaRep,
|
ISysExcelTemplateService sysExcelTemplateService
|
)
|
{
|
_sysDictTypeRep = sysDictTypeRep;
|
_sysDictDataRep = sysDictDataRep;
|
_wmsTaskRep = wmsTaskRep;
|
_wmsWarehouseEntranceRep = wmsWarehouseEntranceRep;
|
_wmsOrderRep = wmsOrderRep;
|
_wmsOrderDetailsRep = wmsOrderDetailsRep;
|
_wmsPlaceRep = wmsPlaceRep;
|
_wmsContainerPlaceRep = wmsContainerPlaceRep;
|
_wmsMaterialStockRep = wmsMaterialStockRep;
|
_wmsContainerRep = wmsContainerRep;
|
_wmsMaterialContainerRep = wmsMaterialContainerRep;
|
_wmsAreaRep= wmsAreaRep;
|
_sysExcelTemplateService = sysExcelTemplateService;
|
}
|
|
/// <summary>
|
/// 分页查询出入库任务管理
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("page")]
|
public async Task<PageResult<TaskOutput>> Page([FromQuery] WmsTaskSearch input)
|
{
|
var wmsTasks = await _wmsTaskRep.DetachedEntities
|
.Where(u => u.AreaName.Contains("绝缘立库"))
|
.Where(!string.IsNullOrEmpty(input.TaskNo), u => EF.Functions.Like(u.TaskNo, $"%{input.TaskNo.Trim()}%"))
|
.Where(input.TaskModel != null, u => u.TaskModel == input.TaskModel)
|
.Where(input.TaskType != null, u => u.TaskType == input.TaskType)
|
.Where(input.TaskStatus != null, u => u.TaskStatus == input.TaskStatus)
|
.Where(!string.IsNullOrEmpty(input.ContainerCode), u => EF.Functions.Like(u.ContainerCode, $"%{input.ContainerCode.Trim()}%"))
|
.Where(!string.IsNullOrEmpty(input.AreaName), u => u.AreaName == input.AreaName)
|
.Where(!string.IsNullOrEmpty(input.OrderNo), u => EF.Functions.Like(u.OrderNo, $"%{input.OrderNo.Trim()}%"))
|
.Where(!string.IsNullOrEmpty(input.SourcePlace), u => EF.Functions.Like(u.SourcePlace, $"%{input.SourcePlace.Trim()}%"))
|
.Where(!string.IsNullOrEmpty(input.ToPlace), u => EF.Functions.Like(u.ToPlace, $"%{input.ToPlace.Trim()}%"))
|
.Where(input.Aisle != null, u => u.Aisle == input.Aisle)
|
.OrderBy(PageInputOrder.OrderBuilder(input))
|
.ProjectToType<TaskOutput>()
|
.ToADPagedListAsync(input.PageNo, input.PageSize);
|
return wmsTasks;
|
}
|
|
/// <summary>
|
/// 不分页查询出入库任务管理列表
|
/// </summary>
|
/// <param name="input">出入库任务管理查询参数</param>
|
/// <returns>(出入库任务管理)实例列表</returns>
|
[HttpGet("listNonPage")]
|
public async Task<List<TaskOutput>> ListNonPageAsync([FromQuery] WmsTaskSearchNonPage input)
|
{
|
var pTaskNo = input.TaskNo?.Trim() ?? "";
|
var pTaskModel = input.TaskModel;
|
var pTaskType = input.TaskType;
|
var pTaskLevel = input.TaskLevel;
|
var pTaskStatus = input.TaskStatus;
|
var pIsRead = input.IsRead;
|
var pContainerCode = input.ContainerCode?.Trim() ?? "";
|
var pAreaName = input.AreaName?.Trim() ?? "";
|
var pOrderNo = input.OrderNo?.Trim() ?? "";
|
var pTaskDodeviceStatus = input.TaskDodeviceStatus;
|
var wmsTasks = await _wmsTaskRep.DetachedEntities
|
.Where(!string.IsNullOrEmpty(pTaskNo), u => EF.Functions.Like(u.TaskNo, $"%{pTaskNo}%"))
|
.Where(pTaskModel != null, u => u.TaskModel == pTaskModel)
|
.Where(pTaskType != null, u => u.TaskType == pTaskType)
|
.Where(pTaskLevel != null, u => u.TaskLevel == pTaskLevel)
|
.Where(pTaskStatus != null, u => u.TaskStatus == pTaskStatus)
|
.Where(pIsRead != null, u => u.IsRead == pIsRead)
|
.Where(!string.IsNullOrEmpty(pContainerCode), u => EF.Functions.Like(u.ContainerCode, $"%{pContainerCode}%"))
|
.Where(!string.IsNullOrEmpty(pAreaName), u => u.AreaName == pAreaName)
|
.Where(!string.IsNullOrEmpty(pOrderNo), u => EF.Functions.Like(u.OrderNo, $"%{pOrderNo}%"))
|
.Where(pTaskDodeviceStatus != null, u => u.TaskDodeviceStatus == pTaskDodeviceStatus)
|
.OrderBy(PageInputOrder.OrderNonPageBuilder(input))
|
.ProjectToType<TaskOutput>()
|
.ToListAsync();
|
return wmsTasks;
|
}
|
|
/// <summary>
|
/// 增加出入库任务管理
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("add")]
|
[NonAction]
|
public async Task Add(AddWmsTaskInput input)
|
{
|
var wmsTask = input.Adapt<WmsTask>();
|
await _wmsTaskRep.InsertAsync(wmsTask);
|
}
|
|
/// <summary>
|
/// 删除出入库任务管理
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("delete")]
|
public async Task Delete(DeleteWmsTaskInput input)
|
{
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == input.Id);
|
await _wmsTaskRep.DeleteAsync(wmsTask);
|
}
|
|
/// <summary>
|
/// 更新出入库任务管理
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("edit")]
|
public async Task Update(UpdateWmsTaskInput input)
|
{
|
var isExist = await _wmsTaskRep.AnyAsync(u => u.Id == input.Id, false);
|
if (!isExist) throw Oops.Oh(ErrorCode.D3000);
|
|
var wmsTask = input.Adapt<WmsTask>();
|
await _wmsTaskRep.UpdateAsync(wmsTask, ignoreNullValues: true);
|
}
|
|
/// <summary>
|
/// 强制完成
|
/// </summary>
|
/// <returns></returns>
|
[HttpPost("finish")]
|
[UnitOfWork]
|
public async Task Finish([FromBody] WmsTaskFinishInput input)
|
{
|
//查询任务
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == input.Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
|
// 查询混合料库区信息
|
var wmsArea = await _wmsAreaRep.FirstOrDefaultAsync(u => u.AreaName.Contains("绝缘立库"));
|
if (wmsArea == null) throw Oops.Oh("库区不存在!");
|
|
// 查询托盘信息,呼救AGV时会进行组盘操作
|
var wmsContainer = await _wmsContainerRep.FirstOrDefaultAsync(z => z.ContainerCode == wmsTask.ContainerCode);
|
if (wmsContainer == null) throw Oops.Oh("托盘不存在!");
|
|
var statusList = new List<TaskStatusEnum> { TaskStatusEnum.WEIZHIXING, TaskStatusEnum.ZHIXINGZHONG , TaskStatusEnum .DAIZHIXING};
|
if (!statusList.Contains(wmsTask.TaskStatus)) throw Oops.Oh("只有未执行和执行中的任务才能强制完成!");
|
|
if (wmsTask.TaskType == TaskType.RUKU) // 入库任务
|
{
|
// 查询库位信息 随机分配库位
|
var wmsPlace = new WmsPlace();
|
if (string.IsNullOrEmpty(wmsTask.ToPlace))
|
wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(u => u.AreaId == wmsArea.Id && u.Islock == YesOrNot.N && u.PlaceStatus == PlaceStatus.KONGXIAN);
|
else
|
wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(u => u.AreaId == wmsArea.Id && u.PlaceCode == wmsTask.ToPlace);
|
if (wmsPlace == null) throw Oops.Oh("库位不存在!");
|
if (wmsPlace.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!");
|
if (wmsPlace.PlaceStatus != PlaceStatus.KONGXIAN) throw Oops.Oh("库位已存货!");
|
// 更新库位状态为“存货”
|
wmsPlace.PlaceStatus = PlaceStatus.CUNHUO;
|
if (wmsTask.Description == "空托") wmsPlace.EmptyContainer = YesOrNot.Y; //是否空托
|
else wmsPlace.EmptyContainer = YesOrNot.N;
|
|
// 创建托盘号库位关系表
|
var wmsContainerPlaceModel = new WmsContainerPlace()
|
{
|
PlaceId = wmsPlace.Id,
|
PlaceCode = wmsPlace.PlaceCode,
|
ContainerId = wmsContainer.Id,
|
ContainerCode = wmsContainer.ContainerCode,
|
ContainerPlaceStatus = CommonStatus.ENABLE
|
};
|
await _wmsContainerPlaceRep.InsertAsync(wmsContainerPlaceModel);
|
|
// 更新库存
|
var wmsMaterialContainerList = await _wmsMaterialContainerRep.DetachedEntities
|
.Where(p => p.OrderNo ==wmsTask.OrderNo && p.BindStatus == CommonStatus.ENABLE).ProjectToType<WmsMaterialContainer>().ToListAsync();
|
|
foreach (var item in wmsMaterialContainerList)
|
{
|
var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(p => p.ContainerCode == wmsContainer.ContainerCode
|
&& p.MaterialBatch == item.MaterialBatch);
|
if (wmsMaterialStock != null)
|
{
|
wmsMaterialStock.Source = RuKuSourceEnum.KONGTUO;
|
wmsMaterialStock.AreaId = wmsPlace.AreaId;
|
wmsMaterialStock.PlaceCode = wmsPlace.PlaceCode;
|
wmsMaterialStock.StockNumber += item.BindQuantity;
|
await _wmsMaterialStockRep.UpdateAsync(wmsMaterialStock);
|
}
|
else
|
{
|
wmsMaterialStock = new WmsMaterialStock()
|
{
|
InspectionMethod = MaterialInspection.MIANJIAN,
|
UnitType = UnitType.ZHONGLIANG,
|
UnitNo = UnitNoType.T,
|
MaterialNo = item.MaterialNo,
|
MaterialType = MaterialType.CHENGPING,
|
MaterialName = item.MaterialName,
|
MaterialSpec = item.MaterialSpec,
|
MaterialBatch = item.MaterialBatch,
|
MaterialDensity = item.MaterialDensity,
|
StockNumber = 1,
|
PlaceCode = wmsPlace.PlaceCode,
|
ContainerId = wmsContainer.Id,
|
ContainerCode = wmsContainer.ContainerCode,
|
AreaId = wmsPlace.AreaId,
|
Source = RuKuSourceEnum.KONGTUO,
|
};
|
await _wmsMaterialStockRep.InsertAsync(wmsMaterialStock);
|
}
|
}
|
// 空料箱入库
|
if (wmsTask.OrderNo == "N/A")
|
{
|
var wmsMaterialStock = new WmsMaterialStock()
|
{
|
InspectionMethod = MaterialInspection.MIANJIAN,
|
UnitType = UnitType.ZHONGLIANG,
|
UnitNo = UnitNoType.T,
|
MaterialNo = "N/A",
|
MaterialType = MaterialType.KONGTUO,
|
MaterialName = "N/A",
|
MaterialSpec = "N/A",
|
MaterialBatch = "N/A",
|
MaterialDensity = "N/A",
|
StockNumber = 0,
|
PlaceCode = wmsPlace.PlaceCode,
|
ContainerId = wmsContainer.Id,
|
ContainerCode = wmsContainer.ContainerCode,
|
AreaId = wmsPlace.AreaId,
|
Source = RuKuSourceEnum.KONGTUO,
|
};
|
await _wmsMaterialStockRep.InsertAsync(wmsMaterialStock);
|
}
|
// 更新任务状态、设备任务状态、托盘编号、目标位置、库区名称
|
wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
|
wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;
|
wmsTask.ContainerCode = wmsContainer.ContainerCode;
|
wmsTask.ToPlace = wmsPlace.PlaceCode;
|
wmsTask.AreaName = wmsPlace.WmsArea.AreaName;
|
wmsTask.IsRead = true;
|
|
// 更新库位状态为存货
|
wmsPlace.PlaceStatus = PlaceStatus.CUNHUO;
|
await _wmsPlaceRep.UpdateAsync(wmsPlace);
|
|
// 更新托盘状态为“库位”
|
wmsContainer.ContainerStatus = ContainerStatus.KUWEI;
|
await _wmsContainerRep.UpdateAsync(wmsContainer);
|
}
|
else if (wmsTask.TaskType == TaskType.CHUKU) //出库任务
|
{
|
var wmsMaterialContainerList = new List<WmsMaterialContainer>();
|
// 查询库位信息
|
var wmsPlace = await _wmsPlaceRep.FirstOrDefaultAsync(u => u.PlaceCode == wmsTask.SourcePlace);
|
if (wmsPlace == null) throw Oops.Oh("库位信息不存在!");
|
if (wmsPlace.Islock == YesOrNot.Y) throw Oops.Oh("库位被锁定!");
|
//if (wmsPlace != null && wmsPlace.PlaceStatus != PlaceStatus.DAICHU) throw Oops.Oh("库位异常货!");
|
|
// 查询是否已存在托盘与库位的关系
|
var wmsContainerPlace = await _wmsContainerPlaceRep.FirstOrDefaultAsync(z => z.PlaceId == wmsPlace.Id && z.PlaceCode == wmsPlace.PlaceCode
|
&& z.ContainerCode == wmsTask.ContainerCode && z.ContainerPlaceStatus == CommonStatus.ENABLE);
|
if (wmsContainerPlace == null) throw Oops.Oh("库位容器关系不存在!");
|
|
// 不是空托才会有组盘关系
|
if (wmsPlace.EmptyContainer == YesOrNot.N)
|
{
|
// 检查物料与空托号关系
|
wmsMaterialContainerList = await _wmsMaterialContainerRep.Where(p => p.ContainerCode == wmsContainer.ContainerCode && p.BindStatus == CommonStatus.ENABLE).ToListAsync();
|
if (wmsMaterialContainerList.Count <= 0) throw Oops.Oh("托盘号与物料关系不存在!");
|
|
}
|
else
|
{
|
// 更新空料箱库存
|
var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(u => u.ContainerCode == wmsContainer.ContainerCode);
|
if (wmsMaterialStock.Source == RuKuSourceEnum.KONGTUO)
|
{
|
await _wmsMaterialStockRep.DeleteAsync(wmsMaterialStock);
|
}
|
}
|
|
//构建出库物料和周转箱号关系
|
var orderNo = "N/A";
|
if (wmsMaterialContainerList.Count > 0) orderNo = YitIdHelper.NextId().ToString();
|
|
foreach (var wmsMaterialContaine in wmsMaterialContainerList)
|
{
|
//更新状态为”删除“
|
wmsMaterialContaine.BindStatus = CommonStatus.DELETED;
|
await _wmsMaterialContainerRep.UpdateNowAsync(wmsMaterialContaine);
|
|
//新增组盘绑定记录 正常
|
var addWmsMaterialContainer = wmsMaterialContaine;
|
addWmsMaterialContainer.Id = YitIdHelper.NextId();
|
addWmsMaterialContainer.OrderNo = orderNo;
|
addWmsMaterialContainer.BindStatus = CommonStatus.ENABLE;
|
await _wmsMaterialContainerRep.InsertNowAsync(addWmsMaterialContainer);
|
// 这里没有分拣操作直接更新库存信息
|
var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(u => u.ContainerCode == wmsMaterialContaine.ContainerCode);
|
wmsMaterialStock.PlaceCode = "N/A";
|
wmsMaterialStock.StockNumber -= wmsMaterialContaine.BindQuantity;
|
await _wmsMaterialStockRep.UpdateAsync(wmsMaterialStock);
|
}
|
|
//更新任务状态
|
wmsTask.TaskStatus = TaskStatusEnum.WANCHENG;
|
wmsTask.TaskDodeviceStatus = TaskDodeviceStatusEnum.W;
|
wmsTask.IsRead = true;
|
|
// 禁用托盘库位关系
|
wmsContainerPlace.ContainerPlaceStatus = CommonStatus.DELETED;
|
await _wmsContainerPlaceRep.UpdateAsync(wmsContainerPlace);
|
|
// 更新库位状态为“空闲”
|
wmsPlace.PlaceStatus = PlaceStatus.KONGXIAN;
|
await _wmsPlaceRep.UpdateAsync(wmsPlace);
|
|
// 更新托盘状态为“空闲”
|
wmsContainer.ContainerStatus = ContainerStatus.KOUXIAN;
|
await _wmsContainerRep.UpdateAsync(wmsContainer);
|
}
|
else //移库任务
|
{
|
|
}
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
|
/// <summary>
|
/// 更新优先级(向上)
|
/// </summary>
|
/// <returns></returns>
|
[HttpPost("upwardTaskLevel")]
|
public async Task UpwardTaskLevel([FromBody] UpdateTaskLevelInput input)
|
{
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == input.Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
if (wmsTask.TaskStatus != TaskStatusEnum.WEIZHIXING) throw Oops.Oh("只有未执行的任务才能更新任务优先级!");
|
if(wmsTask.TaskLevel==5) throw Oops.Oh("任务已为最高级别!");
|
wmsTask.TaskLevel += 1;
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
|
/// <summary>
|
/// 更新优先级(向下)
|
/// </summary>
|
/// <returns></returns>
|
[HttpPost("downTaskLevel")]
|
public async Task DownTaskLevel([FromBody] UpdateTaskLevelInput input)
|
{
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == input.Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
if (wmsTask.TaskStatus != TaskStatusEnum.WEIZHIXING) throw Oops.Oh("只有未执行的任务才能更新任务优先级!");
|
if (wmsTask.TaskLevel == 1) throw Oops.Oh("任务已为最低级别!");
|
wmsTask.TaskLevel -= 1;
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
|
/// <summary>
|
/// 取消
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("CancelTask")]
|
public async Task CancelTask([FromBody] CancelInput input)
|
{
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == input.Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
|
if (wmsTask.TaskStatus != TaskStatusEnum.WEIZHIXING) throw Oops.Oh("只有未执行的任务才能取消任务!");
|
|
wmsTask.TaskStatus = TaskStatusEnum.QUXIAO;
|
wmsTask.IsRead=true;
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
|
|
/// <summary>
|
/// 批量取消
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("batchCancel")]
|
public async Task BatchCancel([FromBody] BatchCancelInput input)
|
{
|
int length = input.Id.Count;
|
for (int i = 0; i < length; i++)
|
{
|
long Id = input.Id[i];
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
|
if (wmsTask.TaskStatus != TaskStatusEnum.WEIZHIXING) throw Oops.Oh("只有未执行的任务才能取消任务!");
|
|
wmsTask.TaskStatus = TaskStatusEnum.QUXIAO;
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
}
|
|
/// <summary>
|
/// 批量暂停
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("batchBreak")]
|
public async Task BatchBreak([FromBody] BatchBreakInput input)
|
{
|
int length = input.Id.Count;
|
for (int i = 0; i < length; i++)
|
{
|
long Id = input.Id[i];
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
|
if (wmsTask.TaskStatus != TaskStatusEnum.WEIZHIXING) throw Oops.Oh("只有未执行的任务才能暂停任务!");
|
|
wmsTask.TaskStatus = TaskStatusEnum.ZANTING;
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
}
|
|
/// <summary>
|
/// 批量继续
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpPost("batchContinue")]
|
public async Task BatchContinue([FromBody] BatchContinueInput input)
|
{
|
int length = input.Id.Count;
|
for (int i = 0; i < length; i++)
|
{
|
long Id = input.Id[i];
|
var wmsTask = await _wmsTaskRep.FirstOrDefaultAsync(u => u.Id == Id);
|
if (wmsTask == null) throw Oops.Oh("任务不存在!");
|
|
if (wmsTask.TaskStatus != TaskStatusEnum.ZANTING) throw Oops.Oh("只有暂停的任务才能继续任务!");
|
|
wmsTask.TaskStatus = TaskStatusEnum.WEIZHIXING;
|
await _wmsTaskRep.UpdateAsync(wmsTask);
|
}
|
}
|
|
/// <summary>
|
/// 获取出入库任务管理
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("detail")]
|
public async Task<TaskOutput> Get([FromQuery] QueryeWmsTaskInput input)
|
{
|
return (await _wmsTaskRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id)).Adapt<TaskOutput>();
|
}
|
|
/// <summary>
|
/// 获取出入库任务管理列表
|
/// </summary>
|
/// <param name="input"></param>
|
/// <returns></returns>
|
[HttpGet("list")]
|
public async Task<List<TaskOutput>> List([FromQuery] TaskInput input)
|
{
|
return await _wmsTaskRep.DetachedEntities.ProjectToType<TaskOutput>().ToListAsync();
|
}
|
|
/// <summary>
|
/// Excel模板导入出入库任务管理功能
|
/// </summary>
|
/// <param name="file">Excel模板文件</param>
|
/// <param name="importExcelType">Excel导入方式</param>
|
/// <returns>导入的记录数</returns>
|
[HttpPost("fromExcel")]
|
public async Task<int> FromExcelAsync(IFormFile file, [FromQuery] ImportExcelType importExcelType)
|
{
|
int size = 200;
|
var excelTemplate = await _sysExcelTemplateService.GetByAppNameAndClassNameAndVersionAsync("WmsTask", "v2");
|
if (excelTemplate == null) throw Oops.Oh(ErrorCode.Excel002);
|
var keys = excelTemplate.UnionUniqueFields.Split(",") ?? Array.Empty<string>();
|
for (var i = 0; i < keys.Length; i++)
|
{
|
keys[i] = keys[i]?.Trim() ?? string.Empty;
|
}
|
ExcelUtil.FromExcel(file, excelTemplate.HeadStartLine, excelTemplate.DataStartLine, out List<string> headers, out List<List<object?>> data, out string sheetName);
|
List<TaskOutput> wmsTaskList = DataConvertUtil.ToObjectList(headers, data, sheetName, keys, excelTemplate?.DataStartLine ?? 2, out Dictionary<string, TaskOutput> dict);
|
List<Dictionary<string, object>> uniqueKeyValueDictList = wmsTaskList.ParseUniqueKeyValueDictList(keys.ToList(), excelTemplate?.DataStartLine ?? 2, sheetName);
|
var filters = DataConvertUtil.GetExpressionListByUniqueDict<WmsTask>(keys.ToList(), uniqueKeyValueDictList, size);
|
var selectKeys = keys.ToList();
|
if (!selectKeys.Contains("Id")) selectKeys.Add("Id");
|
var selector = DataConvertUtil.GetSelectExpressionListByUniqueDict<WmsTask, TaskOutput>(selectKeys);
|
List<WmsTask> updates = new();
|
List<WmsTask> adds = new();
|
|
lock (_lock)
|
{
|
foreach (var filter in filters)
|
{
|
var wmsTaskExistSubList = _wmsTaskRep.Where(filter).Select(selector).ToList();
|
wmsTaskExistSubList.ForEach(x =>
|
{
|
var k = DataConvertUtil.GetKey(x, keys);
|
if (dict.ContainsKey(k)) dict[k].Id = x.Id;
|
});
|
}
|
|
foreach (var wmsTask in wmsTaskList)
|
{
|
if (wmsTask.Id > 0)
|
{
|
if (importExcelType == ImportExcelType.ADD_AND_UPDATE) updates.Add(wmsTask.Adapt<WmsTask>());
|
}
|
else
|
{
|
adds.Add(wmsTask.Adapt<WmsTask>());
|
}
|
}
|
|
if (importExcelType == ImportExcelType.ADD_AND_UPDATE) updates.ForEach(x => _wmsTaskRep.Update(x));
|
|
var maxId = _wmsTaskRep.DetachedEntities.OrderByDescending(x => x.Id).Select(x => x.Id).FirstOrDefault();
|
adds.ForEach(x => x.Id = ++maxId);
|
Db.GetDbContext().Set<WmsTask>().AddRange(adds);
|
Db.GetDbContext().SaveChanges();
|
}
|
|
await Task.CompletedTask;
|
return adds.Count;
|
}
|
|
/// <summary>
|
/// 根据版本下载出入库任务管理的Excel导入模板
|
/// </summary>
|
/// <param name="version">模板版本</param>
|
/// <returns>下载的模板文件</returns>
|
[HttpGet("downloadExcelTemplate")]
|
public async Task<IActionResult> DownloadExcelTemplate([FromQuery] string version)
|
{
|
var excelTemplate = await _sysExcelTemplateService.GetByAppNameAndClassNameAndVersionAsync("WmsTask", version);
|
if (excelTemplate == null) throw Oops.Oh(ErrorCode.Excel002);
|
var path = Path.Combine(@"\", excelTemplate.TemplateFileName);
|
Stream ms = FileUtil.Download(path, excelTemplate.TemplateFileName);
|
var fileName = HttpUtility.UrlEncode($"{excelTemplate.Name}导入模板.xlsx", Encoding.GetEncoding("UTF-8"));
|
return new FileStreamResult(ms, "application/octet-stream") { FileDownloadName = fileName };
|
}
|
|
/// <summary>
|
/// 根据出入库任务管理查询参数导出Excel
|
/// </summary>
|
/// <param name="input">出入库任务管理(熟化库)查询参数</param>
|
/// <returns>导出的Excel文件</returns>
|
[HttpGet("toExcel")]
|
public async Task<IActionResult> ToExcelAsync([FromQuery] WmsTaskSearchNonPage input)
|
{
|
var wmsTaskList = await ListNonPageAsync(input);
|
MemoryStream ms = new();
|
DataConvertUtil.ToExcelData(wmsTaskList, _sysDictTypeRep, _sysDictDataRep, out List<string> headers,
|
out List<List<object>> data, out string sheetName);
|
var excelTemplate = await _sysExcelTemplateService.GetByAppNameAndClassNameAndVersionAsync("WmsTask", "v1");
|
if (excelTemplate != null)
|
{
|
ExcelUtil.ToExcel(excelTemplate.TemplateFileName, headers, data, sheetName, excelTemplate.HeadStartLine, excelTemplate.DataStartLine, ms);
|
}
|
else
|
{
|
ExcelUtil.ToExcel(headers, data, sheetName, ms);
|
}
|
ms.Position = 0;
|
var fileName = HttpUtility.UrlEncode($"{sheetName}[{DateTimeOffset.Now:yyyy-MM-dd}].xlsx", Encoding.GetEncoding("UTF-8"));
|
return new FileStreamResult(ms, "application/octet-stream") { FileDownloadName = fileName };
|
}
|
}
|
}
|