| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- <?php
- namespace App\Module\Pet\Services;
- use App\Module\Pet\Dtos\PetDataDto;
- use App\Module\Pet\Enums\PetStatus;
- use App\Module\Pet\Factories\PetDtoFactory;
- use App\Module\Pet\Logic\PetLogic;
- use App\Module\Pet\Models\PetUser;
- use App\Module\Pet\Models\PetSkill;
- use App\Module\Pet\Models\PetLevelConfig;
- use Exception;
- use Illuminate\Support\Collection;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use UCore\Db\Helper;
- /**
- * 宠物服务类
- *
- * 提供宠物相关的服务,包括获取用户宠物列表、创建宠物、宠物升级、
- * 宠物喂养、宠物洗髓、宠物技能使用等功能。该类是宠物模块对外提供
- * 服务的主要入口,封装了宠物操作的复杂逻辑。
- *
- * 注意:本服务类不负责事务管理,调用方需要自行开启和管理事务。
- * 对于涉及数据修改的方法,强烈建议在调用前开启事务,以确保数据一致性。
- */
- class PetService
- {
- /**
- * 获取用户宠物列表
- *
- * @param int $userId 用户ID
- * @param array $filters 过滤条件
- * @return Collection|PetUser[]
- */
- public static function getUserPets(int $userId, array $filters = []): Collection
- {
- $query = PetUser::where('user_id', $userId);
- // 应用过滤条件
- if (isset($filters['status'])) {
- $query->where('status', $filters['status']);
- }
- if (isset($filters['grade'])) {
- $query->where('grade', $filters['grade']);
- }
- if (isset($filters['min_level'])) {
- $query->where('level', '>=', $filters['min_level']);
- }
- if (isset($filters['max_level'])) {
- $query->where('level', '<=', $filters['max_level']);
- }
- return $query->get();
- }
- /**
- * 创建宠物
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param string $name 宠物名称
- * @param int|null $grade 宠物品阶,如果为null则随机生成(1一品,2二品,3三品,4四品)
- * @param array $options 其他选项
- * @return array 创建结果
- * @throws Exception
- */
- public static function createPet(int $userId, string $name, ?int $grade = null, array $options = []): array
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 创建宠物逻辑
- $petLogic = new PetLogic();
- // 创建宠物
- $result = $petLogic->createPet($userId, $name, $grade, $options);
- return [
- 'success' => true,
- 'pet_id' => $result['pet_id'],
- 'name' => $name,
- 'grade' => $result['grade'],
- 'level' => 1,
- 'message' => '宠物创建成功'
- ];
- } catch (Exception $e) {
- Log::error('创建宠物失败', [
- 'user_id' => $userId,
- 'name' => $name,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 宠物升级
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @return array 升级结果
- * @throws Exception
- */
- public static function levelUpPet(int $userId, int $petId): array
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 宠物逻辑
- $petLogic = new PetLogic();
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 执行升级逻辑
- $result = $petLogic->levelUpPet($petId);
- return [
- 'success' => true,
- 'pet_id' => $petId,
- 'old_level' => $result['old_level'],
- 'new_level' => $result['new_level'],
- 'unlocked_skills' => $result['unlocked_skills'] ?? [],
- 'message' => '宠物升级成功'
- ];
- } catch (Exception $e) {
- Log::error('宠物升级失败', [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 宠物喂养
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @param int $itemId 物品ID(狗粮)
- * @param int $amount 数量
- * @return array 喂养结果
- * @throws Exception
- */
- public static function feedPet(int $userId, int $petId, int $itemId, int $amount = 1): array
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 宠物逻辑
- $petLogic = new PetLogic();
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 检查宠物状态
- if ($pet->status !== PetStatus::NORMAL) {
- throw new Exception("宠物当前状态不允许喂养");
- }
- // 执行喂养逻辑
- $result = $petLogic->feedPet($petId, $itemId, $amount);
- return [
- 'success' => true,
- 'pet_id' => $petId,
- 'item_id' => $itemId,
- 'amount' => $amount,
- 'exp_gained' => $result['exp_gained'],
- 'stamina_gained' => $result['stamina_gained'],
- 'level_up' => $result['level_up'],
- 'message' => '宠物喂养成功'
- ];
- } catch (Exception $e) {
- Log::error('宠物喂养失败', [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'item_id' => $itemId,
- 'amount' => $amount,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 宠物洗髓
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @param int $itemId 洗髓道具ID,如果为0则使用钻石
- * @return array 洗髓结果
- * @throws Exception
- */
- public static function remouldPet(int $userId, int $petId, int $itemId = 0): array
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 宠物逻辑
- $petLogic = new PetLogic();
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 检查宠物状态
- if ($pet->status !== PetStatus::NORMAL) {
- throw new Exception("宠物当前状态不允许洗髓");
- }
- // 执行洗髓逻辑
- $result = $petLogic->remouldPet($petId, $itemId);
- return [
- 'success' => true,
- 'pet_id' => $petId,
- 'old_grade' => $result['old_grade'],
- 'new_grade' => $result['new_grade'],
- 'item_id' => $itemId,
- 'message' => '宠物洗髓成功'
- ];
- } catch (Exception $e) {
- Log::error('宠物洗髓失败', [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'item_id' => $itemId,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 使用宠物技能
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @param int $skillId 技能ID
- * @param array $params 技能参数
- * @return array 技能使用结果
- * @throws Exception
- */
- public static function useSkill(int $userId, int $petId, int $skillId, array $params = []): array
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 宠物逻辑
- $petLogic = new PetLogic();
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 获取技能信息
- $skill = PetSkill::find($skillId);
- if (!$skill) {
- throw new Exception("技能不存在");
- }
- // 检查宠物状态
- if ($pet->status !== PetStatus::NORMAL) {
- throw new Exception("宠物当前状态不允许使用技能");
- }
- // 检查宠物等级是否满足技能要求
- if ($pet->level < $skill->min_level) {
- throw new Exception("宠物等级不足,无法使用该技能");
- }
- // 检查宠物体力是否足够
- if ($pet->stamina < $skill->stamina_cost) {
- throw new Exception("宠物体力不足,无法使用该技能");
- }
- // 执行技能使用逻辑
- $result = $petLogic->useSkill($petId, $skillId, $params);
- return [
- 'success' => true,
- 'pet_id' => $petId,
- 'skill_id' => $skillId,
- 'stamina_cost' => $skill->stamina_cost,
- 'effect_result' => $result['effect_result'],
- 'message' => '技能使用成功'
- ];
- } catch (Exception $e) {
- Log::error('使用宠物技能失败', [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'skill_id' => $skillId,
- 'params' => $params,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 获取宠物状态
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @return PetDataDto 宠物状态信息,参考DataPet结构,包括技能情况,不包含争霸赛情况
- * @throws Exception
- */
- public static function getPetStatus(int $userId, int $petId): PetDataDto
- {
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 计算宠物战力
- $petLogic = new PetLogic();
- $fightingCapacity = $petLogic->calculatePower($petId);
- // 使用工厂类创建宠物DTO
- $petDto = PetDtoFactory::createPetDataDto($pet, $fightingCapacity);
- // 直接返回DTO对象
- return $petDto;
- }
- /**
- * 更新宠物状态
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @param PetStatus $status 新状态
- * @param string $reason 变更原因
- * @return bool 是否更新成功
- * @throws Exception
- */
- public static function updatePetStatus(int $userId, int $petId, PetStatus $status, string $reason = ''): bool
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 宠物逻辑
- $petLogic = new PetLogic();
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 记录旧状态
- $oldStatus = $pet->status;
- // 执行状态变更逻辑
- $result = $petLogic->changeStatus($petId, $status, $reason);
- return true;
- } catch (Exception $e) {
- Log::error('更新宠物状态失败', [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'status' => $status->value,
- 'reason' => $reason,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 恢复宠物体力
- *
- * 注意:调用此方法前,请确保已开启数据库事务
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @param int $minutes 经过的分钟数
- * @return array 恢复结果
- * @throws Exception
- */
- public static function recoverStamina(int $userId, int $petId, int $minutes): array
- {
- // 验证事务是否已开启
- Helper::check_tr();
- try {
- // 宠物逻辑
- $petLogic = new PetLogic();
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 执行体力恢复逻辑
- $recoveredStamina = $petLogic->recoverStamina($petId, $minutes);
- return [
- 'success' => true,
- 'pet_id' => $petId,
- 'recovered_stamina' => $recoveredStamina,
- 'current_stamina' => $pet->fresh()->stamina,
- 'message' => '宠物体力恢复成功'
- ];
- } catch (Exception $e) {
- Log::error('恢复宠物体力失败', [
- 'user_id' => $userId,
- 'pet_id' => $petId,
- 'minutes' => $minutes,
- 'error' => $e->getMessage()
- ]);
- throw $e;
- }
- }
- /**
- * 获取宠物可用技能列表
- *
- * @param int $userId 用户ID
- * @param int $petId 宠物ID
- * @return array 技能列表
- * @throws Exception
- */
- public static function getPetSkills(int $userId, int $petId): array
- {
- // 获取宠物信息
- $pet = PetUser::where('id', $petId)
- ->where('user_id', $userId)
- ->first();
- if (!$pet) {
- throw new Exception("宠物不存在或不属于该用户");
- }
- // 获取所有技能
- $allSkills = PetSkill::all();
- // 筛选出宠物等级可用的技能
- $availableSkills = $allSkills->filter(function ($skill) use ($pet) {
- return $pet->level >= $skill->min_level;
- });
- // 获取技能使用记录,计算冷却时间
- $skillLogs = $pet->skillLogs()
- ->orderBy('used_at', 'desc')
- ->get()
- ->groupBy('skill_id');
- $result = [];
- foreach ($availableSkills as $skill) {
- $lastUsed = null;
- $cooldownRemaining = 0;
- if (isset($skillLogs[$skill->id]) && $skillLogs[$skill->id]->count() > 0) {
- $lastUsed = $skillLogs[$skill->id][0]->used_at;
- $cooldownSeconds = $skill->cool_down;
- $secondsSinceLastUse = now()->diffInSeconds($lastUsed);
- $cooldownRemaining = max(0, $cooldownSeconds - $secondsSinceLastUse);
- }
- $result[] = [
- 'skill_id' => $skill->id,
- 'skill_name' => $skill->skill_name,
- 'stamina_cost' => $skill->stamina_cost,
- 'cool_down' => $skill->cool_down,
- 'effect_desc' => $skill->effect_desc,
- 'min_level' => $skill->min_level,
- 'last_used' => $lastUsed ? $lastUsed->format('Y-m-d H:i:s') : null,
- 'cooldown_remaining' => $cooldownRemaining,
- 'is_available' => $cooldownRemaining === 0 && $pet->stamina >= $skill->stamina_cost
- ];
- }
- return $result;
- }
- }
|