feat: update assessment portal
This commit is contained in:
+142
-30
@@ -6,46 +6,159 @@ const submitBtn = document.getElementById('submitBtn');
|
||||
const submitText = document.getElementById('submitText');
|
||||
let submitIcon = document.getElementById('submitIcon');
|
||||
const alertBox = document.getElementById('alertBox');
|
||||
const mainGrid = document.getElementById('mainGrid');
|
||||
const alertIconWrap = document.getElementById('alertIconWrap');
|
||||
const alertIcon = document.getElementById('alertIcon');
|
||||
const alertTitle = document.getElementById('alertTitle');
|
||||
const alertMessage = document.getElementById('alertMessage');
|
||||
const alertClose = document.getElementById('alertClose');
|
||||
const inlineResult = document.getElementById('inlineResult');
|
||||
const resultPlaceholder = document.getElementById('resultPlaceholder');
|
||||
const resultContent = document.getElementById('resultContent');
|
||||
const resultImage = document.getElementById('resultImage');
|
||||
const resultImportanceWrap = document.getElementById('resultImportanceWrap');
|
||||
const resultImportanceImage = document.getElementById('resultImportanceImage');
|
||||
const excelBtn = document.getElementById('excelBtn');
|
||||
const resultPageBtn = document.getElementById('resultPageBtn');
|
||||
const summaryFilename = document.getElementById('summaryFilename');
|
||||
const summaryCount = document.getElementById('summaryCount');
|
||||
const homeStateKey = 'pipelineLifetime.homeState';
|
||||
let selectedFile = null;
|
||||
let alertTimer = null;
|
||||
let alertHideTimer = null;
|
||||
|
||||
function showAlert(message, type='error') {
|
||||
alertBox.classList.remove('hidden', 'bg-dangerSoft', 'text-dangerText', 'border-red-200', 'bg-blueSoft', 'text-primary', 'border-blue-200');
|
||||
function hideAlert() {
|
||||
clearTimeout(alertTimer);
|
||||
clearTimeout(alertHideTimer);
|
||||
alertBox.classList.remove('opacity-100', 'translate-y-0');
|
||||
alertBox.classList.add('pointer-events-none', 'opacity-0', 'translate-y-3');
|
||||
alertHideTimer = setTimeout(() => {
|
||||
alertBox.classList.add('hidden');
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function showAlert(message, type='error', title) {
|
||||
clearTimeout(alertTimer);
|
||||
clearTimeout(alertHideTimer);
|
||||
alertBox.classList.remove('hidden', 'border-red-200', 'border-blue-200');
|
||||
alertIconWrap.classList.remove('bg-dangerSoft', 'text-dangerText', 'bg-blueSoft', 'text-primary');
|
||||
if (type === 'error') {
|
||||
alertBox.classList.add('bg-dangerSoft', 'text-dangerText', 'border-red-200');
|
||||
alertBox.classList.add('border-red-200');
|
||||
alertIconWrap.classList.add('bg-dangerSoft', 'text-dangerText');
|
||||
alertIcon.textContent = 'priority_high';
|
||||
alertTitle.textContent = title || '需要补充文件';
|
||||
} else {
|
||||
alertBox.classList.add('bg-blueSoft', 'text-primary', 'border-blue-200');
|
||||
alertBox.classList.add('border-blue-200');
|
||||
alertIconWrap.classList.add('bg-blueSoft', 'text-primary');
|
||||
alertIcon.textContent = 'check_circle';
|
||||
alertTitle.textContent = title || '处理完成';
|
||||
}
|
||||
alertMessage.textContent = message;
|
||||
requestAnimationFrame(() => {
|
||||
alertBox.classList.remove('pointer-events-none', 'opacity-0', 'translate-y-3');
|
||||
alertBox.classList.add('opacity-100', 'translate-y-0');
|
||||
});
|
||||
alertTimer = setTimeout(() => {
|
||||
hideAlert();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
alertClose.addEventListener('click', hideAlert);
|
||||
|
||||
function updateSelectedFile(file) {
|
||||
selectedFile = file;
|
||||
selectedFileName.textContent = '已选择文件:' + file.name;
|
||||
selectedFileName.classList.remove('hidden');
|
||||
saveHomeState({ selectedFilename: file.name });
|
||||
}
|
||||
|
||||
function readHomeState() {
|
||||
try {
|
||||
return JSON.parse(sessionStorage.getItem(homeStateKey)) || {};
|
||||
} catch (err) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function saveHomeState(nextState) {
|
||||
try {
|
||||
const currentState = readHomeState();
|
||||
sessionStorage.setItem(homeStateKey, JSON.stringify({ ...currentState, ...nextState }));
|
||||
} catch (err) {
|
||||
// Ignore storage failures; prediction still works without client-side restore.
|
||||
}
|
||||
}
|
||||
|
||||
function renderResult(data) {
|
||||
resultImage.src = data.image_url;
|
||||
if (data.importance_url) {
|
||||
resultImportanceImage.src = data.importance_url;
|
||||
resultImportanceWrap.classList.remove('hidden');
|
||||
} else {
|
||||
resultImportanceWrap.classList.add('hidden');
|
||||
resultImportanceImage.removeAttribute('src');
|
||||
}
|
||||
excelBtn.href = data.excel_url;
|
||||
resultPageBtn.href = data.result_url;
|
||||
resultPlaceholder.classList.add('hidden');
|
||||
resultContent.classList.remove('hidden');
|
||||
resultContent.classList.add('flex');
|
||||
}
|
||||
|
||||
function restoreHomeState() {
|
||||
const savedState = readHomeState();
|
||||
if (savedState.selectedFilename) {
|
||||
selectedFileName.textContent = '上次选择文件:' + savedState.selectedFilename + '(需重新选择)';
|
||||
selectedFileName.classList.remove('hidden');
|
||||
}
|
||||
if (savedState.result) {
|
||||
renderResult(savedState.result);
|
||||
}
|
||||
alertBox.textContent = message;
|
||||
}
|
||||
|
||||
fileInput.addEventListener('change', () => {
|
||||
const file = fileInput.files[0];
|
||||
if (!file) return;
|
||||
selectedFileName.textContent = '已选择文件:' + file.name;
|
||||
selectedFileName.classList.remove('hidden');
|
||||
updateSelectedFile(file);
|
||||
});
|
||||
|
||||
['dragenter', 'dragover'].forEach(evt => dropZone.addEventListener(evt, e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
dropZone.classList.add('border-primary', 'bg-blue-50');
|
||||
}));
|
||||
['dragleave', 'drop'].forEach(evt => dropZone.addEventListener(evt, e => {
|
||||
|
||||
dropZone.addEventListener('dragleave', e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
dropZone.classList.remove('border-primary', 'bg-blue-50');
|
||||
}));
|
||||
});
|
||||
|
||||
dropZone.addEventListener('drop', e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
dropZone.classList.remove('border-primary', 'bg-blue-50');
|
||||
|
||||
const file = e.dataTransfer.files[0];
|
||||
if (!file) return;
|
||||
|
||||
if (window.DataTransfer) {
|
||||
const transfer = new DataTransfer();
|
||||
transfer.items.add(file);
|
||||
fileInput.files = transfer.files;
|
||||
}
|
||||
|
||||
updateSelectedFile(file);
|
||||
});
|
||||
|
||||
form.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
alertBox.classList.add('hidden');
|
||||
if (!fileInput.files.length) {
|
||||
showAlert('请先选择要上传的文件。');
|
||||
hideAlert();
|
||||
if (!selectedFile) {
|
||||
showAlert('点击上传区域选择电子表格或逗号分隔值文件,也可以直接把文件拖放到上传框内。', 'error', '请先选择文件');
|
||||
dropZone.classList.add('border-red-300', 'bg-red-50', 'ring-4', 'ring-red-100');
|
||||
dropZone.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
setTimeout(() => {
|
||||
dropZone.classList.remove('border-red-300', 'bg-red-50', 'ring-4', 'ring-red-100');
|
||||
}, 2400);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,27 +168,24 @@ form.addEventListener('submit', async (e) => {
|
||||
|
||||
try {
|
||||
const formData = new FormData(form);
|
||||
formData.set('file', selectedFile);
|
||||
const resp = await fetch(form.action, { method: 'POST', body: formData });
|
||||
const data = await resp.json();
|
||||
if (!resp.ok) {
|
||||
showAlert(data.error || '预测失败,请稍后重试。');
|
||||
return;
|
||||
}
|
||||
resultImage.src = data.image_url;
|
||||
if (data.importance_url) {
|
||||
resultImportanceImage.src = data.importance_url;
|
||||
resultImportanceWrap.classList.remove('hidden');
|
||||
} else {
|
||||
resultImportanceWrap.classList.add('hidden');
|
||||
}
|
||||
excelBtn.href = data.excel_url;
|
||||
resultPageBtn.href = data.result_url;
|
||||
summaryFilename.textContent = data.original_filename;
|
||||
summaryCount.textContent = data.sample_count;
|
||||
inlineResult.classList.remove('hidden');
|
||||
mainGrid.classList.remove('xl:grid-cols-[1.45fr_1fr]');
|
||||
mainGrid.classList.add('xl:grid-cols-[1.25fr_0.95fr_1.05fr]');
|
||||
showAlert('预测完成,已生成图表与 Excel 报告。', 'success');
|
||||
renderResult(data);
|
||||
saveHomeState({
|
||||
selectedFilename: data.original_filename || selectedFile.name,
|
||||
result: {
|
||||
image_url: data.image_url,
|
||||
importance_url: data.importance_url || '',
|
||||
excel_url: data.excel_url,
|
||||
result_url: data.result_url
|
||||
}
|
||||
});
|
||||
showAlert('预测完成,已生成图表与电子表格报告。', 'success');
|
||||
inlineResult.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
} catch (err) {
|
||||
showAlert('请求失败,请检查后端服务是否正常。');
|
||||
@@ -87,3 +197,5 @@ form.addEventListener('submit', async (e) => {
|
||||
submitIcon = restoredIcon;
|
||||
}
|
||||
});
|
||||
|
||||
restoreHomeState();
|
||||
|
||||
Reference in New Issue
Block a user