bx-935-calc #1

Merged
ksenia_mikhailova merged 15 commits from bx-935-calc into main 2024-07-03 14:57:08 +03:00
4 changed files with 122 additions and 119 deletions
Showing only changes of commit 57cd6cd7c7 - Show all commits

View File

@ -4,6 +4,7 @@ import type { ralTypes } from '@/components/ral'
import { predefLamelleColors, predefPillarColors } from '~/composables/useCalc'; import { predefLamelleColors, predefPillarColors } from '~/composables/useCalc';
const lamelle_height = use_lamelle_height()
const lamelles_count = use_lamelles_count() const lamelles_count = use_lamelles_count()
const fence_section = use_fence_section() const fence_section = use_fence_section()
const remove_pillar = use_remove_pillar() const remove_pillar = use_remove_pillar()
@ -17,7 +18,7 @@ const min_length = use_min_length()
const parametric = reactive({ const parametric = reactive({
length: { length: {
min: min_length.value, min: min_length.value,
max: 2466, max: 2470,
step: 1, step: 1,
}, },
total_length: { total_length: {
@ -27,8 +28,8 @@ const parametric = reactive({
}, },
height: { height: {
min: 675, min: 675,
max: 2400, max: 2500,
step: 115, step: lamelle_height.value * 1000,
} }
}) })
const form_state = reactive({ const form_state = reactive({
@ -71,31 +72,38 @@ const changeParametres = () => {
} }
form_state.total_length_mm = form_state.total_length * 1000 form_state.total_length_mm = form_state.total_length * 1000
let { fence_length, total_length_mm, auto_length, length } = form_state let { fence_length, total_length_mm, auto_length, length, full_sections } = form_state
length = parseFloat(length.toString()) length = parseFloat(length.toString())
if (auto_length) { if (auto_length) {
let w = parametric.length.min let w = parametric.length.min
const max_sections = Math.ceil(total_length_mm / (parametric.length.min + fence_length)) const max_sections = Math.ceil((total_length_mm - fence_length) / (parametric.length.min + fence_length))
const min_sections = Math.ceil(total_length_mm / (parametric.length.max + 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++) { for (let index = min_sections; index <= max_sections; index++) {
full_sections = index
w = (total_length_mm - fence_length * (index - 1)) / index w = (total_length_mm - fence_length * (index - 1)) / index
if (w >= parametric.length.min && w <= parametric.length.max) { if (
w >= parametric.length.min
&& w <= parametric.length.max
&& w * index <= total_length_mm
) {
break break
} }
} }
form_state.length = w
length = w length = w
} }
form_state.full_sections = Math.floor((total_length_mm - fence_length) / (length + fence_length)) if (((full_sections * length) + (full_sections * fence_length) + fence_length) <= total_length_mm) {
if (((form_state.full_sections * length) + (form_state.full_sections * fence_length) + fence_length) !== total_length_mm) { form_state.extra_section = Math.floor((total_length_mm - fence_length) % length)
form_state.extra_section = Math.floor((total_length_mm - fence_length) % form_state.length)
} else { } else {
form_state.extra_section = 0 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 total_length.value = form_state.total_length
lamelles_count.value = lamelles lamelles_count.value = lamelles
fence_section.value = form_state.length * 0.001 fence_section.value = form_state.length * 0.001
@ -124,110 +132,102 @@ const plurals = {
</script> </script>
<template> <template>
<div class="container relative py-4"> <div class="container relative py-4">
<ClientOnly fallback-tag="div"> <form class="form">
<template #fallback> <div class="col-span-12 lg:col-span-6">
<div class="fallback"> <div class="form-row">
Загрузка 3D модели <div class="form-item w-full">
</div> <label for="length">Длина ламельного блока, мм</label>
</template> <input disabled :value="`${form_state.length} мм`" class="w-28" />
<form class="form"> <input id="length" type="range" class="w-full" v-bind="parametric.length"
<div class="col-span-12 lg:col-span-6"> v-model="form_state.length" :disabled="form_state.auto_length" :ref="form_refs.length" />
<div class="form-row"> </div>
<div class="form-item w-full"> <div class="form-item w-full">
<label for="length">Длина ламельного блока, мм</label> <label for="height">Высота забора, мм</label>
<input disabled :value="`${form_state.length} мм`" class="w-28" /> <input disabled :value="`${form_state.height} мм`" class="w-28" />
<input id="length" type="range" class="w-full" v-bind="parametric.length" <input id="height" type="range" class="w-full" v-bind="parametric.height"
v-model="form_state.length" :disabled="form_state.auto_length" v-model="form_state.height" :ref="form_refs.height" />
:ref="form_refs.length" /> </div>
</div> <div class="form-item">
<div class="form-item w-full"> <label for="total_length">Общая длина забора, м</label>
<label for="height">Высота забора, мм</label> <input type="number" id="total_length" v-bind="parametric.total_length"
<input disabled :value="`${form_state.height} мм`" class="w-28" /> v-model="form_state.total_length" :ref="form_refs.total_length" />
<input id="height" type="range" class="w-full" v-bind="parametric.height" </div>
v-model="form_state.height" :ref="form_refs.height" /> <div class="form-item form-item_checkbox">
</div> <input id="auto_length" type="checkbox" v-model="form_state.auto_length" />
<div class="form-item"> <label for="auto_length">Автоматический подбор секции</label>
<label for="total_length">Общая длина забора, м</label> </div>
<input type="number" id="total_length" v-bind="parametric.total_length" <div class="form-item form-item_checkbox">
v-model="form_state.total_length" :ref="form_refs.total_length" /> <input id="remove_pillar" type="checkbox" v-model="form_state.remove_pillar" />
</div> <label for="remove_pillar">Без столбов</label>
<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> </div>
<div class="col-span-12 lg:col-span-6"> </div>
<div class="form-row"> <div class="col-span-12 lg:col-span-6">
<div class="form-item"> <div class="form-row">
<label for="lamelle_color">Цвет ламелей</label> <div class="form-item">
<input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" <label for="lamelle_color">Цвет ламелей</label>
class="w-60" disabled /> <input id="lamelle_color" type="text" :value="getColorNameFromRal(lamelle_color)" class="w-60"
<ColorPicker :cb="setLamelleColor" /> disabled />
</div> <ColorPicker :cb="setLamelleColor" />
<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> <div class="form-item">
<div class="col-span-12 lg:col-span-8 prose min-w-full"> <template v-for="item in predefLamelleColors">
<p> <ColorPicker :color="item" :cb="setLamelleColor" :open="false"
Забор общей длиной {{ form_state.total_length }}{{ '\xa0' }}м, :active="lamelle_color == item" />
{{ section_count }}
<Plural :n="section_count" :forms="plurals.section" /> по
{{ `${parseInt(form_state.length).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> </template>
{{ section_count * lamelles_count }} </div>
<Plural :n="section_count * lamelles_count" :forms="plurals.lamelle" /> <div class="form-item">
{{ `длиной ${parseInt(form_state.length).toFixed(2)}\xa0мм` }}<template <label for="pillar_color">Цвет столба</label>
v-if="form_state.extra_section"> <input id="pillar_color" type="text" :value="getColorNameFromRal(pillar_color)" class="w-60"
{{ ` и ${~~(!!form_state.extra_section.toFixed(2)) * lamelles_count}` }} disabled />
<Plural :n="~~(!!form_state.extra_section) * lamelles_count" :forms="plurals.lamelle" /> <ColorPicker :cb="setPillarColor" />
{{ `длиной ${form_state.extra_section}\xa0мм` }} </div>
</template>. <div class="form-item">
</p> <template v-for="item in predefPillarColors">
<p> <ColorPicker :color="item" :cb="setPillarColor" :open="false"
Окрашивается по технологии порошковой окраски: <br /> :active="pillar_color == item" />
ламели: {{ getColorNameFromRal(lamelle_color)?.toLowerCase() }}; </template>
столбы: {{ getColorNameFromRal(pillar_color)?.toLowerCase() }}. </div>
</p>
</div> </div>
<div class="prose col-span-4"> </div>
<p v-if="form_state.extra_section" class="text-ioprim"> <div class="col-span-12 lg:col-span-8 prose min-w-full">
Внимание! Дополнительная секция приводит к увеличению стоимости. <p>
Рекомендуем вам изменить длину забора или длину секции! Забор общей длиной {{ form_state.total_length }}{{ '\xa0' }}м,
</p> {{ section_count }}
</div> <Plural :n="section_count" :forms="plurals.section" /> по
<div class="form-row justify-center"> {{ `${parseInt(form_state.length).toFixed(2)}\xa0мм` }}{{
<button @click.prevent="toggleModal">Рассчитать прямо сейчас</button> form_state.extra_section ? ` и 1 дополнительная секция
</div> длиной ${form_state.extra_section.toFixed(2)}\xa0мм` : '' }}.
</form> </p>
</ClientOnly> <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" />
{{ `длиной ${parseInt(form_state.length).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>
</div>
<div class="prose 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> </div>
</template> </template>

View File

@ -8,6 +8,7 @@ const { data: calculatorData } = await useFetch<ApiCalcType>(`${apiBase}/calcula
const isModalOpen = useState('modal_open', () => false) const isModalOpen = useState('modal_open', () => false)
const lamelle_height = useState<number>('lamelle_height')
const lamelles_count = useState<number>('lamelles_count') const lamelles_count = useState<number>('lamelles_count')
const fence_section = useState<number>('fence_section') const fence_section = useState<number>('fence_section')
const pillar_color = useState<ralTypes>('pillar_color') const pillar_color = useState<ralTypes>('pillar_color')
@ -115,11 +116,11 @@ const total_txt = computed(() => {
}); });
const prices = { const prices = {
pillar_length: discountValue * pillar, pillar: discountValue * ((pillar * lam_count * lamelle_height.value) + pillar_base),
pillar: discountValue * ((pillar * lam_count * 0.115) + pillar_base), lam_quad_regular: discountValue * lamelles_block * lam_count * lamelle_height.value * length_m,
lam_quad: discountValue * (lamelles_block * lam_count * 0.115), lam_quad_extra: discountValue * lamelles_block * lam_count * lamelle_height.value * extra_m,
} }
console.log(prices)
const extra = { const extra = {
pillar: !remove_pillar.value && { pillar: !remove_pillar.value && {
txt: `Дополнительная секция, столб, 1 шт`, txt: `Дополнительная секция, столб, 1 шт`,
@ -127,7 +128,7 @@ const total_txt = computed(() => {
}, },
lamella: { lamella: {
txt: `Блок ламелей с направляющей, 1 шт`, txt: `Блок ламелей с направляющей, 1 шт`,
value: prices.lam_quad * extra_m * 1 value: prices.lam_quad_extra * 1
}, },
} }
@ -138,7 +139,7 @@ const total_txt = computed(() => {
}, },
lamella: { lamella: {
txt: `Блок ламелей с направляющей, ${sections} шт`, txt: `Блок ламелей с направляющей, ${sections} шт`,
value: prices.lam_quad * length_m * sections value: prices.lam_quad_regular * sections
}, },
}; };

View File

@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { BufferGeometry, Color, Matrix4, Vector3 } from 'three'; import { BufferGeometry, Matrix4, Vector3 } from 'three';
const props = defineProps(['index', 'models']) const props = defineProps(['index', 'models'])
const lamelle_height = use_lamelle_height()
const lamelles_count = use_lamelles_count() const lamelles_count = use_lamelles_count()
const fence_section = use_fence_section() const fence_section = use_fence_section()
const section_count = use_section_count() const section_count = use_section_count()
@ -10,7 +11,7 @@ const extra_section = use_extra_section()
const remove_pillar = use_remove_pillar() const remove_pillar = use_remove_pillar()
const max_size = use_max_size() const max_size = use_max_size()
const lSize = 0.115 const lSize = lamelle_height.value
const bSize = 0.0235 const bSize = 0.0235
const pillar_size = 80 * 0.001 const pillar_size = 80 * 0.001

View File

@ -5,6 +5,7 @@ export const predefLamelleColors = ['3009', '9003', '6027', '5024', '9001', '101
const n = 2 const n = 2
const min = 1300 const min = 1300
export const use_lamelle_height = () => useState<number>('lamelle_height', () => 0.115)
export const use_lamelles_count = () => useState('lamelles_count', () => 14) export const use_lamelles_count = () => useState('lamelles_count', () => 14)
export const use_fence_section = () => useState<number>('fence_section', () => min * 0.001) export const use_fence_section = () => useState<number>('fence_section', () => min * 0.001)
export const use_remove_pillar = () => useState<boolean>('remove_pillar', () => false) export const use_remove_pillar = () => useState<boolean>('remove_pillar', () => false)