feat: 优化业务界面并修复助手意图回复
This commit is contained in:
@@ -334,11 +334,88 @@ def business_command(payload: CommandInput, request: Request):
|
||||
return {"intent": "submit_review", "message": "AI预审报告已提交评审,历史版本保持可查看。", "object_id": submitted["id"], "url": f"/review-pool?submitted={payload.project_id}"}
|
||||
unresolved = [f for f in project_body["findings"] if f["status"] not in ("已解决", "不适用")]
|
||||
latest = project_body["runs"][0] if project_body["runs"] else None
|
||||
message_text = f"{project_body['customer']}当前有{len(unresolved)}项待处理风险、{len(project_body['pending_candidates'])}项材料候选待确认。"
|
||||
if latest:
|
||||
message_text += f"最近一次{('独立评审' if latest.get('run_kind') == 'independent_review' else 'AI预审')}状态为{latest['status']}。"
|
||||
message_text += "下一步:" + (f"处理“{unresolved[0]['title']}”" if unresolved else "生成报告或提交下一环节")
|
||||
return {"intent": "project_status", "message": message_text, "items": [{"id": f["id"], "title": f["title"], "status": f["status"]} for f in unresolved[:5]], "url": f"/xingbang-workbench?project={payload.project_id}"}
|
||||
pending = project_body["pending_candidates"]
|
||||
project_url = f"/xingbang-workbench?project={quote(payload.project_id)}"
|
||||
run_labels = {"queued": "等待执行", "running": "执行中", "completed": "已完成", "partial": "部分完成", "failed": "执行失败", "cancelled": "已取消"}
|
||||
workflow_labels = {"report_ready": "报告准备", "supplementing": "补充材料", "submitted": "待评审领取", "under_review": "评审办理", "returned": "退回补件", "review_approved": "评审通过", "withdrawn": "已撤回"}
|
||||
field_labels = {"facility.amount": "融资金额", "lease.total_value": "租赁物价值", "lease.duplicate_count": "设备清单重复情况", "financial.operating_cashflow": "经营现金流资料", "financial.total_liabilities": "财报负债", "due_diligence.liabilities": "尽调负债", "collection.evidence": "回款依据", "credit.overdue_count": "征信逾期记录", "credit.report_date": "征信报告日期"}
|
||||
|
||||
def finding_title(item):
|
||||
title = item.get("title", "待核查问题")
|
||||
if "." in title and title.endswith("完整性"):
|
||||
field = next(iter(item.get("fields", [])), title[:-3])
|
||||
return field_labels.get(field, title) + "是否完整"
|
||||
return title
|
||||
|
||||
if any(word in message for word in ("下一步", "接下来", "要做什么", "该做什么", "怎么推进", "如何推进", "怎么办")):
|
||||
workflow = project_body.get("workflow_state", "")
|
||||
independent = next((r for r in project_body["runs"] if r.get("run_kind") == "independent_review"), None)
|
||||
if current_role == "reviewer" and workflow == "submitted" and not project_body.get("reviewer_id"):
|
||||
next_text = "下一步请先到项目评审池领取该项目;领取后再发起独立评审。"
|
||||
next_url = "/review-pool"
|
||||
elif current_role == "reviewer" and not independent:
|
||||
next_text = "下一步请发起独立评审,系统会基于评审员专用 Skills 与规则重新核查全链路。"
|
||||
next_url = project_url + "&tab=review"
|
||||
elif workflow == "returned":
|
||||
returned = next((d for d in project_body["review_decisions"] if d.get("decision") == "退回" and not d.get("finding_id") and not d.get("node_id")), None)
|
||||
reason = (returned or {}).get("opinion") or "请查看评审员的退回要求"
|
||||
next_text = f"下一步请先补充退回材料:{reason}。确认材料来源后,重新发起AI预审。"
|
||||
next_url = project_url + "&tab=findings"
|
||||
elif pending:
|
||||
next_text = f"下一步请先确认{len(pending)}项材料候选,确认期间、口径和来源后再更新项目事实。"
|
||||
next_url = project_url + "&tab=findings"
|
||||
elif latest and latest["status"] in ("queued", "running"):
|
||||
next_text = f"本次{('独立评审' if latest.get('run_kind') == 'independent_review' else 'AI预审')}正在{run_labels[latest['status']]}。下一步先查看运行进度,完成后再处理问题。"
|
||||
next_url = project_url
|
||||
elif unresolved:
|
||||
first = unresolved[0]
|
||||
action = first.get("suggested_action") or "补充对应材料并说明核实口径"
|
||||
next_text = f"下一步先处理“{finding_title(first)}”:{action}。处理后重新AI预审,确认问题是否闭环。"
|
||||
next_url = project_url + "&tab=findings#project-findings"
|
||||
elif not latest:
|
||||
next_text = "下一步请发起AI预审,系统会检查当前材料并列出需要补充或人工确认的事项。"
|
||||
next_url = project_url
|
||||
elif not project_body["reports"]:
|
||||
next_text = "当前问题已闭环。下一步请生成AI预审报告,并核对报告内容和来源版本。"
|
||||
next_url = project_url + "&tab=report"
|
||||
elif workflow != "submitted":
|
||||
next_text = "当前报告已经具备送审条件。下一步请核对报告后提交正式评审。"
|
||||
next_url = project_url + "&tab=report"
|
||||
else:
|
||||
next_text = "项目已经提交。下一步请到项目评审池查看领取状态和等待时间。"
|
||||
next_url = "/review-pool"
|
||||
return {"intent": "next_step", "message": next_text, "url": next_url}
|
||||
|
||||
if any(word in message for word in ("什么问题", "哪些问题", "问题是什么", "风险", "异常")):
|
||||
if unresolved:
|
||||
details = ";".join(f"{index + 1}.{finding_title(item)}({item['status']})" for index, item in enumerate(unresolved[:5]))
|
||||
message_text = f"当前共有{len(unresolved)}项未闭环问题:{details}。打开问题页可以逐项查看数据来源、AI判断和解决建议。"
|
||||
else:
|
||||
message_text = "当前没有未闭环问题。你可以继续生成报告,或查看历史检查记录和来源依据。"
|
||||
return {"intent": "project_issues", "message": message_text, "items": [{"id": f["id"], "title": f["title"], "status": f["status"]} for f in unresolved[:5]], "url": project_url + "&tab=findings#project-findings"}
|
||||
|
||||
if any(word in message for word in ("还缺", "缺什么", "缺少", "材料", "补件")):
|
||||
if pending:
|
||||
fields = "、".join(str(item.get("field") or "待确认字段") for item in pending[:5])
|
||||
message_text = f"当前有{len(pending)}项材料解析候选尚未确认:{fields}。请打开材料档案,核对期间、单位和来源后确认。"
|
||||
elif unresolved:
|
||||
message_text = f"当前没有待确认的材料解析候选,但仍有{len(unresolved)}项业务问题。请先查看“{finding_title(unresolved[0])}”的数据依据和补件建议。"
|
||||
else:
|
||||
message_text = f"当前没有待确认的材料候选,已归档{len(project_body['documents'])}份材料,现有问题已闭环。"
|
||||
return {"intent": "materials", "message": message_text, "url": project_url + "&tab=findings"}
|
||||
|
||||
if any(word in message for word in ("到哪", "进度", "状态", "阶段", "办到")):
|
||||
stage = workflow_labels.get(project_body.get("workflow_state", ""), project_body.get("stage") or "处理中")
|
||||
message_text = f"{project_body['customer']}当前处于“{stage}”阶段:有{len(unresolved)}项风险待处理,{len(pending)}项材料候选待确认。"
|
||||
if latest:
|
||||
run_name = "独立评审" if latest.get("run_kind") == "independent_review" else "AI预审"
|
||||
message_text += f"最近一次{run_name}{run_labels.get(latest['status'], latest['status'])}。"
|
||||
return {"intent": "project_status", "message": message_text, "items": [{"id": f["id"], "title": f["title"], "status": f["status"]} for f in unresolved[:5]], "url": project_url}
|
||||
|
||||
if any(word in message for word in ("能做什么", "可以做什么", "怎么用", "如何使用", "帮助")) or message in ("你好", "您好", "嗨"):
|
||||
return {"intent": "help", "message": "我可以帮你查项目进度、说明下一步、列出问题与缺失材料,也可以发起AI预审、生成报告和提交正式评审。你可以直接问:这个项目到哪一步了?或:我接下来要做什么?", "url": project_url}
|
||||
|
||||
return {"intent": "clarify", "message": "我还不能确定你要查哪一项。你可以直接说“查看项目进度”“下一步做什么”“有哪些问题”“还缺什么材料”,也可以使用左侧快捷操作。复杂的自由分析请切换到 mini-openclaw。", "url": project_url}
|
||||
|
||||
|
||||
@router.get("/projects/{project_id}/reports/{report_id}/export")
|
||||
|
||||
Reference in New Issue
Block a user