服务层使用示例.md 19 KB

URS推广模块服务层使用示例

概述

URS推广模块提供了完整的静态服务层架构,支持分离映射关系设计。所有服务都是静态方法,使用简单直接。

服务层架构

UrsUserMappingService (用户映射服务) - 静态方法
UrsReferralService (推荐关系服务) - 静态方法
UrsTalentService (达人等级服务) - 静态方法
UrsRewardDistributionService (奖励分发服务) - 静态方法
UrsTransferFeeService (转账手续费服务) - 静态方法

基础使用

1. 直接调用静态方法

use App\Module\UrsPromotion\Services\UrsUserMappingService;
use App\Module\UrsPromotion\Services\UrsReferralService;
use App\Module\UrsPromotion\Services\UrsTalentService;
use App\Module\UrsPromotion\Services\UrsRewardDistributionService;
use App\Module\UrsPromotion\Services\UrsTransferFeeService;

// 直接调用静态方法,无需实例化
$farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
$referrerId = UrsReferralService::getReferrer($ursUserId);
$talent = UrsTalentService::updateTalentLevel($ursUserId);
$transferFeeRate = UrsTransferFeeService::getBestFeeRateForUser($farmUserId, 'out');

业务场景示例

1. 用户注册流程

// URS用户注册时建立推荐关系
$ursUserId = 1001;
$ursReferrerId = 1000;
$referralCode = 'ABC123'; // 历史推荐码

try {
    $referral = UrsReferralService::createReferral($ursUserId, $ursReferrerId, $referralCode);
    echo "推荐关系建立成功,ID: " . $referral->id;

    // 更新推荐人达人等级
    $referrerTalent = UrsTalentService::updateTalentLevel($ursReferrerId);
    echo "推荐人达人等级: " . $referrerTalent->talent_level;

    // 初始化用户达人等级
    $userTalent = UrsTalentService::updateTalentLevel($ursUserId);
    echo "用户达人等级: " . $userTalent->talent_level;

} catch (\Exception $e) {
    echo "建立失败: " . $e->getMessage();
}

2. 用户进入农场流程

// 用户进入农场时建立映射关系
$ursUserId = 1001;
$farmUserId = 2001;

try {
    $mapping = UrsUserMappingService::createMapping($ursUserId, $farmUserId);
    echo "用户进入农场成功,映射ID: " . $mapping->id;

    // 更新用户达人等级
    $talent = UrsTalentService::updateTalentLevel($ursUserId);
    echo "达人等级: " . $talent->talent_level;

    // 更新推荐人的团队统计
    $referrerId = UrsReferralService::getReferrer($ursUserId);
    if ($referrerId) {
        UrsTalentService::updateTalentLevel($referrerId);
        echo "推荐人团队统计已更新";
    }

} catch (\Exception $e) {
    echo "进入失败: " . $e->getMessage();
}

3. 奖励分发流程

// 用户产生收益时分发奖励
$ursUserId = 1001; // 产生收益的用户
$sourceId = 5001;  // 收益来源ID(如订单ID)
$sourceType = 'order'; // 收益来源类型
$profitType = 'planting_reward'; // 收益类型
$originalAmount = 100.00; // 原始收益金额

// 奖励配置:各层级分成比例
$rewardConfig = [
    1 => 0.10, // 直推10%
    2 => 0.05, // 间推5%
    3 => 0.02, // 三推2%
];

$results = UrsRewardDistributionService::distributeReward(
    $ursUserId,
    $sourceId,
    $sourceType,
    $profitType,
    $originalAmount,
    $rewardConfig
);

echo "奖励分发完成,总分发数量: " . count($results);

$successCount = 0;
$skippedCount = 0;
$totalAmount = 0;

// 查看详细分发结果
foreach ($results as $result) {
    if ($result['status'] === 'success') {
        $successCount++;
        $totalAmount += $result['profit_amount'];
        echo "URS用户 {$result['urs_user_id']} 获得奖励 {$result['profit_amount']}";
    } else {
        $skippedCount++;
        echo "URS用户 {$result['urs_user_id']} 跳过: {$result['reason']}";
    }
}

echo "成功分发: {$successCount}, 跳过数量: {$skippedCount}, 总金额: {$totalAmount}";

单独服务使用示例

1. 用户映射服务 (UrsUserMappingService)

1.1 基础映射操作

// 创建用户映射关系(用户进入农场时)
$ursUserId = 1001;
$farmUserId = 2001;

try {
    $mapping = UrsUserMappingService::createMapping($ursUserId, $farmUserId);
    echo "映射创建成功,ID: " . $mapping->id;
    echo "映射时间: " . $mapping->mappingTime;
} catch (\Exception $e) {
    echo "映射创建失败: " . $e->getMessage();
}

// 检查用户是否已进入农场
$hasEntered = UrsUserMappingService::hasEnteredFarm(1001);
if ($hasEntered) {
    echo "用户已进入农场";
} else {
    echo "用户未进入农场";
}

// 获取农场用户ID
$farmUserId = UrsUserMappingService::getFarmUserId(1001);
if ($farmUserId) {
    echo "农场用户ID: " . $farmUserId;
} else {
    echo "未找到映射关系";
}

// 获取URS用户ID(反向查询)
$ursUserId = UrsUserMappingService::getUrsUserId(2001);
if ($ursUserId) {
    echo "URS用户ID: " . $ursUserId;
} else {
    echo "未找到映射关系";
}

1.2 自动创建用户功能

// 获取或自动创建农场用户(推荐使用)
$ursUserId = 1002;
$farmUserId = UrsUserMappingService::getOrCreateFarmUserId($ursUserId);

if ($farmUserId) {
    echo "农场用户ID: " . $farmUserId;
    echo "用户名格式: urs-" . $ursUserId;
} else {
    echo "创建失败,请检查日志";
}

// 自动创建的用户信息
// 用户名:urs-{ursUserId}
// 密码:随机生成12位字符串
// 状态:自动激活

1.3 批量操作

// 批量获取映射关系
$ursUserIds = [1001, 1002, 1003, 1004];
$mappings = UrsUserMappingService::batchGetFarmUserIds($ursUserIds);

foreach ($mappings as $ursUserId => $farmUserId) {
    echo "URS用户 {$ursUserId} 映射到农场用户 {$farmUserId}";
}

// 获取已进入农场的URS用户列表
$enteredUsers = UrsUserMapping::getEnteredFarmUrsUserIds($ursUserIds);
echo "已进入农场的用户数量: " . count($enteredUsers);

// 批量检查用户状态
foreach ($ursUserIds as $ursUserId) {
    $hasEntered = UrsUserMappingService::hasEnteredFarm($ursUserId);
    echo "URS用户 {$ursUserId}: " . ($hasEntered ? '已进入' : '未进入');
}

1.4 状态管理

// 禁用映射关系
$success = UrsUserMappingService::disableMapping(1001);
if ($success) {
    echo "映射关系已禁用";
} else {
    echo "禁用失败";
}

// 启用映射关系
$success = UrsUserMappingService::enableMapping(1001);
if ($success) {
    echo "映射关系已启用";
} else {
    echo "启用失败";
}

1.5 统计和详情查询

// 获取映射详情
$detail = UrsUserMappingService::getMappingDetail(1001);
if ($detail) {
    echo "URS用户ID: " . $detail->ursUserId;
    echo "农场用户ID: " . $detail->userId;
    echo "映射时间: " . $detail->mappingTime;
    echo "状态: " . ($detail->status ? '有效' : '无效');
}

// 获取映射统计信息
$stats = UrsUserMappingService::getMappingStats();
echo "总映射数: " . $stats['total_mappings'];
echo "有效映射数: " . $stats['valid_mappings'];
echo "无效映射数: " . $stats['invalid_mappings'];
echo "今日新增: " . $stats['today_mappings'];

2. 推荐关系服务

// 获取推荐人
$referrerId = UrsReferralService::getReferrer(1001);

// 获取直推下级
$directReferrals = UrsReferralService::getDirectReferrals(1000);

// 获取推荐关系链(向上查找)
$referralChain = UrsReferralService::getReferralChain(1001, 5);

// 获取团队成员(向下查找)
$teamMembers = UrsReferralService::getTeamMembers(1000, 3);

// 获取推荐统计
$stats = UrsReferralService::getReferralStats(1000);

// 验证推荐关系
$isValid = UrsReferralService::validateReferral(1001);

// 注意:推荐关系的创建现在通过URS同步机制处理
// 使用 UrsReferralSyncLogic::syncReferralRelations() 方法

// 批量更新团队统计
$ursUserIds = [1000, 1001, 1002];
UrsReferralService::batchUpdateTeamStats($ursUserIds);

3. 达人等级服务

// 更新达人等级
$talent = UrsTalentService::updateTalentLevel(1000);

// 获取达人信息
$talentInfo = UrsTalentService::getTalentInfo(1000);

// 检查升级条件
$upgradeCheck = UrsTalentService::checkUpgradeEligibility(1000);

// 获取所有等级配置
$configs = UrsTalentService::getAllTalentConfigs();

// 批量更新达人等级
$ursUserIds = [1000, 1001, 1002];
$batchResults = UrsTalentService::batchUpdateTalentLevels($ursUserIds);

4. 奖励分发服务

// 获取用户奖励统计
$rewardStats = UrsRewardDistributionService::getUserRewardStats(1000);

// 获取跳过的奖励列表
$skippedRewards = UrsRewardDistributionService::getSkippedRewards(1000);

// 分发特定类型奖励
$results = UrsRewardDistributionService::distributeReward(
    1001,           // 产生收益的用户
    5001,           // 收益来源ID
    'order',        // 收益来源类型
    'promotion_reward', // 推广收益
    50.00,          // 原始金额
    [1 => 10.00, 2 => 5.00] // 固定金额配置
);

5. 转账手续费服务 (UrsTransferFeeService)

5.1 基础费率查询

// 获取用户转出费率
$userId = 10001;
$transferOutRate = UrsTransferFeeService::getBestFeeRateForUser($userId, 'out');
echo "用户转出费率: " . ($transferOutRate * 100) . "%";

// 获取用户转入费率
$transferInRate = UrsTransferFeeService::getBestFeeRateForUser($userId, 'in');
echo "用户转入费率: " . ($transferInRate * 100) . "%";

// 直接根据等级计算费率
$houseLevel = 7;
$talentLevel = 3;
$feeRate = UrsTransferFeeService::calculateBestFeeRate($houseLevel, $talentLevel, 'out');
echo "房屋{$houseLevel}级+达人{$talentLevel}级转出费率: " . ($feeRate * 100) . "%";

5.2 转账业务集成

// 转账业务中的费率计算
function processTransfer($userId, $amount, $transferType = 'out') {
    try {
        // 获取用户最优费率
        $feeRate = UrsTransferFeeService::getBestFeeRateForUser($userId, $transferType);

        // 计算手续费
        $feeAmount = $amount * $feeRate;
        $actualAmount = $transferType === 'out' ? $amount - $feeAmount : $amount;

        // 记录转账信息
        $transferInfo = [
            'user_id' => $userId,
            'transfer_type' => $transferType,
            'original_amount' => $amount,
            'fee_rate' => $feeRate,
            'fee_amount' => $feeAmount,
            'actual_amount' => $actualAmount,
        ];

        echo "转账类型: " . ($transferType === 'out' ? '转出' : '转入');
        echo "原始金额: {$amount}";
        echo "手续费率: " . ($feeRate * 100) . "%";
        echo "手续费: {$feeAmount}";
        echo "实际金额: {$actualAmount}";

        return $transferInfo;

    } catch (\Exception $e) {
        echo "费率计算失败: " . $e->getMessage();
        return null;
    }
}

// 使用示例
$transferInfo = processTransfer(10001, 1000, 'out');

5.3 批量费率查询

// 批量查询多个用户的费率
$userIds = [10001, 10002, 10003, 10004];
$transferType = 'out';

$batchRates = [];
foreach ($userIds as $userId) {
    $feeRate = UrsTransferFeeService::getBestFeeRateForUser($userId, $transferType);
    $batchRates[$userId] = $feeRate;
    echo "用户{$userId}的{$transferType}费率: " . ($feeRate * 100) . "%";
}

// 统计费率分布
$rateDistribution = array_count_values($batchRates);
foreach ($rateDistribution as $rate => $count) {
    echo "费率" . ($rate * 100) . "%的用户数量: {$count}";
}

5.4 等级组合费率测试

// 测试不同等级组合的费率
$testCases = [
    ['house' => 0, 'talent' => 0, 'desc' => '新用户默认'],
    ['house' => 7, 'talent' => 0, 'desc' => '房屋7级'],
    ['house' => 10, 'talent' => 0, 'desc' => '房屋10级'],
    ['house' => 12, 'talent' => 0, 'desc' => '房屋12级'],
    ['house' => 0, 'talent' => 1, 'desc' => '初级达人'],
    ['house' => 0, 'talent' => 3, 'desc' => '高级达人'],
    ['house' => 0, 'talent' => 5, 'desc' => '顶级达人'],
    ['house' => 12, 'talent' => 5, 'desc' => '顶级组合'],
];

echo "=== 转出费率测试 ===";
foreach ($testCases as $case) {
    $outRate = UrsTransferFeeService::calculateBestFeeRate(
        $case['house'],
        $case['talent'],
        'out'
    );
    echo "{$case['desc']}: " . ($outRate * 100) . "%";
}

echo "=== 转入费率测试 ===";
foreach ($testCases as $case) {
    $inRate = UrsTransferFeeService::calculateBestFeeRate(
        $case['house'],
        $case['talent'],
        'in'
    );
    echo "{$case['desc']}: " . ($inRate * 100) . "%";
}

5.5 费率变化监控

// 监控用户费率变化
function monitorUserFeeRateChange($userId, $oldHouseLevel, $newHouseLevel, $oldTalentLevel, $newTalentLevel) {
    // 计算变化前的费率
    $oldOutRate = UrsTransferFeeService::calculateBestFeeRate($oldHouseLevel, $oldTalentLevel, 'out');
    $oldInRate = UrsTransferFeeService::calculateBestFeeRate($oldHouseLevel, $oldTalentLevel, 'in');

    // 计算变化后的费率
    $newOutRate = UrsTransferFeeService::calculateBestFeeRate($newHouseLevel, $newTalentLevel, 'out');
    $newInRate = UrsTransferFeeService::calculateBestFeeRate($newHouseLevel, $newTalentLevel, 'in');

    // 计算费率变化
    $outRateChange = $newOutRate - $oldOutRate;
    $inRateChange = $newInRate - $oldInRate;

    echo "用户{$userId}等级变化:";
    echo "房屋等级: {$oldHouseLevel} -> {$newHouseLevel}";
    echo "达人等级: {$oldTalentLevel} -> {$newTalentLevel}";
    echo "转出费率变化: " . ($oldOutRate * 100) . "% -> " . ($newOutRate * 100) . "% (" .
         ($outRateChange >= 0 ? '+' : '') . ($outRateChange * 100) . "%)";
    echo "转入费率变化: " . ($oldInRate * 100) . "% -> " . ($newInRate * 100) . "% (" .
         ($inRateChange >= 0 ? '+' : '') . ($inRateChange * 100) . "%)";

    return [
        'old_out_rate' => $oldOutRate,
        'new_out_rate' => $newOutRate,
        'old_in_rate' => $oldInRate,
        'new_in_rate' => $newInRate,
        'out_rate_change' => $outRateChange,
        'in_rate_change' => $inRateChange,
    ];
}

// 使用示例:用户房屋升级
$rateChange = monitorUserFeeRateChange(10001, 5, 7, 2, 3);

5.6 费率优化建议

// 为用户提供费率优化建议
function getFeeRateOptimizationSuggestion($userId) {
    // 获取用户当前等级信息
    $userInfo = getUserLevelInfo($userId); // 假设这个函数存在
    $currentHouseLevel = $userInfo['house_level'];
    $currentTalentLevel = $userInfo['talent_level'];

    // 获取当前费率
    $currentOutRate = UrsTransferFeeService::calculateBestFeeRate(
        $currentHouseLevel,
        $currentTalentLevel,
        'out'
    );

    $suggestions = [];

    // 检查房屋升级的费率优化
    for ($houseLevel = $currentHouseLevel + 1; $houseLevel <= 12; $houseLevel++) {
        $newOutRate = UrsTransferFeeService::calculateBestFeeRate(
            $houseLevel,
            $currentTalentLevel,
            'out'
        );

        if ($newOutRate < $currentOutRate) {
            $savings = ($currentOutRate - $newOutRate) * 100;
            $suggestions[] = [
                'type' => 'house_upgrade',
                'target_level' => $houseLevel,
                'current_rate' => $currentOutRate * 100,
                'new_rate' => $newOutRate * 100,
                'savings' => $savings,
                'message' => "升级房屋到{$houseLevel}级可节省{$savings}%手续费"
            ];
            break; // 只推荐下一个有优化的等级
        }
    }

    // 检查达人升级的费率优化
    for ($talentLevel = $currentTalentLevel + 1; $talentLevel <= 5; $talentLevel++) {
        $newOutRate = UrsTransferFeeService::calculateBestFeeRate(
            $currentHouseLevel,
            $talentLevel,
            'out'
        );

        if ($newOutRate < $currentOutRate) {
            $savings = ($currentOutRate - $newOutRate) * 100;
            $suggestions[] = [
                'type' => 'talent_upgrade',
                'target_level' => $talentLevel,
                'current_rate' => $currentOutRate * 100,
                'new_rate' => $newOutRate * 100,
                'savings' => $savings,
                'message' => "提升达人等级到{$talentLevel}级可节省{$savings}%手续费"
            ];
            break; // 只推荐下一个有优化的等级
        }
    }

    return $suggestions;
}

// 使用示例
$suggestions = getFeeRateOptimizationSuggestion(10001);
foreach ($suggestions as $suggestion) {
    echo $suggestion['message'];
}

高级使用场景

1. 获取用户完整信息

$completeInfo = $ursService->getUserCompleteInfo(1000);

// 包含以下信息:
// - mapping: 映射关系详情
// - talent: 达人等级信息
// - referral_stats: 推荐关系统计
// - reward_stats: 奖励统计
// - upgrade_eligibility: 升级条件检查

2. 系统统计信息

$systemStats = $ursService->getSystemStats();

// 包含以下统计:
// - mapping_stats: 映射关系统计
// - talent_level_stats: 达人等级分布
// - total_users: 总用户数
// - total_referrals: 总推荐关系数
// - total_profits: 总收益记录数

3. 批量数据同步

$ursUserIds = [1000, 1001, 1002, 1003];
$syncResults = $ursService->batchSyncUserData($ursUserIds);

echo "处理总数: " . $syncResults['total_processed'];
echo "成功数量: " . $syncResults['successful_count'];
echo "失败数量: " . $syncResults['failed_count'];

错误处理

try {
    $result = $ursService->createReferralRelation($ursUserId, $ursReferrerId);
    
    if (!$result['success']) {
        // 业务逻辑错误
        Log::warning('推荐关系建立失败', [
            'urs_user_id' => $ursUserId,
            'error' => $result['error']
        ]);
    }
} catch (\Exception $e) {
    // 系统异常
    Log::error('推荐关系建立异常', [
        'urs_user_id' => $ursUserId,
        'exception' => $e->getMessage()
    ]);
}

最佳实践

  1. 直接调用静态方法:所有服务都是静态方法,无需实例化
  2. 异常处理:使用 try-catch 捕获异常,重要操作都会抛出异常
  3. 日志记录:重要操作都会自动记录日志
  4. 批量操作:大量数据处理时使用批量方法
  5. 事务处理:关键业务流程已内置事务处理
  6. 性能优化:使用批量查询方法减少数据库访问

注意事项

  1. 映射关系:用户必须先进入农场才能获得奖励
  2. 推荐关系:一旦建立不可修改,只能禁用
  3. 达人等级:基于实时团队数据计算
  4. 奖励分发:支持跳过机制,确保奖励链条完整性
  5. 数据一致性:所有关键操作都有事务保护