mns-mini-zabor/components/calcValues.vue

248 lines
11 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 lang="ts">
import { getColorNameFromRal } from '@/components/ral'
import type { ralTypes } from '@/components/ral'
import { predefLamelleColors, predefPillarColors } from '~/composables/useCalc';
const lamelle_height = use_lamelle_height()
const lamelles_count = use_lamelles_count()
const fence_section = use_fence_section()
const remove_pillar = use_remove_pillar()
const pillar_color = use_pillar_color()
const lamelle_color = use_lamelle_color()
const section_count = use_section_count()
const extra_section = use_extra_section()
const total_length = use_total_length()
const min_length = use_min_length()
const parametric = reactive({
length: {
min: min_length.value,
max: 2470,
step: 1,
},
total_length: {
min: min_length.value * 0.001,
max: undefined,
step: 0.5,
},
height: {
min: 20 + lamelle_height.value * 1000 * 5,
max: 20 + lamelle_height.value * 1000 * 20,
step: lamelle_height.value * 1000,
}
})
const form_state = reactive({
length: fence_section.value * 1000,
fence_length: 104,
height: 100 + lamelles_count.value * parametric.height.step,
total_length: total_length.value,
total_length_mm: fence_section.value * 1000,
full_sections: section_count.value,
extra_section: 0,
auto_length: true,
remove_pillar: false
})
const form_refs = {
length: ref(),
height: ref(),
total_length: ref(),
}
const changeParametres = () => {
if (form_state.total_length * 1000 < parametric.length.min) {
return
}
const lamelles = Math.floor(form_state.height / parametric.height.step)
for (const key in form_state) {
if (parametric.hasOwnProperty(key)) {
const key_p = key as keyof typeof parametric
const key_s = key as keyof typeof form_state
if (parametric[key_p].max) {
if (form_state[key_s] > parametric[key_p].max) {
form_state[key_s] = parametric[key_p].max
}
}
}
}
if (form_state.total_length_mm < form_state.length) {
form_state.length = form_state.total_length_mm
}
form_state.total_length_mm = form_state.total_length * 1000
let { fence_length, total_length_mm, auto_length, length, full_sections } = form_state
length = parseFloat(length.toString())
if (auto_length) {
let w = parametric.length.min
const max_sections = Math.floor((total_length_mm - fence_length) / (parametric.length.min + fence_length))
const min_sections = Math.ceil((total_length_mm - fence_length) / (parametric.length.max + fence_length))
for (let index = min_sections; index <= max_sections; index++) {
full_sections = index
w = (total_length_mm - fence_length * (index - 1)) / index
if (
w >= parametric.length.min
&& w <= parametric.length.max
&& w * index <= total_length_mm
) {
break
}
}
length = w
} else {
full_sections = Math.floor((total_length_mm - fence_length) / (length + fence_length))
if (full_sections == 0) {
length = total_length_mm - fence_length - fence_length
}
}
if (((full_sections * length) + (full_sections * fence_length) + fence_length) <= total_length_mm) {
form_state.extra_section = Math.floor((total_length_mm - fence_length) % length)
} else {
form_state.extra_section = 0
}
form_state.full_sections = full_sections
form_state.length = length
form_state.fence_length = fence_length
total_length.value = form_state.total_length
lamelles_count.value = lamelles
fence_section.value = form_state.length * 0.001
section_count.value = form_state.full_sections
extra_section.value = form_state.extra_section
remove_pillar.value = form_state.remove_pillar
goal('calc_fence', form_state)
}
const setLamelleColor = (color: ralTypes) => {
lamelle_color.value = color
}
const setPillarColor = (color: ralTypes) => {
pillar_color.value = color
}
watch(form_state, changeParametres, { deep: true })
const isModalOpen = useState('modal_open', () => false)
const toggleModal = () => {
isModalOpen.value = !isModalOpen.value
}
const plurals = {
lamelle: { one: 'ламель', few: 'ламели', many: 'ламелей' },
fence: { one: 'cтолб', few: 'столба', many: 'столбов' },
section: { one: 'секция', few: 'секции', many: 'секций' },
}
const goal = (target: string, params: object) => {
const nuxtApp = useNuxtApp()
if (nuxtApp.$metrika) {
nuxtApp.$metrika.reachGoal(target, params || {})
}
}
</script>
<template>
<div class="container relative py-4">
<form class="form">
<div class="col-span-12 lg:col-span-6">
<div class="form-row">
<div class="form-item w-full">
<label for="length">Длина ламельного блока, мм</label>
<input disabled :value="`${form_state.length} мм`" class="w-28" />
<input id="length" type="range" class="w-full" v-bind="parametric.length"
v-model="form_state.length" :disabled="form_state.auto_length" :ref="form_refs.length" />
</div>
<div class="form-item w-full">
<label for="height">Высота забора, мм</label>
<input disabled :value="`${form_state.height} мм`" class="w-28" />
<input id="height" type="range" class="w-full" v-bind="parametric.height"
v-model="form_state.height" :ref="form_refs.height" />
</div>
<div class="form-item">
<label for="total_length">Общая длина забора, м</label>
<input type="number" id="total_length" v-bind="parametric.total_length"
v-model="form_state.total_length" :ref="form_refs.total_length" />
</div>
<div class="form-item form-item_checkbox">
<input id="auto_length" type="checkbox" v-model="form_state.auto_length" />
<label for="auto_length">Автоматический подбор секции</label>
</div>
<div class="form-item form-item_checkbox">
<input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
<label for="remove_pillar">Без столбов</label>
</div>
</div>
</div>
<div class="col-span-12 lg:col-span-6">
<div class="form-row">
<div class="form-item">
<label for="lamelle_color">Цвет ламелей</label>
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
disabled />
<ColorPicker :cb="setLamelleColor" />
</div>
<div class="form-item">
<template v-for="item in predefLamelleColors">
<ColorPicker :color="item" :cb="setLamelleColor" :open="false"
:active="lamelle_color == item" />
</template>
</div>
<div class="form-item">
<label for="pillar_color">Цвет столба</label>
<input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" class="w-60"
disabled />
<ColorPicker :cb="setPillarColor" />
</div>
<div class="form-item">
<template v-for="item in predefPillarColors">
<ColorPicker :color="item" :cb="setPillarColor" :open="false"
:active="pillar_color == item" />
</template>
</div>
</div>
</div>
<div class="col-span-12 lg:col-span-8 prose min-w-full">
<template v-if="(form_state.total_length * 1000) >= parametric.length.min">
<p>
Забор общей длиной {{ form_state.total_length }}{{ '\xa0' }}м,
{{ section_count }}
<Plural :n="section_count" :forms="plurals.section" /> по
{{ `${parseFloat(form_state.length.toString()).toFixed(2)}\xa0мм` }}{{
form_state.extra_section ? ` и 1 дополнительная секция
длиной ${form_state.extra_section.toFixed(2)}\xa0мм` : '' }}.
</p>
<p v-if="parametric.length.min <= form_state.total_length * 1000">
Всего <template v-if="!form_state.remove_pillar">
{{ section_count + ~~(!!form_state.extra_section) + 1 }}
<Plural :forms="plurals.fence" :n="section_count + ~~(!!form_state.extra_section) + 1" />,
</template>
{{ section_count * lamelles_count }}
<Plural :n="section_count * lamelles_count" :forms="plurals.lamelle" />
{{ `длиной ${parseFloat(form_state.length.toString()).toFixed(2)}\xa0мм` }}<template
v-if="form_state.extra_section">
{{ ` и ${~~(!!form_state.extra_section.toFixed(2)) * lamelles_count}` }}
<Plural :n="~~(!!form_state.extra_section) * lamelles_count" :forms="plurals.lamelle" />
{{ `длиной ${form_state.extra_section}\xa0мм` }}
</template>.
</p>
<p>
Окрашивается по технологии порошковой окраски: <br />
ламели: {{ getColorNameFromRal(lamelle_color)?.toLowerCase() }};
столбы: {{ getColorNameFromRal(pillar_color)?.toLowerCase() }}.
</p>
</template>
</div>
<div class="prose col-span-12 lg:col-span-4">
<p v-if="form_state.extra_section" class="text-ioprim">
Внимание! Дополнительная секция приводит к увеличению стоимости.
Рекомендуем вам изменить длину забора или длину секции!
</p>
</div>
<div class="form-row justify-center">
<button @click.prevent="toggleModal">Рассчитать прямо сейчас</button>
</div>
</form>
</div>
</template>