140 lines
4.8 KiB
Vue
140 lines
4.8 KiB
Vue
<script setup>
|
||
const props = defineProps({
|
||
statsData: {
|
||
type: Object,
|
||
required: true
|
||
}
|
||
})
|
||
function generateTableData(data, config, showDetails = true) {
|
||
const headers = config.map(c => c.label)
|
||
const rows = []
|
||
|
||
for (const key in data) {
|
||
const entries = data[key]
|
||
|
||
if (!entries.length) continue
|
||
|
||
// Считаем итоговые значения
|
||
const totals = {}
|
||
config.forEach(c => {
|
||
if (c.total) {
|
||
totals[c.key] = entries.reduce((sum, entry) => {
|
||
const val = parseFloat(entry[c.key])
|
||
return sum + (isNaN(val) ? 0 : val)
|
||
}, 0)
|
||
}
|
||
})
|
||
|
||
// Основная строка
|
||
const mainRow = config.map(c => {
|
||
if (c.key === 'key') return key
|
||
if (c.key === 'count') return entries.length
|
||
if (c.total) return totals[c.key].toFixed(c.precision ?? 6)
|
||
return ''
|
||
})
|
||
|
||
// Добавляем флаг isSubRow: false для основной строки
|
||
mainRow.isSubRow = false
|
||
|
||
if (entries.length > 1) {
|
||
rows.push(mainRow)
|
||
}
|
||
|
||
// Подстроки
|
||
if (showDetails) {
|
||
let subRowIndex = 0
|
||
for (const entry of entries) {
|
||
const isOnlyOne = entries.length === 1
|
||
const isFirst = subRowIndex === 0
|
||
|
||
const subRow = config.map(c => {
|
||
if (c.key === 'key') {
|
||
return isOnlyOne ? key : '-'
|
||
}
|
||
if (c.key === 'count') {
|
||
return 1
|
||
}
|
||
const value = entry[c.key]
|
||
if (typeof value === 'number') {
|
||
return value.toFixed(c.precision ?? 6)
|
||
}
|
||
return value ?? '-'
|
||
})
|
||
|
||
// Добавляем служебные метки в подстроку
|
||
subRow.isSubRow = isOnlyOne ? false : true
|
||
subRow.isFirstSubRow = isFirst
|
||
subRow.indexSubRow = subRowIndex++
|
||
subRow.parentKey = key
|
||
|
||
rows.push(subRow)
|
||
}
|
||
}
|
||
}
|
||
|
||
return { headers, rows }
|
||
}
|
||
const standardTableData = computed(() => {
|
||
const standard = props.statsData?.Standard || {}
|
||
|
||
return generateTableData(standard, [
|
||
{ key: 'key', label: 'Название' },
|
||
{ key: 'count', label: 'Количество' }
|
||
], false)
|
||
})
|
||
const weldTableData = computed(() => {
|
||
const weld = props.statsData?.Weld || {}
|
||
|
||
return generateTableData(weld, [
|
||
{ key: 'key', label: 'Сварка' },
|
||
{ key: 'count', label: 'Элементов' },
|
||
{ key: 'length', label: 'Длина шва', total: true, precision: 6 }
|
||
])
|
||
})
|
||
const sheetTableData = computed(() => {
|
||
const sheet = props.statsData?.Sheet || {}
|
||
|
||
return generateTableData(sheet, [
|
||
{ key: 'key', label: 'Параметры листа' },
|
||
{ key: 'count', label: 'Количество' },
|
||
{ key: 'name', label: 'Имя детали' },
|
||
{ key: 'radius', label: 'Радиус гиба', precision: 1 },
|
||
// { key: 'folds', label: 'Количество гибов', precision: 0 },
|
||
{ key: 'area', label: 'Площадь (м²)', total: true, precision: 6 },
|
||
{ key: 'mass', label: 'Масса (кг)', total: true, precision: 6 }
|
||
])
|
||
})
|
||
const pipeTableData = computed(() => {
|
||
const pipe = props.statsData?.Pipe || {}
|
||
|
||
return generateTableData(pipe, [
|
||
{ key: 'key', label: 'Сечение' },
|
||
{ key: 'count', label: 'Элементов' },
|
||
{ key: 'key', label: 'Сечение' }, // дублируем для отображения в подстроках
|
||
{ key: 'length', label: 'Общая длина', total: true, precision: 6 }
|
||
])
|
||
})
|
||
</script>
|
||
<template>
|
||
|
||
<!-- === Листовой металл через TableItem === -->
|
||
<div v-if="sheetTableData.rows.length" class="mt-6">
|
||
<h3 class="text-lg font-semibold mb-2">Листовой металл</h3>
|
||
<TableItem v-bind="sheetTableData" />
|
||
</div>
|
||
|
||
<div v-if="weldTableData.rows.length" class="mt-6">
|
||
<h3 class="text-lg font-semibold mb-2">Сварочные швы</h3>
|
||
<TableItem v-bind="weldTableData" />
|
||
</div>
|
||
|
||
<div v-if="pipeTableData.rows.length" class="mt-6">
|
||
<h3 class="text-lg font-semibold mb-2">Трубы</h3>
|
||
<TableItem v-bind="pipeTableData" />
|
||
</div>
|
||
|
||
<div v-if="standardTableData.rows.length" class="mt-6">
|
||
<h3 class="text-lg font-semibold mb-2">Стандартные изделия</h3>
|
||
<TableItem v-bind="standardTableData" />
|
||
</div>
|
||
</template> |