656 lines
14 KiB
Vue
656 lines
14 KiB
Vue
<template>
|
||
<div class="homework-review">
|
||
<!-- 顶部筛选区域 -->
|
||
<div class="top-section">
|
||
<div class="filter-tabs">
|
||
<span class="tab-item" :class="{ active: activeTab === 'all' }" @click="setActiveTab('all')">全部</span>
|
||
<span class="tab-item" :class="{ active: activeTab === 'publishing' }"
|
||
@click="setActiveTab('publishing')">发布中</span>
|
||
<span class="tab-item" :class="{ active: activeTab === 'ended' }" @click="setActiveTab('ended')">已结束</span>
|
||
</div>
|
||
<div class="class-select">
|
||
<n-select
|
||
v-model:value="selectedClass"
|
||
:options="classOptions"
|
||
placeholder="请选择班级"
|
||
clearable
|
||
style="width: 276px;"
|
||
@update:value="handleClassChange"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 作业列表 -->
|
||
<div class="homework-list">
|
||
<!-- 已结束作业 -->
|
||
<div v-for="homework in filteredHomeworks" :key="homework.id">
|
||
|
||
|
||
<div v-if="homework.status === 'ended'" class="homework-card ended">
|
||
<div class="card-header">
|
||
<h3 class="homework-title">{{ homework.title }}</h3>
|
||
<span class="status-badge ended">已结束</span>
|
||
</div>
|
||
<div class="card-content">
|
||
<div class="content-left">
|
||
<p class="homework-desc">{{ homework.content }}</p>
|
||
<div class="homework-info">
|
||
<div class="info-item">
|
||
<img class="icon" src="/images/teacher/发布人.png" alt="发布人" />
|
||
<span class="text">发布人:{{ homework.publisher }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<img class="icon" src="/images/teacher/起点时间.png" alt="时间" />
|
||
<span class="text">起止时间:{{ homework.timeRange }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="content-right">
|
||
<div class="stats-area">
|
||
<span class="big-number">{{ homework.pendingCount }}</span>
|
||
<span class="label primary">待批</span>
|
||
<span class="label secondary">{{ homework.submittedCount }}已交</span>
|
||
<span class="label secondary">{{ homework.unsubmittedCount }}未交</span>
|
||
</div>
|
||
<n-space>
|
||
<n-button type="primary" @click="reviewHomework(homework.id)">批阅</n-button>
|
||
<n-button type="error" @click="deleteHomework(homework.id)">删除</n-button>
|
||
</n-space>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 发布中作业 -->
|
||
<div v-if="homework.status === 'publishing'" class="homework-card publishing">
|
||
<div class="card-header">
|
||
<h3 class="homework-title">{{ homework.title }}</h3>
|
||
<span class="status-badge publishing">发布中</span>
|
||
</div>
|
||
<div class="card-content">
|
||
<div class="content-left">
|
||
<p class="homework-desc">{{ homework.content }}</p>
|
||
<div class="homework-info">
|
||
<div class="info-item">
|
||
<img class="icon" src="/images/teacher/发布人.png" alt="发布人" />
|
||
<span class="text">发布人:{{ homework.publisher }}</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<img class="icon" src="/images/teacher/起点时间.png" alt="时间" />
|
||
<span class="text">起止时间:{{ homework.timeRange }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="content-right">
|
||
<div class="stats-area">
|
||
<span class="big-number">{{ homework.pendingCount }}</span>
|
||
<span class="label primary">待批</span>
|
||
<span class="label secondary">{{ homework.submittedCount }}已交</span>
|
||
<span class="label secondary">{{ homework.unsubmittedCount }}未交</span>
|
||
</div>
|
||
<n-space>
|
||
<n-button type="primary" @click="viewHomework(homework.id)">查看</n-button>
|
||
<n-button type="error" @click="deleteHomework(homework.id)">删除</n-button>
|
||
</n-space>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||
import { NButton, NSelect } from 'naive-ui'
|
||
import { useRouter } from 'vue-router'
|
||
|
||
interface HomeworkItem {
|
||
id: number
|
||
title: string
|
||
content: string
|
||
publisher: string
|
||
timeRange: string
|
||
status: 'publishing' | 'ended'
|
||
pendingCount: number
|
||
submittedCount: number
|
||
unsubmittedCount: number
|
||
}
|
||
|
||
const router = useRouter()
|
||
const activeTab = ref<'all' | 'publishing' | 'ended'>('all')
|
||
|
||
// 班级选择相关
|
||
const selectedClass = ref<string | null>(null)
|
||
const classOptions = [
|
||
{
|
||
label: '全部班级',
|
||
value: 'all'
|
||
},
|
||
{
|
||
label: '软件工程一班',
|
||
value: 'class1'
|
||
},
|
||
{
|
||
label: '软件工程二班',
|
||
value: 'class2'
|
||
},
|
||
{
|
||
label: '计算机科学一班',
|
||
value: 'class3'
|
||
},
|
||
{
|
||
label: '计算机科学二班',
|
||
value: 'class4'
|
||
},
|
||
{
|
||
label: '信息安全一班',
|
||
value: 'class5'
|
||
}
|
||
]
|
||
|
||
// 屏幕宽度响应式数据
|
||
const screenWidth = ref(window.innerWidth)
|
||
|
||
// 监听窗口大小变化
|
||
const handleResize = () => {
|
||
screenWidth.value = window.innerWidth
|
||
}
|
||
|
||
// 在组件挂载时添加事件监听器
|
||
onMounted(() => {
|
||
window.addEventListener('resize', handleResize)
|
||
})
|
||
|
||
// 在组件卸载时移除事件监听器
|
||
onUnmounted(() => {
|
||
window.removeEventListener('resize', handleResize)
|
||
})
|
||
|
||
const homeworks = ref<HomeworkItem[]>([
|
||
{
|
||
id: 1,
|
||
title: '作业名称作业名称作业名称作业名称',
|
||
content: '作业内容作业内容作业内容作业内容作业内容作业内容作业内容作业内容作业内容',
|
||
publisher: '王建国',
|
||
timeRange: '2025.8.18-2025.9.18',
|
||
status: 'ended',
|
||
pendingCount: 10,
|
||
submittedCount: 0,
|
||
unsubmittedCount: 0
|
||
},
|
||
{
|
||
id: 2,
|
||
title: '作业名称作业名称作业名称作业名称',
|
||
content: '作业内容作业内容作业内容作业内容作业内容作业内容作业内容作业内容作业内容',
|
||
publisher: '王建国',
|
||
timeRange: '2025.8.18-2025.9.18',
|
||
status: 'publishing',
|
||
pendingCount: 0,
|
||
submittedCount: 0,
|
||
unsubmittedCount: 0
|
||
}
|
||
])
|
||
|
||
const setActiveTab = (tab: 'all' | 'publishing' | 'ended') => {
|
||
activeTab.value = tab
|
||
}
|
||
|
||
const handleClassChange = (value: string | null) => {
|
||
console.log('选中的班级:', value)
|
||
// 这里可以添加筛选逻辑
|
||
}
|
||
|
||
const filteredHomeworks = computed(() => {
|
||
if (activeTab.value === 'all') {
|
||
return homeworks.value
|
||
}
|
||
return homeworks.value.filter((homework: HomeworkItem) => homework.status === activeTab.value)
|
||
})
|
||
|
||
const reviewHomework = (id: number) => {
|
||
console.log('批阅作业:', id)
|
||
// 跳转到批阅详情页面
|
||
router.push(`/teacher/course-editor/1/homework/review/${id}`)
|
||
}
|
||
|
||
const viewHomework = (id: number) => {
|
||
console.log('查看作业:', id)
|
||
}
|
||
|
||
const deleteHomework = (id: number) => {
|
||
console.log('删除作业:', id)
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.homework-review {
|
||
width: 100%;
|
||
background: #fff;
|
||
height: 100%;
|
||
}
|
||
|
||
/* 顶部筛选区域 */
|
||
.top-section {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 30px 0 0 25px;
|
||
margin-right: 30px;
|
||
background: #fff;
|
||
border-bottom: 1px solid #e5e5e5;
|
||
}
|
||
|
||
.filter-tabs {
|
||
display: flex;
|
||
gap: 50px;
|
||
}
|
||
|
||
.tab-item {
|
||
font-size: 18px;
|
||
font-weight: 400;
|
||
color: #333333;
|
||
cursor: pointer;
|
||
padding-top: 6px;
|
||
padding-bottom: 20px;
|
||
border-bottom: 3px solid transparent;
|
||
transition: all 0.3s ease;
|
||
position: relative;
|
||
}
|
||
|
||
.tab-item.active {
|
||
color: #5BADD9;
|
||
border-bottom: 4px solid #0288D1;
|
||
}
|
||
|
||
.tab-item:hover {
|
||
color: #2196F3;
|
||
}
|
||
|
||
.class-select {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
/* Naive UI Select 组件样式定制 */
|
||
:deep(.class-select .n-base-selection) {
|
||
background: #fff;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 2px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
:deep(.class-select .n-base-selection:hover) {
|
||
border-color: #0288D1;
|
||
}
|
||
|
||
:deep(.class-select .n-base-selection.n-base-selection--focus) {
|
||
border-color: #0288D1;
|
||
box-shadow: 0 0 0 2px rgba(2, 136, 209, 0.1);
|
||
}
|
||
|
||
:deep(.class-select .n-base-selection-input) {
|
||
color: #062333;
|
||
}
|
||
|
||
:deep(.class-select .n-base-selection-placeholder) {
|
||
color: #999;
|
||
}
|
||
|
||
/* 作业列表 */
|
||
.homework-list {
|
||
padding: 0;
|
||
}
|
||
|
||
.homework-card {
|
||
background: #fff;
|
||
margin: 0;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
padding: 20px 25px;
|
||
position: relative;
|
||
transition: background-color 0.3s ease;
|
||
}
|
||
|
||
.homework-card:hover {
|
||
background-color: #F5F5F5;
|
||
}
|
||
|
||
.homework-card:hover .delete-link {
|
||
opacity: 1;
|
||
}
|
||
|
||
.homework-card:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
/* 卡片头部 */
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.homework-title {
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
color: #062333;
|
||
margin: 0;
|
||
}
|
||
|
||
.status-badge {
|
||
font-size: 16px;
|
||
font-weight: 400;
|
||
padding: 0;
|
||
}
|
||
|
||
.status-badge.ended {
|
||
color: #999999;
|
||
}
|
||
|
||
.status-badge.publishing {
|
||
color: #FF9800;
|
||
}
|
||
|
||
/* 卡片内容 */
|
||
.card-content {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 20px;
|
||
}
|
||
|
||
.content-left {
|
||
flex: 1;
|
||
}
|
||
|
||
.homework-desc {
|
||
font-size: 14px;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
margin: 0 0 20px 0;
|
||
}
|
||
|
||
.homework-info {
|
||
display: flex;
|
||
gap: 30px;
|
||
}
|
||
|
||
.info-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
|
||
.info-item .icon {
|
||
width: 12px;
|
||
height: 12px;
|
||
}
|
||
|
||
.info-item .text {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
/* 右侧内容 */
|
||
.content-right {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
gap: 80px;
|
||
}
|
||
|
||
.delete-link {
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 35%;
|
||
transform: translateY(-50%);
|
||
color: #2196F3;
|
||
font-size: 14px;
|
||
text-decoration: none;
|
||
cursor: pointer;
|
||
align-self: flex-start;
|
||
opacity: 0;
|
||
}
|
||
|
||
.delete-link:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.stats-area {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
gap: 15px;
|
||
}
|
||
|
||
.big-number {
|
||
font-size: 30px;
|
||
font-weight: bold;
|
||
color: #062333;
|
||
line-height: 0.9;
|
||
}
|
||
|
||
|
||
|
||
.label {
|
||
font-size: 12px;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.label.primary {
|
||
color: #062333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.label.secondary {
|
||
color: #999;
|
||
}
|
||
|
||
/* 操作按钮 */
|
||
.action-button {
|
||
background: #0288D1;
|
||
color: white;
|
||
border: none;
|
||
padding: 6px 24px;
|
||
border-radius: 2px;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
transition: background 0.3s ease;
|
||
min-width: 92px;
|
||
}
|
||
|
||
.action-button:hover {
|
||
background: #0288D1;
|
||
}
|
||
|
||
.action-button.review {}
|
||
|
||
.action-button.view {
|
||
background: #0288D1;
|
||
}
|
||
|
||
/* 发布中状态特殊布局调整 */
|
||
.homework-card.publishing .content-right {
|
||
position: relative;
|
||
}
|
||
|
||
.homework-card.publishing .stats-area {
|
||
margin-top: 20px;
|
||
}
|
||
|
||
/* 响应式样式 */
|
||
@media (max-width: 1200px) {
|
||
.top-section {
|
||
flex-direction: column;
|
||
gap: 20px;
|
||
align-items: flex-start;
|
||
padding: 20px 0 0 20px;
|
||
}
|
||
|
||
.filter-tabs {
|
||
gap: 30px;
|
||
}
|
||
|
||
.tab-item {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.class-select {
|
||
width: 100%;
|
||
}
|
||
|
||
:deep(.class-select .n-base-selection) {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 作业卡片在小屏幕下的优化 */
|
||
.homework-card {
|
||
margin: 15px 20px;
|
||
}
|
||
|
||
.card-content {
|
||
flex-direction: column;
|
||
gap: 20px;
|
||
}
|
||
|
||
.content-right {
|
||
align-self: flex-start;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.top-section {
|
||
padding: 15px 0 0 15px;
|
||
}
|
||
|
||
.filter-tabs {
|
||
gap: 20px;
|
||
}
|
||
|
||
.tab-item {
|
||
font-size: 14px;
|
||
padding-bottom: 15px;
|
||
}
|
||
|
||
.class-select {
|
||
width: 100%;
|
||
}
|
||
|
||
:deep(.class-select .n-base-selection) {
|
||
width: 100%;
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* 作业卡片在移动端的优化 */
|
||
.homework-card {
|
||
margin: 10px 15px;
|
||
padding: 15px;
|
||
}
|
||
|
||
.card-header {
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.homework-title {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.status-badge {
|
||
font-size: 12px;
|
||
padding: 4px 8px;
|
||
}
|
||
|
||
.homework-desc {
|
||
font-size: 14px;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.info-item {
|
||
gap: 8px;
|
||
}
|
||
|
||
.info-item .text {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.stats-area {
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.big-number {
|
||
font-size: 24px;
|
||
}
|
||
|
||
.label {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.action-button {
|
||
width: 100%;
|
||
margin-top: 10px;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.top-section {
|
||
padding: 10px 0 0 10px;
|
||
}
|
||
|
||
.filter-tabs {
|
||
gap: 15px;
|
||
}
|
||
|
||
.tab-item {
|
||
font-size: 13px;
|
||
padding-bottom: 10px;
|
||
}
|
||
|
||
/* 作业卡片在超小屏幕下的优化 */
|
||
.homework-card {
|
||
margin: 8px 10px;
|
||
padding: 12px;
|
||
}
|
||
|
||
.homework-title {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.homework-desc {
|
||
font-size: 13px;
|
||
}
|
||
|
||
.info-item .text {
|
||
font-size: 11px;
|
||
}
|
||
|
||
.big-number {
|
||
font-size: 20px;
|
||
}
|
||
|
||
.label {
|
||
font-size: 11px;
|
||
}
|
||
|
||
.delete-link {
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
/* 确保内容不会溢出 */
|
||
.homework-card {
|
||
word-break: break-word;
|
||
overflow-wrap: break-word;
|
||
}
|
||
|
||
.homework-title {
|
||
word-break: break-word;
|
||
overflow-wrap: break-word;
|
||
}
|
||
|
||
.homework-desc {
|
||
word-break: break-word;
|
||
overflow-wrap: break-word;
|
||
}
|
||
</style> |