using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using iWareSql; using System.Data.Entity.Migrations; using iWareSql.Orm; using iWareCommon; using iWareCommon.Utils; using iWareSql.Entity.ViewMode; using iWareSql.DBModel; using iWareModel; using iWareCommon.Common.Globle; using XiGang.Core.Model; using iWareSql.WmsDBModel; using Admin.NET.Application; namespace iWareSql.DataAccess { /// /// 新版本的库位管理 /// public class StationHandlerV2 { private static readonly object lockObject = new object(); private static readonly object lockRemoveObject = new object(); private static readonly object lockFindBestEmptyPlaceForOrdinaryMaterial = new object(); private static Dictionary lockPlaceDict = new Dictionary(); /// /// 验证站点是否可以被使用 /// /// /// public static MessageModel ValidateStationIsAllowUse(int stationId, DbModel context) { var stationList = context.Base_Station.Where(x => x.Id == stationId).ToList(); if (stationList == null || stationList.Count == 0) { return new MessageModel() { data = false, success = false, msg = "站点ID'" + stationId + "'不存在!" }; } if (stationList.Count > 1) { return new MessageModel() { data = false, success = false, msg = "站点ID'" + stationId + "'存在" + stationList.Count + "条数据!" }; } var station = stationList[0]; var stationName = "库位["; if (station.IsRgvStation) { stationName += "RGV站点" + station.RgvStationCode; } else if (station.IsSrmStation) { stationName += "堆垛机站点" + station.SrmStationCode; } stationName += "]"; if (station.IsDeleted == true) { return new MessageModel() { data = false, success = false, msg = stationName + "'已经被禁用!" }; } else if (station.IsFull) { return new MessageModel() { data = false, success = false, msg = stationName + "'已经有货!" }; } else if (station.IsLock) { return new MessageModel() { data = false, success = false, msg = stationName + "'已经被锁定!" }; } //判断库位是否目前有任务在执行 TODO //var isUse = await task_PartServices.IsExistOtherTaskDoing(station.Id); var isUse = PartTaskHandler.IsExistOtherTaskDoing(station.Id); if (isUse) { return new MessageModel() { data = false, success = false, msg = stationName + "'被其他任务占用!" }; } return new MessageModel() { data = true, success = true, msg = "验证站点可以被使用!" }; } #region 锁定库位的方法 /// /// 判断寻找到的库位是否被锁定了( 供 配板余料回库线程、RGV提前配板任务创建时,成品料回库线程、原料入库线程使用) /// /// private static bool ValidateFindPlaceIsLocked(Base_Station validatePlace, string lockReason) { lock (lockObject) { if (validatePlace == null) { return false; } if (lockPlaceDict.ContainsKey(validatePlace.Id)) { Log4NetHelper.WriteInfoLog(LogType.SrmTheadService, "lockPlaceDict已经有该锁了,validatePlace.Id:" + validatePlace.Id + ",字典中的原因是:" + lockPlaceDict[validatePlace.Id] + ",本次原因是:" + lockReason); return true; } else { lockPlaceDict.Add(validatePlace.Id, lockReason + ",库位号:" + validatePlace.SrmStationCode); return false; } } } /// /// 在事务处理完毕后,释放被锁定的库位( 供 配板余料回库线程、RGV提前配板任务创建时,成品料回库线程、原料入库线程使用) /// 一定要放到finaly里执行 /// /// public static void RemoveLockPlaceDict(Base_Station validatePlace) { if (validatePlace == null) { return; } lock (lockRemoveObject) { if (lockPlaceDict.ContainsKey(validatePlace.Id)) { lockPlaceDict.Remove(validatePlace.Id); } } } #endregion #region 寻找空库位 /// /// 寻找空闲的立库空库位 (普通物料) /// /// public static wms_base_place FindBestEmptyPlace(WmsDBModel.WmsDBModel edm, mes_batchOrderUPI_new upiObj ) { try { lock (lockFindBestEmptyPlaceForOrdinaryMaterial) { Thread.Sleep(1000); var emptyStationList = edm.V_EmptyStation.ToList(); //不随机排序 emptyStationList = emptyStationList.OrderBy(x => x.LaneNo).ThenBy(x => x.LayerNo).ThenBy(x => x.ColumnNo).ToList(); //增加该库位是否被任务占用的筛选 [EditBy shaocx,2022-06-02] //emptyStationList = FilterStationForDoingTask(edm, emptyStationList); List usePlaceTypeList = new List(); int placeType = TCSCommon.GetPlaceTypeByWidthLength(upiObj, upiObj.Length, upiObj.Width, ref usePlaceTypeList); //优先查询 var my_emptyStationList = emptyStationList.Where(x => usePlaceTypeList.Contains(x.PlaceType)).OrderBy(x => x.PlaceType).ToList(); if (my_emptyStationList?.Count() > 0) { wms_base_place toPlace = StationHandler.GetPlaceByPlaceId(my_emptyStationList.First().Id, edm); return toPlace; } else { return null; } } } catch (Exception ex) { throw; } } private static List FilterStationForDoingTask(DbModel context, List emptyStationList) { List new_emptyStationList = new List(); //增加该库位是否被任务占用的筛选 [EditBy shaocx,2022-06-02] if (emptyStationList != null && emptyStationList.Count > 0) { foreach (var _findStore in emptyStationList) { var isExistOtherTaskDoing = PartTaskHandler.IsExistOtherTaskDoing(context, _findStore.Id); if (!isExistOtherTaskDoing) { new_emptyStationList.Add(_findStore); } } } return new_emptyStationList; } /// /// 获取分配库位的库区号-版本1,库存分摊,同一个订货号分摊四个库区 /// /// /// /// /// 可用空库位数 /// private static int GetMinKey_Area_V1(string orderNo, DbModel edm, List usableAreaList, Dictionary dict_usableArea) { int minKey_Area = 0; if (!string.IsNullOrEmpty(orderNo)) {//需要按照订货号均分的库位分配方式 //寻找同一订货号的库存,并且是在可用空库位库区中 var wareHoustStoreList = edm.V_Store.Where(x => x.OrderNo == orderNo && usableAreaList.Contains(x.Area)).ToList(); if (wareHoustStoreList != null && wareHoustStoreList.Count > 0) { Dictionary new_dict_usableArea = new Dictionary();//计算现有可放库区的现有订货号的库存数字典 foreach (var item in dict_usableArea) { new_dict_usableArea.Add(item.Key, edm.V_Store.Where(x => x.OrderNo == orderNo && x.Area == item.Key.ToString()).Count()); } //var areaList = wareHoustStoreList.Select(x => x.Area).Distinct().ToList(); //Dictionary area_dict = new Dictionary(); //foreach (var item in areaList) //{ // area_dict.Add(item, wareHoustStoreList.Where(x => x.Area == item).Count()); //} minKey_Area = new_dict_usableArea.OrderBy(d => d.Value).Select(d => d.Key).FirstOrDefault(); } else { minKey_Area = dict_usableArea.OrderByDescending(d => d.Value).Select(d => d.Key).FirstOrDefault(); } } else {//不需要按照订货号均分的库位分配方式 //寻找哪个库区现在空余数最小 //var minKey = dict.Keys.Select(x => new { x, y = dict[x] }).OrderBy(x => x.y).First(); minKey_Area = dict_usableArea.OrderByDescending(d => d.Value).Select(d => d.Key).FirstOrDefault(); } return minKey_Area; } /// /// 获取分配库位的库区号-版本2,入库任务循环入库四个库区 /// /// /// /// /// 可用空库位数 /// private static int GetMinKey_Area_V2(string orderNo, DbModel edm, List usableAreaList, Dictionary dict_usableArea) { int myKey_Area = 0; if (dict_usableArea.Count == 1) { myKey_Area = dict_usableArea.First().Key; return myKey_Area; } //判断上一个入库任务是调用的哪个库区,当前任务就入另一个库区,按顺序 1,2,3,4跳跃入库 var queryDeviceTaskTypeEnum1 = (int)DeviceTaskTypeEnum.组盘入库; var queryDeviceTaskTypeEnum2 = (int)DeviceTaskTypeEnum.空托转运到立体库; var queryDeviceType = (int)EDeviceType.堆垛机; //使用 最新下发时间,来取最后一个任务 【editby shaocx,2022-04-28】 var queryState = (int)DeviceTaskStatusEnum.已取消; var lastPart = edm.Task_Part.Where(x => x.DeviceType == queryDeviceType && (x.TaskType == queryDeviceTaskTypeEnum1 || x.TaskType == queryDeviceTaskTypeEnum2) && x.TaskState != queryState).OrderByDescending(x => x.CreateTime).FirstOrDefault(); if (lastPart == null) { myKey_Area = dict_usableArea.OrderBy(d => d.Key).Select(d => d.Key).FirstOrDefault();//默认从可用库区中调第一个 } else { var current_srmNo = Convert.ToInt32(lastPart.DeviceId);//当前上一个任务执行的库区号 //取不包含current_srmNo的最大值 int max_Area = dict_usableArea.Where(x => x.Key != current_srmNo).OrderByDescending(d => d.Key).Select(d => d.Key).FirstOrDefault(); //取不包含current_srmNo的最小值 int min_Area = dict_usableArea.Where(x => x.Key != current_srmNo).OrderBy(d => d.Key).Select(d => d.Key).FirstOrDefault(); if (current_srmNo > Convert.ToInt32(max_Area)) { myKey_Area = min_Area; } else { //取除了current_srmNo,比current_srmNo大的字典的最小值 myKey_Area = dict_usableArea.Where(x => x.Key > current_srmNo).OrderBy(d => d.Key).Select(d => d.Key).FirstOrDefault(); } } return myKey_Area; } /// /// 获取分配库位的库区号-版本1,库存分摊,托盘分摊四个库区 /// /// /// /// 可用空库位数 /// private static int GetMinKey_AreaForSalver(DbModel edm, List usableAreaList, Dictionary dict_usableArea) { int minKey_Area = 0; //需要按照托盘均分的库位分配方式 //寻找托盘的库存,并且是在可用空库位库区中 var wareHoustStoreList = edm.V_Store.Where(x => x.MaterialType == (int)MaterialTypeEnum.托盘 && usableAreaList.Contains(x.Area)).ToList(); if (wareHoustStoreList != null && wareHoustStoreList.Count > 0) { Dictionary new_dict_usableArea = new Dictionary();//计算现有可放库区的现有订货号的库存数字典 foreach (var item in dict_usableArea) { new_dict_usableArea.Add(item.Key, edm.V_Store.Where(x => x.MaterialType == (int)MaterialTypeEnum.托盘 && x.Area == item.Key.ToString()).Count()); } //var areaList = wareHoustStoreList.Select(x => x.Area).Distinct().ToList(); //Dictionary area_dict = new Dictionary(); //foreach (var item in areaList) //{ // area_dict.Add(item, wareHoustStoreList.Where(x => x.Area == item).Count()); //} minKey_Area = new_dict_usableArea.OrderBy(d => d.Value).Select(d => d.Key).FirstOrDefault(); } else { minKey_Area = dict_usableArea.OrderByDescending(d => d.Value).Select(d => d.Key).FirstOrDefault(); } return minKey_Area; } /// /// 通用的寻找空库位过滤条件 /// /// /// private static List FindEmptyPlaceByCommonFilter(List places) { if (places != null && places.Count() > 0) { places = places.Where(x => !SysGloble.Dict_SpecialPlace.ContainsKey(x.SrmStationCode)).ToList(); return places.ToList(); } else { return null; } } /// /// 过滤掉特殊库位 /// /// /// public static List FindCommonFilter(List places) { if (places != null && places.Count() > 0) { places = places.Where(x => !SysGloble.Dict_SpecialPlace.ContainsKey(x.SrmStationCode)).ToList(); return places.ToList(); } else { return null; } } ///// ///// 寻找立库中的空库位 ///// ///// ///// //public static Base_Station FindBestEmptyPlaceByAreaLogic(EItemType itemType, string reamrk, DbModel edm) //{ // Base_Station place = null; // place = InnerFindBestEmptyPlaceByAreaLogic(edm); // var isLock = ValidateFindPlaceIsLocked(place, reamrk); // if (isLock) // { // return null; // } // return place; //} ///// ///// 寻找在立体库中 可放的空托物料的空库位 ///// ///// ///// //public static Base_Station FindBestEmptyPlaceBySubplate(DbModel edm, string reamrk) //{ // List orderedQueryable_places = edm.Base_Station.Where(x => x.Srm_C_V_P.Count == 0 // && x.IsAsrsPlace == 1 && x.IsTrussPlace == 0 && x.IsConveyorPlace == 0 // && x.Islock == 0 // ).ToList(); // var isRandomFindPlace = WCSConfigHelper.GetConfig_IsRandomFindPlace(); // if (!isRandomFindPlace) // { // orderedQueryable_places = orderedQueryable_places.OrderByDescending(x => x.Row).ThenBy(x => x.Col).ThenBy(x => x.Layer).ToList(); // } // else // {//随机排序 // orderedQueryable_places = ListHelper.RandomList(orderedQueryable_places); // } // var findPlaces = SrmPlaceHandels.FindPlaceByCommonFilter(orderedQueryable_places); // findPlaces = FindPlacesFilterByBreakdown(findPlaces);//通过设备状态来过滤库位 [EditBy shaocx,2020-12-13] // if (findPlaces == null) // { // //无空余 可放的垫板垛物料的库位 // return null; // } // Base_Station fullPlace = findPlaces.FirstOrDefault(); // var isLock = ValidateFindPlaceIsLocked(fullPlace, reamrk); // if (isLock) // { // return null; // } // return fullPlace; //} //private static Base_Station InnerFindBestEmptyPlaceByAreaLogic(DbModel edm) //{ // //符合逻辑区域(物料类型)的、没有CVP绑定关系的库位视为空库位,然后再按行、列、层次序选择 // //同时根据 Islock // var emptyPlaces = edm.Srm_EmptyPlaceView.Where(x => // x.Islock == 0 // ).ToList(); // var isRandomFindPlace = WCSConfigHelper.GetConfig_IsRandomFindPlace(); // if (!isRandomFindPlace) // { // emptyPlaces = emptyPlaces.OrderByDescending(x => x.Row).ThenBy(x => x.Col).ThenBy(x => x.Layer).ToList(); // } // else // {//随机排序 // emptyPlaces = ListHelper.RandomList(emptyPlaces); // } // emptyPlaces = FindPlacesFilterByBreakdown(emptyPlaces);//通过设备状态来过滤库位 [EditBy shaocx,2020-12-13] // if (emptyPlaces == null) // return null; // var emptyPlace = emptyPlaces.FirstOrDefault(); // if (emptyPlace == null) //修复提示为NULL的问题 // return null; // return edm.Base_Station.First(x => x.SrmPlaceNo == emptyPlace.SrmPlaceNo); //} #endregion /// /// 获取RGV库位 /// /// public static Base_Station GetRgvPlace(DbModel edm, string rgvStationNo) { var place = edm.Base_Station.Where(o => o.RgvStationCode == rgvStationNo).FirstOrDefault(); if (place == null) throw new Exception("没有找到RGV" + rgvStationNo + "库位!"); return place; } /// /// [入库]通过立体库的库位获取RGV入库的位置 /// /// public static Base_Station GetRgvPlaceBySrmPlaceForInStore(DbModel edm, Base_Station srmPlace) { string rgvStationNo = ""; EDevice rgvLcation; switch (srmPlace.Area) { case "1": rgvLcation = EDevice.堆垛机1入库口1002; break; case "2": rgvLcation = EDevice.堆垛机2入库口1004; break; case "3": rgvLcation = EDevice.堆垛机3入库口1006; break; case "4": rgvLcation = EDevice.堆垛机4入库口1007; break; default: throw new Exception("错误的立库库位" + srmPlace.SrmStationCode); } rgvStationNo = ((int)rgvLcation).ToString(); var place = edm.Base_Station.Where(o => o.RgvStationCode == rgvStationNo).FirstOrDefault(); if (place == null) throw new Exception("没有找到RGV" + rgvStationNo + "库位!"); return place; } /// /// [出库]通过立体库的库位获取RGV出库的位置 /// /// public static Base_Station GetRgvPlaceBySrmPlaceForOutStore(DbModel edm, Base_Station srmPlace) { string rgvStationNo = ""; EDevice rgvLcation; switch (srmPlace.Area) { case "1": rgvLcation = EDevice.堆垛机1出库口1001; break; case "2": rgvLcation = EDevice.堆垛机2出库口1003; break; case "3": rgvLcation = EDevice.堆垛机3出库口1005; break; case "4": rgvLcation = EDevice.堆垛机4出库口1008; break; default: throw new Exception("错误的立库库位" + srmPlace.SrmStationCode); } rgvStationNo = ((int)rgvLcation).ToString(); var place = edm.Base_Station.Where(o => o.RgvStationCode == rgvStationNo).FirstOrDefault(); if (place == null) throw new Exception("没有找到RGV" + rgvStationNo + "库位!"); return place; } /// /// 根据库位号去判断 所在 排、列、层 /// /// /// public static PlaceLocationView GetPlaceLocationView(Base_Station place) { string no = place.SrmStationCode; List list = no.Split('-').ToList(); if (list.Count != 3) { throw new Exception("库位格式不正确"); } PlaceLocationView result = new PlaceLocationView(); result.Row = Convert.ToInt32(list[0]); result.Col = Convert.ToInt32(list[1]); result.Layer = Convert.ToInt32(list[2]); return result; } /// /// 重新验证库位是否可以允许被使用 /// /// /// /// public static bool IsAllowUsePlace(DbModel edm, Base_Station place) { var new_place = GetPlaceByPlaceId(place.Id, edm); if (new_place.IsLock == false) return true; return false; } /// /// 重新验证库位是否可以允许被使用 /// /// /// /// public static bool IsAllowUsePlace(DbModel edm, Base_Station place, ref string errMsg) { var new_place = GetPlaceByPlaceId(place.Id, edm); var stationName = "库位["; if (new_place.IsRgvStation) { stationName += "RGV站点" + new_place.RgvStationCode; } else if (new_place.IsSrmStation) { stationName += "堆垛机站点" + new_place.SrmStationCode; } stationName += "]"; if (new_place.IsLock == true) { errMsg = stationName + "]被锁定!"; return false; } if (new_place.IsDeleted == true) { errMsg = stationName + "被禁用!"; return false; } if (new_place.IsHasTaskDoing == true) { errMsg = stationName + "被任务占用!"; return false; } //判断库位是否目前有任务在执行 TODO var isUse = PartTaskHandler.IsExistOtherTaskDoing(edm, place.Id); if (isUse) { errMsg = stationName + "被其他任务占用!"; return false; } return true; } /// /// 重新根据库位ID获取库位是否可以允许被使用 /// /// /// /// public static bool IsAllowUsePlaceByPlaceId(DbModel edm, int placeId) { var place = GetPlaceByPlaceId(placeId, edm); if (place.IsLock == false) return true; return false; } /// /// 设置Place的IsLock /// /// /// public static void SetPlaceLockStatus(bool isLock, string userName, ref Base_Station place, string remark) { place.ModifyBy = userName; place.Remark = remark + "[更新锁定/解锁库位,isLock:" + isLock + "]"; place.ModifyTime = DateTime.Now; if (isLock) { place.IsLock = true; //place.Void = (int)VoidEnum.禁用; } else { place.IsLock = false; //place.Void = (int)VoidEnum.可用; } } /// /// 设置Place的isTaskDoing /// /// 是否有任务占用 /// public static void SetPlaceTaskDoingStatus(bool isTaskDoing, string userName, ref Base_Station place, string remark) { place.ModifyBy = userName; place.Remark = remark + "[更新是否有任务占用库位,isTaskDoing:" + isTaskDoing + "]"; place.ModifyTime = DateTime.Now; if (isTaskDoing) { place.IsHasTaskDoing = true; } else { place.IsHasTaskDoing = false; } } /// /// 根据库位ID查找库位对象 /// /// public static Base_Station GetPlaceByPlaceId(int placeId, DbModel edm) { return edm.Base_Station.Where(x => x.Id == placeId).FirstOrDefault(); } /// /// 根据库位号查找库位对象 /// /// 库位号 /// /// public static Base_Station GetPlaceBySrmPlaceNo(string srmPlaceNo, DbModel edm) { return edm.Base_Station.Where(x => x.SrmStationCode == srmPlaceNo).FirstOrDefault(); } /// /// 根据RGV站点号查找库位对象 /// /// RGV站点号 /// /// public static Base_Station GetPlaceByRgvStationNo(string rgvStationNo, DbModel edm) { return edm.Base_Station.Where(x => x.RgvStationCode == rgvStationNo).FirstOrDefault(); } ///// ///// 根据ItemId查找库位对象 ///// ///// //public static Base_Station GetPlaceByItemId(string itemId, DbModel edm) //{ // var cvi = Salver_Material_Handler.GetIVCByItemId(edm, itemId); // var cvp = Salver_Station_Handler.GetCVPByContainerId(edm, cvi.SalverId); // return GetPlaceByPlaceId(cvp.StationId, edm); //} ///// ///// 按照排锁定库位 ///// ///// ///// ///// //public static void LockPlaceByRow(DbModel edm, int selectRow, string remark) //{ // var places = edm.Base_Station.Where(x => x.Row == selectRow).OrderBy(x => x.Row).ToList(); // var s_places = FindPlaceByCommonFilter(places); // foreach (var item in s_places) // { // item.Islock = 1; // item.Void = 1; // item.LastModifier = MachineHelper.GetHostName(); // item.ModifyTime = DateTime.Now; // item.Remark = remark; // } //} /// /// 通过设备类型获取库位编号 /// /// /// public static String GetStationCodeByDeviceType(Base_Station station, EDeviceType deviceType) { var placeNo = ""; switch (deviceType) { case EDeviceType.RGV: placeNo = station.RgvStationCode; break; case EDeviceType.堆垛机: placeNo = station.SrmStationCode; break; } return placeNo; } #region 通过设备状态来过滤库位 /// /// 通过设备状态来过滤库位 /// /// /// private static List FindPlacesFilterByBreakdown(List findPlaces) { if (findPlaces == null && findPlaces.Count == 0) { return findPlaces; } //判读堆垛机故障 FunRetEntity srm1 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.一号堆垛机); if (srm1.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "1").ToList(); } FunRetEntity srm2 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.二号堆垛机); if (srm2.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "2").ToList(); } FunRetEntity srm3 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.三号堆垛机); if (srm3.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "3").ToList(); } FunRetEntity srm4 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.四号堆垛机); if (srm4.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "4").ToList(); } return findPlaces; } /// /// 通过设备状态来过滤库位 /// /// /// public static List FindPlacesFilterByBreakdown(List findPlaces) { if (findPlaces == null && findPlaces.Count == 0) { return findPlaces; } //判读堆垛机故障 FunRetEntity srm1 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.一号堆垛机); if (srm1.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "1").ToList(); } FunRetEntity srm2 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.二号堆垛机); if (srm2.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "2").ToList(); } FunRetEntity srm3 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.三号堆垛机); if (srm3.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "3").ToList(); } FunRetEntity srm4 = Wms_EquipmentSituationHandler.IsEquipmentBreakdown((int)EDevice.四号堆垛机); if (srm4.result) {//故障 findPlaces = findPlaces.Where(x => x.Area != "4").ToList(); } return findPlaces; } #endregion /// /// 获取站点,新建转运任务时 /// /// /// /// /// public static FunRetEntity GetTargtStationForAddTransferTask(DbModel edm, EDevice rgvLocation, ref string errMsg, ref Base_Station targtPlace) { //目标点 targtPlace = StationHandler.GetRgvPlace(edm, ((int)rgvLocation).ToString()); if (targtPlace == null) { return FunRetEntity.Fail("没有找到站点"); } //判断起点是否有任务被占用 if (StationHandler.IsAllowUsePlace(edm, targtPlace, ref errMsg) == false) { return FunRetEntity.Fail(errMsg); } return FunRetEntity.Success("成功"); } } }