yeg
2026-09-06 f2384cd6229df223707ed48c15bce8f1483e35cc
修复仅编辑权限的报表预览与更新入口

保存和取消后按编辑权限读取最新快照,保持历史查看权限独立。补充对应页面验证,并防止更新来源的旧请求覆盖其他报表。
2个文件已修改
33 ■■■■■ 已修改文件
src/views/ReportCompareForm.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/e2e/compare-version-editing.spec.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/ReportCompareForm.vue
@@ -214,7 +214,9 @@
    canQuery.value = Boolean(info.permissions?.some(item => item === '*:*:*' || item === 'system:compare-report:query'))
    if (id) {
      if (mode === 'edit' && (!canEdit.value || version !== undefined)) throw new Error('历史版本只读或无编辑权限')
      const record = await getCompareReport(id, version === undefined ? undefined : Number(version), mode === 'edit')
      // 编辑权限包含读取最新编辑基准,取消或保存后仍可预览;历史查看单独要求查看权限。
      const editingAccess = mode === 'edit' || (!canQuery.value && canEdit.value && version === undefined)
      const record = await getCompareReport(id, version === undefined ? undefined : Number(version), editingAccess)
      if (cancelled) return
      editingRecord.value = record
      loadEditingReport()
@@ -429,13 +431,7 @@
      await createCompareReport({ ...content, selections: selectedTests.value.map(item => item.selection) })
    }
    ElMessage.success('对比报表已保存')
    if (editingId.value && !canQuery.value) {
      editingRecord.value = await getCompareReport(editingId.value, undefined, true)
      loadEditingReport()
      changeSummary.value = ''
    } else {
      await router.push(editingId.value ? { path: `/report-compare/${editingId.value}/edit`, query: { mode: 'view' } } : '/report-compare')
    }
    await router.push(editingId.value ? { path: `/report-compare/${editingId.value}/edit`, query: { mode: 'view' } } : '/report-compare')
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '保存失败,请重试')
  } finally {
@@ -445,6 +441,7 @@
async function generateFromLatestSource() {
  if (saving.value || !editingRecord.value || !editingId.value) return
  const baseRecord = editingRecord.value
  let reason: string
  try {
    const result = await ElMessageBox.prompt('将重新读取当前来源并生成新版本,保留已有人工表格值。', '按最新来源生成版本', {
@@ -453,9 +450,11 @@
    })
    reason = result.value.trim()
  } catch { return }
  if (editingRecord.value !== baseRecord) return
  saving.value = true
  try {
    const record = await refreshCompareSource(editingId.value, editingRecord.value.versionNo, reason)
    const record = await refreshCompareSource(baseRecord.id, baseRecord.versionNo, reason)
    if (editingRecord.value !== baseRecord) return
    editingRecord.value = record
    loadEditingReport()
    ElMessage.success(`已生成版本 ${record.versionNo}`)
@@ -574,6 +573,7 @@
.report-name-panel, .compare-info-panel, .detail-panel, .metrics-panel { background: #fff; border: 1px solid #d8e1e9; }
.report-name-panel { padding: 18px 22px; margin-bottom: 16px; }
.report-name-panel label + label { margin-top: 12px; }
.report-name-panel > span { display: block; margin-top: 12px; overflow-wrap: anywhere; }
.series-swatch { flex: 0 0 12px; width: 12px; height: 12px; display: inline-block; }
.report-name-panel label { display: grid; grid-template-columns: 72px minmax(260px, 420px); align-items: center; gap: 12px; }
.report-name-panel label > span, .detail-meta label > span { color: #52606d; font-size: 12px; font-weight: 500; }
tests/e2e/compare-version-editing.spec.ts
@@ -202,12 +202,23 @@
      await page.getByPlaceholder('请输入报表名称').fill('跨用户编辑V8')
      await page.getByPlaceholder('请输入修改说明').fill('编辑权限跨创建人')
      await page.getByRole('button', { name: '保存新版本', exact: true }).click()
      await expect(page.getByPlaceholder('请输入修改说明')).toHaveValue('')
      await expect(page).toHaveURL(/mode=view$/)
      await expect(page.getByPlaceholder('请输入报表名称')).toHaveValue('跨用户编辑V8')
      const v8 = (await api(page, `compare-report/${v1.id}/editing`)).data
      expect(v8.versionNo).toBe(8)
      expect(v8.operatorName).toBe('version_editor')
      expect(v8.items).toEqual(v7.items)
      await api(page, `compare-report/${v1.id}/refresh-source`, 'POST', { baseVersionNo: 8, changeSummary: '删除来源拒绝更新' }, 500)
      await expect(page.getByRole('button', { name: '历史版本', exact: true })).toHaveCount(0)
      await page.getByRole('button', { name: '编辑报表', exact: true }).click()
      await page.getByPlaceholder('请输入报表名称').fill('取消的修改')
      await page.getByRole('button', { name: '取消编辑', exact: true }).click()
      await expect(page.getByPlaceholder('请输入报表名称')).toHaveValue('跨用户编辑V8')
      await page.getByRole('button', { name: '按最新来源生成版本', exact: true }).click()
      await page.getByPlaceholder('请输入更新来源说明').fill('删除来源拒绝更新')
      const rejectedRefresh = page.waitForResponse(response => response.url().endsWith('/refresh-source'))
      await page.getByRole('button', { name: '生成新版本', exact: true }).click()
      expect((await (await rejectedRefresh).json()).code).toBe(500)
      expect((await api(page, `compare-report/${v1.id}/editing`)).data).toEqual(v8)
    }
    if (canRead) {
      await page.goto(`/report-compare/${v1.id}/edit?mode=view`)