/* global $, window, document, showAlert, showConfirm, showQRCodeModal */ $(document).ready(function() { const adminLink = window.location.pathname.split('/').pop(); let questionnaireData = null; // Функция для получения базового пути API const getApiPath = () => { // Проверяем, содержит ли путь /ms/ (продакшн на dev.bro-js.ru) const pathname = window.location.pathname; const isMsPath = pathname.includes('/ms/questioneer'); if (isMsPath) { // Для продакшна: если в пути есть /ms/, то API доступно по /ms/questioneer/api return '/ms/questioneer/api'; } else { // Для локальной разработки: формируем путь к API без учета текущей страницы // Извлекаем базовый путь из URL страницы до /admin/[adminLink] const basePath = pathname.split('/admin')[0]; // Путь до API приложения return basePath + '/api'; } }; // Загрузка данных опроса const loadQuestionnaire = () => { $.ajax({ url: `${getApiPath()}/questionnaires/admin/${adminLink}`, method: 'GET', success: function(result) { if (result.success) { questionnaireData = result.data; renderQuestionnaire(); } else { $('#loading').text(`Ошибка: ${result.error}`); } }, error: function(error) { console.error('Error loading questionnaire:', error); $('#loading').text('Не удалось загрузить опрос. Пожалуйста, попробуйте позже.'); } }); }; // Отображение данных опроса const renderQuestionnaire = () => { // Заполняем основные данные $('#questionnaire-title').text(questionnaireData.title); $('#questionnaire-description').text(questionnaireData.description || 'Нет описания'); // Формируем ссылки const baseUrl = window.location.origin; const isMsPath = window.location.pathname.includes('/ms/questioneer'); let baseQuestionnairePath; if (isMsPath) { // Для продакшна: используем /ms/questioneer baseQuestionnairePath = '/ms/questioneer'; } else { // Для локальной разработки: используем текущий путь baseQuestionnairePath = window.location.pathname.split('/admin')[0]; } const publicUrl = `${baseUrl}${baseQuestionnairePath}/poll/${questionnaireData.publicLink}`; const adminUrl = `${baseUrl}${baseQuestionnairePath}/admin/${questionnaireData.adminLink}`; $('#public-link').val(publicUrl); $('#admin-link').val(adminUrl); // Отображаем статистику renderStats(questionnaireData.questions); // Показываем контейнер с данными $('#loading').hide(); $('#questionnaire-container').show(); }; // Отображение статистики опроса const renderStats = (questions) => { const $statsContainer = $('#stats-container'); $statsContainer.empty(); // Проверяем, есть ли ответы let hasAnyResponses = false; // Проверяем наличие ответов для каждого типа вопросов for (const question of questions) { // Согласовываем типы вопросов между бэкендом и фронтендом const questionType = normalizeQuestionType(question.type); if (questionType === 'single' || questionType === 'multiple') { if (question.options && question.options.some(option => (option.votes > 0 || option.count > 0))) { hasAnyResponses = true; break; } } else if (questionType === 'tagcloud') { if (question.tags && question.tags.some(tag => tag.count > 0)) { hasAnyResponses = true; break; } } else if (questionType === 'scale' || questionType === 'rating') { // Проверяем оба возможных поля для данных шкалы const hasScaleValues = question.scaleValues && question.scaleValues.length > 0; const hasResponses = question.responses && question.responses.length > 0; if (hasScaleValues || hasResponses) { hasAnyResponses = true; break; } } else if (questionType === 'text') { // Проверяем оба возможных поля для текстовых ответов const hasTextAnswers = question.textAnswers && question.textAnswers.length > 0; const hasAnswers = question.answers && question.answers.length > 0; if (hasTextAnswers || hasAnswers) { hasAnyResponses = true; break; } } } if (!hasAnyResponses) { $statsContainer.html('
', { text: 'Вариант' }), $(' | ', { text: 'Голоса' }), $(' | ', { text: '%' }), $(' | ', { text: 'Визуализация' }) ) ); const $tbody = $(' | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
', { text: option.text }), $(' | ', { text: votes }), $(' | ', { text: `${percent}%` }), $(' | ').append(
$(' ', { class: 'bar-container' }).append(
$(' ', {
class: 'bar',
css: { width: `${percent}%` }
})
)
)
);
$tbody.append($tr);
});
$table.append($thead, $tbody);
$container.append($table);
$container.append($(' ', { class: 'total-votes', text: `Всего голосов: ${totalVotes}` }));
};
// Отображение статистики для облака тегов
const renderTagCloudStats = (question, $container) => {
if (!question.tags || question.tags.length === 0 || !question.tags.some(tag => tag.count > 0)) {
$container.append($(' ', { class: 'no-votes', text: 'Нет выбранных тегов' }));
return;
}
const $tagCloud = $(' ', { class: 'tag-cloud-stats' });
// Находим максимальное количество для масштабирования
const maxCount = Math.max(...question.tags.map(tag => tag.count || 0));
// Сортируем теги по популярности
const sortedTags = [...question.tags].sort((a, b) => (b.count || 0) - (a.count || 0));
sortedTags.forEach(tag => {
if (tag.count && tag.count > 0) {
const fontSize = maxCount > 0 ? 1 + (tag.count / maxCount) * 1.5 : 1; // от 1em до 2.5em
$tagCloud.append(
$('', {
class: 'tag-item',
text: `${tag.text} (${tag.count})`,
css: { fontSize: `${fontSize}em` }
})
);
}
});
$container.append($tagCloud);
};
// Отображение статистики для шкалы и рейтинга
const renderScaleStats = (question, $container) => {
// Используем scaleValues или responses, в зависимости от того, что доступно
const values = question.responses && question.responses.length > 0
? question.responses
: (question.scaleValues || []);
if (values.length === 0) {
$container.append($(' ', { class: 'no-votes', text: 'Нет оценок' }));
return;
}
const sum = values.reduce((a, b) => a + b, 0);
const avg = sum / values.length;
const min = Math.min(...values);
const max = Math.max(...values);
// Создаем контейнер для статистики
const $scaleStats = $(' ', { class: 'scale-stats' });
// Добавляем сводную статистику
$scaleStats.append(
$(' ', { class: 'stat-summary' }).append(
$(' ', { class: 'stat-item' }).append(
$('', { class: 'stat-label', text: 'Среднее значение:' }),
$('', { class: 'stat-value', text: avg.toFixed(1) })
),
$(' ', { class: 'stat-item' }).append(
$('', { class: 'stat-label', text: 'Минимум:' }),
$('', { class: 'stat-value', text: min })
),
$(' ', { class: 'stat-item' }).append(
$('', { class: 'stat-label', text: 'Максимум:' }),
$('', { class: 'stat-value', text: max })
),
$(' ', { class: 'stat-item' }).append(
$('', { class: 'stat-label', text: 'Количество оценок:' }),
$('', { class: 'stat-value', text: values.length })
)
)
);
// Создаем таблицу для визуализации распределения голосов
const $table = $('
|