Order.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. namespace app\common\Service\Commission;
  3. use app\common\Service\Commission\Config as ConfigService;
  4. use app\common\Service\commission\RegionalCommission;
  5. use app\common\model\commission\Order as OrderModel;
  6. use app\common\model\commission\Reward as RewardModel;
  7. use app\common\model\commission\Log as LogModel;
  8. /**
  9. * 分佣业务
  10. */
  11. class Order
  12. {
  13. public $config; // 分销设置
  14. public $item; // 订单商品
  15. public $buyer; // 购买人
  16. public $goods; // 分销商品
  17. public $amount = 0; // 订单商品核算价格
  18. public $commissionLevel = 0; // 分销层级
  19. public $selfBuy; // 是否自购
  20. // 分销状态
  21. const COMMISSION_CLOSE = 0; // 分销功能已关闭
  22. /**
  23. * 构造函数
  24. *
  25. * @param array $item 分销商品
  26. */
  27. public function __construct($item)
  28. {
  29. $this->buyer = new Agent($item['user_id']);
  30. $this->item = $item;
  31. $this->config = new ConfigService();
  32. }
  33. /**
  34. * 检测并设置分销商品规则
  35. *
  36. * @return void
  37. */
  38. public function checkAndSetCommission()
  39. {
  40. // 未找到订单商品或购买人
  41. if (!$this->item || !$this->buyer->user) {
  42. return false;
  43. }
  44. // 获取商品分销佣金规则
  45. $this->goods = new Goods($this->item['goods_id'], $this->item['goods_sku_price_id']);
  46. // 商品有独立分销设置,覆盖默认系统配置
  47. if ($commissionConfig = $this->goods->getCommissionConfig()) {
  48. $this->config->setConfig($commissionConfig);
  49. }
  50. // 获取系统设置分销层级
  51. $this->commissionLevel = $this->config->getCommissionLevel();
  52. // 分销中心已关闭
  53. if (self::COMMISSION_CLOSE === $this->commissionLevel) {
  54. return false;
  55. }
  56. // 商品不参与分销
  57. if (!$this->goods->getCommissionRules()) {
  58. return false;
  59. }
  60. // 是否自购分销订单
  61. $this->selfBuy = $this->buyer->isAgentAvaliable() && $this->config->isSelfBuy();
  62. // 未找到上级分销商且不是自购
  63. if (!$this->buyer->getParentUserId() && !$this->selfBuy) {
  64. return false;
  65. }
  66. // 获取商品结算价格(四舍五入精确到分)
  67. $this->amount = $this->getGoodsCommissionAmount();
  68. // 没有分佣的必要了
  69. if ($this->amount <= 0) {
  70. return false;
  71. }
  72. return true;
  73. }
  74. // 获取商品核算总金额
  75. public function getGoodsCommissionAmount()
  76. {
  77. $commissionType = $this->config->getRewardType();
  78. $amount = round(0, 2);
  79. switch ($commissionType) {
  80. case 'pay_price':
  81. $amount = $this->item['pay_fee'];
  82. break;
  83. case 'goods_price':
  84. $amount = round($this->item['goods_price'] * $this->item['goods_num'], 2);
  85. break;
  86. }
  87. return $amount;
  88. }
  89. /**
  90. * 创建分销订单
  91. */
  92. public function createCommissionOrder()
  93. {
  94. $agentId = $this->selfBuy ? $this->buyer->user->id : $this->buyer->getParentUserId();
  95. if (!$agentId) {
  96. return false;
  97. }
  98. $commissionOrder = OrderModel::where('order_item_id', $this->item['id'])->find();
  99. // 已添加过分销订单
  100. if ($commissionOrder) {
  101. return $commissionOrder;
  102. }
  103. $commissionOrderParams = [
  104. 'self_buy' => intval($this->selfBuy),
  105. 'order_id' => $this->item['order_id'],
  106. 'order_item_id' => $this->item['id'],
  107. 'buyer_id' => $this->buyer->user->id,
  108. 'goods_id' => $this->item['goods_id'],
  109. 'agent_id' => $agentId,
  110. 'amount' => $this->amount,
  111. 'reward_type' => $this->config->getRewardType(),
  112. 'commission_rules' => $this->goods->getCommissionRules(), // 记录当前设置的分佣规则,防止以后系统或者分销商设置有变导致更改历史规则
  113. 'reward_event' => $this->config->getRewardEvent(),
  114. 'commission_order_status' => $this->goods->commissionGoods->commission_order_status, // 是否计入分销业绩
  115. 'commission_reward_status' => RewardModel::COMMISSION_REWARD_STATUS_PENDING, // 佣金状态
  116. ];
  117. $commissionOrder = OrderModel::create($commissionOrderParams);
  118. // 添加分销商推广订单业绩
  119. $orderAgent = new Agent($commissionOrder->agent_id);
  120. if ($orderAgent->isAgentAvaliable() && $commissionOrder->commission_order_status) {
  121. if($this->selfBuy) {
  122. // 添加一级业绩(自购变成一级)
  123. $orderAgent->agent->setInc('child_order_money_first', $commissionOrder->amount);
  124. $orderAgent->agent->setInc('child_order_count_first', 1);
  125. }else {
  126. // 添加二级业绩(原一级变成二级)
  127. $orderAgent->agent->setInc('child_order_money_second', $commissionOrder->amount);
  128. $orderAgent->agent->setInc('child_order_count_second', 1);
  129. }
  130. LogModel::add($commissionOrder['agent_id'], 'order', [
  131. 'type' => 'paid',
  132. 'order' => $commissionOrder,
  133. 'item' => $this->item,
  134. 'buyer' => $this->buyer->user
  135. ], $this->buyer->user);
  136. }
  137. return $commissionOrder;
  138. }
  139. /**
  140. * 执行分销计划,递归往上分佣
  141. *
  142. * @param object $commissionOrder 分销订单
  143. * @param object $currentAgent 当前待分佣的分销商 默认自购开始算
  144. * @param int $currentCommissionLevel 当前分佣层级 一级(自购)开始算
  145. */
  146. public function runCommissionPlan($commissionOrder, $currentAgent = null, $currentCommissionLevel = 1)
  147. {
  148. // 超出分佣层级
  149. if ($this->commissionLevel < $currentCommissionLevel) {
  150. return true;
  151. }
  152. // 当前层级为1且分销订单是自购订单 则当前分销商为购买人自己
  153. if ($currentCommissionLevel === 1) {
  154. $currentAgent = new Agent($commissionOrder->agent_id);
  155. }
  156. if ($currentAgent && !empty($currentAgent->user)) {
  157. // 防止重复添加佣金
  158. $commissionReward = RewardModel::where([
  159. 'commission_order_id' => $commissionOrder->id,
  160. 'agent_id' => $currentAgent->user->id,
  161. 'commission_level' => $currentCommissionLevel, // 分佣层级
  162. ])->find();
  163. if (!$commissionReward) {
  164. $currentAgentLevel = $currentAgent->getAgentLevel();
  165. $currentCommissionLevelRule = $this->goods->getCommissionLevelRule($currentAgentLevel, $currentCommissionLevel);
  166. if ($currentCommissionLevelRule) {
  167. $commission = $this->goods->caculateGoodsCommission($currentCommissionLevelRule, $this->amount, $this->item['goods_num']);
  168. if ($commission > 0) {
  169. $commissionRewardParams = [
  170. 'order_id' => $commissionOrder->order_id,
  171. 'order_item_id' => $commissionOrder->order_item_id,
  172. 'buyer_id' => $commissionOrder->buyer_id, // 购买人
  173. 'commission_order_id' => $commissionOrder->id, // 分销订单ID
  174. 'agent_id' => $currentAgent->user->id, // 待分佣分销商ID
  175. 'type' => 'commission', // 奖金类型
  176. 'commission' => $commission, // 佣金
  177. 'status' => 0, // 佣金状态
  178. 'original_commission' => $commission, // 原始佣金
  179. 'commission_level' => $currentCommissionLevel, // 分佣层级
  180. 'commission_rules' => $currentCommissionLevelRule, // 分佣层级
  181. 'agent_level' => $currentAgentLevel // 分佣时分销商等级
  182. ];
  183. $commissionReward = RewardModel::create($commissionRewardParams);
  184. LogModel::add($commissionReward['agent_id'], 'reward', [
  185. 'type' => 'paid',
  186. 'reward' => $commissionReward,
  187. ], $this->buyer->user);
  188. }
  189. }
  190. }
  191. // 递归执行下一次
  192. $currentCommissionLevel++;
  193. // 超出分销层级
  194. if ($this->commissionLevel < $currentCommissionLevel) {
  195. return true;
  196. }
  197. $parentUserId = $currentAgent->getParentUserId();
  198. // 执行下一级分销任务
  199. if ($parentUserId) {
  200. $parentAgent = new Agent($parentUserId);
  201. $this->runCommissionPlan($commissionOrder, $parentAgent, $currentCommissionLevel);
  202. } else {
  203. // 传统分佣结束后,执行区域分佣
  204. $this->executeRegionalCommission($commissionOrder);
  205. return true;
  206. }
  207. }
  208. }
  209. /**
  210. * 执行区域代理商分佣
  211. */
  212. protected function executeRegionalCommission($commissionOrder)
  213. {
  214. try {
  215. $regionalService = new RegionalCommission($commissionOrder, $this->goods, $this->config);
  216. $regionalService->executeRegionalCommission();
  217. } catch (\Exception $e) {
  218. // 记录错误但不影响主流程
  219. \think\Log::error('区域分佣执行失败: ' . $e->getMessage());
  220. }
  221. }
  222. }