init: 管理会计OS初始代码

包含前后端完整代码:
- 前端:Vue3+Vite+ElementPlus
- 后端:FastAPI+SQLAlchemy
- 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动
- 当前版本:v1.0.0
This commit is contained in:
Hermes CI Fix
2026-05-28 17:32:22 +08:00
commit 3dddd36866
142 changed files with 18533 additions and 0 deletions
+100
View File
@@ -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