refactor: snapshot

This commit is contained in:
wangjiahao
2025-06-10 17:58:37 +08:00
parent 3217546b87
commit 344027c833
25 changed files with 566 additions and 112 deletions
+21 -20
View File
@@ -1,39 +1,40 @@
from xmlrpc.client import Boolean
from fastapi import APIRouter, File, UploadFile, HTTPException
from apps.dashboard.crud.dashboard_service import get_dashboard_list, preview_with_id, \
create_resource, create_canvas, validate_name
from apps.dashboard.crud.dashboard_service import list_resource, load_resource, \
create_resource, create_canvas, validate_name,delete_resource,update_resource
from apps.dashboard.models.dashboard_model import CreateDashboard, BaseDashboard, QueryDashboard
from common.core.deps import SessionDep, CurrentUser
router = APIRouter(tags=["dashboard"], prefix="/dashboard")
@router.post("/list")
async def datasource_list(session: SessionDep,dashboard: QueryDashboard):
return get_dashboard_list(session=session,dashboard=dashboard)
@router.post("/list_resource")
async def list_resource_api(session: SessionDep,dashboard: QueryDashboard):
return list_resource(session=session,dashboard=dashboard)
@router.get("/preview_dashboard/{id}")
async def preview_dashboard(session: SessionDep,id:str):
return preview_with_id(session=session,dashboard_id=id)
@router.post("/load_resource")
async def load_resource_api(session: SessionDep,dashboard: QueryDashboard):
return load_resource(session=session,dashboard=dashboard)
@router.post("/add", response_model=BaseDashboard)
async def add(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
@router.post("/create_resource", response_model=BaseDashboard)
async def create_resource_api(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return create_resource(session, user, dashboard)
@router.post("/update", response_model=BaseDashboard)
async def update(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return create_resource(session, user, dashboard)
@router.post("/add_canvas", response_model=BaseDashboard)
async def add_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
@router.post("/update_resource", response_model=BaseDashboard)
async def update_resource_api(session: SessionDep, user: CurrentUser, dashboard: QueryDashboard):
return update_resource(session=session, user=user, dashboard=dashboard)
@router.delete("/delete_resource/{resource_id}")
async def delete_resource_api(session: SessionDep,resource_id:str):
return delete_resource(session,resource_id)
@router.post("/create_canvas", response_model=BaseDashboard)
async def create_canvas_api(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return create_canvas(session, user, dashboard)
@router.post("/update_canvas", response_model=BaseDashboard)
async def update(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
async def update_canvas_api(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
return
@router.post("/check_name")
async def check_name(session: SessionDep, dashboard: QueryDashboard):
async def check_name_api(session: SessionDep, dashboard: QueryDashboard):
return validate_name(session,dashboard)
@@ -1,23 +1,42 @@
from sqlalchemy import select, and_, text
from apps.dashboard.models.dashboard_model import CoreDashboard, CreateDashboard, QueryDashboard
from apps.dashboard.models.dashboard_model import CoreDashboard, CreateDashboard, QueryDashboard,DashboardBaseResponse
from common.core.deps import SessionDep, CurrentUser
import uuid
import datetime
def get_dashboard_list(session: SessionDep,dashboard: QueryDashboard):
sql = text("SELECT id, name, type,node_type, pid, create_time FROM core_dashboard")
for row in session.exec(sql).mappings():
yield CoreDashboard(**row)
import time
from common.utils.tree_utils import build_tree_generic
def list_resource(session: SessionDep, dashboard: QueryDashboard):
sql = "SELECT id, name, type, node_type, pid, create_time FROM core_dashboard"
filters = []
params = {}
if dashboard.node_type is not None and dashboard.node_type != "":
filters.append("node_type = :node_type")
params["node_type"] = dashboard.node_type
if filters:
sql += " WHERE " + " AND ".join(filters)
result = session.execute(text(sql), params)
nodes = [DashboardBaseResponse(**row) for row in result.mappings()]
tree = build_tree_generic(nodes, root_pid="root")
return tree
def load_resource(session: SessionDep,dashboard: QueryDashboard):
return session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
def preview_with_id(session: SessionDep, dashboard_id: str):
return session.query(CoreDashboard).filter(CoreDashboard.id == id).first()
def get_create_base_info(user: CurrentUser, dashboard: CreateDashboard):
new_id = uuid.uuid4().hex
record = CoreDashboard(**dashboard.model_dump())
record.id = new_id
record.create_by = user.id
record.create_time = int(time.time())
return record
def create_resource(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
record = get_create_base_info(user, dashboard)
session.add(record)
@@ -26,13 +45,15 @@ def create_resource(session: SessionDep, user: CurrentUser, dashboard: CreateDas
session.commit()
return record
def update_resource(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
def update_resource(session: SessionDep, user: CurrentUser, dashboard: QueryDashboard):
record = session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
record.name = dashboard.name
record.update_by = user.id
record.update_time = datetime.datetime.now()
record.update_time = int(time.time())
session.add(record)
session.commit()
return record
def create_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
record = get_create_base_info(user, dashboard)
@@ -41,13 +62,16 @@ def create_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashb
record.canvas_style_data = dashboard.canvas_style_data
session.add(record)
session.flush()
session.refresh(record)
session.commit()
return record
def update_canvas(session: SessionDep, user: CurrentUser, dashboard: CreateDashboard):
record = session.query(CoreDashboard).filter(CoreDashboard.id == dashboard.id).first()
def validate_name( session: SessionDep, dashboard: QueryDashboard) -> bool:
def validate_name(session: SessionDep, dashboard: QueryDashboard) -> bool:
if not dashboard.workspace_id:
raise ValueError("workspace_id is required")
if not dashboard.pid:
@@ -63,7 +87,7 @@ def validate_name( session: SessionDep, dashboard: QueryDashboard) -> bool:
CoreDashboard.name == dashboard.name
)
)
elif dashboard.opt in ('updateLeaf', 'updateFolder'):
elif dashboard.opt in ('updateLeaf', 'updateFolder', 'rename'):
if not dashboard.id:
raise ValueError("id is required for update operation")
query = session.query(CoreDashboard).filter(
@@ -76,4 +100,11 @@ def validate_name( session: SessionDep, dashboard: QueryDashboard) -> bool:
)
else:
raise ValueError(f"Invalid opt value: {dashboard.opt}")
return not session.query(query.exists()).scalar()
return not session.query(query.exists()).scalar()
def delete_resource(session: SessionDep, resource_id: str):
sql = text("DELETE FROM core_dashboard WHERE id = :resource_id")
result = session.execute(sql, {"resource_id": resource_id})
session.commit()
return result.rowcount > 0
@@ -1,6 +1,6 @@
from sqlmodel import SQLModel, Field
from sqlalchemy import String, Column, Text, SmallInteger, BigInteger, Integer,DateTime
from typing import Optional
from typing import Optional, List
from pydantic import BaseModel
class CoreDashboard(SQLModel, table=True):
@@ -127,9 +127,11 @@ class DashboardBaseResponse(BaseModel):
name: Optional[str] = None
pid: Optional[str] = None
node_type: Optional[str] = None
leaf: Optional[bool] = False
type: Optional[str] = None
create_time: Optional[int] = None
update_time: Optional[int] = None
children: List['DashboardBaseResponse'] = []
class BaseDashboard(BaseModel):
id: str = ''
@@ -139,6 +141,7 @@ class BaseDashboard(BaseModel):
org_id: str = ''
type: str = ''
node_type: str = ''
level: int = 0
create_by: int = 0
class QueryDashboard(BaseDashboard):
+22
View File
@@ -0,0 +1,22 @@
from typing import List, Optional, Dict, TypeVar, Protocol, Any
from pydantic import BaseModel
class ITreeNode(Protocol):
id: Optional[str]
pid: Optional[str]
children: List['ITreeNode']
T = TypeVar('T', bound=ITreeNode)
def build_tree_generic(nodes: List[T], root_pid: Any = None) -> List[T]:
node_dict: Dict[str, T] = {node.id: node for node in nodes if node.id is not None}
tree: List[T] = []
for node in nodes:
if node.pid == root_pid:
tree.append(node)
elif node.pid in node_dict:
node_dict[node.pid].children.append(node)
return tree