feat:新增大屏存取发布接口
This commit is contained in:
@@ -45,6 +45,8 @@ class MongoConversationStore:
|
||||
await self._conversations.create_index("created_at")
|
||||
# 按用户查询会话
|
||||
await self._conversations.create_index("user_id")
|
||||
# 按大屏过滤会话
|
||||
await self._conversations.create_index([("user_id", ASCENDING), ("screen_id", ASCENDING)])
|
||||
|
||||
async def _purge_expired(self) -> None:
|
||||
# 只清理没有任何轮次且超过保留时长的空会话,有对话的会话不受影响
|
||||
@@ -66,12 +68,17 @@ class MongoConversationStore:
|
||||
if empty:
|
||||
await self._conversations.delete_many({"_id": {"$in": empty}})
|
||||
|
||||
async def create(self, user_id: int) -> str:
|
||||
async def create(self, user_id: int, screen_id: str | None = None) -> str:
|
||||
await self._purge_expired()
|
||||
conversation_id = str(uuid4())
|
||||
# user_id 来自用户中心,会话只对创建者可见
|
||||
await self._conversations.insert_one(
|
||||
{"_id": conversation_id, "created_at": _now(), "user_id": user_id}
|
||||
{
|
||||
"_id": conversation_id,
|
||||
"created_at": _now(),
|
||||
"user_id": user_id,
|
||||
"screen_id": screen_id,
|
||||
}
|
||||
)
|
||||
return conversation_id
|
||||
|
||||
@@ -121,12 +128,13 @@ class MongoConversationStore:
|
||||
upsert=True,
|
||||
)
|
||||
|
||||
async def list_by_user(
|
||||
self, user_id: int, limit: int, offset: int
|
||||
) -> list[ConversationSummary]:
|
||||
def _with_stats(self, user_id: int, screen_id: str | None) -> list[dict]:
|
||||
match: dict = {"user_id": user_id}
|
||||
if screen_id is not None:
|
||||
match["screen_id"] = screen_id
|
||||
# $unwind 会丢弃没有任何轮次的空会话
|
||||
pipeline = [
|
||||
{"$match": {"user_id": user_id}},
|
||||
return [
|
||||
{"$match": match},
|
||||
{
|
||||
"$lookup": {
|
||||
"from": self._turns.name,
|
||||
@@ -146,6 +154,13 @@ class MongoConversationStore:
|
||||
}
|
||||
},
|
||||
{"$unwind": "$stats"},
|
||||
]
|
||||
|
||||
async def list_by_user(
|
||||
self, user_id: int, limit: int, offset: int, screen_id: str | None = None
|
||||
) -> list[ConversationSummary]:
|
||||
pipeline = [
|
||||
*self._with_stats(user_id, screen_id),
|
||||
{"$sort": {"stats.updated_at": -1, "_id": -1}},
|
||||
{"$skip": offset},
|
||||
{"$limit": limit},
|
||||
@@ -154,8 +169,30 @@ class MongoConversationStore:
|
||||
return [
|
||||
ConversationSummary(
|
||||
conversation_id=item["_id"],
|
||||
title=make_title(item["stats"]["first_prompt"]),
|
||||
title=item.get("title") or make_title(item["stats"]["first_prompt"]),
|
||||
screen_id=item.get("screen_id"),
|
||||
updated_at=item["stats"]["updated_at"],
|
||||
)
|
||||
for item in await cursor.to_list()
|
||||
]
|
||||
|
||||
async def count_by_user(self, user_id: int, screen_id: str | None = None) -> int:
|
||||
pipeline = [*self._with_stats(user_id, screen_id), {"$count": "total"}]
|
||||
cursor = await self._conversations.aggregate(pipeline)
|
||||
counted = await cursor.to_list()
|
||||
return counted[0]["total"] if counted else 0
|
||||
|
||||
async def rename(self, conversation_id: str, user_id: int, title: str) -> bool:
|
||||
if not await self.exists(conversation_id, user_id):
|
||||
return False
|
||||
await self._conversations.update_one(
|
||||
{"_id": conversation_id, "user_id": user_id}, {"$set": {"title": title}}
|
||||
)
|
||||
return True
|
||||
|
||||
async def delete(self, conversation_id: str, user_id: int) -> bool:
|
||||
if not await self.exists(conversation_id, user_id):
|
||||
return False
|
||||
await self._turns.delete_many({"conversation_id": conversation_id})
|
||||
await self._conversations.delete_one({"_id": conversation_id, "user_id": user_id})
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user