2026-09-12 20:42:33 +08:00
|
|
|
|
"""投顾工作台请求 DTO(入参校验;响应多以 dict 返回,随业务拼装)。"""
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import datetime
|
2026-09-13 16:19:24 +08:00
|
|
|
|
from typing import Any, Literal
|
2026-09-12 20:42:33 +08:00
|
|
|
|
|
2026-09-13 16:19:24 +08:00
|
|
|
|
from common_const import (
|
|
|
|
|
|
TALK_SCENE_CUSTOMER_COMPLAINT,
|
|
|
|
|
|
TALK_SCENE_MARKET_FLUCTUATION,
|
|
|
|
|
|
TALK_SCENE_PORTFOLIO_DIVERGENCE,
|
|
|
|
|
|
TALK_SCENE_RISK_BLOCK_ORDER,
|
|
|
|
|
|
)
|
2026-09-12 20:42:33 +08:00
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DraftSaveReq(BaseModel):
|
|
|
|
|
|
"""草稿编辑保存入参(代理到 Agent PUT /draft/{id}/save,Agent 重新适当性校验)。"""
|
|
|
|
|
|
|
|
|
|
|
|
title: str | None = Field(default=None, max_length=128)
|
|
|
|
|
|
content: str = Field(default="")
|
|
|
|
|
|
suggestions: Any = None # 结构化建议清单(超配赎回/低配申购),结构由 Agent 定义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DraftOperateReq(BaseModel):
|
|
|
|
|
|
"""草稿操作入参(仅支持 discard 废弃)。"""
|
|
|
|
|
|
|
|
|
|
|
|
action: str = Field(pattern="^(discard)$")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RebalanceRunReq(BaseModel):
|
|
|
|
|
|
"""触发调仓再平衡(异步受理,结果靠事件回执)。"""
|
|
|
|
|
|
|
|
|
|
|
|
customer_id: int = Field(gt=0)
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-13 18:24:44 +08:00
|
|
|
|
class AdvisorDataQueryReq(BaseModel):
|
|
|
|
|
|
"""工作台代理 Agent 的客户数据查询请求。"""
|
|
|
|
|
|
|
|
|
|
|
|
customer_id: int = Field(gt=0)
|
|
|
|
|
|
question: str = Field(min_length=1, max_length=2000)
|
|
|
|
|
|
session_id: str | None = Field(default=None, max_length=64)
|
|
|
|
|
|
max_rows: int | None = Field(default=None, gt=0, le=10000)
|
|
|
|
|
|
page: int = Field(default=1, ge=1, le=100000)
|
|
|
|
|
|
page_size: int = Field(default=100, ge=1, le=10000)
|
|
|
|
|
|
sort_by: str | None = Field(default=None, max_length=128)
|
|
|
|
|
|
sort_order: Literal["asc", "desc"] = "asc"
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-12 20:42:33 +08:00
|
|
|
|
class TalkScriptReq(BaseModel):
|
|
|
|
|
|
"""生成沟通话术草稿(同步,超时由工作台降级为「稍后重试」)。"""
|
|
|
|
|
|
|
|
|
|
|
|
customer_id: int = Field(gt=0)
|
2026-09-13 16:19:24 +08:00
|
|
|
|
scene_type: Literal[
|
|
|
|
|
|
TALK_SCENE_RISK_BLOCK_ORDER,
|
|
|
|
|
|
TALK_SCENE_MARKET_FLUCTUATION,
|
|
|
|
|
|
TALK_SCENE_PORTFOLIO_DIVERGENCE,
|
|
|
|
|
|
TALK_SCENE_CUSTOMER_COMPLAINT,
|
|
|
|
|
|
]
|
2026-09-12 20:42:33 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RelationReq(BaseModel):
|
|
|
|
|
|
"""客户关系流转(sign=签约 / close=结束服务),工作台是签约状态唯一写入方。"""
|
|
|
|
|
|
|
|
|
|
|
|
action: str = Field(pattern="^(sign|close)$")
|
|
|
|
|
|
reason: str | None = Field(default=None, max_length=128)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VisitCreateReq(BaseModel):
|
|
|
|
|
|
"""人工回访留痕入参(不触发 Agent 记忆抽取)。"""
|
|
|
|
|
|
|
|
|
|
|
|
customer_id: int = Field(gt=0)
|
|
|
|
|
|
visit_type: str = Field(min_length=1, max_length=32)
|
|
|
|
|
|
visit_time: datetime
|
|
|
|
|
|
summary: str | None = None
|
|
|
|
|
|
audio_url: str | None = Field(default=None, max_length=512)
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-13 16:19:24 +08:00
|
|
|
|
class VisitUpdateReq(BaseModel):
|
|
|
|
|
|
"""回访记录可编辑字段;不提供字段时拒绝空更新。"""
|
|
|
|
|
|
|
|
|
|
|
|
visit_type: str | None = Field(default=None, min_length=1, max_length=32)
|
|
|
|
|
|
visit_time: datetime | None = None
|
|
|
|
|
|
summary: str | None = None
|
|
|
|
|
|
audio_url: str | None = Field(default=None, max_length=512)
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-09-12 20:42:33 +08:00
|
|
|
|
class TodoHandleReq(BaseModel):
|
|
|
|
|
|
"""待办处理入参(process=开始处理 / done=完成)。"""
|
|
|
|
|
|
|
|
|
|
|
|
action: str = Field(pattern="^(process|done)$")
|