SHA256
Упростить просмотр билетов второй и третьей очереди
This commit is contained in:
@@ -67,6 +67,18 @@ function formatQueuePrefix(queueId) {
|
||||
return 'Q1';
|
||||
}
|
||||
|
||||
function formatQueueTitle(queueId) {
|
||||
if (queueId === 2) return 'Вторая очередь';
|
||||
if (queueId === 3) return 'Третья очередь';
|
||||
return 'Первая очередь';
|
||||
}
|
||||
|
||||
function formatSupportTicketLabel(queueId, index) {
|
||||
const cleanIndex = BigInt(index || 0n).toString();
|
||||
if (queueId === 2 || queueId === 3) return `${queueId}/${cleanIndex}`;
|
||||
return cleanIndex;
|
||||
}
|
||||
|
||||
function formatUsdCentsText(cents) {
|
||||
const value = Number(cents || 0n) / 100;
|
||||
return value.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 2 });
|
||||
@@ -150,9 +162,9 @@ function parseSupportTicketInput(rawValue) {
|
||||
if (/^\d+$/.test(clean)) {
|
||||
return { queueId: 1, index: BigInt(clean) };
|
||||
}
|
||||
const match = clean.match(/^([123])(?:\s*[-_:\/#]+\s*|\s+)(\d+)$/);
|
||||
const match = clean.match(/^([23])\s*\/\s*(\d+)$/);
|
||||
if (!match) {
|
||||
throw new Error('Формат: для Q1 просто номер, для Q2/Q3 - например 2-15 или 3 8.');
|
||||
throw new Error('Формат: для первой очереди просто номер, для второй и третьей - например 2/7 или 3/8.');
|
||||
}
|
||||
return {
|
||||
queueId: Number(match[1]),
|
||||
@@ -266,8 +278,7 @@ export function render({ navigate }) {
|
||||
card.innerHTML = `
|
||||
<h2 style="margin:0;">Публичная очередь билета</h2>
|
||||
<p class="meta-muted" style="margin:0; line-height:1.55;">
|
||||
Для Q1 вводите просто номер билета. Для Q2 и Q3 укажите номер в формате <code>2-15</code> или <code>3 8</code>.
|
||||
Страница покажет состояние билета и сколько позиций осталось до выплаты.
|
||||
Введите номер билета.
|
||||
</p>
|
||||
`;
|
||||
|
||||
@@ -279,7 +290,7 @@ export function render({ navigate }) {
|
||||
const queryInput = document.createElement('input');
|
||||
queryInput.id = 'public-queue-ticket-query';
|
||||
queryInput.type = 'text';
|
||||
queryInput.placeholder = 'Например: 12, 2-5 или 3 8';
|
||||
queryInput.placeholder = 'Например: 12, 2/5 или 3/8';
|
||||
queryInput.autocomplete = 'off';
|
||||
queryInput.spellcheck = false;
|
||||
styleInputField(queryInput);
|
||||
@@ -334,9 +345,9 @@ export function render({ navigate }) {
|
||||
const ticketInfo = await core.connection.getAccountInfo(ticketPda, 'confirmed');
|
||||
if (!ticketInfo) {
|
||||
result.innerHTML = `
|
||||
<p class="meta-muted" style="margin:0;">Билет ${formatQueuePrefix(parsed.queueId)}-${parsed.index.toString()} пока не создан.</p>
|
||||
<p class="meta-muted" style="margin:0;">Билет ${formatSupportTicketLabel(parsed.queueId, parsed.index)} пока не создан.</p>
|
||||
`;
|
||||
status.textContent = `Билет ${formatQueuePrefix(parsed.queueId)}-${parsed.index.toString()} не найден.`;
|
||||
status.textContent = `Билет ${formatSupportTicketLabel(parsed.queueId, parsed.index)} не найден.`;
|
||||
return;
|
||||
}
|
||||
const ticket = parsePaymentsTicket(ticketInfo.data);
|
||||
@@ -344,18 +355,28 @@ export function render({ navigate }) {
|
||||
const ticketsBefore = parsed.index > 0n ? parsed.index - 1n : 0n;
|
||||
const paidBefore = queueState.ticketsPaid < ticketsBefore ? queueState.ticketsPaid : ticketsBefore;
|
||||
const remainingBefore = ticketsBefore > paidBefore ? ticketsBefore - paidBefore : 0n;
|
||||
result.innerHTML = `
|
||||
<div><b>Билет:</b> ${formatQueuePrefix(parsed.queueId)}-${ticket.index.toString()}</div>
|
||||
<div><b>Статус:</b> ${ticket.isPaid ? 'выплачен' : 'ожидает выплаты'}</div>
|
||||
<div><b>Получатель:</b> <span style="word-break:break-all;">${ticket.recipientWallet}</span></div>
|
||||
<div><b>До него в очереди:</b> ${ticketsBefore.toString()} билетов</div>
|
||||
<div><b>Из них уже выплачено:</b> ${paidBefore.toString()} билетов</div>
|
||||
<div><b>Ещё осталось до него:</b> ${remainingBefore.toString()} билетов</div>
|
||||
<div><b>Уже выплачено по сумме в очереди:</b> ${formatUsdCentsText(queueState.sumPaidUsdCents)} USD</div>
|
||||
<div><b>Сумма этого билета:</b> ${formatUsdCentsText(ticket.payoutUsdCents)} USD</div>
|
||||
<div><b>Накоплено до этого билета:</b> ${formatUsdCentsText(ticket.debtBeforeUsdCents)} USD в очереди до него</div>
|
||||
`;
|
||||
status.textContent = `Билет ${formatQueuePrefix(parsed.queueId)}-${ticket.index.toString()} найден. Источник Solana: ${endpoint}`;
|
||||
if (ticket.queueId === 2 || ticket.queueId === 3) {
|
||||
result.innerHTML = `
|
||||
<div>${formatQueueTitle(ticket.queueId)}</div>
|
||||
<div><b>Номер билета:</b> ${ticket.index.toString()}</div>
|
||||
<div><b>Статус:</b> ${ticket.isPaid ? 'выплачен' : 'ожидает выплаты'}</div>
|
||||
<div><b>Получатель:</b> <span style="word-break:break-all;">${ticket.recipientWallet}</span></div>
|
||||
<div><b>Сумма:</b> ${formatUsdCentsText(ticket.payoutUsdCents)} USD</div>
|
||||
`;
|
||||
} else {
|
||||
result.innerHTML = `
|
||||
<div><b>Билет:</b> ${formatSupportTicketLabel(parsed.queueId, ticket.index)}</div>
|
||||
<div><b>Статус:</b> ${ticket.isPaid ? 'выплачен' : 'ожидает выплаты'}</div>
|
||||
<div><b>Получатель:</b> <span style="word-break:break-all;">${ticket.recipientWallet}</span></div>
|
||||
<div><b>До него в очереди:</b> ${ticketsBefore.toString()} билетов</div>
|
||||
<div><b>Из них уже выплачено:</b> ${paidBefore.toString()} билетов</div>
|
||||
<div><b>Ещё осталось до него:</b> ${remainingBefore.toString()} билетов</div>
|
||||
<div><b>Уже выплачено по сумме в очереди:</b> ${formatUsdCentsText(queueState.sumPaidUsdCents)} USD</div>
|
||||
<div><b>Сумма этого билета:</b> ${formatUsdCentsText(ticket.payoutUsdCents)} USD</div>
|
||||
<div><b>Накоплено до этого билета:</b> ${formatUsdCentsText(ticket.debtBeforeUsdCents)} USD в очереди до него</div>
|
||||
`;
|
||||
}
|
||||
status.textContent = `Билет ${formatSupportTicketLabel(ticket.queueId, ticket.index)} найден. Источник Solana: ${endpoint}`;
|
||||
} catch (error) {
|
||||
result.innerHTML = `<p class="meta-muted" style="margin:0;">${String(error?.message || 'Не удалось загрузить билет')}</p>`;
|
||||
status.textContent = `Не удалось посмотреть билет: ${error?.message || 'unknown'}`;
|
||||
|
||||
@@ -200,6 +200,18 @@ function formatQueuePrefix(queueId) {
|
||||
return 'Q1';
|
||||
}
|
||||
|
||||
function formatQueueTitle(queueId) {
|
||||
if (queueId === 2) return 'Вторая очередь';
|
||||
if (queueId === 3) return 'Третья очередь';
|
||||
return 'Первая очередь';
|
||||
}
|
||||
|
||||
function formatSupportTicketLabel(queueId, index) {
|
||||
const cleanIndex = BigInt(index || 0n).toString();
|
||||
if (queueId === 2 || queueId === 3) return `${queueId}/${cleanIndex}`;
|
||||
return cleanIndex;
|
||||
}
|
||||
|
||||
function parsePaymentsCoef(data) {
|
||||
let offset = 0;
|
||||
const version = data[offset];
|
||||
@@ -276,9 +288,9 @@ function parseSupportTicketInput(rawValue) {
|
||||
if (/^\d+$/.test(clean)) {
|
||||
return { queueId: 1, index: BigInt(clean) };
|
||||
}
|
||||
const match = clean.match(/^([123])(?:\s*[-_:\/#]+\s*|\s+)(\d+)$/);
|
||||
const match = clean.match(/^([23])\s*\/\s*(\d+)$/);
|
||||
if (!match) {
|
||||
throw new Error('Формат: для Q1 просто номер, для Q2/Q3 - например 2-15 или 3 8.');
|
||||
throw new Error('Формат: для первой очереди просто номер, для второй и третьей - например 2/7 или 3/8.');
|
||||
}
|
||||
return {
|
||||
queueId: Number(match[1]),
|
||||
@@ -689,8 +701,7 @@ export function render({ navigate }) {
|
||||
card.innerHTML = `
|
||||
<h2 style="margin:0;">Посмотреть очередь билета</h2>
|
||||
<p class="meta-muted" style="margin:0; line-height:1.55;">
|
||||
Для Q1 вводите просто номер билета. Для Q2 и Q3 укажите номер в формате <code>2-15</code> или <code>3 8</code>.
|
||||
Экран покажет, сколько билетов перед ним уже стоит, сколько уже выплачено и кому принадлежит билет.
|
||||
Введите номер билета.
|
||||
</p>
|
||||
`;
|
||||
|
||||
@@ -702,7 +713,7 @@ export function render({ navigate }) {
|
||||
const queryInput = document.createElement('input');
|
||||
queryInput.id = 'support-ticket-query';
|
||||
queryInput.type = 'text';
|
||||
queryInput.placeholder = 'Например: 12, 2-5 или 3 8';
|
||||
queryInput.placeholder = 'Например: 12, 2/5 или 3/8';
|
||||
queryInput.autocomplete = 'off';
|
||||
queryInput.spellcheck = false;
|
||||
styleSupportInputField(queryInput);
|
||||
@@ -757,7 +768,7 @@ export function render({ navigate }) {
|
||||
const ticketInfo = await core.connection.getAccountInfo(ticketPda, 'confirmed');
|
||||
if (!ticketInfo) {
|
||||
result.innerHTML = `
|
||||
<p class="meta-muted" style="margin:0;">Билет ${formatQueuePrefix(parsed.queueId)}-${parsed.index.toString()} пока не создан.</p>
|
||||
<p class="meta-muted" style="margin:0;">Билет ${formatSupportTicketLabel(parsed.queueId, parsed.index)} пока не создан.</p>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
@@ -766,18 +777,28 @@ export function render({ navigate }) {
|
||||
const ticketsBefore = parsed.index > 0n ? parsed.index - 1n : 0n;
|
||||
const paidBefore = queueState.ticketsPaid < ticketsBefore ? queueState.ticketsPaid : ticketsBefore;
|
||||
const remainingBefore = ticketsBefore > paidBefore ? ticketsBefore - paidBefore : 0n;
|
||||
result.innerHTML = `
|
||||
<div><b>Билет:</b> ${formatQueuePrefix(parsed.queueId)}-${ticket.index.toString()}</div>
|
||||
<div><b>Статус:</b> ${ticket.isPaid ? 'выплачен' : 'ожидает выплаты'}</div>
|
||||
<div><b>Получатель:</b> <span style="word-break:break-all;">${ticket.recipientWallet}</span></div>
|
||||
<div><b>До него в очереди:</b> ${ticketsBefore.toString()} билетов</div>
|
||||
<div><b>Из них уже выплачено:</b> ${paidBefore.toString()} билетов</div>
|
||||
<div><b>Ещё осталось до него:</b> ${remainingBefore.toString()} билетов</div>
|
||||
<div><b>Уже выплачено по сумме в очереди:</b> ${formatUsdCentsText(queueState.sumPaidUsdCents)} USD</div>
|
||||
<div><b>Сумма этого билета:</b> ${formatUsdCentsText(ticket.payoutUsdCents)} USD</div>
|
||||
<div><b>Накоплено до этого билета:</b> ${formatUsdCentsText(ticket.debtBeforeUsdCents)} USD в очереди до него</div>
|
||||
`;
|
||||
setStatus(`Билет ${formatQueuePrefix(parsed.queueId)}-${ticket.index.toString()} найден. Источник Solana: ${endpoint}`);
|
||||
if (ticket.queueId === 2 || ticket.queueId === 3) {
|
||||
result.innerHTML = `
|
||||
<div>${formatQueueTitle(ticket.queueId)}</div>
|
||||
<div><b>Номер билета:</b> ${ticket.index.toString()}</div>
|
||||
<div><b>Статус:</b> ${ticket.isPaid ? 'выплачен' : 'ожидает выплаты'}</div>
|
||||
<div><b>Получатель:</b> <span style="word-break:break-all;">${ticket.recipientWallet}</span></div>
|
||||
<div><b>Сумма:</b> ${formatUsdCentsText(ticket.payoutUsdCents)} USD</div>
|
||||
`;
|
||||
} else {
|
||||
result.innerHTML = `
|
||||
<div><b>Билет:</b> ${formatSupportTicketLabel(parsed.queueId, ticket.index)}</div>
|
||||
<div><b>Статус:</b> ${ticket.isPaid ? 'выплачен' : 'ожидает выплаты'}</div>
|
||||
<div><b>Получатель:</b> <span style="word-break:break-all;">${ticket.recipientWallet}</span></div>
|
||||
<div><b>До него в очереди:</b> ${ticketsBefore.toString()} билетов</div>
|
||||
<div><b>Из них уже выплачено:</b> ${paidBefore.toString()} билетов</div>
|
||||
<div><b>Ещё осталось до него:</b> ${remainingBefore.toString()} билетов</div>
|
||||
<div><b>Уже выплачено по сумме в очереди:</b> ${formatUsdCentsText(queueState.sumPaidUsdCents)} USD</div>
|
||||
<div><b>Сумма этого билета:</b> ${formatUsdCentsText(ticket.payoutUsdCents)} USD</div>
|
||||
<div><b>Накоплено до этого билета:</b> ${formatUsdCentsText(ticket.debtBeforeUsdCents)} USD в очереди до него</div>
|
||||
`;
|
||||
}
|
||||
setStatus(`Билет ${formatSupportTicketLabel(ticket.queueId, ticket.index)} найден. Источник Solana: ${endpoint}`);
|
||||
} catch (error) {
|
||||
result.innerHTML = `<p class="meta-muted" style="margin:0;">${String(error?.message || 'Не удалось загрузить билет')}</p>`;
|
||||
setStatus(`Не удалось посмотреть билет: ${error?.message || 'unknown'}`);
|
||||
|
||||
Reference in New Issue
Block a user