web/front/components/table/stats.vue

140 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>