diff --git a/yunke-server/app/api/routers/export.py b/yunke-server/app/api/routers/export.py index bf06787..7ff4488 100644 --- a/yunke-server/app/api/routers/export.py +++ b/yunke-server/app/api/routers/export.py @@ -128,21 +128,22 @@ async def export_chat_html( start: Annotated[int | None, Query(ge=0)] = None, end: Annotated[int | None, Query(ge=0)] = None, ) -> Response: - q = ( - sa.select(Message) - .where(Message.channel == channel) - .where(Message.owner_account_id == owner_account_id) - ) + # 群聊(room_id)不按 owner 过滤:chat_group 表按 room 去重、owner 被末位 + # 员工覆盖,与消息实际归属 owner 错位会导出空文件(同 ChatTimeline 修复, + # 2026-08-22);room 全局唯一且消息只在单一 owner 名下。 + q = sa.select(Message).where(Message.channel == channel) peer = "" if room_id: q = q.where(Message.room_id == room_id) peer = room_id - elif talker_id: - # DM:限定 room_id 为空,避免误捞群消息 - q = q.where(Message.talker_id == talker_id).where( - (Message.room_id == None) | (Message.room_id == "") # noqa: E711 - ) - peer = talker_id + else: + q = q.where(Message.owner_account_id == owner_account_id) + if talker_id: + # DM:限定 room_id 为空,避免误捞群消息 + q = q.where(Message.talker_id == talker_id).where( + (Message.room_id == None) | (Message.room_id == "") # noqa: E711 + ) + peer = talker_id if start is not None: q = q.where(Message.timestamp >= start) if end is not None: diff --git a/yunke-server/tests/test_api_export.py b/yunke-server/tests/test_api_export.py index 9283948..fb005cf 100644 --- a/yunke-server/tests/test_api_export.py +++ b/yunke-server/tests/test_api_export.py @@ -137,3 +137,26 @@ async def test_export_no_warning_below_cap(make_client): assert r.status_code == 200 # No warning DIV (the CSS class still lives in