mirror of
https://gitcode.com/JianFeeeee/TrulyMEM-TrueHumanMEM.git
synced 2026-09-22 09:58:14 +00:00
多用户系统 + Admin 角色权限 + Web/TUI 同步 + 构建集成
本轮实现功能: 1. 多用户隔离:每个用户独立 config.json + graph.db 2. TUI 登录页 + 旧版自动迁移(core/migrate.py) 3. Admin/User 角色体系(core/embedded_db.py) 4. Web 后台管理 API(userinfo + admin CRUD) 5. Web 设置页用户管理区(仅 admin 可见) 6. TUI 侧栏配置区权限同步(非 admin 隐藏 Web 服务设置) 7. Web 服务打包为独立二进制(trulymem-web) 8. 双入口 PyInstaller 构建脚本(TUI + Web) 9. 活动记录器(core/activity_recorder.py) 10. 静态页面模板(登录/设置/首次引导)
This commit is contained in:
41
core/activity_recorder.py
Normal file
41
core/activity_recorder.py
Normal file
@ -0,0 +1,41 @@
|
||||
import sqlite3
|
||||
import time
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
|
||||
class ActivityRecorder:
|
||||
"""记录 AI 对图数据库的操作到内存 SQLite"""
|
||||
|
||||
def __init__(self):
|
||||
self.conn = sqlite3.connect(":memory:", check_same_thread=False)
|
||||
self.conn.execute("CREATE TABLE activities (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp REAL, action TEXT, tool_name TEXT, entity TEXT, detail TEXT)")
|
||||
self.conn.commit()
|
||||
|
||||
def record(self, action: str, tool_name: str, entity: str, detail: str = "") -> None:
|
||||
self.conn.execute("INSERT INTO activities (timestamp, action, tool_name, entity, detail) VALUES (?, ?, ?, ?, ?)",
|
||||
(time.time(), action, tool_name, entity, detail))
|
||||
self.conn.commit()
|
||||
|
||||
def get_all(self) -> List[Dict]:
|
||||
cursor = self.conn.execute("SELECT id, timestamp, action, tool_name, entity, detail FROM activities ORDER BY id")
|
||||
rows = cursor.fetchall()
|
||||
return [{"id": r[0], "timestamp": r[1], "action": r[2], "tool_name": r[3], "entity": r[4], "detail": r[5]} for r in rows]
|
||||
|
||||
def clear(self) -> None:
|
||||
self.conn.execute("DELETE FROM activities")
|
||||
self.conn.commit()
|
||||
|
||||
def get_summary(self) -> Dict[str, int]:
|
||||
cursor = self.conn.execute("SELECT action, COUNT(*) FROM activities GROUP BY action")
|
||||
rows = cursor.fetchall()
|
||||
return {r[0]: r[1] for r in rows}
|
||||
|
||||
|
||||
_recorder: Optional[ActivityRecorder] = None
|
||||
|
||||
|
||||
def get_recorder() -> ActivityRecorder:
|
||||
global _recorder
|
||||
if _recorder is None:
|
||||
_recorder = ActivityRecorder()
|
||||
return _recorder
|
||||
Reference in New Issue
Block a user