feat(hjf): 公排入队可配置,默认关闭时同步发放积分奖励

- 新增 hjf_queue_pool_enable(迁移 SQL),后台公排配置读写统一为该键
- Pay 监听:关闭公排时同步执行等级检查与 PointsRewardServices::reward,开启时仍派发 HjfOrderPayJob
- PointsRewardServices: bcInc 增量传 string,避免 PHP 类型错误
- hjf:patch-rewards 补偿命令补充等级检查与正确的幂等条件
- uniapp vue.config.js 本地 API 代理调整(H5 开发)
- docs/issues-0323-1 更新

Made-with: Cursor
This commit is contained in:
apple
2026-03-25 07:38:12 +08:00
parent d0cd7e4667
commit 6e5bbee71d
7 changed files with 75 additions and 24 deletions

View File

@@ -36,7 +36,7 @@
1. **已修复**点击获取验证,去除安全验证,直接发送验证码
## 佣金记录页面uniapp/pages/users/user_spread_money
1. 团队业绩统计数据的伞下人数不显示
1. **已修复**团队业绩统计数据的伞下人数不显示
---

View File

@@ -3,7 +3,9 @@ declare(strict_types=1);
namespace app\command;
use app\services\agent\AgentLevelServices;
use app\services\hjf\PointsRewardServices;
use app\services\user\UserServices;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
@@ -57,21 +59,22 @@ class HjfPatchMissingRewards extends Command
/** @var PointsRewardServices $pointsService */
$pointsService = app()->make(PointsRewardServices::class);
/** @var AgentLevelServices $agentLevelServices */
$agentLevelServices = app()->make(AgentLevelServices::class);
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$patched = 0;
$skipped = 0;
foreach ($orders as $order) {
// 幂等检查points_release_log 中是否已有 reward_direct/reward_umbrella 记录
$hasRewardLog = Db::name('points_release_log')
->where('order_id', $order['order_id'])
->where('type', 'reward_direct')
->whereIn('type', ['reward_direct', 'reward_umbrella'])
->count();
$hasRewardBill = Db::name('user_bill')
->where('link_id', $order['id'])
->where('type', 'hjf_frozen_direct')
->count();
if ($hasRewardLog > 0 || $hasRewardBill > 0) {
if ($hasRewardLog > 0) {
$skipped++;
$output->writeln(sprintf(' [SKIP] 订单 #%d (%s) 已有积分奖励记录', $order['id'], $order['order_id']));
continue;
@@ -93,11 +96,23 @@ class HjfPatchMissingRewards extends Command
}
try {
$pointsService->reward((int)$order['uid'], (string)$order['order_id'], (int)$order['id']);
$uid = (int)$order['uid'];
// 先执行等级升级检查,确保积分奖励使用正确的 agent_level
$userCacheInfo = $userServices->getUserCacheInfo($uid);
$spreadUid = $userCacheInfo ? (int)($userCacheInfo['spread_uid'] ?? 0) : (int)$order['spread_uid'];
$twoSpreadUid = 0;
if ($spreadUid > 0 && $oneUserInfo = $userServices->getUserCacheInfo($spreadUid)) {
$twoSpreadUid = $userServices->getSpreadUid($spreadUid, $oneUserInfo, false);
}
$uids = array_values(array_filter(array_unique([$uid, $spreadUid, $twoSpreadUid])));
$agentLevelServices->checkUserLevelFinish($uid, $uids);
// 发放积分奖励PointsRewardServices 内部已做幂等检查)
$pointsService->reward($uid, (string)$order['order_id'], (int)$order['id']);
$patched++;
$output->writeln(sprintf(
' [PATCHED] 订单 #%d (%s) 已补发积分奖励',
$order['id'], $order['order_id']
' [PATCHED] 订单 #%d (%s) uid=%d 等级检查+积分奖励已补发',
$order['id'], $order['order_id'], $uid
));
} catch (\Throwable $e) {
$output->writeln(sprintf(

View File

@@ -54,7 +54,7 @@ class QueueController extends AuthController
'trigger_multiple' => (int)SystemConfigService::get('hjf_trigger_multiple', 4),
'release_rate' => (int)SystemConfigService::get('hjf_release_rate', 4),
'withdraw_fee_rate' => (int)SystemConfigService::get('hjf_withdraw_fee_rate', 7),
'enabled' => (bool)SystemConfigService::get('hjf_queue_enabled', 1),
'enabled' => (bool)SystemConfigService::get('hjf_queue_pool_enable', 0),
];
return $this->success($config);
}
@@ -75,7 +75,7 @@ class QueueController extends AuthController
'hjf_trigger_multiple' => (int)$data['trigger_multiple'],
'hjf_release_rate' => (int)$data['release_rate'],
'hjf_withdraw_fee_rate' => (int)$data['withdraw_fee_rate'],
'hjf_queue_enabled' => (int)$data['enabled'],
'hjf_queue_pool_enable' => (int)$data['enabled'],
];
foreach ($map as $key => $value) {

View File

@@ -14,6 +14,8 @@ namespace app\listener\order;
use app\jobs\agent\AgentJob;
use app\jobs\hjf\HjfOrderPayJob;
use app\services\agent\AgentLevelServices;
use app\services\hjf\PointsRewardServices;
use app\jobs\order\OrderCreateAfterJob;
use app\jobs\order\OrderDeliveryJob;
use app\jobs\order\OrderJob;
@@ -149,13 +151,43 @@ class Pay implements ListenerInterface
//对外接口推送事件
event('out.outPush', ['order_pay_push', ['order_id' => (int)$orderInfo['id']]]);
// 公排入队 + 积分奖励 + 等级升级(仅报单商品订单)
// 报单商品订单:等级检查 + 积分奖励 + 公排入队(受 hjf_queue_pool_enable 控制
if (!empty($orderInfo['is_queue_goods'])) {
HjfOrderPayJob::dispatch([
(int)$orderInfo['uid'],
(string)$orderInfo['order_id'],
(float)($orderInfo['pay_price'] ?? 3600.00),
]);
$queuePoolEnable = (int)sys_config('hjf_queue_pool_enable', 0);
if ($queuePoolEnable) {
// 公排模式(开启):异步派发,含公排入队 + 等级检查 + 积分奖励
HjfOrderPayJob::dispatch([
(int)$orderInfo['uid'],
(string)$orderInfo['order_id'],
(float)($orderInfo['pay_price'] ?? 3600.00),
]);
} else {
// 非公排模式(默认关闭):同步执行等级检查 + 积分奖励,不入公排池,不依赖队列
try {
$uid = (int)$orderInfo['uid'];
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userCacheInfo = $userServices->getUserCacheInfo($uid);
$spreadUid = $userCacheInfo ? (int)($userCacheInfo['spread_uid'] ?? 0) : 0;
$twoSpreadUid = 0;
if ($spreadUid > 0 && $oneUserInfo = $userServices->getUserCacheInfo($spreadUid)) {
$twoSpreadUid = $userServices->getSpreadUid($spreadUid, $oneUserInfo, false);
}
$uids = array_filter(array_unique([$uid, $spreadUid, $twoSpreadUid]));
/** @var AgentLevelServices $agentLevelServices */
$agentLevelServices = app()->make(AgentLevelServices::class);
$agentLevelServices->checkUserLevelFinish($uid, array_values($uids));
/** @var PointsRewardServices $pointsService */
$pointsService = app()->make(PointsRewardServices::class);
$pointsService->reward($uid, (string)$orderInfo['order_id'], (int)$orderInfo['id']);
Log::info('[Pay] 同步积分奖励发放完成 uid=' . $uid . ' order_id=' . $orderInfo['id']);
} catch (\Throwable $e) {
Log::error('[Pay] 同步积分奖励失败 order_id=' . $orderInfo['id'] . ': ' . $e->getMessage());
}
}
}
//自动打标签
event('user.auto.label', [$orderInfo['uid'], '', [], []]);

View File

@@ -143,7 +143,7 @@ class PointsRewardServices extends BaseServices
int $orderDbId = 0
): void {
Db::transaction(function () use ($uid, $points, $orderId, $type, $mark, $orderDbId) {
$this->userDao->bcInc($uid, 'frozen_points', $points, 'uid');
$this->userDao->bcInc($uid, 'frozen_points', (string)$points, 'uid');
$this->logDao->save([
'uid' => $uid,

View File

@@ -341,7 +341,11 @@ VALUES
(0, 'hjf_fee_rate', 'text', 'input', 0,
'', 0, '', 100, 0,
'7', '提现手续费率(%)', '申请提现时收取的手续费比例默认7%', 30, 1);
'7', '提现手续费率(%)', '申请提现时收取的手续费比例默认7%', 30, 1),
(0, 'hjf_queue_pool_enable', 'text', 'input', 0,
'', 0, '', 100, 0,
'0', '公排入队开关', '0=关闭(积分同步发放) 1=开启(通过队列异步处理)', 5, 1);
-- ============================================================

View File

@@ -4,15 +4,15 @@ module.exports = {
port: 8080,
proxy: {
'/api': {
target: 'http://127.0.0.1',
target: 'http://127.0.0.1:20199',
changeOrigin: true
},
'/uploads': {
target: 'http://127.0.0.1',
target: 'http://127.0.0.1:20199',
changeOrigin: true
},
'/statics': {
target: 'http://127.0.0.1',
target: 'http://127.0.0.1:20199',
changeOrigin: true
}
}