referralLogic = $referralLogic; } /** * 生成推荐码 * * @param int $userId 用户ID * @param \DateTime|null $expireTime 过期时间 * @return string|null */ public function generateReferralCode(int $userId, ?\DateTime $expireTime = null): ?string { try { // 检查用户是否已有有效的推荐码 $existingCode = $this->getUserActiveCode($userId); if ($existingCode) { return $existingCode->code; } // 生成唯一的推荐码 $code = $this->generateUniqueCode(); // 创建推荐码记录 $referralCode = new TeamReferralCode(); $referralCode->user_id = $userId; $referralCode->code = $code; $referralCode->usage_count = 0; $referralCode->status = REFERRAL_CODE_STATUS::ACTIVE; $referralCode->expire_time = $expireTime; if ($referralCode->save()) { return $code; } return null; } catch (\Exception $e) { Log::error("生成推荐码失败: " . $e->getMessage()); return null; } } /** * 生成唯一的推荐码 * * @param int $length 推荐码长度 * @return string */ private function generateUniqueCode(int $length = 8): string { $attempts = 0; $maxAttempts = 10; do { // 生成随机字符串 $code = strtoupper(Str::random($length)); // 检查是否已存在 $exists = TeamReferralCode::where('code', $code)->exists(); $attempts++; } while ($exists && $attempts < $maxAttempts); // 如果多次尝试后仍然存在冲突,添加时间戳确保唯一性 if ($exists) { $code = strtoupper(substr(Str::random($length - 4), 0, $length - 4) . substr(time(), -4)); } return $code; } /** * 获取用户的有效推荐码 * * @param int $userId 用户ID * @return TeamReferralCode|null */ public function getUserActiveCode(int $userId): ?TeamReferralCode { $code = TeamReferralCode::where('user_id', $userId) ->where('status', REFERRAL_CODE_STATUS::ACTIVE) ->where(function ($query) { $query->whereNull('expire_time') ->orWhere('expire_time', '>', now()); }) ->first(); return $code; } /** * 验证推荐码 * * @param string $code 推荐码 * @return array 包含验证结果和推荐码信息 */ public function validateReferralCode(string $code): array { try { // 查找推荐码 $referralCode = TeamReferralCode::where('code', $code)->first(); if (!$referralCode) { return [ 'valid' => false, 'message' => '推荐码不存在', 'code' => null ]; } // 检查状态 if ($referralCode->status != REFERRAL_CODE_STATUS::ACTIVE) { return [ 'valid' => false, 'message' => '推荐码已禁用', 'code' => $referralCode ]; } // 检查过期时间 if ($referralCode->expire_time && $referralCode->expire_time->isPast()) { return [ 'valid' => false, 'message' => '推荐码已过期', 'code' => $referralCode ]; } return [ 'valid' => true, 'message' => '推荐码有效', 'code' => $referralCode ]; } catch (\Exception $e) { Log::error("验证推荐码失败: " . $e->getMessage()); return [ 'valid' => false, 'message' => '验证推荐码时发生错误', 'code' => null ]; } } /** * 使用推荐码 * * @param string $code 推荐码 * @param int $userId 使用者ID * @param string $ipAddress IP地址 * @param string $userAgent 用户代理 * @return array 包含使用结果和信息 */ public function useReferralCode(string $code, int $userId, string $ipAddress, string $userAgent): array { try { // 验证推荐码 $validation = $this->validateReferralCode($code); if (!$validation['valid']) { return [ 'success' => false, 'message' => $validation['message'] ]; } $referralCode = $validation['code']; // 检查用户是否使用自己的推荐码 if ($referralCode->user_id == $userId) { return [ 'success' => false, 'message' => '不能使用自己的推荐码' ]; } // 检查用户是否已有推荐人 if ($this->referralLogic->hasReferrer($userId)) { return [ 'success' => false, 'message' => '用户已有推荐人,不能使用推荐码' ]; } // 检查是否形成循环推荐 if ($this->referralLogic->checkCircularReferral($userId, $referralCode->user_id)) { return [ 'success' => false, 'message' => '使用此推荐码会形成循环推荐关系' ]; } // 检查事务是否已开启 \UCore\Db\Helper::check_tr(); // 记录使用记录 $usage = new TeamReferralCodeUsage(); $usage->code = $code; $usage->code_owner_id = $referralCode->user_id; $usage->user_id = $userId; $usage->ip_address = $ipAddress; $usage->user_agent = $userAgent; $usage->status = TeamReferralCodeUsage::STATUS_SUCCESS; $usage->result = '成功使用推荐码'; $usage->save(); // 更新推荐码使用次数 $referralCode->usage_count += 1; $referralCode->save(); // 建立推荐关系 $result = $this->referralLogic->createReferralRelation($userId, $referralCode->user_id); if (!$result) { // 如果建立推荐关系失败,更新使用记录状态 $usage->status = TeamReferralCodeUsage::STATUS_FAILED; $usage->result = '建立推荐关系失败'; $usage->save(); return [ 'success' => false, 'message' => '建立推荐关系失败' ]; } return [ 'success' => true, 'message' => '成功使用推荐码并建立推荐关系', 'referrer_id' => $referralCode->user_id ]; } catch (\Exception $e) { Log::error("使用推荐码失败: " . $e->getMessage()); return [ 'success' => false, 'message' => '使用推荐码时发生错误' ]; } } /** * 禁用推荐码 * * @param string $code 推荐码 * @return bool */ public function disableReferralCode(string $code): bool { try { $referralCode = TeamReferralCode::where('code', $code)->first(); if (!$referralCode) { return false; } $referralCode->status = REFERRAL_CODE_STATUS::DISABLED; return $referralCode->save(); } catch (\Exception $e) { Log::error("禁用推荐码失败: " . $e->getMessage()); return false; } } /** * 清理过期的推荐码 * * @return int 清理的数量 */ public function cleanExpiredReferralCodes(): int { try { return TeamReferralCode::where('status', REFERRAL_CODE_STATUS::ACTIVE) ->whereNotNull('expire_time') ->where('expire_time', '<', now()) ->update(['status' => REFERRAL_CODE_STATUS::DISABLED]); } catch (\Exception $e) { Log::error("清理过期推荐码失败: " . $e->getMessage()); return 0; } } }