web/front/components/table/stats.vue

125 lines
4.1 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 ''
})
rows.push(mainRow)
// Подстроки (если нужно)
if (entries.length > 1 && showDetails) {
for (const entry of entries) {
const subRow = config.map(c => {
if (c.key === 'key') return ''
if (c.key === 'count') return 1
const value = entry[c.key]
if (typeof value === 'number') {
return value.toFixed(c.precision ?? 6)
}
return value ?? '-'
})
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: 'dummy', 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: '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>