fix(names): 会话/统计弹窗/zip 文件名的共享好友昵称读 link 快照
用户报 Lily 聊天窗口「聊天好友」列表里 A**郑 显示成 wxid_ir6uxy2li8no22 ——A**郑是 14 个员工共享的客户,档案行(customer 全局单行 last-wins)挂在 别的员工名下,按 owner 查档案查空,三个显示位回退 wxid: - sessions._meta(会话列表名字/头像/delete_flag) - staff_chat_stats._customer_names(五数字弹窗明细) - chat-html-zip 文件名 统一改为优先 customer_account_link per-owner 快照(link 未覆盖回退档案, 空表过渡安全)。staff_stats(统计分析新客户等)仍是档案口径,属分析语义 另行评估。613 测试绿(新增会话共享好友昵称 2 例)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.deps import get_session
|
||||
from app.api.schemas import StaffChatCustomerOut, StaffChatStatsOut, StaffChatStatsSummary
|
||||
from app.db.models import Customer, Message, MsgDailyStats
|
||||
from app.db.models import Customer, CustomerAccountLink, Message, MsgDailyStats
|
||||
from app.storage.summary import day_key, has_rows as _summary_has_rows
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["staff-chat-stats"])
|
||||
@@ -144,22 +144,43 @@ async def _aggregate_summary(
|
||||
|
||||
|
||||
async def _customer_names(session: AsyncSession, owner: str, talker_ids: list[str]) -> dict[str, tuple[str, str, str]]:
|
||||
"""客户名/头像解析:优先 customer_account_link per-owner 快照,档案兜底。
|
||||
|
||||
共享客户的档案行(customer 全局单行,last-wins)可能挂在别的员工名下,
|
||||
按 owner 查档案会查空、明细列表回退显示 wxid(2026-09-09,同 sessions
|
||||
._meta 修复)。
|
||||
"""
|
||||
if not talker_ids:
|
||||
return {}
|
||||
stmt = sa.select(
|
||||
Customer.friend_id,
|
||||
Customer.friend_remark,
|
||||
Customer.friend_nickname,
|
||||
Customer.real_name,
|
||||
Customer.head_image_url,
|
||||
).where(
|
||||
Customer.channel == "wechat",
|
||||
Customer.owner_account_id == owner,
|
||||
Customer.friend_id.in_(talker_ids),
|
||||
)
|
||||
info: dict[str, tuple[str, str, str]] = {}
|
||||
for fid, remark, nick, real, head in (await session.execute(stmt)).all():
|
||||
link_stmt = sa.select(
|
||||
CustomerAccountLink.friend_id,
|
||||
CustomerAccountLink.friend_remark,
|
||||
CustomerAccountLink.friend_nickname,
|
||||
CustomerAccountLink.real_name,
|
||||
CustomerAccountLink.head_image_url,
|
||||
).where(
|
||||
CustomerAccountLink.channel == "wechat",
|
||||
CustomerAccountLink.owner_account_id == owner,
|
||||
CustomerAccountLink.friend_id.in_(talker_ids),
|
||||
)
|
||||
for fid, remark, nick, real, head in (await session.execute(link_stmt)).all():
|
||||
info[fid] = (remark or nick or real or fid, real or "", head or "")
|
||||
missing = [t for t in talker_ids if t not in info]
|
||||
if missing:
|
||||
stmt = sa.select(
|
||||
Customer.friend_id,
|
||||
Customer.friend_remark,
|
||||
Customer.friend_nickname,
|
||||
Customer.real_name,
|
||||
Customer.head_image_url,
|
||||
).where(
|
||||
Customer.channel == "wechat",
|
||||
Customer.owner_account_id == owner,
|
||||
Customer.friend_id.in_(missing),
|
||||
)
|
||||
for fid, remark, nick, real, head in (await session.execute(stmt)).all():
|
||||
info[fid] = (remark or nick or real or fid, real or "", head or "")
|
||||
return info
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user