| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- <?php
- namespace App\Module\Farm\Logics;
- use App\Module\Farm\Dtos\LandInfoDto;
- use App\Module\Farm\Enums\LAND_STATUS;
- use App\Module\Farm\Enums\LAND_TYPE;
- use App\Module\Farm\Enums\UPGRADE_TYPE;
- use App\Module\Farm\Events\LandUpgradedEvent;
- use App\Module\Farm\Models\FarmLand;
- use App\Module\Farm\Models\FarmLandType;
- use App\Module\Farm\Models\FarmLandUpgradeConfig;
- use App\Module\Farm\Models\FarmUpgradeLog;
- use App\Module\Farm\Models\FarmUser;
- use App\Module\Game\Services\ConsumeService;
- use Illuminate\Support\Collection;
- use Illuminate\Support\Facades\Log;
- use UCore\Dto\Res;
- use UCore\Exception\LogicException;
- use UCore\Db\Helper;
- /**
- * 土地管理逻辑
- */
- class LandLogic
- {
- /**
- * 获取用户的所有土地
- *
- * @param int $userId
- * @return Collection|LandInfoDto[]
- */
- public function getUserLands(int $userId): Collection
- {
- try {
- $lands = FarmLand::where('user_id', $userId)
- ->orderBy('position')
- ->get();
- // dd($lands);
- return $lands->map(function ($land) {
- return LandInfoDto::fromModel($land);
- });
- } catch (\Exception $e) {
- Log::error('获取用户土地失败', [
- 'user_id' => $userId,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return collect();
- }
- }
- /**
- * 获取用户指定位置的土地
- *
- * @param int $userId
- * @param int $position
- * @return LandInfoDto|null
- */
- public function getUserLandByPosition(int $userId, int $position): ?LandInfoDto
- {
- try {
- $land = FarmLand::where('user_id', $userId)
- ->where('position', $position)
- ->first();
- if (!$land) {
- return null;
- }
- return LandInfoDto::fromModel($land);
- } catch (\Exception $e) {
- Log::error('获取用户指定位置土地失败', [
- 'user_id' => $userId,
- 'position' => $position,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return null;
- }
- }
- /**
- * 创建土地
- *
- * @param int $userId
- * @param int $position
- * @param int $landType
- * @return FarmLand|null
- */
- public function createLand(int $userId, int $position, int $landType): ?FarmLand
- {
- try {
- // 检查位置是否已有土地
- $existingLand = FarmLand::where('user_id', $userId)
- ->where('position', $position)
- ->first();
- if ($existingLand) {
- return $existingLand;
- }
- // 创建新土地
- $land = new FarmLand();
- $land->user_id = $userId;
- $land->position = $position;
- $land->land_type = $landType;
- $land->status = LAND_STATUS::IDLE->value;
- $land->save();
- Log::info('创建土地成功', [
- 'user_id' => $userId,
- 'position' => $position,
- 'land_type' => $landType,
- 'land_id' => $land->id
- ]);
- return $land;
- } catch (\Exception $e) {
- Log::error('创建土地失败', [
- 'user_id' => $userId,
- 'position' => $position,
- 'land_type' => $landType,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return null;
- }
- }
- /**
- * 升级土地
- * 调用前必须已经完成所有验证(土地归属、状态、路径、材料等)
- * 要求调用者已开启事务
- *
- * @param int $userId
- * @param int $landId
- * @param int $targetType
- * @return bool
- */
- public function upgradeLand(int $userId, int $landId, int $targetType): bool
- {
- // 验证事务是否已开启
- Helper::check_tr();
- // 获取土地信息
- /**
- * @var FarmLand $land
- */
- $land = FarmLand::where('id', $landId)
- ->where('user_id', $userId)
- ->first();
- // 防错误机制:基础数据检查
- if (!$land) {
- throw new LogicException('Logic层防错误:土地不存在,验证层应该已经检查过');
- }
- // 防错误机制:状态检查
- if ($land->status !== LAND_STATUS::IDLE->value) {
- throw new LogicException('Logic层防错误:土地状态不允许升级,验证层应该已经检查过');
- }
- // 防错误机制:类型检查
- if ($land->land_type === $targetType) {
- throw new LogicException('Logic层防错误:土地已经是目标类型,验证层应该已经检查过');
- }
- // 获取升级配置(这里不再进行完整验证,只获取配置)
- $config = FarmLandUpgradeConfig::where('from_type_id', $land->land_type)
- ->where('to_type_id', $targetType)
- ->first();
- // 防错误机制:配置检查
- if (!$config) {
- throw new LogicException('Logic层防错误:升级配置不存在,验证层应该已经检查过');
- }
- // 更新土地类型
- $oldType = $land->land_type;
- $land->land_type = $targetType;
- $land->save();
- // 创建升级记录
- $upgradeLog = new FarmUpgradeLog();
- $upgradeLog->user_id = $userId;
- $upgradeLog->upgrade_type = UPGRADE_TYPE::LAND->value;
- $upgradeLog->target_id = $landId;
- $upgradeLog->old_level = $oldType;
- $upgradeLog->new_level = $targetType;
- $upgradeLog->materials_consumed = [];
- $upgradeLog->upgrade_time = now();
- $upgradeLog->created_at = now();
- $upgradeLog->save();
- // 进行消耗
- $ec = ConsumeService::executeConsume($userId, $config->materials, 'land_upgrade', $upgradeLog->id, false);
- if ($ec->error) {
- throw new LogicException('消耗失败');
- }
- $upgradeLog->materials_consumed = $ec->data['list'];
- $upgradeLog->save();
- // 触发土地升级事件
- event(new LandUpgradedEvent($userId, $land, $oldType, $targetType, $upgradeLog));
- Log::info('土地升级成功', [
- 'user_id' => $userId,
- 'land_id' => $landId,
- 'old_type' => $oldType,
- 'new_type' => $targetType,
- 'upgrade_log_id' => $upgradeLog->id
- ]);
- return true;
- }
- /**
- * 检查升级路径
- *
- * @param $userId
- * @param $currentType
- * @param $targetType
- * @param bool $checkM 是否检查消耗
- * @return Res
- * @throws \Exception
- */
- static public function checkUpgradePath(int $userId, int $currentType, int $targetType, bool $checkM = true): Res
- {
- // 获取升级配置
- /**
- * @var FarmLandUpgradeConfig $upgradeConfig
- */
- $upgradeConfig = FarmLandUpgradeConfig::where('from_type_id', $currentType)
- ->where('to_type_id', $targetType)
- ->first();
- if (!$upgradeConfig) {
- Log::error('升级路径不存在', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType
- ]);
- return Res::error('升级路径不存在', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType
- ]);
- }
- // 检查用户房屋等级是否满足要求
- $targetLandType = FarmLandType::find($targetType);
- $farmUser = FarmUser::where('user_id', $userId)->first();
- if (!$farmUser || $farmUser->house_level < $targetLandType->unlock_house_level) {
- Log::error('房屋等级不足,无法升级到该土地类型', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType,
- 'house_level' => $farmUser->house_level,
- 'unlock_house_level' => $targetLandType->unlock_house_level
- ]);
- return Res::error('房屋等级不足,无法升级到该土地类型', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType,
- 'house_level' => $farmUser->house_level,
- 'unlock_house_level' => $targetLandType->unlock_house_level
- ]);
- }
- // 检查特殊土地数量限制
- if ($targetLandType->is_special) {
- $specialLandCount = FarmLand::where('user_id', $userId)
- ->whereIn('land_type', [ LAND_TYPE::GOLD->value, LAND_TYPE::BLUE->value, LAND_TYPE::PURPLE->value ])
- ->count();
- $houseConfig = $farmUser->houseConfig;
- if ($specialLandCount >= $houseConfig->special_land_limit) {
- Log::error('特殊土地数量已达上限', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType,
- 'special_land_count' => $specialLandCount,
- 'special_land_limit' => $houseConfig->special_land_limit
- ]);
- return Res::error('特殊土地数量已达上限', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType,
- 'special_land_count' => $specialLandCount,
- 'special_land_limit' => $houseConfig->special_land_limit
- ]);
- }
- }
- // 检查消耗
- if ($checkM) {
- $res = ConsumeService::checkConsume($userId, $upgradeConfig->materials);
- if ($res->error) {
- Log::error('当前路径资源不足', [
- 'user_id' => $userId,
- 'current_type' => $currentType,
- 'target_type' => $targetType,
- 'error' => $res->message
- ]);
- return Res::error('当前路径资源不足', [
- 'msg' => $res->message
- ]);
- }
- }
- return Res::success('升级路径可用', [
- 'config' => $upgradeConfig
- ]);
- }
- /**
- * 获取升级所需材料
- *
- * @param int $currentType 当前土地类型
- * @param int $targetType 目标土地类型
- * @return array 升级所需材料
- */
- public function getUpgradeMaterials(int $currentType, int $targetType): array
- {
- try {
- // 从数据库中获取升级配置
- $upgradeConfig = FarmLandUpgradeConfig::where('from_type_id', $currentType)
- ->where('to_type_id', $targetType)
- ->first();
- if (!$upgradeConfig) {
- return [];
- }
- // 使用模型的 getUpgradeMaterials 方法获取材料
- return $upgradeConfig->getUpgradeMaterials();
- } catch (\Exception $e) {
- Log::error('获取升级所需材料失败', [
- 'current_type' => $currentType,
- 'target_type' => $targetType,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return [];
- }
- }
- /**
- * 获取可用的升级路径(不进行消耗检查)
- *
- * @param int $userId 用户ID
- * @param int $landId 土地ID
- * @param int|null $toType 目标土地类型ID(可选)
- * @return FarmLandUpgradeConfig[]
- *
- */
- public function getAvailableUpgradePaths(int $userId, int $landId, ?int $toType = null): array
- {
- try {
- // 获取土地信息
- $land = FarmLand::where('id', $landId)
- ->where('user_id', $userId)
- ->first();
- if (!$land) {
- return [];
- }
- // 获取当前土地类型
- $currentType = $land->land_type;
- // 获取用户房屋等级
- /**
- * @var FarmUser $farmUser
- */
- $farmUser = FarmUser::where('user_id', $userId)->first();
- if (!$farmUser) {
- return [];
- }
- $houseLevel = $farmUser->house_level;
- // 获取可用的升级路径
- $query = FarmLandUpgradeConfig::where('from_type_id', $currentType)
- ->with('toType');
- // 如果指定了目标类型,则只获取该类型的升级路径
- if ($toType !== null) {
- $query->where('to_type_id', $toType);
- }
- $upgradePaths = $query->get();
- // 过滤出符合房屋等级要求的升级路径
- $availablePaths = $upgradePaths->filter(function ($path) use ($houseLevel) {
- return $path->toType->unlock_house_level <= $houseLevel;
- });
- // 检查特殊土地数量限制
- $specialLandCount = FarmLand::where('user_id', $userId)
- ->whereIn('land_type', [ LAND_TYPE::GOLD->value, LAND_TYPE::BLUE->value, LAND_TYPE::PURPLE->value ])
- ->count();
- $houseConfig = $farmUser->houseConfig;
- // 如果没有找到对应的房屋配置,使用默认值0
- $specialLandLimit = $houseConfig ? $houseConfig->special_land_limit : 0;
- // 如果特殊土地已达上限,过滤掉特殊土地升级路径
- if ($specialLandCount >= $specialLandLimit) {
- $availablePaths = $availablePaths->filter(function ($path) {
- return !$path->toType->is_special;
- });
- }
- // 格式化返回结果
- return $availablePaths->toArray();
- } catch (\Exception $e) {
- Log::error('获取可用升级路径失败', [
- 'user_id' => $userId,
- 'land_id' => $landId,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return [];
- }
- }
- }
|