diff --git a/WCS.BLL/Config/JsConfig.cs b/WCS.BLL/Config/JsConfig.cs index 7390edf..83b67ab 100644 --- a/WCS.BLL/Config/JsConfig.cs +++ b/WCS.BLL/Config/JsConfig.cs @@ -18,6 +18,18 @@ namespace WCS.BLL.Config /// public bool IsSameMatCodeOut { get; set; } /// + /// 数据-数据库路径 + /// + public string DataDbPath { get; set; } + /// + /// 日志-数据库路径 + /// + public string LogDbPath { get; set; } + /// + /// 权限-数据库路径 + /// + public string AuthDbPath { get; set; } + /// /// 是否接入WMS系统 /// public bool IsAccessWMS { get; set; } @@ -25,5 +37,26 @@ namespace WCS.BLL.Config /// WMS系统 /// public string? WMSUrl { get; set; } + + public bool IsResetDBOrTable { get; set; } + #region 盟讯公司后台配置 + public bool IsMx { get; set; } + /// + /// 回传Mes入库/移库 + /// + public string InputStockInStr { get; set; } + /// + /// 回传Mes出库 + /// + public string BunkerOutStr { get; set; } + /// + /// 通过条码查询物料信息接口 + /// + public string QueryBybar { get; set; } + /// + /// 后台配置的组别 + /// + public string GroupName { get; set; } + #endregion } } diff --git a/WCS.BLL/Config/LocalStatic.cs b/WCS.BLL/Config/LocalStatic.cs new file mode 100644 index 0000000..fc33ce1 --- /dev/null +++ b/WCS.BLL/Config/LocalStatic.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WCS.BLL.Config +{ + public static class LocalStatic + { + /// + /// 0x02绿色 0x04蓝色 + /// + public static byte CurrentOutStoreColor = 0x02; + } +} diff --git a/WCS.BLL/DbModels/DingDingSendUser.cs b/WCS.BLL/DbModels/DingDingSendUser.cs new file mode 100644 index 0000000..d19c848 --- /dev/null +++ b/WCS.BLL/DbModels/DingDingSendUser.cs @@ -0,0 +1,19 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WCS.BLL.DbModels +{ + [SugarTable("ding_ding_send_user")] + public class DingDingSendUser + { + /// + /// 工号 + /// + [SugarColumn(ColumnName = "user_name", Length = 50, IsNullable = true, ColumnDescription = "创建人")] + public string UserName { get; set; } + } +} diff --git a/WCS.BLL/DbModels/DocumentSerialNumber.cs b/WCS.BLL/DbModels/DocumentSerialNumber.cs index c5efd11..1860f35 100644 --- a/WCS.BLL/DbModels/DocumentSerialNumber.cs +++ b/WCS.BLL/DbModels/DocumentSerialNumber.cs @@ -12,7 +12,7 @@ namespace WCS.BLL.DbModels /// /// 用于记录单据生成到哪个序号了 /// - [SugarTable("document_serial_number")] + [SugarTable("wcs_document_serial_number")] public class DocumentSerialNumber { /// diff --git a/WCS.BLL/DbModels/InOutRecord.cs b/WCS.BLL/DbModels/InOutRecord.cs index 08014b8..080816f 100644 --- a/WCS.BLL/DbModels/InOutRecord.cs +++ b/WCS.BLL/DbModels/InOutRecord.cs @@ -12,7 +12,7 @@ namespace WCS.BLL.DbModels /// /// 出入库记录 /// - [SugarTable("in_out_record")] + [SugarTable("wcs_in_out_record")] public class InOutRecord { /// @@ -115,6 +115,33 @@ namespace WCS.BLL.DbModels [SugarColumn(ColumnName = "operate_user", Length = 100, IsNullable = true, ColumnDescription = "创建人")] public string OperateUser { get; set; } + /// + /// 串联绑定后的大货架编码 + /// + [SugarColumn(ColumnName = "Bind_shelf_code", IsNullable = true, ColumnDescription = "串联绑定后的大货架编码")] + public string? BigShelfCode { get; set; } = string.Empty; + /// + /// Row 行 + /// + [SugarColumn(ColumnName = "R", Length = 10, IsNullable = true, ColumnDescription = "库位 行")] + public string R { get; set; } + /// + /// Column 列 + /// + [SugarColumn(ColumnName = "C", Length = 10, IsNullable = true, ColumnDescription = "库位 列")] + public string C { get; set; } + /// + /// Column 位 + /// + [SugarColumn(ColumnName = "Wei", Length = 10, IsNullable = true, ColumnDescription = "库位 位 第几个库位灯")] + public string Wei { get; set; } + + /// + /// 货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架) + /// + [SugarColumn(ColumnName = "group_name", Length = 50, IsNullable = false, DefaultValue = "0", ColumnDescription = "货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架)")] + public string GroupName { get; set; } + /// /// 序号 /// diff --git a/WCS.BLL/DbModels/InventoryDetail.cs b/WCS.BLL/DbModels/InventoryDetail.cs index 3707137..93ddf90 100644 --- a/WCS.BLL/DbModels/InventoryDetail.cs +++ b/WCS.BLL/DbModels/InventoryDetail.cs @@ -11,7 +11,7 @@ namespace WCS.BLL.DbModels /// /// 库存明细表 /// - [SugarTable("inventory_detail")] + [SugarTable("wcs_inventory_detail")] public class InventoryDetail { /// @@ -102,7 +102,38 @@ namespace WCS.BLL.DbModels /// [SugarColumn(ColumnName = "is_locked", IsNullable = false, ColumnDescription = "物料是否已被锁定")] public bool IsLocked { get; set; } = false; + /// + /// 串联绑定后的大货架编码 + /// + [SugarColumn(ColumnName = "big_shelf_code", IsNullable = true, ColumnDescription = "串联绑定后的大货架编码")] + public string? BigShelfCode { get; set; } = string.Empty; + /// + /// Row 行 + /// + [SugarColumn(ColumnName = "R", Length = 10, IsNullable = true, ColumnDescription = "库位 行")] + public string R { get; set; } + /// + /// Column 列 + /// + [SugarColumn(ColumnName = "C", Length = 10, IsNullable = true, ColumnDescription = "库位 列")] + public string C { get; set; } + /// + /// Column 位 + /// + [SugarColumn(ColumnName = "Wei", Length = 10, IsNullable = true, ColumnDescription = "库位 位 第几个库位灯")] + public string Wei { get; set; } + /// + /// WarehouseCode 仓库代码 + /// + [SugarColumn(ColumnName = "WarehouseCode", Length = 10, IsNullable = true, ColumnDescription = "仓库代码")] + public string WarehouseCode { get; set; } + + /// + /// 货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架) + /// + [SugarColumn(ColumnName = "group_name", Length = 50, IsNullable = false, DefaultValue = "0", ColumnDescription = "货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架)")] + public string GroupName { get; set; } /// /// 序号 /// diff --git a/WCS.BLL/DbModels/MatBaseInfo.cs b/WCS.BLL/DbModels/MatBaseInfo.cs index 6f234ae..2b1b4a4 100644 --- a/WCS.BLL/DbModels/MatBaseInfo.cs +++ b/WCS.BLL/DbModels/MatBaseInfo.cs @@ -10,7 +10,7 @@ namespace WCS.BLL.DbModels /// ///物料基础信息 /// - [SugarTable("mat_base_info")] + [SugarTable("wcs_mat_base_info")] public partial class MatBaseInfo { /// diff --git a/WCS.BLL/DbModels/MatInfo.cs b/WCS.BLL/DbModels/MatInfo.cs index 9c392f7..896f613 100644 --- a/WCS.BLL/DbModels/MatInfo.cs +++ b/WCS.BLL/DbModels/MatInfo.cs @@ -10,7 +10,7 @@ namespace WCS.BLL.DbModels /// ///物料信息表 /// - [SugarTable("mat_info")] + [SugarTable("wcs_mat_info")] public class MatInfo { /// diff --git a/WCS.BLL/DbModels/ModuleInfo.cs b/WCS.BLL/DbModels/ModuleInfo.cs index 59eeedc..77d31c6 100644 --- a/WCS.BLL/DbModels/ModuleInfo.cs +++ b/WCS.BLL/DbModels/ModuleInfo.cs @@ -11,7 +11,7 @@ namespace WCS.DAL.DbModels /// ///模组信息表 /// - [SugarTable("module_info")] + [SugarTable("wcs_module_info")] public class ModuleInfo { @@ -27,6 +27,12 @@ namespace WCS.DAL.DbModels [SugarColumn(ColumnName = "module_code", Length = 50, IsNullable = false, ColumnDescription = "模组编码")] public string ModuleCode { get; set; } + /// + /// 货架类型Id + /// + [SugarColumn(ColumnName = "shelf_type_id", IsNullable = false,DefaultValue ="0", ColumnDescription = "货架类型Id")] + public int ShelfTypeId { get; set; } + /// /// 货架Id /// @@ -56,7 +62,11 @@ namespace WCS.DAL.DbModels /// [SugarColumn(ColumnName = "client_ip", Length = 50, IsNullable = false, ColumnDescription = "货架对应Can模块的Ip")] public string CleintIp { get; set; } - + /// + /// 货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架) + /// + [SugarColumn(ColumnName = "group_name", Length = 50, IsNullable = false, ColumnDescription = "货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架)")] + public string GroupName { get; set; } /// /// R 行 /// diff --git a/WCS.BLL/DbModels/OrderLight.cs b/WCS.BLL/DbModels/OrderLight.cs index 21fa02a..2d55396 100644 --- a/WCS.BLL/DbModels/OrderLight.cs +++ b/WCS.BLL/DbModels/OrderLight.cs @@ -20,7 +20,7 @@ namespace WCS.BLL.DbModels /// /// 出库单据号 /// - [SugarColumn(ColumnName = "order_number", Length = 50, IsNullable = false, ColumnDescription = "出库单据号")] + [SugarColumn(ColumnName = "order_number", Length = 50, IsNullable = true, ColumnDescription = "出库单据号")] public string OrderNumber { get; set; } /// diff --git a/WCS.BLL/DbModels/OutOrder.cs b/WCS.BLL/DbModels/OutOrder.cs index ae62913..aa8c4a3 100644 --- a/WCS.BLL/DbModels/OutOrder.cs +++ b/WCS.BLL/DbModels/OutOrder.cs @@ -6,7 +6,7 @@ namespace WCS.BLL.DbModels /// /// 出库单据 /// - [SugarTable("out_order")] + [SugarTable("wcs_out_order")] public class OutOrder { /// @@ -49,15 +49,25 @@ namespace WCS.BLL.DbModels /// /// 单据同步类型 /// - [SugarColumn(ColumnName = "sync_type",IsNullable = false, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] + [SugarColumn(ColumnName = "sync_type", IsNullable = false, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] public SyncTypeEnum SyncType { get; set; } + /// + /// 货架类型名称 + /// + [SugarColumn(ColumnName = "shelf_type_name", Length = 50, IsNullable = false, ColumnDescription = "货架类型名称")] + public string ShelfTypeName { get; set; } + /// + /// 货架类型Id + /// + [SugarColumn(ColumnName = "shelf_type_id", IsNullable = false, DefaultValue = "0", ColumnDescription = "货架类型Id")] + public int ShelfTypeId { get; set; } = 0; /// - /// 单据货架类型 : 单灯单据还是货架单据 - /// - [SugarColumn(ColumnName = "shelf_type", IsNullable = false, ColumnDescription = "货架类型 是信息化货架还是智能货架")] - public ShelfTypeEnum ShelfType { get; set; } + /// 货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架) + /// + [SugarColumn(ColumnName = "group_name", Length = 50, IsNullable = false, DefaultValue = "0", ColumnDescription = "货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架)")] + public string GroupName { get; set; } = string.Empty; /// /// 创建时间 @@ -71,6 +81,12 @@ namespace WCS.BLL.DbModels [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "操作员")] public string CreateUser { get; set; } + /// + /// 是否是盟讯公司盘点生成的出库单 + /// + [SugarColumn(ColumnName = "is_MXPD", IsNullable = true, ColumnDescription = "是否是盟讯公司盘点生成的出库单")] + public bool? IsMXPD { get; set; } = false; + /// /// 用于绑定DataGrid中是否选择 /// @@ -82,6 +98,12 @@ namespace WCS.BLL.DbModels /// [SugarColumn(IsIgnore = true)] public int RowNumber { get; set; } + + /// + /// 返回当前是否正在进行出库 + /// + [SugarColumn(IsIgnore = true)] + public bool IsOuting { get; set; } = false; } } diff --git a/WCS.BLL/DbModels/OutOrderDetail.cs b/WCS.BLL/DbModels/OutOrderDetail.cs index 73550b5..477c0e1 100644 --- a/WCS.BLL/DbModels/OutOrderDetail.cs +++ b/WCS.BLL/DbModels/OutOrderDetail.cs @@ -6,7 +6,7 @@ namespace WCS.BLL.DbModels /// /// 出库单据明细表 /// - [SugarTable("out_order_detail")] + [SugarTable("wcs_out_order_detail")] public class OutOrderDetail { /// diff --git a/WCS.BLL/DbModels/OutOrderMatDetail.cs b/WCS.BLL/DbModels/OutOrderMatDetail.cs index 84e1fa5..4061dca 100644 --- a/WCS.BLL/DbModels/OutOrderMatDetail.cs +++ b/WCS.BLL/DbModels/OutOrderMatDetail.cs @@ -11,7 +11,7 @@ namespace WCS.BLL.DbModels /// /// 出库物料明细(库存数据加锁后缓存对应的数据并记录状态) /// - [SugarTable("out_order_mat_detail")] + [SugarTable("wcs_out_order_mat_detail")] public class OutOrderMatDetail { /// @@ -127,6 +127,12 @@ namespace WCS.BLL.DbModels [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "操作员")] public string CreateUser { get; set; } + /// + /// 是否是盟讯公司盘点生成的出库单 + /// + [SugarColumn(ColumnName = "is_MXPD", IsNullable = true, ColumnDescription = "是否是盟讯公司盘点生成的出库单")] + public bool? IsMXPD { get; set; } = false; + /// /// 用于绑定中显示序号 /// diff --git a/WCS.BLL/DbModels/ShelfInfo.cs b/WCS.BLL/DbModels/ShelfInfo.cs index df5f5f6..8448f0b 100644 --- a/WCS.BLL/DbModels/ShelfInfo.cs +++ b/WCS.BLL/DbModels/ShelfInfo.cs @@ -8,7 +8,7 @@ using WCS.BLL.HardWare; namespace WCS.DAL.DbModels { - [SugarTable("shelf_info")] + [SugarTable("wcs_shelf_info")] public class ShelfInfo { @@ -42,6 +42,12 @@ namespace WCS.DAL.DbModels [SugarColumn(ColumnName = "current_mode", IsNullable = false, ColumnDescription = "货架当前状态")] public Mode CurrentMode { get; set; } + /// + /// 货架设置当前模式的时间 + /// + [SugarColumn(ColumnName = "set_current_mode_time", IsNullable = true, ColumnDescription = "设置货架当前模式的时间")] + public DateTime SetCurrentModeTime { get; set; } + /// /// 货架行数 /// @@ -83,7 +89,7 @@ namespace WCS.DAL.DbModels /// 串联绑定后的大货架编码 /// [SugarColumn(ColumnName = "Bind_shelf_code", IsNullable = true, ColumnDescription = "串联绑定后的大货架编码")] - public string? BindShelfCode { get; set; } = string.Empty; + public string? BigShelfCode { get; set; } = string.Empty; /// /// 序号 diff --git a/WCS.BLL/DbModels/ShelfTypeInfo.cs b/WCS.BLL/DbModels/ShelfTypeInfo.cs index 6b0db4b..5e84a14 100644 --- a/WCS.BLL/DbModels/ShelfTypeInfo.cs +++ b/WCS.BLL/DbModels/ShelfTypeInfo.cs @@ -10,7 +10,7 @@ namespace WCS.BLL.DbModels /// /// 货架类型 /// - [SugarTable("shelf_type")] + [SugarTable("wcs_shelf_type")] public class ShelfTypeInfo { [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] diff --git a/WCS.BLL/DbModels/StockTakingOrder.cs b/WCS.BLL/DbModels/StockTakingOrder.cs index 47498ce..ccd2e36 100644 --- a/WCS.BLL/DbModels/StockTakingOrder.cs +++ b/WCS.BLL/DbModels/StockTakingOrder.cs @@ -11,7 +11,7 @@ namespace WCS.BLL.DbModels /// /// 盘点单据 /// - [SugarTable("stock_taking_order")] + [SugarTable("wcs_stock_taking_order")] public class StockTakingOrder { /// diff --git a/WCS.BLL/DbModels/StockTakingOrderMatDetail.cs b/WCS.BLL/DbModels/StockTakingOrderMatDetail.cs index 203ebb3..83b9c33 100644 --- a/WCS.BLL/DbModels/StockTakingOrderMatDetail.cs +++ b/WCS.BLL/DbModels/StockTakingOrderMatDetail.cs @@ -11,7 +11,7 @@ namespace WCS.BLL.DbModels /// /// 盘点单据物料明细 /// - [SugarTable("stock_taking_order_matdetail")] + [SugarTable("wcs_stock_taking_order_matdetail")] public class StockTakingOrderMatDetail { /// diff --git a/WCS.BLL/DbModels/StoreInfo.cs b/WCS.BLL/DbModels/StoreInfo.cs index 0f84620..1b6a409 100644 --- a/WCS.BLL/DbModels/StoreInfo.cs +++ b/WCS.BLL/DbModels/StoreInfo.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace WCS.DAL.DbModels { - [SugarTable("store_info")] + [SugarTable("wcs_store_info")] public partial class StoreInfo { /// @@ -21,12 +21,16 @@ namespace WCS.DAL.DbModels /// [SugarColumn(ColumnName = "store_code", Length = 50, IsNullable = false, ColumnDescription = "库位编码")] public string StoreCode { get; set; } - + /// + /// 货架类型Id + /// + [SugarColumn(ColumnName = "shelf_type_id", IsNullable = false, DefaultValue = "0", ColumnDescription = "货架类型Id")] + public int ShelfTypeId { get; set; } /// /// 模组Id /// [SugarColumn(ColumnName = "module_id", IsNullable = false, ColumnDescription = "模组Id")] - public int ModuleId { get; set; } + public int ModuleId { get; set; } /// /// 模组编号 @@ -88,6 +92,33 @@ namespace WCS.DAL.DbModels [SugarColumn(ColumnName = "offset_voltage", IsNullable = true, ColumnDescription = "电压偏移值")] public decimal OffsetVoltage { get; set; } + /// + /// 串联绑定后的大货架编码 + /// + [SugarColumn(ColumnName = "Bind_shelf_code", IsNullable = true, ColumnDescription = "串联绑定后的大货架编码")] + public string? BigShelfCode { get; set; } = string.Empty; + /// + /// Row 行 + /// + [SugarColumn(ColumnName = "R", Length = 10, IsNullable = true, ColumnDescription = "库位 行")] + public string R { get; set; } + /// + /// Column 列 + /// + [SugarColumn(ColumnName = "C", Length = 10, IsNullable = true, ColumnDescription = "库位 列")] + public string C { get; set; } + /// + /// Column 位 + /// + [SugarColumn(ColumnName = "Wei", Length = 10, IsNullable = true, ColumnDescription = "库位 位 第几个库位灯")] + public string Wei { get; set; } + + /// + /// 货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架) + /// + [SugarColumn(ColumnName = "group_name", Length = 50, IsNullable = false, DefaultValue = "0", ColumnDescription = "货架的组别、区域(区分单个软件管哪些货架的,前端的配置文件配置一个组别,查询时只显示当前组别的货架)")] + public string GroupName { get; set; } + /// /// 序号 /// diff --git a/WCS.BLL/DbModels/SystemApiLogRecord.cs b/WCS.BLL/DbModels/SystemApiLogRecord.cs index e1ae5a9..6746e34 100644 --- a/WCS.BLL/DbModels/SystemApiLogRecord.cs +++ b/WCS.BLL/DbModels/SystemApiLogRecord.cs @@ -10,7 +10,7 @@ namespace WCS.BLL.DbModels /// /// 系统接口日志记录 /// - [SugarTable("system_api_log_record")] + [SugarTable("wcs_system_api_log_record")] public class SystemApiLogRecord { /// diff --git a/WCS.BLL/HardWare/IShelfBase.cs b/WCS.BLL/HardWare/IShelfBase.cs index c346d22..9738217 100644 --- a/WCS.BLL/HardWare/IShelfBase.cs +++ b/WCS.BLL/HardWare/IShelfBase.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using WCS.BLL.DbModels; using WCS.Model; +using static WCS.BLL.HardWare.WarningLight; namespace WCS.BLL.HardWare { @@ -38,12 +39,18 @@ namespace WCS.BLL.HardWare public int ColumnCounts { get; set; } public int LightId { get; set; } + public LightColorEnum LightColor { get; set; } public List ModuleIds { get; set; } + public List Modules { get; set; } public string ClientIp { get; set; } /// /// 货架当前模式 /// public Mode CurrentMode { get; set; } + /// + /// 设置到当前模式的时间 + /// + public DateTime SetCurrentModeTime { get; set; } public MatInfoResponse InStoreData { get; set; } @@ -57,6 +64,8 @@ namespace WCS.BLL.HardWare /// 货架组别 /// public string GroupName { get; set; } + + public string WebSocketIpAddress { get; set; } /// /// 模组 /// @@ -65,7 +74,7 @@ namespace WCS.BLL.HardWare /// /// 设置货架模式 /// - public void SetCurrentMode(); + public void SetCurrentMode(Mode mode); /// /// 货架进入入库模式 @@ -96,7 +105,7 @@ namespace WCS.BLL.HardWare /// /// 货架单个确认盘点 /// - public bool ConfirmStocktakingSingle(int BoardId,int LightNumber); + public bool ConfirmStocktakingSingle(int BoardId, int LightNumber); /// /// 货架退出盘点模式 diff --git a/WCS.BLL/HardWare/IWarningLightBase.cs b/WCS.BLL/HardWare/IWarningLightBase.cs index 0c3a291..b9e41d3 100644 --- a/WCS.BLL/HardWare/IWarningLightBase.cs +++ b/WCS.BLL/HardWare/IWarningLightBase.cs @@ -15,6 +15,8 @@ namespace WCS.BLL.HardWare 红色 = 0x01, 绿色 = 0x02, 蓝色 = 0x03, + //关闭仅用于后台暂存和判断使用 不用于协议 + 关闭 = 0x11, } public enum LightModeEnum { diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index e09ab83..925297c 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using WCS.BLL.DbModels; using WCS.Model; +using static WCS.BLL.HardWare.WarningLight; namespace WCS.BLL.HardWare { @@ -21,10 +22,14 @@ namespace WCS.BLL.HardWare public string OrderNumber { get; set; } public int LightId { get; set; } + public LightColorEnum LightColor { get; set; } public List ModuleIds { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string ClientIp { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public List ExceptionMessages { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public bool IsWarning { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string WebSocketIpAddress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public List Modules { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime SetCurrentModeTime { get; set; } public bool ConfirmStocktakingSingle(int BoardId, int LightNumber) { @@ -34,58 +39,58 @@ namespace WCS.BLL.HardWare public void GoInInstore(string IPAdress) { //找到对应的灯 亮灯 - + } public void GoInOutstore(List MatDetails, OutOrder outOrder) { - throw new NotImplementedException(); + } public void GoInStocktaking() { - throw new NotImplementedException(); + } public void GoInStocktaking(List MatDetails, StockTakingOrder outOrder) { - throw new NotImplementedException(); + } public void GoOutInstore() { //找到已亮灯的 灭灯 - throw new NotImplementedException(); + } public void GoOutOutstore() { - throw new NotImplementedException(); + } public void GoOutStocktaking() { - throw new NotImplementedException(); + } public void Reset() { - throw new NotImplementedException(); + return; } - public void SetCurrentMode() + public void SetCurrentMode(Mode mode) { - throw new NotImplementedException(); + } public void ShelfCheck() { - throw new NotImplementedException(); + } public void Warning() { - throw new NotImplementedException(); + } } } diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index 638efec..9ee8b49 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -1,4 +1,5 @@ -using WCS.BLL.Config; +using System; +using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.Manager; using WCS.DAL.Db; @@ -7,6 +8,7 @@ using WCS.Model; using WCS.Model.ApiModel.InOutRecord; using WCS.Model.ApiModel.OutStore; using WCS.Model.WebSocketModel; +using static WCS.BLL.HardWare.WarningLight; namespace WCS.BLL.HardWare { @@ -21,7 +23,8 @@ namespace WCS.BLL.HardWare ShelfCode = shelfInfo.ShelfCode; RowCounts = shelfInfo.Rowcounts; ColumnCounts = shelfInfo.Columncounts; - CurrentMode = shelfInfo.CurrentMode; + //CurrentMode = shelfInfo.CurrentMode; + SetCurrentMode(Mode.待机模式); ClientIp = shelfInfo.ClientIp; LightId = shelfInfo.LightId; WarningLight = new WarningLight() { LightId = shelfInfo.LightId }; @@ -53,12 +56,15 @@ namespace WCS.BLL.HardWare public int RowCounts { get; set; } public int ColumnCounts { get; set; } public Mode CurrentMode { get; set; } + public DateTime SetCurrentModeTime { get; set; } public string ModulesStr { get; set; }//当前货架所有模组的Str public string GroupName { get; set; } public List Modules { get; set; } = new List(); public TCPClient TcpCleint { get { return TCPClientManager.GetTCPClientByIPHost(ClientIp); } } public int LightId { get; set; } + + public LightColorEnum LightColor { get; set; } public bool IsWarning { get; set; } = false; public WarningLight WarningLight { get; set; } public void ClearWarning() @@ -104,6 +110,9 @@ namespace WCS.BLL.HardWare public List ModuleIds { get; set; } public string ClientIp { get; set; } + //websocket通知的前端的IP地址 + public string WebSocketIpAddress { get; set; } = "127.0.0.2"; + #region 协议处理 public void GoInInstore(string? IPAddress) { @@ -121,7 +130,8 @@ namespace WCS.BLL.HardWare } else { - this.CurrentMode = Mode.入库模式; + //this.CurrentMode = Mode.入库模式; + SetCurrentMode(Mode.入库模式); } //清空错误 ExceptionMessages.Clear(); @@ -186,7 +196,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); @@ -218,7 +228,8 @@ namespace WCS.BLL.HardWare } else { - this.CurrentMode = Mode.待机模式; + //this.CurrentMode = Mode.待机模式; + SetCurrentMode(Mode.待机模式); } //清空错误 @@ -255,7 +266,8 @@ namespace WCS.BLL.HardWare .ToList(); if (list.Count > 0) { - CurrentMode = Mode.待机模式; + //CurrentMode = Mode.待机模式; + SetCurrentMode(Mode.待机模式); foreach (var item in list) { ExceptionMessages.Add($"模组{item.ModuleCode}未成功退出入库模式!"); @@ -267,20 +279,208 @@ namespace WCS.BLL.HardWare var warningModel = new WebSocketMessageModel() { IsWarning = true, - WarningType = WarningTypeEnum.进入入库未响应, + WarningType = WarningTypeEnum.退出入库未响应, StoreId = 0, StoreCode = "", ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } //报警灯熄灭 WarningLight.CloseLight(TcpCleint); + //通知前台货架已结束入库 + Task.Run(() => + { + var warningModel = new WebSocketMessageModel() + { + IsWarning = false, + WarningType = WarningTypeEnum.通知前台结束入库, + StoreId = 0, + StoreCode = "", + ShelfCode = ShelfCode, + ShelfId = ShelfId, + ClientIp = WebSocketIpAddress, + }; + WarningManager.SendWarning(warningModel); + }); } + /// + /// 由自检异常等错误导致的 手动操作处理后重新进入出库模式 + /// + /// + public void GoInOutstoreByWebSocket(int moduleId) + { + try + { + //找到对应的模组 + var module = Modules.Where(t => t.ModuleId == moduleId).First(); + if (module == null) + { + Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】,未找到MouduleId为{moduleId}的模组", LogsType.Outstore); + return; + } + //判断删除后是否还有继续需要亮灯的情况 + if (module.CurrentOutSns == null || module.CurrentOutSns.Count == 0) + { + Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】,模组【{module.ModuleCode}】,不存在需要继续出的物料,给其复位。", LogsType.Outstore); + //不需要这个模组继续亮灯了 + module.Reset(TcpCleint); + + //判断此货架是否还有出库模式的模块 + var isExistOuting = Modules.Where(t => t.CurrentMode == Mode.出库模式).Any(); + if (isExistOuting) + { + //还有继续出的就不管 + } + //这里的处理逻辑应与出库出了最后一盘料相同 + else + { + #region 继续出库进程 + Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】,丢失删除的料刚好为货架需要出库的最后一盘料", LogsType.Outstore); + CurrentOutOrder = null; + + //退出出库模式 + var taskGoOut = Task.Run(() => + { + GoOutOutstore(); + }); + + //看是否是分批次出库的情况 分批次亮灯 + Task.Run(async () => + { + await Task.WhenAll(taskGoOut); + if (LocalFile.Config.IsSameMatCodeOut) + { + #region 触发下一批次的物料发料 + //查一下是否是当前发料单最后一个货架(在出库模式 同一个发料单下) + var isLastShelf = ShelfManager.Shelves + .Where(t => t.OrderNumber == OrderNumber) + .Where(t => t.CurrentMode == Mode.出库模式) + .Any(); + if (!isLastShelf) + { + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料", LogsType.Outstore); + var outOrder = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == OrderNumber) + .First(); + if (outOrder != null) + { + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + + if (outOrderMatDetails != null && outOrderMatDetails.Count > 0) + { + //相邻物料亮不同颜色 这里绿色和蓝色互相切换 + LocalStatic.CurrentOutStoreColor = LocalStatic.CurrentOutStoreColor == (byte)0x02 ? (byte)0x04 : (byte)0x02; + + //存在待出库 然后之前又没亮灯的情况 => 继续分批次亮灯 + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},还有物料未出!", LogsType.Outstore); + var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode) + .Select(o => new { count = o.Count(), bb = o }) + .Where(o => o.count >= 2) + .OrderByDescending(o => o.count) + .ToList(); + //相同物料存在盘数超过2的情况,亮下一个盘数多的物料 + if (outOrderDetailCount.Count > 0) + { + var matCode = outOrderDetailCount.First().bb.Key; + outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) + .ToList(); + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},本次亮灯物料{matCode}!", LogsType.Outstore); + } + //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 + else + { + //剩余物料全出 + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},剩余物料灯全亮!", LogsType.Outstore); + } + + var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) + .Distinct() + .ToList(); + var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); + + var otherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.待机模式).ToList(); + if (otherModeShelfs != null && otherModeShelfs.Count > 0) + { + otherModeShelfs.ForEach(t => + { + t.Reset(); + }); + Thread.Sleep(1000); + } + //对应的货架对应位置 进入出库模式 亮灯 + shelfs.ForEach(shelf => + { + var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode) + + .Distinct() + .ToList(); + shelf.GoInOutstore(matDetails, outOrder); + shelf.OrderNumber = outOrder.OrderNumber; + }); + } + else + { + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},当前物料已发完!", LogsType.Outstore); + } + } + else + { + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},OutOrder为null,肯定是有问题", LogsType.Outstore); + } + } + else + { + Logs.Write($"GoInOutstoreByModule发料单{OrderNumber},非最后一个出库货架!", LogsType.Outstore); + var otherShelfs = ShelfManager.Shelves + .Where(t => t.OrderNumber == OrderNumber) + .Where(t => t.CurrentMode == Mode.出库模式) + .ToList(); + + otherShelfs.ForEach(shelf => + { + try + { + if (shelf is SmartShelf) + { + var smartShelf = (SmartShelf)shelf; + Logs.Write($"GoInOutstoreByModule货架【{smartShelf.ShelfCode}】待取物料{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore); + } + } + catch + { } + }); + } + #endregion + } + }); + #endregion + } + } + + else + { + //继续亮灯 + Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】,模组【{module.ModuleCode}】,存在需要继续出的物料,继续亮灯。", LogsType.Outstore); + module.GoInOutStoreMode(TcpCleint, module.CurrentOutSns); + WarningLight.GreenLight(TcpCleint); + } + } + catch (Exception e) + { + Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】进入出库模式发生异常!", LogsType.Outstore); + GoOutOutstore(); + throw e; + } + } public void GoInOutstore(List MatDetails, OutOrder outOrder) { try @@ -292,13 +492,15 @@ namespace WCS.BLL.HardWare //复位需要点时间间隔才能响应指令 Thread.Sleep(1500); } - CurrentMode = Mode.出库模式; + //CurrentMode = Mode.出库模式; + SetCurrentMode(Mode.出库模式); //第二步:货架添加需要出的SN 出库的领料单号 //移除货架所有现有待出库的MatSN CurrentOutStoreMatSNs.Clear(); ////添加属于当前货架的物料 CurrentOutStoreMatSNs.AddRange(MatDetails.Select(t => t.MatSN).ToList()); + Logs.Write($"货架【{ShelfCode}】本次发料物料为{string.Join(",", CurrentOutStoreMatSNs)}!", LogsType.Outstore); ////记录当前出库的发料单 CurrentOutOrder = outOrder; @@ -354,7 +556,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -362,63 +564,91 @@ namespace WCS.BLL.HardWare } catch (Exception e) { + Logs.Write($"货架【{ShelfCode}】进入出库模式发生异常!", LogsType.Outstore); GoOutOutstore(); throw e; } } public void GoOutOutstore() { - //找到在出库中的模组 - var outingModules = Modules.Where(t => t.CurrentMode == Mode.出库模式) - .ToList(); - foreach (var module in outingModules) + try { - module.GoOutOutStoreMode(TcpCleint); - } - //Task.Run(() => - //{ - //通信校验 - var timeOut = 3000; - var timeSpan = TimeSpan.FromMilliseconds(0); - var beginTime = DateTime.Now; - while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) - { - timeSpan = DateTime.Now - beginTime; - - //所有板子成功退出出库模式 表示退出出库模式成功,跳出循环 - var isExistsOutstore = outingModules.Where(t => t.CurrentMode == Mode.出库模式) - .Where(t => t.IsEnable) - .Any(); - if (!isExistsOutstore) + Logs.Write($"货架【{ShelfCode}】,开始退出出库", LogsType.Outstore); + //找到在出库中的模组 + var outingModules = Modules.Where(t => t.CurrentMode == Mode.出库模式) + .ToList(); + foreach (var module in outingModules) { - break; + module.GoOutOutStoreMode(TcpCleint); } - //循环延时处理 - Thread.Sleep(50); - } - var list = outingModules.Where(t => t.IsEnable && t.CurrentMode == Mode.出库模式).ToList(); - if (list != null && list.Count > 0) - { - var messages = list.Select(t => $"模组{t.ModuleCode}未退出出库模式!").ToList(); - messages.Add("请及时联系技术人员处理!"); - var exceptionMessage = string.Join("\r\n", messages); - var warningModel = new WebSocketMessageModel() + //通信校验 + var timeOut = 3000; + var timeSpan = TimeSpan.FromMilliseconds(0); + var beginTime = DateTime.Now; + while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) { - IsWarning = true, - WarningType = WarningTypeEnum.退出入库未响应, - StoreId = 0, - StoreCode = "", - ShelfCode = ShelfCode, - ShelfId = ShelfId, - WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", - }; - WarningManager.SendWarning(warningModel); + timeSpan = DateTime.Now - beginTime; + + //所有板子成功退出出库模式 表示退出出库模式成功,跳出循环 + var isExistsOutstore = outingModules.Where(t => t.CurrentMode == Mode.出库模式) + .Where(t => t.IsEnable) + .Any(); + if (!isExistsOutstore) + { + break; + } + //循环延时处理 + Thread.Sleep(50); + } + var list = outingModules.Where(t => t.IsEnable && t.CurrentMode == Mode.出库模式).ToList(); + if (list != null && list.Count > 0) + { + var messages = list.Select(t => $"模组{t.ModuleCode}未退出出库模式!").ToList(); + messages.Add("请及时联系技术人员处理!"); + var exceptionMessage = string.Join("\r\n", messages); + var warningModel = new WebSocketMessageModel() + { + IsWarning = true, + WarningType = WarningTypeEnum.退出出库未响应, + StoreId = 0, + StoreCode = "", + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = WebSocketIpAddress, + }; + WarningManager.SendWarning(warningModel); + } + + CurrentOutStoreMatSNs.Clear(); + WarningLight.CloseLight(TcpCleint); + SetCurrentMode(Mode.待机模式); + Logs.Write($"货架【{ShelfCode}】,结束退出出库", LogsType.Outstore); + + Task.Run(() => + { + //判断是否是当前订单最后一个出库货架 + var isOuting = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.出库模式 && t.OrderNumber == OrderNumber) + .Any(); + //WebSocket通知前台以更新左侧出库单列表的状态 + if (!isOuting) + { + #region WebSocket + var messageMode = new WebSocketMessageModel() + { + IsWarning = false, + ClientIp = WebSocketIpAddress, + WarningType = WarningTypeEnum.通知刷新出库单列表, + }; + WarningManager.SendWarning(messageMode); + #endregion + } + }); + } + catch (Exception ex) + { + Logs.Write($"货架【{ShelfCode}】,退出出库时发生异常{ex.Message}", LogsType.Outstore); } - //}); - CurrentOutStoreMatSNs.Clear(); - WarningLight.CloseLight(TcpCleint); - this.CurrentMode = Mode.待机模式; } public void GoInStocktaking(List MatDetails, StockTakingOrder stockTakingOrder) @@ -437,7 +667,8 @@ namespace WCS.BLL.HardWare Thread.Sleep(1500); } - CurrentMode = Mode.盘点模式; + //CurrentMode = Mode.盘点模式; + SetCurrentMode(Mode.盘点模式); //第二步:货架添加 盘点单号 记录当前盘点的发料单 CurrentStockTakingOrder = stockTakingOrder; @@ -503,7 +734,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -536,7 +767,7 @@ namespace WCS.BLL.HardWare var messageMode = new WebSocketMessageModel() { IsWarning = false, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, WarningType = WarningTypeEnum.通知刷新盘点 }; WarningManager.SendWarning(messageMode); @@ -590,24 +821,55 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } }); CurrentOutStoreMatSNs.Clear(); WarningLight.CloseLight(TcpCleint); - this.CurrentMode = Mode.待机模式; + //this.CurrentMode = Mode.待机模式; + SetCurrentMode(Mode.待机模式); } - void IShelfBase.Reset() + public void Reset() { - throw new NotImplementedException(); + var modules = Modules.Where(t => t.IsEnable).ToList(); + if (modules != null && modules.Count > 0) + { + modules.ForEach(t => + { + t.Reset(TcpCleint); + }); + } + WarningLight.CloseLight(TcpCleint); + //this.CurrentMode = Mode.待机模式; + SetCurrentMode(Mode.待机模式); } - void IShelfBase.SetCurrentMode() + public void QueryVoltage(int moduleId) { - throw new NotImplementedException(); + var moudle = Modules.Where(t => t.ModuleId == moduleId).First(); + if (moudle != null) + { + moudle.QueryVoltage(TcpCleint); + } + } + + public void SetCurrentMode(Mode mode) + { + this.CurrentMode = mode; + this.SetCurrentModeTime = DateTime.Now; + Task.Run(() => + { + var shelf = DbHelp.db.Queryable().Where(t => t.Id == ShelfId).First(); + if (shelf != null) + { + shelf.CurrentMode = mode; + shelf.SetCurrentModeTime = SetCurrentModeTime; + DbHelp.db.Updateable(shelf).ExecuteCommand(); + } + }); } void IShelfBase.Warning() @@ -617,9 +879,54 @@ namespace WCS.BLL.HardWare public void ShelfCheck() { - foreach (var module in Modules.Where(t => t.IsEnable).ToList()) + try { - module.ShelfCheck(TcpCleint); + OrderNumber = "自检中..."; + foreach (var module in Modules.Where(t => t.IsEnable).ToList()) + { + module.ShelfCheck(TcpCleint); + } + } + catch (Exception ex) + { + Logs.Write("自检发现异常:" + ex); + } + finally + { + OrderNumber = string.Empty; + } + } + #endregion + + #region 报警灯协议返回处理 + public void WarningLightProcess(byte[] data, int boardId, int lightNumber) + { + if (data[TcpCleint.PreFixLength + 2] == 0x20 && data[TcpCleint.PreFixLength + 3] == 0x01) + { + //常亮或关闭 0x00常亮 0x01关闭 + if (data[TcpCleint.PreFixLength + 5] == 0x00) + { + LightColor = LightColorEnum.关闭; + Logs.Write($"货架[{ShelfCode}],灯状态更新为:{LightColor}"); + } + else if (data[TcpCleint.PreFixLength + 5] == 0x01) + { + switch (data[7]) + { + case 0x01: + LightColor = LightColorEnum.红色; + break; + case 0x02: + LightColor = LightColorEnum.绿色; + break; + case 0x03: + LightColor = LightColorEnum.蓝色; + break; + default: + break; + } + Logs.Write($"货架[{ShelfCode}],灯状态更新为:{LightColor}"); + } } } #endregion @@ -627,7 +934,6 @@ namespace WCS.BLL.HardWare #region 协议返回处理 public void ProtocolProcess(byte[] data, int boardId, int lightNumber) { - Logs.Write("协议处理4"); //协议处理 判断功能位 switch (data[TcpCleint.PreFixLength + 2]) { @@ -664,12 +970,23 @@ namespace WCS.BLL.HardWare case 0x13://复位的返回信号 ResetReturnProcess(data, boardId, lightNumber); break; + case 0x17://电压值1 + QueryVoltageProcess(data, boardId, lightNumber); + break; + case 0x18://电压值2 + QueryVoltageProcess(data, boardId, lightNumber); + break; + case 0x19://电压值3 + QueryVoltageProcess(data, boardId, lightNumber); + break; + case 0x0B://自检结果反馈 + SelfCheckProcess(data, boardId, lightNumber); + break; default: ; break; } - Logs.Write("协议处理5"); } /// /// 进入入库模式返回信号处理 @@ -797,7 +1114,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -831,7 +1148,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -916,7 +1233,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!", - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -946,6 +1263,12 @@ namespace WCS.BLL.HardWare StoreCode = storeInfo.StoreCode, StoreId = storeInfo.Id, + R = storeInfo.R, + C = storeInfo.C, + Wei = storeInfo.Wei, + BigShelfCode = storeInfo.BigShelfCode, + GroupName = storeInfo.GroupName, + MatSN = this.InStoreData.materialBar, MatCode = this.InStoreData.materialCode, MatName = this.InStoreData.materialName, @@ -966,6 +1289,12 @@ namespace WCS.BLL.HardWare StoreId = storeInfo.Id, StoreInfo = storeInfo, + R = storeInfo.R, + C = storeInfo.C, + Wei = storeInfo.Wei, + BigShelfCode = storeInfo.BigShelfCode, + GroupName = storeInfo.GroupName, + MatSN = this.InStoreData.materialBar, MatCode = this.InStoreData.materialCode, MatName = this.InStoreData.materialName, @@ -1019,19 +1348,16 @@ namespace WCS.BLL.HardWare /// public void InStoreExceptionReturnProcess(byte[] data, int boardId, int lightNumber) { - Logs.Write("协议处理5.1"); lightNumber = (int)data[TcpCleint.PreFixLength + 4]; var storeInfo = DbHelp.db.Queryable() .Where(t => t.ShelfId == ShelfId) .Where(t => t.BoardId == boardId && t.LightNumber == lightNumber) .First(); - Logs.Write("协议处理5.2"); if (storeInfo == null) { //TO DO 库位未找到 return; } - Logs.Write("协议处理5.3"); //已放物料丢失了 物料多放了 储位恢复正常 switch (data[TcpCleint.PreFixLength + 3]) { @@ -1051,7 +1377,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, SolvedGuids = warnings.Select(t => t.Guid).ToList(), }; WarningManager.SendWarning(warningModel); @@ -1062,12 +1388,10 @@ namespace WCS.BLL.HardWare }); ProcessingExceptions.RemoveAll(t => t.BoardId == boardId); - Logs.Write("协议处理5.5"); } break; case 0x01: { - Logs.Write("协议处理5.4"); var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!"; var warningModel = new WebSocketMessageModel() { @@ -1079,7 +1403,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -1089,14 +1413,11 @@ namespace WCS.BLL.HardWare LightNumber = lightNumber, ExceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!" }); - Logs.Write("协议处理5.5"); } break; case 0x02: { - Logs.Write("协议处理5.4"); var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; - //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); var warningModel = new WebSocketMessageModel() { WarningType = WarningTypeEnum.入库中异常取出, @@ -1107,7 +1428,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -1117,7 +1438,6 @@ namespace WCS.BLL.HardWare LightNumber = lightNumber, ExceptionMessage = storeInfo.StoreCode + "入库过程中物料丢失!" }); - Logs.Write("协议处理5.5"); } break; default: @@ -1213,7 +1533,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -1247,7 +1567,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -1267,7 +1587,7 @@ namespace WCS.BLL.HardWare { if (CurrentMode != Mode.出库模式) { - Logs.Write($"出库错误:{ShelfCode}该货架模式不是出库模式或盘点模式!"); + Logs.Write($"出库错误:{ShelfCode}该货架模式不是出库模式或盘点模式!", LogsType.Outstore); return; } lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]); @@ -1289,7 +1609,7 @@ namespace WCS.BLL.HardWare if (string.IsNullOrEmpty(storeInfo.CurrentMatSn)) { //该库位是需要出库的库位,物料被多次取出or给了多个正常出库信号 - Logs.Write($"该库位是需要出库的库位,物料被反复取出or给了多个正常出库信号,库位{storeInfo.StoreCode}"); + Logs.Write($"该库位是需要出库的库位,物料被反复取出or给了多个正常出库信号,库位{storeInfo.StoreCode}", LogsType.Outstore); //暂不进行处理 return; } @@ -1297,7 +1617,7 @@ namespace WCS.BLL.HardWare //不是本次出库需要出的物料 if (!CurrentOutStoreMatSNs.Contains(storeInfo.CurrentMatSn)) { - Logs.Write($"{storeInfo.CurrentMatSn}不是本次需要出库的物料"); + Logs.Write($"{storeInfo.CurrentMatSn}不是本次需要出库的物料", LogsType.Outstore); //报警灯报警 WarningLight.WaringLightAlwaysRed(TcpCleint); return; @@ -1307,7 +1627,7 @@ namespace WCS.BLL.HardWare var inventoryDetail = DbHelp.db.Queryable().Where(t => t.MatSN == storeInfo.CurrentMatSn).First(); if (inventoryDetail == null) { - Logs.Write($"{storeInfo.CurrentMatSn}库存信息不存在"); + Logs.Write($"{storeInfo.CurrentMatSn}库存信息不存在", LogsType.Outstore); //报警灯报警 WarningLight.WaringLightAlwaysRed(TcpCleint); return; @@ -1321,7 +1641,7 @@ namespace WCS.BLL.HardWare if (orderMatDetails == null) { - Logs.Write($"{storeInfo.CurrentMatSn},OrderDetail出库明细信息不存在"); + Logs.Write($"{storeInfo.CurrentMatSn},OrderDetail出库明细信息不存在", LogsType.Outstore); //报警灯报警 WarningLight.WaringLightAlwaysRed(TcpCleint); return; @@ -1342,6 +1662,12 @@ namespace WCS.BLL.HardWare StoreId = storeInfo.Id, StoreInfo = storeInfo, + R = storeInfo.R, + C = storeInfo.C, + Wei = storeInfo.Wei, + BigShelfCode = storeInfo.BigShelfCode, + GroupName = storeInfo.GroupName, + MatSN = inventoryDetail.MatSN, MatCode = inventoryDetail.MatCode, MatName = inventoryDetail.MatName, @@ -1350,8 +1676,9 @@ namespace WCS.BLL.HardWare MatSpec = inventoryDetail.MatSpec, MatCustomer = inventoryDetail.MatCustomer, MatSupplier = inventoryDetail.MatSupplier, + OrderNumber = orderMatDetails.OrderNumber, - Direction = DirectionEnum.出库, + Direction = orderMatDetails.IsMXPD == false ? DirectionEnum.出库 : DirectionEnum.盘点下架, }; //库位表 修改 storeInfo.CurrentMatSn = string.Empty; @@ -1385,14 +1712,26 @@ namespace WCS.BLL.HardWare //确认本次出库 module.ComfirmOutstore(TcpCleint, data[TcpCleint.PreFixLength + 3]); - + //更新时间 避免被自动退出 + Task.Run(() => + { + var shelves = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.出库模式 && t.OrderNumber == OrderNumber).ToList(); + foreach (var shelf in shelves) + { + shelf.SetCurrentModeTime = DateTime.Now; + } + }); //当前柜子是否还存在未出库的 + Logs.Write($"货架【{ShelfCode}】,用户取出物料{matSN}", LogsType.Outstore); CurrentOutStoreMatSNs.RemoveAll(t => t == matSN);//删除本次已出的物料SN + Logs.Write($"货架【{ShelfCode}】,当前货架剩余物料{string.Join(",", CurrentOutStoreMatSNs)}", LogsType.Outstore); + var isExsistOut = CurrentOutStoreMatSNs.Any(); var tempOrder = CurrentOutOrder; + var isMXPD = orderMatDetails.IsMXPD == true; //通知前台刷新 Task.Run(() => { @@ -1402,8 +1741,8 @@ namespace WCS.BLL.HardWare var messageMode = new WebSocketMessageModel() { IsWarning = false, - ClientIp = "127.0.0.1", - WarningType = WarningTypeEnum.通知刷新出库 + ClientIp = WebSocketIpAddress, + WarningType = isMXPD ? WarningTypeEnum.通知刷新盟讯盘点 : WarningTypeEnum.通知刷新出库 }; WarningManager.SendWarning(messageMode); }); @@ -1411,6 +1750,7 @@ namespace WCS.BLL.HardWare //本次亮灯的物料已全部取出 if (!isExsistOut) { + Logs.Write($"货架【{ShelfCode}】,本次亮灯的物料已全部取出", LogsType.Outstore); CurrentOutOrder = null; //退出出库模式 @@ -1418,6 +1758,7 @@ namespace WCS.BLL.HardWare { GoOutOutstore(); }); + //看是否是分批次出库的情况 分批次亮灯 Task.Run(async () => { @@ -1432,7 +1773,7 @@ namespace WCS.BLL.HardWare .Any(); if (!isLastShelf) { - Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料"); + Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料", LogsType.Outstore); var outOrder = DbHelp.db.Queryable() .Where(t => t.OrderNumber == OrderNumber) .First(); @@ -1446,8 +1787,11 @@ namespace WCS.BLL.HardWare if (outOrderMatDetails != null && outOrderMatDetails.Count > 0) { + //相邻物料亮不同颜色 这里绿色和蓝色互相切换 + LocalStatic.CurrentOutStoreColor = LocalStatic.CurrentOutStoreColor == (byte)0x02 ? (byte)0x04 : (byte)0x02; + //存在待出库 然后之前又没亮灯的情况 => 继续分批次亮灯 - Logs.Write($"发料单{OrderNumber},还有物料未出!"); + Logs.Write($"发料单{OrderNumber},还有物料未出!", LogsType.Outstore); var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode) .Select(o => new { count = o.Count(), bb = o }) .Where(o => o.count >= 2) @@ -1459,13 +1803,13 @@ namespace WCS.BLL.HardWare var matCode = outOrderDetailCount.First().bb.Key; outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) .ToList(); - Logs.Write($"发料单{OrderNumber},本次亮灯物料{matCode}!"); + Logs.Write($"发料单{OrderNumber},本次亮灯物料{matCode}!", LogsType.Outstore); } //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 else { //剩余物料全出 - Logs.Write($"发料单{OrderNumber},剩余物料灯全亮!"); + Logs.Write($"发料单{OrderNumber},剩余物料灯全亮!", LogsType.Outstore); } var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) @@ -1492,18 +1836,38 @@ namespace WCS.BLL.HardWare shelf.GoInOutstore(matDetails, outOrder); shelf.OrderNumber = outOrder.OrderNumber; }); - } else { - Logs.Write($"发料单{OrderNumber},当前物料已发完!"); + Logs.Write($"发料单{OrderNumber},当前物料已发完!", LogsType.Outstore); } } else { - Logs.Write($"发料单{OrderNumber},OutOrder为null,肯定是有问题"); + Logs.Write($"发料单{OrderNumber},OutOrder为null,肯定是有问题", LogsType.Outstore); } + } + else + { + Logs.Write($"发料单{OrderNumber},非最后一个出库货架!", LogsType.Outstore); + var otherShelfs = ShelfManager.Shelves + .Where(t => t.OrderNumber == OrderNumber) + .Where(t => t.CurrentMode == Mode.出库模式) + .ToList(); + otherShelfs.ForEach(shelf => + { + try + { + if (shelf is SmartShelf) + { + var smartShelf = (SmartShelf)shelf; + Logs.Write($"货架【{smartShelf.ShelfCode}】待取物料{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore); + } + } + catch + { } + }); } #endregion } @@ -1625,7 +1989,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, SolvedGuids = warnings.Select(t => t.Guid).ToList(), }; WarningManager.SendWarning(warningModel); @@ -1640,7 +2004,6 @@ namespace WCS.BLL.HardWare case 0x01: { var exceptionMessage = storeInfo.StoreCode + "出库过程中存在物料上架!"; - //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); var warningModel = new WebSocketMessageModel() { WarningType = WarningTypeEnum.出库中未扫描上架, @@ -1651,7 +2014,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); @@ -1666,7 +2029,6 @@ namespace WCS.BLL.HardWare case 0x02: { var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; - //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); var warningModel = new WebSocketMessageModel() { WarningType = WarningTypeEnum.出库中丢失, @@ -1677,7 +2039,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -1738,6 +2100,229 @@ namespace WCS.BLL.HardWare module.CurrentMode = Mode.待机模式; } } + + public void QueryVoltageProcess(byte[] data, int boardId, int lightNumber) + { + //第n帧 + var n = (int)data[TcpCleint.PreFixLength + 3]; + + var voltage1 = (data[TcpCleint.PreFixLength + 4] << 8) + data[TcpCleint.PreFixLength + 5]; + var voltage2 = (data[TcpCleint.PreFixLength + 6] << 8) + data[TcpCleint.PreFixLength + 7]; + var voltage3 = (data[TcpCleint.PreFixLength + 8] << 8) + data[TcpCleint.PreFixLength + 9]; + + var number1 = (n - 1) * 3 + 1; + var number2 = (n - 1) * 3 + 2; + var number3 = (n - 1) * 3 + 3; + + if (number1 <= 16) + { + var storeInfo1 = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId && t.LightNumber == number1 && t.ShelfId == ShelfId) + .First(); + if (storeInfo1 != null) + { + if (data[TcpCleint.PreFixLength + 2] == 0x17) + storeInfo1.CurrentVoltage = voltage1; + else if (data[TcpCleint.PreFixLength + 2] == 0x18) + storeInfo1.OffsetVoltage = voltage1; + else + storeInfo1.StandardVoltage = voltage1; + DbHelp.db.Updateable(storeInfo1).ExecuteCommand(); + } + } + + if (number2 <= 16) + { + var storeInfo2 = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId && t.LightNumber == number2 && t.ShelfId == ShelfId) + .First(); + if (storeInfo2 != null) + { + if (data[TcpCleint.PreFixLength + 2] == 0x17) + storeInfo2.CurrentVoltage = voltage2; + else if (data[TcpCleint.PreFixLength + 2] == 0x18) + storeInfo2.OffsetVoltage = voltage2; + else + storeInfo2.StandardVoltage = voltage2; + DbHelp.db.Updateable(storeInfo2).ExecuteCommand(); + } + } + + if (number1 <= 16) + { + var storeInfo3 = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId && t.LightNumber == number3 && t.ShelfId == ShelfId) + .First(); + if (storeInfo3 != null) + { + if (data[TcpCleint.PreFixLength + 2] == 0x17) + storeInfo3.CurrentVoltage = voltage3; + else if (data[TcpCleint.PreFixLength + 2] == 0x18) + storeInfo3.OffsetVoltage = voltage3; + else + storeInfo3.StandardVoltage = voltage3; + DbHelp.db.Updateable(storeInfo3).ExecuteCommand(); + } + } + } + + public void SelfCheckProcess(byte[] data, int boardId, int lightNumber) + { + if (data[TcpCleint.PreFixLength + 3] == 0x01) + { + //比对结果相同 + } + //比对结果不同 + else if (data[TcpCleint.PreFixLength + 3] == 0x00) + { + //获取当前板所有库位 + var storeInfos = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId) + .ToList(); + //当前设置的板库位数 + var boardStoreNumber = storeInfos.Count(); + + List dataTemp = new List(); + int index11 = 0; + while (boardStoreNumber > 0) + { + if (boardStoreNumber >= 4) + { + dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(8, '0').Reverse().ToList()); + boardStoreNumber = boardStoreNumber - 4; + } + else + { + dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(2 * boardStoreNumber, '0').Reverse().ToList()); + boardStoreNumber = 0; + } + index11++; + } + + boardStoreNumber = storeInfos.Count(); + for (int index = 0; index <= boardStoreNumber - 1; index++) + { + //当前库位异常 + if (dataTemp[2 * index + 1] == '1') + { + if (dataTemp[2 * index] == '1') + { + var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First(); + if (storeInfo != null) + { + + #region 不处理、WebSocket通知前台 + var exceptionMessage = storeInfo.StoreCode + $"自检发现物料{storeInfo.CurrentMatSn}丢失,请确认是否删除?"; + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.自检丢失, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ModuleId = storeInfo.ModuleId, + ModuleCode = storeInfo.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = WebSocketIpAddress + }; + WarningManager.SendWarning(warningModel); + #endregion + + //#region 【后台】丢失的数据处理 + //Task.Run(() => + //{ + // try + // { + // DbHelp.db.BeginTran(); + // //库位表字段清空 + // storeInfo.CurrentMatSN = string.Empty; + // DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + // //库存表记录删除、插入出入记录 + // var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreCode == storeInfo.StoreCode).First(); + // if (inventoryDetail != null) + // { + // var inOutRecord = new InOutRecord() + // { + // StoreCode = storeInfo.StoreCode, + // StoreId = storeInfo.Id, + // StoreInfo = storeInfo, + + // R = storeInfo.R, + // C = storeInfo.C, + // Wei = storeInfo.Wei, + // WarehouseCode = inventoryDetail.WarehouseCode, + + // MatSN = inventoryDetail.MatSN, + // MatCode = inventoryDetail.MatCode, + // MatName = inventoryDetail.MatName, + // MatBatch = inventoryDetail.MatBatch, + // MatQty = inventoryDetail.MatQty, + // MatSpec = inventoryDetail.MatSpec, + + // OrderNumber = inventoryDetail.OrderNumber, + // OrderProdNumber = inventoryDetail.OrderProdNumber, + // OrderMaterialCode = inventoryDetail.OrderMaterialCode, + // OrderMaterialName = inventoryDetail.OrderMaterialName, + // OrderMaterialSpec = inventoryDetail.OrderMaterialSpec, + + // GroupName = LocalFile.Config.GroupName, + + // Direction = DirectionEnum.丢失, + // }; + // DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + // DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + // } + // DbHelp.db.CommitTran(); + // } + // catch (Exception e) + // { + // DbHelp.db.RollbackTran(); + // } + //}); + //#endregion + } + //库位未配置、返回数据异常 + else + { + Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + } + } + else if (dataTemp[2 * index] == '0') + { + var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First(); + if (storeInfo != null) + { + #region 不处理、WebSocket通知前台 + var exceptionMessage = $"自检发现库位{storeInfo.StoreCode}存在物料未扫描上架,请拿下后点击【确认】消除报警"; + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.自检未扫描上架, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ModuleId = storeInfo.ModuleId, + ModuleCode = storeInfo.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = WebSocketIpAddress + }; + WarningManager.SendWarning(warningModel); + #endregion + //#region 【记录缓存异常信息】 + //var shelfStatus = LocalStatic.ShelfStatuses.Where(t => t.ShelfCode == storeInfo.ShelfCode).First(); + //LocalStatic.CheckErr.Add($"库位{storeInfo.StoreCode}:存在物料未扫描上架,请取出后重新扫描上架!"); + //#endregion + //WaringLightAlwaysRed(shelfStatus.ClientIp, shelfStatus.LightId); + } + else + { + Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + } + } + } + } + } + } #endregion } diff --git a/WCS.BLL/HardWare/SmartShelfModule.cs b/WCS.BLL/HardWare/SmartShelfModule.cs index ab59ceb..8f2e73d 100644 --- a/WCS.BLL/HardWare/SmartShelfModule.cs +++ b/WCS.BLL/HardWare/SmartShelfModule.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using TouchSocket.Core; +using WCS.BLL.Config; using WCS.DAL.Db; using WCS.DAL.DbModels; @@ -65,11 +66,22 @@ namespace WCS.BLL.HardWare /// public byte[] GoOutStockTakingModeData = { 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - /// /// 复位命令 /// public byte[] ResetData = { 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + /// + /// 查询当前电压值 + /// + public byte[] VoltageSingleData = { 0x17, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + /// + /// 电压偏移值 + /// + public byte[] OffsetSingleData = { 0x18, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + /// + /// 电压标准值 + /// + public byte[] StandardSingleData = { 0x19, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #endregion public int ModuleId { get; set; } public string ModuleCode { get; set; } @@ -185,6 +197,7 @@ namespace WCS.BLL.HardWare /// public void GoInOutStoreMode(TCPClient tcpClient, List outSns) { + Logs.Write($"模组{ModuleCode},本次亮灯物料{string.Join(",",outSns)}", LogsType.Outstore); CurrentOutSns = outSns; var storeInfos = DbHelp.db.Queryable().Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) @@ -224,6 +237,15 @@ namespace WCS.BLL.HardWare var data4 = outDataStr.Substring(0, 8); GoInOutstoreModeData[3] = Convert.ToByte(data3, 2); GoInOutstoreModeData[4] = Convert.ToByte(data4, 2); + + if (LocalFile.Config.IsSameMatCodeOut) + { + GoInOutstoreModeData[5] = LocalStatic.CurrentOutStoreColor; + } + else + { + GoInOutstoreModeData[5] = 0x02; + } } tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoInOutstoreModeData)); } @@ -370,5 +392,21 @@ namespace WCS.BLL.HardWare tcpClient.Send(tcpClient.GenerateMessage(BoardId, ComfirmOutstoreData)); } + /// + /// 查询电压值 + /// + /// + public void QueryVoltage(TCPClient tcpClient) + { + Thread.Sleep(10); + Task.Run(() => + { + tcpClient.Send(tcpClient.GenerateMessage(BoardId, VoltageSingleData)); + Thread.Sleep(50); + tcpClient.Send(tcpClient.GenerateMessage(BoardId, StandardSingleData)); + Thread.Sleep(50); + tcpClient.Send(tcpClient.GenerateMessage(BoardId, OffsetSingleData)); + }); + } } } diff --git a/WCS.BLL/Manager/DbInit.cs b/WCS.BLL/Manager/DbInit.cs index a790d46..69b92e8 100644 --- a/WCS.BLL/Manager/DbInit.cs +++ b/WCS.BLL/Manager/DbInit.cs @@ -1,9 +1,13 @@ -using System; +using SqlSugar; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using WCS.BLL.Config; using WCS.BLL.DbModels; +using WCS.BLL.HardWare; +using WCS.DAL; using WCS.DAL.Db; using WCS.DAL.Db.AuthDb; using WCS.DAL.DbModels; @@ -14,35 +18,113 @@ namespace WCS.BLL.Manager { public static void InitDb() { - DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) - , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) - , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) - , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) - , typeof(DocumentSerialNumber) - ); - - DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); - - //初始化单据序列号数据 - if (!DbHelp.db.Queryable().Any()) + Logs.Write("【初始化数据库】开始", LogsType.StartBoot); + //初始化数据库对象 + if (LocalFile.Config.IsMx) { - var outDocumentSerialNumber = new DocumentSerialNumber() + DbHelp.db = new SqlSugarScope(new ConnectionConfig() { - DocumentType = DocumentTypeEnum.出库单据, - UpdateDate = DateTime.Now, - CurrentSerialNumber = 0 - }; - - var stockTakingDocumentSerialNumber = new DocumentSerialNumber() + ConnectionString = LocalFile.Config.DataDbPath, + DbType = DbType.SqlServer,//[Sqlite]安装[System.Data.SQLite]; + IsAutoCloseConnection = true + }, db => { - DocumentType = DocumentTypeEnum.盘点单据, - UpdateDate = DateTime.Now, - CurrentSerialNumber = 0 - }; + db.Aop.OnError = ex => + { + }; + }); - DbHelp.db.Insertable(outDocumentSerialNumber).ExecuteCommand(); - DbHelp.db.Insertable(stockTakingDocumentSerialNumber).ExecuteCommand(); + //sqlserver保存接口日志时因为每个字段要限制长度,当接口返回内容长度过长会报错 + //DbHelp.dbLog = new SqlSugarScope(new ConnectionConfig() + //{ + // ConnectionString = LocalFile.Config.LogDbPath, + // DbType = DbType.SqlServer,//[Sqlite]安装[System.Data.SQLite]; + // IsAutoCloseConnection = true + //}, db => + //{ + // db.Aop.OnError = ex => + // { + // }; + //}); + + AuthDbHelp.db = new SqlSugarScope(new ConnectionConfig() + { + ConnectionString = LocalFile.Config.AuthDbPath, + DbType = DbType.SqlServer,//[Sqlite]安装[System.Data.SQLite]; + IsAutoCloseConnection = true + }, db => + { + db.Aop.OnError = ex => + { + }; + }); + Logs.Write("【初始化数据库】MX", LogsType.StartBoot); } + //手动修改后台配置后再进行CodeFirst 数据库的生成、表的生成 + if (LocalFile.Config.IsResetDBOrTable) + { + #region 建库建表 只在表有变动时运行 + DbHelp.db.DbMaintenance.CreateDatabase(); + DbHelp.dbLog.DbMaintenance.CreateDatabase(); + Logs.Write("【初始化数据库】创建数据库", LogsType.StartBoot); + + DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) + , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) + , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) + , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) + , typeof(DocumentSerialNumber),typeof(OrderLight) + ); + Logs.Write("【初始化数据库】db建表", LogsType.StartBoot); + + DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); + Logs.Write("【初始化数据库】logdb建表", LogsType.StartBoot); + + //初始化单据序列号数据 + if (!DbHelp.db.Queryable().Any()) + { + var outDocumentSerialNumber = new DocumentSerialNumber() + { + DocumentType = DocumentTypeEnum.出库单据, + UpdateDate = DateTime.Now, + CurrentSerialNumber = 0 + }; + + var stockTakingDocumentSerialNumber = new DocumentSerialNumber() + { + DocumentType = DocumentTypeEnum.盘点单据, + UpdateDate = DateTime.Now, + CurrentSerialNumber = 0 + }; + + DbHelp.db.Insertable(outDocumentSerialNumber).ExecuteCommand(); + DbHelp.db.Insertable(stockTakingDocumentSerialNumber).ExecuteCommand(); + } + Logs.Write("【初始化数据库】DocumentSerialNumber", LogsType.StartBoot); + + //初始化货架类型 + if (!DbHelp.db.Queryable().Any()) + { + var smartShelf = new ShelfTypeInfo() + { + ShelfTypeName = "智能货架" + }; + var singleLight = new ShelfTypeInfo() + { + ShelfTypeName = "信息化货架" + }; + DbHelp.db.Insertable(smartShelf).ExecuteCommand(); + DbHelp.db.Insertable(singleLight).ExecuteCommand(); + } + Logs.Write("【初始化数据库】初始化货架类型", LogsType.StartBoot); + + //初始化权限数据库 + AuthDbHelp.InitDb(); + #endregion + + LocalFile.Config.IsResetDBOrTable = false; + LocalFile.SaveConfig(); + } + Logs.Write("【初始化数据库】结束", LogsType.StartBoot); } } } diff --git a/WCS.BLL/Manager/MXBackgroundThread.cs b/WCS.BLL/Manager/MXBackgroundThread.cs new file mode 100644 index 0000000..bab8644 --- /dev/null +++ b/WCS.BLL/Manager/MXBackgroundThread.cs @@ -0,0 +1,361 @@ +using SqlSugar; +using WCS.BLL.Config; +using WCS.BLL.DbModels; +using WCS.BLL.HardWare; +using WCS.BLL.Tool; +using WCS.DAL; +using WCS.DAL.Db; +using WCS.DAL.Db.AuthDb; +using WCS.DAL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MXBackgroundThread; + +namespace WCS.BLL.Manager +{ + //盟讯公司后台方法 + public static class MXBackgroundThread + { + public static void InitBackgroundThread() + { + #region 定时任务:回传Mes入库出库 + Task.Run(() => + { + while (true) + { + //每5秒同步一次 + Thread.Sleep(5000); + try + { + var records = DbHelp.db.Queryable() + .Where(t => t.OperateTime > DateTime.Now.AddDays(-3)) //只查询回传三天内数据 + .Where(t => t.IsUpload == false) + .Includes(t => t.StoreInfo) + .OrderBy(t => t.Id) + .ToList(); + //入库记录上传 + var inventoryDetails = records.Where(t => t.Direction == DirectionEnum.入库) + .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName) + .ToList(); + if (inventoryDetails != null && inventoryDetails.Count > 0) + { + for (int i = 0; i < inventoryDetails.Count; i++) + { + try + { + //请求WMS上传入库记录 + var data = new InputStockInRequest + { + materialBar = inventoryDetails[i].MatSN, + shelfCode = inventoryDetails[i].BigShelfCode, + shelfX = "R" + inventoryDetails[i].R, + shelfY = "C" + inventoryDetails[i].C, + shelfZ = inventoryDetails[i].Wei, + inUser = inventoryDetails[i].OperateUser, + inTime = inventoryDetails[i].OperateTime.ToString("yyyy-MM-dd HH:mm:ss"), + }; + Guid guid = Guid.NewGuid(); + var result = ApiHelp.GetDataFromHttp(LocalFile.Config.InputStockInStr, data, "POST", true); + if (result != null && (result.Code == 200)) + { + //上传成功 更改上传状态 + inventoryDetails[i].IsUpload = true; + DbHelp.db.Updateable(inventoryDetails[i]).ExecuteCommand(); + } + + } + catch (Exception ex) + { + + } + Thread.Sleep(200); + } + } + + //出库记录上传 + var outRecord = records.Where(t => t.Direction == DirectionEnum.出库) + .Where(t => !string.IsNullOrEmpty(t.OrderNumber)) + .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName) + .ToList(); + if (outRecord != null && outRecord.Count > 0) + { + for (int i = 0; i < outRecord.Count; i++) + { + try + { + var retString = string.Empty; + + var data = new BunkerOutRequest() + { + materialBar = outRecord[i].MatSN, + outType = 0, + pickBillNumber = outRecord[i].OrderNumber, + qty = outRecord[i].MatQty, + }; + var result = ApiHelp.GetDataFromHttp(LocalFile.Config.BunkerOutStr, data, "POST", true); + //请求成功 + if (result != null && result.Code == 200) + { + //上传成功 更改上传状态 + outRecord[i].IsUpload = true; + DbHelp.db.Updateable(outRecord[i]).ExecuteCommand(); + } + + } + catch (Exception ex) + { + + } + Thread.Sleep(200); + } + } + } + catch (Exception ex) + { + Logs.Write("【定时任务】上传异常:" + ex.Message); + } + } + }); + #endregion + + #region 定时任务:超时退出 出库、入库、盘点模式 + Task.Run(() => + { + while (true) + { + //每10s一次 + Thread.Sleep(10000); + try + { + #region 入库模式 + var inStoreShelf = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.入库模式) + .Where(t => DateTime.Now - t.SetCurrentModeTime >= TimeSpan.FromMinutes(3)) + .ToList(); + foreach (var shelf in inStoreShelf) + { + shelf.GoOutInstore(); + Logs.Write($"【定时任务:定时退出模式】货架【{shelf.ShelfCode}】超时(3min)未退出入库模式,系统后台自动退出!"); + } + #endregion + + #region 出库模式 + //出库超过n分钟自动进入待机模式 + var outStoreShelf = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.出库模式) + .Where(t => DateTime.Now - t.SetCurrentModeTime >= TimeSpan.FromMinutes(5)) + .ToList(); + foreach (var shelf in outStoreShelf) + { + Logs.Write($"【定时任务:定时退出模式】货架【{shelf.ShelfCode}】超时(5min)未退出出库模式,系统后台自动退出!出库单[{shelf.OrderNumber}]"); + shelf.GoOutOutstore(); + } + #endregion + + #region 盘点模式 + var stockTakingShelf = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.盘点模式) + .Where(t => DateTime.Now - t.SetCurrentModeTime >= TimeSpan.FromMinutes(5)) + .ToList(); + foreach (var shelf in stockTakingShelf) + { + Logs.Write($"【定时任务:定时退出模式】货架【{shelf.ShelfCode}】超时(5min)未退出盘点模式,系统后台自动退出!盘点单[{shelf.OrderNumber}]"); + shelf.GoOutStocktaking(); + } + #endregion + } + catch (Exception e) + { + Logs.Write("【定时任务:定时退出模式】" + e.Message, LogsType.Info); + } + } + }); + #endregion + + #region 定时任务:海康未扫物料码的物料更新数据 + Task.Run(() => + { + while (true) + { + //间隔20秒同步一次 + Thread.Sleep(20000); + try + { + var inventoryDetails = DbHelp.db.Queryable() + .Where(t => t.MatName == "暂时未知") + .Where(t => t.InstoreTime > DateTime.Now.AddDays(-3)) + .ToList(); + if (inventoryDetails != null && inventoryDetails.Count > 0) + { + for (int i = 0; i < inventoryDetails.Count; i++) + { + try + { + //请求WMS获取物料的信息 + var request = new QueryBybarRequest() + { + materialBar = inventoryDetails[i].MatSN + }; + var result = ApiHelp.GetDataFromHttp(LocalFile.Config.QueryBybar, request, "POST", true); + if (result != null && (result.code == 200) && result.data != null && result.data.Count() > 0) + { + //查询成功 更改数值 + var instoreDto = result.data.FirstOrDefault(); + inventoryDetails[i].MatCode = instoreDto.materialCode; + inventoryDetails[i].MatName = instoreDto.materialName; + inventoryDetails[i].MatBatch = instoreDto.batchNo; + inventoryDetails[i].MatSpec = instoreDto.materialSpec; + inventoryDetails[i].MatQty = (int)instoreDto.materialQty; + DbHelp.db.Updateable(inventoryDetails[i]).ExecuteCommand(); + } + + } + catch (Exception ex) + { + + } + Thread.Sleep(500); + } + } + + + + } + catch (Exception ex) + { + Logs.Write("【定时任务】更新海康物料信息异常:" + ex.Message); + } + + Thread.Sleep(3000); + try + { + var inventoryDetails = DbHelp.db.Queryable() + .Where(t => t.WarehouseCode == null) + .Where(t => t.InstoreTime > DateTime.Now.AddDays(-30)) + .ToList(); + if (inventoryDetails != null && inventoryDetails.Count > 0) + { + for (int i = 0; i < inventoryDetails.Count; i++) + { + try + { + var url = $"http://192.168.2.23:9213/integrate/hkwsInventoryDetail/selectMaterialBar?materialBar={inventoryDetails[i].MatSN}"; + var result = ApiHelp.GetDataFromHttp(url, null, "POST", false); + if (result != null && result.code == 200 && result.data != null && !string.IsNullOrEmpty(result.data.warehouseCode)) + { + //查询成功 更改数值 + inventoryDetails[i].WarehouseCode = result.data.warehouseCode; + DbHelp.db.Updateable(inventoryDetails[i]).ExecuteCommand(); + } + + } + catch (Exception ex) + { + Logs.Write("【定时任务】更新仓库代码异常:" + ex.Message); + } + Thread.Sleep(500); + } + } + } + catch (Exception ex) + { + } + } + }); + #endregion + + #region 定时任务:监测警示灯关灯机制 + //判断灯颜色和模式是否对应 + Task.Run(() => + { + while (true) + { + //间隔5秒查询一次 + Thread.Sleep(5000); + try + { + //待机模式未关灯 + var shelves = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.待机模式 && t.LightColor != WarningLight.LightColorEnum.关闭) + .Where(t => t.SetCurrentModeTime < DateTime.Now.AddSeconds(-5)) + .ToList(); + foreach (var shelf in shelves) + { + try + { + if (shelf is SmartShelf) + { + var smartShelf = (SmartShelf)shelf; + smartShelf?.WarningLight.CloseLight(smartShelf.TcpCleint); + Logs.Write($"【定时任务】:监测警示灯关灯机制,关【{shelf.ShelfCode}】灯发送指令成功!"); + } + } + catch (Exception ex) + { + Logs.Write($"【定时任务】:监测警示灯关灯机制,关【{shelf.ShelfCode}】灯发生异常" + ex.Message); + } + } + + //出库模式未亮灯 + var outShelves = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.出库模式 && t.LightColor == WarningLight.LightColorEnum.关闭) + .Where(t => t.SetCurrentModeTime < DateTime.Now.AddSeconds(-5)) + .ToList(); + foreach (var shelf in outShelves) + { + try + { + if (shelf is SmartShelf) + { + var smartShelf = (SmartShelf)shelf; + smartShelf?.WarningLight.GreenLight(smartShelf.TcpCleint); + Logs.Write($"【定时任务】:监测警示灯关灯机制,出库开灯【{shelf.ShelfCode}】发送指令成功!"); + } + } + catch (Exception ex) + { + Logs.Write($"【定时任务】:监测警示灯关灯机制,出库开灯【{shelf.ShelfCode}】发生异常" + ex.Message); + } + } + } + catch (Exception ex) + { + Logs.Write("【定时任务】:监测警示灯关灯机制发生异常" + ex.Message); + } + } + }); + #endregion + } + + /// + /// 发送钉钉消息 + /// + /// 发送的消息内容 + /// 错误信息 + /// 工号列表 + /// + public static bool SendDingDingMsg(string msg, List idList, ref string errMsg) + { + try + { + #region 获取所有工程研发人员 + var list = AuthDbHelp.db.Queryable().Where(t => t.IsGCYF) + .Select(t => t.LoginName) + .ToList(); + #endregion + string ids = string.Join(",", list); + string url = "http://192.168.2.23:9213/integrate/cmccMonitor/rateAlertByCMCC?" + $"context={msg}&messageType=软件管理平台&username={ids}"; + #region 调用接口请求发送钉钉消息 + var Result = ApiHelp.GetDataFromHttp(url, null, "GET"); + if (Result != null && Result.code != 200) + { + errMsg = Result.msg; + return false; + } + return true; + #endregion + + } + catch (Exception ex) + { + errMsg = "接口调用失败"; + return false; + } + } + } +} diff --git a/WCS.BLL/Manager/ShelfManager.cs b/WCS.BLL/Manager/ShelfManager.cs index 1126322..347222e 100644 --- a/WCS.BLL/Manager/ShelfManager.cs +++ b/WCS.BLL/Manager/ShelfManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.HardWare; using WCS.DAL.Db; @@ -20,11 +21,18 @@ namespace WCS.BLL.Manager public static void InitShelves() { - var shelvesInDb = DbHelp.db.Queryable().ToList(); + Logs.Write("【InitShelves】开始", LogsType.StartBoot); + + var shelvesInDbQueryable = DbHelp.db.Queryable(); + if (LocalFile.Config.IsMx) + shelvesInDbQueryable = shelvesInDbQueryable.Where(t => t.GroupName == LocalFile.Config.GroupName); + var shelvesInDb = shelvesInDbQueryable.ToList(); foreach (var shelfInDb in shelvesInDb) { Shelves.Add(InitShelf(shelfInDb)); } + + Logs.Write("【InitShelves】结束", LogsType.StartBoot); } public static IShelfBase InitShelf(ShelfInfo shelfInDb) diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs index cc66223..91ceedc 100644 --- a/WCS.BLL/Manager/TCPClientManager.cs +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; +using WCS.BLL.Config; using WCS.BLL.HardWare; using WCS.DAL.Db; using WCS.DAL.DbModels; @@ -22,107 +23,95 @@ namespace WCS.BLL.Manager public static List TCPClients = new List(); public static void InitTcpClient() { + Logs.Write("【InitTcpClient】开始", LogsType.StartBoot); + var ips = DbHelp.db.Queryable() - //.Where(t => t.ShelfCode.Contains("C")) + .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName),t => t.GroupName == LocalFile.Config.GroupName) .Select(t => t.ClientIp) .Distinct() .ToList(); foreach (var ip in ips) { - var tcpCleint = new TCPClient(ip, ""); - //配置断线重连 - tcpCleint.tcpClient.Received += (client, e) => + Task.Run(() => { - var clientIpHost = client.IP + ":" + client.Port; - var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); - if (TcpCleint == null) + var tcpCleint = new TCPClient(ip, ""); + tcpCleint.tcpClient.Received += (client, e) => { - //TO DO - return EasyTask.CompletedTask; - } - - var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); - e.ByteBlock.Clear(); - var len = data.Length; - for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++) - { - //协议拆包 通过前缀校验是否为完整数据包 - var prefixInData = data.Skip(index).Take(TcpCleint.PreFixLength); - var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix); - if (isEqual) + var clientIpHost = client.IP + ":" + client.Port; + var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); + if (TcpCleint == null) { - Logs.Write("协议处理1!"); - var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray(); - if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度 - { - continue; - } - index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1 - //获取板子ID - var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1]; - var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]); - - Logs.Write("协议处理2!"); - //报警灯 - if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20) - { - var shelf = ShelfManager.Shelves.Where(t => t.ClientIp == clientIpHost) - .Where(t => t.LightId == boardId) - .FirstOrDefault(); - var smartShelf = shelf as SmartShelf; - smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); - } - //!= 0x20 货架类型协议返回 - else - { - Logs.Write("协议处理3!"); - var shelf = ShelfManager.Shelves - .Where(t => t.ClientIp == clientIpHost) - .Where(t => t.ModuleIds.Contains(boardId)) - .FirstOrDefault(); - var smartShelf = shelf as SmartShelf; - smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); - - } - - //协议处理 判断功能位 - //switch (dataTemp[TcpCleint.PreFixLength + 2]) - //{ - // case 0x20://进入入库模式信号 - // //GoInInstoreProcess(dataTemp, boardId, lightNumber); - // break; - // case 0x03://正常入库信号 - // //InStoreReturnProcess(dataTemp); - // break; - // default: - // ; - // break; - //} + return EasyTask.CompletedTask; } - } - Logs.Write("协议处理完毕!"); - return EasyTask.CompletedTask; - }; - //配置首次连接后复位操作 - tcpCleint.tcpClient.Connected += (client, e) => - { - var clientIpHost = client.IP + ":" + client.Port; - var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); - if (TcpCleint == null) - { - return EasyTask.CompletedTask; - } - //首次连接 - if (TcpCleint.IsFirstConnected == false) - { - InitStatus(TcpCleint); - TcpCleint.IsFirstConnected = true; - } - return EasyTask.CompletedTask; - }; - TCPClients.Add(tcpCleint); - tcpCleint.Connect(); + var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); + Logs.Write($"【接收】{BitConverter.ToString(data)}", LogsType.Instructions); + e.ByteBlock.Clear(); + var len = data.Length; + for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++) + { + //协议拆包 通过前缀校验是否为完整数据包 + var prefixInData = data.Skip(index).Take(TcpCleint.PreFixLength); + var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix); + if (isEqual) + { + var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray(); + if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度 + { + continue; + } + Logs.Write($"【处理单条指令 开始】{BitConverter.ToString(dataTemp)}", LogsType.Instructions); + index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1 + //获取板子ID + var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1]; + var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]); + //报警灯 返回来就修改对应的灯的颜色 + if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20) + { + var shelf = ShelfManager.Shelves.Where(t => t.ClientIp == clientIpHost) + .Where(t => t.LightId == boardId) + .FirstOrDefault(); + var smartShelf = shelf as SmartShelf; + smartShelf?.WarningLightProcess(dataTemp, boardId, lightNumber); + } + //!= 0x20 货架类型协议返回 + else + { + var shelf = ShelfManager.Shelves + .Where(t => t.ClientIp == clientIpHost) + .Where(t => t.ModuleIds != null && t.ModuleIds.Contains(boardId)) + .FirstOrDefault(); + var smartShelf = shelf as SmartShelf; + smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); + } + Logs.Write($"【处理单条指令 结束】{BitConverter.ToString(dataTemp)}", LogsType.Instructions); + } + } + return EasyTask.CompletedTask; + }; + //配置首次连接后复位操作 + tcpCleint.tcpClient.Connected += (client, e) => + { + var clientIpHost = client.IP + ":" + client.Port; + var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); + if (TcpCleint == null) + { + return EasyTask.CompletedTask; + } + //首次连接 + if (TcpCleint.IsFirstConnected == false) + { + Logs.Write($"【InitTcpClient】{clientIpHost}完成首次连接", LogsType.StartBoot); + Console.WriteLine($"【InitTcpClient】{clientIpHost}完成首次连接"); + InitStatus(TcpCleint); + TcpCleint.IsFirstConnected = true; + } + return EasyTask.CompletedTask; + }; + + TCPClients.Add(tcpCleint); + tcpCleint.Connect(); + }); } //启动线程监听所有TCP是否已经完成首次连接 @@ -130,22 +119,31 @@ namespace WCS.BLL.Manager { while (true) { - Thread.Sleep(1000); - var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false) - .ToList(); - if (noFirstConnectedClients.Count == 0) + try { - break; - } - else - { - noFirstConnectedClients.ForEach(t => + Thread.Sleep(1000); + var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false) + .ToList(); + if (noFirstConnectedClients.Count == 0) { - t.ReConnectAsync(); - }); + break; + } + else + { + Console.WriteLine($"存在tcp未完成首次连接,继续重连!"); + noFirstConnectedClients.ForEach(t => + { + t.ReConnectAsync(); + }); + } + } + catch (Exception ex) + { + } } }); + Logs.Write("【InitTcpClient】完成 后台继续连接", LogsType.StartBoot); } //后台启动时给所有板子、警示灯发送复位操作 保持状态一致 diff --git a/WCS.BLL/Manager/WarningManager.cs b/WCS.BLL/Manager/WarningManager.cs index ab69ca2..44d1d06 100644 --- a/WCS.BLL/Manager/WarningManager.cs +++ b/WCS.BLL/Manager/WarningManager.cs @@ -75,8 +75,15 @@ namespace WCS.BLL.Manager case WarningTypeEnum.出库自检丢失: SolveLoss(warningInManager); break; + case WarningTypeEnum.自检丢失: + SolveLoss(warningInManager); + break; } } + else if (solveType == SolveTypeEnum.忽略) + { + //不发指令了 + } //消除报警缓存信息 lock (flag) @@ -88,7 +95,6 @@ namespace WCS.BLL.Manager //货架是否还存在报警信息 shelfIsWarning = Warnings.Where(t => t.ShelfId == warning.ShelfId) .Any(); - //对应货架如果不存在报警信息了 指示灯回到对应的状态 if (!shelfIsWarning) { @@ -139,7 +145,6 @@ namespace WCS.BLL.Manager public static void SolveLoss(WebSocketMessageModel warning) { #region 【后台】丢失的数据处理 - try { //获取库位 @@ -164,6 +169,12 @@ namespace WCS.BLL.Manager StoreId = storeInfo.Id, StoreInfo = storeInfo, + R = storeInfo.R, + C = storeInfo.C, + Wei = storeInfo.Wei, + BigShelfCode = storeInfo.BigShelfCode, + GroupName = storeInfo.GroupName, + MatSN = inventoryDetail.MatSN, MatCode = inventoryDetail.MatCode, MatName = inventoryDetail.MatName, @@ -174,9 +185,45 @@ namespace WCS.BLL.Manager MatSupplier = inventoryDetail.MatSupplier, Direction = DirectionEnum.丢失, + OperateUser = warning.SolvedUser, }; DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + + #region 如果是出库 删除正在出库缓存的数据 + if (warning.WarningType == WarningTypeEnum.出库自检丢失) + { + Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,用户点击【处理】,删除数据",LogsType.Outstore); + //清掉需要出库的缓存 + var shelf = ShelfManager.Shelves + .Where(t => t.ShelfId == warning.ShelfId) + .FirstOrDefault(); + if (shelf != null) + { + var smartShelf = shelf as SmartShelf; + if (smartShelf != null) + { + //删除货架上缓存的那一条数据 + smartShelf.CurrentOutStoreMatSNs.RemoveAll(t => t == inventoryDetail.MatSN); + Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,已删除货架缓存,剩余物料为{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore); + + //删除模组上缓存的那一条数据 + var module = smartShelf.Modules.Where(t => t.ModuleId == warning.ModuleId).FirstOrDefault(); + if (module != null) { + module.CurrentOutSns.RemoveAll(t => t == inventoryDetail.MatSN); + Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,已删除模组缓存,剩余物料为{string.Join(",", module.CurrentOutSns)}", LogsType.Outstore); + } + //删除已丢失的出库明细数据 + var outOrderMatDetail = DbHelp.db.Queryable() + .Where(t => t.OrderId == smartShelf.CurrentOutOrder.Id) + .Where(t => t.MatSN == inventoryDetail.MatSN && t.IsSended == false) + .ToList(); + Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,删除出库物料明细数据{outOrderMatDetail.Count}条!"); + DbHelp.db.Deleteable(outOrderMatDetail).ExecuteCommand(); + } + } + } + #endregion } DbHelp.db.CommitTran(); } @@ -217,8 +264,9 @@ namespace WCS.BLL.Manager smartShelf.WarningLight.BlueLight(smartShelf.TcpCleint); break; case Mode.出库模式: - module.GoInOutStoreMode(smartShelf.TcpCleint, module.CurrentOutSns); - smartShelf.WarningLight.GreenLight(smartShelf.TcpCleint); + //module.GoInOutStoreMode(smartShelf.TcpCleint, module.CurrentOutSns); + //smartShelf.WarningLight.GreenLight(smartShelf.TcpCleint); + smartShelf.GoInOutstoreByWebSocket(module.ModuleId); break; case Mode.待机模式: module.Reset(smartShelf.TcpCleint); diff --git a/WCS.BLL/Manager/WebSoceketManager.cs b/WCS.BLL/Manager/WebSoceketManager.cs index 2256bd8..540bcee 100644 --- a/WCS.BLL/Manager/WebSoceketManager.cs +++ b/WCS.BLL/Manager/WebSoceketManager.cs @@ -16,6 +16,8 @@ namespace WCS.BLL.Manager public static object flag = new object(); public static void InitWebSocket() { + Console.WriteLine("【启动WebSocket】开始"); + Logs.Write("【启动WebSocket】开始", LogsType.StartBoot); service = new HttpService(); service.Setup(new TouchSocketConfig()//加载配置 .SetListenIPHosts(7789) @@ -30,11 +32,19 @@ namespace WCS.BLL.Manager .UseAutoPong();//当收到ping报文时自动回应pong a.Add();//自定义插件。 })); - + //客户端成功连接 + service.Connected = (client, e) => + { + Logs.Write("[WebSocket]" + client.GetIPPort() + "成功连接!", LogsType.StartBoot); + Console.WriteLine("[WebSocket]" + client.GetIPPort() +"成功连接!"); + return EasyTask.CompletedTask; + }; service.Start(); - service.Logger.Info("服务器已启动"); + Console.WriteLine("【启动WebSocket】结束"); + Logs.Write("【启动WebSocket】结束", LogsType.StartBoot); } - //尝试发送报警信息给前端 + + //发送报警信息给前端 public static void TrySendMessage(string IpAddress, string Message) { try diff --git a/WCS.BLL/Services/IService/IGenerateService.cs b/WCS.BLL/Services/IService/IGenerateService.cs index e9051a1..c7d1ac3 100644 --- a/WCS.BLL/Services/IService/IGenerateService.cs +++ b/WCS.BLL/Services/IService/IGenerateService.cs @@ -15,5 +15,7 @@ namespace WCS.BLL.Services.IService public Task generateStockTakingNumber(); public Task generateOutOrderNumber(); + + public Task generateMXPDOutOrderNumber(); } } diff --git a/WCS.BLL/Services/IService/IHomerService.cs b/WCS.BLL/Services/IService/IHomerService.cs index 95ade5b..3e254b8 100644 --- a/WCS.BLL/Services/IService/IHomerService.cs +++ b/WCS.BLL/Services/IService/IHomerService.cs @@ -3,6 +3,6 @@ namespace WCS.BLL.Services.IService { public interface IHomerService { - + } } diff --git a/WCS.BLL/Services/IService/IMatInventoryDetailService.cs b/WCS.BLL/Services/IService/IMatInventoryDetailService.cs index 87024f8..55e6e55 100644 --- a/WCS.BLL/Services/IService/IMatInventoryDetailService.cs +++ b/WCS.BLL/Services/IService/IMatInventoryDetailService.cs @@ -15,5 +15,7 @@ namespace WCS.BLL.Services.IService public Task> exportMatInventoryDetail(GetMatInventoryDetailRequest request); public Task>> getMatInventorySummary(GetMatInventorySummaryRequest request); + + public Task> compareMatInventoryDetail(CompareMatInventoryDetailRequest request); } } diff --git a/WCS.BLL/Services/IService/IOutstoreService.cs b/WCS.BLL/Services/IService/IOutstoreService.cs index 8726265..a80d3ff 100644 --- a/WCS.BLL/Services/IService/IOutstoreService.cs +++ b/WCS.BLL/Services/IService/IOutstoreService.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using WCS.Model; +using WCS.Model.ApiModel.MatInventoryDetail; using WCS.Model.ApiModel.OutStore; namespace WCS.BLL.Services.IService { public interface IOutstoreService { + public Task>> importMat(List list); public Task SysOutOrderByMatCode(SysOutOrderByMatCodeRequest request); public Task SysOutOrderByMatSn(SysOutOrderByMatSnRequest request); @@ -19,10 +21,11 @@ namespace WCS.BLL.Services.IService public Task GetOutOrderListByStatus(GetOutOrderListByStatusRequest request); public Task GetOutOrderDetail(GetOutOrderDetailRequest request); + public Task GetOutOrderDetailSingleLight(GetOutOrderDetailRequest request); public Task GetOutOrderMatDetail(GetOutOrderDetailRequest request); - public Task GoInOutstore(GetOutOrderDetailRequest request); + public Task GoInOutstore(GetOutOrderDetailRequest request); public Task GoOutOutstore(GetOutOrderDetailRequest request); diff --git a/WCS.BLL/Services/IService/ISelfCheckService.cs b/WCS.BLL/Services/IService/ISelfCheckService.cs index 141f61a..12793a6 100644 --- a/WCS.BLL/Services/IService/ISelfCheckService.cs +++ b/WCS.BLL/Services/IService/ISelfCheckService.cs @@ -12,5 +12,7 @@ namespace WCS.BLL.Services.IService public interface ISelfCheckService { public Task StartSelfCheckByShelfCode(StartSelfCheckByShelfCodeRequest request); + + public Task StartSelfCheckByGroupName(List GroupNames); } } diff --git a/WCS.BLL/Services/IService/IStoreInfoService.cs b/WCS.BLL/Services/IService/IStoreInfoService.cs index 49bff75..73e869b 100644 --- a/WCS.BLL/Services/IService/IStoreInfoService.cs +++ b/WCS.BLL/Services/IService/IStoreInfoService.cs @@ -32,19 +32,40 @@ namespace WCS.BLL.Services.IService /// - /// 查询货架列表 + /// 查询模组列表 /// /// /// public Task> GetModules(GetModulesRequest request); + /// + /// 禁用或启用模组 + /// + /// + /// + public Task disableOrEnableModule(DisableOrEnableModuleRequest request); /// - /// 查询货架列表 + /// 查询模组电压值 + /// + /// + /// + public Task queryModuleVoltage(QueryModuleVoltageRequest request); + + + /// + /// 查询库位列表 /// /// /// public Task> GetStores(GetStoresRequest request); + /// + /// 禁用或启用库位 + /// + /// + /// + public Task disableOrEnableStore(DisableOrEnableStoreRequest request); + } } diff --git a/WCS.BLL/Services/Service/GenerateService.cs b/WCS.BLL/Services/Service/GenerateService.cs index f89c77f..fb2ee2e 100644 --- a/WCS.BLL/Services/Service/GenerateService.cs +++ b/WCS.BLL/Services/Service/GenerateService.cs @@ -134,6 +134,15 @@ namespace WCS.BLL.Services.Service } } + public async Task generateMXPDOutOrderNumber() + { + lock (stockTakingFlag) + { + var serialNumber = GetSerialNumber(DocumentTypeEnum.出库单据); + return "PDOUT" + DateTime.Now.ToString("yyyyMMdd") + serialNumber.ToString().PadLeft(4, '0'); + } + } + public int GetSerialNumber(DocumentTypeEnum documentType) { var documentSerialNumber = DbHelp.db.Queryable() diff --git a/WCS.BLL/Services/Service/InstoreService.cs b/WCS.BLL/Services/Service/InstoreService.cs index da9625a..4937048 100644 --- a/WCS.BLL/Services/Service/InstoreService.cs +++ b/WCS.BLL/Services/Service/InstoreService.cs @@ -13,6 +13,7 @@ using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MXBackgroundThread; namespace WCS.BLL.Services.Service { @@ -130,7 +131,7 @@ namespace WCS.BLL.Services.Service } IShelfBase shelf = null; - if (!request.IsSingleLightIn) + if (!request.SingleLightIn) { //获取货架 shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); @@ -151,6 +152,8 @@ namespace WCS.BLL.Services.Service Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurrentMode}", }; } + //物料在入库模式,更新时间 避免被后台线程关闭 + shelf.SetCurrentModeTime = DateTime.Now; } #region 获取物料数据 //调用接口或者直接查询数据库 @@ -164,13 +167,13 @@ namespace WCS.BLL.Services.Service { materialBar = request.MatSn }; - var Result = ApiHelp.GetDataFromHttp>>("http://192.168.2.23:9213/integrate/instock/queryBybar", body, "POST"); + var Result = ApiHelp.GetDataFromHttp>>("http://192.168.2.23:9213/integrate/instock/queryBybar", body, "POST", true); //查询到物料信息 if (Result != null && Result.Code == 200 && Result.Data != null && Result.Data.Count > 0) { var data = Result.Data.First(); - if (!request.IsSingleLightIn && shelf != null) + if (!request.SingleLightIn && shelf != null) shelf.InStoreData = new MatInfoResponse() { materialBar = data.materialBar, @@ -180,7 +183,7 @@ namespace WCS.BLL.Services.Service materialSpec = data.materialSpec, batchNo = data.batchNo, supplier = "", - customer = data.materialBar, + customer = "", InstoreUser = request.UserName }; @@ -207,6 +210,47 @@ namespace WCS.BLL.Services.Service else if (Result != null && Result.Code == 200 && Result.Data == null) { //Mes系统中未获取到物料信息 + + //简单校验看是否满足海康物料 + //海康物料 只扫了外箱码 未扫条码 + if ((request.MatSn.Length == 54 || request.MatSn.Length == 56) && !request.MatSn.Contains("\\") && !request.MatSn.Contains("/")) + { + + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = request.MatSn, + materialCode = "暂时未知", + materialName = "暂时未知", + materialQty = 0, + materialSpec = "暂时未知", + batchNo = "暂时未知", + supplier = "", + customer = "", + + InstoreUser = request.UserName + }; + + var matInfo = new MatInfo() + { + MatSn = request.MatSn, + MatCode = "暂时未知", + MatName = "暂时未知", + MatBatch = "暂时未知", + MatQty = 0, + MatSpec = "暂时未知", + MatSupplier = "", + MatCustomer = "", + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + return new ResponseCommon() { Code = 201, @@ -239,7 +283,7 @@ namespace WCS.BLL.Services.Service if (matInfo != null) { //TODO 改成wcs的实体 - if (!request.IsSingleLightIn && shelf != null) + if (!request.SingleLightIn && shelf != null) shelf.InStoreData = new MatInfoResponse() { materialBar = matInfo.MatSn, @@ -468,7 +512,7 @@ namespace WCS.BLL.Services.Service //data1[5] = 0x03; //data1[6] = 0x02; //data1[7] = 0x02; - //byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, true); + //byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, false); byte[] senddata1 = Tool.Helper.InstoreWarnLight(warnLightID); tCPClient.Send(senddata1); //报警灯短亮一次 @@ -491,7 +535,7 @@ namespace WCS.BLL.Services.Service Message = $"入库成功!", Data = rcs.Data, }; - + } } } diff --git a/WCS.BLL/Services/Service/InstoreService.cs.orig b/WCS.BLL/Services/Service/InstoreService.cs.orig new file mode 100644 index 0000000..b0977c8 --- /dev/null +++ b/WCS.BLL/Services/Service/InstoreService.cs.orig @@ -0,0 +1,552 @@ +using OracleInternal.SqlAndPlsqlParser.LocalParsing; +using System.ComponentModel.DataAnnotations.Schema; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using WCS.BLL.Config; +using WCS.BLL.DbModels; +using WCS.BLL.HardWare; +using WCS.BLL.Manager; +using WCS.BLL.Services.IService; +using WCS.BLL.Tool; +using WCS.BLL.Tool.Api.ApiModel; +using WCS.DAL.Db; +using WCS.DAL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MXBackgroundThread; + +namespace WCS.BLL.Services.Service +{ + public class InstoreService : IInstoreService + { + public InstoreService() { } + + public ResponseBase shelfGoInInStore(ShelfGoInInstoreRequest request) + { + //校验货架编码规则 + //取配置文件中得货架编码规则 + bool isValid = false; + var patterns = LocalFile.Config.ModuleCodePatterns; + if (patterns != null && patterns.Count > 0) + { + foreach (var pattern in patterns) + { + isValid = Regex.IsMatch(request.ModuleCode, pattern); + //匹配到第一个符合条件的货架码 就直接退出循环 认为匹配成功 + if (isValid) + break; + } + } + //如果配置文件缺失 使用默认正则进行匹配 + else + { + isValid = Regex.IsMatch(request.ModuleCode, LocalFile.DefaultModuleCodePattern); + } + + if (!isValid) + { + return new ResponseBase() + { + Code = 202, + Message = $"模组编码{request.ModuleCode}不满足模组编码规则!", + }; + } + //找到模组对应的货架 + var shelf = ShelfManager.Shelves.Where(t => t.ModulesStr.Contains(request.ModuleCode)).FirstOrDefault(); + if (shelf == null)//未找到 + { + return new ResponseBase() + { + Code = 201, + Message = "未找到模组对应的货架", + }; + } + //已找到模组对应货架 + shelf.GoInInstore(request.IpAdress); + + if (shelf.CurrentMode == Mode.入库模式) + //成功进入入库模式 + return new ShelfGoInInstoreResponse() + { + Code = 200, + Message = $"货架进入入库模式成功!{string.Join(",", shelf.ExceptionMessages)}", + Data = new ShelfGoInInstoreDto() + { + ShelfCode = shelf.ShelfCode, + ModulesStr = shelf.ModulesStr, + } + }; + else + return new ShelfGoInInstoreResponse() + { + Code = 201, + Message = $"货架进入入库模式失败:{string.Join(",", shelf.ExceptionMessages)}", + Data = null + }; + + } + + public ResponseBase shelfGoOutInStore(ShelfGoOutInStoreRequest request) + { + //获取货架 + var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + if (shelf == null)//货架不存在 + { + return new ResponseCommon() + { + Code = 201, + Message = $"退出入库模式失败:货架[{request.ShelfCode}]不存在!", + }; + } + + //判断扫码枪 是否被其他扫码枪所占用 如果占用 直接退出入库模式 不发指令 + shelf.GoOutInstore(); + + if (shelf.ExceptionMessages == null || shelf.ExceptionMessages.Count == 0) + //已退出 + return new ResponseCommon() + { + Code = 200, + Message = $"货架[{request.ShelfCode}]已退出入库模式!", + }; + else + return new ResponseCommon() + { + Code = 200, + Message = $"货架[{request.ShelfCode}]已退出入库模式!{string.Join(",", shelf.ExceptionMessages)}", + }; + } + + public async Task queryByMatSn(QueryByMatSnRequest request) + { + //判断物料是否已入库 + var inventory = await DbHelp.db.Queryable().Where(t => t.MatSN == request.MatSn).FirstAsync(); + if (inventory != null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:物料{inventory.MatSN}已入库!库位为{inventory.StoreCode}", + }; + } + + IShelfBase shelf = null; + if (!request.SingleLightIn) + { + //获取货架 + shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + if (shelf == null)//货架不存在 + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:货架[{request.ShelfCode}]不存在!", + }; + } + //判断当前是否是入库模式 + if (shelf.CurrentMode != Mode.入库模式) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurrentMode}", + }; + } + } + + #region 获取物料数据 //调用接口或者直接查询数据库 + // 调用接口 + if (LocalFile.Config.IsAccessWMS) + { + #region 调用WMS接口获取物料信息 + try + { + var body = new + { + materialBar = request.MatSn + }; + var Result = ApiHelp.GetDataFromHttp>>("http://192.168.2.23:9213/integrate/instock/queryBybar", body, "POST", true); + + //查询到物料信息 + if (Result != null && Result.Code == 200 && Result.Data != null && Result.Data.Count > 0) + { + var data = Result.Data.First(); + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = data.materialBar, + materialCode = data.materialCode, + materialName = data.materialName, + materialQty = data.materialQty, + materialSpec = data.materialSpec, + batchNo = data.batchNo, + supplier = "", + customer = "", + + InstoreUser = request.UserName + }; + + var matInfo = new MatInfo() + { + MatSn = data.materialBar, + MatCode = data.materialCode, + MatName = data.materialName, + MatBatch = data.batchNo, + MatQty = (int)data.materialQty, + MatSpec = data.materialSpec, + MatSupplier = "", + MatCustomer = "", + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + else if (Result != null && Result.Code == 200 && Result.Data == null) + { + //Mes系统中未获取到物料信息 + + //简单校验看是否满足海康物料 + //海康物料 只扫了外箱码 未扫条码 + if ((request.MatSn.Length == 54 || request.MatSn.Length == 56) && !request.MatSn.Contains("\\") && !request.MatSn.Contains("/")) + { + + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = request.MatSn, + materialCode = "暂时未知", + materialName = "暂时未知", + materialQty = 0, + materialSpec = "暂时未知", + batchNo = "暂时未知", + supplier = "", + customer = "", + + InstoreUser = request.UserName + }; + + var matInfo = new MatInfo() + { + MatSn = request.MatSn, + MatCode = "暂时未知", + MatName = "暂时未知", + MatBatch = "暂时未知", + MatQty = 0, + MatSpec = "暂时未知", + MatSupplier = "", + MatCustomer = "", + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:调用Mes接口未获取到物料信息!", + }; + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:调用Mes接口失败!", + }; + } + } + catch (Exception e) + { + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败:调用Mes接口发生异常{e.Message}", + }; + } + #endregion + } + //查询数据库是否存在这个物料 + else + { + var matInfo = await DbHelp.db.Queryable().Where(t => t.MatSn == request.MatSn).FirstAsync(); + if (matInfo != null) + { + //TODO 改成wcs的实体 + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = matInfo.MatSn, + materialCode = matInfo.MatCode, + materialName = matInfo.MatName, + materialQty = matInfo.MatQty, + materialSpec = matInfo.MatSpec, + batchNo = matInfo.MatBatch, + supplier = matInfo.MatSupplier, + customer = matInfo.MatCustomer, + + InstoreUser = request.UserName + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + else + return new ResponseCommon() + { + Code = 201, + Data = null, + Message = $"不存在物料{request.MatSn}" + }; + } + #endregion + } + + /// + /// 单灯出库时查询物料信息 这里返回库存的数据 + /// + /// + /// + public async Task queryByMatSnOut(QueryByMatSnRequest request) + { + //判断物料是否已入库 + var inventory = await DbHelp.db.Queryable().Where(t => t.MatSN == request.MatSn).FirstAsync(); + if (inventory == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:物料不在库存内,无法进行出库!", + }; + } + else + { + return new ResponseCommon() + { + Code = 200, + Message = $"Success", + Data = new MatInfo() + { + MatSn = inventory.MatSN, + MatCode = inventory.MatCode, + MatName = inventory.MatName, + MatBatch = inventory.MatBatch, + MatQty = inventory.MatQty, + MatSpec = inventory.MatSpec, + MatSupplier = inventory.MatSupplier, + MatCustomer = inventory.MatCustomer, + } + }; + } + } + + public async Task queryInstoreStatus(QueryByMatSnRequest request) + { + //获取货架 + var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + if (shelf == null)//货架不存在 + { + return new ResponseCommon() + { + Code = 201, + Message = $"货架[{request.ShelfCode}]不存在!", + }; + } + + //判断当前是否是入库模式 + if (shelf.CurrentMode != Mode.入库模式) + { + return new ResponseCommon() + { + Code = 201, + Message = $"货架[{request.ShelfCode}]已退出入库模式!\r\n当前为{shelf.CurrentMode}", + }; + } + + //TODO 配置这个时间相当于需要入库扫码后需要等待的时间 + var timeOut = 5000; + var timeSpan = TimeSpan.FromMilliseconds(0); + var beginTime = DateTime.Now; + while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) + { + timeSpan = DateTime.Now - beginTime; + //已入库当前扫码的物料时 查询数据库 + if (shelf.InStoreData == null || (shelf.InStoreData as object) == null) + { + await Task.Delay(50); + var inventoryDetail = DbHelp.db.Queryable() + .Where(t => t.MatSN == request.MatSn) + .First(); + if (inventoryDetail != null) + { + return new ResponseCommon() + { + Code = 200, + Message = $"入库成功!物料已放入库位{inventoryDetail.StoreCode}", + Data = new + { + StoreCode = inventoryDetail.StoreCode, + } + }; + } + else + break; + } + //延时处理 + Thread.Sleep(50); + } + //超时未成功入库 + shelf.InStoreData = null; + return new ResponseCommon() + { + Code = 201, + Message = $"超时未入库!请重新扫码后入库!", + Data = new + { + StoreCode = string.Empty, + } + }; + } + + public async Task queryInstoreStatusSingle(QueryByMatSnRequestSingle request) + { + //获取货架 + //var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + //if (shelf == null)//货架不存在 + //{ + // return new ResponseCommon() + // { + // Code = 201, + // Message = $"货架[{request.ShelfCode}]不存在!", + // }; + //} + List MI = DbHelp.db.Queryable().Where(it => it.ModuleCode == request.ShelfCode).ToList(); + if (MI.Count == 0) + { + return new ResponseCommonSingle() + { + Code = 201, + Message = $"货架[{request.ShelfCode}]不存在!", + }; + } + ResponseCommonSingle rcs = new ResponseCommonSingle(); + rcs.Data = new List(); + + string sendIP = MI[0].CleintIp; //单灯IP + int PCBId = MI[0].BoardId; //单灯PCB板ID + + List SI = DbHelp.db.Queryable().Where(it => it.ModuleCode == request.ShelfCode).ToList(); + + List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == MI[0].ShelfCode).ToList(); + int warnLightID = si[0].LightId; + + foreach (QueryByMatSnRequestSingle.MatSnListDetail matSnListDetail in request.MatSnList) + { + Detail detail = new Detail(); + try + { + InventoryDetail inventoryDetail = new InventoryDetail(); + inventoryDetail.MatSN = matSnListDetail.MatSn; + inventoryDetail.MatCode = matSnListDetail.MatCode; + inventoryDetail.MatName = matSnListDetail.MatName; + inventoryDetail.MatSpec = matSnListDetail.MatSpec; + inventoryDetail.MatBatch = matSnListDetail.MatBatch; + inventoryDetail.MatQty = matSnListDetail.MatQty; + inventoryDetail.MatCustomer = matSnListDetail.MatCustomer; + inventoryDetail.MatSupplier = matSnListDetail.MatSupplier; + inventoryDetail.StoreCode = request.ShelfCode; + inventoryDetail.StoreId = SI[0].Id; + + int count = DbHelp.db.Insertable(inventoryDetail).ExecuteCommand(); + + InOutRecord ior = new InOutRecord(); + ior.MatSN = matSnListDetail.MatSn; + ior.MatCode = matSnListDetail.MatCode; + ior.MatName = matSnListDetail.MatName; + ior.MatSpec = matSnListDetail.MatSpec; + ior.MatBatch = matSnListDetail.MatBatch; + ior.MatQty = matSnListDetail.MatQty; + ior.MatCustomer = matSnListDetail.MatCustomer; + ior.MatSupplier = matSnListDetail.MatSupplier; + ior.StoreCode = request.ShelfCode; + ior.StoreId = SI[0].Id; + ior.Direction = DirectionEnum.入库; + ior.OperateTime = DateTime.Now; + ior.OperateUser = request.UserName; + int count1 = DbHelp.db.Insertable(ior).ExecuteCommand(); + + detail.matsn = matSnListDetail.MatSn; + detail.result = "入库成功"; + rcs.Data.Add(detail); + } + catch (Exception ee) + { + detail.matsn = matSnListDetail.MatSn; + detail.result = "入库失败"; + detail.reason = ee.Message; + rcs.Data.Add(detail); + } + } + //亮灯 + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); +<<<<<<< HEAD + //byte[] data1 = new byte[8]; + //data1[0] = 0xff; + //data1[1] = 0x02; + //data1[2] = 0x00; + //data1[3] = 0x0a; + //data1[4] = (byte)warnLightID; + //data1[5] = 0x03; + //data1[6] = 0x02; + //data1[7] = 0x02; + //byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, true); + byte[] senddata1 = Tool.Helper.InstoreWarnLight(warnLightID); +======= + byte[] data1 = new byte[8]; + data1[0] = 0xff; + data1[1] = 0x02; + data1[2] = 0x00; + data1[3] = 0x0a; + data1[4] = (byte)warnLightID; + data1[5] = 0x03; + data1[6] = 0x02; + data1[7] = 0x02; + byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, false); +>>>>>>> 11 + tCPClient.Send(senddata1); //报警灯短亮一次 + + //byte[] data2 = new byte[8]; + //data2[0] = 0xff; + //data2[1] = 0x01; + //data2[2] = 0x00; + //data2[3] = 0x0a; + //data2[4] = 0x01; + //data2[5] = (byte)PCBId; + //data2[6] = 0x03; + //data2[7] = 0x02; + //byte[] senddata2 = Tool.Helper.Crc16(data2, data2.Length, true); + byte[] senddata2 = Tool.Helper.InstoreLight(PCBId); + tCPClient.Send(senddata2); //库位灯短亮一次 + + return new ResponseCommonSingle() + { + Code = 200, + Message = $"入库成功!", + Data = rcs.Data, + }; + + } + } +} diff --git a/WCS.BLL/Services/Service/MatInventoryDetailService.cs b/WCS.BLL/Services/Service/MatInventoryDetailService.cs index b9881c5..5896341 100644 --- a/WCS.BLL/Services/Service/MatInventoryDetailService.cs +++ b/WCS.BLL/Services/Service/MatInventoryDetailService.cs @@ -6,6 +6,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using TouchSocket.Core; +using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.Services.IService; using WCS.DAL.Db; @@ -128,16 +129,16 @@ namespace WCS.BLL.Services.Service var inventortyDetails = await DbHelp.db.Queryable() .WhereIF(!string.IsNullOrEmpty(request.MatName), t => t.MatName.Contains(request.MatName)) .WhereIF(!string.IsNullOrEmpty(request.MatCode), t => t.MatCode.Contains(request.MatCode)) + .WhereIF(!string.IsNullOrEmpty(request.MatBatch), t => t.MatBatch.Contains(request.MatBatch)) + .Where(t => t.StoreInfo.ShelfTypeId == request.ShelfTypeId) .GroupBy(t => t.MatCode) .GroupBy(t => t.MatBatch) .Select(t => new MatInventorySummaryModel { MatCode = t.MatCode, MatName = t.MatName, - MatBatch = t.MatBatch, MatSpec = t.MatSpec, - MatCustomer = t.MatCustomer, - MatSupplier = t.MatSupplier, + MatBatch = t.MatBatch, TotalQty = SqlFunc.AggregateSum(t.MatQty) }) .ToListAsync(); @@ -149,5 +150,48 @@ namespace WCS.BLL.Services.Service Data = inventortyDetails }; } + + public async Task> compareMatInventoryDetail(CompareMatInventoryDetailRequest request) + { + try + { + //查询 本分组中 是否含有所传SN的物料 + var recordsQueryable = DbHelp.db.Queryable() + .Where(t => request.MatSns.Contains(t.MatSN)) + .OrderBy(t => t.MatCode) + .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.StoreInfo.GroupName == LocalFile.Config.GroupName); + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable.ToListAsync(); + //生成序号 选中 + for (int i = 0; i < records.Count; i++) + { + records[i].RowNumber = i + 1; + records[i].IsSelected = true; + } + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + TotalCount = totalCount, + Count = records.Count, + Lists = records.ToList() + } + }; + } + catch + { + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + Lists = new List() + } + }; + } + } } } diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index 1498139..cea40ba 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -1,11 +1,5 @@ -using SqlSugar; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using TouchSocket.Sockets; +using Microsoft.Data.SqlClient; +using SqlSugar; using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.Manager; @@ -15,6 +9,7 @@ using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MatInventoryDetail; using WCS.Model.ApiModel.OutStore; namespace WCS.BLL.Services.Service @@ -24,6 +19,53 @@ namespace WCS.BLL.Services.Service public OutstoreService() { + } + public async Task>> importMat(List list) + { + //数据校验 + if (list == null || list.Count == 0) + { + return new ResponseCommon>() + { + Code = 201, + Message = "导入失败:导入文件中没有内容!" + }; + } + //需求数量 + var errorCount = list.Where(t => t.需求数量 <= 0).ToList(); + if (errorCount != null && errorCount.Count > 0) + { + return new ResponseCommon>() + { + Code = 201, + Message = "导入失败:需求数量需要大于0!" + }; + } + //每一个物料进行搜索库存 + var returnList = new List(); + foreach (var item in list) + { + var inventoryCount = await DbHelp.db.Queryable() + .Where(t => t.MatCode == item.物料编码) + .Where(t => t.MatBatch == item.物料批次) + .Where(t => t.IsLocked == false) + .SumAsync(t => t.MatQty); + var info = inventoryCount < item.需求数量 ? "库存数量小于需求数量" : string.Empty; + returnList.Add(new MatInventorySummaryModel() + { + MatCode = item.物料编码, + MatName = item.物料名称, + MatBatch = item.物料批次, + NeedQty = item.需求数量, + TotalQty = inventoryCount, + Info = info + }); + } + return new ResponseCommon>() + { + Code = 200, + Data = returnList + }; } public async Task SysOutOrderByMatCode(SysOutOrderByMatCodeRequest request) { @@ -36,6 +78,24 @@ namespace WCS.BLL.Services.Service Message = "出库单据同步失败:缺少需要出库的物料类型!" }; } + //补齐货架类型名称 + if (string.IsNullOrEmpty(request.ShelfTypeName)) + { + var shelfType = await DbHelp.db.Queryable() + .Where(t => t.Id == request.ShelfTypeId) + .FirstAsync(); + if (shelfType == null) + { + return new ResponseBase() + { + Code = 201, + Message = $"出库单据同步失败:缺少必要参数!ShelfTypeId" + }; + } + else + request.ShelfTypeName = shelfType.ShelfTypeName; + } + //保存数据 await DbHelp.db.BeginTranAsync(); try @@ -45,6 +105,8 @@ namespace WCS.BLL.Services.Service OrderNumber = request.OrderNumber, OrderSource = request.OrderSource, OrderType = request.OrderType, + ShelfTypeId = request.ShelfTypeId, + ShelfTypeName = request.ShelfTypeName, SyncType = SyncTypeEnum.ByMatCode, CreateUser = request.UserName, }; @@ -69,6 +131,7 @@ namespace WCS.BLL.Services.Service { Code = 200, Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", + Data = request.OrderNumber }; ; } catch (Exception ex) @@ -95,103 +158,266 @@ namespace WCS.BLL.Services.Service Message = "出库单据同步失败:缺少物料明细!" }; } - //库存有无校验 & 库存已锁校验 - try + //标准版逻辑-库存有无校验 & 库存已锁校验 + if (!LocalFile.Config.IsMx) { - await DbHelp.db.BeginTranAsync(); - var inventoryDetails = await DbHelp.db.Queryable() - .Where(t => request.SnList.Contains(t.MatSN)) - .TranLock(DbLockType.Wait) - .ToListAsync(); - if (inventoryDetails.Count < request.SnList.Count)//库存的物料少于需求的物料数量 + try { - var existsSns = inventoryDetails.Select(t => t.MatSN).ToList(); - request.SnList.RemoveAll(t => existsSns.Contains(t)); - await DbHelp.db.RollbackTranAsync(); - //返回提示哪些物料库存不存在 + await DbHelp.db.BeginTranAsync(); + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.SnList.Contains(t.MatSN)) + .TranLock(DbLockType.Wait) + .ToListAsync(); + if (inventoryDetails.Count < request.SnList.Count)//库存的物料少于需求的物料数量 + { + var existsSns = inventoryDetails.Select(t => t.MatSN).ToList(); + request.SnList.RemoveAll(t => existsSns.Contains(t)); + await DbHelp.db.RollbackTranAsync(); + //返回提示哪些物料库存不存在 + return new ResponseCommon() + { + Code = 201, + Message = "出库单据同步失败:存在物料不在库存中!", + Data = request.SnList + + }; + } + else if (inventoryDetails.Where(t => t.IsLocked).Any()) + { + await DbHelp.db.RollbackTranAsync(); + //返回提示哪些物料库存已被锁定 + return new ResponseCommon() + { + Code = 201, + Message = "出库单据同步失败:存在物料被锁定!", + Data = inventoryDetails.Where(t => t.IsLocked).Select(t => t.MatSN).ToList() + }; + } + + #region 保存数据 + + //锁库存 + inventoryDetails.ForEach(t => + { + t.IsLocked = true; + }); + var lockTask = DbHelp.db.Updateable(inventoryDetails).ExecuteCommandAsync(); + + //保存数据 + var order = new OutOrder() + { + OrderNumber = request.OrderNumber, + OrderSource = request.OrderSource, + OrderType = request.OrderType, + SyncType = SyncTypeEnum.ByMatSn, + CreateUser = request.UserName, + }; + order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); + + //通过库存数据保存出库物料明细表 + var matDetailTasks = inventoryDetails.Select(async t => + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + InventoryDetailId = t.Id, + StoreId = t.StoreId, + StoreCode = t.StoreCode, + MatSN = t.MatSN, + MatCode = t.MatCode, + MatName = t.MatName, + MatSpec = t.MatSpec, + MatBatch = t.MatBatch, + MatQty = t.MatQty, + MatSupplier = t.MatSupplier, + MatCustomer = t.MatCustomer, + CreateUser = request.UserName, + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + }).ToList(); + + await lockTask; + await Task.WhenAll(matDetailTasks); + + await DbHelp.db.CommitTranAsync(); return new ResponseCommon() { - Code = 201, - Message = "出库单据同步失败:存在物料不在库存中!", - Data = request.SnList - + Code = 200, + Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", + Data = order.Id }; + #endregion } - else if (inventoryDetails.Where(t => t.IsLocked).Any()) + catch (Exception ex) { await DbHelp.db.RollbackTranAsync(); - //返回提示哪些物料库存已被锁定 - return new ResponseCommon() + return new ResponseBase() { Code = 201, - Message = "出库单据同步失败:存在物料被锁定!", - Data = inventoryDetails.Where(t => t.IsLocked).Select(t => t.MatSN).ToList() + Message = $"出库单据同步失败:{ex.Message}" }; } - - #region 保存数据 - - //锁库存 - inventoryDetails.ForEach(t => - { - t.IsLocked = true; - }); - var lockTask = DbHelp.db.Updateable(inventoryDetails).ExecuteCommandAsync(); - - //保存数据 - var order = new OutOrder() - { - OrderNumber = request.OrderNumber, - OrderSource = request.OrderSource, - OrderType = request.OrderType, - SyncType = SyncTypeEnum.ByMatSn, - CreateUser = request.UserName, - }; - order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); - - //通过库存数据保存出库物料明细表 - var matDetailTasks = inventoryDetails.Select(async t => - { - var orderMatDetail = new OutOrderMatDetail() - { - OrderId = order.Id, - OrderNumber = order.OrderNumber, - InventoryDetailId = t.Id, - StoreId = t.StoreId, - StoreCode = t.StoreCode, - MatSN = t.MatSN, - MatCode = t.MatCode, - MatName = t.MatName, - MatSpec = t.MatSpec, - MatBatch = t.MatBatch, - MatQty = t.MatQty, - MatSupplier = t.MatSupplier, - MatCustomer = t.MatCustomer, - CreateUser = request.UserName - }; - await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); - }).ToList(); - - await lockTask; - await Task.WhenAll(matDetailTasks); - - await DbHelp.db.CommitTranAsync(); - return new ResponseCommon() - { - Code = 200, - Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", - Data = order.Id - }; - #endregion } - catch (Exception ex) + //盟讯公司逻辑 不锁库存 直接保存数据/清除未发送的 + else { - await DbHelp.db.RollbackTranAsync(); - return new ResponseBase() + try { - Code = 201, - Message = $"出库单据同步失败:{ex.Message}" - }; + DbHelp.db.BeginTran(); + //1. 获取库存物料明细 + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.SnList.Contains(t.MatSN)) + .ToListAsync(); + if (inventoryDetails == null || inventoryDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "保存出库单失败!请重试!", + Data = request.SnList + }; + } + //2. 先获取对应单号是否已经保存 + var outOrder = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.GroupName == LocalFile.Config.GroupName) + .First(); + //数据库中没有才添加 + if (outOrder == null) + { + //OutOrder + outOrder = new OutOrder() + { + OrderNumber = request.OrderNumber, + OrderType = request.OrderType, + OutOrderExeStatus = OutOrderExeStatus.开始发料, + OrderSource = "WCS前端", + SyncType = SyncTypeEnum.ByMatSn, + ShelfTypeName = "智能货架", + ShelfTypeId = 0, + GroupName = LocalFile.Config.GroupName, + IsMXPD = request.IsMXPD, + }; + outOrder.Id = await DbHelp.db.Insertable(outOrder).ExecuteReturnIdentityAsync(); + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.Id == outOrder.Id) + .FirstAsync(); + //保存单据失败了 + if (outOrder == null) + return new ResponseCommon() + { + Code = 201, + Message = "保存出库单失败!保存Order失败!", + Data = request.SnList + }; + + //出库物料明细 + foreach (var item in inventoryDetails) + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = outOrder.Id, + OrderNumber = outOrder.OrderNumber, + InventoryDetailId = item.Id, + StoreId = item.StoreId, + StoreCode = item.StoreCode, + MatSN = item.MatSN, + MatCode = item.MatCode, + MatName = item.MatName, + MatSpec = item.MatSpec, + MatBatch = item.MatBatch, + MatQty = item.MatQty, + MatSupplier = item.MatSupplier, + MatCustomer = item.MatCustomer, + CreateUser = request.UserName, + IsMXPD = request.IsMXPD, + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + } + DbHelp.db.CommitTran(); + } + //数据库已有该Order + else + { + outOrder.CreateTime = DateTime.Now; + DbHelp.db.Updateable(outOrder).ExecuteCommand(); + //删除未出库的 + var outOrderDetails = DbHelp.db.Deleteable() + .Where(t => t.OrderId == outOrder.Id) + .Where(t => t.IsSended == false) + .ExecuteCommand(); + //当前已出库的 //已出库的也不在库存中了 应该查询不到了 + //避免影响效率 就不查重了 + foreach (var item in inventoryDetails) + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = outOrder.Id, + OrderNumber = outOrder.OrderNumber, + InventoryDetailId = item.Id, + StoreId = item.StoreId, + StoreCode = item.StoreCode, + MatSN = item.MatSN, + MatCode = item.MatCode, + MatName = item.MatName, + MatSpec = item.MatSpec, + MatBatch = item.MatBatch, + MatQty = item.MatQty, + MatSupplier = item.MatSupplier, + MatCustomer = item.MatCustomer, + CreateUser = request.UserName, + IsMXPD = request.IsMXPD, + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + } + DbHelp.db.CommitTran(); + + //更新订单状态 + Task.Run(() => + { + if (outOrder != null) + { + #region 物料明细表是否已发完 + var orderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToList(); + var isExistNoSendMat = orderMatDetails.Where(t => t.IsSended == false) + .Any(); + if (isExistNoSendMat) + { + outOrder.OrderStatus = OutOrderStatus.部分发料; + } + else + { + outOrder.OrderStatus = OutOrderStatus.全部发料; + outOrder.OutOrderExeStatus = OutOrderExeStatus.发料完成; + } + #endregion + DbHelp.db.Updateable(outOrder).ExecuteCommand(); + } + }); + } + return new ResponseCommon() + { + Code = 200, + Message = outOrder.OrderNumber, + Data = request.SnList + }; + + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + Logs.Write($"同步出库单据发生异常{ex.Message}", LogsType.Info); + return new ResponseCommon() + { + Code = 201, + Message = $"保存出库单失败!{ex.Message}!", + Data = request.SnList + }; + } + } } @@ -202,7 +428,8 @@ namespace WCS.BLL.Services.Service var recordsQueryable = DbHelp.db.Queryable() .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber.Contains(request.OrderNumber)) .WhereIF(!string.IsNullOrEmpty(request.OrderSource), t => t.OrderSource.Contains(request.OrderSource)) - .WhereIF(!string.IsNullOrEmpty(request.OrderType), t => t.OrderType.Contains(request.OrderType)); + .WhereIF(!string.IsNullOrEmpty(request.OrderType), t => t.OrderType.Contains(request.OrderType)) + .WhereIF(request.ShelfTypeId != 0, t => t.ShelfTypeId == request.ShelfTypeId); var totalCount = await recordsQueryable.CountAsync(); var records = await recordsQueryable @@ -244,23 +471,33 @@ namespace WCS.BLL.Services.Service }; } //直接查询 - var recordsQueryable = DbHelp.db.Queryable().Where(t => request.OrderExeStatus.Contains(t.OutOrderExeStatus)); + var recordsQueryable = DbHelp.db.Queryable() + .Where(t => request.OrderExeStatus.Contains(t.OutOrderExeStatus)) + .WhereIF(request.IsMXPD != null, t => t.IsMXPD == request.IsMXPD) + .WhereIF(LocalFile.Config.IsMx, t => t.CreateTime > DateTime.Now.AddDays(-3)) + .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName); var totalCount = await recordsQueryable.CountAsync(); var records = await recordsQueryable .OrderByDescending(t => t.CreateTime) - //.Take(request.PageSize) .ToListAsync(); + //获取后台当前正在进行出库的订单 将出库状态反馈给前端 + var outingOrderNumbers = ShelfManager.Shelves + .Where(t => t.CurrentMode == HardWare.Mode.出库模式).Select(t => t.OrderNumber) + .ToList(); + foreach (var record in records) + { + if (outingOrderNumbers.Contains(record.OrderNumber)) + record.IsOuting = true; + } + return new PageQueryResponse() { Code = 200, Message = $"success", Data = new PageQueryResponseData() { - //TotalCount = totalCount, - //MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), - //Count = records.Count, Lists = records.ToList() } }; @@ -325,6 +562,74 @@ namespace WCS.BLL.Services.Service }; } + /// + /// 单灯查询物料明细 PDA要求返回数据种data需要增加一层details + /// + /// + /// + public async Task GetOutOrderDetailSingleLight(GetOutOrderDetailRequest request) + { + OutOrder outOrder = null; + + #region 查询出库单 + if (request.OrderId != 0) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.Id == request.OrderId).FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.OrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.OrderNumber)) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } + #endregion + + #region 查询出库单明细 + var orderDetailTask = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToListAsync(); + var orderDetail = await orderDetailTask; + //生成序号 + for (int i = 0; i < orderDetail.Count; i++) + { + orderDetail[i].RowNumber = i + 1; + } + #endregion + + return new ResponseCommonModify() + { + Code = 200, + Message = "Success", + Data = new ResponseCommonDataDetail + { + Details = orderDetail + } + }; + } + public async Task GetOutOrderMatDetail(GetOutOrderDetailRequest request) { OutOrder outOrder = null; @@ -432,7 +737,7 @@ namespace WCS.BLL.Services.Service }; } - if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成 + if (request.IsStart) { order.OutOrderExeStatus = OutOrderExeStatus.开始发料; DbHelp.db.Updateable(order).ExecuteCommand(); @@ -457,6 +762,9 @@ namespace WCS.BLL.Services.Service //看是否是分批次出库的情况 分批次亮灯 if (LocalFile.Config.IsSameMatCodeOut) { + //最先亮的颜色为绿色 + LocalStatic.CurrentOutStoreColor = 0x02; + var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode) .Select(o => new { count = o.Count(), bb = o }) .Where(o => o.count >= 2) @@ -468,14 +776,22 @@ namespace WCS.BLL.Services.Service var matCode = outOrderDetailCount.First().bb.Key; outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) .ToList(); - Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}!"); + Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}!", LogsType.Outstore); + + //分批次亮灯再计算一次出哪些货架 以免亮大灯不亮小灯 + shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) + .Distinct() + .ToList(); + shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); } //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 else { //剩余物料全出 - Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!"); + Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!", LogsType.Outstore); } + + } //对应的货架对应位置 进入出库模式 亮灯 @@ -486,6 +802,7 @@ namespace WCS.BLL.Services.Service .ToList(); shelf.GoInOutstore(matDetails, order); shelf.OrderNumber = order.OrderNumber; + Logs.Write($"出库单{order.OrderNumber},货架{shelf.ShelfCode}进入入库模式!", LogsType.Outstore); }); //返回 @@ -498,6 +815,7 @@ namespace WCS.BLL.Services.Service } catch (Exception ex) { + Logs.Write($"本次发料发生异常!{ex.Message}", LogsType.Outstore); await GoOutOutstore(request); throw ex; } @@ -608,7 +926,7 @@ namespace WCS.BLL.Services.Service Dictionary> dict = new Dictionary>(); foreach (OutOrderMatDetail oomd in outOrderMatDetails) { - List mi= DbHelp.db.Queryable().Where(it => it.ModuleCode == oomd.StoreCode).ToList(); + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == oomd.StoreCode).ToList(); if (mi.Count != 0) { if (!StoreCode.Contains(oomd.StoreCode)) @@ -640,7 +958,7 @@ namespace WCS.BLL.Services.Service { string sendIP = v.Key; TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); - byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor,1); + byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor, 1); tCPClient.Send(lightOn); Thread.Sleep(100); } @@ -660,12 +978,12 @@ namespace WCS.BLL.Services.Service foreach (string shelfcode in WarnLightShelfCode) { List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == shelfcode).ToList(); - if (si.Count != 0) + if (si.Count != 0) { for (int i = 0; i < si.Count; i++) { TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp); - byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId,LightColor,1,0); + byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId, LightColor, 1, 0); tCPClient.Send(warnlightOn); Thread.Sleep(100); } @@ -675,7 +993,7 @@ namespace WCS.BLL.Services.Service return new OutResponseCommonSingle() { Code = 200, - Message = "Success", + Message = LightColor, Data = orcs.Data }; } @@ -713,7 +1031,8 @@ namespace WCS.BLL.Services.Service .Where(t => t.MatCode == outOrderDetail.MatCode) .WhereIF(!string.IsNullOrEmpty(outOrderDetail.MatBatch), t => t.MatBatch == outOrderDetail.MatBatch) .Where(t => t.IsLocked == false)//未锁定的物料 - .OrderBy(t => t.MatBatch)//先进先出 + .Where(t => t.StoreInfo.ShelfTypeId == order.ShelfTypeId) + .OrderBy(t => t.MatBatch)//按批次先进先出 //(t => t.MatQty)//零散料先出 .ToList(); @@ -866,6 +1185,10 @@ namespace WCS.BLL.Services.Service DbHelp.db.Updateable(order).ExecuteCommand(); } + //解锁物料 删除物料明细 + if (order.SyncType == SyncTypeEnum.ByMatCode) + CancelOutOrderMatDetails(order); + //找到正在出对应出库单的货架 var shelves = ShelfManager.Shelves.Where(t => t.OrderNumber == request.OrderNumber) .Where(t => t.CurrentMode == HardWare.Mode.出库模式) @@ -887,10 +1210,6 @@ namespace WCS.BLL.Services.Service t.GoOutOutstore(); }); - //解锁物料 删除物料明细 - if (order.SyncType == SyncTypeEnum.ByMatCode) - CancelOutOrderMatDetails(order); - return new ResponseCommon() { Code = 200, @@ -963,7 +1282,7 @@ namespace WCS.BLL.Services.Service } catch (Exception ee) { - Logs.Write("查询出库单据:"+request.OrderNumber+"对应库位灯颜色失败,"+ ee.Message); + Logs.Write("查询出库单据:" + request.OrderNumber + "对应库位灯颜色失败," + ee.Message); } Dictionary> dict = new Dictionary>(); foreach (OutOrderMatDetail oomd in outOrderMatDetails) @@ -1000,7 +1319,7 @@ namespace WCS.BLL.Services.Service { string sendIP = v.Key; TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); - byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor,0); + byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor, 0); tCPClient.Send(lightOn); Thread.Sleep(100); } @@ -1045,46 +1364,92 @@ namespace WCS.BLL.Services.Service public async Task SingleLightConfirmOutstore(OutOrderMatDetailModelSingle request) { - InOutRecord ior = new InOutRecord(); - List id = DbHelp.db.Queryable().Where(it => it.MatSN == request.MatSn).ToList(); - if (id.Count == 0) + try { + //单据校验 + var order = await DbHelp.db.Queryable() + .Where(it => it.Id == request.OrderId) + .Where(it => it.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"系统不存在单据[{request.OrderNumber}]!", + Data = null + }; + } + //物料校验 + var invetoryDetail = await DbHelp.db.Queryable() + .Where(it => it.Id == request.MatId) + .Where(it => it.MatSN == request.MatSn) + .FirstAsync(); + + if (invetoryDetail == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"库存中不存在物料[{request.MatSn}]!", + Data = null + }; + } + + //物料需求明细校验 + var outOrderDetail = await DbHelp.db.Queryable().Where(it => it.OrderNumber == request.OrderNumber) + .Where(it => it.MatCode == invetoryDetail.MatCode) + .FirstAsync(); + if (outOrderDetail == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"单据[{request.OrderNumber}]需求不包含物料[{invetoryDetail.MatCode}]!", + Data = null + }; + } + + var inOutRecord = new InOutRecord(); + inOutRecord.StoreId = invetoryDetail.StoreId; + inOutRecord.StoreCode = invetoryDetail.StoreCode; + inOutRecord.MatSN = invetoryDetail.MatSN; + inOutRecord.MatCode = invetoryDetail.MatCode; + inOutRecord.MatName = invetoryDetail.MatName; + inOutRecord.MatSpec = invetoryDetail.MatSpec; + inOutRecord.MatBatch = invetoryDetail.MatBatch; + inOutRecord.MatQty = invetoryDetail.MatQty; + inOutRecord.MatSupplier = invetoryDetail.MatSupplier; + inOutRecord.MatCustomer = invetoryDetail.MatCustomer; + inOutRecord.OrderNumber = order.OrderNumber; + inOutRecord.Direction = DirectionEnum.出库; + inOutRecord.OperateUser = request.UserName; + inOutRecord.OperateTime = DateTime.Now; + //保存出库记录 + int count = DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + //删除库存 + DbHelp.db.Deleteable().Where(it => it.MatSN == request.MatSn).ExecuteCommand(); + //更新需求表 + outOrderDetail.OutQty += invetoryDetail.MatQty; + DbHelp.db.Updateable(outOrderDetail).ExecuteCommand(); + return new ResponseCommon() { - Code = 201, - Message = $"此SN不在库存中{request.MatSn}!", + Code = 200, + Message = $"出库成功", Data = null }; } - ior.StoreId = id[0].StoreId; - ior.StoreCode = id[0].StoreCode; - ior.MatSN = request.MatSn; - ior.MatCode = request.MatCode; - ior.MatName = request.MatName; - ior.MatSpec = request.MatSpec; - ior.MatBatch = request.MatBatch; - ior.MatQty = request.Qty; - ior.MatSupplier = request.MatSupplier; - ior.MatCustomer = request.MatCustomer; - ior.OrderNumber = request.orderNumber; - ior.Direction = DirectionEnum.出库; - ior.OperateUser = request.userName; - ior.OperateTime = DateTime.Now; - //保存出库记录 - int count= DbHelp.db.Insertable(ior).ExecuteCommand(); - //删除库存 - DbHelp.db.Deleteable().Where(it => it.MatSN == request.MatSn).ExecuteCommand(); - //更新需求表 - List odd = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.orderNumber).Where(it=>it.MatCode==request.MatCode).ToList(); - odd[0].OutQty += request.Qty; - DbHelp.db.Updateable(odd[0]).ExecuteCommand(); - - return new ResponseCommon() + catch (Exception ex) { - Code = 200, - Message = $"出库成功", - Data = null - }; + return new ResponseCommon() + { + Code = 300, + Message = $"出库发生异常!", + Data = null + }; + } } + } } diff --git a/WCS.BLL/Services/Service/OutstoreService.cs.orig b/WCS.BLL/Services/Service/OutstoreService.cs.orig new file mode 100644 index 0000000..3ec8826 --- /dev/null +++ b/WCS.BLL/Services/Service/OutstoreService.cs.orig @@ -0,0 +1,1311 @@ +using Microsoft.Data.SqlClient; +using SqlSugar; +using WCS.BLL.Config; +using WCS.BLL.DbModels; +using WCS.BLL.Manager; +using WCS.BLL.Services.IService; +using WCS.BLL.Tool; +using WCS.DAL.Db; +using WCS.Model; +using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MatInventoryDetail; +using WCS.Model.ApiModel.OutStore; + +namespace WCS.BLL.Services.Service +{ + public class OutstoreService : IOutstoreService + { + public OutstoreService() + { + + } + public async Task>> importMat(List list) + { + //数据校验 + if (list == null || list.Count == 0) + { + return new ResponseCommon>() + { + Code = 201, + Message = "导入失败:导入文件中没有内容!" + }; + } + //需求数量 + var errorCount = list.Where(t => t.需求数量 <= 0).ToList(); + if (errorCount != null && errorCount.Count > 0) + { + return new ResponseCommon>() + { + Code = 201, + Message = "导入失败:需求数量需要大于0!" + }; + } + //每一个物料进行搜索库存 + var returnList = new List(); + foreach (var item in list) + { + var inventoryCount = await DbHelp.db.Queryable() + .Where(t => t.MatCode == item.物料编码) + .Where(t => t.MatBatch == item.物料批次) + .Where(t => t.IsLocked == false) + .SumAsync(t => t.MatQty); + var info = inventoryCount < item.需求数量 ? "库存数量小于需求数量" : string.Empty; + returnList.Add(new MatInventorySummaryModel() + { + MatCode = item.物料编码, + MatName = item.物料名称, + MatBatch = item.物料批次, + NeedQty = item.需求数量, + TotalQty = inventoryCount, + Info = info + }); + } + return new ResponseCommon>() + { + Code = 200, + Data = returnList + }; + } + public async Task SysOutOrderByMatCode(SysOutOrderByMatCodeRequest request) + { + //参数合法性校验 + if (request.ItemList == null || request.ItemList.Count == 0) + { + return new ResponseBase() + { + Code = 201, + Message = "出库单据同步失败:缺少需要出库的物料类型!" + }; + } + //补齐货架类型名称 + if (string.IsNullOrEmpty(request.ShelfTypeName)) + { + var shelfType = await DbHelp.db.Queryable() + .Where(t => t.Id == request.ShelfTypeId) + .FirstAsync(); + if (shelfType == null) + { + return new ResponseBase() + { + Code = 201, + Message = $"出库单据同步失败:缺少必要参数!ShelfTypeId" + }; + } + else + request.ShelfTypeName = shelfType.ShelfTypeName; + } + + //保存数据 + await DbHelp.db.BeginTranAsync(); + try + { + var order = new OutOrder() + { + OrderNumber = request.OrderNumber, + OrderSource = request.OrderSource, + OrderType = request.OrderType, + ShelfTypeId = request.ShelfTypeId, + ShelfTypeName = request.ShelfTypeName, + SyncType = SyncTypeEnum.ByMatCode, + CreateUser = request.UserName, + }; + order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); + request.ItemList.ForEach(async item => + { + var orderDetail = new OutOrderDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + MatCode = item.MatCode, + MatName = item.MatName, + MatBatch = item.MatBatch, + ReqQty = item.ReqQty, + OutQty = 0, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderDetail).ExecuteCommandAsync(); + }); + await DbHelp.db.CommitTranAsync(); + return new ResponseCommon() + { + Code = 200, + Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", + }; ; + } + catch (Exception ex) + { + await DbHelp.db.RollbackTranAsync(); + Console.WriteLine(ex.Message); + return new ResponseBase() + { + Code = 200, + Message = $"出库单据同步失败:{ex.Message}" + }; + } + } + + public async Task SysOutOrderByMatSn(SysOutOrderByMatSnRequest request) + { + + //参数合法性校验 + if (request.SnList == null || request.SnList.Count == 0) + { + return new ResponseBase() + { + Code = 201, + Message = "出库单据同步失败:缺少物料明细!" + }; + } + //标准版逻辑-库存有无校验 & 库存已锁校验 + if (!LocalFile.Config.IsMx) + { + try + { + await DbHelp.db.BeginTranAsync(); + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.SnList.Contains(t.MatSN)) + .TranLock(DbLockType.Wait) + .ToListAsync(); + if (inventoryDetails.Count < request.SnList.Count)//库存的物料少于需求的物料数量 + { + var existsSns = inventoryDetails.Select(t => t.MatSN).ToList(); + request.SnList.RemoveAll(t => existsSns.Contains(t)); + await DbHelp.db.RollbackTranAsync(); + //返回提示哪些物料库存不存在 + return new ResponseCommon() + { + Code = 201, + Message = "出库单据同步失败:存在物料不在库存中!", + Data = request.SnList + + }; + } + else if (inventoryDetails.Where(t => t.IsLocked).Any()) + { + await DbHelp.db.RollbackTranAsync(); + //返回提示哪些物料库存已被锁定 + return new ResponseCommon() + { + Code = 201, + Message = "出库单据同步失败:存在物料被锁定!", + Data = inventoryDetails.Where(t => t.IsLocked).Select(t => t.MatSN).ToList() + }; + } + + #region 保存数据 + + //锁库存 + inventoryDetails.ForEach(t => + { + t.IsLocked = true; + }); + var lockTask = DbHelp.db.Updateable(inventoryDetails).ExecuteCommandAsync(); + + //保存数据 + var order = new OutOrder() + { + OrderNumber = request.OrderNumber, + OrderSource = request.OrderSource, + OrderType = request.OrderType, + SyncType = SyncTypeEnum.ByMatSn, + CreateUser = request.UserName, + }; + order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); + + //通过库存数据保存出库物料明细表 + var matDetailTasks = inventoryDetails.Select(async t => + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + InventoryDetailId = t.Id, + StoreId = t.StoreId, + StoreCode = t.StoreCode, + MatSN = t.MatSN, + MatCode = t.MatCode, + MatName = t.MatName, + MatSpec = t.MatSpec, + MatBatch = t.MatBatch, + MatQty = t.MatQty, + MatSupplier = t.MatSupplier, + MatCustomer = t.MatCustomer, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + }).ToList(); + + await lockTask; + await Task.WhenAll(matDetailTasks); + + await DbHelp.db.CommitTranAsync(); + return new ResponseCommon() + { + Code = 200, + Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", + Data = order.Id + }; + #endregion + } + catch (Exception ex) + { + await DbHelp.db.RollbackTranAsync(); + return new ResponseBase() + { + Code = 201, + Message = $"出库单据同步失败:{ex.Message}" + }; + } + } + //盟讯公司逻辑 不锁库存 直接保存数据/清除未发送的 + else + { + try + { + DbHelp.db.BeginTran(); + //1. 获取库存物料明细 + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.SnList.Contains(t.MatSN)) + .ToListAsync(); + if (inventoryDetails == null || inventoryDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "保存出库单失败!请重试!", + Data = request.SnList + }; + } + //2. 先获取对应单号是否已经保存 + var outOrder = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.GroupName == LocalFile.Config.GroupName) + .First(); + //数据库中没有才添加 + if (outOrder == null) + { + //OutOrder + outOrder = new OutOrder() + { + OrderNumber = request.OrderNumber, + OutOrderExeStatus = OutOrderExeStatus.开始发料, + OrderSource = "WCS前端", + SyncType = SyncTypeEnum.ByMatSn, + ShelfTypeName = "智能货架", + ShelfTypeId = 0, + GroupName = LocalFile.Config.GroupName, + }; + outOrder.Id = await DbHelp.db.Insertable(outOrder).ExecuteReturnIdentityAsync(); + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.Id == outOrder.Id) + .FirstAsync(); + //保存单据失败了 + if (outOrder == null) + return new ResponseCommon() + { + Code = 201, + Message = "保存出库单失败!保存Order失败!", + Data = request.SnList + }; + + //出库物料明细 + foreach (var item in inventoryDetails) + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = outOrder.Id, + OrderNumber = outOrder.OrderNumber, + InventoryDetailId = item.Id, + StoreId = item.StoreId, + StoreCode = item.StoreCode, + MatSN = item.MatSN, + MatCode = item.MatCode, + MatName = item.MatName, + MatSpec = item.MatSpec, + MatBatch = item.MatBatch, + MatQty = item.MatQty, + MatSupplier = item.MatSupplier, + MatCustomer = item.MatCustomer, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + } + DbHelp.db.CommitTran(); + } + //数据库已有该Order + else + { + outOrder.CreateTime = DateTime.Now; + DbHelp.db.Updateable(outOrder).ExecuteCommand(); + //删除未出库的 + var outOrderDetails = DbHelp.db.Deleteable() + .Where(t => t.OrderId == outOrder.Id) + .Where(t => t.IsSended == false) + .ExecuteCommand(); + //当前已出库的 //已出库的也不在库存中了 应该查询不到了 + //避免影响效率 就不查重了 + foreach (var item in inventoryDetails) + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = outOrder.Id, + OrderNumber = outOrder.OrderNumber, + InventoryDetailId = item.Id, + StoreId = item.StoreId, + StoreCode = item.StoreCode, + MatSN = item.MatSN, + MatCode = item.MatCode, + MatName = item.MatName, + MatSpec = item.MatSpec, + MatBatch = item.MatBatch, + MatQty = item.MatQty, + MatSupplier = item.MatSupplier, + MatCustomer = item.MatCustomer, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + } + DbHelp.db.CommitTran(); + + //更新订单状态 + Task.Run(() => + { + if (outOrder != null) + { + #region 物料明细表是否已发完 + var orderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToList(); + var isExistNoSendMat = orderMatDetails.Where(t => t.IsSended == false) + .Any(); + if (isExistNoSendMat) + { + outOrder.OrderStatus = OutOrderStatus.部分发料; + } + else + { + outOrder.OrderStatus = OutOrderStatus.全部发料; + outOrder.OutOrderExeStatus = OutOrderExeStatus.发料完成; + } + #endregion + DbHelp.db.Updateable(outOrder).ExecuteCommand(); + } + }); + } + return new ResponseCommon() + { + Code = 200, + Message = $"Success", + Data = request.SnList + }; + + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + Logs.Write($"同步出库单据发生异常{ex.Message}", LogsType.Info); + return new ResponseCommon() + { + Code = 201, + Message = $"保存出库单失败!{ex.Message}!", + Data = request.SnList + }; + } + + } + + } + + public async Task GetOutOrderList(GetOutOrderListRequest request) + { + //直接查询 + var recordsQueryable = DbHelp.db.Queryable() + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber.Contains(request.OrderNumber)) + .WhereIF(!string.IsNullOrEmpty(request.OrderSource), t => t.OrderSource.Contains(request.OrderSource)) + .WhereIF(!string.IsNullOrEmpty(request.OrderType), t => t.OrderType.Contains(request.OrderType)) + .WhereIF(request.ShelfTypeId != 0, t => t.ShelfTypeId == request.ShelfTypeId); + + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable + .Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize) + .ToListAsync(); + //生成序号 + for (int i = 0; i < records.Count; i++) + { + records[i].RowNumber = (request.PageNumber - 1) * request.PageSize + i + 1; + } + + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + TotalCount = totalCount, + MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), + Count = records.Count, + Lists = records.ToList() + } + }; + } + + public async Task GetOutOrderListByStatus(GetOutOrderListByStatusRequest request) + { + if (request.OrderExeStatus == null || request.OrderExeStatus.Count == 0) + { + //不传入状态不显示 + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + Lists = new List() + } + }; + } + //直接查询 + var recordsQueryable = DbHelp.db.Queryable().Where(t => request.OrderExeStatus.Contains(t.OutOrderExeStatus)); + + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable + .OrderByDescending(t => t.CreateTime) + //.Take(request.PageSize) + .ToListAsync(); + + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + //TotalCount = totalCount, + //MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), + //Count = records.Count, + Lists = records.ToList() + } + }; + } + public async Task GetOutOrderDetail(GetOutOrderDetailRequest request) + { + OutOrder outOrder = null; + + #region 查询出库单 + if (request.OrderId != 0) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.Id == request.OrderId).FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.OrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.OrderNumber)) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } + #endregion + + #region 查询出库单明细 + var orderDetailTask = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToListAsync(); + var orderDetail = await orderDetailTask; + //生成序号 + for (int i = 0; i < orderDetail.Count; i++) + { + orderDetail[i].RowNumber = i + 1; + } + #endregion + + return new ResponseCommon>() + { + Code = 200, + Message = "Success", + Data = orderDetail + }; + } + + public async Task GetOutOrderMatDetail(GetOutOrderDetailRequest request) + { + OutOrder outOrder = null; + + #region 查询出库单 + if (request.OrderId != 0) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.Id == request.OrderId).FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.OrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.OrderNumber)) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } + #endregion + + #region 出库物料明细 + var orderMatDetailTask = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToListAsync(); + var orderMatDetail = await orderMatDetailTask; + //生成序号 + for (int i = 0; i < orderMatDetail.Count; i++) + { + orderMatDetail[i].RowNumber = i + 1; + } + #endregion + + + return new ResponseCommon> + { + Code = 200, + Message = outOrder.OrderStatus.ToString(), + Data = orderMatDetail + }; + } + + public async Task GoInOutstore(GetOutOrderDetailRequest request) + { + try + { + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + + //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 + if (order.SyncType == SyncTypeEnum.ByMatCode) + { + var result = CaculateOutOrderMatDetails(order, request.UserName); + if (result.Code != 200) + { + return result; + } + } + + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + if (outOrderMatDetails == null || outOrderMatDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据{request.OrderNumber}物料已全部完成出库!", + Data = null + }; + } + + if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成 + { + order.OutOrderExeStatus = OutOrderExeStatus.开始发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + + //按货架分组 按物料找到对应的货架 + var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) + .Distinct() + .ToList(); + var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); ; + + var outherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.待机模式).Select(t => t.ShelfCode).ToList(); + if (outherModeShelfs != null && outherModeShelfs.Count > 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"进入出库模式失败:货架{string.Join("", outherModeShelfs)}不在待机模式", + Data = null + }; + } + //看是否是分批次出库的情况 分批次亮灯 + if (LocalFile.Config.IsSameMatCodeOut) + { + var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode) + .Select(o => new { count = o.Count(), bb = o }) + .Where(o => o.count >= 2) + .OrderByDescending(o => o.count) + .ToList(); + //相同物料存在盘数超过2的情况,亮下一个盘数多的物料 + if (outOrderDetailCount.Count > 0) + { + var matCode = outOrderDetailCount.First().bb.Key; + outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) + .ToList(); + Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}!"); + } + //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 + else + { + //剩余物料全出 + Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!"); + } + } + + //对应的货架对应位置 进入出库模式 亮灯 + shelfs.ForEach(shelf => + { + var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode) + .Distinct() + .ToList(); + shelf.GoInOutstore(matDetails, order); + shelf.OrderNumber = order.OrderNumber; + }); + + //返回 + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + } + catch (Exception ex) + { + await GoOutOutstore(request); + throw ex; + } + } + + public async Task GoInOutstoreSingle(GetOutOrderDetailRequest request) + { + try + { + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + + //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 + if (order.SyncType == SyncTypeEnum.ByMatCode) + { + var result = CaculateOutOrderMatDetails(order, request.UserName); + if (result.Code != 200) + { + return result; + } + } + + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + if (outOrderMatDetails == null || outOrderMatDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据{request.OrderNumber}物料已全部完成出库!", + Data = null + }; + } + + if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成 + { + order.OutOrderExeStatus = OutOrderExeStatus.开始发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + //获取亮灯颜色 + List UsedColor = new List(); + string LightColor = ""; + List ol = DbHelp.db.Queryable().OrderBy(it => it.Id, OrderByType.Asc).ToList(); + foreach (OrderLight orderLight in ol) + { + UsedColor.Add(orderLight.LightColor); + if (orderLight.OrderNumber == request.OrderNumber) + { + LightColor = orderLight.LightColor; + break; + } + } + if (LightColor == "") + { + foreach (OrderLight orderLight in ol) + { + if (orderLight.OrderNumber == null) + { + LightColor = orderLight.LightColor; + DbHelp.db.Updateable().SetColumns(it => it.OrderNumber, request.OrderNumber).Where(it => it.LightColor == LightColor).ExecuteCommand(); + break; + } + } + } + //获取出库需求 + List outorderdetal = DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.OrderId == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .ToList(); + + OutResponseCommonSingle orcs = new OutResponseCommonSingle(); + orcs.Data = new List(); + foreach (OutOrderDetail outdetail in outorderdetal) + { + OutDetail od = new OutDetail(); + od.OrderId = outdetail.OrderId; + od.OrderNumber = outdetail.OrderNumber; + od.MatCode = outdetail.MatCode; + od.MatBatch = outdetail.MatBatch; + od.ReqQty = outdetail.ReqQty; + od.CreateTime = outdetail.CreateTime; + od.CreateUser = outdetail.CreateUser; + od.MatName = outdetail.MatName; + od.OutQty = outdetail.OutQty; + od.LightColor = LightColor; + orcs.Data.Add(od); + } + //需要出库的货架名 + List StoreCode = new List(); + //库位灯亮灯 + Dictionary> dict = new Dictionary>(); + foreach (OutOrderMatDetail oomd in outOrderMatDetails) + { + List mi= DbHelp.db.Queryable().Where(it => it.ModuleCode == oomd.StoreCode).ToList(); + if (mi.Count != 0) + { + if (!StoreCode.Contains(oomd.StoreCode)) + { + StoreCode.Add(oomd.StoreCode); + } + if (!dict.Keys.Contains(mi[0].CleintIp)) + { + List board_id = new List(); + board_id.Add(mi[0].BoardId); + dict.Add(mi[0].CleintIp, board_id); + } + else + { + foreach (var v in dict) + { + if (v.Key == mi[0].CleintIp) + { + if (!v.Value.Contains(mi[0].BoardId)) + { + v.Value.Add(mi[0].BoardId); + } + } + } + } + } + } + foreach (var v in dict) + { + string sendIP = v.Key; + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); + byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor,1); + tCPClient.Send(lightOn); + Thread.Sleep(100); + } + //报警灯亮 + List WarnLightShelfCode = new List(); + foreach (string storecode in StoreCode) + { + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == storecode).ToList(); + if (mi.Count != 0) + { + if (!WarnLightShelfCode.Contains(mi[0].ShelfCode)) + { + WarnLightShelfCode.Add(mi[0].ShelfCode); + } + } + } + foreach (string shelfcode in WarnLightShelfCode) + { + List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == shelfcode).ToList(); + if (si.Count != 0) + { + for (int i = 0; i < si.Count; i++) + { + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp); + byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId,"无",1,0); + tCPClient.Send(warnlightOn); + Thread.Sleep(100); + } + } + } + //返回 + return new OutResponseCommonSingle() + { + Code = 200, + Message = "Success", + Data = orcs.Data + }; + } + catch (Exception ex) + { + await GoOutOutstore(request); + throw ex; + } + } + + //计算、加锁 + private ResponseBase CaculateOutOrderMatDetails(OutOrder order, string createUser = "") + { + try + { + DbHelp.db.BeginTran(); + //第一步 物料需求表 + var outOrderDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .ToList(); + if (outOrderDetails == null || outOrderDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"计算物料失败,{order.OrderNumber}没有出库单据明细!" + }; + } + //第二步 开始计算物料 + List outOrderMatDetails = new List(); + foreach (var outOrderDetail in outOrderDetails) + { + //2.1筛选 满足 物料编码、批次的库存 + var matInventoryDetails = DbHelp.db.Queryable() + .Where(t => t.MatCode == outOrderDetail.MatCode) + .WhereIF(!string.IsNullOrEmpty(outOrderDetail.MatBatch), t => t.MatBatch == outOrderDetail.MatBatch) + .Where(t => t.IsLocked == false)//未锁定的物料 + .Where(t => t.StoreInfo.ShelfTypeId == order.ShelfTypeId) + .OrderBy(t => t.MatBatch)//按批次先进先出 + //(t => t.MatQty)//零散料先出 + .ToList(); + + //2.2按照搜索出来的库存和当前未出的数量 计算需要出的SN + for (int i = 0; i < matInventoryDetails.Count && outOrderDetail.ReqQty - outOrderDetail.OutQty > 0; i++) + { + if (outOrderDetail.ReqQty - outOrderDetail.OutQty <= matInventoryDetails[i].MatQty) + { + outOrderMatDetails.Add(new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + OutOrderDetailId = outOrderDetail.Id, + InventoryDetailId = matInventoryDetails[i].Id, + StoreId = matInventoryDetails[i].StoreId, + StoreCode = matInventoryDetails[i].StoreCode, + MatSN = matInventoryDetails[i].MatSN, + MatCode = matInventoryDetails[i].MatCode, + MatName = matInventoryDetails[i].MatName, + MatSpec = matInventoryDetails[i].MatSpec, + MatBatch = matInventoryDetails[i].MatBatch, + MatQty = matInventoryDetails[i].MatQty, + MatSupplier = matInventoryDetails[i].MatSupplier, + MatCustomer = matInventoryDetails[i].MatCustomer, + IsSended = false, + CreateUser = createUser, + }); + outOrderDetail.ReqQty = 0; + + matInventoryDetails[i].IsLocked = true; + DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand(); + } + else + { + outOrderDetail.ReqQty = outOrderDetail.ReqQty - matInventoryDetails[i].MatQty; + + outOrderMatDetails.Add(new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + OutOrderDetailId = outOrderDetail.Id, + InventoryDetailId = matInventoryDetails[i].Id, + StoreId = matInventoryDetails[i].StoreId, + StoreCode = matInventoryDetails[i].StoreCode, + MatSN = matInventoryDetails[i].MatSN, + MatCode = matInventoryDetails[i].MatCode, + MatName = matInventoryDetails[i].MatName, + MatSpec = matInventoryDetails[i].MatSpec, + MatBatch = matInventoryDetails[i].MatBatch, + MatQty = matInventoryDetails[i].MatQty, + MatSupplier = matInventoryDetails[i].MatSupplier, + MatCustomer = matInventoryDetails[i].MatCustomer, + IsSended = false, + CreateUser = createUser, + }); + + matInventoryDetails[i].IsLocked = true; + DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand(); + } + } + } + DbHelp.db.Insertable(outOrderMatDetails).ExecuteCommand(); + DbHelp.db.CommitTran(); + if (outOrderMatDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"计算物料失败,没有满足条件的物料进行出库!(请检查对应物料是否已被锁定)" + }; + } + else + + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"发生异常:{ex.Message}" + }; + } + } + + //删除 解锁 + private ResponseBase CancelOutOrderMatDetails(OutOrder order) + { + try + { + DbHelp.db.BeginTran(); + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .ToList(); + + var inventoryIds = outOrderMatDetails.Select(t => t.InventoryDetailId).ToList(); + var inventoryDetails = DbHelp.db.Queryable() + .Where(t => inventoryIds.Contains(t.Id)) + .ToList(); + inventoryDetails.ForEach(t => { t.IsLocked = false; }); + DbHelp.db.Deleteable(outOrderMatDetails).ExecuteCommand(); + DbHelp.db.Updateable(inventoryDetails).ExecuteCommand(); + + DbHelp.db.CommitTran(); + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"解锁物料时发生异常:{ex.Message}" + }; + } + } + + public async Task GoOutOutstore(GetOutOrderDetailRequest request) + { + + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + //执行状态改为暂停 + if (request.IsPause && order.OutOrderExeStatus != OutOrderExeStatus.发料完成) + { + order.OutOrderExeStatus = OutOrderExeStatus.暂停发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + + //解锁物料 删除物料明细 + if (order.SyncType == SyncTypeEnum.ByMatCode) + CancelOutOrderMatDetails(order); + + //找到正在出对应出库单的货架 + var shelves = ShelfManager.Shelves.Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.CurrentMode == HardWare.Mode.出库模式) + .ToList(); + + if (shelves == null || shelves.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据【{request.OrderNumber}】不在出库中!", + Data = null + }; + } + + + + //退出出库模式 + shelves.ForEach(t => + { + t.GoOutOutstore(); + }); + + + + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + + } + + public async Task GoOutOutstoreSingle(GetOutOrderDetailRequest request) + { + + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + //判断出库状态 + bool isComplete = true; + List ood = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.OrderNumber).ToList(); + foreach (OutOrderDetail detail in ood) + { + if (detail.ReqQty > detail.OutQty) + { + isComplete = false; + break; + } + } + if (isComplete == false) + { + order.OutOrderExeStatus = OutOrderExeStatus.暂停发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + else + { + order.OutOrderExeStatus = OutOrderExeStatus.发料完成; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + //解锁物料 + List List = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.OrderNumber).ToList(); + foreach (OutOrderMatDetail listdetail in List) + { + DbHelp.db.Updateable().SetColumns(it => it.IsLocked == false).Where(it => it.MatSN == listdetail.MatSN).ExecuteCommand(); + } + + DbHelp.db.Updateable().SetColumns(it => it.OrderNumber == null).Where(it => it.OrderNumber == request.OrderNumber).ExecuteCommand(); + //灭灯 +<<<<<<< HEAD + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == request.OrderNumber) + .ToList(); + //需要出库的货架名 + List StoreCode = new List(); + //库位灯灭灯 + Dictionary> dict = new Dictionary>(); + foreach (OutOrderMatDetail oomd in outOrderMatDetails) + { + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == oomd.StoreCode).ToList(); + if (mi.Count != 0) + { + if (!StoreCode.Contains(oomd.StoreCode)) + { + StoreCode.Add(oomd.StoreCode); + } + if (!dict.Keys.Contains(mi[0].CleintIp)) + { + List board_id = new List(); + board_id.Add(mi[0].BoardId); + dict.Add(mi[0].CleintIp, board_id); + } + else + { + foreach (var v in dict) + { + if (v.Key == mi[0].CleintIp) + { + if (!v.Value.Contains(mi[0].BoardId)) + { + v.Value.Add(mi[0].BoardId); + } + } + } + } + } + } + foreach (var v in dict) + { + string sendIP = v.Key; + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); + byte[] lightOn = Helper.OutstoreLight(v.Value, "无",0); + tCPClient.Send(lightOn); + Thread.Sleep(100); + } + //报警灯灭 + List WarnLightShelfCode = new List(); + foreach (string storecode in StoreCode) + { + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == storecode).ToList(); + if (mi.Count != 0) + { + if (!WarnLightShelfCode.Contains(mi[0].ShelfCode)) + { + WarnLightShelfCode.Add(mi[0].ShelfCode); + } + } + } + foreach (string shelfcode in WarnLightShelfCode) + { + List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == shelfcode).ToList(); + if (si.Count != 0) + { + for (int i = 0; i < si.Count; i++) + { + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp); + byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId, "无", 0, 0); + tCPClient.Send(warnlightOn); + Thread.Sleep(100); + } + } + } + + +======= +>>>>>>> 11 + + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + + } + + public async Task SingleLightConfirmOutstore(OutOrderMatDetailModelSingle request) + { + InOutRecord ior = new InOutRecord(); + List id = DbHelp.db.Queryable().Where(it => it.MatSN == request.MatSn).ToList(); + if (id.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"此SN不在库存中{request.MatSn}!", + Data = null + }; + } + ior.StoreId = id[0].StoreId; + ior.StoreCode = id[0].StoreCode; + ior.MatSN = request.MatSn; + ior.MatCode = request.MatCode; + ior.MatName = request.MatName; + ior.MatSpec = request.MatSpec; + ior.MatBatch = request.MatBatch; + ior.MatQty = request.Qty; + ior.MatSupplier = request.MatSupplier; + ior.MatCustomer = request.MatCustomer; + ior.OrderNumber = request.orderNumber; + ior.Direction = DirectionEnum.出库; + ior.OperateUser = request.userName; + ior.OperateTime = DateTime.Now; + //保存出库记录 + int count = DbHelp.db.Insertable(ior).ExecuteCommand(); + //删除库存 + DbHelp.db.Deleteable().Where(it => it.MatSN == request.MatSn).ExecuteCommand(); + //更新需求表 + List odd = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.orderNumber).Where(it => it.MatCode == request.MatCode).ToList(); + odd[0].OutQty += request.Qty; + DbHelp.db.Updateable(odd[0]).ExecuteCommand(); + + return new ResponseCommon() + { + Code = 200, + Message = $"出库成功", + Data = null + }; + } + + + } +} diff --git a/WCS.BLL/Services/Service/SelfCheckService.cs b/WCS.BLL/Services/Service/SelfCheckService.cs index faf4866..8088fe1 100644 --- a/WCS.BLL/Services/Service/SelfCheckService.cs +++ b/WCS.BLL/Services/Service/SelfCheckService.cs @@ -7,6 +7,7 @@ using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.Model; using WCS.Model.ApiModel.SelfCheck; +using WCS.Model.WebSocketModel; namespace WCS.BLL.Services.Service { @@ -42,5 +43,76 @@ namespace WCS.BLL.Services.Service Message = $"货架{string.Join(",", request.ShelfCodes)}已开始自检!", }; } + + public async Task StartSelfCheckByGroupName(List GroupNames) + { + if (GroupNames == null || GroupNames.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"参数为空!", + }; + } + //获取货架 + var shelfs = ShelfManager.Shelves + .Where(t => GroupNames.Contains(t.GroupName)) + .ToList(); + var cleintIps = shelfs.Select(t => t.ClientIp).Distinct().ToList(); + + foreach (var ip in cleintIps) + { + var currentIdShelfs = shelfs.Where(t => t.ClientIp == ip) + .ToList(); + Task.Run(() => + { + foreach(var shelf in currentIdShelfs) + { + + Task.Run(() => + { + var warningModel = new WebSocketMessageModel() + { + IsWarning = false, + ClientIsReceived = true, + WarningType = WarningTypeEnum.通知自检进度, + StoreId = 0, + StoreCode = "", + ShelfCode = shelf.ShelfCode, + ShelfId = shelf.ShelfId, + ClientIp = shelf.WebSocketIpAddress, + WarningMessage = $"货架【{shelf.ShelfCode}】开始自检" + }; + WarningManager.SendWarning(warningModel); + }); + + shelf.ShelfCheck(); + + Task.Run(() => + { + var warningModel = new WebSocketMessageModel() + { + IsWarning = false, + ClientIsReceived = true, + WarningType = WarningTypeEnum.通知自检进度, + StoreId = 0, + StoreCode = "", + ShelfCode = shelf.ShelfCode, + ShelfId = shelf.ShelfId, + ClientIp = shelf.WebSocketIpAddress, + WarningMessage = $"货架【{shelf.ShelfCode}】已完成自检" + }; + WarningManager.SendWarning(warningModel); + }); + Thread.Sleep(10); + } + }); + } + return new ResponseCommon() + { + Code = 200, + Message = $"已成功开始自检!", + }; + } } } diff --git a/WCS.BLL/Services/Service/StockTakingService.cs b/WCS.BLL/Services/Service/StockTakingService.cs index c71eb2b..b9821db 100644 --- a/WCS.BLL/Services/Service/StockTakingService.cs +++ b/WCS.BLL/Services/Service/StockTakingService.cs @@ -788,10 +788,21 @@ namespace WCS.BLL.Services.Service }; } shelf.ConfirmStocktakingSingle(stockTakingMatDetail.StoreInfo.BoardId, stockTakingMatDetail.StoreInfo.LightNumber); + + #endregion DbHelp.db.CommitTran(); - + //更新时间 避免被自动退出 + Task.Run(() => + { + var shelves = ShelfManager.Shelves.Where(t => t.CurrentMode == HardWare.Mode.盘点模式 && t.OrderNumber == request.StocktakingOrderNumber) + .ToList(); + foreach (var shelf in shelves) + { + shelf.SetCurrentModeTime = DateTime.Now; + } + }); #region 更新Order状态 Task.Run(() => { @@ -941,6 +952,12 @@ namespace WCS.BLL.Services.Service StoreCode = inventoryDetail.StoreCode, StoreId = inventoryDetail.StoreId, + R = inventoryDetail.R, + C = inventoryDetail.C, + Wei = inventoryDetail.Wei, + BigShelfCode = inventoryDetail.BigShelfCode, + GroupName = inventoryDetail.GroupName, + MatSN = inventoryDetail.MatSN, MatCode = inventoryDetail.MatCode, MatName = inventoryDetail.MatName, @@ -949,6 +966,7 @@ namespace WCS.BLL.Services.Service MatSpec = inventoryDetail.MatSpec, MatCustomer = inventoryDetail.MatCustomer, MatSupplier = inventoryDetail.MatSupplier, + OrderNumber = stockTakingOrderMatDetail.StocktakingOrderNumber, Direction = DirectionEnum.盘点, OperateUser = request.UserName diff --git a/WCS.BLL/Services/Service/StoreInfoService.cs b/WCS.BLL/Services/Service/StoreInfoService.cs index 9056619..a4e0c4c 100644 --- a/WCS.BLL/Services/Service/StoreInfoService.cs +++ b/WCS.BLL/Services/Service/StoreInfoService.cs @@ -5,13 +5,17 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using TouchSocket.Core; +using WCS.BLL.Config; using WCS.BLL.DbModels; +using WCS.BLL.HardWare; +using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.DAL; using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; using WCS.Model.ApiModel; +using WCS.Model.ApiModel.InOutRecord; using WCS.Model.ApiModel.StoreInfo; using WCS.Model.ApiModel.User; @@ -50,7 +54,6 @@ namespace WCS.BLL.Services.Service Lists = records.ToList() } }; - } catch (Exception ex) { @@ -106,7 +109,7 @@ namespace WCS.BLL.Services.Service shelfnfo.ClientIp = request.ShelfInfo.ClientIp; shelfnfo.GroupName = request.ShelfInfo.GroupName; shelfnfo.IsBind = request.ShelfInfo.IsBind; - shelfnfo.BindShelfCode = request.ShelfInfo.BindShelfCode; + shelfnfo.BigShelfCode = request.ShelfInfo.BigShelfCode; var rowNum = await DbHelp.db.Updateable(shelfnfo).ExecuteCommandAsync(); if (rowNum == 0) @@ -153,7 +156,7 @@ namespace WCS.BLL.Services.Service ClientIp = request.ShelfInfo.ClientIp, GroupName = request.ShelfInfo.GroupName, IsBind = request.ShelfInfo.IsBind, - BindShelfCode = request.ShelfInfo.BindShelfCode, + BigShelfCode = request.ShelfInfo.BigShelfCode, }; var rowNum = await DbHelp.db.Insertable(newShelfInfo).ExecuteCommandAsync(); if (rowNum == 0) @@ -242,29 +245,36 @@ namespace WCS.BLL.Services.Service /// public async Task> GenerateStoreInfo() { - var shelfInfo = await DbHelp.db.Queryable().Where(t => t.ShelfCode == "C04-1").FirstAsync(); - var ModuleInfos = await DbHelp.db.Queryable().Where(t => t.ShelfId == shelfInfo.Id).ToListAsync(); - ModuleInfos.ForEach(moduleInfo => + var shelfInfos = DbHelp.db.Queryable().ToList(); + foreach (var shelfInfo in shelfInfos) { - for (int i = 1; i <= moduleInfo.LightCount; i++) + var ModuleInfos = await DbHelp.db.Queryable().Where(t => t.ShelfId == shelfInfo.Id).ToListAsync(); + ModuleInfos.ForEach(moduleInfo => { - var storeInfo = new StoreInfo() + for (int i = 1; i <= moduleInfo.LightCount; i++) { - StoreCode = moduleInfo.ModuleCode + "-" + i.ToString(), - ModuleId = moduleInfo.Id, - ModuleCode = moduleInfo.ModuleCode, - ShelfId = shelfInfo.Id, - ShelfCode = shelfInfo.ShelfCode, - BoardId = moduleInfo.BoardId, - LightNumber = i, - Priority = 1, - CurrentMatSn = string.Empty, - }; - DbHelp.db.Insertable(storeInfo).ExecuteCommand(); - - } - }); - + var storeInfo = new StoreInfo() + { + StoreCode = moduleInfo.ModuleCode + "-" + i.ToString(), + ShelfTypeId = 1, + ModuleId = moduleInfo.Id, + ModuleCode = moduleInfo.ModuleCode, + ShelfId = shelfInfo.Id, + ShelfCode = shelfInfo.ShelfCode, + BoardId = moduleInfo.BoardId, + LightNumber = i, + Priority = 1, + CurrentMatSn = string.Empty, + BigShelfCode = moduleInfo.Bigshelfcode, + R = moduleInfo.R, + C = moduleInfo.C, + Wei = i.ToString(), + GroupName = moduleInfo.GroupName, + }; + DbHelp.db.Insertable(storeInfo).ExecuteCommand(); + } + }); + } return new ResponseCommon() { Message = "111" }; } @@ -308,6 +318,131 @@ namespace WCS.BLL.Services.Service }; } } + + /// + /// 禁用或启用模组 + /// + /// + /// + public async Task disableOrEnableModule(DisableOrEnableModuleRequest request) + { + //找到库位 + var moduleInfo = await DbHelp.db.Queryable() + .Where(t => t.Id == request.ModuleId) + .FirstAsync(); + //库位不存在 + if (moduleInfo == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:模组{request.ModuleCode}不存在!" + }; + } + try + { + DbHelp.db.BeginTran(); + //禁用 + if (request.DisableOrEnable == DisableOrEnableEnum.Disable) + { + moduleInfo.IsEnable = false; + //盟讯公司发送钉钉消息 + if (LocalFile.Config.IsMx) + { + var DingDing = string.Empty; + MXBackgroundThread.SendDingDingMsg($"【智能货架】模组{moduleInfo.ModuleCode}被屏蔽", new List { "104379", "103595" }, ref DingDing); + } + } + else + { + moduleInfo.IsEnable = true; + } + DbHelp.db.Updateable(moduleInfo).ExecuteCommand(); + DbHelp.db.CommitTran(); + + #region 更新缓存中的禁用/启动状态 + try + { + var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == moduleInfo.ShelfId) + .FirstOrDefault(); + if (shelf != null) + { + + var moduleInPc = shelf.Modules.Where(t => t.ModuleId == moduleInfo.Id) + .First(); + if (moduleInPc != null) + moduleInPc.IsEnable = request.DisableOrEnable == DisableOrEnableEnum.Enable; + } + } + catch + { + + } + #endregion + + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败:异常{ex.Message}!" + }; + } + } + + + /// + /// 发送指令获取模组的电压值 + /// + /// + /// + /// + public async Task queryModuleVoltage(QueryModuleVoltageRequest request) + { + try + { + var modules = await DbHelp.db.Queryable().Where(t => request.MouduleIds.Contains(t.Id)).ToListAsync(); + var isSend = false; + foreach (var module in modules) + { + var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == module.ShelfId).FirstOrDefault(); + if (shelf != null && shelf is SmartShelf) + { + var smartShelf = (SmartShelf)shelf; + smartShelf.QueryVoltage(module.Id); + isSend = true; + } + } + if (isSend) + return new ResponseCommon() + { + Code = 200, + Message = "Success" + }; + else + return new ResponseCommon() + { + Code = 201, + Message = "操作失败:未找到对应模组" + }; + } + catch (Exception ex) + { + return new ResponseCommon() + { + Code = 300, + Message = "操作失败:" + ex.Message + }; + } + } + #endregion #region 库位管理 @@ -352,6 +487,100 @@ namespace WCS.BLL.Services.Service }; } } + + public async Task disableOrEnableStore(DisableOrEnableStoreRequest request) + { + //找到库位 + var storeInfo = await DbHelp.db.Queryable() + .Where(t => t.Id == request.StoreId) + .FirstAsync(); + //库位不存在 + if (storeInfo == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:库位{request.SroreCode}不存在!" + }; + } + try + { + DbHelp.db.BeginTran(); + //禁用需要删除当前库存数据 + if (request.DisableOrEnable == DisableOrEnableEnum.Disable) + { + + //盟讯公司发送钉钉消息 + if (LocalFile.Config.IsMx) + { + var DingDing = string.Empty; + MXBackgroundThread.SendDingDingMsg($"【智能货架】库位{storeInfo.StoreCode}被屏蔽", new List { "104379", "103595" }, ref DingDing); + } + + //库位 + storeInfo.CurrentMatSn = "禁用"; + //库存数据处理 + var inventorys = DbHelp.db.Queryable() + .Where(t => t.StoreId == storeInfo.Id) + .ToList(); + if (inventorys != null && inventorys.Count > 0) + { + //删除并进行出入库记录 + foreach (var inventory in inventorys) + { + var inOutRecord = new InOutRecord() + { + StoreCode = storeInfo.StoreCode, + StoreId = storeInfo.Id, + StoreInfo = storeInfo, + + R = storeInfo.R, + C = storeInfo.C, + Wei = storeInfo.Wei, + BigShelfCode = storeInfo.BigShelfCode, + GroupName = storeInfo.GroupName, + + MatSN = inventory.MatSN, + MatCode = inventory.MatCode, + MatName = inventory.MatName, + MatSpec = inventory.MatSpec, + MatBatch = inventory.MatBatch, + MatQty = inventory.MatQty, + MatCustomer = inventory.MatCustomer, + MatSupplier = inventory.MatSupplier, + + OperateUser = request.UserName + "(禁用库位)", + Direction = DirectionEnum.丢失, + }; + DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + DbHelp.db.Deleteable(inventory).ExecuteCommand(); + } + } + } + else + { + storeInfo.CurrentMatSn = string.Empty; + } + DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + DbHelp.db.CommitTran(); + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败:异常{ex.Message}!" + }; + } + } + + #endregion } } diff --git a/WCS.BLL/Services/Service/UserService.cs b/WCS.BLL/Services/Service/UserService.cs index 8fa5916..53a144a 100644 --- a/WCS.BLL/Services/Service/UserService.cs +++ b/WCS.BLL/Services/Service/UserService.cs @@ -5,11 +5,16 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using TouchSocket.Core; +using WCS.BLL.Config; +using WCS.BLL.DbModels; +using WCS.BLL.Manager; using WCS.BLL.Services.IService; +using WCS.BLL.Tool; using WCS.DAL; using WCS.DAL.Db.AuthDb; using WCS.Model; using WCS.Model.ApiModel; +using WCS.Model.ApiModel.MXBackgroundThread; using WCS.Model.ApiModel.User; namespace WCS.BLL.Services.Service @@ -393,15 +398,67 @@ namespace WCS.BLL.Services.Service } else//登录模式需要校验密码 { - user = await AuthDbHelp.db.Queryable() - .Where(t => t.LoginName == request.UserName) - .FirstAsync(); + #region 盟讯公司登录接入系统接口 + if (LocalFile.Config.IsMx) + { + #region 调用接口 接入盟讯公司登录 + try + { + var body = new + { + uername = request.UserName, + password = request.PassWord, + }; + var Result = ApiHelp.GetDataFromHttpShortTime("http://192.168.2.23:9213/integrate/login/queryGenerLogin", body, "POST", true); + //账号密码验证成功 + if (Result != null && Result.code == 200) + { + //判断系统中是否有对应用户 + user = await AuthDbHelp.db.Queryable() + .Where(t => t.LoginName == request.UserName) + .FirstAsync(); + //Mes登录成功后wcs这边也添加一个用户 + if (user == null) + { + user = new UserBase() + { + LoginName = request.UserName, + Password = request.PassWord, + RoleIds = new List() { 2 }, + IsAdmin = false, + Time = DateTime.Now, + }; + await AuthDbHelp.db.Insertable(user).ExecuteCommandAsync(); + } + else if (user.Password != request.PassWord) + { + user.Password = request.PassWord; + await AuthDbHelp.db.Updateable(user).ExecuteCommandAsync(); + } + } + //账号密码验证失败 + else + { + + } + } + catch (Exception e) + { + + } + #endregion + } + #endregion + if (user == null) + user = await AuthDbHelp.db.Queryable() + .Where(t => t.LoginName == request.UserName) + .FirstAsync(); if (user == null) { return new ResponseCommon() { Code = 201, - Message = $"登录失败:用户名[{request.UserName}]不存在!", + Message = $"登录失败:用户名[{request.UserName}]不存在或密码输入错误!", Data = null }; } @@ -440,13 +497,23 @@ namespace WCS.BLL.Services.Service //返回字串不返回密码 user.Password = "***"; - var response = new ResponseCommon() { Code = 200, Message = "success", Data = user }; + //登录成功 + if (request.DeviceType == "WCS前端" && request.GroupNames != null) + { + var shelves = ShelfManager.Shelves.Where(t => request.GroupNames.Contains(t.GroupName)) + .ToList(); + foreach (var shelf in shelves) + { + shelf.WebSocketIpAddress = request.WebSocketIpAddress; + } + } + return response; } catch (Exception ex) diff --git a/WCS.BLL/Services/Service/WarningService.cs b/WCS.BLL/Services/Service/WarningService.cs index 4fcd5ce..78844cd 100644 --- a/WCS.BLL/Services/Service/WarningService.cs +++ b/WCS.BLL/Services/Service/WarningService.cs @@ -26,6 +26,7 @@ namespace WCS.BLL.Services.Service .FirstOrDefault(); if (warning != null) { + warning.SolvedUser = request.UserName; WarningManager.ClearWarning(warning, request.SolveType); } //判断一下是否还存在对应报警 diff --git a/WCS.BLL/Tool/Api/ApiHelp.cs b/WCS.BLL/Tool/Api/ApiHelp.cs index 98fffcf..4ce9b0f 100644 --- a/WCS.BLL/Tool/Api/ApiHelp.cs +++ b/WCS.BLL/Tool/Api/ApiHelp.cs @@ -274,7 +274,7 @@ namespace WCS.BLL.Tool public static T GetDataFromHttp(string url, object dataObj, string httpMethod, bool isSaveLog = false) { Guid guid = Guid.NewGuid(); - var data = JsonConvert.SerializeObject(dataObj); + var data = dataObj == null ? string.Empty : JsonConvert.SerializeObject(dataObj); try { if (isSaveLog) @@ -312,5 +312,47 @@ namespace WCS.BLL.Tool return default(T); } } + + public static T GetDataFromHttpShortTime(string url, object dataObj, string httpMethod, bool isSaveLog = false) + { + Guid guid = Guid.NewGuid(); + var data = dataObj == null ? string.Empty : JsonConvert.SerializeObject(dataObj); + try + { + if (isSaveLog) + Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}", LogsType.Api); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = httpMethod; + request.ContentType = "application/json"; + request.Timeout = 2000; + + if (!string.IsNullOrEmpty(data)) + { + string strContent = data; //参数data + using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream())) + { + dataStream.Write(strContent); + dataStream.Close(); + } + } + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + string encoding = response.ContentEncoding; + if (encoding == null || encoding.Length < 1) + { + encoding = "UTF-8"; //默认编码 + } + StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)); + string retString = reader.ReadToEnd(); + if (isSaveLog) + Logs.Write($"【{guid}】请求调用接口结束 返回数据为{retString}", LogsType.Api); + return JsonConvert.DeserializeObject(retString); + } + catch (Exception ex) + { + Logs.Write($"【{guid}】请求调用遇到异常 异常信息为{ex.Message}"); + return default(T); + } + } } } diff --git a/WCS.BLL/Tool/DependencyExtensions.cs b/WCS.BLL/Tool/DependencyExtensions.cs new file mode 100644 index 0000000..75142f7 --- /dev/null +++ b/WCS.BLL/Tool/DependencyExtensions.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.Sockets; + +namespace WCS.BLL.Tool +{ + /// + /// 一个心跳计数器扩展。 + /// + internal static class DependencyExtensions + { + public static readonly DependencyProperty HeartbeatTimerProperty = + DependencyProperty.Register("HeartbeatTimer", null); + + public static bool Ping(this TClient client) where TClient : ITcpClientBase + { + try + { + var data = new byte[] { 0x05, 0x00, 0x00, 0x06, 0x78, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00 }; + client.Send(data); + return true; + } + catch (Exception ex) + { + Logs.Write($"【{client.IP}:{client.Port}】发送心跳中发现异常:" + ex.Message, LogsType.Info); + if (ex is NotConnectedException) + { + + } + } + return false; + } + + public static bool Pong(this TClient client) where TClient : ITcpClientBase + { + try + { + client.Send(new MyRequestInfo() { DataType = DataType.Pong }.PackageAsBytes()); + return true; + } + catch (Exception ex) + { + client.Logger.Exception(ex); + } + + return false; + } + } +} diff --git a/WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs b/WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs new file mode 100644 index 0000000..3f97479 --- /dev/null +++ b/WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.Sockets; + +namespace WCS.BLL.Tool +{ + internal class HeartbeatAndReceivePlugin : PluginBase, ITcpConnectedPlugin, ITcpDisconnectedPlugin, ITcpReceivedPlugin + { + private readonly int m_timeTick; + private readonly ILog logger; + + [DependencyInject("20000")] + public HeartbeatAndReceivePlugin(int timeTick, ILog logger) + { + this.m_timeTick = 20000; + this.logger = logger; + } + + + public async Task OnTcpConnected(ITcpClientBase client, ConnectedEventArgs e) + { + if (client is ISocketClient) + { + return;//此处可判断,如果为服务器,则不用使用心跳。 + } + + if (client.GetValue(DependencyExtensions.HeartbeatTimerProperty) is Timer timer) + { + timer.Dispose(); + } + + client.SetValue(DependencyExtensions.HeartbeatTimerProperty, new Timer((o) => + { + client.Ping(); + }, null, 0, this.m_timeTick)); + await e.InvokeNext(); + } + + public async Task OnTcpDisconnected(ITcpClientBase client, DisconnectEventArgs e) + { + if (client.GetValue(DependencyExtensions.HeartbeatTimerProperty) is Timer timer) + { + timer.Dispose(); + client.SetValue(DependencyExtensions.HeartbeatTimerProperty, null); + } + + await e.InvokeNext(); + } + + public async Task OnTcpReceived(ITcpClientBase client, ReceivedDataEventArgs e) + { + if (e.RequestInfo is MyRequestInfo myRequest) + { + this.logger.Info(myRequest.ToString()); + if (myRequest.DataType == DataType.Ping) + { + client.Pong(); + } + } + await e.InvokeNext(); + } + } +} diff --git a/WCS.BLL/Tool/Helper.cs b/WCS.BLL/Tool/Helper.cs index 7087f23..79b428b 100644 --- a/WCS.BLL/Tool/Helper.cs +++ b/WCS.BLL/Tool/Helper.cs @@ -83,6 +83,30 @@ namespace WCS.BLL.Tool return data.ToArray(); } + public static byte[] Query() + { + byte[] data2 = new byte[4]; + data2[0] = 0xff; + data2[1] = 0x03; + data2[2] = 0x00; + data2[3] = 0x06; + byte[] senddata2 = Tool.Helper.Crc16(data2, data2.Length, true); + return senddata2; + } + + public static byte[] SetId() + { + byte[] data2 = new byte[6]; + data2[0] = 0xff; + data2[1] = 0x04; + data2[2] = 0x00; + data2[3] = 0x08; + data2[4] = 0x03; + data2[5] = 0x01; + byte[] senddata2 = Tool.Helper.Crc16(data2, data2.Length, true); + return senddata2; + } + //出库库位灯亮灯 public static byte[] OutstoreLight(List board_id, string lightcolor,int status) { @@ -200,11 +224,15 @@ namespace WCS.BLL.Tool //入库警示灯短亮(绿色),蜂鸣器鸣叫一次 public static byte[] InstoreWarnLight(int lightid) { + byte[] data1 = new byte[8]; byte[] data1 = new byte[8 + 3 * 6]; data1[0] = 0xff; data1[1] = 0x02; data1[2] = 0x00; data1[3] = 0x0a; + data1[4] = (byte)lightid; + data1[5] = 0x03; + data1[6] = 0x02; for (int i = 0; i < 7; i++) { data1[4 + i * 3] = (byte)(lightid + i); @@ -214,7 +242,8 @@ namespace WCS.BLL.Tool //data1[4] = (byte)lightid; //data1[5] = 0x03; //data1[6] = 0x02; - data1[7] = 0x02; + //data1[7] = 0x02; + data1[7] = 0x00; byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, true); return senddata1; } diff --git a/WCS.BLL/Tool/Logs.cs b/WCS.BLL/Tool/Logs.cs index ec604ac..ad80dc1 100644 --- a/WCS.BLL/Tool/Logs.cs +++ b/WCS.BLL/Tool/Logs.cs @@ -22,18 +22,25 @@ namespace WCS.BLL /// Info, /// - /// 警告 + /// 启动信息 /// - Warning, + StartBoot, /// - /// 错误 + /// 调用外部Api的接口 /// - Err, + Api, /// - /// 数据库错误 + /// 指令发送接收 /// - DbErr, - Api + Instructions, + /// + /// 指令重发 + /// + InstructionResend, + /// + /// 出库流程日志 + /// + Outstore, } /// @@ -115,16 +122,6 @@ namespace WCS.BLL Write($"{contentTitle} {JsonConvert.SerializeObject(content)}", type); } - /// - /// 写入日志 - /// - /// 错误 - /// 是否写入成功 - public static void Write(Exception ex, LogsType type = LogsType.Err) - { - Write(ex.ToString(), type); - } - /// /// 清除日志 /// diff --git a/WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs b/WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs new file mode 100644 index 0000000..9714c97 --- /dev/null +++ b/WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; + +namespace WCS.BLL.Tool +{ + + internal class MyFixedHeaderDataHandlingAdapter : CustomFixedHeaderDataHandlingAdapter + { + public override int HeaderLength => 3; + + public override bool CanSendRequestInfo => false; + + protected override MyRequestInfo GetInstance() + { + return new MyRequestInfo(); + } + + protected override void PreviewSend(IRequestInfo requestInfo) + { + throw new NotImplementedException(); + } + } + + internal class MyRequestInfo : IFixedHeaderRequestInfo + { + public DataType DataType { get; set; } + public byte[] Data { get; set; } + + public int BodyLength { get; private set; } + + public bool OnParsingBody(byte[] body) + { + if (body.Length == this.BodyLength) + { + this.Data = body; + return true; + } + return false; + } + + public bool OnParsingHeader(byte[] header) + { + if (header.Length == 3) + { + this.BodyLength = TouchSocketBitConverter.Default.ToUInt16(header, 0) - 1; + this.DataType = (DataType)header[2]; + return true; + } + return false; + } + + public void Package(ByteBlock byteBlock) + { + byteBlock.Write((ushort)((this.Data == null ? 0 : this.Data.Length) + 1)); + byteBlock.Write((byte)this.DataType); + if (this.Data != null) + { + byteBlock.Write(this.Data); + } + } + + public byte[] PackageAsBytes() + { + using var byteBlock = new ByteBlock(); + this.Package(byteBlock); + return byteBlock.ToArray(); + } + + public override string ToString() + { + return $"数据类型={this.DataType},数据={(this.Data == null ? "null" : Encoding.UTF8.GetString(this.Data))}"; + } + } + + internal enum DataType : byte + { + Ping, + Pong, + Data + } +} diff --git a/WCS.BLL/Tool/TCPClient.cs b/WCS.BLL/Tool/TCPClient.cs index ee74e07..73e25df 100644 --- a/WCS.BLL/Tool/TCPClient.cs +++ b/WCS.BLL/Tool/TCPClient.cs @@ -2,6 +2,7 @@ using System.Text; using TouchSocket.Core; using TouchSocket.Sockets; +using WCS.BLL.Tool; namespace WCS.BLL @@ -68,6 +69,7 @@ namespace WCS.BLL { //配置断线重连 a.UseReconnection(-1, true, 1000); + a.Add(); }) .ConfigureContainer(a => { @@ -79,36 +81,38 @@ namespace WCS.BLL tcpClient.Received += (client, e) => { var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); - Logs.Write($"校验发送接收,收到数据" + BitConverter.ToString(data)); - var len = data.Length; - for (int index = 0; index < data.Length - PreFixLength; index++) + Task.Run(() => { - //协议拆包 通过前缀校验是否为完整数据包 - var prefixInData = data.Skip(index).Take(PreFixLength); - var isEqual = prefixInData.SequenceEqual(Prefix); - if (isEqual) + Logs.Write($"【校验发送接收 开始】" + BitConverter.ToString(data), LogsType.InstructionResend); + var len = data.Length; + for (int index = 0; index < data.Length - PreFixLength; index++) { - var dataTemp = data.Skip(index).Take(PreFixLength + DataLength).ToArray(); - if (dataTemp.Length < PreFixLength + DataLength)//拆包后不满足一条指令的长度 + //协议拆包 通过前缀校验是否为完整数据包 + var prefixInData = data.Skip(index).Take(PreFixLength); + var isEqual = prefixInData.SequenceEqual(Prefix); + if (isEqual) { - continue; + var dataTemp = data.Skip(index).Take(PreFixLength + DataLength).ToArray(); + if (dataTemp.Length < PreFixLength + DataLength)//拆包后不满足一条指令的长度 + { + continue; + } + //获取返回指令的板子ID + var boardId = (dataTemp[PreFixLength + 0] << 8) + dataTemp[PreFixLength + 1]; + //查询当前板子是否有待验证的指令 + var message = new MessageDto(); + MessageList.TryGetValue(boardId, out message); + //功能位校验 功能位相同视为已响应指令 删除对应的指令 + if (message?.Message[PreFixLength + 2] == dataTemp[PreFixLength + 2]) + { + MessageList.TryRemove(boardId, out message); + } + index += (PreFixLength + DataLength - 2);//每次循环index会+1 所以这里-1 } - //获取返回指令的板子ID - var boardId = (data[PreFixLength + 0] << 8) + data[PreFixLength + 1]; - //查询当前板子是否有待验证的指令 - var message = new MessageDto(); - MessageList.TryGetValue(boardId, out message); - //功能位校验 功能位相同视为已响应指令 删除对应的指令 - if (message?.Message[PreFixLength + 2] == dataTemp[PreFixLength + 2]) - { - MessageList.TryRemove(boardId, out message); - } - index += (PreFixLength + DataLength - 1);//每次循环index会+1 所以这里-1 } - } - Logs.Write($"校验发送接收处理完毕" + BitConverter.ToString(data)); + Logs.Write($"【校验发送接收 结束】" + BitConverter.ToString(data), LogsType.InstructionResend); + }); return null; - }; tcpClient.Connected += (client, e) => @@ -131,27 +135,25 @@ namespace WCS.BLL try { //TODO如果指令已发两次 则取消重发 - Console.WriteLine(Thread.CurrentThread.ManagedThreadId); await Task.Delay(100); if (MessageList.Count > 0) { - var failedMessage = MessageList.Where(t => t.Value.SendTimes >= 2).ToList(); + var failedMessage = MessageList.Where(t => t.Value.LastSendTime < DateTime.Now.AddSeconds(-1)) + .ToList(); foreach (var message in failedMessage) { - Logs.Write(BitConverter.ToString(message.Value.Message) + - "指令未响应"); + Logs.Write("【指令重发】" + BitConverter.ToString(message.Value.Message) + "指令超时1s未响应", LogsType.InstructionResend); } - MessageList.RemoveWhen(t => t.Value.SendTimes >= 3); - - Console.WriteLine(Thread.CurrentThread.ManagedThreadId); + MessageList.RemoveWhen(t => t.Value.SendTimes >= 2); foreach (var item in MessageList) { if (item.Value.LastSendTime < DateTime.Now.AddSeconds(-1)) { - tcpClient.Send(item.Value.Message); + + Send(item.Value.Message); item.Value.SendTimes++; item.Value.LastSendTime = DateTime.Now; - await Task.Delay(10); + Logs.Write("【指令重发】" + BitConverter.ToString(item.Value.Message) + "已进行重发", LogsType.InstructionResend); } } } @@ -173,22 +175,36 @@ namespace WCS.BLL } - public void Send(byte[] message) + public void Send(byte[] message, bool IsReSend = false) { try { var boardId = (message[3] << 8) + message[4]; + + if (boardId != 2047 && IsReSend == false) + { + MessageList.TryAdd(boardId, new MessageDto() + { + ID = boardId, + Message = message, + SendTimes = 1 + }); + } + lock (sendLockObject) { tcpClient.Send(message); - //TODO MessageList.AddOrUpdate(new Mes) - //发送自带10ms间隔 - Thread.Sleep(10); + Task.Run(() => + { + Logs.Write($"【发送】{BitConverter.ToString(message)}", LogsType.Instructions); + }); + //发送自带8ms间隔 + Thread.Sleep(8); } } catch (Exception ex) { - //因异常断连时(网线已经被断了) 尝试重连一次 + //因异常断连时(网线已经被断了) 手动重连一次 if (ex is NotConnectedException) { Task.Run(() => @@ -226,18 +242,14 @@ namespace WCS.BLL public class MessageDto { public int ID { get; set; } - /// /// 最后一次发送时间 /// public DateTime LastSendTime { get; set; } = DateTime.Now; - /// /// 发送内容 /// public byte[] Message { get; set; } - - public bool IsWating { get; set; } /// /// 发送次数 /// diff --git a/WCS.DAL/Db/AuthDb/AuthDbHelp.cs b/WCS.DAL/Db/AuthDb/AuthDbHelp.cs index bacaadb..8981d8b 100644 --- a/WCS.DAL/Db/AuthDb/AuthDbHelp.cs +++ b/WCS.DAL/Db/AuthDb/AuthDbHelp.cs @@ -49,7 +49,7 @@ namespace WCS.DAL { Id = 1, LoginName = "admin", - Password = "", + Password = "admin123", RoleIds = new List () { 1 }, IsAdmin = true, Time = dt, diff --git a/WCS.DAL/Db/AuthDb/AuthModels.cs b/WCS.DAL/Db/AuthDb/AuthModels.cs index 813a026..1780d79 100644 --- a/WCS.DAL/Db/AuthDb/AuthModels.cs +++ b/WCS.DAL/Db/AuthDb/AuthModels.cs @@ -10,7 +10,7 @@ namespace WCS.DAL.Db.AuthDb /// /// 用户 /// - [SugarTable("User")] + [SugarTable("wcs_user")] public class UserBase { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] @@ -37,6 +37,13 @@ namespace WCS.DAL.Db.AuthDb /// 是否最大权限 /// public bool IsAdmin { get; set; } + + ///// + ///// 是否是工程研发 + ///// + //[SugarColumn(ColumnName = "IsGCYF", IsNullable = true, ColumnDescription = "是否是工程研发人员")] + public bool IsGCYF { get; set; } = false; + /// /// 创建时间 /// @@ -52,7 +59,7 @@ namespace WCS.DAL.Db.AuthDb /// /// 角色 /// - [SugarTable("Role")] + [SugarTable("wcs_role")] public class RoleBase { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] diff --git a/WCS.DAL/Db/DbHelp.cs b/WCS.DAL/Db/DbHelp.cs index d8a842f..180b104 100644 --- a/WCS.DAL/Db/DbHelp.cs +++ b/WCS.DAL/Db/DbHelp.cs @@ -1,6 +1,7 @@ using SqlSugar; using System; using System.Collections.Generic; +using System.Configuration; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -21,11 +22,8 @@ namespace WCS.DAL.Db { db.Aop.OnError = ex => { - //TO DO LOG - //Logs.Write($@"{nameof(db)}{Environment.NewLine}SQL:{ex?.Sql}{Environment.NewLine}Parametres:{JsonConvert.SerializeObject(ex?.Parametres)}{Environment.NewLine}InnerException:{ex?.InnerException?.ToString()}{Environment.NewLine}Exception:{ex?.ToString()}{Environment.NewLine}", LogsType.DbErr); }; }); - /// /// 日志数据库 /// @@ -38,23 +36,7 @@ namespace WCS.DAL.Db { db.Aop.OnError = ex => { - //TO DO LOG - //Logs.Write($@"{nameof(dbAuth)}{Environment.NewLine}SQL:{ex?.Sql}{Environment.NewLine}Parametres:{JsonConvert.SerializeObject(ex?.Parametres)}{Environment.NewLine}InnerException:{ex?.InnerException?.ToString()}{Environment.NewLine}Exception:{ex?.ToString()}{Environment.NewLine}", LogsType.DbErr); }; }); - - public static void InitDb() - { - //#region 初始化业务数据库 - ////不存在创建数据库,存在不会创建 - //db.DbMaintenance.CreateDatabase(); - ////创建表根据实体类 - //db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo)); - //#endregion - - //#region 初始化日志数据库 - //dbLog.DbMaintenance.CreateDatabase(); - //#endregion - } } } diff --git a/WCS.Model/ApiModel/Home/GetShelfStatusResponse.cs b/WCS.Model/ApiModel/Home/GetShelfStatusResponse.cs index afb0fd9..7d56251 100644 --- a/WCS.Model/ApiModel/Home/GetShelfStatusResponse.cs +++ b/WCS.Model/ApiModel/Home/GetShelfStatusResponse.cs @@ -8,10 +8,10 @@ namespace WCS.Model { public class GetShelfStatusResponse : ResponseBase { - public List Data { get; set; } + public List Data { get; set; } } - public class Shelf + public class ShelfModel { public int ShelfId { get; set; } @@ -33,5 +33,9 @@ namespace WCS.Model /// 货架组别 /// public string GroupName { get; set; } + /// + /// 单据号 + /// + public string OrderNumber { get; set; } } } diff --git a/WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs b/WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs new file mode 100644 index 0000000..e96603b --- /dev/null +++ b/WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Home +{ + public class ResetShelfStatusRequest : RequestBase + { + public List SelfIds { get; set; } + + public bool IsResetAll { get; set; } + + public List GroupNames { get; set; } + } +} diff --git a/WCS.Model/ApiModel/InOutRecord/InOutRecordModel.cs b/WCS.Model/ApiModel/InOutRecord/InOutRecordModel.cs index 4cad1a5..6782aa6 100644 --- a/WCS.Model/ApiModel/InOutRecord/InOutRecordModel.cs +++ b/WCS.Model/ApiModel/InOutRecord/InOutRecordModel.cs @@ -40,5 +40,6 @@ namespace WCS.Model.ApiModel.InOutRecord 出库 = 1, 丢失 = 2, 盘点 = 3, + 盘点下架 = 4, } } diff --git a/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs b/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs index fefa30f..854b56b 100644 --- a/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs +++ b/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs @@ -11,7 +11,6 @@ namespace WCS.Model public string MatSn { get; set; } = string.Empty; public string ShelfCode { get; set; } = string.Empty; public string IpAddress { get; set; } = string.Empty; - - public bool IsSingleLightIn { get; set; } = false; + public bool SingleLightIn { get; set; } = false; } } diff --git a/WCS.Model/ApiModel/MXBackgroundThread/ApiResult.cs b/WCS.Model/ApiModel/MXBackgroundThread/ApiResult.cs new file mode 100644 index 0000000..ab61a70 --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/ApiResult.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class ApiResult + { + /// + /// 处理结果 200成功 + /// + public int code { get; set; } + /// + /// 处理消息 + /// + public string message { get; set; } + + } + + public class ApiResult : ApiResult + { + + /// + /// 数据 + /// + public T data { get; set; } + } + + + public class ApiResultMsg + { + /// + /// 处理结果 200成功 + /// + public int code { get; set; } + /// + /// 处理消息 + /// + public string msg { get; set; } + + } + + public class ApiResultMsg : ApiResultMsg + { + + /// + /// 数据 + /// + public T data { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/BunkerOutRequest.cs b/WCS.Model/ApiModel/MXBackgroundThread/BunkerOutRequest.cs new file mode 100644 index 0000000..96c75a3 --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/BunkerOutRequest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class BunkerOutRequest + { + public string materialBar { get; set; } + /// + /// + /// + public int outType { get; set; } = 0; + /// + /// + /// + public string pickBillNumber { get; set; } + /// + /// + /// + public int qty { get; set; } = 0; + /// + /// + /// + public int warehouseType { get; set; } = 20; + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/ElectronicSiloPushRequest.cs b/WCS.Model/ApiModel/MXBackgroundThread/ElectronicSiloPushRequest.cs new file mode 100644 index 0000000..4213f55 --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/ElectronicSiloPushRequest.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class ElectronicSiloPushRequest + { + public string materialCode { get; set; } + public string warehouseCode { get; set; } + } + + public class ElectronicSiloPushDto + { + public string materialBar { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/InputStockInRequest.cs b/WCS.Model/ApiModel/MXBackgroundThread/InputStockInRequest.cs new file mode 100644 index 0000000..daa5a0f --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/InputStockInRequest.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class InputStockInRequest + { + public string materialBar { get; set; } + + public string shelfCode { get; set; } + + public string shelfX { get; set; } + + public string shelfY { get; set; } + + public string shelfZ { get; set; } + + public string inUser { get; set; } = string.Empty; + + public string inTime { get; set; } + + public int warehouseType { get; set; } = 20; + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/MXMesResponseCommon.cs b/WCS.Model/ApiModel/MXBackgroundThread/MXMesResponseCommon.cs new file mode 100644 index 0000000..c600841 --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/MXMesResponseCommon.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class MXMesResponseCommon + { + public int code { get; set; } + public string message { get; set; } + public string msg { get; set; } + public object data { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/PickOrderRequest.cs b/WCS.Model/ApiModel/MXBackgroundThread/PickOrderRequest.cs new file mode 100644 index 0000000..de230df --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/PickOrderRequest.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class PickOrderRequest + { + public string orderProdNumber { get; set; } + public string orderWorkNumber { get; set; } + public string pickBillNumber { get; set; } + } + + public class PickOrderResponse + { + /// + /// + /// + public int code { get; set; } + /// + /// + /// + public string msg { get; set; } + /// + /// + /// + public List data { get; set; } + } + public class PickOrder + { + public bool IsSelected { get; set; } + public int id { get; set; } + public string pickBillNumber { get; set; } + public string relationPickNumber { get; set; } + public string orderProdIds { get; set; } + public string orderProdNumbers { get; set; } + public string orderWorkIds { get; set; } + public string orderWorkNumbers { get; set; } + public string dictType { get; set; } + public string dictTypeStr + { + get + { + switch (dictType) + { + case "1": + return "生产领料"; + default: return "其他"; + } + } + } + public string dictStatus { get; set; } + public string dictStatusStr + { + get + { + switch (dictStatus) + { + case "15": + return "待领料"; + case "10": + return "部分领料"; + default: return dictStatus.ToString(); + } + } + } + public string createdBy { get; set; } + public string createdDt { get; set; } + public string updatedBy { get; set; } + public string updatedDt { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/QueryByBar.cs b/WCS.Model/ApiModel/MXBackgroundThread/QueryByBar.cs new file mode 100644 index 0000000..1a8ba81 --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/QueryByBar.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class QueryBybarRequest + { + //条码 + public string materialBar { get; set; } + } + + public class InStoreDto + { + public string materialBar { get; set; } + /// + /// + /// + public string materialCode { get; set; } + /// + /// 有源蜂鸣器 + /// + public string materialName { get; set; } + /// + /// TMB09A03/5X9电压3V + /// + public string materialSpec { get; set; } + + public double materialQty { get; set; } + + public string batchNo { get; set; } + } + + public class QueryBybarResponse + { + /// + /// + /// + public int code { get; set; } + /// + /// + /// + public string message { get; set; } + /// + /// + /// + public List data { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/RecommendedBarCodeRequest.cs b/WCS.Model/ApiModel/MXBackgroundThread/RecommendedBarCodeRequest.cs new file mode 100644 index 0000000..d5e9d58 --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/RecommendedBarCodeRequest.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class RecommendedBarCodeRequest + { + public string pickBillNumber { get; set; } + public string warehouseCode { get; set; } = string.Empty; + public int warehouseType { get; set; } = 10; + + } + + public class FistPushRecommendedBarCodeRequest : RecommendedBarCodeRequest + { + public string reportSide { get; set; } = null; + } + + public class RecommendedBarCodeResponse + { + /// + /// + /// + public int code { get; set; } + /// + /// + /// + public string message { get; set; } + /// + /// + /// + public List data { get; set; } + } + + public class PickOrderDetailGetReturnList + { + public bool IsInstore { get; set; } + public int id { get; set; } + public string materialBar { get; set; } + public string materialId { get; set; } + public string materialCode { get; set; } + public string materialName { get; set; } + public string materialSpec { get; set; } + public string unitOfMeasure { get; set; } + public string batchNo { get; set; } + public double qty { get; set; } + public string warehouseId { get; set; } + public string warehouseCode { get; set; } + public string warehouseName { get; set; } + public string shelfCode { get; set; } + public string shelfX { get; set; } + public string shelfY { get; set; } + public string shelfZ { get; set; } + public string inUser { get; set; } + public string inTime { get; set; } + public string outUser { get; set; } + public string outTime { get; set; } + public string createdBy { get; set; } + public string createdDt { get; set; } + public string updatedBy { get; set; } + public string updatedDt { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/SelectMaterialBarDto.cs b/WCS.Model/ApiModel/MXBackgroundThread/SelectMaterialBarDto.cs new file mode 100644 index 0000000..2cb6edf --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/SelectMaterialBarDto.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class SelectMaterialBarDto + { + public string materialBar { get; set; } + + public string warehouseCode { get; set; } + + public string warehouseName { get; set; } + } + + public class SelectMaterialBarResponse + { + /// + /// + /// + public int code { get; set; } + /// + /// + /// + public string msg { get; set; } + /// + /// + /// + public SelectMaterialBarDto data { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MXBackgroundThread/mesLoginRequest.cs b/WCS.Model/ApiModel/MXBackgroundThread/mesLoginRequest.cs new file mode 100644 index 0000000..afe181b --- /dev/null +++ b/WCS.Model/ApiModel/MXBackgroundThread/mesLoginRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MXBackgroundThread +{ + public class MXResponse + { + public int code { get; set; } + public string msg { get; set; } + public object data { get; set; } + } +} diff --git a/WCS.Model/ApiModel/MatInventoryDetail/CompareMatInventoryDetailRequest.cs b/WCS.Model/ApiModel/MatInventoryDetail/CompareMatInventoryDetailRequest.cs new file mode 100644 index 0000000..01cca12 --- /dev/null +++ b/WCS.Model/ApiModel/MatInventoryDetail/CompareMatInventoryDetailRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.MatInventoryDetail +{ + public class CompareMatInventoryDetailRequest : RequestBase + { + public List MatSns { get; set; } + + public string GroupName { get; set; } + + } +} diff --git a/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs b/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs index ccbccdb..38bfa2e 100644 --- a/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs +++ b/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs @@ -10,12 +10,10 @@ namespace WCS.Model.ApiModel.MatInventoryDetail public string MatName { get; set; } - public string MatSpec { get; set; } public string MatBatch { get; set; } - public string MatSupplier { get; set; } - public string MatCustomer { get; set; } + public int ShelfTypeId { get; set; } } } diff --git a/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs b/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs index b485d9c..d0e35f4 100644 --- a/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs +++ b/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs @@ -5,7 +5,7 @@ using System.Text; namespace WCS.Model.ApiModel.MatInventoryDetail { - public class MatInventorySummaryModel: INotifyPropertyChanged + public class MatInventorySummaryModel : INotifyPropertyChanged { public string MatCode { get; set; } @@ -33,6 +33,9 @@ namespace WCS.Model.ApiModel.MatInventoryDetail } } + public string Info { get; set; } + + public bool IsSelected { diff --git a/WCS.Model/ApiModel/OutStore/GetOutOrderDetailSingleLightResponse.cs b/WCS.Model/ApiModel/OutStore/GetOutOrderDetailSingleLightResponse.cs new file mode 100644 index 0000000..081a6f8 --- /dev/null +++ b/WCS.Model/ApiModel/OutStore/GetOutOrderDetailSingleLightResponse.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.OutStore +{ + public class ResponseCommonModify:ResponseCommon + { + public ResponseCommonDataDetail Data { get; set; } + } + + public class ResponseCommonDataDetail + { + public List Details { get; set; } + } +} diff --git a/WCS.Model/ApiModel/OutStore/GetOutOrderListByStatusRequest.cs b/WCS.Model/ApiModel/OutStore/GetOutOrderListByStatusRequest.cs index bfedf5d..3d1018e 100644 --- a/WCS.Model/ApiModel/OutStore/GetOutOrderListByStatusRequest.cs +++ b/WCS.Model/ApiModel/OutStore/GetOutOrderListByStatusRequest.cs @@ -10,5 +10,7 @@ namespace WCS.Model public class GetOutOrderListByStatusRequest : PageQueryRequestBase { public List OrderExeStatus { get; set; } + + public bool? IsMXPD { get; set; } } } diff --git a/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs b/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs index a9b18a0..76c0989 100644 --- a/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs +++ b/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs @@ -13,5 +13,7 @@ namespace WCS.Model public string OrderSource { get; set; } public string OrderType { get; set; } + + public int ShelfTypeId { get; set; } = 0; } } diff --git a/WCS.Model/ApiModel/OutStore/OutImportMatModel.cs b/WCS.Model/ApiModel/OutStore/OutImportMatModel.cs new file mode 100644 index 0000000..49f2694 --- /dev/null +++ b/WCS.Model/ApiModel/OutStore/OutImportMatModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.OutStore +{ + public class OutImportMatModel + { + public string 物料编码 { get; set; } + public string 物料名称 { get; set; } + public string 物料批次 { get; set; } + public int 需求数量 { get; set; } + } +} diff --git a/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModelSingle.cs b/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModelSingle.cs index 5a1ab48..ee2296d 100644 --- a/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModelSingle.cs +++ b/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModelSingle.cs @@ -4,19 +4,12 @@ using System.Text; namespace WCS.Model.ApiModel.OutStore { - public class OutOrderMatDetailModelSingle + public class OutOrderMatDetailModelSingle:RequestBase { - public int orderId { get; set; } - public string orderNumber { get; set; } + public int OrderId { get; set; } + public string OrderNumber { get; set; } + + public int MatId { get; set; } public string MatSn { get; set; } - public string MatCode { get; set; } - public string MatName { get; set; } - public string MatSpec { get; set; } - public string MatBatch { get; set; } - public int MatQty { get; set; } - public string MatCustomer { get; set; } - public string MatSupplier { get; set; } - public int Qty { get; set; } - public string userName { get; set; } } } diff --git a/WCS.Model/ApiModel/OutStore/OutOrderModel.cs b/WCS.Model/ApiModel/OutStore/OutOrderModel.cs index 63cd9de..393eea9 100644 --- a/WCS.Model/ApiModel/OutStore/OutOrderModel.cs +++ b/WCS.Model/ApiModel/OutStore/OutOrderModel.cs @@ -34,6 +34,7 @@ namespace WCS.Model.ApiModel.OutStore } public bool isSelected; public int RowNumber { get; set; } + public bool IsOuting { get; set; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) diff --git a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs index 645ce0c..ddd4019 100644 --- a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs +++ b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs @@ -17,6 +17,15 @@ namespace WCS.Model /// public string OrderType { get; set; } + /// + /// 货架类型Id + /// + public int ShelfTypeId { get; set; } = 0; + /// + /// 货架类型名称 + /// + public string ShelfTypeName { get; set; } = string.Empty; + public List ItemList { get; set; } } diff --git a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatSnRequest.cs b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatSnRequest.cs index e60189d..bff9ecf 100644 --- a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatSnRequest.cs +++ b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatSnRequest.cs @@ -17,6 +17,11 @@ namespace WCS.Model /// public string OrderType { get; set; } + /// + /// 是否是盟讯公司盘点生成的出库单 + /// + public bool IsMXPD { get; set; } = false; + public List SnList { get; set; } } } diff --git a/WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs new file mode 100644 index 0000000..60b978d --- /dev/null +++ b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.StoreInfo +{ + public class DisableOrEnableModuleRequest : RequestBase + { + public int ModuleId { get; set; } + + public string ModuleCode { get; set; } + + public DisableOrEnableEnum DisableOrEnable { get; set; } + } +} diff --git a/WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs new file mode 100644 index 0000000..1b36ec7 --- /dev/null +++ b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.StoreInfo +{ + public class DisableOrEnableStoreRequest : RequestBase + { + public int StoreId { get; set; } + + public string SroreCode { get; set; } + + public DisableOrEnableEnum DisableOrEnable { get; set; } + } + + public enum DisableOrEnableEnum + { + Disable = 0, + Enable = 1 + } + +} diff --git a/WCS.Model/ApiModel/StoreInfo/ModuleInfoModel.cs b/WCS.Model/ApiModel/StoreInfo/ModuleInfoModel.cs index 1213eb9..4cff369 100644 --- a/WCS.Model/ApiModel/StoreInfo/ModuleInfoModel.cs +++ b/WCS.Model/ApiModel/StoreInfo/ModuleInfoModel.cs @@ -24,7 +24,7 @@ namespace WCS.Model.ApiModel.StoreInfo public string C { get; set; } - public string? Bigshelfcode { get; set; } + public string? BigShelfCode { get; set; } public bool IsEnable { get; set; } diff --git a/WCS.Model/ApiModel/StoreInfo/QueryModuleVoltageRequest.cs b/WCS.Model/ApiModel/StoreInfo/QueryModuleVoltageRequest.cs new file mode 100644 index 0000000..67ff5be --- /dev/null +++ b/WCS.Model/ApiModel/StoreInfo/QueryModuleVoltageRequest.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.StoreInfo +{ + public class QueryModuleVoltageRequest : RequestBase + { + public List MouduleIds { get; set; } + } +} diff --git a/WCS.Model/ApiModel/StoreInfo/ShelfInfoModel.cs b/WCS.Model/ApiModel/StoreInfo/ShelfInfoModel.cs index eb2a6af..feb3e4f 100644 --- a/WCS.Model/ApiModel/StoreInfo/ShelfInfoModel.cs +++ b/WCS.Model/ApiModel/StoreInfo/ShelfInfoModel.cs @@ -49,7 +49,7 @@ namespace WCS.Model.ApiModel.StoreInfo public bool IsBind { get; set; } - public string BindShelfCode { get; set; } = string.Empty; + public string BigShelfCode { get; set; } public int RowNumber { get; set; } diff --git a/WCS.Model/ApiModel/User/UserLoginRequest.cs b/WCS.Model/ApiModel/User/UserLoginRequest.cs index f1b9c28..a3ee97f 100644 --- a/WCS.Model/ApiModel/User/UserLoginRequest.cs +++ b/WCS.Model/ApiModel/User/UserLoginRequest.cs @@ -14,5 +14,9 @@ namespace WCS.Model.ApiModel.User /// 是否配置为不登陆(如果不登陆 直接获取admin 且不验证密码了) /// public bool IsNoLogin { get; set; } = false; + + public string WebSocketIpAddress { get; set; } = string.Empty; + + public List GroupNames { get; set; } } } diff --git a/WCS.Model/WebSocketModel/SolveWarningRequesr.cs b/WCS.Model/WebSocketModel/SolveWarningRequesr.cs index 94a718d..7b97545 100644 --- a/WCS.Model/WebSocketModel/SolveWarningRequesr.cs +++ b/WCS.Model/WebSocketModel/SolveWarningRequesr.cs @@ -4,7 +4,7 @@ using System.Text; namespace WCS.Model.WebSocketModel { - public class SolveWarningRequest + public class SolveWarningRequest : RequestBase { public Guid Guid { get; set; } public SolveTypeEnum SolveType { get; set; } diff --git a/WCS.Model/WebSocketModel/WebSocketMessageModel.cs b/WCS.Model/WebSocketModel/WebSocketMessageModel.cs index 40e4f7f..d5cee2f 100644 --- a/WCS.Model/WebSocketModel/WebSocketMessageModel.cs +++ b/WCS.Model/WebSocketModel/WebSocketMessageModel.cs @@ -21,10 +21,20 @@ namespace WCS.Model.WebSocketModel /// public string ClientIp { get; set; } public DateTime LastSendTime { get; set; } + /// + /// 消息创建时间 跟消息时效性有关 + /// + public DateTime CreateTime { get; set; } = DateTime.Now; public bool ClientIsReceived { get; set; } //恢复正常需要消除的报警guid public List SolvedGuids { get; set; } + + + /// + /// 异常处理人 + /// + public string SolvedUser { get; set; } } public enum WarningTypeEnum @@ -46,9 +56,17 @@ namespace WCS.Model.WebSocketModel 进入盘点未响应 = 12, 确认盘点未响应 = 13, 退出盘点未响应 = 14, + + 自检丢失 = 15, + 自检未扫描上架 = 16, + //通知类 恢复正常 = 50, 通知刷新出库 = 51, 通知刷新盘点 = 52, + 通知刷新盟讯盘点 = 53, + 通知前台结束入库 = 54, + 通知刷新出库单列表 = 55, + 通知自检进度 = 56, } } diff --git a/WCS.WebApi/Controllers/FileDownLoadController.cs b/WCS.WebApi/Controllers/FileDownLoadController.cs new file mode 100644 index 0000000..83bfd85 --- /dev/null +++ b/WCS.WebApi/Controllers/FileDownLoadController.cs @@ -0,0 +1,83 @@ +using Microsoft.AspNetCore.Mvc; +using NPOI.HPSF; +using WCS.BLL.Services.IService; +using WCS.Model; +using WCS.Model.ApiModel; +using WCS.Model.ApiModel.User; +using WCS.Model.WebSocketModel; + +namespace WCS.WebApi.Controllers +{ + /// + /// 文件下载 + /// + [ApiController] + [Route("[controller]")] + public class FileDownLoadController : ControllerBase + { + + public FileDownLoadController() + { + + } + + [HttpGet("downloadApp")] + public IActionResult downloadApp(string fileName) + { + // 这里是文件的物理路径,你需要根据实际情况提供 + var filePath = Path.Combine(Directory.GetCurrentDirectory(), $"Files/{fileName}"); + + // 检查文件是否存在 + if (!System.IO.File.Exists(filePath)) + { + return NotFound(); + } + + // 获取文件流 + var stream = System.IO.File.OpenRead(filePath); + // 设置HTTP响应头,使浏览器知道这是一个附件,应该下载而不是打开 + Response.Headers.Add("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + // 返回文件流作为FileResult + return File(stream, "application/octet-stream", fileName); + } + + [HttpGet("getLatestAppName")] + public ResponseCommon getLatestAppName() + { + string directoryPath = Path.Combine(AppContext.BaseDirectory, $"Files"); + + // 获取目录下的所有文件信息 + FileInfo[] files = Directory.GetFiles(directoryPath, "*.APK") + .Select(file => new FileInfo(file)) + .ToArray(); + + if (files == null || files.Length == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "服务器不存在App安装包" + }; + } + //获取最后修改的一个 + FileInfo lastModifiedFile = files.OrderByDescending(f => f.LastWriteTime).First(); + if (lastModifiedFile != null) + { + return new ResponseCommon() + { + Code = 200, + Data = lastModifiedFile.Name + }; + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = "服务器不存在App安装包" + }; + + } + } + } +} diff --git a/WCS.WebApi/Controllers/HomeController.cs b/WCS.WebApi/Controllers/HomeController.cs index 8a15a64..89137e0 100644 --- a/WCS.WebApi/Controllers/HomeController.cs +++ b/WCS.WebApi/Controllers/HomeController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using SqlSugar; using WCS.BLL.DbModels; +using WCS.BLL.HardWare; using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.BLL.Services.Service; @@ -18,10 +19,12 @@ namespace WCS.WebApi.Controllers public class HomeController : ControllerBase { public IHomerService _homerService { get; set; } + public ISelfCheckService _selfCheckService { get; set; } - public HomeController(IHomerService homerService) + public HomeController(IHomerService homerService, ISelfCheckService selfCheckService) { _homerService = homerService; + _selfCheckService = selfCheckService; } [Route("getShelfTypes")] @@ -73,21 +76,104 @@ namespace WCS.WebApi.Controllers { Code = 200, Message = "success", - Data = shelfs.Select(t => new Shelf + Data = shelfs.Select(t => new ShelfModel { ShelfId = t.ShelfId, ShelfCode = t.ShelfCode, CurentMode = (int)t.CurrentMode, ModulesStr = t.ModulesStr, - GroupName = t.GroupName + GroupName = t.GroupName, + OrderNumber = t.OrderNumber, }).ToList(), }; } catch (Exception ex) { - return null; + return new ResponseBase() + { + Code = 300, + Message = "获取失败:" + ex.Message, + }; } } + + [Route("shelfCheckAll")] + [HttpPost(Name = "shelfCheckAll")] + public async Task shelfCheckAll(GetShelfStatusRequest request) + { + try + { + return await _selfCheckService.StartSelfCheckByGroupName(request.GroupNames); + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 300, + Message = "操作失败:" + ex.Message, + }; + } + } + + + /// + /// 重置货架的状态 使其回到待机模式 + /// + /// + /// + [Route("resetShelfStatus")] + [HttpPost(Name = "resetShelfStatus")] + public async Task resetShelfStatus(ResetShelfStatusRequest request) + { + try + { + if (request.IsResetAll == false && (request.SelfIds == null || request.SelfIds.Count == 0)) + { + return new ResponseBase() + { + Code = 201, + Message = "复位失败:请选择需要复位的货架!", + }; + } + if (request.IsResetAll == true && (request.GroupNames == null || request.GroupNames.Count == 0)) + { + return new ResponseBase() + { + Code = 201, + Message = "复位失败:请选择需要复位的货架区域!", + }; + } + var shelfs = new List(); + if (request.IsResetAll == false) + shelfs = ShelfManager.Shelves + .Where(t => request.SelfIds.Contains(t.ShelfId)) + .Where(t => t.CurrentMode != Mode.待机模式) + .ToList(); + else + shelfs = ShelfManager.Shelves + .Where(t => request.GroupNames.Contains(t.GroupName)) + .Where(t => t.CurrentMode != Mode.待机模式) + .ToList(); + foreach (var shelf in shelfs) + { + shelf.Reset(); + } + return new ResponseBase() + { + Code = 200, + Message = "success", + }; + + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 300, + Message = ex.Message, + }; + } + } } } diff --git a/WCS.WebApi/Controllers/InstoreController.cs b/WCS.WebApi/Controllers/InstoreController.cs index d8aa60d..1846fce 100644 --- a/WCS.WebApi/Controllers/InstoreController.cs +++ b/WCS.WebApi/Controllers/InstoreController.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using WCS.BLL.HardWare; using WCS.BLL.Manager; using WCS.BLL.Services.IService; +using WCS.BLL.Tool; using WCS.Model; namespace WebApi.Controllers @@ -141,9 +142,12 @@ namespace WebApi.Controllers //TODO: ƻύ try { + var aa = Helper.Query(); + var bb = Helper.SetId(); return await _instoreService.queryInstoreStatusSingle(request); //ShelfManager. // + } catch (Exception ex) { diff --git a/WCS.WebApi/Controllers/MatInventoryDetailController.cs b/WCS.WebApi/Controllers/MatInventoryDetailController.cs index b0e75e3..ad52277 100644 --- a/WCS.WebApi/Controllers/MatInventoryDetailController.cs +++ b/WCS.WebApi/Controllers/MatInventoryDetailController.cs @@ -86,5 +86,13 @@ namespace WCS.WebApi.Controllers { return await _matInventoryDetailService.getMatInventorySummary(request); } + + [Route("compareMatInventoryDetail")] + [HttpPost(Name = "compareMatInventoryDetail")] + public async Task compareMatInventoryDetail(CompareMatInventoryDetailRequest request) + { + return await _matInventoryDetailService.compareMatInventoryDetail(request); + } + } } diff --git a/WCS.WebApi/Controllers/OutstoreController.cs b/WCS.WebApi/Controllers/OutstoreController.cs index 217e661..d828528 100644 --- a/WCS.WebApi/Controllers/OutstoreController.cs +++ b/WCS.WebApi/Controllers/OutstoreController.cs @@ -1,9 +1,11 @@ using Microsoft.AspNetCore.Mvc; +using MiniExcelLibs; using WCS.BLL.HardWare; using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.BLL.Services.Service; using WCS.Model; +using WCS.Model.ApiModel.MatBaseInfo; using WCS.Model.ApiModel.OutStore; namespace WebApi.Controllers @@ -15,12 +17,54 @@ namespace WebApi.Controllers private readonly IOutstoreService _outstoreService; private readonly IGenerateService _generateService; - public OutstoreController(IOutstoreService outstoreService,IGenerateService generateService) + public OutstoreController(IOutstoreService outstoreService, IGenerateService generateService) { _outstoreService = outstoreService; _generateService = generateService; } + + /// + /// ģУͱȶ + /// + /// + /// + [Route("importMat")] + [HttpPost(Name = "importMat")] + public async Task importMat([FromForm] IFormFile excelFile, [FromForm] string userName, [FromForm] string deviceType) + { + try + { + //ļУ + if (excelFile == null || excelFile.Length == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "ʧ:ļЧݣ" + }; + } + //ȡе + using (var stream = new MemoryStream()) + { + await excelFile.CopyToAsync(stream); + stream.Position = 0; + var list = MiniExcelLibs.MiniExcel.Query(stream, "⵼ģ", ExcelType.XLSX).ToList(); + return await _outstoreService.importMat(list); + } + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 201, + Message = "ʧܣ" + ex.Message, + }; + } + } + + + /// /// ϱͬ /// @@ -33,7 +77,7 @@ namespace WebApi.Controllers try { if (string.IsNullOrEmpty(request.OrderNumber)) - { + { request.OrderNumber = await _generateService.generateOutOrderNumber(); } return await _outstoreService.SysOutOrderByMatCode(request); @@ -62,7 +106,12 @@ namespace WebApi.Controllers { if (string.IsNullOrEmpty(request.OrderNumber)) { - request.OrderNumber = await _generateService.generateOutOrderNumber(); + if (request.IsMXPD) + { + request.OrderNumber = await _generateService.generateMXPDOutOrderNumber(); + } + else + request.OrderNumber = await _generateService.generateOutOrderNumber(); } return await _outstoreService.SysOutOrderByMatSn(request); } @@ -146,6 +195,25 @@ namespace WebApi.Controllers } } + [Route("getOutOrderDetailSingleLight")] + [HttpPost(Name = "getOutOrderDetailSingleLight")] + public async Task getOutOrderDetailSingleLight(GetOutOrderDetailRequest request) + { + try + { + return await _outstoreService.GetOutOrderDetailSingleLight(request); + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 300, + Message = "ѯʧܣ" + ex.Message, + }; + } + } + + /// /// ȡⵥϸ /// diff --git a/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs b/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs index 7376953..6024b66 100644 --- a/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs +++ b/WCS.WebApi/Controllers/RequestResponseLoggingMiddleware.cs @@ -72,28 +72,45 @@ namespace WCS.WebApi.Controllers finally { + var guid = Guid.NewGuid(); //TO DO如何将记日志的 和不记日志的分开 解耦 if (!context.Request.Path.ToString().Contains("getInterfaceRecord")) + { try { + Logs.Write($"[记录接口日志]{guid},开始记录{context.Request.Path.ToString()}", LogsType.Api); var logRecord = new SystemApiLogRecord() { DeviceIp = context?.Connection?.RemoteIpAddress?.ToString(), - RequestUrl = context.Request.Path, + RequestUrl = context.Request?.Path.ToString(), RequestBody = requestBody, - QueryString = context.Request.QueryString.ToString(), + QueryString = context.Request?.QueryString.ToString(), IsResponse = true, ResponseJson = responseBody, RequestTime = requestTime, ResponseTime = DateTime.Now, ExecutionTime = stopwatch.ElapsedMilliseconds }; - await DbHelp.dbLog.Insertable(logRecord).ExecuteCommandAsync(); + Task.Run(() => + { + try + { + DbHelp.dbLog.Insertable(logRecord).ExecuteCommand(); + } + catch (Exception ex) + { + Logs.Write($"[记录接口日志]{guid}保存数据失败!发生异常:" + ex.Message, LogsType.Api); + } + + }); } catch (Exception e) { - //TO DO txt记录失败的日志和响应实体 + Logs.Write($"[记录接口日志]{guid}失败!发生异常:" + e.Message, LogsType.Api); } + } + else + Logs.Write($"[记录接口日志]{guid},不记录getInterfaceRecord", LogsType.Api); } } } diff --git a/WCS.WebApi/Controllers/StoreInfoController.cs b/WCS.WebApi/Controllers/StoreInfoController.cs index 1532fb3..92dc1a4 100644 --- a/WCS.WebApi/Controllers/StoreInfoController.cs +++ b/WCS.WebApi/Controllers/StoreInfoController.cs @@ -52,6 +52,20 @@ namespace WCS.WebApi.Controllers { return await _storeInfoService.GetModules(request); } + + [Route("disableOrEnableModule")] + [HttpPost(Name = "disableOrEnableModule")] + public async Task disableOrEnableModule(DisableOrEnableModuleRequest request) + { + return await _storeInfoService.disableOrEnableModule(request); + } + + [Route("queryModuleVoltage")] + [HttpPost(Name = "queryModuleVoltage")] + public async Task queryModuleVoltage(QueryModuleVoltageRequest request) + { + return await _storeInfoService.queryModuleVoltage(request); + } #endregion #region 库位管理 @@ -61,6 +75,13 @@ namespace WCS.WebApi.Controllers { return await _storeInfoService.GetStores(request); } + + [Route("disableOrEnableStore")] + [HttpPost(Name = "disableOrEnableStore")] + public async Task disableOrEnableStore(DisableOrEnableStoreRequest request) + { + return await _storeInfoService.disableOrEnableStore(request); + } #endregion } } diff --git a/WCS.WebApi/Controllers/UserController.cs b/WCS.WebApi/Controllers/UserController.cs index bc70c55..2cc712b 100644 --- a/WCS.WebApi/Controllers/UserController.cs +++ b/WCS.WebApi/Controllers/UserController.cs @@ -52,6 +52,8 @@ namespace WCS.WebApi.Controllers [HttpPost(Name = "userLogin")] public async Task userLogin(UserLoginRequest request) { + //获取调用设备的Ip地址 + request.WebSocketIpAddress = HttpContext?.Connection?.RemoteIpAddress?.ToString(); return await _userService.UserLogin(request); } } diff --git a/WCS.WebApi/Controllers/WarningController.cs b/WCS.WebApi/Controllers/WarningController.cs index 5392169..410c066 100644 --- a/WCS.WebApi/Controllers/WarningController.cs +++ b/WCS.WebApi/Controllers/WarningController.cs @@ -7,9 +7,6 @@ using WCS.Model.WebSocketModel; namespace WCS.WebApi.Controllers { - /// - /// 权限/用户界面的接口 - /// [ApiController] [Route("[controller]")] public class WarningController : ControllerBase @@ -27,5 +24,7 @@ namespace WCS.WebApi.Controllers { return await _warningService.SolveWarning(request); } + + } } diff --git a/WCS.WebApi/LocalStatic.cs b/WCS.WebApi/LocalStatic.cs deleted file mode 100644 index 5bfa45d..0000000 --- a/WCS.WebApi/LocalStatic.cs +++ /dev/null @@ -1,9 +0,0 @@ -using WCS.BLL; - -namespace WCS.WebApi -{ - public static class LocalStatic - { - - } -} diff --git a/WCS.WebApi/Program.cs b/WCS.WebApi/Program.cs index 176237c..114e893 100644 --- a/WCS.WebApi/Program.cs +++ b/WCS.WebApi/Program.cs @@ -20,57 +20,80 @@ namespace WebApi { public static void Main(string[] args) { +<<<<<<< HEAD WebSoceketManager.InitWebSocket(); - - DbInit.InitDb(); - - LocalFile.SaveConfig(); - - TCPClientManager.InitTcpClient(); - - ShelfManager.InitShelves(); - - //λƺͰ - //TCPClientManager.InitStatus(); - - WarningManager.StartWarningMessageThread(); - - var builder = WebApplication.CreateBuilder(args); - - // Add services to the container. - builder.Services.AddControllers(); - // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle - builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerGen(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - //롢ɵõģʽ - builder.Services.AddSingleton(); - - var app = builder.Build(); - - app.UseMiddleware(); - // Configure the HTTP request pipeline. - if (app.Environment.IsDevelopment()) +======= + try { - app.UseSwagger(); - app.UseSwaggerUI(); - } + //ʼwebsocket + WebSoceketManager.InitWebSocket(); - app.UseAuthorization(); - app.MapControllers(); - app.Run("http://+:8888"); + //ʼݿ + DbInit.InitDb(); +>>>>>>> 7f35077c07959e9571515ee1a1f88123f9e20bd5 + + //ʼļ + LocalFile.SaveConfig(); + + //ʼTCP + TCPClientManager.InitTcpClient(); + + //ʼܻϢ + ShelfManager.InitShelves(); + + //Ϣط߳ + WarningManager.StartWarningMessageThread(); + + //Ѷ˾̨߳ + if (LocalFile.Config.IsMx) + { + MXBackgroundThread.InitBackgroundThread(); + var str = string.Empty; + MXBackgroundThread.SendDingDingMsg("̨ɹ", new List { "104379" }, ref str); + } + + + + var builder = WebApplication.CreateBuilder(args); + // Add services to the container. + builder.Services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + //롢ɵõģʽ + builder.Services.AddSingleton(); + + var app = builder.Build(); + + app.UseMiddleware(); + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseAuthorization(); + app.MapControllers(); + app.Run("http://0.0.0.0:8888");//0.0.0.0ʾipv4 + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } } } } diff --git a/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml b/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml index 36847ea..b1eb0ee 100644 --- a/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml +++ b/WCS.WebApi/Properties/PublishProfiles/FolderProfile1.pubxml @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - false + true false true Release @@ -13,5 +13,11 @@ https://go.microsoft.com/fwlink/?LinkID=208121. bin\Release\net6.0\publish\ FileSystem <_TargetId>Folder + + net6.0 + win-x64 + 118d453b-1693-4c00-8378-20ecbfcf2700 + false + false \ No newline at end of file diff --git a/WCS.WebApi/WCS.WebApi.csproj b/WCS.WebApi/WCS.WebApi.csproj index 840dcac..4cbb681 100644 --- a/WCS.WebApi/WCS.WebApi.csproj +++ b/WCS.WebApi/WCS.WebApi.csproj @@ -18,4 +18,14 @@ + + + + + + + PreserveNewest + + + diff --git a/货架标准上位机/Api/ApiHelp.cs b/货架标准上位机/Api/ApiHelp.cs index f3559d2..4abe7dd 100644 --- a/货架标准上位机/Api/ApiHelp.cs +++ b/货架标准上位机/Api/ApiHelp.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Input; using WCS.Model; +using WCS.Model.ApiModel.MXBackgroundThread; namespace 货架标准上位机.Api { @@ -282,11 +283,11 @@ namespace 货架标准上位机.Api public static T GetDataFromHttp(string url, object dataObj, string httpMethod, bool isSaveLog = false) { Guid guid = Guid.NewGuid(); - var data = JsonConvert.SerializeObject(dataObj); + var data = dataObj == null ? string.Empty : JsonConvert.SerializeObject(dataObj); try { if (isSaveLog) - Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}",LogsType.Api); + Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}", LogsType.Api); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = httpMethod; request.ContentType = "application/json"; @@ -320,5 +321,100 @@ namespace 货架标准上位机.Api return default(T); } } + + /// + /// 调用接口-长延时(MX MES接口返回时间偶尔10秒+为保证业务能正常进行所以增加此接口) + /// + /// + /// + /// + /// + /// + /// + public static ApiResult MXGetDataFromHttpLongWait(string data, string url, string httpMethod, bool isSaveLog = false) + { + Guid guid = Guid.NewGuid(); + try + { + if (isSaveLog) + Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}"); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = httpMethod; + request.ContentType = "application/json"; + request.Timeout = 20000; + if (!string.IsNullOrEmpty(data)) + { + string strContent = data; //参数data + using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream())) + { + dataStream.Write(strContent); + dataStream.Close(); + } + } + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + string encoding = response.ContentEncoding; + if (encoding == null || encoding.Length < 1) + { + encoding = "UTF-8"; //默认编码 + } + StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)); + string retString = reader.ReadToEnd(); + if (isSaveLog) + Logs.Write($"【{guid}】请求调用接口结束 返回数据为{retString}"); + return JsonConvert.DeserializeObject>(retString); + } + catch (Exception ex) + { + Logs.Write($"【{guid}】请求调用遇到异常 异常信息为{ex.Message}"); + return new ApiResult() + { + code = 500, + message = ex.Message, + }; + } + } + public static ApiResult MXGetDataFromHttp(string data, string url, string httpMethod, bool isSaveLog = false) + { + Guid guid = Guid.NewGuid(); + try + { + if (isSaveLog) + Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}"); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = httpMethod; + request.ContentType = "application/json"; + request.Timeout = 8000; + if (!string.IsNullOrEmpty(data)) + { + string strContent = data; //参数data + using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream())) + { + dataStream.Write(strContent); + dataStream.Close(); + } + } + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + string encoding = response.ContentEncoding; + if (encoding == null || encoding.Length < 1) + { + encoding = "UTF-8"; //默认编码 + } + StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)); + string retString = reader.ReadToEnd(); + if (isSaveLog) + Logs.Write($"【{guid}】请求调用接口结束 返回数据为{retString}"); + return JsonConvert.DeserializeObject>(retString); + } + catch (Exception ex) + { + Logs.Write($"【{guid}】请求调用遇到异常 异常信息为{ex.Message}"); + return new ApiResult() + { + code = 500, + message = ex.Message, + }; + } + } } } diff --git a/货架标准上位机/App.xaml b/货架标准上位机/App.xaml index 1640844..feac15d 100644 --- a/货架标准上位机/App.xaml +++ b/货架标准上位机/App.xaml @@ -2,7 +2,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:货架标准上位机" - StartupUri="Views/MainWindows/MainWindow1.xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:hc="https://handyorg.github.io/handycontrol"> diff --git a/货架标准上位机/App.xaml.cs b/货架标准上位机/App.xaml.cs index e7a4e99..02490c8 100644 --- a/货架标准上位机/App.xaml.cs +++ b/货架标准上位机/App.xaml.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; +using System.Management.Instrumentation; using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; namespace 货架标准上位机 { @@ -13,5 +15,20 @@ namespace 货架标准上位机 /// public partial class App : Application { + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + if (LocalFile.Config.IsMx) + { + MainWindow = new MXMainWindow(); + } + else + { + MainWindow = new MainWindow1(); + } + MainWindow.ShowDialog(); + + } } } diff --git a/货架标准上位机/Excel/出库导入模板.xlsx b/货架标准上位机/Excel/出库导入模板.xlsx new file mode 100644 index 0000000..7ac38a0 Binary files /dev/null and b/货架标准上位机/Excel/出库导入模板.xlsx differ diff --git a/货架标准上位机/Fonts/iconfont.ttf b/货架标准上位机/Fonts/iconfont.ttf index c07f703..02b62ec 100644 Binary files a/货架标准上位机/Fonts/iconfont.ttf and b/货架标准上位机/Fonts/iconfont.ttf differ diff --git a/货架标准上位机/Models/JsConfig.cs b/货架标准上位机/Models/JsConfig.cs index ace3ee6..e13e763 100644 --- a/货架标准上位机/Models/JsConfig.cs +++ b/货架标准上位机/Models/JsConfig.cs @@ -19,6 +19,10 @@ namespace 货架标准上位机 /// 货架服务器的Ip和端口号 /// public string ApiIpHost { get; set; } + /// + /// WebSocket服务器的地址 + /// + public string WebSocketUrl { get; set; } public List GroupName { get; set; } @@ -41,6 +45,26 @@ namespace 货架标准上位机 /// 串口扫码枪延时 /// public int ScannerTimeOut { get; set; } + + #region 盟讯公司配置 + public bool IsMx { get; set; } + /// + ///MX-获取要料单接口地址 + /// + public string GetPickOrderUrl { get; set; } + /// + ///MX-获取要料明细接口地址 + /// + public string RecommendedBarCode { get; set; } + /// + ///MX-首盘发料明细接口地址 + /// + public string FirstSendRecommendedBarCode { get; set; } + /// + ///MX-后续发料明细接口地址 + /// + public string ElectronicSiloPush { get; set; } + #endregion } public class JsSysConfig diff --git a/货架标准上位机/Properties/PublishProfiles/FolderProfile.pubxml b/货架标准上位机/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 0000000..98ba478 --- /dev/null +++ b/货架标准上位机/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,13 @@ + + + + + Release + Any CPU + bin\Release\net472\publish\ + FileSystem + <_TargetId>Folder + + \ No newline at end of file diff --git a/货架标准上位机/Resources/扫码枪结束入库二维码.png b/货架标准上位机/Resources/goOutInstore.png similarity index 100% rename from 货架标准上位机/Resources/扫码枪结束入库二维码.png rename to 货架标准上位机/Resources/goOutInstore.png diff --git a/货架标准上位机/ScannerManager.cs b/货架标准上位机/ScannerManager.cs index c46ab88..3742621 100644 --- a/货架标准上位机/ScannerManager.cs +++ b/货架标准上位机/ScannerManager.cs @@ -71,6 +71,8 @@ namespace 货架标准上位机 /// 是否在入库模式中 /// public bool IsInstoreMode { get; set; } + + public DateTime IsInstoreModeTime { get; set; } = DateTime.MinValue; /// /// 串口号 /// diff --git a/货架标准上位机/ViewModels/DeviceViewModel.cs b/货架标准上位机/ViewModels/DeviceViewModel.cs index aa10160..f393f5c 100644 --- a/货架标准上位机/ViewModels/DeviceViewModel.cs +++ b/货架标准上位机/ViewModels/DeviceViewModel.cs @@ -9,531 +9,43 @@ using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using WCS.Model; +using WCS.Model.ApiModel.Home; +using 货架标准上位机.Api; namespace 货架标准上位机.ViewModel { public class DeviceViewModel : BindableBase { - //循环间隙时间 - int whileSleep = 1500; + public ICommand ResetAllShelfCommand { get => new DelegateCommand(ResetAllShelf); } /// - /// 是否繁忙。繁忙状态下不在进行定时刷新操作。 + /// 打开用户 /// - public bool IsBusy { get; set; } = false; - //public IIoTBase plc; - - #region 属性 - /// - /// 监听 - /// - public IEnumerable DataReads { get; set; } - /// - /// 控制 - /// - public IEnumerable DataWrites { get; set; } - /// - /// 气缸 - /// - public IEnumerable DataUrns { get; set; } - /// - /// 伺服 - /// - public IEnumerable DataServos { get; set; } - - private bool IsVis_ = false; - /// - /// 当前页面是否显示 - /// - public bool IsVis { get => IsVis_; set { SetProperty(ref IsVis_, value); } } - - #region 是否展示 - private bool IsVisRead_ = true; - public bool IsVisRead { get => IsVisRead_; set { SetProperty(ref IsVisRead_, value); } } - - private bool IsVisWrite_ = true; - public bool IsVisWrite { get => IsVisWrite_; set { SetProperty(ref IsVisWrite_, value); } } - - private bool IsVisUrn_ = true; - public bool IsVisUrn { get => IsVisUrn_; set { SetProperty(ref IsVisUrn_, value); } } - - private bool IsVisServo_ = true; - public bool IsVisServo { get => IsVisServo_; set { SetProperty(ref IsVisServo_, value); } } - #endregion - - #region 是否折叠 - private bool IsVisExpRead_ = true; - public bool IsVisExpRead { get => IsVisExpRead_; set { SetProperty(ref IsVisExpRead_, value); } } - - private bool IsVisExpWrite_ = true; - public bool IsVisExpWrite { get => IsVisExpWrite_; set { SetProperty(ref IsVisExpWrite_, value); } } - - private bool IsVisExpUrn_ = false; - public bool IsVisExpUrn { get => IsVisExpUrn_; set { SetProperty(ref IsVisExpUrn_, value); } } - - private bool IsVisExpServo_ = false; - public bool IsVisExpServo { get => IsVisExpServo_; set { SetProperty(ref IsVisExpServo_, value); } } - #endregion - - #endregion - - /// - /// 循环读取数据 - /// - public async void WhileRead() + public void ResetAllShelf() { - while (true) + #region 调用接口 请求重置所有货架的状态 + var body = new ResetShelfStatusRequest() { - try - { - if (!IsVis || IsBusy) - { - await Task.Delay(whileSleep); - continue; - } - - ////监控 - if (DataReads != null && IsVisExpRead) - { - foreach (var item in DataReads) - { - if (!item.IsExpanded) - continue; - - var plcAdd = item.ExcelTag; - if (string.IsNullOrWhiteSpace(plcAdd.地址)) - continue; - - var ts = plcAdd.类型.Trim().ToLower(); - switch (ts) - { - case "bool": - //var datab = plc?.Read(plcAdd.地址); - //item.Value = datab?.IsSucceed == true ? datab.Value : false; - break; - case "byte": - //var datay = plc?.Read(plcAdd.地址); - //item.Value = datay?.IsSucceed == true ? datay.Value : "-"; - break; - case "int16": - //var datai16 = plc?.Read(plcAdd.地址); - //item.Value = datai16?.IsSucceed == true ? datai16.Value : "-"; - break; - case "int32": - //var datai32 = plc?.Read(plcAdd.地址); - //item.Value = datai32?.IsSucceed == true ? datai32.Value : "-"; - break; - case "uint16": - //var dataui16 = plc?.Read(plcAdd.地址); - //item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-"; - break; - case "uint32": - //var dataui32 = plc?.Read(plcAdd.地址); - //item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-"; - break; - case "float": - case "single": - //var datas = plc?.Read(plcAdd.地址); - //item.Value = datas?.IsSucceed == true ? datas.Value : "-"; - break; - case "double": - //var datad = plc?.Read(plcAdd.地址); - //item.Value = datad?.IsSucceed == true ? datad.Value : "-"; - break; - default: - break; - } - } - } - - ////控制 - if (DataWrites != null && IsVisExpWrite) - { - foreach (var item in DataWrites) - { - if (!item.IsExpanded) - continue; - - var plcAdd = item.ExcelTag; - if (string.IsNullOrWhiteSpace(plcAdd.读地址)) - continue; - - var ts = plcAdd.类型.Trim().ToLower(); - switch (ts) - { - case "bool": - //var datab = plc?.Read(plcAdd.读地址); - //item.Value = datab?.IsSucceed == true ? datab.Value : false; - break; - case "byte": - //var datay = plc?.Read(plcAdd.读地址); - //item.Value = datay?.IsSucceed == true ? datay.Value : "-"; - break; - case "int16": - //var datai16 = plc?.Read(plcAdd.读地址); - //item.Value = datai16?.IsSucceed == true ? datai16.Value : "-"; - break; - case "int32": - //var datai32 = plc?.Read(plcAdd.读地址); - //item.Value = datai32?.IsSucceed == true ? datai32.Value : "-"; - break; - case "uint16": - //var dataui16 = plc?.Read(plcAdd.读地址); - //item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-"; - break; - case "uint32": - //var dataui32 = plc?.Read(plcAdd.读地址); - //item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-"; - break; - case "float": - case "single": - //var datas = plc?.Read(plcAdd.读地址); - //item.Value = datas?.IsSucceed == true ? datas.Value : "-"; - break; - case "double": - //var datad = plc?.Read(plcAdd.读地址); - //item.Value = datad?.IsSucceed == true ? datad.Value : "-"; - break; - default: - break; - } - } - } - - ////气缸 - if (DataUrns != null && IsVisExpUrn) - { - foreach (var item in DataUrns) - { - if (!item.IsExpanded) - continue; - - var plcAdd = item.ExcelTag; - if (!string.IsNullOrWhiteSpace(plcAdd.推到位地址)) - { - //var data1 = plc?.Read(plcAdd.推到位地址); - //item.IsGoTo = data1?.IsSucceed == true ? data1.Value : false; - } - if (!string.IsNullOrWhiteSpace(plcAdd.回到位地址)) - { - //var data2 = plc?.Read(plcAdd.回到位地址); - //item.IsRetTo = data2?.IsSucceed == true ? data2.Value : false; - } - } - } - - ////伺服 - if (DataServos != null && IsVisExpServo) - { - foreach (var item in DataServos) - { - if (!item.IsExpanded) - continue; - - ////读取地址信息 - var plcAdd = item.ExcelTag; - if (!string.IsNullOrWhiteSpace(plcAdd.当前位置获取)) - { - //var data1 = plc?.Read(plcAdd.当前位置获取); - //item.Location = data1?.IsSucceed == true ? data1.Value : 0; - } - if (!string.IsNullOrWhiteSpace(plcAdd.手动速度获取) && (item.IsJog || !item.IsFold)) - { - //var data2 = plc?.Read(plcAdd.手动速度获取); - //item.JogSpeed = data2?.IsSucceed == true ? data2.Value : 0; - } - if (!string.IsNullOrWhiteSpace(plcAdd.自动速度设置) && (!item.IsJog || !item.IsFold)) - { - //var data3 = plc?.Read(plcAdd.自动速度设置); - //item.AutoSpeed = data3?.IsSucceed == true ? data3.Value : 0; - } - } - } - - await Task.Delay(whileSleep); - } - catch (Exception) - { - - } + IsResetAll = true, + GroupNames = LocalFile.Config.GroupName, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "home/resetShelfStatus", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Warning("复位成功!"); } - } - - /*一起选中【操作控制】【操作气缸】【操作伺服】可以快速解开全部注释*/ - - #region 操作控制 - ////单击 - public void WriteClick(object sender, RoutedEventArgs e) - { - var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("切换")) + else if (Result != null) { - Task.Run(() => - { - var boolval = data.Value is true; - //plc?.Write(dataExcel.写地址, !boolval); - data.Value = !boolval; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); - }); + Growl.Warning(Result.Message); } else { - var ts = dataExcel.类型.Trim().ToLower(); - switch (ts) - { - case "byte": - WriteClickDialog(data); - break; - case "int16": - WriteClickDialog(data); - break; - case "int32": - WriteClickDialog(data); - break; - case "uint16": - WriteClickDialog(data); - break; - case "uint32": - WriteClickDialog(data); - break; - case "float": - case "single": - WriteClickDialog(data); - break; - case "double": - WriteClickDialog(data); - break; - default: - break; - } + Growl.Warning("调用接口失败!"); } + #endregion } - - ////单击弹框 - void WriteClickDialog(DeviceWriteModel data) where T : struct - { - var dataExcel = data.ExcelTag; - var val = TipInputView.Show($"请输入新的[{dataExcel.名称}]值:", "修改值", "请输入值"); - if (!val.HasValue) - return; - - //plc?.Write(dataExcel.写地址, val.Value); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = val.Value, Mode = "" }); - } - - ////按下左键 - public void LeftDown(object sender, MouseButtonEventArgs e) - { - var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.写地址, true); - data.Value = true; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); - }); - } - } - - ////放开左键 - public void LeftUp(object sender, MouseButtonEventArgs e) - { - var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.写地址, false); - data.Value = false; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); - }); - } - } - #endregion - - #region 操作气缸 - ////按钮1单击 - public void Button1_Click(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("切换")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, true); - //plc?.Write(dataExcel.回地址, false); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = true, Mode = mode }); - }); - } - } - - ////按钮1按下 - public void But1ClickDown(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, true); - data.IsGoTo = true; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = true, Mode = mode }); - }); - } - } - - ////按钮1松开 - public void But1ClickUp(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, false); - data.IsGoTo = false; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = false, Mode = mode }); - }); - } - } - - ////按钮2单击 - public void Button2_Click(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("切换")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, false); - //plc?.Write(dataExcel.回地址, true); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = true, Mode = mode }); - }); - } - } - - ////按钮2按下 - public void But2ClickDown(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.回地址, true); - data.IsRetTo = true; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = true, Mode = mode }); - }); - } - } - - ////按钮2松开 - public void But2ClickUp(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.回地址, false); - data.IsRetTo = false; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = false, Mode = mode }); - }); - } - } - #endregion - - #region 操作伺服 - ////尝试改变伺服的位置时 - public void LocationChange(object sender, RoutedEventArgs e) - { - var data = (DeviceServoModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = string.Empty; - - ////运动方式 - if (e.OriginalSource is ServoClickType servoClickType) - { - if (servoClickType == ServoClickType.StartDotAdd) - { - //plc?.Write(dataExcel.位置点动加, true); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "开始点动加", Val = true, Mode = mode }); - } - else if (servoClickType == ServoClickType.EndDotAdd) - { - //plc?.Write(dataExcel.位置点动加, false); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "结束点动加", Val = false, Mode = mode }); - } - else if (servoClickType == ServoClickType.StartDotSub) - { - //plc?.Write(dataExcel.位置点动减, true); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "开始点动减", Val = true, Mode = mode }); - } - else if (servoClickType == ServoClickType.EndDotSub) - { - //plc?.Write(dataExcel.位置点动减, false); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "结束点动减", Val = false, Mode = mode }); - } - } - ////运动到指定位置 - else if (e.OriginalSource is double val) - { - //plc?.Write(dataExcel.位置移动, Convert.ToSingle(val)); - data.Location = val; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "位置移动", Val = val, Mode = mode }); - } - } - - ////尝试改变伺服的速度时 - public void SpeedChange(object sender, RoutedEventArgs e) - { - var data = (DeviceServoModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = string.Empty; - - var data2 = (ServoSpeed)e.OriginalSource; - if (data2.Name.StartsWith("手动")) - { - //plc?.Write(dataExcel.手动速度设置, Convert.ToSingle(data2.Speed)); - data.JogSpeed = data2.Speed; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "手动速度设置", Val = data2.Speed, Mode = mode }); - } - else - { - //plc?.Write(dataExcel.自动速度设置, Convert.ToSingle(data2.Speed)); - data.AutoSpeed = data2.Speed; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "自动速度设置", Val = data2.Speed, Mode = mode }); - - } - } - #endregion } public class DeviceReadModel : BindableBase diff --git a/货架标准上位机/ViewModels/HomeViewModel.cs b/货架标准上位机/ViewModels/HomeViewModel.cs index f8b90ea..bf92eef 100644 --- a/货架标准上位机/ViewModels/HomeViewModel.cs +++ b/货架标准上位机/ViewModels/HomeViewModel.cs @@ -14,6 +14,9 @@ using HandyControl.Tools.Extension; using 货架标准上位机.Views.Controls; using 货架标准上位机.Api; using WCS.Model; +using System.Diagnostics; +using System.Security.Cryptography; +using WCS.Model.ApiModel.Home; namespace 货架标准上位机.ViewModel { @@ -21,6 +24,27 @@ namespace 货架标准上位机.ViewModel { WarnInfoContainer WarnInfo = new WarnInfoContainer();//警告、错误等信息 + public bool IsThisPageVisible = true; + + public HomeViewModel() + { + Task.Run(() => + { + while (true) + { + if (IsThisPageVisible) + { + RefreshUserControl(); + } + Thread.Sleep(2000); + } + }); + + #region 启动自检 + SelfCheck(); + #endregion + } + #region 绑定 private string textErr; /// @@ -44,40 +68,79 @@ namespace 货架标准上位机.ViewModel WarnInfo.RemoveAll(WarnInfoType.AlwayWarn); } - public ICommand AddUserControlCommand { get => new DelegateCommand(AddUserControl); } public WrapPanel wrapPanel; - public async void AddUserControl() + public async void RefreshUserControl() { //var dia = Dialog.Show(new TextDialog()); - //try - //{ - // var body = new GetShelfStatusRequest() - // { - // UserName = "xxx", - // DeviceType = "WCS前端", - // GroupNames = LocalFile.Config.GroupName, + try + { + var body = new GetShelfStatusRequest() + { + UserName = LocalStatic.CurrentUser, + DeviceType = "WCS前端", + GroupNames = LocalFile.Config.GroupName, + }; + var Result = await ApiHelp.Post([LocalFile.Config.ApiIpHost, "home/getShelfStatus"], body); + if (Result != null && Result.Data?.Count > 0) + { + App.Current.Dispatcher.Invoke(() => + { + wrapPanel.Children.Clear(); + Result.Data + .ForEach(t => + { + var shelf = new ShelfStatusControl(t.ShelfCode, t.CurentMode, ""); + wrapPanel.Children.Add(shelf); + }); + }); + } + } + catch (Exception ex) + { - // }; - // var Result = await ApiHelp.Post([LocalFile.Config.ApiIpHost, "home/getShelfStatus"], body); - // if (Result != null && Result.Data?.Count > 0) - // { - // wrapPanel.Children.Clear(); - // Result.Data.ForEach(t => - // { - // var shelf = new ShelfStatusControl(t.ShelfCode, t.CurentMode, t.GroupName); - // wrapPanel.Children.Add(shelf); - // }); - // } - //} - //catch (Exception ex) - //{ + } + finally + { - //} - //finally - //{ - // //dia.Close(); - //} - } + } + } + + public ICommand SelfCheckCommand { get => new DelegateCommand(SelfCheck); } + public void SelfCheck() + { + #region 调用接口请求后台进行自检 + lock (this) + { + try + { + var body = new GetShelfStatusRequest() + { + UserName = LocalStatic.CurrentUser, + DeviceType = "WCS前端", + GroupNames = LocalFile.Config.GroupName, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "home/shelfCheckAll", body, "POST",true); + if (Result != null && Result.Code == 200) + { + + } + else + { + + } + Thread.Sleep(20); + } + catch (Exception ex) + { + + } + finally + { + + } + } + #endregion + } #endregion #region 页面加载时任务 diff --git a/货架标准上位机/ViewModels/InInventoryViewModel.cs b/货架标准上位机/ViewModels/InInventoryViewModel.cs index 09ac937..a428ee5 100644 --- a/货架标准上位机/ViewModels/InInventoryViewModel.cs +++ b/货架标准上位机/ViewModels/InInventoryViewModel.cs @@ -28,6 +28,7 @@ using System.Collections.ObjectModel; using WCS.BLL.DbModels; using WCS.Model.ApiModel.MatBaseInfo; using System.Security.Cryptography; +using Ping9719.WpfEx; namespace 货架标准上位机.ViewModel { @@ -148,6 +149,7 @@ namespace 货架标准上位机.ViewModel if (Result != null && Result.Code == 200) { Logs.Write($"货架{scanner.ShelfCode}已成功退出入库!", LogsType.Scanner); + scanner.IsInstoreMode = false; scanner.ShelfCode = string.Empty; scanner.ModulesStr = string.Empty; } @@ -182,6 +184,7 @@ namespace 货架标准上位机.ViewModel { Logs.Write($"扫码模组{scanner.TempCode},进入入库模式成功!", LogsType.Scanner); scanner.IsInstoreMode = true; + scanner.IsInstoreModeTime = DateTime.Now; scanner.ShelfCode = Result.Data.ShelfCode; scanner.ModulesStr = Result.Data.ModulesStr; @@ -228,9 +231,9 @@ namespace 货架标准上位机.ViewModel var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "instore/shelfGoOutInStore", body, "POST"); if (Result != null && Result.Code == 200) { + scanner.IsInstoreMode = false; scanner.ShelfCode = string.Empty; scanner.ModulesStr = string.Empty; - } } catch (Exception ex) @@ -259,6 +262,33 @@ namespace 货架标准上位机.ViewModel if (Result != null && Result.Code == 200) { scanner.MatSn = Result.Data.MatSN; + #region 调用接口获取入库状态 + Task.Run(() => + { + try + { + var body = new QueryByMatSnRequest() + { + MatSn = scanner.MatSn, + ShelfCode = scanner.ShelfCode, + IpAddress = scanner.COM, + DeviceType = LocalFile.Config.DeviceType, + UserName = LocalStatic.CurrentUser, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "instore/queryInstoreStatus", body, "POST"); + if (Result != null && !string.IsNullOrEmpty(Result.Message)) + { + TextBoxLog.AddLog($"物料[{scanner.MatSn}]" + Result.Message, "InstoreLog", DateTime.Now); + scanner.MatSn = string.Empty; + scanner.ScannerDisplayControl.RefreshValues(scanner.ShelfCode, scanner.MatSn); + } + } + catch (Exception ex) + { + Growl.Warning(ex.Message); + } + }); + #endregion } else if (Result != null && !string.IsNullOrEmpty(Result.Message)) { diff --git a/货架标准上位机/ViewModels/MXViewModel/MXOutInventoryViewModel.cs b/货架标准上位机/ViewModels/MXViewModel/MXOutInventoryViewModel.cs new file mode 100644 index 0000000..568cf3b --- /dev/null +++ b/货架标准上位机/ViewModels/MXViewModel/MXOutInventoryViewModel.cs @@ -0,0 +1,311 @@ +using HandyControl.Controls; +using HandyControl.Data; +using MiniExcelLibs; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.SqlClient; +using System.IO; +using System.Linq; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Web.UI.WebControls; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using TouchSocket.Core; +using WCS.Model; +using WCS.Model.ApiModel.OutStore; +using WCS.Model.ApiModel.Stocktaking; +using 货架标准上位机.Api; +using 货架标准上位机.ViewModel; + +namespace 货架标准上位机.ViewModel +{ + public class MXOutInventoryViewModel : BindableBase + { + public MXOutInventoryViewModel() + { + RefreshOutOrderList(); + } + + #region Property + private OutOrderModel selectedOutOrder; + public OutOrderModel SelectedOutOrder + { + get { return selectedOutOrder; } + set + { + SetProperty(ref selectedOutOrder, value); + if (selectedOutOrder != null) + { + SelectedOutOrderNumber = selectedOutOrder.OrderNumber; + RefreshDataGridItemSource(); + } + else + { + DataGridItemSource?.Clear(); + } + } + } + + private string selectedOutOrderNumber; + public string SelectedOutOrderNumber + { + get => selectedOutOrderNumber; + set + { + SetProperty(ref selectedOutOrderNumber, value); + } + } + + + private ObservableCollection outOrderList; + public ObservableCollection OutOrderList + { + get => outOrderList; + set + { + SetProperty(ref outOrderList, value); + } + } + + private ObservableCollection dataGridItemSource; + public ObservableCollection DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + RefreshCount(); + } + } + + //单据总盘数 + private int totalPan; + public int TotalPan + { + get => totalPan; set + { + SetProperty(ref totalPan, value); + } + } + + private int sendedPan; + public int SendedPan + { + get => sendedPan; set + { + SetProperty(ref sendedPan, value); + } + } + + private string orderStatus; + public string OrderStatus + { + get { return orderStatus; } + set + { + SetProperty(ref orderStatus, value); + } + } + + public void RefreshCount() + { + Task.Run(() => + { + SendedPan = dataGridItemSource.Where(t => t.IsSended).Count(); + TotalPan = dataGridItemSource.Count(); + }); + } + #endregion + + #region Command + public ICommand BtnOutOrderCommand { get => new DelegateCommand(BtnOutOrder); } + public void BtnOutOrder() + { + var window = new MXOutOrderView(); + window.Owner = Application.Current.MainWindow; + window.ShowDialog(); + } + + + public ICommand BtnStartCommand { get => new DelegateCommand(BtnStart); } + public void BtnStart() + { + try + { + //判断是否选择单据 + if (SelectedOutOrder == null) + { + Growl.Warning("未选择单据!"); + return; + } + + #region 调用接口开始出库 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outStore/goInOutstore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Warning("已成功开始出库!"); + RefreshOutOrderList(SelectedOutOrderNumber); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + public ICommand BtnPauseCommand { get => new DelegateCommand(BtnPause); } + public void BtnPause() + { + try + { + //判断是否选择单据 + if (SelectedOutOrder == null) + { + Growl.Warning("未选择单据!"); + return; + } + #region 调用接口结束出库 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outStore/goOutOutstore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Warning("已成功结束出库!"); + RefreshOutOrderList(SelectedOutOrderNumber); + //RefreshDataGridItemSource(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + public void RefreshOutOrderList(string OrderNumber = "") + { + #region 调用接口获取发料单 + try + { + var body = new GetOutOrderListByStatusRequest() + { + IsMXPD = false, + OrderExeStatus = new List() { OutOrderExeStatus.开始发料, OutOrderExeStatus.发料完成 } + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "outstore/getOutOrderListByStatus", body, "POST"); + if (Result != null && Result.Code == 200) + { + OutOrderList = new ObservableCollection(Result.Data.Lists); + if (!string.IsNullOrEmpty(OrderNumber)) + { + SelectedOutOrder = OutOrderList.Where(t => t.OrderNumber == OrderNumber).FirstOrDefault(); + } + } + else if (Result != null && !string.IsNullOrEmpty(Result.Message)) + { + Growl.Warning(Result.Message); + } + } + catch (Exception ex) + { + Growl.Warning(ex.Message); + } + #endregion + } + + public void RefreshDataGridItemSource() + { + if (SelectedOutOrder == null) + { + //选择的单据为空无法进行查询 + return; + } + #region 调用接口获取出库单物料明细 + Task.Run(() => + { + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + + }; + var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "outStore/getOutOrderMatDetail", body, "POST"); + if (Result != null && Result.Code == 200) + { + if (Result.Data.Count > 0) + { + DataGridItemSource = new ObservableCollection(Result.Data); + OrderStatus = Result.Message; + if (OrderStatus == OutOrderStatus.全部发料.ToString()) + { + //全部发料就默认所有货架结束了这个单子 + } + } + else + { + App.Current.Dispatcher.Invoke(() => + { + DataGridItemSource?.Clear(); + }); + Growl.Warning("该单据未查询到发料明细!"); + } + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + }); + #endregion + } + #endregion + } +} diff --git a/货架标准上位机/ViewModels/MXViewModel/MXOutOrderDetailViewViewModel.cs b/货架标准上位机/ViewModels/MXViewModel/MXOutOrderDetailViewViewModel.cs new file mode 100644 index 0000000..c32319a --- /dev/null +++ b/货架标准上位机/ViewModels/MXViewModel/MXOutOrderDetailViewViewModel.cs @@ -0,0 +1,216 @@ +using HandyControl.Controls; +using HandyControl.Data; +using MiniExcelLibs; +using Newtonsoft.Json; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Input; +using TouchSocket.Core; +using System.Windows.Markup; +using System.Security.Policy; +using WCS.Model.ApiModel.MXBackgroundThread; +using 货架标准上位机; +using WCS.Model.ApiModel.MatInventoryDetail; +using 货架标准上位机.Api; +using System.Runtime.CompilerServices; +using WCS.Model; + +namespace 货架标准上位机.ViewModel +{ + public class MXOutOrderDetailViewViewModel : BindableBase + { + /// + /// + /// + /// + /// + /// + /// + /// 是否是首盘发料 + public MXOutOrderDetailViewViewModel( + string billNumber, string warehouseCode + , string orderProdNumbers, string orderWorkNumbers + , int isFirstSend = 0, string reportSide = null + ) + { + BillNumber = billNumber; + OrderProdNumbers = orderProdNumbers; + OrderWorkNumbers = orderWorkNumbers; + WarehouseCode = warehouseCode; + + Task.Run(() => + { + var request = new RecommendedBarCodeRequest() + { + pickBillNumber = billNumber, + warehouseCode = warehouseCode, + warehouseType = 20 + }; + var requeststr = JsonConvert.SerializeObject(request); + var url = string.Empty; + if (isFirstSend == 0) + { + url = LocalFile.Config.RecommendedBarCode; + } + else if (isFirstSend == 1) + { + request = new FistPushRecommendedBarCodeRequest() + { + pickBillNumber = billNumber, + warehouseCode = warehouseCode, + warehouseType = 20, + reportSide = reportSide, + }; + requeststr = JsonConvert.SerializeObject(request); + url = LocalFile.Config.FirstSendRecommendedBarCode; + } + //后续料 + else + { + url = LocalFile.Config.ElectronicSiloPush; + } + + var result = ApiHelp.MXGetDataFromHttp>(requeststr, url, "POST", true); + if (result != null && result.code == 200 && result.data != null && result.data.Count() > 0) + { + //获取推荐的条码 + var matSns = result.data.Select(t => t.materialBar).ToList(); + + //调用 比对库存数据 获取库存中有的数据 + #region 调用接口 比对库存数据 获取库存中有的数据 + try + { + var body = new CompareMatInventoryDetailRequest() + { + MatSns = matSns, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "matInventoryDetail/compareMatInventoryDetail", body, "POST", true); + + //查询到物料信息 + if (Result != null && Result.Data != null && Result.Data.Lists != null && Result.Data.Lists.Count != 0) + { + DataGridItemSource = Result.Data.Lists; + } + else if (Result != null && Result.Code == 200 && (Result.Data == null || Result.Data.Lists == null || Result.Data.Lists.Count == 0)) + { + MessageBox.Show($"未查询到领料明细!所推荐物料在此货架上不存在,请确认是否在其他货架上!\r\n{string.Join(",\r\n", matSns)}"); + DataGridItemSource = null; + } + else + { + MessageBox.Show($"未查询到领料明细!请重试!"); + DataGridItemSource = null; + } + } + catch (Exception e) + { + MessageBox.Show($"未查询到领料明细!请重试!"); + DataGridItemSource = null; + } + #endregion + } + else if (result != null && result.code == 200 && (result.data == null || result.data.Count == 0)) + { + Growl.Warning("未查询到物料明细!MES推荐物料明细为空!"); + DataGridItemSource = null; + } + else + { + Growl.Warning("未查询到领料明细!请求MES接口失败!"); + DataGridItemSource = null; + } + }); + } + + + #region Property + private int selectedCount; + public int SelectedCount + { + get { return selectedCount; } + set { SetProperty(ref selectedCount, value); } + } + + private int selectedPan; + public int SelectedPan + { + get { return selectedPan; } + set { SetProperty(ref selectedPan, value); } + } + //发料单号 + private string billNumber; + public string BillNumber + { + get { return billNumber; } + set { SetProperty(ref billNumber, value); } + } + + //订单号 + private string orderProdNumbers; + public string OrderProdNumbers + { + get { return orderProdNumbers; } + set { SetProperty(ref orderProdNumbers, value); } + } + + //工单号 + private string orderWorkNumbers; + public string OrderWorkNumbers + { + get { return orderWorkNumbers; } + set { SetProperty(ref orderWorkNumbers, value); } + } + + //输入的仓库代码 + private string warehouseCode; + public string WarehouseCode + { + get { return warehouseCode; } + set + { + SetProperty(ref warehouseCode, value); + } + } + + private List dataGridItemSource; + public List DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + RefreshCount(); + } + } + + + public void RefreshCount() + { + Task.Run(() => + { + try + { + SelectedCount = dataGridItemSource.Where(t => t.IsSelected == true).Sum(t => t.MatQty); + SelectedPan = dataGridItemSource.Where(t => t.IsSelected == true).Count(); + } + catch { } + + }); + } + + #endregion + + #region Command + + #endregion + } +} diff --git a/货架标准上位机/ViewModels/MXViewModel/MXOutOrderViewModel.cs b/货架标准上位机/ViewModels/MXViewModel/MXOutOrderViewModel.cs new file mode 100644 index 0000000..f592f81 --- /dev/null +++ b/货架标准上位机/ViewModels/MXViewModel/MXOutOrderViewModel.cs @@ -0,0 +1,132 @@ +using HandyControl.Controls; +using HandyControl.Data; +using MiniExcelLibs; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Controls; +using System.Windows.Input; +using TouchSocket.Core; +using Newtonsoft.Json; +using WCS.Model.ApiModel.MXBackgroundThread; +using 货架标准上位机.Api; + +namespace 货架标准上位机.ViewModel +{ + public class MXOutOrderViewModel : BindableBase + { + public MXOutOrderViewModel() + { + } + + + #region Property + private string matCode1; + public string MatCode1 + { + get { return matCode1; } + set + { + SetProperty(ref matCode1, value); + } + } + + private string orderProdNumber; + public string OrderProdNumber + { + get { return orderProdNumber; } + set + { + SetProperty(ref orderProdNumber, value); + } + } + + private string orderWorkNumber; + public string OrderWorkNumber + { + get { return orderWorkNumber; } + set + { + SetProperty(ref orderWorkNumber, value); + } + } + + private string pickBillNumber; + public string PickBillNumber + { + get { return pickBillNumber; } + set + { + SetProperty(ref pickBillNumber, value); + } + } + + private string warehouseCode; + public string WarehouseCode + { + get { return warehouseCode; } + set + { + SetProperty(ref warehouseCode, value); + } + } + + + + private List dataGridItemSource; + public List DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + } + } + + + + + #endregion + + #region Command + public ICommand BtnSearchCommand { get => new DelegateCommand(BtnSearch); } + public void BtnSearch() + { + Task.Run(() => + { + var request = new PickOrderRequest() + { + orderProdNumber = OrderProdNumber, + orderWorkNumber = OrderWorkNumber, + pickBillNumber = PickBillNumber + }; + var requeststr = JsonConvert.SerializeObject(request); + var result = ApiHelp.MXGetDataFromHttpLongWait>(requeststr, LocalFile.Config.GetPickOrderUrl, "POST"); + if (result != null && result.code == 200 && result.data != null && result.data.Count() > 0) + { + DataGridItemSource = result.data; + } + else if (result != null && result.code == 200 && (result.data == null || result.data.Count == 0)) + { + result.message = "输入的搜索条件未查询到发料单信息!"; + Growl.Warning(result.message); + DataGridItemSource = result.data; + } + else + { + Growl.Warning("调用MES接口超时:搜索失败!"); + } + }); + } + #endregion + + + } +} diff --git a/货架标准上位机/ViewModels/MXViewModel/MXPDViewModel.cs b/货架标准上位机/ViewModels/MXViewModel/MXPDViewModel.cs new file mode 100644 index 0000000..c98af57 --- /dev/null +++ b/货架标准上位机/ViewModels/MXViewModel/MXPDViewModel.cs @@ -0,0 +1,429 @@ +using HandyControl.Controls; +using HandyControl.Data; +using MiniExcelLibs; +using Newtonsoft.Json; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.SqlClient; +using System.IO; +using System.Linq; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Web.UI.WebControls; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using TouchSocket.Core; +using WCS.Model; +using WCS.Model.ApiModel.MatInventoryDetail; +using WCS.Model.ApiModel.MXBackgroundThread; +using WCS.Model.ApiModel.OutStore; +using WCS.Model.ApiModel.Stocktaking; +using 货架标准上位机.Api; +using 货架标准上位机.ViewModel; + +namespace 货架标准上位机.ViewModel +{ + public class MXPDViewModel : BindableBase + { + public MXPDViewModel() + { + RefreshOutOrderList(); + } + + #region Property + private OutOrderModel selectedOutOrder; + public OutOrderModel SelectedOutOrder + { + get { return selectedOutOrder; } + set + { + SetProperty(ref selectedOutOrder, value); + if (selectedOutOrder != null) + { + SelectedOutOrderNumber = selectedOutOrder.OrderNumber; + RefreshDataGridItemSource(); + } + else + { + DataGridItemSource?.Clear(); + } + } + } + + private string selectedOutOrderNumber; + public string SelectedOutOrderNumber + { + get => selectedOutOrderNumber; + set + { + SetProperty(ref selectedOutOrderNumber, value); + } + } + + + private ObservableCollection outOrderList; + public ObservableCollection OutOrderList + { + get => outOrderList; + set + { + SetProperty(ref outOrderList, value); + } + } + + private ObservableCollection dataGridItemSource; + public ObservableCollection DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + RefreshCount(); + } + } + + //单据总盘数 + private int totalPan; + public int TotalPan + { + get => totalPan; set + { + SetProperty(ref totalPan, value); + } + } + + private int sendedPan; + public int SendedPan + { + get => sendedPan; set + { + SetProperty(ref sendedPan, value); + } + } + + private int totalCount; + public int TotalCount + { + get => totalCount; + set { SetProperty(ref totalCount, value); } + } + + + private string orderStatus; + public string OrderStatus + { + get { return orderStatus; } + set + { + SetProperty(ref orderStatus, value); + } + } + + public void RefreshCount() + { + Task.Run(() => + { + SendedPan = dataGridItemSource.Where(t => t.IsSended).Count(); + TotalPan = dataGridItemSource.Count(); + TotalCount = dataGridItemSource.Sum(t => t.MatQty); + }); + } + + + private string matCode; + public string MatCode + { + get => matCode; + set { SetProperty(ref matCode, value); } + } + + private string wareHouseCode; + public string WareHouseCode + { + get => wareHouseCode; + set { SetProperty(ref wareHouseCode, value); } + } + #endregion + + #region Command + public ICommand BtnOutOrderCommand { get => new DelegateCommand(BtnOutOrder); } + public void BtnOutOrder() + { + var window = new MXOutOrderView(); + window.Owner = Application.Current.MainWindow; + window.ShowDialog(); + } + + + public ICommand BtnStartCommand { get => new DelegateCommand(BtnStart); } + public void BtnStart() + { + try + { + //判断是否选择单据 + if (SelectedOutOrder == null) + { + Growl.Warning("未选择单据!"); + return; + } + + #region 调用接口开始出库 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outStore/goInOutstore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Warning("已成功开始出库!"); + RefreshDataGridItemSource(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + public ICommand BtnPauseCommand { get => new DelegateCommand(BtnPause); } + public void BtnPause() + { + try + { + //判断是否选择单据 + if (SelectedOutOrder == null) + { + Growl.Warning("未选择单据!"); + return; + } + #region 调用接口结束出库 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outStore/goOutOutstore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Warning("已成功结束盘点!"); + RefreshDataGridItemSource(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + public ICommand BtnQueryCommand { get => new DelegateCommand(BtnQuery); } + public void BtnQuery() + { + try + { + //请求WMS获取物料明细 + var request = new ElectronicSiloPushRequest() + { + materialCode = MatCode, + warehouseCode = WareHouseCode + }; + var requeststr = JsonConvert.SerializeObject(request); + var result = ApiHelp.MXGetDataFromHttp>(requeststr, "http://192.168.2.23:9213/integrate/inOut/electronicSiloPush", "POST", true); + if (result != null && (result.code == 200) && result.data != null && result.data.Count() > 0) + { + //通过返回的物料明细查询当前库存中有的数据 + var matSns = result.data.Select(t => t.materialBar).ToList(); + //调用 比对库存数据 获取库存中有的数据 + #region 调用接口 比对库存数据 获取库存中有的数据 + try + { + var body = new CompareMatInventoryDetailRequest() + { + MatSns = matSns, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "matInventoryDetail/compareMatInventoryDetail", body, "POST", true); + + //查询到物料信息 + if (Result != null && Result.Data != null && Result.Data.Lists != null && Result.Data.Lists.Count != 0) + { + var count = Result.Data.Lists.Count; + //是否生成盘点单 实际上是出库单 + var dialogResult = HandyControl.Controls.MessageBox.Show($"共查询到有{count}盘物料,是否生成盘点单?", "提示", MessageBoxButton.YesNo); + if (dialogResult == MessageBoxResult.Yes) + { + #region 调用接口保存出库单据 + var body1 = new SysOutOrderByMatSnRequest() + { + IsMXPD = true, + OrderType = "出库", + OrderSource = "WCS前端", + SnList = Result.Data.Lists.Select(t => t.MatSN).ToList(), + DeviceType = LocalFile.Config.DeviceType, + UserName = LocalStatic.CurrentUser + }; + var Result1 = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outstore/sysOutOrderByMatSn", body1, "POST"); + if (Result1 != null && Result1.Code == 200) + { + //出库单据保存成功 刷新左侧出库单列表 + MXPDView.viewModel.RefreshOutOrderList(Result1.Message.ToString()); + Growl.Success("盘点单据保存成功,请点击【开始盘点】进行盘点下架!"); + } + else if (Result1 != null) + { + Growl.Warning(Result1.Message); + } + #endregion + } + else + return; + } + else if (Result != null && Result.Code == 200 && (Result.Data == null || Result.Data.Lists == null || Result.Data.Lists.Count == 0)) + { + HandyControl.Controls.MessageBox.Show($"未查询到需要盘点的明细!所推荐物料在此货架上不存在,请确认是否在其他货架上!\r\n{string.Join(",\r\n", matSns)}"); + DataGridItemSource = null; + } + else + { + HandyControl.Controls.MessageBox.Show($"未查询到需要盘点的明细!请重试!"); + DataGridItemSource = null; + } + } + catch (Exception e) + { + HandyControl.Controls.MessageBox.Show($"未查询到需要盘点的明细!请重试!"); + DataGridItemSource = null; + } + #endregion + } + else + { + Growl.Warning("获取WMS系统库存数据失败!" + result?.message); + } + + } + catch (Exception ex) + { + + } + finally + { + //dia.Close(); + //dia.Collapse(); + } + } + + public void RefreshOutOrderList(string OrderNumber = "") + { + #region 调用接口获取发料单 + try + { + var body = new GetOutOrderListByStatusRequest() + { + OrderExeStatus = new List() { OutOrderExeStatus.开始发料, OutOrderExeStatus.发料完成 }, + IsMXPD = true, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "outstore/getOutOrderListByStatus", body, "POST"); + if (Result != null && Result.Code == 200) + { + OutOrderList = new ObservableCollection(Result.Data.Lists); + if (!string.IsNullOrEmpty(OrderNumber)) + { + SelectedOutOrder = OutOrderList.Where(t => t.OrderNumber == OrderNumber).FirstOrDefault(); + } + } + else if (Result != null && !string.IsNullOrEmpty(Result.Message)) + { + Growl.Warning(Result.Message); + } + } + catch (Exception ex) + { + Growl.Warning(ex.Message); + } + #endregion + } + + public void RefreshDataGridItemSource() + { + if (SelectedOutOrder == null) + { + //选择的单据为空无法进行查询 + return; + } + #region 调用接口获取出库单物料明细 + Task.Run(() => + { + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + + }; + var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "outStore/getOutOrderMatDetail", body, "POST"); + if (Result != null && Result.Code == 200) + { + if (Result.Data.Count > 0) + { + DataGridItemSource = new ObservableCollection(Result.Data); + OrderStatus = Result.Message; + } + else + { + App.Current.Dispatcher.Invoke(() => + { + DataGridItemSource?.Clear(); + }); + Growl.Warning("该单据未查询到发料明细!"); + } + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + }); + #endregion + } + #endregion + } +} diff --git a/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs b/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs index ee7e65b..678b775 100644 --- a/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs +++ b/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs @@ -227,18 +227,6 @@ namespace 货架标准上位机.ViewModel //已经选择文件 调用接口进行导入数据 string path = ofd.FileName; - var body = new GetMatBaseInfoRequest() - { - MatCode = MatCode, - MatName = MatName, - MatSpec = MatSpec, - IsEnable = IsEnable, - - UserName = LocalStatic.CurrentUser, - DeviceType = LocalFile.Config.DeviceType, - PageNumber = CurrentPage, - PageSize = 65535, - }; var result = await ApiHelp.PostImportFileAsync>>(path, System.Net.Http.HttpMethod.Post, LocalFile.Config.ApiIpHost + "matBaseInfo/importMatBaseInfo", LocalStatic.CurrentUser, LocalFile.Config.DeviceType); if (result.Code == 200) diff --git a/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs b/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs index f53dcd9..1cfa65e 100644 --- a/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs +++ b/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs @@ -33,14 +33,7 @@ namespace 货架标准上位机.ViewModel { public MatInventoryDetailViewModel() { - //获取物料编码列表 - //matCodes = DbHelp.db.Queryable() - // .Select(t => new DataModel() - // { - // MatCode = t.MatCode - // }) - // .Distinct() - // .ToList(); + } public void InitMatCode() diff --git a/货架标准上位机/ViewModels/ModuleInfoViewModel.cs b/货架标准上位机/ViewModels/ModuleInfoViewModel.cs index 6476799..b5fde19 100644 --- a/货架标准上位机/ViewModels/ModuleInfoViewModel.cs +++ b/货架标准上位机/ViewModels/ModuleInfoViewModel.cs @@ -19,6 +19,7 @@ using WCS.Model.ApiModel.MatBaseInfo; using WCS.Model.ApiModel.User; using WCS.Model.ApiModel; using Newtonsoft.Json.Bson; +using System.Windows; namespace 货架标准上位机.ViewModel { @@ -75,7 +76,7 @@ namespace 货架标准上位机.ViewModel public ICommand BtnResetCommand { get => new DelegateCommand(BtnReset); } public void BtnReset() { - ModuleCode = string.Empty; + ModuleCode = string.Empty; ShelfCode = string.Empty; } @@ -96,9 +97,10 @@ namespace 货架标准上位机.ViewModel var dia = Dialog.Show(new TextDialog()); try { - var body = new GetShelvesRequest() + var body = new GetModulesRequest() { ShelfCode = ShelfCode, + ModuleCode = ModuleCode, UserName = LocalStatic.CurrentUser, DeviceType = LocalFile.Config.DeviceType, PageNumber = CurrentPage, @@ -153,6 +155,97 @@ namespace 货架标准上位机.ViewModel } } } + + public ICommand DisableCommand { get => new DelegateCommand(Disable); } + public void Disable(ModuleInfoModel module) + { + if (module.IsEnable != true) + { + Growl.Warning("库位未被启用!"); + return; + } + var result = HandyControl.Controls.MessageBox.Show("模组禁用会影响正常流程,请确认是否屏蔽?" + , "提示", MessageBoxButton.YesNo); + if (result == MessageBoxResult.Yes) + { + #region 调用接口 禁用 + try + { + var body = new DisableOrEnableModuleRequest() + { + ModuleId = module.Id, + ModuleCode = module.ModuleCode, + DisableOrEnable = DisableOrEnableEnum.Disable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableModule", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("禁用成功"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } + else + { + return; + } + } + + public ICommand EnableCommand { get => new DelegateCommand(Enable); } + public void Enable(ModuleInfoModel module) + { + if (module.IsEnable == true) + { + Growl.Warning("库位未被禁用!"); + return; + } + #region 调用接口 临时禁用库位 删除库存数据 + try + { + var body = new DisableOrEnableModuleRequest() + { + ModuleId = module.Id, + ModuleCode = module.ModuleCode, + DisableOrEnable = DisableOrEnableEnum.Enable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableModule", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("操作成功!"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } #endregion #region PageOperation 分页操作 diff --git a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs index 53051e8..66ad7fa 100644 --- a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using WCS.BLL.DbModels; using WCS.Model; +using WCS.Model.ApiModel.Home; using WCS.Model.ApiModel.MatInventoryDetail; using 货架标准上位机.Api; @@ -35,6 +37,71 @@ namespace 货架标准上位机.ViewModels SetProperty(ref selectedItemSource, value); } } + + private List shelfTypeItems; + public List ShelfTypeItems + { + get { return shelfTypeItems; } + set + { + SetProperty(ref shelfTypeItems, value); + } + } + public void InitShelfTypeItems() + { + //调用接口更新! + Task.Run(() => + { + var body = new RequestBase() + { + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "home/getShelfTypes", body, "POST"); + if (Result != null && Result.Data != null && Result.Data.Lists.Count() > 0) + { + ShelfTypeItems = Result.Data.Lists; + SelectedShelfTypeItem = Result.Data.Lists.First(); + } + }); + } + + private ShelfTypeModel selectedShelfTypeItem; + public ShelfTypeModel SelectedShelfTypeItem + { + get { return selectedShelfTypeItem; } + set + { + SetProperty(ref selectedShelfTypeItem, value); + } + } + + private int selectedTypeCount = 0; + public int SelectedTypeCount + { + get => selectedTypeCount; + set + { + SetProperty(ref selectedTypeCount, value); + if (selectedTypeCount == 0) + { + ShelfTypeIsEnabled = true; + } + else + { + ShelfTypeIsEnabled = false; + } + } + } + + private bool shelfTypeIsEnabled = true; + public bool ShelfTypeIsEnabled + { + get => shelfTypeIsEnabled; set { SetProperty(ref shelfTypeIsEnabled, value); } + } + + #endregion #region Command @@ -44,7 +111,11 @@ namespace 货架标准上位机.ViewModels public ICommand BtnAddCommand { get => new DelegateCommand(BtnAdd); } public void BtnAdd() { - var window = new OutInventoryAddMatView(); + if (SelectedShelfTypeItem == null) + { + HandyControl.Controls.MessageBox.Show("请选择货架类型!"); + } + var window = new OutInventoryAddMatView(SelectedShelfTypeItem.Id); window.Owner = Application.Current.MainWindow; var result = window.ShowDialog(); if (result == true) @@ -52,6 +123,7 @@ namespace 货架标准上位机.ViewModels if (DataGridItemSource == null) DataGridItemSource = new ObservableCollection(); DataGridItemSource.Add(window.inventorySummary); + SelectedTypeCount = DataGridItemSource.Count; } else { @@ -66,11 +138,12 @@ namespace 货架标准上位机.ViewModels { DataGridItemSource.Remove(obj); - ; + SelectedTypeCount = DataGridItemSource.Count; } catch (Exception ex) { - + Growl.Info(ex.Message); + Logs.Write($"删除物料时发生异常", LogsType.Err); } } @@ -117,6 +190,8 @@ namespace 货架标准上位机.ViewModels { OrderType = "出库", OrderSource = "WCS前端", + ShelfTypeId = SelectedShelfTypeItem.Id, + ShelfTypeName = SelectedShelfTypeItem.ShelfTypeName, ItemList = DataGridItemSource.Select(t => new MatCodeItemList() { MatCode = t.MatCode, diff --git a/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs b/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs index 04f8520..f235045 100644 --- a/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs @@ -58,6 +58,14 @@ namespace 货架标准上位机.ViewModels SetProperty(ref matName, value); } } + + private int shelfTypeId; + public int ShelfTypeId + { + get => shelfTypeId; + set { SetProperty(ref shelfTypeId, value); } + } + #endregion #region Command @@ -74,6 +82,7 @@ namespace 货架标准上位机.ViewModels { MatName = MatName, MatCode = MatCode, + ShelfTypeId = ShelfTypeId, }; var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "matInventoryDetail/getMatInventorySummary", body, "POST"); if (Result != null && Result.Data != null) diff --git a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs index e8bf1b9..42c5d6a 100644 --- a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs @@ -144,6 +144,17 @@ namespace 货架标准上位机.ViewModels BtnSearch(true); } + //导入出库 + public ICommand BtnImportDocumentCommand { get => new DelegateCommand(BtnImportDocument); } + public void BtnImportDocument() + { + var window = new OutInventoryImportDucumentView(); + window.Owner = Application.Current.MainWindow; + var result = window.ShowDialog(); + if (result == true) + BtnSearch(true); + } + public ICommand BtnOrderDetailCommand { get => new DelegateCommand(BtnOrderDetail); } public void BtnOrderDetail() { diff --git a/货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs new file mode 100644 index 0000000..244a656 --- /dev/null +++ b/货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs @@ -0,0 +1,212 @@ +using HandyControl.Controls; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Input; +using WCS.BLL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.MatBaseInfo; +using WCS.Model.ApiModel.MatInventoryDetail; +using 货架标准上位机.Api; + +namespace 货架标准上位机.ViewModels +{ + public class OutInventoryImportDucumentViewModel : BindableBase + { + #region Property + private ObservableCollection dataGridItemSource; + public ObservableCollection DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + } + } + + private MatInventorySummaryModel selectedItemSource; + public MatInventorySummaryModel SelectedItemSource + { + get { return selectedItemSource; } + set + { + SetProperty(ref selectedItemSource, value); + } + } + #endregion + + #region Command + public ICommand BtnDownloadExcelCommand { get => new DelegateCommand(BtnDownloadExcel); } + public async void BtnDownloadExcel() + { + try + { + #region 选择文件保存路径 + Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog(); + sfd.Filter = ".xlsx文件(*.xlsx)|*.xlsx"; + sfd.FileName = "出库导入模板"; + sfd.Title = "请选择文件保存地址"; + sfd.OverwritePrompt = true; + if (sfd.ShowDialog() != true) + { + return; + } + string path = sfd.FileName; + #endregion + + #region 从本地下载复制模板 + string sourceFile = System.Environment.CurrentDirectory + "\\Excel\\出库单据导入模板.xlsx"; // 源文件路径 + string destinationFile = path; // 目标文件路径 + try + { + File.Copy(sourceFile, destinationFile, true); // true表示如果目标文件存在,则覆盖它 + Growl.Success("文件下载成功!"); + } + catch (IOException ioEx) + { + Growl.Success("文件下载失败: " + ioEx.Message); + } + catch (Exception ex) + { + Growl.Success("文件下载失败: " + ex.Message); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("导出失败:" + ex.Message); + } + } + + public ICommand BtnImportCommand { get => new DelegateCommand(BtnImport); } + public async void BtnImport() + { + try + { + #region 选择需要导入文件的路径 + Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); + ofd.Title = "选择模板"; + ofd.Filter = ".xlsx文件(*.xlsx)|*.xlsx"; + ofd.Multiselect = false; + + if (ofd.ShowDialog() != true) + { + return; + } + #endregion + //已经选择文件 调用接口进行导入数据 + string path = ofd.FileName; + #region 接口导入 返回所输入物料的状态信息 校验输入的值 + var result = await ApiHelp.PostImportFileAsync>>(path, System.Net.Http.HttpMethod.Post, + LocalFile.Config.ApiIpHost + "outstore/importMat", LocalStatic.CurrentUser, LocalFile.Config.DeviceType); + if (result.Code == 200) + { + DataGridItemSource = new ObservableCollection(result.Data); + } + else + { + if (result != null && !string.IsNullOrEmpty(result.Message)) + HandyControl.Controls.MessageBox.Show(result.Message); + else + { + HandyControl.Controls.MessageBox.Show("导入失败,请重试!"); + } + } + #endregion + } + catch (Exception ex) + { + Growl.Warning("导入失败:" + ex.Message); + } + } + + public ICommand DelCommand { get => new DelegateCommand(Del); } + public void Del(MatInventorySummaryModel obj) + { + try + { + + DataGridItemSource.Remove(obj); + ; + } + catch (Exception ex) + { + + } + } + + // 定义一个事件,当需要关闭窗口时触发 + public event Action TrueClose; + public event Action FalseClose; + // 一个方法,当满足某些条件时调用,以触发关闭窗口 + protected virtual void OnRequestClose(bool IsTrue) + { + if (IsTrue) + TrueClose?.Invoke(); + else + FalseClose?.Invoke(); + } + public ICommand GenerateOutOrderCommand { get => new DelegateCommand(GenerateOutOrder); } + public void GenerateOutOrder() + { + //数据校验 + if (DataGridItemSource == null || DataGridItemSource.Count == 0) + { + HandyControl.Controls.MessageBox.Show("选择的物料为空无法生成出库单!"); + return; + } + foreach (var itemSource in DataGridItemSource) + { + if (itemSource.NeedQty == 0) + { + Growl.Warning("需求数量未填!"); + SelectedItemSource = itemSource; + return; + } + } + #region 调用接口生成出库单据 + try + { + var body = new SysOutOrderByMatCodeRequest() + { + OrderType = "出库", + OrderSource = "WCS前端", + ItemList = DataGridItemSource.Select(t => new MatCodeItemList() + { + MatCode = t.MatCode, + MatName = t.MatName, + MatBatch = t.MatBatch, + ReqQty = t.NeedQty, + }).ToList(), + DeviceType = LocalFile.Config.DeviceType, + UserName = LocalStatic.CurrentUser + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outstore/sysOutOrderByMatCode", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success(Result.Message); + OnRequestClose(true); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + return; + } + } + catch (Exception ex) + { + Growl.Error("加载数据失败:" + ex.Message); + } + finally + { + } + #endregion + } + #endregion + } +} diff --git a/货架标准上位机/ViewModels/SetViewModel.cs b/货架标准上位机/ViewModels/SetViewModel.cs index ee16e23..1309d78 100644 --- a/货架标准上位机/ViewModels/SetViewModel.cs +++ b/货架标准上位机/ViewModels/SetViewModel.cs @@ -1,15 +1,26 @@ using HandyControl.Controls; +using HandyControl.Tools.Extension; using Microsoft.Win32; using Ping9719.WpfEx.Mvvm; +using QRCoder; using System; using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; using System.IO; using System.IO.Ports; using System.Linq; +using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using System.Windows.Documents; using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Media.Imaging; +using WCS.Model; +using 货架标准上位机.Api; +using 货架标准上位机.Views.Controls; +using static System.Net.WebRequestMethods; namespace 货架标准上位机.ViewModel { @@ -215,5 +226,61 @@ namespace 货架标准上位机.ViewModel { } } + + + public ICommand AppQRCodeCommand { get => new DelegateCommand(AppQRCode); } + public void AppQRCode() + { + try + { + #region 获取最新版App名称 + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "fileDownload/getLatestAppName", null, "GET"); + if (Result != null && Result.Code == 200) + { + //拼凑url + var downLoadUrl = LocalFile.Config.ApiIpHost + $"fileDownload/downloadApp?fileName={Result.Data}"; + //生成二维码 + var qrCodeImage = GenerateQRCode(downLoadUrl); + //展示二维码 + Dialog.Show(new ImageDialog(qrCodeImage)); + + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch + { + } + } + + public BitmapImage GenerateQRCode(string data) + { + QRCodeGenerator qrGenerator = new QRCodeGenerator(); + QRCodeData qrCodeData = qrGenerator.CreateQrCode(data, QRCodeGenerator.ECCLevel.Q); + QRCode qrCode = new QRCode(qrCodeData); + Bitmap qrCodeImage = qrCode.GetGraphic(20, Color.Black, Color.White, true); + // 将System.Drawing.Bitmap转换为System.Windows.Media.Imaging.BitmapImage + using (var memoryStream = new MemoryStream()) + { + // 假设Bitmap的Save方法支持Png格式(通常是这样) + qrCodeImage.Save(memoryStream, ImageFormat.Png); + memoryStream.Position = 0; + var bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = memoryStream; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + + // 返回BitmapImage + return bitmapImage; + } + } } } diff --git a/货架标准上位机/ViewModels/ShelfInfoAddOrUpdateViewModel.cs b/货架标准上位机/ViewModels/ShelfInfoAddOrUpdateViewModel.cs index a5b8063..0b24199 100644 --- a/货架标准上位机/ViewModels/ShelfInfoAddOrUpdateViewModel.cs +++ b/货架标准上位机/ViewModels/ShelfInfoAddOrUpdateViewModel.cs @@ -33,7 +33,7 @@ namespace 货架标准上位机.ViewModel ClientIp = shelfInfoModel.ClientIp; GroupName = shelfInfoModel.GroupName; IsBind = shelfInfoModel.IsBind; - BindShelfCode = shelfInfoModel.BindShelfCode; + BigShelfCode = shelfInfoModel.BigShelfCode; } } @@ -51,7 +51,7 @@ namespace 货架标准上位机.ViewModel ClientIp = ClientIp, GroupName = GroupName, IsBind = IsBind, - BindShelfCode = BindShelfCode, + BigShelfCode = BigShelfCode, }; } @@ -156,13 +156,13 @@ namespace 货架标准上位机.ViewModel } } - private string bindShelfCode; - public string BindShelfCode + private string bigShelfCode; + public string BigShelfCode { - get { return bindShelfCode; } + get { return bigShelfCode; } set { - SetProperty(ref bindShelfCode, value); + SetProperty(ref bigShelfCode, value); } } #endregion diff --git a/货架标准上位机/ViewModels/StoreInfoViewModel.cs b/货架标准上位机/ViewModels/StoreInfoViewModel.cs index c91026c..fc5302a 100644 --- a/货架标准上位机/ViewModels/StoreInfoViewModel.cs +++ b/货架标准上位机/ViewModels/StoreInfoViewModel.cs @@ -19,6 +19,8 @@ using WCS.Model.ApiModel.MatBaseInfo; using WCS.Model.ApiModel.User; using WCS.Model.ApiModel; using Newtonsoft.Json.Bson; +using System.Windows; +using System.Security.Cryptography; namespace 货架标准上位机.ViewModel { @@ -140,6 +142,94 @@ namespace 货架标准上位机.ViewModel } #endregion } + + public ICommand DisableCommand { get => new DelegateCommand(Disable); } + public void Disable(StoreInfoModel store) + { + var result = HandyControl.Controls.MessageBox.Show("库位屏蔽仅用于临时屏蔽硬件损坏识别的未扫描上架!\r\n" + + "操作时会删除对应库位的数据,需要保证对应库位物料已取出。\r\n" + + "请确认是否进行操作?" + , "提示", MessageBoxButton.YesNo); + if (result == MessageBoxResult.Yes) + { + #region 调用接口 临时禁用库位 删除库存数据 + try + { + var body = new DisableOrEnableStoreRequest() + { + StoreId = store.Id, + SroreCode = store.StoreCode, + DisableOrEnable = DisableOrEnableEnum.Disable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableStore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("禁用成功"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } + else + { + return; + } + } + + public ICommand EnableCommand { get => new DelegateCommand(Enable); } + public void Enable(StoreInfoModel store) + { + if (store.CurrentMatSn != "禁用") + { + Growl.Warning("库位未被禁用!"); + return; + } + #region 调用接口 临时禁用库位 删除库存数据 + try + { + var body = new DisableOrEnableStoreRequest() + { + StoreId = store.Id, + SroreCode = store.StoreCode, + DisableOrEnable = DisableOrEnableEnum.Enable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableStore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("操作成功!"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } #endregion #region PageOperation 分页操作 diff --git a/货架标准上位机/Views/Controls/DeviceView.xaml b/货架标准上位机/Views/Controls/DeviceView.xaml index 157de56..821ac3a 100644 --- a/货架标准上位机/Views/Controls/DeviceView.xaml +++ b/货架标准上位机/Views/Controls/DeviceView.xaml @@ -13,126 +13,14 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/货架标准上位机/Views/Controls/DeviceView.xaml.cs b/货架标准上位机/Views/Controls/DeviceView.xaml.cs index 9bbf943..5cd3797 100644 --- a/货架标准上位机/Views/Controls/DeviceView.xaml.cs +++ b/货架标准上位机/Views/Controls/DeviceView.xaml.cs @@ -29,362 +29,19 @@ namespace 货架标准上位机 public DeviceView() { InitializeComponent(); - //viewModel.plc = LocalStatic.Plc; this.DataContext = viewModel; } //第一次显示,渲染Ui private void visfir(object sender, EventArgs e) { - if (IsInDesignMode) - return; - - if (!System.IO.File.Exists(LocalFile.PlcDotPath)) - { - Growl.Info($"没有找到文档[{LocalFile.PlcDotPath}],请联系管理员。"); - return; - } - - //读Excel - viewModel.DataReads = ExcelDeviceReadModel.GetDatas(); - viewModel.DataWrites = ExcelDeviceWriteModel.GetDatas(); - viewModel.DataUrns = ExcelDeviceUrnModel.GetDatas(); - viewModel.DataServos = ExcelDeviceServoModel.GetDatas(); - - //加载页面 - ReadUi(viewModel.DataReads); - WriteUi(viewModel.DataWrites); - UrnUi(viewModel.DataUrns); - ServoUi(viewModel.DataServos); - - //展示限制 - viewModel.IsVisRead = viewModel.DataReads.Any(); - viewModel.IsVisWrite = viewModel.DataWrites.Any(); - viewModel.IsVisUrn = viewModel.DataUrns.Any(); - viewModel.IsVisServo = viewModel.DataServos.Any(); - - Task.Run(viewModel.WhileRead); } private void vis(object sender, DependencyPropertyChangedEventArgs e) { if (IsInDesignMode) return; - - viewModel.IsVis = (bool)e.NewValue; } - #region 渲染页面 - void ReadUi(IEnumerable data) - { - stackPanel1.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.Value = item.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - item.IsExpanded = true; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item.ExcelTag)}.{nameof(item.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - stackPanel1.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - item2.Value = item2.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item2; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item2.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item2.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item2.ExcelTag)}.{nameof(item2.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - expander.Content = wrapPanel; - stackPanel1.Children.Add(expander); - } - } - } - - void WriteUi(IEnumerable data) - { - if (true) - { - stackPanel2.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.Value = item.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - item.IsExpanded = true; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item; - iotState.Click += viewModel.WriteClick; - iotState.PreviewMouseLeftButtonDown += viewModel.LeftDown; - iotState.PreviewMouseLeftButtonUp += viewModel.LeftUp; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item.ExcelTag)}.{nameof(item.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - stackPanel2.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - item2.Value = item2.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item2; - iotState.Click += viewModel.WriteClick; - iotState.PreviewMouseLeftButtonDown += viewModel.LeftDown; - iotState.PreviewMouseLeftButtonUp += viewModel.LeftUp; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item2.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item2.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item2.ExcelTag)}.{nameof(item2.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - expander.Content = wrapPanel; - stackPanel2.Children.Add(expander); - } - } - } - } - - void UrnUi(IEnumerable data) - { - if (true) - { - stackPanel3.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.IsExpanded = true; - - IotUrnMode iotUrn = new IotUrnMode(); - iotUrn.DataContext = item; - iotUrn.SetBinding(IotUrnMode.TextProperty, nameof(item.Name)); - iotUrn.SetBinding(IotUrnMode.IsButBadge1Property, nameof(item.IsGoTo)); - iotUrn.SetBinding(IotUrnMode.IsButBadge2Property, nameof(item.IsRetTo)); - iotUrn.Button1.Click += viewModel.Button1_Click; - iotUrn.Button1.PreviewMouseLeftButtonDown += viewModel.But1ClickDown; - iotUrn.Button1.PreviewMouseLeftButtonUp += viewModel.But1ClickUp; - iotUrn.Button2.Click += viewModel.Button2_Click; - iotUrn.Button2.PreviewMouseLeftButtonDown += viewModel.But2ClickDown; - iotUrn.Button2.PreviewMouseLeftButtonUp += viewModel.But2ClickUp; - - wrapPanel.Children.Add(iotUrn); - } - stackPanel3.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - IotUrnMode iotUrn = new IotUrnMode(); - iotUrn.DataContext = item2; - iotUrn.SetBinding(IotUrnMode.TextProperty, nameof(item2.Name)); - iotUrn.SetBinding(IotUrnMode.IsButBadge1Property, nameof(item2.IsGoTo)); - iotUrn.SetBinding(IotUrnMode.IsButBadge2Property, nameof(item2.IsRetTo)); - iotUrn.Button1.Click += viewModel.Button1_Click; - iotUrn.Button1.PreviewMouseLeftButtonDown += viewModel.But1ClickDown; - iotUrn.Button1.PreviewMouseLeftButtonUp += viewModel.But1ClickUp; - iotUrn.Button2.Click += viewModel.Button2_Click; - iotUrn.Button2.PreviewMouseLeftButtonDown += viewModel.But2ClickDown; - iotUrn.Button2.PreviewMouseLeftButtonUp += viewModel.But2ClickUp; - - wrapPanel.Children.Add(iotUrn); - } - expander.Content = wrapPanel; - stackPanel3.Children.Add(expander); - } - } - } - } - - void ServoUi(IEnumerable data) - { - if (true) - { - stackPanel4.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.IsExpanded = true; - - IotServoMode iotServo = new IotServoMode(); - iotServo.DataContext = item; - iotServo.SetBinding(IotServoMode.TextProperty, nameof(item.Name)); - iotServo.SetBinding(IotServoMode.Speed1Property, nameof(item.JogSpeed)); - iotServo.SetBinding(IotServoMode.Speed2Property, nameof(item.AutoSpeed)); - iotServo.SetBinding(IotServoMode.LocationProperty, nameof(item.Location)); - iotServo.SetBinding(IotServoMode.IsVis1Property, new Binding(nameof(item.IsJog)) { Mode = BindingMode.TwoWay }); - iotServo.SetBinding(IotServoMode.IsFoldProperty, new Binding(nameof(item.IsFold)) { Mode = BindingMode.TwoWay }); - iotServo.LocationChange += viewModel.LocationChange; - iotServo.SpeedChange += viewModel.SpeedChange; - - wrapPanel.Children.Add(iotServo); - } - stackPanel4.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - IotServoMode iotServo = new IotServoMode(); - iotServo.DataContext = item2; - iotServo.SetBinding(IotServoMode.TextProperty, nameof(item2.Name)); - iotServo.SetBinding(IotServoMode.Speed1Property, nameof(item2.JogSpeed)); - iotServo.SetBinding(IotServoMode.Speed2Property, nameof(item2.AutoSpeed)); - iotServo.SetBinding(IotServoMode.LocationProperty, nameof(item2.Location)); - iotServo.SetBinding(IotServoMode.IsVis1Property, new Binding(nameof(item2.IsJog)) { Mode = BindingMode.TwoWay }); - iotServo.SetBinding(IotServoMode.IsFoldProperty, new Binding(nameof(item2.IsFold)) { Mode = BindingMode.TwoWay }); - iotServo.LocationChange += viewModel.LocationChange; - iotServo.SpeedChange += viewModel.SpeedChange; - - wrapPanel.Children.Add(iotServo); - } - expander.Content = wrapPanel; - stackPanel4.Children.Add(expander); - } - } - } - } - #endregion } } diff --git a/货架标准上位机/Views/Controls/ImageDialog.xaml b/货架标准上位机/Views/Controls/ImageDialog.xaml new file mode 100644 index 0000000..91740a1 --- /dev/null +++ b/货架标准上位机/Views/Controls/ImageDialog.xaml @@ -0,0 +1,15 @@ + + + + + + - + - + diff --git a/货架标准上位机/Views/HomeView.xaml.cs b/货架标准上位机/Views/HomeView.xaml.cs index 406f0e0..76528c0 100644 --- a/货架标准上位机/Views/HomeView.xaml.cs +++ b/货架标准上位机/Views/HomeView.xaml.cs @@ -24,7 +24,7 @@ namespace 货架标准上位机 /// public partial class HomeView : UserControlBase { - HomeViewModel viewModel = new HomeViewModel(); + public static HomeViewModel viewModel = new HomeViewModel(); public HomeView() { @@ -40,5 +40,12 @@ namespace 货架标准上位机 viewModel.LoadTask(); } + private void vis(object sender, DependencyPropertyChangedEventArgs e) + { + if (IsInDesignMode) + return; + + viewModel.IsThisPageVisible = (bool)e.NewValue; + } } } diff --git a/货架标准上位机/Views/InInventoryView.xaml b/货架标准上位机/Views/InInventoryView.xaml index a92fbaf..2e62513 100644 --- a/货架标准上位机/Views/InInventoryView.xaml +++ b/货架标准上位机/Views/InInventoryView.xaml @@ -34,7 +34,7 @@ hc:BorderElement.CornerRadius="15" MinHeight="40" FontSize="20" - Content="结束入库" + Content="结束所有入库" FontFamily="{StaticResource IconFont}" Command="{Binding BtnEndCommand}"> @@ -42,17 +42,33 @@ - - - - + + + + + + + + + + + + + + + + + + + + - + diff --git a/货架标准上位机/Views/InInventoryView.xaml.cs b/货架标准上位机/Views/InInventoryView.xaml.cs index c8793cd..c9bb6a9 100644 --- a/货架标准上位机/Views/InInventoryView.xaml.cs +++ b/货架标准上位机/Views/InInventoryView.xaml.cs @@ -36,8 +36,10 @@ namespace 货架标准上位机 t.ScannerDisplayControl = control; scannersWrapPanel.Children.Add(control); }); - } + //ImageSource = new BitmapImage(new Uri("/Resources/goOutInstore.png")); + } + //public BitmapImage ImageSource { get; set; } private void DataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { DataGrid datagrid = sender as DataGrid; diff --git a/货架标准上位机/Views/MXWindows/MXMainWindow.xaml b/货架标准上位机/Views/MXWindows/MXMainWindow.xaml new file mode 100644 index 0000000..f8ac1c8 --- /dev/null +++ b/货架标准上位机/Views/MXWindows/MXMainWindow.xaml @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 主页 + + + + + + + + + + + + 物料入库 + + + + + + + + + + + + + + 物料出库 + + + + + + + + + + + + PDA盘点单 + + + + + + + + + + + + PDA盘点 + + + + + + + + + + + + 物料盘点 + + + + + + + + + + + + 库存查询 + + + + + + + + + + + + 出入记录 + + + + + + + + + + + + 库位管理 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 接口记录 + + + + + + + + + + + + 权限 + + + + + + + + + + + + + + + + + + + + + 调试 + + + + + + + + + + + + + + + + 设置 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/货架标准上位机/Views/MXWindows/MXMainWindow.xaml.cs b/货架标准上位机/Views/MXWindows/MXMainWindow.xaml.cs new file mode 100644 index 0000000..c341185 --- /dev/null +++ b/货架标准上位机/Views/MXWindows/MXMainWindow.xaml.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System.Windows.Threading; +using 货架标准上位机.ViewModel; +using HandyControl.Controls; + +namespace 货架标准上位机 +{ + /// + /// MainWindow1.xaml 的交互逻辑 + /// + public partial class MXMainWindow : HandyControl.Controls.Window + { + public static MainViewModel viewModel = MainWindow.viewModel; + public MXMainWindow() + { + if (!viewModel.InitAgo()) + { + this.Close(); + System.Environment.Exit(0); + } + InitializeComponent(); + this.DataContext = viewModel; + } + + private void load(object sender, RoutedEventArgs e) + { + viewModel.Init(this); + } + + private void tabControl_PreviewKeyDown(object sender, KeyEventArgs e) + { + //取消tabControl快捷键切换 + if (e.Key == Key.LeftCtrl || e.Key == Key.LeftCtrl || e.Key == Key.Tab) + e.Handled = true; + } + + private void Window_Closed(object sender, EventArgs e) + { + System.Environment.Exit(0); + } + } +} diff --git a/货架标准上位机/Views/MXWindows/MXOutInventoryView.xaml b/货架标准上位机/Views/MXWindows/MXOutInventoryView.xaml new file mode 100644 index 0000000..1268104 --- /dev/null +++ b/货架标准上位机/Views/MXWindows/MXOutInventoryView.xaml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/货架标准上位机/Views/MXWindows/MXOutInventoryView.xaml.cs b/货架标准上位机/Views/MXWindows/MXOutInventoryView.xaml.cs new file mode 100644 index 0000000..f93396f --- /dev/null +++ b/货架标准上位机/Views/MXWindows/MXOutInventoryView.xaml.cs @@ -0,0 +1,69 @@ +using Ping9719.WpfEx; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using System.Text.RegularExpressions; +using 货架标准上位机.ViewModel; + +namespace 货架标准上位机 +{ + public partial class MXOutInventoryView : UserControlBase + { + public static MXOutInventoryViewModel viewModel = new MXOutInventoryViewModel(); + public MXOutInventoryView() + { + InitializeComponent(); + this.DataContext = viewModel; + } + + private void DataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) + { + try + { + var viewModel = this.DataContext as InInventoryViewModel; + DataGrid datagrid = sender as DataGrid; + var index = datagrid.SelectedIndex; + if (index >= 0) + { + + } + datagrid.UnselectAllCells(); + } + catch + { + + } + } + + private void ListView_PreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + if (!e.Handled) + { + // ListView拦截鼠标滚轮事件 + e.Handled = true; + + // 激发一个鼠标滚轮事件,冒泡给外层ListView接收到 + var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); + eventArg.RoutedEvent = UIElement.MouseWheelEvent; + eventArg.Source = sender; + var parent = ((Control)sender).Parent as UIElement; + parent.RaiseEvent(eventArg); + } + } + + private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) + { + viewModel.RefreshOutOrderList(viewModel.SelectedOutOrderNumber); + } + } +} diff --git a/货架标准上位机/Views/MXWindows/MXOutOrderDetailView.xaml b/货架标准上位机/Views/MXWindows/MXOutOrderDetailView.xaml new file mode 100644 index 0000000..4ad9511 --- /dev/null +++ b/货架标准上位机/Views/MXWindows/MXOutOrderDetailView.xaml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + A + B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/货架标准上位机/Views/MXWindows/MXPDView.xaml.cs b/货架标准上位机/Views/MXWindows/MXPDView.xaml.cs new file mode 100644 index 0000000..4a001f2 --- /dev/null +++ b/货架标准上位机/Views/MXWindows/MXPDView.xaml.cs @@ -0,0 +1,59 @@ +using Ping9719.WpfEx; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; +using System.Text.RegularExpressions; +using 货架标准上位机.ViewModel; + +namespace 货架标准上位机 +{ + public partial class MXPDView : UserControlBase + { + public static MXPDViewModel viewModel { get; set; } = new MXPDViewModel(); + public MXPDView() + { + InitializeComponent(); + this.DataContext = viewModel; + } + + private void DataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) + { + try + { + DataGrid datagrid = sender as DataGrid; + datagrid.UnselectAllCells(); + } + catch + { + } + } + + private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) + { + viewModel.RefreshOutOrderList(viewModel.SelectedOutOrderNumber); + } + private void ListView_PreviewMouseWheel(object sender, MouseWheelEventArgs e) + { + if (!e.Handled) + { + e.Handled = true; + // 激发一个鼠标滚轮事件,冒泡给外层ListView接收到 + var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); + eventArg.RoutedEvent = UIElement.MouseWheelEvent; + eventArg.Source = sender; + var parent = ((Control)sender).Parent as UIElement; + parent.RaiseEvent(eventArg); + } + } + } +} diff --git a/货架标准上位机/Views/MainWindows/MainWindow.xaml.cs b/货架标准上位机/Views/MainWindows/MainWindow.xaml.cs index e1890e3..1470044 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow.xaml.cs +++ b/货架标准上位机/Views/MainWindows/MainWindow.xaml.cs @@ -27,7 +27,10 @@ namespace 货架标准上位机 public MainWindow() { if (!viewModel.InitAgo()) + { this.Close(); + System.Environment.Exit(0); + } InitializeComponent(); diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml b/货架标准上位机/Views/MainWindows/MainWindow1.xaml index 8081593..60cf77e 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml @@ -8,6 +8,7 @@ xmlns:pi="https://github.com/ping9719/wpfex" xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes" mc:Ignorable="d" + Closed="Window_Closed" Title="{Binding Title}" NonClientAreaBackground="#FFDCEEFF" Height="800" Width="1280" Icon="/Resources/Logo.ico" Background="#FFDCEEFF" WindowStartupLocation="CenterScreen" Loaded="load"> @@ -241,16 +242,16 @@ - - - - - + + + + + @@ -291,10 +292,10 @@ - + diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml.cs b/货架标准上位机/Views/MainWindows/MainWindow1.xaml.cs index 02dd3d6..110ae4a 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml.cs +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml.cs @@ -29,8 +29,10 @@ namespace 货架标准上位机 public MainWindow1() { if (!viewModel.InitAgo()) + { this.Close(); - + System.Environment.Exit(0); + } InitializeComponent(); this.DataContext = viewModel; } @@ -46,5 +48,10 @@ namespace 货架标准上位机 if (e.Key == Key.LeftCtrl || e.Key == Key.LeftCtrl || e.Key == Key.Tab) e.Handled = true; } + + private void Window_Closed(object sender, EventArgs e) + { + System.Environment.Exit(0); + } } } diff --git a/货架标准上位机/Views/MatBaseInfoView.xaml b/货架标准上位机/Views/MatBaseInfoView.xaml index 5d33da3..7faaedb 100644 --- a/货架标准上位机/Views/MatBaseInfoView.xaml +++ b/货架标准上位机/Views/MatBaseInfoView.xaml @@ -113,9 +113,9 @@ @@ -129,7 +129,7 @@ + + + + + + + + + + + + + + + + + + + + + + + 开机启动 @@ -86,7 +94,7 @@ - + - @@ -102,8 +102,8 @@ -