// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 验证全局输入
$speechRate = max(1, min(10, $speechRate));
// 验证每个内容项的输入
foreach ($settings as $i => $set) { // 去掉 &
$settings[$i]['digit1'] = max(1, $set['digit1']);
$settings[$i]['digit2'] = max(1, $set['digit2']);
$settings[$i]['perRow'] = max(1, $set['perRow']);
$settings[$i]['rows'] = max(1, $set['rows']);
$settings[$i]['forceDigit2'] = isset($_POST["force_digit2_$i"]) ? $_POST["force_digit2_$i"] : 'unlimited';
}
// 如果不需要更新题目且已有题目,则保留原题目
if ($updateProblems === 'no' && isset($_SESSION['problems'])) {
$problems = $_SESSION['problems'];
} else {
$problems = [];
foreach ($settings as $index => $set) {
$problemsToGenerate = $set['perRow'] * $set['rows'];
$contentProblems = generateProblems(
$set['type'],
$set['subType'],
$set['digit1'],
$set['digit2'],
$problemsToGenerate,
$set['directRange'],
$set['digitPosition'],
$set['forceDigit2']
);
$problems = array_merge($problems, $contentProblems);
}
$_SESSION['problems'] = $problems;
}
}
<!-- 模式选择选项卡 -->
<div class="tab-content" id="mode-tab" style="<?php echo $activeTab === 'mode' ? 'display: block;' : 'display: none;'; ?>">
<div class="tab-content-header">模式选择</div>
<!-- 题目模式设置 -->
<div class="form-group">
<label for="read_mode">题目模式</label>
<select name="read_mode" id="read_mode">
<option value="no" <?php echo $readMode === 'no' ? 'selected' : ''; ?>>列表模式</option>
<option value="yes" <?php echo $readMode === 'yes' ? 'selected' : ''; ?>>读题模式</option>
<option value="view" <?php echo $readMode === 'view' ? 'selected' : ''; ?>>看题模式</option>
</select>
</div>
<div class="form-row">
<div class="form-group">
<label for="speech_rate">语速 (1-10)</label>
<input type="number" name="speech_rate" id="speech_rate" min="1" max="10" value="<?php echo $speechRate; ?>">
</div>
<div class="form-group">
<label for="display_delay">间隔时间(0-2秒)</label>
<input type="number" name="display_delay" id="display_delay" min="0" max="2" step="0.1" value="<?php echo $displayDelay; ?>">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="show_answer">是否显示答案</label>
<select name="show_answer" id="show_answer">
<option value="no" <?php echo $showAnswer === 'no' ? 'selected' : ''; ?>>否</option>
<option value="yes" <?php echo $showAnswer === 'yes' ? 'selected' : ''; ?>>是</option>
</select>
</div>
<div class="form-group">
<label for="update_problems">是否更新题目</label>
<select name="update_problems" id="update_problems">
<option value="yes" <?php echo $updateProblems === 'yes' ? 'selected' : ''; ?>>是</option>
<option value="no" <?php echo $updateProblems === 'no' ? 'selected' : ''; ?>>否</option>
</select>
</div>
</div>
</div>
<?php else: ?>
<!-- 正常预览模式 -->
<?php
// 首先定义outputPage函数
function outputPage($problemGroups, $titlePages, $studentPages, $headerPages, $footerPages, $currentPage, $totalPages, $showAnswer) {
// 获取页面标题、学生信息等
$title = isset($titlePages[$currentPage - 1]) ? $titlePages[$currentPage - 1] : end($titlePages);
$student = isset($studentPages[$currentPage - 1]) ? $studentPages[$currentPage - 1] : end($studentPages);
$header = isset($headerPages[$currentPage - 1]) ? $headerPages[$currentPage - 1] : end($headerPages);
$footer = isset($footerPages[$currentPage - 1]) ? $footerPages[$currentPage - 1] : end($footerPages);
?>
<div class="a4-page">
<?php if (!empty($header)): ?>
<div class="page-header"><?php echo nl2br(htmlspecialchars($header)); ?></div>
<?php endif; ?>
<?php if (!empty($title)): ?>
<div class="page-title"><?php echo nl2br(htmlspecialchars($title)); ?></div>
<?php endif; ?>
<?php if (!empty($student)): ?>
<div class="student-info <?php
// 判断当前页是否包含乘除法(只要有一个乘除法组就算)
$hasMultiplicationDivision = false;
foreach ($problemGroups as $group) {
if ($group['settings']['type'] === 'multiplication' || $group['settings']['type'] === 'division') {
$hasMultiplicationDivision = true;
break;
}
}
echo $hasMultiplicationDivision ? 'multiplication-division-mode' : 'addition-subtraction-mode';
?>">
<?php
$studentParts = explode('_______', nl2br(htmlspecialchars($student)));
foreach ($studentParts as $index => $part) {
echo $part;
if ($index < count($studentParts) - 1) {
echo '<span class="student-info-line"></span>';
}
}
?>
</div>
<?php endif; ?>
<?php
// 输出每个内容组的题目
foreach ($problemGroups as $group):
$perRow = $group['settings']['perRow'];
$rows = $group['settings']['rows'];
$problems = $group['problems'];
// 按行分割题目
$problemRows = array_chunk($problems, $perRow);
foreach ($problemRows as $row): ?>
<?php if($group['settings']['type'] === 'addition_subtraction'): ?>
<table class="problems-table addition-subtraction-table">
<tr>
<?php foreach ($row as $colIndex => $problem): ?>
<td style="width: <?php echo (100 / $perRow); ?>%;">
<div class="problem-index">NO.<?php echo $problem['pageIndex']; ?></div>
<div class="vertical-underline-top"></div>
<div class="vertical-problem">
<?php foreach ($problem['numbers'] as $i => $number): ?>
<div class="vertical-number">
<?php if ($i > 0 && $number < 0): ?>
-<?php echo abs($number); ?>
<?php else: ?>
<?php echo $i > 0 ? ' '.$number : $number; ?>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<div class="vertical-underline-top"></div>
<?php if ($showAnswer === 'yes'): ?>
<div class="vertical-number answer"><?php echo $problem['result']; ?></div>
<?php else: ?>
<div style="height: 20px;"></div>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
</table>
<?php else: ?>
<table class="problems-table multiplication-division-table">
<tr>
<?php foreach ($row as $colIndex => $problem): ?>
<td style="width: <?php echo (100 / $perRow); ?>%;">
<div class="horizontal-problem">
<span class="vertical-underline-right">NO.<?php echo $problem['pageIndex']; ?> </span>
<span>
<?php echo $problem['numbers'][0]; ?>
<?php echo $group['settings']['type'] === 'multiplication' ? '×' : '÷'; ?>
<?php echo $problem['numbers'][1]; ?> =
</span>
<?php if ($showAnswer === 'yes'): ?>
<span class="answer"><?php echo $problem['result']; ?></span>
<?php else: ?>
<span class="space"></span>
<?php endif; ?>
</div>
</td>
<?php endforeach; ?>
</tr>
</table>
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?>
<div class="page-footer">
<?php if (!empty($footer)): ?>
<?php echo nl2br(htmlspecialchars($footer)); ?>
<?php endif; ?>
<span style="float: right;">
第<?php echo $currentPage; ?>页/共<?php echo $totalPages; ?>页
</span>
</div>
</div>
<?php
}
// 计算总题数
$totalProblems = count($problems);
$allPerRow = [];
$allRows = [];
foreach ($settings as $set) {
$allPerRow[] = $set['perRow'];
$allRows[] = $set['rows'];
}
// 重新组织问题数组,按内容项分组
$groupedProblems = [];
$startIndex = 0;
foreach ($settings as $index => $set) {
$contentTotal = $set['perRow'] * $set['rows'];
$groupedProblems[$index] = array_slice($problems, $startIndex, $contentTotal);
$startIndex += $contentTotal;
}
// 初始化页面相关变量
$currentPage = 1;
$problemIndex = 0; // 全局题目索引
$currentPageGroups = []; // 存储当前页的内容组
$totalPages = 0; // 总页数将在后面计算
$pageProblemIndex = 0; // 每页题目索引(用于强制换页时重置)
// 根据强制换页设置组织页面
foreach ($settings as $currentContentItem => $set) {
$forcePageBreak = $set['forcePageBreak'] === 'yes';
$contentProblems = $groupedProblems[$currentContentItem];
// 如果需要强制换页或者这是第一个内容项,则创建新页面
if ($forcePageBreak || empty($currentPageGroups)) {
// 如果有累积的内容组,先输出当前页
if (!empty($currentPageGroups)) {
$totalPages++;
outputPage($currentPageGroups, $titlePages, $studentPages, $headerPages, $footerPages, $totalPages, $totalPages, $showAnswer);
$currentPageGroups = [];
// 强制换页时重置题目编号
if ($forcePageBreak) {
$pageProblemIndex = 0;
}
}
}
// 为当前内容项的题目添加索引
foreach ($contentProblems as &$problem) {
$problem['index'] = ++$problemIndex; // 全局索引,连续编号
$problem['pageIndex'] = ++$pageProblemIndex; // 每页索引,强制换页时重置
}
unset($problem); // 断开引用
// 将当前内容项添加到当前页
$currentPageGroups[] = [
'settings' => $set,
'problems' => $contentProblems
];
}
// 输出最后一页(如果有内容组)
if (!empty($currentPageGroups)) {
$totalPages++;
outputPage($currentPageGroups, $titlePages, $studentPages, $headerPages, $footerPages, $totalPages, $totalPages, $showAnswer);
}
?>
<?php endif; ?>
// 上移按钮点击事件
document.addEventListener('click', function(e) {
if (e.target && e.target.classList.contains('move-up-btn')) {
const itemIndex = parseInt(e.target.getAttribute('data-item'));
if (itemIndex > 1) {
moveContentItem(itemIndex, 'up');
}
}
});
// 下移按钮点击事件
document.addEventListener('click', function(e) {
if (e.target && e.target.classList.contains('move-down-btn')) {
const itemIndex = parseInt(e.target.getAttribute('data-item'));
const totalItems = parseInt(document.getElementById('content_items').value);
if (itemIndex < totalItems) {
moveContentItem(itemIndex, 'down');
}
}
});
// 移动内容项函数
function moveContentItem(itemIndex, direction) {
const container = document.getElementById('content-items-container');
const items = container.querySelectorAll('.content-item');
const currentItem = document.querySelector(`.content-item[data-item="${itemIndex}"]`);
if (direction === 'up') {
const prevItem = document.querySelector(`.content-item[data-item="${itemIndex - 1}"]`);
container.insertBefore(currentItem, prevItem);
} else {
const nextItem = document.querySelector(`.content-item[data-item="${itemIndex + 1}"]`);
container.insertBefore(nextItem, currentItem);
}
// 重新编号所有内容项
renumberContentItems();
}
// 重新编号内容项
function renumberContentItems() {
const container = document.getElementById('content-items-container');
const items = container.querySelectorAll('.content-item');
items.forEach((item, index) => {
const newIndex = index + 1;
item.setAttribute('data-item', newIndex);
item.querySelector('.tab-content-header').textContent = `内容设置#${newIndex}`;
// 更新所有表单元素的ID和name
item.querySelectorAll('input, select, textarea, label').forEach(element => {
if (element.id) element.id = element.id.replace(/_\d+$/, `_${newIndex}`);
if (element.name) element.name = element.name.replace(/_\d+$/, `_${newIndex}`);
if (element.htmlFor) element.htmlFor = element.htmlFor.replace(/_\d+$/, `_${newIndex}`);
});
// 更新按钮的data-item
item.querySelectorAll('.remove-content-item, .move-up-btn, .move-down-btn').forEach(btn => {
btn.setAttribute('data-item', newIndex);
});
});
// 更新内容项计数
document.getElementById('content_items').value = items.length;
// 更新按钮禁用状态
updateMoveButtonsState();
}
// 更新移动按钮状态
function updateMoveButtonsState() {
const container = document.getElementById('content-items-container');
const items = container.querySelectorAll('.content-item');
const totalItems = items.length;
items.forEach((item, index) => {
const itemIndex = index + 1;
const moveUpBtn = item.querySelector('.move-up-btn');
const moveDownBtn = item.querySelector('.move-down-btn');
if (moveUpBtn) {
moveUpBtn.disabled = itemIndex === 1;
}
if (moveDownBtn) {
moveDownBtn.disabled = itemIndex === totalItems;
}
/* 第一个内容项不显示删除按钮
const removeBtn = item.querySelector('.remove-content-item');
if (removeBtn) {
removeBtn.style.display = itemIndex === 1 ? 'none' : 'inline-block';
}*/
});
}
// 在添加新内容项后调用更新按钮状态
document.getElementById('add-content-item').addEventListener('click', function() {
setTimeout(updateMoveButtonsState, 0);
});
// 初始化时更新按钮状态
document.addEventListener('DOMContentLoaded', updateMoveButtonsState);
当【是否更新题目】选择为【否】时,上移或下移内容项后,整行的顺序没有改变,我要的是整行的题目要跟着上移或下移改变,但每行内部的题目顺序保持不变、题目不变。不要创建新的文件。
比如
内容项#1生成了两道题,1+1、1+2
内容项#2生成了两道题,10+10、11+12
这时预览页显示的是:
1+1 1+2
10+10 11+12
这时我把内容项#1下移了,那么预览页就应该要显示:
10+10 11+12
1+1 1+2
但现在我下移了内容#1,显示的还是:
1+1 1+2
10+10 11+12
上面是部分代码,哪里的原代码要改成什么,写清楚。