|
@@ -0,0 +1,155 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+namespace common\components;
|
|
|
|
|
+
|
|
|
|
|
+use Yii;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 飞鹅云打印日志(Redis 缓存,按 mainId + orderId 聚合)
|
|
|
|
|
+ */
|
|
|
|
|
+class feiePrintLogUtil
|
|
|
|
|
+{
|
|
|
|
|
+ /** 日志缓存 TTL:180 天 */
|
|
|
|
|
+ const CACHE_TTL = 15552000;
|
|
|
|
|
+
|
|
|
|
|
+ /** 待回调映射 TTL:180 天 */
|
|
|
|
|
+ const MAP_TTL = 15552000;
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 订单打印日志 Redis Key
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function logCacheKey($mainId, $orderId)
|
|
|
|
|
+ {
|
|
|
|
|
+ return 'feie_print_log:' . intval($mainId) . ':' . intval($orderId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 飞鹅订单 ID 反查 Redis Key
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function mapCacheKey($feieOrderId)
|
|
|
|
|
+ {
|
|
|
|
|
+ return 'feie_print_map:' . trim((string)$feieOrderId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 打印提交成功后写入 pending 记录,并建立 feieOrderId 反查索引
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function appendPending($mainId, $orderId, $orderSn, $printSn, $feieOrderId)
|
|
|
|
|
+ {
|
|
|
|
|
+ $mainId = intval($mainId);
|
|
|
|
|
+ $orderId = intval($orderId);
|
|
|
|
|
+ $feieOrderId = trim((string)$feieOrderId);
|
|
|
|
|
+ if ($mainId <= 0 || $orderId <= 0 || $feieOrderId === '') {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $mapKey = self::mapCacheKey($feieOrderId);
|
|
|
|
|
+ $mapData = json_encode([
|
|
|
|
|
+ 'mainId' => $mainId,
|
|
|
|
|
+ 'orderId' => $orderId,
|
|
|
|
|
+ 'orderSn' => (string)$orderSn,
|
|
|
|
|
+ 'printSn' => (string)$printSn,
|
|
|
|
|
+ ], JSON_UNESCAPED_UNICODE);
|
|
|
|
|
+ Yii::$app->redis->executeCommand('SETEX', [$mapKey, self::MAP_TTL, $mapData]);
|
|
|
|
|
+
|
|
|
|
|
+ $logKey = self::logCacheKey($mainId, $orderId);
|
|
|
|
|
+ $list = self::decodeList(Yii::$app->redis->executeCommand('GET', [$logKey]));
|
|
|
|
|
+ $list[] = [
|
|
|
|
|
+ 'orderSn' => (string)$orderSn,
|
|
|
|
|
+ 'printSn' => (string)$printSn,
|
|
|
|
|
+ 'feieOrderId' => $feieOrderId,
|
|
|
|
|
+ 'printTime' => 0,
|
|
|
|
|
+ 'printTimeText' => '',
|
|
|
|
|
+ 'status' => 0,
|
|
|
|
|
+ ];
|
|
|
|
|
+ Yii::$app->redis->executeCommand('SETEX', [$logKey, self::CACHE_TTL, json_encode($list, JSON_UNESCAPED_UNICODE)]);
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 飞鹅回调更新打印时间与状态
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function updateByCallback($feieOrderId, $stime, $status, $rawCallback = [])
|
|
|
|
|
+ {
|
|
|
|
|
+ $feieOrderId = trim((string)$feieOrderId);
|
|
|
|
|
+ if ($feieOrderId === '') {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $mapRaw = Yii::$app->redis->executeCommand('GET', [self::mapCacheKey($feieOrderId)]);
|
|
|
|
|
+ if (empty($mapRaw)) {
|
|
|
|
|
+ Yii::warning('飞鹅打印回调未找到映射: ' . $feieOrderId, __METHOD__);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $map = json_decode($mapRaw, true);
|
|
|
|
|
+ if (empty($map['mainId']) || empty($map['orderId'])) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $logKey = self::logCacheKey($map['mainId'], $map['orderId']);
|
|
|
|
|
+ $list = self::decodeList(Yii::$app->redis->executeCommand('GET', [$logKey]));
|
|
|
|
|
+ $stime = intval($stime);
|
|
|
|
|
+ $updated = false;
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($list as &$item) {
|
|
|
|
|
+ if (($item['feieOrderId'] ?? '') === $feieOrderId) {
|
|
|
|
|
+ $item['printTime'] = $stime;
|
|
|
|
|
+ $item['printTimeText'] = $stime > 0 ? date('Y-m-d H:i:s', $stime) : '';
|
|
|
|
|
+ $item['status'] = intval($status);
|
|
|
|
|
+ if (!empty($rawCallback)) {
|
|
|
|
|
+ $item['callbackInfo'] = $rawCallback;
|
|
|
|
|
+ }
|
|
|
|
|
+ $updated = true;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ unset($item);
|
|
|
|
|
+
|
|
|
|
|
+ if (!$updated) {
|
|
|
|
|
+ $list[] = [
|
|
|
|
|
+ 'orderSn' => (string)($map['orderSn'] ?? ''),
|
|
|
|
|
+ 'printSn' => (string)($map['printSn'] ?? ''),
|
|
|
|
|
+ 'feieOrderId' => $feieOrderId,
|
|
|
|
|
+ 'printTime' => $stime,
|
|
|
|
|
+ 'printTimeText' => $stime > 0 ? date('Y-m-d H:i:s', $stime) : '',
|
|
|
|
|
+ 'status' => intval($status),
|
|
|
|
|
+ 'callbackInfo' => $rawCallback,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Yii::$app->redis->executeCommand('SETEX', [$logKey, self::CACHE_TTL, json_encode($list, JSON_UNESCAPED_UNICODE)]);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 读取订单打印日志,按 printTime 降序
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function getList($mainId, $orderId)
|
|
|
|
|
+ {
|
|
|
|
|
+ $logKey = self::logCacheKey($mainId, $orderId);
|
|
|
|
|
+ $list = self::decodeList(Yii::$app->redis->executeCommand('GET', [$logKey]));
|
|
|
|
|
+ usort($list, function ($a, $b) {
|
|
|
|
|
+ $timeA = intval($a['printTime'] ?? 0);
|
|
|
|
|
+ $timeB = intval($b['printTime'] ?? 0);
|
|
|
|
|
+ if ($timeA === $timeB) {
|
|
|
|
|
+ return strcmp($b['feieOrderId'] ?? '', $a['feieOrderId'] ?? '');
|
|
|
|
|
+ }
|
|
|
|
|
+ return $timeB <=> $timeA;
|
|
|
|
|
+ });
|
|
|
|
|
+ return $list;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 解析 Redis 中的 JSON 数组
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function decodeList($raw)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($raw)) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+ $list = json_decode($raw, true);
|
|
|
|
|
+ return is_array($list) ? $list : [];
|
|
|
|
|
+ }
|
|
|
|
|
+}
|