| | |
| | | import { ref } from 'vue' |
| | | import { listSpliceReports, createSpliceReport, editSpliceReport, deleteSpliceReport } from '@/api/spliceReports' |
| | | export type SpliceTestSelection = { id:number; name:string; type:string; durationMinutes:number } |
| | | export type SpliceTestSelection = { id:number; testBatteryId?:number; name:string; type:string; durationMinutes:number } |
| | | export interface SpliceReportRecord { id:number; name:string; creator:string; createdAt:string; experimentName:string; batteryGroup:string; samples:string[]; tests:SpliceTestSelection[]; batteryFields:string[]; specialFields:string[]; detailFieldValues:Record<string,Record<string,string>>; metrics:string[]; seriesColors:string[] } |
| | | export type SpliceReportPayload = Omit<SpliceReportRecord,'id'|'createdAt'> |
| | | const records=ref<SpliceReportRecord[]>([]) |
| | | export function useSpliceReports(){ |
| | | async function load(){ records.value=(await listSpliceReports()).map(item=>({...item,createdAt:String(item.createdAt)}) as unknown as SpliceReportRecord) } |
| | | async function createReport(data:SpliceReportPayload){await createSpliceReport(data as unknown as Record<string, unknown>);await load()} |
| | | async function createReport(data:SpliceReportPayload){ |
| | | const selections = data.tests.map(item => ({ testId: item.id, testBatteryId: item.testBatteryId })) |
| | | if (selections.some(item => !item.testBatteryId)) throw new Error('拼接来源缺少电池身份') |
| | | await createSpliceReport({ name: data.name, description: data.experimentName, selections, settings: { batteryFields: data.batteryFields, specialFields: data.specialFields, detailFieldValues: data.detailFieldValues, metrics: data.metrics, seriesColors: data.seriesColors } }) |
| | | await load() |
| | | } |
| | | async function updateReport(id:number,data:SpliceReportPayload){await editSpliceReport(id,data as unknown as Record<string, unknown>);await load();return true} |
| | | async function removeReport(id:number){await deleteSpliceReport(id);await load()} |
| | | return {records,load,createReport,updateReport,removeReport} |
| | |
| | | <script setup lang="ts"> |
| | | import { toTestDisplayValue } from '@/utils/testDataUnits' |
| | | import { computed, reactive, ref, watch } from 'vue' |
| | | import { computed, reactive, ref, watch, onMounted } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import { use } from 'echarts/core' |
| | |
| | | import { getCurrentUser } from '@/utils/auth' |
| | | import { useBatteryGroupFields } from '@/stores/batteryGroupFields' |
| | | import { useSpliceReports, type SpliceReportPayload, type SpliceTestSelection } from '@/stores/spliceReports' |
| | | import { getSpliceSources } from '@/api/spliceReports' |
| | | import { formationFixedReportFields, formationMetricDefinitions, type FormationMetricDefinition, type FormationMetricKey } from '@/utils/formationReportPrint' |
| | | |
| | | use([CanvasRenderer, LineChart, GridComponent, LegendComponent, MarkLineComponent, TooltipComponent]) |
| | |
| | | const selectedTests = ref<SpliceTestSelection[]>([ |
| | | { id: 101, name: 'SP2电池化成测试', type: '化成', durationMinutes: 90 }, |
| | | ]) |
| | | const candidateTests: SpliceTestSelection[] = [ |
| | | const candidateTests = ref<SpliceTestSelection[]>([ |
| | | { id: 102, name: '化成后静置测试', type: '静置', durationMinutes: 60 }, |
| | | { id: 103, name: '首次容量测试', type: '容量', durationMinutes: 75 }, |
| | | { id: 104, name: '常温倍率放电测试', type: '倍率', durationMinutes: 80 }, |
| | | { id: 105, name: '恢复容量测试', type: '容量', durationMinutes: 70 }, |
| | | { id: 106, name: '循环后静置测试', type: '静置', durationMinutes: 45 }, |
| | | ] |
| | | ]) |
| | | onMounted(async () => { |
| | | const sources = await getSpliceSources() |
| | | candidateTests.value = sources.map(source => ({ id: source.selection.testId, testBatteryId: source.selection.testBatteryId, name: source.name, type: source.type, durationMinutes: 0 })) as SpliceTestSelection[] |
| | | if (!editingId.value && candidateTests.value.length) selectedTests.value = [candidateTests.value[0]] |
| | | }) |
| | | |
| | | const batteryFields = ref(['额定容量', '内阻']) |
| | | const specialFields = ref(['环境温度']) |
| | |
| | | |
| | | const enabledMetrics = computed(() => formationMetricDefinitions.filter(metric => metricVisible[metric.key])) |
| | | const dynamicDetailFields = computed(() => [...batteryFields.value, ...specialFields.value]) |
| | | const selectedCandidate = computed(() => candidateTests.find(item => item.id === selectedCandidateId.value) || null) |
| | | const selectedCandidate = computed(() => candidateTests.value.find(item => item.id === selectedCandidateId.value) || null) |
| | | const batteryFieldOptions = computed(() => [...managedGroupFields.value].sort((a, b) => b.createdAt.localeCompare(a.createdAt))) |
| | | const specialTemplates = computed(() => [ |
| | | { key: 'cycle', name: '循环寿命模板', fields: ['容量保持率', '能量效率', '循环次数', '内阻变化'] }, |