| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- <?php
- namespace App\Module\AppGame\Handler\Promotion;
- use App\Module\AppGame\Handler\BaseHandler;
- use App\Module\UrsPromotion\Services\UrsUserMappingService;
- use App\Module\UrsPromotion\Services\UrsReferralService;
- use App\Module\UrsPromotion\Services\UrsTalentService;
- use App\Module\UrsPromotion\Models\UrsUserRelationCache;
- use App\Module\UrsPromotion\Models\UrsUserMapping;
- use App\Module\User\Services\UserActivityService;
- use App\Module\User\Models\UserInfo;
- use App\Module\Fund\Enums\FUND_TYPE;
- use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
- use App\Module\Fund\Models\FundLogModel;
- use Google\Protobuf\Internal\Message;
- use Illuminate\Support\Facades\Log;
- use Uraus\Kku\Request\RequestPromotionInfo;
- use Uraus\Kku\Response\ResponsePromotionInfo;
- use Uraus\Kku\Common\Reward;
- use Uraus\Kku\Common\RewardCoin;
- use Uraus\Kku\Common\RewardItem;
- use Carbon\Carbon;
- /**
- * 处理推广团队信息请求
- *
- * 获取用户的推广团队统计信息,包括:
- * - 总人数、直推人数、间推人数
- * - 今日新增统计
- * - 团队活跃人数统计
- * - 达人等级信息
- */
- class InfoHandler extends BaseHandler
- {
- /**
- * 是否需要登录
- *
- * @var bool
- */
- protected bool $need_login = true;
- /**
- * 处理推广团队信息请求
- *
- * @param RequestPromotionInfo $data 推广团队信息请求数据
- * @return ResponsePromotionInfo 推广团队信息响应
- */
- public function handle(Message $data): Message
- {
- // 创建响应对象
- $response = new ResponsePromotionInfo();
- try {
- // 更新用户活动时间
- $this->updateUserActivityTime();
- // 获取当前农场用户对应的URS用户ID
- $ursUserId = UrsUserMappingService::getUrsUserId($this->user_id);
- if (!$ursUserId) {
- // 用户未进入URS推广系统,返回空数据
- Log::info('用户未进入URS推广系统', [
- 'user_id' => $this->user_id
- ]);
- return $this->setEmptyResponse($response);
- }
- // Log::debug('获取推广关系统计 start ', [
- // 'user_id' => $this->user_id
- // ]);
- // // 获取推广关系统计
- // $referralStats = UrsReferralService::getReferralStats($ursUserId);
- //// Log::debug('获取推广关系统计 end ', [
- //// 'user_id' => $this->user_id
- //// ]);
- $t = UrsTalentService::getTalentInfo($this->user_id);
- Log::debug('getTodayStats start ', [
- 'user_id' => $this->user_id
- ]);
- // 获取今日统计数据
- $todayStats = $this->getTodayStats($ursUserId);
- Log::debug('getActiveStats start ', [
- 'user_id' => $this->user_id
- ]);
- // 获取活跃用户统计
- $team_active_count = UrsReferralService::getTeamANumber($this->user_id);
- // 获取收益统计
- $rewardStats = $this->getRewardStats($ursUserId);
- // 获取达人等级信息
- $talentInfo = UrsTalentService::getTalentInfo($this->user_id);
- $starLevel = $talentInfo ? $talentInfo->talentLevel : 0;
- // 设置响应数据
- $response->setTotalCount($t->promotionCount);
- $response->setDirectCount($t->directCount);
- $response->setIndirectCount($t->indirectCount);
- $response->setDayRecentCount($todayStats['team_new_count'] ?? 0);
- $response->setDayDirectCount($todayStats['direct_new_count'] ?? 0);
- $response->setActiveCount($team_active_count);
- // $response->setDirectActiveCount($activeStats['direct_active_count'] ?? 0);
- $response->setStarLevel($starLevel);
- // 设置收益数据 - 始终设置奖励字段,没有数据时使用空奖励对象
- $todayReward = $rewardStats['today_reward'] ?? $this->createEmptyReward();
- $totalReward = $rewardStats['total_reward'] ?? $this->createEmptyReward();
- $response->setTodayReward($todayReward);
- $response->setTotalReward($totalReward);
- Log::info('推广团队信息获取成功', [
- 'user_id' => $this->user_id,
- 'urs_user_id' => $ursUserId,
- 'total_count' => $t->promotionCount,
- 'direct_count' => $t->directCount
- ]);
- } catch (\Exception $e) {
- Log::error('获取推广团队信息失败', [
- 'user_id' => $this->user_id,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- // 发生错误时返回空数据
- return $this->setEmptyResponse($response);
- }
- return $response;
- }
- /**
- * 设置空响应数据
- *
- * @param ResponsePromotionInfo $response
- * @return ResponsePromotionInfo
- */
- private function setEmptyResponse(ResponsePromotionInfo $response): ResponsePromotionInfo
- {
- $response->setTotalCount(0);
- $response->setDirectCount(0);
- $response->setIndirectCount(0);
- $response->setDayRecentCount(0);
- $response->setDayDirectCount(0);
- $response->setActiveCount(0);
- $response->setDirectActiveCount(0);
- $response->setStarLevel(0); // 设置达人等级为0
- // 设置空的奖励对象
- $emptyReward = $this->createEmptyReward();
- $response->setTodayReward($emptyReward);
- $response->setTotalReward($emptyReward);
- return $response;
- }
- /**
- * 创建空的奖励对象
- *
- * @return Reward
- */
- private function createEmptyReward(): Reward
- {
- $reward = new Reward();
- // 设置空的奖励列表
- $reward->setItems([]);
- $reward->setCoins([]);
- $reward->setGods([]);
- $reward->setLands([]);
- $reward->setPets([]);
- $reward->setPetPowers([]);
- $reward->setSkins([]);
- return $reward;
- }
- /**
- * 获取今日统计数据
- *
- * @param int $ursUserId URS用户ID
- * @return array
- */
- private function getTodayStats(int $ursUserId): array
- {
- try {
- // 获取当前用户的农场用户ID
- $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
- if (!$farmUserId) {
- return [
- 'direct_new_count' => 0,
- 'team_new_count' => 0
- ];
- }
- // 使用 UrsUserRelationCache 关联 UrsUserMapping 查询今日新增的用户
- // 基于用户的 mapping_time(进入农场时间)而不是缓存的 created_at 时间
- $todayRelations = UrsUserRelationCache::where('related_user_id', $farmUserId)
- ->join('urs_promotion_user_mappings', 'kku_urs_promotion_user_relation_cache.urs_user_id', '=', 'urs_promotion_user_mappings.urs_user_id')
- ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
- ->whereDate('urs_promotion_user_mappings.mapping_time', today())
- ->selectRaw('
- COUNT(CASE WHEN kku_urs_promotion_user_relation_cache.depth = 1 THEN 1 END) as direct_new_count,
- COUNT(CASE WHEN kku_urs_promotion_user_relation_cache.depth <= 3 THEN 1 END) as team_new_count
- ')
- ->first();
- $directNewCount = $todayRelations->direct_new_count ?? 0;
- $teamNewCount = $todayRelations->team_new_count ?? 0;
- return [
- 'direct_new_count' => (int)$directNewCount,
- 'team_new_count' => (int)$teamNewCount
- ];
- } catch (\Exception $e) {
- Log::error('获取今日统计数据失败', [
- 'urs_user_id' => $ursUserId,
- 'error' => $e->getMessage()
- ]);
- return [
- 'direct_new_count' => 0,
- 'team_new_count' => 0
- ];
- }
- }
- /**
- * 获取活跃用户统计
- *
- * @param int $ursUserId URS用户ID
- * @return array
- */
- private function getActiveStats(int $ursUserId): array
- {
- try {
- // 获取当前用户的农场用户ID
- $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
- if (!$farmUserId) {
- return [
- 'direct_active_count' => 0,
- 'team_active_count' => 0
- ];
- }
- $activeThreshold = Carbon::now()->subHours(24); // 24小时内活跃
- // 使用 UrsUserRelationCache 和 UserInfo 进行 JOIN 查询
- // 一次性获取所有团队成员的活跃状态
- $activeStats = UrsUserRelationCache::where('related_user_id', $farmUserId)
- ->where('depth', '<=', 3) // 只统计前3级
- ->join('kku_user_infos', 'kku_urs_promotion_user_relation_cache.user_id', '=', 'kku_user_infos.user_id')
- ->where('kku_user_infos.last_activity_time', '>=', $activeThreshold)
- ->selectRaw('
- COUNT(CASE WHEN depth = 1 THEN 1 END) as direct_active_count,
- COUNT(*) as team_active_count
- ')
- ->first();
- $directActiveCount = $activeStats->direct_active_count ?? 0;
- $teamActiveCount = $activeStats->team_active_count ?? 0;
- return [
- 'direct_active_count' => (int)$directActiveCount,
- 'team_active_count' => (int)$teamActiveCount
- ];
- } catch (\Exception $e) {
- Log::error('获取活跃用户统计失败', [
- 'urs_user_id' => $ursUserId,
- 'error' => $e->getMessage()
- ]);
- return [
- 'direct_active_count' => 0,
- 'team_active_count' => 0
- ];
- }
- }
- /**
- * 获取收益统计
- *
- * @param int $ursUserId URS用户ID
- * @return array
- */
- private function getRewardStats(int $ursUserId): array
- {
- try {
- // 获取对应的农场用户ID
- $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
- if (!$farmUserId) {
- Log::info('URS用户未映射到农场用户', [ 'urs_user_id' => $ursUserId ]);
- return [
- 'today_reward' => null,
- 'total_reward' => null
- ];
- }
- // 获取今日收益统计
- $today = Carbon::today()->format('Y-m-d');
- $tomorrow = Carbon::tomorrow()->format('Y-m-d');
- $todayStats = $this->getRewardStatsFromLogs($farmUserId, $today, $tomorrow);
- // 获取总收益统计
- $totalStats = $this->getRewardStatsFromLogs($farmUserId);
- // 构建今日收益Reward对象
- $todayReward = null;
- if ($todayStats['total_count'] > 0) {
- $todayReward = $this->buildRewardFromStats($todayStats);
- }
- // 构建总收益Reward对象
- $totalReward = null;
- if ($totalStats['total_count'] > 0) {
- $totalReward = $this->buildRewardFromStats($totalStats);
- }
- return [
- 'today_reward' => $todayReward,
- 'total_reward' => $totalReward
- ];
- } catch (\Exception $e) {
- Log::error('获取收益统计失败', [
- 'urs_user_id' => $ursUserId,
- 'error' => $e->getMessage()
- ]);
- return [
- 'today_reward' => null,
- 'total_reward' => null
- ];
- }
- }
- /**
- * 从物品模块和资金模块的日志中获取收益统计
- *
- * @param int $farmUserId 农场用户ID
- * @param string|null $startDate 开始日期
- * @param string|null $endDate 结束日期
- * @return array
- */
- private function getRewardStatsFromLogs(int $farmUserId, ?string $startDate = null, ?string $endDate = null): array
- {
- $stats = [
- 'total_amount' => 0,
- 'total_count' => 0,
- 'items' => [], // 物品奖励列表
- 'coins' => [], // 代币奖励列表
- 'by_source_type' => []
- ];
- try {
- // URS推广相关的收益来源类型
- $ursPromotionSourceTypes = [
- REWARD_SOURCE_TYPE::URSPROMOTION_HAVEST->value,
- REWARD_SOURCE_TYPE::URSPROMOTION_BACKFILL->value,
- REWARD_SOURCE_TYPE::URSPROMOTION_REWARD->value,
- REWARD_SOURCE_TYPE::URSPROMOTION_REGISTER->value,
- REWARD_SOURCE_TYPE::URSPROMOTION_LEVEL->value,
- ];
- // 1.1. 从物品交易日志表中统计URS推广奖励(补充查询)
- $itemQuery = \App\Module\GameItems\Models\ItemTransactionLog::where('user_id', $farmUserId)
- ->where('transaction_type', 1) // 收入类型
- ->whereIn('source_type', $ursPromotionSourceTypes);
- if ($startDate) {
- $itemQuery->where('created_at', '>=', $startDate);
- }
- if ($endDate) {
- $itemQuery->where('created_at', '<=', $endDate);
- }
- $itemLogs = $itemQuery->get();
- foreach ($itemLogs as $log) {
- $stats['total_count']++;
- $itemId = $log->item_id;
- $quantity = $log->quantity;
- if ($itemId > 0) {
- // 累加相同物品的数量
- if (isset($stats['items'][$itemId])) {
- $stats['items'][$itemId] += $quantity;
- } else {
- $stats['items'][$itemId] = $quantity;
- }
- }
- // 按来源类型统计
- $sourceType = $log->source_type;
- if (!isset($stats['by_source_type'][$sourceType])) {
- $stats['by_source_type'][$sourceType] = [ 'amount' => 0, 'count' => 0 ];
- }
- $stats['by_source_type'][$sourceType]['count']++;
- }
- // 2. 从资金日志表中统计钻石奖励
- $fundQuery = FundLogModel::where('user_id', $farmUserId)
- ->where('fund_id', FUND_TYPE::FUND2->value) // 钻石类型
- ->where('amount', '>', 0) // 只统计收入
- ->where('remark', 'like', '%推广%'); // 包含推广关键词的备注
- if ($startDate) {
- $fundQuery->where('create_time', '>=', strtotime($startDate));
- }
- if ($endDate) {
- $fundQuery->where('create_time', '<=', strtotime($endDate));
- }
- $fundLogs = $fundQuery->get();
- foreach ($fundLogs as $log) {
- $stats['total_count']++;
- $amount = (float)$log->amount;
- // 累加钻石数量
- $fundType = FUND_TYPE::FUND2->value;
- if (isset($stats['coins'][$fundType])) {
- $stats['coins'][$fundType] += $amount;
- } else {
- $stats['coins'][$fundType] = $amount;
- }
- $stats['total_amount'] += $amount;
- // 按备注内容推断来源类型
- $sourceType = $this->inferSourceTypeFromRemark($log->remark);
- if (!isset($stats['by_source_type'][$sourceType])) {
- $stats['by_source_type'][$sourceType] = [ 'amount' => 0, 'count' => 0 ];
- }
- $stats['by_source_type'][$sourceType]['amount'] += $amount;
- $stats['by_source_type'][$sourceType]['count']++;
- }
- } catch (\Exception $e) {
- Log::error('从日志获取收益统计失败', [
- 'farm_user_id' => $farmUserId,
- 'start_date' => $startDate,
- 'end_date' => $endDate,
- 'error' => $e->getMessage()
- ]);
- }
- return $stats;
- }
- /**
- * 从备注推断收益来源类型
- *
- * @param string $remark 备注内容
- * @return string
- */
- private function inferSourceTypeFromRemark(string $remark): string
- {
- if (strpos($remark, '收获') !== false) {
- return REWARD_SOURCE_TYPE::URSPROMOTION_HAVEST->value;
- }
- if (strpos($remark, '补发') !== false) {
- return REWARD_SOURCE_TYPE::URSPROMOTION_BACKFILL->value;
- }
- if (strpos($remark, '注册') !== false) {
- return REWARD_SOURCE_TYPE::URSPROMOTION_REGISTER->value;
- }
- if (strpos($remark, '等级') !== false) {
- return REWARD_SOURCE_TYPE::URSPROMOTION_LEVEL->value;
- }
- return REWARD_SOURCE_TYPE::URSPROMOTION_REWARD->value; // 默认推广奖励
- }
- /**
- * 从统计数据构建Reward对象
- *
- * @param array $stats 统计数据
- * @return Reward
- */
- private function buildRewardFromStats(array $stats): Reward
- {
- $reward = new Reward();
- // 创建物品奖励列表
- $items = [];
- if (!empty($stats['items'])) {
- foreach ($stats['items'] as $itemId => $quantity) {
- $rewardItem = new RewardItem();
- $rewardItem->setItemId($itemId);
- $rewardItem->setInstanceId(0); // 默认为0,表示不指定实例
- $rewardItem->setQuantity($quantity);
- $items[] = $rewardItem;
- }
- }
- // 创建代币奖励列表
- $coins = [];
- if (!empty($stats['coins'])) {
- foreach ($stats['coins'] as $fundType => $amount) {
- $rewardCoin = new RewardCoin();
- $rewardCoin->setType($fundType);
- $rewardCoin->setQuantity((float)$amount);
- $coins[] = $rewardCoin;
- }
- }
- $reward->setItems($items);
- $reward->setCoins($coins);
- // 其他奖励类型暂时为空
- $reward->setGods([]);
- $reward->setLands([]);
- $reward->setPets([]);
- $reward->setPetPowers([]);
- $reward->setSkins([]);
- return $reward;
- }
- }
|