yeg
2026-09-08 9a72cbf40e15349d5da9014afc22ac8e1419a681
修复拼接模板与来源详情身份隔离
2个文件已修改
19 ■■■■■ 已修改文件
src/components/SpliceFieldControls.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/e2e/splice-battery-segments.spec.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/SpliceFieldControls.vue
@@ -14,7 +14,8 @@
const loading = ref(false)
const saving = ref(false)
const error = ref('')
const identity = (field: SpliceField) => field.name
// 共享字段以定义 ID 区分;控制台详情只有名称,不能与同名共享字段合并。
const identity = (field: SpliceField) => field.fieldDefinitionId ? `id:${field.fieldDefinitionId}` : `name:${field.name}`
const fieldName = (field: SpliceField) => field.name
function openSettings() {
  const available: SpliceField[] = props.segments.flatMap(segment => (segment.businessFields || []).map(field => ({
@@ -52,7 +53,11 @@
function applyTemplate() {
  const template = templates.value.find(item => item.id === selectedTemplate.value)
  if (!template) { ElMessage.warning('请选择字段模板'); return }
  emit('apply', template.fields.map(field => ({ ...field })))
  const consoleFields: SpliceField[] = [...props.segments.flatMap(segment => (segment.consoleDetail?.batteryFields || []).map(name => ({ name, displayName: name, unit: '', category: 'battery' as const }))), ...props.segments.flatMap(segment => (segment.consoleDetail?.specialFields || []).map(name => ({ name, displayName: name, unit: '', category: 'special' as const })))]
  const selected = template.fields.map(field => ({ ...field }))
  // 模板只替换结构;来源控制台字段仍保留为独立详情行,除非模板明确选择了同一身份。
  for (const field of consoleFields) if (!selected.some(item => item.name === field.name && !item.fieldDefinitionId)) selected.push(field)
  emit('apply', selected)
  templatesVisible.value = false; ElMessage.success('字段模板已应用')
}
async function saveTemplate() {
tests/e2e/splice-battery-segments.spec.ts
@@ -1,6 +1,5 @@
import { expect, test, type Page } from '@playwright/test'
import { Ticket04Stack } from './support/ticket04-stack'
import { spliceSourceValue } from '@/api/spliceReports'
const stack = new Ticket04Stack()
const selection = (testBatteryId: number) => ({ testId: testBatteryId < 9703 ? 9701 : 9702, testBatteryId })
@@ -27,15 +26,6 @@
})
test.afterAll(async () => stack.stop())
test('同名控制台字段与共享字段按身份隔离', () => {
  const segment: any = {
    source: { selection: { testId: 1, testBatteryId: 2 }, batteryNo: '1号' },
    businessFields: [{ fieldDefinitionId: 10, fieldName: '质量', fieldValue: '共享值' }],
    consoleDetail: { batteryFields: ['质量'], specialFields: [], fieldValues: { 质量: '控制台值' } },
  }
  expect(spliceSourceValue(segment, {}, { name: '质量', category: 'battery', displayName: '质量', unit: 'kg', fieldDefinitionId: 10 })).toBe('共享值')
  expect(spliceSourceValue(segment, {}, { name: '质量', category: 'battery', displayName: '质量', unit: '', fieldDefinitionId: null })).toBe('控制台值')
})
async function login(page: Page) {
  await page.goto('/login')
  await page.locator('input[autocomplete="username"]').fill('admin')