diff --git a/frontend/src/api/pipeline.ts b/frontend/src/api/pipeline.ts index 637ba665..8c63d79c 100644 --- a/frontend/src/api/pipeline.ts +++ b/frontend/src/api/pipeline.ts @@ -205,6 +205,15 @@ export async function saveHypothesis(card: CardDraftInput, sentence?: string): P return data.item } +// 决议O②:人工判卡片死(危险区)——卡下活因子陪葬,cause=reason+(随卡判死) +export async function postHypothesisVerdict( + id: string, reason: string, +): Promise<{ ok: boolean; buried: string[] }> { + const { data } = await apiClient.post<{ ok: boolean; buried: string[] }>( + `/pipeline/hypotheses/${id}/verdict`, { reason }) + return data +} + export async function getFactors(): Promise { const { data } = await apiClient.get<{ items: PipelineFactor[] }>('/pipeline/factors') return data.items diff --git a/frontend/src/views/pipeline/HypothesisPool.spec.ts b/frontend/src/views/pipeline/HypothesisPool.spec.ts index 612f8056..5070d42d 100644 --- a/frontend/src/views/pipeline/HypothesisPool.spec.ts +++ b/frontend/src/views/pipeline/HypothesisPool.spec.ts @@ -8,7 +8,7 @@ import { hypothesesMock } from '@/mock/pipelineData' vi.mock('@/api/pipeline', async (importOriginal) => { const actual = await importOriginal() - return { ...actual, getHypotheses: vi.fn(), getGraveyardFactors: vi.fn(), draftHypothesis: vi.fn(), saveHypothesis: vi.fn(), getDecomposeJobs: vi.fn() } + return { ...actual, getHypotheses: vi.fn(), getGraveyardFactors: vi.fn(), draftHypothesis: vi.fn(), saveHypothesis: vi.fn(), getDecomposeJobs: vi.fn(), postHypothesisVerdict: vi.fn() } }) describe('HypothesisPool.vue', () => { @@ -68,6 +68,34 @@ describe('HypothesisPool.vue', () => { expect(dead[0].text()).toContain('fa高管增持超额') expect(dead[0].attributes('title')).toContain('IC 两窗反号') }) + it('决议O②:判死卡片弹窗列陪葬清单+确认后调端点', async () => { + vi.mocked(api.getHypotheses).mockResolvedValue(hypothesesMock) + vi.mocked(api.postHypothesisVerdict).mockResolvedValue( + { ok: true, buried: ['fa高管增持量比'] }) + // el-dialog teleport 到 document.body,须 attachTo 才能从真实 DOM 查弹窗内容 + const w = mount(HypothesisPool, { global: { plugins: [ElementPlus] }, attachTo: document.body }) + await flushPromises() + await w.findAll('.wiz-btn.danger')[0].trigger('click') + await flushPromises() + const dlg = document.querySelector('.el-dialog') + expect(dlg?.textContent).toContain('判死卡片') + expect(dlg?.textContent).toContain('陪葬清单(1 条)') // mock 1 死 1 活,只列活 + expect(dlg?.textContent).toContain('fa高管增持量比') + // 填死因+确认 + const ta = dlg?.querySelector('textarea') as HTMLTextAreaElement + ta.value = '逻辑前提失效' + ta.dispatchEvent(new Event('input', { bubbles: true })) + await flushPromises() + const btn = Array.from(document.querySelectorAll('.el-dialog button')) + .find((b) => b.textContent?.includes('确认判死')) + btn?.click() + await flushPromises() + expect(api.postHypothesisVerdict).toHaveBeenCalledWith( + expect.any(String), '逻辑前提失效') + // 清理:防 teleport 残留污染后续用例 + w.unmount() + document.querySelectorAll('.el-overlay').forEach((el) => el.remove()) + }) }) describe('向导区(P4-1)', () => { diff --git a/frontend/src/views/pipeline/HypothesisPool.vue b/frontend/src/views/pipeline/HypothesisPool.vue index 0a16c7d6..d97849ce 100644 --- a/frontend/src/views/pipeline/HypothesisPool.vue +++ b/frontend/src/views/pipeline/HypothesisPool.vue @@ -1,8 +1,9 @@