root c62156af53 feat(backend): 数字员工平台 B1+B2 批次实现
B1: 项目脚手架 + 数据模型 + 租户管理
- Task 1.1: FastAPI 项目脚手架、SQLite + async SQLAlchemy
- Task 1.2: 7 个数据模型 (Tenant, TenantConfig, DigitalEmployee, Conversation, Message, KnowledgeBase, Document)
- Task 1.3: 租户 CRUD API + LLM 配置(含 API Key AES 加密)

B2: 数字员工配置 + LLM Provider 抽象层
- Task 2.1: 数字员工 CRUD API(关联知识库)
- Task 2.2: BaseLLMProvider 抽象接口 + OpenAI/Qwen Provider
- Task 2.3: Provider 动态实例化 + test-provider 端点

验证: 26 个测试全部通过

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 11:29:48 +08:00

77 lines
2.5 KiB
Python

from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.deps import get_db
from app.schemas.employee import (
EmployeeCreate,
EmployeeResponse,
EmployeeUpdate,
)
from app.services import employee_service
router = APIRouter(prefix="/employees", tags=["employees"])
@router.post("", response_model=EmployeeResponse, status_code=status.HTTP_201_CREATED)
async def create_employee(
data: EmployeeCreate, session: AsyncSession = Depends(get_db)
) -> EmployeeResponse:
employee = await employee_service.create_employee(
session,
tenant_id=data.tenant_id,
name=data.name,
role=data.role,
system_prompt=data.system_prompt,
greeting=data.greeting,
avatar_url=data.avatar_url,
temperature=data.temperature,
max_context_messages=data.max_context_messages,
knowledge_base_ids=data.knowledge_base_ids,
)
return EmployeeResponse.from_model(employee)
@router.get("", response_model=list[EmployeeResponse])
async def list_employees(
tenant_id: str = Query(...), session: AsyncSession = Depends(get_db)
) -> list[EmployeeResponse]:
employees = await employee_service.list_employees(session, tenant_id)
return [EmployeeResponse.from_model(e) for e in employees]
@router.get("/{employee_id}", response_model=EmployeeResponse)
async def get_employee(
employee_id: str, session: AsyncSession = Depends(get_db)
) -> EmployeeResponse:
employee = await employee_service.get_employee(session, employee_id)
return EmployeeResponse.from_model(employee)
@router.patch("/{employee_id}", response_model=EmployeeResponse)
async def update_employee(
employee_id: str,
data: EmployeeUpdate,
session: AsyncSession = Depends(get_db),
) -> EmployeeResponse:
employee = await employee_service.update_employee(
session,
employee_id,
name=data.name,
role=data.role,
system_prompt=data.system_prompt,
greeting=data.greeting,
avatar_url=data.avatar_url,
temperature=data.temperature,
max_context_messages=data.max_context_messages,
knowledge_base_ids=data.knowledge_base_ids,
status=data.status,
)
return EmployeeResponse.from_model(employee)
@router.delete("/{employee_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_employee(
employee_id: str, session: AsyncSession = Depends(get_db)
) -> None:
await employee_service.delete_employee(session, employee_id)