fix(regulatory): 将条件确认移入对话区

This commit is contained in:
2026-06-07 10:37:12 +08:00
parent 48d94884b9
commit 12b476a8ef
3 changed files with 58 additions and 27 deletions

View File

@@ -43,6 +43,7 @@ def workspace(request: HttpRequest) -> HttpResponse:
current = conversations.first()
workflow_cards = build_workflow_cards(current) if current else []
condition_confirmation = build_condition_confirmation(workflow_cards)
return render(
request,
@@ -55,6 +56,7 @@ def workspace(request: HttpRequest) -> HttpResponse:
"messages": current.messages.all() if current else [],
"attachments": FileAttachment.objects.filter(conversation=current).order_by("original_name", "-version_no") if current else [],
"workflow_cards": workflow_cards,
"condition_confirmation": condition_confirmation,
},
)
@@ -154,6 +156,21 @@ def build_workflow_cards(conversation: Conversation) -> list[dict[str, object]]:
return sorted(cards, key=lambda item: item["created_at"], reverse=True)[:5]
def build_condition_confirmation(workflow_cards: list[dict[str, object]]) -> dict[str, object] | None:
for card in workflow_cards:
if (
card.get("workflow_type") == "regulatory_review"
and card.get("status") == RegulatoryReviewBatch.Status.WAITING_USER
and card.get("condition_candidates")
):
return {
"id": card["id"],
"batch_no": card["batch_no"],
"candidates": card["condition_candidates"],
}
return None
def _format_risk_label(risk_summary: dict) -> str:
parts = []
labels = [

View File

@@ -124,6 +124,43 @@
</div>
</article>
{% endfor %}
{% if condition_confirmation %}
<article
class="message assistant"
id="condition-confirmation-{{ condition_confirmation.id }}"
data-node-label="AI 适用条件确认"
>
<div class="message-avatar">AI</div>
<div class="message-bubble">
<form
class="condition-confirm-form"
data-condition-confirm-form
data-batch-id="{{ condition_confirmation.id }}"
data-confirm-url="/api/review-agent/regulatory-review/{{ condition_confirmation.id }}/conditions/"
>
{% csrf_token %}
<strong>适用条件确认</strong>
<p>请确认 {{ condition_confirmation.batch_no }} 的产品类别、注册类型和临床评价路径,确认后我会继续法规核查。</p>
{% for field, config in condition_confirmation.candidates.items %}
<label>
<span>{{ config.label }}</span>
{% if config.input_type == "select" %}
<select name="{{ field }}">
{% for option in config.options %}
<option value="{{ option }}"{% if option == config.suggested %} selected{% endif %}>{{ option }}</option>
{% endfor %}
</select>
{% else %}
<input type="text" name="{{ field }}" value="{{ config.suggested|default:'' }}">
{% endif %}
</label>
{% endfor %}
<button type="submit">确认并继续</button>
<p class="condition-confirm-status" data-condition-confirm-status></p>
</form>
</div>
</article>
{% endif %}
{% else %}
<div class="empty-state">
<p class="eyebrow">审核智能体</p>
@@ -257,33 +294,6 @@
{% if batch.error_message %}
<p class="workflow-error">{{ batch.error_message }}</p>
{% endif %}
{% if batch.workflow_type == "regulatory_review" and batch.status == "waiting_user" and batch.condition_candidates %}
<form
class="condition-confirm-form"
data-condition-confirm-form
data-batch-id="{{ batch.id }}"
data-confirm-url="/api/review-agent/regulatory-review/{{ batch.id }}/conditions/"
>
{% csrf_token %}
<strong>适用条件确认</strong>
{% for field, config in batch.condition_candidates.items %}
<label>
<span>{{ config.label }}</span>
{% if config.input_type == "select" %}
<select name="{{ field }}">
{% for option in config.options %}
<option value="{{ option }}"{% if option == config.suggested %} selected{% endif %}>{{ option }}</option>
{% endfor %}
</select>
{% else %}
<input type="text" name="{{ field }}" value="{{ config.suggested|default:'' }}">
{% endif %}
</label>
{% endfor %}
<button type="submit">确认并继续</button>
<p class="condition-confirm-status" data-condition-confirm-status></p>
</form>
{% endif %}
<ol>
{% for node in batch.nodes %}
<li class="node-status status-{{ node.status }}" data-node-code="{{ node.node_code }}">

View File

@@ -102,6 +102,10 @@ def test_workspace_renders_condition_confirmation_form(client, django_user_model
assert "data-condition-confirm-form" in content
assert "体外诊断试剂" in content
assert "甲胎蛋白检测试剂盒" in content
form_index = content.index("data-condition-confirm-form")
summary_index = content.index('id="summaryPanel"')
assert form_index < summary_index
assert "data-condition-confirm-form" not in content[summary_index:]
def test_workspace_renders_rectification_actions_and_summaries(client, tmp_path, django_user_model):