first commit
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
[*.cs]
|
||||
|
||||
# CS8618: 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
|
||||
dotnet_diagnostic.CS8618.severity = none
|
||||
|
||||
# CS8600: 将 null 字面量或可能为 null 的值转换为非 null 类型。
|
||||
dotnet_diagnostic.CS8600.severity = none
|
||||
|
||||
# CA1305: 指定 IFormatProvider
|
||||
dotnet_diagnostic.CA1305.severity = none
|
||||
@@ -0,0 +1,24 @@
|
||||
bin/
|
||||
**/*/bin/
|
||||
.vs/
|
||||
Debug/
|
||||
Release/
|
||||
Build/
|
||||
obj/
|
||||
/ACS/Properties/PublishProfiles/FolderProfile.pubxml
|
||||
/ACS/Properties/PublishProfiles/FolderProfile.pubxml.user
|
||||
/JSMachine.PrintACS.Windows/JSMachine.PrintACS.Windows.csproj.user
|
||||
/JSMachine.PrintACS.Windows/ACS_Logs
|
||||
ACS_Logs/
|
||||
/JSMachine.PrintACS.Windows/Properties/PublishProfiles/FolderProfile.pubxml.user
|
||||
/JSMachine.PrintACS.Windows/Properties/PublishProfiles
|
||||
/JSMachine.PrintACS.Authorization/tempkey.jwk
|
||||
/JSMachine.PrintACS.Authorization/tempkey.jwk
|
||||
PublishProfiles
|
||||
/JSMachine.PaperMES.Authorization/JSMachine.PaperMES.Authorization.csproj.user
|
||||
/JSMachine.PaperMES.WebHost/JSMachine.PaperMES.WebHost.csproj.user
|
||||
/JSMachine.PaperMES.PaperPreparation/JSMachine.PaperMES.PaperPreparation.csproj.user
|
||||
/JSMachine.PaperMES.PaperReturn/JSMachine.PaperMES.PaperReturn.csproj.user
|
||||
/JSMachine.PaperMES.PaperPreparation.Modules/FodyWeavers.xml
|
||||
/JSMachine.PaperMES.PaperPreparation.Modules/FodyWeavers.xsd
|
||||
/JSMachine.PaperMES.PaperFeed/JSMachine.PaperMES.PaperFeed.csproj.user
|
||||
@@ -0,0 +1,135 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class AGVTaskDto: BindableBase, IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ErpTaskId
|
||||
/// </summary>
|
||||
public Guid ErpTaskId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 合格证号
|
||||
/// </summary>
|
||||
public string BarCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料名称
|
||||
/// </summary>
|
||||
public string MateriaName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料类型
|
||||
/// </summary>
|
||||
public string MateriaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单个托盘上面的物料数量
|
||||
/// </summary>
|
||||
public int MateriaNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 批次号的生成规则为: 作业单号+日期+班次
|
||||
/// </summary>
|
||||
public string MateriaBatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料编号
|
||||
/// </summary>
|
||||
public string MateriaCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联动线出口,机械手设备唯一号
|
||||
/// </summary>
|
||||
public string EquipmentNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工单状态 1:生成任务 2:开始执行 3:第一次暂停 4:执行第二段 5:第二次暂停 6:执行第三段 7:执行成功 -1:任务取消
|
||||
/// </summary>
|
||||
public TaskStatusEnum TaskStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public TaskTypeEnum TaskType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public PriorityEnum Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 楼层
|
||||
/// </summary>
|
||||
public FloorEnum Floor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起点(库位编号)
|
||||
/// </summary>
|
||||
public string StartPositionCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 终点(库位编号)
|
||||
/// </summary>
|
||||
public string EndPositionCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最终出库码头位置(仅对出库任务有效) 1:北区 2:南区 3:人工 4:退货到车间 99:其它
|
||||
/// </summary>
|
||||
public TransportEnum Transport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务是否锁定(在锁定的情况下agvtask暂时不向rcs发送命令,待解锁后才可以,例如入库二楼提升机出口任务,如果托盘还未到出口则该任务还不能执行)
|
||||
/// </summary>
|
||||
public bool IsLock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp数据上传状态
|
||||
/// </summary>
|
||||
public ErpUploadStatusEnum ErpUploadStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp返回错误信息
|
||||
/// </summary>
|
||||
public string ErpReturnMsg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 重试次数
|
||||
/// </summary>
|
||||
public int RetryNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分组Id
|
||||
/// </summary>
|
||||
public Guid GroupId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务信息(生成失败提示等)
|
||||
/// </summary>
|
||||
public string TaskMsg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Infrastructure.LambdaHelp;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Bo
|
||||
{
|
||||
/// <summary>
|
||||
/// 全文搜索分页查询条件
|
||||
/// </summary>
|
||||
public class FullTextSearchByPageConditionBo
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前页
|
||||
/// </summary>
|
||||
public int CurrentPage { get; set; }
|
||||
/// <summary>
|
||||
/// 每页显示的条数
|
||||
/// </summary>
|
||||
public int PageSize { get; set; }
|
||||
/// <summary>
|
||||
/// 要排序的字段
|
||||
/// </summary>
|
||||
public string OrderByFiled { get; set; }
|
||||
/// <summary>
|
||||
///排序方式
|
||||
/// </summary>
|
||||
public OrderByType OrderByType { get; set; }
|
||||
/// <summary>
|
||||
/// 全文搜索类型
|
||||
/// </summary>
|
||||
public FullTextSearchType FullTextSearchType { get; set; }
|
||||
/// <summary>
|
||||
/// 关键字
|
||||
/// </summary>
|
||||
public string KeyWords { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public sealed class DeviceStateDto
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC连接状态
|
||||
/// </summary>
|
||||
public bool PLCConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// PLC是否显示
|
||||
/// </summary>
|
||||
public bool PLCVisible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// DB连接状态
|
||||
/// </summary>
|
||||
public bool DBConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// DB是否显示
|
||||
/// </summary>
|
||||
public bool DBVisible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 扫码器1连接状态
|
||||
/// </summary>
|
||||
public bool CS1Conected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 扫码器1显示状态
|
||||
/// </summary>
|
||||
public bool CS1Visible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 扫码器2连接状态
|
||||
/// </summary>
|
||||
public bool CS2Conected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 扫码器2显示状态
|
||||
/// </summary>
|
||||
public bool CS2Visible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// ERP连接状态
|
||||
/// </summary>
|
||||
public bool ERPConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// ERP显示状态
|
||||
/// </summary>
|
||||
public bool ERPVisible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// ACS连接状态
|
||||
/// </summary>
|
||||
public bool ACSConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// ACS显示状态
|
||||
/// </summary>
|
||||
public bool ACSVisible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 地磅连接状态
|
||||
/// </summary>
|
||||
public bool WBConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 地磅显示状态
|
||||
/// </summary>
|
||||
public bool WBVisible { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 打印机连接状态
|
||||
/// </summary>
|
||||
public bool PrintConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 打印机显示状态
|
||||
/// </summary>
|
||||
public bool PrintVisible { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 进纸端Wifi连接状态
|
||||
/// </summary>
|
||||
public bool WifiConected { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 进纸端Wifi显示状态
|
||||
/// </summary>
|
||||
public bool WifiVisible { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class ERPTaskDto: IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库位编号(起点)
|
||||
/// </summary>
|
||||
public string StorageRackNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生产退库单号
|
||||
/// </summary>
|
||||
public string ProduceReturnCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 销售单号
|
||||
/// </summary>
|
||||
public string SaleNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 销售退库单号
|
||||
/// </summary>
|
||||
public string SaleReturnCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 合格证号
|
||||
/// </summary>
|
||||
public string BarCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料名称
|
||||
/// </summary>
|
||||
public string MateriaName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料类型
|
||||
/// </summary>
|
||||
public string MateriaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 批次号的生成规则为: 作业单号+日期+班次
|
||||
/// </summary>
|
||||
public string MateriaBatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料编号
|
||||
/// </summary>
|
||||
public string MateriaCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联动线出口,机械手设备唯一号
|
||||
/// </summary>
|
||||
public string EquipmentNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// erp下发命令中出入库总数量
|
||||
/// </summary>
|
||||
public int ErpOrderNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务状态
|
||||
/// </summary>
|
||||
public TaskStatusEnum TaskStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public TaskTypeEnum TaskType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 楼层(入库,尾托回库指定楼层使用)
|
||||
/// </summary>
|
||||
public FloorEnum Floor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 码头位置 1:北区 2:南区 3:人工 4:退货到车间 99:其它
|
||||
/// </summary>
|
||||
public TransportEnum Transport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优先级 1:入库 10:出库 20:托盘入库 30:托盘出库 40:移库 99:其它
|
||||
/// </summary>
|
||||
public PriorityEnum Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 锁定 false:未锁定 true:锁定
|
||||
/// </summary>
|
||||
public bool IsLock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已上传给Erp的数量
|
||||
/// </summary>
|
||||
public int AlreadyUploadNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp出库撤单数量
|
||||
/// </summary>
|
||||
public int ErpCancelNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 回调Erp失败/成功 1:成功 0:失败
|
||||
/// </summary>
|
||||
public bool IsCallBackErpEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp回调Wms接口地址
|
||||
/// </summary>
|
||||
public string ErpCallWmsInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Wms回调Erp接口地址
|
||||
/// </summary>
|
||||
public string WmsCallErpInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务信息(生成失败提示等)
|
||||
/// </summary>
|
||||
public string TaskMsg {get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 提升机取货信号统计信息
|
||||
/// </summary>
|
||||
public class ElevatorCountDto : IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提升机编号(1 2)
|
||||
/// </summary>
|
||||
public int ElevatorNo { get; set; }
|
||||
/// <summary>
|
||||
/// 通道号(网带编号)
|
||||
/// </summary>
|
||||
public int ElevatorChannel { get; set; }
|
||||
/// <summary>
|
||||
/// 数量(放货口是wms实际放货的数量,取货口是PLC给的取货信号的次数,如果有货的时候重启wms会造成计数多一个)
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class ElevatorPlcQueueDto : BindableBase, IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提升机编号(1 2)
|
||||
/// </summary>
|
||||
public int ElevatorNo { get; set; }
|
||||
/// <summary>
|
||||
/// 通道号(网带编号)
|
||||
/// </summary>
|
||||
public int ElevatorChannel { get; set; }
|
||||
/// <summary>
|
||||
/// AgvTask的Id
|
||||
/// </summary>
|
||||
public Guid AgvTaskId { get; set; }
|
||||
/// <summary>
|
||||
/// 是否锁定
|
||||
/// </summary>
|
||||
public bool IsLock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
///扫码信息来源
|
||||
/// </summary>
|
||||
public enum BarCodeSource
|
||||
{
|
||||
/// <summary>
|
||||
/// 扫码器扫描
|
||||
/// </summary>
|
||||
CodeScanner = 0,
|
||||
/// <summary>
|
||||
/// 手持PDA上传
|
||||
/// </summary>
|
||||
PDA = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 回调Erp失败/成功 1:成功 0:失败
|
||||
/// </summary>
|
||||
public enum CallBackErpEndEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 失败
|
||||
/// </summary>
|
||||
fail = 0,
|
||||
/// <summary>
|
||||
/// 成功
|
||||
/// </summary>
|
||||
success = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 库位状态
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum StorageRackStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 空闲
|
||||
/// </summary>
|
||||
Empty = 0,
|
||||
/// <summary>
|
||||
/// 有货
|
||||
/// </summary>
|
||||
HaveGoods = 1,
|
||||
/// <summary>
|
||||
/// 锁定
|
||||
/// </summary>
|
||||
Locked = 2,
|
||||
/// <summary>
|
||||
/// 禁用
|
||||
/// </summary>
|
||||
Disabled = 3,
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// Erp数据上传状态
|
||||
/// </summary>
|
||||
public enum ErpUploadStatusEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 等待上传
|
||||
/// </summary>
|
||||
WaittingToUpload = 0,
|
||||
/// <summary>
|
||||
/// 上传成功
|
||||
/// </summary>
|
||||
UploadSuccess = 1,
|
||||
/// <summary>
|
||||
/// 上传失败
|
||||
/// </summary>
|
||||
UploadFailed = 2,
|
||||
/// <summary>
|
||||
/// 接口请求成功但数据被ERP拒收(可能是数据不符合ERP要求,但接口已经请求成功,此种情况系统仅做记录不处理)
|
||||
/// </summary>
|
||||
Refused = 3,
|
||||
/// <summary>
|
||||
/// 无需上传
|
||||
/// </summary>
|
||||
Unnecessary = 4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 楼层
|
||||
/// </summary>
|
||||
public enum FloorEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 一楼
|
||||
/// </summary>
|
||||
FirstFloor=10,
|
||||
/// <summary>
|
||||
/// 二楼
|
||||
/// </summary>
|
||||
SecondFloor=20
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 全文搜索类型
|
||||
/// </summary>
|
||||
public enum FullTextSearchType
|
||||
{
|
||||
/// <summary>
|
||||
/// 精准搜索
|
||||
/// </summary>
|
||||
Equals=0,
|
||||
/// <summary>
|
||||
/// 模糊匹配
|
||||
/// </summary>
|
||||
Like=1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 锁定/未锁定
|
||||
/// </summary>
|
||||
public enum LockEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 未锁定
|
||||
/// </summary>
|
||||
noLock = 0,
|
||||
/// <summary>
|
||||
/// 锁定
|
||||
/// </summary>
|
||||
locked = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
public enum PrintType
|
||||
{
|
||||
/// <summary>
|
||||
/// 新卷入库
|
||||
/// </summary>
|
||||
NewStock=0,
|
||||
/// <summary>
|
||||
/// 出库
|
||||
/// </summary>
|
||||
StockOut=1,
|
||||
/// <summary>
|
||||
/// 残卷回库
|
||||
/// </summary>
|
||||
ReStock=2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先级(参照RCS来)
|
||||
/// </summary>
|
||||
public enum PriorityEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 高
|
||||
/// </summary>
|
||||
High = 4,
|
||||
/// <summary>
|
||||
/// 中
|
||||
/// </summary>
|
||||
Middle = 6,
|
||||
/// <summary>
|
||||
/// 低
|
||||
/// </summary>
|
||||
Low = 8
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 残卷入库来源
|
||||
/// </summary>
|
||||
public enum ReStockInOriginEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 自动入库
|
||||
/// </summary>
|
||||
AutoStockIn = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 编辑补录
|
||||
/// </summary>
|
||||
HandStockIn = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 新增补录
|
||||
/// </summary>
|
||||
AddHandStockIn = 3,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 入库类型
|
||||
/// </summary>
|
||||
public enum StockInTypeEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 新卷入库
|
||||
/// </summary>
|
||||
NewStockIn = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 新卷出库
|
||||
/// </summary>
|
||||
NewStockOut = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 残卷入库
|
||||
/// </summary>
|
||||
ReStockIn = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 残卷出库
|
||||
/// </summary>
|
||||
ReStockOut = 4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 工单任务状态
|
||||
/// </summary>
|
||||
public enum TaskStatusEnum
|
||||
{
|
||||
/// <summary>
|
||||
///待执行
|
||||
/// </summary>
|
||||
[Description("待执行")]
|
||||
Initial = 0,
|
||||
/// <summary>
|
||||
/// 执行中
|
||||
/// </summary>
|
||||
[Description("执行中")]
|
||||
InExecution = 1,
|
||||
/// <summary>
|
||||
/// 执行成功
|
||||
/// </summary>
|
||||
[Description("执行成功")]
|
||||
Completed = 2,
|
||||
/// <summary>
|
||||
/// 执行失败
|
||||
/// </summary>
|
||||
[Description("执行失败")]
|
||||
Failed = 3,
|
||||
/// <summary>
|
||||
/// 暂停
|
||||
/// </summary>
|
||||
[Description("暂停")]
|
||||
Paused = 4,
|
||||
/// <summary>
|
||||
/// 取货完成
|
||||
/// </summary>
|
||||
[Description("取货完成")]
|
||||
PickupCompleted = 5,
|
||||
/// <summary>
|
||||
/// 取消
|
||||
/// </summary>
|
||||
[Description("取消")]
|
||||
Cancelled = -1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public enum TaskTypeEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 码垛入库
|
||||
/// </summary>
|
||||
[Description("码垛入库")]
|
||||
MachineHandIn = 1,
|
||||
/// <summary>
|
||||
/// PDA入库
|
||||
/// </summary>
|
||||
[Description("PDA入库")]
|
||||
PdaIn = 2,
|
||||
/// <summary>
|
||||
/// 销售出库
|
||||
/// </summary>
|
||||
[Description("销售出库")]
|
||||
SaleOut = 3,
|
||||
/// <summary>
|
||||
/// 生产退库(出库的一种,只不过生产退库目的地为退库区)
|
||||
/// </summary>
|
||||
[Description("生产退库")]
|
||||
ProductionOut = 4,
|
||||
/// <summary>
|
||||
/// 尾拖回库(流程和入库一样,但是数据不上传erp)
|
||||
/// </summary>
|
||||
[Description("尾拖回库")]
|
||||
TailIn = 5,
|
||||
/// <summary>
|
||||
/// 搬运(清除起点物料信息,更新终点物料信息)
|
||||
/// </summary>
|
||||
[Description("搬运")]
|
||||
Carry = 6,
|
||||
/// <summary>
|
||||
/// 中转入库(入库时没有可用库位,或者列被锁定,需要先进入中转区)
|
||||
/// </summary>
|
||||
[Description("中转入库")]
|
||||
TransferStockIn = 7,
|
||||
/// <summary>
|
||||
/// 中转出库(出库暂无提升机,临时进入中转区的货物,需要再次进入提升机出库,需要关联出库的erp任务)
|
||||
/// </summary>
|
||||
[Description("中转出库")]
|
||||
TransferStockOut = 8,
|
||||
/// <summary>
|
||||
/// 出库掏货(出库时前面有不同批次货物阻挡,需要将阻挡获取先运送到中转区)
|
||||
/// </summary>
|
||||
[Description("出库掏货")]
|
||||
RemoveStockOutObstruction = 9
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 码头位置
|
||||
/// </summary>
|
||||
public enum TransportEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 北区(出库区) 定义和实际和南区是反的 实际为南区
|
||||
/// </summary>
|
||||
NorthArea = 1,
|
||||
/// <summary>
|
||||
/// 南区(出库区) 定义和实际和北区是反的 实际为北区
|
||||
/// </summary>
|
||||
SouthArea = 2,
|
||||
/// <summary>
|
||||
/// 人工入库区
|
||||
/// </summary>
|
||||
ManualArea = 3,
|
||||
/// <summary>
|
||||
/// 退库区
|
||||
/// </summary>
|
||||
ReturnStockArea = 4,
|
||||
/// <summary>
|
||||
/// 中间出库区
|
||||
/// </summary>
|
||||
MiddleOutArea=5,
|
||||
/// <summary>
|
||||
/// 中转区
|
||||
/// </summary>
|
||||
TransitArea=6,
|
||||
/// <summary>
|
||||
/// 提升机库区
|
||||
/// </summary>
|
||||
Elevator =98,
|
||||
/// <summary>
|
||||
/// 正常存储库区(入库区)
|
||||
/// </summary>
|
||||
NormalArea = 99
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 企望接口记录上传状态
|
||||
/// </summary>
|
||||
public enum WantitErpUploadStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 等待上传
|
||||
/// </summary>
|
||||
WaittingToUpload = 0,
|
||||
/// <summary>
|
||||
/// 上传成功
|
||||
/// </summary>
|
||||
UploadSuccess = 1,
|
||||
/// <summary>
|
||||
/// 上传失败
|
||||
/// </summary>
|
||||
UploadFailed = 2,
|
||||
/// <summary>
|
||||
/// 接口请求成功但数据被ERP拒收(可能是数据不符合ERP要求,但接口已经请求成功,此种情况系统仅做记录不处理)
|
||||
/// </summary>
|
||||
Refused = 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public interface IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity.Enums;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.Application.Dto
|
||||
{
|
||||
public partial class OperationLogDto : IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作来源
|
||||
/// </summary>
|
||||
public OperationSource OperationSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作类型
|
||||
/// </summary>
|
||||
public OperationType OperationType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 旧对象数据
|
||||
/// </summary>
|
||||
public string OldObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 新对象数据
|
||||
/// </summary>
|
||||
public string NewObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public class PagedResultDto<T>
|
||||
{
|
||||
public static readonly PagedResultDto<T> EmptyPagedResult = new PagedResultDto<T>(0, 0, 0, 0, null);
|
||||
|
||||
#region Public Properties
|
||||
/// <summary>
|
||||
/// 总记录数
|
||||
/// </summary>
|
||||
public int TotalRecords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
public int TotalPages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每页的记录数
|
||||
/// </summary>
|
||||
public int PageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前页码
|
||||
/// </summary>
|
||||
public int PageNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置当前页码的记录
|
||||
/// </summary>
|
||||
public List<T> PageData { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public PagedResultDto()
|
||||
{
|
||||
this.PageData = new List<T>();
|
||||
}
|
||||
|
||||
public PagedResultDto(int totalRecords, int totalPages, int pageSize, int pageNumber, List<T> data)
|
||||
{
|
||||
this.TotalPages = totalPages;
|
||||
this.TotalRecords = totalRecords;
|
||||
this.PageSize = pageSize;
|
||||
this.PageNumber = pageNumber;
|
||||
this.PageData = data;
|
||||
}
|
||||
|
||||
public PagedResultDto(int totalRecords, int pageSize, int pageNumber, List<T> data)
|
||||
{
|
||||
if (pageSize > 0)
|
||||
{
|
||||
this.TotalPages = totalRecords % pageSize == 0 ? totalRecords / pageSize : totalRecords / pageSize + 1;
|
||||
}
|
||||
|
||||
this.TotalRecords = totalRecords;
|
||||
this.PageSize = pageSize;
|
||||
this.PageNumber = pageNumber;
|
||||
this.PageData = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 原纸绑定机台信息
|
||||
/// </summary>
|
||||
public class PaperBindInfoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 此条码入库重量
|
||||
/// </summary>
|
||||
public int ReceiveQty { get; set; }
|
||||
/// <summary>
|
||||
/// 材质
|
||||
/// </summary>
|
||||
public string Paper { get; set; }
|
||||
/// <summary>
|
||||
/// 供应商编号
|
||||
/// </summary>
|
||||
public string SuppID { get; set; }
|
||||
/// <summary>
|
||||
/// 条码
|
||||
/// </summary>
|
||||
public string Barcode { get; set; }
|
||||
/// <summary>
|
||||
/// 幅宽
|
||||
/// </summary>
|
||||
public string PaperWidth { get; set; }
|
||||
/// <summary>
|
||||
/// 米数(米)
|
||||
/// </summary>
|
||||
public string StockMeter { get; set; }
|
||||
public string WorkingGroup { get; set; }
|
||||
/// <summary>
|
||||
/// 入库单号
|
||||
/// </summary>
|
||||
public string ReceiveNote { get; set; }
|
||||
/// <summary>
|
||||
/// 规格型号说明
|
||||
/// </summary>
|
||||
public string StockDescription { get; set; }
|
||||
/// <summary>
|
||||
/// 克重
|
||||
/// </summary>
|
||||
public string GPerM2 { get; set; }
|
||||
/// <summary>
|
||||
/// 库区
|
||||
/// </summary>
|
||||
public string Location { get; set; }
|
||||
/// <summary>
|
||||
/// 单价
|
||||
/// </summary>
|
||||
public float UnitPrice { get; set; }
|
||||
/// <summary>
|
||||
/// 可用状态
|
||||
/// X表示不可使用
|
||||
/// NULL、空、V均表示可用
|
||||
/// </summary>
|
||||
public string CanUse { get; set; }
|
||||
/// <summary>
|
||||
/// 物料号
|
||||
/// </summary>
|
||||
public string StockItem { get; set; }
|
||||
/// <summary>
|
||||
/// 残卷标志
|
||||
/// </summary>
|
||||
public string StockMark { get; set; }
|
||||
/// <summary>
|
||||
/// 物料号
|
||||
/// </summary>
|
||||
public string StockType { get; set; }
|
||||
/// <summary>
|
||||
/// 该纸卷库存的唯一身份标记
|
||||
/// </summary>
|
||||
public string ObjID { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string GroupManagementDistributedFactoryID { get; set; }
|
||||
/// <summary>
|
||||
/// 重量(公斤)
|
||||
/// </summary>
|
||||
public string ActualQty { get; set; }
|
||||
/// <summary>
|
||||
/// 供应商简称
|
||||
/// </summary>
|
||||
public string SuppShortName { get; set; }
|
||||
/// <summary>
|
||||
/// 制造商
|
||||
/// </summary>
|
||||
public string Maker { get; set; }
|
||||
/// <summary>
|
||||
/// 库位
|
||||
/// </summary>
|
||||
public string LocSub { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ReceiveDiameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手动指定机台号
|
||||
/// </summary>
|
||||
public int HandMachineNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进纸状态(0:未进纸 1:已进纸)
|
||||
/// </summary>
|
||||
public int InPaperState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的纸质(未代纸情况下此值和实际纸质相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public string WantedPaperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的幅宽(未代纸情况下此值和实际幅宽相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public int WantedPaperWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代纸状态(0: 未代纸 1:已代纸)
|
||||
/// </summary>
|
||||
public int ReplacePaperState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的机台(未代纸情况下此值和实际机台相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public int WantedMachineNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纸质
|
||||
/// </summary>
|
||||
public string PaperMassCode { get; set; }
|
||||
/// <summary>
|
||||
/// 幅宽
|
||||
/// </summary>
|
||||
public int Web { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机台
|
||||
/// </summary>
|
||||
public int MachineNum { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 原纸绑定机台信息
|
||||
/// </summary>
|
||||
public class PaperBindNumDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 此条码入库重量
|
||||
/// </summary>
|
||||
public int ReceiveQty { get; set; }
|
||||
/// <summary>
|
||||
/// 材质
|
||||
/// </summary>
|
||||
public string Paper { get; set; }
|
||||
/// <summary>
|
||||
/// 供应商编号
|
||||
/// </summary>
|
||||
public string SuppID { get; set; }
|
||||
/// <summary>
|
||||
/// 条码
|
||||
/// </summary>
|
||||
public string Barcode { get; set; }
|
||||
/// <summary>
|
||||
/// 幅宽
|
||||
/// </summary>
|
||||
public string PaperWidth { get; set; }
|
||||
/// <summary>
|
||||
/// 米数(米)
|
||||
/// </summary>
|
||||
public string StockMeter { get; set; }
|
||||
public string WorkingGroup { get; set; }
|
||||
/// <summary>
|
||||
/// 入库单号
|
||||
/// </summary>
|
||||
public string ReceiveNote { get; set; }
|
||||
/// <summary>
|
||||
/// 规格型号说明
|
||||
/// </summary>
|
||||
public string StockDescription { get; set; }
|
||||
/// <summary>
|
||||
/// 克重
|
||||
/// </summary>
|
||||
public string GPerM2 { get; set; }
|
||||
/// <summary>
|
||||
/// 库区
|
||||
/// </summary>
|
||||
public string Location { get; set; }
|
||||
/// <summary>
|
||||
/// 单价
|
||||
/// </summary>
|
||||
public float UnitPrice { get; set; }
|
||||
/// <summary>
|
||||
/// 可用状态
|
||||
/// X表示不可使用
|
||||
/// NULL、空、V均表示可用
|
||||
/// </summary>
|
||||
public string CanUse { get; set; }
|
||||
/// <summary>
|
||||
/// 物料号
|
||||
/// </summary>
|
||||
public string StockItem { get; set; }
|
||||
/// <summary>
|
||||
/// 残卷标志
|
||||
/// </summary>
|
||||
public string StockMark { get; set; }
|
||||
/// <summary>
|
||||
/// 物料号
|
||||
/// </summary>
|
||||
public string StockType { get; set; }
|
||||
/// <summary>
|
||||
/// 该纸卷库存的唯一身份标记
|
||||
/// </summary>
|
||||
public string ObjID { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string GroupManagementDistributedFactoryID { get; set; }
|
||||
/// <summary>
|
||||
/// 重量(公斤)
|
||||
/// </summary>
|
||||
public string ActualQty { get; set; }
|
||||
/// <summary>
|
||||
/// 供应商简称
|
||||
/// </summary>
|
||||
public string SuppShortName { get; set; }
|
||||
/// <summary>
|
||||
/// 制造商
|
||||
/// </summary>
|
||||
public string Maker { get; set; }
|
||||
/// <summary>
|
||||
/// 库位
|
||||
/// </summary>
|
||||
public string LocSub { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ReceiveDiameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手动指定机台号
|
||||
/// </summary>
|
||||
public int HandMachineNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进纸状态(0:未进纸 1:已进纸)
|
||||
/// </summary>
|
||||
public int InPaperState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的纸质(未代纸情况下此值和实际纸质相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public string WantedPaperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的幅宽(未代纸情况下此值和实际幅宽相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public int WantedPaperWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代纸状态(0: 未代纸 1:已代纸)
|
||||
/// </summary>
|
||||
public int ReplacePaperState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的机台(未代纸情况下此值和实际机台相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public int WantedMachineNum { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using Prism.Mvvm;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class PaperNewStockInDto : BindableBase, IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
private string _paperLabel;
|
||||
/// <summary>
|
||||
/// 原纸卷标
|
||||
/// </summary>
|
||||
public string PaperLabel
|
||||
{
|
||||
get => _paperLabel;
|
||||
set => SetProperty(ref _paperLabel, value);
|
||||
}
|
||||
|
||||
private string _productLineName;
|
||||
/// <summary>
|
||||
/// 产线名称
|
||||
/// </summary>
|
||||
public string ProductLineName
|
||||
{
|
||||
get => _productLineName;
|
||||
set => SetProperty(ref _productLineName, value);
|
||||
}
|
||||
|
||||
private string _supplier;
|
||||
/// <summary>
|
||||
/// 供应商
|
||||
/// </summary>
|
||||
public string Supplier
|
||||
{
|
||||
get => _supplier;
|
||||
set => SetProperty(ref _supplier, value);
|
||||
}
|
||||
|
||||
private string _makerName;
|
||||
/// <summary>
|
||||
/// 制造商
|
||||
/// </summary>
|
||||
public string MakerName
|
||||
{
|
||||
get => _makerName;
|
||||
set => SetProperty(ref _makerName, value);
|
||||
}
|
||||
|
||||
private string _stockHouseName;
|
||||
/// <summary>
|
||||
/// 仓库名称
|
||||
/// </summary>
|
||||
public string StockHouseName
|
||||
{
|
||||
get => _stockHouseName;
|
||||
set => SetProperty(ref _stockHouseName, value);
|
||||
}
|
||||
|
||||
private string _stockInType;
|
||||
/// <summary>
|
||||
/// 入库类型
|
||||
/// </summary>
|
||||
public string StockInType
|
||||
{
|
||||
get => _stockHouseName;
|
||||
set => SetProperty(ref _stockHouseName, value);
|
||||
}
|
||||
|
||||
private string _locationMark;
|
||||
/// <summary>
|
||||
/// 库位
|
||||
/// </summary>
|
||||
public string LocationMark
|
||||
{
|
||||
get => _locationMark;
|
||||
set => SetProperty(ref _locationMark, value);
|
||||
}
|
||||
|
||||
private int _paperUnitWeight;
|
||||
/// <summary>
|
||||
/// 原纸克重
|
||||
/// </summary>
|
||||
public int PaperUnitWeight
|
||||
{
|
||||
get => _paperUnitWeight;
|
||||
set => SetProperty(ref _paperUnitWeight, value);
|
||||
}
|
||||
|
||||
private string _paperCode;
|
||||
/// <summary>
|
||||
/// 原纸编码(纸质)
|
||||
/// </summary>
|
||||
public string PaperCode
|
||||
{
|
||||
get => _paperCode;
|
||||
set => SetProperty(ref _paperCode, value);
|
||||
}
|
||||
|
||||
private int _paperWidth;
|
||||
/// <summary>
|
||||
/// 门幅
|
||||
/// </summary>
|
||||
public int PaperWidth
|
||||
{
|
||||
get => _paperWidth;
|
||||
set => SetProperty(ref _paperWidth, value);
|
||||
}
|
||||
|
||||
private decimal _inWeight;
|
||||
/// <summary>
|
||||
/// 入库重量
|
||||
/// </summary>
|
||||
public decimal InWeight
|
||||
{
|
||||
get => _inWeight;
|
||||
set => SetProperty(ref _inWeight, value);
|
||||
}
|
||||
|
||||
private decimal _meterLength;
|
||||
/// <summary>
|
||||
/// 米长
|
||||
/// </summary>
|
||||
public decimal MeterLength
|
||||
{
|
||||
get => _meterLength;
|
||||
set => SetProperty(ref _meterLength, value);
|
||||
}
|
||||
|
||||
private string _memo;
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Memo
|
||||
{
|
||||
get => _memo;
|
||||
set => SetProperty(ref _memo, value);
|
||||
}
|
||||
|
||||
private int _printState;
|
||||
/// <summary>
|
||||
/// 打印状态(0:未打印 1:已打印)
|
||||
/// </summary>
|
||||
public int PrintState
|
||||
{
|
||||
get => _printState;
|
||||
set => SetProperty(ref _printState, value);
|
||||
}
|
||||
|
||||
private DateTime? _printTime;
|
||||
/// <summary>
|
||||
/// 打印时间
|
||||
/// </summary>
|
||||
public DateTime? PrintTime
|
||||
{
|
||||
get => _printTime;
|
||||
set => SetProperty(ref _printTime, value);
|
||||
}
|
||||
|
||||
private DateTime? _creationTime;
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime
|
||||
{
|
||||
get => _creationTime;
|
||||
set => SetProperty(ref _creationTime, value);
|
||||
}
|
||||
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class PaperReStockInDto : BindableBase, IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
private string _paperLabel;
|
||||
/// <summary>
|
||||
/// 原纸卷标
|
||||
/// </summary>
|
||||
public string PaperLabel
|
||||
{
|
||||
get => _paperLabel;
|
||||
set => SetProperty(ref _paperLabel, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 产线名称
|
||||
/// </summary>
|
||||
public string ProductLineName { get; set; }
|
||||
|
||||
private string _supplier;
|
||||
/// <summary>
|
||||
/// 供应商
|
||||
/// </summary>
|
||||
public string Supplier
|
||||
{
|
||||
get => _supplier;
|
||||
set => SetProperty(ref _supplier, value);
|
||||
}
|
||||
|
||||
private string _makerName;
|
||||
/// <summary>
|
||||
/// 制造商
|
||||
/// </summary>
|
||||
public string MakerName
|
||||
{
|
||||
get => _makerName;
|
||||
set => SetProperty(ref _makerName, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仓库名称
|
||||
/// </summary>
|
||||
public string _stockHouseName;
|
||||
public string StockHouseName
|
||||
{
|
||||
get => _stockHouseName;
|
||||
set => SetProperty(ref _stockHouseName, value);
|
||||
}
|
||||
|
||||
private string _locationMark;
|
||||
/// <summary>
|
||||
/// 库位
|
||||
/// </summary>
|
||||
public string LocationMark
|
||||
{
|
||||
get => _locationMark;
|
||||
set => SetProperty(ref _locationMark, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入库类型
|
||||
/// </summary>
|
||||
public string StockInType { get; set; }
|
||||
|
||||
private int _paperUnitWeight;
|
||||
/// <summary>
|
||||
/// 原纸克重
|
||||
/// </summary>
|
||||
public int PaperUnitWeight
|
||||
{
|
||||
get => _paperUnitWeight;
|
||||
set => SetProperty(ref _paperUnitWeight, value);
|
||||
}
|
||||
|
||||
private string _paperCode;
|
||||
/// <summary>
|
||||
/// 原纸编码(纸质)
|
||||
/// </summary>
|
||||
public string PaperCode
|
||||
{
|
||||
get => _paperCode;
|
||||
set => SetProperty(ref _paperCode, value);
|
||||
}
|
||||
|
||||
private int _paperWidth;
|
||||
/// <summary>
|
||||
/// 门幅
|
||||
/// </summary>
|
||||
public int PaperWidth
|
||||
{
|
||||
get => _paperWidth;
|
||||
set => SetProperty(ref _paperWidth, value);
|
||||
}
|
||||
|
||||
private decimal _inWeight;
|
||||
/// <summary>
|
||||
/// 入库重量
|
||||
/// </summary>
|
||||
public decimal InWeight
|
||||
{
|
||||
get=> _inWeight;
|
||||
set => SetProperty(ref _inWeight, value);
|
||||
}
|
||||
|
||||
private decimal _meterLength;
|
||||
/// <summary>
|
||||
/// 米长
|
||||
/// </summary>
|
||||
public decimal MeterLength
|
||||
{
|
||||
get => _meterLength;
|
||||
set => SetProperty(ref _meterLength, value);
|
||||
}
|
||||
|
||||
private string _teamName;
|
||||
/// <summary>
|
||||
/// 班组
|
||||
/// </summary>
|
||||
public string TeamName
|
||||
{
|
||||
get => _teamName;
|
||||
set => SetProperty(ref _teamName, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批次Id
|
||||
/// </summary>
|
||||
public Guid? BathId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Memo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印时间
|
||||
/// </summary>
|
||||
public DateTime? PrintTime { get; set; }
|
||||
|
||||
private DateTime? _creationTime;
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime
|
||||
{
|
||||
get => _creationTime;
|
||||
set => SetProperty(ref _creationTime, value);
|
||||
}
|
||||
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源
|
||||
/// </summary>
|
||||
public ReStockInOriginEnum Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 企望接口入库记录上传状态
|
||||
/// 0-等待上传,
|
||||
///1-上传成功,
|
||||
///2-上传失败
|
||||
///3-接口请求成功但数据被ERP拒收(可能是数据不符合ERP要求,但接口已经请求成功,此种情况系统仅做记录不处理)
|
||||
/// </summary>
|
||||
public WantitErpUploadStatus WantitErpUploadStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 信息来源(0-扫码器扫描 1-手持PDA上传)
|
||||
/// </summary>
|
||||
public BarCodeSource BarCodeSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp接口调用成功,但是返回入库失败
|
||||
/// </summary>
|
||||
public string ErpStockInMsg { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Domain.Entity.Enums;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class PaperStockOutDto : BindableBase, IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ACS中的Id
|
||||
/// </summary>
|
||||
public Guid AcsId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束状态
|
||||
/// </summary>
|
||||
public int FinishState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每批所包含的全部Id
|
||||
/// </summary>
|
||||
public string Ids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 新卷残卷Id
|
||||
/// </summary>
|
||||
public Guid NewStockReStockID { get; set; }
|
||||
|
||||
private string _paperLable;
|
||||
/// <summary>
|
||||
/// 原纸卷标
|
||||
/// </summary>
|
||||
public string PaperLabel
|
||||
{
|
||||
get => _paperLable;
|
||||
set => SetProperty(ref _paperLable, value);
|
||||
}
|
||||
|
||||
private string _productLineName;
|
||||
/// <summary>
|
||||
/// 产线名称
|
||||
/// </summary>
|
||||
public string ProductLineName
|
||||
{
|
||||
get => _productLineName;
|
||||
set => SetProperty(ref _productLineName, value);
|
||||
}
|
||||
|
||||
private string _supplier;
|
||||
/// <summary>
|
||||
/// 供应商
|
||||
/// </summary>
|
||||
public string Supplier
|
||||
{
|
||||
get => _supplier;
|
||||
set => SetProperty(ref _supplier, value);
|
||||
}
|
||||
|
||||
private string _makerName;
|
||||
/// <summary>
|
||||
/// 制造商
|
||||
/// </summary>
|
||||
public string MakerName
|
||||
{
|
||||
get => _makerName;
|
||||
set => SetProperty(ref _makerName, value);
|
||||
}
|
||||
|
||||
private int _paperUnitWeight;
|
||||
/// <summary>
|
||||
/// 原纸克重
|
||||
/// </summary>
|
||||
public int PaperUnitWeight
|
||||
{
|
||||
get => _paperUnitWeight;
|
||||
set => SetProperty(ref _paperUnitWeight, value);
|
||||
}
|
||||
|
||||
private string _paperCode;
|
||||
/// <summary>
|
||||
/// 原纸编码(纸质)
|
||||
/// </summary>
|
||||
public string PaperCode
|
||||
{
|
||||
get => _paperCode;
|
||||
set => SetProperty(ref _paperCode, value);
|
||||
}
|
||||
|
||||
private int _paperWidth;
|
||||
/// <summary>
|
||||
/// 门幅
|
||||
/// </summary>
|
||||
public int PaperWidth
|
||||
{
|
||||
get => _paperWidth;
|
||||
set => SetProperty(ref _paperWidth, value);
|
||||
}
|
||||
|
||||
private decimal _outWeight;
|
||||
/// <summary>
|
||||
/// 出库重量
|
||||
/// </summary>
|
||||
public decimal OutWeight
|
||||
{
|
||||
get => _outWeight;
|
||||
set => SetProperty(ref _outWeight, value);
|
||||
}
|
||||
|
||||
private string _stockHouseName;
|
||||
/// <summary>
|
||||
/// 仓库名称
|
||||
/// </summary>
|
||||
public string StockHouseName
|
||||
{
|
||||
get => _stockHouseName;
|
||||
set => SetProperty(ref _stockHouseName, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原纸出库类型
|
||||
/// </summary>
|
||||
public string StockOutType { get; set; }
|
||||
|
||||
private decimal _meterLength;
|
||||
/// <summary>
|
||||
/// 米长
|
||||
/// </summary>
|
||||
public decimal MeterLength
|
||||
{
|
||||
get => _meterLength;
|
||||
set => SetProperty(ref _meterLength, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 机台
|
||||
/// </summary>
|
||||
public string MachineNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库位
|
||||
/// </summary>
|
||||
public string LocationMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在库(0:不在库 1:在库)
|
||||
/// </summary>
|
||||
public int InOutState { get; set; }
|
||||
|
||||
private string _memo;
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Memo
|
||||
{
|
||||
get => _memo;
|
||||
set => SetProperty(ref _memo, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 企望接口出库记录上传状态
|
||||
/// </summary>
|
||||
public WantitErpUploadStatus WantitErpUploadStatus { get; set; }
|
||||
/// <summary>
|
||||
/// 扫码信息来源
|
||||
/// </summary>
|
||||
public BarCodeSource BarCodeSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的纸质(未代纸情况下此值和实际纸质相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public string WantedPaperCode { get; set; }
|
||||
/// <summary>
|
||||
/// 需要的幅宽(未代纸情况下此值和实际幅宽相等,代纸情况下则不等)
|
||||
/// </summary>
|
||||
public int WantedPaperWidth { get; set; }
|
||||
|
||||
private DateTime? _creationTime;
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime
|
||||
{
|
||||
get => _creationTime;
|
||||
set => SetProperty(ref _creationTime, value);
|
||||
}
|
||||
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp接口调用成功,但是返回入库失败
|
||||
/// </summary>
|
||||
public string ErpStockInMsg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备纸错误状态(0:正常 1:错误)
|
||||
/// </summary>
|
||||
public PreparationErrorStateEnum PreparationErrorState { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Domain.Entity.Enums;
|
||||
using Prism.Mvvm;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class PreparationBindMachineDto: BindableBase, IRootDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键Id
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原纸卷标
|
||||
/// </summary>
|
||||
public string PaperLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 材质
|
||||
/// </summary>
|
||||
public string PaperMassCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 门幅
|
||||
/// </summary>
|
||||
public int PaperWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 米长
|
||||
/// </summary>
|
||||
public decimal MeterLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 重量
|
||||
/// </summary>
|
||||
public decimal Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库位
|
||||
/// </summary>
|
||||
public string LocationMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库区
|
||||
/// </summary>
|
||||
public string LocSub { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 供应商简称
|
||||
/// </summary>
|
||||
public string SuppShortName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原纸克重
|
||||
/// </summary>
|
||||
public int PaperUnitWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制造商
|
||||
/// </summary>
|
||||
public string Maker { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手动指定机台号
|
||||
/// </summary>
|
||||
public int HandMachineNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进纸状态(0:未进纸 1:已进纸)
|
||||
/// </summary>
|
||||
public int InPaperState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的纸质(未代纸情况下为空,代纸情况下有值)
|
||||
/// </summary>
|
||||
public string WantedPaperCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的幅宽(未代纸情况下为空,代纸情况下有值)
|
||||
/// </summary>
|
||||
public int WantedPaperWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代纸状态(0: 未代纸 1:已代纸)
|
||||
/// </summary>
|
||||
public int ReplacePaperState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 需要的机台(未代纸情况下为空,代纸情况下有值)
|
||||
/// </summary>
|
||||
public int WantedMachineNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 该纸卷库存的唯一身份标记
|
||||
/// </summary>
|
||||
public string ObjID { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using JSMachine.WMS.Domain.Repository;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// rcs系统的任务信息。模拟测试用
|
||||
/// </summary>
|
||||
public class RcsTaskDto : IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// 任务id
|
||||
/// </summary>
|
||||
public string TaskId { get; set; }
|
||||
/// <summary>
|
||||
/// wms上传时间
|
||||
/// </summary>
|
||||
public DateTime UploadTime { get; set; }
|
||||
/// <summary>
|
||||
/// 起点
|
||||
/// </summary>
|
||||
public string StartPositionCode { get; set; }
|
||||
/// <summary>
|
||||
/// 终点
|
||||
/// </summary>
|
||||
public string EndPositionCode { get; set; }
|
||||
/// <summary>
|
||||
/// 任务状态
|
||||
/// 3:已取消
|
||||
/// 5:发送失败
|
||||
/// 6:运行中
|
||||
///7:执行失败
|
||||
///8:已完成
|
||||
///9:已下发
|
||||
///10:等待确认
|
||||
///20:取货中
|
||||
///21:取货完成
|
||||
///22:放货中
|
||||
///23:放货完成
|
||||
/// 必须
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class ReAutoStockIn
|
||||
{
|
||||
/// <summary>
|
||||
/// 原纸卷标
|
||||
/// </summary>
|
||||
public string PaperLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 入库重量
|
||||
/// </summary>
|
||||
public decimal InWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扫码信息来源
|
||||
/// </summary>
|
||||
public BarCodeSource BarCodeSource { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用层数据传输对象的公共基类,提供实体标识和审计时间字段。
|
||||
/// </summary>
|
||||
public class RootDto
|
||||
{
|
||||
/// <summary>
|
||||
/// DTO 对应的实体唯一标识。
|
||||
/// </summary>
|
||||
public virtual string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据创建时间。
|
||||
/// </summary>
|
||||
public virtual DateTime CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据最后修改时间。
|
||||
/// </summary>
|
||||
public virtual DateTime LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public class SelectRowsDto
|
||||
{
|
||||
public List<PaperBindInfoDto> PaperBindInfoDtos { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public partial class StorageRackDto : IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库位编号
|
||||
/// </summary>
|
||||
public string StorageRackNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 途径提升机指定点的坐标
|
||||
/// </summary>
|
||||
public string AgvPassPointNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提升机通道号(PLC定义的网带编号),提升机库位专用
|
||||
/// </summary>
|
||||
public int? ElevatorChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否锁定
|
||||
/// </summary>
|
||||
public bool IsLock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库位状态 0-空闲 1-有货 2-锁定 3-禁用
|
||||
/// </summary>
|
||||
public StorageRackStatus Status
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsLock)
|
||||
return StorageRackStatus.Locked;
|
||||
if (IsDisabled)
|
||||
return StorageRackStatus.Disabled;
|
||||
if (!string.IsNullOrEmpty(BarCode))
|
||||
return StorageRackStatus.HaveGoods;
|
||||
|
||||
return StorageRackStatus.Empty;
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 库位名称
|
||||
/// </summary>
|
||||
public string StorageRackName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所在的库区排序
|
||||
/// </summary>
|
||||
public int AreaNumSort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库位排序(同一列的库位排序号越大越在里面(以车前进方向为准))
|
||||
/// </summary>
|
||||
public int NumSort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属库区
|
||||
/// </summary>
|
||||
public long? ReservoirAreaId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属库区列(小车进入库位的方向为列)
|
||||
/// </summary>
|
||||
public long ReservoirAreaColumnId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属楼层编号(10-一楼 20-二楼)
|
||||
/// </summary>
|
||||
public FloorEnum Floor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AGV名称
|
||||
/// </summary>
|
||||
public string MachineName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 确认时间
|
||||
/// </summary>
|
||||
public DateTime? ConfirmDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否禁用
|
||||
/// </summary>
|
||||
public bool IsDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 合格证号
|
||||
/// </summary>
|
||||
public string BarCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 客户名称
|
||||
/// </summary>
|
||||
public string CustomName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料名称
|
||||
/// </summary>
|
||||
public string MateriaName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料类型
|
||||
/// </summary>
|
||||
public string MateriaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单个托盘上的物料数量
|
||||
/// </summary>
|
||||
public int MateriaNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 批次号的生成规则为: 作业单号+日期+班次
|
||||
/// </summary>
|
||||
public string MateriaBatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料编码
|
||||
/// </summary>
|
||||
public string MateriaCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联动线出口,机械手设备唯一号
|
||||
/// </summary>
|
||||
public string EquipmentNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 码头位置 1:北区 2:南区 3:人工 4:退货到车间 99:正常存储库位
|
||||
/// </summary>
|
||||
public TransportEnum Transport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Erp回调Wms接口地址
|
||||
/// </summary>
|
||||
public string ErpCallWmsInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Wms回调Erp接口地址
|
||||
/// </summary>
|
||||
public string WmsCallErpInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 清空物料
|
||||
/// </summary>
|
||||
public void ClearMaterial()
|
||||
{
|
||||
BarCode = null;
|
||||
OrderNo = null;
|
||||
CustomName = null;
|
||||
MateriaName = null;
|
||||
MateriaType = null;
|
||||
MateriaNum = 0;
|
||||
MateriaBatch = null;
|
||||
MateriaCode = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否空白可用库位
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsEmpty()
|
||||
{
|
||||
return !this.IsLock && !this.IsDisabled && string.IsNullOrEmpty(this.BarCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空物料并解锁库位
|
||||
/// </summary>
|
||||
public void ClearMaterialAndUnLock()
|
||||
{
|
||||
ClearMaterial();
|
||||
|
||||
IsLock = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定物料信息
|
||||
/// </summary>
|
||||
public void BingdingMaterial(MateriaInfo materiaInfo)
|
||||
{
|
||||
BarCode = materiaInfo.BarCode;
|
||||
OrderNo = materiaInfo.OrderNo;
|
||||
MateriaName = materiaInfo.MateriaName;
|
||||
MateriaType = materiaInfo.MateriaType;
|
||||
MateriaNum = int.Parse(materiaInfo.MateriaNum);
|
||||
MateriaBatch = materiaInfo.MateriaBatch;
|
||||
MateriaCode = materiaInfo.MateriaCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定物料信息并锁定库位
|
||||
/// </summary>
|
||||
public void BingdingMaterialAndLock(MateriaInfo materiaInfo)
|
||||
{
|
||||
BingdingMaterial(materiaInfo);
|
||||
|
||||
IsLock = true;
|
||||
}
|
||||
|
||||
public class StorageRackDtoIEqualityComparer : IEqualityComparer<StorageRackDto>
|
||||
{
|
||||
public bool Equals(StorageRackDto? x, StorageRackDto? y)
|
||||
{
|
||||
return x.StorageRackNo == y.StorageRackNo;
|
||||
}
|
||||
|
||||
public int GetHashCode([DisallowNull] StorageRackDto obj)
|
||||
{
|
||||
return obj.StorageRackNo.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class MateriaInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 合格证号
|
||||
/// </summary>
|
||||
public string BarCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工单号
|
||||
/// </summary>
|
||||
public string OrderNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料名称
|
||||
/// </summary>
|
||||
public string MateriaName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料类型
|
||||
/// </summary>
|
||||
public string MateriaType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料数量
|
||||
/// </summary>
|
||||
public string MateriaNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 批次号
|
||||
/// </summary>
|
||||
public string MateriaBatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 物料编码
|
||||
/// </summary>
|
||||
public string MateriaCode { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
public class UserInfoDto : IRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// 账号
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime? CreationTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime? LastModifiedTime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 企望Erp上传状态
|
||||
/// </summary>
|
||||
public partial class WantitErpUploadStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态代码
|
||||
/// </summary>
|
||||
public int StatusCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态描述
|
||||
/// </summary>
|
||||
public string StatusDes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV 任务应用服务,负责任务数据的转换、持久化以及状态更新。
|
||||
/// </summary>
|
||||
public interface IAGVTaskService: IBaseService<AGVTaskDto, AGVTask>
|
||||
{
|
||||
/// <summary>
|
||||
/// 仅更新 AGV 任务的状态和修改时间,避免覆盖任务的其他字段。
|
||||
/// </summary>
|
||||
/// <param name="agvTask">包含任务标识和目标状态的任务 DTO。</param>
|
||||
/// <returns>数据库更新成功返回 <see langword="true"/>,否则返回 <see langword="false"/>。</returns>
|
||||
public Task<bool> UpdateAgvTaskStatus(AGVTaskDto agvTask);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using JSMachine.WMS.Domain.Repository;
|
||||
using SqlSugar;
|
||||
using System.Data;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IBaseService<TDTO, TAggregateRoot>
|
||||
where TAggregateRoot : AggregateRoot, IAggregateRoot
|
||||
where TDTO : IRootDto
|
||||
{
|
||||
#region Add
|
||||
/// <summary>
|
||||
/// 添加单个实体
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Add(TDTO entity, SqlSugarScope sqlSugarScope=null);
|
||||
/// <summary>
|
||||
/// 添加单个实体
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="ignoreColumns">要忽略的字段</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Add(TDTO dto, params string[] ignoreColumns);
|
||||
/// <summary>
|
||||
/// 批量插入实体
|
||||
/// </summary>
|
||||
/// <param name="entities"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Add(List<TDTO> entities);
|
||||
|
||||
/// <summary>
|
||||
/// 字典方式添加单个实体
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名称</param>
|
||||
/// <param name="dic"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Add(string tableName, Dictionary<string, object> dic);
|
||||
/// <summary>
|
||||
/// 添加之前判断指定字段是否存在,不存在则添加
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> AddIfNotExist(TDTO entity, Expression<Func<TDTO, bool>> expression);
|
||||
#endregion
|
||||
|
||||
#region Delete
|
||||
/// <summary>
|
||||
/// 根据Id删除记录
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> DeleteById(Guid id, SqlSugarScope sqlSugarScope=null);
|
||||
|
||||
/// <summary>
|
||||
/// 根据Id批量删除
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> DeleteBatch(Guid[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// 根据实体删除
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> DeleteByEntity(TDTO aggregateRoot);
|
||||
/// <summary>
|
||||
/// 根据实体批量删除
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoots"></param>
|
||||
/// <returns>受影响行数不等于实体数量视为删除失败</returns>
|
||||
Task<bool> DeleteByEntity(List<TDTO> aggregateRoot);
|
||||
|
||||
/// <summary>
|
||||
/// 根据条件删除
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> DeleByExpression(Expression<Func<TAggregateRoot, bool>> expression);
|
||||
#endregion
|
||||
|
||||
#region Edit
|
||||
/// <summary>
|
||||
/// 更改单个实体
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditSingal(TDTO aggregateRoot);
|
||||
|
||||
/// <summary>
|
||||
/// 更改单个实体但忽略指定的列
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <param name="ignoredColumns">忽略指定的条件</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditSingal(TDTO aggregateRoot, Expression<Func<TDTO, object>> ignoredColumns);
|
||||
|
||||
/// <summary>
|
||||
/// 更改单个实体但忽略指定的列
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <param name="ignoredColumns">要忽略的列名</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditSingal(TDTO aggregateRoot, string[] ignoredColumns);
|
||||
|
||||
/// <summary>
|
||||
/// 更改单个实体中指定的列
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <param name="columns">要更改的列名</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditSingalWithSpecificCols(TDTO aggregateRoot, string[] columns);
|
||||
|
||||
/// <summary>
|
||||
/// 批量更新
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoots"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditBatch(List<TDTO> aggregateRoots);
|
||||
|
||||
/// <summary>
|
||||
/// 快速批量更新
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoots"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditBatchFast(List<TDTO> aggregateRoots);
|
||||
|
||||
/// <summary>
|
||||
/// 字典方式更改
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="dic"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditByDic(string tableName, Dictionary<string, object> dic);
|
||||
|
||||
/// <summary>
|
||||
/// 字典方式批量更改
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="dic"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> EditByDic(string tableName, List<Dictionary<string, object>> dic);
|
||||
#endregion
|
||||
|
||||
#region Query
|
||||
/// <summary>
|
||||
/// 查询所有
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetAll();
|
||||
/// <summary>
|
||||
/// 查询所有
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetAll(string orderByFiled, OrderByType orderByType);
|
||||
/// <summary>
|
||||
/// 分片查询所有
|
||||
/// </summary>
|
||||
/// <param name="fragmentSize">分片大小,分片越大效率越高,但是占用的内存也越大,需要合理考虑数据量和硬件性能确定此参数大小</param>
|
||||
/// <returns></returns>
|
||||
|
||||
Task<List<TDTO>> GetAllFragment(int fragmentSize = 50000);
|
||||
|
||||
/// <summary>
|
||||
/// 分片查询所有(带排序功能)
|
||||
/// </summary>
|
||||
/// <param name="orderByFiled">要排序的字段</param>
|
||||
/// <param name="orderByType">排序方式</param>
|
||||
/// <param name="fragmentSize">分片大小,分片越大效率越高,但是占用的内存也越大,需要合理考虑数据量和硬件性能确定此参数大小</param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetAllFragment(string orderByFiled, OrderByType orderByType, int fragmentSize = 200);
|
||||
|
||||
/// <summary>
|
||||
/// 根据条件查询数量
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Count(Expression<Func<TDTO, bool>> expression);
|
||||
|
||||
/// <summary>
|
||||
/// 根据主键查询
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
Task<TDTO> QueryByKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 查询满足条件的第一个
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
Task<TDTO> GetSingalByExpression(Expression<Func<TDTO, bool>> expression);
|
||||
|
||||
/// <summary>
|
||||
/// 查询满足条件的第一个(带排序)
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <param name="orderByExpress"></param>
|
||||
/// <param name="orderByType"></param>
|
||||
/// <returns></returns>
|
||||
Task<TDTO> GetSingalByExpression(
|
||||
Expression<Func<TDTO, bool>> expression,
|
||||
Expression<Func<TAggregateRoot, object>> orderByExpress,
|
||||
OrderByType orderByType);
|
||||
|
||||
/// <summary>
|
||||
/// 查询满足条件的所有实体
|
||||
/// 注意 在oracle数据中时间段范围查询请使用 SqlFunc.Oracle_ToDate,可大幅提高查询速度
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetListByExpression(Expression<Func<TDTO, bool>> expression);
|
||||
/// <summary>
|
||||
/// 查询满足条件的所有实体(带排序功能)
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <param name="filedName"></param>
|
||||
/// <param name="orderByType"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetListByExpression(Expression<Func<TAggregateRoot, bool>> expression,
|
||||
string filedName,
|
||||
OrderByType orderByType = OrderByType.Desc);
|
||||
|
||||
/// <summary>
|
||||
/// 通过实体查询满足条件的数据
|
||||
/// </summary>
|
||||
/// <param name="aggregateRoot"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetListWhereClass(TDTO dto);
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="pageIndex">当前页码</param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalCount">总记录条数</param>
|
||||
/// <param name="expression">查询条件</param>
|
||||
/// <returns></returns>
|
||||
Task<PagedResult<TDTO>> QueryByPage(PageQueryCondition commonQueryCondition);
|
||||
|
||||
/// <summary>
|
||||
/// 根据主键批量查询
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> QueryByIds(Guid[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// 是否存在
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Exist(Expression<Func<TDTO, bool>> expression);
|
||||
#endregion
|
||||
|
||||
#region RawSql Sql操作
|
||||
/// <summary>
|
||||
/// sql查询,不带参数
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetBySql(string sql);
|
||||
/// <summary>
|
||||
/// sql查询,带参数 参数示例 select * from table where id=@id and name=@name 则字典的key为 "@id"
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlParam"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<TDTO>> GetBySql(string sql, Dictionary<string, object> sqlParam);
|
||||
/// <summary>
|
||||
/// sql查询匿名类型
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<dynamic>> GetDynamicsBysql(string sql);
|
||||
/// <summary>
|
||||
/// sql查询匿名类型,附带参数 参数示例 select * from table where id=@id and name=@name 则字典的key为 "@id"
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlParam"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<dynamic>> GetDynamicsBysql(string sql, Dictionary<string, object> sqlParam);
|
||||
/// <summary>
|
||||
/// 通过sql查询DataTable
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
Task<DataTable> GetDataTableBysql(string sql);
|
||||
/// <summary>
|
||||
/// 通过sql查询DataTable, 参数示例 select * from table where id=@id and name=@name 则字典的key为 "@id"
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlParam"></param>
|
||||
/// <returns></returns>
|
||||
Task<DataTable> GetDataTableBysql(string sql, Dictionary<string, object> sqlParam);
|
||||
/// <summary>
|
||||
/// 执行原生sql
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="params"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> ExcuteSql(string sql, params SugarParameter[] @params);
|
||||
#endregion
|
||||
|
||||
#region 事务
|
||||
/// <summary>
|
||||
/// 开始事务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task BeginTran(SqlSugarScope sqlSugarScope);
|
||||
/// <summary>
|
||||
/// 提交事务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task CommitTran(SqlSugarScope sqlSugarScope);
|
||||
/// <summary>
|
||||
/// 回滚事务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task RollbackTran(SqlSugarScope sqlSugarScope);
|
||||
SqlSugarTransaction UseTranAsync();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IERPTaskService: IBaseService<ERPTaskDto, ERPTask>
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新任务消息(生成失败提示等)
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="taskMsg"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> UpdateTaskMsg(Guid id, string taskMsg);
|
||||
|
||||
/// <summary>
|
||||
/// 更新任务状态(已完成、取消等)
|
||||
/// </summary>
|
||||
/// <param name="erpTask"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> UpdateTaskStatus(ERPTaskDto erpTask);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IElevatorCountService : IBaseService<ElevatorCountDto, ElevatorCount>
|
||||
{
|
||||
/// <summary>
|
||||
/// 计数自增
|
||||
/// </summary>
|
||||
/// <param name="elevatorNo"></param>
|
||||
/// <param name="channel"></param>
|
||||
/// <returns></returns>
|
||||
Task IncrementCount(int elevatorNo, int channel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IElevatorPlcQueueService : IBaseService<ElevatorPlcQueueDto, ElevatorPlcQueue>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Application.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.Application.IService
|
||||
{
|
||||
public interface IOperationLogService : IBaseService<OperationLogDto, OperationLog>
|
||||
{
|
||||
// 可根据业务需求添加自定义方法
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IRcsTaskService : IBaseService<RcsTaskDto, RcsTask>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IStorageRackService : IBaseService<StorageRackDto, StorageRack>
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据库位号查询库位信息
|
||||
/// </summary>
|
||||
/// <param name="storageRackNo"></param>
|
||||
/// <returns></returns>
|
||||
Task<StorageRackDto> GetByStorageRackNo(string storageRackNo);
|
||||
/// <summary>
|
||||
/// 根据提升机编号和通道号获取提所属库位信息
|
||||
/// </summary>
|
||||
/// <param name="elevatorNo"></param>
|
||||
/// <param name="channel"></param>
|
||||
/// <returns></returns>
|
||||
Task<StorageRackDto> GetElevatorWareHouse(int elevatorNo,int channel);
|
||||
/// <summary>
|
||||
/// 获取可用的提升机库位
|
||||
/// </summary>
|
||||
/// <param name="floor"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<StorageRackDto>> GetUsableElevatorWareHouse(FloorEnum floor);
|
||||
/// <summary>
|
||||
/// 锁定库位
|
||||
/// </summary>
|
||||
/// <param name="storageRack"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Lock(StorageRackDto storageRack);
|
||||
/// <summary>
|
||||
/// 解锁库位
|
||||
/// </summary>
|
||||
/// <param name="storageRack"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Unlock(StorageRackDto storageRack);
|
||||
/// <summary>
|
||||
/// 更新锁定状态
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="isLock"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> UpdateLockStatus(Guid id, bool isLock);
|
||||
/// <summary>
|
||||
/// 更新禁用状态
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="isDisable"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> UpdateDisableStatus(Guid id, bool isDisable);
|
||||
/// <summary>
|
||||
/// 预计算可用库位数量(用于pda入库请求时预计算可用库位数量,防止入库时找不到可用库位)
|
||||
/// </summary>
|
||||
/// <param name="floor"></param>
|
||||
/// <returns></returns>
|
||||
//Task<int> PreCalUsableStorageRackCount(FloorEnum floor);
|
||||
|
||||
/// <summary>
|
||||
/// 获取可用的中转库位
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<StorageRackDto> GetUsableTransferStorageRack();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
|
||||
namespace JSMachine.WMS.App.IService
|
||||
{
|
||||
public interface IUserInfoService : IBaseService<UserInfoDto, UserInfo>
|
||||
{
|
||||
// 可以在这里添加UserInfo特有的方法
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Prism.Core" Version="8.1.97" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JSMachine.WMS.Domain\JSMachine.WMS.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class AGVTaskService : BaseService<AGVTaskDto, AGVTask>, IAGVTaskService
|
||||
{
|
||||
private IAGVTaskRepository _agvTaskRepository;
|
||||
public AGVTaskService(IAGVTaskRepository repository) : base(repository)
|
||||
{
|
||||
_agvTaskRepository = repository;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateAgvTaskStatus(AGVTaskDto agvTask)
|
||||
{
|
||||
return await base.EditSingalWithSpecificCols(agvTask, [nameof(AGVTask.TaskStatus)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
using AutoMapper;
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using JSMachine.WMS.Domain.Repository;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure.LambdaHelp;
|
||||
using SqlSugar;
|
||||
using System.Data;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用层通用服务基类,负责 DTO 与领域实体之间的映射,
|
||||
/// 并将增删改查请求委托给对应的领域仓储。
|
||||
/// </summary>
|
||||
/// <typeparam name="TDTO">应用层数据传输对象类型。</typeparam>
|
||||
/// <typeparam name="TAggregateRoot">领域聚合根类型。</typeparam>
|
||||
public class BaseService<TDTO, TAggregateRoot> : IBaseService<TDTO, TAggregateRoot>
|
||||
where TAggregateRoot : AggregateRoot, IAggregateRoot
|
||||
where TDTO : IRootDto
|
||||
{
|
||||
private IBaseRepository<TAggregateRoot> IBaseRepository;
|
||||
private static IMapper _mapper = GlobalServericeProvidor.GetService<IMapper>();
|
||||
public BaseService(IBaseRepository<TAggregateRoot> baseRepository)
|
||||
{
|
||||
IBaseRepository = baseRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加单个 DTO;当 DTO 未提供标识时生成新标识,并维护创建时间和修改时间。
|
||||
/// </summary>
|
||||
/// <param name="dto">待保存的数据传输对象。</param>
|
||||
/// <param name="sqlSugarScope">可选的数据库作用域;为空时使用仓储默认作用域。</param>
|
||||
/// <returns>数据库插入是否成功。</returns>
|
||||
public async virtual Task<bool> Add(TDTO dto, SqlSugarScope sqlSugarScope=null)
|
||||
{
|
||||
if (dto.Id == Guid.Empty)
|
||||
dto.Id = Guid.NewGuid();
|
||||
dto.CreationTime = DateTime.Now;
|
||||
dto.LastModifiedTime = DateTime.Now;
|
||||
|
||||
return await IBaseRepository.Add(_mapper.Map<TAggregateRoot>(dto),sqlSugarScope);
|
||||
}
|
||||
|
||||
public async virtual Task<bool> Add(TDTO dto, params string[] ignoreColumns)
|
||||
{
|
||||
if (dto.Id == Guid.Empty)
|
||||
dto.Id = Guid.NewGuid();
|
||||
dto.CreationTime = DateTime.Now;
|
||||
dto.LastModifiedTime = DateTime.Now;
|
||||
|
||||
return await IBaseRepository.Add(_mapper.Map<TAggregateRoot>(dto), ignoreColumns);
|
||||
}
|
||||
|
||||
public async virtual Task<bool> Add(List<TDTO> entities)
|
||||
{
|
||||
if (entities == null || entities.Count == 0)
|
||||
return false;
|
||||
|
||||
entities.ForEach(p =>
|
||||
{
|
||||
|
||||
if (p.Id == Guid.Empty)
|
||||
p.Id = Guid.NewGuid();
|
||||
|
||||
p.CreationTime = DateTime.Now;
|
||||
p.LastModifiedTime = DateTime.Now;
|
||||
});
|
||||
|
||||
return await IBaseRepository.Add(_mapper.Map<List<TAggregateRoot>>(entities));
|
||||
}
|
||||
|
||||
public async Task<bool> Add(string tableName, Dictionary<string, object> dic)
|
||||
{
|
||||
if (dic.ContainsKey("Id"))
|
||||
dic.Add("Id", Guid.NewGuid().ToString("N"));
|
||||
|
||||
return await IBaseRepository.Add(tableName, dic);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加之前判断指定字段是否存在,不存在则添加
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> AddIfNotExist(TDTO entity, Expression<Func<TDTO, bool>> expression)
|
||||
{
|
||||
return await IBaseRepository.AddIfNotExist(_mapper.Map<TAggregateRoot>(entity),
|
||||
_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression));
|
||||
}
|
||||
|
||||
public async Task<int> Count()
|
||||
{
|
||||
return await IBaseRepository.Count();
|
||||
}
|
||||
|
||||
public async Task<int> Count(Expression<Func<TDTO, bool>> expression)
|
||||
{
|
||||
return await IBaseRepository.Count(_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression));
|
||||
}
|
||||
|
||||
public async Task<bool> DeleByExpression(Expression<Func<TAggregateRoot, bool>> expression)
|
||||
{
|
||||
return await IBaseRepository.DeleByExpression(expression);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteBatch(Guid[] ids)
|
||||
{
|
||||
return await IBaseRepository.DeleteBatch(ids);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteByEntity(TDTO aggregateRoot)
|
||||
{
|
||||
return await IBaseRepository.DeleteByEntity(_mapper.Map<TAggregateRoot>(aggregateRoot));
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteByEntity(List<TDTO> aggregateRoot)
|
||||
{
|
||||
return await IBaseRepository.DeleteByEntity(_mapper.Map<List<TAggregateRoot>>(aggregateRoot));
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteById(Guid id, SqlSugarScope sqlSugarScope=null)
|
||||
{
|
||||
return await IBaseRepository.DeleteById(id,sqlSugarScope);
|
||||
}
|
||||
|
||||
public async Task<bool> EditBatch(List<TDTO> dtos)
|
||||
{
|
||||
dtos.ForEach(p => p.LastModifiedTime = DateTime.Now);
|
||||
|
||||
return await IBaseRepository.EditBatch(_mapper.Map<List<TAggregateRoot>>(dtos));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 快速批量更新
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> EditBatchFast(List<TDTO> dtos)
|
||||
{
|
||||
dtos.ForEach(p => p.LastModifiedTime = DateTime.Now);
|
||||
return await IBaseRepository.EditBatchFast(_mapper.Map<List<TAggregateRoot>>(dtos));
|
||||
}
|
||||
|
||||
public async Task<bool> EditByDic(string tableName, Dictionary<string, object> dic)
|
||||
{
|
||||
return await IBaseRepository.EditByDic(tableName, dic);
|
||||
}
|
||||
|
||||
public async Task<bool> EditByDic(string tableName, List<Dictionary<string, object>> dic)
|
||||
{
|
||||
return await IBaseRepository.EditByDic(tableName, dic);
|
||||
}
|
||||
|
||||
public async virtual Task<bool> EditSingal(TDTO aggregateRoot)
|
||||
{
|
||||
aggregateRoot.LastModifiedTime = DateTime.Now;
|
||||
|
||||
//更新的时候不能够更改数据的添加时间
|
||||
return await IBaseRepository.EditSingal(_mapper.Map<TAggregateRoot>(aggregateRoot), new string[] { "CreationTime" });
|
||||
}
|
||||
|
||||
public async Task<bool> EditSingal(TDTO dto, Expression<Func<TDTO, object>> ignoredColumns)
|
||||
{
|
||||
dto.LastModifiedTime = DateTime.Now;
|
||||
return await IBaseRepository.EditSingal(_mapper.Map<TAggregateRoot>(dto), _mapper.Map<Expression<Func<TAggregateRoot, object>>>(ignoredColumns));
|
||||
}
|
||||
|
||||
public async Task<bool> EditSingal(TDTO dto, string[] ignoredColumns)
|
||||
{
|
||||
dto.LastModifiedTime = DateTime.Now;
|
||||
return await IBaseRepository.EditSingal(_mapper.Map<TAggregateRoot>(dto), ignoredColumns);
|
||||
}
|
||||
|
||||
public async Task<bool> EditSingalWithSpecificCols(TDTO dto, string[] columns)
|
||||
{
|
||||
dto.LastModifiedTime = DateTime.Now;
|
||||
return await IBaseRepository.EditSingalWithSpecificCols(_mapper.Map<TAggregateRoot>(dto), columns);
|
||||
}
|
||||
|
||||
public async Task<bool> Exist(Expression<Func<TDTO, bool>> expression)
|
||||
{
|
||||
return await IBaseRepository.Exist(_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression));
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetAll()
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetAll();
|
||||
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetAll(string orderByFiled, OrderByType orderByType)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetAll(LambdaHelper<TAggregateRoot>.GetOrderExpression<object>(orderByFiled),
|
||||
orderByType);
|
||||
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetAllFragment(int fragmentSize = 50000)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetAllFragment(fragmentSize);
|
||||
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetAllFragment(string orderByFiled, OrderByType orderByType, int fragmentSize = 200)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetAllFragment(
|
||||
LambdaHelper<TAggregateRoot>.GetOrderExpression<object>(orderByFiled),
|
||||
orderByType,
|
||||
fragmentSize);
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetBySql(string sql)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetBySql(sql);
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetBySql(string sql, Dictionary<string, object> sqlParam)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetBySql(sql, sqlParam);
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<DataTable> GetDataTableBysql(string sql)
|
||||
{
|
||||
return await IBaseRepository.GetDataTableBysql(sql);
|
||||
}
|
||||
|
||||
public async Task<DataTable> GetDataTableBysql(string sql, Dictionary<string, object> sqlParam)
|
||||
{
|
||||
return await IBaseRepository.GetDataTableBysql(sql, sqlParam);
|
||||
}
|
||||
|
||||
public async Task<List<dynamic>> GetDynamicsBysql(string sql)
|
||||
{
|
||||
return await IBaseRepository.GetDynamicsBysql(sql);
|
||||
}
|
||||
|
||||
public async Task<List<dynamic>> GetDynamicsBysql(string sql, Dictionary<string, object> sqlParam)
|
||||
{
|
||||
return await IBaseRepository.GetDynamicsBysql(sql, sqlParam);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> GetListByExpression(Expression<Func<TDTO, bool>> expression)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetListByExpression(
|
||||
_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression));
|
||||
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询满足条件的所有实体(带排序功能)
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <param name="orderByExpress"></param>
|
||||
/// <param name="orderByType">Asc = 0,Desc = 1</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<TDTO>> GetListByExpression(Expression<Func<TAggregateRoot, bool>> expression,
|
||||
string filedName,
|
||||
OrderByType orderByType = OrderByType.Desc)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetListByExpression(
|
||||
_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression),
|
||||
filedName,
|
||||
orderByType);
|
||||
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过实体查询满足条件的数据
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<TDTO>> GetListWhereClass(TDTO dto)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.GetListWhereClass(
|
||||
_mapper.Map<TAggregateRoot>(dto));
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<TDTO> GetSingalByExpression(Expression<Func<TDTO, bool>> expression)
|
||||
{
|
||||
TAggregateRoot data = await IBaseRepository.GetSingalByExpression(
|
||||
_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression));
|
||||
|
||||
return _mapper.Map<TDTO>(data);
|
||||
}
|
||||
|
||||
public async Task<TDTO> GetSingalByExpression(
|
||||
Expression<Func<TDTO, bool>> expression,
|
||||
Expression<Func<TAggregateRoot, object>> orderByExpress,
|
||||
OrderByType orderByType)
|
||||
{
|
||||
TAggregateRoot data = await IBaseRepository.GetSingalByExpression(
|
||||
_mapper.Map<Expression<Func<TAggregateRoot, bool>>>(expression), orderByExpress, orderByType);
|
||||
|
||||
return _mapper.Map<TDTO>(data);
|
||||
}
|
||||
|
||||
public async Task<List<TDTO>> QueryByIds(Guid[] ids)
|
||||
{
|
||||
List<TAggregateRoot> data = await IBaseRepository.QueryByIds(ids);
|
||||
return _mapper.Map<List<TDTO>>(data);
|
||||
}
|
||||
|
||||
public async Task<TDTO> QueryByKey(string key)
|
||||
{
|
||||
TAggregateRoot data = await IBaseRepository.QueryByKey(key);
|
||||
return _mapper.Map<TDTO>(data);
|
||||
}
|
||||
|
||||
public async Task<PagedResult<TDTO>> QueryByPage(PageQueryCondition pageQueryCondition)
|
||||
{
|
||||
PagedResult<TAggregateRoot> dataPage = await IBaseRepository.QueryByPage(pageQueryCondition);
|
||||
|
||||
return new PagedResult<TDTO>(dataPage.TotalRecords,
|
||||
dataPage.PageSize,
|
||||
dataPage.PageNumber,
|
||||
_mapper.Map<List<TDTO>>(dataPage.PageData));
|
||||
}
|
||||
|
||||
public async Task<bool> ExcuteSql(string sql, params SugarParameter[] @params)
|
||||
{
|
||||
return await IBaseRepository.ExcuteSql(sql, @params);
|
||||
}
|
||||
|
||||
#region 事务操作
|
||||
public async Task BeginTran(SqlSugarScope sqlSugarScope)
|
||||
{
|
||||
await IBaseRepository.BeginTran(sqlSugarScope);
|
||||
}
|
||||
|
||||
public async Task CommitTran(SqlSugarScope sqlSugarScope)
|
||||
{
|
||||
await IBaseRepository.CommitTran(sqlSugarScope);
|
||||
}
|
||||
|
||||
public async Task RollbackTran(SqlSugarScope sqlSugarScope)
|
||||
{
|
||||
await IBaseRepository.RollbackTran(sqlSugarScope);
|
||||
}
|
||||
|
||||
public SqlSugarTransaction UseTranAsync()
|
||||
{
|
||||
return IBaseRepository.UseTranAsync();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class ERPTaskService : BaseService<ERPTaskDto, ERPTask>, IERPTaskService
|
||||
{
|
||||
private IERPTaskRepository _erpTaskRepository;
|
||||
public ERPTaskService(IERPTaskRepository repository) : base(repository)
|
||||
{
|
||||
_erpTaskRepository = repository;
|
||||
}
|
||||
|
||||
public Task<bool> UpdateTaskMsg(Guid id, string taskMsg)
|
||||
{
|
||||
return _erpTaskRepository.ExcuteSql($"update ERPTask set TaskMsg='{taskMsg}' where Id='{id}'");
|
||||
}
|
||||
|
||||
public Task<bool> UpdateTaskStatus(ERPTaskDto erpTask)
|
||||
{
|
||||
erpTask.LastModifiedTime = DateTime.Now;
|
||||
return base.EditSingalWithSpecificCols(erpTask, [nameof(ERPTaskDto.TaskStatus), nameof(ERPTaskDto.LastModifiedTime)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class ElevatorCountService : BaseService<ElevatorCountDto, ElevatorCount>, IElevatorCountService
|
||||
{
|
||||
public ElevatorCountService(IBaseRepository<ElevatorCount> baseRepository) : base(baseRepository)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计数自增
|
||||
/// </summary>
|
||||
/// <param name="elevatorNo"></param>
|
||||
/// <param name="channel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task IncrementCount(int elevatorNo, int channel)
|
||||
{
|
||||
ElevatorCountDto elevatorCount = await GetSingalByExpression(p =>
|
||||
p.CreationTime >= DateTime.Now.Date &&
|
||||
p.ElevatorNo == elevatorNo &&
|
||||
p.ElevatorChannel == channel);
|
||||
if (elevatorCount == null)
|
||||
{
|
||||
elevatorCount = new()
|
||||
{
|
||||
ElevatorNo = elevatorNo,
|
||||
ElevatorChannel = channel,
|
||||
Count = 1
|
||||
};
|
||||
|
||||
await Add(elevatorCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
elevatorCount.Count++;
|
||||
await EditSingal(elevatorCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class ElevatorPlcQueueService : BaseService<ElevatorPlcQueueDto, ElevatorPlcQueue>, IElevatorPlcQueueService
|
||||
{
|
||||
private IElevatorPlcQueueRepository _elevatorPlcQueueRepository;
|
||||
public ElevatorPlcQueueService(IElevatorPlcQueueRepository repository) : base(repository)
|
||||
{
|
||||
_elevatorPlcQueueRepository = repository;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Application.Dto;
|
||||
using JSMachine.WMS.Application.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
|
||||
namespace JSMachine.WMS.Application.ServiceImpl
|
||||
{
|
||||
public class OperationLogService : BaseService<OperationLogDto, OperationLog>, IOperationLogService
|
||||
{
|
||||
private readonly IOperationLogRepository _operationLogRepository;
|
||||
|
||||
public OperationLogService(IOperationLogRepository repository) : base(repository)
|
||||
{
|
||||
_operationLogRepository = repository;
|
||||
}
|
||||
|
||||
// 可根据业务需求添加自定义操作方法
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class RcsTaskService : BaseService<RcsTaskDto, RcsTask>, IRcsTaskService
|
||||
{
|
||||
private IRcsTaskRepository _rcsTaskRepository;
|
||||
public RcsTaskService(IRcsTaskRepository rcsTaskRepository) : base(rcsTaskRepository)
|
||||
{
|
||||
_rcsTaskRepository = rcsTaskRepository;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using SqlSugar;
|
||||
using static JSMachine.WMS.App.Dto.StorageRackDto;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class StorageRackService : BaseService<StorageRackDto, StorageRack>, IStorageRackService
|
||||
{
|
||||
private IStorageRackRepository _storageRackRepository;
|
||||
public StorageRackService(IStorageRackRepository repository) : base(repository)
|
||||
{
|
||||
_storageRackRepository = repository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据库位号查询库位信息
|
||||
/// </summary>
|
||||
/// <param name="storageRackNo"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<StorageRackDto> GetByStorageRackNo(string storageRackNo)
|
||||
{
|
||||
return await GetSingalByExpression(p => p.StorageRackNo == storageRackNo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据批次号计算目标存储区库位
|
||||
/// </summary>
|
||||
/// <param name="materiaBatch"></param>
|
||||
/// <returns></returns>
|
||||
//public async Task<StorageRackDto> CalculateDestWarehouse(string materiaBatch, FloorEnum floor)
|
||||
//{
|
||||
// //如果某一列有一个库位被锁定,说明该列有未完成的任务(任务完成会解锁库位),因此该列不可以再生成新的任务
|
||||
|
||||
// //获取楼层的所有库位
|
||||
// List<StorageRackDto> wareHouses = await GetListByExpression(p =>
|
||||
// p.Floor == floor && p.Transport == TransportEnum.NormalArea);
|
||||
|
||||
// if (wareHouses.IsNullOrEmpty())
|
||||
// {
|
||||
// LogHelper.Warn($"{floor} 层没有空余库位");
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// wareHouses = wareHouses.OrderBy(p => p.AreaNumSort).OrderBy(p => p.ReservoirAreaColumnId).ToList();
|
||||
|
||||
// List<StorageRackDto> sameBatchWarehouses = wareHouses.Where(p => p.MateriaBatch == materiaBatch).ToList();
|
||||
// StorageRackDto destStorageRack = null;
|
||||
|
||||
// //没有相同批次则任选一个空白的列
|
||||
// if (sameBatchWarehouses.IsNullOrEmpty())
|
||||
// {
|
||||
// var groupByColumn = wareHouses.GroupBy(p => p.ReservoirAreaColumnId);
|
||||
|
||||
// foreach (var columnGroup in groupByColumn)
|
||||
// {
|
||||
// bool emptyColumn = columnGroup.All(p => !p.IsLock && !p.IsDisabled && string.IsNullOrEmpty(p.BarCode));
|
||||
// if (emptyColumn)
|
||||
// {
|
||||
// destStorageRack = columnGroup.OrderByDescending(p => p.NumSort).First();
|
||||
// break;
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else //存在相同批次则搜寻该批次所在的列下是否还有空库位
|
||||
// {
|
||||
// foreach (StorageRackDto sameBatchWarehous in sameBatchWarehouses)
|
||||
// {
|
||||
// var sameColumnWarehouse = wareHouses.Where(p => p.ReservoirAreaColumnId == sameBatchWarehous.ReservoirAreaColumnId);
|
||||
// //同批次的列中也不能有任何库位被锁定
|
||||
// if (sameColumnWarehouse.All(p => !p.IsLock && !p.IsDisabled))
|
||||
// {
|
||||
// destStorageRack = sameColumnWarehouse
|
||||
// .OrderByDescending(p => p.NumSort)
|
||||
// .FirstOrDefault(p => string.IsNullOrEmpty(p.BarCode));
|
||||
|
||||
// if (destStorageRack != null)
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// //如果同批次下都没有合适的库位,则需要找空列
|
||||
// if (destStorageRack == null)
|
||||
// {
|
||||
// List<StorageRackDto> remain = wareHouses.Except(sameBatchWarehouses, new StorageRackDtoIEqualityComparer()).ToList();
|
||||
// if (remain.IsNullOrEmpty())
|
||||
// {
|
||||
// LogHelper.Warn("排除相同批次库位后没有剩余可用库位");
|
||||
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// var groupByColumn = remain.GroupBy(p => p.ReservoirAreaColumnId);
|
||||
|
||||
// foreach (var columnGroup in groupByColumn)
|
||||
// {
|
||||
// bool emptyColumn = columnGroup.All(p => !p.IsLock && !p.IsDisabled && string.IsNullOrEmpty(p.BarCode));
|
||||
// if (emptyColumn)
|
||||
// {
|
||||
// destStorageRack = columnGroup.OrderByDescending(p => p.NumSort).First();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
// return destStorageRack;
|
||||
//}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据批次号判断是否存在空余库位
|
||||
/// </summary>
|
||||
/// <param name="materialBatch"></param>
|
||||
/// <returns></returns>
|
||||
//public async Task<bool> HasEmptyWareHouse(string materiaBatch, TaskTypeEnum taskType, FloorEnum floor)
|
||||
//{
|
||||
// //直接调用目标库位计算方法,能够计算出目标库位则有库位,否则就是没有
|
||||
// //一楼采用完全不混放模式
|
||||
// //二楼视配置
|
||||
|
||||
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 获取可用的提升机库位
|
||||
/// </summary>
|
||||
/// <param name="floor"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<StorageRackDto>> GetUsableElevatorWareHouse(FloorEnum floor)
|
||||
{
|
||||
List<long?> reservoirAreaIds = floor == FloorEnum.FirstFloor ? [1091, 1092] : [2091, 2092];
|
||||
|
||||
List<StorageRackDto> elevatorWarehouse = await
|
||||
GetListByExpression(p =>
|
||||
reservoirAreaIds.Contains(p.ReservoirAreaId)
|
||||
&&
|
||||
!p.IsLock && !p.IsDisabled
|
||||
);
|
||||
return elevatorWarehouse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据提升机编号和通道号获取提所属库位信息
|
||||
/// </summary>
|
||||
/// <param name="elevatorNo"></param>
|
||||
/// <param name="channel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<StorageRackDto> GetElevatorWareHouse(int elevatorNo, int channel)
|
||||
{
|
||||
string nameMatch = elevatorNo == 1 ? "1号" : "2号";
|
||||
StorageRackDto storageRack = await GetSingalByExpression(p => p.ElevatorChannel == channel && p.StorageRackName.Contains(nameMatch));
|
||||
|
||||
return storageRack;
|
||||
}
|
||||
|
||||
public async Task<bool> Lock(StorageRackDto storageRack)
|
||||
{
|
||||
storageRack.IsLock = true;
|
||||
|
||||
LogHelper.Info($"锁定库位{storageRack.StorageRackNo}");
|
||||
|
||||
return await base.EditSingalWithSpecificCols(storageRack, ["IsLock"]);
|
||||
}
|
||||
|
||||
public async Task<bool> Unlock(StorageRackDto storageRack)
|
||||
{
|
||||
storageRack.IsLock = false;
|
||||
LogHelper.Info($"解锁库位{storageRack.StorageRackNo}");
|
||||
|
||||
return await base.EditSingalWithSpecificCols(storageRack, ["IsLock"]);
|
||||
}
|
||||
|
||||
public Task<bool> UpdateLockStatus(Guid id, bool isLock)
|
||||
{
|
||||
return base.ExcuteSql($"update StorageRack set IsLock = {isLock} where Id = '{id}'");
|
||||
}
|
||||
|
||||
public Task<bool> UpdateDisableStatus(Guid id, bool isDisable)
|
||||
{
|
||||
return base.ExcuteSql($"update StorageRack set IsDisabled = {isDisable} where Id = '{id}'");
|
||||
}
|
||||
|
||||
private static readonly SemaphoreSlim SemaphoreSlim = new(1,1);
|
||||
public async Task<StorageRackDto> GetUsableTransferStorageRack()
|
||||
{
|
||||
await SemaphoreSlim.WaitAsync();
|
||||
|
||||
StorageRackDto storageRackDto = await
|
||||
base.GetSingalByExpression(p =>
|
||||
p.Transport == TransportEnum.TransitArea &&
|
||||
!p.IsLock &&
|
||||
!p.IsDisabled &&
|
||||
string.IsNullOrEmpty(p.BarCode));
|
||||
|
||||
if (storageRackDto != null)
|
||||
await Lock(storageRackDto);
|
||||
|
||||
SemaphoreSlim.Release();
|
||||
return storageRackDto;
|
||||
}
|
||||
|
||||
//public async Task<int> PreCalUsableStorageRackCount(FloorEnum floor)
|
||||
//{
|
||||
// //1. 一楼不混放,需要查找同批次,或者空白列
|
||||
// //2.二楼可以混放,仅需要查找到一个空库位即可
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Domain.IRepository;
|
||||
|
||||
namespace JSMachine.WMS.App.ServiceImpl
|
||||
{
|
||||
public class UserInfoService : BaseService<UserInfoDto, UserInfo>, IUserInfoService
|
||||
{
|
||||
private IUserInfoRepository _userInfoRepository;
|
||||
|
||||
public UserInfoService(IUserInfoRepository repository) : base(repository)
|
||||
{
|
||||
_userInfoRepository = repository;
|
||||
}
|
||||
|
||||
// 可以在这里添加UserInfo特有的方法实现
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using IdentityServer4.Models;
|
||||
using JSMachine.WMS.Authorization.Model;
|
||||
|
||||
namespace JSMachine.WMS.Authorization
|
||||
{
|
||||
/// <summary>
|
||||
/// 从授权配置中解析 IdentityServer 的身份资源、API 作用域和客户端信息。
|
||||
/// </summary>
|
||||
public class AuthorizationConfigResolver
|
||||
{
|
||||
private static IConfiguration _configuration;
|
||||
/// <summary>
|
||||
/// 设置后续解析操作使用的配置对象。
|
||||
/// </summary>
|
||||
/// <param name="configuration">包含 AppSettings 配置节的配置对象。</param>
|
||||
public static void SetConfig(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 OpenID Connect 所需的标准身份资源。
|
||||
/// </summary>
|
||||
public static IEnumerable<IdentityResource> IdentityResources =>
|
||||
new List<IdentityResource>
|
||||
{
|
||||
new IdentityResources.OpenId(),
|
||||
new IdentityResources.Profile()
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 从 AppSettings:ApiScopes 读取 API 作用域配置。
|
||||
/// </summary>
|
||||
/// <returns>配置存在时返回 API 作用域集合,否则返回空值。</returns>
|
||||
public static IEnumerable<ApiScope>? GetApiScopes()
|
||||
{
|
||||
return _configuration
|
||||
.GetSection("AppSettings")
|
||||
.GetSection("ApiScopes")
|
||||
.Get<string[]>()
|
||||
?.Select(p => new ApiScope(p));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 AppSettings:Clients 读取客户端配置,并转换为客户端凭据模式定义。
|
||||
/// </summary>
|
||||
/// <returns>配置存在时返回客户端集合,否则返回空值。</returns>
|
||||
public static IEnumerable<Client>? GetClients()
|
||||
{
|
||||
List<ClientInfo> clients = _configuration
|
||||
.GetSection("AppSettings")
|
||||
.GetSection("Clients")
|
||||
.Get<List<ClientInfo>>();
|
||||
|
||||
return clients?.Select(p => new Client
|
||||
{
|
||||
ClientId = p.ClientId,
|
||||
//用于身份验证的密钥
|
||||
ClientSecrets = new Secret[] { new Secret(p.Secret.Sha256()) },
|
||||
//客户端有权访问的范围
|
||||
AllowedScopes = p.AllowedScopes,
|
||||
//过期时间(秒)
|
||||
AccessTokenLifetime = p.AccessTokenLifetime,
|
||||
//没有交互式用户,使用 clientid/secret 进行身份验证
|
||||
AllowedGrantTypes = GrantTypes.ClientCredentials
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace JSMachine.WMS.Authorization
|
||||
{
|
||||
/// <summary>
|
||||
/// 授权服务宿主启动入口,负责创建并运行 ASP.NET Core 主机。
|
||||
/// </summary>
|
||||
public static class AuthorizationEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载授权服务配置、构建 Web 主机并阻塞运行服务。
|
||||
/// </summary>
|
||||
public static void Start()
|
||||
{
|
||||
Host.CreateDefaultBuilder()
|
||||
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
|
||||
webBuilder.UseStartup<Startup>();
|
||||
})
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config
|
||||
.SetBasePath($"{hostingContext.HostingEnvironment.ContentRootPath}")
|
||||
.AddJsonFile("appSettingsAuthorization.json", false, true)
|
||||
.AddEnvironmentVariables();
|
||||
})
|
||||
.Build()
|
||||
.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="IdentityServer4" Version="4.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<NameOfLastUsedPublishProfile>F:\Gitfactory\yzzx_new\papermes1.0\JSMachine.WMS.Authorization\Properties\PublishProfiles\FolderProfile.pubxml</NameOfLastUsedPublishProfile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace JSMachine.WMS.Authorization.Model
|
||||
{
|
||||
public class ClientInfo
|
||||
{
|
||||
public string ClientId { get; set; }
|
||||
public string Secret { get; set; }
|
||||
public List<string> AllowedScopes { get; set; }
|
||||
public int AccessTokenLifetime { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using JSMachine.WMS.Authorization;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
var config = builder.Configuration;
|
||||
AuthorizationConfigResolver.SetConfig(config);
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services
|
||||
.AddIdentityServer()
|
||||
.AddDeveloperSigningCredential() //���������û��֤�����ʹ�õĿ���������
|
||||
.AddInMemoryApiScopes(AuthorizationConfigResolver.GetApiScopes())
|
||||
.AddInMemoryClients(AuthorizationConfigResolver.GetClients())
|
||||
.AddInMemoryIdentityResources(AuthorizationConfigResolver.IdentityResources);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
|
||||
app.UseIdentityServer();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:42074",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"JSMachine.PrintDCS.Authorization": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "http://localhost:5199",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace JSMachine.WMS.Authorization
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers();
|
||||
|
||||
AuthorizationConfigResolver.SetConfig(Configuration);
|
||||
|
||||
services
|
||||
.AddIdentityServer()
|
||||
.AddDeveloperSigningCredential() //���������û��֤�����ʹ�õĿ���������
|
||||
.AddInMemoryApiScopes(AuthorizationConfigResolver.GetApiScopes())
|
||||
.AddInMemoryClients(AuthorizationConfigResolver.GetClients())
|
||||
.AddInMemoryIdentityResources(AuthorizationConfigResolver.IdentityResources);
|
||||
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseIdentityServer();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"urls": "http://127.0.0.1:8077",
|
||||
|
||||
"AppSettings": {
|
||||
"ApiScopes": [ "PostOrderApi" ],
|
||||
"Clients": [
|
||||
{
|
||||
"ClientId": "用友测试用户",
|
||||
"Secret": "123456",
|
||||
"AllowedScopes": [ "PostOrderApi" ],
|
||||
"AccessTokenLifetime": 3600
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Business.Common.Models;
|
||||
|
||||
namespace JSMachine.WMS.Business.Common.IService
|
||||
{
|
||||
/// <summary>
|
||||
/// WMS 公共业务服务,协调库位、ERP 任务和 AGV 任务之间的调度关系。
|
||||
/// </summary>
|
||||
public interface ICommonService
|
||||
{
|
||||
/// <summary>
|
||||
/// 库位所在列是否被锁定(有待完成的任务)
|
||||
/// </summary>
|
||||
/// <param name="storageRack"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> IsColLock(StorageRackDto storageRack);
|
||||
/// <summary>
|
||||
/// 跟据erp任务获取已经生成的agv任务列表(不包含已经取消的任务)
|
||||
/// </summary>
|
||||
/// <param name="erpTask"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<AGVTaskDto>> GetCreatedAgvTasksFromErpTask(ERPTaskDto erpTask,TaskTypeEnum taskType);
|
||||
/// <summary>
|
||||
/// 生成中转任务。指定起点,终点为中转区
|
||||
/// </summary>
|
||||
/// <param name="startPosition"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> CreateAgvTaskToTransferArea(StorageRackDto startPosition, TaskTypeEnum taskType, ERPTaskDto erpTask);
|
||||
/// <summary>
|
||||
/// 中转区作业调度 起点为中转区域 终点需计算
|
||||
/// </summary>
|
||||
/// <param name="startPosition"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> CreateAgvTaskFromTransferArea(StorageRackDto startPosition, AGVTaskDto lastAgvTaskRelated, ERPTaskDto erpTask);
|
||||
/// <summary>
|
||||
/// 生成agv任务并插入数据库
|
||||
/// </summary>
|
||||
/// <param name="startPosition"></param>
|
||||
/// <param name="endPosition"></param>
|
||||
/// <param name="erpTask"></param>
|
||||
/// <returns></returns>
|
||||
Task CreateAndInsertAgvTask(AgvTaskCreationParam agvTaskCreationParam);
|
||||
/// <summary>
|
||||
/// 获取可用提升机库位
|
||||
/// </summary>
|
||||
/// <param name="floor">楼层</param>
|
||||
/// <param name="taskType">任务类型 1-入库 2-出库</param>
|
||||
/// <returns></returns>
|
||||
Task<StorageRackDto> GetUsableElevator(FloorEnum floor, int taskType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.Common.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// AGV任务创建参数模型
|
||||
/// </summary>
|
||||
public class AgvTaskCreationParam
|
||||
{
|
||||
/// <summary>
|
||||
/// 起点
|
||||
/// </summary>
|
||||
public StorageRackDto StartPosition { get; set; }
|
||||
/// <summary>
|
||||
/// 终点
|
||||
/// </summary>
|
||||
public StorageRackDto EndPosition { get; set; }
|
||||
/// <summary>
|
||||
/// 关联的erp任务
|
||||
/// </summary>
|
||||
public Guid ErpTaskId { get; set; }
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public TaskTypeEnum TaskType { get; set; }
|
||||
/// <summary>
|
||||
/// 最终出库码头(仅针对出库有效)
|
||||
/// </summary>
|
||||
public TransportEnum StockOutWharf { get; set; }
|
||||
/// <summary>
|
||||
/// erp上传状态
|
||||
/// </summary>
|
||||
public ErpUploadStatusEnum ErpUploadStatus { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.Common.IService;
|
||||
using JSMachine.WMS.Business.Common.Models;
|
||||
using JSMachine.WMS.Business.SSE;
|
||||
using JSMachine.WMS.Business.StockIn.IService;
|
||||
using JSMachine.WMS.Business.StockIn.ServiceImpl.Strategy;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.Elevator.ModbusIO.Read;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Model;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace JSMachine.WMS.Business.Common.ServiceImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// WMS 通用业务服务,协调 ERP 任务、库位和 AGV 任务,
|
||||
/// 负责中转区及提升机相关任务的生成。
|
||||
/// </summary>
|
||||
public class CommonService : ICommonService
|
||||
{
|
||||
private IERPTaskService _erpTaskService;
|
||||
private IStorageRackService _storageRackService;
|
||||
private IAGVTaskService _agvTaskService;
|
||||
public CommonService(
|
||||
IERPTaskService erpTaskService,
|
||||
IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService)
|
||||
{
|
||||
_erpTaskService = erpTaskService;
|
||||
_storageRackService = storageRackService;
|
||||
_agvTaskService = agvTaskService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定库位所在列是否存在锁定库位。
|
||||
/// 该判断通过查询同列全部库位完成,任一库位被锁定即视为整列锁定。
|
||||
/// </summary>
|
||||
/// <param name="storageRack">用于确定库位列的库位信息。</param>
|
||||
/// <returns>同列存在锁定库位时返回 <see langword="true"/>。</returns>
|
||||
public async Task<bool> IsColLock(StorageRackDto storageRack)
|
||||
{
|
||||
List<StorageRackDto> storageRacksThisCol = await _storageRackService
|
||||
.GetListByExpression(p => p.ReservoirAreaColumnId == storageRack.ReservoirAreaColumnId);
|
||||
|
||||
if (storageRacksThisCol.IsNullOrEmpty())
|
||||
return false;
|
||||
|
||||
if (storageRacksThisCol.Any(p => p.IsLock))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跟据erp任务获取已经生成的agv任务列表(不包含已经取消的任务)
|
||||
/// </summary>
|
||||
/// <param name="materialBatch"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<AGVTaskDto>> GetCreatedAgvTasksFromErpTask(ERPTaskDto erpTask, TaskTypeEnum taskType)
|
||||
{
|
||||
List<AGVTaskDto> agvTasks = await _agvTaskService
|
||||
.GetListByExpression(p => p.ErpTaskId == erpTask.Id &&
|
||||
p.TaskType == taskType &&
|
||||
p.TaskStatus != TaskStatusEnum.Cancelled &&
|
||||
p.TaskStatus != TaskStatusEnum.Failed);
|
||||
|
||||
agvTasks = agvTasks
|
||||
.GroupBy(p => p.BarCode)
|
||||
.Select(p => p.First())
|
||||
.ToList();
|
||||
|
||||
return agvTasks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成到中转区域的任务。指定起点,终点为中转区
|
||||
/// </summary>
|
||||
/// <param name="startPosition"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> CreateAgvTaskToTransferArea(StorageRackDto startPosition, TaskTypeEnum taskType, ERPTaskDto erpTask)
|
||||
{
|
||||
StorageRackDto endPosition = await _storageRackService.GetUsableTransferStorageRack();
|
||||
|
||||
if (endPosition == null)
|
||||
{
|
||||
LogHelper.Info("中转区域库位已满");
|
||||
return false;
|
||||
}
|
||||
|
||||
await CreateAndInsertAgvTask(new AgvTaskCreationParam
|
||||
{
|
||||
StartPosition = startPosition,
|
||||
EndPosition = endPosition,
|
||||
ErpTaskId = erpTask.Id,
|
||||
TaskType = taskType,
|
||||
StockOutWharf = erpTask.Transport,
|
||||
ErpUploadStatus = ErpUploadStatusEnum.Unnecessary
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 中转区作业调度 起点为中转区域 终点需计算
|
||||
/// </summary>
|
||||
/// <param name="startPosition">要调度的中转区物料</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> CreateAgvTaskFromTransferArea(StorageRackDto startPosition, AGVTaskDto lastAgvTaskRelated, ERPTaskDto erpTask)
|
||||
{
|
||||
// 中转区任务按出库、入库、清理出库阻塞物的顺序生成;任一环节失败即停止后续调度。
|
||||
bool bRet = await CreateTransferStockOutAgvTask(startPosition, lastAgvTaskRelated, erpTask);
|
||||
if (!bRet)
|
||||
return false;
|
||||
|
||||
bRet = await CreateTransferStockInAgvTask(startPosition, lastAgvTaskRelated, erpTask);
|
||||
if (!bRet)
|
||||
return false;
|
||||
|
||||
bRet = await CreateRemoveStockOutObstructionAgvTask(startPosition, lastAgvTaskRelated, erpTask);
|
||||
if (!bRet)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> CreateTransferStockOutAgvTask(
|
||||
StorageRackDto startPosition,
|
||||
AGVTaskDto lastAgvTaskRelated,
|
||||
ERPTaskDto erpTask)
|
||||
{
|
||||
if (lastAgvTaskRelated.TaskType != TaskTypeEnum.TransferStockOut)
|
||||
return true;
|
||||
|
||||
StorageRackDto elevator = await GetUsableElevator(FloorEnum.SecondFloor, 2);
|
||||
|
||||
if (elevator == null)
|
||||
{
|
||||
LogHelper.Warn($"中转区出库业务 所有提升机出库库位均被WMS或者PLC锁定,erpTask {lastAgvTaskRelated.ErpTaskId} 无法生成AgvTask");
|
||||
return false;
|
||||
}
|
||||
|
||||
await CreateAndInsertAgvTask(new AgvTaskCreationParam
|
||||
{
|
||||
StartPosition = startPosition,
|
||||
EndPosition = elevator,
|
||||
ErpTaskId = erpTask.Id,
|
||||
TaskType = TaskTypeEnum.TransferStockOut,
|
||||
StockOutWharf = erpTask.Transport,
|
||||
ErpUploadStatus = ErpUploadStatusEnum.Unnecessary
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> CreateTransferStockInAgvTask(StorageRackDto startPosition, AGVTaskDto lastAgvTaskRelated, ERPTaskDto erpTask)
|
||||
{
|
||||
if (lastAgvTaskRelated.TaskType != TaskTypeEnum.TransferStockIn)
|
||||
return true;
|
||||
|
||||
IStockInStrategy stockInStrategy = StrategyFactory.CreateStockInStrategy(
|
||||
TransportEnum.TransitArea,
|
||||
FloorEnum.SecondFloor,
|
||||
startPosition.MateriaBatch);
|
||||
|
||||
StorageRackDto endPosition = await stockInStrategy.CalCulateWarehouse();
|
||||
if (endPosition == null)
|
||||
return false;
|
||||
|
||||
await CreateAndInsertAgvTask(new AgvTaskCreationParam
|
||||
{
|
||||
StartPosition = startPosition,
|
||||
EndPosition = endPosition,
|
||||
ErpTaskId = erpTask.Id,
|
||||
TaskType = lastAgvTaskRelated.TaskType,
|
||||
ErpUploadStatus =
|
||||
(erpTask.TaskType == TaskTypeEnum.PdaIn || erpTask.TaskType == TaskTypeEnum.TailIn) ?
|
||||
ErpUploadStatusEnum.WaittingToUpload :
|
||||
ErpUploadStatusEnum.Unnecessary
|
||||
});
|
||||
return true;
|
||||
}
|
||||
private async Task<bool> CreateRemoveStockOutObstructionAgvTask(
|
||||
StorageRackDto startPosition,
|
||||
AGVTaskDto lastAgvTaskRelated,
|
||||
ERPTaskDto erpTask)
|
||||
{
|
||||
if (lastAgvTaskRelated.TaskType != TaskTypeEnum.RemoveStockOutObstruction)
|
||||
return true;
|
||||
|
||||
IStockInStrategy stockInStrategy = StrategyFactory.CreateStockInStrategy(
|
||||
TransportEnum.TransitArea,
|
||||
FloorEnum.SecondFloor,
|
||||
startPosition.MateriaBatch);
|
||||
|
||||
StorageRackDto endPosition = await stockInStrategy.CalCulateWarehouse();
|
||||
|
||||
if (endPosition == null)
|
||||
return false;
|
||||
|
||||
await CreateAndInsertAgvTask(new AgvTaskCreationParam
|
||||
{
|
||||
StartPosition = startPosition,
|
||||
EndPosition = endPosition,
|
||||
ErpTaskId = erpTask.Id,
|
||||
TaskType = lastAgvTaskRelated.TaskType,
|
||||
ErpUploadStatus =
|
||||
(erpTask.TaskType == TaskTypeEnum.PdaIn || erpTask.TaskType == TaskTypeEnum.TailIn) ?
|
||||
ErpUploadStatusEnum.WaittingToUpload :
|
||||
ErpUploadStatusEnum.Unnecessary
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取可用提升机库位
|
||||
/// </summary>
|
||||
/// <param name="floor">楼层</param>
|
||||
/// <param name="taskType">任务类型 1-入库 2-出库</param>
|
||||
/// <returns></returns>
|
||||
public async Task<StorageRackDto> GetUsableElevator(FloorEnum floor, int taskType)
|
||||
{
|
||||
List<StorageRackDto> elevatorWarehouse = await _storageRackService.GetListByExpression(p =>
|
||||
p.Transport == TransportEnum.Elevator &&
|
||||
p.Floor == floor &&
|
||||
!p.IsLock
|
||||
);
|
||||
|
||||
if (elevatorWarehouse.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<ElevatorPlcStatus> elevatorPlcStatuses = await ElevatorStatusRead.ReadAllElevatorStatus();
|
||||
|
||||
StorageRackDto elevator = null;
|
||||
foreach (StorageRackDto elvatorWarehouse in elevatorWarehouse)
|
||||
{
|
||||
int elevatorNo = elvatorWarehouse.StorageRackName.Contains("1号") ? 1 : 2;
|
||||
|
||||
ElevatorPlcStatus elevatorPlcStatus = elevatorPlcStatuses.First(p => p.ElevatorNo == elevatorNo);
|
||||
|
||||
//入库
|
||||
if (taskType == 1)
|
||||
{
|
||||
if (elvatorWarehouse.ElevatorChannel == 1001 && elevatorPlcStatus.StockInPutdownChanelTwo ||
|
||||
elvatorWarehouse.ElevatorChannel == 1011 && elevatorPlcStatus.StockInPutdownChanelOne)
|
||||
{
|
||||
elevator = elvatorWarehouse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//出库
|
||||
if (taskType == 2)
|
||||
{
|
||||
if (elvatorWarehouse.ElevatorChannel == 2001 && elevatorPlcStatus.StockOutPutdownChanelTwo ||
|
||||
elvatorWarehouse.ElevatorChannel == 2011 && elevatorPlcStatus.StockOutPutdownChanelOne)
|
||||
{
|
||||
elevator = elvatorWarehouse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elevator;
|
||||
}
|
||||
|
||||
public async Task CreateAndInsertAgvTask(AgvTaskCreationParam agvTaskCreationParam)
|
||||
{
|
||||
AGVTaskDto agvTask = new()
|
||||
{
|
||||
ErpTaskId = agvTaskCreationParam.ErpTaskId,
|
||||
BarCode = agvTaskCreationParam.StartPosition.BarCode,
|
||||
OrderNo = agvTaskCreationParam.StartPosition.OrderNo,
|
||||
CustomName = agvTaskCreationParam.StartPosition.CustomName,
|
||||
MateriaName = agvTaskCreationParam.StartPosition.MateriaName,
|
||||
MateriaType = agvTaskCreationParam.StartPosition.MateriaType,
|
||||
MateriaNum = agvTaskCreationParam.StartPosition.MateriaNum,
|
||||
MateriaBatch = agvTaskCreationParam.StartPosition.MateriaBatch,
|
||||
MateriaCode = agvTaskCreationParam.StartPosition.MateriaCode,
|
||||
TaskType = agvTaskCreationParam.TaskType,
|
||||
TaskStatus = TaskStatusEnum.Initial,
|
||||
Priority = agvTaskCreationParam.TaskType == TaskTypeEnum.SaleOut ? PriorityEnum.High : PriorityEnum.Middle,
|
||||
Floor = agvTaskCreationParam.StartPosition.Floor,
|
||||
|
||||
StartPositionCode = agvTaskCreationParam.StartPosition.StorageRackNo,
|
||||
EndPositionCode = agvTaskCreationParam.EndPosition.StorageRackNo,
|
||||
|
||||
Transport = agvTaskCreationParam.StockOutWharf,
|
||||
|
||||
ErpUploadStatus = agvTaskCreationParam.ErpUploadStatus
|
||||
};
|
||||
|
||||
await _storageRackService.Lock(agvTaskCreationParam.StartPosition);
|
||||
await _storageRackService.Lock(agvTaskCreationParam.EndPosition);
|
||||
await _agvTaskService.Add(agvTask);
|
||||
|
||||
//发送广播通知前端网站刷新页面
|
||||
SseEngine.BrodCast(agvTaskCreationParam.StartPosition.Floor.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Exstension\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JSMachine.WMS.Common\JSMachine.WMS.Common.csproj" />
|
||||
<ProjectReference Include="..\JSMachine.WMS.PLC\JSMachine.WMS.PLC.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto;
|
||||
using JSMachine.WMS.RPC.ErpRPC.Dto.Out;
|
||||
using JSMachine.WMS.App.Dto;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.IService
|
||||
{
|
||||
public interface IRcsCallBackService
|
||||
{
|
||||
/// <summary>
|
||||
/// 给Rcs调用,获取AGV上报的任务状态
|
||||
/// </summary>
|
||||
/// <param name="callBackWmsParam"></param>
|
||||
/// <returns></returns>
|
||||
Task<RcsApiResult> DealwithExcutionStatus(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask);
|
||||
|
||||
/// <summary>
|
||||
/// 处理PDA上报的agv报警处理结果
|
||||
/// </summary>
|
||||
/// <param name="agvTaskId"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> DealWithAlarmHandleResult(Guid agvTaskId);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.IService.StaePattern
|
||||
{
|
||||
/// <summary>
|
||||
/// agv任务状态处理器 状态设计模式
|
||||
/// </summary>
|
||||
public interface IAgvTaskStateHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// 处理一次 AGV 状态回调,并按状态推进任务或更新任务结果。
|
||||
/// </summary>
|
||||
/// <param name="agvExcutionInfo">RCS 返回的 AGV 执行信息。</param>
|
||||
/// <param name="agvTask">系统中的 AGV 任务。</param>
|
||||
/// <param name="destWarehouse">任务目标库位。</param>
|
||||
/// <returns>状态处理是否成功。</returns>
|
||||
Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse);
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.IService.StrategyPattern
|
||||
{
|
||||
/// <summary>
|
||||
/// agv任务结束策略(放货完成即代表agv任务结束)
|
||||
/// </summary>
|
||||
public interface ITaskCompletionStrategy
|
||||
{
|
||||
Task<bool> CompleteTaskAsync(AGVTaskDto agvTask, StorageRackDto destWarehouse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StaePattern;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StrategyPattern;
|
||||
using JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern;
|
||||
using JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StrategyPatternImpl;
|
||||
using JSMachine.WMS.Common.Dto.Business;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// RCS 回调业务,将外部 AGV 状态转换为本地任务、库存及报警状态。
|
||||
/// </summary>
|
||||
public class RcsCallBackService : IRcsCallBackService
|
||||
{
|
||||
private IAGVTaskService _agvTaskService;
|
||||
private IElevatorPlcQueueService _elevatorPlcQueueService;
|
||||
private IStorageRackService _storageRackService;
|
||||
private IERPTaskService _erptaskService;
|
||||
private IElevatorCountService _elevatorCountService;
|
||||
|
||||
public RcsCallBackService(
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IStorageRackService storageRackService,
|
||||
IERPTaskService erpTaskService,
|
||||
IElevatorCountService elevatorCountService)
|
||||
{
|
||||
_agvTaskService = agvTaskService;
|
||||
_elevatorPlcQueueService = elevatorPlcQueueService;
|
||||
_storageRackService = storageRackService;
|
||||
_erptaskService = erpTaskService;
|
||||
_elevatorCountService = elevatorCountService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给Rcs调用,获取AGV上报的任务状态
|
||||
/// </summary>
|
||||
/// <param name="callBackWmsParam"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<RcsApiResult> DealwithExcutionStatus(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
// 先处理失败和取消状态,再处理成功状态;各处理器根据回调状态自行决定是否生效。
|
||||
//处理agv执行失败的回调,推送pda报警
|
||||
await HandleFailed(agvExcutionInfo, agvTask);
|
||||
|
||||
await HandleCanceled(agvExcutionInfo, agvTask);
|
||||
//处理agv执行成功的回调
|
||||
RcsApiResult rcsApiResult = await HandleSuccess(agvExcutionInfo, agvTask);
|
||||
|
||||
return rcsApiResult;
|
||||
}
|
||||
|
||||
public async Task<bool> DealWithAlarmHandleResult(Guid agvTaskId)
|
||||
{
|
||||
AGVTaskDto agvTask = await _agvTaskService.GetSingalByExpression(p => p.Id == agvTaskId);
|
||||
|
||||
if (agvTask == null)
|
||||
{
|
||||
LogHelper.Warn($"PDA上传的 {agvTaskId} 任务不存在,该任务告警可能已经处理?");
|
||||
return true;
|
||||
}
|
||||
|
||||
//模拟rcs回调,发送放货完成命令
|
||||
await DealwithExcutionStatus(new AgvExcutionInfo
|
||||
{
|
||||
OrderId = agvTaskId.ToString(),
|
||||
Status = 23
|
||||
}, agvTask);
|
||||
|
||||
//处理完删除缓存中的报警信息
|
||||
GlobalAgvTaskFailedAlarmInfo.RemoveAlarmInfo(agvTaskId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region 处理入库rcs回调信息
|
||||
|
||||
private async Task HandleCanceled(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (agvExcutionInfo.Status != 3)
|
||||
return;
|
||||
|
||||
agvTask.TaskStatus = TaskStatusEnum.Cancelled;
|
||||
await _agvTaskService.EditSingal(agvTask);
|
||||
|
||||
//搬运的任务没有对应的erptask
|
||||
if (agvTask.TaskType != TaskTypeEnum.Carry)
|
||||
{
|
||||
ERPTaskDto erpTask = await _erptaskService.GetSingalByExpression(p => p.Id == agvTask.ErpTaskId);
|
||||
erpTask.TaskStatus = TaskStatusEnum.Cancelled;
|
||||
await _erptaskService.UpdateTaskStatus(erpTask);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleFailed(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (agvExcutionInfo.Status != 7)
|
||||
return;
|
||||
|
||||
//1.一楼 起点在入库库位,终点在提升机,人工搬运托盘到提升机入口,手动提交放货完成信号
|
||||
//2.二楼 起点在提升机出口,终点在存储区库位,人工搬运托盘到库位,手动提交放货完成信号
|
||||
//3.二楼 起点在入库区库位,终点在提升机入口,人工搬运托盘到提升机入口,手动提交放货完成信号
|
||||
//4.一楼 起点在提升机,终点在出货码头,人工搬运托盘到出货码头,无需其他处理
|
||||
|
||||
await HandleStocInFirstFloor(agvExcutionInfo, agvTask);
|
||||
await HandleStocInSecondFloor(agvExcutionInfo, agvTask);
|
||||
await HandleStocOutSecondFloor(agvExcutionInfo, agvTask);
|
||||
await HandleStocOutFirstFloor(agvExcutionInfo, agvTask);
|
||||
}
|
||||
|
||||
#region agv执行失败报警分任务处理
|
||||
private async Task HandleStocInFirstFloor(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (!(agvTask.TaskType == TaskTypeEnum.PdaIn && agvTask.Floor == FloorEnum.FirstFloor))
|
||||
return;
|
||||
|
||||
StorageRackDto destWarehouse = await _storageRackService.GetSingalByExpression(p => p.StorageRackNo == agvTask.EndPositionCode);
|
||||
|
||||
//终点在存储区,人工搬运获取到指定库位,完成后写放货完成
|
||||
if (destWarehouse.Transport == TransportEnum.NormalArea)
|
||||
{
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从车上取下搬运到 {destWarehouse.StorageRackName} " +
|
||||
$"库区的 {destWarehouse.StorageRackNo}库位上,完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn(operatn);
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
|
||||
await UpdateErpTaskStatus(agvTask, TaskStatusEnum.Failed);
|
||||
}
|
||||
|
||||
//终点在提升机入口,人工搬运获取到提升机入口,完成后写放货完成
|
||||
if (destWarehouse.Transport == TransportEnum.Elevator)
|
||||
{
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从车上(或库位{agvTask.StartPositionCode})搬运到 {destWarehouse.StorageRackName} 上," +
|
||||
$"完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn($"任务 id {agvTask.Id} 操作信息:{operatn}");
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
}
|
||||
}
|
||||
private async Task HandleStocInSecondFloor(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (!(agvTask.TaskType == TaskTypeEnum.PdaIn && agvTask.Floor == FloorEnum.SecondFloor))
|
||||
return;
|
||||
|
||||
StorageRackDto startWarehouse = await _storageRackService.GetByStorageRackNo(agvTask.StartPositionCode);
|
||||
StorageRackDto destWarehouse = await _storageRackService.GetByStorageRackNo(agvTask.EndPositionCode);
|
||||
|
||||
//终点在存储区,人工搬运获取到指定库位,完成后写放货完成
|
||||
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从 {startWarehouse.StorageRackName} 搬运到 " +
|
||||
$"{destWarehouse.StorageRackNo}库位上,完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn($"任务 id {agvTask.Id} 操作信息:{operatn}");
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
|
||||
await UpdateErpTaskStatus(agvTask, TaskStatusEnum.Failed);
|
||||
}
|
||||
private async Task HandleStocOutSecondFloor(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (!(agvTask.TaskType == TaskTypeEnum.SaleOut && agvTask.Floor == FloorEnum.SecondFloor))
|
||||
return;
|
||||
|
||||
StorageRackDto destWarehouse = await _storageRackService.GetByStorageRackNo(agvTask.EndPositionCode);
|
||||
|
||||
//终点在存储区,人工搬运获取到指定库位,完成后写放货完成
|
||||
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从车上(或者{agvTask.StartPositionCode})放到 {destWarehouse.StorageRackNo} 上,完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn($"任务 id {agvTask.Id} 操作信息:{operatn}");
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
}
|
||||
private async Task HandleStocOutFirstFloor(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (!(agvTask.TaskType == TaskTypeEnum.SaleOut && agvTask.Floor == FloorEnum.SecondFloor))
|
||||
return;
|
||||
|
||||
StorageRackDto startWarehouse = await _storageRackService.GetByStorageRackNo(agvTask.StartPositionCode);
|
||||
StorageRackDto destWarehouse = await _storageRackService.GetByStorageRackNo(agvTask.EndPositionCode);
|
||||
|
||||
if (startWarehouse.Transport == TransportEnum.Elevator)
|
||||
{
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从 {startWarehouse.StorageRackName} 搬运到 " +
|
||||
$"{(destWarehouse.Transport == TransportEnum.NorthArea ? "北出库码头" : "南出库码头")} " +
|
||||
$"的 {destWarehouse.StorageRackNo} 库位上,完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn($"任务 id {agvTask.Id} 操作信息:{operatn}");
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
}
|
||||
|
||||
if (startWarehouse.Transport == TransportEnum.NorthArea)
|
||||
{
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从 " +
|
||||
$"{startWarehouse} 库位上搬运到北出库码头的" +
|
||||
$"{destWarehouse.StorageRackNo} 库位上,完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn($"任务 id {agvTask.Id} 操作信息:{operatn}");
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
}
|
||||
|
||||
if (startWarehouse.Transport == TransportEnum.SouthArea)
|
||||
{
|
||||
string operatn = $"{agvExcutionInfo.DeviceNum}号小车报警,请将货物从" +
|
||||
$"{startWarehouse} 库位搬运到南出库码头" +
|
||||
$"的 {destWarehouse.StorageRackNo} 库位上,完成后点击已处理按钮";
|
||||
|
||||
LogHelper.Warn($"任务 id {agvTask.Id} 操作信息:{operatn}");
|
||||
|
||||
GlobalAgvTaskFailedAlarmInfo.AddAlarmInfo(new AgvTaskFailedAlarmInfo
|
||||
{
|
||||
AgvTaskId = agvTask.Id,
|
||||
Operation = operatn
|
||||
});
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private async Task<RcsApiResult> HandleSuccess(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask)
|
||||
{
|
||||
if (!new int[] { 21, 23 }.Contains(agvExcutionInfo.Status))
|
||||
{
|
||||
LogHelper.Warn("rcs回调状态不是21,23,不处理");
|
||||
return new RcsApiResult { code = 1000 };
|
||||
}
|
||||
|
||||
StorageRackDto destWarehouse = await _storageRackService.GetSingalByExpression(p => p.StorageRackNo == agvTask.EndPositionCode);
|
||||
if (destWarehouse == null)
|
||||
{
|
||||
LogHelper.Error($"AgvTask终点库位 {agvTask.EndPositionCode} 不存在");
|
||||
return new RcsApiResult { code = 1000 }; ;
|
||||
}
|
||||
|
||||
IAgvTaskStateHandler handler = new RcsCallbackHandlerFactory().CreateHandler(agvExcutionInfo.Status, destWarehouse);
|
||||
if (handler == null)
|
||||
{
|
||||
LogHelper.Error("状态模式 没有匹配的模式可以处理");
|
||||
return new RcsApiResult { code = 1000 };
|
||||
}
|
||||
await handler.HandleAsync(agvExcutionInfo, agvTask, destWarehouse);
|
||||
return new RcsApiResult { code = 1000 };
|
||||
}
|
||||
|
||||
|
||||
private async Task UpdateErpTaskStatus(AGVTaskDto agvTask, TaskStatusEnum taskStatus)
|
||||
{
|
||||
ERPTaskDto erpTask = await _erptaskService.GetSingalByExpression(p => p.Id == agvTask.ErpTaskId);
|
||||
erpTask.TaskStatus = taskStatus;
|
||||
//更新erp任务状态为完成
|
||||
bool bRet = await _erptaskService.EditSingal(erpTask);
|
||||
LogHelper.Info($"更新erptask状态为 {taskStatus} ,数据库操作结果 {bRet}");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 处理销售出库/生产退库,Rcs回调
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 解锁中区库位并绑定合格证
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task UnlockAndSetMiddleWarehouse(StorageRackDto storageRack)
|
||||
{
|
||||
if (storageRack.Transport != TransportEnum.MiddleOutArea)
|
||||
return;
|
||||
|
||||
storageRack.IsLock = false;
|
||||
await _storageRackService.EditSingalWithSpecificCols(storageRack, ["IsLock", "BarCode"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新AgvTask任务状态
|
||||
/// </summary>
|
||||
/// <param name="agvTask">库位编号</param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> UpdateAgvTaskStatus(AGVTaskDto agvTask)
|
||||
{
|
||||
var updateResult = false;
|
||||
|
||||
if (agvTask != null)
|
||||
{
|
||||
updateResult = await _agvTaskService.EditSingal(agvTask);
|
||||
if (!updateResult)
|
||||
{
|
||||
LogHelper.Error($"销售出库:更新AgvTask {agvTask.Id} 的,完成状态失败");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Info($"销售出库:更新AgvTask {agvTask.Id} 的,完成状态成功");
|
||||
}
|
||||
}
|
||||
return updateResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空起点库位上的物料信息
|
||||
/// </summary>
|
||||
/// <param name="agvTask"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> ClearMateriaInfo(AGVTaskDto agvTask)
|
||||
{
|
||||
var clearResult = false;
|
||||
var typeMsg = "";
|
||||
if (agvTask.TaskType == TaskTypeEnum.SaleOut)
|
||||
{
|
||||
typeMsg = "销售出库,";
|
||||
}
|
||||
else if (agvTask.TaskType == TaskTypeEnum.Carry)
|
||||
{
|
||||
typeMsg = "搬运物料,";
|
||||
}
|
||||
|
||||
var clearWarehouse = await _storageRackService.GetSingalByExpression(p => p.StorageRackNo == agvTask.StartPositionCode);
|
||||
if (clearWarehouse != null)
|
||||
{
|
||||
clearWarehouse.MateriaBatch = "";
|
||||
clearWarehouse.MateriaNum = 0;
|
||||
|
||||
clearWarehouse.OrderNo = "";
|
||||
clearWarehouse.MateriaName = "";
|
||||
clearWarehouse.MateriaType = "";
|
||||
clearWarehouse.MateriaCode = "";
|
||||
clearWarehouse.BarCode = "";
|
||||
clearWarehouse.IsLock = false;
|
||||
|
||||
clearResult = await _storageRackService.EditSingal(clearWarehouse);
|
||||
if (!clearResult)
|
||||
{
|
||||
LogHelper.Error($"{typeMsg}清空库位{clearWarehouse.StorageRackNo}上的物料信息{clearWarehouse.MateriaCode}失败");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Info($"{typeMsg}清空库位{clearWarehouse.StorageRackNo}上的物料信息{clearWarehouse.MateriaCode}成功");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Error($"{typeMsg}清空库位时,未查询到库位{agvTask.StartPositionCode}上的物料信息");
|
||||
}
|
||||
return clearResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新终点库位上的物料信息
|
||||
/// </summary>
|
||||
/// <param name="agvTask"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> UpdateMateriaInfo(AGVTaskDto agvTask)
|
||||
{
|
||||
var updateResult = false;
|
||||
|
||||
var updateWarehouse = await _storageRackService.GetSingalByExpression(p => p.StorageRackNo == agvTask.EndPositionCode);
|
||||
if (updateWarehouse != null)
|
||||
{
|
||||
updateWarehouse.MateriaBatch = agvTask.MateriaBatch;
|
||||
updateWarehouse.MateriaNum = agvTask.MateriaNum;
|
||||
|
||||
updateWarehouse.OrderNo = agvTask.OrderNo;
|
||||
updateWarehouse.MateriaName = agvTask.MateriaName;
|
||||
updateWarehouse.MateriaType = agvTask.MateriaType;
|
||||
updateWarehouse.MateriaCode = agvTask.MateriaCode;
|
||||
updateWarehouse.BarCode = agvTask.BarCode;
|
||||
updateWarehouse.IsLock = false;
|
||||
|
||||
updateResult = await _storageRackService.EditSingal(updateWarehouse);
|
||||
if (!updateResult)
|
||||
{
|
||||
LogHelper.Error($"销售出库:更新库位{updateWarehouse.StorageRackNo}上的物料信息{updateWarehouse.MateriaCode}失败");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Info($"销售出库:更新库位{updateWarehouse.StorageRackNo}上的物料信息{updateWarehouse.MateriaCode}成功");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Error($"销售出库:更新库位时,未查询到库位{agvTask.EndPositionCode}上的物料信息");
|
||||
}
|
||||
return updateResult;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StaePattern;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern
|
||||
{
|
||||
/// <summary>
|
||||
/// agv任务执行失败处理器
|
||||
/// </summary>
|
||||
public class FailedStateHandler : IAgvTaskStateHandler
|
||||
{
|
||||
private readonly IAGVTaskService _agvTaskService;
|
||||
/// <summary>创建失败状态处理器。</summary>
|
||||
/// <param name="agvTaskService">AGV 任务持久化服务。</param>
|
||||
public FailedStateHandler(IAGVTaskService agvTaskService)
|
||||
{
|
||||
_agvTaskService=agvTaskService;
|
||||
}
|
||||
|
||||
/// <summary>将当前 AGV 任务标记为失败并保存状态。</summary>
|
||||
/// <param name="agvExcutionInfo">RCS 执行信息。</param>
|
||||
/// <param name="agvTask">待更新的 AGV 任务。</param>
|
||||
/// <param name="destWarehouse">目标库位。</param>
|
||||
/// <returns>状态更新是否成功。</returns>
|
||||
public async Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
agvTask.TaskStatus = TaskStatusEnum.Failed;
|
||||
return await _agvTaskService.UpdateAgvTaskStatus(agvTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StaePattern;
|
||||
using JSMachine.WMS.Business.SSE;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern
|
||||
{
|
||||
/// <summary>
|
||||
/// agv取货完成处理器
|
||||
/// </summary>
|
||||
public class PickupCompletedStateHandler : IAgvTaskStateHandler
|
||||
{
|
||||
private readonly IStorageRackService _storageRackService;
|
||||
private readonly IAGVTaskService _agvTaskService;
|
||||
|
||||
public PickupCompletedStateHandler(IStorageRackService storageRackService, IAGVTaskService agvTaskService)
|
||||
{
|
||||
_storageRackService = storageRackService;
|
||||
_agvTaskService = agvTaskService;
|
||||
}
|
||||
|
||||
public async Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
// 清空出库库位上的物料、解锁库位
|
||||
await ClearMateriaInfo(agvTask);
|
||||
|
||||
//更新AgvTask的状态为 取货完成
|
||||
agvTask.TaskStatus = TaskStatusEnum.PickupCompleted;
|
||||
return await _agvTaskService.UpdateAgvTaskStatus(agvTask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空起点库位上的物料信息
|
||||
/// </summary>
|
||||
/// <param name="agvTask"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> ClearMateriaInfo(AGVTaskDto agvTask)
|
||||
{
|
||||
var clearResult = false;
|
||||
var typeMsg = "";
|
||||
if (agvTask.TaskType == TaskTypeEnum.SaleOut)
|
||||
{
|
||||
typeMsg = "销售出库,";
|
||||
}
|
||||
else if (agvTask.TaskType == TaskTypeEnum.Carry)
|
||||
{
|
||||
typeMsg = "搬运物料,";
|
||||
}
|
||||
|
||||
var clearWarehouse = await _storageRackService.GetSingalByExpression(p => p.StorageRackNo == agvTask.StartPositionCode);
|
||||
if (clearWarehouse != null)
|
||||
{
|
||||
clearWarehouse.MateriaBatch = "";
|
||||
clearWarehouse.MateriaNum = 0;
|
||||
|
||||
clearWarehouse.OrderNo = "";
|
||||
clearWarehouse.MateriaName = "";
|
||||
clearWarehouse.MateriaType = "";
|
||||
clearWarehouse.MateriaCode = "";
|
||||
clearWarehouse.BarCode = "";
|
||||
clearWarehouse.IsLock = false;
|
||||
|
||||
clearResult = await _storageRackService.EditSingal(clearWarehouse);
|
||||
if (!clearResult)
|
||||
{
|
||||
LogHelper.Error($"{typeMsg}清空库位{clearWarehouse.StorageRackNo}上的物料信息{clearWarehouse.MateriaCode}失败");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Info($"{typeMsg}清空库位{clearWarehouse.StorageRackNo}上的物料信息{clearWarehouse.MateriaCode}成功");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Error($"{typeMsg}清空库位时,未查询到库位{agvTask.StartPositionCode}上的物料信息");
|
||||
}
|
||||
|
||||
//发送广播通知前端网站刷新页面
|
||||
SseEngine.BrodCast(agvTask.Floor.ToString());
|
||||
|
||||
return clearResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.SSE;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Model;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.PaperFeedGroundRack.ModbusIO.Write;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern.PutdownCompleted
|
||||
{
|
||||
/// <summary>
|
||||
/// 提升机处理器
|
||||
/// </summary>
|
||||
public class ElevatorDeliveryHandler : PutdownCompletedStateHandler
|
||||
{
|
||||
public ElevatorDeliveryHandler
|
||||
(IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IElevatorCountService elevatorCountService,
|
||||
IERPTaskService erpTaskService) :
|
||||
base(storageRackService, agvTaskService, elevatorPlcQueueService, elevatorCountService, erpTaskService)
|
||||
{
|
||||
}
|
||||
|
||||
public async override Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
var elevatorPlcStatus = new ElevatorPlcStatus();
|
||||
|
||||
//2.1 写PLC放货完成
|
||||
int elevatorNo = destWarehouse.StorageRackName.Contains("1号") ? 1 : 2;
|
||||
elevatorPlcStatus.ElevatorNo = elevatorNo;
|
||||
|
||||
if (destWarehouse.ElevatorChannel == 1001)
|
||||
{
|
||||
elevatorPlcStatus.StockInPutdownChanelTwo = true;
|
||||
}
|
||||
if (destWarehouse.ElevatorChannel == 1011)
|
||||
{
|
||||
elevatorPlcStatus.StockInPutdownChanelOne = true;
|
||||
}
|
||||
if (destWarehouse.ElevatorChannel == 2001)
|
||||
{
|
||||
elevatorPlcStatus.StockOutPutdownChanelTwo = true;
|
||||
}
|
||||
if (destWarehouse.ElevatorChannel == 2011)
|
||||
{
|
||||
elevatorPlcStatus.StockOutPutdownChanelOne = true;
|
||||
}
|
||||
bool bRet = await ElevatorWrite.WriteElevator(elevatorPlcStatus);
|
||||
if (!bRet)
|
||||
{
|
||||
LogHelper.Error($"{agvTask.TaskType.GetDescription()}: " +
|
||||
$"向 {elevatorPlcStatus.ElevatorNo} 号提升机 {destWarehouse.ElevatorChannel} 网带写放货完成信号失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(agvTask.TaskType!=TaskTypeEnum.Carry)
|
||||
{
|
||||
//2.2 写PLC队列信息
|
||||
ElevatorPlcQueueDto elevatorPlcQueue = new()
|
||||
{
|
||||
ElevatorNo = elevatorNo,
|
||||
ElevatorChannel = destWarehouse.ElevatorChannel.Value,
|
||||
AgvTaskId = agvTask.Id,
|
||||
IsLock = false
|
||||
};
|
||||
bRet = await _elevatorPlcQueueService.Add(elevatorPlcQueue);
|
||||
if (!bRet)
|
||||
{
|
||||
LogHelper.Error($"{agvTask.TaskType.GetDescription()}:写PLC队列失败");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Info($"{agvTask.TaskType.GetDescription()}:" +
|
||||
$"写PLC队列成功,提升机编号 {elevatorPlcQueue.ElevatorNo} 通道号 {elevatorPlcQueue.ElevatorChannel}");
|
||||
}
|
||||
|
||||
//提升机计数
|
||||
await _elevatorCountService.IncrementCount(elevatorNo, elevatorPlcQueue.ElevatorChannel);
|
||||
}
|
||||
|
||||
//2.3 更新agvtask的状态为完成
|
||||
await base.CompleteTask(agvTask);
|
||||
|
||||
//2.4 解锁提升机库位
|
||||
await _storageRackService.Unlock(destWarehouse);
|
||||
|
||||
//发送广播通知前端网站刷新页面
|
||||
SseEngine.BrodCast(agvTask.Floor.ToString());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StaePattern;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern.PutdownCompleted
|
||||
{
|
||||
/// <summary>
|
||||
/// 放货完成处理器
|
||||
/// </summary>
|
||||
public abstract class PutdownCompletedStateHandler : IAgvTaskStateHandler
|
||||
{
|
||||
protected readonly IStorageRackService _storageRackService;
|
||||
protected readonly IAGVTaskService _agvTaskService;
|
||||
protected readonly IElevatorPlcQueueService _elevatorPlcQueueService;
|
||||
protected readonly IElevatorCountService _elevatorCountService;
|
||||
protected readonly IERPTaskService _erpTaskService;
|
||||
|
||||
public PutdownCompletedStateHandler(
|
||||
IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IElevatorCountService elevatorCountService,
|
||||
IERPTaskService erpTaskService
|
||||
)
|
||||
{
|
||||
_storageRackService = storageRackService;
|
||||
_agvTaskService = agvTaskService;
|
||||
_elevatorPlcQueueService = elevatorPlcQueueService;
|
||||
_elevatorCountService= elevatorCountService;
|
||||
_erpTaskService = erpTaskService;
|
||||
}
|
||||
|
||||
public abstract Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse);
|
||||
|
||||
protected async Task CompleteTask(AGVTaskDto agvTask)
|
||||
{
|
||||
agvTask.TaskStatus = TaskStatusEnum.Completed;
|
||||
await _agvTaskService.UpdateAgvTaskStatus(agvTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.Common.IService;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StaePattern;
|
||||
using JSMachine.WMS.Business.SSE;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static JSMachine.WMS.App.Dto.StorageRackDto;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern.PutdownCompleted
|
||||
{
|
||||
/// <summary>
|
||||
/// 存储区(包括中转区)放货完成处理器
|
||||
/// </summary>
|
||||
public class StockAreaHandler : PutdownCompletedStateHandler
|
||||
{
|
||||
public StockAreaHandler(
|
||||
IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IElevatorCountService elevatorCountService,
|
||||
IERPTaskService erpTaskService) :
|
||||
base(storageRackService, agvTaskService, elevatorPlcQueueService, elevatorCountService, erpTaskService)
|
||||
{
|
||||
}
|
||||
|
||||
public async override Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
//1.将物料绑定到目标库位
|
||||
//2.解锁目标库位
|
||||
//3.更改agv任务为完成
|
||||
|
||||
destWarehouse.BingdingMaterial(new MateriaInfo
|
||||
{
|
||||
BarCode = agvTask.BarCode,
|
||||
MateriaBatch = agvTask.MateriaBatch,
|
||||
MateriaCode = agvTask.MateriaCode,
|
||||
MateriaName = agvTask.MateriaName,
|
||||
MateriaNum = agvTask.MateriaNum.ToString(),
|
||||
MateriaType = agvTask.MateriaType,
|
||||
OrderNo = agvTask.OrderNo
|
||||
});
|
||||
destWarehouse.IsLock = false;
|
||||
|
||||
await _storageRackService.EditSingal(destWarehouse);
|
||||
|
||||
await CompleteTask(agvTask);
|
||||
|
||||
//更新erp任务为完成状态
|
||||
if (agvTask.TaskType == TaskTypeEnum.PdaIn ||
|
||||
agvTask.TaskType == TaskTypeEnum.TailIn ||
|
||||
agvTask.TaskType == TaskTypeEnum.TransferStockIn)
|
||||
{
|
||||
ERPTaskDto erpTask = await _erpTaskService.GetSingalByExpression(p => p.Id == agvTask.ErpTaskId);
|
||||
if (erpTask != null)
|
||||
{
|
||||
erpTask.TaskStatus = TaskStatusEnum.Completed;
|
||||
erpTask.TaskMsg = "";
|
||||
await _erpTaskService.EditSingalWithSpecificCols(erpTask, ["TaskStatus", "TaskMsg"]);
|
||||
}
|
||||
}
|
||||
|
||||
//发送广播通知前端网站刷新页面
|
||||
SseEngine.BrodCast(agvTask.Floor.ToString());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern.PutdownCompleted
|
||||
{
|
||||
/// <summary>
|
||||
/// 出库码头处理器
|
||||
/// </summary>
|
||||
public class StockOutWharfHandler : PutdownCompletedStateHandler
|
||||
{
|
||||
public StockOutWharfHandler
|
||||
(IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IElevatorCountService elevatorCountService,
|
||||
IERPTaskService erpTaskService) :
|
||||
base(storageRackService, agvTaskService, elevatorPlcQueueService, elevatorCountService, erpTaskService)
|
||||
{
|
||||
}
|
||||
|
||||
public async override Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
destWarehouse.BarCode = agvTask.BarCode;
|
||||
|
||||
agvTask.TaskStatus = TaskStatusEnum.Completed;
|
||||
|
||||
await UnlockAndSetMiddleWarehouse(destWarehouse);
|
||||
|
||||
return await _agvTaskService.UpdateAgvTaskStatus(agvTask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解锁中区库位并绑定合格证
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task UnlockAndSetMiddleWarehouse(StorageRackDto storageRack)
|
||||
{
|
||||
if (storageRack.Transport != TransportEnum.MiddleOutArea)
|
||||
return;
|
||||
|
||||
storageRack.IsLock = false;
|
||||
await _storageRackService.EditSingalWithSpecificCols(storageRack, ["IsLock", "BarCode"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Business.SSE;
|
||||
using JSMachine.WMS.RPC.RcsRPC.Dto.In;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static JSMachine.WMS.App.Dto.StorageRackDto;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern.PutdownCompleted
|
||||
{
|
||||
public class TransitAreaHandler : PutdownCompletedStateHandler
|
||||
{
|
||||
public TransitAreaHandler(
|
||||
IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IElevatorCountService elevatorCountService,
|
||||
IERPTaskService erpTaskService) :
|
||||
base(storageRackService, agvTaskService, elevatorPlcQueueService, elevatorCountService, erpTaskService)
|
||||
{
|
||||
}
|
||||
|
||||
public async override Task<bool> HandleAsync(AgvExcutionInfo agvExcutionInfo, AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
//1.将物料绑定到目标库位
|
||||
//2.解锁目标库位
|
||||
//3.更改agv任务为完成
|
||||
|
||||
destWarehouse.BingdingMaterial(new MateriaInfo
|
||||
{
|
||||
BarCode = agvTask.BarCode,
|
||||
MateriaBatch = agvTask.MateriaBatch,
|
||||
MateriaCode = agvTask.MateriaCode,
|
||||
MateriaName = agvTask.MateriaName,
|
||||
MateriaNum = agvTask.MateriaNum.ToString(),
|
||||
MateriaType = agvTask.MateriaType,
|
||||
OrderNo = agvTask.OrderNo
|
||||
});
|
||||
destWarehouse.IsLock = false;
|
||||
|
||||
await _storageRackService.EditSingal(destWarehouse);
|
||||
|
||||
await CompleteTask(agvTask);
|
||||
|
||||
//发送广播通知前端网站刷新页面
|
||||
SseEngine.BrodCast(agvTask.Floor.ToString());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StaePattern;
|
||||
using JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern.PutdownCompleted;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StatePattern
|
||||
{
|
||||
/// <summary>
|
||||
/// rcs回调处理器工厂类
|
||||
/// </summary>
|
||||
public class RcsCallbackHandlerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据 RCS 返回状态和目标库位运输区域选择状态处理器。
|
||||
/// </summary>
|
||||
/// <param name="status">RCS 任务状态码。</param>
|
||||
/// <param name="destWarehouse">任务目标库位。</param>
|
||||
/// <returns>负责当前状态后续处理的处理器。</returns>
|
||||
public IAgvTaskStateHandler CreateHandler(int status, StorageRackDto destWarehouse)
|
||||
{
|
||||
return status switch
|
||||
{
|
||||
21 => GlobalServericeProvidor.GetService<PickupCompletedStateHandler>(),
|
||||
23 => destWarehouse.Transport switch
|
||||
{
|
||||
TransportEnum.NorthArea or TransportEnum.SouthArea or TransportEnum.MiddleOutArea or TransportEnum.ReturnStockArea
|
||||
=> GlobalServericeProvidor.GetService<StockOutWharfHandler>(),
|
||||
TransportEnum.NormalArea => GlobalServericeProvidor.GetService<StockAreaHandler>(),
|
||||
TransportEnum.TransitArea => GlobalServericeProvidor.GetService<TransitAreaHandler>(),
|
||||
TransportEnum.Elevator => GlobalServericeProvidor.GetService<ElevatorDeliveryHandler>(),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StrategyPattern;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Model;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.PaperFeedGroundRack.ModbusIO.Write;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StrategyPatternImpl
|
||||
{
|
||||
public class ElevatorStrategy : ITaskCompletionStrategy
|
||||
{
|
||||
private readonly IElevatorPlcQueueService _elevatorPlcQueueService;
|
||||
private readonly IStorageRackService _storageRackService;
|
||||
private readonly IAGVTaskService _agvTaskService;
|
||||
private readonly IElevatorCountService _elevatorCountService;
|
||||
|
||||
public ElevatorStrategy(
|
||||
IElevatorPlcQueueService elevatorPlcQueueService,
|
||||
IStorageRackService storageRackService,
|
||||
IElevatorCountService elevatorCountService,
|
||||
IAGVTaskService agvTaskService)
|
||||
{
|
||||
_elevatorPlcQueueService = elevatorPlcQueueService;
|
||||
_storageRackService = storageRackService;
|
||||
_elevatorCountService = elevatorCountService;
|
||||
_agvTaskService = agvTaskService;
|
||||
}
|
||||
|
||||
public async Task<bool> CompleteTaskAsync(AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
ElevatorPlcStatus elevatorPlcStatus = new();
|
||||
|
||||
int elevatorNo = destWarehouse.StorageRackName.Contains("1号") ? 1 : 2;
|
||||
elevatorPlcStatus.ElevatorNo = elevatorNo;
|
||||
|
||||
if (destWarehouse.ElevatorChannel == 1001)
|
||||
{
|
||||
elevatorPlcStatus.StockInPutdownChanelTwo = true;
|
||||
}
|
||||
if (destWarehouse.ElevatorChannel == 1011)
|
||||
{
|
||||
elevatorPlcStatus.StockInPutdownChanelOne = true;
|
||||
}
|
||||
|
||||
bool bRet = await ElevatorWrite.WriteElevator(elevatorPlcStatus);
|
||||
|
||||
if (!bRet)
|
||||
{
|
||||
LogHelper.Error($"向 {elevatorPlcStatus.ElevatorNo} 号提升机 {destWarehouse.ElevatorChannel} 网带写放货完成信号失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
ElevatorPlcQueueDto elevatorPlcQueue = new()
|
||||
{
|
||||
ElevatorNo = elevatorNo,
|
||||
ElevatorChannel = destWarehouse.ElevatorChannel.Value,
|
||||
AgvTaskId = agvTask.Id,
|
||||
IsLock = false
|
||||
};
|
||||
|
||||
bRet = await _elevatorPlcQueueService.Add(elevatorPlcQueue);
|
||||
if (!bRet)
|
||||
{
|
||||
LogHelper.Error($"写PLC队列失败");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Info($"入库:写提升机队列成功 提升机编号 {elevatorPlcQueue.ElevatorNo} 通道号 {elevatorPlcQueue.ElevatorChannel}");
|
||||
}
|
||||
|
||||
agvTask.TaskStatus = TaskStatusEnum.Completed;
|
||||
await _agvTaskService.EditSingalWithSpecificCols(agvTask, ["TaskStatus"]);
|
||||
|
||||
//解锁提升机通道库位
|
||||
await _storageRackService.Unlock(destWarehouse);
|
||||
//提升机计数
|
||||
await _elevatorCountService.IncrementCount(elevatorNo, elevatorPlcQueue.ElevatorChannel);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StrategyPattern;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using Prism;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static JSMachine.WMS.App.Dto.StorageRackDto;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StrategyPatternImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// 存储区策略(普通库位,中转库位)
|
||||
/// </summary>
|
||||
public class StorageAreaStrategy : ITaskCompletionStrategy
|
||||
{
|
||||
private readonly IStorageRackService _storageRackService;
|
||||
private readonly IAGVTaskService _agvTaskService;
|
||||
private readonly IERPTaskService _erpTaskService;
|
||||
public StorageAreaStrategy(
|
||||
IStorageRackService storageRackService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IERPTaskService erpTaskService)
|
||||
{
|
||||
_storageRackService = storageRackService;
|
||||
_agvTaskService = agvTaskService;
|
||||
_erpTaskService = erpTaskService;
|
||||
}
|
||||
|
||||
public async Task<bool> CompleteTaskAsync(AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool bRet = await _agvTaskService.EditSingalWithSpecificCols(agvTask, ["TaskStatus"]);
|
||||
if (!bRet)
|
||||
{
|
||||
LogHelper.Error($"更新agvTask {agvTask.Id} 失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
destWarehouse.BingdingMaterial(new MateriaInfo
|
||||
{
|
||||
BarCode = agvTask.BarCode,
|
||||
MateriaBatch = agvTask.MateriaBatch,
|
||||
MateriaCode = agvTask.MateriaCode,
|
||||
MateriaName = agvTask.MateriaName,
|
||||
MateriaNum = agvTask.MateriaNum.ToString(),
|
||||
MateriaType = agvTask.MateriaType,
|
||||
OrderNo = agvTask.OrderNo
|
||||
});
|
||||
//托盘放到位后解锁库位
|
||||
destWarehouse.IsLock = false;
|
||||
await _storageRackService.EditSingal(destWarehouse);
|
||||
|
||||
agvTask.TaskStatus = TaskStatusEnum.Completed;
|
||||
await _agvTaskService.EditSingalWithSpecificCols(agvTask, ["TaskStatus"]);
|
||||
|
||||
//更新erp任务状态为完成
|
||||
await UpdateErpTaskStatus(agvTask, TaskStatusEnum.Completed);
|
||||
|
||||
return true;
|
||||
}
|
||||
private async Task UpdateErpTaskStatus(AGVTaskDto agvTask, TaskStatusEnum taskStatus)
|
||||
{
|
||||
ERPTaskDto erpTask = await _erpTaskService.GetSingalByExpression(p => p.Id == agvTask.ErpTaskId);
|
||||
erpTask.TaskStatus = taskStatus;
|
||||
//更新erp任务状态为完成
|
||||
bool bRet = await _erpTaskService.EditSingal(erpTask);
|
||||
LogHelper.Info($"更新erptask状态为 {taskStatus} ,数据库操作结果 {bRet}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Business.RcsCallBack.IService.StrategyPattern;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.RcsCallBack.ServiceImpl.StrategyPatternImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据任务楼层、目标区域和提升机区域选择任务完成处理策略。
|
||||
/// </summary>
|
||||
public class TaskCompletionStrategyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 解析 AGV 任务完成后的后续处理策略。
|
||||
/// </summary>
|
||||
/// <param name="agvTask">已完成的 AGV 任务。</param>
|
||||
/// <param name="destWarehouse">任务目标库位。</param>
|
||||
/// <returns>匹配的策略实例;无法匹配时返回空值。</returns>
|
||||
public ITaskCompletionStrategy GetStrategy(AGVTaskDto agvTask, StorageRackDto destWarehouse)
|
||||
{
|
||||
if (agvTask.Floor == FloorEnum.FirstFloor)
|
||||
{
|
||||
if (destWarehouse.Transport == TransportEnum.NormalArea)
|
||||
return GlobalServericeProvidor.GetService<StorageAreaStrategy>();
|
||||
else if (destWarehouse.ReservoirAreaId == 1091 || destWarehouse.ReservoirAreaId == 1092)
|
||||
return GlobalServericeProvidor.GetService<ElevatorStrategy>();
|
||||
}
|
||||
else if (
|
||||
agvTask.Floor == FloorEnum.SecondFloor &&
|
||||
(destWarehouse.Transport == TransportEnum.NormalArea || destWarehouse.Transport == TransportEnum.TransitArea))
|
||||
{
|
||||
return GlobalServericeProvidor.GetService<StorageAreaStrategy>();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace JSMachine.WMS.Business.SSE
|
||||
{
|
||||
public class ClientConnection
|
||||
{
|
||||
public HttpResponse Response { get; set; }
|
||||
public string ClientId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.SSE
|
||||
{
|
||||
public static class SseEngine
|
||||
{
|
||||
private static readonly List<ClientConnection> _clients = [];
|
||||
|
||||
public static void AddClient(ClientConnection client)
|
||||
{
|
||||
_clients.Add(client);
|
||||
}
|
||||
|
||||
public static void RemoveClient(ClientConnection client)
|
||||
{
|
||||
_clients.Remove(client);
|
||||
}
|
||||
|
||||
public static void BrodCast(string message)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
|
||||
foreach (var client in _clients)
|
||||
{
|
||||
var data = $"data: {message}\n\n";
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
client.Response.Body.WriteAsync(bytes, 0, bytes.Length);
|
||||
client.Response.Body.FlushAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Common.Dto.Http.In;
|
||||
using JSMachine.WMS.RPC.ErpRPC.Dto.In.XRBusinessResult;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.IService
|
||||
{
|
||||
public interface IStockInService
|
||||
{
|
||||
/// <summary>
|
||||
/// 入库
|
||||
/// </summary>
|
||||
/// <param name="stockInParam"></param>
|
||||
/// <returns></returns>
|
||||
Task<string> StockIn(PDAInParam stockInParam);
|
||||
/// <summary>
|
||||
/// 从ERPTask生成AgvTask(pda入库)
|
||||
/// </summary>
|
||||
/// <param name="erpTask"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> CreateAgvTaskFirstFloor(ERPTaskDto erpTask);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.IService
|
||||
{
|
||||
/// <summary>
|
||||
/// 入库策略
|
||||
/// </summary>
|
||||
public interface IStockInStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 计算目标库位
|
||||
/// </summary>
|
||||
/// <param name="exceptColumnId">要排除的列(出库掏货再回库不可以回原来的列)</param>
|
||||
/// <returns></returns>
|
||||
Task<StorageRackDto> CalCulateWarehouse();
|
||||
}
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.ServiceImpl;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using NPOI.OpenXmlFormats.Dml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain
|
||||
{
|
||||
/// <summary>
|
||||
/// 放置在已有相同批次的列上
|
||||
/// </summary>
|
||||
public class StockInByExist : StockInHandler
|
||||
{
|
||||
public override async Task<StorageRackDto> CalculateWarehouse(
|
||||
TransportEnum startArea,
|
||||
FloorEnum floor,
|
||||
string materialBatch,
|
||||
List<StorageRackDto> storageRacks
|
||||
)
|
||||
{
|
||||
//1.查找有没有同批次待执行的任务
|
||||
//2.有待执行的任务,直接进入中转区域
|
||||
//3.没有待执行的任务,则采用现有逻辑获取一个同批次库位
|
||||
|
||||
//非中转区的任务,需要先判断是否有同批次未完成的任务,如有则需要等待,确保同批次的货物放满同一列
|
||||
|
||||
await _SemaphoreSlim.WaitAsync();
|
||||
StorageRackDto destStorageRack = null;
|
||||
|
||||
try
|
||||
{
|
||||
storageRacks = await base.GetStorageRackExceptStockout(floor);
|
||||
|
||||
if (storageRacks.IsNullOrEmpty())
|
||||
{
|
||||
LogHelper.Info("没有可用库位");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<AGVTaskDto> uncompletedTasks = await _agvTaskService.GetListByExpression(p =>
|
||||
p.CreationTime > DateTime.Now.Date &&
|
||||
p.MateriaBatch == materialBatch &&
|
||||
(p.TaskType == TaskTypeEnum.PdaIn || p.TaskType == TaskTypeEnum.TailIn || p.TaskType == TaskTypeEnum.TransferStockIn) &&
|
||||
(p.TaskStatus != TaskStatusEnum.Completed)
|
||||
);
|
||||
|
||||
List<long> sameBatchColIds = storageRacks
|
||||
.Where(p =>
|
||||
p.MateriaBatch == materialBatch ||
|
||||
(!uncompletedTasks.IsNullOrEmpty() && uncompletedTasks.Select(x => x.EndPositionCode).Contains(p.StorageRackNo))
|
||||
)
|
||||
.Select(p => p.ReservoirAreaColumnId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (sameBatchColIds.IsNullOrEmpty())
|
||||
{
|
||||
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<StorageRackDto> sameBatchInclude = storageRacks
|
||||
.Where(p => sameBatchColIds.Contains(p.ReservoirAreaColumnId))
|
||||
.ToList();
|
||||
|
||||
var sameBatchIncludeCol = sameBatchInclude.GroupBy(p => p.ReservoirAreaColumnId);
|
||||
|
||||
// 筛选还有空位的列(包含锁定的列)
|
||||
// 有未锁定的列优先取该列
|
||||
// 没有未锁定的列,则任取一列做中转(如果物料所处位置已经是中转区,则不执行)
|
||||
|
||||
var useableStorageCol = sameBatchIncludeCol
|
||||
.FirstOrDefault(p =>
|
||||
p.All(x => !x.IsLock) &&
|
||||
p.Any(x => !x.IsDisabled && string.IsNullOrEmpty(x.BarCode)));
|
||||
|
||||
if (useableStorageCol != null && useableStorageCol.Any())
|
||||
{
|
||||
destStorageRack = useableStorageCol
|
||||
.Where(p => !p.IsDisabled && string.IsNullOrEmpty(p.BarCode))
|
||||
.OrderByDescending(p => p.NumSort)
|
||||
.First();
|
||||
}
|
||||
else
|
||||
{
|
||||
var emptyCols = sameBatchIncludeCol.Where(p => p.Any(x => !x.IsLock && !x.IsDisabled && string.IsNullOrEmpty(x.BarCode)));
|
||||
if (emptyCols.Any())
|
||||
{
|
||||
//如果仅有一个空列,则可以开一个新列,保证最多只开2列
|
||||
if (emptyCols.Count() <= 1)
|
||||
{
|
||||
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
||||
}
|
||||
else
|
||||
{
|
||||
//一楼不允许混放或进入中转区。同批次已开启两列后,等待现有任务完成并解锁列。
|
||||
if (floor == FloorEnum.FirstFloor)
|
||||
{
|
||||
LogHelper.Warn("一楼同批次已开启两列且目标列被锁定,入库任务等待列解锁");
|
||||
return null;
|
||||
}
|
||||
|
||||
//物料已在中转区,则不可以继续在中转区生成任务
|
||||
if (startArea == TransportEnum.TransitArea)
|
||||
{
|
||||
LogHelper.Warn("目标库位所在列被锁定,中转入库任调度需要等待列解锁");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
destStorageRack = await _storageRackService.GetUsableTransferStorageRack();
|
||||
|
||||
if (destStorageRack == null)
|
||||
{
|
||||
LogHelper.Warn($"中转区已满,尝试放货到空白列或者和其他货物混放");
|
||||
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
destStorageRack = await HandleByNext(startArea, floor, materialBatch, storageRacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (destStorageRack != null)
|
||||
{
|
||||
// 先完成数据库锁定,确保数据一致性
|
||||
await _storageRackService.Lock(destStorageRack);
|
||||
}
|
||||
|
||||
return destStorageRack;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error($"入库责任链处理异常:{ex.Message} \n {ex.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_SemaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain
|
||||
{
|
||||
/// <summary>
|
||||
/// 和其他不同批次的货物混合放置
|
||||
/// </summary>
|
||||
public class StockInByMixing : StockInHandler
|
||||
{
|
||||
public override async Task<StorageRackDto> CalculateWarehouse(
|
||||
TransportEnum startArea,
|
||||
FloorEnum floor,
|
||||
string materialBatch,
|
||||
List<StorageRackDto> storageRacks)
|
||||
{
|
||||
if (storageRacks.IsNullOrEmpty())
|
||||
{
|
||||
storageRacks = await base.GetStorageRackExceptStockout(floor);
|
||||
}
|
||||
|
||||
if (storageRacks.IsNullOrEmpty())
|
||||
{
|
||||
LogHelper.Info("没有可用库位");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<StorageRackDto> wareHousesSorted = storageRacks.OrderBy(p => p.AreaNumSort).ToList();
|
||||
|
||||
IEnumerable<IGrouping<long, StorageRackDto>> groupByColumn = wareHousesSorted.GroupBy(p => p.ReservoirAreaColumnId);
|
||||
|
||||
StorageRackDto destStorageRack = null;
|
||||
foreach (var columnGroup in groupByColumn)
|
||||
{
|
||||
bool unlockedColumn = columnGroup.All(p => !p.IsLock);
|
||||
if (unlockedColumn)
|
||||
{
|
||||
destStorageRack = columnGroup
|
||||
.Where(p => string.IsNullOrEmpty(p.BarCode))
|
||||
.OrderByDescending(p => p.NumSort)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (destStorageRack != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (destStorageRack == null && startArea != TransportEnum.TransitArea)
|
||||
{
|
||||
destStorageRack = await _storageRackService.GetUsableTransferStorageRack();
|
||||
|
||||
if (destStorageRack == null)
|
||||
{
|
||||
LogHelper.Warn($"存储区和中转区均无可用的库位");
|
||||
}
|
||||
}
|
||||
|
||||
return destStorageRack;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain
|
||||
{
|
||||
/// <summary>
|
||||
/// 放置在一个空白列列上
|
||||
/// </summary>
|
||||
public class StockInByNew : StockInHandler
|
||||
{
|
||||
public override async Task<StorageRackDto> CalculateWarehouse(
|
||||
TransportEnum startArea,
|
||||
FloorEnum floor,
|
||||
string materialBatch,
|
||||
List<StorageRackDto> storageRacks)
|
||||
{
|
||||
if (storageRacks.IsNullOrEmpty())
|
||||
{
|
||||
storageRacks = await base.GetStorageRackExceptStockout(floor);
|
||||
}
|
||||
|
||||
if (storageRacks.IsNullOrEmpty())
|
||||
{
|
||||
LogHelper.Info("没有可用库位");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<StorageRackDto> storageRacksSorted = storageRacks
|
||||
.OrderBy(p => p.AreaNumSort)
|
||||
.ThenBy(p => p.ReservoirAreaColumnId).ToList();
|
||||
|
||||
var groupByColumn = storageRacksSorted.GroupBy(p => p.ReservoirAreaColumnId);
|
||||
|
||||
StorageRackDto destWarehouse = null;
|
||||
foreach (IGrouping<long, StorageRackDto> column in groupByColumn)
|
||||
{
|
||||
if (column.All(p => p.IsEmpty()))
|
||||
{
|
||||
destWarehouse = column.OrderByDescending(p => p.NumSort).First();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (destWarehouse == null)
|
||||
{
|
||||
return await HandleByNext(startArea, floor,materialBatch, storageRacksSorted);
|
||||
}
|
||||
else
|
||||
{
|
||||
return destWarehouse;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Domain.Entity;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain
|
||||
{
|
||||
/// <summary>
|
||||
/// 责任链模式。入库处理基类 。责任流动方向:StockInByExist=》StockInByNew=》StockInByMixing
|
||||
/// </summary>
|
||||
public abstract class StockInHandler
|
||||
{
|
||||
protected StockInHandler _nextHandler;
|
||||
protected static IStorageRackService _storageRackService = GlobalServericeProvidor.GetService<IStorageRackService>();
|
||||
protected static IAGVTaskService _agvTaskService = GlobalServericeProvidor.GetService<IAGVTaskService>();
|
||||
protected static IERPTaskService _erpTaskService = GlobalServericeProvidor.GetService<IERPTaskService>();
|
||||
|
||||
protected static IStorageRackService StorageRackService = GlobalServericeProvidor.GetService<IStorageRackService>();
|
||||
protected static readonly SemaphoreSlim _SemaphoreSlim = new(1,1);
|
||||
|
||||
public void SetNextHandler(StockInHandler nextHandler)
|
||||
{
|
||||
_nextHandler = nextHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算目标库位
|
||||
/// </summary>
|
||||
/// <param name="startStorageRack">起点</param>
|
||||
/// <param name="materialBatch">批次</param>
|
||||
/// <param name="storageRacks">所有未禁用的库位</param>
|
||||
/// <returns></returns>
|
||||
public abstract Task<StorageRackDto> CalculateWarehouse(
|
||||
TransportEnum startArea, FloorEnum floor, string materialBatch, List<StorageRackDto> storageRacks);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 有下一个处理者,则继续执行下一个处理者的逻辑
|
||||
/// </summary>
|
||||
/// <param name="startStorageRack">起点</param>
|
||||
/// <param name="materialBatch">批次</param>
|
||||
/// <param name="storageRacks">所有未禁用的库位</param>
|
||||
/// <returns></returns>
|
||||
public async Task<StorageRackDto> HandleByNext(
|
||||
TransportEnum startArea,
|
||||
FloorEnum floor,
|
||||
string materialBatch,
|
||||
List<StorageRackDto> storageRacks)
|
||||
{
|
||||
if (_nextHandler != null)
|
||||
{
|
||||
return await _nextHandler.CalculateWarehouse(startArea, floor, materialBatch, storageRacks);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<StorageRackDto>> GetStorageRackExceptStockout(FloorEnum floor)
|
||||
{
|
||||
List<StorageRackDto> storageRacks = await StorageRackService.GetListByExpression(p =>
|
||||
p.Floor == floor &&
|
||||
p.Transport == TransportEnum.NormalArea);
|
||||
|
||||
if(storageRacks.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<ERPTaskDto> erpTaskStockOuts = await _erpTaskService
|
||||
.GetListByExpression(p =>
|
||||
p.CreationTime > DateTime.Now.AddDays(-1) &&
|
||||
p.TaskStatus == TaskStatusEnum.InExecution &&
|
||||
(p.TaskType == TaskTypeEnum.SaleOut || p.TaskType == TaskTypeEnum.ProductionOut)
|
||||
);
|
||||
|
||||
if (!erpTaskStockOuts.IsNullOrEmpty())
|
||||
{
|
||||
List<AGVTaskDto> agvTaks = await _agvTaskService.GetListByExpression(p =>
|
||||
p.CreationTime > DateTime.Now.AddDays(-1) &&
|
||||
erpTaskStockOuts.Select(x => x.Id).Contains(p.ErpTaskId)
|
||||
);
|
||||
|
||||
if (!agvTaks.IsNullOrEmpty())
|
||||
{
|
||||
List<StorageRackDto> startStorageRacks = await StorageRackService.GetListByExpression(p =>
|
||||
agvTaks.Select(x => x.StartPositionCode).Contains(p.StorageRackNo));
|
||||
|
||||
List<long> exceptCols = startStorageRacks.Select(p => p.ReservoirAreaColumnId).Distinct().ToList();
|
||||
|
||||
storageRacks.RemoveAll(p => exceptCols.Contains(p.ReservoirAreaColumnId));
|
||||
}
|
||||
}
|
||||
|
||||
return storageRacks;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Business.StockIn.IService;
|
||||
using JSMachine.WMS.Business.StockIn.ServiceImpl.Strategy;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using JSMachine.WMS.PLC.ModbusImpl.Elevator.Util;
|
||||
using JSMachine.WMS.RPC.ErpRPC.Dto.In.XRBusinessResult;
|
||||
using JSMachine.WMS.RPC.ErpRPC.Dto.Out.XRBusinessResult;
|
||||
using JSMachine.WMS.RPC.ErpRPC.IService;
|
||||
using NPOI.OpenXmlFormats.Dml.Chart;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl
|
||||
{
|
||||
/// <summary>
|
||||
/// PDA入库业务类
|
||||
/// </summary>
|
||||
public class StockInService : IStockInService
|
||||
{
|
||||
private IPaperStorageService _paperStorageService;
|
||||
private IStorageRackService _storageRackService;
|
||||
private IERPTaskService _erpTaskService;
|
||||
private IAGVTaskService _agvTaskService;
|
||||
private IElevatorPlcQueueService _elevatorPlcQueueService;
|
||||
public StockInService(
|
||||
IPaperStorageService paperStorageService,
|
||||
IStorageRackService storageRackService,
|
||||
IERPTaskService erpTaskService,
|
||||
IAGVTaskService agvTaskService,
|
||||
IElevatorPlcQueueService elevatorPlcQueueService
|
||||
)
|
||||
{
|
||||
_paperStorageService = paperStorageService;
|
||||
_storageRackService = storageRackService;
|
||||
_erpTaskService = erpTaskService;
|
||||
_agvTaskService = agvTaskService;
|
||||
_elevatorPlcQueueService = elevatorPlcQueueService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PDA入库
|
||||
/// </summary>
|
||||
/// <param name="stockInParam"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> StockIn(PDAInParam stockInParam)
|
||||
{
|
||||
// 入库流程依次校验重复任务、物料和起点库位,再计算目标库位并创建任务。
|
||||
//1.查询物料信息是否存在
|
||||
//2.查询库位是否存在
|
||||
//3.计算目标库位并锁定
|
||||
//4.写入ErpTask表
|
||||
|
||||
bool existUnCompleteTask = await _erpTaskService.Exist(p =>
|
||||
p.CreationTime > DateTime.Now.Date &&
|
||||
(p.TaskType == TaskTypeEnum.PdaIn || p.TaskType==TaskTypeEnum.TailIn)&&
|
||||
(p.TaskStatus == TaskStatusEnum.Initial || p.TaskStatus == TaskStatusEnum.InExecution) &&
|
||||
p.BarCode == stockInParam.BarCode);
|
||||
|
||||
if (existUnCompleteTask)
|
||||
{
|
||||
LogHelper.Warn($"合格证号 {stockInParam.BarCode} 已有待入库的任务,请检查是否扫错");
|
||||
return $"合格证号 {stockInParam.BarCode} 已有待入库的任务,请检查是否扫错";
|
||||
}
|
||||
|
||||
MateriaInfoDto materiaInfo = await CheckMaterialInfo(stockInParam.BarCode);
|
||||
if (materiaInfo == null)
|
||||
{
|
||||
string msg = $"未在ERP中查询到合格证号为 {stockInParam.BarCode} 的物料信息";
|
||||
|
||||
LogHelper.Warn(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
StorageRackDto startStoragRack = await _storageRackService.GetSingalByExpression(p =>
|
||||
p.StorageRackNo == stockInParam.StorageRackNo &&
|
||||
!p.IsDisabled);
|
||||
|
||||
if (startStoragRack == null)
|
||||
{
|
||||
string msg = $"入库起点库位 {stockInParam.StorageRackNo} 不可用";
|
||||
|
||||
LogHelper.Warn(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
//如果是尾托回库,需要自动计算任务楼层
|
||||
if (stockInParam.TaskType == TaskTypeEnum.TailIn)
|
||||
{
|
||||
AGVTaskDto outTask = await _agvTaskService.GetSingalByExpression(p =>
|
||||
p.BarCode == stockInParam.BarCode &&
|
||||
(p.TaskType == TaskTypeEnum.SaleOut || p.TaskType == TaskTypeEnum.TransferStockOut) &&
|
||||
!p.StartPositionCode.Contains("TSJ"),
|
||||
p => p.CreationTime,
|
||||
SqlSugar.OrderByType.Desc);
|
||||
|
||||
if (outTask == null)
|
||||
{
|
||||
string msg = $"合格证号 {stockInParam.BarCode} 批次 {materiaInfo.MateriaBatch} 没有对应的出库任务," +
|
||||
$"因此不知道该物料原来所属楼层,请人工将该货物放置到合适的库位上,然后使用pda更新物料信息";
|
||||
LogHelper.Error(msg);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
stockInParam.Floor = outTask.Floor;
|
||||
}
|
||||
|
||||
//预先计算可用的库位(所有未禁用,空白库位-未完成的入库任务)
|
||||
int usableWarehouseCout = await _storageRackService.Count(p =>
|
||||
p.Floor == stockInParam.Floor &&
|
||||
p.Transport == TransportEnum.NormalArea &&
|
||||
!p.IsDisabled);
|
||||
int unCompleteErpTaskCount = await _erpTaskService.Count(p =>
|
||||
p.CreationTime > DateTime.Now.Date &&
|
||||
(p.TaskType == TaskTypeEnum.PdaIn || p.TaskType == TaskTypeEnum.TailIn) &&
|
||||
!(p.TaskStatus == TaskStatusEnum.Completed || p.TaskStatus == TaskStatusEnum.Cancelled)
|
||||
);
|
||||
|
||||
if (usableWarehouseCout- unCompleteErpTaskCount <=0)
|
||||
{
|
||||
string msg = $"没有空余库位,无法入库";
|
||||
|
||||
LogHelper.Warn(msg);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ERPTaskDto erpTask = CreateErpTask(stockInParam, materiaInfo);
|
||||
bool bRet = await _erpTaskService.Add(erpTask);
|
||||
if (!bRet)
|
||||
{
|
||||
string msg = $"数据库操作失败";
|
||||
|
||||
LogHelper.Warn(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从ERPTask生成AgvTask(pda入库)
|
||||
/// </summary>
|
||||
/// <param name="erpTask"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> CreateAgvTaskFirstFloor(ERPTaskDto erpTask)
|
||||
{
|
||||
//1.入库到一楼寻找一楼库位
|
||||
//2.入库到二楼寻找一楼提升机库位
|
||||
|
||||
StorageRackDto destWareHouse = await CalculateDestWarehouse(erpTask, erpTask.MateriaBatch, erpTask.Floor);
|
||||
if (destWareHouse == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AGVTaskDto agvTask = new()
|
||||
{
|
||||
ErpTaskId = erpTask.Id,
|
||||
BarCode = erpTask.BarCode,
|
||||
OrderNo = erpTask.OrderNo,
|
||||
CustomName = erpTask.CustomName,
|
||||
MateriaName = erpTask.MateriaName,
|
||||
MateriaType = erpTask.MateriaType,
|
||||
MateriaNum = erpTask.ErpOrderNum,
|
||||
MateriaBatch = erpTask.MateriaBatch,
|
||||
MateriaCode = erpTask.MateriaCode,
|
||||
|
||||
TaskType = erpTask.TaskType,
|
||||
TaskStatus = TaskStatusEnum.Initial,
|
||||
Priority = PriorityEnum.High,
|
||||
Floor = FloorEnum.FirstFloor,
|
||||
|
||||
StartPositionCode = erpTask.StorageRackNo,
|
||||
EndPositionCode = destWareHouse.StorageRackNo,
|
||||
|
||||
ErpUploadStatus = destWareHouse.Transport == TransportEnum.Elevator ? ErpUploadStatusEnum.Unnecessary : ErpUploadStatusEnum.WaittingToUpload,
|
||||
|
||||
Transport = TransportEnum.NormalArea
|
||||
};
|
||||
|
||||
destWareHouse.IsLock = true;
|
||||
|
||||
await _storageRackService.Lock(destWareHouse);
|
||||
return await _agvTaskService.Add(agvTask);
|
||||
}
|
||||
|
||||
private async Task<MateriaInfoDto> CheckMaterialInfo(string barcode)
|
||||
{
|
||||
XRResultDto xRResult = await _paperStorageService.GetMateriaInfo(barcode);
|
||||
if (xRResult?.status == 200)
|
||||
return xRResult.data;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算目标库位
|
||||
/// </summary>
|
||||
/// <param name="materiaInfo"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<StorageRackDto> CalculateDestWarehouse(ERPTaskDto erpTask, string materiaBatch, FloorEnum floor)
|
||||
{
|
||||
//1.入库到一楼寻找一楼库位
|
||||
//2.入库到二楼寻找一楼提升机库位
|
||||
|
||||
if (floor == FloorEnum.FirstFloor)
|
||||
{
|
||||
IStockInStrategy stockInStrategy = StrategyFactory.CreateStockInStrategy(TransportEnum.ManualArea, floor, materiaBatch);
|
||||
|
||||
StorageRackDto destWarehouse = await stockInStrategy.CalCulateWarehouse();
|
||||
return destWarehouse;
|
||||
}
|
||||
|
||||
StorageRackDto elevatorWarehouse = await ElevatorUtil.GetUsableElevatorChannel(erpTask.Id, FloorEnum.FirstFloor);
|
||||
return elevatorWarehouse;
|
||||
}
|
||||
|
||||
private ERPTaskDto CreateErpTask(PDAInParam pdaInParam, MateriaInfoDto materiaInfoDto)
|
||||
{
|
||||
ERPTaskDto eRPTaskDto = new()
|
||||
{
|
||||
StorageRackNo = pdaInParam.StorageRackNo,
|
||||
OrderNo = materiaInfoDto.OrderNo,
|
||||
BarCode = materiaInfoDto.BarCode,
|
||||
MateriaName = materiaInfoDto.MateriaName,
|
||||
ErpOrderNum = pdaInParam.TaskType == TaskTypeEnum.PdaIn ? int.Parse(materiaInfoDto.MateriaNum) : pdaInParam.MertialNum,
|
||||
MateriaBatch = materiaInfoDto.MateriaBatch,
|
||||
MateriaCode = materiaInfoDto.MateriaCode,
|
||||
|
||||
TaskStatus = TaskStatusEnum.Initial,
|
||||
TaskType = pdaInParam.TaskType,
|
||||
Floor = pdaInParam.Floor
|
||||
};
|
||||
|
||||
return eRPTaskDto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Business.StockIn.IService;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static JSMachine.WMS.App.Dto.StorageRackDto;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.Strategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 完全混放策略
|
||||
/// </summary>
|
||||
public class CompleteMixingStrategy : IStockInStrategy
|
||||
{
|
||||
private static readonly IStorageRackService StorageRackService = GlobalServericeProvidor.GetService<IStorageRackService>();
|
||||
private FloorEnum _floor;
|
||||
private TransportEnum _startArea;
|
||||
private string _materiaBatch;
|
||||
|
||||
public CompleteMixingStrategy(TransportEnum startArea, FloorEnum floor, string materiaBatch)
|
||||
{
|
||||
_startArea = startArea;
|
||||
_materiaBatch = materiaBatch;
|
||||
_floor = floor;
|
||||
}
|
||||
|
||||
public async Task<StorageRackDto> CalCulateWarehouse()
|
||||
{
|
||||
//如果某一列有一个库位被锁定,说明该列有未完成的任务(任务完成会解锁库位),因此该列不可以再生成新的任务
|
||||
|
||||
//获取楼层的所有库位
|
||||
List<StorageRackDto> wareHouses = await StorageRackService.GetListByExpression(p =>
|
||||
p.Floor == _floor && p.Transport == TransportEnum.NormalArea);
|
||||
|
||||
if (wareHouses.IsNullOrEmpty())
|
||||
{
|
||||
LogHelper.Warn($"{_floor} 层没有空余库位");
|
||||
return null;
|
||||
}
|
||||
|
||||
wareHouses = wareHouses.OrderBy(p => p.AreaNumSort).ToList();
|
||||
|
||||
IEnumerable<IGrouping<long, StorageRackDto>> groupByColumn = wareHouses.GroupBy(p => p.ReservoirAreaColumnId);
|
||||
|
||||
StorageRackDto destStorageRack = null;
|
||||
foreach (var columnGroup in groupByColumn)
|
||||
{
|
||||
bool emptyColumn = columnGroup.All(p => !p.IsLock && !p.IsDisabled && string.IsNullOrEmpty(p.BarCode));
|
||||
if (emptyColumn)
|
||||
{
|
||||
destStorageRack = columnGroup.OrderByDescending(p => p.NumSort).First();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return destStorageRack;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.Business.StockIn.IService;
|
||||
using JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.Strategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 混合模式策略。同批次的优先放同一列,如果没有库位则混放
|
||||
/// </summary>
|
||||
public class MixedModeStrategy : IStockInStrategy
|
||||
{
|
||||
private FloorEnum _floor;
|
||||
private TransportEnum _startArea;
|
||||
private string _materiaBatch;
|
||||
public MixedModeStrategy(TransportEnum startArea, FloorEnum floor, string materiaBatch)
|
||||
{
|
||||
_floor = floor;
|
||||
_startArea = startArea;
|
||||
_materiaBatch = materiaBatch;
|
||||
}
|
||||
|
||||
public async Task<StorageRackDto> CalCulateWarehouse()
|
||||
{
|
||||
StockInByExist stockInByExist = new();
|
||||
StockInByNew stockInByNew = new();
|
||||
StockInByMixing stockInByMixing = new();
|
||||
|
||||
stockInByExist.SetNextHandler(stockInByNew);
|
||||
stockInByNew.SetNextHandler(stockInByMixing);
|
||||
|
||||
return await stockInByExist.CalculateWarehouse(_startArea, _floor, _materiaBatch, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.IService;
|
||||
using JSMachine.WMS.Business.StockIn.IService;
|
||||
using JSMachine.WMS.Business.StockIn.ServiceImpl.ResponsibilityChain;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.Infrastructure.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static JSMachine.WMS.App.Dto.StorageRackDto;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.Strategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 不混放策略
|
||||
/// </summary>
|
||||
public class NoMixingStrategy : IStockInStrategy
|
||||
{
|
||||
private static readonly IStorageRackService StorageRackService = GlobalServericeProvidor.GetService<IStorageRackService>();
|
||||
private FloorEnum _floor;
|
||||
private TransportEnum _startArea;
|
||||
private string _materiaBatch;
|
||||
public NoMixingStrategy(TransportEnum startArea, FloorEnum floor, string materiaBatch)
|
||||
{
|
||||
_floor = floor;
|
||||
_startArea = startArea;
|
||||
_materiaBatch = materiaBatch;
|
||||
}
|
||||
|
||||
public async Task<StorageRackDto> CalCulateWarehouse()
|
||||
{
|
||||
StockInByExist stockInByExist = new();
|
||||
StockInByNew stockInByNew = new();
|
||||
|
||||
stockInByExist.SetNextHandler(stockInByNew);
|
||||
|
||||
return await stockInByExist.CalculateWarehouse(_startArea, _floor, _materiaBatch, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using JSMachine.WMS.App.Dto.Enum;
|
||||
using JSMachine.WMS.App.Dto;
|
||||
using JSMachine.WMS.Business.StockIn.IService;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JSMachine.WMS.Common;
|
||||
using JSMachine.WMS.Infrastructure;
|
||||
using JSMachine.WMS.App.IService;
|
||||
|
||||
namespace JSMachine.WMS.Business.StockIn.ServiceImpl.Strategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据楼层和配置的混放模式选择入库库位计算策略。
|
||||
/// </summary>
|
||||
public class StrategyFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 0-完全不混放 1-混合模式,优先同批次放一列,没有空库位再混放 2-完全混放模式,不用批次货物放一起
|
||||
/// </summary>
|
||||
/// <param name="startArea">入库起始区域。</param>
|
||||
/// <param name="floor">目标楼层。</param>
|
||||
/// <param name="materiaBatch">物料批次。</param>
|
||||
/// <returns>与当前入库条件匹配的库位计算策略。</returns>
|
||||
public static IStockInStrategy CreateStockInStrategy(TransportEnum startArea, FloorEnum floor, string materiaBatch)
|
||||
{
|
||||
switch (floor == FloorEnum.FirstFloor ? 0 : Global.AppSettings.PlcaementMod)
|
||||
{
|
||||
case 0:
|
||||
return new NoMixingStrategy(startArea, floor, materiaBatch);
|
||||
case 1:
|
||||
return new MixedModeStrategy(startArea, floor, materiaBatch);
|
||||
case 2:
|
||||
return new CompleteMixingStrategy(startArea, floor, materiaBatch);
|
||||
default:
|
||||
return new NoMixingStrategy(startArea, floor, materiaBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user