Order.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\console\service;
  13. use app\common\model\member\GoldRice;
  14. use app\common\service\commission\GiveOutCommission;
  15. use app\console\model\Order as OrderModel;
  16. use app\common\service\BaseService;
  17. use app\common\service\Order as OrderService;
  18. use app\common\service\order\Complete as OrderCompleteService;
  19. use app\common\enum\order\OrderStatus as OrderStatusEnum;
  20. use app\common\library\helper;
  21. use app\console\library\Tools;
  22. use app\api\model\OrderRefund as OrderRefundModel;
  23. use app\common\service\order\Refund as RefundService;
  24. use app\common\model\OrderGoods as OrderGoodsModel;
  25. use app\api\model\user\CommissionsDetail;
  26. use app\api\model\card\UserRiceCard as UserRiceCardModel;
  27. use app\api\model\card\UserRiceCard;
  28. use app\api\model\card\UserRiceCardConsume;
  29. use app\common\model\order\RefundHis;
  30. use app\common\service\goods\source\Factory as FactoryStock;
  31. use think\facade\Db;
  32. /**
  33. * 服务类:订单模块
  34. * Class Order
  35. * @package app\console\service
  36. */
  37. class Order extends BaseService
  38. {
  39. /**
  40. * 未支付订单自动关闭
  41. * @param int $storeId
  42. * @param int $closeMinutes 自定关闭订单分钟数
  43. * @throws \think\db\exception\DataNotFoundException
  44. * @throws \think\db\exception\DbException
  45. * @throws \think\db\exception\ModelNotFoundException
  46. */
  47. public function closeEvent(int $storeId, int $closeMinutes)
  48. {
  49. // 截止时间
  50. $deadlineTime = time() - ((int)$closeMinutes * 60);
  51. // 查询截止时间未支付的订单
  52. $model = new OrderModel;
  53. $list = $model->getListByClose($storeId, $deadlineTime);
  54. // 订单ID集
  55. $orderIds = helper::getArrayColumn($list, 'order_id');
  56. if (!empty($orderIds)) {
  57. // 取消订单事件
  58. foreach ($list as $order) {
  59. OrderService::cancelEvent($order);
  60. }
  61. // 批量更新订单状态为已取消
  62. $model->onBatchUpdate($orderIds, ['order_status' => OrderStatusEnum::CANCELLED]);
  63. }
  64. // 记录日志
  65. Tools::taskLogs('OrderCancel', 'closeEvent', [
  66. 'storeId' => $storeId,
  67. 'closeMinutes' => $closeMinutes,
  68. 'deadlineTime' => $deadlineTime,
  69. 'orderIds' => helper::jsonEncode($orderIds)
  70. ]);
  71. }
  72. /**
  73. * 超时未自提订单自动退款
  74. */
  75. public function refundPickupEvent(int $storeId, int $closeMinutes)
  76. {
  77. // 截止时间
  78. $deadlineTime = time() - ((int)$closeMinutes * 60);
  79. // 查询截止时间未自提的订单
  80. $model = new OrderModel;
  81. $list = $model->getListByUnPickup($storeId, $deadlineTime);
  82. // 订单ID集
  83. $orderIds = helper::getArrayColumn($list, 'order_id');
  84. log_record([
  85. 'name' => '超时未自提订单自动退款',
  86. 'data' => $orderIds
  87. ]);
  88. if (!empty($orderIds)) {
  89. Db::transaction(function() use ($model, $list, $orderIds) {
  90. // 关闭订单事件
  91. foreach ($list as $order) {
  92. // 1.未发生手动退款,则整单退款
  93. if ($order['delivery_type'] != 20 || $order['hx_status'] != 10 || $order['pay_status'] != 20) {
  94. // 不满足门店自提订单条件
  95. continue;
  96. }
  97. if (empty($order['goods'])) { // 订单商品信息不存在
  98. continue;
  99. }
  100. $refund = OrderRefundModel::where(['order_id'=>$order['order_id']])->where('status','in',[0,10,20])->find();
  101. if (!empty($refund)) { // 当前订单已申请售后
  102. continue;
  103. }
  104. $riceCard = UserRiceCardModel::getValidRiceCardDetail($order['rice_card_id']);
  105. if ($order['rice_card_id']) { // 订单商品有使用现金卡
  106. // 验证余额
  107. if ($order['rice_card_money'] + $riceCard['balance'] > $riceCard['face_value']) {
  108. // 现金卡退还金额异常
  109. continue;
  110. }
  111. // 写入现金卡流水明细
  112. UserRiceCardConsume::add($riceCard, $order['order_no'], $order['pay_price'], $order['rice_card_money'], 1, '商品退款');
  113. // 退还现金卡金额
  114. UserRiceCard::setIncByField($order['rice_card_id'], 'balance', (float)$order['rice_card_money']);
  115. $riceCard->effect_state = 1; // 改为 生效
  116. $riceCard->save();
  117. }
  118. $refundMoney = helper::bcsub($order['pay_price'] + $order['rice_card_money'], 0, 2); // 退款金额 = 实付金额 + 现金卡抵扣金额
  119. $goods_images = [];
  120. foreach ($order['goods'] as $arr){ //获取图片url
  121. $goods_images[] = $arr['good_image'];
  122. }
  123. $param['order_id'] = $order['order_id'];
  124. $param['refund_money'] = $refundMoney;
  125. $param['pay_money'] = $order['pay_price'];
  126. $param['gold_rice_amount'] = $order['gold_rice_amount'];
  127. $param['gold_rice_amount_output'] = $order['gold_rice_amount_input'];
  128. $param['rice_card_money'] = $order['rice_card_money'];
  129. $param['rice_card_id'] = $order['rice_card_id'];
  130. $param['express_price'] = $order['express_price'];
  131. $param['goods_type'] = 1; // 未收到货
  132. $param['apply_desc'] = '';
  133. $param['type'] = 30;// 30 未发货退款
  134. $param['refund_number'] = OrderService::createOrderNoPrefix('TKSQ'); //申请单编号
  135. // $param['out_refund_no'] = OrderService::createOrderNoPrefix('TK');//生成退款编号
  136. $param['user_id'] = $order['user_id'];
  137. // $param['goods_images'] = $goods_images;
  138. $param['order_goods_id'] = 0;
  139. $param['store_id'] = 10001;
  140. $param['is_sys_refund'] = 1; //系统退款
  141. $param['goods_num'] = helper::getArrayColumnSum($order['goods'], 'total_num');
  142. $param['finance_refund'] = 10;// 10已退款
  143. $param['out_refund_time'] = time(); //退款时间
  144. $param['refund_succ_time'] = time(); //退款成功时间
  145. $param['refund_close_time'] = time(); //退款关闭时间
  146. $param['status'] = 20;//售后单直接完成
  147. $param['delivery_type'] = $order['delivery_type'];
  148. $param['hx_status'] = $order['hx_status'];
  149. $param['shop_id'] = $order['shop_id'];
  150. if($order['delivery_type']==20){
  151. $param['audit_status'] = 10;//自提单直接门店审核通过
  152. }
  153. if ($param['pay_money'] > 0) {
  154. //直接退款逻辑处理 直接退款
  155. $RefundService = new RefundService();
  156. $refund_ret = $RefundService->execute($order,$param['refund_number'], $param['pay_money']);
  157. if ($refund_ret['status'] == 200) {
  158. $param['transaction_id'] = $refund_ret['data']['transaction_id']; // 微信退款交易号
  159. }
  160. }
  161. //订单商品修改成全额退款状态
  162. OrderGoodsModel::updateBase(['has_refund_full' => 1], ['order_id' => $order['order_id']]);
  163. //全部退款变更不结算
  164. CommissionsDetail::updateAllDetails($order['order_id']);
  165. // 回退商品库存
  166. FactoryStock::getFactory($order['order_source'])->backGoodsStock($order, true);
  167. // 回退多个活动的活动库存
  168. FactoryStock::getFactory($order['order_source'])->backActivityStock($order, true);
  169. $refund_res = OrderRefundModel::create($param);
  170. //关闭订单状态
  171. $RefundService = new OrderService();
  172. $RefundService->closeOrder($param['order_id']);
  173. //写入金米粒记录
  174. GoldRice::refundGoldRiceRoad($order,$refund_res);
  175. //门店自提
  176. $his_type = 11;
  177. $name = $order['user']['nick_name'] ?? '';
  178. $json_str = json_encode(["用户超时未核销,系统自动退款"]);
  179. (new RefundHis())->add($refund_res['order_refund_id'],$name,$his_type,$json_str,[],'系统','用户超时未核销,系统自动退款');
  180. }
  181. });
  182. }
  183. // 记录日志
  184. Tools::taskLogs('PickupOrderRefund', 'refundPickupEvent', [
  185. 'storeId' => $storeId,
  186. 'closeMinutes' => $closeMinutes,
  187. 'deadlineTime' => $deadlineTime,
  188. 'orderIds' => helper::jsonEncode($orderIds)
  189. ]);
  190. }
  191. /**
  192. * 已发货订单自动确认收货
  193. * @param int $storeId
  194. * @param int $receiveDays 自动收货天数
  195. * @throws \think\db\exception\DataNotFoundException
  196. * @throws \think\db\exception\DbException
  197. * @throws \think\db\exception\ModelNotFoundException
  198. */
  199. public function receiveEvent(int $storeId, int $receiveDays)
  200. {
  201. // 截止时间
  202. $deadlineTime = time() - ((int)$receiveDays * 86400);
  203. // 查询截止时间未确认收货的订单ID集
  204. $model = new OrderModel;
  205. $orderIds = $model->getOrderIdsByReceive($storeId, $deadlineTime);
  206. // 更新订单收货状态
  207. if (!empty($orderIds)) {
  208. // 批量更新订单状态为已收货
  209. $model->onUpdateReceived($orderIds);
  210. // 批量处理已完成的订单
  211. $this->onReceiveCompleted($storeId, $orderIds);
  212. //分佣结算逻辑
  213. /* foreach ($orderIds as $orderId){
  214. //分佣结算逻辑
  215. $cm = new GiveOutCommission();
  216. $flag = $cm->confirmGoodsCommission($orderId);
  217. if ($flag == false){
  218. log_record('订单分佣结算失败:'.$orderId);
  219. }
  220. //order_goods的财务结算状态变更
  221. OrderGoods::where('order_id',$orderId)->update(['finance_clearing_status'=>OrderGoods::FINANCE_CLEARING_WAIT]);
  222. }*/
  223. }
  224. // 记录日志
  225. Tools::taskLogs('Order', 'receiveEvent', [
  226. 'storeId' => $storeId,
  227. 'receiveDays' => $receiveDays,
  228. 'deadlineTime' => $deadlineTime,
  229. 'orderIds' => helper::jsonEncode($orderIds)
  230. ]);
  231. }
  232. /**
  233. * 已完成订单自动结算
  234. * @param int $storeId
  235. * @param int $refundDays 售后期限天数
  236. * @throws \think\db\exception\DataNotFoundException
  237. * @throws \think\db\exception\DbException
  238. * @throws \think\db\exception\ModelNotFoundException
  239. */
  240. public function settledEvent(int $storeId, int $refundDays)
  241. {
  242. // 截止时间
  243. $deadlineTime = time() - ((int)$refundDays * 86400);
  244. // 查询截止时间确认收货的订单ID集
  245. $model = new OrderModel;
  246. $list = $model->getOrderListBySettled($storeId, $deadlineTime);
  247. // 订单ID集
  248. $orderIds = helper::getArrayColumn($list, 'order_id');
  249. // 订单结算服务
  250. if (!empty($orderIds)) {
  251. $OrderCompleteService = new OrderCompleteService();
  252. $OrderCompleteService->settled($list);
  253. }
  254. // 记录日志
  255. Tools::taskLogs('Order', 'settledEvent', [
  256. 'storeId' => $storeId,
  257. 'refundDays' => $refundDays,
  258. 'deadlineTime' => $deadlineTime,
  259. 'orderIds' => helper::jsonEncode($orderIds)
  260. ]);
  261. }
  262. /**
  263. * 已确认收货订单自动评价
  264. * @param int $storeId
  265. * @param int $commentDays 评价期限天数
  266. * @throws \think\db\exception\DataNotFoundException
  267. * @throws \think\db\exception\DbException
  268. * @throws \think\db\exception\ModelNotFoundException
  269. */
  270. public function commentEvent(int $storeId, int $commentDays)
  271. {
  272. // 截止时间
  273. $deadlineTime = time() - ((int)$commentDays * 86400);
  274. // 查询截止时间确认收货的订单ID集
  275. $model = new OrderModel;
  276. $list = $model->getOrderListByComment($storeId, $deadlineTime);
  277. // 订单ID集
  278. $orderIds = helper::getArrayColumn($list, 'order_id');
  279. // 订单评价服务
  280. if (!empty($orderIds)) {
  281. $OrderCompleteService = new OrderCompleteService();
  282. $OrderCompleteService->comment($list);
  283. }
  284. // 记录日志
  285. Tools::taskLogs('Order', 'commentEvent', [
  286. 'storeId' => $storeId,
  287. 'commentDays' => $commentDays,
  288. 'deadlineTime' => $deadlineTime,
  289. 'orderIds' => helper::jsonEncode($orderIds),
  290. ]);
  291. }
  292. /**
  293. * 批量处理已完成的订单
  294. * @param int $storeId 商城ID
  295. * @param array $orderIds 订单ID集
  296. * @return bool
  297. * @throws \think\db\exception\DataNotFoundException
  298. * @throws \think\db\exception\DbException
  299. * @throws \think\db\exception\ModelNotFoundException
  300. */
  301. private function onReceiveCompleted(int $storeId, array $orderIds)
  302. {
  303. // 获取已完成的订单列表
  304. $model = new OrderModel;
  305. $list = $model->getListByOrderIds($storeId, $orderIds);
  306. // 执行订单完成后的操作
  307. if (!$list->isEmpty()) {
  308. $OrderCompleteService = new OrderCompleteService();
  309. $OrderCompleteService->complete($list, $storeId);
  310. }
  311. return true;
  312. }
  313. }