AutoRun.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | framework
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2014~2018 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://framework.thinkadmin.top
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( https://mit-license.org )
  10. // +----------------------------------------------------------------------
  11. // | github开源项目:https://github.com/zoujingli/framework
  12. // +----------------------------------------------------------------------
  13. namespace app\store\command;
  14. use think\Db;
  15. /**
  16. * 商城数据处理指令
  17. * Class AutoRun
  18. * @package app\store\command
  19. */
  20. class AutoRun extends \think\console\Command
  21. {
  22. protected function configure()
  23. {
  24. $this->setName('xclean:store')->setDescription('clean up invalid store records');
  25. }
  26. /**
  27. * 业务指令执行
  28. * @param \think\console\Input $input
  29. * @param \think\console\Output $output
  30. * @throws \think\Exception
  31. * @throws \think\db\exception\DataNotFoundException
  32. * @throws \think\db\exception\ModelNotFoundException
  33. * @throws \think\exception\DbException
  34. * @throws \think\exception\PDOException
  35. */
  36. protected function execute(\think\console\Input $input, \think\console\Output $output)
  37. {
  38. // 自动取消30分钟未支付的订单
  39. $this->autoCancelOrder();
  40. // 清理一天前未支付的订单
  41. $this->autoRemoveOrder();
  42. // 订单自动退款处理
  43. // $this->autoRefundOrder();
  44. // 提现自动打款处理
  45. // $this->autoTransfer();
  46. }
  47. /**
  48. * 自动取消30分钟未支付的订单
  49. * @throws \think\Exception
  50. * @throws \think\exception\PDOException
  51. */
  52. private function autoCancelOrder()
  53. {
  54. $datetime = $this->getDatetime('store_order_wait_time');
  55. $where = [['status', 'in', ['1', '2']], ['pay_state', 'eq', '0'], ['create_at', '<', $datetime]];
  56. $count = Db::name('StoreOrder')->where($where)->update([
  57. 'status' => '0',
  58. 'cancel_state' => '1',
  59. 'cancel_at' => date('Y-m-d H:i:s'),
  60. 'cancel_desc' => '30分钟未完成支付自动取消订单',
  61. ]);
  62. if ($count > 0) {
  63. $this->output->info("共计自动取消了30分钟未支付的{$count}笔订单!");
  64. } else {
  65. $this->output->comment('没有需要自动取消30分钟未支付的订单记录!');
  66. }
  67. }
  68. /**
  69. * 清理一天前未支付的订单
  70. * @throws \think\Exception
  71. * @throws \think\db\exception\DataNotFoundException
  72. * @throws \think\db\exception\ModelNotFoundException
  73. * @throws \think\exception\DbException
  74. * @throws \think\exception\PDOException
  75. */
  76. private function autoRemoveOrder()
  77. {
  78. $datetime = $this->getDatetime('store_order_clear_time');
  79. $where = [['status', 'eq', '0'], ['pay_state', 'eq', '0'], ['create_at', '<', $datetime]];
  80. $list = Db::name('StoreOrder')->where($where)->limit(20)->select();
  81. if (count($orderNos = array_unique(array_column($list, 'order_no'))) > 0) {
  82. $this->output->info("自动删除前一天已经取消的订单:" . PHP_EOL . join(',' . PHP_EOL, $orderNos));
  83. Db::name('StoreOrder')->whereIn('order_no', $orderNos)->delete();
  84. Db::name('StoreOrderList')->whereIn('order_no', $orderNos)->delete();
  85. } else {
  86. $this->output->comment('没有需要自动删除前一天已经取消的订单!');
  87. }
  88. }
  89. /**
  90. * 订单自动退款操作
  91. * @throws \think\Exception
  92. * @throws \think\db\exception\DataNotFoundException
  93. * @throws \think\db\exception\ModelNotFoundException
  94. * @throws \think\exception\DbException
  95. * @throws \think\exception\PDOException
  96. */
  97. private function autoRefundOrder()
  98. {
  99. // 未完成退款的订单,执行微信退款操作
  100. foreach (Db::name('StoreOrder')->where(['refund_state' => '1'])->select() as $order) {
  101. try {
  102. $this->output->writeln("正在为 {$order['order_no']} 执行退款操作...");
  103. $result = \We::WePayRefund(config('wechat.wxpay'))->create([
  104. 'transaction_id' => $order['pay_no'],
  105. 'out_refund_no' => $order['refund_no'],
  106. 'total_fee' => $order['price_total'] * 100,
  107. 'refund_fee' => $order['pay_price'] * 100,
  108. 'refund_account' => 'REFUND_SOURCE_UNSETTLED_FUNDS',
  109. ]);
  110. if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
  111. Db::name('StoreOrder')->where(['order_no' => $order['order_no']])->update([
  112. 'refund_state' => '2', 'refund_desc' => '自动退款成功!',
  113. ]);
  114. } else {
  115. Db::name('StoreOrder')->where(['order_no' => $order['order_no']])->update([
  116. 'refund_desc' => isset($result['err_code_des']) ? $result['err_code_des'] : '自动退款失败',
  117. ]);
  118. }
  119. } catch (\Exception $e) {
  120. $this->output->writeln("订单 {$order['order_no']} 执行退款失败,{$e->getMessage()}!");
  121. Db::name('StoreOrder')->where(['order_no' => $order['order_no']])->update(['refund_desc' => $e->getMessage()]);
  122. }
  123. }
  124. $this->output->writeln('自动检测退款订单执行完成!');
  125. }
  126. /**
  127. * 自动企业打款操作
  128. * @throws \think\Exception
  129. * @throws \think\db\exception\DataNotFoundException
  130. * @throws \think\db\exception\ModelNotFoundException
  131. * @throws \think\exception\DbException
  132. * @throws \think\exception\PDOException
  133. */
  134. private function autoTransfer()
  135. {
  136. # 批量企业打款
  137. foreach (Db::name('StoreProfitUsed')->where(['status' => '1'])->select() as $vo) {
  138. try {
  139. $wechat = \We::WePayTransfers(config('wechat.wxpay'));
  140. $result = $wechat->create([
  141. 'partner_trade_no' => $vo['trs_no'],
  142. 'openid' => $vo['openid'],
  143. 'check_name' => 'NO_CHECK',
  144. 'amount' => $vo['pay_price'] * 100,
  145. 'desc' => '营销活动拥金提现',
  146. 'spbill_create_ip' => '127.0.0.1',
  147. ]);
  148. if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
  149. Db::name('StoreProfitUsed')->where(['trs_no' => $vo['trs_no']])->update([
  150. 'status' => '2', 'pay_desc' => '拥金提现成功!', 'pay_no' => $result['payment_no'], 'pay_at' => date('Y-m-d H:i:s'),
  151. ]);
  152. } else {
  153. Db::name('StoreProfitUsed')->where(['trs_no' => $vo['trs_no']])->update([
  154. 'pay_desc' => isset($result['err_code_des']) ? $result['err_code_des'] : '自动打款失败', 'last_at' => date('Y-m-d H:i:s'),
  155. ]);
  156. }
  157. } catch (\Exception $e) {
  158. $this->output->writeln("订单 {$vo['trs_no']} 执行提现失败,{$e->getMessage()}!");
  159. Db::name('StoreProfitUsed')->where(['trs_no' => $vo['trs_no']])->update(['pay_desc' => $e->getMessage()]);
  160. }
  161. }
  162. }
  163. /**
  164. * 获取配置时间
  165. * @param string $code
  166. * @return string
  167. * @throws \think\Exception
  168. * @throws \think\exception\PDOException
  169. */
  170. private function getDatetime($code)
  171. {
  172. $minutes = intval(sysconf($code) * 60);
  173. return date('Y-m-d H:i:s', strtotime("-{$minutes} minutes"));
  174. }
  175. }