小程序后端接入 talkingq 共享库并新增消息与定位能力
This commit is contained in:
111
mini-program/app/schemas/im.py
Normal file
111
mini-program/app/schemas/im.py
Normal file
@@ -0,0 +1,111 @@
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
|
||||
class ChildConversationItem(BaseModel):
|
||||
conversation_id: int
|
||||
conversation_type: int
|
||||
conversation_type_name: str
|
||||
peer_type: str
|
||||
peer_id: str
|
||||
peer_name: str | None = None
|
||||
last_message_preview: str | None = None
|
||||
last_message_at: datetime | None = None
|
||||
message_count: int
|
||||
|
||||
|
||||
class ChildConversationListResponse(BaseModel):
|
||||
items: list[ChildConversationItem]
|
||||
total: int
|
||||
next_cursor: int | None = None
|
||||
|
||||
|
||||
class ChildConversationMessageItem(BaseModel):
|
||||
id: int
|
||||
conversation_id: int
|
||||
seq: int
|
||||
sender_type: str
|
||||
sender_id: str
|
||||
receiver_type: str
|
||||
receiver_id: str
|
||||
content_type: int
|
||||
content_text: str | None = None
|
||||
content_json: dict[str, Any] | None = None
|
||||
media_file_key: str | None = None
|
||||
media_duration_ms: int | None = None
|
||||
media_mime_type: str | None = None
|
||||
media_size_bytes: int | None = None
|
||||
media_transcript_text: str | None = None
|
||||
client_msg_id: str | None = None
|
||||
sender_name_snapshot: str | None = None
|
||||
sender_avatar_snapshot: str | None = None
|
||||
receiver_name_snapshot: str | None = None
|
||||
receiver_avatar_snapshot: str | None = None
|
||||
ext_json: dict[str, Any] | None = None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class ChildConversationMessageListResponse(BaseModel):
|
||||
conversation_id: int
|
||||
has_more: bool
|
||||
next_cursor_seq: int | None = None
|
||||
items: list[ChildConversationMessageItem]
|
||||
|
||||
|
||||
class BaseConversationMessageCreateRequest(BaseModel):
|
||||
content_type: int = Field(ge=1, le=4)
|
||||
content_text: str | None = None
|
||||
content_json: dict[str, Any] | None = None
|
||||
media_file_key: str | None = None
|
||||
media_duration_ms: int | None = Field(default=None, ge=0)
|
||||
media_mime_type: str | None = None
|
||||
media_size_bytes: int | None = Field(default=None, ge=0)
|
||||
media_transcript_text: str | None = None
|
||||
client_msg_id: str = Field(min_length=1, max_length=64)
|
||||
ext_json: dict[str, Any] | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_message_payload(self) -> "BaseConversationMessageCreateRequest":
|
||||
if self.content_type == 1 and not self.content_text:
|
||||
raise ValueError("content_text is required when content_type=1")
|
||||
if self.content_type == 2 and not self.media_file_key:
|
||||
raise ValueError("media_file_key is required when content_type=2")
|
||||
if self.content_type == 3 and not self.media_file_key:
|
||||
raise ValueError("media_file_key is required when content_type=3")
|
||||
if self.content_type == 4 and self.content_json is None:
|
||||
raise ValueError("content_json is required when content_type=4")
|
||||
return self
|
||||
|
||||
|
||||
class ParentChildMessageCreateRequest(BaseConversationMessageCreateRequest):
|
||||
pass
|
||||
|
||||
|
||||
class DeviceMessageCreateRequest(BaseConversationMessageCreateRequest):
|
||||
conversation_type: int = Field(ge=1, le=2)
|
||||
peer_child_id: int | None = Field(default=None, ge=1)
|
||||
parent_user_id: int | None = Field(default=None, ge=1)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_target(self) -> "DeviceMessageCreateRequest":
|
||||
if self.conversation_type == 1:
|
||||
if self.peer_child_id is None:
|
||||
raise ValueError("peer_child_id is required when conversation_type=1")
|
||||
if self.parent_user_id is not None:
|
||||
raise ValueError("parent_user_id must be empty when conversation_type=1")
|
||||
if self.conversation_type == 2:
|
||||
if self.parent_user_id is None:
|
||||
raise ValueError("parent_user_id is required when conversation_type=2")
|
||||
if self.peer_child_id is not None:
|
||||
raise ValueError("peer_child_id must be empty when conversation_type=2")
|
||||
return self
|
||||
|
||||
|
||||
class ConversationMessageCreateResponse(BaseModel):
|
||||
idempotent: bool
|
||||
conversation_id: int
|
||||
conversation_type: int
|
||||
conversation_type_name: str
|
||||
message: ChildConversationMessageItem
|
||||
53
mini-program/app/schemas/location.py
Normal file
53
mini-program/app/schemas/location.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class DeviceLocationReportRequest(BaseModel):
|
||||
coord_type: str = Field(default="gcj02", min_length=1, max_length=16)
|
||||
lat: float = Field(ge=-90, le=90)
|
||||
lng: float = Field(ge=-180, le=180)
|
||||
accuracy_m: int | None = Field(default=None, ge=0)
|
||||
altitude_m: float | None = None
|
||||
speed_mps: float | None = None
|
||||
heading_deg: int | None = Field(default=None, ge=0, le=360)
|
||||
source: int = Field(ge=0)
|
||||
battery_pct: int | None = Field(default=None, ge=0, le=100)
|
||||
device_time: datetime
|
||||
|
||||
|
||||
class DeviceLocationPoint(BaseModel):
|
||||
child_id: int
|
||||
child_name: str | None = None
|
||||
device_id: str
|
||||
coord_type: str
|
||||
lat: float
|
||||
lng: float
|
||||
accuracy_m: int | None = None
|
||||
altitude_m: float | None = None
|
||||
speed_mps: float | None = None
|
||||
heading_deg: int | None = None
|
||||
source: int
|
||||
battery_pct: int | None = None
|
||||
device_time: datetime
|
||||
server_time: datetime
|
||||
|
||||
|
||||
class DeviceLocationCurrentResponse(DeviceLocationPoint):
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class DeviceLocationReportResponse(DeviceLocationCurrentResponse):
|
||||
pass
|
||||
|
||||
|
||||
class DeviceLocationTrajectoryItem(DeviceLocationPoint):
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class DeviceLocationTrajectoryResponse(BaseModel):
|
||||
items: list[DeviceLocationTrajectoryItem]
|
||||
total: int
|
||||
start_at: datetime | None = None
|
||||
end_at: datetime | None = None
|
||||
@@ -1,57 +0,0 @@
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
|
||||
class MessageCreateRequest(BaseModel):
|
||||
peer_user_id: int = Field(gt=0)
|
||||
client_msg_id: str = Field(min_length=1, max_length=64)
|
||||
content_type: int = Field(description="1-text 2-audio 3-image 4-json")
|
||||
content_text: str | None = Field(default=None)
|
||||
content_json: dict[str, Any] | None = None
|
||||
media_file_key: str | None = Field(default=None, max_length=255)
|
||||
media_duration_ms: int | None = Field(default=None, ge=0)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_message_fields(self) -> "MessageCreateRequest":
|
||||
if self.content_type not in {1, 2, 3, 4}:
|
||||
raise ValueError("content_type must be one of 1, 2, 3, 4")
|
||||
|
||||
if self.content_type == 1 and not (self.content_text and self.content_text.strip()):
|
||||
raise ValueError("content_text is required when content_type is 1")
|
||||
|
||||
if self.content_type in {2, 3} and not self.media_file_key:
|
||||
raise ValueError("media_file_key is required when content_type is 2 or 3")
|
||||
|
||||
if self.content_type == 4 and self.content_json is None:
|
||||
raise ValueError("content_json is required when content_type is 4")
|
||||
|
||||
return self
|
||||
|
||||
|
||||
class MessageItem(BaseModel):
|
||||
id: int
|
||||
conversation_id: int
|
||||
seq: int
|
||||
sender_user_id: int | None
|
||||
role: int
|
||||
content_type: int
|
||||
content_text: str | None
|
||||
content_json: dict[str, Any] | None
|
||||
media_file_key: str | None
|
||||
media_duration_ms: int | None
|
||||
client_msg_id: str | None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class MessageCreateResponse(BaseModel):
|
||||
idempotent: bool
|
||||
message: MessageItem
|
||||
|
||||
|
||||
class MessageListResponse(BaseModel):
|
||||
conversation_id: int
|
||||
has_more: bool
|
||||
next_cursor_seq: int | None
|
||||
items: list[MessageItem]
|
||||
Reference in New Issue
Block a user