feat: HSAP platform v2 — modular navigation, quality review, audit log, world model simulation
Major changes: - New frontend (platform/web/): Vite + React 18 + TypeScript + Tailwind - 4-module navigation: 数据送标 / 模型管理 / 车队管理 / 系统管理 - Data catalog with charts (DMS/ADAS/Lane 3-tab view) - Quality review workflow (标注质检): Good/Fine/Bad scoring with auto-advance - Audit enhancements: batch operations, rejection categories, Feishu notifications - Operation audit log (操作日志) - World model simulation studio (仿真工坊) - Dataset version management with snapshots and diff - ADAS 7-class dataset integration (138K images organized + compressed) - User management with Feishu integration and pagination - CRUD/search/filter on all pages, card layout redesign - PIL-optimized image overlay rendering - Auto-snapshot on build, in_review workflow stage - Removed embedded algorithm code (now in workspace)
This commit is contained in:
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
from typing import Annotated, Any
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from fastapi.responses import RedirectResponse
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -12,8 +12,8 @@ from sqlalchemy.orm import Session
|
||||
from as_platform.auth.deps import get_current_user, require_permission
|
||||
from as_platform.auth.feishu import build_authorize_url, exchange_code, is_feishu_configured, verify_state
|
||||
from as_platform.auth.jwt import create_access_token
|
||||
from as_platform.auth.users import get_or_create_dev_user, list_users, set_user_roles, upsert_feishu_user
|
||||
from as_platform.config import DEV_AUTH_ENABLED, FRONTEND_URL
|
||||
from as_platform.auth.users import get_or_create_dev_user, list_users, list_users_paginated, set_user_roles, upsert_feishu_user
|
||||
from as_platform.config import DEV_AUTH_ENABLED, FORCE_DEV_AUTH, FRONTEND_URL
|
||||
from as_platform.db.engine import get_db
|
||||
from as_platform.db.init_db import user_to_dict
|
||||
from as_platform.db.models import User
|
||||
@@ -33,7 +33,7 @@ class SetRolesBody(BaseModel):
|
||||
def auth_config() -> dict[str, Any]:
|
||||
return {
|
||||
"feishu_enabled": is_feishu_configured(),
|
||||
"dev_auth_enabled": DEV_AUTH_ENABLED and not is_feishu_configured(),
|
||||
"dev_auth_enabled": DEV_AUTH_ENABLED and (FORCE_DEV_AUTH or not is_feishu_configured()),
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,10 @@ def feishu_callback(code: str, state: str, db: Annotated[Session, Depends(get_db
|
||||
user = upsert_feishu_user(db, info)
|
||||
db.commit()
|
||||
token = create_access_token(user.id)
|
||||
# 审计日志
|
||||
from as_platform.audit.log_utils import log_op
|
||||
log_op(user_id=user.id, user_name=user.name, category="auth", action="login",
|
||||
target_type="user", target_id=str(user.id), summary=f"飞书登录: {user.name}")
|
||||
# 避免 BrowserRouter 直达路径 404,统一回根路径并附带 token
|
||||
qs = urlencode({"token": token})
|
||||
return RedirectResponse(f"{FRONTEND_URL}/?{qs}")
|
||||
@@ -63,11 +67,15 @@ def feishu_callback(code: str, state: str, db: Annotated[Session, Depends(get_db
|
||||
|
||||
@router.post("/dev/login")
|
||||
def dev_login(body: DevLoginBody, db: Annotated[Session, Depends(get_db)]):
|
||||
if not DEV_AUTH_ENABLED or is_feishu_configured():
|
||||
if not DEV_AUTH_ENABLED or (not FORCE_DEV_AUTH and is_feishu_configured()):
|
||||
raise HTTPException(403, "开发登录未启用")
|
||||
user = get_or_create_dev_user(db, body.name)
|
||||
db.commit()
|
||||
token = create_access_token(user.id)
|
||||
# 审计日志
|
||||
from as_platform.audit.log_utils import log_op
|
||||
log_op(user_id=user.id, user_name=user.name, category="auth", action="login",
|
||||
target_type="user", target_id=str(user.id), summary=f"开发登录: {user.name}")
|
||||
return {"access_token": token, "user": user_to_dict(user)}
|
||||
|
||||
|
||||
@@ -80,8 +88,13 @@ def auth_me(user: Annotated[User, Depends(get_current_user)]):
|
||||
def auth_list_users(
|
||||
_user: Annotated[User, Depends(require_permission("admin:users"))],
|
||||
db: Annotated[Session, Depends(get_db)],
|
||||
search: str = Query(""),
|
||||
role: str = Query(""),
|
||||
offset: int = Query(0, ge=0),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
):
|
||||
return {"items": [user_to_dict(u) for u in list_users(db)]}
|
||||
users, total = list_users_paginated(db, search=search, role_code=role, offset=offset, limit=limit)
|
||||
return {"items": [user_to_dict(u) for u in users], "total": total}
|
||||
|
||||
|
||||
@router.put("/users/{user_id}/roles")
|
||||
@@ -95,4 +108,8 @@ def auth_set_roles(
|
||||
if not user:
|
||||
raise HTTPException(404, "用户不存在")
|
||||
db.commit()
|
||||
from as_platform.audit.log_utils import log_op
|
||||
log_op(user_id=_user.id, user_name=_user.name, category="system", action="set_roles",
|
||||
target_type="user", target_id=str(user_id), summary=f"修改角色: {user.name} → {body.role_codes}",
|
||||
detail={"user_id": user_id, "roles": body.role_codes})
|
||||
return user_to_dict(user)
|
||||
|
||||
Reference in New Issue
Block a user