| | |
| | | import { getTestDetail } from '@/api/tests' |
| | | import { formatBusinessTime } from '@/utils/businessTime' |
| | | import { toTestDisplayValue } from '@/utils/testDataUnits' |
| | | import { formatTestDuration } from '@/utils/testDataDuration' |
| | | |
| | | type ImportStage = 'upload' | 'preview' | 'result' |
| | | |
| | |
| | | XLSX.writeFile(createConsoleImportWorkbook(), '测试三 Sheet 数据导入模板.xlsx') |
| | | } |
| | | |
| | | function previewValue(item: ValidatedImportRow, field: string): string | number { |
| | | // 文件中的系统编号只作展示;真正入库时由系统分配,来源编号不占用此列。 |
| | | if (field === 'recordNo') return String(item.raw['记录编号'] || '-') |
| | | if (field === 'stepDuration' || field === 'relativeTimeSeconds') return formatTestDuration(item.data[field]) |
| | | if (field === 'recordedAt') return formatBusinessTime(item.data[field]) |
| | | const value = item.data[field] |
| | | return typeof value === 'number' ? toTestDisplayValue(field, value) : value ?? '-' |
| | | } |
| | | |
| | | function backToDataList() { |
| | | router.push({ path: `/test-list/${testId}/console`, query: { tab: 'data-list', dataType } }) |
| | | } |
| | |
| | | } |
| | | |
| | | try { |
| | | const workbook = XLSX.read(await file.arrayBuffer(), { type: 'array' }) |
| | | const workbook = XLSX.read(await file.arrayBuffer(), { type: 'array', cellNF: true }) |
| | | sheets.value = workbookMode ? parseConsoleImportWorkbook(workbook, [...knownBatteries.value], selectedBattery.value) : [] |
| | | const rows = workbookMode ? sheets.value.flatMap(sheet => sheet.rows) : parseConsoleImport(workbook, dataType, [...knownBatteries.value], selectedBattery.value) |
| | | if (!rows.length && !workbookMode) { |
| | |
| | | <table><thead><tr><th>工作表</th><th>行数</th><th>有效数</th><th>错误行数</th><th>工作表错误数</th></tr></thead><tbody><tr v-for="sheet in sheets" :key="sheet.type"><td>{{ consoleSheetLabels[sheet.type] }}</td><td>{{ sheet.rows.length }}</td><td>{{ sheet.rows.filter(row => !row.errors.length).length }}</td><td>{{ sheet.rows.filter(row => row.errors.length).length }}</td><td>{{ sheet.errors.length }}</td></tr></tbody></table> |
| | | <el-tabs v-model="previewType"><el-tab-pane v-for="sheet in sheets" :key="sheet.type" :name="sheet.type" :label="consoleSheetLabels[sheet.type]" /></el-tabs> |
| | | </div> |
| | | <div class="preview-table-wrap"><table><thead><tr><th>Excel行号</th><th v-for="(label, field) in consoleImportColumns[previewType]" :key="field">{{ label }}</th><th>校验结果</th></tr></thead><tbody><tr v-for="item in previewRows.slice(0, 12)" :key="item.sourceRow"><td>{{ item.sourceRow }}</td><td v-for="(label, field) in consoleImportColumns[previewType]" :key="label">{{ field === 'recordedAt' ? formatBusinessTime(item.data[field]) : typeof item.data[field] === 'number' ? toTestDisplayValue(field, Number(item.data[field])) : item.data[field] ?? '-' }}</td><td>{{ item.errors.length ? item.errors.join(';') : '通过' }}</td></tr></tbody></table></div> |
| | | <div class="preview-table-wrap"><table><thead><tr><th>Excel行号</th><th v-for="(label, field) in consoleImportColumns[previewType]" :key="field">{{ label }}</th><th>校验结果</th></tr></thead><tbody><tr v-for="item in previewRows.slice(0, 12)" :key="item.sourceRow"><td>{{ item.sourceRow }}</td><td v-for="(label, field) in consoleImportColumns[previewType]" :key="label">{{ previewValue(item, field) }}</td><td>{{ item.errors.length ? item.errors.join(';') : '通过' }}</td></tr></tbody></table></div> |
| | | <p v-if="previewRows.length > 12" class="preview-tip">当前预览前 12 条,共 {{ previewRows.length }} 条数据</p> |
| | | <el-alert v-if="allErrors.length" type="error" :closable="false" :title="workbookMode ? '三 Sheet 校验失败,整批尚未写入数据' : '本页校验失败,尚未写入数据'"><p v-for="(error, index) in allErrors.slice(0, 20)" :key="index">{{ error }}</p></el-alert> |
| | | <el-alert v-if="submitError" class="submit-error" type="error" :closable="false" title="导入未成功"><p>{{ submitError }}</p></el-alert> |