Order.php 12 KB

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