Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
.timetable th { background: #f9f9f9; }
.cell-active { background-color: #bbdefb; color: #0d47a1; font-size: 0.75rem; border-radius: 2px; height: 100%; width: 100%; display: flex; flex-direction: column; justify-content: center; overflow: hidden; }
.cell-active.gray { background-color: #e0e0e0; color: #757575; opacity: 0.8; }
.cell-active.skippable { background-color: #c8e6c9; color: #2e7d32; }
.cell-conflict { background-color: #ffcdd2; color: #b71c1c; }

/* Toast */
Expand Down Expand Up @@ -194,7 +195,13 @@ <h2>我的课程组 ({{ groups.length }})</h2>
<strong>组 {{ idx + 1 }}:</strong> {{ getGroupName(group) }}
<small>({{ getActiveCount(group) }}/{{ group.candidates.length }} 选中)</small>
</span>
<button class="danger" @click.stop="removeGroup(idx)" style="padding: 4px 8px; font-size: 0.8rem;">删除</button>
<div style="display: flex; align-items: center; gap: 10px;" @click.stop>
<label style="font-size: 0.85rem; cursor: pointer; display: flex; align-items: center;">
<input type="checkbox" v-model="group.is_skippable" style="margin-right: 4px;">
是否可逃
</label>
<button class="danger" @click="removeGroup(idx)" style="padding: 4px 8px; font-size: 0.8rem;">删除</button>
</div>
</div>
<div :class="['group-body', group.open ? 'open' : '']">
<label v-for="(course, cIdx) in group.candidates" :key="cIdx" class="result-item">
Expand All @@ -210,6 +217,7 @@ <h2>我的课程组 ({{ groups.length }})</h2>

<h3>偏好设置</h3>
<label><input type="checkbox" v-model="preferences.avoid_early_morning"> 避开早八 (1-2节)</label> <br>
<label><input type="checkbox" v-model="preferences.quality_sleep"> 优质睡眠 (9-13节)</label> <br>
<label><input type="checkbox" v-model="preferences.avoid_weekend"> 避开周末</label> <br>
<div style="margin-top: 10px;">
课程分布:
Expand Down Expand Up @@ -288,6 +296,7 @@ <h2 style="margin:0;">第 {{ currentScheduleIdx + 1 }} 方案课表</h2>
<span>总学分: {{ schedules[currentScheduleIdx].stats?.total_credits }}</span>
<span>总学时: {{ schedules[currentScheduleIdx].stats?.total_hours }}</span>
<span>周平均学时: {{ schedules[currentScheduleIdx].stats?.avg_weekly_hours }}</span>
<span style="color: #2e7d32;">实际每周学时: {{ schedules[currentScheduleIdx].stats?.actual_avg_weekly_hours }}</span>
<span>活跃周次: {{ schedules[currentScheduleIdx].stats?.week_span }}</span>
</div>
<div v-if="schedules[currentScheduleIdx].missing_course_names && schedules[currentScheduleIdx].missing_course_names.length > 0"
Expand Down Expand Up @@ -316,7 +325,7 @@ <h2 style="margin:0;">第 {{ currentScheduleIdx + 1 }} 方案课表</h2>
<td>{{ node }}</td>
<td v-for="day in 7" :key="day">
<div v-if="getCell(currentScheduleIdx, currentWeek, day-1, node-1)"
:class="['cell-active', getCell(currentScheduleIdx, currentWeek, day-1, node-1).isCurrent ? '' : 'gray']"
:class="['cell-active', getCell(currentScheduleIdx, currentWeek, day-1, node-1).isCurrent ? '' : 'gray', getCell(currentScheduleIdx, currentWeek, day-1, node-1).is_skippable ? 'skippable' : '']"
@click="openAlternatives(getCell(currentScheduleIdx, currentWeek, day-1, node-1))"
style="cursor: pointer;">
<div style="font-weight: bold;">{{ getCell(currentScheduleIdx, currentWeek, day-1, node-1).name }}</div>
Expand Down
26 changes: 20 additions & 6 deletions dist/static/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ createApp({
const preferences = reactive({
avoid_early_morning: false,
avoid_weekend: false,
quality_sleep: false, // Avoid 9-13
compactness: 'none',
day_max_limit_enabled: false,
day_max_limit_value: 0,
Expand Down Expand Up @@ -255,7 +256,8 @@ createApp({
groups.value.push({
id: Date.now() + i, // unique-ish id
open: false,
candidates: candidates
candidates: candidates,
is_skippable: false // Default
});
successCount++;
} else {
Expand Down Expand Up @@ -291,7 +293,8 @@ createApp({
groups.value.push({
id: Date.now(),
open: false,
candidates: JSON.parse(JSON.stringify(candidates))
candidates: JSON.parse(JSON.stringify(candidates)),
is_skippable: false // Default
});
// Uncheck after adding
searchResults.value.forEach(c => c.checked = false);
Expand Down Expand Up @@ -377,7 +380,8 @@ createApp({
teacher: c.teacher,
location: loc,
alternatives: c.alternatives,
isCurrent: true
isCurrent: true,
is_skippable: !!c.is_skippable // Pass to view
};
}
}
Expand All @@ -400,7 +404,8 @@ createApp({
teacher: c.teacher,
location: sess.location,
alternatives: c.alternatives,
isCurrent: false // Gray out
isCurrent: false, // Gray out
is_skippable: !!c.is_skippable
};
}
}
Expand All @@ -418,7 +423,8 @@ createApp({
teacher: c.teacher,
location: c.location_text, // Raw text fallback
alternatives: c.alternatives,
isCurrent: false
isCurrent: false,
is_skippable: !!c.is_skippable
};
}
}
Expand Down Expand Up @@ -462,7 +468,15 @@ createApp({
if (raw) {
try {
const data = JSON.parse(raw);
if (data.groups) groups.value = data.groups;
if (data.groups) {
groups.value = data.groups;
// Migration: Add is_skippable if missing
groups.value.forEach(g => {
if (g.is_skippable === undefined) {
g.is_skippable = false;
}
});
}
if (data.preferences) Object.assign(preferences, data.preferences);
return true;
} catch (e) {
Expand Down
Loading