| | |
| | | const cycleNos = ref<number[]>([]) |
| | | const fields = ref<FormationField[]>(structuredClone(defaultFormationFields)) |
| | | const values = ref<Record<string, string>>({}) |
| | | const chargeStepSelections = ref<Record<string, number>>({}) |
| | | const detailFields = computed(() => fields.value.filter(field => field.scope === 'detail')) |
| | | const cycleFields = computed(() => fields.value.filter(field => field.scope === 'cycle')) |
| | | const reportColumns = computed(() => [...new Set(items.value.map(item => item.source.selection.testId))].map(id => ({ |
| | |
| | | function setValue(item: FormationItem, cycle: number, field: FormationField, value: string) { |
| | | values.value[formationValueKey(item, cycle, field)] = value |
| | | } |
| | | function formContent() { return JSON.stringify({ name: reportName.value, description: description.value, fields: fields.value, values: values.value }) } |
| | | function chargeChoices(item: FormationItem, cycle: number) { return item.chargeSteps?.[String(cycle)] || [] } |
| | | function chargeChoice(item: FormationItem, cycle: number) { |
| | | const choices = chargeChoices(item, cycle) |
| | | const reliable = choices.filter(step => ['cc', 'charge', 'charging'].includes((step.stepType || '').toLowerCase())) |
| | | return reliable.length === 1 ? reliable[0] : choices.find(step => step.stepNo === chargeStepSelections.value[`${item.source.selection.testId}|${item.source.selection.testBatteryId}|${cycle}`]) |
| | | } |
| | | function chargeKey(item: FormationItem, cycle: number) { return `${item.source.selection.testId}|${item.source.selection.testBatteryId}|${cycle}` } |
| | | function formContent() { return JSON.stringify({ name: reportName.value, description: description.value, fields: fields.value, values: values.value, chargeStepSelections: chargeStepSelections.value }) } |
| | | function restore(record: SavedFormationReport) { |
| | | saved.value = record; reportName.value = record.name; description.value = record.description || '' |
| | | items.value = record.items; cycleNos.value = record.cycleNos |
| | | fields.value = record.settings.fields; values.value = record.settings.values |
| | | fields.value = record.settings.fields; values.value = record.settings.values; chargeStepSelections.value = record.settings.chargeStepSelections || {} |
| | | changeSummary.value = ''; savedContent.value = formContent() |
| | | } |
| | | function pruneValues() { |
| | |
| | | saving.value = true |
| | | try { |
| | | pruneValues() |
| | | const content = { name: reportName.value.trim(), description: description.value, settings: { fields: fields.value, values: values.value } } |
| | | const content = { name: reportName.value.trim(), description: description.value, settings: { fields: fields.value, values: values.value, chargeStepSelections: chargeStepSelections.value } } |
| | | const result = editingId.value && saved.value |
| | | ? await editFormationReport(editingId.value, { ...content, baseVersionNo: saved.value.versionNo, changeSummary: changeSummary.value.trim() }) |
| | | : await createFormationReport({ ...content, selections: items.value.map(item => item.source.selection) }) |
| | |
| | | if (sequence !== previewSequence) return |
| | | items.value = result.items |
| | | cycleNos.value = result.cycleNos |
| | | for (const item of items.value) for (const cycle of item.cycleNos) { |
| | | const key = `${item.source.selection.testId}|${item.source.selection.testBatteryId}|${cycle}` |
| | | const choices = item.chargeSteps?.[String(cycle)] || [] |
| | | const reliable = choices.filter(step => ['cc', 'charge', 'charging'].includes((step.stepType || '').toLowerCase())) |
| | | if (reliable.length === 1) chargeStepSelections.value[key] = reliable[0].stepNo |
| | | } |
| | | fields.value = fields.value.map(field => field.kind === 'battery' && field.fieldDefinitionId == null |
| | | ? { ...field, fieldDefinitionId: items.value.flatMap(item => item.businessFields).find(value => value.fieldName === field.key)?.fieldDefinitionId ?? null } : field) |
| | | pruneValues() |
| | |
| | | async function load() { |
| | | loading.value = true; loadError.value = '' |
| | | previewSequence++; previewLoading.value = false; previewError.value = '' |
| | | saved.value = null; items.value = []; cycleNos.value = []; values.value = {}; selectedKeys.value = [] |
| | | saved.value = null; items.value = []; cycleNos.value = []; values.value = {}; chargeStepSelections.value = {}; selectedKeys.value = [] |
| | | try { |
| | | const permissions = (await getUserInfo()).permissions || [] |
| | | const has = (action: string) => permissions.includes('*:*:*') || permissions.includes(`system:formation-report:${action}`) |
| | | canCreate.value = has('add'); canEdit.value = has('edit'); canQuery.value = has('query') |
| | | if (!editingId.value) { |
| | | if (!canCreate.value) throw new Error('无新增化成报表权限') |
| | | reportName.value = ''; description.value = ''; fields.value = structuredClone(defaultFormationFields) |
| | | reportName.value = ''; description.value = ''; fields.value = structuredClone(defaultFormationFields); chargeStepSelections.value = {} |
| | | candidates.value = await getFormationSources() |
| | | } else { |
| | | const editing = route.query.mode === 'edit' && !route.query.version |
| | |
| | | <div class="cycle-table-wrap"><table class="cycle-table cycle-data-table" :style="tableStyle"> |
| | | <thead><tr><th>测试</th><th v-for="column in reportColumns" :key="column.id" :colspan="column.items.length">{{ column.name }}</th></tr> |
| | | <tr><th>指标</th><th v-for="item in reportItems" :key="selectionKey(item.source)">{{ item.source.batteryGroup }} / {{ item.source.batteryNo }}</th></tr></thead> |
| | | <tbody><tr v-for="field in cycleFields" :key="field.key"><td>{{ formationFieldLabel(field) }}</td><td v-for="item in reportItems" :key="selectionKey(item.source)"> |
| | | <tbody><tr><td>充电工步号</td><td v-for="item in reportItems" :key="selectionKey(item.source)"><template v-if="item.cycleNos.includes(cycle)"><el-select v-if="chargeChoices(item, cycle).length && !chargeChoice(item, cycle)" :model-value="chargeStepSelections[chargeKey(item, cycle)]" :disabled="readonly" placeholder="选择工步" size="small" @update:model-value="chargeStepSelections[chargeKey(item, cycle)] = $event"><el-option v-for="step in chargeChoices(item, cycle)" :key="step.stepNo" :label="`${step.stepNo} ${step.name || ''}`" :value="step.stepNo" /></el-select><span v-else>{{ chargeChoice(item, cycle)?.stepNo ?? '未识别' }}</span></template><span v-else class="missing-cycle">无该循环</span></td></tr> |
| | | <tr><td>充电工步名称</td><td v-for="item in reportItems" :key="selectionKey(item.source)"><span v-if="!item.cycleNos.includes(cycle)" class="missing-cycle">无该循环</span><span v-else>{{ chargeChoice(item, cycle)?.name || '未选择' }}</span></td></tr> |
| | | <tr><td>终止电压 (V)</td><td v-for="item in reportItems" :key="selectionKey(item.source)"><span v-if="!item.cycleNos.includes(cycle)" class="missing-cycle">无该循环</span><span v-else>{{ chargeChoice(item, cycle)?.endVoltage ?? '缺失' }}</span></td></tr> |
| | | <tr v-for="field in cycleFields" :key="field.key"><td>{{ formationFieldLabel(field) }}</td><td v-for="item in reportItems" :key="selectionKey(item.source)"> |
| | | <span v-if="!item.cycleNos.includes(cycle)" class="missing-cycle">无该循环</span> |
| | | <el-input v-else :model-value="inputValue(item, cycle, field)" @update:model-value="setValue(item, cycle, field, $event)" :disabled="readonly" :aria-label="`${item.source.name} ${item.source.batteryNo} 循环${cycle} ${field.displayName}`" :placeholder="field.kind === 'manual' ? '人工填写' : '指标缺失'" size="small" /> |
| | | </td></tr></tbody> |