feat: 增强日历功能并集成 AgentScope 代理服务

This commit is contained in:
qzl
2026-03-11 15:28:29 +08:00
parent e55e445906
commit e20e7d2a02
85 changed files with 5175 additions and 885 deletions
+3 -5
View File
@@ -9,7 +9,6 @@ from fastapi import APIRouter, Depends, Query
from v1.schedule_items.dependencies import get_schedule_item_service
from v1.schedule_items.schemas import (
ScheduleItemCreateRequest,
ScheduleItemListItem,
ScheduleItemListRequest,
ScheduleItemResponse,
ScheduleItemShareRequest,
@@ -30,15 +29,14 @@ async def create_schedule_item(
return await service.create(request)
@router.get("", response_model=list[ScheduleItemListItem])
@router.get("", response_model=list[ScheduleItemResponse])
async def list_schedule_items(
service: Annotated[ScheduleItemService, Depends(get_schedule_item_service)],
start_at: datetime = Query(..., description="Start date/time for range query"),
end_at: datetime = Query(..., description="End date/time for range query"),
) -> list[ScheduleItemListItem]:
) -> list[ScheduleItemResponse]:
request = ScheduleItemListRequest(start_at=start_at, end_at=end_at)
items = await service.list_by_date_range(request)
return [ScheduleItemListItem.model_validate(item) for item in items]
return await service.list_by_date_range(request)
@router.get("/{item_id}", response_model=ScheduleItemResponse)
+7 -2
View File
@@ -2,6 +2,7 @@ from __future__ import annotations
from datetime import datetime
from enum import Enum
from typing import Literal
from typing import ClassVar
from uuid import UUID
@@ -14,6 +15,8 @@ class AttachmentType(str, Enum):
class ScheduleItemMetadataAttachment(BaseModel):
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
name: str
type: AttachmentType
visible_to: list[UUID] = Field(default_factory=list)
@@ -23,11 +26,13 @@ class ScheduleItemMetadataAttachment(BaseModel):
class ScheduleItemMetadata(BaseModel):
color: str | None = None
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
color: str | None = Field(default=None, pattern=r"^#[0-9A-Fa-f]{6}$")
location: str | None = None
notes: str | None = None
attachments: list[ScheduleItemMetadataAttachment] = Field(default_factory=list)
version: int = 1
version: Literal[1] = 1
class ScheduleItemStatus(str, Enum):
+18 -4
View File
@@ -87,7 +87,7 @@ class ScheduleItemService(BaseService):
"start_at": request.start_at,
"end_at": request.end_at,
"timezone": request.timezone,
"metadata": request.metadata.model_dump() if request.metadata else {},
"extra_metadata": request.metadata.model_dump() if request.metadata else {},
"source_type": source_type,
"status": ScheduleItemStatus.ACTIVE,
"created_by": user_id,
@@ -136,7 +136,13 @@ class ScheduleItemService(BaseService):
# Handle metadata separately (model_dump returns dict)
if "metadata" in update_data and update_data["metadata"] is not None:
update_data["metadata"] = update_data["metadata"].model_dump()
metadata_value = update_data["metadata"]
update_data["extra_metadata"] = (
metadata_value.model_dump()
if hasattr(metadata_value, "model_dump")
else metadata_value
)
del update_data["metadata"]
# Validate time range
next_start = update_data.get("start_at", existing.start_at)
@@ -275,6 +281,14 @@ class ScheduleItemService(BaseService):
return ScheduleItemShareResponse(message="Calendar invitation sent")
def _to_response(self, item: ScheduleItem) -> ScheduleItemResponse:
status_value = (
item.status.value if hasattr(item.status, "value") else item.status
)
source_type_value = (
item.source_type.value
if hasattr(item.source_type, "value")
else item.source_type
)
return ScheduleItemResponse(
id=item.id,
title=item.title,
@@ -285,8 +299,8 @@ class ScheduleItemService(BaseService):
metadata=ScheduleItemMetadata.model_validate(item.extra_metadata)
if item.extra_metadata
else None,
status=ScheduleItemStatus(item.status.value),
source_type=ScheduleItemSourceType(item.source_type.value),
status=ScheduleItemStatus(str(status_value)),
source_type=ScheduleItemSourceType(str(source_type_value)),
created_at=item.created_at,
updated_at=item.updated_at,
)