feiePrintLogUtil.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. namespace common\components;
  3. use Yii;
  4. /**
  5. * 飞鹅云打印日志(Redis 缓存,按 mainId + orderId 聚合)
  6. */
  7. class feiePrintLogUtil
  8. {
  9. /** 日志缓存 TTL:30 天 */
  10. const CACHE_TTL = 2592000;
  11. /** 待回调映射 TTL:30 天 */
  12. const MAP_TTL = 2592000;
  13. /**
  14. * 订单打印日志 Redis Key
  15. */
  16. public static function logCacheKey($mainId, $orderId)
  17. {
  18. return 'feie_print_log:' . intval($mainId) . ':' . intval($orderId);
  19. }
  20. /**
  21. * 飞鹅订单 ID 反查 Redis Key
  22. */
  23. public static function mapCacheKey($feieOrderId)
  24. {
  25. return 'feie_print_map:' . trim((string)$feieOrderId);
  26. }
  27. /**
  28. * 打印提交成功后写入 pending 记录,并建立 feieOrderId 反查索引
  29. */
  30. public static function appendPending($mainId, $orderId, $orderSn, $printSn, $feieOrderId)
  31. {
  32. $mainId = intval($mainId);
  33. $orderId = intval($orderId);
  34. $feieOrderId = trim((string)$feieOrderId);
  35. if ($mainId <= 0 || $orderId <= 0 || $feieOrderId === '') {
  36. return false;
  37. }
  38. $mapKey = self::mapCacheKey($feieOrderId);
  39. $mapData = json_encode([
  40. 'mainId' => $mainId,
  41. 'orderId' => $orderId,
  42. 'orderSn' => (string)$orderSn,
  43. 'printSn' => (string)$printSn,
  44. ], JSON_UNESCAPED_UNICODE);
  45. Yii::$app->redis->executeCommand('SETEX', [$mapKey, self::MAP_TTL, $mapData]);
  46. $logKey = self::logCacheKey($mainId, $orderId);
  47. $list = self::decodeList(Yii::$app->redis->executeCommand('GET', [$logKey]));
  48. $list[] = [
  49. 'orderSn' => (string)$orderSn,
  50. 'printSn' => (string)$printSn,
  51. 'feieOrderId' => $feieOrderId,
  52. 'printTime' => 0,
  53. 'printTimeText' => '',
  54. 'status' => 0,
  55. ];
  56. Yii::$app->redis->executeCommand('SETEX', [$logKey, self::CACHE_TTL, json_encode($list, JSON_UNESCAPED_UNICODE)]);
  57. return true;
  58. }
  59. /**
  60. * 飞鹅回调更新打印时间与状态
  61. */
  62. public static function updateByCallback($feieOrderId, $stime, $status, $rawCallback = [])
  63. {
  64. $feieOrderId = trim((string)$feieOrderId);
  65. if ($feieOrderId === '') {
  66. return false;
  67. }
  68. $mapRaw = Yii::$app->redis->executeCommand('GET', [self::mapCacheKey($feieOrderId)]);
  69. if (empty($mapRaw)) {
  70. Yii::warning('飞鹅打印回调未找到映射: ' . $feieOrderId, __METHOD__);
  71. return false;
  72. }
  73. $map = json_decode($mapRaw, true);
  74. if (empty($map['mainId']) || empty($map['orderId'])) {
  75. return false;
  76. }
  77. $logKey = self::logCacheKey($map['mainId'], $map['orderId']);
  78. $list = self::decodeList(Yii::$app->redis->executeCommand('GET', [$logKey]));
  79. $stime = intval($stime);
  80. $updated = false;
  81. foreach ($list as &$item) {
  82. if (($item['feieOrderId'] ?? '') === $feieOrderId) {
  83. $item['printTime'] = $stime;
  84. $item['printTimeText'] = $stime > 0 ? date('Y-m-d H:i:s', $stime) : '';
  85. $item['status'] = intval($status);
  86. if (!empty($rawCallback)) {
  87. $item['callbackInfo'] = $rawCallback;
  88. }
  89. $updated = true;
  90. break;
  91. }
  92. }
  93. unset($item);
  94. if (!$updated) {
  95. $list[] = [
  96. 'orderSn' => (string)($map['orderSn'] ?? ''),
  97. 'printSn' => (string)($map['printSn'] ?? ''),
  98. 'feieOrderId' => $feieOrderId,
  99. 'printTime' => $stime,
  100. 'printTimeText' => $stime > 0 ? date('Y-m-d H:i:s', $stime) : '',
  101. 'status' => intval($status),
  102. 'callbackInfo' => $rawCallback,
  103. ];
  104. }
  105. Yii::$app->redis->executeCommand('SETEX', [$logKey, self::CACHE_TTL, json_encode($list, JSON_UNESCAPED_UNICODE)]);
  106. return true;
  107. }
  108. /**
  109. * 读取订单打印日志,按 printTime 降序
  110. */
  111. public static function getList($mainId, $orderId)
  112. {
  113. $logKey = self::logCacheKey($mainId, $orderId);
  114. $list = self::decodeList(Yii::$app->redis->executeCommand('GET', [$logKey]));
  115. usort($list, function ($a, $b) {
  116. $timeA = intval($a['printTime'] ?? 0);
  117. $timeB = intval($b['printTime'] ?? 0);
  118. if ($timeA === $timeB) {
  119. return strcmp($b['feieOrderId'] ?? '', $a['feieOrderId'] ?? '');
  120. }
  121. return $timeB <=> $timeA;
  122. });
  123. return $list;
  124. }
  125. /**
  126. * 解析 Redis 中的 JSON 数组
  127. */
  128. protected static function decodeList($raw)
  129. {
  130. if (empty($raw)) {
  131. return [];
  132. }
  133. $list = json_decode($raw, true);
  134. return is_array($list) ? $list : [];
  135. }
  136. }