From d0cd7e4667380cca09c0a52c72d8dfd1277f62c8 Mon Sep 17 00:00:00 2001 From: mac Date: Tue, 24 Mar 2026 23:27:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(fsgx):=20=E4=BC=9E=E4=B8=8B=E4=BA=BA?= =?UTF-8?q?=E6=95=B0=E4=B8=8E=E5=BE=85=E9=87=8A=E6=94=BE=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E5=8F=91=E6=94=BE=E9=93=BE=E8=B7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - spread/people 增加 umbrellaCount、umbrellaOrderCount;MemberLevelServices 递归统计伞下人数 - 佣金记录页使用新字段展示团队业绩 - 报单积分改由 HjfOrderPayJob 在等级升级后发放,避免 grade=0 时序问题 - PointsRewardServices::reward 按 points_release_log 幂等防重复 - 移除 backOrderBrokerage 内同步 grantFrozenPointsByBrokerage Made-with: Cursor --- docs/Untitled | 9 ------ docs/issues-0323-1.md | 12 ++++---- pro_v3.5.1/app/jobs/hjf/HjfOrderPayJob.php | 29 ++++++++++++++----- .../app/services/hjf/MemberLevelServices.php | 26 +++++++++++++++++ .../app/services/hjf/PointsRewardServices.php | 10 +++++++ .../services/order/StoreOrderTakeServices.php | 6 ++-- pro_v3.5.1/app/services/user/UserServices.php | 4 +++ .../pages/users/user_spread_money/index.vue | 4 +-- 8 files changed, 73 insertions(+), 27 deletions(-) delete mode 100644 docs/Untitled diff --git a/docs/Untitled b/docs/Untitled deleted file mode 100644 index 08a4f5de..00000000 --- a/docs/Untitled +++ /dev/null @@ -1,9 +0,0 @@ -🔄 公排模块(3页) ⭐ 全新设计 -│ ├── P12 公排状态页 QueueStatus -│ ├── P13 公排历史记录 QueueHistory -│ └── P14 公排规则说明 QueueRules -├── 💰 资产模块(4页) ⭐ 全新/改造 -│ ├── P15 我的资产总览 Assets -│ ├── P16 提现页 Withdraw -│ ├── P17 余额明细 BalanceDetail -│ └── P18 积分明细 PointsDetail \ No newline at end of file diff --git a/docs/issues-0323-1.md b/docs/issues-0323-1.md index 5f2fdb4c..d3a7e4c0 100644 --- a/docs/issues-0323-1.md +++ b/docs/issues-0323-1.md @@ -21,7 +21,7 @@ ## 定时任务页面,路径:/admin/system/crontab 1. **已修复**增加“手动触发”功能按钮,可以手动触发即执行任务立, -2. 手动触发“fsgx每日积分释放”任务失败, +2. **已修复**手动触发“fsgx每日积分释放”任务失败, ## 用户列表页面,路径:/admin/user/list @@ -36,7 +36,7 @@ 1. **已修复**点击获取验证,去除安全验证,直接发送验证码 ## 佣金记录页面,uniapp/pages/users/user_spread_money -1. 团队业绩统计数据不显示 +1. 团队业绩统计数据的伞下人数不显示 --- @@ -54,8 +54,10 @@ ## 手动测试问题 -1. 排查原因:eb_store_order中id=11在管理后台中的2个页面看不到返现佣金明细和奖励积分明细, +1. 排查原因:eb_store_order报单商品订单完成后在管理后台中的2个页面看不到奖励积分明细, 2. 积分日志页面/admin/marketing/user_point/index看不到奖励积分明细, -3. **已修复**佣金记录页面/admin/finance/finance/commission中用户返现佣金记录详情中看不到返现佣金明细 -4. **相关文件**:`docs/PRD_fsgx_V1.0.md` `docs/page-dev-specs-fsgx.md`, +3. 推荐人会员(直推积分奖励、伞下积分奖励获得者)的待释放积分(`frozen_points`)的值没有update, +4. 同时没有记录报单商品订单产生的待释放积分明细记录:eb_user_bill表中status=0,type=integral,title=直推积分奖励 | 伞下积分奖励 +5. **已修复**佣金记录页面/admin/finance/finance/commission中用户返现佣金记录详情中看不到返现佣金明细 +6. **相关文件**:`docs/PRD_fsgx_V1.0.md` `docs/page-dev-specs-fsgx.md`, diff --git a/pro_v3.5.1/app/jobs/hjf/HjfOrderPayJob.php b/pro_v3.5.1/app/jobs/hjf/HjfOrderPayJob.php index d3fa42c7..d8d1db18 100644 --- a/pro_v3.5.1/app/jobs/hjf/HjfOrderPayJob.php +++ b/pro_v3.5.1/app/jobs/hjf/HjfOrderPayJob.php @@ -4,11 +4,13 @@ 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; /** @@ -18,11 +20,10 @@ use think\facade\Log; * * 执行流程: * 1. 调用 QueuePoolServices::enqueue() 将订单写入公排池 - * 2. 调用 AgentLevelServices::checkUserLevelFinish() 检查升级 + * 2. 调用 AgentLevelServices::checkUserLevelFinish() 检查等级升级 * (复用 CRMEB 分销等级升级流程,已支持 HJF 任务类型 6/7/8) - * - * 注意:积分奖励(直推/伞下)由 StoreOrderTakeServices::grantFrozenPointsByBrokerage - * 在佣金发放时同步调用 PointsRewardServices::reward(),不在此 Job 中重复执行。 + * 3. 等级升级完成后调用 PointsRewardServices::reward() 发放积分奖励 + * (必须在升级后执行,确保级差计算使用正确的 agent_level) * * Class HjfOrderPayJob * @package app\jobs\hjf @@ -47,9 +48,6 @@ class HjfOrderPayJob extends BaseJobs return false; } - // 注意:积分奖励(PointsRewardServices::reward)已由 StoreOrderTakeServices::grantFrozenPointsByBrokerage - // 在佣金发放时同步调用,此处不再重复调用,避免双重发放 frozen_points。 - try { /** @var UserServices $userServices */ $userServices = app()->make(UserServices::class); @@ -70,6 +68,23 @@ class HjfOrderPayJob extends BaseJobs Log::error("[HjfOrderPay] 等级升级检查失败 uid={$uid}: " . $e->getMessage()); } + // 等级升级完成后发放积分奖励(确保使用升级后的 agent_level) + try { + $orderRow = Db::name('store_order') + ->where('order_id', $orderId) + ->where('is_queue_goods', 1) + ->field('id,uid,is_queue_goods') + ->find(); + if ($orderRow) { + /** @var PointsRewardServices $pointsService */ + $pointsService = app()->make(PointsRewardServices::class); + $pointsService->reward($uid, $orderId, (int)$orderRow['id']); + Log::info("[HjfOrderPay] 积分奖励发放完成 uid={$uid} orderId={$orderId}"); + } + } catch (\Throwable $e) { + Log::error("[HjfOrderPay] 积分奖励发放失败 uid={$uid} orderId={$orderId}: " . $e->getMessage()); + } + return true; } } diff --git a/pro_v3.5.1/app/services/hjf/MemberLevelServices.php b/pro_v3.5.1/app/services/hjf/MemberLevelServices.php index 9fd556c4..06dbef40 100644 --- a/pro_v3.5.1/app/services/hjf/MemberLevelServices.php +++ b/pro_v3.5.1/app/services/hjf/MemberLevelServices.php @@ -111,6 +111,32 @@ class MemberLevelServices extends BaseServices return $this->agentLevelTaskServices->getUmbrellaQueueOrderCount($uid); } + /** + * 递归统计伞下总人数(DFS,最大深度 8 层,不含本人) + */ + public function getUmbrellaMemberCount(int $uid, int $maxDepth = 8): int + { + return $this->recursiveUmbrellaMemberCount($uid, $maxDepth); + } + + private function recursiveUmbrellaMemberCount(int $uid, int $remainDepth): int + { + if ($remainDepth <= 0) { + return 0; + } + $children = Db::name('user') + ->where('spread_uid', $uid) + ->column('uid'); + if (empty($children)) { + return 0; + } + $count = count($children); + foreach ($children as $childUid) { + $count += $this->recursiveUmbrellaMemberCount((int)$childUid, $remainDepth - 1); + } + return $count; + } + /** * 手动设置会员等级(管理后台使用) * diff --git a/pro_v3.5.1/app/services/hjf/PointsRewardServices.php b/pro_v3.5.1/app/services/hjf/PointsRewardServices.php index 7475a320..6c01d370 100644 --- a/pro_v3.5.1/app/services/hjf/PointsRewardServices.php +++ b/pro_v3.5.1/app/services/hjf/PointsRewardServices.php @@ -45,6 +45,16 @@ class PointsRewardServices extends BaseServices public function reward(int $orderUid, string $orderId, int $orderDbId = 0): void { try { + // 幂等检查:若该订单已有积分奖励记录则跳过,防止重复发放 + $exists = Db::name('points_release_log') + ->where('order_id', $orderId) + ->whereIn('type', ['reward_direct', 'reward_umbrella']) + ->count(); + if ($exists > 0) { + Log::info("[PointsReward] 订单 {$orderId} 已有积分奖励记录,跳过重复发放"); + return; + } + $buyer = $this->userDao->get($orderUid); if (!$buyer || !$buyer['spread_uid']) { return; diff --git a/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php b/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php index a168f4c0..825f7ee3 100644 --- a/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php +++ b/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php @@ -276,10 +276,8 @@ class StoreOrderTakeServices extends BaseServices //订单中取出 $brokeragePrice = $orderInfo['one_brokerage'] ?? 0; - // fsgx: 积分奖励独立于佣金金额,只要是报单订单且推荐人存在就触发 - if ($isQueueOrder && $one_spread_uid > 0) { - $this->grantFrozenPointsByBrokerage($one_spread_uid, $brokeragePrice, $orderInfo); - } + // fsgx: 积分奖励已移至 HjfOrderPayJob(等级升级完成后触发),此处不再触发 + // 避免推荐人升级前 grade=0 导致积分被跳过的时序问题 // 返佣金额小于等于0 直接返回不返佣金 if ($brokeragePrice <= 0) { diff --git a/pro_v3.5.1/app/services/user/UserServices.php b/pro_v3.5.1/app/services/user/UserServices.php index f0f3817d..64f34568 100644 --- a/pro_v3.5.1/app/services/user/UserServices.php +++ b/pro_v3.5.1/app/services/user/UserServices.php @@ -2533,9 +2533,12 @@ class UserServices extends BaseServices } $spread_one_ids = $this->getUserSpredadUids($uid, 1); $spread_two_ids = $this->getUserSpredadUids($uid, 2); + /** @var \app\services\hjf\MemberLevelServices $memberLevelServices */ + $memberLevelServices = app()->make(\app\services\hjf\MemberLevelServices::class); $data = [ 'total' => count($spread_one_ids), 'totalLevel' => count($spread_two_ids), + 'umbrellaCount' => $memberLevelServices->getUmbrellaMemberCount($uid), 'list' => [] ]; /** @var UserStoreOrderServices $userStoreOrder */ @@ -2556,6 +2559,7 @@ class UserServices extends BaseServices } $data['list'] = $list; $data['brokerage_level'] = (int)sys_config('brokerage_level', 2); + $data['umbrellaOrderCount'] = $memberLevelServices->getUmbrellaQueueOrderCount($uid); $data['count'] = 0; $data['price'] = 0; $data['order_count'] = 0; diff --git a/pro_v3.5.1/view/uniapp/pages/users/user_spread_money/index.vue b/pro_v3.5.1/view/uniapp/pages/users/user_spread_money/index.vue index 0d500e98..c87a9c57 100644 --- a/pro_v3.5.1/view/uniapp/pages/users/user_spread_money/index.vue +++ b/pro_v3.5.1/view/uniapp/pages/users/user_spread_money/index.vue @@ -233,8 +233,8 @@ const d = (res && res.data) || {}; this.teamData = { direct_count: d.total || 0, - umbrella_count: d.totalLevel || 0, - umbrella_orders: d.order_count || 0, + umbrella_count: d.umbrellaCount !== undefined ? d.umbrellaCount : (d.totalLevel || 0), + umbrella_orders: d.umbrellaOrderCount !== undefined ? d.umbrellaOrderCount : (d.order_count || 0), }; }).catch(() => {});