init: 管理会计OS初始代码
包含前后端完整代码: - 前端:Vue3+Vite+ElementPlus - 后端:FastAPI+SQLAlchemy - 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动 - 当前版本:v1.0.0
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user