SxServiceExtension.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using SqlSugar;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Globalization;
  6. using System.Linq;
  7. using wms.dto.response.sx;
  8. using wms.sqlsugar;
  9. using wms.sqlsugar.model.sx;
  10. namespace wms.service.Extensions
  11. {
  12. /// <summary>
  13. /// 时效服务扩展
  14. /// </summary>
  15. public static class SxServiceExtension
  16. {
  17. #region 焊点计算
  18. /// <summary>
  19. /// 装箱时处理焊点盘
  20. /// </summary>
  21. /// <param name="rule">箱号对应的装箱规则</param>
  22. /// <param name="invlist">库存信息</param>
  23. /// <param name="outInvlist">后续可用的不带焊点盘信息</param>
  24. /// <returns>填充后的焊点盘列表</returns>
  25. public static List<StockTemp> ProcessWeldingPointsBoxing(BillPboxrule rule, IEnumerable<StockTemp>? invlist, out IEnumerable<StockTemp>? outInvlist)
  26. {
  27. var solderinvlist = new List<StockTemp>();
  28. invlist ??= Enumerable.Empty<StockTemp>();
  29. // 如果不控制焊点盘数,则直接按生产时间排序后返回
  30. if (rule.SolderMaxCount <= 0)
  31. {
  32. outInvlist = invlist.OrderBy(p => p.ProductTime);
  33. return solderinvlist;
  34. }
  35. // 计算需要获取的焊点盘数量
  36. int itemsPerBox = (rule.SpoolType == "BS60" || rule.SpoolType == "BS40") ? 72 : 36;
  37. int requiredSolderBoxes = Math.Max(0, rule.FullCountQty / itemsPerBox * rule.SolderMaxCount);
  38. // 获取所有带焊点的盘并排序
  39. var availableSolders = invlist.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
  40. // 根据是否管控总焊点数量来选择不同的策略
  41. if (rule.PerSolderMaxCount <= 0)
  42. {
  43. // 不管控总焊点数量,直接取前 N 个
  44. solderinvlist = availableSolders.Take(requiredSolderBoxes).ToList();
  45. }
  46. else
  47. {
  48. // 管控总焊点数量,使用 GetWeldingPointsBoxing 方法
  49. solderinvlist = GetWeldingPointsBoxing(
  50. currentBoxes: solderinvlist,
  51. maxBoxCount: requiredSolderBoxes,
  52. maxTotalSolderCount: rule.PerSolderMaxCount,
  53. inventory: availableSolders
  54. );
  55. }
  56. // 剩余可用库存为无焊点的
  57. outInvlist = invlist.Where(p => p.SolderCount == 0);
  58. return solderinvlist;
  59. }
  60. /// <summary>
  61. /// 获取焊点盘(装箱处理)
  62. /// </summary>
  63. /// <param name="currentBoxes">已有的焊点盘</param>
  64. /// <param name="maxBoxCount">最大焊点盘数</param>
  65. /// <param name="maxTotalSolderCount">最大焊点总数</param>
  66. /// <param name="inventory">库存信息</param>
  67. /// <returns>填充后的焊点盘列表</returns>
  68. public static List<StockTemp> GetWeldingPointsBoxing(List<StockTemp> currentBoxes, int maxBoxCount, int maxTotalSolderCount, IEnumerable<StockTemp>? inventory)
  69. {
  70. if (inventory == null || !inventory.Any()) return currentBoxes;
  71. // 当前状态统计
  72. var currentBoxCount = currentBoxes.Count;
  73. var currentTotalSolderCount = currentBoxes.Sum(x => x.SolderCount);
  74. // 如果已经满载,直接返回
  75. if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) return currentBoxes;
  76. // 将库存转换为列表并排序,避免重复排序
  77. var availableInventory = inventory.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
  78. foreach (var item in availableInventory)
  79. {
  80. // 判断是否还能继续添加
  81. if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) break;
  82. // 添加当前项
  83. currentBoxes.Add(item);
  84. currentBoxCount++;
  85. currentTotalSolderCount += item.SolderCount;
  86. }
  87. return currentBoxes;
  88. }
  89. #endregion 焊点计算
  90. #region 获取码垛位
  91. /// <summary>
  92. /// 根据配置信息获取可用码垛位
  93. /// </summary>
  94. /// <param name="palletizingList">现有码垛位</param>
  95. /// <param name="config">配置表</param>
  96. /// <param name="code">配置信息code</param>
  97. /// <returns></returns>
  98. public static List<sxSysConfig> GetAvailablePalletizingStationsByConfiguration(this List<sxSysConfig> palletizingList, Repository<sxSysConfig> config, string code)
  99. {
  100. // 获取配置中的机器人列表
  101. var configuredRobots = config.GetFirst(x => x.Code == code).SContent.Split("|").Select(x => ToTitleCase(x));
  102. // 定义机器人及其对应的码垛位映射关系
  103. var robotToPalletizingMap = new Dictionary<string, List<string>>
  104. {
  105. { "Robot1", new List<string> { "8090", "8092" } },
  106. { "Robot2", new List<string> { "8096", "8098" } },
  107. { "Robot3", new List<string> { "8307" } }
  108. };
  109. // 获取所有符合条件的码垛位
  110. var availablePalletizingCodes = configuredRobots
  111. .SelectMany(robot =>
  112. {
  113. if (robotToPalletizingMap.TryGetValue(robot, out var palletizing))
  114. {
  115. return palletizing;
  116. }
  117. return Enumerable.Empty<string>();
  118. })
  119. .Distinct();
  120. // 返回匹配的码垛位列表
  121. return palletizingList.Where(palletizing => availablePalletizingCodes.Contains(palletizing.Code)).ToList();
  122. }
  123. /// <summary>
  124. /// 根据配置信息获取可用机械臂
  125. /// </summary>
  126. /// <param name="palletizingList">现有码垛位</param>
  127. /// <param name="config">配置表</param>
  128. /// <param name="code">配置信息code</param>
  129. /// <returns></returns>
  130. public static List<string> GetAvailablePalletizingRobotsByConfiguration(this List<string> palletizingList, Repository<sxSysConfig> config, string code)
  131. {
  132. // 获取配置中的机器人列表
  133. var configuredRobots = config.GetFirst(x => x.Code == code).SContent.Split("|").Select(x => ToTitleCase(x));
  134. // 返回匹配的码垛位列表
  135. return palletizingList.Select(x => ToTitleCase(x)).Where(x => configuredRobots.Contains(x)).ToList();
  136. }
  137. /// <summary>
  138. /// 将字符串转换为首字母大写,其他全小写
  139. /// </summary>
  140. /// <param name="str"></param>
  141. /// <returns></returns>
  142. public static string ToTitleCase(string str)
  143. {
  144. if (string.IsNullOrEmpty(str))
  145. {
  146. return str;
  147. }
  148. // 将字符串转换为全小写
  149. string lowerStr = str.ToLower();
  150. // 使用 TextInfo.ToTitleCase 转换为标题大小写
  151. TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
  152. string titleCasedStr = textInfo.ToTitleCase(lowerStr);
  153. return titleCasedStr;
  154. }
  155. #endregion 获取码垛位
  156. }
  157. }