init
This commit is contained in:
80
frontend/src/components/PriceResult.vue
Normal file
80
frontend/src/components/PriceResult.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="card" v-if="result">
|
||||
<h2 class="mb-4 text-lg font-semibold text-gray-900">Результат расчёта</h2>
|
||||
|
||||
<!-- File info -->
|
||||
<div class="mb-4 rounded-lg bg-gray-50 p-3.5">
|
||||
<p class="text-xs font-semibold uppercase tracking-wider text-gray-500 mb-2">Модель</p>
|
||||
<div class="grid grid-cols-2 gap-2 text-sm">
|
||||
<div><span class="text-gray-500">Файл:</span> {{ result.file_info.filename }}</div>
|
||||
<div><span class="text-gray-500">Объём:</span> {{ result.file_info.volume_cm3 }} см³</div>
|
||||
<div><span class="text-gray-500">Габариты:</span> {{ bbox }}</div>
|
||||
<div>
|
||||
<span class="text-gray-500">Водонепр.:</span>
|
||||
<span :class="result.file_info.is_watertight ? 'text-green-600' : 'text-amber-600'">
|
||||
{{ result.file_info.is_watertight ? 'Да' : 'Нет' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Price breakdown -->
|
||||
<div class="space-y-2.5 mb-4">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-gray-600">Материал ({{ result.calculation.material.name }}, {{ result.calculation.weight_grams }} г)</span>
|
||||
<span class="font-medium">{{ fmt(result.calculation.material_cost_rub) }} ₽</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm">
|
||||
<span class="text-gray-600">Время печати (~{{ result.calculation.print_time_hours }} ч)</span>
|
||||
<span class="font-medium">{{ fmt(result.calculation.time_cost_rub) }} ₽</span>
|
||||
</div>
|
||||
<div v-if="result.calculation.post_processing_cost_rub > 0" class="flex justify-between text-sm">
|
||||
<span class="text-gray-600">Постобработка</span>
|
||||
<span class="font-medium">{{ fmt(result.calculation.post_processing_cost_rub) }} ₽</span>
|
||||
</div>
|
||||
<div class="flex justify-between text-sm border-t border-gray-100 pt-2.5">
|
||||
<span class="text-gray-600">Подитог (1 шт)</span>
|
||||
<span class="font-medium">{{ fmt(result.calculation.subtotal_rub) }} ₽</span>
|
||||
</div>
|
||||
<div v-if="result.calculation.quantity > 1" class="flex justify-between text-sm">
|
||||
<span class="text-gray-600">Количество: {{ result.calculation.quantity }} шт</span>
|
||||
<span v-if="result.calculation.quantity_discount_percent" class="text-green-600 font-medium">
|
||||
-{{ result.calculation.quantity_discount_percent }}% скидка
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total -->
|
||||
<div class="rounded-lg bg-primary-50 p-4 mb-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-sm font-medium text-primary-700">Итого</p>
|
||||
<p class="text-xs text-primary-600">Срок: ~{{ result.calculation.estimated_days }} рабочих дней</p>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-primary-700">{{ fmt(result.calculation.total_rub) }} ₽</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<router-link :to="`/order/${result.calculation_id}`" class="btn-primary w-full text-center block">
|
||||
Оформить заказ
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useCalculatorStore } from '../stores/calculator'
|
||||
|
||||
const store = useCalculatorStore()
|
||||
const result = computed(() => store.result)
|
||||
|
||||
const bbox = computed(() => {
|
||||
if (!result.value) return ''
|
||||
const b = result.value.file_info.bounding_box_mm
|
||||
return `${b.x} x ${b.y} x ${b.z} мм`
|
||||
})
|
||||
|
||||
function fmt(n) {
|
||||
return new Intl.NumberFormat('ru-RU', { maximumFractionDigits: 0 }).format(n)
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user