feat:新增投顾工作台相关接口
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
"""驾驶舱聚合(首页数据与待办聚合,PRD §4.1)。
|
||||
|
||||
口径说明(E1 最小口径):总 AUM=名下客户「持有中」持仓市值之和;有效客户=signed;
|
||||
流失率=closed/总客户;报告产出/发送=advisor_report 计数。回访完成率等精细口径 P2 后置。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from common_const import (
|
||||
CUSTOMER_REL_STATUS_CLOSED,
|
||||
CUSTOMER_REL_STATUS_SIGNED,
|
||||
REPORT_SEND_STATUS_DRAFT,
|
||||
REPORT_SEND_STATUS_SENT,
|
||||
TODO_STATUS_PENDING,
|
||||
)
|
||||
from model.sys_user import SysUser
|
||||
from repositories.advisor_report import AdvisorReportRepo
|
||||
from repositories.advisor_todo import AdvisorTodoRepo
|
||||
from repositories.advisor_visit_record import AdvisorVisitRecordRepo
|
||||
from repositories.customer_relation import CustomerRelationRepo
|
||||
|
||||
|
||||
async def get_dashboard(db: AsyncSession, user: SysUser) -> dict:
|
||||
relation_repo = CustomerRelationRepo(db)
|
||||
todo_repo = AdvisorTodoRepo(db)
|
||||
report_repo = AdvisorReportRepo(db)
|
||||
visit_repo = AdvisorVisitRecordRepo(db)
|
||||
|
||||
pending = await todo_repo.count_by_advisor(advisor_id=user.id, status=TODO_STATUS_PENDING)
|
||||
total = await relation_repo.count_customer_rows(advisor_id=user.id)
|
||||
signed = await relation_repo.count_customer_rows(
|
||||
advisor_id=user.id, status=CUSTOMER_REL_STATUS_SIGNED
|
||||
)
|
||||
closed = await relation_repo.count_customer_rows(
|
||||
advisor_id=user.id, status=CUSTOMER_REL_STATUS_CLOSED
|
||||
)
|
||||
aum = await relation_repo.sum_holdings_value(user.id)
|
||||
sent = await report_repo.count_by_advisor(
|
||||
advisor_id=user.id, send_status=REPORT_SEND_STATUS_SENT
|
||||
)
|
||||
draft = await report_repo.count_by_advisor(
|
||||
advisor_id=user.id, send_status=REPORT_SEND_STATUS_DRAFT
|
||||
)
|
||||
visits = await visit_repo.count_by_advisor(advisor_id=user.id)
|
||||
|
||||
# 客户分层:C1-C5 各档人数(未知等级归入 unknown)
|
||||
levels = {k: 0 for k in ("C1", "C2", "C3", "C4", "C5")}
|
||||
unknown = 0
|
||||
for level, cnt in await relation_repo.risk_level_distribution(user.id):
|
||||
if level in levels:
|
||||
levels[level] = cnt
|
||||
else:
|
||||
unknown += cnt
|
||||
|
||||
return {
|
||||
"todos": {"pending": pending},
|
||||
"overview": {
|
||||
"total_customers": total,
|
||||
"signed_customers": signed,
|
||||
"closed_customers": closed,
|
||||
"churn_rate": round(closed / total, 4) if total else 0.0,
|
||||
"total_aum": f"{aum:.2f}",
|
||||
"reports_sent": sent,
|
||||
"reports_draft": draft,
|
||||
"visits_count": visits,
|
||||
},
|
||||
"customer_levels": {**levels, "unknown": unknown},
|
||||
}
|
||||
Reference in New Issue
Block a user