/// <summary> /// 可疊數量如果歸0->不刪除紀錄,直接更新成0(背包計算上已處理這塊) /// 不可疊->直接砍掉該筆紀錄 /// </summary> /// <param name="uid"></param> /// <param name="items"></param> /// <param name="fromType"></param> /// <param name="from"></param> /// <returns></returns> public static async ETTask <EquipmentResult> DeleteEquipment(long uid, List <EquipmentInfo> items, EquipmentFrom fromType, int from, bool deleteAnyhow = false) { // 回傳結構 var equipmentResult = new EquipmentResult(); // 抓取使用者背包限制資料 User user = await UserDataHelper.FindOneUser(uid); // 無使用者? if (user == null) { equipmentResult.error = ErrorCode.ERR_AccountDoesntExist; return(equipmentResult); } // 先把相關資料搜尋出來 var eids = items.Select(e => e.ConfigId).ToList(); var results = await dbProxy.Query <Equipment>(entity => entity.uid == uid && eids.Contains(entity.configId)); var equipments = results.OfType <Equipment>().ToList(); // 用企劃表id進行分組 var dictConfigId = OtherHelper.Group(equipments, entity => entity.configId); //// 用企劃表type進行分組(TODO:記得擋背包類型下最大存放數) //var dictConfigType = OtherHelper.Group(equipments, entity => entity.configType); // 批處理 var saveBatch = new List <ComponentWithId>(); var logBatch = new List <ComponentWithId>(); var deleteBatch = new List <long>(); var refreshBagType = new List <int>(); for (int i = 0; i < items.Count; i++) { var item = items[i]; if (item.Count <= 0) { equipmentResult.error = ErrorCode.ERR_EquipmentInvalidCount; return(equipmentResult); } if (TryGetEquipmentConfig(item.ConfigId, out CharacterConfig equipmentConfig)) { // 道具是否可用? if (!equipmentConfig.IsAvailable()) { equipmentResult.error = ErrorCode.ERR_EquipmentUnavailable; return(equipmentResult); } if (!dictConfigId.TryGetValue(equipmentConfig.Id, out var userEqs)) { userEqs = new List <Equipment>(0); } // 道具是否可疊加? if (equipmentConfig.IsStackEquipment()) { var maxCount = equipmentConfig.MaxCountOnSlot; // 可疊不該有兩筆以上的記錄 if (userEqs.Count > 1) { // 記在ErrorLog裡 Log.Error(new Exception($"ERR_EquipmentRecordError> Uid:{uid}, Type:{equipmentConfig.Type}, ConfigId:{equipmentConfig.Id}")); await _MergeEquipment(uid, userEqs.ToArray()); // 合併資料後用遞迴再跑一次 return(await DeleteEquipment(uid, items.Skip(i).ToList(), fromType, from)); } // 判斷有無記錄? else if (userEqs.Count == 0) { equipmentResult.error = ErrorCode.ERR_EquipmentBagIsEmpty; return(equipmentResult); } // 存在一筆紀錄了 else { var userEq = userEqs[0]; if (userEq.count < item.Count) { equipmentResult.error = ErrorCode.ERR_EquipmentNotEnough; return(equipmentResult); } userEq.count -= item.Count; saveBatch.Add(userEq); var log = ComponentFactory.Create <EquipmentLog>(); log.from = from; log.fromType = fromType; log.count = item.Count; var dbLog = _GetSaveEquipmentDBLog(uid, userEq, log, DBLog.LogType.SubtractEquipment); logBatch.Add(dbLog); } } else { if (deleteAnyhow) { var configs = userEqs; if (configs.Count < item.Count) { equipmentResult.error = ErrorCode.ERR_EquipmentNotEnough; return(equipmentResult); } for (int k = 0; k < item.Count; k++) { var config = configs[k]; if (!deleteBatch.Contains(config.Id)) { deleteBatch.Add(config.Id); } } } else { if (!deleteBatch.Contains(item.Id)) { deleteBatch.Add(item.Id); } } } if (!refreshBagType.Contains(equipmentConfig.Type)) { refreshBagType.Add(equipmentConfig.Type); } } else { equipmentResult.error = ErrorCode.ERR_EquipmentNotDefined; return(equipmentResult); } } var result = new RepeatedField <EquipmentInfo>(); // 批刪除 // 不可疊加就根據Id直接砍,Log額外再紀錄 if (deleteBatch.Count != 0) { foreach (var v in dictConfigId) { var dels = OtherHelper.SearchAll(v.Value, entity => deleteBatch.Contains(entity.Id)); var delLog = ComponentFactory.Create <EquipmentLog>(); delLog.from = from; delLog.fromType = fromType; var dbLog = _GetDeleteBatchNoStackEquipmentDBLog(uid, dels, delLog); logBatch.Add(dbLog); } await dbProxy.DeleteJson <Equipment>(entity => deleteBatch.Contains(entity.Id)); foreach (var id in deleteBatch) { result.Add(new EquipmentInfo { Id = id, Count = 0, }); } } // 批儲存資料 if (saveBatch.Count != 0) { await dbProxy.SaveBatch(saveBatch); foreach (var item in saveBatch) { result.Add(((Equipment)item).ToEquipmentInfo()); } } // 批儲存Log if (logBatch.Count != 0) { await dbProxy.SaveBatch(logBatch); } if (refreshBagType.Count != 0) { await user.RecalculateBagCount(refreshBagType); } equipmentResult.error = ErrorCode.ERR_Success; equipmentResult.equipmentInfos = result; equipmentResult.userBagInfo = ToUserBagCapacity(user.userBagCapacity); return(equipmentResult); }