Order.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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 array|\think\Model $order 订单详情
  134. * @param int $orderType 订单类型
  135. * @return bool|false|int
  136. * @throws \think\Exception
  137. * @throws \think\exception\DbException
  138. */
  139. public static function grantOrderMoney($order, $orderType = OrderTypeEnum::MASTER)
  140. {
  141. // 订单是否已完成
  142. if ($order['order_status']['value'] != 30) {
  143. return false;
  144. }
  145. // 分销订单详情
  146. $model = \app\common\model\Order::detail(['order_id'=>$order['order_id']]);
  147. if (!$model || $model['is_settled'] == 1) {
  148. return false;
  149. }
  150. $userInfo = User::where(['user_id'=> $order['user_id'],'wxapp_id'=>$order['wxapp_id']])
  151. ->field('user_id,referee_id')
  152. ->find();
  153. $awardScore1 = $awardScore2 = 0;
  154. $firstId = isset($userInfo['referee_id'])? $userInfo['referee_id'] : 0;
  155. if($userInfo && $firstId>0){
  156. $firstInfo = User::where(['user_id'=> $firstId,'wxapp_id'=>$order['wxapp_id']])
  157. ->field('user_id,referee_id')
  158. ->find();
  159. $secondId = isset($firstInfo['referee_id'])? $firstInfo['referee_id'] : 0;
  160. $payMoney = isset($model['total_price'])? floatval($model['total_price']) : 0;
  161. $config = Setting::getItem('commission', $order['wxapp_id']);
  162. $awardScoreRate1 = isset($config['award_score_1'])? floatval($config['award_score_1']) : 0;
  163. $awardScoreRate2 = isset($config['award_score_2'])? floatval($config['award_score_2']) : 0;
  164. // 一级佣金
  165. $awardScore1 = floatval($payMoney * $awardScoreRate1/100);
  166. $awardScore2 = floatval($payMoney * $awardScoreRate2/100);
  167. if($firstId && $firstInfo && $awardScore1>0){
  168. User::grantMoney($firstId, $awardScore1,4,'直推订单佣金');
  169. }
  170. //二级佣金
  171. $secondInfo = User::where(['user_id'=> $secondId,'wxapp_id'=>$order['wxapp_id']])
  172. ->field('user_id,referee_id')
  173. ->find();
  174. if($secondId && $secondInfo && $awardScore2>0){
  175. User::grantMoney($secondInfo, $awardScore2,5,'间推订单佣金');
  176. }
  177. }
  178. // 更新订单结算数据
  179. $model = new \app\common\model\Order();
  180. return $model::where(['order_id'=> $order['order_id']])->update([
  181. 'first_money' => $awardScore1,
  182. 'second_money' => $awardScore2,
  183. 'is_settled' => 1,
  184. 'settle_time' => time()
  185. ]);
  186. }
  187. /**
  188. * 发放分销订单佣金(备份旧的结算)
  189. * @param array|\think\Model $order 订单详情
  190. * @param int $orderType 订单类型
  191. * @return bool|false|int
  192. * @throws \think\Exception
  193. * @throws \think\exception\DbException
  194. */
  195. public static function grantMoneyBack($order, $orderType = OrderTypeEnum::MASTER)
  196. {
  197. // 订单是否已完成
  198. if ($order['order_status']['value'] != 30) {
  199. return false;
  200. }
  201. // 佣金结算天数
  202. $settleDays = Setting::getItem('settlement', $order['wxapp_id'])['settle_days'];
  203. // 判断该订单是否满足结算时间 (订单完成时间 + 佣金结算时间) ≤ 当前时间
  204. $deadlineTime = $order['receipt_time'] + ((int)$settleDays * 86400);
  205. if ($settleDays > 0 && $deadlineTime > time()) {
  206. return false;
  207. }
  208. // 分销订单详情
  209. $model = self::getDetailByOrderId($order['order_id'], $orderType);
  210. if (!$model || $model['is_settled'] == 1) {
  211. return false;
  212. }
  213. // 重新计算分销佣金
  214. $capital = $model->getCapitalByOrder($order);
  215. // 发放一级分销商佣金
  216. $model['first_user_id'] > 0 && User::grantMoney($model['first_user_id'], $capital['first_money']);
  217. // 发放二级分销商佣金
  218. $model['second_user_id'] > 0 && User::grantMoney($model['second_user_id'], $capital['second_money']);
  219. // 发放三级分销商佣金
  220. $model['third_user_id'] > 0 && User::grantMoney($model['third_user_id'], $capital['third_money']);
  221. // 更新分销订单记录
  222. return $model->save([
  223. 'order_price' => $capital['orderPrice'],
  224. 'first_money' => $capital['first_money'],
  225. 'second_money' => $capital['second_money'],
  226. 'third_money' => $capital['third_money'],
  227. 'is_settled' => 1,
  228. 'settle_time' => time()
  229. ]);
  230. }
  231. /**
  232. * 计算订单分销佣金
  233. * @param $order
  234. * @return array
  235. */
  236. protected function getCapitalByOrder($order)
  237. {
  238. // 分销佣金设置
  239. $setting = Setting::getItem('commission', $order['wxapp_id']);
  240. // 分销层级
  241. $level = Setting::getItem('basic', $order['wxapp_id'])['level'];
  242. // 分销订单佣金数据
  243. $capital = [
  244. // 订单总金额(不含运费)
  245. 'orderPrice' => bcsub($order['pay_price'], $order['express_price'], 2),
  246. // 一级分销佣金
  247. 'first_money' => 0.00,
  248. // 二级分销佣金
  249. 'second_money' => 0.00,
  250. // 三级分销佣金
  251. 'third_money' => 0.00
  252. ];
  253. // 计算分销佣金
  254. foreach ($order['goods'] as $goods) {
  255. // 判断商品存在售后退款则不计算佣金
  256. if ($this->checkGoodsRefund($goods)) {
  257. continue;
  258. }
  259. // 商品实付款金额
  260. $goodsPrice = min($capital['orderPrice'], $goods['total_pay_price']);
  261. // 计算商品实际佣金
  262. $goodsCapital = $this->calculateGoodsCapital($setting, $goods, $goodsPrice);
  263. // 累积分销佣金
  264. $level >= 1 && $capital['first_money'] += $goodsCapital['first_money'];
  265. $level >= 2 && $capital['second_money'] += $goodsCapital['second_money'];
  266. $level == 3 && $capital['third_money'] += $goodsCapital['third_money'];
  267. }
  268. return $capital;
  269. }
  270. /**
  271. * 计算商品实际佣金
  272. * @param $setting
  273. * @param $goods
  274. * @param $goodsPrice
  275. * @return array
  276. */
  277. private function calculateGoodsCapital($setting, $goods, $goodsPrice)
  278. {
  279. // 判断是否开启商品单独分销
  280. if ($goods['is_ind_dealer'] == false) {
  281. // 全局分销比例
  282. return [
  283. 'first_money' => $goodsPrice * ($setting['first_money'] * 0.01),
  284. 'second_money' => $goodsPrice * ($setting['second_money'] * 0.01),
  285. 'third_money' => $goodsPrice * ($setting['third_money'] * 0.01)
  286. ];
  287. }
  288. // 商品单独分销
  289. if ($goods['dealer_money_type'] == 10) {
  290. // 分销佣金类型:百分比
  291. return [
  292. 'first_money' => $goodsPrice * ($goods['first_money'] * 0.01),
  293. 'second_money' => $goodsPrice * ($goods['second_money'] * 0.01),
  294. 'third_money' => $goodsPrice * ($goods['third_money'] * 0.01)
  295. ];
  296. } else {
  297. return [
  298. 'first_money' => $goods['total_num'] * $goods['first_money'],
  299. 'second_money' => $goods['total_num'] * $goods['second_money'],
  300. 'third_money' => $goods['total_num'] * $goods['third_money']
  301. ];
  302. }
  303. }
  304. /**
  305. * 验证商品是否存在售后
  306. * @param $goods
  307. * @return bool
  308. */
  309. private function checkGoodsRefund($goods)
  310. {
  311. return !empty($goods['refund'])
  312. && $goods['refund']['type']['value'] == 10
  313. && $goods['refund']['is_agree']['value'] != 20;
  314. }
  315. }