包含前后端完整代码: - 前端:Vue3+Vite+ElementPlus - 后端:FastAPI+SQLAlchemy - 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动 - 当前版本:v1.0.0
101 lines
2.7 KiB
Python
101 lines
2.7 KiB
Python
"""Redis 缓存工具类 — 管理会计OS"""
|
|
import json
|
|
import hashlib
|
|
import logging
|
|
from typing import Any, Optional
|
|
|
|
logger = logging.getLogger("cma.cache")
|
|
|
|
try:
|
|
import redis as redis_lib
|
|
_client = redis_lib.Redis(
|
|
host="127.0.0.1",
|
|
port=6379,
|
|
db=1,
|
|
decode_responses=True,
|
|
socket_connect_timeout=2,
|
|
socket_timeout=3,
|
|
)
|
|
_client.ping()
|
|
_available = True
|
|
logger.info("Redis 缓存已连接 (db=1)")
|
|
except Exception as e:
|
|
_client = None
|
|
_available = False
|
|
logger.warning(f"Redis 不可用,回退到无缓存模式: {e}")
|
|
|
|
|
|
def _make_key(module: str, key: str) -> str:
|
|
"""生成统一格式的缓存key: cma:cache:{module}:{hash}"""
|
|
h = hashlib.md5(key.encode()).hexdigest()[:16]
|
|
return f"cma:cache:{module}:{h}"
|
|
|
|
|
|
def get(module: str, key: str) -> Optional[Any]:
|
|
"""获取缓存"""
|
|
if not _available:
|
|
return None
|
|
try:
|
|
full_key = _make_key(module, key)
|
|
data = _client.get(full_key)
|
|
if data:
|
|
return json.loads(data)
|
|
return None
|
|
except Exception as e:
|
|
logger.warning(f"缓存读取失败 [{module}]: {e}")
|
|
return None
|
|
|
|
|
|
def set(module: str, key: str, value: Any, ttl_seconds: int = 300) -> bool:
|
|
"""写入缓存,默认5分钟"""
|
|
if not _available:
|
|
return False
|
|
try:
|
|
full_key = _make_key(module, key)
|
|
_client.setex(full_key, ttl_seconds, json.dumps(value, ensure_ascii=False))
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"缓存写入失败 [{module}]: {e}")
|
|
return False
|
|
|
|
|
|
def delete(module: str, key: str = None) -> bool:
|
|
"""删除缓存。不传key则清空该模块所有缓存"""
|
|
if not _available:
|
|
return False
|
|
try:
|
|
if key:
|
|
full_key = _make_key(module, key)
|
|
_client.delete(full_key)
|
|
else:
|
|
pattern = f"cma:cache:{module}:*"
|
|
cursor = 0
|
|
while True:
|
|
cursor, keys = _client.scan(cursor=cursor, match=pattern, count=100)
|
|
if keys:
|
|
_client.delete(*keys)
|
|
if cursor == 0:
|
|
break
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"缓存删除失败 [{module}]: {e}")
|
|
return False
|
|
|
|
|
|
def clear_all() -> bool:
|
|
"""清空所有CMA缓存"""
|
|
if not _available:
|
|
return False
|
|
try:
|
|
cursor = 0
|
|
while True:
|
|
cursor, keys = _client.scan(cursor=cursor, match="cma:cache:*", count=200)
|
|
if keys:
|
|
_client.delete(*keys)
|
|
if cursor == 0:
|
|
break
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"缓存清空失败: {e}")
|
|
return False
|