Files
huangjingfen/pro_v3.5.1/app/jobs/hjf/HjfOrderPayJob.php
panchengyong 364d5333d7 fix(hjf): 保单商品多份购买分润计算全链路修复
- 公排入队:按件数拆分为 N 条独立记录,每条单份金额,逐条触发退款检测
- 周期佣金:位次统计改为按报单商品总件数(cart_num 之和),而非订单数
- 分销等级任务:type 6/7 订单数统计改为按 cart_num 累计保单商品份数
- 推荐返佣与积分奖励:验证 cart_num 倍乘逻辑正确

Made-with: Cursor
2026-04-06 02:40:01 +08:00

127 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\jobs\hjf;
use app\services\agent\AgentLevelServices;
use app\services\hjf\PointsRewardServices;
use app\services\hjf\QueuePoolServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Log;
/**
* 报单商品支付成功异步处理 Job
*
* 触发时机Pay 监听器检测到 is_queue_goods=1 时派发。
*
* 执行流程:
* 1. 调用 QueuePoolServices::enqueue() 将订单写入公排池
* 2. 调用 AgentLevelServices::checkUserLevelFinish() 检查等级升级
* (复用 CRMEB 分销等级升级流程,已支持 HJF 任务类型 6/7/8
* 3. 等级升级完成后调用 PointsRewardServices::reward() 发放积分奖励
* (必须在升级后执行,确保级差计算使用正确的 agent_level
*
* Class HjfOrderPayJob
* @package app\jobs\hjf
*/
class HjfOrderPayJob extends BaseJobs
{
use QueueTrait;
public function doJob(int $uid, string $orderId, float $amount = 3600.00): bool
{
// 先查订单与购物车,计算报单商品总件数(公排入队 + 积分奖励共用)
$orderRow = Db::name('store_order')
->where('order_id', $orderId)
->where('is_queue_goods', 1)
->field('id,uid,is_queue_goods')
->find();
$queueQty = 1;
if ($orderRow) {
try {
$cartRows = Db::name('store_order_cart_info')
->where('oid', (int)$orderRow['id'])
->column('cart_info');
$qtySum = 0;
foreach ($cartRows as $row) {
$item = is_string($row) ? json_decode($row, true) : $row;
if (!empty($item['productInfo']['is_queue_goods'])) {
$qtySum += (int)($item['cart_num'] ?? 1);
}
}
if ($qtySum > 0) {
$queueQty = $qtySum;
}
} catch (\Throwable $qe) {
Log::warning("[HjfOrderPay] 计算报单商品数量异常使用默认值1: " . $qe->getMessage());
}
}
// PRD §3.1.2:一次购买多份时,拆分为多个独立记录分别进入公排池
$unitAmount = $queueQty > 1 ? round($amount / $queueQty, 2) : $amount;
try {
/** @var QueuePoolServices $queueServices */
$queueServices = app()->make(QueuePoolServices::class);
for ($i = 0; $i < $queueQty; $i++) {
$subOrderId = $queueQty > 1 ? $orderId . '-' . ($i + 1) : $orderId;
$queueServices->enqueue($uid, $subOrderId, $unitAmount);
}
Log::info("[HjfOrderPay] 公排入队成功 uid={$uid} orderId={$orderId} qty={$queueQty} unitAmount={$unitAmount}");
} catch (ValidateException $e) {
Log::warning("[HjfOrderPay] 入队被锁,延迟重试 uid={$uid} orderId={$orderId}: " . $e->getMessage());
static::dispatchSece(5, [$uid, $orderId, $amount]);
return true;
} catch (\Throwable $e) {
Log::error("[HjfOrderPay] 公排入队异常 uid={$uid} orderId={$orderId}: " . $e->getMessage());
return false;
}
$preUpgradeLevels = [];
try {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->getUserCacheInfo($uid);
$spreadUid = $userInfo ? (int)($userInfo['spread_uid'] ?? 0) : 0;
$twoSpreadUid = 0;
if ($spreadUid > 0 && $oneUserInfo = $userServices->getUserCacheInfo($spreadUid)) {
$twoSpreadUid = $userServices->getSpreadUid($spreadUid, $oneUserInfo, false);
}
$uids = array_unique([$uid, $spreadUid, $twoSpreadUid]);
// fsgx B2在升级前快照各上级用户的 agent_level避免触发升级的那笔订单发放积分
foreach ($uids as $u) {
if ($u <= 0) continue;
$uInfo = $userServices->get((int)$u, ['uid', 'agent_level']);
$preUpgradeLevels[(int)$u] = $uInfo ? (int)($uInfo['agent_level'] ?? 0) : 0;
}
/** @var AgentLevelServices $agentLevelServices */
$agentLevelServices = app()->make(AgentLevelServices::class);
$agentLevelServices->checkUserLevelFinish($uid, $uids);
Log::info("[HjfOrderPay] 等级升级检查完成 uid={$uid}");
} catch (\Throwable $e) {
Log::error("[HjfOrderPay] 等级升级检查失败 uid={$uid}: " . $e->getMessage());
}
// 等级升级完成后发放积分奖励(确保使用升级后的 agent_level
if ($orderRow) {
try {
/** @var PointsRewardServices $pointsService */
$pointsService = app()->make(PointsRewardServices::class);
$pointsService->reward($uid, $orderId, (int)$orderRow['id'], $preUpgradeLevels, $queueQty);
Log::info("[HjfOrderPay] 积分奖励发放完成 uid={$uid} orderId={$orderId} qty={$queueQty}");
} catch (\Throwable $e) {
Log::error("[HjfOrderPay] 积分奖励发放失败 uid={$uid} orderId={$orderId}: " . $e->getMessage());
}
}
return true;
}
}