Order.php 7.4 KB

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