Order.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. namespace app\task\behavior\sharing;
  3. use think\Cache;
  4. use app\task\model\Setting as SettingModel;
  5. use app\task\model\UserCoupon as UserCouponModel;
  6. use app\task\model\sharing\Order as OrderModel;
  7. use app\task\model\sharing\OrderGoods as OrderGoodsModel;
  8. use app\common\enum\OrderType as OrderTypeEnum;
  9. use app\common\service\order\Complete as OrderCompleteService;
  10. use app\common\library\helper;
  11. /**
  12. * 拼团订单行为管理
  13. * Class Order
  14. * @package app\task\behavior
  15. */
  16. class Order
  17. {
  18. /* @var OrderModel $model */
  19. private $model;
  20. // 小程序id
  21. private $wxappId;
  22. /**
  23. * 执行函数
  24. * @param $model
  25. * @return bool
  26. */
  27. public function run($model)
  28. {
  29. if (!$model instanceof OrderModel)
  30. return new OrderModel and false;
  31. if (!$model::$wxapp_id) return false;
  32. // 绑定订单模型
  33. $this->model = $model;
  34. $this->wxappId = $model::$wxapp_id;
  35. if (!Cache::has("__task_space__sharing_order__{$this->wxappId}")) {
  36. // 获取商城交易设置
  37. $config = SettingModel::getItem('trade');
  38. $this->model->transaction(function () use ($config) {
  39. // 未支付订单自动关闭
  40. $this->close($config['order']['close_days']);
  41. // 已发货订单自动确认收货
  42. $this->receive($config['order']['receive_days']);
  43. // 已完成订单结算
  44. $this->settled($config['order']['refund_days']);
  45. });
  46. Cache::set("__task_space__sharing_order__{$this->wxappId}", time(), 3600);
  47. }
  48. return true;
  49. }
  50. /**
  51. * 未支付订单自动关闭
  52. * @param $closeDays
  53. * @return bool
  54. * @throws \think\db\exception\DataNotFoundException
  55. * @throws \think\db\exception\ModelNotFoundException
  56. * @throws \think\exception\DbException
  57. * @throws \Exception
  58. */
  59. private function close($closeDays)
  60. {
  61. // 取消n天以前的的未付款订单
  62. if ($closeDays < 1) {
  63. return false;
  64. }
  65. // 截止时间
  66. $deadlineTime = time() - ((int)$closeDays * 86400);
  67. // 条件
  68. $filter = [
  69. 'pay_status' => 10,
  70. 'order_status' => 10,
  71. 'create_time' => ['<=', $deadlineTime]
  72. ];
  73. // 查询截止时间未支付的订单
  74. $list = $this->model->getList($filter, ['goods', 'user']);
  75. $orderIds = helper::getArrayColumn($list, 'order_id');
  76. // 取消订单事件
  77. if (!empty($orderIds)) {
  78. $OrderGoodsModel = new OrderGoodsModel;
  79. foreach ($list as &$order) {
  80. // 回退商品库存
  81. $OrderGoodsModel->backGoodsStock($order['goods'], false);
  82. // 回退用户优惠券
  83. $order['coupon_id'] > 0 && UserCouponModel::setIsUse($order['coupon_id'], false);
  84. // 回退用户积分
  85. $describe = "订单取消:{$order['order_no']}";
  86. $order['points_num'] > 0 && $order->user->setIncPoints($order['points_num'], $describe);
  87. }
  88. // 批量更新订单状态为已取消
  89. $this->model->onBatchUpdate($orderIds, ['order_status' => 20]);
  90. }
  91. // 记录日志
  92. $this->dologs('close', [
  93. 'close_days' => (int)$closeDays,
  94. 'deadline_time' => $deadlineTime,
  95. 'orderIds' => json_encode($orderIds),
  96. ]);
  97. return true;
  98. }
  99. /**
  100. * 已发货订单自动确认收货
  101. * @param $receiveDays
  102. * @return bool|false|int
  103. * @throws \think\Exception
  104. * @throws \think\exception\DbException
  105. */
  106. private function receive($receiveDays)
  107. {
  108. if ($receiveDays < 1) {
  109. return false;
  110. }
  111. // 截止时间
  112. $deadlineTime = time() - ((int)$receiveDays * 86400);
  113. // 条件
  114. $filter = [
  115. 'pay_status' => 20,
  116. 'delivery_status' => 20,
  117. 'receipt_status' => 10,
  118. 'delivery_time' => ['<=', $deadlineTime]
  119. ];
  120. // 订单id集
  121. $orderIds = $this->model->where($filter)->column('order_id');
  122. if (!empty($orderIds)) {
  123. // 更新订单收货状态
  124. $this->model->onBatchUpdate($orderIds, [
  125. 'receipt_status' => 20,
  126. 'receipt_time' => time(),
  127. 'order_status' => 30
  128. ]);
  129. // 批量处理已完成的订单
  130. $this->onReceiveCompleted($orderIds);
  131. }
  132. // 记录日志
  133. $this->dologs('receive', [
  134. 'receive_days' => (int)$receiveDays,
  135. 'deadline_time' => $deadlineTime,
  136. 'orderIds' => json_encode($orderIds),
  137. ]);
  138. return true;
  139. }
  140. /**
  141. * 批量处理已完成的订单
  142. * @param $orderIds
  143. * @return bool
  144. * @throws \think\Exception
  145. * @throws \think\db\exception\DataNotFoundException
  146. * @throws \think\db\exception\ModelNotFoundException
  147. * @throws \think\exception\DbException
  148. */
  149. private function onReceiveCompleted($orderIds)
  150. {
  151. // 获取已完成的订单列表
  152. $list = $this->model->getList(['order_id' => ['in', $orderIds]], [
  153. 'goods' => ['refund'], // 用于发放分销佣金
  154. ]);
  155. if ($list->isEmpty()) return false;
  156. // 执行订单完成后的操作
  157. $OrderCompleteService = new OrderCompleteService(OrderTypeEnum::SHARING);
  158. $OrderCompleteService->complete($list, $this->wxappId);
  159. return true;
  160. }
  161. /**
  162. * 已完成订单结算
  163. * @param $refundDays
  164. * @throws \think\db\exception\DataNotFoundException
  165. * @throws \think\db\exception\ModelNotFoundException
  166. * @throws \think\exception\DbException
  167. * @throws \Exception
  168. */
  169. private function settled($refundDays)
  170. {
  171. // 获取已完成的订单(未累积用户实际消费金额)
  172. // 条件1:订单状态:已完成
  173. // 条件2:超出售后期限
  174. // 条件3:is_settled 为 0
  175. // 截止时间
  176. $deadlineTime = time() - ((int)$refundDays * 86400);
  177. // 查询条件
  178. $filter = [
  179. 'order_status' => 30,
  180. 'receipt_time' => ['<=', $deadlineTime], // 此处使用<=,用于兼容自动确认收货后
  181. 'is_settled' => 0
  182. ];
  183. // 查询订单列表
  184. $orderList = $this->model->getList($filter, [
  185. 'goods' => ['refund'], // 用于计算售后退款金额
  186. ]);
  187. // 订单id集
  188. $orderIds = helper::getArrayColumn($orderList, 'order_id');
  189. // 订单结算服务
  190. $OrderCompleteService = new OrderCompleteService(OrderTypeEnum::SHARING);
  191. !empty($orderIds) && $OrderCompleteService->settled($orderList);
  192. // 记录日志
  193. $this->dologs('settled', [
  194. 'refund_days' => (int)$refundDays,
  195. 'deadline_time' => $deadlineTime,
  196. 'orderIds' => json_encode($orderIds),
  197. ]);
  198. }
  199. /**
  200. * 记录日志
  201. * @param $method
  202. * @param array $params
  203. * @return bool|int
  204. */
  205. private function dologs($method, $params = [])
  206. {
  207. $value = 'behavior sharing Order --' . $method;
  208. foreach ($params as $key => $val)
  209. $value .= ' --' . $key . ' ' . $val;
  210. return log_write($value);
  211. }
  212. }