2026-03-26 06:55:12 +00:00
|
|
|
from pydantic import BaseModel, Field, EmailStr
|
|
|
|
|
from typing import List, Optional, Any, Dict, Union
|
2026-01-19 11:03:08 +00:00
|
|
|
import datetime
|
|
|
|
|
|
2026-03-26 06:55:12 +00:00
|
|
|
# 认证相关模型
|
2026-01-19 11:03:08 +00:00
|
|
|
class LoginRequest(BaseModel):
|
|
|
|
|
username: str
|
|
|
|
|
password: str
|
|
|
|
|
|
|
|
|
|
class RoleInfo(BaseModel):
|
|
|
|
|
role_id: int
|
|
|
|
|
role_name: str
|
|
|
|
|
|
|
|
|
|
class UserInfo(BaseModel):
|
|
|
|
|
user_id: int
|
|
|
|
|
username: str
|
|
|
|
|
caption: str
|
2026-03-26 06:55:12 +00:00
|
|
|
email: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
role_id: int
|
|
|
|
|
role_name: str
|
2026-03-26 06:55:12 +00:00
|
|
|
avatar_url: Optional[str] = None
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
|
|
|
|
|
class LoginResponse(BaseModel):
|
|
|
|
|
token: str
|
|
|
|
|
user: UserInfo
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class UserListResponse(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
users: List[UserInfo]
|
2026-01-19 11:03:08 +00:00
|
|
|
total: int
|
|
|
|
|
|
|
|
|
|
class CreateUserRequest(BaseModel):
|
|
|
|
|
username: str
|
|
|
|
|
password: Optional[str] = None
|
|
|
|
|
caption: str
|
2026-03-26 06:55:12 +00:00
|
|
|
email: Optional[str] = None
|
2026-03-31 07:17:47 +00:00
|
|
|
avatar_url: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
role_id: int = 2
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class UpdateUserRequest(BaseModel):
|
2026-03-27 09:05:33 +00:00
|
|
|
username: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
caption: Optional[str] = None
|
|
|
|
|
email: Optional[str] = None
|
|
|
|
|
role_id: Optional[int] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
avatar_url: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class UserLog(BaseModel):
|
|
|
|
|
log_id: int
|
|
|
|
|
user_id: int
|
2026-03-26 06:55:12 +00:00
|
|
|
username: str
|
|
|
|
|
action: str
|
|
|
|
|
details: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
ip_address: Optional[str] = None
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
|
2026-03-26 06:55:12 +00:00
|
|
|
# 会议相关模型
|
2026-01-19 11:03:08 +00:00
|
|
|
class AttendeeInfo(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
user_id: Optional[int] = None
|
|
|
|
|
username: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
caption: str
|
|
|
|
|
|
|
|
|
|
class Tag(BaseModel):
|
|
|
|
|
id: int
|
|
|
|
|
name: str
|
|
|
|
|
|
|
|
|
|
class TranscriptionTaskStatus(BaseModel):
|
|
|
|
|
task_id: str
|
2026-03-26 06:55:12 +00:00
|
|
|
status: str
|
|
|
|
|
progress: int
|
|
|
|
|
message: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class Meeting(BaseModel):
|
|
|
|
|
meeting_id: int
|
|
|
|
|
title: str
|
2026-03-26 06:55:12 +00:00
|
|
|
meeting_time: datetime.datetime
|
|
|
|
|
description: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
creator_id: int
|
|
|
|
|
creator_username: str
|
2026-03-26 06:55:12 +00:00
|
|
|
created_at: datetime.datetime
|
|
|
|
|
attendees: List[AttendeeInfo]
|
2026-03-27 07:43:08 +00:00
|
|
|
attendee_ids: Optional[List[int]] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
tags: List[Tag]
|
2026-01-19 11:03:08 +00:00
|
|
|
audio_file_path: Optional[str] = None
|
2026-01-22 07:23:28 +00:00
|
|
|
audio_duration: Optional[float] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
summary: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
transcription_status: Optional[TranscriptionTaskStatus] = None
|
2026-04-02 11:07:41 +00:00
|
|
|
llm_status: Optional[TranscriptionTaskStatus] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
prompt_id: Optional[int] = None
|
|
|
|
|
prompt_name: Optional[str] = None
|
|
|
|
|
overall_status: Optional[str] = None
|
|
|
|
|
overall_progress: Optional[int] = None
|
|
|
|
|
current_stage: Optional[str] = None
|
2026-03-27 08:01:52 +00:00
|
|
|
access_password: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class TranscriptSegment(BaseModel):
|
|
|
|
|
segment_id: int
|
2026-03-26 06:55:12 +00:00
|
|
|
speaker_id: int
|
2026-01-19 11:03:08 +00:00
|
|
|
speaker_tag: str
|
|
|
|
|
start_time_ms: int
|
|
|
|
|
end_time_ms: int
|
|
|
|
|
text_content: str
|
|
|
|
|
|
|
|
|
|
class CreateMeetingRequest(BaseModel):
|
|
|
|
|
title: str
|
2026-03-26 06:55:12 +00:00
|
|
|
meeting_time: datetime.datetime
|
2026-03-27 07:43:08 +00:00
|
|
|
attendee_ids: List[int]
|
2026-03-26 06:55:12 +00:00
|
|
|
description: Optional[str] = None
|
|
|
|
|
tags: Optional[str] = None # 逗号分隔
|
|
|
|
|
prompt_id: Optional[int] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class UpdateMeetingRequest(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
title: Optional[str] = None
|
|
|
|
|
meeting_time: Optional[datetime.datetime] = None
|
2026-03-27 07:43:08 +00:00
|
|
|
attendee_ids: Optional[List[int]] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
description: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
tags: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
summary: Optional[str] = None
|
|
|
|
|
prompt_id: Optional[int] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class SpeakerTagUpdateRequest(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
speaker_id: int
|
2026-01-19 11:03:08 +00:00
|
|
|
new_tag: str
|
|
|
|
|
|
|
|
|
|
class BatchSpeakerTagUpdateRequest(BaseModel):
|
|
|
|
|
updates: List[SpeakerTagUpdateRequest]
|
|
|
|
|
|
|
|
|
|
class TranscriptUpdateRequest(BaseModel):
|
|
|
|
|
segment_id: int
|
2026-04-02 11:07:41 +00:00
|
|
|
text_content: str
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class BatchTranscriptUpdateRequest(BaseModel):
|
|
|
|
|
updates: List[TranscriptUpdateRequest]
|
|
|
|
|
|
|
|
|
|
class PasswordChangeRequest(BaseModel):
|
|
|
|
|
old_password: str
|
|
|
|
|
new_password: str
|
|
|
|
|
|
2026-03-26 06:55:12 +00:00
|
|
|
# 提示词模版模型
|
|
|
|
|
class PromptBase(BaseModel):
|
|
|
|
|
name: str
|
|
|
|
|
task_type: str # MEETING_TASK, KNOWLEDGE_TASK
|
|
|
|
|
content: str
|
|
|
|
|
desc: Optional[str] = None
|
|
|
|
|
is_system: bool = False
|
|
|
|
|
is_default: bool = False
|
|
|
|
|
is_active: bool = True
|
|
|
|
|
|
|
|
|
|
class PromptCreate(PromptBase):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
class PromptUpdate(BaseModel):
|
|
|
|
|
name: Optional[str] = None
|
|
|
|
|
task_type: Optional[str] = None
|
|
|
|
|
content: Optional[str] = None
|
|
|
|
|
desc: Optional[str] = None
|
|
|
|
|
is_system: Optional[bool] = None
|
|
|
|
|
is_default: Optional[bool] = None
|
|
|
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
|
|
|
|
class PromptInfo(PromptBase):
|
|
|
|
|
id: int
|
|
|
|
|
creator_id: Optional[int] = None
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
|
|
|
|
|
# 知识库相关模型
|
2026-01-19 11:03:08 +00:00
|
|
|
class KnowledgeBase(BaseModel):
|
|
|
|
|
kb_id: int
|
|
|
|
|
title: str
|
2026-03-26 06:55:12 +00:00
|
|
|
content: str
|
2026-01-19 11:03:08 +00:00
|
|
|
creator_id: int
|
2026-03-26 06:55:12 +00:00
|
|
|
created_by_name: str
|
2026-01-19 11:03:08 +00:00
|
|
|
is_shared: bool
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
updated_at: datetime.datetime
|
2026-03-26 06:55:12 +00:00
|
|
|
source_meeting_count: int
|
|
|
|
|
source_meetings: Optional[List[Meeting]] = None
|
|
|
|
|
user_prompt: Optional[str] = None
|
|
|
|
|
tags: Optional[List[str]] = None
|
|
|
|
|
prompt_id: Optional[int] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class KnowledgeBaseTask(BaseModel):
|
|
|
|
|
task_id: str
|
|
|
|
|
status: str
|
|
|
|
|
progress: int
|
2026-03-26 06:55:12 +00:00
|
|
|
message: Optional[str] = None
|
|
|
|
|
result: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class CreateKnowledgeBaseRequest(BaseModel):
|
|
|
|
|
user_prompt: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
source_meeting_ids: str # 逗号分隔
|
|
|
|
|
is_shared: bool = False
|
|
|
|
|
prompt_id: Optional[int] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class UpdateKnowledgeBaseRequest(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
title: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
content: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
is_shared: Optional[bool] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class KnowledgeBaseListResponse(BaseModel):
|
|
|
|
|
kbs: List[KnowledgeBase]
|
|
|
|
|
total: int
|
|
|
|
|
|
|
|
|
|
# 客户端下载相关模型
|
|
|
|
|
class ClientDownload(BaseModel):
|
|
|
|
|
id: int
|
2026-03-26 06:55:12 +00:00
|
|
|
platform_code: str
|
|
|
|
|
platform_type: str # mobile, desktop, terminal
|
|
|
|
|
platform_name: str
|
2026-01-19 11:03:08 +00:00
|
|
|
version: str
|
|
|
|
|
version_code: int
|
|
|
|
|
download_url: str
|
|
|
|
|
file_size: Optional[int] = None
|
|
|
|
|
release_notes: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
min_system_version: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
is_active: bool
|
|
|
|
|
is_latest: bool
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
updated_at: datetime.datetime
|
|
|
|
|
|
|
|
|
|
class CreateClientDownloadRequest(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
platform_code: str
|
|
|
|
|
platform_type: Optional[str] = None
|
|
|
|
|
platform_name: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
version: str
|
|
|
|
|
version_code: int
|
|
|
|
|
download_url: str
|
|
|
|
|
file_size: Optional[int] = None
|
|
|
|
|
release_notes: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
min_system_version: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
is_active: bool = True
|
|
|
|
|
is_latest: bool = False
|
|
|
|
|
|
|
|
|
|
class UpdateClientDownloadRequest(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
platform_code: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
platform_type: Optional[str] = None
|
|
|
|
|
platform_name: Optional[str] = None
|
|
|
|
|
version: Optional[str] = None
|
|
|
|
|
version_code: Optional[int] = None
|
|
|
|
|
download_url: Optional[str] = None
|
|
|
|
|
file_size: Optional[int] = None
|
|
|
|
|
release_notes: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
min_system_version: Optional[str] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
is_active: Optional[bool] = None
|
|
|
|
|
is_latest: Optional[bool] = None
|
|
|
|
|
|
|
|
|
|
class ClientDownloadListResponse(BaseModel):
|
|
|
|
|
clients: List[ClientDownload]
|
|
|
|
|
total: int
|
|
|
|
|
|
2026-03-26 06:55:12 +00:00
|
|
|
# 声纹相关模型
|
2026-01-19 11:03:08 +00:00
|
|
|
class VoiceprintInfo(BaseModel):
|
|
|
|
|
user_id: int
|
2026-03-26 06:55:12 +00:00
|
|
|
voiceprint_data: Any
|
|
|
|
|
created_at: datetime.datetime
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class VoiceprintStatus(BaseModel):
|
|
|
|
|
has_voiceprint: bool
|
2026-03-26 06:55:12 +00:00
|
|
|
updated_at: Optional[datetime.datetime] = None
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
class VoiceprintTemplate(BaseModel):
|
2026-03-26 06:55:12 +00:00
|
|
|
content: str
|
2026-01-19 11:03:08 +00:00
|
|
|
duration_seconds: int
|
|
|
|
|
|
|
|
|
|
# 菜单权限相关模型
|
|
|
|
|
class MenuInfo(BaseModel):
|
|
|
|
|
menu_id: int
|
|
|
|
|
menu_code: str
|
|
|
|
|
menu_name: str
|
|
|
|
|
menu_icon: Optional[str] = None
|
|
|
|
|
menu_url: Optional[str] = None
|
|
|
|
|
menu_type: str # 'action', 'link', 'divider'
|
|
|
|
|
parent_id: Optional[int] = None
|
|
|
|
|
sort_order: int
|
|
|
|
|
is_active: bool
|
|
|
|
|
description: Optional[str] = None
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
updated_at: datetime.datetime
|
|
|
|
|
|
|
|
|
|
class MenuListResponse(BaseModel):
|
|
|
|
|
menus: List[MenuInfo]
|
|
|
|
|
total: int
|
|
|
|
|
|
|
|
|
|
class RolePermissionInfo(BaseModel):
|
|
|
|
|
role_id: int
|
|
|
|
|
role_name: str
|
|
|
|
|
menu_ids: List[int]
|
|
|
|
|
|
|
|
|
|
class UpdateRolePermissionsRequest(BaseModel):
|
|
|
|
|
menu_ids: List[int]
|
2026-01-21 07:21:17 +00:00
|
|
|
|
2026-03-26 06:55:12 +00:00
|
|
|
class CreateRoleRequest(BaseModel):
|
|
|
|
|
role_name: str
|
|
|
|
|
|
|
|
|
|
class UpdateRoleRequest(BaseModel):
|
|
|
|
|
role_name: str
|
|
|
|
|
|
|
|
|
|
class CreateMenuRequest(BaseModel):
|
|
|
|
|
menu_code: str
|
|
|
|
|
menu_name: str
|
|
|
|
|
menu_icon: Optional[str] = None
|
|
|
|
|
menu_url: Optional[str] = None
|
|
|
|
|
menu_type: str = "link"
|
|
|
|
|
parent_id: Optional[int] = None
|
|
|
|
|
sort_order: int = 0
|
|
|
|
|
is_active: bool = True
|
|
|
|
|
description: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
class UpdateMenuRequest(BaseModel):
|
|
|
|
|
menu_code: Optional[str] = None
|
|
|
|
|
menu_name: Optional[str] = None
|
|
|
|
|
menu_icon: Optional[str] = None
|
|
|
|
|
menu_url: Optional[str] = None
|
|
|
|
|
menu_type: Optional[str] = None
|
|
|
|
|
parent_id: Optional[int] = None
|
|
|
|
|
sort_order: Optional[int] = None
|
|
|
|
|
is_active: Optional[bool] = None
|
|
|
|
|
description: Optional[str] = None
|
|
|
|
|
|
|
|
|
|
class UserMcpInfo(BaseModel):
|
|
|
|
|
id: int
|
|
|
|
|
user_id: int
|
|
|
|
|
bot_id: str
|
|
|
|
|
bot_secret: str
|
|
|
|
|
status: int
|
|
|
|
|
last_used_at: Optional[datetime.datetime] = None
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
updated_at: datetime.datetime
|
|
|
|
|
|
2026-01-21 07:21:17 +00:00
|
|
|
# 专用终端设备模型
|
|
|
|
|
class Terminal(BaseModel):
|
|
|
|
|
id: int
|
|
|
|
|
imei: str
|
|
|
|
|
terminal_name: Optional[str] = None
|
|
|
|
|
terminal_type: str
|
2026-03-26 06:55:12 +00:00
|
|
|
terminal_type_name: Optional[str] = None
|
2026-01-21 07:21:17 +00:00
|
|
|
description: Optional[str] = None
|
|
|
|
|
status: int # 1: 启用, 0: 停用
|
|
|
|
|
is_activated: int # 1: 已激活, 0: 未激活
|
|
|
|
|
activated_at: Optional[datetime.datetime] = None
|
|
|
|
|
firmware_version: Optional[str] = None
|
|
|
|
|
last_online_at: Optional[datetime.datetime] = None
|
|
|
|
|
ip_address: Optional[str] = None
|
|
|
|
|
mac_address: Optional[str] = None
|
|
|
|
|
created_at: datetime.datetime
|
|
|
|
|
updated_at: datetime.datetime
|
|
|
|
|
created_by: Optional[int] = None
|
|
|
|
|
creator_username: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
current_user_id: Optional[int] = None
|
|
|
|
|
current_username: Optional[str] = None
|
|
|
|
|
current_user_caption: Optional[str] = None
|
2026-01-21 07:21:17 +00:00
|
|
|
|
|
|
|
|
class CreateTerminalRequest(BaseModel):
|
|
|
|
|
imei: str
|
|
|
|
|
terminal_name: Optional[str] = None
|
|
|
|
|
terminal_type: str
|
|
|
|
|
description: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
firmware_version: Optional[str] = None
|
|
|
|
|
mac_address: Optional[str] = None
|
2026-01-21 07:21:17 +00:00
|
|
|
status: int = 1
|
|
|
|
|
|
|
|
|
|
class UpdateTerminalRequest(BaseModel):
|
|
|
|
|
terminal_name: Optional[str] = None
|
|
|
|
|
terminal_type: Optional[str] = None
|
|
|
|
|
description: Optional[str] = None
|
|
|
|
|
firmware_version: Optional[str] = None
|
|
|
|
|
mac_address: Optional[str] = None
|
2026-03-26 06:55:12 +00:00
|
|
|
status: Optional[int] = None
|