| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- using SqlSugar;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Globalization;
- using System.Linq;
- using wms.dto.response.sx;
- using wms.sqlsugar;
- using wms.sqlsugar.model.sx;
- namespace wms.service.Extensions
- {
- /// <summary>
- /// 时效服务扩展
- /// </summary>
- public static class SxServiceExtension
- {
- #region 焊点计算
- /// <summary>
- /// 装箱时处理焊点盘
- /// </summary>
- /// <param name="rule">箱号对应的装箱规则</param>
- /// <param name="invlist">库存信息</param>
- /// <param name="outInvlist">后续可用的不带焊点盘信息</param>
- /// <returns>填充后的焊点盘列表</returns>
- public static List<StockTemp> ProcessWeldingPointsBoxing(BillPboxrule rule, IEnumerable<StockTemp>? invlist, out IEnumerable<StockTemp>? outInvlist)
- {
- var solderinvlist = new List<StockTemp>();
- invlist ??= Enumerable.Empty<StockTemp>();
- // 如果不控制焊点盘数,则直接按生产时间排序后返回
- if (rule.SolderMaxCount <= 0)
- {
- outInvlist = invlist.OrderBy(p => p.ProductTime);
- return solderinvlist;
- }
- // 计算需要获取的焊点盘数量
- int itemsPerBox = (rule.SpoolType == "BS60" || rule.SpoolType == "BS40") ? 72 : 36;
- int requiredSolderBoxes = Math.Max(0, rule.FullCountQty / itemsPerBox * rule.SolderMaxCount);
- // 获取所有带焊点的盘并排序
- var availableSolders = invlist.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
- // 根据是否管控总焊点数量来选择不同的策略
- if (rule.PerSolderMaxCount <= 0)
- {
- // 不管控总焊点数量,直接取前 N 个
- solderinvlist = availableSolders.Take(requiredSolderBoxes).ToList();
- }
- else
- {
- // 管控总焊点数量,使用 GetWeldingPointsBoxing 方法
- solderinvlist = GetWeldingPointsBoxing(
- currentBoxes: solderinvlist,
- maxBoxCount: requiredSolderBoxes,
- maxTotalSolderCount: rule.PerSolderMaxCount,
- inventory: availableSolders
- );
- }
- // 剩余可用库存为无焊点的
- outInvlist = invlist.Where(p => p.SolderCount == 0);
- return solderinvlist;
- }
- /// <summary>
- /// 获取焊点盘(装箱处理)
- /// </summary>
- /// <param name="currentBoxes">已有的焊点盘</param>
- /// <param name="maxBoxCount">最大焊点盘数</param>
- /// <param name="maxTotalSolderCount">最大焊点总数</param>
- /// <param name="inventory">库存信息</param>
- /// <returns>填充后的焊点盘列表</returns>
- public static List<StockTemp> GetWeldingPointsBoxing(List<StockTemp> currentBoxes, int maxBoxCount, int maxTotalSolderCount, IEnumerable<StockTemp>? inventory)
- {
- if (inventory == null || !inventory.Any()) return currentBoxes;
- // 当前状态统计
- var currentBoxCount = currentBoxes.Count;
- var currentTotalSolderCount = currentBoxes.Sum(x => x.SolderCount);
- // 如果已经满载,直接返回
- if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) return currentBoxes;
- // 将库存转换为列表并排序,避免重复排序
- var availableInventory = inventory.Where(p => p.SolderCount > 0).OrderBy(p => p.ProductTime).ThenByDescending(p => p.SolderCount).ToList();
- foreach (var item in availableInventory)
- {
- // 判断是否还能继续添加
- if (currentBoxCount >= maxBoxCount || currentTotalSolderCount >= maxTotalSolderCount) break;
- // 添加当前项
- currentBoxes.Add(item);
- currentBoxCount++;
- currentTotalSolderCount += item.SolderCount;
- }
- return currentBoxes;
- }
- #endregion 焊点计算
- #region 获取码垛位
- /// <summary>
- /// 根据配置信息获取可用码垛位
- /// </summary>
- /// <param name="palletizingList">现有码垛位</param>
- /// <param name="config">配置表</param>
- /// <param name="code">配置信息code</param>
- /// <returns></returns>
- public static List<sxSysConfig> GetAvailablePalletizingStationsByConfiguration(this List<sxSysConfig> palletizingList, Repository<sxSysConfig> config, string code)
- {
- // 获取配置中的机器人列表
- var configuredRobots = config.GetFirst(x => x.Code == code).SContent.Split("|").Select(x => ToTitleCase(x));
- // 定义机器人及其对应的码垛位映射关系
- var robotToPalletizingMap = new Dictionary<string, List<string>>
- {
- { "Robot1", new List<string> { "8090", "8092" } },
- { "Robot2", new List<string> { "8096", "8098" } },
- { "Robot3", new List<string> { "8307" } }
- };
- // 获取所有符合条件的码垛位
- var availablePalletizingCodes = configuredRobots
- .SelectMany(robot =>
- {
- if (robotToPalletizingMap.TryGetValue(robot, out var palletizing))
- {
- return palletizing;
- }
- return Enumerable.Empty<string>();
- })
- .Distinct();
- // 返回匹配的码垛位列表
- return palletizingList.Where(palletizing => availablePalletizingCodes.Contains(palletizing.Code)).ToList();
- }
- /// <summary>
- /// 根据配置信息获取可用机械臂
- /// </summary>
- /// <param name="palletizingList">现有码垛位</param>
- /// <param name="config">配置表</param>
- /// <param name="code">配置信息code</param>
- /// <returns></returns>
- public static List<string> GetAvailablePalletizingRobotsByConfiguration(this List<string> palletizingList, Repository<sxSysConfig> config, string code)
- {
- // 获取配置中的机器人列表
- var configuredRobots = config.GetFirst(x => x.Code == code).SContent.Split("|").Select(x => ToTitleCase(x));
- // 返回匹配的码垛位列表
- return palletizingList.Select(x => ToTitleCase(x)).Where(x => configuredRobots.Contains(x)).ToList();
- }
- /// <summary>
- /// 将字符串转换为首字母大写,其他全小写
- /// </summary>
- /// <param name="str"></param>
- /// <returns></returns>
- public static string ToTitleCase(string str)
- {
- if (string.IsNullOrEmpty(str))
- {
- return str;
- }
- // 将字符串转换为全小写
- string lowerStr = str.ToLower();
- // 使用 TextInfo.ToTitleCase 转换为标题大小写
- TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
- string titleCasedStr = textInfo.ToTitleCase(lowerStr);
- return titleCasedStr;
- }
- #endregion 获取码垛位
- }
- }
|