DelayQueueOrder.Class.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace JinDouYun\Controller\Cron;
  3. use JinDouYun\Controller\Common\Logger;
  4. use Mall\Framework\Factory;
  5. use Mall\Framework\Cache\Redis;
  6. /**
  7. * Description: redis延时队列,订单延时取消
  8. * Class DelayQueueOrder
  9. * @package JinDouYun\Controller\Cron
  10. */
  11. class DelayQueueOrder
  12. {
  13. /**
  14. * @var Redis
  15. */
  16. private $cache;
  17. /**
  18. * @var string
  19. */
  20. private $delayQueueCancelOrderKey = 'delay_queue_cancel_order';
  21. /**
  22. * @var int
  23. */
  24. private $enterpriseId;
  25. /**
  26. * DelayQueueOrder constructor.
  27. * @throws \Exception
  28. */
  29. public function __construct()
  30. {
  31. $this->cache = Factory::cache('default');
  32. $params = self::cliParams();
  33. if (empty($params)){
  34. Logger::logs(E_USER_ERROR,'命令行参数为空',__CLASS__,__LINE__,$params,true);
  35. exit();
  36. }
  37. $enterpriseId = isset($params['enterpriseId']) ? $params['enterpriseId'] : null;
  38. if (empty($enterpriseId)){
  39. Logger::logs(E_USER_ERROR,'enterpriseId参数错误',__CLASS__,__LINE__,true);
  40. exit();
  41. }
  42. $this->enterpriseId = $enterpriseId;
  43. }
  44. /**
  45. * Doc: (des="延时队列,取消订单")
  46. * User: XMing
  47. * Date: 2020/9/23
  48. * Time: 2:36 下午
  49. */
  50. public function run()
  51. {
  52. while (true){
  53. //从有序集合中拿到n秒以前的订单
  54. //TODO 这里要解决每个企业配置不同的订单失效时间问题 (通过命令行传餐 每个企业运行独立的延迟队列)
  55. //TODO 不能放在初始化中查询企业配置,企业配置是动态的(5分钟查询一次当前企业最新配置)
  56. $orderIds = $this->cache->zrangebyscore($this->delayQueueCancelOrderKey.'::'.$this->enterpriseId, 0, time()-60, ['withscores' => TRUE]);
  57. if(empty($orderIds)){
  58. sleep(1);
  59. continue;
  60. }
  61. //拿出的数据立马删除
  62. foreach ($orderIds as $orderId => $taskTime) {
  63. $delRes = $this->cache->zrem($this->delayQueueCancelOrderKey.'::'.$this->enterpriseId, $orderId);
  64. if (!$delRes){
  65. continue;
  66. }
  67. Logger::logs(E_USER_ERROR,'消费订单',__CLASS__,__LINE__,$orderId,true);
  68. }
  69. }
  70. }
  71. /**
  72. * Doc: (des="获取命令行下传递进来的参数")
  73. * User: XMing
  74. * Date: 2020/9/23
  75. * Time: 4:09 下午
  76. * @example php test.php -p3 -t=abc --opt=valopt --opt2 valopt2
  77. * @return array
  78. */
  79. private function cliParams()
  80. {
  81. $result = array();
  82. $params = $GLOBALS['argv'];
  83. array_shift($params);
  84. do {
  85. $tmpEachResult = array_shift($params);
  86. if (!$tmpEachResult) {
  87. break;
  88. }
  89. $p = $tmpEachResult;
  90. if ($p{0} == '-') {
  91. $pname = substr($p, 1);
  92. $value = false;
  93. if ($pname{0} == '-') {// 长选项 (--<param>)
  94. $pname = substr($pname, 1);
  95. if (strpos($p, '=') !== false) {
  96. // value specified inline (--<param>=<value>)
  97. list($pname, $value) = explode('=', substr($p, 2), 2);
  98. }
  99. } else {// 短选项
  100. if (strpos($p, '=') !== false) {
  101. // value specified inline (-<param>=<value>)
  102. list($pname, $value) = explode('=', substr($p, 1), 2);
  103. } else if (strlen($p) > 1) {
  104. $pname = substr($p, 1, 1);
  105. $value = substr($p, 2);
  106. }
  107. }
  108. # 如果上面没有取到值,并且下一个不是以-开头的,则下一个值为当前参数的值
  109. $nextparm = current($params);
  110. if ($value === false
  111. && $nextparm !== false
  112. && $nextparm{0} != '-'
  113. ) {
  114. $value = array_shift($params);
  115. }
  116. $result[$pname] = (string)$value;// 将 false转为空串,以便与http访问时对参数的处理一致
  117. } else {
  118. # 不是以-指定开始的参数,一律丢弃
  119. //$result[] = $p;
  120. }
  121. } while (true);
  122. return $result;
  123. }
  124. }