Order.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. namespace app\common\model\plus\agent;
  3. use app\common\model\BaseModel;
  4. use app\common\enum\order\OrderTypeEnum;
  5. use app\common\model\plus\agent\User as AgentUserModel;
  6. use app\common\model\product\Product as ProductModel;
  7. use app\common\model\plus\agent\Product as AgentProductModel;
  8. /**
  9. * 分销商订单模型
  10. */
  11. class Order extends BaseModel
  12. {
  13. protected $name = 'agent_order';
  14. protected $pk = 'id';
  15. /**
  16. * 订单所属用户
  17. * @return \think\model\relation\BelongsTo
  18. */
  19. public function user()
  20. {
  21. return $this->belongsTo('app\common\model\user\User');
  22. }
  23. /**
  24. * 一级分销商用户
  25. * @return \think\model\relation\BelongsTo
  26. */
  27. public function agentFirst()
  28. {
  29. return $this->belongsTo('app\common\model\user\User', 'first_user_id');
  30. }
  31. /**
  32. * 二级分销商用户
  33. * @return \think\model\relation\BelongsTo
  34. */
  35. public function agentSecond()
  36. {
  37. return $this->belongsTo('app\common\model\user\User', 'second_user_id');
  38. }
  39. /**
  40. * 三级分销商用户
  41. * @return \think\model\relation\BelongsTo
  42. */
  43. public function agentThird()
  44. {
  45. return $this->belongsTo('app\common\model\user\User', 'third_user_id');
  46. }
  47. /**
  48. * 订单类型
  49. * @param $value
  50. * @return array
  51. */
  52. public function getOrderTypeAttr($value)
  53. {
  54. $types = OrderTypeEnum::getTypeName();
  55. return ['text' => $types[$value], 'value' => $value];
  56. }
  57. /**
  58. * 订单详情
  59. * @param $orderId
  60. * @param $orderType
  61. * @return array|\think\Model|null
  62. * @throws \think\db\exception\DataNotFoundException
  63. * @throws \think\db\exception\DbException
  64. * @throws \think\db\exception\ModelNotFoundException
  65. */
  66. public static function getDetailByOrderId($orderId, $orderType)
  67. {
  68. return (new static())->where('order_id', '=', $orderId)
  69. ->where('order_type', '=', $orderType)
  70. ->find();
  71. }
  72. /**
  73. * 发放分销订单佣金
  74. * @param $order
  75. * @param int $orderType
  76. * @return bool
  77. * @throws \think\db\exception\DataNotFoundException
  78. * @throws \think\db\exception\DbException
  79. * @throws \think\db\exception\ModelNotFoundException
  80. */
  81. public static function grantMoney($order, $orderType = OrderTypeEnum::MASTER)
  82. {
  83. // 订单是否已完成
  84. if ($order['order_status']['value'] != 30) {
  85. return false;
  86. }
  87. // 分销订单详情
  88. $model = self::getDetailByOrderId($order['order_id'], $orderType);
  89. if (!$model || $model['is_settled'] == 1) {
  90. return false;
  91. }
  92. // 佣金结算天数
  93. $settleDays = Setting::getItem('settlement', $order['app_id'])['settle_days'];
  94. // 写入结算时间
  95. $deadlineTime = $model['settle_end_time'];
  96. if($deadlineTime == 0){
  97. $deadlineTime = $order['receipt_time'] + $settleDays * 86400;
  98. $model->save([
  99. 'settle_end_time' => $deadlineTime
  100. ]);
  101. }
  102. if ($deadlineTime > time()) {
  103. return false;
  104. }
  105. // 重新计算分销佣金
  106. $capital = $model->getCapitalByOrder($order);
  107. // 发放一级分销商佣金
  108. $model['first_user_id'] > 0 && User::grantMoney($model['first_user_id'], $capital['first_money']);
  109. // 发放二级分销商佣金
  110. $model['second_user_id'] > 0 && User::grantMoney($model['second_user_id'], $capital['second_money']);
  111. // 发放三级分销商佣金
  112. $model['third_user_id'] > 0 && User::grantMoney($model['third_user_id'], $capital['third_money']);
  113. // 更新分销订单记录
  114. $model->save([
  115. 'order_price' => $capital['orderPrice'],
  116. 'first_money' => $model['first_user_id'] > 0? $capital['first_money']:0,
  117. 'second_money' => $model['second_user_id'] > 0? $capital['second_money']:0,
  118. 'third_money' => $model['third_user_id'] > 0? $capital['third_money']:0,
  119. 'is_settled' => 1,
  120. 'settle_time' => time()
  121. ]);
  122. event('AgentUserGrade', $model['first_user_id']);
  123. event('AgentUserGrade', $model['second_user_id']);
  124. event('AgentUserGrade', $model['third_user_id']);
  125. return true;
  126. }
  127. /**
  128. * 计算订单分销佣金
  129. * @param $order
  130. * @return array
  131. */
  132. protected function getCapitalByOrder($order, $source = 'create')
  133. {
  134. // 分销佣金设置
  135. $setting = Setting::getItem('commission', $order['app_id']);
  136. // 分销层级
  137. $level = Setting::getItem('basic', $order['app_id'])['level'];
  138. // 分销订单佣金数据
  139. $capital = [
  140. // 订单总金额(不含运费)
  141. 'orderPrice' => bcsub($order['pay_price'], $order['express_price'], 2),
  142. // 一级分销佣金
  143. 'first_money' => 0.00,
  144. // 二级分销佣金
  145. 'second_money' => 0.00,
  146. // 三级分销佣金
  147. 'third_money' => 0.00,
  148. // 是否记录
  149. 'is_record' => true
  150. ];
  151. $total_count = count($order['product']);
  152. // 计算分销佣金
  153. foreach ($order['product'] as $product) {
  154. // 判断商品是否开放分销
  155. if(ProductModel::detail($product['product_id'])['is_agent'] == 0 && $source == 'create'){
  156. $total_count--;
  157. continue;
  158. }
  159. // 判断商品存在售后退款则不计算佣金
  160. if ($this->checkProductRefund($product)) {
  161. continue;
  162. }
  163. // 商品实付款金额
  164. $productPrice = min($capital['orderPrice'], $product['total_pay_price']);
  165. // 计算商品实际佣金
  166. $productCapital = $this->calculateProductCapital($setting, $product, $productPrice);
  167. // 累积分销佣金
  168. $level >= 1 && $capital['first_money'] += $productCapital['first_money'];
  169. $level >= 2 && $capital['second_money'] += $productCapital['second_money'];
  170. $level == 3 && $capital['third_money'] += $productCapital['third_money'];
  171. }
  172. if($total_count == 0){
  173. $capital['is_record'] = false;
  174. }
  175. return $capital;
  176. }
  177. /**
  178. * 计算商品实际佣金
  179. * @param $setting
  180. * @param $product
  181. * @param $productPrice
  182. * @return float[]|int[]
  183. */
  184. private function calculateProductCapital($setting, $product, $productPrice)
  185. {
  186. $first_user = AgentUserModel::detail($this['first_user_id']);
  187. $second_user = AgentUserModel::detail($this['second_user_id']);
  188. $third_user = AgentUserModel::detail($this['third_user_id']);
  189. $add_first_money = $productPrice * ($first_user['first_percent'] * 0.01);
  190. $add_second_money = $productPrice * ($second_user['second_percent'] * 0.01);
  191. $add_third_money = $productPrice * ($third_user['third_percent'] * 0.01);
  192. $agent_product = AgentProductModel::detail($product['product_id']);
  193. // 全局分销
  194. if ($agent_product['is_ind_agent'] == false) {
  195. // 全局分销比例
  196. return [
  197. 'first_money' => $productPrice * ($setting['first_money'] * 0.01) + $add_first_money,
  198. 'second_money' => $productPrice * ($setting['second_money'] * 0.01) + $add_second_money,
  199. 'third_money' => $productPrice * ($setting['third_money'] * 0.01) + $add_third_money
  200. ];
  201. }
  202. // 商品单独分销
  203. if ($agent_product['agent_money_type'] == 10) {
  204. // 分销佣金类型:百分比
  205. return [
  206. 'first_money' => $productPrice * ($agent_product['first_money'] * 0.01) + $add_first_money,
  207. 'second_money' => $productPrice * ($agent_product['second_money'] * 0.01) + $add_second_money,
  208. 'third_money' => $productPrice * ($agent_product['third_money'] * 0.01) + $add_third_money
  209. ];
  210. } else {
  211. return [
  212. 'first_money' => $product['total_num'] * $agent_product['first_money'] + $add_first_money,
  213. 'second_money' => $product['total_num'] * $agent_product['second_money'] + $add_second_money,
  214. 'third_money' => $product['total_num'] * $agent_product['third_money'] + $add_third_money
  215. ];
  216. }
  217. }
  218. /**
  219. * 验证商品是否存在售后
  220. * @param $product
  221. * @return bool
  222. */
  223. private function checkProductRefund($product)
  224. {
  225. return !empty($product['refund'])
  226. && $product['refund']['type']['value'] != 20
  227. && $product['refund']['is_agree']['value'] != 20;
  228. }
  229. }