From df6f9f4cfaa639f4065c7c42647284ae0e417623 Mon Sep 17 00:00:00 2001 From: liuwei Date: Thu, 23 Apr 2026 13:39:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A7=84=E5=88=99=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=86=99=E5=85=A5Redis=E6=97=B6datetime=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 在规则服务中新增JSON安全转换逻辑,递归处理dict/list结构。 2. 将datetime/date统一转换为字符串后再写入Redis,避免Object of type datetime is not JSON serializable。 3. 保持缓存结构兼容,不影响现有规则匹配流程。 --- utils/fun_command_rule_service.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/utils/fun_command_rule_service.py b/utils/fun_command_rule_service.py index 12684d1..e1abd17 100644 --- a/utils/fun_command_rule_service.py +++ b/utils/fun_command_rule_service.py @@ -11,6 +11,7 @@ import json import re import threading import time +from datetime import date, datetime from typing import Any, Dict, List, Optional, Tuple from loguru import logger @@ -47,13 +48,32 @@ class FunCommandRuleService: """从 MySQL 回源全量启用规则。""" return self.db.list_rules(enabled=True) + def _make_json_safe(self, value: Any) -> Any: + """将任意对象转换为可 JSON 序列化结构。 + + 重点处理: + 1. datetime/date:统一转成字符串,避免 json.dumps 抛异常。 + 2. dict/list:递归处理,确保嵌套结构中的时间字段也可序列化。 + """ + if isinstance(value, datetime): + return value.strftime("%Y-%m-%d %H:%M:%S") + if isinstance(value, date): + return value.strftime("%Y-%m-%d") + if isinstance(value, dict): + return {str(k): self._make_json_safe(v) for k, v in value.items()} + if isinstance(value, list): + return [self._make_json_safe(item) for item in value] + return value + def _write_redis_rules(self, rules: List[Dict[str, Any]]) -> None: """写入 Redis 持久缓存。 注意:这里不设置过期时间,Redis 作为跨进程共享缓存常驻。 """ try: - self.redis.set(self.REDIS_RULES_KEY, json.dumps(rules or [], ensure_ascii=False)) + # 规则行里可能带 created_at/updated_at(datetime),这里先做 JSON 安全转换。 + safe_rules = self._make_json_safe(rules or []) + self.redis.set(self.REDIS_RULES_KEY, json.dumps(safe_rules, ensure_ascii=False)) except Exception as e: logger.warning(f"写入 Redis 规则缓存失败: {e}")