diff --git a/docs/PRD_fsgx_V1.0.md b/docs/PRD_fsgx_V1.0.md index 7af2ac13..84fa25f2 100644 --- a/docs/PRD_fsgx_V1.0.md +++ b/docs/PRD_fsgx_V1.0.md @@ -97,7 +97,11 @@ - 返现基数(按实付金额/按固定金额) - 返现发放时机(支付即发放/确认收货后) -#### 3.1.3 异常与边界 +#### 3.1.3 返现佣金记录 +- 同时记录报单商品订单产生的推荐人佣金明细记录:eb_user_brokerage表中status=1,type=get_brokerage,title=推广佣金 + + +#### 3.1.4 异常与边界 - 退款/撤单后,需回滚对应返现及进度 - 同设备/同账号异常刷单需支持风控拦截 diff --git a/docs/issues-0323-1.md b/docs/issues-0323-1.md index db69c400..c0328f25 100644 --- a/docs/issues-0323-1.md +++ b/docs/issues-0323-1.md @@ -33,6 +33,10 @@ ## 修改密码页面 1. **已修复**点击获取验证,去除安全验证,直接发送验证码 +## 佣金记录页面,uniapp/pages/users/user_spread_money +1. 团队业绩统计数据不显示 + + --- # 测试 diff --git a/pro_v3.5.1/app/listener/order/Pay.php b/pro_v3.5.1/app/listener/order/Pay.php index 3b865b78..7ba1fd64 100644 --- a/pro_v3.5.1/app/listener/order/Pay.php +++ b/pro_v3.5.1/app/listener/order/Pay.php @@ -240,11 +240,17 @@ class Pay implements ListenerInterface } // fsgx: 报单商品(is_queue_goods=1)需要参与周期佣金计算,不受 type=8 限制 $isQueueOrder = !empty($orderInfo['is_queue_goods']); + // 人人分销(2) 或 报单订单:一级/二级佣金写入订单,不因推荐人未标记推广员而丢失(PRD 返现可审计) + $relaxBrokeragePromoter = $isQueueOrder || (int)sys_config('store_brokerage_statu', 1) === 2; if ($cartInfo && (isset($orderInfo['type']) && (!in_array($orderInfo['type'], [4, 5, 7, 8]) || $isQueueOrder))) { /** @var StoreOrderComputedServices $orderComputed */ $orderComputed = app()->make(StoreOrderComputedServices::class); - if ($userServices->checkUserPromoter($spread_uid)) $orderData['one_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'one_brokerage', false); - if ($userServices->checkUserPromoter($spread_two_uid)) $orderData['two_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'two_brokerage', false); + if ($spread_uid > 0 && ($relaxBrokeragePromoter || $userServices->checkUserPromoter($spread_uid))) { + $orderData['one_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'one_brokerage', false); + } + if ($spread_two_uid > 0 && ($relaxBrokeragePromoter || $userServices->checkUserPromoter($spread_two_uid))) { + $orderData['two_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'two_brokerage', false); + } $orderData['division_staff_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_staff_brokerage', false); $orderData['division_agent_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_agent_brokerage', false); $orderData['division_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_brokerage', false); diff --git a/pro_v3.5.1/app/services/hjf/PointsRewardServices.php b/pro_v3.5.1/app/services/hjf/PointsRewardServices.php index c1cdfa23..7475a320 100644 --- a/pro_v3.5.1/app/services/hjf/PointsRewardServices.php +++ b/pro_v3.5.1/app/services/hjf/PointsRewardServices.php @@ -7,6 +7,7 @@ use app\dao\hjf\PointsReleaseLogDao; use app\dao\user\UserDao; use app\services\agent\AgentLevelServices; use app\services\BaseServices; +use app\services\user\UserBillServices; use think\annotation\Inject; use think\facade\Db; use think\facade\Log; @@ -33,17 +34,22 @@ class PointsRewardServices extends BaseServices #[Inject] protected AgentLevelServices $agentLevelServices; + #[Inject] + protected UserBillServices $userBillServices; + /** * 对一笔报单订单发放积分奖励 + * + * @param int $orderDbId 订单表主键 id,用于 user_bill.link_id 关联后台订单 */ - public function reward(int $orderUid, string $orderId): void + public function reward(int $orderUid, string $orderId, int $orderDbId = 0): void { try { $buyer = $this->userDao->get($orderUid); if (!$buyer || !$buyer['spread_uid']) { return; } - $this->propagateReward($buyer['spread_uid'], $orderUid, $orderId, 0); + $this->propagateReward($buyer['spread_uid'], $orderUid, $orderId, 0, 0, $orderDbId); } catch (\Throwable $e) { Log::error("[PointsReward] 积分奖励失败 orderUid={$orderUid} orderId={$orderId}: " . $e->getMessage()); } @@ -63,7 +69,8 @@ class PointsRewardServices extends BaseServices int $fromUid, string $orderId, int $lowerReward, - int $depth = 0 + int $depth = 0, + int $orderDbId = 0 ): void { if ($depth >= 10 || $uid <= 0) { return; @@ -79,7 +86,7 @@ class PointsRewardServices extends BaseServices if ($grade === 0) { if ($user['spread_uid']) { - $this->propagateReward((int)$user['spread_uid'], $uid, $orderId, 0, $depth + 1); + $this->propagateReward((int)$user['spread_uid'], $uid, $orderId, 0, $depth + 1, $orderDbId); } return; } @@ -97,7 +104,8 @@ class PointsRewardServices extends BaseServices $actual, $orderId, $isDirect ? 'reward_direct' : 'reward_umbrella', - ($isDirect ? '直推奖励' : '伞下奖励(级差)') . " - 来源订单 {$orderId}" + ($isDirect ? '直推奖励' : '伞下奖励(级差)') . " - 来源订单 {$orderId}", + $orderDbId ); } @@ -107,7 +115,8 @@ class PointsRewardServices extends BaseServices $uid, $orderId, $reward, - $depth + 1 + $depth + 1, + $orderDbId ); } } @@ -115,9 +124,15 @@ class PointsRewardServices extends BaseServices /** * 写入待释放积分(frozen_points)并记录明细 */ - private function grantFrozenPoints(int $uid, int $points, string $orderId, string $type, string $mark): void - { - Db::transaction(function () use ($uid, $points, $orderId, $type, $mark) { + private function grantFrozenPoints( + int $uid, + int $points, + string $orderId, + string $type, + string $mark, + int $orderDbId = 0 + ): void { + Db::transaction(function () use ($uid, $points, $orderId, $type, $mark, $orderDbId) { $this->userDao->bcInc($uid, 'frozen_points', $points, 'uid'); $this->logDao->save([ @@ -130,6 +145,11 @@ class PointsRewardServices extends BaseServices 'status' => 'frozen', 'order_id' => $orderId, ]); + + // PRD §3.3:营销后台积分日志读 eb_user_bill,双写待释放积分明细(不增加可消费 integral) + $integralBalance = (int)($this->userDao->value(['uid' => $uid], 'integral') ?: 0); + $billType = ($type === 'reward_direct') ? 'hjf_reward_direct_integral' : 'hjf_reward_umbrella_integral'; + $this->userBillServices->income($billType, $uid, $points, $integralBalance, $orderDbId, 0, $mark); }); } } diff --git a/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php b/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php index a2fd1824..ba594882 100644 --- a/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php +++ b/pro_v3.5.1/app/services/order/StoreOrderTakeServices.php @@ -243,6 +243,7 @@ class StoreOrderTakeServices extends BaseServices // 营销产品不返佣金;但报单商品(is_queue_goods=1)无论 type 均需参与返佣 $isQueueOrder = !empty($orderInfo['is_queue_goods']); + $relaxBrokeragePromoter = $isQueueOrder || (int)sys_config('store_brokerage_statu', 1) === 2; if (!$isQueueOrder && (!isset($orderInfo['type']) || in_array($orderInfo['type'], [4, 5, 7, 8]))) { return true; } @@ -266,10 +267,10 @@ class StoreOrderTakeServices extends BaseServices $broken_time = intval(sys_config('extract_time')); $frozen_time = time() + $broken_time * 86400; - //检测是否是分销员 + //检测是否是分销员(报单/人人分销时不强制要求 is_promoter,否则周期返现与积分奖励无法落库) /** @var UserServices $userServices */ $userServices = app()->make(UserServices::class); - if (!$userServices->checkUserPromoter($one_spread_uid)) {//一级不是分销员 直接二级返佣 + if (!$relaxBrokeragePromoter && !$userServices->checkUserPromoter($one_spread_uid)) {//一级不是分销员 直接二级返佣 return $this->backOrderBrokerageTwo($orderInfo, $userInfo, $isSelfBrokerage, $frozen_time); } //订单中取出 @@ -327,9 +328,11 @@ class StoreOrderTakeServices extends BaseServices $orderId = (string)($orderInfo['order_id'] ?? ''); if ($buyerUid <= 0 || $orderId === '') return; + $orderDbId = (int)($orderInfo['id'] ?? 0); + /** @var PointsRewardServices $pointsServices */ $pointsServices = app()->make(PointsRewardServices::class); - $pointsServices->reward($buyerUid, $orderId); + $pointsServices->reward($buyerUid, $orderId, $orderDbId); } catch (\Throwable $e) { Log::error('fsgx grantFrozenPointsByBrokerage error: ' . $e->getMessage()); } @@ -367,8 +370,9 @@ class StoreOrderTakeServices extends BaseServices $spread_two_uid = $isSelfbrokerage ? $userInfoTwo['uid'] : $userInfoTwo['spread_uid']; } $spread_two_uid = (int)$spread_two_uid; - // 获取后台分销类型 1 指定分销 2 人人分销 - if (!$userServices->checkUserPromoter($spread_two_uid)) { + $isQueueOrder = !empty($orderInfo['is_queue_goods']); + $relaxBrokeragePromoter = $isQueueOrder || (int)sys_config('store_brokerage_statu', 1) === 2; + if (!$relaxBrokeragePromoter && !$userServices->checkUserPromoter($spread_two_uid)) { return true; } //订单中取出 diff --git a/pro_v3.5.1/app/services/user/UserBillServices.php b/pro_v3.5.1/app/services/user/UserBillServices.php index 458a5199..bf88c645 100644 --- a/pro_v3.5.1/app/services/user/UserBillServices.php +++ b/pro_v3.5.1/app/services/user/UserBillServices.php @@ -222,6 +222,23 @@ class UserBillServices extends BaseServices 'status' => 1, 'pm' => 1 ], + // fsgx PRD §3.3:报单直推/伞下待释放积分明细(不计入可消费积分汇总) + 'hjf_reward_direct_integral' => [ + 'title' => '直推积分奖励', + 'category' => 'integral', + 'type' => 'hjf_frozen_direct', + 'mark' => '待释放积分{%num%}点', + 'status' => 0, + 'pm' => 1 + ], + 'hjf_reward_umbrella_integral' => [ + 'title' => '伞下积分奖励', + 'category' => 'integral', + 'type' => 'hjf_frozen_umbrella', + 'mark' => '待释放积分{%num%}点', + 'status' => 0, + 'pm' => 1 + ], ]; /** @@ -566,6 +583,10 @@ class UserBillServices extends BaseServices 'integral_refund', 'order_integral_refund', 'pay_product_integral_back', + 'frozen_points_brokerage', + 'frozen_points_release', + 'hjf_frozen_direct', + 'hjf_frozen_umbrella', ]])); $where_data['type'] = 'sign'; $data['CountSign'] = $this->dao->getUserSignPoint($where_data);