feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
"""
|
|
|
|
|
|
Admin 用户管理 API(仅平台管理员可访问)
|
|
|
|
|
|
"""
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
import logging
|
|
|
|
|
|
import uuid
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
from typing import List, Optional
|
|
|
|
|
|
|
|
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
|
|
|
|
from pydantic import BaseModel, Field, EmailStr
|
|
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
from sqlalchemy import func
|
|
|
|
|
|
|
|
|
|
|
|
from app.api.auth import get_current_user
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
from app.api.deps import require_admin
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
from app.core.database import get_db
|
|
|
|
|
|
from app.core.security import get_password_hash
|
|
|
|
|
|
from app.models.user import User
|
|
|
|
|
|
from app.models.workspace import WorkspaceMembership
|
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
router = APIRouter(prefix="/api/v1/admin/users", tags=["admin-users"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ── Request / Response schemas ──
|
|
|
|
|
|
|
|
|
|
|
|
class UserCreateRequest(BaseModel):
|
|
|
|
|
|
username: str = Field(..., min_length=2, max_length=50)
|
|
|
|
|
|
email: EmailStr
|
|
|
|
|
|
password: str = Field(..., min_length=6, max_length=128)
|
|
|
|
|
|
role: str = Field(default="user")
|
|
|
|
|
|
phone: Optional[str] = None
|
|
|
|
|
|
status: str = Field(default="active")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserUpdateRequest(BaseModel):
|
|
|
|
|
|
username: Optional[str] = Field(None, min_length=2, max_length=50)
|
|
|
|
|
|
email: Optional[EmailStr] = None
|
|
|
|
|
|
role: Optional[str] = None
|
|
|
|
|
|
phone: Optional[str] = None
|
|
|
|
|
|
status: Optional[str] = None
|
|
|
|
|
|
subscription_tier: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ResetPasswordRequest(BaseModel):
|
|
|
|
|
|
new_password: str = Field(..., min_length=6, max_length=128)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserItem(BaseModel):
|
|
|
|
|
|
id: str
|
|
|
|
|
|
username: str
|
|
|
|
|
|
email: str
|
|
|
|
|
|
role: str
|
|
|
|
|
|
phone: Optional[str] = None
|
|
|
|
|
|
phone_verified: bool = False
|
|
|
|
|
|
status: str
|
|
|
|
|
|
is_email_verified: bool = False
|
|
|
|
|
|
subscription_tier: str = "free"
|
|
|
|
|
|
daily_usage_count: int = 0
|
|
|
|
|
|
workspace_count: int = 0
|
|
|
|
|
|
created_at: Optional[datetime] = None
|
|
|
|
|
|
updated_at: Optional[datetime] = None
|
|
|
|
|
|
|
|
|
|
|
|
class Config:
|
|
|
|
|
|
from_attributes = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserListResponse(BaseModel):
|
|
|
|
|
|
items: List[UserItem]
|
|
|
|
|
|
total: int
|
|
|
|
|
|
page: int
|
|
|
|
|
|
page_size: int
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ── Endpoints ──
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("", response_model=UserListResponse)
|
|
|
|
|
|
def list_users(
|
|
|
|
|
|
page: int = Query(1, ge=1),
|
|
|
|
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
|
|
|
|
search: Optional[str] = Query(None, description="搜索用户名或邮箱"),
|
|
|
|
|
|
status: Optional[str] = Query(None, description="过滤状态: active/disabled/deleted"),
|
|
|
|
|
|
role: Optional[str] = Query(None, description="过滤角色"),
|
|
|
|
|
|
db: Session = Depends(get_db),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_admin: User = Depends(require_admin()),
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
):
|
|
|
|
|
|
"""获取用户列表(分页、搜索、过滤)"""
|
|
|
|
|
|
q = db.query(User)
|
|
|
|
|
|
|
|
|
|
|
|
if search:
|
|
|
|
|
|
like = f"%{search}%"
|
|
|
|
|
|
q = q.filter((User.username.ilike(like)) | (User.email.ilike(like)))
|
|
|
|
|
|
if status:
|
|
|
|
|
|
q = q.filter(User.status == status)
|
|
|
|
|
|
if role:
|
|
|
|
|
|
q = q.filter(User.role == role)
|
|
|
|
|
|
|
|
|
|
|
|
total = q.count()
|
|
|
|
|
|
items = q.order_by(User.created_at.desc()).offset((page - 1) * page_size).limit(page_size).all()
|
|
|
|
|
|
|
|
|
|
|
|
# 获取每个用户的 workspace 数量
|
|
|
|
|
|
user_ids = [u.id for u in items]
|
|
|
|
|
|
ws_counts = {}
|
|
|
|
|
|
if user_ids:
|
|
|
|
|
|
rows = (
|
|
|
|
|
|
db.query(
|
|
|
|
|
|
WorkspaceMembership.user_id,
|
|
|
|
|
|
func.count(WorkspaceMembership.workspace_id).label("cnt"),
|
|
|
|
|
|
)
|
|
|
|
|
|
.filter(WorkspaceMembership.user_id.in_(user_ids))
|
|
|
|
|
|
.group_by(WorkspaceMembership.user_id)
|
|
|
|
|
|
.all()
|
|
|
|
|
|
)
|
|
|
|
|
|
ws_counts = {r.user_id: r.cnt for r in rows}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
"items": [
|
|
|
|
|
|
{**{c.name: getattr(u, c.name) for c in User.__table__.columns},
|
|
|
|
|
|
"workspace_count": ws_counts.get(u.id, 0)}
|
|
|
|
|
|
for u in items
|
|
|
|
|
|
],
|
|
|
|
|
|
"total": total,
|
|
|
|
|
|
"page": page,
|
|
|
|
|
|
"page_size": page_size,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("", response_model=UserItem)
|
|
|
|
|
|
def create_user(
|
|
|
|
|
|
data: UserCreateRequest,
|
|
|
|
|
|
db: Session = Depends(get_db),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_admin: User = Depends(require_admin()),
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
):
|
|
|
|
|
|
"""管理员创建新用户"""
|
|
|
|
|
|
if db.query(User).filter(User.username == data.username).first():
|
|
|
|
|
|
raise HTTPException(status_code=409, detail="用户名已存在")
|
|
|
|
|
|
if db.query(User).filter(User.email == data.email).first():
|
|
|
|
|
|
raise HTTPException(status_code=409, detail="邮箱已存在")
|
|
|
|
|
|
|
|
|
|
|
|
user = User(
|
|
|
|
|
|
id=str(uuid.uuid4()),
|
|
|
|
|
|
username=data.username,
|
|
|
|
|
|
email=data.email,
|
|
|
|
|
|
password_hash=get_password_hash(data.password),
|
|
|
|
|
|
role=data.role,
|
|
|
|
|
|
phone=data.phone,
|
|
|
|
|
|
status=data.status,
|
|
|
|
|
|
)
|
|
|
|
|
|
db.add(user)
|
|
|
|
|
|
db.commit()
|
|
|
|
|
|
db.refresh(user)
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("管理员创建了用户: %s (%s)", user.username, user.id)
|
|
|
|
|
|
return {**{c.name: getattr(user, c.name) for c in User.__table__.columns}, "workspace_count": 0}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/{user_id}", response_model=UserItem)
|
|
|
|
|
|
def get_user(
|
|
|
|
|
|
user_id: str,
|
|
|
|
|
|
db: Session = Depends(get_db),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_admin: User = Depends(require_admin()),
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
):
|
|
|
|
|
|
"""获取用户详情"""
|
|
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
|
|
|
|
if not user:
|
|
|
|
|
|
raise HTTPException(status_code=404, detail="用户不存在")
|
|
|
|
|
|
|
|
|
|
|
|
ws_count = (
|
|
|
|
|
|
db.query(func.count(WorkspaceMembership.workspace_id))
|
|
|
|
|
|
.filter(WorkspaceMembership.user_id == user_id)
|
|
|
|
|
|
.scalar()
|
|
|
|
|
|
) or 0
|
|
|
|
|
|
|
|
|
|
|
|
return {**{c.name: getattr(user, c.name) for c in User.__table__.columns}, "workspace_count": ws_count}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.put("/{user_id}", response_model=UserItem)
|
|
|
|
|
|
def update_user(
|
|
|
|
|
|
user_id: str,
|
|
|
|
|
|
data: UserUpdateRequest,
|
|
|
|
|
|
db: Session = Depends(get_db),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_admin: User = Depends(require_admin()),
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
):
|
|
|
|
|
|
"""编辑用户"""
|
|
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
|
|
|
|
if not user:
|
|
|
|
|
|
raise HTTPException(status_code=404, detail="用户不存在")
|
|
|
|
|
|
|
|
|
|
|
|
if data.username is not None and data.username != user.username:
|
|
|
|
|
|
if db.query(User).filter(User.username == data.username, User.id != user_id).first():
|
|
|
|
|
|
raise HTTPException(status_code=409, detail="用户名已存在")
|
|
|
|
|
|
user.username = data.username
|
|
|
|
|
|
if data.email is not None and data.email != user.email:
|
|
|
|
|
|
if db.query(User).filter(User.email == data.email, User.id != user_id).first():
|
|
|
|
|
|
raise HTTPException(status_code=409, detail="邮箱已存在")
|
|
|
|
|
|
user.email = data.email
|
|
|
|
|
|
if data.role is not None:
|
|
|
|
|
|
user.role = data.role
|
|
|
|
|
|
if data.phone is not None:
|
|
|
|
|
|
user.phone = data.phone
|
|
|
|
|
|
if data.status is not None:
|
|
|
|
|
|
if data.status not in ("active", "disabled", "deleted"):
|
|
|
|
|
|
raise HTTPException(status_code=400, detail="无效的状态值")
|
|
|
|
|
|
user.status = data.status
|
|
|
|
|
|
if data.subscription_tier is not None:
|
|
|
|
|
|
user.subscription_tier = data.subscription_tier
|
|
|
|
|
|
|
|
|
|
|
|
db.commit()
|
|
|
|
|
|
db.refresh(user)
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("管理员更新了用户: %s (%s)", user.username, user.id)
|
|
|
|
|
|
ws_count = (
|
|
|
|
|
|
db.query(func.count(WorkspaceMembership.workspace_id))
|
|
|
|
|
|
.filter(WorkspaceMembership.user_id == user_id)
|
|
|
|
|
|
.scalar()
|
|
|
|
|
|
) or 0
|
|
|
|
|
|
return {**{c.name: getattr(user, c.name) for c in User.__table__.columns}, "workspace_count": ws_count}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.delete("/{user_id}")
|
|
|
|
|
|
def delete_user(
|
|
|
|
|
|
user_id: str,
|
|
|
|
|
|
db: Session = Depends(get_db),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_admin: User = Depends(require_admin()),
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
):
|
|
|
|
|
|
"""软删除用户(标记为 deleted)"""
|
|
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
|
|
|
|
if not user:
|
|
|
|
|
|
raise HTTPException(status_code=404, detail="用户不存在")
|
|
|
|
|
|
if user.role == "admin":
|
|
|
|
|
|
raise HTTPException(status_code=400, detail="不能删除平台管理员")
|
|
|
|
|
|
|
|
|
|
|
|
user.status = "deleted"
|
|
|
|
|
|
db.commit()
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("管理员软删除了用户: %s (%s)", user.username, user.id)
|
|
|
|
|
|
return {"message": "用户已删除"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/{user_id}/reset-password")
|
|
|
|
|
|
def reset_password(
|
|
|
|
|
|
user_id: str,
|
|
|
|
|
|
data: ResetPasswordRequest,
|
|
|
|
|
|
db: Session = Depends(get_db),
|
feat: virtual company module, team projects, PWA dishes app, and startup scripts overhaul
- Add company module (3-tier org, CEO planning, parallel departments)
- Add company orchestrator, knowledge extractor, presets, scheduler
- Add company API endpoints, models, and frontend views
- Add 今天吃啥 PWA app (69 dishes, real images, offline support)
- Add team_projects output directory structure
- Add unified manage.ps1 for service lifecycle
- Add Windows startup guide v1.0
- Add TTS troubleshooting doc
- Update frontend (AgentChat UX overhaul, new views)
- Update backend (voice engine fix, multi-tenant, RBAC)
- Remove deprecated startup scripts and old docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-10 22:37:56 +08:00
|
|
|
|
_admin: User = Depends(require_admin()),
|
feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00
|
|
|
|
):
|
|
|
|
|
|
"""重置用户密码"""
|
|
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
|
|
|
|
if not user:
|
|
|
|
|
|
raise HTTPException(status_code=404, detail="用户不存在")
|
|
|
|
|
|
|
|
|
|
|
|
user.password_hash = get_password_hash(data.new_password)
|
|
|
|
|
|
db.commit()
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("管理员重置了用户 %s 的密码", user.username)
|
|
|
|
|
|
return {"message": "密码已重置"}
|