Files
filam3d/frontend/src/components/PrintSettings.vue
2026-03-22 14:52:10 +03:00

125 lines
4.7 KiB
Vue

<template>
<div class="card">
<h2 class="mb-4 text-lg font-semibold text-gray-900">3. Параметры печати</h2>
<div class="space-y-5">
<!-- Infill -->
<div>
<div class="flex items-center justify-between mb-2">
<label class="text-sm font-medium text-gray-700" title="Больше заполнение — прочнее, но тяжелее и дороже">
Заполнение
</label>
<span class="text-sm font-semibold text-primary-600">{{ store.settings.infill_percent }}%</span>
</div>
<input
type="range"
:value="store.settings.infill_percent"
@input="store.settings.infill_percent = +$event.target.value"
min="10" max="100" step="5"
class="w-full accent-primary-600"
/>
<div class="mt-1 flex justify-between text-[10px] text-gray-400">
<span>10%</span><span>50%</span><span>100%</span>
</div>
</div>
<!-- Layer height -->
<div>
<div class="flex items-center justify-between mb-2">
<label class="text-sm font-medium text-gray-700" title="Меньше слой — лучше качество, но дольше печать">
Высота слоя
</label>
<span class="text-sm font-semibold text-primary-600">{{ store.settings.layer_height_mm }} мм</span>
</div>
<input
type="range"
:value="store.settings.layer_height_mm"
@input="store.settings.layer_height_mm = +parseFloat($event.target.value).toFixed(2)"
min="0.08" max="0.4" step="0.04"
class="w-full accent-primary-600"
/>
<div class="mt-1 flex justify-between text-[10px] text-gray-400">
<span>0.08</span><span>0.2</span><span>0.4</span>
</div>
</div>
<!-- Quantity -->
<div>
<label class="mb-2 block text-sm font-medium text-gray-700">Количество</label>
<input
type="number"
:value="store.settings.quantity"
@input="store.settings.quantity = Math.max(1, Math.min(500, +$event.target.value || 1))"
min="1" max="500"
class="input-field w-28"
/>
</div>
<!-- Multicolor -->
<div>
<label class="flex items-center gap-3 cursor-pointer rounded-lg border-2 p-3 transition-all"
:class="store.multicolor ? 'border-primary-500 bg-primary-50' : 'border-gray-200 hover:border-gray-300'"
>
<input
type="checkbox"
:checked="store.multicolor"
@change="toggleMulticolor"
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
/>
<div>
<span class="text-sm font-medium text-gray-900">Многоцветная печать</span>
<span class="ml-2 text-xs text-gray-400">(AMS, +30% к стоимости)</span>
<p class="text-xs text-gray-500 mt-0.5">Печать несколькими цветами на Bambu Lab AMS</p>
</div>
</label>
</div>
<!-- Post-processing -->
<div>
<label class="mb-2.5 block text-sm font-medium text-gray-700">Постобработка</label>
<div class="space-y-2">
<label v-for="pp in postProcessingOptions" :key="pp.value" class="flex items-center gap-2.5 cursor-pointer">
<input
type="checkbox"
:value="pp.value"
:checked="store.settings.post_processing.includes(pp.value)"
@change="togglePP(pp.value)"
class="h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
/>
<span class="text-sm text-gray-700">{{ pp.label }}</span>
<span class="text-xs text-gray-400">{{ pp.price }}</span>
</label>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { useCalculatorStore } from '../stores/calculator'
const store = useCalculatorStore()
const postProcessingOptions = [
{ value: 'sanding', label: 'Шлифовка', price: '300 ₽/шт' },
{ value: 'painting', label: 'Покраска', price: '500 ₽/шт' },
{ value: 'threading', label: 'Нарезка резьбы', price: '200 ₽/шт' },
{ value: 'acetone_smoothing', label: 'Ацетоновая обработка (ABS)', price: '400 ₽/шт' },
]
function toggleMulticolor() {
store.multicolor = !store.multicolor
store.result = null
}
function togglePP(value) {
const idx = store.settings.post_processing.indexOf(value)
if (idx > -1) {
store.settings.post_processing.splice(idx, 1)
} else {
store.settings.post_processing.push(value)
}
store.result = null
}
</script>