diff --git a/static/js/app.js b/static/js/app.js index 67a1478..675ac08 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -649,12 +649,14 @@ return; } var cardId = "condition-confirmation-" + confirmation.batch_id; + removeStaleConditionConfirmationCards(cardId); if (document.getElementById(cardId)) { return; } var article = document.createElement("article"); article.className = "message assistant"; article.id = cardId; + article.setAttribute("data-condition-confirmation-card", ""); article.setAttribute("data-node-label", "AI 适用条件确认"); var avatar = document.createElement("div"); @@ -687,6 +689,14 @@ scrollChatToBottom(); } + function removeStaleConditionConfirmationCards(activeCardId) { + document.querySelectorAll("[data-condition-confirmation-card]").forEach(function (card) { + if (card.id !== activeCardId) { + card.remove(); + } + }); + } + function renderConditionFields(candidates) { var html = ""; Object.keys(candidates || {}).forEach(function (field) { @@ -830,9 +840,9 @@ delete workflowPollingTimers[key]; } - function startWorkflowPolling(batchId) { + function startWorkflowPolling(batchId, workflow_type) { var card = workflowCardList ? workflowCardList.querySelector('[data-batch-id="' + batchId + '"]') : null; - var workflow_type = card ? card.getAttribute("data-workflow-type") || "file_summary" : "file_summary"; + workflow_type = workflow_type || (card ? card.getAttribute("data-workflow-type") || "file_summary" : "file_summary"); var key = workflowTimerKey(batchId, workflow_type); if (!batchId || workflowPollingTimers[key]) { return; @@ -907,7 +917,7 @@ status.textContent = "已确认,工作流继续执行。"; } form.classList.add("confirmed"); - startWorkflowPolling(batchId); + startWorkflowPolling(batchId, "regulatory_review"); await refreshWorkflowCard(batchId, "regulatory_review"); } catch (error) { if (status) { @@ -1050,7 +1060,7 @@ assistantMessage.text.innerHTML = renderAssistantContent(assistantText); } else if (eventName === "workflow_started") { ensureWorkflowCard(payload); - startWorkflowPolling(payload.batch_id); + startWorkflowPolling(payload.batch_id, payload.workflow_type); } else if (eventName === "done") { if (payload.assistant_message_id) { assistantMessage.article.id = "message-" + payload.assistant_message_id; diff --git a/templates/home.html b/templates/home.html index e3e1132..50301fb 100644 --- a/templates/home.html +++ b/templates/home.html @@ -128,6 +128,7 @@
AI
diff --git a/tests/test_regulatory_frontend.py b/tests/test_regulatory_frontend.py index c786a6e..9fbef5f 100644 --- a/tests/test_regulatory_frontend.py +++ b/tests/test_regulatory_frontend.py @@ -163,3 +163,20 @@ def test_frontend_selects_status_url_by_workflow_type(): assert "condition_confirmation" in script assert "bindRectificationActionButtons" in script assert "data-rectification-action" in script + + +def test_frontend_polls_regulatory_workflow_with_explicit_workflow_type(): + script = open("static/js/app.js", encoding="utf-8").read() + + assert "function startWorkflowPolling(batchId, workflow_type)" in script + assert "startWorkflowPolling(payload.batch_id, payload.workflow_type)" in script + assert 'startWorkflowPolling(batchId, "regulatory_review")' in script + assert 'workflow_type || (card ? card.getAttribute("data-workflow-type") || "file_summary" : "file_summary")' in script + + +def test_frontend_keeps_single_condition_confirmation_prompt(): + script = open("static/js/app.js", encoding="utf-8").read() + + assert "data-condition-confirmation-card" in script + assert "removeStaleConditionConfirmationCards" in script + assert '[data-condition-confirmation-card]' in script