对齐控制台三类数据字段
按甲方工作簿统一实时、工步、循环子页及下载导出字段,移除多余接收时间和来源列,修正实时绝对时间展示与模板字段。
| | |
| | | ElMessage.warning('没有可下载的数据') |
| | | return |
| | | } |
| | | const headers = activeTab.value === 'cycle' ? ['记录编号', '电池', '循环号', '充电容量(mAh)', '放电容量(mAh)', '充放电效率(%)', '充电能量(mWh)', '放电能量(mWh)'] : activeTab.value === 'step' ? ['记录编号', '电池', '循环号', '工步序号', '工步', '工步时间', '容量(mAh)', '能量(mWh)', '起始电压(V)', '终止电压(V)', '充电中值电压(V)', '放电中值电压(V)'] : ['记录编号', '电池', '循环号', '实际工步号', '实际工步名称', '记录序号', '设备时间', '服务器接收时间', '电压(V)', '电流(mA)', '容量(mAh)', '能量(mWh)', '温度(℃)', '正电位(V)', '负电位(V)'] |
| | | const records = activeTab.value === 'cycle' ? filteredRows.value.map(row => [row.recordNo, row.batteryNo, row.cycleNo, row.chargeCapacity, row.dischargeCapacity, row.efficiency, row.chargeEnergy, row.dischargeEnergy]) : activeTab.value === 'step' ? filteredRows.value.map(row => [row.recordNo, row.batteryNo, row.cycleNo, row.stepNo, row.stepName, row.stepDuration, row.capacity, row.energy, row.startVoltage, row.endVoltage, row.chargeMedianVoltage, row.dischargeMedianVoltage]) : filteredRows.value.map(row => [row.recordNo, row.batteryNo, row.cycleNo, row.stepNo, row.stepName, row.sequenceId, row.recordedAt, row.serverReceivedAt, row.voltage, row.current, row.capacity, row.energy, row.temperature, row.positivePotential, row.negativePotential]) |
| | | const headers = activeTab.value === 'cycle' ? ['记录编号', '电池', '循环序号', '充电容量(mAh)', '放电容量(mAh)', '充放电效率(%)', '充电能量(mWh)', '放电能量(mWh)'] : activeTab.value === 'step' ? ['记录编号', '电池', '循环序号', '工步序号', '工步名称', '工步时间(h:min:s.ms)', '容量(mAh)', '能量(mWh)', '起始电压(V)', '终止电压(V)', '充电中值电压(V)', '放电中值电压(V)'] : ['记录编号', '电池', '循环序号', '工步序号', '工步名称', '记录序号', '记录时间(h:min:s.ms)', '电压(V)', '电流(mA)', '容量(mAh)', '能量(mWh)', '绝对时间', '温度(℃)', '正电位(V)', '负电位(V)'] |
| | | const records = activeTab.value === 'cycle' ? filteredRows.value.map(row => [row.recordNo, row.batteryNo, row.cycleNo, row.chargeCapacity, row.dischargeCapacity, row.efficiency, row.chargeEnergy, row.dischargeEnergy]) : activeTab.value === 'step' ? filteredRows.value.map(row => [row.recordNo, row.batteryNo, row.cycleNo, row.stepNo, row.stepName, row.stepDuration, row.capacity, row.energy, row.startVoltage, row.endVoltage, row.chargeMedianVoltage, row.dischargeMedianVoltage]) : filteredRows.value.map(row => [row.recordNo, row.batteryNo, row.cycleNo, row.stepNo, row.stepName, row.sequenceId, row.recordedAt, row.voltage, row.current, row.capacity, row.energy, row.absoluteTime, row.temperature, row.positivePotential, row.negativePotential]) |
| | | const blob = new Blob([`\uFEFF${[headers, ...records].map(item => item.map(escapeCsv).join(',')).join('\n')}`], { type: 'text/csv;charset=utf-8' }) |
| | | const url = URL.createObjectURL(blob) |
| | | const anchor = document.createElement('a') |
| | |
| | | </th> |
| | | <th>记录编号</th> |
| | | <th>电池</th> |
| | | <th>循环号</th> |
| | | <th>实际工步号</th> |
| | | <th>实际工步名称</th> |
| | | <th>循环序号</th> |
| | | <th>工步序号</th> |
| | | <th>工步名称</th> |
| | | <th>记录序号</th> |
| | | <th>设备时间</th> |
| | | <th>服务器接收时间</th> |
| | | <th class="source-column">来源</th> |
| | | <th>绝对时间</th> |
| | | <th>温度(℃)</th> |
| | | <th>正电位(V)</th> |
| | | <th>负电位(V)</th> |
| | |
| | | <th class="selection-column"></th> |
| | | <th>记录编号</th> |
| | | <th>电池</th> |
| | | <th>循环号</th> |
| | | <th>工步</th> |
| | | <th>设备时间</th> |
| | | <th>服务器接收时间</th> |
| | | <th>循环序号</th> |
| | | <th>工步名称</th> |
| | | <th>工步时间</th> |
| | | <th>容量(mAh)</th> |
| | | <th>能量(mWh)</th> |
| | |
| | | <th class="selection-column"></th> |
| | | <th>记录编号</th> |
| | | <th>电池</th> |
| | | <th>循环号</th> |
| | | <th>设备时间</th> |
| | | <th>服务器接收时间</th> |
| | | <th>循环序号</th> |
| | | <th>充电容量(mAh)</th> |
| | | <th>放电容量(mAh)</th> |
| | | <th>充放电效率(%)</th> |
| | |
| | | <td>{{ row.stepName }}</td> |
| | | <td>{{ row.sequenceId }}</td> |
| | | <td>{{ row.recordedAt }}</td> |
| | | <td>{{ row.serverReceivedAt }}</td> |
| | | <td class="source-column" :title="row.sourceIdentity">{{ row.sourceType === 'COLLECTOR' ? `采集器 ${row.collectorCode}` : row.sourceType === 'SNAPSHOT' ? '检测柜 + 采集器' : '检测柜' }}<small>{{ row.sourceIdentity }}</small><small v-if="row.sourceType === 'SNAPSHOT'">采集器 {{ row.collectorCode }} · {{ row.collectorDeviceTime }}</small><small v-if="row.sourceType === 'COLLECTOR'">{{ row.channelCode }}</small><small v-if="row.extensionMeasurements !== '-'">{{ row.extensionMeasurements }}</small></td> |
| | | <td>{{ row.absoluteTime }}</td> |
| | | <td><el-input v-if="editing && draftRows[row.id]" v-model="draftRows[row.id].temperature" size="small" /><span v-else>{{ row.temperature }}</span></td> |
| | | <td><el-input v-if="editing && draftRows[row.id]" v-model="draftRows[row.id].positivePotential" size="small" /><span v-else>{{ row.positivePotential }}</span></td> |
| | | <td><el-input v-if="editing && draftRows[row.id]" v-model="draftRows[row.id].negativePotential" size="small" /><span v-else>{{ row.negativePotential }}</span></td> |
| | |
| | | </td> |
| | | <td>{{ row.cycleNo }}</td> |
| | | <td>{{ row.stepNo }} · {{ row.stepName }}</td> |
| | | <td>{{ row.recordedAt }}</td> |
| | | <td>{{ row.serverReceivedAt }}</td> |
| | | <td> |
| | | <el-input v-if="editing && draftRows[row.id]" v-model="draftRows[row.id].stepDuration" size="small" /> |
| | | <span v-else>{{ row.stepDuration }}</span> |
| | |
| | | <strong>{{ row.batteryNo }}</strong> |
| | | </td> |
| | | <td>{{ row.cycleNo }}</td> |
| | | <td>{{ row.recordedAt }}</td> |
| | | <td>{{ row.serverReceivedAt }}</td> |
| | | <td> |
| | | <el-input v-if="editing && draftRows[row.id]" v-model="draftRows[row.id].chargeCapacity" size="small" /> |
| | | <span v-else>{{ row.chargeCapacity }}</span> |
| | |
| | | </tr></template |
| | | > |
| | | <tr v-if="!loading && !pagedRows.length"> |
| | | <td :colspan="activeTab === 'realtime' ? 19 : activeTab === 'step' ? 15 : 12" class="empty-cell"> |
| | | <td :colspan="activeTab === 'realtime' ? 17 : activeTab === 'step' ? 14 : 10" class="empty-cell"> |
| | | {{ loadError || '暂无检测柜记录' }} |
| | | </td> |
| | | </tr> |
| | |
| | | import type { ConsoleDataType } from '../api/consoleData' |
| | | |
| | | export const consoleImportColumns = { |
| | | REALTIME: { recordNo: '记录编号', batteryNo: '电池号', recordedAt: '设备时间', cycleNo: '循环序号', stepNo: '工步序号', stepName: '工步名称', sequenceId: '记录序号', voltage: '电压(V)', current: '电流(mA)', capacity: '容量(mAh)', energy: '能量(mWh)', temperature: '温度(℃)', positivePotential: '正电位(V)', negativePotential: '负电位(V)' }, |
| | | REALTIME: { recordNo: '记录编号', batteryNo: '电池号', recordedAt: '记录时间(h:min:s.ms)', cycleNo: '循环序号', stepNo: '工步序号', stepName: '工步名称', sequenceId: '记录序号', voltage: '电压(V)', current: '电流(mA)', capacity: '容量(mAh)', energy: '能量(mWh)', temperature: '温度(℃)', positivePotential: '正电位(V)', negativePotential: '负电位(V)' }, |
| | | STEP: { recordNo: '记录编号', batteryNo: '电池号', recordedAt: '设备时间', cycleNo: '循环序号', stepNo: '工步序号', stepName: '工步', stepDuration: '工步时间', capacity: '容量(mAh)', energy: '能量(mWh)', startVoltage: '起始电压(V)', endVoltage: '终止电压(V)', chargeMedianVoltage: '充电中值电压(V)', dischargeMedianVoltage: '放电中值电压(V)' }, |
| | | CYCLE: { recordNo: '记录编号', batteryNo: '电池号', recordedAt: '设备时间', cycleNo: '循环序号', chargeCapacity: '充电容量(mAh)', dischargeCapacity: '放电容量(mAh)', efficiency: '充放电效率(%)', chargeEnergy: '充电能量(mWh)', dischargeEnergy: '放电能量(mWh)' }, |
| | | } satisfies Record<ConsoleDataType, Record<string, string>> |
| | |
| | | // 旧标准模板按原列头单位读取,避免对 A/Ah/Wh 再次缩放。 |
| | | const headerFor = (field: string, standardHeader: string) => { |
| | | if (party) return partyHeaders[field] || standardHeader |
| | | if (field === 'recordedAt' && headers.includes('设备时间')) return '设备时间' |
| | | const legacyHeader = standardHeader.replace(/\(m(A|Ah|Wh)\)/, '($1)') |
| | | return headers.includes(standardHeader) ? standardHeader : headers.includes(legacyHeader) ? legacyHeader : standardHeader |
| | | } |