'integer', 'sync_status' => 'integer', 'sync_time' => 'integer', 'cost_time' => 'integer', 'retry_times' => 'integer', ]; /** * 同步状态常量 */ const STATUS_FAILED = 0; // 同步失败 const STATUS_SUCCESS = 1; // 同步成功 /** * 交易代码常量 */ const TX_CODE_PUSH = 'A3341TP01'; // 订单推送 const TX_CODE_UPDATE = 'A3341TP02'; // 订单状态更新 const TX_CODE_QUERY = 'A3341TP03'; // 订单查询 const TX_CODE_REFUND = 'A3341TP04'; // 订单退款 /** * 交易代码映射 * @var array */ public static $txCodeMap = [ self::TX_CODE_PUSH => '订单推送', self::TX_CODE_UPDATE => '状态更新', self::TX_CODE_QUERY => '订单查询', self::TX_CODE_REFUND => '订单退款', ]; /** * 同步状态映射 * @var array */ public static $statusMap = [ self::STATUS_FAILED => '失败', self::STATUS_SUCCESS => '成功', ]; /** * 获取交易代码文本 * * @param string $txCode 交易代码 * @return string */ public static function getTxCodeText($txCode) { return self::$txCodeMap[$txCode] ?? '未知交易'; } /** * 获取状态文本 * * @param int $status 状态值 * @return string */ public static function getStatusText($status) { return self::$statusMap[$status] ?? '未知状态'; } /** * 根据订单ID查找同步日志 * * @param int $orderId 订单ID * @param string $txCode 交易代码(可选) * @return array */ public static function findByOrderId($orderId, $txCode = '') { $query = self::where('order_id', $orderId); if ($txCode) { $query->where('tx_code', $txCode); } return $query->order('sync_time', 'desc')->select(); } /** * 根据交易流水号查找 * * @param string $txSeq 交易流水号 * @return CcbSyncLog|null */ public static function findByTxSeq($txSeq) { return self::where('tx_seq', $txSeq)->find(); } /** * 创建同步日志 * * @param array $data 日志数据 * @return CcbSyncLog|false */ public static function createLog($data) { $defaultData = [ 'sync_status' => self::STATUS_FAILED, 'sync_time' => time(), 'retry_times' => 0, 'cost_time' => 0, ]; $logData = array_merge($defaultData, $data); return self::create($logData); } /** * 更新同步状态 * * @param string $txSeq 交易流水号 * @param int $status 状态 * @param array $extraData 额外数据 * @return bool */ public static function updateStatus($txSeq, $status, $extraData = []) { $updateData = array_merge([ 'sync_status' => $status, ], $extraData); return self::where('tx_seq', $txSeq)->update($updateData) !== false; } /** * 记录同步成功 * * @param string $txSeq 交易流水号 * @param mixed $responseData 响应数据 * @param int $costTime 耗时(毫秒) * @return bool */ public static function recordSuccess($txSeq, $responseData, $costTime = 0) { return self::updateStatus($txSeq, self::STATUS_SUCCESS, [ 'response_data' => is_array($responseData) ? json_encode($responseData, JSON_UNESCAPED_UNICODE) : $responseData, 'cost_time' => $costTime, ]); } /** * 记录同步失败 * * @param string $txSeq 交易流水号 * @param string $errorMsg 错误信息 * @param int $costTime 耗时(毫秒) * @return bool */ public static function recordFailure($txSeq, $errorMsg, $costTime = 0) { return self::updateStatus($txSeq, self::STATUS_FAILED, [ 'error_msg' => $errorMsg, 'cost_time' => $costTime, ]); } /** * 增加重试次数 * * @param string $txSeq 交易流水号 * @return bool */ public static function incrementRetry($txSeq) { return self::where('tx_seq', $txSeq)->setInc('retry_times') !== false; } /** * 获取失败的同步日志 * * @param int $limit 限制数量 * @param int $maxRetryTimes 最大重试次数 * @return array */ public static function getFailedList($limit = 100, $maxRetryTimes = 3) { return self::where('sync_status', self::STATUS_FAILED) ->where('retry_times', '<', $maxRetryTimes) ->where('sync_time', '>', time() - 3600 * 24) // 24小时内 ->order('sync_time', 'asc') ->limit($limit) ->select(); } /** * 获取订单最后一次同步记录 * * @param int $orderId 订单ID * @param string $txCode 交易代码 * @return CcbSyncLog|null */ public static function getLastSync($orderId, $txCode) { return self::where('order_id', $orderId) ->where('tx_code', $txCode) ->order('sync_time', 'desc') ->find(); } /** * 检查订单是否同步成功 * * @param int $orderId 订单ID * @param string $txCode 交易代码 * @return bool */ public static function isSyncSuccess($orderId, $txCode) { $lastSync = self::getLastSync($orderId, $txCode); return $lastSync && $lastSync['sync_status'] === self::STATUS_SUCCESS; } /** * 关联订单模型(如果需要) * * @return \think\model\relation\BelongsTo */ public function order() { return $this->belongsTo('app\admin\model\shopro\order\Order', 'order_id', 'id'); } }