2026-08-30-questionnaire-report-merge.md 9.1 KB

问卷管理合并报告管理 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 在 PC 端问卷管理页面内按问卷展开评估记录和报告列表,展示生成状态并支持预览、导出、发送和重新生成。

Architecture: 以现有 questionnaireList.vue 为主页面,通过 Element UI 表格展开行承载该问卷的团队评估记录;每条评估记录复用 reportList 组件展示报告和操作。继续复用现有 API,报告生成使用 DeerFlow genReport 接口;旧报告路由保留,菜单入口不通过数据库迁移修改。

Tech Stack: Vue 2.7、Vue Router、Element UI、Jest、Vue CLI。

Spec: docs/superpowers/specs/2026-08-30-questionnaire-report-merge-design.md

Global Constraints

  • 以问卷管理为主入口。
  • 不改变小程序端、报告生成协议和数据库结构。
  • 报告生成必须使用 /core/team/questionnaire/genReport/{teamQuestionnaireId}
  • 复用现有报告预览、导出、发送、删除和重新生成权限逻辑。
  • 旧报告管理路由保持可访问。

Task 1: Define the questionnaire/report expansion contract

Files:

  • Create: tests/unit/questionnaireReportMerge.spec.js
  • Modify: src/views/modules/agent/questionnaireList.vue

Interfaces:

  • Produces the page-level behaviors toggleReportList(row), loadReportEntries(row), and refreshReportEntry(index).
  • The questionnaire row stores reportExpanded and reportEntries; each report entry has the existing team-questionnaire fields plus showMore and reportList.

  • [ ] Step 1: Write the failing test

Add source-level regression assertions that the questionnaire page imports team questionnaire/report APIs, renders a 报告列表 action and an expandable report section, and does not rely on the old report-page-only questionnaire selector:

const fs = require('fs')
const path = require('path')

const source = fs.readFileSync(
  path.resolve(__dirname, '../../src/views/modules/agent/questionnaireList.vue'),
  'utf8'
)

test('questionnaire management exposes an inline report list action', () => {
  expect(source).toContain('报告列表')
  expect(source).toContain('getTeamQuestionnaireList')
  expect(source).toContain('getTeamReportWjList')
  expect(source).toContain('reportList')
  expect(source).toContain('reportExpanded')
})
  • Step 2: Run test to verify it fails

Run: npm test -- --runInBand tests/unit/questionnaireReportMerge.spec.js --silent

Expected: FAIL because questionnaireList.vue currently has no report action or report APIs.

  • Step 3: Write the minimal page contract

Add the report API imports, a reportList component import, a 报告列表 button in the existing operation column, and an Element UI type="expand" column whose content renders one reportList component per loaded team questionnaire entry. Add row state initialization:

const prepareQuestionnaireRow = row => ({
  ...row,
  reportExpanded: false,
  reportEntries: [],
  reportLoading: false
})

const dataList = ref([])

const toggleReportList = async row => {
  row.reportExpanded = !row.reportExpanded
  if (row.reportExpanded && row.reportEntries.length === 0) {
    await loadReportEntries(row)
  }
}

Use getTeamQuestionnaireList({ page: 1, limit: 100, questionnaireId: row.id }) to load all matching evaluation records for the selected template and map each entry to { ...entry, showMore: false, reportList: [] }.

  • Step 4: Run test to verify it passes

Run: npm test -- --runInBand tests/unit/questionnaireReportMerge.spec.js --silent

Expected: PASS.

  • Step 5: Commit
git add tests/unit/questionnaireReportMerge.spec.js src/views/modules/agent/questionnaireList.vue
git commit -m "feat: 在问卷管理中增加报告列表入口"

Task 2: Connect report status, preview, and report operations

Files:

  • Modify: src/views/modules/agent/questionnaireList.vue
  • Modify: src/components/reportList/index.vue only if an event/prop compatibility fix is required
  • Test: tests/unit/questionnaireReportMerge.spec.js

Interfaces:

  • Consumes: getTeamReportWjList(relationId), deleteTeamReportWj, sendReportUsers, and reCreateReport from src/api/agent/index.js.
  • Produces: expanded report records whose state is rendered by the existing reportList status mapping and whose preview/export actions use existing report artifact fields.

  • [ ] Step 1: Extend the failing test

Add assertions that the page wires report-list events and invokes the current DeerFlow generation helper rather than the legacy endpoint:

test('expanded questionnaire reports retain report operations and current generation endpoint', () => {
  const apiSource = fs.readFileSync(
    path.resolve(__dirname, '../../src/api/agent/index.js'),
    'utf8'
  )
  expect(source).toContain('@toggleReport')
  expect(source).toContain('@reCreateReport')
  expect(source).toContain('@refreshReportList')
  expect(apiSource).toContain('/core/team/questionnaire/genReport/${teamQuestionnaireId}')
})
  • Step 2: Run test to verify it fails

Run: npm test -- --runInBand tests/unit/questionnaireReportMerge.spec.js --silent

Expected: FAIL because the page does not yet wire the report component events or report refresh behavior.

  • Step 3: Implement the report event handlers

Add page handlers matching the existing report page behavior:

const toggleReportEntry = (entry, index) => {
  entry.showMore = !entry.showMore
  if (entry.showMore) {
    getTeamReportWjList(entry.id).then(res => {
      if (res.code !== 0) return proxy.$message.error(res.msg)
      entry.reportList = res.data || []
    })
  } else {
    entry.reportList = []
  }
}

const refreshReportEntry = entry => {
  getTeamReportWjList(entry.id).then(res => {
    if (res.code !== 0) return proxy.$message.error(res.msg)
    entry.reportList = res.data || []
  })
}

Wire deleteReport, sendReport, reCreateReport, and refreshReportList to the same existing API methods and permissions used by report.vue. Keep preview and export inside reportList/index.vue; do not duplicate PDF modal code in the questionnaire page. Ensure the generation operation remains the already-fixed genReportById helper.

  • Step 4: Run test to verify it passes

Run: npm test -- --runInBand tests/unit/questionnaireReportMerge.spec.js --silent

Expected: PASS.

  • Step 5: Commit
git add tests/unit/questionnaireReportMerge.spec.js src/views/modules/agent/questionnaireList.vue src/components/reportList/index.vue
git commit -m "feat: 在问卷页展示报告状态和操作"

Task 3: Preserve navigation compatibility and verify the integrated page

Files:

  • Modify: src/views/modules/home.vue if the homepage report shortcut must point to the merged questionnaire page
  • Modify: src/views/modules/agent/report.vue only if its legacy route requires a compatibility redirect
  • Modify: tests/unit/questionnaireReportMerge.spec.js

Interfaces:

  • Consumes: existing dynamic menu and static route behavior.
  • Produces: old report links remain valid while new primary navigation lands on questionnaire management.

  • [ ] Step 1: Write the failing compatibility test

Add assertions for the chosen compatibility behavior:

test('homepage report shortcut points to the questionnaire management entry', () => {
  const homeSource = fs.readFileSync(
    path.resolve(__dirname, '../../src/views/modules/home.vue'),
    'utf8'
  )
  expect(homeSource).toContain("toTurn('agent-questionnaire')")
  expect(homeSource).not.toContain("toTurn('agent-report')")
})
  • Step 2: Run test to verify it fails

Run: npm test -- --runInBand tests/unit/questionnaireReportMerge.spec.js --silent

Expected: FAIL because the homepage still has a “更多报告” shortcut that targets the standalone report page.

  • Step 3: Implement compatibility behavior

Keep /agent-report available for existing links. Update only new homepage navigation if required; do not delete the legacy report component or alter backend menu records. If dynamic menu configuration still exposes “报告管理”, its page remains functional while “问卷管理” becomes the primary merged entry.

  • Step 4: Run the full verification suite

Run:

npm test -- --runInBand --silent
npm run build

Expected: all unit suites pass and Vue CLI reports Build complete with exit code 0.

  • Step 5: Inspect the final diff

Run:

git diff --check
git status --short
git diff --stat HEAD~3..HEAD

Confirm only the questionnaire/report merge files and plan/spec documents changed; do not stage node_modules, unrelated worktree files, or generated files unless deployment is separately requested.

  • Step 6: Commit
git add src/views/modules/home.vue src/views/modules/agent/report.vue tests/unit/questionnaireReportMerge.spec.js
git commit -m "test: 验证问卷报告管理合并"