|
|
@@ -74,53 +74,79 @@
|
|
|
</el-button>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 作业卡片列表 -->
|
|
|
- <div class="assignment-cards">
|
|
|
- <div
|
|
|
- v-for="assignment in filteredAssignments"
|
|
|
- :key="assignment.assignmentId"
|
|
|
- class="assignment-card"
|
|
|
- >
|
|
|
- <div class="card-header">
|
|
|
- <div class="status-indicator" :class="getStatusClass(assignment)"></div>
|
|
|
- <div class="status-text">{{ getStatusText(assignment) }}</div>
|
|
|
- </div>
|
|
|
- <div class="card-content">
|
|
|
- <h3 class="assignment-name">{{ assignment.assignmentName }}</h3>
|
|
|
- <div class="assignment-type">{{ assignment.type }}</div>
|
|
|
- <div class="assignment-time">截止时间: {{ assignment.endTime }}</div>
|
|
|
- <div class="assignment-second-status">
|
|
|
- <el-icon class="status-icon-check" v-if="getSecondStatusText(assignment) === '已批改'" ><Check /></el-icon>
|
|
|
- <el-icon class="status-icon-calendar" v-if="getSecondStatusText(assignment) === '已提交'" ><Calendar /></el-icon>
|
|
|
- <el-icon class="status-icon-close" v-if="getSecondStatusText(assignment) === '未完成'" ><Close /></el-icon>
|
|
|
- <span class="status-text" :class="getSecondStatusClass(assignment)">
|
|
|
- {{ getSecondStatusText(assignment) }}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="card-actions">
|
|
|
- <el-button class="detail-btn" @click="handleShowDetail(assignment.assignmentId)">
|
|
|
- <el-icon><ZoomIn /></el-icon>
|
|
|
- 详情
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- class="result-btn"
|
|
|
- :disabled="getSecondStatusText(assignment) !== '已批改'"
|
|
|
- @click="viewCorrection(assignment.assignmentId, store.user.id, assignment.type, assignment.assignmentName)"
|
|
|
- >
|
|
|
- <el-icon><ZoomIn /></el-icon>
|
|
|
- 批改结果
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <!-- 作业卡片列表 -->
|
|
|
+ <div class="assignment-cards">
|
|
|
+ <div
|
|
|
+ v-for="assignment in filteredAssignments"
|
|
|
+ :key="assignment.assignmentId"
|
|
|
+ class="assignment-card"
|
|
|
+ @click="handleShowDetail(assignment.assignmentId)"
|
|
|
+ >
|
|
|
+ <!-- 左侧状态装饰条和圆点 -->
|
|
|
+ <div class="card-accent">
|
|
|
+ <div class="accent-line" :class="getStatusClass(assignment)"></div>
|
|
|
+ <div class="accent-dot" :class="getStatusClass(assignment)"></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 卡片内容 -->
|
|
|
+ <div class="card-content">
|
|
|
+ <!-- 左侧信息 -->
|
|
|
+ <div class="left-info">
|
|
|
+ <div class="assignment-name">{{ assignment.assignmentName }}</div>
|
|
|
+ <div class="assignment-type">{{ assignment.type }}</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 中间状态信息 -->
|
|
|
+ <div class="middle-info">
|
|
|
+ <div class="status-badge" :class="getSecondStatusClass(assignment)">
|
|
|
+ <el-icon class="status-icon" v-if="getSecondStatusText(assignment) === '已批改'"><Check /></el-icon>
|
|
|
+ <el-icon class="status-icon" v-else-if="getSecondStatusText(assignment) === '已提交'"><Calendar /></el-icon>
|
|
|
+ <el-icon class="status-icon" v-else><Close /></el-icon>
|
|
|
+ <span>{{ getSecondStatusText(assignment) }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧时间信息 -->
|
|
|
+ <div class="right-info">
|
|
|
+ <div class="time-row">
|
|
|
+ <span class="time-label">开始时间:</span>
|
|
|
+ <span class="time-value">{{ assignment.startTime || '未设置' }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="time-row">
|
|
|
+ <span class="time-label">截止时间:</span>
|
|
|
+ <span class="time-value">{{ assignment.endTime }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 操作按钮 -->
|
|
|
+ <div class="card-actions" @click.stop>
|
|
|
+ <el-button
|
|
|
+ class="detail-btn"
|
|
|
+ size="small"
|
|
|
+ @click="handleShowDetail(assignment.assignmentId)"
|
|
|
+ >
|
|
|
+ 详情
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ class="result-btn"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ :disabled="getSecondStatusText(assignment) !== '已批改'"
|
|
|
+ @click="viewCorrection(assignment.assignmentId, store.user.id, assignment.type, assignment.assignmentName)"
|
|
|
+ >
|
|
|
+ 批改结果
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
- import {ZoomIn, Search} from "@element-plus/icons-vue";
|
|
|
+ import {Search} from "@element-plus/icons-vue";
|
|
|
import {Calendar,Check,Close} from "@element-plus/icons-vue";
|
|
|
import {onMounted, reactive, ref, computed, watch} from "vue";
|
|
|
import useApis from "@/apis";
|
|
|
@@ -412,10 +438,7 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 获取状态文本
|
|
|
- const getStatusText = (assignment: IAssignment) => {
|
|
|
- return getActualStatus(assignment)
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
// 获取第二个状态的文本
|
|
|
const getSecondStatusText = (assignment: IAssignment) => {
|
|
|
@@ -490,13 +513,14 @@
|
|
|
.then((res: any) => {
|
|
|
let data = res.data.data.records
|
|
|
// console.log('课程', courseId, '获取到', data.length, '个作业')
|
|
|
- for(let i = 0; i < data.length; i++) {
|
|
|
- data[i].endTime = formatDate(data[i].endTime)
|
|
|
- data[i].courseId = courseId // 添加课程ID
|
|
|
- homeworkList.tableData.push(data[i])
|
|
|
- allAssignments.value.push(data[i]) // 添加到所有作业数组
|
|
|
- // console.log('添加作业:', data[i].assignmentName, 'courseId:', data[i].courseId)
|
|
|
- }
|
|
|
+ for(let i = 0; i < data.length; i++) {
|
|
|
+ data[i].endTime = formatDate(data[i].endTime)
|
|
|
+ data[i].startTime = data[i].startTime ? formatDate(data[i].startTime) : null
|
|
|
+ data[i].courseId = courseId // 添加课程ID
|
|
|
+ homeworkList.tableData.push(data[i])
|
|
|
+ allAssignments.value.push(data[i]) // 添加到所有作业数组
|
|
|
+ // console.log('添加作业:', data[i].assignmentName, 'courseId:', data[i].courseId)
|
|
|
+ }
|
|
|
// console.log('课程', courseId, '作业加载完成,当前allAssignments总数:', allAssignments.value.length)
|
|
|
|
|
|
// 如果是学生角色,获取作业状态数据
|
|
|
@@ -730,169 +754,197 @@ export default {
|
|
|
|
|
|
/* 作业卡片区域 */
|
|
|
.assignment-cards {
|
|
|
- display: grid;
|
|
|
- grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
|
|
|
- row-gap: 20px; /* 上下行间距 */
|
|
|
- column-gap: 70px; /* 左右列间距 */
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16px;
|
|
|
}
|
|
|
|
|
|
.assignment-card {
|
|
|
background: white;
|
|
|
border-radius: 12px;
|
|
|
- padding: 20px;
|
|
|
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
|
|
+ padding: 0;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
transition: all 0.3s ease;
|
|
|
border: 1px solid #f0f0f0;
|
|
|
- min-height: 220px;
|
|
|
+ min-height: 80px;
|
|
|
+ position: relative;
|
|
|
+ cursor: pointer;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
.assignment-card:hover {
|
|
|
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
|
- transform: translateY(-2px);
|
|
|
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
|
+ transform: translateY(-1px);
|
|
|
}
|
|
|
|
|
|
-.card-header {
|
|
|
+/* 左侧状态装饰条和圆点 */
|
|
|
+.card-accent {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ width: 8px;
|
|
|
display: flex;
|
|
|
+ flex-direction: column;
|
|
|
align-items: center;
|
|
|
- margin-bottom: 15px;
|
|
|
}
|
|
|
|
|
|
-.status-indicator {
|
|
|
- width: 12px;
|
|
|
- height: 12px;
|
|
|
- border-radius: 50%;
|
|
|
- margin-right: 8px;
|
|
|
+.accent-line {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
}
|
|
|
|
|
|
-.status-indicator.status-unpublished {
|
|
|
- background-color: #F0C05A;
|
|
|
+.accent-line.status-proceeding {
|
|
|
+ background-color: #52c41a; /* 绿色 - 进行中 */
|
|
|
}
|
|
|
|
|
|
-.status-indicator.status-proceeding {
|
|
|
- background-color: #52c41a;
|
|
|
+.accent-line.status-unpublished {
|
|
|
+ background-color: #faad14; /* 黄色 - 未发布 */
|
|
|
}
|
|
|
|
|
|
-.status-indicator.status-finished {
|
|
|
- background-color: #ff4d4f;
|
|
|
+.accent-line.status-finished {
|
|
|
+ background-color: #ff4d4f; /* 红色 - 已截止 */
|
|
|
}
|
|
|
|
|
|
-.status-indicator.status-not-started {
|
|
|
- background-color: #faad14;
|
|
|
+.accent-line.status-unknown {
|
|
|
+ background-color: #d9d9d9; /* 灰色 - 未知状态 */
|
|
|
}
|
|
|
|
|
|
-.status-indicator.status-unknown {
|
|
|
- background-color: #d9d9d9;
|
|
|
+.accent-dot {
|
|
|
+ position: absolute;
|
|
|
+ left: 20px;
|
|
|
+ top: 20px;
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ border-radius: 50%;
|
|
|
}
|
|
|
|
|
|
-.status-text {
|
|
|
- font-size: 14px;
|
|
|
- height: 20px;
|
|
|
- color: #666;
|
|
|
- font-weight: 500;
|
|
|
+.accent-dot.status-proceeding {
|
|
|
+ background-color: #52c41a; /* 绿色 - 进行中 */
|
|
|
+}
|
|
|
+
|
|
|
+.accent-dot.status-unpublished {
|
|
|
+ background-color: #faad14; /* 黄色 - 未发布 */
|
|
|
+}
|
|
|
+
|
|
|
+.accent-dot.status-finished {
|
|
|
+ background-color: #ff4d4f; /* 红色 - 已截止 */
|
|
|
+}
|
|
|
+
|
|
|
+.accent-dot.status-unknown {
|
|
|
+ background-color: #d9d9d9; /* 灰色 - 未知状态 */
|
|
|
}
|
|
|
|
|
|
+/* 卡片内容 */
|
|
|
.card-content {
|
|
|
- margin-bottom: 20px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 16px 20px 16px 30px;
|
|
|
+ gap: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 左侧信息 */
|
|
|
+.left-info {
|
|
|
+ margin-left: 15px;
|
|
|
+ flex: 0 0 auto;
|
|
|
+ min-width: 200px;
|
|
|
}
|
|
|
|
|
|
.assignment-name {
|
|
|
font-size: 16px;
|
|
|
font-weight: 600;
|
|
|
color: #2c3e50;
|
|
|
- margin: 0 0 8px 0;
|
|
|
- line-height: 1.4;
|
|
|
- height: 44.8px; /* 固定高度:16px * 1.4 * 2 = 44.8px (两行) */
|
|
|
+ margin: 0 0 6px 0;
|
|
|
+ line-height: 1.3;
|
|
|
overflow: hidden;
|
|
|
- display: -webkit-box;
|
|
|
- -webkit-line-clamp: 2;
|
|
|
- line-clamp: 2;
|
|
|
- -webkit-box-orient: vertical;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ max-width: 180px;
|
|
|
}
|
|
|
|
|
|
.assignment-type {
|
|
|
- font-size: 12px;
|
|
|
- color: #1890ff;
|
|
|
+ font-size: 14px;
|
|
|
+ width: 50px;
|
|
|
+ text-align: center;
|
|
|
background-color: #e6f7ff;
|
|
|
- padding: 2px 8px;
|
|
|
- border-radius: 4px;
|
|
|
- display: inline-block;
|
|
|
- margin-bottom: 8px;
|
|
|
+ color: #1890ff;
|
|
|
+ font-weight: 400;
|
|
|
+ border-radius: 10px;
|
|
|
}
|
|
|
|
|
|
-.assignment-time {
|
|
|
- font-size: 12px;
|
|
|
- color: #666;
|
|
|
- margin-bottom: 15px;
|
|
|
+/* 中间状态信息 */
|
|
|
+.middle-info {
|
|
|
+ margin-left: 20px;
|
|
|
+ flex: 0 0 auto;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ min-width: 120px;
|
|
|
}
|
|
|
|
|
|
-.assignment-second-status {
|
|
|
+.status-badge {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- font-size: 16px;
|
|
|
- margin-bottom: 0px;
|
|
|
+ gap: 6px;
|
|
|
+ padding: 6px 12px;
|
|
|
+ border-radius: 16px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
|
|
|
|
-.assignment-second-status .status-icon-check {
|
|
|
- margin-right: 10px;
|
|
|
- color: #6AA67D;
|
|
|
- font-size: 20px;
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
+.status-badge.status-submitted {
|
|
|
+ background-color: #e6f7ff;
|
|
|
+ color: #1890ff;
|
|
|
}
|
|
|
|
|
|
-.assignment-second-status .status-icon-calendar {
|
|
|
- margin-right: 10px;
|
|
|
- color: #6AA67D;
|
|
|
- font-size: 20px;
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
+.status-badge.status-incomplete {
|
|
|
+ background-color: #fff2e8;
|
|
|
+ color: #fa8c16;
|
|
|
}
|
|
|
|
|
|
-.assignment-second-status .status-icon-close {
|
|
|
- margin-right: 10px;
|
|
|
- color: #C45C4A;
|
|
|
- font-size: 20px;
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
+.status-icon {
|
|
|
+ font-size: 16px;
|
|
|
}
|
|
|
|
|
|
-.assignment-second-status .status-text.status-submitted {
|
|
|
- color: #6AA67D;
|
|
|
+/* 右侧时间信息 */
|
|
|
+.right-info {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 4px;
|
|
|
+ align-items: flex-end;
|
|
|
}
|
|
|
|
|
|
-.assignment-second-status .status-text.status-incomplete {
|
|
|
- color: #C45C4A;
|
|
|
+.time-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ font-size: 13px;
|
|
|
}
|
|
|
|
|
|
-.card-actions {
|
|
|
- display: flex;
|
|
|
- gap: 10px;
|
|
|
+.time-label {
|
|
|
+ color: #666;
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
-.detail-btn, .result-btn {
|
|
|
- padding: 6px 12px;
|
|
|
- font-size: 12px;
|
|
|
- border-radius: 6px;
|
|
|
+.time-value {
|
|
|
+ color: #333;
|
|
|
+ font-weight: 500;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+/* 操作按钮 */
|
|
|
+.card-actions {
|
|
|
+ flex: 0 0 auto;
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- gap: 4px;
|
|
|
- width: 80px;
|
|
|
+ gap: 8px;
|
|
|
+ margin-left: auto;
|
|
|
}
|
|
|
|
|
|
.detail-btn {
|
|
|
- background-color: #f0f0f0;
|
|
|
- border-color: #d9d9d9;
|
|
|
- color: #666;
|
|
|
+ background-color: #5397F8;
|
|
|
+ opacity: 1;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #ffffff;
|
|
|
}
|
|
|
|
|
|
.result-btn {
|
|
|
@@ -902,25 +954,27 @@ export default {
|
|
|
}
|
|
|
|
|
|
.detail-btn:hover {
|
|
|
- background-color: #e6e6e6;
|
|
|
+ background-color: #5397F8;
|
|
|
+ opacity: 0.8;
|
|
|
}
|
|
|
|
|
|
.result-btn:hover {
|
|
|
background-color: #40a9ff;
|
|
|
+ border-color: #40a9ff;
|
|
|
}
|
|
|
|
|
|
/* 禁用状态的批改结果按钮样式 */
|
|
|
.result-btn:disabled {
|
|
|
- background-color: #1890ff;
|
|
|
- border-color: #1890ff;
|
|
|
- color: white;
|
|
|
- opacity: 0.5;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ border-color: #d9d9d9;
|
|
|
+ color: #bfbfbf;
|
|
|
+ opacity: 1;
|
|
|
cursor: not-allowed;
|
|
|
}
|
|
|
|
|
|
.result-btn:disabled:hover {
|
|
|
- background-color: #1890ff;
|
|
|
- border-color: #1890ff;
|
|
|
- color: white;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ border-color: #d9d9d9;
|
|
|
+ color: #bfbfbf;
|
|
|
}
|
|
|
</style>
|