OrderCron.Class.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. <?php
  2. namespace JinDouYun\Controller\Cron;
  3. use JinDouYun\Controller\Common\Logger;
  4. use JinDouYun\Dao\Enterprise\DEnterprise;
  5. use JinDouYun\Dao\Order\DOrder;
  6. use JinDouYun\Dao\Order\DOrderIndex;
  7. use JinDouYun\Model\Stock\MInventory;
  8. use Mall\Framework\Core\StatusCode;
  9. /**
  10. * 订单
  11. * 基本设置增加配置:
  12. * orderAutoCloseSec (货到付款的订单未审核,自动取消订单的时间节点 单位:秒)
  13. * orderAutoFinishSec (订单出库后用户未确认收货. 自动收货节点 单位:秒)
  14. * Class OrderCron
  15. * @package JinDouYun\Controller\Cron
  16. */
  17. class OrderCron
  18. {
  19. /**
  20. * 切割数量
  21. * @var int
  22. */
  23. private $cutTable = 200000;
  24. /**
  25. * 企业列表
  26. * @var array|null
  27. */
  28. private $enterprises = null;
  29. /**
  30. * 当前时间戳
  31. * @var int
  32. */
  33. private $nowTime;
  34. /**
  35. * @var DOrderIndex
  36. */
  37. private $objDOrderIndex;
  38. /**
  39. * @var DOrder
  40. */
  41. private $objDOrder;
  42. /**
  43. * OrderCron constructor.
  44. * @throws \Exception
  45. */
  46. public function __construct()
  47. {
  48. echo date('Y-m-d H:i:s') . ':订单定时任务执行开始' . PHP_EOL;
  49. $this->nowTime = time();
  50. $this->objDOrderIndex = new DOrderIndex();
  51. $this->objDOrder = new DOrder();
  52. $this->objDOrder->setSearchIndex('order_search')->setType('order');
  53. //获取企业
  54. $fields = "e.id,e.enterpriseName,b.basicData";
  55. $sql = 'SELECT ' . $fields . ' FROM qianniao_enterprise_1 as e
  56. LEFT JOIN qianniao_basic_setup as b ON e.id=b.enterpriseId
  57. WHERE b.id IS NOT NULL';
  58. $objDEnterprise = new DEnterprise();
  59. $enterprises = $objDEnterprise->query($sql);
  60. if ($enterprises === false) {
  61. die('查询企业列表失败');
  62. }
  63. foreach ($enterprises as $val){
  64. $json = json_decode($val['basicData'],true);
  65. $this->enterprises[] = [
  66. 'enterpriseId' => $val['id'],
  67. 'enterpriseName' => $val['enterpriseName'],
  68. 'orderAutoCloseSec' => isset($json['orderAutoCloseSec']) ? $json['orderAutoCloseSec'] : null, //自动取消订单设置
  69. 'orderAutoFinishSec' => isset($json['orderAutoFinishSec']) ? $json['orderAutoFinishSec'] : null, //自动收货订单设置
  70. ];
  71. }
  72. if (empty($this->enterprises)) {
  73. die('没有企业订单数据待处理');
  74. }
  75. }
  76. /**
  77. * 自动关闭订单
  78. * condition 订单创建时间 < 当前时间戳-自动关闭时间秒, payType = 3, auditStatus=1, payStatus=4,orderStatus != 6
  79. * @throws \Exception
  80. */
  81. public function autoClose()
  82. {
  83. $field = 'id,userCenterId';
  84. foreach ($this->enterprises as $item) {
  85. //检查企业是否配置订单未支付自动关闭
  86. if (empty((int) $item['orderAutoCloseSec'])) {
  87. file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/cron.log', date('Y-m-d H:i:s') . $item['enterpriseName'] . '未配置订单自动关闭时间,不进行处理' . PHP_EOL, FILE_APPEND);
  88. echo $item['enterpriseName'].'未配置自动取消时间'.PHP_EOL;
  89. continue;
  90. }
  91. //检查过期时间
  92. $expire = $this->nowTime - $item['orderAutoCloseSec'];
  93. $sql = 'SELECT ' . $field . ' FROM qianniao_order_index_' . $item['enterpriseId'] . '
  94. WHERE createTime>1593446400 AND
  95. auditStatus=' . StatusCode::$auditStatus['auditing'] . ' AND
  96. payStatus=' . StatusCode::$delete . ' AND
  97. orderStatus!=' . StatusCode::$orderStatus['close'] . ' AND
  98. createTime < ' . $expire;
  99. //查询数据
  100. // 根据索引表查询订单索引数据
  101. $orderList = $this->objDOrderIndex->query($sql);
  102. if ($orderList === false) {
  103. file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/cron.log', date('Y-m-d H:i:s') . $item['enterpriseName'] . '查询订单时出错' . $this->objDOrderIndex->error() . PHP_EOL, FILE_APPEND);
  104. echo '查询订单时出错'.$this->objDOrderIndex->error().PHP_EOL;
  105. continue;
  106. }
  107. //没有数据
  108. if (empty($orderList)) {
  109. echo $item['enterpriseName'] . '-没有需要处理的订单' . PHP_EOL;
  110. continue;
  111. }
  112. $count = count((array)$orderList);
  113. //处理数据,计算表后缀
  114. $allGroupOrder = [];
  115. foreach ($orderList as $value) {
  116. $tableNum = ceil($value['userCenterId'] / $this->cutTable);
  117. $allGroupOrder[$tableNum][] = $value['id'];
  118. }
  119. //更新操作
  120. $this->objDOrderIndex->beginTransaction();
  121. //更新订单表
  122. foreach ($allGroupOrder as $fix => $row) {
  123. //切换订单分表
  124. $this->objDOrder->setTable('qianniao_order_' . $item['enterpriseId'] . '_' . $fix);
  125. //更新数据
  126. //根据订单编号修改订单数据
  127. $orderUpdate = $this->objDOrder->update(
  128. [
  129. 'orderStatus' => StatusCode::$orderStatus['close'],
  130. 'updateTime' => $this->nowTime
  131. ],
  132. ['id' => $row]
  133. );
  134. if ($orderUpdate === false) {
  135. file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/cron.log', date('Y-m-d H:i:s') . $item['enterpriseName'] . 'update订单时出错' . $this->objDOrder->error() . PHP_EOL, FILE_APPEND);
  136. $this->objDOrderIndex->rollBack();
  137. die('更新订单时出错');
  138. }
  139. //解锁库存
  140. $objMInventory = new MInventory($item['enterpriseId'], '');
  141. $unlockResult = $objMInventory->unlockInventory($row, StatusCode::$orderType['saleOrder'], $this->nowTime);
  142. if (!$unlockResult->isSuccess()) {
  143. file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/cron.log', date('Y-m-d H:i:s') . $item['enterpriseName'] . '解锁库存时出错' . $unlockResult->getData() . PHP_EOL, FILE_APPEND);
  144. $this->objDOrderIndex->rollBack();
  145. die('关闭订单时解锁库存失败');
  146. }
  147. }
  148. //更新订单索引表
  149. $this->objDOrderIndex->setTable('qianniao_order_index_' . $item['enterpriseId']);
  150. $orderIndexUpdate = $this->objDOrderIndex->update(
  151. [
  152. 'orderStatus' => StatusCode::$orderStatus['close'],
  153. 'updateTime' => $this->nowTime
  154. ],
  155. [
  156. 'id' => array_values(array_column((array)$orderList, 'id'))
  157. ]
  158. );
  159. if ($orderIndexUpdate === false) {
  160. file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/cron.log', date('Y-m-d H:i:s') . $item['enterpriseName'] . '解锁库存时出错' . $this->objDOrderIndex->error() . PHP_EOL, FILE_APPEND);
  161. $this->objDOrderIndex->rollBack();
  162. die('更新订单索引表时出错');
  163. }
  164. echo date('Y-m-d H:i:s') . 'SUCCESS:' . $item['enterpriseName'] . '处理成功,共处理' . $count . '条数据' . PHP_EOL;
  165. $this->objDOrderIndex->commit();
  166. // //在ES更新订单状态
  167. // foreach ($orderList as $list) {
  168. // $_id = self::createEsDocumentId($list['id'], $item['enterpriseId']);
  169. // $this->objDOrder->esupdateTypeFieldVaule(['orderStatus' => StatusCode::$orderStatus['close']], $_id);
  170. // }
  171. }
  172. }
  173. /**
  174. * 自动完成订单
  175. * 订单出库后用户未确认收货. 自动收货
  176. *
  177. * @throws \Exception
  178. */
  179. public function autoFinish()
  180. {
  181. $field = 'id,userCenterId';
  182. foreach ($this->enterprises as $item) {
  183. //检查企业是否配置订单自动完成
  184. if (empty((int)$item['orderAutoFinishSec'])) {
  185. echo $item['enterpriseName'].'未配置自动收货时间'.PHP_EOL;
  186. continue;
  187. }
  188. $expire = $this->nowTime - $item['orderAutoFinishSec'];
  189. $sql = 'SELECT ' . $field . ' FROM qianniao_order_index_' . $item['enterpriseId'] . '
  190. WHERE createTime>1620907760 AND
  191. outStatus=' . StatusCode::$standard . ' AND
  192. (orderStatus !=' . StatusCode::$orderStatus['finish'] . ' or isRet = '.StatusCode::$standard.') AND
  193. outTime < ' . $expire;
  194. //查询数据
  195. $orderList = $this->objDOrderIndex->query($sql);
  196. if ($orderList === false) {
  197. echo '查询订单时出错'.$this->objDOrderIndex->error().PHP_EOL;
  198. continue;
  199. }
  200. //没有数据
  201. if (empty($orderList)) {
  202. echo $item['enterpriseName'] . '-没有需要处理的订单' . PHP_EOL;
  203. continue;
  204. }
  205. $count = count((array)$orderList);
  206. //处理数据,计算表后缀
  207. $allGroupOrder = [];
  208. foreach ($orderList as $value) {
  209. $tableNum = ceil($value['userCenterId'] / $this->cutTable);
  210. $allGroupOrder[$tableNum][] = $value['id'];
  211. }
  212. //更新操作
  213. $this->objDOrderIndex->beginTransaction();
  214. //更新订单表
  215. foreach ($allGroupOrder as $fix => $row) {
  216. //切换订单分表
  217. $this->objDOrder->setTable('qianniao_order_' . $item['enterpriseId'] . '_' . $fix);
  218. //更新数据
  219. $orderUpdate = $this->objDOrder->update(
  220. [
  221. 'orderStatus' => StatusCode::$orderStatus['finish'],
  222. 'updateTime' => $this->nowTime,
  223. 'successFullyTime' => $this->nowTime
  224. ],
  225. ['id' => $row]
  226. );
  227. if ($orderUpdate === false) {
  228. echo $item['enterpriseName'] . 'update订单时出错' . $this->objDOrder->error() . PHP_EOL;
  229. $this->objDOrderIndex->rollBack();
  230. die('更新订单时出错');
  231. }
  232. }
  233. $this->objDOrderIndex->setTable('qianniao_order_index_' . $item['enterpriseId']);
  234. $orderIndexUpdate = $this->objDOrderIndex->update(
  235. [
  236. 'orderStatus' => StatusCode::$orderStatus['finish'],
  237. 'updateTime' => $this->nowTime
  238. ],
  239. [
  240. 'id' => array_values(array_column((array)$orderList, 'id'))
  241. ]
  242. );
  243. if ($orderIndexUpdate === false) {
  244. echo $item['enterpriseName'] . '解锁库存时出错' . $this->objDOrderIndex->error() . PHP_EOL;
  245. $this->objDOrderIndex->rollBack();
  246. die('更新订单索引表时出错');
  247. }
  248. echo date('Y-m-d H:i:s') . 'autoFinish-SUCCESS:' . $item['enterpriseName'] . '处理成功,共处理' . $count . '条数据' . PHP_EOL;
  249. $this->objDOrderIndex->commit();
  250. //在ES更新订单审核状态
  251. /*foreach ($orderList as $list) {
  252. $_id = self::createEsDocumentId($list['orderId'], $item['enterpriseId']);
  253. $this->objDOrder->esupdateTypeFieldVaule(['orderStatus' => StatusCode::$orderStatus['finish']], $_id);
  254. }*/
  255. }
  256. }
  257. /**
  258. * 创建文档id
  259. * @param $orderIndexId
  260. * @param $enterpriseId
  261. * @return string
  262. */
  263. private function createEsDocumentId(int $orderIndexId, int $enterpriseId)
  264. {
  265. return 'EnterpriseId_' . $enterpriseId . '_OrderIndexId_' . $orderIndexId;
  266. }
  267. public function __destruct()
  268. {
  269. // TODO: Implement __destruct() method.
  270. echo date('Y-m-d H:i:s') . ':订单定时任务执行结束' . PHP_EOL;
  271. }
  272. }