app端优化

This commit is contained in:
biss committed 2026-08-12 22:16:43 +08:00
1 parent 7994ed1ed3
commit 1e45ede5be
14 files changed
+357 -37

No files matched your search

+60 -1
View File
@@ -917,7 +917,7 @@ onMounted(async () => {
</template>
</el-table-column>
</el-table>
<el-table v-else :data="group.projects" class="project-table student-project-table" size="small">
<el-table v-else :data="group.projects" class="project-table student-project-table desktop-project-table" size="small">
<el-table-column type="expand" width="44">
<template #default="{ row }">
<div class="student-project-detail">
@@ -988,6 +988,43 @@ onMounted(async () => {
</template>
</el-table-column>
</el-table>
<div v-if="isStudent" class="mobile-project-cards">
<article v-for="row in group.projects" :key="row.id" class="mobile-project-card">
<header>
<div>
<span>{{ row.code }}</span>
<h4>{{ row.name }}</h4>
</div>
<el-tag :type="row.arrangementMode === 'Centralized' ? 'primary' : 'success'" size="small" effect="plain">
{{ modeMeta[row.arrangementMode].label }}
</el-tag>
</header>
<p>{{ row.description || modeMeta[row.arrangementMode].note }}</p>
<div class="mobile-project-arrangement">
<template v-if="row.arrangementMode === 'Centralized' && row.scheduleEntry">
<b>统一安排</b>
<span>第 {{ row.scheduleEntry.projectWeek ?? `${row.scheduleEntry.startWeek}–${row.scheduleEntry.endWeek}` }} 周 · 星期 {{ row.scheduleEntry.dayOfWeek }} · 第 {{ row.scheduleEntry.startPeriod }}–{{ row.scheduleEntry.startPeriod + row.scheduleEntry.periodCount - 1 }} 节</span>
<small>{{ row.scheduleEntry.campusName }} · {{ row.scheduleEntry.buildingName }} {{ row.scheduleEntry.classroomName }}</small>
</template>
<template v-else-if="row.arrangementMode === 'SelfScheduled'">
<b>{{ row.myBooking ? '已预约场次' : '选择实验场次' }}</b>
<div v-if="row.sessions.length" class="mobile-session-list">
<article v-for="session in row.sessions" :key="session.id" :class="{ 'is-selected': row.myBooking?.experimentSessionId === session.id }">
<div>
<strong>{{ formatSessionTime(session) }}</strong>
<small>{{ session.campusName }} · {{ session.buildingName }} {{ session.classroomName }}</small>
</div>
<el-tag :type="sessionTagType(session)" size="small" effect="plain">余 {{ session.remainingCount }} / {{ session.capacity }}</el-tag>
<el-button v-if="row.myBooking?.experimentSessionId === session.id" size="small" type="success" disabled>已预约</el-button>
<el-button v-else size="small" type="primary" plain :disabled="row.status !== 'Published' || !!row.myBooking || session.remainingCount <= 0" @click="book(row, session)">预约</el-button>
</article>
</div>
<span v-else class="table-muted">暂无有效实验场次</span>
<el-button v-if="row.myBooking && row.status === 'Published'" class="mobile-cancel-booking" size="small" text type="danger" @click="cancelBooking(row)">取消预约</el-button>
</template>
</div>
</article>
</div>
</div>
</section>
@@ -1593,6 +1630,7 @@ onMounted(async () => {
.batch-project-cell b, .batch-project-cell small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.batch-project-cell b { color: var(--lab-ink); font-size: 12px; }
.batch-project-cell small { color: var(--muted); font-size: 10px; }
.mobile-project-cards { display: none; }
@media (prefers-reduced-motion: reduce) {
.session-ticket { transition: none; }
}
@@ -1611,5 +1649,26 @@ onMounted(async () => {
.student-project-detail { grid-template-columns: 1fr; }
.mode-choice { grid-template-columns: 1fr; }
.intro-actions { flex-wrap: wrap; justify-content: flex-end; }
.desktop-project-table { display: none; }
.mobile-project-cards { display: grid; gap: 1px; background: #dce5ea; }
.mobile-project-card { padding: 15px 14px; background: #fff; }
.mobile-project-card > header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.mobile-project-card > header > div { min-width: 0; }
.mobile-project-card > header span { color: #68808d; font: 700 10px/1.2 Consolas, monospace; letter-spacing: .06em; }
.mobile-project-card h4 { margin: 4px 0 0; color: var(--lab-ink); font-size: 15px; line-height: 1.45; }
.mobile-project-card > p { margin: 9px 0 0; color: #667f8d; font-size: 12px; line-height: 1.6; }
.mobile-project-arrangement { display: grid; gap: 5px; margin-top: 13px; padding: 11px 12px; border-left: 3px solid #a6bbc6; background: #f6fafb; }
.mobile-project-arrangement > b { color: #365364; font-size: 12px; }
.mobile-project-arrangement > span { color: #405d6c; font-size: 12px; line-height: 1.5; }
.mobile-project-arrangement > small { color: #718792; font-size: 11px; line-height: 1.45; }
.mobile-session-list { display: grid; gap: 7px; margin-top: 3px; }
.mobile-session-list > article { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; padding: 9px; border: 1px solid #dce6e9; background: #fff; }
.mobile-session-list > article.is-selected { border-color: #69a99d; box-shadow: inset 3px 0 0 var(--lab-teal); }
.mobile-session-list > article > div { display: grid; gap: 3px; min-width: 0; }
.mobile-session-list strong { color: #304d5d; font-size: 12px; }
.mobile-session-list small { overflow: hidden; color: #718792; font-size: 10px; line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
.mobile-session-list .el-button { grid-column: 2; grid-row: 1 / span 2; align-self: center; min-height: 34px; }
.mobile-session-list .el-tag { grid-column: 1; width: fit-content; }
.mobile-cancel-booking { justify-self: start; margin-top: 2px; }
}
</style>
+18
View File
@@ -535,5 +535,23 @@ h2 {
.result-panel {
padding: 16px;
}
.building-groups {
gap: 14px;
margin-top: 16px;
}
.building-groups article > header {
padding: 12px;
}
.room-grid {
grid-template-columns: 1fr;
}
.room-item {
min-height: 76px;
padding: 13px 14px;
}
}
</style>