hy-farm/muchang/common/utils/MoneyUtil.php
2026-05-29 19:54:56 +08:00

375 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Created by PhpStorm.
* User: zn
* Date: 2017/7/31
* Time: 16:23
*/
namespace common\utils;
use common\models\Item;
use common\models\User;
use common\modules\achievement\AchievementUtil;
use common\modules\dailytask\DailyTaskUtil;
use common\modules\safe\SafeUtil;
use common\modules\systemlog\SystemLog;
use common\modules\systemlog\SystemLogUtil;
use common\services\GameConfigServices;
use common\services\ItemServices;
use common\services\ResultStatusServices;
use common\services\StatusException;
class MoneyUtil
{
const REMOVED_BOX_ITEM_TYPE = 400;
const REMOVED_BOX_ITEM_IDS = [
201012,
201013,
201014,
201015,
201016,
];
/**
* 修改仓库物品
* @param int $pUserID
* @param int $pItemType
* @param bool $pIsAdd
* @param int $pNum
* @param SystemLog $logoVo
* @throws StatusException
*/
public static function checkAndModifyNumByItemType($pUserID, $pItemType, $pIsAdd, $pNum, SystemLog $logoVo)
{
$itemID = GameConfigServices::getItemIDByType2($pItemType);
if (empty($itemID)) throw new StatusException(ResultStatusServices::RS_ITEM_TYPE_ERROR);
self::checkAndModifyNum($pUserID, $itemID, $pIsAdd, $pNum, $logoVo);
}
/**
* 修改仓库物品
* @param int $userID
* @param int $itemID
* @param bool $isAdd
* @param int $num
* @param SystemLog $logoVo
* @return Item
* @throws StatusException
*/
public static function checkAndModifyNum($userID, $itemID, $isAdd, $num, SystemLog $logoVo)
{
//正负验证
if ($isAdd && $num < 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
if (!$isAdd && $num > 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;
}
}