refactor(fsgx): 积分奖励改为按 eb_agent_level 直推/伞下配置值发放

- grantFrozenPointsByBrokerage: 移除「比例×佣金」换算,改为委托
  PointsRewardServices::reward() 按 direct_reward_points /
  umbrella_reward_points 全链路发放 frozen_points
- HjfOrderPayJob: 移除重复的 PointsRewardServices::reward() 调用,
  避免同一笔订单双重发放;Job 仅保留公排入队与等级升级检查

Made-with: Cursor
This commit is contained in:
apple
2026-03-24 14:07:14 +08:00
parent f9ae632f33
commit b5cd96f92b
2 changed files with 26 additions and 41 deletions

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace app\jobs\hjf; namespace app\jobs\hjf;
use app\services\agent\AgentLevelServices; use app\services\agent\AgentLevelServices;
use app\services\hjf\PointsRewardServices;
use app\services\hjf\QueuePoolServices; use app\services\hjf\QueuePoolServices;
use app\services\user\UserServices; use app\services\user\UserServices;
use crmeb\basic\BaseJobs; use crmeb\basic\BaseJobs;
@@ -17,12 +16,14 @@ use think\facade\Log;
* *
* 触发时机Pay 监听器检测到 is_queue_goods=1 时派发。 * 触发时机Pay 监听器检测到 is_queue_goods=1 时派发。
* *
* 执行流程(改造复用版) * 执行流程:
* 1. 调用 QueuePoolServices::enqueue() 将订单写入公排池 * 1. 调用 QueuePoolServices::enqueue() 将订单写入公排池
* 2. 调用 PointsRewardServices::reward() 沿推荐链发放级差积分 * 2. 调用 AgentLevelServices::checkUserLevelFinish() 检查升级
* 3. 调用 AgentLevelServices::checkUserLevelFinish() 检查升级
* (复用 CRMEB 分销等级升级流程,已支持 HJF 任务类型 6/7/8 * (复用 CRMEB 分销等级升级流程,已支持 HJF 任务类型 6/7/8
* *
* 注意:积分奖励(直推/伞下)由 StoreOrderTakeServices::grantFrozenPointsByBrokerage
* 在佣金发放时同步调用 PointsRewardServices::reward(),不在此 Job 中重复执行。
*
* Class HjfOrderPayJob * Class HjfOrderPayJob
* @package app\jobs\hjf * @package app\jobs\hjf
*/ */
@@ -46,14 +47,8 @@ class HjfOrderPayJob extends BaseJobs
return false; return false;
} }
try { // 注意积分奖励PointsRewardServices::reward已由 StoreOrderTakeServices::grantFrozenPointsByBrokerage
/** @var PointsRewardServices $pointsServices */ // 在佣金发放时同步调用,此处不再重复调用,避免双重发放 frozen_points。
$pointsServices = app()->make(PointsRewardServices::class);
$pointsServices->reward($uid, $orderId);
Log::info("[HjfOrderPay] 积分奖励发放完成 uid={$uid} orderId={$orderId}");
} catch (\Throwable $e) {
Log::error("[HjfOrderPay] 积分奖励失败 uid={$uid} orderId={$orderId}: " . $e->getMessage());
}
try { try {
/** @var UserServices $userServices */ /** @var UserServices $userServices */

View File

@@ -22,6 +22,7 @@ use app\services\BaseServices;
use app\services\message\service\StoreServiceServices; use app\services\message\service\StoreServiceServices;
use app\services\message\sms\SmsSendServices; use app\services\message\sms\SmsSendServices;
use app\services\user\member\MemberCardServices; use app\services\user\member\MemberCardServices;
use app\services\hjf\PointsRewardServices;
use app\services\user\UserBillServices; use app\services\user\UserBillServices;
use app\services\user\UserBrokerageServices; use app\services\user\UserBrokerageServices;
use app\services\user\UserServices; use app\services\user\UserServices;
@@ -307,41 +308,30 @@ class StoreOrderTakeServices extends BaseServices
/** /**
* fsgx: 佣金发放后,根据推荐人分销等级给予待释放积分奖励 * fsgx: 佣金发放后,按照 eb_agent_level 配置的「直推/伞下奖励积分」发放 frozen_points
* 积分奖励规则每获得1元佣金发放100积分到 frozen_points可在后台配置调整 *
* @param int $spreadUid 推荐人uid * 积分奖励规则:
* @param string|float $brokeragePrice 本次佣金金额 * - 直推上级:获得其等级 direct_reward_points 配置的积分
* @param array $orderInfo 订单信息 * - 更上级(伞下):按级差规则获得 umbrella_reward_points 积分
* - 具体计算由 PointsRewardServices::reward() 统一实现,同 HjfOrderPayJob 逻辑保持一致
*
* @param int $spreadUid 直推上级uid仅用于前置校验
* @param string|float $brokeragePrice 本次佣金金额(前置校验用)
* @param array $orderInfo 订单信息(需含 uid、order_id
*/ */
protected function grantFrozenPointsByBrokerage(int $spreadUid, $brokeragePrice, array $orderInfo): void protected function grantFrozenPointsByBrokerage(int $spreadUid, $brokeragePrice, array $orderInfo): void
{ {
try { try {
if ($spreadUid <= 0 || $brokeragePrice <= 0) return; if ($spreadUid <= 0 || $brokeragePrice <= 0) return;
/** @var UserServices $userServices */ $buyerUid = (int)($orderInfo['uid'] ?? 0);
$userServices = app()->make(UserServices::class); $orderId = (string)($orderInfo['order_id'] ?? '');
$spreadUser = $userServices->get($spreadUid, ['uid', 'agent_level', 'frozen_points']); if ($buyerUid <= 0 || $orderId === '') return;
// 只有拥有分销等级(创客及以上 agent_level > 0的用户才获得积分
if (!$spreadUser || (int)($spreadUser['agent_level'] ?? 0) <= 0) return; /** @var PointsRewardServices $pointsServices */
// 积分换算每1元佣金 → 100积分可通过后台配置 brokerage_points_ratio 调整 $pointsServices = app()->make(PointsRewardServices::class);
$pointsRatio = (int)sys_config('brokerage_points_ratio', 100); $pointsServices->reward($buyerUid, $orderId);
$points = (int)bcmul((string)$brokeragePrice, (string)$pointsRatio, 0);
if ($points <= 0) return;
// 写入 frozen_points
$userServices->bcInc($spreadUid, 'frozen_points', $points, 'uid');
// 写积分日志(使用 UserBill
/** @var \app\services\user\UserBillServices $userBillServices */
$userBillServices = app()->make(\app\services\user\UserBillServices::class);
$userBillServices->income('frozen_points_brokerage', $spreadUid, [
'number' => $points,
'mark' => '推荐佣金赠积分,订单号:' . ($orderInfo['order_id'] ?? ''),
'balance' => (int)(($spreadUser['frozen_points'] ?? 0) + $points),
'type' => 'integral',
'title' => '推荐佣金',
'pm' => 1,
], (int)(($spreadUser['frozen_points'] ?? 0) + $points), $orderInfo['id'] ?? 0);
} catch (\Throwable $e) { } catch (\Throwable $e) {
// 积分发放失败不影响主流程 Log::error('fsgx grantFrozenPointsByBrokerage error: ' . $e->getMessage());
\think\facade\Log::error('fsgx grantFrozenPointsByBrokerage error: ' . $e->getMessage());
} }
} }