0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR); return SafeUtil::redisLockOperate(function ($tUserID, $tItemID, $tIsAdd, $tNum, SystemLog $logoVo) { //获取信息 $itemDbData = Item::findByUserIDAndItemID($tUserID, $tItemID); $config = GameConfigServices::getParamByPath('item_list.' . $tItemID); if (empty($config)) throw new StatusException(ResultStatusServices::RS_NOT_FIND_IN_CONFIG); if (!$tIsAdd && empty($itemDbData)) throw new StatusException(ResultStatusServices::RS_ITEM_NOT_ENOUGH); //添加操作,并且数据不存在则新建数据 if (empty($itemDbData)) { $itemDbData = new Item(); $itemDbData->user_id = $tUserID; $itemDbData->item_id = $tItemID; $itemDbData->num = 0; $itemDbData->name = $config['name']; $itemDbData->type = $config['type2']; } //修改数量 $itemDbData->num += $tNum; //数量不够减 if ($itemDbData->num < 0) throw new StatusException(ResultStatusServices::RS_ITEM_NOT_ENOUGH); //判断能否买多个 $onlyBuyOne = in_array($itemDbData->type, ItemServices::ITEM_ONLY_BUY_ONE_LIST); if ($onlyBuyOne && $itemDbData->num > 1) throw new StatusException(ResultStatusServices::RS_ITEM_CAN_NOT_BY_MORE); //减少操作,如果数量为0,则删除数据 if (!$tIsAdd && !$itemDbData->getIsNewRecord() && $itemDbData->num <= 0) { if (!$itemDbData->delete()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR); //删除操作 } elseif (!$itemDbData->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR); //保存操作 if (!$logoVo->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR); if ($config['type2'] == ItemServices::ITEM_TYPE2_STONE && $tNum > 0) AchievementUtil::addCount($tUserID, AchievementUtil::ID_ACCUMULATION_STONE, $tNum); return $itemDbData; }, [$userID, $itemID, $isAdd, $num, $logoVo], RedisKeyUtil::lockItem($userID, $itemID)); } /** * 判断并修改更改金钱 * isAdd 是否为添加操作 * @param int $userID * @param bool $isAdd * @param int $gold * @param SystemLog $logoVo * @throws StatusException */ public static function checkAndModifyRes($userID, $isAdd, $num, $type, SystemLog $logoVo) { //正负验证 if ($isAdd && $num < 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR); if (!$isAdd && $num > 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR); SafeUtil::redisLockOperate(function ($userID, $num, $type, SystemLog $logoVo) { //获取用户信息 $userDbData = User::findById($userID); if (!$userDbData) throw new StatusException(ResultStatusServices::RS_NOT_FIND_IN_DB); //修改资源 if ($type == ItemServices::ITEM_TYPE2_GOLD) { $userDbData->gold += $num; if ($userDbData->gold < 0) throw new StatusException(ResultStatusServices::RS_GOLD_NOT_ENOUGH); if (!$userDbData->save(true, ['gold', 'updated_at'])) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR); } if ($type == ItemServices::ITEM_TYPE2_GEM) { $userDbData->gem += $num; if ($userDbData->gem < 0) throw new StatusException(ResultStatusServices::RS_GEM_NOT_ENOUGH); if (!$userDbData->save(true, ['gem', 'updated_at'])) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR); //任务记录 DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_EXPEND_GEM, null, 1); } if (!$logoVo->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR); }, [$userID, $num, $type, $logoVo], RedisKeyUtil::lockUser($userID)); } public static function addUserExp($userID, $exp) { $exp = (int)$exp; return SafeUtil::redisLockOperate(function ($userID, $exp) { if ($exp <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR); //获取用户信息 $userDbData = User::findById($userID); if (!$userDbData) throw new StatusException(ResultStatusServices::RS_NOT_FIND_IN_DB); //达到用户最大等级 // if ($userDbData->level >= GameConfigServices::getMaxPlayerLevel()) throw new StatusException(ResultStatusServices::RS_PLAYER_MAX_LEVEL); $config = GameConfigServices::getParamByPath('player_level.' . $userDbData->level); //增加经验 $userDbData->exp += $exp; if ($userDbData->exp >= $config['exp'] && $userDbData->level < GameConfigServices::getMaxPlayerLevel()) { $userDbData->level++; $userDbData->exp = 0; $userDbData->get_level_gift = EnumUtil::PLAYER_LEVEL_GIFT_NOT_GET; } if (!$userDbData->save(true, ['exp', 'level', 'get_level_gift', 'updated_at'])) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR, $userDbData->getErrors()); return $userDbData; }, [$userID, $exp], RedisKeyUtil::lockUser($userID)); } /** * 解析物品,102001:10,101006:2,201000:10 * @param $itemStr * @param $count * @param $isAdd * @param $userID * @param $logFromType * @param $logDetail * @return array */ public static function parseAllItem($itemStr, $count, $isAdd, $userID, $logFromType, $logDetail) { $list = CommUtil::converStrList(',', $itemStr, 0); if (empty($list)) return []; $getList = []; foreach ($list as $item) { if (empty($item)) continue; $getItem = MoneyUtil::parseItem($item, $count, $isAdd, $userID, $logFromType, $logDetail); if (!empty($getItem)) array_push($getList, $getItem); } return $getList; } public static function parseAllItemIndex($itemStr, $index, $count, $isAdd, $userID, $logFromType, $logDetail) { $list = CommUtil::converStrList(',', $itemStr, 0); if (empty($list) || !isset($list[$index])) return []; $getList = []; $item = $list[$index]; if (empty($item)) return []; $getItem = MoneyUtil::parseItem($item, $count, $isAdd, $userID, $logFromType, $logDetail); if (!empty($getItem)) array_push($getList, $getItem); return $getList; } /** * 解析物品,102001:10 * @param $itemStr * @param $isAdd * @param $userID * @param $logFromType * @param $logDetail * @return array * @throws StatusException */ public static function parseItem($itemStr, $count, $isAdd, $userID, $logFromType, $logDetail) { $count = (int)$count; if ($count <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR); $list = CommUtil::converStrList(':', $itemStr, 2); if (empty($list)) return null; list($itemID, $num) = $list; $itemID = (int)$itemID; $num = (int)$num; $num *= $count; if (in_array($itemID, self::REMOVED_BOX_ITEM_IDS, true)) return null; if (empty($itemID) || $num < 0) throw new StatusException(ResultStatusServices::RS_CONFIG_ERROR); if ($num == 0) return null; $itemConfig = GameConfigServices::getParamByPath('item_list.' . $itemID); if (empty($itemConfig)) throw new StatusException(ResultStatusServices::RS_CONFIG_ERROR); if (!$isAdd) { $num *= -1; if ($num >= 0) throw new StatusException(ResultStatusServices::RS_CONFIG_ERROR); } else { if ($num <= 0) throw new StatusException(ResultStatusServices::RS_CONFIG_ERROR); } $itemType = intval($itemConfig['type2']); if ($itemType == ItemServices::ITEM_TYPE2_GOLD) { $log = SystemLogUtil::get($userID, SystemLogUtil::TYPE_GOLD, $num, 0, $logFromType, $logDetail); MoneyUtil::checkAndModifyRes($userID, $isAdd, $num, ItemServices::ITEM_TYPE2_GOLD, $log); } else if ($itemType == ItemServices::ITEM_TYPE2_GEM) { $log = SystemLogUtil::get($userID, SystemLogUtil::TYPE_GEM, $num, 0, $logFromType, $logDetail); MoneyUtil::checkAndModifyRes($userID, $isAdd, $num, ItemServices::ITEM_TYPE2_GEM, $log); }else if ($itemType == self::REMOVED_BOX_ITEM_TYPE) { return null; } else { $log = SystemLogUtil::get($userID, SystemLogUtil::TYPE_ITEM, $itemID, $num, $logFromType, $logDetail); MoneyUtil::checkAndModifyNum($userID, $itemID, $isAdd, $num, $log); if (!$isAdd && $itemType == ItemServices::ITEM_TYPE2_FRUIT) { AchievementUtil::addCount($userID, AchievementUtil::ID_CONSUME_FRUIT, abs($num)); } if ($isAdd && $itemType == ItemServices::ITEM_TYPE2_CHIP) { AchievementUtil::addCount($userID, AchievementUtil::ID_FRAGMENT_COUNT, abs($num)); } } //if (!$isAdd) { // AchievementUtil::addCount($userID, AchievementUtil::ID_CONSUME, 1); //} return ['item_id' => $itemID, 'num' => $num]; } /** * 解析物品,物品ID:概率:数量 * 201012:85:1,201013:5:1,201014:5:1,201015:5:1 * @param $itemStr * @param $isAdd * @param $userID * @param $logFromType * @param $logDetail * @return array */ public static function parseAllItemOdds($itemStr, $isAdd, $userID, $logFromType, $logDetail) { $list = CommUtil::converStrList(',', $itemStr, 0); if (empty($list)) return null; $oddList = []; foreach ($list as $str) { $list2 = CommUtil::converStrList(':', $str, 3); if (empty($list2)) continue; list($itemID, $odds, $count) = $list2; if (empty($itemID) || empty($odds) || empty($count)) continue; array_push($oddList, ['itemID' => $itemID, 'odds' => $odds, 'count' => $count]); } $item = CommUtil::oddsOne($oddList, "odds"); if (empty($item)) return null; $itemID = $item['itemID']; $count = $item['count']; $str = sprintf('%s:%d', $itemID, $count); $getItem = MoneyUtil::parseItem($str, 1, $isAdd, $userID, $logFromType, $logDetail); if (empty($getItem)) return null; return ['item_id' => $itemID, 'num' => $count]; } /** * 随机几个,102001:10,101006:2,201000:10 * @param $itemStr * @param $count * @param $isAdd * @param $userID * @param $logFromType * @param $logDetail * @return array */ public static function parseAllOddsItem($itemStr, $count, $isAdd, $userID, $logFromType, $logDetail) { $count = intval($count); if ($count <= 0) return []; $list = CommUtil::converStrList(',', $itemStr, 0); if (empty($list)) return []; $getList = []; while ($count > 0) { $listCount = count($list); if ($listCount == 0) return $getList; $listCount--; $index = rand(0, $listCount); $item = $list[$index]; if (empty($item)) continue; $getItem = MoneyUtil::parseItem($item, 1, $isAdd, $userID, $logFromType, $logDetail); if (!empty($getItem)) array_push($getList, $getItem); $count--; } return $getList; } }