Order.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?php
  2. namespace app\common\model\dealer;
  3. use think\Hook;
  4. use app\common\model\BaseModel;
  5. use app\common\enum\OrderType as OrderTypeEnum;
  6. /**
  7. * 分销商订单模型
  8. * Class Apply
  9. * @package app\common\model\dealer
  10. */
  11. class Order extends BaseModel
  12. {
  13. protected $name = 'dealer_order';
  14. /**
  15. * 订单模型初始化
  16. */
  17. public static function init()
  18. {
  19. parent::init();
  20. // 监听分销商订单行为管理
  21. $static = new static;
  22. Hook::listen('DealerOrder', $static);
  23. }
  24. /**
  25. * 订单所属用户
  26. * @return \think\model\relation\BelongsTo
  27. */
  28. public function user()
  29. {
  30. return $this->belongsTo('app\common\model\User');
  31. }
  32. /**
  33. * 一级分销商用户
  34. * @return \think\model\relation\BelongsTo
  35. */
  36. public function dealerFirst()
  37. {
  38. return $this->belongsTo('User', 'first_user_id');
  39. }
  40. /**
  41. * 二级分销商用户
  42. * @return \think\model\relation\BelongsTo
  43. */
  44. public function dealerSecond()
  45. {
  46. return $this->belongsTo('User', 'second_user_id');
  47. }
  48. /**
  49. * 三级分销商用户
  50. * @return \think\model\relation\BelongsTo
  51. */
  52. public function dealerThird()
  53. {
  54. return $this->belongsTo('User', 'third_user_id');
  55. }
  56. /**
  57. * 订单类型
  58. * @param $value
  59. * @return array
  60. */
  61. public function getOrderTypeAttr($value)
  62. {
  63. $types = OrderTypeEnum::getTypeName();
  64. return ['text' => $types[$value], 'value' => $value];
  65. }
  66. /**
  67. * 订单详情
  68. * @param $where
  69. * @return Order|null
  70. * @throws \think\exception\DbException
  71. */
  72. public static function detail($where)
  73. {
  74. return static::get($where);
  75. }
  76. /**
  77. * 订单详情
  78. * @param $orderId
  79. * @param $orderType
  80. * @return Order|null
  81. * @throws \think\exception\DbException
  82. */
  83. public static function getDetailByOrderId($orderId, $orderType)
  84. {
  85. return static::detail(['order_id' => $orderId, 'order_type' => $orderType]);
  86. }
  87. /**
  88. * 发放分销订单佣金
  89. * @param array|\think\Model $order 订单详情
  90. * @param int $orderType 订单类型
  91. * @return bool|false|int
  92. * @throws \think\Exception
  93. * @throws \think\exception\DbException
  94. */
  95. public static function grantMoney($order, $orderType = OrderTypeEnum::MASTER)
  96. {
  97. // 订单是否已完成
  98. if ($order['order_status']['value'] != 30) {
  99. return false;
  100. }
  101. // 佣金结算天数
  102. $settleDays = Setting::getItem('settlement', $order['wxapp_id'])['settle_days'];
  103. // 判断该订单是否满足结算时间 (订单完成时间 + 佣金结算时间) ≤ 当前时间
  104. $deadlineTime = $order['receipt_time'] + ((int)$settleDays * 86400);
  105. if ($settleDays > 0 && $deadlineTime > time()) {
  106. return false;
  107. }
  108. // 分销订单详情
  109. $model = self::getDetailByOrderId($order['order_id'], $orderType);
  110. if (!$model || $model['is_settled'] == 1) {
  111. return false;
  112. }
  113. // 重新计算分销佣金
  114. $capital = $model->getCapitalByOrder($order);
  115. // 发放一级分销商佣金
  116. $model['first_user_id'] > 0 && User::grantMoney($model['first_user_id'], $capital['first_money']);
  117. // 发放二级分销商佣金
  118. $model['second_user_id'] > 0 && User::grantMoney($model['second_user_id'], $capital['second_money']);
  119. // 发放三级分销商佣金
  120. $model['third_user_id'] > 0 && User::grantMoney($model['third_user_id'], $capital['third_money']);
  121. // 更新分销订单记录
  122. return $model->save([
  123. 'order_price' => $capital['orderPrice'],
  124. 'first_money' => $capital['first_money'],
  125. 'second_money' => $capital['second_money'],
  126. 'third_money' => $capital['third_money'],
  127. 'is_settled' => 1,
  128. 'settle_time' => time()
  129. ]);
  130. }
  131. /**
  132. * 计算订单分销佣金
  133. * @param $order
  134. * @return array
  135. */
  136. protected function getCapitalByOrder($order)
  137. {
  138. // 分销佣金设置
  139. $setting = Setting::getItem('commission', $order['wxapp_id']);
  140. // 分销层级
  141. $level = Setting::getItem('basic', $order['wxapp_id'])['level'];
  142. // 分销订单佣金数据
  143. $capital = [
  144. // 订单总金额(不含运费)
  145. 'orderPrice' => bcsub($order['pay_price'], $order['express_price'], 2),
  146. // 一级分销佣金
  147. 'first_money' => 0.00,
  148. // 二级分销佣金
  149. 'second_money' => 0.00,
  150. // 三级分销佣金
  151. 'third_money' => 0.00
  152. ];
  153. // 计算分销佣金
  154. foreach ($order['goods'] as $goods) {
  155. // 判断商品存在售后退款则不计算佣金
  156. if ($this->checkGoodsRefund($goods)) {
  157. continue;
  158. }
  159. // 商品实付款金额
  160. $goodsPrice = min($capital['orderPrice'], $goods['total_pay_price']);
  161. // 计算商品实际佣金
  162. $goodsCapital = $this->calculateGoodsCapital($setting, $goods, $goodsPrice);
  163. // 累积分销佣金
  164. $level >= 1 && $capital['first_money'] += $goodsCapital['first_money'];
  165. $level >= 2 && $capital['second_money'] += $goodsCapital['second_money'];
  166. $level == 3 && $capital['third_money'] += $goodsCapital['third_money'];
  167. }
  168. return $capital;
  169. }
  170. /**
  171. * 计算商品实际佣金
  172. * @param $setting
  173. * @param $goods
  174. * @param $goodsPrice
  175. * @return array
  176. */
  177. private function calculateGoodsCapital($setting, $goods, $goodsPrice)
  178. {
  179. // 判断是否开启商品单独分销
  180. if ($goods['is_ind_dealer'] == false) {
  181. // 全局分销比例
  182. return [
  183. 'first_money' => $goodsPrice * ($setting['first_money'] * 0.01),
  184. 'second_money' => $goodsPrice * ($setting['second_money'] * 0.01),
  185. 'third_money' => $goodsPrice * ($setting['third_money'] * 0.01)
  186. ];
  187. }
  188. // 商品单独分销
  189. if ($goods['dealer_money_type'] == 10) {
  190. // 分销佣金类型:百分比
  191. return [
  192. 'first_money' => $goodsPrice * ($goods['first_money'] * 0.01),
  193. 'second_money' => $goodsPrice * ($goods['second_money'] * 0.01),
  194. 'third_money' => $goodsPrice * ($goods['third_money'] * 0.01)
  195. ];
  196. } else {
  197. return [
  198. 'first_money' => $goods['total_num'] * $goods['first_money'],
  199. 'second_money' => $goods['total_num'] * $goods['second_money'],
  200. 'third_money' => $goods['total_num'] * $goods['third_money']
  201. ];
  202. }
  203. }
  204. /**
  205. * 验证商品是否存在售后
  206. * @param $goods
  207. * @return bool
  208. */
  209. private function checkGoodsRefund($goods)
  210. {
  211. return !empty($goods['refund'])
  212. && $goods['refund']['type']['value'] == 10
  213. && $goods['refund']['is_agree']['value'] != 20;
  214. }
  215. }