Тарифы
This commit is contained in:
@ -33,7 +33,6 @@
|
|||||||
let isPrinting = $state(false);
|
let isPrinting = $state(false);
|
||||||
|
|
||||||
let uid = 0;
|
let uid = 0;
|
||||||
const PRICE_PER_PAGE = 9;
|
|
||||||
|
|
||||||
const qualities = [
|
const qualities = [
|
||||||
{ id: 'low', label: 'Эконом' },
|
{ id: 'low', label: 'Эконом' },
|
||||||
@ -46,6 +45,13 @@
|
|||||||
{ id: 'color', label: 'Цвет' }
|
{ id: 'color', label: 'Цвет' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// ── Тарифная сетка ──
|
||||||
|
function getPricePerPage(pagesCount) {
|
||||||
|
if (pagesCount >= 1000) return 4;
|
||||||
|
if (pagesCount >= 25) return 9;
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
// ── Вспомогательная функция для реактивного обновления ──
|
// ── Вспомогательная функция для реактивного обновления ──
|
||||||
function updateFile(id, changes) {
|
function updateFile(id, changes) {
|
||||||
files = files.map(f => f.id === id ? { ...f, ...changes } : f);
|
files = files.map(f => f.id === id ? { ...f, ...changes } : f);
|
||||||
@ -300,14 +306,17 @@
|
|||||||
function qualityFillFor(file) { return Math.round((file.qualityIndex / (qualities.length - 1)) * 100); }
|
function qualityFillFor(file) { return Math.round((file.qualityIndex / (qualities.length - 1)) * 100); }
|
||||||
function updateQuality(file, val) { updateFile(file.id, { qualityIndex: val }); }
|
function updateQuality(file, val) { updateFile(file.id, { qualityIndex: val }); }
|
||||||
|
|
||||||
// ── Расчет цены ──
|
// ── Расчет цены (ОБНОВЛЕННАЯ ЛОГИКА) ──
|
||||||
const totalPrice = $derived(() => {
|
const totalPrice = $derived(() => {
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
for (const f of files) {
|
for (const f of files) {
|
||||||
const pagesCount = f.selectedPages ? f.selectedPages.size : 0;
|
const pagesCount = f.selectedPages ? f.selectedPages.size : 0;
|
||||||
sum += pagesCount * f.copies;
|
if (pagesCount > 0) {
|
||||||
|
const pricePerPage = getPricePerPage(pagesCount);
|
||||||
|
sum += pagesCount * f.copies * pricePerPage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sum * PRICE_PER_PAGE;
|
return sum;
|
||||||
});
|
});
|
||||||
|
|
||||||
const extraCopies = $derived(files.reduce((sum, f) => sum + (f.copies - 1), 0));
|
const extraCopies = $derived(files.reduce((sum, f) => sum + (f.copies - 1), 0));
|
||||||
@ -484,6 +493,14 @@
|
|||||||
{#if extraCopies > 0}, {extraCopies} {plCopies(extraCopies)}{/if}
|
{#if extraCopies > 0}, {extraCopies} {plCopies(extraCopies)}{/if}
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<!-- РАСЦЕНКА МАЛЕНЬКИМ ПРОЗРАЧНЫМ ШРИФТОМ -->
|
||||||
|
<div class="pricing-info">
|
||||||
|
<span class="price-tier" class:active={files.some(f => (f.selectedPages?.size || 0) < 25)}>10р/л от 1</span>
|
||||||
|
<span class="price-tier" class:active={files.some(f => { const s = f.selectedPages?.size || 0; return s >= 25 && s < 1000; })}>9р/л от 25</span>
|
||||||
|
<span class="price-tier" class:active={files.some(f => (f.selectedPages?.size || 0) >= 1000)}>4р/л от 1000</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="price-summary">
|
<div class="price-summary">
|
||||||
<span class="summary-itogo">Итого</span>
|
<span class="summary-itogo">Итого</span>
|
||||||
<span class="summary-price">{totalPrice()}₽</span>
|
<span class="summary-price">{totalPrice()}₽</span>
|
||||||
@ -607,6 +624,26 @@
|
|||||||
.action-btn:disabled { opacity: 0.6; cursor: wait; }
|
.action-btn:disabled { opacity: 0.6; cursor: wait; }
|
||||||
.action-btn.primary { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); box-shadow: 0 8px 24px -6px rgba(99, 102, 241, 0.5); }
|
.action-btn.primary { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); box-shadow: 0 8px 24px -6px rgba(99, 102, 241, 0.5); }
|
||||||
.action-btn.secondary { background: linear-gradient(135deg, #5b8cff 0%, #38c6ff 100%); box-shadow: 0 8px 24px -6px rgba(72, 150, 255, 0.4); }
|
.action-btn.secondary { background: linear-gradient(135deg, #5b8cff 0%, #38c6ff 100%); box-shadow: 0 8px 24px -6px rgba(72, 150, 255, 0.4); }
|
||||||
|
|
||||||
|
/* ── Стили расценки ── */
|
||||||
|
.pricing-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1.2;
|
||||||
|
color: rgba(255, 255, 255, 0.25);
|
||||||
|
margin-bottom: 4px;
|
||||||
|
user-select: none;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.price-tier {
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
}
|
||||||
|
.price-tier.active {
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
.price-summary { display: flex; justify-content: space-between; align-items: baseline; width: 100%; }
|
.price-summary { display: flex; justify-content: space-between; align-items: baseline; width: 100%; }
|
||||||
.summary-itogo { font-size: 30px; font-weight: 700; color: #8b93a1; }
|
.summary-itogo { font-size: 30px; font-weight: 700; color: #8b93a1; }
|
||||||
.summary-price { font-size: 38px; font-weight: 800; color: #fff; }
|
.summary-price { font-size: 38px; font-weight: 800; color: #fff; }
|
||||||
|
|||||||
11
update_nvm.sh
Executable file
11
update_nvm.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Загружаем nvm
|
||||||
|
export NVM_DIR="$HOME/.nvm"
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||||
|
|
||||||
|
# Устанавливаем LTS версию Node.js
|
||||||
|
nvm install --lts
|
||||||
|
|
||||||
|
# Обновляем npm до последней версии
|
||||||
|
npm install -g npm@latest
|
||||||
Reference in New Issue
Block a user