RGVSystems.cs 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. using PlcSiemens.Core.Extension;
  2. using ServiceCenter.Extensions;
  3. using ServiceCenter.Logs;
  4. using ServiceCenter.SqlSugars;
  5. using SqlSugar;
  6. using System.ComponentModel;
  7. using WCS.Core;
  8. using WCS.Entity;
  9. using WCS.Entity.Protocol.BCR;
  10. using WCS.Entity.Protocol.RGV;
  11. using WCS.Entity.Protocol.Robot;
  12. using WCS.Entity.Protocol.Station;
  13. using WCS.Entity.Protocol.Truss;
  14. using WCS.WorkEngineering.Extensions;
  15. using WCS.WorkEngineering.Worlds;
  16. using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
  17. using TaskStatus = WCS.Entity.TaskStatus;
  18. using TaskType = WCS.Entity.TaskType;
  19. namespace WCS.WorkEngineering.Systems
  20. {
  21. /// <summary>
  22. /// RGV交互系统
  23. /// </summary>
  24. [BelongTo(typeof(RgvWorld))]
  25. [Description("RGV交互系统")]
  26. public class RGVSystems : DeviceSystem<Device<IRGV520, IRGV521, IBCR81>>
  27. {
  28. protected override bool ParallelDo => true;
  29. /// <summary>
  30. /// 取货点设备集合
  31. /// </summary>
  32. private readonly Dictionary<string, List<Device<IStation520, IStation521, IStation523>>> _pickUpDevices = new();
  33. public RGVSystems()
  34. {
  35. //获取所有的巷道集合
  36. var rgvList = Device.All.Where(v => v.HasFlag(DeviceFlags.RGV));
  37. foreach (var rgv in rgvList)
  38. {
  39. _pickUpDevices.Add(rgv.Code, rgv.Sources.Where(v => v.HasFlag(DeviceFlags.输送机)).Select(v => new Device<IStation520, IStation521, IStation523>(v, this.World)).ToList());
  40. }
  41. }
  42. public override void Do(Device<IRGV520, IRGV521, IBCR81> obj)
  43. {
  44. try
  45. {
  46. if (obj.Data.VoucherNo != obj.Data2.VoucherNo)
  47. {
  48. World.Log($"凭证号不一致,DB520:{obj.Data.VoucherNo}-DB521:{obj.Data2.VoucherNo}", LogLevelEnum.High);
  49. return;
  50. }
  51. if (obj.Data2.WorkMode != RGVWorkMode.Automatic)
  52. {
  53. World.Log(obj.Data2.WorkMode.GetDescription());
  54. return;
  55. }
  56. //wcs任务完成确认信号未清除
  57. if (obj.Data.RES1 == 1)
  58. {
  59. World.Log("wcs任务完成确认信号未清除");
  60. return;
  61. }
  62. if (obj.Data2.Status.HasFlag(RGVStatus.Taskfinishi))
  63. {
  64. switch (obj.Data2.CmdType)
  65. {
  66. case RGVCmdType.PickGoods: //单独取货任务完成,默认只有空托盘才会下发单独取货任务
  67. World.Log($"任务处理:开始-取货完成-任务号[{obj.Data2.TaskNumber}]起始地址[{obj.Data2.StartPosition}]目标地址[{obj.Data2.DestPosition}]");
  68. //开始申请读码信息
  69. var bcrCode = obj.Data3.GetBCRCode();
  70. if (bcrCode.IsNullOrWhiteSpace() || bcrCode.Contains(":"))
  71. {
  72. World.Log("扫码失败,内容为空", LogLevelEnum.Mid);
  73. return;
  74. }
  75. World.Log($"任务处理:扫码结果-{bcrCode}");
  76. var taskNumber = 0;
  77. SqlSugarHelper.Do(_db =>
  78. {
  79. var db = _db.Default;
  80. //检查库存表是否有残留库存信息
  81. if (db.Queryable<BillInvnow>().Any(x => x.ContGrpBarCode == bcrCode))
  82. {
  83. World.Log($"【{obj.Entity.Code}】上的托盘 【{bcrCode}】存在历史库存信息,请检查对应托盘条码是否存在未完成的出库任务!!!!!", LogLevelEnum.High);
  84. return;
  85. }
  86. var dev = Device.All.First(x => x.Code == obj.Data2.DestPosition.ToString());
  87. if (dev.HasFlag(DeviceFlags.桁架码垛位))
  88. {
  89. //开始绑定任务,并下发新的任务信息到小车
  90. var palletizingInfo = db.Queryable<WCS_Palletizing>().Single(x => x.Id == obj.Data2.TaskNumber);
  91. if (palletizingInfo == null)
  92. {
  93. World.Log($"未找到对应的码垛信息{obj.Data2.TaskNumber}", LogLevelEnum.Mid);
  94. return;
  95. }
  96. palletizingInfo.PalleCode = bcrCode;
  97. db.UpdateableRowLock(palletizingInfo).UpdateColumns(x => new { x.PalleCode }).ExecuteCommand();
  98. taskNumber = palletizingInfo.Id;
  99. World.Log($"任务处理:当前任务为桁架区域补空托任务");
  100. }
  101. else if (dev.HasFlag(DeviceFlags.环形库码垛工位))
  102. {
  103. //开始处理对应的搬运任务信息
  104. var task = db.Queryable<WCS_TaskInfo>().UpdLock().First(x => x.Type == TaskType.Delivery && x.ID == obj.Data2.TaskNumber && x.AddrTo == obj.Data2.DestPosition.ToString());
  105. if (task == null)
  106. {
  107. World.Log($"未找到对应的搬运任务{obj.Data2.TaskNumber}", LogLevelEnum.Mid);
  108. return;
  109. }
  110. task.BarCode = bcrCode;
  111. db.UpdateableRowLock(task).UpdateColumns(x => new { x.BarCode }).ExecuteCommand();
  112. task.AddWCS_TASK_DTL(db, obj.Entity.Code, obj.Data2.DestPosition.ToString(), $"环形库码垛位{obj.Data2.DestPosition}搬运任务绑定条码信息{bcrCode}");
  113. taskNumber = task.ID;
  114. World.Log($"任务处理:当前任务为环形库区域补空托任务");
  115. }
  116. });
  117. if (taskNumber == 0)
  118. {
  119. World.Log($"取货完成处理失败", LogLevelEnum.Mid);
  120. return;
  121. }
  122. //清空目标点信息
  123. var destDev = new Device<IStation520>(Device.All.FirstOrDefault(x => x.Code == obj.Data2.DestPosition.ToString())!, World);
  124. destDev.Data.TaskNumber = 0;
  125. destDev.Data.GoodsStart = 0;
  126. destDev.Data.GoodsEnd = 0;
  127. obj.Data2.TaskNumber = taskNumber;
  128. obj.Data.RES1 = 1;
  129. World.Log($"任务处理:结束-取货完成-任务号[{obj.Data2.TaskNumber}]起始地址[{obj.Data2.StartPosition}]目标地址[{obj.Data2.DestPosition}]");
  130. break;
  131. case RGVCmdType.PutGoods:
  132. Device destPosition = null;
  133. bool isPalletizing = false;
  134. try
  135. {
  136. World.Log($"任务处理:开始-放货完成-任务号[{obj.Data2.TaskNumber}]起始地址[{obj.Data2.StartPosition}]目标地址[{obj.Data2.DestPosition}]");
  137. WCS_TaskInfo finishiTask = null;
  138. var startPosition = Device.All.Where(x => x.Code == obj.Data2.StartPosition.ToString())
  139. .Select(x => new Device<IStation520, IStation521, IStation523>(x, World))
  140. .FirstOrDefault();
  141. destPosition = Device.All.FirstOrDefault(x => x.Code == obj.Data2.DestPosition.ToString());
  142. isPalletizing = destPosition!.HasFlag(DeviceFlags.桁架码垛位, DeviceFlags.环形库码垛工位);
  143. short countQty = 0;
  144. short shortCode = 0;
  145. SqlSugarHelper.Do(_db =>
  146. {
  147. var db = _db.Default;
  148. if (isPalletizing)
  149. {
  150. if (destPosition.HasFlag(DeviceFlags.桁架码垛位))
  151. {
  152. var palletizingInfo = db.Queryable<WCS_Palletizing>()
  153. .First(x => x.Id == obj.Data.TaskNumber);
  154. countQty = palletizingInfo.CountQty.ToShort();
  155. shortCode = palletizingInfo.ShortCode;
  156. World.Log($"任务处理:当前任务为桁架区域补空托任务");
  157. }
  158. else if (destPosition.HasFlag(DeviceFlags.环形库码垛工位))
  159. {
  160. var deliveryTask = db.Queryable<WCS_TaskInfo>().UpdLock()
  161. .First(x => x.ID == obj.Data.TaskNumber);
  162. countQty = deliveryTask.FullQty;
  163. shortCode = deliveryTask.PalletType;
  164. deliveryTask.Status = TaskStatus.RgvCompleted;
  165. deliveryTask.EditTime = DateTime.Now;
  166. deliveryTask.LastInteractionPoint = obj.Entity.Code;
  167. db.Updateable(deliveryTask).UpdateColumns(x => new { x.Status, x.EditTime, x.LastInteractionPoint }).ExecuteCommand();
  168. deliveryTask.AddWCS_TASK_DTL(db, deliveryTask.AddrTo, $"RGV任务执行结束");
  169. World.Log($"任务处理:当前任务为环形库区域补空托任务");
  170. }
  171. }
  172. });
  173. if (startPosition.Data.TaskNumber == obj.Data.TaskNumber) //初始化起始点信息
  174. {
  175. startPosition.Data.TaskNumber = 0;
  176. startPosition.Data.GoodsEnd = 0;
  177. World.Log($"任务处理:初始化取货点{startPosition.Entity.Code}任务及目标地址信息");
  178. }
  179. //else {
  180. // return;
  181. //}
  182. //目标地址是码垛工位
  183. if (isPalletizing)
  184. {
  185. if (destPosition.HasFlag(DeviceFlags.桁架码垛位))
  186. {
  187. var dest = new Device<ITruss530>(destPosition!, World);
  188. dest.Data.MaxQuantity = countQty;
  189. dest.Data.Quantity = 0;
  190. dest.Data.Type = shortCode;
  191. dest.Data.VoucherNo++;
  192. World.Log($"任务处理:写入码垛信息-码垛位[{dest.Entity.Code}]最大码垛数量[{dest.Data.MaxQuantity}]已码数量[{dest.Data.Quantity}]垛形[{dest.Data.Type}]凭证号[{dest.Data.VoucherNo}]");
  193. }
  194. else if (destPosition.HasFlag(DeviceFlags.环形库码垛工位))
  195. {
  196. var dest = new Device<IRobot530>(destPosition!, World);
  197. dest.Data.MaxQuantity = countQty;
  198. dest.Data.Type = shortCode;
  199. dest.Data.VoucherNo++;
  200. World.Log($"任务处理:写入码垛信息-码垛位[{dest.Entity.Code}]最大码垛数量[{dest.Data.MaxQuantity}]垛形[{dest.Data.Type}]凭证号[{dest.Data.VoucherNo}]");
  201. }
  202. }
  203. }
  204. catch (Exception e)
  205. {
  206. World.Log($"处理小车放货完成是出现错误:{e.Message}-{e.StackTrace}");
  207. return;
  208. }
  209. obj.Data.RES1 = 1;
  210. World.Log($"任务处理:结束-放货完成-任务号[{obj.Data2.TaskNumber}]起始地址[{obj.Data2.StartPosition}]目标地址[{obj.Data2.DestPosition}]");
  211. break;
  212. case RGVCmdType.Move:
  213. World.Log($"任务处理:开始-移动完成-任务号[{obj.Data2.TaskNumber}]目标地址[{obj.Data2.DestPosition}]");
  214. obj.Data.RES1 = 1;
  215. World.Log($"任务处理:结束-移动完成-任务号[{obj.Data2.TaskNumber}]目标地址[{obj.Data2.DestPosition}]");
  216. break;
  217. case RGVCmdType.ChangePutGoods:
  218. break;
  219. case RGVCmdType.ChangePickGoods:
  220. break;
  221. case RGVCmdType.PickPutGoods:
  222. World.Log($"任务处理:开始-取放货完成-任务号[{obj.Data2.TaskNumber}]起始地址[{obj.Data2.StartPosition}]目标地址[{obj.Data2.DestPosition}]");
  223. var statDev = Device.All.FirstOrDefault(x => x.Code == obj.Data.StartPosition.ToString());
  224. //if (statDev.HasFlag(DeviceFlags.二次码垛RGV取货口))
  225. //{
  226. // //var dev = new Device<IStation520, IStation521, ITruss530>(Device.All.FirstOrDefault(x => x.Code == obj.Data.DestPosition.ToString())!, World);
  227. // //WCS_Palletizing pall = new WCS_Palletizing();
  228. // ////获取码垛信息
  229. // //SqlSugarHelper.Do(_db =>
  230. // //{
  231. // // var db = _db.Default;
  232. // // pall = db.Queryable<WCS_Palletizing>().Includes(x => x.Layers, x => x.Rows, x => x.Locs).First(x => x.Id == obj.Data2.TaskNumber);
  233. // //});
  234. // //if (pall == null)
  235. // //{
  236. // // World.Log($"未找到对应任务{obj.Data2.TaskNumber}");
  237. // //}
  238. // //var pallLoc = pall.Layers.SelectMany(x => x.Rows).SelectMany(x => x.Locs).Select(x => new { XYNo = x.XYNo.ToShort(), x.Finish }).ToList();
  239. // //dev.Data3.MaxQuantity = pall.CountQty.ToShort();
  240. // //dev.Data3.Quantity = pallLoc.Count(x => x.Finish).ToShort();
  241. // //dev.Data3.Type = pall.ShortCode;
  242. // //dev.Data3.VoucherNo++;
  243. // //World.Log($"任务处理:二次码垛目标地址写入码垛信息-目标货位[{dev.Entity.Code}]最大码垛数量[{dev.Data3.MaxQuantity}]已码数量[{dev.Data3.Quantity}]垛形[{dev.Data3.Type}]凭证号[{dev.Data3.VoucherNo}]");
  244. // //var destDev = new Device<IStation520, IStation521>(statDev, World);
  245. // //destDev.Data.TaskNumber = 0;
  246. // //destDev.Data.GoodsStart = 0;
  247. // //destDev.Data.GoodsEnd = 0;
  248. // //World.Log($"任务处理:清除起始地址信息-目标货位{destDev.Entity.Code}");
  249. //}
  250. //else
  251. //{
  252. // //var destDev = new Device<IStation520, IStation521>(Device.All.FirstOrDefault(x => x.Code == obj.Data.DestPosition.ToString())!, World);
  253. //}
  254. var stDev = new Device<IStation520, IStation521>(Device.All.FirstOrDefault(x => x.Code == obj.Data.StartPosition.ToString())!, World);
  255. stDev.Data.TaskNumber = 0;
  256. stDev.Data.GoodsStart = 0;
  257. stDev.Data.GoodsEnd = 0;
  258. World.Log($"任务处理:清除目标地址信息-目标货位{stDev.Entity.Code}");
  259. obj.Data.RES1 = 1;
  260. World.Log($"任务处理:结束-取放货完成-任务号[{obj.Data2.TaskNumber}]起始地址[{obj.Data2.StartPosition}]目标地址[{obj.Data2.DestPosition}]");
  261. break;
  262. default:
  263. throw new ArgumentOutOfRangeException();
  264. }
  265. return;
  266. }
  267. if (obj.Data2.SystemStatus != RGVSystemStatus.空闲)
  268. {
  269. World.Log(obj.Data2.SystemStatus.GetDescription());
  270. return;
  271. }
  272. if (obj.Data2.Status.HasFlag(RGVStatus.RES1)) //离开非安全区域
  273. {
  274. World.Log($"任务处理:开始-下发移动任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  275. obj.Data.TaskNumber = obj.Data.TaskNumber;
  276. obj.Data.CmdType = RGVCmdType.Move;
  277. obj.Data.DestPosition = obj.Entity.Code switch
  278. {
  279. "RGV1" => 1668,
  280. "RGV2" => 1683,
  281. "RGV3" => 1698,
  282. "RGV4" => 1713,
  283. "RGV5" => 1728,
  284. "RGV6" => 1743,
  285. _ => throw new ArgumentOutOfRangeException()
  286. };
  287. obj.Data.VoucherNo++;
  288. World.Log($"任务处理:结束-下发移动任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  289. return;
  290. }
  291. if (obj.Data2.CmdType == RGVCmdType.PickGoods && !obj.Data2.Status.HasFlag(RGVStatus.Taskfinishi))
  292. {
  293. if (obj.Data2.Status.HasFlag(RGVStatus.PH_Status))
  294. {
  295. World.Log($"任务处理:开始-下发放货任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]起始地址[{obj.Data.StartPosition}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  296. obj.Data.TaskNumber = obj.Data.TaskNumber;
  297. obj.Data.CmdType = RGVCmdType.PutGoods;
  298. obj.Data.StartPosition = obj.Data2.StartPosition;
  299. obj.Data.DestPosition = obj.Data2.DestPosition;
  300. obj.Data.VoucherNo++;
  301. World.Log($"任务处理:结束-下发放货任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]起始地址[{obj.Data.StartPosition}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  302. return;
  303. }
  304. }
  305. var pickUpDevices = _pickUpDevices.FirstOrDefault(x => x.Key == obj.Entity.Code).Value;
  306. //有货且需要搬运货物的站台
  307. var devs = pickUpDevices.Where(v => v.Data3.Status.HasFlag(StationStatus.PH_Status) && v.Data.TaskNumber != 0)
  308. .Where(v => v.Entity.Code.ToShort() != v.Data.GoodsEnd && v.Data.GoodsEnd != 0)
  309. .ToList();
  310. //筛选出目标站台无货的站台
  311. var putDev = obj.Entity.Targets.Where(x => x.HasFlag(DeviceFlags.输送机))
  312. .Select(x => new Device<IStation520, IStation521, IStation523>(x, World))
  313. .Where(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status))
  314. .Where(x => !x.Data3.Status.HasFlag(StationStatus.OT_Status))
  315. .Select(x => x.Entity.Code.ToShort());
  316. //var devList = devs.OrderBy(x => x.Entity.Code).Where(x => putDev.Contains(x.Data.GoodsEnd));
  317. var devList = devs.OrderBy(x => x.Data.TaskNumber).Where(x => putDev.Contains(x.Data.GoodsEnd));
  318. if (!devList.Any())
  319. {
  320. World.Log($"无可用任务");
  321. }
  322. foreach (var dev in devList)
  323. {
  324. //区分任务是拆盘机到码垛工位,还是码垛工位到拆盘机
  325. if (dev.Entity.HasFlag(DeviceFlags.拆盘机))
  326. {
  327. World.Log($"任务处理:开始-下发取货任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]RGV运行状态[{obj.Data2.WorkMode.GetDescription()}]起始地址[{obj.Data.StartPosition}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  328. obj.Data.TaskNumber = dev.Data.TaskNumber;
  329. obj.Data.CmdType = RGVCmdType.PickGoods;
  330. obj.Data.StartPosition = dev.Entity.Code.ToShort();
  331. obj.Data.DestPosition = dev.Data.GoodsEnd;
  332. obj.Data.VoucherNo++;
  333. World.Log($"任务处理:结束-下发取货任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]起始地址[{obj.Data.StartPosition}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  334. return;
  335. }
  336. //if (dev.Entity.HasFlag(DeviceFlags.二次码垛RGV取货口))
  337. //{
  338. // obj.Data.TaskNumber = dev.Data.TaskNumber;
  339. // obj.Data.CmdType = RGVCmdType.PickPutGoods;
  340. // obj.Data.StartPosition = dev.Entity.Code.ToShort();
  341. // obj.Data.DestPosition = dev.Data.GoodsEnd;
  342. // obj.Data.VoucherNo++;
  343. // return;
  344. //}
  345. World.Log($"任务处理:开始-下发满托入库任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]RGV运行状态[{obj.Data2.WorkMode.GetDescription()}]起始地址[{obj.Data.StartPosition}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  346. //非拆盘机起始任务
  347. //站台中的任务号
  348. WCS_TaskInfo task = null;
  349. SqlSugarHelper.Do(_db =>
  350. {
  351. var db = _db.Default;
  352. var taskInfo = db.Queryable<WCS_TaskInfo>().First(p => p.ID == dev.Data.TaskNumber && p.Status == TaskStatus.ConveyorExecution);
  353. if (taskInfo == null)
  354. {
  355. World.Log($"任务处理:未找到对应的任务{dev.Entity.Code}--{dev.Data.TaskNumber}-1");
  356. return;
  357. }
  358. taskInfo.Status = TaskStatus.RgvExecution;
  359. taskInfo.AddrNext = obj.Entity.Code;
  360. taskInfo.EditWho = "WCS";
  361. taskInfo.EditTime = DateTime.Now; ;
  362. db.UpdateableRowLock(taskInfo).UpdateColumns(x => new { x.Status, x.AddrNext, x.EditWho, x.EditTime }).ExecuteCommand();
  363. taskInfo.AddWCS_TASK_DTL(db, dev.Entity.Code, obj.Entity.Code, $"任务分配至{obj.Entity.Code}");
  364. task = taskInfo;
  365. });
  366. if (task == null)
  367. {
  368. World.Log($"任务处理:未找到对应的任务{dev.Entity.Code}--{dev.Data.TaskNumber}-2");
  369. return;
  370. }
  371. World.Log($"任务处理:满托入库业务流程处理完成-任务[{task.ID}]状态已变更为[{task.Status}]开始准备写入PLC");
  372. obj.Data.TaskNumber = task.ID;
  373. obj.Data.CmdType = RGVCmdType.PickPutGoods;
  374. obj.Data.StartPosition = dev.Entity.Code.ToShort();
  375. obj.Data.DestPosition = dev.Data.GoodsEnd;
  376. obj.Data.VoucherNo++;
  377. World.Log($"任务处理:结束-下发满托入库任务-任务号[{obj.Data.TaskNumber}]任务类型[{obj.Data.CmdType}]起始地址[{obj.Data.StartPosition}]目标地址[{obj.Data.DestPosition}]凭证号[{obj.Data.VoucherNo}]");
  378. return;
  379. }
  380. }
  381. catch (Exception ex)
  382. {
  383. if (ex.Message == "Destination array was not long enough. Check the destination index, length, and the array's lower bounds")
  384. {
  385. World.Log($"未知异常:{ex.StackTrace}");
  386. }
  387. else if (ex.Message == "Number was less than the array's lower bound in the first dimension")
  388. {
  389. World.Log($"未知异常:{ex.StackTrace}");
  390. }
  391. else throw new KnownException(ex.Message, LogLevelEnum.Mid);
  392. }
  393. }
  394. public override bool Select(Device dev)
  395. {
  396. return dev.Code is "RGV1" or "RGV2" or "RGV3" or "RGV4" or "RGV5" or "RGV6";
  397. //return dev.HasFlag(Extensions.DeviceFlags.RGV);
  398. }
  399. }
  400. /// <summary>
  401. /// 库存表
  402. /// </summary>
  403. [SugarTable("Bill_InvNow")]
  404. public partial class BillInvnow : BaseModel
  405. {
  406. /// <summary>
  407. /// 仓库ID 关联仓库表 ID
  408. /// </summary>
  409. [SugarColumn(ColumnDataType = "bigint", IsNullable = false)]
  410. public long WarehouseId { get; set; }
  411. /// <summary>
  412. /// 组盘ID
  413. /// 创建库存的时候 获取条码表ContGrpId
  414. /// </summary>
  415. [SugarColumn(ColumnDataType = "bigint", IsNullable = false)]
  416. public long ContGrpId { get; set; }
  417. /// <summary>
  418. /// 容器条码 同联容器表容器条码 ContBarCode
  419. /// </summary>
  420. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  421. public string ContGrpBarCode { get; set; }
  422. /// <summary>
  423. /// 组盘类型(1物料盘 2空盘)
  424. /// </summary>
  425. [SugarColumn(IsNullable = true)]
  426. public FJContGrpType ContGrpType { get; set; }
  427. /// <summary>
  428. /// 箱条码
  429. /// </summary>
  430. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  431. public string BoxBarCode { get; set; }
  432. /// <summary>
  433. /// Bom单号 关联投料单 帘线工序工单号 BillCode
  434. /// </summary>
  435. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  436. public string BomDocsNo { get; set; }
  437. /// <summary>
  438. /// Bom物料ID
  439. /// </summary>
  440. [SugarColumn(ColumnDataType = "bigint", IsNullable = false)]
  441. public long BomMatId { get; set; }
  442. /// <summary>
  443. /// Bom物料编号
  444. /// </summary>
  445. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  446. public string BomMatCode { get; set; }
  447. /// <summary>
  448. /// Bom物料
  449. /// </summary>
  450. [SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = true)]
  451. public string BomMatName { get; set; }
  452. /// <summary>
  453. /// 垛形主表 ID
  454. /// </summary>
  455. [SugarColumn(ColumnDataType = "bigint", IsNullable = false)]
  456. public long BomSetId { get; set; }
  457. /// <summary>
  458. /// 垛型编码
  459. /// </summary>
  460. [SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = true)]
  461. public string SetGrpCode { get; set; }
  462. /// <summary>
  463. /// 库存状态码
  464. /// </summary>
  465. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  466. public string ExecStateCode { get; set; }
  467. /// <summary>
  468. /// 单据编号 关联单据表单据编号 DocsNo
  469. /// </summary>
  470. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  471. public string ExecDocsNo { get; set; }
  472. /// <summary>
  473. /// 单据行号
  474. /// </summary>
  475. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  476. public string ExecDocsRowNo { get; set; }
  477. /// <summary>
  478. /// 单据类型编号 同单据表TypeNum
  479. /// </summary>
  480. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  481. public string ExecDocsTypeCode { get; set; }
  482. /// <summary>
  483. /// 出入库标识
  484. /// </summary>
  485. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  486. public FJInvInOutType InvInOut { get; set; }
  487. /// <summary>
  488. /// 执行人
  489. /// </summary>
  490. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  491. public string ExecWho { get; set; }
  492. /// <summary>
  493. /// 执行时间
  494. /// </summary>
  495. [SugarColumn(ColumnDataType = "datetime", IsNullable = false)]
  496. public DateTime ExecTime { get; set; }
  497. /// <summary>
  498. /// 行
  499. /// </summary>
  500. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  501. public int PutRow { get; set; }
  502. /// <summary>
  503. /// 列
  504. /// </summary>
  505. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  506. public int PutCol { get; set; }
  507. /// <summary>
  508. /// 层
  509. /// </summary>
  510. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  511. public int PutLayer { get; set; }
  512. /// <summary>
  513. /// 入库条码号 FJ材料号
  514. /// </summary>
  515. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  516. public string InvBarCode { get; set; }
  517. /// <summary>
  518. /// 库存状态
  519. /// </summary>
  520. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  521. public string InvStateCode { get; set; }
  522. /// <summary>
  523. /// 入库单号
  524. /// </summary>
  525. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  526. public string InDocsNo { get; set; }
  527. /// <summary>
  528. /// 入库单行号
  529. /// </summary>
  530. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  531. public string InDocsRowNo { get; set; }
  532. /// <summary>
  533. /// 供应编号
  534. /// </summary>
  535. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  536. public string SuppCode { get; set; }
  537. /// <summary>
  538. /// 供应商名称
  539. /// </summary>
  540. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  541. public string SuppName { get; set; }
  542. /// <summary>
  543. /// 海关编号
  544. /// </summary>
  545. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  546. public string CustCode { get; set; }
  547. /// <summary>
  548. /// 海关名称
  549. /// </summary>
  550. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  551. public string CustName { get; set; }
  552. /// <summary>
  553. /// 物料ID
  554. /// </summary>
  555. [SugarColumn(ColumnDataType = "bigint", IsNullable = false)]
  556. public long MatId { get; set; }
  557. /// <summary>
  558. /// 物料编号
  559. /// </summary>
  560. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  561. public string MatCode { get; set; }
  562. /// <summary>
  563. /// 物料名称
  564. /// </summary>
  565. [SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = true)]
  566. public string MatName { get; set; }
  567. /// <summary>
  568. /// 总重量
  569. /// </summary>
  570. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = false)]
  571. public decimal TolWQty { get; set; }
  572. /// <summary>
  573. /// 净重
  574. /// </summary>
  575. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = false)]
  576. public decimal NetWQty { get; set; }
  577. /// <summary>
  578. /// 皮重
  579. /// </summary>
  580. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = false)]
  581. public decimal TareWQty { get; set; }
  582. /// <summary>
  583. /// 总长
  584. /// </summary>
  585. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = false)]
  586. public decimal LengthQty { get; set; }
  587. /// <summary>
  588. /// 碳当量
  589. /// </summary>
  590. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = false)]
  591. public decimal CaQty { get; set; }
  592. /// <summary>
  593. /// 销售总量
  594. /// </summary>
  595. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = false)]
  596. public decimal SolderQty { get; set; }
  597. /// <summary>
  598. /// 暂定
  599. /// </summary>
  600. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  601. public int ContUsageQty { get; set; }
  602. /// <summary>
  603. /// 批次号
  604. /// </summary>
  605. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  606. public string BatchNo { get; set; }
  607. /// <summary>
  608. /// 生产时间
  609. /// </summary>
  610. [SugarColumn(ColumnDataType = "datetime", IsNullable = false)]
  611. public DateTime ProductTime { get; set; }
  612. /// <summary>
  613. /// 第一次入库时间
  614. /// </summary>
  615. [SugarColumn(ColumnDataType = "datetime", IsNullable = false)]
  616. public DateTime OneInTime { get; set; }
  617. /// <summary>
  618. /// 盘条条码
  619. /// </summary>
  620. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  621. public string RodBarCode { get; set; }
  622. /// <summary>
  623. /// 工字轮条码
  624. /// </summary>
  625. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  626. public string HWBarCode { get; set; }
  627. /// <summary>
  628. /// RFID条码
  629. /// </summary>
  630. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  631. public string RFIDBarCode { get; set; }
  632. /// <summary>
  633. /// 材料号
  634. /// </summary>
  635. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  636. public string CLBarCode { get; set; }
  637. /// <summary>
  638. /// 工字轮条码类型
  639. /// </summary>
  640. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  641. public string HWTypeCode { get; set; }
  642. /// <summary>
  643. /// 炉号
  644. /// </summary>
  645. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  646. public string BoilerNo { get; set; }
  647. /// <summary>
  648. /// 包号
  649. /// </summary>
  650. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  651. public string PackNo { get; set; }
  652. /// <summary>
  653. /// 牌号
  654. /// </summary>
  655. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  656. public string BrandNo { get; set; }
  657. /// <summary>
  658. /// 执行标准
  659. /// </summary>
  660. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  661. public string ExecStd { get; set; }
  662. /// <summary>
  663. /// 许可证号
  664. /// </summary>
  665. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  666. public string LicenceCode { get; set; }
  667. /// <summary>
  668. /// 改手盘标记
  669. /// </summary>
  670. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  671. public bool IsSurplus { get; set; }
  672. /// <summary>
  673. /// 返工标记
  674. /// </summary>
  675. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  676. public bool IsRework { get; set; }
  677. /// <summary>
  678. /// 是否黑盘
  679. /// </summary>
  680. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  681. public bool IsBlack { get; set; }
  682. /// <summary>
  683. /// 是否芯股
  684. /// </summary>
  685. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  686. public bool IsCore { get; set; }
  687. /// <summary>
  688. /// 快投标记
  689. /// </summary>
  690. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  691. public bool IsFast { get; set; }
  692. /// <summary>
  693. /// 是否异常
  694. /// </summary>
  695. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  696. public bool IsFail { get; set; }
  697. /// <summary>
  698. /// 异常原因
  699. /// </summary>
  700. [SugarColumn(ColumnDataType = "nvarchar", Length = 200, IsNullable = true)]
  701. public string FailReason { get; set; }
  702. /// <summary>
  703. /// 单/双丝
  704. /// </summary>
  705. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  706. public string SilkTypeCode { get; set; }
  707. /// <summary>
  708. /// 等级
  709. /// </summary>
  710. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  711. public string Grade { get; set; }
  712. /// <summary>
  713. /// 是否退料
  714. /// </summary>
  715. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  716. public bool IsBack { get; set; }
  717. /// <summary>
  718. /// 退料原因
  719. /// </summary>
  720. [SugarColumn(ColumnDataType = "nvarchar", Length = 200, IsNullable = true)]
  721. public string BackReason { get; set; }
  722. /// <summary>
  723. /// 是否扭转检测
  724. /// </summary>
  725. [SugarColumn(ColumnDataType = "bit", IsNullable = false)]
  726. public bool IsTorsChk { get; set; }
  727. /// <summary>
  728. /// 扭转次数
  729. /// </summary>
  730. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  731. public int TorsChkQty { get; set; }
  732. /// <summary>
  733. /// 扭转检测时间
  734. /// </summary>
  735. [SugarColumn(ColumnDataType = "datetime", IsNullable = false)]
  736. public DateTime TorsChkTime { get; set; }
  737. /// <summary>
  738. /// 正反面
  739. /// </summary>
  740. [SugarColumn(ColumnDataType = "int", IsNullable = true, ColumnDescription = "正反面")]
  741. public int SideNum { get; set; }
  742. /// <summary>
  743. /// 扭转检测结果值
  744. /// </summary>
  745. [SugarColumn(ColumnDataType = "decimal", Length = 18, IsNullable = true)]
  746. public decimal? TorsChkValue { get; set; }
  747. /// <summary>
  748. /// 扭转检测设备号
  749. /// </summary>
  750. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  751. public string TorsChkMachCode { get; set; }
  752. /// <summary>
  753. /// 工序订单号
  754. /// </summary>
  755. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  756. public string ProcessDocsCode { get; set; }
  757. /// <summary>
  758. /// 生产机台号
  759. /// </summary>
  760. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  761. public string ProductMachCode { get; set; }
  762. /// <summary>
  763. /// 生成产线号
  764. /// </summary>
  765. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = true)]
  766. public string ProductLineNo { get; set; }
  767. /// <summary>
  768. /// 货物大小
  769. /// </summary>
  770. [SugarColumn(IsNullable = true)]
  771. public int Size { get; set; }
  772. /// <summary>
  773. /// 托盘类型
  774. /// </summary>
  775. [SugarColumn(IsNullable = true, ColumnDescription = "托盘类型")]
  776. public FJPalletType PalletType { get; set; }
  777. /// <summary>
  778. /// 需要二次码垛的物料
  779. /// </summary>
  780. [SugarColumn(IsNullable = true, ColumnDescription = "循环码垛物料")]
  781. public bool Secondary { get; set; }
  782. }
  783. /// <summary>
  784. /// 基础表实体
  785. /// </summary>
  786. public class BaseModel
  787. {
  788. public BaseModel()
  789. { }
  790. /// <summary>
  791. /// ID
  792. /// </summary>
  793. [SugarColumn(ColumnName = "Id", IsPrimaryKey = true, ColumnDescription = "ID")]
  794. public virtual long Id { get; set; }
  795. /// <summary>
  796. /// 备注
  797. /// </summary>
  798. [SugarColumn(ColumnName = "Memo", Length = 500, IsNullable = true, ColumnDataType = "nvarchar", DefaultValue = "", ColumnDescription = "备注")]
  799. public virtual string Memo { get; set; }
  800. /// <summary>
  801. /// 创建用户
  802. /// </summary>
  803. [SugarColumn(ColumnName = "AddWho", Length = 50, ColumnDataType = "nvarchar", DefaultValue = "", IsNullable = false, ColumnDescription = "创建用户")]
  804. public virtual string AddWho { get; set; } = "";
  805. /// <summary>
  806. /// 更新用户
  807. /// </summary>
  808. [SugarColumn(ColumnName = "EditWho", Length = 50, ColumnDataType = "nvarchar", DefaultValue = "", IsNullable = false, ColumnDescription = "更新用户")]
  809. public virtual string EditWho { get; set; } = "";
  810. /// <summary>
  811. /// 创建时间
  812. /// </summary>
  813. [SugarColumn(ColumnName = "AddTime", DefaultValue = "1900-1-1", IsNullable = false, ColumnDescription = "创建时间")]
  814. public virtual DateTime AddTime { get; set; } = DateTime.Now;
  815. /// <summary>
  816. /// 更新时间
  817. /// </summary>
  818. [SugarColumn(ColumnName = "EditTime", DefaultValue = "1900-1-1", IsNullable = false, ColumnDescription = "更新时间")]
  819. public virtual DateTime EditTime { get; set; } = DateTime.Now;
  820. }
  821. /// <summary>
  822. /// 组盘类型
  823. /// </summary>
  824. public enum FJContGrpType
  825. {
  826. /// <summary>
  827. /// 物料盘
  828. /// </summary>
  829. [Description("物料盘")]
  830. Material = 1,
  831. /// <summary>
  832. /// 空盘
  833. /// </summary>
  834. [Description("空盘")]
  835. EmptyCon = 2,
  836. }
  837. /// <summary>
  838. /// 托盘类型
  839. /// </summary>
  840. public enum FJPalletType
  841. {
  842. /// <summary>
  843. /// 09使用的托盘
  844. /// </summary>
  845. [Description("09使用的托盘")]
  846. Pallet09 = 1,
  847. /// <summary>
  848. /// 非09使用的托盘
  849. /// </summary>
  850. [Description("非09使用的托盘")]
  851. PalletNo09 = 2,
  852. }
  853. /// <summary>
  854. /// 出入库类型
  855. /// </summary>
  856. public enum FJInvInOutType
  857. {
  858. /// <summary>
  859. /// 默认
  860. /// </summary>
  861. [Description("默认")]
  862. Default = 0,
  863. /// <summary>
  864. /// 入库
  865. /// </summary>
  866. [Description("入库")]
  867. In = 1,
  868. /// <summary>
  869. /// 出库
  870. /// </summary>
  871. [Description("出库")]
  872. Out = 2,
  873. }
  874. }