feat: 添加做题的保存功能
在答题界面(answer.html)添加本地保存功能: - 使用 localStorage 保存答题状态(选择题、简答题、画图题) - 保存学生姓名和画图笔画历史 - 有效期 24 小时,过期自动清除 - 页面加载时自动恢复进度 - 页面关闭/刷新前自动保存 - 提交成功后自动清除本地进度 - 添加保存进度按钮和状态提示 Closes #1
This commit is contained in:
@@ -166,6 +166,76 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
border-color: #f59e0b;
|
border-color: #f59e0b;
|
||||||
}
|
}
|
||||||
|
/* 画板样式 */
|
||||||
|
.drawing-board {
|
||||||
|
margin-left: 44px;
|
||||||
|
border: 2px solid #e0e0e0;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
.drawing-canvas {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
border: 2px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: white;
|
||||||
|
cursor: crosshair;
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
.drawing-tools {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.drawing-tools button {
|
||||||
|
padding: 8px 16px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
.btn-clear {
|
||||||
|
background: #ef4444;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-clear:hover {
|
||||||
|
background: #dc2626;
|
||||||
|
}
|
||||||
|
.btn-undo {
|
||||||
|
background: #9ca3af;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-undo:hover {
|
||||||
|
background: #6b7280;
|
||||||
|
}
|
||||||
|
.color-picker {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.color-option {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 3px solid transparent;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
.color-option.active {
|
||||||
|
border-color: #f59e0b;
|
||||||
|
}
|
||||||
|
.brush-size {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.brush-size input[type="range"] {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
.submit-section {
|
.submit-section {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
@@ -186,6 +256,22 @@
|
|||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 5px 20px rgba(245, 158, 11, 0.3);
|
box-shadow: 0 5px 20px rgba(245, 158, 11, 0.3);
|
||||||
}
|
}
|
||||||
|
.btn-save {
|
||||||
|
background: #10b981;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 24px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
.btn-save:hover {
|
||||||
|
background: #059669;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
|
||||||
|
}
|
||||||
.btn-submit:disabled {
|
.btn-submit:disabled {
|
||||||
background: #ccc;
|
background: #ccc;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
@@ -261,6 +347,10 @@
|
|||||||
<div class="stat-label">简答题</div>
|
<div class="stat-label">简答题</div>
|
||||||
<div class="stat-value" th:text="${essayCount} + '道'">0道</div>
|
<div class="stat-value" th:text="${essayCount} + '道'">0道</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-item" th:if="${drawingCount != null && drawingCount > 0}">
|
||||||
|
<div class="stat-label">画图题</div>
|
||||||
|
<div class="stat-value" th:text="${drawingCount} + '道'">0道</div>
|
||||||
|
</div>
|
||||||
<div class="stat-item">
|
<div class="stat-item">
|
||||||
<div class="stat-label">总分</div>
|
<div class="stat-label">总分</div>
|
||||||
<div class="stat-value" th:text="${totalScore} + '分'">100分</div>
|
<div class="stat-value" th:text="${totalScore} + '分'">100分</div>
|
||||||
@@ -270,6 +360,10 @@
|
|||||||
<label for="studentName">做题人姓名 *</label>
|
<label for="studentName">做题人姓名 *</label>
|
||||||
<input type="text" id="studentName" placeholder="请输入您的姓名" required>
|
<input type="text" id="studentName" placeholder="请输入您的姓名" required>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="margin-top: 16px; display: flex; justify-content: center; gap: 12px; align-items: center;">
|
||||||
|
<button type="button" class="btn-save" onclick="saveProgress()" id="saveBtn">保存进度</button>
|
||||||
|
<span id="saveStatus" style="color: #999; font-size: 13px;"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 答题表单 -->
|
<!-- 答题表单 -->
|
||||||
@@ -317,6 +411,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 画图题 -->
|
||||||
|
<div th:if="${drawingQuestions != null}" th:each="q, iterStat : ${drawingQuestions}" class="question-card">
|
||||||
|
<div class="question-header">
|
||||||
|
<span class="question-number" th:text="${choiceCount + essayCount + iterStat.index + 1}">1</span>
|
||||||
|
<span class="question-title" th:text="${q.title}">题目内容</span>
|
||||||
|
<span class="question-score" th:text="${q.score} + '分'">10分</span>
|
||||||
|
<span class="question-type">画图题</span>
|
||||||
|
</div>
|
||||||
|
<div class="drawing-board">
|
||||||
|
<canvas class="drawing-canvas" th:id="'canvas_' + ${q.id}" th:data-qid="${q.id}"></canvas>
|
||||||
|
<div class="drawing-tools">
|
||||||
|
<div class="color-picker">
|
||||||
|
<span style="color: #666; font-size: 12px;">颜色:</span>
|
||||||
|
<div class="color-option active" style="background: #000000;" data-color="#000000"></div>
|
||||||
|
<div class="color-option" style="background: #ef4444;" data-color="#ef4444"></div>
|
||||||
|
<div class="color-option" style="background: #22c55e;" data-color="#22c55e"></div>
|
||||||
|
<div class="color-option" style="background: #3b82f6;" data-color="#3b82f6"></div>
|
||||||
|
</div>
|
||||||
|
<div class="brush-size">
|
||||||
|
<span style="color: #666; font-size: 12px;">粗细:</span>
|
||||||
|
<input type="range" th:id="'brushSize_' + ${q.id}" min="1" max="20" value="3">
|
||||||
|
<span th:id="'brushSizeValue_' + ${q.id}" style="color: #666; font-size: 12px;">3</span>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-undo" th:onclick="'undoStroke(' + ${q.id} + ')'">撤销</button>
|
||||||
|
<button type="button" class="btn-clear" th:onclick="'clearCanvas(' + ${q.id} + ')'">清空</button>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" th:name="'q_' + ${q.id}" th:id="'input_' + ${q.id}" value="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 提交按钮 -->
|
<!-- 提交按钮 -->
|
||||||
<div class="submit-section">
|
<div class="submit-section">
|
||||||
<button type="submit" class="btn-submit">提交答案</button>
|
<button type="submit" class="btn-submit">提交答案</button>
|
||||||
@@ -336,6 +460,334 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
|
// 画板相关变量
|
||||||
|
const canvases = {};
|
||||||
|
const contexts = {};
|
||||||
|
const strokes = {}; // 存储每个画板的笔画历史
|
||||||
|
const currentStrokes = {}; // 当前正在画的笔画
|
||||||
|
|
||||||
|
// 保存和恢复答题状态
|
||||||
|
const EXPIRE_TIME = 24 * 60 * 60 * 1000; // 24小时
|
||||||
|
|
||||||
|
function getStorageKey() {
|
||||||
|
const examUid = document.getElementById('examUid').value;
|
||||||
|
return 'exam_progress_' + examUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveProgress() {
|
||||||
|
const examUid = document.getElementById('examUid').value;
|
||||||
|
const studentName = document.getElementById('studentName').value;
|
||||||
|
const answers = {};
|
||||||
|
const canvasData = {};
|
||||||
|
|
||||||
|
// 保存选择题答案
|
||||||
|
document.querySelectorAll('input[type="radio"]:checked').forEach(radio => {
|
||||||
|
answers[radio.name] = radio.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 保存简答题答案
|
||||||
|
document.querySelectorAll('.essay-input textarea').forEach(textarea => {
|
||||||
|
if (textarea.value.trim()) {
|
||||||
|
answers[textarea.name] = textarea.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 保存画图题
|
||||||
|
Object.keys(strokes).forEach(qid => {
|
||||||
|
if (strokes[qid] && strokes[qid].length > 0) {
|
||||||
|
canvasData[qid] = strokes[qid];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
examUid: examUid,
|
||||||
|
studentName: studentName,
|
||||||
|
answers: answers,
|
||||||
|
canvasData: canvasData,
|
||||||
|
savedAt: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.setItem(getStorageKey(), JSON.stringify(data));
|
||||||
|
updateSaveStatus('保存成功', 'success');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('保存失败:', e);
|
||||||
|
updateSaveStatus('保存失败,存储空间不足', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreProgress() {
|
||||||
|
const key = getStorageKey();
|
||||||
|
const saved = localStorage.getItem(key);
|
||||||
|
if (!saved) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(saved);
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
// 检查是否过期
|
||||||
|
if (now - data.savedAt > EXPIRE_TIME) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
updateSaveStatus('之前的进度已过期(超过24小时)', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复姓名
|
||||||
|
if (data.studentName) {
|
||||||
|
document.getElementById('studentName').value = data.studentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复选择题
|
||||||
|
if (data.answers) {
|
||||||
|
Object.keys(data.answers).forEach(name => {
|
||||||
|
const radio = document.querySelector('input[type="radio"][name="' + name + '"][value="' + data.answers[name] + '"]');
|
||||||
|
if (radio) radio.checked = true;
|
||||||
|
|
||||||
|
const textarea = document.querySelector('textarea[name="' + name + '"]');
|
||||||
|
if (textarea) textarea.value = data.answers[name];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复画图题(需要等canvas初始化完成后)
|
||||||
|
if (data.canvasData) {
|
||||||
|
setTimeout(() => {
|
||||||
|
Object.keys(data.canvasData).forEach(qid => {
|
||||||
|
if (canvases[qid] && contexts[qid]) {
|
||||||
|
strokes[qid] = data.canvasData[qid];
|
||||||
|
redrawCanvas(qid);
|
||||||
|
updateCanvasInput(qid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveTime = new Date(data.savedAt).toLocaleString('zh-CN');
|
||||||
|
updateSaveStatus('已恢复 ' + saveTime + ' 的进度', 'success');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('恢复进度失败:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSavedProgress() {
|
||||||
|
localStorage.removeItem(getStorageKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSaveStatus(message, type) {
|
||||||
|
const statusEl = document.getElementById('saveStatus');
|
||||||
|
if (!statusEl) return;
|
||||||
|
statusEl.textContent = message;
|
||||||
|
if (type === 'success') {
|
||||||
|
statusEl.style.color = '#10b981';
|
||||||
|
} else if (type === 'error') {
|
||||||
|
statusEl.style.color = '#ef4444';
|
||||||
|
} else if (type === 'warning') {
|
||||||
|
statusEl.style.color = '#f59e0b';
|
||||||
|
} else {
|
||||||
|
statusEl.style.color = '#999';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3秒后清除状态
|
||||||
|
setTimeout(() => {
|
||||||
|
statusEl.textContent = '';
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面关闭前自动保存
|
||||||
|
window.addEventListener('beforeunload', function() {
|
||||||
|
saveProgress();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化所有画板
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const canvasElements = document.querySelectorAll('.drawing-canvas');
|
||||||
|
canvasElements.forEach(canvas => {
|
||||||
|
const qid = canvas.dataset.qid;
|
||||||
|
initCanvas(canvas, qid);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 恢复之前保存的进度
|
||||||
|
restoreProgress();
|
||||||
|
});
|
||||||
|
|
||||||
|
function initCanvas(canvas, qid) {
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
canvases[qid] = canvas;
|
||||||
|
contexts[qid] = ctx;
|
||||||
|
strokes[qid] = [];
|
||||||
|
currentStrokes[qid] = [];
|
||||||
|
|
||||||
|
// 设置画布大小
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
canvas.width = rect.width;
|
||||||
|
canvas.height = rect.height;
|
||||||
|
|
||||||
|
// 设置画笔样式
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
ctx.lineJoin = 'round';
|
||||||
|
ctx.strokeStyle = '#000000';
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
|
||||||
|
let isDrawing = false;
|
||||||
|
let lastX = 0;
|
||||||
|
let lastY = 0;
|
||||||
|
|
||||||
|
// 鼠标/触摸事件
|
||||||
|
function getPos(e) {
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
if (e.touches) {
|
||||||
|
return {
|
||||||
|
x: e.touches[0].clientX - rect.left,
|
||||||
|
y: e.touches[0].clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: e.clientX - rect.left,
|
||||||
|
y: e.clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function startDrawing(e) {
|
||||||
|
isDrawing = true;
|
||||||
|
const pos = getPos(e);
|
||||||
|
lastX = pos.x;
|
||||||
|
lastY = pos.y;
|
||||||
|
currentStrokes[qid] = [{
|
||||||
|
x: pos.x,
|
||||||
|
y: pos.y,
|
||||||
|
color: ctx.strokeStyle,
|
||||||
|
width: ctx.lineWidth
|
||||||
|
}];
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(e) {
|
||||||
|
if (!isDrawing) return;
|
||||||
|
const pos = getPos(e);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(lastX, lastY);
|
||||||
|
ctx.lineTo(pos.x, pos.y);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
currentStrokes[qid].push({
|
||||||
|
x: pos.x,
|
||||||
|
y: pos.y,
|
||||||
|
color: ctx.strokeStyle,
|
||||||
|
width: ctx.lineWidth
|
||||||
|
});
|
||||||
|
|
||||||
|
lastX = pos.x;
|
||||||
|
lastY = pos.y;
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopDrawing() {
|
||||||
|
if (isDrawing && currentStrokes[qid].length > 1) {
|
||||||
|
strokes[qid].push([...currentStrokes[qid]]);
|
||||||
|
updateCanvasInput(qid);
|
||||||
|
}
|
||||||
|
isDrawing = false;
|
||||||
|
currentStrokes[qid] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 鼠标事件
|
||||||
|
canvas.addEventListener('mousedown', startDrawing);
|
||||||
|
canvas.addEventListener('mousemove', draw);
|
||||||
|
canvas.addEventListener('mouseup', stopDrawing);
|
||||||
|
canvas.addEventListener('mouseout', stopDrawing);
|
||||||
|
|
||||||
|
// 触摸事件
|
||||||
|
canvas.addEventListener('touchstart', startDrawing, { passive: false });
|
||||||
|
canvas.addEventListener('touchmove', draw, { passive: false });
|
||||||
|
canvas.addEventListener('touchend', stopDrawing);
|
||||||
|
|
||||||
|
// 颜色选择
|
||||||
|
const colorOptions = canvas.parentElement.querySelectorAll('.color-option');
|
||||||
|
colorOptions.forEach(option => {
|
||||||
|
option.addEventListener('click', function() {
|
||||||
|
colorOptions.forEach(o => o.classList.remove('active'));
|
||||||
|
this.classList.add('active');
|
||||||
|
ctx.strokeStyle = this.dataset.color;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 画笔大小
|
||||||
|
const brushSizeInput = document.getElementById('brushSize_' + qid);
|
||||||
|
const brushSizeValue = document.getElementById('brushSizeValue_' + qid);
|
||||||
|
if (brushSizeInput) {
|
||||||
|
brushSizeInput.addEventListener('input', function() {
|
||||||
|
ctx.lineWidth = this.value;
|
||||||
|
if (brushSizeValue) {
|
||||||
|
brushSizeValue.textContent = this.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 窗口大小改变时重新设置画布大小
|
||||||
|
window.addEventListener('resize', function() {
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
canvas.width = rect.width;
|
||||||
|
canvas.height = rect.height;
|
||||||
|
ctx.putImageData(imageData, 0, 0);
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
ctx.lineJoin = 'round';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCanvas(qid) {
|
||||||
|
const canvas = canvases[qid];
|
||||||
|
const ctx = contexts[qid];
|
||||||
|
if (canvas && ctx) {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
strokes[qid] = [];
|
||||||
|
updateCanvasInput(qid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function undoStroke(qid) {
|
||||||
|
const canvas = canvases[qid];
|
||||||
|
const ctx = contexts[qid];
|
||||||
|
if (canvas && ctx && strokes[qid] && strokes[qid].length > 0) {
|
||||||
|
strokes[qid].pop();
|
||||||
|
redrawCanvas(qid);
|
||||||
|
updateCanvasInput(qid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function redrawCanvas(qid) {
|
||||||
|
const canvas = canvases[qid];
|
||||||
|
const ctx = contexts[qid];
|
||||||
|
if (!canvas || !ctx) return;
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
strokes[qid].forEach(stroke => {
|
||||||
|
if (stroke.length < 2) return;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(stroke[0].x, stroke[0].y);
|
||||||
|
ctx.strokeStyle = stroke[0].color;
|
||||||
|
ctx.lineWidth = stroke[0].width;
|
||||||
|
|
||||||
|
for (let i = 1; i < stroke.length; i++) {
|
||||||
|
ctx.lineTo(stroke[i].x, stroke[i].y);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCanvasInput(qid) {
|
||||||
|
const canvas = canvases[qid];
|
||||||
|
const input = document.getElementById('input_' + qid);
|
||||||
|
if (canvas && input) {
|
||||||
|
// 将画布内容转为base64
|
||||||
|
const base64 = canvas.toDataURL('image/png');
|
||||||
|
input.value = base64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单提交
|
||||||
document.getElementById('answerForm').addEventListener('submit', function(e) {
|
document.getElementById('answerForm').addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -346,6 +798,11 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新所有画板的输入值
|
||||||
|
Object.keys(canvases).forEach(qid => {
|
||||||
|
updateCanvasInput(qid);
|
||||||
|
});
|
||||||
|
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const answers = {};
|
const answers = {};
|
||||||
|
|
||||||
@@ -381,6 +838,9 @@
|
|||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
|
// 提交成功后清除本地保存的进度
|
||||||
|
clearSavedProgress();
|
||||||
|
|
||||||
// 填入返回的答案 UID 并显示弹窗
|
// 填入返回的答案 UID 并显示弹窗
|
||||||
const answerUidElement = document.getElementById('answerUid');
|
const answerUidElement = document.getElementById('answerUid');
|
||||||
if (answerUidElement) {
|
if (answerUidElement) {
|
||||||
@@ -409,6 +869,12 @@
|
|||||||
// 重置表单
|
// 重置表单
|
||||||
document.getElementById('answerForm').reset();
|
document.getElementById('answerForm').reset();
|
||||||
document.getElementById('studentName').value = '';
|
document.getElementById('studentName').value = '';
|
||||||
|
// 清空所有画板
|
||||||
|
Object.keys(canvases).forEach(qid => {
|
||||||
|
clearCanvas(qid);
|
||||||
|
});
|
||||||
|
// 清除本地保存的进度
|
||||||
|
clearSavedProgress();
|
||||||
document.querySelector('.btn-submit').disabled = false;
|
document.querySelector('.btn-submit').disabled = false;
|
||||||
document.querySelector('.btn-submit').textContent = '提交答案';
|
document.querySelector('.btn-submit').textContent = '提交答案';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user